mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-05-07 05:53:06 +00:00
Merge branch 'dev_vcard'
This commit is contained in:
commit
6654e66e92
55 changed files with 13273 additions and 286 deletions
|
|
@ -58,6 +58,8 @@ cmake_dependent_option(ENABLE_ASSISTANT "Turn on assistant compiling." YES "ENAB
|
|||
option(ENABLE_DEBUG_LOGS "Turn on or off debug level logs." NO)
|
||||
option(ENABLE_NLS "Build with internationalisation support" YES)
|
||||
option(ENABLE_CALL_LOGS_STORAGE "Turn on compilation of call logs storage." YES)
|
||||
option(ENABLE_FRIENDS_SQL_STORAGE "Turn on compilation of friends sql storage." YES)
|
||||
option(ENABLE_VCARD "Turn on compilation of vcard4 support." YES)
|
||||
|
||||
|
||||
macro(apply_compile_flags SOURCE_FILES)
|
||||
|
|
@ -159,9 +161,25 @@ endif()
|
|||
if(ENABLE_CALL_LOGS_STORAGE)
|
||||
find_package(Sqlite3 REQUIRED)
|
||||
endif()
|
||||
if (ENABLE_FRIENDS_SQL_STORAGE)
|
||||
find_package(Sqlite3 REQUIRED)
|
||||
endif()
|
||||
if(ENABLE_LIME)
|
||||
set(HAVE_LIME 1)
|
||||
endif()
|
||||
if (ENABLE_VCARD)
|
||||
if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS)
|
||||
include("${EP_belcard_CONFIG_DIR}/BelcardConfig.cmake")
|
||||
else()
|
||||
find_package(Belcard)
|
||||
endif()
|
||||
if(NOT BELCARD_FOUND)
|
||||
message(WARNING "Could not find the belcard library!")
|
||||
set(ENABLE_VCARD OFF CACHE BOOL "Enable vcard support." FORCE)
|
||||
else()
|
||||
add_definitions(-DVCARD_ENABLED)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
include(CheckIncludeFiles)
|
||||
|
|
@ -182,6 +200,9 @@ include_directories(
|
|||
if(ENABLE_TUNNEL)
|
||||
include_directories(${TUNNEL_INCLUDE_DIRS})
|
||||
endif()
|
||||
if (ENABLE_VCARD)
|
||||
include_directories(${BELCARD_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
include_directories(${XML2_INCLUDE_DIRS})
|
||||
|
||||
|
|
@ -197,6 +218,9 @@ if(SQLITE3_FOUND)
|
|||
if(ENABLE_CALL_LOGS_STORAGE)
|
||||
add_definitions("-DCALL_LOGS_STORAGE_ENABLED")
|
||||
endif()
|
||||
if(ENABLE_FRIENDS_SQL_STORAGE)
|
||||
add_definitions("-DFRIENDS_SQL_STORAGE_ENABLED")
|
||||
endif()
|
||||
endif()
|
||||
if(INTL_FOUND)
|
||||
set(HAVE_INTL 1)
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ LOCAL_SRC_FILES := \
|
|||
callbacks.c \
|
||||
call_log.c \
|
||||
call_params.c \
|
||||
carddav.c \
|
||||
chat.c \
|
||||
chat_file_transfer.c \
|
||||
conference.cc \
|
||||
|
|
@ -80,7 +81,6 @@ LOCAL_SRC_FILES := \
|
|||
vtables.c \
|
||||
ringtoneplayer.c
|
||||
|
||||
|
||||
ifndef LIBLINPHONE_VERSION
|
||||
LIBLINPHONE_VERSION = "Devel"
|
||||
endif
|
||||
|
|
@ -129,7 +129,7 @@ LOCAL_C_INCLUDES += \
|
|||
$(LOCAL_PATH)/../../../gen \
|
||||
$(LOCAL_PATH)/../../externals/libxml2/include \
|
||||
$(LOCAL_PATH)/../../externals/build/libxml2 \
|
||||
$(LOCAL_PATH)/../../externals/polarssl/include
|
||||
$(LOCAL_PATH)/../../externals/polarssl/include \
|
||||
|
||||
LOCAL_LDLIBS += -llog -ldl -lz
|
||||
|
||||
|
|
@ -262,6 +262,16 @@ ifeq ($(BUILD_SRTP), 1)
|
|||
LOCAL_C_INCLUDES += $(SRTP_C_INCLUDE)
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_VCARD),1)
|
||||
LOCAL_C_INCLUDES += $(VCARD_C_INCLUDE)
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_ILBC), 1)
|
||||
ifneq ($(TARGET_ARCH_ABI),armeabi)
|
||||
LOCAL_CFLAGS += -DHAVE_ILBC=1
|
||||
LOCAL_STATIC_LIBRARIES += libmsilbc
|
||||
endif
|
||||
endif
|
||||
|
||||
LOCAL_C_INCLUDES += $(LIBLINPHONE_EXTENDED_C_INCLUDES)
|
||||
LOCAL_WHOLE_STATIC_LIBRARIES += $(LIBLINPHONE_EXTENDED_STATIC_LIBS)
|
||||
|
|
@ -277,8 +287,16 @@ ifeq ($(BUILD_SRTP),1)
|
|||
LOCAL_STATIC_LIBRARIES += libsrtp
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_VCARD),1)
|
||||
LOCAL_CFLAGS += -DVCARD_ENABLED
|
||||
LOCAL_SRC_FILES += vcard.cc
|
||||
LOCAL_STATIC_LIBRARIES += libbelr libbelcard
|
||||
else
|
||||
LOCAL_SRC_FILES += vcard_stubs.c
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_SQLITE),1)
|
||||
LOCAL_CFLAGS += -DMSG_STORAGE_ENABLED -DCALL_LOGS_STORAGE_ENABLED
|
||||
LOCAL_CFLAGS += -DMSG_STORAGE_ENABLED -DCALL_LOGS_STORAGE_ENABLED -DFRIENDS_SQL_STORAGE_ENABLED
|
||||
LOCAL_STATIC_LIBRARIES += liblinsqlite
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(LOCAL_PATH)/../../externals/sqlite3/
|
||||
|
|
@ -300,7 +318,7 @@ LOCAL_MODULE_FILENAME := liblinphone-$(TARGET_ARCH_ABI)
|
|||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
LOCAL_CPPFLAGS=$(LOCAL_CFLAGS)
|
||||
LOCAL_CPPFLAGS += $(LOCAL_CFLAGS)
|
||||
LOCAL_CFLAGS += -Wdeclaration-after-statement
|
||||
LOCAL_LDFLAGS := -Wl,-soname,$(LOCAL_MODULE_FILENAME).so
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,8 @@ common_SRC_FILES := \
|
|||
tunnel_tester.c \
|
||||
upnp_tester.c \
|
||||
multicast_call_tester.c \
|
||||
complex_sip_call_tester.c
|
||||
vcard_tester.c \
|
||||
complex_sip_call_tester.c \
|
||||
|
||||
common_C_INCLUDES += \
|
||||
$(LOCAL_PATH) \
|
||||
|
|
|
|||
|
|
@ -277,6 +277,12 @@
|
|||
<Content Include="Assets\certificates\cn\openssl-cn.cnf">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Assets\common\vcards.vcf">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Assets\common\thousand_vcards.vcf">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Assets\Logo.png" />
|
||||
<Content Include="Assets\SmallLogo.png" />
|
||||
<Content Include="Assets\SplashScreen.png" />
|
||||
|
|
@ -309,7 +315,8 @@ XCopy /I /Y $(ProjectDir)..\..\..\tester\certificates\altname $(ProjectDir)Asset
|
|||
XCopy /I /Y $(ProjectDir)..\..\..\tester\certificates\cn $(ProjectDir)Assets\certificates\cn
|
||||
XCopy /I /Y $(ProjectDir)..\..\..\tester\images $(ProjectDir)Assets\images
|
||||
XCopy /I /Y $(ProjectDir)..\..\..\tester\rcfiles $(ProjectDir)Assets\rcfiles
|
||||
XCopy /I /Y $(ProjectDir)..\..\..\tester\sounds $(ProjectDir)Assets\sounds</PreBuildEvent>
|
||||
XCopy /I /Y $(ProjectDir)..\..\..\tester\sounds $(ProjectDir)Assets\sounds
|
||||
XCopy /I /Y $(ProjectDir)..\..\..\tester\common $(ProjectDir)Assets\common</PreBuildEvent>
|
||||
</PropertyGroup>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
|
@ -318,4 +325,4 @@ XCopy /I /Y $(ProjectDir)..\..\..\tester\sounds $(ProjectDir)Assets\sounds</PreB
|
|||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
|||
55
cmake/FindBelcard.cmake
Normal file
55
cmake/FindBelcard.cmake
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
############################################################################
|
||||
# FindBelcard.cmake
|
||||
# Copyright (C) 2015 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
############################################################################
|
||||
#
|
||||
# - Find the belcard include file and library
|
||||
#
|
||||
# BELCARD_FOUND - system has belcard
|
||||
# BELCARD_INCLUDE_DIRS - the belcard include directory
|
||||
# BELCARD_LIBRARIES - The libraries needed to use belcard
|
||||
|
||||
set(_BELCARD_ROOT_PATHS
|
||||
${CMAKE_INSTALL_PREFIX}
|
||||
)
|
||||
|
||||
find_path(BELCARD_INCLUDE_DIRS
|
||||
NAMES belcard.hpp
|
||||
HINTS _BELCARD_ROOT_PATHS
|
||||
PATH_SUFFIXES include/belcard
|
||||
)
|
||||
|
||||
if(BELCARD_INCLUDE_DIRS)
|
||||
set(HAVE_BELCARD_H 1)
|
||||
endif()
|
||||
|
||||
find_library(BELCARD_LIBRARIES
|
||||
NAMES belcard
|
||||
HINTS ${_BELCARD_ROOT_PATHS}
|
||||
PATH_SUFFIXES bin lib
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Belcard
|
||||
DEFAULT_MSG
|
||||
BELCARD_INCLUDE_DIRS BELCARD_LIBRARIES HAVE_BELCARD_H
|
||||
)
|
||||
|
||||
mark_as_advanced(BELCARD_INCLUDE_DIRS BELCARD_LIBRARIES HAVE_BELCARD_H)
|
||||
|
|
@ -42,6 +42,13 @@ if(@ENABLE_TUNNEL@)
|
|||
find_package(Tunnel)
|
||||
endif()
|
||||
endif()
|
||||
if(@ENABLE_VCARD@)
|
||||
if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS)
|
||||
include("${EP_belcard_CONFIG_DIR}/BelcardConfig.cmake")
|
||||
else()
|
||||
find_package(Belcard)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
get_filename_component(LINPHONE_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
||||
set(LINPHONE_INCLUDE_DIRS "${LINPHONE_CMAKE_DIR}/../../../include")
|
||||
|
|
@ -59,4 +66,8 @@ if(TUNNEL_FOUND)
|
|||
list(APPEND LINPHONE_INCLUDE_DIRS ${TUNNEL_INCLUDE_DIRS})
|
||||
list(APPEND LINPHONE_LIBRARIES ${TUNNEL_LIBRARIES})
|
||||
endif()
|
||||
if(BELCARD_FOUND)
|
||||
list(APPEND LINPHONE_INCLUDE_DIRS ${BELCARD_INCLUDE_DIRS})
|
||||
list(APPEND LINPHONE_LIBRARIES ${BELCARD_LIBRARIES})
|
||||
endif()
|
||||
set(LINPHONE_FOUND 1)
|
||||
|
|
|
|||
73
configure.ac
73
configure.ac
|
|
@ -880,6 +880,40 @@ if test x$enable_tunnel = xtrue; then
|
|||
AC_DEFINE(TUNNEL_ENABLED,1,[Tells tunnel extension is built-in])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(vcard,
|
||||
[AS_HELP_STRING([--enable-vcard=[yes/no]], [Turn on compilation of vcard (default=auto)])],
|
||||
[case "${enableval}" in
|
||||
yes) enable_vcard=true ;;
|
||||
no) enable_vcard=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-vcard) ;;
|
||||
esac],
|
||||
[enable_vcard=auto]
|
||||
)
|
||||
|
||||
if test x$enable_vcard != xfalse; then
|
||||
PKG_CHECK_MODULES(BELCARD, belcard, [found_vcard=yes],[found_vcard=no])
|
||||
if test "$found_vcard" = "no"; then
|
||||
dnl Check the lib presence in case the PKG-CONFIG version is not found
|
||||
AC_LANG_CPLUSPLUS
|
||||
AC_CHECK_LIB(belcard, main, [BELCARD_LIBS+=" -lbelr -lbelcard"; found_vcard=yes], [foo=bar])
|
||||
AC_LANG_C
|
||||
fi
|
||||
if test "$found_vcard" = "yes"; then
|
||||
BELCARD_CFLAGS+=" -DVCARD_ENABLED"
|
||||
enable_vcard=true
|
||||
else
|
||||
if test x$enable_vcard = xtrue; then
|
||||
AC_MSG_ERROR([belcard, required for vcard support, not found])
|
||||
fi
|
||||
enable_vcard=false
|
||||
fi
|
||||
|
||||
AC_SUBST(BELCARD_CFLAGS)
|
||||
AC_SUBST(BELCARD_LIBS)
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(BUILD_VCARD, test x$enable_vcard = xtrue)
|
||||
|
||||
AC_ARG_ENABLE(msg-storage,
|
||||
[AS_HELP_STRING([--enable-msg-storage=[yes/no]], [Turn on compilation of message storage (default=auto)])],
|
||||
[case "${enableval}" in
|
||||
|
|
@ -950,6 +984,41 @@ fi
|
|||
|
||||
AM_CONDITIONAL(BUILD_CALL_LOGS_STORAGE, test x$enable_call_logs_storage = xtrue)
|
||||
|
||||
AC_ARG_ENABLE(friends-db-storage,
|
||||
[AS_HELP_STRING([--enable-friends-db-storage=[yes/no]], [Turn on compilation of friends database storage (default=auto)])],
|
||||
[case "${enableval}" in
|
||||
yes) enable_friends_db_storage=true ;;
|
||||
no) enable_friends_db_storage=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-friends-db-storage) ;;
|
||||
esac],
|
||||
[enable_friends_db_storage=auto]
|
||||
)
|
||||
|
||||
if test x$enable_friends_db_storage != xfalse; then
|
||||
PKG_CHECK_MODULES(SQLITE3,[sqlite3 >= 3.6.0],[found_sqlite=yes],[found_sqlite=no])
|
||||
if test "$found_sqlite" = "no"; then
|
||||
dnl Check the lib presence in case the PKG-CONFIG version is not found
|
||||
AC_CHECK_LIB(sqlite3, sqlite3_open, [SQLITE3_LIBS+=" -lsqlite3 "; found_sqlite=yes], [foo=bar])
|
||||
fi
|
||||
if test "$found_sqlite" = "yes"; then
|
||||
SQLITE3_CFLAGS+=" -DFRIENDS_SQL_STORAGE_ENABLED"
|
||||
if test "$build_macos" = "yes" -o "$ios_found" = "yes"; then
|
||||
SQLITE3_LIBS+=" -liconv"
|
||||
fi
|
||||
enable_friends_db_storage=true
|
||||
else
|
||||
if test x$enable_friends_db_storage = xtrue; then
|
||||
AC_MSG_ERROR([sqlite3, required for friends database storage, not found])
|
||||
fi
|
||||
enable_friends_db_storage=false
|
||||
fi
|
||||
|
||||
AC_SUBST(SQLITE3_CFLAGS)
|
||||
AC_SUBST(SQLITE3_LIBS)
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(BUILD_FRIENDS_DB_STORAGE, test x$enable_friends_db_storage = xtrue)
|
||||
|
||||
PKG_CHECK_MODULES(BELLESIP, [belle-sip >= 1.4.0])
|
||||
|
||||
SIPSTACK_CFLAGS="$BELLESIP_CFLAGS"
|
||||
|
|
@ -1077,7 +1146,9 @@ printf "* %-30s %s\n" "Account assistant" $build_wizard
|
|||
printf "* %-30s %s\n" "Console interface" $console_ui
|
||||
printf "* %-30s %s\n" "Tools" $build_tools
|
||||
printf "* %-30s %s\n" "Message storage" $enable_msg_storage
|
||||
printf "* %-30s %s\n" "Call logs storage" $enable_call_logs_storage
|
||||
printf "* %-30s %s\n" "Call logs storage" $enable_call_logs_storage
|
||||
printf "* %-30s %s\n" "Friends db storage" $enable_friends_db_storage
|
||||
printf "* %-30s %s\n" "VCard support" $enable_vcard
|
||||
printf "* %-30s %s\n" "IM encryption" $lime
|
||||
printf "* %-30s %s\n" "uPnP support" $build_upnp
|
||||
printf "* %-30s %s\n" "LDAP support" $enable_ldap
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ set(LINPHONE_HEADER_FILES
|
|||
buffer.h
|
||||
call_log.h
|
||||
call_params.h
|
||||
carddav.h
|
||||
conference.h
|
||||
content.h
|
||||
event.h
|
||||
|
|
@ -51,6 +52,7 @@ set(LINPHONE_HEADER_FILES
|
|||
sipsetup.h
|
||||
xml2lpc.h
|
||||
xmlrpc.h
|
||||
vcard.h
|
||||
)
|
||||
|
||||
set(LINPHONE_SOURCE_FILES_C
|
||||
|
|
@ -74,6 +76,7 @@ set(LINPHONE_SOURCE_FILES_C
|
|||
callbacks.c
|
||||
call_log.c
|
||||
call_params.c
|
||||
carddav.c
|
||||
chat.c
|
||||
chat_file_transfer.c
|
||||
contactprovider.c
|
||||
|
|
@ -144,10 +147,6 @@ add_definitions(
|
|||
-DLIBLINPHONE_EXPORTS
|
||||
)
|
||||
|
||||
apply_compile_flags(LINPHONE_SOURCE_FILES_C "CPP" "C")
|
||||
apply_compile_flags(LINPHONE_SOURCE_FILES_CXX "CPP" "CXX")
|
||||
apply_compile_flags(LINPHONE_SOURCE_FILES_OBJC "CPP" "OBJC")
|
||||
|
||||
set(LIBS
|
||||
${BCTOOLBOX_CORE_LIBRARIES}
|
||||
${BELLESIP_LIBRARIES}
|
||||
|
|
@ -175,6 +174,17 @@ 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)
|
||||
list(APPEND STRICT_OPTIONS_CXX "-std=c++11")
|
||||
else()
|
||||
list(APPEND LINPHONE_SOURCE_FILES_C vcard_stubs.c)
|
||||
endif()
|
||||
|
||||
apply_compile_flags(LINPHONE_SOURCE_FILES_C "CPP" "C")
|
||||
apply_compile_flags(LINPHONE_SOURCE_FILES_CXX "CPP" "CXX")
|
||||
apply_compile_flags(LINPHONE_SOURCE_FILES_OBJC "CPP" "OBJC")
|
||||
|
||||
if(ENABLE_STATIC)
|
||||
add_library(linphone-static STATIC ${LINPHONE_HEADER_FILES} ${LINPHONE_SOURCE_FILES_C} ${LINPHONE_SOURCE_FILES_CXX} ${LINPHONE_SOURCE_FILES_OBJC})
|
||||
|
|
|
|||
|
|
@ -44,7 +44,9 @@ linphone_include_HEADERS=\
|
|||
lpconfig.h \
|
||||
sipsetup.h \
|
||||
xml2lpc.h \
|
||||
xmlrpc.h
|
||||
xmlrpc.h \
|
||||
vcard.h \
|
||||
carddav.h
|
||||
|
||||
lib_LTLIBRARIES=liblinphone.la
|
||||
|
||||
|
|
@ -92,6 +94,7 @@ liblinphone_la_SOURCES=\
|
|||
xml.c \
|
||||
xmlrpc.c \
|
||||
vtables.c \
|
||||
carddav.c \
|
||||
ringtoneplayer.c ringtoneplayer.h\
|
||||
$(GITVERSION_FILE)
|
||||
|
||||
|
|
@ -119,6 +122,12 @@ else
|
|||
liblinphone_la_SOURCES+=linphone_tunnel_stubs.c linphone_tunnel.h
|
||||
endif
|
||||
|
||||
if BUILD_VCARD
|
||||
liblinphone_la_SOURCES+=vcard.cc
|
||||
liblinphone_la_CXXFLAGS=-std=c++11
|
||||
else
|
||||
liblinphone_la_SOURCES+=vcard_stubs.c
|
||||
endif
|
||||
|
||||
liblinphone_la_LDFLAGS= -version-info $(LIBLINPHONE_SO_VERSION) -no-undefined
|
||||
|
||||
|
|
@ -146,19 +155,22 @@ liblinphone_la_LIBADD= \
|
|||
$(LIBXML2_LIBS) \
|
||||
$(LDAP_LIBS) \
|
||||
$(SASL_LIBS) \
|
||||
$(BELCARD_LIBS) \
|
||||
$(ZLIB_LIBS)
|
||||
|
||||
|
||||
AM_CPPFLAGS=\
|
||||
-DIN_LINPHONE \
|
||||
-I$(top_srcdir) -I$(top_srcdir)/include -I$(builddir) \
|
||||
$(ORTP_CFLAGS) \
|
||||
$(MEDIASTREAMER_CFLAGS)
|
||||
$(ORTP_CFLAGS) \
|
||||
$(MEDIASTREAMER_CFLAGS) \
|
||||
$(LIBXML2_CFLAGS)
|
||||
|
||||
COMMON_CFLAGS=\
|
||||
$(STRICT_OPTIONS) \
|
||||
-DIN_LINPHONE \
|
||||
$(SIPSTACK_CFLAGS) \
|
||||
-DENABLE_TRACE \
|
||||
-DENABLE_TRACE \
|
||||
-DLOG_DOMAIN=\"LinphoneCore\" \
|
||||
$(IPV6_CFLAGS) \
|
||||
-DORTP_INET6 \
|
||||
|
|
@ -168,6 +180,7 @@ COMMON_CFLAGS=\
|
|||
$(LIBXML2_CFLAGS) \
|
||||
$(LDAP_CFLAGS) \
|
||||
$(SASL_CFLAGS) \
|
||||
$(BELCARD_CFLAGS) \
|
||||
$(ZLIB_CFLAGS)
|
||||
|
||||
if BUILD_WIZARD
|
||||
|
|
|
|||
|
|
@ -20,13 +20,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#ifndef LINPHONE_ACCOUNT_CREATOR_H_
|
||||
#define LINPHONE_ACCOUNT_CREATOR_H_
|
||||
|
||||
#include "linphonecore.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "linphonecore.h"
|
||||
|
||||
/**
|
||||
* @addtogroup misc
|
||||
* @{
|
||||
|
|
|
|||
|
|
@ -997,12 +997,11 @@ typedef struct {
|
|||
unsigned char node[6];
|
||||
} sal_uuid_t;
|
||||
|
||||
|
||||
int sal_create_uuid(Sal*ctx, char *uuid, size_t len){
|
||||
int sal_generate_uuid(char *uuid, size_t len) {
|
||||
sal_uuid_t 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));
|
||||
|
|
@ -1021,10 +1020,17 @@ int sal_create_uuid(Sal*ctx, char *uuid, size_t len){
|
|||
for (i = 0; i < 6; i++)
|
||||
written+=snprintf(uuid+written,len-written,"%2.2x", uuid_struct.node[i]);
|
||||
uuid[len-1]='\0';
|
||||
sal_set_uuid(ctx,uuid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sal_create_uuid(Sal*ctx, char *uuid, size_t len) {
|
||||
if (sal_generate_uuid(uuid, len) == 0) {
|
||||
sal_set_uuid(ctx, uuid);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void make_supported_header(Sal *sal){
|
||||
MSList *it;
|
||||
char *alltags=NULL;
|
||||
|
|
|
|||
|
|
@ -349,7 +349,7 @@ static void linphone_create_table(sqlite3* db) {
|
|||
}
|
||||
}
|
||||
|
||||
void linphone_update_call_log_table(sqlite3* db) {
|
||||
static void linphone_update_call_log_table(sqlite3* db) {
|
||||
char* errmsg=NULL;
|
||||
int ret;
|
||||
|
||||
|
|
@ -461,7 +461,7 @@ error:
|
|||
return 0;
|
||||
}
|
||||
|
||||
void linphone_sql_request_call_log(sqlite3 *db, const char *stmt, MSList **list) {
|
||||
static void linphone_sql_request_call_log(sqlite3 *db, const char *stmt, MSList **list) {
|
||||
char* errmsg = NULL;
|
||||
int ret;
|
||||
ret = sqlite3_exec(db, stmt, create_call_log, list, &errmsg);
|
||||
|
|
@ -471,7 +471,7 @@ void linphone_sql_request_call_log(sqlite3 *db, const char *stmt, MSList **list)
|
|||
}
|
||||
}
|
||||
|
||||
int linphone_sql_request_generic(sqlite3* db, const char *stmt) {
|
||||
static int linphone_sql_request_generic(sqlite3* db, const char *stmt) {
|
||||
char* errmsg = NULL;
|
||||
int ret;
|
||||
ret = sqlite3_exec(db, stmt, NULL, NULL, &errmsg);
|
||||
|
|
|
|||
676
coreapi/carddav.c
Normal file
676
coreapi/carddav.c
Normal file
|
|
@ -0,0 +1,676 @@
|
|||
/*
|
||||
carddav.c
|
||||
Copyright (C) 2015 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "linphonecore.h"
|
||||
#include "private.h"
|
||||
|
||||
LinphoneCardDavContext* linphone_carddav_context_new(LinphoneFriendList *lfl) {
|
||||
LinphoneCardDavContext *carddav_context = NULL;
|
||||
|
||||
if (!lfl || !lfl->uri) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef VCARD_ENABLED
|
||||
carddav_context = (LinphoneCardDavContext *)ms_new0(LinphoneCardDavContext, 1);
|
||||
carddav_context->friend_list = linphone_friend_list_ref(lfl);
|
||||
#else
|
||||
ms_error("vCard isn't available (maybe it wasn't compiled), can't do CardDAV sync");
|
||||
#endif
|
||||
return carddav_context;
|
||||
}
|
||||
|
||||
void linphone_carddav_context_destroy(LinphoneCardDavContext *cdc) {
|
||||
if (cdc) {
|
||||
if (cdc->friend_list) {
|
||||
linphone_friend_list_unref(cdc->friend_list);
|
||||
cdc->friend_list = NULL;
|
||||
}
|
||||
ms_free(cdc);
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_carddav_set_user_data(LinphoneCardDavContext *cdc, void *ud) {
|
||||
cdc->user_data = ud;
|
||||
}
|
||||
|
||||
void* linphone_carddav_get_user_data(LinphoneCardDavContext *cdc) {
|
||||
return cdc->user_data;
|
||||
}
|
||||
|
||||
void linphone_carddav_synchronize(LinphoneCardDavContext *cdc) {
|
||||
cdc->ctag = cdc->friend_list->revision;
|
||||
linphone_carddav_get_current_ctag(cdc);
|
||||
}
|
||||
|
||||
static void linphone_carddav_sync_done(LinphoneCardDavContext *cdc, bool_t success, const char *msg) {
|
||||
if (success) {
|
||||
ms_debug("CardDAV sync successful, saving new cTag: %i", cdc->ctag);
|
||||
linphone_friend_list_update_revision(cdc->friend_list, cdc->ctag);
|
||||
} else {
|
||||
ms_error("CardDAV sync failure: %s", msg);
|
||||
}
|
||||
|
||||
if (cdc->sync_done_cb) {
|
||||
cdc->sync_done_cb(cdc, success, msg);
|
||||
}
|
||||
}
|
||||
|
||||
static int find_matching_friend(LinphoneFriend *lf1, LinphoneFriend *lf2) {
|
||||
LinphoneVCard *lvc1 = linphone_friend_get_vcard(lf1);
|
||||
LinphoneVCard *lvc2 = linphone_friend_get_vcard(lf2);
|
||||
const char *uid1 = NULL, *uid2 = NULL;
|
||||
if (!lvc1 || !lvc2) {
|
||||
return 1;
|
||||
}
|
||||
uid1 = linphone_vcard_get_uid(lvc1);
|
||||
uid2 = linphone_vcard_get_uid(lvc2);
|
||||
if (!uid1 || !uid2) {
|
||||
return 1;
|
||||
}
|
||||
return strcmp(uid1, uid2);
|
||||
}
|
||||
|
||||
static void linphone_carddav_vcards_pulled(LinphoneCardDavContext *cdc, MSList *vCards) {
|
||||
if (vCards != NULL && ms_list_size(vCards) > 0) {
|
||||
MSList *friends = cdc->friend_list->friends;
|
||||
while (vCards) {
|
||||
LinphoneCardDavResponse *vCard = (LinphoneCardDavResponse *)vCards->data;
|
||||
if (vCard) {
|
||||
LinphoneVCard *lvc = linphone_vcard_new_from_vcard4_buffer(vCard->vcard);
|
||||
LinphoneFriend *lf = NULL;
|
||||
MSList *local_friend = NULL;
|
||||
|
||||
if (lvc) {
|
||||
// Compute downloaded vCards' URL and save it (+ eTag)
|
||||
char *vCard_name = strrchr(vCard->url, '/');
|
||||
char full_url[300];
|
||||
snprintf(full_url, sizeof(full_url), "%s%s", cdc->friend_list->uri, vCard_name);
|
||||
linphone_vcard_set_url(lvc, full_url);
|
||||
linphone_vcard_set_etag(lvc, vCard->etag);
|
||||
ms_debug("Downloaded vCard etag/url are %s and %s", vCard->etag, full_url);
|
||||
}
|
||||
lf = linphone_friend_new_from_vcard(lvc);
|
||||
local_friend = ms_list_find_custom(friends, (int (*)(const void*, const void*))find_matching_friend, lf);
|
||||
|
||||
if (local_friend) {
|
||||
LinphoneFriend *lf2 = (LinphoneFriend *)local_friend->data;
|
||||
lf->storage_id = lf2->storage_id;
|
||||
lf->pol = lf2->pol;
|
||||
lf->subscribe = lf2->subscribe;
|
||||
lf->refkey = ms_strdup(lf2->refkey);
|
||||
lf->presence_received = lf2->presence_received;
|
||||
lf->lc = lf2->lc;
|
||||
lf->friend_list = lf2->friend_list;
|
||||
|
||||
if (cdc->contact_updated_cb) {
|
||||
ms_debug("Contact updated: %s", linphone_friend_get_name(lf));
|
||||
cdc->contact_updated_cb(cdc, lf, lf2);
|
||||
}
|
||||
} else {
|
||||
if (cdc->contact_created_cb) {
|
||||
ms_debug("Contact created: %s", linphone_friend_get_name(lf));
|
||||
cdc->contact_created_cb(cdc, lf);
|
||||
}
|
||||
}
|
||||
linphone_friend_unref(lf);
|
||||
}
|
||||
vCards = ms_list_next(vCards);
|
||||
}
|
||||
}
|
||||
ms_list_free(vCards);
|
||||
linphone_carddav_sync_done(cdc, TRUE, NULL);
|
||||
}
|
||||
|
||||
static MSList* parse_vcards_from_xml_response(const char *body) {
|
||||
MSList *result = NULL;
|
||||
xmlparsing_context_t *xml_ctx = linphone_xmlparsing_context_new();
|
||||
xmlSetGenericErrorFunc(xml_ctx, linphone_xmlparsing_genericxml_error);
|
||||
xml_ctx->doc = xmlReadDoc((const unsigned char*)body, 0, NULL, 0);
|
||||
if (xml_ctx->doc != NULL) {
|
||||
if (linphone_create_xml_xpath_context(xml_ctx) < 0) goto end;
|
||||
linphone_xml_xpath_context_init_carddav_ns(xml_ctx);
|
||||
{
|
||||
xmlXPathObjectPtr responses = linphone_get_xml_xpath_object_for_node_list(xml_ctx, "/d:multistatus/d:response");
|
||||
if (responses != NULL && responses->nodesetval != NULL) {
|
||||
xmlNodeSetPtr responses_nodes = responses->nodesetval;
|
||||
if (responses_nodes->nodeNr >= 1) {
|
||||
int i;
|
||||
for (i = 0; i < responses_nodes->nodeNr; i++) {
|
||||
xmlNodePtr response_node = responses_nodes->nodeTab[i];
|
||||
xml_ctx->xpath_ctx->node = response_node;
|
||||
{
|
||||
char *etag = linphone_get_xml_text_content(xml_ctx, "d:propstat/d:prop/d:getetag");
|
||||
char *url = linphone_get_xml_text_content(xml_ctx, "d:href");
|
||||
char *vcard = linphone_get_xml_text_content(xml_ctx, "d:propstat/d:prop/card:address-data");
|
||||
LinphoneCardDavResponse *response = ms_new0(LinphoneCardDavResponse, 1);
|
||||
response->etag = ms_strdup(etag);
|
||||
response->url = ms_strdup(url);
|
||||
response->vcard = ms_strdup(vcard);
|
||||
result = ms_list_append(result, response);
|
||||
ms_debug("Added vCard object with eTag %s, URL %s and vCard %s", etag, url, vcard);
|
||||
}
|
||||
}
|
||||
}
|
||||
xmlXPathFreeObject(responses);
|
||||
}
|
||||
}
|
||||
}
|
||||
end:
|
||||
linphone_xmlparsing_context_destroy(xml_ctx);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int find_matching_vcard(LinphoneCardDavResponse *response, LinphoneFriend *lf) {
|
||||
if (!response->url || !lf || !lf->vcard || !linphone_vcard_get_url(lf->vcard)) {
|
||||
return 1;
|
||||
}
|
||||
return strcmp(response->url, linphone_vcard_get_url(lf->vcard));
|
||||
}
|
||||
|
||||
static void linphone_carddav_vcards_fetched(LinphoneCardDavContext *cdc, MSList *vCards) {
|
||||
if (vCards != NULL && ms_list_size(vCards) > 0) {
|
||||
MSList *friends = cdc->friend_list->friends;
|
||||
MSList *friends_to_remove = NULL;
|
||||
MSList *temp_list = NULL;
|
||||
|
||||
while (friends) {
|
||||
LinphoneFriend *lf = (LinphoneFriend *)friends->data;
|
||||
if (lf) {
|
||||
MSList *vCard = ms_list_find_custom(vCards, (int (*)(const void*, const void*))find_matching_vcard, lf);
|
||||
if (!vCard) {
|
||||
ms_debug("Local friend %s isn't in the remote vCard list, delete it", linphone_friend_get_name(lf));
|
||||
temp_list = ms_list_append(temp_list, linphone_friend_ref(lf));
|
||||
} else {
|
||||
LinphoneCardDavResponse *response = (LinphoneCardDavResponse *)vCard->data;
|
||||
ms_debug("Local friend %s is in the remote vCard list, check eTag", linphone_friend_get_name(lf));
|
||||
if (response) {
|
||||
LinphoneVCard *lvc = linphone_friend_get_vcard(lf);
|
||||
const char *etag = linphone_vcard_get_etag(lvc);
|
||||
ms_debug("Local friend eTag is %s, remote vCard eTag is %s", etag, response->etag);
|
||||
if (lvc && etag && strcmp(etag, response->etag) == 0) {
|
||||
ms_list_remove(vCards, vCard);
|
||||
ms_free(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
friends = ms_list_next(friends);
|
||||
}
|
||||
friends_to_remove = temp_list;
|
||||
while(friends_to_remove) {
|
||||
LinphoneFriend *lf = (LinphoneFriend *)friends_to_remove->data;
|
||||
if (lf) {
|
||||
if (cdc->contact_removed_cb) {
|
||||
ms_debug("Contact removed: %s", linphone_friend_get_name(lf));
|
||||
cdc->contact_removed_cb(cdc, lf);
|
||||
}
|
||||
}
|
||||
friends_to_remove = ms_list_next(friends_to_remove);
|
||||
}
|
||||
temp_list = ms_list_free_with_data(temp_list, (void (*)(void *))linphone_friend_unref);
|
||||
|
||||
linphone_carddav_pull_vcards(cdc, vCards);
|
||||
}
|
||||
ms_list_free(vCards);
|
||||
}
|
||||
|
||||
static MSList* parse_vcards_etags_from_xml_response(const char *body) {
|
||||
MSList *result = NULL;
|
||||
xmlparsing_context_t *xml_ctx = linphone_xmlparsing_context_new();
|
||||
xmlSetGenericErrorFunc(xml_ctx, linphone_xmlparsing_genericxml_error);
|
||||
xml_ctx->doc = xmlReadDoc((const unsigned char*)body, 0, NULL, 0);
|
||||
if (xml_ctx->doc != NULL) {
|
||||
if (linphone_create_xml_xpath_context(xml_ctx) < 0) goto end;
|
||||
linphone_xml_xpath_context_init_carddav_ns(xml_ctx);
|
||||
{
|
||||
xmlXPathObjectPtr responses = linphone_get_xml_xpath_object_for_node_list(xml_ctx, "/d:multistatus/d:response");
|
||||
if (responses != NULL && responses->nodesetval != NULL) {
|
||||
xmlNodeSetPtr responses_nodes = responses->nodesetval;
|
||||
if (responses_nodes->nodeNr >= 1) {
|
||||
int i;
|
||||
for (i = 0; i < responses_nodes->nodeNr; i++) {
|
||||
xmlNodePtr response_node = responses_nodes->nodeTab[i];
|
||||
xml_ctx->xpath_ctx->node = response_node;
|
||||
{
|
||||
char *etag = linphone_get_xml_text_content(xml_ctx, "d:propstat/d:prop/d:getetag");
|
||||
char *url = linphone_get_xml_text_content(xml_ctx, "d:href");
|
||||
LinphoneCardDavResponse *response = ms_new0(LinphoneCardDavResponse, 1);
|
||||
response->etag = ms_strdup(etag);
|
||||
response->url = ms_strdup(url);
|
||||
result = ms_list_append(result, response);
|
||||
ms_debug("Added vCard object with eTag %s and URL %s", etag, url);
|
||||
}
|
||||
}
|
||||
}
|
||||
xmlXPathFreeObject(responses);
|
||||
}
|
||||
}
|
||||
}
|
||||
end:
|
||||
linphone_xmlparsing_context_destroy(xml_ctx);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void linphone_carddav_ctag_fetched(LinphoneCardDavContext *cdc, int ctag) {
|
||||
ms_debug("Remote cTag for CardDAV addressbook is %i, local one is %i", ctag, cdc->ctag);
|
||||
if (ctag == -1 || ctag > cdc->ctag) {
|
||||
cdc->ctag = ctag;
|
||||
linphone_carddav_fetch_vcards(cdc);
|
||||
} else {
|
||||
ms_message("No changes found on server, skipping sync");
|
||||
linphone_carddav_sync_done(cdc, TRUE, "Synchronization skipped because cTag already up to date");
|
||||
}
|
||||
}
|
||||
|
||||
static int parse_ctag_value_from_xml_response(const char *body) {
|
||||
int result = -1;
|
||||
xmlparsing_context_t *xml_ctx = linphone_xmlparsing_context_new();
|
||||
xmlSetGenericErrorFunc(xml_ctx, linphone_xmlparsing_genericxml_error);
|
||||
xml_ctx->doc = xmlReadDoc((const unsigned char*)body, 0, NULL, 0);
|
||||
if (xml_ctx->doc != NULL) {
|
||||
char *response = NULL;
|
||||
if (linphone_create_xml_xpath_context(xml_ctx) < 0) goto end;
|
||||
linphone_xml_xpath_context_init_carddav_ns(xml_ctx);
|
||||
response = linphone_get_xml_text_content(xml_ctx, "/d:multistatus/d:response/d:propstat/d:prop/x1:getctag");
|
||||
if (response) {
|
||||
result = atoi(response);
|
||||
linphone_free_xml_text_content(response);
|
||||
}
|
||||
}
|
||||
end:
|
||||
linphone_xmlparsing_context_destroy(xml_ctx);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void linphone_carddav_query_free(LinphoneCardDavQuery *query) {
|
||||
if (!query) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (query->http_request_listener) {
|
||||
belle_sip_object_unref(query->http_request_listener);
|
||||
query->http_request_listener = NULL;
|
||||
}
|
||||
|
||||
ms_free(query);
|
||||
}
|
||||
|
||||
static void process_response_from_carddav_request(void *data, const belle_http_response_event_t *event) {
|
||||
LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)data;
|
||||
|
||||
if (event->response) {
|
||||
int code = belle_http_response_get_status_code(event->response);
|
||||
if (code == 207 || code == 200 || code == 201 || code == 204) {
|
||||
const char *body = belle_sip_message_get_body((belle_sip_message_t *)event->response);
|
||||
switch(query->type) {
|
||||
case LinphoneCardDavQueryTypePropfind:
|
||||
linphone_carddav_ctag_fetched(query->context, parse_ctag_value_from_xml_response(body));
|
||||
break;
|
||||
case LinphoneCardDavQueryTypeAddressbookQuery:
|
||||
linphone_carddav_vcards_fetched(query->context, parse_vcards_etags_from_xml_response(body));
|
||||
break;
|
||||
case LinphoneCardDavQueryTypeAddressbookMultiget:
|
||||
linphone_carddav_vcards_pulled(query->context, parse_vcards_from_xml_response(body));
|
||||
break;
|
||||
case LinphoneCardDavQueryTypePut:
|
||||
{
|
||||
belle_sip_header_t *header = belle_sip_message_get_header((belle_sip_message_t *)event->response, "ETag");
|
||||
LinphoneFriend *lf = (LinphoneFriend *)query->user_data;
|
||||
LinphoneVCard *lvc = linphone_friend_get_vcard(lf);
|
||||
if (lf && lvc) {
|
||||
if (header) {
|
||||
const char *etag = belle_sip_header_get_unparsed_value(header);
|
||||
if (!linphone_vcard_get_etag(lvc)) {
|
||||
ms_debug("eTag for newly created vCard is: %s", etag);
|
||||
} else {
|
||||
ms_debug("eTag for updated vCard is: %s", etag);
|
||||
}
|
||||
linphone_vcard_set_etag(lvc, etag);
|
||||
|
||||
linphone_carddav_sync_done(query->context, TRUE, NULL);
|
||||
linphone_friend_unref(lf);
|
||||
} else {
|
||||
// For some reason, server didn't return the eTag of the updated/created vCard
|
||||
// We need to do a GET on the vCard to get the correct one
|
||||
MSList *vcard = NULL;
|
||||
LinphoneCardDavResponse *response = (LinphoneCardDavResponse *)ms_new0(LinphoneCardDavResponse, 1);
|
||||
response->url = linphone_vcard_get_url(lvc);
|
||||
response->context = query->context;
|
||||
vcard = ms_list_append(vcard, response);
|
||||
linphone_carddav_pull_vcards(query->context, vcard);
|
||||
ms_list_free(vcard);
|
||||
}
|
||||
}
|
||||
else {
|
||||
linphone_carddav_sync_done(query->context, FALSE, "No LinphoneFriend found in user_date field of query");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LinphoneCardDavQueryTypeDelete:
|
||||
linphone_carddav_sync_done(query->context, TRUE, NULL);
|
||||
break;
|
||||
default:
|
||||
ms_error("Unknown request: %i", query->type);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
char msg[100];
|
||||
snprintf(msg, sizeof(msg), "Unexpected HTTP response code: %i", code);
|
||||
linphone_carddav_sync_done(query->context, FALSE, msg);
|
||||
}
|
||||
} else {
|
||||
linphone_carddav_sync_done(query->context, FALSE, "No response found");
|
||||
}
|
||||
linphone_carddav_query_free(query);
|
||||
}
|
||||
|
||||
static void process_io_error_from_carddav_request(void *data, const belle_sip_io_error_event_t *event) {
|
||||
LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)data;
|
||||
ms_error("I/O error during CardDAV request sending");
|
||||
linphone_carddav_query_free(query);
|
||||
linphone_carddav_sync_done(query->context, FALSE, "I/O error during CardDAV request sending");
|
||||
}
|
||||
|
||||
static void process_auth_requested_from_carddav_request(void *data, belle_sip_auth_event_t *event) {
|
||||
LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)data;
|
||||
LinphoneCardDavContext *cdc = query->context;
|
||||
const char *realm = belle_sip_auth_event_get_realm(event);
|
||||
belle_generic_uri_t *uri = belle_generic_uri_parse(query->url);
|
||||
const char *domain = belle_generic_uri_get_host(uri);
|
||||
LinphoneCore *lc = cdc->friend_list->lc;
|
||||
const MSList *auth_infos = linphone_core_get_auth_info_list(lc);
|
||||
|
||||
ms_debug("Looking for auth info for domain %s and realm %s", domain, realm);
|
||||
while (auth_infos) {
|
||||
LinphoneAuthInfo *auth_info = (LinphoneAuthInfo *)auth_infos->data;
|
||||
if (auth_info->domain && strcmp(domain, auth_info->domain) == 0) {
|
||||
if (!auth_info->realm || strcmp(realm, auth_info->realm) == 0) {
|
||||
belle_sip_auth_event_set_username(event, auth_info->username);
|
||||
belle_sip_auth_event_set_passwd(event, auth_info->passwd);
|
||||
belle_sip_auth_event_set_ha1(event, auth_info->ha1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
auth_infos = ms_list_next(auth_infos);
|
||||
}
|
||||
|
||||
if (!auth_infos) {
|
||||
ms_error("Authentication requested during CardDAV request sending, and username/password weren't provided");
|
||||
linphone_carddav_sync_done(query->context, FALSE, "Authentication requested during CardDAV request sending, and username/password weren't provided");
|
||||
linphone_carddav_query_free(query);
|
||||
}
|
||||
}
|
||||
|
||||
static void linphone_carddav_send_query(LinphoneCardDavQuery *query) {
|
||||
belle_http_request_listener_callbacks_t cbs = { 0 };
|
||||
belle_generic_uri_t *uri = NULL;
|
||||
belle_http_request_t *req = NULL;
|
||||
belle_sip_memory_body_handler_t *bh = NULL;
|
||||
|
||||
uri = belle_generic_uri_parse(query->url);
|
||||
if (!uri) {
|
||||
LinphoneCardDavContext *cdc = query->context;
|
||||
if (cdc && cdc->sync_done_cb) {
|
||||
cdc->sync_done_cb(cdc, FALSE, "Could not send request, URL is invalid");
|
||||
}
|
||||
belle_sip_error("Could not send request, URL %s is invalid", query->url);
|
||||
return;
|
||||
}
|
||||
req = belle_http_request_create(query->method, uri, belle_sip_header_content_type_create("application", "xml; charset=utf-8"), NULL);
|
||||
|
||||
if (!req) {
|
||||
LinphoneCardDavContext *cdc = query->context;
|
||||
if (cdc && cdc->sync_done_cb) {
|
||||
cdc->sync_done_cb(cdc, FALSE, "Could not create belle_http_request_t");
|
||||
}
|
||||
belle_sip_object_unref(uri);
|
||||
belle_sip_error("Could not create belle_http_request_t");
|
||||
return;
|
||||
}
|
||||
|
||||
if (query->depth) {
|
||||
belle_sip_message_add_header((belle_sip_message_t *)req, belle_sip_header_create("Depth", query->depth));
|
||||
} else if (query->ifmatch) {
|
||||
belle_sip_message_add_header((belle_sip_message_t *)req, belle_sip_header_create("If-Match", query->ifmatch));
|
||||
} else if (strcmp(query->method, "PUT")) {
|
||||
belle_sip_message_add_header((belle_sip_message_t *)req, belle_sip_header_create("If-None-Match", "*"));
|
||||
}
|
||||
|
||||
if (query->body) {
|
||||
bh = belle_sip_memory_body_handler_new_copy_from_buffer(query->body, strlen(query->body), NULL, NULL);
|
||||
belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(req), bh ? BELLE_SIP_BODY_HANDLER(bh) : NULL);
|
||||
}
|
||||
|
||||
cbs.process_response = process_response_from_carddav_request;
|
||||
cbs.process_io_error = process_io_error_from_carddav_request;
|
||||
cbs.process_auth_requested = process_auth_requested_from_carddav_request;
|
||||
query->http_request_listener = belle_http_request_listener_create_from_callbacks(&cbs, query);
|
||||
belle_http_provider_send_request(query->context->friend_list->lc->http_provider, req, query->http_request_listener);
|
||||
}
|
||||
|
||||
static LinphoneCardDavQuery* linphone_carddav_create_put_query(LinphoneCardDavContext *cdc, LinphoneVCard *lvc) {
|
||||
LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)ms_new0(LinphoneCardDavQuery, 1);
|
||||
query->context = cdc;
|
||||
query->depth = NULL;
|
||||
query->ifmatch = linphone_vcard_get_etag(lvc);
|
||||
query->body = linphone_vcard_as_vcard4_string(lvc);
|
||||
query->method = "PUT";
|
||||
query->url = linphone_vcard_get_url(lvc);
|
||||
query->type = LinphoneCardDavQueryTypePut;
|
||||
return query;
|
||||
}
|
||||
|
||||
static char* generate_url_from_server_address_and_uid(const char *server_url) {
|
||||
char *result = NULL;
|
||||
if (server_url) {
|
||||
char *uuid = ms_malloc(64);
|
||||
if (sal_generate_uuid(uuid, 64) == 0) {
|
||||
char *url = ms_malloc(300);
|
||||
snprintf(url, 300, "%s/linphone-%s.vcf", server_url, uuid);
|
||||
ms_debug("Generated url is %s", url);
|
||||
result = ms_strdup(url);
|
||||
ms_free(url);
|
||||
}
|
||||
ms_free(uuid);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void linphone_carddav_put_vcard(LinphoneCardDavContext *cdc, LinphoneFriend *lf) {
|
||||
LinphoneVCard *lvc = linphone_friend_get_vcard(lf);
|
||||
if (lvc) {
|
||||
LinphoneCardDavQuery *query = NULL;
|
||||
if (!linphone_vcard_get_uid(lvc)) {
|
||||
linphone_vcard_generate_unique_id(lvc);
|
||||
}
|
||||
|
||||
if (!linphone_vcard_get_url(lvc)) {
|
||||
char *url = generate_url_from_server_address_and_uid(cdc->friend_list->uri);
|
||||
if (url) {
|
||||
linphone_vcard_set_url(lvc, url);
|
||||
ms_free(url);
|
||||
} else {
|
||||
const char *msg = "vCard doesn't have an URL, and friendlist doesn't have a CardDAV server set either, can't push it";
|
||||
ms_warning("%s", msg);
|
||||
if (cdc && cdc->sync_done_cb) {
|
||||
cdc->sync_done_cb(cdc, FALSE, msg);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
query = linphone_carddav_create_put_query(cdc, lvc);
|
||||
query->user_data = linphone_friend_ref(lf);
|
||||
linphone_carddav_send_query(query);
|
||||
} else {
|
||||
const char *msg = NULL;
|
||||
if (!lvc) {
|
||||
msg = "LinphoneVCard is NULL";
|
||||
} else {
|
||||
msg = "Unknown error";
|
||||
}
|
||||
|
||||
if (msg) {
|
||||
ms_error("%s", msg);
|
||||
}
|
||||
|
||||
if (cdc && cdc->sync_done_cb) {
|
||||
cdc->sync_done_cb(cdc, FALSE, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static LinphoneCardDavQuery* linphone_carddav_create_delete_query(LinphoneCardDavContext *cdc, LinphoneVCard *lvc) {
|
||||
LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)ms_new0(LinphoneCardDavQuery, 1);
|
||||
query->context = cdc;
|
||||
query->depth = NULL;
|
||||
query->ifmatch = linphone_vcard_get_etag(lvc);
|
||||
query->body = NULL;
|
||||
query->method = "DELETE";
|
||||
query->url = linphone_vcard_get_url(lvc);
|
||||
query->type = LinphoneCardDavQueryTypeDelete;
|
||||
return query;
|
||||
}
|
||||
|
||||
void linphone_carddav_delete_vcard(LinphoneCardDavContext *cdc, LinphoneFriend *lf) {
|
||||
LinphoneVCard *lvc = linphone_friend_get_vcard(lf);
|
||||
if (lvc && linphone_vcard_get_uid(lvc) && linphone_vcard_get_etag(lvc)) {
|
||||
LinphoneCardDavQuery *query = NULL;
|
||||
|
||||
if (!linphone_vcard_get_url(lvc)) {
|
||||
char *url = generate_url_from_server_address_and_uid(cdc->friend_list->uri);
|
||||
if (url) {
|
||||
linphone_vcard_set_url(lvc, url);
|
||||
ms_free(url);
|
||||
} else {
|
||||
const char *msg = "vCard doesn't have an URL, and friendlist doesn't have a CardDAV server set either, can't delete it";
|
||||
ms_warning("%s", msg);
|
||||
if (cdc && cdc->sync_done_cb) {
|
||||
cdc->sync_done_cb(cdc, FALSE, msg);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
query = linphone_carddav_create_delete_query(cdc, lvc);
|
||||
linphone_carddav_send_query(query);
|
||||
} else {
|
||||
const char *msg = NULL;
|
||||
if (!lvc) {
|
||||
msg = "LinphoneVCard is NULL";
|
||||
} else if (!linphone_vcard_get_uid(lvc)) {
|
||||
msg = "LinphoneVCard doesn't have an UID";
|
||||
} else if (!linphone_vcard_get_etag(lvc)) {
|
||||
msg = "LinphoneVCard doesn't have an eTag";
|
||||
}
|
||||
|
||||
if (msg) {
|
||||
ms_error("%s", msg);
|
||||
}
|
||||
|
||||
if (cdc && cdc->sync_done_cb) {
|
||||
cdc->sync_done_cb(cdc, FALSE, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_carddav_set_synchronization_done_callback(LinphoneCardDavContext *cdc, LinphoneCardDavSynchronizationDoneCb cb) {
|
||||
cdc->sync_done_cb = cb;
|
||||
}
|
||||
|
||||
void linphone_carddav_set_new_contact_callback(LinphoneCardDavContext *cdc, LinphoneCardDavContactCreatedCb cb) {
|
||||
cdc->contact_created_cb = cb;
|
||||
}
|
||||
|
||||
void linphone_carddav_set_updated_contact_callback(LinphoneCardDavContext *cdc, LinphoneCardDavContactUpdatedCb cb) {
|
||||
cdc->contact_updated_cb = cb;
|
||||
}
|
||||
|
||||
void linphone_carddav_set_removed_contact_callback(LinphoneCardDavContext *cdc, LinphoneCardDavContactRemovedCb cb) {
|
||||
cdc->contact_removed_cb = cb;
|
||||
}
|
||||
|
||||
static LinphoneCardDavQuery* linphone_carddav_create_propfind_query(LinphoneCardDavContext *cdc) {
|
||||
LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)ms_new0(LinphoneCardDavQuery, 1);
|
||||
query->context = cdc;
|
||||
query->depth = "0";
|
||||
query->ifmatch = NULL;
|
||||
query->body = "<d:propfind xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\"><d:prop><cs:getctag /></d:prop></d:propfind>";
|
||||
query->method = "PROPFIND";
|
||||
query->url = cdc->friend_list->uri;
|
||||
query->type = LinphoneCardDavQueryTypePropfind;
|
||||
return query;
|
||||
}
|
||||
|
||||
void linphone_carddav_get_current_ctag(LinphoneCardDavContext *cdc) {
|
||||
LinphoneCardDavQuery *query = linphone_carddav_create_propfind_query(cdc);
|
||||
linphone_carddav_send_query(query);
|
||||
}
|
||||
|
||||
static LinphoneCardDavQuery* linphone_carddav_create_addressbook_query(LinphoneCardDavContext *cdc) {
|
||||
LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)ms_new0(LinphoneCardDavQuery, 1);
|
||||
query->context = cdc;
|
||||
query->depth = "1";
|
||||
query->ifmatch = NULL;
|
||||
query->body = "<card:addressbook-query xmlns:d=\"DAV:\" xmlns:card=\"urn:ietf:params:xml:ns:carddav\"><d:prop><d:getetag /></d:prop><card:filter></card:filter></card:addressbook-query>";
|
||||
query->method = "REPORT";
|
||||
query->url = cdc->friend_list->uri;
|
||||
query->type = LinphoneCardDavQueryTypeAddressbookQuery;
|
||||
return query;
|
||||
}
|
||||
|
||||
void linphone_carddav_fetch_vcards(LinphoneCardDavContext *cdc) {
|
||||
LinphoneCardDavQuery *query = linphone_carddav_create_addressbook_query(cdc);
|
||||
linphone_carddav_send_query(query);
|
||||
}
|
||||
|
||||
static LinphoneCardDavQuery* linphone_carddav_create_addressbook_multiget_query(LinphoneCardDavContext *cdc, MSList *vcards) {
|
||||
LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)ms_new0(LinphoneCardDavQuery, 1);
|
||||
char *body = (char *)ms_malloc((ms_list_size(vcards) + 1) * 300 * sizeof(char));
|
||||
MSList *iterator = vcards;
|
||||
|
||||
query->context = cdc;
|
||||
query->depth = "1";
|
||||
query->ifmatch = NULL;
|
||||
query->method = "REPORT";
|
||||
query->url = cdc->friend_list->uri;
|
||||
query->type = LinphoneCardDavQueryTypeAddressbookMultiget;
|
||||
|
||||
sprintf(body, "%s", "<card:addressbook-multiget xmlns:d=\"DAV:\" xmlns:card=\"urn:ietf:params:xml:ns:carddav\"><d:prop><d:getetag /><card:address-data content-type='text/vcard' version='4.0'/></d:prop>");
|
||||
while (iterator) {
|
||||
LinphoneCardDavResponse *response = (LinphoneCardDavResponse *)iterator->data;
|
||||
if (response) {
|
||||
char temp_body[300];
|
||||
snprintf(temp_body, sizeof(temp_body), "<d:href>%s</d:href>", response->url);
|
||||
sprintf(body, "%s%s", body, temp_body);
|
||||
iterator = ms_list_next(iterator);
|
||||
}
|
||||
}
|
||||
sprintf(body, "%s%s", body, "</card:addressbook-multiget>");
|
||||
query->body = ms_strdup(body);
|
||||
ms_free(body);
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
void linphone_carddav_pull_vcards(LinphoneCardDavContext *cdc, MSList *vcards_to_pull) {
|
||||
LinphoneCardDavQuery *query = linphone_carddav_create_addressbook_multiget_query(cdc, vcards_to_pull);
|
||||
linphone_carddav_send_query(query);
|
||||
}
|
||||
170
coreapi/carddav.h
Normal file
170
coreapi/carddav.h
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
carddav.h
|
||||
Copyright (C) 2015 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef LINPHONE_CARDDAV_H
|
||||
#define LINPHONE_CARDDAV_H
|
||||
|
||||
#include "linphonecore.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup carddav_vcard
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef struct _LinphoneCardDavContext LinphoneCardDavContext;
|
||||
|
||||
typedef enum _LinphoneCardDavQueryType {
|
||||
LinphoneCardDavQueryTypePropfind,
|
||||
LinphoneCardDavQueryTypeAddressbookQuery,
|
||||
LinphoneCardDavQueryTypeAddressbookMultiget,
|
||||
LinphoneCardDavQueryTypePut,
|
||||
LinphoneCardDavQueryTypeDelete
|
||||
} LinphoneCardDavQueryType;
|
||||
|
||||
typedef struct _LinphoneCardDavQuery LinphoneCardDavQuery;
|
||||
|
||||
typedef struct _LinphoneCardDavResponse LinphoneCardDavResponse;
|
||||
|
||||
/**
|
||||
* Callback used to notify a new contact has been created on the CardDAV server
|
||||
**/
|
||||
typedef void (*LinphoneCardDavContactCreatedCb)(LinphoneCardDavContext *cdc, LinphoneFriend *lf);
|
||||
|
||||
/**
|
||||
* Callback used to notify a contact has been updated on the CardDAV server
|
||||
**/
|
||||
typedef void (*LinphoneCardDavContactUpdatedCb)(LinphoneCardDavContext *cdc, LinphoneFriend *new_friend, LinphoneFriend *old_friend);
|
||||
|
||||
/**
|
||||
* Callback used to notify a contact has been removed on the CardDAV server
|
||||
**/
|
||||
typedef void (*LinphoneCardDavContactRemovedCb)(LinphoneCardDavContext *cdc, LinphoneFriend *lf);
|
||||
|
||||
/**
|
||||
* Callback used to notify a contact has been removed on the CardDAV server
|
||||
**/
|
||||
typedef void (*LinphoneCardDavSynchronizationDoneCb)(LinphoneCardDavContext *cdc, bool_t success, const char *message);
|
||||
|
||||
/**
|
||||
* Creates a CardDAV context for all related operations
|
||||
* @param lfl LinphoneFriendList object
|
||||
* @return LinphoneCardDavContext object if vCard support is enabled and server URL is available, NULL otherwise
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneCardDavContext* linphone_carddav_context_new(LinphoneFriendList *lfl);
|
||||
|
||||
/**
|
||||
* Deletes a LinphoneCardDavContext object
|
||||
* @param cdc LinphoneCardDavContext object
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_carddav_context_destroy(LinphoneCardDavContext *cdc);
|
||||
|
||||
/**
|
||||
* Sets a user pointer to the LinphoneCardDAVContext object
|
||||
* @param cdc LinphoneCardDavContext object
|
||||
* @param ud The user data pointer
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_carddav_set_user_data(LinphoneCardDavContext *cdc, void *ud);
|
||||
|
||||
/**
|
||||
* Gets the user pointer set in the LinphoneCardDAVContext object
|
||||
* @param cdc LinphoneCardDavContext object
|
||||
* @return The user data pointer if set, NULL otherwise
|
||||
*/
|
||||
LINPHONE_PUBLIC void* linphone_carddav_get_user_data(LinphoneCardDavContext *cdc);
|
||||
|
||||
/**
|
||||
* Starts a synchronization with the remote server to update local friends with server changes
|
||||
* @param cdc LinphoneCardDavContext object
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_carddav_synchronize(LinphoneCardDavContext *cdc);
|
||||
|
||||
/**
|
||||
* Sends a LinphoneFriend to the CardDAV server for update or creation
|
||||
* @param cdc LinphoneCardDavContext object
|
||||
* @param lf a LinphoneFriend object to update/create on the server
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_carddav_put_vcard(LinphoneCardDavContext *cdc, LinphoneFriend *lf);
|
||||
|
||||
/**
|
||||
* Deletes a LinphoneFriend on the CardDAV server
|
||||
* @param cdc LinphoneCardDavContext object
|
||||
* @param lf a LinphoneFriend object to delete on the server
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_carddav_delete_vcard(LinphoneCardDavContext *cdc, LinphoneFriend *lf);
|
||||
|
||||
/**
|
||||
* Set the synchronization done callback.
|
||||
* @param cdc LinphoneCardDavContext object
|
||||
* @param cb The synchronization done callback to be used.
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_carddav_set_synchronization_done_callback(LinphoneCardDavContext *cdc, LinphoneCardDavSynchronizationDoneCb cb);
|
||||
|
||||
/**
|
||||
* Set the new contact callback.
|
||||
* @param cdc LinphoneCardDavContext object
|
||||
* @param cb The new contact callback to be used.
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_carddav_set_new_contact_callback(LinphoneCardDavContext *cdc, LinphoneCardDavContactCreatedCb cb);
|
||||
|
||||
/**
|
||||
* Set the updated contact callback.
|
||||
* @param cdc LinphoneCardDavContext object
|
||||
* @param cb The updated contact callback to be used.
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_carddav_set_updated_contact_callback(LinphoneCardDavContext *cdc, LinphoneCardDavContactUpdatedCb cb);
|
||||
|
||||
/**
|
||||
* Set the removed contact callback.
|
||||
* @param cdc LinphoneCardDavContext object
|
||||
* @param cb The removed contact callback to be used.
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_carddav_set_removed_contact_callback(LinphoneCardDavContext *cdc, LinphoneCardDavContactRemovedCb cb);
|
||||
|
||||
/**
|
||||
* Retrieves the current cTag value for the remote server
|
||||
* @param cdc LinphoneCardDavContext object
|
||||
*/
|
||||
void linphone_carddav_get_current_ctag(LinphoneCardDavContext *cdc);
|
||||
|
||||
/**
|
||||
* Retrieves a list of all the vCards on server side to be able to detect changes
|
||||
* @param cdc LinphoneCardDavContext object
|
||||
*/
|
||||
void linphone_carddav_fetch_vcards(LinphoneCardDavContext *cdc);
|
||||
|
||||
/**
|
||||
* Download asked vCards from the server
|
||||
* @param cdc LinphoneCardDavContext object
|
||||
* @param vcards_to_pull a MSList of LinphoneCardDavResponse objects with at least the url field filled
|
||||
*/
|
||||
void linphone_carddav_pull_vcards(LinphoneCardDavContext *cdc, MSList *vcards_to_pull);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
810
coreapi/friend.c
810
coreapi/friend.c
|
|
@ -26,6 +26,21 @@
|
|||
#include "private.h"
|
||||
#include "lpconfig.h"
|
||||
|
||||
#ifdef FRIENDS_SQL_STORAGE_ENABLED
|
||||
#ifndef _WIN32
|
||||
#if !defined(ANDROID) && !defined(__QNXNTO__)
|
||||
# include <langinfo.h>
|
||||
# include <iconv.h>
|
||||
# include <string.h>
|
||||
#endif
|
||||
#else
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
#define MAX_PATH_SIZE 1024
|
||||
#include "sqlite3.h"
|
||||
#endif
|
||||
|
||||
const char *linphone_online_status_to_string(LinphoneOnlineStatus ss){
|
||||
const char *str=NULL;
|
||||
switch(ss){
|
||||
|
|
@ -109,10 +124,12 @@ void __linphone_friend_do_subscribe(LinphoneFriend *fr){
|
|||
}
|
||||
|
||||
LinphoneFriend * linphone_friend_new(){
|
||||
LinphoneFriend *obj=belle_sip_object_new(LinphoneFriend);
|
||||
obj->pol=LinphoneSPAccept;
|
||||
obj->presence=NULL;
|
||||
obj->subscribe=TRUE;
|
||||
LinphoneFriend *obj = belle_sip_object_new(LinphoneFriend);
|
||||
obj->pol = LinphoneSPAccept;
|
||||
obj->presence = NULL;
|
||||
obj->subscribe = TRUE;
|
||||
obj->vcard = NULL;
|
||||
obj->storage_id = 0;
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
|
@ -126,7 +143,7 @@ LinphoneFriend *linphone_friend_new_with_address(const char *addr){
|
|||
}
|
||||
fr=linphone_friend_new();
|
||||
linphone_friend_set_address(fr,linphone_address);
|
||||
linphone_address_destroy(linphone_address);
|
||||
linphone_address_unref(linphone_address);
|
||||
return fr;
|
||||
}
|
||||
|
||||
|
|
@ -138,8 +155,8 @@ void* linphone_friend_get_user_data(const LinphoneFriend *lf){
|
|||
return lf->user_data;
|
||||
}
|
||||
|
||||
bool_t linphone_friend_in_list(const LinphoneFriend *lf){
|
||||
return lf->in_list;
|
||||
bool_t linphone_friend_in_list(const LinphoneFriend *lf) {
|
||||
return lf->friend_list != NULL;
|
||||
}
|
||||
|
||||
void linphone_core_interpret_friend_uri(LinphoneCore *lc, const char *uri, char **result){
|
||||
|
|
@ -163,7 +180,7 @@ void linphone_core_interpret_friend_uri(LinphoneCore *lc, const char *uri, char
|
|||
linphone_address_set_display_name(id,NULL);
|
||||
linphone_address_set_username(id,uri);
|
||||
*result=linphone_address_as_string(id);
|
||||
linphone_address_destroy(id);
|
||||
linphone_address_unref(id);
|
||||
}
|
||||
}
|
||||
if (*result){
|
||||
|
|
@ -174,25 +191,51 @@ void linphone_core_interpret_friend_uri(LinphoneCore *lc, const char *uri, char
|
|||
}
|
||||
}else {
|
||||
*result=linphone_address_as_string(fr);
|
||||
linphone_address_destroy(fr);
|
||||
linphone_address_unref(fr);
|
||||
}
|
||||
}
|
||||
|
||||
int linphone_friend_set_address(LinphoneFriend *lf, const LinphoneAddress *addr){
|
||||
LinphoneAddress *fr=linphone_address_clone(addr);
|
||||
LinphoneAddress *fr = linphone_address_clone(addr);
|
||||
LinphoneVCard *vcard = NULL;
|
||||
|
||||
linphone_address_clean(fr);
|
||||
if (lf->uri!=NULL) linphone_address_destroy(lf->uri);
|
||||
lf->uri=fr;
|
||||
if (lf->uri != NULL) linphone_address_unref(lf->uri);
|
||||
lf->uri = fr;
|
||||
|
||||
vcard = linphone_friend_get_vcard(lf);
|
||||
if (vcard) {
|
||||
linphone_vcard_edit_main_sip_address(vcard, linphone_address_as_string_uri_only(fr));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int linphone_friend_set_name(LinphoneFriend *lf, const char *name){
|
||||
LinphoneAddress *fr=lf->uri;
|
||||
if (fr==NULL){
|
||||
ms_error("linphone_friend_set_sip_addr() must be called before linphone_friend_set_name().");
|
||||
return -1;
|
||||
LinphoneAddress *fr = lf->uri;
|
||||
LinphoneVCard *vcard = NULL;
|
||||
bool_t vcard_created = FALSE;
|
||||
|
||||
vcard = linphone_friend_get_vcard(lf);
|
||||
if (!vcard) {
|
||||
linphone_friend_create_vcard(lf, name);
|
||||
vcard = linphone_friend_get_vcard(lf);
|
||||
vcard_created = TRUE;
|
||||
}
|
||||
linphone_address_set_display_name(fr,name);
|
||||
if (vcard) {
|
||||
linphone_vcard_set_full_name(vcard, name);
|
||||
if (fr && vcard_created) { // SIP address wasn't set yet, let's do it
|
||||
linphone_vcard_edit_main_sip_address(vcard, linphone_address_as_string_uri_only(fr));
|
||||
}
|
||||
}
|
||||
|
||||
if (!fr && !vcard) {
|
||||
ms_warning("linphone_friend_set_address() must be called before linphone_friend_set_name() to be able to set display name.");
|
||||
return -1;
|
||||
} else if (fr) {
|
||||
linphone_address_set_display_name(fr, name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -201,8 +244,7 @@ int linphone_friend_enable_subscribes(LinphoneFriend *fr, bool_t val){
|
|||
return 0;
|
||||
}
|
||||
|
||||
int linphone_friend_set_inc_subscribe_policy(LinphoneFriend *fr, LinphoneSubscribePolicy pol)
|
||||
{
|
||||
int linphone_friend_set_inc_subscribe_policy(LinphoneFriend *fr, LinphoneSubscribePolicy pol) {
|
||||
fr->pol=pol;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -276,8 +318,9 @@ static void _linphone_friend_release_ops(LinphoneFriend *lf){
|
|||
static void _linphone_friend_destroy(LinphoneFriend *lf){
|
||||
_linphone_friend_release_ops(lf);
|
||||
if (lf->presence != NULL) linphone_presence_model_unref(lf->presence);
|
||||
if (lf->uri!=NULL) linphone_address_destroy(lf->uri);
|
||||
if (lf->uri!=NULL) linphone_address_unref(lf->uri);
|
||||
if (lf->info!=NULL) buddy_info_free(lf->info);
|
||||
if (lf->vcard != NULL) linphone_vcard_free(lf->vcard);
|
||||
}
|
||||
|
||||
static belle_sip_error_code _linphone_friend_marshall(belle_sip_object_t *obj, char* buff, size_t buff_size, size_t *offset) {
|
||||
|
|
@ -296,9 +339,13 @@ const LinphoneAddress *linphone_friend_get_address(const LinphoneFriend *lf){
|
|||
}
|
||||
|
||||
const char * linphone_friend_get_name(const LinphoneFriend *lf) {
|
||||
LinphoneAddress *fr = lf->uri;
|
||||
if (fr == NULL) return NULL;
|
||||
return linphone_address_get_display_name(fr);
|
||||
if (lf && lf->vcard) {
|
||||
return linphone_vcard_get_full_name(lf->vcard);
|
||||
} else if (lf && lf->uri) {
|
||||
LinphoneAddress *fr = lf->uri;
|
||||
return linphone_address_get_display_name(fr);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool_t linphone_friend_get_send_subscribe(const LinphoneFriend *lf){
|
||||
|
|
@ -439,48 +486,65 @@ void linphone_friend_update_subscribes(LinphoneFriend *fr, LinphoneProxyConfig *
|
|||
}
|
||||
}
|
||||
|
||||
void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc){
|
||||
void linphone_friend_save(LinphoneFriend *fr, LinphoneCore *lc) {
|
||||
#ifdef FRIENDS_SQL_STORAGE_ENABLED
|
||||
linphone_core_store_friend_in_db(lc, fr);
|
||||
#else
|
||||
linphone_core_write_friends_config(lc);
|
||||
#endif
|
||||
}
|
||||
|
||||
void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc) {
|
||||
LinphonePresenceModel *model;
|
||||
|
||||
if (fr->uri==NULL) {
|
||||
if (!fr->uri) {
|
||||
ms_warning("No sip url defined.");
|
||||
return;
|
||||
}
|
||||
|
||||
linphone_core_write_friends_config(lc);
|
||||
|
||||
if (fr->inc_subscribe_pending){
|
||||
switch(fr->pol){
|
||||
if (fr->inc_subscribe_pending) {
|
||||
switch(fr->pol) {
|
||||
case LinphoneSPWait:
|
||||
model = linphone_presence_model_new_with_activity(LinphonePresenceActivityOther, "Waiting for user acceptance");
|
||||
linphone_friend_notify(fr,model);
|
||||
linphone_friend_notify(fr, model);
|
||||
linphone_presence_model_unref(model);
|
||||
break;
|
||||
case LinphoneSPAccept:
|
||||
if (fr->lc!=NULL)
|
||||
linphone_friend_notify(fr,fr->lc->presence_model);
|
||||
if (fr->lc)
|
||||
linphone_friend_notify(fr, fr->lc->presence_model);
|
||||
break;
|
||||
case LinphoneSPDeny:
|
||||
linphone_friend_notify(fr,NULL);
|
||||
linphone_friend_notify(fr, NULL);
|
||||
break;
|
||||
}
|
||||
fr->inc_subscribe_pending=FALSE;
|
||||
fr->inc_subscribe_pending = FALSE;
|
||||
}
|
||||
if (fr->lc) {
|
||||
linphone_friend_list_update_subscriptions(fr->lc->friendlist, NULL, linphone_core_should_subscribe_friends_only_when_registered(fr->lc));
|
||||
linphone_friend_list_update_subscriptions(fr->friend_list, NULL, linphone_core_should_subscribe_friends_only_when_registered(fr->lc));
|
||||
}
|
||||
ms_message("linphone_friend_apply() done.");
|
||||
ms_debug("linphone_friend_apply() done.");
|
||||
lc->bl_refresh=TRUE;
|
||||
fr->commit=FALSE;
|
||||
}
|
||||
|
||||
void linphone_friend_edit(LinphoneFriend *fr){
|
||||
void linphone_friend_edit(LinphoneFriend *fr) {
|
||||
if (fr && fr->vcard) {
|
||||
linphone_vcard_compute_md5_hash(fr->vcard);
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_friend_done(LinphoneFriend *fr){
|
||||
ms_return_if_fail(fr!=NULL);
|
||||
if (fr->lc == NULL || !fr->in_list) return;
|
||||
linphone_friend_apply(fr,fr->lc);
|
||||
void linphone_friend_done(LinphoneFriend *fr) {
|
||||
ms_return_if_fail(fr);
|
||||
if (!fr->lc || !fr->friend_list) return;
|
||||
linphone_friend_apply(fr, fr->lc);
|
||||
linphone_friend_save(fr, fr->lc);
|
||||
|
||||
if (fr && fr->vcard) {
|
||||
if (linphone_vcard_compare_md5_hash(fr->vcard) != 0) {
|
||||
ms_debug("vCard's md5 has changed, mark friend as dirty");
|
||||
fr->friend_list->dirty_friends_to_update = ms_list_append(fr->friend_list->dirty_friends_to_update, linphone_friend_ref(fr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4)
|
||||
|
|
@ -504,94 +568,132 @@ LinphoneFriend * linphone_core_create_friend_with_address(LinphoneCore *lc, cons
|
|||
#endif
|
||||
|
||||
void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *lf) {
|
||||
if ((lc->friendlist == NULL) || (linphone_friend_list_add_friend(lc->friendlist, lf) != LinphoneFriendListOK)) return;
|
||||
if (linphone_friend_list_add_friend(linphone_core_get_default_friend_list(lc), lf) != LinphoneFriendListOK) return;
|
||||
if (ms_list_find(lc->subscribers, lf)) {
|
||||
/*if this friend was in the pending subscriber list, now remove it from this list*/
|
||||
lc->subscribers = ms_list_remove(lc->subscribers, lf);
|
||||
linphone_friend_unref(lf);
|
||||
}
|
||||
lf->lc = lc; /*I would prefer this to be done in linphone_friend_list_add_friend()*/
|
||||
if (linphone_core_ready(lc)) linphone_friend_apply(lf, lc);
|
||||
else lf->commit = TRUE;
|
||||
linphone_friend_save(lf, lc);
|
||||
}
|
||||
|
||||
void linphone_core_remove_friend(LinphoneCore *lc, LinphoneFriend *lf) {
|
||||
if (linphone_friend_list_remove_friend(lc->friendlist, lf) == LinphoneFriendListNonExistentFriend) {
|
||||
ms_error("linphone_core_remove_friend(): friend [%p] is not part of core's list.", lf);
|
||||
if (lf && lf->friend_list) {
|
||||
if (linphone_friend_list_remove_friend(lf->friend_list, lf) == LinphoneFriendListNonExistentFriend) {
|
||||
ms_error("linphone_core_remove_friend(): friend [%p] is not part of core's list.", lf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_core_update_friends_subscriptions(LinphoneCore *lc, LinphoneProxyConfig *cfg, bool_t only_when_registered){
|
||||
if (lc->friendlist != NULL)
|
||||
linphone_friend_list_update_subscriptions(lc->friendlist, cfg, only_when_registered);
|
||||
void linphone_core_update_friends_subscriptions(LinphoneCore *lc, LinphoneProxyConfig *cfg, bool_t only_when_registered) {
|
||||
MSList *lists = lc->friends_lists;
|
||||
while (lists) {
|
||||
LinphoneFriendList *list = (LinphoneFriendList *)lists->data;
|
||||
linphone_friend_list_update_subscriptions(list, cfg, only_when_registered);
|
||||
lists = ms_list_next(lists);
|
||||
}
|
||||
}
|
||||
|
||||
bool_t linphone_core_should_subscribe_friends_only_when_registered(const LinphoneCore *lc){
|
||||
return lp_config_get_int(lc->config,"sip","subscribe_presence_only_when_registered",1);
|
||||
}
|
||||
|
||||
void linphone_core_send_initial_subscribes(LinphoneCore *lc){
|
||||
void linphone_core_send_initial_subscribes(LinphoneCore *lc) {
|
||||
MSList *lists = lc->friends_lists;
|
||||
bool_t proxy_config_for_rls_presence_uri_domain = FALSE;
|
||||
LinphoneAddress *rls_address = NULL;
|
||||
const MSList *elem;
|
||||
|
||||
if (lc->initial_subscribes_sent) return;
|
||||
lc->initial_subscribes_sent=TRUE;
|
||||
if (lc->friendlist->rls_uri != NULL) {
|
||||
rls_address = linphone_core_create_address(lc, lc->friendlist->rls_uri);
|
||||
}
|
||||
if (rls_address != NULL) {
|
||||
const char *rls_domain = linphone_address_get_domain(rls_address);
|
||||
if (rls_domain != NULL) {
|
||||
for (elem = linphone_core_get_proxy_config_list(lc); elem != NULL; elem = elem->next) {
|
||||
LinphoneProxyConfig *cfg = (LinphoneProxyConfig *)elem->data;
|
||||
const char *proxy_domain = linphone_proxy_config_get_domain(cfg);
|
||||
if (strcmp(rls_domain, proxy_domain) == 0) {
|
||||
proxy_config_for_rls_presence_uri_domain = TRUE;
|
||||
break;
|
||||
while (lists) {
|
||||
LinphoneFriendList *list = (LinphoneFriendList *)lists->data;
|
||||
if (list->rls_uri != NULL) {
|
||||
rls_address = linphone_core_create_address(lc, list->rls_uri);
|
||||
if (rls_address != NULL) {
|
||||
const char *rls_domain = linphone_address_get_domain(rls_address);
|
||||
if (rls_domain != NULL) {
|
||||
for (elem = linphone_core_get_proxy_config_list(lc); elem != NULL; elem = elem->next) {
|
||||
LinphoneProxyConfig *cfg = (LinphoneProxyConfig *)elem->data;
|
||||
const char *proxy_domain = linphone_proxy_config_get_domain(cfg);
|
||||
if (strcmp(rls_domain, proxy_domain) == 0) {
|
||||
proxy_config_for_rls_presence_uri_domain = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
linphone_address_unref(rls_address);
|
||||
}
|
||||
if (proxy_config_for_rls_presence_uri_domain == TRUE) {
|
||||
ms_message("Presence list activated so do not send initial subscribes it will be done when registered");
|
||||
} else {
|
||||
linphone_core_update_friends_subscriptions(lc,NULL,linphone_core_should_subscribe_friends_only_when_registered(lc));
|
||||
}
|
||||
}
|
||||
linphone_address_unref(rls_address);
|
||||
}
|
||||
if (proxy_config_for_rls_presence_uri_domain == TRUE) {
|
||||
ms_message("Presence list activated so do not send initial subscribes it will be done when registered");
|
||||
} else {
|
||||
linphone_core_update_friends_subscriptions(lc,NULL,linphone_core_should_subscribe_friends_only_when_registered(lc));
|
||||
lists = ms_list_next(lists);
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_core_invalidate_friend_subscriptions(LinphoneCore *lc){
|
||||
if (lc->friendlist != NULL)
|
||||
linphone_friend_list_invalidate_subscriptions(lc->friendlist);
|
||||
void linphone_core_invalidate_friend_subscriptions(LinphoneCore *lc) {
|
||||
MSList *lists = lc->friends_lists;
|
||||
while (lists) {
|
||||
LinphoneFriendList *list = (LinphoneFriendList *)lists->data;
|
||||
linphone_friend_list_invalidate_subscriptions(list);
|
||||
lists = ms_list_next(lists);
|
||||
}
|
||||
lc->initial_subscribes_sent=FALSE;
|
||||
}
|
||||
|
||||
void linphone_friend_set_ref_key(LinphoneFriend *lf, const char *key){
|
||||
if (lf->refkey!=NULL){
|
||||
if (lf->refkey != NULL) {
|
||||
ms_free(lf->refkey);
|
||||
lf->refkey=NULL;
|
||||
lf->refkey = NULL;
|
||||
}
|
||||
if (key) {
|
||||
lf->refkey = ms_strdup(key);
|
||||
}
|
||||
if (lf->lc) {
|
||||
linphone_friend_save(lf, lf->lc);
|
||||
}
|
||||
if (key)
|
||||
lf->refkey=ms_strdup(key);
|
||||
if (lf->lc)
|
||||
linphone_core_write_friends_config(lf->lc);
|
||||
}
|
||||
|
||||
const char *linphone_friend_get_ref_key(const LinphoneFriend *lf){
|
||||
return lf->refkey;
|
||||
}
|
||||
|
||||
LinphoneFriend *linphone_core_find_friend(const LinphoneCore *lc, const LinphoneAddress *addr){
|
||||
return linphone_friend_list_find_friend_by_address(lc->friendlist, addr);
|
||||
LinphoneFriend *linphone_core_find_friend(const LinphoneCore *lc, const LinphoneAddress *addr) {
|
||||
MSList *lists = lc->friends_lists;
|
||||
LinphoneFriend *lf = NULL;
|
||||
while (lists && !lf) {
|
||||
LinphoneFriendList *list = (LinphoneFriendList *)lists->data;
|
||||
lf = linphone_friend_list_find_friend_by_address(list, addr);
|
||||
lists = ms_list_next(lists);
|
||||
}
|
||||
return lf;
|
||||
}
|
||||
|
||||
LinphoneFriend *linphone_core_get_friend_by_address(const LinphoneCore *lc, const char *uri){
|
||||
return linphone_friend_list_find_friend_by_uri(lc->friendlist, uri);
|
||||
LinphoneFriend *linphone_core_get_friend_by_address(const LinphoneCore *lc, const char *uri) {
|
||||
MSList *lists = lc->friends_lists;
|
||||
LinphoneFriend *lf = NULL;
|
||||
while (lists && !lf) {
|
||||
LinphoneFriendList *list = (LinphoneFriendList *)lists->data;
|
||||
lf = linphone_friend_list_find_friend_by_uri(list, uri);
|
||||
lists = ms_list_next(lists);
|
||||
}
|
||||
return lf;
|
||||
}
|
||||
|
||||
LinphoneFriend *linphone_core_get_friend_by_ref_key(const LinphoneCore *lc, const char *key){
|
||||
return linphone_friend_list_find_friend_by_ref_key(lc->friendlist, key);
|
||||
LinphoneFriend *linphone_core_get_friend_by_ref_key(const LinphoneCore *lc, const char *key) {
|
||||
MSList *lists = lc->friends_lists;
|
||||
LinphoneFriend *lf = NULL;
|
||||
while (lists && !lf) {
|
||||
LinphoneFriendList *list = (LinphoneFriendList *)lists->data;
|
||||
lf = linphone_friend_list_find_friend_by_ref_key(list, key);
|
||||
lists = ms_list_next(lists);
|
||||
}
|
||||
return lf;
|
||||
}
|
||||
|
||||
#define key_compare(s1,s2) strcmp(s1,s2)
|
||||
|
|
@ -695,15 +797,18 @@ void linphone_friend_write_to_config_file(LpConfig *config, LinphoneFriend *lf,
|
|||
}
|
||||
}
|
||||
|
||||
void linphone_core_write_friends_config(LinphoneCore* lc)
|
||||
{
|
||||
void linphone_core_write_friends_config(LinphoneCore* lc) {
|
||||
MSList *elem;
|
||||
int i;
|
||||
int store_friends;
|
||||
#ifdef FRIENDS_SQL_STORAGE_ENABLED
|
||||
return;
|
||||
#endif
|
||||
if (! linphone_core_ready(lc)) return; /*dont write config when reading it !*/
|
||||
store_friends = lp_config_get_int(lc->config, "misc", "store_friends", 1);
|
||||
if (store_friends) {
|
||||
for (elem=lc->friendlist->friends,i=0; elem!=NULL; elem=ms_list_next(elem),i++){
|
||||
|
||||
for (elem=linphone_core_get_default_friend_list(lc)->friends,i=0; elem!=NULL; elem=ms_list_next(elem),i++){
|
||||
linphone_friend_write_to_config_file(lc->config,(LinphoneFriend*)elem->data,i);
|
||||
}
|
||||
linphone_friend_write_to_config_file(lc->config,NULL,i); /* set the end */
|
||||
|
|
@ -728,6 +833,97 @@ void linphone_friend_destroy(LinphoneFriend *lf) {
|
|||
linphone_friend_unref(lf);
|
||||
}
|
||||
|
||||
LinphoneVCard* linphone_friend_get_vcard(LinphoneFriend *fr) {
|
||||
if (fr) {
|
||||
return fr->vcard;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void linphone_friend_set_vcard(LinphoneFriend *fr, LinphoneVCard *vcard) {
|
||||
if (!fr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (fr->vcard) {
|
||||
linphone_vcard_free(fr->vcard);
|
||||
}
|
||||
fr->vcard = vcard;
|
||||
linphone_friend_save(fr, fr->lc);
|
||||
}
|
||||
|
||||
bool_t linphone_friend_create_vcard(LinphoneFriend *fr, const char *name) {
|
||||
LinphoneVCard *vcard = NULL;
|
||||
const char *fullName = NULL;
|
||||
LinphoneAddress *addr = NULL;
|
||||
|
||||
if (!fr || fr->vcard) {
|
||||
ms_error("Friend is either null or already has a vcard");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
addr = fr->uri;
|
||||
if (!addr && !name) {
|
||||
ms_error("friend doesn't have an URI and name parameter is null");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (name) {
|
||||
fullName = name;
|
||||
} else {
|
||||
const char *displayName = linphone_address_get_display_name(addr);
|
||||
if (!displayName) {
|
||||
fullName = linphone_address_get_username(addr);
|
||||
} else {
|
||||
fullName = displayName;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fullName) {
|
||||
ms_error("Couldn't determine the name to use for the vCard");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
vcard = linphone_vcard_new();
|
||||
linphone_vcard_set_full_name(vcard, fullName);
|
||||
linphone_friend_set_vcard(fr, vcard);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
LinphoneFriend *linphone_friend_new_from_vcard(LinphoneVCard *vcard) {
|
||||
LinphoneAddress* linphone_address = NULL;
|
||||
LinphoneFriend *fr;
|
||||
const char *name = NULL;
|
||||
MSList *sipAddresses = NULL;
|
||||
|
||||
if (vcard == NULL) {
|
||||
ms_error("Cannot create friend from null vcard");
|
||||
return NULL;
|
||||
}
|
||||
name = linphone_vcard_get_full_name(vcard);
|
||||
sipAddresses = linphone_vcard_get_sip_addresses(vcard);
|
||||
|
||||
fr = linphone_friend_new();
|
||||
// Currently presence takes too much time when dealing with hundreds of friends, so I disabled it for now
|
||||
fr->pol = LinphoneSPDeny;
|
||||
fr->subscribe = FALSE;
|
||||
|
||||
if (sipAddresses) {
|
||||
const char *sipAddress = (const char *)sipAddresses->data;
|
||||
linphone_address = linphone_address_new(sipAddress);
|
||||
if (linphone_address) {
|
||||
linphone_friend_set_address(fr, linphone_address);
|
||||
linphone_address_unref(linphone_address);
|
||||
}
|
||||
}
|
||||
if (name) {
|
||||
linphone_friend_set_name(fr, name);
|
||||
}
|
||||
fr->vcard = vcard;
|
||||
|
||||
return fr;
|
||||
}
|
||||
|
||||
/*drops all references to the core and unref*/
|
||||
void _linphone_friend_release(LinphoneFriend *lf){
|
||||
lf->lc = NULL;
|
||||
|
|
@ -743,3 +939,447 @@ BELLE_SIP_INSTANCIATE_VPTR(LinphoneFriend, belle_sip_object_t,
|
|||
_linphone_friend_marshall,
|
||||
FALSE
|
||||
);
|
||||
|
||||
/*******************************************************************************
|
||||
* SQL storage related functions *
|
||||
******************************************************************************/
|
||||
|
||||
#ifdef FRIENDS_SQL_STORAGE_ENABLED
|
||||
|
||||
static void linphone_create_table(sqlite3* db) {
|
||||
char* errmsg = NULL;
|
||||
int ret;
|
||||
ret = sqlite3_exec(db,"CREATE TABLE IF NOT EXISTS friends ("
|
||||
"id INTEGER PRIMARY KEY AUTOINCREMENT,"
|
||||
"friend_list_id INTEGER,"
|
||||
"sip_uri TEXT NOT NULL,"
|
||||
"subscribe_policy INTEGER,"
|
||||
"send_subscribe INTEGER,"
|
||||
"ref_key TEXT,"
|
||||
"vCard TEXT,"
|
||||
"vCard_etag TEXT,"
|
||||
"vCard_url TEXT,"
|
||||
"presence_received INTEGER"
|
||||
");",
|
||||
0, 0, &errmsg);
|
||||
if (ret != SQLITE_OK) {
|
||||
ms_error("Error in creation: %s.\n", errmsg);
|
||||
sqlite3_free(errmsg);
|
||||
}
|
||||
|
||||
ret = sqlite3_exec(db,"CREATE TABLE IF NOT EXISTS friends_lists ("
|
||||
"id INTEGER PRIMARY KEY AUTOINCREMENT,"
|
||||
"display_name TEXT,"
|
||||
"rls_uri TEXT,"
|
||||
"uri TEXT,"
|
||||
"revision INTEGER"
|
||||
");",
|
||||
0, 0, &errmsg);
|
||||
if (ret != SQLITE_OK) {
|
||||
ms_error("Error in creation: %s.\n", errmsg);
|
||||
sqlite3_free(errmsg);
|
||||
}
|
||||
}
|
||||
|
||||
static void linphone_update_table(sqlite3* db) {
|
||||
|
||||
}
|
||||
|
||||
void linphone_core_friends_storage_init(LinphoneCore *lc) {
|
||||
int ret;
|
||||
const char *errmsg;
|
||||
sqlite3 *db;
|
||||
const MSList *friends_lists = NULL;
|
||||
|
||||
linphone_core_friends_storage_close(lc);
|
||||
|
||||
ret = _linphone_sqlite3_open(lc->friends_db_file, &db);
|
||||
if (ret != SQLITE_OK) {
|
||||
errmsg = sqlite3_errmsg(db);
|
||||
ms_error("Error in the opening: %s.\n", errmsg);
|
||||
sqlite3_close(db);
|
||||
return;
|
||||
}
|
||||
|
||||
linphone_create_table(db);
|
||||
linphone_update_table(db);
|
||||
lc->friends_db = db;
|
||||
|
||||
friends_lists = linphone_core_fetch_friends_lists_from_db(lc);
|
||||
if (friends_lists) {
|
||||
ms_warning("Replacing current default friend list by the one(s) from the database");
|
||||
lc->friends_lists = ms_list_free_with_data(lc->friends_lists, (void (*)(void*))linphone_friend_list_unref);
|
||||
lc->friends_lists = NULL;
|
||||
|
||||
while (friends_lists) {
|
||||
LinphoneFriendList *list = (LinphoneFriendList *)friends_lists->data;
|
||||
linphone_core_add_friend_list(lc, list);
|
||||
friends_lists = ms_list_next(friends_lists);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_core_friends_storage_close(LinphoneCore *lc) {
|
||||
if (lc->friends_db) {
|
||||
sqlite3_close(lc->friends_db);
|
||||
lc->friends_db = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* DB layout:
|
||||
* | 0 | storage_id
|
||||
* | 1 | display_name
|
||||
* | 2 | rls_uri
|
||||
* | 3 | uri
|
||||
* | 4 | revision
|
||||
*/
|
||||
static int create_friend_list(void *data, int argc, char **argv, char **colName) {
|
||||
MSList **list = (MSList **)data;
|
||||
unsigned int storage_id = atoi(argv[0]);
|
||||
LinphoneFriendList *lfl = linphone_core_create_friend_list(NULL);
|
||||
|
||||
lfl->storage_id = storage_id;
|
||||
linphone_friend_list_set_display_name(lfl, argv[1]);
|
||||
linphone_friend_list_set_rls_uri(lfl, argv[2]);
|
||||
linphone_friend_list_set_uri(lfl, argv[3]);
|
||||
lfl->revision = atoi(argv[4]);
|
||||
|
||||
*list = ms_list_append(*list, linphone_friend_list_ref(lfl));
|
||||
linphone_friend_list_unref(lfl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* DB layout:
|
||||
* | 0 | storage_id
|
||||
* | 1 | friend_list_id
|
||||
* | 2 | sip_uri
|
||||
* | 3 | subscribe_policy
|
||||
* | 4 | send_subscribe
|
||||
* | 5 | ref_key
|
||||
* | 6 | vCard
|
||||
* | 7 | vCard eTag
|
||||
* | 8 | vCard URL
|
||||
* | 9 | presence_received
|
||||
*/
|
||||
static int create_friend(void *data, int argc, char **argv, char **colName) {
|
||||
MSList **list = (MSList **)data;
|
||||
LinphoneFriend *lf = NULL;
|
||||
LinphoneVCard *vcard = NULL;
|
||||
unsigned int storage_id = atoi(argv[0]);
|
||||
|
||||
vcard = linphone_vcard_new_from_vcard4_buffer(argv[6]);
|
||||
if (vcard) {
|
||||
linphone_vcard_set_etag(vcard, argv[7]);
|
||||
linphone_vcard_set_url(vcard, argv[8]);
|
||||
lf = linphone_friend_new_from_vcard(vcard);
|
||||
}
|
||||
if (!lf) {
|
||||
LinphoneAddress *addr = linphone_address_new(argv[2]);
|
||||
lf = linphone_friend_new();
|
||||
linphone_friend_set_address(lf, addr);
|
||||
linphone_address_unref(addr);
|
||||
}
|
||||
linphone_friend_set_inc_subscribe_policy(lf, atoi(argv[3]));
|
||||
linphone_friend_send_subscribe(lf, atoi(argv[4]));
|
||||
linphone_friend_set_ref_key(lf, ms_strdup(argv[5]));
|
||||
lf->presence_received = atoi(argv[9]);
|
||||
lf->storage_id = storage_id;
|
||||
|
||||
*list = ms_list_append(*list, linphone_friend_ref(lf));
|
||||
linphone_friend_unref(lf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int linphone_sql_request_friend(sqlite3* db, const char *stmt, MSList **list) {
|
||||
char* errmsg = NULL;
|
||||
int ret;
|
||||
ret = sqlite3_exec(db, stmt, create_friend, list, &errmsg);
|
||||
if (ret != SQLITE_OK) {
|
||||
ms_error("linphone_sql_request: statement %s -> error sqlite3_exec(): %s.", stmt, errmsg);
|
||||
sqlite3_free(errmsg);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int linphone_sql_request_friends_list(sqlite3* db, const char *stmt, MSList **list) {
|
||||
char* errmsg = NULL;
|
||||
int ret;
|
||||
ret = sqlite3_exec(db, stmt, create_friend_list, list, &errmsg);
|
||||
if (ret != SQLITE_OK) {
|
||||
ms_error("linphone_sql_request: statement %s -> error sqlite3_exec(): %s.", stmt, errmsg);
|
||||
sqlite3_free(errmsg);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int linphone_sql_request_generic(sqlite3* db, const char *stmt) {
|
||||
char* errmsg = NULL;
|
||||
int ret;
|
||||
ret = sqlite3_exec(db, stmt, NULL, NULL, &errmsg);
|
||||
if (ret != SQLITE_OK) {
|
||||
ms_error("linphone_sql_request: statement %s -> error sqlite3_exec(): %s.", stmt, errmsg);
|
||||
sqlite3_free(errmsg);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void linphone_core_store_friend_in_db(LinphoneCore *lc, LinphoneFriend *lf) {
|
||||
if (lc && lc->friends_db) {
|
||||
char *buf;
|
||||
int store_friends = lp_config_get_int(lc->config, "misc", "store_friends", 1);
|
||||
LinphoneVCard *vcard = linphone_friend_get_vcard(lf);
|
||||
|
||||
if (!store_friends) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!lf || !lf->friend_list) {
|
||||
ms_warning("Either the friend or the friend list is null, skipping...");
|
||||
return;
|
||||
}
|
||||
|
||||
if (lf->friend_list->storage_id == 0) {
|
||||
ms_warning("Trying to add a friend in db, but friend list isn't, let's do that first");
|
||||
linphone_core_store_friends_list_in_db(lc, lf->friend_list);
|
||||
}
|
||||
|
||||
if (lf->storage_id > 0) {
|
||||
buf = sqlite3_mprintf("UPDATE friends SET friend_list_id=%i,sip_uri=%Q,subscribe_policy=%i,send_subscribe=%i,ref_key=%Q,vCard=%Q,vCard_etag=%Q,vCard_url=%Q,presence_received=%i WHERE (id = %i);",
|
||||
lf->friend_list->storage_id,
|
||||
linphone_address_as_string(linphone_friend_get_address(lf)),
|
||||
lf->pol,
|
||||
lf->subscribe,
|
||||
lf->refkey,
|
||||
linphone_vcard_as_vcard4_string(vcard),
|
||||
linphone_vcard_get_etag(vcard),
|
||||
linphone_vcard_get_url(vcard),
|
||||
lf->presence_received,
|
||||
lf->storage_id
|
||||
);
|
||||
} else {
|
||||
buf = sqlite3_mprintf("INSERT INTO friends VALUES(NULL,%i,%Q,%i,%i,%Q,%Q,%Q,%Q,%i);",
|
||||
lf->friend_list->storage_id,
|
||||
linphone_address_as_string(linphone_friend_get_address(lf)),
|
||||
lf->pol,
|
||||
lf->subscribe,
|
||||
lf->refkey,
|
||||
linphone_vcard_as_vcard4_string(vcard),
|
||||
linphone_vcard_get_etag(vcard),
|
||||
linphone_vcard_get_url(vcard),
|
||||
lf->presence_received
|
||||
);
|
||||
}
|
||||
linphone_sql_request_generic(lc->friends_db, buf);
|
||||
sqlite3_free(buf);
|
||||
|
||||
if (lf->storage_id == 0) {
|
||||
lf->storage_id = sqlite3_last_insert_rowid(lc->friends_db);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_core_store_friends_list_in_db(LinphoneCore *lc, LinphoneFriendList *list) {
|
||||
if (lc && lc->friends_db) {
|
||||
char *buf;
|
||||
int store_friends = lp_config_get_int(lc->config, "misc", "store_friends", 1);
|
||||
|
||||
if (!store_friends) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (list->storage_id > 0) {
|
||||
buf = sqlite3_mprintf("UPDATE friends_lists SET display_name=%Q,rls_uri=%Q,uri=%Q,revision=%i WHERE (id = %i);",
|
||||
list->display_name,
|
||||
list->rls_uri,
|
||||
list->uri,
|
||||
list->revision,
|
||||
list->storage_id
|
||||
);
|
||||
} else {
|
||||
buf = sqlite3_mprintf("INSERT INTO friends_lists VALUES(NULL,%Q,%Q,%Q,%i);",
|
||||
list->display_name,
|
||||
list->rls_uri,
|
||||
list->uri,
|
||||
list->revision
|
||||
);
|
||||
}
|
||||
linphone_sql_request_generic(lc->friends_db, buf);
|
||||
sqlite3_free(buf);
|
||||
|
||||
if (list->storage_id == 0) {
|
||||
list->storage_id = sqlite3_last_insert_rowid(lc->friends_db);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_core_remove_friend_from_db(LinphoneCore *lc, LinphoneFriend *lf) {
|
||||
if (lc && lc->friends_db) {
|
||||
char *buf;
|
||||
if (lf->storage_id == 0) {
|
||||
ms_error("Friend doesn't have a storage_id !");
|
||||
return;
|
||||
}
|
||||
|
||||
buf = sqlite3_mprintf("DELETE FROM friends WHERE id = %i", lf->storage_id);
|
||||
linphone_sql_request_generic(lc->friends_db, buf);
|
||||
sqlite3_free(buf);
|
||||
|
||||
lf->storage_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_core_remove_friends_list_from_db(LinphoneCore *lc, LinphoneFriendList *list) {
|
||||
if (lc && lc->friends_db) {
|
||||
char *buf;
|
||||
if (list->storage_id == 0) {
|
||||
ms_error("Friends list doesn't have a storage_id !");
|
||||
return;
|
||||
}
|
||||
|
||||
buf = sqlite3_mprintf("DELETE FROM friends_lists WHERE id = %i", list->storage_id);
|
||||
linphone_sql_request_generic(lc->friends_db, buf);
|
||||
sqlite3_free(buf);
|
||||
|
||||
list->storage_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc, LinphoneFriendList *list) {
|
||||
char *buf;
|
||||
uint64_t begin,end;
|
||||
MSList *result = NULL;
|
||||
MSList *elem = NULL;
|
||||
|
||||
if (!lc || lc->friends_db == NULL || list == NULL) {
|
||||
ms_warning("Either lc (or list) is NULL or friends database wasn't initialized with linphone_core_friends_storage_init() yet");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buf = sqlite3_mprintf("SELECT * FROM friends WHERE friend_list_id = %i ORDER BY id", list->storage_id);
|
||||
|
||||
begin = ortp_get_cur_time_ms();
|
||||
linphone_sql_request_friend(lc->friends_db, buf, &result);
|
||||
end = ortp_get_cur_time_ms();
|
||||
ms_message("%s(): %i results fetched, completed in %i ms",__FUNCTION__, ms_list_size(result), (int)(end-begin));
|
||||
sqlite3_free(buf);
|
||||
|
||||
for(elem = result; elem != NULL; elem = elem->next) {
|
||||
LinphoneFriend *lf = (LinphoneFriend *)elem->data;
|
||||
lf->lc = lc;
|
||||
lf->friend_list = list;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
MSList* linphone_core_fetch_friends_lists_from_db(LinphoneCore *lc) {
|
||||
char *buf;
|
||||
uint64_t begin,end;
|
||||
MSList *result = NULL;
|
||||
MSList *elem = NULL;
|
||||
|
||||
if (!lc || lc->friends_db == NULL) {
|
||||
ms_warning("Either lc is NULL or friends database wasn't initialized with linphone_core_friends_storage_init() yet");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buf = sqlite3_mprintf("SELECT * FROM friends_lists ORDER BY id");
|
||||
|
||||
begin = ortp_get_cur_time_ms();
|
||||
linphone_sql_request_friends_list(lc->friends_db, buf, &result);
|
||||
end = ortp_get_cur_time_ms();
|
||||
ms_message("%s(): %i results fetched, completed in %i ms",__FUNCTION__, ms_list_size(result), (int)(end-begin));
|
||||
sqlite3_free(buf);
|
||||
|
||||
for(elem = result; elem != NULL; elem = elem->next) {
|
||||
LinphoneFriendList *lfl = (LinphoneFriendList *)elem->data;
|
||||
lfl->lc = lc;
|
||||
lfl->friends = linphone_core_fetch_friends_from_db(lc, lfl);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void linphone_core_friends_storage_init(LinphoneCore *lc) {
|
||||
}
|
||||
|
||||
void linphone_core_friends_storage_close(LinphoneCore *lc) {
|
||||
}
|
||||
|
||||
void linphone_core_store_friend_in_db(LinphoneCore *lc, LinphoneFriend *lf) {
|
||||
}
|
||||
|
||||
void linphone_core_store_friends_list_in_db(LinphoneCore *lc, LinphoneFriendList *list) {
|
||||
}
|
||||
|
||||
void linphone_core_remove_friend_from_db(LinphoneCore *lc, LinphoneFriend *lf) {
|
||||
}
|
||||
|
||||
void linphone_core_remove_friends_list_from_db(LinphoneCore *lc, LinphoneFriendList *list) {
|
||||
}
|
||||
|
||||
MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc, LinphoneFriendList *list) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MSList* linphone_core_fetch_friends_lists_from_db(LinphoneCore *lc) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void linphone_core_set_friends_database_path(LinphoneCore *lc, const char *path) {
|
||||
if (lc->friends_db_file){
|
||||
ms_free(lc->friends_db_file);
|
||||
lc->friends_db_file = NULL;
|
||||
}
|
||||
if (path) {
|
||||
lc->friends_db_file = ms_strdup(path);
|
||||
linphone_core_friends_storage_init(lc);
|
||||
|
||||
linphone_core_migrate_friends_from_rc_to_db(lc);
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_core_migrate_friends_from_rc_to_db(LinphoneCore *lc) {
|
||||
LpConfig *lpc = NULL;
|
||||
LinphoneFriend *lf = NULL;
|
||||
LinphoneFriendList *lfl = linphone_core_get_default_friend_list(lc);
|
||||
int i;
|
||||
#ifndef FRIENDS_SQL_STORAGE_ENABLED
|
||||
ms_warning("linphone has been compiled without sqlite, can't migrate friends");
|
||||
return;
|
||||
#endif
|
||||
if (!lc) {
|
||||
return;
|
||||
}
|
||||
|
||||
lpc = linphone_core_get_config(lc);
|
||||
if (!lpc) {
|
||||
ms_warning("this core has been started without a rc file, nothing to migrate");
|
||||
return;
|
||||
}
|
||||
if (lp_config_get_int(lpc, "misc", "friends_migration_done", 0) == 1) {
|
||||
ms_warning("the friends migration has already been done, skipping...");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; (lf = linphone_friend_new_from_config_file(lc, i)) != NULL; i++) {
|
||||
char friend_section[32];
|
||||
|
||||
if (!linphone_friend_create_vcard(lf, linphone_address_get_username(linphone_friend_get_address(lf)))) {
|
||||
ms_warning("Couldn't create vCard for friend %s", linphone_address_as_string(linphone_friend_get_address(lf)));
|
||||
}
|
||||
|
||||
linphone_friend_list_add_friend(lfl, lf);
|
||||
linphone_friend_unref(lf);
|
||||
|
||||
snprintf(friend_section, sizeof(friend_section), "friend_%i", i);
|
||||
lp_config_clean_section(lpc, friend_section);
|
||||
}
|
||||
|
||||
ms_debug("friends migration successful: %i friends migrated", i);
|
||||
lp_config_set_int(lpc, "misc", "friends_migration_done", 1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,71 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#include <bctoolbox/crypto.h>
|
||||
|
||||
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneFriendListCbs);
|
||||
|
||||
BELLE_SIP_INSTANCIATE_VPTR(LinphoneFriendListCbs, belle_sip_object_t,
|
||||
NULL, // destroy
|
||||
NULL, // clone
|
||||
NULL, // Marshall
|
||||
FALSE
|
||||
);
|
||||
|
||||
static LinphoneFriendListCbs * linphone_friend_list_cbs_new(void) {
|
||||
return belle_sip_object_new(LinphoneFriendListCbs);
|
||||
}
|
||||
|
||||
LinphoneFriendListCbs * linphone_friend_list_get_callbacks(const LinphoneFriendList *list) {
|
||||
return list->cbs;
|
||||
}
|
||||
|
||||
LinphoneFriendListCbs * linphone_friend_list_cbs_ref(LinphoneFriendListCbs *cbs) {
|
||||
belle_sip_object_ref(cbs);
|
||||
return cbs;
|
||||
}
|
||||
|
||||
void linphone_friend_list_cbs_unref(LinphoneFriendListCbs *cbs) {
|
||||
belle_sip_object_unref(cbs);
|
||||
}
|
||||
|
||||
void *linphone_friend_list_cbs_get_user_data(const LinphoneFriendListCbs *cbs) {
|
||||
return cbs->user_data;
|
||||
}
|
||||
|
||||
void linphone_friend_list_cbs_set_user_data(LinphoneFriendListCbs *cbs, void *ud) {
|
||||
cbs->user_data = ud;
|
||||
}
|
||||
|
||||
LinphoneFriendListContactCreatedCb linphone_friend_list_cbs_get_contact_created(const LinphoneFriendListCbs *cbs) {
|
||||
return cbs->contact_created_cb;
|
||||
}
|
||||
|
||||
void linphone_friend_list_cbs_set_contact_created(LinphoneFriendListCbs *cbs, LinphoneFriendListContactCreatedCb cb) {
|
||||
cbs->contact_created_cb = cb;
|
||||
}
|
||||
|
||||
LinphoneFriendListContactDeletedCb linphone_friend_list_cbs_get_contact_deleted(const LinphoneFriendListCbs *cbs) {
|
||||
return cbs->contact_deleted_cb;
|
||||
}
|
||||
|
||||
void linphone_friend_list_cbs_set_contact_deleted(LinphoneFriendListCbs *cbs, LinphoneFriendListContactDeletedCb cb) {
|
||||
cbs->contact_deleted_cb = cb;
|
||||
}
|
||||
|
||||
LinphoneFriendListContactUpdatedCb linphone_friend_list_cbs_get_contact_updated(const LinphoneFriendListCbs *cbs) {
|
||||
return cbs->contact_updated_cb;
|
||||
}
|
||||
|
||||
void linphone_friend_list_cbs_set_contact_updated(LinphoneFriendListCbs *cbs, LinphoneFriendListContactUpdatedCb cb) {
|
||||
cbs->contact_updated_cb = cb;
|
||||
}
|
||||
|
||||
LinphoneFriendListSyncStateChangedCb linphone_friend_list_cbs_get_sync_status_changed(const LinphoneFriendListCbs *cbs) {
|
||||
return cbs->sync_state_changed_cb;
|
||||
}
|
||||
|
||||
void linphone_friend_list_cbs_set_sync_status_changed(LinphoneFriendListCbs *cbs, LinphoneFriendListSyncStateChangedCb cb) {
|
||||
cbs->sync_state_changed_cb = cb;
|
||||
}
|
||||
|
||||
static char * create_resource_list_xml(const LinphoneFriendList *list) {
|
||||
char *xml_content = NULL;
|
||||
|
|
@ -57,8 +122,8 @@ static char * create_resource_list_xml(const LinphoneFriendList *list) {
|
|||
err = xmlTextWriterStartElement(writer, (const xmlChar *)"list");
|
||||
}
|
||||
for (elem = list->friends; elem != NULL; elem = elem->next) {
|
||||
LinphoneFriend *friend = (LinphoneFriend *)elem->data;
|
||||
char *uri = linphone_address_as_string_uri_only(friend->uri);
|
||||
LinphoneFriend *lf = (LinphoneFriend *)elem->data;
|
||||
char *uri = linphone_address_as_string_uri_only(lf->uri);
|
||||
if (err >= 0) {
|
||||
err = xmlTextWriterStartElement(writer, (const xmlChar *)"entry");
|
||||
}
|
||||
|
|
@ -99,7 +164,7 @@ static void linphone_friend_list_parse_multipart_related_body(LinphoneFriendList
|
|||
xml_ctx->doc = xmlReadDoc((const unsigned char*)first_part_body, 0, NULL, 0);
|
||||
if (xml_ctx->doc != NULL) {
|
||||
char xpath_str[MAX_XPATH_LENGTH];
|
||||
LinphoneFriend *friend;
|
||||
LinphoneFriend *lf;
|
||||
LinphoneContent *presence_part;
|
||||
xmlXPathObjectPtr resource_object;
|
||||
const char *version_str = NULL;
|
||||
|
|
@ -133,8 +198,8 @@ static void linphone_friend_list_parse_multipart_related_body(LinphoneFriendList
|
|||
if ((strcmp(full_state_str, "true") == 0) || (strcmp(full_state_str, "1") == 0)) {
|
||||
MSList *l = list->friends;
|
||||
for (; l != NULL; l = l->next) {
|
||||
friend = (LinphoneFriend *)l->data;
|
||||
linphone_friend_set_presence_model(friend, NULL);
|
||||
lf = (LinphoneFriend *)l->data;
|
||||
linphone_friend_set_presence_model(lf, NULL);
|
||||
}
|
||||
full_state = TRUE;
|
||||
}
|
||||
|
|
@ -151,8 +216,8 @@ static void linphone_friend_list_parse_multipart_related_body(LinphoneFriendList
|
|||
snprintf(xpath_str, sizeof(xpath_str), "/rlmi:list/rlmi:resource[%i]/@uri", i);
|
||||
uri = linphone_get_xml_text_content(xml_ctx, xpath_str);
|
||||
if (uri == NULL) continue;
|
||||
friend = linphone_friend_list_find_friend_by_uri(list, uri);
|
||||
if (friend != NULL) {
|
||||
lf = linphone_friend_list_find_friend_by_uri(list, uri);
|
||||
if (lf != NULL) {
|
||||
const char *state = NULL;
|
||||
snprintf(xpath_str, sizeof(xpath_str),"/rlmi:list/rlmi:resource[%i]/rlmi:instance/@state", i);
|
||||
state = linphone_get_xml_text_content(xml_ctx, xpath_str);
|
||||
|
|
@ -168,10 +233,10 @@ static void linphone_friend_list_parse_multipart_related_body(LinphoneFriendList
|
|||
SalPresenceModel *presence = NULL;
|
||||
linphone_notify_parse_presence(linphone_content_get_type(presence_part), linphone_content_get_subtype(presence_part), linphone_content_get_string_buffer(presence_part), &presence);
|
||||
if (presence != NULL) {
|
||||
friend->presence_received = TRUE;
|
||||
linphone_friend_set_presence_model(friend, (LinphonePresenceModel *)presence);
|
||||
lf->presence_received = TRUE;
|
||||
linphone_friend_set_presence_model(lf, (LinphonePresenceModel *)presence);
|
||||
if (full_state == FALSE) {
|
||||
linphone_core_notify_notify_presence_received(list->lc, friend);
|
||||
linphone_core_notify_notify_presence_received(list->lc, lf);
|
||||
}
|
||||
}
|
||||
linphone_content_unref(presence_part);
|
||||
|
|
@ -180,7 +245,7 @@ static void linphone_friend_list_parse_multipart_related_body(LinphoneFriendList
|
|||
if (cid != NULL) linphone_free_xml_text_content(cid);
|
||||
}
|
||||
if (state != NULL) linphone_free_xml_text_content(state);
|
||||
friend->subscribe_active = TRUE;
|
||||
lf->subscribe_active = TRUE;
|
||||
}
|
||||
linphone_free_xml_text_content(uri);
|
||||
}
|
||||
|
|
@ -190,9 +255,9 @@ static void linphone_friend_list_parse_multipart_related_body(LinphoneFriendList
|
|||
if (full_state == TRUE) {
|
||||
MSList *l = list->friends;
|
||||
for (; l != NULL; l = l->next) {
|
||||
friend = (LinphoneFriend *)l->data;
|
||||
if (linphone_friend_is_presence_received(friend) == TRUE) {
|
||||
linphone_core_notify_notify_presence_received(list->lc, friend);
|
||||
lf = (LinphoneFriend *)l->data;
|
||||
if (linphone_friend_is_presence_received(lf) == TRUE) {
|
||||
linphone_core_notify_notify_presence_received(list->lc, lf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -208,8 +273,8 @@ static bool_t linphone_friend_list_has_subscribe_inactive(const LinphoneFriendLi
|
|||
MSList *l = list->friends;
|
||||
bool_t has_subscribe_inactive = FALSE;
|
||||
for (; l != NULL; l = l->next) {
|
||||
LinphoneFriend *friend = (LinphoneFriend *)l->data;
|
||||
if (friend->subscribe_active != TRUE) {
|
||||
LinphoneFriend *lf = (LinphoneFriend *)l->data;
|
||||
if (lf->subscribe_active != TRUE) {
|
||||
has_subscribe_inactive = TRUE;
|
||||
break;
|
||||
}
|
||||
|
|
@ -219,6 +284,7 @@ static bool_t linphone_friend_list_has_subscribe_inactive(const LinphoneFriendLi
|
|||
|
||||
static LinphoneFriendList * linphone_friend_list_new(void) {
|
||||
LinphoneFriendList *list = belle_sip_object_new(LinphoneFriendList);
|
||||
list->cbs = linphone_friend_list_cbs_new();
|
||||
belle_sip_object_ref(list);
|
||||
return list;
|
||||
}
|
||||
|
|
@ -228,7 +294,10 @@ static void linphone_friend_list_destroy(LinphoneFriendList *list) {
|
|||
if (list->rls_uri != NULL) ms_free(list->rls_uri);
|
||||
if (list->content_digest != NULL) ms_free(list->content_digest);
|
||||
if (list->event != NULL) linphone_event_unref(list->event);
|
||||
list->friends = ms_list_free_with_data(list->friends, (void (*)(void *))linphone_friend_unref);
|
||||
if (list->uri != NULL) ms_free(list->uri);
|
||||
if (list->cbs) linphone_friend_list_cbs_unref(list->cbs);
|
||||
if (list->dirty_friends_to_update) list->dirty_friends_to_update = ms_list_free_with_data(list->dirty_friends_to_update, (void (*)(void *))linphone_friend_unref);
|
||||
if (list->friends) list->friends = ms_list_free_with_data(list->friends, (void (*)(void *))_linphone_friend_release);
|
||||
}
|
||||
|
||||
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneFriendList);
|
||||
|
|
@ -259,8 +328,17 @@ void _linphone_friend_list_release(LinphoneFriendList *list){
|
|||
linphone_event_unref(list->event);
|
||||
list->event = NULL;
|
||||
}
|
||||
list->friends = ms_list_free_with_data(list->friends, (void (*)(void *))_linphone_friend_release);
|
||||
belle_sip_object_unref(list);
|
||||
if (list->cbs) {
|
||||
linphone_friend_list_cbs_unref(list->cbs);
|
||||
list->cbs = NULL;
|
||||
}
|
||||
if (list->dirty_friends_to_update) {
|
||||
list->dirty_friends_to_update = ms_list_free_with_data(list->dirty_friends_to_update, (void (*)(void *))linphone_friend_unref);
|
||||
}
|
||||
if (list->friends) {
|
||||
list->friends = ms_list_free_with_data(list->friends, (void (*)(void *))_linphone_friend_release);
|
||||
}
|
||||
linphone_friend_list_unref(list);
|
||||
}
|
||||
|
||||
void linphone_friend_list_unref(LinphoneFriendList *list) {
|
||||
|
|
@ -286,6 +364,7 @@ void linphone_friend_list_set_display_name(LinphoneFriendList *list, const char
|
|||
}
|
||||
if (display_name != NULL) {
|
||||
list->display_name = ms_strdup(display_name);
|
||||
linphone_core_store_friends_list_in_db(list->lc, list);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -300,64 +379,197 @@ void linphone_friend_list_set_rls_uri(LinphoneFriendList *list, const char *rls_
|
|||
}
|
||||
if (rls_uri != NULL) {
|
||||
list->rls_uri = ms_strdup(rls_uri);
|
||||
linphone_core_store_friends_list_in_db(list->lc, list);
|
||||
}
|
||||
}
|
||||
|
||||
LinphoneFriendListStatus linphone_friend_list_add_friend(LinphoneFriendList *list, LinphoneFriend *friend) {
|
||||
if (friend->uri == NULL || friend->in_list) {
|
||||
if (!friend->uri)
|
||||
static LinphoneFriendListStatus _linphone_friend_list_add_friend(LinphoneFriendList *list, LinphoneFriend *lf, bool_t synchronize) {
|
||||
if (!list || !lf->uri || lf->friend_list) {
|
||||
if (!list)
|
||||
ms_error("linphone_friend_list_add_friend(): invalid list, null");
|
||||
if (!lf->uri)
|
||||
ms_error("linphone_friend_list_add_friend(): invalid friend, no sip uri");
|
||||
if (friend->in_list)
|
||||
if (lf->friend_list)
|
||||
ms_error("linphone_friend_list_add_friend(): invalid friend, already in list");
|
||||
return LinphoneFriendListInvalidFriend;
|
||||
}
|
||||
if (ms_list_find(list->friends, friend) != NULL) {
|
||||
if (ms_list_find(list->friends, lf) != NULL) {
|
||||
char *tmp = NULL;
|
||||
const LinphoneAddress *addr = linphone_friend_get_address(friend);
|
||||
const LinphoneAddress *addr = linphone_friend_get_address(lf);
|
||||
if (addr) tmp = linphone_address_as_string(addr);
|
||||
ms_warning("Friend %s already in list [%s], ignored.", tmp ? tmp : "unknown", list->display_name);
|
||||
if (tmp) ms_free(tmp);
|
||||
} else {
|
||||
friend->in_list = TRUE;
|
||||
friend->lc = list->lc; /*In case not set yet*/
|
||||
list->friends = ms_list_append(list->friends, linphone_friend_ref(friend));
|
||||
return linphone_friend_list_import_friend(list, lf, synchronize);
|
||||
}
|
||||
return LinphoneFriendListOK;
|
||||
}
|
||||
|
||||
LinphoneFriendListStatus linphone_friend_list_remove_friend(LinphoneFriendList *list, LinphoneFriend *friend) {
|
||||
MSList *elem = ms_list_find(list->friends, friend);
|
||||
LinphoneFriendListStatus linphone_friend_list_add_friend(LinphoneFriendList *list, LinphoneFriend *lf) {
|
||||
return _linphone_friend_list_add_friend(list, lf, TRUE);
|
||||
}
|
||||
|
||||
LinphoneFriendListStatus linphone_friend_list_add_local_friend(LinphoneFriendList *list, LinphoneFriend *lf) {
|
||||
return _linphone_friend_list_add_friend(list, lf, FALSE);
|
||||
}
|
||||
|
||||
LinphoneFriendListStatus linphone_friend_list_import_friend(LinphoneFriendList *list, LinphoneFriend *lf, bool_t synchronize) {
|
||||
if (!lf->uri || lf->friend_list) {
|
||||
if (!lf->uri)
|
||||
ms_error("linphone_friend_list_add_friend(): invalid friend, no sip uri");
|
||||
if (lf->friend_list)
|
||||
ms_error("linphone_friend_list_add_friend(): invalid friend, already in list");
|
||||
return LinphoneFriendListInvalidFriend;
|
||||
}
|
||||
lf->friend_list = list;
|
||||
lf->lc = list->lc;
|
||||
list->friends = ms_list_append(list->friends, linphone_friend_ref(lf));
|
||||
if (synchronize) {
|
||||
list->dirty_friends_to_update = ms_list_append(list->dirty_friends_to_update, linphone_friend_ref(lf));
|
||||
}
|
||||
#ifdef FRIENDS_SQL_STORAGE_ENABLED
|
||||
linphone_core_store_friend_in_db(lf->lc, lf);
|
||||
#endif
|
||||
return LinphoneFriendListOK;
|
||||
}
|
||||
|
||||
static void carddav_done(LinphoneCardDavContext *cdc, bool_t success, const char *msg) {
|
||||
if (cdc && cdc->friend_list->cbs->sync_state_changed_cb) {
|
||||
cdc->friend_list->cbs->sync_state_changed_cb(cdc->friend_list, success ? LinphoneFriendListSyncSuccessful : LinphoneFriendListSyncFailure, msg);
|
||||
}
|
||||
linphone_carddav_context_destroy(cdc);
|
||||
}
|
||||
|
||||
static LinphoneFriendListStatus _linphone_friend_list_remove_friend(LinphoneFriendList *list, LinphoneFriend *lf, bool_t remove_from_server) {
|
||||
MSList *elem = ms_list_find(list->friends, lf);
|
||||
if (elem == NULL) return LinphoneFriendListNonExistentFriend;
|
||||
friend->in_list = FALSE;
|
||||
linphone_friend_unref(friend);
|
||||
|
||||
#ifdef FRIENDS_SQL_STORAGE_ENABLED
|
||||
linphone_core_remove_friend_from_db(lf->lc, lf);
|
||||
#endif
|
||||
if (remove_from_server) {
|
||||
LinphoneVCard *lvc = linphone_friend_get_vcard(lf);
|
||||
if (lvc && linphone_vcard_get_uid(lvc)) {
|
||||
LinphoneCardDavContext *cdc = linphone_carddav_context_new(list);
|
||||
if (cdc) {
|
||||
cdc->sync_done_cb = carddav_done;
|
||||
if (cdc->friend_list->cbs->sync_state_changed_cb) {
|
||||
cdc->friend_list->cbs->sync_state_changed_cb(cdc->friend_list, LinphoneFriendListSyncStarted, NULL);
|
||||
}
|
||||
linphone_carddav_delete_vcard(cdc, lf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lf->friend_list = NULL;
|
||||
linphone_friend_unref(lf);
|
||||
list->friends = ms_list_remove_link(list->friends, elem);
|
||||
return LinphoneFriendListOK;
|
||||
}
|
||||
|
||||
LinphoneFriendListStatus linphone_friend_list_remove_friend(LinphoneFriendList *list, LinphoneFriend *lf) {
|
||||
return _linphone_friend_list_remove_friend(list, lf, TRUE);
|
||||
}
|
||||
|
||||
const MSList * linphone_friend_list_get_friends(const LinphoneFriendList *list) {
|
||||
return list->friends;
|
||||
}
|
||||
|
||||
void linphone_friend_list_update_dirty_friends(LinphoneFriendList *list) {
|
||||
LinphoneCardDavContext *cdc = linphone_carddav_context_new(list);
|
||||
MSList *dirty_friends = list->dirty_friends_to_update;
|
||||
|
||||
if (cdc) {
|
||||
cdc->sync_done_cb = carddav_done;
|
||||
while (dirty_friends) {
|
||||
LinphoneFriend *lf = (LinphoneFriend *)dirty_friends->data;
|
||||
if (lf) {
|
||||
if (cdc->friend_list->cbs->sync_state_changed_cb) {
|
||||
cdc->friend_list->cbs->sync_state_changed_cb(cdc->friend_list, LinphoneFriendListSyncStarted, NULL);
|
||||
}
|
||||
linphone_carddav_put_vcard(cdc, lf);
|
||||
}
|
||||
dirty_friends = ms_list_next(dirty_friends);
|
||||
}
|
||||
list->dirty_friends_to_update = ms_list_free_with_data(list->dirty_friends_to_update, (void (*)(void *))linphone_friend_unref);
|
||||
}
|
||||
}
|
||||
|
||||
static void carddav_created(LinphoneCardDavContext *cdc, LinphoneFriend *lf) {
|
||||
if (cdc) {
|
||||
LinphoneFriendList *lfl = cdc->friend_list;
|
||||
linphone_friend_list_import_friend(lfl, lf, FALSE);
|
||||
if (cdc->friend_list->cbs->contact_created_cb) {
|
||||
cdc->friend_list->cbs->contact_created_cb(lfl, lf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void carddav_removed(LinphoneCardDavContext *cdc, LinphoneFriend *lf) {
|
||||
if (cdc) {
|
||||
LinphoneFriendList *lfl = cdc->friend_list;
|
||||
_linphone_friend_list_remove_friend(lfl, lf, FALSE);
|
||||
if (cdc->friend_list->cbs->contact_deleted_cb) {
|
||||
cdc->friend_list->cbs->contact_deleted_cb(lfl, lf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void carddav_updated(LinphoneCardDavContext *cdc, LinphoneFriend *lf_new, LinphoneFriend *lf_old) {
|
||||
if (cdc) {
|
||||
LinphoneFriendList *lfl = cdc->friend_list;
|
||||
MSList *elem = ms_list_find(lfl->friends, lf_old);
|
||||
if (elem) {
|
||||
elem->data = linphone_friend_ref(lf_new);
|
||||
}
|
||||
linphone_core_store_friend_in_db(lf_new->lc, lf_new);
|
||||
|
||||
if (cdc->friend_list->cbs->contact_updated_cb) {
|
||||
cdc->friend_list->cbs->contact_updated_cb(lfl, lf_new, lf_old);
|
||||
}
|
||||
linphone_friend_unref(lf_old);
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_friend_list_synchronize_friends_from_server(LinphoneFriendList *list) {
|
||||
LinphoneCardDavContext *cdc = linphone_carddav_context_new(list);
|
||||
|
||||
if (cdc) {
|
||||
cdc->contact_created_cb = carddav_created;
|
||||
cdc->contact_removed_cb = carddav_removed;
|
||||
cdc->contact_updated_cb = carddav_updated;
|
||||
cdc->sync_done_cb = carddav_done;
|
||||
if (cdc && cdc->friend_list->cbs->sync_state_changed_cb) {
|
||||
cdc->friend_list->cbs->sync_state_changed_cb(cdc->friend_list, LinphoneFriendListSyncStarted, NULL);
|
||||
}
|
||||
linphone_carddav_synchronize(cdc);
|
||||
}
|
||||
}
|
||||
|
||||
LinphoneFriend * linphone_friend_list_find_friend_by_address(const LinphoneFriendList *list, const LinphoneAddress *address) {
|
||||
LinphoneFriend *friend = NULL;
|
||||
LinphoneFriend *lf = NULL;
|
||||
const MSList *elem;
|
||||
for (elem = list->friends; elem != NULL; elem = elem->next) {
|
||||
friend = (LinphoneFriend *)elem->data;
|
||||
if (linphone_address_weak_equal(friend->uri, address))
|
||||
return friend;
|
||||
lf = (LinphoneFriend *)elem->data;
|
||||
if (linphone_address_weak_equal(lf->uri, address))
|
||||
return lf;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LinphoneFriend * linphone_friend_list_find_friend_by_uri(const LinphoneFriendList *list, const char *uri) {
|
||||
LinphoneAddress *address = linphone_address_new(uri);
|
||||
LinphoneFriend *friend = address ? linphone_friend_list_find_friend_by_address(list, address) : NULL;
|
||||
LinphoneFriend *lf = address ? linphone_friend_list_find_friend_by_address(list, address) : NULL;
|
||||
if (address) linphone_address_unref(address);
|
||||
return friend;
|
||||
return lf;
|
||||
}
|
||||
|
||||
LinphoneFriend * linphone_friend_list_find_friend_by_ref_key(const LinphoneFriendList *list, const char *ref_key) {
|
||||
const MSList *elem;
|
||||
if (ref_key == NULL) return NULL;
|
||||
for (elem = list->friends; elem != NULL; elem = elem->next) {
|
||||
LinphoneFriend *friend = (LinphoneFriend *)elem->data;
|
||||
if ((friend->refkey != NULL) && (strcmp(friend->refkey, ref_key) == 0)) return friend;
|
||||
LinphoneFriend *lf = (LinphoneFriend *)elem->data;
|
||||
if ((lf->refkey != NULL) && (strcmp(lf->refkey, ref_key) == 0)) return lf;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -365,8 +577,8 @@ LinphoneFriend * linphone_friend_list_find_friend_by_ref_key(const LinphoneFrien
|
|||
LinphoneFriend * linphone_friend_list_find_friend_by_inc_subscribe(const LinphoneFriendList *list, SalOp *op) {
|
||||
const MSList *elem;
|
||||
for (elem = list->friends; elem != NULL; elem = elem->next) {
|
||||
LinphoneFriend *friend = (LinphoneFriend *)elem->data;
|
||||
if (ms_list_find(friend->insubs, op)) return friend;
|
||||
LinphoneFriend *lf = (LinphoneFriend *)elem->data;
|
||||
if (ms_list_find(lf->insubs, op)) return lf;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -374,8 +586,8 @@ LinphoneFriend * linphone_friend_list_find_friend_by_inc_subscribe(const Linphon
|
|||
LinphoneFriend * linphone_friend_list_find_friend_by_out_subscribe(const LinphoneFriendList *list, SalOp *op) {
|
||||
const MSList *elem;
|
||||
for (elem = list->friends; elem != NULL; elem = elem->next) {
|
||||
LinphoneFriend *friend = (LinphoneFriend *)elem->data;
|
||||
if (friend->outsub && ((friend->outsub == op) || sal_op_is_forked_of(friend->outsub, op))) return friend;
|
||||
LinphoneFriend *lf = (LinphoneFriend *)elem->data;
|
||||
if (lf->outsub && ((lf->outsub == op) || sal_op_is_forked_of(lf->outsub, op))) return lf;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -432,8 +644,8 @@ void linphone_friend_list_update_subscriptions(LinphoneFriendList *list, Linphon
|
|||
if (xml_content != NULL) ms_free(xml_content);
|
||||
} else {
|
||||
for (elem = list->friends; elem != NULL; elem = elem->next) {
|
||||
LinphoneFriend *friend = (LinphoneFriend *)elem->data;
|
||||
linphone_friend_update_subscribes(friend, cfg, only_when_registered);
|
||||
LinphoneFriend *lf = (LinphoneFriend *)elem->data;
|
||||
linphone_friend_update_subscribes(lf, cfg, only_when_registered);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -441,16 +653,16 @@ void linphone_friend_list_update_subscriptions(LinphoneFriendList *list, Linphon
|
|||
void linphone_friend_list_invalidate_subscriptions(LinphoneFriendList *list) {
|
||||
const MSList *elem;
|
||||
for (elem = list->friends; elem != NULL; elem = elem->next) {
|
||||
LinphoneFriend *friend = (LinphoneFriend *)elem->data;
|
||||
linphone_friend_invalidate_subscription(friend);
|
||||
LinphoneFriend *lf = (LinphoneFriend *)elem->data;
|
||||
linphone_friend_invalidate_subscription(lf);
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_friend_list_notify_presence(LinphoneFriendList *list, LinphonePresenceModel *presence) {
|
||||
const MSList *elem;
|
||||
for(elem = list->friends; elem != NULL; elem = elem->next) {
|
||||
LinphoneFriend *friend = (LinphoneFriend *)elem->data;
|
||||
linphone_friend_notify(friend, presence);
|
||||
LinphoneFriend *lf = (LinphoneFriend *)elem->data;
|
||||
linphone_friend_notify(lf, presence);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -483,6 +695,27 @@ void linphone_friend_list_notify_presence_received(LinphoneFriendList *list, Lin
|
|||
linphone_content_unref(first_part);
|
||||
}
|
||||
}
|
||||
|
||||
const char * linphone_friend_list_get_uri(const LinphoneFriendList *list) {
|
||||
return list->uri;
|
||||
}
|
||||
|
||||
void linphone_friend_list_set_uri(LinphoneFriendList *list, const char *uri) {
|
||||
if (list->uri != NULL) {
|
||||
ms_free(list->uri);
|
||||
list->uri = NULL;
|
||||
}
|
||||
if (uri != NULL) {
|
||||
list->uri = ms_strdup(uri);
|
||||
linphone_core_store_friends_list_in_db(list->lc, list);
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_friend_list_update_revision(LinphoneFriendList *list, int rev) {
|
||||
list->revision = rev;
|
||||
linphone_core_store_friends_list_in_db(list->lc, list);
|
||||
}
|
||||
|
||||
void linphone_friend_list_subscription_state_changed(LinphoneCore *lc, LinphoneEvent *lev, LinphoneSubscriptionState state) {
|
||||
LinphoneFriendList *list = (LinphoneFriendList *)linphone_event_get_user_data(lev);
|
||||
if (!list) {
|
||||
|
|
@ -501,3 +734,107 @@ void linphone_friend_list_subscription_state_changed(LinphoneCore *lc, LinphoneE
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
LinphoneCore* linphone_friend_list_get_core(LinphoneFriendList *list) {
|
||||
return list->lc;
|
||||
}
|
||||
|
||||
int linphone_friend_list_import_friends_from_vcard4_file(LinphoneFriendList *list, const char *vcard_file) {
|
||||
MSList *vcards = linphone_vcard_list_from_vcard4_file(vcard_file);
|
||||
int count = 0;
|
||||
|
||||
#ifndef VCARD_ENABLED
|
||||
ms_error("vCard support wasn't enabled at compilation time");
|
||||
return -1;
|
||||
#endif
|
||||
if (!vcards) {
|
||||
ms_error("Failed to parse the file %s", vcard_file);
|
||||
return -1;
|
||||
}
|
||||
if (!list) {
|
||||
ms_error("Can't import into a NULL list");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (vcards != NULL && vcards->data != NULL) {
|
||||
LinphoneVCard *vcard = (LinphoneVCard *)vcards->data;
|
||||
LinphoneFriend *lf = linphone_friend_new_from_vcard(vcard);
|
||||
if (lf) {
|
||||
if (LinphoneFriendListOK == linphone_friend_list_import_friend(list, lf, TRUE)) {
|
||||
count++;
|
||||
}
|
||||
linphone_friend_unref(lf);
|
||||
} else {
|
||||
linphone_vcard_free(vcard);
|
||||
}
|
||||
vcards = ms_list_next(vcards);
|
||||
}
|
||||
#ifndef FRIENDS_SQL_STORAGE_ENABLED
|
||||
linphone_core_write_friends_config(list->lc);
|
||||
#endif
|
||||
return count;
|
||||
}
|
||||
|
||||
int linphone_friend_list_import_friends_from_vcard4_buffer(LinphoneFriendList *list, const char *vcard_buffer) {
|
||||
MSList *vcards = linphone_vcard_list_from_vcard4_buffer(vcard_buffer);
|
||||
int count = 0;
|
||||
|
||||
#ifndef VCARD_ENABLED
|
||||
ms_error("vCard support wasn't enabled at compilation time");
|
||||
return -1;
|
||||
#endif
|
||||
if (!vcards) {
|
||||
ms_error("Failed to parse the buffer");
|
||||
return -1;
|
||||
}
|
||||
if (!list) {
|
||||
ms_error("Can't import into a NULL list");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (vcards != NULL && vcards->data != NULL) {
|
||||
LinphoneVCard *vcard = (LinphoneVCard *)vcards->data;
|
||||
LinphoneFriend *lf = linphone_friend_new_from_vcard(vcard);
|
||||
if (lf) {
|
||||
if (LinphoneFriendListOK == linphone_friend_list_import_friend(list, lf, TRUE)) {
|
||||
count++;
|
||||
}
|
||||
linphone_friend_unref(lf);
|
||||
} else {
|
||||
linphone_vcard_free(vcard);
|
||||
}
|
||||
vcards = ms_list_next(vcards);
|
||||
}
|
||||
#ifndef FRIENDS_SQL_STORAGE_ENABLED
|
||||
linphone_core_write_friends_config(list->lc);
|
||||
#endif
|
||||
return count;
|
||||
}
|
||||
|
||||
void linphone_friend_list_export_friends_as_vcard4_file(LinphoneFriendList *list, const char *vcard_file) {
|
||||
FILE *file = NULL;
|
||||
const MSList *friends = linphone_friend_list_get_friends(list);
|
||||
|
||||
file = fopen(vcard_file, "wb");
|
||||
if (file == NULL) {
|
||||
ms_warning("Could not write %s ! Maybe it is read-only. Contacts will not be saved.", vcard_file);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef VCARD_ENABLED
|
||||
ms_error("vCard support wasn't enabled at compilation time");
|
||||
#endif
|
||||
while (friends != NULL && friends->data != NULL) {
|
||||
LinphoneFriend *lf = (LinphoneFriend *)friends->data;
|
||||
LinphoneVCard *vcard = linphone_friend_get_vcard(lf);
|
||||
if (vcard) {
|
||||
const char *vcard_text = linphone_vcard_as_vcard4_string(vcard);
|
||||
fprintf(file, "%s", vcard_text);
|
||||
} else {
|
||||
ms_warning("Couldn't export friend %s because it doesn't have a vCard attached", linphone_address_as_string(linphone_friend_get_address(lf)));
|
||||
}
|
||||
friends = ms_list_next(friends);
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,15 @@ typedef enum _LinphoneFriendListStatus {
|
|||
LinphoneFriendListInvalidFriend
|
||||
} LinphoneFriendListStatus;
|
||||
|
||||
/**
|
||||
* Enum describing the status of a CardDAV synchronization
|
||||
*/
|
||||
typedef enum _LinphoneFriendListSyncStatus {
|
||||
LinphoneFriendListSyncStarted,
|
||||
LinphoneFriendListSyncSuccessful,
|
||||
LinphoneFriendListSyncFailure
|
||||
} LinphoneFriendListSyncStatus;
|
||||
|
||||
/**
|
||||
* The LinphoneFriendList object representing a list of friends.
|
||||
**/
|
||||
|
|
@ -62,11 +71,32 @@ typedef struct _LinphoneFriendList LinphoneFriendList;
|
|||
LINPHONE_PUBLIC LinphoneFriendList * linphone_core_create_friend_list(LinphoneCore *lc);
|
||||
|
||||
/**
|
||||
* Set the friend list.
|
||||
* Add a friend list.
|
||||
* @param[in] lc LinphoneCore object
|
||||
* @param[in] list LinphoneFriendList object
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_core_set_friend_list(LinphoneCore *lc, LinphoneFriendList *list);
|
||||
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
|
||||
*/
|
||||
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 \mslist{LinphoneFriendList} a list of LinphoneFriendList
|
||||
*/
|
||||
LINPHONE_PUBLIC const MSList * 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
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneFriendList * linphone_core_get_default_friend_list(const LinphoneCore *lc);
|
||||
|
||||
/**
|
||||
* Acquire a reference to the friend list.
|
||||
|
|
@ -124,12 +154,21 @@ LINPHONE_PUBLIC const char * linphone_friend_list_get_rls_uri(const LinphoneFrie
|
|||
LINPHONE_PUBLIC void linphone_friend_list_set_rls_uri(LinphoneFriendList *list, const char *rls_uri);
|
||||
|
||||
/**
|
||||
* Add a friend to a friend list.
|
||||
* 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] friend 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 *afriend);
|
||||
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] friend 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.
|
||||
|
|
@ -139,6 +178,13 @@ LINPHONE_PUBLIC LinphoneFriendListStatus linphone_friend_list_add_friend(Linphon
|
|||
**/
|
||||
LINPHONE_PUBLIC LinphoneFriendListStatus linphone_friend_list_remove_friend(LinphoneFriendList *list, LinphoneFriend *afriend);
|
||||
|
||||
/**
|
||||
* Retrieves the list of LinphoneFriend from this LinphoneFriendList.
|
||||
* @param[in] list LinphoneFriendList object
|
||||
* @return \mslist{LinphoneFriend} a list of LinphoneFriend
|
||||
*/
|
||||
LINPHONE_PUBLIC const MSList * linphone_friend_list_get_friends(const LinphoneFriendList *list);
|
||||
|
||||
/**
|
||||
* Find a friend in the friend list using a LinphoneAddress.
|
||||
* @param[in] list LinphoneFriendList object.
|
||||
|
|
@ -174,6 +220,184 @@ LINPHONE_PUBLIC void linphone_friend_list_update_subscriptions(LinphoneFriendLis
|
|||
**/
|
||||
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.
|
||||
* @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] rls_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] rev The revision
|
||||
*/
|
||||
void linphone_friend_list_update_revision(LinphoneFriendList *list, int rev);
|
||||
|
||||
/**
|
||||
* An object to handle the callbacks for LinphoneFriend synchronization.
|
||||
**/
|
||||
typedef struct _LinphoneFriendListCbs LinphoneFriendListCbs;
|
||||
|
||||
/**
|
||||
* Callback used to notify a new contact has been created on the CardDAV server and downloaded locally
|
||||
**/
|
||||
typedef void (*LinphoneFriendListContactCreatedCb)(LinphoneFriendList *list, LinphoneFriend *lf);
|
||||
|
||||
/**
|
||||
* Callback used to notify a contact has been deleted on the CardDAV server
|
||||
**/
|
||||
typedef void (*LinphoneFriendListContactDeletedCb)(LinphoneFriendList *list, LinphoneFriend *lf);
|
||||
|
||||
/**
|
||||
* Callback used to notify a contact has been updated on the CardDAV server
|
||||
**/
|
||||
typedef void (*LinphoneFriendListContactUpdatedCb)(LinphoneFriendList *list, LinphoneFriend *new_friend, LinphoneFriend *old_friend);
|
||||
|
||||
/**
|
||||
* Callback used to notify the status of the synchronization has changed
|
||||
**/
|
||||
typedef void (*LinphoneFriendListSyncStateChangedCb)(LinphoneFriendList *list, LinphoneFriendListSyncStatus status, const char *msg);
|
||||
|
||||
/**
|
||||
* Get the LinphoneFriendListCbs object associated with a LinphoneFriendList.
|
||||
* @param[in] request LinphoneXmlRpcRequest 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.
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneFriendListCbs * linphone_friend_list_cbs_ref(LinphoneFriendListCbs *cbs);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
**/
|
||||
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.
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_friend_list_cbs_set_user_data(LinphoneFriendListCbs *cbs, void *ud);
|
||||
|
||||
/**
|
||||
* Get the contact created callback.
|
||||
* @param[in] cbs LinphoneFriendListCbs object.
|
||||
* @return The current contact created callback.
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneFriendListContactCreatedCb linphone_friend_list_cbs_get_contact_created(const LinphoneFriendListCbs *cbs);
|
||||
|
||||
/**
|
||||
* Set the contact created callback.
|
||||
* @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, LinphoneFriendListContactCreatedCb cb);
|
||||
|
||||
/**
|
||||
* Get the contact deleted callback.
|
||||
* @param[in] cbs LinphoneFriendListCbs object.
|
||||
* @return The current contact deleted callback.
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneFriendListContactDeletedCb linphone_friend_list_cbs_get_contact_deleted(const LinphoneFriendListCbs *cbs);
|
||||
|
||||
/**
|
||||
* Set the contact deleted callback.
|
||||
* @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, LinphoneFriendListContactDeletedCb cb);
|
||||
|
||||
/**
|
||||
* Get the contact updated callback.
|
||||
* @param[in] cbs LinphoneFriendListCbs object.
|
||||
* @return The current contact updated callback.
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneFriendListContactUpdatedCb linphone_friend_list_cbs_get_contact_updated(const LinphoneFriendListCbs *cbs);
|
||||
|
||||
/**
|
||||
* Set the contact updated callback.
|
||||
* @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, LinphoneFriendListContactUpdatedCb cb);
|
||||
|
||||
/**
|
||||
* Get the sync status changed callback.
|
||||
* @param[in] cbs LinphoneFriendListCbs object.
|
||||
* @return The current sync status changedcallback.
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneFriendListSyncStateChangedCb linphone_friend_list_cbs_get_sync_status_changed(const LinphoneFriendListCbs *cbs);
|
||||
|
||||
/**
|
||||
* Set the contact updated callback.
|
||||
* @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, LinphoneFriendListSyncStateChangedCb cb);
|
||||
|
||||
/**
|
||||
* Starts a CardDAV synchronization using value set using linphone_friend_list_set_uri.
|
||||
* @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.
|
||||
*/
|
||||
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
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneCore* linphone_friend_list_get_core(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
|
||||
* @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 int 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
|
||||
* @param[in] vcard_buffer the buffer that contains the vCard(s) to parse
|
||||
* @return the amount of linphone friends created
|
||||
*/
|
||||
LINPHONE_PUBLIC int 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
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import org.linphone.core.LinphoneCoreFactory;
|
|||
import org.linphone.core.LinphoneCoreListener;
|
||||
import org.linphone.core.LinphoneEvent;
|
||||
import org.linphone.core.LinphoneFriend;
|
||||
import org.linphone.core.LinphoneFriendList;
|
||||
import org.linphone.core.LinphoneFriend.SubscribePolicy;
|
||||
import org.linphone.core.LinphoneInfoMessage;
|
||||
import org.linphone.core.LinphoneProxyConfig;
|
||||
|
|
@ -335,4 +336,17 @@ public class TutorialBuddyStatus implements LinphoneCoreListener {
|
|||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void friendListCreated(LinphoneCore lc, LinphoneFriendList list) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void friendListRemoved(LinphoneCore lc, LinphoneFriendList list) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import org.linphone.core.LinphoneCoreFactory;
|
|||
import org.linphone.core.LinphoneCoreListener;
|
||||
import org.linphone.core.LinphoneEvent;
|
||||
import org.linphone.core.LinphoneFriend;
|
||||
import org.linphone.core.LinphoneFriendList;
|
||||
import org.linphone.core.LinphoneInfoMessage;
|
||||
import org.linphone.core.LinphoneProxyConfig;
|
||||
import org.linphone.core.PublishState;
|
||||
|
|
@ -251,5 +252,17 @@ public class TutorialChatRoom implements LinphoneCoreListener, LinphoneChatMessa
|
|||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void friendListCreated(LinphoneCore lc, LinphoneFriendList list) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void friendListRemoved(LinphoneCore lc, LinphoneFriendList list) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import org.linphone.core.LinphoneCoreFactory;
|
|||
import org.linphone.core.LinphoneCoreListener;
|
||||
import org.linphone.core.LinphoneEvent;
|
||||
import org.linphone.core.LinphoneFriend;
|
||||
import org.linphone.core.LinphoneFriendList;
|
||||
import org.linphone.core.LinphoneInfoMessage;
|
||||
import org.linphone.core.LinphoneProxyConfig;
|
||||
import org.linphone.core.PublishState;
|
||||
|
|
@ -257,5 +258,17 @@ public class TutorialHelloWorld implements LinphoneCoreListener {
|
|||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void friendListCreated(LinphoneCore lc, LinphoneFriendList list) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void friendListRemoved(LinphoneCore lc, LinphoneFriendList list) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import org.linphone.core.LinphoneCoreFactory;
|
|||
import org.linphone.core.LinphoneCoreListener;
|
||||
import org.linphone.core.LinphoneEvent;
|
||||
import org.linphone.core.LinphoneFriend;
|
||||
import org.linphone.core.LinphoneFriendList;
|
||||
import org.linphone.core.LinphoneInfoMessage;
|
||||
import org.linphone.core.LinphoneProxyConfig;
|
||||
import org.linphone.core.PublishState;
|
||||
|
|
@ -286,4 +287,18 @@ public class TutorialRegistration implements LinphoneCoreListener {
|
|||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void friendListCreated(LinphoneCore lc, LinphoneFriendList list) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void friendListRemoved(LinphoneCore lc, LinphoneFriendList list) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1373,12 +1373,14 @@ static void video_config_read(LinphoneCore *lc){
|
|||
|
||||
static void ui_config_read(LinphoneCore *lc)
|
||||
{
|
||||
LinphoneFriend *lf;
|
||||
#ifndef FRIENDS_SQL_STORAGE_ENABLED
|
||||
LinphoneFriend *lf = NULL;
|
||||
int i;
|
||||
for (i=0;(lf=linphone_friend_new_from_config_file(lc,i))!=NULL;i++){
|
||||
linphone_core_add_friend(lc,lf);
|
||||
for (i = 0; (lf = linphone_friend_new_from_config_file(lc, i)) != NULL; i++) {
|
||||
linphone_core_add_friend(lc, lf);
|
||||
linphone_friend_unref(lf);
|
||||
}
|
||||
#endif
|
||||
|
||||
call_logs_read_from_config_file(lc);
|
||||
}
|
||||
|
|
@ -1684,7 +1686,7 @@ static void linphone_core_register_default_codecs(LinphoneCore *lc){
|
|||
|
||||
static void linphone_core_internal_notify_received(LinphoneCore *lc, LinphoneEvent *lev, const char *notified_event, const LinphoneContent *body) {
|
||||
if (strcmp(notified_event, "Presence") == 0) {
|
||||
linphone_friend_list_notify_presence_received(lc->friendlist, lev, body);
|
||||
linphone_friend_list_notify_presence_received(linphone_core_get_default_friend_list(lc), lev, body);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1704,7 +1706,9 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab
|
|||
lc->config=lp_config_ref(config);
|
||||
lc->data=userdata;
|
||||
lc->ringstream_autorelease=TRUE;
|
||||
linphone_core_set_friend_list(lc, NULL);
|
||||
|
||||
linphone_core_add_friend_list(lc, NULL);
|
||||
|
||||
linphone_task_list_init(&lc->hooks);
|
||||
|
||||
internal_vtable->notify_received = linphone_core_internal_notify_received;
|
||||
|
|
@ -1949,24 +1953,59 @@ bool_t linphone_core_generic_confort_noise_enabled(const LinphoneCore *lc){
|
|||
return lp_config_get_int(lc->config, "misc", "use_cn", FALSE);
|
||||
}
|
||||
|
||||
const MSList * linphone_core_get_friend_list(const LinphoneCore *lc)
|
||||
{
|
||||
return lc->friendlist->friends;
|
||||
const MSList* linphone_core_get_friend_list(const LinphoneCore *lc) {
|
||||
MSList *lists = lc->friends_lists;
|
||||
if (lists) {
|
||||
LinphoneFriendList *list = (LinphoneFriendList *)lists->data;
|
||||
if (list) {
|
||||
return list->friends;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void linphone_core_set_friend_list(LinphoneCore *lc, LinphoneFriendList *list) {
|
||||
if (lc->friendlist != NULL) {
|
||||
linphone_friend_list_unref(lc->friendlist);
|
||||
lc->friendlist = NULL;
|
||||
const MSList* linphone_core_get_friends_lists(const LinphoneCore *lc) {
|
||||
return lc->friends_lists;
|
||||
}
|
||||
|
||||
LinphoneFriendList* linphone_core_get_default_friend_list(const LinphoneCore *lc) {
|
||||
if (lc && lc->friends_lists) {
|
||||
return (LinphoneFriendList *)lc->friends_lists->data;
|
||||
}
|
||||
if (list != NULL) {
|
||||
lc->friendlist = linphone_friend_list_ref(list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void linphone_core_remove_friend_list(LinphoneCore *lc, LinphoneFriendList *list) {
|
||||
MSList *elem = ms_list_find(lc->friends_lists, list);
|
||||
if (elem == NULL) return;
|
||||
#ifdef FRIENDS_SQL_STORAGE_ENABLED
|
||||
linphone_core_remove_friends_list_from_db(lc, list);
|
||||
#endif
|
||||
linphone_core_notify_friend_list_removed(lc, list);
|
||||
list->lc = NULL;
|
||||
linphone_friend_list_unref(list);
|
||||
lc->friends_lists = ms_list_remove_link(lc->friends_lists, elem);
|
||||
}
|
||||
|
||||
void linphone_core_add_friend_list(LinphoneCore *lc, LinphoneFriendList *list) {
|
||||
if (list) {
|
||||
if (!list->lc) {
|
||||
list->lc = lc;
|
||||
}
|
||||
lc->friends_lists = ms_list_append(lc->friends_lists, linphone_friend_list_ref(list));
|
||||
#ifdef FRIENDS_SQL_STORAGE_ENABLED
|
||||
linphone_core_store_friends_list_in_db(lc, list);
|
||||
#endif
|
||||
linphone_core_notify_friend_list_created(lc, list);
|
||||
} else {
|
||||
const char *rls_uri = NULL;
|
||||
lc->friendlist = linphone_core_create_friend_list(lc);
|
||||
rls_uri = lp_config_get_string(lc->config, "sip", "rls_uri", NULL);
|
||||
if (rls_uri && lp_config_get_int(lc->config, "sip", "use_rls_presence", 0))
|
||||
linphone_friend_list_set_rls_uri(lc->friendlist, rls_uri);
|
||||
const char *rls_uri = lp_config_get_string(lc->config, "sip", "rls_uri", NULL);
|
||||
list = linphone_core_create_friend_list(lc);
|
||||
linphone_friend_list_set_display_name(list, "_default");
|
||||
if (rls_uri && lp_config_get_int(lc->config, "sip", "use_rls_presence", 0)) {
|
||||
linphone_friend_list_set_rls_uri(list, rls_uri);
|
||||
}
|
||||
lc->friends_lists = ms_list_append(lc->friends_lists, linphone_friend_list_ref(list));
|
||||
linphone_friend_list_unref(list);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2758,9 +2797,16 @@ void linphone_core_iterate(LinphoneCore *lc){
|
|||
}
|
||||
|
||||
if (one_second_elapsed) {
|
||||
MSList *elem = NULL;
|
||||
if (lp_config_needs_commit(lc->config)) {
|
||||
lp_config_sync(lc->config);
|
||||
}
|
||||
for (elem = lc->friends_lists; elem != NULL; elem = ms_list_next(elem)) {
|
||||
LinphoneFriendList *list = (LinphoneFriendList *)elem->data;
|
||||
if (list->dirty_friends_to_update) {
|
||||
linphone_friend_list_update_dirty_friends(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (liblinphone_serialize_logs == TRUE) {
|
||||
|
|
@ -6400,9 +6446,8 @@ static void codecs_config_uninit(LinphoneCore *lc)
|
|||
void ui_config_uninit(LinphoneCore* lc)
|
||||
{
|
||||
ms_message("Destroying friends.");
|
||||
_linphone_friend_list_release(lc->friendlist);
|
||||
lc->friendlist = NULL;
|
||||
if (lc->subscribers){
|
||||
lc->friends_lists = ms_list_free_with_data(lc->friends_lists, (void (*)(void*))_linphone_friend_list_release);
|
||||
if (lc->subscribers) {
|
||||
lc->subscribers = ms_list_free_with_data(lc->subscribers, (void (*)(void *))_linphone_friend_release);
|
||||
}
|
||||
if (lc->presence_model) {
|
||||
|
|
@ -6430,18 +6475,22 @@ LpConfig * linphone_core_create_lp_config(LinphoneCore *lc, const char *filename
|
|||
|
||||
static void linphone_core_uninit(LinphoneCore *lc)
|
||||
{
|
||||
MSList *elem = NULL;
|
||||
linphone_task_list_free(&lc->hooks);
|
||||
lc->video_conf.show_local = FALSE;
|
||||
|
||||
while(lc->calls)
|
||||
{
|
||||
while(lc->calls) {
|
||||
LinphoneCall *the_call = lc->calls->data;
|
||||
linphone_core_terminate_call(lc,the_call);
|
||||
linphone_core_iterate(lc);
|
||||
ms_usleep(50000);
|
||||
}
|
||||
|
||||
linphone_friend_list_close_subscriptions(lc->friendlist);
|
||||
for (elem = lc->friends_lists; elem != NULL; elem = ms_list_next(elem)) {
|
||||
LinphoneFriendList *list = (LinphoneFriendList *)elem->data;
|
||||
linphone_friend_list_close_subscriptions(list);
|
||||
}
|
||||
|
||||
lc->chatrooms = ms_list_free_with_data(lc->chatrooms, (MSIterateFunc)linphone_chat_room_release);
|
||||
|
||||
linphone_core_set_state(lc,LinphoneGlobalShutdown,"Shutting down");
|
||||
|
|
@ -6497,14 +6546,22 @@ static void linphone_core_uninit(LinphoneCore *lc)
|
|||
if (lc->chat_db_file){
|
||||
ms_free(lc->chat_db_file);
|
||||
}
|
||||
if (lc->logs_db_file) {
|
||||
ms_free(lc->logs_db_file);
|
||||
}
|
||||
if (lc->friends_db_file) {
|
||||
ms_free(lc->friends_db_file);
|
||||
}
|
||||
if (lc->ringtoneplayer) {
|
||||
linphone_ringtoneplayer_destroy(lc->ringtoneplayer);
|
||||
}
|
||||
|
||||
linphone_core_free_payload_types(lc);
|
||||
if (lc->supported_formats) ms_free(lc->supported_formats);
|
||||
linphone_core_message_storage_close(lc);
|
||||
linphone_core_call_log_storage_close(lc);
|
||||
|
||||
linphone_core_friends_storage_close(lc);
|
||||
|
||||
linphone_core_set_state(lc,LinphoneGlobalOff,"Off");
|
||||
linphone_core_deactivate_log_serialization_if_needed();
|
||||
ms_list_free_with_data(lc->vtable_refs,(void (*)(void *))v_table_reference_destroy);
|
||||
|
|
|
|||
|
|
@ -1200,10 +1200,12 @@ LINPHONE_PUBLIC LinphoneAuthInfo * linphone_auth_info_new_from_config_file(LpCon
|
|||
#include "account_creator.h"
|
||||
#include "friendlist.h"
|
||||
#include "linphone_proxy_config.h"
|
||||
#include "carddav.h"
|
||||
#else
|
||||
#include "linphone/account_creator.h"
|
||||
#include "linphone/friendlist.h"
|
||||
#include "linphone/linphone_proxy_config.h"
|
||||
#include "linphone/carddav.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -2068,6 +2070,20 @@ typedef void (*LinphoneCoreLogCollectionUploadStateChangedCb)(LinphoneCore *lc,
|
|||
*/
|
||||
typedef void (*LinphoneCoreLogCollectionUploadProgressIndicationCb)(LinphoneCore *lc, size_t offset, size_t total);
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
typedef void (*LinphoneCoreFriendListCreatedCb) (LinphoneCore *lc, LinphoneFriendList *list);
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
typedef void (*LinphoneCoreFriendListRemovedCb) (LinphoneCore *lc, LinphoneFriendList *list);
|
||||
|
||||
/**
|
||||
* This structure holds all callbacks that the application should implement.
|
||||
* None is mandatory.
|
||||
|
|
@ -2105,6 +2121,8 @@ typedef struct _LinphoneCoreVTable{
|
|||
LinphoneCoreNetworkReachableCb network_reachable; /**< Callback to report IP network status (I.E up/down )*/
|
||||
LinphoneCoreLogCollectionUploadStateChangedCb log_collection_upload_state_changed; /**< Callback to upload collected logs */
|
||||
LinphoneCoreLogCollectionUploadProgressIndicationCb log_collection_upload_progress_indication; /**< Callback to indicate log collection upload progress */
|
||||
LinphoneCoreFriendListCreatedCb friend_list_created;
|
||||
LinphoneCoreFriendListRemovedCb friend_list_removed;
|
||||
void *user_data; /**<User data associated with the above callbacks */
|
||||
} LinphoneCoreVTable;
|
||||
|
||||
|
|
@ -4419,7 +4437,6 @@ LINPHONE_PUBLIC const char* linphone_transport_to_string(LinphoneTransportType t
|
|||
**/
|
||||
LINPHONE_PUBLIC LinphoneTransportType linphone_transport_parse(const char* transport);
|
||||
|
||||
|
||||
/**
|
||||
* @ingroup media_parameters
|
||||
* Get default call parameters reflecting current linphone core configuration
|
||||
|
|
|
|||
|
|
@ -284,6 +284,13 @@ public:
|
|||
|
||||
friendClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneFriendImpl"));;
|
||||
friendCtrId = env->GetMethodID(friendClass,"<init>", "(J)V");
|
||||
|
||||
friendListClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneFriendListImpl"));;
|
||||
friendListCtrId = env->GetMethodID(friendListClass,"<init>", "(J)V");
|
||||
friendListCreatedId = env->GetMethodID(listenerClass, "friendListCreated", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneFriendList;)V");
|
||||
friendListRemovedId = env->GetMethodID(listenerClass, "friendListRemoved", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneFriendList;)V");
|
||||
friendListSyncStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneFriendList$State"));
|
||||
friendListSyncStateFromIntId = env->GetStaticMethodID(friendListSyncStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneFriendList$State;");
|
||||
|
||||
addressClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneAddressImpl"));
|
||||
addressCtrId = env->GetMethodID(addressClass,"<init>", "(J)V");
|
||||
|
|
@ -326,6 +333,8 @@ public:
|
|||
env->DeleteGlobalRef(chatMessageClass);
|
||||
env->DeleteGlobalRef(chatRoomClass);
|
||||
env->DeleteGlobalRef(friendClass);
|
||||
env->DeleteGlobalRef(friendListClass);
|
||||
env->DeleteGlobalRef(friendListSyncStateClass);
|
||||
env->DeleteGlobalRef(infoMessageClass);
|
||||
env->DeleteGlobalRef(linphoneEventClass);
|
||||
env->DeleteGlobalRef(subscriptionStateClass);
|
||||
|
|
@ -396,6 +405,13 @@ public:
|
|||
jclass friendClass;
|
||||
jmethodID friendCtrId;
|
||||
|
||||
jclass friendListClass;
|
||||
jmethodID friendListCtrId;
|
||||
jmethodID friendListCreatedId;
|
||||
jmethodID friendListRemovedId;
|
||||
jclass friendListSyncStateClass;
|
||||
jmethodID friendListSyncStateFromIntId;
|
||||
|
||||
jclass addressClass;
|
||||
jmethodID addressCtrId;
|
||||
|
||||
|
|
@ -528,6 +544,31 @@ jobject getFriend(JNIEnv *env, LinphoneFriend *lfriend, int *isLocalRef){
|
|||
return jobj;
|
||||
}
|
||||
|
||||
jobject getFriendList(JNIEnv *env, LinphoneFriendList *lfriendList){
|
||||
jobject jobj=0;
|
||||
|
||||
if (lfriendList != NULL){
|
||||
LinphoneCore *lc = linphone_friend_list_get_core(lfriendList);
|
||||
LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc);
|
||||
|
||||
void *up=linphone_friend_list_get_user_data(lfriendList);
|
||||
|
||||
if (up == NULL){
|
||||
jobj=env->NewObject(ljb->friendListClass, ljb->friendListCtrId, (jlong)lfriendList);
|
||||
linphone_friend_list_set_user_data(lfriendList,(void*)env->NewWeakGlobalRef(jobj));
|
||||
linphone_friend_list_ref(lfriendList);
|
||||
}else{
|
||||
|
||||
jobj=env->NewLocalRef((jobject)up);
|
||||
if (jobj == NULL){
|
||||
jobj=env->NewObject(ljb->friendListClass, ljb->friendListCtrId, (jlong)lfriendList);
|
||||
linphone_friend_list_set_user_data(lfriendList,(void*)env->NewWeakGlobalRef(jobj));
|
||||
}
|
||||
}
|
||||
}
|
||||
return jobj;
|
||||
}
|
||||
|
||||
jobject getEvent(JNIEnv *env, LinphoneEvent *lev){
|
||||
if (lev==NULL) return NULL;
|
||||
jobject jev=(jobject)linphone_event_get_user_data(lev);
|
||||
|
|
@ -640,6 +681,13 @@ public:
|
|||
if (ljb->logCollectionUploadStateId) {
|
||||
vTable->log_collection_upload_state_changed = logCollectionUploadStateChange;
|
||||
}
|
||||
|
||||
if (ljb->friendListCreatedId) {
|
||||
vTable->friend_list_created = friendListCreated;
|
||||
}
|
||||
if (ljb->friendListRemovedId) {
|
||||
vTable->friend_list_removed = friendListRemoved;
|
||||
}
|
||||
}
|
||||
|
||||
~LinphoneCoreData() {
|
||||
|
|
@ -1214,6 +1262,40 @@ public:
|
|||
env->DeleteLocalRef(msg);
|
||||
}
|
||||
}
|
||||
static void friendListCreated(LinphoneCore *lc, LinphoneFriendList *list) {
|
||||
JNIEnv *env = 0;
|
||||
jint result = jvm->AttachCurrentThread(&env,NULL);
|
||||
if (result != 0) {
|
||||
ms_error("cannot attach VM");
|
||||
return;
|
||||
}
|
||||
|
||||
LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc);
|
||||
LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc);
|
||||
LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table);
|
||||
env->CallVoidMethod(lcData->listener
|
||||
,ljb->friendListCreatedId
|
||||
,lcData->core
|
||||
,getFriendList(env, list));
|
||||
handle_possible_java_exception(env, lcData->listener);
|
||||
}
|
||||
static void friendListRemoved(LinphoneCore *lc, LinphoneFriendList *list) {
|
||||
JNIEnv *env = 0;
|
||||
jint result = jvm->AttachCurrentThread(&env,NULL);
|
||||
if (result != 0) {
|
||||
ms_error("cannot attach VM");
|
||||
return;
|
||||
}
|
||||
|
||||
LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc);
|
||||
LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc);
|
||||
LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table);
|
||||
env->CallVoidMethod(lcData->listener
|
||||
,ljb->friendListRemovedId
|
||||
,lcData->core
|
||||
,getFriendList(env, list));
|
||||
handle_possible_java_exception(env, lcData->listener);
|
||||
}
|
||||
|
||||
private:
|
||||
static inline void handle_possible_java_exception(JNIEnv *env, jobject listener)
|
||||
|
|
@ -1363,16 +1445,21 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_stopRinging(JNIEnv* env,
|
|||
linphone_core_stop_ringing((LinphoneCore*)lc);
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setChatDatabasePath(JNIEnv* env, jobject thiz, jlong lc, jstring jpath) {
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setChatDatabasePath(JNIEnv* env, jobject thiz, jlong lc, jstring jpath) {
|
||||
const char* path = env->GetStringUTFChars(jpath, NULL);
|
||||
linphone_core_set_chat_database_path((LinphoneCore*)lc, path);
|
||||
env->ReleaseStringUTFChars(jpath, path);
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setCallLogsDatabasePath( JNIEnv* env, jobject thiz, jlong lc, jstring jpath) {
|
||||
const char* path = env->GetStringUTFChars(jpath, NULL);
|
||||
linphone_core_set_call_logs_database_path((LinphoneCore*)lc, path);
|
||||
env->ReleaseStringUTFChars(jpath, path);
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setCallLogsDatabasePath( JNIEnv* env, jobject thiz, jlong lc, jstring jpath) {
|
||||
const char* path = env->GetStringUTFChars(jpath, NULL);
|
||||
linphone_core_set_call_logs_database_path((LinphoneCore*)lc, path);
|
||||
env->ReleaseStringUTFChars(jpath, path);
|
||||
}
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setFriendsDatabasePath( JNIEnv* env, jobject thiz, jlong lc, jstring jpath) {
|
||||
const char* path = env->GetStringUTFChars(jpath, NULL);
|
||||
linphone_core_set_friends_database_path((LinphoneCore*)lc, path);
|
||||
env->ReleaseStringUTFChars(jpath, path);
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setPrimaryContact2(JNIEnv* env, jobject thiz, jlong lc, jstring jcontact) {
|
||||
|
|
@ -1948,6 +2035,7 @@ extern "C" jobject Java_org_linphone_core_LinphoneCoreImpl_getCurrentCall(JNIEnv
|
|||
) {
|
||||
return getCall(env,linphone_core_get_current_call((LinphoneCore*)lc));
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_addFriend(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc
|
||||
|
|
@ -1956,12 +2044,48 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_addFriend(JNIEnv* env
|
|||
linphone_core_add_friend((LinphoneCore*)lc,(LinphoneFriend*)aFriend);
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setFriendList(JNIEnv* env
|
||||
extern "C" jint Java_org_linphone_core_LinphoneFriendListImpl_importFriendsFromVCardFile(JNIEnv* env, jobject thiz, jlong list, jstring jpath) {
|
||||
const char* path = env->GetStringUTFChars(jpath, NULL);
|
||||
int count = linphone_friend_list_import_friends_from_vcard4_file((LinphoneFriendList*)list, path);
|
||||
env->ReleaseStringUTFChars(jpath, path);
|
||||
return count;
|
||||
}
|
||||
|
||||
extern "C" jint Java_org_linphone_core_LinphoneFriendListImpl_importFriendsFromVCardBuffer(JNIEnv* env, jobject thiz, jlong list, jstring jbuffer) {
|
||||
const char* buffer = env->GetStringUTFChars(jbuffer, NULL);
|
||||
int count = linphone_friend_list_import_friends_from_vcard4_buffer((LinphoneFriendList*)list, buffer);
|
||||
env->ReleaseStringUTFChars(jbuffer, buffer);
|
||||
return count;
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneFriendListImpl_exportFriendsToVCardFile(JNIEnv* env, jobject thiz, jlong list, jstring jpath) {
|
||||
const char* path = env->GetStringUTFChars(jpath, NULL);
|
||||
linphone_friend_list_export_friends_as_vcard4_file((LinphoneFriendList*)list, path);
|
||||
env->ReleaseStringUTFChars(jpath, path);
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_addFriendList(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc
|
||||
,jlong friendList
|
||||
) {
|
||||
linphone_core_set_friend_list((LinphoneCore*)lc,(LinphoneFriendList*)friendList);
|
||||
linphone_core_add_friend_list((LinphoneCore*)lc,(LinphoneFriendList*)friendList);
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_removeFriendList(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc
|
||||
,jlong friendList
|
||||
) {
|
||||
LinphoneFriendList *list = (LinphoneFriendList *)friendList;
|
||||
LinphoneFriendListCbs *cbs = linphone_friend_list_get_callbacks(list);
|
||||
if (cbs != NULL) {
|
||||
jobject listener = (jobject) linphone_friend_list_cbs_get_user_data(cbs);
|
||||
if (listener != NULL) {
|
||||
env->DeleteGlobalRef(listener);
|
||||
}
|
||||
}
|
||||
linphone_core_remove_friend_list((LinphoneCore*)lc, list);
|
||||
}
|
||||
|
||||
extern "C" jobjectArray Java_org_linphone_core_LinphoneCoreImpl_getFriendList(JNIEnv* env
|
||||
|
|
@ -1985,6 +2109,27 @@ extern "C" jobjectArray Java_org_linphone_core_LinphoneCoreImpl_getFriendList(JN
|
|||
|
||||
return jFriends;
|
||||
}
|
||||
|
||||
extern "C" jobjectArray Java_org_linphone_core_LinphoneCoreImpl_getFriendLists(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc) {
|
||||
const MSList* friends = linphone_core_get_friends_lists((LinphoneCore*)lc);
|
||||
int friendsSize = ms_list_size(friends);
|
||||
LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data((LinphoneCore *)lc);
|
||||
jobjectArray jFriends = env->NewObjectArray(friendsSize,ljb->friendListClass,NULL);
|
||||
|
||||
for (int i = 0; i < friendsSize; i++) {
|
||||
LinphoneFriendList* lfriend = (LinphoneFriendList*)friends->data;
|
||||
jobject jfriend = getFriendList(env,lfriend);
|
||||
if(jfriend != NULL){
|
||||
env->SetObjectArrayElement(jFriends, i, jfriend);
|
||||
}
|
||||
friends = friends->next;
|
||||
}
|
||||
|
||||
return jFriends;
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setPresenceInfo(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc
|
||||
|
|
@ -3097,6 +3242,128 @@ extern "C" jlong Java_org_linphone_core_LinphoneFriendListImpl_newLinphoneFriend
|
|||
return (jlong)fl;
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneFriendListImpl_setUri(JNIEnv* env, jobject thiz, jlong list, jstring juri) {
|
||||
const char* uri = env->GetStringUTFChars(juri, NULL);
|
||||
linphone_friend_list_set_uri((LinphoneFriendList*)list, uri);
|
||||
env->ReleaseStringUTFChars(juri, uri);
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneFriendListImpl_synchronizeFriendsFromServer(JNIEnv* env, jobject thiz, jlong list) {
|
||||
linphone_friend_list_synchronize_friends_from_server((LinphoneFriendList*)list);
|
||||
}
|
||||
|
||||
static void contact_created(LinphoneFriendList *list, LinphoneFriend *lf) {
|
||||
JNIEnv *env = 0;
|
||||
jint result = jvm->AttachCurrentThread(&env,NULL);
|
||||
if (result != 0) {
|
||||
ms_error("cannot attach VM\n");
|
||||
return;
|
||||
}
|
||||
|
||||
LinphoneFriendListCbs *cbs = linphone_friend_list_get_callbacks(list);
|
||||
jobject listener = (jobject) linphone_friend_list_cbs_get_user_data(cbs);
|
||||
|
||||
if (listener == NULL) {
|
||||
ms_error("contact_created() notification without listener");
|
||||
return ;
|
||||
}
|
||||
jclass clazz = (jclass) env->GetObjectClass(listener);
|
||||
jmethodID method = env->GetMethodID(clazz, "onLinphoneFriendCreated","(Lorg/linphone/core/LinphoneFriendList;Lorg/linphone/core/LinphoneFriend;)V");
|
||||
jobject jlist = getFriendList(env, list);
|
||||
jobject jfriend = getFriend(env, lf);
|
||||
env->DeleteLocalRef(clazz);
|
||||
env->CallVoidMethod(listener, method, jlist, jfriend);
|
||||
}
|
||||
|
||||
static void contact_updated(LinphoneFriendList *list, LinphoneFriend *lf_new, LinphoneFriend *lf_old) {
|
||||
JNIEnv *env = 0;
|
||||
jint result = jvm->AttachCurrentThread(&env,NULL);
|
||||
if (result != 0) {
|
||||
ms_error("cannot attach VM\n");
|
||||
return;
|
||||
}
|
||||
|
||||
LinphoneFriendListCbs *cbs = linphone_friend_list_get_callbacks(list);
|
||||
jobject listener = (jobject) linphone_friend_list_cbs_get_user_data(cbs);
|
||||
|
||||
if (listener == NULL) {
|
||||
ms_error("contact_updated() notification without listener");
|
||||
return ;
|
||||
}
|
||||
jclass clazz = (jclass) env->GetObjectClass(listener);
|
||||
jmethodID method = env->GetMethodID(clazz, "onLinphoneFriendUpdated","(Lorg/linphone/core/LinphoneFriendList;Lorg/linphone/core/LinphoneFriend;Lorg/linphone/core/LinphoneFriend;)V");
|
||||
jobject jlist = getFriendList(env, list);
|
||||
jobject jfriend_new = getFriend(env, lf_new);
|
||||
jobject jfriend_old = getFriend(env, lf_old);
|
||||
env->DeleteLocalRef(clazz);
|
||||
env->CallVoidMethod(listener, method, jlist, jfriend_new, jfriend_old);
|
||||
}
|
||||
|
||||
static void contact_removed(LinphoneFriendList *list, LinphoneFriend *lf) {
|
||||
JNIEnv *env = 0;
|
||||
jint result = jvm->AttachCurrentThread(&env,NULL);
|
||||
if (result != 0) {
|
||||
ms_error("cannot attach VM\n");
|
||||
return;
|
||||
}
|
||||
|
||||
LinphoneFriendListCbs *cbs = linphone_friend_list_get_callbacks(list);
|
||||
jobject listener = (jobject) linphone_friend_list_cbs_get_user_data(cbs);
|
||||
|
||||
if (listener == NULL) {
|
||||
ms_error("contact_removed() notification without listener");
|
||||
return ;
|
||||
}
|
||||
jclass clazz = (jclass) env->GetObjectClass(listener);
|
||||
jmethodID method = env->GetMethodID(clazz, "onLinphoneFriendDeleted","(Lorg/linphone/core/LinphoneFriendList;Lorg/linphone/core/LinphoneFriend;)V");
|
||||
jobject jlist = getFriendList(env, list);
|
||||
jobject jfriend = getFriend(env, lf);
|
||||
env->DeleteLocalRef(clazz);
|
||||
env->CallVoidMethod(listener, method, jlist, jfriend);
|
||||
}
|
||||
|
||||
static void sync_status_changed(LinphoneFriendList *list, LinphoneFriendListSyncStatus status, const char *message) {
|
||||
JNIEnv *env = 0;
|
||||
jint result = jvm->AttachCurrentThread(&env,NULL);
|
||||
if (result != 0) {
|
||||
ms_error("cannot attach VM\n");
|
||||
return;
|
||||
}
|
||||
|
||||
LinphoneFriendListCbs *cbs = linphone_friend_list_get_callbacks(list);
|
||||
jobject listener = (jobject) linphone_friend_list_cbs_get_user_data(cbs);
|
||||
|
||||
if (listener == NULL) {
|
||||
ms_error("sync_status_changed() notification without listener");
|
||||
return ;
|
||||
}
|
||||
jclass clazz = (jclass) env->GetObjectClass(listener);
|
||||
jmethodID method = env->GetMethodID(clazz, "onLinphoneFriendSyncStatusChanged","(Lorg/linphone/core/LinphoneFriendList;Lorg/linphone/core/LinphoneFriendList$State;Ljava/lang/String;)V");
|
||||
jobject jlist = getFriendList(env, list);
|
||||
env->DeleteLocalRef(clazz);
|
||||
|
||||
LinphoneCore *lc = linphone_friend_list_get_core((LinphoneFriendList *)list);
|
||||
LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc);
|
||||
jstring msg = message ? env->NewStringUTF(message) : NULL;
|
||||
env->CallVoidMethod(listener, method, jlist, env->CallStaticObjectMethod(ljb->friendListSyncStateClass, ljb->friendListSyncStateFromIntId, (jint)status), msg);
|
||||
if (msg) {
|
||||
env->DeleteLocalRef(msg);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneFriendListImpl_setListener(JNIEnv* env, jobject thiz, jlong ptr, jobject jlistener) {
|
||||
jobject listener = env->NewGlobalRef(jlistener);
|
||||
LinphoneFriendList *list = (LinphoneFriendList *)ptr;
|
||||
LinphoneFriendListCbs *cbs;
|
||||
|
||||
cbs = linphone_friend_list_get_callbacks(list);
|
||||
linphone_friend_list_cbs_set_user_data(cbs, listener);
|
||||
linphone_friend_list_cbs_set_contact_created(cbs, contact_created);
|
||||
linphone_friend_list_cbs_set_contact_updated(cbs, contact_updated);
|
||||
linphone_friend_list_cbs_set_contact_deleted(cbs, contact_removed);
|
||||
linphone_friend_list_cbs_set_sync_status_changed(cbs, sync_status_changed);
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneFriendImpl_setAddress(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr
|
||||
|
|
@ -3104,13 +3371,22 @@ extern "C" void Java_org_linphone_core_LinphoneFriendImpl_setAddress(JNIEnv* en
|
|||
linphone_friend_set_address((LinphoneFriend*)ptr,(LinphoneAddress*)linphoneAddress);
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneFriendImpl_setName(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr
|
||||
,jstring jname) {
|
||||
const char* name = env->GetStringUTFChars(jname, NULL);
|
||||
linphone_friend_set_name((LinphoneFriend*)ptr, name);
|
||||
env->ReleaseStringUTFChars(jname, name);
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneFriendListImpl_setRLSUri(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr
|
||||
,jstring jrlsUri) {
|
||||
const char* uri = env->GetStringUTFChars(jrlsUri, NULL);
|
||||
linphone_friend_list_set_rls_uri((LinphoneFriendList*)ptr,uri);
|
||||
env->ReleaseStringUTFChars(jrlsUri, uri);
|
||||
linphone_friend_list_set_rls_uri((LinphoneFriendList*)ptr, uri);
|
||||
env->ReleaseStringUTFChars(jrlsUri, uri);
|
||||
}
|
||||
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneFriendListImpl_findFriendByUri(JNIEnv* env
|
||||
|
|
@ -3118,9 +3394,9 @@ extern "C" jlong Java_org_linphone_core_LinphoneFriendListImpl_findFriendByUri(J
|
|||
,jlong friendListptr
|
||||
,jstring juri) {
|
||||
const char* uri = env->GetStringUTFChars(juri, NULL);
|
||||
LinphoneFriend* lResult;
|
||||
lResult = linphone_friend_list_find_friend_by_uri((LinphoneFriendList*)friendListptr,uri);
|
||||
env->ReleaseStringUTFChars(juri, uri);
|
||||
LinphoneFriend* lResult;
|
||||
lResult = linphone_friend_list_find_friend_by_uri((LinphoneFriendList*)friendListptr, uri);
|
||||
env->ReleaseStringUTFChars(juri, uri);
|
||||
return (jlong)lResult;
|
||||
}
|
||||
|
||||
|
|
@ -3128,7 +3404,33 @@ extern "C" void Java_org_linphone_core_LinphoneFriendListImpl_addFriend(JNIEnv*
|
|||
,jobject thiz
|
||||
,jlong friendListptr
|
||||
,jlong friendPtr) {
|
||||
linphone_friend_list_add_friend((LinphoneFriendList*)friendListptr,(LinphoneFriend*)friendPtr);
|
||||
linphone_friend_list_add_friend((LinphoneFriendList*)friendListptr, (LinphoneFriend*)friendPtr);
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneFriendListImpl_addLocalFriend(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong friendListptr
|
||||
,jlong friendPtr) {
|
||||
linphone_friend_list_add_local_friend((LinphoneFriendList*)friendListptr, (LinphoneFriend*)friendPtr);
|
||||
}
|
||||
|
||||
extern "C" jobjectArray Java_org_linphone_core_LinphoneFriendListImpl_getFriendList(JNIEnv* env, jobject thiz, jlong list) {
|
||||
const MSList* friends = linphone_friend_list_get_friends((LinphoneFriendList *)list);
|
||||
int friendsSize = ms_list_size(friends);
|
||||
LinphoneCore *lc = linphone_friend_list_get_core((LinphoneFriendList *)list);
|
||||
LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc);
|
||||
jobjectArray jFriends = env->NewObjectArray(friendsSize,ljb->friendClass,NULL);
|
||||
|
||||
for (int i = 0; i < friendsSize; i++) {
|
||||
LinphoneFriend* lfriend = (LinphoneFriend*)friends->data;
|
||||
jobject jfriend = getFriend(env,lfriend);
|
||||
if(jfriend != NULL){
|
||||
env->SetObjectArrayElement(jFriends, i, jfriend);
|
||||
}
|
||||
friends = friends->next;
|
||||
}
|
||||
|
||||
return jFriends;
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneFriendListImpl_updateSubscriptions(JNIEnv* env
|
||||
|
|
@ -3136,7 +3438,7 @@ extern "C" void Java_org_linphone_core_LinphoneFriendListImpl_updateSubscription
|
|||
,jlong friendListptr
|
||||
,jlong proxyConfigPtr
|
||||
,jboolean jonlyWhenRegistered) {
|
||||
linphone_friend_list_update_subscriptions((LinphoneFriendList*)friendListptr,(LinphoneProxyConfig*)proxyConfigPtr,jonlyWhenRegistered);
|
||||
linphone_friend_list_update_subscriptions((LinphoneFriendList*)friendListptr, (LinphoneProxyConfig*)proxyConfigPtr, jonlyWhenRegistered);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -3147,6 +3449,14 @@ extern "C" jlong Java_org_linphone_core_LinphoneFriendImpl_getAddress(JNIEnv* e
|
|||
,jlong ptr) {
|
||||
return (jlong)linphone_friend_get_address((LinphoneFriend*)ptr);
|
||||
}
|
||||
|
||||
extern "C" jstring Java_org_linphone_core_LinphoneFriendImpl_getName(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr) {
|
||||
const char *name = linphone_friend_get_name((LinphoneFriend*)ptr);
|
||||
return name ? env->NewStringUTF(name) : NULL;
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneFriendImpl_setIncSubscribePolicy(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define LINPHONEFRIEND_H_
|
||||
|
||||
#include "linphonepresence.h"
|
||||
#include "vcard.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
@ -354,13 +355,15 @@ LINPHONE_PUBLIC void linphone_core_interpret_friend_uri(LinphoneCore *lc, const
|
|||
* Add a friend to the current buddy list, if \link linphone_friend_enable_subscribes() subscription attribute \endlink is set, a SIP SUBSCRIBE message is sent.
|
||||
* @param lc #LinphoneCore object
|
||||
* @param fr #LinphoneFriend to add
|
||||
* @deprecated use linphone_friend_list_add_friend() instead.
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *fr);
|
||||
|
||||
/**
|
||||
* remove a friend from the buddy list
|
||||
* Removes a friend from the buddy list
|
||||
* @param lc #LinphoneCore object
|
||||
* @param fr #LinphoneFriend to add
|
||||
* @param fr #LinphoneFriend to remove
|
||||
* @deprecated use linphone_friend_list_remove_friend() instead.
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_core_remove_friend(LinphoneCore *lc, LinphoneFriend *fr);
|
||||
|
||||
|
|
@ -375,6 +378,7 @@ LINPHONE_PUBLIC void linphone_core_reject_subscriber(LinphoneCore *lc, LinphoneF
|
|||
* Get Buddy list of LinphoneFriend
|
||||
* @param[in] lc #LinphoneCore object
|
||||
* @return \mslist{LinphoneFriend}
|
||||
* @deprecated use linphone_core_get_friends_lists() or linphone_friend_list_get_friends() instead.
|
||||
*/
|
||||
LINPHONE_PUBLIC const MSList * linphone_core_get_friend_list(const LinphoneCore *lc);
|
||||
|
||||
|
|
@ -419,14 +423,60 @@ LINPHONE_PUBLIC LinphoneFriend * linphone_friend_ref(LinphoneFriend *lf);
|
|||
|
||||
/**
|
||||
* Release a reference to the linphone friend.
|
||||
* @param[in] lf LinohoneFriend 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
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneCore *linphone_friend_get_core(const LinphoneFriend *fr);
|
||||
|
||||
/**
|
||||
* Returns the vCard object associated to this friend, if any
|
||||
* @param[in] fr LinphoneFriend object
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneVCard* linphone_friend_get_vcard(LinphoneFriend *fr);
|
||||
|
||||
/**
|
||||
* Binds a vCard object to a friend
|
||||
* @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] 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
|
||||
*/
|
||||
LINPHONE_PUBLIC bool_t linphone_friend_create_vcard(LinphoneFriend *fr, const char *name);
|
||||
|
||||
/**
|
||||
* Contructor same as linphone_friend_new() + linphone_friend_set_address()
|
||||
* @param vcard a vCard object
|
||||
* @return a new #LinphoneFriend with \link linphone_friend_get_vcard() vCard initialized \endlink
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneFriend *linphone_friend_new_from_vcard(LinphoneVCard *vcard);
|
||||
|
||||
/**
|
||||
* Sets the database filename where friends will be stored.
|
||||
* If the file does not exist, it will be created.
|
||||
* @ingroup initializing
|
||||
* @param lc the linphone core
|
||||
* @param path filesystem path
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_core_set_friends_database_path(LinphoneCore *lc, const char *path);
|
||||
|
||||
/**
|
||||
* Migrates the friends from the linphonerc to the database if not done yet
|
||||
* @ingroup initializing
|
||||
* @param lc the linphone core
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_core_migrate_friends_from_rc_to_db(LinphoneCore *lc);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1486,7 +1486,7 @@ void linphone_core_notify_all_friends(LinphoneCore *lc, LinphonePresenceModel *p
|
|||
char *activity_str = linphone_presence_activity_to_string(activity);
|
||||
ms_message("Notifying all friends that we are [%s]", activity_str);
|
||||
if (activity_str != NULL) ms_free(activity_str);
|
||||
linphone_friend_list_notify_presence(lc->friendlist, presence);
|
||||
linphone_friend_list_notify_presence(linphone_core_get_default_friend_list(lc), presence);
|
||||
}
|
||||
|
||||
void linphone_subscription_new(LinphoneCore *lc, SalOp *op, const char *from){
|
||||
|
|
@ -1500,8 +1500,8 @@ void linphone_subscription_new(LinphoneCore *lc, SalOp *op, const char *from){
|
|||
ms_message("Receiving new subscription from %s.",from);
|
||||
|
||||
/* check if we answer to this subscription */
|
||||
if (lc->friendlist != NULL) {
|
||||
lf = linphone_friend_list_find_friend_by_address(lc->friendlist, uri);
|
||||
if (linphone_core_get_default_friend_list(lc) != NULL) {
|
||||
lf = linphone_friend_list_find_friend_by_address(linphone_core_get_default_friend_list(lc), uri);
|
||||
}
|
||||
if (lf!=NULL){
|
||||
linphone_friend_add_incoming_subscription(lf, op);
|
||||
|
|
@ -1879,11 +1879,11 @@ void linphone_notify_recv(LinphoneCore *lc, SalOp *op, SalSubscribeStatus ss, Sa
|
|||
LinphoneAddress *friend=NULL;
|
||||
LinphonePresenceModel *presence = model ? (LinphonePresenceModel *)model:linphone_presence_model_new_with_activity(LinphonePresenceActivityOffline, NULL);
|
||||
|
||||
if (lc->friendlist != NULL)
|
||||
lf=linphone_friend_list_find_friend_by_out_subscribe(lc->friendlist,op);
|
||||
if (linphone_core_get_default_friend_list(lc) != NULL)
|
||||
lf=linphone_friend_list_find_friend_by_out_subscribe(linphone_core_get_default_friend_list(lc), op);
|
||||
if (lf==NULL && lp_config_get_int(lc->config,"sip","allow_out_of_subscribe_presence",0)){
|
||||
const SalAddress *addr=sal_op_get_from_address(op);
|
||||
lf = linphone_friend_list_find_friend_by_address(lc->friendlist, (LinphoneAddress *)addr);
|
||||
lf = linphone_friend_list_find_friend_by_address(linphone_core_get_default_friend_list(lc), (LinphoneAddress *)addr);
|
||||
}
|
||||
if (lf!=NULL){
|
||||
LinphonePresenceActivity *activity = NULL;
|
||||
|
|
@ -1929,8 +1929,8 @@ void linphone_notify_recv(LinphoneCore *lc, SalOp *op, SalSubscribeStatus ss, Sa
|
|||
void linphone_subscription_closed(LinphoneCore *lc, SalOp *op){
|
||||
LinphoneFriend *lf = NULL;
|
||||
|
||||
if (lc->friendlist != NULL)
|
||||
lf=linphone_friend_list_find_friend_by_inc_subscribe(lc->friendlist,op);
|
||||
if (linphone_core_get_default_friend_list(lc) != NULL)
|
||||
lf = linphone_friend_list_find_friend_by_inc_subscribe(linphone_core_get_default_friend_list(lc), op);
|
||||
|
||||
if (lf!=NULL){
|
||||
/*this will release the op*/
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include "sipsetup.h"
|
||||
#include "quality_reporting.h"
|
||||
#include "ringtoneplayer.h"
|
||||
#include "vcard.h"
|
||||
|
||||
#include <belle-sip/object.h>
|
||||
#include <belle-sip/dict.h>
|
||||
|
|
@ -422,6 +423,15 @@ LinphoneFriend *linphone_friend_list_find_friend_by_out_subscribe(const Linphone
|
|||
MSList *linphone_find_friend_by_address(MSList *fl, const LinphoneAddress *addr, LinphoneFriend **lf);
|
||||
bool_t linphone_core_should_subscribe_friends_only_when_registered(const LinphoneCore *lc);
|
||||
void linphone_core_update_friends_subscriptions(LinphoneCore *lc, LinphoneProxyConfig *cfg, bool_t only_when_registered);
|
||||
void linphone_core_friends_storage_init(LinphoneCore *lc);
|
||||
void linphone_core_friends_storage_close(LinphoneCore *lc);
|
||||
void linphone_core_store_friend_in_db(LinphoneCore *lc, LinphoneFriend *lf);
|
||||
void linphone_core_remove_friend_from_db(LinphoneCore *lc, LinphoneFriend *lf);
|
||||
void linphone_core_store_friends_list_in_db(LinphoneCore *lc, LinphoneFriendList *list);
|
||||
void linphone_core_remove_friends_list_from_db(LinphoneCore *lc, LinphoneFriendList *list);
|
||||
LINPHONE_PUBLIC MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc, LinphoneFriendList *list);
|
||||
LINPHONE_PUBLIC MSList* linphone_core_fetch_friends_lists_from_db(LinphoneCore *lc);
|
||||
LINPHONE_PUBLIC LinphoneFriendListStatus linphone_friend_list_import_friend(LinphoneFriendList *list, LinphoneFriend *lf, bool_t synchronize);
|
||||
|
||||
int parse_hostname_to_addr(const char *server, struct sockaddr_storage *ss, socklen_t *socklen, int default_port);
|
||||
|
||||
|
|
@ -678,17 +688,29 @@ struct _LinphoneFriend{
|
|||
struct _LinphoneCore *lc;
|
||||
BuddyInfo *info;
|
||||
char *refkey;
|
||||
bool_t in_list;
|
||||
bool_t subscribe;
|
||||
bool_t subscribe_active;
|
||||
bool_t inc_subscribe_pending;
|
||||
bool_t commit;
|
||||
bool_t initial_subscribes_sent; /*used to know if initial subscribe message was sent or not*/
|
||||
bool_t presence_received;
|
||||
LinphoneVCard *vcard;
|
||||
unsigned int storage_id;
|
||||
LinphoneFriendList *friend_list;
|
||||
};
|
||||
|
||||
BELLE_SIP_DECLARE_VPTR(LinphoneFriend);
|
||||
|
||||
struct _LinphoneFriendListCbs {
|
||||
belle_sip_object_t base;
|
||||
void *user_data;
|
||||
LinphoneFriendListContactCreatedCb contact_created_cb;
|
||||
LinphoneFriendListContactDeletedCb contact_deleted_cb;
|
||||
LinphoneFriendListContactUpdatedCb contact_updated_cb;
|
||||
LinphoneFriendListSyncStateChangedCb sync_state_changed_cb;
|
||||
};
|
||||
|
||||
BELLE_SIP_DECLARE_VPTR(LinphoneFriendListCbs);
|
||||
|
||||
struct _LinphoneFriendList {
|
||||
belle_sip_object_t base;
|
||||
|
|
@ -700,11 +722,17 @@ struct _LinphoneFriendList {
|
|||
MSList *friends;
|
||||
unsigned char *content_digest;
|
||||
int expected_notification_version;
|
||||
unsigned int storage_id;
|
||||
char *uri;
|
||||
MSList *dirty_friends_to_update;
|
||||
int revision;
|
||||
LinphoneFriendListCbs *cbs;
|
||||
};
|
||||
|
||||
BELLE_SIP_DECLARE_VPTR(LinphoneFriendList);
|
||||
|
||||
|
||||
|
||||
typedef struct sip_config
|
||||
{
|
||||
char *contact;
|
||||
|
|
@ -885,7 +913,7 @@ struct _LinphoneCore
|
|||
ui_config_t ui_conf;
|
||||
autoreplier_config_t autoreplier_conf;
|
||||
LinphoneProxyConfig *default_proxy;
|
||||
LinphoneFriendList *friendlist;
|
||||
MSList *friends_lists;
|
||||
MSList *auth_info;
|
||||
struct _RingStream *ringstream;
|
||||
time_t dmfs_playing_start_time;
|
||||
|
|
@ -955,6 +983,10 @@ struct _LinphoneCore
|
|||
char *logs_db_file;
|
||||
#ifdef CALL_LOGS_STORAGE_ENABLED
|
||||
sqlite3 *logs_db;
|
||||
#endif
|
||||
char *friends_db_file;
|
||||
#ifdef FRIENDS_SQL_STORAGE_ENABLED
|
||||
sqlite3 *friends_db;
|
||||
#endif
|
||||
#ifdef BUILD_UPNP
|
||||
UpnpContext *upnp;
|
||||
|
|
@ -1229,9 +1261,41 @@ struct _LinphoneAccountCreator {
|
|||
|
||||
BELLE_SIP_DECLARE_VPTR(LinphoneAccountCreator);
|
||||
|
||||
/*****************************************************************************
|
||||
* CardDAV interface *
|
||||
****************************************************************************/
|
||||
|
||||
struct _LinphoneCardDavContext {
|
||||
LinphoneFriendList *friend_list;
|
||||
int ctag;
|
||||
void *user_data;
|
||||
LinphoneCardDavContactCreatedCb contact_created_cb;
|
||||
LinphoneCardDavContactUpdatedCb contact_updated_cb;
|
||||
LinphoneCardDavContactRemovedCb contact_removed_cb;
|
||||
LinphoneCardDavSynchronizationDoneCb sync_done_cb;
|
||||
};
|
||||
|
||||
struct _LinphoneCardDavQuery {
|
||||
LinphoneCardDavContext *context;
|
||||
const char *url;
|
||||
const char *method;
|
||||
const char *body;
|
||||
const char *depth;
|
||||
const char *ifmatch;
|
||||
belle_http_request_listener_t *http_request_listener;
|
||||
void *user_data;
|
||||
LinphoneCardDavQueryType type;
|
||||
};
|
||||
|
||||
struct _LinphoneCardDavResponse {
|
||||
LinphoneCardDavContext *context;
|
||||
const char *etag;
|
||||
const char *url;
|
||||
const char *vcard;
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* REMOTE PROVISIONING FUNCTIONS *
|
||||
* REMOTE PROVISIONING FUNCTIONS *
|
||||
****************************************************************************/
|
||||
|
||||
void linphone_configuring_terminated(LinphoneCore *lc, LinphoneConfiguringState state, const char *message);
|
||||
|
|
@ -1239,7 +1303,7 @@ int linphone_remote_provisioning_download_and_apply(LinphoneCore *lc, const char
|
|||
LINPHONE_PUBLIC int linphone_remote_provisioning_load_file( LinphoneCore* lc, const char* file_path);
|
||||
|
||||
/*****************************************************************************
|
||||
* Player interface
|
||||
* Player interface *
|
||||
****************************************************************************/
|
||||
|
||||
struct _LinphonePlayer{
|
||||
|
|
@ -1282,6 +1346,7 @@ char * linphone_get_xml_text_content(xmlparsing_context_t *xml_ctx, const char *
|
|||
const char * linphone_get_xml_attribute_text_content(xmlparsing_context_t *xml_ctx, const char *xpath_expression, const char *attribute_name);
|
||||
void linphone_free_xml_text_content(const char *text);
|
||||
xmlXPathObjectPtr linphone_get_xml_xpath_object_for_node_list(xmlparsing_context_t *xml_ctx, const char *xpath_expression);
|
||||
void linphone_xml_xpath_context_init_carddav_ns(xmlparsing_context_t *xml_ctx);
|
||||
|
||||
/*****************************************************************************
|
||||
* OTHER UTILITY FUNCTIONS *
|
||||
|
|
@ -1338,6 +1403,7 @@ BELLE_SIP_TYPE_ID(LinphoneXmlRpcRequest),
|
|||
BELLE_SIP_TYPE_ID(LinphoneXmlRpcRequestCbs),
|
||||
BELLE_SIP_TYPE_ID(LinphoneXmlRpcSession),
|
||||
BELLE_SIP_TYPE_ID(LinphoneTunnelConfig),
|
||||
BELLE_SIP_TYPE_ID(LinphoneFriendListCbs),
|
||||
BELLE_SIP_TYPE_ID(LinphoneEvent)
|
||||
BELLE_SIP_DECLARE_TYPES_END
|
||||
|
||||
|
|
@ -1379,6 +1445,8 @@ void linphone_core_notify_subscription_state_changed(LinphoneCore *lc, LinphoneE
|
|||
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);
|
||||
void linphone_core_notify_log_collection_upload_progress_indication(LinphoneCore *lc, size_t offset, size_t total);
|
||||
void linphone_core_notify_friend_list_created(LinphoneCore *lc, LinphoneFriendList *list);
|
||||
void linphone_core_notify_friend_list_removed(LinphoneCore *lc, LinphoneFriendList *list);
|
||||
|
||||
void set_mic_gain_db(AudioStream *st, float gain);
|
||||
void set_playback_gain_db(AudioStream *st, float gain);
|
||||
|
|
|
|||
262
coreapi/vcard.cc
Normal file
262
coreapi/vcard.cc
Normal file
|
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
vcard.cc
|
||||
Copyright (C) 2015 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "vcard.h"
|
||||
#include "belcard/belcard.hpp"
|
||||
#include "belcard/belcard_parser.hpp"
|
||||
#include "sal/sal.h"
|
||||
#include <polarssl/md5.h>
|
||||
|
||||
struct _LinphoneVCard {
|
||||
shared_ptr<belcard::BelCard> belCard;
|
||||
char *etag;
|
||||
char *url;
|
||||
unsigned char *md5;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
LinphoneVCard* linphone_vcard_new(void) {
|
||||
LinphoneVCard* vCard = (LinphoneVCard*) ms_new0(LinphoneVCard, 1);
|
||||
vCard->belCard = belcard::BelCardGeneric::create<belcard::BelCard>();
|
||||
return vCard;
|
||||
}
|
||||
|
||||
void linphone_vcard_free(LinphoneVCard *vCard) {
|
||||
if (!vCard) return;
|
||||
|
||||
vCard->belCard.reset();
|
||||
ms_free(vCard);
|
||||
}
|
||||
|
||||
MSList* linphone_vcard_list_from_vcard4_file(const char *filename) {
|
||||
MSList *result = NULL;
|
||||
if (filename && ortp_file_exist(filename) == 0) {
|
||||
belcard::BelCardParser parser = belcard::BelCardParser::getInstance();
|
||||
shared_ptr<belcard::BelCardList> belCards = parser.parseFile(filename);
|
||||
if (belCards) {
|
||||
for (auto it = belCards->getCards().begin(); it != belCards->getCards().end(); ++it) {
|
||||
shared_ptr<belcard::BelCard> belcard = (*it);
|
||||
LinphoneVCard *vCard = linphone_vcard_new();
|
||||
vCard->belCard = belcard;
|
||||
result = ms_list_append(result, vCard);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
MSList* linphone_vcard_list_from_vcard4_buffer(const char *buffer) {
|
||||
MSList *result = NULL;
|
||||
if (buffer) {
|
||||
belcard::BelCardParser parser = belcard::BelCardParser::getInstance();
|
||||
shared_ptr<belcard::BelCardList> belCards = parser.parse(buffer);
|
||||
if (belCards) {
|
||||
for (auto it = belCards->getCards().begin(); it != belCards->getCards().end(); ++it) {
|
||||
shared_ptr<belcard::BelCard> belCard = (*it);
|
||||
LinphoneVCard *vCard = linphone_vcard_new();
|
||||
vCard->belCard = belCard;
|
||||
result = ms_list_append(result, vCard);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
LinphoneVCard* linphone_vcard_new_from_vcard4_buffer(const char *buffer) {
|
||||
LinphoneVCard *vCard = NULL;
|
||||
if (buffer) {
|
||||
belcard::BelCardParser parser = belcard::BelCardParser::getInstance();
|
||||
shared_ptr<belcard::BelCard> belCard = parser.parseOne(buffer);
|
||||
if (belCard) {
|
||||
vCard = linphone_vcard_new();
|
||||
vCard->belCard = belCard;
|
||||
} else {
|
||||
ms_error("Couldn't parse buffer %s", buffer);
|
||||
}
|
||||
}
|
||||
return vCard;
|
||||
}
|
||||
|
||||
const char * linphone_vcard_as_vcard4_string(LinphoneVCard *vCard) {
|
||||
if (!vCard) return NULL;
|
||||
|
||||
return vCard->belCard->toFoldedString().c_str();
|
||||
}
|
||||
|
||||
void linphone_vcard_set_full_name(LinphoneVCard *vCard, const char *name) {
|
||||
if (!vCard || !name) return;
|
||||
|
||||
shared_ptr<belcard::BelCardFullName> fn = belcard::BelCardGeneric::create<belcard::BelCardFullName>();
|
||||
fn->setValue(name);
|
||||
vCard->belCard->setFullName(fn);
|
||||
}
|
||||
|
||||
const char* linphone_vcard_get_full_name(const LinphoneVCard *vCard) {
|
||||
if (!vCard) return NULL;
|
||||
|
||||
const char *result = vCard->belCard->getFullName() ? vCard->belCard->getFullName()->getValue().c_str() : NULL;
|
||||
return result;
|
||||
}
|
||||
|
||||
void linphone_vcard_add_sip_address(LinphoneVCard *vCard, const char *sip_address) {
|
||||
if (!vCard || !sip_address) return;
|
||||
|
||||
shared_ptr<belcard::BelCardImpp> impp = belcard::BelCardGeneric::create<belcard::BelCardImpp>();
|
||||
impp->setValue(sip_address);
|
||||
vCard->belCard->addImpp(impp);
|
||||
}
|
||||
|
||||
void linphone_vcard_remove_sip_address(LinphoneVCard *vCard, const char *sip_address) {
|
||||
if (!vCard) return;
|
||||
|
||||
for (auto it = vCard->belCard->getImpp().begin(); it != vCard->belCard->getImpp().end(); ++it) {
|
||||
const char *value = (*it)->getValue().c_str();
|
||||
if (strcmp(value, sip_address) == 0) {
|
||||
vCard->belCard->removeImpp(*it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_vcard_edit_main_sip_address(LinphoneVCard *vCard, const char *sip_address) {
|
||||
if (!vCard || !sip_address) return;
|
||||
|
||||
if (vCard->belCard->getImpp().size() > 0) {
|
||||
const shared_ptr<belcard::BelCardImpp> impp = vCard->belCard->getImpp().front();
|
||||
impp->setValue(sip_address);
|
||||
} else {
|
||||
shared_ptr<belcard::BelCardImpp> impp = belcard::BelCardGeneric::create<belcard::BelCardImpp>();
|
||||
impp->setValue(sip_address);
|
||||
vCard->belCard->addImpp(impp);
|
||||
}
|
||||
}
|
||||
|
||||
MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vCard) {
|
||||
MSList *result = NULL;
|
||||
if (!vCard) return NULL;
|
||||
|
||||
for (auto it = vCard->belCard->getImpp().begin(); it != vCard->belCard->getImpp().end(); ++it) {
|
||||
const char *value = (*it)->getValue().c_str();
|
||||
if (strncmp(value, "sip:", 4) == 0) {
|
||||
result = ms_list_append(result, (char *)value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool_t linphone_vcard_generate_unique_id(LinphoneVCard *vCard) {
|
||||
char uuid[64];
|
||||
|
||||
if (vCard) {
|
||||
if (linphone_vcard_get_uid(vCard)) {
|
||||
return FALSE;
|
||||
}
|
||||
if (sal_generate_uuid(uuid, sizeof(uuid)) == 0) {
|
||||
char vcard_uuid[sizeof(uuid)+4];
|
||||
snprintf(vcard_uuid, sizeof(vcard_uuid), "urn:%s", uuid);
|
||||
linphone_vcard_set_uid(vCard, ms_strdup(vcard_uuid));
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void linphone_vcard_set_uid(LinphoneVCard *vCard, const char *uid) {
|
||||
if (!vCard || !uid) return;
|
||||
|
||||
shared_ptr<belcard::BelCardUniqueId> uniqueId = belcard::BelCardGeneric::create<belcard::BelCardUniqueId>();
|
||||
uniqueId->setValue(uid);
|
||||
vCard->belCard->setUniqueId(uniqueId);
|
||||
}
|
||||
|
||||
const char* linphone_vcard_get_uid(const LinphoneVCard *vCard) {
|
||||
if (vCard && vCard->belCard->getUniqueId()) {
|
||||
return vCard->belCard->getUniqueId()->getValue().c_str();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void linphone_vcard_set_etag(LinphoneVCard *vCard, const char * etag) {
|
||||
if (!vCard) {
|
||||
return;
|
||||
}
|
||||
if (vCard->etag) {
|
||||
ms_free(vCard->etag);
|
||||
}
|
||||
vCard->etag = ms_strdup(etag);
|
||||
}
|
||||
|
||||
const char* linphone_vcard_get_etag(const LinphoneVCard *vCard) {
|
||||
if (!vCard) return NULL;
|
||||
return vCard->etag;
|
||||
}
|
||||
|
||||
void linphone_vcard_set_url(LinphoneVCard *vCard, const char * url) {
|
||||
if (!vCard) {
|
||||
return;
|
||||
}
|
||||
if (vCard->url) {
|
||||
ms_free(vCard->url);
|
||||
}
|
||||
vCard->url = ms_strdup(url);
|
||||
}
|
||||
|
||||
const char* linphone_vcard_get_url(const LinphoneVCard *vCard) {
|
||||
if (!vCard) return NULL;
|
||||
return vCard->url;
|
||||
}
|
||||
|
||||
#define VCARD_MD5_HASH_SIZE 16
|
||||
|
||||
void linphone_vcard_compute_md5_hash(LinphoneVCard *vCard) {
|
||||
unsigned char digest[VCARD_MD5_HASH_SIZE];
|
||||
const char *text = NULL;
|
||||
if (!vCard) {
|
||||
return;
|
||||
}
|
||||
text = linphone_vcard_as_vcard4_string(vCard);
|
||||
md5((unsigned char *)text, strlen(text), digest);
|
||||
vCard->md5 = (unsigned char *)ms_malloc(sizeof(digest));
|
||||
memcpy(vCard->md5, digest, sizeof(digest));
|
||||
}
|
||||
|
||||
bool_t linphone_vcard_compare_md5_hash(LinphoneVCard *vCard) {
|
||||
unsigned char *previous_md5 = vCard->md5;
|
||||
unsigned char *new_md5 = NULL;
|
||||
int result = -1;
|
||||
|
||||
if (!previous_md5) {
|
||||
return result;
|
||||
}
|
||||
|
||||
linphone_vcard_compute_md5_hash(vCard);
|
||||
new_md5 = vCard->md5;
|
||||
result = memcmp(new_md5, previous_md5, VCARD_MD5_HASH_SIZE);
|
||||
|
||||
ms_free(previous_md5);
|
||||
ms_free(new_md5);
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
193
coreapi/vcard.h
Normal file
193
coreapi/vcard.h
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
vcard.h
|
||||
Copyright (C) 2015 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef LINPHONE_VCARD_H
|
||||
#define LINPHONE_VCARD_H
|
||||
|
||||
#include <mediastreamer2/mscommon.h>
|
||||
|
||||
#ifndef LINPHONE_PUBLIC
|
||||
#define LINPHONE_PUBLIC MS2_PUBLIC
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup carddav_vcard
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef struct _LinphoneVCard LinphoneVCard;
|
||||
|
||||
/**
|
||||
* Creates a LinphoneVCard object that has a pointer to an empty vCard
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneVCard* linphone_vcard_new(void);
|
||||
|
||||
/**
|
||||
* Deletes a LinphoneVCard object properly
|
||||
* @param[in] vCard the LinphoneVCard to destroy
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_vcard_free(LinphoneVCard *vCard);
|
||||
|
||||
/**
|
||||
* Uses belcard to parse the content of a file and returns all the vcards it contains as LinphoneVCards, or NULL if it contains none.
|
||||
* @param[in] file the path to the file to parse
|
||||
* @return \mslist{LinphoneVCard}
|
||||
*/
|
||||
LINPHONE_PUBLIC MSList* linphone_vcard_list_from_vcard4_file(const char *file);
|
||||
|
||||
/**
|
||||
* Uses belcard to parse the content of a buffer and returns all the vcards it contains as LinphoneVCards, or NULL if it contains none.
|
||||
* @param[in] buffer the buffer to parse
|
||||
* @return \mslist{LinphoneVCard}
|
||||
*/
|
||||
LINPHONE_PUBLIC MSList* linphone_vcard_list_from_vcard4_buffer(const char *buffer);
|
||||
|
||||
/**
|
||||
* Uses belcard to parse the content of a buffer and returns one vCard if possible, or NULL otherwise.
|
||||
* @param[in] buffer the buffer to parse
|
||||
* @return a LinphoneVCard if one could be parsed, or NULL otherwise
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneVCard* linphone_vcard_new_from_vcard4_buffer(const char *buffer);
|
||||
|
||||
/**
|
||||
* Returns the vCard4 representation of 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] 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
|
||||
* @return the display name of the vCard, or NULL
|
||||
*/
|
||||
LINPHONE_PUBLIC const char* linphone_vcard_get_full_name(const LinphoneVCard *vCard);
|
||||
|
||||
/**
|
||||
* Adds a SIP address in the vCard, using the IMPP property
|
||||
* @param[in] vCard the LinphoneVCard
|
||||
* @param[in] sip_address the SIP address to add
|
||||
*/
|
||||
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] sip_address the SIP address to remove
|
||||
*/
|
||||
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] sip_address the new SIP address
|
||||
*/
|
||||
void linphone_vcard_edit_main_sip_address(LinphoneVCard *vCard, const char *sip_address);
|
||||
|
||||
/**
|
||||
* Returns the list of SIP addresses (as const char *) in the vCard (all the IMPP attributes that has an URI value starting by "sip:") or NULL
|
||||
* @param[in] vCard the LinphoneVCard
|
||||
* @return \mslist{const char *}
|
||||
*/
|
||||
LINPHONE_PUBLIC MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vCard);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @return TRUE if operation is successful, otherwise FALSE (for example if it already has an unique ID)
|
||||
*/
|
||||
bool_t linphone_vcard_generate_unique_id(LinphoneVCard *vCard);
|
||||
|
||||
/**
|
||||
* Sets the unique ID of the vCard
|
||||
* @param[in] vCard the LinphoneVCard
|
||||
* @param[in] uid the unique id
|
||||
*/
|
||||
void linphone_vcard_set_uid(LinphoneVCard *vCard, const char *uid);
|
||||
|
||||
/**
|
||||
* Gets the UID of the vCard
|
||||
* @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] 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
|
||||
* @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] 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
|
||||
* @return the URL of the vCard in the CardDAV server, otherwise NULL
|
||||
*/
|
||||
LINPHONE_PUBLIC const char* linphone_vcard_get_url(const LinphoneVCard *vCard);
|
||||
|
||||
/**
|
||||
* Computes the md5 hash for the vCard
|
||||
* @param[in] vCard the LinphoneVCard
|
||||
*/
|
||||
void linphone_vcard_compute_md5_hash(LinphoneVCard *vCard);
|
||||
|
||||
/**
|
||||
* Compares the previously computed md5 hash (using linphone_vcard_compute_md5_hash) with the current one
|
||||
* @param[in] vCard the LinphoneVCard
|
||||
* @return 0 if the md5 hasn't changed, 1 otherwise
|
||||
*/
|
||||
bool_t linphone_vcard_compare_md5_hash(LinphoneVCard *vCard);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
108
coreapi/vcard_stubs.c
Normal file
108
coreapi/vcard_stubs.c
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
vcard_stubs.c
|
||||
Copyright (C) 2015 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "vcard.h"
|
||||
|
||||
struct _LinphoneVCard {
|
||||
void *dummy;
|
||||
};
|
||||
|
||||
LinphoneVCard* linphone_vcard_new(void) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void linphone_vcard_free(LinphoneVCard *vCard) {
|
||||
|
||||
}
|
||||
|
||||
MSList* linphone_vcard_list_from_vcard4_file(const char *filename) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MSList* linphone_vcard_list_from_vcard4_buffer(const char *buffer) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LinphoneVCard* linphone_vcard_new_from_vcard4_buffer(const char *buffer) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char * linphone_vcard_as_vcard4_string(LinphoneVCard *vCard) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void linphone_vcard_set_full_name(LinphoneVCard *vCard, const char *name) {
|
||||
|
||||
}
|
||||
|
||||
const char* linphone_vcard_get_full_name(const LinphoneVCard *vCard) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void linphone_vcard_add_sip_address(LinphoneVCard *vCard, const char *sip_address) {
|
||||
|
||||
}
|
||||
|
||||
void linphone_vcard_remove_sip_address(LinphoneVCard *vCard, const char *sip_address) {
|
||||
|
||||
}
|
||||
|
||||
void linphone_vcard_edit_main_sip_address(LinphoneVCard *vCard, const char *sip_address) {
|
||||
|
||||
}
|
||||
|
||||
MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vCard) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool_t linphone_vcard_generate_unique_id(LinphoneVCard *vCard) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void linphone_vcard_set_uid(LinphoneVCard *vCard, const char *uid) {
|
||||
|
||||
}
|
||||
|
||||
const char* linphone_vcard_get_uid(const LinphoneVCard *vCard) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void linphone_vcard_set_etag(LinphoneVCard *vCard, const char * etag) {
|
||||
|
||||
}
|
||||
|
||||
const char* linphone_vcard_get_etag(const LinphoneVCard *vCard) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void linphone_vcard_set_url(LinphoneVCard *vCard, const char * url) {
|
||||
|
||||
}
|
||||
|
||||
const char* linphone_vcard_get_url(const LinphoneVCard *vCard) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void linphone_vcard_compute_md5_hash(LinphoneVCard *vCard) {
|
||||
|
||||
}
|
||||
|
||||
bool_t linphone_vcard_compare_md5_hash(LinphoneVCard *vCard) {
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -264,6 +264,16 @@ void linphone_core_notify_log_collection_upload_progress_indication(LinphoneCore
|
|||
cleanup_dead_vtable_refs(lc);
|
||||
}
|
||||
|
||||
void linphone_core_notify_friend_list_created(LinphoneCore *lc, LinphoneFriendList *list) {
|
||||
NOTIFY_IF_EXIST(friend_list_created, lc, list);
|
||||
cleanup_dead_vtable_refs(lc);
|
||||
}
|
||||
|
||||
void linphone_core_notify_friend_list_removed(LinphoneCore *lc, LinphoneFriendList *list) {
|
||||
NOTIFY_IF_EXIST(friend_list_removed, lc, list);
|
||||
cleanup_dead_vtable_refs(lc);
|
||||
}
|
||||
|
||||
static VTableReference * v_table_reference_new(LinphoneCoreVTable *vtable, bool_t autorelease, bool_t internal){
|
||||
VTableReference *ref=ms_new0(VTableReference,1);
|
||||
ref->valid=1;
|
||||
|
|
|
|||
|
|
@ -123,3 +123,11 @@ void linphone_free_xml_text_content(const char *text) {
|
|||
xmlXPathObjectPtr linphone_get_xml_xpath_object_for_node_list(xmlparsing_context_t *xml_ctx, const char *xpath_expression) {
|
||||
return xmlXPathEvalExpression((const xmlChar *)xpath_expression, xml_ctx->xpath_ctx);
|
||||
}
|
||||
|
||||
void linphone_xml_xpath_context_init_carddav_ns(xmlparsing_context_t *xml_ctx) {
|
||||
if (xml_ctx && xml_ctx->xpath_ctx) {
|
||||
xmlXPathRegisterNs(xml_ctx->xpath_ctx, (const xmlChar*)"d", (const xmlChar*)"DAV:");
|
||||
xmlXPathRegisterNs(xml_ctx->xpath_ctx, (const xmlChar*)"card", (const xmlChar*)"urn:ietf:params:xml:ns:carddav");
|
||||
xmlXPathRegisterNs(xml_ctx->xpath_ctx, (const xmlChar*)"x1", (const xmlChar*)"http://calendarserver.org/ns/");
|
||||
}
|
||||
}
|
||||
|
|
@ -440,7 +440,7 @@ static void icon_press_handler(GtkEntry *entry){
|
|||
lf=linphone_core_get_friend_by_address(linphone_gtk_get_core(),uri);
|
||||
ms_free(uri);
|
||||
if (lf==NULL)
|
||||
lf=linphone_friend_new();
|
||||
lf=linphone_core_create_friend(linphone_gtk_get_core());
|
||||
if (lf!=NULL){
|
||||
linphone_friend_set_address(lf,addr);
|
||||
linphone_gtk_show_contact(lf, w);
|
||||
|
|
@ -687,14 +687,14 @@ void linphone_gtk_show_friends(void){
|
|||
LinphoneFriend *lf=(LinphoneFriend*)itf->data;
|
||||
const LinphoneAddress *f_uri=linphone_friend_get_address(lf);
|
||||
char *uri=linphone_address_as_string(f_uri);
|
||||
const char *name=linphone_address_get_display_name(f_uri);
|
||||
const char *name=linphone_friend_get_name(lf);
|
||||
const char *display=name;
|
||||
char *escaped=NULL;
|
||||
int nbmsg=0;
|
||||
|
||||
//BuddyInfo *bi;
|
||||
gboolean send_subscribe=linphone_friend_get_send_subscribe(lf);
|
||||
if (name==NULL || name[0]=='\0') {
|
||||
if (display==NULL || display[0]=='\0') {
|
||||
display=linphone_address_get_username(f_uri);
|
||||
}
|
||||
gtk_list_store_append(store,&iter);
|
||||
|
|
@ -716,19 +716,21 @@ void linphone_gtk_show_friends(void){
|
|||
}
|
||||
|
||||
void linphone_gtk_show_contact(LinphoneFriend *lf, GtkWidget *parent){
|
||||
GtkWidget *w=linphone_gtk_create_window("contact", parent);
|
||||
GtkWidget *w = linphone_gtk_create_window("contact", parent);
|
||||
char *uri;
|
||||
const char *name;
|
||||
const LinphoneAddress *f_uri=linphone_friend_get_address(lf);
|
||||
const char *name = linphone_friend_get_name(lf);
|
||||
const LinphoneAddress *f_uri = linphone_friend_get_address(lf);
|
||||
|
||||
uri=linphone_address_as_string_uri_only(f_uri);
|
||||
name=linphone_address_get_display_name(f_uri);
|
||||
if (uri) {
|
||||
gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"sip_address")),uri);
|
||||
ms_free(uri);
|
||||
}
|
||||
|
||||
if (name){
|
||||
gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"name")),name);
|
||||
}
|
||||
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"show_presence")),
|
||||
linphone_friend_get_send_subscribe(lf));
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"allow_presence")),
|
||||
|
|
@ -750,7 +752,7 @@ void linphone_gtk_contact_ok(GtkWidget *button){
|
|||
const gchar *name,*uri;
|
||||
LinphoneAddress* friend_address;
|
||||
if (lf==NULL){
|
||||
lf=linphone_friend_new();
|
||||
lf=linphone_core_create_friend(linphone_gtk_get_core());
|
||||
if (linphone_gtk_get_ui_config_int("use_subscribe_notify",1)==1){
|
||||
show_presence=FALSE;
|
||||
allow_presence=FALSE;
|
||||
|
|
@ -772,9 +774,8 @@ void linphone_gtk_contact_ok(GtkWidget *button){
|
|||
return ;
|
||||
}
|
||||
|
||||
linphone_address_set_display_name(friend_address,name);
|
||||
linphone_friend_set_name(lf,name);
|
||||
linphone_friend_set_address(lf,friend_address);
|
||||
linphone_friend_set_name(lf,name);
|
||||
linphone_friend_send_subscribe(lf,show_presence);
|
||||
linphone_friend_set_inc_subscribe_policy(lf,allow_presence==TRUE ? LinphoneSPAccept : LinphoneSPDeny);
|
||||
if (linphone_friend_in_list(lf)) {
|
||||
|
|
@ -983,3 +984,30 @@ gboolean linphone_gtk_friend_list_motion_event_handler(GtkTreeView *friendlist,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
#define CONFIG_FILE ".linphone-friends.db"
|
||||
|
||||
char *linphone_gtk_friends_storage_get_db_file(const char *filename){
|
||||
const int path_max=1024;
|
||||
char *db_file=NULL;
|
||||
|
||||
db_file=(char *)g_malloc(path_max*sizeof(char));
|
||||
if (filename==NULL) filename=CONFIG_FILE;
|
||||
/*try accessing a local file first if exists*/
|
||||
if (access(CONFIG_FILE,F_OK)==0){
|
||||
snprintf(db_file,path_max,"%s",filename);
|
||||
}else{
|
||||
#ifdef WIN32
|
||||
const char *appdata=getenv("APPDATA");
|
||||
if (appdata){
|
||||
snprintf(db_file,path_max,"%s\\%s",appdata,LINPHONE_CONFIG_DIR);
|
||||
CreateDirectory(db_file,NULL);
|
||||
snprintf(db_file,path_max,"%s\\%s\\%s",appdata,LINPHONE_CONFIG_DIR,filename);
|
||||
}
|
||||
#else
|
||||
const char *home=getenv("HOME");
|
||||
if (home==NULL) home=".";
|
||||
snprintf(db_file,path_max,"%s/%s",home,filename);
|
||||
#endif
|
||||
}
|
||||
return db_file;
|
||||
}
|
||||
|
|
@ -116,6 +116,7 @@ LINPHONE_PUBLIC GtkWidget *linphone_gtk_make_tab_header(const gchar *label, cons
|
|||
|
||||
char *linphone_gtk_message_storage_get_db_file(const char *filename);
|
||||
char *linphone_gtk_call_logs_storage_get_db_file(const char *filename);
|
||||
char *linphone_gtk_friends_storage_get_db_file(const char* filename);
|
||||
LINPHONE_PUBLIC void linphone_gtk_close_assistant(void);
|
||||
|
||||
LINPHONE_PUBLIC LinphoneCore *linphone_gtk_get_core(void);
|
||||
|
|
|
|||
45
gtk/main.c
45
gtk/main.c
|
|
@ -252,7 +252,8 @@ gboolean linphone_gtk_get_audio_assistant_option(void){
|
|||
}
|
||||
|
||||
static void linphone_gtk_init_liblinphone(const char *config_file,
|
||||
const char *factory_config_file, const char *chat_messages_db_file, const char *call_logs_db_file) {
|
||||
const char *factory_config_file, const char *chat_messages_db_file,
|
||||
const char *call_logs_db_file, const char *friends_db_file) {
|
||||
LinphoneCoreVTable vtable={0};
|
||||
gchar *secrets_file=linphone_gtk_get_config_file(SECRETS_FILE);
|
||||
gchar *user_certificates_dir=linphone_gtk_get_config_file(CERTIFICATES_PATH);
|
||||
|
|
@ -299,6 +300,7 @@ static void linphone_gtk_init_liblinphone(const char *config_file,
|
|||
}
|
||||
if (chat_messages_db_file) linphone_core_set_chat_database_path(the_core,chat_messages_db_file);
|
||||
if (call_logs_db_file) linphone_core_set_call_logs_database_path(the_core, call_logs_db_file);
|
||||
if (friends_db_file) linphone_core_set_friends_database_path(the_core, friends_db_file);
|
||||
}
|
||||
|
||||
LinphoneCore *linphone_gtk_get_core(void){
|
||||
|
|
@ -1835,6 +1837,38 @@ void linphone_gtk_show_keypad_checked(GtkCheckMenuItem *check_menu_item) {
|
|||
}
|
||||
}
|
||||
|
||||
void linphone_gtk_import_contacts(void) {
|
||||
GtkWidget *mw = linphone_gtk_get_main_window();
|
||||
GtkWidget *dialog = gtk_file_chooser_dialog_new("Open vCard file", (GtkWindow *)mw, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
|
||||
|
||||
gtk_widget_show(dialog);
|
||||
if (gtk_dialog_run(GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
|
||||
LinphoneCore *lc = linphone_gtk_get_core();
|
||||
char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
||||
LinphoneFriendList *list = linphone_core_get_default_friend_list(lc);
|
||||
linphone_friend_list_import_friends_from_vcard4_file(list, filename);
|
||||
g_free(filename);
|
||||
linphone_gtk_show_friends();
|
||||
}
|
||||
gtk_widget_destroy(dialog);
|
||||
}
|
||||
|
||||
void linphone_gtk_export_contacts(void) {
|
||||
GtkWidget *mw = linphone_gtk_get_main_window();
|
||||
GtkWidget *dialog = gtk_file_chooser_dialog_new("Save vCards as", (GtkWindow *)mw, GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
|
||||
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
|
||||
|
||||
gtk_widget_show(dialog);
|
||||
if (gtk_dialog_run(GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
|
||||
LinphoneCore *lc = linphone_gtk_get_core();
|
||||
char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
||||
LinphoneFriendList *list = linphone_core_get_default_friend_list(lc);
|
||||
linphone_friend_list_export_friends_as_vcard4_file(list, filename);
|
||||
g_free(filename);
|
||||
}
|
||||
gtk_widget_destroy(dialog);
|
||||
}
|
||||
|
||||
gboolean linphone_gtk_keypad_destroyed_handler(void) {
|
||||
GtkWidget *mw = linphone_gtk_get_main_window();
|
||||
GtkWidget *show_keypad_item = linphone_gtk_get_widget(mw, "show_keypad_menu_item");
|
||||
|
|
@ -2065,7 +2099,7 @@ int main(int argc, char *argv[]){
|
|||
const char *icon_name=LINPHONE_ICON_NAME;
|
||||
const char *app_name="Linphone";
|
||||
LpConfig *factory;
|
||||
char *chat_messages_db_file, *call_logs_db_file;
|
||||
char *chat_messages_db_file, *call_logs_db_file, *friends_db_file;
|
||||
GError *error=NULL;
|
||||
const char *tmp;
|
||||
|
||||
|
|
@ -2204,13 +2238,18 @@ core_start:
|
|||
|
||||
chat_messages_db_file=linphone_gtk_message_storage_get_db_file(NULL);
|
||||
call_logs_db_file = linphone_gtk_call_logs_storage_get_db_file(NULL);
|
||||
linphone_gtk_init_liblinphone(config_file, factory_config_file, chat_messages_db_file, call_logs_db_file);
|
||||
friends_db_file = linphone_gtk_friends_storage_get_db_file(NULL);
|
||||
linphone_gtk_init_liblinphone(config_file, factory_config_file, chat_messages_db_file, call_logs_db_file, friends_db_file);
|
||||
g_free(chat_messages_db_file);
|
||||
g_free(call_logs_db_file);
|
||||
g_free(friends_db_file);
|
||||
|
||||
#ifdef CALL_LOGS_STORAGE_ENABLED
|
||||
linphone_gtk_call_log_update(the_ui);
|
||||
#endif
|
||||
#ifdef FRIENDS_SQL_STORAGE_ENABLED
|
||||
linphone_gtk_show_friends();
|
||||
#endif
|
||||
|
||||
/* do not lower timeouts under 30 ms because it exhibits a bug on gtk+/win32, with cpu running 20% all the time...*/
|
||||
gtk_timeout_add(30,(GtkFunction)linphone_gtk_iterate,(gpointer)linphone_gtk_get_core());
|
||||
|
|
|
|||
24
gtk/main.ui
24
gtk/main.ui
|
|
@ -229,6 +229,30 @@
|
|||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="contacts_import_item">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Import contacts from vCards</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="linphone_gtk_import_contacts" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="contacts_export_item">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Export contacts as vCards</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="linphone_gtk_export_contacts" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem" id="separatormenuitem3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="quit_item">
|
||||
<property name="label">gtk-quit</property>
|
||||
|
|
|
|||
|
|
@ -621,6 +621,7 @@ void sal_verify_server_certificates(Sal *ctx, bool_t verify);
|
|||
void sal_verify_server_cn(Sal *ctx, bool_t verify);
|
||||
void sal_set_uuid(Sal*ctx, const char *uuid);
|
||||
int sal_create_uuid(Sal*ctx, char *uuid, size_t len);
|
||||
int sal_generate_uuid(char *uuid, size_t len);
|
||||
LINPHONE_PUBLIC void sal_enable_test_features(Sal*ctx, bool_t enabled);
|
||||
void sal_use_no_initial_route(Sal *ctx, bool_t enabled);
|
||||
|
||||
|
|
|
|||
|
|
@ -1000,9 +1000,14 @@ public interface LinphoneCore {
|
|||
void addFriend(LinphoneFriend lf) throws LinphoneCoreException;
|
||||
|
||||
/**
|
||||
* Sets the friend list for the linphone core.
|
||||
* Adds the friend list to the linphone core.
|
||||
*/
|
||||
void setFriendList(LinphoneFriendList friendList) throws LinphoneCoreException;
|
||||
void addFriendList(LinphoneFriendList friendList) throws LinphoneCoreException;
|
||||
|
||||
/**
|
||||
* Removes the friend list from the linphone core.
|
||||
*/
|
||||
void removeFriendList(LinphoneFriendList friendList) throws LinphoneCoreException;
|
||||
|
||||
/**
|
||||
* Creates a friend list.
|
||||
|
|
@ -1015,6 +1020,12 @@ public interface LinphoneCore {
|
|||
*/
|
||||
LinphoneFriend[] getFriendList();
|
||||
|
||||
/**
|
||||
* Get list of LinphoneFriendList
|
||||
* @return LinphoneFriendList list
|
||||
*/
|
||||
LinphoneFriendList[] getFriendLists();
|
||||
|
||||
/**
|
||||
* @brief Set my presence status
|
||||
* @param minutes_away how long in away
|
||||
|
|
@ -1918,6 +1929,12 @@ public interface LinphoneCore {
|
|||
*/
|
||||
public void setCallLogsDatabasePath(String path);
|
||||
|
||||
/**
|
||||
* Sets the path to the database where the friends will be stored (if enabled)
|
||||
* @param path the database where the friends will be stored.
|
||||
*/
|
||||
public void setFriendsDatabasePath(String path);
|
||||
|
||||
/**
|
||||
* Gets the chat rooms
|
||||
* @return an array of LinphoneChatRoom
|
||||
|
|
@ -2260,6 +2277,7 @@ public interface LinphoneCore {
|
|||
* @param isReachable whether SIP network is reachable.
|
||||
*/
|
||||
public void setSipNetworkReachable(boolean isReachable);
|
||||
|
||||
/**
|
||||
* This method is called by the application to notify the linphone core library when the media (RTP) network is reachable.
|
||||
* This is for advanced usage, when SIP and RTP layers are required to use different interfaces.
|
||||
|
|
|
|||
|
|
@ -226,5 +226,19 @@ public interface LinphoneCoreListener {
|
|||
* @param info Additional information: error message in case of error state, URL of uploaded file in case of success.
|
||||
*/
|
||||
void uploadStateChanged(LinphoneCore lc, LinphoneCore.LogCollectionUploadState state, String info);
|
||||
|
||||
/**
|
||||
* Callback prototype for reporting LinphoneFriendList creation.
|
||||
* @param lc LinphoneCore object
|
||||
* @param list LinphoneFriendList object
|
||||
*/
|
||||
void friendListCreated(LinphoneCore lc, LinphoneFriendList list);
|
||||
|
||||
/**
|
||||
* Callback prototype for reporting LinphoneFriendList removal.
|
||||
* @param lc LinphoneCore object
|
||||
* @param list LinphoneFriendList object
|
||||
*/
|
||||
void friendListRemoved(LinphoneCore lc, LinphoneFriendList list);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -198,4 +198,15 @@ public class LinphoneCoreListenerBase implements LinphoneCoreListener {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void friendListCreated(LinphoneCore lc, LinphoneFriendList list) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void friendListRemoved(LinphoneCore lc, LinphoneFriendList list) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -145,4 +145,14 @@ public interface LinphoneFriend {
|
|||
* @return The reference key of the friend.
|
||||
**/
|
||||
String getRefKey();
|
||||
/**
|
||||
* Set a name for this friend
|
||||
* @param name
|
||||
*/
|
||||
void setName(String name);
|
||||
/**
|
||||
* get name of this friend
|
||||
* @return
|
||||
*/
|
||||
String getName();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,11 +18,85 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
*/
|
||||
package org.linphone.core;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
import org.linphone.core.LinphoneChatMessage.State;
|
||||
|
||||
public interface LinphoneFriendList {
|
||||
public void setRLSUri(String uri);
|
||||
public void setRLSUri(String uri);
|
||||
public void addFriend(LinphoneFriend friend);
|
||||
public void addLocalFriend(LinphoneFriend friend);
|
||||
public LinphoneFriend[] getFriendList();
|
||||
public void updateSubscriptions(LinphoneProxyConfig proxyConfig,boolean onlyWhenRegistered);
|
||||
public LinphoneFriend findFriendByUri(String uri);
|
||||
long getNativePtr();
|
||||
public void setUri(String uri);
|
||||
public void synchronizeFriendsFromServer();
|
||||
|
||||
/**
|
||||
* Imports LinphoneFriends from a vCard 4 file
|
||||
* @return the number of friend imported
|
||||
**/
|
||||
public int importFriendsFromVCardFile(String file);
|
||||
|
||||
/**
|
||||
* Imports LinphoneFriends from a vCard 4 buffer
|
||||
* @return the number of friend imported
|
||||
**/
|
||||
public int importFriendsFromVCardBuffer(String buffer);
|
||||
|
||||
/**
|
||||
* Exports LinphoneFriends to a vCard 4 file
|
||||
**/
|
||||
public void exportFriendsToVCardFile(String file);
|
||||
|
||||
long getNativePtr();
|
||||
|
||||
/**
|
||||
* Set the callbacks associated with the LinphoneFriendList.
|
||||
*/
|
||||
void setListener(LinphoneFriendList.LinphoneFriendListListener listener);
|
||||
|
||||
interface LinphoneFriendListListener {
|
||||
void onLinphoneFriendCreated(LinphoneFriendList list, LinphoneFriend lf);
|
||||
|
||||
void onLinphoneFriendUpdated(LinphoneFriendList list, LinphoneFriend newFriend, LinphoneFriend oldFriend);
|
||||
|
||||
void onLinphoneFriendDeleted(LinphoneFriendList list, LinphoneFriend lf);
|
||||
|
||||
void onLinphoneFriendSyncStatusChanged(LinphoneFriendList list, LinphoneFriendList.State status, String message);
|
||||
}
|
||||
public static class State {
|
||||
static private Vector<State> values = new Vector<State>();
|
||||
public final int value() { return mValue; }
|
||||
|
||||
private final int mValue;
|
||||
private final String mStringValue;
|
||||
|
||||
public final static State SyncStarted = new State(0, "SyncStarted");
|
||||
public final static State SyncSuccessful = new State(1, "SyncSuccessful");
|
||||
public final static State SyncFailure = new State(2, "SyncFailure");
|
||||
|
||||
private State(int value,String stringValue) {
|
||||
mValue = value;
|
||||
values.addElement(this);
|
||||
mStringValue = stringValue;
|
||||
}
|
||||
|
||||
public static State fromInt(int value) {
|
||||
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
State state = (State) values.elementAt(i);
|
||||
if (state.mValue == value) return state;
|
||||
}
|
||||
throw new RuntimeException("state not found [" + value + "]");
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return mStringValue;
|
||||
}
|
||||
|
||||
public int toInt() {
|
||||
return mValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,7 +96,8 @@ class LinphoneCoreImpl implements LinphoneCore {
|
|||
private native void setPreviewWindowId(long nativePtr, Object wid);
|
||||
private native void setDeviceRotation(long nativePtr, int rotation);
|
||||
private native void addFriend(long nativePtr,long friend);
|
||||
private native void setFriendList(long nativePtr,long friendList);
|
||||
private native void addFriendList(long nativePtr,long friendList);
|
||||
private native void removeFriendList(long nativePtr,long friendList);
|
||||
private native LinphoneFriend[] getFriendList(long nativePtr);
|
||||
private native void setPresenceInfo(long nativePtr, int minutes_away, String alternative_contact, int status);
|
||||
private native int getPresenceInfo(long nativePtr);
|
||||
|
|
@ -167,6 +168,7 @@ class LinphoneCoreImpl implements LinphoneCore {
|
|||
private native String getPrimaryContactDisplayName(long nativePtr);
|
||||
private native void setChatDatabasePath(long nativePtr, String path);
|
||||
private native void setCallLogsDatabasePath(long nativePtr, String path);
|
||||
private native void setFriendsDatabasePath(long nativePtr, String path);
|
||||
private native long[] getChatRooms(long nativePtr);
|
||||
private native int migrateToMultiTransport(long nativePtr);
|
||||
private native void migrateCallLogs(long nativePtr);
|
||||
|
|
@ -457,13 +459,23 @@ class LinphoneCoreImpl implements LinphoneCore {
|
|||
return new LinphoneFriendListImpl(this);
|
||||
}
|
||||
|
||||
public synchronized void setFriendList(LinphoneFriendList friendList) throws LinphoneCoreException {
|
||||
setFriendList(nativePtr, ((LinphoneFriendListImpl) friendList).nativePtr);
|
||||
|
||||
public synchronized void addFriendList(LinphoneFriendList friendList) throws LinphoneCoreException {
|
||||
addFriendList(nativePtr,((LinphoneFriendListImpl)friendList).nativePtr);
|
||||
}
|
||||
|
||||
public synchronized void removeFriendList(LinphoneFriendList friendList) throws LinphoneCoreException {
|
||||
removeFriendList(nativePtr,((LinphoneFriendListImpl)friendList).nativePtr);
|
||||
}
|
||||
|
||||
public synchronized LinphoneFriend[] getFriendList() {
|
||||
return getFriendList(nativePtr);
|
||||
}
|
||||
|
||||
private native LinphoneFriendList[] getFriendLists(long nativePtr);
|
||||
public synchronized LinphoneFriendList[] getFriendLists() {
|
||||
return getFriendLists(nativePtr);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public synchronized void setPresenceInfo(int minutes_away, String alternative_contact, OnlineStatus status) {
|
||||
|
|
@ -1206,6 +1218,10 @@ class LinphoneCoreImpl implements LinphoneCore {
|
|||
public synchronized void setCallLogsDatabasePath(String path) {
|
||||
setCallLogsDatabasePath(nativePtr, path);
|
||||
}
|
||||
|
||||
public synchronized void setFriendsDatabasePath(String path) {
|
||||
setFriendsDatabasePath(nativePtr, path);
|
||||
}
|
||||
|
||||
public synchronized LinphoneChatRoom[] getChatRooms() {
|
||||
long[] typesPtr = getChatRooms(nativePtr);
|
||||
|
|
@ -1615,6 +1631,7 @@ class LinphoneCoreImpl implements LinphoneCore {
|
|||
public void setSipNetworkReachable(boolean isReachable) {
|
||||
setSipNetworkReachable(nativePtr, isReachable);
|
||||
}
|
||||
|
||||
private native void setMediaNetworkReachable(long nativePtr, boolean isReachable);
|
||||
@Override
|
||||
public void setMediaNetworkReachable(boolean isReachable) {
|
||||
|
|
|
|||
|
|
@ -118,4 +118,16 @@ class LinphoneFriendImpl implements LinphoneFriend, Serializable {
|
|||
public String getRefKey(){
|
||||
return getRefKey(nativePtr);
|
||||
}
|
||||
|
||||
private native void setName(long nativePtr, String name);
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
setName(nativePtr, name);
|
||||
}
|
||||
|
||||
private native String getName(long nativePtr);
|
||||
@Override
|
||||
public String getName() {
|
||||
return getName(nativePtr);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,20 +19,20 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
package org.linphone.core;
|
||||
|
||||
import java.io.Serializable;
|
||||
import org.linphone.core.LinphoneProxyConfigImpl;
|
||||
|
||||
class LinphoneFriendListImpl implements LinphoneFriendList, Serializable {
|
||||
|
||||
protected final long nativePtr;
|
||||
private native void finalize(long nativePtr);
|
||||
private native long newLinphoneFriendList(long corePtr);
|
||||
private native void setRLSUri(long nativePtr,String uri);
|
||||
private native void addFriend(long nativePtr,long friendPtr);
|
||||
private native void updateSubscriptions(long nativePtr,long proxyConfigPtr,boolean onlyWhenRegistered);
|
||||
private native void setRLSUri(long nativePtr, String uri);
|
||||
private native void addFriend(long nativePtr, long friendPtr);
|
||||
private native void addLocalFriend(long nativePtr, long friendPtr);
|
||||
private native LinphoneFriend[] getFriendList(long nativePtr);
|
||||
private native void updateSubscriptions(long nativePtr, long proxyConfigPtr, boolean onlyWhenRegistered);
|
||||
private native Object getCore(long ptr);
|
||||
private native LinphoneFriend findFriendByUri(long nativePtr,String uri);
|
||||
|
||||
|
||||
private native LinphoneFriend findFriendByUri(long nativePtr, String uri);
|
||||
private native void setListener(long ptr, LinphoneFriendListListener listener);
|
||||
|
||||
protected LinphoneFriendListImpl(LinphoneCoreImpl core) {
|
||||
nativePtr = newLinphoneFriendList(core.nativePtr);
|
||||
|
|
@ -52,6 +52,20 @@ class LinphoneFriendListImpl implements LinphoneFriendList, Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLocalFriend(LinphoneFriend friend) {
|
||||
synchronized(getSyncObject()){
|
||||
addLocalFriend(nativePtr, friend.getNativePtr());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LinphoneFriend[] getFriendList() {
|
||||
synchronized(getSyncObject()){
|
||||
return getFriendList(nativePtr);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSubscriptions(LinphoneProxyConfig proxyConfig,boolean onlyWhenRegistered) {
|
||||
synchronized(getSyncObject()){
|
||||
|
|
@ -66,6 +80,45 @@ class LinphoneFriendListImpl implements LinphoneFriendList, Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
private native void setUri(long nativePtr, String uri);
|
||||
@Override
|
||||
public void setUri(String uri) {
|
||||
synchronized(getSyncObject()) {
|
||||
setUri(nativePtr, uri);
|
||||
}
|
||||
}
|
||||
|
||||
private native void synchronizeFriendsFromServer(long nativePtr);
|
||||
@Override
|
||||
public void synchronizeFriendsFromServer() {
|
||||
synchronized(getSyncObject()) {
|
||||
synchronizeFriendsFromServer(nativePtr);
|
||||
}
|
||||
}
|
||||
|
||||
private native int importFriendsFromVCardFile(long nativePtr, String file);
|
||||
@Override
|
||||
public int importFriendsFromVCardFile(String file) {
|
||||
return importFriendsFromVCardFile(nativePtr, file);
|
||||
}
|
||||
|
||||
private native int importFriendsFromVCardBuffer(long nativePtr, String buffer);
|
||||
@Override
|
||||
public int importFriendsFromVCardBuffer(String buffer) {
|
||||
return importFriendsFromVCardBuffer(nativePtr, buffer);
|
||||
}
|
||||
|
||||
private native void exportFriendsToVCardFile(long nativePtr, String file);
|
||||
@Override
|
||||
public void exportFriendsToVCardFile(String file) {
|
||||
exportFriendsToVCardFile(nativePtr, file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setListener(LinphoneFriendListListener listener) {
|
||||
setListener(nativePtr, listener);
|
||||
}
|
||||
|
||||
|
||||
/*reserved for JNI */
|
||||
protected LinphoneFriendListImpl(long aNativePtr) {
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ set(SOURCE_FILES
|
|||
tunnel_tester.c
|
||||
upnp_tester.c
|
||||
video_tester.c
|
||||
vcard_tester.c
|
||||
)
|
||||
|
||||
apply_compile_flags(SOURCE_FILES "CPP" "C")
|
||||
|
|
|
|||
|
|
@ -68,10 +68,14 @@ RCFILES = \
|
|||
rcfiles/remote_zero_length_params_rc\
|
||||
rcfiles/stun_rc\
|
||||
rcfiles/upnp_rc\
|
||||
rcfiles/zero_length_params_rc
|
||||
rcfiles/zero_length_params_rc\
|
||||
rcfiles/friends_rc\
|
||||
rcfiles/carddav_rc
|
||||
|
||||
IMAGE_FILES = images/nowebcamCIF.jpg
|
||||
|
||||
COMMON_FILE = common/vcards.vcf common/thousand_vcards.vcf
|
||||
|
||||
EXTRA_DIST = tester_hosts\
|
||||
messages.db\
|
||||
$(TESTER_SOUNDS)\
|
||||
|
|
@ -131,7 +135,8 @@ liblinphonetester_la_SOURCES = \
|
|||
tunnel_tester.c \
|
||||
tester.c \
|
||||
upnp_tester.c \
|
||||
video_tester.c
|
||||
video_tester.c \
|
||||
vcard_tester.c
|
||||
|
||||
liblinphonetester_ladir = $(includedir)/linphone
|
||||
|
||||
|
|
@ -147,7 +152,7 @@ dist_liblinphone_tester_DATA = tester_hosts messages.db
|
|||
AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/coreapi -I$(top_srcdir)/tester/common
|
||||
AM_CFLAGS = -DBC_CONFIG_FILE=\"config.h\" $(STRICT_OPTIONS) $(STRICT_OPTIONS_CC) \
|
||||
-DIN_LINPHONE $(ORTP_CFLAGS) $(MEDIASTREAMER_CFLAGS) $(BCTOOLBOXTESTER_CFLAGS) \
|
||||
$(BELLESIP_CFLAGS) $(LIBXML2_CFLAGS) $(SQLITE3_CFLAGS)
|
||||
$(BELLESIP_CFLAGS) $(LIBXML2_CFLAGS) $(SQLITE3_CFLAGS) $(BELCARD_CFLAGS)
|
||||
|
||||
if BUILD_GTK_UI
|
||||
|
||||
|
|
|
|||
8542
tester/common/thousand_vcards.vcf
Normal file
8542
tester/common/thousand_vcards.vcf
Normal file
File diff suppressed because it is too large
Load diff
22
tester/common/vcards.vcf
Normal file
22
tester/common/vcards.vcf
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
BEGIN:VCARD
|
||||
VERSION:4.0
|
||||
KIND:individual
|
||||
FN:Sylvain Berfini
|
||||
N:Berfini;Sylvain;Pascal;;
|
||||
GENDER:M
|
||||
IMPP;PREF=1;TYPE=work:sip:sylvain@sip.linphone.org
|
||||
END:VCARD
|
||||
BEGIN:VCARD
|
||||
VERSION:4.0
|
||||
KIND:individual
|
||||
FN:François Grisez
|
||||
N:Grisez;François;;;
|
||||
IMPP;TYPE=work:sip:francois@sip.linphone.org
|
||||
END:VCARD
|
||||
BEGIN:VCARD
|
||||
VERSION:4.0
|
||||
KIND:individual
|
||||
FN:Margaux Clerc
|
||||
GENDER:F
|
||||
IMPP:sip:margaux@sip.linphone.org
|
||||
END:VCARD
|
||||
|
|
@ -59,6 +59,7 @@ extern test_suite_t video_test_suite;
|
|||
extern test_suite_t multicast_call_test_suite;
|
||||
extern test_suite_t multi_call_test_suite;
|
||||
extern test_suite_t proxy_config_test_suite;
|
||||
extern test_suite_t vcard_test_suite;
|
||||
#if HAVE_SIPP
|
||||
extern test_suite_t complex_sip_call_test_suite;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -238,6 +238,7 @@ static void subscribe_failure_handle_by_app(void) {
|
|||
sal_set_recv_error(marie->lc->sal, 1);
|
||||
|
||||
lf = linphone_core_get_friend_by_address(marie->lc,lf_identity);
|
||||
BC_ASSERT_PTR_NOT_NULL_FATAL(lf);
|
||||
linphone_friend_edit(lf);
|
||||
linphone_friend_enable_subscribes(lf,FALSE); /*disable subscription*/
|
||||
linphone_friend_done(lf);
|
||||
|
|
@ -719,7 +720,8 @@ static void test_presence_list_base(bool_t enable_compression) {
|
|||
linphone_friend_list_add_friend(lfl, lf);
|
||||
lf = linphone_core_create_friend_with_address(laure->lc, "sip:michelle@sip.inexistentdomain.com");
|
||||
linphone_friend_list_add_friend(lfl, lf);
|
||||
linphone_core_set_friend_list(laure->lc, lfl);
|
||||
linphone_core_remove_friend_list(laure->lc, linphone_core_get_default_friend_list(laure->lc));
|
||||
linphone_core_add_friend_list(laure->lc, lfl);
|
||||
linphone_friend_list_unref(lfl);
|
||||
linphone_core_set_presence_model(laure->lc, linphone_core_create_presence_model_with_activity(laure->lc, LinphonePresenceActivityOnline, NULL));
|
||||
|
||||
|
|
@ -729,16 +731,16 @@ static void test_presence_list_base(bool_t enable_compression) {
|
|||
|
||||
wait_for_list(lcs, &laure->stat.number_of_NotifyPresenceReceived, 2, 2000);
|
||||
BC_ASSERT_EQUAL(laure->stat.number_of_NotifyPresenceReceived, 2, int, "%d");
|
||||
BC_ASSERT_EQUAL(laure->lc->friendlist->expected_notification_version, 1, int, "%d");
|
||||
lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, marie_identity);
|
||||
BC_ASSERT_EQUAL(linphone_core_get_default_friend_list(laure->lc)->expected_notification_version, 1, int, "%d");
|
||||
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), marie_identity);
|
||||
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusBusy, int, "%d");
|
||||
BC_ASSERT_EQUAL(lf->presence_received, TRUE, int, "%d");
|
||||
BC_ASSERT_EQUAL(lf->subscribe_active, TRUE, int, "%d");
|
||||
lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, pauline_identity);
|
||||
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), pauline_identity);
|
||||
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusVacation, int, "%d");
|
||||
BC_ASSERT_EQUAL(lf->presence_received, TRUE, int, "%d");
|
||||
BC_ASSERT_EQUAL(lf->subscribe_active, TRUE, int, "%d");
|
||||
lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, "sip:michelle@sip.inexistentdomain.com");
|
||||
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), "sip:michelle@sip.inexistentdomain.com");
|
||||
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d");
|
||||
BC_ASSERT_EQUAL(lf->presence_received, FALSE, int, "%d");
|
||||
BC_ASSERT_EQUAL(lf->subscribe_active, TRUE, int, "%d");
|
||||
|
|
@ -747,14 +749,15 @@ static void test_presence_list_base(bool_t enable_compression) {
|
|||
linphone_friend_list_set_rls_uri(lfl, rls_uri);
|
||||
lf = linphone_core_create_friend_with_address(marie->lc, laure_identity);
|
||||
linphone_friend_list_add_friend(lfl, lf);
|
||||
linphone_core_set_friend_list(marie->lc, lfl);
|
||||
linphone_core_remove_friend_list(marie->lc, linphone_core_get_default_friend_list(marie->lc));
|
||||
linphone_core_add_friend_list(marie->lc, lfl);
|
||||
linphone_friend_list_unref(lfl);
|
||||
linphone_friend_list_update_subscriptions(marie->lc->friendlist, NULL, FALSE);
|
||||
linphone_friend_list_update_subscriptions(linphone_core_get_default_friend_list(marie->lc), NULL, FALSE);
|
||||
|
||||
wait_for_list(lcs, &marie->stat.number_of_NotifyPresenceReceived, 1, 2000);
|
||||
BC_ASSERT_EQUAL(marie->stat.number_of_NotifyPresenceReceived, 1, int, "%d");
|
||||
BC_ASSERT_EQUAL(marie->lc->friendlist->expected_notification_version, 1, int, "%d");
|
||||
lf = linphone_friend_list_find_friend_by_uri(marie->lc->friendlist, laure_identity);
|
||||
BC_ASSERT_EQUAL(linphone_core_get_default_friend_list(marie->lc)->expected_notification_version, 1, int, "%d");
|
||||
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(marie->lc), laure_identity);
|
||||
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOnline, int, "%d");
|
||||
BC_ASSERT_EQUAL(lf->presence_received, TRUE, int, "%d");
|
||||
BC_ASSERT_EQUAL(lf->subscribe_active, TRUE, int, "%d");
|
||||
|
|
@ -763,14 +766,15 @@ static void test_presence_list_base(bool_t enable_compression) {
|
|||
linphone_friend_list_set_rls_uri(lfl, rls_uri);
|
||||
lf = linphone_core_create_friend_with_address(pauline->lc, marie_identity);
|
||||
linphone_friend_list_add_friend(lfl, lf);
|
||||
linphone_core_set_friend_list(pauline->lc, lfl);
|
||||
linphone_core_remove_friend_list(pauline->lc, linphone_core_get_default_friend_list(pauline->lc));
|
||||
linphone_core_add_friend_list(pauline->lc, lfl);
|
||||
linphone_friend_list_unref(lfl);
|
||||
linphone_friend_list_update_subscriptions(pauline->lc->friendlist, NULL, FALSE);
|
||||
linphone_friend_list_update_subscriptions(linphone_core_get_default_friend_list(pauline->lc), NULL, FALSE);
|
||||
|
||||
wait_for_list(lcs, &pauline->stat.number_of_NotifyPresenceReceived, 1, 2000);
|
||||
BC_ASSERT_EQUAL(pauline->stat.number_of_NotifyPresenceReceived, 1, int, "%d");
|
||||
BC_ASSERT_EQUAL(pauline->lc->friendlist->expected_notification_version, 1, int, "%d");
|
||||
lf = linphone_friend_list_find_friend_by_uri(pauline->lc->friendlist, marie_identity);
|
||||
BC_ASSERT_EQUAL(linphone_core_get_default_friend_list(pauline->lc)->expected_notification_version, 1, int, "%d");
|
||||
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(pauline->lc), marie_identity);
|
||||
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusBusy, int, "%d");
|
||||
BC_ASSERT_EQUAL(lf->presence_received, TRUE, int, "%d");
|
||||
BC_ASSERT_EQUAL(lf->subscribe_active, TRUE, int, "%d");
|
||||
|
|
@ -781,14 +785,14 @@ 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(laure->lc->friendlist->expected_notification_version, 2, int, "%d");
|
||||
lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, marie_identity);
|
||||
BC_ASSERT_EQUAL(linphone_core_get_default_friend_list(laure->lc)->expected_notification_version, 2, int, "%d");
|
||||
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), marie_identity);
|
||||
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOnThePhone, int, "%d");
|
||||
|
||||
wait_for_list(lcs, &pauline->stat.number_of_NotifyPresenceReceived, 2, 2000);
|
||||
BC_ASSERT_EQUAL(pauline->stat.number_of_NotifyPresenceReceived, 2, int, "%d");
|
||||
BC_ASSERT_EQUAL(pauline->lc->friendlist->expected_notification_version, 2, int, "%d");
|
||||
lf = linphone_friend_list_find_friend_by_uri(pauline->lc->friendlist, marie_identity);
|
||||
BC_ASSERT_EQUAL(linphone_core_get_default_friend_list(pauline->lc)->expected_notification_version, 2, int, "%d");
|
||||
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(pauline->lc), marie_identity);
|
||||
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOnThePhone, int, "%d");
|
||||
|
||||
ms_message("Disabling publish");
|
||||
|
|
@ -797,15 +801,13 @@ static void test_presence_list_base(bool_t enable_compression) {
|
|||
enable_publish(pauline, FALSE);
|
||||
|
||||
wait_for_list(lcs, &dummy, 1, 2000); /* Wait a little bit for the presence notifications. TODO: Wait for the correct number of PresenceReceived events. */
|
||||
|
||||
lf = linphone_friend_list_find_friend_by_uri(pauline->lc->friendlist, marie_identity);
|
||||
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(pauline->lc), marie_identity);
|
||||
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d");
|
||||
lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, pauline_identity);
|
||||
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), pauline_identity);
|
||||
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d");
|
||||
lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, marie_identity);
|
||||
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), marie_identity);
|
||||
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d");
|
||||
|
||||
lf = linphone_friend_list_find_friend_by_uri(marie->lc->friendlist, laure_identity);
|
||||
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(marie->lc), laure_identity);
|
||||
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d");
|
||||
|
||||
linphone_core_manager_destroy(laure);
|
||||
|
|
@ -842,10 +844,11 @@ static void test_presence_list_subscribe_before_publish(void) {
|
|||
linphone_friend_list_add_friend(lfl, lf);
|
||||
lf = linphone_core_create_friend_with_address(laure->lc, "sip:michelle@sip.inexistentdomain.com");
|
||||
linphone_friend_list_add_friend(lfl, lf);
|
||||
linphone_core_set_friend_list(laure->lc, lfl);
|
||||
linphone_core_remove_friend_list(laure->lc, linphone_core_get_default_friend_list(laure->lc));
|
||||
linphone_core_add_friend_list(laure->lc, lfl);
|
||||
linphone_friend_list_unref(lfl);
|
||||
linphone_core_set_presence_model(laure->lc, linphone_core_create_presence_model_with_activity(laure->lc, LinphonePresenceActivityOnline, NULL));
|
||||
linphone_friend_list_update_subscriptions(laure->lc->friendlist, NULL, FALSE);
|
||||
linphone_friend_list_update_subscriptions(linphone_core_get_default_friend_list(laure->lc), NULL, FALSE);
|
||||
|
||||
lcs = ms_list_append(lcs, laure->lc);
|
||||
lcs = ms_list_append(lcs, pauline->lc);
|
||||
|
|
@ -855,12 +858,12 @@ static void test_presence_list_subscribe_before_publish(void) {
|
|||
enable_publish(pauline, TRUE);
|
||||
wait_for_list(lcs, &pauline->stat.number_of_NotifyPresenceReceived, 1, 2000);
|
||||
BC_ASSERT_GREATER(laure->stat.number_of_NotifyPresenceReceived, 1, int, "%d");
|
||||
BC_ASSERT_GREATER(laure->lc->friendlist->expected_notification_version, 1, int, "%d");
|
||||
lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, pauline_identity);
|
||||
BC_ASSERT_GREATER(linphone_core_get_default_friend_list(laure->lc)->expected_notification_version, 1, int, "%d");
|
||||
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), pauline_identity);
|
||||
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusVacation, int, "%d");
|
||||
BC_ASSERT_EQUAL(lf->presence_received, TRUE, int, "%d");
|
||||
BC_ASSERT_EQUAL(lf->subscribe_active, TRUE, int, "%d");
|
||||
lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, "sip:michelle@sip.inexistentdomain.com");
|
||||
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), "sip:michelle@sip.inexistentdomain.com");
|
||||
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d");
|
||||
BC_ASSERT_EQUAL(lf->presence_received, FALSE, int, "%d");
|
||||
BC_ASSERT_EQUAL(lf->subscribe_active, TRUE, int, "%d");
|
||||
|
|
@ -884,7 +887,8 @@ static void test_presence_list_subscription_expire_for_unknown(void) {
|
|||
linphone_friend_list_set_rls_uri(lfl, rls_uri);
|
||||
lf = linphone_core_create_friend_with_address(laure->lc, "sip:michelle@sip.inexistentdomain.com");
|
||||
linphone_friend_list_add_friend(lfl, lf);
|
||||
linphone_core_set_friend_list(laure->lc, lfl);
|
||||
linphone_core_remove_friend_list(laure->lc, linphone_core_get_default_friend_list(laure->lc));
|
||||
linphone_core_add_friend_list(laure->lc, lfl);
|
||||
linphone_friend_list_update_subscriptions(lfl,NULL,FALSE);
|
||||
|
||||
linphone_friend_list_unref(lfl);
|
||||
|
|
@ -917,11 +921,11 @@ static void test_presence_list_subscribe_with_error(bool_t io_error) {
|
|||
linphone_friend_list_add_friend(lfl, lf);
|
||||
lf = linphone_core_create_friend_with_address(laure->lc, "sip:michelle@sip.inexistentdomain.com");
|
||||
linphone_friend_list_add_friend(lfl, lf);
|
||||
linphone_core_set_friend_list(laure->lc, lfl);
|
||||
linphone_core_remove_friend_list(laure->lc, linphone_core_get_default_friend_list(laure->lc));
|
||||
linphone_core_add_friend_list(laure->lc, lfl);
|
||||
linphone_friend_list_unref(lfl);
|
||||
linphone_core_set_presence_model(laure->lc, linphone_core_create_presence_model_with_activity(laure->lc, LinphonePresenceActivityOnline, NULL));
|
||||
linphone_friend_list_update_subscriptions(laure->lc->friendlist, NULL, FALSE);
|
||||
|
||||
linphone_friend_list_update_subscriptions(linphone_core_get_default_friend_list(laure->lc), NULL, FALSE);
|
||||
lcs = ms_list_append(lcs, laure->lc);
|
||||
lcs = ms_list_append(lcs, pauline->lc);
|
||||
|
||||
|
|
@ -930,12 +934,12 @@ static void test_presence_list_subscribe_with_error(bool_t io_error) {
|
|||
enable_publish(pauline, TRUE);
|
||||
BC_ASSERT_TRUE(wait_for_until(laure->lc, pauline->lc, &laure->stat.number_of_LinphonePresenceActivityVacation, 1, 6000));
|
||||
BC_ASSERT_GREATER(laure->stat.number_of_NotifyPresenceReceived, 1, int, "%d");
|
||||
BC_ASSERT_GREATER(laure->lc->friendlist->expected_notification_version, 1, int, "%d");
|
||||
lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, pauline_identity);
|
||||
BC_ASSERT_GREATER(linphone_core_get_default_friend_list(laure->lc)->expected_notification_version, 1, int, "%d");
|
||||
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), pauline_identity);
|
||||
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusVacation, int, "%d");
|
||||
BC_ASSERT_EQUAL(lf->presence_received, TRUE, int, "%d");
|
||||
BC_ASSERT_EQUAL(lf->subscribe_active, TRUE, int, "%d");
|
||||
lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, "sip:michelle@sip.inexistentdomain.com");
|
||||
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), "sip:michelle@sip.inexistentdomain.com");
|
||||
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d");
|
||||
BC_ASSERT_EQUAL(lf->presence_received, FALSE, int, "%d");
|
||||
BC_ASSERT_EQUAL(lf->subscribe_active, TRUE, int, "%d");
|
||||
|
|
@ -960,7 +964,7 @@ static void test_presence_list_subscribe_with_error(bool_t io_error) {
|
|||
linphone_core_set_presence_model(pauline->lc, linphone_core_create_presence_model_with_activity(pauline->lc, LinphonePresenceActivityAway, NULL));
|
||||
|
||||
BC_ASSERT_TRUE(wait_for_until(laure->lc, pauline->lc, &laure->stat.number_of_LinphonePresenceActivityAway, 1, 6000));
|
||||
lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, pauline_identity);
|
||||
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), pauline_identity);
|
||||
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusAway, int, "%d");
|
||||
|
||||
linphone_core_manager_destroy(laure);
|
||||
|
|
|
|||
12
tester/rcfiles/carddav_rc
Normal file
12
tester/rcfiles/carddav_rc
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
[net]
|
||||
mtu=1300
|
||||
|
||||
[sip]
|
||||
ping_with_options=0
|
||||
sip_random_port=1
|
||||
|
||||
[auth_info_0]
|
||||
domain=dav.linphone.org
|
||||
username=sylvain
|
||||
ha1=4747ce2517a985f2fc20234a38f068b6
|
||||
realm=SabreDAV
|
||||
21
tester/rcfiles/friends_rc
Normal file
21
tester/rcfiles/friends_rc
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
[net]
|
||||
mtu=1300
|
||||
|
||||
[sip]
|
||||
ping_with_options=0
|
||||
sip_random_port=1
|
||||
|
||||
[friend_0]
|
||||
url=sip:sylvain@sip.linphone.org
|
||||
pol=wait
|
||||
subscribe=0
|
||||
|
||||
[friend_1]
|
||||
url="François Grisez" <sip:francois.grisez@sip.linphone.org>
|
||||
pol=accept
|
||||
subscribe=1
|
||||
|
||||
[friend_2]
|
||||
url=sip:margaux.clerc@sip.linphone.org
|
||||
pol=deny
|
||||
subscribe=0
|
||||
|
|
@ -492,6 +492,7 @@ void liblinphone_tester_add_suites() {
|
|||
#if HAVE_SIPP
|
||||
bc_tester_add_suite(&complex_sip_call_test_suite);
|
||||
#endif
|
||||
bc_tester_add_suite(&vcard_test_suite);
|
||||
}
|
||||
|
||||
static int linphone_core_manager_get_max_audio_bw_base(const int array[],int array_size) {
|
||||
|
|
|
|||
676
tester/vcard_tester.c
Normal file
676
tester/vcard_tester.c
Normal file
|
|
@ -0,0 +1,676 @@
|
|||
/*
|
||||
vcard_tester.c
|
||||
Copyright (C) 2015 Belledonne Communications SARL
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "linphonecore.h"
|
||||
#include "private.h"
|
||||
#include "liblinphone_tester.h"
|
||||
#include "carddav.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#ifdef VCARD_ENABLED
|
||||
static char *create_filepath(const char *dir, const char *filename, const char *ext) {
|
||||
return ms_strdup_printf("%s/%s.%s", dir, filename, ext);
|
||||
}
|
||||
|
||||
static void linphone_vcard_import_export_friends_test(void) {
|
||||
LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE);
|
||||
LinphoneFriendList *lfl = linphone_core_get_default_friend_list(manager->lc);
|
||||
const MSList *friends = linphone_friend_list_get_friends(lfl);
|
||||
char *import_filepath = bc_tester_res("common/vcards.vcf");
|
||||
char *export_filepath = create_filepath(bc_tester_get_writable_dir_prefix(), "export_vcards", "vcf");
|
||||
int count = 0;
|
||||
BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d");
|
||||
|
||||
count = linphone_friend_list_import_friends_from_vcard4_file(lfl, import_filepath);
|
||||
BC_ASSERT_EQUAL(count, 3, int, "%d");
|
||||
friends = linphone_friend_list_get_friends(lfl);
|
||||
BC_ASSERT_EQUAL(ms_list_size(friends), 3, int, "%d");
|
||||
|
||||
linphone_friend_list_export_friends_as_vcard4_file(lfl, export_filepath);
|
||||
|
||||
lfl = linphone_core_create_friend_list(manager->lc);
|
||||
count = linphone_friend_list_import_friends_from_vcard4_file(lfl, export_filepath);
|
||||
BC_ASSERT_EQUAL(count, 3, int, "%d");
|
||||
friends = linphone_friend_list_get_friends(lfl);
|
||||
BC_ASSERT_EQUAL(ms_list_size(friends), 3, int, "%d");
|
||||
linphone_friend_list_unref(lfl);
|
||||
|
||||
remove(export_filepath);
|
||||
ms_free(import_filepath);
|
||||
ms_free(export_filepath);
|
||||
linphone_core_manager_destroy(manager);
|
||||
}
|
||||
|
||||
static void linphone_vcard_import_a_lot_of_friends_test(void) {
|
||||
LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE);
|
||||
LinphoneFriendList *lfl = linphone_core_get_default_friend_list(manager->lc);
|
||||
char *import_filepath = bc_tester_res("common/thousand_vcards.vcf");
|
||||
clock_t start, end;
|
||||
double elapsed = 0;
|
||||
const MSList *friends = NULL;
|
||||
FILE *infile;
|
||||
char *buffer;
|
||||
long numbytes;
|
||||
|
||||
start = clock();
|
||||
linphone_friend_list_import_friends_from_vcard4_file(lfl, import_filepath);
|
||||
end = clock();
|
||||
|
||||
friends = linphone_friend_list_get_friends(lfl);
|
||||
BC_ASSERT_EQUAL(ms_list_size(friends), 482, int, "%i"); // Thousand vcards contains 482 contacts with a SIP URI
|
||||
|
||||
elapsed = (double)(end - start);
|
||||
ms_error("Imported a thousand of vCards from file (only %i friends with SIP address found) in %f seconds", ms_list_size(friends), elapsed / CLOCKS_PER_SEC);
|
||||
#ifndef ANDROID
|
||||
BC_ASSERT_TRUE(elapsed < 1500000); // 1.5 seconds
|
||||
#endif
|
||||
|
||||
lfl = linphone_core_create_friend_list(manager->lc);
|
||||
infile = fopen(import_filepath, "r");
|
||||
fseek(infile, 0L, SEEK_END);
|
||||
numbytes = ftell(infile);
|
||||
fseek(infile, 0L, SEEK_SET);
|
||||
buffer = (char*)ms_malloc(numbytes * sizeof(char));
|
||||
numbytes = fread(buffer, sizeof(char), numbytes, infile);
|
||||
fclose(infile);
|
||||
|
||||
start = clock();
|
||||
linphone_friend_list_import_friends_from_vcard4_buffer(lfl, buffer);
|
||||
end = clock();
|
||||
|
||||
friends = linphone_friend_list_get_friends(lfl);
|
||||
BC_ASSERT_EQUAL(ms_list_size(friends), 482, int, "%i"); // Thousand vcards contains 482 contacts with a SIP URI
|
||||
|
||||
elapsed = (double)(end - start);
|
||||
ms_error("Imported a thousand of vCards from buffer (only %i friends with SIP address found) in %f seconds", ms_list_size(friends), elapsed / CLOCKS_PER_SEC);
|
||||
#ifndef ANDROID
|
||||
BC_ASSERT_TRUE(elapsed < 1500000); // 1.5 seconds
|
||||
#endif
|
||||
|
||||
ms_free(buffer);
|
||||
linphone_friend_list_unref(lfl);
|
||||
|
||||
ms_free(import_filepath);
|
||||
linphone_core_manager_destroy(manager);
|
||||
}
|
||||
|
||||
static void linphone_vcard_update_existing_friends_test(void) {
|
||||
LinphoneFriend *lf = linphone_friend_new_with_addr("sip:oldfriend@sip.linphone.org");
|
||||
|
||||
BC_ASSERT_PTR_NOT_NULL_FATAL(lf);
|
||||
BC_ASSERT_PTR_NULL(linphone_friend_get_vcard(lf));
|
||||
|
||||
linphone_friend_edit(lf);
|
||||
linphone_friend_set_name(lf, "Old Friend");
|
||||
linphone_friend_done(lf);
|
||||
|
||||
BC_ASSERT_PTR_NOT_NULL(linphone_friend_get_vcard(lf));
|
||||
BC_ASSERT_STRING_EQUAL(linphone_vcard_get_full_name(linphone_friend_get_vcard(lf)), "Old Friend");
|
||||
linphone_friend_unref(lf);
|
||||
lf = NULL;
|
||||
}
|
||||
|
||||
static void friends_if_no_db_set(void) {
|
||||
LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE);
|
||||
LinphoneFriend *lf = linphone_friend_new();
|
||||
LinphoneAddress *addr = linphone_address_new("sip:sylvain@sip.linphone.org");
|
||||
const MSList *friends = NULL;
|
||||
LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc);
|
||||
|
||||
linphone_friend_set_address(lf, addr);
|
||||
linphone_friend_set_name(lf, "Sylvain");
|
||||
linphone_friend_list_add_friend(lfl, lf);
|
||||
friends = linphone_friend_list_get_friends(lfl);
|
||||
BC_ASSERT_EQUAL(ms_list_size(friends), 1, int, "%d");
|
||||
|
||||
linphone_friend_list_remove_friend(lfl, lf);
|
||||
linphone_friend_unref(lf);
|
||||
friends = linphone_friend_list_get_friends(lfl);
|
||||
BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d");
|
||||
|
||||
linphone_friend_list_unref(lfl);
|
||||
linphone_address_unref(addr);
|
||||
linphone_core_manager_destroy(manager);
|
||||
}
|
||||
|
||||
#ifdef FRIENDS_SQL_STORAGE_ENABLED
|
||||
static void friends_migration(void) {
|
||||
LinphoneCoreManager* manager = linphone_core_manager_new2("friends_rc", FALSE);
|
||||
LinphoneFriendList *lfl = linphone_core_get_default_friend_list(manager->lc);
|
||||
const MSList *friends = linphone_friend_list_get_friends(lfl);
|
||||
MSList *friends_from_db = NULL;
|
||||
char *friends_db = create_filepath(bc_tester_get_writable_dir_prefix(), "friends", "db");
|
||||
BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d");
|
||||
|
||||
unlink(friends_db);
|
||||
linphone_core_set_friends_database_path(manager->lc, friends_db);
|
||||
friends = linphone_friend_list_get_friends(lfl);
|
||||
BC_ASSERT_EQUAL(ms_list_size(friends), 3, int, "%d");
|
||||
friends_from_db = linphone_core_fetch_friends_from_db(manager->lc, lfl);
|
||||
BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 3, int, "%d");
|
||||
|
||||
friends_from_db = ms_list_free_with_data(friends_from_db, (void (*)(void *))linphone_friend_unref);
|
||||
unlink(friends_db);
|
||||
ms_free(friends_db);
|
||||
linphone_core_manager_destroy(manager);
|
||||
}
|
||||
|
||||
typedef struct _LinphoneFriendListStats {
|
||||
int new_list_count;
|
||||
int removed_list_count;
|
||||
} LinphoneFriendListStats;
|
||||
|
||||
static void friend_list_created_cb(LinphoneCore *lc, LinphoneFriendList *list) {
|
||||
LinphoneFriendListStats *stats = (LinphoneFriendListStats *)linphone_friend_list_get_user_data(list);
|
||||
stats->new_list_count++;
|
||||
}
|
||||
|
||||
static void friend_list_removed_cb(LinphoneCore *lc, LinphoneFriendList *list) {
|
||||
LinphoneFriendListStats *stats = (LinphoneFriendListStats *)linphone_friend_list_get_user_data(list);
|
||||
stats->removed_list_count++;
|
||||
}
|
||||
|
||||
static void friends_sqlite_storage(void) {
|
||||
LinphoneCoreVTable *v_table = linphone_core_v_table_new();
|
||||
LinphoneCore* lc = NULL;
|
||||
LinphoneFriendList *lfl = NULL;
|
||||
LinphoneFriend *lf = NULL;
|
||||
LinphoneFriend *lf2 = NULL;
|
||||
LinphoneVCard *lvc = linphone_vcard_new();
|
||||
LinphoneAddress *addr = linphone_address_new("sip:sylvain@sip.linphone.org");
|
||||
const MSList *friends = NULL;
|
||||
MSList *friends_from_db = NULL;
|
||||
MSList *friends_lists_from_db = NULL;
|
||||
char *friends_db = create_filepath(bc_tester_get_writable_dir_prefix(), "friends", "db");
|
||||
LinphoneFriendListStats *stats = (LinphoneFriendListStats *)ms_new0(LinphoneFriendListStats, 1);
|
||||
|
||||
v_table->friend_list_created = friend_list_created_cb;
|
||||
v_table->friend_list_removed = friend_list_removed_cb;
|
||||
lc = linphone_core_new(v_table, NULL, NULL, NULL);
|
||||
friends = linphone_friend_list_get_friends(linphone_core_get_default_friend_list(lc));
|
||||
lfl = linphone_core_create_friend_list(lc);
|
||||
linphone_friend_list_set_user_data(lfl, stats);
|
||||
BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d");
|
||||
|
||||
unlink(friends_db);
|
||||
linphone_core_set_friends_database_path(lc, friends_db);
|
||||
friends_from_db = linphone_core_fetch_friends_from_db(lc, linphone_core_get_default_friend_list(lc));
|
||||
BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 0, int, "%d");
|
||||
|
||||
linphone_vcard_set_etag(lvc, "\"123-456789\"");
|
||||
linphone_vcard_set_url(lvc, "http://dav.somewhere.fr/addressbook/me/someone.vcf");
|
||||
lf = linphone_friend_new_from_vcard(lvc);
|
||||
linphone_friend_set_address(lf, addr);
|
||||
linphone_friend_set_name(lf, "Sylvain");
|
||||
|
||||
linphone_core_add_friend_list(lc, lfl);
|
||||
wait_for_until(lc, NULL, &stats->new_list_count, 1, 1000);
|
||||
BC_ASSERT_EQUAL(stats->new_list_count, 1, int, "%i");
|
||||
linphone_friend_list_unref(lfl);
|
||||
linphone_friend_list_set_display_name(lfl, "Test");
|
||||
BC_ASSERT_EQUAL_FATAL(linphone_friend_list_add_friend(lfl, lf), LinphoneFriendListOK, int, "%i");
|
||||
linphone_friend_unref(lf);
|
||||
BC_ASSERT_EQUAL(lfl->storage_id, 1, int, "%d");
|
||||
BC_ASSERT_EQUAL(lf->storage_id, 1, int, "%d");
|
||||
|
||||
friends = linphone_friend_list_get_friends(linphone_core_get_default_friend_list(lc));
|
||||
BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d");
|
||||
|
||||
friends_lists_from_db = linphone_core_fetch_friends_lists_from_db(lc);
|
||||
BC_ASSERT_EQUAL(ms_list_size(friends_lists_from_db), 1, int, "%d");
|
||||
friends_from_db = ((LinphoneFriendList *)friends_lists_from_db->data)->friends;
|
||||
BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 1, int, "%d");
|
||||
lf2 = (LinphoneFriend *)friends_from_db->data;
|
||||
BC_ASSERT_PTR_NOT_NULL(lf2->lc);
|
||||
BC_ASSERT_PTR_NOT_NULL(lf2->friend_list);
|
||||
friends_lists_from_db = ms_list_free_with_data(friends_lists_from_db, (void (*)(void *))linphone_friend_list_unref);
|
||||
|
||||
friends_from_db = linphone_core_fetch_friends_from_db(lc, lfl);
|
||||
BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 1, int, "%d");
|
||||
if (ms_list_size(friends_from_db) < 1) {
|
||||
goto end;
|
||||
}
|
||||
lf2 = (LinphoneFriend *)friends_from_db->data;
|
||||
BC_ASSERT_STRING_EQUAL(linphone_friend_get_name(lf2), linphone_friend_get_name(lf));
|
||||
BC_ASSERT_EQUAL(lf2->storage_id, lf->storage_id, int, "%i");
|
||||
BC_ASSERT_STRING_EQUAL(linphone_vcard_get_etag(linphone_friend_get_vcard(lf2)), linphone_vcard_get_etag(linphone_friend_get_vcard(lf)));
|
||||
BC_ASSERT_STRING_EQUAL(linphone_vcard_get_url(linphone_friend_get_vcard(lf2)), linphone_vcard_get_url(linphone_friend_get_vcard(lf)));
|
||||
BC_ASSERT_STRING_EQUAL(linphone_address_as_string(linphone_friend_get_address(lf2)), linphone_address_as_string(linphone_friend_get_address(lf)));
|
||||
|
||||
linphone_friend_edit(lf);
|
||||
linphone_friend_set_name(lf, "Margaux");
|
||||
linphone_friend_done(lf);
|
||||
friends_from_db = ms_list_free_with_data(friends_from_db, (void (*)(void *))linphone_friend_unref);
|
||||
friends_from_db = linphone_core_fetch_friends_from_db(lc, lfl);
|
||||
BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 1, int, "%d");
|
||||
if (ms_list_size(friends_from_db) < 1) {
|
||||
goto end;
|
||||
}
|
||||
lf2 = (LinphoneFriend *)friends_from_db->data;
|
||||
BC_ASSERT_STRING_EQUAL(linphone_friend_get_name(lf2), "Margaux");
|
||||
friends_from_db = ms_list_free_with_data(friends_from_db, (void (*)(void *))linphone_friend_unref);
|
||||
|
||||
linphone_friend_list_remove_friend(lfl, lf);
|
||||
friends = linphone_friend_list_get_friends(linphone_core_get_default_friend_list(lc));
|
||||
BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d");
|
||||
friends_from_db = linphone_core_fetch_friends_from_db(lc, lfl);
|
||||
BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 0, int, "%d");
|
||||
|
||||
linphone_core_remove_friend_list(lc, lfl);
|
||||
wait_for_until(lc, NULL, &stats->removed_list_count, 1, 1000);
|
||||
BC_ASSERT_EQUAL(stats->removed_list_count, 1, int, "%i");
|
||||
|
||||
end:
|
||||
unlink(friends_db);
|
||||
ms_free(friends_db);
|
||||
linphone_address_unref(addr);
|
||||
linphone_core_destroy(lc);
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef struct _LinphoneCardDAVStats {
|
||||
int sync_done_count;
|
||||
int new_contact_count;
|
||||
int removed_contact_count;
|
||||
int updated_contact_count;
|
||||
} LinphoneCardDAVStats;
|
||||
|
||||
static void carddav_sync_done(LinphoneCardDavContext *c, bool_t success, const char *message) {
|
||||
LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c);
|
||||
BC_ASSERT_TRUE(success);
|
||||
stats->sync_done_count++;
|
||||
}
|
||||
|
||||
static void carddav_new_contact(LinphoneCardDavContext *c, LinphoneFriend *lf) {
|
||||
LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c);
|
||||
BC_ASSERT_PTR_NOT_NULL_FATAL(lf);
|
||||
stats->new_contact_count++;
|
||||
}
|
||||
|
||||
static void carddav_removed_contact(LinphoneCardDavContext *c, LinphoneFriend *lf) {
|
||||
LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c);
|
||||
BC_ASSERT_PTR_NOT_NULL_FATAL(lf);
|
||||
stats->removed_contact_count++;
|
||||
}
|
||||
|
||||
static void carddav_updated_contact(LinphoneCardDavContext *c, LinphoneFriend *new_lf, LinphoneFriend *old_lf) {
|
||||
LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c);
|
||||
BC_ASSERT_PTR_NOT_NULL_FATAL(new_lf);
|
||||
BC_ASSERT_PTR_NOT_NULL_FATAL(old_lf);
|
||||
stats->updated_contact_count++;
|
||||
}
|
||||
|
||||
static void carddav_sync(void) {
|
||||
LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE);
|
||||
LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1);
|
||||
LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc);
|
||||
LinphoneCardDavContext *c = NULL;
|
||||
|
||||
linphone_friend_list_set_uri(lfl, "http://dav.linphone.org/sabredav/addressbookserver.php/addressbooks/sylvain/default");
|
||||
linphone_core_add_friend_list(manager->lc, lfl);
|
||||
linphone_friend_list_unref(lfl);
|
||||
c = linphone_carddav_context_new(lfl);
|
||||
BC_ASSERT_PTR_NOT_NULL_FATAL(c);
|
||||
|
||||
linphone_carddav_set_user_data(c, stats);
|
||||
linphone_carddav_set_synchronization_done_callback(c, carddav_sync_done);
|
||||
linphone_carddav_set_new_contact_callback(c, carddav_new_contact);
|
||||
linphone_carddav_set_removed_contact_callback(c, carddav_removed_contact);
|
||||
linphone_carddav_set_updated_contact_callback(c, carddav_updated_contact);
|
||||
linphone_carddav_synchronize(c);
|
||||
|
||||
wait_for_until(manager->lc, NULL, &stats->new_contact_count, 1, 2000);
|
||||
BC_ASSERT_EQUAL(stats->new_contact_count, 1, int, "%i");
|
||||
wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000);
|
||||
BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i");
|
||||
|
||||
ms_free(stats);
|
||||
linphone_carddav_context_destroy(c);
|
||||
linphone_core_manager_destroy(manager);
|
||||
}
|
||||
|
||||
static void carddav_sync_2(void) {
|
||||
LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE);
|
||||
LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1);
|
||||
LinphoneFriend *lf = linphone_friend_new_with_address("\"Sylvain\" <sip:sylvain@sip.linphone.org>");
|
||||
char *friends_db = create_filepath(bc_tester_get_writable_dir_prefix(), "friends", "db");
|
||||
LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc);
|
||||
LinphoneCardDavContext *c = NULL;
|
||||
|
||||
linphone_friend_list_set_uri(lfl, "http://dav.linphone.org/sabredav/addressbookserver.php/addressbooks/sylvain/default");
|
||||
linphone_core_add_friend_list(manager->lc, lfl);
|
||||
linphone_friend_list_unref(lfl);
|
||||
c = linphone_carddav_context_new(lfl);
|
||||
BC_ASSERT_PTR_NOT_NULL_FATAL(c);
|
||||
|
||||
unlink(friends_db);
|
||||
linphone_core_set_friends_database_path(manager->lc, friends_db);
|
||||
BC_ASSERT_EQUAL_FATAL(linphone_friend_list_add_friend(lfl, lf), LinphoneFriendListOK, int, "%d");
|
||||
linphone_friend_unref(lf);
|
||||
|
||||
linphone_carddav_set_user_data(c, stats);
|
||||
linphone_carddav_set_synchronization_done_callback(c, carddav_sync_done);
|
||||
linphone_carddav_set_new_contact_callback(c, carddav_new_contact);
|
||||
linphone_carddav_set_removed_contact_callback(c, carddav_removed_contact);
|
||||
linphone_carddav_set_updated_contact_callback(c, carddav_updated_contact);
|
||||
|
||||
linphone_carddav_synchronize(c);
|
||||
|
||||
wait_for_until(manager->lc, NULL, &stats->new_contact_count, 1, 2000);
|
||||
BC_ASSERT_EQUAL(stats->new_contact_count, 1, int, "%i");
|
||||
wait_for_until(manager->lc, NULL, &stats->removed_contact_count, 1, 2000);
|
||||
BC_ASSERT_EQUAL(stats->removed_contact_count, 1, int, "%i");
|
||||
wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000);
|
||||
BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i");
|
||||
|
||||
ms_free(stats);
|
||||
unlink(friends_db);
|
||||
ms_free(friends_db);
|
||||
linphone_carddav_context_destroy(c);
|
||||
linphone_core_manager_destroy(manager);
|
||||
}
|
||||
|
||||
static void carddav_sync_3(void) {
|
||||
LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE);
|
||||
LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1);
|
||||
LinphoneVCard *lvc = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nUID:1f08dd48-29ac-4097-8e48-8596d7776283\r\nFN:Sylvain Berfini\r\nIMPP;TYPE=work:sip:sylvain@sip.linphone.org\r\nEND:VCARD\r\n");
|
||||
LinphoneFriend *lf = linphone_friend_new_from_vcard(lvc);
|
||||
char *friends_db = create_filepath(bc_tester_get_writable_dir_prefix(), "friends", "db");
|
||||
LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc);
|
||||
LinphoneCardDavContext *c = NULL;
|
||||
|
||||
linphone_friend_list_set_uri(lfl, "http://dav.linphone.org/sabredav/addressbookserver.php/addressbooks/sylvain/default");
|
||||
linphone_core_add_friend_list(manager->lc, lfl);
|
||||
linphone_friend_list_unref(lfl);
|
||||
c = linphone_carddav_context_new(lfl);
|
||||
BC_ASSERT_PTR_NOT_NULL_FATAL(c);
|
||||
|
||||
unlink(friends_db);
|
||||
linphone_core_set_friends_database_path(manager->lc, friends_db);
|
||||
BC_ASSERT_EQUAL_FATAL(linphone_friend_list_add_friend(lfl, lf), LinphoneFriendListOK, int, "%d");
|
||||
linphone_friend_unref(lf);
|
||||
|
||||
linphone_carddav_set_user_data(c, stats);
|
||||
linphone_carddav_set_synchronization_done_callback(c, carddav_sync_done);
|
||||
linphone_carddav_set_new_contact_callback(c, carddav_new_contact);
|
||||
linphone_carddav_set_removed_contact_callback(c, carddav_removed_contact);
|
||||
linphone_carddav_set_updated_contact_callback(c, carddav_updated_contact);
|
||||
|
||||
linphone_carddav_synchronize(c);
|
||||
|
||||
wait_for_until(manager->lc, NULL, &stats->updated_contact_count, 1, 2000);
|
||||
BC_ASSERT_EQUAL(stats->updated_contact_count, 1, int, "%i");
|
||||
wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000);
|
||||
BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i");
|
||||
|
||||
ms_free(stats);
|
||||
unlink(friends_db);
|
||||
ms_free(friends_db);
|
||||
linphone_carddav_context_destroy(c);
|
||||
linphone_core_manager_destroy(manager);
|
||||
}
|
||||
|
||||
static void carddav_sync_4(void) {
|
||||
LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE);
|
||||
LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1);
|
||||
LinphoneVCard *lvc = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Margaux Clerc\r\nIMPP;TYPE=work:sip:margaux@sip.linphone.org\r\nEND:VCARD\r\n");
|
||||
LinphoneFriend *lf = linphone_friend_new_from_vcard(lvc);
|
||||
LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc);
|
||||
LinphoneCardDavContext *c = NULL;
|
||||
|
||||
linphone_friend_list_set_uri(lfl, "http://dav.linphone.org/sabredav/addressbookserver.php/addressbooks/sylvain/default");
|
||||
linphone_core_add_friend_list(manager->lc, lfl);
|
||||
linphone_friend_list_unref(lfl);
|
||||
c = linphone_carddav_context_new(lfl);
|
||||
BC_ASSERT_PTR_NOT_NULL_FATAL(c);
|
||||
|
||||
linphone_carddav_set_user_data(c, stats);
|
||||
linphone_carddav_set_synchronization_done_callback(c, carddav_sync_done);
|
||||
linphone_carddav_set_new_contact_callback(c, carddav_new_contact);
|
||||
linphone_carddav_set_removed_contact_callback(c, carddav_removed_contact);
|
||||
linphone_carddav_set_updated_contact_callback(c, carddav_updated_contact);
|
||||
|
||||
BC_ASSERT_PTR_NULL(linphone_vcard_get_uid(lvc));
|
||||
linphone_carddav_put_vcard(c, lf);
|
||||
BC_ASSERT_PTR_NOT_NULL(linphone_vcard_get_uid(lvc));
|
||||
wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000);
|
||||
BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i");
|
||||
|
||||
linphone_carddav_delete_vcard(c, lf);
|
||||
wait_for_until(manager->lc, NULL, &stats->sync_done_count, 2, 2000);
|
||||
BC_ASSERT_EQUAL(stats->sync_done_count, 2, int, "%i");
|
||||
|
||||
linphone_friend_unref(lf);
|
||||
ms_free(stats);
|
||||
linphone_carddav_context_destroy(c);
|
||||
linphone_core_manager_destroy(manager);
|
||||
}
|
||||
|
||||
static void carddav_contact_created(LinphoneFriendList *list, LinphoneFriend *lf) {
|
||||
LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_friend_list_cbs_get_user_data(list->cbs);
|
||||
stats->new_contact_count++;
|
||||
}
|
||||
|
||||
static void carddav_contact_deleted(LinphoneFriendList *list, LinphoneFriend *lf) {
|
||||
LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_friend_list_cbs_get_user_data(list->cbs);
|
||||
stats->removed_contact_count++;
|
||||
}
|
||||
|
||||
static void carddav_contact_updated(LinphoneFriendList *list, LinphoneFriend *new_friend, LinphoneFriend *old_friend) {
|
||||
LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_friend_list_cbs_get_user_data(list->cbs);
|
||||
BC_ASSERT_STRING_EQUAL(linphone_vcard_get_full_name(linphone_friend_get_vcard(new_friend)), linphone_vcard_get_full_name(linphone_friend_get_vcard(old_friend)));
|
||||
stats->updated_contact_count++;
|
||||
}
|
||||
|
||||
static void carddav_sync_status_changed(LinphoneFriendList *list, LinphoneFriendListSyncStatus status, const char *msg) {
|
||||
LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_friend_list_cbs_get_user_data(list->cbs);
|
||||
char *state = status == LinphoneFriendListSyncStarted ? "Sync started" : (status == LinphoneFriendListSyncFailure ? "Sync failure" : "Sync successful");
|
||||
ms_message("[CardDAV] %s : %s", state, msg);
|
||||
if (status == LinphoneFriendListSyncFailure || status == LinphoneFriendListSyncSuccessful) {
|
||||
stats->sync_done_count++;
|
||||
}
|
||||
}
|
||||
|
||||
static void carddav_integration(void) {
|
||||
LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE);
|
||||
LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc);
|
||||
LinphoneVCard *lvc = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Margaux Clerc\r\nIMPP;TYPE=work:sip:margaux@sip.linphone.org\r\nEND:VCARD\r\n");
|
||||
LinphoneFriend *lf = linphone_friend_new_from_vcard(lvc);
|
||||
LinphoneVCard *lvc2 = NULL;
|
||||
LinphoneFriend *lf2 = NULL;
|
||||
LinphoneFriendListCbs *cbs = NULL;
|
||||
LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1);
|
||||
const char *refkey = "toto";
|
||||
|
||||
linphone_friend_list_set_uri(lfl, "http://dav.linphone.org/sabredav/addressbookserver.php/addressbooks/sylvain/default");
|
||||
cbs = linphone_friend_list_get_callbacks(lfl);
|
||||
linphone_friend_list_cbs_set_user_data(cbs, stats);
|
||||
linphone_friend_list_cbs_set_contact_created(cbs, carddav_contact_created);
|
||||
linphone_friend_list_cbs_set_contact_deleted(cbs, carddav_contact_deleted);
|
||||
linphone_friend_list_cbs_set_contact_updated(cbs, carddav_contact_updated);
|
||||
linphone_friend_list_cbs_set_sync_status_changed(cbs, carddav_sync_status_changed);
|
||||
linphone_core_add_friend_list(manager->lc, lfl);
|
||||
|
||||
BC_ASSERT_PTR_NULL(linphone_vcard_get_uid(lvc));
|
||||
BC_ASSERT_EQUAL(ms_list_size(lfl->dirty_friends_to_update), 0, int, "%d");
|
||||
BC_ASSERT_EQUAL_FATAL(linphone_friend_list_add_friend(lfl, lf), LinphoneFriendListOK, int, "%d");
|
||||
BC_ASSERT_EQUAL(ms_list_size(lfl->dirty_friends_to_update), 1, int, "%d");
|
||||
wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000);
|
||||
BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i");
|
||||
BC_ASSERT_EQUAL(ms_list_size(lfl->dirty_friends_to_update), 0, int, "%d");
|
||||
BC_ASSERT_PTR_NOT_NULL(linphone_vcard_get_uid(lvc));
|
||||
linphone_friend_list_remove_friend(lfl, lf);
|
||||
BC_ASSERT_EQUAL(ms_list_size(lfl->friends), 0, int, "%d");
|
||||
wait_for_until(manager->lc, NULL, &stats->sync_done_count, 2, 2000);
|
||||
BC_ASSERT_EQUAL(stats->sync_done_count, 2, int, "%i");
|
||||
linphone_friend_unref(lf);
|
||||
lf = NULL;
|
||||
|
||||
lvc = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Ghislain Mary\r\nIMPP;TYPE=work:sip:ghislain@sip.linphone.org\r\nEND:VCARD\r\n");
|
||||
lf = linphone_friend_new_from_vcard(lvc);
|
||||
BC_ASSERT_EQUAL_FATAL(linphone_friend_list_add_local_friend(lfl, lf), LinphoneFriendListOK, int, "%d");
|
||||
linphone_friend_unref(lf);
|
||||
|
||||
lvc2 = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Sylvain Berfini\r\nIMPP:sip:sberfini@sip.linphone.org\r\nUID:1f08dd48-29ac-4097-8e48-8596d7776283\r\nEND:VCARD\r\n");
|
||||
linphone_vcard_set_url(lvc2, "/sabredav/addressbookserver.php/addressbooks/sylvain/default/me.vcf");
|
||||
lf2 = linphone_friend_new_from_vcard(lvc2);
|
||||
linphone_friend_set_ref_key(lf2, refkey);
|
||||
BC_ASSERT_EQUAL_FATAL(linphone_friend_list_add_local_friend(lfl, lf2), LinphoneFriendListOK, int, "%d");
|
||||
|
||||
BC_ASSERT_EQUAL(lfl->revision, 0, int, "%i");
|
||||
linphone_friend_list_synchronize_friends_from_server(lfl);
|
||||
wait_for_until(manager->lc, NULL, &stats->new_contact_count, 0, 2000);
|
||||
BC_ASSERT_EQUAL(stats->new_contact_count, 0, int, "%i");
|
||||
wait_for_until(manager->lc, NULL, &stats->removed_contact_count, 1, 2000);
|
||||
BC_ASSERT_EQUAL(stats->removed_contact_count, 1, int, "%i");
|
||||
wait_for_until(manager->lc, NULL, &stats->updated_contact_count, 1, 2000);
|
||||
BC_ASSERT_EQUAL(stats->updated_contact_count, 1, int, "%i");
|
||||
BC_ASSERT_NOT_EQUAL(lfl->revision, 0, int, "%i");
|
||||
wait_for_until(manager->lc, NULL, &stats->sync_done_count, 3, 2000);
|
||||
BC_ASSERT_EQUAL(stats->sync_done_count, 3, int, "%i");
|
||||
|
||||
BC_ASSERT_EQUAL_FATAL(ms_list_size(lfl->friends), 1, int, "%i");
|
||||
lf = (LinphoneFriend *)lfl->friends->data;
|
||||
BC_ASSERT_STRING_EQUAL(lf->refkey, refkey);
|
||||
BC_ASSERT_EQUAL(lf->storage_id, lf2->storage_id, int, "%i");
|
||||
linphone_friend_unref(lf2);
|
||||
BC_ASSERT_STRING_EQUAL(linphone_address_as_string_uri_only(lf->uri), "sip:sylvain@sip.linphone.org");
|
||||
|
||||
linphone_friend_edit(lf);
|
||||
linphone_friend_done(lf);
|
||||
BC_ASSERT_EQUAL(ms_list_size(lf->friend_list->dirty_friends_to_update), 0, int, "%i");
|
||||
|
||||
linphone_core_set_network_reachable(manager->lc, FALSE); //To prevent the CardDAV update
|
||||
linphone_friend_edit(lf);
|
||||
linphone_friend_set_name(lf, "François Grisez");
|
||||
linphone_friend_done(lf);
|
||||
BC_ASSERT_EQUAL(ms_list_size(lf->friend_list->dirty_friends_to_update), 1, int, "%i");
|
||||
|
||||
ms_free(stats);
|
||||
linphone_friend_list_unref(lfl);
|
||||
linphone_core_manager_destroy(manager);
|
||||
}
|
||||
|
||||
static void carddav_clean(void) { // This is to ensure the content of the test addressbook is in the correct state for the following tests
|
||||
LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE);
|
||||
LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc);
|
||||
LinphoneFriendListCbs *cbs = linphone_friend_list_get_callbacks(lfl);
|
||||
LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1);
|
||||
MSList *friends = NULL;
|
||||
LinphoneFriend *lf = NULL;
|
||||
LinphoneVCard *lvc = NULL;
|
||||
|
||||
linphone_friend_list_cbs_set_user_data(cbs, stats);
|
||||
linphone_friend_list_cbs_set_contact_created(cbs, carddav_contact_created);
|
||||
linphone_friend_list_cbs_set_contact_deleted(cbs, carddav_contact_deleted);
|
||||
linphone_friend_list_cbs_set_contact_updated(cbs, carddav_contact_updated);
|
||||
linphone_friend_list_cbs_set_sync_status_changed(cbs, carddav_sync_status_changed);
|
||||
linphone_core_add_friend_list(manager->lc, lfl);
|
||||
linphone_friend_list_set_uri(lfl, "http://dav.linphone.org/sabredav/addressbookserver.php/addressbooks/sylvain/default");
|
||||
|
||||
linphone_friend_list_synchronize_friends_from_server(lfl);
|
||||
wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000);
|
||||
BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i");
|
||||
stats->sync_done_count = 0;
|
||||
|
||||
friends = ms_list_copy(lfl->friends);
|
||||
while (friends) {
|
||||
LinphoneFriend *lf = (LinphoneFriend *)friends->data;
|
||||
linphone_friend_list_remove_friend(lfl, lf);
|
||||
wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000);
|
||||
BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i");
|
||||
stats->sync_done_count = 0;
|
||||
stats->removed_contact_count = 0;
|
||||
friends = ms_list_next(friends);
|
||||
}
|
||||
|
||||
lvc = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Sylvain Berfini\r\nIMPP:sip:sylvain@sip.linphone.org\r\nUID:1f08dd48-29ac-4097-8e48-8596d7776283\r\nEND:VCARD\r\n");
|
||||
linphone_vcard_set_url(lvc, "http://dav.linphone.org/sabredav/addressbookserver.php/addressbooks/sylvain/default/me.vcf");
|
||||
lf = linphone_friend_new_from_vcard(lvc);
|
||||
linphone_friend_list_add_friend(lfl, lf);
|
||||
wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000);
|
||||
BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i");
|
||||
|
||||
ms_free(stats);
|
||||
linphone_friend_unref(lf);
|
||||
linphone_friend_list_unref(lfl);
|
||||
linphone_core_manager_destroy(manager);
|
||||
}
|
||||
|
||||
static void carddav_multiple_sync(void) {
|
||||
LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE);
|
||||
LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc);
|
||||
LinphoneFriendListCbs *cbs = linphone_friend_list_get_callbacks(lfl);
|
||||
LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1);
|
||||
|
||||
linphone_friend_list_cbs_set_user_data(cbs, stats);
|
||||
linphone_friend_list_cbs_set_contact_created(cbs, carddav_contact_created);
|
||||
linphone_friend_list_cbs_set_contact_deleted(cbs, carddav_contact_deleted);
|
||||
linphone_friend_list_cbs_set_contact_updated(cbs, carddav_contact_updated);
|
||||
linphone_friend_list_cbs_set_sync_status_changed(cbs, carddav_sync_status_changed);
|
||||
linphone_core_add_friend_list(manager->lc, lfl);
|
||||
linphone_friend_list_set_uri(lfl, "http://dav.linphone.org/sabredav/addressbookserver.php/addressbooks/sylvain/default");
|
||||
|
||||
linphone_friend_list_synchronize_friends_from_server(lfl);
|
||||
wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000);
|
||||
BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i");
|
||||
linphone_friend_list_synchronize_friends_from_server(lfl);
|
||||
wait_for_until(manager->lc, NULL, &stats->sync_done_count, 2, 2000);
|
||||
BC_ASSERT_EQUAL(stats->sync_done_count, 2, int, "%i");
|
||||
linphone_friend_list_synchronize_friends_from_server(lfl);
|
||||
wait_for_until(manager->lc, NULL, &stats->sync_done_count, 3, 2000);
|
||||
BC_ASSERT_EQUAL(stats->sync_done_count, 3, int, "%i");
|
||||
BC_ASSERT_EQUAL(stats->removed_contact_count, 0, int, "%i");
|
||||
|
||||
linphone_friend_list_unref(lfl);
|
||||
linphone_core_manager_destroy(manager);
|
||||
}
|
||||
|
||||
#else
|
||||
static void dummy_test(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
test_t vcard_tests[] = {
|
||||
#ifdef VCARD_ENABLED
|
||||
{ "Import / Export friends from vCards", linphone_vcard_import_export_friends_test },
|
||||
{ "Import a lot of friends from vCards", linphone_vcard_import_a_lot_of_friends_test },
|
||||
{ "vCard creation for existing friends", linphone_vcard_update_existing_friends_test },
|
||||
#ifdef FRIENDS_SQL_STORAGE_ENABLED
|
||||
{ "Friends working if no db set", friends_if_no_db_set },
|
||||
{ "Friends storage migration from rc to db", friends_migration },
|
||||
{ "Friends storage in sqlite database", friends_sqlite_storage },
|
||||
#endif
|
||||
{ "CardDAV clean", carddav_clean }, // This is to ensure the content of the test addressbook is in the correct state for the following tests
|
||||
{ "CardDAV synchronization", carddav_sync },
|
||||
{ "CardDAV synchronization 2", carddav_sync_2 },
|
||||
{ "CardDAV synchronization 3", carddav_sync_3 },
|
||||
{ "CardDAV synchronization 4", carddav_sync_4 },
|
||||
{ "CardDAV integration", carddav_integration },
|
||||
{ "CardDAV multiple synchronizations", carddav_multiple_sync },
|
||||
#else
|
||||
{ "Dummy test", dummy_test }
|
||||
#endif
|
||||
};
|
||||
|
||||
test_suite_t vcard_test_suite = {
|
||||
"VCard", NULL, NULL,
|
||||
liblinphone_tester_before_each, liblinphone_tester_after_each,
|
||||
sizeof(vcard_tests) / sizeof(vcard_tests[0]), vcard_tests
|
||||
};
|
||||
Loading…
Add table
Reference in a new issue