diff --git a/CMakeLists.txt b/CMakeLists.txt index b5a4cbe6a..69be3d8d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,6 +35,7 @@ string(REGEX REPLACE "([a-zA-Z_]+)\\.po" "\\1" LINPHONE_ALL_LANGS_LIST "${LINPHO string(REPLACE ";" " " LINPHONE_ALL_LANGS "${LINPHONE_ALL_LANGS_LIST}") include(CMakeDependentOption) +include(cmake/Tools.cmake) option(ENABLE_SHARED "Build shared library." YES) option(ENABLE_STATIC "Build static library." YES) @@ -46,8 +47,7 @@ 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_SPHINX_DOC "Enable sphinx documentation generation." NO) +option(ENABLE_DOC "Enable API documentation generation." NO) option(ENABLE_JAVADOC "Add a target to generate documentation for Java API" NO) option(ENABLE_LDAP "Enable LDAP support." NO) option(ENABLE_RELATIVE_PREFIX "Find resources relatively to the installation directory." NO) @@ -173,8 +173,15 @@ if(ENABLE_LIME) endif() set(HAVE_LIME 1) endif() -if(ENABLE_CXX_WRAPPER OR ENABLE_CSHARP_WRAPPER OR ENABLE_JAVA_WRAPPER OR ENABLE_SPHINX_DOC) +if(ENABLE_CXX_WRAPPER OR ENABLE_CSHARP_WRAPPER OR ENABLE_JAVA_WRAPPER OR ENABLE_DOC) find_package(PythonInterp REQUIRED) + check_python_module(pystache) + check_python_module(six) + if(ENABLE_DOC) + check_python_module(sphinx) + check_python_module(javasphinx) + check_python_module(sphinx_csharp) + endif() endif() if(UNIX AND NOT APPLE) @@ -182,6 +189,19 @@ if(UNIX AND NOT APPLE) check_include_files(libudev.h HAVE_LIBUDEV_H) endif() +if(MSVC AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone" AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsStore") + find_library(LIBGCC NAMES gcc) + find_library(LIBMINGWEX NAMES mingwex) +endif() + +if(NOT WIN32) + find_package(Iconv QUIET) +endif() +if(ANDROID) + find_package(CpuFeatures REQUIRED) + find_package(Support REQUIRED) +endif() + set(LINPHONE_LDFLAGS "${BELLESIP_LDFLAGS} ${MEDIASTREAMER2_LDFLAGS}") if(BELCARD_FOUND AND APPLE) set(LINPHONE_LDFLAGS "${LINPHONE_LDFLAGS} -stdlib=libc++") @@ -249,6 +269,11 @@ if(ENABLE_DEBUG_LOGS) add_definitions("-DDEBUG_LOGS") endif() +# Enable stdint.h limit macros on C++ files. (Windows only.) +if(MSVC) + add_definitions("-D__STDC_LIMIT_MACROS") +endif() + set(STRICT_OPTIONS_CPP ) set(STRICT_OPTIONS_C ) set(STRICT_OPTIONS_CXX ) @@ -278,7 +303,7 @@ else() ) CHECK_CXX_COMPILER_FLAG("-Wsuggest-override" SUGGEST_OVERRIDE) if (SUGGEST_OVERRIDE) - list(APPEND STRICT_OPTIONS_CXX "-Wsuggest-override" "-Werror=suggest-override") + list(APPEND STRICT_OPTIONS_CXX "-Wsuggest-override" "-Wno-error=suggest-override" ) endif () list(APPEND STRICT_OPTIONS_C "-Wstrict-prototypes" "-Werror=strict-prototypes") if(CMAKE_C_COMPILER_ID STREQUAL "GNU") @@ -342,8 +367,8 @@ add_subdirectory(java) if(ENABLE_JAVA_WRAPPER) add_subdirectory(wrappers/java) endif() -add_subdirectory(src) add_subdirectory(coreapi) +add_subdirectory(src) add_subdirectory(share) if(ENABLE_CONSOLE_UI) add_subdirectory(console) diff --git a/README.md b/README.md index f9eb8a190..3935415a6 100644 --- a/README.md +++ b/README.md @@ -11,19 +11,22 @@ Building liblinphone ### Required dependencies -* *BcToolbox[2]*: portability layer -* *BelleSIP[3]*: SIP stack -* *Mediastreamer2[4]*: multimedia engine -* *Belcard[5]*: VCard support -* libxml2 -* zlib -* libsqlite3: user data storage (disablable) -* gettext and libintl: internationalization support (disablable) +* **BcToolbox[2]:** portability layer +* **BelleSIP[3]:** SIP stack +* **Mediastreamer2[4]:** multimedia engine +* **Belcard[5]:** VCard support +* **libxml2** +* **zlib** +* **libsqlite3:** user data storage (disablable) +* **gettext** and **libintl**: internationalization support (disablable) +* **python interpreter** and **pystache**, **six** python module (needed for C++ wrapper and API documentaiton) +* **doxygen** and **dot** (needed for C++ wrapper and API documentation) ### Opitonal dependencies -* *Bzrtp[6]*: zrtp stack used for Linphone Instant Messaging Encryption +* **Bzrtp[6]**: zrtp stack used for Linphone Instant Messaging Encryption. +* For API documentatino generation: **sphinx**, **javasphinx**, **sphinx_csharp** python modules are needed. ### Build instructions @@ -36,17 +39,17 @@ Building liblinphone ### Supported build opitons -* `CMAKE_INSTALL_PREFIX=` : install prefix -* `CMAKE_PREFIX_PATH=` : column-separated list of prefixes where to search for dependencies -* `ENABLE_SHARED=NO` : do not build the shared library -* `ENABLE_STATIC=NO` : do not build the static library -* `ENABLE_STRICT=NO` : build without strict compilation flags (-Wall -Werror) -* `ENABLE_DOC=NO` : do not generate the reference documentation of liblinphone -* `ENABLE_UNIT_TESTS=NO` : do not build testing binaries -* `ENABLE_VCARD=NO` : disable VCard support -* `ENABLE_SQLITE_STORAGE=NO` : disable SQlite user data storage (message, history, contacts list) -* `ENABLE_TOOLS=NO` : do not build tool binaries -* `ENABLE_LIME=YES` : disable Linphone Instant Messaging Encryption +* **`CMAKE_INSTALL_PREFIX=`** : install prefix +* **`CMAKE_PREFIX_PATH=`** : column-separated list of prefixes where to search for dependencies +* **`ENABLE_SHARED=NO`** : do not build the shared library +* **`ENABLE_STATIC=NO`** : do not build the static library +* **`ENABLE_STRICT=NO`** : build without strict compilation flags (-Wall -Werror) +* **`ENABLE_DOC=YES`** : Make the reference documentation of liblinphone to generated +* **`ENABLE_UNIT_TESTS=NO`** : do not build testing binaries +* **`ENABLE_VCARD=NO`** : disable VCard support +* **`ENABLE_SQLITE_STORAGE=NO`** : disable SQlite user data storage (message, history, contacts list) +* **`ENABLE_TOOLS=NO`** : do not build tool binaries +* **`ENABLE_LIME=YES`** : disable Linphone Instant Messaging Encryption ### Note for packagers @@ -89,4 +92,4 @@ Here is a short description of the content of the source tree. - [3] belle-sip: git://git.linphone.org/belle-sip.git *or* - [4] mediastreamer2: git://git.linphone.org/mediastreamer2.git *or* - [5] belcard: git://git.linphone.org/belcard.git *or* -- [5] bzrtp: git://git.linphone.org/bzrtp.git *or* +- [6] bzrtp: git://git.linphone.org/bzrtp.git *or* diff --git a/cmake/Tools.cmake b/cmake/Tools.cmake new file mode 100644 index 000000000..8c3d3d0c7 --- /dev/null +++ b/cmake/Tools.cmake @@ -0,0 +1,33 @@ +############################################################################ +# LinphoneUtils.cmake +# Copyright (C) 2018 Belledonne Communications, Grenoble France +# +############################################################################ +# +# 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. +# +############################################################################ + +function(check_python_module module_name) + execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import ${module_name}" + RESULT_VARIABLE result + OUTPUT_QUIET + ERROR_QUIET) + if(result EQUAL 0) + message(STATUS "'${module_name}' python module found") + else() + message(FATAL_ERROR "'${module_name}' python module not found") + endif() +endfunction() diff --git a/console/CMakeLists.txt b/console/CMakeLists.txt index 1e4de5e1d..c48c5cbab 100644 --- a/console/CMakeLists.txt +++ b/console/CMakeLists.txt @@ -53,7 +53,7 @@ if(WIN32) endif() add_executable(linphonecsh ${LINPHONECSH_SOURCE_FILES}) -target_link_libraries(linphonecsh ${LINPHONE_LIBS_FOR_TOOLS} ${ORTP_LIBRARIES}) +target_link_libraries(linphonecsh ${LINPHONE_LIBS_FOR_TOOLS} ${BCTOOLBOX_CORE_LIBRARIES} ${ORTP_LIBRARIES}) set_target_properties(linphonecsh PROPERTIES LINK_FLAGS "${LINPHONE_LDFLAGS}") set(INSTALL_TARGETS linphonec linphonecsh) diff --git a/console/commands.c b/console/commands.c index e7cd39bb4..f8334b79e 100644 --- a/console/commands.c +++ b/console/commands.c @@ -2150,7 +2150,7 @@ static int lpc_cmd_speak(LinphoneCore *lc, char *args){ #ifndef _WIN32 char voice[64]; char *sentence; - char cl[128]; + char cl[256]; char wavfile[128]="/tmp/linphonec-espeak-XXXXXX"; int status; FILE *file; diff --git a/coreapi/CMakeLists.txt b/coreapi/CMakeLists.txt index 85e13205c..fb380c2a5 100644 --- a/coreapi/CMakeLists.txt +++ b/coreapi/CMakeLists.txt @@ -20,19 +20,6 @@ # ############################################################################ -if(MSVC AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone" AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsStore") - find_library(LIBGCC NAMES gcc) - find_library(LIBMINGWEX NAMES mingwex) -endif() - -if(NOT WIN32) - find_package(Iconv QUIET) -endif() -if(ANDROID) - find_package(CpuFeatures REQUIRED) - find_package(Support REQUIRED) -endif() - list(APPEND LINPHONE_PRIVATE_HEADER_FILES bellesip_sal/sal_impl.h carddav.h @@ -64,7 +51,6 @@ set(LINPHONE_SOURCE_FILES_C carddav.c chat.c contactprovider.c - content.c dial_plan.c dict.c ec-calibrator.c @@ -137,54 +123,7 @@ else() list(APPEND LINPHONE_SOURCE_FILES_C linphone_tunnel_stubs.c) endif() -bc_git_version(liblinphone ${PROJECT_VERSION}) - -add_definitions( - -DUSE_BELLESIP - -DLIBLINPHONE_EXPORTS -) - -set(LIBS - ${BCTOOLBOX_CORE_LIBRARIES} - ${BELLESIP_LIBRARIES} - ${MEDIASTREAMER2_LIBRARIES} - ${ORTP_LIBRARIES} - ${XML2_LIBRARIES} - ${BELR_LIBRARIES} - ${LIBXSD_LIBRARIES} -) -if(WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsStore") - list(APPEND LIBS "Ws2_32") -endif() -if(ENABLE_LIME) - list(APPEND LIBS ${BZRTP_LIBRARIES}) -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() -if(ICONV_FOUND) - list(APPEND LIBS ${ICONV_LIBRARIES}) -endif() -if(ENABLE_TUNNEL) - list(APPEND LIBS ${TUNNEL_LIBRARIES}) -endif() -if(MSVC AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone" AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsStore") - list(APPEND LIBS ${LIBGCC} ${LIBMINGWEX}) -endif() -if(WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone" AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsStore") - list(APPEND LIBS shlwapi) -endif() -if(INTL_FOUND) - list(APPEND LIBS ${INTL_LIBRARIES}) -endif() if(BELCARD_FOUND) - list(APPEND LIBS ${BELCARD_LIBRARIES}) list(APPEND LINPHONE_SOURCE_FILES_CXX vcard.cc) if(NOT MSVC) list(APPEND STRICT_OPTIONS_CXX "-std=c++11") @@ -196,106 +135,37 @@ else() list(APPEND LINPHONE_SOURCE_FILES_C vcard_stubs.c) endif() + +bc_git_version(liblinphone ${PROJECT_VERSION}) + +add_definitions( + -DUSE_BELLESIP + -DLIBLINPHONE_EXPORTS + -DBCTBX_LOG_DOMAIN="liblinphone" +) + set_source_files_properties(${LINPHONE_SOURCE_FILES_C} PROPERTIES LANGUAGE CXX) bc_apply_compile_flags(LINPHONE_SOURCE_FILES_C STRICT_OPTIONS_CPP STRICT_OPTIONS_CXX) bc_apply_compile_flags(LINPHONE_SOURCE_FILES_CXX STRICT_OPTIONS_CPP STRICT_OPTIONS_CXX) bc_apply_compile_flags(LINPHONE_SOURCE_FILES_OBJC STRICT_OPTIONS_CPP STRICT_OPTIONS_OBJC) -if(ENABLE_STATIC) - add_library(linphone-static STATIC ${LINPHONE_HEADER_FILES} ${LINPHONE_PRIVATE_HEADER_FILES} - ${LINPHONE_SOURCE_FILES_C} ${LINPHONE_SOURCE_FILES_CXX} ${LINPHONE_SOURCE_FILES_OBJC} - $ - ) - set_target_properties(linphone-static PROPERTIES OUTPUT_NAME linphone) - add_dependencies(linphone-static liblinphone-git-version) - target_include_directories(linphone-static PUBLIC ${LINPHONE_INCLUDE_DIRS}) - target_link_libraries(linphone-static INTERFACE ${LIBS}) - if(APPLE) - target_link_libraries(linphone-static INTERFACE "-framework Foundation" "-framework AVFoundation") - endif() - install(TARGETS linphone-static EXPORT ${EXPORT_TARGETS_NAME}Targets - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE - ) -endif() -if(ENABLE_SHARED) - add_library(linphone SHARED "../share/cpim_grammar" ${LINPHONE_HEADER_FILES} ${LINPHONE_PRIVATE_HEADER_FILES} - ${LINPHONE_SOURCE_FILES_C} ${LINPHONE_SOURCE_FILES_CXX} ${LINPHONE_SOURCE_FILES_OBJC} - $ - ) - if(IOS) - if(IOS) - set(MIN_OS ${LINPHONE_IOS_DEPLOYMENT_TARGET}) - else() - set(MIN_OS ${CMAKE_OSX_DEPLOYMENT_TARGET}) - endif() - set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/build/osx/") - set_target_properties(linphone PROPERTIES - FRAMEWORK TRUE - MACOSX_FRAMEWORK_IDENTIFIER org.linphone.linphone - MACOSX_FRAMEWORK_INFO_PLIST Info.plist.in - PUBLIC_HEADER "${LINPHONE_HEADER_FILES}" - RESOURCE "../share/cpim_grammar" - ) - endif() - if(BELCARD_FOUND) - if(APPLE) - set_target_properties(linphone PROPERTIES LINK_FLAGS "-stdlib=libc++") - endif() - endif() - set_target_properties(linphone PROPERTIES LINKER_LANGUAGE CXX) - if(NOT ANDROID) - # Do not version shared library on Android - set_target_properties(linphone PROPERTIES SOVERSION ${LINPHONE_SO_VERSION}) - endif() - add_dependencies(linphone liblinphone-git-version) - target_include_directories(linphone PUBLIC ${LINPHONE_INCLUDE_DIRS}) - target_link_libraries(linphone PRIVATE ${LIBS}) - if(APPLE) - target_link_libraries(linphone PRIVATE "-framework Foundation" "-framework AVFoundation") - endif() - if(WIN32 AND CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone" AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsStore") - set_target_properties(linphone PROPERTIES PREFIX "lib") - elseif(ANDROID) - target_link_libraries(linphone PUBLIC "log" ${SUPPORT_LIBRARIES} ${CPUFEATURES_LIBRARIES}) - if(ENABLE_JAVA_WRAPPER) - add_dependencies(linphone linphonej) - endif() - endif() - if(MSVC) - if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/linphone.pdb - DESTINATION ${CMAKE_INSTALL_BINDIR} - PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE - ) - endif() - endif() - install(TARGETS linphone EXPORT ${EXPORT_TARGETS_NAME}Targets - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - FRAMEWORK DESTINATION Frameworks - PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE +if (ENABLE_STATIC) + add_library(linphone-coreapi-static OBJECT + ${LINPHONE_PRIVATE_HEADER_FILES} ${LINPHONE_SOURCE_FILES_C} ${LINPHONE_SOURCE_FILES_CXX} ${LINPHONE_SOURCE_FILES_OBJC} ) -endif() -if(ICONV_FOUND) - if(APPLE) - # Prevent conflict between the system iconv.h header and the one from macports. - if(ENABLE_STATIC) - target_compile_options(linphone-static PRIVATE "-include" "${ICONV_INCLUDE_DIRS}/iconv.h") - endif() - if(ENABLE_SHARED) - target_compile_options(linphone PRIVATE "-include" "${ICONV_INCLUDE_DIRS}/iconv.h") - endif() - else() - if(ENABLE_STATIC) - target_include_directories(linphone-static PRIVATE ${ICONV_INCLUDE_DIRS}) - endif() - if(ENABLE_SHARED) - target_include_directories(linphone PRIVATE ${ICONV_INCLUDE_DIRS}) - endif() - endif() -endif() + target_include_directories(linphone-coreapi-static SYSTEM PRIVATE ${LINPHONE_INCLUDE_DIRS}) + add_dependencies(linphone-coreapi-static liblinphone-git-version) +endif () + +if (ENABLE_SHARED) + add_library(linphone-coreapi OBJECT + ${LINPHONE_PRIVATE_HEADER_FILES} ${LINPHONE_SOURCE_FILES_C} ${LINPHONE_SOURCE_FILES_CXX} ${LINPHONE_SOURCE_FILES_OBJC} + ) + target_include_directories(linphone-coreapi SYSTEM PRIVATE ${LINPHONE_INCLUDE_DIRS}) + target_compile_options(linphone-coreapi PRIVATE "-fPIC") + add_dependencies(linphone-coreapi liblinphone-git-version) +endif () + add_subdirectory(help) diff --git a/coreapi/Makefile.am b/coreapi/Makefile.am index 4e63d8879..c2b2ee53b 100644 --- a/coreapi/Makefile.am +++ b/coreapi/Makefile.am @@ -39,7 +39,6 @@ liblinphone_la_SOURCES=\ chat_file_transfer.c \ conference.cc conference_private.h \ contactprovider.c contact_providers_priv.h \ - content.c \ dial_plan.c \ dict.c \ ec-calibrator.c \ diff --git a/coreapi/TunnelManager.cc b/coreapi/TunnelManager.cc index 8a51c392c..43b1be150 100644 --- a/coreapi/TunnelManager.cc +++ b/coreapi/TunnelManager.cc @@ -33,7 +33,7 @@ void TunnelManager::addServer(const char *ip, int port,unsigned int udpMirrorPor return; } addServer(ip,port); - mUdpMirrorClients.push_back(UdpMirrorClient(ServerAddr(ip,udpMirrorPort),delay)); + mUdpMirrorClients.push_back(UdpMirrorClient(ServerAddr(ip, (int)udpMirrorPort), delay)); } void TunnelManager::addServer(const char *ip, int port) { @@ -58,7 +58,7 @@ void TunnelManager::addServerPair(const char *ip1, int port1, const char *ip2, i return; } addServerPair(ip1, port1, ip2, port2); - mUdpMirrorClients.push_back(UdpMirrorClient(ServerAddr(ip1, udpMirrorPort), delay)); + mUdpMirrorClients.push_back(UdpMirrorClient(ServerAddr(ip1, (int)udpMirrorPort), delay)); } void TunnelManager::addServerPair(const char *ip1, int port1, const char *ip2, int port2) { @@ -159,7 +159,7 @@ void TunnelManager::startClient() { mTunnelClient = TunnelClient::create(TRUE); } - sal_set_tunnel(mCore->sal, mTunnelClient); + mCore->sal->setTunnel(mTunnelClient); if (!mUseDualClient) { static_cast(mTunnelClient)->setCallback(tunnelCallback,this); } else { @@ -220,21 +220,21 @@ bool TunnelManager::isConnected() const { int TunnelManager::customSendto(struct _RtpTransport *t, mblk_t *msg , int flags, const struct sockaddr *to, socklen_t tolen){ int size; DualSocket *ds = (DualSocket *)t->data; - msgpullup(msg,-1); - size=msgdsize(msg); - ds->sendSocket->sendto(msg->b_rptr,size,to,tolen); + msgpullup(msg, (size_t)-1); + size = (int)msgdsize(msg); + ds->sendSocket->sendto(msg->b_rptr, (size_t)size, to, tolen); return size; } int TunnelManager::customRecvfrom(struct _RtpTransport *t, mblk_t *msg, int flags, struct sockaddr *from, socklen_t *fromlen){ DualSocket *ds = (DualSocket *)t->data; memset(&msg->recv_addr,0,sizeof(msg->recv_addr)); - int err=ds->recvSocket->recvfrom(msg->b_wptr,dblk_lim(msg->b_datap)-dblk_base(msg->b_datap),from,*fromlen); + long err=ds->recvSocket->recvfrom(msg->b_wptr, (size_t)(dblk_lim(msg->b_datap) - dblk_base(msg->b_datap)), from, *fromlen); //to make ice happy inet_aton(((TunnelManager*)(ds->recvSocket)->getUserPointer())->mLocalAddr,&msg->recv_addr.addr.ipi_addr); msg->recv_addr.family = AF_INET; msg->recv_addr.port = htons((unsigned short)(ds->recvSocket)->getPort()); - if (err>0) return err; + if (err>0) return (int)err; return 0; } @@ -281,7 +281,7 @@ TunnelManager::~TunnelManager(){ mTunnelClient->stop(); delete mTunnelClient; } - sal_set_tunnel(mCore->sal,NULL); + mCore->sal->setTunnel(NULL); linphone_core_remove_listener(mCore, mVTable); linphone_core_v_table_destroy(mVTable); } diff --git a/coreapi/account_creator.c b/coreapi/account_creator.c index d624aaef0..c28e510a7 100644 --- a/coreapi/account_creator.c +++ b/coreapi/account_creator.c @@ -21,14 +21,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "linphone/core.h" #include "linphone/lpconfig.h" + #include "c-wrapper/c-wrapper.h" #include "dial-plan/dial-plan.h" -#if !_WIN32 - #include "regex.h" -#endif -#include +#include "bctoolbox/crypto.h" +#include "bctoolbox/regex.h" // TODO: From coreapi. Remove me later. #include "private.h" @@ -112,25 +111,6 @@ static char* _get_identity(const LinphoneAccountCreator *creator) { return identity; } -static bool_t is_matching_regex(const char *entry, const char* regex) { -#if _WIN32 - return TRUE; -#else - regex_t regex_pattern; - char err_msg[256]; - int res; - res = regcomp(®ex_pattern, regex, REG_EXTENDED | REG_NOSUB); - if(res != 0) { - regerror(res, ®ex_pattern, err_msg, sizeof(err_msg)); - ms_error("Could not compile regex '%s: %s", regex, err_msg); - return FALSE; - } - res = regexec(®ex_pattern, entry, 0, NULL, 0); - regfree(®ex_pattern); - return (res != REG_NOMATCH); -#endif -} - LinphoneProxyConfig * linphone_account_creator_create_proxy_config(const LinphoneAccountCreator *creator) { LinphoneAuthInfo *info; LinphoneProxyConfig *cfg = linphone_core_create_proxy_config(creator->core); @@ -288,8 +268,12 @@ void linphone_account_creator_cbs_set_update_account(LinphoneAccountCreatorCbs * static void _linphone_account_creator_destroy(LinphoneAccountCreator *creator) { /*this will drop all pending requests if any*/ if (creator->xmlrpc_session) linphone_xml_rpc_session_release(creator->xmlrpc_session); - if (creator->service != NULL && linphone_account_creator_service_get_destructor_cb(creator->service) != NULL) - linphone_account_creator_service_get_destructor_cb(creator->service)(creator); + if (creator->service != NULL ) { + if (linphone_account_creator_service_get_destructor_cb(creator->service) != NULL) + linphone_account_creator_service_get_destructor_cb(creator->service)(creator); + linphone_account_creator_service_unref(creator->service); + } + linphone_account_creator_cbs_unref(creator->cbs); linphone_proxy_config_unref(creator->proxy_cfg); linphone_account_creator_reset(creator); @@ -309,6 +293,7 @@ LinphoneAccountCreator * _linphone_account_creator_new(LinphoneCore *core, const const char* domain = lp_config_get_string(core->config, "assistant", "domain", NULL); creator = belle_sip_object_new(LinphoneAccountCreator); creator->service = linphone_core_get_account_creator_service(core); + linphone_account_creator_service_ref(creator->service); creator->cbs = linphone_account_creator_cbs_new(); creator->core = core; creator->transport = LinphoneTransportTcp; @@ -383,7 +368,7 @@ LinphoneAccountCreatorUsernameStatus linphone_account_creator_set_username(Linph return LinphoneAccountCreatorUsernameStatusTooLong; } else if (use_phone_number && !linphone_proxy_config_is_phone_number(NULL, username)) { return LinphoneAccountCreatorUsernameStatusInvalid; - } else if (regex && !is_matching_regex(username, regex)) { + } else if (regex && !bctbx_is_matching_regex(username, regex)) { return LinphoneAccountCreatorUsernameStatusInvalidCharacters; } else if (validate_uri(username, NULL, NULL) != 0) { return LinphoneAccountCreatorUsernameStatusInvalid; @@ -506,10 +491,10 @@ const char * linphone_account_creator_get_display_name(const LinphoneAccountCrea } LinphoneAccountCreatorEmailStatus linphone_account_creator_set_email(LinphoneAccountCreator *creator, const char *email) { - if (!email || !is_matching_regex(email, "^.+@.+\\..*$")) { + if (!email || !bctbx_is_matching_regex(email, "^.+@.+\\..*$")) { return LinphoneAccountCreatorEmailStatusMalformed; } - if (!is_matching_regex(email, "^.+@.+\\.[A-Za-z]{2}[A-Za-z]*$")) { + if (!bctbx_is_matching_regex(email, "^.+@.+\\.[A-Za-z]{2}[A-Za-z]*$")) { return LinphoneAccountCreatorEmailStatusInvalidCharacters; } set_string(&creator->email, email, TRUE); diff --git a/coreapi/authentication.c b/coreapi/authentication.c index 9d310da3c..5ae67f4d2 100644 --- a/coreapi/authentication.c +++ b/coreapi/authentication.c @@ -452,8 +452,6 @@ LinphoneAuthInfo * linphone_core_create_auth_info(LinphoneCore *lc, const char * void linphone_core_add_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *info){ LinphoneAuthInfo *ai; - bctbx_list_t *elem; - bctbx_list_t *l; int restarted_op_count=0; bool_t updating=FALSE; @@ -472,10 +470,10 @@ void linphone_core_add_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *info) lc->auth_info=bctbx_list_append(lc->auth_info,linphone_auth_info_clone(info)); /* retry pending authentication operations */ - for(l=elem=lc->sal->get_pending_auths();elem!=NULL;elem=elem->next){ - LinphonePrivate::SalOp *op= static_cast(elem->data); + auto pendingAuths = lc->sal->getPendingAuths(); + for (const auto &op : pendingAuths) { LinphoneAuthInfo *ai; - const SalAuthInfo *req_sai=op->get_auth_requested(); + const SalAuthInfo *req_sai=op->getAuthRequested(); ai=(LinphoneAuthInfo*)_linphone_core_find_auth_info(lc,req_sai->realm,req_sai->username,req_sai->domain, FALSE); if (ai){ SalAuthInfo sai; @@ -495,7 +493,7 @@ void linphone_core_add_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *info) } /*proxy case*/ for (proxy=(bctbx_list_t*)linphone_core_get_proxy_config_list(lc);proxy!=NULL;proxy=proxy->next) { - if (proxy->data == op->get_user_pointer()) { + if (proxy->data == op->getUserPointer()) { linphone_proxy_config_set_state((LinphoneProxyConfig*)(proxy->data),LinphoneRegistrationProgress,"Authentication..."); break; } @@ -504,7 +502,7 @@ void linphone_core_add_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *info) restarted_op_count++; } } - if (l){ + if (!pendingAuths.empty()) { ms_message("linphone_core_add_auth_info(): restarted [%i] operation(s) after %s auth info for\n" "\tusername: [%s]\n" "\trealm [%s]\n" @@ -515,7 +513,6 @@ void linphone_core_add_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *info) info->realm ? info->realm : "", info->domain ? info->domain : ""); } - bctbx_list_free(l); write_auth_infos(lc); } diff --git a/coreapi/bellesip_sal/sal_impl.c b/coreapi/bellesip_sal/sal_impl.c index ad11525fb..bdf3683dd 100644 --- a/coreapi/bellesip_sal/sal_impl.c +++ b/coreapi/bellesip_sal/sal_impl.c @@ -348,6 +348,29 @@ void sal_body_handler_set_subtype(SalBodyHandler *body_handler, const char *subt belle_sip_header_content_type_set_subtype(content_type, subtype); } +const belle_sip_list_t * sal_body_handler_get_content_type_parameters_names(const SalBodyHandler *body_handler) { + belle_sip_header_content_type_t *content_type = BELLE_SIP_HEADER_CONTENT_TYPE(sal_body_handler_find_header(body_handler, "Content-Type")); + if (content_type != NULL) { + return belle_sip_parameters_get_parameter_names(BELLE_SIP_PARAMETERS(content_type)); + } + return NULL; +} + +const char * sal_body_handler_get_content_type_parameter(const SalBodyHandler *body_handler, const char *name) { + belle_sip_header_content_type_t *content_type = BELLE_SIP_HEADER_CONTENT_TYPE(sal_body_handler_find_header(body_handler, "Content-Type")); + if (content_type != NULL) { + return belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(content_type), name); + } + return NULL; +} + +void sal_body_handler_set_content_type_parameter(SalBodyHandler *body_handler, const char *paramName, const char *paramValue) { + belle_sip_header_content_type_t *content_type = BELLE_SIP_HEADER_CONTENT_TYPE(sal_body_handler_find_header(body_handler, "Content-Type")); + if (content_type != NULL) { + belle_sip_parameters_set_parameter(BELLE_SIP_PARAMETERS(content_type), paramName, paramValue); + } +} + const char * sal_body_handler_get_encoding(const SalBodyHandler *body_handler) { belle_sip_header_t *content_encoding = sal_body_handler_find_header(body_handler, "Content-Encoding"); if (content_encoding != NULL) { @@ -396,6 +419,11 @@ SalBodyHandler * sal_body_handler_get_part(const SalBodyHandler *body_handler, i return (SalBodyHandler *)belle_sip_list_nth_data(l, idx); } +const belle_sip_list_t * sal_body_handler_get_parts(const SalBodyHandler *body_handler) { + if (!sal_body_handler_is_multipart(body_handler)) return NULL; + return belle_sip_multipart_body_handler_get_parts(BELLE_SIP_MULTIPART_BODY_HANDLER(body_handler)); +} + SalBodyHandler * sal_body_handler_find_part_by_header(const SalBodyHandler *body_handler, const char *header_name, const char *header_value) { const belle_sip_list_t *l = belle_sip_multipart_body_handler_get_parts(BELLE_SIP_MULTIPART_BODY_HANDLER(body_handler)); for (; l != NULL; l = l->next) { @@ -418,3 +446,7 @@ const char * sal_body_handler_get_header(const SalBodyHandler *body_handler, con } return NULL; } + +const belle_sip_list_t* sal_body_handler_get_headers(const SalBodyHandler *body_handler) { + return belle_sip_body_handler_get_headers(BELLE_SIP_BODY_HANDLER(body_handler)); +} diff --git a/coreapi/bellesip_sal/sal_sdp.c b/coreapi/bellesip_sal/sal_sdp.c index ab3478fb6..9cd5a5ed8 100644 --- a/coreapi/bellesip_sal/sal_sdp.c +++ b/coreapi/bellesip_sal/sal_sdp.c @@ -486,7 +486,7 @@ static void sdp_parse_payload_types(belle_sdp_media_description_t *media_desc, S static void sdp_parse_media_crypto_parameters(belle_sdp_media_description_t *media_desc, SalStreamDescription *stream) { belle_sip_list_t *attribute_it; belle_sdp_attribute_t *attribute; - char tmp[256], tmp2[256], parameters[256]={0}; + char tmp[257], tmp2[257], parameters[257]={0}; int valid_count = 0; int nb; diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index da809bc05..eaa118ae1 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -17,14 +17,15 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ - #include "c-wrapper/internal/c-sal.h" #include "sal/call-op.h" #include "sal/message-op.h" #include "sal/refer-op.h" +#include "linphone/api/c-content.h" #include "linphone/core.h" #include "linphone/utils/utils.h" + #include "private.h" #include "mediastreamer2/mediastream.h" #include "linphone/lpconfig.h" @@ -41,6 +42,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "call/call-p.h" #include "chat/chat-message/chat-message-p.h" #include "chat/chat-room/chat-room.h" +#include "chat/chat-room/client-group-chat-room-p.h" #include "chat/chat-room/server-group-chat-room-p.h" #include "conference/participant.h" #include "conference/session/call-session-p.h" @@ -56,19 +58,26 @@ using namespace LinphonePrivate; static void register_failure(SalOp *op); static void call_received(SalCallOp *h) { + LinphoneCore *lc = reinterpret_cast(h->getSal()->getUserPointer()); + + if (linphone_core_get_global_state(lc) != LinphoneGlobalOn) { + h->decline(SalReasonServiceUnavailable, nullptr); + h->release(); + return; + } + /* Look if this INVITE is for a call that has already been notified but broken because of network failure */ - LinphoneCore *lc = reinterpret_cast(h->get_sal()->get_user_pointer()); if (L_GET_PRIVATE_FROM_C_OBJECT(lc)->inviteReplacesABrokenCall(h)) return; LinphoneAddress *fromAddr = nullptr; - const char *pAssertedId = sal_custom_header_find(h->get_recv_custom_header(), "P-Asserted-Identity"); + const char *pAssertedId = sal_custom_header_find(h->getRecvCustomHeaders(), "P-Asserted-Identity"); /* In some situation, better to trust the network rather than the UAC */ if (lp_config_get_int(linphone_core_get_config(lc), "sip", "call_logs_use_asserted_id_instead_of_from", 0)) { if (pAssertedId) { LinphoneAddress *pAssertedIdAddr = linphone_address_new(pAssertedId); if (pAssertedIdAddr) { - ms_message("Using P-Asserted-Identity [%s] instead of from [%s] for op [%p]", pAssertedId, h->get_from(), h); + ms_message("Using P-Asserted-Identity [%s] instead of from [%s] for op [%p]", pAssertedId, h->getFrom().c_str(), h); fromAddr = pAssertedIdAddr; } else ms_warning("Unsupported P-Asserted-Identity header for op [%p] ", h); @@ -77,22 +86,23 @@ static void call_received(SalCallOp *h) { } if (!fromAddr) - fromAddr = linphone_address_new(h->get_from()); - LinphoneAddress *toAddr = linphone_address_new(h->get_to()); + fromAddr = linphone_address_new(h->getFrom().c_str()); + LinphoneAddress *toAddr = linphone_address_new(h->getTo().c_str()); if (_linphone_core_is_conference_creation(lc, toAddr)) { linphone_address_unref(toAddr); linphone_address_unref(fromAddr); - if (sal_address_has_param(h->get_remote_contact_address(), "text")) { + if (sal_address_has_param(h->getRemoteContactAddress(), "text")) { bool oneToOneChatRoom = false; - const char *oneToOneChatRoomStr = sal_custom_header_find(h->get_recv_custom_header(), "One-To-One-Chat-Room"); + const char *oneToOneChatRoomStr = sal_custom_header_find(h->getRecvCustomHeaders(), "One-To-One-Chat-Room"); if (oneToOneChatRoomStr && (strcmp(oneToOneChatRoomStr, "true") == 0)) oneToOneChatRoom = true; if (oneToOneChatRoom) { - IdentityAddress from(h->get_from()); - list identAddresses = ServerGroupChatRoom::parseResourceLists(h->get_remote_body()); + IdentityAddress from(h->getFrom()); + list identAddresses = ServerGroupChatRoom::parseResourceLists(h->getRemoteBody()); if (identAddresses.size() != 1) { h->decline(SalReasonNotAcceptable, nullptr); + h->release(); return; } IdentityAddress confAddr = L_GET_PRIVATE_FROM_C_OBJECT(lc)->mainDb->findOneToOneConferenceChatRoomAddress(from, identAddresses.front()); @@ -106,17 +116,30 @@ static void call_received(SalCallOp *h) { } // TODO: handle media conference creation if the "text" feature tag is not present return; - } else if (sal_address_has_param(h->get_remote_contact_address(), "text")) { - shared_ptr chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom( - ChatRoomId(IdentityAddress(h->get_to()), IdentityAddress(h->get_to())) - ); - if (chatRoom) { - L_GET_PRIVATE(static_pointer_cast(chatRoom))->confirmJoining(h); - linphone_address_unref(toAddr); - linphone_address_unref(fromAddr); + } else if (sal_address_has_param(h->getRemoteContactAddress(), "text")) { + linphone_address_unref(toAddr); + linphone_address_unref(fromAddr); + if (linphone_core_conference_server_enabled(lc)) { + shared_ptr chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom( + ChatRoomId(IdentityAddress(h->getTo()), IdentityAddress(h->getTo())) + ); + if (chatRoom) { + L_GET_PRIVATE(static_pointer_cast(chatRoom))->confirmJoining(h); + } else { + //invite is for an unknown chatroom + h->decline(SalReasonNotFound, nullptr); + h->release(); + } } else { - //invite is for an unknown chatroom - h->decline(SalReasonNotFound, nullptr); + shared_ptr chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom( + ChatRoomId(IdentityAddress(h->getFrom()), IdentityAddress(h->getTo())) + ); + if (!chatRoom) { + chatRoom = L_GET_PRIVATE_FROM_C_OBJECT(lc)->createClientGroupChatRoom( + h->getSubject(), h->getRemoteContact(), h->getRemoteBody(), false + ); + } + L_GET_PRIVATE(static_pointer_cast(chatRoom))->confirmJoining(h); } return; } else { @@ -136,7 +159,7 @@ static void call_received(SalCallOp *h) { memset(&sei, 0, sizeof(sei)); sal_error_info_set(&sei, SalReasonRedirect, "SIP", 0, nullptr, nullptr); SalAddress *altAddr = sal_address_new(altContact); - h->decline_with_error_info(&sei, altAddr); + h->declineWithErrorInfo(&sei, altAddr); ms_free(altContact); sal_address_unref(altAddr); LinphoneErrorInfo *ei = linphone_error_info_new(); @@ -164,7 +187,7 @@ static void call_received(SalCallOp *h) { /* Check if I'm the caller */ LinphoneAddress *fromAddressToSearchIfMe = nullptr; - if (h->get_privacy() == SalPrivacyNone) + if (h->getPrivacy() == SalPrivacyNone) fromAddressToSearchIfMe = linphone_address_clone(fromAddr); else if (pAssertedId) fromAddressToSearchIfMe = linphone_address_new(pAssertedId); @@ -192,16 +215,17 @@ static void call_received(SalCallOp *h) { } static void call_rejected(SalCallOp *h){ - LinphoneCore *lc=(LinphoneCore *)h->get_sal()->get_user_pointer(); + LinphoneCore *lc = reinterpret_cast(h->getSal()->getUserPointer()); LinphoneErrorInfo *ei = linphone_error_info_new(); linphone_error_info_from_sal_op(ei, h); - linphone_core_report_early_failed_call(lc, LinphoneCallIncoming, linphone_address_new(h->get_from()), linphone_address_new(h->get_to()), ei); + linphone_core_report_early_failed_call(lc, LinphoneCallIncoming, linphone_address_new(h->getFrom().c_str()), linphone_address_new(h->getTo().c_str()), ei); } static void call_ringing(SalOp *h) { - LinphonePrivate::CallSession *session = reinterpret_cast(h->get_user_pointer()); + LinphonePrivate::CallSession *session = reinterpret_cast(h->getUserPointer()); if (!session) return; - L_GET_PRIVATE(session)->remoteRinging(); + auto sessionRef = session->getSharedFromThis(); + L_GET_PRIVATE(sessionRef)->remoteRinging(); } /* @@ -210,83 +234,89 @@ static void call_ringing(SalOp *h) { * - when a request is accepted (pause, resume) */ static void call_accepted(SalOp *op) { - LinphonePrivate::CallSession *session = reinterpret_cast(op->get_user_pointer()); + LinphonePrivate::CallSession *session = reinterpret_cast(op->getUserPointer()); if (!session) { ms_warning("call_accepted: CallSession no longer exists"); return; } - L_GET_PRIVATE(session)->accepted(); + auto sessionRef = session->getSharedFromThis(); + L_GET_PRIVATE(sessionRef)->accepted(); } /* this callback is called when an incoming re-INVITE/ SIP UPDATE modifies the session*/ static void call_updating(SalOp *op, bool_t is_update) { - LinphonePrivate::CallSession *session = reinterpret_cast(op->get_user_pointer()); + LinphonePrivate::CallSession *session = reinterpret_cast(op->getUserPointer()); if (!session) { ms_warning("call_updating: CallSession no longer exists"); return; } - L_GET_PRIVATE(session)->updating(!!is_update); + auto sessionRef = session->getSharedFromThis(); + L_GET_PRIVATE(sessionRef)->updating(!!is_update); } static void call_ack_received(SalOp *op, SalCustomHeader *ack) { - LinphonePrivate::CallSession *session = reinterpret_cast(op->get_user_pointer()); + LinphonePrivate::CallSession *session = reinterpret_cast(op->getUserPointer()); if (!session) { ms_warning("call_ack_received(): no CallSession for which an ack is expected"); return; } - L_GET_PRIVATE(session)->ackReceived(reinterpret_cast(ack)); + auto sessionRef = session->getSharedFromThis(); + L_GET_PRIVATE(sessionRef)->ackReceived(reinterpret_cast(ack)); } static void call_ack_being_sent(SalOp *op, SalCustomHeader *ack) { - LinphonePrivate::CallSession *session = reinterpret_cast(op->get_user_pointer()); + LinphonePrivate::CallSession *session = reinterpret_cast(op->getUserPointer()); if (!session) { ms_warning("call_ack_being_sent(): no CallSession for which an ack is supposed to be sent"); return; } - L_GET_PRIVATE(session)->ackBeingSent(reinterpret_cast(ack)); + auto sessionRef = session->getSharedFromThis(); + L_GET_PRIVATE(sessionRef)->ackBeingSent(reinterpret_cast(ack)); } static void call_terminated(SalOp *op, const char *from) { - LinphonePrivate::CallSession *session = reinterpret_cast(op->get_user_pointer()); + LinphonePrivate::CallSession *session = reinterpret_cast(op->getUserPointer()); if (!session) return; - L_GET_PRIVATE(session)->terminated(); + auto sessionRef = session->getSharedFromThis(); + L_GET_PRIVATE(sessionRef)->terminated(); } static void call_failure(SalOp *op) { - shared_ptr session; - if (op->get_user_pointer()) - session = reinterpret_cast(op->get_user_pointer())->getSharedFromThis(); + LinphonePrivate::CallSession *session = reinterpret_cast(op->getUserPointer()); if (!session) { ms_warning("Failure reported on already terminated CallSession"); return; } - L_GET_PRIVATE(session)->failure(); + auto sessionRef = session->getSharedFromThis(); + L_GET_PRIVATE(sessionRef)->failure(); } static void call_released(SalOp *op) { - LinphonePrivate::CallSession *session = reinterpret_cast(op->get_user_pointer()); + LinphonePrivate::CallSession *session = reinterpret_cast(op->getUserPointer()); if (!session) { /* We can get here when the core manages call at Sal level without creating a Call object. Typicially, * when declining an incoming call with busy because maximum number of calls is reached. */ return; } - L_GET_PRIVATE(session)->setState(LinphonePrivate::CallSession::State::Released, "Call released"); + auto sessionRef = session->getSharedFromThis(); + L_GET_PRIVATE(sessionRef)->setState(LinphonePrivate::CallSession::State::Released, "Call released"); } static void call_cancel_done(SalOp *op) { - LinphonePrivate::CallSession *session = reinterpret_cast(op->get_user_pointer()); + LinphonePrivate::CallSession *session = reinterpret_cast(op->getUserPointer()); if (!session) { ms_warning("Cancel done reported on already terminated CallSession"); return; } - L_GET_PRIVATE(session)->cancelDone(); + auto sessionRef = session->getSharedFromThis(); + L_GET_PRIVATE(sessionRef)->cancelDone(); } static void auth_failure(SalOp *op, SalAuthInfo* info) { - LinphoneCore *lc = reinterpret_cast(op->get_sal()->get_user_pointer()); + LinphoneCore *lc = reinterpret_cast(op->getSal()->getUserPointer()); LinphoneAuthInfo *ai = NULL; if (info != NULL) { @@ -305,7 +335,7 @@ static void auth_failure(SalOp *op, SalAuthInfo* info) { } static void register_success(SalOp *op, bool_t registered){ - LinphoneProxyConfig *cfg=(LinphoneProxyConfig *)op->get_user_pointer(); + LinphoneProxyConfig *cfg=(LinphoneProxyConfig *)op->getUserPointer(); if (!cfg){ ms_message("Registration success for deleted proxy config, ignored"); return; @@ -315,8 +345,8 @@ static void register_success(SalOp *op, bool_t registered){ } static void register_failure(SalOp *op){ - LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)op->get_user_pointer(); - const SalErrorInfo *ei=op->get_error_info(); + LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)op->getUserPointer(); + const SalErrorInfo *ei=op->getErrorInfo(); const char *details=ei->full_string; if (cfg==NULL){ @@ -341,48 +371,57 @@ static void register_failure(SalOp *op){ } static void vfu_request(SalOp *op) { - LinphonePrivate::CallSession *session = reinterpret_cast(op->get_user_pointer()); + LinphonePrivate::CallSession *session = reinterpret_cast(op->getUserPointer()); if (!session) return; - LinphonePrivate::MediaSession *mediaSession = dynamic_cast(session); - if (!mediaSession) { + auto sessionRef = session->getSharedFromThis(); + auto mediaSessionRef = dynamic_pointer_cast(sessionRef); + if (!mediaSessionRef) { ms_warning("VFU request but no MediaSession!"); return; } - L_GET_PRIVATE(mediaSession)->sendVfu(); + L_GET_PRIVATE(mediaSessionRef)->sendVfu(); } static void dtmf_received(SalOp *op, char dtmf) { - LinphonePrivate::CallSession *session = reinterpret_cast(op->get_user_pointer()); + LinphonePrivate::CallSession *session = reinterpret_cast(op->getUserPointer()); if (!session) return; - LinphonePrivate::MediaSession *mediaSession = dynamic_cast(session); - if (!mediaSession) { + auto sessionRef = session->getSharedFromThis(); + auto mediaSessionRef = dynamic_pointer_cast(sessionRef); + if (!mediaSessionRef) { ms_warning("DTMF received but no MediaSession!"); return; } - L_GET_PRIVATE(mediaSession)->dtmfReceived(dtmf); + L_GET_PRIVATE(mediaSessionRef)->dtmfReceived(dtmf); } static void call_refer_received(SalOp *op, const SalAddress *referTo) { - LinphonePrivate::CallSession *session = reinterpret_cast(op->get_user_pointer()); + LinphonePrivate::CallSession *session = reinterpret_cast(op->getUserPointer()); char *addrStr = sal_address_as_string_uri_only(referTo); Address referToAddr(addrStr); string method; if (referToAddr.isValid()) method = referToAddr.getMethodParam(); if (session && (method.empty() || (method == "INVITE"))) { - L_GET_PRIVATE(session)->referred(referToAddr); + auto sessionRef = session->getSharedFromThis(); + L_GET_PRIVATE(sessionRef)->referred(referToAddr); } else { - LinphoneCore *lc = reinterpret_cast(op->get_sal()->get_user_pointer()); + LinphoneCore *lc = reinterpret_cast(op->getSal()->getUserPointer()); linphone_core_notify_refer_received(lc, addrStr); } bctbx_free(addrStr); } static void message_received(SalOp *op, const SalMessage *msg){ - LinphoneCore *lc=(LinphoneCore *)op->get_sal()->get_user_pointer(); - LinphoneCall *call=(LinphoneCall*)op->get_user_pointer(); + LinphoneCore *lc=(LinphoneCore *)op->getSal()->getUserPointer(); + + if (linphone_core_get_global_state(lc) != LinphoneGlobalOn) { + static_cast(op)->reply(SalReasonServiceUnavailable); + return; + } + + LinphoneCall *call=(LinphoneCall*)op->getUserPointer(); LinphoneReason reason = lc->chat_deny_code; if (reason == LinphoneReasonNone) { linphone_core_message_received(lc, op, msg); @@ -408,27 +447,32 @@ static void convert_presence_to_xml_requested(SalOp *op, SalPresenceModel *prese } static void notify_presence(SalOp *op, SalSubscribeStatus ss, SalPresenceModel *model, const char *msg){ - LinphoneCore *lc=(LinphoneCore *)op->get_sal()->get_user_pointer(); + LinphoneCore *lc=(LinphoneCore *)op->getSal()->getUserPointer(); linphone_notify_recv(lc,op,ss,model); } static void subscribe_presence_received(SalPresenceOp *op, const char *from){ - LinphoneCore *lc=(LinphoneCore *)op->get_sal()->get_user_pointer(); + LinphoneCore *lc=(LinphoneCore *)op->getSal()->getUserPointer(); + if (linphone_core_get_global_state(lc) != LinphoneGlobalOn) { + op->decline(SalReasonServiceUnavailable); + return; + } linphone_subscription_new(lc,op,from); } static void subscribe_presence_closed(SalPresenceOp *op, const char *from){ - LinphoneCore *lc=(LinphoneCore *)op->get_sal()->get_user_pointer(); + LinphoneCore *lc=(LinphoneCore *)op->getSal()->getUserPointer(); linphone_subscription_closed(lc,op); } static void ping_reply(SalOp *op) { - LinphonePrivate::CallSession *session = reinterpret_cast(op->get_user_pointer()); + LinphonePrivate::CallSession *session = reinterpret_cast(op->getUserPointer()); if (!session) { ms_warning("Ping reply without CallSession attached..."); return; } - L_GET_PRIVATE(session)->pingReply(); + auto sessionRef = session->getSharedFromThis(); + L_GET_PRIVATE(sessionRef)->pingReply(); } static bool_t fill_auth_info_with_client_certificate(LinphoneCore *lc, SalAuthInfo* sai) { @@ -508,7 +552,7 @@ static bool_t fill_auth_info(LinphoneCore *lc, SalAuthInfo* sai) { } } static bool_t auth_requested(Sal* sal, SalAuthInfo* sai) { - LinphoneCore *lc = (LinphoneCore *)sal->get_user_pointer(); + LinphoneCore *lc = (LinphoneCore *)sal->getUserPointer(); if (fill_auth_info(lc,sai)) { return TRUE; } else { @@ -526,11 +570,12 @@ static bool_t auth_requested(Sal* sal, SalAuthInfo* sai) { } static void notify_refer(SalOp *op, SalReferStatus status) { - LinphonePrivate::CallSession *session = reinterpret_cast(op->get_user_pointer()); + LinphonePrivate::CallSession *session = reinterpret_cast(op->getUserPointer()); if (!session) { ms_warning("Receiving notify_refer for unknown CallSession"); return; } + auto sessionRef = session->getSharedFromThis(); LinphonePrivate::CallSession::State cstate; switch (status) { case SalReferTrying: @@ -544,9 +589,9 @@ static void notify_refer(SalOp *op, SalReferStatus status) { cstate = LinphonePrivate::CallSession::State::Error; break; } - L_GET_PRIVATE(session)->setTransferState(cstate); + L_GET_PRIVATE(sessionRef)->setTransferState(cstate); if (cstate == LinphonePrivate::CallSession::State::Connected) - session->terminate(); // Automatically terminate the call as the transfer is complete + sessionRef->terminate(); // Automatically terminate the call as the transfer is complete } static LinphoneChatMessageState chatStatusSal2Linphone(SalMessageDeliveryStatus status){ @@ -562,7 +607,13 @@ static LinphoneChatMessageState chatStatusSal2Linphone(SalMessageDeliveryStatus } static void message_delivery_update(SalOp *op, SalMessageDeliveryStatus status) { - LinphonePrivate::ChatMessage *msg = reinterpret_cast(op->get_user_pointer()); + auto lc = reinterpret_cast(op->getSal()->getUserPointer()); + if (linphone_core_get_global_state(lc) != LinphoneGlobalOn) { + static_cast(op)->reply(SalReasonDeclined); + return; + } + + LinphonePrivate::ChatMessage *msg = reinterpret_cast(op->getUserPointer()); if (!msg) return; // Do not handle delivery status for isComposing messages. @@ -572,14 +623,15 @@ static void message_delivery_update(SalOp *op, SalMessageDeliveryStatus status) } static void info_received(SalOp *op, SalBodyHandler *body_handler) { - LinphonePrivate::CallSession *session = reinterpret_cast(op->get_user_pointer()); + LinphonePrivate::CallSession *session = reinterpret_cast(op->getUserPointer()); if (!session) return; - L_GET_PRIVATE(session)->infoReceived(body_handler); + auto sessionRef = session->getSharedFromThis(); + L_GET_PRIVATE(sessionRef)->infoReceived(body_handler); } static void subscribe_response(SalOp *op, SalSubscribeStatus status, int will_retry){ - LinphoneEvent *lev=(LinphoneEvent*)op->get_user_pointer(); + LinphoneEvent *lev=(LinphoneEvent*)op->getUserPointer(); if (lev==NULL) return; @@ -596,15 +648,15 @@ static void subscribe_response(SalOp *op, SalSubscribeStatus status, int will_re } static void notify(SalSubscribeOp *op, SalSubscribeStatus st, const char *eventname, SalBodyHandler *body_handler){ - LinphoneEvent *lev=(LinphoneEvent*)op->get_user_pointer(); - LinphoneCore *lc=(LinphoneCore *)op->get_sal()->get_user_pointer(); + LinphoneEvent *lev=(LinphoneEvent*)op->getUserPointer(); + LinphoneCore *lc=(LinphoneCore *)op->getSal()->getUserPointer(); bool_t out_of_dialog = (lev==NULL); if (out_of_dialog) { /*out of dialog notify */ lev = linphone_event_new_with_out_of_dialog_op(lc,op,LinphoneSubscriptionOutgoing,eventname); } { - LinphoneContent *ct=linphone_content_from_sal_body_handler(body_handler); + LinphoneContent *ct = linphone_content_from_sal_body_handler(body_handler); if (ct) { linphone_core_notify_notify_received(lc,lev,eventname,ct); linphone_content_unref(ct); @@ -619,27 +671,36 @@ static void notify(SalSubscribeOp *op, SalSubscribeStatus st, const char *eventn } static void subscribe_received(SalSubscribeOp *op, const char *eventname, const SalBodyHandler *body_handler){ - LinphoneEvent *lev=(LinphoneEvent*)op->get_user_pointer(); - LinphoneCore *lc=(LinphoneCore *)op->get_sal()->get_user_pointer(); + LinphoneEvent *lev=(LinphoneEvent*)op->getUserPointer(); + LinphoneCore *lc=(LinphoneCore *)op->getSal()->getUserPointer(); + + if (linphone_core_get_global_state(lc) != LinphoneGlobalOn) { + op->decline(SalReasonServiceUnavailable); + return; + } if (lev==NULL) { lev=linphone_event_new_with_op(lc,op,LinphoneSubscriptionIncoming,eventname); linphone_event_set_state(lev,LinphoneSubscriptionIncomingReceived); - }else{ + LinphoneContent *ct = linphone_content_from_sal_body_handler(body_handler); + linphone_core_notify_subscribe_received(lc,lev,eventname,ct); + if (ct) + linphone_content_unref(ct); + } else { /*subscribe refresh, unhandled*/ } } static void incoming_subscribe_closed(SalOp *op){ - LinphoneEvent *lev=(LinphoneEvent*)op->get_user_pointer(); + LinphoneEvent *lev=(LinphoneEvent*)op->getUserPointer(); linphone_event_set_state(lev,LinphoneSubscriptionTerminated); } static void on_publish_response(SalOp* op){ - LinphoneEvent *lev=(LinphoneEvent*)op->get_user_pointer(); - const SalErrorInfo *ei=op->get_error_info(); + LinphoneEvent *lev=(LinphoneEvent*)op->getUserPointer(); + const SalErrorInfo *ei=op->getErrorInfo(); if (lev==NULL) return; if (ei->reason==SalReasonNone){ @@ -658,7 +719,7 @@ static void on_publish_response(SalOp* op){ static void on_expire(SalOp *op){ - LinphoneEvent *lev=(LinphoneEvent*)op->get_user_pointer(); + LinphoneEvent *lev=(LinphoneEvent*)op->getUserPointer(); if (lev==NULL) return; @@ -670,14 +731,14 @@ static void on_expire(SalOp *op){ } static void on_notify_response(SalOp *op){ - LinphoneEvent *lev=(LinphoneEvent*)op->get_user_pointer(); + LinphoneEvent *lev=(LinphoneEvent*)op->getUserPointer(); if (!lev) return; if (lev->is_out_of_dialog_op) { switch (linphone_event_get_subscription_state(lev)) { case LinphoneSubscriptionIncomingReceived: - if (op->get_error_info()->reason == SalReasonNone) + if (op->getErrorInfo()->reason == SalReasonNone) linphone_event_set_state(lev, LinphoneSubscriptionTerminated); else linphone_event_set_state(lev, LinphoneSubscriptionError); @@ -699,15 +760,21 @@ static void refer_received(SalOp *op, const SalAddress *refer_to){ LinphonePrivate::Address addr(refer_uri); bctbx_free(refer_uri); if (addr.isValid()) { - LinphoneCore *lc = reinterpret_cast(op->get_sal()->get_user_pointer()); + LinphoneCore *lc = reinterpret_cast(op->getSal()->getUserPointer()); + + if (linphone_core_get_global_state(lc) != LinphoneGlobalOn) { + static_cast(op)->reply(SalReasonDeclined); + return; + } + if (addr.hasUriParam("method") && (addr.getUriParamValue("method") == "BYE")) { if (linphone_core_conference_server_enabled(lc)) { // Removal of a participant at the server side shared_ptr chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom( - ChatRoomId(IdentityAddress(op->get_to()), IdentityAddress(op->get_to())) + ChatRoomId(IdentityAddress(op->getTo()), IdentityAddress(op->getTo())) ); if (chatRoom) { - std::shared_ptr participant = chatRoom->findParticipant(IdentityAddress(op->get_from())); + std::shared_ptr participant = chatRoom->findParticipant(IdentityAddress(op->getFrom())); if (!participant || !participant->isAdmin()) { static_cast(op)->reply(SalReasonDeclined); return; @@ -721,7 +788,7 @@ static void refer_received(SalOp *op, const SalAddress *refer_to){ } else { // The server asks a participant to leave a chat room LinphoneChatRoom *cr = L_GET_C_BACK_PTR( - L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom(ChatRoomId(addr, IdentityAddress(op->get_to()))) + L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom(ChatRoomId(addr, IdentityAddress(op->getTo()))) ); if (cr) { L_GET_CPP_PTR_FROM_C_OBJECT(cr)->leave(); @@ -730,34 +797,51 @@ static void refer_received(SalOp *op, const SalAddress *refer_to){ } static_cast(op)->reply(SalReasonDeclined); } - } else if (addr.hasParam("admin")) { - LinphoneChatRoom *cr = L_GET_C_BACK_PTR(L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom( - ChatRoomId(IdentityAddress(op->get_to()), IdentityAddress(op->get_to())) - )); - if (cr) { - Address fromAddr(op->get_from()); - std::shared_ptr participant = L_GET_CPP_PTR_FROM_C_OBJECT(cr)->findParticipant(fromAddr); - if (!participant || !participant->isAdmin()) { - static_cast(op)->reply(SalReasonDeclined); - return; - } - participant = L_GET_CPP_PTR_FROM_C_OBJECT(cr)->findParticipant(addr); - if (participant) { - bool value = Utils::stob(addr.getParamValue("admin")); - L_GET_CPP_PTR_FROM_C_OBJECT(cr)->setParticipantAdminStatus(participant, value); + } else { + if (linphone_core_conference_server_enabled(lc)) { + shared_ptr chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom( + ChatRoomId(IdentityAddress(op->getTo()), IdentityAddress(op->getTo())) + ); + LinphoneChatRoom *cr = L_GET_C_BACK_PTR(chatRoom); + if (cr) { + Address fromAddr(op->getFrom()); + shared_ptr participant = chatRoom->findParticipant(fromAddr); + if (!participant || !participant->isAdmin()) { + static_cast(op)->reply(SalReasonDeclined); + return; + } + if (addr.hasParam("admin")) { + participant = chatRoom->findParticipant(addr); + if (participant) { + bool value = Utils::stob(addr.getParamValue("admin")); + chatRoom->setParticipantAdminStatus(participant, value); + static_cast(op)->reply(SalReasonNone); + return; + } + } else { + participant = L_GET_PRIVATE(static_pointer_cast(chatRoom))->findFilteredParticipant(addr); + if (!participant) { + list identAddresses; + identAddresses.push_back(addr); + L_GET_PRIVATE(static_pointer_cast(chatRoom))->checkCompatibleParticipants( + IdentityAddress(op->getRemoteContact()), + identAddresses + ); + static_cast(op)->reply(SalReasonNone); + return; + } + } } + } else { + shared_ptr chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom( + ChatRoomId(addr, IdentityAddress(op->getTo())) + ); + if (!chatRoom) + chatRoom = L_GET_PRIVATE_FROM_C_OBJECT(lc)->createClientGroupChatRoom("", addr.asString(), Content(), false); + chatRoom->join(); static_cast(op)->reply(SalReasonNone); return; } - } else { - shared_ptr chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom( - ChatRoomId(addr, IdentityAddress(op->get_to())) - ); - if (!chatRoom) - chatRoom = L_GET_PRIVATE_FROM_C_OBJECT(lc)->createClientGroupChatRoom("", addr.asString(), false); - chatRoom->join(); - static_cast(op)->reply(SalReasonNone); - return; } } } diff --git a/coreapi/carddav.c b/coreapi/carddav.c index 880d778e2..912da2b87 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -573,7 +573,7 @@ static char* generate_url_from_server_address_and_uid(const char *server_url) { char *result = NULL; if (server_url) { char *uuid = reinterpret_cast(ms_malloc(64)); - if (LinphonePrivate::Sal::generate_uuid(uuid, 64) == 0) { + if (LinphonePrivate::Sal::generateUuid(uuid, 64) == 0) { char *url = reinterpret_cast(ms_malloc(300)); snprintf(url, 300, "%s/linphone-%s.vcf", server_url, uuid); ms_debug("Generated url is %s", url); diff --git a/coreapi/chat.c b/coreapi/chat.c index ac9c8dcf0..df42841ee 100644 --- a/coreapi/chat.c +++ b/coreapi/chat.c @@ -69,7 +69,7 @@ const bctbx_list_t *linphone_core_get_chat_rooms (LinphoneCore *lc) { static LinphoneChatRoom *linphone_chat_room_new (LinphoneCore *core, const LinphoneAddress *addr) { return L_GET_C_BACK_PTR(L_GET_CPP_PTR_FROM_C_OBJECT(core)->getOrCreateBasicChatRoom( *L_GET_CPP_PTR_FROM_C_OBJECT(addr), - linphone_core_realtime_text_enabled(core) + !!linphone_core_realtime_text_enabled(core) )); } @@ -84,8 +84,8 @@ LinphoneChatRoom *linphone_core_get_chat_room (LinphoneCore *lc, const LinphoneA return L_GET_C_BACK_PTR(L_GET_CPP_PTR_FROM_C_OBJECT(lc)->getOrCreateBasicChatRoom(*L_GET_CPP_PTR_FROM_C_OBJECT(addr))); } -LinphoneChatRoom *linphone_core_create_client_group_chat_room (LinphoneCore *lc, const char *subject) { - return L_GET_C_BACK_PTR(L_GET_CPP_PTR_FROM_C_OBJECT(lc)->createClientGroupChatRoom(L_C_TO_STRING(subject))); +LinphoneChatRoom *linphone_core_create_client_group_chat_room (LinphoneCore *lc, const char *subject, bool_t fallback) { + return L_GET_C_BACK_PTR(L_GET_CPP_PTR_FROM_C_OBJECT(lc)->createClientGroupChatRoom(L_C_TO_STRING(subject), !!fallback)); } LinphoneChatRoom *_linphone_core_create_server_group_chat_room (LinphoneCore *lc, LinphonePrivate::SalCallOp *op) { @@ -124,13 +124,13 @@ LinphoneChatRoom *linphone_core_find_one_to_one_chat_room ( int linphone_core_message_received(LinphoneCore *lc, LinphonePrivate::SalOp *op, const SalMessage *sal_msg) { LinphoneReason reason = LinphoneReasonNotAcceptable; - const char *peerAddress; - const char *localAddress; + std::string peerAddress; + std::string localAddress; if (linphone_core_conference_server_enabled(lc)) { - localAddress = peerAddress = op->get_to(); + localAddress = peerAddress = op->getTo(); } else { - peerAddress = op->get_from(); - localAddress = op->get_to(); + peerAddress = op->getFrom(); + localAddress = op->getTo(); } shared_ptr chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom( diff --git a/coreapi/conference.cc b/coreapi/conference.cc index b9e91d4b3..06b35378a 100644 --- a/coreapi/conference.cc +++ b/coreapi/conference.cc @@ -685,9 +685,12 @@ void LocalConference::onCallTerminating (LinphoneCall *call) { ms_message("conference_check_uninit(): size=%i", getSize()); if ((remote_count == 1) && !m_terminating) convertConferenceToCall(); + if (remote_count == 0) { - if (m_localParticipantStream) + if (m_localParticipantStream){ removeLocalEndpoint(); + linphone_core_soundcard_hint_check(m_core); + } if (m_recordEndpoint) { ms_audio_conference_remove_member(m_conf, m_recordEndpoint); ms_audio_endpoint_destroy(m_recordEndpoint); diff --git a/coreapi/content.c b/coreapi/content.c deleted file mode 100644 index 8d20964bd..000000000 --- a/coreapi/content.c +++ /dev/null @@ -1,243 +0,0 @@ -/* -linphone -Copyright (C) 2010-2014 Belledonne Communications SARL - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#include "linphone/core.h" - -#include "c-wrapper/c-wrapper.h" - -// TODO: From coreapi. Remove me later. -#include "private.h" - -static void linphone_content_set_sal_body_handler(LinphoneContent *content, SalBodyHandler *body_handler) { - if (content->body_handler != NULL) { - sal_body_handler_unref(content->body_handler); - content->body_handler = NULL; - } - content->body_handler = sal_body_handler_ref(body_handler); -} - -static LinphoneContent * linphone_content_new_with_body_handler(SalBodyHandler *body_handler) { - LinphoneContent *content = belle_sip_object_new(LinphoneContent); - belle_sip_object_ref(content); - content->owned_fields = TRUE; - content->cryptoContext = NULL; /* this field is managed externally by encryption/decryption functions so be careful to initialise it to NULL */ - if (body_handler == NULL) { - linphone_content_set_sal_body_handler(content, sal_body_handler_new()); - } else { - linphone_content_set_sal_body_handler(content, body_handler); - } - return content; -} - -static void linphone_content_destroy(LinphoneContent *content) { - if (content->owned_fields == TRUE) { - if (content->body_handler) sal_body_handler_unref(content->body_handler); - if (content->name) belle_sip_free(content->name); - if (content->key) belle_sip_free(content->key); - /* note : crypto context is allocated/destroyed by the encryption function */ - } -} - -static void linphone_content_clone(LinphoneContent *obj, const LinphoneContent *ref) { - obj->owned_fields = TRUE; - linphone_content_set_sal_body_handler(obj, sal_body_handler_new()); - if ((linphone_content_get_type(ref) != NULL) || (linphone_content_get_subtype(ref) != NULL)) { - linphone_content_set_type(obj, linphone_content_get_type(ref)); - linphone_content_set_subtype(obj, linphone_content_get_subtype(ref)); - } - if (linphone_content_get_encoding(ref) != NULL) { - linphone_content_set_encoding(obj, linphone_content_get_encoding(ref)); - } - linphone_content_set_name(obj, linphone_content_get_name(ref)); - linphone_content_set_key(obj, linphone_content_get_key(ref), linphone_content_get_key_size(ref)); - if (linphone_content_get_buffer(ref) != NULL) { - linphone_content_set_buffer(obj, linphone_content_get_buffer(ref), linphone_content_get_size(ref)); - } else { - linphone_content_set_size(obj, linphone_content_get_size(ref)); - } -} - - -BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneContent); - -BELLE_SIP_INSTANCIATE_VPTR(LinphoneContent, belle_sip_object_t, - (belle_sip_object_destroy_t)linphone_content_destroy, - (belle_sip_object_clone_t)linphone_content_clone, - NULL, // marshal - TRUE -); - - -LinphoneContent * linphone_core_create_content(LinphoneCore *lc) { - return linphone_content_new(); -} - -LinphoneContent * linphone_content_ref(LinphoneContent *content) { - belle_sip_object_ref(content); - return content; -} - -void linphone_content_unref(LinphoneContent *content) { - belle_sip_object_unref(content); -} - -void *linphone_content_get_user_data(const LinphoneContent *content) { - return content->user_data; -} - -void linphone_content_set_user_data(LinphoneContent *content, void *ud) { - content->user_data = ud; -} - -const char * linphone_content_get_type(const LinphoneContent *content) { - return sal_body_handler_get_type(content->body_handler); -} - -void linphone_content_set_type(LinphoneContent *content, const char *type) { - sal_body_handler_set_type(content->body_handler, type); -} - -const char * linphone_content_get_subtype(const LinphoneContent *content) { - return sal_body_handler_get_subtype(content->body_handler); -} - -void linphone_content_set_subtype(LinphoneContent *content, const char *subtype) { - sal_body_handler_set_subtype(content->body_handler, subtype); -} - -uint8_t * linphone_content_get_buffer(const LinphoneContent *content) { - return (uint8_t *)sal_body_handler_get_data(content->body_handler); -} - -void linphone_content_set_buffer(LinphoneContent *content, const uint8_t *buffer, size_t size) { - void *data; - sal_body_handler_set_size(content->body_handler, size); - data = belle_sip_malloc(size + 1); - memcpy(data, buffer, size); - ((char *)data)[size] = '\0'; - sal_body_handler_set_data(content->body_handler, data); -} - -const char * linphone_content_get_string_buffer(const LinphoneContent *content) { - return (const char *)linphone_content_get_buffer(content); -} - -void linphone_content_set_string_buffer(LinphoneContent *content, const char *buffer) { - sal_body_handler_set_size(content->body_handler, strlen(buffer)); - sal_body_handler_set_data(content->body_handler, belle_sip_strdup(buffer)); -} - -size_t linphone_content_get_size(const LinphoneContent *content) { - return sal_body_handler_get_size(content->body_handler); -} - -void linphone_content_set_size(LinphoneContent *content, size_t size) { - sal_body_handler_set_size(content->body_handler, size); -} - -const char * linphone_content_get_encoding(const LinphoneContent *content) { - return sal_body_handler_get_encoding(content->body_handler); -} - -void linphone_content_set_encoding(LinphoneContent *content, const char *encoding) { - sal_body_handler_set_encoding(content->body_handler, encoding); -} - -const char * linphone_content_get_name(const LinphoneContent *content) { - return content->name; -} - -void linphone_content_set_name(LinphoneContent *content, const char *name) { - if (content->name != NULL) { - belle_sip_free(content->name); - content->name = NULL; - } - if (name != NULL) { - content->name = belle_sip_strdup(name); - } -} - -size_t linphone_content_get_key_size(const LinphoneContent *content) { - return content->keyLength; -} - -const char * linphone_content_get_key(const LinphoneContent *content) { - return content->key; -} - -void linphone_content_set_key(LinphoneContent *content, const char *key, const size_t keyLength) { - if (content->key != NULL) { - belle_sip_free(content->key); - content->key = NULL; - } - if (key != NULL) { - content->key = reinterpret_cast(belle_sip_malloc(keyLength + 1)); - memcpy(content->key, key, keyLength); - content->key[keyLength] = '\0'; - content->keyLength = keyLength; - } -} - -/* crypto context is managed(allocated/freed) by the encryption function, so provide the address of field in the private structure */ -void ** linphone_content_get_cryptoContext_address(LinphoneContent *content) { - return &(content->cryptoContext); -} - -bool_t linphone_content_is_multipart(const LinphoneContent *content) { - return sal_body_handler_is_multipart(content->body_handler); -} - -LinphoneContent * linphone_content_get_part(const LinphoneContent *content, int idx) { - SalBodyHandler *part_body_handler; - if (!linphone_content_is_multipart(content)) return NULL; - part_body_handler = sal_body_handler_get_part(content->body_handler, idx); - return linphone_content_from_sal_body_handler(part_body_handler); -} - -LinphoneContent * linphone_content_find_part_by_header(const LinphoneContent *content, const char *header_name, const char *header_value) { - SalBodyHandler *part_body_handler; - if (!linphone_content_is_multipart(content)) return NULL; - part_body_handler = sal_body_handler_find_part_by_header(content->body_handler, header_name, header_value); - return linphone_content_from_sal_body_handler(part_body_handler); -} - -const char * linphone_content_get_custom_header(const LinphoneContent *content, const char *header_name) { - return sal_body_handler_get_header(content->body_handler, header_name); -} - - -LinphoneContent * linphone_content_new(void) { - return linphone_content_new_with_body_handler(NULL); -} - -LinphoneContent * linphone_content_copy(const LinphoneContent *ref) { - return (LinphoneContent *)belle_sip_object_ref(belle_sip_object_clone(BELLE_SIP_OBJECT(ref))); -} - -LinphoneContent * linphone_content_from_sal_body_handler(SalBodyHandler *body_handler) { - if (body_handler) { - return linphone_content_new_with_body_handler(body_handler); - } - return NULL; -} - -SalBodyHandler * sal_body_handler_from_content(const LinphoneContent *content) { - if (content == NULL) return NULL; - return content->body_handler; -} diff --git a/coreapi/error_info.c b/coreapi/error_info.c index a4c29c7f3..fe619e4df 100644 --- a/coreapi/error_info.c +++ b/coreapi/error_info.c @@ -207,9 +207,9 @@ void linphone_error_info_from_sal_op(LinphoneErrorInfo *ei, const LinphonePrivat }else{ const SalErrorInfo *sei; linphone_error_info_reset(ei); - sei = op->get_error_info(); + sei = op->getErrorInfo(); linphone_error_info_from_sal(ei, sei); - sei = op->get_reason_error_info(); + sei = op->getReasonErrorInfo(); linphone_error_info_from_sal_reason_ei(ei, sei); } } diff --git a/coreapi/event.c b/coreapi/event.c index 582774843..ade697ab0 100644 --- a/coreapi/event.c +++ b/coreapi/event.c @@ -119,7 +119,7 @@ void linphone_event_cbs_set_notify_response(LinphoneEventCbs *cbs, LinphoneEvent static void linphone_event_release(LinphoneEvent *lev){ if (lev->op) { /*this will stop the refresher*/ - lev->op->stop_refreshing(); + lev->op->stopRefreshing(); } linphone_event_unref(lev); } @@ -133,7 +133,7 @@ static LinphoneEvent * linphone_event_new_base(LinphoneCore *lc, LinphoneSubscri lev->name=ms_strdup(name); if (strcmp(lev->name, "conference") == 0) lev->internal = TRUE; - lev->op->set_user_pointer(lev); + lev->op->setUserPointer(lev); return lev; } @@ -221,7 +221,7 @@ LinphoneReason linphone_event_get_reason(const LinphoneEvent *lev){ LinphoneEvent *linphone_core_create_subscribe(LinphoneCore *lc, const LinphoneAddress *resource, const char *event, int expires){ LinphoneEvent *lev=linphone_event_new(lc, LinphoneSubscriptionOutgoing, event, expires); linphone_configure_op(lc,lev->op,resource,NULL,TRUE); - lev->op->set_manual_refresher_mode(!lp_config_get_int(lc->config,"sip","refresh_generic_subscribe",1)); + lev->op->setManualRefresherMode(!lp_config_get_int(lc->config,"sip","refresh_generic_subscribe",1)); return lev; } @@ -229,7 +229,7 @@ LinphoneEvent *linphone_core_create_notify(LinphoneCore *lc, const LinphoneAddre LinphoneEvent *lev=linphone_event_new(lc, LinphoneSubscriptionIncoming, event, -1); linphone_configure_op(lc,lev->op,resource,NULL,TRUE); lev->subscription_state = LinphoneSubscriptionIncomingReceived; - lev->op->set_event(event); + lev->op->setEvent(event); lev->is_out_of_dialog_op = TRUE; return lev; } @@ -265,10 +265,10 @@ LinphoneStatus linphone_event_send_subscribe(LinphoneEvent *lev, const LinphoneC } if (lev->send_custom_headers){ - lev->op->set_sent_custom_header(lev->send_custom_headers); + lev->op->setSentCustomHeaders(lev->send_custom_headers); sal_custom_header_free(lev->send_custom_headers); lev->send_custom_headers=NULL; - }else lev->op->set_sent_custom_header(NULL); + }else lev->op->setSentCustomHeaders(NULL); body_handler = sal_body_handler_from_content(body); auto subscribeOp = dynamic_cast(lev->op); @@ -324,7 +324,7 @@ LinphoneStatus linphone_event_notify(LinphoneEvent *lev, const LinphoneContent * ms_error("linphone_event_notify(): cannot notify if not an incoming subscription."); return -1; } - body_handler = sal_body_handler_from_content(body); + body_handler = sal_body_handler_from_content(body, false); auto subscribeOp = dynamic_cast(lev->op); return subscribeOp->notify(body_handler); } @@ -347,7 +347,7 @@ static LinphoneEvent *_linphone_core_create_publish(LinphoneCore *core, Linphone lev = linphone_event_new_with_op(lc, new SalPublishOp(lc->sal), LinphoneSubscriptionInvalidDir, event); lev->expires = expires; linphone_configure_op_with_proxy(lc,lev->op,resource,NULL, !!lp_config_get_int(lc->config,"sip","publish_msg_with_contact",0),cfg); - lev->op->set_manual_refresher_mode(!lp_config_get_int(lc->config,"sip","refresh_generic_publish",1)); + lev->op->setManualRefresherMode(!lp_config_get_int(lc->config,"sip","refresh_generic_publish",1)); return lev; } LinphoneEvent *linphone_core_create_publish(LinphoneCore *lc, const LinphoneAddress *resource, const char *event, int expires){ @@ -374,10 +374,10 @@ static int _linphone_event_send_publish(LinphoneEvent *lev, const LinphoneConten return -1; } if (lev->send_custom_headers){ - lev->op->set_sent_custom_header(lev->send_custom_headers); + lev->op->setSentCustomHeaders(lev->send_custom_headers); sal_custom_header_free(lev->send_custom_headers); lev->send_custom_headers=NULL; - }else lev->op->set_sent_custom_header(NULL); + }else lev->op->setSentCustomHeaders(NULL); body_handler = sal_body_handler_from_content(body); auto publishOp = dynamic_cast(lev->op); err=publishOp->publish(NULL,NULL,lev->name,lev->expires,body_handler); @@ -413,7 +413,7 @@ LinphoneStatus linphone_event_refresh_publish(LinphoneEvent *lev) { return lev->op->refresh(); } void linphone_event_pause_publish(LinphoneEvent *lev) { - if (lev->op) lev->op->stop_refreshing(); + if (lev->op) lev->op->stopRefreshing(); } void linphone_event_unpublish(LinphoneEvent *lev) { lev->terminating = TRUE; /* needed to get clear event*/ @@ -435,7 +435,7 @@ void linphone_event_add_custom_header(LinphoneEvent *ev, const char *name, const } const char* linphone_event_get_custom_header(LinphoneEvent* ev, const char* name){ - const SalCustomHeader *ch=ev->op->get_recv_custom_header(); + const SalCustomHeader *ch=ev->op->getRecvCustomHeaders(); return sal_custom_header_find(ch,name); } @@ -453,7 +453,7 @@ void linphone_event_terminate(LinphoneEvent *lev){ lev->terminating=TRUE; if (lev->dir==LinphoneSubscriptionIncoming){ auto op = dynamic_cast(lev->op); - op->close_notify(); + op->closeNotify(); }else if (lev->dir==LinphoneSubscriptionOutgoing){ auto op = dynamic_cast(lev->op); op->unsubscribe(); @@ -511,7 +511,7 @@ const char *linphone_event_get_name(const LinphoneEvent *lev){ static const LinphoneAddress *_linphone_event_cache_to (const LinphoneEvent *lev) { if (lev->to_address) linphone_address_unref(lev->to_address); - char *buf = sal_address_as_string(lev->op->get_to_address()); + char *buf = sal_address_as_string(lev->op->getToAddress()); ((LinphoneEvent *)lev)->to_address = linphone_address_new(buf); ms_free(buf); return lev->to_address; @@ -520,7 +520,7 @@ static const LinphoneAddress *_linphone_event_cache_to (const LinphoneEvent *lev static const LinphoneAddress *_linphone_event_cache_from (const LinphoneEvent *lev) { if (lev->from_address) linphone_address_unref(lev->from_address); - char *buf = sal_address_as_string(lev->op->get_from_address()); + char *buf = sal_address_as_string(lev->op->getFromAddress()); ((LinphoneEvent *)lev)->from_address = linphone_address_new(buf); ms_free(buf); return lev->from_address; @@ -529,7 +529,7 @@ static const LinphoneAddress *_linphone_event_cache_from (const LinphoneEvent *l static const LinphoneAddress *_linphone_event_cache_remote_contact (const LinphoneEvent *lev) { if (lev->remote_contact_address) linphone_address_unref(lev->remote_contact_address); - char *buf = sal_address_as_string(lev->op->get_remote_contact_address()); + char *buf = sal_address_as_string(lev->op->getRemoteContactAddress()); ((LinphoneEvent *)lev)->remote_contact_address = linphone_address_new(buf); ms_free(buf); return lev->remote_contact_address; diff --git a/coreapi/factory.c b/coreapi/factory.c index 5138534a4..a9434159b 100644 --- a/coreapi/factory.c +++ b/coreapi/factory.c @@ -439,3 +439,7 @@ void linphone_factory_set_log_collection_path(LinphoneFactory *factory, const ch void linphone_factory_enable_log_collection(LinphoneFactory *factory, LinphoneLogCollectionState state) { linphone_core_enable_log_collection(state); } + +LinphoneTunnelConfig *linphone_factory_create_tunnel_config(LinphoneFactory *factory) { + return linphone_tunnel_config_new(); +} diff --git a/coreapi/friend.c b/coreapi/friend.c index 9c929e225..6b3b175ff 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -478,7 +478,7 @@ void linphone_friend_notify(LinphoneFriend *lf, LinphonePresenceModel *presence) } for(elem=lf->insubs; elem!=NULL; elem=bctbx_list_next(elem)){ auto op = reinterpret_cast(bctbx_list_get_data(elem)); - op->notify_presence((SalPresenceModel *)presence); + op->notifyPresence((SalPresenceModel *)presence); } } @@ -531,7 +531,7 @@ void linphone_friend_invalidate_subscription(LinphoneFriend *lf){ } static void close_presence_notification(SalPresenceOp *op) { - op->notify_presence_close(); + op->notifyPresenceClose(); } static void release_sal_op(SalOp *op) { @@ -773,7 +773,7 @@ void linphone_friend_update_subscribes(LinphoneFriend *fr, bool_t only_when_regi linphone_friend_unsubscribe(fr); }else if (!can_subscribe && fr->outsub){ fr->subscribe_active=FALSE; - fr->outsub->stop_refreshing(); + fr->outsub->stopRefreshing(); } } @@ -1779,11 +1779,13 @@ const char * linphone_friend_phone_number_to_sip_uri(LinphoneFriend *lf, const c if(strcmp(normalized_number, phone_number) != 0) { char *old_uri = ms_strdup_printf("sip:%s@%s;user=phone", phone_number, linphone_proxy_config_get_domain(proxy_config)); bctbx_iterator_t *it = bctbx_map_cchar_find_key(lf->friend_list->friends_map_uri, old_uri); - if (!bctbx_iterator_cchar_equals(it, bctbx_map_cchar_end(lf->friend_list->friends_map_uri))){ + bctbx_iterator_t *end = bctbx_map_cchar_end(lf->friend_list->friends_map_uri); + if (!bctbx_iterator_cchar_equals(it, end)){ linphone_friend_unref((LinphoneFriend*)bctbx_pair_cchar_get_second(bctbx_iterator_cchar_get_pair(it))); bctbx_map_cchar_erase(lf->friend_list->friends_map_uri, it); } bctbx_iterator_cchar_delete(it); + bctbx_iterator_cchar_delete(end); ms_free(old_uri); } diff --git a/coreapi/friendlist.c b/coreapi/friendlist.c index 5e9ca2abf..e55892a21 100644 --- a/coreapi/friendlist.c +++ b/coreapi/friendlist.c @@ -19,6 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include +#include "linphone/api/c-content.h" #include "linphone/core.h" #include "c-wrapper/c-wrapper.h" @@ -576,6 +577,7 @@ LinphoneFriendListStatus linphone_friend_list_import_friend(LinphoneFriendList * } iterator = bctbx_list_next(iterator); } + bctbx_list_free(phone_numbers); addresses = linphone_friend_get_addresses(lf); iterator = (bctbx_list_t *)addresses; @@ -798,15 +800,19 @@ LinphoneFriend * linphone_friend_list_find_friend_by_uri(const LinphoneFriendLis return result; } -LinphoneFriend * linphone_friend_list_find_friend_by_ref_key(const LinphoneFriendList *list, const char *ref_key) { - if(list) { - bctbx_iterator_t* it = bctbx_map_cchar_find_key(list->friends_map, ref_key); - if (!bctbx_iterator_cchar_equals(it, bctbx_map_cchar_end(list->friends_map))) { +LinphoneFriend *linphone_friend_list_find_friend_by_ref_key (const LinphoneFriendList *list, const char *ref_key) { + LinphoneFriend *result = NULL; + if (list) { + bctbx_iterator_t *it = bctbx_map_cchar_find_key(list->friends_map, ref_key); + bctbx_iterator_t *end = bctbx_map_cchar_end(list->friends_map); + if (!bctbx_iterator_cchar_equals(it, end)) { bctbx_pair_t *pair = bctbx_iterator_cchar_get_pair(it); - return (LinphoneFriend *)bctbx_pair_cchar_get_second(pair); + result = (LinphoneFriend *)bctbx_pair_cchar_get_second(pair); } + bctbx_iterator_cchar_delete(end); + bctbx_iterator_cchar_delete(it); } - return NULL; + return result; } LinphoneFriend * linphone_friend_list_find_friend_by_inc_subscribe ( @@ -828,7 +834,7 @@ LinphoneFriend * linphone_friend_list_find_friend_by_out_subscribe ( const bctbx_list_t *elem; for (elem = list->friends; elem != NULL; elem = bctbx_list_next(elem)) { LinphoneFriend *lf = (LinphoneFriend *)bctbx_list_get_data(elem); - if (lf->outsub && ((lf->outsub == op) || lf->outsub->is_forked_of(op))) return lf; + if (lf->outsub && ((lf->outsub == op) || lf->outsub->isForkedOf(op))) return lf; } return NULL; } @@ -961,7 +967,7 @@ void linphone_friend_list_notify_presence_received(LinphoneFriendList *list, Lin const char *subtype = linphone_content_get_subtype(body); if ((strcmp(type, "multipart") != 0) || (strcmp(subtype, "related") != 0)) { - ms_warning("multipart presence notified but it is not 'multipart/related'"); + ms_warning("multipart presence notified but it is not 'multipart/related', instead is '%s/%s'", type, subtype); return; } diff --git a/coreapi/help/doc/doxygen/CMakeLists.txt b/coreapi/help/doc/doxygen/CMakeLists.txt index 91c62458d..57dd6b574 100644 --- a/coreapi/help/doc/doxygen/CMakeLists.txt +++ b/coreapi/help/doc/doxygen/CMakeLists.txt @@ -38,14 +38,12 @@ if (ENABLE_DOC OR ENABLE_CXX_WRAPPER OR ENABLE_CSHARP_WRAPPER OR ENABLE_JAVA_WRA ) set(XML_DIR "${CMAKE_CURRENT_BINARY_DIR}/xml") set(LINPHONE_DOXYGEN_XML_DIR ${XML_DIR} PARENT_SCOPE) - add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/html/index.html" "${XML_DIR}/index.xml" - COMMAND ${CMAKE_COMMAND} -E remove -f html/* xml/* + add_custom_command(OUTPUT "${XML_DIR}/index.xml" + COMMAND ${CMAKE_COMMAND} -E remove -f xml/* COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile DEPENDS ${DOC_INPUT_FILES} ) - add_custom_target(linphone-doc ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/html/index.html" "${XML_DIR}/index.xml") - install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/html" "${XML_DIR}" - DESTINATION "${CMAKE_INSTALL_DATADIR}/doc/linphone-${LINPHONE_VERSION}") + add_custom_target(linphone-doc ALL DEPENDS "${XML_DIR}/index.xml") else() if (ENABLE_CXX_WRAPPER) message(FATAL_ERROR "The dot program is needed to generate the linphone documentation. You can get it from http://www.graphviz.org/.") diff --git a/coreapi/help/doc/doxygen/Doxyfile.in b/coreapi/help/doc/doxygen/Doxyfile.in index 851af4c1a..651017491 100644 --- a/coreapi/help/doc/doxygen/Doxyfile.in +++ b/coreapi/help/doc/doxygen/Doxyfile.in @@ -1045,7 +1045,7 @@ IGNORE_PREFIX = # If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output # The default value is: YES. -GENERATE_HTML = YES +GENERATE_HTML = NO # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of @@ -1589,7 +1589,7 @@ EXTRA_SEARCH_MAPPINGS = # If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. # The default value is: YES. -GENERATE_LATEX = YES +GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of @@ -1825,7 +1825,7 @@ RTF_SOURCE_CODE = NO # classes and files. # The default value is: NO. -GENERATE_MAN = YES +GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of diff --git a/coreapi/help/doc/sphinx/CMakeLists.txt b/coreapi/help/doc/sphinx/CMakeLists.txt index 15abb7480..5e1e890c5 100644 --- a/coreapi/help/doc/sphinx/CMakeLists.txt +++ b/coreapi/help/doc/sphinx/CMakeLists.txt @@ -20,42 +20,40 @@ # ############################################################################ -if (ENABLE_SPHINX_DOC) - set(GENERATED_LANGUAGES c cpp csharp) - set(DOCUMENTATION_DIRS ) - set(GENERATED_SPHINX_SOURCES ) - foreach(LANGUAGE_ ${GENERATED_LANGUAGES}) - set(DOCUMENTATION_DIR ${CMAKE_CURRENT_BINARY_DIR}/source/${LANGUAGE_}) - list(APPEND DOCUMENTATION_DIRS ${DOCUMENTATION_DIR}) - list(APPEND GENERATED_SPHINX_SOURCES ${DOCUMENTATION_DIR}/index.rst) - endforeach(LANGUAGE_) - - set(PYTHON_SCRIPTS gendoc.py - ${linphone_SOURCE_DIR}/tools/abstractapi.py - ${linphone_SOURCE_DIR}/tools/genapixml.py - ${linphone_SOURCE_DIR}/tools/metadoc.py - ${linphone_SOURCE_DIR}/tools/metaname.py +if (ENABLE_DOC) + set(doc_source_dir ${CMAKE_CURRENT_BINARY_DIR}/source) + set(doc_output_dir ${CMAKE_CURRENT_BINARY_DIR}/build) + set(reference_doc_source_dir ${doc_source_dir}/reference) + set(static_documentation_files + guides/authentication.rst + guides/buddy_list.rst + guides/call_control.rst + guides/call_logs.rst + guides/call_misc.rst + guides/chatroom.rst + guides/conferencing.rst + guides/event_api.rst + guides/initializing.rst + guides/ios_portability.rst + guides/linphone_address.rst + guides/media_parameters.rst + guides/misc.rst + guides/network_parameters.rst + guides/proxies.rst + index.rst + logo.png + samples/samples.rst ) - set(MUSTACHE_TEMPLATES class_page.mustache - enums_page.mustache - index_page.mustache - ) - configure_file(conf.py.in source/conf.py) - configure_file(source/index.rst source/index.rst COPYONLY) - add_custom_command(OUTPUT ${GENERATED_SPHINX_SOURCES} - COMMAND ${CMAKE_COMMAND} -E remove -f ${DOCUMENTATION_DIRS} - COMMAND ${PYTHON_EXECUTABLE} '${CMAKE_CURRENT_SOURCE_DIR}/gendoc.py' '${LINPHONE_DOXYGEN_XML_DIR}' -o 'source' - DEPENDS ${PYTHON_SCRIPTS} - ${MUSTACHE_TEMPLATES} - ${LINPHONE_DOXYGEN_XML_DIR}/index.xml - linphone-doc - ) - add_custom_command(OUTPUT build/html/index.html - COMMAND ${CMAKE_COMMAND} -E remove_directory build - COMMAND ${PYTHON_EXECUTABLE} -msphinx -M html 'source' 'build' - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/source/conf.py - ${CMAKE_CURRENT_BINARY_DIR}/source/index.rst - ${GENERATED_SPHINX_SOURCES} - ) - add_custom_target(sphinx-doc ALL DEPENDS build/html/index.html) + configure_file(conf.py.in ${doc_source_dir}/conf.py) + foreach(file ${static_documentation_files}) + configure_file(${file} ${doc_source_dir}/${file} COPYONLY) + endforeach(file) + foreach(source ${LINPHONE_C_EXAMPLES_SOURCE}) + configure_file(${source} ${doc_source_dir}/samples/ COPYONLY) + endforeach(source) + execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${doc_source_dir}/_static ${reference_doc_source_dir}) + add_custom_target(sphinx-doc ALL ${PYTHON_EXECUTABLE} '${CMAKE_CURRENT_SOURCE_DIR}/gendoc.py' '${LINPHONE_DOXYGEN_XML_DIR}' -o '${reference_doc_source_dir}' + COMMAND ${PYTHON_EXECUTABLE} -msphinx -M html '${doc_source_dir}' '${doc_output_dir}' + DEPENDS linphone-doc) + install(DIRECTORY ${doc_output_dir}/html/ DESTINATION ${CMAKE_INSTALL_DOCDIR}/${LINPHONE_VERSION}) endif() diff --git a/coreapi/help/doc/sphinx/class_page.mustache b/coreapi/help/doc/sphinx/class_page.mustache index f835c5c3e..947336994 100644 --- a/coreapi/help/doc/sphinx/class_page.mustache +++ b/coreapi/help/doc/sphinx/class_page.mustache @@ -1,6 +1,13 @@ +{{#hasNamespaceDeclarator}} +.. {{#write_declarator}}namespace{{/write_declarator}}:: {{{namespace}}} + {{#isJava}} + :noindex: + {{/isJava}} +{{/hasNamespaceDeclarator}} + {{#make_chapter}}{{{className}}} class{{/make_chapter}} -.. {{#write_declarator}}class{{/write_declarator}}:: {{{fullClassName}}} +.. {{#write_declarator}}class{{/write_declarator}}:: {{{classDeclaration}}} {{#briefDoc}} {{#lines}} @@ -17,9 +24,24 @@ {{{selector}}} +{{#hasNamespaceDeclarator}} +.. {{#write_declarator}}namespace{{/write_declarator}}:: {{{fullClassName}}} + {{#isJava}} + :noindex: + {{/isJava}} +{{/hasNamespaceDeclarator}} + + Summary ======= +{{#hasEnums}} +Enums +----- + +{{{enumsSummary}}} +{{/hasEnums}} + {{#hasProperties}} Properties ---------- @@ -41,18 +63,61 @@ Class methods {{{classMethodsSummary}}} {{/hasClassMethods}} + Detailed descriptions ===================== +{{#hasEnums}} +Enums +----- + +{{#enums}} +{{#make_subsection}}{{{name}}}{{/make_subsection}} +.. {{#write_declarator}}enum{{/write_declarator}}:: {{{declaration}}} + + {{#briefDesc}} + {{#lines}} + {{{line}}} + {{/lines}} + {{/briefDesc}} + + {{{selector}}} + + {{#enumerators}} + {{#isNotJava}} + .. {{#write_declarator}}enumerator{{/write_declarator}}:: {{{name}}} + + {{/isNotJava}} + {{#isJava}} + **{{{name}}}** + {{/isJava}} + {{#briefDesc}} + {{#lines}} + {{{line}}} + {{/lines}} + {{/briefDesc}} + + {{{selector}}} + + {{/enumerators}} +{{/enums}} +{{/hasEnums}} + {{#hasProperties}} Properties ---------- {{#properties}} + +.. _{{{ref_label}}}: + {{{title}}} {{#hasNamespaceDeclarator}} .. {{#write_declarator}}namespace{{/write_declarator}}:: {{{fullClassName}}} + {{#isJava}} + :noindex: + {{/isJava}} {{/hasNamespaceDeclarator}} {{#getter}} @@ -100,6 +165,9 @@ Public methods {{#hasNamespaceDeclarator}} .. {{#write_declarator}}namespace{{/write_declarator}}:: {{{fullClassName}}} + {{#isJava}} + :noindex: + {{/isJava}} {{/hasNamespaceDeclarator}} {{#methods}} @@ -128,6 +196,9 @@ Class methods {{#hasNamespaceDeclarator}} .. {{#write_declarator}}namespace{{/write_declarator}}:: {{{fullClassName}}} + {{#isJava}} + :noindex: + {{/isJava}} {{/hasNamespaceDeclarator}} {{#classMethods}} diff --git a/coreapi/help/doc/sphinx/conf.py.in b/coreapi/help/doc/sphinx/conf.py.in index 378b84244..3d903aaf3 100644 --- a/coreapi/help/doc/sphinx/conf.py.in +++ b/coreapi/help/doc/sphinx/conf.py.in @@ -31,7 +31,7 @@ # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = ['sphinx_csharp.csharp'] +extensions = ['sphinx_csharp.csharp', 'javasphinx'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -83,20 +83,33 @@ todo_include_todos = False # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -#html_theme = 'alabaster' html_theme = 'classic' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. # -# html_theme_options = {} +html_theme_options = { + 'sidebarwidth': '360', + 'body_max_width': '100%', + 'collapsiblesidebar': 'true' +} # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] +# Path to the picture to use as logo. +html_logo = 'logo.png' + +# Enable html5 +html_experimental_html5_writer = True + +# Side bar customization +#html_sidebars = { +# 'reference/*/*' : ['searchbox.html', 'globaltoc.html'] +#} # -- Options for HTMLHelp output ------------------------------------------ diff --git a/coreapi/help/doc/sphinx/enum_page.mustache b/coreapi/help/doc/sphinx/enum_page.mustache new file mode 100644 index 000000000..c400e96eb --- /dev/null +++ b/coreapi/help/doc/sphinx/enum_page.mustache @@ -0,0 +1,39 @@ +{{#namespace}} +.. {{#write_declarator}}namespace{{/write_declarator}}:: {{{namespace}}} + {{#isJava}} + :noindex: + {{/isJava}} +{{/namespace}} + +{{#enum}} +{{#make_chapter}}{{{name}}} enum{{/make_chapter}} + +.. {{#write_declarator}}enum{{/write_declarator}}:: {{{declaration}}} + + {{#briefDesc}} + {{#lines}} + {{{line}}} + {{/lines}} + {{/briefDesc}} + + {{{selector}}} + + {{#enumerators}} + {{#isNotJava}} + .. {{#write_declarator}}enumerator{{/write_declarator}}:: {{{name}}} + + {{/isNotJava}} + {{#isJava}} + **{{{name}}}** + {{/isJava}} + {{#briefDesc}} + {{#lines}} + {{{line}}} + {{/lines}} + {{/briefDesc}} + + {{{selector}}} + + {{/enumerators}} + +{{/enum}} diff --git a/coreapi/help/doc/sphinx/enums_page.mustache b/coreapi/help/doc/sphinx/enums_page.mustache deleted file mode 100644 index fd013094a..000000000 --- a/coreapi/help/doc/sphinx/enums_page.mustache +++ /dev/null @@ -1,30 +0,0 @@ -{{#enums}} -{{{sectionName}}} - -.. {{#write_declarator}}enum{{/write_declarator}}:: {{{fullName}}} - - {{#briefDesc}} - {{#lines}} - {{{line}}} - {{/lines}} - {{/briefDesc}} - - {{{selector}}} - - {{#hasNamespaceDeclarator}} - .. {{#write_declarator}}namespace{{/write_declarator}}:: {{{namespace}}} - {{/hasNamespaceDeclarator}} - - {{#enumerators}} - .. {{#write_declarator}}enumerator{{/write_declarator}}:: {{{name}}}{{#value}} = {{{value}}}{{/value}} - - {{#briefDesc}} - {{#lines}} - {{{line}}} - {{/lines}} - {{/briefDesc}} - - {{{selector}}} - - {{/enumerators}} -{{/enums}} diff --git a/coreapi/help/doc/sphinx/gendoc.py b/coreapi/help/doc/sphinx/gendoc.py index 256ab1fe4..514dfb596 100755 --- a/coreapi/help/doc/sphinx/gendoc.py +++ b/coreapi/help/doc/sphinx/gendoc.py @@ -19,6 +19,7 @@ import argparse +import hashlib import logging import os import pystache @@ -31,7 +32,18 @@ import metaname import metadoc +def md5sum(file): + hasher = hashlib.md5() + with open(file, mode='rb') as f: + hasher.update(f.read()) + return hasher.hexdigest() + + class RstTools: + @staticmethod + def make_part(text): + return RstTools.make_section(text, char='#', overline=True) + @staticmethod def make_chapter(text): return RstTools.make_section(text, char='*', overline=True) @@ -56,12 +68,27 @@ class RstTools: class Table: def __init__(self): self._rows = [] - self._widths = [] - self._heights = [] - + @property def rows(self): return self._rows + + class CSVTable(Table): + def addrow(self, row): + self._rows.append(', '.join([self._format_cell(cell) for cell in row])) + + def __str__(self): + return '.. csv-table::\n\t\n\t' + '\n\t'.join(self._rows) + + def _format_cell(self, cell): + return '"{0}"'.format(cell.replace('"', '""')) + + + class GridTable(Table): + def __init__(self): + RstTools.Table.__init__(self) + self._widths = [] + self._heights = [] def addrow(self, row): if len(self._widths) == 0: @@ -125,78 +152,132 @@ class RstTools: class LangInfo: def __init__(self, langCode): + if langCode not in LangInfo._displayNames: + raise ValueError("Invalid language code '{0}'".format(langCode)) self.langCode = langCode - self.displayName = LangInfo._lang_code_to_display_name(langCode) self.nameTranslator = metaname.Translator.get(langCode) self.langTranslator = abstractapi.Translator.get(langCode) self.docTranslator = metadoc.SphinxTranslator(langCode) - - @staticmethod - def _lang_code_to_display_name(langCode): - if langCode == 'C': - return 'C' - elif langCode == 'Cpp': - return 'C++' - elif langCode == 'CSharp': - return 'C#' - else: - raise ValueError("Invalid language code: '{0}'".format(langCode)) + + @property + def displayName(self): + return LangInfo._displayNames[self.langCode] + + @property + def directory(self): + return self.langCode.lower() + + _displayNames = { + 'C' : 'C', + 'Cpp' : 'C++', + 'Java' : 'Java', + 'CSharp': 'C#' + } -class SphinxPage(object): - def __init__(self, lang, langs, filename): +class SphinxPart(object): + def __init__(self, lang, langs): object.__init__(self) self.lang = lang self.langs = langs - self.filename = filename - - @property - def hasNamespaceDeclarator(self): - return ('namespaceDeclarator' in dir(self.docTranslator)) - + @property def language(self): return self.lang.displayName - + @property def docTranslator(self): return self.lang.docTranslator - + + @property + def hasNamespaceDeclarator(self): + return ('namespaceDeclarator' in dir(self.docTranslator)) + + @property + def isJava(self): + return self.lang.langCode == 'Java' + + @property + def isNotJava(self): + return not self.isJava + + def make_part(self): + return lambda text: RstTools.make_part(pystache.render(text, self)) + def make_chapter(self): return lambda text: RstTools.make_chapter(pystache.render(text, self)) - + def make_section(self): return lambda text: RstTools.make_section(pystache.render(text, self)) - + def make_subsection(self): - return lambda text: RstTools.make_subsection(pystache.render(text, self.properties)) - + return lambda text: RstTools.make_subsection(pystache.render(text, self)) + + def make_subsection(self): + return lambda text: RstTools.make_subsubsection(pystache.render(text, self)) + def write_declarator(self): return lambda text: self.docTranslator.get_declarator(text) - - def write(self, directory): - r = pystache.Renderer() - filepath = os.path.join(directory, self.filename) - with open(filepath, mode='w') as f: - f.write(r.render(self)) - - def _get_translated_namespace(self, obj): - namespace = obj.find_first_ancestor_by_type(abstractapi.Namespace) - return namespace.name.translate(self.lang.nameTranslator, recursive=True) - + def _make_selector(self, obj): links = [] - ref = metadoc.Reference(None) - ref.relatedObject = obj for lang in self.langs: if lang is self.lang: link = lang.displayName else: + if lang.langCode == 'Java' and type(obj) is abstractapi.Enumerator: + ref = metadoc.Reference.make_ref_from_object(None, obj.parent) + else: + ref = metadoc.Reference.make_ref_from_object(None, obj) link = ref.translate(lang.docTranslator, label=lang.displayName) - links.append(link) - return ' '.join(links) + + +class EnumPart(SphinxPart): + def __init__(self, enum, lang, langs, namespace=None): + SphinxPart.__init__(self, lang, langs) + self.name = enum.name.translate(self.lang.nameTranslator) + self.fullName = enum.name.translate(self.lang.nameTranslator, recursive=True) + self.briefDesc = enum.briefDescription.translate(self.docTranslator) + self.enumerators = [self._translate_enumerator(enumerator) for enumerator in enum.enumerators] + self.selector = self._make_selector(enum) + self.sectionName = RstTools.make_section(self.name) + self.declaration = 'public enum {0}'.format(self.name) if self.lang.langCode == 'Java' else self.name + + ref = metadoc.ClassReference(None) + ref.relatedObject = enum + self.link = ref.translate(lang.docTranslator) + + def _translate_enumerator(self, enumerator): + return { + 'name' : enumerator.name.translate(self.lang.nameTranslator), + 'briefDesc' : enumerator.briefDescription.translate(self.docTranslator), + 'value' : enumerator.translate_value(self.lang.langTranslator), + 'selector' : self._make_selector(enumerator) + } + + +class SphinxPage(SphinxPart): + def __init__(self, lang, langs, filename): + SphinxPart.__init__(self, lang, langs) + self.filename = filename + + def write(self, directory): + r = pystache.Renderer() + filepath = os.path.join(directory, self.filename) + tmpFilepath = filepath + '.tmp' + with open(tmpFilepath, mode='w') as f: + f.write(r.render(self)) + if os.path.exists(filepath) and md5sum(filepath) == md5sum(tmpFilepath): + os.remove(tmpFilepath) + else: + os.rename(tmpFilepath, filepath) + return filepath + + def _get_translated_namespace(self, obj): + namespace = obj.find_first_ancestor_by_type(abstractapi.Namespace) + return namespace.name.translate(self.lang.nameTranslator, recursive=True) @staticmethod def _classname_to_filename(classname): @@ -204,60 +285,59 @@ class SphinxPage(object): class IndexPage(SphinxPage): - def __init__(self, lang, langs): - SphinxPage.__init__(self, lang, langs, 'index.rst') - self.tocEntries = [] - - def add_class_entry(self, _class): - self.tocEntries.append({'entryName': SphinxPage._classname_to_filename(_class.name)}) + def __init__(self, lang, filename): + SphinxPage.__init__(self, lang, None, filename) + self._entries = [] + self._sorted = True + + @property + def title(self): + return RstTools.make_chapter("{0} API".format(self.lang.displayName)) + + @property + def dir(self): + return self.lang.directory + + @property + def entries(self): + if not self._sorted: + self._entries.sort(key=lambda x: x['filename']) + self._sorted = True + return self._entries + + def add_entry(self, filename): + self.entries.append({'filename': filename}) + self._sorted = False -class EnumsPage(SphinxPage): - def __init__(self, lang, langs, enums): - SphinxPage.__init__(self, lang, langs, 'enums.rst') - self._translate_enums(enums) - - def _translate_enums(self, enums): - self.enums = [] - for enum in enums: - translatedEnum = { - 'name' : enum.name.translate(self.lang.nameTranslator), - 'fullName' : enum.name.translate(self.lang.nameTranslator, recursive=True), - 'briefDesc' : enum.briefDescription.translate(self.docTranslator), - 'enumerators' : self._translate_enum_values(enum), - 'selector' : self._make_selector(enum) - } - translatedEnum['namespace'] = self._get_translated_namespace(enum) if self.lang.langCode == 'Cpp' else translatedEnum['fullName'] - translatedEnum['sectionName'] = RstTools.make_section(translatedEnum['name']) - self.enums.append(translatedEnum) - - def _translate_enum_values(self, enum): - translatedEnumerators = [] - for enumerator in enum.enumerators: - translatedValue = { - 'name' : enumerator.name.translate(self.lang.nameTranslator), - 'briefDesc' : enumerator.briefDescription.translate(self.docTranslator), - 'value' : enumerator.translate_value(self.lang.langTranslator), - 'selector' : self._make_selector(enumerator) - } - translatedEnumerators.append(translatedValue) - - return translatedEnumerators +class EnumPage(SphinxPage): + def __init__(self, enum, lang, langs): + filename = SphinxPage._classname_to_filename(enum.name) + SphinxPage.__init__(self, lang, langs, filename) + namespace = enum.find_first_ancestor_by_type(abstractapi.Namespace) + self.namespace = namespace.name.translate(lang.nameTranslator) if lang.langCode != 'C' else None + self.enum = EnumPart(enum, lang, langs, namespace=namespace) class ClassPage(SphinxPage): def __init__(self, _class, lang, langs): filename = SphinxPage._classname_to_filename(_class.name) SphinxPage.__init__(self, lang, langs, filename) - self.namespace = self._get_translated_namespace(_class) + namespace = _class.find_first_ancestor_by_type(abstractapi.Namespace) + self.namespace = namespace.name.translate(self.lang.nameTranslator, recursive=True) self.className = _class.name.translate(self.lang.nameTranslator) self.fullClassName = _class.name.translate(self.lang.nameTranslator, recursive=True) self.briefDoc = _class.briefDescription.translate(self.docTranslator) self.detailedDoc = _class.detailedDescription.translate(self.docTranslator) if _class.detailedDescription is not None else None - self.properties = self._translate_properties(_class.properties) + self.enums = [EnumPart(enum, lang, langs) for enum in _class.enums] + self.properties = self._translate_properties(_class.properties) if isinstance(_class, abstractapi.Class) else [] self.methods = self._translate_methods(_class.instanceMethods) self.classMethods = self._translate_methods(_class.classMethods) self.selector = self._make_selector(_class) + + @property + def classDeclaration(self): + return 'public interface {0}'.format(self.className) if self.lang.langCode == 'Java' else self.className @property def hasMethods(self): @@ -270,17 +350,22 @@ class ClassPage(SphinxPage): @property def hasProperties(self): return len(self.properties) > 0 + + @property + def hasEnums(self): + return len(self.enums) > 0 def _translate_properties(self, properties): translatedProperties = [] for property_ in properties: propertyAttr = { 'name' : property_.name.translate(self.lang.nameTranslator), - 'ref_label' : '{0}_{1}'.format(self.lang.langCode, property_.name.to_snake_case(fullName=True)), 'getter' : self._translate_method(property_.getter) if property_.getter is not None else None, 'setter' : self._translate_method(property_.setter) if property_.setter is not None else None } propertyAttr['title'] = RstTools.make_subsubsection(propertyAttr['name']) + propertyAttr['ref_label'] = (self.lang.langCode + '_') + propertyAttr['ref_label'] += (property_.getter.name.to_snake_case(fullName=True) if property_.getter is not None else property_.setter.name.to_snake_case(fullName=True)) translatedProperties.append(propertyAttr) return translatedProperties @@ -291,73 +376,102 @@ class ClassPage(SphinxPage): return translatedMethods def _translate_method(self, method): - prototypeParams = {} - if self.lang.langCode == 'Cpp': - prototypeParams['showStdNs'] = True + namespace = method.find_first_ancestor_by_type(abstractapi.Class,abstractapi.Interface) methAttr = { - 'prototype' : method.translate_as_prototype(self.lang.langTranslator, **prototypeParams), + 'prototype' : method.translate_as_prototype(self.lang.langTranslator, namespace=namespace), 'briefDoc' : method.briefDescription.translate(self.docTranslator), 'detailedDoc' : method.detailedDescription.translate(self.docTranslator), 'selector' : self._make_selector(method) } reference = metadoc.FunctionReference(None) reference.relatedObject = method - methAttr['link'] = reference.translate(self.lang.docTranslator) + methAttr['link'] = reference.translate(self.lang.docTranslator, namespace=method.find_first_ancestor_by_type(abstractapi.Class, abstractapi.Interface)) return methAttr + + @property + def enumsSummary(self): + table = RstTools.CSVTable() + for enum in self.enums: + briefDoc = ' '.join([line['line'] for line in enum.briefDesc['lines']]) + table.addrow((enum.link, briefDoc)) + return table @property def propertiesSummary(self): - table = RstTools.Table() + table = RstTools.CSVTable() for property_ in self.properties: reference = ':ref:`{0}`'.format(property_['ref_label']) briefDoc = property_['getter']['briefDoc'] if property_['getter'] is not None else property_['setter']['briefDoc'] - briefDoc = '\n'.join([line['line'] for line in briefDoc['lines']]) + briefDoc = ' '.join([line['line'] for line in briefDoc['lines']]) table.addrow([reference, briefDoc]) return table @property def instanceMethodsSummary(self): - table = RstTools.Table() + table = RstTools.CSVTable() for method in self.methods: - briefDoc = '\n'.join([line['line'] for line in method['briefDoc']['lines']]) + briefDoc = ' '.join([line['line'] for line in method['briefDoc']['lines']]) table.addrow([method['link'], briefDoc]) return table @property def classMethodsSummary(self): - table = RstTools.Table() + table = RstTools.CSVTable() for method in self.classMethods: - briefDoc = '\n'.join([line['line'] for line in method['briefDoc']['lines']]) + briefDoc = ' '.join([line['line'] for line in method['briefDoc']['lines']]) table.addrow([method['link'], briefDoc]) return table +class OldFilesCleaner: + def __init__(self, rootDirectory): + self._filesToKeep = set() + self.root = rootDirectory + + def protect_file(self, directory): + self._filesToKeep.add(directory) + + def clean(self): + self._clean(self.root) + + def _clean(self, dir_): + if os.path.isdir(dir_): + for filename in os.listdir(dir_): + self._clean(os.path.join(dir_, filename)) + elif dir_ not in self._filesToKeep: + os.remove(dir_) + + class DocGenerator: def __init__(self, api): self.api = api self.languages = [ LangInfo('C'), LangInfo('Cpp'), + LangInfo('Java'), LangInfo('CSharp') ] def generate(self, outputdir): for lang in self.languages: - subdirectory = lang.langCode.lower() - directory = os.path.join(args.outputdir, subdirectory) + directory = os.path.join(args.outputdir, lang.directory) + cleaner = OldFilesCleaner(directory) + indexPage = IndexPage(lang, 'index.rst') if not os.path.exists(directory): os.mkdir(directory) - - enumsPage = EnumsPage(lang, self.languages, absApiParser.enums) - enumsPage.write(directory) - - indexPage = IndexPage(lang, self.languages) - for _class in absApiParser.classes: - page = ClassPage(_class, lang, self.languages) - page.write(directory) - indexPage.add_class_entry(_class) - - indexPage.write(directory) + for enum in self.api.namespace.enums: + page = EnumPage(enum, lang, self.languages) + filepath = page.write(directory) + indexPage.add_entry(page.filename) + cleaner.protect_file(filepath) + for class_ in (self.api.namespace.classes + self.api.namespace.interfaces): + page = ClassPage(class_, lang, self.languages) + filepath = page.write(directory) + indexPage.add_entry(page.filename) + cleaner.protect_file(filepath) + filepath = indexPage.write(directory) + cleaner.protect_file(filepath) + cleaner.clean() if __name__ == '__main__': diff --git a/coreapi/help/doc/sphinx/guides/authentication.rst b/coreapi/help/doc/sphinx/guides/authentication.rst new file mode 100644 index 000000000..464997164 --- /dev/null +++ b/coreapi/help/doc/sphinx/guides/authentication.rst @@ -0,0 +1,4 @@ +Managing authentication: userid and passwords +============================================= + + diff --git a/coreapi/help/doc/sphinx/guides/buddy_list.rst b/coreapi/help/doc/sphinx/guides/buddy_list.rst new file mode 100644 index 000000000..c0a0591c5 --- /dev/null +++ b/coreapi/help/doc/sphinx/guides/buddy_list.rst @@ -0,0 +1,57 @@ +Managing Buddies and buddy list and presence +============================================ +Buddies and buddy list +---------------------- + +Each buddy is represented by a :cpp:type:`LinphoneFriend` object created by function :cpp:func:`linphone_friend_new`. + +Buddy configuration parameters like :cpp:func:`sip uri ` or :cpp:func:`status publication ` policy for +this :cpp:type:`friend ` are configurable for each buddy. + +Here under a typical buddy creation: + +.. code-block:: c + + LinphoneFriend* my_friend=linphone_friend_new_with_addr("sip:joe@sip.linphone.org"); /*creates friend object for buddy joe*/ + linphone_friend_enable_subscribes(my_friend,TRUE); /*configure this friend to emit SUBSCRIBE message after being added to LinphoneCore*/ + linphone_friend_set_inc_subscribe_policy(my_friend,LinphoneSPAccept); /* accept Incoming subscription request for this friend*/ + +:cpp:type:`Friends ` status changes are reported by callback LinphoneCoreVTable.notify_presence_recv + +.. code-block:: c + + static void notify_presence_recv_updated (struct _LinphoneCore *lc, LinphoneFriend *friend) { + const LinphoneAddress* friend_address = linphone_friend_get_address(friend); + printf("New state state [%s] for user id [%s] \n" + ,linphone_online_status_to_string(linphone_friend_get_status(friend)) + ,linphone_address_as_string (friend_address)); + } + +Once created a buddy can be added to the buddy list using function :cpp:func:`linphone_core_add_friend`. Added friends will be notified +about :cpp:func:`local status changes `. + +Any subsequente modifications to :cpp:type:`LinphoneFriend` must be first started by a call to function :cpp:func:`linphone_friend_edit` and validated by function :cpp:func:`linphone_friend_done`. + +.. code-block:: c + + linphone_friend_edit(my_friend); /* start editing friend */ + linphone_friend_enable_subscribes(my_friend,FALSE); /*disable subscription for this friend*/ + linphone_friend_done(my_friend); /*commit changes triggering an UNSUBSCRIBE message*/ + + +Publishing presence status +-------------------------- + +Local presence status can be changed using function :cpp:func:`linphone_core_set_presence_model`. New status is propagated to all +friends :cpp:func:`previously added ` to :cpp:type:`LinphoneCore`. + + +Handling incoming subscription request +-------------------------------------- + +New incoming subscription requests are process according to :cpp:func:`the incoming subscription policy state ` for subscription +initiated by :cpp:func:`members of the buddy list `. + +For incoming request comming from an unknown buddy, the call back LinphoneCoreVTable.new_subscription_request is invoked. + +A complete tutorial can be found at : \ref buddy_tutorials "Registration tutorial" diff --git a/coreapi/help/doc/sphinx/guides/call_control.rst b/coreapi/help/doc/sphinx/guides/call_control.rst new file mode 100644 index 000000000..e6e959348 --- /dev/null +++ b/coreapi/help/doc/sphinx/guides/call_control.rst @@ -0,0 +1,9 @@ +Placing and receiving calls +=========================== + +The :cpp:type:`LinphoneCall` object represents an incoming or outgoing call managed by the :cpp:type:`LinphoneCore`. + +Outgoing calls can be created using :cpp:func:`linphone_core_invite` or :cpp:func:`linphone_core_invite_address`, while incoming calls are notified to the application +through the LinphoneCoreVTable::call_state_changed callback. + +.. seealso:: :ref:`"Basic Call" ` source code. diff --git a/coreapi/help/doc/sphinx/guides/call_logs.rst b/coreapi/help/doc/sphinx/guides/call_logs.rst new file mode 100644 index 000000000..cf68f06fe --- /dev/null +++ b/coreapi/help/doc/sphinx/guides/call_logs.rst @@ -0,0 +1,2 @@ +Managing call logs +================== diff --git a/coreapi/help/doc/sphinx/guides/call_misc.rst b/coreapi/help/doc/sphinx/guides/call_misc.rst new file mode 100644 index 000000000..d77b63b60 --- /dev/null +++ b/coreapi/help/doc/sphinx/guides/call_misc.rst @@ -0,0 +1,4 @@ +Obtaining information about a running call: sound volumes, quality indicators +============================================================================= + +When a call is running, it is possible to retrieve in real time current measured volumes and quality indicator. diff --git a/coreapi/help/doc/sphinx/guides/chatroom.rst b/coreapi/help/doc/sphinx/guides/chatroom.rst new file mode 100644 index 000000000..5d391845c --- /dev/null +++ b/coreapi/help/doc/sphinx/guides/chatroom.rst @@ -0,0 +1,28 @@ +Chat room and messaging +======================= +Exchanging text messages +------------------------ + +Messages are sent using :cpp:type:`LinphoneChatRoom` object. First step is to create a :cpp:func:`chat room ` +from a peer sip uri. + +.. code-block:: c + + LinphoneChatRoom* chat_room = linphone_core_get_chat_room(lc,"sip:joe@sip.linphone.org"); + +Once created, messages are sent using function :cpp:func:`linphone_chat_room_send_message`. + +.. code-block:: c + + linphone_chat_room_send_message(chat_room,"Hello world"); /*sending message*/ + +Incoming message are received from call back LinphoneCoreVTable.text_received + +.. code-block:: c + + void text_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from, const char *message) { + printf(" Message [%s] received from [%s] \n",message,linphone_address_as_string (from)); + } + +.. seealso:: A complete tutorial can be found at :ref:`"Chatroom and messaging" ` source code. + diff --git a/coreapi/help/doc/sphinx/guides/conferencing.rst b/coreapi/help/doc/sphinx/guides/conferencing.rst new file mode 100644 index 000000000..e89b2e3f7 --- /dev/null +++ b/coreapi/help/doc/sphinx/guides/conferencing.rst @@ -0,0 +1,21 @@ +Making an audio conference +========================== + +This API allows to create a conference entirely managed by the client. No server capabilities are required. + +The way such conference is created is by doing the following: + +#. The application shall makes "normal" calls to several destinations (using :cpp:func:`linphone_core_invite`), one after another. +#. While initiating the second call, the first one is automatically paused. +#. Then, once the second call is established, the application has the possibility to merge the two calls to form a conference where each participant + (the local participant, the remote destination of the first call, the remote destination of the second call) can talk together. + This must be done by adding the two calls to the conference using :cpp:func:`linphone_core_add_to_conference`. + +Once merged into a conference the :cpp:type:`LinphoneCall` objects representing the calls that were established remain unchanged, except that +they are tagged as part of the conference (see :cpp:func:`linphone_call_is_in_conference`). The calls in a conference are in the :cpp:enumerator:`LinphoneCallStreamsRunning` state. + +Only a single conference can be created: the purpose of this feature is to allow the local user to create, take part and manage the conference. +This API is not designed to create a conference server application. + +Up to 10 calls can be merged into the conference, however depending on the CPU usage required for doing the encoding/decoding of the streams of each participants, +the effective limit can be lower. diff --git a/coreapi/help/doc/sphinx/guides/event_api.rst b/coreapi/help/doc/sphinx/guides/event_api.rst new file mode 100644 index 000000000..b45f77fca --- /dev/null +++ b/coreapi/help/doc/sphinx/guides/event_api.rst @@ -0,0 +1,4 @@ +Managing generic subscriptions and publishes +============================================ + +The :cpp:type:`LinphoneEvent` api allows application to control subscriptions, receive notifications and make publish to peers, in a generic manner. diff --git a/coreapi/help/doc/sphinx/guides/initializing.rst b/coreapi/help/doc/sphinx/guides/initializing.rst new file mode 100644 index 000000000..c0e46073d --- /dev/null +++ b/coreapi/help/doc/sphinx/guides/initializing.rst @@ -0,0 +1,4 @@ +Initializing liblinphone +======================== + + diff --git a/coreapi/help/doc/sphinx/guides/ios_portability.rst b/coreapi/help/doc/sphinx/guides/ios_portability.rst new file mode 100644 index 000000000..84d8160d9 --- /dev/null +++ b/coreapi/help/doc/sphinx/guides/ios_portability.rst @@ -0,0 +1,285 @@ +iOS portability +=============== +Multitasking +------------ + +Liblinphone for IOS natively supports multitasking assuming application follows multitasking guides provided by Apple. + +First step is to declare application as multitasked. It means adding background mode for both audio and voip to Info.plist file. + +.. code-block:: xml + + UIBackgroundModes + + voip + audio + + + +SIP socket +^^^^^^^^^^ + +Recommended mode is SIP over TCP, because UDP usually requires frequent keep alives for maintaining NAT association at the IP router level. This can +be as frequent as one UDP packet every 15 seconds to maintain the NAT association accross NAT routers. Doing such drains the battery very fast, and +furthermore the iOS keep-alive designed by Apple to handle this task can only be called with a minimum of 10 minutes interval. + +For TCP, liblinphone automatically configures SIP socket for voip (I.E kCFStreamNetworkServiceType set to kCFStreamNetworkServiceTypeVoIP). + +.. note:: + + Since IOS > 4.1 Apple disabled voip mode for UDP sockets. + + +Entering background mode +^^^^^^^^^^^^^^^^^^^^^^^^ + +Before entering in background mode (through ``- (void)applicationDidEnterBackground:(UIApplication *)application``), the application must first refresh +sip registration using function :cpp:func:`linphone_core_refresh_registers` and register a keep-alive handler for periodically refreshing the registration. +The speudo code below shows how to register a keep alive handler: + +.. code-block:: objective-c + + //First refresh registration + linphone_core_refresh_registers(theLinphoneCore); + //wait for registration answer + int i=0; + while (!linphone_proxy_config_is_registered(proxyCfg) && i++<40 ) { + linphone_core_iterate(theLinphoneCore); + usleep(100000); + } + //register keepalive handler + [[UIApplication sharedApplication] setKeepAliveTimeout:600/*minimal interval is 600 s*/ + handler:^{ + //refresh sip registration + linphone_core_refresh_registers(theLinphoneCore); + //make sure sip REGISTER is sent + linphone_core_iterate(theLinphoneCore); + }]; + + +Incoming call notification while in background mode +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Assuming application using liblinphone is well configured for multitasking, incoming calls arriving while liblinphone is in background mode will simply wakeup +liblinphone thread but not resume GUI. To wakeup GUI, it is recommended to send a Local Notification to the user from the #LinphoneCoreCallStateChangedCb. Here +under a speudo code for this operation: + +.. code-block:: objective-c + + if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive) { + // Create a new notification + UILocalNotification* notif = [[[UILocalNotification alloc] init] autorelease]; + if (notif) { + notif.repeatInterval = 0; + notif.alertBody =@"New incoming call"; + notif.alertAction = @"Answer"; + notif.soundName = @"oldphone-mono-30s.caf"; + + [[UIApplication sharedApplication] presentLocalNotificationNow:notif]; + } + + +Networking +---------- +WWAN connection +^^^^^^^^^^^^^^^ + +Liblinphone relies on iOS's standard BSD socket layer for sip/rtp networking. On IOS, WWAN connection is supposed to automatically bring up on any networking +resquest issued by an application. At least on iPhone OS 3.x, BSD sockets do not implement this behavior. So it is recomended to add a special code to make sure +the WWAN connection is properly setup. Pseudo code below describes a way to force WWAN connection by setting up a dummy TCP connection. + +.. code-block:: objective-c + + /*start a new thread to avoid blocking the main ui in case of peer host failure*/ + [NSThread detachNewThreadSelector:@selector(runNetworkConnection) toTarget:self withObject:nil]; + -(void) runNetworkConnection { + CFWriteStreamRef writeStream; + //create a dummy socket + CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"192.168.0.200", 15000, nil, &writeStream); + CFWriteStreamOpen (writeStream); + const char* buff="hello"; + //try to write on this socket + CFWriteStreamWrite (writeStream,(const UInt8*)buff,strlen(buff)); + CFWriteStreamClose (writeStream); + } + +It is recommanded to perform this task each time the application is woken up, including keep alive handler. + + +Managing IP connection state +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Liblinphone for IOS relies on the application to be informed of network connectivity changes. Network state changes when the IP connection moves from DOWN to UP, +or from WIFI to WWAN. Applications using liblinphone must inform libliblinphone of this changes using function :cpp:func:`linphone_core_set_network_reachable`. +Usually this method is called from the IOS NetworkReachability callback. Here under a sample code: + +.. code-block:: c + + //typical reachability callback + void networkReachabilityCallBack(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void * info) { + if ((flags == 0) | (flags & (kSCNetworkReachabilityFlagsConnectionRequired |kSCNetworkReachabilityFlagsConnectionOnTraffic))) { + //network state is off + linphone_core_set_network_reachable(lc,false); + ((LinphoneManager*)info).connectivity = none; + } else { + Connectivity newConnectivity = flags & kSCNetworkReachabilityFlagsIsWWAN ? wwan:wifi; + if (lLinphoneMgr.connectivity == none) { + //notify new network state + linphone_core_set_network_reachable(lc,true); + } else if (lLinphoneMgr.connectivity != newConnectivity) { + // connectivity has changed + linphone_core_set_network_reachable(lc,false); + linphone_core_set_network_reachable(lc,true); + } + //store new connectivity status + lLinphoneMgr.connectivity=newConnectivity; + } + } + + +Sound cards +----------- + +Since IOS 5.0, liblinphone supports 2 sound cards. *AU: Audio Unit Receiver* based on IO units for voice calls plus *AQ: Audio Queue Device* dedicated to rings. +Here under the recommended settings (I.E default one) + +.. code-block:: c + + linphone_core_set_playback_device(lc, "AU: Audio Unit Receiver"); + linphone_core_set_ringer_device(lc, "AQ: Audio Queue Device"); + linphone_core_set_capture_device(lc, "AU: Audio Unit Receiver"); + + +GSM call interaction +-------------------- + +To ensure gentle interaction with GSM calls, it is recommended to register an AudioSession delegate. This allows the application to be notified when its audio +session is interrupted/resumed (presumably by a GSM call). + +.. code-block:: objective-c + + // declare a class handling the AVAudioSessionDelegate protocol + @interface MyClass : NSObject { [...] } + // implement 2 methods : here's an example implementation + -(void) beginInterruption { + LinphoneCall* c = linphone_core_get_current_call(theLinphoneCore); + ms_message("Sound interruption detected!"); + if (c) { + linphone_core_pause_call(theLinphoneCore, c); + } + } + + -(void) endInterruption { + ms_message("Sound interruption ended!"); + const MSList* c = linphone_core_get_calls(theLinphoneCore); + + if (c) { + ms_message("Auto resuming call"); + linphone_core_resume_call(theLinphoneCore, (LinphoneCall*) c->data); + } + } + +.. seealso:: http://developer.apple.com/library/ios/#documentation/AVFoundation/Reference/AVAudioSessionDelegate_ProtocolReference/Reference/Reference.html + +Declare an instance of your class as AudioSession's delegate : + +.. code-block:: objective-c + + [audioSession setDelegate:myClassInstance]; + +.. seealso:: http://developer.apple.com/library/ios/#documentation/AVFoundation/Reference/AVAudioSession_ClassReference/Reference/Reference.html + + +Video +----- + +Since 3.5 video support has been added to liblinphone for IOS. It requires the application to provide liblinphone with pointers to IOS's views hosting video +display and video previous. These two UIView objects must be passed to the core using functions :cpp:func:`linphone_core_set_native_video_window_id` and +:cpp:func:`linphone_core_set_native_preview_window_id`. Here under pseudo code: + +.. code-block:: objective-c + + UIView* display = [[UIView alloc] init]; + UIView* preview = [[UIView alloc] init]; + linphone_core_set_native_video_window_id(lc,(unsigned long)display); + linphone_core_set_native_preview_window_id(lc,(unsigned long)preview); + +Screen rotations are also handled by liblinphone. Two positions are currently supported, namely *UIInterfaceOrientationPortrait* and *UIInterfaceOrientationLandscapeRight*. +Applications may invoke :cpp:func:`linphone_core_set_device_rotation` followed by :cpp:func:`linphone_core_update_call` to notify liblinphone of an orientation +change. Here under a speudo code to handle orientation changes + +.. code-block:: c + + -(void) configureOrientation:(UIInterfaceOrientation) oritentation { + int oldLinphoneOrientation = linphone_core_get_device_rotation(lc); + if (oritentation == UIInterfaceOrientationPortrait ) { + linphone_core_set_native_video_window_id(lc,(unsigned long)display-portrait); + linphone_core_set_native_preview_window_id(lc,(unsigned long)preview-portrait); + linphone_core_set_device_rotation(lc, 0); + + } else if (oritentation == UIInterfaceOrientationLandscapeRight ) { + linphone_core_set_native_video_window_id(lc,(unsigned long)display-landscape); + linphone_core_set_native_preview_window_id(lc,(unsigned long)preview-landscape); + linphone_core_set_device_rotation(lc, 270); + } + + if ((oldLinphoneOrientation != linphone_core_get_device_rotation(lc)) + && linphone_core_get_current_call(lc)) { + //Orientation has changed, must call update call + linphone_core_update_call(lc, linphone_core_get_current_call(lc), NULL); + } + } + + +DTMF feedbacks +-------------- + +Liblinphone provides functions :cpp:func:`to play dtmf ` to the local user. Usually this is used to play a sound when the user +presses a digit, inside or outside of any call. On IOS, libLinphone relies on AudioUnits for interfacing with the audio system. Unfortunately the Audio Unit +initialization is a quite long operation that may trigger a bad user experience if performed each time a DTMF is played, the sound being delayed half a +second after the press. To solve this issue and thus insure real-time precision, liblinphone introduces two functions for :cpp:func:`preloading ` +and :cpp:func:`unloading ` the underlying audio graph responsible for playing DTMFs. + +For an application using function :cpp:func:`linphone_core_play_dtmf`, it is recommanded to call :cpp:func:`linphone_core_start_dtmf_stream` when entering +in foreground and #linphone_core_stop_dtmf_stream() upon entering background mode. + + +Plugins +------- + +On iOS, plugins are built as static libraries so Liblinphone will not be able to load them at runtime dynamically. Instead, you should declare their prototypes: + +.. code-block:: c + + extern void libmsamr_init(MSFactory *factory); + extern void libmsx264_init(MSFactory *factory); + extern void libmsopenh264_init(MSFactory *factory); + extern void libmssilk_init(MSFactory *factory); + extern void libmsbcg729_init(MSFactory *factory); + extern void libmswebrtc_init(MSFactory *factory); + + +Then you should register them after the instantiation of :cpp:type:`LinphoneCore`: + +.. code-block:: c + + theLinphoneCore = linphone_core_new_with_config(/* options ... */); + + // Load plugins if available in the linphone SDK - otherwise these calls will do nothing + MSFactory *f = linphone_core_get_ms_factory(theLinphoneCore); + libmssilk_init(f); + libmsamr_init(f); + libmsx264_init(f); + libmsopenh264_init(f); + libmsbcg729_init(f); + libmswebrtc_init(f); + linphone_core_reload_ms_plugins(theLinphoneCore, NULL); + + +If the plugin has not been enabled at compilation time, a stubbed library will be generated with only libplugin_init method declared, doing nothing. You should +see these trace in logs, if plugin is stubbed: + +.. code-block:: none + + I/lib/Could not find encoder for SILK + I/lib/Could not find decoder for SILK diff --git a/coreapi/help/doc/sphinx/guides/linphone_address.rst b/coreapi/help/doc/sphinx/guides/linphone_address.rst new file mode 100644 index 000000000..8dacb147e --- /dev/null +++ b/coreapi/help/doc/sphinx/guides/linphone_address.rst @@ -0,0 +1,4 @@ +SIP address parser API +====================== + +This api is useful for manipulating SIP addresses ('from' or 'to' headers). diff --git a/coreapi/help/doc/sphinx/guides/media_parameters.rst b/coreapi/help/doc/sphinx/guides/media_parameters.rst new file mode 100644 index 000000000..9a9318a66 --- /dev/null +++ b/coreapi/help/doc/sphinx/guides/media_parameters.rst @@ -0,0 +1,11 @@ +Controlling media parameters +============================ + +Multicast +--------- + +Call using rtp multicast addresses are supported for both audio and video with some limitations. Limitations are, no stun, no ice, no encryption. + +* Incoming call with multicast address are automatically accepted. The called party switches in a media receive only mode. +* Outgoing call willing to send media to a multicast address can activate multicast using :cpp:func:`linphone_core_enable_video_multicast` + or :cpp:func:`linphone_core_enable_audio_multicast`. The calling party switches in a media listen send only mode. diff --git a/coreapi/help/doc/sphinx/guides/misc.rst b/coreapi/help/doc/sphinx/guides/misc.rst new file mode 100644 index 000000000..292840e05 --- /dev/null +++ b/coreapi/help/doc/sphinx/guides/misc.rst @@ -0,0 +1,3 @@ +Miscenalleous: logs, version strings, config storage +==================================================== + diff --git a/coreapi/help/doc/sphinx/guides/network_parameters.rst b/coreapi/help/doc/sphinx/guides/network_parameters.rst new file mode 100644 index 000000000..86faebce6 --- /dev/null +++ b/coreapi/help/doc/sphinx/guides/network_parameters.rst @@ -0,0 +1,2 @@ +Controlling network parameters (ports, mtu…) +============================================ diff --git a/coreapi/help/doc/sphinx/guides/proxies.rst b/coreapi/help/doc/sphinx/guides/proxies.rst new file mode 100644 index 000000000..dd852b0b8 --- /dev/null +++ b/coreapi/help/doc/sphinx/guides/proxies.rst @@ -0,0 +1,76 @@ +Managing proxies +================ + +User registration is controled by :cpp:type:`LinphoneProxyConfig` settings. + +Each :cpp:type:`LinphoneProxyConfig` object can be configured with registration informations like :cpp:func:`proxy address `, +:cpp:func:`user id `, :cpp:func:`refresh period `, and so on. + +A created proxy config using :cpp:func:`linphone_proxy_config_new`, once configured, must be added to :cpp:type:`LinphoneCore` using function :cpp:func:`linphone_core_add_proxy_config`. + +It is recommended to set a default :cpp:type:`proxy config ` using function :cpp:func:`linphone_core_set_default_proxy`. Once done, +if :cpp:type:`proxy config ` has been configured with attribute :cpp:func:`enable register `, +next call to :cpp:func:`linphone_core_iterate` triggers SIP register. + +Registration status is reported by LinphoneCoreRegistrationStateChangedCb. + +This pseudo code demonstrates basic registration operations: + +.. code-block:: c + + LinphoneProxyConfig* proxy_cfg; + /*create proxy config*/ + proxy_cfg = linphone_proxy_config_new(); + /*parse identity*/ + LinphoneAddress *from = linphone_address_new("sip:toto@sip.titi.com"); + LinphoneAuthInfo *info; + if (password!=NULL){ + info=linphone_auth_info_new(linphone_address_get_username(from),NULL,"secret",NULL,NULL); /*create authentication structure from identity*/ + linphone_core_add_auth_info(lc,info); /*add authentication info to LinphoneCore*/ + } + // configure proxy entries + linphone_proxy_config_set_identity(proxy_cfg,identity); /*set identity with user name and domain*/ + const char* server_addr = linphone_address_get_domain(from); /*extract domain address from identity*/ + linphone_proxy_config_set_server_addr(proxy_cfg,server_addr); /* we assume domain = proxy server address*/ + linphone_proxy_config_enable_register(proxy_cfg,TRUE); /*activate registration for this proxy config*/ + linphone_address_destroy(from); /*release resource*/ + + linphone_core_add_proxy_config(lc,proxy_cfg); /*add proxy config to linphone core*/ + linphone_core_set_default_proxy(lc,proxy_cfg); /*set to default proxy*/ + +Registration sate call back: + +.. code-block:: c + + static void registration_state_changed(struct _LinphoneCore *lc, LinphoneProxyConfig *cfg, LinphoneRegistrationState cstate, const char *message){ + printf("New registration state %s for user id [%s] at proxy [%s]\n" + ,linphone_registration_state_to_string(cstate) + ,linphone_proxy_config_get_identity(cfg) + ,linphone_proxy_config_get_addr(cfg)); + } + +Authentication +-------------- + +Most of the time, registration requires :doc:`authentication ` to succeed. :cpp:type:`LinphoneAuthInfo` info must be either added +to :cpp:type:`LinphoneCore` using function :cpp:func:`linphone_core_add_auth_info` before :cpp:type:`LinphoneProxyConfig` is added to Linphone core, or on demand +from call back #LinphoneCoreAuthInfoRequestedCb. + +Unregistration +-------------- + +Unregistration or any changes to :cpp:type:`LinphoneProxyConfig` must be first started by a call to function :cpp:func:`linphone_proxy_config_edit` and validated by +function :cpp:func:`linphone_proxy_config_done`. + +This pseudo code shows how to unregister a user associated to a #LinphoneProxyConfig: + +.. code-block:: c + + LinphoneProxyConfig* proxy_cfg; + linphone_core_get_default_proxy(lc,&proxy_cfg); /* get default proxy config*/ + linphone_proxy_config_edit(proxy_cfg); /*start editing proxy configuration*/ + linphone_proxy_config_enable_register(proxy_cfg,FALSE); /*de-activate registration for this proxy config*/ + linphone_proxy_config_done(proxy_cfg); /*initiate REGISTER with expire = 0*/ + +.. seealso:: A complete tutorial can be found at: :ref:`"Basic registration" ` source code. + diff --git a/coreapi/help/doc/sphinx/index.rst b/coreapi/help/doc/sphinx/index.rst new file mode 100644 index 000000000..03500afe6 --- /dev/null +++ b/coreapi/help/doc/sphinx/index.rst @@ -0,0 +1,70 @@ +.. Linphone API documentation master file, created by + sphinx-quickstart on Mon Jun 19 11:58:21 2017. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to Linphone API's documentation! +======================================== +What is liblinphone +------------------- + +Liblinphone is a high level library for bringing SIP video call functionnality +into an application. It aims at making easy the integration of the SIP +video calls into any applications. All variants of linphone are directly based +on it: + +* linphone (gtk interface) +* linphonec (console interface) +* linphone for iOS +* linphone for Android + +Liblinphone is GPL (see COPYING file). Please understand the licencing details +before using it! + +For any use of this library beyond the rights granted to you by the +GPL license, please contact Belledonne Communications +(contact@belledonne-communications.com). + + +Beginners' guides +----------------- + +.. toctree:: + :maxdepth: 1 + + guides/initializing + guides/call_control + guides/call_misc + guides/media_parameters + guides/proxies + guides/network_parameters + guides/authentication + guides/buddy_list + guides/chatroom + guides/call_logs + guides/linphone_address + guides/conferencing + guides/event_api + guides/misc + guides/ios_portability + + +Code samples +------------ + +.. toctree:: + :maxdepth: 1 + + samples/samples + + +API's reference documentation +----------------------------- + +.. toctree:: + :maxdepth: 1 + + reference/c/index + reference/cpp/index + reference/java/index + reference/csharp/index diff --git a/coreapi/help/doc/sphinx/index_page.mustache b/coreapi/help/doc/sphinx/index_page.mustache index 2fa38ec83..f494d825e 100644 --- a/coreapi/help/doc/sphinx/index_page.mustache +++ b/coreapi/help/doc/sphinx/index_page.mustache @@ -1,19 +1,8 @@ -{{#make_section}}{{{language}}} API{{/make_section}} - -Index of classes ----------------- +{{{title}}} .. toctree:: :maxdepth: 1 - - {{#tocEntries}} - {{{entryName}}} - {{/tocEntries}} -Index of enums --------------- - -.. toctree:: - :maxdepth 1 - - enums.rst + {{#entries}} + {{{filename}}} + {{/entries}} diff --git a/coreapi/help/doc/sphinx/logo.png b/coreapi/help/doc/sphinx/logo.png new file mode 100644 index 000000000..de261e94a Binary files /dev/null and b/coreapi/help/doc/sphinx/logo.png differ diff --git a/coreapi/help/doc/sphinx/samples/samples.rst b/coreapi/help/doc/sphinx/samples/samples.rst new file mode 100644 index 000000000..8d4cc6024 --- /dev/null +++ b/coreapi/help/doc/sphinx/samples/samples.rst @@ -0,0 +1,106 @@ +.. _basic_call_code_sample: + +Basic call +========== + +This program is a *very* simple usage example of liblinphone. It just takes a sip-uri as first argument and attempts to call it + +.. literalinclude:: helloworld.c + :language: c + + +.. _basic_registration_code_sample: + +Basic registration +================== + +This program is a *very* simple usage example of liblinphone, desmonstrating how to initiate a SIP registration from a sip uri identity +passed from the command line. First argument must be like sip:jehan@sip.linphone.org , second must be *password* . Registration is cleared +on *SIGINT*. + +Example: ``registration sip:jehan@sip.linphone.org secret`` + +.. literalinclude:: registration.c + :language: c + + +.. _subscribe_notify_code_sample: + +Generic subscribe/notify example +================================ + +This program is a *very* simple usage example of liblinphone. It demonstrates how to listen to a SIP subscription. +It then sends notify requests back periodically. First argument must be like sip:jehan@sip.linphone.org , second must be *password*. +Registration is cleared on *SIGINT*. + +Example: ``registration sip:jehan@sip.linphone.org secret`` + +.. literalinclude:: registration.c + :language: c + + + +.. _buddy_status_notification_code_sample: + +Basic buddy status notification +=============================== + +This program is a *very* simple usage example of liblinphone, demonstrating how to initiate SIP subscriptions and receive +notifications from a sip uri identity passed from the command line. Argument must be like sip:jehan@sip.linphone.org . +Subscription is cleared on *SIGINT* signal. + +Example: ``budy_list sip:jehan@sip.linphone.org`` + +.. literalinclude:: buddy_status.c + :language: c + + +.. _chatroom_code_sample: + +Chat room and messaging +======================= + +This program is a *very* simple usage example of liblinphone, desmonstrating how to send/receive SIP MESSAGE from a sip uri +identity passed from the command line. Argument must be like sip:jehan@sip.linphone.org . + +Example: ``chatroom sip:jehan@sip.linphone.org`` + +.. literalinclude:: chatroom.c + :language: c + + +.. _file_transfer_code_sample: + +File transfer +============= + +.. literalinclude:: filetransfer.c + :language: c + + + +.. _RT text receiver_code_sample: + +Real Time Text Receiver +======================= + +This program is able to receive chat message in real time on port 5060. Use realtimetext_sender to generate chat message + +Example: ``./realtimetext_receiver`` + +.. literalinclude:: realtimetext_sender.c + :language: c + + +.. _RT_text_sender_code_sample: + +Real Time Text Sender +===================== + +This program just send chat message in real time to dest uri. Use realtimetext_receiver to receive message. + +Example: ``./realtimetext_sender sip:localhost:5060`` + +.. literalinclude:: realtimetext_sender.c + :language: c + diff --git a/coreapi/help/doc/sphinx/source/index.rst b/coreapi/help/doc/sphinx/source/index.rst deleted file mode 100644 index 530adfcc3..000000000 --- a/coreapi/help/doc/sphinx/source/index.rst +++ /dev/null @@ -1,24 +0,0 @@ -.. Linphone API documentation master file, created by - sphinx-quickstart on Mon Jun 19 11:58:21 2017. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to Linphone API's documentation! -======================================== - -.. toctree:: - :maxdepth: 1 - :caption: Contents: - - c/index.rst - cpp/index.rst - csharp/index.rst - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - diff --git a/coreapi/help/examples/C/CMakeLists.txt b/coreapi/help/examples/C/CMakeLists.txt index e89cde8db..cc0ef95a4 100644 --- a/coreapi/help/examples/C/CMakeLists.txt +++ b/coreapi/help/examples/C/CMakeLists.txt @@ -24,8 +24,18 @@ if (ENABLE_TOOLS) if (IOS) set(USE_BUNDLE MACOSX_BUNDLE) endif() - file(GLOB EXECUTABLES_SOURCE RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.c") - foreach(EXECUTABLE ${EXECUTABLES_SOURCE}) + set(LINPHONE_C_EXAMPLES_SOURCE + ${CMAKE_CURRENT_SOURCE_DIR}/buddy_status.c + ${CMAKE_CURRENT_SOURCE_DIR}/chatroom.c + ${CMAKE_CURRENT_SOURCE_DIR}/filetransfer.c + ${CMAKE_CURRENT_SOURCE_DIR}/helloworld.c + ${CMAKE_CURRENT_SOURCE_DIR}/notify.c + ${CMAKE_CURRENT_SOURCE_DIR}/realtimetext_receiver.c + ${CMAKE_CURRENT_SOURCE_DIR}/realtimetext_sender.c + ${CMAKE_CURRENT_SOURCE_DIR}/registration.c + PARENT_SCOPE + ) + foreach(EXECUTABLE ${LINPHONE_C_EXAMPLES_SOURCE}) string(REPLACE ".c" "" EXECUTABLE_NAME ${EXECUTABLE}) bc_apply_compile_flags(${EXECUTABLE} STRICT_OPTIONS_CPP STRICT_OPTIONS_C) add_executable(${EXECUTABLE_NAME} ${USE_BUNDLE} ${EXECUTABLE}) diff --git a/coreapi/info.c b/coreapi/info.c index 5b12089bb..f68bb4522 100644 --- a/coreapi/info.c +++ b/coreapi/info.c @@ -23,6 +23,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include "linphone/api/c-content.h" #include "linphone/core.h" #include "linphone/lpconfig.h" diff --git a/coreapi/lime.c b/coreapi/lime.c index 4270f9d2a..b19eae8be 100644 --- a/coreapi/lime.c +++ b/coreapi/lime.c @@ -17,6 +17,8 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include "linphone/api/c-content.h" + #include "lime.h" #ifdef HAVE_CONFIG_H #include "config.h" @@ -315,7 +317,7 @@ static int lime_deriveKey(limeKey_t *key) { return LIME_UNABLE_TO_DERIVE_KEY; } - /* Derivation is made derived Key = HMAC_SHA256(Key, 0x0000001||"MessageKey"||0x00||SessionId||SessionIndex||0x00000100)*/ + /* Derivation is made derived Key = HMAC_SHA256(Key, 0x0000001||"MessageKey"||0x00||SessionId||SessionIndex||0x00000100)*/ /* total data to be hashed is 55 bytes : 4 + 10 + 1 + 32 + 4 + 4 */ inputData[0] = 0x00; inputData[1] = 0x00; @@ -419,6 +421,8 @@ int lime_encryptFile(void **cryptoContext, unsigned char *key, size_t length, ch int lime_decryptFile(void **cryptoContext, unsigned char *key, size_t length, char *plain, char *cipher) { bctbx_aes_gcm_context_t *gcmContext; + if (key == NULL) return -1; + if (*cryptoContext == NULL) { /* first call to the function, allocate a crypto context and initialise it */ /* key contains 192bits of key || 64 bits of Initialisation Vector, no additional data */ gcmContext = bctbx_aes_gcm_context_new(key, 24, NULL, 0, key+24, 8, BCTBX_GCM_DECRYPT); @@ -481,6 +485,9 @@ int lime_createMultipartMessage(void *cachedb, const char *contentType, uint8_t if (bzrtp_getSelfZID(cachedb, selfURI, selfZid, NULL) != 0) { return LIME_UNABLE_TO_ENCRYPT_MESSAGE; } + if (message == NULL || contentType == NULL) { + return LIME_UNABLE_TO_ENCRYPT_MESSAGE; + } /* encrypted message length is plaintext + 16 for tag */ encryptedMessageLength = (uint32_t)strlen((char *)message) + 16; @@ -787,8 +794,8 @@ int lime_im_encryption_engine_process_incoming_message_cb(LinphoneImEncryptionEn LinphoneCore *lc = linphone_im_encryption_engine_get_core(engine); int errcode = -1; /* check if we have a xml/cipher message to be decrypted */ - if (linphone_chat_message_get_content_type(msg) && - (strcmp("xml/cipher", linphone_chat_message_get_content_type(msg)) == 0 || + if (linphone_chat_message_get_content_type(msg) && + (strcmp("xml/cipher", linphone_chat_message_get_content_type(msg)) == 0 || strcmp("application/cipher.vnd.gsma.rcs-ft-http+xml", linphone_chat_message_get_content_type(msg)) == 0)) { errcode = 0; int retval; @@ -798,6 +805,8 @@ int lime_im_encryption_engine_process_incoming_message_cb(LinphoneImEncryptionEn char *peerUri = NULL; char *selfUri = NULL; + ms_debug("Content type is known (%s), try to decrypt it", linphone_chat_message_get_content_type(msg)); + zrtp_cache_db = linphone_core_get_zrtp_cache_db(lc); if (zrtp_cache_db == NULL) { ms_warning("Unable to load content of ZRTP ZID cache to decrypt message"); @@ -807,7 +816,7 @@ int lime_im_encryption_engine_process_incoming_message_cb(LinphoneImEncryptionEn peerUri = linphone_address_as_string_uri_only(linphone_chat_message_get_from_address(msg)); selfUri = linphone_address_as_string_uri_only(linphone_chat_message_get_to_address(msg)); retval = lime_decryptMultipartMessage(zrtp_cache_db, (uint8_t *)linphone_chat_message_get_text(msg), selfUri, peerUri, &decrypted_body, &decrypted_content_type, - bctbx_time_string_to_sec(lp_config_get_string(lc->config, "sip", "lime_key_validity", "0"))); + bctbx_time_string_to_sec(lp_config_get_string(lc->config, "sip", "lime_key_validity", "0"))); ms_free(peerUri); ms_free(selfUri); if (retval != 0) { @@ -820,9 +829,11 @@ int lime_im_encryption_engine_process_incoming_message_cb(LinphoneImEncryptionEn linphone_chat_message_set_text(msg, (char *)decrypted_body); ms_free(decrypted_body); if (decrypted_content_type != NULL) { + ms_debug("Decrypted content type is ", decrypted_content_type); linphone_chat_message_set_content_type(msg, decrypted_content_type); ms_free(decrypted_content_type); } else { + ms_debug("Decrypted content type is unknown, use plain/text or application/vnd.gsma.rcs-ft-http+xml"); if (strcmp("application/cipher.vnd.gsma.rcs-ft-http+xml", linphone_chat_message_get_content_type(msg)) == 0) { linphone_chat_message_set_content_type(msg, "application/vnd.gsma.rcs-ft-http+xml"); } else { @@ -830,6 +841,8 @@ int lime_im_encryption_engine_process_incoming_message_cb(LinphoneImEncryptionEn } } } + } else { + ms_message("Content type is unknown (%s), don't try to decrypt it", linphone_chat_message_get_content_type(msg)); } return errcode; } @@ -844,9 +857,9 @@ int lime_im_encryption_engine_process_outgoing_message_cb(LinphoneImEncryptionEn if (linphone_chat_message_get_content_type(msg)) { if (strcmp(linphone_chat_message_get_content_type(msg), "application/vnd.gsma.rcs-ft-http+xml") == 0) { /* It's a file transfer, content type shall be set to application/cipher.vnd.gsma.rcs-ft-http+xml - TODO: As of january 2017, the content type is now included in the encrypted body, this - application/cipher.vnd.gsma.rcs-ft-http+xml is kept for compatibility with previous versions, - but may be dropped in the future to use xml/cipher instead. */ + TODO: As of january 2017, the content type is now included in the encrypted body, this + application/cipher.vnd.gsma.rcs-ft-http+xml is kept for compatibility with previous versions, + but may be dropped in the future to use xml/cipher instead. */ new_content_type = "application/cipher.vnd.gsma.rcs-ft-http+xml"; } else if (strcmp(linphone_chat_message_get_content_type(msg), "application/im-iscomposing+xml") == 0) { /* We don't encrypt composing messages */ @@ -893,49 +906,48 @@ int lime_im_encryption_engine_process_downloading_file_cb(LinphoneImEncryptionEn LinphoneContent *content = linphone_chat_message_get_file_transfer_information(msg); if (!content) return -1; - if (!linphone_content_get_key(content)) { - linphone_content_unref(content); + + if (!linphone_content_get_key(content)) return -1; - } - if (!buffer || (size == 0)) { - int result = lime_decryptFile(linphone_content_get_cryptoContext_address(content), NULL, 0, NULL, NULL); - linphone_content_unref(content); - return result; - } + if (!buffer || size == 0) + return lime_decryptFile(linphone_content_get_cryptoContext_address(content), NULL, 0, NULL, NULL); - int result = lime_decryptFile(linphone_content_get_cryptoContext_address(content), - (unsigned char *)linphone_content_get_key(content), size, (char *)decrypted_buffer, (char *)buffer); - linphone_content_unref(content); - return result; + return lime_decryptFile( + linphone_content_get_cryptoContext_address(content), + (unsigned char *)linphone_content_get_key(content), + size, + (char *)decrypted_buffer, + (char *)buffer + ); } int lime_im_encryption_engine_process_uploading_file_cb(LinphoneImEncryptionEngine *engine, LinphoneChatMessage *msg, size_t offset, const uint8_t *buffer, size_t *size, uint8_t *encrypted_buffer) { LinphoneContent *content = linphone_chat_message_get_file_transfer_information(msg); + if (!content) return -1; - if (!linphone_content_get_key(content)) { - linphone_content_unref(content); + + if (!linphone_content_get_key(content)) return -1; - } - if (!buffer || (*size == 0)) { - int result = lime_encryptFile(linphone_content_get_cryptoContext_address(content), NULL, 0, NULL, NULL); - linphone_content_unref(content); - return result; - } + if (!buffer || *size == 0) + return lime_encryptFile(linphone_content_get_cryptoContext_address(content), NULL, 0, NULL, NULL); - size_t file_size = linphone_content_get_size(content); + size_t file_size = linphone_content_get_file_size(content); if (file_size == 0) { ms_warning("File size has not been set, encryption will fail if not done in one step (if file is larger than 16K)"); } else if (offset + *size < file_size) { *size -= (*size % 16); } - int result = lime_encryptFile(linphone_content_get_cryptoContext_address(content), - (unsigned char *)linphone_content_get_key(content), *size, (char *)buffer, (char *)encrypted_buffer); - linphone_content_unref(content); - return result; + return lime_encryptFile( + linphone_content_get_cryptoContext_address(content), + (unsigned char *)linphone_content_get_key(content), + *size, + (char *)buffer, + (char *)encrypted_buffer + ); } bool_t lime_im_encryption_engine_is_file_encryption_enabled_cb(LinphoneImEncryptionEngine *engine, LinphoneChatRoom *room) { @@ -949,10 +961,8 @@ void lime_im_encryption_engine_generate_file_transfer_key_cb(LinphoneImEncryptio * file_transfer_information->key field of the msg */ sal_get_random_bytes((unsigned char *)keyBuffer, FILE_TRANSFER_KEY_SIZE); LinphoneContent *content = linphone_chat_message_get_file_transfer_information(msg); - if (!content) - return; - linphone_content_set_key(content, keyBuffer, FILE_TRANSFER_KEY_SIZE); /* key is duplicated in the content private structure */ - linphone_content_unref(content); + if (content) + linphone_content_set_key(content, keyBuffer, FILE_TRANSFER_KEY_SIZE); /* key is duplicated in the content private structure */ } #else /* HAVE_LIME */ diff --git a/coreapi/linphone_tunnel.cc b/coreapi/linphone_tunnel.cc index c82876105..6c3589147 100644 --- a/coreapi/linphone_tunnel.cc +++ b/coreapi/linphone_tunnel.cc @@ -28,6 +28,7 @@ #include "linphone/core.h" #include "private.h" #include "linphone/lpconfig.h" +#include "c-wrapper/c-wrapper.h" LinphoneTunnel* linphone_core_get_tunnel(const LinphoneCore *lc){ return lc->tunnel; @@ -42,13 +43,13 @@ struct _LinphoneTunnel { static void _linphone_tunnel_uninit(LinphoneTunnel *tunnel); BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneTunnel); -BELLE_SIP_DECLARE_VPTR(LinphoneTunnel); +BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneTunnel); BELLE_SIP_INSTANCIATE_VPTR(LinphoneTunnel, belle_sip_object_t, _linphone_tunnel_uninit, // uninit NULL, // clone NULL, // marshal FALSE // unowned -) +); extern "C" LinphoneTunnel* linphone_core_tunnel_new(LinphoneCore *lc){ LinphoneTunnel* tunnel = belle_sip_object_new(LinphoneTunnel); @@ -231,13 +232,13 @@ static void linphone_tunnel_add_server_intern(LinphoneTunnel *tunnel, LinphoneTu linphone_tunnel_config_get_port(tunnel_config), linphone_tunnel_config_get_host2(tunnel_config), linphone_tunnel_config_get_port2(tunnel_config), - linphone_tunnel_config_get_remote_udp_mirror_port(tunnel_config), - linphone_tunnel_config_get_delay(tunnel_config)); + (unsigned int)linphone_tunnel_config_get_remote_udp_mirror_port(tunnel_config), + (unsigned int)linphone_tunnel_config_get_delay(tunnel_config)); } else { bcTunnel(tunnel)->addServer(linphone_tunnel_config_get_host(tunnel_config), linphone_tunnel_config_get_port(tunnel_config), - linphone_tunnel_config_get_remote_udp_mirror_port(tunnel_config), - linphone_tunnel_config_get_delay(tunnel_config)); + (unsigned int)linphone_tunnel_config_get_remote_udp_mirror_port(tunnel_config), + (unsigned int)linphone_tunnel_config_get_delay(tunnel_config)); } } else if (linphone_tunnel_config_get_host2(tunnel_config) != NULL) { bcTunnel(tunnel)->addServerPair(linphone_tunnel_config_get_host(tunnel_config), diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 856c26ba5..6205237d1 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -18,10 +18,12 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include "linphone/api/c-content.h" #include "linphone/core.h" -#include "linphone/sipsetup.h" #include "linphone/lpconfig.h" #include "linphone/logging.h" +#include "linphone/sipsetup.h" + #include "private.h" #include "logging-private.h" #include "quality_reporting.h" @@ -56,7 +58,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "chat/chat-room/client-group-chat-room-p.h" #include "chat/chat-room/client-group-to-basic-chat-room.h" #include "chat/chat-room/server-group-chat-room-p.h" +#include "conference/handlers/local-conference-list-event-handler.h" #include "conference/handlers/remote-conference-event-handler.h" +#include "conference/handlers/remote-conference-list-event-handler.h" #include "content/content-manager.h" #include "content/content-type.h" #include "core/core-p.h" @@ -370,6 +374,14 @@ void linphone_core_cbs_set_notify_received(LinphoneCoreCbs *cbs, LinphoneCoreCbs cbs->vtable->notify_received = cb; } +LinphoneCoreCbsSubscribeReceivedCb linphone_core_cbs_get_subscribe_received(LinphoneCoreCbs *cbs) { + return cbs->vtable->subscribe_received; +} + +void linphone_core_cbs_set_subscribe_received(LinphoneCoreCbs *cbs, LinphoneCoreCbsSubscribeReceivedCb cb) { + cbs->vtable->subscribe_received = cb; +} + LinphoneCoreCbsPublishStateChangedCb linphone_core_cbs_get_rpublish_state_changed(LinphoneCoreCbs *cbs) { return cbs->vtable->publish_state_changed; } @@ -495,7 +507,7 @@ const LinphoneAddress *linphone_core_get_current_call_remote_address(struct _Lin static void linphone_core_log_collection_handler(const char *domain, OrtpLogLevel level, const char *fmt, va_list args); -void linphone_core_set_log_handler(OrtpLogFunc logfunc) { +void _linphone_core_set_log_handler(OrtpLogFunc logfunc) { liblinphone_user_log_func = logfunc; if (liblinphone_current_log_func == linphone_core_log_collection_handler) { ms_message("There is already a log collection handler, keep it"); @@ -504,9 +516,13 @@ void linphone_core_set_log_handler(OrtpLogFunc logfunc) { } } +void linphone_core_set_log_handler(OrtpLogFunc logfunc){ + _linphone_core_set_log_handler(logfunc); +} + void linphone_core_set_log_file(FILE *file) { if (file == NULL) file = stdout; - linphone_core_set_log_handler(NULL); + _linphone_core_set_log_handler(NULL); bctbx_set_log_file(file); /*gather everythings*/ } @@ -515,14 +531,17 @@ void linphone_core_set_log_level(OrtpLogLevel loglevel) { linphone_logging_service_set_log_level(log_service, _bctbx_log_level_to_linphone_log_level(loglevel)); } + void linphone_core_set_log_level_mask(unsigned int mask) { LinphoneLoggingService *log_service = linphone_logging_service_get(); linphone_logging_service_set_log_level_mask(log_service, _bctbx_log_mask_to_linphone_log_mask(mask)); } + unsigned int linphone_core_get_log_level_mask(void) { LinphoneLoggingService *log_service = linphone_logging_service_get(); return linphone_logging_service_get_log_level_mask(log_service); } + static int _open_log_collection_file_with_idx(int idx) { struct stat statbuf; char *log_filename; @@ -625,8 +644,8 @@ static void linphone_core_log_collection_handler(const char *domain, OrtpLogLeve } if (liblinphone_log_collection_file) { ortp_mutex_lock(&liblinphone_log_collection_mutex); - ret = fprintf(liblinphone_log_collection_file,"%i-%.2i-%.2i %.2i:%.2i:%.2i:%.3i %s %s\n", - 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec, (int)(tp.tv_usec / 1000), lname, msg); + ret = fprintf(liblinphone_log_collection_file,"%i-%.2i-%.2i %.2i:%.2i:%.2i:%.3i [%s] %s %s\n", + 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec, (int)(tp.tv_usec / 1000), domain, lname, msg); fflush(liblinphone_log_collection_file); if (ret > 0) { liblinphone_log_collection_file_size += (size_t)ret; @@ -850,7 +869,7 @@ static void process_response_from_post_file_log_collection(void *data, const bel cur = cur->xmlChildrenNode; /* now loop on the content of the file-info node */ while (cur != NULL) { if (!xmlStrcmp(cur->name, (const xmlChar *)"data")) { - file_url = xmlGetProp(cur, (const xmlChar *)"url"); + file_url = xmlGetProp(cur, (const xmlChar *)"url"); } cur=cur->next; } @@ -864,7 +883,9 @@ static void process_response_from_post_file_log_collection(void *data, const bel } if (file_url != NULL) { linphone_core_notify_log_collection_upload_state_changed(core, LinphoneCoreLogCollectionUploadStateDelivered, (const char *)file_url); + xmlFree(file_url); } + xmlFreeDoc(xmlMessageBody); clean_log_collection_upload_context(core); } else { ms_error("Unexpected HTTP response code %i during log collection upload to %s", code, linphone_core_get_log_collection_upload_server_url(core)); @@ -1047,13 +1068,13 @@ void linphone_core_reset_log_collection(void) { void linphone_core_enable_logs(FILE *file){ if (file==NULL) file=stdout; - ortp_set_log_file(file); + linphone_core_set_log_file(file); linphone_core_set_log_level(ORTP_MESSAGE); } void linphone_core_enable_logs_with_cb(OrtpLogFunc logfunc){ + _linphone_core_set_log_handler(logfunc); linphone_core_set_log_level(ORTP_MESSAGE); - linphone_core_set_log_handler(logfunc); } void linphone_core_disable_logs(void){ @@ -1267,11 +1288,15 @@ static void certificates_config_read(LinphoneCore *lc) { char *root_ca_path = bctbx_strdup_printf("%s/rootca.pem", data_dir); const char *rootca = lp_config_get_string(lc->config,"sip","root_ca", NULL); // If rootca is not existing anymore, we reset it to the default value - if (rootca == NULL || (bctbx_file_exist(rootca) != 0)) { + if (rootca == NULL || ((bctbx_file_exist(rootca) != 0) && (!bctbx_directory_exists(rootca)))) { #ifdef __linux - struct stat sb; - if (stat("/etc/ssl/certs", &sb) == 0 && S_ISDIR(sb.st_mode)) { - rootca = "/etc/ssl/certs"; + #ifdef __ANDROID__ + const char *possible_rootca = "/system/etc/security/cacerts"; + #else + const char *possible_rootca = "/etc/ssl/certs"; + #endif + if (bctbx_directory_exists(possible_rootca)) { + rootca = possible_rootca; } else #endif { @@ -1294,12 +1319,12 @@ static void sip_config_read(LinphoneCore *lc) { int ipv6_default = TRUE; if (lp_config_get_int(lc->config,"sip","use_session_timers",0)==1){ - lc->sal->use_session_timers(200); + lc->sal->useSessionTimers(200); } - lc->sal->use_no_initial_route(!!lp_config_get_int(lc->config,"sip","use_no_initial_route",0)); - lc->sal->use_rport(!!lp_config_get_int(lc->config,"sip","use_rport",1)); - lc->sal->set_contact_linphone_specs(lp_config_get_string(lc->config, "sip", "linphone_specs", NULL)); + lc->sal->useNoInitialRoute(!!lp_config_get_int(lc->config,"sip","use_no_initial_route",0)); + lc->sal->useRport(!!lp_config_get_int(lc->config,"sip","use_rport",1)); + lc->sal->setContactLinphoneSpecs(lp_config_get_string(lc->config, "sip", "linphone_specs", "")); if (!lp_config_get_int(lc->config,"sip","ipv6_migration_done",FALSE) && lp_config_has_entry(lc->config,"sip","use_ipv6")) { lp_config_clean_entry(lc->config,"sip","use_ipv6"); @@ -1318,7 +1343,7 @@ static void sip_config_read(LinphoneCore *lc) { certificates_config_read(lc); /*setting the dscp must be done before starting the transports, otherwise it is not taken into effect*/ - lc->sal->set_dscp(linphone_core_get_sip_dscp(lc)); + lc->sal->setDscp(linphone_core_get_sip_dscp(lc)); /*start listening on ports*/ linphone_core_set_sip_transports(lc,&tr); @@ -1384,7 +1409,7 @@ static void sip_config_read(LinphoneCore *lc) { linphone_core_set_media_encryption(lc,linphone_core_get_media_encryption(lc)); /*enable the reconnection to the primary server when it is up again asap*/ - lc->sal->enable_reconnect_to_primary_asap(!!lp_config_get_int(lc->config,"sip","reconnect_to_primary_asap",0)); + lc->sal->enableReconnectToPrimaryAsap(!!lp_config_get_int(lc->config,"sip","reconnect_to_primary_asap",0)); /*for tuning or test*/ lc->sip_conf.sdp_200_ack = !!lp_config_get_int(lc->config,"sip","sdp_200_ack",0); @@ -1397,12 +1422,12 @@ static void sip_config_read(LinphoneCore *lc) { lc->sip_conf.keepalive_period = (unsigned int)lp_config_get_int(lc->config,"sip","keepalive_period",10000); lc->sip_conf.tcp_tls_keepalive = !!lp_config_get_int(lc->config,"sip","tcp_tls_keepalive",0); linphone_core_enable_keep_alive(lc, (lc->sip_conf.keepalive_period > 0)); - lc->sal->use_one_matching_codec_policy(!!lp_config_get_int(lc->config,"sip","only_one_codec",0)); - lc->sal->use_dates(!!lp_config_get_int(lc->config,"sip","put_date",0)); - lc->sal->enable_sip_update_method(!!lp_config_get_int(lc->config,"sip","sip_update",1)); + lc->sal->useOneMatchingCodecPolicy(!!lp_config_get_int(lc->config,"sip","only_one_codec",0)); + lc->sal->useDates(!!lp_config_get_int(lc->config,"sip","put_date",0)); + lc->sal->enableSipUpdateMethod(!!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)); - lc->sal->set_supported_tags(lp_config_get_string(lc->config,"sip","supported","replaces, outbound, gruu")); + lc->sal->setSupportedTags(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); } @@ -1460,8 +1485,10 @@ static void rtp_config_read(LinphoneCore *lc) { linphone_core_set_avpf_mode(lc,static_cast(lp_config_get_int(lc->config,"rtp","avpf",LinphoneAVPFDisabled))); if ((tmp=lp_config_get_string(lc->config,"rtp","audio_multicast_addr",NULL))) linphone_core_set_audio_multicast_addr(lc,tmp); - else + else { + if (lc->rtp_conf.audio_multicast_addr) bctbx_free(lc->rtp_conf.audio_multicast_addr); lc->rtp_conf.audio_multicast_addr=ms_strdup("224.1.2.3"); + } if ((tmp_int=lp_config_get_int(lc->config,"rtp","audio_multicast_enabled",-1)) >-1) linphone_core_enable_audio_multicast(lc, !!tmp_int); if ((tmp_int=lp_config_get_int(lc->config,"rtp","audio_multicast_ttl",-1))>0) @@ -1470,8 +1497,10 @@ static void rtp_config_read(LinphoneCore *lc) { lc->rtp_conf.audio_multicast_ttl=1;/*local network*/ if ((tmp=lp_config_get_string(lc->config,"rtp","video_multicast_addr",NULL))) linphone_core_set_video_multicast_addr(lc,tmp); - else + else { + if (lc->rtp_conf.video_multicast_addr) bctbx_free(lc->rtp_conf.video_multicast_addr); lc->rtp_conf.video_multicast_addr=ms_strdup("224.1.2.3"); + } if ((tmp_int=lp_config_get_int(lc->config,"rtp","video_multicast_ttl",-1))>-1) linphone_core_set_video_multicast_ttl(lc,tmp_int); else @@ -1597,10 +1626,9 @@ static SalStreamType payload_type_get_stream_type(const PayloadType *pt){ /*this function merges the payload types from the codec default list with the list read from configuration file. * If a new codec becomes supported in Liblinphone or if the list from configuration file is empty or incomplete, all the supported codecs are added - * automatically. This 'l' list is entirely destroyed and rewritten.*/ + * automatically. This 'l' list is entirely rewritten.*/ static bctbx_list_t *add_missing_supported_codecs(LinphoneCore *lc, const bctbx_list_t *default_list, bctbx_list_t *l){ const bctbx_list_t *elem; - bctbx_list_t *newlist; PayloadType *last_seen = NULL; for(elem=default_list; elem!=NULL; elem=elem->next){ @@ -1623,41 +1651,33 @@ static bctbx_list_t *add_missing_supported_codecs(LinphoneCore *lc, const bctbx_ last_seen = (PayloadType*)elem2->data; } } - newlist=bctbx_list_copy_with_data(l,(void *(*)(void*))payload_type_clone); - bctbx_list_free(l); - return newlist; + return l; } /* * This function adds missing codecs, if required by configuration. - * This 'l' list is entirely destroyed and a new list is returned. + * This 'l' list is entirely rewritten if required. */ -static bctbx_list_t *handle_missing_codecs(LinphoneCore *lc, const bctbx_list_t *default_list, bctbx_list_t *l, MSFormatType ft){ +static bctbx_list_t *handle_missing_codecs (LinphoneCore *lc, const bctbx_list_t *default_list, bctbx_list_t *l, MSFormatType ft) { const char *name = "unknown"; - int add_missing; - bctbx_list_t *ret; - switch(ft){ + switch (ft) { case MSAudio: name = "add_missing_audio_codecs"; - break; + break; case MSVideo: name = "add_missing_video_codecs"; - break; + break; case MSText: name = "add_missing_text_codecs"; - break; + break; case MSUnknownMedia: break; } - add_missing = lp_config_get_int(lc->config, "misc", name, 1); - if (add_missing){ - ret = add_missing_supported_codecs(lc, default_list, l); - }else{ - ret = bctbx_list_copy_with_data(l,(void *(*)(void*))payload_type_clone); - bctbx_list_free(l); - } - return ret; + + if (lp_config_get_int(lc->config, "misc", name, 1)) + return add_missing_supported_codecs(lc, default_list, l); + return l; } static bctbx_list_t *codec_append_if_new(bctbx_list_t *l, PayloadType *pt){ @@ -1854,37 +1874,46 @@ void linphone_core_set_expected_bandwidth(LinphoneCore *lc, int bw){ } void linphone_core_set_sip_transport_timeout(LinphoneCore *lc, int timeout_ms) { - lc->sal->set_transport_timeout(timeout_ms); + lc->sal->setTransportTimeout(timeout_ms); if (linphone_core_ready(lc)) lp_config_set_int(lc->config, "sip", "transport_timeout", timeout_ms); } int linphone_core_get_sip_transport_timeout(LinphoneCore *lc) { - return lc->sal->get_transport_timeout(); + return lc->sal->getTransportTimeout(); +} + +bool_t linphone_core_get_dns_set_by_app(LinphoneCore *lc) { + return lc->dns_set_by_app; +} + +void linphone_core_set_dns_servers_app(LinphoneCore *lc, const bctbx_list_t *servers){ + lc->dns_set_by_app = (servers != NULL); + linphone_core_set_dns_servers(lc, servers); } void linphone_core_set_dns_servers(LinphoneCore *lc, const bctbx_list_t *servers){ - lc->sal->set_dns_servers(servers); + lc->sal->setDnsServers(servers); } void linphone_core_enable_dns_srv(LinphoneCore *lc, bool_t enable) { - lc->sal->enable_dns_srv(enable); + lc->sal->enableDnsSrv(!!enable); if (linphone_core_ready(lc)) lp_config_set_int(lc->config, "net", "dns_srv_enabled", enable ? 1 : 0); } bool_t linphone_core_dns_srv_enabled(const LinphoneCore *lc) { - return lc->sal->dns_srv_enabled(); + return lc->sal->dnsSrvEnabled(); } void linphone_core_enable_dns_search(LinphoneCore *lc, bool_t enable) { - lc->sal->enable_dns_search(enable); + lc->sal->enableDnsSearch(!!enable); if (linphone_core_ready(lc)) lp_config_set_int(lc->config, "net", "dns_search_enabled", enable ? 1 : 0); } bool_t linphone_core_dns_search_enabled(const LinphoneCore *lc) { - return lc->sal->dns_search_enabled(); + return lc->sal->dnsSearchEnabled(); } int linphone_core_get_download_bandwidth(const LinphoneCore *lc){ @@ -1960,12 +1989,15 @@ void linphone_core_set_state(LinphoneCore *lc, LinphoneGlobalState gstate, const linphone_core_notify_global_state_changed(lc,gstate,message); } -static void misc_config_read(LinphoneCore *lc) { - LpConfig *config=lc->config; +static void misc_config_read (LinphoneCore *lc) { + LpConfig *config = lc->config; + + lc->max_call_logs = lp_config_get_int(config,"misc","history_max_size",LINPHONE_MAX_CALL_HISTORY_SIZE); + lc->max_calls = lp_config_get_int(config,"misc","max_calls",NB_MAX_CALLS); + + if (lc->user_certificates_path) bctbx_free(lc->user_certificates_path); + lc->user_certificates_path = bctbx_strdup(lp_config_get_string(config, "misc", "user_certificates_path", ".")); - lc->max_call_logs=lp_config_get_int(config,"misc","history_max_size",LINPHONE_MAX_CALL_HISTORY_SIZE); - lc->max_calls=lp_config_get_int(config,"misc","max_calls",NB_MAX_CALLS); - lc->user_certificates_path=ms_strdup(lp_config_get_string(config,"misc","user_certificates_path",".")); lc->send_call_stats_periodical_updates = !!lp_config_get_int(config, "misc", "send_call_stats_periodical_updates", 0); } @@ -2111,59 +2143,70 @@ static void linphone_core_internal_notify_received(LinphoneCore *lc, LinphoneEve } } else if (strcmp(notified_event, "conference") == 0) { const LinphoneAddress *resource = linphone_event_get_resource(lev); - const LinphoneAddress *from = linphone_event_get_from(lev); + char *resourceAddrStr = linphone_address_as_string_uri_only(resource); + if (strcmp(resourceAddrStr, linphone_proxy_config_get_conference_factory_uri(linphone_core_get_default_proxy_config(lc))) == 0) { + bctbx_free(resourceAddrStr); + L_GET_PRIVATE_FROM_C_OBJECT(lc)->remoteListEventHandler->notifyReceived(L_GET_CPP_PTR_FROM_C_OBJECT(body)); + return; + } + bctbx_free(resourceAddrStr); + const LinphoneAddress *from = linphone_event_get_from(lev); shared_ptr chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom(LinphonePrivate::ChatRoomId( IdentityAddress(*L_GET_CPP_PTR_FROM_C_OBJECT(resource)), IdentityAddress(*L_GET_CPP_PTR_FROM_C_OBJECT(from)) )); + if (!chatRoom) + return; - if (chatRoom) { - shared_ptr cgcr; - if (chatRoom->getCapabilities() & ChatRoom::Capabilities::Proxy) - cgcr = static_pointer_cast( - static_pointer_cast(chatRoom)->getProxiedChatRoom()); - else - cgcr = static_pointer_cast(chatRoom); + shared_ptr cgcr; + if (chatRoom->getCapabilities() & ChatRoom::Capabilities::Proxy) + cgcr = static_pointer_cast( + static_pointer_cast(chatRoom)->getProxiedChatRoom()); + else + cgcr = static_pointer_cast(chatRoom); - if (linphone_content_is_multipart(body)) { - // TODO : migrate to c++ 'Content'. - int i = 0; - LinphoneContent *part = NULL; - while ((part = linphone_content_get_part(body, i))) { - i++; - L_GET_PRIVATE(cgcr)->notifyReceived(linphone_content_get_string_buffer(part)); - linphone_content_unref(part); - } - } else - L_GET_PRIVATE(cgcr)->notifyReceived(linphone_content_get_string_buffer(body)); - } + if (linphone_content_is_multipart(body)) { + // TODO : migrate to c++ 'Content'. + int i = 0; + LinphoneContent *part = nullptr; + while ((part = linphone_content_get_part(body, i))) { + i++; + L_GET_PRIVATE(cgcr)->notifyReceived(linphone_content_get_string_buffer(part)); + linphone_content_unref(part); + } + } else + L_GET_PRIVATE(cgcr)->notifyReceived(linphone_content_get_string_buffer(body)); } } -static void _linphone_core_conference_subscription_state_changed(LinphoneCore *lc, LinphoneEvent *lev, LinphoneSubscriptionState state) { - if ( - linphone_event_get_subscription_dir(lev) == LinphoneSubscriptionIncoming && - state == LinphoneSubscriptionIncomingReceived - ) { - const LinphoneAddress *resource = linphone_event_get_resource(lev); - shared_ptr chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom(LinphonePrivate::ChatRoomId( - IdentityAddress(*L_GET_CPP_PTR_FROM_C_OBJECT(resource)), - IdentityAddress(*L_GET_CPP_PTR_FROM_C_OBJECT(resource)) - )); - if (chatRoom) { - linphone_event_accept_subscription(lev); - L_GET_PRIVATE(static_pointer_cast(chatRoom))->subscribeReceived(lev); - } else - linphone_event_deny_subscription(lev, LinphoneReasonDeclined); +static void _linphone_core_conference_subscribe_received(LinphoneCore *lc, LinphoneEvent *lev, const LinphoneContent *body) { + if (body && linphone_event_get_custom_header(lev, "Content-Disposition") && strcasecmp(linphone_event_get_custom_header(lev, "Content-Disposition"), "recipient-list") == 0) { + // List subscription + L_GET_PRIVATE_FROM_C_OBJECT(lc)->localListEventHandler->subscribeReceived(lev, body); + return; + } + + const LinphoneAddress *resource = linphone_event_get_resource(lev); + shared_ptr chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom(LinphonePrivate::ChatRoomId( + IdentityAddress(*L_GET_CPP_PTR_FROM_C_OBJECT(resource)), + IdentityAddress(*L_GET_CPP_PTR_FROM_C_OBJECT(resource)) + )); + if (chatRoom) + L_GET_PRIVATE(static_pointer_cast(chatRoom))->subscribeReceived(lev); + else + linphone_event_deny_subscription(lev, LinphoneReasonDeclined); +} + +static void linphone_core_internal_subscribe_received(LinphoneCore *lc, LinphoneEvent *lev, const char *subscribe_event, const LinphoneContent *body) { + if (strcmp(linphone_event_get_name(lev), "conference") == 0) { + _linphone_core_conference_subscribe_received(lc, lev, body); } } static void linphone_core_internal_subscription_state_changed(LinphoneCore *lc, LinphoneEvent *lev, LinphoneSubscriptionState state) { if (strcasecmp(linphone_event_get_name(lev), "Presence") == 0) { linphone_friend_list_subscription_state_changed(lc, lev, state); - } else if (strcmp(linphone_event_get_name(lev), "conference") == 0) { - _linphone_core_conference_subscription_state_changed(lc, lev, state); } } @@ -2216,25 +2259,28 @@ static void linphone_core_init(LinphoneCore * lc, LinphoneCoreCbs *cbs, LpConfig // We need the Sal on the Android platform helper init msplugins_dir = linphone_factory_get_msplugins_dir(lfactory); - image_resources_dir = linphone_factory_get_image_resources_dir(lfactory); - lc->factory = ms_factory_new_with_voip_and_directories(msplugins_dir, image_resources_dir); - lc->sal=new Sal(lc->factory); - lc->sal->set_http_proxy_host(linphone_core_get_http_proxy_host(lc)); - lc->sal->set_http_proxy_port(linphone_core_get_http_proxy_port(lc)); + image_resources_dir = linphone_factory_get_image_resources_dir(lfactory); - lc->sal->set_user_pointer(lc); - lc->sal->set_callbacks(&linphone_sal_callbacks); + lc->sal=new Sal(NULL); + lc->sal->setRefresherRetryAfter(lp_config_get_int(lc->config, "sip", "refresher_retry_after", 60000)); + lc->sal->setHttpProxyHost(L_C_TO_STRING(linphone_core_get_http_proxy_host(lc))); + lc->sal->setHttpProxyPort(linphone_core_get_http_proxy_port(lc)); + + lc->sal->setUserPointer(lc); + lc->sal->setCallbacks(&linphone_sal_callbacks); #ifdef __ANDROID__ if (system_context) lc->platform_helper = LinphonePrivate::createAndroidPlatformHelpers(lc, system_context); +#elif TARGET_OS_IPHONE + lc->platform_helper = LinphonePrivate::createIosPlatformHelpers(lc, system_context); #endif if (lc->platform_helper == NULL) lc->platform_helper = new LinphonePrivate::StubbedPlatformHelpers(lc); // MS Factory MUST be created after Android has been set, otherwise no camera will be detected ! lc->factory = ms_factory_new_with_voip_and_directories(msplugins_dir, image_resources_dir); - lc->sal->set_factory(lc->factory); + lc->sal->setFactory(lc->factory); belr::GrammarLoader::get().addPath(getPlatformHelpers(lc)->getDataPath()); @@ -2243,6 +2289,7 @@ static void linphone_core_init(LinphoneCore * lc, LinphoneCoreCbs *cbs, LpConfig _linphone_core_init_account_creator_service(lc); linphone_core_cbs_set_notify_received(internal_cbs, linphone_core_internal_notify_received); + linphone_core_cbs_set_subscribe_received(internal_cbs, linphone_core_internal_subscribe_received); linphone_core_cbs_set_subscription_state_changed(internal_cbs, linphone_core_internal_subscription_state_changed); linphone_core_cbs_set_publish_state_changed(internal_cbs, linphone_core_internal_publish_state_changed); _linphone_core_add_callbacks(lc, internal_cbs, TRUE); @@ -2273,11 +2320,11 @@ static void linphone_core_init(LinphoneCore * lc, LinphoneCoreCbs *cbs, LpConfig /* Create the http provider in dual stack mode (ipv4 and ipv6. * If this creates problem, we may need to implement parallel ipv6/ ipv4 http requests in belle-sip. */ - lc->http_provider = belle_sip_stack_create_http_provider(reinterpret_cast(lc->sal->get_stack_impl()), "::0"); + lc->http_provider = belle_sip_stack_create_http_provider(reinterpret_cast(lc->sal->getStackImpl()), "::0"); lc->http_crypto_config = belle_tls_crypto_config_new(); belle_http_provider_set_tls_crypto_config(lc->http_provider,lc->http_crypto_config); - certificates_config_read(lc); + //certificates_config_read(lc); // This will be done below in _linphone_core_read_config() lc->ringtoneplayer = linphone_ringtoneplayer_new(); @@ -2294,6 +2341,8 @@ static void linphone_core_init(LinphoneCore * lc, LinphoneCoreCbs *cbs, LpConfig linphone_core_initialize_supported_content_types(lc); lc->bw_controller = ms_bandwidth_controller_new(); + getPlatformHelpers(lc)->setDnsServers(); + LinphoneFriendList *list = linphone_core_create_friend_list(lc); linphone_friend_list_set_display_name(list, "_default"); linphone_core_add_friend_list(lc, list); @@ -2314,13 +2363,13 @@ void linphone_core_start (LinphoneCore *lc) { const char* uuid=lp_config_get_string(lc->config,"misc","uuid",NULL); if (!uuid){ char tmp[64]; - lc->sal->create_uuid(tmp,sizeof(tmp)); + lc->sal->createUuid(tmp,sizeof(tmp)); lp_config_set_string(lc->config,"misc","uuid",tmp); }else if (strcmp(uuid,"0")!=0) /*to allow to disable sip.instance*/ - lc->sal->set_uuid(uuid); + lc->sal->setUuid(uuid); - if (lc->sal->get_root_ca()) { - belle_tls_crypto_config_set_root_ca(lc->http_crypto_config, lc->sal->get_root_ca()); + if (!lc->sal->getRootCa().empty()) { + belle_tls_crypto_config_set_root_ca(lc->http_crypto_config, lc->sal->getRootCa().c_str()); belle_http_provider_set_tls_crypto_config(lc->http_provider, lc->http_crypto_config); } @@ -2335,17 +2384,6 @@ void linphone_core_start (LinphoneCore *lc) { } } -#ifdef __ANDROID__ -static void _linphone_core_set_platform_helpers(LinphoneCore *lc, LinphonePrivate::PlatformHelpers *ph){ - if (lc->platform_helper) delete getPlatformHelpers(lc); - lc->platform_helper = ph; -} - -static void _linphone_core_set_system_context(LinphoneCore *lc, void *system_context){ - _linphone_core_set_platform_helpers(lc, LinphonePrivate::createAndroidPlatformHelpers(lc, system_context)); -} -#endif - LinphoneCore *_linphone_core_new_with_config(LinphoneCoreCbs *cbs, struct _LpConfig *config, void *userdata, void *system_context, bool_t automatically_start) { LinphoneCore *core = L_INIT(Core); Core::create(core); @@ -2531,8 +2569,8 @@ void linphone_core_enable_lime(LinphoneCore *lc, LinphoneLimeState val){ LinphoneImEncryptionEngine *imee = linphone_im_encryption_engine_new(); LinphoneImEncryptionEngineCbs *cbs = linphone_im_encryption_engine_get_callbacks(imee); - if(lime_is_available()){ - if (linphone_core_ready(lc)){ + if (lime_is_available()) { + if (linphone_core_ready(lc)) { lp_config_set_int(lc->config,"sip","lime",val); } @@ -2861,12 +2899,12 @@ void linphone_core_set_user_agent(LinphoneCore *lc, const char *name, const char char ua_string[256]; snprintf(ua_string, sizeof(ua_string) - 1, "%s/%s", name?name:"", ver?ver:""); if (lc->sal) { - lc->sal->set_user_agent(ua_string); - lc->sal->append_stack_string_to_user_agent(); + lc->sal->setUserAgent(ua_string); + lc->sal->appendStackStringToUserAgent(); } } const char *linphone_core_get_user_agent(LinphoneCore *lc){ - return lc->sal->get_user_agent(); + return lc->sal->getUserAgent().c_str(); } const char *linphone_core_get_user_agent_name(void){ @@ -2909,32 +2947,32 @@ int _linphone_core_apply_transports(LinphoneCore *lc){ else anyaddr="0.0.0.0"; - sal->unlisten_ports(); + sal->unlistenPorts(); listening_address = lp_config_get_string(lc->config,"sip","bind_address",anyaddr); if (linphone_core_get_http_proxy_host(lc)) { - sal->set_http_proxy_host(linphone_core_get_http_proxy_host(lc)); - sal->set_http_proxy_port(linphone_core_get_http_proxy_port(lc)); + sal->setHttpProxyHost(linphone_core_get_http_proxy_host(lc)); + sal->setHttpProxyPort(linphone_core_get_http_proxy_port(lc)); } if (lc->tunnel && linphone_tunnel_sip_enabled(lc->tunnel) && linphone_tunnel_get_activated(lc->tunnel)){ - sal->set_listen_port(anyaddr,tr->udp_port,SalTransportUDP,TRUE); + sal->setListenPort(anyaddr,tr->udp_port,SalTransportUDP,TRUE); }else{ if (tr->udp_port!=0){ - sal->set_listen_port(listening_address,tr->udp_port,SalTransportUDP,FALSE); + sal->setListenPort(listening_address,tr->udp_port,SalTransportUDP,FALSE); } if (tr->tcp_port!=0){ - sal->set_listen_port (listening_address,tr->tcp_port,SalTransportTCP,FALSE); + sal->setListenPort (listening_address,tr->tcp_port,SalTransportTCP,FALSE); } if (linphone_core_sip_transport_supported(lc,LinphoneTransportTls)){ if (tr->tls_port!=0) - sal->set_listen_port (listening_address,tr->tls_port,SalTransportTLS,FALSE); + sal->setListenPort (listening_address,tr->tls_port,SalTransportTLS,FALSE); } } return 0; } bool_t linphone_core_sip_transport_supported(const LinphoneCore *lc, LinphoneTransportType tp){ - return !!lc->sal->transport_available((SalTransport)tp); + return !!lc->sal->isTransportAvailable((SalTransport)tp); } BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneTransports); @@ -3074,17 +3112,17 @@ LinphoneTransports *linphone_core_get_transports(LinphoneCore *lc){ } void linphone_core_get_sip_transports_used(LinphoneCore *lc, LinphoneSipTransports *tr){ - tr->udp_port=lc->sal->get_listening_port(SalTransportUDP); - tr->tcp_port=lc->sal->get_listening_port(SalTransportTCP); - tr->tls_port=lc->sal->get_listening_port(SalTransportTLS); + tr->udp_port=lc->sal->getListeningPort(SalTransportUDP); + tr->tcp_port=lc->sal->getListeningPort(SalTransportTCP); + tr->tls_port=lc->sal->getListeningPort(SalTransportTLS); } LinphoneTransports *linphone_core_get_transports_used(LinphoneCore *lc){ LinphoneTransports *transports = linphone_transports_new(); - transports->udp_port = lc->sal->get_listening_port(SalTransportUDP); - transports->tcp_port = lc->sal->get_listening_port(SalTransportTCP); - transports->tls_port = lc->sal->get_listening_port(SalTransportTLS); - transports->dtls_port = lc->sal->get_listening_port(SalTransportDTLS); + transports->udp_port = lc->sal->getListeningPort(SalTransportUDP); + transports->tcp_port = lc->sal->getListeningPort(SalTransportTCP); + transports->tls_port = lc->sal->getListeningPort(SalTransportTLS); + transports->dtls_port = lc->sal->getListeningPort(SalTransportDTLS); return transports; } @@ -3116,7 +3154,7 @@ void linphone_core_enable_ipv6(LinphoneCore *lc, bool_t val){ bool_t linphone_core_content_encoding_supported(const LinphoneCore *lc, const char *content_encoding) { const char *handle_content_encoding = lp_config_get_string(lc->config, "sip", "handle_content_encoding", "deflate"); - return (strcmp(handle_content_encoding, content_encoding) == 0) && lc->sal->content_encoding_available(content_encoding); + return (strcmp(handle_content_encoding, content_encoding) == 0) && lc->sal->isContentEncodingAvailable(content_encoding); } static void monitor_network_state(LinphoneCore *lc, time_t curtime){ @@ -3237,7 +3275,7 @@ void linphone_core_iterate(LinphoneCore *lc){ uint64_t curtime_ms = ms_get_cur_time_ms(); /*monotonic time*/ time_t current_real_time = ms_time(NULL); int64_t diff_time; - bool_t one_second_elapsed=FALSE; + bool one_second_elapsed = false; if (lc->network_reachable_to_be_notified) { lc->network_reachable_to_be_notified=FALSE; @@ -3250,7 +3288,7 @@ void linphone_core_iterate(LinphoneCore *lc){ lc->prevtime_ms = curtime_ms; } if ((diff_time=(int64_t)(curtime_ms-lc->prevtime_ms)) >= 1000){ - one_second_elapsed=TRUE; + one_second_elapsed = true; if (diff_time>3000){ /*since monotonic time doesn't increment while machine is sleeping, we don't want to catchup too much*/ lc->prevtime_ms = curtime_ms; @@ -3527,7 +3565,7 @@ static void linphone_transfer_routes_to_op(bctbx_list_t *routes, SalOp *op){ bctbx_list_t *it; for(it=routes;it!=NULL;it=it->next){ SalAddress *addr=(SalAddress*)it->data; - op->add_route_address(addr); + op->addRouteAddress(addr); sal_address_destroy(addr); } bctbx_list_free(routes); @@ -3540,7 +3578,7 @@ void linphone_configure_op_with_proxy(LinphoneCore *lc, SalOp *op, const Linphon if (proxy){ identity=linphone_proxy_config_get_identity(proxy); if (linphone_proxy_config_get_privacy(proxy)!=LinphonePrivacyDefault) { - op->set_privacy(linphone_proxy_config_get_privacy(proxy)); + op->setPrivacy(linphone_proxy_config_get_privacy(proxy)); } }else identity=linphone_core_get_primary_contact(lc); /*sending out of calls*/ @@ -3549,21 +3587,21 @@ void linphone_configure_op_with_proxy(LinphoneCore *lc, SalOp *op, const Linphon linphone_transfer_routes_to_op(routes,op); } - op->set_to_address(L_GET_PRIVATE_FROM_C_OBJECT(dest)->getInternalAddress()); - op->set_from(identity); - op->set_sent_custom_header(headers); - op->set_realm(linphone_proxy_config_get_realm(proxy)); + op->setToAddress(L_GET_PRIVATE_FROM_C_OBJECT(dest)->getInternalAddress()); + op->setFrom(identity); + op->setSentCustomHeaders(headers); + op->setRealm(L_C_TO_STRING(linphone_proxy_config_get_realm(proxy))); if (with_contact && proxy && proxy->op){ const LinphoneAddress *contact = linphone_proxy_config_get_contact(proxy); SalAddress *salAddress = nullptr; if (contact) salAddress = sal_address_clone(const_cast(L_GET_PRIVATE_FROM_C_OBJECT(contact)->getInternalAddress())); - op->set_contact_address(salAddress); + op->setContactAddress(salAddress); if (salAddress) sal_address_unref(salAddress); } - op->enable_cnx_ip_to_0000_if_sendonly(!!lp_config_get_default_int(lc->config,"sip","cnx_ip_to_0000_if_sendonly_enabled",0)); /*also set in linphone_call_new_incoming*/ + op->enableCnxIpTo0000IfSendOnly(!!lp_config_get_default_int(lc->config,"sip","cnx_ip_to_0000_if_sendonly_enabled",0)); /*also set in linphone_call_new_incoming*/ } void linphone_configure_op(LinphoneCore *lc, SalOp *op, const LinphoneAddress *dest, SalCustomHeader *headers, bool_t with_contact) { linphone_configure_op_with_proxy(lc, op, dest, headers,with_contact,linphone_core_lookup_known_proxy(lc,dest)); @@ -3700,10 +3738,6 @@ static LinphoneCall * get_unique_call(LinphoneCore *lc) { return call; } -LinphoneStatus linphone_core_accept_call(LinphoneCore *lc, LinphoneCall *call) { - return linphone_call_accept_with_params(call, NULL); -} - LinphoneStatus linphone_core_accept_call_with_params(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params) { if (call == NULL) { call = get_unique_call(lc); @@ -3715,6 +3749,10 @@ LinphoneStatus linphone_core_accept_call_with_params(LinphoneCore *lc, LinphoneC return linphone_call_accept_with_params(call, params); } +LinphoneStatus linphone_core_accept_call(LinphoneCore *lc, LinphoneCall *call) { + return linphone_core_accept_call_with_params(lc, call, NULL); +} + LinphoneStatus linphone_core_redirect_call(LinphoneCore *lc, LinphoneCall *call, const char *redirect_uri) { return linphone_call_redirect(call, redirect_uri); } @@ -4308,7 +4346,7 @@ const char *linphone_core_get_ring(const LinphoneCore *lc){ } void linphone_core_set_root_ca(LinphoneCore *lc, const char *path) { - lc->sal->set_root_ca(path); + lc->sal->setRootCa(L_C_TO_STRING(path)); if (lc->http_crypto_config) { belle_tls_crypto_config_set_root_ca(lc->http_crypto_config, path); } @@ -4316,8 +4354,8 @@ void linphone_core_set_root_ca(LinphoneCore *lc, const char *path) { } void linphone_core_set_root_ca_data(LinphoneCore *lc, const char *data) { - lc->sal->set_root_ca(NULL); - lc->sal->set_root_ca_data(data); + lc->sal->setRootCa(""); + lc->sal->setRootCaData(L_C_TO_STRING(data)); if (lc->http_crypto_config) { belle_tls_crypto_config_set_root_ca_data(lc->http_crypto_config, data); } @@ -4328,7 +4366,7 @@ const char *linphone_core_get_root_ca(LinphoneCore *lc){ } void linphone_core_verify_server_certificates(LinphoneCore *lc, bool_t yesno){ - lc->sal->verify_server_certificates(yesno); + lc->sal->verifyServerCertificates(!!yesno); if (lc->http_crypto_config){ belle_tls_crypto_config_set_verify_exceptions(lc->http_crypto_config, yesno ? 0 : BELLE_TLS_VERIFY_ANY_REASON); } @@ -4336,7 +4374,7 @@ void linphone_core_verify_server_certificates(LinphoneCore *lc, bool_t yesno){ } void linphone_core_verify_server_cn(LinphoneCore *lc, bool_t yesno){ - lc->sal->verify_server_cn(yesno); + lc->sal->verifyServerCn(!!yesno); if (lc->http_crypto_config){ belle_tls_crypto_config_set_verify_exceptions(lc->http_crypto_config, yesno ? 0 : BELLE_TLS_VERIFY_CN_MISMATCH); } @@ -4344,7 +4382,7 @@ void linphone_core_verify_server_cn(LinphoneCore *lc, bool_t yesno){ } void linphone_core_set_ssl_config(LinphoneCore *lc, void *ssl_config) { - lc->sal->set_ssl_config(ssl_config); + lc->sal->setSslConfig(ssl_config); if (lc->http_crypto_config) { belle_tls_crypto_config_set_ssl_config(lc->http_crypto_config, ssl_config); } @@ -4641,9 +4679,9 @@ void linphone_core_set_nat_policy(LinphoneCore *lc, LinphoneNatPolicy *policy) { linphone_nat_policy_save_to_config(lc->nat_policy); } - lc->sal->enable_nat_helper(!!lp_config_get_int(lc->config, "net", "enable_nat_helper", 1)); - lc->sal->enable_auto_contacts(TRUE); - lc->sal->use_rport(!!lp_config_get_int(lc->config, "sip", "use_rport", 1)); + lc->sal->enableNatHelper(!!lp_config_get_int(lc->config, "net", "enable_nat_helper", 1)); + lc->sal->enableAutoContacts(TRUE); + lc->sal->useRport(!!lp_config_get_int(lc->config, "sip", "use_rport", 1)); if (lc->sip_conf.contact) update_primary_contact(lc); } @@ -5619,7 +5657,7 @@ typedef enum{ LinphoneLocalPlayer }LinphoneAudioResourceType; -static MSFilter *get_audio_resource(LinphoneCore *lc, LinphoneAudioResourceType rtype){ +static MSFilter *get_audio_resource(LinphoneCore *lc, LinphoneAudioResourceType rtype, MSSndCard *card) { LinphoneCall *call=linphone_core_get_current_call(lc); AudioStream *stream=NULL; RingStream *ringstream; @@ -5633,9 +5671,18 @@ static MSFilter *get_audio_resource(LinphoneCore *lc, LinphoneAudioResourceType if (rtype==LinphoneLocalPlayer) return stream->local_player; return NULL; } - if (lc->ringstream==NULL){ + if (card && lc->ringstream && card != lc->ringstream->card){ + ring_stop(lc->ringstream); + lc->ringstream = NULL; + } + if (lc->ringstream == NULL) { float amp=lp_config_get_float(lc->config,"sound","dtmf_player_amp",0.1f); - MSSndCard *ringcard=lc->sound_conf.lsd_card ?lc->sound_conf.lsd_card : lc->sound_conf.ring_sndcard; + MSSndCard *ringcard=lc->sound_conf.lsd_card + ? lc->sound_conf.lsd_card + : card + ? card + : lc->sound_conf.ring_sndcard; + if (ringcard == NULL) return NULL; @@ -5652,12 +5699,15 @@ static MSFilter *get_audio_resource(LinphoneCore *lc, LinphoneAudioResourceType return NULL; } -static MSFilter *get_dtmf_gen(LinphoneCore *lc){ - return get_audio_resource(lc,LinphoneToneGenerator); +static MSFilter *get_dtmf_gen(LinphoneCore *lc, MSSndCard *card) { + return get_audio_resource(lc,LinphoneToneGenerator, card); } void linphone_core_play_dtmf(LinphoneCore *lc, char dtmf, int duration_ms){ - MSFilter *f=get_dtmf_gen(lc); + MSSndCard *card = linphone_core_in_call(lc) + ? lc->sound_conf.play_sndcard + : lc->sound_conf.ring_sndcard; + MSFilter *f=get_dtmf_gen(lc, card); if (f==NULL){ ms_error("No dtmf generator at this time !"); return; @@ -5668,8 +5718,8 @@ void linphone_core_play_dtmf(LinphoneCore *lc, char dtmf, int duration_ms){ else ms_filter_call_method(f, MS_DTMF_GEN_START, &dtmf); } -LinphoneStatus linphone_core_play_local(LinphoneCore *lc, const char *audiofile){ - MSFilter *f=get_audio_resource(lc,LinphoneLocalPlayer); +LinphoneStatus _linphone_core_play_local(LinphoneCore *lc, const char *audiofile, MSSndCard *card) { + MSFilter *f=get_audio_resource(lc,LinphoneLocalPlayer, card); int loopms=-1; if (!f) return -1; ms_filter_call_method(f,MS_PLAYER_SET_LOOP,&loopms); @@ -5680,11 +5730,15 @@ LinphoneStatus linphone_core_play_local(LinphoneCore *lc, const char *audiofile) return 0; } +LinphoneStatus linphone_core_play_local(LinphoneCore *lc, const char *audiofile) { + return _linphone_core_play_local(lc, audiofile, NULL); +} + void linphone_core_play_named_tone(LinphoneCore *lc, LinphoneToneID toneid){ if (linphone_core_tone_indications_enabled(lc)){ const char *audiofile=linphone_core_get_tone_file(lc,toneid); if (!audiofile){ - MSFilter *f=get_dtmf_gen(lc); + MSFilter *f=get_dtmf_gen(lc, lc->sound_conf.play_sndcard); MSDtmfGenCustomTone def; if (f==NULL){ ms_error("No dtmf generator at this time !"); @@ -5720,7 +5774,7 @@ void linphone_core_play_named_tone(LinphoneCore *lc, LinphoneToneID toneid){ if (def.duration>0) ms_filter_call_method(f, MS_DTMF_GEN_PLAY_CUSTOM,&def); }else{ - linphone_core_play_local(lc,audiofile); + _linphone_core_play_local(lc,audiofile, lc->sound_conf.play_sndcard); } } } @@ -5730,16 +5784,16 @@ void linphone_core_play_call_error_tone(LinphoneCore *lc, LinphoneReason reason) LinphoneToneDescription *tone=linphone_core_get_call_error_tone(lc,reason); if (tone){ if (tone->audiofile){ - linphone_core_play_local(lc,tone->audiofile); + _linphone_core_play_local(lc, tone->audiofile, lc->sound_conf.play_sndcard); }else if (tone->toneid != LinphoneToneUndefined){ - linphone_core_play_named_tone(lc,tone->toneid); + linphone_core_play_named_tone(lc, tone->toneid); } } } } void linphone_core_stop_dtmf(LinphoneCore *lc){ - MSFilter *f=get_dtmf_gen(lc); + MSFilter *f=get_dtmf_gen(lc, NULL); if (f!=NULL) ms_filter_call_method_noarg (f, MS_DTMF_GEN_STOP); } @@ -5880,8 +5934,8 @@ void sip_config_uninit(LinphoneCore *lc) linphone_vcard_context_destroy(lc->vcard_context); } - lc->sal->reset_transports(); - lc->sal->unlisten_ports(); /*to make sure no new messages are received*/ + lc->sal->resetTransports(); + lc->sal->unlistenPorts(); /*to make sure no new messages are received*/ if (lc->http_provider) { belle_sip_object_unref(lc->http_provider); lc->http_provider=NULL; @@ -6007,9 +6061,9 @@ void _linphone_core_codec_config_write(LinphoneCore *lc){ static void codecs_config_uninit(LinphoneCore *lc) { _linphone_core_codec_config_write(lc); - bctbx_list_free_with_data(lc->codecs_conf.audio_codecs, (void (*)(void*))payload_type_destroy); - bctbx_list_free_with_data(lc->codecs_conf.video_codecs, (void (*)(void*))payload_type_destroy); - bctbx_list_free_with_data(lc->codecs_conf.text_codecs, (void (*)(void*))payload_type_destroy); + bctbx_list_free(lc->codecs_conf.audio_codecs); + bctbx_list_free(lc->codecs_conf.video_codecs); + bctbx_list_free(lc->codecs_conf.text_codecs); } void friends_config_uninit(LinphoneCore* lc) @@ -6026,6 +6080,14 @@ void friends_config_uninit(LinphoneCore* lc) ms_message("Destroying friends done."); } +void linphone_core_enter_background(LinphoneCore *lc) { + L_GET_CPP_PTR_FROM_C_OBJECT(lc)->enterBackground(); +} + +void linphone_core_enter_foreground(LinphoneCore *lc) { + L_GET_CPP_PTR_FROM_C_OBJECT(lc)->enterForeground(); +} + LpConfig * linphone_core_get_config(const LinphoneCore *lc){ return lc->config; } @@ -6188,7 +6250,7 @@ static void set_sip_network_reachable(LinphoneCore* lc,bool_t is_sip_reachable, if (!lc->sip_network_reachable){ linphone_core_invalidate_friend_subscriptions(lc); - lc->sal->reset_transports(); + lc->sal->resetTransports(); } } @@ -6253,7 +6315,7 @@ bool_t linphone_core_is_network_reachable(LinphoneCore* lc) { } ortp_socket_t linphone_core_get_sip_socket(LinphoneCore *lc){ - return lc->sal->get_socket(); + return lc->sal->getSocket(); } void linphone_core_destroy(LinphoneCore *lc){ @@ -6264,6 +6326,7 @@ int linphone_core_get_calls_nb(const LinphoneCore *lc) { return (int)L_GET_CPP_PTR_FROM_C_OBJECT(lc)->getCallCount(); } + void linphone_core_soundcard_hint_check(LinphoneCore* lc) { L_GET_CPP_PTR_FROM_C_OBJECT(lc)->soundcardHintCheck(); } @@ -6372,19 +6435,19 @@ const char *linphone_error_to_string(LinphoneReason err){ void linphone_core_enable_keep_alive(LinphoneCore* lc,bool_t enable) { if (enable > 0) { - lc->sal->use_tcp_tls_keepalive(lc->sip_conf.tcp_tls_keepalive); - lc->sal->set_keepalive_period(lc->sip_conf.keepalive_period); + lc->sal->useTcpTlsKeepAlive(!!lc->sip_conf.tcp_tls_keepalive); + lc->sal->setKeepAlivePeriod(lc->sip_conf.keepalive_period); } else { - lc->sal->set_keepalive_period(0); + lc->sal->setKeepAlivePeriod(0); } } bool_t linphone_core_keep_alive_enabled(LinphoneCore* lc) { - return lc->sal->get_keepalive_period() > 0; + return lc->sal->getKeepAlivePeriod() > 0; } void linphone_core_start_dtmf_stream(LinphoneCore* lc) { - get_dtmf_gen(lc); /*make sure ring stream is started*/ + get_dtmf_gen(lc, lc->sound_conf.ring_sndcard); /*make sure ring stream is started*/ lc->ringstream_autorelease=FALSE; /*disable autorelease mode*/ } @@ -6522,13 +6585,24 @@ void linphone_core_set_zrtp_secrets_file(LinphoneCore *lc, const char* file){ /* rename the newly created sqlite3 file in to the given file name */ rename(file, bkpFile); + +#ifdef _WIN32 + /* We first have to close the file before renaming it */ + sqlite3_close(lc->zrtp_cache_db); +#endif + if (rename(tmpFile, file)==0) { /* set the flag if we were able to set the sqlite file in the correct place (even if migration failed) */ lp_config_set_int(lc->config, "sip", "zrtp_cache_migration_done", TRUE); } +#ifdef _WIN32 + /* Then reopen it */ + _linphone_sqlite3_open(file, &lc->zrtp_cache_db); +#endif + /* clean up */ bctbx_free(bkpFile); - xmlFree(cacheXml); + xmlFreeDoc(cacheXml); } bctbx_free(tmpFile); } else { @@ -6601,12 +6675,11 @@ end: #endif /* SQLITE_STORAGE_ENABLED */ } -void linphone_core_set_user_certificates_path(LinphoneCore *lc, const char* path){ - char* new_value; - new_value = path?ms_strdup(path):NULL; - if (lc->user_certificates_path) ms_free(lc->user_certificates_path); - lp_config_set_string(lc->config,"misc","user_certificates_path",lc->user_certificates_path=new_value); - return ; +void linphone_core_set_user_certificates_path (LinphoneCore *lc, const char *path) { + char *new_value = path ? bctbx_strdup(path) : NULL; + if (lc->user_certificates_path) bctbx_free(lc->user_certificates_path); + lc->user_certificates_path = new_value; + lp_config_set_string(lc->config, "misc", "user_certificates_path", lc->user_certificates_path); } const char *linphone_core_get_user_certificates_path(LinphoneCore *lc){ @@ -6732,7 +6805,7 @@ const char* linphone_core_get_device_identifier(const LinphoneCore *lc) { } void linphone_core_set_sip_dscp(LinphoneCore *lc, int dscp){ - lc->sal->set_dscp(dscp); + lc->sal->setDscp(dscp); if (linphone_core_ready(lc)){ lp_config_set_int_hex(lc->config,"sip","dscp",dscp); _linphone_core_apply_transports(lc); @@ -6796,13 +6869,13 @@ const char * linphone_core_get_file_transfer_server(LinphoneCore *core) { } void linphone_core_add_supported_tag(LinphoneCore *lc, const char *tag){ - lc->sal->add_supported_tag(tag); - lp_config_set_string(lc->config,"sip","supported",lc->sal->get_supported_tags()); + lc->sal->addSupportedTag(tag); + lp_config_set_string(lc->config,"sip","supported",lc->sal->getSupportedTags().c_str()); } void linphone_core_remove_supported_tag(LinphoneCore *lc, const char *tag){ - lc->sal->remove_supported_tag(tag); - lp_config_set_string(lc->config,"sip","supported",lc->sal->get_supported_tags()); + lc->sal->removeSupportedTag(tag); + lp_config_set_string(lc->config,"sip","supported",lc->sal->getSupportedTags().c_str()); } void linphone_core_set_avpf_mode(LinphoneCore *lc, LinphoneAVPFMode mode){ @@ -6930,15 +7003,15 @@ void linphone_core_enable_realtime_text(LinphoneCore *lc, bool_t value) { void linphone_core_set_http_proxy_host(LinphoneCore *lc, const char *host) { lp_config_set_string(lc->config,"sip","http_proxy_host",host); if (lc->sal) { - lc->sal->set_http_proxy_host(host); - lc->sal->set_http_proxy_port(linphone_core_get_http_proxy_port(lc)); /*to make sure default value is set*/ + lc->sal->setHttpProxyHost(host); + lc->sal->setHttpProxyPort(linphone_core_get_http_proxy_port(lc)); /*to make sure default value is set*/ } } void linphone_core_set_http_proxy_port(LinphoneCore *lc, int port) { lp_config_set_int(lc->config,"sip","http_proxy_port",port); if (lc->sal) - lc->sal->set_http_proxy_port(port); + lc->sal->setHttpProxyPort(port); } const char *linphone_core_get_http_proxy_host(const LinphoneCore *lc) { @@ -7184,19 +7257,23 @@ LinphoneImEncryptionEngine *linphone_core_get_im_encryption_engine(const Linphon } void linphone_core_initialize_supported_content_types(LinphoneCore *lc) { - lc->sal->add_content_type_support("text/plain"); - lc->sal->add_content_type_support("message/external-body"); - lc->sal->add_content_type_support("application/vnd.gsma.rcs-ft-http+xml"); - lc->sal->add_content_type_support("application/im-iscomposing+xml"); - lc->sal->add_content_type_support("message/imdn+xml"); + lc->sal->addContentTypeSupport("text/plain"); + lc->sal->addContentTypeSupport("message/external-body"); + lc->sal->addContentTypeSupport("application/vnd.gsma.rcs-ft-http+xml"); + lc->sal->addContentTypeSupport("application/im-iscomposing+xml"); + lc->sal->addContentTypeSupport("message/imdn+xml"); } bool_t linphone_core_is_content_type_supported(const LinphoneCore *lc, const char *content_type) { - return lc->sal->is_content_type_supported(content_type); + return lc->sal->isContentTypeSupported(content_type); } void linphone_core_add_content_type_support(LinphoneCore *lc, const char *content_type) { - lc->sal->add_content_type_support(content_type); + lc->sal->addContentTypeSupport(content_type); +} + +void linphone_core_remove_content_type_support(LinphoneCore *lc, const char *content_type) { + lc->sal->removeContentTypeSupport(content_type); } #ifdef ENABLE_UPDATE_CHECK @@ -7354,5 +7431,5 @@ const char *linphone_core_get_linphone_specs (const LinphoneCore *core) { void linphone_core_set_linphone_specs (LinphoneCore *core, const char *specs) { lp_config_set_string(linphone_core_get_config(core), "sip", "linphone_specs", specs); - core->sal->set_contact_linphone_specs(specs); + core->sal->setContactLinphoneSpecs(L_C_TO_STRING(specs)); } diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index a6b01bb58..9162e5c4f 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -4689,10 +4689,10 @@ extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_setFileTransferFi ReleaseStringUTFChars(env, jpath, path); } -extern "C" jint Java_org_linphone_core_LinphoneChatMessageImpl_downloadFile(JNIEnv* env +extern "C" jboolean Java_org_linphone_core_LinphoneChatMessageImpl_downloadFile(JNIEnv* env ,jobject thiz ,jlong ptr) { - return (jint) linphone_chat_message_download_file((LinphoneChatMessage*)ptr); + return linphone_chat_message_download_file((LinphoneChatMessage*)ptr); } extern "C" jboolean Java_org_linphone_core_LinphoneChatMessageImpl_isSecured(JNIEnv* env @@ -4768,6 +4768,7 @@ static void file_transfer_progress_indication(LinphoneChatMessage *msg, const Li if (jmessage) { env->DeleteLocalRef(jmessage); } + env->DeleteLocalRef(listener); } static void file_transfer_recv(LinphoneChatMessage *msg, const LinphoneContent* content, const LinphoneBuffer *buffer) { @@ -4797,6 +4798,7 @@ static void file_transfer_recv(LinphoneChatMessage *msg, const LinphoneContent* if (jmessage) { env->DeleteLocalRef(jmessage); } + env->DeleteLocalRef(listener); } static LinphoneBuffer* file_transfer_send(LinphoneChatMessage *msg, const LinphoneContent* content, size_t offset, size_t size) { @@ -4827,6 +4829,7 @@ static LinphoneBuffer* file_transfer_send(LinphoneChatMessage *msg, const Linph buffer = create_c_linphone_buffer_from_java_linphone_buffer(env, jbuffer); env->DeleteLocalRef(jbuffer); + env->DeleteLocalRef(listener); return buffer; } @@ -4909,7 +4912,7 @@ extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_sendChatMessage(JNIE ,jlong chatroom_ptr ,jobject message ,jlong messagePtr) { - + linphone_chat_room_send_chat_message_2((LinphoneChatRoom*)chatroom_ptr, (LinphoneChatMessage*)messagePtr); } @@ -7693,7 +7696,7 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setDnsServers(JNIEnv *e } } } - linphone_core_set_dns_servers((LinphoneCore*)lc, l); + linphone_core_set_dns_servers_app((LinphoneCore*)lc, l); bctbx_list_free_with_data(l, ms_free); } @@ -7755,19 +7758,45 @@ static void _next_video_frame_decoded_callback(LinphoneCall *call, void *user_da return; } - jobject listener = (jobject) user_data; + jobject listener = (jobject) env->NewLocalRef((jobject)user_data); + if (listener == NULL){ + ms_error("_next_video_frame_decoded_callback: listener has gone."); + return; + } jclass clazz = (jclass) env->GetObjectClass(listener); jmethodID method = env->GetMethodID(clazz, "onNextVideoFrameDecoded","(Lorg/linphone/core/LinphoneCall;)V"); env->DeleteLocalRef(clazz); jobject jcall = getCall(env, call); env->CallVoidMethod(listener, method, jcall); + env->DeleteLocalRef(listener); } -extern "C" void Java_org_linphone_core_LinphoneCallImpl_setListener(JNIEnv* env, jobject thiz, jlong ptr, jobject jlistener) { - jobject listener = env->NewGlobalRef(jlistener); +static void _on_tmmbr_received(LinphoneCall *call, int index, int bitrate){ + LinphoneCallCbs *cbs = linphone_call_get_current_callbacks(call); + JNIEnv *env = ms_get_jni_env(); + jobject listener = (jobject) env->NewLocalRef((jobject)linphone_call_cbs_get_user_data(cbs)); + if (listener == NULL){ + ms_error("_on_tmmbr_received: listener has gone."); + return; + } + jclass clazz = (jclass) env->GetObjectClass(listener); + jmethodID method = env->GetMethodID(clazz, "tmmbrReceived","(Lorg/linphone/core/LinphoneCall;II)V"); + env->DeleteLocalRef(clazz); + + jobject jcall = getCall(env, call); + env->CallVoidMethod(listener, method, jcall,(jint)index, (jint)bitrate); + env->DeleteLocalRef(listener); +} + +JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneCallImpl_setListener(JNIEnv* env, jobject thiz, jlong ptr, jobject jlistener) { LinphoneCall *call = (LinphoneCall *)ptr; - linphone_call_set_next_video_frame_decoded_callback(call, _next_video_frame_decoded_callback, listener); + LinphoneCallCbs *cbs = linphone_factory_create_call_cbs(linphone_factory_get()); + linphone_call_cbs_set_user_data(cbs, env->NewWeakGlobalRef(jlistener)); + linphone_call_cbs_set_tmmbr_received(cbs, _on_tmmbr_received); + linphone_call_add_callbacks(call, cbs); + + linphone_call_set_next_video_frame_decoded_callback(call, _next_video_frame_decoded_callback, env->NewWeakGlobalRef(jlistener)); } extern "C" void Java_org_linphone_core_LinphoneCallImpl_setVideoWindowId(JNIEnv* env diff --git a/coreapi/localplayer.c b/coreapi/localplayer.c index 88ecc06a8..8984eda1d 100644 --- a/coreapi/localplayer.c +++ b/coreapi/localplayer.c @@ -88,7 +88,6 @@ static int _local_player_get_current_position(LinphonePlayer *obj) { static void _local_player_destroy(LinphonePlayer *obj) { ms_media_player_free((MSMediaPlayer *)obj->impl); - _linphone_player_destroy(obj); } static void _local_player_close(LinphonePlayer *obj) { diff --git a/coreapi/logging.c b/coreapi/logging.c index 9731f872e..f707a37dc 100644 --- a/coreapi/logging.c +++ b/coreapi/logging.c @@ -72,7 +72,7 @@ LinphoneLogLevel _bctbx_log_level_to_linphone_log_level(BctbxLogLevel level) { if (response != tmap.cend()) { return response->first; } else { - ms_fatal("%s(): invalid argurement [%d]", __FUNCTION__, level); + ms_warning("%s(): invalid argurement [%d]", __FUNCTION__, level); return LinphoneLogLevelDebug; } } @@ -95,7 +95,7 @@ unsigned int _bctbx_log_mask_to_linphone_log_mask(unsigned int mask) { BctbxLogLevel _linphone_log_level_to_bctbx_log_level(LinphoneLogLevel level) { try { return _linphone_log_level_to_bctbx_log_level_map.at(level); - } catch (const std::out_of_range &e) { + } catch (const std::out_of_range &) { ms_fatal("%s(): invalid argument [%d]", __FUNCTION__, level); return BCTBX_LOG_LOGLEV_END; } @@ -127,6 +127,7 @@ static void _log_handler_on_message_written_cb(void *info,const char *domain, Bc static void _log_handler_destroy_cb(bctbx_log_handler_t *handler) { LinphoneLoggingService *service = (LinphoneLoggingService *)bctbx_log_handler_get_user_data(handler); + bctbx_free(service->log_handler); service->log_handler = NULL; } @@ -158,11 +159,12 @@ LinphoneLoggingService *linphone_logging_service_ref(LinphoneLoggingService *ser } void linphone_logging_service_unref(LinphoneLoggingService *service) { - belle_sip_object_ref(service); + belle_sip_object_unref(service); } static void _linphone_logging_service_uninit(LinphoneLoggingService *log_service) { - if (log_service->log_handler) bctbx_remove_log_handler(log_service->log_handler); + if (log_service->log_handler) + bctbx_remove_log_handler(log_service->log_handler); linphone_logging_service_cbs_unref(log_service->cbs); } @@ -179,10 +181,11 @@ LinphoneLoggingServiceCbs *linphone_logging_service_get_callbacks(const Linphone static const char *_linphone_logging_service_log_domains[] = { "bctbx", + "belle-sip", "ortp", "mediastreamer", "bzrtp", - "linphone", + BCTBX_LOG_DOMAIN, /* which is "liblinphone", set from CMakeList.txt*/ NULL }; @@ -201,7 +204,7 @@ void linphone_logging_service_set_log_level_mask(LinphoneLoggingService *log_ser } unsigned int linphone_logging_service_get_log_level_mask(const LinphoneLoggingService *log_service) { - return _bctbx_log_mask_to_linphone_log_mask(bctbx_get_log_level_mask(ORTP_LOG_DOMAIN)); + return _bctbx_log_mask_to_linphone_log_mask(bctbx_get_log_level_mask(BCTBX_LOG_DOMAIN)); } void linphone_logging_service_set_log_file(const LinphoneLoggingService *service, const char *dir, const char *filename, size_t max_size) { @@ -237,6 +240,11 @@ void linphone_logging_service_cbs_unref(LinphoneLoggingServiceCbs *cbs) { } void linphone_logging_service_cbs_set_log_message_written(LinphoneLoggingServiceCbs *cbs, LinphoneLoggingServiceCbsLogMessageWrittenCb cb) { + /* We need to set the legacy log handler to NULL here + because LinphoneCore have a default log handler that dump + all messages into the standard output. */ + /*this function is moved here to make sure default log handler is only removed when user defined logging cbs is set*/ + _linphone_core_set_log_handler(NULL); cbs->message_event_cb = cb; } diff --git a/coreapi/lsd.c b/coreapi/lsd.c index f6a3b5104..b09caf4d3 100644 --- a/coreapi/lsd.c +++ b/coreapi/lsd.c @@ -222,6 +222,10 @@ void lsd_player_set_gain(LsdPlayer *p, float gain){ ms_filter_call_method(p->lsd->mixer,MS_AUDIO_MIXER_SET_INPUT_GAIN,&gainctl); } +static void lsd_player_configure_notify_func (void *userdata, MSFilter *, unsigned int, void *) { + lsd_player_configure((LsdPlayer *)userdata); +} + LinphoneSoundDaemon * linphone_sound_daemon_new(MSFactory* factory, const char *cardname, int rate, int nchannels){ int i; MSConnectionPoint mp; @@ -251,7 +255,7 @@ LinphoneSoundDaemon * linphone_sound_daemon_new(MSFactory* factory, const char * mp.pin=0; lsd_player_init(factory, &lsd->branches[0],mp,MS_ITC_SOURCE_ID,lsd); - ms_filter_add_notify_callback(lsd->branches[0].player,(MSFilterNotifyFunc)lsd_player_configure,&lsd->branches[0],FALSE); + ms_filter_add_notify_callback(lsd->branches[0].player,lsd_player_configure_notify_func,&lsd->branches[0],FALSE); for(i=1;ibranches[i],mp,MS_FILE_PLAYER_ID,lsd); diff --git a/coreapi/misc.c b/coreapi/misc.c index 3e255a354..0467dcfea 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -476,7 +476,7 @@ const char * linphone_core_get_echo_canceller_filter_name(const LinphoneCore *lc * task_fun must return BELLE_SIP_STOP when job is finished. **/ void linphone_core_queue_task(LinphoneCore *lc, belle_sip_source_func_t task_fun, void *data, const char *task_description){ - belle_sip_source_t *s=lc->sal->create_timer(task_fun,data, 20, task_description); + belle_sip_source_t *s=lc->sal->createTimer(task_fun,data, 20, task_description); belle_sip_object_unref(s); } @@ -919,8 +919,11 @@ void linphone_core_report_call_log(LinphoneCore *lc, LinphoneCallLog *call_log){ } linphone_address_unref(conference_factory_addr); } - const char *username = linphone_address_get_username(call_log->to); - if (username && (strstr(username, "chatroom-") == username)) + const char *usernameFrom = linphone_address_get_username(call_log->from); + const char *usernameTo = linphone_address_get_username(call_log->to); + if ((usernameFrom && (strstr(usernameFrom, "chatroom-") == usernameFrom)) + || (usernameTo && (strstr(usernameTo, "chatroom-") == usernameTo)) + ) return; // End of workaround diff --git a/coreapi/offeranswer.c b/coreapi/offeranswer.c index 3644d9bcc..d76f1c68e 100644 --- a/coreapi/offeranswer.c +++ b/coreapi/offeranswer.c @@ -498,7 +498,7 @@ static void initiate_incoming(MSFactory *factory, const SalStreamDescription *lo if (remote_offer->haveZrtpHash == 1) { if (local_cap->zrtphash[0] != 0) { /* if ZRTP is available, set the zrtp hash even if it is not selected */ - strncpy((char *)(result->zrtphash), (char *)(local_cap->zrtphash), sizeof(local_cap->zrtphash)); + strncpy((char *)(result->zrtphash), (char *)(local_cap->zrtphash), sizeof(result->zrtphash)); result->haveZrtpHash = 1; } } diff --git a/coreapi/player.c b/coreapi/player.c index a8a73453c..ac9e3f5ab 100644 --- a/coreapi/player.c +++ b/coreapi/player.c @@ -100,10 +100,11 @@ void linphone_player_close(LinphonePlayer *obj){ } void linphone_player_destroy(LinphonePlayer *obj) { - if(obj->destroy) obj->destroy(obj); + _linphone_player_destroy(obj); } void _linphone_player_destroy(LinphonePlayer *player) { + if(player->destroy) player->destroy(player); linphone_player_cbs_unref(player->callbacks); } @@ -133,9 +134,13 @@ static bool_t call_player_check_state(LinphonePlayer *player, bool_t check_playe static void on_eof(void *user_data, MSFilter *f, unsigned int event_id, void *arg){ LinphonePlayer *player=(LinphonePlayer *)user_data; - LinphonePlayerCbs *cbs = linphone_player_get_callbacks(player); - LinphonePlayerCbsEofReachedCb cb = linphone_player_cbs_get_eof_reached(cbs); - if (cb) cb(player); + switch (event_id){ + case MS_PLAYER_EOF: + LinphonePlayerCbs *cbs = linphone_player_get_callbacks(player); + LinphonePlayerCbsEofReachedCb cb = linphone_player_cbs_get_eof_reached(cbs); + if (cb) cb(player); + break; + } } static int call_player_open(LinphonePlayer* player, const char *filename){ diff --git a/coreapi/presence.c b/coreapi/presence.c index eea5c8980..bb4ffa087 100644 --- a/coreapi/presence.c +++ b/coreapi/presence.c @@ -126,6 +126,10 @@ static void presence_note_uninit(LinphonePresenceNote *note) { } } +static void presence_note_unref(void *note) { + linphone_presence_note_unref((LinphonePresenceNote *)note); +} + static LinphonePresenceService * presence_service_new(const char *id, LinphonePresenceBasicStatus status) { LinphonePresenceService *service = belle_sip_object_new(LinphonePresenceService); if (id != NULL) { @@ -143,10 +147,14 @@ static void presence_service_uninit(LinphonePresenceService *service) { if (service->contact != NULL) { ms_free(service->contact); } - bctbx_list_for_each(service->notes, (MSIterateFunc)linphone_presence_note_unref); + bctbx_list_for_each(service->notes, presence_note_unref); bctbx_list_free(service->notes); }; +static void presence_service_unref(void *service) { + linphone_presence_service_unref((LinphonePresenceService *)service); +} + static void presence_service_set_timestamp(LinphonePresenceService *service, time_t timestamp) { service->timestamp = timestamp; } @@ -161,6 +169,10 @@ static void presence_activity_uninit(LinphonePresenceActivity *activity) { } } +static void presence_activity_unref(void *activity) { + linphone_presence_activity_unref((LinphonePresenceActivity *)activity); +} + static time_t parse_timestamp(const char *timestamp) { struct tm ret; time_t seconds; @@ -219,14 +231,18 @@ static void presence_person_uninit(LinphonePresencePerson *person) { if (person->id != NULL) { ms_free(person->id); } - bctbx_list_for_each(person->activities, (MSIterateFunc)linphone_presence_activity_unref); + bctbx_list_for_each(person->activities, presence_activity_unref); bctbx_list_free(person->activities); - bctbx_list_for_each(person->activities_notes, (MSIterateFunc)linphone_presence_note_unref); + bctbx_list_for_each(person->activities_notes, presence_note_unref); bctbx_list_free(person->activities_notes); - bctbx_list_for_each(person->notes, (MSIterateFunc)linphone_presence_note_unref); + bctbx_list_for_each(person->notes, presence_note_unref); bctbx_list_free(person->notes); } +static void presence_person_unref(void *person) { + linphone_presence_person_unref((LinphonePresencePerson *)person); +} + static void presence_person_add_activities_note(LinphonePresencePerson *person, LinphonePresenceNote *note) { person->activities_notes = bctbx_list_append(person->activities_notes, note); } @@ -256,11 +272,11 @@ static void presence_model_find_open_basic_status(LinphonePresenceService *servi static void presence_model_uninit(LinphonePresenceModel *model) { if (model->presentity) linphone_address_unref(model->presentity); - bctbx_list_for_each(model->services, (MSIterateFunc)linphone_presence_service_unref); + bctbx_list_for_each(model->services, presence_service_unref); bctbx_list_free(model->services); - bctbx_list_for_each(model->persons, (MSIterateFunc)linphone_presence_person_unref); + bctbx_list_for_each(model->persons, presence_person_unref); bctbx_list_free(model->persons); - bctbx_list_for_each(model->notes, (MSIterateFunc)linphone_presence_note_unref); + bctbx_list_for_each(model->notes, presence_note_unref); bctbx_list_free(model->notes); } @@ -357,6 +373,7 @@ LinphoneStatus linphone_presence_model_set_contact(LinphonePresenceModel *model, service = linphone_presence_service_new(NULL, LinphonePresenceBasicStatusClosed, NULL); if (service == NULL) return -1; linphone_presence_model_add_service(model, service); + linphone_presence_service_unref(service); } return linphone_presence_service_set_contact(service, contact); } @@ -445,10 +462,14 @@ LinphoneStatus linphone_presence_model_add_activity(LinphonePresenceModel *model return 0; } +static void presence_person_clear_activities(void *person) { + linphone_presence_person_clear_activities((LinphonePresencePerson *)person); +} + LinphoneStatus linphone_presence_model_clear_activities(LinphonePresenceModel *model) { if (model == NULL) return -1; - bctbx_list_for_each(model->persons, (MSIterateFunc)linphone_presence_person_clear_activities); + bctbx_list_for_each(model->persons, presence_person_clear_activities); return 0; } @@ -579,16 +600,16 @@ LinphoneStatus linphone_presence_model_add_note(LinphonePresenceModel *model, co } static void clear_presence_person_notes(LinphonePresencePerson *person) { - bctbx_list_for_each(person->activities_notes, (MSIterateFunc)linphone_presence_note_unref); + bctbx_list_for_each(person->activities_notes, presence_note_unref); bctbx_list_free(person->activities_notes); person->activities_notes = NULL; - bctbx_list_for_each(person->notes, (MSIterateFunc)linphone_presence_note_unref); + bctbx_list_for_each(person->notes, presence_note_unref); bctbx_list_free(person->notes); person->notes = NULL; } static void clear_presence_service_notes(LinphonePresenceService *service) { - bctbx_list_for_each(service->notes, (MSIterateFunc)linphone_presence_note_unref); + bctbx_list_for_each(service->notes, presence_note_unref); bctbx_list_free(service->notes); service->notes = NULL; } @@ -599,7 +620,7 @@ LinphoneStatus linphone_presence_model_clear_notes(LinphonePresenceModel *model) bctbx_list_for_each(model->persons, (MSIterateFunc)clear_presence_person_notes); bctbx_list_for_each(model->services, (MSIterateFunc)clear_presence_service_notes); - bctbx_list_for_each(model->notes, (MSIterateFunc)linphone_presence_note_unref); + bctbx_list_for_each(model->notes, presence_note_unref); bctbx_list_free(model->notes); model->notes = NULL; @@ -635,7 +656,7 @@ LinphoneStatus linphone_presence_model_add_service(LinphonePresenceModel *model, LinphoneStatus linphone_presence_model_clear_services(LinphonePresenceModel *model) { if (model == NULL) return -1; - bctbx_list_for_each(model->services, (MSIterateFunc)linphone_presence_service_unref); + bctbx_list_for_each(model->services, presence_service_unref); bctbx_list_free(model->services); model->services = NULL; return 0; @@ -661,7 +682,7 @@ LinphoneStatus linphone_presence_model_add_person(LinphonePresenceModel *model, LinphoneStatus linphone_presence_model_clear_persons(LinphonePresenceModel *model) { if (model == NULL) return -1; - bctbx_list_for_each(model->persons, (MSIterateFunc)linphone_presence_person_unref); + bctbx_list_for_each(model->persons, presence_person_unref); bctbx_list_free(model->persons); model->persons = NULL; return 0; @@ -797,7 +818,7 @@ LinphoneStatus linphone_presence_service_add_note(LinphonePresenceService *servi LinphoneStatus linphone_presence_service_clear_notes(LinphonePresenceService *service) { if (service == NULL) return -1; - bctbx_list_for_each(service->notes, (MSIterateFunc)linphone_presence_note_unref); + bctbx_list_for_each(service->notes, presence_note_unref); bctbx_list_free(service->notes); service->notes = NULL; return 0; @@ -858,7 +879,7 @@ LinphoneStatus linphone_presence_person_add_activity(LinphonePresencePerson *per LinphoneStatus linphone_presence_person_clear_activities(LinphonePresencePerson *person) { if (person == NULL) return -1; - bctbx_list_for_each(person->activities, (MSIterateFunc)linphone_presence_activity_unref); + bctbx_list_for_each(person->activities, presence_activity_unref); bctbx_list_free(person->activities); person->activities = NULL; return 0; @@ -883,7 +904,7 @@ LinphoneStatus linphone_presence_person_add_note(LinphonePresencePerson *person, LinphoneStatus linphone_presence_person_clear_notes(LinphonePresencePerson *person) { if (person == NULL) return -1; - bctbx_list_for_each(person->notes, (MSIterateFunc)linphone_presence_note_unref); + bctbx_list_for_each(person->notes, presence_note_unref); bctbx_list_free(person->notes); person->notes = NULL; return 0; @@ -908,7 +929,7 @@ LinphoneStatus linphone_presence_person_add_activities_note(LinphonePresencePers LinphoneStatus linphone_presence_person_clear_activities_notes(LinphonePresencePerson *person) { if (person == NULL) return -1; - bctbx_list_for_each(person->activities_notes, (MSIterateFunc)linphone_presence_note_unref); + bctbx_list_for_each(person->activities_notes, presence_note_unref); bctbx_list_free(person->activities_notes); person->activities_notes = NULL; return 0; @@ -1437,7 +1458,7 @@ static int process_pidf_xml_presence_persons(xmlparsing_context_t *xml_ctx, Linp if (err < 0) { /* Remove all the persons added since there was an error. */ - bctbx_list_for_each(model->persons, (MSIterateFunc)linphone_presence_person_unref); + bctbx_list_for_each(model->persons, presence_person_unref); } return err; } @@ -1562,7 +1583,7 @@ void linphone_subscription_new(LinphoneCore *lc, SalSubscribeOp *op, const char linphone_friend_add_incoming_subscription(lf, op); lf->inc_subscribe_pending=TRUE; if (lp_config_get_int(lc->config,"sip","notify_pending_state",0)) { - op->notify_pending_state(); + op->notifyPendingState(); } op->accept(); } else { @@ -1935,7 +1956,7 @@ void linphone_notify_recv(LinphoneCore *lc, SalOp *op, SalSubscribeStatus ss, Sa if (linphone_core_get_default_friend_list(lc) != NULL) lf=linphone_core_find_friend_by_out_subscribe(lc, op); if (lf==NULL && lp_config_get_int(lc->config,"sip","allow_out_of_subscribe_presence",0)){ - char *buf = sal_address_as_string_uri_only(op->get_from_address()); + char *buf = sal_address_as_string_uri_only(op->getFromAddress()); LinphoneAddress *addr = linphone_address_new(buf); lf = linphone_core_find_friend(lc, addr); ms_free(buf); @@ -1999,7 +2020,7 @@ void linphone_subscription_closed(LinphoneCore *lc, SalOp *op){ linphone_friend_remove_incoming_subscription(lf, op); }else{ /*case of an op that we already released because the friend was destroyed*/ - ms_message("Receiving unsuscribe for unknown in-subscribtion from %s", op->get_from()); + ms_message("Receiving unsuscribe for unknown in-subscribtion from %s", op->getFrom().c_str()); } } diff --git a/coreapi/private.h b/coreapi/private.h index 37d433c90..bc33c4184 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -127,7 +127,6 @@ #define STRING_SET(field, value) do{ if (field){bctbx_free(field);field=NULL;}; field=bctbx_strdup(value); }while(0) #define STRING_TRANSFER(field, newvalue) do{ if (field){bctbx_free(field);field=NULL;}; field=newvalue; }while(0) - #ifdef __cplusplus #define getPlatformHelpers(lc) static_cast(lc->platform_helper) #endif diff --git a/coreapi/private_functions.h b/coreapi/private_functions.h index 7649157d0..0f706c415 100644 --- a/coreapi/private_functions.h +++ b/coreapi/private_functions.h @@ -29,6 +29,7 @@ #include "private_types.h" #include "tester_utils.h" +#include "conference/participant-imdn-state.h" #include "sal/op.h" #include "sal/event-op.h" @@ -48,6 +49,8 @@ void linphone_call_notify_stats_updated(LinphoneCall *call, const LinphoneCallSt void linphone_call_notify_info_message_received(LinphoneCall *call, const LinphoneInfoMessage *msg); void linphone_call_notify_ack_processing(LinphoneCall *call, LinphoneHeaders *msg, bool_t is_received); void linphone_call_notify_tmmbr_received(LinphoneCall *call, int stream_index, int tmmbr); +void linphone_call_notify_snapshot_taken(LinphoneCall *call, const char *file_path); +void linphone_call_notify_next_video_frame_decoded(LinphoneCall *call); LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, const LinphoneAddress *from, const LinphoneAddress *to, const LinphoneCallParams *params, LinphoneProxyConfig *cfg); LinphoneCall * linphone_call_new_incoming(struct _LinphoneCore *lc, const LinphoneAddress *from, const LinphoneAddress *to, LinphonePrivate::SalCallOp *op); @@ -238,7 +241,6 @@ LinphoneFriend * linphone_friend_new_from_config_file(struct _LinphoneCore *lc, void linphone_proxy_config_update(LinphoneProxyConfig *cfg); LinphoneProxyConfig * linphone_core_lookup_known_proxy(LinphoneCore *lc, const LinphoneAddress *uri); const char *linphone_core_find_best_identity(LinphoneCore *lc, const LinphoneAddress *to); -int linphone_core_get_local_ip_for(int type, const char *dest, char *result); LINPHONE_PUBLIC void linphone_core_get_local_ip(LinphoneCore *lc, int af, const char *dest, char *result); LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(LinphoneCore *lc, int index); @@ -288,6 +290,8 @@ void _linphone_chat_room_notify_participant_device_removed(LinphoneChatRoom *cr, void _linphone_chat_room_notify_participant_admin_status_changed(LinphoneChatRoom *cr, const LinphoneEventLog *event_log); void _linphone_chat_room_notify_state_changed(LinphoneChatRoom *cr, LinphoneChatRoomState newState); void _linphone_chat_room_notify_subject_changed(LinphoneChatRoom *cr, const LinphoneEventLog *event_log); +void _linphone_chat_room_notify_conference_joined(LinphoneChatRoom *cr, const LinphoneEventLog *event_log); +void _linphone_chat_room_notify_conference_left(LinphoneChatRoom *cr, const LinphoneEventLog *event_log); void _linphone_chat_room_notify_undecryptable_message_received(LinphoneChatRoom *cr, LinphoneChatMessage *msg); void _linphone_chat_room_notify_chat_message_received(LinphoneChatRoom *cr, const LinphoneEventLog *event_log); void _linphone_chat_room_notify_chat_message_sent(LinphoneChatRoom *cr, const LinphoneEventLog *event_log); @@ -298,6 +302,7 @@ void _linphone_chat_room_notify_participant_registration_subscription_requested( void _linphone_chat_room_notify_participant_registration_unsubscription_requested(LinphoneChatRoom *cr, const LinphoneAddress *participantAddr); void _linphone_chat_room_notify_chat_message_should_be_stored(LinphoneChatRoom *cr, LinphoneChatMessage *msg); void _linphone_chat_room_clear_callbacks (LinphoneChatRoom *cr); +const LinphoneParticipantImdnState *_linphone_participant_imdn_state_from_cpp_obj (const LinphonePrivate::ParticipantImdnState &state); LinphoneToneDescription * linphone_tone_description_new(LinphoneReason reason, LinphoneToneID id, const char *audiofile); void linphone_tone_description_destroy(LinphoneToneDescription *obj); @@ -382,7 +387,7 @@ void linphone_configure_op(LinphoneCore *lc, LinphonePrivate::SalOp *op, const L void linphone_configure_op_with_proxy(LinphoneCore *lc, LinphonePrivate::SalOp *op, const LinphoneAddress *dest, SalCustomHeader *headers, bool_t with_contact, LinphoneProxyConfig *proxy); LinphoneContent * linphone_content_new(void); LinphoneContent * linphone_content_copy(const LinphoneContent *ref); -SalBodyHandler *sal_body_handler_from_content(const LinphoneContent *content); +SalBodyHandler *sal_body_handler_from_content(const LinphoneContent *content, bool parseMultipart = true); SalReason linphone_reason_to_sal(LinphoneReason reason); LinphoneReason linphone_reason_from_sal(SalReason reason); void linphone_error_info_to_sal(const LinphoneErrorInfo* ei, SalErrorInfo* sei); @@ -399,7 +404,7 @@ void linphone_event_set_state(LinphoneEvent *lev, LinphoneSubscriptionState stat void linphone_event_set_publish_state(LinphoneEvent *lev, LinphonePublishState state); void _linphone_event_notify_notify_response(const LinphoneEvent *lev); LinphoneSubscriptionState linphone_subscription_state_from_sal(SalSubscribeStatus ss); -LinphoneContent *linphone_content_from_sal_body_handler(SalBodyHandler *ref); +LinphoneContent *linphone_content_from_sal_body_handler(const SalBodyHandler *ref, bool parseMultipart = true); void linphone_core_invalidate_friend_subscriptions(LinphoneCore *lc); void linphone_core_register_offer_answer_providers(LinphoneCore *lc); @@ -501,6 +506,7 @@ void linphone_core_notify_configuring_status(LinphoneCore *lc, LinphoneConfiguri void linphone_core_notify_network_reachable(LinphoneCore *lc, bool_t reachable); void linphone_core_notify_notify_received(LinphoneCore *lc, LinphoneEvent *lev, const char *notified_event, const LinphoneContent *body); +void linphone_core_notify_subscribe_received(LinphoneCore *lc, LinphoneEvent *lev, const char *subscribe_event, const LinphoneContent *body); void linphone_core_notify_subscription_state_changed(LinphoneCore *lc, LinphoneEvent *lev, LinphoneSubscriptionState state); void linphone_core_notify_publish_state_changed(LinphoneCore *lc, LinphoneEvent *lev, LinphonePublishState state); void linphone_core_notify_log_collection_upload_state_changed(LinphoneCore *lc, LinphoneCoreLogCollectionUploadState state, const char *info); @@ -558,6 +564,8 @@ LinphoneNatPolicy * linphone_config_create_nat_policy_from_section(const Linphon SalCustomHeader *linphone_info_message_get_headers (const LinphoneInfoMessage *im); void linphone_info_message_set_headers (LinphoneInfoMessage *im, const SalCustomHeader *headers); +void _linphone_core_set_log_handler(OrtpLogFunc logfunc); + #ifdef __cplusplus } #endif diff --git a/coreapi/private_structs.h b/coreapi/private_structs.h index 9002d1c71..f532cbcf9 100644 --- a/coreapi/private_structs.h +++ b/coreapi/private_structs.h @@ -132,6 +132,8 @@ struct _LinphoneProxyConfig char *refkey; char *sip_etag; /*publish context*/ char *conference_factory_uri; + + bool_t push_notification_allowed; }; BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneProxyConfig); @@ -450,17 +452,6 @@ struct _EchoTester { unsigned int rate; }; -struct _LinphoneContent { - belle_sip_object_t base; - void *user_data; - SalBodyHandler *body_handler; - char *name; /**< used by RCS File transfer messages to store the original filename of the file to be downloaded from server */ - char *key; /**< used by RCS File transfer messages to store the key to encrypt file if needed */ - size_t keyLength; /**< Length of key in bytes */ - void *cryptoContext; /**< crypto context used to encrypt file for RCS file transfer */ - bool_t owned_fields; -}; - BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneContent); struct _LinphoneBuffer { @@ -824,6 +815,7 @@ namespace LinphonePrivate { char *update_check_current_version; \ bctbx_list_t *chat_rooms; \ bctbx_list_t *callsCache; \ + bool_t dns_set_by_app; \ #ifdef SQLITE_STORAGE_ENABLED #define LINPHONE_CORE_STRUCT_FIELDS \ diff --git a/coreapi/proxy.c b/coreapi/proxy.c index 03213da1e..11972d9d1 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -25,6 +25,7 @@ Copyright (C) 2000 Simon MORLAT (simon.morlat@linphone.org) #include "linphone/core.h" #include "linphone/lpconfig.h" #include "linphone/sipsetup.h" + #include "mediastreamer2/mediastream.h" #include "enum.h" @@ -142,6 +143,7 @@ static void linphone_proxy_config_init(LinphoneCore* lc, LinphoneProxyConfig *cf cfg->avpf_rr_interval = lc ? !!lp_config_get_default_int(lc->config, "proxy", "avpf_rr_interval", 5) : 5; cfg->publish_expires= lc ? lp_config_get_default_int(lc->config, "proxy", "publish_expires", -1) : -1; cfg->publish = lc ? !!lp_config_get_default_int(lc->config, "proxy", "publish", FALSE) : FALSE; + cfg->push_notification_allowed = lc ? !!lp_config_get_default_int(lc->config, "proxy", "push_notification_allowed", TRUE) : TRUE; cfg->refkey = refkey ? ms_strdup(refkey) : NULL; if (nat_policy_ref) { LinphoneNatPolicy *policy = linphone_config_create_nat_policy_from_section(lc->config,nat_policy_ref); @@ -434,7 +436,7 @@ void linphone_proxy_config_enable_publish(LinphoneProxyConfig *cfg, bool_t val){ } void linphone_proxy_config_pause_register(LinphoneProxyConfig *cfg){ - if (cfg->op) cfg->op->stop_refreshing(); + if (cfg->op) cfg->op->stopRefreshing(); } void linphone_proxy_config_edit(LinphoneProxyConfig *cfg){ @@ -455,20 +457,16 @@ void linphone_proxy_config_apply(LinphoneProxyConfig *cfg,LinphoneCore *lc){ void linphone_proxy_config_stop_refreshing(LinphoneProxyConfig * cfg){ LinphoneAddress *contact_addr = NULL; - { - const SalAddress *sal_addr = cfg->op && cfg->state == LinphoneRegistrationOk - ? cfg->op->get_contact_address() - : NULL; - if (sal_addr) { - char *buf = sal_address_as_string(sal_addr); - contact_addr = buf ? linphone_address_new(buf) : NULL; - ms_free(buf); - } + const SalAddress *sal_addr = cfg->op && cfg->state == LinphoneRegistrationOk ? cfg->op->getContactAddress() : NULL; + if (sal_addr) { + char *buf = sal_address_as_string(sal_addr); + contact_addr = buf ? linphone_address_new(buf) : NULL; + ms_free(buf); } /*with udp, there is a risk of port reuse, so I prefer to not do anything for now*/ if (contact_addr) { - if (linphone_address_get_transport(contact_addr) != LinphoneTransportUdp) { + if (linphone_address_get_transport(contact_addr) != LinphoneTransportUdp && lp_config_get_int(cfg->lc->config, "sip", "unregister_previous_contact", 0)) { if (cfg->pending_contact) linphone_address_unref(cfg->pending_contact); cfg->pending_contact=contact_addr; @@ -540,10 +538,10 @@ static void linphone_proxy_config_register(LinphoneProxyConfig *cfg){ guess_contact_for_register(cfg); if (cfg->contact_address) - cfg->op->set_contact_address(L_GET_PRIVATE_FROM_C_OBJECT(cfg->contact_address)->getInternalAddress()); - cfg->op->set_user_pointer(cfg); + cfg->op->setContactAddress(L_GET_PRIVATE_FROM_C_OBJECT(cfg->contact_address)->getInternalAddress()); + cfg->op->setUserPointer(cfg); - if (cfg->op->register_( + if (cfg->op->sendRegister( proxy_string, cfg->reg_identity, cfg->expires, @@ -570,7 +568,7 @@ static void linphone_proxy_config_register(LinphoneProxyConfig *cfg){ void linphone_proxy_config_refresh_register(LinphoneProxyConfig *cfg){ if (cfg->reg_sendregister && cfg->op && cfg->state!=LinphoneRegistrationProgress){ - if (cfg->op->register_refresh(cfg->expires) == 0) { + if (cfg->op->refreshRegister(cfg->expires) == 0) { linphone_proxy_config_set_state(cfg,LinphoneRegistrationProgress, "Refresh registration"); } } @@ -852,7 +850,7 @@ LinphoneStatus linphone_proxy_config_done(LinphoneProxyConfig *cfg) if (res == LinphoneProxyConfigAddressDifferent) { _linphone_proxy_config_unregister(cfg); } - cfg->op->set_user_pointer(NULL); /*we don't want to receive status for this un register*/ + cfg->op->setUserPointer(NULL); /*we don't want to receive status for this un register*/ cfg->op->unref(); /*but we keep refresher to handle authentication if needed*/ cfg->op=NULL; } @@ -1047,7 +1045,7 @@ struct _LinphoneCore * linphone_proxy_config_get_core(const LinphoneProxyConfig const char *linphone_proxy_config_get_custom_header(LinphoneProxyConfig *cfg, const char *header_name){ const SalCustomHeader *ch; if (!cfg->op) return NULL; - ch = cfg->op->get_recv_custom_header(); + ch = cfg->op->getRecvCustomHeaders(); return sal_custom_header_find(ch, header_name); } @@ -1189,6 +1187,7 @@ void linphone_proxy_config_write_to_config_file(LpConfig *config, LinphoneProxyC lp_config_set_int(config,key,"dial_escape_plus",cfg->dial_escape_plus); lp_config_set_string(config,key,"dial_prefix",cfg->dial_prefix); lp_config_set_int(config,key,"privacy",(int)cfg->privacy); + lp_config_set_int(config,key,"push_notification_allowed",(int)cfg->push_notification_allowed); if (cfg->refkey) lp_config_set_string(config,key,"refkey",cfg->refkey); lp_config_set_int(config, key, "publish_expires", cfg->publish_expires); @@ -1249,6 +1248,7 @@ LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(LinphoneCore* lc CONFIGURE_INT_VALUE(cfg,config,key,expires,"reg_expires", int) CONFIGURE_BOOL_VALUE(cfg,config,key,register,"reg_sendregister") CONFIGURE_BOOL_VALUE(cfg,config,key,publish,"publish") + linphone_proxy_config_set_push_notification_allowed(cfg, !!lp_config_get_int(config,key,"push_notification_allowed",linphone_proxy_config_is_push_notification_allowed(cfg))); linphone_proxy_config_set_avpf_mode(cfg,static_cast(lp_config_get_int(config,key,"avpf",linphone_proxy_config_get_avpf_mode(cfg)))); CONFIGURE_INT_VALUE(cfg,config,key,avpf_rr_interval,"avpf_rr_interval",uint8_t) CONFIGURE_INT_VALUE(cfg,config,key,dial_escape_plus,"dial_escape_plus",bool_t) @@ -1416,7 +1416,7 @@ const LinphoneErrorInfo *linphone_proxy_config_get_error_info(const LinphoneProx } const LinphoneAddress* linphone_proxy_config_get_service_route(const LinphoneProxyConfig* cfg) { - return cfg->op?(const LinphoneAddress*) cfg->op->get_service_route():NULL; + return cfg->op?(const LinphoneAddress*) cfg->op->getServiceRoute():NULL; } const char* linphone_proxy_config_get_transport(const LinphoneProxyConfig *cfg) { const char* addr=NULL; @@ -1496,7 +1496,7 @@ const LinphoneAddress *linphone_proxy_config_get_contact (const LinphoneProxyCon // Warning : Do not remove, the op can change its contact_address if (!cfg->op) return NULL; - const SalAddress *salAddr = cfg->op->get_contact_address(); + const SalAddress *salAddr = cfg->op->getContactAddress(); if (!salAddr) return NULL; if (cfg->contact_address) @@ -1538,7 +1538,7 @@ LinphoneNatPolicy * linphone_proxy_config_get_nat_policy(const LinphoneProxyConf void linphone_proxy_config_set_nat_policy(LinphoneProxyConfig *cfg, LinphoneNatPolicy *policy) { if (policy != NULL) { - policy = linphone_nat_policy_ref(policy); /* Prevent object destruction if the same policy is used */ + linphone_nat_policy_ref(policy); /* Prevent object destruction if the same policy is used */ policy->lc = cfg->lc; } if (cfg->nat_policy != NULL) linphone_nat_policy_unref(cfg->nat_policy); @@ -1578,3 +1578,11 @@ void linphone_proxy_config_set_conference_factory_uri(LinphoneProxyConfig *cfg, const char * linphone_proxy_config_get_conference_factory_uri(const LinphoneProxyConfig *cfg) { return cfg->conference_factory_uri; } + +bool_t linphone_proxy_config_is_push_notification_allowed(const LinphoneProxyConfig *cfg) { + return cfg->push_notification_allowed; +} + +void linphone_proxy_config_set_push_notification_allowed(LinphoneProxyConfig *cfg, bool_t is_allowed) { + cfg->push_notification_allowed = is_allowed; +} diff --git a/coreapi/quality_reporting.c b/coreapi/quality_reporting.c index 571a8faa0..089077d41 100644 --- a/coreapi/quality_reporting.c +++ b/coreapi/quality_reporting.c @@ -21,7 +21,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "config.h" #endif +#include "linphone/api/c-content.h" #include "linphone/core.h" + #include "private.h" #include "c-wrapper/internal/c-sal.h" #include "sal/sal.h" @@ -378,7 +380,7 @@ static int send_report(LinphoneCall* call, reporting_session_report_t * report, sal_address_has_uri_param(salAddress, "maddr") || linphone_address_get_port(request_uri) != 0) { ms_message("Publishing report with custom route %s", collector_uri); - lev->op->set_route(collector_uri); + lev->op->setRoute(collector_uri); } if (linphone_event_send_publish(lev, content) != 0){ @@ -422,7 +424,7 @@ static const SalStreamDescription * get_media_stream_for_desc(const SalMediaDesc static void update_ip(LinphoneCall * call, int stats_type) { SalStreamType sal_stream_type = stats_type == LINPHONE_CALL_STATS_AUDIO ? SalAudio : stats_type == LINPHONE_CALL_STATS_VIDEO ? SalVideo : SalText; const SalStreamDescription * local_desc = get_media_stream_for_desc(_linphone_call_get_local_desc(call), sal_stream_type); - const SalStreamDescription * remote_desc = get_media_stream_for_desc(L_GET_PRIVATE_FROM_C_OBJECT(call)->getOp()->get_remote_media_description(), sal_stream_type); + const SalStreamDescription * remote_desc = get_media_stream_for_desc(L_GET_PRIVATE_FROM_C_OBJECT(call)->getOp()->getRemoteMediaDescription(), sal_stream_type); LinphoneCallLog *log = L_GET_CPP_PTR_FROM_C_OBJECT(call)->getLog(); if (local_desc != NULL) { @@ -442,7 +444,7 @@ static void update_ip(LinphoneCall * call, int stats_type) { if (strlen(remote_desc->rtp_addr) > 0) { STR_REASSIGN(log->reporting.reports[stats_type]->info.remote_addr.ip, ms_strdup(remote_desc->rtp_addr)); } else { - STR_REASSIGN(log->reporting.reports[stats_type]->info.remote_addr.ip, ms_strdup(L_GET_PRIVATE_FROM_C_OBJECT(call)->getOp()->get_remote_media_description()->addr)); + STR_REASSIGN(log->reporting.reports[stats_type]->info.remote_addr.ip, ms_strdup(L_GET_PRIVATE_FROM_C_OBJECT(call)->getOp()->getRemoteMediaDescription()->addr)); } } } @@ -503,13 +505,12 @@ void linphone_reporting_update_media_info(LinphoneCall * call, int stats_type) { const LinphoneCallParams * current_params = linphone_call_get_current_params(call); LinphoneCallLog *log = L_GET_CPP_PTR_FROM_C_OBJECT(call)->getLog(); reporting_session_report_t * report = log->reporting.reports[stats_type]; - char * dialog_id; // call->op might be already released if hanging up in state LinphoneCallOutgoingInit if (!media_report_enabled(call, stats_type) || !L_GET_PRIVATE_FROM_C_OBJECT(call)->getOp()) return; - dialog_id = L_GET_PRIVATE_FROM_C_OBJECT(call)->getOp()->get_dialog_id(); + std::string dialogId = L_GET_PRIVATE_FROM_C_OBJECT(call)->getOp()->getDialogId(); STR_REASSIGN(report->info.call_id, ms_strdup(log->call_id)); @@ -519,13 +520,13 @@ void linphone_reporting_update_media_info(LinphoneCall * call, int stats_type) { // RFC states: "LocalGroupID provides the identification for the purposes // of aggregation for the local endpoint.". STR_REASSIGN(report->info.local_addr.group, ms_strdup_printf("%s-%s-%s" - , dialog_id ? dialog_id : "" + , dialogId.c_str() , "local" , report->local_metrics.user_agent ? report->local_metrics.user_agent : "" ) ); STR_REASSIGN(report->info.remote_addr.group, ms_strdup_printf("%s-%s-%s" - , dialog_id ? dialog_id : "" + , dialogId.c_str() , "remote" , report->remote_metrics.user_agent ? report->remote_metrics.user_agent : "" ) @@ -580,7 +581,7 @@ void linphone_reporting_update_media_info(LinphoneCall * call, int stats_type) { } } - STR_REASSIGN(report->dialog_id, ms_strdup_printf("%s;%u", dialog_id ? dialog_id : "", report->info.local_addr.ssrc)); + STR_REASSIGN(report->dialog_id, ms_strdup_printf("%s;%u", dialogId.c_str(), report->info.local_addr.ssrc)); if (local_payload != NULL) { report->local_metrics.session_description.payload_type = local_payload->type; @@ -595,8 +596,6 @@ void linphone_reporting_update_media_info(LinphoneCall * call, int stats_type) { report->remote_metrics.session_description.sample_rate = remote_payload->clock_rate; STR_REASSIGN(report->remote_metrics.session_description.fmtp, ms_strdup(remote_payload->recv_fmtp)); } - - ms_free(dialog_id); } /* generate random float in interval ] 0.9 t ; 1.1 t [*/ diff --git a/coreapi/tester_utils.h b/coreapi/tester_utils.h index 966adccab..0dd600d72 100644 --- a/coreapi/tester_utils.h +++ b/coreapi/tester_utils.h @@ -48,6 +48,7 @@ extern "C" { LINPHONE_PUBLIC LinphoneVcardContext *linphone_core_get_vcard_context(const LinphoneCore *lc); LINPHONE_PUBLIC bool_t linphone_core_rtcp_enabled(const LinphoneCore *lc); LINPHONE_PUBLIC void linphone_core_get_local_ip(LinphoneCore *lc, int af, const char *dest, char *result); +LINPHONE_PUBLIC int linphone_core_get_local_ip_for(int type, const char *dest, char *result); LINPHONE_PUBLIC void linphone_core_enable_forced_ice_relay(LinphoneCore *lc, bool_t enable); LINPHONE_PUBLIC void linphone_core_set_zrtp_not_available_simulation(LinphoneCore *lc, bool_t enabled); LINPHONE_PUBLIC belle_http_provider_t *linphone_core_get_http_provider(const LinphoneCore *lc); diff --git a/coreapi/vcard.cc b/coreapi/vcard.cc index 336ecf050..36488137f 100644 --- a/coreapi/vcard.cc +++ b/coreapi/vcard.cc @@ -367,7 +367,7 @@ bool_t linphone_vcard_generate_unique_id(LinphoneVcard *vCard) { if (linphone_vcard_get_uid(vCard)) { return FALSE; } - if (LinphonePrivate::Sal::generate_uuid(uuid, sizeof(uuid)) == 0) { + if (LinphonePrivate::Sal::generateUuid(uuid, sizeof(uuid)) == 0) { char vcard_uuid[sizeof(uuid)+4]; snprintf(vcard_uuid, sizeof(vcard_uuid), "urn:%s", uuid); linphone_vcard_set_uid(vCard, vcard_uuid); diff --git a/coreapi/vtables.c b/coreapi/vtables.c index 4592dec3f..25d7254b0 100644 --- a/coreapi/vtables.c +++ b/coreapi/vtables.c @@ -88,6 +88,7 @@ static void cleanup_dead_vtable_refs(LinphoneCore *lc){ lc->vtable_notify_recursion--; void linphone_core_notify_global_state_changed(LinphoneCore *lc, LinphoneGlobalState gstate, const char *message) { + L_GET_PRIVATE_FROM_C_OBJECT(lc)->notifyGlobalStateChanged(gstate); NOTIFY_IF_EXIST(global_state_changed,lc,gstate,message); cleanup_dead_vtable_refs(lc); } @@ -243,7 +244,7 @@ void linphone_core_notify_configuring_status(LinphoneCore *lc, LinphoneConfiguri } void linphone_core_notify_network_reachable(LinphoneCore *lc, bool_t reachable) { - L_GET_PRIVATE_FROM_C_OBJECT(lc)->notifyNetworkReachable(!!lc->sip_network_reachable, lc->media_network_reachable); + L_GET_PRIVATE_FROM_C_OBJECT(lc)->notifyNetworkReachable(!!lc->sip_network_reachable, !!lc->media_network_reachable); NOTIFY_IF_EXIST(network_reachable, lc,reachable); cleanup_dead_vtable_refs(lc); } @@ -253,6 +254,11 @@ void linphone_core_notify_notify_received(LinphoneCore *lc, LinphoneEvent *lev, cleanup_dead_vtable_refs(lc); } +void linphone_core_notify_subscribe_received(LinphoneCore *lc, LinphoneEvent *lev, const char *subscribe_event, const LinphoneContent *body) { + NOTIFY_IF_EXIST_INTERNAL(subscribe_received, linphone_event_is_internal(lev), lc, lev, subscribe_event, body); + cleanup_dead_vtable_refs(lc); +} + void linphone_core_notify_subscription_state_changed(LinphoneCore *lc, LinphoneEvent *lev, LinphoneSubscriptionState state) { NOTIFY_IF_EXIST_INTERNAL(subscription_state_changed,linphone_event_is_internal(lev), lc,lev,state); cleanup_dead_vtable_refs(lc); diff --git a/daemon/CMakeLists.txt b/daemon/CMakeLists.txt index c50915234..a104ed5c9 100644 --- a/daemon/CMakeLists.txt +++ b/daemon/CMakeLists.txt @@ -79,6 +79,8 @@ set(DAEMON_SOURCE_FILES commands/msfilter-add-fmtp.h commands/netsim.cc commands/netsim.h + commands/play.cc + commands/play.h commands/play-wav.cc commands/play-wav.h commands/pop-event.cc diff --git a/daemon/commands/play.cc b/daemon/commands/play.cc new file mode 100644 index 000000000..f60ae7198 --- /dev/null +++ b/daemon/commands/play.cc @@ -0,0 +1,233 @@ +/* +play-wav.cc +Copyright (C) 2016 Belledonne Communications, Grenoble, France + +This library is free software; you can redistribute it and/or modify it +under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at +your option) any later version. + +This library 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this library; if not, write to the Free Software Foundation, +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "play.h" +#include "call.h" +#include +using namespace std; +#define VOIDPTR_TO_INT(p) ((int)(intptr_t)(p)) + +void IncallPlayerStartCommand::onEof(LinphonePlayer *player){ + pair *callPlayingData = (pair *)linphone_player_get_user_data(player); + Daemon *app = callPlayingData->second; + int id = callPlayingData->first; + app->callPlayingComplete(id); + delete callPlayingData; + linphone_player_set_user_data(player, NULL); +} + + +IncallPlayerStartCommand::IncallPlayerStartCommand() : + DaemonCommand("incall-player-start", "incall-player-start []", + "Play a WAV audio file or a MKV audio/video file. The played media stream will be sent through \n" + "the RTP session of the given call.\n" + " is the file to be played.\n") { + addExample(new DaemonCommandExample("incall-player-start /usr/local/share/sounds/linphone/hello8000.wav 1", + "Status: Ok\n")); + addExample(new DaemonCommandExample("incall-player-start /usr/local/share/sounds/linphone/hello8000.wav 1", + "Status: Error\n" + "Reason: No call with such id.")); + addExample(new DaemonCommandExample("incall-player-start /usr/local/share/sounds/linphone/hello8000.wav", + "Status: Ok\n")); + addExample(new DaemonCommandExample("incall-player-start /usr/local/share/sounds/linphone/hello8000.wav", + "Status: Error\n" + "Reason: No active call.")); +} + +void IncallPlayerStartCommand::exec(Daemon *app, const string& args) { + LinphoneCall *call = NULL; + int cid; + const MSList *elem; + istringstream ist(args); + string filename; + + ist >> filename; + if (ist.eof() && (filename.length() == 0)) { + app->sendResponse(Response("Missing filename parameter.", Response::Error)); + return; + } + if (ist.fail()) { + app->sendResponse(Response("Incorrect filename parameter.", Response::Error)); + return; + } + + ist >> cid; + if (ist.fail()) { + elem = linphone_core_get_calls(app->getCore()); + if (elem != NULL && elem->next == NULL) { + call = (LinphoneCall*)elem->data; + } + } else { + call = app->findCall(cid); + if (call == NULL) { + app->sendResponse(Response("No call with such id.")); + return; + } + } + if (call == NULL) { + app->sendResponse(Response("No active call.")); + return; + } + LinphonePlayer *p = linphone_call_get_player(call); + + LinphonePlayerCbs *cbs=linphone_player_get_callbacks(p); + + pair *callPlayingData = (pair *)linphone_player_get_user_data(p); + if(callPlayingData) callPlayingData = new pair({ + VOIDPTR_TO_INT(linphone_call_get_user_data(call)), + app + }); + linphone_player_set_user_data(p, callPlayingData); + linphone_player_cbs_set_eof_reached(cbs, onEof); + linphone_player_open(p,filename.c_str()); + linphone_player_start(p); + app->sendResponse(Response()); +} + + +IncallPlayerStopCommand::IncallPlayerStopCommand() : + DaemonCommand("incall-player-stop", "incall-player-stop []","Close the opened file.\n") { + addExample(new DaemonCommandExample("incall-player-stop 1", + "Status: Error\n" + "Reason: No call with such id.")); + addExample(new DaemonCommandExample("incall-player-stop 1", + "Status: Ok\n")); + addExample(new DaemonCommandExample("incall-player-stop", + "Status: Ok\n")); + addExample(new DaemonCommandExample("incall-player-stop", + "Status: Error\n" + "Reason: No active call.")); +} + +void IncallPlayerStopCommand::exec(Daemon *app, const string& args) { + LinphoneCall *call = NULL; + int cid; + const MSList *elem; + istringstream ist(args); + ist >> cid; + if (ist.fail()) { + elem = linphone_core_get_calls(app->getCore()); + if (elem != NULL && elem->next == NULL) { + call = (LinphoneCall*)elem->data; + } + } else { + call = app->findCall(cid); + if (call == NULL) { + app->sendResponse(Response("No call with such id.")); + return; + } + } + if (call == NULL) { + app->sendResponse(Response("No active call.")); + return; + } + + LinphonePlayer *p = linphone_call_get_player(call); + + linphone_player_close(p); + app->sendResponse(Response()); + pair *callPlayingData = (pair *)linphone_player_get_user_data(p); + if(callPlayingData) delete callPlayingData; +} + +IncallPlayerPauseCommand::IncallPlayerPauseCommand() : + DaemonCommand("incall-player-pause", "incall-player-pause []", + "Pause the playing of a file.\n") { + addExample(new DaemonCommandExample("incall-player-pause 1", + "Status: Error\n" + "Reason: No call with such id.")); + addExample(new DaemonCommandExample("incall-player-pause 1", + "Status: Ok\n")); + addExample(new DaemonCommandExample("incall-player-pause", + "Status: Ok\n")); + addExample(new DaemonCommandExample("incall-player-pause", + "Status: Error\n" + "Reason: No active call.")); +} + +void IncallPlayerPauseCommand::exec(Daemon *app, const string& args) { + LinphoneCall *call = NULL; + int cid; + const MSList *elem; + istringstream ist(args); + ist >> cid; + if (ist.fail()) { + elem = linphone_core_get_calls(app->getCore()); + if (elem != NULL && elem->next == NULL) { + call = (LinphoneCall*)elem->data; + } + } else { + call = app->findCall(cid); + if (call == NULL) { + app->sendResponse(Response("No call with such id.")); + return; + } + } + if (call == NULL) { + app->sendResponse(Response("No active call.")); + return; + } + + LinphonePlayer *p = linphone_call_get_player(call); + linphone_player_pause(p); + app->sendResponse(Response()); +} + +IncallPlayerResumeCommand::IncallPlayerResumeCommand() : + DaemonCommand("incall-player-resume", "incall-player-resume []", + "Unpause the playing of a file.\n") { + addExample(new DaemonCommandExample("incall-player-resume 1", + "Status: Error\n" + "Reason: No call with such id.")); + addExample(new DaemonCommandExample("incall-player-resume 1", + "Status: Ok\n")); + addExample(new DaemonCommandExample("incall-player-resume", + "Status: Ok\n")); + addExample(new DaemonCommandExample("incall-player-resume", + "Status: Error\n" + "Reason: No active call.")); +} + +void IncallPlayerResumeCommand::exec(Daemon *app, const string& args) { + LinphoneCall *call = NULL; + int cid; + const MSList *elem; + istringstream ist(args); + ist >> cid; + if (ist.fail()) { + elem = linphone_core_get_calls(app->getCore()); + if (elem != NULL && elem->next == NULL) { + call = (LinphoneCall*)elem->data; + } + } else { + call = app->findCall(cid); + if (call == NULL) { + app->sendResponse(Response("No call with such id.")); + return; + } + } + if (call == NULL) { + app->sendResponse(Response("No active call.")); + return; + } + + LinphonePlayer *p = linphone_call_get_player(call); + linphone_player_start(p); + app->sendResponse(Response()); +} diff --git a/daemon/commands/play.h b/daemon/commands/play.h new file mode 100644 index 000000000..ad746dea8 --- /dev/null +++ b/daemon/commands/play.h @@ -0,0 +1,55 @@ +/* +play-wav.h +Copyright (C) 2016 Belledonne Communications, Grenoble, France + +This library is free software; you can redistribute it and/or modify it +under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at +your option) any later version. + +This library 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this library; if not, write to the Free Software Foundation, +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef LINPHONE_DAEMON_COMMAND_PLAY_H_ +#define LINPHONE_DAEMON_COMMAND_PLAY_H_ + +#include "daemon.h" + +class IncallPlayerStartCommand: public DaemonCommand { +public: + IncallPlayerStartCommand(); + + void exec (Daemon *app, const std::string& args) override; + +private: + static void onEof(LinphonePlayer *player); +}; + +class IncallPlayerStopCommand: public DaemonCommand { +public: + IncallPlayerStopCommand(); + + void exec (Daemon *app, const std::string& args) override; +}; + +class IncallPlayerPauseCommand: public DaemonCommand { +public: + IncallPlayerPauseCommand(); + + void exec (Daemon *app, const std::string& args) override; +}; + +class IncallPlayerResumeCommand: public DaemonCommand { +public: + IncallPlayerResumeCommand(); + + void exec (Daemon *app, const std::string& args) override; +}; +#endif // LINPHONE_DAEMON_COMMAND_PLAY_H_ diff --git a/daemon/commands/register-info.cc b/daemon/commands/register-info.cc index 5b39259e5..da1cb58d7 100644 --- a/daemon/commands/register-info.cc +++ b/daemon/commands/register-info.cc @@ -95,10 +95,10 @@ void RegisterInfoCommand::exec(Daemon *app, const string& args) { int id; try { id = atoi(param.c_str()); - } catch (invalid_argument) { + } catch (invalid_argument&) { app->sendResponse(Response("Invalid ID.", Response::Error)); return; - } catch (out_of_range) { + } catch (out_of_range&) { app->sendResponse(Response("Out of range ID.", Response::Error)); return; } diff --git a/daemon/daemon.cc b/daemon/daemon.cc index 77b769f9d..5e79f3298 100644 --- a/daemon/daemon.cc +++ b/daemon/daemon.cc @@ -79,6 +79,7 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #include "commands/netsim.h" #include "commands/cn.h" #include "commands/version.h" +#include "commands/play.h" #include "private.h" using namespace std; @@ -121,13 +122,18 @@ void *Daemon::iterateThread(void *arg) { } EventResponse::EventResponse(Daemon *daemon, LinphoneCall *call, LinphoneCallState state) { + LinphoneCallLog *callLog = linphone_call_get_call_log(call); + const LinphoneAddress *fromAddr = linphone_call_log_get_from_address(callLog); + char *fromStr = linphone_address_as_string(fromAddr); + ostringstream ostr; - char *remote = linphone_call_get_remote_address_as_string(call); - ostr << "Event-type: call-state-changed\nEvent: " << linphone_call_state_to_string(state) << "\n"; - ostr << "From: " << remote << "\n"; + ostr << "Event-type: call-state-changed" << "\n"; + ostr << "Event: " << linphone_call_state_to_string(state) << "\n"; + ostr << "From: " << fromStr << "\n"; ostr << "Id: " << daemon->updateCallId(call) << "\n"; setBody(ostr.str().c_str()); - ms_free(remote); + + bctbx_free(fromStr); } DtmfResponse::DtmfResponse(Daemon *daemon, LinphoneCall *call, int dtmf) { @@ -214,6 +220,15 @@ AudioStreamStatsResponse::AudioStreamStatsResponse(Daemon* daemon, AudioStream* setBody(ostr.str().c_str()); } +CallPlayingStatsResponse::CallPlayingStatsResponse(Daemon* daemon, int id) { + ostringstream ostr; + + ostr << "Event-type: call-playing-complete\n"; + ostr << "Id: " << id << "\n"; + + setBody(ostr.str().c_str()); +} + PayloadTypeResponse::PayloadTypeResponse(LinphoneCore *core, const PayloadType *payloadType, int index, const string &prefix, bool enabled_status) { ostringstream ostr; if (payloadType != NULL) { @@ -486,6 +501,10 @@ void Daemon::initCommands() { mCommands.push_back(new ConfigSetCommand()); mCommands.push_back(new NetsimCommand()); mCommands.push_back(new CNCommand()); + mCommands.push_back(new IncallPlayerStartCommand()); + mCommands.push_back(new IncallPlayerStopCommand()); + mCommands.push_back(new IncallPlayerPauseCommand()); + mCommands.push_back(new IncallPlayerResumeCommand()); mCommands.sort(compareCommands); } @@ -524,6 +543,10 @@ void Daemon::callStatsUpdated(LinphoneCall *call, const LinphoneCallStats *stats } } +void Daemon::callPlayingComplete(int id) { + mEventQueue.push(new CallPlayingStatsResponse(this, id)); +} + void Daemon::dtmfReceived(LinphoneCall *call, int dtmf) { mEventQueue.push(new DtmfResponse(this, call, dtmf)); } diff --git a/daemon/daemon.h b/daemon/daemon.h index 97591982e..79ae20c1e 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -160,6 +160,11 @@ public: const LinphoneCallStats *stats, bool event); }; +class CallPlayingStatsResponse: public Response { +public: + CallPlayingStatsResponse(Daemon *daemon, int id); +}; + class DtmfResponse: public Response { public: DtmfResponse(Daemon *daemon, LinphoneCall *call, int dtmf); @@ -230,7 +235,7 @@ public: void dumpCommandsHelpHtml(); void enableStatsEvents(bool enabled); void enableLSD(bool enabled); - + void callPlayingComplete(int id); void setAutoVideo( bool enabled ){ mAutoVideo = enabled; } inline bool autoVideo(){ return mAutoVideo; } diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 2e09af5eb..225a6c13e 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -33,7 +33,6 @@ set(ROOT_HEADER_FILES chat.h conference.h contactprovider.h - content.h core_utils.h core.h defs.h @@ -85,10 +84,12 @@ set(C_API_HEADER_FILES c-chat-message.h c-chat-room-cbs.h c-chat-room.h + c-content.h c-dial-plan.h c-event-log.h c-magic-search.h c-participant.h + c-participant-imdn-state.h c-search-result.h c-types.h ) diff --git a/include/linphone/Makefile.am b/include/linphone/Makefile.am index dc9488e0b..56c2c3dda 100644 --- a/include/linphone/Makefile.am +++ b/include/linphone/Makefile.am @@ -14,7 +14,6 @@ linphone_include_HEADERS=\ chat.h \ conference.h \ contactprovider.h \ - content.h \ core.h \ core_utils.h \ defs.h \ diff --git a/include/linphone/account_creator.h b/include/linphone/account_creator.h index d5ef4dc12..3d1a7644b 100644 --- a/include/linphone/account_creator.h +++ b/include/linphone/account_creator.h @@ -33,302 +33,302 @@ extern "C" { /** * Callback to notify a response of server. - * @param[in] creator LinphoneAccountCreator object - * @param[in] status The status of the LinphoneAccountCreator test existence operation that has just finished + * @param[in] creator #LinphoneAccountCreator object + * @param[in] status The status of the #LinphoneAccountCreator test existence operation that has just finished **/ typedef void (*LinphoneAccountCreatorCbsStatusCb)(LinphoneAccountCreator *creator, LinphoneAccountCreatorStatus status, const char* resp); /************************** Start Account Creator data **************************/ /** - * Create a LinphoneAccountCreator and set Linphone Request callbacks. - * @param[in] core The LinphoneCore used for the XML-RPC communication + * Create a #LinphoneAccountCreator and set Linphone Request callbacks. + * @param[in] core The #LinphoneCore used for the XML-RPC communication * @param[in] xmlrpc_url The URL to the XML-RPC server. Must be NON NULL. - * @return The new LinphoneAccountCreator object. + * @return The new #LinphoneAccountCreator object. **/ LINPHONE_PUBLIC LinphoneAccountCreator * linphone_account_creator_new(LinphoneCore *core, const char *xmlrpc_url); /** * Reset the account creator entries like username, password, phone number... - * @param[in] creator LinphoneAccountCreator object + * @param[in] creator #LinphoneAccountCreator object **/ LINPHONE_PUBLIC void linphone_account_creator_reset(LinphoneAccountCreator *creator); /** * Send a request to know the existence of account on server. - * @param[in] creator LinphoneAccountCreator object - * @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise + * @param[in] creator #LinphoneAccountCreator object + * @return #LinphoneAccountCreatorStatusRequestOk if the request has been sent, #LinphoneAccountCreatorStatusRequestFailed otherwise **/ LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_is_account_exist(LinphoneAccountCreator *creator); /** * Send a request to create an account on server. - * @param[in] creator LinphoneAccountCreator object - * @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise + * @param[in] creator #LinphoneAccountCreator object + * @return #LinphoneAccountCreatorStatusRequestOk if the request has been sent, #LinphoneAccountCreatorStatusRequestFailed otherwise **/ LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_create_account(LinphoneAccountCreator *creator); /** * Send a request to know if an account is activated on server. - * @param[in] creator LinphoneAccountCreator object - * @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise + * @param[in] creator #LinphoneAccountCreator object + * @return #LinphoneAccountCreatorStatusRequestOk if the request has been sent, #LinphoneAccountCreatorStatusRequestFailed otherwise **/ LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_is_account_activated(LinphoneAccountCreator *creator); /** * Send a request to activate an account on server. - * @param[in] creator LinphoneAccountCreator object - * @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise + * @param[in] creator #LinphoneAccountCreator object + * @return #LinphoneAccountCreatorStatusRequestOk if the request has been sent, #LinphoneAccountCreatorStatusRequestFailed otherwise **/ LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_activate_account(LinphoneAccountCreator *creator); /** * Send a request to link an account to an alias. - * @param[in] creator LinphoneAccountCreator object - * @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise + * @param[in] creator #LinphoneAccountCreator object + * @return #LinphoneAccountCreatorStatusRequestOk if the request has been sent, #LinphoneAccountCreatorStatusRequestFailed otherwise **/ LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_link_account(LinphoneAccountCreator *creator); /** * Send a request to activate an alias. - * @param[in] creator LinphoneAccountCreator object - * @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise + * @param[in] creator #LinphoneAccountCreator object + * @return #LinphoneAccountCreatorStatusRequestOk if the request has been sent, #LinphoneAccountCreatorStatusRequestFailed otherwise **/ LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_activate_alias(LinphoneAccountCreator *creator); /** * Send a request to know if an alias is used. - * @param[in] creator LinphoneAccountCreator object - * @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise + * @param[in] creator #LinphoneAccountCreator object + * @return #LinphoneAccountCreatorStatusRequestOk if the request has been sent, #LinphoneAccountCreatorStatusRequestFailed otherwise **/ LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_is_alias_used(LinphoneAccountCreator *creator); /** * Send a request to know if an account is linked. - * @param[in] creator LinphoneAccountCreator object - * @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise + * @param[in] creator #LinphoneAccountCreator object + * @return #LinphoneAccountCreatorStatusRequestOk if the request has been sent, #LinphoneAccountCreatorStatusRequestFailed otherwise **/ LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_is_account_linked(LinphoneAccountCreator *creator); /** * Send a request to recover an account. - * @param[in] creator LinphoneAccountCreator object - * @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise + * @param[in] creator #LinphoneAccountCreator object + * @return #LinphoneAccountCreatorStatusRequestOk if the request has been sent, #LinphoneAccountCreatorStatusRequestFailed otherwise **/ LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_recover_account(LinphoneAccountCreator *creator); /** * Send a request to update an account. - * @param[in] creator LinphoneAccountCreator object - * @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise + * @param[in] creator #LinphoneAccountCreator object + * @return #LinphoneAccountCreatorStatusRequestOk if the request has been sent, #LinphoneAccountCreatorStatusRequestFailed otherwise **/ LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_update_account(LinphoneAccountCreator *creator); /** * Acquire a reference to the LinphoneAccountCreator. - * @param[in] creator LinphoneAccountCreator object. - * @return The same LinphoneAccountCreator object. + * @param[in] creator #LinphoneAccountCreator object. + * @return The same #LinphoneAccountCreator object. **/ LINPHONE_PUBLIC LinphoneAccountCreator * linphone_account_creator_ref(LinphoneAccountCreator *creator); /** * Release reference to the LinphoneAccountCreator. - * @param[in] creator LinphoneAccountCreator object. + * @param[in] creator #LinphoneAccountCreator object. **/ LINPHONE_PUBLIC void linphone_account_creator_unref(LinphoneAccountCreator *creator); /** * Retrieve the user pointer associated with the LinphoneAccountCreator. - * @param[in] creator LinphoneAccountCreator object. + * @param[in] creator #LinphoneAccountCreator object. * @return The user pointer associated with the LinphoneAccountCreator. **/ LINPHONE_PUBLIC void *linphone_account_creator_get_user_data(const LinphoneAccountCreator *creator); /** * Assign a user pointer to the LinphoneAccountCreator. - * @param[in] creator LinphoneAccountCreator object. + * @param[in] creator #LinphoneAccountCreator object. * @param[in] ud The user pointer to associate with the LinphoneAccountCreator. **/ LINPHONE_PUBLIC void linphone_account_creator_set_user_data(LinphoneAccountCreator *creator, void *ud); /** * Set the username. - * @param[in] creator LinphoneAccountCreator object + * @param[in] creator #LinphoneAccountCreator object * @param[in] username The username to set - * @return LinphoneAccountCreatorUsernameStatusOk if everything is OK, or a specific error otherwise. + * @return #LinphoneAccountCreatorUsernameStatusOk if everything is OK, or a specific error otherwise. **/ LINPHONE_PUBLIC LinphoneAccountCreatorUsernameStatus linphone_account_creator_set_username(LinphoneAccountCreator *creator, const char *username); /** * Get the username. - * @param[in] creator LinphoneAccountCreator object - * @return The username of the LinphoneAccountCreator + * @param[in] creator #LinphoneAccountCreator object + * @return The username of the #LinphoneAccountCreator **/ LINPHONE_PUBLIC const char * linphone_account_creator_get_username(const LinphoneAccountCreator *creator); /** * Set the phone number normalized. - * @param[in] creator LinphoneAccountCreator object + * @param[in] creator #LinphoneAccountCreator object * @param[in] phone_number The phone number to set * @param[in] country_code Country code to associate phone number with - * @return LinphoneAccountCreatorPhoneNumberStatusOk if everything is OK, or specific(s) error(s) otherwise. + * @return #LinphoneAccountCreatorPhoneNumberStatusOk if everything is OK, or specific(s) error(s) otherwise. **/ LINPHONE_PUBLIC LinphoneAccountCreatorPhoneNumberStatusMask linphone_account_creator_set_phone_number(LinphoneAccountCreator *creator, const char *phone_number, const char *country_code); /** * Get the RFC 3966 normalized phone number. - * @param[in] creator LinphoneAccountCreator object - * @return The phone number of the LinphoneAccountCreator + * @param[in] creator #LinphoneAccountCreator object + * @return The phone number of the #LinphoneAccountCreator **/ LINPHONE_PUBLIC const char * linphone_account_creator_get_phone_number(const LinphoneAccountCreator *creator); /** * Set the password. - * @param[in] creator LinphoneAccountCreator object + * @param[in] creator #LinphoneAccountCreator object * @param[in] password The password to set - * @return LinphoneAccountCreatorPasswordStatusOk if everything is OK, or specific(s) error(s) otherwise. + * @return #LinphoneAccountCreatorPasswordStatusOk if everything is OK, or specific(s) error(s) otherwise. **/ LINPHONE_PUBLIC LinphoneAccountCreatorPasswordStatus linphone_account_creator_set_password(LinphoneAccountCreator *creator, const char *password); /** * Get the password. - * @param[in] creator LinphoneAccountCreator object - * @return The password of the LinphoneAccountCreator + * @param[in] creator #LinphoneAccountCreator object + * @return The password of the #LinphoneAccountCreator **/ LINPHONE_PUBLIC const char * linphone_account_creator_get_password(const LinphoneAccountCreator *creator); /** * Set the ha1. - * @param[in] creator LinphoneAccountCreator object + * @param[in] creator #LinphoneAccountCreator object * @param[in] ha1 The ha1 to set - * @return LinphoneAccountCreatorPasswordStatusOk if everything is OK, or a specific error otherwise. + * @return #LinphoneAccountCreatorPasswordStatusOk if everything is OK, or a specific error otherwise. **/ LINPHONE_PUBLIC LinphoneAccountCreatorPasswordStatus linphone_account_creator_set_ha1(LinphoneAccountCreator *creator, const char *ha1); /** * Get the ha1. - * @param[in] creator LinphoneAccountCreator object - * @return The ha1 of the LinphoneAccountCreator + * @param[in] creator #LinphoneAccountCreator object + * @return The ha1 of the #LinphoneAccountCreator **/ LINPHONE_PUBLIC const char * linphone_account_creator_get_ha1(const LinphoneAccountCreator *creator); /** * Set the activation code. - * @param[in] creator LinphoneAccountCreator object + * @param[in] creator #LinphoneAccountCreator object * @param[in] activation_code The activation code to set - * @return LinphoneAccountCreatorActivationCodeStatusOk if everything is OK, or a specific error otherwise. + * @return #LinphoneAccountCreatorActivationCodeStatusOk if everything is OK, or a specific error otherwise. **/ LINPHONE_PUBLIC LinphoneAccountCreatorActivationCodeStatus linphone_account_creator_set_activation_code(LinphoneAccountCreator *creator, const char *activation_code); /** * Get the activation code. - * @param[in] creator LinphoneAccountCreator object - * @return The activation code of the LinphoneAccountCreator + * @param[in] creator #LinphoneAccountCreator object + * @return The activation code of the #LinphoneAccountCreator **/ LINPHONE_PUBLIC const char * linphone_account_creator_get_activation_code(const LinphoneAccountCreator *creator); /** * Set the language to use in email or SMS if supported. - * @param[in] creator LinphoneAccountCreator object + * @param[in] creator #LinphoneAccountCreator object * @param[in] lang The language to use - * @return LinphoneAccountCreatorLanguageStatusOk if everything is OK, or a specific error otherwise. + * @return #LinphoneAccountCreatorLanguageStatusOk if everything is OK, or a specific error otherwise. **/ LINPHONE_PUBLIC LinphoneAccountCreatorLanguageStatus linphone_account_creator_set_language(LinphoneAccountCreator *creator, const char *lang); /** * Get the language use in email of SMS. - * @param[in] creator LinphoneAccountCreator object - * @return The language of the LinphoneAccountCreator + * @param[in] creator #LinphoneAccountCreator object + * @return The language of the #LinphoneAccountCreator **/ LINPHONE_PUBLIC const char * linphone_account_creator_get_language(const LinphoneAccountCreator *creator); /** * Set the display name. - * @param[in] creator LinphoneAccountCreator object + * @param[in] creator #LinphoneAccountCreator object * @param[in] display_name The display name to set - * @return LinphoneAccountCreatorUsernameStatusOk if everything is OK, or a specific error otherwise. + * @return #LinphoneAccountCreatorUsernameStatusOk if everything is OK, or a specific error otherwise. **/ LINPHONE_PUBLIC LinphoneAccountCreatorUsernameStatus linphone_account_creator_set_display_name(LinphoneAccountCreator *creator, const char *display_name); /** * Get the display name. - * @param[in] creator LinphoneAccountCreator object - * @return The display name of the LinphoneAccountCreator + * @param[in] creator #LinphoneAccountCreator object + * @return The display name of the #LinphoneAccountCreator **/ LINPHONE_PUBLIC const char * linphone_account_creator_get_display_name(const LinphoneAccountCreator *creator); /** * Set the email. - * @param[in] creator LinphoneAccountCreator object + * @param[in] creator #LinphoneAccountCreator object * @param[in] email The email to set - * @return LinphoneAccountCreatorEmailStatusOk if everything is OK, or a specific error otherwise. + * @return #LinphoneAccountCreatorEmailStatusOk if everything is OK, or a specific error otherwise. **/ LINPHONE_PUBLIC LinphoneAccountCreatorEmailStatus linphone_account_creator_set_email(LinphoneAccountCreator *creator, const char *email); /** * Get the email. - * @param[in] creator LinphoneAccountCreator object - * @return The email of the LinphoneAccountCreator + * @param[in] creator #LinphoneAccountCreator object + * @return The email of the #LinphoneAccountCreator **/ LINPHONE_PUBLIC const char * linphone_account_creator_get_email(const LinphoneAccountCreator *creator); /** * Set the domain. - * @param[in] creator LinphoneAccountCreator object + * @param[in] creator #LinphoneAccountCreator object * @param[in] domain The domain to set - * @return LinphoneAccountCreatorDomainOk if everything is OK, or a specific error otherwise. + * @return #LinphoneAccountCreatorDomainOk if everything is OK, or a specific error otherwise. **/ LINPHONE_PUBLIC LinphoneAccountCreatorDomainStatus linphone_account_creator_set_domain(LinphoneAccountCreator *creator, const char *domain); /** * Get the domain. - * @param[in] creator LinphoneAccountCreator object - * @return The domain of the LinphoneAccountCreator + * @param[in] creator #LinphoneAccountCreator object + * @return The domain of the #LinphoneAccountCreator **/ LINPHONE_PUBLIC const char * linphone_account_creator_get_domain(const LinphoneAccountCreator *creator); /** * Set Transport - * @param[in] creator LinphoneAccountCreator object + * @param[in] creator #LinphoneAccountCreator object * @param[in] transport The transport to set - * @return LinphoneAccountCreatorTransportOk if everything is OK, or a specific error otherwise. + * @return #LinphoneAccountCreatorTransportOk if everything is OK, or a specific error otherwise. **/ LINPHONE_PUBLIC LinphoneAccountCreatorTransportStatus linphone_account_creator_set_transport(LinphoneAccountCreator *creator, LinphoneTransportType transport); /** * get Transport - * @param[in] creator LinphoneAccountCreator object - * @return The transport of LinphoneAccountCreator + * @param[in] creator #LinphoneAccountCreator object + * @return The transport of #LinphoneAccountCreator **/ LINPHONE_PUBLIC LinphoneTransportType linphone_account_creator_get_transport(const LinphoneAccountCreator *creator); /** * Set the route. - * @param[in] creator LinphoneAccountCreator object + * @param[in] creator #LinphoneAccountCreator object * @param[in] route The route to set - * @return LinphoneAccountCreatorStatusRequestOk if everything is OK, or a specific error otherwise. + * @return #LinphoneAccountCreatorStatusRequestOk if everything is OK, or a specific error otherwise. **/ LINPHONE_DEPRECATED LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_set_route(LinphoneAccountCreator *creator, const char *route); /** * Get the route. - * @param[in] creator LinphoneAccountCreator object - * @return The route of the LinphoneAccountCreator + * @param[in] creator #LinphoneAccountCreator object + * @return The route of the #LinphoneAccountCreator **/ LINPHONE_DEPRECATED LINPHONE_PUBLIC const char * linphone_account_creator_get_route(const LinphoneAccountCreator *creator); /** - * Get the LinphoneAccountCreatorCbs object associated with a LinphoneAccountCreator. - * @param[in] creator LinphoneAccountCreator object - * @return The LinphoneAccountCreatorCbs object associated with the LinphoneAccountCreator. + * Get the #LinphoneAccountCreatorCbs object associated with a LinphoneAccountCreator. + * @param[in] creator #LinphoneAccountCreator object + * @return The #LinphoneAccountCreatorCbs object associated with the LinphoneAccountCreator. **/ LINPHONE_PUBLIC LinphoneAccountCreatorCbs * linphone_account_creator_get_callbacks(const LinphoneAccountCreator *creator); /** - * Get the LinphoneAccountCreatorService object associated with a LinphoneAccountCreator. - * @param[in] creator LinphoneAccountCreator object - * @return The LinphoneAccountCreatorService object associated with the LinphoneAccountCreator. + * Get the #LinphoneAccountCreatorService object associated with a LinphoneAccountCreator. + * @param[in] creator #LinphoneAccountCreator object + * @return The #LinphoneAccountCreatorService object associated with the LinphoneAccountCreator. * @donotwrap **/ LINPHONE_PUBLIC LinphoneAccountCreatorService * linphone_account_creator_get_service(const LinphoneAccountCreator *creator); @@ -338,168 +338,168 @@ LINPHONE_PUBLIC LinphoneAccountCreatorService * linphone_account_creator_get_ser /************************** Start Account Creator Cbs **************************/ /** - * Acquire a reference to a LinphoneAccountCreatorCbs object. - * @param[in] cbs LinphoneAccountCreatorCbs object. - * @return The same LinphoneAccountCreatorCbs object. + * Acquire a reference to a #LinphoneAccountCreatorCbs object. + * @param[in] cbs #LinphoneAccountCreatorCbs object. + * @return The same #LinphoneAccountCreatorCbs object. **/ LINPHONE_PUBLIC LinphoneAccountCreatorCbs * linphone_account_creator_cbs_ref(LinphoneAccountCreatorCbs *cbs); /** - * Release a reference to a LinphoneAccountCreatorCbs object. - * @param[in] cbs LinphoneAccountCreatorCbs object. + * Release a reference to a #LinphoneAccountCreatorCbs object. + * @param[in] cbs #LinphoneAccountCreatorCbs object. **/ LINPHONE_PUBLIC void linphone_account_creator_cbs_unref(LinphoneAccountCreatorCbs *cbs); /** - * Retrieve the user pointer associated with a LinphoneAccountCreatorCbs object. - * @param[in] cbs LinphoneAccountCreatorCbs object. - * @return The user pointer associated with the LinphoneAccountCreatorCbs object. + * Retrieve the user pointer associated with a #LinphoneAccountCreatorCbs object. + * @param[in] cbs #LinphoneAccountCreatorCbs object. + * @return The user pointer associated with the #LinphoneAccountCreatorCbs object. **/ LINPHONE_PUBLIC void *linphone_account_creator_cbs_get_user_data(const LinphoneAccountCreatorCbs *cbs); /** - * Assign a user pointer to a LinphoneAccountCreatorCbs object. - * @param[in] cbs LinphoneAccountCreatorCbs object. - * @param[in] ud The user pointer to associate with the LinphoneAccountCreatorCbs object. + * Assign a user pointer to a #LinphoneAccountCreatorCbs object. + * @param[in] cbs #LinphoneAccountCreatorCbs object. + * @param[in] ud The user pointer to associate with the #LinphoneAccountCreatorCbs object. **/ LINPHONE_PUBLIC void linphone_account_creator_cbs_set_user_data(LinphoneAccountCreatorCbs *cbs, void *ud); /** * Get the create account request. - * @param[in] cbs LinphoneAccountCreatorCbs object. + * @param[in] cbs #LinphoneAccountCreatorCbs object. * @return The current create account request. **/ LINPHONE_PUBLIC LinphoneAccountCreatorCbsStatusCb linphone_account_creator_cbs_get_create_account(const LinphoneAccountCreatorCbs *cbs); /** - * Assign a user pointer to a LinphoneAccountCreatorCbs object. - * @param[in] cbs LinphoneAccountCreatorCbs object. + * Assign a user pointer to a #LinphoneAccountCreatorCbs object. + * @param[in] cbs #LinphoneAccountCreatorCbs object. * @param[in] cb The create account request to be used. **/ LINPHONE_PUBLIC void linphone_account_creator_cbs_set_create_account(LinphoneAccountCreatorCbs *cbs, LinphoneAccountCreatorCbsStatusCb cb); /** * Get the is account exist request. - * @param[in] cbs LinphoneAccountCreatorCbs object. + * @param[in] cbs #LinphoneAccountCreatorCbs object. * @return The current is account exist request. **/ LINPHONE_PUBLIC LinphoneAccountCreatorCbsStatusCb linphone_account_creator_cbs_get_is_account_exist(const LinphoneAccountCreatorCbs *cbs); /** - * Assign a user pointer to a LinphoneAccountCreatorCbs object. - * @param[in] cbs LinphoneAccountCreatorCbs object. + * Assign a user pointer to a #LinphoneAccountCreatorCbs object. + * @param[in] cbs #LinphoneAccountCreatorCbs object. * @param[in] cb The is account exist request to be used. **/ LINPHONE_PUBLIC void linphone_account_creator_cbs_set_is_account_exist(LinphoneAccountCreatorCbs *cbs, LinphoneAccountCreatorCbsStatusCb cb); /** * Get the activate account request. - * @param[in] cbs LinphoneAccountCreatorCbs object. + * @param[in] cbs #LinphoneAccountCreatorCbs object. * @return The current activate account request. **/ LINPHONE_PUBLIC LinphoneAccountCreatorCbsStatusCb linphone_account_creator_cbs_get_activate_account(const LinphoneAccountCreatorCbs *cbs); /** - * Assign a user pointer to a LinphoneAccountCreatorCbs object. - * @param[in] cbs LinphoneAccountCreatorCbs object. + * Assign a user pointer to a #LinphoneAccountCreatorCbs object. + * @param[in] cbs #LinphoneAccountCreatorCbs object. * @param[in] cb The activate account request to be used. **/ LINPHONE_PUBLIC void linphone_account_creator_cbs_set_activate_account(LinphoneAccountCreatorCbs *cbs, LinphoneAccountCreatorCbsStatusCb cb); /** * Get the is account activated request. - * @param[in] cbs LinphoneAccountCreatorCbs object. + * @param[in] cbs #LinphoneAccountCreatorCbs object. * @return The current is account activated request. **/ LINPHONE_PUBLIC LinphoneAccountCreatorCbsStatusCb linphone_account_creator_cbs_get_is_account_activated(const LinphoneAccountCreatorCbs *cbs); /** - * Assign a user pointer to a LinphoneAccountCreatorCbs object. - * @param[in] cbs LinphoneAccountCreatorCbs object. + * Assign a user pointer to a #LinphoneAccountCreatorCbs object. + * @param[in] cbs #LinphoneAccountCreatorCbs object. * @param[in] cb The is account activated request to be used. **/ LINPHONE_PUBLIC void linphone_account_creator_cbs_set_is_account_activated(LinphoneAccountCreatorCbs *cbs, LinphoneAccountCreatorCbsStatusCb cb); /** * Get the link account request. - * @param[in] cbs LinphoneAccountCreatorCbs object. + * @param[in] cbs #LinphoneAccountCreatorCbs object. * @return The current link account request. **/ LINPHONE_PUBLIC LinphoneAccountCreatorCbsStatusCb linphone_account_creator_cbs_get_link_account(const LinphoneAccountCreatorCbs *cbs); /** - * Assign a user pointer to a LinphoneAccountCreatorCbs object. - * @param[in] cbs LinphoneAccountCreatorCbs object. + * Assign a user pointer to a #LinphoneAccountCreatorCbs object. + * @param[in] cbs #LinphoneAccountCreatorCbs object. * @param[in] cb The link account request to be used. **/ LINPHONE_PUBLIC void linphone_account_creator_cbs_set_link_account(LinphoneAccountCreatorCbs *cbs, LinphoneAccountCreatorCbsStatusCb cb); /** * Get the activate alias request. - * @param[in] cbs LinphoneAccountCreatorCbs object. + * @param[in] cbs #LinphoneAccountCreatorCbs object. * @return The current link account request. **/ LINPHONE_PUBLIC LinphoneAccountCreatorCbsStatusCb linphone_account_creator_cbs_get_activate_alias(const LinphoneAccountCreatorCbs *cbs); /** - * Assign a user pointer to a LinphoneAccountCreatorCbs object. - * @param[in] cbs LinphoneAccountCreatorCbs object. + * Assign a user pointer to a #LinphoneAccountCreatorCbs object. + * @param[in] cbs #LinphoneAccountCreatorCbs object. * @param[in] cb The activate alias request to be used. **/ LINPHONE_PUBLIC void linphone_account_creator_cbs_set_activate_alias(LinphoneAccountCreatorCbs *cbs, LinphoneAccountCreatorCbsStatusCb cb); /** * Get the is alias used request. - * @param[in] cbs LinphoneAccountCreatorCbs object. + * @param[in] cbs #LinphoneAccountCreatorCbs object. * @return The current is alias used request. **/ LINPHONE_PUBLIC LinphoneAccountCreatorCbsStatusCb linphone_account_creator_cbs_get_is_alias_used(const LinphoneAccountCreatorCbs *cbs); /** - * Assign a user pointer to a LinphoneAccountCreatorCbs object. - * @param[in] cbs LinphoneAccountCreatorCbs object. + * Assign a user pointer to a #LinphoneAccountCreatorCbs object. + * @param[in] cbs #LinphoneAccountCreatorCbs object. * @param[in] cb The is alias used request to be used. **/ LINPHONE_PUBLIC void linphone_account_creator_cbs_set_is_alias_used(LinphoneAccountCreatorCbs *cbs, LinphoneAccountCreatorCbsStatusCb cb); /** * Get the is account linked request. - * @param[in] cbs LinphoneAccountCreatorCbs object. + * @param[in] cbs #LinphoneAccountCreatorCbs object. * @return The current is account linked request. **/ LINPHONE_PUBLIC LinphoneAccountCreatorCbsStatusCb linphone_account_creator_cbs_get_is_account_linked(const LinphoneAccountCreatorCbs *cbs); /** - * Assign a user pointer to a LinphoneAccountCreatorCbs object. - * @param[in] cbs LinphoneAccountCreatorCbs object. + * Assign a user pointer to a #LinphoneAccountCreatorCbs object. + * @param[in] cbs #LinphoneAccountCreatorCbs object. * @param[in] cb The is account linked request to be used. **/ LINPHONE_PUBLIC void linphone_account_creator_cbs_set_is_account_linked(LinphoneAccountCreatorCbs *cbs, LinphoneAccountCreatorCbsStatusCb cb); /** * Get the recover account request. - * @param[in] cbs LinphoneAccountCreatorCbs object. + * @param[in] cbs #LinphoneAccountCreatorCbs object. * @return The current recover account request. **/ LINPHONE_PUBLIC LinphoneAccountCreatorCbsStatusCb linphone_account_creator_cbs_get_recover_account(const LinphoneAccountCreatorCbs *cbs); /** - * Assign a user pointer to a LinphoneAccountCreatorCbs object. - * @param[in] cbs LinphoneAccountCreatorCbs object. + * Assign a user pointer to a #LinphoneAccountCreatorCbs object. + * @param[in] cbs #LinphoneAccountCreatorCbs object. * @param[in] cb The recover account request to be used. **/ LINPHONE_PUBLIC void linphone_account_creator_cbs_set_recover_account(LinphoneAccountCreatorCbs *cbs, LinphoneAccountCreatorCbsStatusCb cb); /** * Get the update account request. - * @param[in] cbs LinphoneAccountCreatorCbs object. + * @param[in] cbs #LinphoneAccountCreatorCbs object. * @return The current update account request. **/ LINPHONE_PUBLIC LinphoneAccountCreatorCbsStatusCb linphone_account_creator_cbs_get_update_account(const LinphoneAccountCreatorCbs *cbs); /** - * Assign a user pointer to a LinphoneAccountCreatorCbs object. - * @param[in] cbs LinphoneAccountCreatorCbs object. + * Assign a user pointer to a #LinphoneAccountCreatorCbs object. + * @param[in] cbs #LinphoneAccountCreatorCbs object. * @param[in] cb The update account request to be used. **/ LINPHONE_PUBLIC void linphone_account_creator_cbs_set_update_account(LinphoneAccountCreatorCbs *cbs, LinphoneAccountCreatorCbsStatusCb cb); @@ -508,15 +508,15 @@ LINPHONE_PUBLIC void linphone_account_creator_cbs_set_update_account(LinphoneAcc /** * Create and configure a proxy config and a authentication info for an account creator - * @param[in] creator LinphoneAccountCreator object - * @return A LinphoneProxyConfig object if successful, NULL otherwise + * @param[in] creator #LinphoneAccountCreator object + * @return A #LinphoneProxyConfig object if successful, NULL otherwise **/ LINPHONE_PUBLIC LinphoneProxyConfig * linphone_account_creator_create_proxy_config(const LinphoneAccountCreator *creator); /** * Configure an account (create a proxy config and authentication info for it). - * @param[in] creator LinphoneAccountCreator object - * @return A LinphoneProxyConfig object if successful, NULL otherwise + * @param[in] creator #LinphoneAccountCreator object + * @return A #LinphoneProxyConfig object if successful, NULL otherwise **/ LINPHONE_DEPRECATED LINPHONE_PUBLIC LinphoneProxyConfig * linphone_account_creator_configure(const LinphoneAccountCreator *creator); diff --git a/include/linphone/account_creator_service.h b/include/linphone/account_creator_service.h index 1896dee92..f21650088 100644 --- a/include/linphone/account_creator_service.h +++ b/include/linphone/account_creator_service.h @@ -28,7 +28,7 @@ extern "C" { /** * Function to set custom server request. - * @param[in] creator LinphoneAccountCreator object + * @param[in] creator #LinphoneAccountCreator object */ typedef LinphoneAccountCreatorStatus (*LinphoneAccountCreatorRequestFunc)(LinphoneAccountCreator *creator); @@ -40,46 +40,46 @@ typedef LinphoneAccountCreatorStatus (*LinphoneAccountCreatorRequestFunc)(Linpho /************************** Start Account Creator Requests **************************/ /** - * Create a new LinphoneAccountCreatorService object. - * @return a new LinphoneAccountCreatorService object. + * Create a new #LinphoneAccountCreatorService object. + * @return a new #LinphoneAccountCreatorService object. * @donotwrap **/ LINPHONE_PUBLIC LinphoneAccountCreatorService * linphone_account_creator_service_new(void); /** - * Acquire a reference to a LinphoneAccountCreatorService object. - * @param[in] service LinphoneAccountCreatorService object. - * @return The same LinphoneAccountCreatorService object. + * Acquire a reference to a #LinphoneAccountCreatorService object. + * @param[in] service #LinphoneAccountCreatorService object. + * @return The same #LinphoneAccountCreatorService object. * @donotwrap **/ LinphoneAccountCreatorService * linphone_account_creator_service_ref(LinphoneAccountCreatorService *service); /** - * Release a reference to a LinphoneAccountCreatorService object. - * @param[in] service LinphoneAccountCreatorService object. + * Release a reference to a #LinphoneAccountCreatorService object. + * @param[in] service #LinphoneAccountCreatorService object. * @donotwrap **/ void linphone_account_creator_service_unref(LinphoneAccountCreatorService *service); /** - * Retrieve the user pointer associated with a LinphoneAccountCreatorService object. - * @param[in] service LinphoneAccountCreatorService object. - * @return The user pointer associated with the LinphoneAccountCreatorService object. + * Retrieve the user pointer associated with a #LinphoneAccountCreatorService object. + * @param[in] service #LinphoneAccountCreatorService object. + * @return The user pointer associated with the #LinphoneAccountCreatorService object. * @donotwrap **/ LINPHONE_PUBLIC void *linphone_account_creator_service_get_user_data(const LinphoneAccountCreatorService *service); /** - * Assign a user pointer to a LinphoneAccountCreatorService object. - * @param[in] service LinphoneAccountCreatorService object. - * @param[in] ud The user pointer to associate with the LinphoneAccountCreatorService object. + * Assign a user pointer to a #LinphoneAccountCreatorService object. + * @param[in] service #LinphoneAccountCreatorService object. + * @param[in] ud The user pointer to associate with the #LinphoneAccountCreatorService object. * @donotwrap **/ LINPHONE_PUBLIC void linphone_account_creator_service_set_user_data(LinphoneAccountCreatorService *service, void *ud); /** - * Assign a user pointer to a LinphoneAccountCreatorService object. - * @param[in] service LinphoneAccountCreatorService object. + * Assign a user pointer to a #LinphoneAccountCreatorService object. + * @param[in] service #LinphoneAccountCreatorService object. * @param[in] cb The constructor of account creator requests. * @donotwrap **/ @@ -87,15 +87,15 @@ LINPHONE_PUBLIC void linphone_account_creator_service_set_constructor_cb(Linphon /** * Get the constructor of account creator requests. - * @param[in] service LinphoneAccountCreatorService object. + * @param[in] service #LinphoneAccountCreatorService object. * @return The current constructor of create account request. * @donotwrap **/ LINPHONE_PUBLIC LinphoneAccountCreatorRequestFunc linphone_account_creator_service_get_constructor_cb(const LinphoneAccountCreatorService *service); /** - * Assign a user pointer to a LinphoneAccountCreatorService object. - * @param[in] service LinphoneAccountCreatorService object. + * Assign a user pointer to a #LinphoneAccountCreatorService object. + * @param[in] service #LinphoneAccountCreatorService object. * @param[in] cb The destructor. * @donotwrap **/ @@ -103,7 +103,7 @@ LINPHONE_PUBLIC void linphone_account_creator_service_set_destructor_cb(Linphone /** * Get the destructor of create account request. - * @param[in] service LinphoneAccountCreatorService object. + * @param[in] service #LinphoneAccountCreatorService object. * @return The current destructor of create account request. * @donotwrap **/ @@ -111,15 +111,15 @@ LINPHONE_PUBLIC LinphoneAccountCreatorRequestFunc linphone_account_creator_servi /** * Get the create account request. - * @param[in] service LinphoneAccountCreatorService object. + * @param[in] service #LinphoneAccountCreatorService object. * @return The current create account request. * @donotwrap **/ LINPHONE_PUBLIC LinphoneAccountCreatorRequestFunc linphone_account_creator_service_get_create_account_cb(const LinphoneAccountCreatorService *service); /** - * Assign a user pointer to a LinphoneAccountCreatorService object. - * @param[in] service LinphoneAccountCreatorService object. + * Assign a user pointer to a #LinphoneAccountCreatorService object. + * @param[in] service #LinphoneAccountCreatorService object. * @param[in] cb The create account request to be used. * @donotwrap **/ @@ -127,15 +127,15 @@ LINPHONE_PUBLIC void linphone_account_creator_service_set_create_account_cb(Linp /** * Get the is account exist request. - * @param[in] service LinphoneAccountCreatorService object. + * @param[in] service #LinphoneAccountCreatorService object. * @return The current is account exist request. * @donotwrap **/ LINPHONE_PUBLIC LinphoneAccountCreatorRequestFunc linphone_account_creator_service_get_is_account_exist_cb(const LinphoneAccountCreatorService *service); /** - * Assign a user pointer to a LinphoneAccountCreatorService object. - * @param[in] service LinphoneAccountCreatorService object. + * Assign a user pointer to a #LinphoneAccountCreatorService object. + * @param[in] service #LinphoneAccountCreatorService object. * @param[in] cb The is account exist request to be used. * @donotwrap **/ @@ -143,15 +143,15 @@ LINPHONE_PUBLIC void linphone_account_creator_service_set_is_account_exist_cb(Li /** * Get the activate account request. - * @param[in] service LinphoneAccountCreatorService object. + * @param[in] service #LinphoneAccountCreatorService object. * @return The current activate account request. * @donotwrap **/ LINPHONE_PUBLIC LinphoneAccountCreatorRequestFunc linphone_account_creator_service_get_activate_account_cb(const LinphoneAccountCreatorService *service); /** - * Assign a user pointer to a LinphoneAccountCreatorService object. - * @param[in] service LinphoneAccountCreatorService object. + * Assign a user pointer to a #LinphoneAccountCreatorService object. + * @param[in] service #LinphoneAccountCreatorService object. * @param[in] cb The activate account request to be used. * @donotwrap **/ @@ -159,15 +159,15 @@ LINPHONE_PUBLIC void linphone_account_creator_service_set_activate_account_cb(Li /** * Get the is account activated request. - * @param[in] service LinphoneAccountCreatorService object. + * @param[in] service #LinphoneAccountCreatorService object. * @return The current is account activated request. * @donotwrap **/ LINPHONE_PUBLIC LinphoneAccountCreatorRequestFunc linphone_account_creator_service_get_is_account_activated_cb(const LinphoneAccountCreatorService *service); /** - * Assign a user pointer to a LinphoneAccountCreatorService object. - * @param[in] service LinphoneAccountCreatorService object. + * Assign a user pointer to a #LinphoneAccountCreatorService object. + * @param[in] service #LinphoneAccountCreatorService object. * @param[in] cb The is account activated request to be used. * @donotwrap **/ @@ -175,15 +175,15 @@ LINPHONE_PUBLIC void linphone_account_creator_service_set_is_account_activated_c /** * Get the link account request. - * @param[in] service LinphoneAccountCreatorService object. + * @param[in] service #LinphoneAccountCreatorService object. * @return The current link account request. * @donotwrap **/ LINPHONE_PUBLIC LinphoneAccountCreatorRequestFunc linphone_account_creator_service_get_link_account_cb(const LinphoneAccountCreatorService *service); /** - * Assign a user pointer to a LinphoneAccountCreatorService object. - * @param[in] service LinphoneAccountCreatorService object. + * Assign a user pointer to a #LinphoneAccountCreatorService object. + * @param[in] service #LinphoneAccountCreatorService object. * @param[in] cb The link account request to be used. * @donotwrap **/ @@ -191,15 +191,15 @@ LINPHONE_PUBLIC void linphone_account_creator_service_set_link_account_cb(Linpho /** * Get the activate alias request. - * @param[in] service LinphoneAccountCreatorService object. + * @param[in] service #LinphoneAccountCreatorService object. * @return The current link account request. * @donotwrap **/ LINPHONE_PUBLIC LinphoneAccountCreatorRequestFunc linphone_account_creator_service_get_activate_alias_cb(const LinphoneAccountCreatorService *service); /** - * Assign a user pointer to a LinphoneAccountCreatorService object. - * @param[in] service LinphoneAccountCreatorService object. + * Assign a user pointer to a #LinphoneAccountCreatorService object. + * @param[in] service #LinphoneAccountCreatorService object. * @param[in] cb The activate alias request to be used. * @donotwrap **/ @@ -207,15 +207,15 @@ LINPHONE_PUBLIC void linphone_account_creator_service_set_activate_alias_cb(Linp /** * Get the is alias used request. - * @param[in] service LinphoneAccountCreatorService object. + * @param[in] service #LinphoneAccountCreatorService object. * @return The current is alias used request. * @donotwrap **/ LINPHONE_PUBLIC LinphoneAccountCreatorRequestFunc linphone_account_creator_service_get_is_alias_used_cb(const LinphoneAccountCreatorService *service); /** - * Assign a user pointer to a LinphoneAccountCreatorService object. - * @param[in] service LinphoneAccountCreatorService object. + * Assign a user pointer to a #LinphoneAccountCreatorService object. + * @param[in] service #LinphoneAccountCreatorService object. * @param[in] cb The is alias used request to be used. * @donotwrap **/ @@ -223,15 +223,15 @@ LINPHONE_PUBLIC void linphone_account_creator_service_set_is_alias_used_cb(Linph /** * Get the is account linked request. - * @param[in] service LinphoneAccountCreatorService object. + * @param[in] service #LinphoneAccountCreatorService object. * @return The current is account linked request. * @donotwrap **/ LINPHONE_PUBLIC LinphoneAccountCreatorRequestFunc linphone_account_creator_service_get_is_account_linked_cb(const LinphoneAccountCreatorService *service); /** - * Assign a user pointer to a LinphoneAccountCreatorService object. - * @param[in] service LinphoneAccountCreatorService object. + * Assign a user pointer to a #LinphoneAccountCreatorService object. + * @param[in] service #LinphoneAccountCreatorService object. * @param[in] cb The is account linked request to be used. * @donotwrap **/ @@ -239,15 +239,15 @@ LINPHONE_PUBLIC void linphone_account_creator_service_set_is_account_linked_cb(L /** * Get the recover account request. - * @param[in] service LinphoneAccountCreatorService object. + * @param[in] service #LinphoneAccountCreatorService object. * @return The current recover account request. * @donotwrap **/ LINPHONE_PUBLIC LinphoneAccountCreatorRequestFunc linphone_account_creator_service_get_recover_account_cb(const LinphoneAccountCreatorService *service); /** - * Assign a user pointer to a LinphoneAccountCreatorService object. - * @param[in] service LinphoneAccountCreatorService object. + * Assign a user pointer to a #LinphoneAccountCreatorService object. + * @param[in] service #LinphoneAccountCreatorService object. * @param[in] cb The recover account request to be used. * @donotwrap **/ @@ -255,15 +255,15 @@ LINPHONE_PUBLIC void linphone_account_creator_service_set_recover_account_cb(Lin /** * Get the update account request. - * @param[in] service LinphoneAccountCreatorService object. + * @param[in] service #LinphoneAccountCreatorService object. * @return The current update account request. * @donotwrap **/ LINPHONE_PUBLIC LinphoneAccountCreatorRequestFunc linphone_account_creator_service_get_update_account_cb(const LinphoneAccountCreatorService *service); /** - * Assign a user pointer to a LinphoneAccountCreatorService object. - * @param[in] service LinphoneAccountCreatorService object. + * Assign a user pointer to a #LinphoneAccountCreatorService object. + * @param[in] service #LinphoneAccountCreatorService object. * @param[in] cb The update account request to be used. * @donotwrap **/ diff --git a/include/linphone/api/c-address.h b/include/linphone/api/c-address.h index a07554b1b..d4716c5b8 100644 --- a/include/linphone/api/c-address.h +++ b/include/linphone/api/c-address.h @@ -34,23 +34,23 @@ */ /** - * Constructs a LinphoneAddress object by parsing the user supplied address, + * Constructs a #LinphoneAddress object by parsing the user supplied address, * given as a string. **/ LINPHONE_PUBLIC LinphoneAddress *linphone_address_new (const char *address); /** - * Clones a LinphoneAddress object. + * Clones a #LinphoneAddress object. **/ LINPHONE_PUBLIC LinphoneAddress *linphone_address_clone (const LinphoneAddress *address); /** - * Increment reference count of LinphoneAddress object. + * Increment reference count of #LinphoneAddress object. **/ LINPHONE_PUBLIC LinphoneAddress *linphone_address_ref (LinphoneAddress *address); /** - * Decrement reference count of LinphoneAddress object. When dropped to zero, memory is freed. + * Decrement reference count of #LinphoneAddress object. When dropped to zero, memory is freed. **/ LINPHONE_PUBLIC void linphone_address_unref (LinphoneAddress *address); @@ -147,7 +147,7 @@ LINPHONE_PUBLIC const char *linphone_address_get_password (const LinphoneAddress /** * Set the password encoded in the address. * It is used for basic authentication (not recommended). - * @param address the LinphoneAddress + * @param address the #LinphoneAddress * @param password the password to set. **/ LINPHONE_PUBLIC void linphone_address_set_password (LinphoneAddress *address, const char *password); @@ -170,26 +170,26 @@ LINPHONE_PUBLIC char *linphone_address_as_string (const LinphoneAddress *address LINPHONE_PUBLIC char *linphone_address_as_string_uri_only (const LinphoneAddress *address); /** - * Compare two LinphoneAddress ignoring tags and headers, basically just domain, username, and port. - * @param[in] address1 LinphoneAddress object - * @param[in] address2 LinphoneAddress object - * @return Boolean value telling if the LinphoneAddress objects are equal. + * Compare two #LinphoneAddress ignoring tags and headers, basically just domain, username, and port. + * @param[in] address1 #LinphoneAddress object + * @param[in] address2 #LinphoneAddress object + * @return Boolean value telling if the #LinphoneAddress objects are equal. * @see linphone_address_equal() **/ LINPHONE_PUBLIC bool_t linphone_address_weak_equal (const LinphoneAddress *address1, const LinphoneAddress *address2); /** - * Compare two LinphoneAddress taking the tags and headers into account. - * @param[in] address1 LinphoneAddress object - * @param[in] address2 LinphoneAddress object - * @return Boolean value telling if the LinphoneAddress objects are equal. + * Compare two #LinphoneAddress taking the tags and headers into account. + * @param[in] address1 #LinphoneAddress object + * @param[in] address2 #LinphoneAddress object + * @return Boolean value telling if the #LinphoneAddress objects are equal. * @see linphone_address_weak_equal() */ LINPHONE_PUBLIC bool_t linphone_address_equal (const LinphoneAddress *address1, const LinphoneAddress *address2); /** -* Get the header encoded in the address. -* @param address the address + * Get the header encoded in the address. + * @param header_name the header name **/ LINPHONE_PUBLIC const char *linphone_address_get_header (const LinphoneAddress *address, const char *header_name); @@ -204,7 +204,7 @@ LINPHONE_PUBLIC void linphone_address_set_header (LinphoneAddress *address, cons /** * Tell whether a parameter is present in the address - * @param[in] address LinphoneAddress object + * @param[in] address #LinphoneAddress object * @param[in] param_name The name of the parameter * @return A boolean value telling whether the parameter is present in the address */ @@ -212,7 +212,7 @@ LINPHONE_PUBLIC bool_t linphone_address_has_param (const LinphoneAddress *addres /** * Get the value of a parameter of the address - * @param[in] address LinphoneAddress object + * @param[in] address #LinphoneAddress object * @param[in] param_name The name of the parameter * @return The value of the parameter */ @@ -220,7 +220,7 @@ LINPHONE_PUBLIC const char *linphone_address_get_param (const LinphoneAddress *a /** * Set the value of a parameter of the address - * @param[in] address LinphoneAddress object + * @param[in] address #LinphoneAddress object * @param[in] param_name The name of the parameter * @param[in] param_value The new value of the parameter */ @@ -230,7 +230,7 @@ LINPHONE_PUBLIC void linphone_address_set_params (LinphoneAddress *address, cons /** * Tell whether a parameter is present in the URI of the address - * @param[in] address LinphoneAddress object + * @param[in] address #LinphoneAddress object * @param[in] uri_param_name The name of the parameter * @return A boolean value telling whether the parameter is present in the URI of the address */ @@ -238,7 +238,7 @@ LINPHONE_PUBLIC bool_t linphone_address_has_uri_param (const LinphoneAddress *ad /** * Get the value of a parameter of the URI of the address - * @param[in] address LinphoneAddress object + * @param[in] address #LinphoneAddress object * @param[in] uri_param_name The name of the parameter * @return The value of the parameter */ @@ -246,7 +246,7 @@ LINPHONE_PUBLIC const char *linphone_address_get_uri_param (const LinphoneAddres /** * Set the value of a parameter of the URI of the address - * @param[in] address LinphoneAddress object + * @param[in] address #LinphoneAddress object * @param[in] uri_param_name The name of the parameter * @param[in] uri_param_value The new value of the parameter */ @@ -256,13 +256,13 @@ LINPHONE_PUBLIC void linphone_address_set_uri_params (LinphoneAddress *address, /** * Removes the value of a parameter of the URI of the address - * @param[in] address LinphoneAddress object + * @param[in] address #LinphoneAddress object * @param[in] uri_param_name The name of the parameter */ LINPHONE_PUBLIC void linphone_address_remove_uri_param (LinphoneAddress *address, const char *uri_param_name); /** - * Destroys a LinphoneAddress object (actually calls linphone_address_unref()). + * Destroys a #LinphoneAddress object (actually calls linphone_address_unref()). * @deprecated Use linphone_address_unref() instead * @donotwrap **/ diff --git a/include/linphone/api/c-api.h b/include/linphone/api/c-api.h index 039b55246..3cae0b5c2 100644 --- a/include/linphone/api/c-api.h +++ b/include/linphone/api/c-api.h @@ -23,17 +23,19 @@ #include "linphone/utils/general.h" #include "linphone/api/c-address.h" -#include "linphone/api/c-call.h" #include "linphone/api/c-call-cbs.h" #include "linphone/api/c-call-stats.h" +#include "linphone/api/c-call.h" #include "linphone/api/c-callbacks.h" -#include "linphone/api/c-chat-message.h" #include "linphone/api/c-chat-message-cbs.h" -#include "linphone/api/c-chat-room.h" +#include "linphone/api/c-chat-message.h" #include "linphone/api/c-chat-room-cbs.h" +#include "linphone/api/c-chat-room.h" +#include "linphone/api/c-content.h" #include "linphone/api/c-dial-plan.h" #include "linphone/api/c-event-log.h" #include "linphone/api/c-participant.h" +#include "linphone/api/c-participant-imdn-state.h" #include "linphone/api/c-magic-search.h" #include "linphone/api/c-search-result.h" #include "linphone/api/c-types.h" diff --git a/include/linphone/api/c-call-cbs.h b/include/linphone/api/c-call-cbs.h index 207321ddf..2cdd6de49 100644 --- a/include/linphone/api/c-call-cbs.h +++ b/include/linphone/api/c-call-cbs.h @@ -35,126 +35,126 @@ */ /** - * Acquire a reference to the LinphoneCallCbs object. - * @param[in] cbs LinphoneCallCbs object. - * @return The same LinphoneCallCbs object. + * Acquire a reference to the #LinphoneCallCbs object. + * @param[in] cbs #LinphoneCallCbs object. + * @return The same #LinphoneCallCbs object. */ LINPHONE_PUBLIC LinphoneCallCbs *linphone_call_cbs_ref (LinphoneCallCbs *cbs); /** - * Release reference to the LinphoneCallCbs object. - * @param[in] cbs LinphoneCallCbs object. + * Release reference to the #LinphoneCallCbs object. + * @param[in] cbs #LinphoneCallCbs object. */ LINPHONE_PUBLIC void linphone_call_cbs_unref (LinphoneCallCbs *cbs); /** - * Retrieve the user pointer associated with the LinphoneCallCbs object. - * @param[in] cbs LinphoneCallCbs object. - * @return The user pointer associated with the LinphoneCallCbs object. + * Retrieve the user pointer associated with the #LinphoneCallCbs object. + * @param[in] cbs #LinphoneCallCbs object. + * @return The user pointer associated with the #LinphoneCallCbs object. */ LINPHONE_PUBLIC void *linphone_call_cbs_get_user_data (const LinphoneCallCbs *cbs); /** - * Assign a user pointer to the LinphoneCallCbs object. - * @param[in] cbs LinphoneCallCbs object. - * @param[in] ud The user pointer to associate with the LinphoneCallCbs object. + * Assign a user pointer to the #LinphoneCallCbs object. + * @param[in] cbs #LinphoneCallCbs object. + * @param[in] ud The user pointer to associate with the #LinphoneCallCbs object. */ LINPHONE_PUBLIC void linphone_call_cbs_set_user_data (LinphoneCallCbs *cbs, void *ud); /** * Get the dtmf received callback. - * @param[in] cbs LinphoneCallCbs object. + * @param[in] cbs #LinphoneCallCbs object. * @return The current dtmf received callback. */ LINPHONE_PUBLIC LinphoneCallCbsDtmfReceivedCb linphone_call_cbs_get_dtmf_received (LinphoneCallCbs *cbs); /** * Set the dtmf received callback. - * @param[in] cbs LinphoneCallCbs object. + * @param[in] cbs #LinphoneCallCbs object. * @param[in] cb The dtmf received callback to be used. */ LINPHONE_PUBLIC void linphone_call_cbs_set_dtmf_received (LinphoneCallCbs *cbs, LinphoneCallCbsDtmfReceivedCb cb); /** * Get the encryption changed callback. - * @param[in] cbs LinphoneCallCbs object. + * @param[in] cbs #LinphoneCallCbs object. * @return The current encryption changed callback. */ LINPHONE_PUBLIC LinphoneCallCbsEncryptionChangedCb linphone_call_cbs_get_encryption_changed (LinphoneCallCbs *cbs); /** * Set the encryption changed callback. - * @param[in] cbs LinphoneCallCbs object. + * @param[in] cbs #LinphoneCallCbs object. * @param[in] cb The encryption changed callback to be used. */ LINPHONE_PUBLIC void linphone_call_cbs_set_encryption_changed (LinphoneCallCbs *cbs, LinphoneCallCbsEncryptionChangedCb cb); /** * Get the info message received callback. - * @param[in] cbs LinphoneCallCbs object. + * @param[in] cbs #LinphoneCallCbs object. * @return The current info message received callback. */ LINPHONE_PUBLIC LinphoneCallCbsInfoMessageReceivedCb linphone_call_cbs_get_info_message_received (LinphoneCallCbs *cbs); /** * Set the info message received callback. - * @param[in] cbs LinphoneCallCbs object. + * @param[in] cbs #LinphoneCallCbs object. * @param[in] cb The info message received callback to be used. */ LINPHONE_PUBLIC void linphone_call_cbs_set_info_message_received (LinphoneCallCbs *cbs, LinphoneCallCbsInfoMessageReceivedCb cb); /** * Get the state changed callback. - * @param[in] cbs LinphoneCallCbs object. + * @param[in] cbs #LinphoneCallCbs object. * @return The current state changed callback. */ LINPHONE_PUBLIC LinphoneCallCbsStateChangedCb linphone_call_cbs_get_state_changed (LinphoneCallCbs *cbs); /** * Set the state changed callback. - * @param[in] cbs LinphoneCallCbs object. + * @param[in] cbs #LinphoneCallCbs object. * @param[in] cb The state changed callback to be used. */ LINPHONE_PUBLIC void linphone_call_cbs_set_state_changed (LinphoneCallCbs *cbs, LinphoneCallCbsStateChangedCb cb); /** * Get the stats updated callback. - * @param[in] cbs LinphoneCallCbs object. + * @param[in] cbs #LinphoneCallCbs object. * @return The current stats updated callback. */ LINPHONE_PUBLIC LinphoneCallCbsStatsUpdatedCb linphone_call_cbs_get_stats_updated (LinphoneCallCbs *cbs); /** * Set the stats updated callback. - * @param[in] cbs LinphoneCallCbs object. + * @param[in] cbs #LinphoneCallCbs object. * @param[in] cb The stats updated callback to be used. */ LINPHONE_PUBLIC void linphone_call_cbs_set_stats_updated (LinphoneCallCbs *cbs, LinphoneCallCbsStatsUpdatedCb cb); /** * Get the transfer state changed callback. - * @param[in] cbs LinphoneCallCbs object. + * @param[in] cbs #LinphoneCallCbs object. * @return The current transfer state changed callback. */ LINPHONE_PUBLIC LinphoneCallCbsTransferStateChangedCb linphone_call_cbs_get_transfer_state_changed (LinphoneCallCbs *cbs); /** * Set the transfer state changed callback. - * @param[in] cbs LinphoneCallCbs object. + * @param[in] cbs #LinphoneCallCbs object. * @param[in] cb The transfer state changed callback to be used. */ LINPHONE_PUBLIC void linphone_call_cbs_set_transfer_state_changed (LinphoneCallCbs *cbs, LinphoneCallCbsTransferStateChangedCb cb); /** * Get the ACK processing callback. - * @param[in] cbs LinphoneCallCbs object. + * @param[in] cbs #LinphoneCallCbs object. * @return The current ack processing callback. */ LINPHONE_PUBLIC LinphoneCallCbsAckProcessingCb linphone_call_cbs_get_ack_processing (LinphoneCallCbs *cbs); /** * Set ACK processing callback. - * @param[in] cbs LinphoneCallCbs object. + * @param[in] cbs #LinphoneCallCbs object. * @param[in] cb The ack processing callback to be used. */ LINPHONE_PUBLIC void linphone_call_cbs_set_ack_processing (LinphoneCallCbs *cbs, LinphoneCallCbsAckProcessingCb cb); @@ -173,6 +173,34 @@ LINPHONE_PUBLIC LinphoneCallCbsTmmbrReceivedCb linphone_call_cbs_get_tmmbr_recei */ LINPHONE_PUBLIC void linphone_call_cbs_set_tmmbr_received(LinphoneCallCbs *cbs, LinphoneCallCbsTmmbrReceivedCb cb); +/** + * Get the snapshot taken callback. + * @param[in] cbs LinphoneCallCbs object. + * @return The current snapshot taken callback. + */ +LINPHONE_PUBLIC LinphoneCallCbsSnapshotTakenCb linphone_call_cbs_get_snapshot_taken(LinphoneCallCbs *cbs); + +/** + * Set the snapshot taken callback. + * @param[in] cbs LinphoneCallCbs object. + * @param[in] cb The snapshot taken callback to be used. + */ +LINPHONE_PUBLIC void linphone_call_cbs_set_snapshot_taken(LinphoneCallCbs *cbs, LinphoneCallCbsSnapshotTakenCb cb); + + /** + * Get the next video frame decoded callback. + * @param[in] cbs LinphoneCallCbs object. + * @return The current next video frame decoded callback. + */ +LINPHONE_PUBLIC LinphoneCallCbsNextVideoFrameDecodedCb linphone_call_cbs_get_next_video_frame_decoded(LinphoneCallCbs *cbs); + +/** + * Set the next video frame decoded callback. + * @param[in] cbs LinphoneCallCbs object. + * @param[in] cb The next video frame decoded callback to be used. + */ +LINPHONE_PUBLIC void linphone_call_cbs_set_next_video_frame_decoded(LinphoneCallCbs *cbs, LinphoneCallCbsNextVideoFrameDecodedCb cb); + /** * @} */ diff --git a/include/linphone/api/c-call-stats.h b/include/linphone/api/c-call-stats.h index 60eb2e498..c2d18e815 100644 --- a/include/linphone/api/c-call-stats.h +++ b/include/linphone/api/c-call-stats.h @@ -46,29 +46,29 @@ /** * Increment refcount. - * @param[in] stats LinphoneCallStats object + * @param[in] stats #LinphoneCallStats object * @ingroup misc **/ LINPHONE_PUBLIC LinphoneCallStats *linphone_call_stats_ref (LinphoneCallStats *stats); /** * Decrement refcount and possibly free the object. - * @param[in] stats LinphoneCallStats object + * @param[in] stats #LinphoneCallStats object * @ingroup misc **/ LINPHONE_PUBLIC void linphone_call_stats_unref (LinphoneCallStats *stats); /** - * Gets the user data in the LinphoneCallStats object - * @param[in] stats the LinphoneCallStats + * Gets the user data in the #LinphoneCallStats object + * @param[in] stats the #LinphoneCallStats * @return the user data * @ingroup misc */ LINPHONE_PUBLIC void *linphone_call_stats_get_user_data (const LinphoneCallStats *stats); /** - * Sets the user data in the LinphoneCallStats object - * @param[in] stats the LinphoneCallStats object + * Sets the user data in the #LinphoneCallStats object + * @param[in] stats the #LinphoneCallStats object * @param[in] data the user data * @ingroup misc */ @@ -76,7 +76,7 @@ LINPHONE_PUBLIC void linphone_call_stats_set_user_data (LinphoneCallStats *stats /** * Get the type of the stream the stats refer to. - * @param[in] stats LinphoneCallStats object + * @param[in] stats #LinphoneCallStats object * @return The type of the stream the stats refer to */ LINPHONE_PUBLIC LinphoneStreamType linphone_call_stats_get_type (const LinphoneCallStats *stats); @@ -107,14 +107,14 @@ LINPHONE_PUBLIC float linphone_call_stats_get_local_late_rate (const LinphoneCal /** * Gets the local interarrival jitter - * @param[in] stats LinphoneCallStats object + * @param[in] stats #LinphoneCallStats object * @return The interarrival jitter at last emitted sender report **/ LINPHONE_PUBLIC float linphone_call_stats_get_sender_interarrival_jitter (const LinphoneCallStats *stats); /** * Gets the remote reported interarrival jitter - * @param[in] stats LinphoneCallStats object + * @param[in] stats #LinphoneCallStats object * @return The interarrival jitter at last received receiver report **/ LINPHONE_PUBLIC float linphone_call_stats_get_receiver_interarrival_jitter (const LinphoneCallStats *stats); @@ -123,77 +123,77 @@ LINPHONE_PUBLIC const rtp_stats_t *linphone_call_stats_get_rtp_stats (const Linp /** * Gets the cumulative number of late packets - * @param[in] stats LinphoneCallStats object + * @param[in] stats #LinphoneCallStats object * @return The cumulative number of late packets **/ LINPHONE_PUBLIC uint64_t linphone_call_stats_get_late_packets_cumulative_number (const LinphoneCallStats *stats); /** * Get the bandwidth measurement of the received stream, expressed in kbit/s, including IP/UDP/RTP headers. - * @param[in] stats LinphoneCallStats object + * @param[in] stats #LinphoneCallStats object * @return The bandwidth measurement of the received stream in kbit/s. */ LINPHONE_PUBLIC float linphone_call_stats_get_download_bandwidth (const LinphoneCallStats *stats); /** * Get the bandwidth measurement of the sent stream, expressed in kbit/s, including IP/UDP/RTP headers. - * @param[in] stats LinphoneCallStats object + * @param[in] stats #LinphoneCallStats object * @return The bandwidth measurement of the sent stream in kbit/s. */ LINPHONE_PUBLIC float linphone_call_stats_get_upload_bandwidth (const LinphoneCallStats *stats); /** * Get the bandwidth measurement of the received RTCP, expressed in kbit/s, including IP/UDP/RTP headers. - * @param[in] stats LinphoneCallStats object + * @param[in] stats #LinphoneCallStats object * @return The bandwidth measurement of the received RTCP in kbit/s. */ LINPHONE_PUBLIC float linphone_call_stats_get_rtcp_download_bandwidth (const LinphoneCallStats *stats); /** * Get the bandwidth measurement of the sent RTCP, expressed in kbit/s, including IP/UDP/RTP headers. - * @param[in] stats LinphoneCallStats object + * @param[in] stats #LinphoneCallStats object * @return The bandwidth measurement of the sent RTCP in kbit/s. */ LINPHONE_PUBLIC float linphone_call_stats_get_rtcp_upload_bandwidth( const LinphoneCallStats *stats); /** * Get the state of ICE processing. - * @param[in] stats LinphoneCallStats object + * @param[in] stats #LinphoneCallStats object * @return The state of ICE processing. */ LINPHONE_PUBLIC LinphoneIceState linphone_call_stats_get_ice_state (const LinphoneCallStats *stats); /** * Get the state of uPnP processing. - * @param[in] stats LinphoneCallStats object + * @param[in] stats #LinphoneCallStats object * @return The state of uPnP processing. */ LINPHONE_PUBLIC LinphoneUpnpState linphone_call_stats_get_upnp_state (const LinphoneCallStats *stats); /** * Get the IP address family of the remote peer. - * @param[in] stats LinphoneCallStats object + * @param[in] stats #LinphoneCallStats object * @return The IP address family of the remote peer. */ LINPHONE_PUBLIC LinphoneAddressFamily linphone_call_stats_get_ip_family_of_remote (const LinphoneCallStats *stats); /** * Get the jitter buffer size in ms. - * @param[in] stats LinphoneCallStats object + * @param[in] stats #LinphoneCallStats object * @return The jitter buffer size in ms. */ LINPHONE_PUBLIC float linphone_call_stats_get_jitter_buffer_size_ms (const LinphoneCallStats *stats); /** * Get the round trip delay in s. - * @param[in] stats LinphoneCallStats object + * @param[in] stats #LinphoneCallStats object * @return The round trip delay in s. */ LINPHONE_PUBLIC float linphone_call_stats_get_round_trip_delay (const LinphoneCallStats *stats); /** * Get the estimated bandwidth measurement of the received stream, expressed in kbit/s, including IP/UDP/RTP headers. - * @param[in] stats LinphoneCallStats object + * @param[in] stats #LinphoneCallStats object * @return The estimated bandwidth measurement of the received stream in kbit/s. */ LINPHONE_PUBLIC float linphone_call_stats_get_estimated_download_bandwidth(const LinphoneCallStats *stats); diff --git a/include/linphone/api/c-call.h b/include/linphone/api/c-call.h index 464436945..c90b0a0b3 100644 --- a/include/linphone/api/c-call.h +++ b/include/linphone/api/c-call.h @@ -68,8 +68,8 @@ LINPHONE_PUBLIC void linphone_call_set_user_data (LinphoneCall *call, void *ud); /** * Get the core that has created the specified call. - * @param[in] call LinphoneCall object - * @return The LinphoneCore object that has created the specified call. + * @param[in] call #LinphoneCall object + * @return The #LinphoneCore object that has created the specified call. */ LINPHONE_PUBLIC LinphoneCore * linphone_call_get_core (const LinphoneCall *call); @@ -80,7 +80,7 @@ LINPHONE_PUBLIC LinphoneCallState linphone_call_get_state (const LinphoneCall *c /** * Tell whether a call has been asked to autoanswer - * @param[in] call LinphoneCall object + * @param[in] call #LinphoneCall object * @return A boolean value telling whether the call has been asked to autoanswer **/ LINPHONE_PUBLIC bool_t linphone_call_asked_to_autoanswer (LinphoneCall *call); @@ -118,14 +118,14 @@ LINPHONE_PUBLIC LinphoneCallDir linphone_call_get_dir (const LinphoneCall *call) /** * Gets the call log associated to this call. - * @param[in] call LinphoneCall object - * @return The LinphoneCallLog associated with the specified LinphoneCall + * @param[in] call #LinphoneCall object + * @return The #LinphoneCallLog associated with the specified #LinphoneCall **/ LINPHONE_PUBLIC LinphoneCallLog *linphone_call_get_call_log (const LinphoneCall *call); /** * Gets the refer-to uri (if the call was transfered). - * @param[in] call LinphoneCall object + * @param[in] call #LinphoneCall object * @return The refer-to uri of the call (if it was transfered) **/ LINPHONE_PUBLIC const char *linphone_call_get_refer_to (const LinphoneCall *call); @@ -143,7 +143,7 @@ LINPHONE_PUBLIC bool_t linphone_call_has_transfer_pending (const LinphoneCall *c /** * Gets the transferer if this call was started automatically as a result of an incoming transfer request. * The call in which the transfer request was received is returned in this case. - * @param[in] call LinphoneCall object + * @param[in] call #LinphoneCall object * @return The transferer call if the specified call was started automatically as a result of an incoming transfer request, NULL otherwise **/ LINPHONE_PUBLIC LinphoneCall *linphone_call_get_transferer_call (const LinphoneCall *call); @@ -192,7 +192,7 @@ LINPHONE_PUBLIC bool_t linphone_call_camera_enabled (const LinphoneCall *lc); /** * Take a photo of currently received video and write it into a jpeg file. * Note that the snapshot is asynchronous, an application shall not assume that the file is created when the function returns. - * @param call a LinphoneCall + * @param call a #LinphoneCall * @param file a path where to write the jpeg content. * @return 0 if successfull, -1 otherwise (typically if jpeg format is not supported). **/ @@ -201,7 +201,7 @@ LINPHONE_PUBLIC LinphoneStatus linphone_call_take_video_snapshot (LinphoneCall * /** * Take a photo of currently captured video and write it into a jpeg file. * Note that the snapshot is asynchronous, an application shall not assume that the file is created when the function returns. - * @param call a LinphoneCall + * @param call a #LinphoneCall * @param file a path where to write the jpeg content. * @return 0 if successfull, -1 otherwise (typically if jpeg format is not supported). **/ @@ -214,8 +214,8 @@ LINPHONE_PUBLIC LinphoneReason linphone_call_get_reason (const LinphoneCall *cal /** * Returns full details about call errors or termination reasons. - * @param call LinphoneCall object on which we want the information error - * @return LinphoneErrorInfo object holding the reason error. + * @param call #LinphoneCall object on which we want the information error + * @return #LinphoneErrorInfo object holding the reason error. */ LINPHONE_PUBLIC const LinphoneErrorInfo *linphone_call_get_error_info (const LinphoneCall *call); @@ -231,7 +231,7 @@ LINPHONE_PUBLIC const char *linphone_call_get_remote_contact (LinphoneCall *call /** * Returns the ZRTP authentication token to verify. - * @param call the LinphoneCall + * @param call the #LinphoneCall * @return the authentication token to verify. **/ LINPHONE_PUBLIC const char *linphone_call_get_authentication_token (LinphoneCall *call); @@ -240,7 +240,7 @@ LINPHONE_PUBLIC const char *linphone_call_get_authentication_token (LinphoneCall * Returns whether ZRTP authentication token is verified. * If not, it must be verified by users as described in ZRTP procedure. * Once done, the application must inform of the results with linphone_call_set_authentication_token_verified(). - * @param call the LinphoneCall + * @param call the #LinphoneCall * @return TRUE if authentication token is verifed, false otherwise. **/ LINPHONE_PUBLIC bool_t linphone_call_get_authentication_token_verified (const LinphoneCall *call); @@ -248,7 +248,7 @@ LINPHONE_PUBLIC bool_t linphone_call_get_authentication_token_verified (const Li /** * Set the result of ZRTP short code verification by user. * If remote party also does the same, it will update the ZRTP cache so that user's verification will not be required for the two users. - * @param call the LinphoneCall + * @param call the #LinphoneCall * @param verified whether the ZRTP SAS is verified. **/ LINPHONE_PUBLIC void linphone_call_set_authentication_token_verified (LinphoneCall *call, bool_t verified); @@ -291,7 +291,7 @@ LINPHONE_PUBLIC void linphone_call_zoom (LinphoneCall *call, float zoom_factor, * Send the specified dtmf. * * The dtmf is automatically played to the user. - * @param call The LinphoneCall object + * @param call The #LinphoneCall object * @param dtmf The dtmf name specified as a char, such as '0', '#' etc... * @return 0 if successful, -1 on error. **/ @@ -302,7 +302,7 @@ LINPHONE_PUBLIC LinphoneStatus linphone_call_send_dtmf (LinphoneCall *call, char * * The dtmfs are automatically sent to remote, separated by some needed customizable delay. * Sending is canceled if the call state changes to something not LinphoneCallStreamsRunning. - * @param call The LinphoneCall object + * @param call The #LinphoneCall object * @param dtmfs A dtmf sequence such as '123#123123' * @return -2 if there is already a DTMF sequence, -1 if call is not ready, 0 otherwise. **/ @@ -314,7 +314,7 @@ LINPHONE_PUBLIC LinphoneStatus linphone_call_send_dtmfs (LinphoneCall *call, con * Please note that some DTMF could be already sent, * depending on when this function call is delayed from #linphone_call_send_dtmfs. This * function will be automatically called if call state change to anything but LinphoneCallStreamsRunning. - * @param call The LinphoneCall object + * @param call The #LinphoneCall object **/ LINPHONE_PUBLIC void linphone_call_cancel_dtmfs (LinphoneCall *call); @@ -375,7 +375,7 @@ LINPHONE_PUBLIC RtpTransport *linphone_call_get_meta_rtcp_transport (const Linph * Pauses the call. If a music file has been setup using linphone_core_set_play_file(), * this file will be played to the remote user. * The only way to resume a paused call is to call linphone_call_resume(). - * @param[in] call LinphoneCall object + * @param[in] call #LinphoneCall object * @return 0 on success, -1 on failure * @see linphone_call_resume() **/ @@ -384,7 +384,7 @@ LINPHONE_PUBLIC LinphoneStatus linphone_call_pause (LinphoneCall *call); /** * Resumes a call. * The call needs to have been paused previously with linphone_call_pause(). - * @param[in] call LinphoneCall object + * @param[in] call #LinphoneCall object * @return 0 on success, -1 on failure * @see linphone_call_pause() **/ @@ -392,21 +392,21 @@ LINPHONE_PUBLIC LinphoneStatus linphone_call_resume (LinphoneCall *call); /** * Terminates a call. - * @param[in] call LinphoneCall object + * @param[in] call #LinphoneCall object * @return 0 on success, -1 on failure **/LINPHONE_PUBLIC LinphoneStatus linphone_call_terminate (LinphoneCall *call); /** * Terminates a call. - * @param[in] call LinphoneCall object - * @param[in] ei LinphoneErrorInfo + * @param[in] call #LinphoneCall object + * @param[in] ei #LinphoneErrorInfo * @return 0 on success, -1 on failure **/ LINPHONE_PUBLIC LinphoneStatus linphone_call_terminate_with_error_info (LinphoneCall *call, const LinphoneErrorInfo *ei); /** * Redirect the specified call to the given redirect URI. - * @param[in] call A LinphoneCall object + * @param[in] call A #LinphoneCall object * @param[in] redirect_uri The URI to redirect the call to * @return 0 if successful, -1 on error. */ @@ -414,16 +414,16 @@ LINPHONE_PUBLIC LinphoneStatus linphone_call_redirect (LinphoneCall *call, const /** * Decline a pending incoming call, with a reason. - * @param[in] call A LinphoneCall object that must be in the IncomingReceived state - * @param[in] reason The reason for rejecting the call: LinphoneReasonDeclined or LinphoneReasonBusy + * @param[in] call A #LinphoneCall object that must be in the IncomingReceived state + * @param[in] reason The reason for rejecting the call: #LinphoneReasonDeclined or #LinphoneReasonBusy * @return 0 on success, -1 on failure **/ LINPHONE_PUBLIC LinphoneStatus linphone_call_decline (LinphoneCall *call, LinphoneReason reason); /** - * Decline a pending incoming call, with a LinphoneErrorInfo object. - * @param[in] call A LinphoneCall object that must be in the IncomingReceived state - * @param[in] ei LinphoneErrorInfo containing more information on the call rejection. + * Decline a pending incoming call, with a #LinphoneErrorInfo object. + * @param[in] call A #LinphoneCall object that must be in the IncomingReceived state + * @param[in] ei #LinphoneErrorInfo containing more information on the call rejection. * @return 0 on success, -1 on failure */ LINPHONE_PUBLIC int linphone_call_decline_with_error_info (LinphoneCall *call, const LinphoneErrorInfo *ei); @@ -433,9 +433,9 @@ LINPHONE_PUBLIC int linphone_call_decline_with_error_info (LinphoneCall *call, c * * Basically the application is notified of incoming calls within the * call_state_changed callback of the #LinphoneCoreVTable structure, where it will receive - * a LinphoneCallIncoming event with the associated LinphoneCall object. + * a #LinphoneCallIncoming event with the associated #LinphoneCall object. * The application can later accept the call using this method. - * @param[in] call A LinphoneCall object + * @param[in] call A #LinphoneCall object * @return 0 on success, -1 on failure **/ LINPHONE_PUBLIC LinphoneStatus linphone_call_accept (LinphoneCall *call); @@ -445,9 +445,9 @@ LINPHONE_PUBLIC LinphoneStatus linphone_call_accept (LinphoneCall *call); * * Basically the application is notified of incoming calls within the * call_state_changed callback of the #LinphoneCoreVTable structure, where it will receive - * a LinphoneCallIncoming event with the associated LinphoneCall object. + * a #LinphoneCallIncoming event with the associated #LinphoneCall object. * The application can later accept the call using this method. - * @param[in] call A LinphoneCall object + * @param[in] call A #LinphoneCall object * @param[in] params The specific parameters for this call, for example whether video is accepted or not. Use NULL to use default parameters * @return 0 on success, -1 on failure **/ @@ -456,7 +456,7 @@ LINPHONE_PUBLIC LinphoneStatus linphone_call_accept_with_params (LinphoneCall *c /** * Accept an early media session for an incoming call. * This is identical as calling linphone_call_accept_early_media_with_params() with NULL parameters. - * @param[in] call A LinphoneCall object + * @param[in] call A #LinphoneCall object * @return 0 if successful, -1 otherwise * @see linphone_call_accept_early_media_with_params() **/ @@ -467,7 +467,7 @@ LINPHONE_PUBLIC LinphoneStatus linphone_call_accept_early_media (LinphoneCall *c * This means the call is not accepted but audio & video streams can be established if the remote party supports early media. * However, unlike after call acceptance, mic and camera input are not sent during early-media, though received audio & video are played normally. * The call can then later be fully accepted using linphone_call_accept() or linphone_call_accept_with_params(). - * @param[in] call A LinphoneCall object + * @param[in] call A #LinphoneCall object * @param[in] params The call parameters to use (can be NULL) * @return 0 if successful, -1 otherwise **/ @@ -475,36 +475,35 @@ LINPHONE_PUBLIC LinphoneStatus linphone_call_accept_early_media_with_params (Lin /** * Updates a running call according to supplied call parameters or parameters changed in the LinphoneCore. - * In this version this is limited to the following use cases: - * - setting up/down the video stream according to the video parameter of the LinphoneCallParams (see linphone_call_params_enable_video() ). - * - changing the size of the transmitted video after calling linphone_core_set_preferred_video_size() - * In case no changes are requested through the LinphoneCallParams argument, then this argument can be omitted and set to NULL. - * WARNING: Updating a call in the LinphoneCallPaused state will still result in a paused call even if the media directions set in the + * It triggers a SIP reINVITE in order to perform a new offer/answer of media capabilities. + * Changing the size of the transmitted video after calling #linphone_core_set_preferred_video_size() can be used by passing NULL as params argument. + * In case no changes are requested through the #LinphoneCallParams argument, then this argument can be omitted and set to NULL. + * WARNING: Updating a call in the #LinphoneCallPaused state will still result in a paused call even if the media directions set in the * params are sendrecv. To resume a paused call, you need to call linphone_call_resume(). * - * @param[in] call A LinphoneCall object + * @param[in] call A #LinphoneCall object * @param[in] params The new call parameters to use (may be NULL) * @return 0 if successful, -1 otherwise. **/ LINPHONE_PUBLIC LinphoneStatus linphone_call_update (LinphoneCall *call, const LinphoneCallParams *params); /** - * When receiving a #LinphoneCallUpdatedByRemote state notification, prevent LinphoneCore from performing an automatic answer. + * When receiving a #LinphoneCallUpdatedByRemote state notification, prevent #LinphoneCore from performing an automatic answer. * * When receiving a #LinphoneCallUpdatedByRemote state notification (ie an incoming reINVITE), the default behaviour of - * LinphoneCore is defined by the "defer_update_default" option of the "sip" section of the config. If this option is 0 (the default) - * then the LinphoneCore automatically answers the reINIVTE with call parameters unchanged. + * #LinphoneCore is defined by the "defer_update_default" option of the "sip" section of the config. If this option is 0 (the default) + * then the #LinphoneCore automatically answers the reINIVTE with call parameters unchanged. * However when for example when the remote party updated the call to propose a video stream, it can be useful * to prompt the user before answering. This can be achieved by calling linphone_core_defer_call_update() during * the call state notification, to deactivate the automatic answer that would just confirm the audio but reject the video. * Then, when the user responds to dialog prompt, it becomes possible to call linphone_call_accept_update() to answer - * the reINVITE, with eventually video enabled in the LinphoneCallParams argument. + * the reINVITE, with eventually video enabled in the #LinphoneCallParams argument. * * The #LinphoneCallUpdatedByRemote notification can also arrive when receiving an INVITE without SDP. In such case, an unchanged offer is made * in the 200Ok, and when the ACK containing the SDP answer is received, #LinphoneCallUpdatedByRemote is triggered to notify the application of possible * changes in the media session. However in such case defering the update has no meaning since we just generating an offer. * - * @param[in] call A LinphoneCall object + * @param[in] call A #LinphoneCall object * @return 0 if successful, -1 if the linphone_call_defer_update() was done outside a valid #LinphoneCallUpdatedByRemote notification **/ LINPHONE_PUBLIC LinphoneStatus linphone_call_defer_update (LinphoneCall *call); @@ -522,8 +521,8 @@ LINPHONE_PUBLIC LinphoneStatus linphone_call_defer_update (LinphoneCall *call); * If params is not NULL, then the update will be accepted according to the parameters passed. * Typical example is when a user accepts to start video, then params should indicate that video stream should be used * (see linphone_call_params_enable_video()). - * @param[in] call A LinphoneCall object - * @param[in] params A LinphoneCallParams object describing the call parameters to accept + * @param[in] call A #LinphoneCall object + * @param[in] params A #LinphoneCallParams object describing the call parameters to accept * @return 0 if successful, -1 otherwise (actually when this function call is performed outside ot #LinphoneCallUpdatedByRemote state) **/ LINPHONE_PUBLIC LinphoneStatus linphone_call_accept_update (LinphoneCall *call, const LinphoneCallParams *params); @@ -707,8 +706,8 @@ LINPHONE_PUBLIC void linphone_call_stop_recording(LinphoneCall *call); /** * Get a player associated with the call to play a local file and stream it to the remote peer. - * @param[in] call LinphoneCall object - * @return A LinphonePlayer object + * @param[in] call #LinphoneCall object + * @return A #LinphonePlayer object */ LINPHONE_PUBLIC LinphonePlayer * linphone_call_get_player(LinphoneCall *call); @@ -730,7 +729,7 @@ LINPHONE_PUBLIC bool_t linphone_call_media_in_progress(const LinphoneCall *call) LINPHONE_PUBLIC void linphone_call_ogl_render(const LinphoneCall *call); /** - * Send a LinphoneInfoMessage through an established call + * Send a #LinphoneInfoMessage through an established call * @param call the call * @param info the info message **/ @@ -750,25 +749,25 @@ LINPHONE_PUBLIC LinphoneCallStats *linphone_call_get_video_stats(LinphoneCall *c LINPHONE_PUBLIC LinphoneCallStats *linphone_call_get_text_stats(LinphoneCall *call); /** - * Add a listener in order to be notified of LinphoneCall events. Once an event is received, registred LinphoneCallCbs are + * Add a listener in order to be notified of #LinphoneCall events. Once an event is received, registred #LinphoneCallCbs are * invoked sequencially. - * @param[in] call LinphoneCall object to monitor. - * @param[in] cbs A LinphoneCallCbs object holding the callbacks you need. A reference is taken by the LinphoneCall until you invoke linphone_call_remove_callbacks(). + * @param[in] call #LinphoneCall object to monitor. + * @param[in] cbs A #LinphoneCallCbs object holding the callbacks you need. A reference is taken by the #LinphoneCall until you invoke linphone_call_remove_callbacks(). */ LINPHONE_PUBLIC void linphone_call_add_callbacks(LinphoneCall *call, LinphoneCallCbs *cbs); /** - * Remove a listener from a LinphoneCall - * @param[in] call LinphoneCall object - * @param[in] cbs LinphoneCallCbs object to remove. + * Remove a listener from a #LinphoneCall + * @param[in] call #LinphoneCall object + * @param[in] cbs #LinphoneCallCbs object to remove. */ LINPHONE_PUBLIC void linphone_call_remove_callbacks(LinphoneCall *call, LinphoneCallCbs *cbs); /** * Gets the current LinphoneCallCbs. - * This is meant only to be called from a callback to be able to get the user_data associated with the LinphoneCallCbs that is calling the callback. - * @param[in] call LinphoneCall object - * @return The LinphoneCallCbs that has called the last callback + * This is meant only to be called from a callback to be able to get the user_data associated with the #LinphoneCallCbs that is calling the callback. + * @param[in] call #LinphoneCall object + * @return The #LinphoneCallCbs that has called the last callback */ LINPHONE_PUBLIC LinphoneCallCbs *linphone_call_get_current_callbacks(const LinphoneCall *call); @@ -778,16 +777,16 @@ LINPHONE_PUBLIC LinphoneCallCbs *linphone_call_get_current_callbacks(const Linph * linphone_call_accept_with_params(). * However, in some cases it might be desirable from a software design standpoint to modify local parameters outside of the application layer, typically * in the purpose of implementing a custom logic including special headers in INVITE or 200Ok requests, driven by a call_state_changed listener method. - * This function accepts to assign a new LinphoneCallParams only in LinphoneCallOutgoingInit and LinphoneCallIncomingReceived states. - * @param call the LinphoneCall object + * This function accepts to assign a new #LinphoneCallParams only in #LinphoneCallOutgoingInit and #LinphoneCallIncomingReceived states. + * @param call the #LinphoneCall object **/ LINPHONE_PUBLIC void linphone_call_set_params(LinphoneCall *call, const LinphoneCallParams *params); /** * Returns local parameters associated with the call. * This is typically the parameters passed at call initiation to linphone_core_invite_address_with_params() or linphone_call_accept_with_params(), or some default - * parameters if no LinphoneCallParams was explicitely passed during call initiation. - * @param call the LinphoneCall object + * parameters if no #LinphoneCallParams was explicitely passed during call initiation. + * @param call the #LinphoneCall object * @return the call's local parameters. **/ LINPHONE_PUBLIC const LinphoneCallParams * linphone_call_get_params(LinphoneCall *call); diff --git a/include/linphone/api/c-callbacks.h b/include/linphone/api/c-callbacks.h index 339963691..f60dfb469 100644 --- a/include/linphone/api/c-callbacks.h +++ b/include/linphone/api/c-callbacks.h @@ -37,14 +37,14 @@ /** * Callback for being notified of received DTMFs. - * @param call LinphoneCall object that received the dtmf + * @param call #LinphoneCall object that received the dtmf * @param dtmf The ascii code of the dtmf */ typedef void (*LinphoneCallCbsDtmfReceivedCb)(LinphoneCall *call, int dtmf); /** * Call encryption changed callback. - * @param call LinphoneCall object whose encryption is changed. + * @param call #LinphoneCall object whose encryption is changed. * @param on Whether encryption is activated. * @param authentication_token An authentication_token, currently set for ZRTP kind of encryption only. */ @@ -52,14 +52,14 @@ typedef void (*LinphoneCallCbsEncryptionChangedCb)(LinphoneCall *call, bool_t on /** * Callback for receiving info messages. - * @param call LinphoneCall whose info message belongs to. - * @param msg LinphoneInfoMessage object. + * @param call #LinphoneCall whose info message belongs to. + * @param msg #LinphoneInfoMessage object. */ typedef void (*LinphoneCallCbsInfoMessageReceivedCb)(LinphoneCall *call, const LinphoneInfoMessage *msg); /** * Call state notification callback. - * @param call LinphoneCall whose state is changed. + * @param call #LinphoneCall whose state is changed. * @param cstate The new state of the call * @param message An informational message about the state. */ @@ -67,21 +67,21 @@ typedef void (*LinphoneCallCbsStateChangedCb)(LinphoneCall *call, LinphoneCallSt /** * Callback for receiving quality statistics for calls. - * @param call LinphoneCall object whose statistics are notified - * @param stats LinphoneCallStats object + * @param call #LinphoneCall object whose statistics are notified + * @param stats #LinphoneCallStats object */ typedef void (*LinphoneCallCbsStatsUpdatedCb)(LinphoneCall *call, const LinphoneCallStats *stats); /** * Callback for notifying progresses of transfers. - * @param call LinphoneCall that was transfered + * @param call #LinphoneCall that was transfered * @param cstate The state of the call to transfer target at the far end. */ typedef void (*LinphoneCallCbsTransferStateChangedCb)(LinphoneCall *call, LinphoneCallState cstate); /** * Callback for notifying the processing SIP ACK messages. - * @param call LinphoneCall for which an ACK is being received or sent + * @param call #LinphoneCall for which an ACK is being received or sent * @param ack the ACK message * @param is_received if TRUE this ACK is an incoming one, otherwise it is an ACK about to be sent. */ @@ -95,6 +95,19 @@ typedef void (*LinphoneCallCbsAckProcessingCb)(LinphoneCall *call, LinphoneHeade */ typedef void (*LinphoneCallCbsTmmbrReceivedCb)(LinphoneCall *call, int stream_index, int tmmbr); +/** + * Callback for notifying a snapshot taken. + * @param call LinphoneCall for which the snapshot was taken + * @param filepath the name of the saved file + */ +typedef void (*LinphoneCallCbsSnapshotTakenCb)(LinphoneCall *call, const char *filepath); + + /** + * Callback to notify a next video frame has been decoded + * @param call LinphoneCall for which the next video frame has been decoded + */ +typedef void (*LinphoneCallCbsNextVideoFrameDecodedCb)(LinphoneCall *call); + /** * @} **/ @@ -108,9 +121,9 @@ typedef void (*LinphoneCallCbsTmmbrReceivedCb)(LinphoneCall *call, int stream_in /** * Call back used to notify message delivery status * @param msg #LinphoneChatMessage object - * @param status LinphoneChatMessageState + * @param status #LinphoneChatMessageState * @param ud application user data - * @deprecated Use LinphoneChatMessageCbsMsgStateChangedCb instead. + * @deprecated Use #LinphoneChatMessageCbsMsgStateChangedCb instead. * @donotwrap */ typedef void (*LinphoneChatMessageStateChangedCb)(LinphoneChatMessage* msg, LinphoneChatMessageState state, void* ud); @@ -118,10 +131,17 @@ typedef void (*LinphoneChatMessageStateChangedCb)(LinphoneChatMessage* msg, Linp /** * Call back used to notify message delivery status * @param msg #LinphoneChatMessage object - * @param status LinphoneChatMessageState + * @param status #LinphoneChatMessageState */ typedef void (*LinphoneChatMessageCbsMsgStateChangedCb)(LinphoneChatMessage* msg, LinphoneChatMessageState state); +/** + * Call back used to notify participant IMDN state + * @param msg #LinphoneChatMessage object + * @param state #LinphoneParticipantImdnState + */ +typedef void (*LinphoneChatMessageCbsParticipantImdnStateChangedCb)(LinphoneChatMessage* msg, const LinphoneParticipantImdnState *state); + /** * File transfer receive callback prototype. This function is called by the core upon an incoming File transfer is started. This function may be call several time for the same file in case of large file. * @param message #LinphoneChatMessage message from which the body is received. @@ -136,7 +156,7 @@ typedef void (*LinphoneChatMessageCbsFileTransferRecvCb)(LinphoneChatMessage *me * @param content #LinphoneContent outgoing content * @param offset the offset in the file from where to get the data to be sent * @param size the number of bytes expected by the framework - * @return A LinphoneBuffer object holding the data written by the application. An empty buffer means end of file. + * @return A #LinphoneBuffer object holding the data written by the application. An empty buffer means end of file. */ typedef LinphoneBuffer * (*LinphoneChatMessageCbsFileTransferSendCb)(LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t size); @@ -235,6 +255,18 @@ typedef void (*LinphoneChatRoomCbsParticipantDeviceAddedCb) (LinphoneChatRoom *c */ typedef void (*LinphoneChatRoomCbsParticipantDeviceRemovedCb) (LinphoneChatRoom *cr, const LinphoneEventLog *event_log); +/** + * Callback used to notify a chat room has been joined. + * @param[in] cr #LinphoneChatRoom object + */ +typedef void (*LinphoneChatRoomCbsConferenceJoinedCb) (LinphoneChatRoom *cr, const LinphoneEventLog *eventLog); + +/** + * Callback used to notify a chat room has been left. + * @param[in] cr #LinphoneChatRoom object + */ +typedef void (*LinphoneChatRoomCbsConferenceLeftCb) (LinphoneChatRoom *cr, const LinphoneEventLog *eventLog); + /** * Callback used when a group chat room is created server-side to generate the address of the chat room. * The function linphone_chat_room_set_conference_address() needs to be called by this callback. diff --git a/include/linphone/api/c-chat-message-cbs.h b/include/linphone/api/c-chat-message-cbs.h index 440b7a4a0..35dc2ff19 100644 --- a/include/linphone/api/c-chat-message-cbs.h +++ b/include/linphone/api/c-chat-message-cbs.h @@ -34,7 +34,7 @@ * @{ */ -LinphoneChatMessageCbs *linphone_chat_message_cbs_new(void); +LinphoneChatMessageCbs *linphone_chat_message_cbs_new (void); /** * Acquire a reference to the chat room callbacks object. @@ -65,59 +65,73 @@ LINPHONE_PUBLIC void linphone_chat_message_cbs_set_user_data (LinphoneChatMessag /** * Get the message state changed callback. - * @param[in] cbs LinphoneChatMessageCbs object. + * @param[in] cbs #LinphoneChatMessageCbs object. * @return The current message state changed callback. */ - LINPHONE_PUBLIC LinphoneChatMessageCbsMsgStateChangedCb linphone_chat_message_cbs_get_msg_state_changed(const LinphoneChatMessageCbs *cbs); +LINPHONE_PUBLIC LinphoneChatMessageCbsMsgStateChangedCb linphone_chat_message_cbs_get_msg_state_changed (const LinphoneChatMessageCbs *cbs); - /** - * Set the message state changed callback. - * @param[in] cbs LinphoneChatMessageCbs object. - * @param[in] cb The message state changed callback to be used. - */ - LINPHONE_PUBLIC void linphone_chat_message_cbs_set_msg_state_changed(LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsMsgStateChangedCb cb); +/** + * Set the message state changed callback. + * @param[in] cbs LinphoneChatMessageCbs object. + * @param[in] cb The message state changed callback to be used. + */ +LINPHONE_PUBLIC void linphone_chat_message_cbs_set_msg_state_changed (LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsMsgStateChangedCb cb); - /** - * Get the file transfer receive callback. - * @param[in] cbs LinphoneChatMessageCbs object. - * @return The current file transfer receive callback. - */ - LINPHONE_PUBLIC LinphoneChatMessageCbsFileTransferRecvCb linphone_chat_message_cbs_get_file_transfer_recv(const LinphoneChatMessageCbs *cbs); +/** + * Get the file transfer receive callback. + * @param[in] cbs LinphoneChatMessageCbs object. + * @return The current file transfer receive callback. + */ +LINPHONE_PUBLIC LinphoneChatMessageCbsFileTransferRecvCb linphone_chat_message_cbs_get_file_transfer_recv (const LinphoneChatMessageCbs *cbs); - /** - * Set the file transfer receive callback. - * @param[in] cbs LinphoneChatMessageCbs object. - * @param[in] cb The file transfer receive callback to be used. - */ - LINPHONE_PUBLIC void linphone_chat_message_cbs_set_file_transfer_recv(LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsFileTransferRecvCb cb); +/** + * Set the file transfer receive callback. + * @param[in] cbs LinphoneChatMessageCbs object. + * @param[in] cb The file transfer receive callback to be used. + */ +LINPHONE_PUBLIC void linphone_chat_message_cbs_set_file_transfer_recv (LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsFileTransferRecvCb cb); - /** +/** * Get the file transfer send callback. * @param[in] cbs LinphoneChatMessageCbs object. * @return The current file transfer send callback. */ - LINPHONE_PUBLIC LinphoneChatMessageCbsFileTransferSendCb linphone_chat_message_cbs_get_file_transfer_send(const LinphoneChatMessageCbs *cbs); +LINPHONE_PUBLIC LinphoneChatMessageCbsFileTransferSendCb linphone_chat_message_cbs_get_file_transfer_send (const LinphoneChatMessageCbs *cbs); - /** - * Set the file transfer send callback. - * @param[in] cbs LinphoneChatMessageCbs object. - * @param[in] cb The file transfer send callback to be used. - */ - LINPHONE_PUBLIC void linphone_chat_message_cbs_set_file_transfer_send(LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsFileTransferSendCb cb); +/** + * Set the file transfer send callback. + * @param[in] cbs LinphoneChatMessageCbs object. + * @param[in] cb The file transfer send callback to be used. + */ +LINPHONE_PUBLIC void linphone_chat_message_cbs_set_file_transfer_send (LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsFileTransferSendCb cb); - /** - * Get the file transfer progress indication callback. - * @param[in] cbs LinphoneChatMessageCbs object. - * @return The current file transfer progress indication callback. - */ - LINPHONE_PUBLIC LinphoneChatMessageCbsFileTransferProgressIndicationCb linphone_chat_message_cbs_get_file_transfer_progress_indication(const LinphoneChatMessageCbs *cbs); +/** + * Get the file transfer progress indication callback. + * @param[in] cbs LinphoneChatMessageCbs object. + * @return The current file transfer progress indication callback. + */ +LINPHONE_PUBLIC LinphoneChatMessageCbsFileTransferProgressIndicationCb linphone_chat_message_cbs_get_file_transfer_progress_indication (const LinphoneChatMessageCbs *cbs); - /** - * Set the file transfer progress indication callback. - * @param[in] cbs LinphoneChatMessageCbs object. - * @param[in] cb The file transfer progress indication callback to be used. - */ - LINPHONE_PUBLIC void linphone_chat_message_cbs_set_file_transfer_progress_indication(LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsFileTransferProgressIndicationCb cb); +/** + * Set the file transfer progress indication callback. + * @param[in] cbs LinphoneChatMessageCbs object. + * @param[in] cb The file transfer progress indication callback to be used. + */ +LINPHONE_PUBLIC void linphone_chat_message_cbs_set_file_transfer_progress_indication (LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsFileTransferProgressIndicationCb cb); + +/** + * Get the participant IMDN state changed callback. + * @param[in] cbs #LinphoneChatMessageCbs object. + * @return The current participant IMDN state changed callback. + */ +LINPHONE_PUBLIC LinphoneChatMessageCbsParticipantImdnStateChangedCb linphone_chat_message_cbs_get_participant_imdn_state_changed (const LinphoneChatMessageCbs *cbs); + +/** + * Set the participant IMDN state changed callback. + * @param[in] cbs LinphoneChatMessageCbs object. + * @param[in] cb The participant IMDN state changed callback to be used. + */ +LINPHONE_PUBLIC void linphone_chat_message_cbs_set_participant_imdn_state_changed (LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsParticipantImdnStateChangedCb cb); /** * @} diff --git a/include/linphone/api/c-chat-message.h b/include/linphone/api/c-chat-message.h index 1cd3dbd21..25f202f82 100644 --- a/include/linphone/api/c-chat-message.h +++ b/include/linphone/api/c-chat-message.h @@ -20,12 +20,12 @@ #ifndef _L_C_CHAT_MESSAGE_H_ #define _L_C_CHAT_MESSAGE_H_ -#include "linphone/api/c-types.h" #include "linphone/api/c-chat-message-cbs.h" +#include "linphone/api/c-types.h" #ifdef SQLITE_STORAGE_ENABLED -#include -#endif + #include +#endif // ifdef SQLITE_STORAGE_ENABLED // ============================================================================= @@ -37,7 +37,7 @@ typedef enum _LinphoneChatMessageDir{ // ============================================================================= #ifdef __cplusplus - extern "C" { + extern "C" { #endif // ifdef __cplusplus /** @@ -47,99 +47,101 @@ typedef enum _LinphoneChatMessageDir{ /** * Acquire a reference to the chat message. - * @param[in] cr The chat message. + * @param[in] msg #LinphoneChatMessage object. * @return The same chat message. -**/ -LINPHONE_PUBLIC LinphoneChatMessage *linphone_chat_message_ref(LinphoneChatMessage *msg); + */ +LINPHONE_PUBLIC LinphoneChatMessage *linphone_chat_message_ref (LinphoneChatMessage *msg); /** * Release reference to the chat message. - * @param[in] cr The chat message. -**/ -LINPHONE_PUBLIC void linphone_chat_message_unref(LinphoneChatMessage *msg); + * @param[in] msg #LinphoneChatMessage object. + */ +LINPHONE_PUBLIC void linphone_chat_message_unref (LinphoneChatMessage *msg); /** * Retrieve the user pointer associated with the chat message. - * @param[in] cr The chat message. + * @param[in] msg #LinphoneChatMessage object. * @return The user pointer associated with the chat message. -**/ -LINPHONE_PUBLIC void *linphone_chat_message_get_user_data(const LinphoneChatMessage *msg); + */ +LINPHONE_PUBLIC void *linphone_chat_message_get_user_data (const LinphoneChatMessage *msg); /** * Assign a user pointer to the chat message. - * @param[in] cr The chat message. + * @param[in] msg #LinphoneChatMessage object. * @param[in] ud The user pointer to associate with the chat message. -**/ -LINPHONE_PUBLIC void linphone_chat_message_set_user_data(LinphoneChatMessage *msg, void *ud); + */ +LINPHONE_PUBLIC void linphone_chat_message_set_user_data (LinphoneChatMessage *msg, void *ud); // ============================================================================= -LINPHONE_PUBLIC const char * linphone_chat_message_get_external_body_url(const LinphoneChatMessage *msg); +LINPHONE_PUBLIC const char *linphone_chat_message_get_external_body_url (const LinphoneChatMessage *msg); -LINPHONE_PUBLIC void linphone_chat_message_set_external_body_url(LinphoneChatMessage *msg, const char *external_body_url); +LINPHONE_PUBLIC void linphone_chat_message_set_external_body_url (LinphoneChatMessage *msg, const char *external_body_url); /** * Get the time the message was sent. + * @param[in] msg #LinphoneChatMessage object. */ -LINPHONE_PUBLIC time_t linphone_chat_message_get_time(const LinphoneChatMessage* msg); +LINPHONE_PUBLIC time_t linphone_chat_message_get_time (const LinphoneChatMessage *msg); /** * Returns TRUE if the message has been sent, returns FALSE if the message has been received. - * @param message the message -**/ -LINPHONE_PUBLIC bool_t linphone_chat_message_is_outgoing(LinphoneChatMessage* msg); + * @param[in] msg #LinphoneChatMessage object. + */ +LINPHONE_PUBLIC bool_t linphone_chat_message_is_outgoing (LinphoneChatMessage *msg); /** * Get origin of the message - * @param[in] message #LinphoneChatMessage obj + * @param[in] msg #LinphoneChatMessage object. * @return #LinphoneAddress */ -LINPHONE_PUBLIC const LinphoneAddress* linphone_chat_message_get_from_address(LinphoneChatMessage* msg); +LINPHONE_PUBLIC const LinphoneAddress *linphone_chat_message_get_from_address (LinphoneChatMessage *msg); /** * Get destination of the message - * @param[in] message #LinphoneChatMessage obj + * @param[in] msg #LinphoneChatMessage object. * @return #LinphoneAddress */ -LINPHONE_PUBLIC const LinphoneAddress* linphone_chat_message_get_to_address(LinphoneChatMessage* msg); +LINPHONE_PUBLIC const LinphoneAddress *linphone_chat_message_get_to_address (LinphoneChatMessage *msg); /** * Get the content type of a chat message. - * @param[in] message LinphoneChatMessage object + * @param[in] msg #LinphoneChatMessage object. * @return The content type of the chat message */ -LINPHONE_PUBLIC const char * linphone_chat_message_get_content_type(LinphoneChatMessage *msg); +LINPHONE_PUBLIC const char *linphone_chat_message_get_content_type (LinphoneChatMessage *msg); /** * Set the content type of a chat message. * This content type must match a content that is text representable, such as text/plain, text/html or image/svg+xml. - * @param[in] message LinphoneChatMessage object + * @param[in] msg #LinphoneChatMessage object. * @param[in] content_type The new content type of the chat message */ -LINPHONE_PUBLIC void linphone_chat_message_set_content_type(LinphoneChatMessage *msg, const char *content_type); +LINPHONE_PUBLIC void linphone_chat_message_set_content_type (LinphoneChatMessage *msg, const char *content_type); /** * Get text part of this message + * @param[in] msg #LinphoneChatMessage object. * @return text or NULL if no text. * @deprecated use getTextContent() instead */ -LINPHONE_PUBLIC const char* linphone_chat_message_get_text(LinphoneChatMessage* msg); +LINPHONE_PUBLIC const char *linphone_chat_message_get_text (LinphoneChatMessage* msg); /** * Get the message identifier. * It is used to identify a message so that it can be notified as delivered and/or displayed. - * @param[in] cm LinphoneChatMessage object + * @param[in] msg #LinphoneChatMessage object. * @return The message identifier. */ -LINPHONE_PUBLIC const char* linphone_chat_message_get_message_id(const LinphoneChatMessage *msg); +LINPHONE_PUBLIC const char *linphone_chat_message_get_message_id (const LinphoneChatMessage *msg); /** * Linphone message has an app-specific field that can store a text. The application might want * to use it for keeping data over restarts, like thumbnail image path. - * @param message #LinphoneChatMessage + * @param[in] msg #LinphoneChatMessage object. * @return the application-specific data or NULL if none has been stored. */ -LINPHONE_PUBLIC const char* linphone_chat_message_get_appdata(const LinphoneChatMessage* message); +LINPHONE_PUBLIC const char *linphone_chat_message_get_appdata (const LinphoneChatMessage *msg); /** * Linphone message has an app-specific field that can store a text. The application might want @@ -148,228 +150,244 @@ LINPHONE_PUBLIC const char* linphone_chat_message_get_appdata(const LinphoneChat * Invoking this function will attempt to update the message storage to reflect the changeif it is * enabled. * - * @param message #LinphoneChatMessage + * @param[in] msg #LinphoneChatMessage object. * @param data the data to store into the message */ -LINPHONE_PUBLIC void linphone_chat_message_set_appdata(LinphoneChatMessage* message, const char* data); +LINPHONE_PUBLIC void linphone_chat_message_set_appdata (LinphoneChatMessage *msg, const char *data); /** * Returns the chatroom this message belongs to. -**/ -LINPHONE_PUBLIC LinphoneChatRoom* linphone_chat_message_get_chat_room(const LinphoneChatMessage *msg); + * @param[in] msg #LinphoneChatMessage object. + */ +LINPHONE_PUBLIC LinphoneChatRoom *linphone_chat_message_get_chat_room (const LinphoneChatMessage *msg); /** * Get the path to the file to read from or write to during the file transfer. - * @param[in] msg LinphoneChatMessage object + * @param[in] msg #LinphoneChatMessage object * @return The path to the file to use for the file transfer. */ -LINPHONE_PUBLIC const char * linphone_chat_message_get_file_transfer_filepath(LinphoneChatMessage *msg); +LINPHONE_PUBLIC const char *linphone_chat_message_get_file_transfer_filepath (LinphoneChatMessage *msg); // ============================================================================= /** * Get if a chat message is to be stored. - * @param[in] message LinphoneChatMessage object + * @param[in] msg #LinphoneChatMessage object. * @return Whether or not the message is to be stored */ -LINPHONE_PUBLIC bool_t linphone_chat_message_get_to_be_stored(const LinphoneChatMessage *message); +LINPHONE_PUBLIC bool_t linphone_chat_message_get_to_be_stored (const LinphoneChatMessage *msg); /** * Set if a chat message is to be stored. * This content type must match a content that is text representable, such as text/plain, text/html or image/svg+xml. - * @param[in] message LinphoneChatMessage object + * @param[in] msg #LinphoneChatMessage object. * @param[in] to_be_stored Whether or not the chat message is to be stored */ -LINPHONE_PUBLIC void linphone_chat_message_set_to_be_stored(LinphoneChatMessage *message, bool_t to_be_stored); +LINPHONE_PUBLIC void linphone_chat_message_set_to_be_stored (LinphoneChatMessage *msg, bool_t to_be_stored); -LINPHONE_PUBLIC unsigned int linphone_chat_message_store(LinphoneChatMessage *msg); +LINPHONE_PUBLIC unsigned int linphone_chat_message_store (LinphoneChatMessage *msg); /** * Get the state of the message - *@param message #LinphoneChatMessage obj - *@return #LinphoneChatMessageState + * @param[in] msg #LinphoneChatMessage object. + * @return #LinphoneChatMessageState */ -LINPHONE_PUBLIC LinphoneChatMessageState linphone_chat_message_get_state(const LinphoneChatMessage* message); +LINPHONE_PUBLIC LinphoneChatMessageState linphone_chat_message_get_state (const LinphoneChatMessage *msg); /** * Get if the message was encrypted when transfered - * @param[in] message #LinphoneChatMessage obj + * @param[in] msg #LinphoneChatMessage object. * @return whether the message was encrypted when transfered or not */ -LINPHONE_PUBLIC bool_t linphone_chat_message_is_secured(LinphoneChatMessage *msg); +LINPHONE_PUBLIC bool_t linphone_chat_message_is_secured (LinphoneChatMessage *msg); /** * Linphone message can carry external body as defined by rfc2017 - * @param message #LinphoneChatMessage + * @param[in] msg #LinphoneChatMessage object. * @return external body url or NULL if not present. */ -LINPHONE_PUBLIC const char* linphone_chat_message_get_external_body_url(const LinphoneChatMessage* message); +LINPHONE_PUBLIC const char *linphone_chat_message_get_external_body_url (const LinphoneChatMessage *msg); /** * Linphone message can carry external body as defined by rfc2017 * - * @param message a LinphoneChatMessage + * @param[in] msg #LinphoneChatMessage object. * @param url ex: access-type=URL; URL="http://www.foo.com/file" */ -LINPHONE_PUBLIC void linphone_chat_message_set_external_body_url(LinphoneChatMessage* message,const char* url); +LINPHONE_PUBLIC void linphone_chat_message_set_external_body_url (LinphoneChatMessage *msg,const char *url); /** * Get the file_transfer_information (used by call backs to recover informations during a rcs file transfer) * - * @param message #LinphoneChatMessage - * @return a pointer to the LinphoneContent structure or NULL if not present. + * @param[in] msg #LinphoneChatMessage object. + * @return a pointer to the #LinphoneContent structure or NULL if not present. */ -LINPHONE_PUBLIC LinphoneContent* linphone_chat_message_get_file_transfer_information(LinphoneChatMessage* message); +LINPHONE_PUBLIC LinphoneContent *linphone_chat_message_get_file_transfer_information (LinphoneChatMessage *msg); /** * Return whether or not a chat message is a file tranfer. - * @param[in] message LinphoneChatMessage object + * @param[in] msg #LinphoneChatMessage object * @return Whether or not the message is a file tranfer */ -LINPHONE_PUBLIC bool_t linphone_chat_message_is_file_transfer(LinphoneChatMessage *message); +LINPHONE_PUBLIC bool_t linphone_chat_message_is_file_transfer (LinphoneChatMessage *msg); /** * Return whether or not a chat message is a text. - * @param[in] message LinphoneChatMessage object + * @param[in] msg #LinphoneChatMessage object. * @return Whether or not the message is a text */ -LINPHONE_PUBLIC bool_t linphone_chat_message_is_text(LinphoneChatMessage *message); +LINPHONE_PUBLIC bool_t linphone_chat_message_is_text (LinphoneChatMessage *msg); /** * Start the download of the file from remote server * - * @param message #LinphoneChatMessage - * @param status_cb LinphoneChatMessageStateChangeCb status callback invoked when file is downloaded or could not be downloaded + * @param[in] msg #LinphoneChatMessage object. + * @param status_cb #LinphoneChatMessageStateChangeCb status callback invoked when file is downloaded or could not be downloaded * @param ud user data * @deprecated Use linphone_chat_message_download_file() instead. * @donotwrap */ -LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_chat_message_start_file_download(LinphoneChatMessage* message, LinphoneChatMessageStateChangedCb status_cb, void* ud); +LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_chat_message_start_file_download ( + LinphoneChatMessage *msg, + LinphoneChatMessageStateChangedCb status_cb, + void *ud +); /** - * Start the download of the file referenced in a LinphoneChatMessage from remote server. - * @param[in] message LinphoneChatMessage object. + * Start the download of the file referenced in a #LinphoneChatMessage from remote server. + * @param[in] msg #LinphoneChatMessage object. */ -LINPHONE_PUBLIC LinphoneStatus linphone_chat_message_download_file(LinphoneChatMessage *message); +LINPHONE_PUBLIC bool_t linphone_chat_message_download_file (LinphoneChatMessage *msg); /** * Cancel an ongoing file transfer attached to this message.(upload or download) - * @param msg #LinphoneChatMessage + * @param[in] msg #LinphoneChatMessage object. */ -LINPHONE_PUBLIC void linphone_chat_message_cancel_file_transfer(LinphoneChatMessage* msg); +LINPHONE_PUBLIC void linphone_chat_message_cancel_file_transfer (LinphoneChatMessage *msg); /** * Send a chat message. - * @param[in] msg LinphoneChatMessage object + * @param[in] msg #LinphoneChatMessage object. */ LINPHONE_PUBLIC void linphone_chat_message_send (LinphoneChatMessage *msg); /** * Resend a chat message if it is in the 'not delivered' state for whatever reason. - * @param[in] msg LinphoneChatMessage object + * @param[in] msg #LinphoneChatMessage object. * @deprecated Use linphone_chat_message_send instead. * @donotwrap */ -LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_chat_message_resend(LinphoneChatMessage *msg); +LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_chat_message_resend (LinphoneChatMessage *msg); -LINPHONE_PUBLIC const LinphoneAddress* linphone_chat_message_get_peer_address(LinphoneChatMessage *msg); +LINPHONE_PUBLIC const LinphoneAddress *linphone_chat_message_get_peer_address (LinphoneChatMessage *msg); /** * Returns the origin address of a message if it was a outgoing message, or the destination address if it was an incoming message. - *@param message #LinphoneChatMessage obj - *@return #LinphoneAddress + * @param[in] msg #LinphoneChatMessage object. + * @return #LinphoneAddress */ -LINPHONE_PUBLIC const LinphoneAddress *linphone_chat_message_get_local_address(LinphoneChatMessage* message); +LINPHONE_PUBLIC const LinphoneAddress *linphone_chat_message_get_local_address (LinphoneChatMessage *msg); /** * Add custom headers to the message. - * @param message the message + * @param[in] msg #LinphoneChatMessage object. * @param header_name name of the header * @param header_value header value -**/ -LINPHONE_PUBLIC void linphone_chat_message_add_custom_header(LinphoneChatMessage* message, const char *header_name, const char *header_value); + */ +LINPHONE_PUBLIC void linphone_chat_message_add_custom_header ( + LinphoneChatMessage *msg, + const char *header_name, + const char *header_value +); /** * Retrieve a custom header value given its name. - * @param message the message + * @param[in] msg #LinphoneChatMessage object. * @param header_name header name searched -**/ -LINPHONE_PUBLIC const char * linphone_chat_message_get_custom_header(LinphoneChatMessage* message, const char *header_name); + */ +LINPHONE_PUBLIC const char * linphone_chat_message_get_custom_header (LinphoneChatMessage *msg, const char *header_name); /** * Removes a custom header from the message. - * @param msg the message + * @param[in] msg #LinphoneChatMessage object. * @param header_name name of the header to remove -**/ -LINPHONE_PUBLIC void linphone_chat_message_remove_custom_header(LinphoneChatMessage *msg, const char *header_name); + */ +LINPHONE_PUBLIC void linphone_chat_message_remove_custom_header (LinphoneChatMessage *msg, const char *header_name); /** * Returns TRUE if the message has been read, otherwise returns FALSE. - * @param message the message -**/ -LINPHONE_PUBLIC bool_t linphone_chat_message_is_read(LinphoneChatMessage* message); + * @param[in] msg #LinphoneChatMessage object. + */ +LINPHONE_PUBLIC bool_t linphone_chat_message_is_read (LinphoneChatMessage *msg); -LINPHONE_PUBLIC LinphoneReason linphone_chat_message_get_reason(LinphoneChatMessage* msg); +LINPHONE_PUBLIC LinphoneReason linphone_chat_message_get_reason (LinphoneChatMessage *msg); /** * Get full details about delivery error of a chat message. - * @param msg a LinphoneChatMessage - * @return a LinphoneErrorInfo describing the details. -**/ -LINPHONE_PUBLIC const LinphoneErrorInfo *linphone_chat_message_get_error_info(const LinphoneChatMessage *msg); + * @param[in] msg #LinphoneChatMessage object. + * @return a #LinphoneErrorInfo describing the details. + */ +LINPHONE_PUBLIC const LinphoneErrorInfo *linphone_chat_message_get_error_info (const LinphoneChatMessage *msg); /** * Set the path to the file to read from or write to during the file transfer. - * @param[in] msg LinphoneChatMessage object + * @param[in] msg #LinphoneChatMessage object. * @param[in] filepath The path to the file to use for the file transfer. */ -LINPHONE_PUBLIC void linphone_chat_message_set_file_transfer_filepath(LinphoneChatMessage *msg, const char *filepath); +LINPHONE_PUBLIC void linphone_chat_message_set_file_transfer_filepath (LinphoneChatMessage *msg, const char *filepath); /** * Fulfill a chat message char by char. Message linked to a Real Time Text Call send char in realtime following RFC 4103/T.140 * To commit a message, use #linphone_chat_room_send_message - * @param[in] msg LinphoneChatMessage + * @param[in] msg #LinphoneChatMessage object. * @param[in] character T.140 char * @returns 0 if succeed. */ -LINPHONE_PUBLIC LinphoneStatus linphone_chat_message_put_char(LinphoneChatMessage *msg,uint32_t character); +LINPHONE_PUBLIC LinphoneStatus linphone_chat_message_put_char (LinphoneChatMessage *msg, uint32_t character); /** - * Get the LinphoneChatMessageCbs object associated with the LinphoneChatMessage. - * @param[in] msg LinphoneChatMessage object - * @return The LinphoneChatMessageCbs object associated with the LinphoneChatMessage. + * Get the #LinphoneChatMessageCbs object associated with the LinphoneChatMessage. + * @param[in] msg #LinphoneChatMessage object. + * @return The #LinphoneChatMessageCbs object associated with the LinphoneChatMessage. */ -LINPHONE_PUBLIC LinphoneChatMessageCbs * linphone_chat_message_get_callbacks(const LinphoneChatMessage *msg); +LINPHONE_PUBLIC LinphoneChatMessageCbs *linphone_chat_message_get_callbacks (const LinphoneChatMessage *msg); /** * Adds a content to the ChatMessage - * @param[in] msg LinphoneChatMessage object - * @param[in] c_content LinphoneContent object + * @param[in] msg #LinphoneChatMessage object. + * @param[in] c_content #LinphoneContent object */ -LINPHONE_PUBLIC void linphone_chat_message_add_text_content(LinphoneChatMessage *msg, const char *c_content); +LINPHONE_PUBLIC void linphone_chat_message_add_text_content (LinphoneChatMessage *msg, const char *c_content); /** * Returns true if the chat message has a text content - * @param[in] msg LinphoneChatMessage object + * @param[in] msg #LinphoneChatMessage object. * @return true if it has one, false otherwise */ -LINPHONE_PUBLIC bool_t linphone_chat_message_has_text_content(const LinphoneChatMessage *msg); +LINPHONE_PUBLIC bool_t linphone_chat_message_has_text_content (const LinphoneChatMessage *msg); /** * Gets the text content if available as a string - * @param[in] msg LinphoneChatMessage object - * @return the LinphoneContent buffer if available, null otherwise + * @param[in] msg #LinphoneChatMessage object. + * @return the #LinphoneContent buffer if available, null otherwise */ -LINPHONE_PUBLIC const char* linphone_chat_message_get_text_content(const LinphoneChatMessage *msg); +LINPHONE_PUBLIC const char *linphone_chat_message_get_text_content (const LinphoneChatMessage *msg); /** * Gets whether or not a file is currently being downloaded or uploaded - * @param[in] msg LinphoneChatMessage object + * @param[in] msg #LinphoneChatMessage object. * @return true if download or upload is in progress, false otherwise */ -LINPHONE_PUBLIC bool_t linphone_chat_message_is_file_transfer_in_progress(LinphoneChatMessage *msg); +LINPHONE_PUBLIC bool_t linphone_chat_message_is_file_transfer_in_progress (LinphoneChatMessage *msg); -LINPHONE_PUBLIC bctbx_list_t *linphone_chat_message_get_participants_in_state (const LinphoneChatMessage *msg, const LinphoneChatMessageState state); +/** + * Gets the list of participants for which the imdn state has reached the specified state and the time at which they did. + * @param[in] msg #LinphoneChatMessage object. + * @param[in] state The LinphoneChatMessageState the imdn have reached (only use LinphoneChatMessageStateDelivered, + * LinphoneChatMessageStateDeliveredToUser, LinphoneChatMessageStateDisplayed and LinphoneChatMessageStateNotDelivered) + * @return \bctbx_list{LinphoneParticipantImdnState} + */ +LINPHONE_PUBLIC bctbx_list_t *linphone_chat_message_get_participants_by_imdn_state (const LinphoneChatMessage *msg, LinphoneChatMessageState state); /** * @} diff --git a/include/linphone/api/c-chat-room-cbs.h b/include/linphone/api/c-chat-room-cbs.h index 6cbf7bd91..b60a1d1b1 100644 --- a/include/linphone/api/c-chat-room-cbs.h +++ b/include/linphone/api/c-chat-room-cbs.h @@ -63,210 +63,238 @@ LINPHONE_PUBLIC void linphone_chat_room_cbs_set_user_data (LinphoneChatRoomCbs * /** * Get the is-composing received callback. - * @param[in] cbs LinphoneChatRoomCbs object. + * @param[in] cbs #LinphoneChatRoomCbs object. * @return The current is-composing received callback. */ LINPHONE_PUBLIC LinphoneChatRoomCbsIsComposingReceivedCb linphone_chat_room_cbs_get_is_composing_received (const LinphoneChatRoomCbs *cbs); /** * Set the is-composing received callback. - * @param[in] cbs LinphoneChatRoomCbs object. + * @param[in] cbs #LinphoneChatRoomCbs object. * @param[in] cb The is-composing received callback to be used. */ LINPHONE_PUBLIC void linphone_chat_room_cbs_set_is_composing_received (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsIsComposingReceivedCb cb); /** * Get the message received callback. - * @param[in] cbs LinphoneChatRoomCbs object. + * @param[in] cbs #LinphoneChatRoomCbs object. * @return The current message received callback. */ LINPHONE_PUBLIC LinphoneChatRoomCbsMessageReceivedCb linphone_chat_room_cbs_get_message_received (const LinphoneChatRoomCbs *cbs); /** * Set the message received callback. - * @param[in] cbs LinphoneChatRoomCbs object. + * @param[in] cbs #LinphoneChatRoomCbs object. * @param[in] cb The message received callback to be used. */ LINPHONE_PUBLIC void linphone_chat_room_cbs_set_message_received (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsMessageReceivedCb cb); /** * Get the chat message received callback. - * @param[in] cbs LinphoneChatRoomCbs object. + * @param[in] cbs #LinphoneChatRoomCbs object. * @return The current chat message received callback. */ LINPHONE_PUBLIC LinphoneChatRoomCbsChatMessageReceivedCb linphone_chat_room_cbs_get_chat_message_received (const LinphoneChatRoomCbs *cbs); /** * Set the chat message received callback. - * @param[in] cbs LinphoneChatRoomCbs object. + * @param[in] cbs #LinphoneChatRoomCbs object. * @param[in] cb The chat message received callback to be used. */ LINPHONE_PUBLIC void linphone_chat_room_cbs_set_chat_message_received (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsChatMessageReceivedCb cb); /** * Get the chat message sent callback. - * @param[in] cbs LinphoneChatRoomCbs object. + * @param[in] cbs #LinphoneChatRoomCbs object. * @return The current chat message sent callback. */ LINPHONE_PUBLIC LinphoneChatRoomCbsChatMessageSentCb linphone_chat_room_cbs_get_chat_message_sent (const LinphoneChatRoomCbs *cbs); /** * Set the chat message sent callback. - * @param[in] cbs LinphoneChatRoomCbs object. + * @param[in] cbs #LinphoneChatRoomCbs object. * @param[in] cb The chat message sent callback to be used. */ LINPHONE_PUBLIC void linphone_chat_room_cbs_set_chat_message_sent (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsChatMessageSentCb cb); /** * Get the participant added callback. - * @param[in] cbs LinphoneChatRoomCbs object. + * @param[in] cbs #LinphoneChatRoomCbs object. * @return The current participant added callback. */ LINPHONE_PUBLIC LinphoneChatRoomCbsParticipantAddedCb linphone_chat_room_cbs_get_participant_added (const LinphoneChatRoomCbs *cbs); /** * Set the participant added callback. - * @param[in] cbs LinphoneChatRoomCbs object. + * @param[in] cbs #LinphoneChatRoomCbs object. * @param[in] cb The participant added callback to be used. */ LINPHONE_PUBLIC void linphone_chat_room_cbs_set_participant_added (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantAddedCb cb); /** * Get the participant removed callback. - * @param[in] cbs LinphoneChatRoomCbs object. + * @param[in] cbs #LinphoneChatRoomCbs object. * @return The current participant removed callback. */ LINPHONE_PUBLIC LinphoneChatRoomCbsParticipantRemovedCb linphone_chat_room_cbs_get_participant_removed (const LinphoneChatRoomCbs *cbs); /** * Set the participant removed callback. - * @param[in] cbs LinphoneChatRoomCbs object. + * @param[in] cbs #LinphoneChatRoomCbs object. * @param[in] cb The participant removed callback to be used. */ LINPHONE_PUBLIC void linphone_chat_room_cbs_set_participant_removed (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantRemovedCb cb); /** * Get the participant admin status changed callback. - * @param[in] cbs LinphoneChatRoomCbs object. + * @param[in] cbs #LinphoneChatRoomCbs object. * @return The current participant admin status changed callback. */ LINPHONE_PUBLIC LinphoneChatRoomCbsParticipantAdminStatusChangedCb linphone_chat_room_cbs_get_participant_admin_status_changed (const LinphoneChatRoomCbs *cbs); /** * Set the participant admin status changed callback. - * @param[in] cbs LinphoneChatRoomCbs object. + * @param[in] cbs #LinphoneChatRoomCbs object. * @param[in] cb The participant admin status changed callback to be used. */ LINPHONE_PUBLIC void linphone_chat_room_cbs_set_participant_admin_status_changed (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantAdminStatusChangedCb cb); /** * Get the state changed callback. - * @param[in] cbs LinphoneChatRoomCbs object. + * @param[in] cbs #LinphoneChatRoomCbs object. * @return The current state changed callback. */ LINPHONE_PUBLIC LinphoneChatRoomCbsStateChangedCb linphone_chat_room_cbs_get_state_changed (const LinphoneChatRoomCbs *cbs); /** * Set the state changed callback. - * @param[in] cbs LinphoneChatRoomCbs object. + * @param[in] cbs #LinphoneChatRoomCbs object. * @param[in] cb The state changed callback to be used. */ LINPHONE_PUBLIC void linphone_chat_room_cbs_set_state_changed (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsStateChangedCb cb); /** * Get the subject changed callback. - * @param[in] cbs LinphoneChatRoomCbs object. + * @param[in] cbs #LinphoneChatRoomCbs object. * @return The current subject changed callback. */ LINPHONE_PUBLIC LinphoneChatRoomCbsSubjectChangedCb linphone_chat_room_cbs_get_subject_changed (const LinphoneChatRoomCbs *cbs); /** * Set the subject changed callback. - * @param[in] cbs LinphoneChatRoomCbs object. + * @param[in] cbs #LinphoneChatRoomCbs object. * @param[in] cb The subject changed callback to be used. */ LINPHONE_PUBLIC void linphone_chat_room_cbs_set_subject_changed (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsSubjectChangedCb cb); /** * Get the undecryptable message received callback. - * @param[in] cbs LinphoneChatRoomCbs object. + * @param[in] cbs #LinphoneChatRoomCbs object. * @return The current undecryptable message received callback. */ LINPHONE_PUBLIC LinphoneChatRoomCbsUndecryptableMessageReceivedCb linphone_chat_room_cbs_get_undecryptable_message_received (const LinphoneChatRoomCbs *cbs); /** * Set the undecryptable message received callback. - * @param[in] cbs LinphoneChatRoomCbs object. + * @param[in] cbs #LinphoneChatRoomCbs object. * @param[in] cb The undecryptable message received callback to be used. */ LINPHONE_PUBLIC void linphone_chat_room_cbs_set_undecryptable_message_received (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsUndecryptableMessageReceivedCb cb); /** * Get the participant device added callback. - * @param[in] cbs LinphoneChatRoomCbs object. + * @param[in] cbs #LinphoneChatRoomCbs object. * @return The current participant device added callback. */ LINPHONE_PUBLIC LinphoneChatRoomCbsParticipantDeviceAddedCb linphone_chat_room_cbs_get_participant_device_added (const LinphoneChatRoomCbs *cbs); /** * Set the participant device added callback. - * @param[in] cbs LinphoneChatRoomCbs object. + * @param[in] cbs #LinphoneChatRoomCbs object. * @param[in] cb The participant device added callback to be used. */ LINPHONE_PUBLIC void linphone_chat_room_cbs_set_participant_device_added (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantDeviceAddedCb cb); /** * Get the participant device removed callback. - * @param[in] cbs LinphoneChatRoomCbs object. + * @param[in] cbs #LinphoneChatRoomCbs object. * @return The current participant device removed callback. */ LINPHONE_PUBLIC LinphoneChatRoomCbsParticipantDeviceRemovedCb linphone_chat_room_cbs_get_participant_device_removed (const LinphoneChatRoomCbs *cbs); /** * Set the participant device removed callback. - * @param[in] cbs LinphoneChatRoomCbs object. + * @param[in] cbs #LinphoneChatRoomCbs object. * @param[in] cb The participant device removed callback to be used. */ LINPHONE_PUBLIC void linphone_chat_room_cbs_set_participant_device_removed (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantDeviceRemovedCb cb); +/** + * Get the conference joined callback. + * @param[in] cbs LinphoneChatRoomCbs object. + * @return The current conference joined callback. + */ +LINPHONE_PUBLIC LinphoneChatRoomCbsConferenceJoinedCb linphone_chat_room_cbs_get_conference_joined (const LinphoneChatRoomCbs *cbs); + +/** + * Set the conference joined callback. + * @param[in] cbs LinphoneChatRoomCbs object. + * @param[in] cb The conference joined callback to be used. + */ +LINPHONE_PUBLIC void linphone_chat_room_cbs_set_conference_joined (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsConferenceJoinedCb cb); + +/** + * Get the conference left callback. + * @param[in] cbs LinphoneChatRoomCbs object. + * @return The current conference left callback. + */ +LINPHONE_PUBLIC LinphoneChatRoomCbsConferenceLeftCb linphone_chat_room_cbs_get_conference_left (const LinphoneChatRoomCbs *cbs); + +/** + * Set the conference left callback. + * @param[in] cbs LinphoneChatRoomCbs object. + * @param[in] cb The conference left callback to be used. + */ +LINPHONE_PUBLIC void linphone_chat_room_cbs_set_conference_left (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsConferenceLeftCb cb); + /** * Get the conference address generation callback. - * @param[in] cbs LinphoneChatRoomCbs object + * @param[in] cbs #LinphoneChatRoomCbs object * @return The current conference address generation callback */ LINPHONE_PUBLIC LinphoneChatRoomCbsConferenceAddressGenerationCb linphone_chat_room_cbs_get_conference_address_generation (const LinphoneChatRoomCbs *cbs); /** * Set the conference address generation callback. - * @param[in] cbs LinphoneChatRoomCbs object + * @param[in] cbs #LinphoneChatRoomCbs object * @param[in] cb The conference address generation callback to be used */ LINPHONE_PUBLIC void linphone_chat_room_cbs_set_conference_address_generation (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsConferenceAddressGenerationCb cb); /** * Get the participant device fetching callback. - * @param[in] cbs LinphoneChatRoomCbs object + * @param[in] cbs #LinphoneChatRoomCbs object * @return The participant device fetching callback */ LINPHONE_PUBLIC LinphoneChatRoomCbsParticipantDeviceFetchRequestedCb linphone_chat_room_cbs_get_participant_device_fetch_requested (const LinphoneChatRoomCbs *cbs); /** * Set the participant device fetching callback. - * @param[in] cbs LinphoneChatRoomCbs object + * @param[in] cbs #LinphoneChatRoomCbs object * @param[in] cb The participant device fetching callback to be used */ LINPHONE_PUBLIC void linphone_chat_room_cbs_set_participant_device_fetch_requested (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantDeviceFetchRequestedCb cb); /** * Get the participants capabilities callback. - * @param[in] cbs LinphoneChatRoomCbs object + * @param[in] cbs #LinphoneChatRoomCbs object * @return The participants capabilities getting callback */ LINPHONE_PUBLIC LinphoneChatRoomCbsParticipantsCapabilitiesCheckedCb linphone_chat_room_cbs_get_participants_capabilities_checked (const LinphoneChatRoomCbs *cbs); /** * Set the participants capabilities callback. - * @param[in] cbs LinphoneChatRoomCbs object + * @param[in] cbs #LinphoneChatRoomCbs object * @param[in] cb The participants capabilities callback to be used */ LINPHONE_PUBLIC void linphone_chat_room_cbs_set_participants_capabilities_checked (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantsCapabilitiesCheckedCb cb); diff --git a/include/linphone/api/c-chat-room.h b/include/linphone/api/c-chat-room.h index 41f3c669e..b3a98453c 100644 --- a/include/linphone/api/c-chat-room.h +++ b/include/linphone/api/c-chat-room.h @@ -90,7 +90,7 @@ LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_message_2(Linphon * @param initial_content #LinphoneContent initial content. #LinphoneCoreVTable.file_transfer_send is invoked later to notify file transfer progress and collect next chunk of the message if LinphoneContent.data is NULL. * @return a new #LinphoneChatMessage */ -LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_file_transfer_message(LinphoneChatRoom *cr, const LinphoneContent* initial_content); +LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_file_transfer_message(LinphoneChatRoom *cr, LinphoneContent* initial_content); /** * get peer address \link linphone_core_get_chat_room() associated to \endlink this #LinphoneChatRoom @@ -118,11 +118,11 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_chat_room_send_message(Linphon /** * Send a message to peer member of this chat room. - * @param[in] cr LinphoneChatRoom object - * @param[in] msg LinphoneChatMessage object - * The state of the message sending will be notified via the callbacks defined in the LinphoneChatMessageCbs object that can be obtained + * @param[in] cr #LinphoneChatRoom object + * @param[in] msg #LinphoneChatMessage object + * The state of the message sending will be notified via the callbacks defined in the #LinphoneChatMessageCbs object that can be obtained * by calling linphone_chat_message_get_callbacks(). - * The LinphoneChatMessage reference is transfered to the function and thus doesn't need to be unref'd by the application. + * The #LinphoneChatMessage reference is transfered to the function and thus doesn't need to be unref'd by the application. * @deprecated Use linphone_chat_message_send() instead. * @donotwrap */ @@ -130,8 +130,8 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_chat_room_send_chat_message(Li /** * Used to receive a chat message when using async mechanism with IM encryption engine - * @param[in] cr LinphoneChatRoom object - * @param[in] msg LinphoneChatMessage object + * @param[in] cr #LinphoneChatRoom object + * @param[in] msg #LinphoneChatMessage object */ LINPHONE_PUBLIC void linphone_chat_room_receive_chat_message (LinphoneChatRoom *cr, LinphoneChatMessage *msg); @@ -278,16 +278,16 @@ LINPHONE_PUBLIC bool_t linphone_chat_room_lime_available(LinphoneChatRoom *cr); /** * get Curent Call associated to this chatroom if any * To commit a message, use #linphone_chat_room_send_message - * @param[in] room LinphoneChatRomm - * @returns LinphoneCall or NULL. + * @param[in] room #LinphoneChatRomm + * @returns #LinphoneCall or NULL. */ LINPHONE_PUBLIC LinphoneCall *linphone_chat_room_get_call(const LinphoneChatRoom *room); /** - * Add a listener in order to be notified of LinphoneChatRoom events. Once an event is received, registred LinphoneChatRoomCbs are + * Add a listener in order to be notified of #LinphoneChatRoom events. Once an event is received, registred #LinphoneChatRoomCbs are * invoked sequencially. - * @param[in] call LinphoneChatRoom object to monitor. - * @param[in] cbs A LinphoneChatRoomCbs object holding the callbacks you need. A reference is taken by the LinphoneChatRoom until you invoke linphone_call_remove_callbacks(). + * @param[in] call #LinphoneChatRoom object to monitor. + * @param[in] cbs A #LinphoneChatRoomCbs object holding the callbacks you need. A reference is taken by the #LinphoneChatRoom until you invoke linphone_call_remove_callbacks(). */ LINPHONE_PUBLIC void linphone_chat_room_add_callbacks(LinphoneChatRoom *cr, LinphoneChatRoomCbs *cbs); @@ -308,14 +308,14 @@ LINPHONE_PUBLIC LinphoneChatRoomCbs *linphone_chat_room_get_current_callbacks(co /** * Get the state of the chat room. - * @param[in] cr LinphoneChatRoom object + * @param[in] cr #LinphoneChatRoom object * @return The state of the chat room */ LINPHONE_PUBLIC LinphoneChatRoomState linphone_chat_room_get_state (const LinphoneChatRoom *cr); /** * Return whether or not the chat room has been left. - * @param[in] cr LinphoneChatRoom object + * @param[in] cr #LinphoneChatRoom object * @return whether or not the chat room has been left */ LINPHONE_PUBLIC bool_t linphone_chat_room_has_been_left (const LinphoneChatRoom *cr); @@ -330,7 +330,7 @@ LINPHONE_PUBLIC time_t linphone_chat_room_get_last_update_time(const LinphoneCha /** * Add a participant to a chat room. This may fail if this type of chat room does not handle participants. * Use linphone_chat_room_can_handle_participants() to know if this chat room handles participants. - * @param[in] cr A LinphoneChatRoom object + * @param[in] cr A #LinphoneChatRoom object * @param[in] addr The address of the participant to add to the chat room */ LINPHONE_PUBLIC void linphone_chat_room_add_participant (LinphoneChatRoom *cr, const LinphoneAddress *addr); @@ -338,21 +338,21 @@ LINPHONE_PUBLIC void linphone_chat_room_add_participant (LinphoneChatRoom *cr, c /** * Add several participants to a chat room at once. This may fail if this type of chat room does not handle participants. * Use linphone_chat_room_can_handle_participants() to know if this chat room handles participants. - * @param[in] cr A LinphoneChatRoom object + * @param[in] cr A #LinphoneChatRoom object * @param[in] addresses \bctbx_list{LinphoneAddress} */ LINPHONE_PUBLIC void linphone_chat_room_add_participants (LinphoneChatRoom *cr, const bctbx_list_t *addresses); /** * Tells whether a chat room is able to handle participants. - * @param[in] cr A LinphoneChatRoom object + * @param[in] cr A #LinphoneChatRoom object * @return A boolean value telling whether the chat room can handle participants or not */ LINPHONE_PUBLIC bool_t linphone_chat_room_can_handle_participants (const LinphoneChatRoom *cr); /** * Find a participant of a chat room from its address. - * @param[in] cr A LinphoneChatRoom object + * @param[in] cr A #LinphoneChatRoom object * @param[in] addr The address to search in the list of participants of the chat room * @return The participant if found, NULL otherwise. */ @@ -360,14 +360,14 @@ LINPHONE_PUBLIC LinphoneParticipant *linphone_chat_room_find_participant (const /** * Get the capabilities of a chat room. - * @param[in] cr A LinphoneChatRoom object + * @param[in] cr A #LinphoneChatRoom object * @return The capabilities of the chat room */ LINPHONE_PUBLIC LinphoneChatRoomCapabilitiesMask linphone_chat_room_get_capabilities (const LinphoneChatRoom *cr); /** * Check if a chat room has given capabilities. - * @param[in] cr A LinphoneChatRoom object + * @param[in] cr A #LinphoneChatRoom object * @param[in] mask A Capabilities mask * @return True if the mask matches, false otherwise */ @@ -375,62 +375,62 @@ LINPHONE_PUBLIC bool_t linphone_chat_room_has_capability(const LinphoneChatRoom /** * Get the conference address of the chat room. - * @param[in] cr A LinphoneChatRoom object + * @param[in] cr A #LinphoneChatRoom object * @return The conference address of the chat room or NULL if this type of chat room is not conference based */ LINPHONE_PUBLIC const LinphoneAddress *linphone_chat_room_get_conference_address (const LinphoneChatRoom *cr); /** * Get the participant representing myself in the chat room. - * @param[in] cr A LinphoneChatRoom object + * @param[in] cr A #LinphoneChatRoom object * @return The participant representing myself in the conference. */ LINPHONE_PUBLIC LinphoneParticipant *linphone_chat_room_get_me (const LinphoneChatRoom *cr); /** * Get the number of participants in the chat room (that is without ourselves). - * @param[in] cr A LinphoneChatRoom object + * @param[in] cr A #LinphoneChatRoom object * @return The number of participants in the chat room */ LINPHONE_PUBLIC int linphone_chat_room_get_nb_participants (const LinphoneChatRoom *cr); /** * Get the list of participants of a chat room. - * @param[in] cr A LinphoneChatRoom object + * @param[in] cr A #LinphoneChatRoom object * @return \bctbx_list{LinphoneParticipant} */ LINPHONE_PUBLIC bctbx_list_t * linphone_chat_room_get_participants (const LinphoneChatRoom *cr); /** * Get the subject of a chat room. - * @param[in] cr A LinphoneChatRoom object + * @param[in] cr A #LinphoneChatRoom object * @return The subject of the chat room */ LINPHONE_PUBLIC const char * linphone_chat_room_get_subject (const LinphoneChatRoom *cr); /** * Leave a chat room. - * @param[in] cr A LinphoneChatRoom object + * @param[in] cr A #LinphoneChatRoom object */ LINPHONE_PUBLIC void linphone_chat_room_leave (LinphoneChatRoom *cr); /** * Remove a participant of a chat room. - * @param[in] cr A LinphoneChatRoom object + * @param[in] cr A #LinphoneChatRoom object * @param[in] participant The participant to remove from the chat room */ LINPHONE_PUBLIC void linphone_chat_room_remove_participant (LinphoneChatRoom *cr, LinphoneParticipant *participant); /** * Remove several participants of a chat room at once. - * @param[in] cr A LinphoneChatRoom object + * @param[in] cr A #LinphoneChatRoom object * @param[in] participants \bctbx_list{LinphoneParticipant} */ LINPHONE_PUBLIC void linphone_chat_room_remove_participants (LinphoneChatRoom *cr, const bctbx_list_t *participants); /** * Change the admin status of a participant of a chat room (you need to be an admin yourself to do this). - * @param[in] cr A LinphoneChatRoom object + * @param[in] cr A #LinphoneChatRoom object * @param[in] participant The Participant for which to change the admin status * @param[in] isAdmin A boolean value telling whether the participant should now be an admin or not */ @@ -438,30 +438,30 @@ LINPHONE_PUBLIC void linphone_chat_room_set_participant_admin_status (LinphoneCh /** * Set the subject of a chat room. - * @param[in] cr A LinphoneChatRoom object + * @param[in] cr A #LinphoneChatRoom object * @param[in] subject The new subject to set for the chat room */ LINPHONE_PUBLIC void linphone_chat_room_set_subject (LinphoneChatRoom *cr, const char *subject); /** * Gets the list of participants that are currently composing - * @param[in] cr A LinphoneChatRoom object + * @param[in] cr A #LinphoneChatRoom object * @return \bctbx_list{LinphoneAddress} list of addresses that are in the is_composing state */ LINPHONE_PUBLIC const bctbx_list_t * linphone_chat_room_get_composing_addresses(LinphoneChatRoom *cr); /** * Set the conference address of a group chat room. This function needs to be called from the - * LinphoneChatRoomCbsConferenceAddressGenerationCb callback and only there. - * @param[in] cr A LinphoneChatRoom object + * #LinphoneChatRoomCbsConferenceAddressGenerationCb callback and only there. + * @param[in] cr A #LinphoneChatRoom object * @param[in] confAddr The conference address to be used by the group chat room */ LINPHONE_PUBLIC void linphone_chat_room_set_conference_address (LinphoneChatRoom *cr, const LinphoneAddress *confAddr); /** * Set the participant device. This function needs to be called from the - * LinphoneChatRoomCbsParticipantDeviceFetchRequestedCb callback and only there. - * @param[in] cr A LinphoneChatRoom object + * #LinphoneChatRoomCbsParticipantDeviceFetchRequestedCb callback and only there. + * @param[in] cr A #LinphoneChatRoom object * @param[in] partAddr The participant address * @param[in] partDevices \bctbx_list{LinphoneAddress} list of the participant devices to be used by the group chat room */ @@ -478,8 +478,8 @@ LINPHONE_PUBLIC void linphone_chat_room_add_participant_device (LinphoneChatRoom /** * Set the participant device. This function needs to be called from the - * LinphoneChatRoomCbsParticipantsCapabilitiesCheckedCb callback and only there. - * @param[in] cr A LinphoneChatRoom object + * #LinphoneChatRoomCbsParticipantsCapabilitiesCheckedCb callback and only there. + * @param[in] cr A #LinphoneChatRoom object * @param[in] deviceAddr The device address * @param[in] participantsCompatible \bctbx_list{LinphoneAddress} */ diff --git a/include/linphone/api/c-content.h b/include/linphone/api/c-content.h new file mode 100644 index 000000000..48e3a5ccb --- /dev/null +++ b/include/linphone/api/c-content.h @@ -0,0 +1,247 @@ +/* + * c-content.h + * Copyright (C) 2010-2018 Belledonne Communications SARL + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _L_C_CONTENT_H_ +#define _L_C_CONTENT_H_ + +#include "linphone/api/c-types.h" + +// ============================================================================= + +#ifdef __cplusplus + extern "C" { +#endif // ifdef __cplusplus + +/** + * @addtogroup misc + * @{ + */ + +/** + * Acquire a reference to the content. + * @param[in] content #LinphoneContent object. + * @return The same #LinphoneContent object. +**/ +LINPHONE_PUBLIC LinphoneContent *linphone_content_ref (LinphoneContent *content); + +/** + * Release reference to the content. + * @param[in] content #LinphoneContent object. +**/ +LINPHONE_PUBLIC void linphone_content_unref (LinphoneContent *content); + +/** + * Retrieve the user pointer associated with the content. + * @param[in] content #LinphoneContent object. + * @return The user pointer associated with the content. +**/ +LINPHONE_PUBLIC void *linphone_content_get_user_data (const LinphoneContent *content); + +/** + * Assign a user pointer to the content. + * @param[in] content #LinphoneContent object. + * @param[in] ud The user pointer to associate with the content. +**/ +LINPHONE_PUBLIC void linphone_content_set_user_data (LinphoneContent *content, void *user_data); + +/** + * Get the mime type of the content data. + * @param[in] content #LinphoneContent object. + * @return The mime type of the content data, for example "application". + */ +LINPHONE_PUBLIC const char *linphone_content_get_type (const LinphoneContent *content); + +/** + * Set the mime type of the content data. + * @param[in] content #LinphoneContent object. + * @param[in] type The mime type of the content data, for example "application". + */ +LINPHONE_PUBLIC void linphone_content_set_type (LinphoneContent *content, const char *type); + +/** + * Get the mime subtype of the content data. + * @param[in] content #LinphoneContent object. + * @return The mime subtype of the content data, for example "html". + */ +LINPHONE_PUBLIC const char *linphone_content_get_subtype (const LinphoneContent *content); + +/** + * Set the mime subtype of the content data. + * @param[in] content #LinphoneContent object. + * @param[in] subtype The mime subtype of the content data, for example "html". + */ +LINPHONE_PUBLIC void linphone_content_set_subtype (LinphoneContent *content, const char *subtype); + +/** + * Adds a parameter to the ContentType header. + * @param[in] content LinphoneContent object. + * @param[in] name the name of the parameter to add. + * @param[in] value the value of the parameter to add. + */ +LINPHONE_PUBLIC void linphone_content_add_content_type_parameter ( + LinphoneContent *content, + const char *name, + const char *value +); + +/** + * Get the content data buffer, usually a string. + * @param[in] content #LinphoneContent object. + * @return The content data buffer. + */ +LINPHONE_PUBLIC const uint8_t *linphone_content_get_buffer (const LinphoneContent *content); + +/** + * Set the content data buffer, usually a string. + * @param[in] content #LinphoneContent object. + * @param[in] buffer The content data buffer. + * @param[in] size The size of the content data buffer. + */ +LINPHONE_PUBLIC void linphone_content_set_buffer (LinphoneContent *content, const uint8_t *buffer, size_t size); + +/** + * Get the string content data buffer. + * @param[in] content #LinphoneContent object + * @return The string content data buffer. + */ +LINPHONE_PUBLIC const char *linphone_content_get_string_buffer (const LinphoneContent *content); + +/** + * Set the string content data buffer. + * @param[in] content #LinphoneContent object. + * @param[in] buffer The string content data buffer. + */ +LINPHONE_PUBLIC void linphone_content_set_string_buffer (LinphoneContent *content, const char *buffer); + +/** + * Get the content data buffer size, excluding null character despite null character is always set for convenience. + * @param[in] content #LinphoneContent object. + * @return The content data buffer size. + */ +LINPHONE_PUBLIC size_t linphone_content_get_size (const LinphoneContent *content); + +/** + * Get the file size if content is either a FileContent or a FileTransferContent. + * @param[in] content #LinphoneContent object. + * @return The represented file size. + */ +LINPHONE_PUBLIC size_t linphone_content_get_file_size(const LinphoneContent *content); + +/** + * Set the content data size, excluding null character despite null character is always set for convenience. + * @param[in] content #LinphoneContent object + * @param[in] size The content data buffer size. + */ +LINPHONE_PUBLIC void linphone_content_set_size (LinphoneContent *content, size_t size); + +/** + * Get the encoding of the data buffer, for example "gzip". + * @param[in] content #LinphoneContent object. + * @return The encoding of the data buffer. + */ +LINPHONE_PUBLIC const char *linphone_content_get_encoding (const LinphoneContent *content); + +/** + * Set the encoding of the data buffer, for example "gzip". + * @param[in] content #LinphoneContent object. + * @param[in] encoding The encoding of the data buffer. + */ +LINPHONE_PUBLIC void linphone_content_set_encoding (LinphoneContent *content, const char *encoding); + +/** + * Get the name associated with a RCS file transfer message. It is used to store the original filename of the file to be downloaded from server. + * @param[in] content #LinphoneContent object. + * @return The name of the content. + */ +LINPHONE_PUBLIC const char *linphone_content_get_name (const LinphoneContent *content); + +/** + * Set the name associated with a RCS file transfer message. It is used to store the original filename of the file to be downloaded from server. + * @param[in] content #LinphoneContent object. + * @param[in] name The name of the content. + */ +LINPHONE_PUBLIC void linphone_content_set_name (LinphoneContent *content, const char *name); + +/** + * Tell whether a content is a multipart content. + * @param[in] content #LinphoneContent object. + * @return A boolean value telling whether the content is multipart or not. + */ +LINPHONE_PUBLIC bool_t linphone_content_is_multipart (const LinphoneContent *content); + +/** + * Get a part from a multipart content according to its index. + * @param[in] content #LinphoneContent object. + * @param[in] idx The index of the part to get. + * @return A #LinphoneContent object holding the part if found, NULL otherwise. + */ +LINPHONE_PUBLIC LinphoneContent *linphone_content_get_part (const LinphoneContent *content, int idx); + +/** + * Find a part from a multipart content looking for a part header with a specified value. + * @param[in] content #LinphoneContent object. + * @param[in] header_name The name of the header to look for. + * @param[in] header_value The value of the header to look for. + * @return A #LinphoneContent object object the part if found, NULL otherwise. + */ +LINPHONE_PUBLIC LinphoneContent *linphone_content_find_part_by_header ( + const LinphoneContent *content, + const char *header_name, + const char *header_value +); + +/** + * Get a custom header value of a content. + * @param[in] content #LinphoneContent object. + * @param[in] header_name The name of the header to get the value from. + * @return The value of the header if found, NULL otherwise. + */ +LINPHONE_PUBLIC const char *linphone_content_get_custom_header (const LinphoneContent *content, const char *header_name); + +/** + * Get the key associated with a RCS file transfer message if encrypted + * @param[in] content #LinphoneContent object. + * @return The key to encrypt/decrypt the file associated to this content. + */ +LINPHONE_PUBLIC const char *linphone_content_get_key (const LinphoneContent *content); + +/** + * Get the size of key associated with a RCS file transfer message if encrypted + * @param[in] content #LinphoneContent object. + * @return The key size in bytes + */ +LINPHONE_PUBLIC size_t linphone_content_get_key_size (const LinphoneContent *content); + +/** + * Set the key associated with a RCS file transfer message if encrypted + * @param[in] content #LinphoneContent object. + * @param[in] key The key to be used to encrypt/decrypt file associated to this content. + * @param[in] key_length The lengh of the key. + */ +LINPHONE_PUBLIC void linphone_content_set_key (LinphoneContent *content, const char *key, const size_t key_length); + +/** + * @} + */ + +#ifdef __cplusplus + } +#endif // ifdef __cplusplus + +#endif // ifndef _L_C_CONTENT_H_ diff --git a/include/linphone/api/c-magic-search.h b/include/linphone/api/c-magic-search.h index e45bc2605..92b667346 100644 --- a/include/linphone/api/c-magic-search.h +++ b/include/linphone/api/c-magic-search.h @@ -22,9 +22,11 @@ #include "linphone/api/c-types.h" +// ============================================================================= + #ifdef __cplusplus -extern "C" { -#endif + extern "C" { +#endif // ifdef __cplusplus /** * @addtogroup misc @@ -34,88 +36,88 @@ extern "C" { /** * Constructs a LinphoneMagicSearch object **/ -LINPHONE_PUBLIC LinphoneMagicSearch *linphone_magic_search_new(LinphoneCore *lc); +LINPHONE_PUBLIC LinphoneMagicSearch *linphone_magic_search_new (LinphoneCore *lc); /** * Increment reference count of LinphoneMagicSearch object. **/ -LINPHONE_PUBLIC LinphoneMagicSearch *linphone_magic_search_ref(LinphoneMagicSearch *magicSearch); +LINPHONE_PUBLIC LinphoneMagicSearch *linphone_magic_search_ref (LinphoneMagicSearch *magic_search); /** * Decrement reference count of LinphoneMagicSearch object. When dropped to zero, memory is freed. **/ -LINPHONE_PUBLIC void linphone_magic_search_unref(LinphoneMagicSearch *magicSearch); +LINPHONE_PUBLIC void linphone_magic_search_unref (LinphoneMagicSearch *magic_search); /** * Set the minimum value used to calculate the weight in search * @param[in] weight minimum weight **/ -LINPHONE_PUBLIC void linphone_magic_search_set_min_weight(LinphoneMagicSearch *magicSearch, const unsigned int weight); +LINPHONE_PUBLIC void linphone_magic_search_set_min_weight (LinphoneMagicSearch *magic_search, unsigned int weight); /** * @return the minimum value used to calculate the weight in search **/ -LINPHONE_PUBLIC unsigned int linphone_magic_search_get_min_weight(const LinphoneMagicSearch *magicSearch); +LINPHONE_PUBLIC unsigned int linphone_magic_search_get_min_weight (const LinphoneMagicSearch *magic_search); /** * Set the maximum value used to calculate the weight in search * @param[in] weight maximum weight **/ -LINPHONE_PUBLIC void linphone_magic_search_set_max_weight(LinphoneMagicSearch *magicSearch, const unsigned int weight); +LINPHONE_PUBLIC void linphone_magic_search_set_max_weight (LinphoneMagicSearch *magic_search, unsigned int weight); /** * @return the maximum value used to calculate the weight in search **/ -LINPHONE_PUBLIC unsigned int linphone_magic_search_get_max_weight(const LinphoneMagicSearch *magicSearch); +LINPHONE_PUBLIC unsigned int linphone_magic_search_get_max_weight (const LinphoneMagicSearch *magic_search); /** * @return the delimiter used to find matched filter word **/ -LINPHONE_PUBLIC const char *linphone_magic_search_get_delimiter(const LinphoneMagicSearch *magicSearch); +LINPHONE_PUBLIC const char *linphone_magic_search_get_delimiter (const LinphoneMagicSearch *magic_search); /** * Set the delimiter used to find matched filter word * @param[in] delimiter delimiter (example "-_.,") **/ -LINPHONE_PUBLIC void linphone_magic_search_set_delimiter(LinphoneMagicSearch *magicSearch, const char *delimiter); +LINPHONE_PUBLIC void linphone_magic_search_set_delimiter (LinphoneMagicSearch *magic_search, const char *delimiter); /** * @return if the delimiter search is used **/ -LINPHONE_PUBLIC bool_t linphone_magic_search_get_use_delimiter(LinphoneMagicSearch *magicSearch); +LINPHONE_PUBLIC bool_t linphone_magic_search_get_use_delimiter (LinphoneMagicSearch *magic_search); /** * Enable or disable the delimiter in search * @param[in] enable **/ -LINPHONE_PUBLIC void linphone_magic_search_set_use_delimiter(LinphoneMagicSearch *magicSearch, bool_t enable); +LINPHONE_PUBLIC void linphone_magic_search_set_use_delimiter (LinphoneMagicSearch *magic_search, bool_t enable); /** * @return the number of the maximum SearchResult which will be return **/ -LINPHONE_PUBLIC unsigned int linphone_magic_search_get_search_limit(const LinphoneMagicSearch *magicSearch); +LINPHONE_PUBLIC unsigned int linphone_magic_search_get_search_limit (const LinphoneMagicSearch *magic_search); /** * Set the number of the maximum SearchResult which will be return * @param[in] limit **/ -LINPHONE_PUBLIC void linphone_magic_search_set_search_limit(LinphoneMagicSearch *magicSearch, const unsigned int limit); +LINPHONE_PUBLIC void linphone_magic_search_set_search_limit (LinphoneMagicSearch *magic_search, unsigned int limit); /** * @return if the search is limited **/ -LINPHONE_PUBLIC bool_t linphone_magic_search_get_limited_search(const LinphoneMagicSearch *magicSearch); +LINPHONE_PUBLIC bool_t linphone_magic_search_get_limited_search (const LinphoneMagicSearch *magic_search); /** * Enable or disable the limited search * @param[in] limited **/ -LINPHONE_PUBLIC void linphone_magic_search_set_limited_search(LinphoneMagicSearch *magicSearch, const bool_t limited); +LINPHONE_PUBLIC void linphone_magic_search_set_limited_search (LinphoneMagicSearch *magic_search, bool_t limited); /** * Reset the cache to begin a new search **/ -LINPHONE_PUBLIC void linphone_magic_search_reset_search_cache(LinphoneMagicSearch *magicSearch); +LINPHONE_PUBLIC void linphone_magic_search_reset_search_cache (LinphoneMagicSearch *magic_search); /** * Create a sorted list of SearchResult from SipUri, Contact name, @@ -124,13 +126,17 @@ LINPHONE_PUBLIC void linphone_magic_search_reset_search_cache(LinphoneMagicSearc * During the first search, a cache is created and used for the next search * Use linphone_magic_search_reset_search_cache() to begin a new search * @param[in] filter word we search - * @param[in] withDomain domain which we want to search only + * @param[in] domain domain which we want to search only * - "" for searching in all contact * - "*" for searching in contact with sip SipUri * - "yourdomain" for searching in contact from "yourdomain" domain * @return sorted list of \bctbx_list{LinphoneSearchResult} **/ -LINPHONE_PUBLIC bctbx_list_t* linphone_magic_search_get_contact_list_from_filter(LinphoneMagicSearch *magicSearch, const char *filter, const char *withDomain); +LINPHONE_PUBLIC bctbx_list_t* linphone_magic_search_get_contact_list_from_filter ( + LinphoneMagicSearch *magic_search, + const char *filter, + const char *domain +); /** * @} diff --git a/include/linphone/api/c-participant-imdn-state.h b/include/linphone/api/c-participant-imdn-state.h new file mode 100644 index 000000000..041dd2efc --- /dev/null +++ b/include/linphone/api/c-participant-imdn-state.h @@ -0,0 +1,91 @@ +/* + * c-participant-imdn-state.h + * Copyright (C) 2010-2018 Belledonne Communications SARL + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _L_C_PARTICIPANT_IMDN_STATE_H_ +#define _L_C_PARTICIPANT_IMDN_STATE_H_ + +#include "linphone/api/c-types.h" + +// ============================================================================= + +#ifdef __cplusplus + extern "C" { +#endif // ifdef __cplusplus + +/** + * @addtogroup misc + * @{ + */ + +/** + * Increment reference count of LinphoneParticipantImdnState object. + **/ +LINPHONE_PUBLIC LinphoneParticipantImdnState *linphone_participant_imdn_state_ref (LinphoneParticipantImdnState *state); + +/** + * Decrement reference count of LinphoneParticipantImdnState object. + **/ +LINPHONE_PUBLIC void linphone_participant_imdn_state_unref (LinphoneParticipantImdnState *state); + +/** + * Retrieve the user pointer associated with a LinphoneParticipantImdnState. + * @param[in] state A LinphoneParticipantImdnState object + * @return The user pointer associated with the LinphoneParticipantImdnState. +**/ +LINPHONE_PUBLIC void *linphone_participant_imdn_state_get_user_data(const LinphoneParticipantImdnState *state); + +/** + * Assign a user pointer to a LinphoneParticipantImdnState. + * @param[in] state A LinphoneParticipantImdnState object + * @param[in] ud The user pointer to associate with the LinphoneParticipantImdnState +**/ +LINPHONE_PUBLIC void linphone_participant_imdn_state_set_user_data(LinphoneParticipantImdnState *state, void *ud); + +/** + * Get the participant concerned by a LinphoneParticipantImdnState. + * @param[in] state A LinphoneParticipantImdnState object + * @return The participant concerned by the LinphoneParticipantImdnState + */ +LINPHONE_PUBLIC const LinphoneParticipant *linphone_participant_imdn_state_get_participant ( + const LinphoneParticipantImdnState *state +); + +/** + * Get the chat message state the participant is in. + * @param state A LinphoneParticipantImdnState object + * @return The chat message state the participant is in + */ +LINPHONE_PUBLIC LinphoneChatMessageState linphone_participant_imdn_state_get_state (const LinphoneParticipantImdnState *state); + +/** + * Get the timestamp at which a participant has reached the state described by a LinphoneParticipantImdnState. + * @param[in] state A LinphoneParticipantImdnState object + * @return The timestamp at which the participant has reached the state described in the LinphoneParticipantImdnState + */ +LINPHONE_PUBLIC time_t linphone_participant_imdn_state_get_state_change_time (const LinphoneParticipantImdnState *state); + +/** + * @} + */ + +#ifdef __cplusplus + } +#endif // ifdef __cplusplus + +#endif // ifndef _L_C_PARTICIPANT_IMDN_STATE_H_ diff --git a/include/linphone/api/c-participant.h b/include/linphone/api/c-participant.h index e0c187ba5..93e20d2c8 100644 --- a/include/linphone/api/c-participant.h +++ b/include/linphone/api/c-participant.h @@ -34,39 +34,39 @@ */ /** - * Increment reference count of LinphoneParticipant object. + * Increment reference count of #LinphoneParticipant object. **/ LINPHONE_PUBLIC LinphoneParticipant *linphone_participant_ref (LinphoneParticipant *participant); /** - * Decrement reference count of LinphoneParticipant object. + * Decrement reference count of #LinphoneParticipant object. **/ LINPHONE_PUBLIC void linphone_participant_unref (LinphoneParticipant *participant); /** * Retrieve the user pointer associated with the conference participant. - * @param[in] participant A LinphoneParticipant object + * @param[in] participant A #LinphoneParticipant object * @return The user pointer associated with the participant. **/ LINPHONE_PUBLIC void * linphone_participant_get_user_data(const LinphoneParticipant *participant); /** * Assign a user pointer to the conference participant. - * @param[in] participant A LinphoneParticipant object + * @param[in] participant A #LinphoneParticipant object * @param[in] ud The user pointer to associate with the participant **/ LINPHONE_PUBLIC void linphone_participant_set_user_data(LinphoneParticipant *participant, void *ud); /** * Get the address of a conference participant. - * @param[in] participant A LinphoneParticipant object + * @param[in] participant A #LinphoneParticipant object * @return The address of the participant */ LINPHONE_PUBLIC const LinphoneAddress * linphone_participant_get_address (const LinphoneParticipant *participant); /** * Tells whether a conference participant is an administrator of the conference. - * @param[in] participant A LinphoneParticipant object + * @param[in] participant A #LinphoneParticipant object * @return A boolean value telling whether the participant is an administrator */ LINPHONE_PUBLIC bool_t linphone_participant_is_admin (const LinphoneParticipant *participant); diff --git a/include/linphone/api/c-search-result.h b/include/linphone/api/c-search-result.h index 7a4a62485..8730d90ec 100644 --- a/include/linphone/api/c-search-result.h +++ b/include/linphone/api/c-search-result.h @@ -51,6 +51,11 @@ LINPHONE_PUBLIC const LinphoneFriend* linphone_search_result_get_friend(const Li **/ LINPHONE_PUBLIC const LinphoneAddress* linphone_search_result_get_address(const LinphoneSearchResult *searchResult); +/** + * @return Phone Number associed + **/ +LINPHONE_PUBLIC const char* linphone_search_result_get_phone_number(const LinphoneSearchResult *searchResult); + /** * @return the result weight **/ diff --git a/include/linphone/api/c-types.h b/include/linphone/api/c-types.h index f587b77f8..a74df54c0 100644 --- a/include/linphone/api/c-types.h +++ b/include/linphone/api/c-types.h @@ -61,11 +61,11 @@ /** * Object that represents a SIP address. * - * The LinphoneAddress is an opaque object to represents SIP addresses, ie + * The #LinphoneAddress is an opaque object to represents SIP addresses, ie * the content of SIP's 'from' and 'to' headers. * A SIP address is made of display name, username, domain name, port, and various * uri headers (such as tags). It looks like 'Alice '. - * The LinphoneAddress has methods to extract and manipulate all parts of the address. + * The #LinphoneAddress has methods to extract and manipulate all parts of the address. * When some part of the address (for example the username) is empty, the accessor methods * return NULL. * @ingroup linphone_address @@ -77,20 +77,20 @@ typedef struct _LinphoneAddress LinphoneAddress; // ----------------------------------------------------------------------------- /** - * The LinphoneCall object represents a call issued or received by the LinphoneCore + * The #LinphoneCall object represents a call issued or received by the #LinphoneCore * @ingroup call_control -**/ + */ typedef struct _LinphoneCall LinphoneCall; /** Callback prototype */ typedef void (*LinphoneCallCbFunc) (LinphoneCall *call, void *ud); /** - * That class holds all the callbacks which are called by LinphoneCall objects. + * That class holds all the callbacks which are called by #LinphoneCall objects. * * Use linphone_factory_create_call_cbs() to create an instance. Then, call the * callback setters on the events you need to monitor and pass the object to - * a LinphoneCall instance through linphone_call_add_callbacks(). + * a #LinphoneCall instance through linphone_call_add_callbacks(). * @ingroup call_control */ typedef struct _LinphoneCallCbs LinphoneCallCbs; @@ -106,7 +106,7 @@ typedef struct _LinphoneCallCbs LinphoneCallCbs; typedef struct _LinphoneChatMessage LinphoneChatMessage; /** - * An object to handle the callbacks for the handling a LinphoneChatMessage objects. + * An object to handle the callbacks for the handling a #LinphoneChatMessage objects. * @ingroup chatroom */ typedef struct _LinphoneChatMessageCbs LinphoneChatMessageCbs; @@ -119,13 +119,13 @@ typedef struct _LinphoneChatMessageCbs LinphoneChatMessageCbs; typedef struct _LinphoneChatRoom LinphoneChatRoom; /** - * A mask of LinphoneChatRoomCapabilities + * A mask of #LinphoneChatRoomCapabilities * @ingroup chatroom */ typedef int LinphoneChatRoomCapabilitiesMask; /** - * An object to handle the callbacks for the handling a LinphoneChatRoom objects. + * An object to handle the callbacks for the handling a #LinphoneChatRoom objects. * @ingroup chatroom */ typedef struct _LinphoneChatRoomCbs LinphoneChatRoomCbs; @@ -144,43 +144,76 @@ typedef struct _LinphoneEventLog LinphoneEventLog; // Misc. // ----------------------------------------------------------------------------- +/** + * The LinphoneContent object holds data that can be embedded in a signaling message. + * @ingroup misc + */ +typedef struct _LinphoneContent LinphoneContent; + /** * Represents a dial plan * @ingroup misc -**/ + */ typedef struct _LinphoneDialPlan LinphoneDialPlan; /** - * A LinphoneMagicSearch is used to do specifics searchs + * A #LinphoneMagicSearch is used to do specifics searchs * @ingroup misc -**/ + */ typedef struct _LinphoneMagicSearch LinphoneMagicSearch; /** - * The LinphoneParticipant object represents a participant of a conference. * @ingroup misc -**/ + */ typedef struct _LinphoneParticipant LinphoneParticipant; +/** + * The LinphoneParticipantImdnState object represents the state of chat message for a participant of a conference chat room. + * @ingroup misc + */ +typedef struct _LinphoneParticipantImdnState LinphoneParticipantImdnState; + /** * The LinphoneSearchResult object represents a result of a search * @ingroup misc - **/ + */ typedef struct _LinphoneSearchResult LinphoneSearchResult; // ============================================================================= // C Enums. // ============================================================================= +// ----------------------------------------------------------------------------- +// How-to: Declare one enum +// +// 1. Declare a macro like this example in include/linphone/enums/chat-message-enums.h: +// +// #define L_ENUM_VALUES_CHAT_MESSAGE_DIRECTION(F) \ // +// F(Incoming /**< Incoming message */) \ // +// F(Outgoing /**< Outgoing message */) +// +// 2. And in this file, call L_DECLARE_C_ENUM with the enum name and values as params: +// +// L_DECLARE_C_ENUM(ChatMessageDirection, L_ENUM_VALUES_CHAT_MESSAGE_DIRECTION); +// +// 3. Do not forget to replace each single quote (with ') or other special char like +// to an escaped sequence. Otherwise you get this error at compilation: +// +// [ 99%] Building CXX object wrappers/cpp/CMakeFiles/linphone++.dir/src/linphone++.cc.o +// c++: error: WORK/desktop/Build/linphone/wrappers/cpp/src/linphone++.cc: No such file or directory +// c++: fatal error: no input files +// compilation terminated. +// ----------------------------------------------------------------------------- + // ----------------------------------------------------------------------------- // Call. // ----------------------------------------------------------------------------- /** - * LinphoneCallState enum represents the different state a call can reach into. + * #LinphoneCallState enum represents the different state a call can reach into. * The application is notified of state changes through the LinphoneCoreVTable::call_state_changed callback. * @ingroup call_control -**/ + */ L_DECLARE_C_ENUM(CallState, L_ENUM_VALUES_CALL_SESSION_STATE); // ----------------------------------------------------------------------------- @@ -188,25 +221,25 @@ L_DECLARE_C_ENUM(CallState, L_ENUM_VALUES_CALL_SESSION_STATE); // ----------------------------------------------------------------------------- /** - * LinphoneChatMessageDirection is used to indicate if a message is outgoing or incoming. + * #LinphoneChatMessageDirection is used to indicate if a message is outgoing or incoming. * @ingroup chatroom */ L_DECLARE_C_ENUM(ChatMessageDirection, L_ENUM_VALUES_CHAT_MESSAGE_DIRECTION); /** - * LinphoneChatMessageState is used to notify if messages have been succesfully delivered or not. + * #LinphoneChatMessageState is used to notify if messages have been succesfully delivered or not. * @ingroup chatroom -*/ + */ L_DECLARE_C_ENUM(ChatMessageState, L_ENUM_VALUES_CHAT_MESSAGE_STATE); /** - * LinphoneChatRoomCapabilities is used to indicated the capabilities of a chat room. + * #LinphoneChatRoomCapabilities is used to indicated the capabilities of a chat room. * @ingroup chatroom */ L_DECLARE_C_ENUM_FIXED_VALUES(ChatRoomCapabilities, L_ENUM_VALUES_CHAT_ROOM_CAPABILITIES); /** - * LinphoneChatRoomState is used to indicate the current state of a chat room. + * #LinphoneChatRoomState is used to indicate the current state of a chat room. * @ingroup chatroom */ L_DECLARE_C_ENUM(ChatRoomState, L_ENUM_VALUES_CHAT_ROOM_STATE); @@ -216,7 +249,7 @@ L_DECLARE_C_ENUM(ChatRoomState, L_ENUM_VALUES_CHAT_ROOM_STATE); // ----------------------------------------------------------------------------- /** - * LinphoneEventLogType is used to indicate the type of an event. Useful for cast. + * #LinphoneEventLogType is used to indicate the type of an event. Useful for cast. * @ingroup events */ L_DECLARE_C_ENUM(EventLogType, L_ENUM_VALUES_EVENT_LOG_TYPE); diff --git a/include/linphone/auth_info.h b/include/linphone/auth_info.h index 5b9e3a6b1..72ef24d93 100644 --- a/include/linphone/auth_info.h +++ b/include/linphone/auth_info.h @@ -29,7 +29,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /** - * Safely cast a belle_sip_object_t into LinphoneAuthInfo + * Safely cast a belle_sip_object_t into #LinphoneAuthInfo */ #define LINPHONE_AUTH_INFO(obj) BELLE_SIP_CAST(obj, LinphoneAuthInfo) @@ -48,7 +48,7 @@ extern "C" { * @param ha1 The ha1-encrypted password if password is not given in clear text. * @param realm The authentication domain (which can be larger than the sip domain. Unfortunately many SIP servers don't use this parameter. * @param domain The SIP domain for which this authentication information is valid, if it has to be restricted for a single SIP domain. - * @return A #LinphoneAuthInfo object. linphone_auth_info_destroy() must be used to destroy it when no longer needed. The LinphoneCore makes a copy of LinphoneAuthInfo + * @return A #LinphoneAuthInfo object. linphone_auth_info_destroy() must be used to destroy it when no longer needed. The #LinphoneCore makes a copy of #LinphoneAuthInfo * passed through linphone_core_add_auth_info(). **/ LINPHONE_PUBLIC LinphoneAuthInfo *linphone_auth_info_new( diff --git a/include/linphone/buffer.h b/include/linphone/buffer.h index bb7450666..9377546c6 100644 --- a/include/linphone/buffer.h +++ b/include/linphone/buffer.h @@ -35,63 +35,63 @@ extern "C" { */ /** - * Create a new empty LinphoneBuffer object. - * @return A new LinphoneBuffer object. + * Create a new empty #LinphoneBuffer object. + * @return A new #LinphoneBuffer object. */ LINPHONE_PUBLIC LinphoneBuffer * linphone_buffer_new(void); /** - * Create a new LinphoneBuffer object from existing data. + * Create a new #LinphoneBuffer object from existing data. * @param[in] data The initial data to store in the LinphoneBuffer. * @param[in] size The size of the initial data to stroe in the LinphoneBuffer. - * @return A new LinphoneBuffer object. + * @return A new #LinphoneBuffer object. */ LINPHONE_PUBLIC LinphoneBuffer * linphone_buffer_new_from_data(const uint8_t *data, size_t size); /** - * Create a new LinphoneBuffer object from a string. + * Create a new #LinphoneBuffer object from a string. * @param[in] data The initial string content of the LinphoneBuffer. - * @return A new LinphoneBuffer object. + * @return A new #LinphoneBuffer object. */ LINPHONE_PUBLIC LinphoneBuffer * linphone_buffer_new_from_string(const char *data); /** * Acquire a reference to the buffer. - * @param[in] buffer LinphoneBuffer object. - * @return The same LinphoneBuffer object. + * @param[in] buffer #LinphoneBuffer object. + * @return The same #LinphoneBuffer object. **/ LINPHONE_PUBLIC LinphoneBuffer * linphone_buffer_ref(LinphoneBuffer *buffer); /** * Release reference to the buffer. - * @param[in] buffer LinphoneBuffer object. + * @param[in] buffer #LinphoneBuffer object. **/ LINPHONE_PUBLIC void linphone_buffer_unref(LinphoneBuffer *buffer); /** * Retrieve the user pointer associated with the buffer. - * @param[in] buffer LinphoneBuffer object. + * @param[in] buffer #LinphoneBuffer object. * @return The user pointer associated with the buffer. **/ LINPHONE_PUBLIC void *linphone_buffer_get_user_data(const LinphoneBuffer *buffer); /** * Assign a user pointer to the buffer. - * @param[in] buffer LinphoneBuffer object. + * @param[in] buffer #LinphoneBuffer object. * @param[in] ud The user pointer to associate with the buffer. **/ LINPHONE_PUBLIC void linphone_buffer_set_user_data(LinphoneBuffer *buffer, void *ud); /** * Get the content of the data buffer. - * @param[in] buffer LinphoneBuffer object. + * @param[in] buffer #LinphoneBuffer object. * @return The content of the data buffer. */ LINPHONE_PUBLIC const uint8_t * linphone_buffer_get_content(const LinphoneBuffer *buffer); /** * Set the content of the data buffer. - * @param[in] buffer LinphoneBuffer object. + * @param[in] buffer #LinphoneBuffer object. * @param[in] content The content of the data buffer. * @param[in] size The size of the content of the data buffer. */ @@ -99,36 +99,36 @@ LINPHONE_PUBLIC void linphone_buffer_set_content(LinphoneBuffer *buffer, const u /** * Get the string content of the data buffer. - * @param[in] buffer LinphoneBuffer object + * @param[in] buffer #LinphoneBuffer object * @return The string content of the data buffer. */ LINPHONE_PUBLIC const char * linphone_buffer_get_string_content(const LinphoneBuffer *buffer); /** * Set the string content of the data buffer. - * @param[in] buffer LinphoneBuffer object. + * @param[in] buffer #LinphoneBuffer object. * @param[in] content The string content of the data buffer. */ LINPHONE_PUBLIC void linphone_buffer_set_string_content(LinphoneBuffer *buffer, const char *content); /** * Get the size of the content of the data buffer. - * @param[in] buffer LinphoneBuffer object. + * @param[in] buffer #LinphoneBuffer object. * @return The size of the content of the data buffer. */ LINPHONE_PUBLIC size_t linphone_buffer_get_size(const LinphoneBuffer *buffer); /** * Set the size of the content of the data buffer. - * @param[in] buffer LinphoneBuffer object + * @param[in] buffer #LinphoneBuffer object * @param[in] size The size of the content of the data buffer. */ LINPHONE_PUBLIC void linphone_buffer_set_size(LinphoneBuffer *buffer, size_t size); /** - * Tell whether the LinphoneBuffer is empty. - * @param[in] buffer LinphoneBuffer object - * @return A boolean value telling whether the LinphoneBuffer is empty or not. + * Tell whether the #LinphoneBuffer is empty. + * @param[in] buffer #LinphoneBuffer object + * @return A boolean value telling whether the #LinphoneBuffer is empty or not. */ LINPHONE_PUBLIC bool_t linphone_buffer_is_empty(const LinphoneBuffer *buffer); diff --git a/include/linphone/call_log.h b/include/linphone/call_log.h index 187811bab..5e0d84e52 100644 --- a/include/linphone/call_log.h +++ b/include/linphone/call_log.h @@ -38,35 +38,35 @@ extern "C" { /** * Get the call ID used by the call. - * @param[in] cl LinphoneCallLog object + * @param[in] cl #LinphoneCallLog object * @return The call ID used by the call as a string. **/ LINPHONE_PUBLIC const char * linphone_call_log_get_call_id(const LinphoneCallLog *cl); /** * Get the direction of the call. - * @param[in] cl LinphoneCallLog object + * @param[in] cl #LinphoneCallLog object * @return The direction of the call. **/ LINPHONE_PUBLIC LinphoneCallDir linphone_call_log_get_dir(const LinphoneCallLog *cl); /** * Get the duration of the call since connected. - * @param[in] cl LinphoneCallLog object + * @param[in] cl #LinphoneCallLog object * @return The duration of the call in seconds. **/ LINPHONE_PUBLIC int linphone_call_log_get_duration(const LinphoneCallLog *cl); /** * Get the origin address (ie from) of the call. - * @param[in] cl LinphoneCallLog object + * @param[in] cl #LinphoneCallLog object * @return The origin address (ie from) of the call. **/ LINPHONE_PUBLIC const LinphoneAddress * linphone_call_log_get_from_address(const LinphoneCallLog *cl); /** * Get the RTP statistics computed locally regarding the call. - * @param[in] cl LinphoneCallLog object + * @param[in] cl #LinphoneCallLog object * @return The RTP statistics that have been computed locally for the call. * @donotwrap **/ @@ -74,7 +74,7 @@ LINPHONE_PUBLIC const rtp_stats_t * linphone_call_log_get_local_stats(const Linp /** * Get the overall quality indication of the call. - * @param[in] cl LinphoneCallLog object + * @param[in] cl #LinphoneCallLog object * @return The overall quality indication of the call. **/ LINPHONE_PUBLIC float linphone_call_log_get_quality(const LinphoneCallLog *cl); @@ -85,7 +85,7 @@ LINPHONE_PUBLIC float linphone_call_log_get_quality(const LinphoneCallLog *cl); * The reference key can be for example an id to an external database. * It is stored in the config file, thus can survive to process exits/restarts. * - * @param[in] cl LinphoneCallLog object + * @param[in] cl #LinphoneCallLog object * @return The reference key string that has been associated to the call log, or NULL if none has been associated. **/ LINPHONE_PUBLIC const char * linphone_call_log_get_ref_key(const LinphoneCallLog *cl); @@ -99,7 +99,7 @@ LINPHONE_PUBLIC const LinphoneAddress *linphone_call_log_get_local_address(const /** * Get the remote address (that is from or to depending on call direction). - * @param[in] cl LinphoneCallLog object + * @param[in] cl #LinphoneCallLog object * @return The remote address of the call. **/ LINPHONE_PUBLIC const LinphoneAddress * linphone_call_log_get_remote_address(const LinphoneCallLog *cl); @@ -107,7 +107,7 @@ LINPHONE_PUBLIC const LinphoneAddress * linphone_call_log_get_remote_address(con /** * Get the RTP statistics computed by the remote end and sent back via RTCP. * @note Not implemented yet. - * @param[in] cl LinphoneCallLog object + * @param[in] cl #LinphoneCallLog object * @return The RTP statistics that have been computed by the remote end for the call. * @donotwrap **/ @@ -115,21 +115,21 @@ LINPHONE_PUBLIC const rtp_stats_t * linphone_call_log_get_remote_stats(const Lin /** * Get the start date of the call. - * @param[in] cl LinphoneCallLog object + * @param[in] cl #LinphoneCallLog object * @return The date of the beginning of the call. **/ LINPHONE_PUBLIC time_t linphone_call_log_get_start_date(const LinphoneCallLog *cl); /** * Get the status of the call. - * @param[in] cl LinphoneCallLog object + * @param[in] cl #LinphoneCallLog object * @return The status of the call. **/ LINPHONE_PUBLIC LinphoneCallStatus linphone_call_log_get_status(const LinphoneCallLog *cl); /** * Get the destination address (ie to) of the call. - * @param[in] cl LinphoneCallLog object + * @param[in] cl #LinphoneCallLog object * @return The destination address (ie to) of the call. **/ LINPHONE_PUBLIC const LinphoneAddress * linphone_call_log_get_to_address(const LinphoneCallLog *cl); @@ -140,14 +140,14 @@ LINPHONE_PUBLIC const LinphoneAddress * linphone_call_log_get_to_address(const L * The reference key can be for example an id to an external database. * It is stored in the config file, thus can survive to process exits/restarts. * - * @param[in] cl LinphoneCallLog object + * @param[in] cl #LinphoneCallLog object * @param[in] refkey The reference key string to associate to the call log. **/ LINPHONE_PUBLIC void linphone_call_log_set_ref_key(LinphoneCallLog *cl, const char *refkey); /** * Tell whether video was enabled at the end of the call or not. - * @param[in] cl LinphoneCallLog object + * @param[in] cl #LinphoneCallLog object * @return A boolean value telling whether video was enabled at the end of the call. **/ LINPHONE_PUBLIC bool_t linphone_call_log_video_enabled(const LinphoneCallLog *cl); @@ -155,7 +155,7 @@ LINPHONE_PUBLIC bool_t linphone_call_log_video_enabled(const LinphoneCallLog *cl /** * Get a human readable string describing the call. * @note: the returned string must be freed by the application (use ms_free()). - * @param[in] cl LinphoneCallLog object + * @param[in] cl #LinphoneCallLog object * @return A human readable string describing the call. **/ LINPHONE_PUBLIC char * linphone_call_log_to_str(const LinphoneCallLog *cl); @@ -181,28 +181,28 @@ LINPHONE_PUBLIC const LinphoneErrorInfo *linphone_call_log_get_error_info(const /** * Get the user data associated with the call log. - * @param[in] cl LinphoneCallLog object + * @param[in] cl #LinphoneCallLog object * @return The user data associated with the call log. **/ LINPHONE_PUBLIC void *linphone_call_log_get_user_data(const LinphoneCallLog *cl); /** * Assign a user data to the call log. - * @param[in] cl LinphoneCallLog object + * @param[in] cl #LinphoneCallLog object * @param[in] ud The user data to associate with the call log. **/ LINPHONE_PUBLIC void linphone_call_log_set_user_data(LinphoneCallLog *cl, void *ud); /** * Acquire a reference to the call log. - * @param[in] cl LinphoneCallLog object - * @return The same LinphoneCallLog object + * @param[in] cl #LinphoneCallLog object + * @return The same #LinphoneCallLog object **/ LINPHONE_PUBLIC LinphoneCallLog * linphone_call_log_ref(LinphoneCallLog *cl); /** * Release a reference to the call log. - * @param[in] cl LinphoneCallLog object + * @param[in] cl #LinphoneCallLog object **/ LINPHONE_PUBLIC void linphone_call_log_unref(LinphoneCallLog *cl); @@ -242,7 +242,7 @@ LINPHONE_PUBLIC LinphoneCallLog *linphone_core_create_call_log(LinphoneCore *lc, /** * Destroy a LinphoneCallLog. - * @param cl LinphoneCallLog object + * @param cl #LinphoneCallLog object * @deprecated Use linphone_call_log_unref() instead. * @donotwrap */ diff --git a/include/linphone/call_params.h b/include/linphone/call_params.h index 9d3a88211..37cf092dc 100644 --- a/include/linphone/call_params.h +++ b/include/linphone/call_params.h @@ -48,22 +48,22 @@ extern "C" { LINPHONE_PUBLIC void linphone_call_params_add_custom_header(LinphoneCallParams *cp, const char *header_name, const char *header_value); /** - * Copy an existing LinphoneCallParams object to a new LinphoneCallParams object. - * @param[in] cp The LinphoneCallParams object to copy. - * @return A copy of the LinphoneCallParams object. + * Copy an existing #LinphoneCallParams object to a new #LinphoneCallParams object. + * @param[in] cp The #LinphoneCallParams object to copy. + * @return A copy of the #LinphoneCallParams object. **/ LINPHONE_PUBLIC LinphoneCallParams * linphone_call_params_copy(const LinphoneCallParams *cp); /** * Indicate whether sending of early media was enabled. - * @param[in] cp LinphoneCallParams object + * @param[in] cp #LinphoneCallParams object * @return A boolean value telling whether sending of early media was enabled. **/ LINPHONE_PUBLIC bool_t linphone_call_params_early_media_sending_enabled(const LinphoneCallParams *cp); /** * Enable sending of real early media (during outgoing calls). - * @param[in] cp LinphoneCallParams object + * @param[in] cp #LinphoneCallParams object * @param[in] enabled A boolean value telling whether to enable early media sending or not. **/ LINPHONE_PUBLIC void linphone_call_params_enable_early_media_sending(LinphoneCallParams *cp, bool_t enabled); @@ -73,21 +73,21 @@ LINPHONE_PUBLIC void linphone_call_params_enable_early_media_sending(LinphoneCal * Configuring a call to low bandwidth mode will result in the core to activate several settings for the call in order to ensure that bitrate usage * is lowered to the minimum possible. Typically, ptime (packetization time) will be increased, audio codec's output bitrate will be targetted to 20kbit/s provided * that it is achievable by the codec selected after SDP handshake. Video is automatically disabled. - * @param[in] cp LinphoneCallParams object + * @param[in] cp #LinphoneCallParams object * @param[in] enabled A boolean value telling whether to activate the low bandwidth mode or not. **/ LINPHONE_PUBLIC void linphone_call_params_enable_low_bandwidth(LinphoneCallParams *cp, bool_t enabled); /** * Enable audio stream. - * @param[in] cp LinphoneCallParams object + * @param[in] cp #LinphoneCallParams object * @param[in] enabled A boolean value telling whether to enable audio or not. **/ LINPHONE_PUBLIC void linphone_call_params_enable_audio(LinphoneCallParams *cp, bool_t enabled); /** * Enable video stream. - * @param[in] cp LinphoneCallParams object + * @param[in] cp #LinphoneCallParams object * @param[in] enabled A boolean value telling whether to enable video or not. **/ LINPHONE_PUBLIC void linphone_call_params_enable_video(LinphoneCallParams *cp, bool_t enabled); @@ -106,36 +106,36 @@ LINPHONE_PUBLIC const char *linphone_call_params_get_custom_header(const Linphon * that function does not return TRUE even if the conference is running.
* If you want to test whether the conference is running, you should test * whether linphone_core_get_conference() return a non-null pointer. - * @param[in] cp LinphoneCallParams object + * @param[in] cp #LinphoneCallParams object * @return A boolean value telling whether the call is part of the locally managed conference. **/ LINPHONE_PUBLIC bool_t linphone_call_params_get_local_conference_mode(const LinphoneCallParams *cp); /** * Get the kind of media encryption selected for the call. - * @param[in] cp LinphoneCallParams object + * @param[in] cp #LinphoneCallParams object * @return The kind of media encryption selected for the call. **/ LINPHONE_PUBLIC LinphoneMediaEncryption linphone_call_params_get_media_encryption(const LinphoneCallParams *cp); /** * Get requested level of privacy for the call. - * @param[in] cp LinphoneCallParams object + * @param[in] cp #LinphoneCallParams object * @return The privacy mode used for the call. **/ LINPHONE_PUBLIC LinphonePrivacyMask linphone_call_params_get_privacy(const LinphoneCallParams *cp); /** * Get the framerate of the video that is received. - * @param[in] cp LinphoneCallParams object + * @param[in] cp #LinphoneCallParams object * @return The actual received framerate in frames per seconds, 0 if not available. */ LINPHONE_PUBLIC float linphone_call_params_get_received_framerate(const LinphoneCallParams *cp); /** * Get the definition of the received video. - * @param[in] cp LinphoneCallParams object - * @return The received LinphoneVideoDefinition + * @param[in] cp #LinphoneCallParams object + * @return The received #LinphoneVideoDefinition */ LINPHONE_PUBLIC const LinphoneVideoDefinition * linphone_call_params_get_received_video_definition(const LinphoneCallParams *cp); @@ -150,7 +150,7 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED MSVideoSize linphone_call_params_get_receive /** * Get the path for the audio recording of the call. - * @param[in] cp LinphoneCallParams object + * @param[in] cp #LinphoneCallParams object * @return The path to the audio recording of the call. **/ LINPHONE_PUBLIC const char *linphone_call_params_get_record_file(const LinphoneCallParams *cp); @@ -164,20 +164,20 @@ LINPHONE_PUBLIC const char * linphone_call_params_get_rtp_profile(const Linphone /** * Get the framerate of the video that is sent. - * @param[in] cp LinphoneCallParams object + * @param[in] cp #LinphoneCallParams object * @return The actual sent framerate in frames per seconds, 0 if not available. */ LINPHONE_PUBLIC float linphone_call_params_get_sent_framerate(const LinphoneCallParams *cp); /** * Get the definition of the sent video. - * @param[in] cp LinphoneCallParams object - * @return The sent LinphoneVideoDefinition + * @param[in] cp #LinphoneCallParams object + * @return The sent #LinphoneVideoDefinition */ LINPHONE_PUBLIC const LinphoneVideoDefinition * linphone_call_params_get_sent_video_definition(const LinphoneCallParams *cp); /** - * @biref Gets the size of the video that is sent. + * @brief Gets the size of the video that is sent. * @param[in] cp #LinphoneCalParams object * @return The sent video size or MS_VIDEO_SIZE_UNKNOWN if not available. * @deprecated Use #linphone_call_params_get_sent_video_definition() instead. Deprecated since 2017-03-28. @@ -188,7 +188,7 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED MSVideoSize linphone_call_params_get_sent_vi /** * Get the session name of the media session (ie in SDP). * Subject from the SIP message can be retrieved using linphone_call_params_get_custom_header() and is different. - * @param[in] cp LinphoneCallParams object + * @param[in] cp #LinphoneCallParams object * @return The session name of the media session. **/ LINPHONE_PUBLIC const char *linphone_call_params_get_session_name(const LinphoneCallParams *cp); @@ -250,7 +250,7 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED const OrtpPayloadType *linphone_call_params_ * An application that would have reliable way to know network capacity may not use activate_edge_workarounds=1 but instead manually configure * low bandwidth mode with linphone_call_params_enable_low_bandwidth(). * When enabled, this param may transform a call request with video in audio only mode. - * @param[in] cp LinphoneCallParams object + * @param[in] cp #LinphoneCallParams object * @return A boolean value telling whether the low bandwidth mode has been configured/detected. */ LINPHONE_PUBLIC bool_t linphone_call_params_low_bandwidth_enabled(const LinphoneCallParams *cp); @@ -258,14 +258,14 @@ LINPHONE_PUBLIC bool_t linphone_call_params_low_bandwidth_enabled(const Linphone /** * Refine bandwidth settings for this call by setting a bandwidth limit for audio streams. * As a consequence, codecs whose bitrates are not compatible with this limit won't be used. - * @param[in] cp LinphoneCallParams object + * @param[in] cp #LinphoneCallParams object * @param[in] bw The audio bandwidth limit to set in kbit/s. **/ LINPHONE_PUBLIC void linphone_call_params_set_audio_bandwidth_limit(LinphoneCallParams *cp, int bw); /** * Set requested media encryption for a call. - * @param[in] cp LinphoneCallParams object + * @param[in] cp #LinphoneCallParams object * @param[in] enc The media encryption to use for the call. **/ LINPHONE_PUBLIC void linphone_call_params_set_media_encryption(LinphoneCallParams *cp, LinphoneMediaEncryption enc); @@ -273,7 +273,7 @@ LINPHONE_PUBLIC void linphone_call_params_set_media_encryption(LinphoneCallParam /** * Set requested level of privacy for the call. * \xmlonly javascript \endxmlonly - * @param[in] cp LinphoneCallParams object + * @param[in] cp #LinphoneCallParams object * @param[in] privacy The privacy mode to used for the call. **/ LINPHONE_PUBLIC void linphone_call_params_set_privacy(LinphoneCallParams *cp, LinphonePrivacyMask privacy); @@ -283,7 +283,7 @@ LINPHONE_PUBLIC void linphone_call_params_set_privacy(LinphoneCallParams *cp, Li * This function must be used before the call parameters are assigned to the call. * The call recording can be started and paused after the call is established with * linphone_call_start_recording() and linphone_call_pause_recording(). - * @param[in] cp LinphoneCallParams object + * @param[in] cp #LinphoneCallParams object * @param[in] path A string containing the path and filename of the file where audio/video streams are to be written. * The filename must have either .mkv or .wav extention. The video stream will be written only if a MKV file is given. **/ @@ -292,49 +292,49 @@ LINPHONE_PUBLIC void linphone_call_params_set_record_file(LinphoneCallParams *cp /** * Set the session name of the media session (ie in SDP). * Subject from the SIP message (which is different) can be set using linphone_call_params_set_custom_header(). - * @param[in] cp LinphoneCallParams object + * @param[in] cp #LinphoneCallParams object * @param[in] name The session name to be used. **/ LINPHONE_PUBLIC void linphone_call_params_set_session_name(LinphoneCallParams *cp, const char *name); /** * Tell whether audio is enabled or not. - * @param[in] cp LinphoneCallParams object + * @param[in] cp #LinphoneCallParams object * @return A boolean value telling whether audio is enabled or not. **/ LINPHONE_PUBLIC bool_t linphone_call_params_audio_enabled(const LinphoneCallParams *cp); /** * Tell whether video is enabled or not. - * @param[in] cp LinphoneCallParams object + * @param[in] cp #LinphoneCallParams object * @return A boolean value telling whether video is enabled or not. **/ LINPHONE_PUBLIC bool_t linphone_call_params_video_enabled(const LinphoneCallParams *cp); /** * Get the audio stream direction. - * @param[in] cp LinphoneCallParams object + * @param[in] cp #LinphoneCallParams object * @return The audio stream direction associated with the call params. **/ LINPHONE_PUBLIC LinphoneMediaDirection linphone_call_params_get_audio_direction(const LinphoneCallParams *cp); /** * Get the video stream direction. - * @param[in] cp LinphoneCallParams object + * @param[in] cp #LinphoneCallParams object * @return The video stream direction associated with the call params. **/ LINPHONE_PUBLIC LinphoneMediaDirection linphone_call_params_get_video_direction(const LinphoneCallParams *cp); /** * Set the audio stream direction. - * @param[in] cp LinphoneCallParams object + * @param[in] cp #LinphoneCallParams object * @param[in] dir The audio stream direction associated with this call params. **/ LINPHONE_PUBLIC void linphone_call_params_set_audio_direction(LinphoneCallParams *cp, LinphoneMediaDirection dir); /** * Set the video stream direction. - * @param[in] cp LinphoneCallParams object + * @param[in] cp #LinphoneCallParams object * @param[in] dir The video stream direction associated with this call params. **/ LINPHONE_PUBLIC void linphone_call_params_set_video_direction(LinphoneCallParams *cp, LinphoneMediaDirection dir); @@ -356,28 +356,28 @@ void linphone_call_params_set_avpf_rr_interval(LinphoneCallParams *params, uint1 /** * Get the user data associated with the call params. - * @param[in] cp LinphoneCallParams object + * @param[in] cp #LinphoneCallParams object * @return The user data associated with the call params. **/ LINPHONE_PUBLIC void *linphone_call_params_get_user_data(const LinphoneCallParams *cp); /** * Assign a user data to the call params. - * @param[in] cp LinphoneCallParams object + * @param[in] cp #LinphoneCallParams object * @param[in] ud The user data to associate with the call params. **/ LINPHONE_PUBLIC void linphone_call_params_set_user_data(LinphoneCallParams *cp, void *ud); /** * Acquire a reference to the call params. - * @param[in] cp LinphoneCallParams object - * @return The same LinphoneCallParams object + * @param[in] cp #LinphoneCallParams object + * @return The same #LinphoneCallParams object **/ LINPHONE_PUBLIC LinphoneCallParams * linphone_call_params_ref(LinphoneCallParams *cp); /** * Release a reference to the call params. - * @param[in] cp LinphoneCallParams object + * @param[in] cp #LinphoneCallParams object **/ LINPHONE_PUBLIC void linphone_call_params_unref(LinphoneCallParams *cp); @@ -497,8 +497,8 @@ LINPHONE_PUBLIC void linphone_call_params_clear_custom_sdp_media_attributes(Linp #define linphone_call_params_local_conference_mode linphone_call_params_get_local_conference_mode /** - * Destroy a LinphoneCallParams object. - * @param[in] cp LinphoneCallParams object + * Destroy a #LinphoneCallParams object. + * @param[in] cp #LinphoneCallParams object * @deprecated Use linphone_call_params_unref() instead. * @donotwrap **/ diff --git a/include/linphone/callbacks.h b/include/linphone/callbacks.h index a7ce708a6..dbc06de32 100644 --- a/include/linphone/callbacks.h +++ b/include/linphone/callbacks.h @@ -40,9 +40,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ /** - * Callback notifying that a new LinphoneCall (either incoming or outgoing) has been created. - * @param[in] lc LinphoneCore object that has created the call - * @param[in] call The newly created LinphoneCall object + * Callback notifying that a new #LinphoneCall (either incoming or outgoing) has been created. + * @param[in] lc #LinphoneCore object that has created the call + * @param[in] call The newly created #LinphoneCall object */ typedef void (*LinphoneCoreCbsCallCreatedCb)(LinphoneCore *lc, LinphoneCall *call); @@ -61,7 +61,7 @@ typedef LinphoneCoreCbsGlobalStateChangedCb LinphoneCoreGlobalStateChangedCb; /** * Call state notification callback. - * @param lc the LinphoneCore + * @param lc the #LinphoneCore * @param call the call object whose state is changed. * @param cstate the new state of the call * @param message a non NULL informational message about the state. @@ -75,7 +75,7 @@ typedef LinphoneCoreCbsCallStateChangedCb LinphoneCoreCallStateChangedCb; /** * Call encryption changed callback. - * @param lc the LinphoneCore + * @param lc the #LinphoneCore * @param call the call on which encryption is changed. * @param on whether encryption is activated. * @param authentication_token an authentication_token, currently set for ZRTP kind of encryption only. @@ -140,7 +140,7 @@ typedef LinphoneCoreCbsNewSubscriptionRequestedCb LinphoneCoreNewSubscriptionReq /** * Callback for requesting authentication information to application or user. - * @param lc the LinphoneCore + * @param lc the #LinphoneCore * @param realm the realm (domain) on which authentication is required. * @param username the username that needs to be authenticated. * @param domain the domain on which authentication is required. @@ -150,8 +150,8 @@ typedef void (*LinphoneCoreAuthInfoRequestedCb)(LinphoneCore *lc, const char *re /** * Callback for requesting authentication information to application or user. - * @param lc the LinphoneCore - * @param auth_info a LinphoneAuthInfo pre-filled with username, realm and domain values as much as possible + * @param lc the #LinphoneCore + * @param auth_info a #LinphoneAuthInfo pre-filled with username, realm and domain values as much as possible * @param method the type of authentication requested * Application shall reply to this callback using linphone_core_add_auth_info(). */ @@ -165,7 +165,7 @@ typedef LinphoneCoreCbsAuthenticationRequestedCb LinphoneCoreAuthenticationReque /** * Callback to notify a new call-log entry has been added. * This is done typically when a call terminates. - * @param lc the LinphoneCore + * @param lc the #LinphoneCore * @param newcl the new call log entry added. */ typedef void (*LinphoneCoreCbsCallLogUpdatedCb)(LinphoneCore *lc, LinphoneCallLog *newcl); @@ -190,7 +190,7 @@ typedef void (*LinphoneCoreTextMessageReceivedCb)(LinphoneCore *lc, LinphoneChat * Chat message callback prototype * @param lc #LinphoneCore object * @param room #LinphoneChatRoom involved in this conversation. Can be be created by the framework in case \link #LinphoneAddress the from \endlink is not present in any chat room. - * @param LinphoneChatMessage incoming message + * @param #LinphoneChatMessage incoming message */ typedef void (*LinphoneCoreCbsMessageReceivedCb)(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *message); @@ -203,7 +203,7 @@ typedef LinphoneCoreCbsMessageReceivedCb LinphoneCoreMessageReceivedCb; * Chat message not decrypted callback prototype * @param lc #LinphoneCore object * @param room #LinphoneChatRoom involved in this conversation. Can be be created by the framework in case \link #LinphoneAddress the from \endlink is not present in any chat room. - * @param LinphoneChatMessage incoming message + * @param #LinphoneChatMessage incoming message */ typedef void (*LinphoneCoreCbsMessageReceivedUnableDecryptCb)(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *message); @@ -281,7 +281,7 @@ typedef LinphoneCoreCbsBuddyInfoUpdatedCb LinphoneCoreBuddyInfoUpdatedCb; /** * Callback for notifying progresses of transfers. - * @param lc the LinphoneCore + * @param lc the #LinphoneCore * @param transfered the call that was transfered * @param new_call_state the state of the call to transfer target at the far end. */ @@ -294,7 +294,7 @@ typedef LinphoneCoreCbsTransferStateChangedCb LinphoneCoreTransferStateChangedCb /** * Callback for receiving quality statistics for calls. - * @param lc the LinphoneCore + * @param lc the #LinphoneCore * @param call the call * @param stats the call statistics. */ @@ -307,7 +307,7 @@ typedef LinphoneCoreCbsCallStatsUpdatedCb LinphoneCoreCallStatsUpdatedCb; /** * Callback prototype for receiving info messages. - * @param lc the LinphoneCore + * @param lc the #LinphoneCore * @param call the call whose info message belongs to. * @param msg the info message. */ @@ -320,7 +320,7 @@ typedef LinphoneCoreCbsInfoReceivedCb LinphoneCoreInfoReceivedCb; /** * Callback prototype for configuring status changes notification - * @param lc the LinphoneCore + * @param lc the #LinphoneCore * @param message informational message. */ typedef void (*LinphoneCoreCbsConfiguringStatusCb)(LinphoneCore *lc, LinphoneConfiguringState status, const char *message); @@ -332,7 +332,7 @@ typedef LinphoneCoreCbsConfiguringStatusCb LinphoneCoreConfiguringStatusCb; /** * Callback prototype for reporting network change either automatically detected or notified by #linphone_core_set_network_reachable. - * @param lc the LinphoneCore + * @param lc the #LinphoneCore * @param reachable true if network is reachable. */ typedef void (*LinphoneCoreCbsNetworkReachableCb)(LinphoneCore *lc, bool_t reachable); @@ -344,7 +344,7 @@ typedef LinphoneCoreCbsNetworkReachableCb LinphoneCoreNetworkReachableCb; /** * Callback prototype for reporting log collection upload state change. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] state The state of the log collection upload * @param[in] info Additional information: error message in case of error state, URL of uploaded file in case of success. */ @@ -357,7 +357,7 @@ typedef LinphoneCoreCbsLogCollectionUploadStateChangedCb LinphoneCoreLogCollecti /** * Callback prototype for reporting log collection upload progress indication. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object */ typedef void (*LinphoneCoreCbsLogCollectionUploadProgressIndicationCb)(LinphoneCore *lc, size_t offset, size_t total); @@ -368,8 +368,8 @@ typedef LinphoneCoreCbsLogCollectionUploadProgressIndicationCb LinphoneCoreLogCo /** * Callback prototype for reporting when a friend list has been added to the core friends list. - * @param[in] lc LinphoneCore object - * @param[in] list LinphoneFriendList object + * @param[in] lc #LinphoneCore object + * @param[in] list #LinphoneFriendList object */ typedef void (*LinphoneCoreCbsFriendListCreatedCb) (LinphoneCore *lc, LinphoneFriendList *list); @@ -380,8 +380,8 @@ typedef LinphoneCoreCbsFriendListCreatedCb LinphoneCoreFriendListCreatedCb; /** * Callback prototype for reporting when a friend list has been removed from the core friends list. - * @param[in] lc LinphoneCore object - * @param[in] list LinphoneFriendList object + * @param[in] lc #LinphoneCore object + * @param[in] list #LinphoneFriendList object */ typedef void (*LinphoneCoreCbsFriendListRemovedCb) (LinphoneCore *lc, LinphoneFriendList *list); @@ -392,16 +392,16 @@ typedef LinphoneCoreCbsFriendListRemovedCb LinphoneCoreFriendListRemovedCb; /** * Callback prototype for reporting the result of a version update check. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] result The result of the version update check - * @param[in] url The url where to download the new version if the result is LinphoneVersionUpdateCheckNewVersionAvailable + * @param[in] url The url where to download the new version if the result is #LinphoneVersionUpdateCheckNewVersionAvailable */ typedef void (*LinphoneCoreCbsVersionUpdateCheckResultReceivedCb) (LinphoneCore *lc, LinphoneVersionUpdateCheckResult result, const char *version, const char *url); /** - * Callback prototype telling that a LinphoneChatRoom state has changed. - * @param[in] lc LinphoneCore object - * @param[in] cr The LinphoneChatRoom object for which the state has changed + * Callback prototype telling that a #LinphoneChatRoom state has changed. + * @param[in] lc #LinphoneCore object + * @param[in] cr The #LinphoneChatRoom object for which the state has changed */ typedef void (*LinphoneCoreCbsChatRoomStateChangedCb) (LinphoneCore *lc, LinphoneChatRoom *cr, LinphoneChatRoomState state); @@ -431,6 +431,16 @@ typedef void (*LinphoneCoreCbsNotifyReceivedCb)(LinphoneCore *lc, LinphoneEvent */ typedef LinphoneCoreCbsNotifyReceivedCb LinphoneCoreNotifyReceivedCb; +/** + * Callback prototype for notifying the application about subscription received from the network. +**/ +typedef void (*LinphoneCoreCbsSubscribeReceivedCb)(LinphoneCore *lc, LinphoneEvent *lev, const char *subscribe_event, const LinphoneContent *body); + +/** + * Old name of #LinphoneCoreCbsSubscribeReceivedCb. + */ +typedef LinphoneCoreCbsSubscribeReceivedCb LinphoneCoreSubscribeReceivedCb; + /** * Callback prototype for notifying the application about changes of subscription states, including arrival of new subscriptions. **/ @@ -477,29 +487,29 @@ typedef void (*LinphoneEventCbsNotifyResponseCb)(const LinphoneEvent *ev); /** * Callback used to notify a new contact has been created on the CardDAV server and downloaded locally - * @param list The LinphoneFriendList object the new contact is added to - * @param lf The LinphoneFriend object that has been created + * @param list The #LinphoneFriendList object the new contact is added to + * @param lf The #LinphoneFriend object that has been created **/ typedef void (*LinphoneFriendListCbsContactCreatedCb)(LinphoneFriendList *list, LinphoneFriend *lf); /** * Callback used to notify a contact has been deleted on the CardDAV server - * @param list The LinphoneFriendList object a contact has been removed from - * @param lf The LinphoneFriend object that has been deleted + * @param list The #LinphoneFriendList object a contact has been removed from + * @param lf The #LinphoneFriend object that has been deleted **/ typedef void (*LinphoneFriendListCbsContactDeletedCb)(LinphoneFriendList *list, LinphoneFriend *lf); /** * Callback used to notify a contact has been updated on the CardDAV server - * @param list The LinphoneFriendList object in which a contact has been updated - * @param new_friend The new LinphoneFriend object corresponding to the updated contact - * @param old_friend The old LinphoneFriend object before update + * @param list The #LinphoneFriendList object in which a contact has been updated + * @param new_friend The new #LinphoneFriend object corresponding to the updated contact + * @param old_friend The old #LinphoneFriend object before update **/ typedef void (*LinphoneFriendListCbsContactUpdatedCb)(LinphoneFriendList *list, LinphoneFriend *new_friend, LinphoneFriend *old_friend); /** * Callback used to notify the status of the synchronization has changed - * @param list The LinphoneFriendList object for which the status has changed + * @param list The #LinphoneFriendList object for which the status has changed * @param status The new synchronisation status * @param msg An additional information on the status update **/ @@ -529,50 +539,50 @@ typedef void (*LinphoneCoreCbsEcCalibrationResultCb)(LinphoneCore *lc, LinphoneE typedef void (*LinphoneCoreCbsEcCalibrationAudioInitCb)(LinphoneCore *lc); /** - * @biref Function prototype used by #linphone_core_cbs_set_ec_calibrator_audio_uninit(). + * @brief Function prototype used by #linphone_core_cbs_set_ec_calibrator_audio_uninit(). * @param lc The core. */ typedef void (*LinphoneCoreCbsEcCalibrationAudioUninitCb)(LinphoneCore *lc); /** - * Callback to decrypt incoming LinphoneChatMessage + * Callback to decrypt incoming #LinphoneChatMessage * @param engine ImEncryptionEngine object - * @param room LinphoneChatRoom object - * @param msg LinphoneChatMessage object + * @param room #LinphoneChatRoom object + * @param msg #LinphoneChatMessage object * @return -1 if nothing to be done, 0 on success or an integer > 0 for error */ typedef int (*LinphoneImEncryptionEngineCbsIncomingMessageCb)(LinphoneImEncryptionEngine *engine, LinphoneChatRoom *room, LinphoneChatMessage *msg); /** - * Callback to encrypt outgoing LinphoneChatMessage - * @param engine LinphoneImEncryptionEngine object - * @param room LinphoneChatRoom object - * @param msg LinphoneChatMessage object + * Callback to encrypt outgoing #LinphoneChatMessage + * @param engine #LinphoneImEncryptionEngine object + * @param room #LinphoneChatRoom object + * @param msg #LinphoneChatMessage object * @return -1 if nothing to be done, 0 on success or an integer > 0 for error */ typedef int (*LinphoneImEncryptionEngineCbsOutgoingMessageCb)(LinphoneImEncryptionEngine *engine, LinphoneChatRoom *room, LinphoneChatMessage *msg); /** * Callback to know whether or not the engine will encrypt files before uploading them - * @param engine LinphoneImEncryptionEngine object - * @param room LinphoneChatRoom object + * @param engine #LinphoneImEncryptionEngine object + * @param room #LinphoneChatRoom object * @return TRUE if files will be encrypted, FALSE otherwise */ typedef bool_t (*LinphoneImEncryptionEngineCbsIsEncryptionEnabledForFileTransferCb)(LinphoneImEncryptionEngine *engine, LinphoneChatRoom *room); /** * Callback to generate the key used to encrypt the files before uploading them - * Key can be stored in the LinphoneContent object inside the LinphoneChatMessage using linphone_content_set_key - * @param engine LinphoneImEncryptionEngine object - * @param room LinphoneChatRoom object - * @param msg LinphoneChatMessage object + * Key can be stored in the #LinphoneContent object inside the #LinphoneChatMessage using linphone_content_set_key + * @param engine #LinphoneImEncryptionEngine object + * @param room #LinphoneChatRoom object + * @param msg #LinphoneChatMessage object */ typedef void (*LinphoneImEncryptionEngineCbsGenerateFileTransferKeyCb)(LinphoneImEncryptionEngine *engine, LinphoneChatRoom *room, LinphoneChatMessage *msg); /** * Callback to decrypt downloading file - * @param engine LinphoneImEncryptionEngine object - * @param msg LinphoneChatMessage object + * @param engine #LinphoneImEncryptionEngine object + * @param msg #LinphoneChatMessage object * @param offset The current offset of the upload * @param[in] buffer Encrypted data buffer * @param[in] size Size of the encrypted data buffer and maximum size of the decrypted data buffer @@ -583,8 +593,8 @@ typedef int (*LinphoneImEncryptionEngineCbsDownloadingFileCb)(LinphoneImEncrypti /** * Callback to encrypt uploading file - * @param engine LinphoneImEncryptionEngine object - * @param msg LinphoneChatMessage object + * @param engine #LinphoneImEncryptionEngine object + * @param msg #LinphoneChatMessage object * @param offset The current offset of the upload * @param[in] buffer Encrypted data buffer * @param[in,out] size Size of the plain data buffer and the size of the encrypted data buffer once encryption is done @@ -595,7 +605,7 @@ typedef int (*LinphoneImEncryptionEngineCbsUploadingFileCb)(LinphoneImEncryption /** * Callback used to notify the response to an XML-RPC request. - * @param[in] request LinphoneXmlRpcRequest object + * @param[in] request #LinphoneXmlRpcRequest object **/ typedef void (*LinphoneXmlRpcRequestCbsResponseCb)(LinphoneXmlRpcRequest *request); @@ -610,7 +620,7 @@ typedef void (*LinphoneXmlRpcRequestCbsResponseCb)(LinphoneXmlRpcRequest *reques /** * Callback for notifying end of play (file). - * @param[in] player The LinphonePlayer object + * @param[in] player The #LinphonePlayer object **/ typedef void (*LinphonePlayerCbsEofReachedCb)(LinphonePlayer *obj); diff --git a/include/linphone/conference.h b/include/linphone/conference.h index ea12eac85..d61425437 100644 --- a/include/linphone/conference.h +++ b/include/linphone/conference.h @@ -118,7 +118,7 @@ LINPHONE_PUBLIC LinphoneStatus linphone_conference_remove_participant(LinphoneCo LINPHONE_PUBLIC bctbx_list_t *linphone_conference_get_participants(const LinphoneConference *obj); /** - * Invite participants to the conference, by supplying a list of LinphoneAddress + * Invite participants to the conference, by supplying a list of #LinphoneAddress * @param obj The conference. * @param addresses \bctbx_list{LinphoneAddress} * @param params #LinphoneCallParams to use for inviting the participants. diff --git a/include/linphone/content.h b/include/linphone/content.h deleted file mode 100644 index 78ebc3114..000000000 --- a/include/linphone/content.h +++ /dev/null @@ -1,226 +0,0 @@ -/* -content.h -Copyright (C) 2010-2014 Belledonne Communications SARL - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#ifndef LINPHONE_CONTENT_H_ -#define LINPHONE_CONTENT_H_ - - -#include "linphone/types.h" - - -#ifdef __cplusplus -extern "C" { -#endif - - -/** - * @addtogroup misc - * @{ - */ - -/** - * Acquire a reference to the content. - * @param[in] content LinphoneContent object. - * @return The same LinphoneContent object. -**/ -LINPHONE_PUBLIC LinphoneContent * linphone_content_ref(LinphoneContent *content); - -/** - * Release reference to the content. - * @param[in] content LinphoneContent object. -**/ -LINPHONE_PUBLIC void linphone_content_unref(LinphoneContent *content); - -/** - * Retrieve the user pointer associated with the content. - * @param[in] content LinphoneContent object. - * @return The user pointer associated with the content. -**/ -LINPHONE_PUBLIC void *linphone_content_get_user_data(const LinphoneContent *content); - -/** - * Assign a user pointer to the content. - * @param[in] content LinphoneContent object. - * @param[in] ud The user pointer to associate with the content. -**/ -LINPHONE_PUBLIC void linphone_content_set_user_data(LinphoneContent *content, void *ud); - -/** - * Get the mime type of the content data. - * @param[in] content LinphoneContent object. - * @return The mime type of the content data, for example "application". - */ -LINPHONE_PUBLIC const char * linphone_content_get_type(const LinphoneContent *content); - -/** - * Set the mime type of the content data. - * @param[in] content LinphoneContent object. - * @param[in] type The mime type of the content data, for example "application". - */ -LINPHONE_PUBLIC void linphone_content_set_type(LinphoneContent *content, const char *type); - -/** - * Get the mime subtype of the content data. - * @param[in] content LinphoneContent object. - * @return The mime subtype of the content data, for example "html". - */ -LINPHONE_PUBLIC const char * linphone_content_get_subtype(const LinphoneContent *content); - -/** - * Set the mime subtype of the content data. - * @param[in] content LinphoneContent object. - * @param[in] subtype The mime subtype of the content data, for example "html". - */ -LINPHONE_PUBLIC void linphone_content_set_subtype(LinphoneContent *content, const char *subtype); - -/** - * Get the content data buffer, usually a string. - * @param[in] content LinphoneContent object. - * @return The content data buffer. - */ -LINPHONE_PUBLIC uint8_t * linphone_content_get_buffer(const LinphoneContent *content); - -/** - * Set the content data buffer, usually a string. - * @param[in] content LinphoneContent object. - * @param[in] buffer The content data buffer. - * @param[in] size The size of the content data buffer. - */ -LINPHONE_PUBLIC void linphone_content_set_buffer(LinphoneContent *content, const uint8_t *buffer, size_t size); - -/** - * Get the string content data buffer. - * @param[in] content LinphoneContent object - * @return The string content data buffer. - */ -LINPHONE_PUBLIC const char * linphone_content_get_string_buffer(const LinphoneContent *content); - -/** - * Set the string content data buffer. - * @param[in] content LinphoneContent object. - * @param[in] buffer The string content data buffer. - */ -LINPHONE_PUBLIC void linphone_content_set_string_buffer(LinphoneContent *content, const char *buffer); - -/** - * Get the content data buffer size, excluding null character despite null character is always set for convenience. - * @param[in] content LinphoneContent object. - * @return The content data buffer size. - */ -LINPHONE_PUBLIC size_t linphone_content_get_size(const LinphoneContent *content); - -/** - * Set the content data size, excluding null character despite null character is always set for convenience. - * @param[in] content LinphoneContent object - * @param[in] size The content data buffer size. - */ -LINPHONE_PUBLIC void linphone_content_set_size(LinphoneContent *content, size_t size); - -/** - * Get the encoding of the data buffer, for example "gzip". - * @param[in] content LinphoneContent object. - * @return The encoding of the data buffer. - */ -LINPHONE_PUBLIC const char * linphone_content_get_encoding(const LinphoneContent *content); - -/** - * Set the encoding of the data buffer, for example "gzip". - * @param[in] content LinphoneContent object. - * @param[in] encoding The encoding of the data buffer. - */ -LINPHONE_PUBLIC void linphone_content_set_encoding(LinphoneContent *content, const char *encoding); - -/** - * Get the name associated with a RCS file transfer message. It is used to store the original filename of the file to be downloaded from server. - * @param[in] content LinphoneContent object. - * @return The name of the content. - */ -LINPHONE_PUBLIC const char * linphone_content_get_name(const LinphoneContent *content); - -/** - * Set the name associated with a RCS file transfer message. It is used to store the original filename of the file to be downloaded from server. - * @param[in] content LinphoneContent object. - * @param[in] name The name of the content. - */ -LINPHONE_PUBLIC void linphone_content_set_name(LinphoneContent *content, const char *name); - -/** - * Tell whether a content is a multipart content. - * @param[in] content LinphoneContent object. - * @return A boolean value telling whether the content is multipart or not. - */ -LINPHONE_PUBLIC bool_t linphone_content_is_multipart(const LinphoneContent *content); - -/** - * Get a part from a multipart content according to its index. - * @param[in] content LinphoneContent object. - * @param[in] idx The index of the part to get. - * @return A LinphoneContent object holding the part if found, NULL otherwise. - */ -LINPHONE_PUBLIC LinphoneContent * linphone_content_get_part(const LinphoneContent *content, int idx); - -/** - * Find a part from a multipart content looking for a part header with a specified value. - * @param[in] content LinphoneContent object. - * @param[in] header_name The name of the header to look for. - * @param[in] header_value The value of the header to look for. - * @return A LinphoneContent object object the part if found, NULL otherwise. - */ -LINPHONE_PUBLIC LinphoneContent * linphone_content_find_part_by_header(const LinphoneContent *content, const char *header_name, const char *header_value); - -/** - * Get a custom header value of a content. - * @param[in] content LinphoneContent object. - * @param[in] header_name The name of the header to get the value from. - * @return The value of the header if found, NULL otherwise. - */ -LINPHONE_PUBLIC const char * linphone_content_get_custom_header(const LinphoneContent *content, const char *header_name); - -/** - * Get the key associated with a RCS file transfer message if encrypted - * @param[in] content LinphoneContent object. - * @return The key to encrypt/decrypt the file associated to this content. - */ -LINPHONE_PUBLIC const char *linphone_content_get_key(const LinphoneContent *content); - -/** - * Get the size of key associated with a RCS file transfer message if encrypted - * @param[in] content LinphoneContent object. - * @return The key size in bytes - */ -LINPHONE_PUBLIC size_t linphone_content_get_key_size(const LinphoneContent *content); - -/** - * Set the key associated with a RCS file transfer message if encrypted - * @param[in] content LinphoneContent object. - * @param[in] key The key to be used to encrypt/decrypt file associated to this content. - * @param[in] keyLength The lengh of the key. - */ -LINPHONE_PUBLIC void linphone_content_set_key(LinphoneContent *content, const char *key, const size_t keyLength); - -/** - * @} - */ - - -#ifdef __cplusplus -} -#endif - -#endif /* LINPHONE_CONTENT_H_ */ diff --git a/include/linphone/core.h b/include/linphone/core.h index df88100dc..027709570 100644 --- a/include/linphone/core.h +++ b/include/linphone/core.h @@ -42,7 +42,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "linphone/call_stats.h" #include "linphone/chat.h" #include "linphone/conference.h" -#include "linphone/content.h" #include "linphone/dictionary.h" #include "linphone/error_info.h" #include "linphone/event.h" @@ -74,7 +73,7 @@ extern "C" { #endif /** - * Safely down-cast a belle_sip_object_t into LinphoneCore + * Safely down-cast a belle_sip_object_t into #LinphoneCore * @ingroup initializing */ #define LINPHONE_CORE(object) BELLE_SIP_CAST(object, LinphoneCore) @@ -98,9 +97,9 @@ LINPHONE_PUBLIC LinphoneAddress * linphone_core_create_address(LinphoneCore *lc, /** * Create an independent media file player. * This player support WAVE and MATROSKA formats. - * @param lc A LinphoneCore object - * @param sound_card_name Playback sound card. If NULL, the ringer sound card set in LinphoneCore will be used - * @param video_display_name Video display. If NULL, the video display set in LinphoneCore will be used + * @param lc A #LinphoneCore object + * @param sound_card_name Playback sound card. If NULL, the ringer sound card set in #LinphoneCore will be used + * @param video_display_name Video display. If NULL, the video display set in #LinphoneCore will be used * @param window_id Id of the drawing window. Depend of video out * @return A pointer on the new instance. NULL if faild. */ @@ -108,7 +107,7 @@ LINPHONE_PUBLIC LinphonePlayer *linphone_core_create_local_player(LinphoneCore * /** * Creates an empty info message. - * @param lc the LinphoneCore + * @param lc the #LinphoneCore * @return a new LinphoneInfoMessage. * * The info message can later be filled with information using linphone_info_message_add_header() or linphone_info_message_set_content(), @@ -126,7 +125,7 @@ LINPHONE_PUBLIC LinphoneMagicSearch *linphone_core_create_magic_search(LinphoneC /** * Checks if a new version of the application is available. - * @param lc LinphoneCore object + * @param lc #LinphoneCore object * @param current_version The current version of the application */ LINPHONE_PUBLIC void linphone_core_check_for_update(LinphoneCore *lc, const char *current_version); @@ -137,7 +136,7 @@ LINPHONE_PUBLIC void linphone_core_check_for_update(LinphoneCore *lc, const char /** * Get the remote address of the current call. - * @param[in] lc LinphoneCore object. + * @param[in] lc #LinphoneCore object. * @return The remote address of the current call or NULL if there is no current call. * @ingroup call_control */ @@ -182,9 +181,9 @@ typedef struct _LinphoneCoreVTable{ LinphoneCoreInfoReceivedCb info_received; /**data field of the bctbx_list_t points a PayloadType @@ -1735,10 +1769,10 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED const bctbx_list_t *linphone_core_get_audio_ /** * Sets the list of audio codecs. - * @param[in] lc The LinphoneCore object + * @param[in] lc The #LinphoneCore object * @param[in] codecs \bctbx_list{OrtpPayloadType} * @return 0 - * The list is taken by the LinphoneCore thus the application should not free it. + * The list is taken by the #LinphoneCore thus the application should not free it. * This list is made of struct PayloadType describing the codec parameters. * @ingroup media_parameters * @deprecated Use linphone_core_set_audio_payload_types() instead. @@ -1766,7 +1800,7 @@ LINPHONE_PUBLIC void linphone_core_set_video_payload_types(LinphoneCore *lc, con /** * Returns the list of available video codecs. - * @param[in] lc The LinphoneCore object + * @param[in] lc The #LinphoneCore object * @return \bctbx_list{OrtpPayloadType} * * This list is unmodifiable. The ->data field of the bctbx_list_t points a PayloadType @@ -1781,11 +1815,11 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED const bctbx_list_t *linphone_core_get_video_ /** * Sets the list of video codecs. - * @param[in] lc The LinphoneCore object + * @param[in] lc The #LinphoneCore object * @param[in] codecs \bctbx_list{OrtpPayloadType} * @return 0 * - * The list is taken by the LinphoneCore thus the application should not free it. + * The list is taken by the #LinphoneCore thus the application should not free it. * This list is made of struct PayloadType describing the codec parameters. * @ingroup media_parameters * @deprecated Use linphone_core_set_video_payload_types() instead. @@ -1813,7 +1847,7 @@ LINPHONE_PUBLIC void linphone_core_set_text_payload_types(LinphoneCore *lc, cons /** * Returns the list of available text codecs. - * @param[in] lc The LinphoneCore object + * @param[in] lc The #LinphoneCore object * @return \bctbx_list{OrtpPayloadType} * * This list is unmodifiable. The ->data field of the bctbx_list_t points a PayloadType @@ -1828,11 +1862,11 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED const bctbx_list_t *linphone_core_get_text_c /** * Sets the list of text codecs. - * @param[in] lc The LinphoneCore object + * @param[in] lc The #LinphoneCore object * @param[in] codecs \bctbx_list{LinphonePayloadType} * @return 0 * - * The list is taken by the LinphoneCore thus the application should not free it. + * The list is taken by the #LinphoneCore thus the application should not free it. * This list is made of struct PayloadType describing the codec parameters. * @ingroup media_parameters * @deprecated Use linphone_core_set_text_payload_types() instead. @@ -1843,7 +1877,7 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneStatus linphone_core_set_text_codecs /** * Enable RFC3389 generic comfort noise algorithm (CN payload type). * It is disabled by default, because this algorithm is only relevant for legacy codecs (PCMU, PCMA, G722). - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] enabled TRUE if enabled, FALSE otherwise. * @deprecated Use linphone_core_enable_generic_comfort_noise() instead */ @@ -1851,7 +1885,7 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneStatus linphone_core_set_text_codecs /** * Returns enablement of RFC3389 generic comfort noise algorithm. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return TRUE or FALSE. * @deprecated Use linphone_core_generic_comfort_noise_enabled() instead */ @@ -1860,14 +1894,14 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneStatus linphone_core_set_text_codecs /** * Enable RFC3389 generic comfort noise algorithm (CN payload type). * It is disabled by default, because this algorithm is only relevant for legacy codecs (PCMU, PCMA, G722). - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] enabled TRUE if enabled, FALSE otherwise. **/ LINPHONE_PUBLIC void linphone_core_enable_generic_comfort_noise(LinphoneCore *lc, bool_t enabled); /** * Returns enablement of RFC3389 generic comfort noise algorithm. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return TRUE or FALSE. **/ LINPHONE_PUBLIC bool_t linphone_core_generic_comfort_noise_enabled(const LinphoneCore *lc); @@ -1977,7 +2011,7 @@ LINPHONE_PUBLIC LinphonePayloadType *linphone_core_get_payload_type(LinphoneCore LINPHONE_PUBLIC LINPHONE_DEPRECATED int linphone_core_get_payload_type_number(LinphoneCore *lc, const OrtpPayloadType *pt); /** - * Force a number for a payload type. The LinphoneCore does payload type number assignment automatically. THis function is to be used mainly for tests, in order + * Force a number for a payload type. The #LinphoneCore does payload type number assignment automatically. THis function is to be used mainly for tests, in order * to override the automatic assignment mechanism. * @ingroup media_parameters * @deprecated Use linphone_payload_type_set_number() instead @@ -2029,14 +2063,14 @@ LINPHONE_PUBLIC void linphone_core_clear_proxy_config(LinphoneCore *lc); /** * Removes a proxy configuration. * - * LinphoneCore will then automatically unregister and place the proxy configuration + * #LinphoneCore will then automatically unregister and place the proxy configuration * on a deleted list. For that reason, a removed proxy does NOT need to be freed. **/ LINPHONE_PUBLIC void linphone_core_remove_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *config); /** * Returns an unmodifiable list of entered proxy configurations. - * @param[in] lc The LinphoneCore object + * @param[in] lc The #LinphoneCore object * @return \bctbx_list{LinphoneProxyConfig} **/ LINPHONE_PUBLIC const bctbx_list_t *linphone_core_get_proxy_config_list(const LinphoneCore *lc); @@ -2055,7 +2089,7 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED int linphone_core_get_default_proxy(Linphone /** * @return the default proxy configuration, that is the one used to determine the current identity. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The default proxy configuration. **/ LINPHONE_PUBLIC LinphoneProxyConfig * linphone_core_get_default_proxy_config(const LinphoneCore *lc); @@ -2064,9 +2098,9 @@ LINPHONE_PUBLIC LinphoneProxyConfig * linphone_core_get_default_proxy_config(con * Sets the default proxy. * * This default proxy must be part of the list of already entered LinphoneProxyConfig. - * Toggling it as default will make LinphoneCore use the identity associated with + * Toggling it as default will make #LinphoneCore use the identity associated with * the proxy configuration in all incoming and outgoing calls. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] config The proxy configuration to use as the default one. **/ LINPHONE_PUBLIC void linphone_core_set_default_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *config); @@ -2108,7 +2142,7 @@ LINPHONE_PUBLIC void linphone_core_remove_auth_info(LinphoneCore *lc, const Linp /** * Returns an unmodifiable list of currently entered #LinphoneAuthInfo. - * @param[in] lc The LinphoneCore object. + * @param[in] lc The #LinphoneCore object. * @return \bctbx_list{LinphoneAuthInfo} * @ingroup authentication */ @@ -2117,7 +2151,7 @@ LINPHONE_PUBLIC const bctbx_list_t *linphone_core_get_auth_info_list(const Linph /** * Find authentication info matching realm, username, domain criteria. * First of all, (realm,username) pair are searched. If multiple results (which should not happen because realm are supposed to be unique), then domain is added to the search. - * @param lc the LinphoneCore + * @param lc the #LinphoneCore * @param realm the authentication 'realm' (optional) * @param username the SIP username to be authenticated (mandatory) * @param sip_domain the SIP domain name (optional) @@ -2127,7 +2161,7 @@ LINPHONE_PUBLIC const bctbx_list_t *linphone_core_get_auth_info_list(const Linph LINPHONE_PUBLIC const LinphoneAuthInfo *linphone_core_find_auth_info(LinphoneCore *lc, const char *realm, const char *username, const char *sip_domain); /** - * This method is used to abort a user authentication request initiated by LinphoneCore + * This method is used to abort a user authentication request initiated by #LinphoneCore * from the auth_info_requested callback of LinphoneCoreVTable. * @note That function does nothing for now. **/ @@ -2141,15 +2175,15 @@ LINPHONE_PUBLIC void linphone_core_clear_all_auth_info(LinphoneCore *lc); /** * Sets an default account creator service in the core - * @param lc LinphoneCore object - * @param cbs LinphoneAccountCreatorService object + * @param lc #LinphoneCore object + * @param cbs #LinphoneAccountCreatorService object **/ LINPHONE_PUBLIC void linphone_core_set_account_creator_service(LinphoneCore *lc, LinphoneAccountCreatorService *service); /** * Get default account creator service from the core - * @param lc LinphoneCore object - * @return LinphoneAccountCreatorService object + * @param lc #LinphoneCore object + * @return #LinphoneAccountCreatorService object **/ LINPHONE_PUBLIC LinphoneAccountCreatorService * linphone_core_get_account_creator_service(LinphoneCore *lc); @@ -2171,7 +2205,7 @@ LINPHONE_PUBLIC bool_t linphone_core_audio_adaptive_jittcomp_enabled(LinphoneCor /** * Returns the nominal audio jitter buffer size in milliseconds. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The nominal audio jitter buffer size in milliseconds * @ingroup media_parameters **/ @@ -2203,7 +2237,7 @@ LINPHONE_PUBLIC bool_t linphone_core_video_adaptive_jittcomp_enabled(LinphoneCor /** * Returns the nominal video jitter buffer size in milliseconds. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The nominal video jitter buffer size in milliseconds * @ingroup media_parameters **/ @@ -2219,7 +2253,7 @@ LINPHONE_PUBLIC void linphone_core_set_video_jittcomp(LinphoneCore *lc, int mill /** * Gets the UDP port used for audio streaming. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The UDP port used for audio streaming * @ingroup network_parameters **/ @@ -2227,7 +2261,7 @@ LINPHONE_PUBLIC int linphone_core_get_audio_port(const LinphoneCore *lc); /** * Get the audio port range from which is randomly chosen the UDP port used for audio streaming. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[out] min_port The lower bound of the audio port range being used * @param[out] max_port The upper bound of the audio port range being used * @ingroup network_parameters @@ -2237,15 +2271,15 @@ LINPHONE_PUBLIC void linphone_core_get_audio_port_range(const LinphoneCore *lc, /** * Get the audio port range from which is randomly chosen the UDP port used for audio streaming. - * @param[in] lc LinphoneCore object - * @return a LinphoneRange object + * @param[in] lc #LinphoneCore object + * @return a #LinphoneRange object * @ingroup network_parameters */ LINPHONE_PUBLIC LinphoneRange *linphone_core_get_audio_ports_range(const LinphoneCore *lc); /** * Gets the UDP port used for video streaming. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The UDP port used for video streaming * @ingroup network_parameters **/ @@ -2253,7 +2287,7 @@ LINPHONE_PUBLIC int linphone_core_get_video_port(const LinphoneCore *lc); /** * Get the video port range from which is randomly chosen the UDP port used for video streaming. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[out] min_port The lower bound of the video port range being used * @param[out] max_port The upper bound of the video port range being used * @ingroup network_parameters @@ -2263,15 +2297,15 @@ LINPHONE_PUBLIC void linphone_core_get_video_port_range(const LinphoneCore *lc, /** * Get the video port range from which is randomly chosen the UDP port used for video streaming. - * @param[in] lc LinphoneCore object - * @return a LinphoneRange object + * @param[in] lc #LinphoneCore object + * @return a #LinphoneRange object * @ingroup network_parameters */ LINPHONE_PUBLIC LinphoneRange *linphone_core_get_video_ports_range(const LinphoneCore *lc); /** * Gets the UDP port used for text streaming. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The UDP port used for text streaming * @ingroup network_parameters **/ @@ -2279,7 +2313,7 @@ LINPHONE_PUBLIC int linphone_core_get_text_port(const LinphoneCore *lc); /** * Get the video port range from which is randomly chosen the UDP port used for text streaming. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[out] min_port The lower bound of the text port range being used * @param[out] max_port The upper bound of the text port range being used * @ingroup network_parameters @@ -2289,8 +2323,8 @@ LINPHONE_PUBLIC void linphone_core_get_text_port_range(const LinphoneCore *lc, i /** * Get the text port range from which is randomly chosen the UDP port used for text streaming. - * @param[in] lc LinphoneCore object - * @return a LinphoneRange object + * @param[in] lc #LinphoneCore object + * @return a #LinphoneRange object * @ingroup network_parameters */ LINPHONE_PUBLIC LinphoneRange *linphone_core_get_text_ports_range(const LinphoneCore *lc); @@ -2299,10 +2333,10 @@ LINPHONE_PUBLIC LinphoneRange *linphone_core_get_text_ports_range(const Linphone * Gets the value of the no-rtp timeout. * * When no RTP or RTCP packets have been received for a while - * LinphoneCore will consider the call is broken (remote end crashed or + * #LinphoneCore will consider the call is broken (remote end crashed or * disconnected from the network), and thus will terminate the call. * The no-rtp timeout is the duration above which the call is considered broken. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The value of the no-rtp timeout in seconds * @ingroup media_parameters **/ @@ -2312,7 +2346,7 @@ LINPHONE_PUBLIC int linphone_core_get_nortp_timeout(const LinphoneCore *lc); * Sets the UDP port used for audio streaming. * A value of -1 will request the system to allocate the local port randomly. * This is recommended in order to avoid firewall warnings. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] port The UDP port to use for audio streaming * @ingroup network_parameters **/ @@ -2320,7 +2354,7 @@ LINPHONE_PUBLIC void linphone_core_set_audio_port(LinphoneCore *lc, int port); /** * Sets the UDP port range from which to randomly select the port used for audio streaming. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] min_port The lower bound of the audio port range to use * @param[in] max_port The upper bound of the audio port range to use * @ingroup media_parameters @@ -2331,7 +2365,7 @@ LINPHONE_PUBLIC void linphone_core_set_audio_port_range(LinphoneCore *lc, int mi * Sets the UDP port used for video streaming. * A value of -1 will request the system to allocate the local port randomly. * This is recommended in order to avoid firewall warnings. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] port The UDP port to use for video streaming * @ingroup network_parameters **/ @@ -2339,7 +2373,7 @@ LINPHONE_PUBLIC void linphone_core_set_video_port(LinphoneCore *lc, int port); /** * Sets the UDP port range from which to randomly select the port used for video streaming. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] min_port The lower bound of the video port range to use * @param[in] max_port The upper bound of the video port range to use * @ingroup media_parameters @@ -2350,7 +2384,7 @@ LINPHONE_PUBLIC void linphone_core_set_video_port_range(LinphoneCore *lc, int mi * Sets the UDP port used for text streaming. * A value if -1 will request the system to allocate the local port randomly. * This is recommended in order to avoid firewall warnings. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] port The UDP port to use for text streaming * @ingroup network_parameters **/ @@ -2358,7 +2392,7 @@ LINPHONE_PUBLIC void linphone_core_set_text_port(LinphoneCore *lc, int port); /** * Sets the UDP port range from which to randomly select the port used for text streaming. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] min_port The lower bound of the text port range to use * @param[in] max_port The upper bound of the text port range to use * @ingroup media_parameters @@ -2367,7 +2401,7 @@ LINPHONE_PUBLIC void linphone_core_set_text_port_range(LinphoneCore *lc, int min /** * Sets the no-rtp timeout value in seconds. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] seconds The no-rtp timeout value to use in seconds * @ingroup media_parameters * @see linphone_core_get_nortp_timeout() for details. @@ -2376,7 +2410,7 @@ LINPHONE_PUBLIC void linphone_core_set_nortp_timeout(LinphoneCore *lc, int secon /** * Sets whether SIP INFO is to be used to send digits. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] use_info A boolean value telling whether to use SIP INFO to send digits * @ingroup media_parameters **/ @@ -2384,7 +2418,7 @@ LINPHONE_PUBLIC void linphone_core_set_use_info_for_dtmf(LinphoneCore *lc, bool_ /** * Indicates whether SIP INFO is used to send digits. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return A boolean value telling whether SIP INFO is used to send digits * @ingroup media_parameters **/ @@ -2392,7 +2426,7 @@ LINPHONE_PUBLIC bool_t linphone_core_get_use_info_for_dtmf(LinphoneCore *lc); /** * Sets whether RFC2833 is to be used to send digits. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] use_rfc2833 A boolean value telling whether to use RFC2833 to send digits * @ingroup media_parameters **/ @@ -2400,7 +2434,7 @@ LINPHONE_PUBLIC void linphone_core_set_use_rfc2833_for_dtmf(LinphoneCore *lc,boo /** * Indicates whether RFC2833 is used to send digits. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return A boolean value telling whether RFC2833 is used to send digits * @ingroup media_parameters **/ @@ -2408,7 +2442,7 @@ LINPHONE_PUBLIC bool_t linphone_core_get_use_rfc2833_for_dtmf(LinphoneCore *lc); /** * Sets the UDP port to be used by SIP. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] port The UDP port to be used by SIP * @ingroup network_parameters * @deprecated use linphone_core_set_sip_transports() instead. @@ -2418,7 +2452,7 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_core_set_sip_port(LinphoneCore /** * Gets the UDP port used by SIP. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The UDP port used by SIP * @ingroup network_parameters * @deprecated use linphone_core_get_sip_transports() instead. @@ -2430,8 +2464,8 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED int linphone_core_get_sip_port(LinphoneCore * Sets the ports to be used for each of transport (UDP or TCP) * A zero value port for a given transport means the transport * is not used. A value of LC_SIP_TRANSPORT_RANDOM (-1) means the port is to be choosen randomly by the system. - * @param[in] lc LinphoneCore object - * @param[in] transports A LinphoneSipTransports structure giving the ports to use + * @param[in] lc #LinphoneCore object + * @param[in] transports A #LinphoneSipTransports structure giving the ports to use * @return 0 * @ingroup network_parameters * @deprecated Use linphone_core_set_transports instead @@ -2443,7 +2477,7 @@ LINPHONE_PUBLIC LinphoneStatus linphone_core_set_sip_transports(LinphoneCore *lc * Retrieves the port configuration used for each transport (udp, tcp, tls). * A zero value port for a given transport means the transport * is not used. A value of LC_SIP_TRANSPORT_RANDOM (-1) means the port is to be chosen randomly by the system. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[out] transports A #LinphoneSipTransports structure that will receive the configured ports * @return 0 * @ingroup network_parameters @@ -2456,7 +2490,7 @@ LINPHONE_PUBLIC LinphoneStatus linphone_core_get_sip_transports(LinphoneCore *lc * Retrieves the real port number assigned for each sip transport (udp, tcp, tls). * A zero value means that the transport is not activated. * If LC_SIP_TRANSPORT_RANDOM was passed to linphone_core_set_sip_transports(), the random port choosed by the system is returned. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[out] tr A #LinphoneSipTransports structure that will receive the ports being used * @ingroup network_parameters * @deprecated Use linphone_core_get_transports_used instead @@ -2468,8 +2502,8 @@ LINPHONE_PUBLIC void linphone_core_get_sip_transports_used(LinphoneCore *lc, Lin * Sets the ports to be used for each of transport (UDP or TCP) * A zero value port for a given transport means the transport * is not used. A value of LC_SIP_TRANSPORT_RANDOM (-1) means the port is to be choosen randomly by the system. - * @param[in] lc LinphoneCore object - * @param[in] transports A LinphoneSipTransports structure giving the ports to use + * @param[in] lc #LinphoneCore object + * @param[in] transports A #LinphoneSipTransports structure giving the ports to use * @return 0 * @ingroup network_parameters **/ @@ -2479,7 +2513,7 @@ LINPHONE_PUBLIC LinphoneStatus linphone_core_set_transports(LinphoneCore *lc, co * Retrieves the port configuration used for each transport (udp, tcp, tls). * A zero value port for a given transport means the transport * is not used. A value of LC_SIP_TRANSPORT_RANDOM (-1) means the port is to be chosen randomly by the system. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return A #LinphoneTransports structure with the configured ports * @ingroup network_parameters **/ @@ -2489,7 +2523,7 @@ LINPHONE_PUBLIC LinphoneTransports *linphone_core_get_transports(LinphoneCore *l * Retrieves the real port number assigned for each sip transport (udp, tcp, tls). * A zero value means that the transport is not activated. * If LC_SIP_TRANSPORT_RANDOM was passed to linphone_core_set_sip_transports(), the random port choosed by the system is returned. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return A #LinphoneTransports structure with the ports being used * @ingroup network_parameters **/ @@ -2497,93 +2531,93 @@ LINPHONE_PUBLIC LinphoneTransports *linphone_core_get_transports_used(LinphoneCo /** * Increment refcount. - * @param[in] transports LinphoneTransports object + * @param[in] transports #LinphoneTransports object * @ingroup network_parameters **/ LINPHONE_PUBLIC LinphoneTransports *linphone_transports_ref(LinphoneTransports *transports); /** * Decrement refcount and possibly free the object. - * @param[in] transports LinphoneTransports object + * @param[in] transports #LinphoneTransports object * @ingroup network_parameters **/ LINPHONE_PUBLIC void linphone_transports_unref(LinphoneTransports *transports); /** - * Gets the user data in the LinphoneTransports object - * @param[in] transports the LinphoneTransports + * Gets the user data in the #LinphoneTransports object + * @param[in] transports the #LinphoneTransports * @return the user data * @ingroup network_parameters */ LINPHONE_PUBLIC void *linphone_transports_get_user_data(const LinphoneTransports *transports); /** - * Sets the user data in the LinphoneTransports object - * @param[in] transports the LinphoneTransports object + * Sets the user data in the #LinphoneTransports object + * @param[in] transports the #LinphoneTransports object * @param[in] data the user data * @ingroup network_parameters */ LINPHONE_PUBLIC void linphone_transports_set_user_data(LinphoneTransports *transports, void *data); /** - * Gets the UDP port in the LinphoneTransports object - * @param[in] transports the LinphoneTransports object + * Gets the UDP port in the #LinphoneTransports object + * @param[in] transports the #LinphoneTransports object * @return the UDP port * @ingroup network_parameters */ LINPHONE_PUBLIC int linphone_transports_get_udp_port(const LinphoneTransports* transports); /** - * Gets the TCP port in the LinphoneTransports object - * @param[in] transports the LinphoneTransports object + * Gets the TCP port in the #LinphoneTransports object + * @param[in] transports the #LinphoneTransports object * @return the TCP port * @ingroup network_parameters */ LINPHONE_PUBLIC int linphone_transports_get_tcp_port(const LinphoneTransports* transports); /** - * Gets the TLS port in the LinphoneTransports object - * @param[in] transports the LinphoneTransports object + * Gets the TLS port in the #LinphoneTransports object + * @param[in] transports the #LinphoneTransports object * @return the TLS port * @ingroup network_parameters */ LINPHONE_PUBLIC int linphone_transports_get_tls_port(const LinphoneTransports* transports); /** - * Gets the DTLS port in the LinphoneTransports object - * @param[in] transports the LinphoneTransports object + * Gets the DTLS port in the #LinphoneTransports object + * @param[in] transports the #LinphoneTransports object * @return the DTLS port * @ingroup network_parameters */ LINPHONE_PUBLIC int linphone_transports_get_dtls_port(const LinphoneTransports* transports); /** - * Sets the UDP port in the LinphoneTransports object - * @param[in] transports the LinphoneTransports object + * Sets the UDP port in the #LinphoneTransports object + * @param[in] transports the #LinphoneTransports object * @param[in] port the UDP port * @ingroup network_parameters */ LINPHONE_PUBLIC void linphone_transports_set_udp_port(LinphoneTransports *transports, int port); /** - * Sets the TCP port in the LinphoneTransports object - * @param[in] transports the LinphoneTransports object + * Sets the TCP port in the #LinphoneTransports object + * @param[in] transports the #LinphoneTransports object * @param[in] port the TCP port * @ingroup network_parameters */ LINPHONE_PUBLIC void linphone_transports_set_tcp_port(LinphoneTransports *transports, int port); /** - * Sets the TLS port in the LinphoneTransports object - * @param[in] transports the LinphoneTransports object + * Sets the TLS port in the #LinphoneTransports object + * @param[in] transports the #LinphoneTransports object * @param[in] port the TLS port * @ingroup network_parameters */ LINPHONE_PUBLIC void linphone_transports_set_tls_port(LinphoneTransports *transports, int port); /** - * Sets the DTLS port in the LinphoneTransports object - * @param[in] transports the LinphoneTransports object + * Sets the DTLS port in the #LinphoneTransports object + * @param[in] transports the #LinphoneTransports object * @param[in] port the DTLS port * @ingroup network_parameters */ @@ -2591,8 +2625,8 @@ LINPHONE_PUBLIC void linphone_transports_set_dtls_port(LinphoneTransports *trans /** * Tells whether the given transport type is supported by the library. - * @param[in] lc LinphoneCore object - * @param[in] tp LinphoneTranportType to check for support + * @param[in] lc #LinphoneCore object + * @param[in] tp #LinphoneTranportType to check for support * @return A boolean value telling whether the given transport type is supported by the library **/ LINPHONE_PUBLIC bool_t linphone_core_sip_transport_supported(const LinphoneCore *lc, LinphoneTransportType tp); @@ -2611,7 +2645,7 @@ ortp_socket_t linphone_core_get_sip_socket(LinphoneCore *lc); * Set the incoming call timeout in seconds. * If an incoming call isn't answered for this timeout period, it is * automatically declined. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] seconds The new timeout in seconds * @ingroup call_control **/ @@ -2620,7 +2654,7 @@ LINPHONE_PUBLIC void linphone_core_set_inc_timeout(LinphoneCore *lc, int seconds /** * Returns the incoming call timeout * See linphone_core_set_inc_timeout() for details. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The current incoming call timeout in seconds * @ingroup call_control **/ @@ -2629,7 +2663,7 @@ LINPHONE_PUBLIC int linphone_core_get_inc_timeout(LinphoneCore *lc); /** * Set the in call timeout in seconds. * After this timeout period, the call is automatically hangup. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] seconds The new timeout in seconds * @ingroup call_control **/ @@ -2638,7 +2672,7 @@ LINPHONE_PUBLIC void linphone_core_set_in_call_timeout(LinphoneCore *lc, int sec /** * Gets the in call timeout * See linphone_core_set_in_call_timeout() for details. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The current in call timeout in seconds * @ingroup call_control **/ @@ -2647,7 +2681,7 @@ LINPHONE_PUBLIC int linphone_core_get_in_call_timeout(LinphoneCore *lc); /** * Set the in delayed timeout in seconds. * After this timeout period, a delayed call (internal call initialisation or resolution) is resumed. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] seconds The new delayed timeout * @ingroup call_control **/ @@ -2656,7 +2690,7 @@ LINPHONE_PUBLIC void linphone_core_set_delayed_timeout(LinphoneCore *lc, int sec /** * Gets the delayed timeout * See linphone_core_set_delayed_timeout() for details. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The current delayed timeout in seconds * @ingroup call_control **/ @@ -2745,7 +2779,7 @@ LINPHONE_DEPRECATED LINPHONE_PUBLIC LinphoneFirewallPolicy linphone_core_get_fir * Set the policy to use to pass through NATs/firewalls. * It may be overridden by a NAT policy for a specific proxy config. * @param[in] lc #LinphoneCore object - * @param[in] policy LinphoneNatPolicy object + * @param[in] policy #LinphoneNatPolicy object * @ingroup network_parameters * @see linphone_proxy_config_set_nat_policy() */ @@ -2755,7 +2789,7 @@ LINPHONE_PUBLIC void linphone_core_set_nat_policy(LinphoneCore *lc, LinphoneNatP * Get The policy that is used to pass through NATs/firewalls. * It may be overridden by a NAT policy for a specific proxy config. * @param[in] lc #LinphoneCore object - * @return LinphoneNatPolicy object in use. + * @return #LinphoneNatPolicy object in use. * @ingroup network_parameters * @see linphone_proxy_config_get_nat_policy() */ @@ -2763,7 +2797,7 @@ LINPHONE_PUBLIC LinphoneNatPolicy * linphone_core_get_nat_policy(const LinphoneC /** * Gets the list of the available sound devices. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return An unmodifiable array of strings contanining the names of the available sound devices that is NULL terminated * @ingroup media_parameters * @donotwrap @@ -2773,7 +2807,7 @@ LINPHONE_PUBLIC const char** linphone_core_get_sound_devices(LinphoneCore *lc); /** * Gets the list of the available sound devices. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return \bctbx_list{char *} An unmodifiable array of strings contanining the names of the available sound devices that is NULL terminated * @ingroup media_parameters **/ @@ -2796,7 +2830,7 @@ LINPHONE_PUBLIC void linphone_core_reload_sound_devices(LinphoneCore *lc); /** * Tells whether a specified sound device can capture sound. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] device the device name as returned by linphone_core_get_sound_devices() * @return A boolean value telling whether the specified sound device can capture sound * @ingroup media_parameters @@ -2805,7 +2839,7 @@ LINPHONE_PUBLIC bool_t linphone_core_sound_device_can_capture(LinphoneCore *lc, /** * Tells whether a specified sound device can play sound. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] device the device name as returned by linphone_core_get_sound_devices() * @return A boolean value telling whether the specified sound device can play sound * @ingroup media_parameters @@ -2866,7 +2900,7 @@ LINPHONE_DEPRECATED void linphone_core_set_sound_source(LinphoneCore *lc, char s /** * Allow to control microphone level: gain in db. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] level The new microphone level * @ingroup media_parameters **/ @@ -2874,7 +2908,7 @@ LINPHONE_PUBLIC void linphone_core_set_mic_gain_db(LinphoneCore *lc, float level /** * Get microphone gain in db. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The current microphone gain * @ingroup media_parameters **/ @@ -2882,7 +2916,7 @@ LINPHONE_PUBLIC float linphone_core_get_mic_gain_db(LinphoneCore *lc); /** * Allow to control play level before entering sound card: gain in db - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] level The new play level * @ingroup media_parameters **/ @@ -2890,7 +2924,7 @@ LINPHONE_PUBLIC void linphone_core_set_playback_gain_db(LinphoneCore *lc, float /** * Get playback gain in db before entering sound card. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The current playback gain * @ingroup media_parameters **/ @@ -2898,7 +2932,7 @@ LINPHONE_PUBLIC float linphone_core_get_playback_gain_db(LinphoneCore *lc); /** * Gets the name of the currently assigned sound device for ringing. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The name of the currently assigned sound device for ringing * @ingroup media_parameters **/ @@ -2906,7 +2940,7 @@ LINPHONE_PUBLIC const char * linphone_core_get_ringer_device(LinphoneCore *lc); /** * Gets the name of the currently assigned sound device for playback. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The name of the currently assigned sound device for playback * @ingroup media_parameters **/ @@ -2914,7 +2948,7 @@ LINPHONE_PUBLIC const char * linphone_core_get_playback_device(LinphoneCore *lc) /** * Gets the name of the currently assigned sound device for capture. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The name of the currently assigned sound device for capture * @ingroup media_parameters **/ @@ -2922,7 +2956,7 @@ LINPHONE_PUBLIC const char * linphone_core_get_capture_device(LinphoneCore *lc); /** * Sets the sound device used for ringing. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] devid The device name as returned by linphone_core_get_sound_devices() * @return 0 * @ingroup media_parameters @@ -2931,7 +2965,7 @@ LINPHONE_PUBLIC LinphoneStatus linphone_core_set_ringer_device(LinphoneCore *lc, /** * Sets the sound device used for playback. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] devid The device name as returned by linphone_core_get_sound_devices() * @return 0 * @ingroup media_parameters @@ -2940,7 +2974,7 @@ LINPHONE_PUBLIC LinphoneStatus linphone_core_set_playback_device(LinphoneCore *l /** * Sets the sound device used for capture. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] devid The device name as returned by linphone_core_get_sound_devices() * @return 0 * @ingroup media_parameters @@ -2950,14 +2984,14 @@ LINPHONE_PUBLIC LinphoneStatus linphone_core_set_capture_device(LinphoneCore *lc /** * Whenever the liblinphone is playing a ring to advertise an incoming call or ringback of an outgoing call, this function stops * the ringing. Typical use is to stop ringing when the user requests to ignore the call. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @ingroup media_parameters **/ LINPHONE_PUBLIC void linphone_core_stop_ringing(LinphoneCore *lc); /** * Sets the path to a wav file used for ringing. The file must be a wav 16bit linear. Local ring is disabled if null. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] path The path to a wav file to be used for ringing * @ingroup media_parameters **/ @@ -2965,7 +2999,7 @@ LINPHONE_PUBLIC void linphone_core_set_ring(LinphoneCore *lc, const char *path); /** * Returns the path to the wav file used for ringing. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The path to the wav file used for ringing * @ingroup media_parameters **/ @@ -2973,7 +3007,7 @@ LINPHONE_PUBLIC const char *linphone_core_get_ring(const LinphoneCore *lc); /** * Specify whether the tls server certificate must be verified when connecting to a SIP/TLS server. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] yesno A boolean value telling whether the tls server certificate must be verified * @ingroup initializing **/ @@ -2981,7 +3015,7 @@ LINPHONE_PUBLIC void linphone_core_verify_server_certificates(LinphoneCore *lc, /** * Specify whether the tls server certificate common name must be verified when connecting to a SIP/TLS server. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] yesno A boolean value telling whether the tls server certificate common name must be verified * @ingroup initializing **/ @@ -2989,7 +3023,7 @@ LINPHONE_PUBLIC void linphone_core_verify_server_cn(LinphoneCore *lc, bool_t yes /** * Gets the path to a file or folder containing the trusted root CAs (PEM format) - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The path to a file or folder containing the trusted root CAs * @ingroup initializing **/ @@ -2997,7 +3031,7 @@ LINPHONE_PUBLIC const char *linphone_core_get_root_ca(LinphoneCore *lc); /** * Sets the path to a file or folder containing trusted root CAs (PEM format) - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] path The path to a file or folder containing trusted root CAs * @ingroup initializing **/ @@ -3005,7 +3039,7 @@ LINPHONE_PUBLIC void linphone_core_set_root_ca(LinphoneCore *lc, const char *pat /** * Sets the trusted root CAs (PEM format) - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] data The trusted root CAs as a string * @ingroup initializing **/ @@ -3026,7 +3060,7 @@ LINPHONE_PUBLIC void linphone_core_set_ssl_config(LinphoneCore *lc, void *ssl_co * Sets the path to a wav file used for ringing back. * Ringback means the ring that is heard when it's ringing at the remote party. * The file must be a wav 16bit linear. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] path The path to a wav file to be used for ringing back * @ingroup media_parameters **/ @@ -3034,7 +3068,7 @@ LINPHONE_PUBLIC void linphone_core_set_ringback(LinphoneCore *lc, const char *pa /** * Returns the path to the wav file used for ringing back. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The path to the wav file used for ringing back * @ingroup media_parameters **/ @@ -3073,7 +3107,7 @@ LINPHONE_PUBLIC bool_t linphone_core_get_ring_during_incoming_early_media(const LINPHONE_PUBLIC LinphoneStatus linphone_core_preview_ring(LinphoneCore *lc, const char *ring,LinphoneCoreCbFunc func,void * userdata); /** - * Returns the MSFactory (mediastreamer2 factory) used by the LinphoneCore to control mediastreamer2 library. + * Returns the MSFactory (mediastreamer2 factory) used by the #LinphoneCore to control mediastreamer2 library. **/ LINPHONE_PUBLIC MSFactory* linphone_core_get_ms_factory(LinphoneCore* lc); @@ -3081,7 +3115,7 @@ LINPHONE_PUBLIC MSFactory* linphone_core_get_ms_factory(LinphoneCore* lc); * Plays an audio file to the local user. * This function works at any time, during calls, or when no calls are running. * It doesn't request the underlying audio system to support multiple playback streams. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] audiofile The path to an audio file in wav PCM 16 bit format * @return 0 on success, -1 on error * @ingroup misc @@ -3093,7 +3127,7 @@ LINPHONE_PUBLIC LinphoneStatus linphone_core_play_local(LinphoneCore *lc, const * This actually controls software echo cancellation. If hardware echo cancellation is available, * it will be always used and activated for calls, regardless of the value passed to this function. * When hardware echo cancellation is available, the software one is of course not activated. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] val A boolean value telling whether echo cancellation is to be enabled or disabled. * @ingroup media_parameters **/ @@ -3101,7 +3135,7 @@ LINPHONE_PUBLIC void linphone_core_enable_echo_cancellation(LinphoneCore *lc, bo /** * Returns TRUE if echo cancellation is enabled. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return A boolean value telling whether echo cancellation is enabled or disabled * @ingroup media_parameters **/ @@ -3181,7 +3215,7 @@ LINPHONE_PUBLIC void linphone_core_set_rtp_no_xmit_on_audio_mute(LinphoneCore *l /** * Get the list of call logs (past calls). - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return \bctbx_list{LinphoneCallLog} **/ LINPHONE_PUBLIC const bctbx_list_t * linphone_core_get_call_logs(LinphoneCore *lc); @@ -3189,22 +3223,22 @@ LINPHONE_PUBLIC const bctbx_list_t * linphone_core_get_call_logs(LinphoneCore *l /** * Get the list of call logs (past calls) that matches the given #LinphoneAddress. * At the contrary of linphone_core_get_call_logs, it is your responsibility to unref the logs and free this list once you are done using it. - * @param[in] lc LinphoneCore object - * @param[in] addr LinphoneAddress object + * @param[in] lc #LinphoneCore object + * @param[in] addr #LinphoneAddress object * @return \bctbx_list{LinphoneCallLog} **/ LINPHONE_PUBLIC bctbx_list_t * linphone_core_get_call_history_for_address(LinphoneCore *lc, const LinphoneAddress *addr); /** * Get the latest outgoing call log. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return {LinphoneCallLog} **/ LINPHONE_PUBLIC LinphoneCallLog * linphone_core_get_last_outgoing_call_log(LinphoneCore *lc); /** * Get the call log matching the call id, or NULL if can't be found. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] call_id Call id of the call log to find * @return {LinphoneCallLog} **/ @@ -3212,7 +3246,7 @@ LINPHONE_PUBLIC LinphoneCallLog * linphone_core_find_call_log_from_call_id(Linph /** * Erase the call log. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object **/ LINPHONE_PUBLIC void linphone_core_clear_call_logs(LinphoneCore *lc); @@ -3282,11 +3316,11 @@ LINPHONE_PUBLIC bool_t linphone_core_video_supported(LinphoneCore *lc); /** * Enables video globally. * - * This function does not have any effect during calls. It just indicates LinphoneCore to + * This function does not have any effect during calls. It just indicates #LinphoneCore to * initiate future calls with video or not. The two boolean parameters indicate in which * direction video is enabled. Setting both to false disables video entirely. * - * @param lc The LinphoneCore object + * @param lc The #LinphoneCore object * @param vcap_enabled indicates whether video capture is enabled * @param display_enabled indicates whether video display should be shown * @ingroup media_parameters @@ -3362,7 +3396,7 @@ LINPHONE_PUBLIC bool_t linphone_core_video_display_enabled(LinphoneCore *lc); * - video shall be initiated by default for outgoing calls * - video shall be accepter by default for incoming calls * - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] policy The video policy to use * @ingroup media_parameters * @deprecated Deprecated since 2017-04-19. @@ -3373,7 +3407,7 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_core_set_video_policy(Linphone /** * Get the default policy for video. * See linphone_core_set_video_policy() for more details. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The video policy being used * @ingroup media_parameters * @deprecated Deprecated since 2017-04-19. @@ -3383,29 +3417,29 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED const LinphoneVideoPolicy *linphone_core_get /** * Increment refcount. - * @param[in] policy LinphoneVideoActivationPolicy object + * @param[in] policy #LinphoneVideoActivationPolicy object * @ingroup media_parameters **/ LINPHONE_PUBLIC LinphoneVideoActivationPolicy *linphone_video_activation_policy_ref(LinphoneVideoActivationPolicy *policy); /** * Decrement refcount and possibly free the object. - * @param[in] policy LinphoneVideoActivationPolicy object + * @param[in] policy #LinphoneVideoActivationPolicy object * @ingroup media_parameters **/ LINPHONE_PUBLIC void linphone_video_activation_policy_unref(LinphoneVideoActivationPolicy *policy); /** - * Gets the user data in the LinphoneVideoActivationPolicy object - * @param[in] policy the LinphoneVideoActivationPolicy + * Gets the user data in the #LinphoneVideoActivationPolicy object + * @param[in] policy the #LinphoneVideoActivationPolicy * @return the user data * @ingroup media_parameters */ LINPHONE_PUBLIC void *linphone_video_activation_policy_get_user_data(const LinphoneVideoActivationPolicy *policy); /** - * Sets the user data in the LinphoneVideoActivationPolicy object - * @param[in] policy the LinphoneVideoActivationPolicy object + * Sets the user data in the #LinphoneVideoActivationPolicy object + * @param[in] policy the #LinphoneVideoActivationPolicy object * @param[in] data the user data * @ingroup media_parameters */ @@ -3413,7 +3447,7 @@ LINPHONE_PUBLIC void linphone_video_activation_policy_set_user_data(LinphoneVide /** * Gets the value for the automatically accept video policy - * @param[in] policy the LinphoneVideoActivationPolicy object + * @param[in] policy the #LinphoneVideoActivationPolicy object * @return whether or not to automatically accept video requests is enabled * @ingroup media_parameters */ @@ -3421,7 +3455,7 @@ LINPHONE_PUBLIC bool_t linphone_video_activation_policy_get_automatically_accept /** * Gets the value for the automatically initiate video policy - * @param[in] policy the LinphoneVideoActivationPolicy object + * @param[in] policy the #LinphoneVideoActivationPolicy object * @return whether or not to automatically initiate video calls is enabled * @ingroup media_parameters */ @@ -3429,7 +3463,7 @@ LINPHONE_PUBLIC bool_t linphone_video_activation_policy_get_automatically_initia /** * Sets the value for the automatically accept video policy - * @param[in] policy the LinphoneVideoActivationPolicy object + * @param[in] policy the #LinphoneVideoActivationPolicy object * @param[in] enable whether or not to enable automatically accept video requests * @ingroup media_parameters */ @@ -3437,7 +3471,7 @@ LINPHONE_PUBLIC void linphone_video_activation_policy_set_automatically_accept(L /** * Sets the value for the automatically initiate video policy - * @param[in] policy the LinphoneVideoActivationPolicy object + * @param[in] policy the #LinphoneVideoActivationPolicy object * @param[in] enable whether or not to enable automatically initiate video calls * @ingroup media_parameters */ @@ -3448,7 +3482,7 @@ LINPHONE_PUBLIC void linphone_video_activation_policy_set_automatically_initiate * This policy defines whether: * - video shall be initiated by default for outgoing calls * - video shall be accepted by default for incoming calls - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] policy The video policy to use * @ingroup media_parameters **/ @@ -3457,7 +3491,7 @@ LINPHONE_PUBLIC void linphone_core_set_video_activation_policy(LinphoneCore *lc, /** * Get the default policy for video. * See linphone_core_set_video_activation_policy() for more details. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The video policy being used * @ingroup media_parameters **/ @@ -3474,8 +3508,8 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED const MSVideoSizeDef *linphone_core_get_supp /** * Set the preferred video definition for the stream that is captured and sent to the remote party. * All standard video definitions are accepted on the receive path. - * @param[in] lc LinphoneCore object - * @param[in] vdef LinphoneVideoDefinition object + * @param[in] lc #LinphoneCore object + * @param[in] vdef #LinphoneVideoDefinition object * @ingroup media_parameters */ LINPHONE_PUBLIC void linphone_core_set_preferred_video_definition(LinphoneCore *lc, LinphoneVideoDefinition *vdef); @@ -3496,14 +3530,14 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_core_set_preferred_video_size( * This method is for advanced usage where a video capture must be set independently of the definition of the stream actually sent through the call. * This allows for example to have the preview window in High Definition even if due to bandwidth constraint the sent video definition is small. * Using this feature increases the CPU consumption, since a rescaling will be done internally. - * @param[in] lc LinphoneCore object - * @param[in] vdef LinphoneVideoDefinition object + * @param[in] lc #LinphoneCore object + * @param[in] vdef #LinphoneVideoDefinition object * @ingroup media_parameters */ LINPHONE_PUBLIC void linphone_core_set_preview_video_definition(LinphoneCore *lc, LinphoneVideoDefinition *vdef); /** - * @biref Sets the video size for the captured (preview) video. + * @brief Sets the video size for the captured (preview) video. * * This method is for advanced usage where a video capture must be set independently of the size of the stream actually sent through the call. * This allows for example to have the preview window with HD resolution even if due to bandwidth constraint the sent video size is small. @@ -3527,8 +3561,8 @@ LINPHONE_PUBLIC void linphone_core_set_preview_video_size_by_name(LinphoneCore * /** * Get the definition of the captured video. - * @param[in] lc LinphoneCore object - * @return The captured LinphoneVideoDefinition if it was previously set by linphone_core_set_preview_video_definition(), otherwise a 0x0 LinphoneVideoDefinition. + * @param[in] lc #LinphoneCore object + * @return The captured #LinphoneVideoDefinition if it was previously set by linphone_core_set_preview_video_definition(), otherwise a 0x0 LinphoneVideoDefinition. * @see linphone_core_set_preview_video_definition() * @ingroup media_parameters */ @@ -3548,8 +3582,8 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED MSVideoSize linphone_core_get_preview_video_ /** * Get the effective video definition provided by the camera for the captured video. * When preview is disabled or not yet started this function returns a 0x0 video definition. - * @param[in] lc LinphoneCore object - * @return The captured LinphoneVideoDefinition + * @param[in] lc #LinphoneCore object + * @return The captured #LinphoneVideoDefinition * @ingroup media_parameters * @see linphone_core_set_preview_video_definition() */ @@ -3570,8 +3604,8 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED MSVideoSize linphone_core_get_current_previe /** * Get the preferred video definition for the stream that is captured and sent to the remote party. - * @param[in] lc LinphoneCore object - * @return The preferred LinphoneVideoDefinition + * @param[in] lc #LinphoneCore object + * @return The preferred #LinphoneVideoDefinition * @ingroup media_parameters */ LINPHONE_PUBLIC const LinphoneVideoDefinition * linphone_core_get_preferred_video_definition(const LinphoneCore *lc); @@ -3608,7 +3642,7 @@ LINPHONE_PUBLIC void linphone_core_set_preferred_video_size_by_name(LinphoneCore * Based on the available bandwidth constraints and network conditions, the video encoder * remains free to lower the framerate. There is no warranty that the preferred frame rate be the actual framerate. * used during a call. Default value is 0, which means "use encoder's default fps value". - * @param lc the LinphoneCore + * @param lc the #LinphoneCore * @param fps the target frame rate in number of frames per seconds. * @ingroup media_parameters **/ @@ -3631,7 +3665,7 @@ LINPHONE_PUBLIC void linphone_core_preview_ogl_render(const LinphoneCore *lc); /** * Controls video preview enablement. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] val A boolean value telling whether the video preview is to be shown * Video preview refers to the action of displaying the local webcam image * to the user while not in call. @@ -3641,7 +3675,7 @@ LINPHONE_PUBLIC void linphone_core_enable_video_preview(LinphoneCore *lc, bool_t /** * Tells whether video preview is enabled. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return A boolean value telling whether video preview is enabled * @ingroup media_parameters **/ @@ -3686,7 +3720,7 @@ LINPHONE_PUBLIC LinphoneStatus linphone_core_take_preview_snapshot(LinphoneCore /** * Enables or disable self view during calls. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] val A boolean value telling whether to enable self view * Self-view refers to having local webcam image inserted in corner * of the video window during calls. @@ -3697,7 +3731,7 @@ LINPHONE_PUBLIC void linphone_core_enable_self_view(LinphoneCore *lc, bool_t val /** * Tells whether video self view during call is enabled or not. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return A boolean value telling whether self view is enabled * @see linphone_core_enable_self_view() for details. * @ingroup media_parameters @@ -3716,7 +3750,7 @@ LINPHONE_PUBLIC void linphone_core_reload_video_devices(LinphoneCore *lc); /** * Gets the list of the available video capture devices. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return An unmodifiable array of strings contanining the names of the available video capture devices that is NULL terminated * @ingroup media_parameters * @deprecated use linphone_core_get_video_devices_list instead @@ -3726,7 +3760,7 @@ LINPHONE_PUBLIC const char** linphone_core_get_video_devices(const LinphoneCore /** * Gets the list of the available video capture devices. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return \bctbx_list{char *} An unmodifiable array of strings contanining the names of the available video capture devices that is NULL terminated * @ingroup media_parameters **/ @@ -3734,7 +3768,7 @@ LINPHONE_PUBLIC bctbx_list_t * linphone_core_get_video_devices_list(const Linpho /** * Sets the active video device. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param id The name of the video device to use as returned by linphone_core_get_video_devices() * @ingroup media_parameters **/ @@ -3742,7 +3776,7 @@ LINPHONE_PUBLIC LinphoneStatus linphone_core_set_video_device(LinphoneCore *lc, /** * Returns the name of the currently active video device. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The name of the currently active video device * @ingroup media_parameters **/ @@ -3782,7 +3816,7 @@ LINPHONE_PUBLIC float linphone_core_get_static_picture_fps(LinphoneCore *lc); /** * Get the native window handle of the video window. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The native window handle of the video window * @ingroup media_parameters **/ @@ -3809,7 +3843,7 @@ LINPHONE_PUBLIC void linphone_core_set_native_video_window_id(LinphoneCore *lc, /** * Get the native window handle of the video preview window. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The native window handle of the video preview window * @ingroup media_parameters **/ @@ -3819,7 +3853,7 @@ LINPHONE_PUBLIC void * linphone_core_get_native_preview_window_id(const Linphone * Set the native window id where the preview video (local camera) is to be displayed. * This has to be used in conjonction with linphone_core_use_preview_window(). * MacOS, Linux, Windows: if not set or zero the core will create its own window, unless the special id -1 is given. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] id The native window id where the preview video is to be displayed * @ingroup media_parameters **/ @@ -3836,7 +3870,7 @@ LINPHONE_PUBLIC void linphone_core_use_preview_window(LinphoneCore *lc, bool_t y /** * Gets the current device orientation. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The current device orientation * @ingroup media_parameters * @see linphone_core_set_device_rotation() @@ -3849,7 +3883,7 @@ LINPHONE_PUBLIC int linphone_core_get_device_rotation(LinphoneCore *lc); * oriented images. The exact meaning of the value in rotation if left to each device * specific implementations. * IOS supported values are 0 for UIInterfaceOrientationPortrait and 270 for UIInterfaceOrientationLandscapeRight. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] rotation The orientation to use * @ingroup media_parameters **/ @@ -3877,7 +3911,7 @@ void linphone_core_show_video(LinphoneCore *lc, bool_t show); /** * Ask the core to stream audio from and to files, instead of using the soundcard. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] yesno A boolean value asking to stream audio from and to files or not. * @ingroup media_parameters **/ @@ -3886,7 +3920,7 @@ LINPHONE_PUBLIC void linphone_core_set_use_files(LinphoneCore *lc, bool_t yesno) /** * Gets whether linphone is currently streaming audio from and to files, rather * than using the soundcard. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return A boolean value representing whether linphone is streaming audio from and to files or not. * @ingroup media_parameters **/ @@ -3897,7 +3931,7 @@ LINPHONE_PUBLIC bool_t linphone_core_get_use_files(LinphoneCore *lc); * or when files are used instead of soundcards (see linphone_core_set_use_files()). * * The file is a 16 bit linear wav file. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The path to the file that is played when putting somebody on hold. * @ingroup media_parameters */ @@ -3908,7 +3942,7 @@ LINPHONE_PUBLIC const char * linphone_core_get_play_file(const LinphoneCore *lc) * or when files are used instead of soundcards (see linphone_core_set_use_files()). * * The file must be a 16 bit linear wav file. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] file The path to the file to be played when putting somebody on hold. * @ingroup media_parameters **/ @@ -3920,7 +3954,7 @@ LINPHONE_PUBLIC void linphone_core_set_play_file(LinphoneCore *lc, const char *f * * This feature is different from call recording (linphone_call_params_set_record_file()) * The file is a 16 bit linear wav file. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The path to the file where incoming stream is recorded. * @ingroup media_parameters **/ @@ -3932,7 +3966,7 @@ LINPHONE_PUBLIC const char * linphone_core_get_record_file(const LinphoneCore *l * * This feature is different from call recording (linphone_call_params_set_record_file()) * The file will be a 16 bit linear wav file. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] file The path to the file where incoming stream is to be recorded. * @ingroup media_parameters **/ @@ -3940,7 +3974,7 @@ LINPHONE_PUBLIC void linphone_core_set_record_file(LinphoneCore *lc, const char /** * Plays a dtmf sound to the local user. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] dtmf DTMF to play ['0'..'16'] | '#' | '#' * @param[in] duration_ms Duration in ms, -1 means play until next further call to #linphone_core_stop_dtmf() * @ingroup media_parameters @@ -3949,7 +3983,7 @@ LINPHONE_PUBLIC void linphone_core_play_dtmf(LinphoneCore *lc, char dtmf, int du /** * Stops playing a dtmf started by linphone_core_play_dtmf(). - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @ingroup media_parameters **/ LINPHONE_PUBLIC void linphone_core_stop_dtmf(LinphoneCore *lc); @@ -3966,7 +4000,7 @@ LINPHONE_PUBLIC int linphone_core_get_mtu(const LinphoneCore *lc); * Sets the maximum transmission unit size in bytes. * This information is useful for sending RTP packets. * Default value is 1500. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] mtu The MTU in bytes * @ingroup media_parameters **/ @@ -4004,7 +4038,7 @@ LINPHONE_PUBLIC void linphone_core_set_media_network_reachable(LinphoneCore* lc, /** * Enables signaling keep alive, small udp packet sent periodically to keep udp NAT association. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] enable A boolean value telling whether signaling keep alive is to be enabled * @ingroup network_parameters */ @@ -4012,7 +4046,7 @@ LINPHONE_PUBLIC void linphone_core_enable_keep_alive(LinphoneCore* lc, bool_t en /** * Is signaling keep alive enabled. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return A boolean value telling whether signaling keep alive is enabled * @ingroup network_parameters */ @@ -4020,20 +4054,32 @@ LINPHONE_PUBLIC bool_t linphone_core_keep_alive_enabled(LinphoneCore* lc); /** * Retrieves the user pointer that was given to linphone_core_new() - * @param[in] lc LinphoneCore object - * @return The user data associated with the LinphoneCore object + * @param[in] lc #LinphoneCore object + * @return The user data associated with the #LinphoneCore object * @ingroup initializing **/ LINPHONE_PUBLIC void *linphone_core_get_user_data(const LinphoneCore *lc); /** * Associate a user pointer to the linphone core. - * @param[in] lc LinphoneCore object - * @param[in] userdata The user data to associate with the LinphoneCore object + * @param[in] lc #LinphoneCore object + * @param[in] userdata The user data to associate with the #LinphoneCore object * @ingroup initializing **/ LINPHONE_PUBLIC void linphone_core_set_user_data(LinphoneCore *lc, void *userdata); +/** + * This method is called by the application to notify the linphone core library when it enters background mode. + * @ingroup misc + */ +LINPHONE_PUBLIC void linphone_core_enter_background(LinphoneCore *lc); + +/** + * This method is called by the application to notify the linphone core library when it enters foreground mode. + * @ingroup misc + */ +LINPHONE_PUBLIC void linphone_core_enter_foreground(LinphoneCore *lc); + /** * Returns the LpConfig object used to manage the storage (config) file. * @param[in] lc #LinphoneCore object @@ -4072,8 +4118,8 @@ LINPHONE_PUBLIC void linphone_core_set_waiting_callback(LinphoneCore *lc, Linpho LINPHONE_PUBLIC const bctbx_list_t * linphone_core_get_sip_setups(LinphoneCore *lc); /** - * Destroys a LinphoneCore - * @param[in] lc LinphoneCore object + * Destroys a #LinphoneCore + * @param[in] lc #LinphoneCore object * @ingroup initializing * @deprecated Use linphone_core_unref() instead. * @donotwrap @@ -4098,7 +4144,7 @@ void linphone_core_set_rtp_transport_factories(LinphoneCore* lc, LinphoneRtpTran /** * Retrieve RTP statistics regarding current call. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[out] local RTP statistics computed locally. * @param[out] remote RTP statistics computed by far end (obtained via RTCP feedback). * @return 0 or -1 if no call is running. @@ -4108,7 +4154,7 @@ int linphone_core_get_current_call_stats(LinphoneCore *lc, rtp_stats_t *local, r /** * Get the number of Call - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The current number of calls * @ingroup call_control **/ @@ -4117,9 +4163,9 @@ LINPHONE_PUBLIC int linphone_core_get_calls_nb(const LinphoneCore *lc); /** * Gets the current list of calls. * Note that this list is read-only and might be changed by the core after a function call to linphone_core_iterate(). - * Similarly the LinphoneCall objects inside it might be destroyed without prior notice. - * To hold references to LinphoneCall object into your program, you must use linphone_call_ref(). - * @param[in] lc The LinphoneCore object + * Similarly the #LinphoneCall objects inside it might be destroyed without prior notice. + * To hold references to #LinphoneCall object into your program, you must use linphone_call_ref(). + * @param[in] lc The #LinphoneCore object * @return \bctbx_list{LinphoneCall} * @ingroup call_control **/ @@ -4186,7 +4232,7 @@ LINPHONE_PUBLIC void linphone_core_reload_ms_plugins(LinphoneCore *lc, const cha * @ingroup call_control * @param lc * @param uri which should match call remote uri - * @return LinphoneCall or NULL is no match is found + * @return #LinphoneCall or NULL is no match is found */ LINPHONE_PUBLIC LinphoneCall* linphone_core_find_call_from_uri(const LinphoneCore *lc, const char *uri); @@ -4362,7 +4408,7 @@ LINPHONE_PUBLIC void linphone_core_set_max_calls(LinphoneCore *lc, int max); * In order to prevent this situation, an application can use linphone_core_sound_resources_locked() to know whether * it is possible at a given time to start a new outgoing call. * When the function returns TRUE, an application should not allow the user to start an outgoing call. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return A boolean value telling whether a call will need the sound resources in near future * @ingroup call_control **/ @@ -4371,8 +4417,8 @@ LINPHONE_PUBLIC bool_t linphone_core_sound_resources_locked(LinphoneCore *lc); /** * Check if a media encryption type is supported * @param lc core - * @param menc LinphoneMediaEncryption - * @return whether a media encryption scheme is supported by the LinphoneCore engine + * @param menc #LinphoneMediaEncryption + * @return whether a media encryption scheme is supported by the #LinphoneCore engine * @ingroup initializing **/ LINPHONE_PUBLIC bool_t linphone_core_media_encryption_supported(const LinphoneCore *lc, LinphoneMediaEncryption menc); @@ -4425,14 +4471,14 @@ LINPHONE_PUBLIC bool_t linphone_core_tunnel_available(void); * get tunnel instance if available * @ingroup tunnel * @param lc core object - * @returns LinphoneTunnel or NULL if not available + * @returns #LinphoneTunnel or NULL if not available */ LINPHONE_PUBLIC LinphoneTunnel *linphone_core_get_tunnel(const LinphoneCore *lc); /** * Set the DSCP field for SIP signaling channel. * The DSCP defines the quality of service in IP packets. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] dscp The DSCP value to set * @ingroup network_parameters **/ @@ -4441,7 +4487,7 @@ LINPHONE_PUBLIC void linphone_core_set_sip_dscp(LinphoneCore *lc, int dscp); /** * Get the DSCP field for SIP signaling channel. * The DSCP defines the quality of service in IP packets. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The current DSCP value * @ingroup network_parameters **/ @@ -4450,7 +4496,7 @@ LINPHONE_PUBLIC int linphone_core_get_sip_dscp(const LinphoneCore *lc); /** * Set the DSCP field for outgoing audio streams. * The DSCP defines the quality of service in IP packets. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] dscp The DSCP value to set * @ingroup network_parameters **/ @@ -4459,7 +4505,7 @@ LINPHONE_PUBLIC void linphone_core_set_audio_dscp(LinphoneCore *lc, int dscp); /** * Get the DSCP field for outgoing audio streams. * The DSCP defines the quality of service in IP packets. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The current DSCP value * @ingroup network_parameters **/ @@ -4468,7 +4514,7 @@ LINPHONE_PUBLIC int linphone_core_get_audio_dscp(const LinphoneCore *lc); /** * Set the DSCP field for outgoing video streams. * The DSCP defines the quality of service in IP packets. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] dscp The DSCP value to set * @ingroup network_parameters **/ @@ -4477,7 +4523,7 @@ LINPHONE_PUBLIC void linphone_core_set_video_dscp(LinphoneCore *lc, int dscp); /** * Get the DSCP field for outgoing video streams. * The DSCP defines the quality of service in IP packets. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The current DSCP value * @ingroup network_parameters **/ @@ -4498,7 +4544,7 @@ LINPHONE_PUBLIC void linphone_core_set_video_display_filter(LinphoneCore *lc, co /** * Get the name of the mediastreamer2 filter used for echo cancelling. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The name of the mediastreamer2 filter used for echo cancelling * @ingroup media_parameters */ @@ -4507,7 +4553,7 @@ LINPHONE_PUBLIC const char * linphone_core_get_echo_canceller_filter_name(const /** * Set the name of the mediastreamer2 filter to be used for echo cancelling. * This is for advanced users of the library. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] filtername The name of the mediastreamer2 filter to be used for echo cancelling * @ingroup media_parameters */ @@ -4522,7 +4568,7 @@ typedef void (*ContactSearchCallback)( LinphoneContactSearch* id, bctbx_list_t* * Set URI where to download xml configuration file at startup. * This can also be set from configuration file or factory config file, from [misc] section, item "config-uri". * Calling this function does not load the configuration. It will write the value into configuration so that configuration - * from remote URI will take place at next LinphoneCore start. + * from remote URI will take place at next #LinphoneCore start. * @param lc the linphone core * @param uri the http or https uri to use in order to download the configuration. Passing NULL will disable remote provisioning. * @return -1 if uri could not be parsed, 0 otherwise. Note that this does not check validity of URI endpoint nor scheme and download may still fail. @@ -4637,7 +4683,7 @@ LINPHONE_PUBLIC bool_t linphone_core_file_format_supported(LinphoneCore *lc, con /** * This function controls signaling features supported by the core. * They are typically included in a SIP Supported header. - * @param[in] core LinphoneCore object + * @param[in] core #LinphoneCore object * @param[in] tag The feature tag name * @ingroup initializing **/ @@ -4645,7 +4691,7 @@ LINPHONE_PUBLIC void linphone_core_add_supported_tag(LinphoneCore *core, const c /** * Remove a supported tag. - * @param[in] core LinphoneCore object + * @param[in] core #LinphoneCore object * @param[in] tag The tag to remove * @ingroup initializing * @see linphone_core_add_supported_tag() @@ -4654,10 +4700,10 @@ LINPHONE_PUBLIC void linphone_core_remove_supported_tag(LinphoneCore *core, cons /** * Enable RTCP feedback (also known as RTP/AVPF profile). - * Setting LinphoneAVPFDefault is equivalent to LinphoneAVPFDisabled. - * This setting can be overriden per LinphoneProxyConfig with linphone_proxy_config_set_avpf_mode(). + * Setting #LinphoneAVPFDefault is equivalent to LinphoneAVPFDisabled. + * This setting can be overriden per #LinphoneProxyConfig with linphone_proxy_config_set_avpf_mode(). * The value set here is used for calls placed or received out of any proxy configured, or if the proxy config is configured with LinphoneAVPFDefault. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] mode The AVPF mode to use. * @ingroup media_parameters **/ @@ -4665,7 +4711,7 @@ LINPHONE_PUBLIC void linphone_core_set_avpf_mode(LinphoneCore *lc, LinphoneAVPFM /** * Return AVPF enablement. See linphone_core_set_avpf_mode() . - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The current AVPF mode * @ingroup media_parameters **/ @@ -4674,7 +4720,7 @@ LINPHONE_PUBLIC LinphoneAVPFMode linphone_core_get_avpf_mode(const LinphoneCore /** * Set the avpf report interval in seconds. * This value can be overriden by the proxy config using linphone_proxy_config_set_avpf_rr_interval(). - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] interval The report interval in seconds * @ingroup media_parameters **/ @@ -4682,7 +4728,7 @@ LINPHONE_PUBLIC void linphone_core_set_avpf_rr_interval(LinphoneCore *lc, int in /** * Return the avpf report interval in seconds. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The current AVPF report interval in seconds * @ingroup media_parameters **/ @@ -4819,7 +4865,7 @@ LINPHONE_PUBLIC const OrtpNetworkSimulatorParams *linphone_core_get_network_simu /** * Set the video preset to be used for video calls. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] preset The name of the video preset to be used (can be NULL to use the default video preset). * @ingroup media_parameters */ @@ -4827,7 +4873,7 @@ LINPHONE_PUBLIC void linphone_core_set_video_preset(LinphoneCore *lc, const char /** * Get the video preset used for video calls. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return The name of the video preset used for video calls (can be NULL if the default video preset is used). * @ingroup media_parameters */ @@ -4835,7 +4881,7 @@ LINPHONE_PUBLIC const char * linphone_core_get_video_preset(const LinphoneCore * /** * Gets if realtime text is enabled or not - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return true if realtime text is enabled, false otherwise * @ingroup media_parameters */ @@ -4845,7 +4891,7 @@ LINPHONE_PUBLIC void linphone_core_enable_realtime_text(LinphoneCore *lc, bool_t /** * Set http proxy address to be used for signaling during next channel connection. Use #linphone_core_set_network_reachable FASLE/TRUE to force channel restart. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] host Hostname of IP adress of the http proxy (can be NULL to disable). * @ingroup network_parameters */ @@ -4853,7 +4899,7 @@ LINPHONE_PUBLIC void linphone_core_set_http_proxy_host(LinphoneCore *lc, const c /** * Set http proxy port to be used for signaling. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] port of the http proxy. * @ingroup network_parameters */ @@ -4861,7 +4907,7 @@ LINPHONE_PUBLIC void linphone_core_set_http_proxy_port(LinphoneCore *lc, int por /** * Get http proxy address to be used for signaling. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return hostname of IP adress of the http proxy (can be NULL to disable). * @ingroup network_parameters */ @@ -4869,7 +4915,7 @@ LINPHONE_PUBLIC const char *linphone_core_get_http_proxy_host(const LinphoneCore /** * Get http proxy port to be used for signaling. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return port of the http proxy. * @ingroup network_parameters */ @@ -4879,8 +4925,8 @@ LINPHONE_PUBLIC LinphoneRingtonePlayer *linphone_core_get_ringtoneplayer(Linphon /** * Sets a TLS certificate used for TLS authentication - * The certificate won't be stored, you have to set it after each LinphoneCore startup - * @param lc LinphoneCore object + * The certificate won't be stored, you have to set it after each #LinphoneCore startup + * @param lc #LinphoneCore object * @param tls_cert the TLS certificate * @ingroup network_parameters */ @@ -4888,8 +4934,8 @@ LINPHONE_PUBLIC void linphone_core_set_tls_cert(LinphoneCore *lc, const char *tl /** * Sets a TLS key used for TLS authentication - * The key won't be stored, you have to set it after each LinphoneCore startup - * @param lc LinphoneCore object + * The key won't be stored, you have to set it after each #LinphoneCore startup + * @param lc #LinphoneCore object * @param tls_key the TLS key * @ingroup network_parameters */ @@ -4898,7 +4944,7 @@ LINPHONE_PUBLIC void linphone_core_set_tls_key(LinphoneCore *lc, const char *tls /** * Sets a TLS certificate path used for TLS authentication * The path will be stored in the rc file and automatically restored on startup - * @param lc LinphoneCore object + * @param lc #LinphoneCore object * @param tls_cert_path path to the TLS certificate * @ingroup network_parameters */ @@ -4907,7 +4953,7 @@ LINPHONE_PUBLIC void linphone_core_set_tls_cert_path(LinphoneCore *lc, const cha /** * Sets a TLS key path used for TLS authentication * The path will be stored in the rc file and automatically restored on startup - * @param lc LinphoneCore object + * @param lc #LinphoneCore object * @param tls_key_path path to the TLS key * @ingroup network_parameters */ @@ -4915,7 +4961,7 @@ LINPHONE_PUBLIC void linphone_core_set_tls_key_path(LinphoneCore *lc, const char /** * Gets the TLS certificate - * @param lc LinphoneCore object + * @param lc #LinphoneCore object * @return the TLS certificate or NULL if not set yet * @ingroup network_parameters */ @@ -4923,7 +4969,7 @@ LINPHONE_PUBLIC const char *linphone_core_get_tls_cert(const LinphoneCore *lc); /** * Gets the TLS key - * @param lc LinphoneCore object + * @param lc #LinphoneCore object * @return the TLS key or NULL if not set yet * @ingroup network_parameters */ @@ -4931,7 +4977,7 @@ LINPHONE_PUBLIC const char *linphone_core_get_tls_key(const LinphoneCore *lc); /** * Gets the path to the TLS certificate file - * @param lc LinphoneCore object + * @param lc #LinphoneCore object * @return the TLS certificate path or NULL if not set yet * @ingroup network_parameters */ @@ -4939,7 +4985,7 @@ LINPHONE_PUBLIC const char *linphone_core_get_tls_cert_path(const LinphoneCore * /** * Gets the path to the TLS key file - * @param lc LinphoneCore object + * @param lc #LinphoneCore object * @return the TLS key path or NULL if not set yet * @ingroup network_parameters */ @@ -4947,8 +4993,8 @@ LINPHONE_PUBLIC const char *linphone_core_get_tls_key_path(const LinphoneCore *l /** * Sets an IM Encryption Engine in the core - * @param lc LinphoneCore object - * @param imee LinphoneImEncryptionEngine object + * @param lc #LinphoneCore object + * @param imee #LinphoneImEncryptionEngine object * @ingroup chatroom * @donotwrap */ @@ -4956,7 +5002,7 @@ LINPHONE_PUBLIC void linphone_core_set_im_encryption_engine(LinphoneCore *lc, Li /** * Gets the IM Encryption Engine in the core if possible - * @param lc LinphoneCore object + * @param lc #LinphoneCore object * @return the IM Encryption Engine in the core or NULL * @ingroup chatroom * @donotwrap @@ -4965,7 +5011,7 @@ LINPHONE_PUBLIC LinphoneImEncryptionEngine * linphone_core_get_im_encryption_eng /** * Tells whether a content type is supported. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] content_type The content type to check * @return A boolean value telling whether the specified content type is supported or not. */ @@ -4974,14 +5020,14 @@ LINPHONE_PUBLIC bool_t linphone_core_is_content_type_supported(const LinphoneCor /** * Add support for the specified content type. * It is the application responsibility to handle it correctly afterwards. - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @param[in] content_type The content type to add support for */ LINPHONE_PUBLIC void linphone_core_add_content_type_support(LinphoneCore *lc, const char *content_type); /** * Get the linphone specs value telling what functionalities the linphone client supports. - * @param[in] core LinphoneCore object + * @param[in] core #LinphoneCore object * @return The linphone specs telling what functionalities the linphone client supports * @ingroup initializing */ @@ -4989,12 +5035,21 @@ const char *linphone_core_get_linphone_specs (const LinphoneCore *core); /** * Set the linphone specs value telling what functionalities the linphone client supports. - * @param[in] core LinphoneCore object + * @param[in] core #LinphoneCore object * @param[in] specs The linphone specs to set * @ingroup initializing */ void linphone_core_set_linphone_specs (LinphoneCore *core, const char *specs); +/** + * Remove support for the specified content type. + * It is the application responsibility to handle it correctly afterwards. + * @param[in] lc LinphoneCore object + * @param[in] content_type The content type to remove support for + */ +LINPHONE_PUBLIC void linphone_core_remove_content_type_support(LinphoneCore *lc, const char *content_type); + + /** * @addtogroup chatroom * @{ @@ -5018,17 +5073,18 @@ LINPHONE_DEPRECATED LINPHONE_PUBLIC const char *linphone_core_get_chat_database_ /** * Create a client-side group chat room. When calling this function the chat room is only created - * at the client-side and is empty. Pou need to call linphone_chat_room_add_participants() to + * at the client-side and is empty. You need to call linphone_chat_room_add_participants() to * create at the server side and add participants to it. * @param[in] lc A #LinphoneCore object * @param[in] subject The subject of the group chat room + * @param[in] fallback Boolean value telling whether we should plan on being able to fallback to a basic chat room if the client-side group chat room creation fails * @return The newly created client-side group chat room. */ -LINPHONE_PUBLIC LinphoneChatRoom * linphone_core_create_client_group_chat_room(LinphoneCore *lc, const char *subject); +LINPHONE_PUBLIC LinphoneChatRoom * linphone_core_create_client_group_chat_room(LinphoneCore *lc, const char *subject, bool_t fallback); /** * Get a basic chat room whose peer is the supplied address. If it does not exist yet, it will be created. - * No reference is transfered to the application. The LinphoneCore keeps a reference on the chat room. + * No reference is transfered to the application. The #LinphoneCore keeps a reference on the chat room. * @param lc the linphone core * @param addr a linphone address. * @return #LinphoneChatRoom where messaging can take place. @@ -5037,7 +5093,7 @@ LINPHONE_PUBLIC LinphoneChatRoom *linphone_core_get_chat_room(LinphoneCore *lc, /** * Get a basic chat room for messaging from a sip uri like sip:joe@sip.linphone.org. If it does not exist yet, it will be created. - * No reference is transfered to the application. The LinphoneCore keeps a reference on the chat room. + * No reference is transfered to the application. The #LinphoneCore keeps a reference on the chat room. * @param lc A #LinphoneCore object * @param to The destination address for messages. * @return #LinphoneChatRoom where messaging can take place. @@ -5046,7 +5102,7 @@ LINPHONE_PUBLIC LinphoneChatRoom *linphone_core_get_chat_room_from_uri(LinphoneC /** * Find a chat room. - * No reference is transfered to the application. The LinphoneCore keeps a reference on the chat room. + * No reference is transfered to the application. The #LinphoneCore keeps a reference on the chat room. * @param lc the linphone core * @param peer_addr a linphone address. * @param local_addr a linphone address. @@ -5060,7 +5116,7 @@ LINPHONE_PUBLIC LinphoneChatRoom *linphone_core_find_chat_room ( /** * Find a one to one chat room. - * No reference is transfered to the application. The LinphoneCore keeps a reference on the chat room. + * No reference is transfered to the application. The #LinphoneCore keeps a reference on the chat room. * @param lc the linphone core * @param local_addr a linphone address. * @param participant_addr a linphone address. @@ -5100,9 +5156,9 @@ LINPHONE_PUBLIC void linphone_core_enable_chat(LinphoneCore *lc); LINPHONE_PUBLIC bool_t linphone_core_chat_enabled(const LinphoneCore *lc); /** - * Get the LinphoneImNotifPolicy object controlling the instant messaging notifications. - * @param[in] lc LinphoneCore object - * @return A LinphoneImNotifPolicy object. + * Get the #LinphoneImNotifPolicy object controlling the instant messaging notifications. + * @param[in] lc #LinphoneCore object + * @return A #LinphoneImNotifPolicy object. */ LINPHONE_PUBLIC LinphoneImNotifPolicy * linphone_core_get_im_notif_policy(const LinphoneCore *lc); @@ -5112,8 +5168,8 @@ LINPHONE_PUBLIC LinphoneImNotifPolicy * linphone_core_get_im_notif_policy(const /** * Create a content with default values from Linphone core. - * @param[in] lc LinphoneCore object - * @return LinphoneContent object with default values set + * @param[in] lc #LinphoneCore object + * @return #LinphoneContent object with default values set * @ingroup misc */ LINPHONE_PUBLIC LinphoneContent * linphone_core_create_content(LinphoneCore *lc); @@ -5132,7 +5188,7 @@ LINPHONE_PUBLIC LinphoneContent * linphone_core_create_content(LinphoneCore *lc) * @param event the event name * @param expires the whished duration of the subscription * @param body an optional body, may be NULL. - * @return a LinphoneEvent holding the context of the created subcription. + * @return a #LinphoneEvent holding the context of the created subcription. **/ LINPHONE_PUBLIC LinphoneEvent *linphone_core_subscribe(LinphoneCore *lc, const LinphoneAddress *resource, const char *event, int expires, const LinphoneContent *body); @@ -5144,7 +5200,7 @@ LINPHONE_PUBLIC LinphoneEvent *linphone_core_subscribe(LinphoneCore *lc, const L * @param resource the destination resource * @param event the event name * @param expires the whished duration of the subscription - * @return a LinphoneEvent holding the context of the created subcription. + * @return a #LinphoneEvent holding the context of the created subcription. **/ LINPHONE_PUBLIC LinphoneEvent *linphone_core_create_subscribe(LinphoneCore *lc, const LinphoneAddress *resource, const char *event, int expires); @@ -5155,20 +5211,20 @@ LINPHONE_PUBLIC LinphoneEvent *linphone_core_create_subscribe(LinphoneCore *lc, * @param lc the #LinphoneCore * @param resource the destination resource * @param event the event name - * @return a LinphoneEvent holding the context of the notification. + * @return a #LinphoneEvent holding the context of the notification. **/ LINPHONE_PUBLIC LinphoneEvent *linphone_core_create_notify(LinphoneCore *lc, const LinphoneAddress *resource, const char *event); /** * Publish an event state. - * This first create a LinphoneEvent with linphone_core_create_publish() and calls linphone_event_send_publish() to actually send it. + * This first create a #LinphoneEvent with linphone_core_create_publish() and calls linphone_event_send_publish() to actually send it. * After expiry, the publication is refreshed unless it is terminated before. * @param lc the #LinphoneCore * @param resource the resource uri for the event * @param event the event name * @param expires the lifetime of event being published, -1 if no associated duration, in which case it will not be refreshed. * @param body the actual published data - * @return the LinphoneEvent holding the context of the publish. + * @return the #LinphoneEvent holding the context of the publish. **/ LINPHONE_PUBLIC LinphoneEvent *linphone_core_publish(LinphoneCore *lc, const LinphoneAddress *resource, const char *event, int expires, const LinphoneContent *body); @@ -5180,19 +5236,19 @@ LINPHONE_PUBLIC LinphoneEvent *linphone_core_publish(LinphoneCore *lc, const Lin * @param resource the resource uri for the event * @param event the event name * @param expires the lifetime of event being published, -1 if no associated duration, in which case it will not be refreshed. - * @return the LinphoneEvent holding the context of the publish. + * @return the #LinphoneEvent holding the context of the publish. **/ LINPHONE_PUBLIC LinphoneEvent *linphone_core_create_publish(LinphoneCore *lc, const LinphoneAddress *resource, const char *event, int expires); /** * Create a publish context for a one-shot publish. * After being created, the publish must be sent using linphone_event_send_publish(). - * The LinphoneEvent is automatically terminated when the publish transaction is finished, either with success or failure. + * The #LinphoneEvent is automatically terminated when the publish transaction is finished, either with success or failure. * The application must not call linphone_event_terminate() for such one-shot publish. * @param lc the #LinphoneCore * @param resource the resource uri for the event * @param event the event name - * @return the LinphoneEvent holding the context of the publish. + * @return the #LinphoneEvent holding the context of the publish. **/ LINPHONE_PUBLIC LinphoneEvent *linphone_core_create_one_shot_publish(LinphoneCore *lc, const LinphoneAddress *resource, const char *event); @@ -5214,9 +5270,9 @@ LINPHONE_PUBLIC LinphoneEvent *linphone_core_create_one_shot_publish(LinphoneCor LINPHONE_PUBLIC LinphoneFriend * linphone_core_create_friend(LinphoneCore *lc); /** - * Create a LinphoneFriend from the given address. + * Create a #LinphoneFriend from the given address. * @param[in] lc #LinphoneCore object - * @param[in] address A string containing the address to create the LinphoneFriend from + * @param[in] address A string containing the address to create the #LinphoneFriend from * @return The created #LinphoneFriend object */ LINPHONE_PUBLIC LinphoneFriend * linphone_core_create_friend_with_address(LinphoneCore *lc, const char *address); @@ -5257,15 +5313,15 @@ LINPHONE_PUBLIC LinphonePresenceModel * linphone_core_get_presence_model(const L /** * Get my consolidated presence - * @param[in] lc LinphoneCore object + * @param[in] lc #LinphoneCore object * @return My consolidated presence */ LINPHONE_PUBLIC LinphoneConsolidatedPresence linphone_core_get_consolidated_presence(const LinphoneCore *lc); /** * Set my consolidated presence - * @param[in] lc LinphoneCore object - * @param[in] presence LinphoneConsolidatedPresence value + * @param[in] lc #LinphoneCore object + * @param[in] presence #LinphoneConsolidatedPresence value */ LINPHONE_PUBLIC void linphone_core_set_consolidated_presence(LinphoneCore *lc, LinphoneConsolidatedPresence presence); @@ -5300,7 +5356,7 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_core_remove_friend(LinphoneCor LINPHONE_PUBLIC void linphone_core_reject_subscriber(LinphoneCore *lc, LinphoneFriend *lf); /** - * Get Buddy list of LinphoneFriend + * Get Buddy list of #LinphoneFriend * @param[in] lc #LinphoneCore object * @return \bctbx_list{LinphoneFriend} * @deprecated use linphone_core_get_friends_lists() or linphone_friend_list_get_friends() instead. @@ -5316,7 +5372,7 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED const bctbx_list_t * linphone_core_get_frie LINPHONE_PUBLIC void linphone_core_notify_all_friends(LinphoneCore *lc, LinphonePresenceModel *presence); /** - * Search a LinphoneFriend by its address. + * Search a #LinphoneFriend by its address. * @param[in] lc #LinphoneCore object. * @param[in] addr The address to use to search the friend. * @return The #LinphoneFriend object corresponding to the given address. @@ -5326,7 +5382,7 @@ LINPHONE_PUBLIC void linphone_core_notify_all_friends(LinphoneCore *lc, Linphone LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneFriend *linphone_core_get_friend_by_address(const LinphoneCore *lc, const char *addr); /** - * Search a LinphoneFriend by its address. + * Search a #LinphoneFriend by its address. * @param[in] lc #LinphoneCore object. * @param[in] addr The address to use to search the friend. * @return The #LinphoneFriend object corresponding to the given address. @@ -5334,7 +5390,7 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneFriend *linphone_core_get_friend_by_ LINPHONE_PUBLIC LinphoneFriend *linphone_core_find_friend(const LinphoneCore *lc, const LinphoneAddress *addr); /** - * Search a LinphoneFriend by its reference key. + * Search a #LinphoneFriend by its reference key. * @param[in] lc #LinphoneCore object. * @param[in] key The reference key to use to search the friend. * @return The #LinphoneFriend object corresponding to the given reference key. @@ -5359,51 +5415,51 @@ LINPHONE_PUBLIC void linphone_core_set_friends_database_path(LinphoneCore *lc, c LINPHONE_PUBLIC const char* linphone_core_get_friends_database_path(LinphoneCore *lc); /** - * Create a new empty LinphoneFriendList object. - * @param[in] lc LinphoneCore object. - * @return A new LinphoneFriendList object. + * Create a new empty #LinphoneFriendList object. + * @param[in] lc #LinphoneCore object. + * @return A new #LinphoneFriendList object. **/ LINPHONE_PUBLIC LinphoneFriendList * linphone_core_create_friend_list(LinphoneCore *lc); /** * Add a friend list. - * @param[in] lc LinphoneCore object - * @param[in] list LinphoneFriendList object + * @param[in] lc #LinphoneCore object + * @param[in] list #LinphoneFriendList object */ LINPHONE_PUBLIC void linphone_core_add_friend_list(LinphoneCore *lc, LinphoneFriendList *list); /** * Removes a friend list. - * @param[in] lc LinphoneCore object - * @param[in] list LinphoneFriendList object + * @param[in] lc #LinphoneCore object + * @param[in] list #LinphoneFriendList object */ LINPHONE_PUBLIC void linphone_core_remove_friend_list(LinphoneCore *lc, LinphoneFriendList *list); /** - * Retrieves the list of LinphoneFriendList from the core. - * @param[in] lc LinphoneCore object - * @return \bctbx_list{LinphoneFriendList} a list of LinphoneFriendList + * Retrieves the list of #LinphoneFriendList from the core. + * @param[in] lc #LinphoneCore object + * @return \bctbx_list{LinphoneFriendList} a list of #LinphoneFriendList */ LINPHONE_PUBLIC const bctbx_list_t * linphone_core_get_friends_lists(const LinphoneCore *lc); /** - * Retrieves the first list of LinphoneFriend from the core. - * @param[in] lc LinphoneCore object - * @return the first LinphoneFriendList object or NULL + * Retrieves the first list of #LinphoneFriend from the core. + * @param[in] lc #LinphoneCore object + * @return the first #LinphoneFriendList object or NULL */ LINPHONE_PUBLIC LinphoneFriendList * linphone_core_get_default_friend_list(const LinphoneCore *lc); /** - * Retrieves a list of LinphoneAddress sort and filter - * @param[in] lc LinphoneCore object + * Retrieves a list of #LinphoneAddress sort and filter + * @param[in] lc #LinphoneCore object * @param[in] filter Chars used for the filter* * @param[in] sip_only Only sip address or not - * @return \bctbx_list{LinphoneAddress} a list of filtered LinphoneAddress + the LinphoneAddress created with the filter + * @return \bctbx_list{LinphoneAddress} a list of filtered #LinphoneAddress + the #LinphoneAddress created with the filter **/ LINPHONE_PUBLIC const bctbx_list_t * linphone_core_find_contacts_by_char(LinphoneCore *core, const char *filter, bool_t sip_only); /** - * Create a LinphonePresenceActivity with the given type and description. + * Create a #LinphonePresenceActivity with the given type and description. * @param[in] lc #LinphoneCore object. * @param[in] acttype The #LinphonePresenceActivityType to set for the activity. * @param[in] description An additional description of the activity to set for the activity. Can be NULL if no additional description is to be added. @@ -5419,7 +5475,7 @@ LINPHONE_PUBLIC LinphonePresenceActivity * linphone_core_create_presence_activit LINPHONE_PUBLIC LinphonePresenceModel * linphone_core_create_presence_model(LinphoneCore *lc); /** - * Create a LinphonePresenceModel with the given activity type and activity description. + * Create a #LinphonePresenceModel with the given activity type and activity description. * @param[in] lc #LinphoneCore object. * @param[in] acttype The #LinphonePresenceActivityType to set for the activity of the created model. * @param[in] description An additional description of the activity to set for the activity. Can be NULL if no additional description is to be added. @@ -5428,7 +5484,7 @@ LINPHONE_PUBLIC LinphonePresenceModel * linphone_core_create_presence_model(Linp LINPHONE_PUBLIC LinphonePresenceModel * linphone_core_create_presence_model_with_activity(LinphoneCore *lc, LinphonePresenceActivityType acttype, const char *description); /** - * Create a LinphonePresenceModel with the given activity type, activity description, note content and note language. + * Create a #LinphonePresenceModel with the given activity type, activity description, note content and note language. * @param[in] lc #LinphoneCore object. * @param[in] acttype The #LinphonePresenceActivityType to set for the activity of the created model. * @param[in] description An additional description of the activity to set for the activity. Can be NULL if no additional description is to be added. @@ -5439,7 +5495,7 @@ LINPHONE_PUBLIC LinphonePresenceModel * linphone_core_create_presence_model_with LINPHONE_PUBLIC LinphonePresenceModel * linphone_core_create_presence_model_with_activity_and_note(LinphoneCore *lc, LinphonePresenceActivityType acttype, const char *description, const char *note, const char *lang); /** - * Create a LinphonePresenceNote with the given content and language. + * Create a #LinphonePresenceNote with the given content and language. * @param[in] lc #LinphoneCore object. * @param[in] content The content of the note to be created. * @param[in] lang The language of the note to be created. @@ -5448,7 +5504,7 @@ LINPHONE_PUBLIC LinphonePresenceModel * linphone_core_create_presence_model_with LINPHONE_PUBLIC LinphonePresenceNote * linphone_core_create_presence_note(LinphoneCore *lc, const char *content, const char *lang); /** - * Create a LinphonePresencePerson with the given id. + * Create a #LinphonePresencePerson with the given id. * @param[in] lc #LinphoneCore object * @param[in] id The id of the person to be created. * @return The created #LinphonePresencePerson object. @@ -5456,7 +5512,7 @@ LINPHONE_PUBLIC LinphonePresenceNote * linphone_core_create_presence_note(Linpho LINPHONE_PUBLIC LinphonePresencePerson * linphone_core_create_presence_person(LinphoneCore *lc, const char *id); /** - * Create a LinphonePresenceService with the given id, basic status and contact. + * Create a #LinphonePresenceService with the given id, basic status and contact. * @param[in] lc #LinphoneCore object. * @param[in] id The id of the service to be created. * @param[in] basic_status The basic status of the service to be created. @@ -5495,37 +5551,37 @@ LINPHONE_PUBLIC void linphone_core_notify_notify_presence_received_for_uri_or_te /** - * Create a new LinphoneNatPolicy object with every policies being disabled. - * @param[in] lc LinphoneCore object - * @return A new LinphoneNatPolicy object. + * Create a new #LinphoneNatPolicy object with every policies being disabled. + * @param[in] lc #LinphoneCore object + * @return A new #LinphoneNatPolicy object. * @ingroup network_parameters */ LINPHONE_PUBLIC LinphoneNatPolicy * linphone_core_create_nat_policy(LinphoneCore *lc); /** - * Create a new LinphoneNatPolicy by reading the config of a LinphoneCore according to the passed ref. - * @param[in] lc LinphoneCore object - * @param[in] ref The reference of a NAT policy in the config of the LinphoneCore - * @return A new LinphoneNatPolicy object. + * Create a new #LinphoneNatPolicy by reading the config of a #LinphoneCore according to the passed ref. + * @param[in] lc #LinphoneCore object + * @param[in] ref The reference of a NAT policy in the config of the #LinphoneCore + * @return A new #LinphoneNatPolicy object. * @ingroup network_parameters */ LINPHONE_PUBLIC LinphoneNatPolicy * linphone_core_create_nat_policy_from_config(LinphoneCore *lc, const char *ref); /** - * Create a LinphoneAccountCreator and set Linphone Request callbacks. - * @param[in] core The LinphoneCore used for the XML-RPC communication + * Create a #LinphoneAccountCreator and set Linphone Request callbacks. + * @param[in] core The #LinphoneCore used for the XML-RPC communication * @param[in] xmlrpc_url The URL to the XML-RPC server. Must be NON NULL. - * @return The new LinphoneAccountCreator object. + * @return The new #LinphoneAccountCreator object. * @ingroup account_creator **/ LINPHONE_PUBLIC LinphoneAccountCreator * linphone_core_create_account_creator(LinphoneCore *core, const char *xmlrpc_url); /** - * Create a LinphoneXmlRpcSession for a given url. - * @param[in] lc The LinphoneCore used for the XML-RPC communication + * Create a #LinphoneXmlRpcSession for a given url. + * @param[in] lc The #LinphoneCore used for the XML-RPC communication * @param[in] url The URL to the XML-RPC server. Must be NON NULL. - * @return The new LinphoneXmlRpcSession object. + * @return The new #LinphoneXmlRpcSession object. * @ingroup misc **/ LINPHONE_PUBLIC LinphoneXmlRpcSession * linphone_core_create_xml_rpc_session(LinphoneCore *lc, const char *url); diff --git a/include/linphone/enums/call-enums.h b/include/linphone/enums/call-enums.h index e76cb43c3..ff38c00f7 100644 --- a/include/linphone/enums/call-enums.h +++ b/include/linphone/enums/call-enums.h @@ -23,27 +23,27 @@ // ============================================================================= #define L_ENUM_VALUES_CALL_SESSION_STATE(F) \ - F(Idle) \ - F(IncomingReceived) \ - F(OutgoingInit) \ - F(OutgoingProgress) \ - F(OutgoingRinging) \ - F(OutgoingEarlyMedia) \ - F(Connected) \ - F(StreamsRunning) \ - F(Pausing) \ - F(Paused) \ - F(Resuming) \ - F(Referred) \ - F(Error) \ - F(End) \ - F(PausedByRemote) \ - F(UpdatedByRemote) \ - F(IncomingEarlyMedia) \ - F(Updating) \ - F(Released) \ - F(EarlyUpdatedByRemote) \ - F(EarlyUpdating) + F(Idle /**< Initial state */) \ + F(IncomingReceived /**< Incoming call received */) \ + F(OutgoingInit /**< Outgoing call initialized */) \ + F(OutgoingProgress /**< Outgoing call in progress */) \ + F(OutgoingRinging /**< Outgoing call ringing */) \ + F(OutgoingEarlyMedia /**< Outgoing call early media */) \ + F(Connected /**< Connected */) \ + F(StreamsRunning /**< Streams running */) \ + F(Pausing /**< Pausing */) \ + F(Paused /**< Paused */) \ + F(Resuming /**< Resuming */) \ + F(Referred /**< Referred */) \ + F(Error /**< Error */) \ + F(End /**< Call end */) \ + F(PausedByRemote /**< Paused by remote */) \ + F(UpdatedByRemote /**< The call's parameters are updated for example when video is asked by remote */) \ + F(IncomingEarlyMedia /**< We are proposing early media to an incoming call */) \ + F(Updating /**< We have initiated a call update */) \ + F(Released /**< The call object is now released */) \ + F(EarlyUpdatedByRemote /**< The call is updated by remote while not yet answered (SIP UPDATE in early dialog received) */) \ + F(EarlyUpdating /**< We are updating the call while not yet answered (SIP UPDATE in early dialog sent) */) // ============================================================================= // DEPRECATED diff --git a/include/linphone/enums/chat-message-enums.h b/include/linphone/enums/chat-message-enums.h index 2cb254208..ba1184073 100644 --- a/include/linphone/enums/chat-message-enums.h +++ b/include/linphone/enums/chat-message-enums.h @@ -23,17 +23,17 @@ // ============================================================================= #define L_ENUM_VALUES_CHAT_MESSAGE_STATE(F) \ - F(Idle) \ - F(InProgress) \ - F(Delivered) \ - F(NotDelivered) \ - F(FileTransferError) \ - F(FileTransferDone) \ - F(DeliveredToUser) \ - F(Displayed) + F(Idle /**< Initial state */) \ + F(InProgress /**< Delivery in progress */) \ + F(Delivered /**< Message successfully delivered and acknowledged by the server */) \ + F(NotDelivered /**< Message was not delivered */) \ + F(FileTransferError /**< Message was received and acknowledged but cannot get file from server */) \ + F(FileTransferDone /**< File transfer has been completed successfully */) \ + F(DeliveredToUser /**< Message successfully delivered an acknowledged by the remote user */) \ + F(Displayed /**< Message successfully displayed to the remote user */) #define L_ENUM_VALUES_CHAT_MESSAGE_DIRECTION(F) \ - F(Incoming) \ - F(Outgoing) + F(Incoming /**< Incoming message */) \ + F(Outgoing /**< Outgoing message */) #endif // ifndef _L_CHAT_MESSAGE_ENUMS_H_ diff --git a/include/linphone/enums/chat-room-enums.h b/include/linphone/enums/chat-room-enums.h index 7a9459b9c..32f0c4602 100644 --- a/include/linphone/enums/chat-room-enums.h +++ b/include/linphone/enums/chat-room-enums.h @@ -23,22 +23,22 @@ // ============================================================================= #define L_ENUM_VALUES_CHAT_ROOM_STATE(F) \ - F(None) \ - F(Instantiated) \ - F(CreationPending) \ - F(Created) \ - F(CreationFailed) \ - F(TerminationPending) \ - F(Terminated) \ - F(TerminationFailed) \ - F(Deleted) + F(None /**< Initial state */) \ + F(Instantiated /**< Chat room is now instantiated on local */) \ + F(CreationPending /**< One creation request was sent to the server */) \ + F(Created /**< Chat room was created on the server */) \ + F(CreationFailed /**< Chat room creation failed */) \ + F(TerminationPending /**< Wait for chat room termination */) \ + F(Terminated /**< Chat room exists on server but not in local */) \ + F(TerminationFailed /**< The chat room termination failed */) \ + F(Deleted /**< Chat room was deleted on the server */) #define L_ENUM_VALUES_CHAT_ROOM_CAPABILITIES(F) \ - F(Basic, 1 << 0) \ - F(RealTimeText, 1 << 1) \ - F(Conference, 1 << 2) \ - F(Proxy, 1 << 3) \ - F(Migratable, 1 << 4) \ - F(OneToOne, 1 << 5) + F(Basic /**< No server. It's a direct communication */, 1 << 0) \ + F(RealTimeText /**< Supports RTT */, 1 << 1) \ + F(Conference /**< Use server (supports group chat) */, 1 << 2) \ + F(Proxy /**< Special proxy chat room flag */, 1 << 3) \ + F(Migratable /**< Chat room migratable from Basic to Conference */, 1 << 4) \ + F(OneToOne /**< A communication between two participants (can be Basic or Conference) */, 1 << 5) #endif // ifndef _L_CHAT_ROOM_ENUMS_H_ diff --git a/include/linphone/enums/event-log-enums.h b/include/linphone/enums/event-log-enums.h index 3acd1b62c..fd23f7977 100644 --- a/include/linphone/enums/event-log-enums.h +++ b/include/linphone/enums/event-log-enums.h @@ -23,18 +23,18 @@ // ============================================================================= #define L_ENUM_VALUES_EVENT_LOG_TYPE(F) \ - F(None) \ - F(ConferenceCreated) \ - F(ConferenceTerminated) \ - F(ConferenceCallStart) \ - F(ConferenceCallEnd) \ - F(ConferenceChatMessage) \ - F(ConferenceParticipantAdded) \ - F(ConferenceParticipantRemoved) \ - F(ConferenceParticipantSetAdmin) \ - F(ConferenceParticipantUnsetAdmin) \ - F(ConferenceParticipantDeviceAdded) \ - F(ConferenceParticipantDeviceRemoved) \ - F(ConferenceSubjectChanged) + F(None /**< No defined event */) \ + F(ConferenceCreated /**< Conference (created) event */) \ + F(ConferenceTerminated /**< Conference (terminated) event */) \ + F(ConferenceCallStart /**< Conference call (start) event */) \ + F(ConferenceCallEnd /**< Conference call (end) event */) \ + F(ConferenceChatMessage /**< Conference chat message event */) \ + F(ConferenceParticipantAdded /**< Conference participant (added) event */) \ + F(ConferenceParticipantRemoved /**< Conference participant (removed) event */) \ + F(ConferenceParticipantSetAdmin /**< Conference participant (set admin) event */) \ + F(ConferenceParticipantUnsetAdmin /**< Conference participant (unset admin) event */) \ + F(ConferenceParticipantDeviceAdded /**< Conference participant device (added) event */) \ + F(ConferenceParticipantDeviceRemoved /**< Conference participant device (removed) event */) \ + F(ConferenceSubjectChanged /**< Conference subject event */) \ #endif // ifndef _L_EVENT_LOG_ENUMS_H_ diff --git a/include/linphone/error_info.h b/include/linphone/error_info.h index 121983924..23a26c753 100644 --- a/include/linphone/error_info.h +++ b/include/linphone/error_info.h @@ -32,9 +32,9 @@ extern "C" { */ /** - * Create an empty LinphoneErrorInfo object. - * The LinphoneErrorInfo object carries these fields: - * - a LinphoneReason enum member giving overall signification of the error reported. + * Create an empty #LinphoneErrorInfo object. + * The #LinphoneErrorInfo object carries these fields: + * - a #LinphoneReason enum member giving overall signification of the error reported. * - the "protocol" name in which the protocol reason code has meaning, for example SIP or Q.850 * - the "protocol code", an integer referencing the kind of error reported * - the "phrase", a text phrase describing the error @@ -63,10 +63,10 @@ LINPHONE_PUBLIC void linphone_error_info_unref(LinphoneErrorInfo *ei); LINPHONE_PUBLIC LinphoneReason linphone_error_info_get_reason(const LinphoneErrorInfo *ei); /** - * Get pointer to chained LinphoneErrorInfo set in sub_ei. + * Get pointer to chained #LinphoneErrorInfo set in sub_ei. * It corresponds to a Reason header in a received SIP response. * @param ei ErrorInfo object - * @return LinphoneErrorInfo pointer defined in the ei object. + * @return #LinphoneErrorInfo pointer defined in the ei object. */ LINPHONE_PUBLIC LinphoneErrorInfo* linphone_error_info_get_sub_error_info(const LinphoneErrorInfo *ei); @@ -102,10 +102,10 @@ LINPHONE_PUBLIC const char * linphone_error_info_get_warnings(const LinphoneErro LINPHONE_PUBLIC int linphone_error_info_get_protocol_code(const LinphoneErrorInfo *ei); /** - * Assign information to a LinphoneErrorInfo object. + * Assign information to a #LinphoneErrorInfo object. * @param[in] ei ErrorInfo object * @param[in] protocol protocol name - * @param[in] reason reason from LinphoneReason enum + * @param[in] reason reason from #LinphoneReason enum * @param[in] code protocol code * @param[in] status_string description of the reason * @param[in] warning warning message @@ -113,44 +113,44 @@ LINPHONE_PUBLIC int linphone_error_info_get_protocol_code(const LinphoneErrorInf LINPHONE_PUBLIC void linphone_error_info_set(LinphoneErrorInfo *ei, const char *protocol, LinphoneReason reason, int code, const char *status_string, const char *warning); /** - * Set the sub_ei in LinphoneErrorInfo to another LinphoneErrorInfo. - * Used when a reason header is to be added in a SIP response. The first level LinphoneErrorInfo defines the SIP response code and phrase, - * the second (sub) LinphoneErroInfo defining the content of the Reason header. - * @param[in] ei LinphoneErrorInfo object to which the other LinphoneErrorInfo will be appended as ei->sub_ei. - * @param[in] appended_ei LinphoneErrorInfo to append + * Set the sub_ei in #LinphoneErrorInfo to another LinphoneErrorInfo. + * Used when a reason header is to be added in a SIP response. The first level #LinphoneErrorInfo defines the SIP response code and phrase, + * the second (sub) #LinphoneErroInfo defining the content of the Reason header. + * @param[in] ei #LinphoneErrorInfo object to which the other #LinphoneErrorInfo will be appended as ei->sub_ei. + * @param[in] appended_ei #LinphoneErrorInfo to append */ LINPHONE_PUBLIC void linphone_error_info_set_sub_error_info(LinphoneErrorInfo *ei, LinphoneErrorInfo *appended_ei); /** - * Assign reason LinphoneReason to a LinphoneErrorInfo object. + * Assign reason #LinphoneReason to a #LinphoneErrorInfo object. * @param[in] ei ErrorInfo object - * @param[in] reason reason from LinphoneReason enum + * @param[in] reason reason from #LinphoneReason enum */ LINPHONE_PUBLIC void linphone_error_info_set_reason(LinphoneErrorInfo *ei, LinphoneReason reason); /** - * Assign protocol name to a LinphoneErrorInfo object. + * Assign protocol name to a #LinphoneErrorInfo object. * @param[in] ei ErrorInfo object * @param[in] proto the protocol name */ LINPHONE_PUBLIC void linphone_error_info_set_protocol(LinphoneErrorInfo *ei, const char *proto); /** - * Assign protocol code to a LinphoneErrorInfo object. + * Assign protocol code to a #LinphoneErrorInfo object. * @param[in] ei ErrorInfo object * @param[in] code the protocol code */ LINPHONE_PUBLIC void linphone_error_info_set_protocol_code(LinphoneErrorInfo *ei, int code); /** - * Assign phrase to a LinphoneErrorInfo object. + * Assign phrase to a #LinphoneErrorInfo object. * @param[in] ei ErrorInfo object * @param[in] phrase the phrase explaining the error */ LINPHONE_PUBLIC void linphone_error_info_set_phrase(LinphoneErrorInfo *ei, const char *phrase); /** - * Assign warnings to a LinphoneErrorInfo object. + * Assign warnings to a #LinphoneErrorInfo object. * @param[in] ei ErrorInfo object * @param[in] phrase the warnings */ diff --git a/include/linphone/event.h b/include/linphone/event.h index cdb63a6d7..a2306edbc 100644 --- a/include/linphone/event.h +++ b/include/linphone/event.h @@ -34,7 +34,7 @@ extern "C" { /** * Send a subscription previously created by linphone_core_create_subscribe(). - * @param ev the LinphoneEvent + * @param ev the #LinphoneEvent * @param body optional content to attach with the subscription. * @return 0 if successful, -1 otherwise. **/ @@ -42,14 +42,14 @@ LINPHONE_PUBLIC LinphoneStatus linphone_event_send_subscribe(LinphoneEvent *ev, /** * Update (refresh) an outgoing subscription, changing the body. - * @param lev a LinphoneEvent + * @param lev a #LinphoneEvent * @param body an optional body to include in the subscription update, may be NULL. **/ LINPHONE_PUBLIC LinphoneStatus linphone_event_update_subscribe(LinphoneEvent *lev, const LinphoneContent *body); /** * Refresh an outgoing subscription keeping the same body. - * @param lev LinphoneEvent object. + * @param lev #LinphoneEvent object. * @return 0 if successful, -1 otherwise. */ LINPHONE_PUBLIC LinphoneStatus linphone_event_refresh_subscribe(LinphoneEvent *lev); @@ -89,7 +89,7 @@ LINPHONE_PUBLIC LinphoneStatus linphone_event_update_publish(LinphoneEvent *lev, /** * Refresh an outgoing publish keeping the same body. - * @param lev LinphoneEvent object. + * @param lev #LinphoneEvent object. * @return 0 if successful, -1 otherwise. */ LINPHONE_PUBLIC LinphoneStatus linphone_event_refresh_publish(LinphoneEvent *lev); @@ -141,7 +141,7 @@ LINPHONE_PUBLIC void *linphone_event_get_user_data(const LinphoneEvent *ev); /** * Add a custom header to an outgoing susbscription or publish. - * @param ev the LinphoneEvent + * @param ev the #LinphoneEvent * @param name header's name * @param value the header's value. **/ @@ -149,7 +149,7 @@ LINPHONE_PUBLIC void linphone_event_add_custom_header(LinphoneEvent *ev, const c /** * Obtain the value of a given header for an incoming subscription. - * @param ev the LinphoneEvent + * @param ev the #LinphoneEvent * @param name header's name * @return the header's value or NULL if such header doesn't exist. **/ @@ -157,14 +157,14 @@ LINPHONE_PUBLIC const char *linphone_event_get_custom_header(LinphoneEvent *ev, /** * Terminate an incoming or outgoing subscription that was previously acccepted, or a previous publication. - * The LinphoneEvent shall not be used anymore after this operation, unless the application explicitely took a reference on the object with + * The #LinphoneEvent shall not be used anymore after this operation, unless the application explicitely took a reference on the object with * linphone_event_ref(). **/ LINPHONE_PUBLIC void linphone_event_terminate(LinphoneEvent *lev); /** * Increase reference count of LinphoneEvent. - * By default LinphoneEvents created by the core are owned by the core only. + * By default #LinphoneEvents created by the core are owned by the core only. * An application that wishes to retain a reference to it must call linphone_event_ref(). * When this reference is no longer needed, linphone_event_unref() must be called. * @@ -194,13 +194,13 @@ LINPHONE_PUBLIC const LinphoneAddress *linphone_event_get_resource(const Linphon /** * Get the "contact" address of the subscription. - * @param[in] lev LinphoneEvent object + * @param[in] lev #LinphoneEvent object * @return The "contact" address of the subscription */ LINPHONE_PUBLIC const LinphoneAddress *linphone_event_get_remote_contact (const LinphoneEvent *lev); /** - * Returns back pointer to the LinphoneCore that created this LinphoneEvent + * Returns back pointer to the #LinphoneCore that created this #LinphoneEvent **/ LINPHONE_PUBLIC LinphoneCore *linphone_event_get_core(const LinphoneEvent *lev); diff --git a/include/linphone/factory.h b/include/linphone/factory.h index be26938cc..6a1fbbbf0 100644 --- a/include/linphone/factory.h +++ b/include/linphone/factory.h @@ -47,7 +47,7 @@ LINPHONE_PUBLIC void linphone_factory_clean(void); /** * Instanciate a #LinphoneCore object. * - * The LinphoneCore object is the primary handle for doing all phone actions. + * The #LinphoneCore object is the primary handle for doing all phone actions. * It should be unique within your application. * @param factory The #LinphoneFactory singleton. * @param cbs a #LinphoneCoreCbs object holding your application callbacks. A reference @@ -74,7 +74,7 @@ LINPHONE_DEPRECATED LINPHONE_PUBLIC LinphoneCore *linphone_factory_create_core( /** * Instanciate a #LinphoneCore object. * - * The LinphoneCore object is the primary handle for doing all phone actions. + * The #LinphoneCore object is the primary handle for doing all phone actions. * It should be unique within your application. * @param factory The #LinphoneFactory singleton. * @param cbs a #LinphoneCoreCbs object holding your application callbacks. A reference @@ -105,13 +105,13 @@ LINPHONE_DEPRECATED LINPHONE_PUBLIC LinphoneCore *linphone_factory_create_core_2 /** * Instantiate a #LinphoneCore object. * - * The LinphoneCore object is the primary handle for doing all phone actions. It should be unique within your + * The #LinphoneCore object is the primary handle for doing all phone actions. It should be unique within your * application. - * The LinphoneCore object is not started automatically, you need to call linphone_core_start() to that effect. + * The #LinphoneCore object is not started automatically, you need to call linphone_core_start() to that effect. * @param[in] factory The #LinphoneFactory singleton. * @param[in] config_path A path to a config file. If it does not exists it will be created. The config file is used to - * store all settings, proxies... so that all these settings become persistent over the life of the LinphoneCore object. - * It is allowed to set a NULL config file. In that case LinphoneCore will not store any settings. + * store all settings, proxies... so that all these settings become persistent over the life of the #LinphoneCore object. + * It is allowed to set a NULL config file. In that case #LinphoneCore will not store any settings. * @param[in] factory_config_path A path to a read-only config file that can be used to store hard-coded preferences * such as proxy settings or internal preferences. The settings in this factory file always override the ones in the * normal config file. It is optional, use NULL if unneeded. @@ -127,15 +127,15 @@ LINPHONE_PUBLIC LinphoneCore *linphone_factory_create_core_3 ( ); /** - * Instantiates a LinphoneCore object with a given LpConfig. + * Instantiates a #LinphoneCore object with a given LpConfig. * * @param factory The #LinphoneFactory singleton. - * The LinphoneCore object is the primary handle for doing all phone actions. + * The #LinphoneCore object is the primary handle for doing all phone actions. * It should be unique within your application. * @param cbs a #LinphoneCoreCbs object holding your application callbacks. A reference * will be taken on it until the destruciton of the core or the unregistration * with linphone_core_remove_cbs(). - * @param config a pointer to an LpConfig object holding the configuration of the LinphoneCore to be instantiated. + * @param config a pointer to an LpConfig object holding the configuration of the #LinphoneCore to be instantiated. * @see linphone_core_new * @deprecated 2018-01-10: Use linphone_factory_create_core_with_config_3() instead */ @@ -146,15 +146,15 @@ LINPHONE_DEPRECATED LINPHONE_PUBLIC LinphoneCore *linphone_factory_create_core_w ); /** - * Instantiates a LinphoneCore object with a given LpConfig. + * Instantiates a #LinphoneCore object with a given LpConfig. * * @param factory The #LinphoneFactory singleton. - * The LinphoneCore object is the primary handle for doing all phone actions. + * The #LinphoneCore object is the primary handle for doing all phone actions. * It should be unique within your application. * @param cbs a #LinphoneCoreCbs object holding your application callbacks. A reference * will be taken on it until the destruciton of the core or the unregistration * with linphone_core_remove_cbs(). - * @param config a pointer to an LpConfig object holding the configuration of the LinphoneCore to be instantiated. + * @param config a pointer to an LpConfig object holding the configuration of the #LinphoneCore to be instantiated. * @param user_data an application pointer associated with the returned core. * @param system_context a pointer to a system object required by the core to operate. Currently it is required to pass an android Context on android, pass NULL on other platforms. * @see linphone_core_new @@ -169,13 +169,13 @@ LINPHONE_DEPRECATED LINPHONE_PUBLIC LinphoneCore *linphone_factory_create_core_w ); /** - * Instantiate a LinphoneCore object with a given LinphoneConfig. + * Instantiate a #LinphoneCore object with a given LinphoneConfig. * - * The LinphoneCore object is the primary handle for doing all phone actions. It should be unique within your + * The #LinphoneCore object is the primary handle for doing all phone actions. It should be unique within your * application. - * The LinphoneCore object is not started automatically, you need to call linphone_core_start() to that effect. + * The #LinphoneCore object is not started automatically, you need to call linphone_core_start() to that effect. * @param[in] factory The #LinphoneFactory singleton. - * @param[in] config A #LinphoneConfig object holding the configuration for the LinphoneCore to be instantiated. + * @param[in] config A #LinphoneConfig object holding the configuration for the #LinphoneCore to be instantiated. * @param[in] system_context A pointer to a system object required by the core to operate. Currently it is required to * pass an android Context on android, pass NULL on other platforms. * @see linphone_factory_create_core_3 @@ -212,15 +212,15 @@ LINPHONE_PUBLIC LinphoneAddress *linphone_factory_create_address(const LinphoneF * @param ha1 The ha1-encrypted password if password is not given in clear text. * @param realm The authentication domain (which can be larger than the sip domain. Unfortunately many SIP servers don't use this parameter. * @param domain The SIP domain for which this authentication information is valid, if it has to be restricted for a single SIP domain. - * @return A #LinphoneAuthInfo object. linphone_auth_info_destroy() must be used to destroy it when no longer needed. The LinphoneCore makes a copy of LinphoneAuthInfo + * @return A #LinphoneAuthInfo object. linphone_auth_info_destroy() must be used to destroy it when no longer needed. The #LinphoneCore makes a copy of #LinphoneAuthInfo * passed through linphone_core_add_auth_info(). */ LINPHONE_PUBLIC LinphoneAuthInfo *linphone_factory_create_auth_info(const LinphoneFactory *factory, const char *username, const char *userid, const char *passwd, const char *ha1, const char *realm, const char *domain); /** - * Create a LinphoneCallCbs object that holds callbacks for events happening on a call. - * @param[in] factory LinphoneFactory singletion object - * @return A new LinphoneCallCbs object + * Create a #LinphoneCallCbs object that holds callbacks for events happening on a call. + * @param[in] factory #LinphoneFactory singletion object + * @return A new #LinphoneCallCbs object */ LINPHONE_PUBLIC LinphoneCallCbs * linphone_factory_create_call_cbs(const LinphoneFactory *factory); @@ -239,32 +239,32 @@ LINPHONE_PUBLIC LinphoneChatRoomCbs * linphone_factory_create_chat_room_cbs(cons LINPHONE_PUBLIC LinphoneVcard *linphone_factory_create_vcard(LinphoneFactory *factory); /** - * Create a LinphoneVideoDefinition from a given width and height - * @param[in] factory LinphoneFactory singleton object + * Create a #LinphoneVideoDefinition from a given width and height + * @param[in] factory #LinphoneFactory singleton object * @param[in] width The width of the created video definition * @param[in] height The height of the created video definition - * @return A new LinphoneVideoDefinition object + * @return A new #LinphoneVideoDefinition object */ LINPHONE_PUBLIC LinphoneVideoDefinition * linphone_factory_create_video_definition(const LinphoneFactory *factory, unsigned int width, unsigned int height); /** - * Create a LinphoneVideoDefinition from a given standard definition name - * @param[in] factory LinphoneFactory singleton object + * Create a #LinphoneVideoDefinition from a given standard definition name + * @param[in] factory #LinphoneFactory singleton object * @param[in] name The standard definition name of the video definition to create - * @return A new LinphoneVideoDefinition object + * @return A new #LinphoneVideoDefinition object */ LINPHONE_PUBLIC LinphoneVideoDefinition * linphone_factory_create_video_definition_from_name(const LinphoneFactory *factory, const char *name); /** * Get the list of standard video definitions supported by Linphone. - * @param[in] factory LinphoneFactory singleton object + * @param[in] factory #LinphoneFactory singleton object * @return \bctbx_list{LinphoneVideoDefinition} */ LINPHONE_PUBLIC const bctbx_list_t * linphone_factory_get_supported_video_definitions(const LinphoneFactory *factory); /** * Get the top directory where the resources are located. - * @param[in] factory LinphoneFactory object + * @param[in] factory #LinphoneFactory object * @return The path to the top directory where the resources are located */ LINPHONE_PUBLIC const char * linphone_factory_get_top_resources_dir(const LinphoneFactory *factory); @@ -272,199 +272,207 @@ LINPHONE_PUBLIC const char * linphone_factory_get_top_resources_dir(const Linpho /** * Set the top directory where the resources are located. * If you only define this top directory, the other resources directory will automatically be derived form this one. - * @param[in] factory LinphoneFactory object + * @param[in] factory #LinphoneFactory object * @param[in] path The path to the top directory where the resources are located */ LINPHONE_PUBLIC void linphone_factory_set_top_resources_dir(LinphoneFactory *factory, const char *path); /** * Get the directory where the data resources are located. - * @param[in] factory LinphoneFactory object + * @param[in] factory #LinphoneFactory object * @return The path to the directory where the data resources are located */ LINPHONE_PUBLIC const char * linphone_factory_get_data_resources_dir(LinphoneFactory *factory); /** * Set the directory where the data resources are located. - * @param[in] factory LinphoneFactory object + * @param[in] factory #LinphoneFactory object * @param[in] path The path where the data resources are located */ LINPHONE_PUBLIC void linphone_factory_set_data_resources_dir(LinphoneFactory *factory, const char *path); /** * Get the directory where the sound resources are located. - * @param[in] factory LinphoneFactory object + * @param[in] factory #LinphoneFactory object * @return The path to the directory where the sound resources are located */ LINPHONE_PUBLIC const char * linphone_factory_get_sound_resources_dir(LinphoneFactory *factory); /** * Set the directory where the sound resources are located. - * @param[in] factory LinphoneFactory object + * @param[in] factory #LinphoneFactory object * @param[in] path The path where the sound resources are located */ LINPHONE_PUBLIC void linphone_factory_set_sound_resources_dir(LinphoneFactory *factory, const char *path); /** * Get the directory where the ring resources are located. - * @param[in] factory LinphoneFactory object + * @param[in] factory #LinphoneFactory object * @return The path to the directory where the ring resources are located */ LINPHONE_PUBLIC const char * linphone_factory_get_ring_resources_dir(LinphoneFactory *factory); /** * Set the directory where the ring resources are located. - * @param[in] factory LinphoneFactory object + * @param[in] factory #LinphoneFactory object * @param[in] path The path where the ring resources are located */ LINPHONE_PUBLIC void linphone_factory_set_ring_resources_dir(LinphoneFactory *factory, const char *path); /** * Get the directory where the image resources are located. - * @param[in] factory LinphoneFactory object + * @param[in] factory #LinphoneFactory object * @return The path to the directory where the image resources are located */ LINPHONE_PUBLIC const char * linphone_factory_get_image_resources_dir(LinphoneFactory *factory); /** * Set the directory where the image resources are located. - * @param[in] factory LinphoneFactory object + * @param[in] factory #LinphoneFactory object * @param[in] path The path where the image resources are located */ LINPHONE_PUBLIC void linphone_factory_set_image_resources_dir(LinphoneFactory *factory, const char *path); /** * Get the directory where the mediastreamer2 plugins are located. - * @param[in] factory LinphoneFactory object + * @param[in] factory #LinphoneFactory object * @return The path to the directory where the mediastreamer2 plugins are located, or NULL if it has not been set */ LINPHONE_PUBLIC const char * linphone_factory_get_msplugins_dir(LinphoneFactory *factory); /** * Set the directory where the mediastreamer2 plugins are located. - * @param[in] factory LinphoneFactory object + * @param[in] factory #LinphoneFactory object * @param[in] path The path to the directory where the mediastreamer2 plugins are located */ LINPHONE_PUBLIC void linphone_factory_set_msplugins_dir(LinphoneFactory *factory, const char *path); /** * Creates an object LinphoneErrorInfo. - * @param[in] factory LinphoneFactory object - * @return LinphoneErrorInfo object. + * @param[in] factory #LinphoneFactory object + * @return #LinphoneErrorInfo object. */ LINPHONE_PUBLIC LinphoneErrorInfo *linphone_factory_create_error_info(LinphoneFactory *factory); /** * Creates an object LinphoneRange. - * @param[in] factory LinphoneFactory object - * @return LinphoneRange object. + * @param[in] factory #LinphoneFactory object + * @return #LinphoneRange object. */ LINPHONE_PUBLIC LinphoneRange *linphone_factory_create_range(LinphoneFactory *factory); /** * Creates an object LinphoneTransports. - * @param[in] factory LinphoneFactory object - * @return LinphoneTransports object. + * @param[in] factory #LinphoneFactory object + * @return #LinphoneTransports object. */ LINPHONE_PUBLIC LinphoneTransports *linphone_factory_create_transports(LinphoneFactory *factory); /** * Creates an object LinphoneVideoActivationPolicy. - * @param[in] factory LinphoneFactory object - * @return LinphoneVideoActivationPolicy object. + * @param[in] factory #LinphoneFactory object + * @return #LinphoneVideoActivationPolicy object. */ LINPHONE_PUBLIC LinphoneVideoActivationPolicy *linphone_factory_create_video_activation_policy(LinphoneFactory *factory); /** * Returns a bctbx_list_t of all DialPlans - * @param[in] factory the LinphoneFactory object + * @param[in] factory the #LinphoneFactory object * @return \bctbx_list{LinphoneDialPlan} a list of DialPlan */ LINPHONE_PUBLIC const bctbx_list_t * linphone_factory_get_dial_plans(const LinphoneFactory *factory); /** - * Creates an object LinphoneContent - * @param[in] factory the LinphoneFactory - * @return a LinphoneContent + * Creates an object #LinphoneContent + * @param[in] factory the #LinphoneFactory + * @return a #LinphoneContent */ LINPHONE_PUBLIC LinphoneContent *linphone_factory_create_content(LinphoneFactory *factory); /** - * Creates an object LinphoneBuffer - * @param[in] factory the LinphoneFactory - * @return a LinphoneBuffer + * Creates an object #LinphoneBuffer + * @param[in] factory the #LinphoneFactory + * @return a #LinphoneBuffer */ LINPHONE_PUBLIC LinphoneBuffer *linphone_factory_create_buffer(LinphoneFactory *factory); /** - * Creates an object LinphoneBuffer - * @param[in] factory the LinphoneFactory + * Creates an object #LinphoneBuffer + * @param[in] factory the #LinphoneFactory * @param[in] data the data to set in the buffer * @param[in] size the size of the data - * @return a LinphoneBuffer + * @return a #LinphoneBuffer */ LINPHONE_PUBLIC LinphoneBuffer *linphone_factory_create_buffer_from_data(LinphoneFactory *factory, const uint8_t *data, size_t size); /** - * Creates an object LinphoneBuffer - * @param[in] factory the LinphoneFactory + * Creates an object #LinphoneBuffer + * @param[in] factory the #LinphoneFactory * @param[in] data the data to set in the buffer - * @return a LinphoneBuffer + * @return a #LinphoneBuffer */ LINPHONE_PUBLIC LinphoneBuffer *linphone_factory_create_buffer_from_string(LinphoneFactory *factory, const char *data); /** - * Creates an object LinphoneConfig - * @param[in] factory the LinphoneFactory - * @param[in] the path of the config - * @return a LinphoneConfig + * Creates an object #LinphoneConfig + * @param[in] factory the #LinphoneFactory + * @param[in] path the path of the config + * @return a #LinphoneConfig */ LINPHONE_PUBLIC LinphoneConfig *linphone_factory_create_config(LinphoneFactory *factory, const char *path); /** - * Creates an object LinphoneConfig - * @param[in] factory the LinphoneFactory - * @param[in] the path of the config - * @param[in] the path of the factory - * @return a LinphoneConfig + * Creates an object #LinphoneConfig + * @param[in] factory the #LinphoneFactory + * @param[in] path the path of the config + * @param[in] path the path of the factory + * @return a #LinphoneConfig */ LINPHONE_PUBLIC LinphoneConfig *linphone_factory_create_config_with_factory(LinphoneFactory *factory, const char *path, const char *factory_path); /** - * Creates an object LinphoneConfig - * @param[in] factory the LinphoneFactory - * @return a LinphoneConfig + * Creates an object #LinphoneConfig + * @param[in] factory the #LinphoneFactory + * @param[in] data the config data + * @return a #LinphoneConfig */ LINPHONE_PUBLIC LinphoneConfig *linphone_factory_create_config_from_string(LinphoneFactory *factory, const char *data); /** - * Gets the user data in the LinphoneFactory object - * @param[in] factory the LinphoneFactory + * Gets the user data in the #LinphoneFactory object + * @param[in] factory the #LinphoneFactory * @return the user data */ LINPHONE_PUBLIC void *linphone_factory_get_user_data(const LinphoneFactory *factory); /** - * Sets the user data in the LinphoneFactory object - * @param[in] factory the LinphoneFactory object + * Sets the user data in the #LinphoneFactory object + * @param[in] factory the #LinphoneFactory object * @param[in] data the user data */ LINPHONE_PUBLIC void linphone_factory_set_user_data(LinphoneFactory *factory, void *data); /** * Sets the log collection path - * @param[in] factory the LinphoneFactory - * @param[in] the path of the logs + * @param[in] factory the #LinphoneFactory + * @param[in] path the path of the logs */ LINPHONE_PUBLIC void linphone_factory_set_log_collection_path(LinphoneFactory *factory, const char *path); /** * Enables or disables log collection - * @param[in] factory the LinphoneFactory - * @param[in] the policy for log collection + * @param[in] factory the #LinphoneFactory + * @param[in] state the policy for log collection */ LINPHONE_PUBLIC void linphone_factory_enable_log_collection(LinphoneFactory *factory, LinphoneLogCollectionState state); +/** + * Creates an object #LinphoneTunnelConfig + * @param[in] factory the #LinphoneFactory + * @return a #LinphoneTunnelConfig + */ +LINPHONE_PUBLIC LinphoneTunnelConfig *linphone_factory_create_tunnel_config(LinphoneFactory *factory); + /** * @} */ diff --git a/include/linphone/friend.h b/include/linphone/friend.h index 8514efc79..4717ef16f 100644 --- a/include/linphone/friend.h +++ b/include/linphone/friend.h @@ -56,7 +56,7 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneFriend *linphone_friend_new_with_add /** * Destroy a LinphoneFriend. - * @param lf LinphoneFriend object + * @param lf #LinphoneFriend object * @deprecated Use linphone_friend_unref() instead. * @donotwrap */ @@ -77,7 +77,7 @@ LINPHONE_PUBLIC LinphoneStatus linphone_friend_set_address(LinphoneFriend *fr, c /** * Get address of this friend. - * @note the LinphoneAddress object returned is hold by the LinphoneFriend, however calling several time this function may return different objects. + * @note the #LinphoneAddress object returned is hold by the LinphoneFriend, however calling several time this function may return different objects. * @param lf #LinphoneFriend object * @return #LinphoneAddress */ @@ -215,7 +215,7 @@ LINPHONE_PUBLIC const LinphonePresenceModel * linphone_friend_get_presence_model /** * Get the consolidated presence of a friend. - * @param[in] lf LinphoneFriend object + * @param[in] lf #LinphoneFriend object * @return The consolidated presence of the friend */ LINPHONE_PUBLIC LinphoneConsolidatedPresence linphone_friend_get_consolidated_presence(const LinphoneFriend *lf); @@ -285,39 +285,39 @@ LINPHONE_PUBLIC bool_t linphone_friend_in_list(const LinphoneFriend *lf); /** * Acquire a reference to the linphone friend. - * @param[in] lf LinphoneFriend object - * @return The same LinphoneFriend object + * @param[in] lf #LinphoneFriend object + * @return The same #LinphoneFriend object **/ LINPHONE_PUBLIC LinphoneFriend * linphone_friend_ref(LinphoneFriend *lf); /** * Release a reference to the linphone friend. - * @param[in] lf LinphoneFriend object + * @param[in] lf #LinphoneFriend object **/ LINPHONE_PUBLIC void linphone_friend_unref(LinphoneFriend *lf); /** - * Returns the LinphoneCore object managing this friend, if any. - * @param[in] fr LinphoneFriend object + * Returns the #LinphoneCore object managing this friend, if any. + * @param[in] fr #LinphoneFriend object */ LINPHONE_PUBLIC LinphoneCore *linphone_friend_get_core(const LinphoneFriend *fr); /** * Returns the vCard object associated to this friend, if any - * @param[in] fr LinphoneFriend object + * @param[in] fr #LinphoneFriend object */ LINPHONE_PUBLIC LinphoneVcard* linphone_friend_get_vcard(const LinphoneFriend *fr); /** * Binds a vCard object to a friend - * @param[in] fr LinphoneFriend object + * @param[in] fr #LinphoneFriend object * @param[in] vcard The vCard object to bind */ LINPHONE_PUBLIC void linphone_friend_set_vcard(LinphoneFriend *fr, LinphoneVcard *vcard); /** * Creates a vCard object associated to this friend if there isn't one yet and if the full name is available, either by the parameter or the one in the friend's SIP URI - * @param[in] fr LinphoneFriend object + * @param[in] fr #LinphoneFriend object * @param[in] name The full name of the friend or NULL to use the one from the friend's SIP URI * @return true if the vCard has been created, false if it wasn't possible (for exemple if name and the friend's SIP URI are null or if the friend's SIP URI doesn't have a display name), or if there is already one vcard */ diff --git a/include/linphone/friendlist.h b/include/linphone/friendlist.h index 1780e8723..b64536717 100644 --- a/include/linphone/friendlist.h +++ b/include/linphone/friendlist.h @@ -36,126 +36,126 @@ extern "C" { /** * Acquire a reference to the friend list. - * @param[in] list LinphoneFriendList object. - * @return The same LinphoneFriendList object. + * @param[in] list #LinphoneFriendList object. + * @return The same #LinphoneFriendList object. **/ LINPHONE_PUBLIC LinphoneFriendList * linphone_friend_list_ref(LinphoneFriendList *list); /** * Release reference to the friend list. - * @param[in] list LinphoneFriendList object. + * @param[in] list #LinphoneFriendList object. **/ LINPHONE_PUBLIC void linphone_friend_list_unref(LinphoneFriendList *list); /** * Retrieve the user pointer associated with the friend list. - * @param[in] list LinphoneFriendList object. + * @param[in] list #LinphoneFriendList object. * @return The user pointer associated with the friend list. **/ LINPHONE_PUBLIC void * linphone_friend_list_get_user_data(const LinphoneFriendList *list); /** * Assign a user pointer to the friend list. - * @param[in] list LinphoneFriendList object. + * @param[in] list #LinphoneFriendList object. * @param[in] ud The user pointer to associate with the friend list. **/ LINPHONE_PUBLIC void linphone_friend_list_set_user_data(LinphoneFriendList *list, void *ud); /** * Get the display name of the friend list. - * @param[in] list LinphoneFriendList object. + * @param[in] list #LinphoneFriendList object. * @return The display name of the friend list. **/ LINPHONE_PUBLIC const char * linphone_friend_list_get_display_name(const LinphoneFriendList *list); /** * Set the display name of the friend list. - * @param[in] list LinphoneFriendList object. + * @param[in] list #LinphoneFriendList object. * @param[in] display_name The new display name of the friend list. **/ LINPHONE_PUBLIC void linphone_friend_list_set_display_name(LinphoneFriendList *list, const char *display_name); /** * Get the RLS (Resource List Server) URI associated with the friend list to subscribe to these friends presence. - * @param[in] list LinphoneFriendList object. + * @param[in] list #LinphoneFriendList object. * @return The RLS URI associated with the friend list. **/ LINPHONE_PUBLIC const char * linphone_friend_list_get_rls_uri(const LinphoneFriendList *list); /** * Set the RLS (Resource List Server) URI associated with the friend list to subscribe to these friends presence. - * @param[in] list LinphoneFriendList object. + * @param[in] list #LinphoneFriendList object. * @param[in] rls_uri The RLS URI to associate with the friend list. **/ LINPHONE_PUBLIC void linphone_friend_list_set_rls_uri(LinphoneFriendList *list, const char *rls_uri); /** * Get the RLS (Resource List Server) URI associated with the friend list to subscribe to these friends presence. - * @param[in] list LinphoneFriendList object. + * @param[in] list #LinphoneFriendList object. * @return The RLS URI associated with the friend list. **/ LINPHONE_PUBLIC const LinphoneAddress * linphone_friend_list_get_rls_address(const LinphoneFriendList *list); /** * Set the RLS (Resource List Server) URI associated with the friend list to subscribe to these friends presence. - * @param[in] list LinphoneFriendList object. + * @param[in] list #LinphoneFriendList object. * @param[in] rls_addr The RLS URI to associate with the friend list. **/ LINPHONE_PUBLIC void linphone_friend_list_set_rls_address(LinphoneFriendList *list, const LinphoneAddress *rls_addr); /** * Add a friend to a friend list. If or when a remote CardDAV server will be attached to the list, the friend will be sent to the server. - * @param[in] list LinphoneFriendList object. - * @param[in] lf LinphoneFriend object to add to the friend list. - * @return LinphoneFriendListOK if successfully added, LinphoneFriendListInvalidFriend if the friend is not valid. + * @param[in] list #LinphoneFriendList object. + * @param[in] lf #LinphoneFriend object to add to the friend list. + * @return #LinphoneFriendListOK if successfully added, #LinphoneFriendListInvalidFriend if the friend is not valid. **/ LINPHONE_PUBLIC LinphoneFriendListStatus linphone_friend_list_add_friend(LinphoneFriendList *list, LinphoneFriend *lf); /** * Add a friend to a friend list. The friend will never be sent to a remote CardDAV server. - * Warning! LinphoneFriends added this way will be removed on the next synchronization, and the callback contact_deleted will be called. - * @param[in] list LinphoneFriendList object. - * @param[in] lf LinphoneFriend object to add to the friend list. - * @return LinphoneFriendListOK if successfully added, LinphoneFriendListInvalidFriend if the friend is not valid. + * Warning! #LinphoneFriends added this way will be removed on the next synchronization, and the callback contact_deleted will be called. + * @param[in] list #LinphoneFriendList object. + * @param[in] lf #LinphoneFriend object to add to the friend list. + * @return #LinphoneFriendListOK if successfully added, #LinphoneFriendListInvalidFriend if the friend is not valid. **/ LINPHONE_PUBLIC LinphoneFriendListStatus linphone_friend_list_add_local_friend(LinphoneFriendList *list, LinphoneFriend *lf); /** * Remove a friend from a friend list. - * @param[in] list LinphoneFriendList object. - * @param[in] lf LinphoneFriend object to remove from the friend list. - * @return LinphoneFriendListOK if removed successfully, LinphoneFriendListNonExistentFriend if the friend is not in the list. + * @param[in] list #LinphoneFriendList object. + * @param[in] lf #LinphoneFriend object to remove from the friend list. + * @return #LinphoneFriendListOK if removed successfully, #LinphoneFriendListNonExistentFriend if the friend is not in the list. **/ LINPHONE_PUBLIC LinphoneFriendListStatus linphone_friend_list_remove_friend(LinphoneFriendList *list, LinphoneFriend *lf); /** - * Retrieves the list of LinphoneFriend from this LinphoneFriendList. - * @param[in] list LinphoneFriendList object - * @return \bctbx_list{LinphoneFriend} a list of LinphoneFriend + * Retrieves the list of #LinphoneFriend from this LinphoneFriendList. + * @param[in] list #LinphoneFriendList object + * @return \bctbx_list{LinphoneFriend} a list of #LinphoneFriend */ LINPHONE_PUBLIC const bctbx_list_t * linphone_friend_list_get_friends(const LinphoneFriendList *list); /** * Find a friend in the friend list using a LinphoneAddress. - * @param[in] list LinphoneFriendList object. - * @param[in] address LinphoneAddress object of the friend we want to search for. - * @return A LinphoneFriend if found, NULL otherwise. + * @param[in] list #LinphoneFriendList object. + * @param[in] address #LinphoneAddress object of the friend we want to search for. + * @return A #LinphoneFriend if found, NULL otherwise. **/ LINPHONE_PUBLIC LinphoneFriend * linphone_friend_list_find_friend_by_address(const LinphoneFriendList *list, const LinphoneAddress *address); /** * Find a friend in the friend list using an URI string. - * @param[in] list LinphoneFriendList object. + * @param[in] list #LinphoneFriendList object. * @param[in] uri A string containing the URI of the friend we want to search for. - * @return A LinphoneFriend if found, NULL otherwise. + * @return A #LinphoneFriend if found, NULL otherwise. **/ LINPHONE_PUBLIC LinphoneFriend * linphone_friend_list_find_friend_by_uri(const LinphoneFriendList *list, const char *uri); /** * Find a friend in the friend list using a ref key. - * @param[in] list LinphoneFriendList object. + * @param[in] list #LinphoneFriendList object. * @param[in] ref_key The ref key string of the friend we want to search for. - * @return A LinphoneFriend if found, NULL otherwise. + * @return A #LinphoneFriend if found, NULL otherwise. **/ LINPHONE_PUBLIC LinphoneFriend * linphone_friend_list_find_friend_by_ref_key(const LinphoneFriendList *list, const char *ref_key); @@ -168,174 +168,174 @@ LINPHONE_PUBLIC void linphone_friend_list_update_subscriptions(LinphoneFriendLis /** * Notify our presence to all the friends in the friend list that have subscribed to our presence directly (not using a RLS). - * @param[in] list LinphoneFriendList object. - * @param[in] presence LinphonePresenceModel object. + * @param[in] list #LinphoneFriendList object. + * @param[in] presence #LinphonePresenceModel object. **/ LINPHONE_PUBLIC void linphone_friend_list_notify_presence(LinphoneFriendList *list, LinphonePresenceModel *presence); /** * Get the URI associated with the friend list. - * @param[in] list LinphoneFriendList object. + * @param[in] list #LinphoneFriendList object. * @return The URI associated with the friend list. **/ LINPHONE_PUBLIC const char * linphone_friend_list_get_uri(const LinphoneFriendList *list); /** * Set the URI associated with the friend list. - * @param[in] list LinphoneFriendList object. + * @param[in] list #LinphoneFriendList object. * @param[in] uri The URI to associate with the friend list. **/ LINPHONE_PUBLIC void linphone_friend_list_set_uri(LinphoneFriendList *list, const char *uri); /** * Sets the revision from the last synchronization. - * @param[in] list LinphoneFriendList object. + * @param[in] list #LinphoneFriendList object. * @param[in] rev The revision */ LINPHONE_PUBLIC void linphone_friend_list_update_revision(LinphoneFriendList *list, int rev); /** - * Get the LinphoneFriendListCbs object associated with a LinphoneFriendList. - * @param[in] list LinphoneFriendList object - * @return The LinphoneFriendListCbs object associated with the LinphoneFriendList. + * Get the #LinphoneFriendListCbs object associated with a LinphoneFriendList. + * @param[in] list #LinphoneFriendList object + * @return The #LinphoneFriendListCbs object associated with the LinphoneFriendList. **/ LINPHONE_PUBLIC LinphoneFriendListCbs * linphone_friend_list_get_callbacks(const LinphoneFriendList *list); /** - * Acquire a reference to a LinphoneFriendListCbs object. - * @param[in] cbs LinphoneFriendListCbs object. - * @return The same LinphoneFriendListCbs object. + * Acquire a reference to a #LinphoneFriendListCbs object. + * @param[in] cbs #LinphoneFriendListCbs object. + * @return The same #LinphoneFriendListCbs object. **/ LINPHONE_PUBLIC LinphoneFriendListCbs * linphone_friend_list_cbs_ref(LinphoneFriendListCbs *cbs); /** - * Release a reference to a LinphoneFriendListCbs object. - * @param[in] cbs LinphoneFriendListCbs object. + * Release a reference to a #LinphoneFriendListCbs object. + * @param[in] cbs #LinphoneFriendListCbs object. **/ LINPHONE_PUBLIC void linphone_friend_list_cbs_unref(LinphoneFriendListCbs *cbs); /** - * Retrieve the user pointer associated with a LinphoneFriendListCbs object. - * @param[in] cbs LinphoneFriendListCbs object. - * @return The user pointer associated with the LinphoneFriendListCbs object. + * Retrieve the user pointer associated with a #LinphoneFriendListCbs object. + * @param[in] cbs #LinphoneFriendListCbs object. + * @return The user pointer associated with the #LinphoneFriendListCbs object. **/ LINPHONE_PUBLIC void *linphone_friend_list_cbs_get_user_data(const LinphoneFriendListCbs *cbs); /** - * Assign a user pointer to a LinphoneFriendListCbs object. - * @param[in] cbs LinphoneFriendListCbs object. - * @param[in] ud The user pointer to associate with the LinphoneFriendListCbs object. + * Assign a user pointer to a #LinphoneFriendListCbs object. + * @param[in] cbs #LinphoneFriendListCbs object. + * @param[in] ud The user pointer to associate with the #LinphoneFriendListCbs object. **/ LINPHONE_PUBLIC void linphone_friend_list_cbs_set_user_data(LinphoneFriendListCbs *cbs, void *ud); /** * Get the contact created callback. - * @param[in] cbs LinphoneFriendListCbs object. + * @param[in] cbs #LinphoneFriendListCbs object. * @return The current contact created callback. **/ LINPHONE_PUBLIC LinphoneFriendListCbsContactCreatedCb linphone_friend_list_cbs_get_contact_created(const LinphoneFriendListCbs *cbs); /** * Set the contact created callback. - * @param[in] cbs LinphoneFriendListCbs object. + * @param[in] cbs #LinphoneFriendListCbs object. * @param[in] cb The contact created to be used. **/ LINPHONE_PUBLIC void linphone_friend_list_cbs_set_contact_created(LinphoneFriendListCbs *cbs, LinphoneFriendListCbsContactCreatedCb cb); /** * Get the contact deleted callback. - * @param[in] cbs LinphoneFriendListCbs object. + * @param[in] cbs #LinphoneFriendListCbs object. * @return The current contact deleted callback. **/ LINPHONE_PUBLIC LinphoneFriendListCbsContactDeletedCb linphone_friend_list_cbs_get_contact_deleted(const LinphoneFriendListCbs *cbs); /** * Set the contact deleted callback. - * @param[in] cbs LinphoneFriendListCbs object. + * @param[in] cbs #LinphoneFriendListCbs object. * @param[in] cb The contact deleted to be used. **/ LINPHONE_PUBLIC void linphone_friend_list_cbs_set_contact_deleted(LinphoneFriendListCbs *cbs, LinphoneFriendListCbsContactDeletedCb cb); /** * Get the contact updated callback. - * @param[in] cbs LinphoneFriendListCbs object. + * @param[in] cbs #LinphoneFriendListCbs object. * @return The current contact updated callback. **/ LINPHONE_PUBLIC LinphoneFriendListCbsContactUpdatedCb linphone_friend_list_cbs_get_contact_updated(const LinphoneFriendListCbs *cbs); /** * Set the contact updated callback. - * @param[in] cbs LinphoneFriendListCbs object. + * @param[in] cbs #LinphoneFriendListCbs object. * @param[in] cb The contact updated to be used. **/ LINPHONE_PUBLIC void linphone_friend_list_cbs_set_contact_updated(LinphoneFriendListCbs *cbs, LinphoneFriendListCbsContactUpdatedCb cb); /** * Get the sync status changed callback. - * @param[in] cbs LinphoneFriendListCbs object. + * @param[in] cbs #LinphoneFriendListCbs object. * @return The current sync status changedcallback. **/ LINPHONE_PUBLIC LinphoneFriendListCbsSyncStateChangedCb linphone_friend_list_cbs_get_sync_status_changed(const LinphoneFriendListCbs *cbs); /** * Set the contact updated callback. - * @param[in] cbs LinphoneFriendListCbs object. + * @param[in] cbs #LinphoneFriendListCbs object. * @param[in] cb The sync status changed to be used. **/ LINPHONE_PUBLIC void linphone_friend_list_cbs_set_sync_status_changed(LinphoneFriendListCbs *cbs, LinphoneFriendListCbsSyncStateChangedCb cb); /** * Starts a CardDAV synchronization using value set using linphone_friend_list_set_uri. - * @param[in] list LinphoneFriendList object. + * @param[in] list #LinphoneFriendList object. */ LINPHONE_PUBLIC void linphone_friend_list_synchronize_friends_from_server(LinphoneFriendList *list); /** - * Goes through all the LinphoneFriend that are dirty and does a CardDAV PUT to update the server. - * @param[in] list LinphoneFriendList object. + * Goes through all the #LinphoneFriend that are dirty and does a CardDAV PUT to update the server. + * @param[in] list #LinphoneFriendList object. */ LINPHONE_PUBLIC void linphone_friend_list_update_dirty_friends(LinphoneFriendList *list); /** - * Returns the LinphoneCore object attached to this LinphoneFriendList. - * @param[in] list LinphoneFriendList object. - * @return a LinphoneCore object + * Returns the #LinphoneCore object attached to this LinphoneFriendList. + * @param[in] list #LinphoneFriendList object. + * @return a #LinphoneCore object */ LINPHONE_PUBLIC LinphoneCore* linphone_friend_list_get_core(const LinphoneFriendList *list); /** - * Creates and adds LinphoneFriend objects to LinphoneFriendList from a file that contains the vCard(s) to parse - * @param[in] list the LinphoneFriendList object + * Creates and adds #LinphoneFriend objects to #LinphoneFriendList from a file that contains the vCard(s) to parse + * @param[in] list the #LinphoneFriendList object * @param[in] vcard_file the path to a file that contains the vCard(s) to parse * @return the amount of linphone friends created */ LINPHONE_PUBLIC LinphoneStatus linphone_friend_list_import_friends_from_vcard4_file(LinphoneFriendList *list, const char *vcard_file); /** - * Creates and adds LinphoneFriend objects to LinphoneFriendList from a buffer that contains the vCard(s) to parse - * @param[in] list the LinphoneFriendList object + * Creates and adds #LinphoneFriend objects to #LinphoneFriendList from a buffer that contains the vCard(s) to parse + * @param[in] list the #LinphoneFriendList object * @param[in] vcard_buffer the buffer that contains the vCard(s) to parse * @return the amount of linphone friends created */ LINPHONE_PUBLIC LinphoneStatus linphone_friend_list_import_friends_from_vcard4_buffer(LinphoneFriendList *list, const char *vcard_buffer); /** - * Creates and export LinphoneFriend objects from LinphoneFriendList to a file using vCard 4 format - * @param[in] list the LinphoneFriendList object + * Creates and export #LinphoneFriend objects from #LinphoneFriendList to a file using vCard 4 format + * @param[in] list the #LinphoneFriendList object * @param[in] vcard_file the path to a file that will contain the vCards */ LINPHONE_PUBLIC void linphone_friend_list_export_friends_as_vcard4_file(LinphoneFriendList *list, const char *vcard_file); /** * Enable subscription to NOTIFYes of all friends list - * @param[in] list the LinphoneFriendList object + * @param[in] list the #LinphoneFriendList object * @param[in] enabled should subscription be enabled or not */ LINPHONE_PUBLIC void linphone_friend_list_enable_subscriptions(LinphoneFriendList *list, bool_t enabled); /** * Gets whether subscription to NOTIFYes of all friends list are enabled or not - * @param[in] list the LinphoneFriendList object + * @param[in] list the #LinphoneFriendList object * @return Whether subscriptions are enabled or not */ LINPHONE_PUBLIC bool_t linphone_friend_list_subscriptions_enabled(LinphoneFriendList *list); diff --git a/include/linphone/headers.h b/include/linphone/headers.h index f2b20aa56..986eb90b7 100644 --- a/include/linphone/headers.h +++ b/include/linphone/headers.h @@ -46,7 +46,7 @@ LINPHONE_PUBLIC void linphone_headers_unref(LinphoneHeaders *obj); /** * Search for a given header name and return its value. - * @param obj the LinphoneHeaders object + * @param obj the #LinphoneHeaders object * @param name the header's name * @return the header's value or NULL if not found. **/ @@ -55,7 +55,7 @@ LINPHONE_PUBLIC const char* linphone_headers_get_value(LinphoneHeaders *obj, con /** * Add given header name and corresponding value. - * @param obj the LinphoneHeaders object + * @param obj the #LinphoneHeaders object * @param name the header's name * @param the header's value **/ @@ -63,7 +63,7 @@ LINPHONE_PUBLIC void linphone_headers_add(LinphoneHeaders *obj, const char *name /** * Add given header name and corresponding value. - * @param obj the LinphoneHeaders object + * @param obj the #LinphoneHeaders object * @param name the header's name * @param the header's value **/ diff --git a/include/linphone/im_encryption_engine.h b/include/linphone/im_encryption_engine.h index 2a39661a9..8a6bc53b6 100644 --- a/include/linphone/im_encryption_engine.h +++ b/include/linphone/im_encryption_engine.h @@ -33,30 +33,30 @@ extern "C" { /** * Acquire a reference to the LinphoneImEncryptionEngineCbs. - * @param[in] cbs LinphoneImEncryptionEngineCbs object. - * @return The same LinphoneImEncryptionEngineCbs object. + * @param[in] cbs #LinphoneImEncryptionEngineCbs object. + * @return The same #LinphoneImEncryptionEngineCbs object. * @donotwrap **/ LinphoneImEncryptionEngineCbs * linphone_im_encryption_engine_cbs_ref(LinphoneImEncryptionEngineCbs *cbs); /** * Release reference to the LinphoneImEncryptionEngineCbs. - * @param[in] cbs LinphoneImEncryptionEngineCbs object. + * @param[in] cbs #LinphoneImEncryptionEngineCbs object. * @donotwrap **/ void linphone_im_encryption_engine_cbs_unref(LinphoneImEncryptionEngineCbs *cbs); /** - * Gets the user data in the LinphoneImEncryptionEngineCbs object - * @param[in] cbs the LinphoneImEncryptionEngineCbs + * Gets the user data in the #LinphoneImEncryptionEngineCbs object + * @param[in] cbs the #LinphoneImEncryptionEngineCbs * @return the user data * @donotwrap */ LINPHONE_PUBLIC void *linphone_im_encryption_engine_cbs_get_user_data(const LinphoneImEncryptionEngineCbs *cbs); /** - * Sets the user data in the LinphoneImEncryptionEngineCbs object - * @param[in] cbs the LinphoneImEncryptionEngineCbs object + * Sets the user data in the #LinphoneImEncryptionEngineCbs object + * @param[in] cbs the #LinphoneImEncryptionEngineCbs object * @param[in] data the user data * @donotwrap */ @@ -64,54 +64,54 @@ LINPHONE_PUBLIC void linphone_im_encryption_engine_cbs_set_user_data(LinphoneImE /** * Acquire a reference to the LinphoneImEncryptionEngine. - * @param[in] imee LinphoneImEncryptionEngine object. - * @return The same LinphoneImEncryptionEngine object. + * @param[in] imee #LinphoneImEncryptionEngine object. + * @return The same #LinphoneImEncryptionEngine object. * @donotwrap **/ LINPHONE_PUBLIC LinphoneImEncryptionEngine * linphone_im_encryption_engine_ref(LinphoneImEncryptionEngine *imee); /** * Release reference to the LinphoneImEncryptionEngine. - * @param[in] imee LinphoneImEncryptionEngine object. + * @param[in] imee #LinphoneImEncryptionEngine object. * @donotwrap **/ LINPHONE_PUBLIC void linphone_im_encryption_engine_unref(LinphoneImEncryptionEngine *imee); /** - * Gets the user data in the LinphoneImEncryptionEngine object - * @param[in] imee the LinphoneImEncryptionEngine + * Gets the user data in the #LinphoneImEncryptionEngine object + * @param[in] imee the #LinphoneImEncryptionEngine * @return the user data * @donotwrap */ LINPHONE_PUBLIC void *linphone_im_encryption_engine_get_user_data(const LinphoneImEncryptionEngine *imee); /** - * Sets the user data in the LinphoneImEncryptionEngine object - * @param[in] imee the LinphoneImEncryptionEngine object + * Sets the user data in the #LinphoneImEncryptionEngine object + * @param[in] imee the #LinphoneImEncryptionEngine object * @param[in] data the user data * @donotwrap */ LINPHONE_PUBLIC void linphone_im_encryption_engine_set_user_data(LinphoneImEncryptionEngine *imee, void *data); /** - * Gets the LinphoneCore object that created the IM encryption engine - * @param[in] imee LinphoneImEncryptionEngine object - * @return The LinphoneCore object that created the IM encryption engine + * Gets the #LinphoneCore object that created the IM encryption engine + * @param[in] imee #LinphoneImEncryptionEngine object + * @return The #LinphoneCore object that created the IM encryption engine * @donotwrap */ LINPHONE_PUBLIC LinphoneCore * linphone_im_encryption_engine_get_core(LinphoneImEncryptionEngine *imee); /** - * Gets the LinphoneImEncryptionEngineCbs object that holds the callbacks - * @param[in] imee the LinphoneImEncryptionEngine object - * @return the LinphoneImEncryptionEngineCbs object + * Gets the #LinphoneImEncryptionEngineCbs object that holds the callbacks + * @param[in] imee the #LinphoneImEncryptionEngine object + * @return the #LinphoneImEncryptionEngineCbs object * @donotwrap */ LINPHONE_PUBLIC LinphoneImEncryptionEngineCbs* linphone_im_encryption_engine_get_callbacks(const LinphoneImEncryptionEngine *imee); /** * Gets the callback that will decrypt the chat messages upon reception - * @param[in] cbs the LinphoneImEncryptionEngineCbs object + * @param[in] cbs the #LinphoneImEncryptionEngineCbs object * @return the callback * @donotwrap */ @@ -119,7 +119,7 @@ LINPHONE_PUBLIC LinphoneImEncryptionEngineCbsIncomingMessageCb linphone_im_encry /** * Sets the callback that will decrypt the chat messages upon reception - * @param[in] cbs the LinphoneImEncryptionEngineCbs object + * @param[in] cbs the #LinphoneImEncryptionEngineCbs object * @param[in] cb the callback to call * @donotwrap */ @@ -127,7 +127,7 @@ LINPHONE_PUBLIC void linphone_im_encryption_engine_cbs_set_process_incoming_mess /** * Gets the callback that will encrypt the chat messages before sending them - * @param[in] cbs the LinphoneImEncryptionEngineCbs object + * @param[in] cbs the #LinphoneImEncryptionEngineCbs object * @return the callback * @donotwrap */ @@ -135,7 +135,7 @@ LINPHONE_PUBLIC LinphoneImEncryptionEngineCbsOutgoingMessageCb linphone_im_encry /** * Sets the callback that will encrypt the chat messages before sending them - * @param[in] cbs the LinphoneImEncryptionEngineCbs object + * @param[in] cbs the #LinphoneImEncryptionEngineCbs object * @param[in] cb the callback to call * @donotwrap */ @@ -143,7 +143,7 @@ LINPHONE_PUBLIC void linphone_im_encryption_engine_cbs_set_process_outgoing_mess /** * Gets the callback that will decrypt the files while downloading them - * @param[in] cbs the LinphoneImEncryptionEngineCbs object + * @param[in] cbs the #LinphoneImEncryptionEngineCbs object * @return the callback * @donotwrap */ @@ -151,7 +151,7 @@ LINPHONE_PUBLIC LinphoneImEncryptionEngineCbsDownloadingFileCb linphone_im_encry /** * Sets the callback that will decrypt the files while downloading them - * @param[in] cbs the LinphoneImEncryptionEngineCbs object + * @param[in] cbs the #LinphoneImEncryptionEngineCbs object * @param[in] cb the callback to call * @donotwrap */ @@ -159,7 +159,7 @@ LINPHONE_PUBLIC void linphone_im_encryption_engine_cbs_set_process_downloading_f /** * Gets the callback that will will encrypt the files while uploading them - * @param[in] cbs the LinphoneImEncryptionEngineCbs object + * @param[in] cbs the #LinphoneImEncryptionEngineCbs object * @return the callback * @donotwrap */ @@ -167,7 +167,7 @@ LINPHONE_PUBLIC LinphoneImEncryptionEngineCbsUploadingFileCb linphone_im_encrypt /** * Sets the callback that will encrypt the files while uploading them - * @param[in] cbs the LinphoneImEncryptionEngineCbs object + * @param[in] cbs the #LinphoneImEncryptionEngineCbs object * @param[in] cb the callback to call * @donotwrap */ @@ -175,7 +175,7 @@ LINPHONE_PUBLIC void linphone_im_encryption_engine_cbs_set_process_uploading_fil /** * Gets the callback telling wheter or not to encrypt the files - * @param[in] cbs the LinphoneImEncryptionEngineCbs object + * @param[in] cbs the #LinphoneImEncryptionEngineCbs object * @return the callback * @donotwrap */ @@ -183,7 +183,7 @@ LINPHONE_PUBLIC LinphoneImEncryptionEngineCbsIsEncryptionEnabledForFileTransferC /** * Sets the callback telling wheter or not to encrypt the files - * @param[in] cbs the LinphoneImEncryptionEngineCbs object + * @param[in] cbs the #LinphoneImEncryptionEngineCbs object * @param[in] cb the callback to call * @donotwrap */ @@ -191,7 +191,7 @@ LINPHONE_PUBLIC void linphone_im_encryption_engine_cbs_set_is_encryption_enabled /** * Gets the callback that will generate the key to encrypt the file before uploading it - * @param[in] cbs the LinphoneImEncryptionEngineCbs object + * @param[in] cbs the #LinphoneImEncryptionEngineCbs object * @return the callback * @donotwrap */ @@ -199,14 +199,14 @@ LINPHONE_PUBLIC LinphoneImEncryptionEngineCbsGenerateFileTransferKeyCb linphone_ /** * Sets the callback that will generate the key to encrypt the file before uploading it - * @param[in] cbs the LinphoneImEncryptionEngineCbs object + * @param[in] cbs the #LinphoneImEncryptionEngineCbs object * @param[in] cb the callback to call * @donotwrap */ LINPHONE_PUBLIC void linphone_im_encryption_engine_cbs_set_generate_file_transfer_key(LinphoneImEncryptionEngineCbs *cbs, LinphoneImEncryptionEngineCbsGenerateFileTransferKeyCb cb); /** Set a chat message text to be sent by #linphone_chat_room_send_message - * @param[in] msg LinphoneChatMessage + * @param[in] msg #LinphoneChatMessage * @param[in] text Const char * * @returns 0 if succeed. * @donotwrap diff --git a/include/linphone/im_notif_policy.h b/include/linphone/im_notif_policy.h index ee2c1a5a3..33aba022d 100644 --- a/include/linphone/im_notif_policy.h +++ b/include/linphone/im_notif_policy.h @@ -35,124 +35,124 @@ extern "C" { */ /** - * Acquire a reference to the LinphoneImNotifPolicy object. - * @param[in] policy LinphoneImNotifPolicy object. - * @return The same LinphoneImNotifPolicy object. + * Acquire a reference to the #LinphoneImNotifPolicy object. + * @param[in] policy #LinphoneImNotifPolicy object. + * @return The same #LinphoneImNotifPolicy object. **/ LINPHONE_PUBLIC LinphoneImNotifPolicy * linphone_im_notif_policy_ref(LinphoneImNotifPolicy *policy); /** - * Release reference to the LinphoneImNotifPolicy object. - * @param[in] policy LinphoneImNotifPolicy object. + * Release reference to the #LinphoneImNotifPolicy object. + * @param[in] policy #LinphoneImNotifPolicy object. **/ LINPHONE_PUBLIC void linphone_im_notif_policy_unref(LinphoneImNotifPolicy *policy); /** - * Retrieve the user pointer associated with the LinphoneImNotifPolicy object. - * @param[in] policy LinphoneImNotifPolicy object. - * @return The user pointer associated with the LinphoneImNotifPolicy object. + * Retrieve the user pointer associated with the #LinphoneImNotifPolicy object. + * @param[in] policy #LinphoneImNotifPolicy object. + * @return The user pointer associated with the #LinphoneImNotifPolicy object. **/ LINPHONE_PUBLIC void *linphone_im_notif_policy_get_user_data(const LinphoneImNotifPolicy *policy); /** - * Assign a user pointer to the LinphoneImNotifPolicy object. - * @param[in] policy LinphoneImNotifPolicy object. - * @param[in] ud The user pointer to associate with the LinphoneImNotifPolicy object. + * Assign a user pointer to the #LinphoneImNotifPolicy object. + * @param[in] policy #LinphoneImNotifPolicy object. + * @param[in] ud The user pointer to associate with the #LinphoneImNotifPolicy object. **/ LINPHONE_PUBLIC void linphone_im_notif_policy_set_user_data(LinphoneImNotifPolicy *policy, void *ud); /** * Clear an IM notif policy (deactivate all receiving and sending of notifications). - * @param[in] policy LinphoneImNotifPolicy object. + * @param[in] policy #LinphoneImNotifPolicy object. */ LINPHONE_PUBLIC void linphone_im_notif_policy_clear(LinphoneImNotifPolicy *policy); /** * Enable all receiving and sending of notifications. - * @param[in] policy LinphoneImNotifPolicy object. + * @param[in] policy #LinphoneImNotifPolicy object. */ LINPHONE_PUBLIC void linphone_im_notif_policy_enable_all(LinphoneImNotifPolicy *policy); /** * Tell whether is_composing notifications are being sent. - * @param[in] policy LinphoneImNotifPolicy object + * @param[in] policy #LinphoneImNotifPolicy object * @return Boolean value telling whether is_composing notifications are being sent. */ LINPHONE_PUBLIC bool_t linphone_im_notif_policy_get_send_is_composing(const LinphoneImNotifPolicy *policy); /** * Enable is_composing notifications sending. - * @param[in] policy LinphoneImNotifPolicy object + * @param[in] policy #LinphoneImNotifPolicy object * @param[in] enable Boolean value telling whether to send is_composing notifications. */ LINPHONE_PUBLIC void linphone_im_notif_policy_set_send_is_composing(LinphoneImNotifPolicy *policy, bool_t enable); /** * Tell whether is_composing notifications are being notified when received. - * @param[in] policy LinphoneImNotifPolicy object + * @param[in] policy #LinphoneImNotifPolicy object * @return Boolean value telling whether is_composing notifications are being notified when received. */ LINPHONE_PUBLIC bool_t linphone_im_notif_policy_get_recv_is_composing(const LinphoneImNotifPolicy *policy); /** * Enable is_composing notifications receiving. - * @param[in] policy LinphoneImNotifPolicy object + * @param[in] policy #LinphoneImNotifPolicy object * @param[in] enable Boolean value telling whether to notify received is_composing notifications. */ LINPHONE_PUBLIC void linphone_im_notif_policy_set_recv_is_composing(LinphoneImNotifPolicy *policy, bool_t enable); /** * Tell whether imdn delivered notifications are being sent. - * @param[in] policy LinphoneImNotifPolicy object + * @param[in] policy #LinphoneImNotifPolicy object * @return Boolean value telling whether imdn delivered notifications are being sent. */ LINPHONE_PUBLIC bool_t linphone_im_notif_policy_get_send_imdn_delivered(const LinphoneImNotifPolicy *policy); /** * Enable imdn delivered notifications sending. - * @param[in] policy LinphoneImNotifPolicy object + * @param[in] policy #LinphoneImNotifPolicy object * @param[in] enable Boolean value telling whether to send imdn delivered notifications. */ LINPHONE_PUBLIC void linphone_im_notif_policy_set_send_imdn_delivered(LinphoneImNotifPolicy *policy, bool_t enable); /** * Tell whether imdn delivered notifications are being notified when received. - * @param[in] policy LinphoneImNotifPolicy object + * @param[in] policy #LinphoneImNotifPolicy object * @return Boolean value telling whether imdn delivered notifications are being notified when received. */ LINPHONE_PUBLIC bool_t linphone_im_notif_policy_get_recv_imdn_delivered(const LinphoneImNotifPolicy *policy); /** * Enable imdn delivered notifications receiving. - * @param[in] policy LinphoneImNotifPolicy object + * @param[in] policy #LinphoneImNotifPolicy object * @param[in] enable Boolean value telling whether to notify received imdn delivered notifications. */ LINPHONE_PUBLIC void linphone_im_notif_policy_set_recv_imdn_delivered(LinphoneImNotifPolicy *policy, bool_t enable); /** * Tell whether imdn displayed notifications are being sent. - * @param[in] policy LinphoneImNotifPolicy object + * @param[in] policy #LinphoneImNotifPolicy object * @return Boolean value telling whether imdn displayed notifications are being sent. */ LINPHONE_PUBLIC bool_t linphone_im_notif_policy_get_send_imdn_displayed(const LinphoneImNotifPolicy *policy); /** * Enable imdn displayed notifications sending. - * @param[in] policy LinphoneImNotifPolicy object + * @param[in] policy #LinphoneImNotifPolicy object * @param[in] enable Boolean value telling whether to send imdn displayed notifications. */ LINPHONE_PUBLIC void linphone_im_notif_policy_set_send_imdn_displayed(LinphoneImNotifPolicy *policy, bool_t enable); /** * Tell whether imdn displayed notifications are being notified when received. - * @param[in] policy LinphoneImNotifPolicy object + * @param[in] policy #LinphoneImNotifPolicy object * @return Boolean value telling whether imdn displayed notifications are being notified when received. */ LINPHONE_PUBLIC bool_t linphone_im_notif_policy_get_recv_imdn_displayed(const LinphoneImNotifPolicy *policy); /** * Enable imdn displayed notifications receiving. - * @param[in] policy LinphoneImNotifPolicy object + * @param[in] policy #LinphoneImNotifPolicy object * @param[in] enable Boolean value telling whether to notify received imdn displayed notifications. */ LINPHONE_PUBLIC void linphone_im_notif_policy_set_recv_imdn_displayed(LinphoneImNotifPolicy *policy, bool_t enable); diff --git a/include/linphone/info_message.h b/include/linphone/info_message.h index 268fb124c..99804bb14 100644 --- a/include/linphone/info_message.h +++ b/include/linphone/info_message.h @@ -55,7 +55,7 @@ LINPHONE_PUBLIC const char *linphone_info_message_get_header(const LinphoneInfoM * Assign a content to the info message. * @param im the linphone info message * @param content the content described as a #LinphoneContent structure. - * All fields of the LinphoneContent are copied, thus the application can destroy/modify/recycloe the content object freely ater the function returns. + * All fields of the #LinphoneContent are copied, thus the application can destroy/modify/recycloe the content object freely ater the function returns. **/ LINPHONE_PUBLIC void linphone_info_message_set_content(LinphoneInfoMessage *im, const LinphoneContent *content); diff --git a/include/linphone/lpconfig.h b/include/linphone/lpconfig.h index 816e2805c..4fa5f681b 100644 --- a/include/linphone/lpconfig.h +++ b/include/linphone/lpconfig.h @@ -33,7 +33,7 @@ */ /** - * Safely downcast a belle_sip_object into LinphoneConfig + * Safely downcast a belle_sip_object into #LinphoneConfig */ #define LINPHONE_CONFIG(obj) BELLE_SIP_CAST(obj, LinphoneConfig); @@ -42,59 +42,59 @@ extern "C" { #endif /** - * Instantiates a LinphoneConfig object from a user config file. + * Instantiates a #LinphoneConfig object from a user config file. * The caller of this constructor owns a reference. linphone_config_unref() must be called when this object is no longer needed. * @ingroup misc - * @param filename the filename of the config file to read to fill the instantiated LinphoneConfig + * @param filename the filename of the config file to read to fill the instantiated #LinphoneConfig * @see linphone_config_new_with_factory */ LINPHONE_PUBLIC LinphoneConfig * linphone_config_new(const char *filename); /** - * Instantiates a LinphoneConfig object from a user provided buffer. + * Instantiates a #LinphoneConfig object from a user provided buffer. * The caller of this constructor owns a reference. linphone_config_unref() must be called when this object is no longer needed. * @ingroup misc - * @param buffer the buffer from which the LinphoneConfig will be retrieved. We expect the buffer to be null-terminated. + * @param buffer the buffer from which the #LinphoneConfig will be retrieved. We expect the buffer to be null-terminated. * @see linphone_config_new_with_factory * @see linphone_config_new */ LINPHONE_PUBLIC LinphoneConfig * linphone_config_new_from_buffer(const char *buffer); /** - * Instantiates a LinphoneConfig object from a user config file and a factory config file. + * Instantiates a #LinphoneConfig object from a user config file and a factory config file. * The caller of this constructor owns a reference. linphone_config_unref() must be called when this object is no longer needed. * @ingroup misc - * @param config_filename the filename of the user config file to read to fill the instantiated LinphoneConfig - * @param factory_config_filename the filename of the factory config file to read to fill the instantiated LinphoneConfig + * @param config_filename the filename of the user config file to read to fill the instantiated #LinphoneConfig + * @param factory_config_filename the filename of the factory config file to read to fill the instantiated #LinphoneConfig * @see linphone_config_new * - * The user config file is read first to fill the LinphoneConfig and then the factory config file is read. + * The user config file is read first to fill the #LinphoneConfig and then the factory config file is read. * Therefore the configuration parameters defined in the user config file will be overwritten by the parameters * defined in the factory config file. */ LINPHONE_PUBLIC LinphoneConfig * linphone_config_new_with_factory(const char *config_filename, const char *factory_config_filename); /** - * Reads a user config file and fill the LinphoneConfig with the read config values. + * Reads a user config file and fill the #LinphoneConfig with the read config values. * @ingroup misc - * @param lpconfig The LinphoneConfig object to fill with the content of the file - * @param filename The filename of the config file to read to fill the LinphoneConfig + * @param lpconfig The #LinphoneConfig object to fill with the content of the file + * @param filename The filename of the config file to read to fill the #LinphoneConfig */ LINPHONE_PUBLIC LinphoneStatus linphone_config_read_file(LinphoneConfig *lpconfig, const char *filename); /** - * Reads a xml config file and fill the LinphoneConfig with the read config dynamic values. + * Reads a xml config file and fill the #LinphoneConfig with the read config dynamic values. * @ingroup misc - * @param lpconfig The LinphoneConfig object to fill with the content of the file - * @param filename The filename of the config file to read to fill the LinphoneConfig + * @param lpconfig The #LinphoneConfig object to fill with the content of the file + * @param filename The filename of the config file to read to fill the #LinphoneConfig */ LINPHONE_PUBLIC const char* linphone_config_load_from_xml_file(LinphoneConfig *lpc, const char *filename); /** - * Reads a xml config string and fill the LinphoneConfig with the read config dynamic values. + * Reads a xml config string and fill the #LinphoneConfig with the read config dynamic values. * @ingroup misc - * @param lpconfig The LinphoneConfig object to fill with the content of the file - * @param buffer The string of the config file to fill the LinphoneConfig + * @param lpconfig The #LinphoneConfig object to fill with the content of the file + * @param buffer The string of the config file to fill the #LinphoneConfig * @return 0 in case of success */ LINPHONE_PUBLIC LinphoneStatus linphone_config_load_from_xml_string(LpConfig *lpc, const char *buffer); @@ -214,7 +214,7 @@ LINPHONE_PUBLIC void linphone_config_clean_section(LinphoneConfig *lpconfig, con /** * Returns 1 if a given section with a given key is present in the configuration. - * @param[in] lpconfig The LinphoneConfig object + * @param[in] lpconfig The #LinphoneConfig object * @param[in] section * @param[in] key **/ @@ -222,7 +222,7 @@ LINPHONE_PUBLIC int linphone_config_has_entry(const LinphoneConfig *lpconfig, co /** * Removes entries for key,value in a section. - * @param[in] lpconfig The LinphoneConfig object + * @param[in] lpconfig The #LinphoneConfig object * @param[in] section * @param[in] key **/ @@ -230,7 +230,7 @@ LINPHONE_PUBLIC void linphone_config_clean_entry(LinphoneConfig *lpconfig, const /** * Returns the list of sections' names in the LinphoneConfig. - * @param[in] lpconfig The LinphoneConfig object + * @param[in] lpconfig The #LinphoneConfig object * @return a null terminated static array of strings * @deprecated use linphone_config_get_sections_names_list instead * @donotwrap @@ -239,7 +239,7 @@ LINPHONE_PUBLIC const char** linphone_config_get_sections_names(LinphoneConfig * /** * Returns the list of sections' names in the LinphoneConfig. - * @param[in] lpconfig The LinphoneConfig object + * @param[in] lpconfig The #LinphoneConfig object * @return \bctbx_list{char *} a null terminated static array of strings **/ LINPHONE_PUBLIC const bctbx_list_t * linphone_config_get_sections_names_list(LpConfig *lpconfig); @@ -303,7 +303,7 @@ LINPHONE_PUBLIC void linphone_config_unref(LinphoneConfig *lpconfig); /** * Write a string in a file placed relatively with the Linphone configuration file. - * @param lpconfig LinphoneConfig instance used as a reference + * @param lpconfig #LinphoneConfig instance used as a reference * @param filename Name of the file where to write data. The name is relative to the place of the config file * @param data String to write */ @@ -311,7 +311,7 @@ LINPHONE_PUBLIC void linphone_config_write_relative_file(const LinphoneConfig *l /** * Read a string from a file placed beside the Linphone configuration file - * @param lpconfig LinphoneConfig instance used as a reference + * @param lpconfig #LinphoneConfig instance used as a reference * @param filename Name of the file where data will be read from. The name is relative to the place of the config file * @param data Buffer where read string will be stored * @param max_length Length of the buffer @@ -326,15 +326,15 @@ LINPHONE_PUBLIC LinphoneStatus linphone_config_read_relative_file(const Linphone LINPHONE_PUBLIC bool_t linphone_config_relative_file_exists(const LinphoneConfig *lpconfig, const char *filename); /** - * Dumps the LinphoneConfig as XML into a buffer - * @param[in] lpconfig The LinphoneConfig object + * Dumps the #LinphoneConfig as XML into a buffer + * @param[in] lpconfig The #LinphoneConfig object * @return The buffer that contains the XML dump **/ LINPHONE_PUBLIC char* linphone_config_dump_as_xml(const LinphoneConfig *lpconfig); /** - * Dumps the LinphoneConfig as INI into a buffer - * @param[in] lpconfig The LinphoneConfig object + * Dumps the #LinphoneConfig as INI into a buffer + * @param[in] lpconfig The #LinphoneConfig object * @return The buffer that contains the config dump **/ LINPHONE_PUBLIC char* linphone_config_dump(const LinphoneConfig *lpconfig); diff --git a/include/linphone/misc.h b/include/linphone/misc.h index 8db519284..e95ce1252 100644 --- a/include/linphone/misc.h +++ b/include/linphone/misc.h @@ -102,9 +102,9 @@ LINPHONE_PUBLIC const char *linphone_configuring_state_to_string(LinphoneConfigu LINPHONE_PUBLIC const char* linphone_chat_message_state_to_string(const LinphoneChatMessageState state); /** - * Converts a LinphoneReason enum to a string. + * Converts a #LinphoneReason enum to a string. * @param[in] err A #LinphoneReason - * @return The string representation of the specified LinphoneReason + * @return The string representation of the specified #LinphoneReason * @ingroup misc **/ LINPHONE_PUBLIC const char *linphone_reason_to_string(LinphoneReason err); @@ -118,10 +118,10 @@ LINPHONE_PUBLIC const char *linphone_reason_to_string(LinphoneReason err); LINPHONE_PUBLIC LINPHONE_DEPRECATED const char *linphone_online_status_to_string(LinphoneOnlineStatus ss); /** - * Convert a string into LinphoneTunnelMode enum + * Convert a string into #LinphoneTunnelMode enum * @param string String to convert - * @return An LinphoneTunnelMode enum. If the passed string is NULL or - * does not match with any mode, the LinphoneTunnelModeDisable is returned. + * @return An #LinphoneTunnelMode enum. If the passed string is NULL or + * does not match with any mode, the #LinphoneTunnelModeDisable is returned. */ LINPHONE_PUBLIC LinphoneTunnelMode linphone_tunnel_mode_from_string(const char *string); @@ -139,59 +139,59 @@ LINPHONE_PUBLIC const char *linphone_tunnel_mode_to_string(LinphoneTunnelMode mo LINPHONE_PUBLIC bool_t linphone_local_player_matroska_supported(void); /** - * Converts a LinphoneTransportType enum to a lowercase string. + * Converts a #LinphoneTransportType enum to a lowercase string. * @ingroup misc **/ LINPHONE_PUBLIC const char* linphone_transport_to_string(LinphoneTransportType transport); /** - * Converts a lowercase string to a LinphoneTransportType enum. + * Converts a lowercase string to a #LinphoneTransportType enum. * @ingroup misc - * @return Transport matching input, or LinphoneTransportUdp if nothing is found + * @return Transport matching input, or #LinphoneTransportUdp if nothing is found **/ LINPHONE_PUBLIC LinphoneTransportType linphone_transport_parse(const char* transport); /** * Converts an error code to a LinphoneReason. * @param[in] err An error code - * @return The LinphoneReason corresponding to the specified error code + * @return The #LinphoneReason corresponding to the specified error code * @ingroup misc **/ LINPHONE_PUBLIC LinphoneReason linphone_error_code_to_reason(int err); /** - * Converts a LinphoneReason to an error code. - * @param[in] reason A LinphoneReason - * @return The error code corresponding to the specified LinphoneReason + * Converts a #LinphoneReason to an error code. + * @param[in] reason A #LinphoneReason + * @return The error code corresponding to the specified #LinphoneReason * @ingroup misc */ LINPHONE_PUBLIC int linphone_reason_to_error_code(LinphoneReason reason); /** * Increment refcount. - * @param[in] range LinphoneRange object + * @param[in] range #LinphoneRange object * @ingroup misc **/ LINPHONE_PUBLIC LinphoneRange *linphone_range_ref(LinphoneRange *range); /** * Decrement refcount and possibly free the object. - * @param[in] range LinphoneRange object + * @param[in] range #LinphoneRange object * @ingroup misc **/ LINPHONE_PUBLIC void linphone_range_unref(LinphoneRange *range); /** - * Gets the user data in the LinphoneRange object - * @param[in] range the LinphoneRange + * Gets the user data in the #LinphoneRange object + * @param[in] range the #LinphoneRange * @return the user data * @ingroup misc */ LINPHONE_PUBLIC void *linphone_range_get_user_data(const LinphoneRange *range); /** - * Sets the user data in the LinphoneRange object - * @param[in] range the LinphoneRange object + * Sets the user data in the #LinphoneRange object + * @param[in] range the #LinphoneRange object * @param[in] data the user data * @ingroup misc */ @@ -199,7 +199,7 @@ LINPHONE_PUBLIC void linphone_range_set_user_data(LinphoneRange *range, void *da /** * Gets the lower value of the range - * @param[in] range a LinphoneRange + * @param[in] range a #LinphoneRange * @return The lower value * @ingroup misc */ @@ -207,7 +207,7 @@ LINPHONE_PUBLIC int linphone_range_get_min(const LinphoneRange *range); /** * Gets the higher value of the range - * @param[in] range a LinphoneRange + * @param[in] range a #LinphoneRange * @return The higher value * @ingroup misc */ @@ -215,7 +215,7 @@ LINPHONE_PUBLIC int linphone_range_get_max(const LinphoneRange *range); /** * Sets the lower value of the range - * @param[in] range a LinphoneRange + * @param[in] range a #LinphoneRange * @param[in] min the value to set * @ingroup misc */ @@ -223,7 +223,7 @@ LINPHONE_PUBLIC void linphone_range_set_min(LinphoneRange *range, int min); /** * Sets the higher value of the range - * @param[in] range a LinphoneRange + * @param[in] range a #LinphoneRange * @param[in] max the value to set * @ingroup misc */ diff --git a/include/linphone/nat_policy.h b/include/linphone/nat_policy.h index c6dcd97d9..cf275c65a 100644 --- a/include/linphone/nat_policy.h +++ b/include/linphone/nat_policy.h @@ -35,41 +35,41 @@ extern "C" { */ /** - * Acquire a reference to the LinphoneNatPolicy object. - * @param[in] policy LinphoneNatPolicy object. - * @return The same LinphoneNatPolicy object. + * Acquire a reference to the #LinphoneNatPolicy object. + * @param[in] policy #LinphoneNatPolicy object. + * @return The same #LinphoneNatPolicy object. **/ LINPHONE_PUBLIC LinphoneNatPolicy * linphone_nat_policy_ref(LinphoneNatPolicy *policy); /** - * Release reference to the LinphoneNatPolicy object. - * @param[in] policy LinphoneNatPolicy object. + * Release reference to the #LinphoneNatPolicy object. + * @param[in] policy #LinphoneNatPolicy object. **/ LINPHONE_PUBLIC void linphone_nat_policy_unref(LinphoneNatPolicy *policy); /** - * Retrieve the user pointer associated with the LinphoneNatPolicy object. - * @param[in] policy LinphoneNatPolicy object. - * @return The user pointer associated with the LinphoneNatPolicy object. + * Retrieve the user pointer associated with the #LinphoneNatPolicy object. + * @param[in] policy #LinphoneNatPolicy object. + * @return The user pointer associated with the #LinphoneNatPolicy object. **/ LINPHONE_PUBLIC void *linphone_nat_policy_get_user_data(const LinphoneNatPolicy *policy); /** - * Assign a user pointer to the LinphoneNatPolicy object. - * @param[in] policy LinphoneNatPolicy object. - * @param[in] ud The user pointer to associate with the LinphoneNatPolicy object. + * Assign a user pointer to the #LinphoneNatPolicy object. + * @param[in] policy #LinphoneNatPolicy object. + * @param[in] ud The user pointer to associate with the #LinphoneNatPolicy object. **/ LINPHONE_PUBLIC void linphone_nat_policy_set_user_data(LinphoneNatPolicy *policy, void *ud); /** * Clear a NAT policy (deactivate all protocols and unset the STUN server). - * @param[in] policy LinphoneNatPolicy object. + * @param[in] policy #LinphoneNatPolicy object. */ LINPHONE_PUBLIC void linphone_nat_policy_clear(LinphoneNatPolicy *policy); /** * Tell whether STUN is enabled. - * @param[in] policy LinphoneNatPolicy object + * @param[in] policy #LinphoneNatPolicy object * @return Boolean value telling whether STUN is enabled. */ LINPHONE_PUBLIC bool_t linphone_nat_policy_stun_enabled(const LinphoneNatPolicy *policy); @@ -77,14 +77,14 @@ LINPHONE_PUBLIC bool_t linphone_nat_policy_stun_enabled(const LinphoneNatPolicy /** * Enable STUN. * If TURN is also enabled, TURN will be used instead of STUN. - * @param[in] policy LinphoneNatPolicy object + * @param[in] policy #LinphoneNatPolicy object * @param[in] enable Boolean value telling whether to enable STUN. */ LINPHONE_PUBLIC void linphone_nat_policy_enable_stun(LinphoneNatPolicy *policy, bool_t enable); /** * Tell whether TURN is enabled. - * @param[in] policy LinphoneNatPolicy object + * @param[in] policy #LinphoneNatPolicy object * @return Boolean value telling whether TURN is enabled. */ LINPHONE_PUBLIC bool_t linphone_nat_policy_turn_enabled(const LinphoneNatPolicy *policy); @@ -92,14 +92,14 @@ LINPHONE_PUBLIC bool_t linphone_nat_policy_turn_enabled(const LinphoneNatPolicy /** * Enable TURN. * If STUN is also enabled, it is ignored and TURN is used. - * @param[in] policy LinphoneNatPolicy object + * @param[in] policy #LinphoneNatPolicy object * @param[in] enable Boolean value telling whether to enable TURN. */ LINPHONE_PUBLIC void linphone_nat_policy_enable_turn(LinphoneNatPolicy *policy, bool_t enable); /** * Tell whether ICE is enabled. - * @param[in] policy LinphoneNatPolicy object + * @param[in] policy #LinphoneNatPolicy object * @return Boolean value telling whether ICE is enabled. */ LINPHONE_PUBLIC bool_t linphone_nat_policy_ice_enabled(const LinphoneNatPolicy *policy); @@ -107,14 +107,14 @@ LINPHONE_PUBLIC bool_t linphone_nat_policy_ice_enabled(const LinphoneNatPolicy * /** * Enable ICE. * ICE can be enabled without STUN/TURN, in which case only the local candidates will be used. - * @param[in] policy LinphoneNatPolicy object + * @param[in] policy #LinphoneNatPolicy object * @param[in] enable Boolean value telling whether to enable ICE. */ LINPHONE_PUBLIC void linphone_nat_policy_enable_ice(LinphoneNatPolicy *policy, bool_t enable); /** * Tell whether uPnP is enabled. - * @param[in] policy LinphoneNatPolicy object + * @param[in] policy #LinphoneNatPolicy object * @return Boolean value telling whether uPnP is enabled. */ LINPHONE_PUBLIC bool_t linphone_nat_policy_upnp_enabled(const LinphoneNatPolicy *policy); @@ -122,7 +122,7 @@ LINPHONE_PUBLIC bool_t linphone_nat_policy_upnp_enabled(const LinphoneNatPolicy /** * Enable uPnP. * This has the effect to disable every other policies (ICE, STUN and TURN). - * @param[in] policy LinphoneNatPolicy object + * @param[in] policy #LinphoneNatPolicy object * @param[in] enable Boolean value telling whether to enable uPnP. */ LINPHONE_PUBLIC void linphone_nat_policy_enable_upnp(LinphoneNatPolicy *policy, bool_t enable); @@ -130,7 +130,7 @@ LINPHONE_PUBLIC void linphone_nat_policy_enable_upnp(LinphoneNatPolicy *policy, /** * Get the STUN/TURN server to use with this NAT policy. * Used when STUN or TURN are enabled. - * @param[in] policy LinphoneNatPolicy object + * @param[in] policy #LinphoneNatPolicy object * @return The STUN server used by this NAT policy. */ LINPHONE_PUBLIC const char * linphone_nat_policy_get_stun_server(const LinphoneNatPolicy *policy); @@ -138,47 +138,47 @@ LINPHONE_PUBLIC const char * linphone_nat_policy_get_stun_server(const LinphoneN /** * Set the STUN/TURN server to use with this NAT policy. * Used when STUN or TURN are enabled. - * @param[in] policy LinphoneNatPolicy object + * @param[in] policy #LinphoneNatPolicy object * @param[in] stun_server The STUN server to use with this NAT policy. */ LINPHONE_PUBLIC void linphone_nat_policy_set_stun_server(LinphoneNatPolicy *policy, const char *stun_server); /** * Get the username used to authenticate with the STUN/TURN server. - * The authentication will search for a LinphoneAuthInfo with this username. - * If it is not set the username of the currently used LinphoneProxyConfig is used to search for a LinphoneAuthInfo. - * @param[in] policy LinphoneNatPolicy object + * The authentication will search for a #LinphoneAuthInfo with this username. + * If it is not set the username of the currently used #LinphoneProxyConfig is used to search for a LinphoneAuthInfo. + * @param[in] policy #LinphoneNatPolicy object * @return The username used to authenticate with the STUN/TURN server. */ LINPHONE_PUBLIC const char * linphone_nat_policy_get_stun_server_username(const LinphoneNatPolicy *policy); /** * Set the username used to authenticate with the STUN/TURN server. - * The authentication will search for a LinphoneAuthInfo with this username. - * If it is not set the username of the currently used LinphoneProxyConfig is used to search for a LinphoneAuthInfo. - * @param[in] policy LinphoneNatPolicy object + * The authentication will search for a #LinphoneAuthInfo with this username. + * If it is not set the username of the currently used #LinphoneProxyConfig is used to search for a LinphoneAuthInfo. + * @param[in] policy #LinphoneNatPolicy object * @param[in] username The username used to authenticate with the STUN/TURN server. */ LINPHONE_PUBLIC void linphone_nat_policy_set_stun_server_username(LinphoneNatPolicy *policy, const char *username); /** * Start a STUN server DNS resolution. - * @param[in] policy LinphoneNatPolicy object + * @param[in] policy #LinphoneNatPolicy object */ LINPHONE_PUBLIC void linphone_nat_policy_resolve_stun_server(LinphoneNatPolicy *policy); /** * Get the addrinfo representation of the STUN server address. * WARNING: This function may block for up to 1 second. - * @param[in] policy LinphoneNatPolicy object + * @param[in] policy #LinphoneNatPolicy object * @return addrinfo representation of the STUN server address. * @donotwrap */ LINPHONE_PUBLIC const struct addrinfo * linphone_nat_policy_get_stun_server_addrinfo(LinphoneNatPolicy *policy); /** - * Returns the LinphoneCore object managing this nat policy, if any. - * @param[in] fr LinphoneNatPolicy object + * Returns the #LinphoneCore object managing this nat policy, if any. + * @param[in] fr #LinphoneNatPolicy object */ LINPHONE_PUBLIC LinphoneCore *linphone_nat_policy_get_core(const LinphoneNatPolicy *policy); diff --git a/include/linphone/payload_type.h b/include/linphone/payload_type.h index f2cab35ce..a8e420f22 100644 --- a/include/linphone/payload_type.h +++ b/include/linphone/payload_type.h @@ -114,7 +114,7 @@ LINPHONE_PUBLIC int linphone_payload_type_get_channels(const LinphonePayloadType LINPHONE_PUBLIC int linphone_payload_type_get_number(const LinphonePayloadType *pt); /** - * Force a number for a payload type. The LinphoneCore does payload type number assignment automatically. + * Force a number for a payload type. The #LinphoneCore does payload type number assignment automatically. * This function is mainly to be used for tests, in order to override the automatic assignment mechanism. * @param[in] pt The payload type. * @param[in] number The number to assign to the payload type. diff --git a/include/linphone/player.h b/include/linphone/player.h index e061bdc1c..60633f9e6 100644 --- a/include/linphone/player.h +++ b/include/linphone/player.h @@ -37,62 +37,62 @@ extern "C" { /** * Acquire a reference to the player. - * @param[in] player LinphonePlayer object. - * @return The same LinphonePlayer object. + * @param[in] player #LinphonePlayer object. + * @return The same #LinphonePlayer object. **/ LINPHONE_PUBLIC LinphonePlayer * linphone_player_ref(LinphonePlayer *player); /** * Release reference to the player. - * @param[in] player LinphonePlayer object. + * @param[in] player #LinphonePlayer object. **/ LINPHONE_PUBLIC void linphone_player_unref(LinphonePlayer *player); /** * Retrieve the user pointer associated with the player. - * @param[in] player LinphonePlayer object. + * @param[in] player #LinphonePlayer object. * @return The user pointer associated with the player. **/ LINPHONE_PUBLIC void *linphone_player_get_user_data(const LinphonePlayer *player); /** * Assign a user pointer to the player. - * @param[in] player LinphonePlayer object. + * @param[in] player #LinphonePlayer object. * @param[in] ud The user pointer to associate with the player. **/ LINPHONE_PUBLIC void linphone_player_set_user_data(LinphonePlayer *player, void *ud); /** - * Get the LinphonePlayerCbs object associated with the LinphonePlayer. - * @param[in] player LinphonePlayer object - * @return The LinphonePlayerCbs object associated with the LinphonePlayer. + * Get the #LinphonePlayerCbs object associated with the LinphonePlayer. + * @param[in] player #LinphonePlayer object + * @return The #LinphonePlayerCbs object associated with the LinphonePlayer. */ LINPHONE_PUBLIC LinphonePlayerCbs * linphone_player_get_callbacks(const LinphonePlayer *player); /** * Open a file for playing. - * @param[in] obj LinphonePlayer object + * @param[in] obj #LinphonePlayer object * @param[in] filename The path to the file to open */ LINPHONE_PUBLIC LinphoneStatus linphone_player_open(LinphonePlayer *obj, const char *filename); /** * Start playing a file that has been opened with linphone_player_open(). - * @param[in] obj LinphonePlayer object + * @param[in] obj #LinphonePlayer object * @return 0 on success, a negative value otherwise */ LINPHONE_PUBLIC LinphoneStatus linphone_player_start(LinphonePlayer *obj); /** * Pause the playing of a file. - * @param[in] obj LinphonePlayer object + * @param[in] obj #LinphonePlayer object * @return 0 on success, a negative value otherwise */ LINPHONE_PUBLIC LinphoneStatus linphone_player_pause(LinphonePlayer *obj); /** * Seek in an opened file. - * @param[in] obj LinphonePlayer object + * @param[in] obj #LinphonePlayer object * @param[in] time_ms The time we want to go to in the file (in milliseconds). * @return 0 on success, a negative value otherwise. */ @@ -100,74 +100,74 @@ LINPHONE_PUBLIC LinphoneStatus linphone_player_seek(LinphonePlayer *obj, int tim /** * Get the current state of a player. - * @param[in] obj LinphonePlayer object + * @param[in] obj #LinphonePlayer object * @return The current state of the player. */ LINPHONE_PUBLIC LinphonePlayerState linphone_player_get_state(LinphonePlayer *obj); /** * Get the duration of the opened file. - * @param[in] obj LinphonePlayer object + * @param[in] obj #LinphonePlayer object * @return The duration of the opened file */ LINPHONE_PUBLIC int linphone_player_get_duration(LinphonePlayer *obj); /** * Get the current position in the opened file. - * @param[in] obj LinphonePlayer object + * @param[in] obj #LinphonePlayer object * @return The current position in the opened file */ LINPHONE_PUBLIC int linphone_player_get_current_position(LinphonePlayer *obj); /** * Close the opened file. - * @param[in] obj LinphonePlayer object + * @param[in] obj #LinphonePlayer object */ LINPHONE_PUBLIC void linphone_player_close(LinphonePlayer *obj); /** - * Returns the LinphoneCore object managing this player's call, if any. - * @param[in] fr LinphonePlayer object + * Returns the #LinphoneCore object managing this player's call, if any. + * @param[in] fr #LinphonePlayer object */ LINPHONE_PUBLIC LinphoneCore *linphone_player_get_core(const LinphonePlayer *player); /** - * Acquire a reference to the LinphonePlayerCbs object. - * @param[in] cbs LinphonePlayerCbs object. - * @return The same LinphonePlayerCbs object. + * Acquire a reference to the #LinphonePlayerCbs object. + * @param[in] cbs #LinphonePlayerCbs object. + * @return The same #LinphonePlayerCbs object. */ LINPHONE_PUBLIC LinphonePlayerCbs * linphone_player_cbs_ref(LinphonePlayerCbs *cbs); /** - * Release reference to the LinphonePlayerCbs object. - * @param[in] cbs LinphonePlayerCbs object. + * Release reference to the #LinphonePlayerCbs object. + * @param[in] cbs #LinphonePlayerCbs object. */ LINPHONE_PUBLIC void linphone_player_cbs_unref(LinphonePlayerCbs *cbs); /** - * Retrieve the user pointer associated with the LinphonePlayerCbs object. - * @param[in] cbs LinphonePlayerCbs object. - * @return The user pointer associated with the LinphonePlayerCbs object. + * Retrieve the user pointer associated with the #LinphonePlayerCbs object. + * @param[in] cbs #LinphonePlayerCbs object. + * @return The user pointer associated with the #LinphonePlayerCbs object. */ LINPHONE_PUBLIC void *linphone_player_cbs_get_user_data(const LinphonePlayerCbs *cbs); /** - * Assign a user pointer to the LinphonePlayerCbs object. - * @param[in] cbs LinphonePlayerCbs object. - * @param[in] ud The user pointer to associate with the LinphonePlayerCbs object. + * Assign a user pointer to the #LinphonePlayerCbs object. + * @param[in] cbs #LinphonePlayerCbs object. + * @param[in] ud The user pointer to associate with the #LinphonePlayerCbs object. */ LINPHONE_PUBLIC void linphone_player_cbs_set_user_data(LinphonePlayerCbs *cbs, void *ud); /** * Get the end-of-file reached callback. - * @param[in] cbs LinphonePlayerCbs object. + * @param[in] cbs #LinphonePlayerCbs object. * @return The current end-of-file reached callback. */ LINPHONE_PUBLIC LinphonePlayerCbsEofReachedCb linphone_player_cbs_get_eof_reached(const LinphonePlayerCbs *cbs); /** * Set the end-of-file reached callback. - * @param[in] cbs LinphonePlayerCbs object. + * @param[in] cbs #LinphonePlayerCbs object. * @param[in] cb The end-of-file reached callback to be used. */ LINPHONE_PUBLIC void linphone_player_cbs_set_eof_reached(LinphonePlayerCbs *cbs, LinphonePlayerCbsEofReachedCb cb); diff --git a/include/linphone/presence.h b/include/linphone/presence.h index 455508d7e..5290fd223 100644 --- a/include/linphone/presence.h +++ b/include/linphone/presence.h @@ -197,8 +197,8 @@ LINPHONE_PUBLIC LinphoneStatus linphone_presence_model_clear_notes(LinphonePrese /** * Get the consolidated presence from a presence model. - * @param[in] model LinphonePresenceModel object - * @return The LinphoneConsolidatedPresence corresponding to the presence model + * @param[in] model #LinphonePresenceModel object + * @return The #LinphoneConsolidatedPresence corresponding to the presence model */ LINPHONE_PUBLIC LinphoneConsolidatedPresence linphone_presence_model_get_consolidated_presence(const LinphonePresenceModel *model); @@ -282,7 +282,7 @@ LINPHONE_PUBLIC LinphoneStatus linphone_presence_model_clear_persons(LinphonePre * It is any of theses cases: * - basic status is'open' and no activities * - explicit 'online' tag in the status - * @param[in] model LinphonePresenceModel object + * @param[in] model #LinphonePresenceModel object * @return A boolean value telling whether the presence model is considered online or not. */ LINPHONE_PUBLIC bool_t linphone_presence_model_is_online(const LinphonePresenceModel *model); @@ -294,7 +294,7 @@ LINPHONE_PUBLIC bool_t linphone_presence_model_is_online(const LinphonePresenceM /** * Gets the string representation of a presence basic status. - * @param[in] basic_status A LinphonePresenceBasicStatus for which to get a string representation. + * @param[in] basic_status A #LinphonePresenceBasicStatus for which to get a string representation. * @return A pointer a dynamically allocated string representing the given basic status. * * The returned string is to be freed by calling ms_free(). diff --git a/include/linphone/proxy_config.h b/include/linphone/proxy_config.h index edaa9d8c8..5242a71e1 100644 --- a/include/linphone/proxy_config.h +++ b/include/linphone/proxy_config.h @@ -117,8 +117,9 @@ LINPHONE_PUBLIC void linphone_proxy_config_set_expires(LinphoneProxyConfig *cfg, #define linphone_proxy_config_expires linphone_proxy_config_set_expires /** - * Indicates either or not, REGISTRATION must be issued for this #LinphoneProxyConfig . - *
In case this #LinphoneProxyConfig has been added to #LinphoneCore, follows the linphone_proxy_config_edit() rule. + * @brief Indicates either or not, REGISTRATION must be issued for this #LinphoneProxyConfig . + * + * In case this #LinphoneProxyConfig has been added to #LinphoneCore, follows the linphone_proxy_config_edit() rule. * @param[in] cfg #LinphoneProxyConfig object. * @param val if true, registration will be engaged */ @@ -143,11 +144,11 @@ LINPHONE_PUBLIC void linphone_proxy_config_edit(LinphoneProxyConfig *cfg); LINPHONE_PUBLIC LinphoneStatus linphone_proxy_config_done(LinphoneProxyConfig *cfg); /** - * Indicates either or not, PUBLISH must be issued for this #LinphoneProxyConfig . - *
In case this #LinphoneProxyConfig has been added to #LinphoneCore, follows the linphone_proxy_config_edit() rule. - * @param[in] cfg #LinphoneProxyConfig object. - * @param val if true, publish will be engaged + * @brief Indicates either or not, PUBLISH must be issued for this #LinphoneProxyConfig. * + * In case this #LinphoneProxyConfig has been added to #LinphoneCore, follows the #linphone_proxy_config_edit() rule. + * @param[in] cfg #LinphoneProxyConfig object. + * @param val if TRUE, publish will be engaged */ LINPHONE_PUBLIC void linphone_proxy_config_enable_publish(LinphoneProxyConfig *cfg, bool_t val); @@ -406,7 +407,7 @@ LINPHONE_PUBLIC const char* linphone_proxy_config_get_transport(const LinphonePr /** * Destroys a proxy config. - * @note: LinphoneProxyConfig that have been removed from LinphoneCore with + * @note: #LinphoneProxyConfig that have been removed from #LinphoneCore with * linphone_core_remove_proxy_config() must not be freed. * @deprecated * @donotwrap @@ -467,7 +468,7 @@ LINPHONE_PUBLIC LinphoneAddress* linphone_proxy_config_normalize_sip_uri(Linphon /** * Set default privacy policy for all calls routed through this proxy. * @param[in] cfg #LinphoneProxyConfig object. - * @param privacy LinphonePrivacy to configure privacy + * @param privacy #LinphonePrivacy to configure privacy * */ LINPHONE_PUBLIC void linphone_proxy_config_set_privacy(LinphoneProxyConfig *cfg, LinphonePrivacyMask privacy); @@ -529,14 +530,14 @@ LINPHONE_PUBLIC uint8_t linphone_proxy_config_get_avpf_rr_interval(const Linphon /** * Get enablement status of RTCP feedback (also known as AVPF profile). * @param[in] cfg #LinphoneProxyConfig object. - * @return the enablement mode, which can be LinphoneAVPFDefault (use LinphoneCore's mode), LinphoneAVPFEnabled (avpf is enabled), or LinphoneAVPFDisabled (disabled). + * @return the enablement mode, which can be #LinphoneAVPFDefault (use LinphoneCore's mode), #LinphoneAVPFEnabled (avpf is enabled), or #LinphoneAVPFDisabled (disabled). **/ LINPHONE_PUBLIC LinphoneAVPFMode linphone_proxy_config_get_avpf_mode(const LinphoneProxyConfig *cfg); /** * Enable the use of RTCP feedback (also known as AVPF profile). * @param[in] cfg #LinphoneProxyConfig object. - * @param[in] mode the enablement mode, which can be LinphoneAVPFDefault (use LinphoneCore's mode), LinphoneAVPFEnabled (avpf is enabled), or LinphoneAVPFDisabled (disabled). + * @param[in] mode the enablement mode, which can be #LinphoneAVPFDefault (use LinphoneCore's mode), #LinphoneAVPFEnabled (avpf is enabled), or #LinphoneAVPFDisabled (disabled). **/ LINPHONE_PUBLIC void linphone_proxy_config_set_avpf_mode(LinphoneProxyConfig *cfg, LinphoneAVPFMode mode); @@ -589,7 +590,7 @@ LINPHONE_PUBLIC void linphone_proxy_config_set_ref_key(LinphoneProxyConfig *cfg, * Get The policy that is used to pass through NATs/firewalls when using this proxy config. * If it is set to NULL, the default NAT policy from the core will be used instead. * @param[in] cfg #LinphoneProxyConfig object - * @return LinphoneNatPolicy object in use. + * @return #LinphoneNatPolicy object in use. * @see linphone_core_get_nat_policy() */ LINPHONE_PUBLIC LinphoneNatPolicy * linphone_proxy_config_get_nat_policy(const LinphoneProxyConfig *cfg); @@ -598,7 +599,7 @@ LINPHONE_PUBLIC LinphoneNatPolicy * linphone_proxy_config_get_nat_policy(const L * Set the policy to use to pass through NATs/firewalls when using this proxy config. * If it is set to NULL, the default NAT policy from the core will be used instead. * @param[in] cfg #LinphoneProxyConfig object - * @param[in] policy LinphoneNatPolicy object + * @param[in] policy #LinphoneNatPolicy object * @see linphone_core_set_nat_policy() */ LINPHONE_PUBLIC void linphone_proxy_config_set_nat_policy(LinphoneProxyConfig *cfg, LinphoneNatPolicy *policy); @@ -617,6 +618,20 @@ void linphone_proxy_config_set_conference_factory_uri(LinphoneProxyConfig *cfg, */ const char * linphone_proxy_config_get_conference_factory_uri(const LinphoneProxyConfig *cfg); +/** + * Indicates whether to add to the contact parameters the push notification information. + * @param[in] cfg #LinphoneProxyConfig object. + * @param[in] allow True to allow push notification information, false otherwise. + */ +LINPHONE_PUBLIC void linphone_proxy_config_set_push_notification_allowed(LinphoneProxyConfig *cfg, bool_t allow); + +/** + * Indicates whether to add to the contact parameters the push notification information. + * @param[in] cfg #LinphoneProxyConfig object. + * @return True if push notification informations should be added, false otherwise. + */ +LINPHONE_PUBLIC bool_t linphone_proxy_config_is_push_notification_allowed(const LinphoneProxyConfig *cfg); + /** * @} */ diff --git a/include/linphone/ringtoneplayer.h b/include/linphone/ringtoneplayer.h index 81dc5f45d..fce0dd739 100644 --- a/include/linphone/ringtoneplayer.h +++ b/include/linphone/ringtoneplayer.h @@ -35,7 +35,7 @@ LINPHONE_PUBLIC LinphoneStatus linphone_ringtoneplayer_start(MSFactory *factory, /** * Start a ringtone player * @param factory A MSFactory object - * @param rp LinphoneRingtonePlayer object + * @param rp #LinphoneRingtonePlayer object * @param card unused argument * @param ringtone path to the ringtone to play * @param loop_pause_ms pause interval in milliseconds to be observed between end of play and resuming at start. A value of -1 disables loop mode diff --git a/include/linphone/tunnel.h b/include/linphone/tunnel.h index 3fbfa9c4b..fbd174a0f 100644 --- a/include/linphone/tunnel.h +++ b/include/linphone/tunnel.h @@ -37,13 +37,13 @@ /** * Linphone tunnel aims is to bypass IP traffic blocking due to aggressive firewalls which typically only authorize TCP traffic with destination port 443. *
Its principle is tunneling all SIP and/or RTP traffic through a single secure https connection up to a detunnelizer server. - *
This set of methods enhance LinphoneCore functionalities in order to provide an easy to use API to + *
This set of methods enhance #LinphoneCore functionalities in order to provide an easy to use API to * \li provision tunnel servers IP addresses and ports. This functionality is an option not implemented under GPL. Availability can be check at runtime using function #linphone_core_tunnel_available * \li start/stop the tunneling service * \li perform auto-detection whether tunneling is required, based on a test of sending/receiving a flow of UDP packets. * * It takes in charge automatically the SIP registration procedure when connecting or disconnecting to a tunnel server. - * No other action on LinphoneCore is required to enable full operation in tunnel mode. + * No other action on #LinphoneCore is required to enable full operation in tunnel mode. * *
Provision is done using object #LinphoneTunnelConfig created by function #linphone_tunnel_config_new(). Functions #linphone_tunnel_config_set_host * and #linphone_tunnel_config_set_port allow to point to tunnel server IP/port. Once set, use function #linphone_tunnel_add_server to provision a tunnel server. @@ -108,56 +108,56 @@ LINPHONE_PUBLIC void linphone_tunnel_unref(LinphoneTunnel *tunnel); /** * Set the IP address or hostname of the tunnel server. - * @param tunnel LinphoneTunnelConfig object + * @param tunnel #LinphoneTunnelConfig object * @param host The tunnel server IP address or hostname */ LINPHONE_PUBLIC void linphone_tunnel_config_set_host(LinphoneTunnelConfig *tunnel, const char *host); /** * Get the IP address or hostname of the tunnel server. - * @param tunnel LinphoneTunnelConfig object + * @param tunnel #LinphoneTunnelConfig object * @return The tunnel server IP address or hostname */ LINPHONE_PUBLIC const char *linphone_tunnel_config_get_host(const LinphoneTunnelConfig *tunnel); /** * Set tls port of server. - * @param tunnel LinphoneTunnelConfig object + * @param tunnel #LinphoneTunnelConfig object * @param port The tunnel server TLS port, recommended value is 443 */ LINPHONE_PUBLIC void linphone_tunnel_config_set_port(LinphoneTunnelConfig *tunnel, int port); /** * Get the TLS port of the tunnel server. - * @param tunnel LinphoneTunnelConfig object + * @param tunnel #LinphoneTunnelConfig object * @return The TLS port of the tunnel server */ LINPHONE_PUBLIC int linphone_tunnel_config_get_port(const LinphoneTunnelConfig *tunnel); /** * Set the IP address or hostname of the second tunnel server when using dual tunnel client. - * @param tunnel LinphoneTunnelConfig object + * @param tunnel #LinphoneTunnelConfig object * @param host The tunnel server IP address or hostname */ LINPHONE_PUBLIC void linphone_tunnel_config_set_host2(LinphoneTunnelConfig *tunnel, const char *host); /** * Get the IP address or hostname of the second tunnel server when using dual tunnel client. - * @param tunnel LinphoneTunnelConfig object + * @param tunnel #LinphoneTunnelConfig object * @return The tunnel server IP address or hostname */ LINPHONE_PUBLIC const char *linphone_tunnel_config_get_host2(const LinphoneTunnelConfig *tunnel); /** * Set tls port of the second server when using dual tunnel client. - * @param tunnel LinphoneTunnelConfig object + * @param tunnel #LinphoneTunnelConfig object * @param port The tunnel server TLS port, recommended value is 443 */ LINPHONE_PUBLIC void linphone_tunnel_config_set_port2(LinphoneTunnelConfig *tunnel, int port); /** * Get the TLS port of the second tunnel server when using dual tunnel client. - * @param tunnel LinphoneTunnelConfig object + * @param tunnel #LinphoneTunnelConfig object * @return The TLS port of the tunnel server */ LINPHONE_PUBLIC int linphone_tunnel_config_get_port2(const LinphoneTunnelConfig *tunnel); @@ -165,7 +165,7 @@ LINPHONE_PUBLIC int linphone_tunnel_config_get_port2(const LinphoneTunnelConfig /** * Set the remote port on the tunnel server side used to test UDP reachability. * This is used when the mode is set auto, to detect whether the tunnel has to be enabled or not. - * @param tunnel LinphoneTunnelConfig object + * @param tunnel #LinphoneTunnelConfig object * @param remote_udp_mirror_port The remote port on the tunnel server side used to test UDP reachability, set to -1 to disable the feature */ LINPHONE_PUBLIC void linphone_tunnel_config_set_remote_udp_mirror_port(LinphoneTunnelConfig *tunnel, int remote_udp_mirror_port); @@ -173,40 +173,40 @@ LINPHONE_PUBLIC void linphone_tunnel_config_set_remote_udp_mirror_port(LinphoneT /** * Get the remote port on the tunnel server side used to test UDP reachability. * This is used when the mode is set auto, to detect whether the tunnel has to be enabled or not. - * @param tunnel LinphoneTunnelConfig object + * @param tunnel #LinphoneTunnelConfig object * @return The remote port on the tunnel server side used to test UDP reachability */ LINPHONE_PUBLIC int linphone_tunnel_config_get_remote_udp_mirror_port(const LinphoneTunnelConfig *tunnel); /** * Set the UDP packet round trip delay in ms for a tunnel configuration. - * @param tunnel LinphoneTunnelConfig object + * @param tunnel #LinphoneTunnelConfig object * @param delay The UDP packet round trip delay in ms considered as acceptable (recommended value is 1000 ms). */ LINPHONE_PUBLIC void linphone_tunnel_config_set_delay(LinphoneTunnelConfig *tunnel, int delay); /** * Get the UDP packet round trip delay in ms for a tunnel configuration. - * @param tunnel LinphoneTunnelConfig object + * @param tunnel #LinphoneTunnelConfig object * @return The UDP packet round trip delay in ms. */ LINPHONE_PUBLIC int linphone_tunnel_config_get_delay(const LinphoneTunnelConfig *tunnel); /** - * Increment the refcount of LinphoneTunnelConfig object. - * @param cfg the LinphoneTunnelConfig object. + * Increment the refcount of #LinphoneTunnelConfig object. + * @param cfg the #LinphoneTunnelConfig object. * @return the same cfg object. **/ LINPHONE_PUBLIC LinphoneTunnelConfig * linphone_tunnel_config_ref(LinphoneTunnelConfig *cfg); /** - * Decrement the refcount of LinphoneTunnelConfig object. - * @param cfg the LinphoneTunnelConfig object. + * Decrement the refcount of #LinphoneTunnelConfig object. + * @param cfg the #LinphoneTunnelConfig object. **/ LINPHONE_PUBLIC void linphone_tunnel_config_unref(LinphoneTunnelConfig *cfg); /** * Destroy a tunnel configuration - * @param tunnel LinphoneTunnelConfig object + * @param tunnel #LinphoneTunnelConfig object * @deprecated use linphone_tunnel_config_unref(). * @donotwrap */ @@ -228,28 +228,28 @@ LINPHONE_PUBLIC void *linphone_tunnel_config_get_user_data(LinphoneTunnelConfig /** * Add a tunnel server configuration. - * @param tunnel LinphoneTunnel object - * @param tunnel_config LinphoneTunnelConfig object + * @param tunnel #LinphoneTunnel object + * @param tunnel_config #LinphoneTunnelConfig object */ LINPHONE_PUBLIC void linphone_tunnel_add_server(LinphoneTunnel *tunnel, LinphoneTunnelConfig *tunnel_config); /** * Remove a tunnel server configuration. - * @param tunnel LinphoneTunnel object - * @param tunnel_config LinphoneTunnelConfig object + * @param tunnel #LinphoneTunnel object + * @param tunnel_config #LinphoneTunnelConfig object */ LINPHONE_PUBLIC void linphone_tunnel_remove_server(LinphoneTunnel *tunnel, LinphoneTunnelConfig *tunnel_config); /** * Get added servers - * @param tunnel LinphoneTunnel object + * @param tunnel #LinphoneTunnel object * @return \bctbx_list{LinphoneTunnelConfig} */ LINPHONE_PUBLIC const bctbx_list_t *linphone_tunnel_get_servers(const LinphoneTunnel *tunnel); /** * Remove all tunnel server addresses previously entered with linphone_tunnel_add_server() - * @param tunnel LinphoneTunnel object + * @param tunnel #LinphoneTunnel object **/ LINPHONE_PUBLIC void linphone_tunnel_clean_servers(LinphoneTunnel *tunnel); @@ -259,15 +259,15 @@ LINPHONE_PUBLIC void linphone_tunnel_clean_servers(LinphoneTunnel *tunnel); * If the mode is set to 'auto', the tunnel manager will try to established an RTP session * with the tunnel server on the UdpMirrorPort. If the connection fail, the tunnel is automatically * activated whereas the tunnel is automatically disabled if the connection succeed. - * @param tunnel LinphoneTunnel object - * @param mode The desired LinphoneTunnelMode + * @param tunnel #LinphoneTunnel object + * @param mode The desired #LinphoneTunnelMode **/ LINPHONE_PUBLIC void linphone_tunnel_set_mode(LinphoneTunnel *tunnel, LinphoneTunnelMode mode); /** * Get the tunnel mode - * @param tunnel LinphoneTunnel object - * @return The current LinphoneTunnelMode + * @param tunnel #LinphoneTunnel object + * @return The current #LinphoneTunnelMode **/ LINPHONE_PUBLIC LinphoneTunnelMode linphone_tunnel_get_mode(const LinphoneTunnel *tunnel); @@ -275,14 +275,14 @@ LINPHONE_PUBLIC LinphoneTunnelMode linphone_tunnel_get_mode(const LinphoneTunnel * Sets whether or not to use the dual tunnel client mode. * By default this feature is disabled. * After enabling it, add a server with 2 hosts and 2 ports for the feature to work. - * @param tunnel LinphoneTunnel object + * @param tunnel #LinphoneTunnel object * @param dual_mode_enabled TRUE to enable it, FALSE to disable it */ LINPHONE_PUBLIC void linphone_tunnel_enable_dual_mode(LinphoneTunnel *tunnel, bool_t dual_mode_enabled); /** * Get the dual tunnel client mode - * @param tunnel LinphoneTunnel object + * @param tunnel #LinphoneTunnel object * @return TRUE if dual tunnel client mode is enabled, FALSE otherwise **/ LINPHONE_PUBLIC bool_t linphone_tunnel_dual_mode_enabled(const LinphoneTunnel *tunnel); @@ -298,7 +298,7 @@ LINPHONE_PUBLIC bool_t linphone_tunnel_get_activated(const LinphoneTunnel *tunne /** * Check whether the tunnel is connected - * @param tunnel LinphoneTunnel object + * @param tunnel #LinphoneTunnel object * @return A boolean value telling if the tunnel is connected **/ LINPHONE_PUBLIC bool_t linphone_tunnel_connected(const LinphoneTunnel *tunnel); @@ -308,27 +308,27 @@ LINPHONE_PUBLIC bool_t linphone_tunnel_connected(const LinphoneTunnel *tunnel); * This method is useful when the device switches from wifi to Edge/3G or vice versa. In most cases the tunnel client socket * won't be notified promptly that its connection is now zombie, so it is recommended to call this method that will cause * the lost connection to be closed and new connection to be issued. - * @param tunnel LinphoneTunnel object + * @param tunnel #LinphoneTunnel object **/ LINPHONE_PUBLIC void linphone_tunnel_reconnect(LinphoneTunnel *tunnel); /** * Set whether SIP packets must be directly sent to a UA or pass through the tunnel - * @param tunnel LinphoneTunnel object + * @param tunnel #LinphoneTunnel object * @param enable If true, SIP packets shall pass through the tunnel */ LINPHONE_PUBLIC void linphone_tunnel_enable_sip(LinphoneTunnel *tunnel, bool_t enable); /** * Check whether tunnel is set to transport SIP packets - * @param tunnel LinphoneTunnel object + * @param tunnel #LinphoneTunnel object * @return A boolean value telling whether SIP packets shall pass through the tunnel */ LINPHONE_PUBLIC bool_t linphone_tunnel_sip_enabled(const LinphoneTunnel *tunnel); /** * Set an optional http proxy to go through when connecting to tunnel server. - * @param tunnel LinphoneTunnel object + * @param tunnel #LinphoneTunnel object * @param host http proxy host * @param port http proxy port * @param username Optional http proxy username if the proxy request authentication. Currently only basic authentication is supported. Use NULL if not needed. @@ -338,7 +338,7 @@ LINPHONE_PUBLIC void linphone_tunnel_set_http_proxy(LinphoneTunnel *tunnel, cons /** * Retrieve optional http proxy configuration previously set with linphone_tunnel_set_http_proxy(). - * @param tunnel LinphoneTunnel object + * @param tunnel #LinphoneTunnel object * @param host http proxy host * @param port http proxy port * @param username Optional http proxy username if the proxy request authentication. Currently only basic authentication is supported. Use NULL if not needed. @@ -349,7 +349,7 @@ LINPHONE_PUBLIC void linphone_tunnel_get_http_proxy(LinphoneTunnel*tunnel,const /** * Set authentication info for the http proxy - * @param tunnel LinphoneTunnel object + * @param tunnel #LinphoneTunnel object * @param username User name * @param passwd Password */ @@ -387,7 +387,7 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_tunnel_auto_detect(LinphoneTun /** * Tell whether tunnel auto detection is enabled. - * @param[in] tunnel LinphoneTunnel object. + * @param[in] tunnel #LinphoneTunnel object. * @return TRUE if auto detection is enabled, FALSE otherwise. * @deprecated Replaced by linphone_tunnel_get_mode() * @donotwrap diff --git a/include/linphone/types.h b/include/linphone/types.h index 9a8ba46c9..a7ad26c9d 100644 --- a/include/linphone/types.h +++ b/include/linphone/types.h @@ -30,20 +30,20 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "linphone/api/c-types.h" /** - * The LinphoneAccountCreator object used to configure an account on a server via XML-RPC. + * The #LinphoneAccountCreator object used to configure an account on a server via XML-RPC. * @ingroup account_creator **/ typedef struct _LinphoneAccountCreator LinphoneAccountCreator; /** - * An object to define a LinphoneAccountCreator service. + * An object to define a #LinphoneAccountCreator service. * @ingroup account_creator * @donotwrap **/ typedef struct _LinphoneAccountCreatorService LinphoneAccountCreatorService; /** - * An object to handle the responses callbacks for handling the LinphoneAccountCreator operations. + * An object to handle the responses callbacks for handling the #LinphoneAccountCreator operations. * @ingroup account_creator **/ typedef struct _LinphoneAccountCreatorCbs LinphoneAccountCreatorCbs; @@ -200,13 +200,13 @@ typedef enum _LinphoneAudioRoute { * Sometimes, a userid is required by proxy, and realm can be useful to discriminate * different SIP domains. * - * Once created and filled, a LinphoneAuthInfo must be added to the LinphoneCore in + * Once created and filled, a #LinphoneAuthInfo must be added to the #LinphoneCore in * order to become known and used automatically when needed. * Use linphone_core_add_auth_info() for that purpose. * - * The LinphoneCore object can take the initiative to request authentication information + * The #LinphoneCore object can take the initiative to request authentication information * when needed to the application through the auth_info_requested callback of the - * LinphoneCoreVTable structure. + * #LinphoneCoreVTable structure. * * The application can respond to this information request later using * linphone_core_add_auth_info(). This will unblock all pending authentication @@ -236,7 +236,7 @@ typedef enum _LinphoneAVPFMode { } LinphoneAVPFMode; /** - * The LinphoneContent object representing a data buffer. + * The #LinphoneContent object representing a data buffer. * @ingroup misc **/ typedef struct _LinphoneBuffer LinphoneBuffer; @@ -257,7 +257,7 @@ typedef enum _LinphoneCallDir { typedef struct _LinphoneCallLog LinphoneCallLog; /** - * The LinphoneCallParams is an object containing various call related parameters. + * The #LinphoneCallParams is an object containing various call related parameters. * It can be used to retrieve parameters from a currently running call or modify * the call's characteristics dynamically. * @ingroup call_control @@ -265,10 +265,10 @@ typedef struct _LinphoneCallLog LinphoneCallLog; typedef struct _LinphoneCallParams LinphoneCallParams; /** - * The LinphoneCallStats objects carries various statistic informations regarding quality of audio or video streams. + * The #LinphoneCallStats objects carries various statistic informations regarding quality of audio or video streams. * - * To receive these informations periodically and as soon as they are computed, the application is invited to place a #LinphoneCoreCallStatsUpdatedCb callback in the LinphoneCoreVTable structure - * it passes for instanciating the LinphoneCore object (see linphone_core_new() ). + * To receive these informations periodically and as soon as they are computed, the application is invited to place a #LinphoneCoreCallStatsUpdatedCb callback in the #LinphoneCoreVTable structure + * it passes for instanciating the #LinphoneCore object (see linphone_core_new() ). * * At any time, the application can access last computed statistics using linphone_call_get_audio_stats() or linphone_call_get_video_stats(). * @ingroup call_misc @@ -290,7 +290,7 @@ typedef enum _LinphoneCallStatus { } LinphoneCallStatus; /** - * LinphoneConference class + * #LinphoneConference class * The _LinphoneConference struct does not exists, it's the Conference C++ class that is used behind * @ingroup call_control */ @@ -304,7 +304,7 @@ typedef struct _LinphoneConference LinphoneConference; typedef struct _LinphoneConferenceParams LinphoneConferenceParams; /** - * The LinphoneConfig object is used to manipulate a configuration file. + * The #LinphoneConfig object is used to manipulate a configuration file. * * The format of the configuration file is a .ini like format: * - sections are defined in [] @@ -330,7 +330,7 @@ typedef struct _LpConfig LinphoneConfig; #define LpConfig LinphoneConfig /** - * LinphoneGlobalState describes the global state of the LinphoneCore object. + * #LinphoneGlobalState describes the global state of the #LinphoneCore object. * It is notified via the LinphoneCoreVTable::global_state_changed * @ingroup initializing **/ @@ -361,18 +361,12 @@ typedef struct _LinphoneContactSearch LinphoneContactSearch; typedef unsigned int LinphoneContactSearchID; /** - * Old name of LinphoneContactSearchID + * Old name of #LinphoneContactSearchID * @deprecated * @donotwrap */ LINPHONE_DEPRECATED typedef LinphoneContactSearchID ContactSearchID; -/** - * The LinphoneContent object holds data that can be embedded in a signaling message. - * @ingroup misc -**/ -typedef struct _LinphoneContent LinphoneContent; - /** * Linphone core main object created by function linphone_core_new() . * @ingroup initializing @@ -406,7 +400,7 @@ typedef enum _LinphoneEcCalibratorStatus { /** * Object representing full details about a signaling error or status. - * All LinphoneErrorInfo object returned by the liblinphone API are readonly and transcients. For safety they must be used immediately + * All #LinphoneErrorInfo object returned by the liblinphone API are readonly and transcients. For safety they must be used immediately * after obtaining them. Any other function call to the liblinphone may change their content or invalidate the pointer. * @ingroup misc **/ @@ -454,13 +448,13 @@ typedef enum _LinphoneFirewallPolicy { typedef struct _LinphoneFriend LinphoneFriend; /** - * The LinphoneFriendList object representing a list of friends. + * The #LinphoneFriendList object representing a list of friends. * @ingroup buddy_list **/ typedef struct _LinphoneFriendList LinphoneFriendList; /** - * An object to handle the callbacks for LinphoneFriend synchronization. + * An object to handle the callbacks for #LinphoneFriend synchronization. * @ingroup buddy_list **/ typedef struct _LinphoneFriendListCbs LinphoneFriendListCbs; @@ -486,7 +480,7 @@ typedef enum _LinphoneFriendListSyncStatus { } LinphoneFriendListSyncStatus; /** - * LinphoneGlobalState describes the global state of the LinphoneCore object. + * #LinphoneGlobalState describes the global state of the #LinphoneCore object. * It is notified via the LinphoneCoreVTable::global_state_changed * @ingroup initializing **/ @@ -519,7 +513,7 @@ typedef enum _LinphoneIceState { typedef struct _LinphoneImEncryptionEngine LinphoneImEncryptionEngine; /** - * An object to handle the callbacks for the handling a LinphoneImEncryptionEngine object. + * An object to handle the callbacks for the handling a #LinphoneImEncryptionEngine object. * @ingroup misc * @donotwrap */ @@ -533,7 +527,7 @@ typedef struct _LinphoneImEncryptionEngineCbs LinphoneImEncryptionEngineCbs; typedef struct _LinphoneImNotifPolicy LinphoneImNotifPolicy; /** - * The LinphoneInfoMessage is an object representing an informational message sent or received by the core. + * The #LinphoneInfoMessage is an object representing an informational message sent or received by the core. * @ingroup misc **/ typedef struct _LinphoneInfoMessage LinphoneInfoMessage; @@ -561,7 +555,7 @@ typedef enum _LinphoneLogCollectionState { } LinphoneLogCollectionState; /** - * LinphoneCoreLogCollectionUploadState is used to notify if log collection upload have been succesfully delivered or not. + * #LinphoneCoreLogCollectionUploadState is used to notify if log collection upload have been succesfully delivered or not. * @ingroup initializing */ typedef enum _LinphoneCoreLogCollectionUploadState { @@ -628,7 +622,7 @@ typedef enum _LinphoneOnlineStatus{ typedef struct _LinphonePlayer LinphonePlayer; /** - * An object to handle the callbacks for the handling a LinphonePlayer objects. + * An object to handle the callbacks for the handling a #LinphonePlayer objects. * @ingroup call_control */ typedef struct _LinphonePlayerCbs LinphonePlayerCbs; @@ -838,11 +832,11 @@ typedef enum _LinphonePrivacy { typedef unsigned int LinphonePrivacyMask; /** - * The LinphoneProxyConfig object represents a proxy configuration to be used - * by the LinphoneCore object. + * The #LinphoneProxyConfig object represents a proxy configuration to be used + * by the #LinphoneCore object. * Its fields must not be used directly in favour of the accessors methods. - * Once created and filled properly the LinphoneProxyConfig can be given to - * LinphoneCore with linphone_core_add_proxy_config(). + * Once created and filled properly the #LinphoneProxyConfig can be given to + * #LinphoneCore with linphone_core_add_proxy_config(). * This will automatically triggers the registration, if enabled. * * The proxy configuration are persistent to restarts because they are saved @@ -906,7 +900,7 @@ typedef enum _LinphoneReason{ #define LinphoneReasonMedia LinphoneReasonUnsupportedContent /** - * LinphoneRegistrationState describes proxy registration states. + * #LinphoneRegistrationState describes proxy registration states. * @ingroup proxies **/ typedef enum _LinphoneRegistrationState { @@ -942,7 +936,7 @@ typedef struct _LinphoneSipTransports { typedef struct _LinphoneTransports LinphoneTransports; /** - * Old name of LinphoneSipTransports + * Old name of #LinphoneSipTransports * @deprecated * @donotwrap */ @@ -988,7 +982,7 @@ typedef enum _LinphoneSubscriptionDir{ /** * Enum for subscription states. - * LinphoneSubscriptionTerminated and LinphoneSubscriptionError are final states. + * #LinphoneSubscriptionTerminated and #LinphoneSubscriptionError are final states. * @ingroup event_api **/ typedef enum _LinphoneSubscriptionState{ @@ -1064,7 +1058,7 @@ typedef enum _LinphoneUpnpState { } LinphoneUpnpState; /** - * The LinphoneVcard object. + * The #LinphoneVcard object. * @ingroup carddav_vcard */ typedef struct _LinphoneVcard LinphoneVcard; @@ -1080,7 +1074,7 @@ typedef enum _LinphoneVersionUpdateCheckResult { } LinphoneVersionUpdateCheckResult; /** - * The LinphoneVideoDefinition object represents a video definition, eg. its width and its height. + * The #LinphoneVideoDefinition object represents a video definition, eg. its width and its height. * @ingroup media_parameters */ typedef struct _LinphoneVideoDefinition LinphoneVideoDefinition; @@ -1109,7 +1103,7 @@ typedef struct LinphoneVideoSizeDef { } LinphoneVideoSizeDef; /** - * Old name of LinphoneVideoSizeDef + * Old name of #LinphoneVideoSizeDef * @deprecated */ typedef LinphoneVideoSizeDef MSVideoSizeDef; @@ -1131,19 +1125,19 @@ typedef enum _LinphoneXmlRpcArgType { } LinphoneXmlRpcArgType; /** - * The LinphoneXmlRpcRequest object representing a XML-RPC request to be sent. + * The #LinphoneXmlRpcRequest object representing a XML-RPC request to be sent. * @ingroup misc **/ typedef struct _LinphoneXmlRpcRequest LinphoneXmlRpcRequest; /** - * An object to handle the callbacks for handling the LinphoneXmlRpcRequest operations. + * An object to handle the callbacks for handling the #LinphoneXmlRpcRequest operations. * @ingroup misc **/ typedef struct _LinphoneXmlRpcRequestCbs LinphoneXmlRpcRequestCbs; /** - * The LinphoneXmlRpcSession object used to send XML-RPC requests and handle their responses. + * The #LinphoneXmlRpcSession object used to send XML-RPC requests and handle their responses. * @ingroup misc **/ typedef struct _LinphoneXmlRpcSession LinphoneXmlRpcSession; diff --git a/include/linphone/utils/enum-generator.h b/include/linphone/utils/enum-generator.h index f66000791..ebdca6c61 100644 --- a/include/linphone/utils/enum-generator.h +++ b/include/linphone/utils/enum-generator.h @@ -37,10 +37,11 @@ LINPHONE_BEGIN_NAMESPACE // Call the right macro. (With or without value.) #define L_DECLARE_ENUM_MACRO_CHOOSER(...) \ - L_GET_ARG_3(__VA_ARGS__, L_DECLARE_ENUM_VALUE_2_ARGS, L_DECLARE_ENUM_VALUE_1_ARG) + L_EXPAND(L_GET_ARG_3(__VA_ARGS__, L_DECLARE_ENUM_VALUE_2_ARGS, L_DECLARE_ENUM_VALUE_1_ARG)) // Enum value declaration. -#define L_DECLARE_ENUM_VALUE(...) L_DECLARE_ENUM_MACRO_CHOOSER(__VA_ARGS__)(__VA_ARGS__) +#define L_DECLARE_ENUM_VALUE(...) \ + L_EXPAND(L_DECLARE_ENUM_MACRO_CHOOSER(__VA_ARGS__)(__VA_ARGS__)) #ifdef __cplusplus diff --git a/include/linphone/utils/general.h b/include/linphone/utils/general.h index 26c99603e..829d4bda5 100644 --- a/include/linphone/utils/general.h +++ b/include/linphone/utils/general.h @@ -189,15 +189,13 @@ namespace Private { #define L_INTERNAL_DECLARE_PRIVATE(CLASS) \ inline CLASS ## Private *getPrivate () { \ L_INTERNAL_CHECK_OBJECT_INHERITANCE(CLASS); \ - return reinterpret_cast( \ - LinphonePrivate::Private::BetterPrivateAncestor::mPrivate \ - ); \ + using TypeAncestor = LinphonePrivate::Private::BetterPrivateAncestor; \ + return reinterpret_cast(TypeAncestor::mPrivate); \ } \ inline const CLASS ## Private *getPrivate () const { \ L_INTERNAL_CHECK_OBJECT_INHERITANCE(CLASS); \ - return reinterpret_cast( \ - LinphonePrivate::Private::BetterPrivateAncestor::mPrivate \ - ); \ + using TypeAncestor = LinphonePrivate::Private::BetterPrivateAncestor; \ + return reinterpret_cast(TypeAncestor::mPrivate); \ } \ friend class CLASS ## Private; \ friend class Wrapper; diff --git a/include/linphone/utils/utils.h b/include/linphone/utils/utils.h index e13c89889..c93058006 100644 --- a/include/linphone/utils/utils.h +++ b/include/linphone/utils/utils.h @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -82,9 +83,8 @@ namespace Utils { LINPHONE_PUBLIC std::string toString (long double val); LINPHONE_PUBLIC std::string toString (const void *val); - LINPHONE_PUBLIC template::value, T>::type> - inline std::string toString (const T &val) { return getEnumValueAsString(val); } + LINPHONE_PUBLIC inline std::string toString (const T &val) { return getEnumValueAsString(val); } LINPHONE_PUBLIC int stoi (const std::string &str, size_t *idx = 0, int base = 10); LINPHONE_PUBLIC long long stoll (const std::string &str, size_t *idx = 0, int base = 10); @@ -107,11 +107,20 @@ namespace Utils { return str ? str : ""; } + template + LINPHONE_PUBLIC std::string join (const std::vector& elems, const S& delim) { + std::stringstream ss; + auto e = elems.begin(); + ss << *e++; + for (; e != elems.end(); ++e) + ss << delim << *e; + return ss.str(); + } LINPHONE_PUBLIC std::string trim (const std::string &str); template LINPHONE_PUBLIC const T &getEmptyConstRefObject () { - static const T object; + static const T object{}; return object; } diff --git a/include/linphone/vcard.h b/include/linphone/vcard.h index fd12db4fb..9f7527f08 100644 --- a/include/linphone/vcard.h +++ b/include/linphone/vcard.h @@ -38,16 +38,16 @@ extern "C" #define LINPHONE_VCARD BELLE_SIP_CAST(object, LinphoneVcard) /** - * Creates a LinphoneVcard object that has a pointer to an empty vCard - * @return a new LinphoneVcard object + * Creates a #LinphoneVcard object that has a pointer to an empty vCard + * @return a new #LinphoneVcard object * @deprecated Use linphone_factory_create_vcard() instead. * @donotwrap */ LINPHONE_DEPRECATED LINPHONE_PUBLIC LinphoneVcard* linphone_vcard_new(void); /** - * Deletes a LinphoneVcard object properly - * @param[in] vCard the LinphoneVcard to destroy + * Deletes a #LinphoneVcard object properly + * @param[in] vCard the #LinphoneVcard to destroy * @deprecated Use linphone_vcard_unref() or belle_sip_object_unref() instead. * @donotwrap */ @@ -55,145 +55,145 @@ LINPHONE_DEPRECATED LINPHONE_PUBLIC void linphone_vcard_free(LinphoneVcard *vCar /** * Take a ref on a #LinphoneVcard. - * @param[in] vCard LinphoneVcard object + * @param[in] vCard #LinphoneVcard object */ LINPHONE_PUBLIC LinphoneVcard *linphone_vcard_ref(LinphoneVcard *vCard); /** * Release a #LinphoneVcard. - * @param[in] vCard LinphoneVcard object + * @param[in] vCard #LinphoneVcard object */ LINPHONE_PUBLIC void linphone_vcard_unref(LinphoneVcard *vCard); /** * Clone a #LinphoneVcard. - * @param[in] vCard LinphoneVcard object - * @return a new LinphoneVcard object + * @param[in] vCard #LinphoneVcard object + * @return a new #LinphoneVcard object */ LINPHONE_PUBLIC LinphoneVcard *linphone_vcard_clone(const LinphoneVcard *vCard); /** * Returns the vCard4 representation of the LinphoneVcard. - * @param[in] vCard the LinphoneVcard + * @param[in] vCard the #LinphoneVcard * @return a const char * that represents the vCard */ LINPHONE_PUBLIC const char* linphone_vcard_as_vcard4_string(LinphoneVcard *vCard); /** * Sets the FN attribute of the vCard (which is mandatory). - * @param[in] vCard the LinphoneVcard + * @param[in] vCard the #LinphoneVcard * @param[in] name the display name to set for the vCard */ LINPHONE_PUBLIC void linphone_vcard_set_full_name(LinphoneVcard *vCard, const char *name); /** * Returns the FN attribute of the vCard, or NULL if it isn't set yet. - * @param[in] vCard the LinphoneVcard + * @param[in] vCard the #LinphoneVcard * @return the display name of the vCard, or NULL */ LINPHONE_PUBLIC const char* linphone_vcard_get_full_name(const LinphoneVcard *vCard); /** * Sets the skipFieldValidation property of the vcard - * @param[in] vCard the LinphoneVcard + * @param[in] vCard the #LinphoneVcard * @param[in] skip skipFieldValidation property of the vcard */ LINPHONE_PUBLIC void linphone_vcard_set_skip_validation(LinphoneVcard *vCard, bool_t skip); /** * Returns the skipFieldValidation property of the vcard. - * @param[in] vCard the LinphoneVcard + * @param[in] vCard the #LinphoneVcard * @return the skipFieldValidation property of the vcard */ LINPHONE_PUBLIC bool_t linphone_vcard_get_skip_validation(const LinphoneVcard *vCard); /** * Sets the family name in the N attribute of the vCard. - * @param[in] vCard the LinphoneVcard + * @param[in] vCard the #LinphoneVcard * @param[in] name the family name to set for the vCard */ LINPHONE_PUBLIC void linphone_vcard_set_family_name(LinphoneVcard *vCard, const char *name); /** * Returns the family name in the N attribute of the vCard, or NULL if it isn't set yet. - * @param[in] vCard the LinphoneVcard + * @param[in] vCard the #LinphoneVcard * @return the family name of the vCard, or NULL */ LINPHONE_PUBLIC const char* linphone_vcard_get_family_name(const LinphoneVcard *vCard); /** * Sets the given name in the N attribute of the vCard. - * @param[in] vCard the LinphoneVcard + * @param[in] vCard the #LinphoneVcard * @param[in] name the given name to set for the vCard */ LINPHONE_PUBLIC void linphone_vcard_set_given_name(LinphoneVcard *vCard, const char *name); /** * Returns the given name in the N attribute of the vCard, or NULL if it isn't set yet. - * @param[in] vCard the LinphoneVcard + * @param[in] vCard the #LinphoneVcard * @return the given name of the vCard, or NULL */ LINPHONE_PUBLIC const char* linphone_vcard_get_given_name(const LinphoneVcard *vCard); /** * Adds a SIP address in the vCard, using the IMPP property - * @param[in] vCard the LinphoneVcard + * @param[in] vCard the #LinphoneVcard * @param[in] sip_address the SIP address to add */ LINPHONE_PUBLIC void linphone_vcard_add_sip_address(LinphoneVcard *vCard, const char *sip_address); /** * Removes a SIP address in the vCard (if it exists), using the IMPP property - * @param[in] vCard the LinphoneVcard + * @param[in] vCard the #LinphoneVcard * @param[in] sip_address the SIP address to remove */ LINPHONE_PUBLIC void linphone_vcard_remove_sip_address(LinphoneVcard *vCard, const char *sip_address); /** * Edits the preferred SIP address in the vCard (or the first one), using the IMPP property - * @param[in] vCard the LinphoneVcard + * @param[in] vCard the #LinphoneVcard * @param[in] sip_address the new SIP address */ LINPHONE_PUBLIC void linphone_vcard_edit_main_sip_address(LinphoneVcard *vCard, const char *sip_address); /** * Returns the list of SIP addresses (as LinphoneAddress) in the vCard (all the IMPP attributes that has an URI value starting by "sip:") or NULL - * @param[in] vCard the LinphoneVcard + * @param[in] vCard the #LinphoneVcard * @return \bctbx_list{LinphoneAddress} */ LINPHONE_PUBLIC const bctbx_list_t* linphone_vcard_get_sip_addresses(LinphoneVcard *vCard); /** * Adds a phone number in the vCard, using the TEL property - * @param[in] vCard the LinphoneVcard + * @param[in] vCard the #LinphoneVcard * @param[in] phone the phone number to add */ LINPHONE_PUBLIC void linphone_vcard_add_phone_number(LinphoneVcard *vCard, const char *phone); /** * Removes a phone number in the vCard (if it exists), using the TEL property - * @param[in] vCard the LinphoneVcard + * @param[in] vCard the #LinphoneVcard * @param[in] phone the phone number to remove */ LINPHONE_PUBLIC void linphone_vcard_remove_phone_number(LinphoneVcard *vCard, const char *phone); /** * Returns the list of phone numbers (as string) in the vCard (all the TEL attributes) or NULL - * @param[in] vCard the LinphoneVcard + * @param[in] vCard the #LinphoneVcard * @return \bctbx_list{const char *} */ LINPHONE_PUBLIC bctbx_list_t* linphone_vcard_get_phone_numbers(const LinphoneVcard *vCard); /** * Fills the Organization field of the vCard - * @param[in] vCard the LinphoneVcard + * @param[in] vCard the #LinphoneVcard * @param[in] organization the Organization */ LINPHONE_PUBLIC void linphone_vcard_set_organization(LinphoneVcard *vCard, const char *organization); /** * Gets the Organization of the vCard - * @param[in] vCard the LinphoneVcard + * @param[in] vCard the #LinphoneVcard * @return the Organization of the vCard or NULL */ LINPHONE_PUBLIC const char* linphone_vcard_get_organization(const LinphoneVcard *vCard); @@ -201,49 +201,49 @@ LINPHONE_PUBLIC const char* linphone_vcard_get_organization(const LinphoneVcard /** * Generates a random unique id for the vCard. * If is required to be able to synchronize the vCard with a CardDAV server - * @param[in] vCard the LinphoneVcard + * @param[in] vCard the #LinphoneVcard * @return TRUE if operation is successful, otherwise FALSE (for example if it already has an unique ID) */ LINPHONE_PUBLIC bool_t linphone_vcard_generate_unique_id(LinphoneVcard *vCard); /** * Sets the unique ID of the vCard - * @param[in] vCard the LinphoneVcard + * @param[in] vCard the #LinphoneVcard * @param[in] uid the unique id */ LINPHONE_PUBLIC void linphone_vcard_set_uid(LinphoneVcard *vCard, const char *uid); /** * Gets the UID of the vCard - * @param[in] vCard the LinphoneVcard + * @param[in] vCard the #LinphoneVcard * @return the UID of the vCard, otherwise NULL */ LINPHONE_PUBLIC const char* linphone_vcard_get_uid(const LinphoneVcard *vCard); /** * Sets the eTAG of the vCard - * @param[in] vCard the LinphoneVcard + * @param[in] vCard the #LinphoneVcard * @param[in] etag the eTAG */ LINPHONE_PUBLIC void linphone_vcard_set_etag(LinphoneVcard *vCard, const char * etag); /** * Gets the eTag of the vCard - * @param[in] vCard the LinphoneVcard + * @param[in] vCard the #LinphoneVcard * @return the eTag of the vCard in the CardDAV server, otherwise NULL */ LINPHONE_PUBLIC const char* linphone_vcard_get_etag(const LinphoneVcard *vCard); /** * Sets the URL of the vCard - * @param[in] vCard the LinphoneVcard + * @param[in] vCard the #LinphoneVcard * @param[in] url the URL */ LINPHONE_PUBLIC void linphone_vcard_set_url(LinphoneVcard *vCard, const char *url); /** * Gets the URL of the vCard - * @param[in] vCard the LinphoneVcard + * @param[in] vCard the #LinphoneVcard * @return the URL of the vCard in the CardDAV server, otherwise NULL */ LINPHONE_PUBLIC const char* linphone_vcard_get_url(const LinphoneVcard *vCard); diff --git a/include/linphone/video_definition.h b/include/linphone/video_definition.h index 4b8c10e68..4b38e020f 100644 --- a/include/linphone/video_definition.h +++ b/include/linphone/video_definition.h @@ -36,69 +36,69 @@ extern "C" { /** * Acquire a reference to the video definition. - * @param[in] vdef LinphoneVideoDefinition object. - * @return The same LinphoneVideoDefinition object. + * @param[in] vdef #LinphoneVideoDefinition object. + * @return The same #LinphoneVideoDefinition object. **/ LINPHONE_PUBLIC LinphoneVideoDefinition * linphone_video_definition_ref(LinphoneVideoDefinition *vdef); /** * Release reference to the video definition. - * @param[in] vdef LinphoneVideoDefinition object. + * @param[in] vdef #LinphoneVideoDefinition object. **/ LINPHONE_PUBLIC void linphone_video_definition_unref(LinphoneVideoDefinition *vdef); /** * Retrieve the user pointer associated with the video definition. - * @param[in] vdef LinphoneVideoDefinition object. + * @param[in] vdef #LinphoneVideoDefinition object. * @return The user pointer associated with the video definition. **/ LINPHONE_PUBLIC void *linphone_video_definition_get_user_data(const LinphoneVideoDefinition *vdef); /** * Assign a user pointer to the video definition. - * @param[in] vdef LinphoneVideoDefinition object. + * @param[in] vdef #LinphoneVideoDefinition object. * @param[in] ud The user pointer to associate with the video definition. **/ LINPHONE_PUBLIC void linphone_video_definition_set_user_data(LinphoneVideoDefinition *vdef, void *ud); /** * Clone a video definition. - * @param[in] vdef LinphoneVideoDefinition object to be cloned + * @param[in] vdef #LinphoneVideoDefinition object to be cloned * @return The new clone of the video definition */ LINPHONE_PUBLIC LinphoneVideoDefinition * linphone_video_definition_clone(const LinphoneVideoDefinition *vdef); /** * Get the width of the video definition. - * @param[in] vdef LinphoneVideoDefinition object + * @param[in] vdef #LinphoneVideoDefinition object * @return The width of the video definition */ LINPHONE_PUBLIC unsigned int linphone_video_definition_get_width(const LinphoneVideoDefinition *vdef); /** * Set the width of the video definition. - * @param[in] vdef LinphoneVideoDefinition object + * @param[in] vdef #LinphoneVideoDefinition object * @param[in] width The width of the video definition */ LINPHONE_PUBLIC void linphone_video_definition_set_width(LinphoneVideoDefinition *vdef, unsigned int width); /** * Get the height of the video definition. - * @param[in] vdef LinphoneVideoDefinition object + * @param[in] vdef #LinphoneVideoDefinition object * @return The height of the video definition */ LINPHONE_PUBLIC unsigned int linphone_video_definition_get_height(const LinphoneVideoDefinition *vdef); /** * Set the height of the video definition. - * @param[in] vdef LinphoneVideoDefinition object + * @param[in] vdef #LinphoneVideoDefinition object * @param[in] height The height of the video definition */ LINPHONE_PUBLIC void linphone_video_definition_set_height(LinphoneVideoDefinition *vdef, unsigned int height); /** * Set the width and the height of the video definition. - * @param[in] vdef LinphoneVideoDefinition object + * @param[in] vdef #LinphoneVideoDefinition object * @param[in] width The width of the video definition * @param[in] height The height of the video definition */ @@ -106,38 +106,38 @@ LINPHONE_PUBLIC void linphone_video_definition_set_definition(LinphoneVideoDefin /** * Get the name of the video definition. - * @param[in] vdef LinphoneVideoDefinition object + * @param[in] vdef #LinphoneVideoDefinition object * @return The name of the video definition */ LINPHONE_PUBLIC const char * linphone_video_definition_get_name(const LinphoneVideoDefinition *vdef); /** * Set the name of the video definition. - * @param[in] vdef LinphoneVideoDefinition object + * @param[in] vdef #LinphoneVideoDefinition object * @param[in] name The name of the video definition */ LINPHONE_PUBLIC void linphone_video_definition_set_name(LinphoneVideoDefinition *vdef, const char *name); /** - * Tells whether two LinphoneVideoDefinition objects are equal (the widths and the heights are the same but can be switched). - * @param[in] vdef1 LinphoneVideoDefinition object - * @param[in] vdef2 LinphoneVideoDefinition object - * @return A boolean value telling whether the two LinphoneVideoDefinition objects are equal. + * Tells whether two #LinphoneVideoDefinition objects are equal (the widths and the heights are the same but can be switched). + * @param[in] vdef1 #LinphoneVideoDefinition object + * @param[in] vdef2 #LinphoneVideoDefinition object + * @return A boolean value telling whether the two #LinphoneVideoDefinition objects are equal. */ LINPHONE_PUBLIC bool_t linphone_video_definition_equals(const LinphoneVideoDefinition *vdef1, const LinphoneVideoDefinition *vdef2); /** - * Tells whether two LinphoneVideoDefinition objects are strictly equal (the widths are the same and the heights are the same). - * @param[in] vdef1 LinphoneVideoDefinition object - * @param[in] vdef2 LinphoneVideoDefinition object - * @return A boolean value telling whether the two LinphoneVideoDefinition objects are strictly equal. + * Tells whether two #LinphoneVideoDefinition objects are strictly equal (the widths are the same and the heights are the same). + * @param[in] vdef1 #LinphoneVideoDefinition object + * @param[in] vdef2 #LinphoneVideoDefinition object + * @return A boolean value telling whether the two #LinphoneVideoDefinition objects are strictly equal. */ LINPHONE_PUBLIC bool_t linphone_video_definition_strict_equals(const LinphoneVideoDefinition *vdef1, const LinphoneVideoDefinition *vdef2); /** - * Tells whether a LinphoneVideoDefinition is undefined. - * @param[in] vdef LinphoneVideoDefinition object - * @return A boolean value telling whether the LinphoneVideoDefinition is undefined. + * Tells whether a #LinphoneVideoDefinition is undefined. + * @param[in] vdef #LinphoneVideoDefinition object + * @return A boolean value telling whether the #LinphoneVideoDefinition is undefined. */ LINPHONE_PUBLIC bool_t linphone_video_definition_is_undefined(const LinphoneVideoDefinition *vdef); diff --git a/include/linphone/wrapper_utils.h b/include/linphone/wrapper_utils.h index ee7978269..686f8f16f 100644 --- a/include/linphone/wrapper_utils.h +++ b/include/linphone/wrapper_utils.h @@ -89,7 +89,7 @@ LINPHONE_PUBLIC void linphone_chat_room_send_chat_message_2(LinphoneChatRoom *cr * instead of totaly takes ownership on it. Thus, the #LinphoneChatMessage object must be released by the API user after calling * that function. * - * @param[in] msg LinphoneChatMessage object + * @param[in] msg #LinphoneChatMessage object */ LINPHONE_PUBLIC void linphone_chat_message_resend_2(LinphoneChatMessage *msg); diff --git a/include/linphone/xmlrpc.h b/include/linphone/xmlrpc.h index 67f8df2ad..ce3cecfc6 100644 --- a/include/linphone/xmlrpc.h +++ b/include/linphone/xmlrpc.h @@ -35,78 +35,78 @@ extern "C" { */ /** - * Create a new LinphoneXmlRpcRequest object. + * Create a new #LinphoneXmlRpcRequest object. * @param[in] return_type The expected XML-RPC response type. * @param[in] method The XML-RPC method to call. - * @return A new LinphoneXmlRpcRequest object. + * @return A new #LinphoneXmlRpcRequest object. **/ LINPHONE_PUBLIC LinphoneXmlRpcRequest * linphone_xml_rpc_request_new(LinphoneXmlRpcArgType return_type, const char *method); /** * Acquire a reference to the XML-RPC request. - * @param[in] request LinphoneXmlRpcRequest object. - * @return The same LinphoneXmlRpcRequest object. + * @param[in] request #LinphoneXmlRpcRequest object. + * @return The same #LinphoneXmlRpcRequest object. **/ LINPHONE_PUBLIC LinphoneXmlRpcRequest * linphone_xml_rpc_request_ref(LinphoneXmlRpcRequest *request); /** * Release reference to the XML-RPC request. - * @param[in] request LinphoneXmlRpcRequest object. + * @param[in] request #LinphoneXmlRpcRequest object. **/ LINPHONE_PUBLIC void linphone_xml_rpc_request_unref(LinphoneXmlRpcRequest *request); /** * Retrieve the user pointer associated with the XML-RPC request. - * @param[in] request LinphoneXmlRpcRequest object. + * @param[in] request #LinphoneXmlRpcRequest object. * @return The user pointer associated with the XML-RPC request. **/ LINPHONE_PUBLIC void *linphone_xml_rpc_request_get_user_data(const LinphoneXmlRpcRequest *request); /** * Assign a user pointer to the XML-RPC request. - * @param[in] request LinphoneXmlRpcRequest object. + * @param[in] request #LinphoneXmlRpcRequest object. * @param[in] ud The user pointer to associate with the XML-RPC request. **/ LINPHONE_PUBLIC void linphone_xml_rpc_request_set_user_data(LinphoneXmlRpcRequest *request, void *ud); /** * Add an integer argument to an XML-RPC request. - * @param[in] request LinphoneXmlRpcRequest object. + * @param[in] request #LinphoneXmlRpcRequest object. * @param[in] value The integer value of the added argument. **/ LINPHONE_PUBLIC void linphone_xml_rpc_request_add_int_arg(LinphoneXmlRpcRequest *request, int value); /** * Add a string argument to an XML-RPC request. - * @param[in] request LinphoneXmlRpcRequest object. + * @param[in] request #LinphoneXmlRpcRequest object. * @param[in] value The string value of the added argument. **/ LINPHONE_PUBLIC void linphone_xml_rpc_request_add_string_arg(LinphoneXmlRpcRequest *request, const char *value); /** - * Get the LinphoneXmlRpcRequestCbs object associated with a LinphoneXmlRpcRequest. - * @param[in] request LinphoneXmlRpcRequest object - * @return The LinphoneXmlRpcRequestCbs object associated with the LinphoneXmlRpcRequest. + * Get the #LinphoneXmlRpcRequestCbs object associated with a LinphoneXmlRpcRequest. + * @param[in] request #LinphoneXmlRpcRequest object + * @return The #LinphoneXmlRpcRequestCbs object associated with the LinphoneXmlRpcRequest. **/ LINPHONE_PUBLIC LinphoneXmlRpcRequestCbs * linphone_xml_rpc_request_get_callbacks(const LinphoneXmlRpcRequest *request); /** * Get the content of the XML-RPC request. - * @param[in] request LinphoneXmlRpcRequest object. + * @param[in] request #LinphoneXmlRpcRequest object. * @return The string representation of the content of the XML-RPC request. */ LINPHONE_PUBLIC const char * linphone_xml_rpc_request_get_content(const LinphoneXmlRpcRequest *request); /** * Get the status of the XML-RPC request. - * @param[in] request LinphoneXmlRpcRequest object. + * @param[in] request #LinphoneXmlRpcRequest object. * @return The status of the XML-RPC request. **/ LINPHONE_PUBLIC LinphoneXmlRpcStatus linphone_xml_rpc_request_get_status(const LinphoneXmlRpcRequest *request); /** * Get the response to an XML-RPC request sent with linphone_xml_rpc_session_send_request() and returning an integer response. - * @param[in] request LinphoneXmlRpcRequest object. + * @param[in] request #LinphoneXmlRpcRequest object. * @return The integer response to the XML-RPC request. **/ LINPHONE_PUBLIC int linphone_xml_rpc_request_get_int_response(const LinphoneXmlRpcRequest *request); @@ -119,101 +119,101 @@ LINPHONE_PUBLIC int linphone_xml_rpc_request_get_int_response(const LinphoneXmlR LINPHONE_PUBLIC const char * linphone_xml_rpc_request_get_string_response(const LinphoneXmlRpcRequest *request); /** - * Create a new LinphoneXmlRpcSession object. - * @param[in] core The LinphoneCore object used to send the XML-RPC requests. + * Create a new #LinphoneXmlRpcSession object. + * @param[in] core The #LinphoneCore object used to send the XML-RPC requests. * @param[in] url The URL of the XML-RPC server to send the XML-RPC requests to. - * @return A new LinphoneXmlRpcSession object. + * @return A new #LinphoneXmlRpcSession object. */ LINPHONE_PUBLIC LinphoneXmlRpcSession * linphone_xml_rpc_session_new(LinphoneCore *core, const char *url); /** * Acquire a reference to the XML-RPC session. - * @param[in] session LinphoneXmlRpcSession object. - * @return The same LinphoneXmlRpcSession object. + * @param[in] session #LinphoneXmlRpcSession object. + * @return The same #LinphoneXmlRpcSession object. **/ LINPHONE_PUBLIC LinphoneXmlRpcSession * linphone_xml_rpc_session_ref(LinphoneXmlRpcSession *session); /** * Release reference to the XML-RPC session. - * @param[in] session LinphoneXmlRpcSession object. + * @param[in] session #LinphoneXmlRpcSession object. * @warning This will not stop pending xml-rpc requests. Use linphone_xml_rpc_session_release() instead if this is intended. **/ LINPHONE_PUBLIC void linphone_xml_rpc_session_unref(LinphoneXmlRpcSession *session); /** * Retrieve the user pointer associated with the XML-RPC session. - * @param[in] session LinphoneXmlRpcSession object. + * @param[in] session #LinphoneXmlRpcSession object. * @return The user pointer associated with the XML-RPC session. **/ LINPHONE_PUBLIC void *linphone_xml_rpc_session_get_user_data(const LinphoneXmlRpcSession *session); /** * Assign a user pointer to the XML-RPC session. - * @param[in] session LinphoneXmlRpcSession object. + * @param[in] session #LinphoneXmlRpcSession object. * @param[in] ud The user pointer to associate with the XML-RPC session. **/ LINPHONE_PUBLIC void linphone_xml_rpc_session_set_user_data(LinphoneXmlRpcSession *session, void *ud); /** * Send an XML-RPC request. - * @param[in] session LinphoneXmlRpcSession object. - * @param[in] request The LinphoneXmlRpcRequest to be sent. + * @param[in] session #LinphoneXmlRpcSession object. + * @param[in] request The #LinphoneXmlRpcRequest to be sent. **/ LINPHONE_PUBLIC void linphone_xml_rpc_session_send_request(LinphoneXmlRpcSession *session, LinphoneXmlRpcRequest *request); /** * Stop and unref an XML rpc session. Pending requests will be aborted. - * @param[in] session LinphoneXmlRpcSession object. + * @param[in] session #LinphoneXmlRpcSession object. **/ LINPHONE_PUBLIC void linphone_xml_rpc_session_release(LinphoneXmlRpcSession *session); /** - * Acquire a reference to a LinphoneXmlRpcRequestCbs object. - * @param[in] cbs LinphoneXmlRpcRequestCbs object. - * @return The same LinphoneXmlRpcRequestCbs object. + * Acquire a reference to a #LinphoneXmlRpcRequestCbs object. + * @param[in] cbs #LinphoneXmlRpcRequestCbs object. + * @return The same #LinphoneXmlRpcRequestCbs object. **/ LINPHONE_PUBLIC LinphoneXmlRpcRequestCbs * linphone_xml_rpc_request_cbs_ref(LinphoneXmlRpcRequestCbs *cbs); /** - * Release a reference to a LinphoneXmlRpcRequestCbs object. - * @param[in] cbs LinphoneXmlRpcRequestCbs object. + * Release a reference to a #LinphoneXmlRpcRequestCbs object. + * @param[in] cbs #LinphoneXmlRpcRequestCbs object. **/ LINPHONE_PUBLIC void linphone_xml_rpc_request_cbs_unref(LinphoneXmlRpcRequestCbs *cbs); /** - * Retrieve the user pointer associated with a LinphoneXmlRpcRequestCbs object. - * @param[in] cbs LinphoneXmlRpcRequestCbs object. - * @return The user pointer associated with the LinphoneXmlRpcRequestCbs object. + * Retrieve the user pointer associated with a #LinphoneXmlRpcRequestCbs object. + * @param[in] cbs #LinphoneXmlRpcRequestCbs object. + * @return The user pointer associated with the #LinphoneXmlRpcRequestCbs object. **/ LINPHONE_PUBLIC void *linphone_xml_rpc_request_cbs_get_user_data(const LinphoneXmlRpcRequestCbs *cbs); /** - * Assign a user pointer to a LinphoneXmlRpcRequestCbs object. - * @param[in] cbs LinphoneXmlRpcRequestCbs object. - * @param[in] ud The user pointer to associate with the LinphoneXmlRpcRequestCbs object. + * Assign a user pointer to a #LinphoneXmlRpcRequestCbs object. + * @param[in] cbs #LinphoneXmlRpcRequestCbs object. + * @param[in] ud The user pointer to associate with the #LinphoneXmlRpcRequestCbs object. **/ LINPHONE_PUBLIC void linphone_xml_rpc_request_cbs_set_user_data(LinphoneXmlRpcRequestCbs *cbs, void *ud); /** * Get the response callback. - * @param[in] cbs LinphoneXmlRpcRequestCbs object. + * @param[in] cbs #LinphoneXmlRpcRequestCbs object. * @return The current response callback. **/ LINPHONE_PUBLIC LinphoneXmlRpcRequestCbsResponseCb linphone_xml_rpc_request_cbs_get_response(const LinphoneXmlRpcRequestCbs *cbs); /** * Set the response callback. - * @param[in] cbs LinphoneXmlRpcRequestCbs object. + * @param[in] cbs #LinphoneXmlRpcRequestCbs object. * @param[in] cb The response callback to be used. **/ LINPHONE_PUBLIC void linphone_xml_rpc_request_cbs_set_response(LinphoneXmlRpcRequestCbs *cbs, LinphoneXmlRpcRequestCbsResponseCb cb); /** - * Creates a LinphoneXmlRpcRequest from a LinphoneXmlRpcSession - * @param[in] session the LinphoneXmlRpcSession - * @param[in] return_type the return type of the request as a LinphoneXmlRpcArgType + * Creates a #LinphoneXmlRpcRequest from a #LinphoneXmlRpcSession + * @param[in] session the #LinphoneXmlRpcSession + * @param[in] return_type the return type of the request as a #LinphoneXmlRpcArgType * @param[in] method the function name to call - * @return a LinphoneXmlRpcRequest object + * @return a #LinphoneXmlRpcRequest object */ LINPHONE_PUBLIC LinphoneXmlRpcRequest * linphone_xml_rpc_session_create_request(LinphoneXmlRpcSession *session, LinphoneXmlRpcArgType return_type, const char *method); diff --git a/java/common/org/linphone/core/LinphoneCall.java b/java/common/org/linphone/core/LinphoneCall.java index 332a76b57..ead69a5f0 100644 --- a/java/common/org/linphone/core/LinphoneCall.java +++ b/java/common/org/linphone/core/LinphoneCall.java @@ -31,8 +31,12 @@ public interface LinphoneCall { /** * LinphoneCall listener */ - interface LinphoneCallListener { + public interface LinphoneCallListener { void onNextVideoFrameDecoded(LinphoneCall call); + /** + * Invoked when a TMMBR RTCP packet is received. + */ + void tmmbrReceived(LinphoneCall call, int streamIndex, int bitrate); } /** diff --git a/java/common/org/linphone/core/LinphoneChatMessage.java b/java/common/org/linphone/core/LinphoneChatMessage.java index aeec09645..0efe5a94d 100644 --- a/java/common/org/linphone/core/LinphoneChatMessage.java +++ b/java/common/org/linphone/core/LinphoneChatMessage.java @@ -225,7 +225,7 @@ public interface LinphoneChatMessage { /** * Start the download of the file referenced in a LinphoneChatMessage from remote server. */ - int downloadFile(); + boolean downloadFile(); /** * Set the callbacks associated with the LinphoneChatMessage. diff --git a/java/impl/org/linphone/core/LinphoneChatMessageImpl.java b/java/impl/org/linphone/core/LinphoneChatMessageImpl.java index 9ca40a269..a7771766f 100644 --- a/java/impl/org/linphone/core/LinphoneChatMessageImpl.java +++ b/java/impl/org/linphone/core/LinphoneChatMessageImpl.java @@ -16,7 +16,7 @@ public class LinphoneChatMessageImpl implements LinphoneChatMessage { private native void store(long ptr); private native int getStorageId(long ptr); private native void setFileTransferFilepath(long ptr, String path); - private native int downloadFile(long ptr); + private native boolean downloadFile(long ptr); private native void setListener(long ptr, LinphoneChatMessageListener listener); private native void unref(long ptr); @@ -146,7 +146,7 @@ public class LinphoneChatMessageImpl implements LinphoneChatMessage { } @Override - public int downloadFile() { + public boolean downloadFile() { return downloadFile(nativePtr); } diff --git a/share/cpim_grammar b/share/cpim_grammar index 6f8b36d95..c89e4f87f 100644 Binary files a/share/cpim_grammar and b/share/cpim_grammar differ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ca182139f..990974b2c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -20,6 +20,52 @@ # ############################################################################ +set(LIBS + ${BCTOOLBOX_CORE_LIBRARIES} + ${BELLESIP_LIBRARIES} + ${MEDIASTREAMER2_LIBRARIES} + ${ORTP_LIBRARIES} + ${XML2_LIBRARIES} + ${BELR_LIBRARIES} + ${LIBXSD_LIBRARIES} +) +if(WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsStore") + list(APPEND LIBS "Ws2_32") +endif() +if(ENABLE_LIME) + list(APPEND LIBS ${BZRTP_LIBRARIES}) +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() +if(ICONV_FOUND) + list(APPEND LIBS ${ICONV_LIBRARIES}) +endif() +if(ENABLE_TUNNEL) + list(APPEND LIBS ${TUNNEL_LIBRARIES}) +endif() +if(MSVC AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone" AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsStore") + list(APPEND LIBS ${LIBGCC} ${LIBMINGWEX}) +endif() +if(WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone" AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsStore") + list(APPEND LIBS shlwapi) +endif() +if(INTL_FOUND) + list(APPEND LIBS ${INTL_LIBRARIES}) +endif() +if(BELCARD_FOUND) + list(APPEND LIBS ${BELCARD_LIBRARIES}) +endif() +if(ENABLE_TUNNEL) + add_definitions(-DTUNNEL_ENABLED) +endif() + set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES address/address-p.h address/address.h @@ -35,6 +81,11 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES call/remote-conference-call.h chat/chat-message/chat-message-p.h chat/chat-message/chat-message.h + chat/chat-message/imdn-message.h + chat/chat-message/imdn-message-p.h + chat/chat-message/is-composing-message.h + chat/chat-message/notification-message.h + chat/chat-message/notification-message-p.h chat/chat-room/abstract-chat-room-p.h chat/chat-room/abstract-chat-room.h chat/chat-room/basic-chat-room-p.h @@ -73,8 +124,10 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES conference/conference.h conference/handlers/local-conference-event-handler-p.h conference/handlers/local-conference-event-handler.h + conference/handlers/local-conference-list-event-handler.h conference/handlers/remote-conference-event-handler-p.h conference/handlers/remote-conference-event-handler.h + conference/handlers/remote-conference-list-event-handler.h conference/local-conference-p.h conference/local-conference.h conference/params/call-session-params-p.h @@ -82,6 +135,8 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES conference/params/media-session-params-p.h conference/params/media-session-params.h conference/participant-device.h + conference/participant-imdn-state.h + conference/participant-imdn-state-p.h conference/participant-p.h conference/participant.h conference/remote-conference-p.h @@ -99,6 +154,9 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES content/content.h content/file-content.h content/file-transfer-content.h + content/header/header.h + content/header/header-p.h + content/header/header-param.h core/core-accessor.h core/core-listener.h core/core-p.h @@ -150,13 +208,16 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES sal/sal.h search/magic-search-p.h search/magic-search.h - search/search-result-p.h search/search-result.h utils/background-task.h utils/payload-type-handler.h variant/variant.h xml/conference-info.h + xml/imdn.h + xml/is-composing.h + xml/linphone-imdn.h xml/resource-lists.h + xml/rlmi.h xml/xml.h ) @@ -173,10 +234,12 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES c-wrapper/api/c-chat-room-cbs.cpp c-wrapper/api/c-chat-room.cpp c-wrapper/api/c-core.cpp + c-wrapper/api/c-content.cpp c-wrapper/api/c-dial-plan.cpp c-wrapper/api/c-event-log.cpp c-wrapper/api/c-magic-search.cpp c-wrapper/api/c-participant.cpp + c-wrapper/api/c-participant-imdn-state.cpp c-wrapper/api/c-search-result.cpp c-wrapper/internal/c-sal.cpp c-wrapper/internal/c-tools.cpp @@ -184,6 +247,9 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES call/local-conference-call.cpp call/remote-conference-call.cpp chat/chat-message/chat-message.cpp + chat/chat-message/imdn-message.cpp + chat/chat-message/is-composing-message.cpp + chat/chat-message/notification-message.cpp chat/chat-room/abstract-chat-room.cpp chat/chat-room/basic-chat-room.cpp chat/chat-room/basic-to-client-group-chat-room.cpp @@ -207,11 +273,14 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES chat/notification/is-composing.cpp conference/conference.cpp conference/handlers/local-conference-event-handler.cpp + conference/handlers/local-conference-list-event-handler.cpp conference/handlers/remote-conference-event-handler.cpp + conference/handlers/remote-conference-list-event-handler.cpp conference/local-conference.cpp conference/params/call-session-params.cpp conference/params/media-session-params.cpp conference/participant-device.cpp + conference/participant-imdn-state.cpp conference/participant.cpp conference/remote-conference.cpp conference/session/call-session.cpp @@ -222,6 +291,8 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES content/content.cpp content/file-content.cpp content/file-transfer-content.cpp + content/header/header.cpp + content/header/header-param.cpp core/core-accessor.cpp core/core-call.cpp core/core-chat-room.cpp @@ -270,7 +341,11 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES utils/utils.cpp variant/variant.cpp xml/conference-info.cpp + xml/imdn.cpp + xml/is-composing.cpp + xml/linphone-imdn.cpp xml/resource-lists.cpp + xml/rlmi.cpp xml/xml.cpp ) @@ -278,6 +353,7 @@ set(LINPHONE_OBJC_SOURCE_FILES) if (APPLE) list(APPEND LINPHONE_OBJC_SOURCE_FILES core/paths/paths-apple.mm) list(APPEND LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES core/paths/paths-apple.h) + list(APPEND LINPHONE_CXX_OBJECTS_SOURCE_FILES core/platform-helpers/ios-platform-helpers.cpp) elseif (ANDROID) list(APPEND LINPHONE_CXX_OBJECTS_SOURCE_FILES core/paths/paths-android.cpp core/platform-helpers/android-platform-helpers.cpp) list(APPEND LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES core/paths/paths-android.h) @@ -307,21 +383,99 @@ set(LINPHONE_PRIVATE_HEADER_FILES ${LINPHONE_PRIVATE_HEADER_FILES} PARENT_SCOPE) bc_apply_compile_flags(LINPHONE_CXX_OBJECTS_SOURCE_FILES STRICT_OPTIONS_CPP STRICT_OPTIONS_CXX) bc_apply_compile_flags(LINPHONE_OBJC_SOURCE_FILES STRICT_OPTIONS_CPP STRICT_OPTIONS_OBJC) -if (ENABLE_STATIC) - add_library( - linphone-cxx-objects-static OBJECT - ${LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES} ${LINPHONE_CXX_OBJECTS_SOURCE_FILES} ${LINPHONE_OBJC_SOURCE_FILES} - ) - target_compile_definitions(linphone-cxx-objects-static PRIVATE ${LINPHONE_CXX_OBJECTS_DEFINITIONS}) - 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 +if(ENABLE_STATIC) + add_library(linphone-static STATIC ${LINPHONE_HEADER_FILES} ${LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES} ${LINPHONE_CXX_OBJECTS_SOURCE_FILES} ${LINPHONE_OBJC_SOURCE_FILES} + $ ) - target_compile_definitions(linphone-cxx-objects PRIVATE ${LINPHONE_CXX_OBJECTS_DEFINITIONS}) - 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 () + set_target_properties(linphone-static PROPERTIES OUTPUT_NAME linphone) + target_include_directories(linphone-static PUBLIC ${LINPHONE_INCLUDE_DIRS}) + target_link_libraries(linphone-static INTERFACE ${LIBS}) + if(APPLE) + target_link_libraries(linphone-static INTERFACE "-framework Foundation" "-framework AVFoundation") + endif() + install(TARGETS linphone-static EXPORT ${EXPORT_TARGETS_NAME}Targets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE + ) +endif() +if(ENABLE_SHARED) + add_library(linphone SHARED "../share/cpim_grammar" ${LINPHONE_HEADER_FILES} + ${LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES} ${LINPHONE_CXX_OBJECTS_SOURCE_FILES} ${LINPHONE_OBJC_SOURCE_FILES} + $ + ) + #TODO: replace by if(APPLE) when we want to make apple framework on linphone-desktop too + if(IOS) + if(IOS) + set(MIN_OS ${LINPHONE_IOS_DEPLOYMENT_TARGET}) + else() + set(MIN_OS ${CMAKE_OSX_DEPLOYMENT_TARGET}) + endif() + set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/build/osx/") + set_target_properties(linphone PROPERTIES + FRAMEWORK TRUE + MACOSX_FRAMEWORK_IDENTIFIER org.linphone.linphone + MACOSX_FRAMEWORK_INFO_PLIST Info.plist.in + PUBLIC_HEADER "${LINPHONE_HEADER_FILES}" + RESOURCE "../share/cpim_grammar" + ) + endif() + if(BELCARD_FOUND) + if(APPLE) + set_target_properties(linphone PROPERTIES LINK_FLAGS "-stdlib=libc++") + endif() + endif() + + set_target_properties(linphone PROPERTIES LINKER_LANGUAGE CXX) + if(NOT ANDROID) + # Do not version shared library on Android + set_target_properties(linphone PROPERTIES SOVERSION ${LINPHONE_SO_VERSION}) + endif() + target_include_directories(linphone PUBLIC ${LINPHONE_INCLUDE_DIRS}) + target_link_libraries(linphone PRIVATE ${LIBS}) + if(APPLE) + target_link_libraries(linphone PRIVATE "-framework Foundation" "-framework AVFoundation") + endif() + if(WIN32 AND CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone" AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsStore") + set_target_properties(linphone PROPERTIES PREFIX "lib") + elseif(ANDROID) + target_link_libraries(linphone PUBLIC "log" ${SUPPORT_LIBRARIES} ${CPUFEATURES_LIBRARIES}) + if(ENABLE_JAVA_WRAPPER) + add_dependencies(linphone linphonej) + endif() + endif() + if(MSVC) + if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/linphone.pdb + DESTINATION ${CMAKE_INSTALL_BINDIR} + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE + ) + endif() + endif() + install(TARGETS linphone EXPORT ${EXPORT_TARGETS_NAME}Targets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + FRAMEWORK DESTINATION Frameworks + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE + ) +endif() +if(ICONV_FOUND) + if(APPLE) + # Prevent conflict between the system iconv.h header and the one from macports. + if(ENABLE_STATIC) + target_compile_options(linphone-static PRIVATE "-include" "${ICONV_INCLUDE_DIRS}/iconv.h") + endif() + if(ENABLE_SHARED) + target_compile_options(linphone PRIVATE "-include" "${ICONV_INCLUDE_DIRS}/iconv.h") + endif() + else() + if(ENABLE_STATIC) + target_include_directories(linphone-static PRIVATE ${ICONV_INCLUDE_DIRS}) + endif() + if(ENABLE_SHARED) + target_include_directories(linphone PRIVATE ${ICONV_INCLUDE_DIRS}) + endif() + endif() +endif() diff --git a/src/c-wrapper/api/c-address.cpp b/src/c-wrapper/api/c-address.cpp index cdff96c75..dbbe793bc 100644 --- a/src/c-wrapper/api/c-address.cpp +++ b/src/c-wrapper/api/c-address.cpp @@ -37,7 +37,7 @@ LinphoneAddress *linphone_address_new (const char *address) { LinphoneAddress *object = L_INIT(Address); L_SET_CPP_PTR_FROM_C_OBJECT(object, cppPtr); - delete cppPtr; + return object; } @@ -131,11 +131,11 @@ void linphone_address_clean (LinphoneAddress *address) { } char *linphone_address_as_string (const LinphoneAddress *address) { - return ms_strdup(L_GET_CPP_PTR_FROM_C_OBJECT(address)->asString().c_str()); + return bctbx_strdup(L_GET_CPP_PTR_FROM_C_OBJECT(address)->asString().c_str()); } char *linphone_address_as_string_uri_only (const LinphoneAddress *address) { - return ms_strdup(L_GET_CPP_PTR_FROM_C_OBJECT(address)->asStringUriOnly().c_str()); + return bctbx_strdup(L_GET_CPP_PTR_FROM_C_OBJECT(address)->asStringUriOnly().c_str()); } bool_t linphone_address_weak_equal (const LinphoneAddress *address1, const LinphoneAddress *address2) { diff --git a/src/c-wrapper/api/c-call-cbs.cpp b/src/c-wrapper/api/c-call-cbs.cpp index 903dfa26a..8db00054c 100644 --- a/src/c-wrapper/api/c-call-cbs.cpp +++ b/src/c-wrapper/api/c-call-cbs.cpp @@ -34,6 +34,8 @@ struct _LinphoneCallCbs { LinphoneCallCbsTransferStateChangedCb transferStateChangedCb; LinphoneCallCbsAckProcessingCb ackProcessing; LinphoneCallCbsTmmbrReceivedCb tmmbrReceivedCb; + LinphoneCallCbsSnapshotTakenCb snapshotTakenCb; + LinphoneCallCbsNextVideoFrameDecodedCb nextVideoFrameDecodedCb; }; BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneCallCbs); @@ -133,3 +135,19 @@ LinphoneCallCbsTmmbrReceivedCb linphone_call_cbs_get_tmmbr_received (LinphoneCal void linphone_call_cbs_set_tmmbr_received (LinphoneCallCbs *cbs, LinphoneCallCbsTmmbrReceivedCb cb) { cbs->tmmbrReceivedCb = cb; } + +LinphoneCallCbsSnapshotTakenCb linphone_call_cbs_get_snapshot_taken(LinphoneCallCbs *cbs) { + return cbs->snapshotTakenCb; +} + +void linphone_call_cbs_set_snapshot_taken(LinphoneCallCbs *cbs, LinphoneCallCbsSnapshotTakenCb cb) { + cbs->snapshotTakenCb = cb; +} + +LinphoneCallCbsNextVideoFrameDecodedCb linphone_call_cbs_get_next_video_frame_decoded(LinphoneCallCbs *cbs) { + return cbs->nextVideoFrameDecodedCb; +} + +void linphone_call_cbs_set_next_video_frame_decoded(LinphoneCallCbs *cbs, LinphoneCallCbsNextVideoFrameDecodedCb cb) { + cbs->nextVideoFrameDecodedCb = cb; +} diff --git a/src/c-wrapper/api/c-call-params.cpp b/src/c-wrapper/api/c-call-params.cpp index a937e8fdd..cf614024a 100644 --- a/src/c-wrapper/api/c-call-params.cpp +++ b/src/c-wrapper/api/c-call-params.cpp @@ -511,11 +511,9 @@ void linphone_call_params_unref (LinphoneCallParams *cp) { // ============================================================================= LinphoneCallParams *linphone_call_params_new (LinphoneCore *core) { - LinphoneCallParams *params = _linphone_CallParams_init(); - auto mediaSessionParams = new LinphonePrivate::MediaSessionParams(); - L_SET_CPP_PTR_FROM_C_OBJECT(params, mediaSessionParams); + LinphoneCallParams *params = L_INIT(CallParams); + L_SET_CPP_PTR_FROM_C_OBJECT(params, new LinphonePrivate::MediaSessionParams()); L_GET_CPP_PTR_FROM_C_OBJECT(params)->initDefault(L_GET_CPP_PTR_FROM_C_OBJECT(core)); - delete mediaSessionParams; return params; } diff --git a/src/c-wrapper/api/c-call.cpp b/src/c-wrapper/api/c-call.cpp index 0fa450fa5..ffb4b8e30 100644 --- a/src/c-wrapper/api/c-call.cpp +++ b/src/c-wrapper/api/c-call.cpp @@ -43,12 +43,6 @@ L_DECLARE_C_OBJECT_IMPL_WITH_XTORS(Call, bctbx_list_t *callbacks; /* A list of LinphoneCallCbs object */ LinphoneCallCbs *currentCbs; /* The current LinphoneCallCbs object used to call a callback */ char *authenticationTokenCache; - LinphoneCallParams *currentParamsCache; - LinphoneCallParams *paramsCache; - LinphoneCallParams *remoteParamsCache; - LinphoneAddress *diversionAddressCache; - LinphoneAddress *remoteAddressCache; - LinphoneAddress *toAddressCache; mutable char *referToCache; char *remoteContactCache; char *remoteUserAgentCache; @@ -59,28 +53,9 @@ L_DECLARE_C_OBJECT_IMPL_WITH_XTORS(Call, LinphoneChatRoom *chat_room; ) -static void _linphone_call_constructor (LinphoneCall *call) { - call->currentParamsCache = linphone_call_params_new_for_wrapper(); - call->paramsCache = linphone_call_params_new_for_wrapper(); - call->remoteParamsCache = linphone_call_params_new_for_wrapper(); - call->diversionAddressCache = linphone_address_new(nullptr); - call->remoteAddressCache = linphone_address_new(nullptr); - call->toAddressCache = linphone_address_new(nullptr); -} +static void _linphone_call_constructor (LinphoneCall *call) {} static void _linphone_call_destructor (LinphoneCall *call) { - if (call->currentParamsCache) - linphone_call_params_unref(call->currentParamsCache); - if (call->paramsCache) - linphone_call_params_unref(call->paramsCache); - if (call->remoteParamsCache) - linphone_call_params_unref(call->remoteParamsCache); - if (call->diversionAddressCache) - linphone_address_unref(call->diversionAddressCache); - if (call->remoteAddressCache) - linphone_address_unref(call->remoteAddressCache); - if (call->toAddressCache) - linphone_address_unref(call->toAddressCache); if (call->referToCache) bctbx_free(call->referToCache); if (call->remoteContactCache) @@ -92,7 +67,6 @@ static void _linphone_call_destructor (LinphoneCall *call) { bctbx_list_free_with_data(call->callbacks, (bctbx_list_free_func)linphone_call_cbs_unref); } - // ============================================================================= // TODO: To remove! // ============================================================================= @@ -210,6 +184,13 @@ void linphone_call_notify_tmmbr_received (LinphoneCall *call, int stream_index, NOTIFY_IF_EXIST(TmmbrReceived, tmmbr_received, call, stream_index, tmmbr) } +void linphone_call_notify_snapshot_taken(LinphoneCall *call, const char *file_path) { + NOTIFY_IF_EXIST(SnapshotTaken, snapshot_taken, call, file_path) +} + +void linphone_call_notify_next_video_frame_decoded(LinphoneCall *call) { + NOTIFY_IF_EXIST(NextVideoFrameDecoded, next_video_frame_decoded, call) +} // ============================================================================= // Public functions. @@ -226,18 +207,16 @@ LinphoneCallState linphone_call_get_state (const LinphoneCall *call) { bool_t linphone_call_asked_to_autoanswer (LinphoneCall *call) { //return TRUE if the unique(for the moment) incoming call asked to be autoanswered if (call) - return linphone_call_get_op(call)->autoanswer_asked(); + return linphone_call_get_op(call)->autoAnswerAsked(); return FALSE; } const LinphoneAddress *linphone_call_get_remote_address (const LinphoneCall *call) { - L_SET_CPP_PTR_FROM_C_OBJECT(call->remoteAddressCache, &L_GET_CPP_PTR_FROM_C_OBJECT(call)->getRemoteAddress()); - return call->remoteAddressCache; + return L_GET_C_BACK_PTR(&L_GET_CPP_PTR_FROM_C_OBJECT(call)->getRemoteAddress()); } const LinphoneAddress *linphone_call_get_to_address (const LinphoneCall *call) { - L_SET_CPP_PTR_FROM_C_OBJECT(call->toAddressCache, &L_GET_CPP_PTR_FROM_C_OBJECT(call)->getToAddress()); - return call->toAddressCache; + return L_GET_C_BACK_PTR(&L_GET_CPP_PTR_FROM_C_OBJECT(call)->getToAddress()); } const char *linphone_call_get_to_header (const LinphoneCall *call, const char *name) { @@ -255,11 +234,8 @@ char *linphone_call_get_remote_address_as_string (const LinphoneCall *call) { } const LinphoneAddress *linphone_call_get_diversion_address (const LinphoneCall *call) { - LinphonePrivate::Address diversionAddress(L_GET_CPP_PTR_FROM_C_OBJECT(call)->getDiversionAddress()); - if (!diversionAddress.isValid()) - return nullptr; - L_SET_CPP_PTR_FROM_C_OBJECT(call->diversionAddressCache, &diversionAddress); - return call->diversionAddressCache; + const LinphonePrivate::Address &diversionAddress = L_GET_CPP_PTR_FROM_C_OBJECT(call)->getDiversionAddress(); + return diversionAddress.isValid() ? L_GET_C_BACK_PTR(&diversionAddress) : nullptr; } LinphoneCallDir linphone_call_get_dir (const LinphoneCall *call) { @@ -309,17 +285,13 @@ int linphone_call_get_duration (const LinphoneCall *call) { return L_GET_CPP_PTR_FROM_C_OBJECT(call)->getDuration(); } -const LinphoneCallParams *linphone_call_get_current_params(LinphoneCall *call) { - L_SET_CPP_PTR_FROM_C_OBJECT(call->currentParamsCache, L_GET_CPP_PTR_FROM_C_OBJECT(call)->getCurrentParams()); - return call->currentParamsCache; +const LinphoneCallParams *linphone_call_get_current_params (LinphoneCall *call) { + return L_GET_C_BACK_PTR(L_GET_CPP_PTR_FROM_C_OBJECT(call)->getCurrentParams()); } const LinphoneCallParams *linphone_call_get_remote_params(LinphoneCall *call) { const LinphonePrivate::MediaSessionParams *remoteParams = L_GET_CPP_PTR_FROM_C_OBJECT(call)->getRemoteParams(); - if (!remoteParams) - return nullptr; - L_SET_CPP_PTR_FROM_C_OBJECT(call->remoteParamsCache, remoteParams); - return call->remoteParamsCache; + return remoteParams ? L_GET_C_BACK_PTR(remoteParams) : nullptr; } void linphone_call_enable_camera (LinphoneCall *call, bool_t enable) { @@ -603,8 +575,8 @@ void linphone_call_ogl_render (const LinphoneCall *call) { LinphoneStatus linphone_call_send_info_message (LinphoneCall *call, const LinphoneInfoMessage *info) { SalBodyHandler *body_handler = sal_body_handler_from_content(linphone_info_message_get_content(info)); - linphone_call_get_op(call)->set_sent_custom_header(linphone_info_message_get_headers(info)); - return linphone_call_get_op(call)->send_info(nullptr, nullptr, body_handler); + linphone_call_get_op(call)->setSentCustomHeaders(linphone_info_message_get_headers(info)); + return linphone_call_get_op(call)->sendInfo(body_handler); } LinphoneCallStats *linphone_call_get_stats (LinphoneCall *call, LinphoneStreamType type) { @@ -645,8 +617,7 @@ void linphone_call_set_params (LinphoneCall *call, const LinphoneCallParams *par } const LinphoneCallParams *linphone_call_get_params (LinphoneCall *call) { - L_SET_CPP_PTR_FROM_C_OBJECT(call->paramsCache, L_GET_CPP_PTR_FROM_C_OBJECT(call)->getParams()); - return call->paramsCache; + return L_GET_C_BACK_PTR(L_GET_CPP_PTR_FROM_C_OBJECT(call)->getParams()); } // ============================================================================= diff --git a/src/c-wrapper/api/c-chat-message-cbs.cpp b/src/c-wrapper/api/c-chat-message-cbs.cpp index 16511eff6..aced7c8bb 100644 --- a/src/c-wrapper/api/c-chat-message-cbs.cpp +++ b/src/c-wrapper/api/c-chat-message-cbs.cpp @@ -30,6 +30,7 @@ struct _LinphoneChatMessageCbs { LinphoneChatMessageCbsFileTransferRecvCb file_transfer_recv; LinphoneChatMessageCbsFileTransferSendCb file_transfer_send; LinphoneChatMessageCbsFileTransferProgressIndicationCb file_transfer_progress_indication; + LinphoneChatMessageCbsParticipantImdnStateChangedCb participant_imdn_state_changed; }; BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneChatMessageCbs); @@ -66,40 +67,67 @@ void linphone_chat_message_cbs_set_user_data (LinphoneChatMessageCbs *cbs, void cbs->userData = ud; } -LinphoneChatMessageCbsMsgStateChangedCb -linphone_chat_message_cbs_get_msg_state_changed(const LinphoneChatMessageCbs *cbs) { +LinphoneChatMessageCbsMsgStateChangedCb linphone_chat_message_cbs_get_msg_state_changed ( + const LinphoneChatMessageCbs *cbs +) { return cbs->msg_state_changed; } -void linphone_chat_message_cbs_set_msg_state_changed(LinphoneChatMessageCbs *cbs, - LinphoneChatMessageCbsMsgStateChangedCb cb) { +void linphone_chat_message_cbs_set_msg_state_changed ( + LinphoneChatMessageCbs *cbs, + LinphoneChatMessageCbsMsgStateChangedCb cb +) { cbs->msg_state_changed = cb; } -LinphoneChatMessageCbsFileTransferRecvCb linphone_chat_message_cbs_get_file_transfer_recv(const LinphoneChatMessageCbs *cbs) { +LinphoneChatMessageCbsFileTransferRecvCb linphone_chat_message_cbs_get_file_transfer_recv ( + const LinphoneChatMessageCbs *cbs +) { return cbs->file_transfer_recv; } -void linphone_chat_message_cbs_set_file_transfer_recv(LinphoneChatMessageCbs *cbs, - LinphoneChatMessageCbsFileTransferRecvCb cb) { +void linphone_chat_message_cbs_set_file_transfer_recv ( + LinphoneChatMessageCbs *cbs, + LinphoneChatMessageCbsFileTransferRecvCb cb +) { cbs->file_transfer_recv = cb; } -LinphoneChatMessageCbsFileTransferSendCb linphone_chat_message_cbs_get_file_transfer_send(const LinphoneChatMessageCbs *cbs) { +LinphoneChatMessageCbsFileTransferSendCb linphone_chat_message_cbs_get_file_transfer_send ( + const LinphoneChatMessageCbs *cbs +) { return cbs->file_transfer_send; } -void linphone_chat_message_cbs_set_file_transfer_send(LinphoneChatMessageCbs *cbs, - LinphoneChatMessageCbsFileTransferSendCb cb) { +void linphone_chat_message_cbs_set_file_transfer_send ( + LinphoneChatMessageCbs *cbs, + LinphoneChatMessageCbsFileTransferSendCb cb +) { cbs->file_transfer_send = cb; } -LinphoneChatMessageCbsFileTransferProgressIndicationCb -linphone_chat_message_cbs_get_file_transfer_progress_indication(const LinphoneChatMessageCbs *cbs) { +LinphoneChatMessageCbsFileTransferProgressIndicationCb linphone_chat_message_cbs_get_file_transfer_progress_indication ( + const LinphoneChatMessageCbs *cbs +) { return cbs->file_transfer_progress_indication; } -void linphone_chat_message_cbs_set_file_transfer_progress_indication( - LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsFileTransferProgressIndicationCb cb) { +void linphone_chat_message_cbs_set_file_transfer_progress_indication ( + LinphoneChatMessageCbs *cbs, + LinphoneChatMessageCbsFileTransferProgressIndicationCb cb +) { cbs->file_transfer_progress_indication = cb; } + +LinphoneChatMessageCbsParticipantImdnStateChangedCb linphone_chat_message_cbs_get_participant_imdn_state_changed ( + const LinphoneChatMessageCbs *cbs +) { + return cbs->participant_imdn_state_changed; +} + +void linphone_chat_message_cbs_set_participant_imdn_state_changed ( + LinphoneChatMessageCbs *cbs, + LinphoneChatMessageCbsParticipantImdnStateChangedCb cb +) { + cbs->participant_imdn_state_changed = cb; +} diff --git a/src/c-wrapper/api/c-chat-message.cpp b/src/c-wrapper/api/c-chat-message.cpp index a616a9659..c2582bc11 100644 --- a/src/c-wrapper/api/c-chat-message.cpp +++ b/src/c-wrapper/api/c-chat-message.cpp @@ -18,6 +18,7 @@ */ #include "linphone/api/c-chat-message.h" +#include "linphone/api/c-content.h" #include "linphone/utils/utils.h" #include "linphone/wrapper_utils.h" @@ -32,6 +33,7 @@ #include "content/content-type.h" #include "content/content.h" #include "conference/participant.h" +#include "conference/participant-imdn-state.h" // ============================================================================= @@ -41,7 +43,9 @@ static void _linphone_chat_message_constructor (LinphoneChatMessage *msg); static void _linphone_chat_message_destructor (LinphoneChatMessage *msg); L_DECLARE_C_OBJECT_IMPL_WITH_XTORS(ChatMessage, - _linphone_chat_message_constructor, _linphone_chat_message_destructor, + _linphone_chat_message_constructor, + _linphone_chat_message_destructor, + LinphoneChatMessageCbs *cbs; LinphoneAddress *from; // cache for shared_ptr
LinphoneAddress *to; // cache for shared_ptr
@@ -100,69 +104,69 @@ LinphoneChatMessageCbs *linphone_chat_message_get_callbacks(const LinphoneChatMe // Getter and setters // ============================================================================= -LinphoneChatRoom *linphone_chat_message_get_chat_room(const LinphoneChatMessage *msg) { +LinphoneChatRoom *linphone_chat_message_get_chat_room (const LinphoneChatMessage *msg) { return L_GET_C_BACK_PTR(L_GET_CPP_PTR_FROM_C_OBJECT(msg)->getChatRoom()); } -const char *linphone_chat_message_get_external_body_url(const LinphoneChatMessage *msg) { +const char *linphone_chat_message_get_external_body_url (const LinphoneChatMessage *msg) { return L_STRING_TO_C(L_GET_PRIVATE_FROM_C_OBJECT(msg)->getExternalBodyUrl()); } -void linphone_chat_message_set_external_body_url(LinphoneChatMessage *msg, const char *url) { +void linphone_chat_message_set_external_body_url (LinphoneChatMessage *msg, const char *url) { L_GET_PRIVATE_FROM_C_OBJECT(msg)->setExternalBodyUrl(L_C_TO_STRING(url)); } -time_t linphone_chat_message_get_time(const LinphoneChatMessage *msg) { +time_t linphone_chat_message_get_time (const LinphoneChatMessage *msg) { return L_GET_CPP_PTR_FROM_C_OBJECT(msg)->getTime(); } -bool_t linphone_chat_message_is_secured(LinphoneChatMessage *msg) { +bool_t linphone_chat_message_is_secured (LinphoneChatMessage *msg) { return L_GET_CPP_PTR_FROM_C_OBJECT(msg)->isSecured(); } -bool_t linphone_chat_message_is_outgoing(LinphoneChatMessage *msg) { +bool_t linphone_chat_message_is_outgoing (LinphoneChatMessage *msg) { return L_GET_CPP_PTR_FROM_C_OBJECT(msg)->getDirection() == LinphonePrivate::ChatMessage::Direction::Outgoing; } -LinphoneChatMessageState linphone_chat_message_get_state(const LinphoneChatMessage *msg) { +LinphoneChatMessageState linphone_chat_message_get_state (const LinphoneChatMessage *msg) { return ((LinphoneChatMessageState)L_GET_CPP_PTR_FROM_C_OBJECT(msg)->getState()); } -const char* linphone_chat_message_get_message_id(const LinphoneChatMessage *msg) { +const char* linphone_chat_message_get_message_id (const LinphoneChatMessage *msg) { return L_GET_CPP_PTR_FROM_C_OBJECT(msg)->getImdnMessageId().c_str(); } -bool_t linphone_chat_message_is_read(LinphoneChatMessage *msg) { +bool_t linphone_chat_message_is_read (LinphoneChatMessage *msg) { return L_GET_CPP_PTR_FROM_C_OBJECT(msg)->isRead(); } -const char *linphone_chat_message_get_appdata(const LinphoneChatMessage *msg) { +const char *linphone_chat_message_get_appdata (const LinphoneChatMessage *msg) { return L_STRING_TO_C(L_GET_PRIVATE_FROM_C_OBJECT(msg)->getAppdata()); } -void linphone_chat_message_set_appdata(LinphoneChatMessage *msg, const char *data) { +void linphone_chat_message_set_appdata (LinphoneChatMessage *msg, const char *data) { L_GET_PRIVATE_FROM_C_OBJECT(msg)->setAppdata(L_C_TO_STRING(data)); } -const LinphoneAddress *linphone_chat_message_get_from_address(LinphoneChatMessage *msg) { +const LinphoneAddress *linphone_chat_message_get_from_address (LinphoneChatMessage *msg) { if (msg->from) linphone_address_unref(msg->from); msg->from = linphone_address_new(L_GET_CPP_PTR_FROM_C_OBJECT(msg)->getFromAddress().asString().c_str()); return msg->from; } -const LinphoneAddress *linphone_chat_message_get_to_address(LinphoneChatMessage *msg) { +const LinphoneAddress *linphone_chat_message_get_to_address (LinphoneChatMessage *msg) { if (msg->to) linphone_address_unref(msg->to); msg->to = linphone_address_new(L_GET_CPP_PTR_FROM_C_OBJECT(msg)->getToAddress().asString().c_str()); return msg->to; } -const char *linphone_chat_message_get_file_transfer_filepath(LinphoneChatMessage *msg) { +const char *linphone_chat_message_get_file_transfer_filepath (LinphoneChatMessage *msg) { return L_STRING_TO_C(L_GET_PRIVATE_FROM_C_OBJECT(msg)->getFileTransferFilepath()); } -void linphone_chat_message_set_file_transfer_filepath(LinphoneChatMessage *msg, const char *filepath) { +void linphone_chat_message_set_file_transfer_filepath (LinphoneChatMessage *msg, const char *filepath) { L_GET_PRIVATE_FROM_C_OBJECT(msg)->setFileTransferFilepath(L_C_TO_STRING(filepath)); } @@ -174,24 +178,24 @@ void linphone_chat_message_add_custom_header( L_GET_PRIVATE_FROM_C_OBJECT(msg)->addSalCustomHeader(L_C_TO_STRING(header_name), L_C_TO_STRING(header_value)); } -void linphone_chat_message_remove_custom_header(LinphoneChatMessage *msg, const char *header_name) { +void linphone_chat_message_remove_custom_header (LinphoneChatMessage *msg, const char *header_name) { L_GET_PRIVATE_FROM_C_OBJECT(msg)->removeSalCustomHeader(L_C_TO_STRING(header_name)); } -const char *linphone_chat_message_get_custom_header(LinphoneChatMessage *msg, const char *header_name) { +const char *linphone_chat_message_get_custom_header (LinphoneChatMessage *msg, const char *header_name) { msg->cache.customHeaderValue = L_GET_PRIVATE_FROM_C_OBJECT(msg)->getSalCustomHeaderValue(L_C_TO_STRING(header_name)); return L_STRING_TO_C(msg->cache.customHeaderValue); } -const LinphoneErrorInfo *linphone_chat_message_get_error_info(const LinphoneChatMessage *msg) { +const LinphoneErrorInfo *linphone_chat_message_get_error_info (const LinphoneChatMessage *msg) { return L_GET_CPP_PTR_FROM_C_OBJECT(msg)->getErrorInfo(); } -bool_t linphone_chat_message_get_to_be_stored(const LinphoneChatMessage *message) { +bool_t linphone_chat_message_get_to_be_stored (const LinphoneChatMessage *message) { return L_GET_CPP_PTR_FROM_C_OBJECT(message)->getToBeStored(); } -void linphone_chat_message_set_to_be_stored(LinphoneChatMessage *message, bool_t to_be_stored) { +void linphone_chat_message_set_to_be_stored (LinphoneChatMessage *message, bool_t to_be_stored) { L_GET_CPP_PTR_FROM_C_OBJECT(message)->setToBeStored(!!to_be_stored); } @@ -199,11 +203,11 @@ void linphone_chat_message_set_to_be_stored(LinphoneChatMessage *message, bool_t // Methods // ============================================================================= -LinphoneStatus linphone_chat_message_download_file(LinphoneChatMessage *msg) { - return ((LinphoneStatus)L_GET_PRIVATE_FROM_C_OBJECT(msg)->downloadFile()); +bool_t linphone_chat_message_download_file (LinphoneChatMessage *msg) { + return !!L_GET_PRIVATE_FROM_C_OBJECT(msg)->downloadFile(); } -void linphone_chat_message_cancel_file_transfer(LinphoneChatMessage *msg) { +void linphone_chat_message_cancel_file_transfer (LinphoneChatMessage *msg) { L_GET_CPP_PTR_FROM_C_OBJECT(msg)->cancelFileTransfer(); } @@ -211,31 +215,31 @@ void linphone_chat_message_send (LinphoneChatMessage *msg) { L_GET_CPP_PTR_FROM_C_OBJECT(msg)->send(); } -void linphone_chat_message_resend(LinphoneChatMessage *msg) { +void linphone_chat_message_resend (LinphoneChatMessage *msg) { L_GET_CPP_PTR_FROM_C_OBJECT(msg)->send(); } -void linphone_chat_message_resend_2(LinphoneChatMessage *msg) { +void linphone_chat_message_resend_2 (LinphoneChatMessage *msg) { L_GET_CPP_PTR_FROM_C_OBJECT(msg)->send(); } -LinphoneStatus linphone_chat_message_put_char(LinphoneChatMessage *msg, uint32_t character) { +LinphoneStatus linphone_chat_message_put_char (LinphoneChatMessage *msg, uint32_t character) { return ((LinphoneStatus)L_GET_CPP_PTR_FROM_C_OBJECT(msg)->putCharacter(character)); } -void linphone_chat_message_add_text_content(LinphoneChatMessage *msg, const char *c_content) { +void linphone_chat_message_add_text_content (LinphoneChatMessage *msg, const char *c_content) { LinphonePrivate::Content *content = new LinphonePrivate::Content(); LinphonePrivate::ContentType contentType = LinphonePrivate::ContentType::PlainText; content->setContentType(contentType); content->setBody(L_C_TO_STRING(c_content)); - L_GET_CPP_PTR_FROM_C_OBJECT(msg)->addContent(*content); + L_GET_CPP_PTR_FROM_C_OBJECT(msg)->addContent(content); } -bool_t linphone_chat_message_has_text_content(const LinphoneChatMessage *msg) { +bool_t linphone_chat_message_has_text_content (const LinphoneChatMessage *msg) { return L_GET_PRIVATE_FROM_C_OBJECT(msg)->hasTextContent(); } -const char *linphone_chat_message_get_text_content(const LinphoneChatMessage *msg) { +const char *linphone_chat_message_get_text_content (const LinphoneChatMessage *msg) { const LinphonePrivate::Content *content = L_GET_PRIVATE_FROM_C_OBJECT(msg)->getTextContent(); if (content->isEmpty()) return nullptr; @@ -243,14 +247,15 @@ const char *linphone_chat_message_get_text_content(const LinphoneChatMessage *ms return L_STRING_TO_C(msg->cache.textContentBody); } -bool_t linphone_chat_message_is_file_transfer_in_progress(LinphoneChatMessage *msg) { +bool_t linphone_chat_message_is_file_transfer_in_progress (LinphoneChatMessage *msg) { return L_GET_CPP_PTR_FROM_C_OBJECT(msg)->isFileTransferInProgress(); } -bctbx_list_t *linphone_chat_message_get_participants_in_state (const LinphoneChatMessage *msg, const LinphoneChatMessageState state) { - return L_GET_RESOLVED_C_LIST_FROM_CPP_LIST(L_GET_PRIVATE_FROM_C_OBJECT(msg)->getParticipantsInState((LinphonePrivate::ChatMessage::State) state)); +bctbx_list_t *linphone_chat_message_get_participants_by_imdn_state (const LinphoneChatMessage *msg, LinphoneChatMessageState state) { + return L_GET_RESOLVED_C_LIST_FROM_CPP_LIST(L_GET_CPP_PTR_FROM_C_OBJECT(msg)->getParticipantsByImdnState(LinphonePrivate::ChatMessage::State(state))); } + // ============================================================================= // Old listener // ============================================================================= @@ -259,15 +264,15 @@ LinphoneChatMessageStateChangedCb linphone_chat_message_get_message_state_change return msg->message_state_changed_cb; } -void linphone_chat_message_set_message_state_changed_cb(LinphoneChatMessage* msg, LinphoneChatMessageStateChangedCb cb) { +void linphone_chat_message_set_message_state_changed_cb (LinphoneChatMessage* msg, LinphoneChatMessageStateChangedCb cb) { msg->message_state_changed_cb = cb; } -void linphone_chat_message_set_message_state_changed_cb_user_data(LinphoneChatMessage* msg, void *user_data) { +void linphone_chat_message_set_message_state_changed_cb_user_data (LinphoneChatMessage* msg, void *user_data) { msg->message_state_changed_user_data = user_data; } -void * linphone_chat_message_get_message_state_changed_cb_user_data(LinphoneChatMessage* msg) { +void * linphone_chat_message_get_message_state_changed_cb_user_data (LinphoneChatMessage* msg) { return msg->message_state_changed_user_data; } @@ -275,55 +280,57 @@ void * linphone_chat_message_get_message_state_changed_cb_user_data(LinphoneChat // Structure has changed, hard to keep the behavior // ============================================================================= -const char *linphone_chat_message_get_content_type(LinphoneChatMessage *msg) { +const char *linphone_chat_message_get_content_type (LinphoneChatMessage *msg) { msg->cache.contentType = L_GET_PRIVATE_FROM_C_OBJECT(msg)->getContentType().asString(); return L_STRING_TO_C(msg->cache.contentType); } -void linphone_chat_message_set_content_type(LinphoneChatMessage *msg, const char *content_type) { +void linphone_chat_message_set_content_type (LinphoneChatMessage *msg, const char *content_type) { L_GET_PRIVATE_FROM_C_OBJECT(msg)->setContentType(LinphonePrivate::ContentType(L_C_TO_STRING(content_type))); } -const char *linphone_chat_message_get_text(LinphoneChatMessage *msg) { +const char *linphone_chat_message_get_text (LinphoneChatMessage *msg) { return L_STRING_TO_C(L_GET_PRIVATE_FROM_C_OBJECT(msg)->getText()); } -int linphone_chat_message_set_text(LinphoneChatMessage *msg, const char* text) { +int linphone_chat_message_set_text (LinphoneChatMessage *msg, const char* text) { L_GET_PRIVATE_FROM_C_OBJECT(msg)->setText(L_C_TO_STRING(text)); return 0; } -LinphoneContent *linphone_chat_message_get_file_transfer_information(LinphoneChatMessage *msg) { - return L_GET_PRIVATE_FROM_C_OBJECT(msg)->getFileTransferInformation(); +LinphoneContent *linphone_chat_message_get_file_transfer_information (LinphoneChatMessage *msg) { + const LinphonePrivate::Content *content = L_GET_PRIVATE_FROM_C_OBJECT(msg)->getFileTransferInformation(); + if (content) return L_GET_C_BACK_PTR(content); + return NULL; } // ============================================================================= // Nothing to do, they call other C API methods // ============================================================================= -const LinphoneAddress *linphone_chat_message_get_peer_address(LinphoneChatMessage *msg) { +const LinphoneAddress *linphone_chat_message_get_peer_address (LinphoneChatMessage *msg) { return linphone_chat_room_get_peer_address(linphone_chat_message_get_chat_room(msg)); } -const LinphoneAddress *linphone_chat_message_get_local_address(LinphoneChatMessage *msg) { +const LinphoneAddress *linphone_chat_message_get_local_address (LinphoneChatMessage *msg) { if (L_GET_CPP_PTR_FROM_C_OBJECT(msg)->getDirection() == LinphonePrivate::ChatMessage::Direction::Outgoing) return linphone_chat_message_get_from_address(msg); return linphone_chat_message_get_to_address(msg); } -LinphoneReason linphone_chat_message_get_reason(LinphoneChatMessage *msg) { +LinphoneReason linphone_chat_message_get_reason (LinphoneChatMessage *msg) { return linphone_error_info_get_reason(linphone_chat_message_get_error_info(msg)); } -bool_t linphone_chat_message_is_file_transfer(LinphoneChatMessage *msg) { +bool_t linphone_chat_message_is_file_transfer (LinphoneChatMessage *msg) { return L_GET_PRIVATE_FROM_C_OBJECT(msg)->hasFileTransferContent(); } -bool_t linphone_chat_message_is_text(LinphoneChatMessage *msg) { +bool_t linphone_chat_message_is_text (LinphoneChatMessage *msg) { return L_GET_PRIVATE_FROM_C_OBJECT(msg)->hasTextContent(); } -const char *linphone_chat_message_state_to_string(const LinphoneChatMessageState state) { +const char *linphone_chat_message_state_to_string (const LinphoneChatMessageState state) { switch (state) { case LinphoneChatMessageStateIdle: return "LinphoneChatMessageStateIdle"; @@ -345,8 +352,11 @@ const char *linphone_chat_message_state_to_string(const LinphoneChatMessageState return NULL; } -void linphone_chat_message_start_file_download(LinphoneChatMessage *msg, - LinphoneChatMessageStateChangedCb status_cb, void *ud) { +void linphone_chat_message_start_file_download ( + LinphoneChatMessage *msg, + LinphoneChatMessageStateChangedCb status_cb, + void *ud +) { msg->message_state_changed_cb = status_cb; msg->message_state_changed_user_data = ud; linphone_chat_message_download_file(msg); diff --git a/src/c-wrapper/api/c-chat-room-cbs.cpp b/src/c-wrapper/api/c-chat-room-cbs.cpp index 1d3d4d8d6..0927d1b97 100644 --- a/src/c-wrapper/api/c-chat-room-cbs.cpp +++ b/src/c-wrapper/api/c-chat-room-cbs.cpp @@ -35,6 +35,8 @@ struct _LinphoneChatRoomCbs { LinphoneChatRoomCbsParticipantAdminStatusChangedCb participantAdminStatusChangedCb; LinphoneChatRoomCbsStateChangedCb stateChangedCb; LinphoneChatRoomCbsSubjectChangedCb subjectChangedCb; + LinphoneChatRoomCbsConferenceJoinedCb conferenceJoinedCb; + LinphoneChatRoomCbsConferenceLeftCb conferenceLeftCb; LinphoneChatRoomCbsUndecryptableMessageReceivedCb undecryptableMessageReceivedCb; LinphoneChatRoomCbsChatMessageReceivedCb chatMessageReceivedCb; LinphoneChatRoomCbsChatMessageSentCb chatMessageSentCb; @@ -176,6 +178,22 @@ void linphone_chat_room_cbs_set_participant_device_removed (LinphoneChatRoomCbs cbs->participantDeviceRemovedCb = cb; } +LinphoneChatRoomCbsConferenceJoinedCb linphone_chat_room_cbs_get_conference_joined (const LinphoneChatRoomCbs *cbs) { + return cbs->conferenceJoinedCb; +} + +void linphone_chat_room_cbs_set_conference_joined (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsConferenceJoinedCb cb) { + cbs->conferenceJoinedCb = cb; +} + +LinphoneChatRoomCbsConferenceLeftCb linphone_chat_room_cbs_get_conference_left (const LinphoneChatRoomCbs *cbs) { + return cbs->conferenceLeftCb; +} + +void linphone_chat_room_cbs_set_conference_left (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsConferenceLeftCb cb) { + cbs->conferenceLeftCb = cb; +} + LinphoneChatRoomCbsConferenceAddressGenerationCb linphone_chat_room_cbs_get_conference_address_generation (const LinphoneChatRoomCbs *cbs) { return cbs->conferenceAddressGenerationCb; } diff --git a/src/c-wrapper/api/c-chat-room.cpp b/src/c-wrapper/api/c-chat-room.cpp index e549964e0..18f996048 100644 --- a/src/c-wrapper/api/c-chat-room.cpp +++ b/src/c-wrapper/api/c-chat-room.cpp @@ -18,6 +18,7 @@ */ #include +#include // TODO: Remove me later. #include "linphone/chat.h" @@ -355,8 +356,8 @@ const bctbx_list_t *linphone_chat_room_get_composing_addresses (LinphoneChatRoom return cr->composingAddresses; } -LinphoneChatMessage *linphone_chat_room_create_file_transfer_message(LinphoneChatRoom *cr, const LinphoneContent *initial_content) { - shared_ptr cppPtr = L_GET_CPP_PTR_FROM_C_OBJECT(cr)->createFileTransferMessage(initial_content); +LinphoneChatMessage *linphone_chat_room_create_file_transfer_message(LinphoneChatRoom *cr, LinphoneContent *initial_content) { + shared_ptr cppPtr = L_GET_CPP_PTR_FROM_C_OBJECT(cr)->createFileTransferMessage(L_GET_CPP_PTR_FROM_C_OBJECT(initial_content)); LinphoneChatMessage *object = L_INIT(ChatMessage); L_SET_CPP_PTR_FROM_C_OBJECT(object, cppPtr); return object; @@ -442,6 +443,7 @@ const bctbx_list_t *linphone_chat_room_get_callbacks_list(const LinphoneChatRoom if (cb) \ cb(__VA_ARGS__); \ } \ + linphone_chat_room_set_current_callbacks(cr, nullptr); \ bctbx_list_free(callbacksCopy); void _linphone_chat_room_notify_is_composing_received(LinphoneChatRoom *cr, const LinphoneAddress *remoteAddr, bool_t isComposing) { @@ -480,6 +482,14 @@ void _linphone_chat_room_notify_subject_changed(LinphoneChatRoom *cr, const Linp NOTIFY_IF_EXIST(SubjectChanged, subject_changed, cr, event_log) } +void _linphone_chat_room_notify_conference_joined(LinphoneChatRoom *cr, const LinphoneEventLog *eventLog) { + NOTIFY_IF_EXIST(ConferenceJoined, conference_joined, cr, eventLog) +} + +void _linphone_chat_room_notify_conference_left(LinphoneChatRoom *cr, const LinphoneEventLog *eventLog) { + NOTIFY_IF_EXIST(ConferenceLeft, conference_left, cr, eventLog) +} + void _linphone_chat_room_notify_undecryptable_message_received(LinphoneChatRoom *cr, LinphoneChatMessage *msg) { NOTIFY_IF_EXIST(UndecryptableMessageReceived, undecryptable_message_received, cr, msg) } diff --git a/src/c-wrapper/api/c-content.cpp b/src/c-wrapper/api/c-content.cpp new file mode 100644 index 000000000..29ccb9c16 --- /dev/null +++ b/src/c-wrapper/api/c-content.cpp @@ -0,0 +1,337 @@ +/* + * c-content.cpp + * Copyright (C) 2010-2018 Belledonne Communications SARL + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "linphone/api/c-content.h" +#include "linphone/wrapper_utils.h" + +#include "c-wrapper/c-wrapper.h" +#include "content/content-type.h" +#include "content/file-content.h" +#include "content/file-transfer-content.h" +#include "content/header/header-param.h" + +// ============================================================================= + +using namespace std; + +static void _linphone_content_constructor (LinphoneContent *content); +static void _linphone_content_destructor (LinphoneContent *content); + +L_DECLARE_C_CLONABLE_OBJECT_IMPL_WITH_XTORS(Content, + _linphone_content_constructor, + _linphone_content_destructor, + + void *cryptoContext; // Used to encrypt file for RCS file transfer. + + mutable size_t size; + + struct Cache { + string name; + string type; + string subtype; + string buffer; + } mutable cache; +) + +static void _linphone_content_constructor (LinphoneContent *content) { + new(&content->cache) LinphoneContent::Cache(); +} + +static void _linphone_content_destructor (LinphoneContent *content) { + content->cache.~Cache(); +} + +// ============================================================================= +// Reference and user data handling functions. +// ============================================================================= + +LinphoneContent *linphone_content_ref (LinphoneContent *content) { + belle_sip_object_ref(content); + return content; +} + +void linphone_content_unref (LinphoneContent *content) { + belle_sip_object_unref(content); +} + +void *linphone_content_get_user_data (const LinphoneContent *content) { + return L_GET_USER_DATA_FROM_C_OBJECT(content); +} + +void linphone_content_set_user_data (LinphoneContent *content, void *user_data) { + return L_SET_USER_DATA_FROM_C_OBJECT(content, user_data); +} + +// ============================================================================= + +const char *linphone_content_get_type (const LinphoneContent *content) { + return L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType().getType().c_str(); +} + +void linphone_content_set_type (LinphoneContent *content, const char *type) { + LinphonePrivate::ContentType contentType = L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType(); + contentType.setType(L_C_TO_STRING(type)); + L_GET_CPP_PTR_FROM_C_OBJECT(content)->setContentType(contentType); +} + +const char *linphone_content_get_subtype (const LinphoneContent *content) { + return L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType().getSubType().c_str(); +} + +void linphone_content_set_subtype (LinphoneContent *content, const char *subtype) { + LinphonePrivate::ContentType contentType = L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType(); + contentType.setSubType(L_C_TO_STRING(subtype)); + L_GET_CPP_PTR_FROM_C_OBJECT(content)->setContentType(contentType); +} + +void linphone_content_add_content_type_parameter (LinphoneContent *content, const char *name, const char *value) { + LinphonePrivate::ContentType contentType = L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType(); + contentType.addParameter(L_C_TO_STRING(name), L_C_TO_STRING(value)); + L_GET_CPP_PTR_FROM_C_OBJECT(content)->setContentType(contentType); +} + +const uint8_t *linphone_content_get_buffer (const LinphoneContent *content) { + return reinterpret_cast(linphone_content_get_string_buffer(content)); +} + +void linphone_content_set_buffer (LinphoneContent *content, const uint8_t *buffer, size_t size) { + L_GET_CPP_PTR_FROM_C_OBJECT(content)->setBody(buffer, size); +} + +const char *linphone_content_get_string_buffer (const LinphoneContent *content) { + content->cache.buffer = L_GET_CPP_PTR_FROM_C_OBJECT(content)->getBodyAsUtf8String(); + return content->cache.buffer.c_str(); +} + +void linphone_content_set_string_buffer (LinphoneContent *content, const char *buffer) { + L_GET_CPP_PTR_FROM_C_OBJECT(content)->setBodyFromUtf8(L_C_TO_STRING(buffer)); +} + +size_t linphone_content_get_file_size(const LinphoneContent *content) { + const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); + size_t size = 0; + if (c->isFile()) + size = static_cast(c)->getFileSize(); + else if (c->isFileTransfer()) + size = static_cast(c)->getFileSize(); + return size; +} + +size_t linphone_content_get_size (const LinphoneContent *content) { + const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); + size_t size = c->getSize(); + if (size == 0) { + size = content->size; + } + return size; +} + +void linphone_content_set_size (LinphoneContent *content, size_t size) { + content->size = size; +} + +const char *linphone_content_get_encoding (const LinphoneContent *content) { + return L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentEncoding()); +} + +void linphone_content_set_encoding (LinphoneContent *content, const char *encoding) { + L_GET_CPP_PTR_FROM_C_OBJECT(content)->setContentEncoding(L_C_TO_STRING(encoding)); +} + +const char *linphone_content_get_name (const LinphoneContent *content) { + const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); + if (c->isFile()) + return static_cast(c)->getFileName().c_str(); + if (c->isFileTransfer()) + return static_cast(c)->getFileName().c_str(); + return content->cache.name.c_str(); +} + +void linphone_content_set_name (LinphoneContent *content, const char *name) { + LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); + if (c->isFile()) + static_cast(c)->setFileName(L_C_TO_STRING(name)); + else if (c->isFileTransfer()) + static_cast(c)->setFileName(L_C_TO_STRING(name)); + else + content->cache.name = L_C_TO_STRING(name); +} + +bool_t linphone_content_is_multipart (const LinphoneContent *content) { + return L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType().isMultipart(); +} + +LinphoneContent *linphone_content_get_part (const LinphoneContent *content, int idx) { + SalBodyHandler *bodyHandler = sal_body_handler_from_content(content); + if (!sal_body_handler_is_multipart(bodyHandler)) { + sal_body_handler_unref(bodyHandler); + return nullptr; + } + SalBodyHandler *partBodyHandler = sal_body_handler_get_part(bodyHandler, idx); + LinphoneContent *result = linphone_content_from_sal_body_handler(partBodyHandler); + sal_body_handler_unref(bodyHandler); + return result; +} + +LinphoneContent *linphone_content_find_part_by_header (const LinphoneContent *content, const char *headerName, const char *headerValue) { + SalBodyHandler *bodyHandler = sal_body_handler_from_content(content); + if (!sal_body_handler_is_multipart(bodyHandler)) { + sal_body_handler_unref(bodyHandler); + return nullptr; + } + SalBodyHandler *partBodyHandler = sal_body_handler_find_part_by_header(bodyHandler, headerName, headerValue); + LinphoneContent *result = linphone_content_from_sal_body_handler(partBodyHandler); + sal_body_handler_unref(bodyHandler); + return result; +} + +const char *linphone_content_get_custom_header (const LinphoneContent *content, const char *headerName) { + SalBodyHandler *bodyHandler = sal_body_handler_from_content(content); + const char *header = sal_body_handler_get_header(bodyHandler, headerName); + sal_body_handler_unref(bodyHandler); + return header; +} + +const char *linphone_content_get_key (const LinphoneContent *content) { + const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); + if (c->isFileTransfer()) { + const LinphonePrivate::FileTransferContent *ftc = static_cast(c); + return ftc->getFileKey().data(); + } + return nullptr; +} + +size_t linphone_content_get_key_size (const LinphoneContent *content) { + const LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); + if (c->isFileTransfer()) { + const LinphonePrivate::FileTransferContent *ftc = static_cast(c); + return ftc->getFileKeySize(); + } + return 0; +} + +void linphone_content_set_key (LinphoneContent *content, const char *key, const size_t keyLength) { + LinphonePrivate::Content *c = L_GET_CPP_PTR_FROM_C_OBJECT(content); + if (c->isFileTransfer()) { + LinphonePrivate::FileTransferContent *ftc = static_cast(c); + ftc->setFileKey(key, keyLength); + } +} + +// ============================================================================= +// Private functions. +// ============================================================================= + +static LinphoneContent *linphone_content_new_with_body_handler (const SalBodyHandler *bodyHandler, bool parseMultipart) { + LinphoneContent *content = L_INIT(Content); + content->cryptoContext = nullptr; + LinphonePrivate::Content *c = new LinphonePrivate::Content(); + L_SET_CPP_PTR_FROM_C_OBJECT(content, c); + + if (!bodyHandler) + return content; + + linphone_content_set_type(content, sal_body_handler_get_type(bodyHandler)); + linphone_content_set_subtype(content, sal_body_handler_get_subtype(bodyHandler)); + for (const belle_sip_list_t *params = sal_body_handler_get_content_type_parameters_names(bodyHandler); params; params = params->next) { + const char *paramName = reinterpret_cast(params->data); + const char *paramValue = sal_body_handler_get_content_type_parameter(bodyHandler, paramName); + linphone_content_add_content_type_parameter(content, paramName, paramValue); + } + + if (linphone_content_is_multipart(content) && parseMultipart) { + belle_sip_multipart_body_handler_t *mpbh = BELLE_SIP_MULTIPART_BODY_HANDLER(bodyHandler); + char *body = belle_sip_object_to_string(mpbh); + linphone_content_set_string_buffer(content, body); + belle_sip_free(body); + } else { + linphone_content_set_string_buffer(content, reinterpret_cast(sal_body_handler_get_data(bodyHandler))); + } + + const belle_sip_list_t *headers = reinterpret_cast(sal_body_handler_get_headers(bodyHandler)); + while (headers) { + belle_sip_header_t *cHeader = BELLE_SIP_HEADER(headers->data); + LinphonePrivate::Header header = LinphonePrivate::Header(belle_sip_header_get_name(cHeader), belle_sip_header_get_unparsed_value(cHeader)); + L_GET_CPP_PTR_FROM_C_OBJECT(content)->addHeader(header); + headers = headers->next; + } + if (sal_body_handler_get_encoding(bodyHandler)) + linphone_content_set_encoding(content, sal_body_handler_get_encoding(bodyHandler)); + + return content; +} + +LinphoneContent *linphone_content_new (void) { + return linphone_content_new_with_body_handler(nullptr, true); +} + +LinphoneContent *linphone_content_copy (const LinphoneContent *ref) { + return reinterpret_cast(belle_sip_object_clone(BELLE_SIP_OBJECT(ref))); +} + +LinphoneContent *linphone_core_create_content (LinphoneCore *lc) { + return linphone_content_new(); +} + +// Crypto context is managed(allocated/freed) by the encryption function, +// so provide the address of field in the private structure. +void **linphone_content_get_cryptoContext_address (LinphoneContent *content) { + return &content->cryptoContext; +} + +LinphoneContent *linphone_content_from_sal_body_handler (const SalBodyHandler *bodyHandler, bool parseMultipart) { + if (!bodyHandler) + return nullptr; + return linphone_content_new_with_body_handler(bodyHandler, parseMultipart); +} + +SalBodyHandler *sal_body_handler_from_content (const LinphoneContent *content, bool parseMultipart) { + if (!content) + return nullptr; + + SalBodyHandler *bodyHandler; + LinphonePrivate::ContentType contentType = L_GET_CPP_PTR_FROM_C_OBJECT(content)->getContentType(); + if (contentType.isMultipart() && parseMultipart) { + size_t size = linphone_content_get_size(content); + char *buffer = bctbx_strdup(L_GET_CPP_PTR_FROM_C_OBJECT(content)->getBodyAsUtf8String().c_str()); + const char *boundary = L_STRING_TO_C(contentType.getParameter("boundary").getValue()); + belle_sip_multipart_body_handler_t *bh = belle_sip_multipart_body_handler_new_from_buffer(buffer, size, boundary); + bodyHandler = reinterpret_cast(BELLE_SIP_BODY_HANDLER(bh)); + bctbx_free(buffer); + } else { + bodyHandler = sal_body_handler_new(); + sal_body_handler_set_data(bodyHandler, belle_sip_strdup(linphone_content_get_string_buffer(content))); + } + + for (const auto &header : L_GET_CPP_PTR_FROM_C_OBJECT(content)->getHeaders()) { + belle_sip_header_t *additionalHeader = belle_sip_header_parse(header.asString().c_str()); + belle_sip_body_handler_add_header(BELLE_SIP_BODY_HANDLER(bodyHandler), additionalHeader); + } + + sal_body_handler_set_type(bodyHandler, contentType.getType().c_str()); + sal_body_handler_set_subtype(bodyHandler, contentType.getSubType().c_str()); + sal_body_handler_set_size(bodyHandler, linphone_content_get_size(content)); + for (const auto ¶m : contentType.getParameters()) + sal_body_handler_set_content_type_parameter(bodyHandler, param.getName().c_str(), param.getValue().c_str()); + + if (linphone_content_get_encoding(content)) + sal_body_handler_set_encoding(bodyHandler, linphone_content_get_encoding(content)); + + return bodyHandler; +} diff --git a/src/c-wrapper/api/c-magic-search.cpp b/src/c-wrapper/api/c-magic-search.cpp index 028a64ba1..cceae6be7 100644 --- a/src/c-wrapper/api/c-magic-search.cpp +++ b/src/c-wrapper/api/c-magic-search.cpp @@ -17,15 +17,19 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "search/magic-search.h" #include "c-wrapper/c-wrapper.h" +#include "search/magic-search.h" + +// ============================================================================= using namespace std; L_DECLARE_C_OBJECT_IMPL(MagicSearch); LinphoneMagicSearch *linphone_core_create_magic_search(LinphoneCore *lc) { - shared_ptr cppPtr = make_shared(L_GET_CPP_PTR_FROM_C_OBJECT(lc)); + shared_ptr cppPtr = make_shared( + L_GET_CPP_PTR_FROM_C_OBJECT(lc) + ); LinphoneMagicSearch *object = L_INIT(MagicSearch); L_SET_CPP_PTR_FROM_C_OBJECT(object, cppPtr); @@ -36,67 +40,73 @@ LinphoneMagicSearch *linphone_magic_search_new(LinphoneCore *lc) { return linphone_core_create_magic_search(lc); } -LinphoneMagicSearch *linphone_magic_search_ref(LinphoneMagicSearch *magicSearch) { - belle_sip_object_ref(magicSearch); - return magicSearch; +LinphoneMagicSearch *linphone_magic_search_ref (LinphoneMagicSearch *magic_search) { + belle_sip_object_ref(magic_search); + return magic_search; } -void linphone_magic_search_unref(LinphoneMagicSearch *magicSearch) { - belle_sip_object_unref(magicSearch); +void linphone_magic_search_unref (LinphoneMagicSearch *magic_search) { + belle_sip_object_unref(magic_search); } -void linphone_magic_search_set_min_weight(LinphoneMagicSearch *magicSearch, const unsigned int weight) { - L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->setMinWeight(weight); +void linphone_magic_search_set_min_weight (LinphoneMagicSearch *magic_search, unsigned int weight) { + L_GET_CPP_PTR_FROM_C_OBJECT(magic_search)->setMinWeight(weight); } -unsigned int linphone_magic_search_get_min_weight(const LinphoneMagicSearch *magicSearch) { - return L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->getMinWeight(); +unsigned int linphone_magic_search_get_min_weight (const LinphoneMagicSearch *magic_search) { + return L_GET_CPP_PTR_FROM_C_OBJECT(magic_search)->getMinWeight(); } -void linphone_magic_search_set_max_weight(LinphoneMagicSearch *magicSearch, const unsigned int weight) { - L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->setMaxWeight(weight); +void linphone_magic_search_set_max_weight (LinphoneMagicSearch *magic_search, unsigned int weight) { + L_GET_CPP_PTR_FROM_C_OBJECT(magic_search)->setMaxWeight(weight); } -unsigned int linphone_magic_search_get_max_weight(const LinphoneMagicSearch *magicSearch) { - return L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->getMaxWeight(); +unsigned int linphone_magic_search_get_max_weight (const LinphoneMagicSearch *magic_search) { + return L_GET_CPP_PTR_FROM_C_OBJECT(magic_search)->getMaxWeight(); } -const char *linphone_magic_search_get_delimiter(const LinphoneMagicSearch *magicSearch) { - return L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->getDelimiter()); +const char *linphone_magic_search_get_delimiter (const LinphoneMagicSearch *magic_search) { + return L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(magic_search)->getDelimiter()); } -void linphone_magic_search_set_delimiter(LinphoneMagicSearch *magicSearch, const char *delimiter) { - L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->setDelimiter(L_C_TO_STRING(delimiter)); +void linphone_magic_search_set_delimiter (LinphoneMagicSearch *magic_search, const char *delimiter) { + L_GET_CPP_PTR_FROM_C_OBJECT(magic_search)->setDelimiter(L_C_TO_STRING(delimiter)); } -bool_t linphone_magic_search_get_use_delimiter(LinphoneMagicSearch *magicSearch) { - return L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->getUseDelimiter(); +bool_t linphone_magic_search_get_use_delimiter (LinphoneMagicSearch *magic_search) { + return L_GET_CPP_PTR_FROM_C_OBJECT(magic_search)->getUseDelimiter(); } -void linphone_magic_search_set_use_delimiter(LinphoneMagicSearch *magicSearch, bool_t enable) { - L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->setUseDelimiter(enable); +void linphone_magic_search_set_use_delimiter (LinphoneMagicSearch *magic_search, bool_t enable) { + L_GET_CPP_PTR_FROM_C_OBJECT(magic_search)->setUseDelimiter(!!enable); } -unsigned int linphone_magic_search_get_search_limit(const LinphoneMagicSearch *magicSearch) { - return L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->getSearchLimit(); +unsigned int linphone_magic_search_get_search_limit (const LinphoneMagicSearch *magic_search) { + return L_GET_CPP_PTR_FROM_C_OBJECT(magic_search)->getSearchLimit(); } -void linphone_magic_search_set_search_limit(LinphoneMagicSearch *magicSearch, const unsigned int limit) { - L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->setSearchLimit(limit); +void linphone_magic_search_set_search_limit (LinphoneMagicSearch *magic_search, unsigned int limit) { + L_GET_CPP_PTR_FROM_C_OBJECT(magic_search)->setSearchLimit(limit); } -bool_t linphone_magic_search_get_limited_search(const LinphoneMagicSearch *magicSearch) { - return L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->getLimitedSearch(); +bool_t linphone_magic_search_get_limited_search (const LinphoneMagicSearch *magic_search) { + return L_GET_CPP_PTR_FROM_C_OBJECT(magic_search)->getLimitedSearch(); } -void linphone_magic_search_set_limited_search(LinphoneMagicSearch *magicSearch, const bool_t limited) { - L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->setLimitedSearch(limited); +void linphone_magic_search_set_limited_search (LinphoneMagicSearch *magic_search, bool_t limited) { + L_GET_CPP_PTR_FROM_C_OBJECT(magic_search)->setLimitedSearch(!!limited); } -void linphone_magic_search_reset_search_cache(LinphoneMagicSearch *magicSearch) { - L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->resetSearchCache(); +void linphone_magic_search_reset_search_cache (LinphoneMagicSearch *magic_search) { + L_GET_CPP_PTR_FROM_C_OBJECT(magic_search)->resetSearchCache(); } -bctbx_list_t* linphone_magic_search_get_contact_list_from_filter(LinphoneMagicSearch *magicSearch, const char *filter, const char *withDomain) { - return L_GET_RESOLVED_C_LIST_FROM_CPP_LIST(L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->getContactListFromFilter(L_C_TO_STRING(filter), L_C_TO_STRING(withDomain))); +bctbx_list_t* linphone_magic_search_get_contact_list_from_filter ( + LinphoneMagicSearch *magic_search, + const char *filter, + const char *domain +) { + return L_GET_RESOLVED_C_LIST_FROM_CPP_LIST(L_GET_CPP_PTR_FROM_C_OBJECT(magic_search)->getContactListFromFilter( + L_C_TO_STRING(filter), L_C_TO_STRING(domain) + )); } diff --git a/src/c-wrapper/api/c-participant-imdn-state.cpp b/src/c-wrapper/api/c-participant-imdn-state.cpp new file mode 100644 index 000000000..85dc5e74a --- /dev/null +++ b/src/c-wrapper/api/c-participant-imdn-state.cpp @@ -0,0 +1,63 @@ +/* + * c-participant-imdn-state.cpp + * Copyright (C) 2010-2018 Belledonne Communications SARL + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "linphone/api/c-participant-imdn-state.h" + +#include "c-wrapper/c-wrapper.h" +#include "conference/participant.h" +#include "conference/participant-imdn-state.h" + +// ============================================================================= + +using namespace std; + +L_DECLARE_C_CLONABLE_OBJECT_IMPL(ParticipantImdnState); + +LinphoneParticipantImdnState *linphone_participant_imdn_state_ref (LinphoneParticipantImdnState *state) { + belle_sip_object_ref(state); + return state; +} + +void linphone_participant_imdn_state_unref (LinphoneParticipantImdnState *state) { + belle_sip_object_unref(state); +} + +void *linphone_participant_imdn_state_get_user_data(const LinphoneParticipantImdnState *state) { + return L_GET_USER_DATA_FROM_C_OBJECT(state); +} + +void linphone_participant_imdn_state_set_user_data(LinphoneParticipantImdnState *state, void *ud) { + L_SET_USER_DATA_FROM_C_OBJECT(state, ud); +} + +const LinphoneParticipant *linphone_participant_imdn_state_get_participant (const LinphoneParticipantImdnState *state) { + return L_GET_C_BACK_PTR(L_GET_CPP_PTR_FROM_C_OBJECT(state)->getParticipant()); +} + +LinphoneChatMessageState linphone_participant_imdn_state_get_state (const LinphoneParticipantImdnState *state) { + return (LinphoneChatMessageState)L_GET_CPP_PTR_FROM_C_OBJECT(state)->getState(); +} + +time_t linphone_participant_imdn_state_get_state_change_time (const LinphoneParticipantImdnState *state) { + return L_GET_CPP_PTR_FROM_C_OBJECT(state)->getStateChangeTime(); +} + +const LinphoneParticipantImdnState *_linphone_participant_imdn_state_from_cpp_obj (const LinphonePrivate::ParticipantImdnState &state) { + return L_GET_C_BACK_PTR(&state); +} \ No newline at end of file diff --git a/src/c-wrapper/api/c-search-result.cpp b/src/c-wrapper/api/c-search-result.cpp index 77cd38c13..295c0edeb 100644 --- a/src/c-wrapper/api/c-search-result.cpp +++ b/src/c-wrapper/api/c-search-result.cpp @@ -39,6 +39,10 @@ const LinphoneAddress* linphone_search_result_get_address(const LinphoneSearchRe return L_GET_CPP_PTR_FROM_C_OBJECT(searchResult)->getAddress(); } +const char* linphone_search_result_get_phone_number(const LinphoneSearchResult *searchResult) { + return L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(searchResult)->getPhoneNumber()); +} + unsigned int linphone_search_result_get_weight(const LinphoneSearchResult *searchResult) { return L_GET_CPP_PTR_FROM_C_OBJECT(searchResult)->getWeight(); } diff --git a/src/c-wrapper/c-wrapper.h b/src/c-wrapper/c-wrapper.h index e0109ce7c..11d1b2033 100644 --- a/src/c-wrapper/c-wrapper.h +++ b/src/c-wrapper/c-wrapper.h @@ -37,11 +37,13 @@ F(ChatMessage, ChatMessage) \ F(AbstractChatRoom, ChatRoom) \ F(Core, Core) \ + F(Content, Content) \ F(DialPlan, DialPlan) \ F(EventLog, EventLog) \ F(MagicSearch, MagicSearch) \ F(MediaSessionParams, CallParams) \ F(Participant, Participant) \ + F(ParticipantImdnState, ParticipantImdnState) \ F(SearchResult, SearchResult) #define L_REGISTER_SUBTYPES(F) \ @@ -85,7 +87,6 @@ BELLE_SIP_TYPE_ID(LinphoneConferenceParams), BELLE_SIP_TYPE_ID(LinphoneConfig), BELLE_SIP_TYPE_ID(LinphoneContactProvider), BELLE_SIP_TYPE_ID(LinphoneContactSearch), -BELLE_SIP_TYPE_ID(LinphoneContent), BELLE_SIP_TYPE_ID(LinphoneCoreCbs), BELLE_SIP_TYPE_ID(LinphoneErrorInfo), BELLE_SIP_TYPE_ID(LinphoneEvent), diff --git a/src/c-wrapper/internal/c-sal.cpp b/src/c-wrapper/internal/c-sal.cpp index 3e2457fc0..ae0ed5a2d 100644 --- a/src/c-wrapper/internal/c-sal.cpp +++ b/src/c-wrapper/internal/c-sal.cpp @@ -423,8 +423,9 @@ int sal_stream_description_equals(const SalStreamDescription *sd1, const SalStre if (sd1->dir != sd2->dir) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED; /* ICE */ - if (strcmp(sd1->ice_ufrag, sd2->ice_ufrag) != 0) result |= SAL_MEDIA_DESCRIPTION_ICE_RESTART_DETECTED; - if (strcmp(sd1->ice_pwd, sd2->ice_pwd) != 0) result |= SAL_MEDIA_DESCRIPTION_ICE_RESTART_DETECTED; + if (strcmp(sd1->ice_ufrag, sd2->ice_ufrag) != 0 && sd2->ice_ufrag[0] != '\0') result |= SAL_MEDIA_DESCRIPTION_ICE_RESTART_DETECTED; + if (strcmp(sd1->ice_pwd, sd2->ice_pwd) != 0 && sd2->ice_pwd[0] != '\0') result |= SAL_MEDIA_DESCRIPTION_ICE_RESTART_DETECTED; + /*DTLS*/ if (sd1->dtls_role != sd2->dtls_role) result |= SAL_MEDIA_DESCRIPTION_CRYPTO_KEYS_CHANGED; @@ -485,8 +486,8 @@ int sal_media_description_equals(const SalMediaDescription *md1, const SalMediaD if (md1->bandwidth != md2->bandwidth) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED; /* ICE */ - if (strcmp(md1->ice_ufrag, md2->ice_ufrag) != 0) result |= SAL_MEDIA_DESCRIPTION_ICE_RESTART_DETECTED; - if (strcmp(md1->ice_pwd, md2->ice_pwd) != 0) result |= SAL_MEDIA_DESCRIPTION_ICE_RESTART_DETECTED; + if (strcmp(md1->ice_ufrag, md2->ice_ufrag) != 0 && md2->ice_ufrag[0] != '\0') result |= SAL_MEDIA_DESCRIPTION_ICE_RESTART_DETECTED; + if (strcmp(md1->ice_pwd, md2->ice_pwd) != 0 && md2->ice_pwd[0] != '\0') result |= SAL_MEDIA_DESCRIPTION_ICE_RESTART_DETECTED; for(i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; ++i){ if (!sal_stream_description_active(&md1->streams[i]) && !sal_stream_description_active(&md2->streams[i])) continue; @@ -881,65 +882,38 @@ const char* sal_privacy_to_string(SalPrivacy privacy) { } } -static void remove_trailing_spaces(char *line) { - size_t size = strlen(line); - char *end = line + size - 1; - while (end >= line && isspace(*end)) { - end--; - } - *(end + 1) = '\0'; -} - -static int line_get_value(const char *input, const char *key, char *value, size_t value_size, size_t *read){ - const char *end=strchr(input,'\n'); - char line[256]={0}; - char key_candidate[256]; +static int line_get_value(const char *input, const char *key, char *value, size_t value_size, size_t *read) { + const char *end = strchr(input, '\n'); + char line[256] = {0}; + char key_candidate[256]; // key_candidate array must have the same size of line array to avoid potential invalid writes char *equal; size_t len; - if (!end) len=strlen(input); - else len=(size_t)(end + 1 - input); - *read=len; - strncpy(line,input,MIN(len,sizeof(line))); - equal=strchr(line,'='); + + if (!end) len = strlen(input); + else len = (size_t)(end + 1 - input); + *read = len; + strncpy(line, input, MIN(len, sizeof(line))); + + equal = strchr(line, '='); if (!equal) return FALSE; - *equal='\0'; - if (sscanf(line,"%s",key_candidate)!=1) return FALSE; - if (strcasecmp(key,key_candidate)==0){ - equal++; - remove_trailing_spaces(equal); - strncpy(value,equal,value_size-1); - value[value_size-1]='\0'; - return TRUE; - } - return FALSE; + *equal = '\0'; + + if (sscanf(line, "%s", key_candidate) != 1) return FALSE; + if (strcasecmp(key, key_candidate) != 0) return FALSE; + + equal++; + if (strlen(equal) >= value_size) equal[value_size - 1] = '\0'; + if (sscanf(equal, "%s", value) != 1) return FALSE; + return TRUE; } -int sal_lines_get_value(const char *data, const char *key, char *value, size_t value_size){ - size_t read=0; +int sal_lines_get_value(const char *data, const char *key, char *value, size_t value_size) { + size_t read = 0; - do{ - if (line_get_value(data,key,value,value_size,&read)) + do { + if (line_get_value(data, key, value, value_size, &read)) return TRUE; - data+=read; - }while(read!=0); + data += read; + } while (read != 0); return FALSE; } - -#if 0 -const char *sal_op_get_entity_tag(const SalOp* op) { - SalOpBase* op_base = (SalOpBase*)op; - return op_base->entity_tag; -} - - -void sal_op_set_entity_tag(SalOp *op, const char* entity_tag) { - SalOpBase* op_base = (SalOpBase*)op; - if (op_base->entity_tag != NULL){ - ms_free(op_base->entity_tag); - } - if (entity_tag) - op_base->entity_tag = ms_strdup(entity_tag); - else - op_base->entity_tag = NULL; -} -#endif diff --git a/src/c-wrapper/internal/c-sal.h b/src/c-wrapper/internal/c-sal.h index 4aeca0042..f34c4ee5f 100644 --- a/src/c-wrapper/internal/c-sal.h +++ b/src/c-wrapper/internal/c-sal.h @@ -636,6 +636,9 @@ const char * sal_body_handler_get_type(const SalBodyHandler *body_handler); void sal_body_handler_set_type(SalBodyHandler *body_handler, const char *type); const char * sal_body_handler_get_subtype(const SalBodyHandler *body_handler); void sal_body_handler_set_subtype(SalBodyHandler *body_handler, const char *subtype); +const belle_sip_list_t * sal_body_handler_get_content_type_parameters_names(const SalBodyHandler *body_handler); +const char * sal_body_handler_get_content_type_parameter(const SalBodyHandler *body_handler, const char *name); +void sal_body_handler_set_content_type_parameter(SalBodyHandler *body_handler, const char *paramName, const char *paramValue); const char * sal_body_handler_get_encoding(const SalBodyHandler *body_handler); void sal_body_handler_set_encoding(SalBodyHandler *body_handler, const char *encoding); void * sal_body_handler_get_data(const SalBodyHandler *body_handler); @@ -644,8 +647,10 @@ size_t sal_body_handler_get_size(const SalBodyHandler *body_handler); void sal_body_handler_set_size(SalBodyHandler *body_handler, size_t size); bool_t sal_body_handler_is_multipart(const SalBodyHandler *body_handler); SalBodyHandler * sal_body_handler_get_part(const SalBodyHandler *body_handler, int idx); +const belle_sip_list_t * sal_body_handler_get_parts(const SalBodyHandler *body_handler); SalBodyHandler * sal_body_handler_find_part_by_header(const SalBodyHandler *body_handler, const char *header_name, const char *header_value); const char * sal_body_handler_get_header(const SalBodyHandler *body_handler, const char *header_name); +const belle_sip_list_t* sal_body_handler_get_headers(const SalBodyHandler *body_handler); /*this function parses a document with key=value pairs separated by new lines, and extracts the value for a given key*/ int sal_lines_get_value(const char *data, const char *key, char *value, size_t value_size); diff --git a/src/c-wrapper/internal/c-tools.h b/src/c-wrapper/internal/c-tools.h index 17ec09ff5..492cbaccf 100644 --- a/src/c-wrapper/internal/c-tools.h +++ b/src/c-wrapper/internal/c-tools.h @@ -140,6 +140,9 @@ private: struct WrappedClonableObject { belle_sip_object_t base; CppType *cppPtr; + + // By default: External. + WrappedObjectOwner owner; }; // --------------------------------------------------------------------------- @@ -236,7 +239,7 @@ public: : wrappedObject->cppPtr; if (cppObject) - cppObject->setCBackPtr(nullptr); \ + cppObject->setCBackPtr(nullptr); wrappedObject->cppPtr.~shared_ptr(); wrappedObject->weakCppPtr.~weak_ptr(); @@ -248,7 +251,9 @@ public: typename = typename std::enable_if::value, CppType>::type > static void uninitClonableCppObject (CType *cObject) { - delete reinterpret_cast *>(cObject)->cppPtr; + WrappedClonableObject *wrappedObject = reinterpret_cast *>(cObject); + if (wrappedObject->owner == WrappedObjectOwner::External) + delete wrappedObject->cppPtr; } // --------------------------------------------------------------------------- @@ -288,12 +293,22 @@ public: typename CppType, typename = typename std::enable_if::value, CppType>::type > - static void signalCppPtrDestruction (CppType *cppObject) { + static void handleObjectDestruction (CppType *cppObject) { void *value = cppObject->getCBackPtr(); if (value && static_cast *>(value)->owner == WrappedObjectOwner::Internal) belle_sip_object_unref(value); } + template< + typename CppType, + typename = typename std::enable_if::value, CppType>::type + > + static void handleClonableObjectDestruction (CppType *cppObject) { + void *value = cppObject->getCBackPtr(); + if (value && static_cast *>(value)->owner == WrappedObjectOwner::Internal) + belle_sip_object_unref(value); + } + // --------------------------------------------------------------------------- // Get c/cpp ptr helpers. // --------------------------------------------------------------------------- @@ -413,11 +428,13 @@ public: typename CppType = typename CTypeMetaInfo::cppType, typename = typename std::enable_if::value, CppType>::type > - static inline void setCppPtrFromC (CType *cObject, CppType* &&cppObject) { + static inline void setCppPtrFromC (CType *cObject, CppType *cppObject) { CppType **cppObjectAddr = &reinterpret_cast *>(cObject)->cppPtr; if (*cppObjectAddr == cppObject) return; - delete *cppObjectAddr; + + if (reinterpret_cast *>(cObject)->owner == WrappedObjectOwner::External) + delete *cppObjectAddr; *cppObjectAddr = cppObject; (*cppObjectAddr)->setCBackPtr(cObject); @@ -427,15 +444,6 @@ public: #endif } - template< - typename CType, - typename CppType = typename CTypeMetaInfo::cppType, - typename = typename std::enable_if::value, CppType>::type - > - static inline void setCppPtrFromC (CType *cObject, const CppType *cppObject) { - setCppPtrFromC(cObject, new CppType(*cppObject)); - } - // --------------------------------------------------------------------------- // Get c back ptr resolver helpers. // --------------------------------------------------------------------------- @@ -464,7 +472,8 @@ private: return static_cast(value); RetType *cObject = CppTypeMetaInfo::init(); - setCppPtrFromC(cObject, cppObject); + reinterpret_cast *>(cObject)->owner = WrappedObjectOwner::Internal; + setCppPtrFromC(cObject, const_cast(cppObject)); return cObject; } @@ -500,7 +509,6 @@ public: RetType *cObject = CppTypeMetaInfo::init(); reinterpret_cast *>(cObject)->owner = WrappedObjectOwner::Internal; - setCppPtrFromC(cObject, cppObject); return cObject; @@ -561,8 +569,11 @@ public: > static inline bctbx_list_t *getResolvedCListFromCppList (const std::list &cppList) { bctbx_list_t *result = nullptr; - for (const auto &value : cppList) - result = bctbx_list_append(result, getCBackPtr(&value)); + for (const auto &value : cppList) { + auto cValue = getCBackPtr(new CppType(value)); + reinterpret_cast *>(cValue)->owner = WrappedObjectOwner::External; + result = bctbx_list_append(result, cValue); + } return result; } @@ -600,9 +611,9 @@ LINPHONE_END_NAMESPACE #undef L_INTERNAL_WRAPPER_CONSTEXPR -#define L_INTERNAL_C_OBJECT_NO_XTOR(C_OBJECT) +#define L_INTERNAL_C_NO_XTOR(C_OBJECT) -#define L_INTERNAL_DECLARE_C_OBJECT(C_TYPE, CPP_TYPE, ...) \ +#define L_INTERNAL_DECLARE_C_OBJECT(C_TYPE, ...) \ static_assert(LinphonePrivate::CTypeMetaInfo::defined, "Type is not defined."); \ static_assert( \ LinphonePrivate::IsDefinedBaseCppObject< \ @@ -621,13 +632,13 @@ LINPHONE_END_NAMESPACE #define L_INTERNAL_DECLARE_C_OBJECT_FUNCTIONS(C_TYPE, CONSTRUCTOR, DESTRUCTOR) \ BELLE_SIP_DECLARE_VPTR_NO_EXPORT(Linphone ## C_TYPE); \ Linphone ## C_TYPE *_linphone_ ## C_TYPE ## _init () { \ - Linphone ## C_TYPE * object = belle_sip_object_new(Linphone ## C_TYPE); \ + Linphone ## C_TYPE *object = belle_sip_object_new(Linphone ## C_TYPE); \ new(&object->cppPtr) std::shared_ptr(); \ new(&object->weakCppPtr) std::weak_ptr(); \ CONSTRUCTOR(object); \ return object; \ } \ - static void _linphone_ ## C_TYPE ## _uninit(Linphone ## C_TYPE *object) { \ + static void _linphone_ ## C_TYPE ## _uninit (Linphone ## C_TYPE *object) { \ DESTRUCTOR(object); \ LinphonePrivate::Wrapper::uninitBaseCppObject(object); \ } \ @@ -643,6 +654,45 @@ LINPHONE_END_NAMESPACE FALSE \ ); +#define L_INTERNAL_DECLARE_C_CLONABLE_OBJECT(C_TYPE, ...) \ + static_assert(LinphonePrivate::CTypeMetaInfo::defined, "Type is not defined."); \ + static_assert( \ + LinphonePrivate::IsDefinedClonableCppObject< \ + LinphonePrivate::CTypeMetaInfo::cppType \ + >::value, \ + "Type is not declared as clonable object." \ + ); \ + struct _Linphone ## C_TYPE { \ + belle_sip_object_t base; \ + L_CPP_TYPE_OF_C_TYPE(C_TYPE) *cppPtr; \ + int owner; \ + __VA_ARGS__ \ + }; \ + +#define L_INTERNAL_DECLARE_C_CLONABLE_OBJECT_FUNCTIONS(C_TYPE, CONSTRUCTOR, DESTRUCTOR) \ + BELLE_SIP_DECLARE_VPTR_NO_EXPORT(Linphone ## C_TYPE); \ + Linphone ## C_TYPE *_linphone_ ## C_TYPE ## _init () { \ + Linphone ## C_TYPE *object = belle_sip_object_new(Linphone ## C_TYPE); \ + CONSTRUCTOR(object); \ + return object; \ + } \ + static void _linphone_ ## C_TYPE ## _uninit (Linphone ## C_TYPE * object) { \ + DESTRUCTOR(object); \ + LinphonePrivate::Wrapper::uninitClonableCppObject(object); \ + } \ + static void _linphone_ ## C_TYPE ## _clone (Linphone ## C_TYPE *dest, const Linphone ## C_TYPE *src) { \ + L_ASSERT(src->cppPtr); \ + dest->cppPtr = new L_CPP_TYPE_OF_C_TYPE(C_TYPE)(*src->cppPtr); \ + } \ + BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(Linphone ## C_TYPE); \ + BELLE_SIP_INSTANCIATE_VPTR( \ + Linphone ## C_TYPE, belle_sip_object_t, \ + _linphone_ ## C_TYPE ## _uninit, \ + _linphone_ ## C_TYPE ## _clone, \ + NULL, \ + FALSE \ + ); + // ============================================================================= // Public Wrapper API. // ============================================================================= @@ -702,47 +752,23 @@ LINPHONE_END_NAMESPACE // Declare wrapped C object with constructor/destructor. #define L_DECLARE_C_OBJECT_IMPL_WITH_XTORS(C_TYPE, CONSTRUCTOR, DESTRUCTOR, ...) \ - L_INTERNAL_DECLARE_C_OBJECT(C_TYPE, L_CPP_TYPE_OF_C_TYPE(C_TYPE), __VA_ARGS__) \ + L_INTERNAL_DECLARE_C_OBJECT(C_TYPE, __VA_ARGS__) \ L_INTERNAL_DECLARE_C_OBJECT_FUNCTIONS(C_TYPE, CONSTRUCTOR, DESTRUCTOR) // Declare wrapped C object. #define L_DECLARE_C_OBJECT_IMPL(C_TYPE, ...) \ - L_INTERNAL_DECLARE_C_OBJECT(C_TYPE, L_CPP_TYPE_OF_C_TYPE(C_TYPE), __VA_ARGS__) \ - L_INTERNAL_DECLARE_C_OBJECT_FUNCTIONS(C_TYPE, L_INTERNAL_C_OBJECT_NO_XTOR, L_INTERNAL_C_OBJECT_NO_XTOR) + L_INTERNAL_DECLARE_C_OBJECT(C_TYPE, __VA_ARGS__) \ + L_INTERNAL_DECLARE_C_OBJECT_FUNCTIONS(C_TYPE, L_INTERNAL_C_NO_XTOR, L_INTERNAL_C_NO_XTOR) + +// Declare clonable wrapped C object with constructor/destructor. +#define L_DECLARE_C_CLONABLE_OBJECT_IMPL_WITH_XTORS(C_TYPE, CONSTRUCTOR, DESTRUCTOR, ...) \ + L_INTERNAL_DECLARE_C_CLONABLE_OBJECT(C_TYPE, __VA_ARGS__) \ + L_INTERNAL_DECLARE_C_CLONABLE_OBJECT_FUNCTIONS(C_TYPE, CONSTRUCTOR, DESTRUCTOR) // Declare clonable wrapped C object. #define L_DECLARE_C_CLONABLE_OBJECT_IMPL(C_TYPE, ...) \ - static_assert(LinphonePrivate::CTypeMetaInfo::defined, "Type is not defined."); \ - static_assert( \ - LinphonePrivate::IsDefinedClonableCppObject< \ - LinphonePrivate::CTypeMetaInfo::cppType \ - >::value, \ - "Type is not declared as clonable object." \ - ); \ - struct _Linphone ## C_TYPE { \ - belle_sip_object_t base; \ - L_CPP_TYPE_OF_C_TYPE(C_TYPE) *cppPtr; \ - __VA_ARGS__ \ - }; \ - BELLE_SIP_DECLARE_VPTR_NO_EXPORT(Linphone ## C_TYPE); \ - Linphone ## C_TYPE *_linphone_ ## C_TYPE ## _init() { \ - return belle_sip_object_new(Linphone ## C_TYPE); \ - } \ - static void _linphone_ ## C_TYPE ## _uninit(Linphone ## C_TYPE * object) { \ - LinphonePrivate::Wrapper::uninitClonableCppObject(object); \ - } \ - static void _linphone_ ## C_TYPE ## _clone(Linphone ## C_TYPE * dest, const Linphone ## C_TYPE * src) { \ - L_ASSERT(src->cppPtr); \ - dest->cppPtr = new L_CPP_TYPE_OF_C_TYPE(C_TYPE)(*src->cppPtr); \ - } \ - BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(Linphone ## C_TYPE); \ - BELLE_SIP_INSTANCIATE_VPTR( \ - Linphone ## C_TYPE, belle_sip_object_t, \ - _linphone_ ## C_TYPE ## _uninit, \ - _linphone_ ## C_TYPE ## _clone, \ - NULL, \ - FALSE \ - ); + L_INTERNAL_DECLARE_C_CLONABLE_OBJECT(C_TYPE, __VA_ARGS__) \ + L_INTERNAL_DECLARE_C_CLONABLE_OBJECT_FUNCTIONS(C_TYPE, L_INTERNAL_C_NO_XTOR, L_INTERNAL_C_NO_XTOR) // ----------------------------------------------------------------------------- // Helpers. @@ -755,10 +781,6 @@ LINPHONE_END_NAMESPACE // Call the init function of wrapped C object. #define L_INIT(C_TYPE) _linphone_ ## C_TYPE ## _init() -// Signal to wrapper the destruction of cpp base object. -#define L_SIGNAL_CPP_PTR_DESTRUCTION(CPP_OBJECT) \ - LinphonePrivate::Wrapper::signalCppPtrDestruction(CPP_OBJECT); - // Get/set the cpp-ptr of a wrapped C object. #define L_GET_CPP_PTR_FROM_C_OBJECT_1_ARGS(C_OBJECT) \ LinphonePrivate::Wrapper::getCppPtrFromC(C_OBJECT) diff --git a/src/call/call-p.h b/src/call/call-p.h index 0477198df..488df87aa 100644 --- a/src/call/call-p.h +++ b/src/call/call-p.h @@ -111,6 +111,7 @@ private: bool isPlayingRingbackTone (const std::shared_ptr &session) override; void onRealTimeTextCharacterReceived (const std::shared_ptr &session, RealtimeTextReceivedCharacter *character) override; void onTmmbrReceived(const std::shared_ptr &session, int streamIndex, int tmmbr) override; + void onSnapshotTaken(const std::shared_ptr &session, const char *file_path) override; mutable LinphonePlayer *player = nullptr; diff --git a/src/call/call.cpp b/src/call/call.cpp index 6d51ce781..a16d08482 100644 --- a/src/call/call.cpp +++ b/src/call/call.cpp @@ -41,10 +41,8 @@ bool CallPrivate::getAudioMuted () const { shared_ptr CallPrivate::getChatRoom () { L_Q(); if (!chatRoom && (q->getState() != CallSession::State::End) && (q->getState() != CallSession::State::Released)) { - ChatRoomId chatRoomId(q->getRemoteAddress(), q->getLocalAddress()); - RealTimeTextChatRoom *rttcr = new RealTimeTextChatRoom(q->getCore(), chatRoomId); - chatRoom.reset(rttcr); - rttcr->getPrivate()->setCall(q->getSharedFromThis()); + chatRoom = static_pointer_cast(q->getCore()->getOrCreateBasicChatRoom(q->getRemoteAddress(), true)); + chatRoom->getPrivate()->setCall(q->getSharedFromThis()); } return chatRoom; } @@ -124,7 +122,6 @@ shared_ptr CallPrivate::startReferredCall (const MediaSessionParams *param L_GET_PRIVATE(getActiveSession())->setReferPending(false); LinphoneCallParams *lcp = L_GET_C_BACK_PTR(&msp); LinphoneCall *newCall = linphone_core_invite_with_params(q->getCore()->getCCore(), q->getReferTo().c_str(), lcp); - linphone_call_params_unref(lcp); if (newCall) { getActiveSession()->getPrivate()->setTransferTarget(L_GET_PRIVATE_FROM_C_OBJECT(newCall)->getActiveSession()); L_GET_PRIVATE_FROM_C_OBJECT(newCall)->getActiveSession()->getPrivate()->notifyReferState(); @@ -418,6 +415,7 @@ void CallPrivate::onFirstVideoFrameDecoded (const shared_ptr &sessi nextVideoFrameDecoded._func = nullptr; nextVideoFrameDecoded._user_data = nullptr; } + linphone_call_notify_next_video_frame_decoded(L_GET_C_BACK_PTR(q)); } void CallPrivate::onResetFirstVideoFrameDecoded (const shared_ptr &session) { @@ -463,7 +461,7 @@ void CallPrivate::onStopRingingIfNeeded (const shared_ptr &session) L_Q(); LinphoneCore *lc = q->getCore()->getCCore(); bool stopRinging = true; - bool ringDuringEarlyMedia = linphone_core_get_ring_during_incoming_early_media(lc); + bool ringDuringEarlyMedia = !!linphone_core_get_ring_during_incoming_early_media(lc); for (const auto &call : q->getCore()->getCalls()) { if ((call->getState() == CallSession::State::IncomingReceived) || (ringDuringEarlyMedia && call->getState() == CallSession::State::IncomingEarlyMedia)) { @@ -496,6 +494,11 @@ void CallPrivate::onTmmbrReceived (const shared_ptr &session, int s linphone_call_notify_tmmbr_received(L_GET_C_BACK_PTR(q), streamIndex, tmmbr); } +void CallPrivate::onSnapshotTaken(const shared_ptr &session, const char *file_path) { + L_Q(); + linphone_call_notify_snapshot_taken(L_GET_C_BACK_PTR(q), file_path); +} + // ============================================================================= Call::Call (CallPrivate &p, shared_ptr core) : Object(p), CoreAccessor(core) { diff --git a/src/call/call.h b/src/call/call.h index 4cfbf9a8a..7566d9420 100644 --- a/src/call/call.h +++ b/src/call/call.h @@ -34,7 +34,7 @@ class CallPrivate; class CallSessionPrivate; class MediaSessionPrivate; -class Call : public Object, public CoreAccessor { +class LINPHONE_PUBLIC Call : public Object, public CoreAccessor { friend class CallSessionPrivate; friend class ChatMessage; friend class ChatMessagePrivate; diff --git a/src/chat/chat-message/chat-message-p.h b/src/chat/chat-message/chat-message-p.h index 4c957ed71..86bdff7e1 100644 --- a/src/chat/chat-message/chat-message-p.h +++ b/src/chat/chat-message/chat-message-p.h @@ -26,10 +26,11 @@ #include "chat/chat-room/chat-room-id.h" #include "chat/modifier/file-transfer-chat-message-modifier.h" #include "chat/notification/imdn.h" -#include "content/content-type.h" #include "content/content.h" +#include "content/content-type.h" #include "content/file-content.h" #include "content/file-transfer-content.h" +#include "db/main-db.h" #include "db/main-db-chat-message-key.h" #include "event-log/conference/conference-chat-message-event.h" #include "object/object-p.h" @@ -43,6 +44,7 @@ class ChatMessagePrivate : public ObjectPrivate { friend class CpimChatMessageModifier; friend class EncryptionChatMessageModifier; friend class MultipartChatMessageModifier; + friend class NotificationMessagePrivate; public: enum Step { @@ -58,9 +60,8 @@ public: void setDirection (ChatMessage::Direction dir); - void setParticipantState (const IdentityAddress &participantAddress, ChatMessage::State newState); - std::list> getParticipantsInState (const ChatMessage::State state) const; - void setState (ChatMessage::State newState, bool force = false); + void setParticipantState (const IdentityAddress &participantAddress, ChatMessage::State newState, time_t stateChangeTime); + virtual void setState (ChatMessage::State newState, bool force = false); void setTime (time_t time); @@ -98,6 +99,13 @@ public: SalOp *getSalOp () const; void setSalOp (SalOp *op); + bool getDisplayNotificationRequired () const { return displayNotificationRequired; } + bool getNegativeDeliveryNotificationRequired () const { return negativeDeliveryNotificationRequired; } + bool getPositiveDeliveryNotificationRequired () const { return positiveDeliveryNotificationRequired; } + virtual void setDisplayNotificationRequired (bool value) { displayNotificationRequired = value; } + virtual void setNegativeDeliveryNotificationRequired (bool value) { negativeDeliveryNotificationRequired = value; } + virtual void setPositiveDeliveryNotificationRequired (bool value) { positiveDeliveryNotificationRequired = value; } + SalCustomHeader *getSalCustomHeaders () const; void setSalCustomHeaders (SalCustomHeader *headers); @@ -137,16 +145,14 @@ public: bool hasFileTransferContent () const; const Content* getFileTransferContent () const; - LinphoneContent *getFileTransferInformation () const; - void setFileTransferInformation (const LinphoneContent *content); + const Content* getFileTransferInformation () const; + void setFileTransferInformation (Content *content); - void addContent (Content &content); - void removeContent (const Content &content); + void addContent (Content *content); + void removeContent (Content *content); bool downloadFile (); - void sendImdn (Imdn::Type imdnType, LinphoneReason reason); - void notifyReceiving (); LinphoneReason receive (); void send (); @@ -155,11 +161,21 @@ public: void updateInDb (); private: - ChatMessagePrivate(const std::shared_ptr &cr, ChatMessage::Direction dir); - + static bool validStateTransition (ChatMessage::State currentState, ChatMessage::State newState); +public: + mutable MainDbChatMessageKey dbKey; + +protected: + bool displayNotificationRequired = true; + bool negativeDeliveryNotificationRequired = true; + bool positiveDeliveryNotificationRequired = true; + bool toBeStored = true; + std::string contentEncoding; + +private: // TODO: Clean attributes. time_t time = ::ms_time(0); // TODO: Change me in all files. std::string imdnId; @@ -188,10 +204,6 @@ private: // TODO: Remove my comment. VARIABLES OK. // Do not expose. -public: - mutable MainDbChatMessageKey dbKey; - -private: std::weak_ptr chatRoom; ChatRoomId chatRoomId; IdentityAddress fromAddress; @@ -203,7 +215,6 @@ private: std::list contents; bool encryptionPrevented = false; - bool toBeStored = true; mutable bool contentsNotLoadedFromDatabase = false; L_DECLARE_PUBLIC(ChatMessage); }; diff --git a/src/chat/chat-message/chat-message.cpp b/src/chat/chat-message/chat-message.cpp index 0fcde7521..ff2a48399 100644 --- a/src/chat/chat-message/chat-message.cpp +++ b/src/chat/chat-message/chat-message.cpp @@ -19,6 +19,7 @@ #include "object/object-p.h" +#include "linphone/api/c-content.h" #include "linphone/core.h" #include "linphone/lpconfig.h" #include "linphone/utils/utils.h" @@ -32,15 +33,15 @@ #include "chat/chat-room/real-time-text-chat-room.h" #include "chat/modifier/cpim-chat-message-modifier.h" #include "chat/modifier/encryption-chat-message-modifier.h" -#include "chat/modifier/file-transfer-chat-message-modifier.h" #include "chat/modifier/multipart-chat-message-modifier.h" +#include "chat/notification/imdn.h" #include "conference/participant.h" -#include "content/file-content.h" -#include "content/content.h" +#include "conference/participant-imdn-state.h" +#include "content/content-disposition.h" +#include "content/header/header-param.h" #include "core/core.h" #include "core/core-p.h" #include "logger/logger.h" -#include "chat/notification/imdn.h" #include "sip-tools/sip-headers.h" #include "ortp/b64.h" @@ -70,18 +71,9 @@ void ChatMessagePrivate::setIsReadOnly (bool readOnly) { isReadOnly = readOnly; } -void ChatMessagePrivate::setParticipantState (const IdentityAddress &participantAddress, ChatMessage::State newState) { +void ChatMessagePrivate::setParticipantState (const IdentityAddress &participantAddress, ChatMessage::State newState, time_t stateChangeTime) { L_Q(); - if (!(q->getChatRoom()->getCapabilities() & AbstractChatRoom::Capabilities::Conference) - || (linphone_config_get_bool(linphone_core_get_config(q->getChatRoom()->getCore()->getCCore()), - "misc", "enable_simple_group_chat_message_state", TRUE - )) - ) { - setState(newState); - return; - } - if (!dbKey.isValid()) return; @@ -93,7 +85,25 @@ void ChatMessagePrivate::setParticipantState (const IdentityAddress &participant lInfo() << "Chat message " << this << ": moving participant '" << participantAddress.asString() << "' state to " << Utils::toString(newState); - mainDb->setChatMessageParticipantState(eventLog, participantAddress, newState); + mainDb->setChatMessageParticipantState(eventLog, participantAddress, newState, stateChangeTime); + + LinphoneChatMessage *msg = L_GET_C_BACK_PTR(q); + LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg); + if (cbs && linphone_chat_message_cbs_get_participant_imdn_state_changed(cbs)) { + auto participant = q->getChatRoom()->findParticipant(participantAddress); + ParticipantImdnState imdnState(participant, newState, stateChangeTime); + linphone_chat_message_cbs_get_participant_imdn_state_changed(cbs)(msg, + _linphone_participant_imdn_state_from_cpp_obj(imdnState) + ); + } + + if (linphone_config_get_bool(linphone_core_get_config(q->getChatRoom()->getCore()->getCCore()), + "misc", "enable_simple_group_chat_message_state", FALSE + ) + ) { + setState(newState); + return; + } list states = mainDb->getChatMessageParticipantStates(eventLog); size_t nbDisplayedStates = 0; @@ -123,29 +133,6 @@ void ChatMessagePrivate::setParticipantState (const IdentityAddress &participant setState(ChatMessage::State::DeliveredToUser); } -list> ChatMessagePrivate::getParticipantsInState (const ChatMessage::State state) const { - L_Q(); - - list> participantsInState; - if (!(q->getChatRoom()->getCapabilities() & AbstractChatRoom::Capabilities::Conference) || !dbKey.isValid()) { - return participantsInState; - } - - unique_ptr &mainDb = q->getChatRoom()->getCore()->getPrivate()->mainDb; - shared_ptr eventLog = mainDb->getEventFromKey(dbKey); - list addressesInState = mainDb->getChatMessageParticipantsInState(eventLog, state); - const list> &participants = q->getChatRoom()->getParticipants(); - for (IdentityAddress addr : addressesInState) { - for (const auto &participant : participants) { - if (participant->getAddress() == addr) { - participantsInState.push_back(participant); - } - } - } - - return participantsInState; -} - void ChatMessagePrivate::setState (ChatMessage::State newState, bool force) { L_Q(); @@ -173,8 +160,9 @@ void ChatMessagePrivate::setState (ChatMessage::State newState, bool force) { if (state == ChatMessage::State::FileTransferDone && !hasFileTransferContent()) { // We wait until the file has been downloaded to send the displayed IMDN - q->sendDisplayNotification(); - setState(ChatMessage::State::Displayed); + bool doNotStoreInDb = static_cast(q->getChatRoom()->getPrivate())->sendDisplayNotification(q->getSharedFromThis()); + // Force the state so it is stored directly in DB, but when the IMDN has successfully been delivered + setState(ChatMessage::State::Displayed, doNotStoreInDb); } else { updateInDb(); } @@ -239,8 +227,8 @@ const Content* ChatMessagePrivate::getTextContent() const { } bool ChatMessagePrivate::hasFileTransferContent() const { - for (const Content *c : getContents()) { - if (c->getContentType() == ContentType::FileTransfer) { + for (const Content *c : contents) { + if (c->isFileTransfer()) { return true; } } @@ -248,8 +236,8 @@ bool ChatMessagePrivate::hasFileTransferContent() const { } const Content* ChatMessagePrivate::getFileTransferContent() const { - for (const Content *c : getContents()) { - if (c->getContentType() == ContentType::FileTransfer) { + for (const Content *c : contents) { + if (c->isFileTransfer()) { return c; } } @@ -374,51 +362,54 @@ void ChatMessagePrivate::setText (const string &text) { } } -LinphoneContent *ChatMessagePrivate::getFileTransferInformation () const { +const Content *ChatMessagePrivate::getFileTransferInformation () const { if (hasFileTransferContent()) { - return getFileTransferContent()->toLinphoneContent(); + return getFileTransferContent(); } for (const Content *c : getContents()) { if (c->isFile()) { FileContent *fileContent = (FileContent *)c; - return fileContent->toLinphoneContent(); + return fileContent; } } return nullptr; } -void ChatMessagePrivate::setFileTransferInformation (const LinphoneContent *c_content) { +void ChatMessagePrivate::setFileTransferInformation (Content *content) { L_Q(); - // Create a FileContent, it will create the FileTransferContent at upload time - FileContent *fileContent = new FileContent(); - ContentType contentType(linphone_content_get_type(c_content), linphone_content_get_subtype(c_content)); - fileContent->setContentType(contentType); - fileContent->setFileSize(linphone_content_get_size(c_content)); - fileContent->setFileName(linphone_content_get_name(c_content)); - if (linphone_content_get_string_buffer(c_content)) { - fileContent->setBody(linphone_content_get_string_buffer(c_content)); + if (content->isFile()) { + q->addContent(content); + } else { + // This scenario is more likely to happen because the caller is using the C API + LinphoneContent *c_content = L_GET_C_BACK_PTR(content); + FileContent *fileContent = new FileContent(); + fileContent->setContentType(content->getContentType()); + fileContent->setFileSize(linphone_content_get_size(c_content)); // This information is only available from C Content if it was created from C API + fileContent->setFileName(linphone_content_get_name(c_content)); // This information is only available from C Content if it was created from C API + if (!content->isEmpty()) { + fileContent->setBody(content->getBody()); + } + q->addContent(fileContent); } - - q->addContent(*fileContent); } bool ChatMessagePrivate::downloadFile () { L_Q(); for (auto &content : getContents()) - if (content->getContentType() == ContentType::FileTransfer) - return q->downloadFile(*static_cast(content)); + if (content->isFileTransfer()) + return q->downloadFile(static_cast(content)); return false; } -void ChatMessagePrivate::addContent (Content &content) { - getContents().push_back(&content); +void ChatMessagePrivate::addContent (Content *content) { + getContents().push_back(content); } -void ChatMessagePrivate::removeContent (const Content &content) { - getContents().remove(&const_cast(content)); +void ChatMessagePrivate::removeContent (Content *content) { + getContents().remove(content); } void ChatMessagePrivate::loadFileTransferUrlFromBodyToContent() { @@ -445,32 +436,13 @@ void ChatMessagePrivate::setChatRoom (const shared_ptr &cr) { // ----------------------------------------------------------------------------- -void ChatMessagePrivate::sendImdn (Imdn::Type imdnType, LinphoneReason reason) { - L_Q(); - - shared_ptr msg = q->getChatRoom()->createChatMessage(); - - Content *content = new Content(); - content->setContentType(ContentType::Imdn); - content->setBody(Imdn::createXml(imdnId, time, imdnType, reason)); - msg->addContent(*content); - - if (reason != LinphoneReasonNone) - msg->getPrivate()->setEncryptionPrevented(true); - - msg->setToBeStored(false); - msg->getPrivate()->addSalCustomHeader(PriorityHeader::HeaderName, PriorityHeader::NonUrgent); - - msg->getPrivate()->send(); -} - static void forceUtf8Content (Content &content) { // TODO: Deal with other content type in the future. ContentType contentType = content.getContentType(); if (contentType != ContentType::PlainText) return; - string charset = contentType.getParameter(); + string charset = contentType.getParameter("charset").getValue(); if (charset.empty()) return; @@ -489,7 +461,7 @@ static void forceUtf8Content (Content &content) { if (!utf8Body.empty()) { // TODO: use move operator if possible in the future! content.setBodyFromUtf8(utf8Body); - contentType.setParameter(string(contentType.getParameter()).replace(begin, end - begin, "UTF-8")); + contentType.addParameter("charset", "UTF-8"); content.setContentType(contentType); } } @@ -500,11 +472,16 @@ static void forceUtf8Content (Content &content) { void ChatMessagePrivate::notifyReceiving () { L_Q(); - LinphoneChatRoom *chatRoom = L_GET_C_BACK_PTR(q->getChatRoom()); + LinphoneChatRoom *chatRoom = static_pointer_cast(q->getChatRoom())->getPrivate()->getCChatRoom(); if ((getContentType() != ContentType::Imdn) && (getContentType() != ContentType::ImIsComposing)) { _linphone_chat_room_notify_chat_message_should_be_stored(chatRoom, L_GET_C_BACK_PTR(q->getSharedFromThis())); if (toBeStored) storeInDb(); + } else { + // For compatibility, when CPIM is not used + positiveDeliveryNotificationRequired = false; + negativeDeliveryNotificationRequired = false; + displayNotificationRequired = false; } shared_ptr event = make_shared( ::time(nullptr), q->getSharedFromThis() @@ -513,9 +490,8 @@ void ChatMessagePrivate::notifyReceiving () { // Legacy q->getChatRoom()->getPrivate()->notifyChatMessageReceived(q->getSharedFromThis()); - if ((getContentType() != ContentType::Imdn) && (getContentType() != ContentType::ImIsComposing)) { - q->sendDeliveryNotification(LinphoneReasonNone); - } + if (getPositiveDeliveryNotificationRequired()) + static_cast(q->getChatRoom()->getPrivate())->sendDeliveryNotification(q->getSharedFromThis()); } LinphoneReason ChatMessagePrivate::receive () { @@ -539,7 +515,12 @@ LinphoneReason ChatMessagePrivate::receive () { /* Unable to decrypt message */ chatRoom->getPrivate()->notifyUndecryptableChatMessageReceived(q->getSharedFromThis()); reason = linphone_error_code_to_reason(errorCode); - q->sendDeliveryNotification(reason); + if (getNegativeDeliveryNotificationRequired()) { + static_cast(q->getChatRoom()->getPrivate())->sendDeliveryErrorNotification( + q->getSharedFromThis(), + reason + ); + } return reason; } else if (result == ChatMessageModifier::Result::Suspended) { currentRecvStep |= ChatMessagePrivate::Step::Encryption; @@ -597,11 +578,13 @@ LinphoneReason ChatMessagePrivate::receive () { if (errorCode <= 0) { bool foundSupportContentType = false; for (Content *c : contents) { - if (linphone_core_is_content_type_supported(core->getCCore(), c->getContentType().asString().c_str())) { + ContentType ct(c->getContentType()); + ct.cleanParameters(); + if (linphone_core_is_content_type_supported(core->getCCore(), ct.asString().c_str())) { foundSupportContentType = true; break; } else - lError() << "Unsupported content-type: " << c->getContentType().asString(); + lError() << "Unsupported content-type: " << c->getContentType(); } if (!foundSupportContentType) { @@ -621,7 +604,12 @@ LinphoneReason ChatMessagePrivate::receive () { if (errorCode > 0) { reason = linphone_error_code_to_reason(errorCode); - q->sendDeliveryNotification(reason); + if (getNegativeDeliveryNotificationRequired()) { + static_cast(q->getChatRoom()->getPrivate())->sendDeliveryErrorNotification( + q->getSharedFromThis(), + reason + ); + } return reason; } @@ -692,11 +680,11 @@ void ChatMessagePrivate::send () { core->getCCore(), op, peer, getSalCustomHeaders(), !!lp_config_get_int(core->getCCore()->config, "sip", "chat_msg_with_contact", 0) ); - op->set_user_pointer(q); /* If out of call, directly store msg */ + op->setUserPointer(q); /* If out of call, directly store msg */ linphone_address_unref(peer); } - op->set_from(q->getFromAddress().asString().c_str()); - op->set_to(q->getToAddress().asString().c_str()); + op->setFrom(q->getFromAddress().asString().c_str()); + op->setTo(q->getToAddress().asString().c_str()); // --------------------------------------- // Start of message modification @@ -733,7 +721,7 @@ void ChatMessagePrivate::send () { EncryptionChatMessageModifier ecmm; ChatMessageModifier::Result result = ecmm.encode(q->getSharedFromThis(), errorCode); if (result == ChatMessageModifier::Result::Error) { - sal_error_info_set((SalErrorInfo *)op->get_error_info(), SalReasonNotAcceptable, "SIP", errorCode, "Unable to encrypt IM", nullptr); + sal_error_info_set((SalErrorInfo *)op->getErrorInfo(), SalReasonNotAcceptable, "SIP", errorCode, "Unable to encrypt IM", nullptr); setState(ChatMessage::State::NotDelivered); return; } else if (result == ChatMessageModifier::Result::Suspended) { @@ -760,23 +748,28 @@ void ChatMessagePrivate::send () { auto msgOp = dynamic_cast(op); if (!externalBodyUrl.empty()) { - char *content_type = ms_strdup_printf("message/external-body; access-type=URL; URL=\"%s\"", externalBodyUrl.c_str()); - msgOp->send_message(content_type, NULL); - ms_free(content_type); - } else if (internalContent.getContentType().isValid()) { - msgOp->send_message(internalContent.getContentType().asString().c_str(), internalContent.getBodyAsUtf8String().c_str()); + Content content; + ContentType contentType(ContentType::ExternalBody); + contentType.addParameter("access-type", "URL"); + contentType.addParameter("URL", "\"" + externalBodyUrl + "\""); + content.setContentType(contentType); + msgOp->sendMessage(content); } else { - msgOp->send_message(ContentType::PlainText.asString().c_str(), internalContent.getBodyAsUtf8String().c_str()); + if (!internalContent.getContentType().isValid()) + internalContent.setContentType(ContentType::PlainText); + if (!contentEncoding.empty()) + internalContent.setContentEncoding(contentEncoding); + msgOp->sendMessage(internalContent); } // Restore FileContents and remove FileTransferContents list::iterator it = contents.begin(); while (it != contents.end()) { Content *content = *it; - if (content->getContentType() == ContentType::FileTransfer) { - FileTransferContent *fileTransferContent = (FileTransferContent *)content; + if (content->isFileTransfer()) { + FileTransferContent *fileTransferContent = static_cast(content); it = contents.erase(it); - addContent(*fileTransferContent->getFileContent()); + addContent(fileTransferContent->getFileContent()); delete fileTransferContent; } else { it++; @@ -790,7 +783,7 @@ void ChatMessagePrivate::send () { currentSendStep = ChatMessagePrivate::Step::None; if (imdnId.empty()) - setImdnMessageId(op->get_call_id()); /* must be known at that time */ + setImdnMessageId(op->getCallId()); /* must be known at that time */ if (lcall && linphone_call_get_op(lcall) == op) { /* In this case, chat delivery status is not notified, so unrefing chat message right now */ @@ -879,17 +872,25 @@ bool ChatMessagePrivate::validStateTransition (ChatMessage::State currentState, // ----------------------------------------------------------------------------- ChatMessage::ChatMessage (const shared_ptr &chatRoom, ChatMessage::Direction direction) : - Object(*new ChatMessagePrivate(chatRoom,direction)), CoreAccessor(chatRoom->getCore()) { + Object(*new ChatMessagePrivate(chatRoom, direction)), CoreAccessor(chatRoom->getCore()) { +} + +ChatMessage::ChatMessage (ChatMessagePrivate &p) : Object(p), CoreAccessor(p.getPublic()->getChatRoom()->getCore()) { } ChatMessage::~ChatMessage () { L_D(); - - for (Content *content : d->contents) + + for (Content *content : d->contents) { + if (content->isFileTransfer()) { + FileTransferContent *fileTransferContent = static_cast(content); + delete fileTransferContent->getFileContent(); + } delete content; + } if (d->salOp) { - d->salOp->set_user_pointer(nullptr); + d->salOp->setUserPointer(nullptr); d->salOp->unref(); } if (d->salCustomHeaders) @@ -997,6 +998,28 @@ void ChatMessage::setToBeStored (bool value) { // ----------------------------------------------------------------------------- +list ChatMessage::getParticipantsByImdnState (ChatMessage::State state) const { + L_D(); + + list result; + if (!(getChatRoom()->getCapabilities() & AbstractChatRoom::Capabilities::Conference) || !d->dbKey.isValid()) + return result; + + unique_ptr &mainDb = getChatRoom()->getCore()->getPrivate()->mainDb; + shared_ptr eventLog = mainDb->getEventFromKey(d->dbKey); + list dbResults = mainDb->getChatMessageParticipantsByImdnState(eventLog, state); + for (const auto &dbResult : dbResults) { + auto sender = getChatRoom()->findParticipant(getFromAddress()); + auto participant = getChatRoom()->findParticipant(dbResult.address); + if (participant && (participant != sender)) + result.emplace_back(participant, dbResult.state, dbResult.timestamp); + } + + return result; +} + +// ----------------------------------------------------------------------------- + const LinphoneErrorInfo *ChatMessage::getErrorInfo () const { L_D(); if (!d->errorInfo) d->errorInfo = linphone_error_info_new(); // let's do it mutable @@ -1014,13 +1037,13 @@ const list &ChatMessage::getContents () const { return d->getContents(); } -void ChatMessage::addContent (Content &content) { +void ChatMessage::addContent (Content *content) { L_D(); if (!d->isReadOnly) d->addContent(content); } -void ChatMessage::removeContent (const Content &content) { +void ChatMessage::removeContent (Content *content) { L_D(); if (!d->isReadOnly) d->removeContent(content); @@ -1074,25 +1097,9 @@ void ChatMessage::send () { getChatRoom()->getPrivate()->sendChatMessage(getSharedFromThis()); } -void ChatMessage::sendDeliveryNotification (LinphoneReason reason) { +bool ChatMessage::downloadFile(FileTransferContent *fileTransferContent) { L_D(); - - LinphoneImNotifPolicy *policy = linphone_core_get_im_notif_policy(getCore()->getCCore()); - if (linphone_im_notif_policy_get_send_imdn_delivered(policy)) - d->sendImdn(Imdn::Type::Delivery, reason); -} - -void ChatMessage::sendDisplayNotification () { - L_D(); - - LinphoneImNotifPolicy *policy = linphone_core_get_im_notif_policy(getCore()->getCCore()); - if (linphone_im_notif_policy_get_send_imdn_displayed(policy)) - d->sendImdn(Imdn::Type::Display, LinphoneReasonNone); -} - -bool ChatMessage::downloadFile(FileTransferContent &fileTransferContent) { - L_D(); - return d->fileTransferChatMessageModifier.downloadFile(getSharedFromThis(), &fileTransferContent); + return d->fileTransferChatMessageModifier.downloadFile(getSharedFromThis(), fileTransferContent); } bool ChatMessage::isFileTransferInProgress() { @@ -1135,22 +1142,16 @@ int ChatMessage::putCharacter (uint32_t character) { if (character == newLine || character == crlf || character == lf) { shared_ptr core = getCore(); if (lp_config_get_int(core->getCCore()->config, "misc", "store_rtt_messages", 1) == 1) { - // TODO: History. - lDebug() << "New line sent, forge a message with content " << d->rttMessage.c_str(); - d->setTime(ms_time(0)); + lInfo() << "New line sent, forge a message with content " << d->rttMessage; d->state = State::Displayed; - // d->direction = Direction::Outgoing; - // setFromAddress(Address( - // linphone_address_as_string(linphone_address_new(linphone_core_get_identity(core->getCCore()))) - // )); - // linphone_chat_message_store(L_GET_C_BACK_PTR(this)); + d->setText(d->rttMessage); + d->storeInDb(); d->rttMessage = ""; } } else { char *value = LinphonePrivate::Utils::utf8ToChar(character); - d->rttMessage = d->rttMessage + string(value); - lDebug() << "Sent RTT character: " << value << "(" << (unsigned long)character << - "), pending text is " << d->rttMessage.c_str(); + d->rttMessage += string(value); + lDebug() << "Sent RTT character: " << value << "(" << (unsigned long)character << "), pending text is " << d->rttMessage; delete[] value; } diff --git a/src/chat/chat-message/chat-message.h b/src/chat/chat-message/chat-message.h index 2b53bda7d..ef188d8bc 100644 --- a/src/chat/chat-message/chat-message.h +++ b/src/chat/chat-message/chat-message.h @@ -40,6 +40,7 @@ class Content; class FileTransferContent; class ChatMessagePrivate; class Participant; +class ParticipantImdnState; class LINPHONE_PUBLIC ChatMessage : public Object, public CoreAccessor { friend class BasicToClientGroupChatRoom; @@ -49,6 +50,7 @@ class LINPHONE_PUBLIC ChatMessage : public Object, public CoreAccessor { friend class CpimChatMessageModifier; friend class FileTransferChatMessageModifier; friend class Imdn; + friend class ImdnMessagePrivate; friend class MainDb; friend class MainDbPrivate; friend class RealTimeTextChatRoomPrivate; @@ -60,13 +62,11 @@ public: L_DECLARE_ENUM(State, L_ENUM_VALUES_CHAT_MESSAGE_STATE); L_DECLARE_ENUM(Direction, L_ENUM_VALUES_CHAT_MESSAGE_DIRECTION); - ~ChatMessage (); + virtual ~ChatMessage (); // ----- TODO: Remove me. void cancelFileTransfer (); int putCharacter (uint32_t character); - void sendDeliveryNotification (LinphoneReason reason); - void sendDisplayNotification (); void setIsSecured (bool isSecured); // ----- TODO: Remove me. @@ -92,11 +92,13 @@ public: bool isReadOnly () const; bool getToBeStored () const; - void setToBeStored (bool value); + virtual void setToBeStored (bool value); + + std::list getParticipantsByImdnState (State state) const; const std::list &getContents () const; - void addContent (Content &content); - void removeContent (const Content &content); + void addContent (Content *content); + void removeContent (Content *content); const Content &getInternalContent () const; void setInternalContent (const Content &content); @@ -106,9 +108,12 @@ public: void addCustomHeader (const std::string &headerName, const std::string &headerValue); void removeCustomHeader (const std::string &headerName); - bool downloadFile (FileTransferContent &content); + bool downloadFile (FileTransferContent *content); bool isFileTransferInProgress(); +protected: + explicit ChatMessage (ChatMessagePrivate &p); + private: ChatMessage (const std::shared_ptr &chatRoom, ChatMessage::Direction direction); diff --git a/src/chat/chat-message/imdn-message-p.h b/src/chat/chat-message/imdn-message-p.h new file mode 100644 index 000000000..57b0678e9 --- /dev/null +++ b/src/chat/chat-message/imdn-message-p.h @@ -0,0 +1,47 @@ +/* + * imdn-message-p.h + * Copyright (C) 2010-2018 Belledonne Communications SARL + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _L_IMDN_MESSAGE_P_H_ +#define _L_IMDN_MESSAGE_P_H_ + +#include "chat/chat-message/imdn-message.h" +#include "chat/chat-message/notification-message-p.h" + +// ============================================================================= + +LINPHONE_BEGIN_NAMESPACE + +class ImdnMessagePrivate : public NotificationMessagePrivate { +public: + const ImdnMessage::Context &getContext () { return context; } + +private: + ImdnMessagePrivate (const ImdnMessage::Context &context) + : NotificationMessagePrivate(context.chatRoom, ChatMessage::Direction::Outgoing), context(context) {} + + void setState (ChatMessage::State newState, bool force = false) override; + + ImdnMessage::Context context; + + L_DECLARE_PUBLIC(ImdnMessage); +}; + +LINPHONE_END_NAMESPACE + +#endif // ifndef _L_IMDN_MESSAGE_P_H_ diff --git a/src/chat/chat-message/imdn-message.cpp b/src/chat/chat-message/imdn-message.cpp new file mode 100644 index 000000000..9e849560d --- /dev/null +++ b/src/chat/chat-message/imdn-message.cpp @@ -0,0 +1,93 @@ +/* + * imdn-message.cpp + * Copyright (C) 2010-2018 Belledonne Communications SARL + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "chat/chat-message/imdn-message-p.h" +#include "chat/chat-room/chat-room-p.h" +#include "content/content-disposition.h" +#include "logger/logger.h" +#include "sip-tools/sip-headers.h" + +// ============================================================================= + +using namespace std; + +LINPHONE_BEGIN_NAMESPACE + +// ----------------------------------------------------------------------------- + +void ImdnMessagePrivate::setState (ChatMessage::State newState, bool force) { + L_Q(); + + if (newState == ChatMessage::State::Delivered) { + for (const auto &message : context.deliveredMessages) + message->getPrivate()->updateInDb(); + for (const auto &message : context.displayedMessages) + message->getPrivate()->updateInDb(); + static_pointer_cast(context.chatRoom)->getPrivate()->getImdnHandler()->onImdnMessageDelivered(q->getSharedFromThis()); + } else if (newState == ChatMessage::State::NotDelivered) { + // TODO: Maybe we should retry sending the IMDN message if we get an error here + } +} + +// ----------------------------------------------------------------------------- + +ImdnMessage::ImdnMessage ( + const shared_ptr &chatRoom, + const list> &deliveredMessages, + const list> &displayedMessages +) : ImdnMessage(Context(chatRoom, deliveredMessages, displayedMessages)) {} + +ImdnMessage::ImdnMessage ( + const shared_ptr &chatRoom, + const list &nonDeliveredMessages +) : ImdnMessage(Context(chatRoom, nonDeliveredMessages)) {} + +ImdnMessage::ImdnMessage (const std::shared_ptr &message) : ImdnMessage(message->getPrivate()->context) {} + +ImdnMessage::ImdnMessage (const Context &context) : NotificationMessage(*new ImdnMessagePrivate(context)) { + L_D(); + + for (const auto &message : d->context.deliveredMessages) { + Content *content = new Content(); + content->setContentDisposition(ContentDisposition::Notification); + content->setContentType(ContentType::Imdn); + content->setBody(Imdn::createXml(message->getImdnMessageId(), message->getTime(), Imdn::Type::Delivery, LinphoneReasonNone)); + addContent(content); + } + for (const auto &message : d->context.displayedMessages) { + Content *content = new Content(); + content->setContentDisposition(ContentDisposition::Notification); + content->setContentType(ContentType::Imdn); + content->setBody(Imdn::createXml(message->getImdnMessageId(), message->getTime(), Imdn::Type::Display, LinphoneReasonNone)); + addContent(content); + } + for (const auto &mr : d->context.nonDeliveredMessages) { + Content *content = new Content(); + content->setContentDisposition(ContentDisposition::Notification); + content->setContentType(ContentType::Imdn); + content->setBody(Imdn::createXml(mr.message->getImdnMessageId(), mr.message->getTime(), Imdn::Type::Delivery, mr.reason)); + addContent(content); + } + + d->addSalCustomHeader(PriorityHeader::HeaderName, PriorityHeader::NonUrgent); + if (!d->context.nonDeliveredMessages.empty()) + d->setEncryptionPrevented(true); +} + +LINPHONE_END_NAMESPACE diff --git a/src/chat/chat-message/imdn-message.h b/src/chat/chat-message/imdn-message.h new file mode 100644 index 000000000..28ce11084 --- /dev/null +++ b/src/chat/chat-message/imdn-message.h @@ -0,0 +1,77 @@ +/* + * imdn-message.h + * Copyright (C) 2010-2018 Belledonne Communications SARL + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _L_IMDN_MESSAGE_H_ +#define _L_IMDN_MESSAGE_H_ + +#include "chat/chat-message/notification-message.h" +#include "chat/notification/imdn.h" + +// ============================================================================= + +LINPHONE_BEGIN_NAMESPACE + +class ImdnMessagePrivate; + +class LINPHONE_PUBLIC ImdnMessage : public NotificationMessage { +public: + friend class ChatRoomPrivate; + friend class Imdn; + + L_OVERRIDE_SHARED_FROM_THIS(ImdnMessage); + + virtual ~ImdnMessage () = default; + +private: + struct Context { + Context ( + const std::shared_ptr &chatRoom, + const std::list> &deliveredMessages, + const std::list> &displayedMessages + ) : chatRoom(chatRoom), deliveredMessages(deliveredMessages), displayedMessages(displayedMessages) {} + Context ( + const std::shared_ptr &chatRoom, + const std::list &nonDeliveredMessages + ) : chatRoom(chatRoom), nonDeliveredMessages(nonDeliveredMessages) {} + + std::shared_ptr chatRoom; + std::list> deliveredMessages; + std::list> displayedMessages; + std::list nonDeliveredMessages; + }; + + ImdnMessage ( + const std::shared_ptr &chatRoom, + const std::list> &deliveredMessages, + const std::list> &displayedMessages + ); + ImdnMessage ( + const std::shared_ptr &chatRoom, + const std::list &nonDeliveredMessages + ); + ImdnMessage (const std::shared_ptr &message); + ImdnMessage (const Context &context); + + L_DECLARE_PRIVATE(ImdnMessage); + L_DISABLE_COPY(ImdnMessage); +}; + +LINPHONE_END_NAMESPACE + +#endif // ifndef _L_IMDN_MESSAGE_H_ diff --git a/src/chat/chat-message/is-composing-message.cpp b/src/chat/chat-message/is-composing-message.cpp new file mode 100644 index 000000000..9797e9e9e --- /dev/null +++ b/src/chat/chat-message/is-composing-message.cpp @@ -0,0 +1,46 @@ +/* + * is-composing-message.cpp + * Copyright (C) 2010-2018 Belledonne Communications SARL + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "chat/chat-message/notification-message-p.h" +#include "chat/chat-message/is-composing-message.h" +#include "sip-tools/sip-headers.h" + +// ============================================================================= + +using namespace std; + +LINPHONE_BEGIN_NAMESPACE + +// ----------------------------------------------------------------------------- + +IsComposingMessage::IsComposingMessage ( + const shared_ptr &chatRoom, + IsComposing &isComposingHandler, + bool isComposing +) : NotificationMessage(*new NotificationMessagePrivate(chatRoom, ChatMessage::Direction::Outgoing)) { + L_D(); + Content *content = new Content(); + content->setContentType(ContentType::ImIsComposing); + content->setBody(isComposingHandler.createXml(isComposing)); + addContent(content); + d->addSalCustomHeader(PriorityHeader::HeaderName, PriorityHeader::NonUrgent); + d->addSalCustomHeader("Expires", "0"); +} + +LINPHONE_END_NAMESPACE diff --git a/src/chat/chat-message/is-composing-message.h b/src/chat/chat-message/is-composing-message.h new file mode 100644 index 000000000..41f2a8c7f --- /dev/null +++ b/src/chat/chat-message/is-composing-message.h @@ -0,0 +1,51 @@ +/* + * is-composing-message.h + * Copyright (C) 2010-2018 Belledonne Communications SARL + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _L_IS_COMPOSING_MESSAGE_H_ +#define _L_IS_COMPOSING_MESSAGE_H_ + +#include "chat/chat-message/notification-message.h" +#include "chat/notification/is-composing.h" + +// ============================================================================= + +LINPHONE_BEGIN_NAMESPACE + +class LINPHONE_PUBLIC IsComposingMessage : public NotificationMessage { +public: + friend class ChatRoomPrivate; + + L_OVERRIDE_SHARED_FROM_THIS(IsComposingMessage); + + virtual ~IsComposingMessage () = default; + +private: + IsComposingMessage ( + const std::shared_ptr &chatRoom, + IsComposing &isComposingHandler, + bool isComposing + ); + + L_DECLARE_PRIVATE(NotificationMessage); + L_DISABLE_COPY(IsComposingMessage); +}; + +LINPHONE_END_NAMESPACE + +#endif // ifndef _L_IS_COMPOSING_MESSAGE_H_ diff --git a/src/chat/chat-message/notification-message-p.h b/src/chat/chat-message/notification-message-p.h new file mode 100644 index 000000000..28e2bbb52 --- /dev/null +++ b/src/chat/chat-message/notification-message-p.h @@ -0,0 +1,50 @@ +/* + * notification-message-p.h + * Copyright (C) 2010-2018 Belledonne Communications SARL + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _L_NOTIFICATION_MESSAGE_P_H_ +#define _L_NOTIFICATION_MESSAGE_P_H_ + +#include "chat/chat-message/chat-message-p.h" +#include "chat/chat-message/notification-message.h" + +// ============================================================================= + +LINPHONE_BEGIN_NAMESPACE + +class NotificationMessagePrivate : public ChatMessagePrivate { + friend class ImdnMessage; + friend class IsComposingMessage; + +protected: + NotificationMessagePrivate(const std::shared_ptr &cr, ChatMessage::Direction dir) + : ChatMessagePrivate(cr, dir) {} + + void setState (ChatMessage::State newState, bool force = false) override {}; + +private: + void setDisplayNotificationRequired (bool value) override {} + void setNegativeDeliveryNotificationRequired (bool value) override {} + void setPositiveDeliveryNotificationRequired (bool value) override {} + + L_DECLARE_PUBLIC(NotificationMessage); +}; + +LINPHONE_END_NAMESPACE + +#endif // ifndef _L_NOTIFICATION_MESSAGE_P_H_ diff --git a/src/chat/chat-message/notification-message.cpp b/src/chat/chat-message/notification-message.cpp new file mode 100644 index 000000000..16c649d13 --- /dev/null +++ b/src/chat/chat-message/notification-message.cpp @@ -0,0 +1,46 @@ +/* + * notification-message.cpp + * Copyright (C) 2010-2018 Belledonne Communications SARL + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "chat/chat-message/notification-message-p.h" + +// ============================================================================= + +using namespace std; + +LINPHONE_BEGIN_NAMESPACE + +// ----------------------------------------------------------------------------- + +NotificationMessage::NotificationMessage (const shared_ptr &chatRoom, ChatMessage::Direction direction) : + NotificationMessage(*new NotificationMessagePrivate(chatRoom, direction)) { +} + +NotificationMessage::NotificationMessage (NotificationMessagePrivate &p) : ChatMessage(p) { + L_D(); + d->displayNotificationRequired = false; + d->negativeDeliveryNotificationRequired = false; + d->positiveDeliveryNotificationRequired = false; + d->toBeStored = false; + d->contentEncoding = "deflate"; +} + +void NotificationMessage::setToBeStored (bool value) { +} + +LINPHONE_END_NAMESPACE diff --git a/src/chat/chat-message/notification-message.h b/src/chat/chat-message/notification-message.h new file mode 100644 index 000000000..f818a009f --- /dev/null +++ b/src/chat/chat-message/notification-message.h @@ -0,0 +1,53 @@ +/* + * notification-message.h + * Copyright (C) 2010-2018 Belledonne Communications SARL + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _L_NOTIFICATION_MESSAGE_H_ +#define _L_NOTIFICATION_MESSAGE_H_ + +#include "chat/chat-message/chat-message.h" + +// ============================================================================= + +LINPHONE_BEGIN_NAMESPACE + +class NotificationMessagePrivate; + +class LINPHONE_PUBLIC NotificationMessage : public ChatMessage { +public: + friend class ChatRoomPrivate; + + L_OVERRIDE_SHARED_FROM_THIS(NotificationMessage); + + virtual ~NotificationMessage () = default; + + void setToBeStored (bool value) override; + +protected: + explicit NotificationMessage (NotificationMessagePrivate &p); + +private: + NotificationMessage (const std::shared_ptr &chatRoom, ChatMessage::Direction direction); + + L_DECLARE_PRIVATE(NotificationMessage); + L_DISABLE_COPY(NotificationMessage); +}; + +LINPHONE_END_NAMESPACE + +#endif // ifndef _L_NOTIFICATION_MESSAGE_H_ diff --git a/src/chat/chat-room/abstract-chat-room-p.h b/src/chat/chat-room/abstract-chat-room-p.h index bd2ea703e..de9054965 100644 --- a/src/chat/chat-room/abstract-chat-room-p.h +++ b/src/chat/chat-room/abstract-chat-room-p.h @@ -47,6 +47,8 @@ public: virtual void addTransientEvent (const std::shared_ptr &eventLog) = 0; virtual void removeTransientEvent (const std::shared_ptr &eventLog) = 0; + virtual void sendDeliveryNotifications () = 0; + virtual void notifyChatMessageReceived (const std::shared_ptr &chatMessage) = 0; virtual void notifyUndecryptableChatMessageReceived (const std::shared_ptr &chatMessage) = 0; diff --git a/src/chat/chat-room/abstract-chat-room.h b/src/chat/chat-room/abstract-chat-room.h index 9662f89b9..8a259466f 100644 --- a/src/chat/chat-room/abstract-chat-room.h +++ b/src/chat/chat-room/abstract-chat-room.h @@ -89,8 +89,7 @@ public: virtual std::shared_ptr createChatMessage () = 0; virtual std::shared_ptr createChatMessage (const std::string &text) = 0; - // TODO: Remove LinphoneContent by LinphonePrivate::Content. - virtual std::shared_ptr createFileTransferMessage (const LinphoneContent *initialContent) = 0; + virtual std::shared_ptr createFileTransferMessage (Content *initialContent) = 0; virtual std::shared_ptr findChatMessage (const std::string &messageId) const = 0; virtual std::shared_ptr findChatMessage ( diff --git a/src/chat/chat-room/basic-chat-room.cpp b/src/chat/chat-room/basic-chat-room.cpp index 619b52dc7..5951f482d 100644 --- a/src/chat/chat-room/basic-chat-room.cpp +++ b/src/chat/chat-room/basic-chat-room.cpp @@ -32,7 +32,7 @@ LINPHONE_BEGIN_NAMESPACE // ----------------------------------------------------------------------------- BasicChatRoom::BasicChatRoom (const shared_ptr &core, const ChatRoomId &chatRoomId) : - ChatRoom(*new BasicChatRoomPrivate, core, chatRoomId) {} + BasicChatRoom(*new BasicChatRoomPrivate, core, chatRoomId) {} BasicChatRoom::BasicChatRoom ( BasicChatRoomPrivate &p, @@ -88,7 +88,7 @@ void BasicChatRoom::addParticipants (const list &, const CallSe lError() << "addParticipants() is not allowed on a BasicChatRoom"; } -void BasicChatRoom::removeParticipant (const shared_ptr &) { +void BasicChatRoom::removeParticipant (const shared_ptr &) { lError() << "removeParticipant() is not allowed on a BasicChatRoom"; } diff --git a/src/chat/chat-room/basic-chat-room.h b/src/chat/chat-room/basic-chat-room.h index e66aceba0..767ebaa35 100644 --- a/src/chat/chat-room/basic-chat-room.h +++ b/src/chat/chat-room/basic-chat-room.h @@ -48,7 +48,7 @@ public: void addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) override; void addParticipants (const std::list &addresses, const CallSessionParams *params, bool hasMedia) override; - void removeParticipant (const std::shared_ptr &participant) override; + void removeParticipant (const std::shared_ptr &participant) override; void removeParticipants (const std::list> &participants) override; std::shared_ptr findParticipant (const IdentityAddress &addr) const override; diff --git a/src/chat/chat-room/basic-to-client-group-chat-room.cpp b/src/chat/chat-room/basic-to-client-group-chat-room.cpp index 67f9ea2fc..960067b14 100644 --- a/src/chat/chat-room/basic-to-client-group-chat-room.cpp +++ b/src/chat/chat-room/basic-to-client-group-chat-room.cpp @@ -78,7 +78,7 @@ public: } migrationRealTime = currentRealTime; clientGroupChatRoom = static_pointer_cast( - chatRoom->getCore()->getPrivate()->createClientGroupChatRoom(chatRoom->getSubject(), "", false) + chatRoom->getCore()->getPrivate()->createClientGroupChatRoom(chatRoom->getSubject(), "", Content(), false) ); clientGroupChatRoom->getPrivate()->setCallSessionListener(this); clientGroupChatRoom->getPrivate()->setChatRoomListener(this); diff --git a/src/chat/chat-room/chat-room-p.h b/src/chat/chat-room/chat-room-p.h index 4d177d845..e882891c9 100644 --- a/src/chat/chat-room/chat-room-p.h +++ b/src/chat/chat-room/chat-room-p.h @@ -25,12 +25,16 @@ #include "abstract-chat-room-p.h" #include "chat-room-id.h" #include "chat-room.h" +#include "chat/notification/imdn.h" #include "chat/notification/is-composing.h" // ============================================================================= LINPHONE_BEGIN_NAMESPACE +class ImdnMessage; +class IsComposingMessage; + class ChatRoomPrivate : public AbstractChatRoomPrivate, public IsComposingListener { public: inline void setProxyChatRoom (AbstractChatRoom *value) { proxyChatRoom = value; } @@ -54,8 +58,20 @@ public: void removeTransientEvent (const std::shared_ptr &eventLog) override; std::shared_ptr createChatMessage (ChatMessage::Direction direction); + std::shared_ptr createImdnMessage ( + const std::list> &deliveredMessages, + const std::list> &displayedMessages + ); + std::shared_ptr createImdnMessage (const std::list &nonDeliveredMessages); + std::shared_ptr createImdnMessage (const std::shared_ptr &message); + std::shared_ptr createIsComposingMessage (); std::list> findChatMessages (const std::string &messageId) const; + void sendDeliveryErrorNotification (const std::shared_ptr &message, LinphoneReason reason); + void sendDeliveryNotification (const std::shared_ptr &message); + void sendDeliveryNotifications () override; + bool sendDisplayNotification (const std::shared_ptr &message); + void notifyChatMessageReceived (const std::shared_ptr &chatMessage) override; void notifyIsComposingReceived (const Address &remoteAddress, bool isComposing); void notifyStateChanged (); @@ -69,6 +85,8 @@ public: void onIsComposingStateChanged (bool isComposing) override; void onIsRemoteComposingStateChanged (const Address &remoteAddress, bool isComposing) override; + Imdn *getImdnHandler () const { return imdnHandler.get(); } + LinphoneChatRoom *getCChatRoom () const; std::list remoteIsComposing; @@ -84,6 +102,7 @@ private: time_t creationTime = std::time(nullptr); time_t lastUpdateTime = std::time(nullptr); + std::unique_ptr imdnHandler; std::unique_ptr isComposingHandler; bool isComposing = false; diff --git a/src/chat/chat-room/chat-room.cpp b/src/chat/chat-room/chat-room.cpp index 28106b50d..6b70da34d 100644 --- a/src/chat/chat-room/chat-room.cpp +++ b/src/chat/chat-room/chat-room.cpp @@ -23,9 +23,11 @@ #include "c-wrapper/c-wrapper.h" #include "chat/chat-message/chat-message-p.h" +#include "chat/chat-message/imdn-message.h" +#include "chat/chat-message/is-composing-message.h" +#include "chat/chat-message/notification-message-p.h" #include "chat/chat-room/chat-room-p.h" #include "core/core-p.h" -#include "sip-tools/sip-headers.h" #include "logger/logger.h" // ============================================================================= @@ -76,21 +78,8 @@ void ChatRoomPrivate::sendIsComposingNotification () { if (!linphone_im_notif_policy_get_send_is_composing(policy)) return; - string payload = isComposingHandler->marshal(isComposing); - if (payload.empty()) - return; - - Content *content = new Content(); - content->setContentType(ContentType::ImIsComposing); - content->setBody(payload); - - shared_ptr chatMessage = createChatMessage(ChatMessage::Direction::Outgoing); - chatMessage->setToBeStored(false); - chatMessage->addContent(*content); - chatMessage->getPrivate()->addSalCustomHeader(PriorityHeader::HeaderName, PriorityHeader::NonUrgent); - chatMessage->getPrivate()->addSalCustomHeader("Expires", "0"); - - chatMessage->getPrivate()->send(); + auto isComposingMsg = createIsComposingMessage(); + isComposingMsg->getPrivate()->send(); } // ----------------------------------------------------------------------------- @@ -121,6 +110,28 @@ shared_ptr ChatRoomPrivate::createChatMessage (ChatMessage::Directi return shared_ptr(new ChatMessage(q->getSharedFromThis(), direction)); } +shared_ptr ChatRoomPrivate::createImdnMessage ( + const list> &deliveredMessages, + const list> &displayedMessages +) { + L_Q(); + return shared_ptr(new ImdnMessage(q->getSharedFromThis(), deliveredMessages, displayedMessages)); +} + +shared_ptr ChatRoomPrivate::createImdnMessage (const list &nonDeliveredMessages) { + L_Q(); + return shared_ptr(new ImdnMessage(q->getSharedFromThis(), nonDeliveredMessages)); +} + +shared_ptr ChatRoomPrivate::createImdnMessage (const shared_ptr &message) { + return shared_ptr(new ImdnMessage(message)); +} + +shared_ptr ChatRoomPrivate::createIsComposingMessage () { + L_Q(); + return shared_ptr(new IsComposingMessage(q->getSharedFromThis(), *isComposingHandler.get(), isComposing)); +} + list> ChatRoomPrivate::findChatMessages (const string &messageId) const { L_Q(); return q->getCore()->getPrivate()->mainDb->findChatMessages(q->getChatRoomId(), messageId); @@ -128,6 +139,42 @@ list> ChatRoomPrivate::findChatMessages (const string &m // ----------------------------------------------------------------------------- +void ChatRoomPrivate::sendDeliveryErrorNotification (const shared_ptr &message, LinphoneReason reason) { + L_Q(); + LinphoneImNotifPolicy *policy = linphone_core_get_im_notif_policy(q->getCore()->getCCore()); + if (linphone_im_notif_policy_get_send_imdn_delivered(policy)) + imdnHandler->notifyDeliveryError(message, reason); +} + +void ChatRoomPrivate::sendDeliveryNotification (const shared_ptr &message) { + L_Q(); + LinphoneImNotifPolicy *policy = linphone_core_get_im_notif_policy(q->getCore()->getCCore()); + if (linphone_im_notif_policy_get_send_imdn_delivered(policy)) + imdnHandler->notifyDelivery(message); +} + +void ChatRoomPrivate::sendDeliveryNotifications () { + L_Q(); + LinphoneImNotifPolicy *policy = linphone_core_get_im_notif_policy(q->getCore()->getCCore()); + if (linphone_im_notif_policy_get_send_imdn_delivered(policy)) { + auto messages = q->getCore()->getPrivate()->mainDb->findChatMessagesToBeNotifiedAsDelivered(q->getChatRoomId()); + for (const auto message : messages) + imdnHandler->notifyDelivery(message); + } +} + +bool ChatRoomPrivate::sendDisplayNotification (const shared_ptr &message) { + L_Q(); + LinphoneImNotifPolicy *policy = linphone_core_get_im_notif_policy(q->getCore()->getCCore()); + if (linphone_im_notif_policy_get_send_imdn_displayed(policy)) { + imdnHandler->notifyDisplay(message); + return true; + } + return false; +} + +// ----------------------------------------------------------------------------- + void ChatRoomPrivate::notifyChatMessageReceived (const shared_ptr &chatMessage) { L_Q(); LinphoneChatRoom *cr = getCChatRoom(); @@ -188,13 +235,13 @@ LinphoneReason ChatRoomPrivate::onSipMessageReceived (SalOp *op, const SalMessag LinphoneCore *cCore = core->getCCore(); msg = createChatMessage( - IdentityAddress(op->get_from()) == q->getLocalAddress() + IdentityAddress(op->getFrom()) == q->getLocalAddress() ? ChatMessage::Direction::Outgoing : ChatMessage::Direction::Incoming ); Content content; - if (message->url && (ContentType(message->content_type) == ContentType::ExternalBody)) { + if (message->url && (ContentType(message->content_type).weakEqual(ContentType::ExternalBody))) { lInfo() << "Received a message with an external body URL " << message->url; content.setContentType(ContentType::FileTransfer); content.setBody(msg->getPrivate()->createFakeFileTransferFromUrl(message->url)); @@ -205,35 +252,30 @@ LinphoneReason ChatRoomPrivate::onSipMessageReceived (SalOp *op, const SalMessag msg->setInternalContent(content); msg->getPrivate()->setTime(message->time); - msg->getPrivate()->setImdnMessageId(op->get_call_id()); + msg->getPrivate()->setImdnMessageId(op->getCallId()); - const SalCustomHeader *ch = op->get_recv_custom_header(); + const SalCustomHeader *ch = op->getRecvCustomHeaders(); if (ch) msg->getPrivate()->setSalCustomHeaders(sal_custom_header_clone(ch)); reason = msg->getPrivate()->receive(); if (reason == LinphoneReasonNotAcceptable || reason == LinphoneReasonUnknown) { - /* Return LinphoneReasonNone to avoid flexisip resending us a message we can't decrypt */ - reason = LinphoneReasonNone; - goto end; + // Return LinphoneReasonNone to avoid flexisip resending us a message we can't decrypt + return LinphoneReasonNone; } if (msg->getPrivate()->getContentType() == ContentType::ImIsComposing) { onIsComposingReceived(msg->getFromAddress(), msg->getPrivate()->getText()); - if (lp_config_get_int(linphone_core_get_config(cCore), "sip", "deliver_imdn", 0) != 1) { - goto end; - } + if (lp_config_get_int(linphone_core_get_config(cCore), "sip", "deliver_imdn", 0) != 1) + return reason; } else if (msg->getPrivate()->getContentType() == ContentType::Imdn) { onImdnReceived(msg); - if (lp_config_get_int(linphone_core_get_config(cCore), "sip", "deliver_imdn", 0) != 1) { - goto end; - } + if (lp_config_get_int(linphone_core_get_config(cCore), "sip", "deliver_imdn", 0) != 1) + return reason; } onChatMessageReceived(msg); - -end: return reason; } @@ -286,9 +328,16 @@ ChatRoom::ChatRoom (ChatRoomPrivate &p, const shared_ptr &core, const Chat L_D(); d->chatRoomId = chatRoomId; + d->imdnHandler.reset(new Imdn(this)); d->isComposingHandler.reset(new IsComposing(core->getCCore(), d)); } +ChatRoom::~ChatRoom () { + L_D(); + + d->imdnHandler.reset(); +} + // ----------------------------------------------------------------------------- const ChatRoomId &ChatRoom::getChatRoomId () const { @@ -377,7 +426,11 @@ int ChatRoom::getChatMessageCount () const { } int ChatRoom::getUnreadChatMessageCount () const { - return getCore()->getPrivate()->mainDb->getUnreadChatMessageCount(getChatRoomId()); + L_D(); + int dbUnreadCount = getCore()->getPrivate()->mainDb->getUnreadChatMessageCount(getChatRoomId()); + int notifiedCount = d->imdnHandler->getDisplayNotificationCount(); + L_ASSERT(dbUnreadCount >= notifiedCount); + return dbUnreadCount - notifiedCount; } // ----------------------------------------------------------------------------- @@ -414,11 +467,11 @@ shared_ptr ChatRoom::createChatMessage (const string &text) { Content *content = new Content(); content->setContentType(ContentType::PlainText); content->setBody(text); - chatMessage->addContent(*content); + chatMessage->addContent(content); return chatMessage; } -shared_ptr ChatRoom::createFileTransferMessage (const LinphoneContent *initialContent) { +shared_ptr ChatRoom::createFileTransferMessage (Content *initialContent) { shared_ptr chatMessage = createChatMessage(); chatMessage->getPrivate()->setFileTransferInformation(initialContent); return chatMessage; @@ -443,16 +496,21 @@ shared_ptr ChatRoom::findChatMessage (const string &messageId, Chat void ChatRoom::markAsRead () { L_D(); + bool globallyMarkAsReadInDb = true; CorePrivate *dCore = getCore()->getPrivate(); for (auto &chatMessage : dCore->mainDb->getUnreadChatMessages(d->chatRoomId)) { // Do not send display notification for file transfer until it has been downloaded (it won't have a file transfer content anymore) if (!chatMessage->getPrivate()->hasFileTransferContent()) { - chatMessage->sendDisplayNotification(); - chatMessage->getPrivate()->setState(ChatMessage::State::Displayed, true); // True will ensure the setState won't update the database so it will be done below by the markChatMessagesAsRead + bool doNotStoreInDb = d->sendDisplayNotification(chatMessage); + // Force the state so it is stored directly in DB, but when the IMDN has successfully been delivered + chatMessage->getPrivate()->setState(ChatMessage::State::Displayed, doNotStoreInDb); + if (doNotStoreInDb) + globallyMarkAsReadInDb = false; } } - dCore->mainDb->markChatMessagesAsRead(d->chatRoomId); + if (globallyMarkAsReadInDb) + dCore->mainDb->markChatMessagesAsRead(d->chatRoomId); } LINPHONE_END_NAMESPACE diff --git a/src/chat/chat-room/chat-room.h b/src/chat/chat-room/chat-room.h index 40cad5ae3..9c361df82 100644 --- a/src/chat/chat-room/chat-room.h +++ b/src/chat/chat-room/chat-room.h @@ -30,10 +30,15 @@ class ChatRoomPrivate; class LINPHONE_PUBLIC ChatRoom : public AbstractChatRoom { public: + friend class ChatMessagePrivate; + friend class Imdn; + friend class ImdnMessagePrivate; friend class ProxyChatRoomPrivate; L_OVERRIDE_SHARED_FROM_THIS(ChatRoom); + ~ChatRoom (); + const ChatRoomId &getChatRoomId () const override; const IdentityAddress &getPeerAddress () const override; @@ -65,8 +70,7 @@ public: std::shared_ptr createChatMessage () override; std::shared_ptr createChatMessage (const std::string &text) override; - // TODO: Remove LinphoneContent by LinphonePrivate::Content. - std::shared_ptr createFileTransferMessage (const LinphoneContent *initialContent) override; + std::shared_ptr createFileTransferMessage (Content *initialContent) override; std::shared_ptr findChatMessage (const std::string &messageId) const override; std::shared_ptr findChatMessage ( diff --git a/src/chat/chat-room/client-group-chat-room-p.h b/src/chat/chat-room/client-group-chat-room-p.h index e617b517d..a23f4c15e 100644 --- a/src/chat/chat-room/client-group-chat-room-p.h +++ b/src/chat/chat-room/client-group-chat-room-p.h @@ -35,9 +35,12 @@ public: void notifyReceived (const std::string &body); void multipartNotifyReceived (const std::string &body); + void confirmJoining (SalCallOp *op); void setCallSessionListener (CallSessionListener *listener); void setChatRoomListener (ChatRoomListener *listener) { chatRoomListener = listener; } + unsigned int getLastNotifyId () const; + // ChatRoomListener void onChatRoomInsertRequested (const std::shared_ptr &chatRoom) override; void onChatRoomInsertInDatabaseRequested (const std::shared_ptr &chatRoom) override; @@ -47,12 +50,16 @@ public: void onCallSessionSetReleased (const std::shared_ptr &session) override; void onCallSessionStateChanged (const std::shared_ptr &session, CallSession::State state, const std::string &message) override; + void onChatRoomCreated (const Address &remoteContact); + private: + void acceptSession (const std::shared_ptr &session); + CallSessionListener *callSessionListener = this; ChatRoomListener *chatRoomListener = this; ClientGroupChatRoom::CapabilitiesMask capabilities = ClientGroupChatRoom::Capabilities::Conference; bool deletionOnTerminationEnabled = false; - BackgroundTask bgTask; + BackgroundTask bgTask { "Subscribe/notify of full state conference" }; L_DECLARE_PUBLIC(ClientGroupChatRoom); }; diff --git a/src/chat/chat-room/client-group-chat-room.cpp b/src/chat/chat-room/client-group-chat-room.cpp index 29c872d30..3e576d155 100644 --- a/src/chat/chat-room/client-group-chat-room.cpp +++ b/src/chat/chat-room/client-group-chat-room.cpp @@ -17,14 +17,18 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include + #include "linphone/utils/utils.h" #include "address/address-p.h" #include "basic-to-client-group-chat-room.h" #include "c-wrapper/c-wrapper.h" #include "client-group-chat-room-p.h" -#include "conference/handlers/remote-conference-event-handler.h" +#include "conference/handlers/remote-conference-event-handler-p.h" +#include "conference/handlers/remote-conference-list-event-handler.h" #include "conference/participant-p.h" +#include "conference/participant-device.h" #include "conference/remote-conference-p.h" #include "conference/session/call-session-p.h" #include "content/content-disposition.h" @@ -90,6 +94,7 @@ void ClientGroupChatRoomPrivate::multipartNotifyReceived (const string &body) { void ClientGroupChatRoomPrivate::setCallSessionListener (CallSessionListener *listener) { L_Q(); L_Q_T(RemoteConference, qConference); + callSessionListener = listener; shared_ptr session = qConference->getPrivate()->focus->getPrivate()->getSession(); if (session) @@ -101,6 +106,38 @@ void ClientGroupChatRoomPrivate::setCallSessionListener (CallSessionListener *li } } +unsigned int ClientGroupChatRoomPrivate::getLastNotifyId () const { + L_Q_T(RemoteConference, qConference); + return qConference->getPrivate()->eventHandler->getLastNotify(); +} + +// ----------------------------------------------------------------------------- + +void ClientGroupChatRoomPrivate::confirmJoining (SalCallOp *op) { + L_Q(); + L_Q_T(RemoteConference, qConference); + + auto focus = qConference->getPrivate()->focus; + bool previousSession = (focus->getPrivate()->getSession() != nullptr); + auto session = focus->getPrivate()->createSession(*q, nullptr, false, this); + session->configure(LinphoneCallIncoming, nullptr, op, Address(op->getFrom()), Address(op->getTo())); + session->startIncomingNotification(false); + + if (!previousSession) { + setState(ClientGroupChatRoom::State::CreationPending); + // Handle participants addition + list identAddresses = ClientGroupChatRoom::parseResourceLists(op->getRemoteBody()); + for (const auto &addr : identAddresses) { + auto participant = q->findParticipant(addr); + if (!participant) { + participant = make_shared(addr); + qConference->getPrivate()->participants.push_back(participant); + } + } + } + acceptSession(session); +} + // ----------------------------------------------------------------------------- void ClientGroupChatRoomPrivate::onChatRoomInsertRequested (const shared_ptr &chatRoom) { @@ -110,7 +147,10 @@ void ClientGroupChatRoomPrivate::onChatRoomInsertRequested (const shared_ptr &chatRoom) { L_Q(); - q->getCore()->getPrivate()->insertChatRoomWithDb(chatRoom); + L_Q_T(RemoteConference, qConference); + + unsigned int notifyId = qConference->getPrivate()->eventHandler->getLastNotify();; + q->getCore()->getPrivate()->insertChatRoomWithDb(chatRoom, notifyId); } void ClientGroupChatRoomPrivate::onChatRoomDeleteRequested (const shared_ptr &chatRoom) { @@ -139,14 +179,11 @@ void ClientGroupChatRoomPrivate::onCallSessionStateChanged ( if (newState == CallSession::State::Connected) { if (q->getState() == ChatRoom::State::CreationPending) { - IdentityAddress addr(session->getRemoteContactAddress()->asStringUriOnly()); - q->onConferenceCreated(addr); - if (session->getRemoteContactAddress()->hasParam("isfocus")) { - bgTask.start(q->getCore(), 32); // It will be stopped when receiving the first notify - qConference->getPrivate()->eventHandler->subscribe(q->getChatRoomId()); - } + onChatRoomCreated(*session->getRemoteContactAddress()); } else if (q->getState() == ChatRoom::State::TerminationPending) qConference->getPrivate()->focus->getPrivate()->getSession()->terminate(); + } else if (newState == CallSession::State::End) { + setState(ChatRoom::State::TerminationPending); } else if (newState == CallSession::State::Released) { if (q->getState() == ChatRoom::State::TerminationPending) { if (session->getReason() == LinphoneReasonNone) { @@ -174,23 +211,50 @@ void ClientGroupChatRoomPrivate::onCallSessionStateChanged ( } } +void ClientGroupChatRoomPrivate::onChatRoomCreated (const Address &remoteContact) { + L_Q(); + L_Q_T(RemoteConference, qConference); + + IdentityAddress addr(remoteContact); + q->onConferenceCreated(addr); + if (remoteContact.hasParam("isfocus")) { + if (q->getCore()->getPrivate()->remoteListEventHandler->findHandler(q->getChatRoomId())) { + q->getCore()->getPrivate()->remoteListEventHandler->subscribe(); + } else { + bgTask.start(q->getCore(), 32); // It will be stopped when receiving the first notify + qConference->getPrivate()->eventHandler->subscribe(q->getChatRoomId()); + } + } +} + +// ----------------------------------------------------------------------------- + +void ClientGroupChatRoomPrivate::acceptSession (const shared_ptr &session) { + if (session->getState() == CallSession::State::UpdatedByRemote) + session->acceptUpdate(); + else + session->accept(); +} + // ============================================================================= ClientGroupChatRoom::ClientGroupChatRoom ( const shared_ptr &core, const string &uri, const IdentityAddress &me, - const string &subject + const string &subject, + const Content &content ) : ChatRoom(*new ClientGroupChatRoomPrivate, core, ChatRoomId(IdentityAddress(), me)), RemoteConference(core, me, nullptr) { L_D_T(RemoteConference, dConference); - L_D(); - + IdentityAddress focusAddr(uri); dConference->focus = make_shared(focusAddr); dConference->focus->getPrivate()->addDevice(focusAddr); RemoteConference::setSubject(subject); - d->bgTask.setName("Subscribe/notify of full state conference"); + list identAddresses = Conference::parseResourceLists(content); + for (const auto &addr : identAddresses) + dConference->participants.push_back(make_shared(addr)); } ClientGroupChatRoom::ClientGroupChatRoom ( @@ -200,7 +264,8 @@ ClientGroupChatRoom::ClientGroupChatRoom ( AbstractChatRoom::CapabilitiesMask capabilities, const string &subject, list> &&participants, - unsigned int lastNotifyId + unsigned int lastNotifyId, + bool hasBeenLeft ) : ChatRoom(*new ClientGroupChatRoomPrivate, core, chatRoomId), RemoteConference(core, me->getAddress(), nullptr) { L_D(); @@ -216,12 +281,22 @@ RemoteConference(core, me->getAddress(), nullptr) { getMe()->getPrivate()->setAdmin(me->isAdmin()); + dConference->eventHandler->setChatRoomId(chatRoomId); dConference->eventHandler->setLastNotify(lastNotifyId); - dConference->eventHandler->subscribe(getChatRoomId()); + if (!hasBeenLeft) + getCore()->getPrivate()->remoteListEventHandler->addHandler(dConference->eventHandler.get()); } ClientGroupChatRoom::~ClientGroupChatRoom () { L_D(); + L_D_T(RemoteConference, dConference); + + try { + if (getCore()->getPrivate()->remoteListEventHandler) + getCore()->getPrivate()->remoteListEventHandler->removeHandler(dConference->eventHandler.get()); + } catch (const bad_weak_ptr &) { + // Unable to unregister listener here. Core is destroyed and the listener doesn't exist. + } d->setCallSessionListener(nullptr); } @@ -251,7 +326,7 @@ ClientGroupChatRoom::CapabilitiesMask ClientGroupChatRoom::getCapabilities () co } bool ClientGroupChatRoom::hasBeenLeft () const { - return getState() != State::Created; + return (getState() != State::Created); } bool ClientGroupChatRoom::canHandleParticipants () const { @@ -273,22 +348,7 @@ void ClientGroupChatRoom::deleteFromDb () { } void ClientGroupChatRoom::addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) { - list addresses; - addresses.push_back(addr); - addParticipants(addresses, params, hasMedia); -} - -void ClientGroupChatRoom::addParticipants ( - const list &addresses, - const CallSessionParams *params, - bool hasMedia -) { L_D(); - L_D_T(RemoteConference, dConference); - - list addressesList = d->cleanAddressesList(addresses); - if (addressesList.empty()) - return; if ((getState() != ChatRoom::State::Instantiated) && (getState() != ChatRoom::State::Created)) { lError() << "Cannot add participants to the ClientGroupChatRoom in a state other than Instantiated or Created"; @@ -300,6 +360,41 @@ void ClientGroupChatRoom::addParticipants ( return; } + LinphoneCore *cCore = getCore()->getCCore(); + if (getState() == ChatRoom::State::Instantiated) { + list addressesList; + addressesList.push_back(addr); + Content content; + content.setBody(getResourceLists(addressesList)); + content.setContentType(ContentType::ResourceLists); + content.setContentDisposition(ContentDisposition::RecipientList); + + auto session = d->createSession(); + session->startInvite(nullptr, getSubject(), &content); + d->setState(ChatRoom::State::CreationPending); + } else { + SalReferOp *referOp = new SalReferOp(cCore->sal); + LinphoneAddress *lAddr = linphone_address_new(getConferenceAddress().asString().c_str()); + linphone_configure_op(cCore, referOp, lAddr, nullptr, true); + linphone_address_unref(lAddr); + Address referToAddr = addr; + referToAddr.setParam("text"); + referOp->sendRefer(referToAddr.getPrivate()->getInternalAddress()); + referOp->unref(); + } +} + +void ClientGroupChatRoom::addParticipants ( + const list &addresses, + const CallSessionParams *params, + bool hasMedia +) { + L_D(); + + list addressesList = d->cleanAddressesList(addresses); + if (addressesList.empty()) + return; + if ((getState() == ChatRoom::State::Instantiated) && (addressesList.size() == 1) && (linphone_config_get_bool(linphone_core_get_config(L_GET_C_BACK_PTR(getCore())), @@ -308,27 +403,24 @@ void ClientGroupChatRoom::addParticipants ( d->capabilities |= ClientGroupChatRoom::Capabilities::OneToOne; } - Content content; - content.setBody(getResourceLists(addressesList)); - content.setContentType(ContentType::ResourceLists); - content.setContentDisposition(ContentDisposition::RecipientList); - // TODO: Activate compression - //if (linphone_core_content_encoding_supported(getCore()->getCCore(), "deflate")) - // content.setContentEncoding("deflate"); - // TODO: Activate compression + if (getState() == ChatRoom::State::Instantiated) { + Content content; + content.setBody(getResourceLists(addressesList)); + content.setContentType(ContentType::ResourceLists); + content.setContentDisposition(ContentDisposition::RecipientList); + if (linphone_core_content_encoding_supported(getCore()->getCCore(), "deflate")) + content.setContentEncoding("deflate"); - shared_ptr session = dConference->focus->getPrivate()->getSession(); - if (session) - session->update(nullptr, getSubject(), &content); - else { - session = d->createSession(); + auto session = d->createSession(); session->startInvite(nullptr, getSubject(), &content); - if (getState() == ChatRoom::State::Instantiated) - d->setState(ChatRoom::State::CreationPending); + d->setState(ChatRoom::State::CreationPending); + } else { + for (const auto &addr : addresses) + addParticipant(addr, params, hasMedia); } } -void ClientGroupChatRoom::removeParticipant (const shared_ptr &participant) { +void ClientGroupChatRoom::removeParticipant (const shared_ptr &participant) { LinphoneCore *cCore = getCore()->getCCore(); SalReferOp *referOp = new SalReferOp(cCore->sal); @@ -338,7 +430,7 @@ void ClientGroupChatRoom::removeParticipant (const shared_ptr Address referToAddr = participant->getAddress(); referToAddr.setParam("text"); referToAddr.setUriParam("method", "BYE"); - referOp->send_refer(referToAddr.getPrivate()->getInternalAddress()); + referOp->sendRefer(referToAddr.getPrivate()->getInternalAddress()); referOp->unref(); } @@ -380,7 +472,7 @@ void ClientGroupChatRoom::setParticipantAdminStatus (const shared_ptrgetAddress(); referToAddr.setParam("text"); referToAddr.setParam("admin", Utils::toString(isAdmin)); - referOp->send_refer(referToAddr.getPrivate()->getInternalAddress()); + referOp->sendRefer(referToAddr.getPrivate()->getInternalAddress()); referOp->unref(); } @@ -422,7 +514,8 @@ void ClientGroupChatRoom::join () { if (session) { if (getState() != ChatRoom::State::TerminationPending) session->startInvite(nullptr, "", nullptr); - d->setState(ChatRoom::State::CreationPending); + if (getState() != ChatRoom::State::Created) + d->setState(ChatRoom::State::CreationPending); } } @@ -431,7 +524,6 @@ void ClientGroupChatRoom::leave () { L_D_T(RemoteConference, dConference); dConference->eventHandler->unsubscribe(); - shared_ptr session = dConference->focus->getPrivate()->getSession(); if (session) session->terminate(); @@ -454,23 +546,33 @@ void ClientGroupChatRoom::onConferenceCreated (const IdentityAddress &addr) { dConference->focus->getPrivate()->addDevice(addr); d->chatRoomId = ChatRoomId(addr, d->chatRoomId.getLocalAddress()); d->chatRoomListener->onChatRoomInsertRequested(getSharedFromThis()); + d->setState(ChatRoom::State::Created); } void ClientGroupChatRoom::onConferenceKeywordsChanged (const vector &keywords) { L_D(); - d->capabilities |= ClientGroupChatRoom::Capabilities::OneToOne; + if (find(keywords.cbegin(), keywords.cend(), "one-to-one") != keywords.cend()) + d->capabilities |= ClientGroupChatRoom::Capabilities::OneToOne; } void ClientGroupChatRoom::onConferenceTerminated (const IdentityAddress &addr) { L_D(); L_D_T(RemoteConference, dConference); + + dConference->eventHandler->unsubscribe(); dConference->eventHandler->resetLastNotify(); d->setState(ChatRoom::State::Terminated); - d->addEvent(make_shared( + + auto event = make_shared( EventLog::Type::ConferenceTerminated, time(nullptr), d->chatRoomId - )); + ); + d->addEvent(event); + + LinphoneChatRoom *cr = d->getCChatRoom(); + _linphone_chat_room_notify_conference_left(cr, L_GET_C_BACK_PTR(event)); + if (d->deletionOnTerminationEnabled) { d->deletionOnTerminationEnabled = false; d->chatRoomListener->onChatRoomDeleteRequested(getSharedFromThis()); @@ -479,30 +581,37 @@ void ClientGroupChatRoom::onConferenceTerminated (const IdentityAddress &addr) { void ClientGroupChatRoom::onFirstNotifyReceived (const IdentityAddress &addr) { L_D(); - d->setState(ChatRoom::State::Created); - - if (getParticipantCount() == 1) { - ChatRoomId id(getParticipants().front()->getAddress(), getMe()->getAddress()); - shared_ptr chatRoom = getCore()->findChatRoom(id); - if (chatRoom && (chatRoom->getCapabilities() & ChatRoom::Capabilities::Basic)) { - BasicToClientGroupChatRoom::migrate(getSharedFromThis(), chatRoom); - d->bgTask.stop(); - return; - } + + if (getState() != ChatRoom::State::Created) { + lWarning() << "First notify received in ClientGroupChatRoom that is not in the Created state, ignoring it!"; + return; } - d->chatRoomListener->onChatRoomInsertInDatabaseRequested(getSharedFromThis()); + bool performMigration = false; + shared_ptr chatRoom; + if (getParticipantCount() == 1) { + ChatRoomId id(getParticipants().front()->getAddress(), getMe()->getAddress()); + chatRoom = getCore()->findChatRoom(id); + if (chatRoom && (chatRoom->getCapabilities() & ChatRoom::Capabilities::Basic)) + performMigration = true; + } - d->bgTask.stop(); - // TODO: Bug. Event is inserted many times. - // Avoid this in the future. Deal with signals/slots system. - #if 0 - d->addEvent(make_shared( + if (performMigration) + BasicToClientGroupChatRoom::migrate(getSharedFromThis(), chatRoom); + else + d->chatRoomListener->onChatRoomInsertInDatabaseRequested(getSharedFromThis()); + + auto event = make_shared( EventLog::Type::ConferenceCreated, time(nullptr), d->chatRoomId - )); - #endif + ); + d->addEvent(event); + + LinphoneChatRoom *cr = d->getCChatRoom(); + _linphone_chat_room_notify_conference_joined(cr, L_GET_C_BACK_PTR(event)); + + d->bgTask.stop(); } void ClientGroupChatRoom::onParticipantAdded (const shared_ptr &event, bool isFullState) { diff --git a/src/chat/chat-room/client-group-chat-room.h b/src/chat/chat-room/client-group-chat-room.h index 9bb13f526..cc3205a67 100644 --- a/src/chat/chat-room/client-group-chat-room.h +++ b/src/chat/chat-room/client-group-chat-room.h @@ -43,7 +43,8 @@ public: const std::shared_ptr &core, const std::string &factoryUri, const IdentityAddress &me, - const std::string &subject + const std::string &subject, + const Content &content ); ClientGroupChatRoom ( @@ -53,7 +54,8 @@ public: AbstractChatRoom::CapabilitiesMask capabilities, const std::string &subject, std::list> &&participants, - unsigned int lastNotifyId + unsigned int lastNotifyId, + bool hasBeenLeft = false ); ~ClientGroupChatRoom (); @@ -77,7 +79,7 @@ public: void addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) override; void addParticipants (const std::list &addresses, const CallSessionParams *params, bool hasMedia) override; - void removeParticipant (const std::shared_ptr &participant) override; + void removeParticipant (const std::shared_ptr &participant) override; void removeParticipants (const std::list> &participants) override; std::shared_ptr findParticipant (const IdentityAddress &addr) const override; diff --git a/src/chat/chat-room/client-group-to-basic-chat-room.cpp b/src/chat/chat-room/client-group-to-basic-chat-room.cpp index c72f9cfec..e2f6746f3 100644 --- a/src/chat/chat-room/client-group-to-basic-chat-room.cpp +++ b/src/chat/chat-room/client-group-to-basic-chat-room.cpp @@ -43,7 +43,8 @@ public: void onChatRoomInsertInDatabaseRequested (const shared_ptr &chatRoom) override { L_Q(); // Insert the proxy chat room instead of the real one - q->getCore()->getPrivate()->insertChatRoomWithDb(q->getSharedFromThis()); + unsigned int notifyId = static_cast(chatRoom->getPrivate())->getLastNotifyId(); + q->getCore()->getPrivate()->insertChatRoomWithDb(q->getSharedFromThis(), notifyId); } void onChatRoomDeleteRequested (const shared_ptr &chatRoom) override { @@ -79,10 +80,15 @@ public: cgcr->getPrivate()->setCallSessionListener(nullptr); cgcr->getPrivate()->setChatRoomListener(nullptr); Core::deleteChatRoom(q->getSharedFromThis()); - setupProxy(); + LinphoneChatRoom *lcr = L_GET_C_BACK_PTR(q); shared_ptr bcr = cgcr->getCore()->getOrCreateBasicChatRoom(invitedAddresses.front()); L_SET_CPP_PTR_FROM_C_OBJECT(lcr, bcr); + /* getOrCreateBasicChatRoom will automatically set the state to Instantiated and Created + * but because CPP ptr hasn't been set yet in this case the application's ChatRoom won't be notified + * that's why we set both states again here... */ + bcr->getPrivate()->setState(ChatRoom::State::Instantiated); + bcr->getPrivate()->setState(ChatRoom::State::Created); return; } cgcr->getPrivate()->onCallSessionStateChanged(session, newState, message); diff --git a/src/chat/chat-room/proxy-chat-room-p.h b/src/chat/chat-room/proxy-chat-room-p.h index b10aa3d8a..fc6840b34 100644 --- a/src/chat/chat-room/proxy-chat-room-p.h +++ b/src/chat/chat-room/proxy-chat-room-p.h @@ -57,6 +57,10 @@ public: chatRoom->getPrivate()->removeTransientEvent(eventLog); } + inline void sendDeliveryNotifications () override { + chatRoom->getPrivate()->sendDeliveryNotifications(); + } + inline void notifyChatMessageReceived (const std::shared_ptr &chatMessage) override { chatRoom->getPrivate()->notifyChatMessageReceived(chatMessage); } diff --git a/src/chat/chat-room/proxy-chat-room.cpp b/src/chat/chat-room/proxy-chat-room.cpp index 6ddcb4f74..2316d3f70 100644 --- a/src/chat/chat-room/proxy-chat-room.cpp +++ b/src/chat/chat-room/proxy-chat-room.cpp @@ -173,7 +173,7 @@ shared_ptr ProxyChatRoom::createChatMessage (const string &text) { return d->chatRoom->createChatMessage(text); } -shared_ptr ProxyChatRoom::createFileTransferMessage (const LinphoneContent *initialContent) { +shared_ptr ProxyChatRoom::createFileTransferMessage (Content *initialContent) { L_D(); return d->chatRoom->createFileTransferMessage(initialContent); } @@ -248,7 +248,7 @@ void ProxyChatRoom::addParticipants ( return d->chatRoom->addParticipants(addresses, params, hasMedia); } -void ProxyChatRoom::removeParticipant (const shared_ptr &participant) { +void ProxyChatRoom::removeParticipant (const shared_ptr &participant) { L_D(); d->chatRoom->removeParticipant(participant); } diff --git a/src/chat/chat-room/proxy-chat-room.h b/src/chat/chat-room/proxy-chat-room.h index 5e4c68d11..a464bb791 100644 --- a/src/chat/chat-room/proxy-chat-room.h +++ b/src/chat/chat-room/proxy-chat-room.h @@ -66,8 +66,7 @@ public: std::shared_ptr createChatMessage () override; std::shared_ptr createChatMessage (const std::string &text) override; - // TODO: Remove LinphoneContent by LinphonePrivate::Content. - std::shared_ptr createFileTransferMessage (const LinphoneContent *initialContent) override; + std::shared_ptr createFileTransferMessage (Content *initialContent) override; std::shared_ptr findChatMessage (const std::string &messageId) const override; std::shared_ptr findChatMessage ( @@ -97,7 +96,7 @@ public: bool hasMedia ) override; - void removeParticipant (const std::shared_ptr &participant) override; + void removeParticipant (const std::shared_ptr &participant) override; void removeParticipants (const std::list> &participants) override; std::shared_ptr findParticipant (const IdentityAddress &participantAddress) const override; diff --git a/src/chat/chat-room/real-time-text-chat-room.cpp b/src/chat/chat-room/real-time-text-chat-room.cpp index a33a19535..bacf87a81 100644 --- a/src/chat/chat-room/real-time-text-chat-room.cpp +++ b/src/chat/chat-room/real-time-text-chat-room.cpp @@ -21,7 +21,7 @@ #include "call/call.h" #include "chat/chat-message/chat-message-p.h" #include "conference/participant.h" -#include "core/core.h" +#include "core/core-p.h" #include "logger/logger.h" #include "real-time-text-chat-room-p.h" @@ -43,8 +43,13 @@ void RealTimeTextChatRoomPrivate::realtimeTextReceived (uint32_t character, cons LinphoneCore *cCore = core->getCCore(); if (call && call->getCurrentParams()->realtimeTextEnabled()) { - if (!pendingMessage) - pendingMessage = q->createChatMessage(""); + if (!pendingMessage) { + pendingMessage = q->createChatMessage(); + pendingMessage->getPrivate()->setDirection(ChatMessage::Direction::Incoming); + Content *content = new Content(); + content->setContentType(ContentType::PlainText); + pendingMessage->addContent(content); + } Character cmc; cmc.value = character; @@ -56,23 +61,24 @@ void RealTimeTextChatRoomPrivate::realtimeTextReceived (uint32_t character, cons if ((character == new_line) || (character == crlf) || (character == lf)) { // End of message - lDebug() << "New line received, forge a message with content " << pendingMessage->getPrivate()->getText().c_str(); + auto content = pendingMessage->getContents().front(); + lDebug() << "New line received, forge a message with content " << content->getBodyAsString(); pendingMessage->getPrivate()->setState(ChatMessage::State::Delivered); - pendingMessage->getPrivate()->setDirection(ChatMessage::Direction::Incoming); pendingMessage->getPrivate()->setTime(::ms_time(0)); if (lp_config_get_int(linphone_core_get_config(cCore), "misc", "store_rtt_messages", 1) == 1) - pendingMessage->getPrivate()->storeInDb(); + pendingMessage->setToBeStored(true); + else + pendingMessage->setToBeStored(false); onChatMessageReceived(pendingMessage); pendingMessage = nullptr; receivedRttCharacters.clear(); } else { char *value = Utils::utf8ToChar(character); - string text(pendingMessage->getPrivate()->getText()); - text += string(value); - pendingMessage->getPrivate()->setText(text); - lDebug() << "Received RTT character: " << value << " (" << character << "), pending text is " << pendingMessage->getPrivate()->getText(); + auto content = pendingMessage->getContents().front(); + content->setBody(content->getBodyAsString() + string(value)); + lDebug() << "Received RTT character: " << value << " (" << character << "), pending text is " << content->getBodyAsString(); delete[] value; } } @@ -84,6 +90,16 @@ void RealTimeTextChatRoomPrivate::sendChatMessage (const shared_ptr if (call && call->getCurrentParams()->realtimeTextEnabled()) { uint32_t newLine = 0x2028; chatMessage->putCharacter(newLine); + + ChatMessagePrivate *dChatMessage = chatMessage->getPrivate(); + shared_ptr event = static_pointer_cast( + q->getCore()->getPrivate()->mainDb->getEventFromKey(dChatMessage->dbKey) + ); + if (!event) + event = make_shared(time(nullptr), chatMessage); + + LinphoneChatRoom *cr = getCChatRoom(); + _linphone_chat_room_notify_chat_message_sent(cr, L_GET_C_BACK_PTR(event)); } } diff --git a/src/chat/chat-room/server-group-chat-room-p.h b/src/chat/chat-room/server-group-chat-room-p.h index 911f31f67..daa8ae629 100644 --- a/src/chat/chat-room/server-group-chat-room-p.h +++ b/src/chat/chat-room/server-group-chat-room-p.h @@ -69,7 +69,7 @@ public: private: struct Message { Message (const std::string &from, const ContentType &contentType, const std::string &text, const SalCustomHeader *salCustomHeaders) - : fromAddr(from) + : fromAddr(from) { content.setContentType(contentType); if (!text.empty()) @@ -91,6 +91,7 @@ private: static void copyMessageHeaders (const std::shared_ptr &fromMessage, const std::shared_ptr &toMessage); + void byeDevice (const std::shared_ptr &device); void designateAdmin (); void dispatchMessage (const std::shared_ptr &message, const std::string &uri); void finalizeCreation (); @@ -100,7 +101,7 @@ private: void queueMessage (const std::shared_ptr &msg, const IdentityAddress &deviceAddress); void removeNonPresentParticipants (const std::list &compatibleParticipants); - void onParticipantDeviceLeft (const std::shared_ptr &session); + void onParticipantDeviceLeft (const std::shared_ptr &device); // ChatRoomListener void onChatRoomInsertRequested (const std::shared_ptr &chatRoom) override; diff --git a/src/chat/chat-room/server-group-chat-room-stub.cpp b/src/chat/chat-room/server-group-chat-room-stub.cpp index d8204fc5b..7e5a3b7a8 100644 --- a/src/chat/chat-room/server-group-chat-room-stub.cpp +++ b/src/chat/chat-room/server-group-chat-room-stub.cpp @@ -84,6 +84,8 @@ void ServerGroupChatRoomPrivate::addParticipantDevice (const IdentityAddress &pa void ServerGroupChatRoomPrivate::addCompatibleParticipants (const IdentityAddress &deviceAddr, const list &participantCompatible) {} +void ServerGroupChatRoomPrivate::checkCompatibleParticipants (const IdentityAddress &deviceAddr, const list &addressesToCheck) {} + // ----------------------------------------------------------------------------- LinphoneReason ServerGroupChatRoomPrivate::onSipMessageReceived (SalOp *, const SalMessage *) { @@ -92,6 +94,8 @@ LinphoneReason ServerGroupChatRoomPrivate::onSipMessageReceived (SalOp *, const // ----------------------------------------------------------------------------- +void ServerGroupChatRoomPrivate::byeDevice (const shared_ptr &device) {} + void ServerGroupChatRoomPrivate::designateAdmin () {} void ServerGroupChatRoomPrivate::dispatchMessage (const shared_ptr &message, const string &uri) {} @@ -112,7 +116,7 @@ void ServerGroupChatRoomPrivate::removeNonPresentParticipants (const list &session) {} +void ServerGroupChatRoomPrivate::onParticipantDeviceLeft (const shared_ptr &device) {} // ----------------------------------------------------------------------------- @@ -135,8 +139,8 @@ void ServerGroupChatRoomPrivate::onCallSessionSetReleased (const shared_ptr &core, SalCallOp *op) -: ChatRoom(*new ServerGroupChatRoomPrivate, core, ChatRoomId(IdentityAddress(op->get_to()), IdentityAddress(op->get_to()))), -LocalConference(core, IdentityAddress(op->get_to()), nullptr) { +: ChatRoom(*new ServerGroupChatRoomPrivate, core, ChatRoomId(IdentityAddress(op->getTo()), IdentityAddress(op->getTo()))), +LocalConference(core, IdentityAddress(op->getTo()), nullptr) { L_D(); d->chatRoomListener = d; } @@ -151,16 +155,18 @@ ServerGroupChatRoom::ServerGroupChatRoom ( ) : ChatRoom(*new ServerGroupChatRoomPrivate, core, ChatRoomId(peerAddress, peerAddress)), LocalConference(core, peerAddress, nullptr) {} +ServerGroupChatRoom::~ServerGroupChatRoom () {}; + ServerGroupChatRoom::CapabilitiesMask ServerGroupChatRoom::getCapabilities () const { return 0; } void ServerGroupChatRoom::allowCpim (bool value) { - + } void ServerGroupChatRoom::allowMultipart (bool value) { - + } bool ServerGroupChatRoom::canHandleCpim () const { @@ -187,7 +193,7 @@ void ServerGroupChatRoom::addParticipant (const IdentityAddress &, const CallSes void ServerGroupChatRoom::addParticipants (const list &, const CallSessionParams *, bool) {} -void ServerGroupChatRoom::removeParticipant (const shared_ptr &) {} +void ServerGroupChatRoom::removeParticipant (const shared_ptr &participant) {} void ServerGroupChatRoom::removeParticipants (const list> &) {} diff --git a/src/chat/chat-room/server-group-chat-room.h b/src/chat/chat-room/server-group-chat-room.h index 57d49dcfc..7f83f9253 100644 --- a/src/chat/chat-room/server-group-chat-room.h +++ b/src/chat/chat-room/server-group-chat-room.h @@ -45,6 +45,8 @@ public: unsigned int lastNotifyId ); + ~ServerGroupChatRoom (); + std::shared_ptr getCore () const; void allowCpim (bool value) override; @@ -68,7 +70,7 @@ public: bool hasMedia ) override; - void removeParticipant (const std::shared_ptr &participant) override; + void removeParticipant (const std::shared_ptr &participant) override; void removeParticipants (const std::list> &participants) override; std::shared_ptr findParticipant (const IdentityAddress &participantAddress) const override; diff --git a/src/chat/cpim/header/cpim-core-headers.cpp b/src/chat/cpim/header/cpim-core-headers.cpp index 6d88fccca..4f35651fe 100644 --- a/src/chat/cpim/header/cpim-core-headers.cpp +++ b/src/chat/cpim/header/cpim-core-headers.cpp @@ -17,6 +17,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include +#include + +#include "linphone/utils/utils.h" + +#include "logger/logger.h" + #include "chat/cpim/parser/cpim-parser.h" #include "cpim-header-p.h" @@ -28,51 +35,278 @@ using namespace std; LINPHONE_BEGIN_NAMESPACE -Cpim::CoreHeader::CoreHeader () : Header(*new HeaderPrivate) {} +class Cpim::ContactHeaderPrivate : public HeaderPrivate { +public: + string uri; + string formalName; +}; -Cpim::CoreHeader::CoreHeader (HeaderPrivate &p) : Header(p) {} +Cpim::ContactHeader::ContactHeader () : Header(*new ContactHeaderPrivate) {} -Cpim::CoreHeader::~CoreHeader () {} +Cpim::ContactHeader::ContactHeader (const string &uri, const string &formalName) : ContactHeader() { + setUri(uri); + setFormalName(formalName); +} -bool Cpim::CoreHeader::isValid () const { - return !getValue().empty(); +string Cpim::ContactHeader::getUri () const { + L_D(); + return d->uri; +} + +void Cpim::ContactHeader::setUri (const string &uri) { + L_D(); + d->uri = uri; +} + +string Cpim::ContactHeader::getFormalName () const { + L_D(); + return d->formalName; +} + +void Cpim::ContactHeader::setFormalName (const string &formalName) { + L_D(); + if (formalName.front() == '\"' && formalName.back() == '\"') + d->formalName = formalName.substr(1, formalName.size() - 2); + else if (formalName.back() == ' ') + d->formalName = formalName.substr(0, formalName.size() - 1); + else + d->formalName = formalName; +} + +string Cpim::ContactHeader::getValue () const { + L_D(); + string result; + if (!d->formalName.empty()) + result += "\"" + d->formalName + "\""; + result += "<" + d->uri + ">"; + return result; +} + +string Cpim::ContactHeader::asString () const { + return getName() + ": " + getValue() + "\r\n"; } // ----------------------------------------------------------------------------- -#define MAKE_CORE_HEADER_IMPL(CLASS_PREFIX) \ - bool Cpim::CLASS_PREFIX ## Header::setValue(const string &value) { \ - return Parser::getInstance()->coreHeaderIsValid(value) && Header::setValue(value); \ +class Cpim::DateTimeHeaderPrivate : public HeaderPrivate { +public: + tm dateTime; + tm dateTimeOffset; + string signOffset; +}; + +Cpim::DateTimeHeader::DateTimeHeader () : Header(*new DateTimeHeaderPrivate) {} + +Cpim::DateTimeHeader::DateTimeHeader (time_t time) : DateTimeHeader() { + setTime(time); +} + +Cpim::DateTimeHeader::DateTimeHeader (const tm &time, const tm &timeOffset, const string &signOffset) : DateTimeHeader() { + setTime(time, timeOffset, signOffset); +} + +time_t Cpim::DateTimeHeader::getTime () const { + L_D(); + + tm result = d->dateTime; + result.tm_year -= 1900; + result.tm_isdst = 0; + + if (d->signOffset == "+") { + result.tm_hour += d->dateTimeOffset.tm_hour; + result.tm_min += d->dateTimeOffset.tm_min; + + while (result.tm_min > 59) { + result.tm_hour++; + result.tm_min -= 60; + } + } + else if (d->signOffset == "-") { + result.tm_hour -= d->dateTimeOffset.tm_hour; + result.tm_hour -= d->dateTimeOffset.tm_min; + + while (result.tm_min < 0) { + result.tm_hour--; + result.tm_min += 60; + } } -MAKE_CORE_HEADER_IMPL(From); -MAKE_CORE_HEADER_IMPL(To); -MAKE_CORE_HEADER_IMPL(Cc); -MAKE_CORE_HEADER_IMPL(DateTime); -MAKE_CORE_HEADER_IMPL(MessageId); + return Utils::getTmAsTimeT(result); +} -MAKE_CORE_HEADER_IMPL(Ns); -MAKE_CORE_HEADER_IMPL(Require); +void Cpim::DateTimeHeader::setTime (const time_t time) { + L_D(); -#undef MAKE_CORE_HEADER_IMPL + d->signOffset = "Z"; + d->dateTime = Utils::getTimeTAsTm(time); + d->dateTime.tm_year += 1900; +} + +void Cpim::DateTimeHeader::setTime (const tm &time, const tm &timeOffset, const string &signOffset) { + L_D(); + + d->dateTime = time; + d->dateTimeOffset = timeOffset; + d->signOffset = signOffset; +} + +string Cpim::DateTimeHeader::getValue () const { + L_D(); + + stringstream ss; + ss << setfill('0') << setw(4) << d->dateTime.tm_year << "-" + << setfill('0') << setw(2) << d->dateTime.tm_mon + 1 << "-" + << setfill('0') << setw(2) << d->dateTime.tm_mday << "T" + << setfill('0') << setw(2) << d->dateTime.tm_hour << ":" + << setfill('0') << setw(2) << d->dateTime.tm_min << ":" + << setfill('0') << setw(2) << d->dateTime.tm_sec; + + ss << d->signOffset; + if (d->signOffset != "Z") + ss << setfill('0') << setw(2) << d->dateTimeOffset.tm_hour << ":" + << setfill('0') << setw(2) << d->dateTimeOffset.tm_min; + + return ss.str(); +} + +string Cpim::DateTimeHeader::asString () const { + return getName() + ": " + getValue() + "\r\n"; +} + +struct tm Cpim::DateTimeHeader::getTimeStruct () const { + L_D(); + return d->dateTime; +} + +struct tm Cpim::DateTimeHeader::getTimeOffset () const { + L_D(); + return d->dateTimeOffset; +} + +string Cpim::DateTimeHeader::getSignOffset () const { + L_D(); + return d->signOffset; +} // ----------------------------------------------------------------------------- -void Cpim::CoreHeader::force (const string &value) { - Header::setValue(value); +class Cpim::NsHeaderPrivate : public HeaderPrivate { +public: + string uri; + string prefixName; +}; + +Cpim::NsHeader::NsHeader () : Header(*new NsHeaderPrivate) {} + +Cpim::NsHeader::NsHeader (const string &uri, const string &prefixName) : NsHeader() { + setUri(uri); + setPrefixName(prefixName); +} + +string Cpim::NsHeader::getUri () const { + L_D(); + return d->uri; +} + +void Cpim::NsHeader::setUri (const string &uri) { + L_D(); + d->uri = uri; +} + +string Cpim::NsHeader::getPrefixName () const { + L_D(); + return d->prefixName; +} + +void Cpim::NsHeader::setPrefixName (const string &prefixName) { + L_D(); + d->prefixName = prefixName; +} + +string Cpim::NsHeader::getValue () const { + L_D(); + + string ns; + if (!d->prefixName.empty()) + ns = d->prefixName + " "; + + return ns + "<" + d->uri + ">"; +} + +string Cpim::NsHeader::asString () const { + return getName() + ": " + getValue() + "\r\n"; +} + +// ----------------------------------------------------------------------------- + +class Cpim::RequireHeaderPrivate : public HeaderPrivate { +public: + list headerNames; +}; + +Cpim::RequireHeader::RequireHeader () : Header(*new RequireHeaderPrivate) {} + +Cpim::RequireHeader::RequireHeader (const string &headerNames) : RequireHeader() { + for (const string &header : Utils::split(headerNames, ",")) { + addHeaderName(header); + } +} + +Cpim::RequireHeader::RequireHeader (const list &headerNames) : RequireHeader() { + L_D(); + d->headerNames = headerNames; +} + +list Cpim::RequireHeader::getHeaderNames () const { + L_D(); + return d->headerNames; +} + +void Cpim::RequireHeader::addHeaderName (const string &headerName) { + L_D(); + d->headerNames.push_back(headerName); +} + +string Cpim::RequireHeader::getValue () const { + L_D(); + + string requires; + for (const string &header : d->headerNames) { + if (header != d->headerNames.front()) + requires += ","; + requires += header; + } + + return requires; +} + +string Cpim::RequireHeader::asString () const { + return getName() + ": " + getValue() + "\r\n"; } // ----------------------------------------------------------------------------- class Cpim::SubjectHeaderPrivate : public HeaderPrivate { public: + string subject; string language; }; -Cpim::SubjectHeader::SubjectHeader () : CoreHeader(*new SubjectHeaderPrivate) {} +Cpim::SubjectHeader::SubjectHeader () : Header(*new SubjectHeaderPrivate) {} -bool Cpim::SubjectHeader::setValue (const string &value) { - return Parser::getInstance()->coreHeaderIsValid(value) && Header::setValue(value); +Cpim::SubjectHeader::SubjectHeader (const string &subject, const string &language) : SubjectHeader() { + setSubject(subject); + setLanguage(language); +} + +string Cpim::SubjectHeader::getSubject () const { + L_D(); + return d->subject; +} + +void Cpim::SubjectHeader::setSubject (const string &subject) { + L_D(); + d->subject = subject; } string Cpim::SubjectHeader::getLanguage () const { @@ -80,30 +314,23 @@ string Cpim::SubjectHeader::getLanguage () const { return d->language; } -bool Cpim::SubjectHeader::setLanguage (const string &language) { - if (!language.empty() && !Parser::getInstance()->subjectHeaderLanguageIsValid(language)) - return false; - +void Cpim::SubjectHeader::setLanguage (const string &language) { L_D(); d->language = language; - - return true; } -string Cpim::SubjectHeader::asString () const { +string Cpim::SubjectHeader::getValue () const { L_D(); string languageParam; if (!d->language.empty()) languageParam = ";lang=" + d->language; - return getName() + ":" + languageParam + " " + getValue() + "\r\n"; + return languageParam + " " + d->subject; } -void Cpim::SubjectHeader::force (const string &value, const string &language) { - L_D(); - CoreHeader::force(value); - d->language = language; +string Cpim::SubjectHeader::asString () const { + return getName() + ":" + getValue() + "\r\n"; } LINPHONE_END_NAMESPACE diff --git a/src/chat/cpim/header/cpim-core-headers.h b/src/chat/cpim/header/cpim-core-headers.h index 0fa205011..2ddd7ea29 100644 --- a/src/chat/cpim/header/cpim-core-headers.h +++ b/src/chat/cpim/header/cpim-core-headers.h @@ -20,61 +20,160 @@ #ifndef _L_CPIM_CORE_HEADERS_H_ #define _L_CPIM_CORE_HEADERS_H_ +#include +#include + #include "cpim-header.h" // ============================================================================= LINPHONE_BEGIN_NAMESPACE -#define MAKE_CORE_HEADER(CLASS_PREFIX, NAME) \ - class LINPHONE_PUBLIC CLASS_PREFIX ## Header : public CoreHeader { \ +#define MAKE_CONTACT_HEADER(CLASS_PREFIX, NAME) \ + class LINPHONE_PUBLIC CLASS_PREFIX ## Header : public ContactHeader { \ public: \ - CLASS_PREFIX ## Header() = default; \ - inline std::string getName() const override { \ + CLASS_PREFIX ## Header () = default; \ + CLASS_PREFIX ## Header (const std::string &uri, const std::string &formalName = "") : ContactHeader (uri, formalName) {} \ + inline std::string getName () const override { \ return NAME; \ } \ - bool setValue(const std::string &value) override; \ private: \ L_DISABLE_COPY(CLASS_PREFIX ## Header); \ }; namespace Cpim { - class HeaderNode; + class DateTimeHeaderNode; // ------------------------------------------------------------------------- - // Generic core header. + // Specific Contact headers declaration. // ------------------------------------------------------------------------- - class LINPHONE_PUBLIC CoreHeader : public Header { - friend class HeaderNode; + class ContactHeaderPrivate; + class LINPHONE_PUBLIC ContactHeader : public Header { public: - CoreHeader (); + ContactHeader (); - virtual ~CoreHeader () = 0; + ContactHeader (const std::string &uri, const std::string &formalName = ""); - bool isValid () const override; + std::string getUri () const; + void setUri (const std::string &uri); - protected: - explicit CoreHeader (HeaderPrivate &p); + std::string getFormalName () const; + void setFormalName (const std::string &formalName); - void force (const std::string &value); + std::string getValue () const override; + + std::string asString () const override; private: - L_DISABLE_COPY(CoreHeader); + L_DECLARE_PRIVATE(ContactHeader); + L_DISABLE_COPY(ContactHeader); }; // ------------------------------------------------------------------------- - // Core headers. + + MAKE_CONTACT_HEADER(From, "From"); + MAKE_CONTACT_HEADER(To, "To"); + MAKE_CONTACT_HEADER(Cc, "cc"); + + // ------------------------------------------------------------------------- + // Specific DateTime declaration. // ------------------------------------------------------------------------- - MAKE_CORE_HEADER(From, "From"); - MAKE_CORE_HEADER(To, "To"); - MAKE_CORE_HEADER(Cc, "cc"); - MAKE_CORE_HEADER(DateTime, "DateTime"); - MAKE_CORE_HEADER(MessageId, "Message-ID"); - MAKE_CORE_HEADER(Ns, "NS"); - MAKE_CORE_HEADER(Require, "Require"); + class DateTimeHeaderPrivate; + + class LINPHONE_PUBLIC DateTimeHeader : public Header { + friend class DateTimeHeaderNode; + + public: + DateTimeHeader (); + + DateTimeHeader (time_t time); + + DateTimeHeader (const tm &time, const tm &timeOffset, const std::string &signOffset); + + inline std::string getName () const override { + return "DateTime"; + } + + time_t getTime () const; + void setTime (const time_t time); + + void setTime (const tm &time, const tm &timeOffset, const std::string &signOffset); + + std::string getValue () const override; + + std::string asString () const override; + + private: + tm getTimeStruct () const; + tm getTimeOffset () const; + std::string getSignOffset () const; + + L_DECLARE_PRIVATE(DateTimeHeader); + L_DISABLE_COPY(DateTimeHeader); + }; + + // ------------------------------------------------------------------------- + // Specific Ns declaration. + // ------------------------------------------------------------------------- + + class NsHeaderPrivate; + + class LINPHONE_PUBLIC NsHeader : public Header { + public: + NsHeader (); + + NsHeader (const std::string &uri, const std::string &prefixName = ""); + + inline std::string getName () const override { + return "NS"; + } + + std::string getPrefixName () const; + void setPrefixName (const std::string &prefixName); + + std::string getUri () const; + void setUri (const std::string &uri); + + std::string getValue () const override; + + std::string asString () const override; + + private: + L_DECLARE_PRIVATE(NsHeader); + L_DISABLE_COPY(NsHeader); + }; + + // ------------------------------------------------------------------------- + // Specific Require declaration. + // ------------------------------------------------------------------------- + + class RequireHeaderPrivate; + + class LINPHONE_PUBLIC RequireHeader : public Header { + public: + RequireHeader (); + + RequireHeader (const std::string &headerNames); + RequireHeader (const std::list &headerNames); + + inline std::string getName () const override { + return "Require"; + } + + std::list getHeaderNames () const; + void addHeaderName (const std::string &headerName); + + std::string getValue () const override; + + std::string asString () const override; + + private: + L_DECLARE_PRIVATE(RequireHeader); + L_DISABLE_COPY(RequireHeader); + }; // ------------------------------------------------------------------------- // Specific Subject declaration. @@ -82,33 +181,33 @@ namespace Cpim { class SubjectHeaderPrivate; - class LINPHONE_PUBLIC SubjectHeader : public CoreHeader { - friend class HeaderNode; - + class LINPHONE_PUBLIC SubjectHeader : public Header { public: SubjectHeader (); + SubjectHeader (const std::string &subject, const std::string &language = ""); + inline std::string getName () const override { return "Subject"; } - bool setValue (const std::string &value) override; + std::string getSubject () const; + void setSubject (const std::string &subject); std::string getLanguage () const; - bool setLanguage (const std::string &language); + void setLanguage (const std::string &language); + + std::string getValue () const override; std::string asString () const override; - protected: - void force (const std::string &value, const std::string &language); - private: L_DECLARE_PRIVATE(SubjectHeader); L_DISABLE_COPY(SubjectHeader); }; } -#undef MAKE_CORE_HEADER +#undef MAKE_CONTACT_HEADER LINPHONE_END_NAMESPACE diff --git a/src/chat/cpim/header/cpim-generic-header.cpp b/src/chat/cpim/header/cpim-generic-header.cpp index 67a7b81d4..6c5947777 100644 --- a/src/chat/cpim/header/cpim-generic-header.cpp +++ b/src/chat/cpim/header/cpim-generic-header.cpp @@ -34,38 +34,50 @@ LINPHONE_BEGIN_NAMESPACE class Cpim::GenericHeaderPrivate : public HeaderPrivate { public: - GenericHeaderPrivate () : parameters(make_shared > >()) {} + GenericHeaderPrivate () : parameters(make_shared>>()) {} string name; - shared_ptr > > parameters; + string value; + shared_ptr>> parameters; }; Cpim::GenericHeader::GenericHeader () : Header(*new GenericHeaderPrivate) {} +Cpim::GenericHeader::GenericHeader (string name, string value, string parameters) : GenericHeader() { + setName(name); + setValue(value); + + for (const auto ¶meter : Utils::split(parameters, ';')) { + size_t equalIndex = parameter.find('='); + if (equalIndex != string::npos) + addParameter(parameter.substr(0, equalIndex), parameter.substr(equalIndex + 1)); + } +} + string Cpim::GenericHeader::getName () const { L_D(); return d->name; } -bool Cpim::GenericHeader::setName (const string &name) { +void Cpim::GenericHeader::setName (const string &name) { L_D(); static const set reserved = { "From", "To", "cc", "DateTime", "Subject", "NS", "Require" }; - if ( - reserved.find(name) != reserved.end() || - !Parser::getInstance()->headerNameIsValid(name) - ) - return false; - - d->name = name; - return true; + if (reserved.find(name) == reserved.end()) + d->name = name; } -bool Cpim::GenericHeader::setValue (const string &value) { - return Parser::getInstance()->headerValueIsValid(value) && Header::setValue(value); +string Cpim::GenericHeader::getValue () const { + L_D(); + return d->value; +} + +void Cpim::GenericHeader::setValue (const string &value) { + L_D(); + d->value = value; } Cpim::GenericHeader::ParameterList Cpim::GenericHeader::getParameters () const { @@ -73,14 +85,9 @@ Cpim::GenericHeader::ParameterList Cpim::GenericHeader::getParameters () const { return d->parameters; } -bool Cpim::GenericHeader::addParameter (const string &key, const string &value) { +void Cpim::GenericHeader::addParameter (const string &key, const string &value) { L_D(); - - if (!Parser::getInstance()->headerParameterIsValid(key + "=" + value)) - return false; - d->parameters->push_back(make_pair(key, value)); - return true; } void Cpim::GenericHeader::removeParameter (const string &key, const string &value) { @@ -88,11 +95,6 @@ void Cpim::GenericHeader::removeParameter (const string &key, const string &valu d->parameters->remove(make_pair(key, value)); } -bool Cpim::GenericHeader::isValid () const { - L_D(); - return !d->name.empty() && !getValue().empty(); -} - string Cpim::GenericHeader::asString () const { L_D(); @@ -103,21 +105,4 @@ string Cpim::GenericHeader::asString () const { return d->name + ":" + parameters + " " + getValue() + "\r\n"; } -// ----------------------------------------------------------------------------- - -void Cpim::GenericHeader::force (const string &name, const string &value, const string ¶meters) { - L_D(); - - // Set name/value. - d->name = name; - Header::setValue(value); - - // Parse and build parameters list. - for (const auto ¶meter : Utils::split(parameters, ';')) { - size_t equalIndex = parameter.find('='); - if (equalIndex != string::npos) - d->parameters->push_back(make_pair(parameter.substr(0, equalIndex), parameter.substr(equalIndex + 1))); - } -} - LINPHONE_END_NAMESPACE diff --git a/src/chat/cpim/header/cpim-generic-header.h b/src/chat/cpim/header/cpim-generic-header.h index 2433a9cb7..6ee8a3695 100644 --- a/src/chat/cpim/header/cpim-generic-header.h +++ b/src/chat/cpim/header/cpim-generic-header.h @@ -38,24 +38,22 @@ namespace Cpim { public: GenericHeader (); + GenericHeader (std::string name, std::string value, std::string parameters = ""); + std::string getName () const override; - bool setName (const std::string &name); + void setName (const std::string &name); - bool setValue (const std::string &value) override; + std::string getValue () const override; + void setValue (const std::string &value); - typedef std::shared_ptr > > ParameterList; + typedef std::shared_ptr>> ParameterList; ParameterList getParameters () const; - bool addParameter (const std::string &key, const std::string &value); + void addParameter (const std::string &key, const std::string &value); void removeParameter (const std::string &key, const std::string &value); - bool isValid () const override; - std::string asString () const override; - protected: - void force (const std::string &name, const std::string &value, const std::string ¶meters); - private: L_DECLARE_PRIVATE(GenericHeader); L_DISABLE_COPY(GenericHeader); diff --git a/src/chat/cpim/header/cpim-header-p.h b/src/chat/cpim/header/cpim-header-p.h index 048e91309..2aaea0acb 100644 --- a/src/chat/cpim/header/cpim-header-p.h +++ b/src/chat/cpim/header/cpim-header-p.h @@ -30,8 +30,6 @@ LINPHONE_BEGIN_NAMESPACE namespace Cpim { class HeaderPrivate : public ObjectPrivate { private: - std::string value; - L_DECLARE_PUBLIC(Header); }; } diff --git a/src/chat/cpim/header/cpim-header.cpp b/src/chat/cpim/header/cpim-header.cpp index 8141d7811..6a3b83470 100644 --- a/src/chat/cpim/header/cpim-header.cpp +++ b/src/chat/cpim/header/cpim-header.cpp @@ -29,20 +29,4 @@ LINPHONE_BEGIN_NAMESPACE Cpim::Header::Header (HeaderPrivate &p) : Object(p) {} -string Cpim::Header::getValue () const { - L_D(); - return d->value; -} - -bool Cpim::Header::setValue (const string &value) { - L_D(); - d->value = value; - return true; -} - -string Cpim::Header::asString () const { - L_D(); - return getName() + ": " + d->value + "\r\n"; -} - LINPHONE_END_NAMESPACE diff --git a/src/chat/cpim/header/cpim-header.h b/src/chat/cpim/header/cpim-header.h index 13dcfdce8..f71d115b0 100644 --- a/src/chat/cpim/header/cpim-header.h +++ b/src/chat/cpim/header/cpim-header.h @@ -35,12 +35,9 @@ namespace Cpim { virtual std::string getName () const = 0; - std::string getValue () const; - virtual bool setValue (const std::string &value); + virtual std::string getValue () const = 0; - virtual bool isValid () const = 0; - - virtual std::string asString () const; + virtual std::string asString () const = 0; protected: explicit Header (HeaderPrivate &p); diff --git a/src/chat/cpim/message/cpim-message.cpp b/src/chat/cpim/message/cpim-message.cpp index 84753f4ef..ca4aa3b4d 100644 --- a/src/chat/cpim/message/cpim-message.cpp +++ b/src/chat/cpim/message/cpim-message.cpp @@ -18,6 +18,7 @@ */ #include +#include #include "linphone/utils/utils.h" @@ -36,10 +37,10 @@ LINPHONE_BEGIN_NAMESPACE class Cpim::MessagePrivate : public ObjectPrivate { public: - typedef list > PrivHeaderList; + using PrivHeaderList = list>; + using PrivHeaderMap = map>; - shared_ptr cpimHeaders = make_shared(); // TODO: Remove this useless variable - shared_ptr messageHeaders = make_shared(); + PrivHeaderMap messageHeaders; shared_ptr contentHeaders = make_shared(); string content; }; @@ -48,50 +49,47 @@ Cpim::Message::Message () : Object(*new MessagePrivate) {} // ----------------------------------------------------------------------------- -Cpim::Message::HeaderList Cpim::Message::getCpimHeaders () const { +Cpim::Message::HeaderList Cpim::Message::getMessageHeaders (const string &ns) const { L_D(); - return d->cpimHeaders; + + if (d->messageHeaders.find(ns) == d->messageHeaders.end()) + return nullptr; + + return d->messageHeaders.at(ns); } -bool Cpim::Message::addCpimHeader (const Header &cpimHeader) { +void Cpim::Message::addMessageHeader (const Header &messageHeader, const string &ns) { L_D(); - if (!cpimHeader.isValid()) - return false; + if (d->messageHeaders.find(ns) == d->messageHeaders.end()) + d->messageHeaders[ns] = make_shared(); - d->cpimHeaders->push_back(Parser::getInstance()->cloneHeader(cpimHeader)); - return true; + auto list = d->messageHeaders.at(ns); + list->push_back(Parser::getInstance()->cloneHeader(messageHeader)); } -void Cpim::Message::removeCpimHeader (const Header &cpimHeader) { +void Cpim::Message::removeMessageHeader (const Header &messageHeader, const string &ns) { L_D(); - d->cpimHeaders->remove_if([&cpimHeader](const shared_ptr &header) { - return cpimHeader.getName() == header->getName() && cpimHeader.getValue() == header->getValue(); - }); + + if (d->messageHeaders.find(ns) != d->messageHeaders.end()) + d->messageHeaders.at(ns)->remove_if([&messageHeader](const shared_ptr &header) { + return messageHeader.getName() == header->getName() && messageHeader.getValue() == header->getValue(); + }); } -// ----------------------------------------------------------------------------- - -Cpim::Message::HeaderList Cpim::Message::getMessageHeaders () const { - L_D(); - return d->messageHeaders; -} - -bool Cpim::Message::addMessageHeader (const Header &messageHeader) { +shared_ptr Cpim::Message::getMessageHeader (const string &name, const string &ns) const { L_D(); - if (!messageHeader.isValid()) - return false; + if (d->messageHeaders.find(ns) == d->messageHeaders.end()) + return nullptr; - d->messageHeaders->push_back(Parser::getInstance()->cloneHeader(messageHeader)); - return true; -} + auto list = d->messageHeaders.at(ns); + for (const auto &messageHeader : *list) { + if (messageHeader->getName() == name) + return messageHeader; + } -void Cpim::Message::removeMessageHeader (const Header &messageHeader) { - L_D(); - d->messageHeaders->remove_if([&messageHeader](const shared_ptr &header) { - return messageHeader.getName() == header->getName() && messageHeader.getValue() == header->getValue(); - }); + return nullptr; } // ----------------------------------------------------------------------------- @@ -101,14 +99,9 @@ Cpim::Message::HeaderList Cpim::Message::getContentHeaders () const { return d->contentHeaders; } -bool Cpim::Message::addContentHeader (const Header &contentHeader) { +void Cpim::Message::addContentHeader (const Header &contentHeader) { L_D(); - - if (!contentHeader.isValid()) - return false; - d->contentHeaders->push_back(Parser::getInstance()->cloneHeader(contentHeader)); - return true; } void Cpim::Message::removeContentHeader (const Header &contentHeader) { @@ -118,6 +111,17 @@ void Cpim::Message::removeContentHeader (const Header &contentHeader) { }); } +shared_ptr Cpim::Message::getContentHeader(const string &name) const { + L_D(); + + for (const auto &contentHeader : *d->contentHeaders) { + if (contentHeader->getName() == name) + return contentHeader; + } + + return nullptr; +} + // ----------------------------------------------------------------------------- string Cpim::Message::getContent () const { @@ -133,30 +137,19 @@ bool Cpim::Message::setContent (const string &content) { // ----------------------------------------------------------------------------- -bool Cpim::Message::isValid () const { - L_D(); - - return find_if(d->cpimHeaders->cbegin(), d->cpimHeaders->cend(), - [](const shared_ptr &header) { - return Utils::iequals(header->getName(), "content-type") && (ContentType(header->getValue()) == ContentType::Cpim); - }) != d->cpimHeaders->cend(); -} - -// ----------------------------------------------------------------------------- - string Cpim::Message::asString () const { L_D(); string output; - // TODO: Remove cpimHeaders - for (const auto &cpimHeader : *d->cpimHeaders) - output += cpimHeader->asString(); - output += "\r\n"; - // TODO Remove cpimHeaders - - if (d->messageHeaders->size() > 0) { - for (const auto &messageHeader : *d->messageHeaders) - output += messageHeader->asString(); + if (d->messageHeaders.size() > 0) { + for (const auto &entry : d->messageHeaders) { + auto list = entry.second; + for (const auto &messageHeader : *list) { + if (entry.first != "") + output += entry.first + "."; + output += messageHeader->asString(); + } + } output += "\r\n"; } diff --git a/src/chat/cpim/message/cpim-message.h b/src/chat/cpim/message/cpim-message.h index c7778c929..19e91a43a 100644 --- a/src/chat/cpim/message/cpim-message.h +++ b/src/chat/cpim/message/cpim-message.h @@ -34,27 +34,21 @@ namespace Cpim { public: Message (); - typedef std::shared_ptr > > HeaderList; + typedef std::shared_ptr>> HeaderList; - // TODO: Remove these useless methods - HeaderList getCpimHeaders () const; - bool addCpimHeader (const Header &cpimHeader); - void removeCpimHeader (const Header &cpimHeader); - // TODO: Remove these useless methods + HeaderList getMessageHeaders (const std::string &ns = "") const; + void addMessageHeader (const Header &messageHeader, const std::string &ns = ""); + void removeMessageHeader (const Header &messageHeader, const std::string &ns = ""); + std::shared_ptr getMessageHeader (const std::string &name, const std::string &ns = "") const; - HeaderList getMessageHeaders () const; - bool addMessageHeader (const Header &messageHeader); - void removeMessageHeader (const Header &messageHeader); - HeaderList getContentHeaders () const; - bool addContentHeader (const Header &contentHeader); + void addContentHeader (const Header &contentHeader); void removeContentHeader (const Header &contentHeader); + std::shared_ptr getContentHeader (const std::string &name) const; std::string getContent () const; bool setContent (const std::string &content); - bool isValid () const; // TODO: Remove this useless method - std::string asString () const; static std::shared_ptr createFromString (const std::string &str); diff --git a/src/chat/cpim/parser/cpim-parser.cpp b/src/chat/cpim/parser/cpim-parser.cpp index d3beb28d2..23fa0a360 100644 --- a/src/chat/cpim/parser/cpim-parser.cpp +++ b/src/chat/cpim/parser/cpim-parser.cpp @@ -17,7 +17,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include +#include #include #include @@ -53,20 +53,10 @@ namespace Cpim { HeaderNode () = default; explicit HeaderNode (const Header &header) : mName(header.getName()), mValue(header.getValue()) { - // Generic header. const GenericHeader *genericHeader = dynamic_cast(&header); if (genericHeader) { for (const auto ¶meter : *genericHeader->getParameters()) mParameters += ";" + parameter.first + "=" + parameter.second; - return; - } - - // Subject header. - const SubjectHeader *subjectHeader = dynamic_cast(&header); - if (subjectHeader) { - const string language = subjectHeader->getLanguage(); - if (!language.empty()) - mParameters = ";lang=" + language; } } @@ -75,7 +65,12 @@ namespace Cpim { } void setName (const string &name) { - mName = name; + static const set reserved = { + "From", "To", "cc", "DateTime", "Subject", "NS", "Require" + }; + + if (reserved.find(name) == reserved.end()) + mName = name; } string getParameters () const { @@ -94,68 +89,425 @@ namespace Cpim { mValue = value; } - shared_ptr
createHeader (bool force) const; + virtual shared_ptr
createHeader () const; + + virtual bool isValid () const; private: - template - shared_ptr
createCoreHeader (bool force) const { - shared_ptr header = make_shared(); - if (force) - header->force(mValue); - else if (!header->setValue(mValue)) { - lWarning() << "Unable to set value on core header: `" << mName << "` => `" << mValue << "`."; - return nullptr; - } - - return header; - } - string mName; string mValue; string mParameters; }; - template<> - shared_ptr
HeaderNode::createCoreHeader(bool force) const { - shared_ptr header = make_shared(); - const string language = mParameters.length() >= 6 ? mParameters.substr(6) : ""; - - if (force) - header->force(mValue, language); - else if (!header->setValue(mValue) || (!language.empty() && !header->setLanguage(language))) { - lWarning() << "Unable to set value on subject header: `" << - mName << "` => `" << mValue << "`, `" << language << "`."; - return nullptr; - } - - return header; + bool HeaderNode::isValid () const { + return !mName.empty() && !mValue.empty(); } - shared_ptr
HeaderNode::createHeader (bool force = false) const { - static const unordered_map(HeaderNode::*)(bool)const> reservedHandlers = { - { "From", &HeaderNode::createCoreHeader }, - { "To", &HeaderNode::createCoreHeader }, - { "cc", &HeaderNode::createCoreHeader }, - { "DateTime", &HeaderNode::createCoreHeader }, - { "Message-ID", &HeaderNode::createCoreHeader }, - { "Subject", &HeaderNode::createCoreHeader }, - { "NS", &HeaderNode::createCoreHeader }, - { "Require", &HeaderNode::createCoreHeader } - }; + shared_ptr
HeaderNode::createHeader () const { + if (!isValid()) + return nullptr; - // Core Header. - const auto it = reservedHandlers.find(mName); - if (it != reservedHandlers.cend()) - return (this->*it->second)(force); - - // Generic Header shared_ptr genericHeader = make_shared(); - genericHeader->force(mName, mValue, mParameters); + genericHeader->setName(mName); + + for (const auto ¶meter : Utils::split(mParameters, ';')) { + size_t equalIndex = parameter.find('='); + if (equalIndex != string::npos) + genericHeader->addParameter(parameter.substr(0, equalIndex), parameter.substr(equalIndex + 1)); + } + + genericHeader->setValue(mValue); return genericHeader; } // ------------------------------------------------------------------------- + class ContactHeaderNode : public HeaderNode { + public: + ContactHeaderNode () = default; + + string getFormalName () const { + return mFormalName; + } + + void setFormalName (const string &formalName) { + mFormalName = formalName; + } + + string getUri () const { + return mUri; + } + + void setUri (const string &uri) { + mUri = uri; + } + + bool isValid () const override; + + private: + string mFormalName; + string mUri; + }; + + bool ContactHeaderNode::isValid () const { + return !mUri.empty(); + } + + // ------------------------------------------------------------------------- + + class FromHeaderNode : public ContactHeaderNode { + public: + FromHeaderNode () = default; + + explicit FromHeaderNode (const Header &header) { + const FromHeader *fromHeader = dynamic_cast(&header); + if (fromHeader) { + setFormalName(fromHeader->getFormalName()); + setUri(fromHeader->getUri()); + } + } + + shared_ptr
createHeader () const override; + }; + + shared_ptr
FromHeaderNode::createHeader () const { + if (!isValid()) + return nullptr; + + return make_shared(getUri(), getFormalName()); + } + + // ------------------------------------------------------------------------- + + class ToHeaderNode : public ContactHeaderNode { + public: + ToHeaderNode () = default; + + explicit ToHeaderNode (const Header &header) { + const ToHeader *toHeader = dynamic_cast(&header); + if (toHeader) { + setFormalName(toHeader->getFormalName()); + setUri(toHeader->getUri()); + } + } + + shared_ptr
createHeader () const override; + }; + + shared_ptr
ToHeaderNode::createHeader () const { + if (!isValid()) + return nullptr; + + return make_shared(getUri(), getFormalName()); + } + + // ------------------------------------------------------------------------- + + class CcHeaderNode : public ContactHeaderNode { + public: + CcHeaderNode () = default; + + explicit CcHeaderNode (const Header &header) { + const CcHeader *ccHeader = dynamic_cast(&header); + if (ccHeader) { + setFormalName(ccHeader->getFormalName()); + setUri(ccHeader->getUri()); + } + } + + shared_ptr
createHeader () const override; + }; + + shared_ptr
CcHeaderNode::createHeader () const { + if (!isValid()) + return nullptr; + + return make_shared(getUri(), getFormalName()); + } + + // ------------------------------------------------------------------------- + + class DateTimeOffsetNode : public Node { + friend class DateTimeHeaderNode; + + public: + DateTimeOffsetNode () { + mSign = "Z"; + } + + void setHour (const string &value) { + mHour = Utils::stoi(value); + } + + void setMinute (const string &value) { + mMinute = Utils::stoi(value); + } + + void setSign (const string &value) { + mSign = value; + } + + private: + string mSign; + int mHour; + int mMinute; + }; + + class DateTimeHeaderNode : public HeaderNode { + public: + DateTimeHeaderNode () = default; + + explicit DateTimeHeaderNode (const Header &header) { + const DateTimeHeader *dateTimeHeader = dynamic_cast(&header); + if (dateTimeHeader) { + setTime(dateTimeHeader->getTimeStruct()); + setTimeOffset(dateTimeHeader->getTimeOffset()); + setSignOffset(dateTimeHeader->getSignOffset()); + } + } + + struct tm getTime () const { + return mTime; + } + + void setTime (const struct tm &time) { + mTime = time; + } + + struct tm getTimeOffset () const { + return mTimeOffset; + } + + void setTimeOffset (const struct tm &timeOffset) { + mTimeOffset = timeOffset; + } + + string getSignOffset () const { + return mSignOffset; + } + + void setSignOffset (const string &signOffset) { + mSignOffset = signOffset; + } + + void setYear (const string &value) { + mTime.tm_year = Utils::stoi(value); + } + + void setMonth (const string &value) { + mTime.tm_mon = Utils::stoi(value) - 1; + } + + void setMonthDay (const string &value) { + mTime.tm_mday = Utils::stoi(value); + } + + void setHour (const string &value) { + mTime.tm_hour = Utils::stoi(value); + } + + void setMinute (const string &value) { + mTime.tm_min = Utils::stoi(value); + } + + void setSecond (const string &value) { + mTime.tm_sec = Utils::stoi(value); + } + + void setOffset (const shared_ptr &offset) { + mTimeOffset.tm_hour = offset->mHour; + mTimeOffset.tm_min = offset->mMinute; + mSignOffset = offset->mSign; + } + + bool isValid () const override; + + shared_ptr
createHeader() const override; + + private: + tm mTime; + tm mTimeOffset; + string mSignOffset; + }; + + bool DateTimeHeaderNode::isValid () const { + static const int daysInMonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + + // Check date. + const bool isLeapYear = (mTime.tm_year % 4 == 0 && mTime.tm_year % 100 != 0) || mTime.tm_year % 400 == 0; + + if (mTime.tm_mon < 1 || mTime.tm_mon > 12) + return false; + + if (mTime.tm_mday < 1 || (mTime.tm_mon == 2 && isLeapYear ? mTime.tm_mday > 29 : mTime.tm_mday > daysInMonth[mTime.tm_mon - 1])) + return false; + + // Check time. + if (mTime.tm_hour > 24 || mTime.tm_min > 59 || mTime.tm_sec > 60) + return false; + + // Check num offset. + if (mSignOffset != "Z") { + if (mTimeOffset.tm_hour > 24 || mTime.tm_min > 59) + return false; + } + + return true; + } + + shared_ptr
DateTimeHeaderNode::createHeader () const { + if (!isValid()) + return nullptr; + + return make_shared(getTime(), getTimeOffset(), getSignOffset()); + } + + // ------------------------------------------------------------------------- + + class SubjectHeaderNode : public HeaderNode { + public: + SubjectHeaderNode () = default; + + explicit SubjectHeaderNode (const Header &header) { + const SubjectHeader *subjectHeader = dynamic_cast(&header); + if (subjectHeader) { + setLanguage(subjectHeader->getLanguage()); + setSubject(subjectHeader->getSubject()); + } + } + + string getLanguage () const { + return mLanguage; + } + + void setLanguage (const string &language) { + mLanguage = language; + } + + string getSubject () const { + return mSubject; + } + + void setSubject (const string &subject) { + mSubject = subject; + } + + bool isValid () const override; + + shared_ptr
createHeader () const override; + + private: + string mLanguage; + string mSubject; + }; + + bool SubjectHeaderNode::isValid () const { + return !mSubject.empty(); + } + + shared_ptr
SubjectHeaderNode::createHeader () const { + if (!isValid()) + return nullptr; + + return make_shared(getSubject(), getLanguage()); + } + + // ------------------------------------------------------------------------- + + class NsHeaderNode : public HeaderNode { + public: + NsHeaderNode () = default; + + explicit NsHeaderNode (const Header &header) { + const NsHeader *nsHeader = dynamic_cast(&header); + if (nsHeader) { + setPrefixName(nsHeader->getPrefixName()); + setUri(nsHeader->getUri()); + } + } + + string getPrefixName () const { + return mPrefixName; + } + + void setPrefixName (const string &prefixName) { + mPrefixName = prefixName; + } + + string getUri () const { + return mUri; + } + + void setUri (const string &uri) { + mUri = uri; + } + + bool isValid () const override; + + shared_ptr
createHeader () const override; + + private: + string mPrefixName; + string mUri; + }; + + bool NsHeaderNode::isValid () const { + return !mUri.empty(); + } + + shared_ptr
NsHeaderNode::createHeader () const { + if (!isValid()) + return nullptr; + + return make_shared(getUri(), getPrefixName()); + } + + // ------------------------------------------------------------------------- + + class RequireHeaderNode : public HeaderNode { + public: + RequireHeaderNode () = default; + + explicit RequireHeaderNode (const Header &header) { + const RequireHeader *requireHeader = dynamic_cast(&header); + if (requireHeader) { + for (const auto &header : requireHeader->getHeaderNames()) { + if (header != requireHeader->getHeaderNames().front()) + mHeaderNames += ","; + mHeaderNames += header; + } + } + } + + string getHeaderNames () const { + return mHeaderNames; + } + + void setHeaderNames (const string &headerNames) { + mHeaderNames = headerNames; + } + + bool isValid () const override; + + shared_ptr
createHeader () const override; + + private: + string mHeaderNames; + }; + + bool RequireHeaderNode::isValid () const { + return !mHeaderNames.empty(); + } + + shared_ptr
RequireHeaderNode::createHeader () const { + if (!isValid()) + return nullptr; + + return make_shared(mHeaderNames); + } + + // ------------------------------------------------------------------------- + class ListHeaderNode : public Node, public list > {}; @@ -164,67 +516,61 @@ namespace Cpim { class MessageNode : public Node { public: - void addHeaders (const shared_ptr &headers) { - mHeaders->push_back(headers); + void addMessageHeaders (const shared_ptr &headers) { + for (const auto &headerNode : *headers) { + mMessageHeaders.push_back(headerNode); + } + } + + void addContentHeaders (const shared_ptr &headers) { + for (const auto &headerNode : *headers) { + mContentHeaders.push_back(headerNode); + } } // Warning: Call this function one time! shared_ptr createMessage () const { - size_t size = mHeaders->size(); - if (size < 2 || size > 3) { // TODO: Check that size is == 2 + if (mContentHeaders.empty() || mMessageHeaders.empty()) { lWarning() << "Bad headers lists size."; return nullptr; } + //TODO: Verify all headers from other namespaces + const shared_ptr message = make_shared(); - // TODO: To remove - if (size == 3) { - const shared_ptr cpimHeaders = mHeaders->front(); - if (find_if(cpimHeaders->cbegin(), cpimHeaders->cend(), - [](const shared_ptr &headerNode) { - return Utils::iequals(headerNode->getName(), "content-type") && (ContentType(headerNode->getValue()) == ContentType::Cpim); - }) == cpimHeaders->cend()) { - lWarning() << "No MIME `Content-Type` found!"; + // Add message headers. + for (const auto &headerNode : mMessageHeaders) { + string ns = ""; + + string::size_type n = headerNode->getName().find("."); + if (n != string::npos) { + ns = headerNode->getName().substr(0, n); + headerNode->setName(headerNode->getName().substr(n + 1)); + } + + const shared_ptr header = headerNode->createHeader(); + if (!header) return nullptr; - } - // Add MIME headers. - for (const auto &headerNode : *cpimHeaders) { - const shared_ptr header = headerNode->createHeader(); - if (!header || !message->addCpimHeader(*header)) - return nullptr; - } - - // Add message headers. - for (const auto &headerNode : **(++mHeaders->cbegin())) { - const shared_ptr header = headerNode->createHeader(); - if (!header || !message->addMessageHeader(*header)) - return nullptr; - } - } - // TODO: To remove - else { - // Add message headers. - for (const auto &headerNode : *mHeaders->front()) { - const shared_ptr header = headerNode->createHeader(); - if (!header || !message->addMessageHeader(*header)) - return nullptr; - } + message->addMessageHeader(*header, ns); } // Add content headers. - for (const auto &headerNode : *mHeaders->back()) { + for (const auto &headerNode : mContentHeaders) { const shared_ptr header = headerNode->createHeader(); - if (!header || !message->addContentHeader(*header)) + if (!header) return nullptr; + + message->addContentHeader(*header); } return message; } private: - shared_ptr > > mHeaders = make_shared > >(); + list> mContentHeaders; + list> mMessageHeaders; }; } @@ -237,17 +583,17 @@ public: Cpim::Parser::Parser () : Singleton(*new ParserPrivate) { L_D(); -#if TARGET_OS_IPHONE - CFBundleRef bundle = CFBundleGetBundleWithIdentifier( CFSTR("org.linphone.linphone") ); - CFURLRef grammar_url = CFBundleCopyResourceURL(bundle, CFSTR(CPIM_GRAMMAR), NULL, NULL); - CFStringRef grammar_path = CFURLCopyFileSystemPath(grammar_url, kCFURLPOSIXPathStyle); - CFStringEncoding encoding_method = CFStringGetSystemEncoding(); - const char *path = CFStringGetCStringPtr(grammar_path, encoding_method); - CFRelease(grammar_url); - CFRelease(grammar_path); -#else - const char *path = CPIM_GRAMMAR; -#endif + #if TARGET_OS_IPHONE + CFBundleRef bundle = CFBundleGetBundleWithIdentifier(CFSTR("org.linphone.linphone")); + CFURLRef grammarUrl = CFBundleCopyResourceURL(bundle, CFSTR(CPIM_GRAMMAR), nullptr, nullptr); + CFStringRef grammarPath = CFURLCopyFileSystemPath(grammarUrl, kCFURLPOSIXPathStyle); + CFStringEncoding encodingMethod = CFStringGetSystemEncoding(); + const char *path = CFStringGetCStringPtr(grammarPath, encodingMethod); + CFRelease(grammarUrl); + CFRelease(grammarPath); + #else + const char *path = CPIM_GRAMMAR; + #endif d->grammar = belr::GrammarLoader::get().load(path); if (!d->grammar) lFatal() << "Unable to load CPIM grammar."; @@ -261,27 +607,64 @@ shared_ptr Cpim::Parser::parseMessage (const string &input) { typedef void (list >::*pushPtr)(const shared_ptr &value); belr::Parser > parser(d->grammar); - parser.setHandler( - "Message", belr::make_fn(make_shared ) - )->setCollector( - "Headers", belr::make_sfn(&MessageNode::addHeaders) - ); + parser.setHandler("Message", belr::make_fn(make_shared)) + ->setCollector("Message-headers", belr::make_sfn(&MessageNode::addMessageHeaders)) + ->setCollector("Content-headers", belr::make_sfn(&MessageNode::addContentHeaders)); - parser.setHandler( - "Headers", belr::make_fn(make_shared ) - )->setCollector( - "Header", belr::make_sfn(static_cast(&ListHeaderNode::push_back)) - ); + parser.setHandler("Message-headers", belr::make_fn(make_shared)) + ->setCollector("Header", belr::make_sfn(static_cast(&ListHeaderNode::push_back))) + ->setCollector("From-header", belr::make_sfn(static_cast(&ListHeaderNode::push_back))) + ->setCollector("To-header", belr::make_sfn(static_cast(&ListHeaderNode::push_back))) + ->setCollector("DateTime-header", belr::make_sfn(static_cast(&ListHeaderNode::push_back))) + ->setCollector("cc-header", belr::make_sfn(static_cast(&ListHeaderNode::push_back))) + ->setCollector("Subject-header", belr::make_sfn(static_cast(&ListHeaderNode::push_back))) + ->setCollector("NS-header", belr::make_sfn(static_cast(&ListHeaderNode::push_back))) + ->setCollector("Require-header", belr::make_sfn(static_cast(&ListHeaderNode::push_back))); - parser.setHandler( - "Header", belr::make_fn(make_shared ) - )->setCollector( - "Header-name", belr::make_sfn(&HeaderNode::setName) - )->setCollector( - "Header-value", belr::make_sfn(&HeaderNode::setValue) - )->setCollector( - "Header-parameters", belr::make_sfn(&HeaderNode::setParameters) - ); + parser.setHandler("Content-headers", belr::make_fn(make_shared)) + ->setCollector("Header", belr::make_sfn(static_cast(&ListHeaderNode::push_back))); + + parser.setHandler("Header", belr::make_fn(make_shared)) + ->setCollector("Header-name", belr::make_sfn(&HeaderNode::setName)) + ->setCollector("Header-value", belr::make_sfn(&HeaderNode::setValue)) + ->setCollector("Header-parameters", belr::make_sfn(&HeaderNode::setParameters)); + + parser.setHandler("From-header", belr::make_fn(make_shared)) + ->setCollector("Formal-name", belr::make_sfn(&FromHeaderNode::setFormalName)) + ->setCollector("URI", belr::make_sfn(&FromHeaderNode::setUri)); + + parser.setHandler("To-header", belr::make_fn(make_shared)) + ->setCollector("Formal-name", belr::make_sfn(&ToHeaderNode::setFormalName)) + ->setCollector("URI", belr::make_sfn(&ToHeaderNode::setUri)); + + parser.setHandler("cc-header", belr::make_fn(make_shared)) + ->setCollector("Formal-name", belr::make_sfn(&CcHeaderNode::setFormalName)) + ->setCollector("URI", belr::make_sfn(&CcHeaderNode::setUri)); + + parser.setHandler("DateTime-header", belr::make_fn(make_shared)) + ->setCollector("date-fullyear", belr::make_sfn(&DateTimeHeaderNode::setYear)) + ->setCollector("date-month", belr::make_sfn(&DateTimeHeaderNode::setMonth)) + ->setCollector("date-mday", belr::make_sfn(&DateTimeHeaderNode::setMonthDay)) + ->setCollector("time-hour", belr::make_sfn(&DateTimeHeaderNode::setHour)) + ->setCollector("time-minute", belr::make_sfn(&DateTimeHeaderNode::setMinute)) + ->setCollector("time-second", belr::make_sfn(&DateTimeHeaderNode::setSecond)) + ->setCollector("time-offset", belr::make_sfn(&DateTimeHeaderNode::setOffset)); + + parser.setHandler("time-offset", belr::make_fn(make_shared)) + ->setCollector("time-sign", belr::make_sfn(&DateTimeOffsetNode::setSign)) + ->setCollector("time-hour", belr::make_sfn(&DateTimeOffsetNode::setHour)) + ->setCollector("time-minute", belr::make_sfn(&DateTimeOffsetNode::setMinute)); + + parser.setHandler("Subject-header", belr::make_fn(make_shared)) + ->setCollector("Language-tag", belr::make_sfn(&SubjectHeaderNode::setLanguage)) + ->setCollector("Header-value", belr::make_sfn(&SubjectHeaderNode::setSubject)); + + parser.setHandler("Ns-header", belr::make_fn(make_shared)) + ->setCollector("Name-prefix", belr::make_sfn(&NsHeaderNode::setPrefixName)) + ->setCollector("URI", belr::make_sfn(&NsHeaderNode::setUri)); + + parser.setHandler("Require-header", belr::make_fn(make_shared)) + ->setCollector("Require-header-value", belr::make_sfn(&RequireHeaderNode::setHeaderNames)); size_t parsedSize; shared_ptr node = parser.parseInput("Message", input, &parsedSize); @@ -306,149 +689,28 @@ shared_ptr Cpim::Parser::parseMessage (const string &input) { // ----------------------------------------------------------------------------- shared_ptr Cpim::Parser::cloneHeader (const Header &header) { - return HeaderNode(header).createHeader(true); -} + if (header.getName() == "From") + return FromHeaderNode(header).createHeader(); -// ----------------------------------------------------------------------------- + if (header.getName() == "To") + return ToHeaderNode(header).createHeader(); -class EmptyObject {}; + if (header.getName() == "cc") + return CcHeaderNode(header).createHeader(); -static bool headerIsValid (const shared_ptr &grammar, const string &input) { - belr::Parser > parser(grammar); - parser.setHandler( - "Header", belr::make_fn(make_shared ) - ); + if (header.getName() == "DateTime") + return DateTimeHeaderNode(header).createHeader(); - size_t parsedSize; - shared_ptr node = parser.parseInput("Header", input, &parsedSize); - return node && parsedSize == input.length(); -} + if (header.getName() == "Subject") + return SubjectHeaderNode(header).createHeader(); -bool Cpim::Parser::headerNameIsValid (const string &headerName) const { - L_D(); - return headerIsValid(d->grammar, headerName + ": value\r\n"); -} + if (header.getName() == "NS") + return NsHeaderNode(header).createHeader(); -bool Cpim::Parser::headerValueIsValid (const string &headerValue) const { - L_D(); - return headerIsValid(d->grammar, "key: " + headerValue + "\r\n"); -} + if (header.getName() == "Require") + return RequireHeaderNode(header).createHeader(); -bool Cpim::Parser::headerParameterIsValid (const string &headerParameter) const { - L_D(); - return headerIsValid(d->grammar, "key:;" + headerParameter + " value\r\n"); -} - -// ----------------------------------------------------------------------------- - -static bool coreHeaderIsValid ( - const shared_ptr &grammar, - const string &headerName, - const string &headerValue, - const string &headerParams = string() -) { - const string mainRule = headerName + "-header"; - - belr::Parser > parser(grammar); - parser.setHandler( - mainRule, belr::make_fn(make_shared ) - ); - - const string input = headerName + ":" + headerParams + " " + headerValue; - - size_t parsedSize; - shared_ptr node = parser.parseInput(mainRule, input, &parsedSize); - return node && parsedSize == input.length(); -} - -template<> -bool Cpim::Parser::coreHeaderIsValid (const string &headerValue) const { - L_D(); - return LinphonePrivate::coreHeaderIsValid(d->grammar, "From", headerValue); -} - -template<> -bool Cpim::Parser::coreHeaderIsValid (const string &headerValue) const { - L_D(); - return LinphonePrivate::coreHeaderIsValid(d->grammar, "To", headerValue); -} - -template<> -bool Cpim::Parser::coreHeaderIsValid (const string &headerValue) const { - L_D(); - return LinphonePrivate::coreHeaderIsValid(d->grammar, "cc", headerValue); -} - -template<> -bool Cpim::Parser::coreHeaderIsValid (const string &headerValue) const { - static const int daysInMonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - - L_D(); - if (!LinphonePrivate::coreHeaderIsValid(d->grammar, "DateTime", headerValue)) - return false; - - // Check date. - const int year = Utils::stoi(headerValue.substr(0, 4)); - const bool isLeapYear = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0; - - const int month = Utils::stoi(headerValue.substr(5, 2)); - if (month < 1 || month > 12) - return false; - - const int day = Utils::stoi(headerValue.substr(8, 2)); - if (day < 1 || (month == 2 && isLeapYear ? day > 29 : day > daysInMonth[month - 1])) - return false; - - // Check time. - if ( - Utils::stoi(headerValue.substr(11, 2)) > 24 || - Utils::stoi(headerValue.substr(14, 2)) > 59 || - Utils::stoi(headerValue.substr(17, 2)) > 60 - ) - return false; - - // Check num offset. - if (headerValue.back() != 'Z') { - size_t length = headerValue.length(); - if ( - Utils::stoi(headerValue.substr(length - 5, 2)) > 24 || - Utils::stoi(headerValue.substr(length - 2, 2)) > 59 - ) - return false; - } - - return true; -} - -template<> -bool Cpim::Parser::coreHeaderIsValid (const string &headerValue) const { - L_D(); - return LinphonePrivate::coreHeaderIsValid(d->grammar, "Message-ID", headerValue); -} - -template<> -bool Cpim::Parser::coreHeaderIsValid (const string &headerValue) const { - L_D(); - return LinphonePrivate::coreHeaderIsValid(d->grammar, "Subject", headerValue); -} - -template<> -bool Cpim::Parser::coreHeaderIsValid (const string &headerValue) const { - L_D(); - return LinphonePrivate::coreHeaderIsValid(d->grammar, "NS", headerValue); -} - -template<> -bool Cpim::Parser::coreHeaderIsValid (const string &headerValue) const { - L_D(); - return LinphonePrivate::coreHeaderIsValid(d->grammar, "Require", headerValue); -} - -// ----------------------------------------------------------------------------- - -bool Cpim::Parser::subjectHeaderLanguageIsValid (const string &language) const { - L_D(); - return LinphonePrivate::coreHeaderIsValid(d->grammar, "Subject", "SubjectValue", ";lang=" + language); + return HeaderNode(header).createHeader(); } LINPHONE_END_NAMESPACE diff --git a/src/chat/cpim/parser/cpim-parser.h b/src/chat/cpim/parser/cpim-parser.h index 46864274a..076400841 100644 --- a/src/chat/cpim/parser/cpim-parser.h +++ b/src/chat/cpim/parser/cpim-parser.h @@ -38,49 +38,12 @@ namespace Cpim { std::shared_ptr
cloneHeader (const Header &header); - bool headerNameIsValid (const std::string &headerName) const; - bool headerValueIsValid (const std::string &headerValue) const; - bool headerParameterIsValid (const std::string &headerParameter) const; - - template - bool coreHeaderIsValid (const std::string &headerValue) const { - return false; - } - - bool subjectHeaderLanguageIsValid (const std::string &language) const; - private: Parser (); L_DECLARE_PRIVATE(Parser); L_DISABLE_COPY(Parser); }; - - // --------------------------------------------------------------------------- - - template<> - bool Parser::coreHeaderIsValid(const std::string &headerValue) const; - - template<> - bool Parser::coreHeaderIsValid(const std::string &headerValue) const; - - template<> - bool Parser::coreHeaderIsValid(const std::string &headerValue) const; - - template<> - bool Parser::coreHeaderIsValid(const std::string &headerValue) const; - - template<> - bool Parser::coreHeaderIsValid(const std::string &headerValue) const; - - template<> - bool Parser::coreHeaderIsValid(const std::string &headerValue) const; - - template<> - bool Parser::coreHeaderIsValid(const std::string &headerValue) const; - - template<> - bool Parser::coreHeaderIsValid(const std::string &headerValue) const; } LINPHONE_END_NAMESPACE diff --git a/src/chat/cpim/parser/cpim-rules b/src/chat/cpim/parser/cpim-rules index a0b866fee..18c438efc 100644 --- a/src/chat/cpim/parser/cpim-rules +++ b/src/chat/cpim/parser/cpim-rules @@ -1,7 +1,13 @@ -Message = Headers CRLF Headers CRLF [Headers CRLF] +Message = [Crappy-header CRLF] Message-headers CRLF Content-headers CRLF -Headers = *Header -Header = Header-name ":" Header-parameters SP Header-value CRLF +Crappy-header = "Content-Type: Message/CPIM" CRLF + +Message-headers = 1*( Message-header CRLF ) +Message-header = From-header / To-header / DateTime-header / cc-header / Subject-header / NS-header / Require-header / Header + +Content-headers = 1*( Header CRLF ) + +Header = Header-name ":" Header-parameters SP Header-value Header-name = [ Name-prefix "." ] Name Name-prefix = Name @@ -25,13 +31,11 @@ To-header-value = [ Formal-name ] "<" URI ">" DateTime-header = %d68.97.116.101.84.105.109.101 ": " DateTime-header-value DateTime-header-value = date-time -Message-ID-header = %d77.101.115.115.97.103.101.45.73.68 ": " Token - cc-header = %d99.99 ": " cc-header-value cc-header-value = [ Formal-name ] "<" URI ">" Subject-header = %d83.117.98.106.101.99.116 ":" Subject-header-value -Subject-header-value = [ ";" Lang-param ] SP *HEADERCHAR +Subject-header-value = [ ";" Lang-param ] SP Header-value NS-header = %d78.83 ": " NS-header-value NS-header-value = [ Name-prefix SP ] "<" URI ">" @@ -136,7 +140,8 @@ time-minute = 2DIGIT time-second = 2DIGIT time-secfrac = "." 1*DIGIT -time-numoffset = ( "+" / "-" ) time-hour ":" time-minute +time-sign = "+" / "-" +time-numoffset = time-sign time-hour ":" time-minute time-offset = "Z" / time-numoffset partial-time = time-hour ":" time-minute ":" time-second [ time-secfrac ] diff --git a/src/chat/modifier/cpim-chat-message-modifier.cpp b/src/chat/modifier/cpim-chat-message-modifier.cpp index 8958c0f82..d4853bf2d 100644 --- a/src/chat/modifier/cpim-chat-message-modifier.cpp +++ b/src/chat/modifier/cpim-chat-message-modifier.cpp @@ -17,11 +17,14 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include "linphone/utils/utils.h" + #include "address/address.h" #include "chat/chat-message/chat-message-p.h" #include "chat/cpim/cpim.h" -#include "content/content-type.h" #include "content/content.h" +#include "content/content-disposition.h" +#include "content/content-type.h" #include "logger/logger.h" #include "cpim-chat-message-modifier.h" @@ -35,25 +38,44 @@ LINPHONE_BEGIN_NAMESPACE ChatMessageModifier::Result CpimChatMessageModifier::encode (const shared_ptr &message, int &errorCode) { Cpim::Message cpimMessage; - // TODO: Remove this buggy Content-Type header - Cpim::GenericHeader cpimContentTypeHeader; - cpimContentTypeHeader.setName("Content-Type"); - cpimContentTypeHeader.setValue(ContentType::Cpim.asString()); - cpimMessage.addCpimHeader(cpimContentTypeHeader); - // TODO: Remove this buggy Content-Type header + cpimMessage.addMessageHeader( + Cpim::FromHeader(cpimAddressUri(message->getFromAddress()), cpimAddressDisplayName(message->getFromAddress())) + ); + cpimMessage.addMessageHeader( + Cpim::ToHeader(cpimAddressUri(message->getToAddress()), cpimAddressDisplayName(message->getToAddress())) + ); + cpimMessage.addMessageHeader( + Cpim::DateTimeHeader(message->getTime()) + ); - Cpim::FromHeader cpimFromHeader; - cpimFromHeader.setValue(cpimAddressAsString(message->getFromAddress())); - cpimMessage.addMessageHeader(cpimFromHeader); - Cpim::ToHeader cpimToHeader; - cpimToHeader.setValue(cpimAddressAsString(message->getToAddress())); - cpimMessage.addMessageHeader(cpimToHeader); - char token[13]; - belle_sip_random_token(token, sizeof(token)); - Cpim::MessageIdHeader cpimMessageIdHeader; - cpimMessageIdHeader.setValue(token); - cpimMessage.addMessageHeader(cpimMessageIdHeader); - message->getPrivate()->setImdnMessageId(token); + if (message->getPrivate()->getPositiveDeliveryNotificationRequired() + || message->getPrivate()->getNegativeDeliveryNotificationRequired() + || message->getPrivate()->getDisplayNotificationRequired() + ) { + const string imdnNamespace = "imdn"; + cpimMessage.addMessageHeader(Cpim::NsHeader("urn:ietf:params:imdn", imdnNamespace)); + + char token[13]; + belle_sip_random_token(token, sizeof(token)); + cpimMessage.addMessageHeader( + Cpim::GenericHeader("Message-ID", token) // TODO: Replace by imdnNamespace + ".Message-ID"); + ); + message->getPrivate()->setImdnMessageId(token); + + vector dispositionNotificationValues; + if (message->getPrivate()->getPositiveDeliveryNotificationRequired()) + dispositionNotificationValues.emplace_back("positive-delivery"); + if (message->getPrivate()->getNegativeDeliveryNotificationRequired()) + dispositionNotificationValues.emplace_back("negative-delivery"); + if (message->getPrivate()->getDisplayNotificationRequired()) + dispositionNotificationValues.emplace_back("display"); + cpimMessage.addMessageHeader( + Cpim::GenericHeader( + imdnNamespace + ".Disposition-Notification", + Utils::join(dispositionNotificationValues, ", ") + ) + ); + } const Content *content; if (!message->getInternalContent().isEmpty()) { @@ -66,21 +88,19 @@ ChatMessageModifier::Result CpimChatMessageModifier::encode (const shared_ptrgetContents().front(); } - Cpim::GenericHeader contentTypeHeader; - contentTypeHeader.setName("Content-Type"); - contentTypeHeader.setValue(content->getContentType().asString()); - cpimMessage.addContentHeader(contentTypeHeader); - const string contentBody = content->getBodyAsString(); - cpimMessage.setContent(contentBody); - - // TODO: Remove this check because of buggy Content-Type header - if (!cpimMessage.isValid()) { - lError() << "[CPIM] Message is invalid: " << contentBody; - errorCode = 500; - return ChatMessageModifier::Result::Error; + if (content->getContentDisposition().isValid()) { + cpimMessage.addContentHeader( + Cpim::GenericHeader("Content-Disposition", content->getContentDisposition().asString()) + ); } - // TODO: Remove this check because of buggy Content-Type header + cpimMessage.addContentHeader( + Cpim::GenericHeader("Content-Type", content->getContentType().asString()) + ); + cpimMessage.addContentHeader( + Cpim::GenericHeader("Content-Length", to_string(contentBody.size())) + ); + cpimMessage.setContent(contentBody); Content newContent; newContent.setContentType(ContentType::Cpim); @@ -98,50 +118,75 @@ ChatMessageModifier::Result CpimChatMessageModifier::decode (const shared_ptrgetContents().front(); if (content->getContentType() != ContentType::Cpim) { - lError() << "[CPIM] Message is not CPIM but " << content->getContentType().asString(); + lError() << "[CPIM] Message is not CPIM but " << content->getContentType(); return ChatMessageModifier::Result::Skipped; } const string contentBody = content->getBodyAsString(); const shared_ptr cpimMessage = Cpim::Message::createFromString(contentBody); - if (!cpimMessage) { + if (!cpimMessage || !cpimMessage->getMessageHeader("From") || !cpimMessage->getMessageHeader("To")) { lError() << "[CPIM] Message is invalid: " << contentBody; - errorCode = 500; + errorCode = 488; // Not Acceptable return ChatMessageModifier::Result::Error; } Content newContent; - bool contentTypeFound = false; - Cpim::Message::HeaderList l = cpimMessage->getContentHeaders(); - if (l) { - for (const auto &header : *l.get()) { - if (header->getName() == "Content-Type") { - contentTypeFound = true; - newContent.setContentType(ContentType(header->getValue())); + auto contentTypeHeader = cpimMessage->getContentHeader("Content-Type"); + if (!contentTypeHeader) { + lError() << "[CPIM] No Content-type for the content of the message"; + errorCode = 488; // Not Acceptable + return ChatMessageModifier::Result::Error; + } + newContent.setContentType(ContentType(contentTypeHeader->getValue())); + auto contentDispositionHeader = cpimMessage->getContentHeader("Content-Disposition"); + if (contentDispositionHeader) + newContent.setContentDisposition(ContentDisposition(contentDispositionHeader->getValue())); + newContent.setBody(cpimMessage->getContent()); + + message->getPrivate()->setPositiveDeliveryNotificationRequired(false); + message->getPrivate()->setNegativeDeliveryNotificationRequired(false); + message->getPrivate()->setDisplayNotificationRequired(false); + + string imdnNamespace = ""; + auto messageHeaders = cpimMessage->getMessageHeaders(); + if (messageHeaders) { + for (const auto &header : *messageHeaders.get()) { + if (header->getName() != "NS") + continue; + auto nsHeader = static_pointer_cast(header); + if (nsHeader->getUri() == "urn:ietf:params:imdn") { + imdnNamespace = nsHeader->getPrefixName(); break; } } } - if (!contentTypeFound) { - lError() << "[CPIM] No Content-type for the content of the message"; - errorCode = 500; - return ChatMessageModifier::Result::Error; - } - newContent.setBody(cpimMessage->getContent()); - Address cpimFromAddress; - Address cpimToAddress; - l = cpimMessage->getMessageHeaders(); - if (l) { - for (const auto &header : *l.get()) { - if (header->getName() == "From") - cpimFromAddress = Address(header->getValue()); - else if (header->getName() == "To") - cpimToAddress = Address(header->getValue()); - else if (header->getName() == "Message-ID") - message->getPrivate()->setImdnMessageId(header->getValue()); + auto fromHeader = static_pointer_cast(cpimMessage->getMessageHeader("From")); + Address cpimFromAddress(fromHeader->getValue()); + auto toHeader = static_pointer_cast(cpimMessage->getMessageHeader("To")); + Address cpimToAddress(toHeader->getValue()); + auto dateTimeHeader = static_pointer_cast(cpimMessage->getMessageHeader("DateTime")); + if (dateTimeHeader) + message->getPrivate()->setTime(dateTimeHeader->getTime()); + + auto messageIdHeader = cpimMessage->getMessageHeader("Message-ID"); // TODO: For compatibility, to remove + if (!imdnNamespace.empty()) { + if (!messageIdHeader) + messageIdHeader = cpimMessage->getMessageHeader("Message-ID", imdnNamespace); + auto dispositionNotificationHeader = cpimMessage->getMessageHeader("Disposition-Notification", imdnNamespace); + if (dispositionNotificationHeader) { + vector values = Utils::split(dispositionNotificationHeader->getValue(), ", "); + for (const auto &value : values) + if (value == "positive-delivery") + message->getPrivate()->setPositiveDeliveryNotificationRequired(true); + else if (value == "negative-delivery") + message->getPrivate()->setNegativeDeliveryNotificationRequired(true); + else if (value == "display") + message->getPrivate()->setDisplayNotificationRequired(true); } } + if (messageIdHeader) + message->getPrivate()->setImdnMessageId(messageIdHeader->getValue()); // Modify the initial message since there was no error message->setInternalContent(newContent); @@ -151,12 +196,12 @@ ChatMessageModifier::Result CpimChatMessageModifier::decode (const shared_ptr"; - return os.str(); +string CpimChatMessageModifier::cpimAddressDisplayName (const Address &addr) const { + return addr.getDisplayName(); +} + +string CpimChatMessageModifier::cpimAddressUri (const Address &addr) const { + return addr.asStringUriOnly(); } LINPHONE_END_NAMESPACE diff --git a/src/chat/modifier/cpim-chat-message-modifier.h b/src/chat/modifier/cpim-chat-message-modifier.h index ab63c74e6..04dab858a 100644 --- a/src/chat/modifier/cpim-chat-message-modifier.h +++ b/src/chat/modifier/cpim-chat-message-modifier.h @@ -34,7 +34,8 @@ public: Result decode (const std::shared_ptr &message, int &errorCode) override; private: - std::string cpimAddressAsString (const Address &addr) const; + std::string cpimAddressDisplayName (const Address &addr) const; + std::string cpimAddressUri (const Address &addr) const; }; LINPHONE_END_NAMESPACE diff --git a/src/chat/modifier/file-transfer-chat-message-modifier.cpp b/src/chat/modifier/file-transfer-chat-message-modifier.cpp index d9d0767b2..c3001231a 100644 --- a/src/chat/modifier/file-transfer-chat-message-modifier.cpp +++ b/src/chat/modifier/file-transfer-chat-message-modifier.cpp @@ -17,15 +17,17 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "c-wrapper/c-wrapper.h" +#include "linphone/api/c-content.h" + #include "address/address.h" +#include "bctoolbox/crypto.h" +#include "c-wrapper/c-wrapper.h" #include "chat/chat-message/chat-message-p.h" +#include "chat/chat-room/chat-room-p.h" #include "content/content-type.h" #include "content/content.h" -#include "chat/chat-room/chat-room-p.h" #include "core/core.h" #include "logger/logger.h" -#include "bctoolbox/crypto.h" #include "file-transfer-chat-message-modifier.h" @@ -107,14 +109,13 @@ void FileTransferChatMessageModifier::fileTransferOnProgress ( LinphoneChatMessage *msg = L_GET_C_BACK_PTR(message); LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg); - LinphoneContent *content = currentFileContentToTransfer->toLinphoneContent(); + LinphoneContent *content = L_GET_C_BACK_PTR((Content *)currentFileContentToTransfer); if (linphone_chat_message_cbs_get_file_transfer_progress_indication(cbs)) { linphone_chat_message_cbs_get_file_transfer_progress_indication(cbs)(msg, content, offset, total); } else { // Legacy: call back given by application level. linphone_core_notify_file_transfer_progress_indication(message->getCore()->getCCore(), msg, content, offset, total); } - linphone_content_unref(content); } static int _chat_message_on_send_body ( @@ -157,7 +158,7 @@ int FileTransferChatMessageModifier::onSendBody ( LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg); LinphoneChatMessageCbsFileTransferSendCb file_transfer_send_cb = linphone_chat_message_cbs_get_file_transfer_send(cbs); - LinphoneContent *content = currentFileContentToTransfer->toLinphoneContent(); + LinphoneContent *content = L_GET_C_BACK_PTR((Content *)currentFileContentToTransfer); if (file_transfer_send_cb) { LinphoneBuffer *lb = file_transfer_send_cb(msg, content, offset, *size); if (lb) { @@ -171,7 +172,6 @@ int FileTransferChatMessageModifier::onSendBody ( // Legacy linphone_core_notify_file_transfer_send(message->getCore()->getCCore(), msg, content, (char *)buffer, size); } - linphone_content_unref(content); } LinphoneImEncryptionEngine *imee = linphone_core_get_im_encryption_engine(message->getCore()->getCCore()); @@ -241,28 +241,35 @@ void FileTransferChatMessageModifier::processResponseFromPostFile (const belle_h string first_part_header; belle_sip_body_handler_t *first_part_bh; - bool_t is_file_encryption_enabled = FALSE; + bool is_file_encryption_enabled = false; LinphoneImEncryptionEngine *imee = linphone_core_get_im_encryption_engine(message->getCore()->getCCore()); if (imee && message->getChatRoom()) { LinphoneImEncryptionEngineCbs *imee_cbs = linphone_im_encryption_engine_get_callbacks(imee); LinphoneImEncryptionEngineCbsIsEncryptionEnabledForFileTransferCb is_encryption_enabled_for_file_transfer_cb = linphone_im_encryption_engine_cbs_get_is_encryption_enabled_for_file_transfer(imee_cbs); if (is_encryption_enabled_for_file_transfer_cb) { - is_file_encryption_enabled = is_encryption_enabled_for_file_transfer_cb(imee, L_GET_C_BACK_PTR(message->getChatRoom())); + is_file_encryption_enabled = !!is_encryption_enabled_for_file_transfer_cb(imee, L_GET_C_BACK_PTR(message->getChatRoom())); } } + + FileTransferContent *fileTransferContent = new FileTransferContent(); + fileTransferContent->setContentType(ContentType::FileTransfer); + fileTransferContent->setFileSize(currentFileContentToTransfer->getFileSize()); // Copy file size information + message->getPrivate()->addContent(fileTransferContent); + // shall we encrypt the file if (is_file_encryption_enabled && message->getChatRoom()) { + // temporary storage for the Content-disposition header value : use a generic filename to not leak it + // Actual filename stored in msg->file_transfer_information->name will be set in encrypted msg + // sended to the + first_part_header = "form-data; name=\"File\"; filename=\"filename.txt\""; + LinphoneImEncryptionEngineCbs *imee_cbs = linphone_im_encryption_engine_get_callbacks(imee); LinphoneImEncryptionEngineCbsGenerateFileTransferKeyCb generate_file_transfer_key_cb = linphone_im_encryption_engine_cbs_get_generate_file_transfer_key(imee_cbs); if (generate_file_transfer_key_cb) { generate_file_transfer_key_cb(imee, L_GET_C_BACK_PTR(message->getChatRoom()), L_GET_C_BACK_PTR(message)); } - // temporary storage for the Content-disposition header value : use a generic filename to not leak it - // Actual filename stored in msg->file_transfer_information->name will be set in encrypted msg - // sended to the - first_part_header = "form-data; name=\"File\"; filename=\"filename.txt\""; } else { // temporary storage for the Content-disposition header value first_part_header = "form-data; name=\"File\"; filename=\"" + currentFileContentToTransfer->getFileName() + "\""; @@ -277,6 +284,8 @@ void FileTransferChatMessageModifier::processResponseFromPostFile (const belle_h // No need to add again the callback for progression, otherwise it will be called twice first_part_bh = (belle_sip_body_handler_t *)belle_sip_file_body_handler_new(currentFileContentToTransfer->getFilePath().c_str(), nullptr, this); belle_sip_file_body_handler_set_user_body_handler((belle_sip_file_body_handler_t *)first_part_bh, body_handler); + // Ensure the file size has been set to the correct value + fileTransferContent->setFileSize(belle_sip_file_body_handler_get_file_size((belle_sip_file_body_handler_t *)first_part_bh)); } else if (!currentFileContentToTransfer->isEmpty()) { first_part_bh = (belle_sip_body_handler_t *)belle_sip_memory_body_handler_new_from_buffer( ms_strdup(currentFileContentToTransfer->getBodyAsString().c_str()), @@ -298,12 +307,25 @@ void FileTransferChatMessageModifier::processResponseFromPostFile (const belle_h uploadFile(); belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(httpRequest), BELLE_SIP_BODY_HANDLER(bh)); } else if (code == 200) { // file has been uploaded correctly, get server reply and send it + FileTransferContent *fileTransferContent = nullptr; + for (Content *c : message->getPrivate()->getContents()) { + if (c->isFileTransfer()) { + FileTransferContent *tmpContent = static_cast(c); + if (!tmpContent->getFileContent() && tmpContent->getSize() == 0) { + // If FileTransferContent doesn't have a FileContent yet and is empty + // It's the one we seek, otherwise it may be a previous uploaded FileTransferContent + fileTransferContent = tmpContent; + break; + } + } + } + const char *body = belle_sip_message_get_body((belle_sip_message_t *)event->response); if (body && strlen(body) > 0) { - FileTransferContent *fileTransferContent = new FileTransferContent(); // if we have an encryption key for the file, we must insert it into the msg and restore the correct filename - string content_key = currentFileContentToTransfer->getFileKey(); - if (!content_key.empty()) { + const unsigned char *contentKey = reinterpret_cast(fileTransferContent->getFileKey().data()); + size_t contentKeySize = fileTransferContent->getFileKeySize(); + if (contentKeySize > 0) { // parse the msg body xmlDocPtr xmlMessageBody = xmlParseDoc((const xmlChar *)body); @@ -316,16 +338,15 @@ void FileTransferChatMessageModifier::processResponseFromPostFile (const belle_h xmlChar *typeAttribute = xmlGetProp(cur, (const xmlChar *)"type"); // this is the node we are looking for : add a file-key children node if (!xmlStrcmp(typeAttribute, (const xmlChar *)"file")) { - size_t content_key_size = content_key.length(); // need to parse the children node to update the file-name one xmlNodePtr fileInfoNodeChildren = cur->xmlChildrenNode; // convert key to base64 size_t b64Size; - bctbx_base64_encode(nullptr, &b64Size, (unsigned char *)content_key.c_str(), content_key_size); + bctbx_base64_encode(nullptr, &b64Size, contentKey, contentKeySize); unsigned char *keyb64 = (unsigned char *)ms_malloc0(b64Size + 1); int xmlStringLength; - bctbx_base64_encode(keyb64, &b64Size, (unsigned char *)content_key.c_str(), content_key_size); + bctbx_base64_encode(keyb64, &b64Size, contentKey, contentKeySize); keyb64[b64Size] = '\0'; // libxml need a null terminated string // add the node containing the key to the file-info node @@ -361,11 +382,9 @@ void FileTransferChatMessageModifier::processResponseFromPostFile (const belle_h } FileContent *fileContent = currentFileContentToTransfer; - fileTransferContent->setContentType(ContentType::FileTransfer); fileTransferContent->setFileContent(fileContent); - message->getPrivate()->removeContent(*fileContent); - message->getPrivate()->addContent(*fileTransferContent); + message->getPrivate()->removeContent(fileContent); message->getPrivate()->setState(ChatMessage::State::FileTransferDone); releaseHttpRequest(); @@ -373,17 +392,44 @@ void FileTransferChatMessageModifier::processResponseFromPostFile (const belle_h fileUploadEndBackgroundTask(); } else { lWarning() << "Received empty response from server, file transfer failed"; + FileTransferContent *fileTransferContent = nullptr; + for (Content *c : message->getPrivate()->getContents()) { + if (c->isFileTransfer()) { + fileTransferContent = static_cast(c); + message->getPrivate()->removeContent(fileTransferContent); + delete fileTransferContent; + break; + } + } message->getPrivate()->setState(ChatMessage::State::NotDelivered); releaseHttpRequest(); fileUploadEndBackgroundTask(); } } else if (code == 400) { lWarning() << "Received HTTP code response " << code << " for file transfer, probably meaning file is too large"; + FileTransferContent *fileTransferContent = nullptr; + for (Content *c : message->getPrivate()->getContents()) { + if (c->isFileTransfer()) { + fileTransferContent = static_cast(c); + message->getPrivate()->removeContent(fileTransferContent); + delete fileTransferContent; + break; + } + } message->getPrivate()->setState(ChatMessage::State::FileTransferError); releaseHttpRequest(); fileUploadEndBackgroundTask(); } else { lWarning() << "Unhandled HTTP code response " << code << " for file transfer"; + FileTransferContent *fileTransferContent = nullptr; + for (Content *c : message->getPrivate()->getContents()) { + if (c->isFileTransfer()) { + fileTransferContent = static_cast(c); + message->getPrivate()->removeContent(fileTransferContent); + delete fileTransferContent; + break; + } + } message->getPrivate()->setState(ChatMessage::State::NotDelivered); releaseHttpRequest(); fileUploadEndBackgroundTask(); @@ -500,7 +546,7 @@ void FileTransferChatMessageModifier::fileUploadEndBackgroundTask () { // ---------------------------------------------------------- -static void fillFileTransferContentInformationsFromVndGsmaRcsFtHttpXml(FileTransferContent *fileTransferContent) { +static void fillFileTransferContentInformationsFromVndGsmaRcsFtHttpXml (FileTransferContent *fileTransferContent) { xmlChar *fileUrl = nullptr; xmlDocPtr xmlMessageBody; xmlNodePtr cur; @@ -523,7 +569,6 @@ static void fillFileTransferContentInformationsFromVndGsmaRcsFtHttpXml(FileTrans fileTransferContent->setFileSize(size); xmlFree(fileSizeString); } - if (!xmlStrcmp(cur->name, (const xmlChar *)"file-name")) { xmlChar *filename = xmlNodeListGetString(xmlMessageBody, cur->xmlChildrenNode, 1); fileTransferContent->setFileName((char *)filename); @@ -532,6 +577,20 @@ static void fillFileTransferContentInformationsFromVndGsmaRcsFtHttpXml(FileTrans if (!xmlStrcmp(cur->name, (const xmlChar *)"data")) { fileUrl = xmlGetProp(cur, (const xmlChar *)"url"); } + if (!xmlStrcmp(cur->name, (const xmlChar *)"file-key")) { + // there is a key in the msg: file has been encrypted + // convert the key from base 64 + xmlChar *keyb64 = xmlNodeListGetString(xmlMessageBody, cur->xmlChildrenNode, 1); + size_t keyLength; + bctbx_base64_decode(NULL, &keyLength, (unsigned char *)keyb64, strlen((const char *)keyb64)); + uint8_t *keyBuffer = (uint8_t *)malloc(keyLength); + // decode the key into local key buffer + bctbx_base64_decode(keyBuffer, &keyLength, (unsigned char *)keyb64, strlen((const char *)keyb64)); + fileTransferContent->setFileKey((const char *)keyBuffer, keyLength); + // duplicate key value into the linphone content private structure + xmlFree(keyb64); + free(keyBuffer); + } cur = cur->next; } @@ -559,13 +618,13 @@ ChatMessageModifier::Result FileTransferChatMessageModifier::decode (const share fileTransferContent->setContentType(internalContent.getContentType()); fileTransferContent->setBody(internalContent.getBody()); fillFileTransferContentInformationsFromVndGsmaRcsFtHttpXml(fileTransferContent); - message->addContent(*fileTransferContent); + message->addContent(fileTransferContent); return ChatMessageModifier::Result::Done; } for (Content *content : message->getContents()) { - if (content->getContentType() == ContentType::FileTransfer) { - FileTransferContent *fileTransferContent = (FileTransferContent *)content; + if (content->isFileTransfer()) { + FileTransferContent *fileTransferContent = static_cast(content); fillFileTransferContentInformationsFromVndGsmaRcsFtHttpXml(fileTransferContent); } } @@ -634,8 +693,7 @@ static void createFileTransferInformationsFromVndGsmaRcsFtHttpXml (FileTransferC uint8_t *keyBuffer = (uint8_t *)malloc(keyLength); // decode the key into local key buffer bctbx_base64_decode(keyBuffer, &keyLength, (unsigned char *)keyb64, strlen((const char *)keyb64)); - string key = string((const char *)keyBuffer); - fileContent->setFileKey(key); + fileTransferContent->setFileKey((const char *)keyBuffer, keyLength); // duplicate key value into the linphone content private structure xmlFree(keyb64); free(keyBuffer); @@ -699,7 +757,7 @@ void FileTransferChatMessageModifier::onRecvBody (belle_sip_user_body_handler_t if (currentFileContentToTransfer->getFilePath().empty()) { LinphoneChatMessage *msg = L_GET_C_BACK_PTR(message); LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg); - LinphoneContent *content = currentFileContentToTransfer->toLinphoneContent(); + LinphoneContent *content = L_GET_C_BACK_PTR((Content *)currentFileContentToTransfer); if (linphone_chat_message_cbs_get_file_transfer_recv(cbs)) { LinphoneBuffer *lb = linphone_buffer_new_from_data(buffer, size); linphone_chat_message_cbs_get_file_transfer_recv(cbs)(msg, content, lb); @@ -708,7 +766,6 @@ void FileTransferChatMessageModifier::onRecvBody (belle_sip_user_body_handler_t // Legacy: call back given by application level linphone_core_notify_file_transfer_recv(message->getCore()->getCCore(), msg, content, (const char *)buffer, size); } - linphone_content_unref(content); } } else { lWarning() << "File transfer decrypt failed with code " << (int)retval; @@ -740,7 +797,7 @@ void FileTransferChatMessageModifier::onRecvEnd (belle_sip_user_body_handler_t * if (currentFileContentToTransfer->getFilePath().empty()) { LinphoneChatMessage *msg = L_GET_C_BACK_PTR(message); LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg); - LinphoneContent *content = currentFileContentToTransfer->toLinphoneContent(); + LinphoneContent *content = L_GET_C_BACK_PTR((Content *)currentFileContentToTransfer); if (linphone_chat_message_cbs_get_file_transfer_recv(cbs)) { LinphoneBuffer *lb = linphone_buffer_new(); linphone_chat_message_cbs_get_file_transfer_recv(cbs)(msg, content, lb); @@ -749,19 +806,18 @@ void FileTransferChatMessageModifier::onRecvEnd (belle_sip_user_body_handler_t * // Legacy: call back given by application level linphone_core_notify_file_transfer_recv(message->getCore()->getCCore(), msg, content, nullptr, 0); } - linphone_content_unref(content); } } if (retval <= 0 && message->getState() != ChatMessage::State::FileTransferError) { // Remove the FileTransferContent from the message and store the FileContent FileContent *fileContent = currentFileContentToTransfer; - message->getPrivate()->addContent(*fileContent); + message->getPrivate()->addContent(fileContent); for (Content *content : message->getContents()) { - if (content->getContentType() == ContentType::FileTransfer) { - FileTransferContent *fileTransferContent = (FileTransferContent*)content; + if (content->isFileTransfer()) { + FileTransferContent *fileTransferContent = static_cast(content); if (fileTransferContent->getFileContent() == fileContent) { - message->getPrivate()->removeContent(*content); + message->getPrivate()->removeContent(content); delete fileTransferContent; break; } @@ -814,7 +870,7 @@ void FileTransferChatMessageModifier::processResponseHeadersFromGetFile (const b } else { lWarning() << "No file transfer information for msg [" << this << "]: creating..."; FileContent *content = createFileTransferInformationFromHeaders(response); - message->addContent(*content); + message->addContent(content); } size_t body_size = 0; @@ -891,24 +947,27 @@ void FileTransferChatMessageModifier::processResponseFromGetFile (const belle_ht } } -int FileTransferChatMessageModifier::downloadFile(const shared_ptr &message, FileTransferContent *fileTransferContent) { +bool FileTransferChatMessageModifier::downloadFile ( + const shared_ptr &message, + FileTransferContent *fileTransferContent +) { chatMessage = message; if (httpRequest) { - lError() << "linphone_chat_message_download_file(): there is already a download in progress"; - return -1; + lError() << "There is already a download in progress."; + return false; } if (fileTransferContent->getContentType() != ContentType::FileTransfer) { - lError() << "linphone_chat_message_download_file(): content type is not FileTransfer"; - return -1; + lError() << "Content type is not a FileTransfer."; + return false; } createFileTransferInformationsFromVndGsmaRcsFtHttpXml(fileTransferContent); FileContent *fileContent = fileTransferContent->getFileContent(); currentFileContentToTransfer = fileContent; if (!currentFileContentToTransfer) - return -1; + return false; // THIS IS ONLY FOR BACKWARD C API COMPAT if (currentFileContentToTransfer->getFilePath().empty() && !message->getPrivate()->getFileTransferFilepath().empty()) { @@ -922,10 +981,10 @@ int FileTransferChatMessageModifier::downloadFile(const shared_ptr cbs.process_auth_requested = _chat_message_process_auth_requested_download; int err = startHttpTransfer(fileTransferContent->getFileUrl(), "GET", &cbs); // File URL has been set by createFileTransferInformationsFromVndGsmaRcsFtHttpXml if (err == -1) - return -1; + return false; // start the download, status is In Progress message->getPrivate()->setState(ChatMessage::State::InProgress); - return 0; + return true; } // ---------------------------------------------------------- @@ -944,7 +1003,7 @@ void FileTransferChatMessageModifier::cancelFileTransfer () { ? L_C_TO_STRING(linphone_core_get_file_transfer_server(message->getCore()->getCCore())) : currentFileContentToTransfer->getFilePath().c_str() ); - + } else { lInfo() << "Warning: http request still running for ORPHAN msg: this is a memory leak"; } @@ -968,7 +1027,7 @@ void FileTransferChatMessageModifier::releaseHttpRequest () { } } -string FileTransferChatMessageModifier::createFakeFileTransferFromUrl(const string &url) { +string FileTransferChatMessageModifier::createFakeFileTransferFromUrl (const string &url) { string fileName = url.substr(url.find_last_of("/") + 1); stringstream fakeXml; fakeXml << "\r\n"; diff --git a/src/chat/modifier/file-transfer-chat-message-modifier.h b/src/chat/modifier/file-transfer-chat-message-modifier.h index d6d9af736..d2dde9b7d 100644 --- a/src/chat/modifier/file-transfer-chat-message-modifier.h +++ b/src/chat/modifier/file-transfer-chat-message-modifier.h @@ -53,28 +53,28 @@ public: void processIoErrorUpload (const belle_sip_io_error_event_t *event); void processAuthRequestedUpload (const belle_sip_auth_event *event); - void onRecvBody(belle_sip_user_body_handler_t *bh, belle_sip_message_t *m, size_t offset, uint8_t *buffer, size_t size); - void onRecvEnd(belle_sip_user_body_handler_t *bh); - void processResponseHeadersFromGetFile(const belle_http_response_event_t *event); - void processAuthRequestedDownload(const belle_sip_auth_event *event); - void processIoErrorDownload(const belle_sip_io_error_event_t *event); - void processResponseFromGetFile(const belle_http_response_event_t *event); + void onRecvBody (belle_sip_user_body_handler_t *bh, belle_sip_message_t *m, size_t offset, uint8_t *buffer, size_t size); + void onRecvEnd (belle_sip_user_body_handler_t *bh); + void processResponseHeadersFromGetFile (const belle_http_response_event_t *event); + void processAuthRequestedDownload (const belle_sip_auth_event *event); + void processIoErrorDownload (const belle_sip_io_error_event_t *event); + void processResponseFromGetFile (const belle_http_response_event_t *event); - int downloadFile(const std::shared_ptr &message, FileTransferContent *fileTransferContent); - void cancelFileTransfer(); - bool isFileTransferInProgressAndValid(); - std::string createFakeFileTransferFromUrl(const std::string &url); + bool downloadFile (const std::shared_ptr &message, FileTransferContent *fileTransferContent); + void cancelFileTransfer (); + bool isFileTransferInProgressAndValid (); + std::string createFakeFileTransferFromUrl (const std::string &url); private: - int uploadFile(); - int startHttpTransfer(const std::string &url, const std::string &action, belle_http_request_listener_callbacks_t *cbs); - void fileUploadBeginBackgroundTask(); - void fileUploadEndBackgroundTask(); + int uploadFile (); + int startHttpTransfer (const std::string &url, const std::string &action, belle_http_request_listener_callbacks_t *cbs); + void fileUploadBeginBackgroundTask (); + void fileUploadEndBackgroundTask (); - void releaseHttpRequest(); + void releaseHttpRequest (); std::weak_ptr chatMessage; - FileContent* currentFileContentToTransfer; + FileContent* currentFileContentToTransfer = nullptr; belle_http_request_t *httpRequest = nullptr; belle_http_request_listener_t *httpListener = nullptr; diff --git a/src/chat/modifier/multipart-chat-message-modifier.cpp b/src/chat/modifier/multipart-chat-message-modifier.cpp index 243cb32e1..8ed8312d9 100644 --- a/src/chat/modifier/multipart-chat-message-modifier.cpp +++ b/src/chat/modifier/multipart-chat-message-modifier.cpp @@ -20,13 +20,11 @@ // TODO: Remove me later. #include "private.h" -#include "address/address.h" #include "chat/chat-message/chat-message.h" -#include "chat/chat-room/chat-room.h" #include "content/content-type.h" +#include "content/header/header.h" +#include "content/content-manager.h" #include "content/file-transfer-content.h" -#include "logger/logger.h" -#include "core/core.h" #include "multipart-chat-message-modifier.h" @@ -43,90 +41,30 @@ ChatMessageModifier::Result MultipartChatMessageModifier::encode ( if (message->getContents().size() <= 1) return ChatMessageModifier::Result::Skipped; - LinphoneCore *lc = message->getChatRoom()->getCore()->getCCore(); - char tmp[64]; - lc->sal->create_uuid(tmp, sizeof(tmp)); - string boundary = tmp; - stringstream multipartMessage; - - multipartMessage << "--" << boundary; - for (Content *content : message->getContents()) { - multipartMessage << "\r\n"; - multipartMessage << "Content-Type: " << content->getContentType().asString() << "\r\n\r\n"; - multipartMessage << content->getBodyAsString() << "\r\n\r\n"; - multipartMessage << "--" << boundary; - } - multipartMessage << "--"; - - Content newContent; - ContentType newContentType(ContentType::Multipart); - newContentType.setParameter("boundary=" + boundary); - newContent.setContentType(newContentType); - newContent.setBody(multipartMessage.str()); - message->setInternalContent(newContent); + Content content = ContentManager::contentListToMultipart(message->getContents()); + message->setInternalContent(content); return ChatMessageModifier::Result::Done; } ChatMessageModifier::Result MultipartChatMessageModifier::decode (const shared_ptr &message, int &errorCode) { - if (message->getInternalContent().getContentType().getType() == "multipart") { - string boundary = message->getInternalContent().getContentType().getParameter(); - if (boundary.empty()) { - lError() << "Boundary parameter of content-type not found: " << message->getInternalContent().getContentType().asString(); - return ChatMessageModifier::Result::Error; - } - - size_t pos = boundary.find("="); - if (pos == string::npos) { - lError() << "Parameter seems invalid: " << boundary; - return ChatMessageModifier::Result::Error; - } - boundary = "--" + boundary.substr(pos + 1); - lInfo() << "Multipart boundary is " << boundary; - - const vector body = message->getInternalContent().getBody(); - string contentsString(body.begin(), body.end()); - - pos = contentsString.find(boundary); - if (pos == string::npos) { - lError() << "Boundary not found in body !"; - return ChatMessageModifier::Result::Error; - } - - size_t start = pos + boundary.length() + 2; // 2 is the size of \r\n - size_t end; - do { - end = contentsString.find(boundary, start); - if (end != string::npos) { - string contentString = contentsString.substr(start, end - start); - - size_t contentTypePos = contentString.find(": ") + 2; // 2 is the size of : - size_t endOfLinePos = contentString.find("\r\n"); - if (contentTypePos >= endOfLinePos) { - lError() << "Content should start by a 'Content-Type: ' line !"; - continue; + if (message->getInternalContent().getContentType().isMultipart()) { + for (Content &c : ContentManager::multipartToContentList(message->getInternalContent())) { + Content *content; + if (c.getContentType() == ContentType::FileTransfer) { + content = new FileTransferContent(); + content->setContentType(c.getContentType()); + content->setContentDisposition(c.getContentDisposition()); + content->setContentEncoding(c.getContentEncoding()); + for (const Header &header : c.getHeaders()) { + content->addHeader(header); } - string contentTypeString = contentString.substr(contentTypePos, endOfLinePos - contentTypePos); - ContentType contentType(contentTypeString); - - endOfLinePos += 4; // 4 is two time the size of \r\n - string contentBody = contentString.substr(endOfLinePos, contentString.length() - (endOfLinePos + 4)); // 4 is two time the size of \r\n - - Content *content; - if (contentType == ContentType::FileTransfer) { - content = new FileTransferContent(); - } else { - content = new Content(); - } - content->setContentType(contentType); - content->setBody(contentBody); - message->addContent(*content); - - lInfo() << "Parsed and added content with type " << contentType.asString(); + content->setBodyFromUtf8(c.getBodyAsUtf8String()); + } else { + content = new Content(c); } - start = end + boundary.length() + 2; // 2 is the size of \r\n - } while (end != string::npos); - + message->addContent(content); + } return ChatMessageModifier::Result::Done; } return ChatMessageModifier::Result::Skipped; diff --git a/src/chat/notification/imdn.cpp b/src/chat/notification/imdn.cpp index 817ae3a2a..8afe38a6b 100644 --- a/src/chat/notification/imdn.cpp +++ b/src/chat/notification/imdn.cpp @@ -17,10 +17,14 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "chat/chat-message/chat-message-p.h" -#include "chat/chat-room/chat-room.h" -#include "core/core.h" +#include + +#include "chat/chat-message/imdn-message-p.h" +#include "chat/chat-room/chat-room-p.h" +#include "core/core-p.h" #include "logger/logger.h" +#include "xml/imdn.h" +#include "xml/linphone-imdn.h" #include "imdn.h" @@ -30,181 +34,227 @@ using namespace std; LINPHONE_BEGIN_NAMESPACE -const string Imdn::imdnPrefix = "/imdn:imdn"; +// ----------------------------------------------------------------------------- -string Imdn::createXml (const string &id, time_t time, Imdn::Type imdnType, LinphoneReason reason) { - xmlBufferPtr buf; - xmlTextWriterPtr writer; - int err; - string content; - char *datetime = nullptr; +Imdn::Imdn (ChatRoom *chatRoom) : chatRoom(chatRoom) { + chatRoom->getCore()->getPrivate()->registerListener(this); +} - // Check that the chat message has a message id. - if (id.empty()) - return content; +Imdn::~Imdn () { + stopTimer(); + chatRoom->getCore()->getPrivate()->unregisterListener(this); +} - buf = xmlBufferCreate(); - if (buf == nullptr) { - lError() << "Error creating the XML buffer"; - return content; - } - writer = xmlNewTextWriterMemory(buf, 0); - if (writer == nullptr) { - lError() << "Error creating the XML writer"; - return content; - } +// ----------------------------------------------------------------------------- - datetime = linphone_timestamp_to_rfc3339_string(time); - err = xmlTextWriterStartDocument(writer, "1.0", "UTF-8", nullptr); - if (err >= 0) { - err = xmlTextWriterStartElementNS(writer, nullptr, (const xmlChar *)"imdn", - (const xmlChar *)"urn:ietf:params:xml:ns:imdn"); +int Imdn::getDisplayNotificationCount () const { + return static_cast(displayedMessages.size()); +} + +// ----------------------------------------------------------------------------- + +void Imdn::notifyDelivery (const shared_ptr &message) { + if (find(deliveredMessages.begin(), deliveredMessages.end(), message) == deliveredMessages.end()) { + deliveredMessages.push_back(message); + startTimer(); } - if ((err >= 0) && (reason != LinphoneReasonNone)) { - err = xmlTextWriterWriteAttributeNS(writer, (const xmlChar *)"xmlns", (const xmlChar *)"linphoneimdn", nullptr, (const xmlChar *)"http://www.linphone.org/xsds/imdn.xsd"); +} + +void Imdn::notifyDeliveryError (const shared_ptr &message, LinphoneReason reason) { + auto it = find_if(nonDeliveredMessages.begin(), nonDeliveredMessages.end(), [message](const MessageReason mr) { + return message == mr.message; + }); + if (it == nonDeliveredMessages.end()) { + nonDeliveredMessages.emplace_back(message, reason); + startTimer(); } - if (err >= 0) { - err = xmlTextWriterWriteElement(writer, (const xmlChar *)"message-id", (const xmlChar *)id.c_str()); +} + +void Imdn::notifyDisplay (const shared_ptr &message) { + auto it = find(deliveredMessages.begin(), deliveredMessages.end(), message); + if (it != deliveredMessages.end()) + deliveredMessages.erase(it); + + if (find(displayedMessages.begin(), displayedMessages.end(), message) == displayedMessages.end()) { + displayedMessages.push_back(message); + startTimer(); } - if (err >= 0) { - err = xmlTextWriterWriteElement(writer, (const xmlChar *)"datetime", (const xmlChar *)datetime); +} + +// ----------------------------------------------------------------------------- + +void Imdn::onImdnMessageDelivered (const std::shared_ptr &message) { + // If an IMDN has been successfully delivered, remove it from the list so that + // it does not get sent again + auto context = message->getPrivate()->getContext(); + for (const auto &deliveredMsg : context.deliveredMessages) + deliveredMessages.remove(deliveredMsg); + + for (const auto &displayedMsg : context.displayedMessages) + displayedMessages.remove(displayedMsg); + + for (const auto &nonDeliveredMsg : context.nonDeliveredMessages) + nonDeliveredMessages.remove(nonDeliveredMsg); + + sentImdnMessages.remove(message); +} + +// ----------------------------------------------------------------------------- + +void Imdn::onGlobalStateChanged (LinphoneGlobalState state) { + if (state == LinphoneGlobalShutdown) { + auto ref = chatRoom->getSharedFromThis(); + deliveredMessages.clear(); + displayedMessages.clear(); + nonDeliveredMessages.clear(); + sentImdnMessages.clear(); } - if (err >= 0) { - if (imdnType == Imdn::Type::Delivery) { - err = xmlTextWriterStartElement(writer, (const xmlChar *)"delivery-notification"); - } else { - err = xmlTextWriterStartElement(writer, (const xmlChar *)"display-notification"); - } +} + +void Imdn::onNetworkReachable (bool sipNetworkReachable, bool mediaNetworkReachable) { + if (sipNetworkReachable) { + // When the SIP network gets up, retry notification + sentImdnMessages.clear(); + send(); } - if (err >= 0) { - err = xmlTextWriterStartElement(writer, (const xmlChar *)"status"); - } - if (err >= 0) { - if (reason == LinphoneReasonNone) { - if (imdnType == Imdn::Type::Delivery) { - err = xmlTextWriterStartElement(writer, (const xmlChar *)"delivered"); - } else { - err = xmlTextWriterStartElement(writer, (const xmlChar *)"displayed"); - } - } else { - err = xmlTextWriterStartElement(writer, (const xmlChar *)"error"); - } - } - if (err >= 0) { - // Close the "delivered", "displayed" or "error" element. - err = xmlTextWriterEndElement(writer); - } - if ((err >= 0) && (reason != LinphoneReasonNone)) { - err = xmlTextWriterStartElementNS(writer, (const xmlChar *)"linphoneimdn", (const xmlChar *)"reason", nullptr); - if (err >= 0) { - char codestr[16]; - snprintf(codestr, 16, "%d", linphone_reason_to_error_code(reason)); - err = xmlTextWriterWriteAttribute(writer, (const xmlChar *)"code", (const xmlChar *)codestr); - } - if (err >= 0) { - err = xmlTextWriterWriteString(writer, (const xmlChar *)linphone_reason_to_string(reason)); - } - if (err >= 0) { - err = xmlTextWriterEndElement(writer); - } - } - if (err >= 0) { - // Close the "status" element. - err = xmlTextWriterEndElement(writer); - } - if (err >= 0) { - // Close the "delivery-notification" or "display-notification" element. - err = xmlTextWriterEndElement(writer); - } - if (err >= 0) { - // Close the "imdn" element. - err = xmlTextWriterEndElement(writer); - } - if (err >= 0) { - err = xmlTextWriterEndDocument(writer); - } - if (err > 0) { - // xmlTextWriterEndDocument returns the size of the content. - content = string((char *)buf->content); - } - xmlFreeTextWriter(writer); - xmlBufferFree(buf); +} + +// ----------------------------------------------------------------------------- + +string Imdn::createXml (const string &id, time_t timestamp, Imdn::Type imdnType, LinphoneReason reason) { + char *datetime = linphone_timestamp_to_rfc3339_string(timestamp); + Xsd::Imdn::Imdn imdn(id, datetime); ms_free(datetime); - return content; + bool needLinphoneImdnNamespace = false; + if (imdnType == Imdn::Type::Delivery) { + Xsd::Imdn::Status status; + if (reason == LinphoneReasonNone) { + auto delivered = Xsd::Imdn::Delivered(); + status.setDelivered(delivered); + } else { + auto failed = Xsd::Imdn::Failed(); + status.setFailed(failed); + Xsd::LinphoneImdn::ImdnReason imdnReason(linphone_reason_to_string(reason)); + imdnReason.setCode(linphone_reason_to_error_code(reason)); + status.setReason(imdnReason); + needLinphoneImdnNamespace = true; + } + Xsd::Imdn::DeliveryNotification deliveryNotification(status); + imdn.setDeliveryNotification(deliveryNotification); + } else if (imdnType == Imdn::Type::Display) { + Xsd::Imdn::Status1 status; + auto displayed = Xsd::Imdn::Displayed(); + status.setDisplayed(displayed); + Xsd::Imdn::DisplayNotification displayNotification(status); + imdn.setDisplayNotification(displayNotification); + } + + stringstream ss; + Xsd::XmlSchema::NamespaceInfomap map; + map[""].name = "urn:ietf:params:xml:ns:imdn"; + if (needLinphoneImdnNamespace) + map["imdn"].name = "http://www.linphone.org/xsds/imdn.xsd"; + Xsd::Imdn::serializeImdn(ss, imdn, map, "UTF-8", Xsd::XmlSchema::Flags::dont_pretty_print); + return ss.str(); } void Imdn::parse (const shared_ptr &chatMessage) { - xmlparsing_context_t *xmlCtx = linphone_xmlparsing_context_new(); - xmlSetGenericErrorFunc(xmlCtx, linphone_xmlparsing_genericxml_error); - xmlCtx->doc = xmlReadDoc((const unsigned char *)chatMessage->getPrivate()->getText().c_str(), 0, nullptr, 0); - if (xmlCtx->doc) - parse(chatMessage, xmlCtx); - else - lWarning() << "Wrongly formatted IMDN XML: " << xmlCtx->errorBuffer; - linphone_xmlparsing_context_destroy(xmlCtx); + shared_ptr cr = chatMessage->getChatRoom(); + for (const auto &content : chatMessage->getPrivate()->getContents()) { + istringstream data(content->getBodyAsString()); + unique_ptr imdn(Xsd::Imdn::parseImdn(data, Xsd::XmlSchema::Flags::dont_validate)); + if (!imdn) + continue; + shared_ptr cm = cr->findChatMessage(imdn->getMessageId()); + if (!cm) { + lWarning() << "Received IMDN for unknown message " << imdn->getMessageId(); + } else { + auto policy = linphone_core_get_im_notif_policy(cr->getCore()->getCCore()); + time_t imdnTime = chatMessage->getTime(); + const IdentityAddress &participantAddress = chatMessage->getFromAddress().getAddressWithoutGruu(); + auto &deliveryNotification = imdn->getDeliveryNotification(); + auto &displayNotification = imdn->getDisplayNotification(); + if (deliveryNotification.present()) { + auto &status = deliveryNotification.get().getStatus(); + if (status.getDelivered().present() && linphone_im_notif_policy_get_recv_imdn_delivered(policy)) + cm->getPrivate()->setParticipantState(participantAddress, ChatMessage::State::DeliveredToUser, imdnTime); + else if ((status.getFailed().present() || status.getError().present()) + && linphone_im_notif_policy_get_recv_imdn_delivered(policy) + ) + cm->getPrivate()->setParticipantState(participantAddress, ChatMessage::State::NotDelivered, imdnTime); + } else if (displayNotification.present()) { + auto &status = displayNotification.get().getStatus(); + if (status.getDisplayed().present() && linphone_im_notif_policy_get_recv_imdn_displayed(policy)) + cm->getPrivate()->setParticipantState(participantAddress, ChatMessage::State::Displayed, imdnTime); + } + } + } } -void Imdn::parse (const shared_ptr &imdnMessage, xmlparsing_context_t *xmlCtx) { - char xpathStr[MAX_XPATH_LENGTH]; - char *messageIdStr = nullptr; - char *datetimeStr = nullptr; - if (linphone_create_xml_xpath_context(xmlCtx) < 0) +// ----------------------------------------------------------------------------- + +int Imdn::timerExpired (void *data, unsigned int revents) { + Imdn *d = reinterpret_cast(data); + d->stopTimer(); + d->send(); + return BELLE_SIP_STOP; +} + +// ----------------------------------------------------------------------------- + +bool Imdn::aggregationEnabled () const { + auto config = linphone_core_get_config(chatRoom->getCore()->getCCore()); + bool aggregateImdn = linphone_config_get_bool(config, "misc", "aggregate_imdn", TRUE); + return (chatRoom->canHandleCpim() && aggregateImdn); +} + +void Imdn::send () { + bool networkReachable = linphone_core_is_network_reachable(chatRoom->getCore()->getCCore()); + if (!networkReachable) return; - xmlXPathRegisterNs(xmlCtx->xpath_ctx, (const xmlChar *)"imdn", (const xmlChar *)"urn:ietf:params:xml:ns:imdn"); - xmlXPathObjectPtr imdnObject = linphone_get_xml_xpath_object_for_node_list(xmlCtx, imdnPrefix.c_str()); - if (imdnObject) { - if (imdnObject->nodesetval && (imdnObject->nodesetval->nodeNr >= 1)) { - snprintf(xpathStr, sizeof(xpathStr), "%s[1]/imdn:message-id", imdnPrefix.c_str()); - messageIdStr = linphone_get_xml_text_content(xmlCtx, xpathStr); - snprintf(xpathStr, sizeof(xpathStr), "%s[1]/imdn:datetime", imdnPrefix.c_str()); - datetimeStr = linphone_get_xml_text_content(xmlCtx, xpathStr); + if (!deliveredMessages.empty() || !displayedMessages.empty()) { + auto imdnMessage = chatRoom->getPrivate()->createImdnMessage(deliveredMessages, displayedMessages); + sentImdnMessages.push_back(imdnMessage); + imdnMessage->getPrivate()->send(); + if (!aggregationEnabled()) { + deliveredMessages.clear(); + displayedMessages.clear(); } - xmlXPathFreeObject(imdnObject); + } + if (!nonDeliveredMessages.empty()) { + auto imdnMessage = chatRoom->getPrivate()->createImdnMessage(nonDeliveredMessages); + sentImdnMessages.push_back(imdnMessage); + imdnMessage->getPrivate()->send(); + if (!aggregationEnabled()) + nonDeliveredMessages.clear(); + } +} + +void Imdn::startTimer () { + if (!aggregationEnabled()) { + // Compatibility mode for basic chat rooms, do not aggregate notifications + send(); + return; } - if (messageIdStr && datetimeStr) { - shared_ptr cr = imdnMessage->getChatRoom(); - shared_ptr cm = cr->findChatMessage(messageIdStr, ChatMessage::Direction::Outgoing); - const IdentityAddress &participantAddress = imdnMessage->getFromAddress().getAddressWithoutGruu(); - if (!cm) { - lWarning() << "Received IMDN for unknown message " << messageIdStr; - } else { - LinphoneImNotifPolicy *policy = linphone_core_get_im_notif_policy(cr->getCore()->getCCore()); - snprintf(xpathStr, sizeof(xpathStr), "%s[1]/imdn:delivery-notification/imdn:status", imdnPrefix.c_str()); - xmlXPathObjectPtr deliveryStatusObject = linphone_get_xml_xpath_object_for_node_list(xmlCtx, xpathStr); - snprintf(xpathStr, sizeof(xpathStr), "%s[1]/imdn:display-notification/imdn:status", imdnPrefix.c_str()); - xmlXPathObjectPtr displayStatusObject = linphone_get_xml_xpath_object_for_node_list(xmlCtx, xpathStr); - if (deliveryStatusObject && linphone_im_notif_policy_get_recv_imdn_delivered(policy)) { - if (deliveryStatusObject->nodesetval && (deliveryStatusObject->nodesetval->nodeNr >= 1)) { - xmlNodePtr node = deliveryStatusObject->nodesetval->nodeTab[0]; - if (node->children && node->children->name) { - if (strcmp((const char *)node->children->name, "delivered") == 0) { - cm->getPrivate()->setParticipantState(participantAddress, ChatMessage::State::DeliveredToUser); - } else if (strcmp((const char *)node->children->name, "error") == 0) { - cm->getPrivate()->setParticipantState(participantAddress, ChatMessage::State::NotDelivered); - } - } - } - xmlXPathFreeObject(deliveryStatusObject); - } - if (displayStatusObject && linphone_im_notif_policy_get_recv_imdn_displayed(policy)) { - if (displayStatusObject->nodesetval && (displayStatusObject->nodesetval->nodeNr >= 1)) { - xmlNodePtr node = displayStatusObject->nodesetval->nodeTab[0]; - if (node->children && node->children->name) { - if (strcmp((const char *)node->children->name, "displayed") == 0) { - cm->getPrivate()->setParticipantState(participantAddress, ChatMessage::State::Displayed); - } - } - } - xmlXPathFreeObject(displayStatusObject); - } - } + unsigned int duration = 500; + if (!timer) + timer = chatRoom->getCore()->getCCore()->sal->createTimer(timerExpired, this, duration, "imdn timeout"); + else + belle_sip_source_set_timeout(timer, duration); + bgTask.start(chatRoom->getCore(), 1); +} + +void Imdn::stopTimer () { + if (timer) { + auto core = chatRoom->getCore()->getCCore(); + if (core && core->sal) + core->sal->cancelTimer(timer); + belle_sip_object_unref(timer); + timer = nullptr; } - if (messageIdStr) - linphone_free_xml_text_content(messageIdStr); - if (datetimeStr) - linphone_free_xml_text_content(datetimeStr); + bgTask.stop(); } LINPHONE_END_NAMESPACE diff --git a/src/chat/notification/imdn.h b/src/chat/notification/imdn.h index e6eea4766..58755fdd8 100644 --- a/src/chat/notification/imdn.h +++ b/src/chat/notification/imdn.h @@ -22,29 +22,72 @@ #include "linphone/utils/general.h" +#include "core/core-listener.h" +#include "utils/background-task.h" + #include "private.h" // ============================================================================= LINPHONE_BEGIN_NAMESPACE +class ChatMessage; class ChatRoom; +class ImdnMessage; -class Imdn { +class Imdn : public CoreListener { public: enum class Type { Delivery, Display }; + struct MessageReason { + MessageReason (const std::shared_ptr &message, LinphoneReason reason) + : message(message), reason(reason) {} + + bool operator== (const MessageReason &other) const { + return (message == other.message) && (reason == other.reason); + } + + const std::shared_ptr message; + LinphoneReason reason; + }; + + Imdn (ChatRoom *chatRoom); + ~Imdn (); + + int getDisplayNotificationCount () const; + + void notifyDelivery (const std::shared_ptr &message); + void notifyDeliveryError (const std::shared_ptr &message, LinphoneReason reason); + void notifyDisplay (const std::shared_ptr &message); + + void onImdnMessageDelivered (const std::shared_ptr &message); + + // CoreListener + void onGlobalStateChanged (LinphoneGlobalState state) override; + void onNetworkReachable (bool sipNetworkReachable, bool mediaNetworkReachable) override; + static std::string createXml (const std::string &id, time_t time, Imdn::Type imdnType, LinphoneReason reason); static void parse (const std::shared_ptr &chatMessage); private: - static void parse (const std::shared_ptr &chatMessage, xmlparsing_context_t *xmlCtx); + static int timerExpired (void *data, unsigned int revents); + + bool aggregationEnabled () const; + void send (); + void startTimer (); + void stopTimer (); private: - static const std::string imdnPrefix; + ChatRoom *chatRoom = nullptr; + std::list> deliveredMessages; + std::list> displayedMessages; + std::list nonDeliveredMessages; + std::list> sentImdnMessages; + belle_sip_source_t *timer = nullptr; + BackgroundTask bgTask { "IMDN sending" }; }; LINPHONE_END_NAMESPACE diff --git a/src/chat/notification/is-composing.cpp b/src/chat/notification/is-composing.cpp index c567bd3b8..343bf53d9 100644 --- a/src/chat/notification/is-composing.cpp +++ b/src/chat/notification/is-composing.cpp @@ -24,6 +24,7 @@ #include "chat/chat-room/chat-room-p.h" #include "chat/notification/is-composing.h" #include "logger/logger.h" +#include "xml/is-composing.h" // ============================================================================= @@ -42,10 +43,6 @@ struct IsRemoteComposingData { // ----------------------------------------------------------------------------- -const string IsComposing::isComposingPrefix = "/xsi:isComposing"; - -// ----------------------------------------------------------------------------- - IsComposing::IsComposing (LinphoneCore *core, IsComposingListener *listener) : core(core), listener(listener) {} @@ -55,72 +52,40 @@ IsComposing::~IsComposing () { // ----------------------------------------------------------------------------- -string IsComposing::marshal (bool isComposing) { - string content; +string IsComposing::createXml (bool isComposing) { + Xsd::IsComposing::IsComposing node(isComposing ? "active" : "idle"); + if (isComposing) + node.setRefresh(static_cast(lp_config_get_int(core->config, "sip", "composing_refresh_timeout", defaultRefreshTimeout))); - xmlBufferPtr buf = xmlBufferCreate(); - if (!buf) { - lError() << "Error creating the XML buffer"; - return content; - } - xmlTextWriterPtr writer = xmlNewTextWriterMemory(buf, 0); - if (!writer) { - lError() << "Error creating the XML writer"; - return content; - } - - int err = xmlTextWriterStartDocument(writer, "1.0", "UTF-8", nullptr); - if (err >= 0) { - err = xmlTextWriterStartElementNS(writer, nullptr, (const xmlChar *)"isComposing", - (const xmlChar *)"urn:ietf:params:xml:ns:im-iscomposing"); - } - if (err >= 0) { - err = xmlTextWriterWriteAttributeNS(writer, (const xmlChar *)"xmlns", (const xmlChar *)"xsi", nullptr, - (const xmlChar *)"http://www.w3.org/2001/XMLSchema-instance"); - } - if (err >= 0) { - err = xmlTextWriterWriteAttributeNS(writer, (const xmlChar *)"xsi", (const xmlChar *)"schemaLocation", nullptr, - (const xmlChar *)"urn:ietf:params:xml:ns:im-composing iscomposing.xsd"); - } - if (err >= 0) { - err = xmlTextWriterWriteElement(writer, (const xmlChar *)"state", - isComposing ? (const xmlChar *)"active" : (const xmlChar *)"idle"); - } - if ((err >= 0) && isComposing) { - int refreshTimeout = lp_config_get_int(core->config, "sip", "composing_refresh_timeout", defaultRefreshTimeout); - err = xmlTextWriterWriteElement(writer, (const xmlChar *)"refresh", (const xmlChar *)Utils::toString(refreshTimeout).c_str()); - } - if (err >= 0) { - /* Close the "isComposing" element. */ - err = xmlTextWriterEndElement(writer); - } - if (err >= 0) { - err = xmlTextWriterEndDocument(writer); - } - if (err > 0) { - /* xmlTextWriterEndDocument returns the size of the content. */ - content = (char *)buf->content; - } - xmlFreeTextWriter(writer); - xmlBufferFree(buf); - return content; + stringstream ss; + Xsd::XmlSchema::NamespaceInfomap map; + map[""].name = "urn:ietf:params:xml:ns:im-iscomposing"; + Xsd::IsComposing::serializeIsComposing(ss, node, map, "UTF-8", Xsd::XmlSchema::Flags::dont_pretty_print); + return ss.str(); } void IsComposing::parse (const Address &remoteAddr, const string &text) { - xmlparsing_context_t *xmlCtx = linphone_xmlparsing_context_new(); - xmlSetGenericErrorFunc(xmlCtx, linphone_xmlparsing_genericxml_error); - xmlCtx->doc = xmlReadDoc((const unsigned char *)text.c_str(), 0, nullptr, 0); - if (xmlCtx->doc) - parse(xmlCtx, remoteAddr); - else - lWarning() << "Wrongly formatted presence XML: " << xmlCtx->errorBuffer; - linphone_xmlparsing_context_destroy(xmlCtx); + istringstream data(text); + unique_ptr node(Xsd::IsComposing::parseIsComposing(data, Xsd::XmlSchema::Flags::dont_validate)); + if (!node) + return; + + if (node->getState() == "active") { + unsigned long long refresh = 0; + if (node->getRefresh().present()) + refresh = node->getRefresh().get(); + startRemoteRefreshTimer(remoteAddr.asStringUriOnly(), refresh); + listener->onIsRemoteComposingStateChanged(remoteAddr, true); + } else if (node->getState() == "idle") { + stopRemoteRefreshTimer(remoteAddr.asStringUriOnly()); + listener->onIsRemoteComposingStateChanged(remoteAddr, false); + } } void IsComposing::startIdleTimer () { unsigned int duration = getIdleTimerDuration(); if (!idleTimer) { - idleTimer = core->sal->create_timer(idleTimerExpired, this, + idleTimer = core->sal->createTimer(idleTimerExpired, this, duration * 1000, "composing idle timeout"); } else { belle_sip_source_set_timeout(idleTimer, duration * 1000); @@ -130,7 +95,7 @@ void IsComposing::startIdleTimer () { void IsComposing::startRefreshTimer () { unsigned int duration = getRefreshTimerDuration(); if (!refreshTimer) { - refreshTimer = core->sal->create_timer(refreshTimerExpired, this, + refreshTimer = core->sal->createTimer(refreshTimerExpired, this, duration * 1000, "composing refresh timeout"); } else { belle_sip_source_set_timeout(refreshTimer, duration * 1000); @@ -148,7 +113,7 @@ void IsComposing::stopTimers () { void IsComposing::stopIdleTimer () { if (idleTimer) { if (core && core->sal) - core->sal->cancel_timer(idleTimer); + core->sal->cancelTimer(idleTimer); belle_sip_object_unref(idleTimer); idleTimer = nullptr; } @@ -157,7 +122,7 @@ void IsComposing::stopIdleTimer () { void IsComposing::stopRefreshTimer () { if (refreshTimer) { if (core && core->sal) - core->sal->cancel_timer(refreshTimer); + core->sal->cancelTimer(refreshTimer); belle_sip_object_unref(refreshTimer); refreshTimer = nullptr; } @@ -186,47 +151,6 @@ unsigned int IsComposing::getRemoteRefreshTimerDuration () { return remoteRefreshTimerDuration < 0 ? 0 : static_cast(remoteRefreshTimerDuration); } -void IsComposing::parse (xmlparsing_context_t *xmlCtx, const Address &remoteAddr) { - char xpathStr[MAX_XPATH_LENGTH]; - char *stateStr = nullptr; - char *refreshStr = nullptr; - int i; - bool state = false; - - if (linphone_create_xml_xpath_context(xmlCtx) < 0) - return; - - xmlXPathRegisterNs(xmlCtx->xpath_ctx, (const xmlChar *)"xsi", (const xmlChar *)"urn:ietf:params:xml:ns:im-iscomposing"); - xmlXPathObjectPtr isComposingObject = linphone_get_xml_xpath_object_for_node_list(xmlCtx, isComposingPrefix.c_str()); - if (isComposingObject) { - if (isComposingObject->nodesetval) { - for (i = 1; i <= isComposingObject->nodesetval->nodeNr; i++) { - snprintf(xpathStr, sizeof(xpathStr), "%s[%i]/xsi:state", isComposingPrefix.c_str(), i); - stateStr = linphone_get_xml_text_content(xmlCtx, xpathStr); - if (!stateStr) - continue; - snprintf(xpathStr, sizeof(xpathStr), "%s[%i]/xsi:refresh", isComposingPrefix.c_str(), i); - refreshStr = linphone_get_xml_text_content(xmlCtx, xpathStr); - } - } - xmlXPathFreeObject(isComposingObject); - } - - if (stateStr) { - if (strcmp(stateStr, "active") == 0) { - state = true; - startRemoteRefreshTimer(remoteAddr.asStringUriOnly(), refreshStr); - } else { - stopRemoteRefreshTimer(remoteAddr.asStringUriOnly()); - } - - listener->onIsRemoteComposingStateChanged(remoteAddr, state); - linphone_free_xml_text_content(stateStr); - } - if (refreshStr) - linphone_free_xml_text_content(refreshStr); -} - int IsComposing::idleTimerExpired () { stopRefreshTimer(); stopIdleTimer(); @@ -245,14 +169,14 @@ int IsComposing::remoteRefreshTimerExpired (const string &uri) { return BELLE_SIP_STOP; } -void IsComposing::startRemoteRefreshTimer (const string &uri, const char *refreshStr) { +void IsComposing::startRemoteRefreshTimer (const string &uri, unsigned long long refresh) { unsigned int duration = getRemoteRefreshTimerDuration(); - if (refreshStr) - duration = static_cast(Utils::stoi(refreshStr)); + if (refresh != 0) + duration = static_cast(refresh); auto it = remoteRefreshTimers.find(uri); if (it == remoteRefreshTimers.end()) { IsRemoteComposingData *data = new IsRemoteComposingData(this, uri); - belle_sip_source_t *timer = core->sal->create_timer(remoteRefreshTimerExpired, data, + belle_sip_source_t *timer = core->sal->createTimer(remoteRefreshTimerExpired, data, duration * 1000, "composing remote refresh timeout"); pair p(uri, timer); remoteRefreshTimers.insert(p); @@ -268,7 +192,7 @@ void IsComposing::stopAllRemoteRefreshTimers () { unordered_map::iterator IsComposing::stopRemoteRefreshTimer (const unordered_map::const_iterator it) { belle_sip_source_t *timer = it->second; if (core && core->sal) { - core->sal->cancel_timer(timer); + core->sal->cancelTimer(timer); delete reinterpret_cast(belle_sip_source_get_user_data(timer)); } belle_sip_object_unref(timer); diff --git a/src/chat/notification/is-composing.h b/src/chat/notification/is-composing.h index 5722537d5..b556dffef 100644 --- a/src/chat/notification/is-composing.h +++ b/src/chat/notification/is-composing.h @@ -38,7 +38,7 @@ public: IsComposing (LinphoneCore *core, IsComposingListener *listener); ~IsComposing (); - std::string marshal (bool isComposing); + std::string createXml (bool isComposing); void parse (const Address &remoteAddr, const std::string &content); void startIdleTimer (); void startRefreshTimer (); @@ -51,11 +51,10 @@ private: unsigned int getIdleTimerDuration (); unsigned int getRefreshTimerDuration (); unsigned int getRemoteRefreshTimerDuration (); - void parse (xmlparsing_context_t *xmlCtx, const Address &remoteAddr); int idleTimerExpired (); int refreshTimerExpired (); int remoteRefreshTimerExpired (const std::string &uri); - void startRemoteRefreshTimer (const std::string &uri, const char *refreshStr); + void startRemoteRefreshTimer (const std::string &uri, unsigned long long refresh); void stopAllRemoteRefreshTimers (); std::unordered_map::iterator stopRemoteRefreshTimer (const std::unordered_map::const_iterator it); @@ -67,7 +66,6 @@ private: static const int defaultIdleTimeout = 15; static const int defaultRefreshTimeout = 60; static const int defaultRemoteRefreshTimeout = 120; - static const std::string isComposingPrefix; LinphoneCore *core = nullptr; IsComposingListener *listener = nullptr; diff --git a/src/conference/conference-interface.h b/src/conference/conference-interface.h index aacf6bfab..cf694327a 100644 --- a/src/conference/conference-interface.h +++ b/src/conference/conference-interface.h @@ -55,7 +55,7 @@ public: virtual const std::string &getSubject () const = 0; virtual void join () = 0; virtual void leave () = 0; - virtual void removeParticipant (const std::shared_ptr &participant) = 0; + virtual void removeParticipant (const std::shared_ptr &participant) = 0; virtual void removeParticipants (const std::list> &participants) = 0; virtual void setParticipantAdminStatus (const std::shared_ptr &participant, bool isAdmin) = 0; virtual void setSubject (const std::string &subject) = 0; diff --git a/src/conference/conference-listener.h b/src/conference/conference-listener.h index f185259f8..292928059 100644 --- a/src/conference/conference-listener.h +++ b/src/conference/conference-listener.h @@ -28,7 +28,7 @@ LINPHONE_BEGIN_NAMESPACE -class ConferenceListener { +class LINPHONE_PUBLIC ConferenceListener { public: virtual ~ConferenceListener () = default; diff --git a/src/conference/conference.cpp b/src/conference/conference.cpp index 9e22d0207..7dc5ed023 100644 --- a/src/conference/conference.cpp +++ b/src/conference/conference.cpp @@ -18,9 +18,14 @@ */ #include "conference-p.h" +#include "conference/participant-device.h" #include "conference/session/call-session-p.h" +#include "content/content.h" +#include "content/content-disposition.h" +#include "content/content-type.h" #include "logger/logger.h" #include "participant-p.h" +#include "xml/resource-lists.h" // ============================================================================= @@ -97,7 +102,7 @@ void Conference::join () {} void Conference::leave () {} -void Conference::removeParticipant (const shared_ptr &participant) { +void Conference::removeParticipant (const shared_ptr &participant) { lError() << "Conference class does not handle removeParticipant() generically"; } @@ -154,6 +159,8 @@ shared_ptr Conference::findParticipantDevice (const shared_pt return nullptr; } +// ----------------------------------------------------------------------------- + bool Conference::isMe (const IdentityAddress &addr) const { L_D(); IdentityAddress cleanedAddr(addr); @@ -163,4 +170,46 @@ bool Conference::isMe (const IdentityAddress &addr) const { return cleanedMeAddr == cleanedAddr; } +// ----------------------------------------------------------------------------- + +string Conference::getResourceLists (const list &addresses) const { + Xsd::ResourceLists::ResourceLists rl = Xsd::ResourceLists::ResourceLists(); + Xsd::ResourceLists::ListType l = Xsd::ResourceLists::ListType(); + for (const auto &addr : addresses) { + Xsd::ResourceLists::EntryType entry = Xsd::ResourceLists::EntryType(addr.asString()); + l.getEntry().push_back(entry); + } + rl.getList().push_back(l); + + Xsd::XmlSchema::NamespaceInfomap map; + stringstream xmlBody; + serializeResourceLists(xmlBody, rl, map); + return xmlBody.str(); +} + +// ----------------------------------------------------------------------------- + +list Conference::parseResourceLists (const Content &content) { + if ((content.getContentType() == ContentType::ResourceLists) + && ((content.getContentDisposition().weakEqual(ContentDisposition::RecipientList)) + || (content.getContentDisposition().weakEqual(ContentDisposition::RecipientListHistory)) + ) + ) { + istringstream data(content.getBodyAsString()); + unique_ptr rl(Xsd::ResourceLists::parseResourceLists( + data, + Xsd::XmlSchema::Flags::dont_validate + )); + list addresses; + for (const auto &l : rl->getList()) { + for (const auto &entry : l.getEntry()) { + IdentityAddress addr(entry.getUri()); + addresses.push_back(move(addr)); + } + } + return addresses; + } + return list(); +} + LINPHONE_END_NAMESPACE diff --git a/src/conference/conference.h b/src/conference/conference.h index 0df0ae998..a5ee6643b 100644 --- a/src/conference/conference.h +++ b/src/conference/conference.h @@ -34,6 +34,7 @@ class CallSession; class CallSessionListener; class CallSessionPrivate; class ConferencePrivate; +class Content; class ParticipantDevice; class LINPHONE_PUBLIC Conference : @@ -62,11 +63,14 @@ public: const std::string &getSubject () const override; void join () override; void leave () override; - void removeParticipant (const std::shared_ptr &participant) override; + void removeParticipant (const std::shared_ptr &participant) override; void removeParticipants (const std::list> &participants) override; void setParticipantAdminStatus (const std::shared_ptr &participant, bool isAdmin) override; void setSubject (const std::string &subject) override; + std::string getResourceLists (const std::list &addresses) const; + static std::list parseResourceLists (const Content &content); + protected: explicit Conference ( ConferencePrivate &p, diff --git a/src/conference/handlers/local-conference-event-handler.cpp b/src/conference/handlers/local-conference-event-handler.cpp index 9847a93e9..de857918a 100644 --- a/src/conference/handlers/local-conference-event-handler.cpp +++ b/src/conference/handlers/local-conference-event-handler.cpp @@ -19,9 +19,12 @@ #include +#include "linphone/api/c-content.h" #include "linphone/utils/utils.h" +#include "c-wrapper/c-wrapper.h" #include "conference/local-conference.h" +#include "conference/participant-device.h" #include "conference/participant-p.h" #include "content/content-manager.h" #include "content/content-type.h" @@ -108,8 +111,8 @@ string LocalConferenceEventHandlerPrivate::createNotifyMultipart (int notifyId) list contents; for (const auto &eventLog : events) { - Content content; - content.setContentType(ContentType("application","conference-info")); + Content *content = new Content(); + content->setContentType(ContentType::ConferenceInfo); string body; shared_ptr notifiedEvent = static_pointer_cast(eventLog); int eventNotifyId = static_cast(notifiedEvent->getNotifyId()); @@ -179,13 +182,19 @@ string LocalConferenceEventHandlerPrivate::createNotifyMultipart (int notifyId) L_ASSERT(false); continue; } - content.setBody(body); - contents.push_back(content); + contents.emplace_back(Content()); + contents.back().setContentType(ContentType::ConferenceInfo); + contents.back().setBody(body); } if (contents.empty()) - return ""; - return ContentManager::contentListToMultipart(contents).getBodyAsString(); + return Utils::getEmptyConstRefObject(); + + list contentPtrs; + for (auto &content : contents) + contentPtrs.push_back(&content); + string multipart = ContentManager::contentListToMultipart(contentPtrs).getBodyAsString(); + return multipart; } string LocalConferenceEventHandlerPrivate::createNotifyParticipantAdded (const Address &addr, int notifyId) { @@ -362,22 +371,23 @@ void LocalConferenceEventHandlerPrivate::notifyParticipantDevice (const string & LinphoneEventCbs *cbs = linphone_event_get_callbacks(ev); linphone_event_cbs_set_user_data(cbs, this); linphone_event_cbs_set_notify_response(cbs, notifyResponseCb); - LinphoneContent *content = linphone_core_create_content(ev->lc); - linphone_content_set_buffer(content, (const uint8_t *)notify.c_str(), strlen(notify.c_str())); - linphone_content_set_type( - content, - multipart ? "multipart" : "application" - ); - linphone_content_set_subtype( - content, - multipart ? "mixed;boundary=---------------------------14737809831466499882746641449" : "conference-info" - ); + + Content content; + content.setBody(notify); + ContentType contentType; + if (multipart) { + contentType = ContentType(ContentType::Multipart); + contentType.addParameter("boundary", MultipartBoundary); + } else + contentType = ContentType(ContentType::ConferenceInfo); + + content.setContentType(contentType); // TODO: Activate compression //if (linphone_core_content_encoding_supported(conf->getCore()->getCCore(), "deflate")) // linphone_content_set_encoding(content, "deflate"); // TODO: Activate compression - linphone_event_notify(ev, content); - linphone_content_unref(content); + LinphoneContent *cContent = L_GET_C_BACK_PTR(&content); + linphone_event_notify(ev, cContent); } // ============================================================================= @@ -399,6 +409,7 @@ void LocalConferenceEventHandler::subscribeReceived (LinphoneEvent *lev, bool on bctbx_free(addrStr); if (!participant) { lError() << "received SUBSCRIBE corresponds to no participant of the conference; " << d->conf->getConferenceAddress().asString() << ", no NOTIFY sent."; + linphone_event_deny_subscription(lev, LinphoneReasonDeclined); return; } @@ -407,16 +418,18 @@ void LocalConferenceEventHandler::subscribeReceived (LinphoneEvent *lev, bool on IdentityAddress contactAddr(contactAddrStr); bctbx_free(contactAddrStr); shared_ptr device = participant->getPrivate()->findDevice(contactAddr); - if (!device) { + if (!device || (device->getState() != ParticipantDevice::State::Present && device->getState() != ParticipantDevice::State::Joining)) { lError() << "received SUBSCRIBE for conference: " << d->conf->getConferenceAddress().asString() << "device sending subscribe: " << contactAddr.asString() << " is not known, no NOTIFY sent."; + linphone_event_deny_subscription(lev, LinphoneReasonDeclined); return; } + linphone_event_accept_subscription(lev); if (linphone_event_get_subscription_state(lev) == LinphoneSubscriptionActive) { unsigned int lastNotify = static_cast(Utils::stoi(linphone_event_get_custom_header(lev, "Last-Notify-Version"))); device->setConferenceSubscribeEvent(lev); - if (lastNotify == 0) { + if (lastNotify == 0 || (device->getState() == ParticipantDevice::State::Joining)) { lInfo() << "Sending initial notify of conference:" << d->conf->getConferenceAddress().asString() << " to: " << device->getAddress().asString(); d->notifyFullState(d->createNotifyFullState(static_cast(d->lastNotify), oneToOne), device); } else if (lastNotify < d->lastNotify) { @@ -524,4 +537,19 @@ void LocalConferenceEventHandler::setChatRoomId (const ChatRoomId &chatRoomId) { d->chatRoomId = chatRoomId; } +ChatRoomId LocalConferenceEventHandler::getChatRoomId () const { + L_D(); + return d->chatRoomId; +} + +string LocalConferenceEventHandler::getNotifyForId (int notifyId, bool oneToOne) { + L_D(); + if (notifyId == 0) + return d->createNotifyFullState(static_cast(d->lastNotify), oneToOne); + else if (notifyId < static_cast(d->lastNotify)) + return d->createNotifyMultipart(notifyId); + + return Utils::getEmptyConstRefObject(); +} + LINPHONE_END_NAMESPACE diff --git a/src/conference/handlers/local-conference-event-handler.h b/src/conference/handlers/local-conference-event-handler.h index b44095f73..6f8a5cc3c 100644 --- a/src/conference/handlers/local-conference-event-handler.h +++ b/src/conference/handlers/local-conference-event-handler.h @@ -38,6 +38,7 @@ class LocalConference; class LocalConferenceEventHandlerPrivate; class LocalConferenceEventHandler : public Object { +friend class LocalConferenceListEventHandler; public: LocalConferenceEventHandler (LocalConference *localConference, unsigned int notify = 0); @@ -51,6 +52,9 @@ public: void setLastNotify (unsigned int lastNotify); void setChatRoomId (const ChatRoomId &chatRoomId); + ChatRoomId getChatRoomId () const; + + std::string getNotifyForId (int notifyId, bool oneToOne = false); private: L_DECLARE_PRIVATE(LocalConferenceEventHandler); diff --git a/src/conference/handlers/local-conference-list-event-handler.cpp b/src/conference/handlers/local-conference-list-event-handler.cpp new file mode 100644 index 000000000..af0d6d9dd --- /dev/null +++ b/src/conference/handlers/local-conference-list-event-handler.cpp @@ -0,0 +1,202 @@ +/* + * local-conference-list-event-handler.cpp + * Copyright (C) 2010-2018 Belledonne Communications SARL + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "belle-sip/utils.h" +#include "linphone/enums/chat-room-enums.h" +#include "linphone/utils/utils.h" +#include "linphone/api/c-address.h" + +#include "address/address.h" +#include "c-wrapper/c-wrapper.h" +#include "chat/chat-room/abstract-chat-room.h" +#include "conference/participant-p.h" +#include "conference/participant-device.h" +#include "content/content.h" +#include "content/content-manager.h" +#include "content/content-type.h" +#include "core/core.h" +#include "local-conference-event-handler.h" +#include "local-conference-list-event-handler.h" +#include "logger/logger.h" +#include "xml/resource-lists.h" +#include "xml/rlmi.h" + +// TODO: Remove me later. +#include "private.h" + +// ============================================================================= + +using namespace std; + +LINPHONE_BEGIN_NAMESPACE + +namespace { + constexpr const char MultipartBoundaryListEventHandler[] = "---------------------------14737809831412343453453"; +} + +// ----------------------------------------------------------------------------- + +LocalConferenceListEventHandler::LocalConferenceListEventHandler (const std::shared_ptr &core) : CoreAccessor(core) {} + +// ----------------------------------------------------------------------------- + +void LocalConferenceListEventHandler::subscribeReceived (LinphoneEvent *lev, const LinphoneContent *body) { + LinphoneSubscriptionState subscriptionState = linphone_event_get_subscription_state(lev); + + const string &xmlBody = string(linphone_content_get_string_buffer(body)); + if (xmlBody.empty()) { + linphone_event_deny_subscription(lev, LinphoneReasonDeclined); + return; + } + + linphone_event_accept_subscription(lev); + + if (subscriptionState != LinphoneSubscriptionIncomingReceived && subscriptionState != LinphoneSubscriptionTerminated) + return; + + const LinphoneAddress *lAddr = linphone_event_get_from(lev); + char *addrStr = linphone_address_as_string(lAddr); + IdentityAddress participantAddr(addrStr); + bctbx_free(addrStr); + + const LinphoneAddress *lDeviceAddr = linphone_event_get_remote_contact(lev); + char *deviceAddrStr = linphone_address_as_string(lDeviceAddr); + IdentityAddress deviceAddr(deviceAddrStr); + bctbx_free(deviceAddrStr); + + list contents; + Content *rlmiContent = new Content(); + rlmiContent->setContentType(ContentType::Rlmi); + + // Create Rlmi body + Xsd::Rlmi::List::ResourceSequence resources; + + // Parse resource list + bool noContent = true; + istringstream data(xmlBody); + unique_ptr rl(Xsd::ResourceLists::parseResourceLists( + data, + Xsd::XmlSchema::Flags::dont_validate + )); + for (const auto &l : rl->getList()) { + for (const auto &entry : l.getEntry()) { + Address addr(entry.getUri()); + string notifyIdStr = addr.getUriParamValue("Last-Notify"); + addr.removeUriParam("Last-Notify"); + ChatRoomId chatRoomId(addr, addr); + LocalConferenceEventHandler *handler = findHandler(chatRoomId); + if (!handler) + continue; + + shared_ptr chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(linphone_event_get_core(lev))->findChatRoom(chatRoomId); + if (!chatRoom) { + lError() << "Received subscribe for unknown chat room: " << chatRoomId; + continue; + } + + shared_ptr participant = chatRoom->findParticipant(participantAddr); + if (!participant) { + lError() << "Received subscribe for unknown participant: " << participantAddr << " for chat room: " << chatRoomId; + continue; + } + shared_ptr device = participant->getPrivate()->findDevice(deviceAddr); + if (!device || (device->getState() != ParticipantDevice::State::Present && device->getState() != ParticipantDevice::State::Joining)) { + lError() << "Received subscribe for unknown device: " << deviceAddr << " for participant: " + << participantAddr << " for chat room: " << chatRoomId; + continue; + } + device->setConferenceSubscribeEvent((subscriptionState == LinphoneSubscriptionIncomingReceived) ? lev : nullptr); + + int notifyId = (notifyIdStr.empty() || device->getState() == ParticipantDevice::State::Joining) ? 0 : Utils::stoi(notifyIdStr); + string notifyBody = handler->getNotifyForId(notifyId, !!(chatRoom->getCapabilities() & AbstractChatRoom::Capabilities::OneToOne)); + if (notifyBody.empty()) + continue; + + noContent = false; + Content *content = new Content(); + if (notifyId > 0) { + ContentType contentType(ContentType::Multipart); + contentType.addParameter("boundary", string(MultipartBoundary)); + content->setContentType(contentType); + } else + content->setContentType(ContentType::ConferenceInfo); + + content->setBody(notifyBody); + char token[17]; + belle_sip_random_token(token, sizeof(token)); + content->addHeader("Content-Id", token); + content->addHeader("Content-Length", Utils::toString(notifyBody.size())); + contents.push_back(content); + + // Add entry into the Rlmi content of the notify body + Xsd::Rlmi::Resource resource(addr.asStringUriOnly()); + Xsd::Rlmi::Resource::InstanceSequence instances; + Xsd::Rlmi::Instance instance(token, Xsd::Rlmi::State::Value::active); + instances.push_back(instance); + resource.setInstance(instances); + resources.push_back(resource); + } + } + + if (noContent) + return; + + Xsd::Rlmi::List list("", 0, TRUE); + list.setResource(resources); + Xsd::XmlSchema::NamespaceInfomap map; + stringstream rlmiBody; + Xsd::Rlmi::serializeList(rlmiBody, list, map); + rlmiContent->setBody(rlmiBody.str()); + + contents.push_front(rlmiContent); + Content multipart = ContentManager::contentListToMultipart(contents, MultipartBoundaryListEventHandler); + if (linphone_core_content_encoding_supported(getCore()->getCCore(), "deflate")) + multipart.setContentEncoding("deflate"); + LinphoneContent *cContent = L_GET_C_BACK_PTR(&multipart); + linphone_event_notify(lev, cContent); + contents.clear(); +} + +// ----------------------------------------------------------------------------- + +void LocalConferenceListEventHandler::addHandler (LocalConferenceEventHandler *handler) { + if (handler) + handlers.push_back(handler); +} + +void LocalConferenceListEventHandler::removeHandler (LocalConferenceEventHandler *handler) { + if (handler) + handlers.remove(handler); +} + +LocalConferenceEventHandler *LocalConferenceListEventHandler::findHandler (const ChatRoomId &chatRoomId) const { + for (const auto &handler : handlers) { + if (handler->getChatRoomId() == chatRoomId) + return handler; + } + + return nullptr; +} + +const list &LocalConferenceListEventHandler::getHandlers () const { + return handlers; +} + +LINPHONE_END_NAMESPACE + diff --git a/src/conference/handlers/local-conference-list-event-handler.h b/src/conference/handlers/local-conference-list-event-handler.h new file mode 100644 index 000000000..854fa37c1 --- /dev/null +++ b/src/conference/handlers/local-conference-list-event-handler.h @@ -0,0 +1,54 @@ +/* + * local-conference-list-event-handler.h + * Copyright (C) 2010-2018 Belledonne Communications SARL + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _L_LOCAL_CONFERENCE_LIST_EVENT_HANDLER_H_ +#define _L_LOCAL_CONFERENCE_LIST_EVENT_HANDLER_H_ + +#include +#include + +#include "chat/chat-room/chat-room-id.h" +#include "core/core-accessor.h" +#include "linphone/utils/general.h" + +// ============================================================================= + +LINPHONE_BEGIN_NAMESPACE + +class LocalConferenceEventHandler; + +class LocalConferenceListEventHandler : public CoreAccessor { +public: + LocalConferenceListEventHandler (const std::shared_ptr &core); + + void subscribeReceived (LinphoneEvent *lev, const LinphoneContent *body); + void addHandler (LocalConferenceEventHandler *handler); + void removeHandler (LocalConferenceEventHandler *handler); + LocalConferenceEventHandler *findHandler (const ChatRoomId &chatRoomId) const; + const std::list &getHandlers () const; + +private: + std::list handlers; + +}; + +LINPHONE_END_NAMESPACE + +#endif // ifndef _L_LOCAL_CONFERENCE_LIST_EVENT_HANDLER_H_ + diff --git a/src/conference/handlers/remote-conference-event-handler-p.h b/src/conference/handlers/remote-conference-event-handler-p.h index 8d4a06836..84903a293 100644 --- a/src/conference/handlers/remote-conference-event-handler-p.h +++ b/src/conference/handlers/remote-conference-event-handler-p.h @@ -32,6 +32,7 @@ LINPHONE_BEGIN_NAMESPACE class RemoteConferenceEventHandlerPrivate : public ObjectPrivate, public CoreListener { + friend class ClientGroupChatRoom; private: void simpleNotifyReceived (const std::string &xmlBody); void subscribe (); @@ -40,6 +41,8 @@ private: // CoreListener void onNetworkReachable (bool sipNetworkReachable, bool mediaNetworkReachable) override; void onRegistrationStateChanged (LinphoneProxyConfig *cfg, LinphoneRegistrationState state, const std::string &message) override; + void onEnteringBackground () override; + void onEnteringForeground () override; ChatRoomId chatRoomId; diff --git a/src/conference/handlers/remote-conference-event-handler.cpp b/src/conference/handlers/remote-conference-event-handler.cpp index 090c81ff6..bc97ca183 100644 --- a/src/conference/handlers/remote-conference-event-handler.cpp +++ b/src/conference/handlers/remote-conference-event-handler.cpp @@ -24,6 +24,7 @@ #include "conference/remote-conference.h" #include "content/content-manager.h" +#include "content/content-type.h" #include "content/content.h" #include "core/core-p.h" #include "logger/logger.h" @@ -207,8 +208,8 @@ void RemoteConferenceEventHandlerPrivate::subscribe () { return; } - lev = linphone_event_ref(linphone_core_create_subscribe(conf->getCore()->getCCore(), lAddr, "conference", 600)); - lev->op->set_from(chatRoomId.getLocalAddress().asString().c_str()); + lev = linphone_core_create_subscribe(conf->getCore()->getCCore(), lAddr, "conference", 600); + lev->op->setFrom(chatRoomId.getLocalAddress().asString().c_str()); const string &lastNotifyStr = Utils::toString(lastNotify); linphone_event_add_custom_header(lev, "Last-Notify-Version", lastNotifyStr.c_str()); linphone_address_unref(lAddr); @@ -221,7 +222,6 @@ void RemoteConferenceEventHandlerPrivate::subscribe () { void RemoteConferenceEventHandlerPrivate::unsubscribe () { if (lev) { linphone_event_terminate(lev); - linphone_event_unref(lev); lev = nullptr; } } @@ -238,6 +238,14 @@ void RemoteConferenceEventHandlerPrivate::onRegistrationStateChanged (LinphonePr subscribe(); } +void RemoteConferenceEventHandlerPrivate::onEnteringBackground () { + unsubscribe(); +} + +void RemoteConferenceEventHandlerPrivate::onEnteringForeground () { + subscribe(); +} + // ----------------------------------------------------------------------------- RemoteConferenceEventHandler::RemoteConferenceEventHandler (RemoteConference *remoteConference) : @@ -256,8 +264,7 @@ RemoteConferenceEventHandler::~RemoteConferenceEventHandler () { // Unable to unregister listener here. Core is destroyed and the listener doesn't exist. } - if (d->lev) - unsubscribe(); + unsubscribe(); } // ----------------------------------------------------------------------------- @@ -278,8 +285,7 @@ void RemoteConferenceEventHandler::unsubscribe () { void RemoteConferenceEventHandler::notifyReceived (const string &xmlBody) { L_D(); - lInfo() << "NOTIFY received for conference: (remote=" << d->chatRoomId.getPeerAddress().asString() << - ", local=" << d->chatRoomId.getLocalAddress().asString() << ")."; + lInfo() << "NOTIFY received for conference: " << d->chatRoomId; d->simpleNotifyReceived(xmlBody); } @@ -287,11 +293,13 @@ void RemoteConferenceEventHandler::notifyReceived (const string &xmlBody) { void RemoteConferenceEventHandler::multipartNotifyReceived (const string &xmlBody) { L_D(); - lInfo() << "multipart NOTIFY received for conference: (remote=" << d->chatRoomId.getPeerAddress().asString() << - ", local=" << d->chatRoomId.getLocalAddress().asString() << ")."; + lInfo() << "multipart NOTIFY received for conference: " << d->chatRoomId; Content multipart; multipart.setBody(xmlBody); + ContentType contentType(ContentType::Multipart); + contentType.addParameter("boundary", MultipartBoundary); + multipart.setContentType(contentType); for (const auto &content : ContentManager::multipartToContentList(multipart)) d->simpleNotifyReceived(content.getBodyAsString()); @@ -299,6 +307,11 @@ void RemoteConferenceEventHandler::multipartNotifyReceived (const string &xmlBod // ----------------------------------------------------------------------------- +void RemoteConferenceEventHandler::setChatRoomId (ChatRoomId chatRoomId) { + L_D(); + d->chatRoomId = chatRoomId; +} + const ChatRoomId &RemoteConferenceEventHandler::getChatRoomId () const { L_D(); return d->chatRoomId; diff --git a/src/conference/handlers/remote-conference-event-handler.h b/src/conference/handlers/remote-conference-event-handler.h index c7dae40ac..550ffeff1 100644 --- a/src/conference/handlers/remote-conference-event-handler.h +++ b/src/conference/handlers/remote-conference-event-handler.h @@ -31,6 +31,7 @@ class RemoteConference; class RemoteConferenceEventHandlerPrivate; class RemoteConferenceEventHandler : public Object { + friend class ClientGroupChatRoom; public: RemoteConferenceEventHandler (RemoteConference *remoteConference); ~RemoteConferenceEventHandler (); @@ -40,6 +41,7 @@ public: void multipartNotifyReceived (const std::string &xmlBody); void unsubscribe (); + void setChatRoomId (ChatRoomId chatRoomId); const ChatRoomId &getChatRoomId () const; unsigned int getLastNotify () const; diff --git a/src/conference/handlers/remote-conference-list-event-handler.cpp b/src/conference/handlers/remote-conference-list-event-handler.cpp new file mode 100644 index 000000000..1c77a4636 --- /dev/null +++ b/src/conference/handlers/remote-conference-list-event-handler.cpp @@ -0,0 +1,256 @@ +/* + * remote-conference-list-event-handler.cpp + * Copyright (C) 2010-2018 Belledonne Communications SARL + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "linphone/api/c-api.h" +#include "linphone/core.h" +#include "linphone/event.h" +#include "linphone/proxy_config.h" +#include "linphone/utils/utils.h" + +#include "address/address.h" +#include "c-wrapper/c-wrapper.h" +#include "content/content-manager.h" +#include "content/content-type.h" +#include "core/core-p.h" +#include "logger/logger.h" +#include "remote-conference-event-handler.h" +#include "remote-conference-list-event-handler.h" +#include "xml/conference-info.h" +#include "xml/resource-lists.h" +#include "xml/rlmi.h" + +// TODO: Remove me later. +#include "private.h" + +// ============================================================================= + +using namespace std; + +LINPHONE_BEGIN_NAMESPACE + +// ----------------------------------------------------------------------------- + +RemoteConferenceListEventHandler::RemoteConferenceListEventHandler (const std::shared_ptr &core) : CoreAccessor(core) { + getCore()->getPrivate()->registerListener(this); +} + +RemoteConferenceListEventHandler::~RemoteConferenceListEventHandler () { + try { + getCore()->getPrivate()->unregisterListener(this); + } catch (const bad_weak_ptr &) { + // Unable to unregister listener here. Core is destroyed and the listener doesn't exist. + } + + unsubscribe(); +} + +// ----------------------------------------------------------------------------- + +void RemoteConferenceListEventHandler::subscribe () { + if (lev) { + linphone_event_unref(lev); + lev = nullptr; + } + + if (handlers.size() == 0) + return; + + Content content; + content.setContentType(ContentType::ResourceLists); + + Xsd::ResourceLists::ResourceLists rl = Xsd::ResourceLists::ResourceLists(); + Xsd::ResourceLists::ListType l = Xsd::ResourceLists::ListType(); + for (const auto &handler : handlers) { + const ChatRoomId &chatRoomId = handler->getChatRoomId(); + shared_ptr cr = getCore()->findChatRoom(chatRoomId); + if (!cr) + continue; + + if (cr->hasBeenLeft()) + continue; + + Address addr = chatRoomId.getPeerAddress(); + addr.setUriParam("Last-Notify", Utils::toString(handler->getLastNotify())); + Xsd::ResourceLists::EntryType entry = Xsd::ResourceLists::EntryType(addr.asStringUriOnly()); + l.getEntry().push_back(entry); + } + rl.getList().push_back(l); + + Xsd::XmlSchema::NamespaceInfomap map; + stringstream xmlBody; + serializeResourceLists(xmlBody, rl, map); + content.setBody(xmlBody.str()); + + LinphoneCore *lc = getCore()->getCCore(); + LinphoneProxyConfig *cfg = linphone_core_get_default_proxy_config(lc); + if (!cfg || (linphone_proxy_config_get_state(cfg) != LinphoneRegistrationOk)) + return; + + LinphoneAddress *rlsAddr = linphone_address_new(linphone_proxy_config_get_conference_factory_uri(cfg)); + + lev = linphone_core_create_subscribe(lc, rlsAddr, "conference", 600); + char *from = linphone_address_as_string(linphone_proxy_config_get_contact(linphone_core_get_default_proxy_config(getCore()->getCCore()))); + lev->op->setFrom(from); + bctbx_free(from); + linphone_address_unref(rlsAddr); + linphone_event_set_internal(lev, TRUE); + linphone_event_add_custom_header(lev, "Require", "recipient-list-subscribe"); + linphone_event_add_custom_header(lev, "Accept", "multipart/related, application/conference-info+xml, application/rlmi+xml"); + linphone_event_add_custom_header(lev, "Content-Disposition", "recipient-list"); + if (linphone_core_content_encoding_supported(lc, "deflate")) { + content.setContentEncoding("deflate"); + linphone_event_add_custom_header(lev, "Accept-Encoding", "deflate"); + } + linphone_event_set_user_data(lev, this); + LinphoneContent *cContent = L_GET_C_BACK_PTR(&content); + linphone_event_send_subscribe(lev, cContent); +} + +void RemoteConferenceListEventHandler::unsubscribe () { + if (lev) { + linphone_event_terminate(lev); + lev = nullptr; + } +} + +void RemoteConferenceListEventHandler::notifyReceived (const Content *notifyContent) { + char *from = linphone_address_as_string(linphone_event_get_from(lev)); + const IdentityAddress local(from); + + if (notifyContent->getContentType().weakEqual(ContentType::ConferenceInfo)) { + // Simple notify received directly from a chat-room + const string &xmlBody = notifyContent->getBodyAsString(); + istringstream data(xmlBody); + unique_ptr confInfo = Xsd::ConferenceInfo::parseConferenceInfo(data, Xsd::XmlSchema::Flags::dont_validate); + + IdentityAddress entityAddress(confInfo->getEntity().c_str()); + ChatRoomId id(entityAddress, local); + RemoteConferenceEventHandler *handler = findHandler(id); + if (!handler) + return; + + handler->notifyReceived(xmlBody); + return; + } + + list contents = ContentManager::multipartToContentList(*notifyContent); + bctbx_free(from); + map addresses; + for (const auto &content : contents) { + const string &body = content.getBodyAsString(); + const ContentType &contentType = content.getContentType(); + if (contentType == ContentType::Rlmi) { + addresses = parseRlmi(body); + continue; + } + + const string &cid = content.getHeader("Content-Id").getValue(); + if (cid.empty()) + continue; + + map::const_iterator it = addresses.find(cid); + if (it == addresses.cend()) + continue; + + IdentityAddress peer = it->second; + ChatRoomId id(peer, local); + RemoteConferenceEventHandler *handler = findHandler(id); + if (!handler) + continue; + + if (contentType.weakEqual(ContentType::Multipart)) + handler->multipartNotifyReceived(body); + else if (contentType.weakEqual(ContentType::ConferenceInfo)) + handler->notifyReceived(body); + } +} + +// ----------------------------------------------------------------------------- + +RemoteConferenceEventHandler *RemoteConferenceListEventHandler::findHandler (const ChatRoomId &chatRoomId) const { + for (const auto &handler : handlers) { + if (handler->getChatRoomId() == chatRoomId) + return handler; + } + + return nullptr; +} + +const list &RemoteConferenceListEventHandler::getHandlers () const { + return handlers; +} + +void RemoteConferenceListEventHandler::addHandler (RemoteConferenceEventHandler *handler) { + if (handler) + handlers.push_back(handler); +} + +void RemoteConferenceListEventHandler::removeHandler (RemoteConferenceEventHandler *handler) { + if (handler) + handlers.remove(handler); +} + +map RemoteConferenceListEventHandler::parseRlmi (const string &xmlBody) const { + istringstream data(xmlBody); + unique_ptr rlmi(Xsd::Rlmi::parseList( + data, + Xsd::XmlSchema::Flags::dont_validate + )); + map addresses; + for (const auto &resource : rlmi->getResource()) { + if (resource.getInstance().empty()) + continue; + + const string &uri = string(resource.getUri()); + if (uri.empty()) + continue; + + IdentityAddress peer(uri); + for (const auto &instance : resource.getInstance()) { + const string &cid = string(instance.getId()); + if (cid.empty()) + continue; + + addresses.emplace(cid, peer); + } + } + return addresses; +} + +// ----------------------------------------------------------------------------- + +void RemoteConferenceListEventHandler::onNetworkReachable (bool sipNetworkReachable, bool mediaNetworkReachable) { + if (!sipNetworkReachable) + unsubscribe(); +} + +void RemoteConferenceListEventHandler::onRegistrationStateChanged (LinphoneProxyConfig *cfg, LinphoneRegistrationState state, const std::string &message) { + if (state == LinphoneRegistrationOk) + subscribe(); +} + +void RemoteConferenceListEventHandler::onEnteringBackground () { + unsubscribe(); +} + +void RemoteConferenceListEventHandler::onEnteringForeground () { + subscribe(); +} + +LINPHONE_END_NAMESPACE diff --git a/src/conference/handlers/remote-conference-list-event-handler.h b/src/conference/handlers/remote-conference-list-event-handler.h new file mode 100644 index 000000000..c93dc4ca5 --- /dev/null +++ b/src/conference/handlers/remote-conference-list-event-handler.h @@ -0,0 +1,70 @@ +/* + * remote-conference-list-event-handler.h + * Copyright (C) 2010-2018 Belledonne Communications SARL + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _L_REMOTE_CONFERENCE_LIST_EVENT_HANDLER_H_ +#define _L_REMOTE_CONFERENCE_LIST_EVENT_HANDLER_H_ + +#include +#include +#include + +#include "linphone/types.h" +#include "linphone/utils/general.h" + +#include "chat/chat-room/chat-room-id.h" +#include "core/core-accessor.h" +#include "core/core-listener.h" + +// ============================================================================= + +LINPHONE_BEGIN_NAMESPACE + +class Address; +class Content; +class RemoteConferenceEventHandler; + +class RemoteConferenceListEventHandler : public CoreAccessor , public CoreListener { +public: + RemoteConferenceListEventHandler (const std::shared_ptr &core); + ~RemoteConferenceListEventHandler (); + + void subscribe (); + void unsubscribe (); + void notifyReceived (const Content *notifyContent); + void addHandler (RemoteConferenceEventHandler *handler); + void removeHandler (RemoteConferenceEventHandler *handler); + RemoteConferenceEventHandler *findHandler (const ChatRoomId &chatRoomId) const; + const std::list &getHandlers () const; + +private: + std::list handlers; + LinphoneEvent *lev = nullptr; + + std::map parseRlmi (const std::string &xmlBody) const; + + // CoreListener + void onNetworkReachable (bool sipNetworkReachable, bool mediaNetworkReachable) override; + void onRegistrationStateChanged (LinphoneProxyConfig *cfg, LinphoneRegistrationState state, const std::string &message) override; + void onEnteringBackground () override; + void onEnteringForeground () override; +}; + +LINPHONE_END_NAMESPACE + +#endif // ifndef _L_REMOTE_CONFERENCE_LIST_EVENT_HANDLER_H_ diff --git a/src/conference/local-conference.cpp b/src/conference/local-conference.cpp index 847400131..def610da1 100644 --- a/src/conference/local-conference.cpp +++ b/src/conference/local-conference.cpp @@ -17,14 +17,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "content/content.h" -#include "content/content-disposition.h" -#include "content/content-type.h" #include "handlers/local-conference-event-handler.h" #include "local-conference-p.h" #include "logger/logger.h" #include "participant-p.h" -#include "xml/resource-lists.h" // ============================================================================= @@ -59,7 +55,7 @@ void LocalConference::addParticipant (const IdentityAddress &addr, const CallSes d->activeParticipant = participant; } -void LocalConference::removeParticipant (const shared_ptr &participant) { +void LocalConference::removeParticipant (const shared_ptr &participant) { L_D(); for (const auto &p : d->participants) { if (participant->getAddress() == p->getAddress()) { @@ -69,25 +65,4 @@ void LocalConference::removeParticipant (const shared_ptr &pa } } -list LocalConference::parseResourceLists (const Content &content) { - if ((content.getContentType() == ContentType::ResourceLists) - && (content.getContentDisposition() == ContentDisposition::RecipientList) - ) { - istringstream data(content.getBodyAsString()); - unique_ptr rl(Xsd::ResourceLists::parseResourceLists( - data, - Xsd::XmlSchema::Flags::dont_validate - )); - list addresses; - for (const auto &l : rl->getList()) { - for (const auto &entry : l.getEntry()) { - IdentityAddress addr(entry.getUri()); - addresses.push_back(move(addr)); - } - } - return addresses; - } - return list(); -} - LINPHONE_END_NAMESPACE diff --git a/src/conference/local-conference.h b/src/conference/local-conference.h index 7dee773e4..d926ecf54 100644 --- a/src/conference/local-conference.h +++ b/src/conference/local-conference.h @@ -26,7 +26,6 @@ LINPHONE_BEGIN_NAMESPACE -class Content; class LocalConferencePrivate; class LocalConference : public Conference { @@ -38,9 +37,7 @@ public: /* ConferenceInterface */ void addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) override; - void removeParticipant (const std::shared_ptr &participant) override; - - static std::list parseResourceLists (const Content &content); + void removeParticipant (const std::shared_ptr &participant) override; private: L_DECLARE_PRIVATE(LocalConference); diff --git a/src/conference/participant-device.cpp b/src/conference/participant-device.cpp index 4c147a38d..c6cbcc197 100644 --- a/src/conference/participant-device.cpp +++ b/src/conference/participant-device.cpp @@ -29,7 +29,7 @@ LINPHONE_BEGIN_NAMESPACE ParticipantDevice::ParticipantDevice () {} -ParticipantDevice::ParticipantDevice (const Participant *participant, const IdentityAddress &gruu) +ParticipantDevice::ParticipantDevice (Participant *participant, const IdentityAddress &gruu) : mParticipant(participant), mGruu(gruu) {} ParticipantDevice::~ParticipantDevice () { diff --git a/src/conference/participant-device.h b/src/conference/participant-device.h index e10da6394..284c83917 100644 --- a/src/conference/participant-device.h +++ b/src/conference/participant-device.h @@ -44,13 +44,13 @@ public: }; ParticipantDevice (); - explicit ParticipantDevice (const Participant *participant, const IdentityAddress &gruu); + explicit ParticipantDevice (Participant *participant, const IdentityAddress &gruu); virtual ~ParticipantDevice (); bool operator== (const ParticipantDevice &device) const; inline const IdentityAddress &getAddress () const { return mGruu; } - const Participant *getParticipant () const { return mParticipant; } + Participant *getParticipant () const { return mParticipant; } inline std::shared_ptr getSession () const { return mSession; } inline void setSession (std::shared_ptr session) { mSession = session; } inline State getState () const { return mState; } @@ -63,7 +63,7 @@ public: bool isValid () const { return mGruu.isValid(); } private: - const Participant *mParticipant = nullptr; + Participant *mParticipant = nullptr; IdentityAddress mGruu; std::shared_ptr mSession; LinphoneEvent *mConferenceSubscribeEvent = nullptr; diff --git a/src/conference/participant-imdn-state-p.h b/src/conference/participant-imdn-state-p.h new file mode 100644 index 000000000..981bfefb1 --- /dev/null +++ b/src/conference/participant-imdn-state-p.h @@ -0,0 +1,42 @@ +/* + * participant-imdn-state-p.h + * Copyright (C) 2010-2018 Belledonne Communications SARL + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _L_PARTICIPANT_IMDN_STATE_P_H_ +#define _L_PARTICIPANT_IMDN_STATE_P_H_ + +#include "object/clonable-object-p.h" + +#include "conference/participant-imdn-state.h" + +// ============================================================================= + +LINPHONE_BEGIN_NAMESPACE + +class ParticipantImdnStatePrivate : public ClonableObjectPrivate { +public: + std::shared_ptr participant; + ChatMessage::State state = ChatMessage::State::Idle; + time_t stateChangeTime = 0; + + L_DECLARE_PUBLIC(ParticipantImdnState); +}; + +LINPHONE_END_NAMESPACE + +#endif // ifndef _L_PARTICIPANT_IMDN_STATE_P_H_ diff --git a/src/conference/participant-imdn-state.cpp b/src/conference/participant-imdn-state.cpp new file mode 100644 index 000000000..cd3772bdb --- /dev/null +++ b/src/conference/participant-imdn-state.cpp @@ -0,0 +1,61 @@ +/* + * participant-imdn-state.cpp + * Copyright (C) 2010-2018 Belledonne Communications SARL + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "participant-imdn-state-p.h" + +using namespace std; + +LINPHONE_BEGIN_NAMESPACE + +// ============================================================================= + +ParticipantImdnState::ParticipantImdnState (const shared_ptr &participant, ChatMessage::State state, time_t stateChangeTime) + : ClonableObject(*new ParticipantImdnStatePrivate) +{ + L_D(); + d->participant = participant; + d->state = state; + d->stateChangeTime = stateChangeTime; +} + +ParticipantImdnState::ParticipantImdnState(const ParticipantImdnState &other) : ClonableObject(*new ParticipantImdnStatePrivate) { + L_D(); + d->participant = other.getParticipant(); + d->state = other.getState(); + d->stateChangeTime = other.getStateChangeTime(); +} + +// ----------------------------------------------------------------------------- + +shared_ptr ParticipantImdnState::getParticipant () const { + L_D(); + return d->participant; +} + +ChatMessage::State ParticipantImdnState::getState () const { + L_D(); + return d->state; +} + +time_t ParticipantImdnState::getStateChangeTime () const { + L_D(); + return d->stateChangeTime; +} + +LINPHONE_END_NAMESPACE diff --git a/src/conference/participant-imdn-state.h b/src/conference/participant-imdn-state.h new file mode 100644 index 000000000..0a9c7ded4 --- /dev/null +++ b/src/conference/participant-imdn-state.h @@ -0,0 +1,48 @@ +/* + * participant-imdn-state.h + * Copyright (C) 2010-2018 Belledonne Communications SARL + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _L_PARTICIPANT_IMDN_STATE_H_ +#define _L_PARTICIPANT_IMDN_STATE_H_ + +#include "chat/chat-message/chat-message.h" +#include "object/clonable-object.h" + +// ============================================================================= + +LINPHONE_BEGIN_NAMESPACE + +class Participant; +class ParticipantImdnStatePrivate; + +class ParticipantImdnState : public ClonableObject { +public: + ParticipantImdnState (const std::shared_ptr &participant, ChatMessage::State state, time_t stateChangeTime); + ParticipantImdnState (const ParticipantImdnState &other); + + std::shared_ptr getParticipant () const; + ChatMessage::State getState () const; + time_t getStateChangeTime () const; + +private: + L_DECLARE_PRIVATE(ParticipantImdnState); +}; + +LINPHONE_END_NAMESPACE + +#endif // ifndef _L_PARTICIPANT_IMDN_STATE_H_ diff --git a/src/conference/participant.cpp b/src/conference/participant.cpp index 68d6e26f7..f72094c7f 100644 --- a/src/conference/participant.cpp +++ b/src/conference/participant.cpp @@ -20,6 +20,7 @@ #include #include "object/object-p.h" +#include "participant-device.h" #include "participant-p.h" #include "participant.h" diff --git a/src/conference/participant.h b/src/conference/participant.h index f3ac911a5..f1d9f1040 100644 --- a/src/conference/participant.h +++ b/src/conference/participant.h @@ -25,7 +25,6 @@ #include "address/identity-address.h" #include "object/object.h" #include "conference/params/call-session-params.h" -#include "conference/participant-device.h" // ============================================================================= @@ -45,6 +44,7 @@ class Participant : public Object { friend class LocalConferenceCallPrivate; friend class LocalConferenceEventHandler; friend class LocalConferenceEventHandlerPrivate; + friend class LocalConferenceListEventHandler; friend class MainDb; friend class MainDbPrivate; friend class MediaSessionPrivate; diff --git a/src/conference/remote-conference-p.h b/src/conference/remote-conference-p.h index 01c09bef3..9d256af10 100644 --- a/src/conference/remote-conference-p.h +++ b/src/conference/remote-conference-p.h @@ -32,7 +32,7 @@ class RemoteConferenceEventHandler; class RemoteConferencePrivate : public ConferencePrivate { public: std::shared_ptr focus; - std::unique_ptr eventHandler; + std::shared_ptr eventHandler; private: L_DECLARE_PUBLIC(RemoteConference); diff --git a/src/conference/remote-conference.cpp b/src/conference/remote-conference.cpp index ffdcde9ab..537832189 100644 --- a/src/conference/remote-conference.cpp +++ b/src/conference/remote-conference.cpp @@ -21,7 +21,6 @@ #include "logger/logger.h" #include "participant-p.h" #include "remote-conference-p.h" -#include "xml/resource-lists.h" // ============================================================================= @@ -59,7 +58,7 @@ void RemoteConference::addParticipant (const IdentityAddress &addr, const CallSe d->activeParticipant = participant; } -void RemoteConference::removeParticipant (const shared_ptr &participant) { +void RemoteConference::removeParticipant (const shared_ptr &participant) { L_D(); for (const auto &p : d->participants) { if (participant->getAddress() == p->getAddress()) { @@ -69,21 +68,6 @@ void RemoteConference::removeParticipant (const shared_ptr &p } } -string RemoteConference::getResourceLists (const list &addresses) const { - Xsd::ResourceLists::ResourceLists rl = Xsd::ResourceLists::ResourceLists(); - Xsd::ResourceLists::ListType l = Xsd::ResourceLists::ListType(); - for (const auto &addr : addresses) { - Xsd::ResourceLists::EntryType entry = Xsd::ResourceLists::EntryType(addr.asString()); - l.getEntry().push_back(entry); - } - rl.getList().push_back(l); - - Xsd::XmlSchema::NamespaceInfomap map; - stringstream xmlBody; - serializeResourceLists(xmlBody, rl, map); - return xmlBody.str(); -} - // ----------------------------------------------------------------------------- void RemoteConference::onConferenceCreated (const IdentityAddress &) {} diff --git a/src/conference/remote-conference.h b/src/conference/remote-conference.h index 1dd2b5931..3490113e5 100644 --- a/src/conference/remote-conference.h +++ b/src/conference/remote-conference.h @@ -38,9 +38,7 @@ public: /* ConferenceInterface */ void addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) override; - void removeParticipant (const std::shared_ptr &participant) override; - - std::string getResourceLists (const std::list &addresses) const; + void removeParticipant (const std::shared_ptr &participant) override; protected: /* ConferenceListener */ diff --git a/src/conference/session/call-session-listener.h b/src/conference/session/call-session-listener.h index edc634f22..3b9c20668 100644 --- a/src/conference/session/call-session-listener.h +++ b/src/conference/session/call-session-listener.h @@ -55,6 +55,7 @@ public: virtual void onInfoReceived (const std::shared_ptr &session, const LinphoneInfoMessage *im) {} virtual void onNoMediaTimeoutCheck (const std::shared_ptr &session, bool oneSecondElapsed) {} virtual void onTmmbrReceived (const std::shared_ptr &session, int streamIndex, int tmmbr) {} + virtual void onSnapshotTaken(const std::shared_ptr &session, const char *file_path) {} virtual void onEncryptionChanged (const std::shared_ptr &session, bool activated, const std::string &authToken) {} @@ -80,6 +81,7 @@ public: virtual bool isPlayingRingbackTone (const std::shared_ptr &session) { return false; } virtual void onRealTimeTextCharacterReceived (const std::shared_ptr &session, RealtimeTextReceivedCharacter *data) {} + }; LINPHONE_END_NAMESPACE diff --git a/src/conference/session/call-session.cpp b/src/conference/session/call-session.cpp index 668f0df33..9a4656353 100644 --- a/src/conference/session/call-session.cpp +++ b/src/conference/session/call-session.cpp @@ -19,19 +19,18 @@ #include -#include "c-wrapper/c-wrapper.h" +#include "linphone/api/c-content.h" +#include "linphone/core.h" #include "address/address-p.h" +#include "c-wrapper/c-wrapper.h" #include "call/call-p.h" #include "conference/params/call-session-params-p.h" #include "conference/session/call-session-p.h" #include "conference/session/call-session.h" #include "core/core-p.h" - #include "logger/logger.h" -#include "linphone/core.h" - #include "private.h" using namespace std; @@ -51,13 +50,13 @@ int CallSessionPrivate::computeDuration () const { * end apparently does not support. This features are: privacy, video... */ void CallSessionPrivate::initializeParamsAccordingToIncomingCallParams () { - currentParams->setPrivacy((LinphonePrivacyMask)op->get_privacy()); + currentParams->setPrivacy((LinphonePrivacyMask)op->getPrivacy()); } void CallSessionPrivate::notifyReferState () { SalCallOp *refererOp = referer->getPrivate()->getOp(); if (refererOp) - refererOp->notify_refer_state(op); + refererOp->notifyReferState(op); } void CallSessionPrivate::setState (CallSession::State newState, const string &message) { @@ -178,11 +177,11 @@ bool CallSessionPrivate::startPing () { pingReplied = false; pingOp = new SalOp(q->getCore()->getCCore()->sal); if (direction == LinphoneCallIncoming) { - const char *from = pingOp->get_from(); - const char *to = pingOp->get_to(); + string from = pingOp->getFrom(); + string to = pingOp->getTo(); linphone_configure_op(q->getCore()->getCCore(), pingOp, log->from, nullptr, false); - pingOp->set_route(op->get_network_origin()); - pingOp->ping(from, to); + pingOp->setRoute(op->getNetworkOrigin()); + pingOp->ping(from.c_str(), to.c_str()); } else if (direction == LinphoneCallOutgoing) { char *from = linphone_address_as_string(log->from); char *to = linphone_address_as_string(log->to); @@ -190,7 +189,7 @@ bool CallSessionPrivate::startPing () { ms_free(from); ms_free(to); } - pingOp->set_user_pointer(this); + pingOp->setUserPointer(this); return true; } return false; @@ -231,7 +230,7 @@ void CallSessionPrivate::accepted () { default: break; } - currentParams->setPrivacy((LinphonePrivacyMask)op->get_privacy()); + currentParams->setPrivacy((LinphonePrivacyMask)op->getPrivacy()); } void CallSessionPrivate::ackBeingSent (LinphoneHeaders *headers) { @@ -255,12 +254,12 @@ void CallSessionPrivate::cancelDone () { bool CallSessionPrivate::failure () { L_Q(); - const SalErrorInfo *ei = op->get_error_info(); + const SalErrorInfo *ei = op->getErrorInfo(); switch (ei->reason) { case SalReasonRedirect: if ((state == CallSession::State::OutgoingInit) || (state == CallSession::State::OutgoingProgress) || (state == CallSession::State::OutgoingRinging) /* Push notification case */ || (state == CallSession::State::OutgoingEarlyMedia)) { - const SalAddress *redirectionTo = op->get_remote_contact_address(); + const SalAddress *redirectionTo = op->getRemoteContactAddress(); if (redirectionTo) { char *url = sal_address_as_string(redirectionTo); lWarning() << "Redirecting CallSession [" << q << "] to " << url; @@ -313,7 +312,7 @@ bool CallSessionPrivate::failure () { void CallSessionPrivate::infoReceived (SalBodyHandler *bodyHandler) { L_Q(); LinphoneInfoMessage *info = linphone_core_create_info_message(q->getCore()->getCCore()); - linphone_info_message_set_headers(info, op->get_recv_custom_header()); + linphone_info_message_set_headers(info, op->getRecvCustomHeaders()); if (bodyHandler) { LinphoneContent *content = linphone_content_from_sal_body_handler(bodyHandler); linphone_info_message_set_content(info, content); @@ -345,7 +344,7 @@ void CallSessionPrivate::referred (const Address &referToAddr) { void CallSessionPrivate::remoteRinging () { L_Q(); /* Set privacy */ - currentParams->setPrivacy((LinphonePrivacyMask)op->get_privacy()); + currentParams->setPrivacy((LinphonePrivacyMask)op->getPrivacy()); if (listener) listener->onStartRinging(q->getSharedFromThis()); lInfo() << "Remote ringing..."; @@ -357,12 +356,12 @@ void CallSessionPrivate::replaceOp (SalCallOp *newOp) { SalCallOp *oldOp = op; CallSession::State oldState = state; op = newOp; - op->set_user_pointer(q); - op->set_local_media_description(oldOp->get_local_media_description()); + op->setUserPointer(q); + op->setLocalMediaDescription(oldOp->getLocalMediaDescription()); switch (state) { case CallSession::State::IncomingEarlyMedia: case CallSession::State::IncomingReceived: - op->notify_ringing((state == CallSession::State::IncomingEarlyMedia) ? true : false); + op->notifyRinging((state == CallSession::State::IncomingEarlyMedia) ? true : false); break; case CallSession::State::Connected: case CallSession::State::StreamsRunning: @@ -375,17 +374,17 @@ void CallSessionPrivate::replaceOp (SalCallOp *newOp) { switch (oldState) { case CallSession::State::IncomingEarlyMedia: case CallSession::State::IncomingReceived: - oldOp->set_user_pointer(nullptr); // In order for the call session to not get terminated by terminating this op + oldOp->setUserPointer(nullptr); // In order for the call session to not get terminated by terminating this op // Do not terminate a forked INVITE - if (op->get_replaces()) + if (op->getReplaces()) oldOp->terminate(); else - oldOp->kill_dialog(); + oldOp->killDialog(); break; case CallSession::State::Connected: case CallSession::State::StreamsRunning: oldOp->terminate(); - oldOp->kill_dialog(); + oldOp->killDialog(); break; default: break; @@ -402,7 +401,7 @@ void CallSessionPrivate::terminated () { return; case CallSession::State::IncomingReceived: case CallSession::State::IncomingEarlyMedia: - if (!op->get_reason_error_info()->protocol || strcmp(op->get_reason_error_info()->protocol, "") == 0) { + if (!op->getReasonErrorInfo()->protocol || strcmp(op->getReasonErrorInfo()->protocol, "") == 0) { linphone_error_info_set(ei, nullptr, LinphoneReasonNotAnswered, 0, "Incoming call cancelled", nullptr); nonOpError = true; } @@ -448,7 +447,7 @@ void CallSessionPrivate::updated (bool isUpdate) { case CallSession::State::Pausing: case CallSession::State::Resuming: sal_error_info_set(&sei, SalReasonInternalError, "SIP", 0, nullptr, nullptr); - op->decline_with_error_info(&sei, nullptr); + op->declineWithErrorInfo(&sei, nullptr); BCTBX_NO_BREAK; /* no break */ case CallSession::State::Idle: case CallSession::State::OutgoingInit: @@ -502,7 +501,7 @@ void CallSessionPrivate::accept (const CallSessionParams *csp) { if (csp) setParams(new CallSessionParams(*csp)); if (params) - op->set_sent_custom_header(params->getPrivate()->getCustomHeaders()); + op->setSentCustomHeaders(params->getPrivate()->getCustomHeaders()); op->accept(); if (listener) @@ -528,9 +527,9 @@ LinphoneStatus CallSessionPrivate::checkForAcceptation () { listener->onCheckForAcceptation(q->getSharedFromThis()); /* Check if this call is supposed to replace an already running one */ - SalOp *replaced = op->get_replaces(); + SalOp *replaced = op->getReplaces(); if (replaced) { - CallSession *session = reinterpret_cast(replaced->get_user_pointer()); + CallSession *session = reinterpret_cast(replaced->getUserPointer()); if (session) { lInfo() << "CallSession " << q << " replaces CallSession " << session << ". This last one is going to be terminated automatically"; session->terminate(); @@ -544,8 +543,8 @@ void CallSessionPrivate::handleIncomingReceivedStateInIncomingNotification () { /* Try to be best-effort in giving real local or routable contact address for 100Rel case */ setContactOp(); if (notifyRinging) - op->notify_ringing(false); - if (op->get_replaces() && lp_config_get_int(linphone_core_get_config(q->getCore()->getCCore()), "sip", "auto_answer_replacing_calls", 1)) + op->notifyRinging(false); + if (op->getReplaces() && lp_config_get_int(linphone_core_get_config(q->getCore()->getCCore()), "sip", "auto_answer_replacing_calls", 1)) q->accept(); } @@ -648,9 +647,9 @@ LinphoneStatus CallSessionPrivate::startUpdate (const string &subject) { } if (destProxy && destProxy->op) { /* Give a chance to update the contact address if connectivity has changed */ - op->set_contact_address(destProxy->op->get_contact_address()); + op->setContactAddress(destProxy->op->getContactAddress()); } else - op->set_contact_address(nullptr); + op->setContactAddress(nullptr); return op->update(newSubject.c_str(), q->getParams()->getPrivate()->getNoUserConsent()); } @@ -704,7 +703,7 @@ void CallSessionPrivate::setContactOp () { for (auto it = contactParams.begin(); it != contactParams.end(); it++) linphone_address_set_param(contact, it->first.c_str(), it->second.empty() ? nullptr : it->second.c_str()); salAddress = const_cast(L_GET_PRIVATE_FROM_C_OBJECT(contact)->getInternalAddress()); - op->set_contact_address(salAddress); + op->setContactAddress(salAddress); linphone_address_unref(contact); } } @@ -738,12 +737,12 @@ void CallSessionPrivate::createOpTo (const LinphoneAddress *to) { if (op) op->release(); op = new SalCallOp(q->getCore()->getCCore()->sal); - op->set_user_pointer(q); + op->setUserPointer(q); if (params->getPrivate()->getReferer()) - op->set_referer(params->getPrivate()->getReferer()->getPrivate()->getOp()); + op->setReferrer(params->getPrivate()->getReferer()->getPrivate()->getOp()); linphone_configure_op(q->getCore()->getCCore(), op, to, q->getParams()->getPrivate()->getCustomHeaders(), false); if (q->getParams()->getPrivacy() != LinphonePrivacyDefault) - op->set_privacy((SalPrivacyMask)q->getParams()->getPrivacy()); + op->setPrivacy((SalPrivacyMask)q->getParams()->getPrivacy()); /* else privacy might be set by proxy */ } @@ -752,13 +751,13 @@ void CallSessionPrivate::createOpTo (const LinphoneAddress *to) { LinphoneAddress * CallSessionPrivate::getFixedContact () const { L_Q(); LinphoneAddress *result = nullptr; - if (op && op->get_contact_address()) { + if (op && op->getContactAddress()) { /* If already choosed, don't change it */ return nullptr; - } else if (pingOp && pingOp->get_contact_address()) { + } else if (pingOp && pingOp->getContactAddress()) { /* If the ping OPTIONS request succeeded use the contact guessed from the received, rport */ lInfo() << "Contact has been fixed using OPTIONS"; - char *addr = sal_address_as_string(pingOp->get_contact_address()); + char *addr = sal_address_as_string(pingOp->getContactAddress()); result = linphone_address_new(addr); ms_free(addr); } else if (destProxy && destProxy->op && linphone_proxy_config_get_contact(destProxy)) { @@ -787,12 +786,12 @@ void CallSessionPrivate::reinviteToRecoverFromConnectionLoss () { void CallSessionPrivate::repairByInviteWithReplaces () { L_Q(); - const char *callId = op->get_call_id(); - const char *fromTag = op->get_local_tag(); - const char *toTag = op->get_remote_tag(); - op->kill_dialog(); + string callId = op->getCallId(); + const char *fromTag = op->getLocalTag(); + const char *toTag = op->getRemoteTag(); + op->killDialog(); createOp(); - op->set_replaces(callId, fromTag, toTag); + op->setReplaces(callId.c_str(), fromTag, toTag); q->startInvite(nullptr); } @@ -820,9 +819,9 @@ void CallSessionPrivate::repairIfBroken () { switch (state) { case CallSession::State::Updating: case CallSession::State::Pausing: - if (op->dialog_request_pending()) { + if (op->dialogRequestPending()) { // Need to cancel first re-INVITE as described in section 5.5 of RFC 6141 - if (op->cancel_invite() == 0){ + if (op->cancelInvite() == 0){ reinviteOnCancelResponseRequested = true; } } @@ -830,19 +829,19 @@ void CallSessionPrivate::repairIfBroken () { case CallSession::State::StreamsRunning: case CallSession::State::Paused: case CallSession::State::PausedByRemote: - if (!op->dialog_request_pending()) + if (!op->dialogRequestPending()) reinviteToRecoverFromConnectionLoss(); break; case CallSession::State::UpdatedByRemote: - if (op->dialog_request_pending()) { + if (op->dialogRequestPending()) { sal_error_info_set(&sei, SalReasonServiceUnavailable, "SIP", 0, nullptr, nullptr); - op->decline_with_error_info(&sei, nullptr); + op->declineWithErrorInfo(&sei, nullptr); } reinviteToRecoverFromConnectionLoss(); break; case CallSession::State::OutgoingInit: case CallSession::State::OutgoingProgress: - if (op->cancel_invite() == 0){ + if (op->cancelInvite() == 0){ reinviteOnCancelResponseRequested = true; } break; @@ -932,10 +931,13 @@ void CallSession::configure (LinphoneCallDir direction, LinphoneProxyConfig *cfg if (op) { /* We already have an op for incoming calls */ d->op = op; - d->op->set_user_pointer(this); - op->enable_cnx_ip_to_0000_if_sendonly(!!lp_config_get_default_int(linphone_core_get_config(getCore()->getCCore()), - "sip", "cnx_ip_to_0000_if_sendonly_enabled", 0)); - d->log->call_id = ms_strdup(op->get_call_id()); /* Must be known at that time */ + d->op->setUserPointer(this); + op->enableCnxIpTo0000IfSendOnly( + !!lp_config_get_default_int( + linphone_core_get_config(getCore()->getCCore()), "sip", "cnx_ip_to_0000_if_sendonly_enabled", 0 + ) + ); + d->log->call_id = ms_strdup(op->getCallId().c_str()); /* Must be known at that time */ } if (direction == LinphoneCallOutgoing) { @@ -969,7 +971,7 @@ LinphoneStatus CallSession::decline (const LinphoneErrorInfo *ei) { } if (ei) { linphone_error_info_to_sal(ei, &sei); - d->op->decline_with_error_info(&sei , nullptr); + d->op->declineWithErrorInfo(&sei , nullptr); } else d->op->decline(SalReasonDeclined, nullptr); sal_error_info_reset(&sei); @@ -1054,7 +1056,7 @@ LinphoneStatus CallSession::redirect (const Address &redirectAddr) { SalErrorInfo sei; memset(&sei, 0, sizeof(sei)); sal_error_info_set(&sei, SalReasonRedirect, "SIP", 0, nullptr, nullptr); - d->op->decline_with_error_info(&sei, redirectAddr.getPrivate()->getInternalAddress()); + d->op->declineWithErrorInfo(&sei, redirectAddr.getPrivate()->getInternalAddress()); linphone_error_info_set(d->ei, nullptr, LinphoneReasonMovedPermanently, 302, "Call redirected", nullptr); d->nonOpError = true; d->terminate(); @@ -1097,7 +1099,7 @@ int CallSession::startInvite (const Address *destination, const string &subject, /* Take a ref because sal_call() may destroy the CallSession if no SIP transport is available */ shared_ptr ref = getSharedFromThis(); if (content) - d->op->set_local_body(*content); + d->op->setLocalBody(*content); int result = d->op->call(from, destinationStr.c_str(), subject.empty() ? nullptr : subject.c_str()); ms_free(from); if (result < 0) { @@ -1107,7 +1109,7 @@ int CallSession::startInvite (const Address *destination, const string &subject, d->setState(CallSession::State::Error, "Call failed"); } } else { - d->log->call_id = ms_strdup(d->op->get_call_id()); /* Must be known at that time */ + d->log->call_id = ms_strdup(d->op->getCallId().c_str()); /* Must be known at that time */ d->setState(CallSession::State::OutgoingProgress, "Outgoing call in progress"); } return result; @@ -1135,7 +1137,7 @@ LinphoneStatus CallSession::terminate (const LinphoneErrorInfo *ei) { default: if (ei) { linphone_error_info_to_sal(ei, &sei); - d->op->terminate_with_error(&sei); + d->op->terminate(&sei); sal_error_info_reset(&sei); } else d->op->terminate(); @@ -1148,7 +1150,7 @@ LinphoneStatus CallSession::terminate (const LinphoneErrorInfo *ei) { LinphoneStatus CallSession::transfer (const shared_ptr &dest) { L_D(); - int result = d->op->refer_with_replaces(dest->getPrivate()->op); + int result = d->op->referWithReplaces(dest->getPrivate()->op); d->setTransferState(CallSession::State::OutgoingInit); return result; } @@ -1176,7 +1178,7 @@ LinphoneStatus CallSession::update (const CallSessionParams *csp, const string & lWarning() << "CallSession::update() is given the current params, this is probably not what you intend to do!"; if (csp) d->setParams(new CallSessionParams(*csp)); - d->op->set_local_body(content ? *content : Content()); + d->op->setLocalBody(content ? *content : Content()); LinphoneStatus result = d->startUpdate(subject); if (result && (d->state != initialState)) { /* Restore initial state */ @@ -1195,7 +1197,7 @@ LinphoneCallDir CallSession::getDirection () const { const Address& CallSession::getDiversionAddress () const { L_D(); if (d->op) { - char *addrStr = sal_address_as_string(d->op->get_diversion_address()); + char *addrStr = sal_address_as_string(d->op->getDiversionAddress()); d->diversionAddress = Address(addrStr); bctbx_free(addrStr); } else { @@ -1258,7 +1260,7 @@ string CallSession::getRemoteContact () const { L_D(); if (d->op) { /* sal_op_get_remote_contact preserves header params */ - return d->op->get_remote_contact(); + return d->op->getRemoteContact(); } return string(); } @@ -1268,7 +1270,7 @@ const Address *CallSession::getRemoteContactAddress () const { if (!d->op) { return nullptr; } - char *addrStr = sal_address_as_string(d->op->get_remote_contact_address()); + char *addrStr = sal_address_as_string(d->op->getRemoteContactAddress()); d->remoteContactAddress = Address(addrStr); bctbx_free(addrStr); return &d->remoteContactAddress; @@ -1277,7 +1279,7 @@ const Address *CallSession::getRemoteContactAddress () const { const CallSessionParams * CallSession::getRemoteParams () { L_D(); if (d->op){ - const SalCustomHeader *ch = d->op->get_recv_custom_header(); + const SalCustomHeader *ch = d->op->getRecvCustomHeaders(); if (ch) { /* Instanciate a remote_params only if a SIP message was received before (custom headers indicates this) */ if (!d->remoteParams) @@ -1301,7 +1303,7 @@ CallSession::State CallSession::getPreviousState () const { const Address& CallSession::getToAddress () const { L_D(); - d->toAddress = Address(d->op->get_to()); + d->toAddress = Address(d->op->getTo()); return d->toAddress; } @@ -1317,24 +1319,24 @@ shared_ptr CallSession::getTransferTarget () const { string CallSession::getToHeader (const string &name) const { L_D(); - return L_C_TO_STRING(sal_custom_header_find(d->op->get_recv_custom_header(), name.c_str())); + return L_C_TO_STRING(sal_custom_header_find(d->op->getRecvCustomHeaders(), name.c_str())); } // ----------------------------------------------------------------------------- string CallSession::getRemoteUserAgent () const { L_D(); - if (d->op && d->op->get_remote_ua()) - return d->op->get_remote_ua(); + if (d->op) + return d->op->getRemoteUserAgent(); return string(); } shared_ptr CallSession::getReplacedCallSession () const { L_D(); - SalOp *replacedOp = d->op->get_replaces(); + SalOp *replacedOp = d->op->getReplaces(); if (!replacedOp) return nullptr; - return reinterpret_cast(replacedOp->get_user_pointer())->getSharedFromThis(); + return reinterpret_cast(replacedOp->getUserPointer())->getSharedFromThis(); } CallSessionParams * CallSession::getCurrentParams () const { diff --git a/src/conference/session/media-session-p.h b/src/conference/session/media-session-p.h index 7013e7b18..efdfe04fd 100644 --- a/src/conference/session/media-session-p.h +++ b/src/conference/session/media-session-p.h @@ -106,6 +106,9 @@ public: // CoreListener void onNetworkReachable (bool sipNetworkReachable, bool mediaNetworkReachable) override; + // Call listener + void snapshotTakenCb(void *userdata, struct _MSFilter *f, unsigned int id, void *arg); + private: static OrtpJitterBufferAlgorithm jitterBufferNameToAlgo (const std::string &name); diff --git a/src/conference/session/media-session.cpp b/src/conference/session/media-session.cpp index 853d6ffc4..c0d1741d8 100644 --- a/src/conference/session/media-session.cpp +++ b/src/conference/session/media-session.cpp @@ -83,8 +83,8 @@ void MediaSessionPrivate::accepted () { linphone_task_list_init(&tl); /* Reset the internal call update flag, so it doesn't risk to be copied and used in further re-INVITEs */ getParams()->getPrivate()->setInternalCallUpdate(false); - SalMediaDescription *rmd = op->get_remote_media_description(); - SalMediaDescription *md = op->get_final_media_description(); + SalMediaDescription *rmd = op->getRemoteMediaDescription(); + SalMediaDescription *md = op->getFinalMediaDescription(); if (!md && (prevState == CallSession::State::OutgoingEarlyMedia) && resultDesc) { lInfo() << "Using early media SDP since none was received with the 200 OK"; md = resultDesc; @@ -95,7 +95,7 @@ void MediaSessionPrivate::accepted () { /* There is a valid SDP in the response, either offer or answer, and we're able to start/update the streams */ if (rmd) { /* Handle remote ICE attributes if any. */ - iceAgent->updateFromRemoteMediaDescription(localDesc, rmd, !op->is_offerer()); + iceAgent->updateFromRemoteMediaDescription(localDesc, rmd, !op->isOfferer()); } CallSession::State nextState = CallSession::State::Idle; string nextStateMsg; @@ -199,7 +199,7 @@ void MediaSessionPrivate::dtmfReceived (char dtmf) { bool MediaSessionPrivate::failure () { L_Q(); - const SalErrorInfo *ei = op->get_error_info(); + const SalErrorInfo *ei = op->getErrorInfo(); switch (ei->reason) { case SalReasonRedirect: stopStreams(); @@ -276,9 +276,10 @@ void MediaSessionPrivate::pausedByRemote () { void MediaSessionPrivate::remoteRinging () { L_Q(); /* Set privacy */ - getCurrentParams()->setPrivacy((LinphonePrivacyMask)op->get_privacy()); - SalMediaDescription *md = op->get_final_media_description(); + getCurrentParams()->setPrivacy((LinphonePrivacyMask)op->getPrivacy()); + SalMediaDescription *md = op->getFinalMediaDescription(); if (md) { + SalMediaDescription *rmd = op->getRemoteMediaDescription(); /* Initialize the remote call params by invoking linphone_call_get_remote_params(). This is useful as the SDP may not be present in the 200Ok */ q->getRemoteParams(); /* Accept early media */ @@ -300,6 +301,7 @@ void MediaSessionPrivate::remoteRinging () { if (listener) listener->onStopRinging(q->getSharedFromThis()); lInfo() << "Doing early media..."; + iceAgent->updateFromRemoteMediaDescription(localDesc, rmd, !op->isOfferer()); updateStreams(md, state); if ((q->getCurrentParams()->getAudioDirection() == LinphoneMediaDirectionInactive) && audioStream) { if (listener) @@ -323,7 +325,7 @@ int MediaSessionPrivate::resumeAfterFailedTransfer () { if (automaticallyPaused && (state == CallSession::State::Pausing)) return BELLE_SIP_CONTINUE; // Was still in pausing state if (automaticallyPaused && (state == CallSession::State::Paused)) { - if (op->is_idle()) + if (op->isIdle()) q->resume(); else { lInfo() << "MediaSessionPrivate::resumeAfterFailedTransfer(), op was busy"; @@ -359,7 +361,7 @@ void MediaSessionPrivate::terminated () { /* This callback is called when an incoming re-INVITE/ SIP UPDATE modifies the session */ void MediaSessionPrivate::updated (bool isUpdate) { - SalMediaDescription *rmd = op->get_remote_media_description(); + SalMediaDescription *rmd = op->getRemoteMediaDescription(); switch (state) { case CallSession::State::PausedByRemote: if (sal_media_description_has_dir(rmd, SalStreamSendRecv) || sal_media_description_has_dir(rmd, SalStreamRecvOnly)) { @@ -386,7 +388,7 @@ void MediaSessionPrivate::updated (bool isUpdate) { void MediaSessionPrivate::updating (bool isUpdate) { L_Q(); - SalMediaDescription *rmd = op->get_remote_media_description(); + SalMediaDescription *rmd = op->getRemoteMediaDescription(); fixCallParams(rmd); if (state != CallSession::State::Paused) { /* Refresh the local description, but in paused state, we don't change anything. */ @@ -396,16 +398,16 @@ void MediaSessionPrivate::updating (bool isUpdate) { params->initDefault(q->getCore()); } makeLocalMediaDescription(); - op->set_local_media_description(localDesc); + op->setLocalMediaDescription(localDesc); } if (rmd) { SalErrorInfo sei; memset(&sei, 0, sizeof(sei)); expectMediaInAck = false; - SalMediaDescription *md = op->get_final_media_description(); + SalMediaDescription *md = op->getFinalMediaDescription(); if (md && (sal_media_description_empty(md) || linphone_core_incompatible_security(q->getCore()->getCCore(), md))) { sal_error_info_set(&sei, SalReasonNotAcceptable, "SIP", 0, nullptr, nullptr); - op->decline_with_error_info(&sei, nullptr); + op->declineWithErrorInfo(&sei, nullptr); sal_error_info_reset(&sei); return; } @@ -415,7 +417,7 @@ void MediaSessionPrivate::updating (bool isUpdate) { if (diff & (SAL_MEDIA_DESCRIPTION_CRYPTO_POLICY_CHANGED | SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED)) { lWarning() << "Cannot accept this update, it is changing parameters that require user approval"; sal_error_info_set(&sei, SalReasonUnknown, "SIP", 504, "Cannot change the session parameters without prompting the user", nullptr); - op->decline_with_error_info(&sei, nullptr); + op->declineWithErrorInfo(&sei, nullptr); sal_error_info_reset(&sei); return; } @@ -704,31 +706,29 @@ shared_ptr MediaSessionPrivate::getMe () const { void MediaSessionPrivate::setState (CallSession::State newState, const string &message) { L_Q(); - SalMediaDescription *rmd; - - lInfo()<<"MediaSessionPrivate::setState"; - - /* Take a ref on the session otherwise it might get destroyed during the call to setState */ + + // Take a ref on the session otherwise it might get destroyed during the call to setState shared_ptr sessionRef = q->getSharedFromThis(); if ((newState != state) && (newState != CallSession::State::StreamsRunning)) q->cancelDtmfs(); CallSessionPrivate::setState(newState, message); if (listener) listener->onCallSessionStateChangedForReporting(q->getSharedFromThis()); - switch(newState){ + SalMediaDescription *rmd = nullptr; + switch (newState) { case CallSession::State::UpdatedByRemote: - /*Handle specifically the case of an incoming ICE-concluded reINVITE*/ - lInfo()<<"Checking for ICE reINVITE"; - rmd = op->get_remote_media_description(); - if (iceAgent && rmd != nullptr && iceAgent->checkIceReinviteNeedsDeferedResponse(rmd)){ + // Handle specifically the case of an incoming ICE-concluded reINVITE + lInfo() << "Checking for ICE reINVITE"; + rmd = op->getRemoteMediaDescription(); + if (iceAgent && rmd && iceAgent->checkIceReinviteNeedsDeferedResponse(rmd)) { deferUpdate = true; deferUpdateInternal = true; incomingIceReinvitePending = true; - lInfo()<<"CallSession [" << q << "]: ICE reinvite received, but one or more check-lists are not completed. Response will be sent later, when ICE has completed"; + lInfo() << "CallSession [" << q << "]: ICE reinvite received, but one or more check-lists are not completed. Response will be sent later, when ICE has completed"; } - break; + break; default: - break; + break; } } @@ -880,12 +880,12 @@ void MediaSessionPrivate::initializeParamsAccordingToIncomingCallParams () { CallSessionPrivate::initializeParamsAccordingToIncomingCallParams(); getCurrentParams()->getPrivate()->setUpdateCallWhenIceCompleted(getParams()->getPrivate()->getUpdateCallWhenIceCompleted()); getParams()->enableVideo(linphone_core_video_enabled(q->getCore()->getCCore()) && q->getCore()->getCCore()->video_policy.automatically_accept); - SalMediaDescription *md = op->get_remote_media_description(); + SalMediaDescription *md = op->getRemoteMediaDescription(); if (md) { /* It is licit to receive an INVITE without SDP, in this case WE choose the media parameters according to policy */ setCompatibleIncomingCallParams(md); /* Set multicast role & address if any */ - if (!op->is_offerer()) { + if (!op->isOfferer()) { for (int i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) { if (md->streams[i].dir == SalStreamInactive) continue; @@ -938,7 +938,7 @@ void MediaSessionPrivate::updateBiggestDesc (SalMediaDescription *md) { } void MediaSessionPrivate::updateRemoteSessionIdAndVer () { - SalMediaDescription *desc = op->get_remote_media_description(); + SalMediaDescription *desc = op->getRemoteMediaDescription(); if (desc) { remoteSessionId = desc->session_id; remoteSessionVer = desc->session_ver; @@ -1129,12 +1129,12 @@ string MediaSessionPrivate::getBindIpForStream (int streamIndex) { /* As multicast sender, we must decide a local interface to use to send multicast, and bind to it */ char multicastBindIp[LINPHONE_IPADDR_SIZE]; memset(multicastBindIp, 0, sizeof(multicastBindIp)); - linphone_core_get_local_ip_for(pc->multicastIp.find_first_of(':') ? AF_INET6 : AF_INET, nullptr, multicastBindIp); + linphone_core_get_local_ip_for((pc->multicastIp.find_first_of(':') == string::npos) ? AF_INET : AF_INET6, nullptr, multicastBindIp); bindIp = pc->multicastBindIp = multicastBindIp; } else { /* Otherwise we shall use an address family of the same family of the multicast address, because * dual stack socket and multicast don't work well on Mac OS (linux is OK, as usual). */ - bindIp = pc->multicastIp.find_first_of(':') ? "::0" : "0.0.0.0"; + bindIp = (pc->multicastIp.find_first_of(':') == string::npos) ? "0.0.0.0" : "::0"; } } return bindIp; @@ -1155,7 +1155,7 @@ void MediaSessionPrivate::getLocalIp (const Address &remoteAddr) { /* If a known proxy was identified for this call, then we may have a chance to take the local ip address * from the socket that connects to this proxy */ if (destProxy && destProxy->op) { - ip = destProxy->op->get_local_address(nullptr); + ip = destProxy->op->getLocalAddress(nullptr); if (ip) { lInfo() << "Found media local-ip from signaling."; mediaLocalIp = ip; @@ -1175,7 +1175,7 @@ void MediaSessionPrivate::getLocalIp (const Address &remoteAddr) { hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = AI_NUMERICHOST; - err = getaddrinfo(remoteAddr.getDomain().c_str(), NULL, &hints, &res); + err = getaddrinfo(remoteAddr.getDomain().c_str(), nullptr, &hints, &res); if (err == 0) dest = remoteAddr.getDomain().c_str(); if (res) freeaddrinfo(res); @@ -1216,9 +1216,9 @@ void MediaSessionPrivate::selectIncomingIpVersion () { L_Q(); if (linphone_core_ipv6_enabled(q->getCore()->getCCore())) { if (destProxy && destProxy->op) - af = destProxy->op->get_address_family(); + af = destProxy->op->getAddressFamily(); else - af = op->get_address_family(); + af = op->getAddressFamily(); } else af = AF_INET; } @@ -1242,16 +1242,16 @@ void MediaSessionPrivate::selectOutgoingIpVersion () { if (sal_address_is_ipv6(L_GET_PRIVATE_FROM_C_OBJECT(to)->getInternalAddress())) af = AF_INET6; else if (destProxy && destProxy->op) - af = destProxy->op->get_address_family(); + af = destProxy->op->getAddressFamily(); else { char ipv4[LINPHONE_IPADDR_SIZE]; char ipv6[LINPHONE_IPADDR_SIZE]; bool haveIpv6 = false; bool haveIpv4 = false; /* Check connectivity for IPv4 and IPv6 */ - if (linphone_core_get_local_ip_for(AF_INET6, NULL, ipv6) == 0) + if (linphone_core_get_local_ip_for(AF_INET6, nullptr, ipv6) == 0) haveIpv6 = true; - if (linphone_core_get_local_ip_for(AF_INET, NULL, ipv4) == 0) + if (linphone_core_get_local_ip_for(AF_INET, nullptr, ipv4) == 0) haveIpv4 = true; if (haveIpv6) { if (!haveIpv4) @@ -1667,15 +1667,15 @@ SalMulticastRole MediaSessionPrivate::getMulticastRole (SalStreamType type) { SalMulticastRole multicastRole = SalMulticastInactive; if (op) { SalStreamDescription *streamDesc = nullptr; - SalMediaDescription *remoteDesc = op->get_remote_media_description(); + SalMediaDescription *remoteDesc = op->getRemoteMediaDescription(); if (!localDesc && !remoteDesc && (direction == LinphoneCallOutgoing)) { /* Well using call dir */ if (((type == SalAudio) && getParams()->audioMulticastEnabled()) || ((type == SalVideo) && getParams()->videoMulticastEnabled())) multicastRole = SalMulticastSender; - } else if (localDesc && (!remoteDesc || op->is_offerer())) { + } else if (localDesc && (!remoteDesc || op->isOfferer())) { streamDesc = sal_media_description_find_best_stream(localDesc, type); - } else if (!op->is_offerer() && remoteDesc) { + } else if (!op->isOfferer() && remoteDesc) { streamDesc = sal_media_description_find_best_stream(remoteDesc, type); } @@ -1717,8 +1717,8 @@ void MediaSessionPrivate::setDtlsFingerprint (MSMediaStreamSessions *sessions, c } void MediaSessionPrivate::setDtlsFingerprintOnAllStreams () { - SalMediaDescription *remote = op->get_remote_media_description(); - SalMediaDescription *result = op->get_final_media_description(); + SalMediaDescription *remote = op->getRemoteMediaDescription(); + SalMediaDescription *result = op->getFinalMediaDescription(); if (!remote || !result) { /* This can happen in some tricky cases (early-media without SDP in the 200). In that case, simply skip DTLS code */ return; @@ -1830,8 +1830,8 @@ void MediaSessionPrivate::startDtls (MSMediaStreamSessions *sessions, const SalS } void MediaSessionPrivate::startDtlsOnAllStreams () { - SalMediaDescription *remote = op->get_remote_media_description(); - SalMediaDescription *result = op->get_final_media_description(); + SalMediaDescription *remote = op->getRemoteMediaDescription(); + SalMediaDescription *result = op->getFinalMediaDescription(); if (!remote || !result) { /* This can happen in some tricky cases (early-media without SDP in the 200). In that case, simply skip DTLS code */ return; @@ -1997,7 +1997,7 @@ void MediaSessionPrivate::applyJitterBufferParams (RtpSession *session, Linphone JBParameters params; rtp_session_get_jitter_buffer_params(session, ¶ms); params.min_size = lp_config_get_int(config, "rtp", "jitter_buffer_min_size", 40); - params.max_size = lp_config_get_int(config, "rtp", "jitter_buffer_max_size", 250); + params.max_size = lp_config_get_int(config, "rtp", "jitter_buffer_max_size", 500); params.max_packets = params.max_size * 200 / 1000; /* Allow 200 packet per seconds, quite large */ const char *algo = lp_config_get_string(config, "rtp", "jitter_buffer_algorithm", "rls"); params.buffer_algorithm = jitterBufferNameToAlgo(algo ? algo : ""); @@ -2100,7 +2100,7 @@ void MediaSessionPrivate::configureRtpSessionForRtcpFb (const SalStreamDescripti } void MediaSessionPrivate::configureRtpSessionForRtcpXr (SalStreamType type) { - SalMediaDescription *remote = op->get_remote_media_description(); + SalMediaDescription *remote = op->getRemoteMediaDescription(); if (!remote) return; const SalStreamDescription *localStream = sal_media_description_find_best_stream(localDesc, type); @@ -2242,7 +2242,7 @@ void MediaSessionPrivate::handleIceEvents (OrtpEvent *ev) { case CallSession::State::Idle: stopStreamsForIceGathering(); updateLocalMediaDescriptionFromIce(); - op->set_local_media_description(localDesc); + op->setLocalMediaDescription(localDesc); deferIncomingNotification = false; startIncomingNotification(); break; @@ -2356,7 +2356,7 @@ void MediaSessionPrivate::initializeAudioStream () { SalMediaDescription *remoteDesc = nullptr; SalStreamDescription *streamDesc = nullptr; if (op) - remoteDesc = op->get_remote_media_description(); + remoteDesc = op->getRemoteMediaDescription(); if (remoteDesc) streamDesc = sal_media_description_find_best_stream(remoteDesc, SalAudio); @@ -2386,8 +2386,10 @@ void MediaSessionPrivate::initializeAudioStream () { params.limeKeyTimeSpan = bctbx_time_string_to_sec(lp_config_get_string(linphone_core_get_config(q->getCore()->getCCore()), "sip", "lime_key_validity", "0")); setZrtpCryptoTypesParameters(¶ms); audio_stream_enable_zrtp(audioStream, ¶ms); - if (peerUri != NULL) ms_free(peerUri); - if (selfUri != NULL) ms_free(selfUri); + if (peerUri) + ms_free(peerUri); + if (selfUri) + ms_free(selfUri); } media_stream_reclaim_sessions(&audioStream->ms, &sessions[mainAudioStreamIndex]); @@ -2460,7 +2462,7 @@ void MediaSessionPrivate::initializeTextStream () { SalMediaDescription *remoteDesc = nullptr; SalStreamDescription *streamDesc = nullptr; if (op) - remoteDesc = op->get_remote_media_description(); + remoteDesc = op->getRemoteMediaDescription(); if (remoteDesc) streamDesc = sal_media_description_find_best_stream(remoteDesc, SalText); @@ -2504,7 +2506,7 @@ void MediaSessionPrivate::initializeVideoStream () { SalMediaDescription *remoteDesc = nullptr; SalStreamDescription *streamDesc = nullptr; if (op) - remoteDesc = op->get_remote_media_description(); + remoteDesc = op->getRemoteMediaDescription(); if (remoteDesc) streamDesc = sal_media_description_find_best_stream(remoteDesc, SalVideo); @@ -2744,7 +2746,7 @@ void MediaSessionPrivate::startAudioStream (CallSession::State targetState, bool getCurrentParams()->getPrivate()->setInConference(getParams()->getPrivate()->getInConference()); getCurrentParams()->enableLowBandwidth(getParams()->lowBandwidthEnabled()); // Start ZRTP engine if needed : set here or remote have a zrtp-hash attribute - SalMediaDescription *remote = op->get_remote_media_description(); + SalMediaDescription *remote = op->getRemoteMediaDescription(); const SalStreamDescription *remoteStream = sal_media_description_find_best_stream(remote, SalAudio); if (linphone_core_media_encryption_supported(q->getCore()->getCCore(), LinphoneMediaEncryptionZRTP) && ((getParams()->getMediaEncryption() == LinphoneMediaEncryptionZRTP) || (remoteStream->haveZrtpHash == 1))) { @@ -2863,7 +2865,7 @@ void MediaSessionPrivate::startTextStream () { configureRtpSessionForRtcpFb(tstream); configureRtpSessionForRtcpXr(SalText); rtp_session_enable_rtcp_mux(textStream->ms.sessions.rtp_session, tstream->rtcp_mux); - bool_t isMulticast = ms_is_multicast(rtpAddr); + bool isMulticast = !!ms_is_multicast(rtpAddr); if (isMulticast) rtp_session_set_multicast_ttl(textStream->ms.sessions.rtp_session, tstream->ttl); text_stream_start(textStream, textProfile, rtpAddr, tstream->rtp_port, rtcpAddr, @@ -2996,7 +2998,7 @@ void MediaSessionPrivate::startVideoStream (CallSession::State targetState) { if (listener) listener->onResetFirstVideoFrameDecoded(q->getSharedFromThis()); /* Start ZRTP engine if needed : set here or remote have a zrtp-hash attribute */ - SalMediaDescription *remote = op->get_remote_media_description(); + SalMediaDescription *remote = op->getRemoteMediaDescription(); const SalStreamDescription *remoteStream = sal_media_description_find_best_stream(remote, SalVideo); if ((getParams()->getMediaEncryption() == LinphoneMediaEncryptionZRTP) || (remoteStream->haveZrtpHash == 1)) { /* Audio stream is already encrypted and video stream is active */ @@ -3342,7 +3344,7 @@ uint16_t MediaSessionPrivate::getAvpfRrInterval () const { unsigned int MediaSessionPrivate::getNbActiveStreams () const { SalMediaDescription *md = nullptr; if (op) - md = op->get_remote_media_description(); + md = op->getRemoteMediaDescription(); if (!md) return 0; return sal_media_description_nb_active_streams_of_type(md, SalAudio) + sal_media_description_nb_active_streams_of_type(md, SalVideo) + sal_media_description_nb_active_streams_of_type(md, SalText); @@ -3526,8 +3528,8 @@ void MediaSessionPrivate::handleIncomingReceivedStateInIncomingNotification () { if (proposeEarlyMedia) q->acceptEarlyMedia(); else - op->notify_ringing(false); - if (op->get_replaces() && !!lp_config_get_int(linphone_core_get_config(q->getCore()->getCCore()), "sip", "auto_answer_replacing_calls", 1)) + op->notifyRinging(false); + if (op->getReplaces() && !!lp_config_get_int(linphone_core_get_config(q->getCore()->getCCore()), "sip", "auto_answer_replacing_calls", 1)) q->accept(); } @@ -3560,7 +3562,7 @@ LinphoneStatus MediaSessionPrivate::pause () { broken = false; setState(CallSession::State::Pausing, "Pausing call"); makeLocalMediaDescription(); - op->set_local_media_description(localDesc); + op->setLocalMediaDescription(localDesc); op->update(subject.c_str(), false); if (listener) listener->onResetCurrentSession(q->getSharedFromThis()); @@ -3588,9 +3590,9 @@ LinphoneStatus MediaSessionPrivate::startAcceptUpdate (CallSession::State nextSt } makeLocalMediaDescription(); updateRemoteSessionIdAndVer(); - op->set_local_media_description(localDesc); + op->setLocalMediaDescription(localDesc); op->accept(); - SalMediaDescription *md = op->get_final_media_description(); + SalMediaDescription *md = op->getFinalMediaDescription(); iceAgent->stopIceForInactiveStreams(md); if (md && !sal_media_description_empty(md)) updateStreams(md, nextState); @@ -3604,14 +3606,14 @@ LinphoneStatus MediaSessionPrivate::startUpdate (const string &subject) { if (!getParams()->getPrivate()->getNoUserConsent()) makeLocalMediaDescription(); if (!q->getCore()->getCCore()->sip_conf.sdp_200_ack) - op->set_local_media_description(localDesc); + op->setLocalMediaDescription(localDesc); else - op->set_local_media_description(nullptr); + op->setLocalMediaDescription(nullptr); LinphoneStatus result = CallSessionPrivate::startUpdate(subject); if (q->getCore()->getCCore()->sip_conf.sdp_200_ack) { /* We are NOT offering, set local media description after sending the call so that we are ready to * process the remote offer when it will arrive. */ - op->set_local_media_description(localDesc); + op->setLocalMediaDescription(localDesc); } return result; } @@ -3723,7 +3725,7 @@ void MediaSessionPrivate::accept (const MediaSessionParams *msp, bool wasRinging setParams(new MediaSessionParams(*msp)); iceAgent->prepare(localDesc, true); makeLocalMediaDescription(); - op->set_local_media_description(localDesc); + op->setLocalMediaDescription(localDesc); } updateRemoteSessionIdAndVer(); @@ -3744,7 +3746,7 @@ void MediaSessionPrivate::accept (const MediaSessionParams *msp, bool wasRinging CallSessionPrivate::accept(nullptr); - SalMediaDescription *newMd = op->get_final_media_description(); + SalMediaDescription *newMd = op->getFinalMediaDescription(); iceAgent->stopIceForInactiveStreams(newMd); if (newMd) { updateStreams(newMd, CallSession::State::StreamsRunning); @@ -3755,7 +3757,7 @@ void MediaSessionPrivate::accept (const MediaSessionParams *msp, bool wasRinging LinphoneStatus MediaSessionPrivate::acceptUpdate (const CallSessionParams *csp, CallSession::State nextState, const string &stateInfo) { L_Q(); - SalMediaDescription *desc = op->get_remote_media_description(); + SalMediaDescription *desc = op->getRemoteMediaDescription(); bool keepSdpVersion = !!lp_config_get_int(linphone_core_get_config(q->getCore()->getCCore()), "sip", "keep_sdp_version", 0); if (keepSdpVersion && (desc->session_id == remoteSessionId) && (desc->session_ver == remoteSessionVer)) { /* Remote has sent an INVITE with the same SDP as before, so send a 200 OK with the same SDP as before. */ @@ -3767,7 +3769,7 @@ LinphoneStatus MediaSessionPrivate::acceptUpdate (const CallSessionParams *csp, if (csp) setParams(new MediaSessionParams(*static_cast(csp))); else { - if (!op->is_offerer()) { + if (!op->isOfferer()) { /* Reset call params for multicast because this param is only relevant when offering */ getParams()->enableAudioMulticast(false); getParams()->enableVideoMulticast(false); @@ -3868,7 +3870,7 @@ int MediaSessionPrivate::sendDtmf () { } if (linphone_core_get_use_info_for_dtmf(lc)) { // Out of Band DTMF (use INFO method) - op->send_dtmf(dtmfSequence.front()); + op->sendDtmf(dtmfSequence.front()); } dtmfSequence.erase(0, 1); @@ -4017,12 +4019,12 @@ LinphoneStatus MediaSession::acceptEarlyMedia (const MediaSessionParams *msp) { if (msp) { d->setParams(new MediaSessionParams(*msp)); d->makeLocalMediaDescription(); - d->op->set_local_media_description(d->localDesc); - d->op->set_sent_custom_header(d->getParams()->getPrivate()->getCustomHeaders()); + d->op->setLocalMediaDescription(d->localDesc); + d->op->setSentCustomHeaders(d->getParams()->getPrivate()->getCustomHeaders()); } - d->op->notify_ringing(true); + d->op->notifyRinging(true); d->setState(CallSession::State::IncomingEarlyMedia, "Incoming call early media"); - SalMediaDescription *md = d->op->get_final_media_description(); + SalMediaDescription *md = d->op->getFinalMediaDescription(); if (md) d->updateStreams(md, d->state); return 0; @@ -4042,7 +4044,7 @@ void MediaSession::cancelDtmfs () { if (!d->dtmfTimer) return; - getCore()->getCCore()->sal->cancel_timer(d->dtmfTimer); + getCore()->getCCore()->sal->cancelTimer(d->dtmfTimer); belle_sip_object_unref(d->dtmfTimer); d->dtmfTimer = nullptr; d->dtmfSequence.clear(); @@ -4078,7 +4080,7 @@ void MediaSession::configure (LinphoneCallDir direction, LinphoneProxyConfig *cf d->setParams(new MediaSessionParams()); d->params->initDefault(getCore()); d->initializeParamsAccordingToIncomingCallParams(); - SalMediaDescription *md = d->op->get_remote_media_description(); + SalMediaDescription *md = d->op->getRemoteMediaDescription(); if (d->natPolicy && linphone_nat_policy_ice_enabled(d->natPolicy)) { if (md) { /* Create the ice session now if ICE is required */ @@ -4179,9 +4181,9 @@ LinphoneStatus MediaSession::resume () { d->makeLocalMediaDescription(); sal_media_description_set_dir(d->localDesc, SalStreamSendRecv); if (!getCore()->getCCore()->sip_conf.sdp_200_ack) - d->op->set_local_media_description(d->localDesc); + d->op->setLocalMediaDescription(d->localDesc); else - d->op->set_local_media_description(nullptr); + d->op->setLocalMediaDescription(nullptr); string subject = "Call resuming"; if (d->getParams()->getPrivate()->getInConference() && !getCurrentParams()->getPrivate()->getInConference()) subject = "Conference"; @@ -4193,7 +4195,7 @@ LinphoneStatus MediaSession::resume () { if (getCore()->getCCore()->sip_conf.sdp_200_ack) { /* We are NOT offering, set local media description after sending the call so that we are ready to * process the remote offer when it will arrive. */ - d->op->set_local_media_description(d->localDesc); + d->op->setLocalMediaDescription(d->localDesc); } return 0; } @@ -4216,7 +4218,7 @@ LinphoneStatus MediaSession::sendDtmfs (const std::string &dtmfs) { if (delayMs < 0) delayMs = 0; d->dtmfSequence = dtmfs; - d->dtmfTimer = getCore()->getCCore()->sal->create_timer(MediaSessionPrivate::sendDtmf, this, static_cast(delayMs), "DTMF sequence timer"); + d->dtmfTimer = getCore()->getCCore()->sal->createTimer(MediaSessionPrivate::sendDtmf, this, static_cast(delayMs), "DTMF sequence timer"); } return 0; } @@ -4225,6 +4227,11 @@ void MediaSession::sendVfuRequest () { #ifdef VIDEO_ENABLED L_D(); MediaSessionParams *curParams = getCurrentParams(); + + if (d->videoStream && d->videoStream->ms.decoder) { + ms_filter_call_method_noarg(d->videoStream->ms.decoder, MS_VIDEO_DECODER_RESET_FIRST_IMAGE_NOTIFICATION); + } + if ((curParams->avpfEnabled() || curParams->getPrivate()->implicitRtcpFbEnabled()) && d->videoStream && media_stream_get_state(&d->videoStream->ms) == MSStreamStarted) { // || sal_media_description_has_implicit_avpf((const SalMediaDescription *)call->resultdesc) lInfo() << "Request Full Intra Request on CallSession [" << this << "]"; @@ -4232,7 +4239,7 @@ void MediaSession::sendVfuRequest () { } else if (getCore()->getCCore()->sip_conf.vfu_with_info) { lInfo() << "Request SIP INFO FIR on CallSession [" << this << "]"; if (d->state == CallSession::State::StreamsRunning) - d->op->send_vfu_request(); + d->op->sendVfuRequest(); } else lInfo() << "vfu request using sip disabled from config [sip,vfu_with_info]"; #endif @@ -4241,8 +4248,8 @@ void MediaSession::sendVfuRequest () { void MediaSession::startIncomingNotification (bool notifyRinging) { L_D(); d->makeLocalMediaDescription(); - d->op->set_local_media_description(d->localDesc); - SalMediaDescription *md = d->op->get_final_media_description(); + d->op->setLocalMediaDescription(d->localDesc); + SalMediaDescription *md = d->op->getFinalMediaDescription(); if (md) { if (sal_media_description_empty(md) || linphone_core_incompatible_security(getCore()->getCCore(), md)) { LinphoneErrorInfo *ei = linphone_error_info_new(); @@ -4270,7 +4277,7 @@ int MediaSession::startInvite (const Address *destination, const string &subject } if (!getCore()->getCCore()->sip_conf.sdp_200_ack) { /* We are offering, set local media description before sending the call */ - d->op->set_local_media_description(d->localDesc); + d->op->setLocalMediaDescription(d->localDesc); } int result = CallSession::startInvite(destination, subject, content); @@ -4282,7 +4289,7 @@ int MediaSession::startInvite (const Address *destination, const string &subject if (getCore()->getCCore()->sip_conf.sdp_200_ack) { /* We are NOT offering, set local media description after sending the call so that we are ready to process the remote offer when it will arrive. */ - d->op->set_local_media_description(d->localDesc); + d->op->setLocalMediaDescription(d->localDesc); } return result; } @@ -4362,11 +4369,30 @@ void MediaSession::resetFirstVideoFrameDecoded () { ms_filter_call_method_noarg(d->videoStream->ms.decoder, MS_VIDEO_DECODER_RESET_FIRST_IMAGE_NOTIFICATION); } +void MediaSessionPrivate::snapshotTakenCb(void *userdata, struct _MSFilter *f, unsigned int id, void *arg) { +#ifdef VIDEO_ENABLED + L_Q(); + if (id == MS_JPEG_WRITER_SNAPSHOT_TAKEN) { + const char *filepath = (const char *) arg; + listener->onSnapshotTaken(q->getSharedFromThis(), filepath); + } +#endif +} + +#ifdef VIDEO_ENABLED +static void snapshot_taken(void *userdata, struct _MSFilter *f, unsigned int id, void *arg) { + MediaSessionPrivate *d = (MediaSessionPrivate *)userdata; + d->snapshotTakenCb(userdata, f, id, arg); +} +#endif + LinphoneStatus MediaSession::takePreviewSnapshot (const string& file) { #ifdef VIDEO_ENABLED L_D(); if (d->videoStream && d->videoStream->local_jpegwriter) { + ms_filter_clear_notify_callback(d->videoStream->jpegwriter); const char *filepath = file.empty() ? nullptr : file.c_str(); + ms_filter_add_notify_callback(d->videoStream->local_jpegwriter, snapshot_taken, d, TRUE); return ms_filter_call_method(d->videoStream->local_jpegwriter, MS_JPEG_WRITER_TAKE_SNAPSHOT, (void *)filepath); } lWarning() << "Cannot take local snapshot: no currently running video stream on this call"; @@ -4378,7 +4404,9 @@ LinphoneStatus MediaSession::takeVideoSnapshot (const string& file) { #ifdef VIDEO_ENABLED L_D(); if (d->videoStream && d->videoStream->jpegwriter) { + ms_filter_clear_notify_callback(d->videoStream->jpegwriter); const char *filepath = file.empty() ? nullptr : file.c_str(); + ms_filter_add_notify_callback(d->videoStream->jpegwriter, snapshot_taken, d, TRUE); return ms_filter_call_method(d->videoStream->jpegwriter, MS_JPEG_WRITER_TAKE_SNAPSHOT, (void *)filepath); } lWarning() << "Cannot take snapshot: no currently running video stream on this call"; @@ -4603,7 +4631,7 @@ float MediaSession::getRecordVolume () const { const MediaSessionParams * MediaSession::getRemoteParams () { L_D(); if (d->op){ - SalMediaDescription *md = d->op->get_remote_media_description(); + SalMediaDescription *md = d->op->getRemoteMediaDescription(); if (md) { d->setRemoteParams(new MediaSessionParams()); unsigned int nbAudioStreams = sal_media_description_nb_active_streams_of_type(md, SalAudio); @@ -4639,7 +4667,7 @@ const MediaSessionParams * MediaSession::getRemoteParams () { d->getRemoteParams()->getPrivate()->setCustomSdpMediaAttributes(LinphoneStreamTypeVideo, md->streams[d->mainVideoStreamIndex].custom_sdp_attributes); d->getRemoteParams()->getPrivate()->setCustomSdpMediaAttributes(LinphoneStreamTypeText, md->streams[d->mainTextStreamIndex].custom_sdp_attributes); } - const SalCustomHeader *ch = d->op->get_recv_custom_header(); + const SalCustomHeader *ch = d->op->getRecvCustomHeaders(); if (ch) { /* Instanciate a remote_params only if a SIP message was received before (custom headers indicates this) */ if (!d->remoteParams) diff --git a/src/content/content-disposition.cpp b/src/content/content-disposition.cpp index ccaf7da15..b7c6c9f16 100644 --- a/src/content/content-disposition.cpp +++ b/src/content/content-disposition.cpp @@ -38,6 +38,7 @@ public: // ----------------------------------------------------------------------------- +const ContentDisposition ContentDisposition::Notification("notification"); const ContentDisposition ContentDisposition::RecipientList("recipient-list"); const ContentDisposition ContentDisposition::RecipientListHistory("recipient-list-history; handling=optional"); @@ -63,10 +64,13 @@ ContentDisposition &ContentDisposition::operator= (const ContentDisposition &oth return *this; } -bool ContentDisposition::operator== (const ContentDisposition &other) const { +bool ContentDisposition::weakEqual (const ContentDisposition &other) const { L_D(); - return d->disposition == other.getPrivate()->disposition - && getParameter() == other.getParameter(); + return d->disposition == other.getPrivate()->disposition; +} + +bool ContentDisposition::operator== (const ContentDisposition &other) const { + return weakEqual(other) && (getParameter() == other.getParameter()); } bool ContentDisposition::operator!= (const ContentDisposition &other) const { diff --git a/src/content/content-disposition.h b/src/content/content-disposition.h index 6f2fcc9ca..e01b289bb 100644 --- a/src/content/content-disposition.h +++ b/src/content/content-disposition.h @@ -35,6 +35,7 @@ public: ContentDisposition &operator= (const ContentDisposition &other); + bool weakEqual (const ContentDisposition &other) const; bool operator== (const ContentDisposition &other) const; bool operator!= (const ContentDisposition &other) const; @@ -51,6 +52,7 @@ public: std::string asString () const; + static const ContentDisposition Notification; static const ContentDisposition RecipientList; static const ContentDisposition RecipientListHistory; diff --git a/src/content/content-manager.cpp b/src/content/content-manager.cpp index 94ee69ce9..e63e6ff19 100644 --- a/src/content/content-manager.cpp +++ b/src/content/content-manager.cpp @@ -19,9 +19,15 @@ #include +#include "c-wrapper/c-wrapper.h" + +#include "linphone/api/c-content.h" + +#include "content-disposition.h" #include "content-manager.h" #include "content-type.h" #include "content/content.h" +#include "content/header/header-param.h" // ============================================================================= @@ -29,90 +35,56 @@ using namespace std; LINPHONE_BEGIN_NAMESPACE -namespace { - constexpr const char MultipartBoundary[] = "---------------------------14737809831466499882746641449"; -} - // ----------------------------------------------------------------------------- list ContentManager::multipartToContentList (const Content &content) { - const string body = content.getBodyAsString(); - belle_sip_multipart_body_handler_t *mpbh = belle_sip_multipart_body_handler_new_from_buffer( - body.c_str(), body.length(), MultipartBoundary - ); - belle_sip_object_ref(mpbh); + LinphoneContent *cContent = L_GET_C_BACK_PTR(&content); + SalBodyHandler *sbh = sal_body_handler_from_content(cContent); list contents; - for (const belle_sip_list_t *parts = belle_sip_multipart_body_handler_get_parts(mpbh); parts; parts = parts->next) { - belle_sip_body_handler_t *part = BELLE_SIP_BODY_HANDLER(parts->data); - belle_sip_header_content_type_t *partContentType = nullptr; - for (const belle_sip_list_t *it = belle_sip_body_handler_get_headers(part); it; it = it->next) { - belle_sip_header_t *header = BELLE_SIP_HEADER(it->data); - if (strcasecmp("Content-Type", belle_sip_header_get_name(header)) == 0) { - partContentType = BELLE_SIP_HEADER_CONTENT_TYPE(header); - break; - } - } - - Content content; - content.setBody(static_cast( - belle_sip_memory_body_handler_get_buffer(BELLE_SIP_MEMORY_BODY_HANDLER(part)) - )); - content.setContentType(ContentType( - belle_sip_header_content_type_get_type(partContentType), - belle_sip_header_content_type_get_subtype(partContentType) - )); - contents.push_back(move(content)); + for (const belle_sip_list_t *parts = sal_body_handler_get_parts(sbh); parts; parts = parts->next) { + SalBodyHandler *part = (SalBodyHandler *)parts->data; + LinphoneContent *cContent = linphone_content_from_sal_body_handler(part, false); + Content *cppContent = L_GET_CPP_PTR_FROM_C_OBJECT(cContent); + if (content.getContentDisposition().isValid()) + cppContent->setContentDisposition(content.getContentDisposition()); + contents.push_back(*cppContent); + linphone_content_unref(cContent); } - belle_sip_object_unref(mpbh); + sal_body_handler_unref(sbh); return contents; } -Content ContentManager::contentListToMultipart (const list &contents) { +Content ContentManager::contentListToMultipart (const list &contents, const string &boundary) { belle_sip_multipart_body_handler_t *mpbh = belle_sip_multipart_body_handler_new( - nullptr, nullptr, nullptr, MultipartBoundary + nullptr, nullptr, nullptr, boundary.c_str() ); - belle_sip_object_ref(mpbh); + mpbh = (belle_sip_multipart_body_handler_t *)belle_sip_object_ref(mpbh); - for (const auto &content : contents) { - const ContentType &contentType = content.getContentType(); - belle_sip_header_t *cContentType = BELLE_SIP_HEADER( - belle_sip_header_content_type_create( - contentType.getType().c_str(), - string(contentType.getSubType() + "; charset=\"UTF-8\"").c_str() - ) - ); + ContentDisposition disposition; + for (Content *content : contents) { + // Is this content-disposition stuff generic or only valid for notification content-disposition? + if (content->getContentDisposition().isValid()) + disposition = content->getContentDisposition(); - const string body = content.getBodyAsString(); - belle_sip_memory_body_handler_t *mbh = belle_sip_memory_body_handler_new_copy_from_buffer( - body.c_str(), body.length(), nullptr, nullptr - ); - belle_sip_body_handler_add_header(BELLE_SIP_BODY_HANDLER(mbh), cContentType); - - for (const auto &header : content.getHeaders()) { - belle_sip_header_t *additionalHeader = BELLE_SIP_HEADER( - belle_sip_header_create( - header.first.c_str(), - header.second.c_str() - ) - ); - belle_sip_body_handler_add_header(BELLE_SIP_BODY_HANDLER(mbh), additionalHeader); - } - - belle_sip_multipart_body_handler_add_part(mpbh, BELLE_SIP_BODY_HANDLER(mbh)); + LinphoneContent *cContent = L_GET_C_BACK_PTR(content); + SalBodyHandler *sbh = sal_body_handler_from_content(cContent, false); + belle_sip_multipart_body_handler_add_part(mpbh, BELLE_SIP_BODY_HANDLER(sbh)); } - char *desc = belle_sip_object_to_string(mpbh); - Content content; - content.setBody(desc); - belle_sip_free(desc); + SalBodyHandler *sbh = (SalBodyHandler *)mpbh; + sal_body_handler_set_type(sbh, ContentType::Multipart.getType().c_str()); + sal_body_handler_set_subtype(sbh, ContentType::Multipart.getSubType().c_str()); + sal_body_handler_set_content_type_parameter(sbh, "boundary", boundary.c_str()); + + LinphoneContent *cContent = linphone_content_from_sal_body_handler(sbh); belle_sip_object_unref(mpbh); - ContentType contentType = ContentType::Multipart; - contentType.setParameter("boundary=" + string(MultipartBoundary)); - content.setContentType(contentType); - + Content content = *L_GET_CPP_PTR_FROM_C_OBJECT(cContent); + if (disposition.isValid()) + content.setContentDisposition(disposition); + linphone_content_unref(cContent); return content; } diff --git a/src/content/content-manager.h b/src/content/content-manager.h index 8251d3c3b..d44c9c3ad 100644 --- a/src/content/content-manager.h +++ b/src/content/content-manager.h @@ -30,9 +30,12 @@ LINPHONE_BEGIN_NAMESPACE class Content; +namespace { + constexpr const char MultipartBoundary[] = "---------------------------14737809831466499882746641449"; +} namespace ContentManager { std::list multipartToContentList (const Content &content); - Content contentListToMultipart (const std::list &contents); + Content contentListToMultipart (const std::list &contents, const std::string &boundary = MultipartBoundary); } LINPHONE_END_NAMESPACE diff --git a/src/content/content-p.h b/src/content/content-p.h index 167712313..b32d61ef4 100644 --- a/src/content/content-p.h +++ b/src/content/content-p.h @@ -29,13 +29,17 @@ LINPHONE_BEGIN_NAMESPACE +class Header; + class ContentPrivate : public ClonableObjectPrivate { private: std::vector body; ContentType contentType; ContentDisposition contentDisposition; std::string contentEncoding; - std::list> headers; + std::list
headers; + + const std::list>::const_iterator findHeader (const std::string &headerName) const; L_DECLARE_PUBLIC(Content); }; diff --git a/src/content/content-type.cpp b/src/content/content-type.cpp index 78c356af6..29913d57e 100644 --- a/src/content/content-type.cpp +++ b/src/content/content-type.cpp @@ -20,7 +20,8 @@ #include "linphone/utils/utils.h" #include "content-type.h" -#include "object/clonable-object-p.h" +#include "header/header-p.h" +#include "header/header-param.h" // ============================================================================= @@ -30,11 +31,10 @@ LINPHONE_BEGIN_NAMESPACE // ----------------------------------------------------------------------------- -class ContentTypePrivate : public ClonableObjectPrivate { +class ContentTypePrivate : public HeaderPrivate { public: string type; string subType; - string parameter; }; // ----------------------------------------------------------------------------- @@ -48,11 +48,12 @@ const ContentType ContentType::ImIsComposing("application/im-iscomposing+xml"); const ContentType ContentType::Multipart("multipart/mixed"); const ContentType ContentType::PlainText("text/plain"); const ContentType ContentType::ResourceLists("application/resource-lists+xml"); +const ContentType ContentType::Rlmi("application/rlmi+xml"); const ContentType ContentType::Sdp("application/sdp"); // ----------------------------------------------------------------------------- -ContentType::ContentType (const string &contentType) : ClonableObject(*new ContentTypePrivate) { +ContentType::ContentType (const string &contentType) : Header(*new ContentTypePrivate) { L_D(); size_t pos = contentType.find('/'); @@ -68,11 +69,23 @@ ContentType::ContentType (const string &contentType) : ClonableObject(*new Conte d->type.clear(); } - if (posParam != string::npos) - setParameter(Utils::trim(contentType.substr(posParam + 1))); + if (posParam != string::npos) { + string params = contentType.substr(posParam + 1); + string token; + do { + posParam = params.find(";"); + if (posParam == string::npos) { + token = params; + } else { + token = params.substr(0, posParam); + } + addParameter(HeaderParam(token)); + params.erase(0, posParam + 1); + } while (posParam != std::string::npos); + } } -ContentType::ContentType (const string &type, const string &subType) : ClonableObject(*new ContentTypePrivate) { +ContentType::ContentType (const string &type, const string &subType) : Header(*new ContentTypePrivate) { L_D(); if (setType(type) && !setSubType(subType)) @@ -82,31 +95,57 @@ ContentType::ContentType (const string &type, const string &subType) : ClonableO ContentType::ContentType ( const string &type, const string &subType, - const string ¶meter -) : ClonableObject(*new ContentTypePrivate) { + const HeaderParam ¶meter +) : Header(*new ContentTypePrivate) { L_D(); if (setType(type) && !setSubType(subType)) d->type.clear(); - setParameter(parameter); + addParameter(parameter); } -ContentType::ContentType (const ContentType &other) : ContentType(other.getType(), other.getSubType(), other.getParameter()) {} +ContentType::ContentType ( + const string &type, + const string &subType, + const std::list ¶meters +) : Header(*new ContentTypePrivate) { + L_D(); + + if (setType(type) && !setSubType(subType)) + d->type.clear(); + addParameters(parameters); +} + +ContentType::ContentType (const ContentType &other) : ContentType(other.getType(), other.getSubType(), other.getParameters()) {} ContentType &ContentType::operator= (const ContentType &other) { if (this != &other) { setType(other.getType()); setSubType(other.getSubType()); - setParameter(other.getParameter()); + cleanParameters(); + addParameters(other.getParameters()); } return *this; } +bool ContentType::weakEqual (const ContentType &other) const { + return (getType() == other.getType()) && (getSubType() == other.getSubType()); +} + bool ContentType::operator== (const ContentType &other) const { - return getType() == other.getType() && - getSubType() == other.getSubType() && - getParameter() == other.getParameter(); + if (!weakEqual(other)) + return false; + if (getParameters().size() != other.getParameters().size()) + return false; + for (const auto ¶m : getParameters()) { + auto it = other.findParameter(param.getName()); + if (it == other.getParameters().cend()) + return false; + if (it->getValue() != param.getValue()) + return false; + } + return true; } bool ContentType::operator!= (const ContentType &other) const { @@ -122,6 +161,7 @@ bool ContentType::setType (const string &type) { L_D(); if (type.find('/') == string::npos) { d->type = Utils::stringToLower(type); + setValue(d->type + "/" + d->subType); return true; } return false; @@ -136,21 +176,12 @@ bool ContentType::setSubType (const string &subType) { L_D(); if (subType.find('/') == string::npos) { d->subType = Utils::stringToLower(subType); + setValue(d->type + "/" + d->subType); return true; } return false; } -const string &ContentType::getParameter () const { - L_D(); - return d->parameter; -} - -void ContentType::setParameter (const string ¶meter) { - L_D(); - d->parameter = parameter; -} - bool ContentType::isEmpty () const { L_D(); return d->type.empty() && d->subType.empty(); @@ -161,18 +192,10 @@ bool ContentType::isValid () const { return !d->type.empty() && !d->subType.empty(); } -string ContentType::asString () const { - L_D(); - if (isValid()) { - string asString = d->type + "/" + d->subType; - if (!d->parameter.empty()) - asString += "; " + d->parameter; - return asString; - } - return ""; +bool ContentType::isMultipart() const { + return getType() == "multipart"; } - bool ContentType::isFile () const { // TODO Remove when not needed anymore in step 2.1 of maindb return isFile(*this); @@ -186,6 +209,7 @@ bool ContentType::isFile (const ContentType &contentType) { contentType != Imdn && contentType != ImIsComposing && contentType != ResourceLists && + contentType != Rlmi && contentType != Sdp && contentType != Cpim && contentType != ConferenceInfo; diff --git a/src/content/content-type.h b/src/content/content-type.h index b13063115..ae802952b 100644 --- a/src/content/content-type.h +++ b/src/content/content-type.h @@ -21,22 +21,26 @@ #define _L_CONTENT_TYPE_H_ #include "object/clonable-object.h" +#include "header/header.h" // ============================================================================= LINPHONE_BEGIN_NAMESPACE class ContentTypePrivate; +class HeaderParam; -class LINPHONE_PUBLIC ContentType : public ClonableObject { +class LINPHONE_PUBLIC ContentType : public Header { public: explicit ContentType (const std::string &contentType = ""); ContentType (const std::string &type, const std::string &subType); - ContentType (const std::string &type, const std::string &subType, const std::string ¶meter); + ContentType (const std::string &type, const std::string &subType, const HeaderParam ¶meter); + ContentType (const std::string &type, const std::string &subType, const std::list ¶meters); ContentType (const ContentType &other); ContentType &operator= (const ContentType &other); + bool weakEqual (const ContentType &other) const; bool operator== (const ContentType &other) const; bool operator!= (const ContentType &other) const; @@ -55,10 +59,7 @@ public: const std::string &getSubType () const; bool setSubType (const std::string &subType); - const std::string &getParameter () const; - void setParameter (const std::string ¶meter); - - std::string asString () const; + bool isMultipart() const; static bool isFile (const ContentType &contentType); @@ -71,6 +72,7 @@ public: static const ContentType Multipart; static const ContentType PlainText; static const ContentType ResourceLists; + static const ContentType Rlmi; static const ContentType Sdp; private: diff --git a/src/content/content.cpp b/src/content/content.cpp index aa30503d4..631d94351 100644 --- a/src/content/content.cpp +++ b/src/content/content.cpp @@ -25,6 +25,7 @@ #include "content-p.h" #include "content-type.h" +#include "header/header.h" // ============================================================================= @@ -32,7 +33,7 @@ using namespace std; LINPHONE_BEGIN_NAMESPACE -// ----------------------------------------------------------------------------- +// ============================================================================= Content::Content () : ClonableObject(*new ContentPrivate) {} @@ -190,17 +191,37 @@ bool Content::isFile () const { return false; } +bool Content::isFileTransfer () const { + return false; +} + void Content::addHeader (const string &headerName, const string &headerValue) { L_D(); removeHeader(headerName); - d->headers.push_back(make_pair(headerName, headerValue)); + Header header = Header(headerName, headerValue); + d->headers.push_back(header); } -const list> &Content::getHeaders () const { +void Content::addHeader (const Header &header) { + L_D(); + removeHeader(header.getName()); + d->headers.push_back(header); +} + +const list
&Content::getHeaders () const { L_D(); return d->headers; } +const Header &Content::getHeader (const string &headerName) const { + L_D(); + list
::const_iterator it = findHeader(headerName); + if (it != d->headers.cend()) { + return *it; + } + return Utils::getEmptyConstRefObject
(); +} + void Content::removeHeader (const string &headerName) { L_D(); auto it = findHeader(headerName); @@ -208,18 +229,11 @@ void Content::removeHeader (const string &headerName) { d->headers.remove(*it); } -list>::const_iterator Content::findHeader (const string &headerName) const { +list
::const_iterator Content::findHeader (const string &headerName) const { L_D(); - return findIf(d->headers, [&headerName](const pair &pair) { - return pair.first == headerName; + return findIf(d->headers, [&headerName](const Header &header) { + return header.getName() == headerName; }); } -LinphoneContent *Content::toLinphoneContent () const { - LinphoneContent *content = linphone_core_create_content(nullptr); - linphone_content_set_type(content, getContentType().getType().c_str()); - linphone_content_set_subtype(content, getContentType().getSubType().c_str()); - return content; -} - LINPHONE_END_NAMESPACE diff --git a/src/content/content.h b/src/content/content.h index c570670c5..3c29d3a1a 100644 --- a/src/content/content.h +++ b/src/content/content.h @@ -35,6 +35,7 @@ LINPHONE_BEGIN_NAMESPACE class ContentDisposition; class ContentType; class ContentPrivate; +class Header; class LINPHONE_PUBLIC Content : public ClonableObject, public AppDataContainer { public: @@ -74,14 +75,14 @@ public: bool isEmpty () const; virtual bool isFile () const; + virtual bool isFileTransfer () const; - const std::list> &getHeaders () const; + const std::list
&getHeaders () const; + const Header &getHeader (const std::string &headerName) const; void addHeader (const std::string &headerName, const std::string &headerValue); + void addHeader (const Header &header); void removeHeader (const std::string &headerName); - std::list>::const_iterator findHeader (const std::string &headerName) const; - - // TODO: Remove me later. - virtual LinphoneContent *toLinphoneContent () const; + std::list
::const_iterator findHeader (const std::string &headerName) const; protected: explicit Content (ContentPrivate &p); diff --git a/src/content/file-content.cpp b/src/content/file-content.cpp index 851d935d3..b4a0ef0fb 100644 --- a/src/content/file-content.cpp +++ b/src/content/file-content.cpp @@ -36,7 +36,6 @@ public: string fileName; string filePath; size_t fileSize = 0; - string fileKey; }; // ----------------------------------------------------------------------------- @@ -48,7 +47,6 @@ FileContent::FileContent (const FileContent &other) : Content(*new FileContentPr d->fileName = other.getFileName(); d->filePath = other.getFilePath(); d->fileSize = other.getFileSize(); - d->fileKey = other.getFileKey(); } FileContent::FileContent (FileContent &&other) : Content(*new FileContentPrivate) { @@ -56,18 +54,14 @@ FileContent::FileContent (FileContent &&other) : Content(*new FileContentPrivate d->fileName = move(other.getPrivate()->fileName); d->filePath = move(other.getPrivate()->filePath); d->fileSize = move(other.getPrivate()->fileSize); - d->fileKey = move(other.getPrivate()->fileKey); } FileContent &FileContent::operator= (const FileContent &other) { L_D(); - if (this != &other) { Content::operator=(other); d->fileName = other.getFileName(); d->filePath = other.getFilePath(); d->fileSize = other.getFileSize(); - d->fileKey = other.getFileKey(); - } return *this; } @@ -78,7 +72,6 @@ FileContent &FileContent::operator= (FileContent &&other) { d->fileName = move(other.getPrivate()->fileName); d->filePath = move(other.getPrivate()->filePath); d->fileSize = move(other.getPrivate()->fileSize); - d->fileKey = move(other.getPrivate()->fileKey); return *this; } @@ -87,8 +80,7 @@ bool FileContent::operator== (const FileContent &other) const { return Content::operator==(other) && d->fileName == other.getFileName() && d->filePath == other.getFilePath() && - d->fileSize == other.getFileSize() && - d->fileKey == other.getFileKey(); + d->fileSize == other.getFileSize(); } void FileContent::setFileSize (size_t size) { @@ -121,28 +113,12 @@ const string &FileContent::getFilePath () const { return d->filePath; } -void FileContent::setFileKey (const string &key) { - L_D(); - d->fileKey = key; -} - -const string &FileContent::getFileKey () const { - L_D(); - return d->fileKey; -} - bool FileContent::isFile () const { return true; } -LinphoneContent *FileContent::toLinphoneContent () const { - LinphoneContent *content = linphone_core_create_content(nullptr); - linphone_content_set_type(content, getContentType().getType().c_str()); - linphone_content_set_subtype(content, getContentType().getSubType().c_str()); - linphone_content_set_name(content, getFileName().c_str()); - linphone_content_set_size(content, getFileSize()); - linphone_content_set_key(content, getFileKey().c_str(), getFileKey().size()); - return content; +bool FileContent::isFileTransfer () const { + return false; } LINPHONE_END_NAMESPACE diff --git a/src/content/file-content.h b/src/content/file-content.h index 645fc6312..081a5898a 100644 --- a/src/content/file-content.h +++ b/src/content/file-content.h @@ -48,13 +48,8 @@ public: void setFilePath (const std::string &path); const std::string &getFilePath () const; - void setFileKey (const std::string &key); - const std::string &getFileKey () const; - bool isFile () const override; - - // TODO: Remove me later. - LinphoneContent *toLinphoneContent () const override; + bool isFileTransfer () const override; private: L_DECLARE_PRIVATE(FileContent); diff --git a/src/content/file-transfer-content.cpp b/src/content/file-transfer-content.cpp index 4bc5ed691..8bf22f7a0 100644 --- a/src/content/file-transfer-content.cpp +++ b/src/content/file-transfer-content.cpp @@ -38,11 +38,14 @@ public: string filePath; FileContent *fileContent = nullptr; size_t fileSize = 0; + std::vector fileKey; }; // ----------------------------------------------------------------------------- -FileTransferContent::FileTransferContent () : Content(*new FileTransferContentPrivate) {} +FileTransferContent::FileTransferContent () : Content(*new FileTransferContentPrivate) { + setContentType(ContentType::FileTransfer); +} FileTransferContent::FileTransferContent (const FileTransferContent &other) : Content(*new FileTransferContentPrivate) { L_D(); @@ -51,6 +54,7 @@ FileTransferContent::FileTransferContent (const FileTransferContent &other) : Co d->filePath = other.getFilePath(); d->fileContent = other.getFileContent(); d->fileSize = other.getFileSize(); + d->fileKey = other.getFileKey(); } FileTransferContent::FileTransferContent (FileTransferContent &&other) : Content(*new FileTransferContentPrivate) { @@ -60,6 +64,7 @@ FileTransferContent::FileTransferContent (FileTransferContent &&other) : Content d->filePath = move(other.getPrivate()->filePath); d->fileContent = move(other.getPrivate()->fileContent); d->fileSize = move(other.getPrivate()->fileSize); + d->fileKey = move(other.getPrivate()->fileKey); } FileTransferContent &FileTransferContent::operator= (const FileTransferContent &other) { @@ -71,6 +76,7 @@ FileTransferContent &FileTransferContent::operator= (const FileTransferContent & d->filePath = other.getFilePath(); d->fileContent = other.getFileContent(); d->fileSize = other.getFileSize(); + d->fileKey = other.getFileKey(); } return *this; @@ -84,6 +90,8 @@ FileTransferContent &FileTransferContent::operator= (FileTransferContent &&other d->filePath = move(other.getPrivate()->filePath); d->fileContent = move(other.getPrivate()->fileContent); d->fileSize = move(other.getPrivate()->fileSize); + d->fileKey = move(other.getPrivate()->fileKey); + return *this; } @@ -146,17 +154,27 @@ size_t FileTransferContent::getFileSize () const { return d->fileSize; } -LinphoneContent *FileTransferContent::toLinphoneContent () const { - LinphoneContent *content = linphone_core_create_content(nullptr); - linphone_content_set_type(content, getContentType().getType().c_str()); - linphone_content_set_subtype(content, getContentType().getSubType().c_str()); - linphone_content_set_name(content, getFileName().c_str()); - linphone_content_set_size(content, getFileSize()); - return content; +void FileTransferContent::setFileKey (const char *key, size_t size) { + L_D(); + d->fileKey = vector(key, key + size); +} + +const vector &FileTransferContent::getFileKey () const { + L_D(); + return d->fileKey; +} + +size_t FileTransferContent::getFileKeySize() const { + L_D(); + return d->fileKey.size(); } bool FileTransferContent::isFile () const { return false; } +bool FileTransferContent::isFileTransfer () const { + return true; +} + LINPHONE_END_NAMESPACE diff --git a/src/content/file-transfer-content.h b/src/content/file-transfer-content.h index 59b4cc125..4ae07867b 100644 --- a/src/content/file-transfer-content.h +++ b/src/content/file-transfer-content.h @@ -20,6 +20,8 @@ #ifndef _L_FILE_TRANSFER_CONTENT_H_ #define _L_FILE_TRANSFER_CONTENT_H_ +#include + #include "content.h" // ============================================================================= @@ -55,10 +57,12 @@ public: void setFileSize (size_t size); size_t getFileSize () const; - bool isFile () const override; + void setFileKey (const char *key, size_t size); + const std::vector &getFileKey () const; + size_t getFileKeySize() const; - // TODO: Remove me later. - LinphoneContent *toLinphoneContent () const override; + bool isFile () const override; + bool isFileTransfer () const override; private: L_DECLARE_PRIVATE(FileTransferContent); diff --git a/src/search/search-result-p.h b/src/content/header/header-p.h similarity index 71% rename from src/search/search-result-p.h rename to src/content/header/header-p.h index 07830689a..fd4663efe 100644 --- a/src/search/search-result-p.h +++ b/src/content/header/header-p.h @@ -1,5 +1,5 @@ /* - * search-result-p.h + * header-p.h * Copyright (C) 2010-2018 Belledonne Communications SARL * * This program is free software; you can redistribute it and/or @@ -17,26 +17,27 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef _L_SEARCH_RESULT_P_H_ -#define _L_SEARCH_RESULT_P_H_ +#ifndef _L_HEADER_P_H_ +#define _L_HEADER_P_H_ + +#include -#include "search-result.h" #include "object/clonable-object-p.h" -#include "linphone/types.h" +#include "header.h" + +// ============================================================================= LINPHONE_BEGIN_NAMESPACE -class SearchResultPrivate : public ClonableObjectPrivate { +class HeaderPrivate : public ClonableObjectPrivate { private: - const LinphoneFriend *mFriend; - const LinphoneAddress *mAddress; - unsigned int mWeight; - - L_DECLARE_PUBLIC(SearchResult); + std::string name; + std::string value; + std::list parameters; + L_DECLARE_PUBLIC(Header); }; LINPHONE_END_NAMESPACE -#endif //_L_SEARCH_RESULT_P_H_ - +#endif // ifndef _L_HEADER_P_H_ \ No newline at end of file diff --git a/src/content/header/header-param.cpp b/src/content/header/header-param.cpp new file mode 100644 index 000000000..9605a2f84 --- /dev/null +++ b/src/content/header/header-param.cpp @@ -0,0 +1,108 @@ +/* + * header-param.cpp + * Copyright (C) 2010-2018 Belledonne Communications SARL + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "linphone/utils/utils.h" + +#include "header-param.h" +#include "object/clonable-object-p.h" + +// ============================================================================= + +using namespace std; + +LINPHONE_BEGIN_NAMESPACE + +// ----------------------------------------------------------------------------- + +class HeaderParamPrivate : public ClonableObjectPrivate { +public: + string name; + string value; +}; + +// ----------------------------------------------------------------------------- + +HeaderParam::HeaderParam (const string ¶m) : ClonableObject(*new HeaderParamPrivate) { + size_t pos = param.find("="); + size_t end = param.length(); + + if (pos == string::npos) { + setName(param); + } else { + setName(param.substr(0, pos)); + setValue(param.substr(pos + 1, end - (pos + 1))); + } +} + +HeaderParam::HeaderParam (const string &name, const string &value) : ClonableObject(*new HeaderParamPrivate) { + setName(name); + setValue(value); +} + +HeaderParam::HeaderParam (const HeaderParam &other) : HeaderParam(other.getName(), other.getValue()) {} + +HeaderParam &HeaderParam::operator= (const HeaderParam &other) { + if (this != &other) { + setName(other.getName()); + setValue(other.getValue()); + } + + return *this; +} + +bool HeaderParam::operator== (const HeaderParam &other) const { + return getName() == other.getName() && + getValue() == other.getValue(); +} + +bool HeaderParam::operator!= (const HeaderParam &other) const { + return !(*this == other); +} + +const string &HeaderParam::getName () const { + L_D(); + return d->name; +} + +bool HeaderParam::setName (const string &name) { + L_D(); + d->name = name; + return true; +} + +const string &HeaderParam::getValue () const { + L_D(); + return d->value; +} + +bool HeaderParam::setValue (const string &value) { + L_D(); + d->value = value; + return true; +} + +string HeaderParam::asString () const { + L_D(); + string asString = ";" + d->name; + if (!d->value.empty()) + asString += "=" + d->value; + return asString; +} + +LINPHONE_END_NAMESPACE diff --git a/src/content/header/header-param.h b/src/content/header/header-param.h new file mode 100644 index 000000000..a9471b486 --- /dev/null +++ b/src/content/header/header-param.h @@ -0,0 +1,61 @@ +/* + * header-param.h + * Copyright (C) 2010-2018 Belledonne Communications SARL + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _L_HEADER_PARAM_H_ +#define _L_HEADER_PARAM_H_ + +#include "object/clonable-object.h" + +// ============================================================================= + +LINPHONE_BEGIN_NAMESPACE + +class HeaderParamPrivate; + +class LINPHONE_PUBLIC HeaderParam : public ClonableObject { +public: + explicit HeaderParam (const std::string &header = ""); + HeaderParam (const std::string &name, const std::string &value); + HeaderParam (const HeaderParam &other); + + HeaderParam &operator= (const HeaderParam &other); + + bool operator== (const HeaderParam &other) const; + bool operator!= (const HeaderParam &other) const; + + // Delete these operators to prevent putting complicated content-type strings + // in the code. Instead define static const HeaderParam objects below. + bool operator== (const std::string &other) const = delete; + bool operator!= (const std::string &other) const = delete; + + const std::string &getName () const; + bool setName (const std::string &name); + + const std::string &getValue () const; + bool setValue (const std::string &value); + + std::string asString () const; + +private: + L_DECLARE_PRIVATE(HeaderParam); +}; + +LINPHONE_END_NAMESPACE + +#endif // ifndef _L_HEADER_PARAM_H_ diff --git a/src/content/header/header.cpp b/src/content/header/header.cpp new file mode 100644 index 000000000..5924cdf5b --- /dev/null +++ b/src/content/header/header.cpp @@ -0,0 +1,183 @@ +/* + * header.cpp + * Copyright (C) 2010-2018 Belledonne Communications SARL + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include "linphone/utils/utils.h" +#include "linphone/utils/algorithm.h" + +#include "header-p.h" +#include "header-param.h" + +// ============================================================================= + +using namespace std; + +LINPHONE_BEGIN_NAMESPACE + +// ----------------------------------------------------------------------------- + +Header::Header(HeaderPrivate &p) : ClonableObject(p) {} + +Header::Header() : ClonableObject(*new HeaderPrivate) {} + +Header::Header (const string &name, const string &value) : ClonableObject(*new HeaderPrivate) { + setName(name); + + size_t posParam = value.find(";"); + if (posParam == string::npos) { + setValue(value); + return; + } + + string parsedValue = value.substr(0, posParam); + string params = value.substr(posParam + 1); + string token; + do { + posParam = params.find(";"); + if (posParam == string::npos) { + token = params; + } else { + token = params.substr(0, posParam); + } + addParameter(HeaderParam(token)); + params.erase(0, posParam + 1); + } while (posParam != std::string::npos); + + setValue(parsedValue); +} + +Header::Header (const string &name, const string &value, const list ¶ms) : Header(name, value) { + addParameters(params); +} + +Header::Header (const Header &other) : Header(other.getName(), other.getValue(), other.getParameters()) {} + +Header &Header::operator= (const Header &other) { + if (this != &other) { + setName(other.getName()); + setValue(other.getValue()); + cleanParameters(); + addParameters(other.getParameters()); + } + + return *this; +} + +bool Header::operator== (const Header &other) const { + return getName() == other.getName() && + getValue() == other.getValue(); +} + +bool Header::operator!= (const Header &other) const { + return !(*this == other); +} + +void Header::setName (const string &name) { + L_D(); + d->name = name; +} + +string Header::getName () const { + L_D(); + return d->name; +} + +void Header::setValue (const string &value) { + L_D(); + d->value = value; +} + +string Header::getValue () const { + L_D(); + return d->value; +} + +void Header::cleanParameters () { + L_D(); + d->parameters.clear(); +} + +const list &Header::getParameters () const { + L_D(); + return d->parameters; +} + +void Header::addParameter (const string ¶mName, const string ¶mValue) { + addParameter(HeaderParam(paramName, paramValue)); +} + +void Header::addParameter (const HeaderParam ¶m) { + L_D(); + removeParameter(param); + d->parameters.push_back(param); +} + +void Header::addParameters(const list ¶ms) { + for (auto it = std::begin(params); it!=std::end(params); ++it) { + HeaderParam param = *it; + addParameter(param.getName(), param.getValue()); + } +} + +void Header::removeParameter (const string ¶mName) { + L_D(); + auto it = findParameter(paramName); + if (it != d->parameters.cend()) + d->parameters.remove(*it); +} + +void Header::removeParameter (const HeaderParam ¶m) { + removeParameter(param.getName()); +} + +list::const_iterator Header::findParameter (const string ¶mName) const { + L_D(); + return findIf(d->parameters, [¶mName](const HeaderParam ¶m) { + return param.getName() == paramName; + }); +} + +const HeaderParam &Header::getParameter (const string ¶mName) const { + L_D(); + list::const_iterator it = findParameter(paramName); + if (it != d->parameters.cend()) { + return *it; + } + return Utils::getEmptyConstRefObject(); +} + +string Header::asString () const { + stringstream asString; + if (!getName().empty()) { + asString << getName() << ":"; + } + asString << getValue(); + for (const auto ¶m : getParameters()) { + asString << param.asString(); + } + return asString.str(); +} + +ostream &operator<<(ostream& stream, const Header& header) { + stream << header.asString(); + return stream; +} + +LINPHONE_END_NAMESPACE \ No newline at end of file diff --git a/src/content/header/header.h b/src/content/header/header.h new file mode 100644 index 000000000..583572523 --- /dev/null +++ b/src/content/header/header.h @@ -0,0 +1,74 @@ +/* + * header.h + * Copyright (C) 2010-2018 Belledonne Communications SARL + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _L_HEADER_H_ +#define _L_HEADER_H_ + +#include + +#include "object/clonable-object.h" + +// ============================================================================= + +LINPHONE_BEGIN_NAMESPACE + +class HeaderPrivate; +class HeaderParam; + +class LINPHONE_PUBLIC Header : public ClonableObject { +public: + Header (); + Header (const std::string &name, const std::string &value); + Header (const std::string &name, const std::string &value, const std::list ¶ms); + Header (const Header &other); + + Header &operator= (const Header &other); + + bool operator== (const Header &other) const; + bool operator!= (const Header &other) const; + + void setName (const std::string &name); + std::string getName () const; + + void setValue (const std::string &value); + std::string getValue () const; + + void cleanParameters (); + const std::list &getParameters () const; + void addParameter (const std::string ¶mName, const std::string ¶mValue); + void addParameter (const HeaderParam ¶m); + void addParameters(const std::list ¶ms); + void removeParameter (const std::string ¶mName); + void removeParameter (const HeaderParam ¶m); + std::list::const_iterator findParameter (const std::string ¶mName) const; + const HeaderParam &getParameter (const std::string ¶mName) const; + + std::string asString () const; + friend std::ostream &operator<<(std::ostream&, const Header&); + +protected: + explicit Header (HeaderPrivate &p); + +private: + L_DECLARE_PRIVATE(Header); +}; + +LINPHONE_END_NAMESPACE + +#endif // ifndef _L_HEADER_H_ diff --git a/src/core/core-accessor.h b/src/core/core-accessor.h index 6a6e911a7..0461e253c 100644 --- a/src/core/core-accessor.h +++ b/src/core/core-accessor.h @@ -30,7 +30,7 @@ class Core; class CoreAccessorPrivate; // Decorator to get a valid core instance. -LINPHONE_PUBLIC class CoreAccessor { +class LINPHONE_PUBLIC CoreAccessor { public: CoreAccessor (const std::shared_ptr &core); CoreAccessor (const std::shared_ptr &&core); diff --git a/src/core/core-call.cpp b/src/core/core-call.cpp index 5bc9912a7..119db552b 100644 --- a/src/core/core-call.cpp +++ b/src/core/core-call.cpp @@ -27,6 +27,7 @@ // TODO: Remove me later. #include "c-wrapper/c-wrapper.h" +#include "conference_private.h" #include @@ -58,17 +59,15 @@ bool CorePrivate::canWeAddCall () const { bool CorePrivate::inviteReplacesABrokenCall (SalCallOp *op) { CallSession *replacedSession = nullptr; - SalCallOp *replacedOp = op->get_replaces(); + SalCallOp *replacedOp = op->getReplaces(); if (replacedOp) - replacedSession = reinterpret_cast(replacedOp->get_user_pointer()); + replacedSession = reinterpret_cast(replacedOp->getUserPointer()); for (const auto &call : calls) { shared_ptr session = call->getPrivate()->getActiveSession(); if (session - && ((session->getPrivate()->isBroken() && op->compare_op(session->getPrivate()->getOp())) - || ((replacedSession == session.get()) - && (strcmp(op->get_from(), replacedOp->get_from()) == 0) - && (strcmp(op->get_to(), replacedOp->get_to()) == 0))) - ) { + && ((session->getPrivate()->isBroken() && op->compareOp(session->getPrivate()->getOp())) + || (replacedSession == session.get() && op->getFrom() == replacedOp->getFrom() && op->getTo() == replacedOp->getTo()) + )) { session->getPrivate()->replaceOp(op); return true; } @@ -301,9 +300,12 @@ void Core::soundcardHintCheck () { LinphoneConfig *config = linphone_core_get_config(L_GET_C_BACK_PTR(this)); bool useRtpIo = !!lp_config_get_int(config, "sound", "rtp_io", FALSE); bool useRtpIoEnableLocalOutput = !!lp_config_get_int(config, "sound", "rtp_io_enable_local_output", FALSE); - bool useFiles = L_GET_C_BACK_PTR(getSharedFromThis())->use_files; + + LinphoneConference *conf_ctx = getCCore()->conf_ctx; + if (conf_ctx && linphone_conference_get_size(conf_ctx) >= 1) return; + if ((!d->hasCalls() || noNeedForSound) - && (!useFiles && (!useRtpIo || (useRtpIo && useRtpIoEnableLocalOutput)))) { + && (!L_GET_C_BACK_PTR(getSharedFromThis())->use_files && (!useRtpIo || (useRtpIo && useRtpIoEnableLocalOutput)))) { lInfo() << "Notifying soundcard that we don't need it anymore for calls"; d->notifySoundcardUsage(false); } diff --git a/src/core/core-chat-room.cpp b/src/core/core-chat-room.cpp index 291c2a600..c4282c6b6 100644 --- a/src/core/core-chat-room.cpp +++ b/src/core/core-chat-room.cpp @@ -18,6 +18,7 @@ */ #include +#include #include "address/identity-address.h" #include "chat/chat-room/basic-chat-room.h" @@ -100,7 +101,7 @@ shared_ptr CorePrivate::createBasicChatRoom ( return chatRoom; } -shared_ptr CorePrivate::createClientGroupChatRoom (const string &subject, const string &uri, bool fallback) { +shared_ptr CorePrivate::createClientGroupChatRoom (const string &subject, const string &uri, const Content &content, bool fallback) { L_Q(); string usedUri; @@ -135,7 +136,7 @@ shared_ptr CorePrivate::createClientGroupChatRoom (const strin shared_ptr chatRoom; { shared_ptr clientGroupChatRoom = make_shared( - q->getSharedFromThis(), usedUri, IdentityAddress(from), subject + q->getSharedFromThis(), usedUri, IdentityAddress(from), subject, content ); ClientGroupChatRoomPrivate *dClientGroupChatRoom = clientGroupChatRoom->getPrivate(); @@ -171,16 +172,18 @@ void CorePrivate::insertChatRoom (const shared_ptr &chatRoom) } } -void CorePrivate::insertChatRoomWithDb (const shared_ptr &chatRoom) { +void CorePrivate::insertChatRoomWithDb (const shared_ptr &chatRoom, unsigned int notifyId) { L_ASSERT(chatRoom->getState() == ChatRoom::State::Created); - mainDb->insertChatRoom(chatRoom); + mainDb->insertChatRoom(chatRoom, notifyId); } void CorePrivate::loadChatRooms () { chatRooms.clear(); chatRoomsById.clear(); - for (auto &chatRoom : mainDb->getChatRooms()) + for (auto &chatRoom : mainDb->getChatRooms()) { insertChatRoom(chatRoom); + chatRoom->getPrivate()->sendDeliveryNotifications(); + } } void CorePrivate::replaceChatRoom (const shared_ptr &replacedChatRoom, const shared_ptr &newChatRoom) { @@ -265,9 +268,9 @@ shared_ptr Core::findOneToOneChatRoom ( return nullptr; } -shared_ptr Core::createClientGroupChatRoom (const string &subject) { +shared_ptr Core::createClientGroupChatRoom (const string &subject, bool fallback) { L_D(); - return d->createClientGroupChatRoom(subject); + return d->createClientGroupChatRoom(subject, "", Content(), fallback); } shared_ptr Core::getOrCreateBasicChatRoom (const ChatRoomId &chatRoomId, bool isRtt) { diff --git a/src/core/core-listener.h b/src/core/core-listener.h index d3589bc2e..53784f59e 100644 --- a/src/core/core-listener.h +++ b/src/core/core-listener.h @@ -30,8 +30,11 @@ class CoreListener { public: virtual ~CoreListener () = default; + virtual void onGlobalStateChanged (LinphoneGlobalState state) {} virtual void onNetworkReachable (bool sipNetworkReachable, bool mediaNetworkReachable) {} virtual void onRegistrationStateChanged (LinphoneProxyConfig *cfg, LinphoneRegistrationState state, const std::string &message) {} + virtual void onEnteringBackground () {} + virtual void onEnteringForeground () {} }; LINPHONE_END_NAMESPACE diff --git a/src/core/core-p.h b/src/core/core-p.h index 0106dd502..d740ff4be 100644 --- a/src/core/core-p.h +++ b/src/core/core-p.h @@ -31,6 +31,8 @@ LINPHONE_BEGIN_NAMESPACE class CoreListener; +class LocalConferenceListEventHandler; +class RemoteConferenceListEventHandler; class CorePrivate : public ObjectPrivate { public: @@ -39,8 +41,11 @@ public: void unregisterListener (CoreListener *listener); void uninit (); + void notifyGlobalStateChanged (LinphoneGlobalState state); void notifyNetworkReachable (bool sipNetworkReachable, bool mediaNetworkReachable); void notifyRegistrationStateChanged (LinphoneProxyConfig *cfg, LinphoneRegistrationState state, const std::string &message); + void notifyEnteringBackground (); + void notifyEnteringForeground (); int addCall (const std::shared_ptr &call); bool canWeAddCall () const; @@ -59,14 +64,18 @@ public: void loadChatRooms (); void insertChatRoom (const std::shared_ptr &chatRoom); - void insertChatRoomWithDb (const std::shared_ptr &chatRoom); + void insertChatRoomWithDb (const std::shared_ptr &chatRoom, unsigned int notifyId = 0); std::shared_ptr createBasicChatRoom (const ChatRoomId &chatRoomId, AbstractChatRoom::CapabilitiesMask capabilities); - std::shared_ptr createClientGroupChatRoom (const std::string &subject, const std::string &uri = "", bool fallback = true); + std::shared_ptr createClientGroupChatRoom (const std::string &subject, const std::string &uri = "", const Content &content = Content(), bool fallback = true); void replaceChatRoom (const std::shared_ptr &replacedChatRoom, const std::shared_ptr &newChatRoom); std::unique_ptr mainDb; + std::unique_ptr remoteListEventHandler; + std::unique_ptr localListEventHandler; private: + bool isInBackground = false; + std::list listeners; std::list> calls; diff --git a/src/core/core.cpp b/src/core/core.cpp index 9e9d94cc6..834d74d45 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -20,8 +20,12 @@ #include #include +//#include "linphone/utils/general.h" + #include "address/address-p.h" #include "call/call.h" +#include "conference/handlers/local-conference-list-event-handler.h" +#include "conference/handlers/remote-conference-list-event-handler.h" #include "core/core-listener.h" #include "core/core-p.h" #include "logger/logger.h" @@ -42,6 +46,8 @@ LINPHONE_BEGIN_NAMESPACE void CorePrivate::init () { L_Q(); mainDb.reset(new MainDb(q->getSharedFromThis())); + remoteListEventHandler = makeUnique(q->getSharedFromThis()); + localListEventHandler = makeUnique(q->getSharedFromThis()); AbstractDb::Backend backend; string uri = L_C_TO_STRING(lp_config_get_string(linphone_core_get_config(L_GET_C_BACK_PTR(q)), "storage", "uri", nullptr)); @@ -81,21 +87,52 @@ void CorePrivate::uninit () { chatRoomsById.clear(); noCreatedClientGroupChatRooms.clear(); + remoteListEventHandler = nullptr; + localListEventHandler = nullptr; + AddressPrivate::clearSipAddressesCache(); } // ----------------------------------------------------------------------------- +void CorePrivate::notifyGlobalStateChanged (LinphoneGlobalState state) { + auto listenersCopy = listeners; // Allow removable of a listener in its own call + for (const auto &listener : listenersCopy) + listener->onGlobalStateChanged(state); +} + void CorePrivate::notifyNetworkReachable (bool sipNetworkReachable, bool mediaNetworkReachable) { - for (const auto &listener : listeners) + auto listenersCopy = listeners; // Allow removable of a listener in its own call + for (const auto &listener : listenersCopy) listener->onNetworkReachable(sipNetworkReachable, mediaNetworkReachable); } void CorePrivate::notifyRegistrationStateChanged (LinphoneProxyConfig *cfg, LinphoneRegistrationState state, const string &message) { - for (const auto &listener : listeners) + auto listenersCopy = listeners; // Allow removable of a listener in its own call + for (const auto &listener : listenersCopy) listener->onRegistrationStateChanged(cfg, state, message); } +void CorePrivate::notifyEnteringBackground () { + if (isInBackground) + return; + + isInBackground = true; + auto listenersCopy = listeners; // Allow removable of a listener in its own call + for (const auto &listener : listenersCopy) + listener->onEnteringBackground(); +} + +void CorePrivate::notifyEnteringForeground () { + if (!isInBackground) + return; + + isInBackground = false; + auto listenersCopy = listeners; // Allow removable of a listener in its own call + for (const auto &listener : listenersCopy) + listener->onEnteringForeground(); +} + // ============================================================================= Core::Core () : Object(*new CorePrivate) { @@ -114,6 +151,24 @@ shared_ptr Core::create (LinphoneCore *cCore) { return core; } +// --------------------------------------------------------------------------- +// Application lifecycle. +// --------------------------------------------------------------------------- + +void Core::enterBackground () { + L_D(); + d->notifyEnteringBackground(); +} + +void Core::enterForeground () { + L_D(); + d->notifyEnteringForeground(); +} + +// --------------------------------------------------------------------------- +// C-Core. +// --------------------------------------------------------------------------- + LinphoneCore *Core::getCCore () const { return L_GET_C_BACK_PTR(this); } diff --git a/src/core/core.h b/src/core/core.h index a8a15630a..ba9356e55 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -44,18 +44,22 @@ class LINPHONE_PUBLIC Core : public Object { friend class BasicToClientGroupChatRoomPrivate; friend class CallPrivate; friend class CallSession; + friend class ChatMessage; friend class ChatMessagePrivate; friend class ChatRoom; friend class ChatRoomPrivate; friend class ClientGroupChatRoom; friend class ClientGroupChatRoomPrivate; friend class ClientGroupToBasicChatRoomPrivate; + friend class Imdn; friend class LocalConferenceEventHandlerPrivate; friend class MainDb; friend class MainDbChatMessageKey; friend class MainDbEventKey; friend class MediaSessionPrivate; + friend class RealTimeTextChatRoomPrivate; friend class RemoteConferenceEventHandler; + friend class RemoteConferenceListEventHandler; friend class ServerGroupChatRoom; friend class ServerGroupChatRoomPrivate; @@ -67,6 +71,13 @@ public: // Return a new Core instance. Entry point of Linphone. static std::shared_ptr create (LinphoneCore *cCore); + // --------------------------------------------------------------------------- + // Application lifecycle. + // --------------------------------------------------------------------------- + + void enterBackground (); + void enterForeground (); + // --------------------------------------------------------------------------- // C-Core. // --------------------------------------------------------------------------- @@ -101,7 +112,7 @@ public: const IdentityAddress &participantAddress ) const; - std::shared_ptr createClientGroupChatRoom (const std::string &subject); + std::shared_ptr createClientGroupChatRoom (const std::string &subject, bool fallback = true); std::shared_ptr createClientGroupChatRoom ( const std::string &subject, const IdentityAddress &localAddress diff --git a/src/core/paths/paths-android.cpp b/src/core/paths/paths-android.cpp index 5abf19364..72ffa0bd8 100644 --- a/src/core/paths/paths-android.cpp +++ b/src/core/paths/paths-android.cpp @@ -19,8 +19,6 @@ #include -#include "linphone/utils/utils.h" - #include "core/platform-helpers/platform-helpers.h" #include "paths-android.h" @@ -31,16 +29,16 @@ using namespace std; LINPHONE_BEGIN_NAMESPACE -string SysPaths::getDataPath (PlatformHelpers *platformHelper) { - if (!platformHelper) - return Utils::getEmptyConstRefObject(); - return platformHelper->getDataPath(); +string SysPaths::getDataPath (PlatformHelpers *platformHelpers) { + if (!platformHelpers) + return ""; + return platformHelpers->getDataPath(); } -string SysPaths::getConfigPath (PlatformHelpers *platformHelper) { - if (!platformHelper) - return Utils::getEmptyConstRefObject(); - return platformHelper->getConfigPath(); +string SysPaths::getConfigPath (PlatformHelpers *platformHelpers) { + if (!platformHelpers) + return ""; + return platformHelpers->getConfigPath(); } LINPHONE_END_NAMESPACE diff --git a/src/core/paths/paths-android.h b/src/core/paths/paths-android.h index c81010eda..828c5147b 100644 --- a/src/core/paths/paths-android.h +++ b/src/core/paths/paths-android.h @@ -31,8 +31,8 @@ LINPHONE_BEGIN_NAMESPACE class PlatformHelpers; namespace SysPaths { - LINPHONE_PUBLIC std::string getDataPath (PlatformHelpers *platformHelper); - LINPHONE_PUBLIC std::string getConfigPath (PlatformHelpers *platformHelper); + LINPHONE_PUBLIC std::string getDataPath (PlatformHelpers *platformHelpers); + LINPHONE_PUBLIC std::string getConfigPath (PlatformHelpers *platformHelpers); } LINPHONE_END_NAMESPACE diff --git a/src/core/paths/paths-apple.h b/src/core/paths/paths-apple.h index f1e3ffb44..fd1c8f6eb 100644 --- a/src/core/paths/paths-apple.h +++ b/src/core/paths/paths-apple.h @@ -31,8 +31,8 @@ LINPHONE_BEGIN_NAMESPACE class PlatformHelpers; namespace SysPaths { - LINPHONE_PUBLIC std::string getDataPath (PlatformHelpers *platformHelper); - LINPHONE_PUBLIC std::string getConfigPath (PlatformHelpers *platformHelper); + LINPHONE_PUBLIC std::string getDataPath (PlatformHelpers *platformHelpers); + LINPHONE_PUBLIC std::string getConfigPath (PlatformHelpers *platformHelpers); } LINPHONE_END_NAMESPACE diff --git a/src/core/paths/paths-apple.mm b/src/core/paths/paths-apple.mm index 8ed4d52d4..94c0e886b 100644 --- a/src/core/paths/paths-apple.mm +++ b/src/core/paths/paths-apple.mm @@ -17,54 +17,50 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#import "linphone/utils/utils.h" - -#import "core/platform-helpers/platform-helpers.h" -#import "logger/logger.h" -#import "paths-apple.h" - #import +#import "logger/logger.h" + +#import "paths-apple.h" + // ============================================================================= LINPHONE_BEGIN_NAMESPACE -std::string SysPaths::getDataPath (PlatformHelpers *platformHelper) { +std::string SysPaths::getDataPath (PlatformHelpers *) { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); NSString *writablePath = [paths objectAtIndex:0]; NSString *fullPath = [writablePath stringByAppendingString:@"/linphone/"]; - if(![[NSFileManager defaultManager] fileExistsAtPath:fullPath]) { + if (![[NSFileManager defaultManager] fileExistsAtPath:fullPath]) { NSError *error; lInfo() << "Data path " << fullPath.UTF8String << " does not exist, creating it."; if (![[NSFileManager defaultManager] createDirectoryAtPath:fullPath - withIntermediateDirectories:YES - attributes:nil - error:&error]) { + withIntermediateDirectories:YES + attributes:nil + error:&error]) { lError() << "Create data path directory error: " << error.description; } } - const char *ret = fullPath.UTF8String; - return ret; + return fullPath.UTF8String; } -std::string SysPaths::getConfigPath (PlatformHelpers *platformHelper) { +std::string SysPaths::getConfigPath (PlatformHelpers *) { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES); NSString *configPath = [paths objectAtIndex:0]; NSString *fullPath = [configPath stringByAppendingString:@"/Preferences/linphone/"]; - if(![[NSFileManager defaultManager] fileExistsAtPath:fullPath]) { + if (![[NSFileManager defaultManager] fileExistsAtPath:fullPath]) { NSError *error; lInfo() << "Config path " << fullPath.UTF8String << " does not exist, creating it."; if (![[NSFileManager defaultManager] createDirectoryAtPath:fullPath - withIntermediateDirectories:YES - attributes:nil - error:&error]) { + withIntermediateDirectories:YES + attributes:nil + error:&error]) { lError() << "Create config path directory error: " << error.description; } } - const char *ret = fullPath.UTF8String; - return ret; + return fullPath.UTF8String; } LINPHONE_END_NAMESPACE diff --git a/src/core/paths/paths-linux.cpp b/src/core/paths/paths-linux.cpp index b0055125c..09bd962b5 100644 --- a/src/core/paths/paths-linux.cpp +++ b/src/core/paths/paths-linux.cpp @@ -17,9 +17,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "linphone/utils/utils.h" - -#include "core/platform-helpers/platform-helpers.h" #include "logger/logger.h" #include "paths-linux.h" @@ -41,12 +38,12 @@ static string getBaseDirectory () { return base; } -string SysPaths::getDataPath (PlatformHelpers *platformHelper) { +string SysPaths::getDataPath (PlatformHelpers *) { static string dataPath = getBaseDirectory() + "/.local/share/linphone/"; return dataPath; } -string SysPaths::getConfigPath (PlatformHelpers *platformHelper) { +string SysPaths::getConfigPath (PlatformHelpers *) { static string configPath = getBaseDirectory() + "/.config/linphone/"; return configPath; } diff --git a/src/core/paths/paths-linux.h b/src/core/paths/paths-linux.h index 1c7a9e3b6..d5bc59977 100644 --- a/src/core/paths/paths-linux.h +++ b/src/core/paths/paths-linux.h @@ -31,8 +31,8 @@ LINPHONE_BEGIN_NAMESPACE class PlatformHelpers; namespace SysPaths { - LINPHONE_PUBLIC std::string getDataPath (PlatformHelpers *platformHelper); - LINPHONE_PUBLIC std::string getConfigPath (PlatformHelpers *platformHelper); + LINPHONE_PUBLIC std::string getDataPath (PlatformHelpers *platformHelpers); + LINPHONE_PUBLIC std::string getConfigPath (PlatformHelpers *platformHelpers); } LINPHONE_END_NAMESPACE diff --git a/src/core/paths/paths-windows.cpp b/src/core/paths/paths-windows.cpp index 351d0b304..827db3500 100644 --- a/src/core/paths/paths-windows.cpp +++ b/src/core/paths/paths-windows.cpp @@ -17,11 +17,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include - -#include "shlobj.h" - -#include "linphone/utils/utils.h" +#include +#include +#include #include "core/platform-helpers/platform-helpers.h" @@ -33,23 +31,28 @@ using namespace std; LINPHONE_BEGIN_NAMESPACE -string SysPaths::getDataPath (PlatformHelpers *platformHelper) { - TCHAR szPath[MAX_PATH]; - // Get path for each computer, non-user specific and non-roaming data. - if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, szPath))) { - stringstream path; - path << boost::lexical_cast(szPath) << "\\linphone\\"; - string ret = path.str(); - boost::replace_all(ret, "\\", "\\\\"); - return ret; +static string getPath (const GUID &id) { + string strPath; + + LPWSTR path; + if (SHGetKnownFolderPath(id, KF_FLAG_DONT_VERIFY, 0, &path) == S_OK) { + strPath = _bstr_t(path); + replace(strPath.begin(), strPath.end(), '\\', '/'); + CoTaskMemFree(path); } - return Utils::getEmptyConstRefObject(); + return strPath; } -string SysPaths::getConfigPath (PlatformHelpers *platformHelper) { - // Seems to be the same directory. - return getDataPath(platformHelper); + +string SysPaths::getDataPath (PlatformHelpers *) { + static string dataPath = getPath(FOLDERID_LocalAppData); + return dataPath; +} + +string SysPaths::getConfigPath (PlatformHelpers *platformHelpers) { + // Yes, same path. + return getDataPath(platformHelpers); } LINPHONE_END_NAMESPACE diff --git a/src/core/paths/paths-windows.h b/src/core/paths/paths-windows.h index 2429bb46d..1ee9d92f7 100644 --- a/src/core/paths/paths-windows.h +++ b/src/core/paths/paths-windows.h @@ -31,8 +31,8 @@ LINPHONE_BEGIN_NAMESPACE class PlatformHelpers; namespace SysPaths { - LINPHONE_PUBLIC std::string getDataPath (PlatformHelpers *platformHelper); - LINPHONE_PUBLIC std::string getConfigPath (PlatformHelpers *platformHelper); + LINPHONE_PUBLIC std::string getDataPath (PlatformHelpers *platformHelpers); + LINPHONE_PUBLIC std::string getConfigPath (PlatformHelpers *platformHelpers); } LINPHONE_END_NAMESPACE diff --git a/src/core/paths/paths.cpp b/src/core/paths/paths.cpp index a2f65d95e..3f5dd2374 100644 --- a/src/core/paths/paths.cpp +++ b/src/core/paths/paths.cpp @@ -38,12 +38,12 @@ using namespace std; LINPHONE_BEGIN_NAMESPACE -string Paths::getPath (Paths::Type type, PlatformHelpers *platformHelper) { +string Paths::getPath (Paths::Type type, PlatformHelpers *platformHelpers) { switch (type) { case Data: - return SysPaths::getDataPath(platformHelper); + return SysPaths::getDataPath(platformHelpers); case Config: - return SysPaths::getConfigPath(platformHelper); + return SysPaths::getConfigPath(platformHelpers); } L_ASSERT(false); diff --git a/src/core/paths/paths.h b/src/core/paths/paths.h index 83976401f..f7fdf9b5b 100644 --- a/src/core/paths/paths.h +++ b/src/core/paths/paths.h @@ -35,7 +35,7 @@ namespace Paths { Config }; - LINPHONE_PUBLIC std::string getPath (Type type, PlatformHelpers *platformHelper); + LINPHONE_PUBLIC std::string getPath (Type type, PlatformHelpers *platformHelpers); } LINPHONE_END_NAMESPACE diff --git a/src/core/platform-helpers/android-platform-helpers.cpp b/src/core/platform-helpers/android-platform-helpers.cpp index ca6fa3c89..fe27646cb 100644 --- a/src/core/platform-helpers/android-platform-helpers.cpp +++ b/src/core/platform-helpers/android-platform-helpers.cpp @@ -123,7 +123,7 @@ AndroidPlatformHelpers::~AndroidPlatformHelpers () { } void AndroidPlatformHelpers::setDnsServers () { - if (!mJavaHelper) { + if (!mJavaHelper || linphone_core_get_dns_set_by_app(mCore)) { lError() << "AndroidPlatformHelpers' mJavaHelper is null."; return; } diff --git a/src/core/platform-helpers/ios-platform-helpers.cpp b/src/core/platform-helpers/ios-platform-helpers.cpp new file mode 100644 index 000000000..6e9ed2f5b --- /dev/null +++ b/src/core/platform-helpers/ios-platform-helpers.cpp @@ -0,0 +1,119 @@ +/* +linphone +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. +*/ + +#ifdef __APPLE__ +#include "TargetConditionals.h" +#endif + +#if TARGET_OS_IPHONE + +#include "linphone/utils/general.h" +#include "linphone/utils/utils.h" + +#include "logger/logger.h" +#include "platform-helpers.h" + +// TODO: Remove me +#include "private.h" + +// ============================================================================= + +using namespace std; + +LINPHONE_BEGIN_NAMESPACE + +class IosPlatformHelpers : public PlatformHelpers { +public: + IosPlatformHelpers (LinphoneCore *lc, void *system_context); + ~IosPlatformHelpers () = default; + + void setDnsServers () override {} + void acquireWifiLock () override {} + void releaseWifiLock () override {} + void acquireMcastLock () override {} + void releaseMcastLock () override {} + void acquireCpuLock () override; + void releaseCpuLock () override; + string getDataPath () override {return Utils::getEmptyConstRefObject();} + string getConfigPath () override {return Utils::getEmptyConstRefObject();} + +private: + void bgTaskTimeout (); + static void sBgTaskTimeout (void *data); + + long int mCpuLockTaskId; + int mCpuLockCount; +}; + +// ============================================================================= + +IosPlatformHelpers::IosPlatformHelpers (LinphoneCore *lc, void *system_context) : PlatformHelpers(lc) { + mCpuLockCount = 0; + mCpuLockTaskId = 0; + lInfo() << "IosPlatformHelpers is fully initialised"; +} + +// ----------------------------------------------------------------------------- + +void IosPlatformHelpers::bgTaskTimeout () { + lError() << "IosPlatformHelpers: the system requests that the cpu lock is released now."; + if (mCpuLockTaskId != 0) { + belle_sip_end_background_task(static_cast(mCpuLockTaskId)); + mCpuLockTaskId = 0; + } +} + +void IosPlatformHelpers::sBgTaskTimeout (void *data) { + IosPlatformHelpers *zis = static_cast(data); + zis->bgTaskTimeout(); +} + +// ----------------------------------------------------------------------------- + +void IosPlatformHelpers::acquireCpuLock () { + // on iOS, cpu lock is implemented by a long running task and it is abstracted by belle-sip, so let's use belle-sip directly. + if (mCpuLockCount == 0) + mCpuLockTaskId = static_cast(belle_sip_begin_background_task("Liblinphone cpu lock", sBgTaskTimeout, this)); + + mCpuLockCount++; +} + +void IosPlatformHelpers::releaseCpuLock () { + mCpuLockCount--; + if (mCpuLockCount != 0) + return; + + if (mCpuLockTaskId == 0) { + lError() << "IosPlatformHelpers::releaseCpuLock(): too late, the lock has been released already by the system."; + return; + } + + belle_sip_end_background_task(static_cast(mCpuLockTaskId)); + mCpuLockTaskId = 0; +} + +// ----------------------------------------------------------------------------- + +PlatformHelpers *createIosPlatformHelpers (LinphoneCore *lc, void *system_context) { + return new IosPlatformHelpers(lc, system_context); +} + +LINPHONE_END_NAMESPACE + +#endif diff --git a/src/core/platform-helpers/platform-helpers.h b/src/core/platform-helpers/platform-helpers.h index a0fd0b073..6a55c8756 100644 --- a/src/core/platform-helpers/platform-helpers.h +++ b/src/core/platform-helpers/platform-helpers.h @@ -72,6 +72,7 @@ public: }; PlatformHelpers *createAndroidPlatformHelpers (LinphoneCore *lc, void *systemContext); +PlatformHelpers *createIosPlatformHelpers (LinphoneCore *lc, void *systemContext); LINPHONE_END_NAMESPACE diff --git a/src/db/internal/statements.cpp b/src/db/internal/statements.cpp index 6b6754228..01ae12da0 100644 --- a/src/db/internal/statements.cpp +++ b/src/db/internal/statements.cpp @@ -55,33 +55,33 @@ namespace Statements { // --------------------------------------------------------------------------- constexpr const char *select[SelectCount] = { - [SelectSipAddressId] = R"( + /* SelectSipAddressId */ R"( SELECT id FROM sip_address WHERE value = :1 )", - [SelectChatRoomId] = R"( + /* SelectChatRoomId */ R"( SELECT id FROM chat_room WHERE peer_sip_address_id = :1 AND local_sip_address_id = :2 )", - [SelectChatRoomParticipantId] = R"( + /* SelectChatRoomParticipantId */ R"( SELECT id FROM chat_room_participant WHERE chat_room_id = :1 AND participant_sip_address_id = :2 )", - [SelectOneToOneChatRoomId] = R"( + /* SelectOneToOneChatRoomId */ R"( SELECT chat_room_id FROM one_to_one_chat_room WHERE participant_a_sip_address_id IN (:1, :2) AND participant_b_sip_address_id IN (:3, :4) )", - [SelectConferenceEvent] = R"( - SELECT conference_event_view.id AS event_id, type, conference_event_view.creation_time, from_sip_address.value, to_sip_address.value, time, imdn_message_id, state, direction, is_secured, notify_id, device_sip_address.value, participant_sip_address.value, conference_event_view.subject, peer_sip_address.value, local_sip_address.value + /* SelectConferenceEvent */ R"( + SELECT conference_event_view.id AS event_id, type, conference_event_view.creation_time, from_sip_address.value, to_sip_address.value, time, imdn_message_id, state, direction, is_secured, notify_id, device_sip_address.value, participant_sip_address.value, conference_event_view.subject, delivery_notification_required, display_notification_required, peer_sip_address.value, local_sip_address.value FROM conference_event_view JOIN chat_room ON chat_room.id = chat_room_id JOIN sip_address AS peer_sip_address ON peer_sip_address.id = peer_sip_address_id @@ -93,8 +93,8 @@ namespace Statements { WHERE event_id = :1 )", - [SelectConferenceEvents] = R"( - SELECT conference_event_view.id AS event_id, type, creation_time, from_sip_address.value, to_sip_address.value, time, imdn_message_id, state, direction, is_secured, notify_id, device_sip_address.value, participant_sip_address.value, subject + /* SelectConferenceEvents */ R"( + SELECT conference_event_view.id AS event_id, type, creation_time, from_sip_address.value, to_sip_address.value, time, imdn_message_id, state, direction, is_secured, notify_id, device_sip_address.value, participant_sip_address.value, subject, delivery_notification_required, display_notification_required FROM conference_event_view LEFT JOIN sip_address AS from_sip_address ON from_sip_address.id = from_sip_address_id LEFT JOIN sip_address AS to_sip_address ON to_sip_address.id = to_sip_address_id @@ -109,7 +109,7 @@ namespace Statements { // --------------------------------------------------------------------------- constexpr AbstractStatement insert[InsertCount] = { - [InsertOneToOneChatRoom] = R"( + /* InsertOneToOneChatRoom */ R"( INSERT INTO one_to_one_chat_room ( chat_room_id, participant_a_sip_address_id, participant_b_sip_address_id ) VALUES (:1, :2, :3) diff --git a/src/db/main-db-p.h b/src/db/main-db-p.h index 8a8a52ad1..41b4e5c6f 100644 --- a/src/db/main-db-p.h +++ b/src/db/main-db-p.h @@ -44,6 +44,8 @@ private: // Misc helpers. // --------------------------------------------------------------------------- + static time_t getTmAsTimeT (const tm &t); + std::shared_ptr findChatRoom (const ChatRoomId &chatRoomId) const; // --------------------------------------------------------------------------- @@ -58,10 +60,10 @@ private: long long localSipAddressId, const tm &creationTime ); - long long insertChatRoom (const std::shared_ptr &chatRoom); + long long insertChatRoom (const std::shared_ptr &chatRoom, unsigned int notifyId = 0); long long insertChatRoomParticipant (long long chatRoomId, long long participantSipAddressId, bool isAdmin); void insertChatRoomParticipantDevice (long long participantId, long long participantDeviceSipAddressId); - void insertChatMessageParticipant (long long chatMessageId, long long sipAddressId, int state); + void insertChatMessageParticipant (long long chatMessageId, long long sipAddressId, int state, time_t stateChangeTime); long long selectSipAddressId (const std::string &sipAddress) const; long long selectChatRoomId (long long peerSipAddressId, long long localSipAddressId) const; @@ -148,6 +150,13 @@ private: long long insertConferenceParticipantDeviceEvent (const std::shared_ptr &eventLog); long long insertConferenceSubjectEvent (const std::shared_ptr &eventLog); + void setChatMessageParticipantState ( + const std::shared_ptr &eventLog, + const IdentityAddress &participantAddress, + ChatMessage::State state, + time_t stateChangeTime + ); + // --------------------------------------------------------------------------- // Cache API. // --------------------------------------------------------------------------- diff --git a/src/db/main-db.cpp b/src/db/main-db.cpp index e6cfd375d..f96a6e14d 100644 --- a/src/db/main-db.cpp +++ b/src/db/main-db.cpp @@ -26,6 +26,7 @@ #include "chat/chat-room/chat-room-p.h" #include "chat/chat-room/client-group-chat-room.h" #include "chat/chat-room/server-group-chat-room.h" +#include "conference/participant-device.h" #include "conference/participant-p.h" #include "core/core-p.h" #include "event-log/event-log-p.h" @@ -47,7 +48,7 @@ using namespace std; LINPHONE_BEGIN_NAMESPACE namespace { - constexpr unsigned int ModuleVersionEvents = makeVersion(1, 0, 1); + constexpr unsigned int ModuleVersionEvents = makeVersion(1, 0, 4); constexpr unsigned int ModuleVersionFriends = makeVersion(1, 0, 0); constexpr unsigned int ModuleVersionLegacyFriendsImport = makeVersion(1, 0, 0); constexpr unsigned int ModuleVersionLegacyHistoryImport = makeVersion(1, 0, 0); @@ -226,6 +227,12 @@ static string buildSqlEventFilter ( // Misc helpers. // ----------------------------------------------------------------------------- +time_t MainDbPrivate::getTmAsTimeT (const tm &t) { + tm t2 = t; + t2.tm_isdst = 0; + return Utils::getTmAsTimeT(t2); +} + shared_ptr MainDbPrivate::findChatRoom (const ChatRoomId &chatRoomId) const { L_Q(); shared_ptr chatRoom = q->getCore()->findChatRoom(chatRoomId); @@ -315,14 +322,18 @@ long long MainDbPrivate::insertOrUpdateImportedBasicChatRoom ( return dbSession.getLastInsertId(); } -long long MainDbPrivate::insertChatRoom (const shared_ptr &chatRoom) { +long long MainDbPrivate::insertChatRoom (const shared_ptr &chatRoom, unsigned int notifyId) { const ChatRoomId &chatRoomId = chatRoom->getChatRoomId(); const long long &peerSipAddressId = insertSipAddress(chatRoomId.getPeerAddress().asString()); const long long &localSipAddressId = insertSipAddress(chatRoomId.getLocalAddress().asString()); long long id = selectChatRoomId(peerSipAddressId, localSipAddressId); - if (id >= 0) + if (id >= 0) { + // The chat room is already stored in DB, but still update the notify id that might have changed + *dbSession.getBackendSession() << "UPDATE chat_room SET last_notify_id = :lastNotifyId WHERE id = :chatRoomId", + soci::use(notifyId), soci::use(id); return id; + } lInfo() << "Insert new chat room in database: " << chatRoomId << "."; @@ -335,10 +346,14 @@ long long MainDbPrivate::insertChatRoom (const shared_ptr &cha const string &subject = chatRoom->getSubject(); const int &flags = chatRoom->hasBeenLeft(); *dbSession.getBackendSession() << "INSERT INTO chat_room (" - " peer_sip_address_id, local_sip_address_id, creation_time, last_update_time, capabilities, subject, flags" - ") VALUES (:peerSipAddressId, :localSipAddressId, :creationTime, :lastUpdateTime, :capabilities, :subject, :flags)", - soci::use(peerSipAddressId), soci::use(localSipAddressId), soci::use(creationTime), soci::use(lastUpdateTime), - soci::use(capabilities), soci::use(subject), soci::use(flags); + " peer_sip_address_id, local_sip_address_id, creation_time," + " last_update_time, capabilities, subject, flags, last_notify_id" + ") VALUES (" + " :peerSipAddressId, :localSipAddressId, :creationTime," + " :lastUpdateTime, :capabilities, :subject, :flags, :lastNotifyId" + ")", + soci::use(peerSipAddressId), soci::use(localSipAddressId), soci::use(creationTime), + soci::use(lastUpdateTime), soci::use(capabilities), soci::use(subject), soci::use(flags), soci::use(notifyId); id = dbSession.getLastInsertId(); if (!chatRoom->canHandleParticipants()) @@ -408,12 +423,12 @@ void MainDbPrivate::insertChatRoomParticipantDevice ( soci::use(participantId), soci::use(participantDeviceSipAddressId); } -void MainDbPrivate::insertChatMessageParticipant (long long chatMessageId, long long sipAddressId, int state) { - if (state != static_cast(ChatMessage::State::Displayed)) - *dbSession.getBackendSession() << - "INSERT INTO chat_message_participant (event_id, participant_sip_address_id, state)" - " VALUES (:chatMessageId, :sipAddressId, :state)", - soci::use(chatMessageId), soci::use(sipAddressId), soci::use(state); +void MainDbPrivate::insertChatMessageParticipant (long long chatMessageId, long long sipAddressId, int state, time_t stateChangeTime) { + const tm &stateChangeTm = Utils::getTimeTAsTm(stateChangeTime); + *dbSession.getBackendSession() << + "INSERT INTO chat_message_participant (event_id, participant_sip_address_id, state, state_change_time)" + " VALUES (:chatMessageId, :sipAddressId, :state, :stateChangeTm)", + soci::use(chatMessageId), soci::use(sipAddressId), soci::use(state), soci::use(stateChangeTm); } // ----------------------------------------------------------------------------- @@ -610,8 +625,10 @@ shared_ptr MainDbPrivate::selectConferenceChatMessageEvent ( dChatMessage->forceFromAddress(IdentityAddress(row.get(3))); dChatMessage->forceToAddress(IdentityAddress(row.get(4))); - dChatMessage->setTime(Utils::getTmAsTimeT(row.get(5))); + dChatMessage->setTime(MainDbPrivate::getTmAsTimeT(row.get(5))); dChatMessage->setImdnMessageId(row.get(6)); + dChatMessage->setPositiveDeliveryNotificationRequired(bool(row.get(14))); + dChatMessage->setDisplayNotificationRequired(bool(row.get(15))); dChatMessage->markContentsAsNotLoaded(); dChatMessage->setIsReadOnly(true); @@ -701,7 +718,9 @@ long long MainDbPrivate::insertConferenceEvent (const shared_ptr &even soci::use(curChatRoomId); if (eventLog->getType() == EventLog::Type::ConferenceTerminated) - *session << "UPDATE chat_room SET flags = 1 WHERE id = :chatRoomId", soci::use(curChatRoomId); + *session << "UPDATE chat_room SET flags = 1, last_notify_id = 0 WHERE id = :chatRoomId", soci::use(curChatRoomId); + else if (eventLog->getType() == EventLog::Type::ConferenceCreated) + *session << "UPDATE chat_room SET flags = 0 WHERE id = :chatRoomId", soci::use(curChatRoomId); } if (chatRoomId) @@ -728,23 +747,28 @@ long long MainDbPrivate::insertConferenceChatMessageEvent (const shared_ptrgetDirection()); const string &imdnMessageId = chatMessage->getImdnMessageId(); const int &isSecured = chatMessage->isSecured() ? 1 : 0; + const int &deliveryNotificationRequired = chatMessage->getPrivate()->getPositiveDeliveryNotificationRequired(); + const int &displayNotificationRequired = chatMessage->getPrivate()->getDisplayNotificationRequired(); *dbSession.getBackendSession() << "INSERT INTO conference_chat_message_event (" " event_id, from_sip_address_id, to_sip_address_id," - " time, state, direction, imdn_message_id, is_secured" + " time, state, direction, imdn_message_id, is_secured," + " delivery_notification_required, display_notification_required" ") VALUES (" " :eventId, :localSipaddressId, :remoteSipaddressId," - " :time, :state, :direction, :imdnMessageId, :isSecured" + " :time, :state, :direction, :imdnMessageId, :isSecured," + " :deliveryNotificationRequired, :displayNotificationRequired" ")", soci::use(eventId), soci::use(fromSipAddressId), soci::use(toSipAddressId), soci::use(messageTime), soci::use(state), soci::use(direction), - soci::use(imdnMessageId), soci::use(isSecured); + soci::use(imdnMessageId), soci::use(isSecured), + soci::use(deliveryNotificationRequired), soci::use(displayNotificationRequired); for (const Content *content : chatMessage->getContents()) insertContent(eventId, *content); for (const auto &participant : chatMessage->getChatRoom()->getParticipants()) { const long long &participantSipAddressId = selectSipAddressId(participant->getAddress().asString()); - insertChatMessageParticipant(eventId, participantSipAddressId, state); + insertChatMessageParticipant(eventId, participantSipAddressId, state, chatMessage->getTime()); } return eventId; @@ -766,6 +790,13 @@ void MainDbPrivate::updateConferenceChatMessageEvent (const shared_ptr deleteContents(eventId); for (const auto &content : chatMessage->getContents()) insertContent(eventId, *content); + + if ((chatMessage->getDirection() == ChatMessage::Direction::Outgoing) + && ((chatMessage->getState() == ChatMessage::State::Delivered) || (chatMessage->getState() == ChatMessage::State::NotDelivered)) + ) { + for (const auto &participant : chatMessage->getChatRoom()->getParticipants()) + setChatMessageParticipantState(eventLog, participant->getAddress(), chatMessage->getState(), std::time(nullptr)); + } } long long MainDbPrivate::insertConferenceNotifiedEvent (const shared_ptr &eventLog, long long *chatRoomId) { @@ -891,6 +922,26 @@ long long MainDbPrivate::insertConferenceSubjectEvent (const shared_ptr &eventLog, + const IdentityAddress &participantAddress, + ChatMessage::State state, + time_t stateChangeTime +) { + const EventLogPrivate *dEventLog = eventLog->getPrivate(); + MainDbKeyPrivate *dEventKey = static_cast(dEventLog->dbKey).getPrivate(); + const long long &eventId = dEventKey->storageId; + const long long &participantSipAddressId = selectSipAddressId(participantAddress.asString()); + int stateInt = static_cast(state); + const tm &stateChangeTm = Utils::getTimeTAsTm(stateChangeTime); + + *dbSession.getBackendSession() << "UPDATE chat_message_participant SET state = :state," + " state_change_time = :stateChangeTm" + " WHERE event_id = :eventId AND participant_sip_address_id = :participantSipAddressId", + soci::use(stateInt), soci::use(stateChangeTm), soci::use(eventId), soci::use(participantSipAddressId); +} + + // ----------------------------------------------------------------------------- // Cache API. // ----------------------------------------------------------------------------- @@ -968,7 +1019,7 @@ unsigned int MainDbPrivate::getModuleVersion (const string &name) { void MainDbPrivate::updateModuleVersion (const string &name, unsigned int version) { unsigned int oldVersion = getModuleVersion(name); - if (oldVersion == version) + if (version <= oldVersion) return; soci::session *session = dbSession.getBackendSession(); @@ -977,11 +1028,48 @@ void MainDbPrivate::updateModuleVersion (const string &name, unsigned int versio } void MainDbPrivate::updateSchema () { + L_Q(); + soci::session *session = dbSession.getBackendSession(); unsigned int version = getModuleVersion("events"); if (version < makeVersion(1, 0, 1)) *session << "ALTER TABLE chat_room_participant_device ADD COLUMN state TINYINT UNSIGNED DEFAULT 0"; + if (version < makeVersion(1, 0, 2)) { + *session << "DROP TRIGGER IF EXISTS chat_message_participant_deleter"; + *session << "ALTER TABLE chat_message_participant ADD COLUMN state_change_time" + + dbSession.timestampType() + " NOT NULL DEFAULT " + dbSession.currentTimestamp(); + } + if (version < makeVersion(1, 0, 3)) { + // Remove client group one-to-one chat rooms for the moment as there are still some issues + // with them and we prefer to keep using basic chat rooms instead + const int &capabilities = ChatRoom::CapabilitiesMask(ChatRoom::Capabilities::Conference) + | ChatRoom::CapabilitiesMask(ChatRoom::Capabilities::OneToOne); + *session << "DELETE FROM chat_room WHERE (capabilities & :capabilities1) = :capabilities2", + soci::use(capabilities), soci::use(capabilities); + linphone_config_set_bool(linphone_core_get_config(q->getCore()->getCCore()), "misc", "prefer_basic_chat_room", TRUE); + } + if (version < makeVersion(1, 0, 4)) { + *session << "ALTER TABLE conference_chat_message_event ADD COLUMN delivery_notification_required BOOLEAN NOT NULL DEFAULT 0"; + *session << "ALTER TABLE conference_chat_message_event ADD COLUMN display_notification_required BOOLEAN NOT NULL DEFAULT 0"; + + *session << "DROP VIEW IF EXISTS conference_event_view"; + + string query; + if (q->getBackend() == AbstractDb::Backend::Mysql) + query = "CREATE OR REPLACE VIEW conference_event_view AS"; + else + query = "CREATE VIEW IF NOT EXISTS conference_event_view AS"; + *session << query + + " SELECT id, type, creation_time, chat_room_id, from_sip_address_id, to_sip_address_id, time, imdn_message_id, state, direction, is_secured, notify_id, device_sip_address_id, participant_sip_address_id, subject, delivery_notification_required, display_notification_required" + " FROM event" + " LEFT JOIN conference_event ON conference_event.event_id = event.id" + " LEFT JOIN conference_chat_message_event ON conference_chat_message_event.event_id = event.id" + " LEFT JOIN conference_notified_event ON conference_notified_event.event_id = event.id" + " LEFT JOIN conference_participant_device_event ON conference_participant_device_event.event_id = event.id" + " LEFT JOIN conference_participant_event ON conference_participant_event.event_id = event.id" + " LEFT JOIN conference_subject_event ON conference_subject_event.event_id = event.id"; + } } // ----------------------------------------------------------------------------- @@ -1210,26 +1298,28 @@ void MainDbPrivate::importLegacyHistory (DbSession &inDbSession) { creationTime ); const int &isSecured = message.get(LegacyMessageColIsSecured, 0); + const int deliveryNotificationRequired = 0; + const int displayNotificationRequired = 0; *session << "INSERT INTO conference_event (event_id, chat_room_id)" " VALUES (:eventId, :chatRoomId)", soci::use(eventId), soci::use(chatRoomId); *session << "INSERT INTO conference_chat_message_event (" " event_id, from_sip_address_id, to_sip_address_id," - " time, state, direction, imdn_message_id, is_secured" + " time, state, direction, imdn_message_id, is_secured," + " delivery_notification_required, display_notification_required" ") VALUES (" " :eventId, :localSipAddressId, :remoteSipAddressId," - " :creationTime, :state, :direction, '', :isSecured" + " :creationTime, :state, :direction, '', :isSecured," + " :deliveryNotificationRequired, :displayNotificationRequired" ")", soci::use(eventId), soci::use(localSipAddressId), soci::use(remoteSipAddressId), - soci::use(creationTime), soci::use(state), soci::use(direction), - soci::use(isSecured); + soci::use(creationTime), soci::use(state), soci::use(direction), soci::use(isSecured), + soci::use(deliveryNotificationRequired), soci::use(displayNotificationRequired); if (content) insertContent(eventId, *content); insertChatRoomParticipant(chatRoomId, remoteSipAddressId, false); - - if (state != int(ChatMessage::State::Displayed)) - insertChatMessageParticipant(eventId, remoteSipAddressId, state); + insertChatMessageParticipant(eventId, remoteSipAddressId, state, std::time(nullptr)); } tr.commit(); lInfo() << "Successful import of legacy messages."; @@ -1570,50 +1660,12 @@ void MainDb::init () { " ON DELETE CASCADE" ") " + charset; - { - string query; - if (getBackend() == Backend::Mysql) - query = "CREATE OR REPLACE VIEW conference_event_view AS"; - else - query = "CREATE VIEW IF NOT EXISTS conference_event_view AS"; - - *session << query + - " SELECT id, type, creation_time, chat_room_id, from_sip_address_id, to_sip_address_id, time, imdn_message_id, state, direction, is_secured, notify_id, device_sip_address_id, participant_sip_address_id, subject" - " FROM event" - " LEFT JOIN conference_event ON conference_event.event_id = event.id" - " LEFT JOIN conference_chat_message_event ON conference_chat_message_event.event_id = event.id" - " LEFT JOIN conference_notified_event ON conference_notified_event.event_id = event.id" - " LEFT JOIN conference_participant_device_event ON conference_participant_device_event.event_id = event.id" - " LEFT JOIN conference_participant_event ON conference_participant_event.event_id = event.id" - " LEFT JOIN conference_subject_event ON conference_subject_event.event_id = event.id"; - } - *session << "CREATE TABLE IF NOT EXISTS db_module_version (" " name" + varcharPrimaryKeyStr(255) + "," " version INT UNSIGNED NOT NULL" ") " + charset; - if (getBackend() == Backend::Mysql) { - *session << - "DROP TRIGGER IF EXISTS chat_message_participant_deleter"; - *session << - "CREATE TRIGGER chat_message_participant_deleter" - " AFTER UPDATE ON conference_chat_message_event FOR EACH ROW" - " BEGIN" - " IF NEW.state = " + Utils::toString(int(ChatMessage::State::Displayed)) + " THEN" - " DELETE FROM chat_message_participant WHERE event_id = NEW.event_id;" - " END IF;" - " END "; - } else - *session << - "CREATE TRIGGER IF NOT EXISTS chat_message_participant_deleter" - " AFTER UPDATE OF state ON conference_chat_message_event FOR EACH ROW" - " WHEN NEW.state = " + Utils::toString(int(ChatMessage::State::Displayed)) + - " BEGIN" - " DELETE FROM chat_message_participant WHERE event_id = NEW.event_id;" - " END "; - d->updateSchema(); d->updateModuleVersion("events", ModuleVersionEvents); @@ -1785,7 +1837,7 @@ shared_ptr MainDb::getEventFromKey (const MainDbKey &dbKey) { *d->dbSession.getBackendSession() << Statements::get(Statements::SelectConferenceEvent), soci::into(row), soci::use(eventId); - ChatRoomId chatRoomId(IdentityAddress(row.get(14)), IdentityAddress(row.get(15))); + ChatRoomId chatRoomId(IdentityAddress(row.get(16)), IdentityAddress(row.get(17))); shared_ptr chatRoom = d->findChatRoom(chatRoomId); if (!chatRoom) return shared_ptr(); @@ -1947,6 +1999,33 @@ list> MainDb::getUnreadChatMessages (const ChatRoomId &c }; } +list MainDb::getChatMessageParticipantsByImdnState ( + const shared_ptr &eventLog, + ChatMessage::State state +) const { + return L_DB_TRANSACTION { + L_D(); + + const EventLogPrivate *dEventLog = eventLog->getPrivate(); + MainDbKeyPrivate *dEventKey = static_cast(dEventLog->dbKey).getPrivate(); + const long long &eventId = dEventKey->storageId; + int stateInt = static_cast(state); + + static const string query = "SELECT sip_address.value, chat_message_participant.state_change_time" + " FROM sip_address, chat_message_participant" + " WHERE event_id = :eventId AND state = :state" + " AND sip_address.id = chat_message_participant.participant_sip_address_id"; + soci::rowset rows = (d->dbSession.getBackendSession()->prepare << query, + soci::use(eventId), soci::use(stateInt) + ); + + list result; + for (const auto &row : rows) + result.emplace_back(IdentityAddress(row.get(0)), state, MainDbPrivate::getTmAsTimeT(row.get(1))); + return result; + }; +} + list MainDb::getChatMessageParticipantStates (const shared_ptr &eventLog) const { return L_DB_TRANSACTION { L_D(); @@ -1970,30 +2049,6 @@ list MainDb::getChatMessageParticipantStates (const shared_p }; } -list MainDb::getChatMessageParticipantsInState (const shared_ptr &eventLog, const ChatMessage::State state) const { - return L_DB_TRANSACTION { - L_D(); - - const EventLogPrivate *dEventLog = eventLog->getPrivate(); - MainDbKeyPrivate *dEventKey = static_cast(dEventLog->dbKey).getPrivate(); - const long long &eventId = dEventKey->storageId; - - int stateInt = static_cast(state); - list participantsAddresses; - - static const string query = "SELECT sip_address.value" - " FROM sip_address, chat_message_participant" - " WHERE event_id = :eventId AND state = :state" - " AND sip_address.id = chat_message_participant.participant_sip_address_id"; - soci::rowset rows = (d->dbSession.getBackendSession()->prepare << query, soci::use(eventId), soci::use(stateInt)); - for (const auto &row : rows) { - participantsAddresses.push_back(IdentityAddress(row.get(0))); - } - - return participantsAddresses; - }; -} - ChatMessage::State MainDb::getChatMessageParticipantState ( const shared_ptr &eventLog, const IdentityAddress &participantAddress @@ -2018,21 +2073,12 @@ ChatMessage::State MainDb::getChatMessageParticipantState ( void MainDb::setChatMessageParticipantState ( const shared_ptr &eventLog, const IdentityAddress &participantAddress, - ChatMessage::State state + ChatMessage::State state, + time_t stateChangeTime ) { L_DB_TRANSACTION { L_D(); - - const EventLogPrivate *dEventLog = eventLog->getPrivate(); - MainDbKeyPrivate *dEventKey = static_cast(dEventLog->dbKey).getPrivate(); - const long long &eventId = dEventKey->storageId; - const long long &participantSipAddressId = d->selectSipAddressId(participantAddress.asString()); - int stateInt = static_cast(state); - - *d->dbSession.getBackendSession() << "UPDATE chat_message_participant SET state = :state" - " WHERE event_id = :eventId AND participant_sip_address_id = :participantSipAddressId", - soci::use(stateInt), soci::use(eventId), soci::use(participantSipAddressId); - + d->setChatMessageParticipantState(eventLog, participantAddress, state, stateChangeTime); tr.commit(); }; } @@ -2082,6 +2128,43 @@ list> MainDb::findChatMessages ( }; } +list> MainDb::findChatMessagesToBeNotifiedAsDelivered ( + const ChatRoomId &chatRoomId +) const { + static const string query = Statements::get(Statements::SelectConferenceEvents) + + string(" AND direction = :direction AND state = :state AND delivery_notification_required <> 0"); + + DurationLogger durationLogger( + "Find chat messages to be notified as delivered: (peer=" + chatRoomId.getPeerAddress().asString() + + ", local=" + chatRoomId.getLocalAddress().asString() + ")." + ); + + return L_DB_TRANSACTION { + L_D(); + + shared_ptr chatRoom = d->findChatRoom(chatRoomId); + list> chatMessages; + if (!chatRoom) + return chatMessages; + + const long long &dbChatRoomId = d->selectChatRoomId(chatRoomId); + const int &state = int(ChatMessage::State::Delivered); + const int &direction = int(ChatMessage::Direction::Incoming); + soci::rowset rows = ( + d->dbSession.getBackendSession()->prepare << query, soci::use(dbChatRoomId), soci::use(direction), soci::use(state) + ); + for (const auto &row : rows) { + shared_ptr event = d->selectGenericConferenceEvent(chatRoom, row); + if (event) { + L_ASSERT(event->getType() == EventLog::Type::ConferenceChatMessage); + chatMessages.push_back(static_pointer_cast(event)->getChatMessage()); + } + } + + return chatMessages; + }; +} + list> MainDb::getHistory (const ChatRoomId &chatRoomId, int nLast, FilterMask mask) const { return getHistoryRange(chatRoomId, 0, nLast, mask); } @@ -2226,7 +2309,7 @@ void MainDb::loadChatMessageContents (const shared_ptr &chatMessage string data; fetchContentAppData(session, *content, contentId, data); } - chatMessage->addContent(*content); + chatMessage->addContent(content); } // 2 - Load external body url from body into FileTransferContent if needed. @@ -2353,7 +2436,8 @@ list> MainDb::getChatRooms () const { capabilities, subject, move(participants), - lastNotifyId + lastNotifyId, + hasBeenLeft ); AbstractChatRoomPrivate *dChatRoom = chatRoom->getPrivate(); dChatRoom->setState(ChatRoom::State::Instantiated); @@ -2380,8 +2464,8 @@ list> MainDb::getChatRooms () const { continue; // Not fetched. AbstractChatRoomPrivate *dChatRoom = chatRoom->getPrivate(); - dChatRoom->setCreationTime(Utils::getTmAsTimeT(creationTime)); - dChatRoom->setLastUpdateTime(Utils::getTmAsTimeT(lastUpdateTime)); + dChatRoom->setCreationTime(MainDbPrivate::getTmAsTimeT(creationTime)); + dChatRoom->setLastUpdateTime(MainDbPrivate::getTmAsTimeT(lastUpdateTime)); lInfo() << "Found chat room in DB: (peer=" << chatRoomId.getPeerAddress().asString() << ", local=" << chatRoomId.getLocalAddress().asString() << ")."; @@ -2395,11 +2479,11 @@ list> MainDb::getChatRooms () const { }; } -void MainDb::insertChatRoom (const shared_ptr &chatRoom) { +void MainDb::insertChatRoom (const shared_ptr &chatRoom, unsigned int notifyId) { L_DB_TRANSACTION { L_D(); - d->insertChatRoom(chatRoom); + d->insertChatRoom(chatRoom, notifyId); tr.commit(); }; } diff --git a/src/db/main-db.h b/src/db/main-db.h index ae46a5e3e..53d471dbc 100644 --- a/src/db/main-db.h +++ b/src/db/main-db.h @@ -20,6 +20,7 @@ #ifndef _L_MAIN_DB_H_ #define _L_MAIN_DB_H_ +#include #include #include "linphone/utils/enum-mask.h" @@ -59,6 +60,15 @@ public: typedef EnumMask FilterMask; + struct ParticipantState { + ParticipantState (const IdentityAddress &address, ChatMessage::State state, time_t timestamp) + : address(address), state(state), timestamp(timestamp) {} + + IdentityAddress address; + ChatMessage::State state = ChatMessage::State::Idle; + time_t timestamp = 0; + }; + MainDb (const std::shared_ptr &core); // --------------------------------------------------------------------------- @@ -85,13 +95,18 @@ public: // Conference chat message events. // --------------------------------------------------------------------------- + using ParticipantStateRetrievalFunc = std::function(const std::shared_ptr &eventLog)>; + int getChatMessageCount (const ChatRoomId &chatRoomId = ChatRoomId()) const; int getUnreadChatMessageCount (const ChatRoomId &chatRoomId = ChatRoomId()) const; void markChatMessagesAsRead (const ChatRoomId &chatRoomId) const; std::list> getUnreadChatMessages (const ChatRoomId &chatRoomId) const; + std::list getChatMessageParticipantsByImdnState ( + const std::shared_ptr &eventLog, + ChatMessage::State state + ) const; std::list getChatMessageParticipantStates (const std::shared_ptr &eventLog) const; - std::list getChatMessageParticipantsInState (const std::shared_ptr &eventLog, const ChatMessage::State state) const; ChatMessage::State getChatMessageParticipantState ( const std::shared_ptr &eventLog, const IdentityAddress &participantAddress @@ -99,7 +114,8 @@ public: void setChatMessageParticipantState ( const std::shared_ptr &eventLog, const IdentityAddress &participantAddress, - ChatMessage::State state + ChatMessage::State state, + time_t stateChangeTime ); std::shared_ptr getLastChatMessage (const ChatRoomId &chatRoomId) const; @@ -109,6 +125,10 @@ public: const std::string &imdnMessageId ) const; + std::list> findChatMessagesToBeNotifiedAsDelivered ( + const ChatRoomId &chatRoomId + ) const; + // --------------------------------------------------------------------------- // Conference events. // --------------------------------------------------------------------------- @@ -140,7 +160,7 @@ public: // --------------------------------------------------------------------------- std::list> getChatRooms () const; - void insertChatRoom (const std::shared_ptr &chatRoom); + void insertChatRoom (const std::shared_ptr &chatRoom, unsigned int notifyId = 0); void deleteChatRoom (const ChatRoomId &chatRoomId); void enableChatRoomMigration (const ChatRoomId &chatRoomId, bool enable); diff --git a/src/db/session/db-session.cpp b/src/db/session/db-session.cpp index e9fbc4450..b78ae04e7 100644 --- a/src/db/session/db-session.cpp +++ b/src/db/session/db-session.cpp @@ -124,6 +124,31 @@ string DbSession::varcharPrimaryKeyStr (int length) const { return ""; } +string DbSession::currentTimestamp () const { + L_D(); + + switch (d->backend) { + case DbSessionPrivate::Backend::Mysql: + return " CURRENT_TIMESTAMP"; + case DbSessionPrivate::Backend::Sqlite3: + // Ugly hack but Sqlite3 does not allow table alteration where we add a date column using a default value + // of CURRENT_TIMESTAMP + { + const tm &now = Utils::getTimeTAsTm(std::time(nullptr)); + const size_t bufSize = 22; + char buffer[bufSize]; + snprintf(buffer, bufSize, "'%d-%02d-%02d %02d:%02d:%02d'", + now.tm_year + 1900, now.tm_mon + 1, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec); + return buffer; + } + case DbSessionPrivate::Backend::None: + return ""; + } + + L_ASSERT(false); + return ""; +} + string DbSession::timestampType () const { L_D(); diff --git a/src/db/session/db-session.h b/src/db/session/db-session.h index 0189bf997..d05c47e18 100644 --- a/src/db/session/db-session.h +++ b/src/db/session/db-session.h @@ -47,6 +47,7 @@ public: std::string primaryKeyRefStr (const std::string &type = "INT") const; std::string varcharPrimaryKeyStr (int length) const; + std::string currentTimestamp () const; std::string timestampType () const; std::string noLimitValue () const; diff --git a/src/dial-plan/dial-plan.cpp b/src/dial-plan/dial-plan.cpp index c3b20a49d..9d8b64be6 100644 --- a/src/dial-plan/dial-plan.cpp +++ b/src/dial-plan/dial-plan.cpp @@ -128,7 +128,7 @@ const list DialPlanPrivate::DialPlans = { { "Hungary", "HU", "36", 9, "00" }, { "Iceland", "IS", "354", 9, "00" }, { "India", "IN", "91", 10, "00" }, - { "Indonesia", "ID", "62", 10, "001" }, + { "Indonesia", "ID", "62", 12, "001" }, { "Iran", "IR", "98", 10, "00" }, { "Iraq", "IQ", "964", 10, "00" }, { "Ireland", "IE", "353", 9, "00" }, diff --git a/src/nat/ice-agent.cpp b/src/nat/ice-agent.cpp index cbc74cd4a..727781482 100644 --- a/src/nat/ice-agent.cpp +++ b/src/nat/ice-agent.cpp @@ -81,7 +81,7 @@ void IceAgent::deleteSession () { } void IceAgent::gatheringFinished () { - const SalMediaDescription *rmd = mediaSession.getPrivate()->getOp()->get_remote_media_description(); + const SalMediaDescription *rmd = mediaSession.getPrivate()->getOp()->getRemoteMediaDescription(); if (rmd) clearUnusedIceCandidates(mediaSession.getPrivate()->getLocalDesc(), rmd); if (!iceSession) @@ -134,7 +134,7 @@ bool IceAgent::prepare (const SalMediaDescription *localDesc, bool incomingOffer SalMediaDescription *remoteDesc = nullptr; bool hasVideo = false; if (incomingOffer) { - remoteDesc = mediaSession.getPrivate()->getOp()->get_remote_media_description(); + remoteDesc = mediaSession.getPrivate()->getOp()->getRemoteMediaDescription(); hasVideo = linphone_core_video_enabled(mediaSession.getCore()->getCCore()) && linphone_core_media_description_contains_video_stream(remoteDesc); } else @@ -546,7 +546,7 @@ void IceAgent::createIceCheckListsAndParseIceAttributes (const SalMediaDescripti ); } if (!iceRestarted) { - bool_t losingPairsAdded = false; + bool losingPairsAdded = false; for (int j = 0; j < SAL_MEDIA_DESCRIPTION_MAX_ICE_REMOTE_CANDIDATES; j++) { const SalIceRemoteCandidate *remoteCandidate = &stream->ice_remote_candidates[j]; const char *addr = nullptr; @@ -740,32 +740,25 @@ void IceAgent::updateIceStateInCallStatsForStream (LinphoneCallStats *stats, Ice } } -bool IceAgent::checkIceReinviteNeedsDeferedResponse(SalMediaDescription *md){ - int i,j; - IceCheckList *cl; - - if (!iceSession) return false; +bool IceAgent::checkIceReinviteNeedsDeferedResponse(SalMediaDescription *md) { + if (!iceSession || (ice_session_state(iceSession) != IS_Running)) + return false; - if (ice_session_state(iceSession) != IS_Running ) return false; - - for (i = 0; i < md->nb_streams; i++) { + for (int i = 0; i < md->nb_streams; i++) { SalStreamDescription *stream = &md->streams[i]; - cl = ice_session_check_list(iceSession, i); - - if (cl==NULL) continue; - if (stream->ice_mismatch == TRUE) { - return false; - } - if (stream->rtp_port == 0) { + IceCheckList *cl = ice_session_check_list(iceSession, i); + if (!cl) continue; - } - - if (ice_check_list_state(cl) != ICL_Running) continue; - for (j = 0; j < SAL_MEDIA_DESCRIPTION_MAX_ICE_CANDIDATES; j++) { + if (stream->ice_mismatch) + return false; + if ((stream->rtp_port == 0) || (ice_check_list_state(cl) != ICL_Running)) + continue; + + for (int j = 0; j < SAL_MEDIA_DESCRIPTION_MAX_ICE_REMOTE_CANDIDATES; j++) { const SalIceRemoteCandidate *remote_candidate = &stream->ice_remote_candidates[j]; - if (remote_candidate->addr[0] != '\0') return true; - + if (remote_candidate->addr[0] != '\0') + return true; } } return false; diff --git a/src/nat/ice-agent.h b/src/nat/ice-agent.h index 0e702010b..cb688f0af 100644 --- a/src/nat/ice-agent.h +++ b/src/nat/ice-agent.h @@ -70,7 +70,7 @@ public: * Checks if an incoming offer with ICE needs a delayed answer, because the ice session hasn't completed yet with * connecvity checks. */ - bool checkIceReinviteNeedsDeferedResponse(SalMediaDescription *md); + bool checkIceReinviteNeedsDeferedResponse (SalMediaDescription *md); private: void addLocalIceCandidates (int family, const char *addr, IceCheckList *audioCl, IceCheckList *videoCl, IceCheckList *textCl); diff --git a/src/object/base-object.cpp b/src/object/base-object.cpp index ebedc602a..7ef6e2b22 100644 --- a/src/object/base-object.cpp +++ b/src/object/base-object.cpp @@ -19,8 +19,6 @@ #include "base-object-p.h" #include "base-object.h" - -// Necessary for: L_SIGNAL_CPP_PTR_DESTRUCTION. #include "c-wrapper/internal/c-tools.h" // ============================================================================= @@ -34,7 +32,7 @@ BaseObject::BaseObject (BaseObjectPrivate &p) : mPrivate(&p) { } BaseObject::~BaseObject () { - L_SIGNAL_CPP_PTR_DESTRUCTION(this); + Wrapper::handleObjectDestruction(this); delete mPrivate; } diff --git a/src/object/clonable-object.cpp b/src/object/clonable-object.cpp index 38d1bba37..5c6ce7f4a 100644 --- a/src/object/clonable-object.cpp +++ b/src/object/clonable-object.cpp @@ -17,6 +17,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include "c-wrapper/internal/c-tools.h" #include "clonable-object-p.h" #include "clonable-object.h" @@ -43,6 +44,7 @@ ClonableObject::ClonableObject (ClonableObjectPrivate &p) { } while (false); ClonableObject::~ClonableObject () { + Wrapper::handleClonableObjectDestruction(this); UNREF(); } diff --git a/src/object/object.h b/src/object/object.h index a175e0813..8a313ff17 100644 --- a/src/object/object.h +++ b/src/object/object.h @@ -37,6 +37,13 @@ LINPHONE_BEGIN_NAMESPACE +#ifdef _WIN32 + // TODO: Avoid this error. Maybe with a custom enabled_shared_from_this. + // Disable C4251 triggered by std::enabled_shared_from_this. + #pragma warning(push) + #pragma warning(disable: 4251) +#endif // ifdef _WIN32 + /* * Main Object of Linphone. Can be shared but is not Clonable. * Supports properties and shared from this. @@ -62,6 +69,10 @@ private: L_DISABLE_COPY(Object); }; +#ifdef _WIN32 + #pragma warning(pop) +#endif // ifdef _WIN32 + LINPHONE_END_NAMESPACE #endif // ifndef _L_OBJECT_H_ diff --git a/src/sal/call-op.cpp b/src/sal/call-op.cpp index a900ab5d8..910031635 100644 --- a/src/sal/call-op.cpp +++ b/src/sal/call-op.cpp @@ -32,46 +32,46 @@ using namespace std; LINPHONE_BEGIN_NAMESPACE SalCallOp::~SalCallOp() { - if (this->local_media) sal_media_description_unref(this->local_media); - if (this->remote_media) sal_media_description_unref(this->remote_media); + if (mLocalMedia) sal_media_description_unref(mLocalMedia); + if (mRemoteMedia) sal_media_description_unref(mRemoteMedia); } -int SalCallOp::set_local_media_description(SalMediaDescription *desc) { +int SalCallOp::setLocalMediaDescription(SalMediaDescription *desc) { if (desc) { sal_media_description_ref(desc); belle_sip_error_code error; belle_sdp_session_description_t *sdp = media_description_to_sdp(desc); - vector buffer = marshal_media_description(sdp, error); + vector buffer = marshalMediaDescription(sdp, error); if (error != BELLE_SIP_OK) return -1; - this->local_body.setContentType(ContentType::Sdp); - this->local_body.setBody(move(buffer)); + mLocalBody.setContentType(ContentType::Sdp); + mLocalBody.setBody(move(buffer)); } else { - this->local_body = Content(); + mLocalBody = Content(); } - if (this->local_media) - sal_media_description_unref(this->local_media); - this->local_media=desc; + if (mLocalMedia) + sal_media_description_unref(mLocalMedia); + mLocalMedia=desc; - if (this->remote_media){ + if (mRemoteMedia){ /*case of an incoming call where we modify the local capabilities between the time * the call is ringing and it is accepted (for example if you want to accept without video*/ /*reset the sdp answer so that it is computed again*/ - if (this->sdp_answer){ - belle_sip_object_unref(this->sdp_answer); - this->sdp_answer=NULL; + if (mSdpAnswer){ + belle_sip_object_unref(mSdpAnswer); + mSdpAnswer=NULL; } } return 0; } -int SalCallOp::set_local_body(const Content &body) { +int SalCallOp::setLocalBody(const Content &body) { Content bodyCopy = body; - return set_local_body(move(bodyCopy)); + return setLocalBody(move(bodyCopy)); } -int SalCallOp::set_local_body(const Content &&body) { +int SalCallOp::setLocalBody(const Content &&body) { if (!body.isValid()) return -1; if (body.getContentType() == ContentType::Sdp) { @@ -85,15 +85,15 @@ int SalCallOp::set_local_body(const Content &&body) { return -1; } } - if (this->local_media) sal_media_description_unref(this->local_media); - this->local_media = desc; + if (mLocalMedia) sal_media_description_unref(mLocalMedia); + mLocalMedia = desc; } - this->local_body = body; + mLocalBody = body; return 0; } -belle_sip_header_allow_t *SalCallOp::create_allow(bool_t enable_update) { +belle_sip_header_allow_t *SalCallOp::createAllow(bool enable_update) { belle_sip_header_allow_t* header_allow; char allow [256]; snprintf(allow,sizeof(allow),"INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO%s",(enable_update?", UPDATE":"")); @@ -101,7 +101,7 @@ belle_sip_header_allow_t *SalCallOp::create_allow(bool_t enable_update) { return header_allow; } -int SalCallOp::set_custom_body(belle_sip_message_t *msg, const Content &body) { +int SalCallOp::setCustomBody(belle_sip_message_t *msg, const Content &body) { ContentType contentType = body.getContentType(); auto contentDisposition = body.getContentDisposition(); string contentEncoding = body.getContentEncoding(); @@ -137,7 +137,7 @@ int SalCallOp::set_custom_body(belle_sip_message_t *msg, const Content &body) { return 0; } -std::vector SalCallOp::marshal_media_description(belle_sdp_session_description_t *session_desc, belle_sip_error_code &error) { +std::vector SalCallOp::marshalMediaDescription(belle_sdp_session_description_t *session_desc, belle_sip_error_code &error) { size_t length = 0; size_t bufLen = 2048; vector buff(bufLen); @@ -163,65 +163,65 @@ std::vector SalCallOp::marshal_media_description(belle_sdp_session_descrip return buff; } -int SalCallOp::set_sdp(belle_sip_message_t *msg,belle_sdp_session_description_t* session_desc) { +int SalCallOp::setSdp(belle_sip_message_t *msg,belle_sdp_session_description_t* session_desc) { belle_sip_error_code error; if (session_desc == NULL) return -1; - vector buff = marshal_media_description(session_desc, error); + vector buff = marshalMediaDescription(session_desc, error); if (error != BELLE_SIP_OK) return -1; Content body; body.setContentType(ContentType::Sdp); body.setBody(move(buff)); - set_custom_body(msg, body); + setCustomBody(msg, body); return 0; } -int SalCallOp::set_sdp_from_desc(belle_sip_message_t *msg, const SalMediaDescription *desc) { +int SalCallOp::setSdpFromDesc(belle_sip_message_t *msg, const SalMediaDescription *desc) { int err; belle_sdp_session_description_t *sdp=media_description_to_sdp(desc); - err=set_sdp(msg,sdp); + err=setSdp(msg,sdp); belle_sip_object_unref(sdp); return err; } -void SalCallOp::fill_invite(belle_sip_request_t* invite) { - belle_sip_message_add_header(BELLE_SIP_MESSAGE(invite),BELLE_SIP_HEADER(create_allow(this->root->enable_sip_update))); - if (this->root->session_expires!=0){ +void SalCallOp::fillInvite(belle_sip_request_t* invite) { + belle_sip_message_add_header(BELLE_SIP_MESSAGE(invite),BELLE_SIP_HEADER(createAllow(mRoot->mEnableSipUpdate))); + if (mRoot->mSessionExpires!=0){ belle_sip_message_add_header(BELLE_SIP_MESSAGE(invite),belle_sip_header_create( "Session-expires", "600;refresher=uas")); belle_sip_message_add_header(BELLE_SIP_MESSAGE(invite),belle_sip_header_create( "Supported", "timer")); } - this->sdp_offering = (this->local_body.getContentType() == ContentType::Sdp); - set_custom_body(BELLE_SIP_MESSAGE(invite), this->local_body); + mSdpOffering = (mLocalBody.getContentType() == ContentType::Sdp); + setCustomBody(BELLE_SIP_MESSAGE(invite), mLocalBody); } -void SalCallOp::set_released() { - if (!this->call_released){ - this->state=State::Terminated; - this->root->callbacks.call_released(this); - this->call_released=TRUE; +void SalCallOp::setReleased() { + if (!mCallReleased){ + mState=State::Terminated; + mRoot->mCallbacks.call_released(this); + mCallReleased=TRUE; /*be aware that the following line may destroy the op*/ - set_or_update_dialog(NULL); + setOrUpdateDialog(NULL); } } -void SalCallOp::process_io_error_cb(void *user_ctx, const belle_sip_io_error_event_t *event) { +void SalCallOp::processIoErrorCb(void *user_ctx, const belle_sip_io_error_event_t *event) { SalCallOp *op = (SalCallOp *)user_ctx; - if (op->state == State::Terminated) return; + if (op->mState == State::Terminated) return; - if (op->pending_client_trans && (belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(op->pending_client_trans)) == BELLE_SIP_TRANSACTION_INIT)) { + if (op->mPendingClientTransaction && (belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(op->mPendingClientTransaction)) == BELLE_SIP_TRANSACTION_INIT)) { - sal_error_info_set(&op->error_info, SalReasonIOError, "SIP", 503, "IO error", NULL); - op->root->callbacks.call_failure(op); + sal_error_info_set(&op->mErrorInfo, SalReasonIOError, "SIP", 503, "IO error", NULL); + op->mRoot->mCallbacks.call_failure(op); - if (!op->dialog || belle_sip_dialog_get_state(op->dialog) != BELLE_SIP_DIALOG_CONFIRMED){ + if (!op->mDialog || belle_sip_dialog_get_state(op->mDialog) != BELLE_SIP_DIALOG_CONFIRMED){ /* Call terminated very very early, before INVITE is even sent, probably DNS resolution timeout. */ - op->state = State::Terminating; - op->set_released(); + op->mState = State::Terminating; + op->setReleased(); } } else { /* Nothing to be done. If the error comes from a connectivity loss, @@ -229,15 +229,15 @@ void SalCallOp::process_io_error_cb(void *user_ctx, const belle_sip_io_error_eve } } -void SalCallOp::cancelling_invite(const SalErrorInfo *info) { - cancel_invite_with_info(info); - this->state=State::Terminating; +void SalCallOp::cancellingInvite(const SalErrorInfo *info) { + cancelInvite(info); + mState=State::Terminating; } -Content SalCallOp::extract_body(belle_sip_message_t *message) { +Content SalCallOp::extractBody(belle_sip_message_t *message) { Content body; belle_sip_header_content_type_t *content_type = belle_sip_message_get_header_by_type(message, belle_sip_header_content_type_t); - belle_sip_header_content_disposition_t *contentDisposition = belle_sip_message_get_header_by_type(message, belle_sip_header_content_disposition_t); + belle_sip_header_content_disposition_t *contentDispositionHeader = belle_sip_message_get_header_by_type(message, belle_sip_header_content_disposition_t); belle_sip_header_content_length_t *content_length = belle_sip_message_get_header_by_type(message, belle_sip_header_content_length_t); const char *type_str = content_type ? belle_sip_header_content_type_get_type(content_type) : NULL; const char *subtype_str = content_type ? belle_sip_header_content_type_get_subtype(content_type) : NULL; @@ -245,25 +245,28 @@ Content SalCallOp::extract_body(belle_sip_message_t *message) { const char *body_str = belle_sip_message_get_body(message); if (type_str && subtype_str) body.setContentType(ContentType(type_str, subtype_str)); - if (contentDisposition) - body.setContentDisposition( - ContentDisposition(belle_sip_header_content_disposition_get_content_disposition(contentDisposition)) - ); + if (contentDispositionHeader) { + auto contentDisposition = ContentDisposition(belle_sip_header_content_disposition_get_content_disposition(contentDispositionHeader)); + if (belle_sip_parameters_has_parameter(BELLE_SIP_PARAMETERS(contentDispositionHeader), "handling")) { + contentDisposition.setParameter("handling=" + string(belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(contentDispositionHeader), "handling"))); + } + body.setContentDisposition(contentDisposition); + } if (length > 0 && body_str) body.setBody(body_str, length); return body; } -int SalCallOp::parse_sdp_body(const Content &body,belle_sdp_session_description_t** session_desc, SalReason *error) { +int SalCallOp::parseSdpBody(const Content &body,belle_sdp_session_description_t** session_desc, SalReason *error) { *session_desc = NULL; *error = SalReasonNone; - if (this->sdp_handling == SalOpSDPSimulateError) { + if (mSdpHandling == SalOpSDPSimulateError) { ms_error("Simulating SDP parsing error for op %p", this); *error = SalReasonNotAcceptable; return -1; } - if (this->sdp_handling == SalOpSDPSimulateRemove) { + if (mSdpHandling == SalOpSDPSimulateRemove) { ms_error("Simulating no SDP for op %p", this); return 0; } @@ -281,7 +284,7 @@ int SalCallOp::parse_sdp_body(const Content &body,belle_sdp_session_description_ return 0; } -void SalCallOp::set_addr_to_0000(char value[], size_t sz) { +void SalCallOp::setAddrTo0000(char value[], size_t sz) { if (ms_is_ipv6(value)) { strncpy(value,"::0", sz); } else { @@ -290,97 +293,97 @@ void SalCallOp::set_addr_to_0000(char value[], size_t sz) { return; } -void SalCallOp::sdp_process(){ - ms_message("Doing SDP offer/answer process of type %s", this->sdp_offering ? "outgoing" : "incoming"); - if (this->result){ - sal_media_description_unref(this->result); - this->result = NULL; +void SalCallOp::sdpProcess(){ + ms_message("Doing SDP offer/answer process of type %s", mSdpOffering ? "outgoing" : "incoming"); + if (mResult){ + sal_media_description_unref(mResult); + mResult = NULL; } /* if SDP was invalid */ - if (this->remote_media == NULL) return; + if (mRemoteMedia == NULL) return; - this->result=sal_media_description_new(); - if (this->sdp_offering){ - offer_answer_initiate_outgoing(this->root->factory, this->local_media,this->remote_media,this->result); + mResult=sal_media_description_new(); + if (mSdpOffering){ + offer_answer_initiate_outgoing(mRoot->mFactory, mLocalMedia,mRemoteMedia,mResult); }else{ int i; - if (this->sdp_answer){ - belle_sip_object_unref(this->sdp_answer); + if (mSdpAnswer){ + belle_sip_object_unref(mSdpAnswer); } - offer_answer_initiate_incoming(this->root->factory, this->local_media,this->remote_media,this->result,this->root->one_matching_codec); + offer_answer_initiate_incoming(mRoot->mFactory, mLocalMedia,mRemoteMedia,mResult,mRoot->mOneMatchingCodec); /*for backward compatibility purpose*/ - if(this->_cnx_ip_to_0000_if_sendonly_enabled && sal_media_description_has_dir(this->result,SalStreamSendOnly)) { - set_addr_to_0000(this->result->addr, sizeof(this->result->addr)); + if(mCnxIpTo0000IfSendOnlyEnabled && sal_media_description_has_dir(mResult,SalStreamSendOnly)) { + setAddrTo0000(mResult->addr, sizeof(mResult->addr)); for(i=0;iresult->streams[i].dir == SalStreamSendOnly) { - set_addr_to_0000(this->result->streams[i].rtp_addr, sizeof(this->result->streams[i].rtp_addr)); - set_addr_to_0000(this->result->streams[i].rtcp_addr, sizeof(this->result->streams[i].rtcp_addr)); + if (mResult->streams[i].dir == SalStreamSendOnly) { + setAddrTo0000(mResult->streams[i].rtp_addr, sizeof(mResult->streams[i].rtp_addr)); + setAddrTo0000(mResult->streams[i].rtcp_addr, sizeof(mResult->streams[i].rtcp_addr)); } } } - this->sdp_answer=(belle_sdp_session_description_t *)belle_sip_object_ref(media_description_to_sdp(this->result)); + mSdpAnswer=(belle_sdp_session_description_t *)belle_sip_object_ref(media_description_to_sdp(mResult)); /*once we have generated the SDP answer, we modify the result description for processing by the upper layer. It should contains media parameters constraint from the remote offer, not our response*/ - strcpy(this->result->addr,this->remote_media->addr); - this->result->bandwidth=this->remote_media->bandwidth; + strcpy(mResult->addr,mRemoteMedia->addr); + mResult->bandwidth=mRemoteMedia->bandwidth; for(i=0;iresult->streams[i].rtp_port!=0){ /*if stream was accepted*/ - strcpy(this->result->streams[i].rtp_addr,this->remote_media->streams[i].rtp_addr); - this->result->streams[i].ptime=this->remote_media->streams[i].ptime; - this->result->streams[i].bandwidth=this->remote_media->streams[i].bandwidth; - this->result->streams[i].rtp_port=this->remote_media->streams[i].rtp_port; - strcpy(this->result->streams[i].rtcp_addr,this->remote_media->streams[i].rtcp_addr); - this->result->streams[i].rtcp_port=this->remote_media->streams[i].rtcp_port; + if (mResult->streams[i].rtp_port!=0){ /*if stream was accepted*/ + strcpy(mResult->streams[i].rtp_addr,mRemoteMedia->streams[i].rtp_addr); + mResult->streams[i].ptime=mRemoteMedia->streams[i].ptime; + mResult->streams[i].bandwidth=mRemoteMedia->streams[i].bandwidth; + mResult->streams[i].rtp_port=mRemoteMedia->streams[i].rtp_port; + strcpy(mResult->streams[i].rtcp_addr,mRemoteMedia->streams[i].rtcp_addr); + mResult->streams[i].rtcp_port=mRemoteMedia->streams[i].rtcp_port; - if (sal_stream_description_has_srtp(&this->result->streams[i])) { - this->result->streams[i].crypto[0] = this->remote_media->streams[i].crypto[0]; + if (sal_stream_description_has_srtp(&mResult->streams[i])) { + mResult->streams[i].crypto[0] = mRemoteMedia->streams[i].crypto[0]; } } } } } -void SalCallOp::handle_body_from_response(belle_sip_response_t* response) { +void SalCallOp::handleBodyFromResponse(belle_sip_response_t* response) { SalReason reason; belle_sdp_session_description_t* sdp = nullptr; - Content body = extract_body(BELLE_SIP_MESSAGE(response)); - if (this->remote_media){ - sal_media_description_unref(this->remote_media); - this->remote_media=NULL; + Content body = extractBody(BELLE_SIP_MESSAGE(response)); + if (mRemoteMedia){ + sal_media_description_unref(mRemoteMedia); + mRemoteMedia=NULL; } if (body.getContentType() == ContentType::Sdp) { - if (parse_sdp_body(body, &sdp, &reason) == 0) { + if (parseSdpBody(body, &sdp, &reason) == 0) { if (sdp) { - this->remote_media = sal_media_description_new(); - sdp_to_media_description(sdp, this->remote_media); - this->remote_body = move(body); + mRemoteMedia = sal_media_description_new(); + sdp_to_media_description(sdp, mRemoteMedia); + mRemoteBody = move(body); }/*if no sdp in response, what can we do ?*/ } /* process sdp in any case to reset result media description*/ - if (this->local_media) sdp_process(); + if (mLocalMedia) sdpProcess(); } else { - this->remote_body = move(body); + mRemoteBody = move(body); } } -void SalCallOp::set_error(belle_sip_response_t* response, bool_t fatal){ - set_error_info_from_response(response); - if (fatal) this->state = State::Terminating; - this->root->callbacks.call_failure(this); +void SalCallOp::setError(belle_sip_response_t* response, bool fatal){ + setErrorInfoFromResponse(response); + if (fatal) mState = State::Terminating; + mRoot->mCallbacks.call_failure(this); } -int SalCallOp::vfu_retry_cb (void *user_data, unsigned int events) { +int SalCallOp::vfuRetryCb (void *user_data, unsigned int events) { SalCallOp *op=(SalCallOp *)user_data; - op->send_vfu_request(); + op->sendVfuRequest(); op->unref(); return BELLE_SIP_STOP; } -void SalCallOp::process_response_cb(void *op_base, const belle_sip_response_event_t *event) { +void SalCallOp::processResponseCb(void *op_base, const belle_sip_response_event_t *event) { SalCallOp * op = (SalCallOp *)op_base; belle_sip_request_t* ack; belle_sip_dialog_state_t dialog_state; @@ -397,7 +400,7 @@ void SalCallOp::process_response_cb(void *op_base, const belle_sip_response_even return; } req=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(client_transaction)); - op->set_or_update_dialog(dialog); + op->setOrUpdateDialog(dialog); dialog_state=dialog ? belle_sip_dialog_get_state(dialog) : BELLE_SIP_DIALOG_NULL; method=belle_sip_request_get_method(req); ms_message("Op [%p] receiving call response [%i], dialog is [%p] in state [%s]",op,code,dialog,belle_sip_dialog_state_to_string(dialog_state)); @@ -407,67 +410,67 @@ void SalCallOp::process_response_cb(void *op_base, const belle_sip_response_even case BELLE_SIP_DIALOG_NULL: case BELLE_SIP_DIALOG_EARLY: { if (strcmp("INVITE",method)==0 ) { - if (op->state == State::Terminating) { + if (op->mState == State::Terminating) { /*check if CANCEL was sent before*/ - if (strcmp("CANCEL",belle_sip_request_get_method(belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(op->pending_client_trans))))!=0) { + if (strcmp("CANCEL",belle_sip_request_get_method(belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(op->mPendingClientTransaction))))!=0) { /*it wasn't sent */ if (code<200) { - op->cancelling_invite(NULL); + op->cancellingInvite(NULL); }else{ /* no need to send the INVITE because the UAS rejected the INVITE*/ - if (op->dialog==NULL) op->set_released(); + if (op->mDialog==NULL) op->setReleased(); } } else { /*it was sent already, so just expect the 487 or any error response to send the call_released() notification*/ if (code>=300){ - if (op->dialog==NULL) op->set_released(); + if (op->mDialog==NULL) op->setReleased(); } } } else if (code >= 180 && code<200) { belle_sip_response_t *prev_response=reinterpret_cast(belle_sip_object_data_get(BELLE_SIP_OBJECT(dialog),"early_response")); if (!prev_response || code>belle_sip_response_get_status_code(prev_response)){ - op->handle_body_from_response(response); - op->root->callbacks.call_ringing(op); + op->handleBodyFromResponse(response); + op->mRoot->mCallbacks.call_ringing(op); } belle_sip_object_data_set(BELLE_SIP_OBJECT(dialog),"early_response",belle_sip_object_ref(response),belle_sip_object_unref); } else if (code>=300){ - op->set_error(response, TRUE); - if (op->dialog==NULL) op->set_released(); + op->setError(response, TRUE); + if (op->mDialog==NULL) op->setReleased(); } } else if (code >=200 && code<300) { if (strcmp("UPDATE",method)==0) { - op->handle_body_from_response(response); - op->root->callbacks.call_accepted(op); + op->handleBodyFromResponse(response); + op->mRoot->mCallbacks.call_accepted(op); } else if (strcmp("CANCEL", method) == 0) { - op->root->callbacks.call_cancel_done(op); + op->mRoot->mCallbacks.call_cancel_done(op); } } } break; case BELLE_SIP_DIALOG_CONFIRMED: { - switch (op->state) { + switch (op->mState) { case State::Early:/*invite case*/ case State::Active: /*re-invite, INFO, UPDATE case*/ if (strcmp("INVITE",method)==0){ if (code >=200 && code<300) { - op->handle_body_from_response(response); - ack=belle_sip_dialog_create_ack(op->dialog,belle_sip_dialog_get_local_seq_number(op->dialog)); + op->handleBodyFromResponse(response); + ack=belle_sip_dialog_create_ack(op->mDialog,belle_sip_dialog_get_local_seq_number(op->mDialog)); if (ack == NULL) { ms_error("This call has been already terminated."); return ; } - if (op->sdp_answer){ - set_sdp(BELLE_SIP_MESSAGE(ack),op->sdp_answer); - belle_sip_object_unref(op->sdp_answer); - op->sdp_answer=NULL; + if (op->mSdpAnswer){ + setSdp(BELLE_SIP_MESSAGE(ack),op->mSdpAnswer); + belle_sip_object_unref(op->mSdpAnswer); + op->mSdpAnswer=NULL; } - belle_sip_message_add_header(BELLE_SIP_MESSAGE(ack),BELLE_SIP_HEADER(op->root->user_agent)); - op->root->callbacks.call_accepted(op); /*INVITE*/ - op->root->callbacks.call_ack_being_sent(op, (SalCustomHeader*)ack); - belle_sip_dialog_send_ack(op->dialog,ack); - op->state=State::Active; + belle_sip_message_add_header(BELLE_SIP_MESSAGE(ack),BELLE_SIP_HEADER(op->mRoot->mUserAgentHeader)); + op->mRoot->mCallbacks.call_accepted(op); /*INVITE*/ + op->mRoot->mCallbacks.call_ack_being_sent(op, (SalCustomHeader*)ack); + belle_sip_dialog_send_ack(op->mDialog,ack); + op->mState=State::Active; }else if (code >= 300){ - op->set_error(response, FALSE); + op->setError(response, FALSE); } }else if (strcmp("INFO",method)==0){ if (code == 491 @@ -475,30 +478,32 @@ void SalCallOp::process_response_cb(void *op_base, const belle_sip_response_even && strcmp("application",belle_sip_header_content_type_get_type(header_content_type))==0 && strcmp("media_control+xml",belle_sip_header_content_type_get_subtype(header_content_type))==0) { unsigned int retry_in = rand() % 1001; // [0;1000] - belle_sip_source_t *s=op->root->create_timer(vfu_retry_cb,op->ref(), retry_in, "vfu request retry"); + belle_sip_source_t *s=op->mRoot->createTimer(vfuRetryCb,op->ref(), retry_in, "vfu request retry"); ms_message("Rejected vfu request on op [%p], just retry in [%u] ms",op,retry_in); belle_sip_object_unref(s); }else { /*ignoring*/ } }else if (strcmp("UPDATE",method)==0){ - op->root->callbacks.call_accepted(op); /*INVITE*/ + op->mRoot->mCallbacks.call_accepted(op); /*INVITE*/ }else if (strcmp("CANCEL",method)==0){ - op->root->callbacks.call_cancel_done(op); + op->mRoot->mCallbacks.call_cancel_done(op); } break; case State::Terminating: - op->send_request(belle_sip_dialog_create_request(op->dialog,"BYE")); + op->sendRequest(belle_sip_dialog_create_request(op->mDialog,"BYE")); break; case State::Terminated: default: - ms_error("Call op [%p] receives unexpected answer [%i] while in state [%s].",op,code, to_string(op->state)); + lError() << "Call op [" << op << "] receives unexpected answer [" << code << "] while in state [" << toString(op->mState) << "]"; } } break; case BELLE_SIP_DIALOG_TERMINATED: { - if (strcmp("INVITE",method)==0 && code >= 300){ - op->set_error(response, TRUE); + if ((code >= 300) + && ((strcmp("INVITE", method) == 0) || (strcmp("BYE", method) == 0)) + ) { + op->setError(response, TRUE); } } break; @@ -510,30 +515,30 @@ void SalCallOp::process_response_cb(void *op_base, const belle_sip_response_even op->unref(); } -void SalCallOp::process_timeout_cb(void *user_ctx, const belle_sip_timeout_event_t *event) { +void SalCallOp::processTimeoutCb(void *user_ctx, const belle_sip_timeout_event_t *event) { SalCallOp * op=(SalCallOp *)user_ctx; - if (op->state==State::Terminated) return; + if (op->mState==State::Terminated) return; - if (!op->dialog) { + if (!op->mDialog) { /*call terminated very early*/ - sal_error_info_set(&op->error_info, SalReasonRequestTimeout, "SIP", 408, "Request timeout", NULL); - op->root->callbacks.call_failure(op); - op->state = State::Terminating; - op->set_released(); + sal_error_info_set(&op->mErrorInfo, SalReasonRequestTimeout, "SIP", 408, "Request timeout", NULL); + op->mRoot->mCallbacks.call_failure(op); + op->mState = State::Terminating; + op->setReleased(); } else { /*dialog will terminated shortly, nothing to do*/ } } -void SalCallOp::process_transaction_terminated_cb(void *user_ctx, const belle_sip_transaction_terminated_event_t *event) { +void SalCallOp::processTransactionTerminatedCb(void *user_ctx, const belle_sip_transaction_terminated_event_t *event) { SalCallOp * op = (SalCallOp *)user_ctx; belle_sip_client_transaction_t *client_transaction=belle_sip_transaction_terminated_event_get_client_transaction(event); belle_sip_server_transaction_t *server_transaction=belle_sip_transaction_terminated_event_get_server_transaction(event); belle_sip_request_t* req; belle_sip_response_t* resp; int code = 0; - bool_t release_call=FALSE; + bool release_call = false; if (client_transaction) { req=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(client_transaction)); @@ -544,33 +549,33 @@ void SalCallOp::process_transaction_terminated_cb(void *user_ctx, const belle_si } if (resp) code = belle_sip_response_get_status_code(resp); - if (op->state == State::Terminating + if (op->mState == State::Terminating && strcmp("BYE",belle_sip_request_get_method(req))==0 && (!resp || (belle_sip_response_get_status_code(resp) != 401 && belle_sip_response_get_status_code(resp) != 407)) - && op->dialog==NULL) { - release_call=TRUE; - }else if (op->state == State::Early && code < 200){ + && op->mDialog==NULL) { + release_call=true; + }else if (op->mState == State::Early && code < 200){ /*call terminated early*/ - sal_error_info_set(&op->error_info, SalReasonIOError, "SIP", 503, "I/O error", NULL); - op->state = State::Terminating; - op->root->callbacks.call_failure(op); - release_call=TRUE; + sal_error_info_set(&op->mErrorInfo, SalReasonIOError, "SIP", 503, "I/O error", NULL); + op->mState = State::Terminating; + op->mRoot->mCallbacks.call_failure(op); + release_call=true; } if (server_transaction){ - if (op->pending_server_trans==server_transaction){ - belle_sip_object_unref(op->pending_server_trans); - op->pending_server_trans=NULL; + if (op->mPendingServerTransaction==server_transaction){ + belle_sip_object_unref(op->mPendingServerTransaction); + op->mPendingServerTransaction=NULL; } - if (op->pending_update_server_trans==server_transaction){ - belle_sip_object_unref(op->pending_update_server_trans); - op->pending_update_server_trans=NULL; + if (op->mPendingUpdateServerTransaction==server_transaction){ + belle_sip_object_unref(op->mPendingUpdateServerTransaction); + op->mPendingUpdateServerTransaction=NULL; } } - if (release_call) op->set_released(); + if (release_call) op->setReleased(); } -int SalCallOp::is_media_description_acceptable(SalMediaDescription *md) { +int SalCallOp::isMediaDescriptionAcceptable(SalMediaDescription *md) { if (md->nb_streams==0){ ms_warning("Media description does not define any stream."); return FALSE; @@ -578,94 +583,94 @@ int SalCallOp::is_media_description_acceptable(SalMediaDescription *md) { return TRUE; } -SalReason SalCallOp::process_body_for_invite(belle_sip_request_t* invite) { +SalReason SalCallOp::processBodyForInvite(belle_sip_request_t* invite) { SalReason reason = SalReasonNone; - Content body = extract_body(BELLE_SIP_MESSAGE(invite)); + Content body = extractBody(BELLE_SIP_MESSAGE(invite)); if (!body.isValid()) return SalReasonUnsupportedContent; if ((body.getContentType() == ContentType::Sdp) || (body.getContentType().isEmpty() && body.isEmpty())) { belle_sdp_session_description_t* sdp; - if (parse_sdp_body(body, &sdp, &reason) == 0) { + if (parseSdpBody(body, &sdp, &reason) == 0) { if (sdp) { - this->sdp_offering = FALSE; - if (this->remote_media) sal_media_description_unref(this->remote_media); - this->remote_media = sal_media_description_new(); - sdp_to_media_description(sdp, this->remote_media); + mSdpOffering = FALSE; + if (mRemoteMedia) sal_media_description_unref(mRemoteMedia); + mRemoteMedia = sal_media_description_new(); + sdp_to_media_description(sdp, mRemoteMedia); /*make some sanity check about the SDP received*/ - if (!is_media_description_acceptable(this->remote_media)) { + if (!isMediaDescriptionAcceptable(mRemoteMedia)) { reason = SalReasonNotAcceptable; } belle_sip_object_unref(sdp); - } else this->sdp_offering = TRUE; /*INVITE without SDP*/ + } else mSdpOffering = TRUE; /*INVITE without SDP*/ } if (reason != SalReasonNone) { SalErrorInfo sei; memset(&sei, 0, sizeof(sei)); sal_error_info_set(&sei, reason, "SIP", 0, NULL, NULL); - decline_with_error_info(&sei, NULL); + declineWithErrorInfo(&sei, NULL); sal_error_info_reset(&sei); } } - this->remote_body = move(body); + mRemoteBody = move(body); return reason; } -SalReason SalCallOp::process_body_for_ack(belle_sip_request_t *ack) { +SalReason SalCallOp::processBodyForAck(belle_sip_request_t *ack) { SalReason reason = SalReasonNone; - Content body = extract_body(BELLE_SIP_MESSAGE(ack)); + Content body = extractBody(BELLE_SIP_MESSAGE(ack)); if (!body.isValid()) return SalReasonUnsupportedContent; if (body.getContentType() == ContentType::Sdp) { belle_sdp_session_description_t *sdp; - if (parse_sdp_body(body, &sdp, &reason) == 0) { + if (parseSdpBody(body, &sdp, &reason) == 0) { if (sdp) { - if (this->remote_media) sal_media_description_unref(this->remote_media); - this->remote_media = sal_media_description_new(); - sdp_to_media_description(sdp, this->remote_media); - this->sdp_process(); + if (mRemoteMedia) sal_media_description_unref(mRemoteMedia); + mRemoteMedia = sal_media_description_new(); + sdp_to_media_description(sdp, mRemoteMedia); + sdpProcess(); belle_sip_object_unref(sdp); } else { ms_warning("SDP expected in ACK but not found."); } } } - this->remote_body = move(body); + mRemoteBody = move(body); return reason; } -void SalCallOp::call_terminated(belle_sip_server_transaction_t* server_transaction, int status_code, belle_sip_request_t* cancel_request) { +void SalCallOp::callTerminated(belle_sip_server_transaction_t* server_transaction, int status_code, belle_sip_request_t* cancel_request) { belle_sip_response_t* resp; belle_sip_request_t* server_req = belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(server_transaction)); - this->state = State::Terminating; - set_reason_error_info(BELLE_SIP_MESSAGE(cancel_request ? cancel_request : server_req)); - resp=create_response_from_request(server_req,status_code); + mState = State::Terminating; + setReasonErrorInfo(BELLE_SIP_MESSAGE(cancel_request ? cancel_request : server_req)); + resp=createResponseFromRequest(server_req,status_code); belle_sip_server_transaction_send_response(server_transaction,resp); - this->root->callbacks.call_terminated(this,this->dir==Dir::Incoming?this->get_from():this->get_to()); + mRoot->mCallbacks.call_terminated(this,mDir==Dir::Incoming?getFrom().c_str():getTo().c_str()); } -void SalCallOp::reset_descriptions() { - if (this->remote_media){ - sal_media_description_unref(this->remote_media); - this->remote_media=NULL; +void SalCallOp::resetDescriptions() { + if (mRemoteMedia){ + sal_media_description_unref(mRemoteMedia); + mRemoteMedia=NULL; } - if (this->result){ - sal_media_description_unref(this->result); - this->result=NULL; + if (mResult){ + sal_media_description_unref(mResult); + mResult=NULL; } } -void SalCallOp::unsupported_method(belle_sip_server_transaction_t* server_transaction,belle_sip_request_t* request) { +void SalCallOp::unsupportedMethod(belle_sip_server_transaction_t* server_transaction,belle_sip_request_t* request) { belle_sip_response_t* resp; resp=belle_sip_response_create_from_request(request,501); belle_sip_server_transaction_send_response(server_transaction,resp); } -bool_t SalCallOp::is_a_pending_invite_incoming_transaction(belle_sip_transaction_t *tr){ +bool SalCallOp::isAPendingIncomingInviteTransaction(belle_sip_transaction_t *tr){ return BELLE_SIP_OBJECT_IS_INSTANCE_OF(tr, belle_sip_ist_t) && belle_sip_transaction_state_is_transient( belle_sip_transaction_get_state(tr)); } -void SalCallOp::process_request_event_cb(void *op_base, const belle_sip_request_event_t *event) { +void SalCallOp::processRequestEventCb(void *op_base, const belle_sip_request_event_t *event) { SalCallOp * op = (SalCallOp *)op_base; SalReason reason; belle_sip_server_transaction_t* server_transaction=NULL; @@ -674,56 +679,56 @@ void SalCallOp::process_request_event_cb(void *op_base, const belle_sip_request_ belle_sip_response_t* resp; belle_sip_header_t* call_info; const char *method=belle_sip_request_get_method(req); - bool_t is_update=FALSE; - bool_t drop_op = FALSE; + bool is_update = false; + bool drop_op = false; if (strcmp("ACK",method)!=0){ /*ACK doesn't create a server transaction*/ - server_transaction = belle_sip_provider_create_server_transaction(op->root->prov,belle_sip_request_event_get_request(event)); + server_transaction = belle_sip_provider_create_server_transaction(op->mRoot->mProvider,belle_sip_request_event_get_request(event)); belle_sip_object_ref(server_transaction); belle_sip_transaction_set_application_data(BELLE_SIP_TRANSACTION(server_transaction),op->ref()); } if (strcmp("INVITE",method)==0) { - if (op->pending_server_trans) belle_sip_object_unref(op->pending_server_trans); + if (op->mPendingServerTransaction) belle_sip_object_unref(op->mPendingServerTransaction); /*updating pending invite transaction*/ - op->pending_server_trans=server_transaction; - belle_sip_object_ref(op->pending_server_trans); + op->mPendingServerTransaction=server_transaction; + belle_sip_object_ref(op->mPendingServerTransaction); } if (strcmp("UPDATE",method)==0) { - if (op->pending_update_server_trans) belle_sip_object_unref(op->pending_update_server_trans); + if (op->mPendingUpdateServerTransaction) belle_sip_object_unref(op->mPendingUpdateServerTransaction); /*updating pending update transaction*/ - op->pending_update_server_trans=server_transaction; - belle_sip_object_ref(op->pending_update_server_trans); + op->mPendingUpdateServerTransaction=server_transaction; + belle_sip_object_ref(op->mPendingUpdateServerTransaction); } - if (!op->dialog) { - op->set_or_update_dialog(belle_sip_provider_create_dialog(op->root->prov, BELLE_SIP_TRANSACTION(op->pending_server_trans))); - ms_message("new incoming call from [%s] to [%s]",op->get_from(),op->get_to()); + if (!op->mDialog) { + op->setOrUpdateDialog(belle_sip_provider_create_dialog(op->mRoot->mProvider, BELLE_SIP_TRANSACTION(op->mPendingServerTransaction))); + ms_message("new incoming call from [%s] to [%s]",op->getFrom().c_str(),op->getTo().c_str()); } - dialog_state=belle_sip_dialog_get_state(op->dialog); + dialog_state=belle_sip_dialog_get_state(op->mDialog); switch(dialog_state) { case BELLE_SIP_DIALOG_NULL: { if (strcmp("INVITE",method)==0) { - if (!op->replaces && (op->replaces=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_replaces_t))) { - belle_sip_object_ref(op->replaces); - } else if(op->replaces) { + if (!op->mReplaces && (op->mReplaces=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_replaces_t))) { + belle_sip_object_ref(op->mReplaces); + } else if(op->mReplaces) { ms_warning("replace header already set"); } - if ( (reason = op->process_body_for_invite(req)) == SalReasonNone) { + if ( (reason = op->processBodyForInvite(req)) == SalReasonNone) { if ((call_info=belle_sip_message_get_header(BELLE_SIP_MESSAGE(req),"Call-Info"))) { if( strstr(belle_sip_header_get_unparsed_value(call_info),"answer-after=") != NULL) { - op->auto_answer_asked=TRUE; + op->mAutoAnswerAsked=TRUE; ms_message("The caller asked to automatically answer the call(Emergency?)\n"); } } - op->root->callbacks.call_received(op); + op->mRoot->mCallbacks.call_received(op); }else{ - sal_error_info_set(&op->error_info, reason, "SIP", 0, NULL, NULL); - op->root->callbacks.call_rejected(op); + sal_error_info_set(&op->mErrorInfo, reason, "SIP", 0, NULL, NULL); + op->mRoot->mCallbacks.call_rejected(op); /*the INVITE was declined by process_sdp_for_invite(). As we are not inside an established dialog, we can drop the op immediately*/ - drop_op = TRUE; + drop_op = true; } break; }BCTBX_NO_BREAK; /* else same behavior as for EARLY state, thus NO BREAK*/ @@ -733,68 +738,68 @@ void SalCallOp::process_request_event_cb(void *op_base, const belle_sip_request_ if(belle_sip_request_event_get_server_transaction(event)) { /*first answer 200 ok to cancel*/ belle_sip_server_transaction_send_response(server_transaction - ,op->create_response_from_request(req,200)); + ,op->createResponseFromRequest(req,200)); /*terminate invite transaction*/ - op->call_terminated(op->pending_server_trans,487,req); + op->callTerminated(op->mPendingServerTransaction,487,req); } else { /*call leg does not exist*/ belle_sip_server_transaction_send_response(server_transaction - ,op->create_response_from_request(req,481)); + ,op->createResponseFromRequest(req,481)); } } else if (strcmp("PRACK",method)==0) { - resp=op->create_response_from_request(req,200); + resp=op->createResponseFromRequest(req,200); belle_sip_server_transaction_send_response(server_transaction,resp); } else if (strcmp("UPDATE",method)==0) { - op->reset_descriptions(); - if (op->process_body_for_invite(req)==SalReasonNone) - op->root->callbacks.call_updating(op,TRUE); + op->resetDescriptions(); + if (op->processBodyForInvite(req)==SalReasonNone) + op->mRoot->mCallbacks.call_updating(op,TRUE); } else { belle_sip_error("Unexpected method [%s] for dialog state BELLE_SIP_DIALOG_EARLY",belle_sip_request_get_method(req)); - unsupported_method(server_transaction,req); + unsupportedMethod(server_transaction,req); } break; } case BELLE_SIP_DIALOG_CONFIRMED: /*great ACK received*/ if (strcmp("ACK",method)==0) { - if (!op->pending_client_trans || - !belle_sip_transaction_state_is_transient(belle_sip_transaction_get_state((belle_sip_transaction_t*)op->pending_client_trans))){ - if (op->sdp_offering){ - op->process_body_for_ack(req); + if (!op->mPendingClientTransaction || + !belle_sip_transaction_state_is_transient(belle_sip_transaction_get_state((belle_sip_transaction_t*)op->mPendingClientTransaction))){ + if (op->mSdpOffering){ + op->processBodyForAck(req); } - op->root->callbacks.call_ack_received(op, (SalCustomHeader*)req); + op->mRoot->mCallbacks.call_ack_received(op, (SalCustomHeader*)req); }else{ ms_message("Ignored received ack since a new client transaction has been started since."); } } else if(strcmp("BYE",method)==0) { - op->call_terminated(server_transaction,200,req); + op->callTerminated(server_transaction,200,req); /*call end not notified by dialog deletion because transaction can end before dialog*/ } else if(strcmp("INVITE",method)==0 || (is_update=(strcmp("UPDATE",method)==0)) ) { if (is_update && !belle_sip_message_get_body(BELLE_SIP_MESSAGE(req))) { /*session timer case*/ /*session expire should be handled. to be done when real session timer (rfc4028) will be implemented*/ - resp=op->create_response_from_request(req,200); + resp=op->createResponseFromRequest(req,200); belle_sip_server_transaction_send_response(server_transaction,resp); - belle_sip_object_unref(op->pending_update_server_trans); - op->pending_update_server_trans=NULL; + belle_sip_object_unref(op->mPendingUpdateServerTransaction); + op->mPendingUpdateServerTransaction=NULL; } else { /*re-invite*/ - op->reset_descriptions(); - if (op->process_body_for_invite(req)==SalReasonNone) - op->root->callbacks.call_updating(op,is_update); + op->resetDescriptions(); + if (op->processBodyForInvite(req)==SalReasonNone) + op->mRoot->mCallbacks.call_updating(op,is_update); } } else if (strcmp("INFO",method)==0){ if (belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)) && strstr(belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)),"picture_fast_update")) { /*vfu request*/ ms_message("Receiving VFU request on op [%p]",op); - if (op->root->callbacks.vfu_request){ - op->root->callbacks.vfu_request(op); + if (op->mRoot->mCallbacks.vfu_request){ + op->mRoot->mCallbacks.vfu_request(op); } }else{ belle_sip_message_t *msg = BELLE_SIP_MESSAGE(req); - belle_sip_body_handler_t *body_handler = BELLE_SIP_BODY_HANDLER(op->get_body_handler(msg)); + belle_sip_body_handler_t *body_handler = BELLE_SIP_BODY_HANDLER(op->getBodyHandler(msg)); if (body_handler) { belle_sip_header_content_type_t *content_type = belle_sip_message_get_header_by_type(msg, belle_sip_header_content_type_t); if (content_type @@ -802,39 +807,39 @@ void SalCallOp::process_request_event_cb(void *op_base, const belle_sip_request_ && (strcmp(belle_sip_header_content_type_get_subtype(content_type), "dtmf-relay") == 0)) { char tmp[10]; if (sal_lines_get_value(belle_sip_message_get_body(msg), "Signal",tmp, sizeof(tmp))){ - op->root->callbacks.dtmf_received(op,tmp[0]); + op->mRoot->mCallbacks.dtmf_received(op,tmp[0]); } }else - op->root->callbacks.info_received(op, (SalBodyHandler *)body_handler); + op->mRoot->mCallbacks.info_received(op, (SalBodyHandler *)body_handler); } else { - op->root->callbacks.info_received(op,NULL); + op->mRoot->mCallbacks.info_received(op,NULL); } } - resp=op->create_response_from_request(req,200); + resp=op->createResponseFromRequest(req,200); belle_sip_server_transaction_send_response(server_transaction,resp); }else if (strcmp("REFER",method)==0) { - op->process_refer(event,server_transaction); + op->processRefer(event,server_transaction); } else if (strcmp("NOTIFY",method)==0) { - op->process_notify(event,server_transaction); + op->processNotify(event,server_transaction); } else if (strcmp("OPTIONS",method)==0) { - resp=op->create_response_from_request(req,200); + resp=op->createResponseFromRequest(req,200); belle_sip_server_transaction_send_response(server_transaction,resp); } else if (strcmp("CANCEL",method)==0) { - belle_sip_transaction_t *last_transaction = belle_sip_dialog_get_last_transaction(op->dialog); - if (last_transaction == NULL || !is_a_pending_invite_incoming_transaction(last_transaction) ) { + belle_sip_transaction_t *last_transaction = belle_sip_dialog_get_last_transaction(op->mDialog); + if (last_transaction == NULL || !isAPendingIncomingInviteTransaction(last_transaction) ) { /*call leg does not exist because 200ok already sent*/ - belle_sip_server_transaction_send_response(server_transaction,op->create_response_from_request(req,481)); + belle_sip_server_transaction_send_response(server_transaction,op->createResponseFromRequest(req,481)); } else { /* CANCEL on re-INVITE for which a 200ok has not been sent yet */ - belle_sip_server_transaction_send_response(server_transaction, op->create_response_from_request(req, 200)); + belle_sip_server_transaction_send_response(server_transaction, op->createResponseFromRequest(req, 200)); belle_sip_server_transaction_send_response(BELLE_SIP_SERVER_TRANSACTION(last_transaction), - op->create_response_from_request(belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(last_transaction)), 487)); + op->createResponseFromRequest(belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(last_transaction)), 487)); } } else if (strcmp("MESSAGE",method)==0){ - op->process_incoming_message(event); + op->processIncomingMessage(event); }else{ - ms_error("unexpected method [%s] for dialog [%p]",belle_sip_request_get_method(req),op->dialog); - unsupported_method(server_transaction,req); + ms_error("unexpected method [%s] for dialog [%p]",belle_sip_request_get_method(req),op->mDialog); + unsupportedMethod(server_transaction,req); } break; default: @@ -846,96 +851,95 @@ void SalCallOp::process_request_event_cb(void *op_base, const belle_sip_request_ if (drop_op) op->release(); } -void SalCallOp::set_call_as_released(SalCallOp *op) { - op->set_released(); +void SalCallOp::setCallAsReleased(SalCallOp *op) { + op->setReleased(); } -void SalCallOp::process_dialog_terminated_cb(void *ctx, const belle_sip_dialog_terminated_event_t *event) { +void SalCallOp::processDialogTerminatedCb(void *ctx, const belle_sip_dialog_terminated_event_t *event) { SalCallOp * op=(SalCallOp *)ctx; - if (op->dialog && op->dialog==belle_sip_dialog_terminated_event_get_dialog(event)) { + if (op->mDialog && op->mDialog==belle_sip_dialog_terminated_event_get_dialog(event)) { /*belle_sip_transaction_t* trans=belle_sip_dialog_get_last_transaction(op->dialog);*/ ms_message("Dialog [%p] terminated for op [%p]",belle_sip_dialog_terminated_event_get_dialog(event),op); - switch(belle_sip_dialog_get_previous_state(op->dialog)) { + switch(belle_sip_dialog_get_previous_state(op->mDialog)) { case BELLE_SIP_DIALOG_EARLY: case BELLE_SIP_DIALOG_NULL: - if (op->state!=State::Terminated && op->state!=State::Terminating) { + if (op->mState!=State::Terminated && op->mState!=State::Terminating) { /*this is an early termination due to incorrect response received*/ - op->root->callbacks.call_failure(op); - op->state=State::Terminating; + op->mRoot->mCallbacks.call_failure(op); + op->mState=State::Terminating; } break; case BELLE_SIP_DIALOG_CONFIRMED: - if (op->state!=State::Terminated && op->state!=State::Terminating) { + if (op->mState!=State::Terminated && op->mState!=State::Terminating) { /*this is probably a normal termination from a BYE*/ - op->root->callbacks.call_terminated(op,op->dir==Dir::Incoming?op->get_from():op->get_to()); - op->state=State::Terminating; + op->mRoot->mCallbacks.call_terminated(op,op->mDir==Dir::Incoming?op->getFrom().c_str():op->getTo().c_str()); + op->mState=State::Terminating; } break; default: break; } - belle_sip_main_loop_do_later(belle_sip_stack_get_main_loop(op->root->stack) - ,(belle_sip_callback_t) set_call_as_released + belle_sip_main_loop_do_later(belle_sip_stack_get_main_loop(op->mRoot->mStack) + ,(belle_sip_callback_t) setCallAsReleased , op); } else { ms_error("dialog unknown for op "); } } -void SalCallOp::fill_cbs() { +void SalCallOp::fillCallbacks() { static belle_sip_listener_callbacks_t call_op_callbacks = {0}; if (call_op_callbacks.process_response_event==NULL){ - call_op_callbacks.process_io_error=process_io_error_cb; - call_op_callbacks.process_response_event=process_response_cb; - call_op_callbacks.process_timeout=process_timeout_cb; - call_op_callbacks.process_transaction_terminated=process_transaction_terminated_cb; - call_op_callbacks.process_request_event=process_request_event_cb; - call_op_callbacks.process_dialog_terminated=process_dialog_terminated_cb; + call_op_callbacks.process_io_error=processIoErrorCb; + call_op_callbacks.process_response_event=processResponseCb; + call_op_callbacks.process_timeout=processTimeoutCb; + call_op_callbacks.process_transaction_terminated=processTransactionTerminatedCb; + call_op_callbacks.process_request_event=processRequestEventCb; + call_op_callbacks.process_dialog_terminated=processDialogTerminatedCb; } - this->callbacks=&call_op_callbacks; - this->type=Type::Call; + mCallbacks=&call_op_callbacks; + mType=Type::Call; } int SalCallOp::call(const char *from, const char *to, const char *subject) { belle_sip_request_t* invite; - this->dir=Dir::Outgoing; + mDir=Dir::Outgoing; - set_from(from); - set_to(to); + setFrom(from); + setTo(to); ms_message("[%s] calling [%s] on op [%p]", from, to, this); - invite=build_request("INVITE"); + invite=buildRequest("INVITE"); if( invite == NULL ){ /* can happen if the op has an invalid address */ return -1; } - fill_invite(invite); + fillInvite(invite); if (subject) belle_sip_message_add_header(BELLE_SIP_MESSAGE(invite), belle_sip_header_create("Subject", subject)); - fill_cbs(); - if (this->replaces){ - belle_sip_message_add_header(BELLE_SIP_MESSAGE(invite),BELLE_SIP_HEADER(this->replaces)); + fillCallbacks(); + if (mReplaces){ + belle_sip_message_add_header(BELLE_SIP_MESSAGE(invite),BELLE_SIP_HEADER(mReplaces)); } - if (this->referred_by) - belle_sip_message_add_header(BELLE_SIP_MESSAGE(invite),BELLE_SIP_HEADER(this->referred_by)); + if (mReferredBy) + belle_sip_message_add_header(BELLE_SIP_MESSAGE(invite),BELLE_SIP_HEADER(mReferredBy)); - return send_request(invite); + return sendRequest(invite); } -int SalCallOp::notify_ringing(bool_t early_media){ +int SalCallOp::notifyRinging(bool early_media){ int status_code =early_media?183:180; - belle_sip_request_t* req=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(this->pending_server_trans)); - belle_sip_response_t* ringing_response = create_response_from_request(req,status_code); + belle_sip_request_t* req=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(mPendingServerTransaction)); + belle_sip_response_t* ringing_response = createResponseFromRequest(req,status_code); belle_sip_header_t *require; const char *tags=NULL; - if (early_media){ - handle_offer_answer_response(ringing_response); - } + if (early_media) + handleOfferAnswerResponse(ringing_response); require=belle_sip_message_get_header((belle_sip_message_t*)req,"Require"); if (require) tags=belle_sip_header_get_unparsed_value(require); /* if client requires 100rel, then add necessary stuff*/ @@ -948,13 +952,13 @@ int SalCallOp::notify_ringing(bool_t early_media){ if (tags && strstr(tags,"100rel")!=0) #endif { - belle_sip_header_address_t* contact= (belle_sip_header_address_t*)get_contact_address(); + belle_sip_header_address_t* contact= (belle_sip_header_address_t*)getContactAddress(); belle_sip_header_contact_t* contact_header; if (contact && (contact_header=belle_sip_header_contact_create(contact))) { belle_sip_message_add_header(BELLE_SIP_MESSAGE(ringing_response),BELLE_SIP_HEADER(contact_header)); } } - belle_sip_server_transaction_send_response(this->pending_server_trans,ringing_response); + belle_sip_server_transaction_send_response(mPendingServerTransaction,ringing_response); return 0; } @@ -964,11 +968,11 @@ int SalCallOp::accept() { belle_sip_server_transaction_t* transaction; /*first check if an UPDATE transaction need to be accepted*/ - if (this->pending_update_server_trans) { - transaction= this->pending_update_server_trans; - } else if (this->pending_server_trans) { + if (mPendingUpdateServerTransaction) { + transaction= mPendingUpdateServerTransaction; + } else if (mPendingServerTransaction) { /*so it must be an invite/re-invite*/ - transaction= this->pending_server_trans; + transaction= mPendingServerTransaction; } else { ms_error("No transaction to accept for op [%p]", this); return -1; @@ -976,39 +980,39 @@ int SalCallOp::accept() { ms_message("Accepting server transaction [%p] on op [%p]", transaction, this); /* sends a 200 OK */ - response = create_response_from_request(belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(transaction)),200); + response = createResponseFromRequest(belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(transaction)),200); if (response==NULL){ ms_error("Fail to build answer for call"); return -1; } - belle_sip_message_add_header(BELLE_SIP_MESSAGE(response),BELLE_SIP_HEADER(create_allow(this->root->enable_sip_update))); - if (this->root->session_expires!=0){ + belle_sip_message_add_header(BELLE_SIP_MESSAGE(response),BELLE_SIP_HEADER(createAllow(mRoot->mEnableSipUpdate))); + if (mRoot->mSessionExpires!=0){ /* if (h->supports_session_timers) {*/ belle_sip_message_add_header(BELLE_SIP_MESSAGE(response),belle_sip_header_create("Supported", "timer")); belle_sip_message_add_header(BELLE_SIP_MESSAGE(response),belle_sip_header_create( "Session-expires", "600;refresher=uac")); /*}*/ } - if ((contact_header=create_contact())) { + if ((contact_header=createContact())) { belle_sip_message_add_header(BELLE_SIP_MESSAGE(response),BELLE_SIP_HEADER(contact_header)); } - add_custom_headers(BELLE_SIP_MESSAGE(response)); + addCustomHeaders(BELLE_SIP_MESSAGE(response)); - handle_offer_answer_response(response); + handleOfferAnswerResponse(response); belle_sip_server_transaction_send_response(transaction,response); - if (this->pending_update_server_trans) { - belle_sip_object_unref(this->pending_update_server_trans); - this->pending_update_server_trans=NULL; + if (mPendingUpdateServerTransaction) { + belle_sip_object_unref(mPendingUpdateServerTransaction); + mPendingUpdateServerTransaction=NULL; } - if (this->state == State::Early){ - this->state = State::Active; + if (mState == State::Early){ + mState = State::Active; } return 0; } -int SalCallOp::decline(SalReason reason, const char *redirection /*optional*/){ +int SalCallOp::decline(SalReason reason, const char *redirection){ belle_sip_response_t* response; belle_sip_header_contact_t* contact=NULL; int status=to_sip_code(reason); @@ -1024,19 +1028,19 @@ int SalCallOp::decline(SalReason reason, const char *redirection /*optional*/){ ms_error("Cannot redirect to null"); } } - trans=(belle_sip_transaction_t*)this->pending_server_trans; - if (!trans) trans=(belle_sip_transaction_t*)this->pending_update_server_trans; + trans=(belle_sip_transaction_t*)mPendingServerTransaction; + if (!trans) trans=(belle_sip_transaction_t*)mPendingUpdateServerTransaction; if (!trans){ ms_error("sal_call_decline(): no pending transaction to decline."); return -1; } - response = create_response_from_request(belle_sip_transaction_get_request(trans),status); + response = createResponseFromRequest(belle_sip_transaction_get_request(trans),status); if (contact) belle_sip_message_add_header(BELLE_SIP_MESSAGE(response),BELLE_SIP_HEADER(contact)); belle_sip_server_transaction_send_response(BELLE_SIP_SERVER_TRANSACTION(trans),response); return 0; } -belle_sip_header_reason_t *SalCallOp::make_reason_header( const SalErrorInfo *info){ +belle_sip_header_reason_t *SalCallOp::makeReasonHeader( const SalErrorInfo *info){ if (info && info->reason != SalReasonNone) { belle_sip_header_reason_t* reason = BELLE_SIP_HEADER_REASON(belle_sip_header_reason_new()); belle_sip_header_reason_set_text(reason, info->status_string); @@ -1047,7 +1051,7 @@ belle_sip_header_reason_t *SalCallOp::make_reason_header( const SalErrorInfo *in return NULL; } -int SalCallOp::decline_with_error_info(const SalErrorInfo *info, const SalAddress *redirectionAddr /*optional*/){ +int SalCallOp::declineWithErrorInfo(const SalErrorInfo *info, const SalAddress *redirectionAddr){ belle_sip_response_t* response; belle_sip_header_contact_t* contact=NULL; int status = info->protocol_code; @@ -1061,14 +1065,14 @@ int SalCallOp::decline_with_error_info(const SalErrorInfo *info, const SalAddres ms_error("Cannot redirect to null"); } } - trans=(belle_sip_transaction_t*)this->pending_server_trans; - if (!trans) trans=(belle_sip_transaction_t*)this->pending_update_server_trans; + trans=(belle_sip_transaction_t*)mPendingServerTransaction; + if (!trans) trans=(belle_sip_transaction_t*)mPendingUpdateServerTransaction; if (!trans){ ms_error("sal_call_decline_with_error_info(): no pending transaction to decline."); return -1; } - response = create_response_from_request(belle_sip_transaction_get_request(trans),status); - belle_sip_header_reason_t* reason_header = make_reason_header(info->sub_sei); + response = createResponseFromRequest(belle_sip_transaction_get_request(trans),status); + belle_sip_header_reason_t* reason_header = makeReasonHeader(info->sub_sei); if (reason_header) { belle_sip_message_add_header(BELLE_SIP_MESSAGE(response),BELLE_SIP_HEADER(reason_header)); } @@ -1080,73 +1084,71 @@ int SalCallOp::decline_with_error_info(const SalErrorInfo *info, const SalAddres return 0; } -int SalCallOp::update(const char *subject, bool_t no_user_consent) { +int SalCallOp::update(const char *subject, bool no_user_consent) { belle_sip_request_t *update; belle_sip_dialog_state_t state; - if (this->dialog == NULL) { + if (mDialog == NULL) { /* If the dialog does not exist, this is that we are trying to recover from a connection loss during a very early state of outgoing call initiation (the dialog has not been created yet). */ - const char *from = get_from(); - const char *to = get_to(); - return call(from, to, subject); + return call(mFrom.c_str(), mTo.c_str(), subject); } - state = belle_sip_dialog_get_state(this->dialog); - belle_sip_dialog_enable_pending_trans_checking(this->dialog,this->root->pending_trans_checking); + state = belle_sip_dialog_get_state(mDialog); + belle_sip_dialog_enable_pending_trans_checking(mDialog,mRoot->mPendingTransactionChecking); /*check for dialog state*/ if ( state == BELLE_SIP_DIALOG_CONFIRMED) { if (no_user_consent) - update=belle_sip_dialog_create_request(this->dialog,"UPDATE"); + update=belle_sip_dialog_create_request(mDialog,"UPDATE"); else - update=belle_sip_dialog_create_request(this->dialog,"INVITE"); + update=belle_sip_dialog_create_request(mDialog,"INVITE"); } else if (state == BELLE_SIP_DIALOG_EARLY) { - update=belle_sip_dialog_create_request(this->dialog,"UPDATE"); + update=belle_sip_dialog_create_request(mDialog,"UPDATE"); } else { - ms_error("Cannot update op [%p] with dialog [%p] in state [%s]", this, this->dialog,belle_sip_dialog_state_to_string(state)); + ms_error("Cannot update op [%p] with dialog [%p] in state [%s]", this, mDialog,belle_sip_dialog_state_to_string(state)); return -1; } if (update){ belle_sip_message_add_header(BELLE_SIP_MESSAGE(update),belle_sip_header_create( "Subject", subject)); - fill_invite(update); - return send_request(update); + fillInvite(update); + return sendRequest(update); } /*it failed why ?*/ - if (belle_sip_dialog_request_pending(this->dialog)) - sal_error_info_set(&this->error_info,SalReasonRequestPending, "SIP", 491,NULL,NULL); + if (belle_sip_dialog_request_pending(mDialog)) + sal_error_info_set(&mErrorInfo,SalReasonRequestPending, "SIP", 491,NULL,NULL); else - sal_error_info_set(&this->error_info,SalReasonUnknown, "SIP", 500,NULL,NULL); + sal_error_info_set(&mErrorInfo,SalReasonUnknown, "SIP", 500,NULL,NULL); return -1; } -int SalCallOp::cancel_invite_with_info(const SalErrorInfo *info) { +int SalCallOp::cancelInvite(const SalErrorInfo *info) { belle_sip_request_t* cancel; - ms_message("Cancelling INVITE request from [%s] to [%s] ",get_from(), get_to()); + ms_message("Cancelling INVITE request from [%s] to [%s] ",getFrom().c_str(), getTo().c_str()); - if (this->pending_client_trans == NULL) { + if (mPendingClientTransaction == NULL) { ms_warning("There is no transaction to cancel."); return -1; } - cancel = belle_sip_client_transaction_create_cancel(this->pending_client_trans); + cancel = belle_sip_client_transaction_create_cancel(mPendingClientTransaction); if (cancel) { if (info && info->reason != SalReasonNone) { - belle_sip_header_reason_t* reason = make_reason_header(info); + belle_sip_header_reason_t* reason = makeReasonHeader(info); belle_sip_message_add_header(BELLE_SIP_MESSAGE(cancel),BELLE_SIP_HEADER(reason)); } - send_request(cancel); + sendRequest(cancel); return 0; - } else if (this->dialog) { - belle_sip_dialog_state_t state = belle_sip_dialog_get_state(this->dialog);; + } else if (mDialog) { + belle_sip_dialog_state_t state = belle_sip_dialog_get_state(mDialog);; /*case where the response received is invalid (could not establish a dialog), but the transaction is not cancellable * because already terminated*/ switch(state) { case BELLE_SIP_DIALOG_EARLY: case BELLE_SIP_DIALOG_NULL: /*force kill the dialog*/ - ms_warning("op [%p]: force kill of dialog [%p]", this, this->dialog); - belle_sip_dialog_delete(this->dialog); + ms_warning("op [%p]: force kill of dialog [%p]", this, mDialog); + belle_sip_dialog_delete(mDialog); break; default: break; @@ -1155,16 +1157,16 @@ int SalCallOp::cancel_invite_with_info(const SalErrorInfo *info) { return -1; } -SalMediaDescription *SalCallOp::get_final_media_description() { - if (this->local_media && this->remote_media && !this->result){ - sdp_process(); +SalMediaDescription *SalCallOp::getFinalMediaDescription() { + if (mLocalMedia && mRemoteMedia && !mResult){ + sdpProcess(); } - return this->result; + return mResult; } -int SalCallOp::refer_to(belle_sip_header_refer_to_t* refer_to, belle_sip_header_referred_by_t* referred_by) { +int SalCallOp::referTo(belle_sip_header_refer_to_t* refer_to, belle_sip_header_referred_by_t* referred_by) { char* tmp; - belle_sip_request_t* req=this->dialog?belle_sip_dialog_create_request(this->dialog,"REFER"):build_request("REFER"); + belle_sip_request_t* req=mDialog?belle_sip_dialog_create_request(mDialog,"REFER"):buildRequest("REFER"); if (!req) { tmp=belle_sip_uri_to_string(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(refer_to))); ms_error("Cannot refer to [%s] for op [%p]",tmp, this); @@ -1173,25 +1175,25 @@ int SalCallOp::refer_to(belle_sip_header_refer_to_t* refer_to, belle_sip_header_ } belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(refer_to)); if (referred_by) belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(referred_by)); - return send_request(req); + return sendRequest(req); } int SalCallOp::refer(const char *refer_to_){ belle_sip_header_address_t *referred_by; belle_sip_header_refer_to_t* refer_to_header; - if (this->dialog) { - referred_by=(belle_sip_header_address_t*)belle_sip_object_clone(BELLE_SIP_OBJECT(belle_sip_dialog_get_local_party(this->dialog))); + if (mDialog) { + referred_by=(belle_sip_header_address_t*)belle_sip_object_clone(BELLE_SIP_OBJECT(belle_sip_dialog_get_local_party(mDialog))); }else{ - referred_by=BELLE_SIP_HEADER_ADDRESS(get_from_address()); + referred_by=BELLE_SIP_HEADER_ADDRESS(getFromAddress()); } refer_to_header=belle_sip_header_refer_to_create(belle_sip_header_address_parse(refer_to_)); - return refer_to(refer_to_header,belle_sip_header_referred_by_create(referred_by)); + return referTo(refer_to_header,belle_sip_header_referred_by_create(referred_by)); } -int SalCallOp::refer_with_replaces(SalCallOp *other_call_op) { - belle_sip_dialog_state_t other_call_dialog_state=other_call_op->dialog?belle_sip_dialog_get_state(other_call_op->dialog):BELLE_SIP_DIALOG_NULL; - belle_sip_dialog_state_t op_dialog_state= this->dialog?belle_sip_dialog_get_state(this->dialog):BELLE_SIP_DIALOG_NULL; +int SalCallOp::referWithReplaces(SalCallOp *other_call_op) { + belle_sip_dialog_state_t other_call_dialog_state=other_call_op->mDialog?belle_sip_dialog_get_state(other_call_op->mDialog):BELLE_SIP_DIALOG_NULL; + belle_sip_dialog_state_t op_dialog_state= mDialog?belle_sip_dialog_get_state(mDialog):BELLE_SIP_DIALOG_NULL; belle_sip_header_replaces_t* replaces; belle_sip_header_refer_to_t* refer_to_; belle_sip_header_referred_by_t* referred_by; @@ -1212,7 +1214,7 @@ int SalCallOp::refer_with_replaces(SalCallOp *other_call_op) { return -1; } - refer_to_ =belle_sip_header_refer_to_create(belle_sip_dialog_get_remote_party(other_call_op->dialog)); + refer_to_ =belle_sip_header_refer_to_create(belle_sip_dialog_get_remote_party(other_call_op->mDialog)); belle_sip_parameters_clean(BELLE_SIP_PARAMETERS(refer_to_)); /*rfc3891 ... @@ -1224,29 +1226,29 @@ int SalCallOp::refer_with_replaces(SalCallOp *other_call_op) { User Agent Client (UAC) places the Call-ID, to-tag, and from-tag information for the target dialog in a single Replaces header field and sends the new INVITE to the target.*/ - from_tag=belle_sip_dialog_get_local_tag(other_call_op->dialog); - to_tag=belle_sip_dialog_get_remote_tag(other_call_op->dialog); + from_tag=belle_sip_dialog_get_local_tag(other_call_op->mDialog); + to_tag=belle_sip_dialog_get_remote_tag(other_call_op->mDialog); - replaces=belle_sip_header_replaces_create(belle_sip_header_call_id_get_call_id(belle_sip_dialog_get_call_id(other_call_op->dialog)) + replaces=belle_sip_header_replaces_create(belle_sip_header_call_id_get_call_id(belle_sip_dialog_get_call_id(other_call_op->mDialog)) ,from_tag,to_tag); escaped_replaces=belle_sip_header_replaces_value_to_escaped_string(replaces); belle_sip_uri_set_header(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(refer_to_)),"Replaces",escaped_replaces); belle_sip_free(escaped_replaces); - referred_by=belle_sip_header_referred_by_create(belle_sip_dialog_get_local_party(this->dialog)); + referred_by=belle_sip_header_referred_by_create(belle_sip_dialog_get_local_party(mDialog)); belle_sip_parameters_clean(BELLE_SIP_PARAMETERS(referred_by)); - return refer_to(refer_to_,referred_by); + return referTo(refer_to_,referred_by); } -int SalCallOp::set_referer(SalCallOp *refered_call){ - if (refered_call->replaces) - SalOp::set_replaces(refered_call->replaces); - if (refered_call->referred_by) - set_referred_by(refered_call->referred_by); +int SalCallOp::setReferrer(SalCallOp *refered_call){ + if (refered_call->mReplaces) + SalOp::setReplaces(refered_call->mReplaces); + if (refered_call->mReferredBy) + setReferredBy(refered_call->mReferredBy); return 0; } -SalCallOp *SalCallOp::get_replaces() { - if (this->replaces){ +SalCallOp *SalCallOp::getReplaces() const { + if (mReplaces){ /*rfc3891 3. User Agent Server Behavior: Receiving a Replaces Header @@ -1259,17 +1261,17 @@ SalCallOp *SalCallOp::get_replaces() { is compared to the local tag, and the from-tag parameter is compared to the remote tag. */ - belle_sip_dialog_t* dialog=belle_sip_provider_find_dialog(this->root->prov - ,belle_sip_header_replaces_get_call_id(this->replaces) - ,belle_sip_header_replaces_get_to_tag(this->replaces) - ,belle_sip_header_replaces_get_from_tag(this->replaces)); + belle_sip_dialog_t* dialog=belle_sip_provider_find_dialog(mRoot->mProvider + ,belle_sip_header_replaces_get_call_id(mReplaces) + ,belle_sip_header_replaces_get_to_tag(mReplaces) + ,belle_sip_header_replaces_get_from_tag(mReplaces)); if (!dialog) { /*for backward compatibility with liblinphone <= 3.10.2-243 */ - dialog=belle_sip_provider_find_dialog(this->root->prov - ,belle_sip_header_replaces_get_call_id(this->replaces) - ,belle_sip_header_replaces_get_from_tag(this->replaces) - ,belle_sip_header_replaces_get_to_tag(this->replaces)); + dialog=belle_sip_provider_find_dialog(mRoot->mProvider + ,belle_sip_header_replaces_get_call_id(mReplaces) + ,belle_sip_header_replaces_get_from_tag(mReplaces) + ,belle_sip_header_replaces_get_to_tag(mReplaces)); } if (dialog) { return (SalCallOp*)belle_sip_dialog_get_application_data(dialog); @@ -1278,9 +1280,9 @@ SalCallOp *SalCallOp::get_replaces() { return NULL; } -int SalCallOp::send_dtmf(char dtmf){ - if (this->dialog && (belle_sip_dialog_get_state(this->dialog) == BELLE_SIP_DIALOG_CONFIRMED || belle_sip_dialog_get_state(this->dialog) == BELLE_SIP_DIALOG_EARLY)){ - belle_sip_request_t *req=belle_sip_dialog_create_queued_request(this->dialog,"INFO"); +int SalCallOp::sendDtmf(char dtmf){ + if (mDialog && (belle_sip_dialog_get_state(mDialog) == BELLE_SIP_DIALOG_CONFIRMED || belle_sip_dialog_get_state(mDialog) == BELLE_SIP_DIALOG_EARLY)){ + belle_sip_request_t *req=belle_sip_dialog_create_queued_request(mDialog,"INFO"); if (req){ size_t bodylen; char dtmf_body[128]={0}; @@ -1290,69 +1292,69 @@ int SalCallOp::send_dtmf(char dtmf){ belle_sip_message_set_body((belle_sip_message_t*)req,dtmf_body,bodylen); belle_sip_message_add_header((belle_sip_message_t*)req,(belle_sip_header_t*)belle_sip_header_content_length_create(bodylen)); belle_sip_message_add_header((belle_sip_message_t*)req,(belle_sip_header_t*)belle_sip_header_content_type_create("application", "dtmf-relay")); - send_request(req); + sendRequest(req); }else ms_error("sal_call_send_dtmf(): could not build request"); }else ms_error("sal_call_send_dtmf(): no dialog"); return 0; } -int SalCallOp::terminate_with_error(const SalErrorInfo *info) { +int SalCallOp::terminate(const SalErrorInfo *info) { SalErrorInfo sei; const SalErrorInfo *p_sei; - belle_sip_dialog_state_t dialog_state = this->dialog ? belle_sip_dialog_get_state(this->dialog) : BELLE_SIP_DIALOG_NULL; + belle_sip_dialog_state_t dialog_state = mDialog ? belle_sip_dialog_get_state(mDialog) : BELLE_SIP_DIALOG_NULL; int ret = 0; memset(&sei, 0, sizeof(sei)); - if (info == NULL && dialog_state != BELLE_SIP_DIALOG_CONFIRMED && this->dir == Dir::Incoming) { + if (info == NULL && dialog_state != BELLE_SIP_DIALOG_CONFIRMED && mDir == Dir::Incoming) { /*the purpose of this line is to set a default SalErrorInfo for declining an incoming call (not yet established of course) */ sal_error_info_set(&sei,SalReasonDeclined, "SIP", 0, NULL, NULL); p_sei = &sei; } else{ p_sei = info; } - if (this->state==State::Terminating || this->state==State::Terminated) { - ms_error("Cannot terminate op [%p] in state [%s]",this,to_string(this->state)); + if (mState==State::Terminating || mState==State::Terminated) { + lError() << "Cannot terminate op [" << this << "] in state [" << toString(mState) << "]"; ret = -1; goto end; } switch(dialog_state) { case BELLE_SIP_DIALOG_CONFIRMED: { - belle_sip_request_t * req = belle_sip_dialog_create_request(this->dialog,"BYE"); + belle_sip_request_t * req = belle_sip_dialog_create_request(mDialog,"BYE"); if (info && info->reason != SalReasonNone) { - belle_sip_header_reason_t* reason = make_reason_header(info); + belle_sip_header_reason_t* reason = makeReasonHeader(info); belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(reason)); } - send_request(req); - this->state=State::Terminating; + sendRequest(req); + mState=State::Terminating; break; } case BELLE_SIP_DIALOG_NULL: { - if (this->dir == Dir::Incoming) { - decline_with_error_info(p_sei, NULL); - this->state=State::Terminated; - } else if (this->pending_client_trans){ - if (belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(this->pending_client_trans)) == BELLE_SIP_TRANSACTION_PROCEEDING){ - cancelling_invite(p_sei); + if (mDir == Dir::Incoming) { + declineWithErrorInfo(p_sei, NULL); + mState=State::Terminated; + } else if (mPendingClientTransaction){ + if (belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(mPendingClientTransaction)) == BELLE_SIP_TRANSACTION_PROCEEDING){ + cancellingInvite(p_sei); } else { /* Case where the CANCEL cannot be sent because no provisional response was received so far. * The Op must be kept for the time of the transaction in case a response is received later. * The state is passed to Terminating to remember to terminate later. */ - this->state=State::Terminating; + mState=State::Terminating; /* However, even if the transaction is kept alive, we can stop sending retransmissions to avoid flowing the network with no longer * necessary messages and avoid confusion in logs.*/ - belle_sip_client_transaction_stop_retransmissions(this->pending_client_trans); + belle_sip_client_transaction_stop_retransmissions(mPendingClientTransaction); } } break; } case BELLE_SIP_DIALOG_EARLY: { - if (this->dir == Dir::Incoming) { - decline_with_error_info(p_sei,NULL); - this->state=State::Terminated; + if (mDir == Dir::Incoming) { + declineWithErrorInfo(p_sei,NULL); + mState=State::Terminated; } else { - cancelling_invite(p_sei); + cancellingInvite(p_sei); } break; } @@ -1367,7 +1369,7 @@ end: return ret; } -void SalCallOp::send_vfu_request() { +void SalCallOp::sendVfuRequest() { char info_body[] = "" "" @@ -1378,30 +1380,30 @@ void SalCallOp::send_vfu_request() { " " ""; size_t content_lenth = sizeof(info_body) - 1; - belle_sip_dialog_state_t dialog_state= this->dialog?belle_sip_dialog_get_state(this->dialog):BELLE_SIP_DIALOG_NULL; /*no dialog = dialog in NULL state*/ + belle_sip_dialog_state_t dialog_state= mDialog?belle_sip_dialog_get_state(mDialog):BELLE_SIP_DIALOG_NULL; /*no dialog = dialog in NULL state*/ if (dialog_state == BELLE_SIP_DIALOG_CONFIRMED) { - belle_sip_request_t* info = belle_sip_dialog_create_queued_request(this->dialog,"INFO"); + belle_sip_request_t* info = belle_sip_dialog_create_queued_request(mDialog,"INFO"); int error=TRUE; if (info) { belle_sip_message_add_header(BELLE_SIP_MESSAGE(info),BELLE_SIP_HEADER(belle_sip_header_content_type_create("application","media_control+xml"))); belle_sip_message_add_header(BELLE_SIP_MESSAGE(info),BELLE_SIP_HEADER(belle_sip_header_content_length_create(content_lenth))); belle_sip_message_set_body(BELLE_SIP_MESSAGE(info),info_body,content_lenth); - error=send_request(info); + error=sendRequest(info); } if (error) - ms_warning("Cannot send vfu request to [%s] ", get_to()); + ms_warning("Cannot send vfu request to [%s] ", getTo().c_str()); } else { - ms_warning("Cannot send vfu request to [%s] because dialog [%p] in wrong state [%s]",get_to() - ,this->dialog + ms_warning("Cannot send vfu request to [%s] because dialog [%p] in wrong state [%s]",getTo().c_str() + ,mDialog ,belle_sip_dialog_state_to_string(dialog_state)); } return ; } -int SalCallOp::send_notify_for_refer(int code, const char *reason) { - belle_sip_request_t* notify=belle_sip_dialog_create_queued_request(this->dialog,"NOTIFY"); +int SalCallOp::sendNotifyForRefer(int code, const char *reason) { + belle_sip_request_t* notify=belle_sip_dialog_create_queued_request(mDialog,"NOTIFY"); char *sipfrag=belle_sip_strdup_printf("SIP/2.0 %i %s\r\n",code,reason); size_t content_length=strlen(sipfrag); belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify) @@ -1411,54 +1413,54 @@ int SalCallOp::send_notify_for_refer(int code, const char *reason) { belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify),BELLE_SIP_HEADER(belle_sip_header_content_type_create("message","sipfrag"))); belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify),BELLE_SIP_HEADER(belle_sip_header_content_length_create(content_length))); belle_sip_message_assign_body(BELLE_SIP_MESSAGE(notify),sipfrag,content_length); - return send_request(notify); + return sendRequest(notify); } -void SalCallOp::notify_last_response(SalCallOp *newcall) { - belle_sip_client_transaction_t *tr=newcall->pending_client_trans; +void SalCallOp::notifyLastResponse(SalCallOp *newcall) { + belle_sip_client_transaction_t *tr=newcall->mPendingClientTransaction; belle_sip_response_t *resp=NULL; if (tr){ resp=belle_sip_transaction_get_response((belle_sip_transaction_t*)tr); } if (resp==NULL){ - send_notify_for_refer(100, "Trying"); + sendNotifyForRefer(100, "Trying"); }else{ - send_notify_for_refer(belle_sip_response_get_status_code(resp), belle_sip_response_get_reason_phrase(resp)); + sendNotifyForRefer(belle_sip_response_get_status_code(resp), belle_sip_response_get_reason_phrase(resp)); } } -int SalCallOp::notify_refer_state(SalCallOp *newcall) { +int SalCallOp::notifyReferState(SalCallOp *newcall) { belle_sip_dialog_state_t state; - if(belle_sip_dialog_get_state(this->dialog) == BELLE_SIP_DIALOG_TERMINATED){ + if(belle_sip_dialog_get_state(mDialog) == BELLE_SIP_DIALOG_TERMINATED){ return 0; } - state = newcall->dialog?belle_sip_dialog_get_state(newcall->dialog):BELLE_SIP_DIALOG_NULL; + state = newcall->mDialog?belle_sip_dialog_get_state(newcall->mDialog):BELLE_SIP_DIALOG_NULL; switch(state) { case BELLE_SIP_DIALOG_EARLY: - send_notify_for_refer(100, "Trying"); + sendNotifyForRefer(100, "Trying"); break; case BELLE_SIP_DIALOG_CONFIRMED: - send_notify_for_refer(200, "Ok"); + sendNotifyForRefer(200, "Ok"); break; case BELLE_SIP_DIALOG_TERMINATED: case BELLE_SIP_DIALOG_NULL: - notify_last_response(newcall); + notifyLastResponse(newcall); break; } return 0; } -void SalCallOp::set_replaces(const char *call_id, const char *from_tag, const char *to_tag) { +void SalCallOp::setReplaces(const char *call_id, const char *from_tag, const char *to_tag) { belle_sip_header_replaces_t *replaces = belle_sip_header_replaces_create(call_id, from_tag, to_tag); - SalOp::set_replaces(replaces); + SalOp::setReplaces(replaces); } -void SalCallOp::set_sdp_handling(SalOpSDPHandling handling) { +void SalCallOp::setSdpHandling(SalOpSDPHandling handling) { if (handling != SalOpSDPNormal) ms_message("Enabling special SDP handling for SalOp[%p]!", this); - this->sdp_handling = handling; + mSdpHandling = handling; } -void SalCallOp::process_refer(const belle_sip_request_event_t *event, belle_sip_server_transaction_t *server_transaction) { +void SalCallOp::processRefer(const belle_sip_request_event_t *event, belle_sip_server_transaction_t *server_transaction) { belle_sip_request_t* req = belle_sip_request_event_get_request(event); belle_sip_header_refer_to_t *refer_to= belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_refer_to_t); belle_sip_header_referred_by_t *referred_by= belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_referred_by_t); @@ -1470,24 +1472,24 @@ void SalCallOp::process_refer(const belle_sip_request_event_t *event, belle_sip_ refer_to_uri=belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(refer_to)); if (refer_to_uri && belle_sip_uri_get_header(refer_to_uri,"Replaces")) { - SalOp::set_replaces(belle_sip_header_replaces_create2(belle_sip_uri_get_header(refer_to_uri,"Replaces"))); + SalOp::setReplaces(belle_sip_header_replaces_create2(belle_sip_uri_get_header(refer_to_uri,"Replaces"))); belle_sip_uri_remove_header(refer_to_uri,"Replaces"); } if (referred_by){ - set_referred_by(referred_by); + setReferredBy(referred_by); } - resp = create_response_from_request(req,202); + resp = createResponseFromRequest(req,202); belle_sip_server_transaction_send_response(server_transaction,resp); - this->root->callbacks.call_refer_received(this,(SalAddress*)BELLE_SIP_HEADER_ADDRESS(refer_to)); + mRoot->mCallbacks.call_refer_received(this,(SalAddress*)BELLE_SIP_HEADER_ADDRESS(refer_to)); } else { ms_warning("cannot do anything with the refer without destination"); - resp = create_response_from_request(req,400); + resp = createResponseFromRequest(req,400); belle_sip_server_transaction_send_response(server_transaction,resp); } } -void SalCallOp::process_notify(const belle_sip_request_event_t *event, belle_sip_server_transaction_t* server_transaction) { +void SalCallOp::processNotify(const belle_sip_request_event_t *event, belle_sip_server_transaction_t* server_transaction) { belle_sip_request_t* req = belle_sip_request_event_get_request(event); const char* body = belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)); belle_sip_header_t* header_event=belle_sip_message_get_header(BELLE_SIP_MESSAGE(req),"Event"); @@ -1514,48 +1516,49 @@ void SalCallOp::process_notify(const belle_sip_request_event_t *event, belle_sip status=SalReferFailed; } belle_sip_object_unref(sipfrag); - resp = create_response_from_request(req,200); + resp = createResponseFromRequest(req,200); belle_sip_server_transaction_send_response(server_transaction,resp); - this->root->callbacks.notify_refer(this,status); + mRoot->mCallbacks.notify_refer(this,status); } }else{ ms_error("Notify without sipfrag, trashing"); - resp = create_response_from_request(req,501); + resp = createResponseFromRequest(req,501); belle_sip_server_transaction_send_response(server_transaction,resp); } } -int SalCallOp::send_message(const char* content_type, const char *msg) { - if (!this->dialog) return -1; - belle_sip_request_t* req=belle_sip_dialog_create_queued_request(this->dialog,"MESSAGE"); - prepare_message_request(req, content_type, msg); - return send_request(req); +int SalCallOp::sendMessage (const Content &content) { + if (!mDialog) + return -1; + belle_sip_request_t *req = belle_sip_dialog_create_queued_request(mDialog, "MESSAGE"); + prepareMessageRequest(req, content); + return sendRequest(req); } -bool_t SalCallOp::compare_op(const SalCallOp *op2) const { - return (strcmp(this->call_id, op2->call_id) == 0); +bool SalCallOp::compareOp(const SalCallOp *op2) const { + return mCallId == op2->mCallId; } -void SalCallOp::handle_offer_answer_response(belle_sip_response_t* response) { - if (this->local_media){ +void SalCallOp::handleOfferAnswerResponse(belle_sip_response_t* response) { + if (mLocalMedia){ /*this is the case where we received an invite without SDP*/ - if (this->sdp_offering) { - set_sdp_from_desc(BELLE_SIP_MESSAGE(response),this->local_media); + if (mSdpOffering) { + setSdpFromDesc(BELLE_SIP_MESSAGE(response),mLocalMedia); }else{ - if ( this->sdp_answer==NULL ) + if ( mSdpAnswer==NULL ) { - if( this->sdp_handling == SalOpSDPSimulateRemove ){ + if( mSdpHandling == SalOpSDPSimulateRemove ){ ms_warning("Simulating SDP removal in answer for op %p", this); } else { - sdp_process(); + sdpProcess(); } } - if (this->sdp_answer){ - set_sdp(BELLE_SIP_MESSAGE(response),this->sdp_answer); - belle_sip_object_unref(this->sdp_answer); - this->sdp_answer=NULL; + if (mSdpAnswer){ + setSdp(BELLE_SIP_MESSAGE(response),mSdpAnswer); + belle_sip_object_unref(mSdpAnswer); + mSdpAnswer=NULL; } } }else{ diff --git a/src/sal/call-op.h b/src/sal/call-op.h index fea958e6d..dfb4ead5e 100644 --- a/src/sal/call-op.h +++ b/src/sal/call-op.h @@ -25,105 +25,103 @@ LINPHONE_BEGIN_NAMESPACE -class SalCallOp: public SalOp, public SalMessageOpInterface { +class SalCallOp : public SalOp, public SalMessageOpInterface { public: - SalCallOp(Sal *sal): SalOp(sal) {} - ~SalCallOp() override; + SalCallOp (Sal *sal) : SalOp(sal) {} + ~SalCallOp () override; - SalMediaDescription *get_local_media_description () const { return local_media; } - int set_local_media_description(SalMediaDescription *desc); - int set_local_body(const Content &body); - int set_local_body(const Content &&body); + SalMediaDescription *getLocalMediaDescription () const { return mLocalMedia; } + int setLocalMediaDescription (SalMediaDescription *desc); + int setLocalBody (const Content &body); + int setLocalBody (const Content &&body); - SalMediaDescription *get_remote_media_description() {return this->remote_media;} - const Content &get_remote_body() const {return this->remote_body;} - SalMediaDescription *get_final_media_description(); + SalMediaDescription *getRemoteMediaDescription () { return mRemoteMedia; } + const Content &getRemoteBody () const { return mRemoteBody; } + SalMediaDescription *getFinalMediaDescription (); - int call(const char *from, const char *to, const char *subject); - int notify_ringing(bool_t early_media); - int accept(); - int decline(SalReason reason, const char *redirection /*optional*/); - int decline_with_error_info(const SalErrorInfo *info, const SalAddress *redirectionAddr /*optional*/); - int update(const char *subject, bool_t no_user_consent); - int cancel_invite() { return cancel_invite_with_info(NULL);} - int cancel_invite_with_info(const SalErrorInfo *info); - int refer(const char *refer_to_); - int refer_with_replaces(SalCallOp *other_call_op); - int set_referer(SalCallOp *refered_call); - SalCallOp *get_replaces(); - int send_dtmf(char dtmf); - int terminate() {return terminate_with_error(NULL);} - int terminate_with_error(const SalErrorInfo *info); - bool_t autoanswer_asked() const {return this->auto_answer_asked;} - void send_vfu_request(); - int is_offerer() const {return this->sdp_offering;} - int notify_refer_state(SalCallOp *newcall); - bool_t compare_op(const SalCallOp *op2) const; - bool_t dialog_request_pending() const {return (belle_sip_dialog_request_pending(this->dialog) != 0);} - const char *get_local_tag() {return belle_sip_dialog_get_local_tag(this->dialog);} - const char *get_remote_tag() {return belle_sip_dialog_get_remote_tag(this->dialog);} - void set_replaces(const char *call_id, const char *from_tag, const char *to_tag); - void set_sdp_handling(SalOpSDPHandling handling); + int call (const char *from, const char *to, const char *subject); + int notifyRinging (bool earlyMedia); + int accept (); + int decline (SalReason reason, const char *redirection = nullptr); + int declineWithErrorInfo (const SalErrorInfo *info, const SalAddress *redirectionAddr = nullptr); + int update (const char *subject, bool noUserConsent); + int cancelInvite (const SalErrorInfo *info = nullptr); + int refer (const char *referTo); + int referWithReplaces (SalCallOp *otherCallOp); + int setReferrer (SalCallOp *referredCall); + SalCallOp *getReplaces () const; + int sendDtmf (char dtmf); + int terminate (const SalErrorInfo *info = nullptr); + bool autoAnswerAsked () const { return mAutoAnswerAsked; } + void sendVfuRequest (); + int isOfferer () const { return mSdpOffering; } + int notifyReferState (SalCallOp *newCallOp); + bool compareOp (const SalCallOp *otherCallOp) const; + bool dialogRequestPending () const { return (belle_sip_dialog_request_pending(mDialog) != 0); } + const char *getLocalTag () { return belle_sip_dialog_get_local_tag(mDialog); } + const char *getRemoteTag () { return belle_sip_dialog_get_remote_tag(mDialog); } + void setReplaces (const char *callId, const char *fromTag, const char *toTag); + void setSdpHandling (SalOpSDPHandling handling); // Implementation of SalMessageOpInterface - int send_message(const char* content_type, const char *msg) override; - int reply(SalReason reason) override {return SalOp::reply_message(reason);} + int sendMessage (const Content &content) override; + int reply (SalReason reason) override { return SalOp::replyMessage(reason); } private: - virtual void fill_cbs() override; - void set_released(); + virtual void fillCallbacks () override; + void setReleased (); - void set_error(belle_sip_response_t* response, bool_t fatal); - void call_terminated(belle_sip_server_transaction_t* server_transaction, int status_code, belle_sip_request_t* cancel_request); - void reset_descriptions(); + void setError (belle_sip_response_t *response, bool fatal); + void callTerminated (belle_sip_server_transaction_t *serverTransaction, int statusCode, belle_sip_request_t *cancelRequest); + void resetDescriptions (); - int parse_sdp_body(const Content &body,belle_sdp_session_description_t** session_desc, SalReason *error); - void sdp_process(); - void handle_body_from_response(belle_sip_response_t* response); - SalReason process_body_for_invite(belle_sip_request_t* invite); - SalReason process_body_for_ack(belle_sip_request_t *ack); - void handle_offer_answer_response(belle_sip_response_t* response); + int parseSdpBody (const Content &body, belle_sdp_session_description_t **sessionDesc, SalReason *error); + void sdpProcess (); + void handleBodyFromResponse (belle_sip_response_t *response); + SalReason processBodyForInvite (belle_sip_request_t *invite); + SalReason processBodyForAck (belle_sip_request_t *ack); + void handleOfferAnswerResponse (belle_sip_response_t *response); - void fill_invite(belle_sip_request_t* invite); - void cancelling_invite(const SalErrorInfo *info); - int refer_to(belle_sip_header_refer_to_t* refer_to, belle_sip_header_referred_by_t* referred_by); - int send_notify_for_refer(int code, const char *reason); - void notify_last_response(SalCallOp *newcall); - void process_refer(const belle_sip_request_event_t *event, belle_sip_server_transaction_t *server_transaction); - void process_notify(const belle_sip_request_event_t *event, belle_sip_server_transaction_t* server_transaction); + void fillInvite (belle_sip_request_t *invite); + void cancellingInvite (const SalErrorInfo *info); + int referTo (belle_sip_header_refer_to_t *referToHeader, belle_sip_header_referred_by_t *referredByHeader); + int sendNotifyForRefer (int code, const char *reason); + void notifyLastResponse (SalCallOp *newCallOp); + void processRefer (const belle_sip_request_event_t *event, belle_sip_server_transaction_t *serverTransaction); + void processNotify (const belle_sip_request_event_t *event, belle_sip_server_transaction_t *serverTransaction); - static void set_addr_to_0000(char value[], size_t sz); - static int is_media_description_acceptable(SalMediaDescription *md); - static bool_t is_a_pending_invite_incoming_transaction(belle_sip_transaction_t *tr); - static void set_call_as_released(SalCallOp *op); - static void unsupported_method(belle_sip_server_transaction_t* server_transaction,belle_sip_request_t* request); - static belle_sip_header_reason_t *make_reason_header( const SalErrorInfo *info); - static belle_sip_header_allow_t *create_allow(bool_t enable_update); - static std::vector marshal_media_description(belle_sdp_session_description_t *session_desc, belle_sip_error_code &error); + static void setAddrTo0000 (char value[], size_t sz); + static int isMediaDescriptionAcceptable (SalMediaDescription *md); + static bool isAPendingIncomingInviteTransaction (belle_sip_transaction_t *tr); + static void setCallAsReleased (SalCallOp *op); + static void unsupportedMethod (belle_sip_server_transaction_t *serverTransaction, belle_sip_request_t *request); + static belle_sip_header_reason_t *makeReasonHeader (const SalErrorInfo *info); + static belle_sip_header_allow_t *createAllow (bool enableUpdate); + static std::vector marshalMediaDescription (belle_sdp_session_description_t *sessionDesc, belle_sip_error_code &error); // belle_sip_message handlers - static int set_custom_body(belle_sip_message_t *msg, const Content &body); - static int set_sdp(belle_sip_message_t *msg,belle_sdp_session_description_t* session_desc); - static int set_sdp_from_desc(belle_sip_message_t *msg, const SalMediaDescription *desc); - static void process_io_error_cb(void *user_ctx, const belle_sip_io_error_event_t *event); - static Content extract_body(belle_sip_message_t *message); + static int setCustomBody (belle_sip_message_t *message, const Content &body); + static int setSdp (belle_sip_message_t *message, belle_sdp_session_description_t *sessionDesc); + static int setSdpFromDesc (belle_sip_message_t *message, const SalMediaDescription *desc); + static void processIoErrorCb (void *userCtx, const belle_sip_io_error_event_t *event); + static Content extractBody (belle_sip_message_t *message); // Callbacks - static int vfu_retry_cb (void *user_data, unsigned int events); - static void process_response_cb(void *op_base, const belle_sip_response_event_t *event); - static void process_timeout_cb(void *user_ctx, const belle_sip_timeout_event_t *event); - static void process_transaction_terminated_cb(void *user_ctx, const belle_sip_transaction_terminated_event_t *event); - static void process_request_event_cb(void *op_base, const belle_sip_request_event_t *event); - static void process_dialog_terminated_cb(void *ctx, const belle_sip_dialog_terminated_event_t *event); + static int vfuRetryCb (void *userCtx, unsigned int events); + static void processResponseCb (void *userCtx, const belle_sip_response_event_t *event); + static void processTimeoutCb (void *userCtx, const belle_sip_timeout_event_t *event); + static void processTransactionTerminatedCb (void *userCtx, const belle_sip_transaction_terminated_event_t *event); + static void processRequestEventCb (void *userCtx, const belle_sip_request_event_t *event); + static void processDialogTerminatedCb (void *userCtx, const belle_sip_dialog_terminated_event_t *event); // Private constants - static const size_t SIP_MESSAGE_BODY_LIMIT = 16*1024; // 16kB + static const size_t SIP_MESSAGE_BODY_LIMIT = 16 * 1024; // 16kB // Attributes - SalMediaDescription *local_media = NULL; - SalMediaDescription *remote_media = NULL; - Content local_body; - Content remote_body; + SalMediaDescription *mLocalMedia = nullptr; + SalMediaDescription *mRemoteMedia = nullptr; + Content mLocalBody; + Content mRemoteBody; }; LINPHONE_END_NAMESPACE diff --git a/src/sal/event-op.cpp b/src/sal/event-op.cpp index 89cbdb5e7..b7c316264 100644 --- a/src/sal/event-op.cpp +++ b/src/sal/event-op.cpp @@ -23,7 +23,7 @@ using namespace std; LINPHONE_BEGIN_NAMESPACE -void SalSubscribeOp::subscribe_process_io_error_cb(void *user_ctx, const belle_sip_io_error_event_t *event) { +void SalSubscribeOp::subscribeProcessIoErrorCb(void *user_ctx, const belle_sip_io_error_event_t *event) { SalSubscribeOp *op = (SalSubscribeOp *)user_ctx; belle_sip_object_t *src = belle_sip_io_error_event_get_source(event); if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(src, belle_sip_client_transaction_t)){ @@ -32,14 +32,14 @@ void SalSubscribeOp::subscribe_process_io_error_cb(void *user_ctx, const belle_s const char *method=belle_sip_request_get_method(req); if (strcmp(method,"NOTIFY")==0){ - SalErrorInfo *ei=&op->error_info; + SalErrorInfo *ei=&op->mErrorInfo; sal_error_info_set(ei,SalReasonIOError, "SIP", 0,NULL,NULL); - op->root->callbacks.on_notify_response(op); + op->mRoot->mCallbacks.on_notify_response(op); } } } -void SalSubscribeOp::subscribe_response_event_cb(void *op_base, const belle_sip_response_event_t *event){ +void SalSubscribeOp::subscribeResponseEventCb(void *op_base, const belle_sip_response_event_t *event){ SalSubscribeOp *op = (SalSubscribeOp *)op_base; belle_sip_request_t * req; const char *method; @@ -50,12 +50,12 @@ void SalSubscribeOp::subscribe_response_event_cb(void *op_base, const belle_sip_ method = belle_sip_request_get_method(req); if (strcmp(method,"NOTIFY")==0){ - op->set_error_info_from_response(belle_sip_response_event_get_response(event)); - op->root->callbacks.on_notify_response(op); + op->setErrorInfoFromResponse(belle_sip_response_event_get_response(event)); + op->mRoot->mCallbacks.on_notify_response(op); } } -void SalSubscribeOp::subscribe_process_timeout_cb(void *user_ctx, const belle_sip_timeout_event_t *event) { +void SalSubscribeOp::subscribeProcessTimeoutCb(void *user_ctx, const belle_sip_timeout_event_t *event) { SalSubscribeOp *op = (SalSubscribeOp *)user_ctx; belle_sip_request_t * req; const char *method; @@ -66,33 +66,33 @@ void SalSubscribeOp::subscribe_process_timeout_cb(void *user_ctx, const belle_si method = belle_sip_request_get_method(req); if (strcmp(method,"NOTIFY")==0){ - SalErrorInfo *ei=&op->error_info; + SalErrorInfo *ei=&op->mErrorInfo; sal_error_info_set(ei,SalReasonRequestTimeout, "SIP", 0,NULL,NULL); - op->root->callbacks.on_notify_response(op); + op->mRoot->mCallbacks.on_notify_response(op); } } -void SalSubscribeOp::handle_notify(belle_sip_request_t *req, const char *eventname, SalBodyHandler* body_handler){ +void SalSubscribeOp::handleNotify(belle_sip_request_t *req, const char *eventname, SalBodyHandler* body_handler){ SalSubscribeStatus sub_state; belle_sip_header_subscription_state_t* subscription_state_header=belle_sip_message_get_header_by_type(req,belle_sip_header_subscription_state_t); belle_sip_response_t* resp; - belle_sip_server_transaction_t* server_transaction = this->pending_server_trans; + belle_sip_server_transaction_t* server_transaction = mPendingServerTransaction; if (!subscription_state_header || strcasecmp(BELLE_SIP_SUBSCRIPTION_STATE_TERMINATED,belle_sip_header_subscription_state_get_state(subscription_state_header)) ==0) { sub_state=SalSubscribeTerminated; - ms_message("Outgoing subscription terminated by remote [%s]",get_to()); + ms_message("Outgoing subscription terminated by remote [%s]",getTo().c_str()); } else sub_state=SalSubscribeActive; ref(); - this->root->callbacks.notify(this,sub_state,eventname,body_handler); - resp=create_response_from_request(req,200); + mRoot->mCallbacks.notify(this,sub_state,eventname,body_handler); + resp=createResponseFromRequest(req,200); belle_sip_server_transaction_send_response(server_transaction,resp); unref(); } -void SalSubscribeOp::subscribe_process_request_event_cb(void *op_base, const belle_sip_request_event_t *event) { +void SalSubscribeOp::subscribeProcessRequestEventCb(void *op_base, const belle_sip_request_event_t *event) { SalSubscribeOp * op = (SalSubscribeOp *)op_base; - belle_sip_server_transaction_t* server_transaction = belle_sip_provider_create_server_transaction(op->root->prov,belle_sip_request_event_get_request(event)); + belle_sip_server_transaction_t* server_transaction = belle_sip_provider_create_server_transaction(op->mRoot->mProvider,belle_sip_request_event_get_request(event)); belle_sip_request_t* req = belle_sip_request_event_get_request(event); belle_sip_dialog_state_t dialog_state; belle_sip_header_expires_t* expires = belle_sip_message_get_header_by_type(req,belle_sip_header_expires_t); @@ -104,68 +104,68 @@ void SalSubscribeOp::subscribe_process_request_event_cb(void *op_base, const bel belle_sip_dialog_t *dialog = NULL; belle_sip_object_ref(server_transaction); - if (op->pending_server_trans) belle_sip_object_unref(op->pending_server_trans); - op->pending_server_trans=server_transaction; + if (op->mPendingServerTransaction) belle_sip_object_unref(op->mPendingServerTransaction); + op->mPendingServerTransaction=server_transaction; event_header=belle_sip_message_get_header_by_type(req,belle_sip_header_event_t); - body_handler = BELLE_SIP_BODY_HANDLER(op->get_body_handler(BELLE_SIP_MESSAGE(req))); + body_handler = BELLE_SIP_BODY_HANDLER(op->getBodyHandler(BELLE_SIP_MESSAGE(req))); if (event_header==NULL){ ms_warning("No event header in incoming SUBSCRIBE."); - resp=op->create_response_from_request(req,400); + resp=op->createResponseFromRequest(req,400); belle_sip_server_transaction_send_response(server_transaction,resp); - if (!op->dialog) op->release(); + if (!op->mDialog) op->release(); return; } - if (op->event==NULL) { - op->event=event_header; - belle_sip_object_ref(op->event); + if (op->mEvent==NULL) { + op->mEvent=event_header; + belle_sip_object_ref(op->mEvent); } eventname=belle_sip_header_event_get_package_name(event_header); - if (!op->dialog) { + if (!op->mDialog) { if (strcmp(method,"SUBSCRIBE")==0){ - dialog = belle_sip_provider_create_dialog(op->root->prov,BELLE_SIP_TRANSACTION(server_transaction)); + dialog = belle_sip_provider_create_dialog(op->mRoot->mProvider,BELLE_SIP_TRANSACTION(server_transaction)); if (!dialog){ - resp=op->create_response_from_request(req,481); + resp=op->createResponseFromRequest(req,481); belle_sip_server_transaction_send_response(server_transaction,resp); op->release(); return; } - op->set_or_update_dialog(dialog); - ms_message("new incoming subscription from [%s] to [%s]",op->get_from(),op->get_to()); + op->setOrUpdateDialog(dialog); + ms_message("new incoming subscription from [%s] to [%s]",op->getFrom().c_str(),op->getTo().c_str()); }else{ /*this is a NOTIFY*/ - op->handle_notify(req, eventname, (SalBodyHandler *)body_handler); + op->handleNotify(req, eventname, (SalBodyHandler *)body_handler); return; } } - dialog_state=belle_sip_dialog_get_state(op->dialog); + dialog_state=belle_sip_dialog_get_state(op->mDialog); switch(dialog_state) { case BELLE_SIP_DIALOG_NULL: { const char *type = NULL; belle_sip_header_content_type_t *content_type = belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req), belle_sip_header_content_type_t); if (content_type) type = belle_sip_header_content_type_get_type(content_type); - op->root->callbacks.subscribe_received(op, eventname, type ? (SalBodyHandler *)body_handler : NULL); + op->mRoot->mCallbacks.subscribe_received(op, eventname, type ? (SalBodyHandler *)body_handler : NULL); break; } case BELLE_SIP_DIALOG_EARLY: - ms_error("unexpected method [%s] for dialog [%p] in state BELLE_SIP_DIALOG_EARLY ",belle_sip_request_get_method(req),op->dialog); + ms_error("unexpected method [%s] for dialog [%p] in state BELLE_SIP_DIALOG_EARLY ",belle_sip_request_get_method(req),op->mDialog); break; case BELLE_SIP_DIALOG_CONFIRMED: if (strcmp("NOTIFY",method)==0) { - op->handle_notify(req, eventname, (SalBodyHandler *)body_handler); + op->handleNotify(req, eventname, (SalBodyHandler *)body_handler); } else if (strcmp("SUBSCRIBE",method)==0) { /*either a refresh of an unsubscribe*/ if (expires && belle_sip_header_expires_get_expires(expires)>0) { - resp=op->create_response_from_request(req,200); + resp=op->createResponseFromRequest(req,200); belle_sip_server_transaction_send_response(server_transaction,resp); } else if(expires) { - ms_message("Unsubscribe received from [%s]",op->get_from()); - resp=op->create_response_from_request(req,200); + ms_message("Unsubscribe received from [%s]",op->getFrom().c_str()); + resp=op->createResponseFromRequest(req,200); belle_sip_server_transaction_send_response(server_transaction,resp); - op->root->callbacks.incoming_subscribe_closed(op); + op->mRoot->mCallbacks.incoming_subscribe_closed(op); } } break; @@ -175,52 +175,52 @@ void SalSubscribeOp::subscribe_process_request_event_cb(void *op_base, const bel } } -void SalSubscribeOp::subscribe_process_dialog_terminated_cb(void *ctx, const belle_sip_dialog_terminated_event_t *event) { +void SalSubscribeOp::subscribeProcessDialogTerminatedCb(void *ctx, const belle_sip_dialog_terminated_event_t *event) { belle_sip_dialog_t *dialog = belle_sip_dialog_terminated_event_get_dialog(event); SalSubscribeOp * op= (SalSubscribeOp *)ctx; - if (op->dialog) { + if (op->mDialog) { if (belle_sip_dialog_terminated_event_is_expired(event)){ if (!belle_sip_dialog_is_server(dialog)){ /*notify the app that our subscription is dead*/ const char *eventname = NULL; - if (op->event){ - eventname = belle_sip_header_event_get_package_name(op->event); + if (op->mEvent){ + eventname = belle_sip_header_event_get_package_name(op->mEvent); } - op->root->callbacks.notify(op, SalSubscribeTerminated, eventname, NULL); + op->mRoot->mCallbacks.notify(op, SalSubscribeTerminated, eventname, NULL); }else{ - op->root->callbacks.incoming_subscribe_closed(op); + op->mRoot->mCallbacks.incoming_subscribe_closed(op); } } - op->set_or_update_dialog(NULL); + op->setOrUpdateDialog(NULL); } } -void SalSubscribeOp::_release_cb(SalOp *op_base) { +void SalSubscribeOp::releaseCb(SalOp *op_base) { auto *op =reinterpret_cast(op_base); - if(op->refresher) { - belle_sip_refresher_stop(op->refresher); - belle_sip_object_unref(op->refresher); - op->refresher=NULL; - op->set_or_update_dialog(NULL); /*only if we have refresher. else dialog terminated event will remove association*/ + if(op->mRefresher) { + belle_sip_refresher_stop(op->mRefresher); + belle_sip_object_unref(op->mRefresher); + op->mRefresher=NULL; + op->setOrUpdateDialog(NULL); /*only if we have refresher. else dialog terminated event will remove association*/ } } -void SalSubscribeOp::fill_cbs() { +void SalSubscribeOp::fillCallbacks() { static belle_sip_listener_callbacks_t op_subscribe_callbacks={0}; if (op_subscribe_callbacks.process_io_error==NULL){ - op_subscribe_callbacks.process_io_error=subscribe_process_io_error_cb; - op_subscribe_callbacks.process_response_event=subscribe_response_event_cb; - op_subscribe_callbacks.process_timeout=subscribe_process_timeout_cb; - op_subscribe_callbacks.process_transaction_terminated=subscribe_process_transaction_terminated_cb; - op_subscribe_callbacks.process_request_event=subscribe_process_request_event_cb; - op_subscribe_callbacks.process_dialog_terminated=subscribe_process_dialog_terminated_cb; + op_subscribe_callbacks.process_io_error=subscribeProcessIoErrorCb; + op_subscribe_callbacks.process_response_event=subscribeResponseEventCb; + op_subscribe_callbacks.process_timeout=subscribeProcessTimeoutCb; + op_subscribe_callbacks.process_transaction_terminated=subscribeProcessTransactionTerminatedCb; + op_subscribe_callbacks.process_request_event=subscribeProcessRequestEventCb; + op_subscribe_callbacks.process_dialog_terminated=subscribeProcessDialogTerminatedCb; } - this->callbacks=&op_subscribe_callbacks; - this->type=Type::Subscribe; - this->release_cb=_release_cb; + mCallbacks=&op_subscribe_callbacks; + mType=Type::Subscribe; + mReleaseCb=releaseCb; } -void SalSubscribeOp::subscribe_refresher_listener_cb (belle_sip_refresher_t* refresher,void* user_pointer,unsigned int status_code,const char* reason_phrase, int will_retry) { +void SalSubscribeOp::subscribeRefresherListenerCb (belle_sip_refresher_t* refresher,void* user_pointer,unsigned int status_code,const char* reason_phrase, int will_retry) { SalSubscribeOp * op = (SalSubscribeOp *)user_pointer; belle_sip_transaction_t *tr=BELLE_SIP_TRANSACTION(belle_sip_refresher_get_transaction(refresher)); /*belle_sip_response_t* response=belle_sip_transaction_get_response(tr);*/ @@ -230,17 +230,17 @@ void SalSubscribeOp::subscribe_refresher_listener_cb (belle_sip_refresher_t* ref if (status_code>=200 && status_code<300){ if (status_code==200) sss=SalSubscribeActive; else if (status_code==202) sss=SalSubscribePending; - op->set_or_update_dialog(belle_sip_transaction_get_dialog(tr)); - op->root->callbacks.subscribe_response(op,sss, will_retry); + op->setOrUpdateDialog(belle_sip_transaction_get_dialog(tr)); + op->mRoot->mCallbacks.subscribe_response(op,sss, will_retry); } else if (status_code >= 300) { SalReason reason = SalReasonUnknown; if (status_code == 503) { /*refresher returns 503 for IO error*/ reason = SalReasonIOError; } - sal_error_info_set(&op->error_info, reason, "SIP", (int)status_code, reason_phrase, NULL); - op->root->callbacks.subscribe_response(op,sss, will_retry); + sal_error_info_set(&op->mErrorInfo, reason, "SIP", (int)status_code, reason_phrase, NULL); + op->mRoot->mCallbacks.subscribe_response(op,sss, will_retry); }else if (status_code==0){ - op->root->callbacks.on_expire(op); + op->mRoot->mCallbacks.on_expire(op); } } @@ -249,63 +249,63 @@ int SalSubscribeOp::subscribe(const char *from, const char *to, const char *even belle_sip_request_t *req=NULL; if (from) - set_from(from); + setFrom(from); if (to) - set_to(to); + setTo(to); - if (!this->dialog){ - fill_cbs(); - req=build_request("SUBSCRIBE"); + if (!mDialog){ + fillCallbacks(); + req=buildRequest("SUBSCRIBE"); if( req == NULL ) { return -1; } - set_event(eventname); - belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(this->event)); + setEvent(eventname); + belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(mEvent)); belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_expires_create(expires))); belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(req), BELLE_SIP_BODY_HANDLER(body_handler)); - return send_and_create_refresher(req,expires,subscribe_refresher_listener_cb); - }else if (this->refresher){ - const belle_sip_transaction_t *tr=(const belle_sip_transaction_t*) belle_sip_refresher_get_transaction(this->refresher); + return sendRequestAndCreateRefresher(req,expires,subscribeRefresherListenerCb); + }else if (mRefresher){ + const belle_sip_transaction_t *tr=(const belle_sip_transaction_t*) belle_sip_refresher_get_transaction(mRefresher); belle_sip_request_t *last_req=belle_sip_transaction_get_request(tr); /* modify last request to update body*/ belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(last_req), BELLE_SIP_BODY_HANDLER(body_handler)); - return belle_sip_refresher_refresh(this->refresher,expires); + return belle_sip_refresher_refresh(mRefresher,expires); } ms_warning("sal_subscribe(): no dialog and no refresher ?"); return -1; } int SalSubscribeOp::accept() { - belle_sip_request_t* req=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(this->pending_server_trans)); + belle_sip_request_t* req=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(mPendingServerTransaction)); belle_sip_header_expires_t* expires = belle_sip_message_get_header_by_type(req,belle_sip_header_expires_t); - belle_sip_response_t* resp = create_response_from_request(req,200); + belle_sip_response_t* resp = createResponseFromRequest(req,200); belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp),BELLE_SIP_HEADER(expires)); - belle_sip_server_transaction_send_response(this->pending_server_trans,resp); + belle_sip_server_transaction_send_response(mPendingServerTransaction,resp); return 0; } int SalSubscribeOp::decline(SalReason reason) { - belle_sip_response_t* resp = belle_sip_response_create_from_request(belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(this->pending_server_trans)), + belle_sip_response_t* resp = belle_sip_response_create_from_request(belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(mPendingServerTransaction)), to_sip_code(reason)); - belle_sip_server_transaction_send_response(this->pending_server_trans,resp); + belle_sip_server_transaction_send_response(mPendingServerTransaction,resp); return 0; } -int SalSubscribeOp::notify_pending_state() { +int SalSubscribeOp::notifyPendingState() { - if (this->dialog != NULL && this->pending_server_trans) { + if (mDialog != NULL && mPendingServerTransaction) { belle_sip_request_t* notify; belle_sip_header_subscription_state_t* sub_state; ms_message("Sending NOTIFY with subscription state pending for op [%p]", this); - if (!(notify=belle_sip_dialog_create_request(this->dialog,"NOTIFY"))) { + if (!(notify=belle_sip_dialog_create_request(mDialog,"NOTIFY"))) { ms_error("Cannot create NOTIFY on op [%p]", this); return -1; } - if (this->event) belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify),BELLE_SIP_HEADER(this->event)); + if (mEvent) belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify),BELLE_SIP_HEADER(mEvent)); sub_state=belle_sip_header_subscription_state_new(); belle_sip_header_subscription_state_set_state(sub_state,BELLE_SIP_SUBSCRIPTION_STATE_PENDING); belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify), BELLE_SIP_HEADER(sub_state)); - return send_request(notify); + return sendRequest(notify); } else { ms_warning("NOTIFY with subscription state pending for op [%p] not implemented in this case (either dialog pending trans does not exist", this); } @@ -316,101 +316,100 @@ int SalSubscribeOp::notify_pending_state() { int SalSubscribeOp::notify(const SalBodyHandler *body_handler) { belle_sip_request_t* notify; - if (this->dialog){ - if (!(notify=belle_sip_dialog_create_queued_request(this->dialog,"NOTIFY"))) return -1; + if (mDialog){ + if (!(notify=belle_sip_dialog_create_queued_request(mDialog,"NOTIFY"))) return -1; }else{ - fill_cbs(); - notify = build_request("NOTIFY"); + fillCallbacks(); + notify = buildRequest("NOTIFY"); } - if (this->event) belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify),BELLE_SIP_HEADER(this->event)); + if (mEvent) belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify),BELLE_SIP_HEADER(mEvent)); belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify) - , this->dialog ? + , mDialog ? BELLE_SIP_HEADER(belle_sip_header_subscription_state_create(BELLE_SIP_SUBSCRIPTION_STATE_ACTIVE,600)) : BELLE_SIP_HEADER(belle_sip_header_subscription_state_create(BELLE_SIP_SUBSCRIPTION_STATE_TERMINATED,0)) ); belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(notify), BELLE_SIP_BODY_HANDLER(body_handler)); - return send_request(notify); + return sendRequest(notify); } -int SalSubscribeOp::close_notify() { +int SalSubscribeOp::closeNotify() { belle_sip_request_t* notify; - if (!this->dialog) return -1; - if (!(notify=belle_sip_dialog_create_queued_request(this->dialog,"NOTIFY"))) return -1; - if (this->event) belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify),BELLE_SIP_HEADER(this->event)); + if (!mDialog) return -1; + if (!(notify=belle_sip_dialog_create_queued_request(mDialog,"NOTIFY"))) return -1; + if (mEvent) belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify),BELLE_SIP_HEADER(mEvent)); belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify) ,BELLE_SIP_HEADER(belle_sip_header_subscription_state_create(BELLE_SIP_SUBSCRIPTION_STATE_TERMINATED,-1))); - return send_request(notify); + return sendRequest(notify); } -void SalPublishOp::publish_response_event_cb(void *userctx, const belle_sip_response_event_t *event) { +void SalPublishOp::publishResponseEventCb(void *userctx, const belle_sip_response_event_t *event) { SalPublishOp *op=(SalPublishOp *)userctx; - op->set_error_info_from_response(belle_sip_response_event_get_response(event)); - if (op->error_info.protocol_code>=200){ - op->root->callbacks.on_publish_response(op); + op->setErrorInfoFromResponse(belle_sip_response_event_get_response(event)); + if (op->mErrorInfo.protocol_code>=200){ + op->mRoot->mCallbacks.on_publish_response(op); } } -void SalPublishOp::fill_cbs() { +void SalPublishOp::fillCallbacks() { static belle_sip_listener_callbacks_t op_publish_callbacks={0}; if (op_publish_callbacks.process_response_event==NULL){ - op_publish_callbacks.process_response_event=publish_response_event_cb; + op_publish_callbacks.process_response_event=publishResponseEventCb; } - this->callbacks=&op_publish_callbacks; - this->type=Type::Publish; + mCallbacks=&op_publish_callbacks; + mType=Type::Publish; } -void SalPublishOp::publish_refresher_listener_cb (belle_sip_refresher_t* refresher,void* user_pointer,unsigned int status_code,const char* reason_phrase, int will_retry) { +void SalPublishOp::publishRefresherListenerCb (belle_sip_refresher_t* refresher,void* user_pointer,unsigned int status_code,const char* reason_phrase, int will_retry) { SalPublishOp * op = (SalPublishOp *)user_pointer; - const belle_sip_client_transaction_t* last_publish_trans=belle_sip_refresher_get_transaction(op->refresher); + const belle_sip_client_transaction_t* last_publish_trans=belle_sip_refresher_get_transaction(op->mRefresher); belle_sip_response_t *response=belle_sip_transaction_get_response(BELLE_SIP_TRANSACTION(last_publish_trans)); - ms_message("Publish refresher [%i] reason [%s] for proxy [%s]",status_code,reason_phrase?reason_phrase:"none",op->get_proxy()); + ms_message("Publish refresher [%i] reason [%s] for proxy [%s]",status_code,reason_phrase?reason_phrase:"none",op->getProxy().c_str()); if (status_code==0){ - op->root->callbacks.on_expire(op); + op->mRoot->mCallbacks.on_expire(op); }else if (status_code>=200){ belle_sip_header_t *sip_etag; - const char *sip_etag_string = NULL; + string sipEtagStr; if (response && (sip_etag = belle_sip_message_get_header(BELLE_SIP_MESSAGE(response), "SIP-ETag"))) { - sip_etag_string = belle_sip_header_get_unparsed_value(sip_etag); + sipEtagStr = belle_sip_header_get_unparsed_value(sip_etag); } - op->set_entity_tag(sip_etag_string); - sal_error_info_set(&op->error_info,SalReasonUnknown, "SIP", (int)status_code, reason_phrase, NULL); - op->assign_recv_headers((belle_sip_message_t*)response); - op->root->callbacks.on_publish_response(op); + op->setEntityTag(sipEtagStr); + sal_error_info_set(&op->mErrorInfo,SalReasonUnknown, "SIP", (int)status_code, reason_phrase, NULL); + op->assignRecvHeaders((belle_sip_message_t*)response); + op->mRoot->mCallbacks.on_publish_response(op); } } int SalPublishOp::publish(const char *from, const char *to, const char *eventname, int expires, const SalBodyHandler *body_handler) { belle_sip_request_t *req=NULL; - if(!this->refresher || !belle_sip_refresher_get_transaction(this->refresher)) { + if(!mRefresher || !belle_sip_refresher_get_transaction(mRefresher)) { if (from) - set_from(from); + setFrom(from); if (to) - set_to(to); + setTo(to); - fill_cbs(); - req=build_request("PUBLISH"); + fillCallbacks(); + req=buildRequest("PUBLISH"); if( req == NULL ){ return -1; } - - if (get_entity_tag()) { - belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),belle_sip_header_create("SIP-If-Match", get_entity_tag())); - } - - if (get_contact_address()){ - belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(create_contact())); + + if (!mEntityTag.empty()) + belle_sip_message_add_header(BELLE_SIP_MESSAGE(req), belle_sip_header_create("SIP-If-Match", mEntityTag.c_str())); + + if (getContactAddress()){ + belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(createContact())); } belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),belle_sip_header_create("Event",eventname)); belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(req), BELLE_SIP_BODY_HANDLER(body_handler)); if (expires!=-1) - return send_and_create_refresher(req,expires,publish_refresher_listener_cb); - else return send_request(req); + return sendRequestAndCreateRefresher(req,expires,publishRefresherListenerCb); + else return sendRequest(req); } else { /*update status*/ - const belle_sip_client_transaction_t* last_publish_trans=belle_sip_refresher_get_transaction(this->refresher); + const belle_sip_client_transaction_t* last_publish_trans=belle_sip_refresher_get_transaction(mRefresher); belle_sip_request_t* last_publish=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(last_publish_trans)); /*update body*/ if (expires == 0) { @@ -418,16 +417,16 @@ int SalPublishOp::publish(const char *from, const char *to, const char *eventnam } else { belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(last_publish), BELLE_SIP_BODY_HANDLER(body_handler)); } - return belle_sip_refresher_refresh(this->refresher,expires==-1 ? BELLE_SIP_REFRESHER_REUSE_EXPIRES : expires); + return belle_sip_refresher_refresh(mRefresher,expires==-1 ? BELLE_SIP_REFRESHER_REUSE_EXPIRES : expires); } } int SalPublishOp::unpublish() { - if (this->refresher){ - const belle_sip_transaction_t *tr=(const belle_sip_transaction_t*) belle_sip_refresher_get_transaction(this->refresher); + if (mRefresher){ + const belle_sip_transaction_t *tr=(const belle_sip_transaction_t*) belle_sip_refresher_get_transaction(mRefresher); belle_sip_request_t *last_req=belle_sip_transaction_get_request(tr); belle_sip_message_set_body(BELLE_SIP_MESSAGE(last_req), NULL, 0); - belle_sip_refresher_refresh(this->refresher,0); + belle_sip_refresher_refresh(mRefresher,0); return 0; } return -1; diff --git a/src/sal/event-op.h b/src/sal/event-op.h index 585adbbab..4b4f3b7f0 100644 --- a/src/sal/event-op.h +++ b/src/sal/event-op.h @@ -24,49 +24,49 @@ LINPHONE_BEGIN_NAMESPACE -class SalEventOp: public SalOp { +class SalEventOp : public SalOp { public: - SalEventOp(Sal *sal): SalOp(sal) {} + SalEventOp (Sal *sal) : SalOp(sal) {} }; class SalSubscribeOp: public SalEventOp { public: - SalSubscribeOp(Sal *sal): SalEventOp(sal) {} + SalSubscribeOp (Sal *sal): SalEventOp(sal) {} - int subscribe(const char *from, const char *to, const char *eventname, int expires, const SalBodyHandler *body_handler); - int unsubscribe() {return SalOp::unsubscribe();} - int accept(); - int decline(SalReason reason); - int notify_pending_state(); - int notify(const SalBodyHandler *body_handler); - int close_notify(); + int subscribe (const char *from, const char *to, const char *eventName, int expires, const SalBodyHandler *bodyHandler); + int unsubscribe () { return SalOp::unsubscribe(); } + int accept (); + int decline (SalReason reason); + int notifyPendingState (); + int notify (const SalBodyHandler *bodyHandler); + int closeNotify (); private: - virtual void fill_cbs() override; - void handle_notify(belle_sip_request_t *req, const char *eventname, SalBodyHandler* body_handler); + virtual void fillCallbacks () override; + void handleNotify (belle_sip_request_t *request, const char *eventName, SalBodyHandler *bodyHandler); - static void subscribe_process_io_error_cb(void *user_ctx, const belle_sip_io_error_event_t *event); - static void subscribe_response_event_cb(void *op_base, const belle_sip_response_event_t *event); - static void subscribe_process_timeout_cb(void *user_ctx, const belle_sip_timeout_event_t *event); - static void subscribe_process_transaction_terminated_cb(void *user_ctx, const belle_sip_transaction_terminated_event_t *event) {} - static void subscribe_process_request_event_cb(void *op_base, const belle_sip_request_event_t *event); - static void subscribe_process_dialog_terminated_cb(void *ctx, const belle_sip_dialog_terminated_event_t *event); - static void _release_cb(SalOp *op_base); - static void subscribe_refresher_listener_cb (belle_sip_refresher_t* refresher,void* user_pointer,unsigned int status_code,const char* reason_phrase, int will_retry); + static void subscribeProcessIoErrorCb (void *userCtx, const belle_sip_io_error_event_t *event); + static void subscribeResponseEventCb (void *userCtx, const belle_sip_response_event_t *event); + static void subscribeProcessTimeoutCb (void *userCtx, const belle_sip_timeout_event_t *event); + static void subscribeProcessTransactionTerminatedCb (void *userCtx, const belle_sip_transaction_terminated_event_t *event) {} + static void subscribeProcessRequestEventCb (void *userCtx, const belle_sip_request_event_t *event); + static void subscribeProcessDialogTerminatedCb (void *userCtx, const belle_sip_dialog_terminated_event_t *event); + static void releaseCb (SalOp *op); + static void subscribeRefresherListenerCb (belle_sip_refresher_t *refresher, void *userCtx, unsigned int statusCode, const char *reasonPhrase, int willRetry); }; -class SalPublishOp: public SalEventOp { +class SalPublishOp : public SalEventOp { public: - SalPublishOp(Sal *sal): SalEventOp(sal) {} + SalPublishOp (Sal *sal) : SalEventOp(sal) {} - int publish(const char *from, const char *to, const char *eventname, int expires, const SalBodyHandler *body_handler); - int unpublish(); + int publish (const char *from, const char *to, const char *eventName, int expires, const SalBodyHandler *bodyHandler); + int unpublish (); private: - virtual void fill_cbs() override; + virtual void fillCallbacks () override; - static void publish_response_event_cb(void *userctx, const belle_sip_response_event_t *event); - static void publish_refresher_listener_cb (belle_sip_refresher_t* refresher,void* user_pointer,unsigned int status_code,const char* reason_phrase, int will_retry); + static void publishResponseEventCb (void *userCtx, const belle_sip_response_event_t *event); + static void publishRefresherListenerCb (belle_sip_refresher_t *refresher, void *userCtx, unsigned int statusCode, const char *reasonPhrase, int willRetry); }; LINPHONE_END_NAMESPACE diff --git a/src/sal/message-op-interface.h b/src/sal/message-op-interface.h index acc5ea49c..79ee4debd 100644 --- a/src/sal/message-op-interface.h +++ b/src/sal/message-op-interface.h @@ -20,17 +20,55 @@ #ifndef _L_SAL_MESSAGE_OP_INTERFACE_H_ #define _L_SAL_MESSAGE_OP_INTERFACE_H_ +#include + +#include "content/content.h" +#include "content/content-type.h" + LINPHONE_BEGIN_NAMESPACE class SalMessageOpInterface { public: virtual ~SalMessageOpInterface() = default; - virtual int send_message(const char* content_type, const char *msg) = 0; - virtual int reply(SalReason reason) = 0; + virtual int sendMessage (const Content &content) = 0; + virtual int reply (SalReason reason) = 0; protected: - void prepare_message_request(belle_sip_request_t *req, const char* content_type, const char *msg); + void prepareMessageRequest (belle_sip_request_t *req, const Content &content) { + time_t curtime = std::time(nullptr); + belle_sip_message_add_header( + BELLE_SIP_MESSAGE(req), + BELLE_SIP_HEADER(belle_sip_header_date_create_from_time(&curtime)) + ); + std::string contentEncoding = content.getContentEncoding(); + if (!contentEncoding.empty()) + belle_sip_message_add_header( + BELLE_SIP_MESSAGE(req), + belle_sip_header_create("Content-Encoding", contentEncoding.c_str()) + ); + const ContentType &contentType = content.getContentType(); + std::string contentTypeStr = std::string(BELLE_SIP_CONTENT_TYPE ": ") + contentType.asString(); + belle_sip_message_add_header( + BELLE_SIP_MESSAGE(req), + BELLE_SIP_HEADER(belle_sip_header_content_type_parse(contentTypeStr.c_str())) + ); + if (content.isEmpty()) { + belle_sip_message_add_header( + BELLE_SIP_MESSAGE(req), + BELLE_SIP_HEADER(belle_sip_header_content_length_create(0)) + ); + } else { + std::string body = content.getBodyAsUtf8String(); + size_t contentLength = body.size(); + belle_sip_message_add_header( + BELLE_SIP_MESSAGE(req), + BELLE_SIP_HEADER(belle_sip_header_content_length_create(contentLength)) + ); + belle_sip_message_set_body(BELLE_SIP_MESSAGE(req), body.c_str(), contentLength); + } + } + }; LINPHONE_END_NAMESPACE diff --git a/src/sal/message-op.cpp b/src/sal/message-op.cpp index 090f5f50e..c7d882b39 100644 --- a/src/sal/message-op.cpp +++ b/src/sal/message-op.cpp @@ -23,26 +23,26 @@ using namespace std; LINPHONE_BEGIN_NAMESPACE -void SalMessageOp::process_error() { - if (this->dir == Dir::Outgoing) { - this->root->callbacks.message_delivery_update(this, SalMessageDeliveryFailed); +void SalMessageOp::processError() { + if (mDir == Dir::Outgoing) { + mRoot->mCallbacks.message_delivery_update(this, SalMessageDeliveryFailed); } else { ms_warning("unexpected io error for incoming message on op [%p]", this); } - this->state=State::Terminated; + mState=State::Terminated; } -void SalMessageOp::process_io_error_cb(void *user_ctx, const belle_sip_io_error_event_t *event) { +void SalMessageOp::processIoErrorCb(void *user_ctx, const belle_sip_io_error_event_t *event) { SalMessageOp * op = (SalMessageOp *)user_ctx; - sal_error_info_set(&op->error_info,SalReasonIOError, "SIP", 503,"IO Error",NULL); - op->process_error(); + sal_error_info_set(&op->mErrorInfo,SalReasonIOError, "SIP", 503,"IO Error",NULL); + op->processError(); } -void SalMessageOp::process_response_event_cb(void *op_base, const belle_sip_response_event_t *event) { +void SalMessageOp::processResponseEventCb(void *op_base, const belle_sip_response_event_t *event) { SalMessageOp * op = (SalMessageOp *)op_base; int code = belle_sip_response_get_status_code(belle_sip_response_event_get_response(event)); SalMessageDeliveryStatus status; - op->set_error_info_from_response(belle_sip_response_event_get_response(event)); + op->setErrorInfoFromResponse(belle_sip_response_event_get_response(event)); if (code>=100 && code <200) status=SalMessageDeliveryInProgress; @@ -51,54 +51,40 @@ void SalMessageOp::process_response_event_cb(void *op_base, const belle_sip_resp else status=SalMessageDeliveryFailed; - op->root->callbacks.message_delivery_update(op,status); + op->mRoot->mCallbacks.message_delivery_update(op,status); } -void SalMessageOp::process_timeout_cb(void *user_ctx, const belle_sip_timeout_event_t *event) { +void SalMessageOp::processTimeoutCb(void *user_ctx, const belle_sip_timeout_event_t *event) { SalMessageOp * op=(SalMessageOp *)user_ctx; - sal_error_info_set(&op->error_info,SalReasonRequestTimeout, "SIP", 408,"Request timeout",NULL); - op->process_error(); + sal_error_info_set(&op->mErrorInfo,SalReasonRequestTimeout, "SIP", 408,"Request timeout",NULL); + op->processError(); } -void SalMessageOp::process_request_event_cb(void *op_base, const belle_sip_request_event_t *event) { +void SalMessageOp::processRequestEventCb(void *op_base, const belle_sip_request_event_t *event) { SalMessageOp * op = (SalMessageOp *)op_base; - op->process_incoming_message(event); + op->processIncomingMessage(event); } -void SalMessageOp::fill_cbs() { +void SalMessageOp::fillCallbacks() { static belle_sip_listener_callbacks_t op_message_callbacks = {0}; if (op_message_callbacks.process_io_error==NULL) { - op_message_callbacks.process_io_error=process_io_error_cb; - op_message_callbacks.process_response_event=process_response_event_cb; - op_message_callbacks.process_timeout=process_timeout_cb; - op_message_callbacks.process_request_event=process_request_event_cb; + op_message_callbacks.process_io_error=processIoErrorCb; + op_message_callbacks.process_response_event=processResponseEventCb; + op_message_callbacks.process_timeout=processTimeoutCb; + op_message_callbacks.process_request_event=processRequestEventCb; } - this->callbacks=&op_message_callbacks; - this->type=Type::Message; + mCallbacks=&op_message_callbacks; + mType=Type::Message; } -void SalMessageOpInterface::prepare_message_request(belle_sip_request_t *req, const char* content_type, const char *msg) { - char content_type_raw[256]; - size_t content_length = msg?strlen(msg):0; - time_t curtime = ms_time(NULL); - snprintf(content_type_raw,sizeof(content_type_raw),BELLE_SIP_CONTENT_TYPE ": %s",content_type); - belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_content_type_parse(content_type_raw))); - belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_content_length_create(content_length))); - belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_date_create_from_time(&curtime))); - if (msg){ - /*don't call set_body() with null argument because it resets content type and content length*/ - belle_sip_message_set_body(BELLE_SIP_MESSAGE(req), msg, content_length); - } -} - -int SalMessageOp::send_message(const char* content_type, const char *msg) { - fill_cbs(); - this->dir = Dir::Outgoing; - belle_sip_request_t *req = build_request("MESSAGE"); +int SalMessageOp::sendMessage (const Content &content) { + fillCallbacks(); + mDir = Dir::Outgoing; + belle_sip_request_t *req = buildRequest("MESSAGE"); if (!req) return -1; - prepare_message_request(req, content_type, msg); - return send_request(req); + prepareMessageRequest(req, content); + return sendRequest(req); } LINPHONE_END_NAMESPACE diff --git a/src/sal/message-op.h b/src/sal/message-op.h index 9c1527ba8..73cd9efae 100644 --- a/src/sal/message-op.h +++ b/src/sal/message-op.h @@ -25,21 +25,21 @@ LINPHONE_BEGIN_NAMESPACE -class SalMessageOp: public SalOp, public SalMessageOpInterface { +class SalMessageOp : public SalOp, public SalMessageOpInterface { public: - SalMessageOp(Sal *sal): SalOp(sal) {} + SalMessageOp (Sal *sal) : SalOp(sal) {} - int send_message(const char* content_type, const char *msg) override; - int reply(SalReason reason) override {return SalOp::reply_message(reason);} + int sendMessage (const Content &content) override; + int reply (SalReason reason) override { return SalOp::replyMessage(reason); } private: - virtual void fill_cbs() override; - void process_error(); + virtual void fillCallbacks () override; + void processError (); - static void process_io_error_cb(void *user_ctx, const belle_sip_io_error_event_t *event); - static void process_response_event_cb(void *op_base, const belle_sip_response_event_t *event); - static void process_timeout_cb(void *user_ctx, const belle_sip_timeout_event_t *event); - static void process_request_event_cb(void *op_base, const belle_sip_request_event_t *event); + static void processIoErrorCb (void *userCtx, const belle_sip_io_error_event_t *event); + static void processResponseEventCb (void *userCtx, const belle_sip_response_event_t *event); + static void processTimeoutCb (void *userCtx, const belle_sip_timeout_event_t *event); + static void processRequestEventCb (void *userCtx, const belle_sip_request_event_t *event); }; LINPHONE_END_NAMESPACE diff --git a/src/sal/op.cpp b/src/sal/op.cpp index e5e211f3b..219ffb568 100644 --- a/src/sal/op.cpp +++ b/src/sal/op.cpp @@ -19,6 +19,7 @@ #include +#include "c-wrapper/internal/c-tools.h" #include "sal/op.h" #include "bellesip_sal/sal_impl.h" @@ -27,282 +28,222 @@ using namespace std; LINPHONE_BEGIN_NAMESPACE SalOp::SalOp(Sal *sal) { - this->root = sal; - this->sdp_handling = sal->default_sdp_handling; - memset(&this->error_info, 0, sizeof(this->error_info)); - memset(&this->reason_error_info, 0, sizeof(this->reason_error_info)); + mRoot = sal; + mSdpHandling = sal->mDefaultSdpHandling; + memset(&mErrorInfo, 0, sizeof(mErrorInfo)); + memset(&mReasonErrorInfo, 0, sizeof(mReasonErrorInfo)); ref(); } SalOp::~SalOp() { - ms_message("Destroying op [%p] of type [%s]",this,to_string(this->type)); + lInfo() << "Destroying op [" << this << "] of type [" << toString(mType) << "]"; - if (this->pending_auth_transaction) belle_sip_object_unref(this->pending_auth_transaction); - this->root->remove_pending_auth(this); - if (this->auth_info) { - sal_auth_info_delete(this->auth_info); + if (mPendingAuthTransaction) belle_sip_object_unref(mPendingAuthTransaction); + mRoot->removePendingAuth(this); + if (mAuthInfo) { + sal_auth_info_delete(mAuthInfo); } - if (this->sdp_answer) belle_sip_object_unref(this->sdp_answer); - if (this->refresher) { - belle_sip_object_unref(this->refresher); - this->refresher=NULL; + if (mSdpAnswer) belle_sip_object_unref(mSdpAnswer); + if (mRefresher) { + belle_sip_object_unref(mRefresher); + mRefresher=NULL; } - if (this->result) - sal_media_description_unref(this->result); - if(this->replaces) belle_sip_object_unref(this->replaces); - if(this->referred_by) belle_sip_object_unref(this->referred_by); + if (mResult) + sal_media_description_unref(mResult); + if(mReplaces) belle_sip_object_unref(mReplaces); + if(mReferredBy) belle_sip_object_unref(mReferredBy); - if (this->pending_client_trans) belle_sip_object_unref(this->pending_client_trans); - if (this->pending_server_trans) belle_sip_object_unref(this->pending_server_trans); - if (this->pending_update_server_trans) belle_sip_object_unref(this->pending_update_server_trans); - if (this->event) belle_sip_object_unref(this->event); + if (mPendingClientTransaction) belle_sip_object_unref(mPendingClientTransaction); + if (mPendingServerTransaction) belle_sip_object_unref(mPendingServerTransaction); + if (mPendingUpdateServerTransaction) belle_sip_object_unref(mPendingUpdateServerTransaction); + if (mEvent) belle_sip_object_unref(mEvent); - sal_error_info_reset(&this->error_info); - if (this->from_address){ - sal_address_destroy(this->from_address); - this->from_address=NULL; + sal_error_info_reset(&mErrorInfo); + if (mFromAddress){ + sal_address_destroy(mFromAddress); + mFromAddress=NULL; } - if (this->to_address){ - sal_address_destroy(this->to_address); - this->to_address=NULL; + if (mToAddress){ + sal_address_destroy(mToAddress); + mToAddress=NULL; } - if (this->service_route){ - sal_address_destroy(this->service_route); - this->service_route=NULL; + if (mServiceRoute){ + sal_address_destroy(mServiceRoute); + mServiceRoute=NULL; } - if (this->origin_address){ - sal_address_destroy(this->origin_address); - this->origin_address=NULL; + if (mOriginAddress){ + sal_address_destroy(mOriginAddress); + mOriginAddress=NULL; } - if (this->from) { - ms_free(this->from); - this->from=NULL; + if (mContactAddress) { + sal_address_destroy(mContactAddress); } - if (this->to) { - ms_free(this->to); - this->to=NULL; + if (mRemoteContactAddress){ + sal_address_destroy(mRemoteContactAddress); } - if (this->subject) { - ms_free(this->subject); - this->subject = NULL; - } - if (this->route) { - ms_free(this->route); - this->route=NULL; - } - if (this->realm) { - ms_free(this->realm); - this->realm=NULL; - } - if (this->contact_address) { - sal_address_destroy(this->contact_address); - } - if (this->origin){ - ms_free(this->origin); - this->origin=NULL; - } - if (this->remote_ua){ - ms_free(this->remote_ua); - this->remote_ua=NULL; - } - if (this->remote_contact){ - ms_free(this->remote_contact); - this->remote_contact=NULL; - } - if (this->remote_contact_address){ - sal_address_destroy(this->remote_contact_address); - } - if (this->call_id) - ms_free(this->call_id); - if (this->service_route) { - sal_address_destroy(this->service_route); - } - if (this->route_addresses){ - bctbx_list_for_each(this->route_addresses,(void (*)(void*)) sal_address_destroy); - this->route_addresses=bctbx_list_free(this->route_addresses); - } - if (this->recv_custom_headers) - sal_custom_header_free(this->recv_custom_headers); - if (this->sent_custom_headers) - sal_custom_header_free(this->sent_custom_headers); - - if (this->entity_tag != NULL){ - ms_free(this->entity_tag); - this->entity_tag = NULL; + if (mServiceRoute) { + sal_address_destroy(mServiceRoute); } + for (auto &addr : mRouteAddresses) + sal_address_unref(addr); + if (mRecvCustomHeaders) + sal_custom_header_free(mRecvCustomHeaders); + if (mSentCustomHeaders) + sal_custom_header_free(mSentCustomHeaders); } SalOp *SalOp::ref() { - _ref++; + mRef++; return this; } void *SalOp::unref() { - _ref--; - if (_ref==0) { + mRef--; + if (mRef==0) { delete this; - } else if (_ref<0) { + } else if (mRef<0) { ms_fatal("SalOp [%p]: too many unrefs.",this); } return NULL; } -void SalOp::set_contact_address(const SalAddress *address) { - if (this->contact_address) sal_address_destroy(this->contact_address); - this->contact_address=address?sal_address_clone(address):NULL; +void SalOp::setContactAddress(const SalAddress *address) { + if (mContactAddress) sal_address_destroy(mContactAddress); + mContactAddress=address?sal_address_clone(address):NULL; } -void SalOp::assign_address(SalAddress** address, const char *value) { - if (*address){ +void SalOp::assignAddress (SalAddress **address, const string &value) { + if (*address) { sal_address_destroy(*address); - *address=NULL; + *address = nullptr; } - if (value) - *address=sal_address_new(value); + if (!value.empty()) + *address = sal_address_new(value.c_str()); } -void SalOp::assign_string(char **str, const char *arg) { - if (*str){ - ms_free(*str); - *str=NULL; - } - if (arg) - *str=ms_strdup(arg); -} - -void SalOp::set_route(const char *route) { - char* route_string=NULL; - if (this->route_addresses) { - bctbx_list_for_each(this->route_addresses,(void (*)(void *))sal_address_destroy); - this->route_addresses=bctbx_list_free(this->route_addresses); - } - if (route) { - this->route_addresses=bctbx_list_append(NULL,NULL); - assign_address((SalAddress**)&(this->route_addresses->data),route); - route_string=sal_address_as_string((SalAddress*)this->route_addresses->data); - } - assign_string(&this->route,route_string); - if(route_string) ms_free(route_string); -} - -void SalOp::set_route_address(const SalAddress *address){ - char* address_string=sal_address_as_string(address); /*can probably be optimized*/ - set_route(address_string); - ms_free(address_string); -} - -void SalOp::add_route_address(const SalAddress *address) { - if (this->route_addresses) { - this->route_addresses=bctbx_list_append(this->route_addresses,(void*)sal_address_clone(address)); +void SalOp::setRoute (const string &value) { + for (auto &address : mRouteAddresses) + sal_address_unref(address); + mRouteAddresses.clear(); + if (value.empty()) { + mRoute.clear(); } else { - set_route_address(address); + auto address = sal_address_new(value.c_str()); + mRouteAddresses.push_back(address); + char *routeStr = sal_address_as_string(address); + mRoute = routeStr; + ms_free(routeStr); } } -void SalOp::set_realm(const char *realm) { - if (this->realm != NULL){ - ms_free(this->realm); +void SalOp::setRouteAddress(const SalAddress *address){ + char* address_string=sal_address_as_string(address); /*can probably be optimized*/ + setRoute(address_string); + ms_free(address_string); +} + +void SalOp::addRouteAddress (const SalAddress *address) { + if (mRouteAddresses.empty()) + setRouteAddress(address); + else + mRouteAddresses.push_back(sal_address_clone(address)); +} + +void SalOp::setFrom (const string &value) { + assignAddress(&mFromAddress, value); + if (mFromAddress) { + char *valueStr = sal_address_as_string(mFromAddress); + mFrom = valueStr; + ms_free(valueStr); + } else { + mFrom.clear(); } - this->realm = ms_strdup(realm); } -#define SET_PARAM(name) \ - char* name##_string=NULL; \ - assign_address(&this->name##_address,name); \ - if (this->name##_address) { \ - name##_string=sal_address_as_string(this->name##_address); \ - }\ - assign_string(&this->name,name##_string); \ - if(name##_string) ms_free(name##_string); - -void SalOp::set_subject (const char *subject) { - assign_string(&this->subject, subject); -} - -void SalOp::set_from(const char *from){ - SET_PARAM(from); -} - -void SalOp::set_from_address(const SalAddress *from) { +void SalOp::setFromAddress(const SalAddress *from) { char* address_string=sal_address_as_string(from); /*can probably be optimized*/ - set_from(address_string); + setFrom(address_string); ms_free(address_string); } -void SalOp::set_to(const char *to) { - SET_PARAM(to); +void SalOp::setTo (const string &value) { + assignAddress(&mToAddress, value); + if (mToAddress) { + char *valueStr = sal_address_as_string(mToAddress); + mTo = valueStr; + ms_free(valueStr); + } else { + mTo.clear(); + } } -void SalOp::set_to_address(const SalAddress *to) { +void SalOp::setToAddress(const SalAddress *to) { char* address_string=sal_address_as_string(to); /*can probably be optimized*/ - set_to(address_string); + setTo(address_string); ms_free(address_string); } -void SalOp::set_diversion_address(const SalAddress *diversion) { - if (this->diversion_address) sal_address_destroy(this->diversion_address); - this->diversion_address=diversion ? sal_address_clone(diversion) : NULL; +void SalOp::setDiversionAddress(const SalAddress *diversion) { + if (mDiversionAddress) sal_address_destroy(mDiversionAddress); + mDiversionAddress=diversion ? sal_address_clone(diversion) : NULL; } int SalOp::refresh() { - if (this->refresher) { - belle_sip_refresher_refresh(this->refresher,belle_sip_refresher_get_expires(this->refresher)); + if (mRefresher) { + belle_sip_refresher_refresh(mRefresher,belle_sip_refresher_get_expires(mRefresher)); return 0; } - ms_warning("sal_refresh on op [%p] of type [%s] no refresher",this,to_string(this->type)); + lWarning() << "No refresher on op [" << this << "] of type [" << toString(mType) << "]"; return -1; } -void SalOp::kill_dialog() { - ms_warning("op [%p]: force kill of dialog [%p]", this, this->dialog); - belle_sip_dialog_delete(this->dialog); +void SalOp::killDialog() { + ms_warning("op [%p]: force kill of dialog [%p]", this, mDialog); + belle_sip_dialog_delete(mDialog); } void SalOp::release() { /*if in terminating state, keep this state because it means we are waiting for a response to be able to terminate the operation.*/ - if (this->state!=State::Terminating) - this->state=State::Terminated; - set_user_pointer(NULL);/*mandatory because releasing op doesn't not mean freeing op. Make sure back pointer will not be used later*/ - if (this->release_cb) - this->release_cb(this); - if (this->refresher) { - belle_sip_refresher_stop(this->refresher); + if (mState!=State::Terminating) + mState=State::Terminated; + setUserPointer(NULL);/*mandatory because releasing op doesn't not mean freeing op. Make sure back pointer will not be used later*/ + if (mReleaseCb) + mReleaseCb(this); + if (mRefresher) { + belle_sip_refresher_stop(mRefresher); } - this->op_released = TRUE; + mOpReleased = TRUE; unref(); } -int SalOp::send_request_with_contact(belle_sip_request_t* request, bool_t add_contact) { +int SalOp::sendRequestWithContact(belle_sip_request_t* request, bool add_contact) { belle_sip_client_transaction_t* client_transaction; - belle_sip_provider_t* prov=this->root->prov; - belle_sip_uri_t* outbound_proxy=NULL; + belle_sip_provider_t* prov=mRoot->mProvider; belle_sip_header_contact_t* contact; int result =-1; belle_sip_uri_t *next_hop_uri=NULL; if (add_contact && !belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(request),belle_sip_header_contact_t)) { - contact = create_contact(); + contact = createContact(); belle_sip_message_set_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_HEADER(contact)); } /*keep existing*/ - add_custom_headers((belle_sip_message_t*)request); + addCustomHeaders((belle_sip_message_t*)request); - if (!this->dialog || belle_sip_dialog_get_state(this->dialog) == BELLE_SIP_DIALOG_NULL) { + if (!mDialog || belle_sip_dialog_get_state(mDialog) == BELLE_SIP_DIALOG_NULL) { /*don't put route header if dialog is in confirmed state*/ - const MSList *elem=get_route_addresses(); + auto routeAddresses = getRouteAddresses(); const char *transport; const char *method=belle_sip_request_get_method(request); belle_sip_listening_point_t *udplp=belle_sip_provider_get_listening_point(prov,"UDP"); - if (elem) { - outbound_proxy=belle_sip_header_address_get_uri((belle_sip_header_address_t*)elem->data); - next_hop_uri=outbound_proxy; - }else{ - next_hop_uri=(belle_sip_uri_t*)belle_sip_object_clone((belle_sip_object_t*)belle_sip_request_get_uri(request)); - } + if (routeAddresses.empty()) + next_hop_uri = (belle_sip_uri_t*)belle_sip_object_clone((belle_sip_object_t*)belle_sip_request_get_uri(request)); + else + next_hop_uri = belle_sip_header_address_get_uri((belle_sip_header_address_t*)routeAddresses.front()); transport=belle_sip_uri_get_transport_param(next_hop_uri); if (transport==NULL){ /*compatibility mode: by default it should be udp as not explicitely set and if no udp listening point is available, then use @@ -341,32 +282,33 @@ int SalOp::send_request_with_contact(belle_sip_request_t* request, bool_t add_co client_transaction = belle_sip_provider_create_client_transaction(prov,request); belle_sip_transaction_set_application_data(BELLE_SIP_TRANSACTION(client_transaction),ref()); - if (this->pending_client_trans) belle_sip_object_unref(this->pending_client_trans); + if (mPendingClientTransaction) belle_sip_object_unref(mPendingClientTransaction); - this->pending_client_trans=client_transaction; /*update pending inv for being able to cancel*/ - belle_sip_object_ref(this->pending_client_trans); + mPendingClientTransaction=client_transaction; /*update pending inv for being able to cancel*/ + belle_sip_object_ref(mPendingClientTransaction); if (belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(request),belle_sip_header_user_agent_t)==NULL) - belle_sip_message_add_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_HEADER(this->root->user_agent)); + belle_sip_message_add_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_HEADER(mRoot->mUserAgentHeader)); if (!belle_sip_message_get_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_AUTHORIZATION) && !belle_sip_message_get_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_PROXY_AUTHORIZATION)) { /*hmm just in case we already have authentication param in cache*/ - belle_sip_provider_add_authorization(this->root->prov,request,NULL,NULL,NULL,this->realm); + belle_sip_provider_add_authorization(mRoot->mProvider,request,NULL,NULL,NULL,L_STRING_TO_C(mRealm)); } result = belle_sip_client_transaction_send_request_to(client_transaction,next_hop_uri/*might be null*/); /*update call id if not set yet for this OP*/ - if (result == 0 && !this->call_id) { - this->call_id=ms_strdup(belle_sip_header_call_id_get_call_id(BELLE_SIP_HEADER_CALL_ID(belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(request), belle_sip_header_call_id_t)))); + if (result == 0 && mCallId.empty()) { + mCallId = belle_sip_header_call_id_get_call_id( + BELLE_SIP_HEADER_CALL_ID(belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(request), belle_sip_header_call_id_t))); } return result; } -int SalOp::send_request(belle_sip_request_t* request) { - bool_t need_contact=FALSE; +int SalOp::sendRequest(belle_sip_request_t* request) { + bool need_contact=FALSE; if (request==NULL) { return -1; /*sanity check*/ } @@ -380,20 +322,20 @@ int SalOp::send_request(belle_sip_request_t* request) { ||strcmp(belle_sip_request_get_method(request),"SUBSCRIBE")==0 ||strcmp(belle_sip_request_get_method(request),"OPTIONS")==0 ||strcmp(belle_sip_request_get_method(request),"REFER")==0) /* Despite contact seems not mandatory, call flow example show a Contact in REFER requests*/ - need_contact=TRUE; + need_contact=true; - return send_request_with_contact(request,need_contact); + return sendRequestWithContact(request,need_contact); } -void SalOp::resend_request(belle_sip_request_t* request) { +void SalOp::resendRequest(belle_sip_request_t* request) { belle_sip_header_cseq_t* cseq=(belle_sip_header_cseq_t*)belle_sip_message_get_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_CSEQ); belle_sip_header_cseq_set_seq_number(cseq,belle_sip_header_cseq_get_seq_number(cseq)+1); - send_request(request); + sendRequest(request); } -int SalOp::process_redirect(){ - belle_sip_request_t* request = belle_sip_transaction_get_request((belle_sip_transaction_t*)this->pending_client_trans); - belle_sip_response_t *response = belle_sip_transaction_get_response((belle_sip_transaction_t*)this->pending_client_trans); +int SalOp::processRedirect(){ + belle_sip_request_t* request = belle_sip_transaction_get_request((belle_sip_transaction_t*)mPendingClientTransaction); + belle_sip_response_t *response = belle_sip_transaction_get_response((belle_sip_transaction_t*)mPendingClientTransaction); belle_sip_header_contact_t *redirect_contact = belle_sip_message_get_header_by_type((belle_sip_message_t*)response, belle_sip_header_contact_t); belle_sip_uri_t *redirect_uri; belle_sip_header_call_id_t *callid = belle_sip_message_get_header_by_type((belle_sip_message_t*)request, belle_sip_header_call_id_t); @@ -411,47 +353,43 @@ int SalOp::process_redirect(){ return -1; } - if (this->dialog && belle_sip_dialog_get_state(this->dialog)==BELLE_SIP_DIALOG_CONFIRMED){ + if (mDialog && belle_sip_dialog_get_state(mDialog)==BELLE_SIP_DIALOG_CONFIRMED){ ms_warning("Redirect not handled within established dialogs. Does it make sense ?"); return -1; } - set_or_update_dialog(NULL); + setOrUpdateDialog(NULL); belle_sip_message_remove_header_from_ptr((belle_sip_message_t*)request, (belle_sip_header_t*)callid); - belle_sip_message_add_header((belle_sip_message_t*)request, (belle_sip_header_t*)(callid = belle_sip_provider_create_call_id(this->get_sal()->prov))); - if (this->call_id){ - /*reset the call-id of op, it will be set when new request will be sent*/ - ms_free(this->call_id); - this->call_id = NULL; - } + belle_sip_message_add_header((belle_sip_message_t*)request, (belle_sip_header_t*)(callid = belle_sip_provider_create_call_id(getSal()->mProvider))); + mCallId.clear(); // Reset the call-id of op, it will be set when new request will be sent belle_sip_request_set_uri(request, redirect_uri); redirect_uri = BELLE_SIP_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(redirect_uri))); belle_sip_uri_set_port(redirect_uri, 0); belle_sip_parameters_remove_parameter(BELLE_SIP_PARAMETERS(redirect_uri), "transport"); belle_sip_header_address_set_uri((belle_sip_header_address_t*)to, redirect_uri); - send_request(request); + sendRequest(request); return 0; } -void SalOp::process_authentication() { - belle_sip_request_t* initial_request=belle_sip_transaction_get_request((belle_sip_transaction_t*)this->pending_auth_transaction); +void SalOp::processAuthentication() { + belle_sip_request_t* initial_request=belle_sip_transaction_get_request((belle_sip_transaction_t*)mPendingAuthTransaction); belle_sip_request_t* new_request; - bool_t is_within_dialog=FALSE; + bool is_within_dialog=false; belle_sip_list_t* auth_list=NULL; belle_sip_auth_event_t* auth_event; - belle_sip_response_t *response=belle_sip_transaction_get_response((belle_sip_transaction_t*)this->pending_auth_transaction); + belle_sip_response_t *response=belle_sip_transaction_get_response((belle_sip_transaction_t*)mPendingAuthTransaction); belle_sip_header_from_t *from=belle_sip_message_get_header_by_type(initial_request,belle_sip_header_from_t); belle_sip_uri_t *from_uri=belle_sip_header_address_get_uri((belle_sip_header_address_t*)from); if (strcasecmp(belle_sip_uri_get_host(from_uri),"anonymous.invalid")==0){ /*prefer using the from from the SalOp*/ - from_uri=belle_sip_header_address_get_uri((belle_sip_header_address_t*)get_from_address()); + from_uri=belle_sip_header_address_get_uri((belle_sip_header_address_t*)getFromAddress()); } - if (this->dialog && belle_sip_dialog_get_state(this->dialog)==BELLE_SIP_DIALOG_CONFIRMED) { - new_request = belle_sip_dialog_create_request_from(this->dialog,initial_request); + if (mDialog && belle_sip_dialog_get_state(mDialog)==BELLE_SIP_DIALOG_CONFIRMED) { + new_request = belle_sip_dialog_create_request_from(mDialog,initial_request); if (!new_request) - new_request = belle_sip_dialog_create_queued_request_from(this->dialog,initial_request); - is_within_dialog=TRUE; + new_request = belle_sip_dialog_create_queued_request_from(mDialog,initial_request); + is_within_dialog=true; } else { new_request=initial_request; belle_sip_message_remove_header(BELLE_SIP_MESSAGE(new_request),BELLE_SIP_AUTHORIZATION); @@ -462,56 +400,55 @@ void SalOp::process_authentication() { return; } - if (belle_sip_provider_add_authorization(this->root->prov,new_request,response,from_uri,&auth_list,this->realm)) { - if (is_within_dialog) { - send_request(new_request); - } else { - resend_request(new_request); - } - this->root->remove_pending_auth(this); + if (belle_sip_provider_add_authorization(mRoot->mProvider,new_request,response,from_uri,&auth_list,L_STRING_TO_C(mRealm))) { + if (is_within_dialog) + sendRequest(new_request); + else + resendRequest(new_request); + mRoot->removePendingAuth(this); }else { belle_sip_header_from_t *from=belle_sip_message_get_header_by_type(response,belle_sip_header_from_t); char *tmp=belle_sip_object_to_string(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from))); ms_message("No auth info found for [%s]",tmp); belle_sip_free(tmp); - this->root->add_pending_auth(this); + mRoot->addPendingAuth(this); if (is_within_dialog) { belle_sip_object_unref(new_request); } } /*always store auth info, for case of wrong credential*/ - if (this->auth_info) { - sal_auth_info_delete(this->auth_info); - this->auth_info=NULL; + if (mAuthInfo) { + sal_auth_info_delete(mAuthInfo); + mAuthInfo=NULL; } if (auth_list){ auth_event=(belle_sip_auth_event_t*)(auth_list->data); - this->auth_info=sal_auth_info_create(auth_event); + mAuthInfo=sal_auth_info_create(auth_event); belle_sip_list_free_with_data(auth_list,(void (*)(void*))belle_sip_auth_event_destroy); } } -char *SalOp::get_dialog_id() const { - if (this->dialog != NULL) { - return ms_strdup_printf("%s;to-tag=%s;from-tag=%s", this->call_id, - belle_sip_dialog_get_remote_tag(this->dialog), belle_sip_dialog_get_local_tag(this->dialog)); - } - return NULL; +string SalOp::getDialogId () const { + if (!mDialog) + return string(); + stringstream ss; + ss << mCallId << ";to-tag=" << belle_sip_dialog_get_remote_tag(mDialog) << ";from-tag=" << belle_sip_dialog_get_local_tag(mDialog); + return ss.str(); } -int SalOp::get_address_family() const { +int SalOp::getAddressFamily() const { belle_sip_transaction_t *tr=NULL; belle_sip_header_address_t *contact; - if (this->refresher) - tr=(belle_sip_transaction_t *)belle_sip_refresher_get_transaction(this->refresher); + if (mRefresher) + tr=(belle_sip_transaction_t *)belle_sip_refresher_get_transaction(mRefresher); if (tr==NULL) - tr=(belle_sip_transaction_t *)this->pending_client_trans; + tr=(belle_sip_transaction_t *)mPendingClientTransaction; if (tr==NULL) - tr=(belle_sip_transaction_t *)this->pending_server_trans; + tr=(belle_sip_transaction_t *)mPendingServerTransaction; if (tr==NULL){ ms_error("Unable to determine IP version from signaling operation."); @@ -519,7 +456,7 @@ int SalOp::get_address_family() const { } - if (this->refresher) { + if (mRefresher) { belle_sip_response_t *resp = belle_sip_transaction_get_response(tr); belle_sip_header_via_t *via = resp ?belle_sip_message_get_header_by_type(resp,belle_sip_header_via_t):NULL; if (!via){ @@ -537,66 +474,57 @@ int SalOp::get_address_family() const { } } -bool_t SalOp::is_idle() const { - if (this->dialog){ - return !belle_sip_dialog_request_pending(this->dialog); - } - return TRUE; +bool SalOp::isIdle() const { + if (mDialog) + return !belle_sip_dialog_request_pending(mDialog); + return true; } -void SalOp::set_entity_tag(const char* entity_tag) { - if (this->entity_tag != NULL) ms_free(this->entity_tag); - this->entity_tag = entity_tag ? ms_strdup(entity_tag) : NULL; -} - -void SalOp::set_event(const char *eventname) { - belle_sip_header_event_t *header = NULL; - if (this->event) belle_sip_object_unref(this->event); - if (eventname){ - header = belle_sip_header_event_create(eventname); +void SalOp::setEvent (const string &eventName) { + belle_sip_header_event_t *header = nullptr; + if (mEvent) + belle_sip_object_unref(mEvent); + if (!eventName.empty()) { + header = belle_sip_header_event_create(eventName.c_str()); belle_sip_object_ref(header); } - this->event = header; + mEvent = header; } -void SalOp::add_initial_route_set(belle_sip_request_t *request, const MSList *list) { - const MSList *elem; - for (elem=list;elem!=NULL;elem=elem->next){ - SalAddress *addr=(SalAddress*)elem->data; - belle_sip_header_route_t *route; - belle_sip_uri_t *uri; - /*Optimization: if the initial route set only contains one URI which is the same as the request URI, ommit it*/ - if (elem==list && list->next==NULL){ - belle_sip_uri_t *requri=belle_sip_request_get_uri(request); - /*skip the first route it is the same as the request uri*/ - if (strcmp(sal_address_get_domain(addr),belle_sip_uri_get_host(requri))==0 ){ - ms_message("Skipping top route of initial route-set because same as request-uri."); +void SalOp::addInitialRouteSet (belle_sip_request_t *request, const list &routeAddresses) { + bool uniqueRoute = routeAddresses.size() == 1; + for (const auto &address : routeAddresses) { + // Optimization: if the initial route set only contains one URI which is the same as the request URI, ommit it + if (uniqueRoute) { + belle_sip_uri_t *requestUri = belle_sip_request_get_uri(request); + // Skip the first route it is the same as the request uri + if (strcmp(sal_address_get_domain(address), belle_sip_uri_get_host(requestUri)) == 0) { + ms_message("Skipping top route of initial route-set because same as request-uri"); continue; } } - route=belle_sip_header_route_create((belle_sip_header_address_t*)addr); - uri=belle_sip_header_address_get_uri((belle_sip_header_address_t*)route); - belle_sip_uri_set_lr_param(uri,1); - belle_sip_message_add_header((belle_sip_message_t*)request,(belle_sip_header_t*)route); + belle_sip_header_route_t *route = belle_sip_header_route_create((belle_sip_header_address_t *)address); + belle_sip_uri_t *uri = belle_sip_header_address_get_uri((belle_sip_header_address_t *)route); + belle_sip_uri_set_lr_param(uri, 1); + belle_sip_message_add_header((belle_sip_message_t *)request, (belle_sip_header_t *)route); } } -belle_sip_request_t* SalOp::build_request(const char* method) { +belle_sip_request_t* SalOp::buildRequest (const string &method) { belle_sip_header_from_t* from_header; belle_sip_header_to_t* to_header; - belle_sip_provider_t* prov=this->root->prov; + belle_sip_provider_t* prov=mRoot->mProvider; belle_sip_request_t *req; belle_sip_uri_t* req_uri; belle_sip_uri_t* to_uri; belle_sip_header_call_id_t *call_id_header; const SalAddress* to_address; - const MSList *elem=get_route_addresses(); char token[10]; /* check that the op has a correct to address */ - to_address = get_to_address(); + to_address = getToAddress(); if( to_address == NULL ){ ms_error("No To: address, cannot build request"); return NULL; @@ -608,8 +536,8 @@ belle_sip_request_t* SalOp::build_request(const char* method) { return NULL; } - if (strcmp("REGISTER",method)==0 || this->privacy==SalPrivacyNone) { - from_header = belle_sip_header_from_create(BELLE_SIP_HEADER_ADDRESS(get_from_address()) + if ((method == "REGISTER") || (mPrivacy == SalPrivacyNone)) { + from_header = belle_sip_header_from_create(BELLE_SIP_HEADER_ADDRESS(getFromAddress()) ,belle_sip_random_token(token,sizeof(token))); } else { from_header=belle_sip_header_from_create2("Anonymous ",belle_sip_random_token(token,sizeof(token))); @@ -617,80 +545,83 @@ belle_sip_request_t* SalOp::build_request(const char* method) { /*make sure to preserve components like headers or port*/ req_uri = (belle_sip_uri_t*)belle_sip_object_clone((belle_sip_object_t*)to_uri); - belle_sip_uri_set_secure(req_uri,is_secure()); + belle_sip_uri_set_secure(req_uri,isSecure()); to_header = belle_sip_header_to_create(BELLE_SIP_HEADER_ADDRESS(to_address),NULL); call_id_header = belle_sip_provider_create_call_id(prov); - if (get_call_id()) { - belle_sip_header_call_id_set_call_id(call_id_header, get_call_id()); - } + if (!mCallId.empty()) + belle_sip_header_call_id_set_call_id(call_id_header, mCallId.c_str()); req=belle_sip_request_create( req_uri, - method, + method.c_str(), call_id_header, - belle_sip_header_cseq_create(20,method), + belle_sip_header_cseq_create(20,method.c_str()), from_header, to_header, belle_sip_header_via_new(), 70); - if (this->privacy & SalPrivacyId) { - belle_sip_header_p_preferred_identity_t* p_preferred_identity=belle_sip_header_p_preferred_identity_create(BELLE_SIP_HEADER_ADDRESS(get_from_address())); + if (mPrivacy & SalPrivacyId) { + belle_sip_header_p_preferred_identity_t* p_preferred_identity=belle_sip_header_p_preferred_identity_create(BELLE_SIP_HEADER_ADDRESS(getFromAddress())); belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(p_preferred_identity)); } - if (elem && strcmp(method,"REGISTER")!=0 && !this->root->no_initial_route){ - add_initial_route_set(req,elem); - } + auto routeAddresses = getRouteAddresses(); + if (!routeAddresses.empty() && (method != "REGISTER") && !mRoot->mNoInitialRoute) + addInitialRouteSet(req, routeAddresses); - if (strcmp("REGISTER",method)!=0 && this->privacy!=SalPrivacyNone ){ + if ((method != "REGISTER") && (mPrivacy != SalPrivacyNone)) { belle_sip_header_privacy_t* privacy_header=belle_sip_header_privacy_new(); - if (this->privacy&SalPrivacyCritical) + if (mPrivacy&SalPrivacyCritical) belle_sip_header_privacy_add_privacy(privacy_header,sal_privacy_to_string(SalPrivacyCritical)); - if (this->privacy&SalPrivacyHeader) + if (mPrivacy&SalPrivacyHeader) belle_sip_header_privacy_add_privacy(privacy_header,sal_privacy_to_string(SalPrivacyHeader)); - if (this->privacy&SalPrivacyId) + if (mPrivacy&SalPrivacyId) belle_sip_header_privacy_add_privacy(privacy_header,sal_privacy_to_string(SalPrivacyId)); - if (this->privacy&SalPrivacyNone) + if (mPrivacy&SalPrivacyNone) belle_sip_header_privacy_add_privacy(privacy_header,sal_privacy_to_string(SalPrivacyNone)); - if (this->privacy&SalPrivacySession) + if (mPrivacy&SalPrivacySession) belle_sip_header_privacy_add_privacy(privacy_header,sal_privacy_to_string(SalPrivacySession)); - if (this->privacy&SalPrivacyUser) + if (mPrivacy&SalPrivacyUser) belle_sip_header_privacy_add_privacy(privacy_header,sal_privacy_to_string(SalPrivacyUser)); belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(privacy_header)); } - belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),this->root->supported); + belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),mRoot->mSupportedHeader); return req; } -void SalOp::set_error_info_from_response(belle_sip_response_t *response) { +void SalOp::setErrorInfoFromResponse(belle_sip_response_t *response) { int code = belle_sip_response_get_status_code(response); const char *reason_phrase=belle_sip_response_get_reason_phrase(response); belle_sip_header_t *warning=belle_sip_message_get_header(BELLE_SIP_MESSAGE(response),"Warning"); - SalErrorInfo *ei=&this->error_info; + SalErrorInfo *ei=&mErrorInfo; const char *warnings; warnings=warning ? belle_sip_header_get_unparsed_value(warning) : NULL; sal_error_info_set(ei,SalReasonUnknown,"SIP", code,reason_phrase,warnings); - set_reason_error_info(BELLE_SIP_MESSAGE(response)); + setReasonErrorInfo(BELLE_SIP_MESSAGE(response)); } -const char* SalOp::to_string(const State value) { - switch(value) { - case State::Early: return"SalOpStateEarly"; - case State::Active: return "SalOpStateActive"; - case State::Terminating: return "SalOpStateTerminating"; - case State::Terminated: return "SalOpStateTerminated"; - default: - return "Unknown"; +string SalOp::toString (const State value) { + switch (value) { + case State::Early: + return"SalOpStateEarly"; + case State::Active: + return "SalOpStateActive"; + case State::Terminating: + return "SalOpStateTerminating"; + case State::Terminated: + return "SalOpStateTerminated"; + default: + return "Unknown"; } } -void SalOp::set_reason_error_info(belle_sip_message_t *msg) { +void SalOp::setReasonErrorInfo(belle_sip_message_t *msg) { belle_sip_header_reason_t* reason_header = belle_sip_message_get_header_by_type(msg,belle_sip_header_reason_t); if (reason_header){ - SalErrorInfo *ei=&this->reason_error_info; // ?// + SalErrorInfo *ei=&mReasonErrorInfo; // ?// const char *protocol = belle_sip_header_reason_get_protocol(reason_header); int code = belle_sip_header_reason_get_cause(reason_header); const char *text = belle_sip_header_reason_get_text(reason_header); @@ -698,41 +629,41 @@ void SalOp::set_reason_error_info(belle_sip_message_t *msg) { } } -void SalOp::set_referred_by(belle_sip_header_referred_by_t* referred_by) { - if (this->referred_by){ - belle_sip_object_unref(this->referred_by); +void SalOp::setReferredBy(belle_sip_header_referred_by_t* referred_by) { + if (mReferredBy){ + belle_sip_object_unref(mReferredBy); } - this->referred_by=referred_by; - belle_sip_object_ref(this->referred_by); + mReferredBy=referred_by; + belle_sip_object_ref(mReferredBy); } -void SalOp::set_replaces(belle_sip_header_replaces_t* replaces) { - if (this->replaces){ - belle_sip_object_unref(this->replaces); +void SalOp::setReplaces(belle_sip_header_replaces_t* replaces) { + if (mReplaces){ + belle_sip_object_unref(mReplaces); } - this->replaces=replaces; - belle_sip_object_ref(this->replaces); + mReplaces=replaces; + belle_sip_object_ref(mReplaces); } -int SalOp::send_request_with_expires(belle_sip_request_t* request,int expires) { +int SalOp::sendRequestWithExpires(belle_sip_request_t* request,int expires) { belle_sip_header_expires_t* expires_header=(belle_sip_header_expires_t*)belle_sip_message_get_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_EXPIRES); if (!expires_header && expires>=0) { belle_sip_message_add_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_HEADER(expires_header=belle_sip_header_expires_new())); } if (expires_header) belle_sip_header_expires_set_expires(expires_header,expires); - return send_request(request); + return sendRequest(request); } -int SalOp::send_and_create_refresher(belle_sip_request_t* req, int expires,belle_sip_refresher_listener_t listener) { - if (send_request_with_expires(req,expires)==0) { - if (this->refresher) { - belle_sip_refresher_stop(this->refresher); - belle_sip_object_unref(this->refresher); +int SalOp::sendRequestAndCreateRefresher(belle_sip_request_t* req, int expires,belle_sip_refresher_listener_t listener) { + if (sendRequestWithExpires(req,expires)==0) { + if (mRefresher) { + belle_sip_refresher_stop(mRefresher); + belle_sip_object_unref(mRefresher); } - if ((this->refresher = belle_sip_client_transaction_create_refresher(this->pending_client_trans))) { + if ((mRefresher = belle_sip_client_transaction_create_refresher(mPendingClientTransaction))) { /*since refresher acquires the transaction, we should remove our context from the transaction, because we won't be notified * that it is terminated anymore.*/ unref();/*loose the reference that was given to the transaction when creating it*/ @@ -740,10 +671,10 @@ int SalOp::send_and_create_refresher(belle_sip_request_t* req, int expires,belle Something in the design is not very good here, it makes things complicated to the belle-sip user. Possible ideas to improve things: refresher shall not use belle_sip_transaction_set_application_data() internally, refresher should let the first transaction notify the user as a normal transaction*/ - belle_sip_refresher_set_listener(this->refresher,listener, this); - belle_sip_refresher_set_retry_after(this->refresher,this->root->refresher_retry_after); - belle_sip_refresher_set_realm(this->refresher,this->realm); - belle_sip_refresher_enable_manual_mode(this->refresher, this->manual_refresher); + belle_sip_refresher_set_listener(mRefresher,listener, this); + belle_sip_refresher_set_retry_after(mRefresher,mRoot->mRefresherRetryAfter); + belle_sip_refresher_set_realm(mRefresher,L_STRING_TO_C(mRealm)); + belle_sip_refresher_enable_manual_mode(mRefresher, mManualRefresher); return 0; } else { return -1; @@ -752,12 +683,12 @@ int SalOp::send_and_create_refresher(belle_sip_request_t* req, int expires,belle return -1; } -belle_sip_header_contact_t *SalOp::create_contact() { +belle_sip_header_contact_t *SalOp::createContact() { belle_sip_header_contact_t* contact_header; belle_sip_uri_t* contact_uri; - if (get_contact_address()) { - contact_header = belle_sip_header_contact_create(BELLE_SIP_HEADER_ADDRESS(get_contact_address())); + if (getContactAddress()) { + contact_header = belle_sip_header_contact_create(BELLE_SIP_HEADER_ADDRESS(getContactAddress())); } else { contact_header= belle_sip_header_contact_new(); } @@ -769,78 +700,78 @@ belle_sip_header_contact_t *SalOp::create_contact() { } belle_sip_uri_set_user_password(contact_uri,NULL); - belle_sip_uri_set_secure(contact_uri,is_secure()); - if (this->privacy!=SalPrivacyNone){ + belle_sip_uri_set_secure(contact_uri,isSecure()); + if (mPrivacy!=SalPrivacyNone){ belle_sip_uri_set_user(contact_uri,NULL); } /*don't touch contact in case of gruu*/ if (!belle_sip_parameters_has_parameter(BELLE_SIP_PARAMETERS(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(contact_header))),"gr")) { - belle_sip_header_contact_set_automatic(contact_header,this->root->auto_contacts); - if (this->root->uuid) { - if (belle_sip_parameters_has_parameter(BELLE_SIP_PARAMETERS(contact_header),"+sip.instance")==0){ - char *instance_id=belle_sip_strdup_printf("\"\"",this->root->uuid); - belle_sip_parameters_set_parameter(BELLE_SIP_PARAMETERS(contact_header),"+sip.instance",instance_id); - belle_sip_free(instance_id); - } + belle_sip_header_contact_set_automatic(contact_header,mRoot->mAutoContacts); + if (!mRoot->mUuid.empty() + && !belle_sip_parameters_has_parameter(BELLE_SIP_PARAMETERS(contact_header), "+sip.instance") + ) { + stringstream ss; + ss << "\"mUuid << ">\""; + string instanceId = ss.str(); + belle_sip_parameters_set_parameter(BELLE_SIP_PARAMETERS(contact_header), "+sip.instance", instanceId.c_str()); } } - if (this->root->linphone_specs && strlen(this->root->linphone_specs) > 0) { - if (belle_sip_parameters_has_parameter(BELLE_SIP_PARAMETERS(contact_header),"+org.linphone.specs") == 0) { - belle_sip_parameters_set_parameter(BELLE_SIP_PARAMETERS(contact_header), "+org.linphone.specs", this->root->linphone_specs); - } + if (!mRoot->mLinphoneSpecs.empty() + && !belle_sip_parameters_has_parameter(BELLE_SIP_PARAMETERS(contact_header), "+org.linphone.specs") + ) { + belle_sip_parameters_set_parameter(BELLE_SIP_PARAMETERS(contact_header), "+org.linphone.specs", mRoot->mLinphoneSpecs.c_str()); } return contact_header; } -void SalOp::unlink_op_with_dialog(belle_sip_dialog_t* dialog) { +void SalOp::unlinkOpFromDialog(belle_sip_dialog_t* dialog) { belle_sip_dialog_set_application_data(dialog,NULL); unref(); belle_sip_object_unref(dialog); } -belle_sip_dialog_t *SalOp::link_op_with_dialog(belle_sip_dialog_t* dialog) { +belle_sip_dialog_t *SalOp::linkOpWithDialog(belle_sip_dialog_t* dialog) { belle_sip_dialog_set_application_data(dialog,ref()); belle_sip_object_ref(dialog); return dialog; } -void SalOp::set_or_update_dialog(belle_sip_dialog_t* dialog) { - ms_message("op [%p] : set_or_update_dialog() current=[%p] new=[%p]", this, this->dialog,dialog); +void SalOp::setOrUpdateDialog(belle_sip_dialog_t* dialog) { + ms_message("op [%p] : set_or_update_dialog() current=[%p] new=[%p]", this, mDialog,dialog); ref(); - if (this->dialog!=dialog){ - if (this->dialog){ + if (mDialog!=dialog){ + if (mDialog){ /*FIXME: shouldn't we delete unconfirmed dialogs ?*/ - unlink_op_with_dialog(this->dialog); - this->dialog=NULL; + unlinkOpFromDialog(mDialog); + mDialog=NULL; } if (dialog) { - this->dialog=link_op_with_dialog(dialog); - belle_sip_dialog_enable_pending_trans_checking(dialog,this->root->pending_trans_checking); + mDialog=linkOpWithDialog(dialog); + belle_sip_dialog_enable_pending_trans_checking(dialog,mRoot->mPendingTransactionChecking); } } unref(); } -int SalOp::ping(const char *from, const char *to) { - set_from(from); - set_to(to); - return send_request(build_request("OPTIONS")); +int SalOp::ping (const string &from, const string &to) { + setFrom(from); + setTo(to); + return sendRequest(buildRequest("OPTIONS")); } -int SalOp::send_info(const char *from, const char *to, const SalBodyHandler *body_handler) { - if (this->dialog && belle_sip_dialog_get_state(this->dialog) == BELLE_SIP_DIALOG_CONFIRMED) { - belle_sip_request_t *req; - belle_sip_dialog_enable_pending_trans_checking(this->dialog,this->root->pending_trans_checking); - req=belle_sip_dialog_create_queued_request(this->dialog,"INFO"); - belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(req), BELLE_SIP_BODY_HANDLER(body_handler)); - return send_request(req); - }else{ - ms_error("Cannot send INFO message on op [%p] because dialog is not in confirmed state yet.", this); +int SalOp::sendInfo (const SalBodyHandler *bodyHandler) { + if (mDialog && (belle_sip_dialog_get_state(mDialog) == BELLE_SIP_DIALOG_CONFIRMED)) { + belle_sip_dialog_enable_pending_trans_checking(mDialog, mRoot->mPendingTransactionChecking); + belle_sip_request_t *request = belle_sip_dialog_create_queued_request(mDialog, "INFO"); + belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(request), BELLE_SIP_BODY_HANDLER(bodyHandler)); + return sendRequest(request); + } else { + lError() << "Cannot send INFO message on op [" << this << "] because dialog is not in confirmed state yet"; } return -1; } -SalBodyHandler *SalOp::get_body_handler(belle_sip_message_t *msg) { +SalBodyHandler *SalOp::getBodyHandler(belle_sip_message_t *msg) { belle_sip_body_handler_t *body_handler = belle_sip_message_get_body_handler(msg); if (body_handler != NULL) { belle_sip_header_content_type_t *content_type = belle_sip_message_get_header_by_type(msg, belle_sip_header_content_type_t); @@ -853,31 +784,37 @@ SalBodyHandler *SalOp::get_body_handler(belle_sip_message_t *msg) { return (SalBodyHandler *)body_handler; } -void SalOp::assign_recv_headers(belle_sip_message_t *incoming) { +void SalOp::assignRecvHeaders(belle_sip_message_t *incoming) { if (incoming) belle_sip_object_ref(incoming); - if (this->recv_custom_headers){ - belle_sip_object_unref(this->recv_custom_headers); - this->recv_custom_headers=NULL; + if (mRecvCustomHeaders){ + belle_sip_object_unref(mRecvCustomHeaders); + mRecvCustomHeaders=NULL; } if (incoming){ - this->recv_custom_headers=(SalCustomHeader*)incoming; + mRecvCustomHeaders=(SalCustomHeader*)incoming; } } -void SalOp::set_remote_contact(const char* remote_contact) { - assign_address(&this->remote_contact_address,remote_contact); - /*to preserve header params*/ - assign_string(&this->remote_contact,remote_contact); +void SalOp::setRemoteContact (const string &value) { + assignAddress(&mRemoteContactAddress, value); + mRemoteContact = value; // To preserve header params } -void SalOp::set_network_origin(const char *origin) { - SET_PARAM(origin); +void SalOp::setNetworkOrigin (const string &value) { + assignAddress(&mOriginAddress, value); + if (mOriginAddress) { + char *valueStr = sal_address_as_string(mOriginAddress); + mOrigin = valueStr; + ms_free(valueStr); + } else { + mOrigin.clear(); + } } -void SalOp::set_network_origin_address(SalAddress *origin){ - char* address_string=sal_address_as_string(origin); /*can probably be optimized*/ - set_network_origin(address_string); - ms_free(address_string); +void SalOp::setNetworkOriginAddress (SalAddress *value) { + char *valueStr = sal_address_as_string(value); // Can probably be optimized + setNetworkOrigin(valueStr); + ms_free(valueStr); } /* @@ -888,79 +825,83 @@ When a Privacy header is constructed, it MUST consist of either the 'session' (each of which MUST appear at most once) which MAY in turn be followed by the 'critical' indicator. */ -void SalOp::set_privacy_from_message(belle_sip_message_t* msg) { +void SalOp::setPrivacyFromMessage(belle_sip_message_t* msg) { belle_sip_header_privacy_t* privacy = belle_sip_message_get_header_by_type(msg,belle_sip_header_privacy_t); if (!privacy) { - set_privacy(SalPrivacyNone); + setPrivacy(SalPrivacyNone); } else { belle_sip_list_t* privacy_list=belle_sip_header_privacy_get_privacy(privacy); - set_privacy(0); + setPrivacy(0); for (;privacy_list!=NULL;privacy_list=privacy_list->next) { char* privacy_value=(char*)privacy_list->data; if(strcmp(sal_privacy_to_string(SalPrivacyCritical),privacy_value) == 0) - set_privacy(get_privacy()|SalPrivacyCritical); + setPrivacy(getPrivacy()|SalPrivacyCritical); if(strcmp(sal_privacy_to_string(SalPrivacyHeader),privacy_value) == 0) - set_privacy(get_privacy()|SalPrivacyHeader); + setPrivacy(getPrivacy()|SalPrivacyHeader); if(strcmp(sal_privacy_to_string(SalPrivacyId),privacy_value) == 0) - set_privacy(get_privacy()|SalPrivacyId); + setPrivacy(getPrivacy()|SalPrivacyId); if(strcmp(sal_privacy_to_string(SalPrivacyNone),privacy_value) == 0) { - set_privacy(SalPrivacyNone); + setPrivacy(SalPrivacyNone); break; } if(strcmp(sal_privacy_to_string(SalPrivacySession),privacy_value) == 0) - set_privacy(get_privacy()|SalPrivacySession); + setPrivacy(getPrivacy()|SalPrivacySession); if(strcmp(sal_privacy_to_string(SalPrivacyUser),privacy_value) == 0) - set_privacy(get_privacy()|SalPrivacyUser); + setPrivacy(getPrivacy()|SalPrivacyUser); } } } -void SalOp::set_remote_ua(belle_sip_message_t* message) { - belle_sip_header_user_agent_t* user_agent=belle_sip_message_get_header_by_type(message,belle_sip_header_user_agent_t); - char user_agent_string[256]; - if (user_agent && belle_sip_header_user_agent_get_products_as_string(user_agent,user_agent_string,sizeof(user_agent_string))>0) { - if (this->remote_ua!=NULL){ - ms_free(this->remote_ua); - } - this->remote_ua=ms_strdup(user_agent_string); +void SalOp::setRemoteUserAgent (belle_sip_message_t *message) { + belle_sip_header_user_agent_t *userAgentHeader = belle_sip_message_get_header_by_type(message, belle_sip_header_user_agent_t); + char userAgentStr[256]; + if (userAgentHeader + && belle_sip_header_user_agent_get_products_as_string(userAgentHeader, userAgentStr, sizeof(userAgentStr)) > 0 + ) { + mRemoteUserAgent = userAgentStr; } } -const char *SalOp::to_string(const Type type) { - switch(type) { - case Type::Register: return "SalOpRegister"; - case Type::Call: return "SalOpCall"; - case Type::Message: return "SalOpMessage"; - case Type::Presence: return "SalOpPresence"; - default: return "SalOpUnknown"; +string SalOp::toString (const Type type) { + switch (type) { + case Type::Register: + return "SalOpRegister"; + case Type::Call: + return "SalOpCall"; + case Type::Message: + return "SalOpMessage"; + case Type::Presence: + return "SalOpPresence"; + default: + return "SalOpUnknown"; } } -bool_t SalOp::is_secure() const { - const SalAddress* from = get_from_address(); - const SalAddress* to = get_to_address(); +bool SalOp::isSecure() const { + const SalAddress* from = getFromAddress(); + const SalAddress* to = getToAddress(); return from && to && strcasecmp("sips",sal_address_get_scheme(from))==0 && strcasecmp("sips",sal_address_get_scheme(to))==0; } /* * Warning: this function takes owneship of the custom headers */ -void SalOp::set_sent_custom_header(SalCustomHeader* ch){ - if (this->sent_custom_headers){ - sal_custom_header_free(this->sent_custom_headers); - this->sent_custom_headers=NULL; +void SalOp::setSentCustomHeaders(SalCustomHeader* ch){ + if (mSentCustomHeaders){ + sal_custom_header_free(mSentCustomHeaders); + mSentCustomHeaders=NULL; } if (ch) belle_sip_object_ref((belle_sip_message_t*)ch); - this->sent_custom_headers=ch; + mSentCustomHeaders=ch; } -void SalOp::add_headers(belle_sip_header_t *h, belle_sip_message_t *msg){ +void SalOp::addHeaders(belle_sip_header_t *h, belle_sip_message_t *msg){ if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(h,belle_sip_header_contact_t)){ belle_sip_header_contact_t* newct; /*special case for contact, we want to keep everything from the custom contact but set automatic mode and add our own parameters as well*/ - set_contact_address((SalAddress*)BELLE_SIP_HEADER_ADDRESS(h)); - newct = create_contact(); + setContactAddress((SalAddress*)BELLE_SIP_HEADER_ADDRESS(h)); + newct = createContact(); belle_sip_message_set_header(BELLE_SIP_MESSAGE(msg),BELLE_SIP_HEADER(newct)); return; } @@ -969,32 +910,32 @@ void SalOp::add_headers(belle_sip_header_t *h, belle_sip_message_t *msg){ } -void SalOp::add_custom_headers(belle_sip_message_t *msg){ - if (this->sent_custom_headers){ - belle_sip_message_t *ch=(belle_sip_message_t*)this->sent_custom_headers; +void SalOp::addCustomHeaders(belle_sip_message_t *msg){ + if (mSentCustomHeaders){ + belle_sip_message_t *ch=(belle_sip_message_t*)mSentCustomHeaders; belle_sip_list_t *l=belle_sip_message_get_all_headers(ch); belle_sip_list_t *elem; for(elem=l;elem!=NULL;elem=elem->next){ - add_headers((belle_sip_header_t*)elem->data,msg); + addHeaders((belle_sip_header_t*)elem->data,msg); } belle_sip_list_free(l); } } int SalOp::unsubscribe(){ - if (this->refresher){ - const belle_sip_transaction_t *tr=(const belle_sip_transaction_t*) belle_sip_refresher_get_transaction(this->refresher); + if (mRefresher){ + const belle_sip_transaction_t *tr=(const belle_sip_transaction_t*) belle_sip_refresher_get_transaction(mRefresher); belle_sip_request_t *last_req=belle_sip_transaction_get_request(tr); belle_sip_message_set_body(BELLE_SIP_MESSAGE(last_req), NULL, 0); - belle_sip_refresher_refresh(this->refresher,0); + belle_sip_refresher_refresh(mRefresher,0); return 0; } return -1; } -void SalOp::process_incoming_message(const belle_sip_request_event_t *event) { +void SalOp::processIncomingMessage(const belle_sip_request_event_t *event) { belle_sip_request_t* req = belle_sip_request_event_get_request(event); - belle_sip_server_transaction_t* server_transaction = belle_sip_provider_create_server_transaction(this->root->prov,req); + belle_sip_server_transaction_t* server_transaction = belle_sip_provider_create_server_transaction(mRoot->mProvider,req); belle_sip_header_address_t* address; belle_sip_header_from_t* from_header; belle_sip_header_content_type_t* content_type; @@ -1004,7 +945,7 @@ void SalOp::process_incoming_message(const belle_sip_request_event_t *event) { belle_sip_header_cseq_t* cseq = belle_sip_message_get_header_by_type(req,belle_sip_header_cseq_t); belle_sip_header_date_t *date=belle_sip_message_get_header_by_type(req,belle_sip_header_date_t); char* from; - bool_t external_body=FALSE; + bool external_body = false; from_header=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_from_t); content_type=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_content_type_t); @@ -1013,12 +954,12 @@ void SalOp::process_incoming_message(const belle_sip_request_event_t *event) { SalMessage salmsg; char message_id[256]={0}; - if (this->pending_server_trans) belle_sip_object_unref(this->pending_server_trans); + if (mPendingServerTransaction) belle_sip_object_unref(mPendingServerTransaction); - this->pending_server_trans=server_transaction; - belle_sip_object_ref(this->pending_server_trans); + mPendingServerTransaction=server_transaction; + belle_sip_object_ref(mPendingServerTransaction); - external_body=is_external_body(content_type); + external_body=isExternalBody(content_type); address=belle_sip_header_address_create(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(from_header)) ,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from_header))); from=belle_sip_object_to_string(BELLE_SIP_OBJECT(address)); @@ -1029,15 +970,21 @@ void SalOp::process_incoming_message(const belle_sip_request_event_t *event) { /* if we just deciphered a message, use the deciphered part(which can be a rcs xml body pointing to the file to retreive from server)*/ salmsg.text=(!external_body)?belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)):NULL; salmsg.url=NULL; - salmsg.content_type = ms_strdup_printf("%s/%s", belle_sip_header_content_type_get_type(content_type), belle_sip_header_content_type_get_subtype(content_type)); + + char buffer[1024]; + size_t offset = 0; + belle_sip_parameters_marshal(BELLE_SIP_PARAMETERS(content_type), buffer, 1024, &offset); + buffer[offset] = '\0'; + salmsg.content_type = ms_strdup_printf("%s/%s%s", belle_sip_header_content_type_get_type(content_type), belle_sip_header_content_type_get_subtype(content_type), buffer); if (external_body && belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(content_type),"URL")) { size_t url_length=strlen(belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(content_type),"URL")); salmsg.url = ms_strdup(belle_sip_parameters_get_parameter(BELLE_SIP_PARAMETERS(content_type),"URL")+1); /* skip first "*/ ((char*)salmsg.url)[url_length-2]='\0'; /*remove trailing "*/ } + salmsg.message_id=message_id; salmsg.time=date ? belle_sip_header_date_get_time(date) : time(NULL); - this->root->callbacks.message_received(this,&salmsg); + mRoot->mCallbacks.message_received(this,&salmsg); belle_sip_object_unref(address); belle_sip_free(from); @@ -1046,50 +993,42 @@ void SalOp::process_incoming_message(const belle_sip_request_event_t *event) { } else { ms_error("Unsupported MESSAGE (no Content-Type)"); resp = belle_sip_response_create_from_request(req, errcode); - add_message_accept((belle_sip_message_t*)resp); + addMessageAccept((belle_sip_message_t*)resp); belle_sip_server_transaction_send_response(server_transaction,resp); release(); } } -bool_t SalOp::is_external_body(belle_sip_header_content_type_t* content_type) { +bool SalOp::isExternalBody(belle_sip_header_content_type_t* content_type) { return strcmp("message",belle_sip_header_content_type_get_type(content_type))==0 && strcmp("external-body",belle_sip_header_content_type_get_subtype(content_type))==0; } -int SalOp::reply_message(SalReason reason) { - if (this->pending_server_trans){ +int SalOp::replyMessage(SalReason reason) { + if (mPendingServerTransaction){ int code=to_sip_code(reason); belle_sip_response_t *resp = belle_sip_response_create_from_request( - belle_sip_transaction_get_request((belle_sip_transaction_t*)this->pending_server_trans),code); - belle_sip_server_transaction_send_response(this->pending_server_trans,resp); + belle_sip_transaction_get_request((belle_sip_transaction_t*)mPendingServerTransaction),code); + belle_sip_server_transaction_send_response(mPendingServerTransaction,resp); return 0; }else ms_error("sal_message_reply(): no server transaction"); return -1; } -void SalOp::add_message_accept(belle_sip_message_t *msg) { - bctbx_list_t *item; - const char *str; - char *old; - char *header = ms_strdup("xml/cipher, application/cipher.vnd.gsma.rcs-ft-http+xml"); - - for (item = this->root->supported_content_types; item != NULL; item = bctbx_list_next(item)) { - str = (const char *)bctbx_list_get_data(item); - old = header; - header = ms_strdup_printf("%s, %s", old, str); - ms_free(old); - } - - belle_sip_message_add_header(msg, belle_sip_header_create("Accept", header)); - ms_free(header); +void SalOp::addMessageAccept (belle_sip_message_t *message) { + stringstream ss; + ss << "xml/cipher, application/cipher.vnd.gsma.rcs-ft-http+xml"; + for (const auto &supportedContentType : mRoot->mSupportedContentTypes) + ss << ", " << supportedContentType; + string headerValue = ss.str(); + belle_sip_message_add_header(message, belle_sip_header_create("Accept", headerValue.c_str())); } -void SalOp::set_service_route(const SalAddress* service_route) { - if (this->service_route) - sal_address_destroy(this->service_route); +void SalOp::setServiceRoute(const SalAddress* service_route) { + if (mServiceRoute) + sal_address_destroy(mServiceRoute); - this->service_route=service_route?sal_address_clone(service_route):NULL; + mServiceRoute=service_route?sal_address_clone(service_route):NULL; } LINPHONE_END_NAMESPACE diff --git a/src/sal/op.h b/src/sal/op.h index 317d3f632..501ee2f60 100644 --- a/src/sal/op.h +++ b/src/sal/op.h @@ -26,107 +26,118 @@ #include "c-wrapper/internal/c-sal.h" #include "content/content.h" +#include "logger/logger.h" #include "sal/sal.h" LINPHONE_BEGIN_NAMESPACE class SalOp { public: - SalOp(Sal *sal); - virtual ~SalOp(); + SalOp (Sal *sal); + virtual ~SalOp (); - SalOp *ref(); - void *unref(); + SalOp *ref (); + void *unref (); - Sal *get_sal() const {return this->root;} + Sal *getSal () const { return mRoot; } - void set_user_pointer(void *up) {this->user_pointer=up;} - void *get_user_pointer() const {return this->user_pointer;} + void setUserPointer (void *value) { mUserPointer = value; } + void *getUserPointer () const { return mUserPointer; } - void set_subject (const char *subject); - const char *get_subject () const { return this->subject; } + void setSubject (const std::string &value) { mSubject = value; } + const std::string &getSubject () const { return mSubject; } - void set_from(const char *from); - void set_from_address(const SalAddress *from); - const char *get_from() const {return this->from;} - const SalAddress *get_from_address() const {return this->from_address;} + void setFrom (const std::string &value); + void setFromAddress (const SalAddress *value); + const std::string &getFrom () const { return mFrom; } + const SalAddress *getFromAddress () const { return mFromAddress; } - void set_to(const char *to); - void set_to_address(const SalAddress *to); - const char *get_to() const {return this->to;} - const SalAddress *get_to_address() const {return this->to_address;} + void setTo (const std::string &value); + void setToAddress (const SalAddress *value); + const std::string &getTo () const { return mTo; } + const SalAddress *getToAddress () const { return mToAddress; } - void set_contact_address(const SalAddress* address); - const SalAddress *get_contact_address() const {return this->contact_address;} + void setContactAddress (const SalAddress* value); + const SalAddress *getContactAddress() const { return mContactAddress; } - void set_route(const char *route); - void set_route_address(const SalAddress* address); - const bctbx_list_t *get_route_addresses() const {return this->route_addresses;} - void add_route_address(const SalAddress* address); + void setRoute (const std::string &value); + void setRouteAddress (const SalAddress *value); + const std::list &getRouteAddresses () const { return mRouteAddresses; } + void addRouteAddress (const SalAddress *address); - void set_diversion_address(const SalAddress *diversion); - const SalAddress *get_diversion_address() const {return this->diversion_address;} + void setDiversionAddress (const SalAddress *value); + const SalAddress *getDiversionAddress () const { return mDiversionAddress; } - void set_service_route(const SalAddress* service_route); - const SalAddress *get_service_route() const {return this->service_route;} + void setServiceRoute (const SalAddress *value); + const SalAddress *getServiceRoute () const { return mServiceRoute; } - void set_manual_refresher_mode(bool_t enabled) {this->manual_refresher=enabled;} + void setManualRefresherMode (bool value) { mManualRefresher = value; } - void set_entity_tag(const char* entity_tag); - const char *get_entity_tag() const {return this->entity_tag;} + void setEntityTag (const std::string &value) { mEntityTag = value; } + const std::string &getEntityTag() const { return mEntityTag; } - void set_event(const char *eventname); + void setEvent (const std::string &eventName); - void set_privacy(SalPrivacyMask privacy) {this->privacy=privacy;} - SalPrivacyMask get_privacy() const {return this->privacy;} + void setPrivacy (SalPrivacyMask value) { mPrivacy = value; } + SalPrivacyMask getPrivacy() const { return mPrivacy; } - void set_realm(const char *realm); + void setRealm (const std::string &value) { mRealm = value; } - void set_sent_custom_header(SalCustomHeader* ch); + void setSentCustomHeaders (SalCustomHeader *ch); - void enable_cnx_ip_to_0000_if_sendonly(bool_t yesno) {this->_cnx_ip_to_0000_if_sendonly_enabled = yesno;} - bool_t cnx_ip_to_0000_if_sendonly_enabled() const {return this->_cnx_ip_to_0000_if_sendonly_enabled;} + void enableCnxIpTo0000IfSendOnly (bool value) { mCnxIpTo0000IfSendOnlyEnabled = value; } + bool cnxIpTo0000IfSendOnlyEnabled () const { return mCnxIpTo0000IfSendOnlyEnabled; } - const char *get_proxy() const {return this->route;} - const char *get_network_origin() const {return this->origin;} - const char* get_call_id() const {return this->call_id;} - char* get_dialog_id() const; - int get_address_family() const; - const SalCustomHeader *get_recv_custom_header() const {return this->recv_custom_headers;} - const char *get_remote_contact() const {return this->remote_contact;} - const SalAddress *get_remote_contact_address() const {return this->remote_contact_address;} - const char *get_remote_ua() const {return this->remote_ua;} + const std::string &getProxy () const { return mRoute; } + const std::string &getNetworkOrigin () const { return mOrigin; } + const std::string &getCallId () const { return mCallId; } + std::string getDialogId () const; + int getAddressFamily () const; + const SalCustomHeader *getRecvCustomHeaders () const { return mRecvCustomHeaders; } + const std::string &getRemoteContact () const { return mRemoteContact; } + const SalAddress *getRemoteContactAddress () const { return mRemoteContactAddress; } + const std::string &getRemoteUserAgent () const { return mRemoteUserAgent; } - const char *get_public_address(int *port) {return this->refresher ? belle_sip_refresher_get_public_address(this->refresher, port) : NULL;} - const char *get_local_address(int *port) {return this->refresher ? belle_sip_refresher_get_local_address(this->refresher, port) : NULL;} + const char *getPublicAddress (int *port) { + return mRefresher ? belle_sip_refresher_get_public_address(mRefresher, port) : nullptr; + } + const char *getLocalAddress (int *port) { + return mRefresher ? belle_sip_refresher_get_local_address(mRefresher, port) : nullptr; + } - const SalErrorInfo *get_error_info() const {return &this->error_info;} - const SalErrorInfo *get_reason_error_info() const {return &this->reason_error_info;} + const SalErrorInfo *getErrorInfo () const { return &mErrorInfo; } + const SalErrorInfo *getReasonErrorInfo () const { return &mReasonErrorInfo; } - bool_t is_forked_of(const SalOp *op2) const {return this->call_id && op2->call_id && strcmp(this->call_id, op2->call_id) == 0;} - bool_t is_idle() const ; + bool isForkedOf (const SalOp *op) const { + return !mCallId.empty() && !op->mCallId.empty() && (mCallId == op->mCallId); + } + bool isIdle () const; - void stop_refreshing() {if (this->refresher) belle_sip_refresher_stop(this->refresher);} - int refresh(); - void kill_dialog(); - void release(); + void stopRefreshing () { + if (mRefresher) + belle_sip_refresher_stop(mRefresher); + } + int refresh (); + void killDialog (); + void release (); - virtual void authenticate(const SalAuthInfo *info) {process_authentication();} - void cancel_authentication() {ms_fatal("sal_op_cancel_authentication not implemented yet");} - SalAuthInfo *get_auth_requested() {return this->auth_info;} + virtual void authenticate (const SalAuthInfo *info) { + processAuthentication(); } + void cancelAuthentication () { lFatal() << "SalOp::cancelAuthentication not implemented yet"; } + SalAuthInfo *getAuthRequested () { return mAuthInfo; } - int ping(const char *from, const char *to); - int send_info(const char *from, const char *to, const SalBodyHandler *body_handler); + int ping (const std::string &from, const std::string &to); + int sendInfo (const SalBodyHandler *bodyHandler); protected: enum class State { Early = 0, Active, - Terminating, /*this state is used to wait until a proceeding state, so we can send the cancel*/ + Terminating, // This state is used to wait until a proceeding state, so we can send the cancel Terminated }; - static const char* to_string(const State value); + static std::string toString (const State value); enum class Dir { Incoming = 0, @@ -141,118 +152,119 @@ protected: Presence, Publish, Subscribe, - Refer /*for out of dialog refer only*/ + Refer // For out of dialog refer only }; - static const char *to_string(const SalOp::Type type); + static std::string toString (const Type type); - typedef void (*ReleaseCb)(SalOp *op); + using ReleaseCb = void (*) (SalOp *op); - virtual void fill_cbs() {} - void release_impl(); - void process_authentication(); - int process_redirect(); + virtual void fillCallbacks () {} + void releaseImpl (); + void processAuthentication (); + int processRedirect (); - belle_sip_request_t* build_request(const char* method); - int send_request(belle_sip_request_t* request); - int send_request_with_contact(belle_sip_request_t* request, bool_t add_contact); - int send_request_with_expires(belle_sip_request_t* request,int expires); - void resend_request(belle_sip_request_t* request); - int send_and_create_refresher(belle_sip_request_t* req, int expires,belle_sip_refresher_listener_t listener); + belle_sip_request_t *buildRequest (const std::string &method); + int sendRequest (belle_sip_request_t *request); + int sendRequestWithContact (belle_sip_request_t *request, bool addContact); + int sendRequestWithExpires (belle_sip_request_t *request, int expires); + void resendRequest (belle_sip_request_t *request); + int sendRequestAndCreateRefresher (belle_sip_request_t *request, int expires, belle_sip_refresher_listener_t listener); - void set_reason_error_info(belle_sip_message_t *msg); - void set_error_info_from_response(belle_sip_response_t *response); + void setReasonErrorInfo (belle_sip_message_t *message); + void setErrorInfoFromResponse (belle_sip_response_t *response); - void set_referred_by(belle_sip_header_referred_by_t* referred_by); - void set_replaces(belle_sip_header_replaces_t* replaces); + void setReferredBy (belle_sip_header_referred_by_t *referredByHeader); + void setReplaces (belle_sip_header_replaces_t *replacesHeader); - void set_remote_contact(const char* remote_contact); - void set_network_origin(const char *origin); - void set_network_origin_address(SalAddress *origin); - void set_privacy_from_message(belle_sip_message_t* msg); - void set_remote_ua(belle_sip_message_t* message); + void setRemoteContact (const std::string &value); + void setNetworkOrigin (const std::string &value); + void setNetworkOriginAddress (SalAddress *value); + void setPrivacyFromMessage (belle_sip_message_t *message); + void setRemoteUserAgent (belle_sip_message_t *message); - belle_sip_response_t *create_response_from_request(belle_sip_request_t *req, int code) {return this->root->create_response_from_request(req,code);} - belle_sip_header_contact_t *create_contact(); + belle_sip_response_t *createResponseFromRequest (belle_sip_request_t *request, int code) { + return mRoot->createResponseFromRequest(request, code); + } + belle_sip_header_contact_t *createContact (); - void set_or_update_dialog(belle_sip_dialog_t* dialog); - belle_sip_dialog_t *link_op_with_dialog(belle_sip_dialog_t* dialog); - void unlink_op_with_dialog(belle_sip_dialog_t* dialog); + void setOrUpdateDialog (belle_sip_dialog_t *dialog); + belle_sip_dialog_t *linkOpWithDialog (belle_sip_dialog_t *dialog); + void unlinkOpFromDialog (belle_sip_dialog_t *dialog); - SalBodyHandler *get_body_handler(belle_sip_message_t *msg); + SalBodyHandler *getBodyHandler (belle_sip_message_t *message); - void assign_recv_headers(belle_sip_message_t *incoming); + void assignRecvHeaders (belle_sip_message_t *message); - bool_t is_secure() const; - void add_headers(belle_sip_header_t *h, belle_sip_message_t *msg); - void add_custom_headers(belle_sip_message_t *msg); - int unsubscribe(); + bool isSecure () const; + void addHeaders (belle_sip_header_t *h, belle_sip_message_t *message); + void addCustomHeaders (belle_sip_message_t *message); + int unsubscribe (); - void process_incoming_message(const belle_sip_request_event_t *event); - int reply_message(SalReason reason); - void add_message_accept(belle_sip_message_t *msg); - static bool_t is_external_body(belle_sip_header_content_type_t* content_type); + void processIncomingMessage (const belle_sip_request_event_t *event); + int replyMessage (SalReason reason); + void addMessageAccept (belle_sip_message_t *message); - static void assign_address(SalAddress** address, const char *value); - static void assign_string(char **str, const char *arg); - static void add_initial_route_set(belle_sip_request_t *request, const MSList *list); + static bool isExternalBody (belle_sip_header_content_type_t* contentType); + + static void assignAddress (SalAddress **address, const std::string &value); + static void addInitialRouteSet (belle_sip_request_t *request, const std::list &routeAddresses); // SalOpBase - Sal *root = NULL; - char *route = NULL; /*or request-uri for REGISTER*/ - MSList* route_addresses = NULL; /*list of SalAddress* */ - SalAddress* contact_address = NULL; - char *subject = NULL; - char *from = NULL; - SalAddress* from_address = NULL; - char *to = NULL; - SalAddress* to_address = NULL; - char *origin = NULL; - SalAddress* origin_address = NULL; - SalAddress* diversion_address = NULL; - char *remote_ua = NULL; - SalAddress* remote_contact_address = NULL; - char *remote_contact = NULL; - void *user_pointer = NULL; - char* call_id = NULL; - char* realm = NULL; - SalAddress* service_route = NULL; /*as defined by rfc3608, might be a list*/ - SalCustomHeader *sent_custom_headers = NULL; - SalCustomHeader *recv_custom_headers = NULL; - char* entity_tag = NULL; /*as defined by rfc3903 (I.E publih)*/ - ReleaseCb release_cb = NULL; + Sal *mRoot = nullptr; + std::string mRoute; // Or request-uri for REGISTER + std::list mRouteAddresses; + SalAddress *mContactAddress = nullptr; + std::string mSubject; + std::string mFrom; + SalAddress* mFromAddress = nullptr; + std::string mTo; + SalAddress *mToAddress = nullptr; + std::string mOrigin; + SalAddress *mOriginAddress = nullptr; + SalAddress *mDiversionAddress = nullptr; + std::string mRemoteUserAgent; + SalAddress *mRemoteContactAddress = nullptr; + std::string mRemoteContact; + void *mUserPointer = nullptr; + std::string mCallId; + std::string mRealm; + SalAddress *mServiceRoute = nullptr; // As defined by rfc3608, might be a list + SalCustomHeader *mSentCustomHeaders = nullptr; + SalCustomHeader *mRecvCustomHeaders = nullptr; + std::string mEntityTag; // As defined by rfc3903 (I.E publih) + ReleaseCb mReleaseCb = nullptr; - // BelleSip implementation - const belle_sip_listener_callbacks_t *callbacks = NULL; - SalErrorInfo error_info; - SalErrorInfo reason_error_info; - belle_sip_client_transaction_t *pending_auth_transaction = NULL; - belle_sip_server_transaction_t* pending_server_trans = NULL; - belle_sip_server_transaction_t* pending_update_server_trans = NULL; - belle_sip_client_transaction_t* pending_client_trans = NULL; - SalAuthInfo* auth_info = NULL; - belle_sip_dialog_t* dialog = NULL; - belle_sip_header_replaces_t *replaces = NULL; - belle_sip_header_referred_by_t *referred_by = NULL; - SalMediaDescription *result = NULL; - belle_sdp_session_description_t *sdp_answer = NULL; - State state = State::Early; - Dir dir = Dir::Incoming; - belle_sip_refresher_t* refresher = NULL; - int _ref = 0; - Type type = Type::Unknown; - SalPrivacyMask privacy = SalPrivacyNone; - belle_sip_header_event_t *event = NULL; /*used by SalOpSubscribe kinds*/ - SalOpSDPHandling sdp_handling = SalOpSDPNormal; - int auth_requests = 0; /*number of auth requested for this op*/ - bool_t _cnx_ip_to_0000_if_sendonly_enabled = FALSE; - bool_t auto_answer_asked = FALSE; - bool_t sdp_offering = FALSE; - bool_t call_released = FALSE; - bool_t manual_refresher = FALSE; - bool_t has_auth_pending = FALSE; - bool_t supports_session_timers = FALSE; - bool_t op_released = FALSE; + const belle_sip_listener_callbacks_t *mCallbacks = nullptr; + SalErrorInfo mErrorInfo; + SalErrorInfo mReasonErrorInfo; + belle_sip_client_transaction_t *mPendingAuthTransaction = nullptr; + belle_sip_server_transaction_t *mPendingServerTransaction = nullptr; + belle_sip_server_transaction_t *mPendingUpdateServerTransaction = nullptr; + belle_sip_client_transaction_t *mPendingClientTransaction = nullptr; + SalAuthInfo *mAuthInfo = nullptr; + belle_sip_dialog_t *mDialog = nullptr; + belle_sip_header_replaces_t *mReplaces = nullptr; + belle_sip_header_referred_by_t *mReferredBy = nullptr; + SalMediaDescription *mResult = nullptr; + belle_sdp_session_description_t *mSdpAnswer = nullptr; + State mState = State::Early; + Dir mDir = Dir::Incoming; + belle_sip_refresher_t *mRefresher = nullptr; + int mRef = 0; + Type mType = Type::Unknown; + SalPrivacyMask mPrivacy = SalPrivacyNone; + belle_sip_header_event_t *mEvent = nullptr; // Used by SalOpSubscribe kinds + SalOpSDPHandling mSdpHandling = SalOpSDPNormal; + int mAuthRequests = 0; // number of auth requested for this op + bool mCnxIpTo0000IfSendOnlyEnabled = false; + bool mAutoAnswerAsked = false; + bool mSdpOffering = false; + bool mCallReleased = false; + bool mManualRefresher = false; + bool mHasAuthPending = false; + bool mSupportsSessionTimers = false; + bool mOpReleased = false; friend class Sal; }; diff --git a/src/sal/presence-op.cpp b/src/sal/presence-op.cpp index 641352506..4ba469ebd 100644 --- a/src/sal/presence-op.cpp +++ b/src/sal/presence-op.cpp @@ -17,13 +17,14 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include "c-wrapper/internal/c-tools.h" #include "sal/presence-op.h" using namespace std; LINPHONE_BEGIN_NAMESPACE -void SalPresenceOp::presence_process_io_error_cb(void *user_ctx, const belle_sip_io_error_event_t *event) { +void SalPresenceOp::presenceProcessIoErrorCb(void *user_ctx, const belle_sip_io_error_event_t *event) { SalPresenceOp * op = (SalPresenceOp *)user_ctx; belle_sip_request_t* request; belle_sip_client_transaction_t* client_transaction = NULL; @@ -38,32 +39,32 @@ void SalPresenceOp::presence_process_io_error_cb(void *user_ctx, const belle_sip request = belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(client_transaction)); if (strcmp("SUBSCRIBE",belle_sip_request_get_method(request))==0){ - if (op->refresher){ + if (op->mRefresher){ ms_warning("presence_process_io_error() refresher is present, should not happen"); return; } - ms_message("subscription to [%s] io error",op->get_to()); - if (!op->op_released){ - op->root->callbacks.notify_presence(op,SalSubscribeTerminated, NULL,NULL); /*NULL = offline*/ + ms_message("subscription to [%s] io error",op->getTo().c_str()); + if (!op->mOpReleased){ + op->mRoot->mCallbacks.notify_presence(op,SalSubscribeTerminated, NULL,NULL); /*NULL = offline*/ } } } -void SalPresenceOp::presence_refresher_listener_cb(belle_sip_refresher_t* refresher, void* user_pointer, unsigned int status_code, const char* reason_phrase, int will_retry) { +void SalPresenceOp::presenceRefresherListenerCb(belle_sip_refresher_t* refresher, void* user_pointer, unsigned int status_code, const char* reason_phrase, int will_retry) { SalPresenceOp * op = (SalPresenceOp *)user_pointer; if (status_code >= 300) { ms_message("The SUBSCRIBE dialog no longer works. Let's restart a new one."); - belle_sip_refresher_stop(op->refresher); - if (op->dialog) { /*delete previous dialog if any*/ - op->set_or_update_dialog(NULL); + belle_sip_refresher_stop(op->mRefresher); + if (op->mDialog) { /*delete previous dialog if any*/ + op->setOrUpdateDialog(NULL); } - if (op->get_contact_address()) { + if (op->getContactAddress()) { /*contact is also probably not good*/ - SalAddress* contact=sal_address_clone(op->get_contact_address()); + SalAddress* contact=sal_address_clone(op->getContactAddress()); sal_address_set_port(contact,-1); sal_address_set_domain(contact,NULL); - op->set_contact_address(contact); + op->setContactAddress(contact); sal_address_destroy(contact); } /*send a new SUBSCRIBE, that will attempt to establish a new dialog*/ @@ -71,13 +72,13 @@ void SalPresenceOp::presence_refresher_listener_cb(belle_sip_refresher_t* refres } if (status_code == 0 || status_code == 503){ /*timeout or io error: the remote doesn't seem reachable.*/ - if (!op->op_released){ - op->root->callbacks.notify_presence(op,SalSubscribeActive, NULL,NULL); /*NULL = offline*/ + if (!op->mOpReleased){ + op->mRoot->mCallbacks.notify_presence(op,SalSubscribeActive, NULL,NULL); /*NULL = offline*/ } } } -void SalPresenceOp::presence_response_event_cb(void *op_base, const belle_sip_response_event_t *event) { +void SalPresenceOp::presenceResponseEventCb(void *op_base, const belle_sip_response_event_t *event) { SalPresenceOp * op = (SalPresenceOp *)op_base; belle_sip_dialog_state_t dialog_state; belle_sip_client_transaction_t* client_transaction = belle_sip_response_event_get_client_transaction(event); @@ -86,23 +87,23 @@ void SalPresenceOp::presence_response_event_cb(void *op_base, const belle_sip_re int code = belle_sip_response_get_status_code(response); belle_sip_header_expires_t* expires; - op->set_error_info_from_response(response); + op->setErrorInfoFromResponse(response); if (code>=300) { if (strcmp("SUBSCRIBE",belle_sip_request_get_method(request))==0){ - ms_message("subscription to [%s] rejected",op->get_to()); - if (!op->op_released){ - op->root->callbacks.notify_presence(op,SalSubscribeTerminated, NULL,NULL); /*NULL = offline*/ + ms_message("subscription to [%s] rejected",op->getTo().c_str()); + if (!op->mOpReleased){ + op->mRoot->mCallbacks.notify_presence(op,SalSubscribeTerminated, NULL,NULL); /*NULL = offline*/ } return; } } - op->set_or_update_dialog(belle_sip_response_event_get_dialog(event)); - if (!op->dialog) { + op->setOrUpdateDialog(belle_sip_response_event_get_dialog(event)); + if (!op->mDialog) { ms_message("presence op [%p] receive out of dialog answer [%i]",op,code); return; } - dialog_state=belle_sip_dialog_get_state(op->dialog); + dialog_state=belle_sip_dialog_get_state(op->mDialog); switch(dialog_state) { case BELLE_SIP_DIALOG_NULL: @@ -113,15 +114,15 @@ void SalPresenceOp::presence_response_event_cb(void *op_base, const belle_sip_re case BELLE_SIP_DIALOG_CONFIRMED: { if (strcmp("SUBSCRIBE",belle_sip_request_get_method(request))==0) { expires=belle_sip_message_get_header_by_type(request,belle_sip_header_expires_t); - if(op->refresher) { - belle_sip_refresher_stop(op->refresher); - belle_sip_object_unref(op->refresher); - op->refresher=NULL; + if(op->mRefresher) { + belle_sip_refresher_stop(op->mRefresher); + belle_sip_object_unref(op->mRefresher); + op->mRefresher=NULL; } if ((expires != NULL) && (belle_sip_header_expires_get_expires(expires) > 0)) { - op->refresher=belle_sip_client_transaction_create_refresher(client_transaction); - belle_sip_refresher_set_listener(op->refresher,presence_refresher_listener_cb,op); - belle_sip_refresher_set_realm(op->refresher,op->realm); + op->mRefresher=belle_sip_client_transaction_create_refresher(client_transaction); + belle_sip_refresher_set_listener(op->mRefresher,presenceRefresherListenerCb,op); + belle_sip_refresher_set_realm(op->mRefresher,L_STRING_TO_C(op->mRealm)); } } break; @@ -133,7 +134,7 @@ void SalPresenceOp::presence_response_event_cb(void *op_base, const belle_sip_re } } -void SalPresenceOp::presence_process_timeout_cb(void *user_ctx, const belle_sip_timeout_event_t *event) { +void SalPresenceOp::presenceProcessTimeoutCb(void *user_ctx, const belle_sip_timeout_event_t *event) { SalPresenceOp * op = (SalPresenceOp *)user_ctx; belle_sip_client_transaction_t* client_transaction = belle_sip_timeout_event_get_client_transaction(event); belle_sip_request_t* request; @@ -143,18 +144,18 @@ void SalPresenceOp::presence_process_timeout_cb(void *user_ctx, const belle_sip_ request = belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(client_transaction)); if (strcmp("SUBSCRIBE",belle_sip_request_get_method(request))==0){ - ms_message("subscription to [%s] timeout",op->get_to()); - if (!op->op_released){ - op->root->callbacks.notify_presence(op,SalSubscribeTerminated, NULL,NULL); /*NULL = offline*/ + ms_message("subscription to [%s] timeout",op->getTo().c_str()); + if (!op->mOpReleased){ + op->mRoot->mCallbacks.notify_presence(op,SalSubscribeTerminated, NULL,NULL); /*NULL = offline*/ } } } -void SalPresenceOp::presence_process_transaction_terminated_cb(void *user_ctx, const belle_sip_transaction_terminated_event_t *event) { +void SalPresenceOp::presenceProcessTransactionTerminatedCb(void *user_ctx, const belle_sip_transaction_terminated_event_t *event) { ms_message("presence_process_transaction_terminated not implemented yet"); } -SalPresenceModel *SalPresenceOp::process_presence_notification(belle_sip_request_t *req) { +SalPresenceModel *SalPresenceOp::processPresenceNotification(belle_sip_request_t *req) { belle_sip_header_content_type_t *content_type = belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req), belle_sip_header_content_type_t); belle_sip_header_content_length_t *content_length = belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req), belle_sip_header_content_length_t); const char *body = belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)); @@ -166,8 +167,8 @@ SalPresenceModel *SalPresenceOp::process_presence_notification(belle_sip_request return NULL; if (body==NULL) return NULL; - if (!this->op_released){ - this->root->callbacks.parse_presence_requested(this, + if (!mOpReleased){ + mRoot->mCallbacks.parse_presence_requested(this, belle_sip_header_content_type_get_type(content_type), belle_sip_header_content_type_get_subtype(content_type), body, @@ -177,9 +178,9 @@ SalPresenceModel *SalPresenceOp::process_presence_notification(belle_sip_request return result; } -void SalPresenceOp::handle_notify(belle_sip_request_t *req, belle_sip_dialog_t *dialog) { +void SalPresenceOp::handleNotify(belle_sip_request_t *req, belle_sip_dialog_t *dialog) { belle_sip_response_t* resp=NULL; - belle_sip_server_transaction_t* server_transaction= this->pending_server_trans; + belle_sip_server_transaction_t* server_transaction= mPendingServerTransaction; belle_sip_header_subscription_state_t* subscription_state_header=belle_sip_message_get_header_by_type(req,belle_sip_header_subscription_state_t); SalSubscribeStatus sub_state; @@ -187,100 +188,100 @@ void SalPresenceOp::handle_notify(belle_sip_request_t *req, belle_sip_dialog_t * SalPresenceModel *presence_model = NULL; const char* body = belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)); - if (this->dialog !=NULL && dialog != this->dialog){ - ms_warning("Receiving a NOTIFY from a dialog we haven't stored (op->dialog=%p dialog=%p)", this->dialog, dialog); + if (mDialog !=NULL && dialog != mDialog){ + ms_warning("Receiving a NOTIFY from a dialog we haven't stored (op->dialog=%p dialog=%p)", mDialog, dialog); } if (!subscription_state_header || strcasecmp(BELLE_SIP_SUBSCRIPTION_STATE_TERMINATED,belle_sip_header_subscription_state_get_state(subscription_state_header)) ==0) { sub_state=SalSubscribeTerminated; - ms_message("Outgoing subscription terminated by remote [%s]",get_to()); + ms_message("Outgoing subscription terminated by remote [%s]",getTo().c_str()); } else { - sub_state=belle_sip_message_get_subscription_state(BELLE_SIP_MESSAGE(req)); + sub_state=getSubscriptionState(BELLE_SIP_MESSAGE(req)); } - presence_model = process_presence_notification(req); + presence_model = processPresenceNotification(req); if (presence_model != NULL || body==NULL) { /* Presence notification body parsed successfully. */ - resp = create_response_from_request(req, 200); /*create first because the op may be destroyed by notify_presence */ - if (!this->op_released){ - this->root->callbacks.notify_presence(this, sub_state, presence_model, NULL); + resp = createResponseFromRequest(req, 200); /*create first because the op may be destroyed by notify_presence */ + if (!mOpReleased){ + mRoot->mCallbacks.notify_presence(this, sub_state, presence_model, NULL); } } else if (body){ /* Formatting error in presence notification body. */ ms_warning("Wrongly formatted presence document."); - resp = create_response_from_request(req, 488); + resp = createResponseFromRequest(req, 488); } if (resp) belle_sip_server_transaction_send_response(server_transaction,resp); } } -void SalPresenceOp::presence_process_request_event_cb(void *op_base, const belle_sip_request_event_t *event) { +void SalPresenceOp::presenceProcessRequestEventCb(void *op_base, const belle_sip_request_event_t *event) { SalPresenceOp * op = (SalPresenceOp *)op_base; - belle_sip_server_transaction_t* server_transaction = belle_sip_provider_create_server_transaction(op->root->prov,belle_sip_request_event_get_request(event)); + belle_sip_server_transaction_t* server_transaction = belle_sip_provider_create_server_transaction(op->mRoot->mProvider,belle_sip_request_event_get_request(event)); belle_sip_request_t* req = belle_sip_request_event_get_request(event); belle_sip_dialog_state_t dialog_state; belle_sip_response_t* resp; const char *method=belle_sip_request_get_method(req); belle_sip_header_event_t *event_header; belle_sip_object_ref(server_transaction); - if (op->pending_server_trans) belle_sip_object_unref(op->pending_server_trans); - op->pending_server_trans=server_transaction; + if (op->mPendingServerTransaction) belle_sip_object_unref(op->mPendingServerTransaction); + op->mPendingServerTransaction=server_transaction; event_header=belle_sip_message_get_header_by_type(req,belle_sip_header_event_t); if (event_header==NULL){ ms_warning("No event header in incoming SUBSCRIBE."); - resp=op->create_response_from_request(req,400); + resp=op->createResponseFromRequest(req,400); belle_sip_server_transaction_send_response(server_transaction,resp); - if (!op->dialog) op->release(); + if (!op->mDialog) op->release(); return; } - if (op->event==NULL) { - op->event=event_header; - belle_sip_object_ref(op->event); + if (op->mEvent==NULL) { + op->mEvent=event_header; + belle_sip_object_ref(op->mEvent); } - if (!op->dialog) { + if (!op->mDialog) { if (strcmp(method,"SUBSCRIBE")==0){ - belle_sip_dialog_t *dialog = belle_sip_provider_create_dialog(op->root->prov,BELLE_SIP_TRANSACTION(server_transaction)); + belle_sip_dialog_t *dialog = belle_sip_provider_create_dialog(op->mRoot->mProvider,BELLE_SIP_TRANSACTION(server_transaction)); if (!dialog){ - resp=op->create_response_from_request(req,481); + resp=op->createResponseFromRequest(req,481); belle_sip_server_transaction_send_response(server_transaction,resp); op->release(); return; } - op->set_or_update_dialog(dialog); - ms_message("new incoming subscription from [%s] to [%s]",op->get_from(),op->get_to()); + op->setOrUpdateDialog(dialog); + ms_message("new incoming subscription from [%s] to [%s]",op->getFrom().c_str(),op->getTo().c_str()); }else if (strcmp(method,"NOTIFY")==0 && belle_sip_request_event_get_dialog(event)) { /*special case of dialog created by notify matching subscribe*/ - op->set_or_update_dialog(belle_sip_request_event_get_dialog(event)); + op->setOrUpdateDialog(belle_sip_request_event_get_dialog(event)); } else {/* this is a NOTIFY */ ms_message("Receiving out of dialog notify"); - op->handle_notify(req, belle_sip_request_event_get_dialog(event)); + op->handleNotify(req, belle_sip_request_event_get_dialog(event)); return; } } - dialog_state=belle_sip_dialog_get_state(op->dialog); + dialog_state=belle_sip_dialog_get_state(op->mDialog); switch(dialog_state) { case BELLE_SIP_DIALOG_NULL: { if (strcmp("NOTIFY",method)==0) { - op->handle_notify(req, belle_sip_request_event_get_dialog(event)); + op->handleNotify(req, belle_sip_request_event_get_dialog(event)); } else if (strcmp("SUBSCRIBE",method)==0) { - op->root->callbacks.subscribe_presence_received(op,op->get_from()); + op->mRoot->mCallbacks.subscribe_presence_received(op,op->getFrom().c_str()); } break; } case BELLE_SIP_DIALOG_EARLY: - ms_error("unexpected method [%s] for dialog [%p] in state BELLE_SIP_DIALOG_EARLY ",method,op->dialog); + ms_error("unexpected method [%s] for dialog [%p] in state BELLE_SIP_DIALOG_EARLY ",method,op->mDialog); break; case BELLE_SIP_DIALOG_CONFIRMED: if (strcmp("NOTIFY",method)==0) { - op->handle_notify(req, belle_sip_request_event_get_dialog(event)); + op->handleNotify(req, belle_sip_request_event_get_dialog(event)); } else if (strcmp("SUBSCRIBE",method)==0) { /*either a refresh or an unsubscribe. If it is a refresh there is nothing to notify to the app. If it is an unSUBSCRIBE, then the dialog will be terminated shortly, and this will be notified to the app through the dialog_terminated callback.*/ - resp=op->create_response_from_request(req,200); + resp=op->createResponseFromRequest(req,200); belle_sip_server_transaction_send_response(server_transaction,resp); } break; @@ -290,78 +291,78 @@ void SalPresenceOp::presence_process_request_event_cb(void *op_base, const belle } } -void SalPresenceOp::presence_process_dialog_terminated_cb(void *ctx, const belle_sip_dialog_terminated_event_t *event) { +void SalPresenceOp::presenceProcessDialogTerminatedCb(void *ctx, const belle_sip_dialog_terminated_event_t *event) { SalPresenceOp * op= (SalPresenceOp *)ctx; - if (op->dialog && belle_sip_dialog_is_server(op->dialog)) { - ms_message("Incoming subscribtion from [%s] terminated",op->get_from()); - if (!op->op_released){ - op->root->callbacks.subscribe_presence_closed(op, op->get_from()); + if (op->mDialog && belle_sip_dialog_is_server(op->mDialog)) { + ms_message("Incoming subscribtion from [%s] terminated",op->getFrom().c_str()); + if (!op->mOpReleased){ + op->mRoot->mCallbacks.subscribe_presence_closed(op, op->getFrom().c_str()); } - op->set_or_update_dialog(NULL); + op->setOrUpdateDialog(NULL); }/* else client dialog is managed by refresher*/ } -void SalPresenceOp::_release_cb(SalOp *op_base) { +void SalPresenceOp::releaseCb(SalOp *op_base) { SalPresenceOp *op =(SalPresenceOp *)op_base; - if(op->refresher) { - belle_sip_refresher_stop(op->refresher); - belle_sip_object_unref(op->refresher); - op->refresher=NULL; - op->set_or_update_dialog(NULL); /*only if we have refresher. else dialog terminated event will remove association*/ + if(op->mRefresher) { + belle_sip_refresher_stop(op->mRefresher); + belle_sip_object_unref(op->mRefresher); + op->mRefresher=NULL; + op->setOrUpdateDialog(NULL); /*only if we have refresher. else dialog terminated event will remove association*/ } } -void SalPresenceOp::fill_cbs() { +void SalPresenceOp::fillCallbacks() { static belle_sip_listener_callbacks_t op_presence_callbacks={0}; if (op_presence_callbacks.process_request_event==NULL){ - op_presence_callbacks.process_io_error=presence_process_io_error_cb; - op_presence_callbacks.process_response_event=presence_response_event_cb; - op_presence_callbacks.process_timeout= presence_process_timeout_cb; - op_presence_callbacks.process_transaction_terminated=presence_process_transaction_terminated_cb; - op_presence_callbacks.process_request_event=presence_process_request_event_cb; - op_presence_callbacks.process_dialog_terminated=presence_process_dialog_terminated_cb; + op_presence_callbacks.process_io_error=presenceProcessIoErrorCb; + op_presence_callbacks.process_response_event=presenceResponseEventCb; + op_presence_callbacks.process_timeout= presenceProcessTimeoutCb; + op_presence_callbacks.process_transaction_terminated=presenceProcessTransactionTerminatedCb; + op_presence_callbacks.process_request_event=presenceProcessRequestEventCb; + op_presence_callbacks.process_dialog_terminated=presenceProcessDialogTerminatedCb; } - this->callbacks=&op_presence_callbacks; - this->type=Type::Presence; - this->release_cb=_release_cb; + mCallbacks=&op_presence_callbacks; + mType=Type::Presence; + mReleaseCb=releaseCb; } int SalPresenceOp::subscribe(const char *from, const char *to, int expires) { belle_sip_request_t *req=NULL; if (from) - set_from(from); + setFrom(from); if (to) - set_to(to); + setTo(to); - fill_cbs(); + fillCallbacks(); if (expires==-1){ - if (this->refresher){ - expires=belle_sip_refresher_get_expires(this->refresher); - belle_sip_object_unref(this->refresher); - this->refresher=NULL; + if (mRefresher){ + expires=belle_sip_refresher_get_expires(mRefresher); + belle_sip_object_unref(mRefresher); + mRefresher=NULL; }else{ ms_error("sal_subscribe_presence(): cannot guess expires from previous refresher."); return -1; } } - if (!this->event){ - this->event=belle_sip_header_event_create("presence"); - belle_sip_object_ref(this->event); + if (!mEvent){ + mEvent=belle_sip_header_event_create("presence"); + belle_sip_object_ref(mEvent); } - belle_sip_parameters_remove_parameter(BELLE_SIP_PARAMETERS(this->from_address),"tag"); - belle_sip_parameters_remove_parameter(BELLE_SIP_PARAMETERS(this->to_address),"tag"); - req=build_request("SUBSCRIBE"); + belle_sip_parameters_remove_parameter(BELLE_SIP_PARAMETERS(mFromAddress),"tag"); + belle_sip_parameters_remove_parameter(BELLE_SIP_PARAMETERS(mToAddress),"tag"); + req=buildRequest("SUBSCRIBE"); if( req ){ - belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(this->event)); + belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(mEvent)); belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_expires_create(expires))); } - return send_request(req); + return sendRequest(req); } -int SalPresenceOp::check_dialog_state() { - belle_sip_dialog_state_t state= this->dialog?belle_sip_dialog_get_state(this->dialog): BELLE_SIP_DIALOG_NULL; +int SalPresenceOp::checkDialogState() { + belle_sip_dialog_state_t state= mDialog?belle_sip_dialog_get_state(mDialog): BELLE_SIP_DIALOG_NULL; if (state != BELLE_SIP_DIALOG_CONFIRMED) { ms_warning("Cannot notify presence for op [%p] because dialog in state [%s]", this, belle_sip_dialog_state_to_string(state)); return -1; @@ -369,15 +370,15 @@ int SalPresenceOp::check_dialog_state() { return 0; } -belle_sip_request_t *SalPresenceOp::create_presence_notify() { - belle_sip_request_t* notify=belle_sip_dialog_create_queued_request(this->dialog,"NOTIFY"); +belle_sip_request_t *SalPresenceOp::createPresenceNotify() { + belle_sip_request_t* notify=belle_sip_dialog_create_queued_request(mDialog,"NOTIFY"); if (!notify) return NULL; belle_sip_message_add_header((belle_sip_message_t*)notify,belle_sip_header_create("Event","presence")); return notify; } -void SalPresenceOp::add_presence_info(belle_sip_message_t *notify, SalPresenceModel *presence) { +void SalPresenceOp::addPresenceInfo(belle_sip_message_t *notify, SalPresenceModel *presence) { char *contact_info; char *content = NULL; size_t content_length; @@ -385,7 +386,7 @@ void SalPresenceOp::add_presence_info(belle_sip_message_t *notify, SalPresenceMo if (presence){ belle_sip_header_from_t *from=belle_sip_message_get_header_by_type(notify,belle_sip_header_from_t); contact_info=belle_sip_uri_to_string(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from))); - this->root->callbacks.convert_presence_to_xml_requested(this, presence, contact_info, &content); + mRoot->mCallbacks.convert_presence_to_xml_requested(this, presence, contact_info, &content); belle_sip_free(contact_info); if (content == NULL) return; } @@ -404,38 +405,38 @@ void SalPresenceOp::add_presence_info(belle_sip_message_t *notify, SalPresenceMo } } -int SalPresenceOp::notify_presence(SalPresenceModel *presence) { +int SalPresenceOp::notifyPresence(SalPresenceModel *presence) { belle_sip_request_t* notify=NULL; - if (check_dialog_state()) { + if (checkDialogState()) { return -1; } - notify=create_presence_notify(); + notify=createPresenceNotify(); if (!notify) return-1; - add_presence_info(BELLE_SIP_MESSAGE(notify),presence); /*FIXME, what about expires ??*/ + addPresenceInfo(BELLE_SIP_MESSAGE(notify),presence); /*FIXME, what about expires ??*/ belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify) ,BELLE_SIP_HEADER(belle_sip_header_subscription_state_create(BELLE_SIP_SUBSCRIPTION_STATE_ACTIVE,600))); - return send_request(notify); + return sendRequest(notify); } -int SalPresenceOp::notify_presence_close() { +int SalPresenceOp::notifyPresenceClose() { belle_sip_request_t* notify=NULL; int status; - if (check_dialog_state()) { + if (checkDialogState()) { return -1; } - notify=create_presence_notify(); + notify=createPresenceNotify(); if (!notify) return-1; - add_presence_info(BELLE_SIP_MESSAGE(notify),NULL); /*FIXME, what about expires ??*/ + addPresenceInfo(BELLE_SIP_MESSAGE(notify),NULL); /*FIXME, what about expires ??*/ belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify) ,BELLE_SIP_HEADER(belle_sip_header_subscription_state_create(BELLE_SIP_SUBSCRIPTION_STATE_TERMINATED,-1))); - status = send_request(notify); - set_or_update_dialog(NULL); /*because we may be chalanged for the notify, so we must release dialog right now*/ + status = sendRequest(notify); + setOrUpdateDialog(NULL); /*because we may be chalanged for the notify, so we must release dialog right now*/ return status; } -SalSubscribeStatus SalPresenceOp::belle_sip_message_get_subscription_state(const belle_sip_message_t *msg) { +SalSubscribeStatus SalPresenceOp::getSubscriptionState(const belle_sip_message_t *msg) { belle_sip_header_subscription_state_t* subscription_state_header=belle_sip_message_get_header_by_type(msg,belle_sip_header_subscription_state_t); SalSubscribeStatus sss=SalSubscribeNone; if (subscription_state_header){ diff --git a/src/sal/presence-op.h b/src/sal/presence-op.h index d0cf26b9a..72e5238a5 100644 --- a/src/sal/presence-op.h +++ b/src/sal/presence-op.h @@ -24,33 +24,33 @@ LINPHONE_BEGIN_NAMESPACE -class SalPresenceOp: public SalSubscribeOp { +class SalPresenceOp : public SalSubscribeOp { public: - SalPresenceOp(Sal *sal): SalSubscribeOp(sal) {} + SalPresenceOp (Sal *sal) : SalSubscribeOp(sal) {} - int subscribe(const char *from, const char *to, int expires); - int unsubscribe() {return SalOp::unsubscribe();} - int notify_presence(SalPresenceModel *presence); - int notify_presence_close(); + int subscribe (const char *from, const char *to, int expires); + int unsubscribe () { return SalOp::unsubscribe(); } + int notifyPresence (SalPresenceModel *presence); + int notifyPresenceClose (); private: - virtual void fill_cbs() override; - void handle_notify(belle_sip_request_t *req, belle_sip_dialog_t *dialog); - SalPresenceModel * process_presence_notification(belle_sip_request_t *req); - int check_dialog_state(); - belle_sip_request_t *create_presence_notify(); - void add_presence_info(belle_sip_message_t *notify, SalPresenceModel *presence); + virtual void fillCallbacks () override; + void handleNotify (belle_sip_request_t *request, belle_sip_dialog_t *dialog); + SalPresenceModel *processPresenceNotification (belle_sip_request_t *request); + int checkDialogState (); + belle_sip_request_t *createPresenceNotify (); + void addPresenceInfo (belle_sip_message_t *notify, SalPresenceModel *presence); - static SalSubscribeStatus belle_sip_message_get_subscription_state(const belle_sip_message_t *msg); + static SalSubscribeStatus getSubscriptionState (const belle_sip_message_t *message); - static void presence_process_io_error_cb(void *user_ctx, const belle_sip_io_error_event_t *event); - static void presence_response_event_cb(void *op_base, const belle_sip_response_event_t *event); - static void presence_refresher_listener_cb(belle_sip_refresher_t* refresher, void* user_pointer, unsigned int status_code, const char* reason_phrase, int will_retry); - static void presence_process_timeout_cb(void *user_ctx, const belle_sip_timeout_event_t *event); - static void presence_process_transaction_terminated_cb(void *user_ctx, const belle_sip_transaction_terminated_event_t *event); - static void presence_process_request_event_cb(void *op_base, const belle_sip_request_event_t *event); - static void presence_process_dialog_terminated_cb(void *ctx, const belle_sip_dialog_terminated_event_t *event); - static void _release_cb(SalOp *op_base); + static void presenceProcessIoErrorCb (void *userCtx, const belle_sip_io_error_event_t *event); + static void presenceResponseEventCb (void *userCtx, const belle_sip_response_event_t *event); + static void presenceRefresherListenerCb (belle_sip_refresher_t *refresher, void *userCtx, unsigned int statusCode, const char *reasonPhrase, int willRetry); + static void presenceProcessTimeoutCb (void *userCtx, const belle_sip_timeout_event_t *event); + static void presenceProcessTransactionTerminatedCb (void *userCtx, const belle_sip_transaction_terminated_event_t *event); + static void presenceProcessRequestEventCb (void *userCtx, const belle_sip_request_event_t *event); + static void presenceProcessDialogTerminatedCb (void *userCtx, const belle_sip_dialog_terminated_event_t *event); + static void releaseCb (SalOp *op); }; LINPHONE_END_NAMESPACE diff --git a/src/sal/refer-op.cpp b/src/sal/refer-op.cpp index 6cc1b34b1..93d36e1dd 100644 --- a/src/sal/refer-op.cpp +++ b/src/sal/refer-op.cpp @@ -23,38 +23,38 @@ using namespace std; LINPHONE_BEGIN_NAMESPACE -void SalReferOp::process_error() { - this->state=State::Terminated; +void SalReferOp::processError() { + mState=State::Terminated; } -void SalReferOp::process_io_error_cb(void *user_ctx, const belle_sip_io_error_event_t *event) { +void SalReferOp::processIoErrorCb(void *user_ctx, const belle_sip_io_error_event_t *event) { SalReferOp * op = (SalReferOp *)user_ctx; - sal_error_info_set(&op->error_info,SalReasonIOError, "SIP", 503,"IO Error",NULL); - op->process_error(); + sal_error_info_set(&op->mErrorInfo,SalReasonIOError, "SIP", 503,"IO Error",NULL); + op->processError(); } -void SalReferOp::process_response_event_cb(void *op_base, const belle_sip_response_event_t *event) { +void SalReferOp::processResponseEventCb(void *op_base, const belle_sip_response_event_t *event) { SalReferOp * op = (SalReferOp *)op_base; - op->set_error_info_from_response(belle_sip_response_event_get_response(event)); + op->setErrorInfoFromResponse(belle_sip_response_event_get_response(event)); /*the response is not notified to the app*/ /*To be done when necessary*/ } -void SalReferOp::process_timeout_cb(void *user_ctx, const belle_sip_timeout_event_t *event) { +void SalReferOp::processTimeoutCb(void *user_ctx, const belle_sip_timeout_event_t *event) { SalReferOp * op=(SalReferOp *)user_ctx; - sal_error_info_set(&op->error_info,SalReasonRequestTimeout, "SIP", 408,"Request timeout",NULL); - op->process_error(); + sal_error_info_set(&op->mErrorInfo,SalReasonRequestTimeout, "SIP", 408,"Request timeout",NULL); + op->processError(); } -void SalReferOp::process_request_event_cb(void *op_base, const belle_sip_request_event_t *event) { +void SalReferOp::processRequestEventCb(void *op_base, const belle_sip_request_event_t *event) { SalReferOp * op = (SalReferOp *)op_base; belle_sip_request_t *req = belle_sip_request_event_get_request(event); belle_sip_header_refer_to_t *refer_to= belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_refer_to_t); - belle_sip_server_transaction_t *server_transaction = belle_sip_provider_create_server_transaction(op->root->prov,belle_sip_request_event_get_request(event)); + belle_sip_server_transaction_t *server_transaction = belle_sip_provider_create_server_transaction(op->mRoot->mProvider,belle_sip_request_event_get_request(event)); belle_sip_object_ref(server_transaction); belle_sip_transaction_set_application_data(BELLE_SIP_TRANSACTION(server_transaction),op->ref()); - op->pending_server_trans = server_transaction; + op->mPendingServerTransaction = server_transaction; if (!refer_to){ ms_warning("cannot do anything with the refer without destination"); @@ -63,49 +63,49 @@ void SalReferOp::process_request_event_cb(void *op_base, const belle_sip_request return; } SalAddress *referToAddr = sal_address_new(belle_sip_header_get_unparsed_value(BELLE_SIP_HEADER(refer_to))); - op->root->callbacks.refer_received(op, referToAddr); + op->mRoot->mCallbacks.refer_received(op, referToAddr); /*the app is expected to reply in the callback*/ sal_address_unref(referToAddr); op->unref(); } -void SalReferOp::fill_cbs() { +void SalReferOp::fillCallbacks() { static belle_sip_listener_callbacks_t op_refer_callbacks = {0}; if (op_refer_callbacks.process_io_error==NULL) { - op_refer_callbacks.process_io_error=process_io_error_cb; - op_refer_callbacks.process_response_event=process_response_event_cb; - op_refer_callbacks.process_timeout=process_timeout_cb; - op_refer_callbacks.process_request_event=process_request_event_cb; + op_refer_callbacks.process_io_error=processIoErrorCb; + op_refer_callbacks.process_response_event=processResponseEventCb; + op_refer_callbacks.process_timeout=processTimeoutCb; + op_refer_callbacks.process_request_event=processRequestEventCb; } - this->callbacks=&op_refer_callbacks; - this->type=Type::Refer; + mCallbacks=&op_refer_callbacks; + mType=Type::Refer; } SalReferOp::SalReferOp(Sal *sal) : SalOp(sal){ - fill_cbs(); + fillCallbacks(); } -int SalReferOp::send_refer(const SalAddress *refer_to) { - this->dir=Dir::Outgoing; +int SalReferOp::sendRefer(const SalAddress *refer_to) { + mDir=Dir::Outgoing; - belle_sip_request_t* req=build_request("REFER"); + belle_sip_request_t* req=buildRequest("REFER"); if (req == NULL ) return -1; - if (get_contact_address()) belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(create_contact())); + if (getContactAddress()) belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(createContact())); belle_sip_header_address_t *address = BELLE_SIP_HEADER_ADDRESS(refer_to); belle_sip_uri_t *uri = belle_sip_header_address_get_uri(address); if (!belle_sip_uri_get_host(uri)) belle_sip_header_address_set_automatic(address, true); belle_sip_header_refer_to_t *refer_to_header = belle_sip_header_refer_to_create(address); belle_sip_message_add_header(BELLE_SIP_MESSAGE(req), BELLE_SIP_HEADER(refer_to_header)); - return send_request(req); + return sendRequest(req); } int SalReferOp::reply(SalReason reason){ - if (this->pending_server_trans){ + if (mPendingServerTransaction){ int code=to_sip_code(reason); belle_sip_response_t *resp = belle_sip_response_create_from_request( - belle_sip_transaction_get_request((belle_sip_transaction_t*)this->pending_server_trans),code); - belle_sip_server_transaction_send_response(this->pending_server_trans,resp); + belle_sip_transaction_get_request((belle_sip_transaction_t*)mPendingServerTransaction),code); + belle_sip_server_transaction_send_response(mPendingServerTransaction,resp); return 0; }else ms_error("SalReferOp::reply: no server transaction"); return -1; diff --git a/src/sal/refer-op.h b/src/sal/refer-op.h index c69b4e362..74300e7f9 100644 --- a/src/sal/refer-op.h +++ b/src/sal/refer-op.h @@ -24,23 +24,23 @@ LINPHONE_BEGIN_NAMESPACE -class SalReferOp: public SalOp{ +class SalReferOp : public SalOp { public: - SalReferOp(Sal *sal); + SalReferOp (Sal *sal); - int send_refer(const SalAddress *refer_to); - int reply(SalReason reason); + int sendRefer (const SalAddress *referTo); + int reply (SalReason reason); private: - virtual void fill_cbs() override; - void process_error(); + virtual void fillCallbacks () override; + void processError (); - static void process_io_error_cb(void *user_ctx, const belle_sip_io_error_event_t *event); - static void process_response_event_cb(void *op_base, const belle_sip_response_event_t *event); - static void process_timeout_cb(void *user_ctx, const belle_sip_timeout_event_t *event); - static void process_request_event_cb(void *op_base, const belle_sip_request_event_t *event); + static void processIoErrorCb (void *userCtx, const belle_sip_io_error_event_t *event); + static void processResponseEventCb (void *userCtx, const belle_sip_response_event_t *event); + static void processTimeoutCb (void *userCtx, const belle_sip_timeout_event_t *event); + static void processRequestEventCb (void *userCtx, const belle_sip_request_event_t *event); }; LINPHONE_END_NAMESPACE -#endif // ifndef _L_SAL_MESSAGE_OP_H_ +#endif // ifndef _L_SAL_REFER_OP_H_ diff --git a/src/sal/register-op.cpp b/src/sal/register-op.cpp index 4552bddf8..63c0e8759 100644 --- a/src/sal/register-op.cpp +++ b/src/sal/register-op.cpp @@ -24,31 +24,31 @@ using namespace std; LINPHONE_BEGIN_NAMESPACE -int SalRegisterOp::register_(const char *proxy, const char *from, int expires, const SalAddress* old_contact) { +int SalRegisterOp::sendRegister(const char *proxy, const char *from, int expires, const SalAddress* old_contact) { belle_sip_request_t *req; belle_sip_uri_t* req_uri; belle_sip_header_t* accept_header; - if (this->refresher){ - belle_sip_refresher_stop(this->refresher); - belle_sip_object_unref(this->refresher); - this->refresher=NULL; + if (mRefresher){ + belle_sip_refresher_stop(mRefresher); + belle_sip_object_unref(mRefresher); + mRefresher=NULL; } - this->type=Type::Register; - set_from(from); - set_to(from); - set_route(proxy); - req = build_request("REGISTER"); + mType=Type::Register; + setFrom(from); + setTo(from); + setRoute(proxy); + req = buildRequest("REGISTER"); req_uri = belle_sip_request_get_uri(req); belle_sip_uri_set_user(req_uri,NULL); /*remove userinfo if any*/ - if (this->root->_use_dates) { + if (mRoot->mUseDates) { time_t curtime=time(NULL); belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_date_create_from_time(&curtime))); } accept_header = belle_sip_header_create("Accept", "application/sdp, text/plain, application/vnd.gsma.rcs-ft-http+xml"); belle_sip_message_add_header(BELLE_SIP_MESSAGE(req), accept_header); - belle_sip_message_set_header(BELLE_SIP_MESSAGE(req),(belle_sip_header_t*)create_contact()); + belle_sip_message_set_header(BELLE_SIP_MESSAGE(req),(belle_sip_header_t*)createContact()); if (old_contact) { belle_sip_header_contact_t *contact=belle_sip_header_contact_create((const belle_sip_header_address_t *)old_contact); if (contact) { @@ -62,22 +62,22 @@ int SalRegisterOp::register_(const char *proxy, const char *from, int expires, c ms_error("Cannot add old contact header to op [%p]",this); } } - return send_and_create_refresher(req,expires,register_refresher_listener); + return sendRequestAndCreateRefresher(req,expires,registerRefresherListener); } -void SalRegisterOp::register_refresher_listener(belle_sip_refresher_t* refresher, void* user_pointer, unsigned int status_code, const char* reason_phrase, int will_retry) { +void SalRegisterOp::registerRefresherListener(belle_sip_refresher_t* refresher, void* user_pointer, unsigned int status_code, const char* reason_phrase, int will_retry) { SalRegisterOp * op = (SalRegisterOp *)user_pointer; belle_sip_response_t* response=belle_sip_transaction_get_response(BELLE_SIP_TRANSACTION(belle_sip_refresher_get_transaction(refresher))); - ms_message("Register refresher [%i] reason [%s] for proxy [%s]",status_code,reason_phrase,op->get_proxy()); + ms_message("Register refresher [%i] reason [%s] for proxy [%s]",status_code,reason_phrase,op->getProxy().c_str()); if (belle_sip_refresher_get_auth_events(refresher)) { - if (op->auth_info) sal_auth_info_delete(op->auth_info); + if (op->mAuthInfo) sal_auth_info_delete(op->mAuthInfo); /*only take first one for now*/ - op->auth_info=sal_auth_info_create((belle_sip_auth_event_t*)(belle_sip_refresher_get_auth_events(refresher)->data)); + op->mAuthInfo=sal_auth_info_create((belle_sip_auth_event_t*)(belle_sip_refresher_get_auth_events(refresher)->data)); } - sal_error_info_set(&op->error_info,SalReasonUnknown, "SIP", (int)status_code, reason_phrase, NULL); + sal_error_info_set(&op->mErrorInfo,SalReasonUnknown, "SIP", (int)status_code, reason_phrase, NULL); if (status_code>=200){ - op->assign_recv_headers((belle_sip_message_t*)response); + op->assignRecvHeaders((belle_sip_message_t*)response); } if(status_code == 200) { /*check service route rfc3608*/ @@ -87,24 +87,24 @@ void SalRegisterOp::register_refresher_listener(belle_sip_refresher_t* refresher if ((service_route=belle_sip_message_get_header_by_type(response,belle_sip_header_service_route_t))) { service_route_address=belle_sip_header_address_create(NULL,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(service_route))); } - op->set_service_route((const SalAddress*)service_route_address); + op->setServiceRoute((const SalAddress*)service_route_address); if (service_route_address) belle_sip_object_unref(service_route_address); - op->root->remove_pending_auth(op); /*just in case*/ + op->mRoot->removePendingAuth(op); /*just in case*/ if (contact) { 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); - op->set_contact_address((SalAddress*)belle_sip_header_address_parse(unquoted)); + op->setContactAddress((SalAddress*)belle_sip_header_address_parse(unquoted)); bctbx_free(unquoted); belle_sip_parameters_remove_parameter(p, "pub-gruu"); } else { - op->set_contact_address((SalAddress*)(BELLE_SIP_HEADER_ADDRESS(contact))); /*update contact with real value*/ + op->setContactAddress((SalAddress*)(BELLE_SIP_HEADER_ADDRESS(contact))); /*update contact with real value*/ } } - op->root->callbacks.register_success(op,belle_sip_refresher_get_expires(op->refresher)>0); + op->mRoot->mCallbacks.register_success(op,belle_sip_refresher_get_expires(op->mRefresher)>0); } else if (status_code>=400) { /* from rfc3608, 6.1. If the UA refreshes the registration, the stored value of the Service- @@ -115,14 +115,14 @@ void SalRegisterOp::register_refresher_listener(belle_sip_refresher_t* refresher request is refused or if an existing registration expires and the UA chooses not to re-register, the UA SHOULD discard any stored service route for that address-of-record. */ - op->set_service_route(NULL); + op->setServiceRoute(NULL); op->ref(); /*take a ref while invoking the callback to make sure the operations done after are valid*/ - op->root->callbacks.register_failure(op); - if (op->state!=State::Terminated && op->auth_info) { + op->mRoot->mCallbacks.register_failure(op); + if (op->mState!=State::Terminated && op->mAuthInfo) { /*add pending auth*/ - op->root->add_pending_auth(op); + op->mRoot->addPendingAuth(op); if (status_code==403 || status_code==401 || status_code==407 ) - op->root->callbacks.auth_failure(op,op->auth_info); + op->mRoot->mCallbacks.auth_failure(op,op->mAuthInfo); } op->unref(); } diff --git a/src/sal/register-op.h b/src/sal/register-op.h index d14b9612a..e7e06791c 100644 --- a/src/sal/register-op.h +++ b/src/sal/register-op.h @@ -24,19 +24,22 @@ LINPHONE_BEGIN_NAMESPACE -class SalRegisterOp: public SalOp { +class SalRegisterOp : public SalOp { public: - SalRegisterOp(Sal *sal): SalOp(sal) {} + SalRegisterOp(Sal *sal) : SalOp(sal) {} - int register_(const char *proxy, const char *from, int expires, const SalAddress* old_contact); - int register_refresh(int expires) {return this->refresher ? belle_sip_refresher_refresh(this->refresher,expires) : -1;} - int unregister() {return register_refresh(0);} + int sendRegister (const char *proxy, const char *from, int expires, const SalAddress *oldContact); + int refreshRegister (int expires) { + return mRefresher ? belle_sip_refresher_refresh(mRefresher, expires) : -1; + } + int unregister() { return refreshRegister(0); } - virtual void authenticate(const SalAuthInfo *info) override {register_refresh(-1);} + void authenticate (const SalAuthInfo *info) override { + refreshRegister(-1); } private: - virtual void fill_cbs() override {}; - static void register_refresher_listener(belle_sip_refresher_t* refresher, void* user_pointer, unsigned int status_code, const char* reason_phrase, int will_retry); + virtual void fillCallbacks () override {}; + static void registerRefresherListener (belle_sip_refresher_t *refresher, void *userCtx, unsigned int statusCode, const char *reasonPhrase, int willRetry); }; LINPHONE_END_NAMESPACE diff --git a/src/sal/sal.cpp b/src/sal/sal.cpp index a25236587..ac3db4c15 100644 --- a/src/sal/sal.cpp +++ b/src/sal/sal.cpp @@ -17,6 +17,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include + #include "sal/sal.h" #include "sal/call-op.h" #include "sal/presence-op.h" @@ -27,30 +29,32 @@ #include "tester_utils.h" #include "private.h" +#include "c-wrapper/internal/c-tools.h" + using namespace std; LINPHONE_BEGIN_NAMESPACE -void Sal::process_dialog_terminated_cb(void *sal, const belle_sip_dialog_terminated_event_t *event) { +void Sal::processDialogTerminatedCb(void *sal, const belle_sip_dialog_terminated_event_t *event) { belle_sip_dialog_t* dialog = belle_sip_dialog_terminated_event_get_dialog(event); SalOp* op = reinterpret_cast(belle_sip_dialog_get_application_data(dialog)); - if (op && op->callbacks && op->callbacks->process_dialog_terminated) { - op->callbacks->process_dialog_terminated(op,event); + if (op && op->mCallbacks && op->mCallbacks->process_dialog_terminated) { + op->mCallbacks->process_dialog_terminated(op,event); } else { ms_error("sal process_dialog_terminated no op found for this dialog [%p], ignoring",dialog); } } -void Sal::process_io_error_cb(void *user_ctx, const belle_sip_io_error_event_t *event){ +void Sal::processIoErrorCb(void *user_ctx, const belle_sip_io_error_event_t *event){ belle_sip_client_transaction_t*client_transaction; SalOp* op; if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(belle_sip_io_error_event_get_source(event),belle_sip_client_transaction_t)) { client_transaction=BELLE_SIP_CLIENT_TRANSACTION(belle_sip_io_error_event_get_source(event)); op = (SalOp*)belle_sip_transaction_get_application_data(BELLE_SIP_TRANSACTION(client_transaction)); /*also reset auth count on IO error*/ - op->auth_requests=0; - if (op->callbacks && op->callbacks->process_io_error) { - op->callbacks->process_io_error(op,event); + op->mAuthRequests=0; + if (op->mCallbacks && op->mCallbacks->process_io_error) { + op->mCallbacks->process_io_error(op,event); } } else { /*ms_error("sal process_io_error not implemented yet for non transaction");*/ @@ -58,7 +62,7 @@ void Sal::process_io_error_cb(void *user_ctx, const belle_sip_io_error_event_t * } } -void Sal::process_request_event_cb (void *ud, const belle_sip_request_event_t *event) { +void Sal::processRequestEventCb (void *ud, const belle_sip_request_event_t *event) { Sal *sal = (Sal *)ud; SalOp *op = NULL; belle_sip_request_t *req = belle_sip_request_event_get_request(event); @@ -84,7 +88,7 @@ void Sal::process_request_event_cb (void *ud, const belle_sip_request_event_t *e belle_sip_transaction_t * sub_trans = belle_sip_dialog_get_last_transaction(dialog); op = (SalOp*)belle_sip_transaction_get_application_data(sub_trans); } - if (op == NULL || op->state == SalOp::State::Terminated){ + if (op == NULL || op->mState == SalOp::State::Terminated){ ms_warning("Receiving request for null or terminated op [%p], ignored",op); return; } @@ -94,7 +98,7 @@ void Sal::process_request_event_cb (void *ud, const belle_sip_request_event_t *e if ((strcmp("INVITE",method)==0 || strcmp("NOTIFY",method)==0) && (belle_sip_header_to_get_tag(to) != NULL)) { ms_warning("Receiving %s with to-tag but no know dialog here. Rejecting.", method); resp=belle_sip_response_create_from_request(req,481); - belle_sip_provider_send_response(sal->prov,resp); + belle_sip_provider_send_response(sal->mProvider,resp); return; /* by default (eg. when a to-tag is present), out of dialog ACK are automatically handled in lower layers (belle-sip) but in case it misses, it will be forwarded to us */ @@ -105,52 +109,52 @@ void Sal::process_request_event_cb (void *ud, const belle_sip_request_event_t *e if (strcmp("INVITE",method)==0) { op=new SalCallOp(sal); - op->fill_cbs(); + op->fillCallbacks(); }else if ((strcmp("SUBSCRIBE",method)==0 || strcmp("NOTIFY",method)==0) && (evh=belle_sip_message_get_header(BELLE_SIP_MESSAGE(req),"Event"))!=NULL) { if (strncmp(belle_sip_header_get_unparsed_value(evh),"presence",strlen("presence"))==0){ op=new SalPresenceOp(sal); } else { op=new SalSubscribeOp(sal); } - op->fill_cbs(); + op->fillCallbacks(); }else if (strcmp("MESSAGE",method)==0) { op=new SalMessageOp(sal); - op->fill_cbs(); + op->fillCallbacks(); }else if (strcmp("REFER",method)==0) { op=new SalReferOp(sal); }else if (strcmp("OPTIONS",method)==0) { resp=belle_sip_response_create_from_request(req,200); - belle_sip_provider_send_response(sal->prov,resp); + belle_sip_provider_send_response(sal->mProvider,resp); return; }else if (strcmp("INFO",method)==0) { resp=belle_sip_response_create_from_request(req,481);/*INFO out of call dialogs are not allowed*/ - belle_sip_provider_send_response(sal->prov,resp); + belle_sip_provider_send_response(sal->mProvider,resp); return; }else if (strcmp("BYE",method)==0) { resp=belle_sip_response_create_from_request(req,481);/*out of dialog BYE */ - belle_sip_provider_send_response(sal->prov,resp); + belle_sip_provider_send_response(sal->mProvider,resp); return; }else if (strcmp("CANCEL",method)==0) { resp=belle_sip_response_create_from_request(req,481);/*out of dialog CANCEL */ - belle_sip_provider_send_response(sal->prov,resp); + belle_sip_provider_send_response(sal->mProvider,resp); return; - }else if (sal->_enable_test_features && strcmp("PUBLISH",method)==0) { + }else if (sal->mEnableTestFeatures && strcmp("PUBLISH",method)==0) { resp=belle_sip_response_create_from_request(req,200);/*out of dialog PUBLISH */ belle_sip_message_add_header((belle_sip_message_t*)resp,belle_sip_header_create("SIP-Etag","4441929FFFZQOA")); - belle_sip_provider_send_response(sal->prov,resp); + belle_sip_provider_send_response(sal->mProvider,resp); return; }else { ms_error("sal process_request_event not implemented yet for method [%s]",belle_sip_request_get_method(req)); resp=belle_sip_response_create_from_request(req,405); belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp) ,BELLE_SIP_HEADER(belle_sip_header_allow_create("INVITE, CANCEL, ACK, BYE, SUBSCRIBE, NOTIFY, MESSAGE, OPTIONS, INFO"))); - belle_sip_provider_send_response(sal->prov,resp); + belle_sip_provider_send_response(sal->mProvider,resp); return; } - op->dir=SalOp::Dir::Incoming; + op->mDir=SalOp::Dir::Incoming; } - if (!op->from_address) { + if (!op->mFromAddress) { if (belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from_header))) address=belle_sip_header_address_create(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(from_header)) ,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from_header))); @@ -159,15 +163,15 @@ void Sal::process_request_event_cb (void *ud, const belle_sip_request_event_t *e ,belle_sip_header_address_get_absolute_uri(BELLE_SIP_HEADER_ADDRESS(from_header))); else ms_error("Cannot not find from uri from request [%p]",req); - op->set_from_address((SalAddress*)address); + op->setFromAddress((SalAddress*)address); belle_sip_object_unref(address); } if( remote_contact ){ - op->set_remote_contact(belle_sip_header_get_unparsed_value(BELLE_SIP_HEADER(remote_contact))); + op->setRemoteContact(belle_sip_header_get_unparsed_value(BELLE_SIP_HEADER(remote_contact))); } - if (!op->to_address) { + if (!op->mToAddress) { to=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_to_t); if (belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(to))) address=belle_sip_header_address_create(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(to)) @@ -178,16 +182,16 @@ void Sal::process_request_event_cb (void *ud, const belle_sip_request_event_t *e else ms_error("Cannot not find to uri from request [%p]",req); - op->set_to_address((SalAddress*)address); + op->setToAddress((SalAddress*)address); belle_sip_object_unref(address); } if (subjectHeader) { const char *subject = belle_sip_header_get_unparsed_value(subjectHeader); - op->set_subject(subject); + op->setSubject(subject); } - if(!op->diversion_address){ + if(!op->mDiversionAddress){ diversion=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_diversion_t); if (diversion) { if (belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(diversion))) @@ -199,42 +203,44 @@ void Sal::process_request_event_cb (void *ud, const belle_sip_request_event_t *e else ms_warning("Cannot not find diversion header from request [%p]",req); if (address) { - op->set_diversion_address((SalAddress*)address); + op->setDiversionAddress((SalAddress*)address); belle_sip_object_unref(address); } } } - if (!op->origin) { + if (op->mOrigin.empty()) { /*set origin uri*/ origin_address=belle_sip_header_address_create(NULL,belle_sip_request_extract_origin(req)); - op->set_network_origin_address((SalAddress*)origin_address); + op->setNetworkOriginAddress((SalAddress*)origin_address); belle_sip_object_unref(origin_address); } - if (!op->remote_ua) { - op->set_remote_ua(BELLE_SIP_MESSAGE(req)); + if (op->mRemoteUserAgent.empty()) + op->setRemoteUserAgent(BELLE_SIP_MESSAGE(req)); + + if (op->mCallId.empty()) { + op->mCallId = belle_sip_header_call_id_get_call_id( + BELLE_SIP_HEADER_CALL_ID(belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req), belle_sip_header_call_id_t)) + ); } - if (!op->call_id) { - op->call_id=ms_strdup(belle_sip_header_call_id_get_call_id(BELLE_SIP_HEADER_CALL_ID(belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req), belle_sip_header_call_id_t)))); - } /*It is worth noting that proxies can (and will) remove this header field*/ - op->set_privacy_from_message((belle_sip_message_t*)req); + op->setPrivacyFromMessage((belle_sip_message_t*)req); if (strcmp("ACK",method) != 0){ /*The ACK custom header is processed specifically later on*/ - op->assign_recv_headers((belle_sip_message_t*)req); + op->assignRecvHeaders((belle_sip_message_t*)req); } - if (op->callbacks && op->callbacks->process_request_event) { - op->callbacks->process_request_event(op,event); + if (op->mCallbacks && op->mCallbacks->process_request_event) { + op->mCallbacks->process_request_event(op,event); } else { ms_error("sal process_request_event not implemented yet"); } } -void Sal::process_response_event_cb(void *user_ctx, const belle_sip_response_event_t *event) { +void Sal::processResponseEventCb(void *user_ctx, const belle_sip_response_event_t *event) { belle_sip_client_transaction_t* client_transaction = belle_sip_response_event_get_client_transaction(event); belle_sip_response_t* response = belle_sip_response_event_get_response(event); int response_code = belle_sip_response_get_status_code(response); @@ -247,81 +253,83 @@ void Sal::process_response_event_cb(void *user_ctx, const belle_sip_response_eve belle_sip_request_t* request=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(client_transaction)); belle_sip_header_contact_t* remote_contact = belle_sip_message_get_header_by_type(response, belle_sip_header_contact_t); - if (op->state == SalOp::State::Terminated) { + if (op->mState == SalOp::State::Terminated) { belle_sip_message("Op [%p] is terminated, nothing to do with this [%i]", op, response_code); return; } /*do it all the time, since we can receive provisional responses from a different instance than the final one*/ - op->set_remote_ua(BELLE_SIP_MESSAGE(response)); + op->setRemoteUserAgent(BELLE_SIP_MESSAGE(response)); if(remote_contact) { - op->set_remote_contact(belle_sip_header_get_unparsed_value(BELLE_SIP_HEADER(remote_contact))); + op->setRemoteContact(belle_sip_header_get_unparsed_value(BELLE_SIP_HEADER(remote_contact))); } - if (!op->call_id) { - op->call_id=ms_strdup(belle_sip_header_call_id_get_call_id(BELLE_SIP_HEADER_CALL_ID(belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(response), belle_sip_header_call_id_t)))); + if (op->mCallId.empty()) { + op->mCallId = belle_sip_header_call_id_get_call_id( + BELLE_SIP_HEADER_CALL_ID(belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(response), belle_sip_header_call_id_t)) + ); } - op->assign_recv_headers((belle_sip_message_t*)response); + op->assignRecvHeaders((belle_sip_message_t*)response); - if (op->callbacks && op->callbacks->process_response_event) { + if (op->mCallbacks && op->mCallbacks->process_response_event) { /*handle authorization*/ switch (response_code) { case 200: break; case 401: case 407: - if (op->state == SalOp::State::Terminating && strcmp("BYE",belle_sip_request_get_method(request))!=0) { + if (op->mState == SalOp::State::Terminating && strcmp("BYE",belle_sip_request_get_method(request))!=0) { /*only bye are completed*/ belle_sip_message("Op is in state terminating, nothing else to do "); } else { - if (op->pending_auth_transaction){ - belle_sip_object_unref(op->pending_auth_transaction); - op->pending_auth_transaction=NULL; + if (op->mPendingAuthTransaction){ + belle_sip_object_unref(op->mPendingAuthTransaction); + op->mPendingAuthTransaction=NULL; } - if (++op->auth_requests > 2) { - ms_warning("Auth info cannot be found for op [%s/%s] after 2 attempts, giving up",op->get_from() - ,op->get_to()); - op->root->callbacks.auth_failure(op,op->auth_info); - op->root->remove_pending_auth(op); + if (++op->mAuthRequests > 2) { + ms_warning("Auth info cannot be found for op [%s/%s] after 2 attempts, giving up",op->getFrom().c_str() + ,op->getTo().c_str()); + op->mRoot->mCallbacks.auth_failure(op,op->mAuthInfo); + op->mRoot->removePendingAuth(op); } else { - op->pending_auth_transaction=(belle_sip_client_transaction_t*)belle_sip_object_ref(client_transaction); - op->process_authentication(); + op->mPendingAuthTransaction=(belle_sip_client_transaction_t*)belle_sip_object_ref(client_transaction); + op->processAuthentication(); return; } } break; case 403: - if (op->auth_info) op->root->callbacks.auth_failure(op,op->auth_info); + if (op->mAuthInfo) op->mRoot->mCallbacks.auth_failure(op,op->mAuthInfo); break; case 302: case 301: - if (op->process_redirect() == 0) + if (op->processRedirect() == 0) return; break; } if (response_code >= 180 && response_code !=401 && response_code !=407 && response_code !=403) { /*not an auth request*/ - op->auth_requests=0; + op->mAuthRequests=0; } - op->callbacks->process_response_event(op,event); + op->mCallbacks->process_response_event(op,event); } else { ms_error("Unhandled event response [%p]",event); } } } -void Sal::process_timeout_cb(void *user_ctx, const belle_sip_timeout_event_t *event) { +void Sal::processTimeoutCb(void *user_ctx, const belle_sip_timeout_event_t *event) { belle_sip_client_transaction_t* client_transaction = belle_sip_timeout_event_get_client_transaction(event); SalOp* op = (SalOp*)belle_sip_transaction_get_application_data(BELLE_SIP_TRANSACTION(client_transaction)); - if (op && op->callbacks && op->callbacks->process_timeout) { - op->callbacks->process_timeout(op,event); + if (op && op->mCallbacks && op->mCallbacks->process_timeout) { + op->mCallbacks->process_timeout(op,event); } else { ms_error("Unhandled event timeout [%p]",event); } } -void Sal::process_transaction_terminated_cb(void *user_ctx, const belle_sip_transaction_terminated_event_t *event) { +void Sal::processTransactionTerminatedCb(void *user_ctx, const belle_sip_transaction_terminated_event_t *event) { belle_sip_client_transaction_t* client_transaction = belle_sip_transaction_terminated_event_get_client_transaction(event); belle_sip_server_transaction_t* server_transaction = belle_sip_transaction_terminated_event_get_server_transaction(event); belle_sip_transaction_t* trans; @@ -333,8 +341,8 @@ void Sal::process_transaction_terminated_cb(void *user_ctx, const belle_sip_tran trans=BELLE_SIP_TRANSACTION(server_transaction); op = (SalOp*)belle_sip_transaction_get_application_data(trans); - if (op && op->callbacks && op->callbacks->process_transaction_terminated) { - op->callbacks->process_transaction_terminated(op,event); + if (op && op->mCallbacks && op->mCallbacks->process_transaction_terminated) { + op->mCallbacks->process_transaction_terminated(op,event); } else { ms_message("Unhandled transaction terminated [%p]",trans); } @@ -344,9 +352,9 @@ void Sal::process_transaction_terminated_cb(void *user_ctx, const belle_sip_tran } } -void Sal::process_auth_requested_cb(void *sal, belle_sip_auth_event_t *event) { +void Sal::processAuthRequestedCb(void *sal, belle_sip_auth_event_t *event) { SalAuthInfo* auth_info = sal_auth_info_create(event); - ((Sal*)sal)->callbacks.auth_requested(reinterpret_cast(sal),auth_info); + ((Sal*)sal)->mCallbacks.auth_requested(reinterpret_cast(sal),auth_info); belle_sip_auth_event_set_passwd(event,(const char*)auth_info->password); belle_sip_auth_event_set_ha1(event,(const char*)auth_info->ha1); belle_sip_auth_event_set_userid(event,(const char*)auth_info->userid); @@ -359,117 +367,114 @@ Sal::Sal(MSFactory *factory){ belle_sip_listener_callbacks_t listener_callbacks = {0}; /*belle_sip_object_enable_marshal_check(TRUE);*/ - this->factory = factory; + mFactory = factory; /*first create the stack, which initializes the belle-sip object's pool for this thread*/ - this->stack = belle_sip_stack_new(NULL); + mStack = belle_sip_stack_new(NULL); - this->user_agent=belle_sip_header_user_agent_new(); + mUserAgentHeader=belle_sip_header_user_agent_new(); #if defined(PACKAGE_NAME) && defined(LIBLINPHONE_VERSION) - belle_sip_header_user_agent_add_product(this->user_agent, PACKAGE_NAME "/" LIBLINPHONE_VERSION); + belle_sip_header_user_agent_add_product(user_agent, PACKAGE_NAME "/" LIBLINPHONE_VERSION); #else - belle_sip_header_user_agent_add_product(this->user_agent, "Unknown"); + belle_sip_header_user_agent_add_product(mUserAgentHeader, "Unknown"); #endif - append_stack_string_to_user_agent(); - belle_sip_object_ref(this->user_agent); + appendStackStringToUserAgent(); + belle_sip_object_ref(mUserAgentHeader); - this->prov = belle_sip_stack_create_provider(this->stack,NULL); - enable_nat_helper(TRUE); + mProvider = belle_sip_stack_create_provider(mStack,NULL); + enableNatHelper(TRUE); - listener_callbacks.process_dialog_terminated=process_dialog_terminated_cb; - listener_callbacks.process_io_error=process_io_error_cb; - listener_callbacks.process_request_event=process_request_event_cb; - listener_callbacks.process_response_event=process_response_event_cb; - listener_callbacks.process_timeout=process_timeout_cb; - listener_callbacks.process_transaction_terminated=process_transaction_terminated_cb; - listener_callbacks.process_auth_requested=process_auth_requested_cb; - this->listener=belle_sip_listener_create_from_callbacks(&listener_callbacks, this); - belle_sip_provider_add_sip_listener(this->prov, this->listener); + listener_callbacks.process_dialog_terminated=processDialogTerminatedCb; + listener_callbacks.process_io_error=processIoErrorCb; + listener_callbacks.process_request_event=processRequestEventCb; + listener_callbacks.process_response_event=processResponseEventCb; + listener_callbacks.process_timeout=processTimeoutCb; + listener_callbacks.process_transaction_terminated=processTransactionTerminatedCb; + listener_callbacks.process_auth_requested=processAuthRequestedCb; + mListener=belle_sip_listener_create_from_callbacks(&listener_callbacks, this); + belle_sip_provider_add_sip_listener(mProvider, mListener); } Sal::~Sal() { - belle_sip_object_unref(this->user_agent); - belle_sip_object_unref(this->prov); - belle_sip_object_unref(this->stack); - belle_sip_object_unref(this->listener); - if (this->supported) belle_sip_object_unref(this->supported); - bctbx_list_free_with_data(this->supported_tags,ms_free); - bctbx_list_free_with_data(this->supported_content_types, ms_free); - if (this->uuid) ms_free(this->uuid); - if (this->root_ca) ms_free(this->root_ca); - if (this->root_ca_data) ms_free(this->root_ca_data); - if (this->linphone_specs) ms_free(this->linphone_specs); + belle_sip_object_unref(mUserAgentHeader); + belle_sip_object_unref(mProvider); + belle_sip_object_unref(mStack); + belle_sip_object_unref(mListener); + if (mSupportedHeader) + belle_sip_object_unref(mSupportedHeader); } -void Sal::set_callbacks(const Callbacks *cbs) { - memcpy(&this->callbacks,cbs,sizeof(*cbs)); - if (this->callbacks.call_received==NULL) - this->callbacks.call_received=(OnCallReceivedCb)unimplemented_stub; - if (this->callbacks.call_ringing==NULL) - this->callbacks.call_ringing=(OnCallRingingCb)unimplemented_stub; - if (this->callbacks.call_accepted==NULL) - this->callbacks.call_accepted=(OnCallAcceptedCb)unimplemented_stub; - if (this->callbacks.call_failure==NULL) - this->callbacks.call_failure=(OnCallFailureCb)unimplemented_stub; - if (this->callbacks.call_terminated==NULL) - this->callbacks.call_terminated=(OnCallTerminatedCb)unimplemented_stub; - if (this->callbacks.call_released==NULL) - this->callbacks.call_released=(OnCallReleasedCb)unimplemented_stub; - if (this->callbacks.call_updating==NULL) - this->callbacks.call_updating=(OnCallUpdatingCb)unimplemented_stub; - if (this->callbacks.auth_failure==NULL) - this->callbacks.auth_failure=(OnAuthFailureCb)unimplemented_stub; - if (this->callbacks.register_success==NULL) - this->callbacks.register_success=(OnRegisterSuccessCb)unimplemented_stub; - if (this->callbacks.register_failure==NULL) - this->callbacks.register_failure=(OnRegisterFailureCb)unimplemented_stub; - if (this->callbacks.dtmf_received==NULL) - this->callbacks.dtmf_received=(OnDtmfReceivedCb)unimplemented_stub; - if (this->callbacks.notify==NULL) - this->callbacks.notify=(OnNotifyCb)unimplemented_stub; - if (this->callbacks.subscribe_received==NULL) - this->callbacks.subscribe_received=(OnSubscribeReceivedCb)unimplemented_stub; - if (this->callbacks.incoming_subscribe_closed==NULL) - this->callbacks.incoming_subscribe_closed=(OnIncomingSubscribeClosedCb)unimplemented_stub; - if (this->callbacks.parse_presence_requested==NULL) - this->callbacks.parse_presence_requested=(OnParsePresenceRequestedCb)unimplemented_stub; - if (this->callbacks.convert_presence_to_xml_requested==NULL) - this->callbacks.convert_presence_to_xml_requested=(OnConvertPresenceToXMLRequestedCb)unimplemented_stub; - if (this->callbacks.notify_presence==NULL) - this->callbacks.notify_presence=(OnNotifyPresenceCb)unimplemented_stub; - if (this->callbacks.subscribe_presence_received==NULL) - this->callbacks.subscribe_presence_received=(OnSubscribePresenceReceivedCb)unimplemented_stub; - if (this->callbacks.message_received==NULL) - this->callbacks.message_received=(OnMessageReceivedCb)unimplemented_stub; - if (this->callbacks.ping_reply==NULL) - this->callbacks.ping_reply=(OnPingReplyCb)unimplemented_stub; - if (this->callbacks.auth_requested==NULL) - this->callbacks.auth_requested=(OnAuthRequestedCb)unimplemented_stub; - if (this->callbacks.info_received==NULL) - this->callbacks.info_received=(OnInfoReceivedCb)unimplemented_stub; - if (this->callbacks.on_publish_response==NULL) - this->callbacks.on_publish_response=(OnPublishResponseCb)unimplemented_stub; - if (this->callbacks.on_expire==NULL) - this->callbacks.on_expire=(OnExpireCb)unimplemented_stub; +void Sal::setCallbacks(const Callbacks *cbs) { + memcpy(&mCallbacks,cbs,sizeof(*cbs)); + if (mCallbacks.call_received==NULL) + mCallbacks.call_received=(OnCallReceivedCb)unimplementedStub; + if (mCallbacks.call_ringing==NULL) + mCallbacks.call_ringing=(OnCallRingingCb)unimplementedStub; + if (mCallbacks.call_accepted==NULL) + mCallbacks.call_accepted=(OnCallAcceptedCb)unimplementedStub; + if (mCallbacks.call_failure==NULL) + mCallbacks.call_failure=(OnCallFailureCb)unimplementedStub; + if (mCallbacks.call_terminated==NULL) + mCallbacks.call_terminated=(OnCallTerminatedCb)unimplementedStub; + if (mCallbacks.call_released==NULL) + mCallbacks.call_released=(OnCallReleasedCb)unimplementedStub; + if (mCallbacks.call_updating==NULL) + mCallbacks.call_updating=(OnCallUpdatingCb)unimplementedStub; + if (mCallbacks.auth_failure==NULL) + mCallbacks.auth_failure=(OnAuthFailureCb)unimplementedStub; + if (mCallbacks.register_success==NULL) + mCallbacks.register_success=(OnRegisterSuccessCb)unimplementedStub; + if (mCallbacks.register_failure==NULL) + mCallbacks.register_failure=(OnRegisterFailureCb)unimplementedStub; + if (mCallbacks.dtmf_received==NULL) + mCallbacks.dtmf_received=(OnDtmfReceivedCb)unimplementedStub; + if (mCallbacks.notify==NULL) + mCallbacks.notify=(OnNotifyCb)unimplementedStub; + if (mCallbacks.subscribe_received==NULL) + mCallbacks.subscribe_received=(OnSubscribeReceivedCb)unimplementedStub; + if (mCallbacks.incoming_subscribe_closed==NULL) + mCallbacks.incoming_subscribe_closed=(OnIncomingSubscribeClosedCb)unimplementedStub; + if (mCallbacks.parse_presence_requested==NULL) + mCallbacks.parse_presence_requested=(OnParsePresenceRequestedCb)unimplementedStub; + if (mCallbacks.convert_presence_to_xml_requested==NULL) + mCallbacks.convert_presence_to_xml_requested=(OnConvertPresenceToXMLRequestedCb)unimplementedStub; + if (mCallbacks.notify_presence==NULL) + mCallbacks.notify_presence=(OnNotifyPresenceCb)unimplementedStub; + if (mCallbacks.subscribe_presence_received==NULL) + mCallbacks.subscribe_presence_received=(OnSubscribePresenceReceivedCb)unimplementedStub; + if (mCallbacks.message_received==NULL) + mCallbacks.message_received=(OnMessageReceivedCb)unimplementedStub; + if (mCallbacks.ping_reply==NULL) + mCallbacks.ping_reply=(OnPingReplyCb)unimplementedStub; + if (mCallbacks.auth_requested==NULL) + mCallbacks.auth_requested=(OnAuthRequestedCb)unimplementedStub; + if (mCallbacks.info_received==NULL) + mCallbacks.info_received=(OnInfoReceivedCb)unimplementedStub; + if (mCallbacks.on_publish_response==NULL) + mCallbacks.on_publish_response=(OnPublishResponseCb)unimplementedStub; + if (mCallbacks.on_expire==NULL) + mCallbacks.on_expire=(OnExpireCb)unimplementedStub; } -void Sal::set_tls_properties(){ - belle_sip_listening_point_t *lp=belle_sip_provider_get_listening_point(this->prov,"TLS"); +void Sal::setTlsProperties(){ + belle_sip_listening_point_t *lp=belle_sip_provider_get_listening_point(mProvider,"TLS"); if (lp){ belle_sip_tls_listening_point_t *tlp=BELLE_SIP_TLS_LISTENING_POINT(lp); belle_tls_crypto_config_t *crypto_config = belle_tls_crypto_config_new(); int verify_exceptions = BELLE_TLS_VERIFY_NONE; - if (!this->tls_verify) verify_exceptions = BELLE_TLS_VERIFY_ANY_REASON; - else if (!this->tls_verify_cn) verify_exceptions = BELLE_TLS_VERIFY_CN_MISMATCH; + if (!mTlsVerify) verify_exceptions = BELLE_TLS_VERIFY_ANY_REASON; + else if (!mTlsVerifyCn) verify_exceptions = BELLE_TLS_VERIFY_CN_MISMATCH; belle_tls_crypto_config_set_verify_exceptions(crypto_config, verify_exceptions); - if (this->root_ca != NULL) belle_tls_crypto_config_set_root_ca(crypto_config, this->root_ca); - if (this->root_ca_data != NULL) belle_tls_crypto_config_set_root_ca_data(crypto_config, this->root_ca_data); - if (this->ssl_config != NULL) belle_tls_crypto_config_set_ssl_config(crypto_config, this->ssl_config); + if (!mRootCa.empty()) + belle_tls_crypto_config_set_root_ca(crypto_config, mRootCa.c_str()); + if (!mRootCaData.empty()) + belle_tls_crypto_config_set_root_ca_data(crypto_config, mRootCaData.c_str()); + if (mSslConfig != NULL) belle_tls_crypto_config_set_ssl_config(crypto_config, mSslConfig); belle_sip_tls_listening_point_set_crypto_config(tlp, crypto_config); belle_sip_object_unref(crypto_config); } } -int Sal::add_listen_port(SalAddress* addr, bool_t is_tunneled) { +int Sal::addListenPort(SalAddress* addr, bool is_tunneled) { int result; belle_sip_listening_point_t* lp; if (is_tunneled){ @@ -478,7 +483,7 @@ int Sal::add_listen_port(SalAddress* addr, bool_t is_tunneled) { ms_error("Tunneled mode is only available for UDP kind of transports."); return -1; } - lp = belle_sip_tunnel_listening_point_new(this->stack, this->tunnel_client); + lp = belle_sip_tunnel_listening_point_new(mStack, mTunnelClient); if (!lp){ ms_error("Could not create tunnel listening point."); return -1; @@ -488,16 +493,16 @@ int Sal::add_listen_port(SalAddress* addr, bool_t is_tunneled) { return -1; #endif }else{ - lp = belle_sip_stack_create_listening_point(this->stack, + lp = belle_sip_stack_create_listening_point(mStack, sal_address_get_domain(addr), sal_address_get_port(addr), sal_transport_to_string(sal_address_get_transport(addr))); } if (lp) { - belle_sip_listening_point_set_keep_alive(lp,(int)this->keep_alive); - result = belle_sip_provider_add_listening_point(this->prov,lp); + belle_sip_listening_point_set_keep_alive(lp,(int)mKeepAlive); + result = belle_sip_provider_add_listening_point(mProvider,lp); if (sal_address_get_transport(addr)==SalTransportTLS) { - set_tls_properties(); + setTlsProperties(); } } else { return -1; @@ -505,254 +510,227 @@ int Sal::add_listen_port(SalAddress* addr, bool_t is_tunneled) { return result; } -int Sal::set_listen_port(const char *addr, int port, SalTransport tr, bool_t is_tunneled) { - SalAddress* sal_addr = sal_address_new(NULL); - int result; - sal_address_set_domain(sal_addr,addr); - sal_address_set_port(sal_addr,port); - sal_address_set_transport(sal_addr,tr); - result = add_listen_port(sal_addr, is_tunneled); - sal_address_destroy(sal_addr); +int Sal::setListenPort (const string &addr, int port, SalTransport tr, bool isTunneled) { + SalAddress *salAddr = sal_address_new(nullptr); + sal_address_set_domain(salAddr, L_STRING_TO_C(addr)); + sal_address_set_port(salAddr, port); + sal_address_set_transport(salAddr, tr); + int result = addListenPort(salAddr, isTunneled); + sal_address_destroy(salAddr); return result; } -int Sal::get_listening_port(SalTransport tr){ +int Sal::getListeningPort(SalTransport tr){ const char *tpn=sal_transport_to_string(tr); - belle_sip_listening_point_t *lp=belle_sip_provider_get_listening_point(this->prov, tpn); + belle_sip_listening_point_t *lp=belle_sip_provider_get_listening_point(mProvider, tpn); if (lp){ return belle_sip_listening_point_get_port(lp); } return 0; } -int Sal::unlisten_ports(){ - const belle_sip_list_t * lps = belle_sip_provider_get_listening_points(this->prov); +int Sal::unlistenPorts(){ + const belle_sip_list_t * lps = belle_sip_provider_get_listening_points(mProvider); belle_sip_list_t * tmp_list = belle_sip_list_copy(lps); - belle_sip_list_for_each2 (tmp_list,(void (*)(void*,void*))remove_listening_point,this->prov); + belle_sip_list_for_each2 (tmp_list,(void (*)(void*,void*))removeListeningPoint,mProvider); belle_sip_list_free(tmp_list); ms_message("sal_unlisten_ports done"); return 0; } -int Sal::transport_available(SalTransport t) { +int Sal::isTransportAvailable(SalTransport t) { switch(t){ case SalTransportUDP: case SalTransportTCP: return TRUE; case SalTransportTLS: - return belle_sip_stack_tls_available(this->stack); + return belle_sip_stack_tls_available(mStack); case SalTransportDTLS: return FALSE; } return FALSE; } -void Sal::make_supported_header(){ - bctbx_list_t *it; - char *alltags=NULL; - size_t buflen=64; - size_t written=0; +void Sal::makeSupportedHeader () { + if (mSupportedHeader) { + belle_sip_object_unref(mSupportedHeader); + mSupportedHeader = nullptr; + } + string tags = Utils::join(mSupportedTags, ", "); + if (tags.empty()) + return; + mSupportedHeader = belle_sip_header_create("Supported", tags.c_str()); + if (mSupportedHeader) + belle_sip_object_ref(mSupportedHeader); +} - if (this->supported){ - belle_sip_object_unref(this->supported); - this->supported=NULL; - } - for(it=this->supported_tags;it!=NULL;it=it->next){ - const char *tag=(const char*)it->data; - size_t taglen=strlen(tag); - if (alltags==NULL || (written+taglen+1>=buflen)) alltags=reinterpret_cast(ms_realloc(alltags,(buflen=buflen*2))); - written+=(size_t)snprintf(alltags+written,buflen-written,it->next ? "%s, " : "%s",tag); - } - if (alltags){ - this->supported=belle_sip_header_create("Supported",alltags); - if (this->supported){ - belle_sip_object_ref(this->supported); - } - ms_free(alltags); +void Sal::setSupportedTags (const string &tags) { + vector splittedTags = Utils::split(tags, ","); + mSupportedTags.clear(); + for (const auto &tag : splittedTags) + mSupportedTags.push_back(Utils::trim(tag)); + makeSupportedHeader(); +} + +const string &Sal::getSupportedTags () const { + if (mSupportedHeader) + mSupported = belle_sip_header_get_unparsed_value(mSupportedHeader); + else + mSupported.clear(); + return mSupported; +} + +void Sal::addSupportedTag (const string &tag) { + auto it = find(mSupportedTags.cbegin(), mSupportedTags.cend(), tag); + if (it == mSupportedTags.cend()) { + mSupportedTags.push_back(tag); + makeSupportedHeader(); } } -void Sal::set_supported_tags(const char* tags){ - this->supported_tags=bctbx_list_free_with_data(this->supported_tags,ms_free); - if (tags){ - char *iter; - char *buffer=ms_strdup(tags); - char *tag; - char *context=NULL; - iter=buffer; - while((tag=strtok_r(iter,", ",&context))!=NULL){ - iter=NULL; - this->supported_tags=bctbx_list_append(this->supported_tags,ms_strdup(tag)); - } - ms_free(buffer); - } - make_supported_header(); -} - -void Sal::add_supported_tag(const char* tag){ - bctbx_list_t *elem=bctbx_list_find_custom(this->supported_tags,(bctbx_compare_func)strcasecmp,tag); - if (!elem){ - this->supported_tags=bctbx_list_append(this->supported_tags,ms_strdup(tag)); - make_supported_header(); +void Sal::removeSupportedTag (const string &tag) { + auto it = find(mSupportedTags.begin(), mSupportedTags.end(), tag); + if (it != mSupportedTags.end()) { + mSupportedTags.erase(it); + makeSupportedHeader(); } } -void Sal::remove_supported_tag(const char* tag){ - bctbx_list_t *elem=bctbx_list_find_custom(this->supported_tags,(bctbx_compare_func)strcasecmp,tag); - if (elem){ - ms_free(elem->data); - this->supported_tags=bctbx_list_erase_link(this->supported_tags,elem); - make_supported_header(); - } -} - -int Sal::reset_transports() { +int Sal::resetTransports() { ms_message("Reseting transports"); - belle_sip_provider_clean_channels(this->prov); + belle_sip_provider_clean_channels(mProvider); return 0; } -ortp_socket_t Sal::get_socket() const { +ortp_socket_t Sal::getSocket() const { ms_warning("sal_get_socket is deprecated"); return -1; } -void Sal::set_user_agent(const char *user_agent) { - belle_sip_header_user_agent_set_products(this->user_agent,NULL); - belle_sip_header_user_agent_add_product(this->user_agent,user_agent); +void Sal::setUserAgent (const string &value) { + belle_sip_header_user_agent_set_products(mUserAgentHeader, nullptr); + belle_sip_header_user_agent_add_product(mUserAgentHeader, L_STRING_TO_C(value)); } -const char* Sal::get_user_agent() const { - static char user_agent[255]; - belle_sip_header_user_agent_get_products_as_string(this->user_agent, user_agent, 254); - return user_agent; +const string &Sal::getUserAgent () const { + char userAgent[256]; + belle_sip_header_user_agent_get_products_as_string(mUserAgentHeader, userAgent, (unsigned int)sizeof(userAgent) - 1); + mUserAgent = userAgent; + return mUserAgent; } -void Sal::append_stack_string_to_user_agent() { - char stack_string[64]; - snprintf(stack_string, sizeof(stack_string) - 1, "(belle-sip/%s)", belle_sip_version_to_string()); - belle_sip_header_user_agent_add_product(this->user_agent, stack_string); +void Sal::appendStackStringToUserAgent () { + stringstream ss; + ss << "(belle-sip/" << belle_sip_version_to_string() << ")"; + string stackStr = ss.str(); + belle_sip_header_user_agent_add_product(mUserAgentHeader, stackStr.c_str()); } -void Sal::set_keepalive_period(unsigned int value) { +void Sal::setKeepAlivePeriod(unsigned int value) { const belle_sip_list_t* iterator; belle_sip_listening_point_t* lp; - this->keep_alive=value; - for (iterator=belle_sip_provider_get_listening_points(this->prov);iterator!=NULL;iterator=iterator->next) { + mKeepAlive=value; + for (iterator=belle_sip_provider_get_listening_points(mProvider);iterator!=NULL;iterator=iterator->next) { lp=(belle_sip_listening_point_t*)iterator->data; - if (this->use_tcp_tls_keep_alive || strcasecmp(belle_sip_listening_point_get_transport(lp),"udp")==0) { - belle_sip_listening_point_set_keep_alive(lp,(int)this->keep_alive); + if (mUseTcpTlsKeepAlive || strcasecmp(belle_sip_listening_point_get_transport(lp),"udp")==0) { + belle_sip_listening_point_set_keep_alive(lp,(int)mKeepAlive); } } } -int Sal::set_tunnel(void *tunnelclient) { +int Sal::setTunnel(void *tunnelclient) { #ifdef TUNNEL_ENABLED - this->tunnel_client=tunnelclient; + mTunnelClient=tunnelclient; return 0; #else return -1; #endif } -bool_t Sal::is_content_type_supported(const char *content_type) const { - bctbx_list_t *item; - for (item = this->supported_content_types; item != NULL; item = bctbx_list_next(item)) { - const char *item_content_type = (const char *)bctbx_list_get_data(item); - if (strcmp(item_content_type, content_type) == 0) return TRUE; - } - return FALSE; +void Sal::setHttpProxyHost (const string &value) { + belle_sip_stack_set_http_proxy_host(mStack, L_STRING_TO_C(value)); } -void Sal::add_content_type_support(const char *content_type) { - if ((content_type != NULL) && (is_content_type_supported(content_type) == FALSE)) { - this->supported_content_types = bctbx_list_append(this->supported_content_types, ms_strdup(content_type)); - } +const string &Sal::getHttpProxyHost () const { + mHttpProxyHost = belle_sip_stack_get_http_proxy_host(mStack); + return mHttpProxyHost; } -void Sal::use_rport(bool_t use_rports) { - belle_sip_provider_enable_rport(this->prov,use_rports); +bool Sal::isContentEncodingAvailable (const string &contentEncoding) const { + return !!belle_sip_stack_content_encoding_available(mStack, L_STRING_TO_C(contentEncoding)); +} + +bool Sal::isContentTypeSupported (const string &contentType) const { + auto it = find_if(mSupportedContentTypes.cbegin(), mSupportedContentTypes.cend(), + [contentType](string supportedContentType) { return contentType == supportedContentType; }); + return it != mSupportedContentTypes.cend(); +} + +void Sal::addContentTypeSupport (const string &contentType) { + if (!contentType.empty() && !isContentTypeSupported(contentType)) + mSupportedContentTypes.push_back(contentType); +} + +void Sal::removeContentTypeSupport (const string &contentType) { + auto it = find(mSupportedContentTypes.begin(), mSupportedContentTypes.end(), contentType); + if (it != mSupportedContentTypes.end()) + mSupportedContentTypes.erase(it); +} + +void Sal::useRport(bool use_rports) { + belle_sip_provider_enable_rport(mProvider,use_rports); ms_message("Sal use rport [%s]", use_rports ? "enabled" : "disabled"); } -void Sal::set_contact_linphone_specs(const char *specs) { - if (this->linphone_specs) { - ms_free(this->linphone_specs); - this->linphone_specs = NULL; - } - if (specs) { - this->linphone_specs = ms_strdup(specs); - } +void Sal::setRootCa (const string &value) { + mRootCa = value; + setTlsProperties(); } -void Sal::set_root_ca(const char* rootCa) { - if (this->root_ca) { - ms_free(this->root_ca); - this->root_ca = NULL; - } - if (rootCa) - this->root_ca = ms_strdup(rootCa); - set_tls_properties(); +void Sal::setRootCaData (const string &value) { + mRootCaData = value; + setTlsProperties(); } -void Sal::set_root_ca_data(const char* data) { - if (this->root_ca_data) { - ms_free(this->root_ca_data); - this->root_ca_data = NULL; - } - if (data) - this->root_ca_data = ms_strdup(data); - set_tls_properties(); +void Sal::verifyServerCertificates(bool verify) { + mTlsVerify=verify; + setTlsProperties(); } -void Sal::verify_server_certificates(bool_t verify) { - this->tls_verify=verify; - set_tls_properties(); +void Sal::verifyServerCn(bool verify) { + mTlsVerifyCn = verify; + setTlsProperties(); } -void Sal::verify_server_cn(bool_t verify) { - this->tls_verify_cn = verify; - set_tls_properties(); +void Sal::setSslConfig(void *ssl_config) { + mSslConfig = ssl_config; + setTlsProperties(); } -void Sal::set_ssl_config(void *ssl_config) { - this->ssl_config = ssl_config; - set_tls_properties(); -} - -void Sal::set_uuid(const char *uuid){ - if (this->uuid){ - ms_free(this->uuid); - this->uuid=NULL; - } - if (uuid) - this->uuid=ms_strdup(uuid); -} - -int Sal::create_uuid(char *uuid, size_t len) { - if (generate_uuid(uuid, len) == 0) { - set_uuid(uuid); +int Sal::createUuid(char *uuid, size_t len) { + if (generateUuid(uuid, len) == 0) { + setUuid(uuid); return 0; } return -1; } -int Sal::generate_uuid(char *uuid, size_t len) { - sal_uuid_t uuid_struct; +int Sal::generateUuid(char *uuid, size_t len) { + SalUuid uuid_struct; int i; int written; if (len==0) return -1; /*create an UUID as described in RFC4122, 4.4 */ - belle_sip_random_bytes((unsigned char*)&uuid_struct, sizeof(sal_uuid_t)); - uuid_struct.clock_seq_hi_and_reserved&=(unsigned char)~(1<<6); - uuid_struct.clock_seq_hi_and_reserved|=(unsigned char)1<<7; - uuid_struct.time_hi_and_version&=(unsigned char)~(0xf<<12); - uuid_struct.time_hi_and_version|=(unsigned char)4<<12; + belle_sip_random_bytes((unsigned char*)&uuid_struct, sizeof(SalUuid)); + uuid_struct.clockSeqHiAndReserved&=(unsigned char)~(1<<6); + uuid_struct.clockSeqHiAndReserved|=(unsigned char)1<<7; + uuid_struct.timeHiAndVersion&=(unsigned char)~(0xf<<12); + uuid_struct.timeHiAndVersion|=(unsigned char)4<<12; - written=snprintf(uuid,len,"%8.8x-%4.4x-%4.4x-%2.2x%2.2x-", uuid_struct.time_low, uuid_struct.time_mid, - uuid_struct.time_hi_and_version, uuid_struct.clock_seq_hi_and_reserved, - uuid_struct.clock_seq_low); + written=snprintf(uuid,len,"%8.8x-%4.4x-%4.4x-%2.2x%2.2x-", uuid_struct.timeLow, uuid_struct.timeMid, + uuid_struct.timeHiAndVersion, uuid_struct.clockSeqHiAndReserved, + uuid_struct.clockSeqLow); if ((written < 0) || ((size_t)written > (len +13))) { ms_error("sal_create_uuid(): buffer is too short !"); return -1; @@ -763,63 +741,79 @@ int Sal::generate_uuid(char *uuid, size_t len) { return 0; } -void Sal::add_pending_auth(SalOp *op){ - if (bctbx_list_find(this->pending_auths,op)==NULL){ - this->pending_auths=bctbx_list_append(this->pending_auths,op); - op->has_auth_pending=TRUE; +void Sal::addPendingAuth (SalOp *op) { + auto it = find(mPendingAuths.cbegin(), mPendingAuths.cend(), op); + if (it == mPendingAuths.cend()) { + mPendingAuths.push_back(op); + op->mHasAuthPending = true; } } -void Sal::remove_pending_auth(SalOp *op){ - if (op->has_auth_pending){ - op->has_auth_pending=FALSE; - if (bctbx_list_find(this->pending_auths,op)){ - this->pending_auths=bctbx_list_remove(this->pending_auths,op); - } +void Sal::removePendingAuth (SalOp *op) { + if (op->mHasAuthPending) { + op->mHasAuthPending = false; + mPendingAuths.remove(op); } } -void Sal::set_default_sdp_handling(SalOpSDPHandling sdp_handling_method) { +void Sal::setDefaultSdpHandling(SalOpSDPHandling sdp_handling_method) { if (sdp_handling_method != SalOpSDPNormal ) ms_message("Enabling special SDP handling for all new SalOp in Sal[%p]!", this); - this->default_sdp_handling = sdp_handling_method; + mDefaultSdpHandling = sdp_handling_method; } -void Sal::enable_nat_helper(bool_t enable) { - this->_nat_helper_enabled=enable; - belle_sip_provider_enable_nat_helper(this->prov,enable); +void Sal::enableNatHelper(bool enable) { + mNatHelperEnabled=enable; + belle_sip_provider_enable_nat_helper(mProvider,enable); ms_message("Sal nat helper [%s]",enable?"enabled":"disabled"); } -void Sal::get_default_local_ip(int address_family, char *ip, size_t iplen) { +void Sal::getDefaultLocalIp(int address_family, char *ip, size_t iplen) { strncpy(ip,address_family==AF_INET6 ? "::1" : "127.0.0.1",iplen); ms_error("sal_get_default_local_ip() is deprecated."); } -void Sal::set_dns_servers(const bctbx_list_t *servers){ +void Sal::setDnsServers(const bctbx_list_t *servers){ belle_sip_list_t *l = NULL; /*we have to convert the bctbx_list_t into a belle_sip_list_t first*/ for (; servers != NULL; servers = servers->next){ l = belle_sip_list_append(l, servers->data); } - belle_sip_stack_set_dns_servers(this->stack, l); + belle_sip_stack_set_dns_servers(mStack, l); belle_sip_list_free(l); } -belle_sip_source_t *Sal::create_timer(belle_sip_source_func_t func, void *data, unsigned int timeout_value_ms, const char* timer_name) { - belle_sip_main_loop_t *ml = belle_sip_stack_get_main_loop(this->stack); - return belle_sip_main_loop_create_timeout(ml, func, data, timeout_value_ms, timer_name); +void Sal::setDnsUserHostsFile (const string &value) { + belle_sip_stack_set_dns_user_hosts_file(mStack, value.c_str()); } -void Sal::cancel_timer(belle_sip_source_t *timer) { - belle_sip_main_loop_t *ml = belle_sip_stack_get_main_loop(this->stack); +const string &Sal::getDnsUserHostsFile () const { + mDnsUserHostsFile = belle_sip_stack_get_dns_user_hosts_file(mStack); + return mDnsUserHostsFile; +} + +belle_sip_resolver_context_t *Sal::resolveA (const string &name, int port, int family, belle_sip_resolver_callback_t cb, void *data) { + return belle_sip_stack_resolve_a(mStack, L_STRING_TO_C(name), port, family, cb, data); +} + +belle_sip_resolver_context_t *Sal::resolve (const string &service, const string &transport, const string &name, int port, int family, belle_sip_resolver_callback_t cb, void *data) { + return belle_sip_stack_resolve(mStack, L_STRING_TO_C(service), L_STRING_TO_C(transport), L_STRING_TO_C(name), port, family, cb, data); +} + +belle_sip_source_t *Sal::createTimer (belle_sip_source_func_t func, void *data, unsigned int timeoutValueMs, const string &timerName) { + belle_sip_main_loop_t *ml = belle_sip_stack_get_main_loop(mStack); + return belle_sip_main_loop_create_timeout(ml, func, data, timeoutValueMs, L_STRING_TO_C(timerName)); +} + +void Sal::cancelTimer(belle_sip_source_t *timer) { + belle_sip_main_loop_t *ml = belle_sip_stack_get_main_loop(mStack); belle_sip_main_loop_remove_source(ml, timer); } -belle_sip_response_t* Sal::create_response_from_request (belle_sip_request_t* req, int code ) { +belle_sip_response_t* Sal::createResponseFromRequest (belle_sip_request_t* req, int code ) { belle_sip_response_t *resp=belle_sip_response_create_from_request(req,code); - belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp),BELLE_SIP_HEADER(this->user_agent)); - belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp), this->supported); + belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp),BELLE_SIP_HEADER(mUserAgentHeader)); + belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp), mSupportedHeader); return resp; } @@ -940,90 +934,90 @@ void sal_uninit(Sal* sal) { } int sal_create_uuid(Sal *ctx, char *uuid, size_t len) { - return ctx->create_uuid(uuid, len); + return ctx->createUuid(uuid, len); } void sal_set_uuid(Sal *ctx, const char *uuid) { - ctx->set_uuid(uuid); + ctx->setUuid(L_C_TO_STRING(uuid)); } void sal_default_set_sdp_handling(Sal* h, SalOpSDPHandling handling_method) { - h->set_default_sdp_handling(handling_method); + h->setDefaultSdpHandling(handling_method); } void sal_set_send_error(Sal *sal,int value) { - sal->set_send_error(value); + sal->setSendError(value); } void sal_set_recv_error(Sal *sal,int value) { - sal->set_recv_error(value); + sal->setRecvError(value); } -int sal_enable_pending_trans_checking(Sal *sal, bool_t value) { - return sal->enable_pending_trans_checking(value); +void sal_enable_pending_trans_checking(Sal *sal, bool value) { + sal->enablePendingTransactionChecking(value); } void sal_enable_unconditional_answer(Sal *sal,int value) { - sal->enable_unconditional_answer(value); + sal->enableUnconditionalAnswer(value); } void sal_set_dns_timeout(Sal* sal,int timeout) { - sal->set_dns_timeout(timeout); + sal->setDnsTimeout(timeout); } void sal_set_dns_user_hosts_file(Sal *sal, const char *hosts_file) { - sal->set_dns_user_hosts_file(hosts_file); + sal->setDnsUserHostsFile(hosts_file); } void *sal_get_stack_impl(Sal *sal) { - return sal->get_stack_impl(); + return sal->getStackImpl(); } void sal_set_refresher_retry_after(Sal *sal,int value) { - sal->set_refresher_retry_after(value); + sal->setRefresherRetryAfter(value); } int sal_get_refresher_retry_after(const Sal *sal) { - return sal->get_refresher_retry_after(); + return sal->getRefresherRetryAfter(); } void sal_set_transport_timeout(Sal* sal,int timeout) { - sal->set_transport_timeout(timeout); + sal->setTransportTimeout(timeout); } -void sal_enable_test_features(Sal*ctx, bool_t enabled) { - ctx->enable_test_features(enabled); +void sal_enable_test_features(Sal*ctx, bool enabled) { + ctx->enableTestFeatures(enabled); } int sal_transport_available(Sal *ctx, SalTransport t) { - return ctx->transport_available(t); + return ctx->isTransportAvailable(t); } const SalErrorInfo *sal_op_get_error_info(const SalOp *op) { - return op->get_error_info(); + return op->getErrorInfo(); } -bool_t sal_call_dialog_request_pending(const SalOp *op) { +bool sal_call_dialog_request_pending(const SalOp *op) { auto callOp = dynamic_cast(op); - return callOp->dialog_request_pending(); + return callOp->dialogRequestPending(); } void sal_call_set_sdp_handling(SalOp *h, SalOpSDPHandling handling) { auto callOp = dynamic_cast(h); - callOp->set_sdp_handling(handling); + callOp->setSdpHandling(handling); } SalMediaDescription * sal_call_get_final_media_description(SalOp *h) { auto callOp = dynamic_cast(h); - return callOp->get_final_media_description(); + return callOp->getFinalMediaDescription(); } belle_sip_resolver_context_t *sal_resolve_a(Sal *sal, const char *name, int port, int family, belle_sip_resolver_callback_t cb, void *data) { - return sal->resolve_a(name, port, family, cb, data); + return sal->resolveA(name, port, family, cb, data); } Sal *sal_op_get_sal(SalOp *op) { - return op->get_sal(); + return op->getSal(); } SalOp *sal_create_refer_op(Sal *sal) { @@ -1036,31 +1030,31 @@ void sal_release_op(SalOp *op) { void sal_op_set_from(SalOp *sal_refer_op, const char* from) { auto referOp = dynamic_cast(sal_refer_op); - referOp->set_from(from); + referOp->setFrom(from); } void sal_op_set_to(SalOp *sal_refer_op, const char* to) { auto referOp = dynamic_cast(sal_refer_op); - referOp->set_to(to); + referOp->setTo(to); } void sal_op_send_refer(SalOp *sal_refer_op, SalAddress* refer_to) { auto referOp = dynamic_cast(sal_refer_op); - referOp->send_refer(refer_to); + referOp->sendRefer(refer_to); } void sal_set_user_pointer(Sal *sal, void *user_pointer) { - sal->set_user_pointer(user_pointer); + sal->setUserPointer(user_pointer); } void *sal_get_user_pointer(Sal *sal) { - return sal->get_user_pointer(); + return sal->getUserPointer(); } void sal_set_call_refer_callback(Sal *sal, void (*OnReferCb)(SalOp *op, const SalAddress *referto)) { struct Sal::Callbacks cbs = {NULL}; cbs.refer_received = OnReferCb; - sal->set_callbacks(&cbs); + sal->setCallbacks(&cbs); } } diff --git a/src/sal/sal.h b/src/sal/sal.h index 3e48bc481..082929f1b 100644 --- a/src/sal/sal.h +++ b/src/sal/sal.h @@ -20,9 +20,14 @@ #ifndef _L_SAL_H_ #define _L_SAL_H_ -#include "c-wrapper/internal/c-sal.h" +#include +#include + #include "linphone/utils/general.h" +#include "c-wrapper/internal/c-sal.h" +#include "logger/logger.h" + LINPHONE_BEGIN_NAMESPACE class SalOp; @@ -32,44 +37,44 @@ class SalSubscribeOp; class SalPresenceOp; class SalReferOp; -class Sal{ +class Sal { public: - typedef void (*OnCallReceivedCb)(SalCallOp *op); - typedef void (*OnCallRingingCb)(SalOp *op); - typedef void (*OnCallAcceptedCb)(SalOp *op); - typedef void (*OnCallAckReceivedCb)(SalOp *op, SalCustomHeader *ack); - typedef void (*OnCallAckBeingSentCb)(SalOp *op, SalCustomHeader *ack); - typedef void (*OnCallUpdatingCb)(SalOp *op, bool_t is_update);/* Called when a reINVITE/UPDATE is received*/ - typedef void (*OnCallTerminatedCb)(SalOp *op, const char *from); - typedef void (*OnCallFailureCb)(SalOp *op); - typedef void (*OnCallReleasedCb)(SalOp *salop); - typedef void (*OnCallCancelDoneCb)(SalOp *salop); - typedef void (*OnAuthRequestedLegacyCb)(SalOp *op, const char *realm, const char *username); - typedef bool_t (*OnAuthRequestedCb)(Sal *sal,SalAuthInfo* info); - typedef void (*OnAuthFailureCb)(SalOp *op, SalAuthInfo* info); - typedef void (*OnRegisterSuccessCb)(SalOp *op, bool_t registered); - typedef void (*OnRegisterFailureCb)(SalOp *op); - typedef void (*OnVfuRequestCb)(SalOp *op); - typedef void (*OnDtmfReceivedCb)(SalOp *op, char dtmf); - typedef void (*OnCallReferCb)(SalOp *op, const SalAddress *referto); - typedef void (*OnReferCb)(SalOp *op, const SalAddress *referto); - typedef void (*OnMessageReceivedCb)(SalOp *op, const SalMessage *msg); - typedef void (*OnMessageDeliveryUpdateCb)(SalOp *op, SalMessageDeliveryStatus); - typedef void (*OnNotifyReferCb)(SalOp *op, SalReferStatus state); - typedef void (*OnSubscribeResponseCb)(SalOp *op, SalSubscribeStatus status, int will_retry); - typedef void (*OnNotifyCb)(SalSubscribeOp *op, SalSubscribeStatus status, const char *event, SalBodyHandler *body); - typedef void (*OnSubscribeReceivedCb)(SalSubscribeOp *salop, const char *event, const SalBodyHandler *body); - typedef void (*OnIncomingSubscribeClosedCb)(SalOp *salop); - typedef void (*OnParsePresenceRequestedCb)(SalOp *salop, const char *content_type, const char *content_subtype, const char *content, SalPresenceModel **result); - typedef void (*OnConvertPresenceToXMLRequestedCb)(SalOp *salop, SalPresenceModel *presence, const char *contact, char **content); - typedef void (*OnNotifyPresenceCb)(SalOp *op, SalSubscribeStatus ss, SalPresenceModel *model, const char *msg); - typedef void (*OnSubscribePresenceReceivedCb)(SalPresenceOp *salop, const char *from); - typedef void (*OnSubscribePresenceClosedCb)(SalPresenceOp *salop, const char *from); - typedef void (*OnPingReplyCb)(SalOp *salop); - typedef void (*OnInfoReceivedCb)(SalOp *salop, SalBodyHandler *body); - typedef void (*OnPublishResponseCb)(SalOp *salop); - typedef void (*OnNotifyResponseCb)(SalOp *salop); - typedef void (*OnExpireCb)(SalOp *salop); + using OnCallReceivedCb = void (*) (SalCallOp *op); + using OnCallRingingCb = void (*) (SalOp *op); + using OnCallAcceptedCb = void (*) (SalOp *op); + using OnCallAckReceivedCb = void (*) (SalOp *op, SalCustomHeader *ack); + using OnCallAckBeingSentCb = void (*) (SalOp *op, SalCustomHeader *ack); + using OnCallUpdatingCb = void (*) (SalOp *op, bool_t isUpdate); // Called when a reINVITE/UPDATE is received + using OnCallTerminatedCb = void (*) (SalOp *op, const char *from); + using OnCallFailureCb = void (*) (SalOp *op); + using OnCallReleasedCb = void (*) (SalOp *op); + using OnCallCancelDoneCb = void (*) (SalOp *op); + using OnAuthRequestedLegacyCb = void (*) (SalOp *op, const char *realm, const char *username); + using OnAuthRequestedCb = bool_t (*) (Sal *sal, SalAuthInfo *info); + using OnAuthFailureCb = void (*) (SalOp *op, SalAuthInfo *info); + using OnRegisterSuccessCb = void (*) (SalOp *op, bool_t registered); + using OnRegisterFailureCb = void (*) (SalOp *op); + using OnVfuRequestCb = void (*) (SalOp *op); + using OnDtmfReceivedCb = void (*) (SalOp *op, char dtmf); + using OnCallReferCb = void (*) (SalOp *op, const SalAddress *referTo); + using OnReferCb = void (*) (SalOp *op, const SalAddress *referTo); + using OnMessageReceivedCb = void (*) (SalOp *op, const SalMessage *msg); + using OnMessageDeliveryUpdateCb = void (*) (SalOp *op, SalMessageDeliveryStatus status); + using OnNotifyReferCb = void (*) (SalOp *op, SalReferStatus status); + using OnSubscribeResponseCb = void (*) (SalOp *op, SalSubscribeStatus status, int willRetry); + using OnNotifyCb = void (*) (SalSubscribeOp *op, SalSubscribeStatus status, const char *event, SalBodyHandler *body); + using OnSubscribeReceivedCb = void (*) (SalSubscribeOp *op, const char *event, const SalBodyHandler *body); + using OnIncomingSubscribeClosedCb = void (*) (SalOp *op); + using OnParsePresenceRequestedCb = void (*) (SalOp *op, const char *contentType, const char *contentSubtype, const char *content, SalPresenceModel **result); + using OnConvertPresenceToXMLRequestedCb = void (*) (SalOp *op, SalPresenceModel *presence, const char *contact, char **content); + using OnNotifyPresenceCb = void (*) (SalOp *op, SalSubscribeStatus ss, SalPresenceModel *model, const char *msg); + using OnSubscribePresenceReceivedCb = void (*) (SalPresenceOp *op, const char *from); + using OnSubscribePresenceClosedCb = void (*) (SalPresenceOp *op, const char *from); + using OnPingReplyCb = void (*) (SalOp *op); + using OnInfoReceivedCb = void (*) (SalOp *op, SalBodyHandler *body); + using OnPublishResponseCb = void (*) (SalOp *op); + using OnNotifyResponseCb = void (*) (SalOp *op); + using OnExpireCb = void (*) (SalOp *op); struct Callbacks { OnCallReceivedCb call_received; @@ -89,7 +94,7 @@ public: OnRegisterFailureCb register_failure; OnVfuRequestCb vfu_request; OnDtmfReceivedCb dtmf_received; - + OnMessageReceivedCb message_received; OnMessageDeliveryUpdateCb message_delivery_update; OnNotifyReferCb notify_refer; @@ -108,210 +113,216 @@ public: OnPublishResponseCb on_publish_response; OnExpireCb on_expire; OnNotifyResponseCb on_notify_response; - OnReferCb refer_received; /*for out of dialog refer*/ + OnReferCb refer_received; // For out of dialog refer }; Sal(MSFactory *factory); ~Sal(); - void set_factory(MSFactory *factory) { - this->factory = factory; - } + void setFactory (MSFactory *value) { mFactory = value; } - void set_user_pointer(void *user_data) {this->up=user_data;} - void *get_user_pointer() const {return this->up;} + void setUserPointer (void *value) { mUserPointer = value; } + void *getUserPointer () const { return mUserPointer; } - void set_callbacks(const Callbacks *cbs); + void setCallbacks (const Callbacks *cbs); - void *get_stack_impl() {return this->stack;} + void *getStackImpl() const { return mStack; } - int iterate() {belle_sip_stack_sleep(this->stack,0); return 0;} + int iterate () { belle_sip_stack_sleep(mStack, 0); return 0; } - void set_send_error(int value) {belle_sip_stack_set_send_error(this->stack,value);} - void set_recv_error(int value) {belle_sip_provider_set_recv_error(this->prov,value);} + void setSendError (int value) { belle_sip_stack_set_send_error(mStack, value); } + void setRecvError (int value) { belle_sip_provider_set_recv_error(mProvider, value); } - /******************/ - /* SIP parameters */ - /******************/ - void set_supported_tags(const char* tags); - const char *get_supported_tags() const {return this->supported ? belle_sip_header_get_unparsed_value(this->supported) : NULL;} - void add_supported_tag(const char* tag); - void remove_supported_tag(const char* tag); + // --------------------------------------------------------------------------- + // SIP parameters + // --------------------------------------------------------------------------- + void setSupportedTags (const std::string &tags); + const std::string &getSupportedTags () const; + void addSupportedTag (const std::string &tag); + void removeSupportedTag (const std::string &tag); - void set_user_agent(const char *user_agent); - const char* get_user_agent() const; - void append_stack_string_to_user_agent(); + void setUserAgent (const std::string &value); + const std::string &getUserAgent () const; + void appendStackStringToUserAgent (); - bool_t content_encoding_available(const char *content_encoding) {return (bool_t)belle_sip_stack_content_encoding_available(this->stack, content_encoding);} - bool_t is_content_type_supported(const char *content_type) const; - void add_content_type_support(const char *content_type); + bool isContentEncodingAvailable (const std::string &contentEncoding) const; + bool isContentTypeSupported (const std::string &contentType) const; + void addContentTypeSupport (const std::string &contentType); + void removeContentTypeSupport (const std::string &contentType); - void set_default_sdp_handling(SalOpSDPHandling sdp_handling_method); + void setDefaultSdpHandling (SalOpSDPHandling sdpHandlingMethod); - void set_uuid(const char *uuid); - int create_uuid(char *uuid, size_t len); - static int generate_uuid(char *uuid, size_t len); + void setUuid (const std::string &value) { mUuid = value; } + int createUuid (char *uuid, size_t len); + static int generateUuid (char *uuid, size_t len); - void enable_nat_helper(bool_t enable); - bool_t nat_helper_enabled() const {return this->_nat_helper_enabled;} + void enableNatHelper (bool value); + bool natHelperEnabled () const { return mNatHelperEnabled; } - bool_t pending_trans_checking_enabled() const {return this->pending_trans_checking;} - int enable_pending_trans_checking(bool_t value) {this->pending_trans_checking = value; return 0;} + bool pendingTransactionCheckingEnabled () const { return mPendingTransactionChecking; } + void enablePendingTransactionChecking (bool value) { mPendingTransactionChecking = value; } - void set_refresher_retry_after(int value) {this->refresher_retry_after=value;} - int get_refresher_retry_after() const {return this->refresher_retry_after;} + void setRefresherRetryAfter (int value) { mRefresherRetryAfter = value; } + int getRefresherRetryAfter () const { return mRefresherRetryAfter; } - void enable_sip_update_method(bool_t value) {this->enable_sip_update=value;} - void use_session_timers(int expires) {this->session_expires=expires;} - void use_dates(bool_t enabled) {this->_use_dates=enabled;} - void use_one_matching_codec_policy(bool_t one_matching_codec) {this->one_matching_codec=one_matching_codec;} - void use_rport(bool_t use_rports); - void enable_auto_contacts(bool_t enabled) {this->auto_contacts=enabled;} - void enable_test_features(bool_t enabled) {this->_enable_test_features=enabled;} - void use_no_initial_route(bool_t enabled) {this->no_initial_route=enabled;} - void enable_unconditional_answer(int value) {belle_sip_provider_enable_unconditional_answer(this->prov,value);} - void enable_reconnect_to_primary_asap(bool_t enabled) {belle_sip_stack_enable_reconnect_to_primary_asap(this->stack,enabled);} + void enableSipUpdateMethod (bool value) { mEnableSipUpdate = value; } + void useSessionTimers (int expires) { mSessionExpires = expires; } + void useDates (bool value) { mUseDates = value; } + void useOneMatchingCodecPolicy (bool value) { mOneMatchingCodec = value; } + void useRport (bool value); + void enableAutoContacts (bool value) { mAutoContacts = value; } + void enableTestFeatures (bool value) { mEnableTestFeatures = value; } + void useNoInitialRoute (bool value) { mNoInitialRoute = value; } + void enableUnconditionalAnswer (int value) { belle_sip_provider_enable_unconditional_answer(mProvider, value); } + void enableReconnectToPrimaryAsap (bool value) { belle_sip_stack_enable_reconnect_to_primary_asap(mStack, value); } - bctbx_list_t *get_pending_auths() const {return bctbx_list_copy(this->pending_auths);} + const std::list &getPendingAuths () const { return mPendingAuths; } - void set_contact_linphone_specs(const char *specs); - - /**********************/ - /* Network parameters */ - /**********************/ - int set_listen_port(const char *addr, int port, SalTransport tr, bool_t is_tunneled); - int get_listening_port(SalTransport tr); - int transport_available(SalTransport t); - - void get_default_local_ip(int address_family, char *ip, size_t iplen); - - void set_transport_timeout(int timeout) {belle_sip_stack_set_transport_timeout(this->stack, timeout);} - int get_transport_timeout() const {return belle_sip_stack_get_transport_timeout(this->stack);} - - void set_keepalive_period(unsigned int value); - unsigned int get_keepalive_period() const {return this->keep_alive;} - void use_tcp_tls_keepalive(bool_t enabled) {this->use_tcp_tls_keep_alive=enabled;} - - void set_dscp(int dscp) {belle_sip_stack_set_default_dscp(this->stack,dscp);} - - int set_tunnel(void *tunnelclient); - - void set_http_proxy_host(const char *host) {belle_sip_stack_set_http_proxy_host(this->stack, host);} - const char *get_http_proxy_host() const {return belle_sip_stack_get_http_proxy_host(this->stack);} - - void set_http_proxy_port(int port) {belle_sip_stack_set_http_proxy_port(this->stack, port);} - int get_http_proxy_port() const {return belle_sip_stack_get_http_proxy_port(this->stack);} - - ortp_socket_t get_socket() const; - - int unlisten_ports(); - int reset_transports(); + void setContactLinphoneSpecs (const std::string &value) { mLinphoneSpecs = value; } - /******************/ - /* TLS parameters */ - /******************/ - void set_ssl_config(void *ssl_config); - void set_root_ca(const char* rootCa); - void set_root_ca_data(const char* data); - const char *get_root_ca() const {return this->root_ca;} + // --------------------------------------------------------------------------- + // Network parameters + // --------------------------------------------------------------------------- + int setListenPort (const std::string &addr, int port, SalTransport tr, bool isTunneled); + int getListeningPort (SalTransport tr); + int isTransportAvailable (SalTransport t); - void verify_server_certificates(bool_t verify); - void verify_server_cn(bool_t verify); + void getDefaultLocalIp (int addressFamily, char *ip, size_t ipLen); + + void setTransportTimeout (int value) { belle_sip_stack_set_transport_timeout(mStack, value); } + int getTransportTimeout () const { return belle_sip_stack_get_transport_timeout(mStack); } + + void setKeepAlivePeriod (unsigned int value); + unsigned int getKeepAlivePeriod () const { return mKeepAlive; } + void useTcpTlsKeepAlive (bool value) { mUseTcpTlsKeepAlive = value; } + + void setDscp (int dscp) { belle_sip_stack_set_default_dscp(mStack, dscp); } + + int setTunnel (void *tunnelClient); + + void setHttpProxyHost (const std::string &value); + const std::string &getHttpProxyHost () const; + + void setHttpProxyPort (int value) { belle_sip_stack_set_http_proxy_port(mStack, value); } + int getHttpProxyPort () const { return belle_sip_stack_get_http_proxy_port(mStack); } + + ortp_socket_t getSocket () const; + + int unlistenPorts (); + int resetTransports (); - /******************/ - /* DNS resolution */ - /******************/ - void set_dns_timeout(int timeout) {belle_sip_stack_set_dns_timeout(this->stack, timeout);} - int get_dns_timeout() const {return belle_sip_stack_get_dns_timeout(this->stack);} + // --------------------------------------------------------------------------- + // TLS parameters + // --------------------------------------------------------------------------- + void setSslConfig (void *sslConfig); + void setRootCa (const std::string &value); + void setRootCaData (const std::string &value); + const std::string &getRootCa () const { return mRootCa; } - void set_dns_servers(const bctbx_list_t *servers); - - void enable_dns_search(bool_t enable) {belle_sip_stack_enable_dns_search(this->stack, (unsigned char)enable);} - bool_t dns_search_enabled() const {return (bool_t)belle_sip_stack_dns_search_enabled(this->stack);} - - void enable_dns_srv(bool_t enable) {belle_sip_stack_enable_dns_srv(this->stack, (unsigned char)enable);} - bool_t dns_srv_enabled() const {return (bool_t)belle_sip_stack_dns_srv_enabled(this->stack);} - - void set_dns_user_hosts_file(const char *hosts_file) {belle_sip_stack_set_dns_user_hosts_file(this->stack, hosts_file);} - const char *get_dns_user_hosts_file() const {return belle_sip_stack_get_dns_user_hosts_file(this->stack);} - - belle_sip_resolver_context_t *resolve_a(const char *name, int port, int family, belle_sip_resolver_callback_t cb, void *data) - {return belle_sip_stack_resolve_a(this->stack,name,port,family,cb,data);} - belle_sip_resolver_context_t *resolve(const char *service, const char *transport, const char *name, int port, int family, belle_sip_resolver_callback_t cb, void *data) - {return belle_sip_stack_resolve(this->stack, service, transport, name, port, family, cb, data);} + void verifyServerCertificates (bool value); + void verifyServerCn (bool value); - /**********/ - /* Timers */ - /**********/ - belle_sip_source_t *create_timer(belle_sip_source_func_t func, void *data, unsigned int timeout_value_ms, const char* timer_name); - void cancel_timer(belle_sip_source_t *timer); + // --------------------------------------------------------------------------- + // DNS resolution + // --------------------------------------------------------------------------- + void setDnsTimeout (int value) { belle_sip_stack_set_dns_timeout(mStack, value); } + int getDnsTimeout () const { return belle_sip_stack_get_dns_timeout(mStack); } + + void setDnsServers (const bctbx_list_t *servers); + + void enableDnsSearch (bool value) { belle_sip_stack_enable_dns_search(mStack, (unsigned char)value); } + bool dnsSearchEnabled () const { return !!belle_sip_stack_dns_search_enabled(mStack); } + + void enableDnsSrv (bool value) { belle_sip_stack_enable_dns_srv(mStack, (unsigned char)value); } + bool dnsSrvEnabled () const { return !!belle_sip_stack_dns_srv_enabled(mStack); } + + void setDnsUserHostsFile (const std::string &value); + const std::string &getDnsUserHostsFile () const; + + belle_sip_resolver_context_t *resolveA (const std::string &name, int port, int family, belle_sip_resolver_callback_t cb, void *data); + belle_sip_resolver_context_t *resolve (const std::string &service, const std::string &transport, const std::string &name, int port, int family, belle_sip_resolver_callback_t cb, void *data); + + + // --------------------------------------------------------------------------- + // Timers + // --------------------------------------------------------------------------- + belle_sip_source_t *createTimer (belle_sip_source_func_t func, void *data, unsigned int timeoutValueMs, const std::string &timerName); + void cancelTimer (belle_sip_source_t *timer); private: - struct sal_uuid_t { - unsigned int time_low; - unsigned short time_mid; - unsigned short time_hi_and_version; - unsigned char clock_seq_hi_and_reserved; - unsigned char clock_seq_low; + struct SalUuid { + unsigned int timeLow; + unsigned short timeMid; + unsigned short timeHiAndVersion; + unsigned char clockSeqHiAndReserved; + unsigned char clockSeqLow; unsigned char node[6]; }; - void set_tls_properties(); - int add_listen_port(SalAddress* addr, bool_t is_tunneled); - void make_supported_header(); - void add_pending_auth(SalOp *op); - void remove_pending_auth(SalOp *op); - belle_sip_response_t* create_response_from_request (belle_sip_request_t* req, int code ); + void setTlsProperties (); + int addListenPort (SalAddress *addr, bool isTunneled); + void makeSupportedHeader (); + void addPendingAuth (SalOp *op); + void removePendingAuth (SalOp *op); + belle_sip_response_t *createResponseFromRequest (belle_sip_request_t *req, int code); - static void unimplemented_stub() {ms_warning("Unimplemented SAL callback");} - static void remove_listening_point(belle_sip_listening_point_t* lp,belle_sip_provider_t* prov) {belle_sip_provider_remove_listening_point(prov,lp);} + static void unimplementedStub() { lWarning() << "Unimplemented SAL callback"; } + static void removeListeningPoint (belle_sip_listening_point_t *lp,belle_sip_provider_t *prov) { + belle_sip_provider_remove_listening_point(prov, lp); + } - /* Internal callbacks */ - static void process_dialog_terminated_cb(void *sal, const belle_sip_dialog_terminated_event_t *event); - static void process_io_error_cb(void *user_ctx, const belle_sip_io_error_event_t *event); - static void process_request_event_cb(void *ud, const belle_sip_request_event_t *event); - static void process_response_event_cb(void *user_ctx, const belle_sip_response_event_t *event); - static void process_timeout_cb(void *user_ctx, const belle_sip_timeout_event_t *event); - static void process_transaction_terminated_cb(void *user_ctx, const belle_sip_transaction_terminated_event_t *event); - static void process_auth_requested_cb(void *sal, belle_sip_auth_event_t *event); + // Internal callbacks + static void processDialogTerminatedCb (void *userCtx, const belle_sip_dialog_terminated_event_t *event); + static void processIoErrorCb (void *userCtx, const belle_sip_io_error_event_t *event); + static void processRequestEventCb (void *userCtx, const belle_sip_request_event_t *event); + static void processResponseEventCb (void *userCtx, const belle_sip_response_event_t *event); + static void processTimeoutCb (void *userCtx, const belle_sip_timeout_event_t *event); + static void processTransactionTerminatedCb (void *userCtx, const belle_sip_transaction_terminated_event_t *event); + static void processAuthRequestedCb (void *userCtx, belle_sip_auth_event_t *event); - MSFactory *factory = NULL; - Callbacks callbacks = {0}; - MSList *pending_auths = NULL;/*MSList of SalOp */ - belle_sip_stack_t* stack = NULL; - belle_sip_provider_t *prov = NULL; - belle_sip_header_user_agent_t* user_agent = NULL; - belle_sip_listener_t *listener = NULL; - void *tunnel_client = NULL; - void *up = NULL; /*user pointer*/ - int session_expires = 0; - unsigned int keep_alive = 0; - char *root_ca = NULL; - char *root_ca_data = NULL; - char *uuid = NULL; - int refresher_retry_after = 60000; /*retry after value for refresher*/ - MSList *supported_tags = NULL;/*list of char * */ - belle_sip_header_t *supported = NULL; - bool_t one_matching_codec = FALSE; - bool_t use_tcp_tls_keep_alive = FALSE; - bool_t _nat_helper_enabled = FALSE; - bool_t tls_verify = TRUE; - bool_t tls_verify_cn = TRUE; - bool_t _use_dates = FALSE; - bool_t auto_contacts = TRUE; - bool_t _enable_test_features = FALSE; - bool_t no_initial_route = FALSE; - bool_t enable_sip_update = TRUE; /*true by default*/ - SalOpSDPHandling default_sdp_handling = SalOpSDPNormal; - bool_t pending_trans_checking = TRUE; /*testing purpose*/ - void *ssl_config = NULL; - bctbx_list_t *supported_content_types = NULL; /* list of char* */ - char *linphone_specs = NULL; + MSFactory *mFactory = nullptr; + Callbacks mCallbacks = { 0 }; + std::list mPendingAuths; + belle_sip_stack_t *mStack = nullptr; + belle_sip_provider_t *mProvider = nullptr; + belle_sip_header_user_agent_t *mUserAgentHeader = nullptr; + belle_sip_listener_t *mListener = nullptr; + void *mTunnelClient = nullptr; + void *mUserPointer = nullptr; // User pointer + int mSessionExpires = 0; + unsigned int mKeepAlive = 0; + std::string mRootCa; + std::string mRootCaData; + std::string mUuid; + int mRefresherRetryAfter = 60000; // Retry after value for refresher + std::vector mSupportedTags; + belle_sip_header_t *mSupportedHeader = nullptr; + bool mOneMatchingCodec = false; + bool mUseTcpTlsKeepAlive = false; + bool mNatHelperEnabled = false; + bool mTlsVerify = true; + bool mTlsVerifyCn = true; + bool mUseDates = false; + bool mAutoContacts = true; + bool mEnableTestFeatures = false; + bool mNoInitialRoute = false; + bool mEnableSipUpdate = true; + SalOpSDPHandling mDefaultSdpHandling = SalOpSDPNormal; + bool mPendingTransactionChecking = true; // For testing purposes + void *mSslConfig = nullptr; + std::vector mSupportedContentTypes; + std::string mLinphoneSpecs; + + // Cache values + mutable std::string mDnsUserHostsFile; + mutable std::string mHttpProxyHost; + mutable std::string mSupported; + mutable std::string mUserAgent; friend class SalOp; friend class SalCallOp; @@ -328,3 +339,4 @@ int to_sip_code(SalReason r); LINPHONE_END_NAMESPACE #endif // ifndef _L_SAL_H_ + diff --git a/src/search/magic-search.cpp b/src/search/magic-search.cpp index 6e8a8fa94..3c8c92379 100644 --- a/src/search/magic-search.cpp +++ b/src/search/magic-search.cpp @@ -20,11 +20,13 @@ #include "magic-search-p.h" #include +#include #include "c-wrapper/internal/c-tools.h" #include "linphone/utils/utils.h" #include "linphone/core.h" #include "linphone/types.h" +#include "logger/logger.h" #include "private.h" using namespace std; @@ -119,7 +121,7 @@ list MagicSearch::getContactListFromFilter(const string &filter, c list returnList; LinphoneProxyConfig *proxy = nullptr; - if (filter.empty()) return list(); + if (filter.empty()) return getAllFriends(); if (getSearchCache() != nullptr) { resultList = continueSearch(filter, withDomain); @@ -148,7 +150,7 @@ list MagicSearch::getContactListFromFilter(const string &filter, c if (domain) { string filterAddress = "sip:" + filter + "@" + domain; LinphoneAddress *lastResult = linphone_core_create_address(this->getCore()->getCCore(), filterAddress.c_str()); - if (lastResult) returnList.push_back(SearchResult(0, lastResult, nullptr)); + if (lastResult) returnList.push_back(SearchResult(0, lastResult, "", nullptr)); } } @@ -170,6 +172,23 @@ void MagicSearch::setSearchCache(list *cache) { d->mCacheResult = cache; } +list MagicSearch::getAllFriends() { + list returnList; + LinphoneFriendList *list = linphone_core_get_default_friend_list(this->getCore()->getCCore()); + + for (bctbx_list_t *f = list->friends ; f != nullptr ; f = bctbx_list_next(f)) { + const LinphoneFriend *lFriend = reinterpret_cast(f->data); + const LinphoneAddress* lAddress = linphone_friend_get_address(lFriend); + bctbx_list_t *lPhoneNumbers = linphone_friend_get_phone_numbers(lFriend); + string lPhoneNumber = (lPhoneNumbers != nullptr) ? static_cast(lPhoneNumbers->data) : ""; + + if (lAddress) linphone_address_ref(const_cast(lAddress)); + returnList.push_back(SearchResult(1, lAddress, lPhoneNumber, lFriend)); + } + + return returnList; +} + list *MagicSearch::beginNewSearch(const string &filter, const string &withDomain) { list *resultList = new list(); LinphoneFriendList *list = linphone_core_get_default_friend_list(this->getCore()->getCCore()); @@ -179,7 +198,9 @@ list *MagicSearch::beginNewSearch(const string &filter, const stri for (bctbx_list_t *f = list->friends ; f != nullptr ; f = bctbx_list_next(f)) { SearchResult result = searchInFriend(reinterpret_cast(f->data), filter, withDomain); if (result.getWeight() > getMinWeight()) { - resultList->push_back(result); + if (result.getAddress() || !result.getPhoneNumber().empty()) { + resultList->push_back(result); + } } } @@ -191,7 +212,9 @@ list *MagicSearch::beginNewSearch(const string &filter, const stri if (addr) { unsigned int weight = searchInAddress(addr, filter, withDomain); if (weight > getMinWeight()) { - resultList->push_back(SearchResult(weight, addr, nullptr)); + // FIXME: Ugly temporary workaround to solve weak. Remove me later. + linphone_address_ref(const_cast(addr)); + resultList->push_back(SearchResult(weight, addr, "", nullptr)); } } } @@ -204,10 +227,17 @@ list *MagicSearch::continueSearch(const string &filter, const stri const list *cacheList = getSearchCache(); for (const auto sr : *cacheList) { - if (sr.getFriend()) { - SearchResult result = searchInFriend(sr.getFriend(), filter, withDomain); - if (result.getWeight() > getMinWeight()) { - resultList->push_back(result); + if (sr.getAddress() || !sr.getPhoneNumber().empty()) { + if (sr.getFriend()) { + SearchResult result = searchInFriend(sr.getFriend(), filter, withDomain); + if (result.getWeight() > getMinWeight()) { + resultList->push_back(result); + } + } else { + unsigned int weight = searchInAddress(sr.getAddress(), filter, withDomain); + if (weight > getMinWeight()) { + resultList->push_back(SearchResult(weight, sr.getAddress(), sr.getPhoneNumber(), nullptr)); + } } } } @@ -216,10 +246,13 @@ list *MagicSearch::continueSearch(const string &filter, const stri } SearchResult MagicSearch::searchInFriend(const LinphoneFriend *lFriend, const string &filter, const string &withDomain) { + string phoneNumber = ""; unsigned int weight = getMinWeight(); const LinphoneAddress* lAddress = linphone_friend_get_address(lFriend); - if (!checkDomain(lFriend, lAddress, withDomain)) return SearchResult(weight, nullptr); + if (!checkDomain(lFriend, lAddress, withDomain)) { + if (!withDomain.empty()) return SearchResult(weight, nullptr, ""); + } // NAME if (linphone_core_vcard_supported()) { @@ -232,20 +265,29 @@ SearchResult MagicSearch::searchInFriend(const LinphoneFriend *lFriend, const st weight += searchInAddress(lAddress, filter, withDomain) * 1; // PHONE NUMBER + LinphoneProxyConfig *proxy = linphone_core_get_default_proxy_config(this->getCore()->getCCore()); bctbx_list_t *begin, *phoneNumbers = linphone_friend_get_phone_numbers(lFriend); begin = phoneNumbers; - while (phoneNumbers != nullptr && phoneNumbers->data != nullptr) { + while (phoneNumbers && phoneNumbers->data) { string number = static_cast(phoneNumbers->data); const LinphonePresenceModel *presence = linphone_friend_get_presence_model_for_uri_or_tel(lFriend, number.c_str()); - weight += getWeight(number, filter); - if (presence != nullptr) { - weight += getWeight(linphone_presence_model_get_contact(presence), filter) * 2; + phoneNumber = number; + if (proxy) { + phoneNumber = linphone_proxy_config_normalize_phone_number(proxy, phoneNumber.c_str()); + } + weight += getWeight(phoneNumber.c_str(), filter); + if (presence) { + char *contact = linphone_presence_model_get_contact(presence); + weight += getWeight(contact, filter) * 2; + bctbx_free(contact); } phoneNumbers = phoneNumbers->next; } if (begin) bctbx_list_free(begin); - return SearchResult(weight, lAddress, lFriend); + // FIXME: Ugly temporary workaround to solve weak. Remove me later. + if (lAddress) linphone_address_ref(const_cast(lAddress)); + return SearchResult(weight, lAddress, phoneNumber, lFriend); } unsigned int MagicSearch::searchInAddress(const LinphoneAddress *lAddress, const string &filter, const string &withDomain) { @@ -264,12 +306,18 @@ unsigned int MagicSearch::searchInAddress(const LinphoneAddress *lAddress, const } unsigned int MagicSearch::getWeight(const string &stringWords, const string &filter) const { + locale loc; + string filterLC = filter; + string stringWordsLC = stringWords; size_t weight = string::npos; - // Finding all occurrences of "filter" in "stringWords" - for (size_t w = stringWords.find(filter); + transform(stringWordsLC.begin(), stringWordsLC.end(), stringWordsLC.begin(), [](unsigned char c){ return tolower(c); }); + transform(filterLC.begin(), filterLC.end(), filterLC.begin(), [](unsigned char c){ return tolower(c); }); + + // Finding all occurrences of "filterLC" in "stringWordsLC" + for (size_t w = stringWordsLC.find(filterLC); w != string::npos; - w = stringWords.find(filter, w + filter.length()) + w = stringWordsLC.find(filterLC, w + filterLC.length()) ) { // weight max if occurence find at beginning if (w == 0) { @@ -277,8 +325,8 @@ unsigned int MagicSearch::getWeight(const string &stringWords, const string &fil } else { bool isDelimiter = false; if (getUseDelimiter()) { - // get the char before the matched filter - const char l = stringWords.at(w - 1); + // get the char before the matched filterLC + const char l = stringWordsLC.at(w - 1); // Check if it's a delimiter for (const char d : getDelimiter()) { if (l == d) { @@ -290,7 +338,7 @@ unsigned int MagicSearch::getWeight(const string &stringWords, const string &fil unsigned int newWeight = getMaxWeight() - (unsigned int)((isDelimiter) ? 1 : w + 1); weight = (weight != string::npos) ? weight + newWeight : newWeight; } - // Only one search on the stringWords for the moment + // Only one search on the stringWordsLC for the moment // due to weight calcul which dos not take into the case of multiple occurence break; } @@ -300,20 +348,27 @@ unsigned int MagicSearch::getWeight(const string &stringWords, const string &fil bool MagicSearch::checkDomain(const LinphoneFriend *lFriend, const LinphoneAddress *lAddress, const string &withDomain) const { bool onlySipUri = !withDomain.empty() && withDomain.compare("*") != 0; - const LinphonePresenceModel *presenceModel = (lFriend) ? linphone_friend_get_presence_model(lFriend) : nullptr; - const char *contactPresence = (presenceModel) ? linphone_presence_model_get_contact(presenceModel) : nullptr; - const LinphoneAddress *addrPresence = (contactPresence) ? - linphone_core_create_address(this->getCore()->getCCore(), contactPresence) : nullptr; + const LinphonePresenceModel *presenceModel = lFriend ? linphone_friend_get_presence_model(lFriend) : nullptr; + char *contactPresence = presenceModel ? linphone_presence_model_get_contact(presenceModel) : nullptr; - return ( + LinphoneAddress *addrPresence = nullptr; + if (contactPresence) { + addrPresence = linphone_core_create_address(this->getCore()->getCCore(), contactPresence); + bctbx_free(contactPresence); + } + + bool soFarSoGood = // If we don't want Sip URI only or Address or Presence model - (!onlySipUri || lAddress != nullptr || presenceModel != nullptr) && + (!onlySipUri || lAddress || presenceModel) && // And If we don't want Sip URI only or Address match or Address presence match (!onlySipUri || - (lAddress != nullptr && withDomain.compare(linphone_address_get_domain(lAddress)) == 0) || - (addrPresence != nullptr && withDomain.compare(linphone_address_get_domain(addrPresence)) == 0) - ) - ); + (lAddress && withDomain.compare(linphone_address_get_domain(lAddress)) == 0) || + (addrPresence && withDomain.compare(linphone_address_get_domain(addrPresence)) == 0) + ); + + if (addrPresence) linphone_address_unref(addrPresence); + + return soFarSoGood; } LINPHONE_END_NAMESPACE diff --git a/src/search/magic-search.h b/src/search/magic-search.h index 7fa34f294..7020405c0 100644 --- a/src/search/magic-search.h +++ b/src/search/magic-search.h @@ -140,6 +140,13 @@ private: **/ void setSearchCache(std::list *cache); + /** + * Get all friends as SearchResult + * @return all friends in a SearchResult list + * @private + **/ + std::list getAllFriends(); + /** * Begin the search from friend list * @param[in] filter word we search diff --git a/src/search/search-result.cpp b/src/search/search-result.cpp index 2c032e76b..d8b78adea 100644 --- a/src/search/search-result.cpp +++ b/src/search/search-result.cpp @@ -17,46 +17,67 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "search-result-p.h" -#include "linphone/utils/utils.h" +#include "linphone/api/c-address.h" -using namespace LinphonePrivate; +#include "object/clonable-object-p.h" +#include "search-result.h" + +// ============================================================================= LINPHONE_BEGIN_NAMESPACE -SearchResult::SearchResult(const unsigned int weight, const LinphoneAddress *a, const LinphoneFriend *f) : ClonableObject(*new SearchResultPrivate) { +class SearchResultPrivate : public ClonableObjectPrivate { +private: + const LinphoneFriend *mFriend; + const LinphoneAddress *mAddress; + std::string mPhoneNumber; + unsigned int mWeight; + + L_DECLARE_PUBLIC(SearchResult); +}; + +using namespace std; + +SearchResult::SearchResult(const unsigned int weight, const LinphoneAddress *a, const string &pn, const LinphoneFriend *f) : ClonableObject(*new SearchResultPrivate) { L_D(); d->mWeight = weight; d->mAddress = a; d->mFriend = f; + d->mPhoneNumber = pn; } SearchResult::SearchResult(const SearchResult &sr) : ClonableObject(*new SearchResultPrivate) { L_D(); d->mWeight = sr.getWeight(); d->mAddress = sr.getAddress(); + if (d->mAddress) linphone_address_ref(const_cast(d->mAddress)); d->mFriend = sr.getFriend(); + d->mPhoneNumber = sr.getPhoneNumber(); } -SearchResult::~SearchResult() {}; +SearchResult::~SearchResult() { + L_D(); + // FIXME: Ugly temporary workaround to solve weak. Remove me later. + if (d->mAddress) linphone_address_unref(const_cast(d->mAddress)); +}; -bool SearchResult::operator<(const SearchResult& rsr) const{ - return this->getWeight() < rsr.getWeight(); +bool SearchResult::operator<(const SearchResult &other) const { + return getWeight() < other.getWeight(); } -bool SearchResult::operator>(const SearchResult& rsr) const{ - return this->getWeight() > rsr.getWeight(); +bool SearchResult::operator>(const SearchResult &other) const { + return getWeight() > other.getWeight(); } -bool SearchResult::operator>=(const SearchResult& rsr) const{ - return this->getWeight() >= rsr.getWeight(); +bool SearchResult::operator>=(const SearchResult &other) const { + return getWeight() >= other.getWeight(); } -bool SearchResult::operator=(const SearchResult& rsr) const{ - return this->getWeight() == rsr.getWeight(); +bool SearchResult::operator=(const SearchResult &other) const { + return getWeight() == other.getWeight(); } -const LinphoneFriend* SearchResult::getFriend() const { +const LinphoneFriend *SearchResult::getFriend() const { L_D(); return d->mFriend; } @@ -66,6 +87,11 @@ const LinphoneAddress *SearchResult::getAddress() const { return d->mAddress; } +const string &SearchResult::getPhoneNumber() const { + L_D(); + return d->mPhoneNumber; +} + unsigned int SearchResult::getWeight() const { L_D(); return d->mWeight; diff --git a/src/search/search-result.h b/src/search/search-result.h index d453a273a..cee73aafc 100644 --- a/src/search/search-result.h +++ b/src/search/search-result.h @@ -20,10 +20,12 @@ #ifndef _L_SEARCH_RESULT_H_ #define _L_SEARCH_RESULT_H_ -#include "object/clonable-object.h" #include "linphone/utils/general.h" #include "linphone/types.h" -#include "private.h" + +#include "object/clonable-object.h" + +// ============================================================================= LINPHONE_BEGIN_NAMESPACE @@ -31,25 +33,30 @@ class SearchResultPrivate; class LINPHONE_PUBLIC SearchResult : public ClonableObject { public: - SearchResult() = delete; - SearchResult(const unsigned int weight, const LinphoneAddress *a, const LinphoneFriend *f = nullptr); - SearchResult(const SearchResult &sr); + // TODO: Use C++ Address! Not LinphoneAddress. + SearchResult(const unsigned int weight, const LinphoneAddress *a, const std::string &pn, const LinphoneFriend *f = nullptr); + SearchResult(const SearchResult &other); ~SearchResult(); - bool operator<(const SearchResult& rsr) const; - bool operator>(const SearchResult& rsr) const; - bool operator>=(const SearchResult& rsr) const; - bool operator=(const SearchResult& rsr) const; + bool operator<(const SearchResult &other) const; + bool operator>(const SearchResult &other) const; + bool operator>=(const SearchResult &other) const; + bool operator=(const SearchResult &other) const; /** * @return LinphoneFriend associed **/ - const LinphoneFriend* getFriend() const; + const LinphoneFriend *getFriend()const; /** * @return LinphoneAddress associed **/ - const LinphoneAddress* getAddress() const; + const LinphoneAddress *getAddress() const; + + /** + * @return Phone Number associed + **/ + const std::string &getPhoneNumber() const; /** * @return the result weight diff --git a/src/sip-tools/sip-headers.h b/src/sip-tools/sip-headers.h index 969735841..788fec285 100644 --- a/src/sip-tools/sip-headers.h +++ b/src/sip-tools/sip-headers.h @@ -29,13 +29,13 @@ using namespace std; LINPHONE_BEGIN_NAMESPACE namespace PriorityHeader { - constexpr const char HeaderName[] = "Priority"; + constexpr char HeaderName[] = "Priority"; // Values - constexpr const char NonUrgent[] = "non-urgent"; - constexpr const char Urgent[] = "urgent"; - constexpr const char Emergency[] = "emergency"; - constexpr const char Normal[] = "normal"; + constexpr char NonUrgent[] = "non-urgent"; + constexpr char Urgent[] = "urgent"; + constexpr char Emergency[] = "emergency"; + constexpr char Normal[] = "normal"; } LINPHONE_END_NAMESPACE diff --git a/src/utils/background-task.cpp b/src/utils/background-task.cpp index 0aaeb3397..fcea4f2f3 100644 --- a/src/utils/background-task.cpp +++ b/src/utils/background-task.cpp @@ -27,6 +27,8 @@ // ============================================================================= +using namespace std; + LINPHONE_BEGIN_NAMESPACE void BackgroundTask::sHandleTimeout (void *context) { @@ -43,7 +45,7 @@ void BackgroundTask::handleSalTimeout () { stop(); } -void BackgroundTask::start (const std::shared_ptr &core, int maxDurationSeconds) { +void BackgroundTask::start (const shared_ptr &core, int maxDurationSeconds) { if (mName.empty()) { lError() << "No name was set on background task"; return; @@ -59,7 +61,7 @@ void BackgroundTask::start (const std::shared_ptr &core, int maxDurationSe mId = newId; if (maxDurationSeconds > 0) { mSal = core->getCCore()->sal; - mTimeout = mSal->create_timer(sHandleSalTimeout, this, (unsigned int)maxDurationSeconds * 1000, mName.c_str()); + mTimeout = mSal->createTimer(sHandleSalTimeout, this, (unsigned int)maxDurationSeconds * 1000, mName.c_str()); } } @@ -70,7 +72,7 @@ void BackgroundTask::stop () { lInfo() << "Ending background task [" << mId << "] with name: [" << mName << "]"; sal_end_background_task(mId); if (mTimeout) { - mSal->cancel_timer(mTimeout); + mSal->cancelTimer(mTimeout); belle_sip_object_unref(mTimeout); mTimeout = nullptr; } diff --git a/src/utils/background-task.h b/src/utils/background-task.h index 2567a5b6d..fbf11106f 100644 --- a/src/utils/background-task.h +++ b/src/utils/background-task.h @@ -35,23 +35,17 @@ class Core; class BackgroundTask { public: BackgroundTask () {} - BackgroundTask (const std::string &name) {} - virtual ~BackgroundTask () { - stop(); - } + BackgroundTask (const std::string &name) : mName(name) {} + virtual ~BackgroundTask () { stop(); } - void setName (const std::string &name) { - mName = name; - } + void setName (const std::string &name) { mName = name; } - const std::string &getName () const { - return mName; - } + const std::string &getName () const { return mName; } /** * Start a long running task for at most max_duration_seconds, after which it is automatically terminated */ - void start (const std::shared_ptr &core, int maxDurationSeconds = 15 * 60); // 15 min by default, like on iOS + void start (const std::shared_ptr &core, int maxDurationSeconds = 15 * 60); // 15 min by default, like on iOS void stop (); protected: diff --git a/src/utils/utils.cpp b/src/utils/utils.cpp index eb5ba94d2..b05174a63 100644 --- a/src/utils/utils.cpp +++ b/src/utils/utils.cpp @@ -27,6 +27,10 @@ #include "linphone/utils/utils.h" +#include "logger/logger.h" + +#include "private.h" + // ============================================================================= using namespace std; @@ -184,12 +188,42 @@ string Utils::trim (const string &str) { // ----------------------------------------------------------------------------- tm Utils::getTimeTAsTm (time_t time) { - tm result; - return *gmtime_r(&time, &result); + #ifdef _WIN32 + return *gmtime(&time); + #else + tm result; + return *gmtime_r(&time, &result); + #endif } -long Utils::getTmAsTimeT (const tm &time) { - return timegm(&const_cast(time)); +time_t Utils::getTmAsTimeT (const tm &time) { + time_t result; + + #if defined(LINPHONE_WINDOWS_UNIVERSAL) || defined(LINPHONE_MSC_VER_GREATER_19) + long adjust_timezone; + #else + time_t adjust_timezone; + #endif + + #if TARGET_IPHONE_SIMULATOR + result = timegm(&const_cast(time)); + adjust_timezone = 0; + #else + result = mktime(&const_cast(time)); + + #if defined(LINPHONE_WINDOWS_UNIVERSAL) || defined(LINPHONE_MSC_VER_GREATER_19) + _get_timezone(&adjust_timezone); + #else + adjust_timezone = timezone; + #endif + #endif + + if (result == (time_t)-1) { + lError() << "mktime failed: " << strerror(errno); + return (time_t)-1; + } + + return result - (time_t)adjust_timezone; } // ----------------------------------------------------------------------------- diff --git a/src/xml/conference-info.cpp b/src/xml/conference-info.cpp index 5089051d7..59f648483 100644 --- a/src/xml/conference-info.cpp +++ b/src/xml/conference-info.cpp @@ -36,9 +36,16 @@ #if __clang__ || __GNUC__ >= 4 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wfloat-equal" + #pragma GCC diagnostic ignored "-Wsign-conversion" + #pragma GCC diagnostic ignored "-Wconversion" +#endif #if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-override" #endif +#if __GNUC__ >=7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" #endif // // End prologue. @@ -54,7 +61,7 @@ namespace LinphonePrivate namespace ConferenceInfo { // ConferenceType - // + // const ConferenceType::ConferenceDescriptionOptional& ConferenceType:: getConferenceDescription () const @@ -376,7 +383,7 @@ namespace LinphonePrivate // StateType - // + // StateType:: StateType (Value v) @@ -413,7 +420,7 @@ namespace LinphonePrivate StateType& StateType:: operator= (Value v) { - static_cast< ::LinphonePrivate::Xsd::XmlSchema::String& > (*this) = + static_cast< ::LinphonePrivate::Xsd::XmlSchema::String& > (*this) = ::LinphonePrivate::Xsd::XmlSchema::String (_xsd_StateType_literals_[v]); return *this; @@ -421,7 +428,7 @@ namespace LinphonePrivate // ConferenceDescriptionType - // + // const ConferenceDescriptionType::DisplayTextOptional& ConferenceDescriptionType:: getDisplayText () const @@ -707,7 +714,7 @@ namespace LinphonePrivate // HostType - // + // const HostType::DisplayTextOptional& HostType:: getDisplayText () const @@ -849,7 +856,7 @@ namespace LinphonePrivate // ConferenceStateType - // + // const ConferenceStateType::UserCountOptional& ConferenceStateType:: getUserCount () const @@ -973,7 +980,7 @@ namespace LinphonePrivate // ConferenceMediaType - // + // const ConferenceMediaType::EntrySequence& ConferenceMediaType:: getEntry () const @@ -1025,7 +1032,7 @@ namespace LinphonePrivate // ConferenceMediumType - // + // const ConferenceMediumType::DisplayTextOptional& ConferenceMediumType:: getDisplayText () const @@ -1197,7 +1204,7 @@ namespace LinphonePrivate // UrisType - // + // const UrisType::EntrySequence& UrisType:: getEntry () const @@ -1285,7 +1292,7 @@ namespace LinphonePrivate // UriType - // + // const UriType::UriType1& UriType:: getUri () const @@ -1481,7 +1488,7 @@ namespace LinphonePrivate } // UsersType - // + // const UsersType::UserSequence& UsersType:: getUser () const @@ -1587,7 +1594,7 @@ namespace LinphonePrivate // UserType - // + // const UserType::DisplayTextOptional& UserType:: getDisplayText () const @@ -1873,7 +1880,7 @@ namespace LinphonePrivate // UserRolesType - // + // const UserRolesType::EntrySequence& UserRolesType:: getEntry () const @@ -1949,7 +1956,7 @@ namespace LinphonePrivate } // EndpointType - // + // const EndpointType::DisplayTextOptional& EndpointType:: getDisplayText () const @@ -2325,7 +2332,7 @@ namespace LinphonePrivate // EndpointStatusType - // + // EndpointStatusType:: EndpointStatusType (Value v) @@ -2362,7 +2369,7 @@ namespace LinphonePrivate EndpointStatusType& EndpointStatusType:: operator= (Value v) { - static_cast< ::LinphonePrivate::Xsd::XmlSchema::String& > (*this) = + static_cast< ::LinphonePrivate::Xsd::XmlSchema::String& > (*this) = ::LinphonePrivate::Xsd::XmlSchema::String (_xsd_EndpointStatusType_literals_[v]); return *this; @@ -2370,7 +2377,7 @@ namespace LinphonePrivate // JoiningType - // + // JoiningType:: JoiningType (Value v) @@ -2407,7 +2414,7 @@ namespace LinphonePrivate JoiningType& JoiningType:: operator= (Value v) { - static_cast< ::LinphonePrivate::Xsd::XmlSchema::String& > (*this) = + static_cast< ::LinphonePrivate::Xsd::XmlSchema::String& > (*this) = ::LinphonePrivate::Xsd::XmlSchema::String (_xsd_JoiningType_literals_[v]); return *this; @@ -2415,7 +2422,7 @@ namespace LinphonePrivate // DisconnectionType - // + // DisconnectionType:: DisconnectionType (Value v) @@ -2452,7 +2459,7 @@ namespace LinphonePrivate DisconnectionType& DisconnectionType:: operator= (Value v) { - static_cast< ::LinphonePrivate::Xsd::XmlSchema::String& > (*this) = + static_cast< ::LinphonePrivate::Xsd::XmlSchema::String& > (*this) = ::LinphonePrivate::Xsd::XmlSchema::String (_xsd_DisconnectionType_literals_[v]); return *this; @@ -2460,7 +2467,7 @@ namespace LinphonePrivate // ExecutionType - // + // const ExecutionType::WhenOptional& ExecutionType:: getWhen () const @@ -2584,7 +2591,7 @@ namespace LinphonePrivate // CallType - // + // const CallType::SipOptional& CallType:: getSip () const @@ -2666,7 +2673,7 @@ namespace LinphonePrivate // SipDialogIdType - // + // const SipDialogIdType::DisplayTextOptional& SipDialogIdType:: getDisplayText () const @@ -2838,7 +2845,7 @@ namespace LinphonePrivate // MediaType - // + // const MediaType::DisplayTextOptional& MediaType:: getDisplayText () const @@ -3070,7 +3077,7 @@ namespace LinphonePrivate // MediaStatusType - // + // MediaStatusType:: MediaStatusType (Value v) @@ -3107,7 +3114,7 @@ namespace LinphonePrivate MediaStatusType& MediaStatusType:: operator= (Value v) { - static_cast< ::LinphonePrivate::Xsd::XmlSchema::String& > (*this) = + static_cast< ::LinphonePrivate::Xsd::XmlSchema::String& > (*this) = ::LinphonePrivate::Xsd::XmlSchema::String (_xsd_MediaStatusType_literals_[v]); return *this; @@ -3115,7 +3122,7 @@ namespace LinphonePrivate // SidebarsByValType - // + // const SidebarsByValType::EntrySequence& SidebarsByValType:: getEntry () const @@ -3208,6 +3215,15 @@ namespace LinphonePrivate #include +#include + +namespace _xsd +{ + static + const ::xsd::cxx::tree::type_factory_plate< 0, char > + type_factory_plate_init; +} + namespace LinphonePrivate { namespace Xsd @@ -6779,6 +6795,15 @@ namespace LinphonePrivate #include +#include + +namespace _xsd +{ + static + const ::xsd::cxx::tree::std_ostream_plate< 0, char > + std_ostream_plate_init; +} + namespace LinphonePrivate { namespace Xsd @@ -7563,6 +7588,15 @@ namespace LinphonePrivate #include #include +#include + +namespace _xsd +{ + static + const ::xsd::cxx::tree::type_serializer_plate< 0, char > + type_serializer_plate_init; +} + namespace LinphonePrivate { namespace Xsd @@ -9304,8 +9338,15 @@ namespace LinphonePrivate // Begin epilogue. // +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif +#if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) + #pragma GCC diagnostic pop +#endif #if __clang__ || __GNUC__ >= 4 #pragma GCC diagnostic pop #endif // // End epilogue. + diff --git a/src/xml/conference-info.h b/src/xml/conference-info.h index 79e9e19c3..e9c315fd5 100644 --- a/src/xml/conference-info.h +++ b/src/xml/conference-info.h @@ -51,9 +51,16 @@ #if __clang__ || __GNUC__ >= 4 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wfloat-equal" + #pragma GCC diagnostic ignored "-Wsign-conversion" + #pragma GCC diagnostic ignored "-Wconversion" +#endif #if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-override" #endif +#if __GNUC__ >=7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" #endif // // End prologue. @@ -240,6 +247,8 @@ namespace LinphonePrivate typedef ::xsd::cxx::tree::unexpected_enumerator< char > UnexpectedEnumerator; typedef ::xsd::cxx::tree::expected_text_content< char > ExpectedTextContent; typedef ::xsd::cxx::tree::no_prefix_mapping< char > NoPrefixMapping; + typedef ::xsd::cxx::tree::no_type_info< char > NoTypeInfo; + typedef ::xsd::cxx::tree::not_derived< char > NotDerived; typedef ::xsd::cxx::tree::serialization< char > Serialization; // Error handler callback interface. @@ -573,7 +582,7 @@ namespace LinphonePrivate ConferenceType& operator= (const ConferenceType& x); - virtual + virtual ~ConferenceType (); // Implementation. @@ -882,7 +891,7 @@ namespace LinphonePrivate ConferenceDescriptionType& operator= (const ConferenceDescriptionType& x); - virtual + virtual ~ConferenceDescriptionType (); // Implementation. @@ -1030,7 +1039,7 @@ namespace LinphonePrivate HostType& operator= (const HostType& x); - virtual + virtual ~HostType (); // Implementation. @@ -1164,7 +1173,7 @@ namespace LinphonePrivate ConferenceStateType& operator= (const ConferenceStateType& x); - virtual + virtual ~ConferenceStateType (); // Implementation. @@ -1246,7 +1255,7 @@ namespace LinphonePrivate ConferenceMediaType& operator= (const ConferenceMediaType& x); - virtual + virtual ~ConferenceMediaType (); // Implementation. @@ -1406,7 +1415,7 @@ namespace LinphonePrivate ConferenceMediumType& operator= (const ConferenceMediumType& x); - virtual + virtual ~ConferenceMediumType (); // Implementation. @@ -1512,7 +1521,7 @@ namespace LinphonePrivate UrisType& operator= (const UrisType& x); - virtual + virtual ~UrisType (); // Implementation. @@ -1674,7 +1683,7 @@ namespace LinphonePrivate UriType& operator= (const UriType& x); - virtual + virtual ~UriType (); // Implementation. @@ -1730,7 +1739,7 @@ namespace LinphonePrivate _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0) const; - virtual + virtual ~KeywordsType (); }; @@ -1834,7 +1843,7 @@ namespace LinphonePrivate UsersType& operator= (const UsersType& x); - virtual + virtual ~UsersType (); // Implementation. @@ -2080,7 +2089,7 @@ namespace LinphonePrivate UserType& operator= (const UserType& x); - virtual + virtual ~UserType (); // Implementation. @@ -2168,7 +2177,7 @@ namespace LinphonePrivate UserRolesType& operator= (const UserRolesType& x); - virtual + virtual ~UserRolesType (); // Implementation. @@ -2220,7 +2229,7 @@ namespace LinphonePrivate _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0) const; - virtual + virtual ~UserLanguagesType (); }; @@ -2513,7 +2522,7 @@ namespace LinphonePrivate EndpointType& operator= (const EndpointType& x); - virtual + virtual ~EndpointType (); // Implementation. @@ -2828,7 +2837,7 @@ namespace LinphonePrivate ExecutionType& operator= (const ExecutionType& x); - virtual + virtual ~ExecutionType (); // Implementation. @@ -2928,7 +2937,7 @@ namespace LinphonePrivate CallType& operator= (const CallType& x); - virtual + virtual ~CallType (); // Implementation. @@ -3089,7 +3098,7 @@ namespace LinphonePrivate SipDialogIdType& operator= (const SipDialogIdType& x); - virtual + virtual ~SipDialogIdType (); // Implementation. @@ -3295,7 +3304,7 @@ namespace LinphonePrivate MediaType& operator= (const MediaType& x); - virtual + virtual ~MediaType (); // Implementation. @@ -3461,7 +3470,7 @@ namespace LinphonePrivate SidebarsByValType& operator= (const SidebarsByValType& x); - virtual + virtual ~SidebarsByValType (); // Implementation. @@ -3708,14 +3717,14 @@ namespace LinphonePrivate void serializeConferenceInfo (::std::ostream& os, - const ::LinphonePrivate::Xsd::ConferenceInfo::ConferenceType& x, + const ::LinphonePrivate::Xsd::ConferenceInfo::ConferenceType& x, const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), const ::std::string& e = "UTF-8", ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); void serializeConferenceInfo (::std::ostream& os, - const ::LinphonePrivate::Xsd::ConferenceInfo::ConferenceType& x, + const ::LinphonePrivate::Xsd::ConferenceInfo::ConferenceType& x, ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& eh, const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), const ::std::string& e = "UTF-8", @@ -3723,7 +3732,7 @@ namespace LinphonePrivate void serializeConferenceInfo (::std::ostream& os, - const ::LinphonePrivate::Xsd::ConferenceInfo::ConferenceType& x, + const ::LinphonePrivate::Xsd::ConferenceInfo::ConferenceType& x, ::xercesc::DOMErrorHandler& eh, const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), const ::std::string& e = "UTF-8", @@ -3734,14 +3743,14 @@ namespace LinphonePrivate void serializeConferenceInfo (::xercesc::XMLFormatTarget& ft, - const ::LinphonePrivate::Xsd::ConferenceInfo::ConferenceType& x, + const ::LinphonePrivate::Xsd::ConferenceInfo::ConferenceType& x, const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), const ::std::string& e = "UTF-8", ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); void serializeConferenceInfo (::xercesc::XMLFormatTarget& ft, - const ::LinphonePrivate::Xsd::ConferenceInfo::ConferenceType& x, + const ::LinphonePrivate::Xsd::ConferenceInfo::ConferenceType& x, ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& eh, const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), const ::std::string& e = "UTF-8", @@ -3749,7 +3758,7 @@ namespace LinphonePrivate void serializeConferenceInfo (::xercesc::XMLFormatTarget& ft, - const ::LinphonePrivate::Xsd::ConferenceInfo::ConferenceType& x, + const ::LinphonePrivate::Xsd::ConferenceInfo::ConferenceType& x, ::xercesc::DOMErrorHandler& eh, const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), const ::std::string& e = "UTF-8", @@ -3767,7 +3776,7 @@ namespace LinphonePrivate // ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > - serializeConferenceInfo (const ::LinphonePrivate::Xsd::ConferenceInfo::ConferenceType& x, + serializeConferenceInfo (const ::LinphonePrivate::Xsd::ConferenceInfo::ConferenceType& x, const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); @@ -3899,6 +3908,12 @@ namespace LinphonePrivate // Begin epilogue. // +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif +#if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) + #pragma GCC diagnostic pop +#endif #if __clang__ || __GNUC__ >= 4 #pragma GCC diagnostic pop #endif diff --git a/src/xml/epilogue.txt b/src/xml/epilogue.txt index ebe68c888..faa93c2e5 100644 --- a/src/xml/epilogue.txt +++ b/src/xml/epilogue.txt @@ -1,3 +1,9 @@ +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif +#if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) + #pragma GCC diagnostic pop +#endif #if __clang__ || __GNUC__ >= 4 #pragma GCC diagnostic pop #endif diff --git a/src/xml/generate.py b/src/xml/generate.py index 0046c4b05..e1214dbf9 100755 --- a/src/xml/generate.py +++ b/src/xml/generate.py @@ -51,6 +51,7 @@ def generate(name): "--generate-serialization", "--generate-ostream", "--generate-detach", + "--generate-polymorphic", "--std", "c++11", "--type-naming", "java", "--function-naming", "java", @@ -62,6 +63,7 @@ def generate(name): "--show-sloc", "--prologue-file", prologue_file, "--epilogue-file", epilogue_file, + "--root-element-first", "--type-regex", "%(?:[^ ]* )?([^,-]+)-([^,-]+)-([^,-]+)-?([^,-]*)%\\u$1\\u$2\\u$3\\u$4%", "--type-regex", "%(?:[^ ]* )?([^,-]+)-([^,-]+)-?([^,-]*)%\\u$1\\u$2\\u$3%", "--type-regex", "%(?:[^ ]* )?([^,-]+)-?([^,-]*)%\\u$1\\u$2%", @@ -90,7 +92,11 @@ def generate(name): "--serializer-regex", "%([^-]+)-?([^-]*)%serialize\\u$1\\u$2%", "--namespace-map", "http://www.w3.org/2001/XMLSchema=LinphonePrivate::Xsd::XmlSchema", "--namespace-map", "urn:ietf:params:xml:ns:conference-info=LinphonePrivate::Xsd::ConferenceInfo", + "--namespace-map", "urn:ietf:params:xml:ns:imdn=LinphonePrivate::Xsd::Imdn", + "--namespace-map", "urn:ietf:params:xml:ns:im-iscomposing=LinphonePrivate::Xsd::IsComposing", + "--namespace-map", "http://www.linphone.org/xsds/imdn.xsd=LinphonePrivate::Xsd::LinphoneImdn", "--namespace-map", "urn:ietf:params:xml:ns:resource-lists=LinphonePrivate::Xsd::ResourceLists", + "--namespace-map", "urn:ietf:params:xml:ns:rlmi=LinphonePrivate::Xsd::Rlmi", source_file ], shell=False) p.communicate() @@ -100,7 +106,11 @@ def generate(name): def main(argv = None): generate("xml") generate("conference-info") + generate("imdn") + generate("is-composing") + generate("linphone-imdn") generate("resource-lists") + generate("rlmi") if __name__ == "__main__": sys.exit(main()) diff --git a/src/xml/imdn.cpp b/src/xml/imdn.cpp new file mode 100644 index 000000000..653fa2604 --- /dev/null +++ b/src/xml/imdn.cpp @@ -0,0 +1,3449 @@ +// Copyright (c) 2005-2014 Code Synthesis Tools CC +// +// This program was generated by CodeSynthesis XSD, an XML Schema to +// C++ data binding compiler. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as +// published by the Free Software Foundation. +// +// 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 St, Fifth Floor, Boston, MA 02110-1301 USA +// +// In addition, as a special exception, Code Synthesis Tools CC gives +// permission to link this program with the Xerces-C++ library (or with +// modified versions of Xerces-C++ that use the same license as Xerces-C++), +// and distribute linked combinations including the two. You must obey +// the GNU General Public License version 2 in all respects for all of +// the code used other than Xerces-C++. If you modify this copy of the +// program, you may extend this exception to your version of the program, +// but you are not obligated to do so. If you do not wish to do so, delete +// this exception statement from your version. +// +// Furthermore, Code Synthesis Tools CC makes a special exception for +// the Free/Libre and Open Source Software (FLOSS) which is described +// in the accompanying FLOSSE file. +// + +// Begin prologue. +// +#if __clang__ || __GNUC__ >= 4 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wfloat-equal" + #pragma GCC diagnostic ignored "-Wsign-conversion" + #pragma GCC diagnostic ignored "-Wconversion" +#endif +#if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsuggest-override" +#endif +#if __GNUC__ >=7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" +#endif +// +// End prologue. + +#include + +#include "imdn.h" + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace Imdn + { + // Imdn + // + + const Imdn::MessageIdType& Imdn:: + getMessageId () const + { + return this->message_id_.get (); + } + + Imdn::MessageIdType& Imdn:: + getMessageId () + { + return this->message_id_.get (); + } + + void Imdn:: + setMessageId (const MessageIdType& x) + { + this->message_id_.set (x); + } + + void Imdn:: + setMessageId (::std::unique_ptr< MessageIdType > x) + { + this->message_id_.set (std::move (x)); + } + + ::std::unique_ptr< Imdn::MessageIdType > Imdn:: + setDetachMessage_id () + { + return this->message_id_.detach (); + } + + const Imdn::DatetimeType& Imdn:: + getDatetime () const + { + return this->datetime_.get (); + } + + Imdn::DatetimeType& Imdn:: + getDatetime () + { + return this->datetime_.get (); + } + + void Imdn:: + setDatetime (const DatetimeType& x) + { + this->datetime_.set (x); + } + + void Imdn:: + setDatetime (::std::unique_ptr< DatetimeType > x) + { + this->datetime_.set (std::move (x)); + } + + ::std::unique_ptr< Imdn::DatetimeType > Imdn:: + setDetachDatetime () + { + return this->datetime_.detach (); + } + + const Imdn::RecipientUriOptional& Imdn:: + getRecipientUri () const + { + return this->recipient_uri_; + } + + Imdn::RecipientUriOptional& Imdn:: + getRecipientUri () + { + return this->recipient_uri_; + } + + void Imdn:: + setRecipientUri (const RecipientUriType& x) + { + this->recipient_uri_.set (x); + } + + void Imdn:: + setRecipientUri (const RecipientUriOptional& x) + { + this->recipient_uri_ = x; + } + + void Imdn:: + setRecipientUri (::std::unique_ptr< RecipientUriType > x) + { + this->recipient_uri_.set (std::move (x)); + } + + const Imdn::OriginalRecipientUriOptional& Imdn:: + getOriginalRecipientUri () const + { + return this->original_recipient_uri_; + } + + Imdn::OriginalRecipientUriOptional& Imdn:: + getOriginalRecipientUri () + { + return this->original_recipient_uri_; + } + + void Imdn:: + setOriginalRecipientUri (const OriginalRecipientUriType& x) + { + this->original_recipient_uri_.set (x); + } + + void Imdn:: + setOriginalRecipientUri (const OriginalRecipientUriOptional& x) + { + this->original_recipient_uri_ = x; + } + + void Imdn:: + setOriginalRecipientUri (::std::unique_ptr< OriginalRecipientUriType > x) + { + this->original_recipient_uri_.set (std::move (x)); + } + + const Imdn::SubjectOptional& Imdn:: + getSubject () const + { + return this->subject_; + } + + Imdn::SubjectOptional& Imdn:: + getSubject () + { + return this->subject_; + } + + void Imdn:: + setSubject (const SubjectType& x) + { + this->subject_.set (x); + } + + void Imdn:: + setSubject (const SubjectOptional& x) + { + this->subject_ = x; + } + + void Imdn:: + setSubject (::std::unique_ptr< SubjectType > x) + { + this->subject_.set (std::move (x)); + } + + const Imdn::DeliveryNotificationOptional& Imdn:: + getDeliveryNotification () const + { + return this->delivery_notification_; + } + + Imdn::DeliveryNotificationOptional& Imdn:: + getDeliveryNotification () + { + return this->delivery_notification_; + } + + void Imdn:: + setDeliveryNotification (const DeliveryNotificationType& x) + { + this->delivery_notification_.set (x); + } + + void Imdn:: + setDeliveryNotification (const DeliveryNotificationOptional& x) + { + this->delivery_notification_ = x; + } + + void Imdn:: + setDeliveryNotification (::std::unique_ptr< DeliveryNotificationType > x) + { + this->delivery_notification_.set (std::move (x)); + } + + const Imdn::DisplayNotificationOptional& Imdn:: + getDisplayNotification () const + { + return this->display_notification_; + } + + Imdn::DisplayNotificationOptional& Imdn:: + getDisplayNotification () + { + return this->display_notification_; + } + + void Imdn:: + setDisplayNotification (const DisplayNotificationType& x) + { + this->display_notification_.set (x); + } + + void Imdn:: + setDisplayNotification (const DisplayNotificationOptional& x) + { + this->display_notification_ = x; + } + + void Imdn:: + setDisplayNotification (::std::unique_ptr< DisplayNotificationType > x) + { + this->display_notification_.set (std::move (x)); + } + + const Imdn::ProcessingNotificationOptional& Imdn:: + getProcessingNotification () const + { + return this->processing_notification_; + } + + Imdn::ProcessingNotificationOptional& Imdn:: + getProcessingNotification () + { + return this->processing_notification_; + } + + void Imdn:: + setProcessingNotification (const ProcessingNotificationType& x) + { + this->processing_notification_.set (x); + } + + void Imdn:: + setProcessingNotification (const ProcessingNotificationOptional& x) + { + this->processing_notification_ = x; + } + + void Imdn:: + setProcessingNotification (::std::unique_ptr< ProcessingNotificationType > x) + { + this->processing_notification_.set (std::move (x)); + } + + const Imdn::AnySequence& Imdn:: + getAny () const + { + return this->any_; + } + + Imdn::AnySequence& Imdn:: + getAny () + { + return this->any_; + } + + void Imdn:: + setAny (const AnySequence& s) + { + this->any_ = s; + } + + const ::xercesc::DOMDocument& Imdn:: + getDomDocument () const + { + return *this->dom_document_; + } + + ::xercesc::DOMDocument& Imdn:: + getDomDocument () + { + return *this->dom_document_; + } + + + // DeliveryNotification + // + + const DeliveryNotification::StatusType& DeliveryNotification:: + getStatus () const + { + return this->status_.get (); + } + + DeliveryNotification::StatusType& DeliveryNotification:: + getStatus () + { + return this->status_.get (); + } + + void DeliveryNotification:: + setStatus (const StatusType& x) + { + this->status_.set (x); + } + + void DeliveryNotification:: + setStatus (::std::unique_ptr< StatusType > x) + { + this->status_.set (std::move (x)); + } + + ::std::unique_ptr< DeliveryNotification::StatusType > DeliveryNotification:: + setDetachStatus () + { + return this->status_.detach (); + } + + + // Delivered + // + + + // Failed + // + + + // DisplayNotification + // + + const DisplayNotification::StatusType& DisplayNotification:: + getStatus () const + { + return this->status_.get (); + } + + DisplayNotification::StatusType& DisplayNotification:: + getStatus () + { + return this->status_.get (); + } + + void DisplayNotification:: + setStatus (const StatusType& x) + { + this->status_.set (x); + } + + void DisplayNotification:: + setStatus (::std::unique_ptr< StatusType > x) + { + this->status_.set (std::move (x)); + } + + ::std::unique_ptr< DisplayNotification::StatusType > DisplayNotification:: + setDetachStatus () + { + return this->status_.detach (); + } + + + // Displayed + // + + + // ProcessingNotification + // + + const ProcessingNotification::StatusType& ProcessingNotification:: + getStatus () const + { + return this->status_.get (); + } + + ProcessingNotification::StatusType& ProcessingNotification:: + getStatus () + { + return this->status_.get (); + } + + void ProcessingNotification:: + setStatus (const StatusType& x) + { + this->status_.set (x); + } + + void ProcessingNotification:: + setStatus (::std::unique_ptr< StatusType > x) + { + this->status_.set (std::move (x)); + } + + ::std::unique_ptr< ProcessingNotification::StatusType > ProcessingNotification:: + setDetachStatus () + { + return this->status_.detach (); + } + + + // Processed + // + + + // Stored + // + + + // Forbidden + // + + + // Error + // + + + // Status + // + + const Status::DeliveredOptional& Status:: + getDelivered () const + { + return this->delivered_; + } + + Status::DeliveredOptional& Status:: + getDelivered () + { + return this->delivered_; + } + + void Status:: + setDelivered (const DeliveredType& x) + { + this->delivered_.set (x); + } + + void Status:: + setDelivered (const DeliveredOptional& x) + { + this->delivered_ = x; + } + + void Status:: + setDelivered (::std::unique_ptr< DeliveredType > x) + { + this->delivered_.set (std::move (x)); + } + + const Status::FailedOptional& Status:: + getFailed () const + { + return this->failed_; + } + + Status::FailedOptional& Status:: + getFailed () + { + return this->failed_; + } + + void Status:: + setFailed (const FailedType& x) + { + this->failed_.set (x); + } + + void Status:: + setFailed (const FailedOptional& x) + { + this->failed_ = x; + } + + void Status:: + setFailed (::std::unique_ptr< FailedType > x) + { + this->failed_.set (std::move (x)); + } + + const Status::ForbiddenOptional& Status:: + getForbidden () const + { + return this->forbidden_; + } + + Status::ForbiddenOptional& Status:: + getForbidden () + { + return this->forbidden_; + } + + void Status:: + setForbidden (const ForbiddenType& x) + { + this->forbidden_.set (x); + } + + void Status:: + setForbidden (const ForbiddenOptional& x) + { + this->forbidden_ = x; + } + + void Status:: + setForbidden (::std::unique_ptr< ForbiddenType > x) + { + this->forbidden_.set (std::move (x)); + } + + const Status::ErrorOptional& Status:: + getError () const + { + return this->error_; + } + + Status::ErrorOptional& Status:: + getError () + { + return this->error_; + } + + void Status:: + setError (const ErrorType& x) + { + this->error_.set (x); + } + + void Status:: + setError (const ErrorOptional& x) + { + this->error_ = x; + } + + void Status:: + setError (::std::unique_ptr< ErrorType > x) + { + this->error_.set (std::move (x)); + } + + const Status::ReasonOptional& Status:: + getReason () const + { + return this->reason_; + } + + Status::ReasonOptional& Status:: + getReason () + { + return this->reason_; + } + + void Status:: + setReason (const ReasonType& x) + { + this->reason_.set (x); + } + + void Status:: + setReason (const ReasonOptional& x) + { + this->reason_ = x; + } + + void Status:: + setReason (::std::unique_ptr< ReasonType > x) + { + this->reason_.set (std::move (x)); + } + + + // Status1 + // + + const Status1::DisplayedOptional& Status1:: + getDisplayed () const + { + return this->displayed_; + } + + Status1::DisplayedOptional& Status1:: + getDisplayed () + { + return this->displayed_; + } + + void Status1:: + setDisplayed (const DisplayedType& x) + { + this->displayed_.set (x); + } + + void Status1:: + setDisplayed (const DisplayedOptional& x) + { + this->displayed_ = x; + } + + void Status1:: + setDisplayed (::std::unique_ptr< DisplayedType > x) + { + this->displayed_.set (std::move (x)); + } + + const Status1::ForbiddenOptional& Status1:: + getForbidden () const + { + return this->forbidden_; + } + + Status1::ForbiddenOptional& Status1:: + getForbidden () + { + return this->forbidden_; + } + + void Status1:: + setForbidden (const ForbiddenType& x) + { + this->forbidden_.set (x); + } + + void Status1:: + setForbidden (const ForbiddenOptional& x) + { + this->forbidden_ = x; + } + + void Status1:: + setForbidden (::std::unique_ptr< ForbiddenType > x) + { + this->forbidden_.set (std::move (x)); + } + + const Status1::ErrorOptional& Status1:: + getError () const + { + return this->error_; + } + + Status1::ErrorOptional& Status1:: + getError () + { + return this->error_; + } + + void Status1:: + setError (const ErrorType& x) + { + this->error_.set (x); + } + + void Status1:: + setError (const ErrorOptional& x) + { + this->error_ = x; + } + + void Status1:: + setError (::std::unique_ptr< ErrorType > x) + { + this->error_.set (std::move (x)); + } + + const Status1::AnySequence& Status1:: + getAny () const + { + return this->any_; + } + + Status1::AnySequence& Status1:: + getAny () + { + return this->any_; + } + + void Status1:: + setAny (const AnySequence& s) + { + this->any_ = s; + } + + const ::xercesc::DOMDocument& Status1:: + getDomDocument () const + { + return *this->dom_document_; + } + + ::xercesc::DOMDocument& Status1:: + getDomDocument () + { + return *this->dom_document_; + } + + + // Status2 + // + + const Status2::ProcessedOptional& Status2:: + getProcessed () const + { + return this->processed_; + } + + Status2::ProcessedOptional& Status2:: + getProcessed () + { + return this->processed_; + } + + void Status2:: + setProcessed (const ProcessedType& x) + { + this->processed_.set (x); + } + + void Status2:: + setProcessed (const ProcessedOptional& x) + { + this->processed_ = x; + } + + void Status2:: + setProcessed (::std::unique_ptr< ProcessedType > x) + { + this->processed_.set (std::move (x)); + } + + const Status2::StoredOptional& Status2:: + getStored () const + { + return this->stored_; + } + + Status2::StoredOptional& Status2:: + getStored () + { + return this->stored_; + } + + void Status2:: + setStored (const StoredType& x) + { + this->stored_.set (x); + } + + void Status2:: + setStored (const StoredOptional& x) + { + this->stored_ = x; + } + + void Status2:: + setStored (::std::unique_ptr< StoredType > x) + { + this->stored_.set (std::move (x)); + } + + const Status2::ForbiddenOptional& Status2:: + getForbidden () const + { + return this->forbidden_; + } + + Status2::ForbiddenOptional& Status2:: + getForbidden () + { + return this->forbidden_; + } + + void Status2:: + setForbidden (const ForbiddenType& x) + { + this->forbidden_.set (x); + } + + void Status2:: + setForbidden (const ForbiddenOptional& x) + { + this->forbidden_ = x; + } + + void Status2:: + setForbidden (::std::unique_ptr< ForbiddenType > x) + { + this->forbidden_.set (std::move (x)); + } + + const Status2::ErrorOptional& Status2:: + getError () const + { + return this->error_; + } + + Status2::ErrorOptional& Status2:: + getError () + { + return this->error_; + } + + void Status2:: + setError (const ErrorType& x) + { + this->error_.set (x); + } + + void Status2:: + setError (const ErrorOptional& x) + { + this->error_ = x; + } + + void Status2:: + setError (::std::unique_ptr< ErrorType > x) + { + this->error_.set (std::move (x)); + } + + const Status2::AnySequence& Status2:: + getAny () const + { + return this->any_; + } + + Status2::AnySequence& Status2:: + getAny () + { + return this->any_; + } + + void Status2:: + setAny (const AnySequence& s) + { + this->any_ = s; + } + + const ::xercesc::DOMDocument& Status2:: + getDomDocument () const + { + return *this->dom_document_; + } + + ::xercesc::DOMDocument& Status2:: + getDomDocument () + { + return *this->dom_document_; + } + } + } +} + +#include + +#include + +#include + +namespace _xsd +{ + static + const ::xsd::cxx::tree::type_factory_plate< 0, char > + type_factory_plate_init; +} + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace Imdn + { + // Imdn + // + + Imdn:: + Imdn (const MessageIdType& message_id, + const DatetimeType& datetime) + : ::LinphonePrivate::Xsd::XmlSchema::Type (), + dom_document_ (::xsd::cxx::xml::dom::create_document< char > ()), + message_id_ (message_id, this), + datetime_ (datetime, this), + recipient_uri_ (this), + original_recipient_uri_ (this), + subject_ (this), + delivery_notification_ (this), + display_notification_ (this), + processing_notification_ (this), + any_ (this->getDomDocument ()) + { + } + + Imdn:: + Imdn (const Imdn& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (x, f, c), + dom_document_ (::xsd::cxx::xml::dom::create_document< char > ()), + message_id_ (x.message_id_, f, this), + datetime_ (x.datetime_, f, this), + recipient_uri_ (x.recipient_uri_, f, this), + original_recipient_uri_ (x.original_recipient_uri_, f, this), + subject_ (x.subject_, f, this), + delivery_notification_ (x.delivery_notification_, f, this), + display_notification_ (x.display_notification_, f, this), + processing_notification_ (x.processing_notification_, f, this), + any_ (x.any_, this->getDomDocument ()) + { + } + + Imdn:: + Imdn (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (e, f | ::LinphonePrivate::Xsd::XmlSchema::Flags::base, c), + dom_document_ (::xsd::cxx::xml::dom::create_document< char > ()), + message_id_ (this), + datetime_ (this), + recipient_uri_ (this), + original_recipient_uri_ (this), + subject_ (this), + delivery_notification_ (this), + display_notification_ (this), + processing_notification_ (this), + any_ (this->getDomDocument ()) + { + if ((f & ::LinphonePrivate::Xsd::XmlSchema::Flags::base) == 0) + { + ::xsd::cxx::xml::dom::parser< char > p (e, true, false, false); + this->parse (p, f); + } + } + + void Imdn:: + parse (::xsd::cxx::xml::dom::parser< char >& p, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + for (; p.more_content (); p.next_content (false)) + { + const ::xercesc::DOMElement& i (p.cur_element ()); + const ::xsd::cxx::xml::qualified_name< char > n ( + ::xsd::cxx::xml::dom::name< char > (i)); + + // message-id + // + if (n.name () == "message-id" && n.namespace_ () == "urn:ietf:params:xml:ns:imdn") + { + ::std::unique_ptr< MessageIdType > r ( + MessageIdTraits::create (i, f, this)); + + if (!message_id_.present ()) + { + this->message_id_.set (::std::move (r)); + continue; + } + } + + // datetime + // + if (n.name () == "datetime" && n.namespace_ () == "urn:ietf:params:xml:ns:imdn") + { + ::std::unique_ptr< DatetimeType > r ( + DatetimeTraits::create (i, f, this)); + + if (!datetime_.present ()) + { + this->datetime_.set (::std::move (r)); + continue; + } + } + + // recipient-uri + // + if (n.name () == "recipient-uri" && n.namespace_ () == "urn:ietf:params:xml:ns:imdn") + { + ::std::unique_ptr< RecipientUriType > r ( + RecipientUriTraits::create (i, f, this)); + + if (!this->recipient_uri_) + { + this->recipient_uri_.set (::std::move (r)); + continue; + } + } + + // original-recipient-uri + // + if (n.name () == "original-recipient-uri" && n.namespace_ () == "urn:ietf:params:xml:ns:imdn") + { + ::std::unique_ptr< OriginalRecipientUriType > r ( + OriginalRecipientUriTraits::create (i, f, this)); + + if (!this->original_recipient_uri_) + { + this->original_recipient_uri_.set (::std::move (r)); + continue; + } + } + + // subject + // + if (n.name () == "subject" && n.namespace_ () == "urn:ietf:params:xml:ns:imdn") + { + ::std::unique_ptr< SubjectType > r ( + SubjectTraits::create (i, f, this)); + + if (!this->subject_) + { + this->subject_.set (::std::move (r)); + continue; + } + } + + // delivery-notification + // + if (n.name () == "delivery-notification" && n.namespace_ () == "urn:ietf:params:xml:ns:imdn") + { + ::std::unique_ptr< DeliveryNotificationType > r ( + DeliveryNotificationTraits::create (i, f, this)); + + if (!this->delivery_notification_) + { + this->delivery_notification_.set (::std::move (r)); + continue; + } + } + + // display-notification + // + if (n.name () == "display-notification" && n.namespace_ () == "urn:ietf:params:xml:ns:imdn") + { + ::std::unique_ptr< DisplayNotificationType > r ( + DisplayNotificationTraits::create (i, f, this)); + + if (!this->display_notification_) + { + this->display_notification_.set (::std::move (r)); + continue; + } + } + + // processing-notification + // + if (n.name () == "processing-notification" && n.namespace_ () == "urn:ietf:params:xml:ns:imdn") + { + ::std::unique_ptr< ProcessingNotificationType > r ( + ProcessingNotificationTraits::create (i, f, this)); + + if (!this->processing_notification_) + { + this->processing_notification_.set (::std::move (r)); + continue; + } + } + + // any + // + if ((!n.namespace_ ().empty () && n.namespace_ () != "urn:ietf:params:xml:ns:imdn")) + { + ::xercesc::DOMElement* r ( + static_cast< ::xercesc::DOMElement* > ( + this->getDomDocument ().importNode ( + const_cast< ::xercesc::DOMElement* > (&i), true))); + this->any_.push_back (r); + continue; + } + + break; + } + + if (!message_id_.present ()) + { + throw ::xsd::cxx::tree::expected_element< char > ( + "message-id", + "urn:ietf:params:xml:ns:imdn"); + } + + if (!datetime_.present ()) + { + throw ::xsd::cxx::tree::expected_element< char > ( + "datetime", + "urn:ietf:params:xml:ns:imdn"); + } + } + + Imdn* Imdn:: + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) const + { + return new class Imdn (*this, f, c); + } + + Imdn& Imdn:: + operator= (const Imdn& x) + { + if (this != &x) + { + static_cast< ::LinphonePrivate::Xsd::XmlSchema::Type& > (*this) = x; + this->message_id_ = x.message_id_; + this->datetime_ = x.datetime_; + this->recipient_uri_ = x.recipient_uri_; + this->original_recipient_uri_ = x.original_recipient_uri_; + this->subject_ = x.subject_; + this->delivery_notification_ = x.delivery_notification_; + this->display_notification_ = x.display_notification_; + this->processing_notification_ = x.processing_notification_; + this->any_ = x.any_; + } + + return *this; + } + + Imdn:: + ~Imdn () + { + } + + // DeliveryNotification + // + + DeliveryNotification:: + DeliveryNotification (const StatusType& status) + : ::LinphonePrivate::Xsd::XmlSchema::Type (), + status_ (status, this) + { + } + + DeliveryNotification:: + DeliveryNotification (::std::unique_ptr< StatusType > status) + : ::LinphonePrivate::Xsd::XmlSchema::Type (), + status_ (std::move (status), this) + { + } + + DeliveryNotification:: + DeliveryNotification (const DeliveryNotification& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (x, f, c), + status_ (x.status_, f, this) + { + } + + DeliveryNotification:: + DeliveryNotification (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (e, f | ::LinphonePrivate::Xsd::XmlSchema::Flags::base, c), + status_ (this) + { + if ((f & ::LinphonePrivate::Xsd::XmlSchema::Flags::base) == 0) + { + ::xsd::cxx::xml::dom::parser< char > p (e, true, false, false); + this->parse (p, f); + } + } + + void DeliveryNotification:: + parse (::xsd::cxx::xml::dom::parser< char >& p, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + for (; p.more_content (); p.next_content (false)) + { + const ::xercesc::DOMElement& i (p.cur_element ()); + const ::xsd::cxx::xml::qualified_name< char > n ( + ::xsd::cxx::xml::dom::name< char > (i)); + + // status + // + if (n.name () == "status" && n.namespace_ () == "urn:ietf:params:xml:ns:imdn") + { + ::std::unique_ptr< StatusType > r ( + StatusTraits::create (i, f, this)); + + if (!status_.present ()) + { + this->status_.set (::std::move (r)); + continue; + } + } + + break; + } + + if (!status_.present ()) + { + throw ::xsd::cxx::tree::expected_element< char > ( + "status", + "urn:ietf:params:xml:ns:imdn"); + } + } + + DeliveryNotification* DeliveryNotification:: + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) const + { + return new class DeliveryNotification (*this, f, c); + } + + DeliveryNotification& DeliveryNotification:: + operator= (const DeliveryNotification& x) + { + if (this != &x) + { + static_cast< ::LinphonePrivate::Xsd::XmlSchema::Type& > (*this) = x; + this->status_ = x.status_; + } + + return *this; + } + + DeliveryNotification:: + ~DeliveryNotification () + { + } + + // Delivered + // + + Delivered:: + Delivered () + : ::LinphonePrivate::Xsd::XmlSchema::Type () + { + } + + Delivered:: + Delivered (const Delivered& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (x, f, c) + { + } + + Delivered:: + Delivered (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (e, f, c) + { + } + + Delivered:: + Delivered (const ::xercesc::DOMAttr& a, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (a, f, c) + { + } + + Delivered:: + Delivered (const ::std::string& s, + const ::xercesc::DOMElement* e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (s, e, f, c) + { + } + + Delivered* Delivered:: + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) const + { + return new class Delivered (*this, f, c); + } + + Delivered:: + ~Delivered () + { + } + + // Failed + // + + Failed:: + Failed () + : ::LinphonePrivate::Xsd::XmlSchema::Type () + { + } + + Failed:: + Failed (const Failed& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (x, f, c) + { + } + + Failed:: + Failed (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (e, f, c) + { + } + + Failed:: + Failed (const ::xercesc::DOMAttr& a, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (a, f, c) + { + } + + Failed:: + Failed (const ::std::string& s, + const ::xercesc::DOMElement* e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (s, e, f, c) + { + } + + Failed* Failed:: + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) const + { + return new class Failed (*this, f, c); + } + + Failed:: + ~Failed () + { + } + + // DisplayNotification + // + + DisplayNotification:: + DisplayNotification (const StatusType& status) + : ::LinphonePrivate::Xsd::XmlSchema::Type (), + status_ (status, this) + { + } + + DisplayNotification:: + DisplayNotification (::std::unique_ptr< StatusType > status) + : ::LinphonePrivate::Xsd::XmlSchema::Type (), + status_ (std::move (status), this) + { + } + + DisplayNotification:: + DisplayNotification (const DisplayNotification& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (x, f, c), + status_ (x.status_, f, this) + { + } + + DisplayNotification:: + DisplayNotification (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (e, f | ::LinphonePrivate::Xsd::XmlSchema::Flags::base, c), + status_ (this) + { + if ((f & ::LinphonePrivate::Xsd::XmlSchema::Flags::base) == 0) + { + ::xsd::cxx::xml::dom::parser< char > p (e, true, false, false); + this->parse (p, f); + } + } + + void DisplayNotification:: + parse (::xsd::cxx::xml::dom::parser< char >& p, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + for (; p.more_content (); p.next_content (false)) + { + const ::xercesc::DOMElement& i (p.cur_element ()); + const ::xsd::cxx::xml::qualified_name< char > n ( + ::xsd::cxx::xml::dom::name< char > (i)); + + // status + // + if (n.name () == "status" && n.namespace_ () == "urn:ietf:params:xml:ns:imdn") + { + ::std::unique_ptr< StatusType > r ( + StatusTraits::create (i, f, this)); + + if (!status_.present ()) + { + this->status_.set (::std::move (r)); + continue; + } + } + + break; + } + + if (!status_.present ()) + { + throw ::xsd::cxx::tree::expected_element< char > ( + "status", + "urn:ietf:params:xml:ns:imdn"); + } + } + + DisplayNotification* DisplayNotification:: + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) const + { + return new class DisplayNotification (*this, f, c); + } + + DisplayNotification& DisplayNotification:: + operator= (const DisplayNotification& x) + { + if (this != &x) + { + static_cast< ::LinphonePrivate::Xsd::XmlSchema::Type& > (*this) = x; + this->status_ = x.status_; + } + + return *this; + } + + DisplayNotification:: + ~DisplayNotification () + { + } + + // Displayed + // + + Displayed:: + Displayed () + : ::LinphonePrivate::Xsd::XmlSchema::Type () + { + } + + Displayed:: + Displayed (const Displayed& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (x, f, c) + { + } + + Displayed:: + Displayed (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (e, f, c) + { + } + + Displayed:: + Displayed (const ::xercesc::DOMAttr& a, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (a, f, c) + { + } + + Displayed:: + Displayed (const ::std::string& s, + const ::xercesc::DOMElement* e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (s, e, f, c) + { + } + + Displayed* Displayed:: + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) const + { + return new class Displayed (*this, f, c); + } + + Displayed:: + ~Displayed () + { + } + + // ProcessingNotification + // + + ProcessingNotification:: + ProcessingNotification (const StatusType& status) + : ::LinphonePrivate::Xsd::XmlSchema::Type (), + status_ (status, this) + { + } + + ProcessingNotification:: + ProcessingNotification (::std::unique_ptr< StatusType > status) + : ::LinphonePrivate::Xsd::XmlSchema::Type (), + status_ (std::move (status), this) + { + } + + ProcessingNotification:: + ProcessingNotification (const ProcessingNotification& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (x, f, c), + status_ (x.status_, f, this) + { + } + + ProcessingNotification:: + ProcessingNotification (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (e, f | ::LinphonePrivate::Xsd::XmlSchema::Flags::base, c), + status_ (this) + { + if ((f & ::LinphonePrivate::Xsd::XmlSchema::Flags::base) == 0) + { + ::xsd::cxx::xml::dom::parser< char > p (e, true, false, false); + this->parse (p, f); + } + } + + void ProcessingNotification:: + parse (::xsd::cxx::xml::dom::parser< char >& p, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + for (; p.more_content (); p.next_content (false)) + { + const ::xercesc::DOMElement& i (p.cur_element ()); + const ::xsd::cxx::xml::qualified_name< char > n ( + ::xsd::cxx::xml::dom::name< char > (i)); + + // status + // + if (n.name () == "status" && n.namespace_ () == "urn:ietf:params:xml:ns:imdn") + { + ::std::unique_ptr< StatusType > r ( + StatusTraits::create (i, f, this)); + + if (!status_.present ()) + { + this->status_.set (::std::move (r)); + continue; + } + } + + break; + } + + if (!status_.present ()) + { + throw ::xsd::cxx::tree::expected_element< char > ( + "status", + "urn:ietf:params:xml:ns:imdn"); + } + } + + ProcessingNotification* ProcessingNotification:: + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) const + { + return new class ProcessingNotification (*this, f, c); + } + + ProcessingNotification& ProcessingNotification:: + operator= (const ProcessingNotification& x) + { + if (this != &x) + { + static_cast< ::LinphonePrivate::Xsd::XmlSchema::Type& > (*this) = x; + this->status_ = x.status_; + } + + return *this; + } + + ProcessingNotification:: + ~ProcessingNotification () + { + } + + // Processed + // + + Processed:: + Processed () + : ::LinphonePrivate::Xsd::XmlSchema::Type () + { + } + + Processed:: + Processed (const Processed& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (x, f, c) + { + } + + Processed:: + Processed (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (e, f, c) + { + } + + Processed:: + Processed (const ::xercesc::DOMAttr& a, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (a, f, c) + { + } + + Processed:: + Processed (const ::std::string& s, + const ::xercesc::DOMElement* e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (s, e, f, c) + { + } + + Processed* Processed:: + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) const + { + return new class Processed (*this, f, c); + } + + Processed:: + ~Processed () + { + } + + // Stored + // + + Stored:: + Stored () + : ::LinphonePrivate::Xsd::XmlSchema::Type () + { + } + + Stored:: + Stored (const Stored& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (x, f, c) + { + } + + Stored:: + Stored (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (e, f, c) + { + } + + Stored:: + Stored (const ::xercesc::DOMAttr& a, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (a, f, c) + { + } + + Stored:: + Stored (const ::std::string& s, + const ::xercesc::DOMElement* e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (s, e, f, c) + { + } + + Stored* Stored:: + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) const + { + return new class Stored (*this, f, c); + } + + Stored:: + ~Stored () + { + } + + // Forbidden + // + + Forbidden:: + Forbidden () + : ::LinphonePrivate::Xsd::XmlSchema::Type () + { + } + + Forbidden:: + Forbidden (const Forbidden& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (x, f, c) + { + } + + Forbidden:: + Forbidden (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (e, f, c) + { + } + + Forbidden:: + Forbidden (const ::xercesc::DOMAttr& a, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (a, f, c) + { + } + + Forbidden:: + Forbidden (const ::std::string& s, + const ::xercesc::DOMElement* e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (s, e, f, c) + { + } + + Forbidden* Forbidden:: + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) const + { + return new class Forbidden (*this, f, c); + } + + Forbidden:: + ~Forbidden () + { + } + + // Error + // + + Error:: + Error () + : ::LinphonePrivate::Xsd::XmlSchema::Type () + { + } + + Error:: + Error (const Error& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (x, f, c) + { + } + + Error:: + Error (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (e, f, c) + { + } + + Error:: + Error (const ::xercesc::DOMAttr& a, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (a, f, c) + { + } + + Error:: + Error (const ::std::string& s, + const ::xercesc::DOMElement* e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (s, e, f, c) + { + } + + Error* Error:: + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) const + { + return new class Error (*this, f, c); + } + + Error:: + ~Error () + { + } + + // Status + // + + Status:: + Status () + : ::LinphonePrivate::Xsd::XmlSchema::Type (), + delivered_ (this), + failed_ (this), + forbidden_ (this), + error_ (this), + reason_ (this) + { + } + + Status:: + Status (const Status& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (x, f, c), + delivered_ (x.delivered_, f, this), + failed_ (x.failed_, f, this), + forbidden_ (x.forbidden_, f, this), + error_ (x.error_, f, this), + reason_ (x.reason_, f, this) + { + } + + Status:: + Status (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (e, f | ::LinphonePrivate::Xsd::XmlSchema::Flags::base, c), + delivered_ (this), + failed_ (this), + forbidden_ (this), + error_ (this), + reason_ (this) + { + if ((f & ::LinphonePrivate::Xsd::XmlSchema::Flags::base) == 0) + { + ::xsd::cxx::xml::dom::parser< char > p (e, true, false, false); + this->parse (p, f); + } + } + + void Status:: + parse (::xsd::cxx::xml::dom::parser< char >& p, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + for (; p.more_content (); p.next_content (false)) + { + const ::xercesc::DOMElement& i (p.cur_element ()); + const ::xsd::cxx::xml::qualified_name< char > n ( + ::xsd::cxx::xml::dom::name< char > (i)); + + // delivered + // + if (n.name () == "delivered" && n.namespace_ () == "urn:ietf:params:xml:ns:imdn") + { + ::std::unique_ptr< DeliveredType > r ( + DeliveredTraits::create (i, f, this)); + + if (!this->delivered_) + { + this->delivered_.set (::std::move (r)); + continue; + } + } + + // failed + // + if (n.name () == "failed" && n.namespace_ () == "urn:ietf:params:xml:ns:imdn") + { + ::std::unique_ptr< FailedType > r ( + FailedTraits::create (i, f, this)); + + if (!this->failed_) + { + this->failed_.set (::std::move (r)); + continue; + } + } + + // forbidden + // + if (n.name () == "forbidden" && n.namespace_ () == "urn:ietf:params:xml:ns:imdn") + { + ::std::unique_ptr< ForbiddenType > r ( + ForbiddenTraits::create (i, f, this)); + + if (!this->forbidden_) + { + this->forbidden_.set (::std::move (r)); + continue; + } + } + + // error + // + if (n.name () == "error" && n.namespace_ () == "urn:ietf:params:xml:ns:imdn") + { + ::std::unique_ptr< ErrorType > r ( + ErrorTraits::create (i, f, this)); + + if (!this->error_) + { + this->error_.set (::std::move (r)); + continue; + } + } + + // reason + // + if (n.name () == "reason" && n.namespace_ () == "http://www.linphone.org/xsds/imdn.xsd") + { + ::std::unique_ptr< ReasonType > r ( + ReasonTraits::create (i, f, this)); + + if (!this->reason_) + { + this->reason_.set (::std::move (r)); + continue; + } + } + + break; + } + } + + Status* Status:: + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) const + { + return new class Status (*this, f, c); + } + + Status& Status:: + operator= (const Status& x) + { + if (this != &x) + { + static_cast< ::LinphonePrivate::Xsd::XmlSchema::Type& > (*this) = x; + this->delivered_ = x.delivered_; + this->failed_ = x.failed_; + this->forbidden_ = x.forbidden_; + this->error_ = x.error_; + this->reason_ = x.reason_; + } + + return *this; + } + + Status:: + ~Status () + { + } + + // Status1 + // + + Status1:: + Status1 () + : ::LinphonePrivate::Xsd::XmlSchema::Type (), + dom_document_ (::xsd::cxx::xml::dom::create_document< char > ()), + displayed_ (this), + forbidden_ (this), + error_ (this), + any_ (this->getDomDocument ()) + { + } + + Status1:: + Status1 (const Status1& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (x, f, c), + dom_document_ (::xsd::cxx::xml::dom::create_document< char > ()), + displayed_ (x.displayed_, f, this), + forbidden_ (x.forbidden_, f, this), + error_ (x.error_, f, this), + any_ (x.any_, this->getDomDocument ()) + { + } + + Status1:: + Status1 (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (e, f | ::LinphonePrivate::Xsd::XmlSchema::Flags::base, c), + dom_document_ (::xsd::cxx::xml::dom::create_document< char > ()), + displayed_ (this), + forbidden_ (this), + error_ (this), + any_ (this->getDomDocument ()) + { + if ((f & ::LinphonePrivate::Xsd::XmlSchema::Flags::base) == 0) + { + ::xsd::cxx::xml::dom::parser< char > p (e, true, false, false); + this->parse (p, f); + } + } + + void Status1:: + parse (::xsd::cxx::xml::dom::parser< char >& p, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + for (; p.more_content (); p.next_content (false)) + { + const ::xercesc::DOMElement& i (p.cur_element ()); + const ::xsd::cxx::xml::qualified_name< char > n ( + ::xsd::cxx::xml::dom::name< char > (i)); + + // displayed + // + if (n.name () == "displayed" && n.namespace_ () == "urn:ietf:params:xml:ns:imdn") + { + ::std::unique_ptr< DisplayedType > r ( + DisplayedTraits::create (i, f, this)); + + if (!this->displayed_) + { + this->displayed_.set (::std::move (r)); + continue; + } + } + + // forbidden + // + if (n.name () == "forbidden" && n.namespace_ () == "urn:ietf:params:xml:ns:imdn") + { + ::std::unique_ptr< ForbiddenType > r ( + ForbiddenTraits::create (i, f, this)); + + if (!this->forbidden_) + { + this->forbidden_.set (::std::move (r)); + continue; + } + } + + // error + // + if (n.name () == "error" && n.namespace_ () == "urn:ietf:params:xml:ns:imdn") + { + ::std::unique_ptr< ErrorType > r ( + ErrorTraits::create (i, f, this)); + + if (!this->error_) + { + this->error_.set (::std::move (r)); + continue; + } + } + + // any + // + if ((!n.namespace_ ().empty () && n.namespace_ () != "urn:ietf:params:xml:ns:imdn")) + { + ::xercesc::DOMElement* r ( + static_cast< ::xercesc::DOMElement* > ( + this->getDomDocument ().importNode ( + const_cast< ::xercesc::DOMElement* > (&i), true))); + this->any_.push_back (r); + continue; + } + + break; + } + } + + Status1* Status1:: + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) const + { + return new class Status1 (*this, f, c); + } + + Status1& Status1:: + operator= (const Status1& x) + { + if (this != &x) + { + static_cast< ::LinphonePrivate::Xsd::XmlSchema::Type& > (*this) = x; + this->displayed_ = x.displayed_; + this->forbidden_ = x.forbidden_; + this->error_ = x.error_; + this->any_ = x.any_; + } + + return *this; + } + + Status1:: + ~Status1 () + { + } + + // Status2 + // + + Status2:: + Status2 () + : ::LinphonePrivate::Xsd::XmlSchema::Type (), + dom_document_ (::xsd::cxx::xml::dom::create_document< char > ()), + processed_ (this), + stored_ (this), + forbidden_ (this), + error_ (this), + any_ (this->getDomDocument ()) + { + } + + Status2:: + Status2 (const Status2& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (x, f, c), + dom_document_ (::xsd::cxx::xml::dom::create_document< char > ()), + processed_ (x.processed_, f, this), + stored_ (x.stored_, f, this), + forbidden_ (x.forbidden_, f, this), + error_ (x.error_, f, this), + any_ (x.any_, this->getDomDocument ()) + { + } + + Status2:: + Status2 (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (e, f | ::LinphonePrivate::Xsd::XmlSchema::Flags::base, c), + dom_document_ (::xsd::cxx::xml::dom::create_document< char > ()), + processed_ (this), + stored_ (this), + forbidden_ (this), + error_ (this), + any_ (this->getDomDocument ()) + { + if ((f & ::LinphonePrivate::Xsd::XmlSchema::Flags::base) == 0) + { + ::xsd::cxx::xml::dom::parser< char > p (e, true, false, false); + this->parse (p, f); + } + } + + void Status2:: + parse (::xsd::cxx::xml::dom::parser< char >& p, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + for (; p.more_content (); p.next_content (false)) + { + const ::xercesc::DOMElement& i (p.cur_element ()); + const ::xsd::cxx::xml::qualified_name< char > n ( + ::xsd::cxx::xml::dom::name< char > (i)); + + // processed + // + if (n.name () == "processed" && n.namespace_ () == "urn:ietf:params:xml:ns:imdn") + { + ::std::unique_ptr< ProcessedType > r ( + ProcessedTraits::create (i, f, this)); + + if (!this->processed_) + { + this->processed_.set (::std::move (r)); + continue; + } + } + + // stored + // + if (n.name () == "stored" && n.namespace_ () == "urn:ietf:params:xml:ns:imdn") + { + ::std::unique_ptr< StoredType > r ( + StoredTraits::create (i, f, this)); + + if (!this->stored_) + { + this->stored_.set (::std::move (r)); + continue; + } + } + + // forbidden + // + if (n.name () == "forbidden" && n.namespace_ () == "urn:ietf:params:xml:ns:imdn") + { + ::std::unique_ptr< ForbiddenType > r ( + ForbiddenTraits::create (i, f, this)); + + if (!this->forbidden_) + { + this->forbidden_.set (::std::move (r)); + continue; + } + } + + // error + // + if (n.name () == "error" && n.namespace_ () == "urn:ietf:params:xml:ns:imdn") + { + ::std::unique_ptr< ErrorType > r ( + ErrorTraits::create (i, f, this)); + + if (!this->error_) + { + this->error_.set (::std::move (r)); + continue; + } + } + + // any + // + if ((!n.namespace_ ().empty () && n.namespace_ () != "urn:ietf:params:xml:ns:imdn")) + { + ::xercesc::DOMElement* r ( + static_cast< ::xercesc::DOMElement* > ( + this->getDomDocument ().importNode ( + const_cast< ::xercesc::DOMElement* > (&i), true))); + this->any_.push_back (r); + continue; + } + + break; + } + } + + Status2* Status2:: + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) const + { + return new class Status2 (*this, f, c); + } + + Status2& Status2:: + operator= (const Status2& x) + { + if (this != &x) + { + static_cast< ::LinphonePrivate::Xsd::XmlSchema::Type& > (*this) = x; + this->processed_ = x.processed_; + this->stored_ = x.stored_; + this->forbidden_ = x.forbidden_; + this->error_ = x.error_; + this->any_ = x.any_; + } + + return *this; + } + + Status2:: + ~Status2 () + { + } + } + } +} + +#include + +#include + +namespace _xsd +{ + static + const ::xsd::cxx::tree::std_ostream_plate< 0, char > + std_ostream_plate_init; +} + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace Imdn + { + ::std::ostream& + operator<< (::std::ostream& o, const Imdn& i) + { + o << ::std::endl << "message-id: " << i.getMessageId (); + o << ::std::endl << "datetime: " << i.getDatetime (); + if (i.getRecipientUri ()) + { + o << ::std::endl << "recipient-uri: " << *i.getRecipientUri (); + } + + if (i.getOriginalRecipientUri ()) + { + o << ::std::endl << "original-recipient-uri: " << *i.getOriginalRecipientUri (); + } + + if (i.getSubject ()) + { + o << ::std::endl << "subject: " << *i.getSubject (); + } + + if (i.getDeliveryNotification ()) + { + o << ::std::endl << "delivery-notification: " << *i.getDeliveryNotification (); + } + + if (i.getDisplayNotification ()) + { + o << ::std::endl << "display-notification: " << *i.getDisplayNotification (); + } + + if (i.getProcessingNotification ()) + { + o << ::std::endl << "processing-notification: " << *i.getProcessingNotification (); + } + + return o; + } + + ::std::ostream& + operator<< (::std::ostream& o, const DeliveryNotification& i) + { + o << ::std::endl << "status: " << i.getStatus (); + return o; + } + + ::std::ostream& + operator<< (::std::ostream& o, const Delivered&) + { + return o; + } + + ::std::ostream& + operator<< (::std::ostream& o, const Failed&) + { + return o; + } + + ::std::ostream& + operator<< (::std::ostream& o, const DisplayNotification& i) + { + o << ::std::endl << "status: " << i.getStatus (); + return o; + } + + ::std::ostream& + operator<< (::std::ostream& o, const Displayed&) + { + return o; + } + + ::std::ostream& + operator<< (::std::ostream& o, const ProcessingNotification& i) + { + o << ::std::endl << "status: " << i.getStatus (); + return o; + } + + ::std::ostream& + operator<< (::std::ostream& o, const Processed&) + { + return o; + } + + ::std::ostream& + operator<< (::std::ostream& o, const Stored&) + { + return o; + } + + ::std::ostream& + operator<< (::std::ostream& o, const Forbidden&) + { + return o; + } + + ::std::ostream& + operator<< (::std::ostream& o, const Error&) + { + return o; + } + + ::std::ostream& + operator<< (::std::ostream& o, const Status& i) + { + if (i.getDelivered ()) + { + o << ::std::endl << "delivered: " << *i.getDelivered (); + } + + if (i.getFailed ()) + { + o << ::std::endl << "failed: " << *i.getFailed (); + } + + if (i.getForbidden ()) + { + o << ::std::endl << "forbidden: " << *i.getForbidden (); + } + + if (i.getError ()) + { + o << ::std::endl << "error: " << *i.getError (); + } + + if (i.getReason ()) + { + o << ::std::endl << "reason: " << *i.getReason (); + } + + return o; + } + + ::std::ostream& + operator<< (::std::ostream& o, const Status1& i) + { + if (i.getDisplayed ()) + { + o << ::std::endl << "displayed: " << *i.getDisplayed (); + } + + if (i.getForbidden ()) + { + o << ::std::endl << "forbidden: " << *i.getForbidden (); + } + + if (i.getError ()) + { + o << ::std::endl << "error: " << *i.getError (); + } + + return o; + } + + ::std::ostream& + operator<< (::std::ostream& o, const Status2& i) + { + if (i.getProcessed ()) + { + o << ::std::endl << "processed: " << *i.getProcessed (); + } + + if (i.getStored ()) + { + o << ::std::endl << "stored: " << *i.getStored (); + } + + if (i.getForbidden ()) + { + o << ::std::endl << "forbidden: " << *i.getForbidden (); + } + + if (i.getError ()) + { + o << ::std::endl << "error: " << *i.getError (); + } + + return o; + } + } + } +} + +#include +#include +#include + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace Imdn + { + ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > + parseImdn (const ::std::string& u, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0, + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) == 0); + + ::xsd::cxx::tree::error_handler< char > h; + + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::xsd::cxx::xml::dom::parse< char > ( + u, h, p, f)); + + h.throw_if_failed< ::xsd::cxx::tree::parsing< char > > (); + + return ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > ( + ::LinphonePrivate::Xsd::Imdn::parseImdn ( + std::move (d), f | ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom, p)); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > + parseImdn (const ::std::string& u, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0, + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) == 0); + + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::xsd::cxx::xml::dom::parse< char > ( + u, h, p, f)); + + if (!d.get ()) + throw ::xsd::cxx::tree::parsing< char > (); + + return ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > ( + ::LinphonePrivate::Xsd::Imdn::parseImdn ( + std::move (d), f | ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom, p)); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > + parseImdn (const ::std::string& u, + ::xercesc::DOMErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::xsd::cxx::xml::dom::parse< char > ( + u, h, p, f)); + + if (!d.get ()) + throw ::xsd::cxx::tree::parsing< char > (); + + return ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > ( + ::LinphonePrivate::Xsd::Imdn::parseImdn ( + std::move (d), f | ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom, p)); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > + parseImdn (::std::istream& is, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0, + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) == 0); + + ::xsd::cxx::xml::sax::std_input_source isrc (is); + return ::LinphonePrivate::Xsd::Imdn::parseImdn (isrc, f, p); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > + parseImdn (::std::istream& is, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0, + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) == 0); + + ::xsd::cxx::xml::sax::std_input_source isrc (is); + return ::LinphonePrivate::Xsd::Imdn::parseImdn (isrc, h, f, p); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > + parseImdn (::std::istream& is, + ::xercesc::DOMErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::sax::std_input_source isrc (is); + return ::LinphonePrivate::Xsd::Imdn::parseImdn (isrc, h, f, p); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > + parseImdn (::std::istream& is, + const ::std::string& sid, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0, + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) == 0); + + ::xsd::cxx::xml::sax::std_input_source isrc (is, sid); + return ::LinphonePrivate::Xsd::Imdn::parseImdn (isrc, f, p); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > + parseImdn (::std::istream& is, + const ::std::string& sid, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0, + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) == 0); + + ::xsd::cxx::xml::sax::std_input_source isrc (is, sid); + return ::LinphonePrivate::Xsd::Imdn::parseImdn (isrc, h, f, p); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > + parseImdn (::std::istream& is, + const ::std::string& sid, + ::xercesc::DOMErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::sax::std_input_source isrc (is, sid); + return ::LinphonePrivate::Xsd::Imdn::parseImdn (isrc, h, f, p); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > + parseImdn (::xercesc::InputSource& i, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::tree::error_handler< char > h; + + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::xsd::cxx::xml::dom::parse< char > ( + i, h, p, f)); + + h.throw_if_failed< ::xsd::cxx::tree::parsing< char > > (); + + return ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > ( + ::LinphonePrivate::Xsd::Imdn::parseImdn ( + std::move (d), f | ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom, p)); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > + parseImdn (::xercesc::InputSource& i, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::xsd::cxx::xml::dom::parse< char > ( + i, h, p, f)); + + if (!d.get ()) + throw ::xsd::cxx::tree::parsing< char > (); + + return ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > ( + ::LinphonePrivate::Xsd::Imdn::parseImdn ( + std::move (d), f | ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom, p)); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > + parseImdn (::xercesc::InputSource& i, + ::xercesc::DOMErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::xsd::cxx::xml::dom::parse< char > ( + i, h, p, f)); + + if (!d.get ()) + throw ::xsd::cxx::tree::parsing< char > (); + + return ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > ( + ::LinphonePrivate::Xsd::Imdn::parseImdn ( + std::move (d), f | ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom, p)); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > + parseImdn (const ::xercesc::DOMDocument& doc, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + if (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + static_cast< ::xercesc::DOMDocument* > (doc.cloneNode (true))); + + return ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > ( + ::LinphonePrivate::Xsd::Imdn::parseImdn ( + std::move (d), f | ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom, p)); + } + + const ::xercesc::DOMElement& e (*doc.getDocumentElement ()); + const ::xsd::cxx::xml::qualified_name< char > n ( + ::xsd::cxx::xml::dom::name< char > (e)); + + if (n.name () == "imdn" && + n.namespace_ () == "urn:ietf:params:xml:ns:imdn") + { + ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > r ( + ::xsd::cxx::tree::traits< ::LinphonePrivate::Xsd::Imdn::Imdn, char >::create ( + e, f, 0)); + return r; + } + + throw ::xsd::cxx::tree::unexpected_element < char > ( + n.name (), + n.namespace_ (), + "imdn", + "urn:ietf:params:xml:ns:imdn"); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > + parseImdn (::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties&) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > c ( + ((f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) && + !(f & ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom)) + ? static_cast< ::xercesc::DOMDocument* > (d->cloneNode (true)) + : 0); + + ::xercesc::DOMDocument& doc (c.get () ? *c : *d); + const ::xercesc::DOMElement& e (*doc.getDocumentElement ()); + + const ::xsd::cxx::xml::qualified_name< char > n ( + ::xsd::cxx::xml::dom::name< char > (e)); + + if (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) + doc.setUserData (::LinphonePrivate::Xsd::XmlSchema::dom::treeNodeKey, + (c.get () ? &c : &d), + 0); + + if (n.name () == "imdn" && + n.namespace_ () == "urn:ietf:params:xml:ns:imdn") + { + ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > r ( + ::xsd::cxx::tree::traits< ::LinphonePrivate::Xsd::Imdn::Imdn, char >::create ( + e, f, 0)); + return r; + } + + throw ::xsd::cxx::tree::unexpected_element < char > ( + n.name (), + n.namespace_ (), + "imdn", + "urn:ietf:params:xml:ns:imdn"); + } + } + } +} + +#include +#include +#include + +#include + +namespace _xsd +{ + static + const ::xsd::cxx::tree::type_serializer_plate< 0, char > + type_serializer_plate_init; +} + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace Imdn + { + void + serializeImdn (::std::ostream& o, + const ::LinphonePrivate::Xsd::Imdn::Imdn& s, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m, + const ::std::string& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0); + + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::LinphonePrivate::Xsd::Imdn::serializeImdn (s, m, f)); + + ::xsd::cxx::tree::error_handler< char > h; + + ::xsd::cxx::xml::dom::ostream_format_target t (o); + if (!::xsd::cxx::xml::dom::serialize (t, *d, e, h, f)) + { + h.throw_if_failed< ::xsd::cxx::tree::serialization< char > > (); + } + } + + void + serializeImdn (::std::ostream& o, + const ::LinphonePrivate::Xsd::Imdn::Imdn& s, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& h, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m, + const ::std::string& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0); + + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::LinphonePrivate::Xsd::Imdn::serializeImdn (s, m, f)); + ::xsd::cxx::xml::dom::ostream_format_target t (o); + if (!::xsd::cxx::xml::dom::serialize (t, *d, e, h, f)) + { + throw ::xsd::cxx::tree::serialization< char > (); + } + } + + void + serializeImdn (::std::ostream& o, + const ::LinphonePrivate::Xsd::Imdn::Imdn& s, + ::xercesc::DOMErrorHandler& h, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m, + const ::std::string& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::LinphonePrivate::Xsd::Imdn::serializeImdn (s, m, f)); + ::xsd::cxx::xml::dom::ostream_format_target t (o); + if (!::xsd::cxx::xml::dom::serialize (t, *d, e, h, f)) + { + throw ::xsd::cxx::tree::serialization< char > (); + } + } + + void + serializeImdn (::xercesc::XMLFormatTarget& t, + const ::LinphonePrivate::Xsd::Imdn::Imdn& s, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m, + const ::std::string& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::LinphonePrivate::Xsd::Imdn::serializeImdn (s, m, f)); + + ::xsd::cxx::tree::error_handler< char > h; + + if (!::xsd::cxx::xml::dom::serialize (t, *d, e, h, f)) + { + h.throw_if_failed< ::xsd::cxx::tree::serialization< char > > (); + } + } + + void + serializeImdn (::xercesc::XMLFormatTarget& t, + const ::LinphonePrivate::Xsd::Imdn::Imdn& s, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& h, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m, + const ::std::string& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::LinphonePrivate::Xsd::Imdn::serializeImdn (s, m, f)); + if (!::xsd::cxx::xml::dom::serialize (t, *d, e, h, f)) + { + throw ::xsd::cxx::tree::serialization< char > (); + } + } + + void + serializeImdn (::xercesc::XMLFormatTarget& t, + const ::LinphonePrivate::Xsd::Imdn::Imdn& s, + ::xercesc::DOMErrorHandler& h, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m, + const ::std::string& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::LinphonePrivate::Xsd::Imdn::serializeImdn (s, m, f)); + if (!::xsd::cxx::xml::dom::serialize (t, *d, e, h, f)) + { + throw ::xsd::cxx::tree::serialization< char > (); + } + } + + void + serializeImdn (::xercesc::DOMDocument& d, + const ::LinphonePrivate::Xsd::Imdn::Imdn& s, + ::LinphonePrivate::Xsd::XmlSchema::Flags) + { + ::xercesc::DOMElement& e (*d.getDocumentElement ()); + const ::xsd::cxx::xml::qualified_name< char > n ( + ::xsd::cxx::xml::dom::name< char > (e)); + + if (n.name () == "imdn" && + n.namespace_ () == "urn:ietf:params:xml:ns:imdn") + { + e << s; + } + else + { + throw ::xsd::cxx::tree::unexpected_element < char > ( + n.name (), + n.namespace_ (), + "imdn", + "urn:ietf:params:xml:ns:imdn"); + } + } + + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > + serializeImdn (const ::LinphonePrivate::Xsd::Imdn::Imdn& s, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::xsd::cxx::xml::dom::serialize< char > ( + "imdn", + "urn:ietf:params:xml:ns:imdn", + m, f)); + + ::LinphonePrivate::Xsd::Imdn::serializeImdn (*d, s, f); + return d; + } + + void + operator<< (::xercesc::DOMElement& e, const Imdn& i) + { + e << static_cast< const ::LinphonePrivate::Xsd::XmlSchema::Type& > (i); + + // message-id + // + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "message-id", + "urn:ietf:params:xml:ns:imdn", + e)); + + s << i.getMessageId (); + } + + // datetime + // + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "datetime", + "urn:ietf:params:xml:ns:imdn", + e)); + + s << i.getDatetime (); + } + + // recipient-uri + // + if (i.getRecipientUri ()) + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "recipient-uri", + "urn:ietf:params:xml:ns:imdn", + e)); + + s << *i.getRecipientUri (); + } + + // original-recipient-uri + // + if (i.getOriginalRecipientUri ()) + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "original-recipient-uri", + "urn:ietf:params:xml:ns:imdn", + e)); + + s << *i.getOriginalRecipientUri (); + } + + // subject + // + if (i.getSubject ()) + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "subject", + "urn:ietf:params:xml:ns:imdn", + e)); + + s << *i.getSubject (); + } + + // delivery-notification + // + if (i.getDeliveryNotification ()) + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "delivery-notification", + "urn:ietf:params:xml:ns:imdn", + e)); + + s << *i.getDeliveryNotification (); + } + + // display-notification + // + if (i.getDisplayNotification ()) + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "display-notification", + "urn:ietf:params:xml:ns:imdn", + e)); + + s << *i.getDisplayNotification (); + } + + // processing-notification + // + if (i.getProcessingNotification ()) + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "processing-notification", + "urn:ietf:params:xml:ns:imdn", + e)); + + s << *i.getProcessingNotification (); + } + + // any + // + for (Imdn::AnyConstIterator + b (i.getAny ().begin ()), n (i.getAny ().end ()); + b != n; ++b) + { + e.appendChild ( + e.getOwnerDocument ()->importNode ( + const_cast< ::xercesc::DOMElement* > (&(*b)), true)); + } + } + + void + operator<< (::xercesc::DOMElement& e, const DeliveryNotification& i) + { + e << static_cast< const ::LinphonePrivate::Xsd::XmlSchema::Type& > (i); + + // status + // + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "status", + "urn:ietf:params:xml:ns:imdn", + e)); + + s << i.getStatus (); + } + } + + void + operator<< (::xercesc::DOMElement& e, const Delivered& i) + { + e << static_cast< const ::LinphonePrivate::Xsd::XmlSchema::Type& > (i); + } + + void + operator<< (::xercesc::DOMAttr&, const Delivered&) + { + } + + void + operator<< (::LinphonePrivate::Xsd::XmlSchema::ListStream&, + const Delivered&) + { + } + + void + operator<< (::xercesc::DOMElement& e, const Failed& i) + { + e << static_cast< const ::LinphonePrivate::Xsd::XmlSchema::Type& > (i); + } + + void + operator<< (::xercesc::DOMAttr&, const Failed&) + { + } + + void + operator<< (::LinphonePrivate::Xsd::XmlSchema::ListStream&, + const Failed&) + { + } + + void + operator<< (::xercesc::DOMElement& e, const DisplayNotification& i) + { + e << static_cast< const ::LinphonePrivate::Xsd::XmlSchema::Type& > (i); + + // status + // + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "status", + "urn:ietf:params:xml:ns:imdn", + e)); + + s << i.getStatus (); + } + } + + void + operator<< (::xercesc::DOMElement& e, const Displayed& i) + { + e << static_cast< const ::LinphonePrivate::Xsd::XmlSchema::Type& > (i); + } + + void + operator<< (::xercesc::DOMAttr&, const Displayed&) + { + } + + void + operator<< (::LinphonePrivate::Xsd::XmlSchema::ListStream&, + const Displayed&) + { + } + + void + operator<< (::xercesc::DOMElement& e, const ProcessingNotification& i) + { + e << static_cast< const ::LinphonePrivate::Xsd::XmlSchema::Type& > (i); + + // status + // + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "status", + "urn:ietf:params:xml:ns:imdn", + e)); + + s << i.getStatus (); + } + } + + void + operator<< (::xercesc::DOMElement& e, const Processed& i) + { + e << static_cast< const ::LinphonePrivate::Xsd::XmlSchema::Type& > (i); + } + + void + operator<< (::xercesc::DOMAttr&, const Processed&) + { + } + + void + operator<< (::LinphonePrivate::Xsd::XmlSchema::ListStream&, + const Processed&) + { + } + + void + operator<< (::xercesc::DOMElement& e, const Stored& i) + { + e << static_cast< const ::LinphonePrivate::Xsd::XmlSchema::Type& > (i); + } + + void + operator<< (::xercesc::DOMAttr&, const Stored&) + { + } + + void + operator<< (::LinphonePrivate::Xsd::XmlSchema::ListStream&, + const Stored&) + { + } + + void + operator<< (::xercesc::DOMElement& e, const Forbidden& i) + { + e << static_cast< const ::LinphonePrivate::Xsd::XmlSchema::Type& > (i); + } + + void + operator<< (::xercesc::DOMAttr&, const Forbidden&) + { + } + + void + operator<< (::LinphonePrivate::Xsd::XmlSchema::ListStream&, + const Forbidden&) + { + } + + void + operator<< (::xercesc::DOMElement& e, const Error& i) + { + e << static_cast< const ::LinphonePrivate::Xsd::XmlSchema::Type& > (i); + } + + void + operator<< (::xercesc::DOMAttr&, const Error&) + { + } + + void + operator<< (::LinphonePrivate::Xsd::XmlSchema::ListStream&, + const Error&) + { + } + + void + operator<< (::xercesc::DOMElement& e, const Status& i) + { + e << static_cast< const ::LinphonePrivate::Xsd::XmlSchema::Type& > (i); + + // delivered + // + if (i.getDelivered ()) + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "delivered", + "urn:ietf:params:xml:ns:imdn", + e)); + + s << *i.getDelivered (); + } + + // failed + // + if (i.getFailed ()) + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "failed", + "urn:ietf:params:xml:ns:imdn", + e)); + + s << *i.getFailed (); + } + + // forbidden + // + if (i.getForbidden ()) + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "forbidden", + "urn:ietf:params:xml:ns:imdn", + e)); + + s << *i.getForbidden (); + } + + // error + // + if (i.getError ()) + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "error", + "urn:ietf:params:xml:ns:imdn", + e)); + + s << *i.getError (); + } + + // reason + // + if (i.getReason ()) + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "reason", + "http://www.linphone.org/xsds/imdn.xsd", + e)); + + s << *i.getReason (); + } + } + + void + operator<< (::xercesc::DOMElement& e, const Status1& i) + { + e << static_cast< const ::LinphonePrivate::Xsd::XmlSchema::Type& > (i); + + // displayed + // + if (i.getDisplayed ()) + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "displayed", + "urn:ietf:params:xml:ns:imdn", + e)); + + s << *i.getDisplayed (); + } + + // forbidden + // + if (i.getForbidden ()) + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "forbidden", + "urn:ietf:params:xml:ns:imdn", + e)); + + s << *i.getForbidden (); + } + + // error + // + if (i.getError ()) + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "error", + "urn:ietf:params:xml:ns:imdn", + e)); + + s << *i.getError (); + } + + // any + // + for (Status1::AnyConstIterator + b (i.getAny ().begin ()), n (i.getAny ().end ()); + b != n; ++b) + { + e.appendChild ( + e.getOwnerDocument ()->importNode ( + const_cast< ::xercesc::DOMElement* > (&(*b)), true)); + } + } + + void + operator<< (::xercesc::DOMElement& e, const Status2& i) + { + e << static_cast< const ::LinphonePrivate::Xsd::XmlSchema::Type& > (i); + + // processed + // + if (i.getProcessed ()) + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "processed", + "urn:ietf:params:xml:ns:imdn", + e)); + + s << *i.getProcessed (); + } + + // stored + // + if (i.getStored ()) + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "stored", + "urn:ietf:params:xml:ns:imdn", + e)); + + s << *i.getStored (); + } + + // forbidden + // + if (i.getForbidden ()) + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "forbidden", + "urn:ietf:params:xml:ns:imdn", + e)); + + s << *i.getForbidden (); + } + + // error + // + if (i.getError ()) + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "error", + "urn:ietf:params:xml:ns:imdn", + e)); + + s << *i.getError (); + } + + // any + // + for (Status2::AnyConstIterator + b (i.getAny ().begin ()), n (i.getAny ().end ()); + b != n; ++b) + { + e.appendChild ( + e.getOwnerDocument ()->importNode ( + const_cast< ::xercesc::DOMElement* > (&(*b)), true)); + } + } + } + } +} + +#include + +// Begin epilogue. +// +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif +#if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) + #pragma GCC diagnostic pop +#endif +#if __clang__ || __GNUC__ >= 4 + #pragma GCC diagnostic pop +#endif +// +// End epilogue. + diff --git a/src/xml/imdn.h b/src/xml/imdn.h new file mode 100644 index 000000000..ca544a67c --- /dev/null +++ b/src/xml/imdn.h @@ -0,0 +1,1739 @@ +// Copyright (c) 2005-2014 Code Synthesis Tools CC +// +// This program was generated by CodeSynthesis XSD, an XML Schema to +// C++ data binding compiler. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as +// published by the Free Software Foundation. +// +// 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 St, Fifth Floor, Boston, MA 02110-1301 USA +// +// In addition, as a special exception, Code Synthesis Tools CC gives +// permission to link this program with the Xerces-C++ library (or with +// modified versions of Xerces-C++ that use the same license as Xerces-C++), +// and distribute linked combinations including the two. You must obey +// the GNU General Public License version 2 in all respects for all of +// the code used other than Xerces-C++. If you modify this copy of the +// program, you may extend this exception to your version of the program, +// but you are not obligated to do so. If you do not wish to do so, delete +// this exception statement from your version. +// +// Furthermore, Code Synthesis Tools CC makes a special exception for +// the Free/Libre and Open Source Software (FLOSS) which is described +// in the accompanying FLOSSE file. +// + +#ifndef XML_IMDN_H +#define XML_IMDN_H + +#ifndef XSD_CXX11 +#define XSD_CXX11 +#endif + +#ifndef XSD_USE_CHAR +#define XSD_USE_CHAR +#endif + +#ifndef XSD_CXX_TREE_USE_CHAR +#define XSD_CXX_TREE_USE_CHAR +#endif + +// Begin prologue. +// +#if __clang__ || __GNUC__ >= 4 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wfloat-equal" + #pragma GCC diagnostic ignored "-Wsign-conversion" + #pragma GCC diagnostic ignored "-Wconversion" +#endif +#if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsuggest-override" +#endif +#if __GNUC__ >=7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" +#endif +// +// End prologue. + +#include + +#if (XSD_INT_VERSION != 4000000L) +#error XSD runtime version mismatch +#endif + +#include + +#include + +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace XmlSchema + { + // anyType and anySimpleType. + // + typedef ::xsd::cxx::tree::type Type; + typedef ::xsd::cxx::tree::simple_type< char, Type > SimpleType; + typedef ::xsd::cxx::tree::type Container; + + // 8-bit + // + typedef signed char Byte; + typedef unsigned char UnsignedByte; + + // 16-bit + // + typedef short Short; + typedef unsigned short UnsignedShort; + + // 32-bit + // + typedef int Int; + typedef unsigned int UnsignedInt; + + // 64-bit + // + typedef long long Long; + typedef unsigned long long UnsignedLong; + + // Supposed to be arbitrary-length integral types. + // + typedef long long Integer; + typedef long long NonPositiveInteger; + typedef unsigned long long NonNegativeInteger; + typedef unsigned long long PositiveInteger; + typedef long long NegativeInteger; + + // Boolean. + // + typedef bool Boolean; + + // Floating-point types. + // + typedef float Float; + typedef double Double; + typedef double Decimal; + + // String types. + // + typedef ::xsd::cxx::tree::string< char, SimpleType > String; + typedef ::xsd::cxx::tree::normalized_string< char, String > NormalizedString; + typedef ::xsd::cxx::tree::token< char, NormalizedString > Token; + typedef ::xsd::cxx::tree::name< char, Token > Name; + typedef ::xsd::cxx::tree::nmtoken< char, Token > Nmtoken; + typedef ::xsd::cxx::tree::nmtokens< char, SimpleType, Nmtoken > Nmtokens; + typedef ::xsd::cxx::tree::ncname< char, Name > Ncname; + typedef ::xsd::cxx::tree::language< char, Token > Language; + + // ID/IDREF. + // + typedef ::xsd::cxx::tree::id< char, Ncname > Id; + typedef ::xsd::cxx::tree::idref< char, Ncname, Type > Idref; + typedef ::xsd::cxx::tree::idrefs< char, SimpleType, Idref > Idrefs; + + // URI. + // + typedef ::xsd::cxx::tree::uri< char, SimpleType > Uri; + + // Qualified name. + // + typedef ::xsd::cxx::tree::qname< char, SimpleType, Uri, Ncname > Qname; + + // Binary. + // + typedef ::xsd::cxx::tree::buffer< char > Buffer; + typedef ::xsd::cxx::tree::base64_binary< char, SimpleType > Base64Binary; + typedef ::xsd::cxx::tree::hex_binary< char, SimpleType > HexBinary; + + // Date/time. + // + typedef ::xsd::cxx::tree::time_zone TimeZone; + typedef ::xsd::cxx::tree::date< char, SimpleType > Date; + typedef ::xsd::cxx::tree::date_time< char, SimpleType > DateTime; + typedef ::xsd::cxx::tree::duration< char, SimpleType > Duration; + typedef ::xsd::cxx::tree::gday< char, SimpleType > Gday; + typedef ::xsd::cxx::tree::gmonth< char, SimpleType > Gmonth; + typedef ::xsd::cxx::tree::gmonth_day< char, SimpleType > GmonthDay; + typedef ::xsd::cxx::tree::gyear< char, SimpleType > Gyear; + typedef ::xsd::cxx::tree::gyear_month< char, SimpleType > GyearMonth; + typedef ::xsd::cxx::tree::time< char, SimpleType > Time; + + // Entity. + // + typedef ::xsd::cxx::tree::entity< char, Ncname > Entity; + typedef ::xsd::cxx::tree::entities< char, SimpleType, Entity > Entities; + + typedef ::xsd::cxx::tree::content_order ContentOrder; + // Namespace information and list stream. Used in + // serialization functions. + // + typedef ::xsd::cxx::xml::dom::namespace_info< char > NamespaceInfo; + typedef ::xsd::cxx::xml::dom::namespace_infomap< char > NamespaceInfomap; + typedef ::xsd::cxx::tree::list_stream< char > ListStream; + typedef ::xsd::cxx::tree::as_double< Double > AsDouble; + typedef ::xsd::cxx::tree::as_decimal< Decimal > AsDecimal; + typedef ::xsd::cxx::tree::facet Facet; + + // Flags and properties. + // + typedef ::xsd::cxx::tree::flags Flags; + typedef ::xsd::cxx::tree::properties< char > Properties; + + // Parsing/serialization diagnostics. + // + typedef ::xsd::cxx::tree::severity Severity; + typedef ::xsd::cxx::tree::error< char > Error; + typedef ::xsd::cxx::tree::diagnostics< char > Diagnostics; + + // Exceptions. + // + typedef ::xsd::cxx::tree::exception< char > Exception; + typedef ::xsd::cxx::tree::bounds< char > Bounds; + typedef ::xsd::cxx::tree::duplicate_id< char > DuplicateId; + typedef ::xsd::cxx::tree::parsing< char > Parsing; + typedef ::xsd::cxx::tree::expected_element< char > ExpectedElement; + typedef ::xsd::cxx::tree::unexpected_element< char > UnexpectedElement; + typedef ::xsd::cxx::tree::expected_attribute< char > ExpectedAttribute; + typedef ::xsd::cxx::tree::unexpected_enumerator< char > UnexpectedEnumerator; + typedef ::xsd::cxx::tree::expected_text_content< char > ExpectedTextContent; + typedef ::xsd::cxx::tree::no_prefix_mapping< char > NoPrefixMapping; + typedef ::xsd::cxx::tree::no_type_info< char > NoTypeInfo; + typedef ::xsd::cxx::tree::not_derived< char > NotDerived; + typedef ::xsd::cxx::tree::serialization< char > Serialization; + + // Error handler callback interface. + // + typedef ::xsd::cxx::xml::error_handler< char > ErrorHandler; + + // DOM interaction. + // + namespace dom + { + // Automatic pointer for DOMDocument. + // + using ::xsd::cxx::xml::dom::unique_ptr; + +#ifndef XSD_CXX_TREE_TREE_NODE_KEY__LINPHONEPRIVATE__XSD__XMLSCHEMA +#define XSD_CXX_TREE_TREE_NODE_KEY__LINPHONEPRIVATE__XSD__XMLSCHEMA + // DOM user data key for back pointers to tree nodes. + // + const XMLCh* const treeNodeKey = ::xsd::cxx::tree::user_data_keys::node; +#endif + } + } + } +} + +// Forward declarations. +// +namespace LinphonePrivate +{ + namespace Xsd + { + namespace Imdn + { + class Imdn; + class DeliveryNotification; + class Delivered; + class Failed; + class DisplayNotification; + class Displayed; + class ProcessingNotification; + class Processed; + class Stored; + class Forbidden; + class Error; + class Status; + class Status1; + class Status2; + } + } +} + + +#include // ::std::unique_ptr +#include // std::numeric_limits +#include // std::binary_search +#include // std::move + +#include + +#include +#include +#include +#include + +#include + +#include + +#include "linphone-imdn.h" + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace Imdn + { + class Imdn: public ::LinphonePrivate::Xsd::XmlSchema::Type + { + public: + // message-id + // + typedef ::LinphonePrivate::Xsd::XmlSchema::Token MessageIdType; + typedef ::xsd::cxx::tree::traits< MessageIdType, char > MessageIdTraits; + + const MessageIdType& + getMessageId () const; + + MessageIdType& + getMessageId (); + + void + setMessageId (const MessageIdType& x); + + void + setMessageId (::std::unique_ptr< MessageIdType > p); + + ::std::unique_ptr< MessageIdType > + setDetachMessage_id (); + + // datetime + // + typedef ::LinphonePrivate::Xsd::XmlSchema::String DatetimeType; + typedef ::xsd::cxx::tree::traits< DatetimeType, char > DatetimeTraits; + + const DatetimeType& + getDatetime () const; + + DatetimeType& + getDatetime (); + + void + setDatetime (const DatetimeType& x); + + void + setDatetime (::std::unique_ptr< DatetimeType > p); + + ::std::unique_ptr< DatetimeType > + setDetachDatetime (); + + // recipient-uri + // + typedef ::LinphonePrivate::Xsd::XmlSchema::Uri RecipientUriType; + typedef ::xsd::cxx::tree::optional< RecipientUriType > RecipientUriOptional; + typedef ::xsd::cxx::tree::traits< RecipientUriType, char > RecipientUriTraits; + + const RecipientUriOptional& + getRecipientUri () const; + + RecipientUriOptional& + getRecipientUri (); + + void + setRecipientUri (const RecipientUriType& x); + + void + setRecipientUri (const RecipientUriOptional& x); + + void + setRecipientUri (::std::unique_ptr< RecipientUriType > p); + + // original-recipient-uri + // + typedef ::LinphonePrivate::Xsd::XmlSchema::Uri OriginalRecipientUriType; + typedef ::xsd::cxx::tree::optional< OriginalRecipientUriType > OriginalRecipientUriOptional; + typedef ::xsd::cxx::tree::traits< OriginalRecipientUriType, char > OriginalRecipientUriTraits; + + const OriginalRecipientUriOptional& + getOriginalRecipientUri () const; + + OriginalRecipientUriOptional& + getOriginalRecipientUri (); + + void + setOriginalRecipientUri (const OriginalRecipientUriType& x); + + void + setOriginalRecipientUri (const OriginalRecipientUriOptional& x); + + void + setOriginalRecipientUri (::std::unique_ptr< OriginalRecipientUriType > p); + + // subject + // + typedef ::LinphonePrivate::Xsd::XmlSchema::String SubjectType; + typedef ::xsd::cxx::tree::optional< SubjectType > SubjectOptional; + typedef ::xsd::cxx::tree::traits< SubjectType, char > SubjectTraits; + + const SubjectOptional& + getSubject () const; + + SubjectOptional& + getSubject (); + + void + setSubject (const SubjectType& x); + + void + setSubject (const SubjectOptional& x); + + void + setSubject (::std::unique_ptr< SubjectType > p); + + // delivery-notification + // + typedef ::LinphonePrivate::Xsd::Imdn::DeliveryNotification DeliveryNotificationType; + typedef ::xsd::cxx::tree::optional< DeliveryNotificationType > DeliveryNotificationOptional; + typedef ::xsd::cxx::tree::traits< DeliveryNotificationType, char > DeliveryNotificationTraits; + + const DeliveryNotificationOptional& + getDeliveryNotification () const; + + DeliveryNotificationOptional& + getDeliveryNotification (); + + void + setDeliveryNotification (const DeliveryNotificationType& x); + + void + setDeliveryNotification (const DeliveryNotificationOptional& x); + + void + setDeliveryNotification (::std::unique_ptr< DeliveryNotificationType > p); + + // display-notification + // + typedef ::LinphonePrivate::Xsd::Imdn::DisplayNotification DisplayNotificationType; + typedef ::xsd::cxx::tree::optional< DisplayNotificationType > DisplayNotificationOptional; + typedef ::xsd::cxx::tree::traits< DisplayNotificationType, char > DisplayNotificationTraits; + + const DisplayNotificationOptional& + getDisplayNotification () const; + + DisplayNotificationOptional& + getDisplayNotification (); + + void + setDisplayNotification (const DisplayNotificationType& x); + + void + setDisplayNotification (const DisplayNotificationOptional& x); + + void + setDisplayNotification (::std::unique_ptr< DisplayNotificationType > p); + + // processing-notification + // + typedef ::LinphonePrivate::Xsd::Imdn::ProcessingNotification ProcessingNotificationType; + typedef ::xsd::cxx::tree::optional< ProcessingNotificationType > ProcessingNotificationOptional; + typedef ::xsd::cxx::tree::traits< ProcessingNotificationType, char > ProcessingNotificationTraits; + + const ProcessingNotificationOptional& + getProcessingNotification () const; + + ProcessingNotificationOptional& + getProcessingNotification (); + + void + setProcessingNotification (const ProcessingNotificationType& x); + + void + setProcessingNotification (const ProcessingNotificationOptional& x); + + void + setProcessingNotification (::std::unique_ptr< ProcessingNotificationType > p); + + // any + // + typedef ::xsd::cxx::tree::element_sequence AnySequence; + typedef AnySequence::iterator AnyIterator; + typedef AnySequence::const_iterator AnyConstIterator; + + const AnySequence& + getAny () const; + + AnySequence& + getAny (); + + void + setAny (const AnySequence& s); + + // DOMDocument for wildcard content. + // + const ::xercesc::DOMDocument& + getDomDocument () const; + + ::xercesc::DOMDocument& + getDomDocument (); + + // Constructors. + // + Imdn (const MessageIdType&, + const DatetimeType&); + + Imdn (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + Imdn (const Imdn& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + virtual Imdn* + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0) const; + + Imdn& + operator= (const Imdn& x); + + virtual + ~Imdn (); + + // Implementation. + // + protected: + void + parse (::xsd::cxx::xml::dom::parser< char >&, + ::LinphonePrivate::Xsd::XmlSchema::Flags); + + protected: + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > dom_document_; + + ::xsd::cxx::tree::one< MessageIdType > message_id_; + ::xsd::cxx::tree::one< DatetimeType > datetime_; + RecipientUriOptional recipient_uri_; + OriginalRecipientUriOptional original_recipient_uri_; + SubjectOptional subject_; + DeliveryNotificationOptional delivery_notification_; + DisplayNotificationOptional display_notification_; + ProcessingNotificationOptional processing_notification_; + AnySequence any_; + }; + + class DeliveryNotification: public ::LinphonePrivate::Xsd::XmlSchema::Type + { + public: + // status + // + typedef ::LinphonePrivate::Xsd::Imdn::Status StatusType; + typedef ::xsd::cxx::tree::traits< StatusType, char > StatusTraits; + + const StatusType& + getStatus () const; + + StatusType& + getStatus (); + + void + setStatus (const StatusType& x); + + void + setStatus (::std::unique_ptr< StatusType > p); + + ::std::unique_ptr< StatusType > + setDetachStatus (); + + // Constructors. + // + DeliveryNotification (const StatusType&); + + DeliveryNotification (::std::unique_ptr< StatusType >); + + DeliveryNotification (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + DeliveryNotification (const DeliveryNotification& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + virtual DeliveryNotification* + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0) const; + + DeliveryNotification& + operator= (const DeliveryNotification& x); + + virtual + ~DeliveryNotification (); + + // Implementation. + // + protected: + void + parse (::xsd::cxx::xml::dom::parser< char >&, + ::LinphonePrivate::Xsd::XmlSchema::Flags); + + protected: + ::xsd::cxx::tree::one< StatusType > status_; + }; + + class Delivered: public ::LinphonePrivate::Xsd::XmlSchema::Type + { + public: + // Constructors. + // + Delivered (); + + Delivered (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + Delivered (const ::xercesc::DOMAttr& a, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + Delivered (const ::std::string& s, + const ::xercesc::DOMElement* e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + Delivered (const Delivered& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + virtual Delivered* + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0) const; + + virtual + ~Delivered (); + }; + + class Failed: public ::LinphonePrivate::Xsd::XmlSchema::Type + { + public: + // Constructors. + // + Failed (); + + Failed (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + Failed (const ::xercesc::DOMAttr& a, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + Failed (const ::std::string& s, + const ::xercesc::DOMElement* e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + Failed (const Failed& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + virtual Failed* + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0) const; + + virtual + ~Failed (); + }; + + class DisplayNotification: public ::LinphonePrivate::Xsd::XmlSchema::Type + { + public: + // status + // + typedef ::LinphonePrivate::Xsd::Imdn::Status1 StatusType; + typedef ::xsd::cxx::tree::traits< StatusType, char > StatusTraits; + + const StatusType& + getStatus () const; + + StatusType& + getStatus (); + + void + setStatus (const StatusType& x); + + void + setStatus (::std::unique_ptr< StatusType > p); + + ::std::unique_ptr< StatusType > + setDetachStatus (); + + // Constructors. + // + DisplayNotification (const StatusType&); + + DisplayNotification (::std::unique_ptr< StatusType >); + + DisplayNotification (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + DisplayNotification (const DisplayNotification& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + virtual DisplayNotification* + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0) const; + + DisplayNotification& + operator= (const DisplayNotification& x); + + virtual + ~DisplayNotification (); + + // Implementation. + // + protected: + void + parse (::xsd::cxx::xml::dom::parser< char >&, + ::LinphonePrivate::Xsd::XmlSchema::Flags); + + protected: + ::xsd::cxx::tree::one< StatusType > status_; + }; + + class Displayed: public ::LinphonePrivate::Xsd::XmlSchema::Type + { + public: + // Constructors. + // + Displayed (); + + Displayed (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + Displayed (const ::xercesc::DOMAttr& a, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + Displayed (const ::std::string& s, + const ::xercesc::DOMElement* e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + Displayed (const Displayed& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + virtual Displayed* + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0) const; + + virtual + ~Displayed (); + }; + + class ProcessingNotification: public ::LinphonePrivate::Xsd::XmlSchema::Type + { + public: + // status + // + typedef ::LinphonePrivate::Xsd::Imdn::Status2 StatusType; + typedef ::xsd::cxx::tree::traits< StatusType, char > StatusTraits; + + const StatusType& + getStatus () const; + + StatusType& + getStatus (); + + void + setStatus (const StatusType& x); + + void + setStatus (::std::unique_ptr< StatusType > p); + + ::std::unique_ptr< StatusType > + setDetachStatus (); + + // Constructors. + // + ProcessingNotification (const StatusType&); + + ProcessingNotification (::std::unique_ptr< StatusType >); + + ProcessingNotification (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + ProcessingNotification (const ProcessingNotification& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + virtual ProcessingNotification* + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0) const; + + ProcessingNotification& + operator= (const ProcessingNotification& x); + + virtual + ~ProcessingNotification (); + + // Implementation. + // + protected: + void + parse (::xsd::cxx::xml::dom::parser< char >&, + ::LinphonePrivate::Xsd::XmlSchema::Flags); + + protected: + ::xsd::cxx::tree::one< StatusType > status_; + }; + + class Processed: public ::LinphonePrivate::Xsd::XmlSchema::Type + { + public: + // Constructors. + // + Processed (); + + Processed (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + Processed (const ::xercesc::DOMAttr& a, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + Processed (const ::std::string& s, + const ::xercesc::DOMElement* e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + Processed (const Processed& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + virtual Processed* + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0) const; + + virtual + ~Processed (); + }; + + class Stored: public ::LinphonePrivate::Xsd::XmlSchema::Type + { + public: + // Constructors. + // + Stored (); + + Stored (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + Stored (const ::xercesc::DOMAttr& a, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + Stored (const ::std::string& s, + const ::xercesc::DOMElement* e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + Stored (const Stored& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + virtual Stored* + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0) const; + + virtual + ~Stored (); + }; + + class Forbidden: public ::LinphonePrivate::Xsd::XmlSchema::Type + { + public: + // Constructors. + // + Forbidden (); + + Forbidden (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + Forbidden (const ::xercesc::DOMAttr& a, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + Forbidden (const ::std::string& s, + const ::xercesc::DOMElement* e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + Forbidden (const Forbidden& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + virtual Forbidden* + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0) const; + + virtual + ~Forbidden (); + }; + + class Error: public ::LinphonePrivate::Xsd::XmlSchema::Type + { + public: + // Constructors. + // + Error (); + + Error (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + Error (const ::xercesc::DOMAttr& a, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + Error (const ::std::string& s, + const ::xercesc::DOMElement* e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + Error (const Error& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + virtual Error* + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0) const; + + virtual + ~Error (); + }; + + class Status: public ::LinphonePrivate::Xsd::XmlSchema::Type + { + public: + // delivered + // + typedef ::LinphonePrivate::Xsd::Imdn::Delivered DeliveredType; + typedef ::xsd::cxx::tree::optional< DeliveredType > DeliveredOptional; + typedef ::xsd::cxx::tree::traits< DeliveredType, char > DeliveredTraits; + + const DeliveredOptional& + getDelivered () const; + + DeliveredOptional& + getDelivered (); + + void + setDelivered (const DeliveredType& x); + + void + setDelivered (const DeliveredOptional& x); + + void + setDelivered (::std::unique_ptr< DeliveredType > p); + + // failed + // + typedef ::LinphonePrivate::Xsd::Imdn::Failed FailedType; + typedef ::xsd::cxx::tree::optional< FailedType > FailedOptional; + typedef ::xsd::cxx::tree::traits< FailedType, char > FailedTraits; + + const FailedOptional& + getFailed () const; + + FailedOptional& + getFailed (); + + void + setFailed (const FailedType& x); + + void + setFailed (const FailedOptional& x); + + void + setFailed (::std::unique_ptr< FailedType > p); + + // forbidden + // + typedef ::LinphonePrivate::Xsd::Imdn::Forbidden ForbiddenType; + typedef ::xsd::cxx::tree::optional< ForbiddenType > ForbiddenOptional; + typedef ::xsd::cxx::tree::traits< ForbiddenType, char > ForbiddenTraits; + + const ForbiddenOptional& + getForbidden () const; + + ForbiddenOptional& + getForbidden (); + + void + setForbidden (const ForbiddenType& x); + + void + setForbidden (const ForbiddenOptional& x); + + void + setForbidden (::std::unique_ptr< ForbiddenType > p); + + // error + // + typedef ::LinphonePrivate::Xsd::Imdn::Error ErrorType; + typedef ::xsd::cxx::tree::optional< ErrorType > ErrorOptional; + typedef ::xsd::cxx::tree::traits< ErrorType, char > ErrorTraits; + + const ErrorOptional& + getError () const; + + ErrorOptional& + getError (); + + void + setError (const ErrorType& x); + + void + setError (const ErrorOptional& x); + + void + setError (::std::unique_ptr< ErrorType > p); + + // reason + // + typedef ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason ReasonType; + typedef ::xsd::cxx::tree::optional< ReasonType > ReasonOptional; + typedef ::xsd::cxx::tree::traits< ReasonType, char > ReasonTraits; + + const ReasonOptional& + getReason () const; + + ReasonOptional& + getReason (); + + void + setReason (const ReasonType& x); + + void + setReason (const ReasonOptional& x); + + void + setReason (::std::unique_ptr< ReasonType > p); + + // Constructors. + // + Status (); + + Status (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + Status (const Status& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + virtual Status* + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0) const; + + Status& + operator= (const Status& x); + + virtual + ~Status (); + + // Implementation. + // + protected: + void + parse (::xsd::cxx::xml::dom::parser< char >&, + ::LinphonePrivate::Xsd::XmlSchema::Flags); + + protected: + DeliveredOptional delivered_; + FailedOptional failed_; + ForbiddenOptional forbidden_; + ErrorOptional error_; + ReasonOptional reason_; + }; + + class Status1: public ::LinphonePrivate::Xsd::XmlSchema::Type + { + public: + // displayed + // + typedef ::LinphonePrivate::Xsd::Imdn::Displayed DisplayedType; + typedef ::xsd::cxx::tree::optional< DisplayedType > DisplayedOptional; + typedef ::xsd::cxx::tree::traits< DisplayedType, char > DisplayedTraits; + + const DisplayedOptional& + getDisplayed () const; + + DisplayedOptional& + getDisplayed (); + + void + setDisplayed (const DisplayedType& x); + + void + setDisplayed (const DisplayedOptional& x); + + void + setDisplayed (::std::unique_ptr< DisplayedType > p); + + // forbidden + // + typedef ::LinphonePrivate::Xsd::Imdn::Forbidden ForbiddenType; + typedef ::xsd::cxx::tree::optional< ForbiddenType > ForbiddenOptional; + typedef ::xsd::cxx::tree::traits< ForbiddenType, char > ForbiddenTraits; + + const ForbiddenOptional& + getForbidden () const; + + ForbiddenOptional& + getForbidden (); + + void + setForbidden (const ForbiddenType& x); + + void + setForbidden (const ForbiddenOptional& x); + + void + setForbidden (::std::unique_ptr< ForbiddenType > p); + + // error + // + typedef ::LinphonePrivate::Xsd::Imdn::Error ErrorType; + typedef ::xsd::cxx::tree::optional< ErrorType > ErrorOptional; + typedef ::xsd::cxx::tree::traits< ErrorType, char > ErrorTraits; + + const ErrorOptional& + getError () const; + + ErrorOptional& + getError (); + + void + setError (const ErrorType& x); + + void + setError (const ErrorOptional& x); + + void + setError (::std::unique_ptr< ErrorType > p); + + // any + // + typedef ::xsd::cxx::tree::element_sequence AnySequence; + typedef AnySequence::iterator AnyIterator; + typedef AnySequence::const_iterator AnyConstIterator; + + const AnySequence& + getAny () const; + + AnySequence& + getAny (); + + void + setAny (const AnySequence& s); + + // DOMDocument for wildcard content. + // + const ::xercesc::DOMDocument& + getDomDocument () const; + + ::xercesc::DOMDocument& + getDomDocument (); + + // Constructors. + // + Status1 (); + + Status1 (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + Status1 (const Status1& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + virtual Status1* + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0) const; + + Status1& + operator= (const Status1& x); + + virtual + ~Status1 (); + + // Implementation. + // + protected: + void + parse (::xsd::cxx::xml::dom::parser< char >&, + ::LinphonePrivate::Xsd::XmlSchema::Flags); + + protected: + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > dom_document_; + + DisplayedOptional displayed_; + ForbiddenOptional forbidden_; + ErrorOptional error_; + AnySequence any_; + }; + + class Status2: public ::LinphonePrivate::Xsd::XmlSchema::Type + { + public: + // processed + // + typedef ::LinphonePrivate::Xsd::Imdn::Processed ProcessedType; + typedef ::xsd::cxx::tree::optional< ProcessedType > ProcessedOptional; + typedef ::xsd::cxx::tree::traits< ProcessedType, char > ProcessedTraits; + + const ProcessedOptional& + getProcessed () const; + + ProcessedOptional& + getProcessed (); + + void + setProcessed (const ProcessedType& x); + + void + setProcessed (const ProcessedOptional& x); + + void + setProcessed (::std::unique_ptr< ProcessedType > p); + + // stored + // + typedef ::LinphonePrivate::Xsd::Imdn::Stored StoredType; + typedef ::xsd::cxx::tree::optional< StoredType > StoredOptional; + typedef ::xsd::cxx::tree::traits< StoredType, char > StoredTraits; + + const StoredOptional& + getStored () const; + + StoredOptional& + getStored (); + + void + setStored (const StoredType& x); + + void + setStored (const StoredOptional& x); + + void + setStored (::std::unique_ptr< StoredType > p); + + // forbidden + // + typedef ::LinphonePrivate::Xsd::Imdn::Forbidden ForbiddenType; + typedef ::xsd::cxx::tree::optional< ForbiddenType > ForbiddenOptional; + typedef ::xsd::cxx::tree::traits< ForbiddenType, char > ForbiddenTraits; + + const ForbiddenOptional& + getForbidden () const; + + ForbiddenOptional& + getForbidden (); + + void + setForbidden (const ForbiddenType& x); + + void + setForbidden (const ForbiddenOptional& x); + + void + setForbidden (::std::unique_ptr< ForbiddenType > p); + + // error + // + typedef ::LinphonePrivate::Xsd::Imdn::Error ErrorType; + typedef ::xsd::cxx::tree::optional< ErrorType > ErrorOptional; + typedef ::xsd::cxx::tree::traits< ErrorType, char > ErrorTraits; + + const ErrorOptional& + getError () const; + + ErrorOptional& + getError (); + + void + setError (const ErrorType& x); + + void + setError (const ErrorOptional& x); + + void + setError (::std::unique_ptr< ErrorType > p); + + // any + // + typedef ::xsd::cxx::tree::element_sequence AnySequence; + typedef AnySequence::iterator AnyIterator; + typedef AnySequence::const_iterator AnyConstIterator; + + const AnySequence& + getAny () const; + + AnySequence& + getAny (); + + void + setAny (const AnySequence& s); + + // DOMDocument for wildcard content. + // + const ::xercesc::DOMDocument& + getDomDocument () const; + + ::xercesc::DOMDocument& + getDomDocument (); + + // Constructors. + // + Status2 (); + + Status2 (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + Status2 (const Status2& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + virtual Status2* + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0) const; + + Status2& + operator= (const Status2& x); + + virtual + ~Status2 (); + + // Implementation. + // + protected: + void + parse (::xsd::cxx::xml::dom::parser< char >&, + ::LinphonePrivate::Xsd::XmlSchema::Flags); + + protected: + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > dom_document_; + + ProcessedOptional processed_; + StoredOptional stored_; + ForbiddenOptional forbidden_; + ErrorOptional error_; + AnySequence any_; + }; + } + } +} + +#include + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace Imdn + { + ::std::ostream& + operator<< (::std::ostream&, const Imdn&); + + ::std::ostream& + operator<< (::std::ostream&, const DeliveryNotification&); + + ::std::ostream& + operator<< (::std::ostream&, const Delivered&); + + ::std::ostream& + operator<< (::std::ostream&, const Failed&); + + ::std::ostream& + operator<< (::std::ostream&, const DisplayNotification&); + + ::std::ostream& + operator<< (::std::ostream&, const Displayed&); + + ::std::ostream& + operator<< (::std::ostream&, const ProcessingNotification&); + + ::std::ostream& + operator<< (::std::ostream&, const Processed&); + + ::std::ostream& + operator<< (::std::ostream&, const Stored&); + + ::std::ostream& + operator<< (::std::ostream&, const Forbidden&); + + ::std::ostream& + operator<< (::std::ostream&, const Error&); + + ::std::ostream& + operator<< (::std::ostream&, const Status&); + + ::std::ostream& + operator<< (::std::ostream&, const Status1&); + + ::std::ostream& + operator<< (::std::ostream&, const Status2&); + } + } +} + +#include + +#include +#include +#include + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace Imdn + { + // Parse a URI or a local file. + // + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > + parseImdn (const ::std::string& uri, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > + parseImdn (const ::std::string& uri, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > + parseImdn (const ::std::string& uri, + ::xercesc::DOMErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + // Parse std::istream. + // + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > + parseImdn (::std::istream& is, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > + parseImdn (::std::istream& is, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > + parseImdn (::std::istream& is, + ::xercesc::DOMErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > + parseImdn (::std::istream& is, + const ::std::string& id, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > + parseImdn (::std::istream& is, + const ::std::string& id, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > + parseImdn (::std::istream& is, + const ::std::string& id, + ::xercesc::DOMErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + // Parse xercesc::InputSource. + // + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > + parseImdn (::xercesc::InputSource& is, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > + parseImdn (::xercesc::InputSource& is, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > + parseImdn (::xercesc::InputSource& is, + ::xercesc::DOMErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + // Parse xercesc::DOMDocument. + // + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > + parseImdn (const ::xercesc::DOMDocument& d, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Imdn::Imdn > + parseImdn (::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + } + } +} + +#include + +#include +#include +#include + +#include + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace Imdn + { + // Serialize to std::ostream. + // + + void + serializeImdn (::std::ostream& os, + const ::LinphonePrivate::Xsd::Imdn::Imdn& x, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), + const ::std::string& e = "UTF-8", + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + void + serializeImdn (::std::ostream& os, + const ::LinphonePrivate::Xsd::Imdn::Imdn& x, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& eh, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), + const ::std::string& e = "UTF-8", + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + void + serializeImdn (::std::ostream& os, + const ::LinphonePrivate::Xsd::Imdn::Imdn& x, + ::xercesc::DOMErrorHandler& eh, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), + const ::std::string& e = "UTF-8", + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + // Serialize to xercesc::XMLFormatTarget. + // + + void + serializeImdn (::xercesc::XMLFormatTarget& ft, + const ::LinphonePrivate::Xsd::Imdn::Imdn& x, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), + const ::std::string& e = "UTF-8", + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + void + serializeImdn (::xercesc::XMLFormatTarget& ft, + const ::LinphonePrivate::Xsd::Imdn::Imdn& x, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& eh, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), + const ::std::string& e = "UTF-8", + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + void + serializeImdn (::xercesc::XMLFormatTarget& ft, + const ::LinphonePrivate::Xsd::Imdn::Imdn& x, + ::xercesc::DOMErrorHandler& eh, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), + const ::std::string& e = "UTF-8", + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + // Serialize to an existing xercesc::DOMDocument. + // + + void + serializeImdn (::xercesc::DOMDocument& d, + const ::LinphonePrivate::Xsd::Imdn::Imdn& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + // Serialize to a new xercesc::DOMDocument. + // + + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > + serializeImdn (const ::LinphonePrivate::Xsd::Imdn::Imdn& x, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + void + operator<< (::xercesc::DOMElement&, const Imdn&); + + void + operator<< (::xercesc::DOMElement&, const DeliveryNotification&); + + void + operator<< (::xercesc::DOMElement&, const Delivered&); + + void + operator<< (::xercesc::DOMAttr&, const Delivered&); + + void + operator<< (::LinphonePrivate::Xsd::XmlSchema::ListStream&, + const Delivered&); + + void + operator<< (::xercesc::DOMElement&, const Failed&); + + void + operator<< (::xercesc::DOMAttr&, const Failed&); + + void + operator<< (::LinphonePrivate::Xsd::XmlSchema::ListStream&, + const Failed&); + + void + operator<< (::xercesc::DOMElement&, const DisplayNotification&); + + void + operator<< (::xercesc::DOMElement&, const Displayed&); + + void + operator<< (::xercesc::DOMAttr&, const Displayed&); + + void + operator<< (::LinphonePrivate::Xsd::XmlSchema::ListStream&, + const Displayed&); + + void + operator<< (::xercesc::DOMElement&, const ProcessingNotification&); + + void + operator<< (::xercesc::DOMElement&, const Processed&); + + void + operator<< (::xercesc::DOMAttr&, const Processed&); + + void + operator<< (::LinphonePrivate::Xsd::XmlSchema::ListStream&, + const Processed&); + + void + operator<< (::xercesc::DOMElement&, const Stored&); + + void + operator<< (::xercesc::DOMAttr&, const Stored&); + + void + operator<< (::LinphonePrivate::Xsd::XmlSchema::ListStream&, + const Stored&); + + void + operator<< (::xercesc::DOMElement&, const Forbidden&); + + void + operator<< (::xercesc::DOMAttr&, const Forbidden&); + + void + operator<< (::LinphonePrivate::Xsd::XmlSchema::ListStream&, + const Forbidden&); + + void + operator<< (::xercesc::DOMElement&, const Error&); + + void + operator<< (::xercesc::DOMAttr&, const Error&); + + void + operator<< (::LinphonePrivate::Xsd::XmlSchema::ListStream&, + const Error&); + + void + operator<< (::xercesc::DOMElement&, const Status&); + + void + operator<< (::xercesc::DOMElement&, const Status1&); + + void + operator<< (::xercesc::DOMElement&, const Status2&); + } + } +} + +#include + +// Begin epilogue. +// +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif +#if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) + #pragma GCC diagnostic pop +#endif +#if __clang__ || __GNUC__ >= 4 + #pragma GCC diagnostic pop +#endif +// +// End epilogue. + +#endif // XML_IMDN_H diff --git a/src/xml/imdn.xsd b/src/xml/imdn.xsd new file mode 100644 index 000000000..f69675f60 --- /dev/null +++ b/src/xml/imdn.xsd @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/xml/is-composing.cpp b/src/xml/is-composing.cpp new file mode 100644 index 000000000..ced754a84 --- /dev/null +++ b/src/xml/is-composing.cpp @@ -0,0 +1,971 @@ +// Copyright (c) 2005-2014 Code Synthesis Tools CC +// +// This program was generated by CodeSynthesis XSD, an XML Schema to +// C++ data binding compiler. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as +// published by the Free Software Foundation. +// +// 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 St, Fifth Floor, Boston, MA 02110-1301 USA +// +// In addition, as a special exception, Code Synthesis Tools CC gives +// permission to link this program with the Xerces-C++ library (or with +// modified versions of Xerces-C++ that use the same license as Xerces-C++), +// and distribute linked combinations including the two. You must obey +// the GNU General Public License version 2 in all respects for all of +// the code used other than Xerces-C++. If you modify this copy of the +// program, you may extend this exception to your version of the program, +// but you are not obligated to do so. If you do not wish to do so, delete +// this exception statement from your version. +// +// Furthermore, Code Synthesis Tools CC makes a special exception for +// the Free/Libre and Open Source Software (FLOSS) which is described +// in the accompanying FLOSSE file. +// + +// Begin prologue. +// +#if __clang__ || __GNUC__ >= 4 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wfloat-equal" + #pragma GCC diagnostic ignored "-Wsign-conversion" + #pragma GCC diagnostic ignored "-Wconversion" +#endif +#if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsuggest-override" +#endif +#if __GNUC__ >=7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" +#endif +// +// End prologue. + +#include + +#include "is-composing.h" + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace IsComposing + { + // IsComposing + // + + const IsComposing::StateType& IsComposing:: + getState () const + { + return this->state_.get (); + } + + IsComposing::StateType& IsComposing:: + getState () + { + return this->state_.get (); + } + + void IsComposing:: + setState (const StateType& x) + { + this->state_.set (x); + } + + void IsComposing:: + setState (::std::unique_ptr< StateType > x) + { + this->state_.set (std::move (x)); + } + + ::std::unique_ptr< IsComposing::StateType > IsComposing:: + setDetachState () + { + return this->state_.detach (); + } + + const IsComposing::LastactiveOptional& IsComposing:: + getLastactive () const + { + return this->lastactive_; + } + + IsComposing::LastactiveOptional& IsComposing:: + getLastactive () + { + return this->lastactive_; + } + + void IsComposing:: + setLastactive (const LastactiveType& x) + { + this->lastactive_.set (x); + } + + void IsComposing:: + setLastactive (const LastactiveOptional& x) + { + this->lastactive_ = x; + } + + void IsComposing:: + setLastactive (::std::unique_ptr< LastactiveType > x) + { + this->lastactive_.set (std::move (x)); + } + + const IsComposing::ContenttypeOptional& IsComposing:: + getContenttype () const + { + return this->contenttype_; + } + + IsComposing::ContenttypeOptional& IsComposing:: + getContenttype () + { + return this->contenttype_; + } + + void IsComposing:: + setContenttype (const ContenttypeType& x) + { + this->contenttype_.set (x); + } + + void IsComposing:: + setContenttype (const ContenttypeOptional& x) + { + this->contenttype_ = x; + } + + void IsComposing:: + setContenttype (::std::unique_ptr< ContenttypeType > x) + { + this->contenttype_.set (std::move (x)); + } + + const IsComposing::RefreshOptional& IsComposing:: + getRefresh () const + { + return this->refresh_; + } + + IsComposing::RefreshOptional& IsComposing:: + getRefresh () + { + return this->refresh_; + } + + void IsComposing:: + setRefresh (const RefreshType& x) + { + this->refresh_.set (x); + } + + void IsComposing:: + setRefresh (const RefreshOptional& x) + { + this->refresh_ = x; + } + + const IsComposing::AnySequence& IsComposing:: + getAny () const + { + return this->any_; + } + + IsComposing::AnySequence& IsComposing:: + getAny () + { + return this->any_; + } + + void IsComposing:: + setAny (const AnySequence& s) + { + this->any_ = s; + } + + const ::xercesc::DOMDocument& IsComposing:: + getDomDocument () const + { + return *this->dom_document_; + } + + ::xercesc::DOMDocument& IsComposing:: + getDomDocument () + { + return *this->dom_document_; + } + } + } +} + +#include + +#include + +#include + +namespace _xsd +{ + static + const ::xsd::cxx::tree::type_factory_plate< 0, char > + type_factory_plate_init; +} + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace IsComposing + { + // IsComposing + // + + IsComposing:: + IsComposing (const StateType& state) + : ::LinphonePrivate::Xsd::XmlSchema::Type (), + dom_document_ (::xsd::cxx::xml::dom::create_document< char > ()), + state_ (state, this), + lastactive_ (this), + contenttype_ (this), + refresh_ (this), + any_ (this->getDomDocument ()) + { + } + + IsComposing:: + IsComposing (const IsComposing& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (x, f, c), + dom_document_ (::xsd::cxx::xml::dom::create_document< char > ()), + state_ (x.state_, f, this), + lastactive_ (x.lastactive_, f, this), + contenttype_ (x.contenttype_, f, this), + refresh_ (x.refresh_, f, this), + any_ (x.any_, this->getDomDocument ()) + { + } + + IsComposing:: + IsComposing (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (e, f | ::LinphonePrivate::Xsd::XmlSchema::Flags::base, c), + dom_document_ (::xsd::cxx::xml::dom::create_document< char > ()), + state_ (this), + lastactive_ (this), + contenttype_ (this), + refresh_ (this), + any_ (this->getDomDocument ()) + { + if ((f & ::LinphonePrivate::Xsd::XmlSchema::Flags::base) == 0) + { + ::xsd::cxx::xml::dom::parser< char > p (e, true, false, false); + this->parse (p, f); + } + } + + void IsComposing:: + parse (::xsd::cxx::xml::dom::parser< char >& p, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + for (; p.more_content (); p.next_content (false)) + { + const ::xercesc::DOMElement& i (p.cur_element ()); + const ::xsd::cxx::xml::qualified_name< char > n ( + ::xsd::cxx::xml::dom::name< char > (i)); + + // state + // + if (n.name () == "state" && n.namespace_ () == "urn:ietf:params:xml:ns:im-iscomposing") + { + ::std::unique_ptr< StateType > r ( + StateTraits::create (i, f, this)); + + if (!state_.present ()) + { + this->state_.set (::std::move (r)); + continue; + } + } + + // lastactive + // + if (n.name () == "lastactive" && n.namespace_ () == "urn:ietf:params:xml:ns:im-iscomposing") + { + ::std::unique_ptr< LastactiveType > r ( + LastactiveTraits::create (i, f, this)); + + if (!this->lastactive_) + { + this->lastactive_.set (::std::move (r)); + continue; + } + } + + // contenttype + // + if (n.name () == "contenttype" && n.namespace_ () == "urn:ietf:params:xml:ns:im-iscomposing") + { + ::std::unique_ptr< ContenttypeType > r ( + ContenttypeTraits::create (i, f, this)); + + if (!this->contenttype_) + { + this->contenttype_.set (::std::move (r)); + continue; + } + } + + // refresh + // + if (n.name () == "refresh" && n.namespace_ () == "urn:ietf:params:xml:ns:im-iscomposing") + { + if (!this->refresh_) + { + this->refresh_.set (RefreshTraits::create (i, f, this)); + continue; + } + } + + // any + // + if ((!n.namespace_ ().empty () && n.namespace_ () != "urn:ietf:params:xml:ns:im-iscomposing")) + { + ::xercesc::DOMElement* r ( + static_cast< ::xercesc::DOMElement* > ( + this->getDomDocument ().importNode ( + const_cast< ::xercesc::DOMElement* > (&i), true))); + this->any_.push_back (r); + continue; + } + + break; + } + + if (!state_.present ()) + { + throw ::xsd::cxx::tree::expected_element< char > ( + "state", + "urn:ietf:params:xml:ns:im-iscomposing"); + } + } + + IsComposing* IsComposing:: + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) const + { + return new class IsComposing (*this, f, c); + } + + IsComposing& IsComposing:: + operator= (const IsComposing& x) + { + if (this != &x) + { + static_cast< ::LinphonePrivate::Xsd::XmlSchema::Type& > (*this) = x; + this->state_ = x.state_; + this->lastactive_ = x.lastactive_; + this->contenttype_ = x.contenttype_; + this->refresh_ = x.refresh_; + this->any_ = x.any_; + } + + return *this; + } + + IsComposing:: + ~IsComposing () + { + } + } + } +} + +#include + +#include + +namespace _xsd +{ + static + const ::xsd::cxx::tree::std_ostream_plate< 0, char > + std_ostream_plate_init; +} + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace IsComposing + { + ::std::ostream& + operator<< (::std::ostream& o, const IsComposing& i) + { + o << ::std::endl << "state: " << i.getState (); + if (i.getLastactive ()) + { + o << ::std::endl << "lastactive: " << *i.getLastactive (); + } + + if (i.getContenttype ()) + { + o << ::std::endl << "contenttype: " << *i.getContenttype (); + } + + if (i.getRefresh ()) + { + o << ::std::endl << "refresh: " << *i.getRefresh (); + } + + return o; + } + } + } +} + +#include +#include +#include + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace IsComposing + { + ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > + parseIsComposing (const ::std::string& u, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0, + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) == 0); + + ::xsd::cxx::tree::error_handler< char > h; + + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::xsd::cxx::xml::dom::parse< char > ( + u, h, p, f)); + + h.throw_if_failed< ::xsd::cxx::tree::parsing< char > > (); + + return ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > ( + ::LinphonePrivate::Xsd::IsComposing::parseIsComposing ( + std::move (d), f | ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom, p)); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > + parseIsComposing (const ::std::string& u, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0, + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) == 0); + + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::xsd::cxx::xml::dom::parse< char > ( + u, h, p, f)); + + if (!d.get ()) + throw ::xsd::cxx::tree::parsing< char > (); + + return ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > ( + ::LinphonePrivate::Xsd::IsComposing::parseIsComposing ( + std::move (d), f | ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom, p)); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > + parseIsComposing (const ::std::string& u, + ::xercesc::DOMErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::xsd::cxx::xml::dom::parse< char > ( + u, h, p, f)); + + if (!d.get ()) + throw ::xsd::cxx::tree::parsing< char > (); + + return ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > ( + ::LinphonePrivate::Xsd::IsComposing::parseIsComposing ( + std::move (d), f | ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom, p)); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > + parseIsComposing (::std::istream& is, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0, + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) == 0); + + ::xsd::cxx::xml::sax::std_input_source isrc (is); + return ::LinphonePrivate::Xsd::IsComposing::parseIsComposing (isrc, f, p); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > + parseIsComposing (::std::istream& is, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0, + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) == 0); + + ::xsd::cxx::xml::sax::std_input_source isrc (is); + return ::LinphonePrivate::Xsd::IsComposing::parseIsComposing (isrc, h, f, p); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > + parseIsComposing (::std::istream& is, + ::xercesc::DOMErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::sax::std_input_source isrc (is); + return ::LinphonePrivate::Xsd::IsComposing::parseIsComposing (isrc, h, f, p); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > + parseIsComposing (::std::istream& is, + const ::std::string& sid, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0, + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) == 0); + + ::xsd::cxx::xml::sax::std_input_source isrc (is, sid); + return ::LinphonePrivate::Xsd::IsComposing::parseIsComposing (isrc, f, p); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > + parseIsComposing (::std::istream& is, + const ::std::string& sid, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0, + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) == 0); + + ::xsd::cxx::xml::sax::std_input_source isrc (is, sid); + return ::LinphonePrivate::Xsd::IsComposing::parseIsComposing (isrc, h, f, p); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > + parseIsComposing (::std::istream& is, + const ::std::string& sid, + ::xercesc::DOMErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::sax::std_input_source isrc (is, sid); + return ::LinphonePrivate::Xsd::IsComposing::parseIsComposing (isrc, h, f, p); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > + parseIsComposing (::xercesc::InputSource& i, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::tree::error_handler< char > h; + + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::xsd::cxx::xml::dom::parse< char > ( + i, h, p, f)); + + h.throw_if_failed< ::xsd::cxx::tree::parsing< char > > (); + + return ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > ( + ::LinphonePrivate::Xsd::IsComposing::parseIsComposing ( + std::move (d), f | ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom, p)); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > + parseIsComposing (::xercesc::InputSource& i, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::xsd::cxx::xml::dom::parse< char > ( + i, h, p, f)); + + if (!d.get ()) + throw ::xsd::cxx::tree::parsing< char > (); + + return ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > ( + ::LinphonePrivate::Xsd::IsComposing::parseIsComposing ( + std::move (d), f | ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom, p)); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > + parseIsComposing (::xercesc::InputSource& i, + ::xercesc::DOMErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::xsd::cxx::xml::dom::parse< char > ( + i, h, p, f)); + + if (!d.get ()) + throw ::xsd::cxx::tree::parsing< char > (); + + return ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > ( + ::LinphonePrivate::Xsd::IsComposing::parseIsComposing ( + std::move (d), f | ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom, p)); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > + parseIsComposing (const ::xercesc::DOMDocument& doc, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + if (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + static_cast< ::xercesc::DOMDocument* > (doc.cloneNode (true))); + + return ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > ( + ::LinphonePrivate::Xsd::IsComposing::parseIsComposing ( + std::move (d), f | ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom, p)); + } + + const ::xercesc::DOMElement& e (*doc.getDocumentElement ()); + const ::xsd::cxx::xml::qualified_name< char > n ( + ::xsd::cxx::xml::dom::name< char > (e)); + + if (n.name () == "isComposing" && + n.namespace_ () == "urn:ietf:params:xml:ns:im-iscomposing") + { + ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > r ( + ::xsd::cxx::tree::traits< ::LinphonePrivate::Xsd::IsComposing::IsComposing, char >::create ( + e, f, 0)); + return r; + } + + throw ::xsd::cxx::tree::unexpected_element < char > ( + n.name (), + n.namespace_ (), + "isComposing", + "urn:ietf:params:xml:ns:im-iscomposing"); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > + parseIsComposing (::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties&) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > c ( + ((f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) && + !(f & ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom)) + ? static_cast< ::xercesc::DOMDocument* > (d->cloneNode (true)) + : 0); + + ::xercesc::DOMDocument& doc (c.get () ? *c : *d); + const ::xercesc::DOMElement& e (*doc.getDocumentElement ()); + + const ::xsd::cxx::xml::qualified_name< char > n ( + ::xsd::cxx::xml::dom::name< char > (e)); + + if (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) + doc.setUserData (::LinphonePrivate::Xsd::XmlSchema::dom::treeNodeKey, + (c.get () ? &c : &d), + 0); + + if (n.name () == "isComposing" && + n.namespace_ () == "urn:ietf:params:xml:ns:im-iscomposing") + { + ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > r ( + ::xsd::cxx::tree::traits< ::LinphonePrivate::Xsd::IsComposing::IsComposing, char >::create ( + e, f, 0)); + return r; + } + + throw ::xsd::cxx::tree::unexpected_element < char > ( + n.name (), + n.namespace_ (), + "isComposing", + "urn:ietf:params:xml:ns:im-iscomposing"); + } + } + } +} + +#include +#include +#include + +#include + +namespace _xsd +{ + static + const ::xsd::cxx::tree::type_serializer_plate< 0, char > + type_serializer_plate_init; +} + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace IsComposing + { + void + serializeIsComposing (::std::ostream& o, + const ::LinphonePrivate::Xsd::IsComposing::IsComposing& s, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m, + const ::std::string& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0); + + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::LinphonePrivate::Xsd::IsComposing::serializeIsComposing (s, m, f)); + + ::xsd::cxx::tree::error_handler< char > h; + + ::xsd::cxx::xml::dom::ostream_format_target t (o); + if (!::xsd::cxx::xml::dom::serialize (t, *d, e, h, f)) + { + h.throw_if_failed< ::xsd::cxx::tree::serialization< char > > (); + } + } + + void + serializeIsComposing (::std::ostream& o, + const ::LinphonePrivate::Xsd::IsComposing::IsComposing& s, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& h, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m, + const ::std::string& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0); + + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::LinphonePrivate::Xsd::IsComposing::serializeIsComposing (s, m, f)); + ::xsd::cxx::xml::dom::ostream_format_target t (o); + if (!::xsd::cxx::xml::dom::serialize (t, *d, e, h, f)) + { + throw ::xsd::cxx::tree::serialization< char > (); + } + } + + void + serializeIsComposing (::std::ostream& o, + const ::LinphonePrivate::Xsd::IsComposing::IsComposing& s, + ::xercesc::DOMErrorHandler& h, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m, + const ::std::string& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::LinphonePrivate::Xsd::IsComposing::serializeIsComposing (s, m, f)); + ::xsd::cxx::xml::dom::ostream_format_target t (o); + if (!::xsd::cxx::xml::dom::serialize (t, *d, e, h, f)) + { + throw ::xsd::cxx::tree::serialization< char > (); + } + } + + void + serializeIsComposing (::xercesc::XMLFormatTarget& t, + const ::LinphonePrivate::Xsd::IsComposing::IsComposing& s, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m, + const ::std::string& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::LinphonePrivate::Xsd::IsComposing::serializeIsComposing (s, m, f)); + + ::xsd::cxx::tree::error_handler< char > h; + + if (!::xsd::cxx::xml::dom::serialize (t, *d, e, h, f)) + { + h.throw_if_failed< ::xsd::cxx::tree::serialization< char > > (); + } + } + + void + serializeIsComposing (::xercesc::XMLFormatTarget& t, + const ::LinphonePrivate::Xsd::IsComposing::IsComposing& s, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& h, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m, + const ::std::string& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::LinphonePrivate::Xsd::IsComposing::serializeIsComposing (s, m, f)); + if (!::xsd::cxx::xml::dom::serialize (t, *d, e, h, f)) + { + throw ::xsd::cxx::tree::serialization< char > (); + } + } + + void + serializeIsComposing (::xercesc::XMLFormatTarget& t, + const ::LinphonePrivate::Xsd::IsComposing::IsComposing& s, + ::xercesc::DOMErrorHandler& h, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m, + const ::std::string& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::LinphonePrivate::Xsd::IsComposing::serializeIsComposing (s, m, f)); + if (!::xsd::cxx::xml::dom::serialize (t, *d, e, h, f)) + { + throw ::xsd::cxx::tree::serialization< char > (); + } + } + + void + serializeIsComposing (::xercesc::DOMDocument& d, + const ::LinphonePrivate::Xsd::IsComposing::IsComposing& s, + ::LinphonePrivate::Xsd::XmlSchema::Flags) + { + ::xercesc::DOMElement& e (*d.getDocumentElement ()); + const ::xsd::cxx::xml::qualified_name< char > n ( + ::xsd::cxx::xml::dom::name< char > (e)); + + if (n.name () == "isComposing" && + n.namespace_ () == "urn:ietf:params:xml:ns:im-iscomposing") + { + e << s; + } + else + { + throw ::xsd::cxx::tree::unexpected_element < char > ( + n.name (), + n.namespace_ (), + "isComposing", + "urn:ietf:params:xml:ns:im-iscomposing"); + } + } + + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > + serializeIsComposing (const ::LinphonePrivate::Xsd::IsComposing::IsComposing& s, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::xsd::cxx::xml::dom::serialize< char > ( + "isComposing", + "urn:ietf:params:xml:ns:im-iscomposing", + m, f)); + + ::LinphonePrivate::Xsd::IsComposing::serializeIsComposing (*d, s, f); + return d; + } + + void + operator<< (::xercesc::DOMElement& e, const IsComposing& i) + { + e << static_cast< const ::LinphonePrivate::Xsd::XmlSchema::Type& > (i); + + // state + // + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "state", + "urn:ietf:params:xml:ns:im-iscomposing", + e)); + + s << i.getState (); + } + + // lastactive + // + if (i.getLastactive ()) + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "lastactive", + "urn:ietf:params:xml:ns:im-iscomposing", + e)); + + s << *i.getLastactive (); + } + + // contenttype + // + if (i.getContenttype ()) + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "contenttype", + "urn:ietf:params:xml:ns:im-iscomposing", + e)); + + s << *i.getContenttype (); + } + + // refresh + // + if (i.getRefresh ()) + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "refresh", + "urn:ietf:params:xml:ns:im-iscomposing", + e)); + + s << *i.getRefresh (); + } + + // any + // + for (IsComposing::AnyConstIterator + b (i.getAny ().begin ()), n (i.getAny ().end ()); + b != n; ++b) + { + e.appendChild ( + e.getOwnerDocument ()->importNode ( + const_cast< ::xercesc::DOMElement* > (&(*b)), true)); + } + } + } + } +} + +#include + +// Begin epilogue. +// +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif +#if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) + #pragma GCC diagnostic pop +#endif +#if __clang__ || __GNUC__ >= 4 + #pragma GCC diagnostic pop +#endif +// +// End epilogue. + diff --git a/src/xml/is-composing.h b/src/xml/is-composing.h new file mode 100644 index 000000000..a19585c91 --- /dev/null +++ b/src/xml/is-composing.h @@ -0,0 +1,687 @@ +// Copyright (c) 2005-2014 Code Synthesis Tools CC +// +// This program was generated by CodeSynthesis XSD, an XML Schema to +// C++ data binding compiler. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as +// published by the Free Software Foundation. +// +// 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 St, Fifth Floor, Boston, MA 02110-1301 USA +// +// In addition, as a special exception, Code Synthesis Tools CC gives +// permission to link this program with the Xerces-C++ library (or with +// modified versions of Xerces-C++ that use the same license as Xerces-C++), +// and distribute linked combinations including the two. You must obey +// the GNU General Public License version 2 in all respects for all of +// the code used other than Xerces-C++. If you modify this copy of the +// program, you may extend this exception to your version of the program, +// but you are not obligated to do so. If you do not wish to do so, delete +// this exception statement from your version. +// +// Furthermore, Code Synthesis Tools CC makes a special exception for +// the Free/Libre and Open Source Software (FLOSS) which is described +// in the accompanying FLOSSE file. +// + +#ifndef XML_IS_COMPOSING_H +#define XML_IS_COMPOSING_H + +#ifndef XSD_CXX11 +#define XSD_CXX11 +#endif + +#ifndef XSD_USE_CHAR +#define XSD_USE_CHAR +#endif + +#ifndef XSD_CXX_TREE_USE_CHAR +#define XSD_CXX_TREE_USE_CHAR +#endif + +// Begin prologue. +// +#if __clang__ || __GNUC__ >= 4 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wfloat-equal" + #pragma GCC diagnostic ignored "-Wsign-conversion" + #pragma GCC diagnostic ignored "-Wconversion" +#endif +#if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsuggest-override" +#endif +#if __GNUC__ >=7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" +#endif +// +// End prologue. + +#include + +#if (XSD_INT_VERSION != 4000000L) +#error XSD runtime version mismatch +#endif + +#include + +#include + +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace XmlSchema + { + // anyType and anySimpleType. + // + typedef ::xsd::cxx::tree::type Type; + typedef ::xsd::cxx::tree::simple_type< char, Type > SimpleType; + typedef ::xsd::cxx::tree::type Container; + + // 8-bit + // + typedef signed char Byte; + typedef unsigned char UnsignedByte; + + // 16-bit + // + typedef short Short; + typedef unsigned short UnsignedShort; + + // 32-bit + // + typedef int Int; + typedef unsigned int UnsignedInt; + + // 64-bit + // + typedef long long Long; + typedef unsigned long long UnsignedLong; + + // Supposed to be arbitrary-length integral types. + // + typedef long long Integer; + typedef long long NonPositiveInteger; + typedef unsigned long long NonNegativeInteger; + typedef unsigned long long PositiveInteger; + typedef long long NegativeInteger; + + // Boolean. + // + typedef bool Boolean; + + // Floating-point types. + // + typedef float Float; + typedef double Double; + typedef double Decimal; + + // String types. + // + typedef ::xsd::cxx::tree::string< char, SimpleType > String; + typedef ::xsd::cxx::tree::normalized_string< char, String > NormalizedString; + typedef ::xsd::cxx::tree::token< char, NormalizedString > Token; + typedef ::xsd::cxx::tree::name< char, Token > Name; + typedef ::xsd::cxx::tree::nmtoken< char, Token > Nmtoken; + typedef ::xsd::cxx::tree::nmtokens< char, SimpleType, Nmtoken > Nmtokens; + typedef ::xsd::cxx::tree::ncname< char, Name > Ncname; + typedef ::xsd::cxx::tree::language< char, Token > Language; + + // ID/IDREF. + // + typedef ::xsd::cxx::tree::id< char, Ncname > Id; + typedef ::xsd::cxx::tree::idref< char, Ncname, Type > Idref; + typedef ::xsd::cxx::tree::idrefs< char, SimpleType, Idref > Idrefs; + + // URI. + // + typedef ::xsd::cxx::tree::uri< char, SimpleType > Uri; + + // Qualified name. + // + typedef ::xsd::cxx::tree::qname< char, SimpleType, Uri, Ncname > Qname; + + // Binary. + // + typedef ::xsd::cxx::tree::buffer< char > Buffer; + typedef ::xsd::cxx::tree::base64_binary< char, SimpleType > Base64Binary; + typedef ::xsd::cxx::tree::hex_binary< char, SimpleType > HexBinary; + + // Date/time. + // + typedef ::xsd::cxx::tree::time_zone TimeZone; + typedef ::xsd::cxx::tree::date< char, SimpleType > Date; + typedef ::xsd::cxx::tree::date_time< char, SimpleType > DateTime; + typedef ::xsd::cxx::tree::duration< char, SimpleType > Duration; + typedef ::xsd::cxx::tree::gday< char, SimpleType > Gday; + typedef ::xsd::cxx::tree::gmonth< char, SimpleType > Gmonth; + typedef ::xsd::cxx::tree::gmonth_day< char, SimpleType > GmonthDay; + typedef ::xsd::cxx::tree::gyear< char, SimpleType > Gyear; + typedef ::xsd::cxx::tree::gyear_month< char, SimpleType > GyearMonth; + typedef ::xsd::cxx::tree::time< char, SimpleType > Time; + + // Entity. + // + typedef ::xsd::cxx::tree::entity< char, Ncname > Entity; + typedef ::xsd::cxx::tree::entities< char, SimpleType, Entity > Entities; + + typedef ::xsd::cxx::tree::content_order ContentOrder; + // Namespace information and list stream. Used in + // serialization functions. + // + typedef ::xsd::cxx::xml::dom::namespace_info< char > NamespaceInfo; + typedef ::xsd::cxx::xml::dom::namespace_infomap< char > NamespaceInfomap; + typedef ::xsd::cxx::tree::list_stream< char > ListStream; + typedef ::xsd::cxx::tree::as_double< Double > AsDouble; + typedef ::xsd::cxx::tree::as_decimal< Decimal > AsDecimal; + typedef ::xsd::cxx::tree::facet Facet; + + // Flags and properties. + // + typedef ::xsd::cxx::tree::flags Flags; + typedef ::xsd::cxx::tree::properties< char > Properties; + + // Parsing/serialization diagnostics. + // + typedef ::xsd::cxx::tree::severity Severity; + typedef ::xsd::cxx::tree::error< char > Error; + typedef ::xsd::cxx::tree::diagnostics< char > Diagnostics; + + // Exceptions. + // + typedef ::xsd::cxx::tree::exception< char > Exception; + typedef ::xsd::cxx::tree::bounds< char > Bounds; + typedef ::xsd::cxx::tree::duplicate_id< char > DuplicateId; + typedef ::xsd::cxx::tree::parsing< char > Parsing; + typedef ::xsd::cxx::tree::expected_element< char > ExpectedElement; + typedef ::xsd::cxx::tree::unexpected_element< char > UnexpectedElement; + typedef ::xsd::cxx::tree::expected_attribute< char > ExpectedAttribute; + typedef ::xsd::cxx::tree::unexpected_enumerator< char > UnexpectedEnumerator; + typedef ::xsd::cxx::tree::expected_text_content< char > ExpectedTextContent; + typedef ::xsd::cxx::tree::no_prefix_mapping< char > NoPrefixMapping; + typedef ::xsd::cxx::tree::no_type_info< char > NoTypeInfo; + typedef ::xsd::cxx::tree::not_derived< char > NotDerived; + typedef ::xsd::cxx::tree::serialization< char > Serialization; + + // Error handler callback interface. + // + typedef ::xsd::cxx::xml::error_handler< char > ErrorHandler; + + // DOM interaction. + // + namespace dom + { + // Automatic pointer for DOMDocument. + // + using ::xsd::cxx::xml::dom::unique_ptr; + +#ifndef XSD_CXX_TREE_TREE_NODE_KEY__LINPHONEPRIVATE__XSD__XMLSCHEMA +#define XSD_CXX_TREE_TREE_NODE_KEY__LINPHONEPRIVATE__XSD__XMLSCHEMA + // DOM user data key for back pointers to tree nodes. + // + const XMLCh* const treeNodeKey = ::xsd::cxx::tree::user_data_keys::node; +#endif + } + } + } +} + +// Forward declarations. +// +namespace LinphonePrivate +{ + namespace Xsd + { + namespace IsComposing + { + class IsComposing; + } + } +} + + +#include // ::std::unique_ptr +#include // std::numeric_limits +#include // std::binary_search +#include // std::move + +#include + +#include +#include +#include +#include + +#include + +#include + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace IsComposing + { + class IsComposing: public ::LinphonePrivate::Xsd::XmlSchema::Type + { + public: + // state + // + typedef ::LinphonePrivate::Xsd::XmlSchema::String StateType; + typedef ::xsd::cxx::tree::traits< StateType, char > StateTraits; + + const StateType& + getState () const; + + StateType& + getState (); + + void + setState (const StateType& x); + + void + setState (::std::unique_ptr< StateType > p); + + ::std::unique_ptr< StateType > + setDetachState (); + + // lastactive + // + typedef ::LinphonePrivate::Xsd::XmlSchema::DateTime LastactiveType; + typedef ::xsd::cxx::tree::optional< LastactiveType > LastactiveOptional; + typedef ::xsd::cxx::tree::traits< LastactiveType, char > LastactiveTraits; + + const LastactiveOptional& + getLastactive () const; + + LastactiveOptional& + getLastactive (); + + void + setLastactive (const LastactiveType& x); + + void + setLastactive (const LastactiveOptional& x); + + void + setLastactive (::std::unique_ptr< LastactiveType > p); + + // contenttype + // + typedef ::LinphonePrivate::Xsd::XmlSchema::String ContenttypeType; + typedef ::xsd::cxx::tree::optional< ContenttypeType > ContenttypeOptional; + typedef ::xsd::cxx::tree::traits< ContenttypeType, char > ContenttypeTraits; + + const ContenttypeOptional& + getContenttype () const; + + ContenttypeOptional& + getContenttype (); + + void + setContenttype (const ContenttypeType& x); + + void + setContenttype (const ContenttypeOptional& x); + + void + setContenttype (::std::unique_ptr< ContenttypeType > p); + + // refresh + // + typedef ::LinphonePrivate::Xsd::XmlSchema::PositiveInteger RefreshType; + typedef ::xsd::cxx::tree::optional< RefreshType > RefreshOptional; + typedef ::xsd::cxx::tree::traits< RefreshType, char > RefreshTraits; + + const RefreshOptional& + getRefresh () const; + + RefreshOptional& + getRefresh (); + + void + setRefresh (const RefreshType& x); + + void + setRefresh (const RefreshOptional& x); + + // any + // + typedef ::xsd::cxx::tree::element_sequence AnySequence; + typedef AnySequence::iterator AnyIterator; + typedef AnySequence::const_iterator AnyConstIterator; + + const AnySequence& + getAny () const; + + AnySequence& + getAny (); + + void + setAny (const AnySequence& s); + + // DOMDocument for wildcard content. + // + const ::xercesc::DOMDocument& + getDomDocument () const; + + ::xercesc::DOMDocument& + getDomDocument (); + + // Constructors. + // + IsComposing (const StateType&); + + IsComposing (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + IsComposing (const IsComposing& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + virtual IsComposing* + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0) const; + + IsComposing& + operator= (const IsComposing& x); + + virtual + ~IsComposing (); + + // Implementation. + // + protected: + void + parse (::xsd::cxx::xml::dom::parser< char >&, + ::LinphonePrivate::Xsd::XmlSchema::Flags); + + protected: + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > dom_document_; + + ::xsd::cxx::tree::one< StateType > state_; + LastactiveOptional lastactive_; + ContenttypeOptional contenttype_; + RefreshOptional refresh_; + AnySequence any_; + }; + } + } +} + +#include + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace IsComposing + { + ::std::ostream& + operator<< (::std::ostream&, const IsComposing&); + } + } +} + +#include + +#include +#include +#include + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace IsComposing + { + // Parse a URI or a local file. + // + + ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > + parseIsComposing (const ::std::string& uri, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > + parseIsComposing (const ::std::string& uri, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > + parseIsComposing (const ::std::string& uri, + ::xercesc::DOMErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + // Parse std::istream. + // + + ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > + parseIsComposing (::std::istream& is, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > + parseIsComposing (::std::istream& is, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > + parseIsComposing (::std::istream& is, + ::xercesc::DOMErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > + parseIsComposing (::std::istream& is, + const ::std::string& id, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > + parseIsComposing (::std::istream& is, + const ::std::string& id, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > + parseIsComposing (::std::istream& is, + const ::std::string& id, + ::xercesc::DOMErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + // Parse xercesc::InputSource. + // + + ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > + parseIsComposing (::xercesc::InputSource& is, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > + parseIsComposing (::xercesc::InputSource& is, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > + parseIsComposing (::xercesc::InputSource& is, + ::xercesc::DOMErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + // Parse xercesc::DOMDocument. + // + + ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > + parseIsComposing (const ::xercesc::DOMDocument& d, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::IsComposing::IsComposing > + parseIsComposing (::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + } + } +} + +#include + +#include +#include +#include + +#include + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace IsComposing + { + // Serialize to std::ostream. + // + + void + serializeIsComposing (::std::ostream& os, + const ::LinphonePrivate::Xsd::IsComposing::IsComposing& x, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), + const ::std::string& e = "UTF-8", + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + void + serializeIsComposing (::std::ostream& os, + const ::LinphonePrivate::Xsd::IsComposing::IsComposing& x, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& eh, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), + const ::std::string& e = "UTF-8", + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + void + serializeIsComposing (::std::ostream& os, + const ::LinphonePrivate::Xsd::IsComposing::IsComposing& x, + ::xercesc::DOMErrorHandler& eh, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), + const ::std::string& e = "UTF-8", + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + // Serialize to xercesc::XMLFormatTarget. + // + + void + serializeIsComposing (::xercesc::XMLFormatTarget& ft, + const ::LinphonePrivate::Xsd::IsComposing::IsComposing& x, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), + const ::std::string& e = "UTF-8", + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + void + serializeIsComposing (::xercesc::XMLFormatTarget& ft, + const ::LinphonePrivate::Xsd::IsComposing::IsComposing& x, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& eh, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), + const ::std::string& e = "UTF-8", + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + void + serializeIsComposing (::xercesc::XMLFormatTarget& ft, + const ::LinphonePrivate::Xsd::IsComposing::IsComposing& x, + ::xercesc::DOMErrorHandler& eh, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), + const ::std::string& e = "UTF-8", + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + // Serialize to an existing xercesc::DOMDocument. + // + + void + serializeIsComposing (::xercesc::DOMDocument& d, + const ::LinphonePrivate::Xsd::IsComposing::IsComposing& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + // Serialize to a new xercesc::DOMDocument. + // + + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > + serializeIsComposing (const ::LinphonePrivate::Xsd::IsComposing::IsComposing& x, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + void + operator<< (::xercesc::DOMElement&, const IsComposing&); + } + } +} + +#include + +// Begin epilogue. +// +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif +#if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) + #pragma GCC diagnostic pop +#endif +#if __clang__ || __GNUC__ >= 4 + #pragma GCC diagnostic pop +#endif +// +// End epilogue. + +#endif // XML_IS_COMPOSING_H diff --git a/src/xml/is-composing.xsd b/src/xml/is-composing.xsd new file mode 100644 index 000000000..7cf4a8b70 --- /dev/null +++ b/src/xml/is-composing.xsd @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + diff --git a/src/xml/linphone-imdn.cpp b/src/xml/linphone-imdn.cpp new file mode 100644 index 000000000..5f064f1a5 --- /dev/null +++ b/src/xml/linphone-imdn.cpp @@ -0,0 +1,726 @@ +// Copyright (c) 2005-2014 Code Synthesis Tools CC +// +// This program was generated by CodeSynthesis XSD, an XML Schema to +// C++ data binding compiler. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as +// published by the Free Software Foundation. +// +// 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 St, Fifth Floor, Boston, MA 02110-1301 USA +// +// In addition, as a special exception, Code Synthesis Tools CC gives +// permission to link this program with the Xerces-C++ library (or with +// modified versions of Xerces-C++ that use the same license as Xerces-C++), +// and distribute linked combinations including the two. You must obey +// the GNU General Public License version 2 in all respects for all of +// the code used other than Xerces-C++. If you modify this copy of the +// program, you may extend this exception to your version of the program, +// but you are not obligated to do so. If you do not wish to do so, delete +// this exception statement from your version. +// +// Furthermore, Code Synthesis Tools CC makes a special exception for +// the Free/Libre and Open Source Software (FLOSS) which is described +// in the accompanying FLOSSE file. +// + +// Begin prologue. +// +#if __clang__ || __GNUC__ >= 4 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wfloat-equal" + #pragma GCC diagnostic ignored "-Wsign-conversion" + #pragma GCC diagnostic ignored "-Wconversion" +#endif +#if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsuggest-override" +#endif +#if __GNUC__ >=7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" +#endif +// +// End prologue. + +#include + +#include "linphone-imdn.h" + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace LinphoneImdn + { + // ImdnReason + // + + const ImdnReason::CodeType& ImdnReason:: + getCode () const + { + return this->code_.get (); + } + + ImdnReason::CodeType& ImdnReason:: + getCode () + { + return this->code_.get (); + } + + void ImdnReason:: + setCode (const CodeType& x) + { + this->code_.set (x); + } + + ImdnReason::CodeType ImdnReason:: + getCodeDefaultValue () + { + return CodeType (200); + } + } + } +} + +#include + +#include + +#include + +namespace _xsd +{ + static + const ::xsd::cxx::tree::type_factory_plate< 0, char > + type_factory_plate_init; +} + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace LinphoneImdn + { + // ImdnReason + // + + ImdnReason:: + ImdnReason () + : ::LinphonePrivate::Xsd::XmlSchema::String (), + code_ (getCodeDefaultValue (), this) + { + } + + ImdnReason:: + ImdnReason (const char* _xsd_String_base) + : ::LinphonePrivate::Xsd::XmlSchema::String (_xsd_String_base), + code_ (getCodeDefaultValue (), this) + { + } + + ImdnReason:: + ImdnReason (const ::std::string& _xsd_String_base) + : ::LinphonePrivate::Xsd::XmlSchema::String (_xsd_String_base), + code_ (getCodeDefaultValue (), this) + { + } + + ImdnReason:: + ImdnReason (const ::LinphonePrivate::Xsd::XmlSchema::String& _xsd_String_base) + : ::LinphonePrivate::Xsd::XmlSchema::String (_xsd_String_base), + code_ (getCodeDefaultValue (), this) + { + } + + ImdnReason:: + ImdnReason (const ImdnReason& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::String (x, f, c), + code_ (x.code_, f, this) + { + } + + ImdnReason:: + ImdnReason (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::String (e, f | ::LinphonePrivate::Xsd::XmlSchema::Flags::base, c), + code_ (this) + { + if ((f & ::LinphonePrivate::Xsd::XmlSchema::Flags::base) == 0) + { + ::xsd::cxx::xml::dom::parser< char > p (e, false, false, true); + this->parse (p, f); + } + } + + void ImdnReason:: + parse (::xsd::cxx::xml::dom::parser< char >& p, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + while (p.more_attributes ()) + { + const ::xercesc::DOMAttr& i (p.next_attribute ()); + const ::xsd::cxx::xml::qualified_name< char > n ( + ::xsd::cxx::xml::dom::name< char > (i)); + + if (n.name () == "code" && n.namespace_ ().empty ()) + { + this->code_.set (CodeTraits::create (i, f, this)); + continue; + } + } + + if (!code_.present ()) + { + this->code_.set (getCodeDefaultValue ()); + } + } + + ImdnReason* ImdnReason:: + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) const + { + return new class ImdnReason (*this, f, c); + } + + ImdnReason& ImdnReason:: + operator= (const ImdnReason& x) + { + if (this != &x) + { + static_cast< ::LinphonePrivate::Xsd::XmlSchema::String& > (*this) = x; + this->code_ = x.code_; + } + + return *this; + } + + ImdnReason:: + ~ImdnReason () + { + } + } + } +} + +#include + +#include + +namespace _xsd +{ + static + const ::xsd::cxx::tree::std_ostream_plate< 0, char > + std_ostream_plate_init; +} + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace LinphoneImdn + { + ::std::ostream& + operator<< (::std::ostream& o, const ImdnReason& i) + { + o << static_cast< const ::LinphonePrivate::Xsd::XmlSchema::String& > (i); + + o << ::std::endl << "code: " << i.getCode (); + return o; + } + } + } +} + +#include +#include +#include + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace LinphoneImdn + { + ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > + parseReason (const ::std::string& u, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0, + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) == 0); + + ::xsd::cxx::tree::error_handler< char > h; + + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::xsd::cxx::xml::dom::parse< char > ( + u, h, p, f)); + + h.throw_if_failed< ::xsd::cxx::tree::parsing< char > > (); + + return ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > ( + ::LinphonePrivate::Xsd::LinphoneImdn::parseReason ( + std::move (d), f | ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom, p)); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > + parseReason (const ::std::string& u, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0, + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) == 0); + + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::xsd::cxx::xml::dom::parse< char > ( + u, h, p, f)); + + if (!d.get ()) + throw ::xsd::cxx::tree::parsing< char > (); + + return ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > ( + ::LinphonePrivate::Xsd::LinphoneImdn::parseReason ( + std::move (d), f | ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom, p)); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > + parseReason (const ::std::string& u, + ::xercesc::DOMErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::xsd::cxx::xml::dom::parse< char > ( + u, h, p, f)); + + if (!d.get ()) + throw ::xsd::cxx::tree::parsing< char > (); + + return ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > ( + ::LinphonePrivate::Xsd::LinphoneImdn::parseReason ( + std::move (d), f | ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom, p)); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > + parseReason (::std::istream& is, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0, + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) == 0); + + ::xsd::cxx::xml::sax::std_input_source isrc (is); + return ::LinphonePrivate::Xsd::LinphoneImdn::parseReason (isrc, f, p); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > + parseReason (::std::istream& is, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0, + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) == 0); + + ::xsd::cxx::xml::sax::std_input_source isrc (is); + return ::LinphonePrivate::Xsd::LinphoneImdn::parseReason (isrc, h, f, p); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > + parseReason (::std::istream& is, + ::xercesc::DOMErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::sax::std_input_source isrc (is); + return ::LinphonePrivate::Xsd::LinphoneImdn::parseReason (isrc, h, f, p); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > + parseReason (::std::istream& is, + const ::std::string& sid, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0, + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) == 0); + + ::xsd::cxx::xml::sax::std_input_source isrc (is, sid); + return ::LinphonePrivate::Xsd::LinphoneImdn::parseReason (isrc, f, p); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > + parseReason (::std::istream& is, + const ::std::string& sid, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0, + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) == 0); + + ::xsd::cxx::xml::sax::std_input_source isrc (is, sid); + return ::LinphonePrivate::Xsd::LinphoneImdn::parseReason (isrc, h, f, p); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > + parseReason (::std::istream& is, + const ::std::string& sid, + ::xercesc::DOMErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::sax::std_input_source isrc (is, sid); + return ::LinphonePrivate::Xsd::LinphoneImdn::parseReason (isrc, h, f, p); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > + parseReason (::xercesc::InputSource& i, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::tree::error_handler< char > h; + + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::xsd::cxx::xml::dom::parse< char > ( + i, h, p, f)); + + h.throw_if_failed< ::xsd::cxx::tree::parsing< char > > (); + + return ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > ( + ::LinphonePrivate::Xsd::LinphoneImdn::parseReason ( + std::move (d), f | ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom, p)); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > + parseReason (::xercesc::InputSource& i, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::xsd::cxx::xml::dom::parse< char > ( + i, h, p, f)); + + if (!d.get ()) + throw ::xsd::cxx::tree::parsing< char > (); + + return ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > ( + ::LinphonePrivate::Xsd::LinphoneImdn::parseReason ( + std::move (d), f | ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom, p)); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > + parseReason (::xercesc::InputSource& i, + ::xercesc::DOMErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::xsd::cxx::xml::dom::parse< char > ( + i, h, p, f)); + + if (!d.get ()) + throw ::xsd::cxx::tree::parsing< char > (); + + return ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > ( + ::LinphonePrivate::Xsd::LinphoneImdn::parseReason ( + std::move (d), f | ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom, p)); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > + parseReason (const ::xercesc::DOMDocument& doc, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + if (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + static_cast< ::xercesc::DOMDocument* > (doc.cloneNode (true))); + + return ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > ( + ::LinphonePrivate::Xsd::LinphoneImdn::parseReason ( + std::move (d), f | ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom, p)); + } + + const ::xercesc::DOMElement& e (*doc.getDocumentElement ()); + const ::xsd::cxx::xml::qualified_name< char > n ( + ::xsd::cxx::xml::dom::name< char > (e)); + + if (n.name () == "reason" && + n.namespace_ () == "http://www.linphone.org/xsds/imdn.xsd") + { + ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > r ( + ::xsd::cxx::tree::traits< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason, char >::create ( + e, f, 0)); + return r; + } + + throw ::xsd::cxx::tree::unexpected_element < char > ( + n.name (), + n.namespace_ (), + "reason", + "http://www.linphone.org/xsds/imdn.xsd"); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > + parseReason (::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties&) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > c ( + ((f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) && + !(f & ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom)) + ? static_cast< ::xercesc::DOMDocument* > (d->cloneNode (true)) + : 0); + + ::xercesc::DOMDocument& doc (c.get () ? *c : *d); + const ::xercesc::DOMElement& e (*doc.getDocumentElement ()); + + const ::xsd::cxx::xml::qualified_name< char > n ( + ::xsd::cxx::xml::dom::name< char > (e)); + + if (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) + doc.setUserData (::LinphonePrivate::Xsd::XmlSchema::dom::treeNodeKey, + (c.get () ? &c : &d), + 0); + + if (n.name () == "reason" && + n.namespace_ () == "http://www.linphone.org/xsds/imdn.xsd") + { + ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > r ( + ::xsd::cxx::tree::traits< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason, char >::create ( + e, f, 0)); + return r; + } + + throw ::xsd::cxx::tree::unexpected_element < char > ( + n.name (), + n.namespace_ (), + "reason", + "http://www.linphone.org/xsds/imdn.xsd"); + } + } + } +} + +#include +#include +#include + +#include + +namespace _xsd +{ + static + const ::xsd::cxx::tree::type_serializer_plate< 0, char > + type_serializer_plate_init; +} + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace LinphoneImdn + { + void + serializeReason (::std::ostream& o, + const ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason& s, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m, + const ::std::string& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0); + + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::LinphonePrivate::Xsd::LinphoneImdn::serializeReason (s, m, f)); + + ::xsd::cxx::tree::error_handler< char > h; + + ::xsd::cxx::xml::dom::ostream_format_target t (o); + if (!::xsd::cxx::xml::dom::serialize (t, *d, e, h, f)) + { + h.throw_if_failed< ::xsd::cxx::tree::serialization< char > > (); + } + } + + void + serializeReason (::std::ostream& o, + const ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason& s, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& h, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m, + const ::std::string& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0); + + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::LinphonePrivate::Xsd::LinphoneImdn::serializeReason (s, m, f)); + ::xsd::cxx::xml::dom::ostream_format_target t (o); + if (!::xsd::cxx::xml::dom::serialize (t, *d, e, h, f)) + { + throw ::xsd::cxx::tree::serialization< char > (); + } + } + + void + serializeReason (::std::ostream& o, + const ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason& s, + ::xercesc::DOMErrorHandler& h, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m, + const ::std::string& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::LinphonePrivate::Xsd::LinphoneImdn::serializeReason (s, m, f)); + ::xsd::cxx::xml::dom::ostream_format_target t (o); + if (!::xsd::cxx::xml::dom::serialize (t, *d, e, h, f)) + { + throw ::xsd::cxx::tree::serialization< char > (); + } + } + + void + serializeReason (::xercesc::XMLFormatTarget& t, + const ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason& s, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m, + const ::std::string& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::LinphonePrivate::Xsd::LinphoneImdn::serializeReason (s, m, f)); + + ::xsd::cxx::tree::error_handler< char > h; + + if (!::xsd::cxx::xml::dom::serialize (t, *d, e, h, f)) + { + h.throw_if_failed< ::xsd::cxx::tree::serialization< char > > (); + } + } + + void + serializeReason (::xercesc::XMLFormatTarget& t, + const ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason& s, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& h, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m, + const ::std::string& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::LinphonePrivate::Xsd::LinphoneImdn::serializeReason (s, m, f)); + if (!::xsd::cxx::xml::dom::serialize (t, *d, e, h, f)) + { + throw ::xsd::cxx::tree::serialization< char > (); + } + } + + void + serializeReason (::xercesc::XMLFormatTarget& t, + const ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason& s, + ::xercesc::DOMErrorHandler& h, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m, + const ::std::string& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::LinphonePrivate::Xsd::LinphoneImdn::serializeReason (s, m, f)); + if (!::xsd::cxx::xml::dom::serialize (t, *d, e, h, f)) + { + throw ::xsd::cxx::tree::serialization< char > (); + } + } + + void + serializeReason (::xercesc::DOMDocument& d, + const ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason& s, + ::LinphonePrivate::Xsd::XmlSchema::Flags) + { + ::xercesc::DOMElement& e (*d.getDocumentElement ()); + const ::xsd::cxx::xml::qualified_name< char > n ( + ::xsd::cxx::xml::dom::name< char > (e)); + + if (n.name () == "reason" && + n.namespace_ () == "http://www.linphone.org/xsds/imdn.xsd") + { + e << s; + } + else + { + throw ::xsd::cxx::tree::unexpected_element < char > ( + n.name (), + n.namespace_ (), + "reason", + "http://www.linphone.org/xsds/imdn.xsd"); + } + } + + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > + serializeReason (const ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason& s, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::xsd::cxx::xml::dom::serialize< char > ( + "reason", + "http://www.linphone.org/xsds/imdn.xsd", + m, f)); + + ::LinphonePrivate::Xsd::LinphoneImdn::serializeReason (*d, s, f); + return d; + } + + void + operator<< (::xercesc::DOMElement& e, const ImdnReason& i) + { + e << static_cast< const ::LinphonePrivate::Xsd::XmlSchema::String& > (i); + + // code + // + { + ::xercesc::DOMAttr& a ( + ::xsd::cxx::xml::dom::create_attribute ( + "code", + e)); + + a << i.getCode (); + } + } + } + } +} + +#include + +// Begin epilogue. +// +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif +#if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) + #pragma GCC diagnostic pop +#endif +#if __clang__ || __GNUC__ >= 4 + #pragma GCC diagnostic pop +#endif +// +// End epilogue. + diff --git a/src/xml/linphone-imdn.h b/src/xml/linphone-imdn.h new file mode 100644 index 000000000..ea7478f60 --- /dev/null +++ b/src/xml/linphone-imdn.h @@ -0,0 +1,601 @@ +// Copyright (c) 2005-2014 Code Synthesis Tools CC +// +// This program was generated by CodeSynthesis XSD, an XML Schema to +// C++ data binding compiler. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as +// published by the Free Software Foundation. +// +// 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 St, Fifth Floor, Boston, MA 02110-1301 USA +// +// In addition, as a special exception, Code Synthesis Tools CC gives +// permission to link this program with the Xerces-C++ library (or with +// modified versions of Xerces-C++ that use the same license as Xerces-C++), +// and distribute linked combinations including the two. You must obey +// the GNU General Public License version 2 in all respects for all of +// the code used other than Xerces-C++. If you modify this copy of the +// program, you may extend this exception to your version of the program, +// but you are not obligated to do so. If you do not wish to do so, delete +// this exception statement from your version. +// +// Furthermore, Code Synthesis Tools CC makes a special exception for +// the Free/Libre and Open Source Software (FLOSS) which is described +// in the accompanying FLOSSE file. +// + +#ifndef XML_LINPHONE_IMDN_H +#define XML_LINPHONE_IMDN_H + +#ifndef XSD_CXX11 +#define XSD_CXX11 +#endif + +#ifndef XSD_USE_CHAR +#define XSD_USE_CHAR +#endif + +#ifndef XSD_CXX_TREE_USE_CHAR +#define XSD_CXX_TREE_USE_CHAR +#endif + +// Begin prologue. +// +#if __clang__ || __GNUC__ >= 4 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wfloat-equal" + #pragma GCC diagnostic ignored "-Wsign-conversion" + #pragma GCC diagnostic ignored "-Wconversion" +#endif +#if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsuggest-override" +#endif +#if __GNUC__ >=7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" +#endif +// +// End prologue. + +#include + +#if (XSD_INT_VERSION != 4000000L) +#error XSD runtime version mismatch +#endif + +#include + +#include + +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace XmlSchema + { + // anyType and anySimpleType. + // + typedef ::xsd::cxx::tree::type Type; + typedef ::xsd::cxx::tree::simple_type< char, Type > SimpleType; + typedef ::xsd::cxx::tree::type Container; + + // 8-bit + // + typedef signed char Byte; + typedef unsigned char UnsignedByte; + + // 16-bit + // + typedef short Short; + typedef unsigned short UnsignedShort; + + // 32-bit + // + typedef int Int; + typedef unsigned int UnsignedInt; + + // 64-bit + // + typedef long long Long; + typedef unsigned long long UnsignedLong; + + // Supposed to be arbitrary-length integral types. + // + typedef long long Integer; + typedef long long NonPositiveInteger; + typedef unsigned long long NonNegativeInteger; + typedef unsigned long long PositiveInteger; + typedef long long NegativeInteger; + + // Boolean. + // + typedef bool Boolean; + + // Floating-point types. + // + typedef float Float; + typedef double Double; + typedef double Decimal; + + // String types. + // + typedef ::xsd::cxx::tree::string< char, SimpleType > String; + typedef ::xsd::cxx::tree::normalized_string< char, String > NormalizedString; + typedef ::xsd::cxx::tree::token< char, NormalizedString > Token; + typedef ::xsd::cxx::tree::name< char, Token > Name; + typedef ::xsd::cxx::tree::nmtoken< char, Token > Nmtoken; + typedef ::xsd::cxx::tree::nmtokens< char, SimpleType, Nmtoken > Nmtokens; + typedef ::xsd::cxx::tree::ncname< char, Name > Ncname; + typedef ::xsd::cxx::tree::language< char, Token > Language; + + // ID/IDREF. + // + typedef ::xsd::cxx::tree::id< char, Ncname > Id; + typedef ::xsd::cxx::tree::idref< char, Ncname, Type > Idref; + typedef ::xsd::cxx::tree::idrefs< char, SimpleType, Idref > Idrefs; + + // URI. + // + typedef ::xsd::cxx::tree::uri< char, SimpleType > Uri; + + // Qualified name. + // + typedef ::xsd::cxx::tree::qname< char, SimpleType, Uri, Ncname > Qname; + + // Binary. + // + typedef ::xsd::cxx::tree::buffer< char > Buffer; + typedef ::xsd::cxx::tree::base64_binary< char, SimpleType > Base64Binary; + typedef ::xsd::cxx::tree::hex_binary< char, SimpleType > HexBinary; + + // Date/time. + // + typedef ::xsd::cxx::tree::time_zone TimeZone; + typedef ::xsd::cxx::tree::date< char, SimpleType > Date; + typedef ::xsd::cxx::tree::date_time< char, SimpleType > DateTime; + typedef ::xsd::cxx::tree::duration< char, SimpleType > Duration; + typedef ::xsd::cxx::tree::gday< char, SimpleType > Gday; + typedef ::xsd::cxx::tree::gmonth< char, SimpleType > Gmonth; + typedef ::xsd::cxx::tree::gmonth_day< char, SimpleType > GmonthDay; + typedef ::xsd::cxx::tree::gyear< char, SimpleType > Gyear; + typedef ::xsd::cxx::tree::gyear_month< char, SimpleType > GyearMonth; + typedef ::xsd::cxx::tree::time< char, SimpleType > Time; + + // Entity. + // + typedef ::xsd::cxx::tree::entity< char, Ncname > Entity; + typedef ::xsd::cxx::tree::entities< char, SimpleType, Entity > Entities; + + typedef ::xsd::cxx::tree::content_order ContentOrder; + // Namespace information and list stream. Used in + // serialization functions. + // + typedef ::xsd::cxx::xml::dom::namespace_info< char > NamespaceInfo; + typedef ::xsd::cxx::xml::dom::namespace_infomap< char > NamespaceInfomap; + typedef ::xsd::cxx::tree::list_stream< char > ListStream; + typedef ::xsd::cxx::tree::as_double< Double > AsDouble; + typedef ::xsd::cxx::tree::as_decimal< Decimal > AsDecimal; + typedef ::xsd::cxx::tree::facet Facet; + + // Flags and properties. + // + typedef ::xsd::cxx::tree::flags Flags; + typedef ::xsd::cxx::tree::properties< char > Properties; + + // Parsing/serialization diagnostics. + // + typedef ::xsd::cxx::tree::severity Severity; + typedef ::xsd::cxx::tree::error< char > Error; + typedef ::xsd::cxx::tree::diagnostics< char > Diagnostics; + + // Exceptions. + // + typedef ::xsd::cxx::tree::exception< char > Exception; + typedef ::xsd::cxx::tree::bounds< char > Bounds; + typedef ::xsd::cxx::tree::duplicate_id< char > DuplicateId; + typedef ::xsd::cxx::tree::parsing< char > Parsing; + typedef ::xsd::cxx::tree::expected_element< char > ExpectedElement; + typedef ::xsd::cxx::tree::unexpected_element< char > UnexpectedElement; + typedef ::xsd::cxx::tree::expected_attribute< char > ExpectedAttribute; + typedef ::xsd::cxx::tree::unexpected_enumerator< char > UnexpectedEnumerator; + typedef ::xsd::cxx::tree::expected_text_content< char > ExpectedTextContent; + typedef ::xsd::cxx::tree::no_prefix_mapping< char > NoPrefixMapping; + typedef ::xsd::cxx::tree::no_type_info< char > NoTypeInfo; + typedef ::xsd::cxx::tree::not_derived< char > NotDerived; + typedef ::xsd::cxx::tree::serialization< char > Serialization; + + // Error handler callback interface. + // + typedef ::xsd::cxx::xml::error_handler< char > ErrorHandler; + + // DOM interaction. + // + namespace dom + { + // Automatic pointer for DOMDocument. + // + using ::xsd::cxx::xml::dom::unique_ptr; + +#ifndef XSD_CXX_TREE_TREE_NODE_KEY__LINPHONEPRIVATE__XSD__XMLSCHEMA +#define XSD_CXX_TREE_TREE_NODE_KEY__LINPHONEPRIVATE__XSD__XMLSCHEMA + // DOM user data key for back pointers to tree nodes. + // + const XMLCh* const treeNodeKey = ::xsd::cxx::tree::user_data_keys::node; +#endif + } + } + } +} + +// Forward declarations. +// +namespace LinphonePrivate +{ + namespace Xsd + { + namespace LinphoneImdn + { + class ImdnReason; + } + } +} + + +#include // ::std::unique_ptr +#include // std::numeric_limits +#include // std::binary_search +#include // std::move + +#include + +#include +#include +#include +#include + +#include + +#include + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace LinphoneImdn + { + class ImdnReason: public ::LinphonePrivate::Xsd::XmlSchema::String + { + public: + // code + // + typedef ::LinphonePrivate::Xsd::XmlSchema::Int CodeType; + typedef ::xsd::cxx::tree::traits< CodeType, char > CodeTraits; + + const CodeType& + getCode () const; + + CodeType& + getCode (); + + void + setCode (const CodeType& x); + + static CodeType + getCodeDefaultValue (); + + // Constructors. + // + ImdnReason (); + + ImdnReason (const char*); + + ImdnReason (const ::std::string&); + + ImdnReason (const ::LinphonePrivate::Xsd::XmlSchema::String&); + + ImdnReason (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + ImdnReason (const ImdnReason& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + virtual ImdnReason* + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0) const; + + ImdnReason& + operator= (const ImdnReason& x); + + virtual + ~ImdnReason (); + + // Implementation. + // + protected: + void + parse (::xsd::cxx::xml::dom::parser< char >&, + ::LinphonePrivate::Xsd::XmlSchema::Flags); + + protected: + ::xsd::cxx::tree::one< CodeType > code_; + }; + } + } +} + +#include + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace LinphoneImdn + { + ::std::ostream& + operator<< (::std::ostream&, const ImdnReason&); + } + } +} + +#include + +#include +#include +#include + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace LinphoneImdn + { + // Parse a URI or a local file. + // + + ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > + parseReason (const ::std::string& uri, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > + parseReason (const ::std::string& uri, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > + parseReason (const ::std::string& uri, + ::xercesc::DOMErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + // Parse std::istream. + // + + ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > + parseReason (::std::istream& is, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > + parseReason (::std::istream& is, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > + parseReason (::std::istream& is, + ::xercesc::DOMErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > + parseReason (::std::istream& is, + const ::std::string& id, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > + parseReason (::std::istream& is, + const ::std::string& id, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > + parseReason (::std::istream& is, + const ::std::string& id, + ::xercesc::DOMErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + // Parse xercesc::InputSource. + // + + ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > + parseReason (::xercesc::InputSource& is, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > + parseReason (::xercesc::InputSource& is, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > + parseReason (::xercesc::InputSource& is, + ::xercesc::DOMErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + // Parse xercesc::DOMDocument. + // + + ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > + parseReason (const ::xercesc::DOMDocument& d, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason > + parseReason (::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + } + } +} + +#include + +#include +#include +#include + +#include + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace LinphoneImdn + { + // Serialize to std::ostream. + // + + void + serializeReason (::std::ostream& os, + const ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason& x, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), + const ::std::string& e = "UTF-8", + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + void + serializeReason (::std::ostream& os, + const ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason& x, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& eh, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), + const ::std::string& e = "UTF-8", + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + void + serializeReason (::std::ostream& os, + const ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason& x, + ::xercesc::DOMErrorHandler& eh, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), + const ::std::string& e = "UTF-8", + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + // Serialize to xercesc::XMLFormatTarget. + // + + void + serializeReason (::xercesc::XMLFormatTarget& ft, + const ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason& x, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), + const ::std::string& e = "UTF-8", + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + void + serializeReason (::xercesc::XMLFormatTarget& ft, + const ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason& x, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& eh, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), + const ::std::string& e = "UTF-8", + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + void + serializeReason (::xercesc::XMLFormatTarget& ft, + const ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason& x, + ::xercesc::DOMErrorHandler& eh, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), + const ::std::string& e = "UTF-8", + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + // Serialize to an existing xercesc::DOMDocument. + // + + void + serializeReason (::xercesc::DOMDocument& d, + const ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + // Serialize to a new xercesc::DOMDocument. + // + + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > + serializeReason (const ::LinphonePrivate::Xsd::LinphoneImdn::ImdnReason& x, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + void + operator<< (::xercesc::DOMElement&, const ImdnReason&); + } + } +} + +#include + +// Begin epilogue. +// +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif +#if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) + #pragma GCC diagnostic pop +#endif +#if __clang__ || __GNUC__ >= 4 + #pragma GCC diagnostic pop +#endif +// +// End epilogue. + +#endif // XML_LINPHONE_IMDN_H diff --git a/src/xml/linphone-imdn.xsd b/src/xml/linphone-imdn.xsd new file mode 100644 index 000000000..6a6136a0d --- /dev/null +++ b/src/xml/linphone-imdn.xsd @@ -0,0 +1,15 @@ + + + + + + + + + + + + diff --git a/src/xml/prologue.txt b/src/xml/prologue.txt index f2a7bf6f0..2349b5d94 100644 --- a/src/xml/prologue.txt +++ b/src/xml/prologue.txt @@ -1,7 +1,14 @@ #if __clang__ || __GNUC__ >= 4 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wfloat-equal" -#ifndef __ANDROID__ + #pragma GCC diagnostic ignored "-Wsign-conversion" + #pragma GCC diagnostic ignored "-Wconversion" +#endif +#if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-override" #endif +#if __GNUC__ >=7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" #endif diff --git a/src/xml/resource-lists.cpp b/src/xml/resource-lists.cpp index 5d42e0137..d74589fde 100644 --- a/src/xml/resource-lists.cpp +++ b/src/xml/resource-lists.cpp @@ -36,9 +36,16 @@ #if __clang__ || __GNUC__ >= 4 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wfloat-equal" + #pragma GCC diagnostic ignored "-Wsign-conversion" + #pragma GCC diagnostic ignored "-Wconversion" +#endif #if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-override" #endif +#if __GNUC__ >=7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" #endif // // End prologue. @@ -54,7 +61,7 @@ namespace LinphonePrivate namespace ResourceLists { // ListType - // + // const ListType::DisplayNameOptional& ListType:: getDisplayName () const @@ -238,7 +245,7 @@ namespace LinphonePrivate // EntryType - // + // const EntryType::DisplayNameOptional& EntryType:: getDisplayName () const @@ -350,7 +357,7 @@ namespace LinphonePrivate // EntryRefType - // + // const EntryRefType::DisplayNameOptional& EntryRefType:: getDisplayName () const @@ -462,7 +469,7 @@ namespace LinphonePrivate // ExternalType - // + // const ExternalType::DisplayNameOptional& ExternalType:: getDisplayName () const @@ -574,7 +581,7 @@ namespace LinphonePrivate // DisplayNameType - // + // const DisplayNameType::LangOptional& DisplayNameType:: getLang () const @@ -608,15 +615,15 @@ namespace LinphonePrivate // List - // + // // DisplayName - // + // // ResourceLists - // + // const ResourceLists::ListSequence& ResourceLists:: getList () const @@ -643,6 +650,15 @@ namespace LinphonePrivate #include +#include + +namespace _xsd +{ + static + const ::xsd::cxx::tree::type_factory_plate< 0, char > + type_factory_plate_init; +} + namespace LinphonePrivate { namespace Xsd @@ -1558,6 +1574,15 @@ namespace LinphonePrivate #include +#include + +namespace _xsd +{ + static + const ::xsd::cxx::tree::std_ostream_plate< 0, char > + std_ostream_plate_init; +} + namespace LinphonePrivate { namespace Xsd @@ -1976,6 +2001,15 @@ namespace LinphonePrivate #include #include +#include + +namespace _xsd +{ + static + const ::xsd::cxx::tree::type_serializer_plate< 0, char > + type_serializer_plate_init; +} + namespace LinphonePrivate { namespace Xsd @@ -2483,8 +2517,15 @@ namespace LinphonePrivate // Begin epilogue. // +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif +#if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) + #pragma GCC diagnostic pop +#endif #if __clang__ || __GNUC__ >= 4 #pragma GCC diagnostic pop #endif // // End epilogue. + diff --git a/src/xml/resource-lists.h b/src/xml/resource-lists.h index 1062cfb31..b2384df98 100644 --- a/src/xml/resource-lists.h +++ b/src/xml/resource-lists.h @@ -51,9 +51,16 @@ #if __clang__ || __GNUC__ >= 4 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wfloat-equal" + #pragma GCC diagnostic ignored "-Wsign-conversion" + #pragma GCC diagnostic ignored "-Wconversion" +#endif #if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-override" #endif +#if __GNUC__ >=7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" #endif // // End prologue. @@ -240,6 +247,8 @@ namespace LinphonePrivate typedef ::xsd::cxx::tree::unexpected_enumerator< char > UnexpectedEnumerator; typedef ::xsd::cxx::tree::expected_text_content< char > ExpectedTextContent; typedef ::xsd::cxx::tree::no_prefix_mapping< char > NoPrefixMapping; + typedef ::xsd::cxx::tree::no_type_info< char > NoTypeInfo; + typedef ::xsd::cxx::tree::not_derived< char > NotDerived; typedef ::xsd::cxx::tree::serialization< char > Serialization; // Error handler callback interface. @@ -480,7 +489,7 @@ namespace LinphonePrivate ListType& operator= (const ListType& x); - virtual + virtual ~ListType (); // Implementation. @@ -604,7 +613,7 @@ namespace LinphonePrivate EntryType& operator= (const EntryType& x); - virtual + virtual ~EntryType (); // Implementation. @@ -724,7 +733,7 @@ namespace LinphonePrivate EntryRefType& operator= (const EntryRefType& x); - virtual + virtual ~EntryRefType (); // Implementation. @@ -845,7 +854,7 @@ namespace LinphonePrivate ExternalType& operator= (const ExternalType& x); - virtual + virtual ~ExternalType (); // Implementation. @@ -913,7 +922,7 @@ namespace LinphonePrivate DisplayNameType& operator= (const DisplayNameType& x); - virtual + virtual ~DisplayNameType (); // Implementation. @@ -946,7 +955,7 @@ namespace LinphonePrivate _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0) const; - virtual + virtual ~List (); }; @@ -975,7 +984,7 @@ namespace LinphonePrivate _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0) const; - virtual + virtual ~DisplayName (); }; @@ -1018,7 +1027,7 @@ namespace LinphonePrivate ResourceLists& operator= (const ResourceLists& x); - virtual + virtual ~ResourceLists (); // Implementation. @@ -1209,14 +1218,14 @@ namespace LinphonePrivate void serializeResourceLists (::std::ostream& os, - const ::LinphonePrivate::Xsd::ResourceLists::ResourceLists& x, + const ::LinphonePrivate::Xsd::ResourceLists::ResourceLists& x, const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), const ::std::string& e = "UTF-8", ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); void serializeResourceLists (::std::ostream& os, - const ::LinphonePrivate::Xsd::ResourceLists::ResourceLists& x, + const ::LinphonePrivate::Xsd::ResourceLists::ResourceLists& x, ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& eh, const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), const ::std::string& e = "UTF-8", @@ -1224,7 +1233,7 @@ namespace LinphonePrivate void serializeResourceLists (::std::ostream& os, - const ::LinphonePrivate::Xsd::ResourceLists::ResourceLists& x, + const ::LinphonePrivate::Xsd::ResourceLists::ResourceLists& x, ::xercesc::DOMErrorHandler& eh, const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), const ::std::string& e = "UTF-8", @@ -1235,14 +1244,14 @@ namespace LinphonePrivate void serializeResourceLists (::xercesc::XMLFormatTarget& ft, - const ::LinphonePrivate::Xsd::ResourceLists::ResourceLists& x, + const ::LinphonePrivate::Xsd::ResourceLists::ResourceLists& x, const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), const ::std::string& e = "UTF-8", ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); void serializeResourceLists (::xercesc::XMLFormatTarget& ft, - const ::LinphonePrivate::Xsd::ResourceLists::ResourceLists& x, + const ::LinphonePrivate::Xsd::ResourceLists::ResourceLists& x, ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& eh, const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), const ::std::string& e = "UTF-8", @@ -1250,7 +1259,7 @@ namespace LinphonePrivate void serializeResourceLists (::xercesc::XMLFormatTarget& ft, - const ::LinphonePrivate::Xsd::ResourceLists::ResourceLists& x, + const ::LinphonePrivate::Xsd::ResourceLists::ResourceLists& x, ::xercesc::DOMErrorHandler& eh, const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), const ::std::string& e = "UTF-8", @@ -1268,7 +1277,7 @@ namespace LinphonePrivate // ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > - serializeResourceLists (const ::LinphonePrivate::Xsd::ResourceLists::ResourceLists& x, + serializeResourceLists (const ::LinphonePrivate::Xsd::ResourceLists::ResourceLists& x, const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); @@ -1291,6 +1300,12 @@ namespace LinphonePrivate // Begin epilogue. // +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif +#if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) + #pragma GCC diagnostic pop +#endif #if __clang__ || __GNUC__ >= 4 #pragma GCC diagnostic pop #endif diff --git a/src/xml/rlmi.cpp b/src/xml/rlmi.cpp new file mode 100644 index 000000000..eb0541331 --- /dev/null +++ b/src/xml/rlmi.cpp @@ -0,0 +1,2121 @@ +// Copyright (c) 2005-2014 Code Synthesis Tools CC +// +// This program was generated by CodeSynthesis XSD, an XML Schema to +// C++ data binding compiler. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as +// published by the Free Software Foundation. +// +// 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 St, Fifth Floor, Boston, MA 02110-1301 USA +// +// In addition, as a special exception, Code Synthesis Tools CC gives +// permission to link this program with the Xerces-C++ library (or with +// modified versions of Xerces-C++ that use the same license as Xerces-C++), +// and distribute linked combinations including the two. You must obey +// the GNU General Public License version 2 in all respects for all of +// the code used other than Xerces-C++. If you modify this copy of the +// program, you may extend this exception to your version of the program, +// but you are not obligated to do so. If you do not wish to do so, delete +// this exception statement from your version. +// +// Furthermore, Code Synthesis Tools CC makes a special exception for +// the Free/Libre and Open Source Software (FLOSS) which is described +// in the accompanying FLOSSE file. +// + +// Begin prologue. +// +#if __clang__ || __GNUC__ >= 4 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wfloat-equal" + #pragma GCC diagnostic ignored "-Wsign-conversion" + #pragma GCC diagnostic ignored "-Wconversion" +#endif +#if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsuggest-override" +#endif +#if __GNUC__ >=7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" +#endif +// +// End prologue. + +#include + +#include "rlmi.h" + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace Rlmi + { + // List + // + + const List::NameSequence& List:: + getName () const + { + return this->name_; + } + + List::NameSequence& List:: + getName () + { + return this->name_; + } + + void List:: + setName (const NameSequence& s) + { + this->name_ = s; + } + + const List::ResourceSequence& List:: + getResource () const + { + return this->resource_; + } + + List::ResourceSequence& List:: + getResource () + { + return this->resource_; + } + + void List:: + setResource (const ResourceSequence& s) + { + this->resource_ = s; + } + + const List::UriType& List:: + getUri () const + { + return this->uri_.get (); + } + + List::UriType& List:: + getUri () + { + return this->uri_.get (); + } + + void List:: + setUri (const UriType& x) + { + this->uri_.set (x); + } + + void List:: + setUri (::std::unique_ptr< UriType > x) + { + this->uri_.set (std::move (x)); + } + + ::std::unique_ptr< List::UriType > List:: + setDetachUri () + { + return this->uri_.detach (); + } + + const List::VersionType& List:: + getVersion () const + { + return this->version_.get (); + } + + List::VersionType& List:: + getVersion () + { + return this->version_.get (); + } + + void List:: + setVersion (const VersionType& x) + { + this->version_.set (x); + } + + const List::FullStateType& List:: + getFullState () const + { + return this->fullState_.get (); + } + + List::FullStateType& List:: + getFullState () + { + return this->fullState_.get (); + } + + void List:: + setFullState (const FullStateType& x) + { + this->fullState_.set (x); + } + + const List::CidOptional& List:: + getCid () const + { + return this->cid_; + } + + List::CidOptional& List:: + getCid () + { + return this->cid_; + } + + void List:: + setCid (const CidType& x) + { + this->cid_.set (x); + } + + void List:: + setCid (const CidOptional& x) + { + this->cid_ = x; + } + + void List:: + setCid (::std::unique_ptr< CidType > x) + { + this->cid_.set (std::move (x)); + } + + const List::AnyAttributeSet& List:: + getAnyAttribute () const + { + return this->any_attribute_; + } + + List::AnyAttributeSet& List:: + getAnyAttribute () + { + return this->any_attribute_; + } + + void List:: + setAnyAttribute (const AnyAttributeSet& s) + { + this->any_attribute_ = s; + } + + const ::xercesc::DOMDocument& List:: + getDomDocument () const + { + return *this->dom_document_; + } + + ::xercesc::DOMDocument& List:: + getDomDocument () + { + return *this->dom_document_; + } + + + // Resource + // + + const Resource::NameSequence& Resource:: + getName () const + { + return this->name_; + } + + Resource::NameSequence& Resource:: + getName () + { + return this->name_; + } + + void Resource:: + setName (const NameSequence& s) + { + this->name_ = s; + } + + const Resource::InstanceSequence& Resource:: + getInstance () const + { + return this->instance_; + } + + Resource::InstanceSequence& Resource:: + getInstance () + { + return this->instance_; + } + + void Resource:: + setInstance (const InstanceSequence& s) + { + this->instance_ = s; + } + + const Resource::UriType& Resource:: + getUri () const + { + return this->uri_.get (); + } + + Resource::UriType& Resource:: + getUri () + { + return this->uri_.get (); + } + + void Resource:: + setUri (const UriType& x) + { + this->uri_.set (x); + } + + void Resource:: + setUri (::std::unique_ptr< UriType > x) + { + this->uri_.set (std::move (x)); + } + + ::std::unique_ptr< Resource::UriType > Resource:: + setDetachUri () + { + return this->uri_.detach (); + } + + const Resource::AnyAttributeSet& Resource:: + getAnyAttribute () const + { + return this->any_attribute_; + } + + Resource::AnyAttributeSet& Resource:: + getAnyAttribute () + { + return this->any_attribute_; + } + + void Resource:: + setAnyAttribute (const AnyAttributeSet& s) + { + this->any_attribute_ = s; + } + + const ::xercesc::DOMDocument& Resource:: + getDomDocument () const + { + return *this->dom_document_; + } + + ::xercesc::DOMDocument& Resource:: + getDomDocument () + { + return *this->dom_document_; + } + + + // Instance + // + + const Instance::AnySequence& Instance:: + getAny () const + { + return this->any_; + } + + Instance::AnySequence& Instance:: + getAny () + { + return this->any_; + } + + void Instance:: + setAny (const AnySequence& s) + { + this->any_ = s; + } + + const Instance::IdType& Instance:: + getId () const + { + return this->id_.get (); + } + + Instance::IdType& Instance:: + getId () + { + return this->id_.get (); + } + + void Instance:: + setId (const IdType& x) + { + this->id_.set (x); + } + + void Instance:: + setId (::std::unique_ptr< IdType > x) + { + this->id_.set (std::move (x)); + } + + ::std::unique_ptr< Instance::IdType > Instance:: + setDetachId () + { + return this->id_.detach (); + } + + const Instance::StateType& Instance:: + getState () const + { + return this->state_.get (); + } + + Instance::StateType& Instance:: + getState () + { + return this->state_.get (); + } + + void Instance:: + setState (const StateType& x) + { + this->state_.set (x); + } + + void Instance:: + setState (::std::unique_ptr< StateType > x) + { + this->state_.set (std::move (x)); + } + + ::std::unique_ptr< Instance::StateType > Instance:: + setDetachState () + { + return this->state_.detach (); + } + + const Instance::ReasonOptional& Instance:: + getReason () const + { + return this->reason_; + } + + Instance::ReasonOptional& Instance:: + getReason () + { + return this->reason_; + } + + void Instance:: + setReason (const ReasonType& x) + { + this->reason_.set (x); + } + + void Instance:: + setReason (const ReasonOptional& x) + { + this->reason_ = x; + } + + void Instance:: + setReason (::std::unique_ptr< ReasonType > x) + { + this->reason_.set (std::move (x)); + } + + const Instance::CidOptional& Instance:: + getCid () const + { + return this->cid_; + } + + Instance::CidOptional& Instance:: + getCid () + { + return this->cid_; + } + + void Instance:: + setCid (const CidType& x) + { + this->cid_.set (x); + } + + void Instance:: + setCid (const CidOptional& x) + { + this->cid_ = x; + } + + void Instance:: + setCid (::std::unique_ptr< CidType > x) + { + this->cid_.set (std::move (x)); + } + + const Instance::AnyAttributeSet& Instance:: + getAnyAttribute () const + { + return this->any_attribute_; + } + + Instance::AnyAttributeSet& Instance:: + getAnyAttribute () + { + return this->any_attribute_; + } + + void Instance:: + setAnyAttribute (const AnyAttributeSet& s) + { + this->any_attribute_ = s; + } + + const ::xercesc::DOMDocument& Instance:: + getDomDocument () const + { + return *this->dom_document_; + } + + ::xercesc::DOMDocument& Instance:: + getDomDocument () + { + return *this->dom_document_; + } + + + // Name + // + + const Name::LangOptional& Name:: + getLang () const + { + return this->lang_; + } + + Name::LangOptional& Name:: + getLang () + { + return this->lang_; + } + + void Name:: + setLang (const LangType& x) + { + this->lang_.set (x); + } + + void Name:: + setLang (const LangOptional& x) + { + this->lang_ = x; + } + + void Name:: + setLang (::std::unique_ptr< LangType > x) + { + this->lang_.set (std::move (x)); + } + + + // State + // + + State:: + State (Value v) + : ::LinphonePrivate::Xsd::XmlSchema::String (_xsd_State_literals_[v]) + { + } + + State:: + State (const char* v) + : ::LinphonePrivate::Xsd::XmlSchema::String (v) + { + } + + State:: + State (const ::std::string& v) + : ::LinphonePrivate::Xsd::XmlSchema::String (v) + { + } + + State:: + State (const ::LinphonePrivate::Xsd::XmlSchema::String& v) + : ::LinphonePrivate::Xsd::XmlSchema::String (v) + { + } + + State:: + State (const State& v, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::String (v, f, c) + { + } + + State& State:: + operator= (Value v) + { + static_cast< ::LinphonePrivate::Xsd::XmlSchema::String& > (*this) = + ::LinphonePrivate::Xsd::XmlSchema::String (_xsd_State_literals_[v]); + + return *this; + } + } + } +} + +#include + +#include + +#include + +namespace _xsd +{ + static + const ::xsd::cxx::tree::type_factory_plate< 0, char > + type_factory_plate_init; +} + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace Rlmi + { + // List + // + + List:: + List (const UriType& uri, + const VersionType& version, + const FullStateType& fullState) + : ::LinphonePrivate::Xsd::XmlSchema::Type (), + dom_document_ (::xsd::cxx::xml::dom::create_document< char > ()), + name_ (this), + resource_ (this), + uri_ (uri, this), + version_ (version, this), + fullState_ (fullState, this), + cid_ (this), + any_attribute_ (this->getDomDocument ()) + { + } + + List:: + List (const List& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (x, f, c), + dom_document_ (::xsd::cxx::xml::dom::create_document< char > ()), + name_ (x.name_, f, this), + resource_ (x.resource_, f, this), + uri_ (x.uri_, f, this), + version_ (x.version_, f, this), + fullState_ (x.fullState_, f, this), + cid_ (x.cid_, f, this), + any_attribute_ (x.any_attribute_, this->getDomDocument ()) + { + } + + List:: + List (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (e, f | ::LinphonePrivate::Xsd::XmlSchema::Flags::base, c), + dom_document_ (::xsd::cxx::xml::dom::create_document< char > ()), + name_ (this), + resource_ (this), + uri_ (this), + version_ (this), + fullState_ (this), + cid_ (this), + any_attribute_ (this->getDomDocument ()) + { + if ((f & ::LinphonePrivate::Xsd::XmlSchema::Flags::base) == 0) + { + ::xsd::cxx::xml::dom::parser< char > p (e, true, false, true); + this->parse (p, f); + } + } + + void List:: + parse (::xsd::cxx::xml::dom::parser< char >& p, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + for (; p.more_content (); p.next_content (false)) + { + const ::xercesc::DOMElement& i (p.cur_element ()); + const ::xsd::cxx::xml::qualified_name< char > n ( + ::xsd::cxx::xml::dom::name< char > (i)); + + // name + // + if (n.name () == "name" && n.namespace_ () == "urn:ietf:params:xml:ns:rlmi") + { + ::std::unique_ptr< NameType > r ( + NameTraits::create (i, f, this)); + + this->name_.push_back (::std::move (r)); + continue; + } + + // resource + // + if (n.name () == "resource" && n.namespace_ () == "urn:ietf:params:xml:ns:rlmi") + { + ::std::unique_ptr< ResourceType > r ( + ResourceTraits::create (i, f, this)); + + this->resource_.push_back (::std::move (r)); + continue; + } + + break; + } + + while (p.more_attributes ()) + { + const ::xercesc::DOMAttr& i (p.next_attribute ()); + const ::xsd::cxx::xml::qualified_name< char > n ( + ::xsd::cxx::xml::dom::name< char > (i)); + + if (n.name () == "uri" && n.namespace_ ().empty ()) + { + this->uri_.set (UriTraits::create (i, f, this)); + continue; + } + + if (n.name () == "version" && n.namespace_ ().empty ()) + { + this->version_.set (VersionTraits::create (i, f, this)); + continue; + } + + if (n.name () == "fullState" && n.namespace_ ().empty ()) + { + this->fullState_.set (FullStateTraits::create (i, f, this)); + continue; + } + + if (n.name () == "cid" && n.namespace_ ().empty ()) + { + this->cid_.set (CidTraits::create (i, f, this)); + continue; + } + + // any_attribute + // + if ((n.namespace_ () != ::xsd::cxx::xml::bits::xmlns_namespace< char > () && + n.namespace_ () != ::xsd::cxx::xml::bits::xsi_namespace< char > ())) + { + ::xercesc::DOMAttr* r ( + static_cast< ::xercesc::DOMAttr* > ( + this->getDomDocument ().importNode ( + const_cast< ::xercesc::DOMAttr* > (&i), true))); + this->any_attribute_ .insert (r); + continue; + } + } + + if (!uri_.present ()) + { + throw ::xsd::cxx::tree::expected_attribute< char > ( + "uri", + ""); + } + + if (!version_.present ()) + { + throw ::xsd::cxx::tree::expected_attribute< char > ( + "version", + ""); + } + + if (!fullState_.present ()) + { + throw ::xsd::cxx::tree::expected_attribute< char > ( + "fullState", + ""); + } + } + + List* List:: + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) const + { + return new class List (*this, f, c); + } + + List& List:: + operator= (const List& x) + { + if (this != &x) + { + static_cast< ::LinphonePrivate::Xsd::XmlSchema::Type& > (*this) = x; + this->name_ = x.name_; + this->resource_ = x.resource_; + this->uri_ = x.uri_; + this->version_ = x.version_; + this->fullState_ = x.fullState_; + this->cid_ = x.cid_; + this->any_attribute_ = x.any_attribute_; + } + + return *this; + } + + List:: + ~List () + { + } + + // Resource + // + + Resource:: + Resource (const UriType& uri) + : ::LinphonePrivate::Xsd::XmlSchema::Type (), + dom_document_ (::xsd::cxx::xml::dom::create_document< char > ()), + name_ (this), + instance_ (this), + uri_ (uri, this), + any_attribute_ (this->getDomDocument ()) + { + } + + Resource:: + Resource (const Resource& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (x, f, c), + dom_document_ (::xsd::cxx::xml::dom::create_document< char > ()), + name_ (x.name_, f, this), + instance_ (x.instance_, f, this), + uri_ (x.uri_, f, this), + any_attribute_ (x.any_attribute_, this->getDomDocument ()) + { + } + + Resource:: + Resource (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (e, f | ::LinphonePrivate::Xsd::XmlSchema::Flags::base, c), + dom_document_ (::xsd::cxx::xml::dom::create_document< char > ()), + name_ (this), + instance_ (this), + uri_ (this), + any_attribute_ (this->getDomDocument ()) + { + if ((f & ::LinphonePrivate::Xsd::XmlSchema::Flags::base) == 0) + { + ::xsd::cxx::xml::dom::parser< char > p (e, true, false, true); + this->parse (p, f); + } + } + + void Resource:: + parse (::xsd::cxx::xml::dom::parser< char >& p, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + for (; p.more_content (); p.next_content (false)) + { + const ::xercesc::DOMElement& i (p.cur_element ()); + const ::xsd::cxx::xml::qualified_name< char > n ( + ::xsd::cxx::xml::dom::name< char > (i)); + + // name + // + if (n.name () == "name" && n.namespace_ () == "urn:ietf:params:xml:ns:rlmi") + { + ::std::unique_ptr< NameType > r ( + NameTraits::create (i, f, this)); + + this->name_.push_back (::std::move (r)); + continue; + } + + // instance + // + if (n.name () == "instance" && n.namespace_ () == "urn:ietf:params:xml:ns:rlmi") + { + ::std::unique_ptr< InstanceType > r ( + InstanceTraits::create (i, f, this)); + + this->instance_.push_back (::std::move (r)); + continue; + } + + break; + } + + while (p.more_attributes ()) + { + const ::xercesc::DOMAttr& i (p.next_attribute ()); + const ::xsd::cxx::xml::qualified_name< char > n ( + ::xsd::cxx::xml::dom::name< char > (i)); + + if (n.name () == "uri" && n.namespace_ ().empty ()) + { + this->uri_.set (UriTraits::create (i, f, this)); + continue; + } + + // any_attribute + // + if ((n.namespace_ () != ::xsd::cxx::xml::bits::xmlns_namespace< char > () && + n.namespace_ () != ::xsd::cxx::xml::bits::xsi_namespace< char > ())) + { + ::xercesc::DOMAttr* r ( + static_cast< ::xercesc::DOMAttr* > ( + this->getDomDocument ().importNode ( + const_cast< ::xercesc::DOMAttr* > (&i), true))); + this->any_attribute_ .insert (r); + continue; + } + } + + if (!uri_.present ()) + { + throw ::xsd::cxx::tree::expected_attribute< char > ( + "uri", + ""); + } + } + + Resource* Resource:: + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) const + { + return new class Resource (*this, f, c); + } + + Resource& Resource:: + operator= (const Resource& x) + { + if (this != &x) + { + static_cast< ::LinphonePrivate::Xsd::XmlSchema::Type& > (*this) = x; + this->name_ = x.name_; + this->instance_ = x.instance_; + this->uri_ = x.uri_; + this->any_attribute_ = x.any_attribute_; + } + + return *this; + } + + Resource:: + ~Resource () + { + } + + // Instance + // + + Instance:: + Instance (const IdType& id, + const StateType& state) + : ::LinphonePrivate::Xsd::XmlSchema::Type (), + dom_document_ (::xsd::cxx::xml::dom::create_document< char > ()), + any_ (this->getDomDocument ()), + id_ (id, this), + state_ (state, this), + reason_ (this), + cid_ (this), + any_attribute_ (this->getDomDocument ()) + { + } + + Instance:: + Instance (const Instance& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (x, f, c), + dom_document_ (::xsd::cxx::xml::dom::create_document< char > ()), + any_ (x.any_, this->getDomDocument ()), + id_ (x.id_, f, this), + state_ (x.state_, f, this), + reason_ (x.reason_, f, this), + cid_ (x.cid_, f, this), + any_attribute_ (x.any_attribute_, this->getDomDocument ()) + { + } + + Instance:: + Instance (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::Type (e, f | ::LinphonePrivate::Xsd::XmlSchema::Flags::base, c), + dom_document_ (::xsd::cxx::xml::dom::create_document< char > ()), + any_ (this->getDomDocument ()), + id_ (this), + state_ (this), + reason_ (this), + cid_ (this), + any_attribute_ (this->getDomDocument ()) + { + if ((f & ::LinphonePrivate::Xsd::XmlSchema::Flags::base) == 0) + { + ::xsd::cxx::xml::dom::parser< char > p (e, true, false, true); + this->parse (p, f); + } + } + + void Instance:: + parse (::xsd::cxx::xml::dom::parser< char >& p, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + for (; p.more_content (); p.next_content (false)) + { + const ::xercesc::DOMElement& i (p.cur_element ()); + const ::xsd::cxx::xml::qualified_name< char > n ( + ::xsd::cxx::xml::dom::name< char > (i)); + + // any + // + if (true) + { + ::xercesc::DOMElement* r ( + static_cast< ::xercesc::DOMElement* > ( + this->getDomDocument ().importNode ( + const_cast< ::xercesc::DOMElement* > (&i), true))); + this->any_.push_back (r); + continue; + } + + break; + } + + while (p.more_attributes ()) + { + const ::xercesc::DOMAttr& i (p.next_attribute ()); + const ::xsd::cxx::xml::qualified_name< char > n ( + ::xsd::cxx::xml::dom::name< char > (i)); + + if (n.name () == "id" && n.namespace_ ().empty ()) + { + this->id_.set (IdTraits::create (i, f, this)); + continue; + } + + if (n.name () == "state" && n.namespace_ ().empty ()) + { + this->state_.set (StateTraits::create (i, f, this)); + continue; + } + + if (n.name () == "reason" && n.namespace_ ().empty ()) + { + this->reason_.set (ReasonTraits::create (i, f, this)); + continue; + } + + if (n.name () == "cid" && n.namespace_ ().empty ()) + { + this->cid_.set (CidTraits::create (i, f, this)); + continue; + } + + // any_attribute + // + if ((n.namespace_ () != ::xsd::cxx::xml::bits::xmlns_namespace< char > () && + n.namespace_ () != ::xsd::cxx::xml::bits::xsi_namespace< char > ())) + { + ::xercesc::DOMAttr* r ( + static_cast< ::xercesc::DOMAttr* > ( + this->getDomDocument ().importNode ( + const_cast< ::xercesc::DOMAttr* > (&i), true))); + this->any_attribute_ .insert (r); + continue; + } + } + + if (!id_.present ()) + { + throw ::xsd::cxx::tree::expected_attribute< char > ( + "id", + ""); + } + + if (!state_.present ()) + { + throw ::xsd::cxx::tree::expected_attribute< char > ( + "state", + ""); + } + } + + Instance* Instance:: + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) const + { + return new class Instance (*this, f, c); + } + + Instance& Instance:: + operator= (const Instance& x) + { + if (this != &x) + { + static_cast< ::LinphonePrivate::Xsd::XmlSchema::Type& > (*this) = x; + this->any_ = x.any_; + this->id_ = x.id_; + this->state_ = x.state_; + this->reason_ = x.reason_; + this->cid_ = x.cid_; + this->any_attribute_ = x.any_attribute_; + } + + return *this; + } + + Instance:: + ~Instance () + { + } + + // Name + // + + Name:: + Name () + : ::LinphonePrivate::Xsd::XmlSchema::String (), + lang_ (this) + { + } + + Name:: + Name (const char* _xsd_String_base) + : ::LinphonePrivate::Xsd::XmlSchema::String (_xsd_String_base), + lang_ (this) + { + } + + Name:: + Name (const ::std::string& _xsd_String_base) + : ::LinphonePrivate::Xsd::XmlSchema::String (_xsd_String_base), + lang_ (this) + { + } + + Name:: + Name (const ::LinphonePrivate::Xsd::XmlSchema::String& _xsd_String_base) + : ::LinphonePrivate::Xsd::XmlSchema::String (_xsd_String_base), + lang_ (this) + { + } + + Name:: + Name (const Name& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::String (x, f, c), + lang_ (x.lang_, f, this) + { + } + + Name:: + Name (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::String (e, f | ::LinphonePrivate::Xsd::XmlSchema::Flags::base, c), + lang_ (this) + { + if ((f & ::LinphonePrivate::Xsd::XmlSchema::Flags::base) == 0) + { + ::xsd::cxx::xml::dom::parser< char > p (e, false, false, true); + this->parse (p, f); + } + } + + void Name:: + parse (::xsd::cxx::xml::dom::parser< char >& p, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + while (p.more_attributes ()) + { + const ::xercesc::DOMAttr& i (p.next_attribute ()); + const ::xsd::cxx::xml::qualified_name< char > n ( + ::xsd::cxx::xml::dom::name< char > (i)); + + if (n.name () == "lang" && n.namespace_ () == "http://www.w3.org/XML/1998/namespace") + { + this->lang_.set (LangTraits::create (i, f, this)); + continue; + } + } + } + + Name* Name:: + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) const + { + return new class Name (*this, f, c); + } + + Name& Name:: + operator= (const Name& x) + { + if (this != &x) + { + static_cast< ::LinphonePrivate::Xsd::XmlSchema::String& > (*this) = x; + this->lang_ = x.lang_; + } + + return *this; + } + + Name:: + ~Name () + { + } + + // State + // + + State:: + State (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::String (e, f, c) + { + _xsd_State_convert (); + } + + State:: + State (const ::xercesc::DOMAttr& a, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::String (a, f, c) + { + _xsd_State_convert (); + } + + State:: + State (const ::std::string& s, + const ::xercesc::DOMElement* e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) + : ::LinphonePrivate::Xsd::XmlSchema::String (s, e, f, c) + { + _xsd_State_convert (); + } + + State* State:: + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f, + ::LinphonePrivate::Xsd::XmlSchema::Container* c) const + { + return new class State (*this, f, c); + } + + State::Value State:: + _xsd_State_convert () const + { + ::xsd::cxx::tree::enum_comparator< char > c (_xsd_State_literals_); + const Value* i (::std::lower_bound ( + _xsd_State_indexes_, + _xsd_State_indexes_ + 3, + *this, + c)); + + if (i == _xsd_State_indexes_ + 3 || _xsd_State_literals_[*i] != *this) + { + throw ::xsd::cxx::tree::unexpected_enumerator < char > (*this); + } + + return *i; + } + + const char* const State:: + _xsd_State_literals_[3] = + { + "active", + "pending", + "terminated" + }; + + const State::Value State:: + _xsd_State_indexes_[3] = + { + ::LinphonePrivate::Xsd::Rlmi::State::active, + ::LinphonePrivate::Xsd::Rlmi::State::pending, + ::LinphonePrivate::Xsd::Rlmi::State::terminated + }; + } + } +} + +#include + +#include + +namespace _xsd +{ + static + const ::xsd::cxx::tree::std_ostream_plate< 0, char > + std_ostream_plate_init; +} + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace Rlmi + { + ::std::ostream& + operator<< (::std::ostream& o, const List& i) + { + for (List::NameConstIterator + b (i.getName ().begin ()), e (i.getName ().end ()); + b != e; ++b) + { + o << ::std::endl << "name: " << *b; + } + + for (List::ResourceConstIterator + b (i.getResource ().begin ()), e (i.getResource ().end ()); + b != e; ++b) + { + o << ::std::endl << "resource: " << *b; + } + + o << ::std::endl << "uri: " << i.getUri (); + o << ::std::endl << "version: " << i.getVersion (); + o << ::std::endl << "fullState: " << i.getFullState (); + if (i.getCid ()) + { + o << ::std::endl << "cid: " << *i.getCid (); + } + + return o; + } + + ::std::ostream& + operator<< (::std::ostream& o, const Resource& i) + { + for (Resource::NameConstIterator + b (i.getName ().begin ()), e (i.getName ().end ()); + b != e; ++b) + { + o << ::std::endl << "name: " << *b; + } + + for (Resource::InstanceConstIterator + b (i.getInstance ().begin ()), e (i.getInstance ().end ()); + b != e; ++b) + { + o << ::std::endl << "instance: " << *b; + } + + o << ::std::endl << "uri: " << i.getUri (); + return o; + } + + ::std::ostream& + operator<< (::std::ostream& o, const Instance& i) + { + o << ::std::endl << "id: " << i.getId (); + o << ::std::endl << "state: " << i.getState (); + if (i.getReason ()) + { + o << ::std::endl << "reason: " << *i.getReason (); + } + + if (i.getCid ()) + { + o << ::std::endl << "cid: " << *i.getCid (); + } + + return o; + } + + ::std::ostream& + operator<< (::std::ostream& o, const Name& i) + { + o << static_cast< const ::LinphonePrivate::Xsd::XmlSchema::String& > (i); + + if (i.getLang ()) + { + o << ::std::endl << "lang: " << *i.getLang (); + } + + return o; + } + + ::std::ostream& + operator<< (::std::ostream& o, State::Value i) + { + return o << State::_xsd_State_literals_[i]; + } + + ::std::ostream& + operator<< (::std::ostream& o, const State& i) + { + return o << static_cast< const ::LinphonePrivate::Xsd::XmlSchema::String& > (i); + } + } + } +} + +#include +#include +#include + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace Rlmi + { + ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > + parseList (const ::std::string& u, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0, + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) == 0); + + ::xsd::cxx::tree::error_handler< char > h; + + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::xsd::cxx::xml::dom::parse< char > ( + u, h, p, f)); + + h.throw_if_failed< ::xsd::cxx::tree::parsing< char > > (); + + return ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > ( + ::LinphonePrivate::Xsd::Rlmi::parseList ( + std::move (d), f | ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom, p)); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > + parseList (const ::std::string& u, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0, + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) == 0); + + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::xsd::cxx::xml::dom::parse< char > ( + u, h, p, f)); + + if (!d.get ()) + throw ::xsd::cxx::tree::parsing< char > (); + + return ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > ( + ::LinphonePrivate::Xsd::Rlmi::parseList ( + std::move (d), f | ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom, p)); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > + parseList (const ::std::string& u, + ::xercesc::DOMErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::xsd::cxx::xml::dom::parse< char > ( + u, h, p, f)); + + if (!d.get ()) + throw ::xsd::cxx::tree::parsing< char > (); + + return ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > ( + ::LinphonePrivate::Xsd::Rlmi::parseList ( + std::move (d), f | ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom, p)); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > + parseList (::std::istream& is, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0, + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) == 0); + + ::xsd::cxx::xml::sax::std_input_source isrc (is); + return ::LinphonePrivate::Xsd::Rlmi::parseList (isrc, f, p); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > + parseList (::std::istream& is, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0, + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) == 0); + + ::xsd::cxx::xml::sax::std_input_source isrc (is); + return ::LinphonePrivate::Xsd::Rlmi::parseList (isrc, h, f, p); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > + parseList (::std::istream& is, + ::xercesc::DOMErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::sax::std_input_source isrc (is); + return ::LinphonePrivate::Xsd::Rlmi::parseList (isrc, h, f, p); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > + parseList (::std::istream& is, + const ::std::string& sid, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0, + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) == 0); + + ::xsd::cxx::xml::sax::std_input_source isrc (is, sid); + return ::LinphonePrivate::Xsd::Rlmi::parseList (isrc, f, p); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > + parseList (::std::istream& is, + const ::std::string& sid, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0, + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) == 0); + + ::xsd::cxx::xml::sax::std_input_source isrc (is, sid); + return ::LinphonePrivate::Xsd::Rlmi::parseList (isrc, h, f, p); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > + parseList (::std::istream& is, + const ::std::string& sid, + ::xercesc::DOMErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::xml::sax::std_input_source isrc (is, sid); + return ::LinphonePrivate::Xsd::Rlmi::parseList (isrc, h, f, p); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > + parseList (::xercesc::InputSource& i, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::xsd::cxx::tree::error_handler< char > h; + + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::xsd::cxx::xml::dom::parse< char > ( + i, h, p, f)); + + h.throw_if_failed< ::xsd::cxx::tree::parsing< char > > (); + + return ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > ( + ::LinphonePrivate::Xsd::Rlmi::parseList ( + std::move (d), f | ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom, p)); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > + parseList (::xercesc::InputSource& i, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::xsd::cxx::xml::dom::parse< char > ( + i, h, p, f)); + + if (!d.get ()) + throw ::xsd::cxx::tree::parsing< char > (); + + return ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > ( + ::LinphonePrivate::Xsd::Rlmi::parseList ( + std::move (d), f | ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom, p)); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > + parseList (::xercesc::InputSource& i, + ::xercesc::DOMErrorHandler& h, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::xsd::cxx::xml::dom::parse< char > ( + i, h, p, f)); + + if (!d.get ()) + throw ::xsd::cxx::tree::parsing< char > (); + + return ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > ( + ::LinphonePrivate::Xsd::Rlmi::parseList ( + std::move (d), f | ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom, p)); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > + parseList (const ::xercesc::DOMDocument& doc, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p) + { + if (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + static_cast< ::xercesc::DOMDocument* > (doc.cloneNode (true))); + + return ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > ( + ::LinphonePrivate::Xsd::Rlmi::parseList ( + std::move (d), f | ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom, p)); + } + + const ::xercesc::DOMElement& e (*doc.getDocumentElement ()); + const ::xsd::cxx::xml::qualified_name< char > n ( + ::xsd::cxx::xml::dom::name< char > (e)); + + if (n.name () == "list" && + n.namespace_ () == "urn:ietf:params:xml:ns:rlmi") + { + ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > r ( + ::xsd::cxx::tree::traits< ::LinphonePrivate::Xsd::Rlmi::List, char >::create ( + e, f, 0)); + return r; + } + + throw ::xsd::cxx::tree::unexpected_element < char > ( + n.name (), + n.namespace_ (), + "list", + "urn:ietf:params:xml:ns:rlmi"); + } + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > + parseList (::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d, + ::LinphonePrivate::Xsd::XmlSchema::Flags f, + const ::LinphonePrivate::Xsd::XmlSchema::Properties&) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > c ( + ((f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) && + !(f & ::LinphonePrivate::Xsd::XmlSchema::Flags::own_dom)) + ? static_cast< ::xercesc::DOMDocument* > (d->cloneNode (true)) + : 0); + + ::xercesc::DOMDocument& doc (c.get () ? *c : *d); + const ::xercesc::DOMElement& e (*doc.getDocumentElement ()); + + const ::xsd::cxx::xml::qualified_name< char > n ( + ::xsd::cxx::xml::dom::name< char > (e)); + + if (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::keep_dom) + doc.setUserData (::LinphonePrivate::Xsd::XmlSchema::dom::treeNodeKey, + (c.get () ? &c : &d), + 0); + + if (n.name () == "list" && + n.namespace_ () == "urn:ietf:params:xml:ns:rlmi") + { + ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > r ( + ::xsd::cxx::tree::traits< ::LinphonePrivate::Xsd::Rlmi::List, char >::create ( + e, f, 0)); + return r; + } + + throw ::xsd::cxx::tree::unexpected_element < char > ( + n.name (), + n.namespace_ (), + "list", + "urn:ietf:params:xml:ns:rlmi"); + } + } + } +} + +#include +#include +#include + +#include + +namespace _xsd +{ + static + const ::xsd::cxx::tree::type_serializer_plate< 0, char > + type_serializer_plate_init; +} + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace Rlmi + { + void + serializeList (::std::ostream& o, + const ::LinphonePrivate::Xsd::Rlmi::List& s, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m, + const ::std::string& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0); + + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::LinphonePrivate::Xsd::Rlmi::serializeList (s, m, f)); + + ::xsd::cxx::tree::error_handler< char > h; + + ::xsd::cxx::xml::dom::ostream_format_target t (o); + if (!::xsd::cxx::xml::dom::serialize (t, *d, e, h, f)) + { + h.throw_if_failed< ::xsd::cxx::tree::serialization< char > > (); + } + } + + void + serializeList (::std::ostream& o, + const ::LinphonePrivate::Xsd::Rlmi::List& s, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& h, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m, + const ::std::string& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + ::xsd::cxx::xml::auto_initializer i ( + (f & ::LinphonePrivate::Xsd::XmlSchema::Flags::dont_initialize) == 0); + + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::LinphonePrivate::Xsd::Rlmi::serializeList (s, m, f)); + ::xsd::cxx::xml::dom::ostream_format_target t (o); + if (!::xsd::cxx::xml::dom::serialize (t, *d, e, h, f)) + { + throw ::xsd::cxx::tree::serialization< char > (); + } + } + + void + serializeList (::std::ostream& o, + const ::LinphonePrivate::Xsd::Rlmi::List& s, + ::xercesc::DOMErrorHandler& h, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m, + const ::std::string& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::LinphonePrivate::Xsd::Rlmi::serializeList (s, m, f)); + ::xsd::cxx::xml::dom::ostream_format_target t (o); + if (!::xsd::cxx::xml::dom::serialize (t, *d, e, h, f)) + { + throw ::xsd::cxx::tree::serialization< char > (); + } + } + + void + serializeList (::xercesc::XMLFormatTarget& t, + const ::LinphonePrivate::Xsd::Rlmi::List& s, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m, + const ::std::string& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::LinphonePrivate::Xsd::Rlmi::serializeList (s, m, f)); + + ::xsd::cxx::tree::error_handler< char > h; + + if (!::xsd::cxx::xml::dom::serialize (t, *d, e, h, f)) + { + h.throw_if_failed< ::xsd::cxx::tree::serialization< char > > (); + } + } + + void + serializeList (::xercesc::XMLFormatTarget& t, + const ::LinphonePrivate::Xsd::Rlmi::List& s, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& h, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m, + const ::std::string& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::LinphonePrivate::Xsd::Rlmi::serializeList (s, m, f)); + if (!::xsd::cxx::xml::dom::serialize (t, *d, e, h, f)) + { + throw ::xsd::cxx::tree::serialization< char > (); + } + } + + void + serializeList (::xercesc::XMLFormatTarget& t, + const ::LinphonePrivate::Xsd::Rlmi::List& s, + ::xercesc::DOMErrorHandler& h, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m, + const ::std::string& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::LinphonePrivate::Xsd::Rlmi::serializeList (s, m, f)); + if (!::xsd::cxx::xml::dom::serialize (t, *d, e, h, f)) + { + throw ::xsd::cxx::tree::serialization< char > (); + } + } + + void + serializeList (::xercesc::DOMDocument& d, + const ::LinphonePrivate::Xsd::Rlmi::List& s, + ::LinphonePrivate::Xsd::XmlSchema::Flags) + { + ::xercesc::DOMElement& e (*d.getDocumentElement ()); + const ::xsd::cxx::xml::qualified_name< char > n ( + ::xsd::cxx::xml::dom::name< char > (e)); + + if (n.name () == "list" && + n.namespace_ () == "urn:ietf:params:xml:ns:rlmi") + { + e << s; + } + else + { + throw ::xsd::cxx::tree::unexpected_element < char > ( + n.name (), + n.namespace_ (), + "list", + "urn:ietf:params:xml:ns:rlmi"); + } + } + + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > + serializeList (const ::LinphonePrivate::Xsd::Rlmi::List& s, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m, + ::LinphonePrivate::Xsd::XmlSchema::Flags f) + { + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d ( + ::xsd::cxx::xml::dom::serialize< char > ( + "list", + "urn:ietf:params:xml:ns:rlmi", + m, f)); + + ::LinphonePrivate::Xsd::Rlmi::serializeList (*d, s, f); + return d; + } + + void + operator<< (::xercesc::DOMElement& e, const List& i) + { + e << static_cast< const ::LinphonePrivate::Xsd::XmlSchema::Type& > (i); + + // any_attribute + // + for (List::AnyAttributeConstIterator + b (i.getAnyAttribute ().begin ()), n (i.getAnyAttribute ().end ()); + b != n; ++b) + { + ::xercesc::DOMAttr* a ( + static_cast< ::xercesc::DOMAttr* > ( + e.getOwnerDocument ()->importNode ( + const_cast< ::xercesc::DOMAttr* > (&(*b)), true))); + + if (a->getLocalName () == 0) + e.setAttributeNode (a); + else + e.setAttributeNodeNS (a); + } + + // name + // + for (List::NameConstIterator + b (i.getName ().begin ()), n (i.getName ().end ()); + b != n; ++b) + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "name", + "urn:ietf:params:xml:ns:rlmi", + e)); + + s << *b; + } + + // resource + // + for (List::ResourceConstIterator + b (i.getResource ().begin ()), n (i.getResource ().end ()); + b != n; ++b) + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "resource", + "urn:ietf:params:xml:ns:rlmi", + e)); + + s << *b; + } + + // uri + // + { + ::xercesc::DOMAttr& a ( + ::xsd::cxx::xml::dom::create_attribute ( + "uri", + e)); + + a << i.getUri (); + } + + // version + // + { + ::xercesc::DOMAttr& a ( + ::xsd::cxx::xml::dom::create_attribute ( + "version", + e)); + + a << i.getVersion (); + } + + // fullState + // + { + ::xercesc::DOMAttr& a ( + ::xsd::cxx::xml::dom::create_attribute ( + "fullState", + e)); + + a << i.getFullState (); + } + + // cid + // + if (i.getCid ()) + { + ::xercesc::DOMAttr& a ( + ::xsd::cxx::xml::dom::create_attribute ( + "cid", + e)); + + a << *i.getCid (); + } + } + + void + operator<< (::xercesc::DOMElement& e, const Resource& i) + { + e << static_cast< const ::LinphonePrivate::Xsd::XmlSchema::Type& > (i); + + // any_attribute + // + for (Resource::AnyAttributeConstIterator + b (i.getAnyAttribute ().begin ()), n (i.getAnyAttribute ().end ()); + b != n; ++b) + { + ::xercesc::DOMAttr* a ( + static_cast< ::xercesc::DOMAttr* > ( + e.getOwnerDocument ()->importNode ( + const_cast< ::xercesc::DOMAttr* > (&(*b)), true))); + + if (a->getLocalName () == 0) + e.setAttributeNode (a); + else + e.setAttributeNodeNS (a); + } + + // name + // + for (Resource::NameConstIterator + b (i.getName ().begin ()), n (i.getName ().end ()); + b != n; ++b) + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "name", + "urn:ietf:params:xml:ns:rlmi", + e)); + + s << *b; + } + + // instance + // + for (Resource::InstanceConstIterator + b (i.getInstance ().begin ()), n (i.getInstance ().end ()); + b != n; ++b) + { + ::xercesc::DOMElement& s ( + ::xsd::cxx::xml::dom::create_element ( + "instance", + "urn:ietf:params:xml:ns:rlmi", + e)); + + s << *b; + } + + // uri + // + { + ::xercesc::DOMAttr& a ( + ::xsd::cxx::xml::dom::create_attribute ( + "uri", + e)); + + a << i.getUri (); + } + } + + void + operator<< (::xercesc::DOMElement& e, const Instance& i) + { + e << static_cast< const ::LinphonePrivate::Xsd::XmlSchema::Type& > (i); + + // any_attribute + // + for (Instance::AnyAttributeConstIterator + b (i.getAnyAttribute ().begin ()), n (i.getAnyAttribute ().end ()); + b != n; ++b) + { + ::xercesc::DOMAttr* a ( + static_cast< ::xercesc::DOMAttr* > ( + e.getOwnerDocument ()->importNode ( + const_cast< ::xercesc::DOMAttr* > (&(*b)), true))); + + if (a->getLocalName () == 0) + e.setAttributeNode (a); + else + e.setAttributeNodeNS (a); + } + + // any + // + for (Instance::AnyConstIterator + b (i.getAny ().begin ()), n (i.getAny ().end ()); + b != n; ++b) + { + e.appendChild ( + e.getOwnerDocument ()->importNode ( + const_cast< ::xercesc::DOMElement* > (&(*b)), true)); + } + + // id + // + { + ::xercesc::DOMAttr& a ( + ::xsd::cxx::xml::dom::create_attribute ( + "id", + e)); + + a << i.getId (); + } + + // state + // + { + ::xercesc::DOMAttr& a ( + ::xsd::cxx::xml::dom::create_attribute ( + "state", + e)); + + a << i.getState (); + } + + // reason + // + if (i.getReason ()) + { + ::xercesc::DOMAttr& a ( + ::xsd::cxx::xml::dom::create_attribute ( + "reason", + e)); + + a << *i.getReason (); + } + + // cid + // + if (i.getCid ()) + { + ::xercesc::DOMAttr& a ( + ::xsd::cxx::xml::dom::create_attribute ( + "cid", + e)); + + a << *i.getCid (); + } + } + + void + operator<< (::xercesc::DOMElement& e, const Name& i) + { + e << static_cast< const ::LinphonePrivate::Xsd::XmlSchema::String& > (i); + + // lang + // + if (i.getLang ()) + { + ::xercesc::DOMAttr& a ( + ::xsd::cxx::xml::dom::create_attribute ( + "lang", + "http://www.w3.org/XML/1998/namespace", + e)); + + a << *i.getLang (); + } + } + + void + operator<< (::xercesc::DOMElement& e, const State& i) + { + e << static_cast< const ::LinphonePrivate::Xsd::XmlSchema::String& > (i); + } + + void + operator<< (::xercesc::DOMAttr& a, const State& i) + { + a << static_cast< const ::LinphonePrivate::Xsd::XmlSchema::String& > (i); + } + + void + operator<< (::LinphonePrivate::Xsd::XmlSchema::ListStream& l, + const State& i) + { + l << static_cast< const ::LinphonePrivate::Xsd::XmlSchema::String& > (i); + } + } + } +} + +#include + +// Begin epilogue. +// +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif +#if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) + #pragma GCC diagnostic pop +#endif +#if __clang__ || __GNUC__ >= 4 + #pragma GCC diagnostic pop +#endif +// +// End epilogue. + diff --git a/src/xml/rlmi.h b/src/xml/rlmi.h new file mode 100644 index 000000000..68855f6cc --- /dev/null +++ b/src/xml/rlmi.h @@ -0,0 +1,1156 @@ +// Copyright (c) 2005-2014 Code Synthesis Tools CC +// +// This program was generated by CodeSynthesis XSD, an XML Schema to +// C++ data binding compiler. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as +// published by the Free Software Foundation. +// +// 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 St, Fifth Floor, Boston, MA 02110-1301 USA +// +// In addition, as a special exception, Code Synthesis Tools CC gives +// permission to link this program with the Xerces-C++ library (or with +// modified versions of Xerces-C++ that use the same license as Xerces-C++), +// and distribute linked combinations including the two. You must obey +// the GNU General Public License version 2 in all respects for all of +// the code used other than Xerces-C++. If you modify this copy of the +// program, you may extend this exception to your version of the program, +// but you are not obligated to do so. If you do not wish to do so, delete +// this exception statement from your version. +// +// Furthermore, Code Synthesis Tools CC makes a special exception for +// the Free/Libre and Open Source Software (FLOSS) which is described +// in the accompanying FLOSSE file. +// + +#ifndef XML_RLMI_H +#define XML_RLMI_H + +#ifndef XSD_CXX11 +#define XSD_CXX11 +#endif + +#ifndef XSD_USE_CHAR +#define XSD_USE_CHAR +#endif + +#ifndef XSD_CXX_TREE_USE_CHAR +#define XSD_CXX_TREE_USE_CHAR +#endif + +// Begin prologue. +// +#if __clang__ || __GNUC__ >= 4 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wfloat-equal" + #pragma GCC diagnostic ignored "-Wsign-conversion" + #pragma GCC diagnostic ignored "-Wconversion" +#endif +#if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsuggest-override" +#endif +#if __GNUC__ >=7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" +#endif +// +// End prologue. + +#include + +#if (XSD_INT_VERSION != 4000000L) +#error XSD runtime version mismatch +#endif + +#include + +#include + +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace XmlSchema + { + // anyType and anySimpleType. + // + typedef ::xsd::cxx::tree::type Type; + typedef ::xsd::cxx::tree::simple_type< char, Type > SimpleType; + typedef ::xsd::cxx::tree::type Container; + + // 8-bit + // + typedef signed char Byte; + typedef unsigned char UnsignedByte; + + // 16-bit + // + typedef short Short; + typedef unsigned short UnsignedShort; + + // 32-bit + // + typedef int Int; + typedef unsigned int UnsignedInt; + + // 64-bit + // + typedef long long Long; + typedef unsigned long long UnsignedLong; + + // Supposed to be arbitrary-length integral types. + // + typedef long long Integer; + typedef long long NonPositiveInteger; + typedef unsigned long long NonNegativeInteger; + typedef unsigned long long PositiveInteger; + typedef long long NegativeInteger; + + // Boolean. + // + typedef bool Boolean; + + // Floating-point types. + // + typedef float Float; + typedef double Double; + typedef double Decimal; + + // String types. + // + typedef ::xsd::cxx::tree::string< char, SimpleType > String; + typedef ::xsd::cxx::tree::normalized_string< char, String > NormalizedString; + typedef ::xsd::cxx::tree::token< char, NormalizedString > Token; + typedef ::xsd::cxx::tree::name< char, Token > Name; + typedef ::xsd::cxx::tree::nmtoken< char, Token > Nmtoken; + typedef ::xsd::cxx::tree::nmtokens< char, SimpleType, Nmtoken > Nmtokens; + typedef ::xsd::cxx::tree::ncname< char, Name > Ncname; + typedef ::xsd::cxx::tree::language< char, Token > Language; + + // ID/IDREF. + // + typedef ::xsd::cxx::tree::id< char, Ncname > Id; + typedef ::xsd::cxx::tree::idref< char, Ncname, Type > Idref; + typedef ::xsd::cxx::tree::idrefs< char, SimpleType, Idref > Idrefs; + + // URI. + // + typedef ::xsd::cxx::tree::uri< char, SimpleType > Uri; + + // Qualified name. + // + typedef ::xsd::cxx::tree::qname< char, SimpleType, Uri, Ncname > Qname; + + // Binary. + // + typedef ::xsd::cxx::tree::buffer< char > Buffer; + typedef ::xsd::cxx::tree::base64_binary< char, SimpleType > Base64Binary; + typedef ::xsd::cxx::tree::hex_binary< char, SimpleType > HexBinary; + + // Date/time. + // + typedef ::xsd::cxx::tree::time_zone TimeZone; + typedef ::xsd::cxx::tree::date< char, SimpleType > Date; + typedef ::xsd::cxx::tree::date_time< char, SimpleType > DateTime; + typedef ::xsd::cxx::tree::duration< char, SimpleType > Duration; + typedef ::xsd::cxx::tree::gday< char, SimpleType > Gday; + typedef ::xsd::cxx::tree::gmonth< char, SimpleType > Gmonth; + typedef ::xsd::cxx::tree::gmonth_day< char, SimpleType > GmonthDay; + typedef ::xsd::cxx::tree::gyear< char, SimpleType > Gyear; + typedef ::xsd::cxx::tree::gyear_month< char, SimpleType > GyearMonth; + typedef ::xsd::cxx::tree::time< char, SimpleType > Time; + + // Entity. + // + typedef ::xsd::cxx::tree::entity< char, Ncname > Entity; + typedef ::xsd::cxx::tree::entities< char, SimpleType, Entity > Entities; + + typedef ::xsd::cxx::tree::content_order ContentOrder; + // Namespace information and list stream. Used in + // serialization functions. + // + typedef ::xsd::cxx::xml::dom::namespace_info< char > NamespaceInfo; + typedef ::xsd::cxx::xml::dom::namespace_infomap< char > NamespaceInfomap; + typedef ::xsd::cxx::tree::list_stream< char > ListStream; + typedef ::xsd::cxx::tree::as_double< Double > AsDouble; + typedef ::xsd::cxx::tree::as_decimal< Decimal > AsDecimal; + typedef ::xsd::cxx::tree::facet Facet; + + // Flags and properties. + // + typedef ::xsd::cxx::tree::flags Flags; + typedef ::xsd::cxx::tree::properties< char > Properties; + + // Parsing/serialization diagnostics. + // + typedef ::xsd::cxx::tree::severity Severity; + typedef ::xsd::cxx::tree::error< char > Error; + typedef ::xsd::cxx::tree::diagnostics< char > Diagnostics; + + // Exceptions. + // + typedef ::xsd::cxx::tree::exception< char > Exception; + typedef ::xsd::cxx::tree::bounds< char > Bounds; + typedef ::xsd::cxx::tree::duplicate_id< char > DuplicateId; + typedef ::xsd::cxx::tree::parsing< char > Parsing; + typedef ::xsd::cxx::tree::expected_element< char > ExpectedElement; + typedef ::xsd::cxx::tree::unexpected_element< char > UnexpectedElement; + typedef ::xsd::cxx::tree::expected_attribute< char > ExpectedAttribute; + typedef ::xsd::cxx::tree::unexpected_enumerator< char > UnexpectedEnumerator; + typedef ::xsd::cxx::tree::expected_text_content< char > ExpectedTextContent; + typedef ::xsd::cxx::tree::no_prefix_mapping< char > NoPrefixMapping; + typedef ::xsd::cxx::tree::no_type_info< char > NoTypeInfo; + typedef ::xsd::cxx::tree::not_derived< char > NotDerived; + typedef ::xsd::cxx::tree::serialization< char > Serialization; + + // Error handler callback interface. + // + typedef ::xsd::cxx::xml::error_handler< char > ErrorHandler; + + // DOM interaction. + // + namespace dom + { + // Automatic pointer for DOMDocument. + // + using ::xsd::cxx::xml::dom::unique_ptr; + +#ifndef XSD_CXX_TREE_TREE_NODE_KEY__LINPHONEPRIVATE__XSD__XMLSCHEMA +#define XSD_CXX_TREE_TREE_NODE_KEY__LINPHONEPRIVATE__XSD__XMLSCHEMA + // DOM user data key for back pointers to tree nodes. + // + const XMLCh* const treeNodeKey = ::xsd::cxx::tree::user_data_keys::node; +#endif + } + } + } +} + +// Forward declarations. +// +namespace LinphonePrivate +{ + namespace Xsd + { + namespace Rlmi + { + class List; + class Resource; + class Instance; + class Name; + class State; + } + } +} + + +#include // ::std::unique_ptr +#include // std::numeric_limits +#include // std::binary_search +#include // std::move + +#include + +#include +#include +#include +#include + +#include + +#include + +#include "xml.h" + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace Rlmi + { + class List: public ::LinphonePrivate::Xsd::XmlSchema::Type + { + public: + // name + // + typedef ::LinphonePrivate::Xsd::Rlmi::Name NameType; + typedef ::xsd::cxx::tree::sequence< NameType > NameSequence; + typedef NameSequence::iterator NameIterator; + typedef NameSequence::const_iterator NameConstIterator; + typedef ::xsd::cxx::tree::traits< NameType, char > NameTraits; + + const NameSequence& + getName () const; + + NameSequence& + getName (); + + void + setName (const NameSequence& s); + + // resource + // + typedef ::LinphonePrivate::Xsd::Rlmi::Resource ResourceType; + typedef ::xsd::cxx::tree::sequence< ResourceType > ResourceSequence; + typedef ResourceSequence::iterator ResourceIterator; + typedef ResourceSequence::const_iterator ResourceConstIterator; + typedef ::xsd::cxx::tree::traits< ResourceType, char > ResourceTraits; + + const ResourceSequence& + getResource () const; + + ResourceSequence& + getResource (); + + void + setResource (const ResourceSequence& s); + + // uri + // + typedef ::LinphonePrivate::Xsd::XmlSchema::Uri UriType; + typedef ::xsd::cxx::tree::traits< UriType, char > UriTraits; + + const UriType& + getUri () const; + + UriType& + getUri (); + + void + setUri (const UriType& x); + + void + setUri (::std::unique_ptr< UriType > p); + + ::std::unique_ptr< UriType > + setDetachUri (); + + // version + // + typedef ::LinphonePrivate::Xsd::XmlSchema::UnsignedInt VersionType; + typedef ::xsd::cxx::tree::traits< VersionType, char > VersionTraits; + + const VersionType& + getVersion () const; + + VersionType& + getVersion (); + + void + setVersion (const VersionType& x); + + // fullState + // + typedef ::LinphonePrivate::Xsd::XmlSchema::Boolean FullStateType; + typedef ::xsd::cxx::tree::traits< FullStateType, char > FullStateTraits; + + const FullStateType& + getFullState () const; + + FullStateType& + getFullState (); + + void + setFullState (const FullStateType& x); + + // cid + // + typedef ::LinphonePrivate::Xsd::XmlSchema::String CidType; + typedef ::xsd::cxx::tree::optional< CidType > CidOptional; + typedef ::xsd::cxx::tree::traits< CidType, char > CidTraits; + + const CidOptional& + getCid () const; + + CidOptional& + getCid (); + + void + setCid (const CidType& x); + + void + setCid (const CidOptional& x); + + void + setCid (::std::unique_ptr< CidType > p); + + // any_attribute + // + typedef ::xsd::cxx::tree::attribute_set< char > AnyAttributeSet; + typedef AnyAttributeSet::iterator AnyAttributeIterator; + typedef AnyAttributeSet::const_iterator AnyAttributeConstIterator; + + const AnyAttributeSet& + getAnyAttribute () const; + + AnyAttributeSet& + getAnyAttribute (); + + void + setAnyAttribute (const AnyAttributeSet& s); + + // DOMDocument for wildcard content. + // + const ::xercesc::DOMDocument& + getDomDocument () const; + + ::xercesc::DOMDocument& + getDomDocument (); + + // Constructors. + // + List (const UriType&, + const VersionType&, + const FullStateType&); + + List (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + List (const List& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + virtual List* + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0) const; + + List& + operator= (const List& x); + + virtual + ~List (); + + // Implementation. + // + protected: + void + parse (::xsd::cxx::xml::dom::parser< char >&, + ::LinphonePrivate::Xsd::XmlSchema::Flags); + + protected: + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > dom_document_; + + NameSequence name_; + ResourceSequence resource_; + ::xsd::cxx::tree::one< UriType > uri_; + ::xsd::cxx::tree::one< VersionType > version_; + ::xsd::cxx::tree::one< FullStateType > fullState_; + CidOptional cid_; + AnyAttributeSet any_attribute_; + }; + + class Resource: public ::LinphonePrivate::Xsd::XmlSchema::Type + { + public: + // name + // + typedef ::LinphonePrivate::Xsd::Rlmi::Name NameType; + typedef ::xsd::cxx::tree::sequence< NameType > NameSequence; + typedef NameSequence::iterator NameIterator; + typedef NameSequence::const_iterator NameConstIterator; + typedef ::xsd::cxx::tree::traits< NameType, char > NameTraits; + + const NameSequence& + getName () const; + + NameSequence& + getName (); + + void + setName (const NameSequence& s); + + // instance + // + typedef ::LinphonePrivate::Xsd::Rlmi::Instance InstanceType; + typedef ::xsd::cxx::tree::sequence< InstanceType > InstanceSequence; + typedef InstanceSequence::iterator InstanceIterator; + typedef InstanceSequence::const_iterator InstanceConstIterator; + typedef ::xsd::cxx::tree::traits< InstanceType, char > InstanceTraits; + + const InstanceSequence& + getInstance () const; + + InstanceSequence& + getInstance (); + + void + setInstance (const InstanceSequence& s); + + // uri + // + typedef ::LinphonePrivate::Xsd::XmlSchema::Uri UriType; + typedef ::xsd::cxx::tree::traits< UriType, char > UriTraits; + + const UriType& + getUri () const; + + UriType& + getUri (); + + void + setUri (const UriType& x); + + void + setUri (::std::unique_ptr< UriType > p); + + ::std::unique_ptr< UriType > + setDetachUri (); + + // any_attribute + // + typedef ::xsd::cxx::tree::attribute_set< char > AnyAttributeSet; + typedef AnyAttributeSet::iterator AnyAttributeIterator; + typedef AnyAttributeSet::const_iterator AnyAttributeConstIterator; + + const AnyAttributeSet& + getAnyAttribute () const; + + AnyAttributeSet& + getAnyAttribute (); + + void + setAnyAttribute (const AnyAttributeSet& s); + + // DOMDocument for wildcard content. + // + const ::xercesc::DOMDocument& + getDomDocument () const; + + ::xercesc::DOMDocument& + getDomDocument (); + + // Constructors. + // + Resource (const UriType&); + + Resource (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + Resource (const Resource& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + virtual Resource* + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0) const; + + Resource& + operator= (const Resource& x); + + virtual + ~Resource (); + + // Implementation. + // + protected: + void + parse (::xsd::cxx::xml::dom::parser< char >&, + ::LinphonePrivate::Xsd::XmlSchema::Flags); + + protected: + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > dom_document_; + + NameSequence name_; + InstanceSequence instance_; + ::xsd::cxx::tree::one< UriType > uri_; + AnyAttributeSet any_attribute_; + }; + + class Instance: public ::LinphonePrivate::Xsd::XmlSchema::Type + { + public: + // any + // + typedef ::xsd::cxx::tree::element_sequence AnySequence; + typedef AnySequence::iterator AnyIterator; + typedef AnySequence::const_iterator AnyConstIterator; + + const AnySequence& + getAny () const; + + AnySequence& + getAny (); + + void + setAny (const AnySequence& s); + + // id + // + typedef ::LinphonePrivate::Xsd::XmlSchema::String IdType; + typedef ::xsd::cxx::tree::traits< IdType, char > IdTraits; + + const IdType& + getId () const; + + IdType& + getId (); + + void + setId (const IdType& x); + + void + setId (::std::unique_ptr< IdType > p); + + ::std::unique_ptr< IdType > + setDetachId (); + + // state + // + typedef ::LinphonePrivate::Xsd::Rlmi::State StateType; + typedef ::xsd::cxx::tree::traits< StateType, char > StateTraits; + + const StateType& + getState () const; + + StateType& + getState (); + + void + setState (const StateType& x); + + void + setState (::std::unique_ptr< StateType > p); + + ::std::unique_ptr< StateType > + setDetachState (); + + // reason + // + typedef ::LinphonePrivate::Xsd::XmlSchema::String ReasonType; + typedef ::xsd::cxx::tree::optional< ReasonType > ReasonOptional; + typedef ::xsd::cxx::tree::traits< ReasonType, char > ReasonTraits; + + const ReasonOptional& + getReason () const; + + ReasonOptional& + getReason (); + + void + setReason (const ReasonType& x); + + void + setReason (const ReasonOptional& x); + + void + setReason (::std::unique_ptr< ReasonType > p); + + // cid + // + typedef ::LinphonePrivate::Xsd::XmlSchema::String CidType; + typedef ::xsd::cxx::tree::optional< CidType > CidOptional; + typedef ::xsd::cxx::tree::traits< CidType, char > CidTraits; + + const CidOptional& + getCid () const; + + CidOptional& + getCid (); + + void + setCid (const CidType& x); + + void + setCid (const CidOptional& x); + + void + setCid (::std::unique_ptr< CidType > p); + + // any_attribute + // + typedef ::xsd::cxx::tree::attribute_set< char > AnyAttributeSet; + typedef AnyAttributeSet::iterator AnyAttributeIterator; + typedef AnyAttributeSet::const_iterator AnyAttributeConstIterator; + + const AnyAttributeSet& + getAnyAttribute () const; + + AnyAttributeSet& + getAnyAttribute (); + + void + setAnyAttribute (const AnyAttributeSet& s); + + // DOMDocument for wildcard content. + // + const ::xercesc::DOMDocument& + getDomDocument () const; + + ::xercesc::DOMDocument& + getDomDocument (); + + // Constructors. + // + Instance (const IdType&, + const StateType&); + + Instance (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + Instance (const Instance& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + virtual Instance* + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0) const; + + Instance& + operator= (const Instance& x); + + virtual + ~Instance (); + + // Implementation. + // + protected: + void + parse (::xsd::cxx::xml::dom::parser< char >&, + ::LinphonePrivate::Xsd::XmlSchema::Flags); + + protected: + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > dom_document_; + + AnySequence any_; + ::xsd::cxx::tree::one< IdType > id_; + ::xsd::cxx::tree::one< StateType > state_; + ReasonOptional reason_; + CidOptional cid_; + AnyAttributeSet any_attribute_; + }; + + class Name: public ::LinphonePrivate::Xsd::XmlSchema::String + { + public: + // lang + // + typedef ::namespace_::Lang LangType; + typedef ::xsd::cxx::tree::optional< LangType > LangOptional; + typedef ::xsd::cxx::tree::traits< LangType, char > LangTraits; + + const LangOptional& + getLang () const; + + LangOptional& + getLang (); + + void + setLang (const LangType& x); + + void + setLang (const LangOptional& x); + + void + setLang (::std::unique_ptr< LangType > p); + + // Constructors. + // + Name (); + + Name (const char*); + + Name (const ::std::string&); + + Name (const ::LinphonePrivate::Xsd::XmlSchema::String&); + + Name (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + Name (const Name& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + virtual Name* + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0) const; + + Name& + operator= (const Name& x); + + virtual + ~Name (); + + // Implementation. + // + protected: + void + parse (::xsd::cxx::xml::dom::parser< char >&, + ::LinphonePrivate::Xsd::XmlSchema::Flags); + + protected: + LangOptional lang_; + }; + + class State: public ::LinphonePrivate::Xsd::XmlSchema::String + { + public: + enum Value + { + active, + pending, + terminated + }; + + State (Value v); + + State (const char* v); + + State (const ::std::string& v); + + State (const ::LinphonePrivate::Xsd::XmlSchema::String& v); + + State (const ::xercesc::DOMElement& e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + State (const ::xercesc::DOMAttr& a, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + State (const ::std::string& s, + const ::xercesc::DOMElement* e, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + State (const State& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0); + + virtual State* + _clone (::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + ::LinphonePrivate::Xsd::XmlSchema::Container* c = 0) const; + + State& + operator= (Value v); + + virtual + operator Value () const + { + return _xsd_State_convert (); + } + + protected: + Value + _xsd_State_convert () const; + + public: + static const char* const _xsd_State_literals_[3]; + static const Value _xsd_State_indexes_[3]; + }; + } + } +} + +#include + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace Rlmi + { + ::std::ostream& + operator<< (::std::ostream&, const List&); + + ::std::ostream& + operator<< (::std::ostream&, const Resource&); + + ::std::ostream& + operator<< (::std::ostream&, const Instance&); + + ::std::ostream& + operator<< (::std::ostream&, const Name&); + + ::std::ostream& + operator<< (::std::ostream&, State::Value); + + ::std::ostream& + operator<< (::std::ostream&, const State&); + } + } +} + +#include + +#include +#include +#include + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace Rlmi + { + // Parse a URI or a local file. + // + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > + parseList (const ::std::string& uri, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > + parseList (const ::std::string& uri, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > + parseList (const ::std::string& uri, + ::xercesc::DOMErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + // Parse std::istream. + // + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > + parseList (::std::istream& is, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > + parseList (::std::istream& is, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > + parseList (::std::istream& is, + ::xercesc::DOMErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > + parseList (::std::istream& is, + const ::std::string& id, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > + parseList (::std::istream& is, + const ::std::string& id, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > + parseList (::std::istream& is, + const ::std::string& id, + ::xercesc::DOMErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + // Parse xercesc::InputSource. + // + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > + parseList (::xercesc::InputSource& is, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > + parseList (::xercesc::InputSource& is, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > + parseList (::xercesc::InputSource& is, + ::xercesc::DOMErrorHandler& eh, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + // Parse xercesc::DOMDocument. + // + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > + parseList (const ::xercesc::DOMDocument& d, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + + ::std::unique_ptr< ::LinphonePrivate::Xsd::Rlmi::List > + parseList (::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > d, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0, + const ::LinphonePrivate::Xsd::XmlSchema::Properties& p = ::LinphonePrivate::Xsd::XmlSchema::Properties ()); + } + } +} + +#include + +#include +#include +#include + +#include + +namespace LinphonePrivate +{ + namespace Xsd + { + namespace Rlmi + { + // Serialize to std::ostream. + // + + void + serializeList (::std::ostream& os, + const ::LinphonePrivate::Xsd::Rlmi::List& x, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), + const ::std::string& e = "UTF-8", + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + void + serializeList (::std::ostream& os, + const ::LinphonePrivate::Xsd::Rlmi::List& x, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& eh, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), + const ::std::string& e = "UTF-8", + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + void + serializeList (::std::ostream& os, + const ::LinphonePrivate::Xsd::Rlmi::List& x, + ::xercesc::DOMErrorHandler& eh, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), + const ::std::string& e = "UTF-8", + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + // Serialize to xercesc::XMLFormatTarget. + // + + void + serializeList (::xercesc::XMLFormatTarget& ft, + const ::LinphonePrivate::Xsd::Rlmi::List& x, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), + const ::std::string& e = "UTF-8", + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + void + serializeList (::xercesc::XMLFormatTarget& ft, + const ::LinphonePrivate::Xsd::Rlmi::List& x, + ::LinphonePrivate::Xsd::XmlSchema::ErrorHandler& eh, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), + const ::std::string& e = "UTF-8", + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + void + serializeList (::xercesc::XMLFormatTarget& ft, + const ::LinphonePrivate::Xsd::Rlmi::List& x, + ::xercesc::DOMErrorHandler& eh, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), + const ::std::string& e = "UTF-8", + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + // Serialize to an existing xercesc::DOMDocument. + // + + void + serializeList (::xercesc::DOMDocument& d, + const ::LinphonePrivate::Xsd::Rlmi::List& x, + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + // Serialize to a new xercesc::DOMDocument. + // + + ::LinphonePrivate::Xsd::XmlSchema::dom::unique_ptr< ::xercesc::DOMDocument > + serializeList (const ::LinphonePrivate::Xsd::Rlmi::List& x, + const ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap& m = ::LinphonePrivate::Xsd::XmlSchema::NamespaceInfomap (), + ::LinphonePrivate::Xsd::XmlSchema::Flags f = 0); + + void + operator<< (::xercesc::DOMElement&, const List&); + + void + operator<< (::xercesc::DOMElement&, const Resource&); + + void + operator<< (::xercesc::DOMElement&, const Instance&); + + void + operator<< (::xercesc::DOMElement&, const Name&); + + void + operator<< (::xercesc::DOMElement&, const State&); + + void + operator<< (::xercesc::DOMAttr&, const State&); + + void + operator<< (::LinphonePrivate::Xsd::XmlSchema::ListStream&, + const State&); + } + } +} + +#include + +// Begin epilogue. +// +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif +#if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) + #pragma GCC diagnostic pop +#endif +#if __clang__ || __GNUC__ >= 4 + #pragma GCC diagnostic pop +#endif +// +// End epilogue. + +#endif // XML_RLMI_H diff --git a/src/xml/rlmi.xsd b/src/xml/rlmi.xsd new file mode 100644 index 000000000..a903802fb --- /dev/null +++ b/src/xml/rlmi.xsd @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/xml/xml.cpp b/src/xml/xml.cpp index b8c204909..7c5162e3d 100644 --- a/src/xml/xml.cpp +++ b/src/xml/xml.cpp @@ -36,9 +36,16 @@ #if __clang__ || __GNUC__ >= 4 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wfloat-equal" + #pragma GCC diagnostic ignored "-Wsign-conversion" + #pragma GCC diagnostic ignored "-Wconversion" +#endif #if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-override" #endif +#if __GNUC__ >=7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" #endif // // End prologue. @@ -73,7 +80,7 @@ namespace namespace_ } // Space - // + // Space:: Space (Value v) @@ -110,7 +117,7 @@ namespace namespace_ Space& Space:: operator= (Value v) { - static_cast< ::LinphonePrivate::Xsd::XmlSchema::Ncname& > (*this) = + static_cast< ::LinphonePrivate::Xsd::XmlSchema::Ncname& > (*this) = ::LinphonePrivate::Xsd::XmlSchema::Ncname (_xsd_Space_literals_[v]); return *this; @@ -118,7 +125,7 @@ namespace namespace_ // Lang_member - // + // Lang_member:: Lang_member (Value v) @@ -155,7 +162,7 @@ namespace namespace_ Lang_member& Lang_member:: operator= (Value v) { - static_cast< ::LinphonePrivate::Xsd::XmlSchema::String& > (*this) = + static_cast< ::LinphonePrivate::Xsd::XmlSchema::String& > (*this) = ::LinphonePrivate::Xsd::XmlSchema::String (_xsd_Lang_member_literals_[v]); return *this; @@ -166,6 +173,15 @@ namespace namespace_ #include +#include + +namespace _xsd +{ + static + const ::xsd::cxx::tree::type_factory_plate< 0, char > + type_factory_plate_init; +} + namespace namespace_ { // Lang @@ -344,6 +360,15 @@ namespace namespace_ #include +#include + +namespace _xsd +{ + static + const ::xsd::cxx::tree::std_ostream_plate< 0, char > + std_ostream_plate_init; +} + namespace namespace_ { ::std::ostream& @@ -389,6 +414,15 @@ namespace namespace_ #include #include +#include + +namespace _xsd +{ + static + const ::xsd::cxx::tree::type_serializer_plate< 0, char > + type_serializer_plate_init; +} + namespace namespace_ { void @@ -453,8 +487,15 @@ namespace namespace_ // Begin epilogue. // +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif +#if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) + #pragma GCC diagnostic pop +#endif #if __clang__ || __GNUC__ >= 4 #pragma GCC diagnostic pop #endif // // End epilogue. + diff --git a/src/xml/xml.h b/src/xml/xml.h index af3c3c3a2..c05ea2029 100644 --- a/src/xml/xml.h +++ b/src/xml/xml.h @@ -51,9 +51,16 @@ #if __clang__ || __GNUC__ >= 4 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wfloat-equal" + #pragma GCC diagnostic ignored "-Wsign-conversion" + #pragma GCC diagnostic ignored "-Wconversion" +#endif #if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-override" #endif +#if __GNUC__ >=7 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" #endif // // End prologue. @@ -240,6 +247,8 @@ namespace LinphonePrivate typedef ::xsd::cxx::tree::unexpected_enumerator< char > UnexpectedEnumerator; typedef ::xsd::cxx::tree::expected_text_content< char > ExpectedTextContent; typedef ::xsd::cxx::tree::no_prefix_mapping< char > NoPrefixMapping; + typedef ::xsd::cxx::tree::no_type_info< char > NoTypeInfo; + typedef ::xsd::cxx::tree::not_derived< char > NotDerived; typedef ::xsd::cxx::tree::serialization< char > Serialization; // Error handler callback interface. @@ -510,6 +519,12 @@ namespace namespace_ // Begin epilogue. // +#if __GNUC__ >= 7 + #pragma GCC diagnostic pop +#endif +#if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) + #pragma GCC diagnostic pop +#endif #if __clang__ || __GNUC__ >= 4 #pragma GCC diagnostic pop #endif diff --git a/tester/CMakeLists.txt b/tester/CMakeLists.txt index 2fdf1354c..68cd7fe1b 100644 --- a/tester/CMakeLists.txt +++ b/tester/CMakeLists.txt @@ -77,6 +77,7 @@ set(CERTIFICATE_CLIENT_FILES set(CERTIFICATE_FILES ${CERTIFICATE_ALT_FILES} ${CERTIFICATE_CN_FILES} ${CERTIFICATE_CLIENT_FILES}) set(DB_FILES + db/friends.db db/linphone.db db/messages.db ) @@ -115,6 +116,8 @@ set(RC_FILES rcfiles/marie_zrtp_aes256_rc rcfiles/marie_zrtp_b256_rc rcfiles/marie_zrtp_srtpsuite_aes256_rc + rcfiles/marie_zrtp_ecdh255_rc + rcfiles/marie_zrtp_ecdh448_rc rcfiles/michelle_rc_udp rcfiles/multi_account_rc rcfiles/pauline_alt_rc @@ -132,6 +135,8 @@ set(RC_FILES rcfiles/pauline_zrtp_aes256_rc rcfiles/pauline_zrtp_b256_rc rcfiles/pauline_zrtp_srtpsuite_aes256_rc + rcfiles/pauline_zrtp_ecdh255_rc + rcfiles/pauline_zrtp_ecdh448_rc rcfiles/remote_zero_length_params_rc rcfiles/stun_rc rcfiles/zero_length_params_rc @@ -201,7 +206,7 @@ set(SOURCE_FILES_C set(SOURCE_FILES_CXX clonable-object-tester.cpp conference-event-tester.cpp - content-manager-tester.cpp + contents-tester.cpp cpim-tester.cpp main-db-tester.cpp multipart-tester.cpp diff --git a/tester/account_creator_tester.c b/tester/account_creator_tester.c index 3ae77ff98..cc5773f3a 100644 --- a/tester/account_creator_tester.c +++ b/tester/account_creator_tester.c @@ -62,8 +62,9 @@ static void local_username_too_short(void) { LinphoneAccountCreatorUsernameStatus, "%i"); - linphone_account_creator_unref(creator); + linphone_core_manager_destroy(marie); + linphone_account_creator_unref(creator); } static void local_username_too_long(void) { diff --git a/tester/call_multi_tester.c b/tester/call_multi_tester.c index da58f20eb..913eb43ec 100644 --- a/tester/call_multi_tester.c +++ b/tester/call_multi_tester.c @@ -1151,10 +1151,12 @@ void do_not_stop_ringing_when_declining_one_of_two_incoming_calls(void) { pauline_called_by_marie=linphone_core_get_current_call(marie->lc); linphone_call_decline(pauline_called_by_laure, LinphoneReasonDeclined); BC_ASSERT_TRUE(wait_for(laure->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); + BC_ASSERT_TRUE(wait_for(laure->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallReleased,1)); BC_ASSERT_TRUE(linphone_ringtoneplayer_is_started(linphone_core_get_ringtoneplayer(pauline->lc))); linphone_call_terminate(pauline_called_by_marie); BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallEnd,2)); + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallReleased,2)); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); diff --git a/tester/call_multicast_tester.c b/tester/call_multicast_tester.c index 4b21370e8..249c2adfb 100644 --- a/tester/call_multicast_tester.c +++ b/tester/call_multicast_tester.c @@ -55,7 +55,7 @@ static void call_multicast_base(bool_t video) { BC_ASSERT_GREATER(linphone_core_manager_get_max_audio_down_bw(marie),70,int,"%d"); if (video) { /*check video path*/ - linphone_call_set_next_video_frame_decoded_callback(linphone_core_get_current_call(marie->lc),linphone_call_iframe_decoded_cb,marie->lc); + linphone_call_set_first_video_frame_decoded_cb(linphone_core_get_current_call(marie->lc)); linphone_call_send_vfu_request(linphone_core_get_current_call(marie->lc)); BC_ASSERT_TRUE( wait_for(marie->lc,pauline->lc,&marie->stat.number_of_IframeDecoded,1)); } @@ -149,7 +149,7 @@ static void early_media_with_multicast_base(bool_t video) { /* send a 183 to initiate the early media */ if (video) { /*check video path*/ - linphone_call_set_next_video_frame_decoded_callback(linphone_core_get_current_call(pauline->lc),linphone_call_iframe_decoded_cb,pauline->lc); + linphone_call_set_first_video_frame_decoded_cb(linphone_core_get_current_call(pauline->lc)); } linphone_call_accept_early_media(linphone_core_get_current_call(pauline->lc)); @@ -160,7 +160,7 @@ static void early_media_with_multicast_base(bool_t video) { /* send a 183 to initiate the early media */ if (video) { /*check video path*/ - linphone_call_set_next_video_frame_decoded_callback(linphone_core_get_current_call(pauline2->lc),linphone_call_iframe_decoded_cb,pauline2->lc); + linphone_call_set_first_video_frame_decoded_cb(linphone_core_get_current_call(pauline2->lc)); } linphone_call_accept_early_media(linphone_core_get_current_call(pauline2->lc)); diff --git a/tester/call_single_tester.c b/tester/call_single_tester.c index 08be21bf9..a6287f1fe 100644 --- a/tester/call_single_tester.c +++ b/tester/call_single_tester.c @@ -173,12 +173,12 @@ void linphone_transfer_state_changed(LinphoneCore *lc, LinphoneCall *transfered, } -void linphone_call_iframe_decoded_cb(LinphoneCall *call,void * user_data) { - LinphoneCallLog *calllog = linphone_call_get_call_log(call); - char* to=linphone_address_as_string(linphone_call_log_get_to(calllog)); - char* from=linphone_address_as_string(linphone_call_log_get_from(calllog)); +static void linphone_call_next_video_frame_decoded_cb(LinphoneCall *call) { + LinphoneCallLog *clog = linphone_call_get_call_log(call); + char* to=linphone_address_as_string(linphone_call_log_get_to(clog)); + char* from=linphone_address_as_string(linphone_call_log_get_to(clog)); stats* counters; - LinphoneCore* lc=(LinphoneCore*)user_data; + LinphoneCore* lc = linphone_call_get_core(call); ms_message("call from [%s] to [%s] receive iFrame",from,to); ms_free(to); ms_free(from); @@ -186,6 +186,13 @@ void linphone_call_iframe_decoded_cb(LinphoneCall *call,void * user_data) { counters->number_of_IframeDecoded++; } +void linphone_call_set_first_video_frame_decoded_cb(LinphoneCall *call) { + LinphoneCallCbs *call_cbs = linphone_factory_create_call_cbs(linphone_factory_get()); + linphone_call_cbs_set_next_video_frame_decoded(call_cbs, linphone_call_next_video_frame_decoded_cb); + linphone_call_add_callbacks(call, call_cbs); + linphone_call_cbs_unref(call_cbs); +} + #define reset_call_stats(var, value) \ if (var) linphone_call_stats_unref(var); \ var = value @@ -1340,7 +1347,7 @@ static void cancelled_ringing_call(void) { const bctbx_list_t * call_history; LinphoneCall* out_call; - char * db_path= bctbx_strdup_printf("%s,%s",bc_tester_get_writable_dir_prefix(),"tmp_call_log.db"); + char * db_path= bctbx_strdup_printf("%s/%s",bc_tester_get_writable_dir_prefix(),"tmp_call_log.db"); linphone_core_set_call_logs_database_path(marie->lc,db_path); @@ -2669,7 +2676,10 @@ static void zrtp_cipher_call(void) { call_base_with_configfile(LinphoneMediaEncryptionZRTP,FALSE,FALSE,LinphonePolicyNoFirewall,FALSE, "marie_zrtp_aes256_rc", "pauline_tcp_rc"); } - +static void zrtp_key_agreement_call(void) { + call_base_with_configfile(LinphoneMediaEncryptionZRTP,FALSE,FALSE,LinphonePolicyNoFirewall,FALSE, "marie_zrtp_ecdh255_rc", "pauline_zrtp_ecdh255_rc"); + call_base_with_configfile(LinphoneMediaEncryptionZRTP,FALSE,FALSE,LinphonePolicyNoFirewall,FALSE, "marie_zrtp_ecdh448_rc", "pauline_zrtp_ecdh448_rc"); +} static void dtls_srtp_call(void) { call_base(LinphoneMediaEncryptionDTLS,FALSE,FALSE,LinphonePolicyNoFirewall,FALSE); @@ -3652,9 +3662,12 @@ void check_media_direction(LinphoneCoreManager* mgr, LinphoneCall *call, bctbx_l LinphoneCallStats *stats = linphone_call_get_video_stats(call); if (video_dir != LinphoneMediaDirectionInactive){ + LinphoneCallCbs *call_cbs = linphone_factory_create_call_cbs(linphone_factory_get()); BC_ASSERT_TRUE(linphone_call_params_video_enabled(params)); BC_ASSERT_EQUAL(linphone_call_params_get_video_direction(params), video_dir, int, "%d"); - linphone_call_set_next_video_frame_decoded_callback(call,linphone_call_iframe_decoded_cb,mgr->lc); + linphone_call_cbs_set_next_video_frame_decoded(call_cbs, linphone_call_next_video_frame_decoded_cb); + linphone_call_add_callbacks(call, call_cbs); + linphone_call_cbs_unref(call_cbs); linphone_call_send_vfu_request(call); } switch (video_dir) { @@ -5301,11 +5314,13 @@ static void _call_with_network_switch(bool_t use_ice, bool_t with_socket_refresh linphone_call_pause(pauline_call); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallPausedByRemote, 1)); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallPaused, 1)); + wait_for_until(marie->lc, pauline->lc, NULL, 0, 1000); } else if (callee_pause) { marie_call = linphone_core_get_current_call(marie->lc); linphone_call_pause(marie_call); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallPausedByRemote, 1)); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallPaused, 1)); + wait_for_until(marie->lc, pauline->lc, NULL, 0, 1000); } /*marie looses the network and reconnects*/ @@ -6441,6 +6456,7 @@ test_t call_tests[] = { TEST_NO_TAG("ZRTP silent call", zrtp_silent_call), TEST_NO_TAG("ZRTP SAS call", zrtp_sas_call), TEST_NO_TAG("ZRTP Cipher call", zrtp_cipher_call), + TEST_NO_TAG("ZRTP Key Agreement call", zrtp_key_agreement_call), TEST_NO_TAG("DTLS SRTP call", dtls_srtp_call), TEST_NO_TAG("DTLS SRTP call with media relay", dtls_srtp_call_with_media_realy), TEST_NO_TAG("SRTP call with declined srtp", call_with_declined_srtp), diff --git a/tester/call_video_tester.c b/tester/call_video_tester.c index 4b4efb5ad..d96b7b1a3 100644 --- a/tester/call_video_tester.c +++ b/tester/call_video_tester.c @@ -21,6 +21,7 @@ #include "tester_utils.h" #ifdef VIDEO_ENABLED + static void call_paused_resumed_with_video_base_call_cb(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *message) { if (cstate == LinphoneCallUpdatedByRemote) { LinphoneCallParams *params = linphone_core_create_call_params(lc, call); @@ -275,7 +276,7 @@ bool_t request_video(LinphoneCoreManager* caller,LinphoneCoreManager* callee, bo } if (video_added) { - linphone_call_set_next_video_frame_decoded_callback(call_obj,linphone_call_iframe_decoded_cb,callee->lc); + linphone_call_set_first_video_frame_decoded_cb(call_obj); /*send vfu*/ linphone_call_send_vfu_request(call_obj); BC_ASSERT_TRUE(wait_for(caller->lc,callee->lc,&callee->stat.number_of_IframeDecoded,initial_callee_stat.number_of_IframeDecoded+1)); @@ -599,7 +600,7 @@ void video_call_base_2(LinphoneCoreManager* caller,LinphoneCoreManager* callee, BC_ASSERT_TRUE(linphone_call_log_video_enabled(linphone_call_get_call_log(caller_call))); /*check video path*/ - linphone_call_set_next_video_frame_decoded_callback(callee_call,linphone_call_iframe_decoded_cb,callee->lc); + linphone_call_set_first_video_frame_decoded_cb(callee_call); linphone_call_send_vfu_request(callee_call); BC_ASSERT_TRUE( wait_for(callee->lc,caller->lc,&callee->stat.number_of_IframeDecoded,1)); } else { @@ -622,8 +623,8 @@ static void check_fir(LinphoneCoreManager* caller,LinphoneCoreManager* callee ){ /*check video path is established in both directions. Indeed, FIR are ignored until the first RTP packet is received, because SSRC is not known.*/ - linphone_call_set_next_video_frame_decoded_callback(callee_call,linphone_call_iframe_decoded_cb,callee->lc); - linphone_call_set_next_video_frame_decoded_callback(caller_call,linphone_call_iframe_decoded_cb,caller->lc); + linphone_call_set_first_video_frame_decoded_cb(callee_call); + linphone_call_set_first_video_frame_decoded_cb(caller_call); BC_ASSERT_TRUE( wait_for(callee->lc,caller->lc,&callee->stat.number_of_IframeDecoded,1)); BC_ASSERT_TRUE( wait_for(callee->lc,caller->lc,&caller->stat.number_of_IframeDecoded,1)); @@ -639,7 +640,7 @@ static void check_fir(LinphoneCoreManager* caller,LinphoneCoreManager* callee ){ ms_message("check_fir: [%p] received %d FIR ",&caller_call ,caller_vstream->ms_video_stat.counter_rcvd_fir); ms_message("check_fir: [%p] stat number of iframe decoded %d ",&callee_call, callee->stat.number_of_IframeDecoded); - linphone_call_set_next_video_frame_decoded_callback(caller_call,linphone_call_iframe_decoded_cb,caller->lc); + linphone_call_set_first_video_frame_decoded_cb(caller_call); linphone_call_send_vfu_request(caller_call); BC_ASSERT_TRUE( wait_for(callee->lc,caller->lc,&caller->stat.number_of_IframeDecoded,1)); @@ -878,8 +879,8 @@ static void video_call_established_by_reinvite_with_implicit_avpf(void) { BC_ASSERT_TRUE(linphone_call_params_video_enabled(linphone_call_get_current_params(callee_call))); BC_ASSERT_TRUE(linphone_call_params_video_enabled(linphone_call_get_current_params(caller_call))); - linphone_call_set_next_video_frame_decoded_callback(caller_call,linphone_call_iframe_decoded_cb,caller->lc); - linphone_call_set_next_video_frame_decoded_callback(callee_call,linphone_call_iframe_decoded_cb,callee->lc); + linphone_call_set_first_video_frame_decoded_cb(caller_call); + linphone_call_set_first_video_frame_decoded_cb(callee_call); BC_ASSERT_TRUE( wait_for(callee->lc,caller->lc,&callee->stat.number_of_IframeDecoded,1)); BC_ASSERT_TRUE( wait_for(callee->lc,caller->lc,&caller->stat.number_of_IframeDecoded,1)); @@ -1328,10 +1329,7 @@ static void accept_call_in_send_only_base(LinphoneCoreManager* pauline, Linphone /*The send-only client shall set rtp symmetric in absence of media relay for this test.*/ lp_config_set_int(linphone_core_get_config(marie->lc),"rtp","symmetric",1); - linphone_call_set_next_video_frame_decoded_callback(linphone_core_invite_address(pauline->lc,marie->identity) - ,linphone_call_iframe_decoded_cb - ,pauline->lc); - + linphone_call_set_first_video_frame_decoded_cb(linphone_core_invite_address(pauline->lc,marie->identity)); BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallIncomingReceived,1,DEFAULT_WAIT_FOR)); @@ -1693,6 +1691,15 @@ static void video_call_recording_vp8_test(void) { record_call("recording", TRUE, "VP8"); } +static void snapshot_taken(LinphoneCall *call, const char *filepath) { + char *filename = bc_tester_file("snapshot.jpeg"); + LinphoneCore *lc = linphone_call_get_core(call); + stats *callstats = get_stats(lc); + BC_ASSERT_STRING_EQUAL(filepath, filename); + callstats->number_of_snapshot_taken++; + ms_free(filename); +} + static void video_call_snapshot(void) { LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); @@ -1700,7 +1707,6 @@ static void video_call_snapshot(void) { LinphoneCallParams *paulineParams = linphone_core_create_call_params(pauline->lc, NULL); LinphoneCall *callInst = NULL; char *filename = bc_tester_file("snapshot.jpeg"); - int dummy = 0; bool_t call_succeeded = FALSE; linphone_core_enable_video_capture(marie->lc, TRUE); @@ -1712,12 +1718,73 @@ static void video_call_snapshot(void) { BC_ASSERT_TRUE(call_succeeded = call_with_params(marie, pauline, marieParams, paulineParams)); BC_ASSERT_PTR_NOT_NULL(callInst = linphone_core_get_current_call(marie->lc)); - if((call_succeeded == TRUE) && (callInst != NULL)) { + if (call_succeeded == TRUE && callInst != NULL) { + LinphoneCall *marie_call = linphone_core_get_current_call(marie->lc); + LinphoneCallCbs *marie_call_cbs = linphone_factory_create_call_cbs(linphone_factory_get()); + BC_ASSERT_PTR_NOT_NULL(marie_call); + linphone_call_cbs_set_snapshot_taken(marie_call_cbs, snapshot_taken); + linphone_call_add_callbacks(marie_call, marie_call_cbs); + linphone_call_cbs_unref(marie_call_cbs); int jpeg_support = linphone_call_take_video_snapshot(callInst, filename); if (jpeg_support < 0) { ms_warning("No jpegwriter support!"); } else { - wait_for_until(marie->lc, pauline->lc, &dummy, 1, 5000); + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_snapshot_taken,1)); + BC_ASSERT_EQUAL(ortp_file_exist(filename), 0, int, "%d"); + remove(filename); + } + end_call(marie, pauline); + } + ms_free(filename); + linphone_call_params_unref(marieParams); + linphone_call_params_unref(paulineParams); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +static void video_call_snapshots(void) { + LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + LinphoneCallParams *marieParams = linphone_core_create_call_params(marie->lc, NULL); + LinphoneCallParams *paulineParams = linphone_core_create_call_params(pauline->lc, NULL); + LinphoneCall *callInst = NULL; + char *filename = bc_tester_file("snapshot.jpeg"); + bool_t call_succeeded = FALSE; + int dummy = 0; + + linphone_core_enable_video_capture(marie->lc, TRUE); + linphone_core_enable_video_display(marie->lc, TRUE); + linphone_core_enable_video_capture(pauline->lc, TRUE); + linphone_core_enable_video_display(pauline->lc, FALSE); + linphone_call_params_enable_video(marieParams, TRUE); + linphone_call_params_enable_video(paulineParams, TRUE); + + BC_ASSERT_TRUE(call_succeeded = call_with_params(marie, pauline, marieParams, paulineParams)); + BC_ASSERT_PTR_NOT_NULL(callInst = linphone_core_get_current_call(marie->lc)); + if (call_succeeded == TRUE && callInst != NULL) { + LinphoneCall *marie_call = linphone_core_get_current_call(marie->lc); + LinphoneCallCbs *marie_call_cbs = linphone_factory_create_call_cbs(linphone_factory_get()); + BC_ASSERT_PTR_NOT_NULL(marie_call); + linphone_call_cbs_set_snapshot_taken(marie_call_cbs, snapshot_taken); + linphone_call_add_callbacks(marie_call, marie_call_cbs); + linphone_call_cbs_unref(marie_call_cbs); + int jpeg_support = linphone_call_take_video_snapshot(callInst, filename); + if (jpeg_support < 0) { + ms_warning("No jpegwriter support!"); + } else { + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_snapshot_taken,1)); + BC_ASSERT_EQUAL(ortp_file_exist(filename), 0, int, "%d"); + remove(filename); + + wait_for_until(marie->lc, pauline->lc, &dummy, 1, 1000); + linphone_call_take_video_snapshot(callInst, filename); + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_snapshot_taken,2)); + BC_ASSERT_EQUAL(ortp_file_exist(filename), 0, int, "%d"); + remove(filename); + + wait_for_until(marie->lc, pauline->lc, &dummy, 1, 1000); + linphone_call_take_video_snapshot(callInst, filename); + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_snapshot_taken,3)); BC_ASSERT_EQUAL(ortp_file_exist(filename), 0, int, "%d"); remove(filename); } @@ -1894,7 +1961,6 @@ static void outgoing_reinvite_with_invalid_ack_sdp(void) { linphone_core_manager_destroy(caller); } -#endif static void video_call_with_no_audio_and_no_video_codec(void){ LinphoneCoreManager* callee = linphone_core_manager_new("marie_rc"); LinphoneCoreManager* caller = linphone_core_manager_new(transport_supported(LinphoneTransportTcp) ? "pauline_rc" : "pauline_tcp_rc"); @@ -2164,7 +2230,6 @@ static void video_call_expected_fps_for_high_bandwidth(void) { } test_t call_video_tests[] = { -#ifdef VIDEO_ENABLED TEST_NO_TAG("Call paused resumed with video", call_paused_resumed_with_video), TEST_NO_TAG("Call paused resumed with video no sdp ack", call_paused_resumed_with_no_sdp_ack), TEST_NO_TAG("Call paused resumed with video no sdk ack using video policy for resume offers", call_paused_resumed_with_no_sdp_ack_using_video_policy), @@ -2213,6 +2278,7 @@ test_t call_video_tests[] = { TEST_NO_TAG("Video call recording (H264)", video_call_recording_h264_test), TEST_NO_TAG("Video call recording (VP8)", video_call_recording_vp8_test), TEST_NO_TAG("Snapshot", video_call_snapshot), + TEST_NO_TAG("Snapshots", video_call_snapshots), TEST_NO_TAG("Video call with early media and no matching audio codecs", video_call_with_early_media_no_matching_audio_codecs), TEST_NO_TAG("DTLS SRTP video call", dtls_srtp_video_call), TEST_ONE_TAG("DTLS SRTP ice video call", dtls_srtp_ice_video_call, "ICE"), @@ -2235,8 +2301,9 @@ test_t call_video_tests[] = { TEST_NO_TAG("Video call expected FPS for low bandwidth", video_call_expected_fps_for_low_bandwidth), TEST_NO_TAG("Video call expected FPS for regular bandwidth", video_call_expected_fps_for_regular_bandwidth), TEST_NO_TAG("Video call expected FPS for high bandwidth", video_call_expected_fps_for_high_bandwidth) -#endif }; test_suite_t call_video_test_suite = {"Video Call", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each, sizeof(call_video_tests) / sizeof(call_video_tests[0]), call_video_tests}; + +#endif // ifdef VIDEO_ENABLED diff --git a/tester/complex_sip_case_tester.c b/tester/complex_sip_case_tester.c index 60a671629..fc2ad0c43 100644 --- a/tester/complex_sip_case_tester.c +++ b/tester/complex_sip_case_tester.c @@ -58,15 +58,18 @@ FILE *sip_start(const char *senario, const char* dest_username, const char *pass char *dest; char *command; FILE *file; - + char local_ip[64]; if (linphone_address_get_port(dest_addres)>0) dest = ms_strdup_printf("%s:%i",linphone_address_get_domain(dest_addres),linphone_address_get_port(dest_addres)); else dest = ms_strdup_printf("%s",linphone_address_get_domain(dest_addres)); + + linphone_core_get_local_ip_for(AF_INET, linphone_address_get_domain(dest_addres), local_ip); //until errors logs are handled correctly and stop breaks output, they will be DISABLED - command = ms_strdup_printf(SIPP_COMMAND" -sf %s -s %s %s -trace_err -trace_msg -rtp_echo -m 1 -d 1000 -ap %s 2>/dev/null",senario + command = ms_strdup_printf(SIPP_COMMAND" -sf %s -s %s %s -i %s -trace_err -trace_msg -rtp_echo -m 1 -d 1000 -ap %s 2>/dev/null",senario ,dest_username ,dest + ,local_ip ,(passwd?passwd:"none")); ms_message("Starting sipp command [%s]",command); @@ -109,8 +112,8 @@ LinphoneAddress * linphone_core_manager_resolve(LinphoneCoreManager *mgr, const ,&addrinfo); dest=linphone_address_new(NULL); - - wait_for(mgr->lc, mgr->lc, (int*)&addrinfo, 1); + + wait_for_until(mgr->lc, mgr->lc, (int*)&addrinfo, 1,2000); err=bctbx_getnameinfo((struct sockaddr*)addrinfo->ai_addr,addrinfo->ai_addrlen,ipstring,INET6_ADDRSTRLEN,NULL,0,NI_NUMERICHOST); if (err !=0 ){ ms_error("linphone_core_manager_resolve(): getnameinfo error %s", gai_strerror(err)); @@ -168,7 +171,7 @@ static void call_with_audio_mline_before_video_in_sdp(void) { linphone_core_iterate(mgr->lc); scen = bc_tester_res("sipp/call_with_audio_mline_before_video_in_sdp.xml"); - + sipp_out = sip_start(scen, linphone_address_get_username(mgr->identity), NULL, mgr->identity); if (sipp_out) { @@ -365,12 +368,23 @@ static test_t tests[] = { }; #endif +static bool_t previous_liblinphonetester_ipv6; +static void before_each(void) { + previous_liblinphonetester_ipv6=liblinphonetester_ipv6; + liblinphonetester_ipv6=FALSE; /*sipp do not support ipv6 and remote port*/ + liblinphone_tester_before_each(); +} +static void after_each(void) { + liblinphonetester_ipv6=previous_liblinphonetester_ipv6; + liblinphone_tester_after_each(); +} + test_suite_t complex_sip_call_test_suite = { "Complex SIP Case", NULL, NULL, - liblinphone_tester_before_each, - liblinphone_tester_after_each, + before_each, + after_each, #if HAVE_SIPP sizeof(tests) / sizeof(tests[0]), tests diff --git a/tester/content-manager-tester.cpp b/tester/contents-tester.cpp similarity index 62% rename from tester/content-manager-tester.cpp rename to tester/contents-tester.cpp index e21cc6399..99ecee08d 100644 --- a/tester/content-manager-tester.cpp +++ b/tester/contents-tester.cpp @@ -21,13 +21,15 @@ #include "content/content-manager.h" #include "content/content-type.h" #include "content/content.h" +#include "content/header/header-param.h" #include "liblinphone_tester.h" #include "tester_utils.h" +#include "logger/logger.h" using namespace LinphonePrivate; using namespace std; -static const char* multipart = \ +static const char* source_multipart = \ "-----------------------------14737809831466499882746641449\r\n" \ "Content-Type: application/rlmi+xml;charset=\"UTF-8\"\r\n\r\n" \ "" \ @@ -60,6 +62,7 @@ static const char* multipart = \ " " \ "" \ "-----------------------------14737809831466499882746641449\r\n" \ +"Content-Encoding: b64\r\n" \ "Content-Type: application/pidf+xml;charset=\"UTF-8\"\r\n\r\n" \ "" \ "" \ @@ -77,6 +80,7 @@ static const char* multipart = \ " " \ "" \ "-----------------------------14737809831466499882746641449\r\n" \ +"Content-Id: toto;param1=value1;param2;param3=value3\r\n" \ "Content-Type: application/pidf+xml;charset=\"UTF-8\"\r\n\r\n" \ "" \ "" \ @@ -95,6 +99,80 @@ static const char* multipart = \ "" \ "-----------------------------14737809831466499882746641449--\r\n"; +static const char* generated_multipart = \ +"-----------------------------14737809831466499882746641449\r\n" \ +"Content-Type: application/rlmi+xml;charset=\"UTF-8\"\r\n" \ +"Content-Length:582\r\n\r\n" \ +"" \ +"" \ +" " \ +" " \ +" " \ +" " \ +" " \ +" " \ +" " \ +" " \ +" " \ +"" \ +"-----------------------------14737809831466499882746641449\r\n" \ +"Content-Type: application/pidf+xml;charset=\"UTF-8\"\r\n" \ +"Content-Length:561\r\n\r\n" \ +"" \ +"" \ +" " \ +" " \ +" open" \ +" " \ +" sip:+YYYYYYYYYY@sip.linphone.org;user=phone" \ +" 2017-10-25T13:18:26" \ +" " \ +" " \ +" " \ +" " \ +" " \ +" " \ +"" \ +"-----------------------------14737809831466499882746641449\r\n" \ +"Content-Encoding:b64\r\n" \ +"Content-Type: application/pidf+xml;charset=\"UTF-8\"\r\n" \ +"Content-Length:561\r\n\r\n" \ +"" \ +"" \ +" " \ +" " \ +" open" \ +" " \ +" sip:+XXXXXXXXXX@sip.linphone.org;user=phone" \ +" 2017-10-25T13:18:26" \ +" " \ +" " \ +" " \ +" " \ +" " \ +" " \ +"" \ +"-----------------------------14737809831466499882746641449\r\n" \ +"Content-Id:toto;param1=value1;param2;param3=value3\r\n" \ +"Content-Type: application/pidf+xml;charset=\"UTF-8\"\r\n" \ +"Content-Length:546\r\n\r\n" \ +"" \ +"" \ +" " \ +" " \ +" open" \ +" " \ +" sip:someone@sip.linphone.org" \ +" 2017-10-25T13:18:26" \ +" " \ +" " \ +" " \ +" " \ +" " \ +" " \ +"" \ +"-----------------------------14737809831466499882746641449--\r\n"; + static const char* part1 = \ "" \ "" \ @@ -162,7 +240,7 @@ static const char* part4 = \ void multipart_to_list () { Content multipartContent; - multipartContent.setBody(multipart); + multipartContent.setBody(source_multipart); multipartContent.setContentType(ContentType("multipart", "related")); list contents = ContentManager::multipartToContentList(multipartContent); @@ -220,6 +298,7 @@ void multipart_to_list () { ms_message("\n\n----- Original part 3 -----"); ms_message("%s", originalStr3.c_str()); BC_ASSERT_TRUE(originalStr3 == generatedStr3); + BC_ASSERT_TRUE(content3.getHeader("Content-Encoding").getValue() == "b64"); Content content4 = contents.front(); contents.pop_front(); @@ -234,29 +313,43 @@ void multipart_to_list () { generatedStr4.erase(std::remove(generatedStr4.begin(), generatedStr4.end(), '\r'), generatedStr4.end()); generatedStr4.erase(std::remove(generatedStr4.begin(), generatedStr4.end(), '\n'), generatedStr4.end()); ms_message("\n\n----- Generated part 4 -----"); - ms_message("%s", generatedStr3.c_str()); + ms_message("%s", generatedStr4.c_str()); ms_message("\n\n----- Original part 4 -----"); ms_message("%s", originalStr4.c_str()); BC_ASSERT_TRUE(originalStr4 == generatedStr4); + BC_ASSERT_TRUE(content4.getHeader("Content-Id").getValue() == "toto"); + BC_ASSERT_TRUE(content4.getHeader("Content-Id").getParameter("param1").getValue() == "value1"); + BC_ASSERT_TRUE(content4.getHeader("Content-Id").getParameter("param2").getValue().empty()); + BC_ASSERT_TRUE(content4.getHeader("Content-Id").getParameter("param3").getValue() == "value3"); } void list_to_multipart () { + ContentType contentType = ContentType("application", "rlmi+xml"); + contentType.addParameter("charset", "\"UTF-8\""); Content content1; content1.setBody(part1); - content1.setContentType(ContentType("application", "rlmi+xml")); + content1.setContentType(contentType); + contentType = ContentType("application", "pidf+xml"); + contentType.addParameter("charset", "\"UTF-8\""); Content content2; content2.setBody(part2); - content2.setContentType(ContentType("application", "pidf+xml")); + content2.setContentType(contentType); Content content3; content3.setBody(part3); - content3.setContentType(ContentType("application", "pidf+xml")); + content3.addHeader("Content-Encoding", "b64"); + content3.setContentType(contentType); Content content4; + Header header = Header("Content-Id", "toto"); + header.addParameter("param1", "value1"); + header.addParameter("param2", ""); + header.addParameter("param3", "value3"); + content4.addHeader(header); content4.setBody(part4); - content4.setContentType(ContentType("application", "pidf+xml")); - list contents = {content1, content2, content3, content4}; + content4.setContentType(contentType); + list contents = {&content1, &content2, &content3, &content4}; Content multipartContent = ContentManager::contentListToMultipart(contents); - string originalStr(multipart); + string originalStr(generated_multipart); originalStr.erase(std::remove(originalStr.begin(), originalStr.end(), ' '), originalStr.end()); originalStr.erase(std::remove(originalStr.begin(), originalStr.end(), '\t'), originalStr.end()); originalStr.erase(std::remove(originalStr.begin(), originalStr.end(), '\r'), originalStr.end()); @@ -276,16 +369,67 @@ void list_to_multipart () { BC_ASSERT_TRUE(originalStr == generatedStr); } -test_t content_manager_tests[] = { +static void content_type_parsing(void) { + string type = "message/external-body;access-type=URL;URL=\"https://www.linphone.org/img/linphone-open-source-voip-projectX2.png\""; + ContentType contentType = ContentType(type); + BC_ASSERT_STRING_EQUAL("message", contentType.getType().c_str()); + BC_ASSERT_STRING_EQUAL("external-body", contentType.getSubType().c_str()); + BC_ASSERT_STRING_EQUAL("URL", contentType.getParameter("access-type").getValue().c_str()); + BC_ASSERT_STRING_EQUAL("\"https://www.linphone.org/img/linphone-open-source-voip-projectX2.png\"", contentType.getParameter("URL").getValue().c_str()); + BC_ASSERT_STRING_EQUAL("", contentType.getParameter("boundary").getValue().c_str()); + BC_ASSERT_EQUAL(2, contentType.getParameters().size(), int, "%d"); + lInfo() << "Content-Type is " << contentType; + BC_ASSERT_TRUE(type == contentType.asString()); + + type = "multipart/mixed;boundary=-----------------------------14737809831466499882746641450"; + contentType = ContentType(type); + BC_ASSERT_STRING_EQUAL("multipart", contentType.getType().c_str()); + BC_ASSERT_STRING_EQUAL("mixed", contentType.getSubType().c_str()); + BC_ASSERT_STRING_EQUAL("-----------------------------14737809831466499882746641450", contentType.getParameter("boundary").getValue().c_str()); + BC_ASSERT_STRING_EQUAL("", contentType.getParameter("access-type").getValue().c_str()); + BC_ASSERT_EQUAL(1, contentType.getParameters().size(), int, "%d"); + lInfo() << "Content-Type is " << contentType; + BC_ASSERT_TRUE(type == contentType.asString()); + + type = "plain/text"; + contentType = ContentType(type); + BC_ASSERT_STRING_EQUAL("plain", contentType.getType().c_str()); + BC_ASSERT_STRING_EQUAL("text", contentType.getSubType().c_str()); + BC_ASSERT_STRING_EQUAL("", contentType.getParameter("boundary").getValue().c_str()); + BC_ASSERT_EQUAL(0, contentType.getParameters().size(), int, "%d"); + lInfo() << "Content-Type is " << contentType; + BC_ASSERT_TRUE(type == contentType.asString()); +} + +static void content_header_parsing(void) { + string value = "toto;param1=value1;param2;param3=value3"; + Header header = Header("Content-Id", value); + BC_ASSERT_TRUE(header.getValue() == "toto"); + BC_ASSERT_TRUE(header.getParameter("param1").getValue() == "value1"); + BC_ASSERT_TRUE(header.getParameter("param2").getValue().empty()); + BC_ASSERT_TRUE(header.getParameter("param3").getValue() == "value3"); + BC_ASSERT_EQUAL(3, header.getParameters().size(), int, "%d"); + BC_ASSERT_STRING_EQUAL("", header.getParameter("encoding").getValue().c_str()); + + value = "b64"; + header = Header("Content-Encoding", value); + BC_ASSERT_TRUE(header.getValue() == value); + BC_ASSERT_EQUAL(0, header.getParameters().size(), int, "%d"); + BC_ASSERT_STRING_EQUAL("", header.getParameter("access-type").getValue().c_str()); +} + +test_t contents_tests[] = { TEST_NO_TAG("Multipart to list", multipart_to_list), - TEST_NO_TAG("List to multipart", list_to_multipart) + TEST_NO_TAG("List to multipart", list_to_multipart), + TEST_NO_TAG("Content type parsing", content_type_parsing), + TEST_NO_TAG("Content header parsing", content_header_parsing) }; -test_suite_t content_manager_test_suite = { - "Content manager", +test_suite_t contents_test_suite = { + "Contents", nullptr, nullptr, liblinphone_tester_before_each, liblinphone_tester_after_each, - sizeof(content_manager_tests) / sizeof(content_manager_tests[0]), content_manager_tests + sizeof(contents_tests) / sizeof(contents_tests[0]), contents_tests }; diff --git a/tester/cpim-tester.cpp b/tester/cpim-tester.cpp index e803ae33a..ec1f8338a 100644 --- a/tester/cpim-tester.cpp +++ b/tester/cpim-tester.cpp @@ -37,7 +37,7 @@ using namespace std; using namespace LinphonePrivate; static void parse_minimal_message () { - const string str = "Content-type: Message/CPIM\r\n" + const string str = "Subject: the weather will be fine today\r\n" "\r\n" "Content-Type: text/plain; charset=utf-8\r\n" "\r\n"; @@ -48,18 +48,12 @@ static void parse_minimal_message () { const string str2 = message->asString(); BC_ASSERT_STRING_EQUAL(str2.c_str(), str.c_str()); - BC_ASSERT_STRING_EQUAL(message->getContent().c_str(), ""); + const string content = message->getContent(); + BC_ASSERT_STRING_EQUAL(content.c_str(), ""); } static void set_generic_header_name () { const list > entries = { - { "toto", true }, - { "george.abitbol", true }, - { "tata/titi", false }, - { "hey ho", false }, - { " fail", false }, - { "fail2 ", false }, - // Reserved. { "From", false }, { "To", false }, @@ -67,59 +61,19 @@ static void set_generic_header_name () { { "DateTime", false }, { "Subject", false }, { "NS", false }, - { "Require", false }, - - // Case sensitivity. - { "FROM", true }, - { "to", true }, - { "cC", true }, - { "Datetime", true }, - { "SuBject", true }, - { "nS", true }, - { "requirE", true } + { "Require", false } }; for (const auto &entry : entries) { - Cpim::GenericHeader genericHeader; - - const bool result = genericHeader.setName(entry.first); - BC_ASSERT_EQUAL(result, entry.second, bool, "%d"); + Cpim::GenericHeader genericHeader(entry.first, ""); const string name = genericHeader.getName(); - - if (result) - BC_ASSERT_STRING_EQUAL(name.c_str(), entry.first.c_str()); - else - BC_ASSERT_STRING_EQUAL(name.c_str(), ""); - } -} - -static void set_generic_header_value () { - const list > entries = { - { "MyFeatures ", true }, - { "2000-12-13T13:40:00-08:00", true }, - { "2000-12-13T13:40:00-08:00", true }, - { "text/xml; charset=utf-8", true }, - { "text/xml; charset=ut\r\nf-8", false } - }; - - for (const auto &entry : entries) { - Cpim::GenericHeader genericHeader; - - const bool result = genericHeader.setValue(entry.first); - BC_ASSERT_EQUAL(result, entry.second, bool, "%d"); - - const string value = genericHeader.getValue(); - - if (result) - BC_ASSERT_STRING_EQUAL(value.c_str(), entry.first.c_str()); - else - BC_ASSERT_STRING_EQUAL(value.c_str(), ""); + BC_ASSERT_STRING_EQUAL(name.c_str(), ""); } } static void check_core_header_names () { - const list, string> > entries = { + const list, string> > entries = { { make_shared(), "From" }, { make_shared(), "To" }, { make_shared(), "cc" }, @@ -135,118 +89,13 @@ static void check_core_header_names () { } } -static void set_core_header_values () { - const list, list > > > entries = { - { make_shared(), { - { "Winnie the Pooh ", true }, - { "", true }, - { "", true }, - { "toto", false } - } }, - { make_shared(), { - { "", true }, - { "toto", false }, - { "", true }, - { "", true } - } }, - { make_shared(), { - { "", true }, - { "", true }, - { "", true }, - { "toto", false } - } }, - { make_shared(), { - { "abcd", false }, - { "1985-04-12T23:20:50.52Z", true }, - { "1996-12-19T16:39:57-08:00", true }, - { "1990-12-31T23:59:60Z", true }, - { "1990-12-31T15:59:60-08:00", true }, - { "2001-02-29T10:10:10Z", false }, - { "2000-02-29T10:10:10Z", true }, - { "1937-01-01T12:00:27.87+00:20", true }, - { "1937-01-01T12:00:27.87Z", true }, - { "1956", false } - } }, - { make_shared(), { - { "Eeyore's feeling very depressed today", true }, - { "🤣", true }, - { "hello", true } - } }, - { make_shared(), { - { "MyAlias ", true }, - { "What is this? - Barry Burton", false }, - { "", true }, - { "(), { - { "MyAlias.VitalHeader", true }, - { "MyAlias.VitalHeader,Test", true }, - { "MyAlias.VitalHeader,🤣", false } - } } - }; - - for (const auto &entry : entries) { - const shared_ptr header = entry.first; - string previousValue; - - for (const auto &test : entry.second) { - const bool result = header->setValue(test.first); - BC_ASSERT_EQUAL(result, test.second, bool, "%d"); - - const string value = header->getValue(); - - if (result) - BC_ASSERT_STRING_EQUAL(value.c_str(), test.first.c_str()); - else - BC_ASSERT_STRING_EQUAL(value.c_str(), previousValue.c_str()); - - previousValue = value; - } - } -} - -static void check_subject_header_language () { - Cpim::SubjectHeader subjectHeader; - - // Check for not defined language. - { - const string language = subjectHeader.getLanguage(); - BC_ASSERT_STRING_EQUAL(language.c_str(), ""); - } - - // Set valid language. - { - const string languageToSet = "fr"; - - BC_ASSERT_TRUE(subjectHeader.setLanguage(languageToSet)); - BC_ASSERT_TRUE(languageToSet == subjectHeader.getLanguage()); - - const string str = subjectHeader.asString(); - const string expected = "Subject:;lang=" + languageToSet + " \r\n"; - BC_ASSERT_STRING_EQUAL(str.c_str(), expected.c_str()); - } - - // Set invalid language. - { - const string languageToSet = "fr--"; - BC_ASSERT_FALSE(subjectHeader.setLanguage(languageToSet)); - BC_ASSERT_FALSE(languageToSet == subjectHeader.getLanguage()); - BC_ASSERT_FALSE(subjectHeader.isValid()); - } -} - static void parse_rfc_example () { const string body = "" "Here is the text of my message." ""; - const string str = "Content-type: Message/CPIM\r\n" - "\r\n" - "From: MR SANDERS \r\n" - "To: Depressed Donkey \r\n" + const string str = "From: \"MR SANDERS\"\r\n" + "To: \"Depressed Donkey\"\r\n" "DateTime: 2000-12-13T13:40:00-08:00\r\n" "Subject: the weather will be fine today\r\n" "Subject:;lang=fr beau temps prevu pour aujourd'hui\r\n" @@ -267,6 +116,14 @@ static void parse_rfc_example () { string content = message->getContent(); BC_ASSERT_STRING_EQUAL(content.c_str(), body.c_str()); + + Cpim::Message::HeaderList list = message->getMessageHeaders(); + if (!BC_ASSERT_PTR_NOT_NULL(list)) return; + BC_ASSERT_EQUAL(list->size(), 7, int, "%d"); + + list = message->getMessageHeaders("MyFeatures"); + if (!BC_ASSERT_PTR_NOT_NULL(list)) return; + BC_ASSERT_EQUAL(list->size(), 2, int, "%d"); } static void parse_message_with_generic_header_parameters () { @@ -274,9 +131,7 @@ static void parse_message_with_generic_header_parameters () { "Here is the text of my message." ""; - const string str = "Content-type: Message/CPIM\r\n" - "\r\n" - "From: MR SANDERS \r\n" + const string str = "From: \"MR SANDERS\"\r\n" "Test:;aaa=bbb;yes=no CheckMe\r\n" "yaya: coucou\r\n" "yepee:;good=bad ugly\r\n" @@ -297,81 +152,55 @@ static void parse_message_with_generic_header_parameters () { static void build_message () { Cpim::Message message; - if (!BC_ASSERT_FALSE(message.isValid())) - return; - - // Set CPIM headers. - Cpim::GenericHeader cpimContentTypeHeader; - if (!BC_ASSERT_TRUE(cpimContentTypeHeader.setName("Content-Type"))) return; - if (!BC_ASSERT_TRUE(cpimContentTypeHeader.setValue("Message/CPIM"))) return; - - if (!BC_ASSERT_TRUE(message.addCpimHeader(cpimContentTypeHeader))) return; // Set message headers. - Cpim::FromHeader fromHeader; - if (!BC_ASSERT_TRUE(fromHeader.setValue("MR SANDERS "))) return; + Cpim::FromHeader fromHeader("im:piglet@100akerwood.com", "MR SANDERS"); - Cpim::ToHeader toHeader; - if (!BC_ASSERT_TRUE(toHeader.setValue("Depressed Donkey "))) return; + Cpim::ToHeader toHeader("im:eeyore@100akerwood.com", "Depressed Donkey"); - Cpim::DateTimeHeader dateTimeHeader; - if (!BC_ASSERT_TRUE(dateTimeHeader.setValue("2000-12-13T13:40:00-08:00"))) return; + // 976686000 is 2000-12-13T13:40:00-08:00 + Cpim::DateTimeHeader dateTimeHeader(976686000); + BC_ASSERT_EQUAL(dateTimeHeader.getTime(), 976686000, int, "%d"); - Cpim::SubjectHeader subjectHeader; - if (!BC_ASSERT_TRUE(subjectHeader.setValue("the weather will be fine today"))) return; + Cpim::SubjectHeader subjectHeader("the weather will be fine today"); - Cpim::SubjectHeader subjectWithLanguageHeader; - if (!BC_ASSERT_TRUE(subjectWithLanguageHeader.setValue("beau temps prevu pour aujourd'hui"))) return; - if (!BC_ASSERT_TRUE(subjectWithLanguageHeader.setLanguage("fr"))) return; + Cpim::SubjectHeader subjectWithLanguageHeader("beau temps prevu pour aujourd'hui", "fr"); - Cpim::NsHeader nsHeader; - if (!BC_ASSERT_TRUE(nsHeader.setValue("MyFeatures "))) return; + Cpim::NsHeader nsHeader("mid:MessageFeatures@id.foo.com", "MyFeatures"); - Cpim::RequireHeader requireHeader; - if (!BC_ASSERT_TRUE(requireHeader.setValue("MyFeatures.VitalMessageOption"))) return; + Cpim::RequireHeader requireHeader("MyFeatures.VitalMessageOption"); - Cpim::GenericHeader vitalMessageHeader; - if (!BC_ASSERT_TRUE(vitalMessageHeader.setName("MyFeatures.VitalMessageOption"))) return; - if (!BC_ASSERT_TRUE(vitalMessageHeader.setValue("Confirmation-requested"))) return; + Cpim::GenericHeader vitalMessageHeader("MyFeatures.VitalMessageOption", "Confirmation-requested"); - Cpim::GenericHeader wackyMessageHeader; - if (!BC_ASSERT_TRUE(wackyMessageHeader.setName("MyFeatures.WackyMessageOption"))) return; - if (!BC_ASSERT_TRUE(wackyMessageHeader.setValue("Use-silly-font"))) return; + Cpim::GenericHeader wackyMessageHeader("MyFeatures.WackyMessageOption", "Use-silly-font"); - if (!BC_ASSERT_TRUE(message.addMessageHeader(fromHeader))) return; - if (!BC_ASSERT_TRUE(message.addMessageHeader(toHeader))) return; - if (!BC_ASSERT_TRUE(message.addMessageHeader(dateTimeHeader))) return; - if (!BC_ASSERT_TRUE(message.addMessageHeader(subjectHeader))) return; - if (!BC_ASSERT_TRUE(message.addMessageHeader(subjectWithLanguageHeader))) return; - if (!BC_ASSERT_TRUE(message.addMessageHeader(nsHeader))) return; - if (!BC_ASSERT_TRUE(message.addMessageHeader(requireHeader))) return; - if (!BC_ASSERT_TRUE(message.addMessageHeader(vitalMessageHeader))) return; - if (!BC_ASSERT_TRUE(message.addMessageHeader(wackyMessageHeader))) return; + message.addMessageHeader(fromHeader); + message.addMessageHeader(toHeader); + message.addMessageHeader(dateTimeHeader); + message.addMessageHeader(subjectHeader); + message.addMessageHeader(subjectWithLanguageHeader); + message.addMessageHeader(nsHeader); + message.addMessageHeader(requireHeader); + message.addMessageHeader(vitalMessageHeader); + message.addMessageHeader(wackyMessageHeader); // Set Content headers. - Cpim::GenericHeader contentTypeHeader; - if (!BC_ASSERT_TRUE(contentTypeHeader.setName("Content-Type"))) return; - if (!BC_ASSERT_TRUE( contentTypeHeader.setValue("text/xml; charset=utf-8"))) return; - if (!BC_ASSERT_TRUE(message.addContentHeader(contentTypeHeader))) return; + Cpim::GenericHeader contentTypeHeader("Content-Type", "text/xml; charset=utf-8"); + message.addContentHeader(contentTypeHeader); - Cpim::GenericHeader contentIdHeader; - if (!BC_ASSERT_TRUE(contentIdHeader.setName("Content-ID"))) return; - if (!BC_ASSERT_TRUE( contentIdHeader.setValue("<1234567890@foo.com>"))) return; - if (!BC_ASSERT_TRUE(message.addContentHeader(contentIdHeader))) return; + Cpim::GenericHeader contentIdHeader("Content-ID", "<1234567890@foo.com>"); + message.addContentHeader(contentIdHeader); const string content = "" "Here is the text of my message." ""; if (!BC_ASSERT_TRUE(message.setContent(content))) return; - if (!BC_ASSERT_TRUE(message.isValid())) return; const string strMessage = message.asString(); - const string expectedMessage = "Content-Type: Message/CPIM\r\n" - "\r\n" - "From: MR SANDERS \r\n" - "To: Depressed Donkey \r\n" - "DateTime: 2000-12-13T13:40:00-08:00\r\n" + const string expectedMessage = "From: \"MR SANDERS\"\r\n" + "To: \"Depressed Donkey\"\r\n" + "DateTime: 2000-12-13T05:40:00Z\r\n" "Subject: the weather will be fine today\r\n" "Subject:;lang=fr beau temps prevu pour aujourd'hui\r\n" "NS: MyFeatures \r\n" @@ -389,21 +218,33 @@ static void build_message () { BC_ASSERT_STRING_EQUAL(strMessage.c_str(), expectedMessage.c_str()); } -static int fake_im_encryption_engine_process_incoming_message_cb(LinphoneImEncryptionEngine *engine, LinphoneChatRoom *room, LinphoneChatMessage *msg) { - BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_content_type(msg), ContentType::Cpim.asString().c_str()); // Encryption is the first receiving step, so this message should be CPIM +static int fake_im_encryption_engine_process_incoming_message_cb ( + LinphoneImEncryptionEngine *engine, + LinphoneChatRoom *room, + LinphoneChatMessage *msg +) { + // Encryption is the first receiving step, so this message should be CPIM. + const string expected = ContentType::Cpim.asString(); + BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_content_type(msg), expected.c_str()); return -1; } -static int fake_im_encryption_engine_process_outgoing_message_cb(LinphoneImEncryptionEngine *engine, LinphoneChatRoom *room, LinphoneChatMessage *msg) { - BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_content_type(msg), ContentType::Cpim.asString().c_str()); // Encryption is the last sending step, so this message should be CPIM +static int fake_im_encryption_engine_process_outgoing_message_cb ( + LinphoneImEncryptionEngine *engine, + LinphoneChatRoom *room, + LinphoneChatMessage *msg +) { + // Encryption is the last sending step, so this message should be CPIM. + const string expected = ContentType::Cpim.asString(); + BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_content_type(msg), expected.c_str()); return -1; } -static void cpim_chat_message_modifier_base(bool_t use_multipart) { +static void cpim_chat_message_modifier_base (bool useMultipart) { LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); - // We use a fake encryption engine just to check the internal content type during the sending/receiving process + // We use a fake encryption engine just to check the internal content type during the sending/receiving process. LinphoneImEncryptionEngine *marie_imee = linphone_im_encryption_engine_new(); LinphoneImEncryptionEngineCbs *marie_cbs = linphone_im_encryption_engine_get_callbacks(marie_imee); LinphoneImEncryptionEngine *pauline_imee = linphone_im_encryption_engine_new(); @@ -413,29 +254,36 @@ static void cpim_chat_message_modifier_base(bool_t use_multipart) { linphone_core_set_im_encryption_engine(marie->lc, marie_imee); linphone_core_set_im_encryption_engine(pauline->lc, pauline_imee); - IdentityAddress paulineAddress(linphone_address_as_string_uri_only(pauline->identity)); + char *paulineUri = linphone_address_as_string_uri_only(pauline->identity); + IdentityAddress paulineAddress(paulineUri); + bctbx_free(paulineUri); + shared_ptr marieRoom = marie->lc->cppPtr->getOrCreateBasicChatRoom(paulineAddress); marieRoom->allowCpim(true); shared_ptr marieMessage = marieRoom->createChatMessage("Hello CPIM"); - if (use_multipart) { + if (useMultipart) { marieRoom->allowMultipart(true); Content *content = new Content(); content->setContentType(ContentType::PlainText); content->setBody("Hello Part 2"); - marieMessage->addContent(*content); + marieMessage->addContent(content); } marieMessage->send(); BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageReceived,1)); - BC_ASSERT_STRING_EQUAL(marieMessage->getInternalContent().getContentType().asString().c_str(), ""); // Internal content is cleaned after message is sent or received + BC_ASSERT_TRUE(marieMessage->getInternalContent().getContentType().isEmpty()); // Internal content is cleaned after message is sent or received BC_ASSERT_PTR_NOT_NULL(pauline->stat.last_received_chat_message); if (pauline->stat.last_received_chat_message != NULL) { BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), "Hello CPIM"); - BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_content_type(pauline->stat.last_received_chat_message), ContentType::PlainText.asString().c_str()); + const string expected = ContentType::PlainText.asString(); + BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_content_type(pauline->stat.last_received_chat_message), expected.c_str()); } + marieMessage.reset(); + marieRoom.reset(); + linphone_im_encryption_engine_unref(marie_imee); linphone_im_encryption_engine_unref(pauline_imee); @@ -443,26 +291,23 @@ static void cpim_chat_message_modifier_base(bool_t use_multipart) { linphone_core_manager_destroy(pauline); } -static void cpim_chat_message_modifier(void) { +static void cpim_chat_message_modifier () { cpim_chat_message_modifier_base(FALSE); } -static void cpim_chat_message_modifier_with_multipart_body(void) { +static void cpim_chat_message_modifier_with_multipart_body () { cpim_chat_message_modifier_base(TRUE); } test_t cpim_tests[] = { TEST_NO_TAG("Parse minimal CPIM message", parse_minimal_message), TEST_NO_TAG("Set generic header name", set_generic_header_name), - TEST_NO_TAG("Set generic header value", set_generic_header_value), TEST_NO_TAG("Check core header names", check_core_header_names), - TEST_NO_TAG("Set core header values", set_core_header_values), - TEST_NO_TAG("Check Subject header language", check_subject_header_language), TEST_NO_TAG("Parse RFC example", parse_rfc_example), TEST_NO_TAG("Parse Message with generic header parameters", parse_message_with_generic_header_parameters), TEST_NO_TAG("Build Message", build_message), TEST_NO_TAG("CPIM chat message modifier", cpim_chat_message_modifier), - TEST_NO_TAG("CPIM chat message modifier with multipart body", cpim_chat_message_modifier_with_multipart_body), + TEST_NO_TAG("CPIM chat message modifier with multipart body", cpim_chat_message_modifier_with_multipart_body) }; test_suite_t cpim_test_suite = { diff --git a/tester/dtmf_tester.c b/tester/dtmf_tester.c index c73e05acc..3523fd339 100644 --- a/tester/dtmf_tester.c +++ b/tester/dtmf_tester.c @@ -22,9 +22,7 @@ void dtmf_received(LinphoneCore *lc, LinphoneCall *call, int dtmf) { stats* counters = get_stats(lc); char** dst = &counters->dtmf_list_received; - *dst = *dst ? - ms_strcat_printf(*dst, "%c", dtmf) - : ms_strdup_printf("%c", dtmf); + *dst = *dst ? ms_strcat_printf(*dst, "%c", dtmf) : ms_strdup_printf("%c", dtmf); counters->dtmf_count++; } diff --git a/tester/eventapi_tester.c b/tester/eventapi_tester.c index 2119f3500..8324a587e 100644 --- a/tester/eventapi_tester.c +++ b/tester/eventapi_tester.c @@ -41,7 +41,7 @@ void linphone_notify_received(LinphoneCore *lc, LinphoneEvent *lev, const char * if (!BC_ASSERT_PTR_NOT_NULL(content)) return; if (!linphone_content_is_multipart(content) && (!ua || !strstr(ua, "flexisip"))) { /*disable check for full presence server support*/ /*hack to disable content checking for list notify */ - BC_ASSERT_STRING_EQUAL(notify_content,(const char*)linphone_content_get_buffer(content)); + BC_ASSERT_STRING_EQUAL(linphone_content_get_string_buffer(content), notify_content); } mgr=get_manager(lc); mgr->stat.number_of_NotifyReceived++; diff --git a/tester/flexisip_tester.c b/tester/flexisip_tester.c index 19bdbe9d7..c98380d85 100644 --- a/tester/flexisip_tester.c +++ b/tester/flexisip_tester.c @@ -77,7 +77,7 @@ static void message_forking(void) { lcs=bctbx_list_append(lcs,marie2->lc); linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed); - linphone_chat_room_send_chat_message(chat_room, message); + linphone_chat_message_send(message); BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneMessageReceived,1,3000)); BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneMessageReceived,1,1000)); BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneMessageDelivered,1,1000)); @@ -120,7 +120,7 @@ static void message_forking_with_unreachable_recipients(void) { linphone_core_set_network_reachable(marie3->lc,FALSE); linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed); - linphone_chat_room_send_chat_message(chat_room, message); + linphone_chat_message_send(message); BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneMessageReceived,1,3000)); BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneMessageDelivered,1,1000)); BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1, int, "%d"); @@ -174,7 +174,7 @@ static void message_forking_with_all_recipients_unreachable(void) { linphone_core_set_network_reachable(marie3->lc,FALSE); linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed); - linphone_chat_room_send_chat_message(chat_room, message); + linphone_chat_message_send(message); BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneMessageInProgress,1,5000)); /*flexisip will accept the message with 202 after 16 seconds*/ @@ -207,19 +207,28 @@ static void message_forking_with_all_recipients_unreachable(void) { } static void message_forking_with_unreachable_recipients_with_gruu(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); - LinphoneCoreManager* marie2 = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager *marie = ms_new0(LinphoneCoreManager, 1); + LinphoneCoreManager *pauline = ms_new0(LinphoneCoreManager, 1); + LinphoneCoreManager *marie2 = ms_new0(LinphoneCoreManager, 1); + + linphone_core_manager_init(marie, "marie_rc", NULL); + linphone_core_manager_init(pauline, transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc", NULL); + linphone_core_manager_init(marie2, "marie_rc", NULL); + + linphone_core_add_supported_tag(marie->lc,"gruu"); + linphone_core_add_supported_tag(pauline->lc,"gruu"); + linphone_core_add_supported_tag(marie2->lc,"gruu"); + + linphone_core_manager_start(marie,TRUE); + linphone_core_manager_start(pauline,TRUE); + linphone_core_manager_start(marie2,TRUE); + bctbx_list_t* lcs=bctbx_list_append(NULL,marie->lc); LinphoneProxyConfig *marie_proxy_config = linphone_core_get_default_proxy_config(marie->lc); - LinphoneProxyConfig *marie2_proxy_config = linphone_core_get_default_proxy_config(marie2->lc); const LinphoneAddress *marie_address = linphone_proxy_config_get_contact(marie_proxy_config); - const LinphoneAddress *marie2_address = linphone_proxy_config_get_contact(marie2_proxy_config); LinphoneChatRoom* chat_room_1 = linphone_core_get_chat_room(pauline->lc, marie_address); LinphoneChatMessage* message_1 = linphone_chat_room_create_message(chat_room_1,"Bli bli bli \n blu"); - LinphoneChatRoom* chat_room_2 = linphone_core_get_chat_room(pauline->lc, marie2_address); - LinphoneChatMessage* message_2 = linphone_chat_room_create_message(chat_room_2,"Bla bla bla \n bli"); lcs=bctbx_list_append(lcs,pauline->lc); lcs=bctbx_list_append(lcs,marie2->lc); @@ -235,30 +244,69 @@ static void message_forking_with_unreachable_recipients_with_gruu(void) { linphone_core_set_network_reachable(marie2->lc,FALSE); linphone_chat_room_send_chat_message(chat_room_1, message_1); - linphone_chat_room_send_chat_message(chat_room_2, message_2); BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageReceived, 0, int, "%d"); BC_ASSERT_EQUAL(marie2->stat.number_of_LinphoneMessageReceived, 0, int, "%d"); /*marie 2 goes online */ linphone_core_set_network_reachable(marie2->lc,TRUE); - BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneMessageReceived,1,3000)); + BC_ASSERT_FALSE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneMessageReceived,1,3000)); /*wait a long time so that all transactions are expired*/ wait_for_list(lcs,NULL,0,32000); /*marie goes online now*/ linphone_core_set_network_reachable(marie->lc,TRUE); - BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneMessageReceived,1,3000)); - + if (BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneMessageReceived,1,3000))) { + BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marie->stat.last_received_chat_message), linphone_chat_message_get_text(message_1)); + } linphone_chat_message_unref(message_1); - linphone_chat_message_unref(message_2); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(marie2); linphone_core_manager_destroy(pauline); bctbx_list_free(lcs); } +static void text_message_expires(void) { + LinphoneCoreManager* marie = linphone_core_manager_new4("marie_rc",TRUE,NULL,"message-expires=60",3); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); + + linphone_core_set_network_reachable(marie->lc, FALSE); + /* Wait for 5 seconds for surely cut marie of network */ + wait_for_until(pauline->lc, marie->lc, NULL, 0, 5000); + + linphone_chat_room_send_message(linphone_core_get_chat_room(pauline->lc,marie->identity), "hello"); + linphone_core_set_network_reachable(marie->lc, TRUE); + + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1)); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +static void text_call_expires(void) { + LinphoneCoreManager* marie = linphone_core_manager_new4("marie_rc",TRUE,NULL,"message-expires=60",3); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); + bctbx_list_t* lcs=bctbx_list_append(NULL,pauline->lc); + lcs=bctbx_list_append(lcs,marie->lc); + + linphone_core_set_network_reachable(marie->lc, FALSE); + /* Wait for 5 seconds for surely cut marie of network */ + wait_for_until(pauline->lc, marie->lc, NULL, 0, 5000); + + linphone_core_invite_address(pauline->lc,marie->identity); + linphone_core_set_network_reachable(marie->lc, TRUE); + + /*pauline shouldn't hear ringback*/ + BC_ASSERT_FALSE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,5000)); + /*all devices from Marie shouldn't be ringing*/ + BC_ASSERT_FALSE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,5000)); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + bctbx_list_free(lcs); +} + static void call_forking(void){ LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); @@ -486,18 +534,77 @@ static void call_forking_with_push_notification_single(void){ BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,1000)); /*marie accepts the call*/ - linphone_call_accept(linphone_core_get_current_call(marie->lc)); - BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,5000)); - BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,1000)); - BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallConnected,1,1000)); - BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,1000)); + if (BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(marie->lc))) { + linphone_call_accept(linphone_core_get_current_call(marie->lc)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,5000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallConnected,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,1000)); - liblinphone_tester_check_rtcp(pauline,marie); + liblinphone_tester_check_rtcp(pauline,marie); - linphone_call_terminate(linphone_core_get_current_call(pauline->lc)); - BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,5000)); - BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,5000)); + linphone_call_terminate(linphone_core_get_current_call(pauline->lc)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,5000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,5000)); + } + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(marie); + bctbx_list_free(lcs); +} +/* + * This test is a variant of push notification (single) where the client do send ambigous REGISTER with two contacts, + * one of them being the previous contact address with "expires=0" to tell the server to remove it. +**/ +static void call_forking_with_push_notification_double_contact(void){ + bctbx_list_t* lcs; + LinphoneCoreManager* marie = linphone_core_manager_new2( "marie_rc", FALSE); + LinphoneCoreManager* pauline = linphone_core_manager_new2( transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc",FALSE); + int dummy=0; + + + lp_config_set_int(linphone_core_get_config(marie->lc), "sip", "unregister_previous_contact", 1); + lp_config_set_int(linphone_core_get_config(pauline->lc), "sip", "unregister_previous_contact", 1); + linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL); + linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL); + linphone_proxy_config_set_contact_uri_parameters( + linphone_core_get_default_proxy_config(marie->lc), + "app-id=org.linphonetester;pn-tok=aaabbb;pn-type=apple;pn-msg-str=33;pn-call-str=34;"); + + lcs=bctbx_list_append(NULL,pauline->lc); + lcs=bctbx_list_append(lcs,marie->lc); + + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneRegistrationOk,1,5000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneRegistrationOk,1,5000)); + + /*unfortunately marie gets unreachable due to crappy 3G operator or iOS bug...*/ + linphone_core_set_network_reachable(marie->lc,FALSE); + + linphone_core_invite_address(pauline->lc,marie->identity); + + /*After 5 seconds the server is expected to send a push notification to marie, this will wake up linphone, that will reconnect:*/ + wait_for_list(lcs,&dummy,1,6000); + linphone_core_set_network_reachable(marie->lc,TRUE); + + /*Marie shall receive the call immediately*/ + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,5000)); + /*pauline should hear ringback as well*/ + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,1000)); + + /*marie accepts the call*/ + if (BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(marie->lc))) { + linphone_call_accept(linphone_core_get_current_call(marie->lc)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,5000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallConnected,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,1000)); + + liblinphone_tester_check_rtcp(pauline,marie); + + linphone_call_terminate(linphone_core_get_current_call(pauline->lc)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,5000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,5000)); + } linphone_core_manager_destroy(pauline); linphone_core_manager_destroy(marie); bctbx_list_free(lcs); @@ -534,22 +641,23 @@ static void call_forking_with_push_notification_multiple(void){ BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallIncomingReceived,1,5000)); /*marie2 accepts the call*/ - linphone_call_accept(linphone_core_get_current_call(marie2->lc)); - BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,1000)); - BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,1000)); - BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallConnected,1,1000)); - BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallStreamsRunning,1,1000)); + if (BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(marie2->lc))) { + linphone_call_accept(linphone_core_get_current_call(marie2->lc)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallConnected,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallStreamsRunning,1,1000)); - /*call to marie should be cancelled*/ - BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000)); + /*call to marie should be cancelled*/ + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000)); - liblinphone_tester_check_rtcp(pauline,marie2); + liblinphone_tester_check_rtcp(pauline,marie2); - linphone_call_terminate(linphone_core_get_current_call(pauline->lc)); - - BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000)); - BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,1000)); + linphone_call_terminate(linphone_core_get_current_call(pauline->lc)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,1000)); + } linphone_core_manager_destroy(pauline); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(marie2); @@ -889,7 +997,7 @@ static void file_transfer_message_rcs_to_external_body_client(void) { } linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed); linphone_chat_message_cbs_set_file_transfer_send(cbs, tester_file_transfer_send); - linphone_chat_room_send_chat_message(chat_room,message); + linphone_chat_message_send(message); BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,1)); if (marie->stat.last_received_chat_message ) { @@ -933,7 +1041,7 @@ static void dos_module_trigger(void) { char msg[128]; sprintf(msg, "Flood message number %i", i); chat_msg = linphone_chat_room_create_message(chat_room, msg); - linphone_chat_room_send_chat_message(chat_room, chat_msg); + linphone_chat_message_send(chat_msg); wait_for_until(marie->lc, pauline->lc, &dummy, 1, 10); i++; } while (i < number_of_messge_to_send); @@ -945,7 +1053,7 @@ static void dos_module_trigger(void) { reset_counters(&marie->stat); reset_counters(&pauline->stat); chat_msg = linphone_chat_room_create_message(chat_room, passmsg); - linphone_chat_room_send_chat_message(chat_room, chat_msg); + linphone_chat_message_send(chat_msg); BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived, 1)); BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageReceived, 1, int, "%d"); if (marie->stat.last_received_chat_message) { @@ -1257,7 +1365,7 @@ static void tls_client_auth_try_register(const char *identity, bool_t with_good_ }else{ BC_ASSERT_TRUE(wait_for(lcm->lc, NULL, &lcm->stat.number_of_LinphoneRegistrationFailed, 1)); BC_ASSERT_EQUAL(lcm->stat.number_of_LinphoneRegistrationOk,0, int, "%d"); - /*we should expect at least 2 "auth_requested": one for the TLS certificate, another one because the server rejects the REGISTER with 401, + /*we should expect at least 2 "auth_requested": one for the TLS certificate, another one because the server rejects the REGISTER with 401, with eventually MD5 + SHA256 challenge*/ /*If the certificate isn't recognized at all, the connection will not happen and no SIP response will be received from server.*/ if (with_good_cert) BC_ASSERT_GREATER(lcm->stat.number_of_auth_info_requested,2, int, "%d"); @@ -1353,24 +1461,33 @@ end: ms_free(hellopath); } +static void register_without_regid(void) { + LinphoneCoreManager *marie = linphone_core_manager_new2("marie_rc", FALSE); + linphone_core_manager_start(marie,TRUE); + 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_NULL(strstr(linphone_address_as_string_uri_only(addr), "regid")); + } + linphone_core_manager_destroy(marie); +} + void test_removing_old_tport(void) { - bctbx_list_t* lcs; - LinphoneCoreManager* marie2; LinphoneCoreManager* marie1 = linphone_core_manager_new("marie_rc"); - lcs=bctbx_list_append(NULL,marie1->lc); + bctbx_list_t *lcs = bctbx_list_append(NULL, marie1->lc); BC_ASSERT_TRUE(wait_for_list(lcs,&marie1->stat.number_of_LinphoneRegistrationOk,1,5000)); - marie2 = ms_new0(LinphoneCoreManager, 1); - linphone_core_manager_init(marie2, "marie_rc", NULL); - sal_set_uuid(linphone_core_get_sal(marie2->lc), linphone_config_get_string(linphone_core_get_config(marie1->lc),"misc", "uuid", "0")); + LinphoneCoreManager *marie2 = linphone_core_manager_create("marie_rc"); + const char *uuid = linphone_config_get_string(linphone_core_get_config(marie1->lc), "misc", "uuid", "0"); + lp_config_set_string(linphone_core_get_config(marie2->lc), "misc", "uuid", uuid); linphone_core_manager_start(marie2, TRUE); - lcs=bctbx_list_append(lcs, marie2->lc); + lcs = bctbx_list_append(lcs, marie2->lc); linphone_core_refresh_registers(marie2->lc); - BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneRegistrationOk,1,5000)); - - BC_ASSERT_TRUE(wait_for_list(lcs,&marie1->stat.number_of_LinphoneRegistrationProgress,2,5000)); + BC_ASSERT_TRUE(wait_for_list(lcs, &marie2->stat.number_of_LinphoneRegistrationOk, 1, 5000)); + BC_ASSERT_TRUE(wait_for_list(lcs, &marie1->stat.number_of_LinphoneRegistrationProgress, 2, 5000)); linphone_core_manager_destroy(marie1); linphone_core_manager_destroy(marie2); @@ -1389,7 +1506,7 @@ static void on_refer_received(SalOp *op, const SalAddress *refer_to) { Sal *sal = sal_op_get_sal(op); LinphoneCoreManager *receiver = (LinphoneCoreManager*)sal_get_user_pointer(sal); receiver->stat.number_of_LinphoneCallRefered++; - + } void resend_refer_other_devices(void) { @@ -1447,18 +1564,340 @@ void resend_refer_other_devices(void) { bctbx_list_free(lcs); } +void sequential_forking(void) { + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + LinphoneCoreManager* marie2 = linphone_core_manager_create("marie_rc"); + + bctbx_list_t* lcs=bctbx_list_append(NULL,pauline->lc); + + /*we don't set marie "q" because it is by default at 1.0 if it is not present (RFC 4596)*/ + linphone_proxy_config_set_contact_parameters( + linphone_core_get_default_proxy_config(marie2->lc), + "q=0.5;"); + + linphone_core_manager_start(marie2, TRUE); + + lcs=bctbx_list_append(lcs,marie->lc); + lcs=bctbx_list_append(lcs,marie2->lc); + + linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL); + linphone_core_set_user_agent(marie2->lc,"Natted Linphone",NULL); + linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL); + + linphone_core_invite_address(pauline->lc,marie->identity); + /*pauline should hear ringback*/ + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,3000)); + /*first device from Marie should be ringing*/ + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,3000)); + /*the second should not*/ + BC_ASSERT_EQUAL(marie2->stat.number_of_LinphoneCallIncomingReceived, 0, int, "%d"); + + LinphoneCall *call = linphone_core_get_current_call(marie->lc); + if (!BC_ASSERT_PTR_NOT_NULL(call)) return; + + /*marie accepts the call on its second device*/ + linphone_call_accept(call); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallConnected,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,1000)); + + /*second device should have received nothing*/ + BC_ASSERT_EQUAL(marie2->stat.number_of_LinphoneCallEnd, 0, int, "%d"); + + linphone_call_terminate(linphone_core_get_current_call(pauline->lc)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000)); + + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(marie2); + bctbx_list_free(lcs); +} + +void sequential_forking_with_timeout_for_highest_priority(void) { + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + LinphoneCoreManager* marie2 = linphone_core_manager_create("marie_rc"); + LinphoneCoreManager* marie3 = linphone_core_manager_create("marie_rc"); + + bctbx_list_t* lcs=bctbx_list_append(NULL,pauline->lc); + + /*we don't set marie "q" because it is by default at 1.0 if it is not present (RFC 4596)*/ + linphone_proxy_config_set_contact_parameters( + linphone_core_get_default_proxy_config(marie2->lc), + "q=0.5;"); + + linphone_proxy_config_set_contact_parameters( + linphone_core_get_default_proxy_config(marie3->lc), + "q=0.5;"); + + linphone_core_manager_start(marie2, TRUE); + linphone_core_manager_start(marie3, TRUE); + + lcs=bctbx_list_append(lcs,marie->lc); + lcs=bctbx_list_append(lcs,marie2->lc); + lcs=bctbx_list_append(lcs,marie3->lc); + + linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL); + linphone_core_set_user_agent(marie2->lc,"Natted Linphone",NULL); + linphone_core_set_user_agent(marie3->lc,"Natted Linphone",NULL); + linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL); + + /*set first device not reachable*/ + linphone_core_set_network_reachable(marie->lc,FALSE); + + linphone_core_invite_address(pauline->lc,marie->identity); + + /*pauline should hear ringback*/ + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,3000)); + /*first device should receive nothing since it is disconnected*/ + BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallIncomingReceived, 0, int, "%d"); + /*second and third devices should have received the call*/ + BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallIncomingReceived,1,3000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallIncomingReceived,1,3000)); + + LinphoneCall *call = linphone_core_get_current_call(marie3->lc); + if (!BC_ASSERT_PTR_NOT_NULL(call)) return; + + /*marie accepts the call on her third device*/ + linphone_call_accept(call); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallConnected,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallStreamsRunning,1,1000)); + + /*second device should stop ringing*/ + BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,1000)); + + linphone_call_terminate(linphone_core_get_current_call(pauline->lc)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallEnd,1,1000)); + + /*first device should have received nothing*/ + BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallEnd, 0, int, "%d"); + + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(marie2); + linphone_core_manager_destroy(marie3); + bctbx_list_free(lcs); +} + +void sequential_forking_with_no_response_for_highest_priority(void) { + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + LinphoneCoreManager* marie2 = linphone_core_manager_create("marie_rc"); + + bctbx_list_t* lcs=bctbx_list_append(NULL,pauline->lc); + + /*we don't set marie "q" because it is by default at 1.0 if it is not present (RFC 4596)*/ + linphone_proxy_config_set_contact_parameters( + linphone_core_get_default_proxy_config(marie2->lc), + "q=0.5;"); + + linphone_core_manager_start(marie2, TRUE); + + lcs=bctbx_list_append(lcs,marie->lc); + lcs=bctbx_list_append(lcs,marie2->lc); + + linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL); + linphone_core_set_user_agent(marie2->lc,"Natted Linphone",NULL); + linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL); + + linphone_core_invite_address(pauline->lc,marie->identity); + + /*pauline should hear ringback*/ + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,3000)); + /*first device should receive the call*/ + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,3000)); + /*second device should have not received the call yet*/ + BC_ASSERT_EQUAL(marie2->stat.number_of_LinphoneCallIncomingReceived, 0, int, "%d"); + + /*we wait for the call to try the next branches*/ + wait_for_list(lcs,NULL,0,10000); + + /*then the second device should receive the call*/ + BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallIncomingReceived, 1, 3000)); + + LinphoneCall *call = linphone_core_get_current_call(marie2->lc); + if (!BC_ASSERT_PTR_NOT_NULL(call)) return; + + /*marie accepts the call on her second device*/ + linphone_call_accept(call); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallConnected,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallStreamsRunning,1,1000)); + + /*the first device should finish*/ + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd, 1, 3000)); + + linphone_call_terminate(linphone_core_get_current_call(pauline->lc)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,1000)); + + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(marie2); + bctbx_list_free(lcs); +} + +void sequential_forking_with_insertion_of_higher_priority(void) { + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + LinphoneCoreManager* marie2 = linphone_core_manager_create("marie_rc"); + + bctbx_list_t* lcs=bctbx_list_append(NULL,pauline->lc); + + /*we don't set marie "q" because it is by default at 1.0 if it is not present (RFC 4596)*/ + linphone_proxy_config_set_contact_parameters( + linphone_core_get_default_proxy_config(marie2->lc), + "q=0.5;"); + + linphone_core_manager_start(marie2, TRUE); + + lcs=bctbx_list_append(lcs,marie->lc); + lcs=bctbx_list_append(lcs,marie2->lc); + + linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL); + linphone_core_set_user_agent(marie2->lc,"Natted Linphone",NULL); + linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL); + + /*set first device not reachable*/ + linphone_core_set_network_reachable(marie->lc,FALSE); + + linphone_core_invite_address(pauline->lc,marie->identity); + + /*pauline should hear ringback*/ + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,3000)); + /*first device should receive nothing since it is disconnected*/ + BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallIncomingReceived, 0, int, "%d"); + /*second device should have received the call*/ + BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallIncomingReceived,1,3000)); + + /*we create a new device*/ + LinphoneCoreManager* marie3 = linphone_core_manager_new("marie_rc"); + lcs=bctbx_list_append(lcs,marie3->lc); + linphone_core_set_user_agent(marie3->lc,"Natted Linphone",NULL); + + /*this device should receive the call*/ + BC_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallIncomingReceived,1,3000)); + + LinphoneCall *call = linphone_core_get_current_call(marie3->lc); + if (!BC_ASSERT_PTR_NOT_NULL(call)) return; + + /*marie accepts the call on her third device*/ + linphone_call_accept(call); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallConnected,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallStreamsRunning,1,1000)); + + /*second device should stop ringing*/ + BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,1000)); + + linphone_call_terminate(linphone_core_get_current_call(pauline->lc)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallEnd,1,1000)); + + /*first device should have received nothing*/ + BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallEnd, 0, int, "%d"); + + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(marie2); + linphone_core_manager_destroy(marie3); + bctbx_list_free(lcs); +} + +void sequential_forking_with_fallback_route(void) { + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + LinphoneCoreManager* pauline2 = linphone_core_manager_create(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + LinphoneCoreManager* marie = linphone_core_manager_create("marie_rc"); + + bctbx_list_t* lcs=bctbx_list_append(NULL,pauline->lc); + + /*we set pauline2 and marie to another test server that is configured with a fallback route*/ + linphone_proxy_config_set_server_addr( + linphone_core_get_default_proxy_config(pauline2->lc), + "sip:sip2.linphone.org:5071;transport=tls"); + + linphone_proxy_config_set_route( + linphone_core_get_default_proxy_config(pauline2->lc), + "sip:sip2.linphone.org:5071;transport=tls"); + + linphone_proxy_config_set_server_addr( + linphone_core_get_default_proxy_config(marie->lc), + "sip:sip2.linphone.org:5070;transport=tcp"); + + linphone_proxy_config_set_route( + linphone_core_get_default_proxy_config(marie->lc), + "sip:sip2.linphone.org:5070;transport=tcp;lr"); + + linphone_core_manager_start(pauline2, TRUE); + linphone_core_manager_start(marie, TRUE); + + lcs=bctbx_list_append(lcs,pauline2->lc); + lcs=bctbx_list_append(lcs,marie->lc); + + linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL); + linphone_core_set_user_agent(pauline2->lc,"Natted Linphone",NULL); + linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL); + + /*set pauline2 not reachable*/ + linphone_core_set_network_reachable(pauline2->lc,FALSE); + + /*marie invites pauline2 on the other server*/ + linphone_core_invite_address(marie->lc,pauline2->identity); + + /*marie should hear ringback*/ + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallOutgoingRinging,1,3000)); + /*pauline2 should receive nothing since it is disconnected*/ + BC_ASSERT_EQUAL(pauline2->stat.number_of_LinphoneCallIncomingReceived, 0, int, "%d"); + + /*the call should be routed to the first server with pauline account*/ + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallIncomingReceived,1,3000)); + + LinphoneCall *call = linphone_core_get_current_call(pauline->lc); + if (!BC_ASSERT_PTR_NOT_NULL(call)) return; + + /*pauline accepts the call*/ + linphone_call_accept(call); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallConnected,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,1000)); + + linphone_call_terminate(linphone_core_get_current_call(marie->lc)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000)); + + /*first device should have received nothing*/ + BC_ASSERT_EQUAL(pauline2->stat.number_of_LinphoneCallEnd, 0, int, "%d"); + + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(pauline2); + linphone_core_manager_destroy(marie); + bctbx_list_free(lcs); +} + test_t flexisip_tests[] = { TEST_ONE_TAG("Subscribe forking", subscribe_forking, "LeaksMemory"), TEST_NO_TAG("Message forking", message_forking), TEST_NO_TAG("Message forking with unreachable recipients", message_forking_with_unreachable_recipients), TEST_NO_TAG("Message forking with all recipients unreachable", message_forking_with_all_recipients_unreachable), TEST_NO_TAG("Message forking with unreachable recipients with gruu", message_forking_with_unreachable_recipients_with_gruu), + TEST_NO_TAG("Message expires", text_message_expires), + TEST_NO_TAG("Call expires", text_call_expires), TEST_NO_TAG("Call forking", call_forking), TEST_NO_TAG("Call forking cancelled", call_forking_cancelled), TEST_NO_TAG("Call forking declined globaly", call_forking_declined_globaly), TEST_NO_TAG("Call forking declined localy", call_forking_declined_localy), TEST_NO_TAG("Call forking with urgent reply", call_forking_with_urgent_reply), TEST_NO_TAG("Call forking with push notification (single)", call_forking_with_push_notification_single), + TEST_NO_TAG("Call forking with push notification with double contact", call_forking_with_push_notification_double_contact), TEST_NO_TAG("Call forking with push notification (multiple)", call_forking_with_push_notification_multiple), TEST_NO_TAG("Call forking not responded", call_forking_not_responded), TEST_NO_TAG("Early-media call forking", early_media_call_forking), @@ -1484,7 +1923,13 @@ test_t flexisip_tests[] = { TEST_NO_TAG("TLS authentication - client rejected due to unrecognized certificate chain", tls_client_auth_bad_certificate), TEST_NO_TAG("Transcoder", transcoder_tester), TEST_NO_TAG("Removing old tport on flexisip for the same client", test_removing_old_tport), - TEST_NO_TAG("Resend of REFER with other devices", resend_refer_other_devices) + TEST_NO_TAG("Resend of REFER with other devices", resend_refer_other_devices), + TEST_NO_TAG("Sequential forking", sequential_forking), + TEST_NO_TAG("Sequential forking with timeout for highest priority", sequential_forking_with_timeout_for_highest_priority), + TEST_NO_TAG("Sequential forking with no response from highest priority", sequential_forking_with_no_response_for_highest_priority), + TEST_NO_TAG("Sequential forking with insertion of higher priority", sequential_forking_with_insertion_of_higher_priority), + TEST_NO_TAG("Sequential forking with fallback route", sequential_forking_with_fallback_route), + TEST_NO_TAG("Registered contact does not have regid param", register_without_regid) }; diff --git a/tester/group_chat_tester.c b/tester/group_chat_tester.c index 9ddfc9329..b3f8b6bf0 100644 --- a/tester/group_chat_tester.c +++ b/tester/group_chat_tester.c @@ -69,6 +69,7 @@ static void chat_room_participant_device_added (LinphoneChatRoom *cr, const Linp static void chat_room_state_changed (LinphoneChatRoom *cr, LinphoneChatRoomState newState) { LinphoneCore *core = linphone_chat_room_get_core(cr); LinphoneCoreManager *manager = (LinphoneCoreManager *)linphone_core_get_user_data(core); + ms_message("ChatRoom [%p] state changed: %d", cr, newState); switch (newState) { case LinphoneChatRoomStateNone: break; @@ -105,6 +106,12 @@ static void chat_room_subject_changed (LinphoneChatRoom *cr, const LinphoneEvent manager->stat.number_of_subject_changed++; } +static void chat_room_conference_joined (LinphoneChatRoom *cr, const LinphoneEventLog *event_log) { + LinphoneCore *core = linphone_chat_room_get_core(cr); + LinphoneCoreManager *manager = (LinphoneCoreManager *)linphone_core_get_user_data(core); + manager->stat.number_of_LinphoneChatRoomConferenceJoined++; +} + static void core_chat_room_state_changed (LinphoneCore *core, LinphoneChatRoom *cr, LinphoneChatRoomState state) { if (state == LinphoneChatRoomStateInstantiated) { LinphoneChatRoomCbs *cbs = linphone_factory_create_chat_room_cbs(linphone_factory_get()); @@ -115,6 +122,7 @@ static void core_chat_room_state_changed (LinphoneCore *core, LinphoneChatRoom * linphone_chat_room_cbs_set_state_changed(cbs, chat_room_state_changed); linphone_chat_room_cbs_set_subject_changed(cbs, chat_room_subject_changed); linphone_chat_room_cbs_set_participant_device_added(cbs, chat_room_participant_device_added); + linphone_chat_room_cbs_set_conference_joined(cbs, chat_room_conference_joined); linphone_chat_room_add_callbacks(cr, cbs); linphone_chat_room_cbs_unref(cbs); } @@ -180,9 +188,9 @@ static void _send_file_plus_text(LinphoneChatRoom* cr, const char *sendFilepath, cbs = linphone_chat_message_get_callbacks(msg); linphone_chat_message_cbs_set_file_transfer_send(cbs, tester_file_transfer_send); - linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed); + linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed); linphone_chat_message_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication); - linphone_chat_room_send_chat_message(cr, msg); + linphone_chat_message_send(msg); linphone_content_unref(content); linphone_chat_message_unref(msg); } @@ -192,7 +200,7 @@ static void _send_file(LinphoneChatRoom* cr, const char *sendFilepath) { } static void _receive_file(bctbx_list_t *coresList, LinphoneCoreManager *lcm, stats *receiverStats, const char *receive_filepath, const char *sendFilepath) { - if (BC_ASSERT_TRUE(wait_for_list(coresList, &lcm->stat.number_of_LinphoneMessageReceivedWithFile, receiverStats->number_of_LinphoneMessageReceivedWithFile+1, 10000))) { + if (BC_ASSERT_TRUE(wait_for_list(coresList, &lcm->stat.number_of_LinphoneMessageReceivedWithFile, receiverStats->number_of_LinphoneMessageReceivedWithFile + 1, 10000))) { LinphoneChatMessageCbs *cbs; LinphoneChatMessage *msg = lcm->stat.last_received_chat_message; @@ -210,7 +218,7 @@ static void _receive_file(bctbx_list_t *coresList, LinphoneCoreManager *lcm, sta } static void _receive_file_plus_text(bctbx_list_t *coresList, LinphoneCoreManager *lcm, stats *receiverStats, const char *receive_filepath, const char *sendFilepath, const char *text) { - if (BC_ASSERT_TRUE(wait_for_list(coresList, &lcm->stat.number_of_LinphoneMessageReceivedWithFile, receiverStats->number_of_LinphoneMessageReceivedWithFile+1, 10000))) { + if (BC_ASSERT_TRUE(wait_for_list(coresList, &lcm->stat.number_of_LinphoneMessageReceivedWithFile, receiverStats->number_of_LinphoneMessageReceivedWithFile + 1, 10000))) { LinphoneChatMessageCbs *cbs; LinphoneChatMessage *msg = lcm->stat.last_received_chat_message; @@ -253,8 +261,9 @@ static void start_core_for_conference(bctbx_list_t *coreManagerList) { } static LinphoneChatRoom * check_creation_chat_room_client_side(bctbx_list_t *lcs, LinphoneCoreManager *lcm, stats *initialStats, const LinphoneAddress *confAddr, const char* subject, int participantNumber, bool_t isAdmin) { - BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneChatRoomStateCreationPending, initialStats->number_of_LinphoneChatRoomStateCreationPending + 1, 5000)); - BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneChatRoomStateCreated, initialStats->number_of_LinphoneChatRoomStateCreated + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneChatRoomStateCreationPending, initialStats->number_of_LinphoneChatRoomStateCreationPending + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneChatRoomStateCreated, initialStats->number_of_LinphoneChatRoomStateCreated + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneChatRoomConferenceJoined, initialStats->number_of_LinphoneChatRoomConferenceJoined + 1, 3000)); char *deviceIdentity = linphone_core_get_device_identity(lcm->lc); LinphoneAddress *localAddr = linphone_address_new(deviceIdentity); bctbx_free(deviceIdentity); @@ -273,7 +282,7 @@ static LinphoneChatRoom * check_creation_chat_room_client_side(bctbx_list_t *lcs } static LinphoneChatRoom * create_chat_room_client_side(bctbx_list_t *lcs, LinphoneCoreManager *lcm, stats *initialStats, bctbx_list_t *participantsAddresses, const char* initialSubject, int expectedParticipantSize) { - LinphoneChatRoom *chatRoom = linphone_core_create_client_group_chat_room(lcm->lc, initialSubject); + LinphoneChatRoom *chatRoom = linphone_core_create_client_group_chat_room(lcm->lc, initialSubject, FALSE); if (!chatRoom) return NULL; BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneChatRoomStateInstantiated, initialStats->number_of_LinphoneChatRoomStateInstantiated + 1, 100)); @@ -282,8 +291,9 @@ static LinphoneChatRoom * create_chat_room_client_side(bctbx_list_t *lcs, Linpho linphone_chat_room_add_participants(chatRoom, participantsAddresses); // Check that the chat room is correctly created on Marie's side and that the participants are added - BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneChatRoomStateCreationPending, initialStats->number_of_LinphoneChatRoomStateCreationPending + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneChatRoomStateCreated, initialStats->number_of_LinphoneChatRoomStateCreated + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneChatRoomStateCreationPending, initialStats->number_of_LinphoneChatRoomStateCreationPending + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneChatRoomStateCreated, initialStats->number_of_LinphoneChatRoomStateCreated + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneChatRoomConferenceJoined, initialStats->number_of_LinphoneChatRoomConferenceJoined + 1, 3000)); BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(chatRoom), (expectedParticipantSize >= 0) ? expectedParticipantSize : (int)bctbx_list_size(participantsAddresses), int, "%d"); @@ -343,9 +353,9 @@ static void group_chat_room_creation_server (void) { // Marie now changes the subject linphone_chat_room_set_subject(marieCr, newSubject); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed, initialMarieStats.number_of_subject_changed + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed, initialPaulineStats.number_of_subject_changed + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed, initialLaureStats.number_of_subject_changed + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed, initialMarieStats.number_of_subject_changed + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed, initialPaulineStats.number_of_subject_changed + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed, initialLaureStats.number_of_subject_changed + 1, 3000)); BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(marieCr), newSubject); BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(paulineCr), newSubject); BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(laureCr), newSubject); @@ -356,9 +366,9 @@ static void group_chat_room_creation_server (void) { linphone_address_unref(paulineAddr); BC_ASSERT_PTR_NOT_NULL(paulineParticipant); linphone_chat_room_set_participant_admin_status(marieCr, paulineParticipant, TRUE); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participant_admin_statuses_changed, initialMarieStats.number_of_participant_admin_statuses_changed + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participant_admin_statuses_changed, initialPaulineStats.number_of_participant_admin_statuses_changed + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participant_admin_statuses_changed, initialLaureStats.number_of_participant_admin_statuses_changed + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participant_admin_statuses_changed, initialMarieStats.number_of_participant_admin_statuses_changed + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participant_admin_statuses_changed, initialPaulineStats.number_of_participant_admin_statuses_changed + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participant_admin_statuses_changed, initialLaureStats.number_of_participant_admin_statuses_changed + 1, 3000)); BC_ASSERT_TRUE(linphone_participant_is_admin(paulineParticipant)); // Pauline adds Chloe to the chat room @@ -370,9 +380,9 @@ static void group_chat_room_creation_server (void) { // Check that the chat room is correctly created on Chloe's side and that she was added everywhere LinphoneChatRoom *chloeCr = check_creation_chat_room_client_side(coresList, chloe, &initialChloeStats, confAddr, newSubject, 3, FALSE); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participants_added, initialMarieStats.number_of_participants_added + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participants_added, initialPaulineStats.number_of_participants_added + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participants_added, initialLaureStats.number_of_participants_added + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participants_added, initialMarieStats.number_of_participants_added + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participants_added, initialPaulineStats.number_of_participants_added + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participants_added, initialLaureStats.number_of_participants_added + 1, 3000)); BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marieCr), 3, int, "%d"); BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(paulineCr), 3, int, "%d"); BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(laureCr), 3, int, "%d"); @@ -383,7 +393,7 @@ static void group_chat_room_creation_server (void) { linphone_address_unref(marieAddr); BC_ASSERT_PTR_NOT_NULL(marieParticipant); linphone_chat_room_set_participant_admin_status(paulineCr, marieParticipant, FALSE); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participant_admin_statuses_changed, initialPaulineStats.number_of_participant_admin_statuses_changed + 2, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participant_admin_statuses_changed, initialPaulineStats.number_of_participant_admin_statuses_changed + 2, 3000)); BC_ASSERT_FALSE(linphone_participant_is_admin(marieParticipant)); // Marie tries to change the subject again but is not admin, so it is not changed @@ -392,18 +402,18 @@ static void group_chat_room_creation_server (void) { // Chloe begins composing a message linphone_chat_room_compose(chloeCr); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingActiveReceived, initialMarieStats.number_of_LinphoneIsComposingActiveReceived + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneIsComposingActiveReceived, initialPaulineStats.number_of_LinphoneIsComposingActiveReceived + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneIsComposingActiveReceived, initialLaureStats.number_of_LinphoneIsComposingActiveReceived + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingActiveReceived, initialMarieStats.number_of_LinphoneIsComposingActiveReceived + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneIsComposingActiveReceived, initialPaulineStats.number_of_LinphoneIsComposingActiveReceived + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneIsComposingActiveReceived, initialLaureStats.number_of_LinphoneIsComposingActiveReceived + 1, 3000)); const char *chloeTextMessage = "Hello"; LinphoneChatMessage *chloeMessage = _send_message(chloeCr, chloeTextMessage); - BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneMessageDelivered, initialChloeStats.number_of_LinphoneMessageDelivered + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, initialMarieStats.number_of_LinphoneMessageReceived + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneMessageReceived, initialLaureStats.number_of_LinphoneMessageReceived + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingIdleReceived, initialMarieStats.number_of_LinphoneIsComposingIdleReceived + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneIsComposingIdleReceived, initialPaulineStats.number_of_LinphoneIsComposingIdleReceived + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneIsComposingIdleReceived, initialLaureStats.number_of_LinphoneIsComposingIdleReceived + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneMessageDelivered, initialChloeStats.number_of_LinphoneMessageDelivered + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, initialMarieStats.number_of_LinphoneMessageReceived + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneMessageReceived, initialLaureStats.number_of_LinphoneMessageReceived + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingIdleReceived, initialMarieStats.number_of_LinphoneIsComposingIdleReceived + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneIsComposingIdleReceived, initialPaulineStats.number_of_LinphoneIsComposingIdleReceived + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneIsComposingIdleReceived, initialLaureStats.number_of_LinphoneIsComposingIdleReceived + 1, 3000)); BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marie->stat.last_received_chat_message), chloeTextMessage); linphone_chat_message_unref(chloeMessage); LinphoneAddress *chloeAddr = linphone_address_new(linphone_core_get_identity(chloe->lc)); @@ -417,10 +427,10 @@ static void group_chat_room_creation_server (void) { BC_ASSERT_PTR_NOT_NULL(laureParticipant); linphone_chat_room_remove_participant(paulineCr, laureParticipant); BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(marieCr), newSubject); - BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomStateTerminated, initialLaureStats.number_of_LinphoneChatRoomStateTerminated + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_participants_removed, initialChloeStats.number_of_participants_removed + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participants_removed, initialMarieStats.number_of_participants_removed + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participants_removed, initialPaulineStats.number_of_participants_removed + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomStateTerminated, initialLaureStats.number_of_LinphoneChatRoomStateTerminated + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_participants_removed, initialChloeStats.number_of_participants_removed + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participants_removed, initialMarieStats.number_of_participants_removed + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participants_removed, initialPaulineStats.number_of_participants_removed + 1, 3000)); // Pauline removes Marie and Chloe from the chat room marieAddr = linphone_address_new(linphone_core_get_identity(marie->lc)); @@ -437,8 +447,8 @@ static void group_chat_room_creation_server (void) { participantsToRemove = bctbx_list_append(participantsToRemove, chloeParticipant); linphone_chat_room_remove_participants(paulineCr, participantsToRemove); bctbx_list_free_with_data(participantsToRemove, (bctbx_list_free_func)linphone_participant_unref); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateTerminated, initialMarieStats.number_of_LinphoneChatRoomStateTerminated + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneChatRoomStateTerminated, initialChloeStats.number_of_LinphoneChatRoomStateTerminated + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateTerminated, initialMarieStats.number_of_LinphoneChatRoomStateTerminated + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneChatRoomStateTerminated, initialChloeStats.number_of_LinphoneChatRoomStateTerminated + 1, 3000)); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participants_removed, initialPaulineStats.number_of_participants_removed + 2, 1000)); BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(paulineCr), 0, int, "%d"); @@ -446,7 +456,7 @@ static void group_chat_room_creation_server (void) { wait_for_list(coresList, &dummy, 1, 1000); linphone_chat_room_leave(paulineCr); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomStateTerminationPending, initialPaulineStats.number_of_LinphoneChatRoomStateTerminationPending + 1, 100)); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomStateTerminated, initialPaulineStats.number_of_LinphoneChatRoomStateTerminated + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomStateTerminated, initialPaulineStats.number_of_LinphoneChatRoomStateTerminated + 1, 3000)); // Clean db from chat room linphone_core_manager_delete_chat_room(marie, marieCr, coresList); @@ -530,8 +540,8 @@ static void group_chat_room_add_participant (void) { // Pauline begins composing a message linphone_chat_room_compose(paulineCr); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingActiveReceived, initialMarieStats.number_of_LinphoneIsComposingActiveReceived + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneIsComposingActiveReceived, initialPaulineStats.number_of_LinphoneIsComposingActiveReceived + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingActiveReceived, initialMarieStats.number_of_LinphoneIsComposingActiveReceived + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneIsComposingActiveReceived, initialPaulineStats.number_of_LinphoneIsComposingActiveReceived + 1, 3000)); // Now, Chloe is upgrading to group chat client linphone_core_set_network_reachable(chloe->lc, FALSE); @@ -552,9 +562,9 @@ static void group_chat_room_add_participant (void) { // Check that the chat room is correctly created on Chloe's side and that she was added everywhere LinphoneChatRoom *chloeCr = check_creation_chat_room_client_side(coresList, chloe, &initialChloeStats, confAddr, initialSubject, 3, FALSE); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participants_added, initialMarieStats.number_of_participants_added + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participants_added, initialPaulineStats.number_of_participants_added + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participants_added, initialLaureStats.number_of_participants_added + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participants_added, initialMarieStats.number_of_participants_added + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participants_added, initialPaulineStats.number_of_participants_added + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participants_added, initialLaureStats.number_of_participants_added + 1, 3000)); BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marieCr), 3, int, "%d"); BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(paulineCr), 3, int, "%d"); BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(laureCr), 3, int, "%d"); @@ -669,14 +679,14 @@ static void group_chat_room_message (bool_t encrypt) { // Chloe begins composing a message linphone_chat_room_compose(chloeCr); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingActiveReceived, initialMarieStats.number_of_LinphoneIsComposingActiveReceived + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneIsComposingActiveReceived, initialPaulineStats.number_of_LinphoneIsComposingActiveReceived + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingActiveReceived, initialMarieStats.number_of_LinphoneIsComposingActiveReceived + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneIsComposingActiveReceived, initialPaulineStats.number_of_LinphoneIsComposingActiveReceived + 1, 3000)); const char *chloeTextMessage = "Hello"; LinphoneChatMessage *chloeMessage = _send_message(chloeCr, chloeTextMessage); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, initialMarieStats.number_of_LinphoneMessageReceived + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingIdleReceived, initialMarieStats.number_of_LinphoneIsComposingIdleReceived + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneIsComposingIdleReceived, initialPaulineStats.number_of_LinphoneIsComposingIdleReceived + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, initialMarieStats.number_of_LinphoneMessageReceived + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingIdleReceived, initialMarieStats.number_of_LinphoneIsComposingIdleReceived + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneIsComposingIdleReceived, initialPaulineStats.number_of_LinphoneIsComposingIdleReceived + 1, 3000)); LinphoneChatMessage *marieLastMsg = marie->stat.last_received_chat_message; if (!BC_ASSERT_PTR_NOT_NULL(marieLastMsg)) goto end; @@ -689,14 +699,14 @@ static void group_chat_room_message (bool_t encrypt) { // Pauline begins composing a messagewith some accents linphone_chat_room_compose(paulineCr); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingActiveReceived, initialMarieStats.number_of_LinphoneIsComposingActiveReceived + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneIsComposingActiveReceived, initialChloeStats.number_of_LinphoneIsComposingActiveReceived + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingActiveReceived, initialMarieStats.number_of_LinphoneIsComposingActiveReceived + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneIsComposingActiveReceived, initialChloeStats.number_of_LinphoneIsComposingActiveReceived + 1, 3000)); const char *paulineTextMessage = "Héllö Dàrling"; LinphoneChatMessage *paulineMessage = _send_message(paulineCr, paulineTextMessage); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, initialMarieStats.number_of_LinphoneMessageReceived + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneMessageReceived, initialChloeStats.number_of_LinphoneMessageReceived + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingIdleReceived, initialMarieStats.number_of_LinphoneIsComposingIdleReceived + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneIsComposingIdleReceived, initialChloeStats.number_of_LinphoneIsComposingIdleReceived + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, initialMarieStats.number_of_LinphoneMessageReceived + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneMessageReceived, initialChloeStats.number_of_LinphoneMessageReceived + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingIdleReceived, initialMarieStats.number_of_LinphoneIsComposingIdleReceived + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneIsComposingIdleReceived, initialChloeStats.number_of_LinphoneIsComposingIdleReceived + 1, 3000)); marieLastMsg = marie->stat.last_received_chat_message; if (!BC_ASSERT_PTR_NOT_NULL(marieLastMsg)) goto end; @@ -1087,9 +1097,9 @@ static void group_chat_room_change_subject (void) { // Marie now changes the subject linphone_chat_room_set_subject(marieCr, newSubject); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed, initialMarieStats.number_of_subject_changed + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed, initialPaulineStats.number_of_subject_changed + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed, initialLaureStats.number_of_subject_changed + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed, initialMarieStats.number_of_subject_changed + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed, initialPaulineStats.number_of_subject_changed + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed, initialLaureStats.number_of_subject_changed + 1, 3000)); BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(marieCr), newSubject); BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(paulineCr), newSubject); BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(laureCr), newSubject); @@ -1138,9 +1148,9 @@ static void group_chat_room_change_subject_non_admin (void) { // Marie now changes the subject linphone_chat_room_set_subject(paulineCr, newSubject); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed, initialMarieStats.number_of_subject_changed, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed, initialPaulineStats.number_of_subject_changed, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed, initialLaureStats.number_of_subject_changed, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed, initialMarieStats.number_of_subject_changed, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed, initialPaulineStats.number_of_subject_changed, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed, initialLaureStats.number_of_subject_changed, 3000)); BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(marieCr), initialSubject); BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(paulineCr), initialSubject); BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(laureCr), initialSubject); @@ -1254,11 +1264,11 @@ static void group_chat_room_send_message_with_participant_removed (void) { LinphoneChatMessage *laureMessage = _send_message(laureCr, laureTextMessage); linphone_chat_message_unref(laureMessage); - BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneMessageReceived, initialMarieStats.number_of_LinphoneMessageDelivered, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, initialMarieStats.number_of_LinphoneMessageReceived, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingIdleReceived, initialMarieStats.number_of_LinphoneIsComposingIdleReceived, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneIsComposingIdleReceived, initialPaulineStats.number_of_LinphoneIsComposingIdleReceived, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneMessageReceived, initialMarieStats.number_of_LinphoneMessageDelivered, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, initialMarieStats.number_of_LinphoneMessageReceived, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingIdleReceived, initialMarieStats.number_of_LinphoneIsComposingIdleReceived, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneIsComposingIdleReceived, initialPaulineStats.number_of_LinphoneIsComposingIdleReceived, 3000)); end: // Clean db from chat room @@ -1360,9 +1370,9 @@ static void group_chat_room_come_back_after_disconnection (void) { // Marie now changes the subject linphone_chat_room_set_subject(marieCr, newSubject); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed, initialMarieStats.number_of_subject_changed + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed, initialPaulineStats.number_of_subject_changed + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed, initialLaureStats.number_of_subject_changed + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed, initialMarieStats.number_of_subject_changed + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed, initialPaulineStats.number_of_subject_changed + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed, initialLaureStats.number_of_subject_changed + 1, 3000)); BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(marieCr), newSubject); BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(paulineCr), newSubject); BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(laureCr), newSubject); @@ -1417,35 +1427,34 @@ static void group_chat_room_create_room_with_disconnected_friends_base (bool_t i const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr); if (initial_message) { - LinphoneChatMessage* msg = linphone_chat_room_create_message(marieCr, "Salut"); + LinphoneChatMessage *msg = linphone_chat_room_create_message(marieCr, "Salut"); linphone_chat_message_send(msg); linphone_chat_message_unref(msg); } wait_for_list(coresList, &dummy, 1, 4000); - // Reconnect pauline and laure + // Reconnect Pauline and check that the chat room is correctly created on Pauline's side and that the participants are added linphone_core_set_network_reachable(pauline->lc, TRUE); - linphone_core_set_network_reachable(laure->lc, TRUE); - - // Check that the chat room is correctly created on Pauline's side and that the participants are added paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr, initialSubject, 2, FALSE); if (!BC_ASSERT_PTR_NOT_NULL(paulineCr)) goto end; - // Check that the chat room is correctly created on Laure's side and that the participants are added + + // Reconnect Laure and check that the chat room is correctly created on Laure's side and that the participants are added + linphone_core_set_network_reachable(laure->lc, TRUE); laureCr = check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE); if (!BC_ASSERT_PTR_NOT_NULL(laureCr)) goto end; if (initial_message) { - if (BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, 1, 10000))) { + if (BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, 1, 3000))) { LinphoneChatMessage *msg = linphone_chat_room_get_last_message_in_history(paulineCr); if (BC_ASSERT_PTR_NOT_NULL(msg)) { BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(msg), "Salut"); linphone_chat_message_unref(msg); } } - if (BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneMessageReceived, 1, 10000))) { + if (BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneMessageReceived, 1, 3000))) { LinphoneChatMessage *msg = linphone_chat_room_get_last_message_in_history(laureCr); if (BC_ASSERT_PTR_NOT_NULL(msg)) { BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(msg), "Salut"); @@ -1475,7 +1484,7 @@ static void group_chat_room_create_room_with_disconnected_friends_and_initial_me group_chat_room_create_room_with_disconnected_friends_base(TRUE); } -static void group_chat_room_reinvited_after_removed_base (bool_t offline_when_removed, bool_t offline_when_reinvited) { +static void group_chat_room_reinvited_after_removed_base (bool_t offline_when_removed, bool_t offline_when_reinvited, bool_t restart_after_reinvited) { LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc"); LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc"); LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc"); @@ -1528,13 +1537,15 @@ static void group_chat_room_reinvited_after_removed_base (bool_t offline_when_re bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, laure); bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList); bctbx_list_free(tmpCoresManagerList); - initialLaureStats = laure->stat; linphone_core_manager_start(laure, TRUE); coresList = bctbx_list_concat(coresList, tmpCoresList); coresManagerList = bctbx_list_append(coresManagerList, laure); } if (!offline_when_reinvited) - BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomStateTerminated, initialLaureStats.number_of_LinphoneChatRoomStateTerminated + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomStateTerminated, initialLaureStats.number_of_LinphoneChatRoomStateTerminated + 1, 5000)); + + wait_for_list(coresList,0, 1, 2000); + initialLaureStats = laure->stat; // Marie adds Laure to the chat room participantsAddresses = bctbx_list_append(participantsAddresses, laureAddr); @@ -1550,16 +1561,13 @@ static void group_chat_room_reinvited_after_removed_base (bool_t offline_when_re bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, laure); bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList); bctbx_list_free(tmpCoresManagerList); - initialLaureStats = laure->stat; linphone_core_manager_start(laure, TRUE); coresList = bctbx_list_concat(coresList, tmpCoresList); coresManagerList = bctbx_list_append(coresManagerList, laure); - BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomStateCreationPending, initialLaureStats.number_of_LinphoneChatRoomStateCreationPending + 1, 5000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomStateCreated, initialLaureStats.number_of_LinphoneChatRoomStateCreated + 2, 5000)); - } else { - BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomStateCreationPending, initialLaureStats.number_of_LinphoneChatRoomStateCreationPending + 1, 5000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomStateCreated, initialLaureStats.number_of_LinphoneChatRoomStateCreated + 1, 5000)); } + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomStateCreationPending, initialLaureStats.number_of_LinphoneChatRoomStateCreationPending + 1, 5000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomStateCreated, initialLaureStats.number_of_LinphoneChatRoomStateCreated + 1, 5000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomConferenceJoined, initialLaureStats.number_of_LinphoneChatRoomConferenceJoined + 1, 5000)); BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marieCr), 2, int, "%d"); BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(paulineCr), 2, int, "%d"); char *laureIdentity = linphone_core_get_device_identity(laure->lc); @@ -1571,6 +1579,43 @@ static void group_chat_room_reinvited_after_removed_base (bool_t offline_when_re BC_ASSERT_PTR_EQUAL(newLaureCr, laureCr); BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(newLaureCr), 2, int, "%d"); BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(newLaureCr), initialSubject); + BC_ASSERT_FALSE(linphone_chat_room_has_been_left(newLaureCr)); + + unsigned int nbLaureConferenceCreatedEventsBeforeRestart = 0; + bctbx_list_t *laureHistory = linphone_chat_room_get_history_events(newLaureCr, 0); + for (bctbx_list_t *item = laureHistory; item; item = bctbx_list_next(item)) { + LinphoneEventLog *event = (LinphoneEventLog *)bctbx_list_get_data(item); + if (linphone_event_log_get_type(event) == LinphoneEventLogTypeConferenceCreated) + nbLaureConferenceCreatedEventsBeforeRestart++; + } + bctbx_list_free_with_data(laureHistory, (bctbx_list_free_func)linphone_event_log_unref); + BC_ASSERT_EQUAL(nbLaureConferenceCreatedEventsBeforeRestart, 2, unsigned int, "%u"); + + if (restart_after_reinvited) { + coresList = bctbx_list_remove(coresList, laure->lc); + linphone_core_manager_reinit(laure); + bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, laure); + bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList); + bctbx_list_free(tmpCoresManagerList); + coresList = bctbx_list_concat(coresList, tmpCoresList); + linphone_core_manager_start(laure, TRUE); + laureIdentity = linphone_core_get_device_identity(laure->lc); + laureAddr = linphone_address_new(laureIdentity); + newLaureCr = linphone_core_find_chat_room(laure->lc, confAddr, laureAddr); + linphone_address_unref(laureAddr); + wait_for_list(coresList,0, 1, 2000); + BC_ASSERT_FALSE(linphone_chat_room_has_been_left(newLaureCr)); + + unsigned int nbLaureConferenceCreatedEventsAfterRestart = 0; + bctbx_list_t *laureHistory = linphone_chat_room_get_history_events(newLaureCr, 0); + for (bctbx_list_t *item = laureHistory; item; item = bctbx_list_next(item)) { + LinphoneEventLog *event = (LinphoneEventLog *)bctbx_list_get_data(item); + if (linphone_event_log_get_type(event) == LinphoneEventLogTypeConferenceCreated) + nbLaureConferenceCreatedEventsAfterRestart++; + } + bctbx_list_free_with_data(laureHistory, (bctbx_list_free_func)linphone_event_log_unref); + BC_ASSERT_EQUAL(nbLaureConferenceCreatedEventsAfterRestart, nbLaureConferenceCreatedEventsBeforeRestart, unsigned int, "%u"); + } // Clean db from chat room linphone_core_manager_delete_chat_room(marie, marieCr, coresList); @@ -1585,15 +1630,19 @@ static void group_chat_room_reinvited_after_removed_base (bool_t offline_when_re } static void group_chat_room_reinvited_after_removed (void) { - group_chat_room_reinvited_after_removed_base(FALSE, FALSE); + group_chat_room_reinvited_after_removed_base(FALSE, FALSE, FALSE); +} + +static void group_chat_room_reinvited_after_removed_2 (void) { + group_chat_room_reinvited_after_removed_base(FALSE, FALSE, TRUE); } static void group_chat_room_reinvited_after_removed_while_offline (void) { - group_chat_room_reinvited_after_removed_base(TRUE, FALSE); + group_chat_room_reinvited_after_removed_base(TRUE, FALSE, FALSE); } static void group_chat_room_reinvited_after_removed_while_offline_2 (void) { - group_chat_room_reinvited_after_removed_base(TRUE, TRUE); + group_chat_room_reinvited_after_removed_base(TRUE, TRUE, FALSE); } static void group_chat_room_reinvited_after_removed_with_several_devices (void) { @@ -1715,9 +1764,9 @@ static void group_chat_room_notify_after_disconnection (void) { // Marie now changes the subject const char *newSubject = "New subject"; linphone_chat_room_set_subject(marieCr, newSubject); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed, initialMarieStats.number_of_subject_changed + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed, initialPaulineStats.number_of_subject_changed + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed, initialLaureStats.number_of_subject_changed + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed, initialMarieStats.number_of_subject_changed + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed, initialPaulineStats.number_of_subject_changed + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed, initialLaureStats.number_of_subject_changed + 1, 3000)); BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(marieCr), newSubject); BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(paulineCr), newSubject); BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(laureCr), newSubject); @@ -1728,9 +1777,9 @@ static void group_chat_room_notify_after_disconnection (void) { // Marie now changes the subject newSubject = "Let's go drink a beer"; linphone_chat_room_set_subject(marieCr, newSubject); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed, initialMarieStats.number_of_subject_changed + 2, 10000)); - BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed, initialPaulineStats.number_of_subject_changed + 2, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed, initialLaureStats.number_of_subject_changed + 2, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed, initialMarieStats.number_of_subject_changed + 2, 3000)); + BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed, initialPaulineStats.number_of_subject_changed + 2, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed, initialLaureStats.number_of_subject_changed + 2, 3000)); BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(marieCr), newSubject); BC_ASSERT_STRING_NOT_EQUAL(linphone_chat_room_get_subject(paulineCr), newSubject); BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(laureCr), newSubject); @@ -1738,7 +1787,7 @@ static void group_chat_room_notify_after_disconnection (void) { linphone_core_set_network_reachable(pauline->lc, TRUE); wait_for_list(coresList, &dummy, 1, 1000); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed, initialPaulineStats.number_of_subject_changed + 2, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed, initialPaulineStats.number_of_subject_changed + 2, 3000)); BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(paulineCr), newSubject); @@ -1749,9 +1798,9 @@ static void group_chat_room_notify_after_disconnection (void) { // Marie now changes the subject newSubject = "Let's go drink a mineral water !"; linphone_chat_room_set_subject(marieCr, newSubject); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed, initialMarieStats.number_of_subject_changed + 3, 10000)); - BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed, initialPaulineStats.number_of_subject_changed + 3, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed, initialLaureStats.number_of_subject_changed + 3, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed, initialMarieStats.number_of_subject_changed + 3, 3000)); + BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed, initialPaulineStats.number_of_subject_changed + 3, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed, initialLaureStats.number_of_subject_changed + 3, 3000)); BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(marieCr), newSubject); BC_ASSERT_STRING_NOT_EQUAL(linphone_chat_room_get_subject(paulineCr), newSubject); BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(laureCr), newSubject); @@ -1773,7 +1822,7 @@ static void group_chat_room_notify_after_disconnection (void) { linphone_core_set_network_reachable(pauline->lc, TRUE); wait_for_list(coresList, &dummy, 1, 1000); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed, initialPaulineStats.number_of_subject_changed + 3, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed, initialPaulineStats.number_of_subject_changed + 3, 3000)); BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(paulineCr), newSubject); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participant_admin_statuses_changed, initialPaulineStats.number_of_participant_admin_statuses_changed + 1, 1000)); BC_ASSERT_TRUE(linphone_participant_is_admin(laureParticipantFromPauline)); @@ -1885,7 +1934,6 @@ static void group_chat_room_send_refer_to_all_devices (void) { linphone_core_manager_destroy(laure); } -#if 0 static void group_chat_room_add_device (void) { LinphoneCoreManager *marie1 = linphone_core_manager_create("marie_rc"); LinphoneCoreManager *pauline1 = linphone_core_manager_create("pauline_rc"); @@ -1989,7 +2037,6 @@ static void group_chat_room_add_device (void) { linphone_core_manager_destroy(pauline2); linphone_core_manager_destroy(laure); } -#endif static void multiple_is_composing_notification(void) { LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc"); @@ -2131,15 +2178,15 @@ static void group_chat_room_fallback_to_basic_chat_room (void) { stats initialPaulineStats = pauline->stat; // Marie creates a new group chat room - LinphoneChatRoom *marieCr = linphone_core_create_client_group_chat_room(marie->lc, "Fallback"); + LinphoneChatRoom *marieCr = linphone_core_create_client_group_chat_room(marie->lc, "Fallback", TRUE); BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateInstantiated, initialMarieStats.number_of_LinphoneChatRoomStateInstantiated + 1, 100)); // Add participants linphone_chat_room_add_participants(marieCr, participantsAddresses); // Check that the group chat room creation fails and that a fallback to a basic chat room is done - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreationPending, initialMarieStats.number_of_LinphoneChatRoomStateCreationPending + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreated, initialMarieStats.number_of_LinphoneChatRoomStateCreated + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreationPending, initialMarieStats.number_of_LinphoneChatRoomStateCreationPending + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreated, initialMarieStats.number_of_LinphoneChatRoomStateCreated + 1, 3000)); BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneChatRoomStateCreationFailed, initialMarieStats.number_of_LinphoneChatRoomStateCreationFailed, int, "%d"); BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marieCr), 1, int, "%d"); BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesBasic); @@ -2187,15 +2234,15 @@ static void group_chat_room_creation_fails_if_invited_participants_dont_support_ stats initialMarieStats = marie->stat; // Marie creates a new group chat room - LinphoneChatRoom *marieCr = linphone_core_create_client_group_chat_room(marie->lc, "Hello there"); + LinphoneChatRoom *marieCr = linphone_core_create_client_group_chat_room(marie->lc, "Hello there", FALSE); BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateInstantiated, initialMarieStats.number_of_LinphoneChatRoomStateInstantiated + 1, 100)); // Add participants linphone_chat_room_add_participants(marieCr, participantsAddresses); - // Check that the group chat room creation fails and that a fallback to a basic chat room is done - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreationPending, initialMarieStats.number_of_LinphoneChatRoomStateCreationPending + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreationFailed, initialMarieStats.number_of_LinphoneChatRoomStateCreationFailed + 1, 10000)); + // Check that the group chat room creation fails + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreationPending, initialMarieStats.number_of_LinphoneChatRoomStateCreationPending + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreationFailed, initialMarieStats.number_of_LinphoneChatRoomStateCreationFailed + 1, 3000)); bctbx_list_free_with_data(participantsAddresses, (bctbx_list_free_func)linphone_address_unref); participantsAddresses = NULL; BC_ASSERT_EQUAL(linphone_chat_room_get_state(marieCr), LinphoneChatRoomStateCreationFailed, int, "%d"); @@ -2299,14 +2346,16 @@ static void group_chat_room_migrate_from_basic_chat_room (void) { msg = linphone_chat_room_create_message(marieCr, "Did you migrate?"); linphone_chat_message_send(msg); linphone_chat_message_unref(msg); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreationPending, initialMarieStats.number_of_LinphoneChatRoomStateCreationPending + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreated, initialMarieStats.number_of_LinphoneChatRoomStateCreated + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreationPending, initialMarieStats.number_of_LinphoneChatRoomStateCreationPending + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreated, initialMarieStats.number_of_LinphoneChatRoomStateCreated + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomConferenceJoined, initialMarieStats.number_of_LinphoneChatRoomConferenceJoined + 1, 3000)); BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesConference); BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marieCr), 1, int, "%d"); BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(marieCr), 2, int, "%d"); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomStateCreationPending, initialPaulineStats.number_of_LinphoneChatRoomStateCreationPending + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomStateCreated, initialPaulineStats.number_of_LinphoneChatRoomStateCreated + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomStateCreationPending, initialPaulineStats.number_of_LinphoneChatRoomStateCreationPending + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomStateCreated, initialPaulineStats.number_of_LinphoneChatRoomStateCreated + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomConferenceJoined, initialPaulineStats.number_of_LinphoneChatRoomConferenceJoined + 1, 3000)); BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(paulineCr) & LinphoneChatRoomCapabilitiesConference); BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(paulineCr), 1, int, "%d"); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 1000)); @@ -2357,15 +2406,15 @@ static void group_chat_room_migrate_from_basic_to_client_fail (void) { stats initialPaulineStats = pauline->stat; // Marie creates a new group chat room - LinphoneChatRoom *marieCr = linphone_core_create_client_group_chat_room(marie->lc, "Fallback"); + LinphoneChatRoom *marieCr = linphone_core_create_client_group_chat_room(marie->lc, "Fallback", TRUE); BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateInstantiated, initialMarieStats.number_of_LinphoneChatRoomStateInstantiated + 1, 100)); // Add participants linphone_chat_room_add_participants(marieCr, participantsAddresses); // Check that the group chat room creation fails and that a fallback to a basic chat room is done - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreationPending, initialMarieStats.number_of_LinphoneChatRoomStateCreationPending + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreated, initialMarieStats.number_of_LinphoneChatRoomStateCreated + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreationPending, initialMarieStats.number_of_LinphoneChatRoomStateCreationPending + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreated, initialMarieStats.number_of_LinphoneChatRoomStateCreated + 1, 3000)); BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneChatRoomStateCreationFailed, initialMarieStats.number_of_LinphoneChatRoomStateCreationFailed, int, "%d"); BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marieCr), 1, int, "%d"); BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesBasic); @@ -2375,6 +2424,7 @@ static void group_chat_room_migrate_from_basic_to_client_fail (void) { // Send a message and check that a basic chat room is created on Pauline's side LinphoneChatMessage *msg = linphone_chat_room_create_message(marieCr, "Hey Pauline!"); linphone_chat_message_send(msg); + linphone_chat_message_unref(msg); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 1000)); BC_ASSERT_PTR_NOT_NULL(pauline->stat.last_received_chat_message); if (pauline->stat.last_received_chat_message) @@ -2386,17 +2436,19 @@ static void group_chat_room_migrate_from_basic_to_client_fail (void) { // Enable chat room migration and restart core for Marie _linphone_chat_room_enable_migration(marieCr, TRUE); + linphone_chat_room_unref(marieCr); coresList = bctbx_list_remove(coresList, marie->lc); linphone_core_manager_reinit(marie); bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, marie); - init_core_for_conference(tmpCoresManagerList); + bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList); bctbx_list_free(tmpCoresManagerList); - coresList = bctbx_list_append(coresList, marie->lc); + coresList = bctbx_list_concat(coresList, tmpCoresList); linphone_core_manager_start(marie, TRUE); // Send a new message to initiate chat room migration LinphoneAddress *paulineAddr = linphone_address_new(linphone_core_get_identity(pauline->lc)); marieCr = linphone_core_get_chat_room(marie->lc, paulineAddr); + linphone_address_unref(paulineAddr); BC_ASSERT_PTR_NOT_NULL(marieCr); if (marieCr) { initialMarieStats = marie->stat; @@ -2404,6 +2456,7 @@ static void group_chat_room_migrate_from_basic_to_client_fail (void) { BC_ASSERT_EQUAL(linphone_chat_room_get_capabilities(marieCr), LinphoneChatRoomCapabilitiesBasic | LinphoneChatRoomCapabilitiesProxy | LinphoneChatRoomCapabilitiesMigratable | LinphoneChatRoomCapabilitiesOneToOne, int, "%d"); msg = linphone_chat_room_create_message(marieCr, "Did you migrate?"); linphone_chat_message_send(msg); + linphone_chat_message_unref(msg); BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreationPending, initialMarieStats.number_of_LinphoneChatRoomStateCreationPending + 1, 3000)); BC_ASSERT_FALSE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreated, initialMarieStats.number_of_LinphoneChatRoomStateCreated + 1, 3000)); BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesBasic); @@ -2419,18 +2472,20 @@ static void group_chat_room_migrate_from_basic_to_client_fail (void) { msg = linphone_chat_room_create_message(marieCr, "Let's go drink a beer"); linphone_chat_message_send(msg); + linphone_chat_message_unref(msg); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 2, 1000)); BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(marieCr), 3, int, "%d"); BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(paulineCr), 3, int, "%d"); msg = linphone_chat_room_create_message(paulineCr, "Let's go drink mineral water instead"); linphone_chat_message_send(msg); + linphone_chat_message_unref(msg); BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, initialMarieStats.number_of_LinphoneMessageReceived + 1, 1000)); BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(marieCr), 4, int, "%d"); BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(paulineCr), 4, int, "%d"); // Activate groupchat on Pauline's side and wait for 5 seconds, the migration should now be done on next message sending - lp_config_set_int(linphone_core_get_config(marie->lc),"misc","basic_to_client_group_chat_room_migration_timer",5); + lp_config_set_int(linphone_core_get_config(marie->lc), "misc", "basic_to_client_group_chat_room_migration_timer", 5); linphone_core_set_linphone_specs(pauline->lc, "groupchat"); linphone_core_set_network_reachable(pauline->lc, FALSE); wait_for_list(coresList, &dummy, 1, 1000); @@ -2438,14 +2493,17 @@ static void group_chat_room_migrate_from_basic_to_client_fail (void) { wait_for_list(coresList, &dummy, 1, 5000); msg = linphone_chat_room_create_message(marieCr, "And now, did you migrate?"); linphone_chat_message_send(msg); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreationPending, initialMarieStats.number_of_LinphoneChatRoomStateCreationPending + 2, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreated, initialMarieStats.number_of_LinphoneChatRoomStateCreated + 1, 10000)); + linphone_chat_message_unref(msg); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreationPending, initialMarieStats.number_of_LinphoneChatRoomStateCreationPending + 2, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreated, initialMarieStats.number_of_LinphoneChatRoomStateCreated + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomConferenceJoined, initialMarieStats.number_of_LinphoneChatRoomConferenceJoined + 1, 3000)); BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesConference); BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marieCr), 1, int, "%d"); BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(marieCr), 5, int, "%d"); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomStateCreationPending, initialPaulineStats.number_of_LinphoneChatRoomStateCreationPending + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomStateCreated, initialPaulineStats.number_of_LinphoneChatRoomStateCreated + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomStateCreationPending, initialPaulineStats.number_of_LinphoneChatRoomStateCreationPending + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomStateCreated, initialPaulineStats.number_of_LinphoneChatRoomStateCreated + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomConferenceJoined, initialPaulineStats.number_of_LinphoneChatRoomConferenceJoined + 1, 3000)); BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(paulineCr) & LinphoneChatRoomCapabilitiesConference); BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(paulineCr), 1, int, "%d"); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 3, 1000)); @@ -2508,13 +2566,13 @@ static void group_chat_donot_room_migrate_from_basic_chat_room (void) { msg = linphone_chat_room_create_message(marieCr, "Did you migrate?"); linphone_chat_message_send(msg); linphone_chat_message_unref(msg); - BC_ASSERT_FALSE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreationPending, initialMarieStats.number_of_LinphoneChatRoomStateCreationPending + 1, 10000)); + BC_ASSERT_FALSE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreationPending, initialMarieStats.number_of_LinphoneChatRoomStateCreationPending + 1, 3000)); BC_ASSERT_FALSE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreated, initialMarieStats.number_of_LinphoneChatRoomStateCreated + 1, 3000)); BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesBasic); BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marieCr), 1, int, "%d"); BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(marieCr), 2, int, "%d"); - BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomStateCreationPending, initialPaulineStats.number_of_LinphoneChatRoomStateCreationPending + 1, 10000)); + BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomStateCreationPending, initialPaulineStats.number_of_LinphoneChatRoomStateCreationPending + 1, 3000)); BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomStateCreated, initialPaulineStats.number_of_LinphoneChatRoomStateCreated + 1, 3000)); BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(paulineCr) & LinphoneChatRoomCapabilitiesBasic); BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(paulineCr), 1, int, "%d"); @@ -2657,8 +2715,8 @@ static void group_chat_room_unique_one_to_one_chat_room (void) { // Marie sends a message const char *textMessage = "Hello"; LinphoneChatMessage *message = _send_message(marieCr, textMessage); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageDelivered, initialMarieStats.number_of_LinphoneMessageDelivered + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageDelivered, initialMarieStats.number_of_LinphoneMessageDelivered + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 3000)); BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), textMessage); linphone_chat_message_unref(message); @@ -2676,8 +2734,8 @@ static void group_chat_room_unique_one_to_one_chat_room (void) { // Marie sends a new message textMessage = "Hey again"; message = _send_message(marieCr, textMessage); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageDelivered, initialMarieStats.number_of_LinphoneMessageDelivered + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageDelivered, initialMarieStats.number_of_LinphoneMessageDelivered + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 3000)); BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), textMessage); linphone_chat_message_unref(message); @@ -2723,8 +2781,8 @@ static void group_chat_room_unique_one_to_one_chat_room_recreated_from_message_b // Marie sends a message const char *textMessage = "Hello"; LinphoneChatMessage *message = _send_message(marieCr, textMessage); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageDelivered, initialMarieStats.number_of_LinphoneMessageDelivered + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageDelivered, initialMarieStats.number_of_LinphoneMessageDelivered + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 3000)); BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), textMessage); linphone_chat_message_unref(message); @@ -2755,8 +2813,8 @@ static void group_chat_room_unique_one_to_one_chat_room_recreated_from_message_b // Pauline sends a new message textMessage = "Hey you"; message = _send_message(paulineCr, textMessage); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageDelivered, initialPaulineStats.number_of_LinphoneMessageDelivered + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, initialMarieStats.number_of_LinphoneMessageReceived + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageDelivered, initialPaulineStats.number_of_LinphoneMessageDelivered + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, initialMarieStats.number_of_LinphoneMessageReceived + 1, 3000)); BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marie->stat.last_received_chat_message), textMessage); linphone_chat_message_unref(message); @@ -2792,10 +2850,10 @@ static void group_chat_room_unique_one_to_one_chat_room_recreated_from_message_w static void group_chat_room_unique_one_to_one_chat_room_recreated_from_message_2 (void) { LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc"); LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc"); - /*create a second device for marie, but it is inactive after registration in this test*/ + // Create a second device for Marie, but it is inactive after registration in this test LinphoneCoreManager *marie2 = linphone_core_manager_create("marie_rc"); - /*Create a seconde device for pauline, but again inactivate after registration*/ - LinphoneCoreManager *pauline2 = linphone_core_manager_create("marie_rc"); + // Create a second device for Pauline, but again inactivate it after registration + LinphoneCoreManager *pauline2 = linphone_core_manager_create("pauline_rc"); bctbx_list_t *coresManagerList = NULL; bctbx_list_t *participantsAddresses = NULL; coresManagerList = bctbx_list_append(coresManagerList, marie); @@ -2807,10 +2865,12 @@ static void group_chat_room_unique_one_to_one_chat_room_recreated_from_message_2 participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc))); stats initialMarieStats = marie->stat; stats initialPaulineStats = pauline->stat; + stats initialMarie2Stats = marie2->stat; + stats initialPauline2Stats = pauline2->stat; linphone_core_set_network_reachable(marie2->lc, FALSE); linphone_core_set_network_reachable(pauline2->lc, FALSE); - + // Marie creates a new group chat room const char *initialSubject = "Pauline"; LinphoneChatRoom *marieCr = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, -1); @@ -2825,8 +2885,8 @@ static void group_chat_room_unique_one_to_one_chat_room_recreated_from_message_2 // Marie sends a message const char *textMessage = "Hello"; LinphoneChatMessage *message = _send_message(marieCr, textMessage); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageDelivered, initialMarieStats.number_of_LinphoneMessageDelivered + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageDelivered, initialMarieStats.number_of_LinphoneMessageDelivered + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 3000)); BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), textMessage); linphone_chat_message_unref(message); @@ -2848,17 +2908,29 @@ static void group_chat_room_unique_one_to_one_chat_room_recreated_from_message_2 BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesOneToOne); textMessage = "Hey you"; message = _send_message(marieCr, textMessage); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageDelivered, initialMarieStats.number_of_LinphoneMessageDelivered + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageDelivered, initialMarieStats.number_of_LinphoneMessageDelivered + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 3000)); BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), textMessage); linphone_chat_message_unref(message); - - // Clean db from chat room - linphone_core_manager_delete_chat_room(marie, marieCr, coresList); } - linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList); - wait_for_list(coresList, 0, 1, 2000); + // Clean db from chat room + linphone_core_set_network_reachable(marie2->lc, TRUE); + linphone_core_set_network_reachable(pauline2->lc, TRUE); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie2->stat.number_of_LinphoneChatRoomStateCreationPending, initialMarie2Stats.number_of_LinphoneChatRoomStateCreationPending + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie2->stat.number_of_LinphoneChatRoomStateCreated, initialMarie2Stats.number_of_LinphoneChatRoomStateCreated + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie2->stat.number_of_LinphoneChatRoomConferenceJoined, initialMarie2Stats.number_of_LinphoneChatRoomConferenceJoined + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline2->stat.number_of_LinphoneChatRoomStateCreationPending, initialPauline2Stats.number_of_LinphoneChatRoomStateCreationPending + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline2->stat.number_of_LinphoneChatRoomStateCreated, initialPauline2Stats.number_of_LinphoneChatRoomStateCreated + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline2->stat.number_of_LinphoneChatRoomConferenceJoined, initialPauline2Stats.number_of_LinphoneChatRoomConferenceJoined + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline2->stat.number_of_LinphoneMessageReceived, initialPauline2Stats.number_of_LinphoneMessageReceived + 1, 3000)); + linphone_core_manager_delete_chat_room(marie, marieCr, coresList); + linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateTerminated, initialMarieStats.number_of_LinphoneChatRoomStateTerminated + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomStateTerminated, initialPaulineStats.number_of_LinphoneChatRoomStateTerminated + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie2->stat.number_of_LinphoneChatRoomStateTerminated, initialMarie2Stats.number_of_LinphoneChatRoomStateTerminated + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline2->stat.number_of_LinphoneChatRoomStateTerminated, initialPauline2Stats.number_of_LinphoneChatRoomStateTerminated + 1, 3000)); + BC_ASSERT_EQUAL(linphone_core_get_call_history_size(marie->lc), 0, int,"%i"); BC_ASSERT_EQUAL(linphone_core_get_call_history_size(pauline->lc), 0, int,"%i"); BC_ASSERT_PTR_NULL(linphone_core_get_call_logs(marie->lc)); @@ -2867,8 +2939,6 @@ static void group_chat_room_unique_one_to_one_chat_room_recreated_from_message_2 linphone_address_unref(confAddr); bctbx_list_free(coresList); bctbx_list_free(coresManagerList); - linphone_core_set_network_reachable(marie2->lc, TRUE); - linphone_core_set_network_reachable(pauline2->lc, TRUE); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); linphone_core_manager_destroy(marie2); @@ -2901,16 +2971,16 @@ static void group_chat_room_join_one_to_one_chat_room_with_a_new_device (void) { // Marie1 sends a message const char *textMessage = "Hello"; LinphoneChatMessage *message = _send_message(marie1Cr, textMessage); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie1->stat.number_of_LinphoneMessageDelivered, initialMarie1Stats.number_of_LinphoneMessageDelivered + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie1->stat.number_of_LinphoneMessageDelivered, initialMarie1Stats.number_of_LinphoneMessageDelivered + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 3000)); BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), textMessage); linphone_chat_message_unref(message); // Pauline answers to the previous message textMessage = "Hey. How are you?"; message = _send_message(paulineCr, textMessage); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageDelivered, initialPaulineStats.number_of_LinphoneMessageDelivered + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie1->stat.number_of_LinphoneMessageReceived, initialMarie1Stats.number_of_LinphoneMessageReceived + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageDelivered, initialPaulineStats.number_of_LinphoneMessageDelivered + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie1->stat.number_of_LinphoneMessageReceived, initialMarie1Stats.number_of_LinphoneMessageReceived + 1, 3000)); BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marie1->stat.last_received_chat_message), textMessage); linphone_chat_message_unref(message); @@ -2919,6 +2989,7 @@ static void group_chat_room_join_one_to_one_chat_room_with_a_new_device (void) { coresManagerList = bctbx_list_remove(coresManagerList, marie1); coresList = bctbx_list_remove(coresList, marie1->lc); LinphoneCoreManager *marie2 = linphone_core_manager_create("marie_rc"); + stats initialMarie2Stats = marie2->stat; bctbx_list_t *newCoresManagerList = bctbx_list_append(NULL, marie2); bctbx_list_t *newCoresList = init_core_for_conference(newCoresManagerList); start_core_for_conference(newCoresManagerList); @@ -2926,27 +2997,29 @@ static void group_chat_room_join_one_to_one_chat_room_with_a_new_device (void) { coresList = bctbx_list_concat(coresList, newCoresList); // Marie2 gets the one-to-one chat room with Pauline - stats initialMarie2Stats = marie2->stat; LinphoneChatRoom *marie2Cr = check_creation_chat_room_client_side(coresList, marie2, &initialMarie2Stats, confAddr, initialSubject, 1, FALSE); BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marie2Cr) & LinphoneChatRoomCapabilitiesOneToOne); // Marie2 sends a new message textMessage = "Fine and you?"; message = _send_message(marie2Cr, textMessage); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie2->stat.number_of_LinphoneMessageDelivered, initialMarie2Stats.number_of_LinphoneMessageDelivered + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 2, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie2->stat.number_of_LinphoneMessageDelivered, initialMarie2Stats.number_of_LinphoneMessageDelivered + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 2, 3000)); BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), textMessage); linphone_chat_message_unref(message); // Pauline answers to the previous message textMessage = "Perfect!"; message = _send_message(paulineCr, textMessage); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageDelivered, initialPaulineStats.number_of_LinphoneMessageDelivered + 2, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie2->stat.number_of_LinphoneMessageReceived, initialMarie2Stats.number_of_LinphoneMessageReceived + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageDelivered, initialPaulineStats.number_of_LinphoneMessageDelivered + 2, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie2->stat.number_of_LinphoneMessageReceived, initialMarie2Stats.number_of_LinphoneMessageReceived + 1, 3000)); BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marie2->stat.last_received_chat_message), textMessage); linphone_chat_message_unref(message); // Clean db from chat room + int previousNbRegistrationOk = marie1->stat.number_of_LinphoneRegistrationOk; + linphone_core_set_network_reachable(marie1->lc, TRUE); + wait_for_until(marie1->lc, NULL, &marie1->stat.number_of_LinphoneRegistrationOk, previousNbRegistrationOk + 1, 2000); linphone_core_manager_delete_chat_room(marie2, marie2Cr, coresList); linphone_core_delete_chat_room(marie1->lc, marie1Cr); linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList); @@ -2986,6 +3059,7 @@ static void group_chat_room_new_unique_one_to_one_chat_room_after_both_participa // Both participants delete the chat room linphone_core_manager_delete_chat_room(marie, marieCr, coresList); linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList); + wait_for_list(coresList, 0, 1, 3000); // Marie re-creates a chat room with Pauline initialMarieStats = marie->stat; @@ -3031,14 +3105,12 @@ static void imdn_for_group_chat_room (void) { stats initialMarieStats = marie->stat; stats initialPaulineStats = pauline->stat; stats initialChloeStats = chloe->stat; + time_t initialTime = ms_time(NULL); // Enable IMDN linphone_im_notif_policy_enable_all(linphone_core_get_im_notif_policy(marie->lc)); linphone_im_notif_policy_enable_all(linphone_core_get_im_notif_policy(pauline->lc)); linphone_im_notif_policy_enable_all(linphone_core_get_im_notif_policy(chloe->lc)); - linphone_config_set_bool(linphone_core_get_config(marie->lc), "misc", "enable_simple_group_chat_message_state", FALSE); - linphone_config_set_bool(linphone_core_get_config(pauline->lc), "misc", "enable_simple_group_chat_message_state", FALSE); - linphone_config_set_bool(linphone_core_get_config(chloe->lc), "misc", "enable_simple_group_chat_message_state", FALSE); // Marie creates a new group chat room const char *initialSubject = "Colleagues"; @@ -3054,8 +3126,8 @@ static void imdn_for_group_chat_room (void) { // Chloe begins composing a message const char *chloeTextMessage = "Hello"; LinphoneChatMessage *chloeMessage = _send_message(chloeCr, chloeTextMessage); - BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, initialMarieStats.number_of_LinphoneMessageReceived + 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, initialMarieStats.number_of_LinphoneMessageReceived + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 3000)); LinphoneChatMessage *marieLastMsg = marie->stat.last_received_chat_message; if (!BC_ASSERT_PTR_NOT_NULL(marieLastMsg)) goto end; @@ -3065,15 +3137,238 @@ static void imdn_for_group_chat_room (void) { linphone_address_unref(chloeAddr); // Check that the message has been delivered to Marie and Pauline - BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneMessageDeliveredToUser, initialChloeStats.number_of_LinphoneMessageDeliveredToUser + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneMessageDeliveredToUser, initialChloeStats.number_of_LinphoneMessageDeliveredToUser + 1, 3000)); + BC_ASSERT_PTR_NULL(linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDisplayed)); + bctbx_list_t *participantsThatReceivedChloeMessage = linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDeliveredToUser); + if (BC_ASSERT_PTR_NOT_NULL(participantsThatReceivedChloeMessage)) { + BC_ASSERT_EQUAL((int)bctbx_list_size(participantsThatReceivedChloeMessage), 2, int, "%d"); + for (bctbx_list_t *item = participantsThatReceivedChloeMessage; item; item = bctbx_list_next(item)) { + LinphoneParticipantImdnState *state = (LinphoneParticipantImdnState *)bctbx_list_get_data(item); + BC_ASSERT_GREATER(linphone_participant_imdn_state_get_state_change_time(state), initialTime, int, "%d"); + BC_ASSERT_EQUAL(linphone_participant_imdn_state_get_state(state), LinphoneChatMessageStateDeliveredToUser, int, "%d"); + BC_ASSERT_PTR_NOT_NULL(linphone_participant_imdn_state_get_participant(state)); + } + bctbx_list_free_with_data(participantsThatReceivedChloeMessage, (bctbx_list_free_func)linphone_participant_imdn_state_unref); + } + BC_ASSERT_PTR_NULL(linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDelivered)); + BC_ASSERT_PTR_NULL(linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateNotDelivered)); // Marie marks the message as read, check that the state is not yet displayed on Chloe's side linphone_chat_room_mark_as_read(marieCr); - BC_ASSERT_FALSE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneMessageDisplayed, initialChloeStats.number_of_LinphoneMessageDisplayed + 1, 1000)); + BC_ASSERT_FALSE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneMessageDisplayed, initialChloeStats.number_of_LinphoneMessageDisplayed + 1, 3000)); + bctbx_list_t *participantsThatDisplayedChloeMessage = linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDisplayed); + if (BC_ASSERT_PTR_NOT_NULL(participantsThatDisplayedChloeMessage)) { + BC_ASSERT_EQUAL((int)bctbx_list_size(participantsThatDisplayedChloeMessage), 1, int, "%d"); + bctbx_list_free_with_data(participantsThatDisplayedChloeMessage, (bctbx_list_free_func)linphone_participant_imdn_state_unref); + } + participantsThatReceivedChloeMessage = linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDeliveredToUser); + if (BC_ASSERT_PTR_NOT_NULL(participantsThatReceivedChloeMessage)) { + BC_ASSERT_EQUAL((int)bctbx_list_size(participantsThatReceivedChloeMessage), 1, int, "%d"); + bctbx_list_free_with_data(participantsThatReceivedChloeMessage, (bctbx_list_free_func)linphone_participant_imdn_state_unref); + } + BC_ASSERT_PTR_NULL(linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDelivered)); + BC_ASSERT_PTR_NULL(linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateNotDelivered)); // Pauline also marks the message as read, check that the state is now displayed on Chloe's side linphone_chat_room_mark_as_read(paulineCr); - BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneMessageDisplayed, initialChloeStats.number_of_LinphoneMessageDisplayed + 1, 1000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneMessageDisplayed, initialChloeStats.number_of_LinphoneMessageDisplayed + 1, 3000)); + participantsThatDisplayedChloeMessage = linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDisplayed); + if (BC_ASSERT_PTR_NOT_NULL(participantsThatDisplayedChloeMessage)) { + BC_ASSERT_EQUAL((int)bctbx_list_size(participantsThatDisplayedChloeMessage), 2, int, "%d"); + bctbx_list_free_with_data(participantsThatDisplayedChloeMessage, (bctbx_list_free_func)linphone_participant_imdn_state_unref); + } + BC_ASSERT_PTR_NULL(linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDeliveredToUser)); + BC_ASSERT_PTR_NULL(linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDelivered)); + BC_ASSERT_PTR_NULL(linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateNotDelivered)); + + linphone_chat_message_unref(chloeMessage); + +end: + // Clean db from chat room + linphone_core_manager_delete_chat_room(marie, marieCr, coresList); + linphone_core_manager_delete_chat_room(chloe, chloeCr, coresList); + linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList); + + bctbx_list_free(coresList); + bctbx_list_free(coresManagerList); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(chloe); +} + +static void aggregated_imdn_for_group_chat_room_base (bool_t read_while_offline) { + LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc"); + LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc"); + LinphoneCoreManager *chloe = linphone_core_manager_create("chloe_rc"); + bctbx_list_t *coresManagerList = NULL; + bctbx_list_t *participantsAddresses = NULL; + coresManagerList = bctbx_list_append(coresManagerList, marie); + coresManagerList = bctbx_list_append(coresManagerList, pauline); + coresManagerList = bctbx_list_append(coresManagerList, chloe); + bctbx_list_t *coresList = init_core_for_conference(coresManagerList); + start_core_for_conference(coresManagerList); + participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc))); + participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(chloe->lc))); + stats initialMarieStats = marie->stat; + stats initialPaulineStats = pauline->stat; + stats initialChloeStats = chloe->stat; + + // Enable IMDN + linphone_im_notif_policy_enable_all(linphone_core_get_im_notif_policy(marie->lc)); + linphone_im_notif_policy_enable_all(linphone_core_get_im_notif_policy(pauline->lc)); + linphone_im_notif_policy_enable_all(linphone_core_get_im_notif_policy(chloe->lc)); + + // Marie creates a new group chat room + const char *initialSubject = "Colleagues"; + LinphoneChatRoom *marieCr = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, -1); + const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr); + + // Check that the chat room is correctly created on Pauline's side and that the participants are added + LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr, initialSubject, 2, FALSE); + + // Check that the chat room is correctly created on Chloe's side and that the participants are added + LinphoneChatRoom *chloeCr = check_creation_chat_room_client_side(coresList, chloe, &initialChloeStats, confAddr, initialSubject, 2, FALSE); + + // Chloe begins composing a message + const char *chloeTextMessage = "Hello"; + const char *chloeTextMessage2 = "Long time no talk"; + const char *chloeTextMessage3 = "How are you?"; + LinphoneChatMessage *chloeMessage = _send_message(chloeCr, chloeTextMessage); + LinphoneChatMessage *chloeMessage2 = _send_message(chloeCr, chloeTextMessage2); + LinphoneChatMessage *chloeMessage3 = _send_message(chloeCr, chloeTextMessage3); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, initialMarieStats.number_of_LinphoneMessageReceived + 3, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 3, 3000)); + LinphoneChatMessage *marieLastMsg = marie->stat.last_received_chat_message; + if (!BC_ASSERT_PTR_NOT_NULL(marieLastMsg)) + goto end; + BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marieLastMsg), chloeTextMessage3); + LinphoneAddress *chloeAddr = linphone_address_new(linphone_core_get_identity(chloe->lc)); + BC_ASSERT_TRUE(linphone_address_weak_equal(chloeAddr, linphone_chat_message_get_from_address(marieLastMsg))); + linphone_address_unref(chloeAddr); + + // Mark the messages as read on Marie's and Pauline's sides + linphone_chat_room_mark_as_read(marieCr); + if (read_while_offline) { + linphone_core_set_network_reachable(pauline->lc, FALSE); + linphone_chat_room_mark_as_read(paulineCr); + wait_for_list(coresList, 0, 1, 2000); + linphone_core_set_network_reachable(pauline->lc, TRUE); + } else { + linphone_chat_room_mark_as_read(paulineCr); + } + BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneMessageDisplayed, initialChloeStats.number_of_LinphoneMessageDisplayed + 1, 3000)); + BC_ASSERT_EQUAL(chloe->stat.number_of_LinphoneMessageDeliveredToUser, 0, int, "%d"); + if (read_while_offline) { + wait_for_list(coresList, 0, 1, 2000); // To prevent memory leak + } + + linphone_chat_message_unref(chloeMessage3); + linphone_chat_message_unref(chloeMessage2); + linphone_chat_message_unref(chloeMessage); + +end: + // Clean db from chat room + linphone_core_manager_delete_chat_room(marie, marieCr, coresList); + linphone_core_manager_delete_chat_room(chloe, chloeCr, coresList); + linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList); + + bctbx_list_free(coresList); + bctbx_list_free(coresManagerList); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(chloe); +} + +static void aggregated_imdn_for_group_chat_room (void) { + aggregated_imdn_for_group_chat_room_base(FALSE); +} + +static void aggregated_imdn_for_group_chat_room_read_while_offline (void) { + aggregated_imdn_for_group_chat_room_base(TRUE); +} + +static void imdn_sent_from_db_state (void) { + LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc"); + LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc"); + LinphoneCoreManager *chloe = linphone_core_manager_create("chloe_rc"); + bctbx_list_t *coresManagerList = NULL; + bctbx_list_t *participantsAddresses = NULL; + coresManagerList = bctbx_list_append(coresManagerList, marie); + coresManagerList = bctbx_list_append(coresManagerList, pauline); + coresManagerList = bctbx_list_append(coresManagerList, chloe); + bctbx_list_t *coresList = init_core_for_conference(coresManagerList); + start_core_for_conference(coresManagerList); + participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc))); + participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(chloe->lc))); + stats initialMarieStats = marie->stat; + stats initialPaulineStats = pauline->stat; + stats initialChloeStats = chloe->stat; + time_t initialTime = ms_time(NULL); + + // Enable IMDN except for Marie + linphone_im_notif_policy_clear(linphone_core_get_im_notif_policy(marie->lc)); + linphone_im_notif_policy_enable_all(linphone_core_get_im_notif_policy(pauline->lc)); + linphone_im_notif_policy_enable_all(linphone_core_get_im_notif_policy(chloe->lc)); + + // Marie creates a new group chat room + const char *initialSubject = "Colleagues"; + LinphoneChatRoom *marieCr = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, -1); + LinphoneAddress *confAddr = linphone_address_clone(linphone_chat_room_get_conference_address(marieCr)); + + // Check that the chat room is correctly created on Pauline's side and that the participants are added + LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr, initialSubject, 2, FALSE); + + // Check that the chat room is correctly created on Chloe's side and that the participants are added + LinphoneChatRoom *chloeCr = check_creation_chat_room_client_side(coresList, chloe, &initialChloeStats, confAddr, initialSubject, 2, FALSE); + + // Chloe begins composing a message + const char *chloeTextMessage = "Hello"; + LinphoneChatMessage *chloeMessage = _send_message(chloeCr, chloeTextMessage); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, initialMarieStats.number_of_LinphoneMessageReceived + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 3000)); + LinphoneChatMessage *marieLastMsg = marie->stat.last_received_chat_message; + if (!BC_ASSERT_PTR_NOT_NULL(marieLastMsg)) + goto end; + BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marieLastMsg), chloeTextMessage); + LinphoneAddress *chloeAddr = linphone_address_new(linphone_core_get_identity(chloe->lc)); + BC_ASSERT_TRUE(linphone_address_weak_equal(chloeAddr, linphone_chat_message_get_from_address(marieLastMsg))); + linphone_address_unref(chloeAddr); + + // Check that the message is not globally marked as delivered to user since Marie do not notify its delivery + BC_ASSERT_FALSE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneMessageDeliveredToUser, initialChloeStats.number_of_LinphoneMessageDeliveredToUser + 1, 3000)); + + // Restart Marie's core with IMDN enabled so that delivery notification is sent when chat room is loaded from DB + coresList = bctbx_list_remove(coresList, marie->lc); + linphone_core_manager_reinit(marie); + bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, marie); + bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList); + bctbx_list_free(tmpCoresManagerList); + coresList = bctbx_list_concat(coresList, tmpCoresList); + linphone_im_notif_policy_enable_all(linphone_core_get_im_notif_policy(marie->lc)); + linphone_core_manager_start(marie, TRUE); + char *marieIdentity = linphone_core_get_device_identity(marie->lc); + LinphoneAddress *marieAddr = linphone_address_new(marieIdentity); + bctbx_free(marieIdentity); + marieCr = linphone_core_find_chat_room(marie->lc, confAddr, marieAddr); + linphone_address_unref(marieAddr); + linphone_address_unref(confAddr); + + // Check that the message has been delivered to Marie and Pauline + BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneMessageDeliveredToUser, initialChloeStats.number_of_LinphoneMessageDeliveredToUser + 1, 3000)); + BC_ASSERT_PTR_NULL(linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDisplayed)); + bctbx_list_t *participantsThatReceivedChloeMessage = linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDeliveredToUser); + if (BC_ASSERT_PTR_NOT_NULL(participantsThatReceivedChloeMessage)) { + BC_ASSERT_EQUAL((int)bctbx_list_size(participantsThatReceivedChloeMessage), 2, int, "%d"); + for (bctbx_list_t *item = participantsThatReceivedChloeMessage; item; item = bctbx_list_next(item)) { + LinphoneParticipantImdnState *state = (LinphoneParticipantImdnState *)bctbx_list_get_data(item); + BC_ASSERT_GREATER(linphone_participant_imdn_state_get_state_change_time(state), initialTime, int, "%d"); + BC_ASSERT_EQUAL(linphone_participant_imdn_state_get_state(state), LinphoneChatMessageStateDeliveredToUser, int, "%d"); + BC_ASSERT_PTR_NOT_NULL(linphone_participant_imdn_state_get_participant(state)); + } + bctbx_list_free_with_data(participantsThatReceivedChloeMessage, (bctbx_list_free_func)linphone_participant_imdn_state_unref); + } + BC_ASSERT_PTR_NULL(linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDelivered)); + BC_ASSERT_PTR_NULL(linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateNotDelivered)); linphone_chat_message_unref(chloeMessage); @@ -3124,7 +3419,7 @@ static void find_one_to_one_chat_room (void) { // Chloe leave the chat room linphone_chat_room_leave(chloeCr); BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneChatRoomStateTerminationPending, initialChloeStats.number_of_LinphoneChatRoomStateTerminationPending + 1, 100)); - BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneChatRoomStateTerminated, initialChloeStats.number_of_LinphoneChatRoomStateTerminated + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneChatRoomStateTerminated, initialChloeStats.number_of_LinphoneChatRoomStateTerminated + 1, 3000)); BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participants_removed, initialPaulineStats.number_of_participants_removed + 1, 1000)); BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participants_removed, initialMarieStats.number_of_participants_removed + 1, 1000)); @@ -3233,6 +3528,302 @@ static void group_chat_room_new_device_after_creation (void) { linphone_core_manager_destroy(laure); } +static void group_chat_room_list_subscription (void) { + LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc"); + LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc"); + LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc"); + bctbx_list_t *coresManagerList = NULL; + bctbx_list_t *participantsAddresses = NULL; + coresManagerList = bctbx_list_append(coresManagerList, marie); + coresManagerList = bctbx_list_append(coresManagerList, pauline); + coresManagerList = bctbx_list_append(coresManagerList, laure); + bctbx_list_t *coresList = init_core_for_conference(coresManagerList); + stats initialMarieStats = marie->stat; + stats initialPaulineStats = pauline->stat; + stats initialLaureStats = laure->stat; + start_core_for_conference(coresManagerList); + participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc))); + participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc))); + int dummy = 0; + + // Marie creates a new group chat room + const char *initialSubject = "Colleagues"; + LinphoneChatRoom *marieCr1 = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, -1); + const LinphoneAddress *confAddr1 = linphone_chat_room_get_conference_address(marieCr1); + // Check that the chat room is correctly created on Pauline1 and Pauline2's sides and that the participants are added + LinphoneChatRoom *paulineCr1 = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr1, initialSubject, 2, FALSE); + LinphoneChatRoom *laureCr1 = check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr1, initialSubject, 2, FALSE); + initialMarieStats = marie->stat; + initialPaulineStats = pauline->stat; + initialLaureStats = laure->stat; + + // Marie creates a new group chat room + initialSubject = "Friends"; + participantsAddresses = NULL; + participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc))); + participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc))); + LinphoneChatRoom *marieCr2 = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, -1); + const LinphoneAddress *confAddr2 = linphone_chat_room_get_conference_address(marieCr2); + // Check that the chat room is correctly created on Pauline1 and Pauline2's sides and that the participants are added + LinphoneChatRoom *paulineCr2 = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr2, initialSubject, 2, FALSE); + LinphoneChatRoom *laureCr2 = check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr2, initialSubject, 2, FALSE); + initialMarieStats = marie->stat; + initialPaulineStats = pauline->stat; + initialLaureStats = laure->stat; + + // Marie creates a new group chat room + initialSubject = "Bros"; + participantsAddresses = NULL; + participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc))); + participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc))); + LinphoneChatRoom *marieCr3 = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, -1); + const LinphoneAddress *confAddr3 = linphone_chat_room_get_conference_address(marieCr3); + // Check that the chat room is correctly created on Pauline1 and Pauline2's sides and that the participants are added + LinphoneChatRoom *paulineCr3 = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr3, initialSubject, 2, FALSE); + LinphoneChatRoom *laureCr3 = check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr3, initialSubject, 2, FALSE); + + participantsAddresses = NULL; + + // Marie designates Pauline as admin in chat room 1 + LinphoneAddress *paulineAddr = linphone_address_new(linphone_core_get_identity(pauline->lc)); + LinphoneParticipant *paulineParticipant = linphone_chat_room_find_participant(marieCr1, paulineAddr); + linphone_address_unref(paulineAddr); + BC_ASSERT_PTR_NOT_NULL(paulineParticipant); + linphone_chat_room_set_participant_admin_status(marieCr1, paulineParticipant, TRUE); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participant_admin_statuses_changed, initialMarieStats.number_of_participant_admin_statuses_changed + 1, 1000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participant_admin_statuses_changed, initialPaulineStats.number_of_participant_admin_statuses_changed + 1, 1000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participant_admin_statuses_changed, initialLaureStats.number_of_participant_admin_statuses_changed + 1, 1000)); + BC_ASSERT_TRUE(linphone_participant_is_admin(paulineParticipant)); + + // Pauline's device goes off + paulineAddr = linphone_address_clone(linphone_chat_room_get_local_address(paulineCr1)); + coresList = bctbx_list_remove(coresList, pauline->lc); + linphone_core_set_network_reachable(pauline->lc, FALSE); + wait_for_list(coresList, &dummy, 1, 1000); + + // Marie designates Laure as admin in chat rooms 1 & 3 + LinphoneAddress *laureAddr = linphone_address_new(linphone_core_get_identity(laure->lc)); + LinphoneParticipant *laureParticipant1 = linphone_chat_room_find_participant(marieCr1, laureAddr); + LinphoneParticipant *laureParticipant2 = linphone_chat_room_find_participant(marieCr2, laureAddr); + LinphoneParticipant *laureParticipant3 = linphone_chat_room_find_participant(marieCr3, laureAddr); + BC_ASSERT_PTR_NOT_NULL(laureParticipant1); + BC_ASSERT_PTR_NOT_NULL(laureParticipant2); + BC_ASSERT_PTR_NOT_NULL(laureParticipant3); + linphone_chat_room_set_participant_admin_status(marieCr1, laureParticipant1, TRUE); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participant_admin_statuses_changed, initialMarieStats.number_of_participant_admin_statuses_changed + 2, 1000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participant_admin_statuses_changed, initialLaureStats.number_of_participant_admin_statuses_changed + 2, 1000)); + BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_participant_admin_statuses_changed, initialPaulineStats.number_of_participant_admin_statuses_changed + 2, 1000)); + BC_ASSERT_TRUE(linphone_participant_is_admin(laureParticipant1)); + linphone_chat_room_set_participant_admin_status(marieCr3, laureParticipant3, TRUE); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participant_admin_statuses_changed, initialMarieStats.number_of_participant_admin_statuses_changed + 3, 1000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participant_admin_statuses_changed, initialLaureStats.number_of_participant_admin_statuses_changed + 3, 1000)); + BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_participant_admin_statuses_changed, initialPaulineStats.number_of_participant_admin_statuses_changed + 3, 1000)); + BC_ASSERT_TRUE(linphone_participant_is_admin(laureParticipant3)); + + // Marie now changes the subject or chat room 1 + const char *newSubject = "New subject"; + linphone_chat_room_set_subject(marieCr1, newSubject); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed, initialMarieStats.number_of_subject_changed + 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed, initialLaureStats.number_of_subject_changed + 1, 10000)); + BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed, initialPaulineStats.number_of_subject_changed + 1, 10000)); + BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(marieCr1), newSubject); + BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(laureCr1), newSubject); + + // Pauline is back + linphone_core_manager_reinit(pauline); + bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, pauline); + bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList); + bctbx_list_free(tmpCoresManagerList); + coresList = bctbx_list_concat(coresList, tmpCoresList); + linphone_core_manager_start(pauline, TRUE); + paulineCr1 = linphone_core_find_chat_room(pauline->lc, confAddr1, paulineAddr); + paulineCr2 = linphone_core_find_chat_room(pauline->lc, confAddr2, paulineAddr); + paulineCr3 = linphone_core_find_chat_room(pauline->lc, confAddr3, paulineAddr); + BC_ASSERT_PTR_NOT_NULL(paulineCr1); + BC_ASSERT_PTR_NOT_NULL(paulineCr2); + BC_ASSERT_PTR_NOT_NULL(paulineCr3); + linphone_address_unref(paulineAddr); + LinphoneParticipant *laureParticipantOfPauline1 = linphone_chat_room_find_participant(paulineCr1, laureAddr); + LinphoneParticipant *laureParticipantOfPauline2 = linphone_chat_room_find_participant(paulineCr2, laureAddr); + LinphoneParticipant *laureParticipantOfPauline3 = linphone_chat_room_find_participant(paulineCr3, laureAddr); + BC_ASSERT_PTR_NOT_NULL(laureParticipantOfPauline1); + BC_ASSERT_PTR_NOT_NULL(laureParticipantOfPauline2); + BC_ASSERT_PTR_NOT_NULL(laureParticipantOfPauline3); + linphone_address_unref(laureAddr); + wait_for_list(coresList, &dummy, 1, 5000); + + // Check that Pauline receive the missing info and not more + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participant_admin_statuses_changed, initialPaulineStats.number_of_participant_admin_statuses_changed + 2, 1000)); + BC_ASSERT_TRUE(linphone_participant_is_admin(laureParticipantOfPauline1)); + BC_ASSERT_TRUE(linphone_participant_is_admin(laureParticipantOfPauline3)); + BC_ASSERT_FALSE(linphone_participant_is_admin(laureParticipantOfPauline2)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed, initialPaulineStats.number_of_subject_changed + 1, 10000)); + BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(paulineCr1), newSubject); + + // Check that Pauline can still receive info once back + // Marie now changes the subject or chat room 1 + newSubject = "New New subject"; + linphone_chat_room_set_subject(marieCr1, newSubject); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed, initialMarieStats.number_of_subject_changed + 2, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed, initialLaureStats.number_of_subject_changed + 2, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed, initialPaulineStats.number_of_subject_changed + 2, 10000)); + BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(marieCr1), newSubject); + BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(laureCr1), newSubject); + BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(paulineCr1), newSubject); + // Marie now changes the subject or chat room 2 + newSubject = "Newer subject"; + linphone_chat_room_set_subject(marieCr2, newSubject); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed, initialMarieStats.number_of_subject_changed + 3, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed, initialLaureStats.number_of_subject_changed + 3, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed, initialPaulineStats.number_of_subject_changed + 3, 10000)); + BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(marieCr2), newSubject); + BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(laureCr2), newSubject); + BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(paulineCr2), newSubject); + // Marie now changes the subject or chat room 3 + newSubject = "Newest subject"; + linphone_chat_room_set_subject(marieCr3, newSubject); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed, initialMarieStats.number_of_subject_changed + 4, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed, initialLaureStats.number_of_subject_changed + 4, 10000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed, initialPaulineStats.number_of_subject_changed + 4, 10000)); + BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(marieCr3), newSubject); + BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(laureCr3), newSubject); + BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(paulineCr3), newSubject); + + // Clean db from chat room + linphone_core_manager_delete_chat_room(marie, marieCr1, coresList); + linphone_core_manager_delete_chat_room(pauline, paulineCr1, coresList); + linphone_core_manager_delete_chat_room(laure, laureCr1, coresList); + linphone_core_manager_delete_chat_room(marie, marieCr2, coresList); + linphone_core_manager_delete_chat_room(pauline, paulineCr2, coresList); + linphone_core_manager_delete_chat_room(laure, laureCr2, coresList); + linphone_core_manager_delete_chat_room(marie, marieCr3, coresList); + linphone_core_manager_delete_chat_room(pauline, paulineCr3, coresList); + linphone_core_manager_delete_chat_room(laure, laureCr3, coresList); + + bctbx_list_free(coresList); + bctbx_list_free(coresManagerList); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(laure); +} + +static void group_chat_room_complex_participant_removal_scenario (void) { + LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc"); + LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc"); + LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc"); + bctbx_list_t *coresManagerList = NULL; + bctbx_list_t *participantsAddresses = NULL; + coresManagerList = bctbx_list_append(coresManagerList, marie); + coresManagerList = bctbx_list_append(coresManagerList, pauline); + coresManagerList = bctbx_list_append(coresManagerList, laure); + bctbx_list_t *coresList = init_core_for_conference(coresManagerList); + start_core_for_conference(coresManagerList); + participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc))); + participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc))); + stats initialMarieStats = marie->stat; + stats initialPaulineStats = pauline->stat; + stats initialLaureStats = laure->stat; + + // Marie creates a new group chat room + const char *initialSubject = "Colleagues"; + LinphoneChatRoom *marieCr = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, -1); + participantsAddresses = NULL; + const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr); + + // Check that the chat room is correctly created on Pauline's side and that the participants are added + LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr, initialSubject, 2, FALSE); + + // Check that the chat room is correctly created on Laure's side and that the participants are added + check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE); + + // Restart Laure core + linphone_core_set_network_reachable(laure->lc, FALSE); + char *laureIdentity = linphone_core_get_device_identity(laure->lc); + LinphoneAddress *laureAddr = linphone_address_new(laureIdentity); + bctbx_free(laureIdentity); + coresList = bctbx_list_remove(coresList, laure->lc); + linphone_core_manager_reinit(laure); + bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, laure); + bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList); + bctbx_list_free(tmpCoresManagerList); + coresList = bctbx_list_concat(coresList, tmpCoresList); + linphone_core_manager_start(laure, TRUE); + initialLaureStats = laure->stat; + + // Marie removes Laure from the chat room + LinphoneParticipant *laureParticipant = linphone_chat_room_find_participant(marieCr, laureAddr); + BC_ASSERT_PTR_NOT_NULL(laureParticipant); + linphone_chat_room_remove_participant(marieCr, laureParticipant); + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participants_removed, initialMarieStats.number_of_participants_removed + 1, 1000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participants_removed, initialPaulineStats.number_of_participants_removed + 1, 1000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomStateTerminated, initialLaureStats.number_of_LinphoneChatRoomStateTerminated + 1, 3000)); + + wait_for_list(coresList,0, 1, 2000); + initialLaureStats = laure->stat; + + linphone_proxy_config_refresh_register(linphone_core_get_default_proxy_config(laure->lc)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneRegistrationOk, initialLaureStats.number_of_LinphoneRegistrationOk + 1, 1000)); + BC_ASSERT_FALSE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomStateTerminated, initialLaureStats.number_of_LinphoneChatRoomStateTerminated + 1, 3000)); + + // Marie adds Laure to the chat room + participantsAddresses = bctbx_list_append(participantsAddresses, laureAddr); + linphone_chat_room_add_participants(marieCr, participantsAddresses); + bctbx_list_free_with_data(participantsAddresses, (bctbx_list_free_func)linphone_address_unref); + participantsAddresses = NULL; + BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participants_added, initialMarieStats.number_of_participants_added + 1, 1000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participants_added, initialPaulineStats.number_of_participants_added + 1, 1000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomStateCreationPending, initialLaureStats.number_of_LinphoneChatRoomStateCreationPending + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomStateCreated, initialLaureStats.number_of_LinphoneChatRoomStateCreated + 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomConferenceJoined, initialLaureStats.number_of_LinphoneChatRoomConferenceJoined + 1, 3000)); + BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marieCr), 2, int, "%d"); + BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(paulineCr), 2, int, "%d"); + laureIdentity = linphone_core_get_device_identity(laure->lc); + laureAddr = linphone_address_new(laureIdentity); + bctbx_free(laureIdentity); + LinphoneChatRoom *newLaureCr = linphone_core_find_chat_room(laure->lc, confAddr, laureAddr); + linphone_address_unref(laureAddr); + BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(newLaureCr), 2, int, "%d"); + BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(newLaureCr), initialSubject); + BC_ASSERT_FALSE(linphone_chat_room_has_been_left(newLaureCr)); + + unsigned int nbLaureConferenceCreatedEventsBeforeRestart = 0; + bctbx_list_t *laureHistory = linphone_chat_room_get_history_events(newLaureCr, 0); + for (bctbx_list_t *item = laureHistory; item; item = bctbx_list_next(item)) { + LinphoneEventLog *event = (LinphoneEventLog *)bctbx_list_get_data(item); + if (linphone_event_log_get_type(event) == LinphoneEventLogTypeConferenceCreated) + nbLaureConferenceCreatedEventsBeforeRestart++; + } + bctbx_list_free_with_data(laureHistory, (bctbx_list_free_func)linphone_event_log_unref); + BC_ASSERT_EQUAL(nbLaureConferenceCreatedEventsBeforeRestart, 2, unsigned int, "%u"); + + initialLaureStats = laure->stat; + linphone_proxy_config_refresh_register(linphone_core_get_default_proxy_config(laure->lc)); + BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneRegistrationOk, initialLaureStats.number_of_LinphoneRegistrationOk + 1, 1000)); + BC_ASSERT_FALSE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomConferenceJoined, initialLaureStats.number_of_LinphoneChatRoomConferenceJoined + 1, 3000)); + BC_ASSERT_FALSE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomStateTerminated, initialLaureStats.number_of_LinphoneChatRoomStateTerminated + 1, 3000)); + + unsigned int nbLaureConferenceCreatedEventsAfterRestart = 0; + laureHistory = linphone_chat_room_get_history_events(newLaureCr, 0); + for (bctbx_list_t *item = laureHistory; item; item = bctbx_list_next(item)) { + LinphoneEventLog *event = (LinphoneEventLog *)bctbx_list_get_data(item); + if (linphone_event_log_get_type(event) == LinphoneEventLogTypeConferenceCreated) + nbLaureConferenceCreatedEventsAfterRestart++; + } + bctbx_list_free_with_data(laureHistory, (bctbx_list_free_func)linphone_event_log_unref); + BC_ASSERT_EQUAL(nbLaureConferenceCreatedEventsAfterRestart, nbLaureConferenceCreatedEventsBeforeRestart, unsigned int, "%u"); + + // Clean db from chat room + linphone_core_manager_delete_chat_room(marie, marieCr, coresList); + linphone_core_manager_delete_chat_room(laure, newLaureCr, coresList); + linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList); + + bctbx_list_free(coresList); + bctbx_list_free(coresManagerList); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(laure); +} + test_t group_chat_tests[] = { TEST_NO_TAG("Group chat room creation server", group_chat_room_creation_server), TEST_ONE_TAG("Add participant", group_chat_room_add_participant, "LeaksMemory"), @@ -3250,16 +3841,16 @@ test_t group_chat_tests[] = { TEST_NO_TAG("Send message with a participant removed", group_chat_room_send_message_with_participant_removed), TEST_NO_TAG("Leave group chat room", group_chat_room_leave), TEST_NO_TAG("Come back on a group chat room after a disconnection", group_chat_room_come_back_after_disconnection), - TEST_NO_TAG("Create chat room with disconnected friends", group_chat_room_create_room_with_disconnected_friends), + TEST_ONE_TAG("Create chat room with disconnected friends", group_chat_room_create_room_with_disconnected_friends, "LeaksMemory"), TEST_ONE_TAG("Create chat room with disconnected friends and initial message", group_chat_room_create_room_with_disconnected_friends_and_initial_message, "LeaksMemory"), TEST_NO_TAG("Reinvited after removed from group chat room", group_chat_room_reinvited_after_removed), + TEST_ONE_TAG("Reinvited after removed from group chat room 2", group_chat_room_reinvited_after_removed_2, "LeaksMemory"), TEST_ONE_TAG("Reinvited after removed from group chat room while offline", group_chat_room_reinvited_after_removed_while_offline, "LeaksMemory"), TEST_ONE_TAG("Reinvited after removed from group chat room while offline 2", group_chat_room_reinvited_after_removed_while_offline_2, "LeaksMemory"), - TEST_ONE_TAG("Reinvited after removed from group chat room with several devices", group_chat_room_reinvited_after_removed_with_several_devices, "LeaksMemory"), + TEST_NO_TAG("Reinvited after removed from group chat room with several devices", group_chat_room_reinvited_after_removed_with_several_devices), TEST_NO_TAG("Notify after disconnection", group_chat_room_notify_after_disconnection), TEST_NO_TAG("Send refer to all participants devices", group_chat_room_send_refer_to_all_devices), - // TODO: Use when we support adding a new device in created conf - //TEST_ONE_TAGS("Admin add device and doesn't lose admin status", group_chat_room_add_device, "LeaksMemory"), + TEST_NO_TAG("Admin add device and doesn't lose admin status", group_chat_room_add_device), TEST_NO_TAG("Send multiple is composing", multiple_is_composing_notification), TEST_ONE_TAG("Fallback to basic chat room", group_chat_room_fallback_to_basic_chat_room, "LeaksMemory"), TEST_NO_TAG("Group chat room creation fails if invited participants don't support it", group_chat_room_creation_fails_if_invited_participants_dont_support_it), @@ -3274,10 +3865,15 @@ test_t group_chat_tests[] = { TEST_ONE_TAG("Unique one-to-one chatroom recreated from message with app restart", group_chat_room_unique_one_to_one_chat_room_recreated_from_message_with_app_restart, "LeaksMemory"), TEST_NO_TAG("Join one-to-one chat room with a new device", group_chat_room_join_one_to_one_chat_room_with_a_new_device), TEST_NO_TAG("New unique one-to-one chatroom after both participants left", group_chat_room_new_unique_one_to_one_chat_room_after_both_participants_left), - TEST_NO_TAG("Unique one-to-one chatroom re-created from the party that deleted it, with inactive devices", group_chat_room_unique_one_to_one_chat_room_recreated_from_message_2), + TEST_ONE_TAG("Unique one-to-one chatroom re-created from the party that deleted it, with inactive devices", group_chat_room_unique_one_to_one_chat_room_recreated_from_message_2, "LeaksMemory"), TEST_NO_TAG("IMDN for group chat room", imdn_for_group_chat_room), + TEST_NO_TAG("Aggregated IMDN for group chat room", aggregated_imdn_for_group_chat_room), + TEST_NO_TAG("Aggregated IMDN for group chat room read while offline", aggregated_imdn_for_group_chat_room_read_while_offline), + TEST_ONE_TAG("IMDN sent from DB state", imdn_sent_from_db_state, "LeaksMemory"), TEST_NO_TAG("Find one to one chat room", find_one_to_one_chat_room), - TEST_NO_TAG("New device after group chat room creation", group_chat_room_new_device_after_creation) + TEST_NO_TAG("New device after group chat room creation", group_chat_room_new_device_after_creation), + TEST_ONE_TAG("Chat room list subscription", group_chat_room_list_subscription, "LeaksMemory"), + TEST_ONE_TAG("Complex participant removal scenario", group_chat_room_complex_participant_removal_scenario, "LeaksMemory") }; test_suite_t group_chat_test_suite = { diff --git a/tester/liblinphone_tester.c b/tester/liblinphone_tester.c index d4f030bb8..1a67a2be9 100644 --- a/tester/liblinphone_tester.c +++ b/tester/liblinphone_tester.c @@ -160,7 +160,7 @@ static void log_handler(int lev, const char *fmt, va_list args) { #endif va_end(cap); #endif - bctbx_logv(ORTP_LOG_DOMAIN, lev, fmt, args); + bctbx_logv(BCTBX_LOG_DOMAIN, lev, fmt, args); } void liblinphone_tester_init(void(*ftester_printf)(int level, const char *fmt, va_list args)) { diff --git a/tester/liblinphone_tester.h b/tester/liblinphone_tester.h index 6c83d1c8a..76123ca2c 100644 --- a/tester/liblinphone_tester.h +++ b/tester/liblinphone_tester.h @@ -41,11 +41,15 @@ extern "C" { extern test_suite_t account_creator_test_suite; extern test_suite_t call_test_suite; -extern test_suite_t call_video_test_suite; + +#if VIDEO_ENABLED + extern test_suite_t call_video_test_suite; +#endif + extern test_suite_t clonable_object_test_suite; extern test_suite_t conference_event_test_suite; extern test_suite_t conference_test_suite; -extern test_suite_t content_manager_test_suite; +extern test_suite_t contents_test_suite; extern test_suite_t cpim_test_suite; extern test_suite_t dtmf_test_suite; extern test_suite_t event_test_suite; @@ -73,12 +77,12 @@ extern test_suite_t upnp_test_suite; extern test_suite_t video_test_suite; #ifdef VCARD_ENABLED -extern test_suite_t vcard_test_suite; + extern test_suite_t vcard_test_suite; #endif extern test_suite_t audio_bypass_suite; #if HAVE_SIPP -extern test_suite_t complex_sip_call_test_suite; + extern test_suite_t complex_sip_call_test_suite; #endif extern int manager_count; @@ -183,6 +187,7 @@ typedef struct _stats { int number_of_LinphoneIsComposingIdleReceived; int progress_of_LinphoneFileTransfer; + int number_of_LinphoneChatRoomConferenceJoined; int number_of_LinphoneChatRoomStateInstantiated; int number_of_LinphoneChatRoomStateCreationPending; int number_of_LinphoneChatRoomStateCreated; @@ -291,6 +296,8 @@ typedef struct _stats { int number_of_participants_removed; int number_of_subject_changed; int number_of_participant_devices_added; + + int number_of_snapshot_taken; }stats; @@ -328,6 +335,7 @@ void linphone_core_manager_configure (LinphoneCoreManager *mgr); void linphone_core_manager_start(LinphoneCoreManager *mgr, bool_t check_for_proxies); LinphoneCoreManager* linphone_core_manager_create2(const char* rc_file, const char* phone_alias); LinphoneCoreManager* linphone_core_manager_create(const char* rc_file); +LinphoneCoreManager* linphone_core_manager_new4(const char* rc_file, int check_for_proxies, const char* phone_aliasconst, const char* contact_params, int expires); LinphoneCoreManager* linphone_core_manager_new3(const char* rc_file, bool_t check_for_proxies, const char* phone_alias); LinphoneCoreManager* linphone_core_manager_new2(const char* rc_file, bool_t check_for_proxies); LinphoneCoreManager* linphone_core_manager_new(const char* rc_file); @@ -403,7 +411,7 @@ void account_manager_destroy(void); LinphoneAddress *account_manager_get_identity_with_modified_identity(const LinphoneAddress *modified_identity); LinphoneCore *configure_lc_from(LinphoneCoreCbs *cbs, const char *path, const char *file, void *user_data); -void linphone_call_iframe_decoded_cb(LinphoneCall *call,void * user_data); +void linphone_call_set_first_video_frame_decoded_cb(LinphoneCall *call); void call_paused_resumed_base(bool_t multicast,bool_t with_losses); void simple_call_base(bool_t enable_multicast_recv_side); void call_base_with_configfile(LinphoneMediaEncryption mode, bool_t enable_video,bool_t enable_relay,LinphoneFirewallPolicy policy,bool_t enable_tunnel, const char *marie_rc, const char *pauline_rc); diff --git a/tester/local_tester_hosts b/tester/local_tester_hosts index 453c74f53..94fbdce4d 100644 --- a/tester/local_tester_hosts +++ b/tester/local_tester_hosts @@ -1,4 +1,4 @@ 127.0.0.1 sip2.linphone.org sip.example.org sipopen.example.org auth.example.org auth1.example.org auth2.example.org altname.linphone.org sip.wildcard1.linphone.org altname.wildcard2.linphone.org sipv4.example.org conf.example.org ::1 sip2.linphone.org sip.example.org sipopen.example.org auth.example.org auth1.example.org auth2.example.org altname.linphone.org sip.wildcard1.linphone.org altname.wildcard2.linphone.org 188.165.46.90 tunnel.wildcard2.linphone.org -64:ff9b::94.23.19.176 sipv4-nat64.example.org +64:ff9b::94.23.19.176 sipv4-nat64.example.org diff --git a/tester/message_tester.c b/tester/message_tester.c index 396f4b9c4..096873f43 100644 --- a/tester/message_tester.c +++ b/tester/message_tester.c @@ -31,9 +31,6 @@ #include #endif -#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4) -#pragma GCC diagnostic push -#endif #ifdef _MSC_VER #pragma warning(disable : 4996) #endif @@ -41,12 +38,14 @@ static char* message_external_body_url=NULL; +#ifdef SQLITE_STORAGE_ENABLED /* sql cache creation string, contains 3 string to be inserted : selfuri/selfuri/peeruri */ static const char *marie_zid_sqlcache = "BEGIN TRANSACTION; CREATE TABLE IF NOT EXISTS ziduri (zuid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,zid BLOB NOT NULL DEFAULT '000000000000',selfuri TEXT NOT NULL DEFAULT 'unset',peeruri TEXT NOT NULL DEFAULT 'unset'); INSERT INTO `ziduri` (zuid,zid,selfuri,peeruri) VALUES (1,X'4ddc8042bee500ad0366bf93','%s','self'), (2,X'bcb4028bf55e1b7ac4c4edee','%s','%s'); CREATE TABLE IF NOT EXISTS zrtp (zuid INTEGER NOT NULL DEFAULT 0 UNIQUE,rs1 BLOB DEFAULT NULL,rs2 BLOB DEFAULT NULL,aux BLOB DEFAULT NULL,pbx BLOB DEFAULT NULL,pvs BLOB DEFAULT NULL,FOREIGN KEY(zuid) REFERENCES ziduri(zuid) ON UPDATE CASCADE ON DELETE CASCADE); INSERT INTO `zrtp` (zuid,rs1,rs2,aux,pbx,pvs) VALUES (2,X'f0e0ad4d3d4217ba4048d1553e5ab26fae0b386cdac603f29a66d5f4258e14ef',NULL,NULL,NULL,X'01'); CREATE TABLE IF NOT EXISTS lime (zuid INTEGER NOT NULL DEFAULT 0 UNIQUE,sndKey BLOB DEFAULT NULL,rcvKey BLOB DEFAULT NULL,sndSId BLOB DEFAULT NULL,rcvSId BLOB DEFAULT NULL,sndIndex BLOB DEFAULT NULL,rcvIndex BLOB DEFAULT NULL,valid BLOB DEFAULT NULL,FOREIGN KEY(zuid) REFERENCES ziduri(zuid) ON UPDATE CASCADE ON DELETE CASCADE); INSERT INTO `lime` (zuid,sndKey,rcvKey,sndSId,rcvSId,sndIndex,rcvIndex,valid) VALUES (2,X'97c75a5a92a041b415296beec268efc3373ef4aa8b3d5f301ac7522a7fb4e332',x'3b74b709b961e5ebccb1db6b850ea8c1f490546d6adee2f66b5def7093cead3d',X'e2ebca22ad33071bc37631393bf25fc0a9badeea7bf6dcbcb5d480be7ff8c5ea',X'a2086d195344ec2997bf3de7441d261041cda5d90ed0a0411ab2032e5860ea48',X'33376935',X'7ce32d86',X'0000000000000000'); COMMIT;"; static const char *pauline_zid_sqlcache = "BEGIN TRANSACTION; CREATE TABLE IF NOT EXISTS ziduri (zuid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,zid BLOB NOT NULL DEFAULT '000000000000',selfuri TEXT NOT NULL DEFAULT 'unset',peeruri TEXT NOT NULL DEFAULT 'unset'); INSERT INTO `ziduri` (zuid,zid,selfuri,peeruri) VALUES (1,X'bcb4028bf55e1b7ac4c4edee','%s','self'), (2,X'4ddc8042bee500ad0366bf93','%s','%s'); CREATE TABLE IF NOT EXISTS zrtp (zuid INTEGER NOT NULL DEFAULT 0 UNIQUE,rs1 BLOB DEFAULT NULL,rs2 BLOB DEFAULT NULL,aux BLOB DEFAULT NULL,pbx BLOB DEFAULT NULL,pvs BLOB DEFAULT NULL,FOREIGN KEY(zuid) REFERENCES ziduri(zuid) ON UPDATE CASCADE ON DELETE CASCADE); INSERT INTO `zrtp` (zuid,rs1,rs2,aux,pbx,pvs) VALUES (2,X'f0e0ad4d3d4217ba4048d1553e5ab26fae0b386cdac603f29a66d5f4258e14ef',NULL,NULL,NULL,X'01'); CREATE TABLE IF NOT EXISTS lime (zuid INTEGER NOT NULL DEFAULT 0 UNIQUE,sndKey BLOB DEFAULT NULL,rcvKey BLOB DEFAULT NULL,sndSId BLOB DEFAULT NULL,rcvSId BLOB DEFAULT NULL,sndIndex BLOB DEFAULT NULL,rcvIndex BLOB DEFAULT NULL,valid BLOB DEFAULT NULL,FOREIGN KEY(zuid) REFERENCES ziduri(zuid) ON UPDATE CASCADE ON DELETE CASCADE); INSERT INTO `lime` (zuid,rcvKey,sndKey,rcvSId,sndSId,rcvIndex,sndIndex,valid) VALUES (2,X'97c75a5a92a041b415296beec268efc3373ef4aa8b3d5f301ac7522a7fb4e332',x'3b74b709b961e5ebccb1db6b850ea8c1f490546d6adee2f66b5def7093cead3d',X'e2ebca22ad33071bc37631393bf25fc0a9badeea7bf6dcbcb5d480be7ff8c5ea',X'a2086d195344ec2997bf3de7441d261041cda5d90ed0a0411ab2032e5860ea48',X'33376935',X'7ce32d86',X'0000000000000000'); COMMIT;"; static const char *xmlCacheMigration = "\n00112233445566778899aabb99887766554433221100ffeec4274f13a2b6fa05c15ec93158f930e7264b0a893393376dbc80c6eb1cccdc5asip:bob@sip.linphone.org219d9e445d10d4ed64083c7ccbb83a23bc17a97df0af5de4261f3fe026b05b0b747e72a5cc996413cb9fa6e3d18d8b370436e274cd6ba4efc1a4580340af57cadf2bf38e719fa89e17332cf8d5e774ee70d347baa74d16dee01f306c54789869928ce78b0bfc30427a02b1b668b2b3b0496d5664d7e89b75ed292ee97e3fc850496bcc8959337abe5dda11f388384b349d210612f30824268a3753a7afa52ef6df5866dca76315c4sip:bob2@sip.linphone.orgffeeddccbbaa987654321012858b495dfad483af3c088f26d68c4beebc638bd44feae45aea726a771727235esip:bob@sip.linphone.orgb6aac945057bc4466bfe9a23771c6a1b3b8d72ec3e7d8f30ed63cbc5a9479a25bea5ac3225edd0545b816f061a8190370e3ee5160e75404846a34d1580e0c26317ce70fdf12e500294bcb5f2ffef53096761bb1c912b21e972ae03a5a9f05c477e13a20e15a517700f0be0921f74b96d4b4a0c539d5e14d5cdd8706441874ac075e18caa2cfbbf061533dee20c8116dc2c282cae9adfea689b87bc4c6a4e18a846f12e3e7fea39590987654321fedcba5a5a5a5acb6ecc87d1dd87b23f225eec53a26fc541384917623e0c46abab8c0350c6929e92bb03988e8f0ccfefa37a55fd7c5893bea3bfbb27312f49dd9b10d0e3c15fc72315705a5830b98f68458fcd49623144cb34a667512c4d44686aee125bb8b62294c56eea0dd829379263b6da3f6ac0a95388090f168a3568736ca0bd9f8d595fc319ae0d41183fec90afc412d42253c5b456580f7a463c111c7293623b8631f4sip:bob@sip.linphone.org2c46ddcc15f5779e0000000058f095bf01"; +#endif // SQLITE_STORAGE_ENABLED void message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage* msg) { char* from=linphone_address_as_string(linphone_chat_message_get_from_address(msg)); @@ -64,10 +63,9 @@ void message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMess } counters->last_received_chat_message=linphone_chat_message_ref(msg); LinphoneContent * content = linphone_chat_message_get_file_transfer_information(msg); - if (content) { + if (content) counters->number_of_LinphoneMessageReceivedWithFile++; - linphone_content_unref(content); - } else if (linphone_chat_message_get_external_body_url(msg)) { + else if (linphone_chat_message_get_external_body_url(msg)) { counters->number_of_LinphoneMessageExtBodyReceived++; if (message_external_body_url) { BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_external_body_url(msg),message_external_body_url); @@ -287,7 +285,7 @@ void text_message_base(LinphoneCoreManager* marie, LinphoneCoreManager* pauline) LinphoneChatMessage* msg = linphone_chat_room_create_message(room,"Bli bli bli \n blu"); LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg); linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed); - linphone_chat_room_send_chat_message(room, msg); + linphone_chat_message_send(msg); BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageDelivered,1)); BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1)); @@ -352,7 +350,7 @@ static void text_message_with_credential_from_auth_callback(void) { linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); - linphone_auth_info_destroy(text_message_with_credential_from_auth_cb_auth_info); + linphone_auth_info_unref(text_message_with_credential_from_auth_cb_auth_info); text_message_with_credential_from_auth_cb_auth_info = NULL; } @@ -413,7 +411,7 @@ static void text_message_with_send_error(void) { /*simulate a network error*/ sal_set_send_error(linphone_core_get_sal(marie->lc), -1); linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed); - linphone_chat_room_send_chat_message(chat_room,msg); + linphone_chat_message_send(msg); /* check transient msg list: the msg should be in it, and should be the only one */ BC_ASSERT_EQUAL(_linphone_chat_room_get_transient_message_count(chat_room), 1, int, "%d"); @@ -462,7 +460,7 @@ void transfer_message_base2(LinphoneCoreManager* marie, LinphoneCoreManager* pau msg = create_message_from_sintel_trailer(chat_room); } - linphone_chat_room_send_chat_message(chat_room,msg); + linphone_chat_message_send(msg); if (upload_error) { int chat_room_size = 0; @@ -612,7 +610,7 @@ static void transfer_message_upload_cancelled(void) { chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity); msg = create_message_from_sintel_trailer(chat_room); - linphone_chat_room_send_chat_message(chat_room,msg); + linphone_chat_message_send(msg); /*wait for file to be 25% uploaded and cancel the transfer */ BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.progress_of_LinphoneFileTransfer, 25, 60000)); @@ -641,7 +639,7 @@ static void transfer_message_download_cancelled(void) { /* create a chatroom on pauline's side */ chat_room = linphone_core_get_chat_room(pauline->lc,marie->identity); msg = create_message_from_sintel_trailer(chat_room); - linphone_chat_room_send_chat_message(chat_room,msg); + linphone_chat_message_send(msg); /* wait for marie to receive pauline's msg */ BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,1, 60000)); @@ -693,8 +691,8 @@ static void file_transfer_2_messages_simultaneously(void) { BC_ASSERT_EQUAL((unsigned int)bctbx_list_size(linphone_core_get_chat_rooms(marie->lc)), 0, unsigned int, "%u"); if (bctbx_list_size(linphone_core_get_chat_rooms(marie->lc)) == 0) { - linphone_chat_room_send_chat_message(pauline_room,msg); - linphone_chat_room_send_chat_message(pauline_room,msg2); + linphone_chat_message_send(msg); + linphone_chat_message_send(msg2); if (BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,1, 60000))) { LinphoneChatMessage *recvMsg = linphone_chat_message_ref(marie->stat.last_received_chat_message); BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,2, 60000)); @@ -752,7 +750,7 @@ static void file_transfer_external_body_url(bool_t use_file_body_handler_in_down linphone_chat_message_set_external_body_url(msg, "https://www.linphone.org/img/linphone-open-source-voip-projectX2.png"); linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed); - linphone_chat_room_send_chat_message(chat_room, msg); + linphone_chat_message_send(msg); linphone_chat_message_unref(msg); BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneMessageReceivedWithFile, 1, 60000)); @@ -798,7 +796,7 @@ static void text_message_denied(void) { /*pauline doesn't want to be disturbed*/ linphone_core_disable_chat(pauline->lc,LinphoneReasonDoNotDisturb); linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed); - linphone_chat_room_send_chat_message(chat_room,msg); + linphone_chat_message_send(msg); BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageNotDelivered,1)); BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageReceived,0, int, "%d"); @@ -832,12 +830,12 @@ void info_message_base(bool_t with_content) { info=linphone_core_create_info_message(marie->lc); linphone_info_message_add_header(info,"Weather","still bad"); if (with_content) { - LinphoneContent* ct=linphone_core_create_content(marie->lc); - linphone_content_set_type(ct,"application"); - linphone_content_set_subtype(ct,"somexml"); - linphone_content_set_buffer(ct,(const uint8_t *)info_content,strlen(info_content)); - linphone_info_message_set_content(info,ct); - linphone_content_unref(ct); + LinphoneContent* content = linphone_core_create_content(marie->lc); + linphone_content_set_type(content, "application"); + linphone_content_set_subtype(content, "somexml"); + linphone_content_set_buffer(content, (const uint8_t *)info_content, strlen(info_content)); + linphone_info_message_set_content(info, content); + linphone_content_unref(content); } linphone_call_send_info_message(linphone_core_get_current_call(marie->lc),info); linphone_info_message_unref(info); @@ -860,7 +858,7 @@ void info_message_base(bool_t with_content) { BC_ASSERT_PTR_NOT_NULL(linphone_content_get_subtype(content)); if (linphone_content_get_type(content)) BC_ASSERT_STRING_EQUAL(linphone_content_get_type(content),"application"); if (linphone_content_get_subtype(content)) BC_ASSERT_STRING_EQUAL(linphone_content_get_subtype(content),"somexml"); - if (linphone_content_get_buffer(content))BC_ASSERT_STRING_EQUAL((const char*)linphone_content_get_buffer(content),info_content); + if (linphone_content_get_buffer(content))BC_ASSERT_STRING_EQUAL(linphone_content_get_string_buffer(content),info_content); BC_ASSERT_EQUAL((int)linphone_content_get_size(content),(int)strlen(info_content), int, "%d"); } } @@ -1037,7 +1035,7 @@ static void _imdn_notifications(bool_t with_lime) { sent_cm = linphone_chat_room_create_message(pauline_chat_room, "Tell me if you get my message"); cbs = linphone_chat_message_get_callbacks(sent_cm); linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed); - linphone_chat_room_send_chat_message(pauline_chat_room, sent_cm); + linphone_chat_message_send(sent_cm); BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageReceived, 1)); marie_chat_room = linphone_core_get_chat_room(marie->lc, pauline->identity); history = linphone_chat_room_get_history(marie_chat_room, 1); @@ -1117,7 +1115,7 @@ static void _im_notification_policy(bool_t with_lime) { msg1 = linphone_chat_room_create_message(pauline_chat_room, "Happy new year!"); cbs = linphone_chat_message_get_callbacks(msg1); linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed); - linphone_chat_room_send_chat_message(pauline_chat_room, msg1); + linphone_chat_message_send(msg1); BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageReceived, 1)); wait_for_until(pauline->lc, marie->lc, &dummy, 1, 1500); /* Just to sleep while iterating */ BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageDeliveredToUser, 0, int, "%d"); @@ -1125,13 +1123,13 @@ static void _im_notification_policy(bool_t with_lime) { msg2 = linphone_chat_room_create_message(pauline_chat_room, "I said: Happy new year!"); cbs = linphone_chat_message_get_callbacks(msg2); linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed); - linphone_chat_room_send_chat_message(pauline_chat_room, msg2); + linphone_chat_message_send(msg2); BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageReceived, 2)); BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneMessageDeliveredToUser, 1)); msg3 = linphone_chat_room_create_message(marie_chat_room, "Thank you! Happy easter to you!"); cbs = linphone_chat_message_get_callbacks(msg3); linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed); - linphone_chat_room_send_chat_message(marie_chat_room, msg3); + linphone_chat_message_send(msg3); BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneMessageReceived, 1)); wait_for_until(pauline->lc, marie->lc, &dummy, 1, 1500); /* Just to sleep while iterating */ BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageDeliveredToUser, 0, int, "%d"); @@ -1139,7 +1137,7 @@ static void _im_notification_policy(bool_t with_lime) { msg4 = linphone_chat_room_create_message(marie_chat_room, "Yeah, yeah, I heard that..."); cbs = linphone_chat_message_get_callbacks(msg4); linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed); - linphone_chat_room_send_chat_message(marie_chat_room, msg4); + linphone_chat_message_send(msg4); BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneMessageReceived, 2)); BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageDeliveredToUser, 1)); @@ -1179,7 +1177,6 @@ static void imdn_notifications_with_lime(void) { static void im_notification_policy_with_lime(void) { _im_notification_policy(TRUE); } -#endif static void _im_error_delivery_notification(bool_t online) { LinphoneChatRoom *chat_room; @@ -1218,7 +1215,7 @@ static void _im_error_delivery_notification(bool_t online) { msg = linphone_chat_room_create_message(chat_room, "Happy new year!"); cbs = linphone_chat_message_get_callbacks(msg); linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed); - linphone_chat_room_send_chat_message(chat_room, msg); + linphone_chat_message_send(msg); if (!online) { linphone_core_set_network_reachable(marie->lc, FALSE); BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneMessageDelivered, 1, 60000)); @@ -1232,7 +1229,7 @@ static void _im_error_delivery_notification(bool_t online) { /* Restore the ZID cache of the receiver and resend the chat message */ linphone_core_set_zrtp_cache_db(marie->lc, zrtp_cache_db_holder); - linphone_chat_message_resend(msg); + linphone_chat_message_send(msg); BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageReceived, 2)); /* Check the new message is now received */ BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneMessageDeliveredToUser, 1)); linphone_chat_message_unref(msg); @@ -1252,7 +1249,6 @@ static void im_error_delivery_notification_offline(void) { _im_error_delivery_notification(FALSE); } -#ifdef SQLITE_STORAGE_ENABLED static void lime_text_message(void) { LinphoneChatRoom* chat_room; LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); @@ -1418,7 +1414,7 @@ void lime_transfer_message_base(bool_t encrypt_file,bool_t download_file_from_st msg = create_message_from_sintel_trailer(linphone_core_get_chat_room(pauline->lc, marie->identity)); } - linphone_chat_room_send_chat_message(linphone_chat_message_get_chat_room(msg), msg); + linphone_chat_message_send(msg); BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,1, 60000)); if (marie->stat.last_received_chat_message ) { LinphoneChatMessage *recv_msg; @@ -1442,7 +1438,6 @@ void lime_transfer_message_base(bool_t encrypt_file,bool_t download_file_from_st BC_ASSERT_PTR_NOT_NULL(linphone_content_get_key(content)); else BC_ASSERT_PTR_NULL(linphone_content_get_key(content)); - linphone_content_unref(content); if (use_file_body_handler_in_download) { linphone_chat_message_set_file_transfer_filepath(recv_msg, receive_filepath); @@ -1637,7 +1632,7 @@ void crash_during_file_transfer(void) { /* Create a chatroom and a file transfer message on pauline's side */ chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity); msg = create_file_transfer_message_from_sintel_trailer(chat_room); - linphone_chat_room_send_chat_message(chat_room, msg); + linphone_chat_message_send(msg); /* Wait for 25% of the file to be uploaded and crash by stopping the iteration, saving the chat database and destroying the core */ BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &pauline->stat.progress_of_LinphoneFileTransfer, 25, 60000)); @@ -1647,7 +1642,7 @@ void crash_during_file_transfer(void) { /* Create a new core and check that the message stored in the saved database is in the not delivered state */ linphone_core_manager_restart(pauline, TRUE); linphone_core_set_file_transfer_server(pauline->lc, "https://www.linphone.org:444/lft.php"); - + //BC_ASSERT_TRUE(wait_for(pauline->lc, pauline->lc, &pauline->stat.number_of_LinphoneRegistrationOk, 1)); chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity); @@ -1684,9 +1679,9 @@ void crash_during_file_transfer(void) { } } - + bctbx_list_free_with_data(msg_list, (bctbx_list_free_func)linphone_chat_message_unref); - + linphone_core_manager_destroy(pauline); linphone_core_manager_destroy(marie); @@ -1698,7 +1693,7 @@ static void text_status_after_destroying_chat_room(void) { LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); LinphoneChatRoom *chatroom = linphone_core_get_chat_room_from_uri(marie->lc, ""); LinphoneChatMessage *msg = linphone_chat_room_create_message(chatroom, "hello"); - linphone_chat_room_send_chat_message(chatroom, msg); + linphone_chat_message_send(msg); linphone_core_delete_chat_room(marie->lc, chatroom); //since message is orphan, we do not expect to be notified of state change BC_ASSERT_FALSE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneMessageNotDelivered, 1, 1000)); @@ -1714,7 +1709,7 @@ static void file_transfer_not_sent_if_invalid_url(void) { LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg); linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed); linphone_core_set_file_transfer_server(marie->lc, "INVALID URL"); - linphone_chat_room_send_chat_message(chatroom, msg); + linphone_chat_message_send(msg); BC_ASSERT_TRUE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneMessageNotDelivered, 1, 1000)); linphone_chat_message_unref(msg); linphone_core_manager_destroy(marie); @@ -1727,7 +1722,7 @@ void file_transfer_io_error_base(char *server_url, bool_t destroy_room) { LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg); linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed); linphone_core_set_file_transfer_server(marie->lc, server_url); - linphone_chat_room_send_chat_message(chatroom, msg); + linphone_chat_message_send(msg); BC_ASSERT_TRUE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneMessageInProgress, 1, 1000)); if (destroy_room) { linphone_core_delete_chat_room(marie->lc, chatroom); @@ -1773,7 +1768,7 @@ static void real_time_text(bool_t audio_stream_enabled, bool_t srtp_enabled, boo if (mess_with_marie_payload_number) { const bctbx_list_t *elem; - for (elem = linphone_core_get_text_codecs(marie->lc); elem != NULL; elem = elem->next) { + for (elem = linphone_core_get_text_payload_types(marie->lc); elem != NULL; elem = elem->next) { PayloadType *pt = (PayloadType*)elem->data; if (strcasecmp(pt->mime_type, payload_type_t140.mime_type) == 0) { payload_type_set_number(pt, 99); @@ -1782,7 +1777,7 @@ static void real_time_text(bool_t audio_stream_enabled, bool_t srtp_enabled, boo } } else if (mess_with_pauline_payload_number) { const bctbx_list_t *elem; - for (elem = linphone_core_get_text_codecs(pauline->lc); elem != NULL; elem = elem->next) { + for (elem = linphone_core_get_text_payload_types(pauline->lc); elem != NULL; elem = elem->next) { PayloadType *pt = (PayloadType*)elem->data; if (strcasecmp(pt->mime_type, payload_type_t140.mime_type) == 0) { payload_type_set_number(pt, 99); @@ -1838,7 +1833,7 @@ static void real_time_text(bool_t audio_stream_enabled, bool_t srtp_enabled, boo BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneIsComposingActiveReceived, (int)i+1, 1000)); BC_ASSERT_EQUAL(linphone_chat_room_get_char(marie_chat_room), message[i], char, "%c"); } - linphone_chat_room_send_chat_message(pauline_chat_room, rtt_message); + linphone_chat_message_send(rtt_message); BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageReceived, 1)); linphone_chat_message_unref(rtt_message); @@ -1939,8 +1934,8 @@ static void real_time_text_conversation(void) { } /*Commit the message, triggers a NEW LINE in T.140 */ - linphone_chat_room_send_chat_message(pauline_chat_room, pauline_rtt_message); - linphone_chat_room_send_chat_message(marie_chat_room, marie_rtt_message); + linphone_chat_message_send(pauline_rtt_message); + linphone_chat_message_send(marie_rtt_message); BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageReceived, 1)); { @@ -1977,8 +1972,8 @@ static void real_time_text_conversation(void) { } /*Commit the message, triggers a NEW LINE in T.140 */ - linphone_chat_room_send_chat_message(pauline_chat_room, pauline_rtt_message); - linphone_chat_room_send_chat_message(marie_chat_room, marie_rtt_message); + linphone_chat_message_send(pauline_rtt_message); + linphone_chat_message_send(marie_rtt_message); BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageReceived, 1)); { @@ -2112,7 +2107,7 @@ static void real_time_text_message_accented_chars(void) { BC_ASSERT_EQUAL(linphone_chat_room_get_char(marie_chat_room), message[i], unsigned long, "%lu"); } - linphone_chat_room_send_chat_message(pauline_chat_room, rtt_message); + linphone_chat_message_send(rtt_message); BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageReceived, 1)); BC_ASSERT_PTR_NOT_NULL(marie->stat.last_received_chat_message); if (marie->stat.last_received_chat_message) { @@ -2172,7 +2167,7 @@ static void real_time_text_copy_paste(void) { } } } - linphone_chat_room_send_chat_message(pauline_chat_room, rtt_message); + linphone_chat_message_send(rtt_message); BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageReceived, 1)); linphone_chat_message_unref(rtt_message); } @@ -2211,7 +2206,7 @@ void chat_message_custom_headers(void) { linphone_chat_message_remove_custom_header(msg, "Test1"); linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed); - linphone_chat_room_send_chat_message(chat_room,msg); + linphone_chat_message_send(msg); BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1)); BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageDelivered,1)); @@ -2261,7 +2256,7 @@ void _text_message_with_custom_content_type(bool_t with_lime) { cbs = linphone_chat_message_get_callbacks(msg); linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed); - linphone_chat_room_send_chat_message(chat_room, msg); + linphone_chat_message_send(msg); BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageReceived, 1)); BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneMessageDelivered, 1)); @@ -2294,15 +2289,19 @@ void text_message_with_custom_content_type_and_lime(void) { static int im_encryption_engine_process_incoming_message_cb(LinphoneImEncryptionEngine *engine, LinphoneChatRoom *room, LinphoneChatMessage *msg) { + ms_debug("IM encryption process incoming message with content type %s", linphone_chat_message_get_content_type(msg)); if (linphone_chat_message_get_content_type(msg)) { if (strcmp(linphone_chat_message_get_content_type(msg), "cipher/b64") == 0) { size_t b64Size = 0; unsigned char *output; - bctbx_base64_decode(NULL, &b64Size, (unsigned char *)linphone_chat_message_get_text(msg), strlen(linphone_chat_message_get_text(msg))); + const char *data = linphone_chat_message_get_text(msg); + ms_debug("IM encryption process incoming message crypted message is %s", data); + bctbx_base64_decode(NULL, &b64Size, (unsigned char *)data, strlen(data)); output = (unsigned char *)ms_malloc(b64Size+1), - bctbx_base64_decode(output, &b64Size, (unsigned char *)linphone_chat_message_get_text(msg), strlen(linphone_chat_message_get_text(msg))); + bctbx_base64_decode(output, &b64Size, (unsigned char *)data, strlen(data)); output[b64Size] = '\0'; linphone_chat_message_set_text(msg, (char *)output); + ms_debug("IM encryption process incoming message decrypted message is %s", output); ms_free(output); linphone_chat_message_set_content_type(msg, "text/plain"); return 0; @@ -2344,7 +2343,7 @@ static int im_encryption_engine_process_outgoing_message_cb(LinphoneImEncryption static bool_t im_encryption_engine_process_outgoing_message_async_impl(LinphoneChatMessage** msg) { if (*msg) { im_encryption_engine_process_outgoing_message_cb(NULL,NULL,*msg); - linphone_chat_room_send_chat_message(linphone_chat_message_get_chat_room(*msg), *msg); + linphone_chat_message_send(*msg); linphone_chat_message_unref(*msg); *msg=NULL; } @@ -2393,7 +2392,7 @@ void im_encryption_engine_b64_base(bool_t async) { chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity); chat_msg = linphone_chat_room_create_message(chat_room, "Bla bla bla bla"); - linphone_chat_room_send_chat_message(chat_room, chat_msg); + linphone_chat_message_send(chat_msg); BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1)); BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(chat_msg), "Bla bla bla bla"); BC_ASSERT_PTR_NOT_NULL(marie->stat.last_received_chat_message); @@ -2582,7 +2581,3 @@ test_suite_t message_test_suite = { liblinphone_tester_after_each, sizeof(message_tests) / sizeof(message_tests[0]), message_tests }; - -#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4) -#pragma GCC diagnostic pop -#endif diff --git a/tester/multipart-tester.cpp b/tester/multipart-tester.cpp index 3fdd9073a..663b114f4 100644 --- a/tester/multipart-tester.cpp +++ b/tester/multipart-tester.cpp @@ -53,13 +53,13 @@ static void chat_message_multipart_modifier_base(bool first_file_transfer, bool content->setContentType(ContentType("video/mkv")); content->setFilePath(send_filepath); content->setFileName("sintel_trailer_opus_h264.mkv"); - marieMessage->addContent(*content); + marieMessage->addContent(content); bc_free(send_filepath); } else { Content *content = new Content(); content->setContentType(ContentType::PlainText); - content->setBody("Hello Part 1"); - marieMessage->addContent(*content); + content->setBody("Hello part 1"); + marieMessage->addContent(content); } if (second_file_transfer) { @@ -68,13 +68,13 @@ static void chat_message_multipart_modifier_base(bool first_file_transfer, bool content->setContentType(ContentType("file/vcf")); content->setFilePath(send_filepath); content->setFileName("vcards.vcf"); - marieMessage->addContent(*content); + marieMessage->addContent(content); bc_free(send_filepath); } else { Content *content = new Content(); content->setContentType(ContentType::PlainText); - content->setBody("Hello Part 2"); - marieMessage->addContent(*content); + content->setBody("Hello part 2"); + marieMessage->addContent(content); } linphone_core_set_file_transfer_server(marie->lc,"https://www.linphone.org:444/lft.php"); @@ -82,7 +82,21 @@ static void chat_message_multipart_modifier_base(bool first_file_transfer, bool BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageReceived,1)); BC_ASSERT_PTR_NOT_NULL(pauline->stat.last_received_chat_message); - BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_content_type(pauline->stat.last_received_chat_message), "multipart/mixed"); + + if (first_file_transfer || second_file_transfer) { + LinphoneContent *content = linphone_chat_message_get_file_transfer_information(pauline->stat.last_received_chat_message); + BC_ASSERT_PTR_NOT_NULL(content); + } + if (!first_file_transfer || !second_file_transfer) { + const char *content = linphone_chat_message_get_text_content(pauline->stat.last_received_chat_message); + BC_ASSERT_PTR_NOT_NULL(content); + if (!first_file_transfer) + BC_ASSERT_STRING_EQUAL(content, "Hello part 1"); + else if (!second_file_transfer) + BC_ASSERT_STRING_EQUAL(content, "Hello part 2"); + } + + marieRoom.reset(); // Avoid bad weak ptr when the core is destroyed below this line. linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); diff --git a/tester/presence_server_tester.c b/tester/presence_server_tester.c index db3f0ca07..9e8669f27 100644 --- a/tester/presence_server_tester.c +++ b/tester/presence_server_tester.c @@ -430,8 +430,10 @@ static void test_presence_list_base(bool_t enable_compression) { lcs = bctbx_list_append(lcs, pauline->lc); wait_for_list(lcs, &laure->stat.number_of_NotifyPresenceReceived, 2, 4000); - BC_ASSERT_EQUAL(laure->stat.number_of_NotifyPresenceReceived, 2, int, "%d"); - BC_ASSERT_EQUAL(linphone_friend_list_get_expected_notification_version(linphone_core_get_default_friend_list(laure->lc)), 1, int, "%d"); + BC_ASSERT_GREATER(laure->stat.number_of_NotifyPresenceReceived, 2, int, "%d"); + BC_ASSERT_LOWER(laure->stat.number_of_NotifyPresenceReceived, 3, int, "%d"); + BC_ASSERT_GREATER(linphone_friend_list_get_expected_notification_version(linphone_core_get_default_friend_list(laure->lc)), 1, int, "%d"); + BC_ASSERT_LOWER(linphone_friend_list_get_expected_notification_version(linphone_core_get_default_friend_list(laure->lc)), 2, int, "%d"); lf = linphone_friend_list_find_friend_by_address(linphone_core_get_default_friend_list(laure->lc), get_identity_address(marie)); if (!BC_ASSERT_PTR_NOT_NULL(lf)) goto end; BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusBusy, int, "%d"); @@ -485,7 +487,8 @@ static void test_presence_list_base(bool_t enable_compression) { /* The number of PresenceReceived events can be 3 or 4 here. TODO: ideally it should always be 3. */ BC_ASSERT_GREATER(laure->stat.number_of_NotifyPresenceReceived, 3, int, "%d"); BC_ASSERT_LOWER(laure->stat.number_of_NotifyPresenceReceived, 4, int, "%d"); - BC_ASSERT_EQUAL(linphone_friend_list_get_expected_notification_version(linphone_core_get_default_friend_list(laure->lc)), 2, int, "%d"); + BC_ASSERT_GREATER(linphone_friend_list_get_expected_notification_version(linphone_core_get_default_friend_list(laure->lc)), 2, int, "%d"); + BC_ASSERT_LOWER(linphone_friend_list_get_expected_notification_version(linphone_core_get_default_friend_list(laure->lc)), 3, int, "%d"); lf = linphone_friend_list_find_friend_by_address(linphone_core_get_default_friend_list(laure->lc), get_identity_address(marie)); BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOnThePhone, int, "%d"); @@ -865,12 +868,13 @@ static void long_term_presence_phone_alias(void) { } static const char* random_phone_number(void) { - static char phone[10]; + static char phone[11]; int i; phone[0] = '+'; for (i = 1; i < 10; i++) { phone[i] = '0' + rand() % 10; } + phone[10] = '\0'; return phone; } diff --git a/tester/quality_reporting_tester.c b/tester/quality_reporting_tester.c index 1ebe8e1d0..1cd5ef8df 100644 --- a/tester/quality_reporting_tester.c +++ b/tester/quality_reporting_tester.c @@ -16,46 +16,44 @@ along with this program. If not, see . */ -#include #include "linphone/core.h" #include "liblinphone_tester.h" #include "tester_utils.h" #include "quality_reporting.h" -/*avoid crash if x is NULL on libc versions <4.5.26 */ +/* Avoid crash if x is NULL on libc versions <4.5.26 */ #define __strstr(x, y) ((x==NULL)?NULL:strstr(x,y)) -void on_report_send_mandatory(const LinphoneCall *call, SalStreamType stream_type, const LinphoneContent *content){ - char * body = (char *)linphone_content_get_buffer(content); - char * remote_metrics_start = __strstr(body, "RemoteMetrics:"); - BC_ASSERT_TRUE( - __strstr(body, "VQIntervalReport\r\n") == body || - __strstr(body, "VQSessionReport\r\n") == body || - __strstr(body, "VQSessionReport: CallTerm\r\n") == body +static void on_report_send_mandatory (const LinphoneCall *call, SalStreamType stream_type, const LinphoneContent *content) { + const char *body = linphone_content_get_string_buffer(content); + char *remote_metrics_start = __strstr(body, "RemoteMetrics:"); + BC_ASSERT_TRUE((__strstr(body, "VQIntervalReport\r\n") == body) + || (__strstr(body, "VQSessionReport\r\n") == body) + || (__strstr(body, "VQSessionReport: CallTerm\r\n") == body) ); - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "CallID:")); - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "LocalID:")); - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "RemoteID:")); - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "OrigID:")); - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "LocalGroup:")); - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "RemoteGroup:")); - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "LocalAddr:")); - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "IP=")); - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "PORT=")); - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "SSRC=")); - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "RemoteAddr:")); - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "IP=")); - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "PORT=")); - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "SSRC=")); - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "LocalMetrics:")); - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "Timestamps:")); - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "START=")); - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "STOP=")); + BC_ASSERT_PTR_NOT_NULL(body = __strstr(body, "CallID:")); + BC_ASSERT_PTR_NOT_NULL(body = __strstr(body, "LocalID:")); + BC_ASSERT_PTR_NOT_NULL(body = __strstr(body, "RemoteID:")); + BC_ASSERT_PTR_NOT_NULL(body = __strstr(body, "OrigID:")); + BC_ASSERT_PTR_NOT_NULL(body = __strstr(body, "LocalGroup:")); + BC_ASSERT_PTR_NOT_NULL(body = __strstr(body, "RemoteGroup:")); + BC_ASSERT_PTR_NOT_NULL(body = __strstr(body, "LocalAddr:")); + BC_ASSERT_PTR_NOT_NULL(body = __strstr(body, "IP=")); + BC_ASSERT_PTR_NOT_NULL(body = __strstr(body, "PORT=")); + BC_ASSERT_PTR_NOT_NULL(body = __strstr(body, "SSRC=")); + BC_ASSERT_PTR_NOT_NULL(body = __strstr(body, "RemoteAddr:")); + BC_ASSERT_PTR_NOT_NULL(body = __strstr(body, "IP=")); + BC_ASSERT_PTR_NOT_NULL(body = __strstr(body, "PORT=")); + BC_ASSERT_PTR_NOT_NULL(body = __strstr(body, "SSRC=")); + BC_ASSERT_PTR_NOT_NULL(body = __strstr(body, "LocalMetrics:")); + BC_ASSERT_PTR_NOT_NULL(body = __strstr(body, "Timestamps:")); + BC_ASSERT_PTR_NOT_NULL(body = __strstr(body, "START=")); + BC_ASSERT_PTR_NOT_NULL(body = __strstr(body, "STOP=")); - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "SessionDesc:")); - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "PT=")); - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "PD=")); - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "SR=")); + BC_ASSERT_PTR_NOT_NULL(body = __strstr(body, "SessionDesc:")); + BC_ASSERT_PTR_NOT_NULL(body = __strstr(body, "PT=")); + BC_ASSERT_PTR_NOT_NULL(body = __strstr(body, "PD=")); + BC_ASSERT_PTR_NOT_NULL(body = __strstr(body, "SR=")); /* We should have not reached RemoteMetrics section yet */ BC_ASSERT_TRUE(!remote_metrics_start || body < remote_metrics_start); @@ -63,57 +61,58 @@ void on_report_send_mandatory(const LinphoneCall *call, SalStreamType stream_typ BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "DialogID:")); } -char * on_report_send_verify_metrics(const reporting_content_metrics_t *metrics, char * body){ - if (metrics->rtcp_xr_count){ - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "SessionDesc:")); - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "JitterBuffer:")); - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "PacketLoss:")); - } - if (metrics->rtcp_sr_count+metrics->rtcp_xr_count>0){ - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "Delay:")); - } - if (metrics->rtcp_xr_count){ - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "QualityEst:")); +static const char *on_report_send_verify_metrics (const reporting_content_metrics_t *metrics, const char *body) { + if (metrics->rtcp_xr_count) { + BC_ASSERT_PTR_NOT_NULL(body = __strstr(body, "SessionDesc:")); + BC_ASSERT_PTR_NOT_NULL(body = __strstr(body, "JitterBuffer:")); + BC_ASSERT_PTR_NOT_NULL(body = __strstr(body, "PacketLoss:")); } + if (metrics->rtcp_sr_count + metrics->rtcp_xr_count > 0) + BC_ASSERT_PTR_NOT_NULL(body = __strstr(body, "Delay:")); + if (metrics->rtcp_xr_count) + BC_ASSERT_PTR_NOT_NULL(body = __strstr(body, "QualityEst:")); return body; } -void on_report_send_with_rtcp_xr_local(const LinphoneCall *call, SalStreamType stream_type, const LinphoneContent *content){ - char * body = (char*)linphone_content_get_buffer(content); - char * remote_metrics_start = __strstr(body, "RemoteMetrics:"); - reporting_session_report_t * report = linphone_quality_reporting_get_reports(linphone_call_log_get_quality_reporting(linphone_call_get_log(call)))[stream_type]; - on_report_send_mandatory(call,stream_type,content); - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "LocalMetrics:")); - BC_ASSERT_TRUE(!remote_metrics_start || on_report_send_verify_metrics(&report->local_metrics,body) < remote_metrics_start); -} -void on_report_send_with_rtcp_xr_remote(const LinphoneCall *call, SalStreamType stream_type, const LinphoneContent *content){ - char * body = (char*)linphone_content_get_buffer(content); - reporting_session_report_t * report = linphone_quality_reporting_get_reports(linphone_call_log_get_quality_reporting(linphone_call_get_log(call)))[stream_type]; +static void on_report_send_with_rtcp_xr_local (const LinphoneCall *call, SalStreamType stream_type, const LinphoneContent *content) { + char *remote_metrics_start = __strstr(linphone_content_get_string_buffer(content), "RemoteMetrics:"); + reporting_session_report_t *report = linphone_quality_reporting_get_reports(linphone_call_log_get_quality_reporting(linphone_call_get_log(call)))[stream_type]; + on_report_send_mandatory(call, stream_type, content); - on_report_send_mandatory(call,stream_type,content); - if (report->remote_metrics.rtcp_sr_count+report->remote_metrics.rtcp_xr_count>0){ - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "RemoteMetrics:")); - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "Timestamps:")); - on_report_send_verify_metrics(&report->remote_metrics,body); + const char *body = linphone_content_get_string_buffer(content); + BC_ASSERT_PTR_NOT_NULL(body = __strstr(body, "LocalMetrics:")); + BC_ASSERT_TRUE(!remote_metrics_start || on_report_send_verify_metrics(&report->local_metrics, body) < remote_metrics_start); +} + +static void on_report_send_with_rtcp_xr_remote (const LinphoneCall *call, SalStreamType stream_type, const LinphoneContent *content) { + char *body = (char *)linphone_content_get_buffer(content); + reporting_session_report_t *report = linphone_quality_reporting_get_reports(linphone_call_log_get_quality_reporting(linphone_call_get_log(call)))[stream_type]; + + on_report_send_mandatory(call, stream_type, content); + if ((report->remote_metrics.rtcp_sr_count + report->remote_metrics.rtcp_xr_count) > 0) { + BC_ASSERT_PTR_NOT_NULL(body = __strstr(body, "RemoteMetrics:")); + BC_ASSERT_PTR_NOT_NULL(body = __strstr(body, "Timestamps:")); + on_report_send_verify_metrics(&report->remote_metrics, body); } } -void on_report_send_with_rtcp_xr_both(const LinphoneCall *call, SalStreamType stream_type, const LinphoneContent *content){ - on_report_send_with_rtcp_xr_local(call,stream_type,content); - on_report_send_with_rtcp_xr_remote(call,stream_type,content); + +/* +static void on_report_send_with_rtcp_xr_both (const LinphoneCall *call, SalStreamType stream_type, const LinphoneContent *content) { + on_report_send_with_rtcp_xr_local(call, stream_type, content); + on_report_send_with_rtcp_xr_remote(call, stream_type, content); } +*/ -bool_t create_call_for_quality_reporting_tests( - LinphoneCoreManager* marie, - LinphoneCoreManager* pauline, - LinphoneCall** call_marie, - LinphoneCall** call_pauline, - LinphoneCallParams * params_marie, - LinphoneCallParams * params_pauline - ) { - - - bool_t call_succeeded = call_with_params(marie,pauline,params_marie,params_pauline); +static bool_t create_call_for_quality_reporting_tests ( + LinphoneCoreManager *marie, + LinphoneCoreManager *pauline, + LinphoneCall **call_marie, + LinphoneCall **call_pauline, + LinphoneCallParams *params_marie, + LinphoneCallParams *params_pauline +) { + bool_t call_succeeded = call_with_params(marie, pauline, params_marie, params_pauline); BC_ASSERT_TRUE(call_succeeded); if (call_succeeded) { if (call_marie) { @@ -128,24 +127,23 @@ bool_t create_call_for_quality_reporting_tests( return call_succeeded; } -static void quality_reporting_not_used_without_config(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_quality_reporting_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); - LinphoneCall* call_marie = NULL; - LinphoneCall* call_pauline = NULL; +static void quality_reporting_not_used_without_config (void) { + LinphoneCoreManager *marie = linphone_core_manager_new("marie_quality_reporting_rc"); + LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc"); + LinphoneCall *call_marie = NULL; + LinphoneCall *call_pauline = NULL; reporting_session_report_t **quality_reports = NULL; - - if (create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline, NULL, NULL)) { - // marie has stats collection enabled but pauline has not + if (create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline, NULL, NULL)) { + // Marie has stats collection enabled but Pauline has not BC_ASSERT_TRUE(linphone_proxy_config_quality_reporting_enabled(linphone_call_get_dest_proxy(call_marie))); BC_ASSERT_FALSE(linphone_proxy_config_quality_reporting_enabled(linphone_call_get_dest_proxy(call_pauline))); - // this field should be already filled + // This field should be already filled quality_reports = linphone_quality_reporting_get_reports(linphone_call_log_get_quality_reporting(linphone_call_get_log(call_marie))); BC_ASSERT_PTR_NOT_NULL(quality_reports[0]->info.local_addr.ip); - // but not this one since it is updated at the end of call + // But not this one since it is updated at the end of call BC_ASSERT_PTR_NULL(quality_reports[0]->dialog_id); end_call(marie, pauline); } @@ -154,89 +152,94 @@ static void quality_reporting_not_used_without_config(void) { linphone_core_manager_destroy(pauline); } -static void quality_reporting_not_sent_if_call_not_started(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_quality_reporting_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); - LinphoneCallLog* out_call_log; - LinphoneCall* out_call; +static void quality_reporting_not_sent_if_call_not_started (void) { + LinphoneCoreManager *marie = linphone_core_manager_new("marie_quality_reporting_rc"); + LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc"); + LinphoneCallLog *out_call_log; + LinphoneCall *out_call; - linphone_core_set_max_calls(pauline->lc,0); - out_call = linphone_core_invite(marie->lc,"pauline"); + linphone_core_set_max_calls(pauline->lc, 0); + out_call = linphone_core_invite(marie->lc, "pauline"); BC_ASSERT_PTR_NOT_NULL(out_call); - if(out_call == NULL) goto end; + if (!out_call) + goto end; linphone_call_ref(out_call); - BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallError,1, 10000)); - BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallError,1, int, "%d"); + BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallError, 1, 10000)); + BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallError, 1, int, "%d"); - if (bctbx_list_size(linphone_core_get_call_logs(marie->lc))>0) { - out_call_log=(LinphoneCallLog*)(linphone_core_get_call_logs(marie->lc)->data); + if (bctbx_list_size(linphone_core_get_call_logs(marie->lc)) > 0) { + out_call_log = (LinphoneCallLog *)(linphone_core_get_call_logs(marie->lc)->data); BC_ASSERT_PTR_NOT_NULL(out_call_log); - BC_ASSERT_EQUAL(linphone_call_log_get_status(out_call_log),LinphoneCallAborted, int, "%d"); + BC_ASSERT_EQUAL(linphone_call_log_get_status(out_call_log), LinphoneCallAborted, int, "%d"); } linphone_call_unref(out_call); - // wait a few time... - wait_for_until(marie->lc,NULL,NULL,0,1000); + // Wait a few time... + wait_for_until(marie->lc, NULL, NULL, 0, 1000); + + // Since the callee was busy, there should be no publish to do + BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress, 0, int, "%d"); + BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk, 0, int, "%d"); - // since the callee was busy, there should be no publish to do - BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress,0, int, "%d"); - BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,0, int, "%d"); end: linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } -static void quality_reporting_not_sent_if_low_bandwidth(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_quality_reporting_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); - LinphoneCallParams* marie_params; - - marie_params=linphone_core_create_call_params(marie->lc, NULL); - linphone_call_params_enable_low_bandwidth(marie_params,TRUE); +static void quality_reporting_not_sent_if_low_bandwidth (void) { + LinphoneCoreManager *marie = linphone_core_manager_new("marie_quality_reporting_rc"); + LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc"); + LinphoneCallParams *marie_params = linphone_core_create_call_params(marie->lc, NULL); + linphone_call_params_enable_low_bandwidth(marie_params, TRUE); if (create_call_for_quality_reporting_tests(marie, pauline, NULL, NULL, marie_params, NULL)) { end_call(marie, pauline); - BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress,0, int, "%d"); - BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,0, int, "%d"); + BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress, 0, int, "%d"); + BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk, 0, int, "%d"); } linphone_call_params_unref(marie_params); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } -void on_report_send_remove_fields(const LinphoneCall *call, SalStreamType stream_type, const LinphoneContent *content){ - char *body = (char*)linphone_content_get_buffer(content); - /*corrupt start of the report*/ - strncpy(body, "corrupted report is corrupted", strlen("corrupted report is corrupted")); +static void on_report_send_remove_fields (const LinphoneCall *call, SalStreamType stream_type, const LinphoneContent *content) { + char *body = bctbx_strdup(linphone_content_get_string_buffer(content)); + /* Corrupt start of the report */ + const char *corrupted_str = "corrupted report is corrupted"; + size_t corrupted_len = strlen(corrupted_str); + strncpy(body, corrupted_str, corrupted_len); + linphone_content_set_string_buffer((LinphoneContent *)content, body); + bctbx_free(body); } -static void quality_reporting_invalid_report(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_quality_reporting_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); - LinphoneCall* call_marie = NULL; - LinphoneCall* call_pauline = NULL; +static void quality_reporting_invalid_report (void) { + LinphoneCoreManager *marie = linphone_core_manager_new("marie_quality_reporting_rc"); + LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc"); + LinphoneCall *call_marie = NULL; + LinphoneCall *call_pauline = NULL; if (create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline, NULL, NULL)) { linphone_reporting_set_on_report_send(call_marie, on_report_send_remove_fields); end_call(marie, pauline); - BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishProgress,1)); - BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishError,1,3000)); - BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishError,1, int, "%d"); - BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,0, int, "%d"); + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphonePublishProgress, 1)); + BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, &marie->stat.number_of_LinphonePublishError, 1, 3000)); + BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishError, 1, int, "%d"); + BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk, 0, int, "%d"); } + linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } -static void quality_reporting_at_call_termination(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_quality_reporting_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc_rtcp_xr"); - LinphoneCall* call_marie = NULL; - LinphoneCall* call_pauline = NULL; +static void quality_reporting_at_call_termination (void) { + LinphoneCoreManager *marie = linphone_core_manager_new("marie_quality_reporting_rc"); + LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_rc_rtcp_xr"); + LinphoneCall *call_marie = NULL; + LinphoneCall *call_pauline = NULL; reporting_session_report_t **quality_reports = NULL; if (create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline, NULL, NULL)) { @@ -244,32 +247,33 @@ static void quality_reporting_at_call_termination(void) { linphone_core_terminate_all_calls(marie->lc); - // now dialog id should be filled + // Now dialog id should be filled quality_reports = linphone_quality_reporting_get_reports(linphone_call_log_get_quality_reporting(linphone_call_get_log(call_marie))); BC_ASSERT_PTR_NOT_NULL(quality_reports[0]->dialog_id); - BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallReleased,1, 10000)); - BC_ASSERT_TRUE(wait_for_until(pauline->lc,NULL,&pauline->stat.number_of_LinphoneCallReleased,1, 10000)); + BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallReleased, 1, 10000)); + BC_ASSERT_TRUE(wait_for_until(pauline->lc, NULL, &pauline->stat.number_of_LinphoneCallReleased, 1, 10000)); BC_ASSERT_PTR_NULL(linphone_core_get_current_call(marie->lc)); BC_ASSERT_PTR_NULL(linphone_core_get_current_call(pauline->lc)); // PUBLISH submission to the collector should be ok - BC_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphonePublishProgress,1)); - BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress,1, int, "%d"); - BC_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphonePublishOk,1)); + BC_ASSERT_TRUE(wait_for(marie->lc, NULL, &marie->stat.number_of_LinphonePublishProgress, 1)); + BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress, 1, int, "%d"); + BC_ASSERT_TRUE(wait_for(marie->lc, NULL, &marie->stat.number_of_LinphonePublishOk, 1)); } + linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } -static void quality_reporting_interval_report(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc_rtcp_xr"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc_rtcp_xr"); - LinphoneCall* call_marie = NULL; - LinphoneCall* call_pauline = NULL; +static void quality_reporting_interval_report (void) { + LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc_rtcp_xr"); + LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_rc_rtcp_xr"); + LinphoneCall *call_marie = NULL; + LinphoneCall *call_pauline = NULL; - if (create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline, NULL, NULL)) { + if (create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline, NULL, NULL)) { linphone_reporting_set_on_report_send(call_marie, on_report_send_mandatory); linphone_proxy_config_set_quality_reporting_interval(linphone_call_get_dest_proxy(call_marie), 1); @@ -277,125 +281,128 @@ static void quality_reporting_interval_report(void) { BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(pauline->lc)); // PUBLISH submission to the collector should be ok - BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishProgress,1,60000)); - BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,1,60000)); + BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, &marie->stat.number_of_LinphonePublishProgress, 1, 60000)); + BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, &marie->stat.number_of_LinphonePublishOk, 1, 60000)); end_call(marie, pauline); } + linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } #ifdef VIDEO_ENABLED -static void quality_reporting_session_report_if_video_stopped(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc_rtcp_xr"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); - LinphoneCall* call_pauline = NULL; - LinphoneCall* call_marie = NULL; - LinphoneCallParams* pauline_params; - LinphoneCallParams* marie_params; +static void quality_reporting_session_report_if_video_stopped (void) { + LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc_rtcp_xr"); + LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc"); + LinphoneCall *call_pauline = NULL; + LinphoneCall *call_marie = NULL; + LinphoneCallParams *pauline_params; + LinphoneCallParams *marie_params; linphone_core_enable_video_capture(marie->lc, TRUE); linphone_core_enable_video_display(marie->lc, FALSE); linphone_core_enable_video_capture(pauline->lc, TRUE); linphone_core_enable_video_display(pauline->lc, FALSE); - marie_params=linphone_core_create_call_params(marie->lc, NULL); - linphone_call_params_enable_video(marie_params,TRUE); - pauline_params=linphone_core_create_call_params(pauline->lc, NULL); - linphone_call_params_enable_video(pauline_params,TRUE); + marie_params = linphone_core_create_call_params(marie->lc, NULL); + linphone_call_params_enable_video(marie_params, TRUE); + pauline_params = linphone_core_create_call_params(pauline->lc, NULL); + linphone_call_params_enable_video(pauline_params, TRUE); if (create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline, marie_params, pauline_params)) { linphone_reporting_set_on_report_send(call_marie, on_report_send_with_rtcp_xr_local); - BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress,0, int, "%d"); - BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,0, int, "%d"); + BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress, 0, int, "%d"); + BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk, 0, int, "%d"); - BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,NULL,0,3000)); + BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, NULL, 0, 3000)); BC_ASSERT_TRUE(linphone_call_params_video_enabled(linphone_call_get_current_params(call_pauline))); - /*remove video*/ + /* Remove video */ linphone_call_params_unref(pauline_params); - pauline_params=linphone_core_create_call_params(pauline->lc, call_pauline); - linphone_call_params_enable_video(pauline_params,FALSE); - linphone_call_update(call_pauline,pauline_params); + pauline_params = linphone_core_create_call_params(pauline->lc, call_pauline); + linphone_call_params_enable_video(pauline_params, FALSE); + linphone_call_update(call_pauline, pauline_params); linphone_call_params_unref(pauline_params); - BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishProgress,1,10000)); - BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,1,10000)); + BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, &marie->stat.number_of_LinphonePublishProgress, 1, 10000)); + BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, &marie->stat.number_of_LinphonePublishOk, 1, 10000)); BC_ASSERT_FALSE(linphone_call_params_video_enabled(linphone_call_get_current_params(call_pauline))); end_call(marie, pauline); - BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishProgress,2,5000)); - BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,2,5000)); + BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, &marie->stat.number_of_LinphonePublishProgress, 2, 5000)); + BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, &marie->stat.number_of_LinphonePublishOk, 2, 5000)); } linphone_call_params_unref(marie_params); - linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } #endif -void publish_report_with_route_state_changed(LinphoneCore *lc, LinphoneEvent *ev, LinphonePublishState state){ +static void publish_report_with_route_state_changed (LinphoneCore *lc, LinphoneEvent *ev, LinphonePublishState state) { if (state == LinphonePublishProgress) { - BC_ASSERT_STRING_EQUAL(linphone_address_as_string(linphone_event_get_resource(ev)), linphone_proxy_config_get_quality_reporting_collector(linphone_core_get_default_proxy_config(lc))); + char *uri = linphone_address_as_string(linphone_event_get_resource(ev)); + BC_ASSERT_STRING_EQUAL(uri, linphone_proxy_config_get_quality_reporting_collector(linphone_core_get_default_proxy_config(lc))); + bctbx_free(uri); } } static void quality_reporting_sent_using_custom_route(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_quality_reporting_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); - LinphoneCall* call_marie = NULL; - LinphoneCall* call_pauline = NULL; + LinphoneCoreManager *marie = linphone_core_manager_new("marie_quality_reporting_rc"); + LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc"); + LinphoneCall *call_marie = NULL; + LinphoneCall *call_pauline = NULL; LinphoneCoreCbs *cbs = linphone_factory_create_core_cbs(linphone_factory_get()); linphone_core_cbs_set_publish_state_changed(cbs, publish_report_with_route_state_changed); linphone_core_add_callbacks(marie->lc, cbs); linphone_core_cbs_unref(cbs); - //INVALID collector: sip.linphone.org do not collect reports, so it will throw a 404 Not Found error + // INVALID collector: sip.linphone.org do not collect reports, so it will throw a 404 Not Found error linphone_proxy_config_set_quality_reporting_collector(linphone_core_get_default_proxy_config(marie->lc), "sip:sip.linphone.org"); if (create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline, NULL, NULL)) { end_call(marie, pauline); // PUBLISH submission to the collector should be ERROR since route is not valid - BC_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphonePublishProgress,1)); - BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress,1, int, "%d"); - BC_ASSERT_TRUE(wait_for_until(marie->lc,NULL,&marie->stat.number_of_LinphonePublishError,1,10000)); - BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,0,int, "%d"); + BC_ASSERT_TRUE(wait_for(marie->lc, NULL, &marie->stat.number_of_LinphonePublishProgress, 1)); + BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress, 1, int, "%d"); + BC_ASSERT_TRUE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphonePublishError, 1, 10000)); + BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk, 0, int, "%d"); } + linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } #ifdef VIDEO_ENABLED -static void quality_reporting_interval_report_video_and_rtt(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc_rtcp_xr"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc_rtcp_xr"); - LinphoneCall* call_marie = NULL; - LinphoneCall* call_pauline = NULL; - LinphoneCallParams* pauline_params; - LinphoneCallParams* marie_params; - LinphoneChatRoom *pauline_chat_room; +static void quality_reporting_interval_report_video_and_rtt (void) { + LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc_rtcp_xr"); + LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_rc_rtcp_xr"); + LinphoneCall *call_marie = NULL; + LinphoneCall *call_pauline = NULL; + LinphoneCallParams *pauline_params; + LinphoneCallParams *marie_params; + LinphoneChatRoom *pauline_chat_room; linphone_core_enable_video_capture(marie->lc, TRUE); linphone_core_enable_video_display(marie->lc, FALSE); linphone_core_enable_video_capture(pauline->lc, TRUE); linphone_core_enable_video_display(pauline->lc, FALSE); - marie_params=linphone_core_create_call_params(marie->lc, NULL); - linphone_call_params_enable_video(marie_params,TRUE); - linphone_call_params_enable_realtime_text(marie_params,TRUE); - pauline_params=linphone_core_create_call_params(pauline->lc, NULL); - linphone_call_params_enable_video(pauline_params,TRUE); - linphone_call_params_enable_realtime_text(pauline_params,TRUE); + marie_params = linphone_core_create_call_params(marie->lc, NULL); + linphone_call_params_enable_video(marie_params, TRUE); + linphone_call_params_enable_realtime_text(marie_params, TRUE); + pauline_params = linphone_core_create_call_params(pauline->lc, NULL); + linphone_call_params_enable_video(pauline_params, TRUE); + linphone_call_params_enable_realtime_text(pauline_params, TRUE); - if (create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline, marie_params, pauline_params)) { + if (create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline, marie_params, pauline_params)) { linphone_reporting_set_on_report_send(call_marie, on_report_send_mandatory); linphone_proxy_config_set_quality_reporting_interval(linphone_call_get_dest_proxy(call_marie), 3); - BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,NULL,0,3000)); + BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, NULL, 0, 3000)); BC_ASSERT_TRUE(linphone_call_params_video_enabled(linphone_call_get_current_params(call_pauline))); BC_ASSERT_TRUE(linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(call_pauline))); @@ -403,28 +410,32 @@ static void quality_reporting_interval_report_video_and_rtt(void) { BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(pauline->lc)); // PUBLISH submission to the collector should be ok - BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishProgress,1,5000)); - BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,1,10000)); + BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, &marie->stat.number_of_LinphonePublishProgress, 1, 5000)); + BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, &marie->stat.number_of_LinphonePublishOk, 1, 10000)); pauline_chat_room = linphone_call_get_chat_room(call_pauline); BC_ASSERT_PTR_NOT_NULL(pauline_chat_room); + LinphoneChatMessage *rtt_message = NULL; if (pauline_chat_room) { - const char* message = "Lorem Ipsum Belledonnum Communicatum"; + const char *message = "Lorem Ipsum Belledonnum Communicatum"; size_t i; - LinphoneChatMessage* rtt_message = linphone_chat_room_create_message(pauline_chat_room,NULL); + rtt_message = linphone_chat_room_create_message(pauline_chat_room, NULL); LinphoneChatRoom *marie_chat_room = linphone_call_get_chat_room(call_marie); for (i = 0; i < strlen(message); i++) { linphone_chat_message_put_char(rtt_message, message[i]); - BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneIsComposingActiveReceived, (int)i+1, 1000)); + BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneIsComposingActiveReceived, (int)(i + 1), 1000)); BC_ASSERT_EQUAL(linphone_chat_room_get_char(marie_chat_room), message[i], char, "%c"); } - linphone_chat_room_send_chat_message(pauline_chat_room, rtt_message); + linphone_chat_message_send(rtt_message); } end_call(marie, pauline); - /*wait that all publish complete*/ - BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,marie->stat.number_of_LinphonePublishProgress,60000)); + /* Wait that all publish complete */ + BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, &marie->stat.number_of_LinphonePublishOk, marie->stat.number_of_LinphonePublishProgress, 60000)); + + if (rtt_message) + linphone_chat_message_unref(rtt_message); } linphone_call_params_unref(marie_params); @@ -435,10 +446,10 @@ static void quality_reporting_interval_report_video_and_rtt(void) { } #endif -static void video_bandwidth_estimation(void){ +static void video_bandwidth_estimation (void) { LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_rc"); - LinphoneVideoPolicy pol = {0}; + LinphoneVideoPolicy pol = { 0 }; OrtpNetworkSimulatorParams simparams = { 0 }; linphone_core_set_video_device(marie->lc, "Mire: Mire (synthetic moving picture)"); @@ -458,14 +469,15 @@ static void video_bandwidth_estimation(void){ simparams.max_bandwidth = 300000; linphone_core_set_network_simulator_params(marie->lc, &simparams); - if (BC_ASSERT_TRUE(call(marie, pauline))){ - /*wait for the first TMMBR*/ + if (BC_ASSERT_TRUE(call(marie, pauline))) { + /* Wait for the first TMMBR */ BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, &marie->stat.number_of_tmmbr_received, 1, 50000)); BC_ASSERT_GREATER((float)marie->stat.last_tmmbr_value_received, 270000.f, float, "%f"); BC_ASSERT_LOWER((float)marie->stat.last_tmmbr_value_received, 330000.f, float, "%f"); end_call(marie, pauline); } + linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } @@ -478,13 +490,15 @@ test_t quality_reporting_tests[] = { TEST_NO_TAG("Call term session report sent if call ended normally", quality_reporting_at_call_termination), TEST_NO_TAG("Interval report if interval is configured", quality_reporting_interval_report), #ifdef VIDEO_ENABLED - TEST_NO_TAG("Interval report if interval is configured with video and realtime text", quality_reporting_interval_report_video_and_rtt), - TEST_NO_TAG("Session report sent if video stopped during call", quality_reporting_session_report_if_video_stopped), - #endif + TEST_NO_TAG("Interval report if interval is configured with video and realtime text", quality_reporting_interval_report_video_and_rtt), + TEST_NO_TAG("Session report sent if video stopped during call", quality_reporting_session_report_if_video_stopped), + #endif // ifdef VIDEO_ENABLED TEST_NO_TAG("Sent using custom route", quality_reporting_sent_using_custom_route), TEST_NO_TAG("Video bandwidth estimation", video_bandwidth_estimation) }; -test_suite_t quality_reporting_test_suite = {"QualityReporting", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each, - sizeof(quality_reporting_tests) / sizeof(quality_reporting_tests[0]), - quality_reporting_tests}; +test_suite_t quality_reporting_test_suite = { + "QualityReporting", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each, + sizeof(quality_reporting_tests) / sizeof(quality_reporting_tests[0]), + quality_reporting_tests +}; diff --git a/tester/rcfiles/account_creator_rc b/tester/rcfiles/account_creator_rc index 443827462..943f8fca2 100644 --- a/tester/rcfiles/account_creator_rc +++ b/tester/rcfiles/account_creator_rc @@ -4,7 +4,7 @@ password_max_length=12 password_min_length=3 username_max_length=14 username_min_length=3 -username_regex=^[A-Za-z0-9_.\-]*$ +username_regex=^[A-Za-z0-9_.\-\ ]*$ xmlrpc_url=https://sip2.linphone.org:446/wizard.php [proxy_default_values] diff --git a/tester/rcfiles/marie_zrtp_ecdh255_rc b/tester/rcfiles/marie_zrtp_ecdh255_rc new file mode 100644 index 000000000..54374fc58 --- /dev/null +++ b/tester/rcfiles/marie_zrtp_ecdh255_rc @@ -0,0 +1,53 @@ +[sip] +sip_port=-1 +sip_tcp_port=-1 +sip_tls_port=-1 +default_proxy=0 +ping_with_options=0 + +composing_idle_timeout=1 +zrtp_cipher_suites=MS_ZRTP_CIPHER_AES3,MS_ZRTP_CIPHER_AES1 +zrtp_key_agreements_suites=MS_ZRTP_KEY_AGREEMENT_X255 + +[auth_info_0] +username=marie +userid=marie +passwd=secret +realm=sip.example.org + + +[proxy_0] +reg_proxy=sip.example.org;transport=tcp +reg_route=sip.example.org;transport=tcp;lr +reg_identity="Super Marie" +reg_expires=3600 +reg_sendregister=1 +publish=0 +dial_escape_plus=0 + +[friend_0] +url="Paupoche" +pol=accept +subscribe=0 + + +[rtp] +audio_rtp_port=18070-28000 +video_rtp_port=28070-38000 + +[video] +display=0 +capture=0 +show_local=0 +size=qcif +enabled=0 +self_view=0 +automatically_initiate=0 +automatically_accept=0 +device=StaticImage: Static picture + +[sound] +echocancellation=0 #to not overload cpu in case of VG + +[net] +dns_srv_enabled=0 #no srv needed in general diff --git a/tester/rcfiles/marie_zrtp_ecdh448_rc b/tester/rcfiles/marie_zrtp_ecdh448_rc new file mode 100644 index 000000000..76037ed1d --- /dev/null +++ b/tester/rcfiles/marie_zrtp_ecdh448_rc @@ -0,0 +1,54 @@ +[sip] +sip_port=-1 +sip_tcp_port=-1 +sip_tls_port=-1 +default_proxy=0 +ping_with_options=0 + +composing_idle_timeout=1 +zrtp_cipher_suites=MS_ZRTP_CIPHER_AES3,MS_ZRTP_CIPHER_AES1 +zrtp_key_agreements_suites=MS_ZRTP_KEY_AGREEMENT_X448 +zrtp_hash_suites=MS_ZRTP_HASH_S384 + +[auth_info_0] +username=marie +userid=marie +passwd=secret +realm=sip.example.org + + +[proxy_0] +reg_proxy=sip.example.org;transport=tcp +reg_route=sip.example.org;transport=tcp;lr +reg_identity="Super Marie" +reg_expires=3600 +reg_sendregister=1 +publish=0 +dial_escape_plus=0 + +[friend_0] +url="Paupoche" +pol=accept +subscribe=0 + + +[rtp] +audio_rtp_port=18070-28000 +video_rtp_port=28070-38000 + +[video] +display=0 +capture=0 +show_local=0 +size=qcif +enabled=0 +self_view=0 +automatically_initiate=0 +automatically_accept=0 +device=StaticImage: Static picture + +[sound] +echocancellation=0 #to not overload cpu in case of VG + +[net] +dns_srv_enabled=0 #no srv needed in general diff --git a/tester/rcfiles/pauline_zrtp_ecdh255_rc b/tester/rcfiles/pauline_zrtp_ecdh255_rc new file mode 100644 index 000000000..5788c7add --- /dev/null +++ b/tester/rcfiles/pauline_zrtp_ecdh255_rc @@ -0,0 +1,52 @@ +[sip] +sip_port=-1 +sip_tcp_port=-1 +sip_tls_port=-1 +default_proxy=0 +ping_with_options=0 + +composing_idle_timeout=1 +zrtp_cipher_suites=MS_ZRTP_CIPHER_AES3,MS_ZRTP_CIPHER_AES1 +zrtp_key_agreements_suites=MS_ZRTP_KEY_AGREEMENT_X255 + +[auth_info_0] +username=pauline +userid=pauline +passwd=secret +realm=sip.example.org + + +[proxy_0] +reg_proxy=sip2.linphone.org;transport=tcp +reg_route=sip2.linphone.org;transport=tcp +reg_identity=sip:pauline@sip.example.org +reg_expires=3600 +reg_sendregister=1 +publish=0 +dial_escape_plus=0 + +#[friend_0] +#url="Mariette" +#pol=accept +#subscribe=0 + +[rtp] +audio_rtp_port=18070-28000 +video_rtp_port=39072-49000 + +[video] +display=0 +capture=0 +show_local=0 +size=qcif +enabled=0 +self_view=0 +automatically_initiate=0 +automatically_accept=0 +device=StaticImage: Static picture + +[sound] +echocancellation=0 #to not overload cpu in case of VG + +[net] +dns_srv_enabled=0 #no srv needed in general diff --git a/tester/rcfiles/pauline_zrtp_ecdh448_rc b/tester/rcfiles/pauline_zrtp_ecdh448_rc new file mode 100644 index 000000000..0eaefeac7 --- /dev/null +++ b/tester/rcfiles/pauline_zrtp_ecdh448_rc @@ -0,0 +1,53 @@ +[sip] +sip_port=-1 +sip_tcp_port=-1 +sip_tls_port=-1 +default_proxy=0 +ping_with_options=0 + +composing_idle_timeout=1 +zrtp_cipher_suites=MS_ZRTP_CIPHER_AES3,MS_ZRTP_CIPHER_AES1 +zrtp_key_agreements_suites=MS_ZRTP_KEY_AGREEMENT_X448 +zrtp_hash_suites=MS_ZRTP_HASH_S384 + +[auth_info_0] +username=pauline +userid=pauline +passwd=secret +realm=sip.example.org + + +[proxy_0] +reg_proxy=sip2.linphone.org;transport=tcp +reg_route=sip2.linphone.org;transport=tcp +reg_identity=sip:pauline@sip.example.org +reg_expires=3600 +reg_sendregister=1 +publish=0 +dial_escape_plus=0 + +#[friend_0] +#url="Mariette" +#pol=accept +#subscribe=0 + +[rtp] +audio_rtp_port=18070-28000 +video_rtp_port=39072-49000 + +[video] +display=0 +capture=0 +show_local=0 +size=qcif +enabled=0 +self_view=0 +automatically_initiate=0 +automatically_accept=0 +device=StaticImage: Static picture + +[sound] +echocancellation=0 #to not overload cpu in case of VG + +[net] +dns_srv_enabled=0 #no srv needed in general diff --git a/tester/register_tester.c b/tester/register_tester.c index 44e83945f..e69ec1937 100644 --- a/tester/register_tester.c +++ b/tester/register_tester.c @@ -89,7 +89,7 @@ static void register_with_refresh_base_3_for_algo( reset_counters(counters); linphone_core_set_transports(lc, transport); - proxy_cfg = linphone_proxy_config_new(); + proxy_cfg = linphone_core_create_proxy_config(lc); from = create_linphone_address_for_algo(domain, username); @@ -475,7 +475,39 @@ static void authenticated_register_with_provided_credentials(void){ BC_ASSERT_PTR_NULL(lp_config_get_string(linphone_core_get_config(lcm->lc), "auth_info_0", "passwd", NULL)); BC_ASSERT_PTR_NOT_NULL(lp_config_get_string(linphone_core_get_config(lcm->lc), "auth_info_0", "ha1", NULL)); - linphone_proxy_config_destroy(cfg); + linphone_proxy_config_unref(cfg); + linphone_core_manager_destroy(lcm); +} + +static void authenticated_register_with_provided_credentials_and_username_with_space(void) { + LinphoneCoreManager *lcm = linphone_core_manager_new(NULL); + stats *counters = get_stats(lcm->lc); + LinphoneProxyConfig *cfg = linphone_core_create_proxy_config(lcm->lc); + const char *username = "test username"; + LinphoneAddress *from = create_linphone_address_for_algo(auth_domain, username); + + char *addr = linphone_address_as_string(from); + linphone_proxy_config_set_identity(cfg, addr); + ms_free(addr); + + linphone_proxy_config_enable_register(cfg, TRUE); + linphone_proxy_config_set_expires(cfg, 1); + linphone_proxy_config_set_route(cfg, test_route); + linphone_proxy_config_set_server_addr(cfg, test_route); + linphone_address_unref(from); + + LinphoneAuthInfo *ai = linphone_auth_info_new(username, NULL, test_password, NULL, NULL, test_route); + linphone_core_add_auth_info(lcm->lc, ai); + linphone_auth_info_unref(ai); + linphone_core_add_proxy_config(lcm->lc, cfg); + + BC_ASSERT_TRUE(wait_for(lcm->lc, lcm->lc, &counters->number_of_LinphoneRegistrationOk, 1)); + BC_ASSERT_EQUAL(counters->number_of_auth_info_requested, 0, int, "%d"); + + BC_ASSERT_PTR_NULL(lp_config_get_string(linphone_core_get_config(lcm->lc), "auth_info_0", "passwd", NULL)); + BC_ASSERT_PTR_NOT_NULL(lp_config_get_string(linphone_core_get_config(lcm->lc), "auth_info_0", "ha1", NULL)); + + linphone_proxy_config_unref(cfg); linphone_core_manager_destroy(lcm); } @@ -1312,6 +1344,7 @@ test_t register_tests[] = { TEST_NO_TAG("Authenticated register with wrong late credentials", authenticated_register_with_wrong_late_credentials), TEST_NO_TAG("Authenticated register with late credentials", authenticated_register_with_late_credentials), TEST_NO_TAG("Authenticated register with provided credentials", authenticated_register_with_provided_credentials), + TEST_NO_TAG("Authenticated register with provided credentials, username with space", authenticated_register_with_provided_credentials_and_username_with_space), TEST_NO_TAG("Register with refresh", simple_register_with_refresh), TEST_NO_TAG("Authenticated register with refresh", simple_auth_register_with_refresh), TEST_NO_TAG("Register with refresh and send error", register_with_refresh_with_send_error), diff --git a/tester/remote_provisioning/marie_xml b/tester/remote_provisioning/marie_xml new file mode 100644 index 000000000..fe923803d --- /dev/null +++ b/tester/remote_provisioning/marie_xml @@ -0,0 +1,51 @@ + + +
+ -1 + -1 + -1 + 0 + 0 + 0 + 1 +
+
+ marie + marie + secret + + sip.example.org +
+
+ sip.example.org;transport=tcp + sip.example.org;transport=tcp;lr + sip:marie@sip.example.org + 3600 + 1 + 0 + 0 +
+
+ "Paupoche" <sip:pauline@sip.example.org> + accept + 0 +
+
+ 8070 + 9072 +
+
+ 0 + 0 + 0 + vga + 0 + 0 + 0 + 0 + StaticImage: Static picture +
+
+ 0 #to not overload cpu in case of VG +
+
diff --git a/tester/setup_tester.c b/tester/setup_tester.c index b10705004..dfd74b6ec 100644 --- a/tester/setup_tester.c +++ b/tester/setup_tester.c @@ -54,7 +54,10 @@ static void _remove_friends_from_list(LinphoneFriendList *list, const char *frie unsigned int i; for (i = 0 ; i < size ; i++) { LinphoneFriend *fr = linphone_friend_list_find_friend_by_uri(list, friends[i]); - if (fr) linphone_friend_list_remove_friend(list, fr); + if (fr) { + linphone_friend_list_remove_friend(list, fr); + linphone_friend_unref(fr); + } } } @@ -91,9 +94,10 @@ static void _check_friend_result_list(LinphoneCore *lc, const bctbx_list_t *resu if (addr) { char *addrUri = linphone_address_as_string_uri_only(addr); if (addrUri && strcmp(addrUri, uri) == 0) { + bctbx_free(addrUri); return; } - if (addrUri) free(addrUri); + if (addrUri) bctbx_free(addrUri); } } } @@ -102,7 +106,9 @@ static void _check_friend_result_list(LinphoneCore *lc, const bctbx_list_t *resu } static void _create_call_log(LinphoneCore *lc, LinphoneAddress *addrFrom, LinphoneAddress *addrTo) { - linphone_core_create_call_log(lc, addrFrom, addrTo, LinphoneCallOutgoing, 100, time(NULL), time(NULL), LinphoneCallSuccess, FALSE, 1.0); + linphone_call_log_unref( + linphone_core_create_call_log(lc, addrFrom, addrTo, LinphoneCallOutgoing, 100, time(NULL), time(NULL), LinphoneCallSuccess, FALSE, 1.0) + ); } static void linphone_version_test(void){ @@ -115,6 +121,7 @@ static void linphone_version_test(void){ static void core_init_test(void) { LinphoneCore* lc; lc = linphone_factory_create_core(linphone_factory_get(),NULL,NULL,NULL); + /* until we have good certificates on our test server... */ linphone_core_verify_server_certificates(lc,FALSE); if (BC_ASSERT_PTR_NOT_NULL(lc)) { @@ -475,6 +482,29 @@ static void custom_tones_setup(void){ linphone_core_manager_destroy(mgr); } +static void search_friend_without_filter(void) { + LinphoneMagicSearch *magicSearch = NULL; + bctbx_list_t *resultList = NULL; + LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); + LinphoneFriendList *lfl = linphone_core_get_default_friend_list(manager->lc); + + _create_friends_from_tab(manager->lc, lfl, sFriends, sSizeFriend); + + magicSearch = linphone_magic_search_new(manager->lc); + + resultList = linphone_magic_search_get_contact_list_from_filter(magicSearch, "", ""); + + if (BC_ASSERT_PTR_NOT_NULL(resultList)) { + BC_ASSERT_EQUAL(bctbx_list_size(resultList), S_SIZE_FRIEND, int, "%d"); + bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref); + } + + _remove_friends_from_list(lfl, sFriends, sSizeFriend); + + linphone_magic_search_unref(magicSearch); + linphone_core_manager_destroy(manager); +} + static void search_friend_all_domains(void) { LinphoneMagicSearch *magicSearch = NULL; bctbx_list_t *resultList = NULL; @@ -492,7 +522,7 @@ static void search_friend_all_domains(void) { _check_friend_result_list(manager->lc, resultList, 0, sFriends[2], NULL);//"sip:allo@sip.example.org" _check_friend_result_list(manager->lc, resultList, 1, sFriends[3], NULL);//"sip:hello@sip.example.org" _check_friend_result_list(manager->lc, resultList, 2, sFriends[4], NULL);//"sip:hello@sip.test.org" - bctbx_list_free(resultList); + bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref); } _remove_friends_from_list(lfl, sFriends, sSizeFriend); @@ -517,7 +547,7 @@ static void search_friend_one_domain(void) { BC_ASSERT_EQUAL(bctbx_list_size(resultList), 2, int, "%d"); _check_friend_result_list(manager->lc, resultList, 0, sFriends[2], NULL);//"sip:allo@sip.example.org" _check_friend_result_list(manager->lc, resultList, 1, sFriends[3], NULL);//"sip:hello@sip.example.org" - bctbx_list_free(resultList); + bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref); } _remove_friends_from_list(lfl, sFriends, sSizeFriend); @@ -547,7 +577,7 @@ static void search_friend_research_estate(void) { _check_friend_result_list(manager->lc, resultList, 4, sFriends[2], NULL);//"sip:allo@sip.example.org" _check_friend_result_list(manager->lc, resultList, 5, sFriends[3], NULL);//"sip:hello@sip.example.org" _check_friend_result_list(manager->lc, resultList, 6, sFriends[4], NULL);//"sip:hello@sip.test.org" - bctbx_list_free(resultList); + bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref); } resultList = linphone_magic_search_get_contact_list_from_filter(magicSearch, "la", ""); @@ -556,7 +586,7 @@ static void search_friend_research_estate(void) { BC_ASSERT_EQUAL(bctbx_list_size(resultList), 2, int, "%d"); _check_friend_result_list(manager->lc, resultList, 0, sFriends[8], NULL);//"sip:laure@sip.test.org" _check_friend_result_list(manager->lc, resultList, 1, sFriends[6], NULL);//"sip:laura@sip.example.org" - bctbx_list_free(resultList); + bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref); } _remove_friends_from_list(lfl, sFriends, sSizeFriend); @@ -581,7 +611,7 @@ static void search_friend_research_estate_reset(void) { BC_ASSERT_EQUAL(bctbx_list_size(resultList), 2, int, "%d"); _check_friend_result_list(manager->lc, resultList, 0, sFriends[6], NULL);//"sip:laura@sip.example.org" _check_friend_result_list(manager->lc, resultList, 1, sFriends[8], NULL);//"sip:laure@sip.test.org" - bctbx_list_free(resultList); + bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref); } linphone_magic_search_reset_search_cache(magicSearch); @@ -597,7 +627,7 @@ static void search_friend_research_estate_reset(void) { _check_friend_result_list(manager->lc, resultList, 4, sFriends[2], NULL);//"sip:allo@sip.example.org" _check_friend_result_list(manager->lc, resultList, 5, sFriends[3], NULL);//"sip:hello@sip.example.org" _check_friend_result_list(manager->lc, resultList, 6, sFriends[4], NULL);//"sip:hello@sip.test.org" - bctbx_list_free(resultList); + bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref); } _remove_friends_from_list(lfl, sFriends, sSizeFriend); @@ -623,10 +653,56 @@ static void search_friend_with_phone_number(void) { if (BC_ASSERT_PTR_NOT_NULL(resultList)) { BC_ASSERT_EQUAL(bctbx_list_size(resultList), 3, int, "%d"); - _check_friend_result_list(manager->lc, resultList, 0, sFriends[11], NULL);//"sip:+111223344@sip.example.org" - _check_friend_result_list(manager->lc, resultList, 1, sFriends[10], NULL);//"sip:+33655667788@sip.example.org" + _check_friend_result_list(manager->lc, resultList, 0, sFriends[11], NULL);//"sip:+33655667788@sip.example.org" + _check_friend_result_list(manager->lc, resultList, 1, sFriends[10], NULL);//"sip:+111223344@sip.example.org" _check_friend_result_list(manager->lc, resultList, 2, sFriends[5], NULL);//"sip:marie@sip.example.org" - bctbx_list_free(resultList); + bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref); + } + + linphone_magic_search_reset_search_cache(magicSearch); + + resultList = linphone_magic_search_get_contact_list_from_filter(magicSearch, "5", ""); + + if (BC_ASSERT_PTR_NOT_NULL(resultList)) { + BC_ASSERT_EQUAL(bctbx_list_size(resultList), 2, int, "%d"); + _check_friend_result_list(manager->lc, resultList, 0, sFriends[11], NULL);//"sip:+33655667788@sip.example.org" + _check_friend_result_list(manager->lc, resultList, 1, sFriends[5], NULL);//"sip:marie@sip.example.org" + bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref); + } + + resultList = linphone_magic_search_get_contact_list_from_filter(magicSearch, "55", ""); + + if (BC_ASSERT_PTR_NOT_NULL(resultList)) { + BC_ASSERT_EQUAL(bctbx_list_size(resultList), 2, int, "%d"); + _check_friend_result_list(manager->lc, resultList, 0, sFriends[11], NULL);//"sip:+33655667788@sip.example.org" + _check_friend_result_list(manager->lc, resultList, 1, sFriends[5], NULL);//"sip:marie@sip.example.org" + bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref); + } + + resultList = linphone_magic_search_get_contact_list_from_filter(magicSearch, "556", ""); + + if (BC_ASSERT_PTR_NOT_NULL(resultList)) { + BC_ASSERT_EQUAL(bctbx_list_size(resultList), 2, int, "%d"); + _check_friend_result_list(manager->lc, resultList, 0, sFriends[11], NULL);//"sip:+33655667788@sip.example.org" + _check_friend_result_list(manager->lc, resultList, 1, sFriends[5], NULL);//"sip:marie@sip.example.org" + bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref); + } + + resultList = linphone_magic_search_get_contact_list_from_filter(magicSearch, "5566", ""); + + if (BC_ASSERT_PTR_NOT_NULL(resultList)) { + BC_ASSERT_EQUAL(bctbx_list_size(resultList), 2, int, "%d"); + _check_friend_result_list(manager->lc, resultList, 0, sFriends[11], NULL);//"sip:+33655667788@sip.example.org" + _check_friend_result_list(manager->lc, resultList, 1, sFriends[5], NULL);//"sip:marie@sip.example.org" + bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref); + } + + resultList = linphone_magic_search_get_contact_list_from_filter(magicSearch, "55667", ""); + + if (BC_ASSERT_PTR_NOT_NULL(resultList)) { + BC_ASSERT_EQUAL(bctbx_list_size(resultList), 1, int, "%d"); + _check_friend_result_list(manager->lc, resultList, 0, sFriends[11], NULL);//"sip:+33655667788@sip.example.org" + bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref); } _remove_friends_from_list(lfl, sFriends, sSizeFriend); @@ -640,8 +716,8 @@ static void search_friend_with_presence(void) { bctbx_list_t *resultList = NULL; LinphoneCoreManager* manager = linphone_core_manager_create("marie_rc"); LinphoneFriendList *lfl = linphone_core_get_default_friend_list(manager->lc); - const char* chloeSipUri = {"sip:chloe@sip.example.org"}; - const char* chloePhoneNumber = {"0633556644"}; + const char *chloeSipUri = "sip:chloe@sip.example.org"; + const char *chloePhoneNumber = "0633556644"; LinphoneFriend *chloeFriend = linphone_core_create_friend(manager->lc); LinphonePresenceModel *chloePresence = linphone_core_create_presence_model(manager->lc); LinphoneProxyConfig *proxy = linphone_core_get_default_proxy_config(manager->lc); @@ -667,7 +743,7 @@ static void search_friend_with_presence(void) { _check_friend_result_list(manager->lc, resultList, 0, sFriends[11], NULL);//"sip:+111223344@sip.example.org" _check_friend_result_list(manager->lc, resultList, 1, chloeSipUri, chloePhoneNumber);//"sip:chloe@sip.example.org" _check_friend_result_list(manager->lc, resultList, 2, sFriends[10], NULL);//"sip:+33655667788@sip.example.org" - bctbx_list_free(resultList); + bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref); } linphone_magic_search_reset_search_cache(magicSearch); @@ -678,15 +754,15 @@ static void search_friend_with_presence(void) { // 1 + last address from filter "sip:chloe@sip.example.org" BC_ASSERT_EQUAL(bctbx_list_size(resultList), 2, int, "%d"); _check_friend_result_list(manager->lc, resultList, 0, chloeSipUri, chloePhoneNumber);//"sip:chloe@sip.example.org" - bctbx_list_free(resultList); + bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref); } _remove_friends_from_list(lfl, sFriends, sSizeFriend); - { - LinphoneFriend *fr = linphone_friend_list_find_friend_by_uri(lfl, chloeSipUri); - if (fr != NULL) linphone_friend_list_remove_friend(lfl, fr); - if (chloeFriend) linphone_friend_unref(chloeFriend); - } + + LinphoneFriend *fr = linphone_friend_list_find_friend_by_uri(lfl, chloeSipUri); + linphone_friend_list_remove_friend(lfl, fr); + + if (chloeFriend) linphone_friend_unref(chloeFriend); linphone_magic_search_unref(magicSearch); linphone_core_manager_destroy(manager); @@ -722,7 +798,7 @@ static void search_friend_in_call_log(void) { _check_friend_result_list(manager->lc, resultList, 1, sFriends[1], NULL);//"sip:charette@sip.example.org" _check_friend_result_list(manager->lc, resultList, 2, chloeSipUri, NULL);//"sip:chloe@sip.example.org" _check_friend_result_list(manager->lc, resultList, 3, charlesSipUri, NULL);//"sip:charles@sip.test.org" - bctbx_list_free(resultList); + bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref); } linphone_magic_search_reset_search_cache(magicSearch); @@ -733,7 +809,7 @@ static void search_friend_in_call_log(void) { BC_ASSERT_EQUAL(bctbx_list_size(resultList), 2, int, "%d"); _check_friend_result_list(manager->lc, resultList, 0, sFriends[0], NULL);//"sip:charu@sip.test.org" _check_friend_result_list(manager->lc, resultList, 1, charlesSipUri, NULL);//"sip:charles@sip.test.org" - bctbx_list_free(resultList); + bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref); } _remove_friends_from_list(lfl, sFriends, sSizeFriend); @@ -768,9 +844,11 @@ static void search_friend_last_item_is_filter(void) { BC_ASSERT_STRING_EQUAL(linphone_address_get_username(srAddress), "newaddress"); } } - bctbx_list_free(resultList); + bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref); } + _remove_friends_from_list(lfl, sFriends, sSizeFriend); + linphone_magic_search_unref(magicSearch); linphone_core_manager_destroy(manager); } @@ -811,7 +889,7 @@ static void search_friend_with_name(void) { BC_ASSERT_EQUAL(bctbx_list_size(resultList), 2, int, "%d"); _check_friend_result_list(manager->lc, resultList, 0, stephanie1SipUri, NULL);//"sip:toto@sip.example.org" _check_friend_result_list(manager->lc, resultList, 1, stephanie2SipUri, NULL);//"sip:stephanie@sip.example.org" - bctbx_list_free(resultList); + bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref); } linphone_magic_search_reset_search_cache(magicSearch); @@ -822,7 +900,7 @@ static void search_friend_with_name(void) { BC_ASSERT_EQUAL(bctbx_list_size(resultList), 2, int, "%d"); _check_friend_result_list(manager->lc, resultList, 0, stephanie2SipUri, NULL);//"sip:stephanie@sip.example.org" _check_friend_result_list(manager->lc, resultList, 1, stephanie1SipUri, NULL);//"sip:toto@sip.example.org" - bctbx_list_free(resultList); + bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref); } _remove_friends_from_list(lfl, sFriends, sSizeFriend); @@ -837,38 +915,85 @@ static void search_friend_with_name(void) { linphone_core_manager_destroy(manager); } -static void search_friend_large_database(void) { - MSTimeSpec start, current; +static void search_friend_with_name_with_uppercase(void) { LinphoneMagicSearch *magicSearch = NULL; bctbx_list_t *resultList = NULL; - char *dbPath = bc_tester_res("db/friends.db"); - char searchedFriend[] = {"6295103032641994169"}; - char subBuff[30]; LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); - unsigned int i; + LinphoneFriendList *lfl = linphone_core_get_default_friend_list(manager->lc); + const char *stephanie1SipUri = {"sip:toto@sip.example.org"}; + const char *stephanie2SipUri = {"sip:stephanie@sip.example.org"}; + LinphoneFriend *stephanie1Friend = linphone_core_create_friend(manager->lc); + LinphoneFriend *stephanie2Friend = linphone_core_create_friend(manager->lc); + LinphoneVcard *stephanie1Vcard = linphone_factory_create_vcard(linphone_factory_get()); + LinphoneVcard *stephanie2Vcard = linphone_factory_create_vcard(linphone_factory_get()); + const char *stephanie1Name = {"STEPHANIE delarue"}; + const char *stephanie2Name = {"alias delarue"}; - linphone_core_set_friends_database_path(manager->lc, dbPath); + _create_friends_from_tab(manager->lc, lfl, sFriends, sSizeFriend); + + linphone_vcard_set_full_name(stephanie1Vcard, stephanie1Name); // STEPHANIE delarue + linphone_vcard_set_url(stephanie1Vcard, stephanie1SipUri); //sip:toto@sip.example.org + linphone_vcard_add_sip_address(stephanie1Vcard, stephanie1SipUri); + linphone_friend_set_vcard(stephanie1Friend, stephanie1Vcard); + linphone_core_add_friend(manager->lc, stephanie1Friend); + + linphone_vcard_set_full_name(stephanie2Vcard, stephanie2Name); // alias delarue + linphone_vcard_set_url(stephanie2Vcard, stephanie2SipUri); //sip:stephanie@sip.example.org + linphone_vcard_add_sip_address(stephanie2Vcard, stephanie2SipUri); + linphone_friend_set_vcard(stephanie2Friend, stephanie2Vcard); + linphone_core_add_friend(manager->lc, stephanie2Friend); magicSearch = linphone_magic_search_new(manager->lc); - for (i = 1; i < sizeof(searchedFriend) ; i++) { - memcpy(subBuff, &searchedFriend, i); + resultList = linphone_magic_search_get_contact_list_from_filter(magicSearch, "stephanie", ""); + + if (BC_ASSERT_PTR_NOT_NULL(resultList)) { + BC_ASSERT_EQUAL(bctbx_list_size(resultList), 2, int, "%d"); + _check_friend_result_list(manager->lc, resultList, 0, stephanie1SipUri, NULL);//"sip:toto@sip.example.org" + _check_friend_result_list(manager->lc, resultList, 1, stephanie2SipUri, NULL);//"sip:stephanie@sip.example.org" + bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref); + } + + linphone_magic_search_reset_search_cache(magicSearch); + + _remove_friends_from_list(lfl, sFriends, sSizeFriend); + linphone_friend_list_remove_friend(lfl, stephanie1Friend); + linphone_friend_list_remove_friend(lfl, stephanie2Friend); + if (stephanie1Friend) linphone_friend_unref(stephanie1Friend); + if (stephanie2Friend) linphone_friend_unref(stephanie2Friend); + if (stephanie1Vcard) linphone_vcard_unref(stephanie1Vcard); + if (stephanie2Vcard) linphone_vcard_unref(stephanie2Vcard); + + linphone_magic_search_unref(magicSearch); + linphone_core_manager_destroy(manager); +} + +static void search_friend_large_database(void) { + char *dbPath = bc_tester_res("db/friends.db"); + char *searchedFriend = "6295103032641994169"; + LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); + linphone_core_set_friends_database_path(manager->lc, dbPath); + LinphoneMagicSearch *magicSearch = linphone_magic_search_new(manager->lc); + + for (size_t i = 1; i < strlen(searchedFriend) ; i++) { + MSTimeSpec start, current; + char subBuff[20]; + memcpy(subBuff, searchedFriend, i); subBuff[i] = '\0'; liblinphone_tester_clock_start(&start); - resultList = linphone_magic_search_get_contact_list_from_filter(magicSearch, subBuff, ""); + bctbx_list_t *resultList = linphone_magic_search_get_contact_list_from_filter(magicSearch, subBuff, ""); if (BC_ASSERT_PTR_NOT_NULL(resultList)) { ms_get_cur_time(¤t); - ms_message("Searching time: %lld ms" ,((current.tv_sec - start.tv_sec)*1000LL) + ((current.tv_nsec - start.tv_nsec)/1000000LL)); - - if (BC_ASSERT_PTR_NOT_NULL(resultList)) ms_message("List size: %zu", bctbx_list_size(resultList)); - - bctbx_list_free(resultList); + ms_message("Searching time: %lld ms", + ((current.tv_sec - start.tv_sec) * 1000LL) + ((current.tv_nsec - start.tv_nsec) / 1000000LL)); + ms_message("List size: %zu", bctbx_list_size(resultList)); + bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref); } } - free(dbPath); linphone_magic_search_unref(magicSearch); linphone_core_manager_destroy(manager); + free(dbPath); } test_t setup_tests[] = { @@ -888,16 +1013,18 @@ test_t setup_tests[] = { TEST_NO_TAG("Codec usability", codec_usability_test), TEST_NO_TAG("Codec setup", codec_setup), TEST_NO_TAG("Custom tones setup", custom_tones_setup), - TEST_TWO_TAGS("Search friend from all domains", search_friend_all_domains, "MagicSearch", "LeaksMemory"), - TEST_TWO_TAGS("Search friend from one domain", search_friend_one_domain, "MagicSearch", "LeaksMemory"), - TEST_TWO_TAGS("Multiple looking for friends with the same cache", search_friend_research_estate, "MagicSearch", "LeaksMemory"), - TEST_TWO_TAGS("Multiple looking for friends with cache resetting", search_friend_research_estate_reset, "MagicSearch", "LeaksMemory"), - TEST_TWO_TAGS("Search friend with phone number", search_friend_with_phone_number, "MagicSearch", "LeaksMemory"), - TEST_TWO_TAGS("Search friend and find it with its presence", search_friend_with_presence, "MagicSearch", "LeaksMemory"), - TEST_TWO_TAGS("Search friend in call log", search_friend_in_call_log, "MagicSearch", "LeaksMemory"), - TEST_TWO_TAGS("Search friend last item is the filter", search_friend_last_item_is_filter, "MagicSearch", "LeaksMemory"), - TEST_TWO_TAGS("Search friend with name", search_friend_with_name, "MagicSearch", "LeaksMemory"), - TEST_TWO_TAGS("Search friend in large friends database", search_friend_large_database, "MagicSearch", "LeaksMemory") + TEST_ONE_TAG("Search friend without filter", search_friend_without_filter, "MagicSearch"), + TEST_ONE_TAG("Search friend from all domains", search_friend_all_domains, "MagicSearch"), + TEST_ONE_TAG("Search friend from one domain", search_friend_one_domain, "MagicSearch"), + TEST_ONE_TAG("Multiple looking for friends with the same cache", search_friend_research_estate, "MagicSearch"), + TEST_ONE_TAG("Multiple looking for friends with cache resetting", search_friend_research_estate_reset, "MagicSearch"), + TEST_ONE_TAG("Search friend with phone number", search_friend_with_phone_number, "MagicSearch"), + TEST_ONE_TAG("Search friend and find it with its presence", search_friend_with_presence, "MagicSearch"), + TEST_ONE_TAG("Search friend in call log", search_friend_in_call_log, "MagicSearch"), + TEST_ONE_TAG("Search friend last item is the filter", search_friend_last_item_is_filter, "MagicSearch"), + TEST_ONE_TAG("Search friend with name", search_friend_with_name, "MagicSearch"), + TEST_ONE_TAG("Search friend with uppercase name", search_friend_with_name_with_uppercase, "MagicSearch"), + TEST_ONE_TAG("Search friend in large friends database", search_friend_large_database, "MagicSearch") }; test_suite_t setup_test_suite = {"Setup", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each, diff --git a/tester/sipp/simple_publish.xml b/tester/sipp/simple_publish.xml index 4040471ce..7b0ddfda2 100644 --- a/tester/sipp/simple_publish.xml +++ b/tester/sipp/simple_publish.xml @@ -38,10 +38,11 @@ Content-Length: [len] - + open + sip:[service]@[local_ip]:[local_port] 2015-09-28T15:49:00Z @@ -74,10 +75,11 @@ Content-Length: [len] - + open + sip:[service]@[local_ip]:[local_port] 2015-09-28T15:49:00Z diff --git a/tester/tester.c b/tester/tester.c index 8d4e1b87d..53b408d3c 100644 --- a/tester/tester.c +++ b/tester/tester.c @@ -108,6 +108,8 @@ static void auth_info_requested(LinphoneCore *lc, const char *realm, const char void reset_counters( stats* counters) { if (counters->last_received_chat_message) linphone_chat_message_unref(counters->last_received_chat_message); if (counters->last_received_info_message) linphone_info_message_unref(counters->last_received_info_message); + if (counters->dtmf_list_received) bctbx_free(counters->dtmf_list_received); + memset(counters,0,sizeof(stats)); } @@ -431,6 +433,17 @@ LinphoneCoreManager* linphone_core_manager_create(const char* rc_file) { return linphone_core_manager_create2(rc_file, NULL); } +LinphoneCoreManager* linphone_core_manager_new4(const char* rc_file, int check_for_proxies, const char* phone_alias, const char* contact_params, int expires) { + /* This function is for testing purposes. */ + LinphoneCoreManager *manager = ms_new0(LinphoneCoreManager, 1); + + linphone_core_manager_init(manager, rc_file, phone_alias); + linphone_proxy_config_set_contact_parameters(linphone_core_get_default_proxy_config(manager->lc), contact_params); + linphone_proxy_config_set_expires(linphone_core_get_default_proxy_config(manager->lc), expires); + linphone_core_manager_start(manager, check_for_proxies); + return manager; +} + LinphoneCoreManager* linphone_core_manager_new3(const char* rc_file, bool_t check_for_proxies, const char* phone_alias) { LinphoneCoreManager *manager = linphone_core_manager_create2(rc_file, phone_alias); linphone_core_manager_start(manager, check_for_proxies); @@ -488,10 +501,6 @@ void linphone_core_manager_uninit(LinphoneCoreManager *mgr) { if (mgr->phone_alias) { ms_free(mgr->phone_alias); } - if (mgr->stat.last_received_chat_message) { - linphone_chat_message_unref(mgr->stat.last_received_chat_message); - } - if (mgr->stat.last_received_info_message) linphone_info_message_unref(mgr->stat.last_received_info_message); if (mgr->identity) { linphone_address_unref(mgr->identity); } @@ -505,6 +514,8 @@ void linphone_core_manager_uninit(LinphoneCoreManager *mgr) { if (mgr->cbs) linphone_core_cbs_unref(mgr->cbs); + reset_counters(&mgr->stat); + manager_count--; linphone_core_set_log_level_mask(old_log_level); } @@ -597,7 +608,9 @@ void liblinphone_tester_add_suites() { bc_tester_add_suite(&tunnel_test_suite); bc_tester_add_suite(&offeranswer_test_suite); bc_tester_add_suite(&call_test_suite); - bc_tester_add_suite(&call_video_test_suite); + #ifdef VIDEO_ENABLED + bc_tester_add_suite(&call_video_test_suite); + #endif // ifdef VIDEO_ENABLED bc_tester_add_suite(&audio_bypass_suite); bc_tester_add_suite(&multi_call_test_suite); bc_tester_add_suite(&message_test_suite); @@ -607,7 +620,7 @@ void liblinphone_tester_add_suites() { bc_tester_add_suite(&stun_test_suite); bc_tester_add_suite(&event_test_suite); bc_tester_add_suite(&conference_event_test_suite); - bc_tester_add_suite(&content_manager_test_suite); + bc_tester_add_suite(&contents_test_suite); bc_tester_add_suite(&flexisip_test_suite); bc_tester_add_suite(&remote_provisioning_test_suite); bc_tester_add_suite(&quality_reporting_test_suite); diff --git a/tester/tools/private-access.h b/tester/tools/private-access.h index 79e0f9429..6f49adc09 100644 --- a/tester/tools/private-access.h +++ b/tester/tools/private-access.h @@ -38,7 +38,7 @@ #define L_ENABLE_ATTR_ACCESS(CLASS, ATTR_TYPE, ATTR_NAME) \ template \ struct L_INTERNAL_STRUCT_L_ATTR_GET(CLASS, ATTR_NAME) { \ - friend constexpr ATTR_TYPE (CLASS::*get(AttrSpy *)) { \ + friend constexpr ATTR_TYPE CLASS::*get(AttrSpy *) { \ return Attr; \ } \ }; \ @@ -46,7 +46,7 @@ struct L_INTERNAL_STRUCT_ATTR_SPY(ATTR_NAME); \ template<> \ struct L_INTERNAL_STRUCT_ATTR_SPY(ATTR_NAME) { \ - friend constexpr ATTR_TYPE (CLASS::*get(L_INTERNAL_STRUCT_ATTR_SPY(ATTR_NAME) *)); \ + friend constexpr ATTR_TYPE CLASS::*get(L_INTERNAL_STRUCT_ATTR_SPY(ATTR_NAME) *); \ }; \ template struct L_INTERNAL_STRUCT_L_ATTR_GET(CLASS, ATTR_NAME)< \ L_INTERNAL_STRUCT_ATTR_SPY(ATTR_NAME), \ diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 664ed68e6..84cfcd62f 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -364,8 +364,12 @@ static void friends_sqlite_store_lot_of_friends(void) { char* errmsg = NULL; int ret; char *buf; + char *friends_db = bc_tester_file("friends.db"); + + unlink(friends_db); + ret = sqlite3_open(friends_db, &db); + bc_free(friends_db); - ret = sqlite3_open(linphone_core_get_friends_database_path(lc), &db); BC_ASSERT_TRUE(ret ==SQLITE_OK); ret = sqlite3_exec(db,"BEGIN",0,0,&errmsg); BC_ASSERT_TRUE(ret ==SQLITE_OK); @@ -432,8 +436,12 @@ static void friends_sqlite_find_friend_in_lot_of_friends(void) { char *buf; bctoolboxTimeSpec t1; bctoolboxTimeSpec t2; + char *friends_db = bc_tester_file("friends.db"); + + unlink(friends_db); + ret = sqlite3_open(friends_db, &db); + bc_free(friends_db); - ret = sqlite3_open(linphone_core_get_friends_database_path(lc), &db); BC_ASSERT_TRUE(ret ==SQLITE_OK); ret = sqlite3_exec(db,"BEGIN",0,0,&errmsg); BC_ASSERT_TRUE(ret ==SQLITE_OK); @@ -943,7 +951,9 @@ static void find_friend_by_ref_key_test(void) { goto end; } addr = linphone_friend_get_address(lf2); - BC_ASSERT_STRING_EQUAL(linphone_address_as_string_uri_only(addr), "sip:toto@sip.linphone.org"); + char *uri_addr = linphone_address_as_string_uri_only(addr); + BC_ASSERT_STRING_EQUAL(uri_addr, "sip:toto@sip.linphone.org"); + bctbx_free(uri_addr); BC_ASSERT_EQUAL(lf2, lf, void*, "%p"); end: linphone_friend_unref(lf); diff --git a/tools/abstractapi.py b/tools/abstractapi.py index 2ea931971..e4a464b43 100644 --- a/tools/abstractapi.py +++ b/tools/abstractapi.py @@ -428,27 +428,32 @@ class Class(Namespace): self.classMethods.sort() -class Interface(DocumentableObject): +class Interface(Namespace): def __init__(self, name): - DocumentableObject.__init__(self, name) - self.methods = [] + Namespace.__init__(self, name) + self.instanceMethods = [] + self.classMethods = [] self._listenedClass = None - - def add_method(self, method): - self.methods.append(method) + + def add_instance_methods(self, method): + self.instanceMethods.append(method) method.parent = self - + + def add_class_methods(self, method): + self.classMethods.append(method) + method.parent = self + @property def listenedClass(self): return self._listenedClass - + @listenedClass.setter def listenedClass(self, method): - self.methods.append(method) + self.instanceMethods.append(method) method.parent = self - + def sort(self): - self.methods.sort() + self.instanceMethods.sort() class CParser(object): @@ -619,7 +624,7 @@ class CParser(object): self._fix_all_types_in_method(method) def _fix_all_types_in_interface(self, interface): - for method in interface.methods: + for method in interface.instanceMethods: self._fix_all_types_in_method(method) def _fix_all_types_in_method(self, method): @@ -784,7 +789,7 @@ class CParser(object): if property.name != 'user_data': try: method = self._parse_listener_property(property, listener, cclass.events) - listener.add_method(method) + listener.add_instance_methods(method) except BlacklistedSymbolError as e: logger.debug(e) @@ -819,6 +824,8 @@ class CParser(object): argName.from_snake_case(arg.name) argument = Argument(argName, self.parse_type(arg)) method.add_arguments(argument) + method.briefDescription = event.briefDoc + method.detailedDescription = event.detailedDoc return method @@ -949,15 +956,12 @@ class Translator: except KeyError: raise ValueError("Invalid language code: '{0}'".format(langCode)) - def _get_object_name(self, obj): - return obj.desc.name if isinstance(obj, (EnumType, ClassType)) else obj.name - - def _compute_namespace_name(self, namespace, obj): - if namespace is not None: - return namespace.name if namespace is not GlobalNs else None - else: - namespace = obj.find_first_ancestor_by_type(Enum, Class, Namespace, Interface) - return metaname.Name.find_common_parent(self._get_object_name(obj), namespace.name) + @staticmethod + def _namespace_to_name_translator_params(namespace): + return { + 'recursive': True, + 'topAncestor': namespace.name if namespace is not None else None + } class CLikeLangTranslator(Translator): @@ -971,8 +975,11 @@ class CLikeLangTranslator(Translator): else: raise TypeError('invalid enumerator value type: {0}'.format(value)) - def translate_argument(self, argument, **kargs): - return '{0} {1}'.format(argument.type.translate(self, **kargs), argument.name.translate(self.nameTranslator)) + def translate_argument(self, argument, hideArgName=False, namespace=None): + ret = argument.type.translate(self, namespace=namespace) + if not hideArgName: + ret += (' ' + argument.name.translate(self.nameTranslator)) + return ret class CLangTranslator(CLikeLangTranslator): @@ -982,19 +989,19 @@ class CLangTranslator(CLikeLangTranslator): self.falseConstantToken = 'FALSE' self.trueConstantToken = 'TRUE' - def translate_base_type(self, _type): + def translate_base_type(self, _type, **kargs): return _type.cDecl - def translate_enum_type(self, _type): + def translate_enum_type(self, _type, **kargs): return _type.cDecl - def translate_class_type(self, _type): + def translate_class_type(self, _type, **kargs): return _type.cDecl - def translate_list_type(self, _type): + def translate_list_type(self, _type, **kargs): return _type.cDecl - def translate_enumerator_value(self, value): + def translate_enumerator_value(self, value, **kargs): if value is None: return None elif isinstance(value, int): @@ -1004,19 +1011,20 @@ class CLangTranslator(CLikeLangTranslator): else: raise TypeError('invalid enumerator value type: {0}'.format(value)) - def translate_method_as_prototype(self, method, **params): - _class = method.find_first_ancestor_by_type(Class) - params = '{const}{className} *obj'.format( - className=_class.name.to_c(), - const='const ' if method.isconst else '' - ) - for arg in method.args: - params += (', ' + arg.translate(self)) - - return '{returnType} {name}({params})'.format( - returnType=method.returnType.translate(self), + def translate_method_as_prototype(self, method, hideArguments=False, hideArgNames=False, hideReturnType=False, stripDeclarators=False, namespace=None): + _class = method.find_first_ancestor_by_type(Class,Interface) + params = [] + if not hideArguments: + params.append('{const}{className} *obj'.format( + className=_class.name.to_c(), + const='const ' if method.isconst and not stripDeclarators else '' + )) + for arg in method.args: + params.append(arg.translate(self, hideArgName=hideArgNames)) + return '{returnType}{name}({params})'.format( + returnType=(method.returnType.translate(self) + ' ') if not hideReturnType else '', name=method.name.translate(self.nameTranslator), - params=params + params=', '.join(params) ) @@ -1028,7 +1036,7 @@ class CppLangTranslator(CLikeLangTranslator): self.trueConstantToken = 'true' self.ambigousTypes = [] - def translate_base_type(self, _type, showStdNs=True, namespace=None): + def translate_base_type(self, _type, namespace=None): if _type.name == 'void': if _type.isref: return 'void *' @@ -1058,14 +1066,11 @@ class CppLangTranslator(CLikeLangTranslator): elif _type.name == 'status': res = 'linphone::Status' elif _type.name == 'string': - res = CppLangTranslator.prepend_std('string', showStdNs) + res = 'std::string' if type(_type.parent) is Argument: res += ' &' elif _type.name == 'string_array': - res = '{0}<{1}>'.format( - CppLangTranslator.prepend_std('list', showStdNs), - CppLangTranslator.prepend_std('string', showStdNs) - ) + res = 'std::list' if type(_type.parent) is Argument: res += ' &' else: @@ -1085,81 +1090,50 @@ class CppLangTranslator(CLikeLangTranslator): res += ' *' return res - def translate_enum_type(self, type_, showStdNs=True, namespace=None): + def translate_enum_type(self, type_, namespace=None): if type_.desc is None: raise TranslationError('{0} has not been fixed'.format(type_.name)) - nsName = self._compute_namespace_name(namespace, type_) - return type_.desc.name.translate(self.nameTranslator, recursive=True, topAncestor=nsName) + return type_.desc.name.translate(self.nameTranslator, **Translator._namespace_to_name_translator_params(namespace)) - def translate_class_type(self, type_, showStdNs=True, namespace=None): + def translate_class_type(self, type_, namespace=None): if type_.desc is None: raise TranslationError('{0} has not been fixed'.format(type_.name)) - nsName = self._compute_namespace_name(namespace, type_) - res = type_.desc.name.translate(self.nameTranslator, recursive=True, topAncestor=nsName) + res = type_.desc.name.translate(self.nameTranslator, **Translator._namespace_to_name_translator_params(namespace)) if type_.desc.refcountable: if type_.isconst: res = 'const ' + res if type(type_.parent) is Argument: - return 'const {0}<{1}> &'.format( - CppLangTranslator.prepend_std('shared_ptr', showStdNs), - res - ) + return 'const std::shared_ptr<{0}> &'.format(res) else: - return '{0}<{1}>'.format( - CppLangTranslator.prepend_std('shared_ptr', showStdNs), - res - ) + return 'std::shared_ptr<{0}>'.format(res) else: if type(type_.parent) is Argument: return 'const {0} &'.format(res) else: return '{0}'.format(res) - def translate_list_type(self, _type, showStdNs=True, namespace=None): + def translate_list_type(self, _type, namespace=None): if _type.containedTypeDesc is None: raise TranslationError('{0} has not been fixed'.format(_type.containedTypeName)) elif isinstance(_type.containedTypeDesc, BaseType): res = _type.containedTypeDesc.translate(self) else: - res = _type.containedTypeDesc.translate(self, showStdNs=showStdNs, namespace=namespace) + res = _type.containedTypeDesc.translate(self, namespace=namespace) if type(_type.parent) is Argument: - return 'const {0}<{1} > &'.format( - CppLangTranslator.prepend_std('list', showStdNs), - res - ) + return 'const std::list<{0}> &'.format(res) else: - return '{0}<{1} >'.format( - CppLangTranslator.prepend_std('list', showStdNs), - res - ) + return 'std::list<{0}>'.format(res) - def translate_method_as_prototype(self, method, showStdNs=True, namespace=None): - nsName = self._compute_namespace_name(namespace, method) - - argsString = '' - argStrings = [] - for arg in method.args: - argStrings.append(arg.translate(self, showStdNs=showStdNs, namespace=namespace)) - argsString = ', '.join(argStrings) - - return '{_return} {name}({args}){const}'.format( - _return=method.returnType.translate(self, ), - name=method.name.translate(self.nameTranslator, recursive=True, topAncestor=nsName), - args=argsString, - const=' const' if method.isconst else '' + def translate_method_as_prototype(self, method, hideArguments=False, hideArgNames=False, hideReturnType=False, stripDeclarators=False, namespace=None): + argsAsString = ', '.join([arg.translate(self, hideArgName=hideArgNames, namespace=namespace) for arg in method.args]) if not hideArguments else '' + return '{return_}{name}({args}){const}'.format( + return_=(method.returnType.translate(self, namespace=namespace) + ' ') if not hideReturnType else '', + name=method.name.translate(self.nameTranslator, **Translator._namespace_to_name_translator_params(namespace)), + args=argsAsString, + const=' const' if method.isconst and not stripDeclarators else '' ) - - @staticmethod - def prepend_std(string, prepend): - return 'std::' + string if prepend else string - - def _compute_namespace_name(self, namespace, obj): - nsName = Translator._compute_namespace_name(self, namespace, obj) - if self._get_object_name(obj).to_c() in self.ambigousTypes: - nsName = None - return nsName class JavaLangTranslator(CLikeLangTranslator): @@ -1226,14 +1200,12 @@ class JavaLangTranslator(CLikeLangTranslator): elif jni: return 'jint' else: - nsName = self._compute_namespace_name(namespace, _type) - return _type.desc.name.translate(self.nameTranslator, recursive=True, topAncestor=nsName) + return _type.desc.name.translate(self.nameTranslator, **Translator._namespace_to_name_translator_params(namespace)) def translate_class_type(self, _type, native=False, jni=False, isReturn=False, namespace=None): if jni: return 'jobject' - nsName = self._compute_namespace_name(namespace, _type) - return _type.desc.name.translate(self.nameTranslator, recursive=True, topAncestor=nsName) + return _type.desc.name.translate(self.nameTranslator, **Translator._namespace_to_name_translator_params(namespace)) def translate_list_type(self, _type, native=False, jni=False, isReturn=False, namespace=None): if jni: @@ -1247,11 +1219,11 @@ class JavaLangTranslator(CLikeLangTranslator): ptrtype = _type.containedTypeDesc.translate(self, native=native) ptrtype = '' if type(_type.containedTypeDesc) is ClassType: - ptrtype = _type.containedTypeDesc.translate(self, native=native) + ptrtype = _type.containedTypeDesc.translate(self, native=native, namespace=namespace) elif type(_type.containedTypeDesc) is BaseType: - ptrtype = _type.containedTypeDesc.translate(self, native=native) + ptrtype = _type.containedTypeDesc.translate(self, native=native, namespace=namespace) elif type(_type.containedTypeDesc) is EnumType: - ptrtype = _type.containedTypeDesc.translate(self, native=native) + ptrtype = _type.containedTypeDesc.translate(self, native=native, namespace=namespace) else: if _type.containedTypeDesc: raise Error('translation of bctbx_list_t of ' + _type.containedTypeDesc.name) @@ -1259,8 +1231,19 @@ class JavaLangTranslator(CLikeLangTranslator): raise Error('translation of bctbx_list_t of unknow type !') return ptrtype + '[]' - def translate_argument(self, arg, native=False, jni=False): - return '{0} {1}'.format(arg.type.translate(self, native=native, jni=jni), arg.name.translate(self.nameTranslator)) + def translate_argument(self, arg, native=False, jni=False, hideArgName=False, namespace=None): + res = arg.type.translate(self, native=native, jni=jni, namespace=namespace) + if not hideArgName: + res += (' ' + arg.name.translate(self.nameTranslator)) + return res + + def translate_method_as_prototype(self, method, hideArguments=False, hideArgNames=False, hideReturnType=False, stripDeclarators=False, namespace=None): + return '{public}{returnType}{methodName}({arguments})'.format( + public='public ' if not stripDeclarators else '', + returnType=(method.returnType.translate(self, isReturn=True, namespace=namespace) + ' ') if not hideReturnType else '', + methodName=method.name.translate(self.nameTranslator, **Translator._namespace_to_name_translator_params(namespace)), + arguments=', '.join([arg.translate(self, hideArgName=hideArgNames, namespace=namespace) for arg in method.args]) if not hideArguments else '' + ) class CSharpLangTranslator(CLikeLangTranslator): @@ -1270,7 +1253,7 @@ class CSharpLangTranslator(CLikeLangTranslator): self.falseConstantToken = 'false' self.trueConstantToken = 'true' - def translate_base_type(self, _type, dllImport=True): + def translate_base_type(self, _type, dllImport=True, namespace=None): if _type.name == 'void': if _type.isref: return 'IntPtr' @@ -1319,16 +1302,16 @@ class CSharpLangTranslator(CLikeLangTranslator): return res - def translate_enum_type(self, _type, dllImport=True): + def translate_enum_type(self, _type, dllImport=True, namespace=None): if dllImport and type(_type.parent) is Argument: return 'int' else: - return _type.desc.name.translate(self.nameTranslator) + return _type.desc.name.translate(self.nameTranslator, **Translator._namespace_to_name_translator_params(namespace)) - def translate_class_type(self, _type, dllImport=True): - return "IntPtr" if dllImport else _type.desc.name.translate(self.nameTranslator) + def translate_class_type(self, _type, dllImport=True, namespace=None): + return "IntPtr" if dllImport else _type.desc.name.translate(self.nameTranslator, **Translator._namespace_to_name_translator_params(namespace)) - def translate_list_type(self, _type, dllImport=True): + def translate_list_type(self, _type, dllImport=True, namespace=None): if dllImport: return 'IntPtr' else: @@ -1338,7 +1321,7 @@ class CSharpLangTranslator(CLikeLangTranslator): else: raise TranslationError('translation of bctbx_list_t of basic C types is not supported') elif type(_type.containedTypeDesc) is ClassType: - ptrType = _type.containedTypeDesc.desc.name.translate(self.nameTranslator) + ptrType = _type.containedTypeDesc.desc.name.translate(self.nameTranslator, **Translator._namespace_to_name_translator_params(namespace)) return 'IEnumerable<' + ptrType + '>' else: if _type.containedTypeDesc: @@ -1346,22 +1329,17 @@ class CSharpLangTranslator(CLikeLangTranslator): else: raise TranslationError('translation of bctbx_list_t of unknow type !') - def translate_argument(self, arg, dllImport=True): + def translate_argument(self, arg, dllImport=True, namespace=None): return '{0} {1}'.format( - arg.type.translate(self, dllImport=dllImport), + arg.type.translate(self, dllImport=dllImport, namespace=None), arg.name.translate(self.nameTranslator) ) - def translate_method_as_prototype(self, method): - kargs = { - 'static' : 'static ' if method.type == Method.Type.Class else '', - 'override' : 'override ' if method.name.translate(self.nameTranslator) == 'ToString' else '', - 'returnType' : method.returnType.translate(self, dllImport=False), - 'name' : method.name.translate(self.nameTranslator), - 'args' : '' - } - for arg in method.args: - if kargs['args'] != '': - kargs['args'] += ', ' - kargs['args'] += arg.translate(self, dllImport=False) - return '{static}{override}{returnType} {name}({args})'.format(**kargs) + def translate_method_as_prototype(self, method, hideArguments=False, hideArgNames=False, hideReturnType=False, stripDeclarators=False, namespace=None): + return '{static}{override}{returnType}{name}({args})'.format( + static = 'static ' if method.type == Method.Type.Class and not stripDeclarators else '', + override = 'override ' if method.name.translate(self.nameTranslator) == 'ToString' and not stripDeclarators else '', + returnType = (method.returnType.translate(self, dllImport=False, namespace=namespace) + ' ') if not hideReturnType else '', + name = method.name.translate(self.nameTranslator, **Translator._namespace_to_name_translator_params(namespace)), + args = ', '.join([arg.translate(self, dllImport=False, namespace=namespace) for arg in method.args]) if not hideArguments else '' + ) diff --git a/tools/genapixml.py b/tools/genapixml.py index e7530d412..e3f699cff 100755 --- a/tools/genapixml.py +++ b/tools/genapixml.py @@ -460,6 +460,8 @@ class Project: definition = node.find('./definition').text if definition.startswith('typedef '): definition = definition[8 :] + briefDoc = self.docparser.parse_description(node.find('./briefdescription')) + detailedDoc = self.docparser.parse_description(node.find('./detaileddescription')) if name.endswith('Cb'): pos = definition.find("(*") if pos == -1: @@ -515,9 +517,9 @@ class Project: if deprecatedNode is not None: f.deprecated = True f.briefDescription = ''.join(node.find('./briefdescription').itertext()).strip() - f.briefDoc = self.docparser.parse_description(node.find('./briefdescription')) - f.detailedDoc = self.docparser.parse_description(node.find('./detaileddescription')) + f.briefDoc = briefDoc f.detailedDescription = self.__cleanDescription(node.find('./detaileddescription')) + f.detailedDoc = detailedDoc return f else: pos = definition.rfind(" " + name) @@ -528,9 +530,9 @@ class Project: if deprecatedNode is not None: td.deprecated = True td.briefDescription = ''.join(node.find('./briefdescription').itertext()).strip() - td.briefDoc = self.docparser.parse_description(node.find('./briefdescription')) - td.detailedDoc = self.docparser.parse_description(node.find('./detaileddescription')) + td.briefDoc = briefDoc td.detailedDescription = self.__cleanDescription(node.find('./detaileddescription')) + td.detailedDoc = detailedDoc return td return None diff --git a/tools/metadoc.py b/tools/metadoc.py index 22655adf7..1e4967e08 100644 --- a/tools/metadoc.py +++ b/tools/metadoc.py @@ -138,12 +138,25 @@ class Reference(ParagraphPart): ParagraphPart.__init__(self) self.cname = cname self.relatedObject = None - - def translate(self, docTranslator, **kargs): - return docTranslator.translate_reference(self, **kargs) + + @staticmethod + def make_ref_from_object(cname, obj): + if isinstance(obj, (abstractapi.Enum, abstractapi.Enumerator, abstractapi.Class, abstractapi.Interface)): + ref = ClassReference(cname) + elif isinstance(obj, abstractapi.Method): + ref = FunctionReference(cname) + else: + raise TypeError('cannot create documentation reference from {0}'.format(str(obj))) + ref.relatedObject = obj + return ref class ClassReference(Reference): + def translate(self, docTranslator, **kargs): + if self.relatedObject is None: + raise ReferenceTranslationError(self.cname) + return docTranslator.translate_class_reference(self, **kargs) + def resolve(self, api): try: self.relatedObject = api.classesIndex[self.cname] @@ -152,6 +165,11 @@ class ClassReference(Reference): class FunctionReference(Reference): + def translate(self, docTranslator, **kargs): + if self.relatedObject is None: + raise ReferenceTranslationError(self.cname) + return docTranslator.translate_function_reference(self, **kargs) + def resolve(self, api): try: self.relatedObject = api.methodsIndex[self.cname] @@ -385,6 +403,7 @@ class ReferenceTranslationError(TranslationError): class Translator: def __init__(self, langCode): + self.langCode = langCode self.textWidth = 80 self.nameTranslator = metaname.Translator.get(langCode) self.langTranslator = abstractapi.Translator.get(langCode) @@ -417,12 +436,13 @@ class Translator: else: if namespace is None: description = ref.find_root() - namespaceObj = description.relatedObject.find_first_ancestor_by_type(abstractapi.Namespace, abstractapi.Class) - namespace = namespaceObj.name - if namespace.is_prefix_of(ref.relatedObject.name): - commonName = namespace + namespace = description.relatedObject.find_first_ancestor_by_type(abstractapi.Namespace, abstractapi.Class) + if namespace is abstractapi.GlobalNs: + commonName = None + elif namespace.name.is_prefix_of(ref.relatedObject.name): + commonName = namespace.name else: - commonName = metaname.Name.find_common_parent(ref.relatedObject.name, namespace) + commonName = metaname.Name.find_common_parent(ref.relatedObject.name, namespace.name) return ref.relatedObject.name.translate(self.nameTranslator, recursive=True, topAncestor=commonName) def translate_keyword(self, keyword): @@ -495,13 +515,16 @@ class DoxygenTranslator(Translator): def _tag_as_brief(self, lines): if len(lines) > 0: lines[0] = '@brief ' + lines[0] - - def translate_reference(self, ref): - refStr = Translator.translate_reference(self, ref) + + def translate_class_reference(self, ref, **kargs): if isinstance(ref.relatedObject, (abstractapi.Class, abstractapi.Enum)): - return '#' + refStr - elif isinstance(ref.relatedObject, abstractapi.Method): - return refStr + '()' + return '#' + Translator.translate_reference(self, ref) + else: + raise ReferenceTranslationError(ref.cname) + + def translate_function_reference(self, ref, **kargs): + if isinstance(ref.relatedObject, abstractapi.Method): + return Translator.translate_reference(self, ref) + '()' else: raise ReferenceTranslationError(ref.cname) @@ -533,16 +556,17 @@ class SphinxTranslator(Translator): def __init__(self, langCode): Translator.__init__(self, langCode) if langCode == 'C': - self.domain = 'c' + self.domain = 'cpp' self.classDeclarator = 'type' + self.interfaceDeclarator = self.classDeclarator self.methodDeclarator = 'function' - self.enumDeclarator = 'type' - self.enumeratorDeclarator = 'var' - self.enumeratorReferencer = 'data' + self.enumDeclarator = 'enum' + self.enumeratorDeclarator = 'enumerator' self.methodReferencer = 'func' elif langCode == 'Cpp': self.domain = 'cpp' self.classDeclarator = 'class' + self.interfaceDeclarator = self.classDeclarator self.methodDeclarator = 'function' self.enumDeclarator = 'enum' self.enumeratorDeclarator = 'enumerator' @@ -551,14 +575,25 @@ class SphinxTranslator(Translator): elif langCode == 'CSharp': self.domain = 'csharp' self.classDeclarator = 'class' + self.interfaceDeclarator = self.classDeclarator self.methodDeclarator = 'method' self.enumDeclarator = 'enum' self.enumeratorDeclarator = 'value' self.namespaceDeclarator = 'namespace' self.classReferencer = 'type' + self.interfaceReferencer = self.classReferencer self.enumReferencer = 'type' self.enumeratorReferencer = 'enum' self.methodReferencer = 'meth' + elif langCode == 'Java': + self.domain = 'java' + self.classDeclarator = 'type' + self.interfaceDeclarator = self.classDeclarator + self.methodDeclarator = 'method' + self.enumDeclarator = 'type' + self.enumeratorDeclarator = 'field' + self.namespaceDeclarator = 'package' + self.methodReferencer = 'meth' else: raise ValueError('invalid language code: {0}'.format(langCode)) @@ -580,18 +615,30 @@ class SphinxTranslator(Translator): return self.get_declarator(typeName) except AttributeError: raise ValueError("'{0}' referencer type not supported".format(typeName)) - - def translate_reference(self, ref, label=None, namespace=None): - strRef = Translator.translate_reference(self, ref, absName=True) - kargs = { - 'tag' : self._sphinx_ref_tag(ref), - 'ref' : strRef, - } - kargs['label'] = label if label is not None else Translator.translate_reference(self, ref, namespace=namespace) - if isinstance(ref, FunctionReference): - kargs['label'] += '()' - - return ':{tag}:`{label} <{ref}>`'.format(**kargs) + + def translate_class_reference(self, ref, label=None, namespace=None): + return ':{tag}:`{label} <{ref}>`'.format( + tag=self._sphinx_ref_tag(ref), + label=label if label is not None else Translator.translate_reference(self, ref, namespace=namespace), + ref=Translator.translate_reference(self, ref, absName=True) + ) + + def translate_function_reference(self, ref, label=None, useNamespace=True, namespace=None): + if self.domain == 'csharp': + refStr = ref.relatedObject.name.translate(self.nameTranslator, **abstractapi.Translator._namespace_to_name_translator_params(namespace)) + else: + refStr = ref.relatedObject.translate_as_prototype(self.langTranslator, + hideArguments=self.domain != 'java', + hideArgNames=self.domain == 'java', + hideReturnType=True, + stripDeclarators=True, + namespace=namespace + ) + return ':{tag}:`{label} <{ref}>`'.format( + tag=self._sphinx_ref_tag(ref), + label=label if label is not None else '{0}()'.format(Translator.translate_reference(self, ref, namespace=namespace)), + ref=refStr + ) def translate_keyword(self, keyword): translatedKeyword = Translator.translate_keyword(self, keyword) @@ -641,9 +688,11 @@ class SandCastleTranslator(Translator): if len(lines) > 0: lines.insert(0, '') lines.append('') - - def translate_reference(self, ref): + + def translate_function_reference(self, ref): + refStr = Translator.translate_reference(self, ref, absName=True) + return ''.format(refStr) + + def translate_class_reference(self, ref): refStr = Translator.translate_reference(self, ref, absName=True) - if isinstance(ref, FunctionReference): - refStr += '()' return ''.format(refStr) diff --git a/tools/python/apixml2python.py b/tools/python/apixml2python.py index 2c27fb386..c0d57b85e 100755 --- a/tools/python/apixml2python.py +++ b/tools/python/apixml2python.py @@ -29,7 +29,9 @@ from apixml2python.linphone import LinphoneModule, HandWrittenClassMethod, HandW blacklisted_classes = [ 'LinphoneIntRange', 'LinphoneTunnel', - 'LinphoneTunnelConfig' + 'LinphoneTunnelConfig', + 'LinphoneLoggingService', + 'LinphoneLoggingServiceCbs' ] blacklisted_events = [ 'LinphoneChatMessageStateChangedCb', # not respecting naming convention @@ -73,6 +75,7 @@ blacklisted_functions = [ 'linphone_proxy_config_set_privacy', # missing LinphonePrivacyMask 'linphone_tunnel_get_http_proxy', # to be handwritten because of double pointer indirection 'linphone_vcard_get_belcard', # specific to C++ + '' ] hand_written_functions = [ HandWrittenClassMethod('Buffer', 'new_from_data', 'linphone_buffer_new_from_data', "Create a new LinphoneBuffer object from existing data.\n\n:param data: The initial data to store in the LinphoneBuffer.\n:type data: ByteArray\n:returns: A new LinphoneBuffer object.\n:rtype: linphone.Buffer"), diff --git a/tools/python/apixml2python/linphone_module.mustache b/tools/python/apixml2python/linphone_module.mustache index 06c5b25ee..c0ed8f6fa 100644 --- a/tools/python/apixml2python/linphone_module.mustache +++ b/tools/python/apixml2python/linphone_module.mustache @@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include #include #include +#include #include #include diff --git a/wrappers/cpp/genwrapper.py b/wrappers/cpp/genwrapper.py index 5d34caf13..c67edb99a 100755 --- a/wrappers/cpp/genwrapper.py +++ b/wrappers/cpp/genwrapper.py @@ -104,7 +104,7 @@ class CppTranslator(object): classDict['listenerClassName'] = _class.listenerInterface.name.translate(self.nameTranslator) classDict['cListenerName'] = _class.listenerInterface.name.to_c() classDict['cppListenerName'] = _class.listenerInterface.name.translate(self.nameTranslator) - for method in _class.listenerInterface.methods: + for method in _class.listenerInterface.instanceMethods: classDict['wrapperCbs'].append(self._generate_wrapper_callback(_class, method)) if ismonolistenable: @@ -173,7 +173,7 @@ class CppTranslator(object): 'isListener' : True, 'methods' : [] } - for method in interface.methods: + for method in interface.instanceMethods: methodDict = self.translate_method(method, genImpl=False) intDict['methods'].append(methodDict) @@ -361,52 +361,41 @@ class ClassHeader(object): self.filename = '{0}.hh'.format(_class.name.to_snake_case()) self.priorDeclarations = [] self.private_type = _class.name.to_camel_case(fullName=True) - self.includes = {'internal': [], 'external': []} - includes = self.needed_includes(_class) - - for include in includes['external']: - self.includes['external'].append({'name': include}) - - for include in includes['internal']: - self.includes['internal'].append({'name': include}) + self._populate_needed_includes(_class) - def needed_includes(self, _class): - includes = {'internal': [], 'external': []} - + def _populate_needed_includes(self, _class): if type(_class) is AbsApi.Class: for _property in _class.properties: if _property.setter is not None: - self._needed_includes_from_method(_property.setter, includes) + self._populate_needed_includes_from_method(_property.setter) if _property.getter is not None: - self._needed_includes_from_method(_property.getter, includes) + self._populate_needed_includes_from_method(_property.getter) if type(_class) is AbsApi.Class: methods = _class.classMethods + _class.instanceMethods else: - methods = _class.methods + methods = _class.instanceMethods for method in methods: - self._needed_includes_from_type(method.returnType, includes) + self._populate_needed_includes_from_type(method.returnType) for arg in method.args: - self._needed_includes_from_type(arg.type, includes) + self._populate_needed_includes_from_type(arg.type) if isinstance(_class, AbsApi.Class) and _class.listenerInterface is not None: decl = 'class ' + _class.listenerInterface.name.translate(metaname.Translator.get('Cpp')) self._add_prior_declaration(decl) currentClassInclude = _class.name.to_snake_case() - if currentClassInclude in includes['internal']: - includes['internal'].remove(currentClassInclude) - - return includes + if currentClassInclude in self.includes['internal']: + self.includes['internal'].remove(currentClassInclude) - def _needed_includes_from_method(self, method, includes): - self._needed_includes_from_type(method.returnType, includes) + def _populate_needed_includes_from_method(self, method): + self._populate_needed_includes_from_type(method.returnType) for arg in method.args: - self._needed_includes_from_type(arg.type, includes) + self._populate_needed_includes_from_type(arg.type) - def _needed_includes_from_type(self, type_, includes): + def _populate_needed_includes_from_type(self, type_): translator = metaname.Translator.get('Cpp') if isinstance(type_, AbsApi.ClassType): class_ = type_.desc @@ -415,7 +404,7 @@ class ClassHeader(object): self._add_prior_declaration(decl) else: rootClass = class_.find_first_ancestor_by_type(AbsApi.Namespace, priorAncestor=True) - self._add_include(includes, 'internal', rootClass.name.to_snake_case()) + self._add_include('internal', rootClass.name.to_snake_case()) elif isinstance(type_, AbsApi.EnumType): enum = type_.desc if enum.parent == self.rootNs: @@ -423,19 +412,19 @@ class ClassHeader(object): else: rootClass = enum.find_first_ancestor_by_type(AbsApi.Namespace, priorAncestor=True) headerFile = rootClass.name.to_snake_case() - self._add_include(includes, 'internal', headerFile) + self._add_include('internal', headerFile) elif isinstance(type_, AbsApi.BaseType): if type_.name == 'integer' and isinstance(type_.size, int): - self._add_include(includes, 'external', 'cstdint') + self._add_include('external', 'cstdint') elif type_.name == 'string': - self._add_include(includes, 'external', 'string') + self._add_include('external', 'string') elif isinstance(type_, AbsApi.ListType): - self._add_include(includes, 'external', 'list') - self._needed_includes_from_type(type_.containedTypeDesc, includes) + self._add_include('external', 'list') + self._populate_needed_includes_from_type(type_.containedTypeDesc) - def _add_include(self, includes, location, name): - if not name in includes[location]: - includes[location].append(name) + def _add_include(self, location, name): + if next((x for x in self.includes[location] if x['name']==name), None) is None: + self.includes[location].append({'name': name}) def _add_prior_declaration(self, decl): if next((x for x in self.priorDeclarations if x['declaration']==decl), None) is None: diff --git a/wrappers/csharp/genwrapper.py b/wrappers/csharp/genwrapper.py index de474eea9..83fd39ed4 100644 --- a/wrappers/csharp/genwrapper.py +++ b/wrappers/csharp/genwrapper.py @@ -491,13 +491,7 @@ if __name__ == '__main__': parser = AbsApi.CParser(project) 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'] + 'linphone_core_get_current_vtable'] parser.classBl += 'LinphoneCoreVTable' parser.methodBl.remove('getCurrentCallbacks') parser.parse_all() diff --git a/wrappers/csharp/wrapper_impl.mustache b/wrappers/csharp/wrapper_impl.mustache index 8837b4475..91da3f494 100644 --- a/wrappers/csharp/wrapper_impl.mustache +++ b/wrappers/csharp/wrapper_impl.mustache @@ -183,7 +183,11 @@ namespace Linphone obj.nativePtr = ptr; obj.handle = GCHandle.Alloc(obj, GCHandleType.WeakTrackResurrection); objPtr = GCHandle.ToIntPtr(obj.handle); +#if WINDOWS_UWP belle_sip_object_data_set(ptr, "cs_obj", objPtr, IntPtr.Zero); +#else + belle_sip_object_data_set(ptr, "cs_obj", objPtr, null); +#endif return obj; } @@ -377,13 +381,9 @@ namespace Linphone } {{/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 + public string NativeVideoWindowIdString { get { @@ -396,13 +396,9 @@ namespace Linphone } {{/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 + public string NativeVideoWindowIdString { get { @@ -414,13 +410,8 @@ namespace Linphone } } - [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 + public string NativePreviewWindowIdString { get { diff --git a/wrappers/java/classes/tools/AndroidPlatformHelper.java b/wrappers/java/classes/tools/AndroidPlatformHelper.java index b90a3cea0..34ba1445a 100644 --- a/wrappers/java/classes/tools/AndroidPlatformHelper.java +++ b/wrappers/java/classes/tools/AndroidPlatformHelper.java @@ -177,65 +177,60 @@ public class AndroidPlatformHelper { if (resId == 0) { Log.d("App doesn't seem to embed resource " + name + "in it's res/raw/ directory, use linphone's instead"); resId = mResources.getIdentifier(name, "raw", "org.linphone"); + if (resId == 0) { + Log.e("App doesn't seem to embed resource " + name + "in it's res/raw/ directory, please add it"); + } } return resId; } private void copyAssetsFromPackage() { try { - copyIfNotExist(getResourceIdentifierFromName("cpim_grammar"), mGrammarCpimFile); - } - catch (Exception e) { + copyEvenIfExists(getResourceIdentifierFromName("cpim_grammar"), mGrammarCpimFile); + } catch (Exception e) { Log.e(e, "AndroidPlatformHelper: Cannot copy \"cpim_grammar\" from package."); } try { - copyIfNotExist(getResourceIdentifierFromName("vcard_grammar"), mGrammarVcardFile); - } - catch (Exception e) { + copyEvenIfExists(getResourceIdentifierFromName("vcard_grammar"), mGrammarVcardFile); + } catch (Exception e) { Log.e(e, "AndroidPlatformHelper: Cannot copy \"vcard_grammar\" from package."); } try { - copyIfNotExist(getResourceIdentifierFromName("notes_of_the_optimistic"), mRingSoundFile); - } - catch (Exception e) { + copyEvenIfExists(getResourceIdentifierFromName("notes_of_the_optimistic"), mRingSoundFile); + } catch (Exception e) { Log.e(e, "AndroidPlatformHelper: Cannot copy \"notes_of_the_optimistic\" from package."); } try { - copyIfNotExist(getResourceIdentifierFromName("ringback"), mRingbackSoundFile); - }catch (Exception e) { + copyEvenIfExists(getResourceIdentifierFromName("ringback"), mRingbackSoundFile); + } catch (Exception e) { Log.e(e, "AndroidPlatformHelper: Cannot copy \"ringback\" from package."); } try { - copyIfNotExist(getResourceIdentifierFromName("hold"), mPauseSoundFile); - } - catch (Exception e) { + copyEvenIfExists(getResourceIdentifierFromName("hold"), mPauseSoundFile); + } catch (Exception e) { Log.e(e, "AndroidPlatformHelper: Cannot copy \"hold\" from package."); } try { - copyIfNotExist(getResourceIdentifierFromName("incoming_chat"), mErrorToneFile); - } - catch (Exception e) { + copyEvenIfExists(getResourceIdentifierFromName("incoming_chat"), mErrorToneFile); + } catch (Exception e) { Log.e(e, "AndroidPlatformHelper: Cannot copy \"incoming_chat\" from package."); } try { - copyIfNotExist(getResourceIdentifierFromName("rootca"), mLinphoneRootCaFile); - } - catch (Exception e) { + copyEvenIfExists(getResourceIdentifierFromName("rootca"), mLinphoneRootCaFile); + } catch (Exception e) { Log.e(e, "AndroidPlatformHelper: Cannot copy \"rootca\" from package."); } } - public void copyIfNotExist(int ressourceId, String target) throws IOException { + public void copyEvenIfExists(int ressourceId, String target) throws IOException { File lFileToCopy = new File(target); - if (!lFileToCopy.exists()) { - copyFromPackage(ressourceId,lFileToCopy.getName()); - } + copyFromPackage(ressourceId, lFileToCopy.getName()); } public void copyFromPackage(int ressourceId, String target) throws IOException{ diff --git a/wrappers/java/genwrapper.py b/wrappers/java/genwrapper.py index 82480d18b..1572e2381 100755 --- a/wrappers/java/genwrapper.py +++ b/wrappers/java/genwrapper.py @@ -161,12 +161,12 @@ class JavaTranslator(object): properties.append(self.translate_method(_property.setter, _hasCoreAccessor)) return properties - def translate_jni_property(self, className, _property): + def translate_jni_property(self, class_, _property): properties = [] if _property.getter is not None: - properties.append(self.translate_jni_method(className, _property.getter)) + properties.append(self.translate_jni_method(class_, _property.getter)) if _property.setter is not None: - properties.append(self.translate_jni_method(className, _property.setter)) + properties.append(self.translate_jni_method(class_, _property.setter)) return properties def generate_listener(self, name, _class): @@ -183,7 +183,7 @@ class JavaTranslator(object): methodDict['params'] = _class.name.to_camel_case() + 'Listener listener' methodDict['native_params'] = 'long nativePtr, ' + _class.name.to_camel_case() + 'Listener listener' methodDict['static_native_params'] = '' - methodDict['native_params_impl'] = ', listener' + methodDict['native_params_impl'] = 'nativePtr, listener' methodDict['deprecated'] = False methodDict['doc'] = None @@ -202,8 +202,10 @@ class JavaTranslator(object): def translate_method(self, _method, _hasCoreAccessor=False): methodDict = {} - methodDict['return'] = _method.returnType.translate(self.langTranslator, isReturn=True) - methodDict['return_native'] = _method.returnType.translate(self.langTranslator, native=True, isReturn=True) + namespace = _method.find_first_ancestor_by_type(AbsApi.Namespace) + + methodDict['return'] = _method.returnType.translate(self.langTranslator, isReturn=True, namespace=namespace) + methodDict['return_native'] = _method.returnType.translate(self.langTranslator, native=True, isReturn=True, namespace=namespace) methodDict['return_keyword'] = '' if methodDict['return'] == 'void' else 'return ' methodDict['hasReturn'] = not methodDict['return'] == 'void' @@ -217,57 +219,50 @@ class JavaTranslator(object): methodDict['enumCast'] = type(_method.returnType) is AbsApi.EnumType methodDict['classCast'] = type(_method.returnType) is AbsApi.ClassType - methodDict['params'] = '' - methodDict['native_params'] = 'long nativePtr' - methodDict['static_native_params'] = '' - methodDict['native_params_impl'] = '' - for arg in _method.args: - if arg is not _method.args[0]: - methodDict['params'] += ', ' - methodDict['static_native_params'] += ', ' - methodDict['native_params'] += ', ' - methodDict['native_params_impl'] += ', ' - - methodDict['params'] += arg.translate(self.langTranslator) - methodDict['native_params'] += arg.translate(self.langTranslator, native=True) - methodDict['static_native_params'] += arg.translate(self.langTranslator, native=True) - if type(arg.type) is AbsApi.EnumType: - methodDict['native_params_impl'] += arg.name.translate(self.nameTranslator) + '.toInt()' - else: - methodDict['native_params_impl'] += arg.name.translate(self.nameTranslator) + methodDict['params'] = ', '.join([arg.translate(self.langTranslator, namespace=namespace) for arg in _method.args]) + methodDict['native_params'] = ', '.join(['long nativePtr'] + [arg.translate(self.langTranslator, native=True, namespace=namespace) for arg in _method.args]) + methodDict['static_native_params'] = ', '.join([arg.translate(self.langTranslator, native=True, namespace=namespace) for arg in _method.args]) + methodDict['native_params_impl'] = ', '.join( + ['nativePtr'] + [arg.name.translate(self.nameTranslator) + ('.toInt()' if type(arg.type) is AbsApi.EnumType else '') for arg in _method.args]) methodDict['deprecated'] = _method.deprecated methodDict['doc'] = _method.briefDescription.translate(self.docTranslator) if _method.briefDescription is not None else None return methodDict - def translate_jni_method(self, className, _method, static=False): + def translate_jni_method(self, class_, _method, static=False): jni_blacklist = ['linphone_call_set_native_video_window_id', 'linphone_core_set_native_preview_window_id', 'linphone_core_set_native_video_window_id'] + namespace = class_.find_first_ancestor_by_type(AbsApi.Namespace) + className = class_.name.translate(self.nameTranslator) + methodDict = {'notEmpty': True} - methodDict['classCName'] = 'Linphone' + className.to_camel_case() - methodDict['className'] = className.to_camel_case() - methodDict['classImplName'] = className.to_camel_case() + 'Impl' - methodDict['isLinphoneFactory'] = className.to_camel_case() == 'Factory' + methodDict['classCName'] = class_.name.to_c() + methodDict['className'] = className + methodDict['classImplName'] = className + 'Impl' + methodDict['isLinphoneFactory'] = (className == 'Factory') methodDict['jniPath'] = self.jni_path - methodDict['return'] = _method.returnType.translate(self.langTranslator, jni=True, isReturn=True) + methodDict['return'] = _method.returnType.translate(self.langTranslator, jni=True, isReturn=True, namespace=namespace) methodDict['hasListReturn'] = methodDict['return'] == 'jobjectArray' methodDict['hasByteArrayReturn'] = methodDict['return'] == 'jbyteArray' methodDict['hasReturn'] = not methodDict['return'] == 'void' and not methodDict['hasListReturn'] and not methodDict['hasByteArrayReturn'] methodDict['hasStringReturn'] = methodDict['return'] == 'jstring' methodDict['hasNormalReturn'] = not methodDict['hasListReturn'] and not methodDict['hasStringReturn'] and not methodDict['hasByteArrayReturn'] - methodDict['name'] = 'Java_' + self.jni_package + className.to_camel_case() + 'Impl_' + _method.name.to_camel_case(lower=True) + methodDict['name'] = 'Java_' + self.jni_package + className + 'Impl_' + _method.name.translate(self.nameTranslator) methodDict['notStatic'] = not static - methodDict['c_name'] = 'linphone_' + className.to_snake_case() + "_" + _method.name.to_snake_case() - if _method.name.to_snake_case() == 'create_core': - methodDict['c_name'] = 'linphone_' + className.to_snake_case() + "_" + 'create_core_3' - elif _method.name.to_snake_case() == 'create_core_with_config': - methodDict['c_name'] = 'linphone_' + className.to_snake_case() + "_" + 'create_core_with_config_3' + + if _method.name.to_c() == 'linphone_factory_create_core': + methodDict['c_name'] = 'linphone_factory_create_core_3' + elif _method.name.to_c() == 'linphone_factory_create_core_with_config': + methodDict['c_name'] = 'linphone_factory_create_core_with_config_3' + else: + methodDict['c_name'] = _method.name.to_c() + methodDict['returnObject'] = methodDict['hasReturn'] and type(_method.returnType) is AbsApi.ClassType - methodDict['returnClassName'] = _method.returnType.translate(self.langTranslator) + methodDict['returnClassName'] = _method.returnType.translate(self.langTranslator, namespace=namespace) methodDict['isRealObjectArray'] = False methodDict['isStringObjectArray'] = False methodDict['c_type_return'] = _method.returnType.translate(self.clangTranslator) @@ -303,7 +298,7 @@ class JavaTranslator(object): else: methodDict['params_impl'] += ', ' - methodDict['params'] += arg.translate(self.langTranslator, jni=True) + methodDict['params'] += arg.translate(self.langTranslator, jni=True, namespace=namespace) argname = arg.name.translate(self.nameTranslator) if type(arg.type) is AbsApi.ClassType: @@ -353,14 +348,14 @@ class JavaTranslator(object): for _property in _class.properties: try: classDict['methods'] += self.translate_property(_property, hasCoreAccessor) - classDict['jniMethods'] += self.translate_jni_property(_class.name, _property) + classDict['jniMethods'] += self.translate_jni_property(_class, _property) except AbsApi.Error as e: logging.error('error while translating {0} property: {1}'.format(_property.name.to_snake_case(), e.args[0])) for method in _class.instanceMethods: try: methodDict = self.translate_method(method, hasCoreAccessor) - jniMethodDict = self.translate_jni_method(_class.name, method) + jniMethodDict = self.translate_jni_method(_class, method) classDict['methods'].append(methodDict) classDict['jniMethods'].append(jniMethodDict) except AbsApi.Error as e: @@ -369,7 +364,7 @@ class JavaTranslator(object): for method in _class.classMethods: try: methodDict = self.translate_method(method, hasCoreAccessor) - jniMethodDict = self.translate_jni_method(_class.name, method, True) + jniMethodDict = self.translate_jni_method(_class, method, True) classDict['methods'].append(methodDict) classDict['jniMethods'].append(jniMethodDict) except AbsApi.Error as e: @@ -470,7 +465,7 @@ class JavaTranslator(object): interfaceDict['doc'] = _class.briefDescription.translate(self.docTranslator) - for method in _class.methods: + for method in _class.instanceMethods: interfaceDict['methods'].append(self.translate_method(method)) interfaceDict['jniMethods'].append(self.translate_jni_interface(_class.listenedClass, _class.name, method)) @@ -533,7 +528,7 @@ class JniInterface(object): self.cPrefix = javaClass.cPrefix self.callbacks = [] listener = apiClass.listenerInterface - for method in listener.methods: + for method in listener.instanceMethods: self.callbacks.append({ 'callbackName': '_{0}_cb'.format(method.name.to_snake_case(fullName=True)), 'callback': method.name.to_snake_case()[3:], # Remove the on_ @@ -659,6 +654,8 @@ class Proguard(object): def __init__(self, package): self.package = package self.classes = [] + self.enums = [] + self.listeners = [] def add_class(self, javaClass): obj = { @@ -668,6 +665,27 @@ class Proguard(object): } self.classes.append(obj) + for javaEnum in javaClass.enums: + enumObj = { + 'package': self.package, + 'className': javaClass.className + "$" + javaEnum.className, + } + self.enums.append(enumObj) + + def add_enum(self, javaEnum): + obj = { + 'package': self.package, + 'className': javaEnum.className, + } + self.enums.append(obj) + + def add_interface(self, javaInterface): + obj = { + 'package': self.package, + 'className': javaInterface.className, + } + self.listeners.append(obj) + ########################################################################## class GenWrapper(object): @@ -715,8 +733,10 @@ class GenWrapper(object): for name, value in self.enums.items(): self.render(value, self.javadir + '/' + value.filename) + self.proguard.add_enum(value) for name, value in self.interfaces.items(): self.render(value, self.javadir + '/' + value.filename) + self.proguard.add_interface(value) for name, value in self.classes.items(): self.render(value, self.javadir + '/' + value.filename) self.jni.add_object(value) diff --git a/wrappers/java/java_class.mustache b/wrappers/java/java_class.mustache index b827684ee..4f62209f2 100644 --- a/wrappers/java/java_class.mustache +++ b/wrappers/java/java_class.mustache @@ -95,6 +95,11 @@ public {{#isLinphoneFactory}}abstract class{{/isLinphoneFactory}}{{#isNotLinphon abstract public OpenH264DownloadHelper createOpenH264DownloadHelper(Context context); + /** + * Gets the LoggingService singleton + */ + abstract public LoggingService getLoggingService(); + abstract public void setDebugMode(boolean enable, String tag); abstract public Core getCore(long ptr); @@ -176,6 +181,12 @@ class {{classImplName}} {{#isLinphoneFactory}}extends{{/isLinphoneFactory}}{{#is return getCore(nativePtr, ptr); } + @Override + public LoggingService getLoggingService() { + LoggingService l = new LoggingServiceImpl(0); + return l.get(); + } + @Override public native void setDebugMode(boolean enable, String tag); {{/isLinphoneFactory}} @@ -185,7 +196,7 @@ class {{classImplName}} {{#isLinphoneFactory}}extends{{/isLinphoneFactory}}{{#is @Override synchronized public {{return}} {{name}}({{params}}) {{#exception}}throws CoreException{{/exception}} { {{#hasCoreAccessor}}{{#isNotGetCore}}synchronized(core) { {{/isNotGetCore}}{{/hasCoreAccessor}} - {{#exception}}int exceptionResult = {{/exception}}{{return_keyword}}{{#enumCast}}{{return}}.fromInt({{/enumCast}}{{#classCast}}({{return}}){{/classCast}}{{name}}(nativePtr{{native_params_impl}}){{#enumCast}}){{/enumCast}};{{#exception}} + {{#exception}}int exceptionResult = {{/exception}}{{return_keyword}}{{#enumCast}}{{return}}.fromInt({{/enumCast}}{{#classCast}}({{return}}){{/classCast}}{{name}}({{native_params_impl}}){{#enumCast}}){{/enumCast}};{{#exception}} if (exceptionResult != 0) throw new CoreException("{{name}} returned value " + exceptionResult);{{/exception}}{{#hasCoreAccessor}}{{#isNotGetCore}} }{{/isNotGetCore}}{{/hasCoreAccessor}} } diff --git a/wrappers/java/proguard.mustache b/wrappers/java/proguard.mustache index 4ba8b9d44..65dd2ed12 100644 --- a/wrappers/java/proguard.mustache +++ b/wrappers/java/proguard.mustache @@ -1,12 +1,22 @@ # Don't warn stuff that we are not "proguarding", warnings would make the build fail. -dontwarn org.linphone.** -# The following intefaces are referenced from JNI +# The following interfaces and classes are referenced from JNI {{#classes}} -keep interface {{package}}.{{className}} {*;} -keep class {{package}}.{{classImplName}} {*;} {{/classes}} +# The following enums are referenced from JNI +{{#enums}} +-keep class {{package}}.{{className}} {*;} +{{/enums}} + +# The following listeners are referenced from JNI +{{#listeners}} +-keep class {{package}}.{{className}} {*;} +{{/listeners}} + # Liblinphone tools -keep class org.linphone.core.tools.* {*;}