diff --git a/.cproject b/.cproject index aafe2d5c4..f4c0aff9b 100644 --- a/.cproject +++ b/.cproject @@ -1,7 +1,5 @@ - - - + @@ -45,6 +43,7 @@ + diff --git a/CMakeLists.txt b/CMakeLists.txt index 89333bde4..fad26da22 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,12 +20,12 @@ # ############################################################################ -cmake_minimum_required(VERSION 2.8.12) +cmake_minimum_required(VERSION 3.0) project(LINPHONE C CXX) set(LINPHONE_MAJOR_VERSION "3") -set(LINPHONE_MINOR_VERSION "7") +set(LINPHONE_MINOR_VERSION "8") set(LINPHONE_MICRO_VERSION "0") set(LINPHONE_VERSION "${LINPHONE_MAJOR_VERSION}.${LINPHONE_MINOR_VERSION}.${LINPHONE_MICRO_VERSION}") set(LINPHONE_SO_VERSION "6") @@ -53,17 +53,46 @@ cmake_dependent_option(ENABLE_ASSISTANT "Turn on assistant compiling." YES "ENAB list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") -list(APPEND CMAKE_MODULE_PATH "${CMAKE_PREFIX_PATH}/share/cmake/Modules") -include(CheckIncludeFile) include(CheckSymbolExists) +include(CMakePushCheckState) +set(MSVC_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include/MSVC") if(MSVC) - list(APPEND CMAKE_REQUIRED_INCLUDES "${CMAKE_PREFIX_PATH}/include/MSVC") + list(APPEND CMAKE_REQUIRED_INCLUDES "${MSVC_INCLUDE_DIR}") + + if(ENABLE_GTK_UI) + if(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/intltool_win32.zip") + message(STATUS "Installing intltool") + file(DOWNLOAD http://ftp.acc.umu.se/pub/GNOME/binaries/win32/intltool/0.40/intltool_0.40.4-1_win32.zip "${CMAKE_CURRENT_BINARY_DIR}/intltool_win32.zip" SHOW_PROGRESS) + execute_process( + COMMAND "${CMAKE_COMMAND}" "-E" "tar" "x" "${CMAKE_CURRENT_BINARY_DIR}/intltool_win32.zip" + WORKING_DIRECTORY "${CMAKE_INSTALL_PREFIX}" + ) + endif() + if(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/gtk+-bundle_win32.zip") + message(STATUS "Installing GTK") + file(DOWNLOAD http://ftp.gnome.org/pub/gnome/binaries/win32/gtk+/2.24/gtk+-bundle_2.24.10-20120208_win32.zip "${CMAKE_CURRENT_BINARY_DIR}/gtk+-bundle_win32.zip" SHOW_PROGRESS) + execute_process( + COMMAND "${CMAKE_COMMAND}" "-E" "tar" "x" "${CMAKE_CURRENT_BINARY_DIR}/gtk+-bundle_win32.zip" + WORKING_DIRECTORY "${CMAKE_INSTALL_PREFIX}" + ) + endif() + endif() + if(ENABLE_ASSISTANT) + if(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/libsoup.zip") + message(STATUS "Installing libsoup") + file(DOWNLOAD http://www.linphone.org/files/libsoup_2.24.0-1_win32.zip "${CMAKE_CURRENT_BINARY_DIR}/libsoup.zip" SHOW_PROGRESS) + execute_process( + COMMAND "${CMAKE_COMMAND}" "-E" "tar" "x" "${CMAKE_CURRENT_BINARY_DIR}/libsoup.zip" + WORKING_DIRECTORY "${CMAKE_INSTALL_PREFIX}" + ) + endif() + endif() endif() find_package(BelleSIP REQUIRED) -find_package(MS2 REQUIRED) +find_package(Mediastreamer2 REQUIRED) find_package(XML2 REQUIRED) if(ENABLE_UNIT_TESTS) find_package(CUnit) @@ -87,10 +116,7 @@ if(ENABLE_TUNNEL) endif() endif() if(ENABLE_MSG_STORAGE) - find_package(Sqlite3) - if(NOT SQLITE3_FOUND) - message(FATAL_ERROR "Could not find the sqlite3 library!") - endif() + find_package(Sqlite3 REQUIRED) endif() if(ENABLE_NOTIFY) find_package(Notify) @@ -119,7 +145,7 @@ include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/coreapi/ ${BELLESIP_INCLUDE_DIRS} - ${MS2_INCLUDE_DIRS} + ${MEDIASTREAMER2_INCLUDE_DIRS} ${XML2_INCLUDE_DIRS} ) if(SQLITE3_FOUND) @@ -132,9 +158,8 @@ endif() if(ENABLE_ASSISTANT) include_directories(${SOUP_INCLUDE_DIRS}) endif() - if(MSVC) - include_directories(${CMAKE_PREFIX_PATH}/include/MSVC) + include_directories(${MSVC_INCLUDE_DIR}) endif() add_definitions("-DIN_LINPHONE") @@ -166,6 +191,9 @@ else() set(LINPHONE_DATA_DIR "${CMAKE_INSTALL_PREFIX}") endif() set(LINPHONE_PLUGINS_DIR "${LINPHONE_DATA_DIR}/lib/liblinphone/plugins") +if(WIN32) + set(LINPHONE_CONFIG_DIR "Linphone") +endif() set(PACKAGE_LOCALE_DIR "${LINPHONE_DATA_DIR}/share/locale") set(PACKAGE_DATA_DIR "${LINPHONE_DATA_DIR}/share") set(PACKAGE_SOUND_DIR "${LINPHONE_DATA_DIR}/share/sounds/linphone") @@ -196,9 +224,29 @@ if(ENABLE_UNIT_TESTS) endif() -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindLinphone.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/FindLinphone.cmake) - -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/FindLinphone.cmake - DESTINATION share/cmake/Modules - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ +include(CMakePackageConfigHelpers) +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/LinphoneConfigVersion.cmake" + VERSION ${LINPHONE_VERSION} + COMPATIBILITY AnyNewerVersion +) +export(EXPORT LinphoneTargets + FILE "${CMAKE_CURRENT_BINARY_DIR}/LinphoneTargets.cmake" + NAMESPACE BelledonneCommunications:: +) +configure_file(cmake/LinphoneConfig.cmake.in + "${CMAKE_CURRENT_BINARY_DIR}/LinphoneConfig.cmake" + @ONLY +) + +set(ConfigPackageLocation lib/cmake/Linphone) +install(EXPORT LinphoneTargets + FILE LinphoneTargets.cmake + NAMESPACE BelledonneCommunications:: + DESTINATION ${ConfigPackageLocation} +) +install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/LinphoneConfig.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/LinphoneConfigVersion.cmake" + DESTINATION ${ConfigPackageLocation} ) diff --git a/NEWS b/NEWS index acdbf2e45..8e40b72b6 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,4 @@ -linphone-3.8.0 -- Date to be defined +linphone-3.8.0 -- March 11th, 2015 Application level improvements: * The video window has now controls in order to switch fullscreen mode and terminate call. * The out of call video preview feature (to test camera) is moved into the settings and is no longer linked to the in-call video preview feature. diff --git a/README.macos.md b/README.macos.md index 20660a5a0..15746cf5e 100644 --- a/README.macos.md +++ b/README.macos.md @@ -63,10 +63,7 @@ The next pieces need to be compiled manually. * To ensure compatibility with multiple MacOS versions it is recommended to do: export MACOSX_DEPLOYMENT_TARGET=10.6 - export CFLAGS="-arch i386 -arch x86_64 -mmacosx-version-min=10.5" - export OBJCFLAGS="-arch i386 -arch x86_64 -mmacosx-version-min=10.5" - export CXXFLAGS="-arch i386 -arch x86_64 -mmacosx-version-min=10.5" - export LDFLAGS="-arch i386 -arch x86_64 -mmacosx-version-min=10.5 -Wl,-headerpad_max_install_names -Wl,-read_only_relocs -Wl,suppress" + export LDFLAGS="-Wl,-headerpad_max_install_names -Wl,-read_only_relocs -Wl,suppress" * (MacPorts only) Install libantlr3c (library used by belle-sip for parsing) diff --git a/build/android/Android.mk b/build/android/Android.mk index fbdeff652..6a55fc92b 100755 --- a/build/android/Android.mk +++ b/build/android/Android.mk @@ -58,6 +58,7 @@ LOCAL_SRC_FILES := \ linphone_tunnel_config.c \ localplayer.c \ lpc2xml.c \ + lime.c \ lpconfig.c \ message_storage.c \ misc.c \ @@ -71,7 +72,8 @@ LOCAL_SRC_FILES := \ siplogin.c \ sipsetup.c \ xml2lpc.c \ - xml.c + xml.c \ + vtables.c ifndef LIBLINPHONE_VERSION LIBLINPHONE_VERSION = "Devel" @@ -117,7 +119,8 @@ LOCAL_C_INCLUDES += \ $(LOCAL_PATH)/../../belle-sip/include \ $(LOCAL_PATH)/../../../gen \ $(LOCAL_PATH)/../../externals/libxml2/include \ - $(LOCAL_PATH)/../../externals/build/libxml2 + $(LOCAL_PATH)/../../externals/build/libxml2 \ + $(LOCAL_PATH)/../../externals/polarssl/include LOCAL_LDLIBS += -llog -ldl -lz diff --git a/build/android/liblinphone_tester.mk b/build/android/liblinphone_tester.mk index d62f055d8..58953a8a1 100644 --- a/build/android/liblinphone_tester.mk +++ b/build/android/liblinphone_tester.mk @@ -20,7 +20,8 @@ common_SRC_FILES := \ dtmf_tester.c \ accountmanager.c \ offeranswer_tester.c \ - multicast_call_tester.c + multicast_call_tester.c \ + multi_call.c common_C_INCLUDES += \ $(LOCAL_PATH) \ diff --git a/cmake/FindCUnit.cmake b/cmake/FindCUnit.cmake new file mode 100644 index 000000000..10c1a10b6 --- /dev/null +++ b/cmake/FindCUnit.cmake @@ -0,0 +1,58 @@ +############################################################################ +# FindCUnit.txt +# 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 CUnit include file and library +# +# CUNIT_FOUND - system has CUnit +# CUNIT_INCLUDE_DIRS - the CUnit include directory +# CUNIT_LIBRARIES - The libraries needed to use CUnit + +include(CheckIncludeFile) +include(CheckLibraryExists) + +set(_CUNIT_ROOT_PATHS + ${CMAKE_INSTALL_PREFIX} +) + +find_path(CUNIT_INCLUDE_DIRS + NAMES CUnit/CUnit.h + HINTS _CUNIT_ROOT_PATHS + PATH_SUFFIXES include +) + +if(CUNIT_INCLUDE_DIRS) + set(HAVE_CUNIT_CUNIT_H 1) +endif() + +find_library(CUNIT_LIBRARIES + NAMES cunit + HINTS ${_CUNIT_ROOT_PATHS} + PATH_SUFFIXES bin lib +) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(CUnit + DEFAULT_MSG + CUNIT_INCLUDE_DIRS CUNIT_LIBRARIES +) + +mark_as_advanced(CUNIT_INCLUDE_DIRS CUNIT_LIBRARIES) diff --git a/cmake/FindIconv.cmake b/cmake/FindIconv.cmake new file mode 100644 index 000000000..c65317a56 --- /dev/null +++ b/cmake/FindIconv.cmake @@ -0,0 +1,55 @@ +############################################################################ +# FindIconv.cmake +# Copyright (C) 2014 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 iconv include file and library +# +# ICONV_FOUND - system has libiconv +# ICONV_INCLUDE_DIRS - the libiconv include directory +# ICONV_LIBRARIES - The libraries needed to use libiconv + +set(_ICONV_ROOT_PATHS + ${CMAKE_INSTALL_PREFIX} +) + +find_path(ICONV_INCLUDE_DIRS + NAMES iconv.h + HINTS _ICONV_ROOT_PATHS + PATH_SUFFIXES include +) + +if(ICONV_INCLUDE_DIRS) + set(HAVE_ICONV_H 1) +endif() + +find_library(ICONV_LIBRARIES + NAMES iconv + HINTS ${_ICONV_ROOT_PATHS} + PATH_SUFFIXES bin lib +) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Iconv + DEFAULT_MSG + ICONV_INCLUDE_DIRS ICONV_LIBRARIES HAVE_ICONV_H +) + +mark_as_advanced(ICONV_INCLUDE_DIRS ICONV_LIBRARIES HAVE_ICONV_H) diff --git a/cmake/FindIntl.cmake b/cmake/FindIntl.cmake new file mode 100644 index 000000000..35ec969cd --- /dev/null +++ b/cmake/FindIntl.cmake @@ -0,0 +1,56 @@ +############################################################################ +# FindIntl.cmake +# Copyright (C) 2014 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 libintl include file and library +# +# INTL_FOUND - system has libintl +# INTL_INCLUDE_DIRS - the libintl include directory +# INTL_LIBRARIES - The libraries needed to use libintl + +set(_INTL_ROOT_PATHS + ${CMAKE_INSTALL_PREFIX} +) + +find_path(INTL_INCLUDE_DIRS + NAMES libintl.h + HINTS _INTL_ROOT_PATHS + PATH_SUFFIXES include +) + +if(INTL_INCLUDE_DIRS) + set(HAVE_LIBINTL_H 1) +endif() + +set(INTL_ARGS INTL_INCLUDE_DIRS HAVE_LIBINTL_H) +if(NOT UNIX OR APPLE) + find_library(INTL_LIBRARIES + NAMES intl + HINTS ${_INTL_ROOT_PATHS} + PATH_SUFFIXES bin lib + ) + list(APPEND INTL_ARGS INTL_LIBRARIES) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Intl DEFAULT_MSG ${INTL_ARGS}) + +mark_as_advanced(${INTL_ARGS}) diff --git a/cmake/FindLinphone.cmake.in b/cmake/FindLinphone.cmake.in deleted file mode 100644 index 5f8b03b19..000000000 --- a/cmake/FindLinphone.cmake.in +++ /dev/null @@ -1,83 +0,0 @@ -############################################################################ -# FindLinphone.cmake -# Copyright (C) 2014 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 linphone include file and library -# -# LINPHONE_FOUND - system has linphone -# LINPHONE_INCLUDE_DIRS - the linphone include directory -# LINPHONE_LIBRARIES - The libraries needed to use linphone -# LINPHONE_CPPFLAGS - The compilation flags needed to use linphone -# LINPHONE_LDFLAGS - The linking flags needed to use linphone - -find_package(ORTP REQUIRED) -find_package(MS2 REQUIRED) -find_package(XML2 REQUIRED) -find_package(BelleSIP REQUIRED) -if(@ENABLE_MSG_STORAGE@) - find_package(Sqlite3) -endif() - -set(_LINPHONE_ROOT_PATHS - ${WITH_LINPHONE} - ${CMAKE_INSTALL_PREFIX} -) - -find_path(LINPHONE_INCLUDE_DIRS - NAMES linphone/linphonecore.h - HINTS _LINPHONE_ROOT_PATHS - PATH_SUFFIXES include -) - -if(LINPHONE_INCLUDE_DIRS) - set(HAVE_LINPHONE_LINPHONECORE_H 1) -endif() - -find_library(LINPHONE_LIBRARIES - NAMES linphone - HINTS ${_LINPHONE_ROOT_PATHS} - PATH_SUFFIXES bin lib -) - -list(APPEND LINPHONE_INCLUDE_DIRS ${ORTP_INCLUDE_DIRS} ${MS2_INCLUDE_DIRS} ${XML2_INCLUDE_DIRS} ${BELLESIP_INCLUDE_DIRS}) -list(APPEND LINPHONE_LIBRARIES ${ORTP_LIBRARIES} ${MS2_LIBRARIES} ${XML2_LIBRARIES} ${BELLESIP_LIBRARIES}) - -if(SQLITE3_FOUND) - list(APPEND LINPHONE_INCLUDE_DIRS ${SQLITE3_INCLUDE_DIRS}) - list(APPEND LINPHONE_LIBRARIES ${SQLITE3_LIBRARIES}) -endif() - -if(WIN32) - list(APPEND LINPHONE_LIBRARIES shlwapi) -endif(WIN32) - -list(REMOVE_DUPLICATES LINPHONE_INCLUDE_DIRS) -list(REMOVE_DUPLICATES LINPHONE_LIBRARIES) -set(LINPHONE_CPPFLAGS "${MS2_CPPFLAGS}") -set(LINPHONE_LDFLAGS "${MS2_LDFLAGS} ${BELLESIP_LDFLAGS}") - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(Linphone - DEFAULT_MSG - LINPHONE_INCLUDE_DIRS LINPHONE_LIBRARIES -) - -mark_as_advanced(LINPHONE_INCLUDE_DIRS LINPHONE_LIBRARIES LINPHONE_CPPFLAGS LINPHONE_LDFLAGS) diff --git a/cmake/FindNotify.cmake b/cmake/FindNotify.cmake index f77e0885f..a9fb4d978 100644 --- a/cmake/FindNotify.cmake +++ b/cmake/FindNotify.cmake @@ -27,7 +27,6 @@ # NOTIFY_LIBRARIES - The libraries needed to use libnotify set(_NOTIFY_ROOT_PATHS - ${WITH_NOTIFY} ${CMAKE_INSTALL_PREFIX} ) diff --git a/cmake/FindSoup.cmake b/cmake/FindSoup.cmake index 82735a317..3aeffaefa 100644 --- a/cmake/FindSoup.cmake +++ b/cmake/FindSoup.cmake @@ -26,10 +26,12 @@ # SOUP_INCLUDE_DIRS - the libsoup include directory # SOUP_LIBRARIES - The libraries needed to use libsoup +if(WIN32) + set(GTK2_ADDITIONAL_SUFFIXES "../lib/glib-2.0/include" "../lib/gtk-2.0/include") +endif() find_package(GTK2 2.18 REQUIRED gtk) set(_SOUP_ROOT_PATHS - ${WITH_SOUP} ${CMAKE_INSTALL_PREFIX} ) diff --git a/cmake/FindSqlite3.cmake b/cmake/FindSqlite3.cmake new file mode 100644 index 000000000..7cab06bd1 --- /dev/null +++ b/cmake/FindSqlite3.cmake @@ -0,0 +1,55 @@ +############################################################################ +# FindSqlite3.cmake +# Copyright (C) 2014 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 sqlite3 include file and library +# +# SQLITE3_FOUND - system has sqlite3 +# SQLITE3_INCLUDE_DIRS - the sqlite3 include directory +# SQLITE3_LIBRARIES - The libraries needed to use sqlite3 + +set(_SQLITE3_ROOT_PATHS + ${CMAKE_INSTALL_PREFIX} +) + +find_path(SQLITE3_INCLUDE_DIRS + NAMES sqlite3.h + HINTS _SQLITE3_ROOT_PATHS + PATH_SUFFIXES include +) + +if(SQLITE3_INCLUDE_DIRS) + set(HAVE_SQLITE3_H 1) +endif() + +find_library(SQLITE3_LIBRARIES + NAMES sqlite3 + HINTS ${_SQLITE3_ROOT_PATHS} + PATH_SUFFIXES bin lib +) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Sqlite3 + DEFAULT_MSG + SQLITE3_INCLUDE_DIRS SQLITE3_LIBRARIES HAVE_SQLITE3_H +) + +mark_as_advanced(SQLITE3_INCLUDE_DIRS SQLITE3_LIBRARIES HAVE_SQLITE3_H) diff --git a/cmake/FindXML2.cmake b/cmake/FindXML2.cmake new file mode 100644 index 000000000..9d0eebe14 --- /dev/null +++ b/cmake/FindXML2.cmake @@ -0,0 +1,55 @@ +############################################################################ +# FindXML2.txt +# 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 libxml2 include file and library +# +# XML2_FOUND - system has libxml2 +# XML2_INCLUDE_DIRS - the libxml2 include directory +# XML2_LIBRARIES - The libraries needed to use libxml2 + +set(_XML2_ROOT_PATHS + ${CMAKE_INSTALL_PREFIX} +) + +find_path(XML2_INCLUDE_DIRS + NAMES libxml/xmlreader.h + HINTS _XML2_ROOT_PATHS + PATH_SUFFIXES include/libxml2 +) + +if(XML2_INCLUDE_DIRS) + set(HAVE_LIBXML_XMLREADER_H 1) +endif() + +find_library(XML2_LIBRARIES + NAMES xml2 + HINTS ${_XML2_ROOT_PATHS} + PATH_SUFFIXES bin lib +) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(XML2 + DEFAULT_MSG + XML2_INCLUDE_DIRS XML2_LIBRARIES +) + +mark_as_advanced(XML2_INCLUDE_DIRS XML2_LIBRARIES) diff --git a/cmake/LinphoneConfig.cmake.in b/cmake/LinphoneConfig.cmake.in new file mode 100644 index 000000000..d7aa6cc22 --- /dev/null +++ b/cmake/LinphoneConfig.cmake.in @@ -0,0 +1,51 @@ +############################################################################ +# LinphoneConfig.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. +# +############################################################################ +# +# Config file for the belle-sip package. +# It defines the following variables: +# +# LINPHONE_FOUND - system has linphone +# LINPHONE_INCLUDE_DIRS - the linphone include directory +# LINPHONE_LIBRARIES - The libraries needed to use linphone +# LINPHONE_CPPFLAGS - The compilation flags needed to use linphone +# LINPHONE_LDFLAGS - The linking flags needed to use linphone + +include("${CMAKE_CURRENT_LIST_DIR}/LinphoneTargets.cmake") +find_package(Mediastreamer2 REQUIRED) +find_package(BelleSIP REQUIRED) +if(@ENABLE_TUNNEL@) + find_package(Tunnel) +endif() + +get_filename_component(LINPHONE_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) +set(LINPHONE_INCLUDE_DIRS "${LINPHONE_CMAKE_DIR}/../../../include") +set(LINPHONE_LIBRARIES BelledonneCommunications::linphone) +set(LINPHONE_LDFLAGS @LINK_FLAGS@) +list(APPEND LINPHONE_INCLUDE_DIRS ${MEDIASTREAMER2_INCLUDE_DIRS} ${BELLESIP_INCLUDE_DIRS}) +list(APPEND LINPHONE_LIBRARIES ${MEDIASTREAMER2_LIBRARIES} ${BELLESIP_LIBRARIES}) +set(LINPHONE_CPPFLAGS "${MEDIASTREAMER2_CPPFLAGS}") +set(LINPHONE_LDFLAGS "${MEDIASTREAMER2_LDFLAGS} ${BELLESIP_LDFLAGS}") +if(TUNNEL_FOUND) + list(APPEND LINPHONE_INCLUDE_DIRS ${TUNNEL_INCLUDE_DIRS}) + list(APPEND LINPHONE_LIBRARIES ${TUNNEL_LIBRARIES}) +endif() +set(LINPHONE_FOUND 1) diff --git a/config.h.cmake b/config.h.cmake index 0d442cb36..cd6aa1cc3 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -29,6 +29,7 @@ #define LINPHONE_ALL_LANGS "${LINPHONE_ALL_LANGS}" #define LINPHONE_PLUGINS_DIR "${LINPHONE_PLUGINS_DIR}" +#define LINPHONE_CONFIG_DIR "${LINPHONE_CONFIG_DIR}" #define GETTEXT_PACKAGE "${GETTEXT_PACKAGE}" diff --git a/configure.ac b/configure.ac index 1e048a6b9..554e310c0 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ dnl Process this file with autoconf to produce a configure script. -AC_INIT([linphone],[3.7.0-linphone-daemon],[linphone-developers@nongnu.org]) +AC_INIT([linphone],[3.8.0-linphone-daemon],[linphone-developers@nongnu.org]) AC_CANONICAL_SYSTEM AC_CONFIG_SRCDIR([coreapi/linphonecore.c]) @@ -30,7 +30,7 @@ AC_SUBST(LINPHONE_VERSION) AC_MSG_NOTICE([$PACKAGE_NAME-$PACKAGE_VERSION A full featured audio/video sip phone.]) AC_MSG_NOTICE([licensed under the terms of the General Public License (GPL)]) -AM_INIT_AUTOMAKE([1.9 tar-pax]) +AM_INIT_AUTOMAKE([1.9 tar-pax subdir-objects]) AC_SUBST([LIBTOOL_DEPS]) m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],) AC_SUBST([docdir], [${datadir}/doc]) @@ -71,7 +71,7 @@ case $target in mingw_found=yes AC_CHECK_TOOL(WINDRES, windres) ;; - armv6-apple-darwin|armv7-apple-darwin|i386-apple-darwin|armv7s-apple-darwin) + armv6-apple-darwin|armv7-apple-darwin|i386-apple-darwin|armv7s-apple-darwin|aarch64-apple-darwin|*-apple-darwin.ios) CFLAGS="$CFLAGS -DTARGET_OS_IPHONE=1 " LIBS="$LIBS -framework CoreFoundation -framework AudioToolbox -framework CoreAudio -framework Foundation -framework QuartzCore -framework OpenGLES -framework UIKit -framework AVFoundation" ios_found=yes @@ -377,15 +377,6 @@ if test "$gtk_ui" = "true" ; then fi fi -case "$target" in - #macosx 64 bits - x86_64-apple-darwin*) - LIBS="$LIBS -mmacosx-version-min=10.6" - CXXFLAGS="$CXXFLAGS -mmacosx-version-min=10.6" - CFLAGS="$CFLAGS -mmacosx-version-min=10.6" - ;; -esac - dnl os-specific problems not handled by existing macros. case "$host_os" in *freebsd*) @@ -769,7 +760,7 @@ AC_ARG_ENABLE(external-ortp, ) if test "$external_ortp" = 'true'; then - PKG_CHECK_MODULES([ORTP], [ortp >= 0.23.0]) + PKG_CHECK_MODULES([ORTP], [ortp >= 0.24.0]) ORTP_VERSION=`$PKG_CONFIG --modversion ortp` else AC_CONFIG_SUBDIRS( oRTP ) @@ -798,7 +789,7 @@ AC_ARG_ENABLE([external-mediastreamer], AS_CASE($enable_external_mediastreamer, [yes], - [PKG_CHECK_MODULES([MEDIASTREAMER], [mediastreamer >= 2.10.0]) + [PKG_CHECK_MODULES([MEDIASTREAMER], [mediastreamer >= 2.11.0]) MS2_VERSION=`$PKG_CONFIG --modversion mediastreamer`], [no], [AC_CONFIG_SUBDIRS( mediastreamer2 ) @@ -869,7 +860,7 @@ fi AM_CONDITIONAL(BUILD_MSG_STORAGE, test x$enable_msg_storage = xtrue) -PKG_CHECK_MODULES(BELLESIP, [belle-sip >= 1.3.1]) +PKG_CHECK_MODULES(BELLESIP, [belle-sip >= 1.4.0]) SIPSTACK_CFLAGS="$BELLESIP_CFLAGS" SIPSTACK_LIBS="$BELLESIP_LIBS" diff --git a/coreapi/CMakeLists.txt b/coreapi/CMakeLists.txt index 4c35d14a7..0f9d453a4 100644 --- a/coreapi/CMakeLists.txt +++ b/coreapi/CMakeLists.txt @@ -25,6 +25,10 @@ if(MSVC) find_library(LIBMINGWEX NAMES mingwex) endif() +if(NOT WIN32) + find_package(Iconv) +endif() + set(SOURCE_FILES address.c @@ -59,6 +63,7 @@ set(SOURCE_FILES friend.c info.c ldap/ldapprovider.c + lime.c linphonecall.c linphonecore.c linphonecore.h @@ -87,6 +92,7 @@ set(SOURCE_FILES xml2lpc.c xml2lpc.h xml.c + vtables.c ) if(ENABLE_TUNNEL) list(APPEND SOURCE_FILES @@ -118,12 +124,15 @@ set(LIBS ${LIBGCC} ${LIBMINGWEX} ${BELLESIP_LIBRARIES} - ${MS2_LIBRARIES} + ${MEDIASTREAMER2_LIBRARIES} ${XML2_LIBRARIES} ) if(SQLITE3_FOUND) list(APPEND LIBS ${SQLITE3_LIBRARIES}) endif() +if(ICONV_FOUND) + list(APPEND LIBS ${ICONV_LIBRARIES}) +endif() if(ENABLE_TUNNEL) list(APPEND LIBS ${TUNNEL_LIBRARIES}) endif() @@ -150,8 +159,11 @@ else() endif() endif() endif() +if(ICONV_FOUND) + target_include_directories(linphone PUBLIC ${ICONV_INCLUDE_DIRS}) +endif() -install(TARGETS linphone +install(TARGETS linphone EXPORT LinphoneTargets RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib diff --git a/coreapi/Makefile.am b/coreapi/Makefile.am index 116530afa..df58a716b 100644 --- a/coreapi/Makefile.am +++ b/coreapi/Makefile.am @@ -9,7 +9,7 @@ GITREVISION=`cd $(top_srcdir) && git rev-parse HEAD` ## We can't only depend on the presence of the .git/ directory anymore, ## because of gits submodule handling. ## We now simply issue a git log on configure.ac and if the output is empty (error or file not tracked), then we are not in git. -GITLOG=$(shell git log -1 --pretty=format:%H $(top_srcdir)/configure.ac) +GITLOG=`cd $(top_srcdir) && git log -1 --pretty=format:%H configure.ac` ECHO=/bin/echo @@ -65,6 +65,7 @@ liblinphone_la_SOURCES=\ linphonecore_utils.h \ localplayer.c \ lpc2xml.c \ + lime.c lime.h\ lpconfig.c lpconfig.h \ lsd.c \ message_storage.c \ @@ -81,6 +82,7 @@ liblinphone_la_SOURCES=\ sipsetup.c sipsetup.h \ xml2lpc.c \ xml.c \ + vtables.c \ $(GITVERSION_FILE) if BUILD_UPNP diff --git a/coreapi/bellesip_sal/sal_op_message.c b/coreapi/bellesip_sal/sal_op_message.c index 017845833..921f8c0a6 100644 --- a/coreapi/bellesip_sal/sal_op_message.c +++ b/coreapi/bellesip_sal/sal_op_message.c @@ -18,6 +18,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "sal_impl.h" +#include "linphonecore.h" +#include "private.h" +#include "lime.h" +#include + static void process_error( SalOp* op) { if (op->dir == SalOpDirOutgoing) { op->base.root->callbacks.text_delivery_update(op, SalTextDeliveryFailed); @@ -56,14 +61,22 @@ static void process_response_event(void *op_base, const belle_sip_response_event } static bool_t is_rcs_filetransfer(belle_sip_header_content_type_t* content_type) { - return strcmp("application",belle_sip_header_content_type_get_type(content_type))==0 - && strcmp("vnd.gsma.rcs-ft-http+xml",belle_sip_header_content_type_get_subtype(content_type))==0; + return (strcmp("application",belle_sip_header_content_type_get_type(content_type))==0) + && ((strcmp("vnd.gsma.rcs-ft-http+xml",belle_sip_header_content_type_get_subtype(content_type))==0) || (strcmp("cipher.vnd.gsma.rcs-ft-http+xml",belle_sip_header_content_type_get_subtype(content_type))==0)); } static bool_t is_plain_text(belle_sip_header_content_type_t* content_type) { return strcmp("text",belle_sip_header_content_type_get_type(content_type))==0 && strcmp("plain",belle_sip_header_content_type_get_subtype(content_type))==0; } + +static bool_t is_cipher_xml(belle_sip_header_content_type_t* content_type) { + return (strcmp("xml",belle_sip_header_content_type_get_type(content_type))==0 + && strcmp("cipher",belle_sip_header_content_type_get_subtype(content_type))==0) + + || (strcmp("application",belle_sip_header_content_type_get_type(content_type))==0 + && strcmp("cipher.vnd.gsma.rcs-ft-http+xml",belle_sip_header_content_type_get_subtype(content_type))==0); +} static bool_t is_external_body(belle_sip_header_content_type_t* content_type) { return strcmp("message",belle_sip_header_content_type_get_type(content_type))==0 && strcmp("external-body",belle_sip_header_content_type_get_subtype(content_type))==0; @@ -74,7 +87,7 @@ static bool_t is_im_iscomposing(belle_sip_header_content_type_t* content_type) { } static void add_message_accept(belle_sip_message_t *msg){ - belle_sip_message_add_header(msg,belle_sip_header_create("Accept","text/plain, message/external-body, application/im-iscomposing+xml, application/vnd.gsma.rcs-ft-http+xml")); + belle_sip_message_add_header(msg,belle_sip_header_create("Accept","text/plain, message/external-body, application/im-iscomposing+xml, xml/cipher, application/vnd.gsma.rcs-ft-http+xml, application/cipher.vnd.gsma.rcs-ft-http+xml")); } void sal_process_incoming_message(SalOp *op,const belle_sip_request_event_t *event){ @@ -84,19 +97,74 @@ void sal_process_incoming_message(SalOp *op,const belle_sip_request_event_t *eve belle_sip_header_from_t* from_header; belle_sip_header_content_type_t* content_type; belle_sip_response_t* resp; + int errcode=500; belle_sip_header_call_id_t* call_id = belle_sip_message_get_header_by_type(req,belle_sip_header_call_id_t); belle_sip_header_cseq_t* cseq = belle_sip_message_get_header_by_type(req,belle_sip_header_cseq_t); belle_sip_header_date_t *date=belle_sip_message_get_header_by_type(req,belle_sip_header_date_t); char* from; bool_t plain_text=FALSE; bool_t external_body=FALSE; + bool_t cipher_xml=FALSE; bool_t rcs_filetransfer=FALSE; + uint8_t *decryptedMessage = NULL; from_header=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_from_t); content_type=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_content_type_t); + /* check if we have a xml/cipher message to be decrypted */ + if (content_type && (cipher_xml=is_cipher_xml(content_type))) { + /* access the zrtp cache to get keys needed to decipher the message */ + LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); + FILE *CACHEFD = fopen(lc->zrtp_secrets_cache, "rb+"); + if (CACHEFD == NULL) { + ms_warning("Unable to access ZRTP ZID cache to decrypt message"); + goto error; + } else { + size_t cacheSize; + char *cacheString; + int retval; + xmlDocPtr cacheXml; + + cacheString=ms_load_file_content(CACHEFD, &cacheSize); + if (!cacheString){ + ms_warning("Unable to load content of ZRTP ZID cache to decrypt message"); + goto error; + } + cacheString[cacheSize] = '\0'; + cacheSize += 1; + fclose(CACHEFD); + cacheXml = xmlParseDoc((xmlChar*)cacheString); + ms_free(cacheString); + retval = lime_decryptMultipartMessage(cacheXml, (uint8_t *)belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)), &decryptedMessage); + if (retval != 0) { + ms_warning("Unable to decrypt message, reason : %s - op [%p]", lime_error_code_to_string(retval), op); + free(decryptedMessage); + xmlFreeDoc(cacheXml); + errcode = 488; + goto error; + } else { + /* dump updated cache to a string */ + xmlChar *xmlStringOutput; + int xmlStringLength; + xmlDocDumpFormatMemoryEnc(cacheXml, &xmlStringOutput, &xmlStringLength, "UTF-8", 0); + /* write it to the cache file */ + CACHEFD = fopen(lc->zrtp_secrets_cache, "wb+"); + if (fwrite(xmlStringOutput, 1, xmlStringLength, CACHEFD)<=0){ + ms_warning("Fail to write cache"); + } + xmlFree(xmlStringOutput); + fclose(CACHEFD); + } + + xmlFreeDoc(cacheXml); + } + + } + + rcs_filetransfer=is_rcs_filetransfer(content_type); if (content_type && ((plain_text=is_plain_text(content_type)) || (external_body=is_external_body(content_type)) - || (rcs_filetransfer=is_rcs_filetransfer(content_type)))) { + || (decryptedMessage!=NULL) + || rcs_filetransfer)) { SalMessage salmsg; char message_id[256]={0}; @@ -111,7 +179,12 @@ void sal_process_incoming_message(SalOp *op,const belle_sip_request_event_t *eve ,belle_sip_header_call_id_get_call_id(call_id) ,belle_sip_header_cseq_get_seq_number(cseq)); salmsg.from=from; - salmsg.text=(plain_text||rcs_filetransfer)?belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)):NULL; + /* if we just deciphered a message, use the deciphered part(which can be a rcs xml body pointing to the file to retreive from server)*/ + if (cipher_xml) { + salmsg.text = (char *)decryptedMessage; + } else { /* message body wasn't ciphered */ + salmsg.text=(plain_text||rcs_filetransfer)?belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)):NULL; + } salmsg.url=NULL; salmsg.content_type = NULL; if (rcs_filetransfer) { /* if we have a rcs file transfer, set the type, message body (stored in salmsg.text) contains all needed information to retrieve the file */ @@ -125,6 +198,8 @@ void sal_process_incoming_message(SalOp *op,const belle_sip_request_event_t *eve salmsg.message_id=message_id; salmsg.time=date ? belle_sip_header_date_get_time(date) : time(NULL); op->base.root->callbacks.text_received(op,&salmsg); + + free(decryptedMessage); belle_sip_object_unref(address); belle_sip_free(from); if (salmsg.url) ms_free((char*)salmsg.url); @@ -145,8 +220,14 @@ void sal_process_incoming_message(SalOp *op,const belle_sip_request_event_t *eve resp = belle_sip_response_create_from_request(req,415); add_message_accept((belle_sip_message_t*)resp); belle_sip_server_transaction_send_response(server_transaction,resp); + sal_op_release(op); return; } + return; +error: + resp = belle_sip_response_create_from_request(req, errcode); + belle_sip_server_transaction_send_response(server_transaction,resp); + sal_op_release(op); } static void process_request_event(void *op_base, const belle_sip_request_event_t *event) { @@ -154,11 +235,13 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t sal_process_incoming_message(op,event); } -int sal_message_send(SalOp *op, const char *from, const char *to, const char* content_type, const char *msg){ +int sal_message_send(SalOp *op, const char *from, const char *to, const char* content_type, const char *msg, const char *peer_uri){ belle_sip_request_t* req; char content_type_raw[256]; size_t content_length = msg?strlen(msg):0; time_t curtime=time(NULL); + uint8_t *multipartEncryptedMessage = NULL; + int retval; if (op->dialog){ /*for SIP MESSAGE that are sent in call's dialog*/ @@ -179,13 +262,70 @@ int sal_message_send(SalOp *op, const char *from, const char *to, const char* co belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(sal_op_create_contact(op))); } } + + /* shall we try to encrypt the message?*/ + if ((strcmp(content_type, "xml/cipher") == 0) || ((strcmp(content_type, "application/cipher.vnd.gsma.rcs-ft-http+xml") == 0))) { + /* access the zrtp cache to get keys needed to cipher the message */ + LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); + FILE *CACHEFD = fopen(lc->zrtp_secrets_cache, "rb+"); + if (CACHEFD == NULL) { + ms_warning("Unable to access ZRTP ZID cache to encrypt message"); + /*probably not a good idea to do this:*/ + sal_error_info_set(&op->error_info, SalReasonNotAcceptable, 488, "Unable to encrypt IM", NULL); + op->base.root->callbacks.text_delivery_update(op,SalTextDeliveryFailed); + return -1; + } else { + size_t cacheSize; + char *cacheString; + xmlDocPtr cacheXml; + int retval; + + cacheString=ms_load_file_content(CACHEFD, &cacheSize); + if (!cacheString){ + ms_warning("Unable to load content of ZRTP ZID cache to encrypt message"); + return -1; + } + cacheString[cacheSize] = '\0'; + cacheSize += 1; + fclose(CACHEFD); + cacheXml = xmlParseDoc((xmlChar*)cacheString); + ms_free(cacheString); + retval = lime_createMultipartMessage(cacheXml, (uint8_t *)msg, (uint8_t *)peer_uri, &multipartEncryptedMessage); + if (retval != 0) { + ms_warning("Unable to encrypt message for %s : %s - op [%p]", peer_uri, lime_error_code_to_string(retval), op); + xmlFreeDoc(cacheXml); + free(multipartEncryptedMessage); + /*probably not a good idea to do this:*/ + sal_error_info_set(&op->error_info, SalReasonNotAcceptable, 488, "Unable to encrypt IM", NULL); + op->base.root->callbacks.text_delivery_update(op,SalTextDeliveryFailed); + return -1; + } else { + /* dump updated cache to a string */ + xmlChar *xmlStringOutput; + int xmlStringLength; + xmlDocDumpFormatMemoryEnc(cacheXml, &xmlStringOutput, &xmlStringLength, "UTF-8", 0); + /* write it to the cache file */ + CACHEFD = fopen(lc->zrtp_secrets_cache, "wb+"); + if (fwrite(xmlStringOutput, 1, xmlStringLength, CACHEFD)<=0){ + ms_warning("Unable to write zid cache"); + } + xmlFree(xmlStringOutput); + fclose(CACHEFD); + content_length = strlen((const char *)multipartEncryptedMessage); + } + xmlFreeDoc(cacheXml); + } + } + snprintf(content_type_raw,sizeof(content_type_raw),BELLE_SIP_CONTENT_TYPE ": %s",content_type); belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_content_type_parse(content_type_raw))); belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_content_length_create(content_length))); belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_date_create_from_time(&curtime))); - belle_sip_message_set_body(BELLE_SIP_MESSAGE(req),msg,content_length); - return sal_op_send_request(op,req); + belle_sip_message_set_body(BELLE_SIP_MESSAGE(req),(multipartEncryptedMessage==NULL)?msg:(const char *)multipartEncryptedMessage,content_length); + retval = sal_op_send_request(op,req); + free(multipartEncryptedMessage); + return retval; } int sal_message_reply(SalOp *op, SalReason reason){ @@ -200,7 +340,7 @@ int sal_message_reply(SalOp *op, SalReason reason){ } int sal_text_send(SalOp *op, const char *from, const char *to, const char *msg) { - return sal_message_send(op,from,to,"text/plain",msg); + return sal_message_send(op,from,to,"text/plain",msg, NULL); } static belle_sip_listener_callbacks_t op_message_callbacks={0}; diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index fa29096b7..df6170c77 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -147,8 +147,10 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia /* we already started media: check if we really need to restart it*/ if (oldmd){ int md_changed = media_parameters_changed(call, oldmd, new_md); - if ((md_changed & SAL_MEDIA_DESCRIPTION_CODEC_CHANGED) || call->playing_ringbacktone) { + if ((md_changed & SAL_MEDIA_DESCRIPTION_CODEC_CHANGED)){ ms_message("Media descriptions are different, need to restart the streams."); + } else if ( call->playing_ringbacktone) { + ms_message("Playing ringback tone, will restart the streams."); } else { if (md_changed == SAL_MEDIA_DESCRIPTION_UNCHANGED) { if (call->all_muted){ @@ -391,6 +393,19 @@ static void try_early_media_forking(LinphoneCall *call, SalMediaDescription *md) } } +static void start_remote_ring(LinphoneCore *lc, LinphoneCall *call) { + if (lc->sound_conf.play_sndcard!=NULL){ + MSSndCard *ringcard=lc->sound_conf.lsd_card ? lc->sound_conf.lsd_card : lc->sound_conf.play_sndcard; + if (call->localdesc->streams[0].max_rate>0) ms_snd_card_set_preferred_sample_rate(ringcard, call->localdesc->streams[0].max_rate); + /*we release sound before playing ringback tone*/ + if (call->audiostream) + audio_stream_unprepare_sound(call->audiostream); + if( lc->sound_conf.remote_ring ){ + lc->ringstream=ring_start(lc->sound_conf.remote_ring,2000,ringcard); + } + } +} + static void call_ringing(SalOp *h){ LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(h)); LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(h); @@ -411,16 +426,7 @@ static void call_ringing(SalOp *h){ return; } if (lc->ringstream!=NULL) return;/*already ringing !*/ - if (lc->sound_conf.play_sndcard!=NULL){ - MSSndCard *ringcard=lc->sound_conf.lsd_card ? lc->sound_conf.lsd_card : lc->sound_conf.play_sndcard; - if (call->localdesc->streams[0].max_rate>0) ms_snd_card_set_preferred_sample_rate(ringcard, call->localdesc->streams[0].max_rate); - /*we release sound before playing ringback tone*/ - if (call->audiostream) - audio_stream_unprepare_sound(call->audiostream); - if( lc->sound_conf.remote_ring ){ - lc->ringstream=ring_start(lc->sound_conf.remote_ring,2000,ringcard); - } - } + start_remote_ring(lc, call); ms_message("Remote ringing..."); linphone_core_notify_display_status(lc,_("Remote ringing...")); linphone_call_set_state(call,LinphoneCallOutgoingRinging,"Remote ringing"); @@ -444,6 +450,10 @@ static void call_ringing(SalOp *h){ linphone_core_stop_ringing(lc); ms_message("Doing early media..."); linphone_core_update_streams(lc,call,md); + if ((linphone_call_params_get_audio_direction(linphone_call_get_current_params(call)) == LinphoneMediaDirectionInactive) && call->audiostream) { + if (lc->ringstream != NULL) return; /* Already ringing! */ + start_remote_ring(lc, call); + } } } @@ -455,23 +465,24 @@ static void call_ringing(SalOp *h){ static void call_accepted(SalOp *op){ LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op); - SalMediaDescription *md; + SalMediaDescription *md, *rmd; bool_t update_state=TRUE; if (call==NULL){ ms_warning("No call to accept."); return ; } + rmd=sal_call_get_remote_media_description(op); /*set privacy*/ call->current_params->privacy=(LinphonePrivacyMask)sal_op_get_privacy(call->op); /* Handle remote ICE attributes if any. */ - if (call->ice_session != NULL) { - linphone_call_update_ice_from_remote_media_description(call, sal_call_get_remote_media_description(op)); + if (call->ice_session != NULL && rmd) { + linphone_call_update_ice_from_remote_media_description(call, rmd); } #ifdef BUILD_UPNP - if (call->upnp_session != NULL) { - linphone_core_update_upnp_from_remote_media_description(call, sal_call_get_remote_media_description(op)); + if (call->upnp_session != NULL && rmd) { + linphone_core_update_upnp_from_remote_media_description(call, rmd); } #endif //BUILD_UPNP diff --git a/coreapi/chat.c b/coreapi/chat.c index 269af03e6..c750c4f69 100644 --- a/coreapi/chat.c +++ b/coreapi/chat.c @@ -26,14 +26,18 @@ #include "private.h" #include "lpconfig.h" #include "belle-sip/belle-sip.h" +#include "lime.h" +#include "ortp/b64.h" #include +#include #include #define COMPOSING_DEFAULT_IDLE_TIMEOUT 15 #define COMPOSING_DEFAULT_REFRESH_TIMEOUT 60 #define COMPOSING_DEFAULT_REMOTE_REFRESH_TIMEOUT 120 +#define FILE_TRANSFER_KEY_SIZE 32 static LinphoneChatMessageCbs * linphone_chat_message_cbs_new(void) { return belle_sip_object_new(LinphoneChatMessageCbs); @@ -176,6 +180,7 @@ static void process_io_error_upload(void *data, const belle_sip_io_error_event_t if (msg->cb) { msg->cb(msg, LinphoneChatMessageStateNotDelivered, msg->cb_ud); } + if (linphone_chat_message_cbs_get_msg_state_changed(msg->callbacks)) { linphone_chat_message_cbs_get_msg_state_changed(msg->callbacks)(msg, LinphoneChatMessageStateNotDelivered); } @@ -244,18 +249,49 @@ static int linphone_chat_message_file_transfer_on_send_body(belle_sip_user_body_ /* if we've not reach the end of file yet, ask for more data*/ if (offsetfile_transfer_information)){ - /* get data from call back */ - if (linphone_chat_message_cbs_get_file_transfer_send(chatMsg->callbacks)) { - LinphoneBuffer *lb = linphone_chat_message_cbs_get_file_transfer_send(chatMsg->callbacks)(chatMsg, chatMsg->file_transfer_information, offset, *size); - if (lb == NULL) *size = 0; - else { - *size = linphone_buffer_get_size(lb); - memcpy(buffer, linphone_buffer_get_content(lb), *size); - linphone_buffer_unref(lb); + + if (linphone_content_get_key(chatMsg->file_transfer_information) != NULL) { /* if we have a key to cipher the message, use it! */ + char *plainBuffer; + /* get data from callback to a plainBuffer */ + /* if this chunk is not the last one, the lenght must be a multiple of block cipher size(16 bytes)*/ + if (offset+*size < linphone_content_get_size(chatMsg->file_transfer_information)) { + *size -=(*size%16); + } + plainBuffer = (char *)malloc(*size); + if (linphone_chat_message_cbs_get_file_transfer_send(chatMsg->callbacks)) { + LinphoneBuffer *lb = linphone_chat_message_cbs_get_file_transfer_send(chatMsg->callbacks)(chatMsg, chatMsg->file_transfer_information, offset, *size); + if (lb == NULL) *size = 0; + else { + *size = linphone_buffer_get_size(lb); + memcpy(plainBuffer, linphone_buffer_get_content(lb), *size); + linphone_buffer_unref(lb); + } + } else { + /* Legacy */ + linphone_core_notify_file_transfer_send(lc, chatMsg, chatMsg->file_transfer_information, plainBuffer, size); + } + + lime_encryptFile(linphone_content_get_cryptoContext_address(chatMsg->file_transfer_information), (unsigned char *)linphone_content_get_key(chatMsg->file_transfer_information), *size, plainBuffer, (char*)buffer); + free(plainBuffer); + /* check if we reach the end of file */ + if (offset+*size >= linphone_content_get_size(chatMsg->file_transfer_information)) { + /* conclude file ciphering by calling it context with a zero size */ + lime_encryptFile(linphone_content_get_cryptoContext_address(chatMsg->file_transfer_information), NULL, 0, NULL, NULL); } } else { - /* Legacy */ - linphone_core_notify_file_transfer_send(lc, chatMsg, chatMsg->file_transfer_information, buf, size); + /* get data from call back */ + if (linphone_chat_message_cbs_get_file_transfer_send(chatMsg->callbacks)) { + LinphoneBuffer *lb = linphone_chat_message_cbs_get_file_transfer_send(chatMsg->callbacks)(chatMsg, chatMsg->file_transfer_information, offset, *size); + if (lb == NULL) *size = 0; + else { + *size = linphone_buffer_get_size(lb); + memcpy(buffer, linphone_buffer_get_content(lb), *size); + linphone_buffer_unref(lb); + } + } else { + /* Legacy */ + linphone_core_notify_file_transfer_send(lc, chatMsg, chatMsg->file_transfer_information, buf, size); + } } } @@ -286,8 +322,19 @@ static void linphone_chat_message_process_response_from_post_file(void *data, co char *first_part_header; belle_sip_body_handler_t *first_part_bh; - /* temporary storage for the Content-disposition header value */ - first_part_header = belle_sip_strdup_printf("form-data; name=\"File\"; filename=\"%s\"", linphone_content_get_name(msg->file_transfer_information)); + /* shall we encrypt the file */ + if (linphone_core_lime_enabled(msg->chat_room->lc)) { + char keyBuffer[FILE_TRANSFER_KEY_SIZE]; /* temporary storage of generated key: 192 bits of key + 64 bits of initial vector */ + /* generate a random 192 bits key + 64 bits of initial vector and store it into the file_transfer_information->key field of the message */ + sal_get_random_bytes((unsigned char *)keyBuffer, FILE_TRANSFER_KEY_SIZE); + linphone_content_set_key(msg->file_transfer_information, keyBuffer, FILE_TRANSFER_KEY_SIZE); /* key is duplicated in the content private structure */ + /* temporary storage for the Content-disposition header value : use a generic filename to not leak it + * Actual filename stored in msg->file_transfer_information->name will be set in encrypted message sended to the */ + first_part_header = belle_sip_strdup_printf("form-data; name=\"File\"; filename=\"filename.txt\""); + } else { + /* temporary storage for the Content-disposition header value */ + first_part_header = belle_sip_strdup_printf("form-data; name=\"File\"; filename=\"%s\"", linphone_content_get_name(msg->file_transfer_information)); + } /* create a user body handler to take care of the file and add the content disposition and content-type headers */ if (msg->file_transfer_filepath != NULL) { @@ -324,11 +371,65 @@ static void linphone_chat_message_process_response_from_post_file(void *data, co l=belle_http_request_listener_create_from_callbacks(&cbs,msg); belle_http_provider_send_request(msg->chat_room->lc->http_provider,msg->http_request,l); } - if (code == 200 ) { /* file has been uploaded correctly, get server reply and send it */ + + if (code == 200 ) { /* file has been uplaoded correctly, get server reply and send it */ const char *body = belle_sip_message_get_body((belle_sip_message_t *)event->response); belle_sip_object_unref(msg->http_request); msg->http_request = NULL; - msg->message = ms_strdup(body); + + /* if we have an encryption key for the file, we must insert it into the message and restore the correct filename */ + if (linphone_content_get_key(msg->file_transfer_information) != NULL) { + /* parse the message body */ + xmlDocPtr xmlMessageBody = xmlParseDoc((const xmlChar *)body); + + xmlNodePtr cur = xmlDocGetRootElement(xmlMessageBody); + if (cur != NULL) { + cur = cur->xmlChildrenNode; + while (cur!=NULL) { + if (!xmlStrcmp(cur->name, (const xmlChar *)"file-info")) { /* we found a file info node, check it has a type="file" attribute */ + xmlChar *typeAttribute = xmlGetProp(cur, (const xmlChar *)"type"); + if(!xmlStrcmp(typeAttribute, (const xmlChar *)"file")) { /* this is the node we are looking for : add a file-key children node */ + xmlNodePtr fileInfoNodeChildren = cur->xmlChildrenNode; /* need to parse the children node to update the file-name one */ + /* convert key to base64 */ + int b64Size = b64_encode(NULL, FILE_TRANSFER_KEY_SIZE, NULL, 0); + char *keyb64 = (char *)malloc(b64Size+1); + int xmlStringLength; + + b64Size = b64_encode(linphone_content_get_key(msg->file_transfer_information), FILE_TRANSFER_KEY_SIZE, keyb64, b64Size); + keyb64[b64Size] = '\0'; /* libxml need a null terminated string */ + + /* add the node containing the key to the file-info node */ + xmlNewTextChild(cur, NULL, (const xmlChar *)"file-key", (const xmlChar *)keyb64); + xmlFree(typeAttribute); + free(keyb64); + + /* look for the file-name node and update its content */ + while (fileInfoNodeChildren!=NULL) { + if (!xmlStrcmp(fileInfoNodeChildren->name, (const xmlChar *)"file-name")) { /* we found a the file-name node, update its content with the real filename */ + /* update node content */ + xmlNodeSetContent(fileInfoNodeChildren, (const xmlChar *)(linphone_content_get_name(msg->file_transfer_information))); + break; + } + fileInfoNodeChildren = fileInfoNodeChildren->next; + } + + + /* dump the xml into msg->message */ + xmlDocDumpFormatMemoryEnc(xmlMessageBody, (xmlChar **)&msg->message, &xmlStringLength, "UTF-8", 0); + + break; + } + xmlFree(typeAttribute); + } + cur = cur->next; + } + } + xmlFreeDoc(xmlMessageBody); + + } else { /* no encryption key, transfer in plain, just copy the message sent by server */ + msg->message = ms_strdup(body); + } + msg->content_type = ms_strdup("application/vnd.gsma.rcs-ft-http+xml"); if (msg->cb) { msg->cb(msg, LinphoneChatMessageStateFileTransferDone, msg->cb_ud); @@ -339,7 +440,6 @@ static void linphone_chat_message_process_response_from_post_file(void *data, co _linphone_chat_room_send_message(msg->chat_room, msg); } } - } @@ -632,20 +732,29 @@ static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatM linphone_configure_op(cr->lc,op,cr->peer_url,msg->custom_headers,lp_config_get_int(cr->lc->config,"sip","chat_msg_with_contact",0)); sal_op_set_user_pointer(op, msg); /*if out of call, directly store msg*/ } + + if (msg->external_body_url) { content_type=ms_strdup_printf("message/external-body; access-type=URL; URL=\"%s\"",msg->external_body_url); - sal_message_send(op,identity,cr->peer,content_type, NULL); + sal_message_send(op,identity,cr->peer,content_type, NULL, NULL); ms_free(content_type); - } else { /* the message is either text or have a file transfer using RCS recommendation */ - if (msg->content_type == NULL) { /* if no content type is specified, it is a text message */ - sal_text_send(op, identity, cr->peer,msg->message); + } else { + if (linphone_core_lime_enabled(cr->lc)) { /* shall we try to encrypt messages? */ + linphone_chat_message_ref(msg); /* ref the message or it may be destroyed by callback if the encryption failed */ + if ((msg->content_type != NULL) && (strcmp(msg->content_type, "application/vnd.gsma.rcs-ft-http+xml") == 0 )) { /* it's a file transfer, content type shall be set to application/cipher.vnd.gsma.rcs-ft-http+xml*/ + sal_message_send(op, identity, cr->peer, "application/cipher.vnd.gsma.rcs-ft-http+xml", msg->message, linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr))); + } else { + sal_message_send(op, identity, cr->peer, "xml/cipher", msg->message, linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr))); + } } else { - sal_message_send(op, identity, cr->peer, msg->content_type, msg->message); - // Remove the message to prevent the xml from the file uplaod to be stored in the database - ms_free(msg->message); - msg->message = NULL; + if (msg->content_type == NULL) { + sal_text_send(op, identity, cr->peer,msg->message); + } else { /* rcs file transfer */ + sal_message_send(op, identity, cr->peer, msg->content_type, msg->message, NULL); + } } } + msg->dir=LinphoneChatMessageOutgoing; msg->from=linphone_address_new(identity); msg->storage_id=linphone_chat_message_store(msg); @@ -752,6 +861,18 @@ void linphone_core_message_received(LinphoneCore *lc, SalOp *op, const SalMessag file_url = xmlGetProp(cur, (const xmlChar *)"url"); } + if (!xmlStrcmp(cur->name, (const xmlChar *)"file-key")) { /* there is a key in the message: file has been encrypted */ + /* convert the key from base 64 */ + xmlChar *keyb64 = xmlNodeListGetString(xmlMessageBody, cur->xmlChildrenNode, 1); + int keyLength = b64_decode((char *)keyb64, strlen((char *)keyb64), NULL, 0); + uint8_t *keyBuffer = (uint8_t *)malloc(keyLength); + /* decode the key into local key buffer */ + b64_decode((char *)keyb64, strlen((char *)keyb64), keyBuffer, keyLength); + linphone_content_set_key(msg->file_transfer_information, (char *)keyBuffer, keyLength); /* duplicate key value into the linphone content private structure */ + xmlFree(keyb64); + free(keyBuffer); + } + cur=cur->next; } xmlFree(typeAttribute); @@ -1069,7 +1190,7 @@ static void linphone_chat_room_send_is_composing_notification(LinphoneChatRoom * } content = linphone_chat_room_create_is_composing_xml(cr); if (content != NULL) { - sal_message_send(op, identity, cr->peer, "application/im-iscomposing+xml", content); + sal_message_send(op, identity, cr->peer, "application/im-iscomposing+xml", content, NULL); ms_free(content); } } @@ -1217,14 +1338,36 @@ static void on_recv_body(belle_sip_user_body_handler_t *bh, belle_sip_message_t LinphoneChatMessage* chatMsg=(LinphoneChatMessage *)data; LinphoneCore *lc = chatMsg->chat_room->lc; - if (linphone_chat_message_cbs_get_file_transfer_recv(chatMsg->callbacks)) { - LinphoneBuffer *lb = linphone_buffer_new_from_data(buffer, size); - linphone_chat_message_cbs_get_file_transfer_recv(chatMsg->callbacks)(chatMsg, chatMsg->file_transfer_information, lb); - linphone_buffer_unref(lb); - } else { - /* Legacy: call back given by application level */ - linphone_core_notify_file_transfer_recv(lc, chatMsg, chatMsg->file_transfer_information, (char *)buffer, size); + /* first call may be with a zero size, ignore it */ + if (size == 0) { + return; } + + if (linphone_content_get_key(chatMsg->file_transfer_information) != NULL) { /* we have a key, we must decrypt the file */ + /* get data from callback to a plainBuffer */ + char *plainBuffer = (char *)malloc(size); + lime_decryptFile(linphone_content_get_cryptoContext_address(chatMsg->file_transfer_information), (unsigned char *)linphone_content_get_key(chatMsg->file_transfer_information), size, plainBuffer, (char *)buffer); + if (linphone_chat_message_cbs_get_file_transfer_recv(chatMsg->callbacks)) { + LinphoneBuffer *lb = linphone_buffer_new_from_data((unsigned char *)plainBuffer, size); + linphone_chat_message_cbs_get_file_transfer_recv(chatMsg->callbacks)(chatMsg, chatMsg->file_transfer_information, lb); + linphone_buffer_unref(lb); + } else { + /* legacy: call back given by application level */ + linphone_core_notify_file_transfer_recv(lc, chatMsg, chatMsg->file_transfer_information, plainBuffer, size); + } + free(plainBuffer); + } else { /* regular file, no deciphering */ + if (linphone_chat_message_cbs_get_file_transfer_recv(chatMsg->callbacks)) { + LinphoneBuffer *lb = linphone_buffer_new_from_data(buffer, size); + linphone_chat_message_cbs_get_file_transfer_recv(chatMsg->callbacks)(chatMsg, chatMsg->file_transfer_information, lb); + linphone_buffer_unref(lb); + } else { + /* Legacy: call back given by application level */ + linphone_core_notify_file_transfer_recv(lc, chatMsg, chatMsg->file_transfer_information, (char *)buffer, size); + } + } + + return; } @@ -1293,6 +1436,10 @@ static void linphone_chat_process_response_from_get_file(void *data, const belle if (code==200) { LinphoneChatMessage* chatMsg=(LinphoneChatMessage *)data; LinphoneCore *lc = chatMsg->chat_room->lc; + /* if the file was encrypted, finish the decryption and free context */ + if (linphone_content_get_key(chatMsg->file_transfer_information) != NULL) { + lime_decryptFile(linphone_content_get_cryptoContext_address(chatMsg->file_transfer_information), NULL, 0, NULL, NULL); + } /* file downloaded succesfully, call again the callback with size at zero */ if (linphone_chat_message_cbs_get_file_transfer_recv(chatMsg->callbacks)) { LinphoneBuffer *lb = linphone_buffer_new(); @@ -1320,8 +1467,13 @@ void linphone_chat_message_download_file(LinphoneChatMessage *message) { belle_http_request_listener_t *l; belle_generic_uri_t *uri; const char *url=message->external_body_url; - char* ua = ms_strdup_printf("%s/%s", linphone_core_get_user_agent_name(), linphone_core_get_user_agent_version()); + char* ua; + if (url == NULL) { + ms_error("Cannot download file from chat message [%p] because url is NULL",message); + return; + } + ua = ms_strdup_printf("%s/%s", linphone_core_get_user_agent_name(), linphone_core_get_user_agent_version()); uri=belle_generic_uri_parse(url); message->http_request=belle_http_request_create("GET", diff --git a/coreapi/contactprovider.h b/coreapi/contactprovider.h index 83cbee1b7..d5c016562 100644 --- a/coreapi/contactprovider.h +++ b/coreapi/contactprovider.h @@ -22,7 +22,7 @@ void linphone_contact_search_init(LinphoneContactSearch* obj, const char* predic ContactSearchID linphone_contact_search_get_id(LinphoneContactSearch* obj); const char* linphone_contact_search_get_predicate(LinphoneContactSearch* obj); void linphone_contact_search_invoke_cb(LinphoneContactSearch* req, MSList* friends); -LinphoneContactSearch* linphone_contact_search_ref(void* obj); +LINPHONE_PUBLIC LinphoneContactSearch* linphone_contact_search_ref(void* obj); void linphone_contact_search_unref(void* obj); LinphoneContactSearch* linphone_contact_search_cast( void*obj ); @@ -32,10 +32,10 @@ void linphone_contact_provider_init(LinphoneContactProvider* obj, Linph LinphoneCore* linphone_contact_provider_get_core(LinphoneContactProvider* obj); const char* linphone_contact_provider_get_name(LinphoneContactProvider* obj); LinphoneContactProvider* linphone_contact_provider_ref(void* obj); -void linphone_contact_provider_unref(void* obj); -LinphoneContactProvider* linphone_contact_provider_cast( void*obj ); +LINPHONE_PUBLIC void linphone_contact_provider_unref(void* obj); +LINPHONE_PUBLIC LinphoneContactProvider* linphone_contact_provider_cast( void*obj ); -LinphoneContactSearch* linphone_contact_provider_begin_search(LinphoneContactProvider* obj, +LINPHONE_PUBLIC LinphoneContactSearch* linphone_contact_provider_begin_search(LinphoneContactProvider* obj, const char* predicate, ContactSearchCallback cb, void* data); diff --git a/coreapi/content.c b/coreapi/content.c index 36ebbb0a7..9f5cd4fee 100644 --- a/coreapi/content.c +++ b/coreapi/content.c @@ -29,6 +29,8 @@ static void linphone_content_destroy(LinphoneContent *content) { if (content->lcp.data) belle_sip_free(content->lcp.data); if (content->lcp.encoding) belle_sip_free(content->lcp.encoding); if (content->lcp.name) belle_sip_free(content->lcp.name); + if (content->lcp.key) belle_sip_free(content->lcp.key); + /* note : crypto context is allocated/destroyed by the encryption function */ } } @@ -38,6 +40,7 @@ static void linphone_content_clone(LinphoneContent *obj, const LinphoneContent * linphone_content_set_subtype(obj, linphone_content_get_subtype(ref)); linphone_content_set_encoding(obj, linphone_content_get_encoding(ref)); linphone_content_set_name(obj, linphone_content_get_name(ref)); + linphone_content_set_key(obj, linphone_content_get_key(ref), linphone_content_get_key_size(ref)); if (linphone_content_get_buffer(ref) != NULL) { linphone_content_set_buffer(obj, linphone_content_get_buffer(ref), linphone_content_get_size(ref)); } else { @@ -161,12 +164,36 @@ void linphone_content_set_name(LinphoneContent *content, const char *name) { } } +size_t linphone_content_get_key_size(const LinphoneContent *content) { + return content->lcp.keyLength; +} + +const char * linphone_content_get_key(const LinphoneContent *content) { + return content->lcp.key; +} + +void linphone_content_set_key(LinphoneContent *content, const char *key, const size_t keyLength) { + if (content->lcp.key != NULL) { + belle_sip_free(content->lcp.key); + content->lcp.key = NULL; + } + if (key != NULL) { + content->lcp.key = belle_sip_malloc(keyLength); + memcpy(content->lcp.key, key, keyLength); + } +} + +/* crypto context is managed(allocated/freed) by the encryption function, so provide the address of field in the private structure */ +void ** linphone_content_get_cryptoContext_address(LinphoneContent *content) { + return &(content->lcp.cryptoContext); +} LinphoneContent * linphone_content_new(void) { LinphoneContent *content = belle_sip_object_new(LinphoneContent); belle_sip_object_ref(content); content->owned_fields = TRUE; + content->lcp.cryptoContext = NULL; /* this field is managed externally by encryption/decryption functions so be careful to initialise it to NULL */ return content; } diff --git a/coreapi/content.h b/coreapi/content.h index e3e0166ce..1e21138eb 100644 --- a/coreapi/content.h +++ b/coreapi/content.h @@ -51,6 +51,9 @@ struct _LinphoneContentPrivate{ When provided by callback #LinphoneCoreFileTransferSendCb or #LinphoneCoreFileTransferRecvCb, it states the total number of bytes of the transfered file*/ char *encoding; /** + +#if POLARSSL_VERSION_NUMBER >= 0x01030000 /* for Polarssl version 1.3 */ +#include "polarssl/sha256.h" +#else /* for Polarssl version 1.2 */ +#include "polarssl/sha2.h" +#endif +/** + * @brief convert an hexa char [0-9a-fA-F] into the corresponding unsigned integer value + * Any invalid char will be converted to zero without any warning + * + * @param[in] inputChar a char which shall be in range [0-9a-fA-F] + * + * @return the unsigned integer value in range [0-15] + */ +uint8_t lime_charToByte(uint8_t inputChar) { + /* 0-9 */ + if (inputChar>0x29 && inputChar<0x3A) { + return inputChar - 0x30; + } + + /* a-f */ + if (inputChar>0x60 && inputChar<0x67) { + return inputChar - 0x57; /* 0x57 = 0x61(a) + 0x0A*/ + } + + /* A-F */ + if (inputChar>0x40 && inputChar<0x47) { + return inputChar - 0x37; /* 0x37 = 0x41(a) + 0x0A*/ + } + + /* shall never arrive here, string is not Hex*/ + return 0; + +} + +/** + * @brief convert a byte which value is in range [0-15] into an hexa char [0-9a-fA-F] + * + * @param[in] inputByte an integer which shall be in range [0-15] + * + * @return the hexa char [0-9a-f] corresponding to the input + */ +uint8_t lime_byteToChar(uint8_t inputByte) { + inputByte &=0x0F; /* restrict the input value to range [0-15] */ + /* 0-9 */ + if(inputByte<0x0A) { + return inputByte+0x30; + } + /* a-f */ + return inputByte + 0x57; +} + + +/** + * @brief Convert an hexadecimal string into the corresponding byte buffer + * + * @param[out] outputBytes The output bytes buffer, must have a length of half the input string buffer + * @param[in] inputString The input string buffer, must be hexadecimal(it is not checked by function, any non hexa char is converted to 0) + * @param[in] inputStringLength The lenght in chars of the string buffer, output is half this length + */ +void lime_strToUint8(uint8_t *outputBytes, uint8_t *inputString, uint16_t inputStringLength) { + int i; + for (i=0; i>4)&0x0F); + outputString[2*i+1] = lime_byteToChar(inputBytes[i]&0x0F); + } +} + + + +int lime_getSelfZid(xmlDocPtr cacheBuffer, uint8_t selfZid[25]) { + xmlNodePtr cur; + xmlChar *selfZidHex; + + if (cacheBuffer == NULL ) { + return LIME_INVALID_CACHE; + } + + cur = xmlDocGetRootElement(cacheBuffer); + /* if we found a root element, parse its children node */ + if (cur!=NULL) + { + cur = cur->xmlChildrenNode; + } + selfZidHex = NULL; + while (cur!=NULL) { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"selfZID"))){ /* self ZID found, extract it */ + selfZidHex = xmlNodeListGetString(cacheBuffer, cur->xmlChildrenNode, 1); + /* copy it to the output buffer and add the null termination */ + memcpy(selfZid, selfZidHex, 24); + selfZid[24]='\0'; + break; + } + cur = cur->next; + } + + /* did we found a ZID? */ + if (selfZidHex == NULL) { + return LIME_INVALID_CACHE; + } + + xmlFree(selfZidHex); + return 0; +} + +int lime_getCachedSndKeysByURI(xmlDocPtr cacheBuffer, limeURIKeys_t *associatedKeys) { + xmlNodePtr cur; + + /* parse the file to get all peer matching the sipURI given in associatedKeys*/ + if (cacheBuffer == NULL ) { /* there is no cache return error */ + return LIME_INVALID_CACHE; + } + + /* reset number of associated keys and their buffer */ + associatedKeys->associatedZIDNumber = 0; + associatedKeys->peerKeys = NULL; + + cur = xmlDocGetRootElement(cacheBuffer); + /* if we found a root element, parse its children node */ + if (cur!=NULL) + { + cur = cur->xmlChildrenNode; + } + while (cur!=NULL) { /* loop on all peer nodes */ + uint8_t matchingURIFlag = 0; /* this flag is set to one if we found the requested sipURI in the current peer node */ + if ((!xmlStrcmp(cur->name, (const xmlChar *)"peer"))) { /* found a peer node, check if there is a matching sipURI node in it */ + xmlNodePtr peerNodeChildren = cur->xmlChildrenNode; + matchingURIFlag = 0; + + /* loop on children nodes until the end or we found the matching sipURI */ + while (peerNodeChildren!=NULL && matchingURIFlag==0) { + if (!xmlStrcmp(peerNodeChildren->name, (const xmlChar *)"uri")) { /* found a peer an URI node, check the content */ + xmlChar *uriNodeContent = xmlNodeListGetString(cacheBuffer, peerNodeChildren->xmlChildrenNode, 1); + if (!xmlStrcmp(uriNodeContent, (const xmlChar *)associatedKeys->peerURI)) { /* found a match with requested URI */ + matchingURIFlag=1; + } + xmlFree(uriNodeContent); + } + peerNodeChildren = peerNodeChildren->next; + } + + if (matchingURIFlag == 1) { /* we found a match for the URI in this peer node, extract the keys, session Id and index values */ + /* allocate a new limeKey_t structure to hold the retreived keys */ + limeKey_t *currentPeerKeys = (limeKey_t *)malloc(sizeof(limeKey_t)); + uint8_t itemFound = 0; /* count the item found, we must get all of the requested infos: 5 nodes*/ + uint8_t pvs = 0; + + peerNodeChildren = cur->xmlChildrenNode; /* reset peerNodeChildren to the first child of node */ + while (peerNodeChildren!=NULL && itemFound<5) { + xmlChar *nodeContent = NULL; + if (!xmlStrcmp(peerNodeChildren->name, (const xmlChar *)"ZID")) { + nodeContent = xmlNodeListGetString(cacheBuffer, peerNodeChildren->xmlChildrenNode, 1); + lime_strToUint8(currentPeerKeys->peerZID, nodeContent, 24); + itemFound++; + } + + if (!xmlStrcmp(peerNodeChildren->name, (const xmlChar *)"sndKey")) { + nodeContent = xmlNodeListGetString(cacheBuffer, peerNodeChildren->xmlChildrenNode, 1); + lime_strToUint8(currentPeerKeys->key, nodeContent, 64); + itemFound++; + } + if (!xmlStrcmp(peerNodeChildren->name, (const xmlChar *)"sndSId")) { + nodeContent = xmlNodeListGetString(cacheBuffer, peerNodeChildren->xmlChildrenNode, 1); + lime_strToUint8(currentPeerKeys->sessionId, nodeContent, 64); + itemFound++; + } + if (!xmlStrcmp(peerNodeChildren->name, (const xmlChar *)"sndIndex")) { + uint8_t sessionIndexBuffer[4]; /* session index is a uint32_t but we first retrieved it as an hexa string, convert it to a 4 uint8_t buffer */ + nodeContent = xmlNodeListGetString(cacheBuffer, peerNodeChildren->xmlChildrenNode, 1); + lime_strToUint8(sessionIndexBuffer, nodeContent, 8); + /* convert it back to a uint32_t (MSByte first)*/ + currentPeerKeys->sessionIndex = sessionIndexBuffer[3] + (sessionIndexBuffer[2]<<8) + (sessionIndexBuffer[1]<<16) + (sessionIndexBuffer[0]<<24); + itemFound++; + } + if (!xmlStrcmp(peerNodeChildren->name, (const xmlChar *)"pvs")) { + nodeContent = xmlNodeListGetString(cacheBuffer, peerNodeChildren->xmlChildrenNode, 1); + lime_strToUint8(&pvs, nodeContent, 2); /* pvs is retrieved as a 2 characters hexa string, convert it to an int8 */ + itemFound++; + } + + xmlFree(nodeContent); + peerNodeChildren = peerNodeChildren->next; + } + + /* check if we have all the requested information and the PVS flag is set to 1 */ + if (itemFound == 5 && pvs == 1) { + associatedKeys->associatedZIDNumber +=1; + /* extend array of pointer to limeKey_t structures to add the one we found */ + associatedKeys->peerKeys = (limeKey_t **)realloc(associatedKeys->peerKeys, (associatedKeys->associatedZIDNumber)*sizeof(limeKey_t *)); + + /* add the new entry at the end */ + associatedKeys->peerKeys[associatedKeys->associatedZIDNumber-1] = currentPeerKeys; + + } else { + free(currentPeerKeys); + } + } + } + cur = cur->next; + } + return 0; +} + +int lime_getCachedRcvKeyByZid(xmlDocPtr cacheBuffer, limeKey_t *associatedKey) { + uint8_t peerZidHex[25]; + /* to check we collect all the information needed from the cache and that pvs(boolean for previously verified Sas) is set in cache */ + uint8_t itemFound = 0; + uint8_t pvs = 0; + xmlNodePtr cur; + + if (cacheBuffer == NULL ) { /* there is no cache return error */ + return LIME_INVALID_CACHE; + } + + /* get the given ZID into hex format */ + lime_int8ToStr(peerZidHex, associatedKey->peerZID, 12); + peerZidHex[24]='\0'; /* must be a null terminated string */ + + cur = xmlDocGetRootElement(cacheBuffer); + /* if we found a root element, parse its children node */ + if (cur!=NULL) + { + cur = cur->xmlChildrenNode; + + } + + while (cur!=NULL) { /* loop on all peer nodes */ + if ((!xmlStrcmp(cur->name, (const xmlChar *)"peer"))){ /* found a peer, check his ZID element */ + xmlChar *currentZidHex = xmlNodeListGetString(cacheBuffer, cur->xmlChildrenNode->xmlChildrenNode, 1); /* ZID is the first element of peer */ + if (!xmlStrcmp(currentZidHex, (const xmlChar *)peerZidHex)) { /* we found the peer element we are looking for */ + xmlNodePtr peerNodeChildren = cur->xmlChildrenNode->next; + while (peerNodeChildren != NULL && itemFound<4) { /* look for the tag we want to read : rcvKey, rcvSId, rcvIndex and pvs*/ + xmlChar *nodeContent = NULL; + if (!xmlStrcmp(peerNodeChildren->name, (const xmlChar *)"rcvKey")) { + nodeContent = xmlNodeListGetString(cacheBuffer, peerNodeChildren->xmlChildrenNode, 1); + lime_strToUint8(associatedKey->key, nodeContent, 64); + itemFound++; + } + if (!xmlStrcmp(peerNodeChildren->name, (const xmlChar *)"rcvSId")) { + nodeContent = xmlNodeListGetString(cacheBuffer, peerNodeChildren->xmlChildrenNode, 1); + lime_strToUint8(associatedKey->sessionId, nodeContent, 64); + itemFound++; + } + if (!xmlStrcmp(peerNodeChildren->name, (const xmlChar *)"rcvIndex")) { + uint8_t sessionIndexBuffer[4]; /* session index is a uint32_t but we first retrieved it as an hexa string, convert it to a 4 uint8_t buffer */ + nodeContent = xmlNodeListGetString(cacheBuffer, peerNodeChildren->xmlChildrenNode, 1); + lime_strToUint8(sessionIndexBuffer, nodeContent, 8); + /* convert it back to a uint32_t (MSByte first)*/ + associatedKey->sessionIndex = sessionIndexBuffer[3] + (sessionIndexBuffer[2]<<8) + (sessionIndexBuffer[1]<<16) + (sessionIndexBuffer[0]<<24); + itemFound++; + } + if (!xmlStrcmp(peerNodeChildren->name, (const xmlChar *)"pvs")) { + nodeContent = xmlNodeListGetString(cacheBuffer, peerNodeChildren->xmlChildrenNode, 1); + lime_strToUint8(&pvs, nodeContent, 2); /* pvs is retrieved as a 2 characters hexa string, convert it to an int8 */ + itemFound++; + } + xmlFree(nodeContent); + peerNodeChildren = peerNodeChildren->next; + } + xmlFree(currentZidHex); + break; /* we parsed the peer node we were looking for, get out of the main while */ + } + xmlFree(currentZidHex); + } + cur = cur->next; + } + + /* if we manage to find the correct key information and that pvs is set to 1, return 0 (success) */ + if ((pvs == 1) && (itemFound == 4)) { + return 0; + } + + /* otherwise, key wasn't found or is invalid */ + return LIME_NO_VALID_KEY_FOUND_FOR_PEER; +} + +int lime_setCachedKey(xmlDocPtr cacheBuffer, limeKey_t *associatedKey, uint8_t role) { + xmlNodePtr cur; + uint8_t peerZidHex[25]; + uint8_t keyHex[65]; /* key is 32 bytes long -> 64 bytes string + null termination */ + uint8_t sessionIdHex[65]; /* sessionId is 32 bytes long -> 64 bytes string + null termination */ + uint8_t sessionIndexHex[9]; /* sessionInedx is an uint32_t : 4 bytes long -> 8 bytes string + null termination */ + uint8_t itemFound = 0; + + if (cacheBuffer == NULL ) { /* there is no cache return error */ + return LIME_INVALID_CACHE; + } + + /* get the given ZID into hex format */ + lime_int8ToStr(peerZidHex, associatedKey->peerZID, 12); + peerZidHex[24]='\0'; /* must be a null terminated string */ + + cur = xmlDocGetRootElement(cacheBuffer); + /* if we found a root element, parse its children node */ + if (cur!=NULL) + { + cur = cur->xmlChildrenNode; + + } + + /* convert the given tag content to null terminated Hexadecimal strings */ + lime_int8ToStr(keyHex, associatedKey->key, 32); + keyHex[64] = '\0'; + lime_int8ToStr(sessionIdHex, associatedKey->sessionId, 32); + sessionIdHex[64] = '\0'; + sessionIndexHex[0] = lime_byteToChar((uint8_t)((associatedKey->sessionIndex>>28)&0x0F)); + sessionIndexHex[1] = lime_byteToChar((uint8_t)((associatedKey->sessionIndex>>24)&0x0F)); + sessionIndexHex[2] = lime_byteToChar((uint8_t)((associatedKey->sessionIndex>>20)&0x0F)); + sessionIndexHex[3] = lime_byteToChar((uint8_t)((associatedKey->sessionIndex>>16)&0x0F)); + sessionIndexHex[4] = lime_byteToChar((uint8_t)((associatedKey->sessionIndex>>12)&0x0F)); + sessionIndexHex[5] = lime_byteToChar((uint8_t)((associatedKey->sessionIndex>>8)&0x0F)); + sessionIndexHex[6] = lime_byteToChar((uint8_t)((associatedKey->sessionIndex>>4)&0x0F)); + sessionIndexHex[7] = lime_byteToChar((uint8_t)((associatedKey->sessionIndex)&0x0F)); + sessionIndexHex[8] = '\0'; + + while (cur!=NULL && itemFound<3) { /* loop on all peer nodes */ + if ((!xmlStrcmp(cur->name, (const xmlChar *)"peer"))){ /* found a peer, check his ZID element */ + xmlChar *currentZidHex = xmlNodeListGetString(cacheBuffer, cur->xmlChildrenNode->xmlChildrenNode, 1); /* ZID is the first element of peer */ + if (!xmlStrcmp(currentZidHex, (const xmlChar *)peerZidHex)) { /* we found the peer element we are looking for */ + xmlNodePtr peerNodeChildren = cur->xmlChildrenNode->next; + while (peerNodeChildren != NULL && itemFound<3) { /* look for the tag we want to write */ + if (role == LIME_RECEIVER) { /* writing receiver key */ + if (!xmlStrcmp(peerNodeChildren->name, (const xmlChar *)"rcvKey")) { + xmlNodeSetContent(peerNodeChildren, (const xmlChar *)keyHex); + itemFound++; + } + if (!xmlStrcmp(peerNodeChildren->name, (const xmlChar *)"rcvSId")) { + xmlNodeSetContent(peerNodeChildren, (const xmlChar *)sessionIdHex); + itemFound++; + } + if (!xmlStrcmp(peerNodeChildren->name, (const xmlChar *)"rcvIndex")) { + xmlNodeSetContent(peerNodeChildren, (const xmlChar *)sessionIndexHex); + itemFound++; + } + } else { /* writing sender key */ + if (!xmlStrcmp(peerNodeChildren->name, (const xmlChar *)"sndKey")) { + xmlNodeSetContent(peerNodeChildren, (const xmlChar *)keyHex); + itemFound++; + } + if (!xmlStrcmp(peerNodeChildren->name, (const xmlChar *)"sndSId")) { + xmlNodeSetContent(peerNodeChildren, (const xmlChar *)sessionIdHex); + itemFound++; + } + if (!xmlStrcmp(peerNodeChildren->name, (const xmlChar *)"sndIndex")) { + xmlNodeSetContent(peerNodeChildren, (const xmlChar *)sessionIndexHex); + itemFound++; + } + } + peerNodeChildren = peerNodeChildren->next; + } + } + xmlFree(currentZidHex); + } + cur = cur->next; + } + + + return 0; +} + +int lime_deriveKey(limeKey_t *key) { + uint8_t inputData[55]; + uint8_t derivedKey[32]; + + if (key == NULL) { + return LIME_UNABLE_TO_DERIVE_KEY; + } + +#if 0 + /*not doing anything yet since key and sessionId are array, not pointers*/ + if ((key->key == NULL) || (key->sessionId == NULL)) { + return LIME_UNABLE_TO_DERIVE_KEY; + } +#endif + + /* Derivation is made derived Key = HMAC_SHA256(Key, 0x0000001||"MessageKey"||0x00||SessionId||SessionIndex||0x00000100)*/ + /* total data to be hashed is 55 bytes : 4 + 10 + 1 + 32 + 4 + 4 */ + inputData[0] = 0x00; + inputData[1] = 0x00; + inputData[2] = 0x00; + inputData[3] = 0x01; + + memcpy(inputData+4, "MessageKey", 10); + + inputData[14] = 0x00; + + memcpy(inputData+15, key->sessionId, 32); + + inputData[47] = (uint8_t)((key->sessionIndex>>24)&0x000000FF); + inputData[48] = (uint8_t)((key->sessionIndex>>16)&0x000000FF); + inputData[49] = (uint8_t)((key->sessionIndex>>8)&0x000000FF); + inputData[50] = (uint8_t)(key->sessionIndex&0x000000FF); + + inputData[51] = 0x00; + inputData[52] = 0x00; + inputData[53] = 0x01; + inputData[54] = 0x00; + + /* derive the key in a temp buffer */ +#if POLARSSL_VERSION_NUMBER >= 0x01030000 /* for Polarssl version 1.3 */ + sha256_hmac(key->key, 32, inputData, 55, derivedKey, 0); /* last param to zero to select SHA256 and not SHA224 */ +#else /* for Polarssl version 1.2 */ + sha2_hmac(key->key, 32, inputData, 55, derivedKey, 0); /* last param to zero to select SHA256 and not SHA224 */ +#endif /* POLARSSL_VERSION_NUMBER */ + + /* overwrite the old key with the derived one */ + memcpy(key->key, derivedKey, 32); + + /* increment the session Index */ + key->sessionIndex += 1; + return 0; +} + +void lime_freeKeys(limeURIKeys_t associatedKeys) { + int i; + + /* free all associated keys */ + for (i=0; i< associatedKeys.associatedZIDNumber; i++) { + if (associatedKeys.peerKeys[i] != NULL) { + free(associatedKeys.peerKeys[i]); + associatedKeys.peerKeys[i] = NULL; + } + } + + free(associatedKeys.peerKeys); + + /* free sipURI string */ + free(associatedKeys.peerURI); +} + +int lime_encryptMessage(limeKey_t *key, uint8_t *plainMessage, uint32_t messageLength, uint8_t selfZID[12], uint8_t *encryptedMessage) { + uint8_t authenticatedData[28]; + gcm_context gcmContext; + /* Authenticated data is senderZID(12 bytes)||receiverZID(12 bytes)||sessionIndex(4 bytes) */ + memcpy(authenticatedData, selfZID, 12); + memcpy(authenticatedData+12, key->peerZID, 12); + authenticatedData[24] = (uint8_t)((key->sessionIndex>>24)&0x000000FF); + authenticatedData[25] = (uint8_t)((key->sessionIndex>>16)&0x000000FF); + authenticatedData[26] = (uint8_t)((key->sessionIndex>>8)&0x000000FF); + authenticatedData[27] = (uint8_t)(key->sessionIndex&0x000000FF); + + /* AES-GCM : key is 192 bits long, Init Vector 64 bits. 256 bits key given is AES key||IV */ + /* tag is 16 bytes long and is set in the 16 first bytes of the encrypted message */ + gcm_init(&gcmContext, POLARSSL_CIPHER_ID_AES, key->key, 192); + gcm_crypt_and_tag(&gcmContext, GCM_ENCRYPT, messageLength, key->key+24, 8, authenticatedData, 28, plainMessage, encryptedMessage+16, 16, encryptedMessage); + gcm_free(&gcmContext); + + return 0; +} + +int lime_encryptFile(void **cryptoContext, unsigned char *key, size_t length, char *plain, char *cipher) { + gcm_context *gcmContext; + + if (*cryptoContext == NULL) { /* first call to the function, allocate a crypto context and initialise it */ + gcmContext = (gcm_context *)malloc(sizeof(gcm_context)); + *cryptoContext = (void *)gcmContext; + gcm_init(gcmContext, POLARSSL_CIPHER_ID_AES, key, 192); + gcm_starts(gcmContext, GCM_ENCRYPT, key+24, 8, NULL, 0); /* key contains 192bits of key || 64 bits of Initialisation Vector */ + } else { /* this is not the first call, get the context */ + gcmContext = (gcm_context *)*cryptoContext; + } + + if (length != 0) { + gcm_update(gcmContext, length, (const unsigned char *)plain, (unsigned char *)cipher); + } else { /* lenght is 0, finish the stream */ + gcm_finish(gcmContext, NULL, 0); /* do not generate tag */ + gcm_free(gcmContext); + free(*cryptoContext); + *cryptoContext = NULL; + } + + return 0; +} + +int lime_decryptFile(void **cryptoContext, unsigned char *key, size_t length, char *plain, char *cipher) { + gcm_context *gcmContext; + + if (*cryptoContext == NULL) { /* first call to the function, allocate a crypto context and initialise it */ + gcmContext = (gcm_context *)malloc(sizeof(gcm_context)); + *cryptoContext = (void *)gcmContext; + gcm_init(gcmContext, POLARSSL_CIPHER_ID_AES, key, 192); + gcm_starts(gcmContext, GCM_DECRYPT, key+24, 8, NULL, 0); /* key contains 192bits of key || 64 bits of Initialisation Vector */ + } else { /* this is not the first call, get the context */ + gcmContext = (gcm_context *)*cryptoContext; + } + + if (length != 0) { + gcm_update(gcmContext, length, (const unsigned char *)cipher, (unsigned char *)plain); + } else { /* lenght is 0, finish the stream */ + gcm_finish(gcmContext, NULL, 0); /* do not generate tag */ + gcm_free(gcmContext); + free(*cryptoContext); + *cryptoContext = NULL; + } + + return 0; +} + + +int lime_decryptMessage(limeKey_t *key, uint8_t *encryptedMessage, uint32_t messageLength, uint8_t selfZID[12], uint8_t *plainMessage) { + uint8_t authenticatedData[28]; + gcm_context gcmContext; + int retval; + + /* Authenticated data is senderZID(12 bytes)||receiverZID(12 bytes)||sessionIndex(4 bytes) */ + memcpy(authenticatedData, key->peerZID, 12); + memcpy(authenticatedData+12, selfZID, 12); + authenticatedData[24] = (uint8_t)((key->sessionIndex>>24)&0x000000FF); + authenticatedData[25] = (uint8_t)((key->sessionIndex>>16)&0x000000FF); + authenticatedData[26] = (uint8_t)((key->sessionIndex>>8)&0x000000FF); + authenticatedData[27] = (uint8_t)(key->sessionIndex&0x000000FF); + + /* AES-GCM : key is 192 bits long, Init Vector 64 bits. 256 bits key given is AES key||IV */ + /* tag is 16 bytes long and is the 16 first bytes of the encrypted message */ + gcm_init(&gcmContext, POLARSSL_CIPHER_ID_AES, key->key, 192); + /* messageLength-16 is the length of encrypted data, messageLength include the 16 bytes tag included at the begining of encryptedMessage */ + retval = gcm_auth_decrypt(&gcmContext, messageLength-16, key->key+24, 8, authenticatedData, 28, encryptedMessage, 16, encryptedMessage+16, plainMessage); + gcm_free(&gcmContext); + /* add the null termination char */ + plainMessage[messageLength-16] = '\0'; + + return retval; +} + +int lime_createMultipartMessage(xmlDocPtr cacheBuffer, uint8_t *message, uint8_t *peerURI, uint8_t **output) { + uint8_t selfZidHex[25]; + uint8_t selfZid[12]; /* same data but in byte buffer */ + uint32_t encryptedMessageLength; + limeURIKeys_t associatedKeys; + xmlDocPtr xmlOutputMessage; + xmlNodePtr rootNode; + int i; + int xmlStringLength; + + /* retrieve selfZIDHex from cache(return a 24 char hexa string + null termination) */ + if (lime_getSelfZid(cacheBuffer, selfZidHex) != 0) { + return LIME_UNABLE_TO_ENCRYPT_MESSAGE; + } + lime_strToUint8(selfZid, selfZidHex, 24); + + /* encrypted message length is plaintext + 16 for tag */ + encryptedMessageLength = strlen((char *)message) + 16; + + /* retrieve keys associated to the peer URI */ + associatedKeys.peerURI = (uint8_t *)malloc(strlen((char *)peerURI)+1); + strcpy((char *)(associatedKeys.peerURI), (char *)peerURI); + associatedKeys.associatedZIDNumber = 0; + associatedKeys.peerKeys = NULL; + + if (lime_getCachedSndKeysByURI(cacheBuffer, &associatedKeys) != 0) { + lime_freeKeys(associatedKeys); + return LIME_UNABLE_TO_ENCRYPT_MESSAGE; + } + + if (associatedKeys.associatedZIDNumber == 0) { + lime_freeKeys(associatedKeys); + return LIME_NO_VALID_KEY_FOUND_FOR_PEER; + } + + /* create an xml doc to hold the multipart message */ + xmlOutputMessage = xmlNewDoc((const xmlChar *)"1.0"); + /* root tag is "doc" */ + rootNode = xmlNewDocNode(xmlOutputMessage, NULL, (const xmlChar *)"doc", NULL); + xmlDocSetRootElement(xmlOutputMessage, rootNode); + /* add the self ZID child */ + xmlNewTextChild(rootNode, NULL, (const xmlChar *)"ZID", selfZidHex); + + /* loop on all keys found */ + for (i=0; i + * peerZID + * session index + * ciphertext + * */ + msgNode = xmlNewDocNode(xmlOutputMessage, NULL, (const xmlChar *)"msg", NULL); + lime_int8ToStr(peerZidHex, currentKey->peerZID, 12); + peerZidHex[24] = '\0'; + sessionIndexHex[0] = lime_byteToChar((uint8_t)((currentKey->sessionIndex>>28)&0x0F)); + sessionIndexHex[1] = lime_byteToChar((uint8_t)((currentKey->sessionIndex>>24)&0x0F)); + sessionIndexHex[2] = lime_byteToChar((uint8_t)((currentKey->sessionIndex>>20)&0x0F)); + sessionIndexHex[3] = lime_byteToChar((uint8_t)((currentKey->sessionIndex>>16)&0x0F)); + sessionIndexHex[4] = lime_byteToChar((uint8_t)((currentKey->sessionIndex>>12)&0x0F)); + sessionIndexHex[5] = lime_byteToChar((uint8_t)((currentKey->sessionIndex>>8)&0x0F)); + sessionIndexHex[6] = lime_byteToChar((uint8_t)((currentKey->sessionIndex>>4)&0x0F)); + sessionIndexHex[7] = lime_byteToChar((uint8_t)((currentKey->sessionIndex)&0x0F)); + sessionIndexHex[8] = '\0'; + + xmlNewTextChild(msgNode, NULL, (const xmlChar *)"pzid", peerZidHex); + xmlNewTextChild(msgNode, NULL, (const xmlChar *)"index", sessionIndexHex); + + /* convert the cipherText to base 64 */ + b64Size = b64_encode(NULL, encryptedMessageLength, NULL, 0); + encryptedMessageb64 = (char *)malloc(b64Size+1); + b64Size = b64_encode(encryptedMessage, encryptedMessageLength, encryptedMessageb64, b64Size); + encryptedMessageb64[b64Size] = '\0'; /* libxml need a null terminated string */ + xmlNewTextChild(msgNode, NULL, (const xmlChar *)"text", (const xmlChar *)encryptedMessageb64); + free(encryptedMessage); + free(encryptedMessageb64); + + /* add the message Node into the doc */ + xmlAddChild(rootNode, msgNode); + + /* update the key used */ + lime_deriveKey(currentKey); + lime_setCachedKey(cacheBuffer, currentKey, LIME_SENDER); + } + + /* dump the whole message doc into the output */ + xmlDocDumpFormatMemoryEnc(xmlOutputMessage, output, &xmlStringLength, "UTF-8", 0); + xmlFreeDoc(xmlOutputMessage); + + lime_freeKeys(associatedKeys); + + return 0; +} + +int lime_decryptMultipartMessage(xmlDocPtr cacheBuffer, uint8_t *message, uint8_t **output) { + int retval; + uint8_t selfZidHex[25]; + uint8_t selfZid[12]; /* same data but in byte buffer */ + limeKey_t associatedKey; + xmlChar *peerZidHex = NULL; + xmlNodePtr cur; + uint8_t *encryptedMessage = NULL; + uint32_t encryptedMessageLength = 0; + uint32_t usedSessionIndex = 0; + xmlDocPtr xmlEncryptedMessage; + + if (cacheBuffer == NULL) { + return LIME_INVALID_CACHE; + } + /* retrieve selfZIDHex from cache(return a 24 char hexa string + null termination) */ + if (lime_getSelfZid(cacheBuffer, selfZidHex) != 0) { + return LIME_UNABLE_TO_DECRYPT_MESSAGE; + } + lime_strToUint8(selfZid, selfZidHex, 24); + + /* parse the message into an xml doc */ + /* make sure we have a valid xml message before trying to parse it */ + if (memcmp(message, "", 38) != 0 ) { + return LIME_INVALID_ENCRYPTED_MESSAGE; + } + xmlEncryptedMessage = xmlParseDoc((const xmlChar *)message); + if (xmlEncryptedMessage == NULL) { + return LIME_INVALID_ENCRYPTED_MESSAGE; + } + + /* retrieve the sender ZID which is the first child of root */ + cur = xmlDocGetRootElement(xmlEncryptedMessage); + if (cur != NULL) { + cur = cur->xmlChildrenNode; + if ((!xmlStrcmp(cur->name, (const xmlChar *)"ZID"))){ /* sender ZID found, extract it */ + peerZidHex = xmlNodeListGetString(xmlEncryptedMessage, cur->xmlChildrenNode, 1); + /* convert it from hexa string to bytes string and set the result in the associatedKey structure */ + lime_strToUint8(associatedKey.peerZID, peerZidHex, strlen((char *)peerZidHex)); + cur = cur->next; + } + } + + if (peerZidHex != NULL) { + /* get from cache the matching key */ + retval = lime_getCachedRcvKeyByZid(cacheBuffer, &associatedKey); + + if (retval != 0) { + xmlFree(peerZidHex); + xmlFreeDoc(xmlEncryptedMessage); + return retval; + } + + /* retrieve the portion of message which is encrypted with our key */ + while (cur != NULL) { /* loop on all "msg" node in the message */ + xmlNodePtr msgChildrenNode = cur->xmlChildrenNode; + xmlChar *currentZidHex = xmlNodeListGetString(cacheBuffer, msgChildrenNode->xmlChildrenNode, 1); /* pZID is the first element of msg */ + if (!xmlStrcmp(currentZidHex, (const xmlChar *)selfZidHex)) { /* we found the msg node we are looking for */ + /* get the index (second node in the msg one) */ + xmlChar *sessionIndexHex; + xmlChar *encryptedMessageb64; + + msgChildrenNode = msgChildrenNode->next; + sessionIndexHex = xmlNodeListGetString(cacheBuffer, msgChildrenNode->xmlChildrenNode, 1); + usedSessionIndex = (((uint32_t)lime_charToByte(sessionIndexHex[0]))<<28) + | (((uint32_t)lime_charToByte(sessionIndexHex[1]))<<24) + | (((uint32_t)lime_charToByte(sessionIndexHex[2]))<<20) + | (((uint32_t)lime_charToByte(sessionIndexHex[3]))<<16) + | (((uint32_t)lime_charToByte(sessionIndexHex[4]))<<12) + | (((uint32_t)lime_charToByte(sessionIndexHex[5]))<<8) + | (((uint32_t)lime_charToByte(sessionIndexHex[6]))<<4) + | (((uint32_t)lime_charToByte(sessionIndexHex[7]))); + xmlFree(sessionIndexHex); + /* get the encrypted message */ + msgChildrenNode = msgChildrenNode->next; + /* convert the cipherText from base 64 */ + encryptedMessageb64 = xmlNodeListGetString(cacheBuffer, msgChildrenNode->xmlChildrenNode, 1); + encryptedMessageLength = b64_decode((char *)encryptedMessageb64, strlen((char *)encryptedMessageb64), NULL, 0); + encryptedMessage = (uint8_t *)malloc(encryptedMessageLength); + encryptedMessageLength = b64_decode((char *)encryptedMessageb64, strlen((char *)encryptedMessageb64), encryptedMessage, encryptedMessageLength); + xmlFree(encryptedMessageb64); + } + + cur = cur->next; + xmlFree(currentZidHex); + } + } + + xmlFree(peerZidHex); + xmlFreeDoc(xmlEncryptedMessage); + + /* do we have retrieved correctly all the needed data */ + if (encryptedMessage == NULL) { + return LIME_UNABLE_TO_DECRYPT_MESSAGE; + } + + /* shall we derive our key before going for decryption */ + if (usedSessionIndex < associatedKey.sessionIndex) { + /* something wen't wrong with the cache, this shall never happend */ + free(encryptedMessage); + return LIME_UNABLE_TO_DECRYPT_MESSAGE; + } + + if ((usedSessionIndex - associatedKey.sessionIndex > MAX_DERIVATION_NUMBER) ) { + /* we missed to many messages, ask for a cache reset via a ZRTP call */ + free(encryptedMessage); + return LIME_UNABLE_TO_DECRYPT_MESSAGE; + } + + while (usedSessionIndex>associatedKey.sessionIndex) { + lime_deriveKey(&associatedKey); + } + + /* decrypt the message */ + *output = (uint8_t *)malloc(encryptedMessageLength - 16 +1); /* plain message is same length than encrypted one with 16 bytes less for the tag + 1 to add the null termination char */ + retval = lime_decryptMessage(&associatedKey, encryptedMessage, encryptedMessageLength, selfZid, *output); + + free(encryptedMessage); + + if (retval!=0 ) { + free(*output); + *output = NULL; + return LIME_UNABLE_TO_DECRYPT_MESSAGE; + } + + /* update used key */ + lime_deriveKey(&associatedKey); + lime_setCachedKey(cacheBuffer, &associatedKey, LIME_RECEIVER); + + return 0; +} + +char *lime_error_code_to_string(int errorCode) { + switch (errorCode) { + case LIME_INVALID_CACHE: return "Invalid ZRTP cache"; + case LIME_UNABLE_TO_DERIVE_KEY: return "Unable to derive Key"; + case LIME_UNABLE_TO_ENCRYPT_MESSAGE: return "Unable to encrypt message"; + case LIME_UNABLE_TO_DECRYPT_MESSAGE: return "Unable to decrypt message"; + case LIME_NO_VALID_KEY_FOUND_FOR_PEER: return "No valid key found"; + case LIME_INVALID_ENCRYPTED_MESSAGE: return "Invalid encrypted message"; + } + return "Unknow error"; + +} diff --git a/coreapi/lime.h b/coreapi/lime.h new file mode 100644 index 000000000..dae36d898 --- /dev/null +++ b/coreapi/lime.h @@ -0,0 +1,199 @@ +#ifndef LIME_H +#define LIME_H + +#define LIME_INVALID_CACHE 0x1001 +#define LIME_UNABLE_TO_DERIVE_KEY 0x1002 +#define LIME_UNABLE_TO_ENCRYPT_MESSAGE 0x1004 +#define LIME_UNABLE_TO_DECRYPT_MESSAGE 0x1008 +#define LIME_NO_VALID_KEY_FOUND_FOR_PEER 0x1010 +#define LIME_INVALID_ENCRYPTED_MESSAGE 0x1020 + +/* this define the maximum key derivation number allowed to get the caches back in sync in case of missed messages */ +#define MAX_DERIVATION_NUMBER 100 + +#define LIME_SENDER 0x01 +#define LIME_RECEIVER 0x02 +#include +#include +#include +#include + +#include + +#ifndef LINPHONE_PUBLIC +#define LINPHONE_PUBLIC MS2_PUBLIC +#endif + +/** + * @brief Structure holding all needed material to encrypt/decrypt Messages */ +typedef struct limeKey_struct { + uint8_t key[32]; /**< a 256 bit key used to encrypt/decrypt message */ + uint8_t sessionId[32]; /**< a session id used to derive key */ + uint32_t sessionIndex; /**< an index to count number of derivation */ + uint8_t peerZID[12]; /**< the ZID associated to this key */ +} limeKey_t; + +/** + * @brief Store the differents keys associated to a sipURI */ +typedef struct limeURIKeys_struct { + limeKey_t **peerKeys; /**< an array of all the key material associated to each ZID matching the specified URI */ + uint16_t associatedZIDNumber; /**< previous array length */ + uint8_t *peerURI; /**< the sip URI associated to all the keys, must be a null terminated string */ +} limeURIKeys_t; + +/** + * @brief Retrieve selfZID from cache + * + * @param[in] cacheBuffer The xmlDoc containing current cache + * @param[out] selfZid The ZID found as a 24 hexa char string null terminated + * + * @return 0 on success, error code otherwise + */ +LINPHONE_PUBLIC int lime_getSelfZid(xmlDocPtr cacheBuffer, uint8_t selfZid[25]); + +/** + * @brief Get from cache all the senders keys associated to the given URI + * peerKeys field from associatedKeys param must be NULL when calling this function. + * Structure content must then be freed using lime_freeKeys function + * + * @param[in] cacheBuffer The xmlDoc containing current cache + * @param[in/out] associatedKeys Structure containing the peerURI. After this call contains all key material associated to the given URI. Must be then freed through lime_freeKeys function + * + * @return 0 on success, error code otherwise + */ +LINPHONE_PUBLIC int lime_getCachedSndKeysByURI(xmlDocPtr cacheBuffer, limeURIKeys_t *associatedKeys); + +/** + * @brief Get the receiver key associated to the ZID given in the associatedKey parameter + * + * @param[in] cacheBuffer The xmlDoc containing current cache + * @param[in/out] associatedKey Structure containing the peerZID and will store the retrieved key + * + * @return 0 on success, error code otherwise + */ +LINPHONE_PUBLIC int lime_getCachedRcvKeyByZid(xmlDocPtr cacheBuffer, limeKey_t *associatedKey); + +/** + * @brief Set in cache the given key material, association is made by ZID contained in the associatedKey parameter + * + * @param[out] cacheBuffer The xmlDoc containing current cache to be updated + * @param[in/out] associatedKey Structure containing the key and ZID to identify the peer node to be updated + * @param[in] role Can be LIME_SENDER or LIME_RECEIVER, specify which key we want to update + * + * @return 0 on success, error code otherwise + */ + +LINPHONE_PUBLIC int lime_setCachedKey(xmlDocPtr cacheBuffer, limeKey_t *associatedKey, uint8_t role); + +/** + * @brief Free all allocated data in the associated keys structure + * Note, this will also free the peerURI string which then must have been allocated + * + * @param[in/out] associatedKeys The structure to be cleaned + * + */ +LINPHONE_PUBLIC void lime_freeKeys(limeURIKeys_t associatedKeys); + +/** + * @brief Derive in place the key given in parameter and increment session index + * Derivation is made derived Key = HMAC_SHA256(Key, 0x0000001||"MessageKey"||0x00||SessionId||SessionIndex||256) + * + * @param[in/out] key The structure containing the original key which will be overwritten, the sessionId and SessionIndex + * + * @return 0 on success, error code otherwise + */ +LINPHONE_PUBLIC int lime_deriveKey(limeKey_t *key); + +/** + * @brief encrypt a message with the given key + * + * @param[in] key Key to use: first 192 bits are used as key, last 64 bits as init vector + * @param[in] message The string to be encrypted + * @param[in] messageLength The length in bytes of the message to be encrypted + * @param[in] selfZID The self ZID is use in authentication tag computation + * @param[out] encryptedMessage A buffer to hold the output, ouput length is input's one + 16 for the authentication tag + * Authentication tag is set at the begining of the encrypted Message + * + * @return 0 on success, error code otherwise + * + */ +LINPHONE_PUBLIC int lime_encryptMessage(limeKey_t *key, uint8_t *plainMessage, uint32_t messageLength, uint8_t selfZID[12], uint8_t *encryptedMessage); + +/** + * @brief Encrypt a file before transfering it to the server, encryption is done in several call, first one will be done with cryptoContext null, last one with length = 0 + * + * @param[in/out] cryptoContext The context used to encrypt the file using AES-GCM. Is created at first call(if null) + * @param[in] key 256 bits : 192 bits of key || 64 bits of Initial Vector + * @param[in] length Length of data to be encrypted, if 0 it will conclude the encryption + * @param[in] plain Plain data to be encrypted (length bytes) + * @param[out] cipher Output to a buffer allocated by caller, at least length bytes available + * + * @return 0 on success, error code otherwise + * + */ +LINPHONE_PUBLIC int lime_encryptFile(void **cryptoContext, unsigned char *key, size_t length, char *plain, char *cipher); + +/** + * @brief Decrypt a file retrieved from server, decryption is done in several call, first one will be done with cryptoContext null, last one with length = 0 + * + * @param[in/out] cryptoContext The context used to decrypt the file using AES-GCM. Is created at first call(if null) + * @param[in] key 256 bits : 192 bits of key || 64 bits of Initial Vector + * @param[in] length Length of data to be decrypted, if 0 it will conclude the decryption + * @param[out] plain Output to a buffer allocated by caller, at least length bytes available + * @param[in] cipher Cipher text to be decrypted(length bytes) + * + * @return 0 on success, error code otherwise + * + */ +LINPHONE_PUBLIC int lime_decryptFile(void **cryptoContext, unsigned char *key, size_t length, char *plain, char *cipher); + +/** + * @brief decrypt and authentify a message with the given key + * + * @param[in] key Key to use: first 192 bits are used as key, last 64 bits as init vector + * @param[in] message The string to be decrypted + * @param[in] messageLength The length in bytes of the message to be decrypted (this include the 16 bytes tag at the begining of the message) + * @param[in] selfZID The self ZID is use in authentication tag computation + * @param[out] plainMessage A buffer to hold the output, ouput length is input's one - 16 for the authentication tag + 1 for null termination char + * Authentication tag is retrieved at the begining of the encrypted Message + * + * @return 0 on success, error code otherwise + * + */ + +LINPHONE_PUBLIC int lime_decryptMessage(limeKey_t *key, uint8_t *encryptedMessage, uint32_t messageLength, uint8_t selfZID[12], uint8_t *plainMessage); + +/** + * @brief create the encrypted multipart xml message from plain text and destination URI + * Retrieve in cache the needed keys which are then updated. Output buffer is allocated and must be freed by caller + * + * @param[in/out] cacheBuffer The xmlDoc containing current cache, get the keys and selfZID from it, updated by this function with derivated keys + * @param[in] message The plain text message to be encrypted + * @param[in] peerURI The destination URI, associated keys will be found in cache + * @param[out] output The output buffer, allocated and set with the encrypted message xml body(null terminated string). Must be freed by caller + * + * @return 0 on success, error code otherwise + */ +LINPHONE_PUBLIC int lime_createMultipartMessage(xmlDocPtr cacheBuffer, uint8_t *message, uint8_t *peerURI, uint8_t **output); + +/** + * @brief decrypt a multipart xml message + * Retrieve in cache the needed key which is then updated. Output buffer is allocated and must be freed by caller + * + * @param[in/out] cacheBuffer The xmlDoc containing current cache, get the key and selfZID from it, updated by this function with derivated keys + * @param[in] message The multipart message, contain one or several part identified by destination ZID, one shall match the self ZID retrieved from cache + * @param[out] output The output buffer, allocated and set with the decrypted message(null terminated string). Must be freed by caller + * + * @return 0 on success, error code otherwise + */ + +LINPHONE_PUBLIC int lime_decryptMultipartMessage(xmlDocPtr cacheBuffer, uint8_t *message, uint8_t **output); + +/** + * @brief given a readable version of error code generated by Lime functions + * @param[in] errorCode The error code + * @return a string containing the error description + */ +LINPHONE_PUBLIC char *lime_error_code_to_string(int errorCode); + +#endif /* LIME_H */ diff --git a/coreapi/linphone_tunnel.h b/coreapi/linphone_tunnel.h index c1c378ed3..ecaaf2227 100644 --- a/coreapi/linphone_tunnel.h +++ b/coreapi/linphone_tunnel.h @@ -28,20 +28,59 @@ #include "linphonecore.h" + /** * @addtogroup tunnel * @{ **/ /** - * This set of methods enhance LinphoneCore functionalities in order to provide an easy to use API to - * - provision tunnel servers ip addresses and ports. This functionality is an option not implemented under GPL. - * - start/stop the tunneling service - * - perform auto-detection whether tunneling is required, based on a test of sending/receiving a flow of UDP packets. + * Linphone tunnel aims is to bypass IP traffic blocking due to aggressive firewalls which typically only authorize TCP traffic with destination port 443. + *
Its principle is tunneling all SIP and/or RTP traffic through a single secure https connection up to a detunnelizer server. + *
This set of methods enhance LinphoneCore functionalities in order to provide an easy to use API to + * \li provision tunnel servers IP addresses and ports. This functionality is an option not implemented under GPL. Availability can be check at runtime using function #linphone_core_tunnel_available + * \li start/stop the tunneling service + * \li perform auto-detection whether tunneling is required, based on a test of sending/receiving a flow of UDP packets. * * It takes in charge automatically the SIP registration procedure when connecting or disconnecting to a tunnel server. * No other action on LinphoneCore is required to enable full operation in tunnel mode. - **/ + * + *
Provision is done using object #LinphoneTunnelConfig created by function #linphone_tunnel_config_new(). Functions #linphone_tunnel_config_set_host + * and #linphone_tunnel_config_set_port allow to point to tunnel server IP/port. Once set, use function #linphone_tunnel_add_server to provision a tunnel server. + *
Finally tunnel mode configuration is achieved by function #linphone_tunnel_set_mode. + *
Tunnel connection status can be checked using function #linphone_tunnel_connected. + * + * Bellow pseudo code that can be use to configure, enable, check state and disable tunnel functionality: + * + * \code + LinphoneTunnel *tunnel = linphone_core_get_tunnel(linphone_core); + LinphoneTunnelConfig *config=linphone_tunnel_config_new(); //instantiate tunnel configuration + linphone_tunnel_config_set_host(config, "tunnel.linphone.org"); //set tunnel server host address + linphone_tunnel_config_set_port(config, 443); //set tunnel server port + linphone_tunnel_add_server(tunnel, config); //provision tunnel config + linphone_tunnel_set_mode(tunnel, LinphoneTunnelModeEnable); //activate the tunnel unconditional + + while (!linphone_tunnel_connected(tunnel)) { //wait for tunnel to be ready + linphone_core_iterate(linphone_core); //schedule core main loop + ms_sleep(100); //wait 100ms + } + + LinphoneCall *call = linphone_core_invite(linphone_core,"sip:foo@example.org"); //place an outgoing call + linphone_call_ref(call); //acquire a reference on the call to avoid deletion after completion + //... + linphone_core_terminate_call(linphone_core,call); + + while (linphone_call_get_state(call) != LinphoneCallReleased) { //wait for call to be in release state + linphone_core_iterate(linphone_core); //schedule core main loop + ms_sleep(100); //wait 100ms + } + + linphone_tunnel_set_mode(tunnel, LinphoneTunnelModeDisable); //deactivate tunnel + linphone_call_unref(call); //release reference on the call + + \endcode +* +* **/ #ifdef __cplusplus extern "C" diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 3f0be84cd..5b550a245 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -240,7 +240,7 @@ static int get_max_codec_sample_rate(const MSList *codecs){ for(it=codecs;it!=NULL;it=it->next){ PayloadType *pt=(PayloadType*)it->data; int sample_rate; - + if( strcasecmp("G722",pt->mime_type) == 0 ){ /* G722 spec says 8000 but the codec actually requires 16000 */ sample_rate = 16000; @@ -283,7 +283,7 @@ static void linphone_core_assign_payload_type_numbers(LinphoneCore *lc, MSList * for (elem=codecs; elem!=NULL; elem=elem->next){ PayloadType *pt=(PayloadType*)elem->data; int number=payload_type_get_number(pt); - + /*check if number is duplicated: it could be the case if the remote forced us to use a mapping with a previous offer*/ if (number!=-1 && !(pt->flags & PAYLOAD_TYPE_FROZEN_NUMBER)){ if (!is_payload_type_number_available(codecs, number, pt)){ @@ -291,7 +291,7 @@ static void linphone_core_assign_payload_type_numbers(LinphoneCore *lc, MSList * number=-1; /*need to be re-assigned*/ } } - + if (number==-1){ while(dyn_number<127){ if (is_payload_type_number_available(codecs, dyn_number, NULL)){ @@ -364,7 +364,7 @@ static MSList *make_codec_list(LinphoneCore *lc, CodecConstraints * hints, SalSt for(it=codecs;it!=NULL;it=it->next){ PayloadType *pt=(PayloadType*)it->data; int num; - + if (!(pt->flags & PAYLOAD_TYPE_ENABLED)) continue; if (hints->bandwidth_limit>0 && !linphone_core_is_payload_type_usable_for_bandwidth(lc,pt,hints->bandwidth_limit)){ @@ -376,14 +376,14 @@ static MSList *make_codec_list(LinphoneCore *lc, CodecConstraints * hints, SalSt continue; } pt=payload_type_clone(pt); - + /*look for a previously assigned number for this codec*/ num=find_payload_type_number(hints->previously_used, pt); if (num!=-1){ payload_type_set_number(pt,num); payload_type_set_flag(pt, PAYLOAD_TYPE_FROZEN_NUMBER); } - + l=ms_list_append(l, pt); nb++; if ((hints->max_codecs > 0) && (nb >= hints->max_codecs)) break; @@ -568,8 +568,8 @@ static const char *linphone_call_get_bind_ip_for_stream(LinphoneCall *call, int static const char *linphone_call_get_public_ip_for_stream(LinphoneCall *call, int stream_index){ const char *public_ip=call->localip; - - if (stream_index<2 && call->media_ports[stream_index].multicast_ip[0]!='\0') + + if (stream_index<2 && call->media_ports[stream_index].multicast_ip[0]!='\0') public_ip=call->media_ports[stream_index].multicast_ip; return public_ip; } @@ -584,7 +584,7 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall * LinphoneAddress *addr; const char *subject; CodecConstraints codec_hints={0}; - + /*multicast is only set in case of outgoing call*/ if (call->dir == LinphoneCallOutgoing && linphone_core_audio_multicast_enabled(lc)) { md->streams[0].ttl=linphone_core_get_audio_multicast_ttl(lc); @@ -803,7 +803,7 @@ static void linphone_call_init_common(LinphoneCall *call, LinphoneAddress *from, linphone_core_get_video_port_range(call->core, &min_port, &max_port); port_config_set(call,1,min_port,max_port); - + if (call->dir==LinphoneCallOutgoing){ if ( linphone_core_audio_multicast_enabled(call->core)){ strncpy(call->media_ports[0].multicast_ip, @@ -817,7 +817,7 @@ static void linphone_call_init_common(LinphoneCall *call, LinphoneAddress *from, linphone_call_init_stats(&call->stats[LINPHONE_CALL_STATS_AUDIO], LINPHONE_CALL_STATS_AUDIO); linphone_call_init_stats(&call->stats[LINPHONE_CALL_STATS_VIDEO], LINPHONE_CALL_STATS_VIDEO); - + } void linphone_call_init_stats(LinphoneCallStats *stats, int type) { @@ -1285,12 +1285,6 @@ void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const call->log->status=LinphoneCallSuccess; call->log->connected_date_time=time(NULL); break; - case LinphoneCallStreamsRunning: - if (call->dtmfs_timer!=NULL){ - /*cancelling DTMF sequence, if any*/ - linphone_call_cancel_dtmfs(call); - } - break; case LinphoneCallReleased: #ifdef ANDROID ms_message("Call [%p] releases wifi/multicast lock",call); @@ -1300,7 +1294,13 @@ void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const break; default: break; + } + if(cstate!=LinphoneCallStreamsRunning) { + if (call->dtmfs_timer!=NULL){ + /*cancelling DTMF sequence, if any*/ + linphone_call_cancel_dtmfs(call); + } } linphone_core_notify_call_state_changed(lc,call,cstate,message); linphone_reporting_call_state_updated(call); @@ -1873,7 +1873,7 @@ void linphone_call_init_audio_stream(LinphoneCall *call){ if (call->audiostream != NULL) return; if (call->sessions[0].rtp_session==NULL){ call->audiostream=audiostream=audio_stream_new2(linphone_call_get_bind_ip_for_stream(call,0), - call->media_ports[0].mcast_rtp_port ? call->media_ports[0].mcast_rtp_port : call->media_ports[0].rtp_port, + call->media_ports[0].mcast_rtp_port ? call->media_ports[0].mcast_rtp_port : call->media_ports[0].rtp_port, call->media_ports[0].mcast_rtcp_port ? call->media_ports[0].mcast_rtcp_port : call->media_ports[0].rtcp_port); linphone_call_join_multicast_group(call, 0, &audiostream->ms); rtp_session_enable_network_simulation(call->audiostream->ms.sessions.rtp_session, &lc->net_conf.netsim_params); @@ -2091,9 +2091,7 @@ static void parametrize_equalizer(LinphoneCore *lc, AudioStream *st){ } void set_mic_gain_db(AudioStream *st, float gain){ - if (st->volsend){ - ms_filter_call_method(st->volsend,MS_VOLUME_SET_DB_GAIN,&gain); - }else ms_warning("Could not apply mic gain: gain control wasn't activated."); + audio_stream_set_mic_gain_db(st, gain); } void set_playback_gain_db(AudioStream *st, float gain){ @@ -2350,6 +2348,11 @@ void static start_dtls( MSMediaStreamSessions *sessions, const SalStreamDescrip void static start_dtls_on_all_streams(LinphoneCall *call) { SalMediaDescription *remote_desc = sal_call_get_remote_media_description(call->op); SalMediaDescription *result_desc = sal_call_get_final_media_description(call->op); + if( remote_desc == NULL || result_desc == NULL ){ + ms_warning("Invalid remote or result media description, disabling DTLS"); + return; + } + if (call->audiostream && (media_stream_get_state((const MediaStream *)call->audiostream) == MSStreamStarted))/*dtls must start at the end of ice*/ start_dtls(&call->audiostream->ms.sessions ,sal_media_description_find_best_stream(result_desc,SalAudio) @@ -2379,6 +2382,12 @@ void static set_dtls_fingerprint( MSMediaStreamSessions *sessions, const SalStr void static set_dtls_fingerprint_on_all_streams(LinphoneCall *call) { SalMediaDescription *remote_desc = sal_call_get_remote_media_description(call->op); SalMediaDescription *result_desc = sal_call_get_final_media_description(call->op); + + if( remote_desc == NULL || result_desc == NULL ){ + ms_warning("Invalid remote or final media desc, aborting DTLS fingerprinting"); + return; + } + if (call->audiostream && (media_stream_get_state((const MediaStream *)call->audiostream) == MSStreamStarted))/*dtls must start at the end of ice*/ set_dtls_fingerprint(&call->audiostream->ms.sessions ,sal_media_description_find_best_stream(result_desc,SalAudio) @@ -2419,7 +2428,7 @@ static void linphone_call_start_audio_stream(LinphoneCall *call, bool_t muted, b playfile=lc->play_file; recfile=lc->rec_file; call->audio_profile=make_profile(call,call->resultdesc,stream,&used_pt); - + if (used_pt!=-1){ call->current_params->audio_codec = rtp_profile_get_payload(call->audio_profile, used_pt); if (playcard==NULL) { @@ -2490,7 +2499,7 @@ static void linphone_call_start_audio_stream(LinphoneCall *call, bool_t muted, b configure_rtp_session_for_rtcp_xr(lc, call, SalAudio); if (is_multicast) rtp_session_set_multicast_ttl(call->audiostream->ms.sessions.rtp_session,stream->ttl); - + audio_stream_start_full( call->audiostream, call->audio_profile, @@ -2507,6 +2516,9 @@ static void linphone_call_start_audio_stream(LinphoneCall *call, bool_t muted, b use_ec ); post_configure_audio_streams(call, muted && !send_ringbacktone); + + media_stream_session_encryption_mandatory_enable(&call->audiostream->ms.sessions,linphone_core_is_media_encryption_mandatory(call->core)); + if (stream->dir==SalStreamSendOnly && playfile!=NULL){ int pause_time=500; ms_filter_call_method(call->audiostream->soundread,MS_FILE_PLAYER_LOOP,&pause_time); @@ -2639,6 +2651,7 @@ static void linphone_call_start_video_stream(LinphoneCall *call, bool_t all_inpu (linphone_core_rtcp_enabled(lc) && !is_multicast) ? (vstream->rtcp_port ? vstream->rtcp_port : vstream->rtp_port+1) : 0, used_pt, linphone_core_get_video_jittcomp(lc), cam); } + media_stream_session_encryption_mandatory_enable(&call->videostream->ms.sessions,linphone_core_is_media_encryption_mandatory(call->core)); } }else ms_warning("No video stream accepted."); }else{ @@ -2652,6 +2665,49 @@ static void linphone_call_start_video_stream(LinphoneCall *call, bool_t all_inpu #endif } +static void setZrtpCryptoTypesParameters(MSZrtpParams *params, LinphoneCore *lc) +{ + int i; + const MSCryptoSuite *srtp_suites; + + if (params == NULL) return; + if (lc == NULL) return; + + srtp_suites = linphone_core_get_srtp_crypto_suites(lc); + if (srtp_suites!=NULL) { + for(i=0; srtp_suites[i]!=MS_CRYPTO_SUITE_INVALID && iciphers[params->ciphersCount++] = MS_ZRTP_CIPHER_AES1; + params->authTags[params->authTagsCount++] = MS_ZRTP_AUTHTAG_HS32; + break; + case MS_AES_128_NO_AUTH: + params->ciphers[params->ciphersCount++] = MS_ZRTP_CIPHER_AES1; + break; + case MS_NO_CIPHER_SHA1_80: + params->authTags[params->authTagsCount++] = MS_ZRTP_AUTHTAG_HS80; + break; + case MS_AES_128_SHA1_80: + params->ciphers[params->ciphersCount++] = MS_ZRTP_CIPHER_AES1; + params->authTags[params->authTagsCount++] = MS_ZRTP_AUTHTAG_HS80; + break; + case MS_AES_256_SHA1_80: + params->ciphers[params->ciphersCount++] = MS_ZRTP_CIPHER_AES3; + params->authTags[params->authTagsCount++] = MS_ZRTP_AUTHTAG_HS80; + break; + case MS_AES_256_SHA1_32: + params->ciphers[params->ciphersCount++] = MS_ZRTP_CIPHER_AES3; + params->authTags[params->authTagsCount++] = MS_ZRTP_AUTHTAG_HS80; + break; + case MS_CRYPTO_SUITE_INVALID: + break; + } + } + } + + params->keyAgreementsCount = linphone_core_get_zrtp_key_agreements(lc, params->keyAgreements); +} + void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_muted, bool_t send_ringbacktone){ LinphoneCore *lc=call->core; bool_t use_arc=linphone_core_adaptive_rate_control_enabled(lc); @@ -2696,6 +2752,8 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut memset(¶ms,0,sizeof(MSZrtpParams)); /*call->current_params.media_encryption will be set later when zrtp is activated*/ params.zid_file=lc->zrtp_secrets_cache; + params.uri= linphone_address_as_string_uri_only((call->dir==LinphoneCallIncoming) ? call->log->from : call->log->to); + setZrtpCryptoTypesParameters(¶ms,call->core); audio_stream_enable_zrtp(call->audiostream,¶ms); #if VIDEO_ENABLED if (media_stream_secured((MediaStream *)call->audiostream) && media_stream_get_state((MediaStream *)call->videostream) == MSStreamStarted) { @@ -3246,7 +3304,7 @@ void linphone_call_stop_recording(LinphoneCall *call){ static void report_bandwidth(LinphoneCall *call, MediaStream *as, MediaStream *vs){ bool_t as_active = as ? (media_stream_get_state(as) == MSStreamStarted) : FALSE; bool_t vs_active = vs ? (media_stream_get_state(vs) == MSStreamStarted) : FALSE; - + call->stats[LINPHONE_CALL_STATS_AUDIO].download_bandwidth=(as_active) ? (media_stream_get_down_bw(as)*1e-3) : 0; call->stats[LINPHONE_CALL_STATS_AUDIO].upload_bandwidth=(as_active) ? (media_stream_get_up_bw(as)*1e-3) : 0; call->stats[LINPHONE_CALL_STATS_VIDEO].download_bandwidth=(vs_active) ? (media_stream_get_down_bw(vs)*1e-3) : 0; @@ -3256,18 +3314,18 @@ static void report_bandwidth(LinphoneCall *call, MediaStream *as, MediaStream *v call->stats[LINPHONE_CALL_STATS_VIDEO].rtcp_download_bandwidth=(vs_active) ? (media_stream_get_rtcp_down_bw(vs)*1e-3) : 0; call->stats[LINPHONE_CALL_STATS_VIDEO].rtcp_upload_bandwidth=(vs_active) ? (media_stream_get_rtcp_up_bw(vs)*1e-3) : 0; - ms_message("Bandwidth usage for call [%p]: audio[ rtp]=[d=%.1f,u=%.1f], video[ rtp]=[d=%.1f,u=%.1f] kbit/sec", - call, - call->stats[LINPHONE_CALL_STATS_AUDIO].download_bandwidth, - call->stats[LINPHONE_CALL_STATS_AUDIO].upload_bandwidth , - call->stats[LINPHONE_CALL_STATS_VIDEO].download_bandwidth, - call->stats[LINPHONE_CALL_STATS_VIDEO].upload_bandwidth - ); - ms_message(" [rtcp]=[d=%.1f,u=%.1f], video[rtcp]=[d=%.1f,u=%.1f] kbit/sec", - call->stats[LINPHONE_CALL_STATS_AUDIO].rtcp_download_bandwidth, - call->stats[LINPHONE_CALL_STATS_AUDIO].rtcp_upload_bandwidth , - call->stats[LINPHONE_CALL_STATS_VIDEO].rtcp_download_bandwidth, - call->stats[LINPHONE_CALL_STATS_VIDEO].rtcp_upload_bandwidth + ms_message( "Bandwidth usage for call [%p]:\n" + "\tRTP audio=[d=%5.1f,u=%5.1f], video=[d=%5.1f,u=%5.1f] kbits/sec\n" + "\tRTCP audio=[d=%5.1f,u=%5.1f], video=[d=%5.1f,u=%5.1f] kbits/sec", + call, + call->stats[LINPHONE_CALL_STATS_AUDIO].download_bandwidth, + call->stats[LINPHONE_CALL_STATS_AUDIO].upload_bandwidth, + call->stats[LINPHONE_CALL_STATS_VIDEO].download_bandwidth, + call->stats[LINPHONE_CALL_STATS_VIDEO].upload_bandwidth, + call->stats[LINPHONE_CALL_STATS_AUDIO].rtcp_download_bandwidth, + call->stats[LINPHONE_CALL_STATS_AUDIO].rtcp_upload_bandwidth, + call->stats[LINPHONE_CALL_STATS_VIDEO].rtcp_download_bandwidth, + call->stats[LINPHONE_CALL_STATS_VIDEO].rtcp_upload_bandwidth ); } diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index ae7a22222..4aa402f81 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1,6 +1,7 @@ /* linphone Copyright (C) 2000 Simon MORLAT (simon.morlat@linphone.org) +Copyright (C) 2010 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 @@ -189,7 +190,16 @@ static void linphone_core_log_collection_handler(OrtpLogLevel level, const char struct stat statbuf; if (liblinphone_log_func != NULL) { +#ifndef WIN32 + va_list args_copy; + va_copy(args_copy, args); + liblinphone_log_func(level, fmt, args_copy); + va_end(args_copy); +#else + /* This works on 32 bits, luckily. */ + /* TODO: va_copy is available in Visual Studio 2013. */ liblinphone_log_func(level, fmt, args); +#endif } ortp_gettimeofday(&tp, NULL); @@ -323,27 +333,31 @@ void linphone_core_enable_log_collection(LinphoneLogCollectionState state) { } } -static void delete_log_collection_upload_file(void) { +static void clean_log_collection_upload_context(LinphoneCore *lc) { char *filename = ms_strdup_printf("%s/%s_log.%s", liblinphone_log_collection_path ? liblinphone_log_collection_path : LOG_COLLECTION_DEFAULT_PATH, liblinphone_log_collection_prefix ? liblinphone_log_collection_prefix : LOG_COLLECTION_DEFAULT_PREFIX, COMPRESSED_LOG_COLLECTION_EXTENSION); unlink(filename); ms_free(filename); + if (lc && lc->log_collection_upload_information) { + ms_free(lc->log_collection_upload_information); + lc->log_collection_upload_information=NULL; + } } static void process_io_error_upload_log_collection(void *data, const belle_sip_io_error_event_t *event) { LinphoneCore *core = (LinphoneCore *)data; ms_error("I/O Error during log collection upload to %s", linphone_core_get_log_collection_upload_server_url(core)); linphone_core_notify_log_collection_upload_state_changed(core, LinphoneCoreLogCollectionUploadStateNotDelivered, "I/O Error"); - delete_log_collection_upload_file(); + clean_log_collection_upload_context(core); } static void process_auth_requested_upload_log_collection(void *data, belle_sip_auth_event_t *event) { LinphoneCore *core = (LinphoneCore *)data; ms_error("Error during log collection upload: auth requested to connect %s", linphone_core_get_log_collection_upload_server_url(core)); linphone_core_notify_log_collection_upload_state_changed(core, LinphoneCoreLogCollectionUploadStateNotDelivered, "Auth requested"); - delete_log_collection_upload_file(); + clean_log_collection_upload_context(core); } /** @@ -470,7 +484,7 @@ static void process_response_from_post_file_log_collection(void *data, const bel if (file_url != NULL) { linphone_core_notify_log_collection_upload_state_changed(core, LinphoneCoreLogCollectionUploadStateDelivered, (const char *)file_url); } - delete_log_collection_upload_file(); + clean_log_collection_upload_context(core); } } } @@ -609,7 +623,7 @@ char * linphone_core_compress_log_collection() { void linphone_core_reset_log_collection() { char *filename; ortp_mutex_lock(&liblinphone_log_collection_mutex); - delete_log_collection_upload_file(); + clean_log_collection_upload_context(NULL); filename = ms_strdup_printf("%s/%s1.log", liblinphone_log_collection_path ? liblinphone_log_collection_path : LOG_COLLECTION_DEFAULT_PATH, liblinphone_log_collection_prefix ? liblinphone_log_collection_prefix : LOG_COLLECTION_DEFAULT_PREFIX); @@ -890,6 +904,8 @@ static void sip_config_read(LinphoneCore *lc) tmp=lp_config_get_int(lc->config,"sip","guess_hostname",1); linphone_core_set_guess_hostname(lc,tmp); + tmp=lp_config_get_int(lc->config,"sip","lime",FALSE); + linphone_core_enable_lime(lc,tmp); tmp=lp_config_get_int(lc->config,"sip","inc_timeout",30); linphone_core_set_inc_timeout(lc,tmp); @@ -1075,7 +1091,10 @@ static bool_t get_codec(LinphoneCore *lc, SalStreamType type, int index, Payload pt=find_payload(type==SalAudio ? lc->default_audio_codecs : lc->default_video_codecs,mime,rate,channels,fmtp); if (!pt){ MSList **default_list=(type==SalAudio) ? &lc->default_audio_codecs : &lc->default_video_codecs; - ms_warning("Codec %s/%i read from conf is not in the default list.",mime,rate); + if (type==SalAudio) + ms_warning("Codec %s/%i/%i read from conf is not in the default list.",mime,rate,channels); + else + ms_warning("Codec %s/%i read from conf is not in the default list.",mime,rate); pt=payload_type_new(); pt->type=(type==SalAudio) ? PAYLOAD_AUDIO_PACKETIZED : PAYLOAD_VIDEO; pt->mime_type=ortp_strdup(mime); @@ -1086,6 +1105,7 @@ static bool_t get_codec(LinphoneCore *lc, SalStreamType type, int index, Payload *default_list=ms_list_append(*default_list, pt); } if (enabled ) pt->flags|=PAYLOAD_TYPE_ENABLED; + else pt->flags&=~PAYLOAD_TYPE_ENABLED; *ret=pt; return TRUE; } @@ -1292,7 +1312,7 @@ void linphone_core_set_adaptive_rate_algorithm(LinphoneCore *lc, const char* alg * See linphone_core_set_adaptive_rate_algorithm(). **/ const char * linphone_core_get_adaptive_rate_algorithm(const LinphoneCore *lc){ - return lp_config_get_string(lc->config, "net", "adaptive_rate_algorithm", "Simple"); + return lp_config_get_string(lc->config, "net", "adaptive_rate_algorithm", "Stateful"); } bool_t linphone_core_rtcp_enabled(const LinphoneCore *lc){ @@ -1473,7 +1493,7 @@ static void misc_config_read(LinphoneCore *lc) { LpConfig *config=lc->config; const char *uuid; - lc->max_call_logs=lp_config_get_int(config,"misc","history_max_size",15); + lc->max_call_logs=lp_config_get_int(config,"misc","history_max_size",30); lc->max_calls=lp_config_get_int(config,"misc","max_calls",NB_MAX_CALLS); uuid=lp_config_get_string(config,"misc","uuid",NULL); @@ -1615,7 +1635,7 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab memcpy(local_vtable,vtable,sizeof(LinphoneCoreVTable)); - lc->vtables=ms_list_append(lc->vtables,local_vtable); + _linphone_core_add_listener(lc, local_vtable, TRUE); linphone_core_set_state(lc,LinphoneGlobalStartup,"Starting up"); ortp_init(); @@ -1810,6 +1830,20 @@ bool_t linphone_core_get_guess_hostname(LinphoneCore *lc){ return lc->sip_conf.guess_hostname; } +/** + * Tells to LinphoneCore to use Linphone Instant Messaging encryption + * + */ +void linphone_core_enable_lime(LinphoneCore *lc, bool_t val){ + if (linphone_core_ready(lc)){ + lp_config_set_int(lc->config,"sip","lime",val); + } +} + +bool_t linphone_core_lime_enabled(const LinphoneCore *lc){ + return lp_config_get_int(lc->config,"sip", "lime", FALSE); +} + /** * Same as linphone_core_get_primary_contact() but the result is a LinphoneAddress object * instead of const char* @@ -4768,8 +4802,12 @@ bool_t linphone_core_echo_limiter_enabled(const LinphoneCore *lc){ } static void linphone_core_mute_audio_stream(LinphoneCore *lc, AudioStream *st, bool_t val) { - audio_stream_set_mic_gain(st, - (val==TRUE) ? 0 : pow(10,lc->sound_conf.soft_mic_lev/10)); + if (val) { + audio_stream_set_mic_gain(st, 0); + } else { + audio_stream_set_mic_gain_db(st, lc->sound_conf.soft_mic_lev); + } + if ( linphone_core_get_rtp_no_xmit_on_audio_mute(lc) ){ audio_stream_mute_rtp(st,val); } @@ -6341,7 +6379,7 @@ static void linphone_core_uninit(LinphoneCore *lc) ms_exit(); linphone_core_set_state(lc,LinphoneGlobalOff,"Off"); linphone_core_deactivate_log_serialization_if_needed(); - ms_list_free_with_data(lc->vtables,(void (*)(void *))linphone_core_v_table_destroy); + ms_list_free_with_data(lc->vtable_refs,(void (*)(void *))v_table_reference_destroy); } static void set_network_reachable(LinphoneCore* lc,bool_t isReachable, time_t curtime){ @@ -7123,144 +7161,6 @@ int linphone_payload_type_get_channels(const LinphonePayloadType *pt) { return pt->channels; } -LinphoneCoreVTable *linphone_core_v_table_new() { - return ms_new0(LinphoneCoreVTable,1); -} - -void linphone_core_v_table_set_user_data(LinphoneCoreVTable *table, void *data) { - table->user_data = data; -} - -void* linphone_core_v_table_get_user_data(LinphoneCoreVTable *table) { - return table->user_data; -} - -void linphone_core_v_table_destroy(LinphoneCoreVTable* table) { - ms_free(table); -} - -LinphoneCoreVTable *linphone_core_get_current_vtable(LinphoneCore *lc) { - return lc->current_vtable; -} - -#define NOTIFY_IF_EXIST(function_name) \ - MSList* iterator; \ - ms_message ("Linphone core [%p] notifying [%s]",lc,#function_name);\ - for (iterator=lc->vtables; iterator!=NULL; iterator=iterator->next) \ - if ((lc->current_vtable=((LinphoneCoreVTable*)(iterator->data)))->function_name)\ - ((LinphoneCoreVTable*)(iterator->data))->function_name -void linphone_core_notify_global_state_changed(LinphoneCore *lc, LinphoneGlobalState gstate, const char *message) { - NOTIFY_IF_EXIST(global_state_changed)(lc,gstate,message); -} -void linphone_core_notify_call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *message){ - NOTIFY_IF_EXIST(call_state_changed)(lc,call,cstate,message); -} -void linphone_core_notify_call_encryption_changed(LinphoneCore *lc, LinphoneCall *call, bool_t on, const char *authentication_token) { - NOTIFY_IF_EXIST(call_encryption_changed)(lc,call,on,authentication_token); -} -void linphone_core_notify_registration_state_changed(LinphoneCore *lc, LinphoneProxyConfig *cfg, LinphoneRegistrationState cstate, const char *message){ - NOTIFY_IF_EXIST(registration_state_changed)(lc,cfg,cstate,message); -} -void linphone_core_notify_show_interface(LinphoneCore *lc){ - NOTIFY_IF_EXIST(show)(lc); -} -void linphone_core_notify_display_status(LinphoneCore *lc, const char *message) { - NOTIFY_IF_EXIST(display_status)(lc,message); -} -void linphone_core_notify_display_message(LinphoneCore *lc, const char *message){ - NOTIFY_IF_EXIST(display_message)(lc,message); -} -void linphone_core_notify_display_warning(LinphoneCore *lc, const char *message){ - NOTIFY_IF_EXIST(display_warning)(lc,message); -} -void linphone_core_notify_display_url(LinphoneCore *lc, const char *message, const char *url){ - NOTIFY_IF_EXIST(display_url)(lc,message,url); -} -void linphone_core_notify_notify_presence_received(LinphoneCore *lc, LinphoneFriend * lf){ - NOTIFY_IF_EXIST(notify_presence_received)(lc,lf); -} -void linphone_core_notify_new_subscription_requested(LinphoneCore *lc, LinphoneFriend *lf, const char *url){ - NOTIFY_IF_EXIST(new_subscription_requested)(lc,lf,url); -} -void linphone_core_notify_auth_info_requested(LinphoneCore *lc, const char *realm, const char *username, const char *domain){ - NOTIFY_IF_EXIST(auth_info_requested)(lc,realm,username,domain); -} -void linphone_core_notify_call_log_updated(LinphoneCore *lc, LinphoneCallLog *newcl){ - NOTIFY_IF_EXIST(call_log_updated)(lc,newcl); -} -void linphone_core_notify_text_message_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from, const char *message){ - NOTIFY_IF_EXIST(text_received)(lc,room,from,message); -} -void linphone_core_notify_message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *message){ - NOTIFY_IF_EXIST(message_received)(lc,room,message); -} -void linphone_core_notify_file_transfer_recv(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, const char* buff, size_t size) { - NOTIFY_IF_EXIST(file_transfer_recv)(lc,message,content,buff,size); -} -void linphone_core_notify_file_transfer_send(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, char* buff, size_t* size) { - NOTIFY_IF_EXIST(file_transfer_send)(lc,message,content,buff,size); -} -void linphone_core_notify_file_transfer_progress_indication(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t total) { - NOTIFY_IF_EXIST(file_transfer_progress_indication)(lc,message,content,offset,total); -} -void linphone_core_notify_is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room) { - NOTIFY_IF_EXIST(is_composing_received)(lc,room); -} -void linphone_core_notify_dtmf_received(LinphoneCore* lc, LinphoneCall *call, int dtmf) { - NOTIFY_IF_EXIST(dtmf_received)(lc,call,dtmf); -} -bool_t linphone_core_dtmf_received_has_listener(const LinphoneCore* lc) { - MSList* iterator; - for (iterator=lc->vtables; iterator!=NULL; iterator=iterator->next) - if (((LinphoneCoreVTable*)(iterator->data))->dtmf_received) - return TRUE; - return FALSE; -} -void linphone_core_notify_refer_received(LinphoneCore *lc, const char *refer_to) { - NOTIFY_IF_EXIST(refer_received)(lc,refer_to); -} -void linphone_core_notify_buddy_info_updated(LinphoneCore *lc, LinphoneFriend *lf) { - NOTIFY_IF_EXIST(buddy_info_updated)(lc,lf); -} -void linphone_core_notify_transfer_state_changed(LinphoneCore *lc, LinphoneCall *transfered, LinphoneCallState new_call_state) { - NOTIFY_IF_EXIST(transfer_state_changed)(lc,transfered,new_call_state); -} -void linphone_core_notify_call_stats_updated(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallStats *stats) { - NOTIFY_IF_EXIST(call_stats_updated)(lc,call,stats); -} -void linphone_core_notify_info_received(LinphoneCore *lc, LinphoneCall *call, const LinphoneInfoMessage *msg) { - NOTIFY_IF_EXIST(info_received)(lc,call,msg); -} -void linphone_core_notify_configuring_status(LinphoneCore *lc, LinphoneConfiguringState status, const char *message) { - NOTIFY_IF_EXIST(configuring_status)(lc,status,message); -} -void linphone_core_notify_network_reachable(LinphoneCore *lc, bool_t reachable) { - NOTIFY_IF_EXIST(network_reachable)(lc,reachable); -} -void linphone_core_notify_notify_received(LinphoneCore *lc, LinphoneEvent *lev, const char *notified_event, const LinphoneContent *body) { - NOTIFY_IF_EXIST(notify_received)(lc,lev,notified_event,body); -} -void linphone_core_notify_subscription_state_changed(LinphoneCore *lc, LinphoneEvent *lev, LinphoneSubscriptionState state) { - NOTIFY_IF_EXIST(subscription_state_changed)(lc,lev,state); -} -void linphone_core_notify_publish_state_changed(LinphoneCore *lc, LinphoneEvent *lev, LinphonePublishState state) { - NOTIFY_IF_EXIST(publish_state_changed)(lc,lev,state); -} -void linphone_core_notify_log_collection_upload_state_changed(LinphoneCore *lc, LinphoneCoreLogCollectionUploadState state, const char *info) { - NOTIFY_IF_EXIST(log_collection_upload_state_changed)(lc, state, info); -} -void linphone_core_notify_log_collection_upload_progress_indication(LinphoneCore *lc, size_t offset, size_t total) { - NOTIFY_IF_EXIST(log_collection_upload_progress_indication)(lc, offset, total); -} -void linphone_core_add_listener(LinphoneCore *lc, LinphoneCoreVTable *vtable) { - ms_message("Vtable [%p] registered on core [%p]",lc,vtable); - lc->vtables=ms_list_append(lc->vtables,vtable); -} -void linphone_core_remove_listener(LinphoneCore *lc, const LinphoneCoreVTable *vtable) { - ms_message("Vtable [%p] unregistered on core [%p]",lc,vtable); - lc->vtables=ms_list_remove(lc->vtables,(void*)vtable); -} - int linphone_core_set_audio_multicast_addr(LinphoneCore *lc, const char* ip) { char* new_value; if (ip && !ms_is_multicast(ip)) { @@ -7289,7 +7189,6 @@ const char* linphone_core_get_audio_multicast_addr(const LinphoneCore *lc) { return lc->rtp_conf.audio_multicast_addr; } - const char* linphone_core_get_video_multicast_addr(const LinphoneCore *lc){ return lc->rtp_conf.video_multicast_addr; } diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 5f1e4f5c2..4f642acc3 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -200,9 +200,9 @@ LINPHONE_PUBLIC int linphone_error_info_get_protocol_code(const LinphoneErrorInf /* linphone dictionary */ LINPHONE_PUBLIC LinphoneDictionary* linphone_dictionary_new(void); -LinphoneDictionary * linphone_dictionary_clone(const LinphoneDictionary* src); -LinphoneDictionary * linphone_dictionary_ref(LinphoneDictionary* obj); -void linphone_dictionary_unref(LinphoneDictionary* obj); +LINPHONE_PUBLIC LinphoneDictionary * linphone_dictionary_clone(const LinphoneDictionary* src); +LINPHONE_PUBLIC LinphoneDictionary * linphone_dictionary_ref(LinphoneDictionary* obj); +LINPHONE_PUBLIC void linphone_dictionary_unref(LinphoneDictionary* obj); LINPHONE_PUBLIC void linphone_dictionary_set_int(LinphoneDictionary* obj, const char* key, int value); LINPHONE_PUBLIC int linphone_dictionary_get_int(LinphoneDictionary* obj, const char* key, int default_value); LINPHONE_PUBLIC void linphone_dictionary_set_string(LinphoneDictionary* obj, const char* key, const char*value); @@ -218,14 +218,14 @@ LINPHONE_PUBLIC void linphone_dictionary_foreach( const LinphoneDictionary* obj, * @return a #LinphoneDictionary with all the keys from a section, or NULL if the section doesn't exist * @ingroup misc */ -LinphoneDictionary* lp_config_section_to_dict( const LpConfig* lpconfig, const char* section ); +LINPHONE_PUBLIC LinphoneDictionary* lp_config_section_to_dict( const LpConfig* lpconfig, const char* section ); /** * Loads a dictionary into a section of the lpconfig. If the section doesn't exist it is created. * Overwrites existing keys, creates non-existing keys. * @ingroup misc */ -void lp_config_load_dict_to_section( LpConfig* lpconfig, const char* section, const LinphoneDictionary* dict); +LINPHONE_PUBLIC void lp_config_load_dict_to_section( LpConfig* lpconfig, const char* section, const LinphoneDictionary* dict); /** @@ -583,15 +583,15 @@ typedef struct _LinphonePlayer LinphonePlayer; **/ typedef void (*LinphonePlayerEofCallback)(struct _LinphonePlayer *obj, void *user_data); -int linphone_player_open(LinphonePlayer *obj, const char *filename, LinphonePlayerEofCallback, void *user_data); -int linphone_player_start(LinphonePlayer *obj); -int linphone_player_pause(LinphonePlayer *obj); -int linphone_player_seek(LinphonePlayer *obj, int time_ms); -MSPlayerState linphone_player_get_state(LinphonePlayer *obj); -int linphone_player_get_duration(LinphonePlayer *obj); -int linphone_player_get_current_position(LinphonePlayer *obj); -void linphone_player_close(LinphonePlayer *obj); -void linphone_player_destroy(LinphonePlayer *obj); +LINPHONE_PUBLIC int linphone_player_open(LinphonePlayer *obj, const char *filename, LinphonePlayerEofCallback, void *user_data); +LINPHONE_PUBLIC int linphone_player_start(LinphonePlayer *obj); +LINPHONE_PUBLIC int linphone_player_pause(LinphonePlayer *obj); +LINPHONE_PUBLIC int linphone_player_seek(LinphonePlayer *obj, int time_ms); +LINPHONE_PUBLIC MSPlayerState linphone_player_get_state(LinphonePlayer *obj); +LINPHONE_PUBLIC int linphone_player_get_duration(LinphonePlayer *obj); +LINPHONE_PUBLIC int linphone_player_get_current_position(LinphonePlayer *obj); +LINPHONE_PUBLIC void linphone_player_close(LinphonePlayer *obj); +LINPHONE_PUBLIC void linphone_player_destroy(LinphonePlayer *obj); /** * @brief Create an independent media file player. @@ -1062,7 +1062,7 @@ LINPHONE_PUBLIC const char* linphone_proxy_config_get_transport(const LinphonePr /* destruction is called automatically when removing the proxy config */ LINPHONE_PUBLIC void linphone_proxy_config_destroy(LinphoneProxyConfig *cfg); LINPHONE_PUBLIC void linphone_proxy_config_set_sip_setup(LinphoneProxyConfig *cfg, const char *type); -SipSetupContext *linphone_proxy_config_get_sip_setup_context(LinphoneProxyConfig *cfg); +LINPHONE_PUBLIC SipSetupContext *linphone_proxy_config_get_sip_setup_context(LinphoneProxyConfig *cfg); LINPHONE_PUBLIC SipSetup *linphone_proxy_config_get_sip_setup(LinphoneProxyConfig *cfg); /** @@ -1186,19 +1186,19 @@ typedef struct _LinphoneAccountCreator{ bool_t succeeded; }LinphoneAccountCreator; -LinphoneAccountCreator *linphone_account_creator_new(LinphoneCore *core, const char *type); -void linphone_account_creator_set_username(LinphoneAccountCreator *obj, const char *username); -void linphone_account_creator_set_password(LinphoneAccountCreator *obj, const char *password); -void linphone_account_creator_set_domain(LinphoneAccountCreator *obj, const char *domain); -void linphone_account_creator_set_route(LinphoneAccountCreator *obj, const char *route); -void linphone_account_creator_set_email(LinphoneAccountCreator *obj, const char *email); -void linphone_account_creator_set_suscribe(LinphoneAccountCreator *obj, int suscribre); -const char * linphone_account_creator_get_username(LinphoneAccountCreator *obj); -const char * linphone_account_creator_get_domain(LinphoneAccountCreator *obj); -int linphone_account_creator_test_existence(LinphoneAccountCreator *obj); -int linphone_account_creator_test_validation(LinphoneAccountCreator *obj); -LinphoneProxyConfig * linphone_account_creator_validate(LinphoneAccountCreator *obj); -void linphone_account_creator_destroy(LinphoneAccountCreator *obj); +LINPHONE_PUBLIC LinphoneAccountCreator *linphone_account_creator_new(LinphoneCore *core, const char *type); +LINPHONE_PUBLIC void linphone_account_creator_set_username(LinphoneAccountCreator *obj, const char *username); +LINPHONE_PUBLIC void linphone_account_creator_set_password(LinphoneAccountCreator *obj, const char *password); +LINPHONE_PUBLIC void linphone_account_creator_set_domain(LinphoneAccountCreator *obj, const char *domain); +LINPHONE_PUBLIC void linphone_account_creator_set_route(LinphoneAccountCreator *obj, const char *route); +LINPHONE_PUBLIC void linphone_account_creator_set_email(LinphoneAccountCreator *obj, const char *email); +LINPHONE_PUBLIC void linphone_account_creator_set_suscribe(LinphoneAccountCreator *obj, int suscribre); +LINPHONE_PUBLIC const char * linphone_account_creator_get_username(LinphoneAccountCreator *obj); +LINPHONE_PUBLIC const char * linphone_account_creator_get_domain(LinphoneAccountCreator *obj); +LINPHONE_PUBLIC int linphone_account_creator_test_existence(LinphoneAccountCreator *obj); +LINPHONE_PUBLIC int linphone_account_creator_test_validation(LinphoneAccountCreator *obj); +LINPHONE_PUBLIC LinphoneProxyConfig * linphone_account_creator_validate(LinphoneAccountCreator *obj); +LINPHONE_PUBLIC void linphone_account_creator_destroy(LinphoneAccountCreator *obj); struct _LinphoneAuthInfo; @@ -1890,7 +1890,7 @@ 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 */ - void *user_data; + void *user_data; /**NewGlobalRef(jlistener); - for (iterator = core->vtables; iterator != NULL; ) { - LinphoneCoreVTable *vTable = (LinphoneCoreVTable*)(iterator->data); + for (iterator = core->vtable_refs; iterator != NULL; ) { + VTableReference *ref=(VTableReference*)(iterator->data); + LinphoneCoreVTable *vTable = ref->valid ? ref->vtable : NULL; iterator = iterator->next; //Because linphone_core_remove_listener may change the list if (vTable) { LinphoneCoreData *data = (LinphoneCoreData*) linphone_core_v_table_get_user_data(vTable); @@ -1965,15 +1968,31 @@ extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_startEchoCalibration(JNI } -extern "C" jboolean Java_org_linphone_core_LinphoneCoreImpl_needsEchoCalibration(JNIEnv *env, jobject thiz, jlong lc){ +extern "C" jboolean Java_org_linphone_core_LinphoneCoreImpl_needsEchoCalibration(JNIEnv *env, jobject thiz, jlong lc) { MSSndCard *sndcard; - MSSndCardManager *m=ms_snd_card_manager_get(); - const char *card=linphone_core_get_capture_device((LinphoneCore*)lc); - sndcard=ms_snd_card_manager_get_card(m,card); - if (sndcard == NULL){ + MSSndCardManager *m = ms_snd_card_manager_get(); + const char *card = linphone_core_get_capture_device((LinphoneCore*)lc); + sndcard = ms_snd_card_manager_get_card(m, card); + if (sndcard == NULL) { ms_error("Could not get soundcard %s", card); return TRUE; } + + if (ms_snd_card_get_capabilities(sndcard) & MS_SND_CARD_CAP_BUILTIN_ECHO_CANCELLER) return FALSE; + if (ms_snd_card_get_minimal_latency(sndcard) != 0) return FALSE; + return TRUE; +} + +extern "C" jboolean Java_org_linphone_core_LinphoneCoreImpl_needsEchoCanceler(JNIEnv *env, jobject thiz, jlong lc) { + MSSndCard *sndcard; + MSSndCardManager *m = ms_snd_card_manager_get(); + const char *card = linphone_core_get_capture_device((LinphoneCore*)lc); + sndcard = ms_snd_card_manager_get_card(m, card); + if (sndcard == NULL) { + ms_error("Could not get soundcard %s", card); + return TRUE; + } + if (ms_snd_card_get_capabilities(sndcard) & MS_SND_CARD_CAP_BUILTIN_ECHO_CANCELLER) return FALSE; return TRUE; } @@ -3046,6 +3065,8 @@ extern "C" jlong Java_org_linphone_core_LinphoneChatRoomImpl_createFileTransferM return (jlong) message; } + + extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_cancelFileTransfer(JNIEnv* env, jobject thiz, jlong ptr) { linphone_chat_message_cancel_file_transfer((LinphoneChatMessage *)ptr); } @@ -3193,6 +3214,105 @@ extern "C" jint Java_org_linphone_core_LinphoneChatMessageImpl_getStorageId(JNIE return (jint) linphone_chat_message_get_storage_id((LinphoneChatMessage*)ptr); } +extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_setFileTransferFilepath(JNIEnv* env + ,jobject thiz + ,jlong ptr, jstring jpath) { + const char* path = env->GetStringUTFChars(jpath, NULL); + linphone_chat_message_set_file_transfer_filepath((LinphoneChatMessage*)ptr, path); + env->ReleaseStringUTFChars(jpath, path); +} + +extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_downloadFile(JNIEnv* env + ,jobject thiz + ,jlong ptr) { + linphone_chat_message_download_file((LinphoneChatMessage*)ptr); +} + +static void message_state_changed(LinphoneChatMessage* msg, LinphoneChatMessageState state) { + JNIEnv *env = 0; + jint result = jvm->AttachCurrentThread(&env,NULL); + if (result != 0) { + ms_error("cannot attach VM\n"); + return; + } + + jobject listener = (jobject) msg->cb_ud; + jclass clazz = (jclass) env->GetObjectClass(listener); + jmethodID method = env->GetMethodID(clazz, "onLinphoneChatMessageStateChanged","(Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneChatMessage$State;)V"); + jobject jmessage = getChatMessage(env, msg); + + jclass chatMessageStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneChatMessage$State")); + jmethodID chatMessageStateFromIntId = env->GetStaticMethodID(chatMessageStateClass, "fromInt","(I)Lorg/linphone/core/LinphoneChatMessage$State;"); + env->CallVoidMethod(listener, method, jmessage, env->CallStaticObjectMethod(chatMessageStateClass, chatMessageStateFromIntId, (jint)state)); + + if (state == LinphoneChatMessageStateDelivered || state == LinphoneChatMessageStateNotDelivered) { + env->DeleteGlobalRef(listener); + } +} + +static void file_transfer_progress_indication(LinphoneChatMessage *msg, const LinphoneContent* content, size_t offset, size_t total) { + JNIEnv *env = 0; + jint result = jvm->AttachCurrentThread(&env,NULL); + if (result != 0) { + ms_error("cannot attach VM\n"); + return; + } + + jobject listener = (jobject) msg->cb_ud; + jclass clazz = (jclass) env->GetObjectClass(listener); + jmethodID method = env->GetMethodID(clazz, "onLinphoneChatMessageFileTransferProgressChanged", "(Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneContent;II)V"); + jobject jmessage = getChatMessage(env, msg); + env->CallVoidMethod(listener, method, jmessage, content ? create_java_linphone_content(env, content) : NULL, offset, total); +} + +static void file_transfer_recv(LinphoneChatMessage *msg, const LinphoneContent* content, const LinphoneBuffer *buffer) { + JNIEnv *env = 0; + jint result = jvm->AttachCurrentThread(&env,NULL); + if (result != 0) { + ms_error("cannot attach VM\n"); + return; + } + + jobject listener = (jobject) msg->cb_ud; + jclass clazz = (jclass) env->GetObjectClass(listener); + jmethodID method = env->GetMethodID(clazz, "onLinphoneChatMessageFileTransferReceived", "(Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneContent;Lorg/linphone/core/LinphoneBuffer;)V"); + jobject jmessage = getChatMessage(env, msg); + env->CallVoidMethod(listener, method, jmessage, content ? create_java_linphone_content(env, content) : NULL, buffer ? create_java_linphone_buffer(env, buffer) : NULL); +} + +static LinphoneBuffer* file_transfer_send(LinphoneChatMessage *msg, const LinphoneContent* content, size_t offset, size_t size) { + JNIEnv *env = 0; + jint result = jvm->AttachCurrentThread(&env,NULL); + LinphoneBuffer *buffer = NULL; + if (result != 0) { + ms_error("cannot attach VM\n"); + return buffer; + } + + jobject listener = (jobject) msg->cb_ud; + jclass clazz = (jclass) env->GetObjectClass(listener); + jmethodID method = env->GetMethodID(clazz, "onLinphoneChatMessageFileTransferSent","(Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneContent;IILorg/linphone/core/LinphoneBuffer;)V"); + jobject jmessage = getChatMessage(env, msg); + jobject jbuffer = create_java_linphone_buffer(env, NULL); + env->CallVoidMethod(listener, method, jmessage, content ? create_java_linphone_content(env, content) : NULL, offset, size, jbuffer); + + buffer = create_c_linphone_buffer_from_java_linphone_buffer(env, jbuffer); + return buffer; +} + +extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_setListener(JNIEnv* env, jobject thiz, jlong ptr, jobject jlistener) { + jobject listener = env->NewGlobalRef(jlistener); + LinphoneChatMessage *message = (LinphoneChatMessage *)ptr; + LinphoneChatMessageCbs *cbs; + + message->cb_ud = listener; + cbs = linphone_chat_message_get_callbacks(message); + linphone_chat_message_cbs_set_msg_state_changed(cbs, message_state_changed); + linphone_chat_message_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication); + linphone_chat_message_cbs_set_file_transfer_recv(cbs, file_transfer_recv); + linphone_chat_message_cbs_set_file_transfer_send(cbs, file_transfer_send); +} + extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_unref(JNIEnv* env ,jobject thiz ,jlong ptr) { @@ -3275,11 +3395,15 @@ extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_sendMessage2(JNIEnv* linphone_chat_room_send_message2((LinphoneChatRoom*)chatroom_ptr, (LinphoneChatMessage*)messagePtr, chat_room_impl_callback, (void*)listener); } -extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_startFileDownload(JNIEnv* env, jobject thiz, jlong ptr, jobject jlistener) { - jobject listener = env->NewGlobalRef(jlistener); - LinphoneChatMessage * message = (LinphoneChatMessage *)ptr; - message->cb_ud = listener; - linphone_chat_message_start_file_download(message, chat_room_impl_callback, NULL); +extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_sendChatMessage(JNIEnv* env + ,jobject thiz + ,jlong chatroom_ptr + ,jobject message + ,jlong messagePtr) { + message = env->NewGlobalRef(message); + linphone_chat_message_ref((LinphoneChatMessage*)messagePtr); + linphone_chat_message_set_user_data((LinphoneChatMessage*)messagePtr, message); + linphone_chat_room_send_chat_message((LinphoneChatRoom*)chatroom_ptr, (LinphoneChatMessage*)messagePtr); } extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setVideoWindowId(JNIEnv* env @@ -4428,6 +4552,52 @@ static jobject create_java_linphone_content(JNIEnv *env, const LinphoneContent * return jobj; } +static jobject create_java_linphone_buffer(JNIEnv *env, const LinphoneBuffer *buffer) { + jclass bufferClass; + jmethodID ctor; + jbyteArray jdata = NULL; + jint jsize = 0; + + bufferClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneBufferImpl")); + ctor = env->GetMethodID(bufferClass,"", "([BI)V"); + jsize = buffer ? (jint) buffer->size : 0; + + if (buffer && buffer->content) { + jdata = env->NewByteArray(buffer->size); + env->SetByteArrayRegion(jdata, 0, buffer->size, (jbyte*)buffer->content); + } + + jobject jobj = env->NewObject(bufferClass, ctor, jdata, jsize); + env->DeleteGlobalRef(bufferClass); + return jobj; +} + +static LinphoneBuffer* create_c_linphone_buffer_from_java_linphone_buffer(JNIEnv *env, jobject jbuffer) { + jclass bufferClass; + jmethodID getSizeMethod, getDataMethod; + LinphoneBuffer *buffer; + jint jsize; + jobject jdata; + jbyteArray jcontent; + uint8_t *content; + + bufferClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneBufferImpl")); + getSizeMethod = env->GetMethodID(bufferClass, "getSize", "()I"); + getDataMethod = env->GetMethodID(bufferClass, "getContent", "()[B"); + + jsize = env->CallIntMethod(jbuffer, getSizeMethod); + jdata = env->CallObjectMethod(jbuffer, getDataMethod); + jcontent = reinterpret_cast(jdata); + content = (uint8_t*)env->GetByteArrayElements(jcontent, NULL); + + buffer = linphone_buffer_new_from_data(content, (size_t)jsize); + + env->ReleaseByteArrayElements(jcontent, (jbyte*)content, JNI_ABORT); + env->DeleteGlobalRef(bufferClass); + + return buffer; +} + /* * Class: org_linphone_core_LinphoneInfoMessageImpl * Method: getContent diff --git a/coreapi/message_storage.c b/coreapi/message_storage.c index cfee1c873..69a71c544 100644 --- a/coreapi/message_storage.c +++ b/coreapi/message_storage.c @@ -26,7 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #endif #ifndef WIN32 -#ifndef ANDROID +#if !defined(ANDROID) && !defined(__QNXNTO__) # include # include # include @@ -592,7 +592,7 @@ void linphone_core_message_storage_set_debug(LinphoneCore *lc, bool_t debug){ } static int _linphone_sqlite3_open(const char *db_file, sqlite3 **db) { -#ifdef ANDROID +#if defined(ANDROID) || defined(__QNXNTO__) return sqlite3_open(db_file, db); #elif defined(WIN32) int ret; diff --git a/coreapi/misc.c b/coreapi/misc.c index 666ac8919..f978e2948 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -1533,7 +1533,7 @@ void linphone_core_set_tone(LinphoneCore *lc, LinphoneToneID id, const char *aud } const MSCryptoSuite * linphone_core_get_srtp_crypto_suites(LinphoneCore *lc){ - const char *config=lp_config_get_string(lc->config,"sip","srtp_crypto_suites","AES_CM_128_HMAC_SHA1_80, AES_CM_128_HMAC_SHA1_32"); + const char *config=lp_config_get_string(lc->config,"sip","srtp_crypto_suites","AES_CM_128_HMAC_SHA1_80, AES_CM_128_HMAC_SHA1_32, AES_CM_256_HMAC_SHA1_80, AES_CM_256_HMAC_SHA1_32"); char *tmp=ms_strdup(config); char *sep; char *pos; @@ -1581,6 +1581,41 @@ const MSCryptoSuite * linphone_core_get_srtp_crypto_suites(LinphoneCore *lc){ return result; } +static char * seperate_string_list(char **str) { + char *ret; + + if (str == NULL) return NULL; + if (*str == NULL) return NULL; + if (**str == '\0') return NULL; + + ret = *str; + for ( ; **str!='\0' && **str!=' ' && **str!=','; (*str)++); + if (**str == '\0') { + return ret; + } else { + **str = '\0'; + do { (*str)++; } while (**str!='\0' && (**str==' ' || **str==',')); + return ret; + } +} + +MsZrtpCryptoTypesCount linphone_core_get_zrtp_key_agreements(LinphoneCore *lc, MSZrtpKeyAgreement keyAgreements[MS_MAX_ZRTP_CRYPTO_TYPES]){ + char *config=strdup(lp_config_get_string(lc->config, "sip", "zrtp_key_agreements_suites", "MS_ZRTP_KEY_AGREEMENT_DH3K, MS_ZRTP_KEY_AGREEMENT_DH2K")); + char *entry; + MsZrtpCryptoTypesCount key_agreements_count = 0; + + if (config == NULL) return 0; + + while ((entry = seperate_string_list(&config))) { + const MSZrtpKeyAgreement agreement = ms_zrtp_key_agreement_from_string(entry); + if (agreement != MS_ZRTP_KEY_AGREEMENT_INVALID) { + ms_message("Configured zrtp key agreement: '%s'", ms_zrtp_key_agreement_to_string(agreement)); + keyAgreements[key_agreements_count++] = agreement; + } + } + + return key_agreements_count; +} const char ** linphone_core_get_supported_file_formats(LinphoneCore *core){ diff --git a/coreapi/private.h b/coreapi/private.h index d08c569ff..27ad33d52 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -321,7 +321,7 @@ void _linphone_proxy_config_release(LinphoneProxyConfig *cfg); * Can be NULL * */ const LinphoneAddress* linphone_proxy_config_get_service_route(const LinphoneProxyConfig* cfg); -char* linphone_proxy_config_get_contact(const LinphoneProxyConfig *cfg); +LINPHONE_PUBLIC char* linphone_proxy_config_get_contact(const LinphoneProxyConfig *cfg); void linphone_friend_close_subscriptions(LinphoneFriend *lf); void linphone_friend_update_subscribes(LinphoneFriend *fr, LinphoneProxyConfig *cfg, bool_t only_when_registered); @@ -717,7 +717,7 @@ typedef struct _LinphoneConference LinphoneConference; struct _LinphoneCore { - MSList* vtables; + MSList* vtable_refs; Sal *sal; LinphoneGlobalState state; struct _LpConfig *config; @@ -767,6 +767,8 @@ struct _LinphoneCore char* zrtp_secrets_cache; char* user_certificates_path; LinphoneVideoPolicy video_policy; + time_t network_last_check; + bool_t use_files; bool_t apply_nat_settings; bool_t initial_subscribes_sent; @@ -776,13 +778,11 @@ struct _LinphoneCore bool_t auto_net_state_mon; bool_t network_reachable; bool_t network_reachable_to_be_notified; /*set to true when state must be notified in next iterate*/ + bool_t use_preview_window; - - time_t network_last_check; - bool_t network_last_status; bool_t ringstream_autorelease; - bool_t pad[2]; + bool_t vtables_running; char localip[LINPHONE_IPADDR_SIZE]; int device_rotation; int max_calls; @@ -801,6 +801,7 @@ struct _LinphoneCore belle_tls_verify_policy_t *http_verify_policy; MSList *tones; LinphoneReason chat_deny_code; + char *file_transfer_server; const char **supported_formats; LinphoneContent *log_collection_upload_information; LinphoneCoreVTable *current_vtable; // the latest vtable to call a callback, see linphone_core_get_current_vtable @@ -973,7 +974,7 @@ BELLE_SIP_DECLARE_VPTR(LinphoneBuffer); void linphone_configuring_terminated(LinphoneCore *lc, LinphoneConfiguringState state, const char *message); int linphone_remote_provisioning_download_and_apply(LinphoneCore *lc, const char *remote_provisioning_uri); -int linphone_remote_provisioning_load_file( LinphoneCore* lc, const char* file_path); +LINPHONE_PUBLIC int linphone_remote_provisioning_load_file( LinphoneCore* lc, const char* file_path); /***************************************************************************** * Player interface @@ -1048,6 +1049,7 @@ static MS2_INLINE bool_t payload_type_enabled(const PayloadType *pt) { bool_t is_payload_type_number_available(const MSList *l, int number, const PayloadType *ignore); const MSCryptoSuite * linphone_core_get_srtp_crypto_suites(LinphoneCore *lc); +MsZrtpCryptoTypesCount linphone_core_get_zrtp_key_agreements(LinphoneCore *lc, MSZrtpKeyAgreement keyAgreements[MS_MAX_ZRTP_CRYPTO_TYPES]); /** Belle Sip-based objects need unique ids */ @@ -1113,6 +1115,37 @@ void set_playback_gain_db(AudioStream *st, float gain); LinphoneMediaDirection media_direction_from_sal_stream_dir(SalStreamDir dir); SalStreamDir sal_dir_from_call_params_dir(LinphoneMediaDirection cpdir); +/***************************************************************************** + * LINPHONE CONTENT PRIVATE ACCESSORS * + ****************************************************************************/ +/** + * Get the key associated with a RCS file transfer message if encrypted + * @param[in] content LinphoneContent object. + * @return The key to encrypt/decrypt the file associated to this content. + */ +const char *linphone_content_get_key(const LinphoneContent *content); + +/** + * Get the size of key associated with a RCS file transfer message if encrypted + * @param[in] content LinphoneContent object. + * @return The key size in bytes + */ +size_t linphone_content_get_key_size(const LinphoneContent *content); +/** + * Set the key associated with a RCS file transfer message if encrypted + * @param[in] content LinphoneContent object. + * @param[in] key The key to be used to encrypt/decrypt file associated to this content. + */ +void linphone_content_set_key(LinphoneContent *content, const char *key, const size_t keyLength); + +/** + * Get the address of the crypto context associated with a RCS file transfer message if encrypted + * @param[in] content LinphoneContent object. + * @return The address of the pointer to the crypto context. Crypto context is managed(alloc/free) + * by the encryption/decryption functions, so we give the address to store/retrieve the pointer + */ +void ** linphone_content_get_cryptoContext_address(LinphoneContent *content); + #ifdef ANDROID void linphone_core_wifi_lock_acquire(LinphoneCore *lc); void linphone_core_wifi_lock_release(LinphoneCore *lc); @@ -1120,6 +1153,18 @@ void linphone_core_multicast_lock_acquire(LinphoneCore *lc); void linphone_core_multicast_lock_release(LinphoneCore *lc); #endif +struct _VTableReference{ + LinphoneCoreVTable *vtable; + bool_t valid; + bool_t autorelease; +}; + +typedef struct _VTableReference VTableReference; + +void v_table_reference_destroy(VTableReference *ref); + +void _linphone_core_add_listener(LinphoneCore *lc, LinphoneCoreVTable *vtable, bool_t autorelease); + #ifdef __cplusplus } #endif diff --git a/coreapi/proxy.c b/coreapi/proxy.c index 19b362b6e..2a21d6312 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -510,7 +510,7 @@ void linphone_proxy_config_refresh_register(LinphoneProxyConfig *obj){ /** * Sets a dialing prefix to be automatically prepended when inviting a number with * linphone_core_invite(); - * This dialing prefix shall usually be the country code of the country where the user is living. + * This dialing prefix shall usually be the country code of the country where the user is living, without "+". * **/ void linphone_proxy_config_set_dial_prefix(LinphoneProxyConfig *cfg, const char *prefix){ @@ -917,7 +917,7 @@ static void replace_plus(const char *src, char *dest, size_t destlen, const char if (icp && src[0]=='+' && (destlen>(i=strlen(icp))) ){ src++; - strcpy(dest,icp); + strncpy(dest, icp, destlen); } for(;(idial_prefix==NULL || proxy->dial_prefix[0]=='\0'){ /*no prefix configured, nothing else to do*/ - strncpy(result,flatten,result_len); - ms_free(flatten); + strncpy(result,flatten,result_len-1); }else{ dial_plan_t dialplan; lookup_dial_plan(proxy->dial_prefix,&dialplan); ms_debug("Using dialplan '%s'",dialplan.country); - if (flatten[0]=='+' || strstr(flatten,dialplan.icp)==flatten){ + if (flatten[0]=='+'){ /* the number has international prefix or +, so nothing to do*/ ms_debug("Prefix already present."); - /*eventually replace the plus*/ + /*eventually replace the plus by the international calling prefix of the country*/ replace_plus(flatten,result,result_len,proxy->dial_escape_plus ? dialplan.icp : NULL); - ms_free(flatten); + }else if (strstr(flatten,dialplan.icp)==flatten){ + if (!proxy->dial_escape_plus) + replace_icp(flatten, result, result_len, dialplan.icp); + else + strncpy(result, flatten, result_len-1); }else{ int numlen; int i=0; @@ -956,7 +969,7 @@ bool_t linphone_proxy_config_normalize_number(LinphoneProxyConfig *proxy, const /*keep at most national number significant digits */ skip=numlen-dialplan.nnl; if (skip<0) skip=0; - /*first prepend internation calling prefix or +*/ + /*first prepend international calling prefix or +*/ if (proxy->dial_escape_plus){ strncpy(result,dialplan.icp,result_len); i+=strlen(dialplan.icp); @@ -971,12 +984,12 @@ bool_t linphone_proxy_config_normalize_number(LinphoneProxyConfig *proxy, const } /*add user digits */ strncpy(result+i,flatten+skip,result_len-i-1); - ms_free(flatten); } } + ms_free(flatten); return TRUE; } else { - strncpy(result,username,result_len); + strncpy(result,username,result_len-1); return FALSE; } } diff --git a/coreapi/remote_provisioning.c b/coreapi/remote_provisioning.c index 5562f65db..c206b5828 100644 --- a/coreapi/remote_provisioning.c +++ b/coreapi/remote_provisioning.c @@ -60,32 +60,9 @@ static void linphone_remote_provisioning_apply(LinphoneCore *lc, const char *xml , error_msg); } -static char *load_file_content(const char *path){ - FILE *f=fopen(path,"rb"); - size_t bufsize=2048; - size_t step=bufsize; - size_t pos=0; - size_t count; - char *buffer=ms_malloc(bufsize+1); - if (!f) { - ms_error("load_file_content(): could not open [%s]",path); - return NULL; - } - while((count=fread(buffer+pos, 1, step, f))>0){ - pos+=count; - if (pos+step>=bufsize){ - bufsize*=2; - buffer=ms_realloc(buffer, bufsize+1); - } - } - buffer[pos]='\0'; - fclose(f); - return buffer; -} - int linphone_remote_provisioning_load_file( LinphoneCore* lc, const char* file_path){ int status = -1; - char* provisioning=load_file_content(file_path); + char* provisioning=ms_load_path_content(file_path, NULL); if (provisioning){ linphone_remote_provisioning_apply(lc, provisioning); diff --git a/coreapi/sipsetup.h b/coreapi/sipsetup.h index 7b1b2ed44..2cbe24036 100644 --- a/coreapi/sipsetup.h +++ b/coreapi/sipsetup.h @@ -23,6 +23,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "mediastreamer2/mscommon.h" +#ifndef LINPHONE_PUBLIC +#define LINPHONE_PUBLIC MS2_PUBLIC +#endif + struct _SipSetup; struct _BuddyInfo; @@ -120,7 +124,7 @@ extern "C"{ BuddyInfo *buddy_info_new(void); void buddy_info_free(BuddyInfo *info); -void buddy_lookup_request_set_key(BuddyLookupRequest *req, const char *key); +LINPHONE_PUBLIC void buddy_lookup_request_set_key(BuddyLookupRequest *req, const char *key); void buddy_lookup_request_set_max_results(BuddyLookupRequest *req, int ncount); @@ -128,28 +132,28 @@ void sip_setup_register(SipSetup *ss); void sip_setup_register_all(void); SipSetup *sip_setup_lookup(const char *type_name); void sip_setup_unregister_all(void); -unsigned int sip_setup_get_capabilities(SipSetup *s); +LINPHONE_PUBLIC unsigned int sip_setup_get_capabilities(SipSetup *s); SipSetupContext * sip_setup_context_new(SipSetup *s, struct _LinphoneProxyConfig *cfg); int sip_setup_context_account_exists(SipSetupContext *ctx, const char *uri); int sip_setup_context_account_validated(SipSetupContext *ctx, const char *uri); int sip_setup_context_create_account(SipSetupContext *ctx, const char *uri, const char *passwd, const char *email, int suscribe); -int sip_setup_context_get_capabilities(SipSetupContext *ctx); -int sip_setup_context_login_account(SipSetupContext * ctx, const char *uri, const char *passwd, const char *userid); +LINPHONE_PUBLIC int sip_setup_context_get_capabilities(SipSetupContext *ctx); +LINPHONE_PUBLIC int sip_setup_context_login_account(SipSetupContext * ctx, const char *uri, const char *passwd, const char *userid); int sip_setup_context_get_proxy(SipSetupContext *ctx, const char *domain, char *proxy, size_t sz); int sip_setup_context_get_stun_servers(SipSetupContext *ctx, char *stun1, char *stun2, size_t size); int sip_setup_context_get_relay(SipSetupContext *ctx, char *relay, size_t size); -BuddyLookupRequest *sip_setup_context_create_buddy_lookup_request(SipSetupContext *ctx); -int sip_setup_context_buddy_lookup_submit(SipSetupContext *ctx , BuddyLookupRequest *req); -int sip_setup_context_buddy_lookup_free(SipSetupContext *ctx , BuddyLookupRequest *req); +LINPHONE_PUBLIC BuddyLookupRequest *sip_setup_context_create_buddy_lookup_request(SipSetupContext *ctx); +LINPHONE_PUBLIC int sip_setup_context_buddy_lookup_submit(SipSetupContext *ctx , BuddyLookupRequest *req); +LINPHONE_PUBLIC int sip_setup_context_buddy_lookup_free(SipSetupContext *ctx , BuddyLookupRequest *req); const char * sip_setup_context_get_notice(SipSetupContext *ctx); const char ** sip_setup_context_get_domains(SipSetupContext *ctx); void sip_setup_context_free(SipSetupContext *ctx); -int sip_setup_context_logout(SipSetupContext *ctx); +LINPHONE_PUBLIC int sip_setup_context_logout(SipSetupContext *ctx); /*internal methods for use WITHIN plugins: do not use elsewhere*/ struct _LinphoneProxyConfig *sip_setup_context_get_proxy_config(const SipSetupContext *ctx); diff --git a/coreapi/sipwizard.c b/coreapi/sipwizard.c index 8d92de9dc..879b9942a 100644 --- a/coreapi/sipwizard.c +++ b/coreapi/sipwizard.c @@ -255,8 +255,6 @@ SipSetup linphone_sip_wizard={ NULL, NULL, NULL, - NULL, - NULL, sip_wizard_get_domains, NULL, NULL, diff --git a/coreapi/vtables.c b/coreapi/vtables.c new file mode 100644 index 000000000..3a5672509 --- /dev/null +++ b/coreapi/vtables.c @@ -0,0 +1,266 @@ +/* +linphone +Copyright (C) 2000 Simon MORLAT (simon.morlat@linphone.org) +Copyright (C) 2010 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 "private.h" + + +LinphoneCoreVTable *linphone_core_v_table_new() { + return ms_new0(LinphoneCoreVTable,1); +} + +void linphone_core_v_table_set_user_data(LinphoneCoreVTable *table, void *data) { + table->user_data = data; +} + +void* linphone_core_v_table_get_user_data(LinphoneCoreVTable *table) { + return table->user_data; +} + +void linphone_core_v_table_destroy(LinphoneCoreVTable* table) { + ms_free(table); +} + +LinphoneCoreVTable *linphone_core_get_current_vtable(LinphoneCore *lc) { + return lc->current_vtable; +} + +static void cleanup_dead_vtable_refs(LinphoneCore *lc){ + MSList *it,*next_it; + for(it=lc->vtable_refs; it!=NULL; ){ + VTableReference *ref=(VTableReference*)it->data; + next_it=it->next; + if (ref->valid==0){ + ref->valid=0; + lc->vtable_refs=ms_list_remove_link(lc->vtable_refs, it); + ms_free(ref); + } + it=next_it; + } +} + +#define NOTIFY_IF_EXIST(function_name) \ + MSList* iterator; \ + VTableReference *ref; \ + ms_message("Linphone core [%p] notifying [%s]",lc,#function_name);\ + for (iterator=lc->vtable_refs; iterator!=NULL; iterator=iterator->next) \ + if ((ref=(VTableReference*)iterator->data)->valid && (lc->current_vtable=ref->vtable)->function_name)\ + lc->current_vtable->function_name + +void linphone_core_notify_global_state_changed(LinphoneCore *lc, LinphoneGlobalState gstate, const char *message) { + NOTIFY_IF_EXIST(global_state_changed)(lc,gstate,message); + cleanup_dead_vtable_refs(lc); +} + +void linphone_core_notify_call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *message){ + NOTIFY_IF_EXIST(call_state_changed)(lc,call,cstate,message); + cleanup_dead_vtable_refs(lc); +} + +void linphone_core_notify_call_encryption_changed(LinphoneCore *lc, LinphoneCall *call, bool_t on, const char *authentication_token) { + NOTIFY_IF_EXIST(call_encryption_changed)(lc,call,on,authentication_token); + cleanup_dead_vtable_refs(lc); +} + +void linphone_core_notify_registration_state_changed(LinphoneCore *lc, LinphoneProxyConfig *cfg, LinphoneRegistrationState cstate, const char *message){ + NOTIFY_IF_EXIST(registration_state_changed)(lc,cfg,cstate,message); + cleanup_dead_vtable_refs(lc); +} + +void linphone_core_notify_show_interface(LinphoneCore *lc){ + NOTIFY_IF_EXIST(show)(lc); + cleanup_dead_vtable_refs(lc); +} + +void linphone_core_notify_display_status(LinphoneCore *lc, const char *message) { + NOTIFY_IF_EXIST(display_status)(lc,message); + cleanup_dead_vtable_refs(lc); +} + +void linphone_core_notify_display_message(LinphoneCore *lc, const char *message){ + NOTIFY_IF_EXIST(display_message)(lc,message); + cleanup_dead_vtable_refs(lc); +} + +void linphone_core_notify_display_warning(LinphoneCore *lc, const char *message){ + NOTIFY_IF_EXIST(display_warning)(lc,message); + cleanup_dead_vtable_refs(lc); +} + +void linphone_core_notify_display_url(LinphoneCore *lc, const char *message, const char *url){ + NOTIFY_IF_EXIST(display_url)(lc,message,url); + cleanup_dead_vtable_refs(lc); +} + +void linphone_core_notify_notify_presence_received(LinphoneCore *lc, LinphoneFriend * lf){ + NOTIFY_IF_EXIST(notify_presence_received)(lc,lf); + cleanup_dead_vtable_refs(lc); +} + +void linphone_core_notify_new_subscription_requested(LinphoneCore *lc, LinphoneFriend *lf, const char *url){ + NOTIFY_IF_EXIST(new_subscription_requested)(lc,lf,url); + cleanup_dead_vtable_refs(lc); +} + +void linphone_core_notify_auth_info_requested(LinphoneCore *lc, const char *realm, const char *username, const char *domain){ + NOTIFY_IF_EXIST(auth_info_requested)(lc,realm,username,domain); + cleanup_dead_vtable_refs(lc); +} + +void linphone_core_notify_call_log_updated(LinphoneCore *lc, LinphoneCallLog *newcl){ + NOTIFY_IF_EXIST(call_log_updated)(lc,newcl); + cleanup_dead_vtable_refs(lc); +} + +void linphone_core_notify_text_message_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from, const char *message){ + NOTIFY_IF_EXIST(text_received)(lc,room,from,message); + cleanup_dead_vtable_refs(lc); +} + +void linphone_core_notify_message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *message){ + NOTIFY_IF_EXIST(message_received)(lc,room,message); + cleanup_dead_vtable_refs(lc); +} + +void linphone_core_notify_file_transfer_recv(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, const char* buff, size_t size) { + NOTIFY_IF_EXIST(file_transfer_recv)(lc,message,content,buff,size); + cleanup_dead_vtable_refs(lc); +} + +void linphone_core_notify_file_transfer_send(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, char* buff, size_t* size) { + NOTIFY_IF_EXIST(file_transfer_send)(lc,message,content,buff,size); + cleanup_dead_vtable_refs(lc); +} + +void linphone_core_notify_file_transfer_progress_indication(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t total) { + NOTIFY_IF_EXIST(file_transfer_progress_indication)(lc,message,content,offset,total); + cleanup_dead_vtable_refs(lc); +} + +void linphone_core_notify_is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room) { + NOTIFY_IF_EXIST(is_composing_received)(lc,room); + cleanup_dead_vtable_refs(lc); +} + +void linphone_core_notify_dtmf_received(LinphoneCore* lc, LinphoneCall *call, int dtmf) { + NOTIFY_IF_EXIST(dtmf_received)(lc,call,dtmf); + cleanup_dead_vtable_refs(lc); +} + +bool_t linphone_core_dtmf_received_has_listener(const LinphoneCore* lc) { + MSList* iterator; + for (iterator=lc->vtable_refs; iterator!=NULL; iterator=iterator->next){ + VTableReference *ref=(VTableReference*)iterator->data; + if (ref->valid && ref->vtable->dtmf_received) + return TRUE; + } + return FALSE; +} + +void linphone_core_notify_refer_received(LinphoneCore *lc, const char *refer_to) { + NOTIFY_IF_EXIST(refer_received)(lc,refer_to); + cleanup_dead_vtable_refs(lc); +} + +void linphone_core_notify_buddy_info_updated(LinphoneCore *lc, LinphoneFriend *lf) { + NOTIFY_IF_EXIST(buddy_info_updated)(lc,lf); + cleanup_dead_vtable_refs(lc); +} + +void linphone_core_notify_transfer_state_changed(LinphoneCore *lc, LinphoneCall *transfered, LinphoneCallState new_call_state) { + NOTIFY_IF_EXIST(transfer_state_changed)(lc,transfered,new_call_state); + cleanup_dead_vtable_refs(lc); +} + +void linphone_core_notify_call_stats_updated(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallStats *stats) { + NOTIFY_IF_EXIST(call_stats_updated)(lc,call,stats); + cleanup_dead_vtable_refs(lc); +} + +void linphone_core_notify_info_received(LinphoneCore *lc, LinphoneCall *call, const LinphoneInfoMessage *msg) { + NOTIFY_IF_EXIST(info_received)(lc,call,msg); + cleanup_dead_vtable_refs(lc); +} + +void linphone_core_notify_configuring_status(LinphoneCore *lc, LinphoneConfiguringState status, const char *message) { + NOTIFY_IF_EXIST(configuring_status)(lc,status,message); + cleanup_dead_vtable_refs(lc); +} + +void linphone_core_notify_network_reachable(LinphoneCore *lc, bool_t reachable) { + NOTIFY_IF_EXIST(network_reachable)(lc,reachable); + cleanup_dead_vtable_refs(lc); +} + +void linphone_core_notify_notify_received(LinphoneCore *lc, LinphoneEvent *lev, const char *notified_event, const LinphoneContent *body) { + NOTIFY_IF_EXIST(notify_received)(lc,lev,notified_event,body); + cleanup_dead_vtable_refs(lc); +} + +void linphone_core_notify_subscription_state_changed(LinphoneCore *lc, LinphoneEvent *lev, LinphoneSubscriptionState state) { + NOTIFY_IF_EXIST(subscription_state_changed)(lc,lev,state); + cleanup_dead_vtable_refs(lc); +} + +void linphone_core_notify_publish_state_changed(LinphoneCore *lc, LinphoneEvent *lev, LinphonePublishState state) { + NOTIFY_IF_EXIST(publish_state_changed)(lc,lev,state); + cleanup_dead_vtable_refs(lc); +} + +void linphone_core_notify_log_collection_upload_state_changed(LinphoneCore *lc, LinphoneCoreLogCollectionUploadState state, const char *info) { + NOTIFY_IF_EXIST(log_collection_upload_state_changed)(lc, state, info); + cleanup_dead_vtable_refs(lc); +} + +void linphone_core_notify_log_collection_upload_progress_indication(LinphoneCore *lc, size_t offset, size_t total) { + NOTIFY_IF_EXIST(log_collection_upload_progress_indication)(lc, offset, total); + cleanup_dead_vtable_refs(lc); +} + +static VTableReference * v_table_reference_new(LinphoneCoreVTable *vtable, bool_t autorelease){ + VTableReference *ref=ms_new0(VTableReference,1); + ref->valid=1; + ref->autorelease=autorelease; + ref->vtable=vtable; + return ref; +} + +void v_table_reference_destroy(VTableReference *ref){ + if (ref->autorelease) linphone_core_v_table_destroy(ref->vtable); + ms_free(ref); +} + +void _linphone_core_add_listener(LinphoneCore *lc, LinphoneCoreVTable *vtable, bool_t autorelease) { + ms_message("Vtable [%p] registered on core [%p]",lc,vtable); + lc->vtable_refs=ms_list_append(lc->vtable_refs,v_table_reference_new(vtable, autorelease)); +} + +void linphone_core_add_listener(LinphoneCore *lc, LinphoneCoreVTable *vtable){ + _linphone_core_add_listener(lc, vtable, FALSE); +} + +void linphone_core_remove_listener(LinphoneCore *lc, const LinphoneCoreVTable *vtable) { + MSList *it; + ms_message("Vtable [%p] unregistered on core [%p]",lc,vtable); + for(it=lc->vtable_refs; it!=NULL; it=it->next){ + VTableReference *ref=(VTableReference*)it->data; + if (ref->vtable==vtable) + ref->valid=0; + } +} diff --git a/gtk/CMakeLists.txt b/gtk/CMakeLists.txt index 7af375971..ea923ea6d 100644 --- a/gtk/CMakeLists.txt +++ b/gtk/CMakeLists.txt @@ -20,7 +20,11 @@ # ############################################################################ +if(WIN32) + set(GTK2_ADDITIONAL_SUFFIXES "../lib/glib-2.0/include" "../lib/gtk-2.0/include") +endif() find_package(GTK2 2.18 REQUIRED gtk) +find_package(Intl REQUIRED) set(UI_FILES about.ui @@ -44,6 +48,7 @@ set(UI_FILES ) set(PIXMAPS stock_people.png) +set(LICENSE ../COPYING) set(SOURCE_FILES audio_assistant.c @@ -64,6 +69,9 @@ set(SOURCE_FILES utils.c videowindow.c ) +if(WIN32) + list(APPEND SOURCE_FILES linphone.rc) +endif() if(ENABLE_ASSISTANT) list(APPEND SOURCE_FILES setupwizard.c) @@ -73,10 +81,20 @@ if(GETTEXT_FOUND) add_definitions("-DENABLE_NLS") endif() -add_executable(linphone-gtk ${SOURCE_FILES}) -set_target_properties(linphone-gtk PROPERTIES OUTPUT_NAME linphone) -target_include_directories(linphone-gtk PUBLIC ${GTK2_INCLUDE_DIRS}) +if(WIN32) + add_executable(linphone-gtk WIN32 ${SOURCE_FILES}) +else() + add_executable(linphone-gtk ${SOURCE_FILES}) +endif() +set_target_properties(linphone-gtk PROPERTIES OUTPUT_NAME linphone LINKER_LANGUAGE CXX) +target_include_directories(linphone-gtk PUBLIC ${GTK2_INCLUDE_DIRS} ${INTL_INCLUDE_DIRS}) target_link_libraries(linphone-gtk linphone ${GTK2_LIBRARIES}) +if(INTL_LIBRARIES) + target_link_libraries(linphone-gtk ${INTL_LIBRARIES}) +endif() +if(WIN32) + target_link_libraries(linphone-gtk Wininet) +endif() if(ENABLE_NOTIFY) target_include_directories(linphone-gtk PUBLIC ${NOTIFY_INCLUDE_DIRS}) target_link_libraries(linphone-gtk ${NOTIFY_LIBRARIES}) @@ -92,7 +110,7 @@ install(TARGETS linphone-gtk PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE ) -install(FILES ${UI_FILES} ${PIXMAPS} +install(FILES ${UI_FILES} ${PIXMAPS} ${LICENSE} DESTINATION ${PACKAGE_DATA_DIR}/linphone PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ ) diff --git a/gtk/chat.c b/gtk/chat.c index 1f2234d72..79f0d0535 100644 --- a/gtk/chat.c +++ b/gtk/chat.c @@ -23,6 +23,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #endif +#if defined(WIN32) && !defined(F_OK) +#define F_OK 00 /*visual studio does not define F_OK*/ +#endif + #define NB_MSG_HIST 250 #define CONFIG_FILE ".linphone-history.db" diff --git a/gtk/friendlist.c b/gtk/friendlist.c index 70be2484f..3aafb3187 100644 --- a/gtk/friendlist.c +++ b/gtk/friendlist.c @@ -148,7 +148,7 @@ static void linphone_gtk_set_selection_to_uri_bar(GtkTreeView *treeview){ } } -void linphone_gtk_add_contact(){ +void linphone_gtk_add_contact(void){ GtkWidget *w=linphone_gtk_create_window("contact"); int presence_enabled=linphone_gtk_get_ui_config_int("use_subscribe_notify",1); diff --git a/gtk/incall_view.c b/gtk/incall_view.c index a44097ae0..f291afcb5 100644 --- a/gtk/incall_view.c +++ b/gtk/incall_view.c @@ -499,7 +499,7 @@ static void display_peer_name_in_label(GtkWidget *label, const LinphoneAddress * uri_label=g_markup_printf_escaped("%s\n",id); gtk_label_set_markup(GTK_LABEL(label),uri_label); g_free(uri_label); - g_free(id); + ms_free(id); } void linphone_gtk_in_call_view_set_calling(LinphoneCall *call){ diff --git a/gtk/linphone.h b/gtk/linphone.h index cfb52f5e7..a4b87ce25 100644 --- a/gtk/linphone.h +++ b/gtk/linphone.h @@ -83,121 +83,236 @@ GtkWidget*create_pixmap(const gchar *filename); GtkWidget *_gtk_image_new_from_memory_at_scale(const void *data, gint len, gint w, gint h, gboolean preserve_ratio); GdkPixbuf *_gdk_pixbuf_new_from_memory_at_scale(const void *data, gint len, gint w, gint h, gboolean preserve_ratio); -void linphone_gtk_destroy_window(GtkWidget *window); -GtkWidget *linphone_gtk_create_window(const char *window_name); -GtkWidget *linphone_gtk_get_widget(GtkWidget *window, const char *name); -GtkWidget *linphone_gtk_create_widget(const char *filename, const char *widget_name); +LINPHONE_PUBLIC void linphone_gtk_destroy_window(GtkWidget *window); +LINPHONE_PUBLIC GtkWidget *linphone_gtk_create_window(const char *window_name); +LINPHONE_PUBLIC GtkWidget *linphone_gtk_get_widget(GtkWidget *window, const char *name); +LINPHONE_PUBLIC GtkWidget *linphone_gtk_create_widget(const char *filename, const char *widget_name); const char *linphone_gtk_message_storage_get_db_file(const char *filename); -void linphone_gtk_show_assistant(void); -void linphone_gtk_close_assistant(void); +LINPHONE_PUBLIC void linphone_gtk_show_assistant(void); +LINPHONE_PUBLIC void linphone_gtk_close_assistant(void); -LinphoneCore *linphone_gtk_get_core(void); -GtkWidget *linphone_gtk_get_main_window(); -void linphone_gtk_display_something(GtkMessageType type,const gchar *message); -void linphone_gtk_start_call(GtkWidget *button); -void linphone_gtk_call_terminated(); -void linphone_gtk_set_my_presence(LinphoneOnlineStatus ss); -void linphone_gtk_show_parameters(void); -void linphone_gtk_fill_soundcards(GtkWidget *pb); -void linphone_gtk_fill_webcams(GtkWidget *pb); -void linphone_gtk_load_identities(void); -void linphone_gtk_call_log_update(GtkWidget *w); -void linphone_gtk_create_log_window(void); -void linphone_gtk_log_show(void); -void linphone_gtk_show_main_window(void); -void linphone_gtk_log_push(OrtpLogLevel lev, const char *fmt, va_list args); -void linphone_gtk_destroy_log_window(void); -void linphone_gtk_refer_received(LinphoneCore *lc, const char *refer_to); -gboolean linphone_gtk_check_logs(); -const gchar *linphone_gtk_get_ui_config(const char *key, const char *def); -int linphone_gtk_get_ui_config_int(const char *key, int def); -void linphone_gtk_set_ui_config_int(const char *key , int val); -void linphone_gtk_visibility_set(const char *hiddens, const char *window_name, GtkWidget *w, gboolean show); +LINPHONE_PUBLIC LinphoneCore *linphone_gtk_get_core(void); +LINPHONE_PUBLIC GtkWidget *linphone_gtk_get_main_window(); +LINPHONE_PUBLIC void linphone_gtk_display_something(GtkMessageType type, const gchar *message); +LINPHONE_PUBLIC void linphone_gtk_start_call(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_call_terminated(); +LINPHONE_PUBLIC void linphone_gtk_set_my_presence(LinphoneOnlineStatus ss); +LINPHONE_PUBLIC void linphone_gtk_show_parameters(void); +LINPHONE_PUBLIC void linphone_gtk_fill_soundcards(GtkWidget *pb); +LINPHONE_PUBLIC void linphone_gtk_fill_webcams(GtkWidget *pb); +LINPHONE_PUBLIC void linphone_gtk_load_identities(void); +LINPHONE_PUBLIC void linphone_gtk_call_log_update(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_create_log_window(void); +LINPHONE_PUBLIC void linphone_gtk_log_show(void); +LINPHONE_PUBLIC void linphone_gtk_show_main_window(void); +LINPHONE_PUBLIC void linphone_gtk_log_push(OrtpLogLevel lev, const char *fmt, va_list args); +LINPHONE_PUBLIC void linphone_gtk_destroy_log_window(void); +LINPHONE_PUBLIC void linphone_gtk_refer_received(LinphoneCore *lc, const char *refer_to); +LINPHONE_PUBLIC gboolean linphone_gtk_check_logs(); +LINPHONE_PUBLIC const gchar *linphone_gtk_get_ui_config(const char *key, const char *def); +LINPHONE_PUBLIC int linphone_gtk_get_ui_config_int(const char *key, int def); +LINPHONE_PUBLIC void linphone_gtk_set_ui_config_int(const char *key, int val); +LINPHONE_PUBLIC void linphone_gtk_visibility_set(const char *hiddens, const char *window_name, GtkWidget *w, gboolean show); -LinphoneLDAPContactProvider* linphone_gtk_get_ldap(void); -void linphone_gtk_set_ldap(LinphoneLDAPContactProvider* ldap); -int linphone_gtk_is_ldap_supported(void); +LINPHONE_PUBLIC LinphoneLDAPContactProvider* linphone_gtk_get_ldap(void); +LINPHONE_PUBLIC void linphone_gtk_set_ldap(LinphoneLDAPContactProvider* ldap); +LINPHONE_PUBLIC int linphone_gtk_is_ldap_supported(void); -void linphone_gtk_open_browser(const char *url); -void linphone_gtk_check_for_new_version(void); -const char *linphone_gtk_get_lang(const char *config_file); -void linphone_gtk_set_lang(const char *code); -SipSetupContext* linphone_gtk_get_default_sip_setup_context(void); -GtkWidget * linphone_gtk_show_buddy_lookup_window(SipSetupContext *ctx); -void linphone_gtk_buddy_lookup_set_keyword(GtkWidget *w, const char *kw); -void * linphone_gtk_wait(LinphoneCore *lc, void *ctx, LinphoneWaitingState ws, const char *purpose, float progress); -void linphone_gtk_terminate_call(GtkWidget *button); -void linphone_gtk_call_update_tab_header(LinphoneCall *call,gboolean pause); -void linphone_gtk_show_directory_search(void); -void linphone_gtk_status_icon_set_blinking(gboolean val); -void linphone_gtk_notify(LinphoneCall *call, const char *msg); +LINPHONE_PUBLIC void linphone_gtk_open_browser(const char *url); +LINPHONE_PUBLIC void linphone_gtk_check_for_new_version(void); +LINPHONE_PUBLIC const char *linphone_gtk_get_lang(const char *config_file); +LINPHONE_PUBLIC void linphone_gtk_set_lang(const char *code); +LINPHONE_PUBLIC SipSetupContext* linphone_gtk_get_default_sip_setup_context(void); +LINPHONE_PUBLIC GtkWidget * linphone_gtk_show_buddy_lookup_window(SipSetupContext *ctx); +LINPHONE_PUBLIC void linphone_gtk_buddy_lookup_set_keyword(GtkWidget *w, const char *kw); +LINPHONE_PUBLIC void * linphone_gtk_wait(LinphoneCore *lc, void *ctx, LinphoneWaitingState ws, const char *purpose, float progress); +LINPHONE_PUBLIC void linphone_gtk_terminate_call(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_call_update_tab_header(LinphoneCall *call, gboolean pause); +LINPHONE_PUBLIC void linphone_gtk_show_directory_search(void); +LINPHONE_PUBLIC void linphone_gtk_status_icon_set_blinking(gboolean val); +LINPHONE_PUBLIC void linphone_gtk_notify(LinphoneCall *call, const char *msg); -void linphone_gtk_load_chatroom(LinphoneChatRoom *cr,const LinphoneAddress *uri,GtkWidget *chat_view); -void linphone_gtk_send_text(); -GtkWidget * linphone_gtk_init_chatroom(LinphoneChatRoom *cr, const LinphoneAddress *with); -LinphoneChatRoom * linphone_gtk_create_chatroom(const LinphoneAddress *with); -void linphone_gtk_text_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *msg); -void linphone_gtk_is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room); +LINPHONE_PUBLIC void linphone_gtk_load_chatroom(LinphoneChatRoom *cr, const LinphoneAddress *uri, GtkWidget *chat_view); +LINPHONE_PUBLIC void linphone_gtk_send_text(); +LINPHONE_PUBLIC GtkWidget * linphone_gtk_init_chatroom(LinphoneChatRoom *cr, const LinphoneAddress *with); +LINPHONE_PUBLIC LinphoneChatRoom * linphone_gtk_create_chatroom(const LinphoneAddress *with); +LINPHONE_PUBLIC void linphone_gtk_text_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *msg); +LINPHONE_PUBLIC void linphone_gtk_is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room); -void linphone_gtk_friend_list_update_chat_picture(); -void linphone_gtk_friend_list_set_chat_conversation(const LinphoneAddress *la); -gboolean linphone_gtk_friend_list_is_contact(const LinphoneAddress *addr); -void linphone_gtk_friend_list_set_active_address(const LinphoneAddress *addr); -const LinphoneAddress *linphone_gtk_friend_list_get_active_address(void); -void linphone_gtk_notebook_tab_select(GtkNotebook *notebook,GtkWidget *page,guint page_num, gpointer data); -void linphone_gtk_show_friends(void); -void linphone_gtk_show_contact(LinphoneFriend *lf); -void linphone_gtk_buddy_info_updated(LinphoneCore *lc, LinphoneFriend *lf); +LINPHONE_PUBLIC void linphone_gtk_friend_list_update_chat_picture(); +LINPHONE_PUBLIC void linphone_gtk_friend_list_set_chat_conversation(const LinphoneAddress *la); +LINPHONE_PUBLIC gboolean linphone_gtk_friend_list_is_contact(const LinphoneAddress *addr); +LINPHONE_PUBLIC void linphone_gtk_friend_list_set_active_address(const LinphoneAddress *addr); +LINPHONE_PUBLIC const LinphoneAddress *linphone_gtk_friend_list_get_active_address(void); +LINPHONE_PUBLIC void linphone_gtk_notebook_tab_select(GtkNotebook *notebook, GtkWidget *page, guint page_num, gpointer data); +LINPHONE_PUBLIC void linphone_gtk_show_friends(void); +LINPHONE_PUBLIC void linphone_gtk_show_contact(LinphoneFriend *lf); +LINPHONE_PUBLIC void linphone_gtk_buddy_info_updated(LinphoneCore *lc, LinphoneFriend *lf); /*functions controlling the different views*/ -gboolean linphone_gtk_use_in_call_view(); -LinphoneCall *linphone_gtk_get_currently_displayed_call(gboolean *is_conf); -void linphone_gtk_create_in_call_view(LinphoneCall *call); -void linphone_gtk_in_call_view_set_calling(LinphoneCall *call); -void linphone_gtk_in_call_view_set_in_call(LinphoneCall *call); -void linphone_gtk_in_call_view_update_duration(LinphoneCall *call); -void linphone_gtk_in_call_view_terminate(LinphoneCall *call, const char *error_msg); -void linphone_gtk_in_call_view_set_incoming(LinphoneCall *call); -void linphone_gtk_in_call_view_set_paused(LinphoneCall *call); -void linphone_gtk_in_call_view_set_transfer_status(LinphoneCall *call,LinphoneCallState cstate); -void linphone_gtk_mute_clicked(GtkButton *button); -void transfer_button_clicked(GtkWidget *button, gpointer call_ref); -void linphone_gtk_enable_mute_button(GtkButton *button, gboolean sensitive); -void linphone_gtk_enable_hold_button(LinphoneCall *call, gboolean sensitive, gboolean holdon); -void linphone_gtk_enable_transfer_button(LinphoneCore *lc, gboolean value); -void linphone_gtk_enable_conference_button(LinphoneCore *lc, gboolean value); -void linphone_gtk_set_in_conference(LinphoneCall *call); -void linphone_gtk_unset_from_conference(LinphoneCall *call); -void linphone_gtk_terminate_conference_participant(LinphoneCall *call); -void linphone_gtk_in_call_view_show_encryption(LinphoneCall *call); -void linphone_gtk_update_video_button(LinphoneCall *call); -void linphone_gtk_init_audio_meter(GtkWidget *w, get_volume_t get_volume, void *data); -void linphone_gtk_uninit_audio_meter(GtkWidget *w); +LINPHONE_PUBLIC gboolean linphone_gtk_use_in_call_view(); +LINPHONE_PUBLIC LinphoneCall *linphone_gtk_get_currently_displayed_call(gboolean *is_conf); +LINPHONE_PUBLIC void linphone_gtk_create_in_call_view(LinphoneCall *call); +LINPHONE_PUBLIC void linphone_gtk_in_call_view_set_calling(LinphoneCall *call); +LINPHONE_PUBLIC void linphone_gtk_in_call_view_set_in_call(LinphoneCall *call); +LINPHONE_PUBLIC void linphone_gtk_in_call_view_update_duration(LinphoneCall *call); +LINPHONE_PUBLIC void linphone_gtk_in_call_view_terminate(LinphoneCall *call, const char *error_msg); +LINPHONE_PUBLIC void linphone_gtk_in_call_view_set_incoming(LinphoneCall *call); +LINPHONE_PUBLIC void linphone_gtk_in_call_view_set_paused(LinphoneCall *call); +LINPHONE_PUBLIC void linphone_gtk_in_call_view_set_transfer_status(LinphoneCall *call, LinphoneCallState cstate); +LINPHONE_PUBLIC void linphone_gtk_mute_clicked(GtkButton *button); +LINPHONE_PUBLIC void transfer_button_clicked(GtkWidget *button, gpointer call_ref); +LINPHONE_PUBLIC void linphone_gtk_enable_mute_button(GtkButton *button, gboolean sensitive); +LINPHONE_PUBLIC void linphone_gtk_enable_hold_button(LinphoneCall *call, gboolean sensitive, gboolean holdon); +LINPHONE_PUBLIC void linphone_gtk_enable_transfer_button(LinphoneCore *lc, gboolean value); +LINPHONE_PUBLIC void linphone_gtk_enable_conference_button(LinphoneCore *lc, gboolean value); +LINPHONE_PUBLIC void linphone_gtk_set_in_conference(LinphoneCall *call); +LINPHONE_PUBLIC void linphone_gtk_unset_from_conference(LinphoneCall *call); +LINPHONE_PUBLIC void linphone_gtk_terminate_conference_participant(LinphoneCall *call); +LINPHONE_PUBLIC void linphone_gtk_in_call_view_show_encryption(LinphoneCall *call); +LINPHONE_PUBLIC void linphone_gtk_update_video_button(LinphoneCall *call); +LINPHONE_PUBLIC void linphone_gtk_init_audio_meter(GtkWidget *w, get_volume_t get_volume, void *data); +LINPHONE_PUBLIC void linphone_gtk_uninit_audio_meter(GtkWidget *w); -void linphone_gtk_show_login_frame(LinphoneProxyConfig *cfg, gboolean disable_auto_login); -void linphone_gtk_exit_login_frame(void); -void linphone_gtk_set_ui_config(const char *key, const char *value); +LINPHONE_PUBLIC void linphone_gtk_show_login_frame(LinphoneProxyConfig *cfg, gboolean disable_auto_login); +LINPHONE_PUBLIC void linphone_gtk_exit_login_frame(void); +LINPHONE_PUBLIC void linphone_gtk_set_ui_config(const char *key, const char *value); -void linphone_gtk_log_uninit(); +LINPHONE_PUBLIC void linphone_gtk_log_uninit(); -bool_t linphone_gtk_init_instance(const char *app_name, int option, const char *addr_to_call); -void linphone_gtk_uninit_instance(void); -void linphone_gtk_monitor_usb(void); -void linphone_gtk_unmonitor_usb(void); +LINPHONE_PUBLIC bool_t linphone_gtk_init_instance(const char *app_name, int option, const char *addr_to_call); +LINPHONE_PUBLIC void linphone_gtk_uninit_instance(void); +LINPHONE_PUBLIC void linphone_gtk_monitor_usb(void); +LINPHONE_PUBLIC void linphone_gtk_unmonitor_usb(void); -void linphone_gtk_fill_combo_box(GtkWidget *combo, const char **devices, const char *selected, DeviceCap cap); -gchar *linphone_gtk_get_record_path(const LinphoneAddress *address, gboolean is_conference); -void linphone_gtk_schedule_restart(void); +LINPHONE_PUBLIC void linphone_gtk_fill_combo_box(GtkWidget *combo, const char **devices, const char *selected, DeviceCap cap); +LINPHONE_PUBLIC gchar *linphone_gtk_get_record_path(const LinphoneAddress *address, gboolean is_conference); +LINPHONE_PUBLIC void linphone_gtk_schedule_restart(void); -void linphone_gtk_show_audio_assistant(void); -gboolean linphone_gtk_get_audio_assistant_option(void); +LINPHONE_PUBLIC void linphone_gtk_show_audio_assistant(void); +LINPHONE_PUBLIC gboolean linphone_gtk_get_audio_assistant_option(void); -void linphone_gtk_set_configuration_uri(void); -GtkWidget * linphone_gtk_show_config_fetching(void); -void linphone_gtk_close_config_fetching(GtkWidget *w, LinphoneConfiguringState state); -const char *linphone_gtk_get_sound_path(const char *file); -void linphone_gtk_in_call_show_video(LinphoneCall *call); -char *linphone_gtk_address(const LinphoneAddress *addr);/*return human readable identifier for a LinphoneAddress */ -GtkWidget *linphone_gtk_get_camera_preview_window(void); +LINPHONE_PUBLIC void linphone_gtk_set_configuration_uri(void); +LINPHONE_PUBLIC GtkWidget * linphone_gtk_show_config_fetching(void); +LINPHONE_PUBLIC void linphone_gtk_close_config_fetching(GtkWidget *w, LinphoneConfiguringState state); +LINPHONE_PUBLIC const char *linphone_gtk_get_sound_path(const char *file); +LINPHONE_PUBLIC void linphone_gtk_in_call_show_video(LinphoneCall *call); +LINPHONE_PUBLIC char *linphone_gtk_address(const LinphoneAddress *addr);/*return human readable identifier for a LinphoneAddress */ +LINPHONE_PUBLIC GtkWidget *linphone_gtk_get_camera_preview_window(void); +LINPHONE_PUBLIC void linphone_gtk_login_frame_connect_clicked(GtkWidget *button); + +LINPHONE_PUBLIC gboolean linphone_gtk_call_log_reset_missed_call(GtkWidget *w, GdkEvent *event, gpointer user_data); +LINPHONE_PUBLIC void linphone_gtk_history_row_activated(GtkWidget *treeview); +LINPHONE_PUBLIC void linphone_gtk_history_row_selected(GtkWidget *treeview); +LINPHONE_PUBLIC void linphone_gtk_clear_call_logs(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_add_contact(void); +LINPHONE_PUBLIC void linphone_gtk_contact_activated(GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data); +LINPHONE_PUBLIC void linphone_gtk_contact_clicked(GtkTreeView *treeview); +LINPHONE_PUBLIC void linphone_gtk_add_button_clicked(void); +LINPHONE_PUBLIC void linphone_gtk_edit_button_clicked(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_remove_button_clicked(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_my_presence_clicked(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_directory_search_button_clicked(GtkWidget *button); +LINPHONE_PUBLIC gboolean linphone_gtk_popup_contact_menu(GtkWidget *list, GdkEventButton *event); +LINPHONE_PUBLIC gboolean linphone_gtk_contact_list_button_pressed(GtkWidget *widget, GdkEventButton *event); +LINPHONE_PUBLIC void linphone_gtk_auth_token_verified_clicked(GtkButton *button); +LINPHONE_PUBLIC void linphone_gtk_hold_clicked(GtkButton *button); +LINPHONE_PUBLIC void linphone_gtk_record_call_toggled(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_log_hide(void); +LINPHONE_PUBLIC void linphone_gtk_log_scroll_to_end(GtkToggleButton *button); +LINPHONE_PUBLIC void linphone_gtk_log_clear(void); +LINPHONE_PUBLIC void linphone_gtk_logout_clicked(void); + +LINPHONE_PUBLIC void linphone_gtk_about_response(GtkDialog *dialog, gint id); +LINPHONE_PUBLIC void linphone_gtk_show_about(void); +LINPHONE_PUBLIC void linphone_gtk_start_call(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_uri_bar_activate(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_terminate_call(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_decline_clicked(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_answer_clicked(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_enable_video(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_enable_self_view(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_used_identity_changed(GtkWidget *w); +LINPHONE_PUBLIC void on_proxy_refresh_button_clicked(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_link_to_website(GtkWidget *item); +LINPHONE_PUBLIC void linphone_gtk_options_activate(GtkWidget *item); +LINPHONE_PUBLIC void linphone_gtk_create_keypad(GtkWidget *button); + +LINPHONE_PUBLIC void linphone_gtk_keyword_changed(GtkEditable *e); +LINPHONE_PUBLIC void linphone_gtk_buddy_lookup_contact_activated(GtkWidget *treeview); +LINPHONE_PUBLIC void linphone_gtk_add_buddy_from_database(GtkWidget *button); +LINPHONE_PUBLIC gboolean linphone_gtk_call_log_button_pressed(GtkWidget *widget, GdkEventButton *event); +LINPHONE_PUBLIC void linphone_gtk_call_statistics_closed(GtkWidget *call_stats); +LINPHONE_PUBLIC void linphone_gtk_config_uri_cancel(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_config_uri_changed(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_contact_cancel(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_contact_ok(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_dscp_edit(void); +LINPHONE_PUBLIC void linphone_gtk_dscp_edit_response(GtkWidget *dialog, guint response_id); +LINPHONE_PUBLIC void linphone_gtk_keypad_key_released(GtkWidget *w, GdkEvent *event, gpointer userdata); +LINPHONE_PUBLIC void linphone_gtk_keypad_key_pressed(GtkWidget *w, GdkEvent *event, gpointer userdata); +LINPHONE_PUBLIC void linphone_gtk_ldap_save(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_ldap_reset(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_parameters_destroyed(GtkWidget *pb); +LINPHONE_PUBLIC void linphone_gtk_mtu_set(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_mtu_changed(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_use_sip_info_dtmf_toggled(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_ipv6_toggled(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_disabled_udp_port_toggle(GtkCheckButton *button); +LINPHONE_PUBLIC void linphone_gtk_random_udp_port_toggle(GtkCheckButton *button); +LINPHONE_PUBLIC void linphone_gtk_udp_port_value_changed(GtkSpinButton *button); +LINPHONE_PUBLIC void linphone_gtk_disabled_tcp_port_toggle(GtkCheckButton *button); +LINPHONE_PUBLIC void linphone_gtk_random_tcp_port_toggle(GtkCheckButton *button); +LINPHONE_PUBLIC void linphone_gtk_tcp_port_value_changed(GtkSpinButton *button); +LINPHONE_PUBLIC void linphone_gtk_min_audio_port_changed(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_max_audio_port_changed(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_fixed_audio_port_toggle(void); +LINPHONE_PUBLIC void linphone_gtk_min_video_port_changed(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_max_video_port_changed(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_fixed_video_port_toggle(void); +LINPHONE_PUBLIC void linphone_gtk_set_media_encryption_mandatory(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_edit_tunnel(GtkButton *button); +LINPHONE_PUBLIC void linphone_gtk_no_firewall_toggled(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_use_nat_address_toggled(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_use_stun_toggled(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_use_ice_toggled(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_use_upnp_toggled(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_nat_address_changed(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_stun_server_changed(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_ring_file_set(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_play_ring_file(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_alsa_special_device_changed(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_capture_device_changed(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_ring_device_changed(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_playback_device_changed(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_echo_cancelation_toggled(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_cam_changed(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_video_size_changed(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_video_renderer_changed(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_show_camera_preview_clicked(GtkButton *button); +LINPHONE_PUBLIC void linphone_gtk_update_my_contact(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_add_proxy(GtkButton *button); +LINPHONE_PUBLIC void linphone_gtk_edit_proxy(GtkButton *button); +LINPHONE_PUBLIC void linphone_gtk_remove_proxy(GtkButton *button); +LINPHONE_PUBLIC void linphone_gtk_clear_passwords(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_codec_view_changed(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_codec_up(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_codec_down(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_codec_enable(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_codec_disable(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_upload_bw_changed(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_download_bw_changed(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_adaptive_rate_control_toggled(GtkToggleButton *button); +LINPHONE_PUBLIC void linphone_gtk_lang_changed(GtkComboBox *combo); +LINPHONE_PUBLIC void linphone_gtk_ui_level_toggled(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_show_ldap_config(GtkWidget* button); +LINPHONE_PUBLIC void linphone_gtk_parameters_closed(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_password_ok(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_password_cancel(GtkWidget *w); +LINPHONE_PUBLIC void linphone_gtk_proxy_ok(GtkButton *button); +LINPHONE_PUBLIC void linphone_gtk_proxy_cancel(GtkButton *button); +LINPHONE_PUBLIC void linphone_gtk_proxy_address_changed(GtkEditable *editable); +LINPHONE_PUBLIC void linphone_gtk_proxy_transport_changed(GtkWidget *combo); +LINPHONE_PUBLIC void linphone_gtk_tunnel_ok(GtkButton *button); diff --git a/gtk/logging.c b/gtk/logging.c index c5eb883c0..c91f51138 100644 --- a/gtk/logging.c +++ b/gtk/logging.c @@ -202,7 +202,7 @@ static void linphone_gtk_log_file(OrtpLogLevel lev, const char *msg) } } -void linphone_gtk_log_hide(){ +void linphone_gtk_log_hide(void){ if (log_window) gtk_widget_hide(log_window); } diff --git a/gtk/loginframe.c b/gtk/loginframe.c index 7b6bd0c2b..727a746d1 100644 --- a/gtk/loginframe.c +++ b/gtk/loginframe.c @@ -19,7 +19,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "linphone.h" -void linphone_gtk_login_frame_connect_clicked(GtkWidget *button); void test_button_clicked_cb(GtkWidget *button); void linphone_gtk_exit_login_frame(void); @@ -122,7 +121,7 @@ void linphone_gtk_exit_login_frame(void){ gtk_widget_show(linphone_gtk_get_widget(mw,"disconnect_item")); } -void linphone_gtk_logout_clicked(){ +void linphone_gtk_logout_clicked(void){ LinphoneCore *lc=linphone_gtk_get_core(); LinphoneProxyConfig *cfg=NULL; linphone_core_get_default_proxy(lc,&cfg); diff --git a/gtk/main.c b/gtk/main.c index f840435cc..ac0b4cd52 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -27,7 +27,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include +#ifndef WIN32 #include +#endif #ifdef HAVE_GTK_OSX #include @@ -36,6 +38,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifdef WIN32 #define chdir _chdir #include "direct.h" +#ifndef F_OK +#define F_OK 00 /*visual studio does not define F_OK*/ +#endif #endif #if defined(HAVE_NOTIFY1) || defined(HAVE_NOTIFY4) @@ -102,77 +107,43 @@ static gchar *custom_config_file=NULL; static gboolean restart=FALSE; static GtkWidget *config_fetching_dialog=NULL; +#if _MSC_VER + +#define LINPHONE_OPTION(optlname, optsname, optarg, optargdata, optdesc) \ +{ \ + optlname, \ + optsname, \ + 0, \ + optarg, \ + optargdata, \ + optdesc, \ + NULL \ +} + +#else + +#define LINPHONE_OPTION(optlname, optsname, optarg, optargdata, optdesc) \ +{ \ + .long_name = optlname, \ + .short_name = optsname, \ + .arg = optarg, \ + .arg_data = optargdata, \ + .description = optdesc, \ +} + +#endif + static GOptionEntry linphone_options[]={ - { - .long_name="verbose", - .short_name= '\0', - .arg=G_OPTION_ARG_NONE, - .arg_data= (gpointer)&verbose, - .description=N_("log to stdout some debug information while running.") - }, - { - .long_name = "logfile", - .short_name = 'l', - .arg = G_OPTION_ARG_STRING, - .arg_data = &linphone_logfile, - .description = N_("path to a file to write logs into.") - }, - { - .long_name = "no-video", - .short_name = '\0', - .arg = G_OPTION_ARG_NONE, - .arg_data = (gpointer)&no_video, - .description = N_("Start linphone with video disabled.") - }, - { - .long_name="iconified", - .short_name= '\0', - .arg=G_OPTION_ARG_NONE, - .arg_data= (gpointer)&iconified, - .description=N_("Start only in the system tray, do not show the main interface.") - }, - { - .long_name = "call", - .short_name = 'c', - .arg = G_OPTION_ARG_STRING, - .arg_data = &addr_to_call, - .description = N_("address to call right now") - }, - { - .long_name = "auto-answer", - .short_name = 'a', - .arg = G_OPTION_ARG_NONE, - .arg_data = (gpointer) & auto_answer, - .description = N_("if set automatically answer incoming calls") - }, - { - .long_name = "workdir", - .short_name = '\0', - .arg = G_OPTION_ARG_STRING, - .arg_data = (gpointer) & workingdir, - .description = N_("Specifiy a working directory (should be the base of the installation, eg: c:\\Program Files\\Linphone)") - }, - { - .long_name = "config", - .short_name = '\0', - .arg = G_OPTION_ARG_FILENAME, - .arg_data = (gpointer) &custom_config_file, - .description = N_("Configuration file") - }, - { - .long_name = "run-audio-assistant", - .short_name = '\0', - .arg = G_OPTION_ARG_NONE, - .arg_data = (gpointer) &run_audio_assistant, - .description = N_("Run the audio assistant") - }, - { - .long_name = "selftest", - .short_name = '\0', - .arg = G_OPTION_ARG_NONE, - .arg_data = (gpointer) &selftest, - .description = N_("Run self test and exit 0 if succeed") - }, + LINPHONE_OPTION("verbose", '\0', G_OPTION_ARG_NONE, (gpointer)&verbose, N_("log to stdout some debug information while running.")), + LINPHONE_OPTION("logfile", 'l', G_OPTION_ARG_STRING, &linphone_logfile, N_("path to a file to write logs into.")), + LINPHONE_OPTION("no-video", '\0', G_OPTION_ARG_NONE, (gpointer)&no_video, N_("Start linphone with video disabled.")), + LINPHONE_OPTION("iconified", '\0', G_OPTION_ARG_NONE, (gpointer)&iconified, N_("Start only in the system tray, do not show the main interface.")), + LINPHONE_OPTION("call", 'c', G_OPTION_ARG_STRING, &addr_to_call, N_("address to call right now")), + LINPHONE_OPTION("auto-answer", 'a', G_OPTION_ARG_NONE, (gpointer) & auto_answer, N_("if set automatically answer incoming calls")), + LINPHONE_OPTION("workdir", '\0', G_OPTION_ARG_STRING, (gpointer) & workingdir, N_("Specifiy a working directory (should be the base of the installation, eg: c:\\Program Files\\Linphone)")), + LINPHONE_OPTION("config", '\0', G_OPTION_ARG_FILENAME, (gpointer) &custom_config_file, N_("Configuration file")), + LINPHONE_OPTION("run-audio-assistant", '\0', G_OPTION_ARG_NONE, (gpointer) &run_audio_assistant, N_("Run the audio assistant")), + LINPHONE_OPTION("selftest", '\0', G_OPTION_ARG_NONE, (gpointer) &selftest, N_("Run self test and exit 0 if succeed")), {0} }; @@ -538,7 +509,7 @@ static void about_url_clicked(GtkAboutDialog *dialog, const char *url, gpointer linphone_gtk_open_browser(url); } -void linphone_gtk_show_about(){ +void linphone_gtk_show_about(void){ struct stat filestat; const char *license_file=PACKAGE_DATA_DIR "/linphone/COPYING"; GtkWidget *about; @@ -557,7 +528,7 @@ void linphone_gtk_show_about(){ if (filestat.st_size>0){ char *license=g_malloc(filestat.st_size+1); FILE *f=fopen(license_file,"r"); - if (f && fread(license,filestat.st_size,1,f)==1){ + if (f && fread(license,1,filestat.st_size,f)>0){ license[filestat.st_size]='\0'; gtk_about_dialog_set_license(GTK_ABOUT_DIALOG(about),license); } @@ -2114,7 +2085,7 @@ int main(int argc, char *argv[]){ progpath = strdup(argv[0]); config_file=linphone_gtk_get_config_file(NULL); - + workingdir= (tmp=g_getenv("LINPHONE_WORKDIR")) ? g_strdup(tmp) : NULL; #ifdef WIN32 @@ -2141,6 +2112,7 @@ int main(int argc, char *argv[]){ } #elif __APPLE__ setenv("LANG",lang,1); + setenv("LANGUAGE",lang,1); #else setenv("LANGUAGE",lang,1); #endif @@ -2166,7 +2138,7 @@ int main(int argc, char *argv[]){ g_critical("%s", error->message); return -1; } - if (config_file) free(config_file); + if (config_file) g_free(config_file); if (custom_config_file && !g_path_is_absolute(custom_config_file)) { gchar *res = g_get_current_dir(); res = g_strjoin(G_DIR_SEPARATOR_S, res, custom_config_file, NULL); @@ -2257,7 +2229,7 @@ core_start: restart=FALSE; goto core_start; } - if (config_file) free(config_file); + if (config_file) g_free(config_file); #ifndef HAVE_GTK_OSX /*workaround a bug on win32 that makes status icon still present in the systray even after program exit.*/ if (icon) gtk_status_icon_set_visible(icon,FALSE); @@ -2266,3 +2238,8 @@ core_start: return 0; } +#ifdef _MSC_VER +int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { + return main(__argc, __argv); +} +#endif diff --git a/gtk/propertybox.c b/gtk/propertybox.c index 8a271c3dd..5f2c177ab 100644 --- a/gtk/propertybox.c +++ b/gtk/propertybox.c @@ -1741,7 +1741,7 @@ static int read_dscp(GtkWidget *entry){ return -1; } -void linphone_gtk_dscp_edit(){ +void linphone_gtk_dscp_edit(void){ LinphoneCore *lc=linphone_gtk_get_core(); GtkWidget *widget=linphone_gtk_create_window("dscp_settings"); show_dscp(linphone_gtk_get_widget(widget,"sip_dscp"), diff --git a/gtk/videowindow.c b/gtk/videowindow.c index 220569077..8d26eb212 100644 --- a/gtk/videowindow.c +++ b/gtk/videowindow.c @@ -260,7 +260,7 @@ static GtkWidget *create_video_window(LinphoneCall *call){ const char *icon_path=linphone_gtk_get_ui_config("icon",LINPHONE_ICON); GdkPixbuf *pbuf=create_pixbuf(icon_path); guint timeout; - MSVideoSize vsize=MS_VIDEO_SIZE_CIF; + MSVideoSize vsize={MS_VIDEO_SIZE_CIF_W,MS_VIDEO_SIZE_CIF_H}; GdkColor color; addr=linphone_call_get_remote_address(call); diff --git a/include/MSVC/inttypes.h b/include/MSVC/inttypes.h new file mode 100644 index 000000000..4b3828a21 --- /dev/null +++ b/include/MSVC/inttypes.h @@ -0,0 +1,305 @@ +// ISO C9x compliant inttypes.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. The name of the author may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_INTTYPES_H_ // [ +#define _MSC_INTTYPES_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include "stdint.h" + +// 7.8 Format conversion of integer types + +typedef struct { + intmax_t quot; + intmax_t rem; +} imaxdiv_t; + +// 7.8.1 Macros for format specifiers + +#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 + +// The fprintf macros for signed integers are: +#define PRId8 "d" +#define PRIi8 "i" +#define PRIdLEAST8 "d" +#define PRIiLEAST8 "i" +#define PRIdFAST8 "d" +#define PRIiFAST8 "i" + +#define PRId16 "hd" +#define PRIi16 "hi" +#define PRIdLEAST16 "hd" +#define PRIiLEAST16 "hi" +#define PRIdFAST16 "hd" +#define PRIiFAST16 "hi" + +#define PRId32 "I32d" +#define PRIi32 "I32i" +#define PRIdLEAST32 "I32d" +#define PRIiLEAST32 "I32i" +#define PRIdFAST32 "I32d" +#define PRIiFAST32 "I32i" + +#define PRId64 "I64d" +#define PRIi64 "I64i" +#define PRIdLEAST64 "I64d" +#define PRIiLEAST64 "I64i" +#define PRIdFAST64 "I64d" +#define PRIiFAST64 "I64i" + +#define PRIdMAX "I64d" +#define PRIiMAX "I64i" + +#define PRIdPTR "Id" +#define PRIiPTR "Ii" + +// The fprintf macros for unsigned integers are: +#define PRIo8 "o" +#define PRIu8 "u" +#define PRIx8 "x" +#define PRIX8 "X" +#define PRIoLEAST8 "o" +#define PRIuLEAST8 "u" +#define PRIxLEAST8 "x" +#define PRIXLEAST8 "X" +#define PRIoFAST8 "o" +#define PRIuFAST8 "u" +#define PRIxFAST8 "x" +#define PRIXFAST8 "X" + +#define PRIo16 "ho" +#define PRIu16 "hu" +#define PRIx16 "hx" +#define PRIX16 "hX" +#define PRIoLEAST16 "ho" +#define PRIuLEAST16 "hu" +#define PRIxLEAST16 "hx" +#define PRIXLEAST16 "hX" +#define PRIoFAST16 "ho" +#define PRIuFAST16 "hu" +#define PRIxFAST16 "hx" +#define PRIXFAST16 "hX" + +#define PRIo32 "I32o" +#define PRIu32 "I32u" +#define PRIx32 "I32x" +#define PRIX32 "I32X" +#define PRIoLEAST32 "I32o" +#define PRIuLEAST32 "I32u" +#define PRIxLEAST32 "I32x" +#define PRIXLEAST32 "I32X" +#define PRIoFAST32 "I32o" +#define PRIuFAST32 "I32u" +#define PRIxFAST32 "I32x" +#define PRIXFAST32 "I32X" + +#define PRIo64 "I64o" +#define PRIu64 "I64u" +#define PRIx64 "I64x" +#define PRIX64 "I64X" +#define PRIoLEAST64 "I64o" +#define PRIuLEAST64 "I64u" +#define PRIxLEAST64 "I64x" +#define PRIXLEAST64 "I64X" +#define PRIoFAST64 "I64o" +#define PRIuFAST64 "I64u" +#define PRIxFAST64 "I64x" +#define PRIXFAST64 "I64X" + +#define PRIoMAX "I64o" +#define PRIuMAX "I64u" +#define PRIxMAX "I64x" +#define PRIXMAX "I64X" + +#define PRIoPTR "Io" +#define PRIuPTR "Iu" +#define PRIxPTR "Ix" +#define PRIXPTR "IX" + +// The fscanf macros for signed integers are: +#define SCNd8 "d" +#define SCNi8 "i" +#define SCNdLEAST8 "d" +#define SCNiLEAST8 "i" +#define SCNdFAST8 "d" +#define SCNiFAST8 "i" + +#define SCNd16 "hd" +#define SCNi16 "hi" +#define SCNdLEAST16 "hd" +#define SCNiLEAST16 "hi" +#define SCNdFAST16 "hd" +#define SCNiFAST16 "hi" + +#define SCNd32 "ld" +#define SCNi32 "li" +#define SCNdLEAST32 "ld" +#define SCNiLEAST32 "li" +#define SCNdFAST32 "ld" +#define SCNiFAST32 "li" + +#define SCNd64 "I64d" +#define SCNi64 "I64i" +#define SCNdLEAST64 "I64d" +#define SCNiLEAST64 "I64i" +#define SCNdFAST64 "I64d" +#define SCNiFAST64 "I64i" + +#define SCNdMAX "I64d" +#define SCNiMAX "I64i" + +#ifdef _WIN64 // [ +# define SCNdPTR "I64d" +# define SCNiPTR "I64i" +#else // _WIN64 ][ +# define SCNdPTR "ld" +# define SCNiPTR "li" +#endif // _WIN64 ] + +// The fscanf macros for unsigned integers are: +#define SCNo8 "o" +#define SCNu8 "u" +#define SCNx8 "x" +#define SCNX8 "X" +#define SCNoLEAST8 "o" +#define SCNuLEAST8 "u" +#define SCNxLEAST8 "x" +#define SCNXLEAST8 "X" +#define SCNoFAST8 "o" +#define SCNuFAST8 "u" +#define SCNxFAST8 "x" +#define SCNXFAST8 "X" + +#define SCNo16 "ho" +#define SCNu16 "hu" +#define SCNx16 "hx" +#define SCNX16 "hX" +#define SCNoLEAST16 "ho" +#define SCNuLEAST16 "hu" +#define SCNxLEAST16 "hx" +#define SCNXLEAST16 "hX" +#define SCNoFAST16 "ho" +#define SCNuFAST16 "hu" +#define SCNxFAST16 "hx" +#define SCNXFAST16 "hX" + +#define SCNo32 "lo" +#define SCNu32 "lu" +#define SCNx32 "lx" +#define SCNX32 "lX" +#define SCNoLEAST32 "lo" +#define SCNuLEAST32 "lu" +#define SCNxLEAST32 "lx" +#define SCNXLEAST32 "lX" +#define SCNoFAST32 "lo" +#define SCNuFAST32 "lu" +#define SCNxFAST32 "lx" +#define SCNXFAST32 "lX" + +#define SCNo64 "I64o" +#define SCNu64 "I64u" +#define SCNx64 "I64x" +#define SCNX64 "I64X" +#define SCNoLEAST64 "I64o" +#define SCNuLEAST64 "I64u" +#define SCNxLEAST64 "I64x" +#define SCNXLEAST64 "I64X" +#define SCNoFAST64 "I64o" +#define SCNuFAST64 "I64u" +#define SCNxFAST64 "I64x" +#define SCNXFAST64 "I64X" + +#define SCNoMAX "I64o" +#define SCNuMAX "I64u" +#define SCNxMAX "I64x" +#define SCNXMAX "I64X" + +#ifdef _WIN64 // [ +# define SCNoPTR "I64o" +# define SCNuPTR "I64u" +# define SCNxPTR "I64x" +# define SCNXPTR "I64X" +#else // _WIN64 ][ +# define SCNoPTR "lo" +# define SCNuPTR "lu" +# define SCNxPTR "lx" +# define SCNXPTR "lX" +#endif // _WIN64 ] + +#endif // __STDC_FORMAT_MACROS ] + +// 7.8.2 Functions for greatest-width integer types + +// 7.8.2.1 The imaxabs function +#define imaxabs _abs64 + +// 7.8.2.2 The imaxdiv function + +// This is modified version of div() function from Microsoft's div.c found +// in %MSVC.NET%\crt\src\div.c +#ifdef STATIC_IMAXDIV // [ +static +#else // STATIC_IMAXDIV ][ +_inline +#endif // STATIC_IMAXDIV ] +imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) +{ + imaxdiv_t result; + + result.quot = numer / denom; + result.rem = numer % denom; + + if (numer < 0 && result.rem > 0) { + // did division wrong; must fix up + ++result.quot; + result.rem -= denom; + } + + return result; +} + +// 7.8.2.3 The strtoimax and strtoumax functions +#define strtoimax _strtoi64 +#define strtoumax _strtoui64 + +// 7.8.2.4 The wcstoimax and wcstoumax functions +#define wcstoimax _wcstoi64 +#define wcstoumax _wcstoui64 + + +#endif // _MSC_INTTYPES_H_ ] diff --git a/include/MSVC/stdint.h b/include/MSVC/stdint.h new file mode 100644 index 000000000..d02608a59 --- /dev/null +++ b/include/MSVC/stdint.h @@ -0,0 +1,247 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2008 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. The name of the author may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include + +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when +// compiling for ARM we should wrap include with 'extern "C++" {}' +// or compiler give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#ifdef __cplusplus +extern "C" { +#endif +# include +#ifdef __cplusplus +} +#endif + +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types + +// Visual Studio 6 and Embedded Visual C++ 4 doesn't +// realize that, e.g. char has the same size as __int8 +// so we give up on __intX for them. +#if (_MSC_VER < 1300) + typedef signed char int8_t; + typedef signed short int16_t; + typedef signed int int32_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; +#else + typedef signed __int8 int8_t; + typedef signed __int16 int16_t; + typedef signed __int32 int32_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; +#endif +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; + + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ + typedef signed __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef _W64 signed int intptr_t; + typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +# define INTPTR_MIN INT64_MIN +# define INTPTR_MAX INT64_MAX +# define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +# define INTPTR_MIN INT32_MIN +# define INTPTR_MAX INT32_MAX +# define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +# define PTRDIFF_MIN _I64_MIN +# define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +# define PTRDIFF_MIN _I32_MIN +# define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +# ifdef _WIN64 // [ +# define SIZE_MAX _UI64_MAX +# else // _WIN64 ][ +# define SIZE_MAX _UI32_MAX +# endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in +#ifndef WCHAR_MIN // [ +# define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +# define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +#define INTMAX_C INT64_C +#define UINTMAX_C UINT64_C + +#endif // __STDC_CONSTANT_MACROS ] + + +#endif // _MSC_STDINT_H_ ] diff --git a/include/sal/sal.h b/include/sal/sal.h index 7d0ae1eb7..a663c16cd 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -698,9 +698,9 @@ int sal_call_notify_refer_state(SalOp *h, SalOp *newcall); * @param h the Sal instance * @param handling_method Could be SalOpSDPNormal, SalOpSDPSimulateError, SalOpSDPSimulateRemoval (\ref SalOpSDPHandling) */ -void sal_default_set_sdp_handling(Sal* h, SalOpSDPHandling handling_method) ; +LINPHONE_PUBLIC void sal_default_set_sdp_handling(Sal* h, SalOpSDPHandling handling_method) ; /* Second version: for a specific call*/ -void sal_call_set_sdp_handling(SalOp *h, SalOpSDPHandling handling) ; +LINPHONE_PUBLIC void sal_call_set_sdp_handling(SalOp *h, SalOpSDPHandling handling) ; /*Registration*/ int sal_register(SalOp *op, const char *proxy, const char *from, int expires); @@ -710,7 +710,7 @@ int sal_unregister(SalOp *h); /*Messaging */ int sal_text_send(SalOp *op, const char *from, const char *to, const char *text); -int sal_message_send(SalOp *op, const char *from, const char *to, const char* content_type, const char *msg); +int sal_message_send(SalOp *op, const char *from, const char *to, const char* content_type, const char *msg, const char *peer_uri); int sal_message_reply(SalOp *op, SalReason reason); /*presence Subscribe/notify*/ @@ -812,7 +812,7 @@ LINPHONE_PUBLIC bool_t sal_dns_srv_enabled(const Sal *sal); LINPHONE_PUBLIC void sal_set_dns_user_hosts_file(Sal *sal, const char *hosts_file); LINPHONE_PUBLIC const char *sal_get_dns_user_hosts_file(const Sal *sal); unsigned int sal_get_random(void); -char *sal_get_random_token(int size); +LINPHONE_PUBLIC char *sal_get_random_token(int size); unsigned char * sal_get_random_bytes(unsigned char *ret, size_t size); belle_sip_source_t * sal_create_timer(Sal *sal, belle_sip_source_func_t func, void *data, unsigned int timeout_value_ms, const char* timer_name); void sal_cancel_timer(Sal *sal, belle_sip_source_t *timer); @@ -821,7 +821,7 @@ int sal_body_has_type(const SalBody *body, const char *type, const char *subtype /*this function parses a document with key=value pairs separated by new lines, and extracts the value for a given key*/ int sal_lines_get_value(const char *data, const char *key, char *value, size_t value_size); -belle_sip_stack_t *sal_get_belle_sip_stack(Sal *sal); +LINPHONE_PUBLIC belle_sip_stack_t *sal_get_belle_sip_stack(Sal *sal); char* sal_op_get_public_uri(SalOp *sal); unsigned long sal_begin_background_task(const char *name, void (*max_time_reached)(void *), void *data); diff --git a/java/common/org/linphone/core/LinphoneBuffer.java b/java/common/org/linphone/core/LinphoneBuffer.java new file mode 100644 index 000000000..1aee74c18 --- /dev/null +++ b/java/common/org/linphone/core/LinphoneBuffer.java @@ -0,0 +1,15 @@ +package org.linphone.core; + +/** + * The LinphoneContent object representing a data buffer. +**/ +public interface LinphoneBuffer { + + byte[] getContent(); + + void setContent(byte[] data); + + int getSize(); + + void setSize(int size); +} diff --git a/java/common/org/linphone/core/LinphoneChatMessage.java b/java/common/org/linphone/core/LinphoneChatMessage.java index b1b839b5e..b80c3a070 100644 --- a/java/common/org/linphone/core/LinphoneChatMessage.java +++ b/java/common/org/linphone/core/LinphoneChatMessage.java @@ -4,9 +4,38 @@ import java.util.Vector; public interface LinphoneChatMessage { - interface StateListener{ + @Deprecated + interface StateListener { void onLinphoneChatMessageStateChanged(LinphoneChatMessage msg, State state); } + + interface LinphoneChatMessageListener { + void onLinphoneChatMessageStateChanged(LinphoneChatMessage msg, State state); + + /** + * This function is called by the core upon an incoming File transfer is started. This function may be call several time for the same file in case of large file. + * @param content incoming content information + * @param buffer holding the received data. Empty buffer means end of file. + */ + void onLinphoneChatMessageFileTransferReceived(LinphoneChatMessage msg, LinphoneContent content, LinphoneBuffer buffer); + + /** + * This function is called by the core when an outgoing file transfer is started. This function is called until size is set to 0. + * @param content incoming content information + * @param offset the offset in the file from where to get the data to be sent + * @param size the number of bytes expected by the framework + * @param bufferToFill A LinphoneBuffer object holding the data written by the application. An empty buffer means end of file. + */ + void onLinphoneChatMessageFileTransferSent(LinphoneChatMessage msg, LinphoneContent content, int offset, int size, LinphoneBuffer bufferToFill); + + /** + * File transfer progress indication callback prototype. + * @param content incoming content information + * @param offset The number of bytes sent/received since the beginning of the transfer. + * @param total The total number of bytes to be sent/received. + */ + void onLinphoneChatMessageFileTransferProgressChanged(LinphoneChatMessage msg, LinphoneContent content, int offset, int total); + } public static class State { static private Vector values = new Vector(); private final int mValue; @@ -33,6 +62,10 @@ public interface LinphoneChatMessage { * Message was received(and acknowledged) but cannot get file from server */ public final static State FileTransferError = new State(4,"FileTransferError"); + /** + * File transfer has been completed successfully. + */ + public final static State FileTransferDone = new State(5,"FileTransferDone"); private State(int value,String stringValue) { mValue = value; @@ -158,11 +191,6 @@ public interface LinphoneChatMessage { */ ErrorInfo getErrorInfo(); - /** - * Start the download of the file bundled in the message - */ - void startFileDownload(LinphoneChatMessage.StateListener listener); - /** * Cancel an ongoing file transfer attached to this message.(upload or download). */ @@ -184,4 +212,19 @@ public interface LinphoneChatMessage { */ String getAppData(); + /** + * Set the path to the file to read from or write to during the file transfer. + * @param path The path to the file to use for the file transfer. + */ + void setFileTransferFilepath(String path); + + /** + * Start the download of the file referenced in a LinphoneChatMessage from remote server. + */ + void downloadFile(); + + /** + * Set the callbacks associated with the LinphoneChatMessage. + */ + void setListener(LinphoneChatMessage.LinphoneChatMessageListener listener); } diff --git a/java/common/org/linphone/core/LinphoneChatRoom.java b/java/common/org/linphone/core/LinphoneChatRoom.java index b18e79d0c..f94f4e764 100644 --- a/java/common/org/linphone/core/LinphoneChatRoom.java +++ b/java/common/org/linphone/core/LinphoneChatRoom.java @@ -44,6 +44,7 @@ public interface LinphoneChatRoom { * Send a message to peer member of this chat room. * @param chat message */ + @Deprecated void sendMessage(LinphoneChatMessage message, LinphoneChatMessage.StateListener listener); /** @@ -144,4 +145,9 @@ public interface LinphoneChatRoom { */ LinphoneChatMessage createFileTransferMessage(LinphoneContent content); + /** + * + * @param message + */ + void sendChatMessage(LinphoneChatMessage message); } diff --git a/java/common/org/linphone/core/LinphoneCore.java b/java/common/org/linphone/core/LinphoneCore.java index 62d6de6e8..2c4616dd8 100644 --- a/java/common/org/linphone/core/LinphoneCore.java +++ b/java/common/org/linphone/core/LinphoneCore.java @@ -1164,6 +1164,12 @@ public interface LinphoneCore { * If the device has a builtin echo canceller or calibration value is already known, it will return false. */ boolean needsEchoCalibration(); + + /** + * Returns true if the software echo canceler needs to be turned on. + * If the device has a builtin echo canceller, it will return false. + */ + boolean needsEchoCanceler(); void enableIpv6(boolean enable); diff --git a/java/common/org/linphone/core/LinphoneCoreFactory.java b/java/common/org/linphone/core/LinphoneCoreFactory.java index f7d5ccd66..8019ec7bd 100644 --- a/java/common/org/linphone/core/LinphoneCoreFactory.java +++ b/java/common/org/linphone/core/LinphoneCoreFactory.java @@ -145,7 +145,7 @@ abstract public class LinphoneCoreFactory { /** * Create a LinphoneContent object from byte array. */ - abstract public LinphoneContent createLinphoneContent(String type, String subType,byte [] data, String encoding); + abstract public LinphoneContent createLinphoneContent(String type, String subType, byte[] data, String encoding); /** * Create a PresenceActivity object. diff --git a/java/impl/org/linphone/core/LinphoneBufferImpl.java b/java/impl/org/linphone/core/LinphoneBufferImpl.java new file mode 100644 index 000000000..143fd1e17 --- /dev/null +++ b/java/impl/org/linphone/core/LinphoneBufferImpl.java @@ -0,0 +1,33 @@ +package org.linphone.core; + +public class LinphoneBufferImpl implements LinphoneBuffer { + private byte[] mData; + private int mSize; + + public LinphoneBufferImpl(byte[] data, int size) + { + mData = data; + mSize = size; + } + + @Override + public byte[] getContent() { + return mData; + } + + @Override + public void setContent(byte[] data) { + mData = data; + } + + @Override + public int getSize() { + return mSize; + } + + @Override + public void setSize(int size) { + mSize = size; + } + +} diff --git a/java/impl/org/linphone/core/LinphoneChatMessageImpl.java b/java/impl/org/linphone/core/LinphoneChatMessageImpl.java index 59a1dc509..8665e4049 100644 --- a/java/impl/org/linphone/core/LinphoneChatMessageImpl.java +++ b/java/impl/org/linphone/core/LinphoneChatMessageImpl.java @@ -15,6 +15,9 @@ public class LinphoneChatMessageImpl implements LinphoneChatMessage { private native boolean isOutgoing(long ptr); private native void store(long ptr); private native int getStorageId(long ptr); + private native void setFileTransferFilepath(long ptr, String path); + private native void downloadFile(long ptr); + private native void setListener(long ptr, LinphoneChatMessageListener listener); private native void unref(long ptr); protected LinphoneChatMessageImpl(long aNativePtr) { @@ -113,12 +116,6 @@ public class LinphoneChatMessageImpl implements LinphoneChatMessage { super.finalize(); } - private native void startFileDownload(long ptr, StateListener listener); - @Override - public void startFileDownload(StateListener listener) { - startFileDownload(nativePtr, listener); - } - private native Object getFileTransferInformation(long ptr); @Override public LinphoneContent getFileTransferInformation() { @@ -142,4 +139,19 @@ public class LinphoneChatMessageImpl implements LinphoneChatMessage { public void cancelFileTransfer() { cancelFileTransfer(nativePtr); } + + @Override + public void setFileTransferFilepath(String path) { + setFileTransferFilepath(nativePtr, path); + } + + @Override + public void downloadFile() { + downloadFile(nativePtr); + } + + @Override + public void setListener(LinphoneChatMessageListener listener) { + setListener(nativePtr, listener); + } } diff --git a/java/impl/org/linphone/core/LinphoneChatRoomImpl.java b/java/impl/org/linphone/core/LinphoneChatRoomImpl.java index 9236bce03..cfda7b6e2 100644 --- a/java/impl/org/linphone/core/LinphoneChatRoomImpl.java +++ b/java/impl/org/linphone/core/LinphoneChatRoomImpl.java @@ -21,6 +21,7 @@ package org.linphone.core; import org.linphone.core.LinphoneChatMessage.State; import org.linphone.core.LinphoneChatMessage.StateListener; +@SuppressWarnings("deprecation") class LinphoneChatRoomImpl implements LinphoneChatRoom { protected final long nativePtr; private native long createLinphoneChatMessage(long ptr, String message); @@ -41,6 +42,7 @@ class LinphoneChatRoomImpl implements LinphoneChatRoom { private native long createLinphoneChatMessage2(long ptr, String message, String url, int state, long timestamp, boolean isRead, boolean isIncoming); + private native void sendChatMessage(long ptr, Object message, long messagePtr); protected LinphoneChatRoomImpl(long aNativePtr) { nativePtr = aNativePtr; @@ -176,5 +178,8 @@ class LinphoneChatRoomImpl implements LinphoneChatRoom { return new LinphoneChatMessageImpl(createFileTransferMessage(nativePtr, content.getName(), content.getType(), content.getSubtype(), content.getRealSize())); } } - + @Override + public void sendChatMessage(LinphoneChatMessage message) { + sendChatMessage(nativePtr, message, ((LinphoneChatMessageImpl)message).getNativePtr()); + } } diff --git a/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java b/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java index 90fd5a0f6..5b2a87c55 100644 --- a/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java +++ b/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java @@ -154,7 +154,7 @@ public class LinphoneCoreFactoryImpl extends LinphoneCoreFactory { @Override public LinphoneContent createLinphoneContent(String type, String subType, String data) { - return new LinphoneContentImpl(type,subType,data.getBytes(),null); + return new LinphoneContentImpl(type,subType,data == null ? null : data.getBytes(), null); } @Override diff --git a/java/impl/org/linphone/core/LinphoneCoreImpl.java b/java/impl/org/linphone/core/LinphoneCoreImpl.java index 9586ea371..80d007172 100644 --- a/java/impl/org/linphone/core/LinphoneCoreImpl.java +++ b/java/impl/org/linphone/core/LinphoneCoreImpl.java @@ -1045,6 +1045,11 @@ class LinphoneCoreImpl implements LinphoneCore { public synchronized boolean needsEchoCalibration() { return needsEchoCalibration(nativePtr); } + private native boolean needsEchoCanceler(long ptr); + @Override + public synchronized boolean needsEchoCanceler() { + return needsEchoCanceler(nativePtr); + } private native void declineCall(long coreptr, long callptr, int reason); @Override public synchronized void declineCall(LinphoneCall aCall, Reason reason) { diff --git a/mediastreamer2 b/mediastreamer2 index e35a1e71b..8e8dd84a3 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit e35a1e71bdc64bc914b866b1a66815d5e47f8a01 +Subproject commit 8e8dd84a37db6d079b254229575b4109973b61a0 diff --git a/oRTP b/oRTP index 496b5b1fd..19ed314d5 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 496b5b1fd0053bf94e5e0fcecf9cd43713820ca1 +Subproject commit 19ed314d52d4061a21daa4805aef9459ad31640c diff --git a/po/ar.po b/po/ar.po index 97b57e7b5..ab28394f1 100644 --- a/po/ar.po +++ b/po/ar.po @@ -9,10 +9,9 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-02-17 12:28+0100\n" -"PO-Revision-Date: 2015-02-17 11:28+0000\n" -"Last-Translator: Belledonne Communications \n" +"POT-Creation-Date: 2015-03-11 16:26+0100\n" +"PO-Revision-Date: 2015-02-17 21:52+0000\n" +"Last-Translator: محيي الدين \n" "Language-Team: Arabic (http://www.transifex.com/projects/p/linphone-gtk/" "language/ar/)\n" "Language: ar\n" @@ -102,54 +101,54 @@ msgstr "أنا" msgid "Couldn't find pixmap file: %s" msgstr "أيقونة غير موجودة : %s" -#: ../gtk/chat.c:367 ../gtk/friendlist.c:924 +#: ../gtk/chat.c:374 ../gtk/friendlist.c:924 msgid "Invalid sip contact !" msgstr "جهة اتصال sip غير صالحة !" -#: ../gtk/main.c:109 +#: ../gtk/main.c:137 msgid "log to stdout some debug information while running." msgstr "أظهِرْ بعض معلومات التنقيح خلال التشغيل." -#: ../gtk/main.c:116 +#: ../gtk/main.c:138 msgid "path to a file to write logs into." msgstr "الدليل إلى الملف الذي سيُكتَب فيه سجل الوقائع." -#: ../gtk/main.c:123 +#: ../gtk/main.c:139 msgid "Start linphone with video disabled." msgstr "ابدأ لِنْفُونْ لكن دون تفعيل الفيديو." -#: ../gtk/main.c:130 +#: ../gtk/main.c:140 msgid "Start only in the system tray, do not show the main interface." msgstr "شغِّله مُصغَّرا، ولا تُظهِر الواجهة الرئيسية." -#: ../gtk/main.c:137 +#: ../gtk/main.c:141 msgid "address to call right now" msgstr "العنوان المُراد الاتصال به الآن" -#: ../gtk/main.c:144 +#: ../gtk/main.c:142 msgid "if set automatically answer incoming calls" msgstr "إذا تم التفعيل، سيجيب تلقائيا عن المكالمات الواردة" -#: ../gtk/main.c:151 +#: ../gtk/main.c:143 msgid "" "Specifiy a working directory (should be the base of the installation, eg: c:" "\\Program Files\\Linphone)" msgstr "" "حدِّد مجلد العمل (الذي سيكون مجلد التثبيت، مثلا c:\\Program Files\\Linphone)" -#: ../gtk/main.c:158 +#: ../gtk/main.c:144 msgid "Configuration file" msgstr "ملف التهيئة" -#: ../gtk/main.c:165 +#: ../gtk/main.c:145 msgid "Run the audio assistant" msgstr "ابدأ مرشد الصوت" -#: ../gtk/main.c:172 +#: ../gtk/main.c:146 msgid "Run self test and exit 0 if succeed" msgstr "شغِّل الاختبار الذاتي ثم اخرِجْ 0 إذا نجح" -#: ../gtk/main.c:1088 +#: ../gtk/main.c:1061 #, c-format msgid "" "%s would like to add you to his contact list.\n" @@ -161,7 +160,7 @@ msgstr "" "هل تريد السماح له برؤية معلومات حضورك وكذا إضافته إلى جهة اتصالك أيضا ؟ إذا " "أجبت ب لا، سيُحظَر هذا الشخص مؤقتا." -#: ../gtk/main.c:1165 +#: ../gtk/main.c:1138 #, c-format msgid "" "Please enter your password for username %s\n" @@ -170,59 +169,59 @@ msgstr "" "ادخل كلمة السر ل %s\n" " في نطاق %s:" -#: ../gtk/main.c:1286 +#: ../gtk/main.c:1259 msgid "Call error" msgstr "خطأ في المكالمة" -#: ../gtk/main.c:1289 ../coreapi/linphonecore.c:3787 +#: ../gtk/main.c:1262 ../coreapi/linphonecore.c:3791 msgid "Call ended" msgstr "إنتهت المكالمة" -#: ../gtk/main.c:1292 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1265 ../coreapi/call_log.c:221 msgid "Incoming call" msgstr "مكالمة واردة" -#: ../gtk/main.c:1294 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1267 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 msgid "Answer" msgstr "أجِبْ" -#: ../gtk/main.c:1296 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1269 ../gtk/main.ui.h:6 msgid "Decline" msgstr "ارفضْ" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 msgid "Call paused" msgstr "المكالمة متوقفة" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 #, c-format msgid "by %s" msgstr "بواسطة %s" -#: ../gtk/main.c:1372 +#: ../gtk/main.c:1345 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "يود %s تشغيل الفيديو. هل تقبل ذلك ؟" -#: ../gtk/main.c:1534 +#: ../gtk/main.c:1507 msgid "Website link" msgstr "وصلة إلى الموقع وِبْ" -#: ../gtk/main.c:1583 +#: ../gtk/main.c:1556 msgid "Linphone - a video internet phone" msgstr "لِنْفُونْ - الهاتف المرئي عبر الإنترنت" -#: ../gtk/main.c:1675 +#: ../gtk/main.c:1648 #, c-format msgid "%s (Default)" msgstr "%s (افتراضي)" -#: ../gtk/main.c:2007 ../coreapi/callbacks.c:1027 +#: ../gtk/main.c:1980 ../coreapi/callbacks.c:1045 #, c-format msgid "We are transferred to %s" msgstr "التحويل إلى %s" -#: ../gtk/main.c:2017 +#: ../gtk/main.c:1990 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." @@ -230,7 +229,7 @@ msgstr "" "لا وجود للوحة الصوت على هذا الحاسوب.\n" "لن تتمكن من تلقي أو إجراء أي مكالمة." -#: ../gtk/main.c:2161 +#: ../gtk/main.c:2135 msgid "A free SIP video-phone" msgstr "هاتف SIP المرئي الحر" @@ -394,7 +393,7 @@ msgstr "SRTP" #: ../gtk/propertybox.c:1246 msgid "DTLS" -msgstr "" +msgstr "DTLS" #: ../gtk/propertybox.c:1253 msgid "ZRTP" @@ -709,7 +708,7 @@ msgstr "آمن بواسطة SRTP" #: ../gtk/incall_view.c:685 msgid "Secured by DTLS" -msgstr "" +msgstr "مُؤمَّن بواسطة DTLS" #: ../gtk/incall_view.c:691 #, c-format @@ -773,7 +772,7 @@ msgstr "" msgid "(Paused)" msgstr "(متوقف)" -#: ../gtk/loginframe.c:88 +#: ../gtk/loginframe.c:87 #, c-format msgid "Please enter login information for %s" msgstr "يُرجى إدخال معلومات الولوج ل %s" @@ -1751,60 +1750,60 @@ msgstr "تجري التهيئة..." msgid "Please wait while fetching configuration from server..." msgstr "رجاءً انتظر ريثما ينتهي من جلب الإعدادات من الخادم..." -#: ../coreapi/linphonecore.c:1508 +#: ../coreapi/linphonecore.c:1512 msgid "Ready" msgstr "جاهز" -#: ../coreapi/linphonecore.c:2495 +#: ../coreapi/linphonecore.c:2499 msgid "Configuring" msgstr "تجري التهيئة" -#: ../coreapi/linphonecore.c:2669 +#: ../coreapi/linphonecore.c:2673 msgid "Looking for telephone number destination..." msgstr "يجري البحث عن وجهة رقم الهاتف..." -#: ../coreapi/linphonecore.c:2671 +#: ../coreapi/linphonecore.c:2675 msgid "Could not resolve this number." msgstr "لم يتمكن من إيجاد هذا الرقم." #. must be known at that time -#: ../coreapi/linphonecore.c:2957 +#: ../coreapi/linphonecore.c:2961 msgid "Contacting" msgstr "يتصل ب" -#: ../coreapi/linphonecore.c:2962 +#: ../coreapi/linphonecore.c:2966 msgid "Could not call" msgstr "لم يتمكن من الاتصال" -#: ../coreapi/linphonecore.c:3112 +#: ../coreapi/linphonecore.c:3116 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "آسف، وصل عدد المكالمات الآنية إلى حده الأقصى" -#: ../coreapi/linphonecore.c:3270 +#: ../coreapi/linphonecore.c:3274 msgid "is contacting you" msgstr "يتصل بك" -#: ../coreapi/linphonecore.c:3271 +#: ../coreapi/linphonecore.c:3275 msgid " and asked autoanswer." msgstr "ويطلب ردا تلقائيا." -#: ../coreapi/linphonecore.c:3395 +#: ../coreapi/linphonecore.c:3399 msgid "Modifying call parameters..." msgstr "يجري تعديل إعدادات المكالمة..." -#: ../coreapi/linphonecore.c:3743 +#: ../coreapi/linphonecore.c:3747 msgid "Connected." msgstr "متصل." -#: ../coreapi/linphonecore.c:3768 +#: ../coreapi/linphonecore.c:3772 msgid "Call aborted" msgstr "أُلغيت المكالمة" -#: ../coreapi/linphonecore.c:3958 +#: ../coreapi/linphonecore.c:3962 msgid "Could not pause the call" msgstr "لم يتمكن من توقيف المكالمة مؤقتا" -#: ../coreapi/linphonecore.c:3961 +#: ../coreapi/linphonecore.c:3965 msgid "Pausing the current call..." msgstr "وضع المكالمة قيد الانتظار..." @@ -1888,112 +1887,112 @@ msgstr "" msgid "Could not login as %s" msgstr "تعذر الولوج بالهوية %s" -#: ../coreapi/callbacks.c:404 +#: ../coreapi/callbacks.c:419 msgid "Remote ringing." msgstr "يرن الجرس عن بعد..." -#: ../coreapi/callbacks.c:425 +#: ../coreapi/callbacks.c:431 msgid "Remote ringing..." msgstr "يرن الجرس عن بعد..." -#: ../coreapi/callbacks.c:442 +#: ../coreapi/callbacks.c:448 msgid "Early media." msgstr "أخذ المكالمة مبكرا." -#: ../coreapi/callbacks.c:503 +#: ../coreapi/callbacks.c:521 #, c-format msgid "Call with %s is paused." msgstr "المكاملة مع %s متوقفة." -#: ../coreapi/callbacks.c:516 +#: ../coreapi/callbacks.c:534 #, c-format msgid "Call answered by %s - on hold." msgstr "يجيب %s عن المكالمة - في وضع الانتظار." -#: ../coreapi/callbacks.c:526 +#: ../coreapi/callbacks.c:544 msgid "Call resumed." msgstr "استُعيدت المكالمة." -#: ../coreapi/callbacks.c:530 +#: ../coreapi/callbacks.c:548 #, c-format msgid "Call answered by %s." msgstr "أجاب عن المكالمة %s." -#: ../coreapi/callbacks.c:553 +#: ../coreapi/callbacks.c:571 msgid "Incompatible, check codecs or security settings..." msgstr "غير موائم، تحقق من المراميز أو إعدادات الأمان..." -#: ../coreapi/callbacks.c:558 ../coreapi/callbacks.c:870 +#: ../coreapi/callbacks.c:576 ../coreapi/callbacks.c:888 msgid "Incompatible media parameters." msgstr "إعدادات الوسائط غير موائمة." -#: ../coreapi/callbacks.c:588 +#: ../coreapi/callbacks.c:606 msgid "We have been resumed." msgstr "استُأنِفت المكالمة." #. we are being paused -#: ../coreapi/callbacks.c:596 +#: ../coreapi/callbacks.c:614 msgid "We are paused by other party." msgstr "وُقِّفت المكالمة مؤقتا من طرف آخر." #. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:630 +#: ../coreapi/callbacks.c:648 msgid "Call is updated by remote." msgstr "حُدِّث الاتصال من البعيد." -#: ../coreapi/callbacks.c:746 +#: ../coreapi/callbacks.c:764 msgid "Call terminated." msgstr "أُنهيت المكالمة." -#: ../coreapi/callbacks.c:774 +#: ../coreapi/callbacks.c:792 msgid "User is busy." msgstr "المستخدم مشغول." -#: ../coreapi/callbacks.c:775 +#: ../coreapi/callbacks.c:793 msgid "User is temporarily unavailable." msgstr "المستخدم غير متاح مؤقتا." #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:777 +#: ../coreapi/callbacks.c:795 msgid "User does not want to be disturbed." msgstr "لا يريد المستخدم أي إزعاج." -#: ../coreapi/callbacks.c:778 +#: ../coreapi/callbacks.c:796 msgid "Call declined." msgstr "تم تجاهل المكالمة." -#: ../coreapi/callbacks.c:793 +#: ../coreapi/callbacks.c:811 msgid "Request timeout." msgstr "انتهت مهلة الطلب." -#: ../coreapi/callbacks.c:824 +#: ../coreapi/callbacks.c:842 msgid "Redirected" msgstr "مُوجَّه" -#: ../coreapi/callbacks.c:879 +#: ../coreapi/callbacks.c:897 msgid "Call failed." msgstr "فشل الاتصال." -#: ../coreapi/callbacks.c:957 +#: ../coreapi/callbacks.c:975 #, c-format msgid "Registration on %s successful." msgstr "تم التسجيل في %s بنجاح." -#: ../coreapi/callbacks.c:958 +#: ../coreapi/callbacks.c:976 #, c-format msgid "Unregistration on %s done." msgstr "أُلغي التسجيل في %s ." -#: ../coreapi/callbacks.c:976 +#: ../coreapi/callbacks.c:994 msgid "no response timeout" msgstr "لا إجابة قبل انتهاء المهلة" -#: ../coreapi/callbacks.c:979 +#: ../coreapi/callbacks.c:997 #, c-format msgid "Registration on %s failed: %s" msgstr "فَشِل التسجيل في %s: %s" -#: ../coreapi/callbacks.c:986 +#: ../coreapi/callbacks.c:1004 msgid "Service unavailable, retrying" msgstr "خدمة غير متاحة، تجري الإعادة" @@ -2003,7 +2002,7 @@ msgstr "خدمة غير متاحة، تجري الإعادة" msgid "Authentication token is %s" msgstr "شارة التحقق من الهوية هي %s" -#: ../coreapi/linphonecall.c:3492 +#: ../coreapi/linphonecall.c:3600 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." diff --git a/po/cs.po b/po/cs.po index 79d5e0344..6cf402f00 100644 --- a/po/cs.po +++ b/po/cs.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-02-17 12:28+0100\n" +"POT-Creation-Date: 2015-03-11 16:26+0100\n" "PO-Revision-Date: 2015-02-17 11:28+0000\n" "Last-Translator: Belledonne Communications \n" @@ -95,35 +95,35 @@ msgstr "Já" msgid "Couldn't find pixmap file: %s" msgstr "Nelze najít soubor s obrázkem: %s" -#: ../gtk/chat.c:367 ../gtk/friendlist.c:924 +#: ../gtk/chat.c:374 ../gtk/friendlist.c:924 msgid "Invalid sip contact !" msgstr "Neplatný sipový kontakt!" -#: ../gtk/main.c:109 +#: ../gtk/main.c:137 msgid "log to stdout some debug information while running." msgstr "Za běhu vypisuje některé ladicí informace na standardní výstup." -#: ../gtk/main.c:116 +#: ../gtk/main.c:138 msgid "path to a file to write logs into." msgstr "Soubor, kam zapisovat protokol." -#: ../gtk/main.c:123 +#: ../gtk/main.c:139 msgid "Start linphone with video disabled." msgstr "Spustí linphone se zakázaným obrazem." -#: ../gtk/main.c:130 +#: ../gtk/main.c:140 msgid "Start only in the system tray, do not show the main interface." msgstr "Spustí se pouze do systémové oblasti, nezobrazí hlavní okno." -#: ../gtk/main.c:137 +#: ../gtk/main.c:141 msgid "address to call right now" msgstr "Zavolá právě teď na tuto adresu" -#: ../gtk/main.c:144 +#: ../gtk/main.c:142 msgid "if set automatically answer incoming calls" msgstr "je-li nastaveno, automaticky zvedne příchozí hovor" -#: ../gtk/main.c:151 +#: ../gtk/main.c:143 msgid "" "Specifiy a working directory (should be the base of the installation, eg: c:" "\\Program Files\\Linphone)" @@ -131,19 +131,19 @@ msgstr "" "Zadejte pracovní adresář (měl by být základní instalační adresář, například " "c:\\Program Files\\Linphone)" -#: ../gtk/main.c:158 +#: ../gtk/main.c:144 msgid "Configuration file" msgstr "" -#: ../gtk/main.c:165 +#: ../gtk/main.c:145 msgid "Run the audio assistant" msgstr "" -#: ../gtk/main.c:172 +#: ../gtk/main.c:146 msgid "Run self test and exit 0 if succeed" msgstr "" -#: ../gtk/main.c:1088 +#: ../gtk/main.c:1061 #, c-format msgid "" "%s would like to add you to his contact list.\n" @@ -156,66 +156,66 @@ msgstr "" "do svého adresáře?\n" "Odpovíte-li ne, tato osobo bude dočasně blokována." -#: ../gtk/main.c:1165 +#: ../gtk/main.c:1138 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" msgstr "" -#: ../gtk/main.c:1286 +#: ../gtk/main.c:1259 msgid "Call error" msgstr "Chyba hovoru" -#: ../gtk/main.c:1289 ../coreapi/linphonecore.c:3787 +#: ../gtk/main.c:1262 ../coreapi/linphonecore.c:3791 msgid "Call ended" msgstr "Hovor ukončen" -#: ../gtk/main.c:1292 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1265 ../coreapi/call_log.c:221 msgid "Incoming call" msgstr "Příchozí hovor" -#: ../gtk/main.c:1294 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1267 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 msgid "Answer" msgstr "Odpovědět" -#: ../gtk/main.c:1296 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1269 ../gtk/main.ui.h:6 msgid "Decline" msgstr "Odmítnout" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 msgid "Call paused" msgstr "Hovor odložen" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 #, c-format msgid "by %s" msgstr "kým: %s" -#: ../gtk/main.c:1372 +#: ../gtk/main.c:1345 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "%s navrhuje začít videohovor. Přijímáte?" -#: ../gtk/main.c:1534 +#: ../gtk/main.c:1507 msgid "Website link" msgstr "Odkaz na webovou stránku" -#: ../gtk/main.c:1583 +#: ../gtk/main.c:1556 msgid "Linphone - a video internet phone" msgstr "Lipnhone – internetový videofon" -#: ../gtk/main.c:1675 +#: ../gtk/main.c:1648 #, c-format msgid "%s (Default)" msgstr "%s (Výchozí)" -#: ../gtk/main.c:2007 ../coreapi/callbacks.c:1027 +#: ../gtk/main.c:1980 ../coreapi/callbacks.c:1045 #, c-format msgid "We are transferred to %s" msgstr "Byly jsme přepojeni na %s" -#: ../gtk/main.c:2017 +#: ../gtk/main.c:1990 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." @@ -223,7 +223,7 @@ msgstr "" "Na tomto počítači nebyla objevena žádná zvuková karta.\n" "Nebudete moci vytáčet a přijímat a zvukové hovory." -#: ../gtk/main.c:2161 +#: ../gtk/main.c:2135 msgid "A free SIP video-phone" msgstr "Volný SIP videofon" @@ -762,7 +762,7 @@ msgstr "" msgid "(Paused)" msgstr "(Odloženo)" -#: ../gtk/loginframe.c:88 +#: ../gtk/loginframe.c:87 #, c-format msgid "Please enter login information for %s" msgstr "Prosím, zadejte své přihlašovací jméno pro %s:" @@ -1721,60 +1721,60 @@ msgstr "" msgid "Please wait while fetching configuration from server..." msgstr "" -#: ../coreapi/linphonecore.c:1508 +#: ../coreapi/linphonecore.c:1512 msgid "Ready" msgstr "Připraven." -#: ../coreapi/linphonecore.c:2495 +#: ../coreapi/linphonecore.c:2499 msgid "Configuring" msgstr "" -#: ../coreapi/linphonecore.c:2669 +#: ../coreapi/linphonecore.c:2673 msgid "Looking for telephone number destination..." msgstr "Vyhledává se umístění čísla…" -#: ../coreapi/linphonecore.c:2671 +#: ../coreapi/linphonecore.c:2675 msgid "Could not resolve this number." msgstr "Toto číslo nelze vyhledat." #. must be known at that time -#: ../coreapi/linphonecore.c:2957 +#: ../coreapi/linphonecore.c:2961 msgid "Contacting" msgstr "Navazuje se spojení" -#: ../coreapi/linphonecore.c:2962 +#: ../coreapi/linphonecore.c:2966 msgid "Could not call" msgstr "Nelze volat" -#: ../coreapi/linphonecore.c:3112 +#: ../coreapi/linphonecore.c:3116 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "Je nám líto, ale byl dosažen maximální počet současných hovorů." -#: ../coreapi/linphonecore.c:3270 +#: ../coreapi/linphonecore.c:3274 msgid "is contacting you" msgstr "vás volá" -#: ../coreapi/linphonecore.c:3271 +#: ../coreapi/linphonecore.c:3275 msgid " and asked autoanswer." msgstr " a požaduje automatickou zvednutí." -#: ../coreapi/linphonecore.c:3395 +#: ../coreapi/linphonecore.c:3399 msgid "Modifying call parameters..." msgstr "Upravují se parametry hovoru…" -#: ../coreapi/linphonecore.c:3743 +#: ../coreapi/linphonecore.c:3747 msgid "Connected." msgstr "Připojeno." -#: ../coreapi/linphonecore.c:3768 +#: ../coreapi/linphonecore.c:3772 msgid "Call aborted" msgstr "Hovor přerušen" -#: ../coreapi/linphonecore.c:3958 +#: ../coreapi/linphonecore.c:3962 msgid "Could not pause the call" msgstr "Hovor nebylo možné odložit" -#: ../coreapi/linphonecore.c:3961 +#: ../coreapi/linphonecore.c:3965 msgid "Pausing the current call..." msgstr "Současný hovor se odkládá…" @@ -1859,112 +1859,112 @@ msgstr "" msgid "Could not login as %s" msgstr "Nelze se přihlásit jako %s" -#: ../coreapi/callbacks.c:404 +#: ../coreapi/callbacks.c:419 msgid "Remote ringing." msgstr "Vyzvání na druhé straně." -#: ../coreapi/callbacks.c:425 +#: ../coreapi/callbacks.c:431 msgid "Remote ringing..." msgstr "Vyzvání na druhé straně…" -#: ../coreapi/callbacks.c:442 +#: ../coreapi/callbacks.c:448 msgid "Early media." msgstr "Časná média." -#: ../coreapi/callbacks.c:503 +#: ../coreapi/callbacks.c:521 #, c-format msgid "Call with %s is paused." msgstr "Hovor s %s je odložen." -#: ../coreapi/callbacks.c:516 +#: ../coreapi/callbacks.c:534 #, c-format msgid "Call answered by %s - on hold." msgstr "Hovor přijat kým: %s – odložen." -#: ../coreapi/callbacks.c:526 +#: ../coreapi/callbacks.c:544 msgid "Call resumed." msgstr "Hovor obnoven." -#: ../coreapi/callbacks.c:530 +#: ../coreapi/callbacks.c:548 #, c-format msgid "Call answered by %s." msgstr "Hovor přijat kým: %s." -#: ../coreapi/callbacks.c:553 +#: ../coreapi/callbacks.c:571 msgid "Incompatible, check codecs or security settings..." msgstr "Není slučitelné. Zkontrolujte nastavení kodeků a zabezpečení…" -#: ../coreapi/callbacks.c:558 ../coreapi/callbacks.c:870 +#: ../coreapi/callbacks.c:576 ../coreapi/callbacks.c:888 msgid "Incompatible media parameters." msgstr "Neslučitelné parametry médií." -#: ../coreapi/callbacks.c:588 +#: ../coreapi/callbacks.c:606 msgid "We have been resumed." msgstr "Byli jsme obnoveni." #. we are being paused -#: ../coreapi/callbacks.c:596 +#: ../coreapi/callbacks.c:614 msgid "We are paused by other party." msgstr "Byli jsme odloženi protistranou." #. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:630 +#: ../coreapi/callbacks.c:648 msgid "Call is updated by remote." msgstr "Hovor byl aktualizován protistranou." -#: ../coreapi/callbacks.c:746 +#: ../coreapi/callbacks.c:764 msgid "Call terminated." msgstr "Hovor ukončen." -#: ../coreapi/callbacks.c:774 +#: ../coreapi/callbacks.c:792 msgid "User is busy." msgstr "Uživatel je zaneprázdněn." -#: ../coreapi/callbacks.c:775 +#: ../coreapi/callbacks.c:793 msgid "User is temporarily unavailable." msgstr "Uživatel je dočasně nedostupný." #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:777 +#: ../coreapi/callbacks.c:795 msgid "User does not want to be disturbed." msgstr "Uživatel si nepřeje být rušen." -#: ../coreapi/callbacks.c:778 +#: ../coreapi/callbacks.c:796 msgid "Call declined." msgstr "Volání odmítnuto." -#: ../coreapi/callbacks.c:793 +#: ../coreapi/callbacks.c:811 msgid "Request timeout." msgstr "" -#: ../coreapi/callbacks.c:824 +#: ../coreapi/callbacks.c:842 msgid "Redirected" msgstr "Přesměrováno" -#: ../coreapi/callbacks.c:879 +#: ../coreapi/callbacks.c:897 msgid "Call failed." msgstr "Volání se nezdařilo." -#: ../coreapi/callbacks.c:957 +#: ../coreapi/callbacks.c:975 #, c-format msgid "Registration on %s successful." msgstr "Registrace na %s byla úspěšná." -#: ../coreapi/callbacks.c:958 +#: ../coreapi/callbacks.c:976 #, c-format msgid "Unregistration on %s done." msgstr "Odregistrování z %s hotovo." -#: ../coreapi/callbacks.c:976 +#: ../coreapi/callbacks.c:994 msgid "no response timeout" msgstr "odpověď nedorazila včas" -#: ../coreapi/callbacks.c:979 +#: ../coreapi/callbacks.c:997 #, c-format msgid "Registration on %s failed: %s" msgstr "Registrace na %s selhala: %s" -#: ../coreapi/callbacks.c:986 +#: ../coreapi/callbacks.c:1004 msgid "Service unavailable, retrying" msgstr "" @@ -1974,7 +1974,7 @@ msgstr "" msgid "Authentication token is %s" msgstr "Klíč k ověření totožnosti je %s" -#: ../coreapi/linphonecall.c:3492 +#: ../coreapi/linphonecall.c:3600 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." diff --git a/po/de.po b/po/de.po index 204117b52..645e8b52e 100644 --- a/po/de.po +++ b/po/de.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-02-17 12:28+0100\n" +"POT-Creation-Date: 2015-03-11 16:26+0100\n" "PO-Revision-Date: 2015-02-17 11:28+0000\n" "Last-Translator: Belledonne Communications \n" @@ -95,37 +95,37 @@ msgstr "Eigenes Telefon" msgid "Couldn't find pixmap file: %s" msgstr "Pixmapdatei %s kann nicht gefunden werden." -#: ../gtk/chat.c:367 ../gtk/friendlist.c:924 +#: ../gtk/chat.c:374 ../gtk/friendlist.c:924 msgid "Invalid sip contact !" msgstr "Ungültiger SIP-Kontakt!" -#: ../gtk/main.c:109 +#: ../gtk/main.c:137 msgid "log to stdout some debug information while running." msgstr "Ausgabe von Debug-Informationen auf stdout während der Laufzeit" -#: ../gtk/main.c:116 +#: ../gtk/main.c:138 msgid "path to a file to write logs into." msgstr "Pfad zu einer Datei, in die Protokolle geschrieben werden." -#: ../gtk/main.c:123 +#: ../gtk/main.c:139 msgid "Start linphone with video disabled." msgstr "Linphone mit ausgeschaltetem Video starten." -#: ../gtk/main.c:130 +#: ../gtk/main.c:140 msgid "Start only in the system tray, do not show the main interface." msgstr "" "Nur im Systemabschnitt der Kontrollleiste starten, aber das Hauptfenster " "nicht zeigen." -#: ../gtk/main.c:137 +#: ../gtk/main.c:141 msgid "address to call right now" msgstr "Im Moment anzurufende Adresse" -#: ../gtk/main.c:144 +#: ../gtk/main.c:142 msgid "if set automatically answer incoming calls" msgstr "Falls aktiviert, werden eingehende Anrufe automatisch beantwortet" -#: ../gtk/main.c:151 +#: ../gtk/main.c:143 msgid "" "Specifiy a working directory (should be the base of the installation, eg: c:" "\\Program Files\\Linphone)" @@ -133,19 +133,19 @@ msgstr "" "Geben Sie einen Arbeitsordner an (sollte der Installationsordner sein, z. B. " "C:\\Programme\\Linphone)" -#: ../gtk/main.c:158 +#: ../gtk/main.c:144 msgid "Configuration file" msgstr "Konfigurationsdatei" -#: ../gtk/main.c:165 +#: ../gtk/main.c:145 msgid "Run the audio assistant" msgstr "Starte den Audio-Assistent" -#: ../gtk/main.c:172 +#: ../gtk/main.c:146 msgid "Run self test and exit 0 if succeed" msgstr "" -#: ../gtk/main.c:1088 +#: ../gtk/main.c:1061 #, c-format msgid "" "%s would like to add you to his contact list.\n" @@ -158,7 +158,7 @@ msgstr "" "Ihrer Kontaktliste hinzufügen?\n" "Wenn Sie mit Nein antworten, wird diese Person vorläufig blockiert." -#: ../gtk/main.c:1165 +#: ../gtk/main.c:1138 #, c-format msgid "" "Please enter your password for username %s\n" @@ -167,59 +167,59 @@ msgstr "" "Bitte geben Sie Ihr Passwort für den Benutzernamen %s\n" " für Bereich %s ein:" -#: ../gtk/main.c:1286 +#: ../gtk/main.c:1259 msgid "Call error" msgstr "Anruf fehlgeschlagen" -#: ../gtk/main.c:1289 ../coreapi/linphonecore.c:3787 +#: ../gtk/main.c:1262 ../coreapi/linphonecore.c:3791 msgid "Call ended" msgstr "Anruf beendet" -#: ../gtk/main.c:1292 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1265 ../coreapi/call_log.c:221 msgid "Incoming call" msgstr "Eingehender Anruf" -#: ../gtk/main.c:1294 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1267 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 msgid "Answer" msgstr "Annehmen" -#: ../gtk/main.c:1296 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1269 ../gtk/main.ui.h:6 msgid "Decline" msgstr "Abweisen" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 msgid "Call paused" msgstr "Anruf wird gehalten" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 #, c-format msgid "by %s" msgstr "von %s" -#: ../gtk/main.c:1372 +#: ../gtk/main.c:1345 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "%s schlägt vor, eine Videoübertragung zu starten. Nehmen Sie an?" -#: ../gtk/main.c:1534 +#: ../gtk/main.c:1507 msgid "Website link" msgstr "Website-Verknüpfung" -#: ../gtk/main.c:1583 +#: ../gtk/main.c:1556 msgid "Linphone - a video internet phone" msgstr "Linphone - ein Internet-Video-Telefon" -#: ../gtk/main.c:1675 +#: ../gtk/main.c:1648 #, c-format msgid "%s (Default)" msgstr "%s (Vorgabe)" -#: ../gtk/main.c:2007 ../coreapi/callbacks.c:1027 +#: ../gtk/main.c:1980 ../coreapi/callbacks.c:1045 #, c-format msgid "We are transferred to %s" msgstr "Vermittlung nach %s" -#: ../gtk/main.c:2017 +#: ../gtk/main.c:1990 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." @@ -227,7 +227,7 @@ msgstr "" "Auf diesem Rechner können keine Soundkarten gefunden werden.\n" "Sie können keine Audio-Anrufe tätigen oder entgegennehmen." -#: ../gtk/main.c:2161 +#: ../gtk/main.c:2135 msgid "A free SIP video-phone" msgstr "Ein freies SIP-Video-Telefon" @@ -771,7 +771,7 @@ msgstr "" msgid "(Paused)" msgstr "(pausiert)" -#: ../gtk/loginframe.c:88 +#: ../gtk/loginframe.c:87 #, c-format msgid "Please enter login information for %s" msgstr "Bitte geben Sie die Anmeldeinformationen für %s ein." @@ -1755,60 +1755,60 @@ msgid "Please wait while fetching configuration from server..." msgstr "" "Bitte warten Sie während die Einstellungen vom Server abgerufen werden..." -#: ../coreapi/linphonecore.c:1508 +#: ../coreapi/linphonecore.c:1512 msgid "Ready" msgstr "Bereit" -#: ../coreapi/linphonecore.c:2495 +#: ../coreapi/linphonecore.c:2499 msgid "Configuring" msgstr "Einstellen" -#: ../coreapi/linphonecore.c:2669 +#: ../coreapi/linphonecore.c:2673 msgid "Looking for telephone number destination..." msgstr "Telefonnummernziel wird gesucht..." -#: ../coreapi/linphonecore.c:2671 +#: ../coreapi/linphonecore.c:2675 msgid "Could not resolve this number." msgstr "Diese Nummer kann nicht aufgelöst werden." #. must be known at that time -#: ../coreapi/linphonecore.c:2957 +#: ../coreapi/linphonecore.c:2961 msgid "Contacting" msgstr "Verbindungsaufbau" -#: ../coreapi/linphonecore.c:2962 +#: ../coreapi/linphonecore.c:2966 msgid "Could not call" msgstr "Anruf kann nicht getätigt werden." -#: ../coreapi/linphonecore.c:3112 +#: ../coreapi/linphonecore.c:3116 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "Die maximale Anzahl der gleichzeitigen Anrufe ist erreicht." -#: ../coreapi/linphonecore.c:3270 +#: ../coreapi/linphonecore.c:3274 msgid "is contacting you" msgstr "ruft Sie an" -#: ../coreapi/linphonecore.c:3271 +#: ../coreapi/linphonecore.c:3275 msgid " and asked autoanswer." msgstr " und fragt nach automatischer Antwort." -#: ../coreapi/linphonecore.c:3395 +#: ../coreapi/linphonecore.c:3399 msgid "Modifying call parameters..." msgstr "Die Anrufparameter werden verändert..." -#: ../coreapi/linphonecore.c:3743 +#: ../coreapi/linphonecore.c:3747 msgid "Connected." msgstr "Verbunden." -#: ../coreapi/linphonecore.c:3768 +#: ../coreapi/linphonecore.c:3772 msgid "Call aborted" msgstr "Anruf abgebrochen" -#: ../coreapi/linphonecore.c:3958 +#: ../coreapi/linphonecore.c:3962 msgid "Could not pause the call" msgstr "Anruf kann nicht gehalten werden" -#: ../coreapi/linphonecore.c:3961 +#: ../coreapi/linphonecore.c:3965 msgid "Pausing the current call..." msgstr "Aktueller Anruf wird gehalten..." @@ -1894,112 +1894,112 @@ msgstr "" msgid "Could not login as %s" msgstr "Anmeldung als %s fehlgeschlagen" -#: ../coreapi/callbacks.c:404 +#: ../coreapi/callbacks.c:419 msgid "Remote ringing." msgstr "Klingeln bei der Gegenseite." -#: ../coreapi/callbacks.c:425 +#: ../coreapi/callbacks.c:431 msgid "Remote ringing..." msgstr "Klingeln bei der Gegenseite..." -#: ../coreapi/callbacks.c:442 +#: ../coreapi/callbacks.c:448 msgid "Early media." msgstr "nicht kompatibel, prüfe Codecs oder Sicherheitseinstellungen..." -#: ../coreapi/callbacks.c:503 +#: ../coreapi/callbacks.c:521 #, c-format msgid "Call with %s is paused." msgstr "Anruf mit %s wird gehalten." -#: ../coreapi/callbacks.c:516 +#: ../coreapi/callbacks.c:534 #, c-format msgid "Call answered by %s - on hold." msgstr "Der von %s entgegengenommene Anruf wird gehalten." -#: ../coreapi/callbacks.c:526 +#: ../coreapi/callbacks.c:544 msgid "Call resumed." msgstr "Anruf fortgesetzt." -#: ../coreapi/callbacks.c:530 +#: ../coreapi/callbacks.c:548 #, c-format msgid "Call answered by %s." msgstr "Anruf wird von %s entgegengenommen." -#: ../coreapi/callbacks.c:553 +#: ../coreapi/callbacks.c:571 msgid "Incompatible, check codecs or security settings..." msgstr "Inkompatibel, prüfe Codecs oder Sicherheitseinstellungen..." -#: ../coreapi/callbacks.c:558 ../coreapi/callbacks.c:870 +#: ../coreapi/callbacks.c:576 ../coreapi/callbacks.c:888 msgid "Incompatible media parameters." msgstr "Inkompatible Medienparameter." -#: ../coreapi/callbacks.c:588 +#: ../coreapi/callbacks.c:606 msgid "We have been resumed." msgstr "Anruf wird fortgesetzt." #. we are being paused -#: ../coreapi/callbacks.c:596 +#: ../coreapi/callbacks.c:614 msgid "We are paused by other party." msgstr "Anruf wird von der Gegenseite gehalten." #. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:630 +#: ../coreapi/callbacks.c:648 msgid "Call is updated by remote." msgstr "Anruf ist von der Gegenseite aktualisiert worden." -#: ../coreapi/callbacks.c:746 +#: ../coreapi/callbacks.c:764 msgid "Call terminated." msgstr "Anruf beendet." -#: ../coreapi/callbacks.c:774 +#: ../coreapi/callbacks.c:792 msgid "User is busy." msgstr "Teilnehmer ist besetzt." -#: ../coreapi/callbacks.c:775 +#: ../coreapi/callbacks.c:793 msgid "User is temporarily unavailable." msgstr "Teilnehmer zur Zeit nicht verfügbar." #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:777 +#: ../coreapi/callbacks.c:795 msgid "User does not want to be disturbed." msgstr "Teilnehmer möchte nicht gestört werden." -#: ../coreapi/callbacks.c:778 +#: ../coreapi/callbacks.c:796 msgid "Call declined." msgstr "Anruf abgewiesen" -#: ../coreapi/callbacks.c:793 +#: ../coreapi/callbacks.c:811 msgid "Request timeout." msgstr "Zeitüberschreitung bei der Anfrage" -#: ../coreapi/callbacks.c:824 +#: ../coreapi/callbacks.c:842 msgid "Redirected" msgstr "Umgeleitet" -#: ../coreapi/callbacks.c:879 +#: ../coreapi/callbacks.c:897 msgid "Call failed." msgstr "Anruf fehlgeschlagen." -#: ../coreapi/callbacks.c:957 +#: ../coreapi/callbacks.c:975 #, c-format msgid "Registration on %s successful." msgstr "Registrierung auf %s erfolgreich." -#: ../coreapi/callbacks.c:958 +#: ../coreapi/callbacks.c:976 #, c-format msgid "Unregistration on %s done." msgstr "Abmeldung von %s ist erfolgt." -#: ../coreapi/callbacks.c:976 +#: ../coreapi/callbacks.c:994 msgid "no response timeout" msgstr "Zeitüberschreitung bei der Antwort" -#: ../coreapi/callbacks.c:979 +#: ../coreapi/callbacks.c:997 #, c-format msgid "Registration on %s failed: %s" msgstr "Registrierung auf %s fehlgeschlagen: %s" -#: ../coreapi/callbacks.c:986 +#: ../coreapi/callbacks.c:1004 msgid "Service unavailable, retrying" msgstr "Service nicht verfügbar, versuche erneut" @@ -2009,7 +2009,7 @@ msgstr "Service nicht verfügbar, versuche erneut" msgid "Authentication token is %s" msgstr "Authentifizierungs-Token ist %s" -#: ../coreapi/linphonecall.c:3492 +#: ../coreapi/linphonecall.c:3600 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." diff --git a/po/es.po b/po/es.po index db3d1dd72..c3e0b494f 100644 --- a/po/es.po +++ b/po/es.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-02-17 12:28+0100\n" +"POT-Creation-Date: 2015-03-11 16:26+0100\n" "PO-Revision-Date: 2015-02-17 11:28+0000\n" "Last-Translator: Belledonne Communications \n" @@ -89,36 +89,36 @@ msgstr "Yo" msgid "Couldn't find pixmap file: %s" msgstr "No se pudo encontrar el archivo pixmap: %s" -#: ../gtk/chat.c:367 ../gtk/friendlist.c:924 +#: ../gtk/chat.c:374 ../gtk/friendlist.c:924 msgid "Invalid sip contact !" msgstr "¡Contacto SIP no válido!" -#: ../gtk/main.c:109 +#: ../gtk/main.c:137 msgid "log to stdout some debug information while running." msgstr "" "registra a stdout cierta información de depuración durante la ejecución." -#: ../gtk/main.c:116 +#: ../gtk/main.c:138 msgid "path to a file to write logs into." msgstr "ruta a un fichero donde escribir logs." -#: ../gtk/main.c:123 +#: ../gtk/main.c:139 msgid "Start linphone with video disabled." msgstr "" -#: ../gtk/main.c:130 +#: ../gtk/main.c:140 msgid "Start only in the system tray, do not show the main interface." msgstr "Iniciar sólo en la barra de tareas, no mostrar la interfaz principal." -#: ../gtk/main.c:137 +#: ../gtk/main.c:141 msgid "address to call right now" msgstr "dirección a la que llamar inmediatamente" -#: ../gtk/main.c:144 +#: ../gtk/main.c:142 msgid "if set automatically answer incoming calls" msgstr "si está activo, responder a llamadas entrantes automáticamente" -#: ../gtk/main.c:151 +#: ../gtk/main.c:143 msgid "" "Specifiy a working directory (should be the base of the installation, eg: c:" "\\Program Files\\Linphone)" @@ -126,19 +126,19 @@ msgstr "" "Especifique un directorio de trabajo (debería ser la raíz de la instalación, " "ej: c:\\Archivos de Programa\\Linphone)" -#: ../gtk/main.c:158 +#: ../gtk/main.c:144 msgid "Configuration file" msgstr "" -#: ../gtk/main.c:165 +#: ../gtk/main.c:145 msgid "Run the audio assistant" msgstr "" -#: ../gtk/main.c:172 +#: ../gtk/main.c:146 msgid "Run self test and exit 0 if succeed" msgstr "" -#: ../gtk/main.c:1088 +#: ../gtk/main.c:1061 #, c-format msgid "" "%s would like to add you to his contact list.\n" @@ -151,66 +151,66 @@ msgstr "" "contactos?\n" "Si responde no, esta persona será bloqueada temporalmente." -#: ../gtk/main.c:1165 +#: ../gtk/main.c:1138 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" msgstr "" -#: ../gtk/main.c:1286 +#: ../gtk/main.c:1259 msgid "Call error" msgstr "" -#: ../gtk/main.c:1289 ../coreapi/linphonecore.c:3787 +#: ../gtk/main.c:1262 ../coreapi/linphonecore.c:3791 msgid "Call ended" msgstr "" -#: ../gtk/main.c:1292 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1265 ../coreapi/call_log.c:221 msgid "Incoming call" msgstr "Llamada entrante" -#: ../gtk/main.c:1294 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1267 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 msgid "Answer" msgstr "Contestar" -#: ../gtk/main.c:1296 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1269 ../gtk/main.ui.h:6 msgid "Decline" msgstr "" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 msgid "Call paused" msgstr "" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 #, c-format msgid "by %s" msgstr "" -#: ../gtk/main.c:1372 +#: ../gtk/main.c:1345 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "" -#: ../gtk/main.c:1534 +#: ../gtk/main.c:1507 msgid "Website link" msgstr "Enlace a la Web" -#: ../gtk/main.c:1583 +#: ../gtk/main.c:1556 msgid "Linphone - a video internet phone" msgstr "Linphone - un video-teléfono a través de Internet" -#: ../gtk/main.c:1675 +#: ../gtk/main.c:1648 #, c-format msgid "%s (Default)" msgstr "%s (Opción predeterminada)" -#: ../gtk/main.c:2007 ../coreapi/callbacks.c:1027 +#: ../gtk/main.c:1980 ../coreapi/callbacks.c:1045 #, c-format msgid "We are transferred to %s" msgstr "Somos transferidos a %s" -#: ../gtk/main.c:2017 +#: ../gtk/main.c:1990 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." @@ -218,7 +218,7 @@ msgstr "" "No se ha encontrado una tarjeta de sonido en este equipo.\n" "No será posible realizar o recibir llamadas de audio." -#: ../gtk/main.c:2161 +#: ../gtk/main.c:2135 msgid "A free SIP video-phone" msgstr "Un video-teléfono SIP gratuito" @@ -744,7 +744,7 @@ msgstr "" msgid "(Paused)" msgstr "" -#: ../gtk/loginframe.c:88 +#: ../gtk/loginframe.c:87 #, c-format msgid "Please enter login information for %s" msgstr "Por favor, introduzca los datos de inicio de sesión para %s" @@ -1705,60 +1705,60 @@ msgstr "" msgid "Please wait while fetching configuration from server..." msgstr "" -#: ../coreapi/linphonecore.c:1508 +#: ../coreapi/linphonecore.c:1512 msgid "Ready" msgstr "" -#: ../coreapi/linphonecore.c:2495 +#: ../coreapi/linphonecore.c:2499 msgid "Configuring" msgstr "" -#: ../coreapi/linphonecore.c:2669 +#: ../coreapi/linphonecore.c:2673 msgid "Looking for telephone number destination..." msgstr "Buscando el número de teléfono del destinatario…" -#: ../coreapi/linphonecore.c:2671 +#: ../coreapi/linphonecore.c:2675 msgid "Could not resolve this number." msgstr "No se ha podido resolver este número." #. must be known at that time -#: ../coreapi/linphonecore.c:2957 +#: ../coreapi/linphonecore.c:2961 msgid "Contacting" msgstr "" -#: ../coreapi/linphonecore.c:2962 +#: ../coreapi/linphonecore.c:2966 msgid "Could not call" msgstr "" -#: ../coreapi/linphonecore.c:3112 +#: ../coreapi/linphonecore.c:3116 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "Disculpe, se ha alcanzado el máximo número de llamadas simultáneas" -#: ../coreapi/linphonecore.c:3270 +#: ../coreapi/linphonecore.c:3274 msgid "is contacting you" msgstr "" -#: ../coreapi/linphonecore.c:3271 +#: ../coreapi/linphonecore.c:3275 msgid " and asked autoanswer." msgstr "y ha solicitado auto respuesta." -#: ../coreapi/linphonecore.c:3395 +#: ../coreapi/linphonecore.c:3399 msgid "Modifying call parameters..." msgstr "Modificando parámetros de llamada…" -#: ../coreapi/linphonecore.c:3743 +#: ../coreapi/linphonecore.c:3747 msgid "Connected." msgstr "Conectado." -#: ../coreapi/linphonecore.c:3768 +#: ../coreapi/linphonecore.c:3772 msgid "Call aborted" msgstr "" -#: ../coreapi/linphonecore.c:3958 +#: ../coreapi/linphonecore.c:3962 msgid "Could not pause the call" msgstr "No se pudo pausar la llamada" -#: ../coreapi/linphonecore.c:3961 +#: ../coreapi/linphonecore.c:3965 msgid "Pausing the current call..." msgstr "Pausando la llamada actual..." @@ -1844,112 +1844,112 @@ msgstr "" msgid "Could not login as %s" msgstr "" -#: ../coreapi/callbacks.c:404 +#: ../coreapi/callbacks.c:419 msgid "Remote ringing." msgstr "" -#: ../coreapi/callbacks.c:425 +#: ../coreapi/callbacks.c:431 msgid "Remote ringing..." msgstr "" -#: ../coreapi/callbacks.c:442 +#: ../coreapi/callbacks.c:448 msgid "Early media." msgstr "Medios iniciales." -#: ../coreapi/callbacks.c:503 +#: ../coreapi/callbacks.c:521 #, c-format msgid "Call with %s is paused." msgstr "La llamada con %s está puesta en pausa." -#: ../coreapi/callbacks.c:516 +#: ../coreapi/callbacks.c:534 #, c-format msgid "Call answered by %s - on hold." msgstr "Llamada respondida por %s - en espera." -#: ../coreapi/callbacks.c:526 +#: ../coreapi/callbacks.c:544 msgid "Call resumed." msgstr "" -#: ../coreapi/callbacks.c:530 +#: ../coreapi/callbacks.c:548 #, c-format msgid "Call answered by %s." msgstr "" -#: ../coreapi/callbacks.c:553 +#: ../coreapi/callbacks.c:571 msgid "Incompatible, check codecs or security settings..." msgstr "" -#: ../coreapi/callbacks.c:558 ../coreapi/callbacks.c:870 +#: ../coreapi/callbacks.c:576 ../coreapi/callbacks.c:888 msgid "Incompatible media parameters." msgstr "" -#: ../coreapi/callbacks.c:588 +#: ../coreapi/callbacks.c:606 msgid "We have been resumed." msgstr "" #. we are being paused -#: ../coreapi/callbacks.c:596 +#: ../coreapi/callbacks.c:614 msgid "We are paused by other party." msgstr "" #. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:630 +#: ../coreapi/callbacks.c:648 msgid "Call is updated by remote." msgstr "" -#: ../coreapi/callbacks.c:746 +#: ../coreapi/callbacks.c:764 msgid "Call terminated." msgstr "" -#: ../coreapi/callbacks.c:774 +#: ../coreapi/callbacks.c:792 msgid "User is busy." msgstr "El usuario está ocupado." -#: ../coreapi/callbacks.c:775 +#: ../coreapi/callbacks.c:793 msgid "User is temporarily unavailable." msgstr "El usuario no está disponible temporalmente." #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:777 +#: ../coreapi/callbacks.c:795 msgid "User does not want to be disturbed." msgstr "El usuario no quiere que le molesten." -#: ../coreapi/callbacks.c:778 +#: ../coreapi/callbacks.c:796 msgid "Call declined." msgstr "Llamada rechazada." -#: ../coreapi/callbacks.c:793 +#: ../coreapi/callbacks.c:811 msgid "Request timeout." msgstr "" -#: ../coreapi/callbacks.c:824 +#: ../coreapi/callbacks.c:842 msgid "Redirected" msgstr "Redigirida" -#: ../coreapi/callbacks.c:879 +#: ../coreapi/callbacks.c:897 msgid "Call failed." msgstr "" -#: ../coreapi/callbacks.c:957 +#: ../coreapi/callbacks.c:975 #, c-format msgid "Registration on %s successful." msgstr "" -#: ../coreapi/callbacks.c:958 +#: ../coreapi/callbacks.c:976 #, c-format msgid "Unregistration on %s done." msgstr "" -#: ../coreapi/callbacks.c:976 +#: ../coreapi/callbacks.c:994 msgid "no response timeout" msgstr "timeout sin respuesta" -#: ../coreapi/callbacks.c:979 +#: ../coreapi/callbacks.c:997 #, c-format msgid "Registration on %s failed: %s" msgstr "" -#: ../coreapi/callbacks.c:986 +#: ../coreapi/callbacks.c:1004 msgid "Service unavailable, retrying" msgstr "" @@ -1959,7 +1959,7 @@ msgstr "" msgid "Authentication token is %s" msgstr "" -#: ../coreapi/linphonecall.c:3492 +#: ../coreapi/linphonecall.c:3600 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." diff --git a/po/fr.po b/po/fr.po index 33fa26d57..557cee354 100644 --- a/po/fr.po +++ b/po/fr.po @@ -12,8 +12,8 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-02-17 12:28+0100\n" -"PO-Revision-Date: 2015-02-17 11:30+0000\n" +"POT-Creation-Date: 2015-03-11 16:26+0100\n" +"PO-Revision-Date: 2015-02-17 14:38+0000\n" "Last-Translator: Belledonne Communications \n" "Language-Team: French (http://www.transifex.com/projects/p/linphone-gtk/" @@ -96,35 +96,35 @@ msgstr "Moi" msgid "Couldn't find pixmap file: %s" msgstr "Icone non trouvée: %s" -#: ../gtk/chat.c:367 ../gtk/friendlist.c:924 +#: ../gtk/chat.c:374 ../gtk/friendlist.c:924 msgid "Invalid sip contact !" msgstr "Contact sip invalide !" -#: ../gtk/main.c:109 +#: ../gtk/main.c:137 msgid "log to stdout some debug information while running." msgstr "affiche des informations de debogage" -#: ../gtk/main.c:116 +#: ../gtk/main.c:138 msgid "path to a file to write logs into." msgstr "chemin vers le fichier de logs." -#: ../gtk/main.c:123 +#: ../gtk/main.c:139 msgid "Start linphone with video disabled." msgstr "Démarrer linphone avec la vidéo désactivée." -#: ../gtk/main.c:130 +#: ../gtk/main.c:140 msgid "Start only in the system tray, do not show the main interface." msgstr "Démarre iconifié, sans interface principale." -#: ../gtk/main.c:137 +#: ../gtk/main.c:141 msgid "address to call right now" msgstr "adresse à appeler maintenant" -#: ../gtk/main.c:144 +#: ../gtk/main.c:142 msgid "if set automatically answer incoming calls" msgstr "si positionné, répond automatiquement aux appels entrants" -#: ../gtk/main.c:151 +#: ../gtk/main.c:143 msgid "" "Specifiy a working directory (should be the base of the installation, eg: c:" "\\Program Files\\Linphone)" @@ -132,19 +132,19 @@ msgstr "" "Spécifie un répertoire de travail (qui devrait être le répertoire " "d'installation, par exemple c:\\Program Files\\Linphone)" -#: ../gtk/main.c:158 +#: ../gtk/main.c:144 msgid "Configuration file" msgstr "Ficher de configuration" -#: ../gtk/main.c:165 +#: ../gtk/main.c:145 msgid "Run the audio assistant" msgstr "Démarre l'assistant audio" -#: ../gtk/main.c:172 +#: ../gtk/main.c:146 msgid "Run self test and exit 0 if succeed" msgstr "Exécuter le test local et retourner 0 en cas de succès" -#: ../gtk/main.c:1088 +#: ../gtk/main.c:1061 #, c-format msgid "" "%s would like to add you to his contact list.\n" @@ -158,7 +158,7 @@ msgstr "" "Si vous répondez non, cette personne sera mise temporairement sur liste " "noire." -#: ../gtk/main.c:1165 +#: ../gtk/main.c:1138 #, c-format msgid "" "Please enter your password for username %s\n" @@ -167,59 +167,59 @@ msgstr "" "Entrez le mot de passe pour %s\n" " sur le domaine %s:" -#: ../gtk/main.c:1286 +#: ../gtk/main.c:1259 msgid "Call error" msgstr "Erreur lors de l'appel" -#: ../gtk/main.c:1289 ../coreapi/linphonecore.c:3787 +#: ../gtk/main.c:1262 ../coreapi/linphonecore.c:3791 msgid "Call ended" msgstr "Appel terminé." -#: ../gtk/main.c:1292 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1265 ../coreapi/call_log.c:221 msgid "Incoming call" msgstr "Appel entrant" -#: ../gtk/main.c:1294 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1267 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 msgid "Answer" msgstr "Répondre" -#: ../gtk/main.c:1296 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1269 ../gtk/main.ui.h:6 msgid "Decline" msgstr "Refuser" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 msgid "Call paused" msgstr "Appel en pause" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 #, c-format msgid "by %s" msgstr "b>par %s" -#: ../gtk/main.c:1372 +#: ../gtk/main.c:1345 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "%s propose de démarrer la vidéo. Acceptez-vous ?" -#: ../gtk/main.c:1534 +#: ../gtk/main.c:1507 msgid "Website link" msgstr "Lien site web" -#: ../gtk/main.c:1583 +#: ../gtk/main.c:1556 msgid "Linphone - a video internet phone" msgstr "Linphone - un téléphone video pour l'internet" -#: ../gtk/main.c:1675 +#: ../gtk/main.c:1648 #, c-format msgid "%s (Default)" msgstr "%s (par défaut)" -#: ../gtk/main.c:2007 ../coreapi/callbacks.c:1027 +#: ../gtk/main.c:1980 ../coreapi/callbacks.c:1045 #, c-format msgid "We are transferred to %s" msgstr "Transfert vers %s" -#: ../gtk/main.c:2017 +#: ../gtk/main.c:1990 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." @@ -227,7 +227,7 @@ msgstr "" "Aucune carte son n'a été détectée sur cet ordinateur.\n" "Vous ne pourrez pas effectuer d'appels audio." -#: ../gtk/main.c:2161 +#: ../gtk/main.c:2135 msgid "A free SIP video-phone" msgstr "Un visiophone libre" @@ -770,7 +770,7 @@ msgstr "" msgid "(Paused)" msgstr "(en attente)" -#: ../gtk/loginframe.c:88 +#: ../gtk/loginframe.c:87 #, c-format msgid "Please enter login information for %s" msgstr "Entrez vos identifiants pour %s" @@ -1754,60 +1754,60 @@ msgstr "" "Veuillez patenter un instant pendant le chargement de la configuration " "distante..." -#: ../coreapi/linphonecore.c:1508 +#: ../coreapi/linphonecore.c:1512 msgid "Ready" msgstr "Prêt." -#: ../coreapi/linphonecore.c:2495 +#: ../coreapi/linphonecore.c:2499 msgid "Configuring" msgstr "Configuration en cours" -#: ../coreapi/linphonecore.c:2669 +#: ../coreapi/linphonecore.c:2673 msgid "Looking for telephone number destination..." msgstr "Recherche de la destination du numéro de téléphone..." -#: ../coreapi/linphonecore.c:2671 +#: ../coreapi/linphonecore.c:2675 msgid "Could not resolve this number." msgstr "La destination n'a pu être trouvée." #. must be known at that time -#: ../coreapi/linphonecore.c:2957 +#: ../coreapi/linphonecore.c:2961 msgid "Contacting" msgstr "Appel de" -#: ../coreapi/linphonecore.c:2962 +#: ../coreapi/linphonecore.c:2966 msgid "Could not call" msgstr "Echec de l'appel" -#: ../coreapi/linphonecore.c:3112 +#: ../coreapi/linphonecore.c:3116 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "Désolé, le nombre maximum d'appels simultanés est atteint." -#: ../coreapi/linphonecore.c:3270 +#: ../coreapi/linphonecore.c:3274 msgid "is contacting you" msgstr "vous appelle" -#: ../coreapi/linphonecore.c:3271 +#: ../coreapi/linphonecore.c:3275 msgid " and asked autoanswer." msgstr "et sollicite un décrochage automatique." -#: ../coreapi/linphonecore.c:3395 +#: ../coreapi/linphonecore.c:3399 msgid "Modifying call parameters..." msgstr "Modifications des paramètres d'appels..." -#: ../coreapi/linphonecore.c:3743 +#: ../coreapi/linphonecore.c:3747 msgid "Connected." msgstr "En ligne." -#: ../coreapi/linphonecore.c:3768 +#: ../coreapi/linphonecore.c:3772 msgid "Call aborted" msgstr "Appel abandonné" -#: ../coreapi/linphonecore.c:3958 +#: ../coreapi/linphonecore.c:3962 msgid "Could not pause the call" msgstr "La mise en attente a échoué" -#: ../coreapi/linphonecore.c:3961 +#: ../coreapi/linphonecore.c:3965 msgid "Pausing the current call..." msgstr "Mise en attente de l'appel..." @@ -1893,112 +1893,112 @@ msgstr "" msgid "Could not login as %s" msgstr "Echec de la connexion en tant que %s" -#: ../coreapi/callbacks.c:404 +#: ../coreapi/callbacks.c:419 msgid "Remote ringing." msgstr "Sonnerie distante." -#: ../coreapi/callbacks.c:425 +#: ../coreapi/callbacks.c:431 msgid "Remote ringing..." msgstr "Sonnerie distante..." -#: ../coreapi/callbacks.c:442 +#: ../coreapi/callbacks.c:448 msgid "Early media." msgstr "Prise d'appel anticipée." -#: ../coreapi/callbacks.c:503 +#: ../coreapi/callbacks.c:521 #, c-format msgid "Call with %s is paused." msgstr "%s est maintenant en attente." -#: ../coreapi/callbacks.c:516 +#: ../coreapi/callbacks.c:534 #, c-format msgid "Call answered by %s - on hold." msgstr "Appel répondu par %s - en attente" -#: ../coreapi/callbacks.c:526 +#: ../coreapi/callbacks.c:544 msgid "Call resumed." msgstr "Appel repris." -#: ../coreapi/callbacks.c:530 +#: ../coreapi/callbacks.c:548 #, c-format msgid "Call answered by %s." msgstr "Appel répondu par %s." -#: ../coreapi/callbacks.c:553 +#: ../coreapi/callbacks.c:571 msgid "Incompatible, check codecs or security settings..." msgstr "Incompatible, vérfiez les codecs ou les paramètres de sécurité..." -#: ../coreapi/callbacks.c:558 ../coreapi/callbacks.c:870 +#: ../coreapi/callbacks.c:576 ../coreapi/callbacks.c:888 msgid "Incompatible media parameters." msgstr "Paramètres media incompatibles." -#: ../coreapi/callbacks.c:588 +#: ../coreapi/callbacks.c:606 msgid "We have been resumed." msgstr "Appel repris." #. we are being paused -#: ../coreapi/callbacks.c:596 +#: ../coreapi/callbacks.c:614 msgid "We are paused by other party." msgstr "L'appel a été mis en attente." #. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:630 +#: ../coreapi/callbacks.c:648 msgid "Call is updated by remote." msgstr "L'appel est modifié par la partie distante." -#: ../coreapi/callbacks.c:746 +#: ../coreapi/callbacks.c:764 msgid "Call terminated." msgstr "Appel terminé." -#: ../coreapi/callbacks.c:774 +#: ../coreapi/callbacks.c:792 msgid "User is busy." msgstr "Occupé..." -#: ../coreapi/callbacks.c:775 +#: ../coreapi/callbacks.c:793 msgid "User is temporarily unavailable." msgstr "L'usager est temporairement indisponible." #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:777 +#: ../coreapi/callbacks.c:795 msgid "User does not want to be disturbed." msgstr "L'usager ne souhaite pas être dérangé" -#: ../coreapi/callbacks.c:778 +#: ../coreapi/callbacks.c:796 msgid "Call declined." msgstr "Appel décliné." -#: ../coreapi/callbacks.c:793 +#: ../coreapi/callbacks.c:811 msgid "Request timeout." msgstr "Délai d'attente de la requête dépassé." -#: ../coreapi/callbacks.c:824 +#: ../coreapi/callbacks.c:842 msgid "Redirected" msgstr "Redirection" -#: ../coreapi/callbacks.c:879 +#: ../coreapi/callbacks.c:897 msgid "Call failed." msgstr "L'appel a échoué." -#: ../coreapi/callbacks.c:957 +#: ../coreapi/callbacks.c:975 #, c-format msgid "Registration on %s successful." msgstr "Enregistrement sur %s effectué." -#: ../coreapi/callbacks.c:958 +#: ../coreapi/callbacks.c:976 #, c-format msgid "Unregistration on %s done." msgstr "Désenregistrement sur %s effectué." -#: ../coreapi/callbacks.c:976 +#: ../coreapi/callbacks.c:994 msgid "no response timeout" msgstr "Pas de réponse" -#: ../coreapi/callbacks.c:979 +#: ../coreapi/callbacks.c:997 #, c-format msgid "Registration on %s failed: %s" msgstr "Echec de l'enregistrement sur %s: %s" -#: ../coreapi/callbacks.c:986 +#: ../coreapi/callbacks.c:1004 msgid "Service unavailable, retrying" msgstr "Service indisponible, nouvelle tentative" @@ -2008,7 +2008,7 @@ msgstr "Service indisponible, nouvelle tentative" msgid "Authentication token is %s" msgstr "Le jeton d'authentification est %s" -#: ../coreapi/linphonecall.c:3492 +#: ../coreapi/linphonecall.c:3600 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." diff --git a/po/he.po b/po/he.po index 553b97f58..f0b2ac7d1 100644 --- a/po/he.po +++ b/po/he.po @@ -4,6 +4,7 @@ # # Translators: # Eli Zaretskii , 2012 +# Gautier Pelloux-Prayer , 2015 # GenghisKhan , 2014 # GenghisKhan , 2014 # GenghisKhan , 2012-2013 @@ -11,10 +12,9 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-02-17 12:28+0100\n" -"PO-Revision-Date: 2015-02-17 11:28+0000\n" -"Last-Translator: Belledonne Communications \n" +"POT-Creation-Date: 2015-03-11 16:26+0100\n" +"PO-Revision-Date: 2015-03-11 15:33+0000\n" +"Last-Translator: Gautier Pelloux-Prayer \n" "Language-Team: Hebrew (http://www.transifex.com/projects/p/linphone-gtk/" "language/he/)\n" "Language: he\n" @@ -95,53 +95,53 @@ msgstr "אני" msgid "Couldn't find pixmap file: %s" msgstr "לא ניתן למצוא קובץ ‫pixmap: ‫%s" -#: ../gtk/chat.c:367 ../gtk/friendlist.c:924 +#: ../gtk/chat.c:374 ../gtk/friendlist.c:924 msgid "Invalid sip contact !" msgstr "כתובת sip לא תקפה !" -#: ../gtk/main.c:109 +#: ../gtk/main.c:137 msgid "log to stdout some debug information while running." msgstr "" -#: ../gtk/main.c:116 +#: ../gtk/main.c:138 msgid "path to a file to write logs into." msgstr "" -#: ../gtk/main.c:123 +#: ../gtk/main.c:139 msgid "Start linphone with video disabled." msgstr "" -#: ../gtk/main.c:130 +#: ../gtk/main.c:140 msgid "Start only in the system tray, do not show the main interface." msgstr "" -#: ../gtk/main.c:137 +#: ../gtk/main.c:141 msgid "address to call right now" msgstr "" -#: ../gtk/main.c:144 +#: ../gtk/main.c:142 msgid "if set automatically answer incoming calls" msgstr "" -#: ../gtk/main.c:151 +#: ../gtk/main.c:143 msgid "" "Specifiy a working directory (should be the base of the installation, eg: c:" "\\Program Files\\Linphone)" msgstr "" -#: ../gtk/main.c:158 +#: ../gtk/main.c:144 msgid "Configuration file" msgstr "" -#: ../gtk/main.c:165 +#: ../gtk/main.c:145 msgid "Run the audio assistant" msgstr "" -#: ../gtk/main.c:172 +#: ../gtk/main.c:146 msgid "Run self test and exit 0 if succeed" msgstr "" -#: ../gtk/main.c:1088 +#: ../gtk/main.c:1061 #, c-format msgid "" "%s would like to add you to his contact list.\n" @@ -154,7 +154,7 @@ msgstr "" "שלך ?\n" "היה ותשובתך תהיה לא, אדם זה יהיה מסומן באופן זמני ברשימה השחורה." -#: ../gtk/main.c:1165 +#: ../gtk/main.c:1138 #, c-format msgid "" "Please enter your password for username %s\n" @@ -163,59 +163,59 @@ msgstr "" "אנא הזן סיסמה עבור משתמש %s\n" "במתחם %s:" -#: ../gtk/main.c:1286 +#: ../gtk/main.c:1259 msgid "Call error" msgstr "שגיאת קריאה" -#: ../gtk/main.c:1289 ../coreapi/linphonecore.c:3787 +#: ../gtk/main.c:1262 ../coreapi/linphonecore.c:3791 msgid "Call ended" msgstr "שיחה הסתיימה" -#: ../gtk/main.c:1292 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1265 ../coreapi/call_log.c:221 msgid "Incoming call" msgstr "קריאה נכנסת" -#: ../gtk/main.c:1294 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1267 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 msgid "Answer" msgstr "לענות" -#: ../gtk/main.c:1296 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1269 ../gtk/main.ui.h:6 msgid "Decline" msgstr "לדחות" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 msgid "Call paused" msgstr "שיחה הושהתה" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 #, c-format msgid "by %s" msgstr "על ידי %s" -#: ../gtk/main.c:1372 +#: ../gtk/main.c:1345 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "‏%s רוצה להתחיל וידאו. האם אתה מסכים ?" -#: ../gtk/main.c:1534 +#: ../gtk/main.c:1507 msgid "Website link" msgstr "קישור אתר רשת" -#: ../gtk/main.c:1583 +#: ../gtk/main.c:1556 msgid "Linphone - a video internet phone" -msgstr "‫Linphone - וידאופון אינטרנטי" +msgstr "‫Linphone - וידאופון אינטרנטי" -#: ../gtk/main.c:1675 +#: ../gtk/main.c:1648 #, c-format msgid "%s (Default)" msgstr "‫%s (ברירת מחדל)" -#: ../gtk/main.c:2007 ../coreapi/callbacks.c:1027 +#: ../gtk/main.c:1980 ../coreapi/callbacks.c:1045 #, c-format msgid "We are transferred to %s" msgstr "אנחנו מועברים אל %s" -#: ../gtk/main.c:2017 +#: ../gtk/main.c:1990 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." @@ -223,7 +223,7 @@ msgstr "" "לא אותרו כרטיסי קול במחשב זה.\n" "לא תהיה ביכולתך לשלוח או לקבל שיחות אודיו." -#: ../gtk/main.c:2161 +#: ../gtk/main.c:2135 msgid "A free SIP video-phone" msgstr "וידאופון SIP חופשי" @@ -759,7 +759,7 @@ msgstr "" msgid "(Paused)" msgstr "(מושהה)" -#: ../gtk/loginframe.c:88 +#: ../gtk/loginframe.c:87 #, c-format msgid "Please enter login information for %s" msgstr "נא להזין מידע התחברות עבור %s" @@ -1718,60 +1718,60 @@ msgstr "" msgid "Please wait while fetching configuration from server..." msgstr "" -#: ../coreapi/linphonecore.c:1508 +#: ../coreapi/linphonecore.c:1512 msgid "Ready" msgstr "מוכן" -#: ../coreapi/linphonecore.c:2495 +#: ../coreapi/linphonecore.c:2499 msgid "Configuring" msgstr "" -#: ../coreapi/linphonecore.c:2669 +#: ../coreapi/linphonecore.c:2673 msgid "Looking for telephone number destination..." msgstr "מחפש כעת עבור יעד מספר טלפון..." -#: ../coreapi/linphonecore.c:2671 +#: ../coreapi/linphonecore.c:2675 msgid "Could not resolve this number." msgstr "לא ניתן לפתור את מספר זה." #. must be known at that time -#: ../coreapi/linphonecore.c:2957 +#: ../coreapi/linphonecore.c:2961 msgid "Contacting" msgstr "מתקשר כעת" -#: ../coreapi/linphonecore.c:2962 +#: ../coreapi/linphonecore.c:2966 msgid "Could not call" msgstr "לא ניתן להתקשר" -#: ../coreapi/linphonecore.c:3112 +#: ../coreapi/linphonecore.c:3116 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "הגענו אל המספר המרבי של שיחות מקבילות, עמך הסליחה" -#: ../coreapi/linphonecore.c:3270 +#: ../coreapi/linphonecore.c:3274 msgid "is contacting you" msgstr "מתקשר/ת אליך" -#: ../coreapi/linphonecore.c:3271 +#: ../coreapi/linphonecore.c:3275 msgid " and asked autoanswer." msgstr " ומבקש/ת מענה אוטומטי." -#: ../coreapi/linphonecore.c:3395 +#: ../coreapi/linphonecore.c:3399 msgid "Modifying call parameters..." msgstr "מתאים כעת פרמטרים של שיחה..." -#: ../coreapi/linphonecore.c:3743 +#: ../coreapi/linphonecore.c:3747 msgid "Connected." msgstr "מקושר." -#: ../coreapi/linphonecore.c:3768 +#: ../coreapi/linphonecore.c:3772 msgid "Call aborted" msgstr "קריאה בוטלה" -#: ../coreapi/linphonecore.c:3958 +#: ../coreapi/linphonecore.c:3962 msgid "Could not pause the call" msgstr "לא ניתן להשהות את השיחה" -#: ../coreapi/linphonecore.c:3961 +#: ../coreapi/linphonecore.c:3965 msgid "Pausing the current call..." msgstr "משהה כעת שיחה נוכחית..." @@ -1855,112 +1855,112 @@ msgstr "" msgid "Could not login as %s" msgstr "לא ניתן להתחבר בזהות %s" -#: ../coreapi/callbacks.c:404 +#: ../coreapi/callbacks.c:419 msgid "Remote ringing." msgstr "צלצול מרוחק." -#: ../coreapi/callbacks.c:425 +#: ../coreapi/callbacks.c:431 msgid "Remote ringing..." msgstr "צלצול מרוחק..." -#: ../coreapi/callbacks.c:442 +#: ../coreapi/callbacks.c:448 msgid "Early media." msgstr "מדיה מוקדמת." -#: ../coreapi/callbacks.c:503 +#: ../coreapi/callbacks.c:521 #, c-format msgid "Call with %s is paused." msgstr "שיחה עם %s מושהית." -#: ../coreapi/callbacks.c:516 +#: ../coreapi/callbacks.c:534 #, c-format msgid "Call answered by %s - on hold." msgstr "קריאה נענתה על ידי %s - בהמתנה." -#: ../coreapi/callbacks.c:526 +#: ../coreapi/callbacks.c:544 msgid "Call resumed." msgstr "קריאה חודשה." -#: ../coreapi/callbacks.c:530 +#: ../coreapi/callbacks.c:548 #, c-format msgid "Call answered by %s." msgstr "קריאה נענתה על ידי %s." -#: ../coreapi/callbacks.c:553 +#: ../coreapi/callbacks.c:571 msgid "Incompatible, check codecs or security settings..." msgstr "חוסר תאימות, בדוק קודקים או הגדרות אבטחה..." -#: ../coreapi/callbacks.c:558 ../coreapi/callbacks.c:870 +#: ../coreapi/callbacks.c:576 ../coreapi/callbacks.c:888 msgid "Incompatible media parameters." msgstr "פרמטריי מדיה חסרי תואמים." -#: ../coreapi/callbacks.c:588 +#: ../coreapi/callbacks.c:606 msgid "We have been resumed." msgstr "חזרנו." #. we are being paused -#: ../coreapi/callbacks.c:596 +#: ../coreapi/callbacks.c:614 msgid "We are paused by other party." msgstr "אנו מושהים על ידי צד אחר." #. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:630 +#: ../coreapi/callbacks.c:648 msgid "Call is updated by remote." msgstr "שיחה עודכנה מרחוק." -#: ../coreapi/callbacks.c:746 +#: ../coreapi/callbacks.c:764 msgid "Call terminated." msgstr "קריאה הסתיימה." -#: ../coreapi/callbacks.c:774 +#: ../coreapi/callbacks.c:792 msgid "User is busy." msgstr "משתמש עסוק כעת." -#: ../coreapi/callbacks.c:775 +#: ../coreapi/callbacks.c:793 msgid "User is temporarily unavailable." msgstr "משתמש לא זמין זמנית." #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:777 +#: ../coreapi/callbacks.c:795 msgid "User does not want to be disturbed." msgstr "משתמש לא מעוניין שיפריעו לו." -#: ../coreapi/callbacks.c:778 +#: ../coreapi/callbacks.c:796 msgid "Call declined." msgstr "קריאה סורבה." -#: ../coreapi/callbacks.c:793 +#: ../coreapi/callbacks.c:811 msgid "Request timeout." msgstr "" -#: ../coreapi/callbacks.c:824 +#: ../coreapi/callbacks.c:842 msgid "Redirected" msgstr "מכוון מחדש" -#: ../coreapi/callbacks.c:879 +#: ../coreapi/callbacks.c:897 msgid "Call failed." msgstr "קריאה נכשלה." -#: ../coreapi/callbacks.c:957 +#: ../coreapi/callbacks.c:975 #, c-format msgid "Registration on %s successful." msgstr "רישום אצל %s הושלם בהצלחה." -#: ../coreapi/callbacks.c:958 +#: ../coreapi/callbacks.c:976 #, c-format msgid "Unregistration on %s done." msgstr "אי רישום אצל %s סוים." -#: ../coreapi/callbacks.c:976 +#: ../coreapi/callbacks.c:994 msgid "no response timeout" msgstr "אין היענות תוך זמן מוגדר" -#: ../coreapi/callbacks.c:979 +#: ../coreapi/callbacks.c:997 #, c-format msgid "Registration on %s failed: %s" msgstr "רישום אצל %s נכשל: %s" -#: ../coreapi/callbacks.c:986 +#: ../coreapi/callbacks.c:1004 msgid "Service unavailable, retrying" msgstr "" @@ -1970,7 +1970,7 @@ msgstr "" msgid "Authentication token is %s" msgstr "אות האימות הינה %s" -#: ../coreapi/linphonecall.c:3492 +#: ../coreapi/linphonecall.c:3600 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." diff --git a/po/hu.po b/po/hu.po index 1ff87b778..75e5856d3 100644 --- a/po/hu.po +++ b/po/hu.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-02-17 12:28+0100\n" +"POT-Creation-Date: 2015-03-11 16:26+0100\n" "PO-Revision-Date: 2015-02-17 11:28+0000\n" "Last-Translator: Belledonne Communications \n" @@ -89,35 +89,35 @@ msgstr "én" msgid "Couldn't find pixmap file: %s" msgstr "Nemtalálható a pixmap fájl: %s" -#: ../gtk/chat.c:367 ../gtk/friendlist.c:924 +#: ../gtk/chat.c:374 ../gtk/friendlist.c:924 msgid "Invalid sip contact !" msgstr "Érvénytelen sip partner !" -#: ../gtk/main.c:109 +#: ../gtk/main.c:137 msgid "log to stdout some debug information while running." msgstr "Futás közben némi hibakeresési információ az stdout-ra naplózása." -#: ../gtk/main.c:116 +#: ../gtk/main.c:138 msgid "path to a file to write logs into." msgstr "fájl elérési útja, melybe a naplók kerülnek." -#: ../gtk/main.c:123 +#: ../gtk/main.c:139 msgid "Start linphone with video disabled." msgstr "Linphone indítása, videó kikpacsolva. " -#: ../gtk/main.c:130 +#: ../gtk/main.c:140 msgid "Start only in the system tray, do not show the main interface." msgstr "Csak a tálcaikon indítása, ne mutassa a fő ablakot." -#: ../gtk/main.c:137 +#: ../gtk/main.c:141 msgid "address to call right now" msgstr "Cím azonnali híváshoz" -#: ../gtk/main.c:144 +#: ../gtk/main.c:142 msgid "if set automatically answer incoming calls" msgstr "Bekapcsolva automatikusan válaszol a bejövő hívásokra" -#: ../gtk/main.c:151 +#: ../gtk/main.c:143 msgid "" "Specifiy a working directory (should be the base of the installation, eg: c:" "\\Program Files\\Linphone)" @@ -125,19 +125,19 @@ msgstr "" "Adjon meg egy munkakönyvtárat (ennek az installációs könyvtárnak kéne " "lennie, pl. C:\\Program Files\\Linphone)" -#: ../gtk/main.c:158 +#: ../gtk/main.c:144 msgid "Configuration file" msgstr "" -#: ../gtk/main.c:165 +#: ../gtk/main.c:145 msgid "Run the audio assistant" msgstr "" -#: ../gtk/main.c:172 +#: ../gtk/main.c:146 msgid "Run self test and exit 0 if succeed" msgstr "" -#: ../gtk/main.c:1088 +#: ../gtk/main.c:1061 #, c-format msgid "" "%s would like to add you to his contact list.\n" @@ -150,66 +150,66 @@ msgstr "" "szeretné adni a partnerlistához?\n" "Ha nemmel válaszol, ez a személy átmenetileg tiltólistára kerül." -#: ../gtk/main.c:1165 +#: ../gtk/main.c:1138 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" msgstr "" -#: ../gtk/main.c:1286 +#: ../gtk/main.c:1259 msgid "Call error" msgstr "Hiba a hívás közben" -#: ../gtk/main.c:1289 ../coreapi/linphonecore.c:3787 +#: ../gtk/main.c:1262 ../coreapi/linphonecore.c:3791 msgid "Call ended" msgstr "Hívás vége" -#: ../gtk/main.c:1292 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1265 ../coreapi/call_log.c:221 msgid "Incoming call" msgstr "Beérkező hívás" -#: ../gtk/main.c:1294 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1267 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 msgid "Answer" msgstr "Hívás fogadása" -#: ../gtk/main.c:1296 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1269 ../gtk/main.ui.h:6 msgid "Decline" msgstr "Elutasítás" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 msgid "Call paused" msgstr "Hívás várakoztatva" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 #, c-format msgid "by %s" msgstr "a következő által: %s" -#: ../gtk/main.c:1372 +#: ../gtk/main.c:1345 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "%s szerené elidítani a videót. Elfogadja?" -#: ../gtk/main.c:1534 +#: ../gtk/main.c:1507 msgid "Website link" msgstr "Internetes oldal" -#: ../gtk/main.c:1583 +#: ../gtk/main.c:1556 msgid "Linphone - a video internet phone" msgstr "Linphone - internetes videó telefon" -#: ../gtk/main.c:1675 +#: ../gtk/main.c:1648 #, c-format msgid "%s (Default)" msgstr "%s (Alapértelmezett)" -#: ../gtk/main.c:2007 ../coreapi/callbacks.c:1027 +#: ../gtk/main.c:1980 ../coreapi/callbacks.c:1045 #, c-format msgid "We are transferred to %s" msgstr "Át vagyunk irányítva ide: %s" -#: ../gtk/main.c:2017 +#: ../gtk/main.c:1990 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." @@ -217,7 +217,7 @@ msgstr "" "Hangkártya nincs érzékelve ezen a számítógépen.\n" "Nem fog tudni hang hívásokat küldeni vagy fogadni." -#: ../gtk/main.c:2161 +#: ../gtk/main.c:2135 msgid "A free SIP video-phone" msgstr "Egy ingyenes SIP video-telefon" @@ -757,7 +757,7 @@ msgstr "" msgid "(Paused)" msgstr "(Várakoztatva)" -#: ../gtk/loginframe.c:88 +#: ../gtk/loginframe.c:87 #, c-format msgid "Please enter login information for %s" msgstr "Kérem, adja meg a bejelentkezési információt %s -hoz" @@ -1718,60 +1718,60 @@ msgstr "" msgid "Please wait while fetching configuration from server..." msgstr "" -#: ../coreapi/linphonecore.c:1508 +#: ../coreapi/linphonecore.c:1512 msgid "Ready" msgstr "Kész" -#: ../coreapi/linphonecore.c:2495 +#: ../coreapi/linphonecore.c:2499 msgid "Configuring" msgstr "" -#: ../coreapi/linphonecore.c:2669 +#: ../coreapi/linphonecore.c:2673 msgid "Looking for telephone number destination..." msgstr "Telefonszám-cél keresése..." -#: ../coreapi/linphonecore.c:2671 +#: ../coreapi/linphonecore.c:2675 msgid "Could not resolve this number." msgstr "Nem sikkerült értelmezni a számot." #. must be known at that time -#: ../coreapi/linphonecore.c:2957 +#: ../coreapi/linphonecore.c:2961 msgid "Contacting" msgstr "Kapcsolódás" -#: ../coreapi/linphonecore.c:2962 +#: ../coreapi/linphonecore.c:2966 msgid "Could not call" msgstr "Nem sikerült hívni" -#: ../coreapi/linphonecore.c:3112 +#: ../coreapi/linphonecore.c:3116 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "Elnézést, elértük a egyidejű hívások maximális számát" -#: ../coreapi/linphonecore.c:3270 +#: ../coreapi/linphonecore.c:3274 msgid "is contacting you" msgstr "kapcsolatba lépett veled." -#: ../coreapi/linphonecore.c:3271 +#: ../coreapi/linphonecore.c:3275 msgid " and asked autoanswer." msgstr "és automatikus választ kért." -#: ../coreapi/linphonecore.c:3395 +#: ../coreapi/linphonecore.c:3399 msgid "Modifying call parameters..." msgstr "A hívási jellemzők módosítása..." -#: ../coreapi/linphonecore.c:3743 +#: ../coreapi/linphonecore.c:3747 msgid "Connected." msgstr "Kapcsolódva." -#: ../coreapi/linphonecore.c:3768 +#: ../coreapi/linphonecore.c:3772 msgid "Call aborted" msgstr "Hívás megszakítva" -#: ../coreapi/linphonecore.c:3958 +#: ../coreapi/linphonecore.c:3962 msgid "Could not pause the call" msgstr "Nem sikerült várakoztatni a hívást" -#: ../coreapi/linphonecore.c:3961 +#: ../coreapi/linphonecore.c:3965 msgid "Pausing the current call..." msgstr "Jelenlegi hívás várakoztatásának aktiválása..." @@ -1857,113 +1857,113 @@ msgstr "" msgid "Could not login as %s" msgstr "Nem sikerült belépni ezzel: %s" -#: ../coreapi/callbacks.c:404 +#: ../coreapi/callbacks.c:419 msgid "Remote ringing." msgstr "Távoli csengés." -#: ../coreapi/callbacks.c:425 +#: ../coreapi/callbacks.c:431 msgid "Remote ringing..." msgstr "Távoli csengés..." -#: ../coreapi/callbacks.c:442 +#: ../coreapi/callbacks.c:448 msgid "Early media." msgstr "Korai médiák." -#: ../coreapi/callbacks.c:503 +#: ../coreapi/callbacks.c:521 #, c-format msgid "Call with %s is paused." msgstr "A hívás a következővel: %s várakoztatva" -#: ../coreapi/callbacks.c:516 +#: ../coreapi/callbacks.c:534 #, c-format msgid "Call answered by %s - on hold." msgstr "%s fogadta a hívást - várakoztatva." -#: ../coreapi/callbacks.c:526 +#: ../coreapi/callbacks.c:544 msgid "Call resumed." msgstr "Hívás visszatért" -#: ../coreapi/callbacks.c:530 +#: ../coreapi/callbacks.c:548 #, c-format msgid "Call answered by %s." msgstr "%s válaszolt a hívásra." -#: ../coreapi/callbacks.c:553 +#: ../coreapi/callbacks.c:571 msgid "Incompatible, check codecs or security settings..." msgstr "" "Nem kompatibilis, ellenőrizze a kódek- vagy a biztonsági beállításokat..." -#: ../coreapi/callbacks.c:558 ../coreapi/callbacks.c:870 +#: ../coreapi/callbacks.c:576 ../coreapi/callbacks.c:888 msgid "Incompatible media parameters." msgstr "Nem kompatibilis médiajellemzők." -#: ../coreapi/callbacks.c:588 +#: ../coreapi/callbacks.c:606 msgid "We have been resumed." msgstr "Visszatértünk." #. we are being paused -#: ../coreapi/callbacks.c:596 +#: ../coreapi/callbacks.c:614 msgid "We are paused by other party." msgstr "Megállítva a másik fél által." #. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:630 +#: ../coreapi/callbacks.c:648 msgid "Call is updated by remote." msgstr "A hívás távolról frissítve." -#: ../coreapi/callbacks.c:746 +#: ../coreapi/callbacks.c:764 msgid "Call terminated." msgstr "A hívás befejezve." -#: ../coreapi/callbacks.c:774 +#: ../coreapi/callbacks.c:792 msgid "User is busy." msgstr "A felhasználó foglalt." -#: ../coreapi/callbacks.c:775 +#: ../coreapi/callbacks.c:793 msgid "User is temporarily unavailable." msgstr "A felhasználó ideiglenesen nem elérhető" #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:777 +#: ../coreapi/callbacks.c:795 msgid "User does not want to be disturbed." msgstr "A felhasználó nem akarja, hogy zavarják." -#: ../coreapi/callbacks.c:778 +#: ../coreapi/callbacks.c:796 msgid "Call declined." msgstr "Hívás elutasítva" -#: ../coreapi/callbacks.c:793 +#: ../coreapi/callbacks.c:811 msgid "Request timeout." msgstr "" -#: ../coreapi/callbacks.c:824 +#: ../coreapi/callbacks.c:842 msgid "Redirected" msgstr "Átirányítva" -#: ../coreapi/callbacks.c:879 +#: ../coreapi/callbacks.c:897 msgid "Call failed." msgstr "Nem sikerült a hívás." -#: ../coreapi/callbacks.c:957 +#: ../coreapi/callbacks.c:975 #, c-format msgid "Registration on %s successful." msgstr "A regisztáció a %s -n sikerült." -#: ../coreapi/callbacks.c:958 +#: ../coreapi/callbacks.c:976 #, c-format msgid "Unregistration on %s done." msgstr "A kiregisztrálás kész a következőn: %s ." -#: ../coreapi/callbacks.c:976 +#: ../coreapi/callbacks.c:994 msgid "no response timeout" msgstr "időtúllépés után nincs válasz" -#: ../coreapi/callbacks.c:979 +#: ../coreapi/callbacks.c:997 #, c-format msgid "Registration on %s failed: %s" msgstr "A regisztáció a %s -n nem sikerült: %s" -#: ../coreapi/callbacks.c:986 +#: ../coreapi/callbacks.c:1004 msgid "Service unavailable, retrying" msgstr "" @@ -1973,7 +1973,7 @@ msgstr "" msgid "Authentication token is %s" msgstr "Hitelesítési jel: %s" -#: ../coreapi/linphonecall.c:3492 +#: ../coreapi/linphonecall.c:3600 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." diff --git a/po/it.po b/po/it.po index 7561f7f0d..d9fb54e86 100644 --- a/po/it.po +++ b/po/it.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-02-17 12:28+0100\n" +"POT-Creation-Date: 2015-03-11 16:26+0100\n" "PO-Revision-Date: 2015-02-17 11:28+0000\n" "Last-Translator: Belledonne Communications \n" @@ -89,53 +89,53 @@ msgstr "" msgid "Couldn't find pixmap file: %s" msgstr "" -#: ../gtk/chat.c:367 ../gtk/friendlist.c:924 +#: ../gtk/chat.c:374 ../gtk/friendlist.c:924 msgid "Invalid sip contact !" msgstr "Contatto SIP non valido" -#: ../gtk/main.c:109 +#: ../gtk/main.c:137 msgid "log to stdout some debug information while running." msgstr "" -#: ../gtk/main.c:116 +#: ../gtk/main.c:138 msgid "path to a file to write logs into." msgstr "" -#: ../gtk/main.c:123 +#: ../gtk/main.c:139 msgid "Start linphone with video disabled." msgstr "" -#: ../gtk/main.c:130 +#: ../gtk/main.c:140 msgid "Start only in the system tray, do not show the main interface." msgstr "" -#: ../gtk/main.c:137 +#: ../gtk/main.c:141 msgid "address to call right now" msgstr "" -#: ../gtk/main.c:144 +#: ../gtk/main.c:142 msgid "if set automatically answer incoming calls" msgstr "" -#: ../gtk/main.c:151 +#: ../gtk/main.c:143 msgid "" "Specifiy a working directory (should be the base of the installation, eg: c:" "\\Program Files\\Linphone)" msgstr "" -#: ../gtk/main.c:158 +#: ../gtk/main.c:144 msgid "Configuration file" msgstr "" -#: ../gtk/main.c:165 +#: ../gtk/main.c:145 msgid "Run the audio assistant" msgstr "" -#: ../gtk/main.c:172 +#: ../gtk/main.c:146 msgid "Run self test and exit 0 if succeed" msgstr "" -#: ../gtk/main.c:1088 +#: ../gtk/main.c:1061 #, c-format msgid "" "%s would like to add you to his contact list.\n" @@ -147,72 +147,72 @@ msgstr "" "veda il tuo stato o aggiungerlo alla tua lista dei contatti Se rispondi no " "questo utente sarà momentaneamente bloccato." -#: ../gtk/main.c:1165 +#: ../gtk/main.c:1138 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" msgstr "" -#: ../gtk/main.c:1286 +#: ../gtk/main.c:1259 msgid "Call error" msgstr "" -#: ../gtk/main.c:1289 ../coreapi/linphonecore.c:3787 +#: ../gtk/main.c:1262 ../coreapi/linphonecore.c:3791 msgid "Call ended" msgstr "Chiamata terminata" -#: ../gtk/main.c:1292 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1265 ../coreapi/call_log.c:221 msgid "Incoming call" msgstr "Chimata in entrata" -#: ../gtk/main.c:1294 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1267 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 msgid "Answer" msgstr "" -#: ../gtk/main.c:1296 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1269 ../gtk/main.ui.h:6 msgid "Decline" msgstr "Rifiuta" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 msgid "Call paused" msgstr "" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 #, c-format msgid "by %s" msgstr "" -#: ../gtk/main.c:1372 +#: ../gtk/main.c:1345 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "" -#: ../gtk/main.c:1534 +#: ../gtk/main.c:1507 msgid "Website link" msgstr "" -#: ../gtk/main.c:1583 +#: ../gtk/main.c:1556 msgid "Linphone - a video internet phone" msgstr "" -#: ../gtk/main.c:1675 +#: ../gtk/main.c:1648 #, c-format msgid "%s (Default)" msgstr "%s (Default)" -#: ../gtk/main.c:2007 ../coreapi/callbacks.c:1027 +#: ../gtk/main.c:1980 ../coreapi/callbacks.c:1045 #, c-format msgid "We are transferred to %s" msgstr "" -#: ../gtk/main.c:2017 +#: ../gtk/main.c:1990 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." msgstr "" -#: ../gtk/main.c:2161 +#: ../gtk/main.c:2135 msgid "A free SIP video-phone" msgstr "" @@ -740,7 +740,7 @@ msgstr "" msgid "(Paused)" msgstr "" -#: ../gtk/loginframe.c:88 +#: ../gtk/loginframe.c:87 #, c-format msgid "Please enter login information for %s" msgstr "Prego inserire le proprie credenziali di accesso per %s" @@ -1698,60 +1698,60 @@ msgstr "" msgid "Please wait while fetching configuration from server..." msgstr "" -#: ../coreapi/linphonecore.c:1508 +#: ../coreapi/linphonecore.c:1512 msgid "Ready" msgstr "Pronto" -#: ../coreapi/linphonecore.c:2495 +#: ../coreapi/linphonecore.c:2499 msgid "Configuring" msgstr "" -#: ../coreapi/linphonecore.c:2669 +#: ../coreapi/linphonecore.c:2673 msgid "Looking for telephone number destination..." msgstr "Ricerca numero destinazione..." -#: ../coreapi/linphonecore.c:2671 +#: ../coreapi/linphonecore.c:2675 msgid "Could not resolve this number." msgstr "Impossibile risolvere il numero." #. must be known at that time -#: ../coreapi/linphonecore.c:2957 +#: ../coreapi/linphonecore.c:2961 msgid "Contacting" msgstr "In connessione" -#: ../coreapi/linphonecore.c:2962 +#: ../coreapi/linphonecore.c:2966 msgid "Could not call" msgstr "" -#: ../coreapi/linphonecore.c:3112 +#: ../coreapi/linphonecore.c:3116 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "" -#: ../coreapi/linphonecore.c:3270 +#: ../coreapi/linphonecore.c:3274 msgid "is contacting you" msgstr "" -#: ../coreapi/linphonecore.c:3271 +#: ../coreapi/linphonecore.c:3275 msgid " and asked autoanswer." msgstr "" -#: ../coreapi/linphonecore.c:3395 +#: ../coreapi/linphonecore.c:3399 msgid "Modifying call parameters..." msgstr "" -#: ../coreapi/linphonecore.c:3743 +#: ../coreapi/linphonecore.c:3747 msgid "Connected." msgstr "Connessione" -#: ../coreapi/linphonecore.c:3768 +#: ../coreapi/linphonecore.c:3772 msgid "Call aborted" msgstr "" -#: ../coreapi/linphonecore.c:3958 +#: ../coreapi/linphonecore.c:3962 msgid "Could not pause the call" msgstr "" -#: ../coreapi/linphonecore.c:3961 +#: ../coreapi/linphonecore.c:3965 msgid "Pausing the current call..." msgstr "" @@ -1836,112 +1836,112 @@ msgstr "" msgid "Could not login as %s" msgstr "impossibile login come %s" -#: ../coreapi/callbacks.c:404 +#: ../coreapi/callbacks.c:419 msgid "Remote ringing." msgstr "" -#: ../coreapi/callbacks.c:425 +#: ../coreapi/callbacks.c:431 msgid "Remote ringing..." msgstr "" -#: ../coreapi/callbacks.c:442 +#: ../coreapi/callbacks.c:448 msgid "Early media." msgstr "" -#: ../coreapi/callbacks.c:503 +#: ../coreapi/callbacks.c:521 #, c-format msgid "Call with %s is paused." msgstr "" -#: ../coreapi/callbacks.c:516 +#: ../coreapi/callbacks.c:534 #, c-format msgid "Call answered by %s - on hold." msgstr "" -#: ../coreapi/callbacks.c:526 +#: ../coreapi/callbacks.c:544 msgid "Call resumed." msgstr "" -#: ../coreapi/callbacks.c:530 +#: ../coreapi/callbacks.c:548 #, c-format msgid "Call answered by %s." msgstr "" -#: ../coreapi/callbacks.c:553 +#: ../coreapi/callbacks.c:571 msgid "Incompatible, check codecs or security settings..." msgstr "" -#: ../coreapi/callbacks.c:558 ../coreapi/callbacks.c:870 +#: ../coreapi/callbacks.c:576 ../coreapi/callbacks.c:888 msgid "Incompatible media parameters." msgstr "" -#: ../coreapi/callbacks.c:588 +#: ../coreapi/callbacks.c:606 msgid "We have been resumed." msgstr "" #. we are being paused -#: ../coreapi/callbacks.c:596 +#: ../coreapi/callbacks.c:614 msgid "We are paused by other party." msgstr "" #. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:630 +#: ../coreapi/callbacks.c:648 msgid "Call is updated by remote." msgstr "" -#: ../coreapi/callbacks.c:746 +#: ../coreapi/callbacks.c:764 msgid "Call terminated." msgstr "Chiamata terminata." -#: ../coreapi/callbacks.c:774 +#: ../coreapi/callbacks.c:792 msgid "User is busy." msgstr "Utente occupato" -#: ../coreapi/callbacks.c:775 +#: ../coreapi/callbacks.c:793 msgid "User is temporarily unavailable." msgstr "Utente non disponibile" #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:777 +#: ../coreapi/callbacks.c:795 msgid "User does not want to be disturbed." msgstr "L'utente non vuole essere disturbato" -#: ../coreapi/callbacks.c:778 +#: ../coreapi/callbacks.c:796 msgid "Call declined." msgstr "Chiamata rifiutata" -#: ../coreapi/callbacks.c:793 +#: ../coreapi/callbacks.c:811 msgid "Request timeout." msgstr "" -#: ../coreapi/callbacks.c:824 +#: ../coreapi/callbacks.c:842 msgid "Redirected" msgstr "" -#: ../coreapi/callbacks.c:879 +#: ../coreapi/callbacks.c:897 msgid "Call failed." msgstr "" -#: ../coreapi/callbacks.c:957 +#: ../coreapi/callbacks.c:975 #, c-format msgid "Registration on %s successful." msgstr "Registrazione su %s attiva" -#: ../coreapi/callbacks.c:958 +#: ../coreapi/callbacks.c:976 #, c-format msgid "Unregistration on %s done." msgstr "Unregistrazione su %s" -#: ../coreapi/callbacks.c:976 +#: ../coreapi/callbacks.c:994 msgid "no response timeout" msgstr "timeout no risposta" -#: ../coreapi/callbacks.c:979 +#: ../coreapi/callbacks.c:997 #, c-format msgid "Registration on %s failed: %s" msgstr "Registrazione su %s fallita: %s" -#: ../coreapi/callbacks.c:986 +#: ../coreapi/callbacks.c:1004 msgid "Service unavailable, retrying" msgstr "" @@ -1951,7 +1951,7 @@ msgstr "" msgid "Authentication token is %s" msgstr "" -#: ../coreapi/linphonecall.c:3492 +#: ../coreapi/linphonecall.c:3600 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." diff --git a/po/ja.po b/po/ja.po index e4420706b..7a809c610 100644 --- a/po/ja.po +++ b/po/ja.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-02-17 12:28+0100\n" +"POT-Creation-Date: 2015-03-11 16:26+0100\n" "PO-Revision-Date: 2015-02-17 11:28+0000\n" "Last-Translator: Belledonne Communications \n" @@ -91,35 +91,35 @@ msgstr "自分" msgid "Couldn't find pixmap file: %s" msgstr "pixmapファイルが見つかりません %s" -#: ../gtk/chat.c:367 ../gtk/friendlist.c:924 +#: ../gtk/chat.c:374 ../gtk/friendlist.c:924 msgid "Invalid sip contact !" msgstr "無効なSIP接続です!" -#: ../gtk/main.c:109 +#: ../gtk/main.c:137 msgid "log to stdout some debug information while running." msgstr "実行中にいくつかのデバッグ情報をstdoutに送信します。" -#: ../gtk/main.c:116 +#: ../gtk/main.c:138 msgid "path to a file to write logs into." msgstr "ログを書き込むファイルへのパス。" -#: ../gtk/main.c:123 +#: ../gtk/main.c:139 msgid "Start linphone with video disabled." msgstr "ビデオを無効にしてLinphoneを開始します。" -#: ../gtk/main.c:130 +#: ../gtk/main.c:140 msgid "Start only in the system tray, do not show the main interface." msgstr "主なインターフェイスを表示しないでシステムトレイに移動します。" -#: ../gtk/main.c:137 +#: ../gtk/main.c:141 msgid "address to call right now" msgstr "今すぐに呼び出す" -#: ../gtk/main.c:144 +#: ../gtk/main.c:142 msgid "if set automatically answer incoming calls" msgstr "着信呼び出しが設定されている場合自動的に応答する" -#: ../gtk/main.c:151 +#: ../gtk/main.c:143 msgid "" "Specifiy a working directory (should be the base of the installation, eg: c:" "\\Program Files\\Linphone)" @@ -127,19 +127,19 @@ msgstr "" "作業ディレクトリをSpecifiy (インストールした時のベースである必要があります。" "例:c:\\Program Files\\Linphone)" -#: ../gtk/main.c:158 +#: ../gtk/main.c:144 msgid "Configuration file" msgstr "設定ファイル" -#: ../gtk/main.c:165 +#: ../gtk/main.c:145 msgid "Run the audio assistant" msgstr "オーディオアシスタントを実行" -#: ../gtk/main.c:172 +#: ../gtk/main.c:146 msgid "Run self test and exit 0 if succeed" msgstr "" -#: ../gtk/main.c:1088 +#: ../gtk/main.c:1061 #, c-format msgid "" "%s would like to add you to his contact list.\n" @@ -152,72 +152,72 @@ msgstr "" "す。\n" "あなたが拒否すると、この人は一時的にブラックリストへ登録されます。" -#: ../gtk/main.c:1165 +#: ../gtk/main.c:1138 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" msgstr "" -#: ../gtk/main.c:1286 +#: ../gtk/main.c:1259 msgid "Call error" msgstr "呼出エラー" -#: ../gtk/main.c:1289 ../coreapi/linphonecore.c:3787 +#: ../gtk/main.c:1262 ../coreapi/linphonecore.c:3791 msgid "Call ended" msgstr "呼出終了" -#: ../gtk/main.c:1292 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1265 ../coreapi/call_log.c:221 msgid "Incoming call" msgstr "着信" -#: ../gtk/main.c:1294 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1267 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 msgid "Answer" msgstr "応答" -#: ../gtk/main.c:1296 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1269 ../gtk/main.ui.h:6 msgid "Decline" msgstr "拒否" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 msgid "Call paused" msgstr "呼び出しの一時停止" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 #, c-format msgid "by %s" msgstr "%s" -#: ../gtk/main.c:1372 +#: ../gtk/main.c:1345 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "" -#: ../gtk/main.c:1534 +#: ../gtk/main.c:1507 msgid "Website link" msgstr "ウェブサイトリンク" -#: ../gtk/main.c:1583 +#: ../gtk/main.c:1556 msgid "Linphone - a video internet phone" msgstr "Linphone - ビデオインターネット電話" -#: ../gtk/main.c:1675 +#: ../gtk/main.c:1648 #, c-format msgid "%s (Default)" msgstr "%s (デフォルト)" -#: ../gtk/main.c:2007 ../coreapi/callbacks.c:1027 +#: ../gtk/main.c:1980 ../coreapi/callbacks.c:1045 #, c-format msgid "We are transferred to %s" msgstr "%s に転送しました" -#: ../gtk/main.c:2017 +#: ../gtk/main.c:1990 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." msgstr "" -#: ../gtk/main.c:2161 +#: ../gtk/main.c:2135 msgid "A free SIP video-phone" msgstr "無料 SIP ビデオ-電話" @@ -752,7 +752,7 @@ msgstr "" msgid "(Paused)" msgstr "(停止中)" -#: ../gtk/loginframe.c:88 +#: ../gtk/loginframe.c:87 #, c-format msgid "Please enter login information for %s" msgstr "" @@ -1723,60 +1723,60 @@ msgstr "" msgid "Please wait while fetching configuration from server..." msgstr "" -#: ../coreapi/linphonecore.c:1508 +#: ../coreapi/linphonecore.c:1512 msgid "Ready" msgstr "準備" -#: ../coreapi/linphonecore.c:2495 +#: ../coreapi/linphonecore.c:2499 msgid "Configuring" msgstr "" -#: ../coreapi/linphonecore.c:2669 +#: ../coreapi/linphonecore.c:2673 msgid "Looking for telephone number destination..." msgstr "" -#: ../coreapi/linphonecore.c:2671 +#: ../coreapi/linphonecore.c:2675 msgid "Could not resolve this number." msgstr "" #. must be known at that time -#: ../coreapi/linphonecore.c:2957 +#: ../coreapi/linphonecore.c:2961 msgid "Contacting" msgstr "" -#: ../coreapi/linphonecore.c:2962 +#: ../coreapi/linphonecore.c:2966 msgid "Could not call" msgstr "" -#: ../coreapi/linphonecore.c:3112 +#: ../coreapi/linphonecore.c:3116 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "" -#: ../coreapi/linphonecore.c:3270 +#: ../coreapi/linphonecore.c:3274 msgid "is contacting you" msgstr "" -#: ../coreapi/linphonecore.c:3271 +#: ../coreapi/linphonecore.c:3275 msgid " and asked autoanswer." msgstr "と自動応答を尋ねる" -#: ../coreapi/linphonecore.c:3395 +#: ../coreapi/linphonecore.c:3399 msgid "Modifying call parameters..." msgstr "コールパラメーターの変更..." -#: ../coreapi/linphonecore.c:3743 +#: ../coreapi/linphonecore.c:3747 msgid "Connected." msgstr "接続しました。" -#: ../coreapi/linphonecore.c:3768 +#: ../coreapi/linphonecore.c:3772 msgid "Call aborted" msgstr "呼び出しを打ち切る" -#: ../coreapi/linphonecore.c:3958 +#: ../coreapi/linphonecore.c:3962 msgid "Could not pause the call" msgstr "呼び出しを一時停止できませんでした" -#: ../coreapi/linphonecore.c:3961 +#: ../coreapi/linphonecore.c:3965 msgid "Pausing the current call..." msgstr "現在の通話を一時停止..." @@ -1857,112 +1857,112 @@ msgstr "" msgid "Could not login as %s" msgstr "" -#: ../coreapi/callbacks.c:404 +#: ../coreapi/callbacks.c:419 msgid "Remote ringing." msgstr "" -#: ../coreapi/callbacks.c:425 +#: ../coreapi/callbacks.c:431 msgid "Remote ringing..." msgstr "" -#: ../coreapi/callbacks.c:442 +#: ../coreapi/callbacks.c:448 msgid "Early media." msgstr "Early media." -#: ../coreapi/callbacks.c:503 +#: ../coreapi/callbacks.c:521 #, c-format msgid "Call with %s is paused." msgstr "" -#: ../coreapi/callbacks.c:516 +#: ../coreapi/callbacks.c:534 #, c-format msgid "Call answered by %s - on hold." msgstr "" -#: ../coreapi/callbacks.c:526 +#: ../coreapi/callbacks.c:544 msgid "Call resumed." msgstr "" -#: ../coreapi/callbacks.c:530 +#: ../coreapi/callbacks.c:548 #, c-format msgid "Call answered by %s." msgstr "" -#: ../coreapi/callbacks.c:553 +#: ../coreapi/callbacks.c:571 msgid "Incompatible, check codecs or security settings..." msgstr "" -#: ../coreapi/callbacks.c:558 ../coreapi/callbacks.c:870 +#: ../coreapi/callbacks.c:576 ../coreapi/callbacks.c:888 msgid "Incompatible media parameters." msgstr "" -#: ../coreapi/callbacks.c:588 +#: ../coreapi/callbacks.c:606 msgid "We have been resumed." msgstr "" #. we are being paused -#: ../coreapi/callbacks.c:596 +#: ../coreapi/callbacks.c:614 msgid "We are paused by other party." msgstr "" #. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:630 +#: ../coreapi/callbacks.c:648 msgid "Call is updated by remote." msgstr "" -#: ../coreapi/callbacks.c:746 +#: ../coreapi/callbacks.c:764 msgid "Call terminated." msgstr "呼び出し終了。" -#: ../coreapi/callbacks.c:774 +#: ../coreapi/callbacks.c:792 msgid "User is busy." msgstr "相手はビジーです。" -#: ../coreapi/callbacks.c:775 +#: ../coreapi/callbacks.c:793 msgid "User is temporarily unavailable." msgstr "相手は、今出られません。" #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:777 +#: ../coreapi/callbacks.c:795 msgid "User does not want to be disturbed." msgstr "相手は手が離せないようです。" -#: ../coreapi/callbacks.c:778 +#: ../coreapi/callbacks.c:796 msgid "Call declined." msgstr "通話は拒否されました。" -#: ../coreapi/callbacks.c:793 +#: ../coreapi/callbacks.c:811 msgid "Request timeout." msgstr "リクエストは時間切れです。" -#: ../coreapi/callbacks.c:824 +#: ../coreapi/callbacks.c:842 msgid "Redirected" msgstr "" -#: ../coreapi/callbacks.c:879 +#: ../coreapi/callbacks.c:897 msgid "Call failed." msgstr "" -#: ../coreapi/callbacks.c:957 +#: ../coreapi/callbacks.c:975 #, c-format msgid "Registration on %s successful." msgstr "" -#: ../coreapi/callbacks.c:958 +#: ../coreapi/callbacks.c:976 #, c-format msgid "Unregistration on %s done." msgstr "" -#: ../coreapi/callbacks.c:976 +#: ../coreapi/callbacks.c:994 msgid "no response timeout" msgstr "" -#: ../coreapi/callbacks.c:979 +#: ../coreapi/callbacks.c:997 #, c-format msgid "Registration on %s failed: %s" msgstr "" -#: ../coreapi/callbacks.c:986 +#: ../coreapi/callbacks.c:1004 msgid "Service unavailable, retrying" msgstr "" @@ -1972,7 +1972,7 @@ msgstr "" msgid "Authentication token is %s" msgstr "" -#: ../coreapi/linphonecall.c:3492 +#: ../coreapi/linphonecall.c:3600 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." diff --git a/po/nb_NO.po b/po/nb_NO.po index e6bb13dc7..010981476 100644 --- a/po/nb_NO.po +++ b/po/nb_NO.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-02-17 12:28+0100\n" +"POT-Creation-Date: 2015-03-11 16:26+0100\n" "PO-Revision-Date: 2015-02-17 11:28+0000\n" "Last-Translator: Belledonne Communications \n" @@ -90,35 +90,35 @@ msgstr "" msgid "Couldn't find pixmap file: %s" msgstr "Fant ikke pixmap fli: %s" -#: ../gtk/chat.c:367 ../gtk/friendlist.c:924 +#: ../gtk/chat.c:374 ../gtk/friendlist.c:924 msgid "Invalid sip contact !" msgstr "Ugyldig SIP kontakt !" -#: ../gtk/main.c:109 +#: ../gtk/main.c:137 msgid "log to stdout some debug information while running." msgstr "skriv logg-informasjon under kjøring" -#: ../gtk/main.c:116 +#: ../gtk/main.c:138 msgid "path to a file to write logs into." msgstr "" -#: ../gtk/main.c:123 +#: ../gtk/main.c:139 msgid "Start linphone with video disabled." msgstr "" -#: ../gtk/main.c:130 +#: ../gtk/main.c:140 msgid "Start only in the system tray, do not show the main interface." msgstr "Start skjult i systemkurven, ikke vis programbildet." -#: ../gtk/main.c:137 +#: ../gtk/main.c:141 msgid "address to call right now" msgstr "address som skal ringes nå" -#: ../gtk/main.c:144 +#: ../gtk/main.c:142 msgid "if set automatically answer incoming calls" msgstr "besvarer innkommende samtaler automatisk om valgt" -#: ../gtk/main.c:151 +#: ../gtk/main.c:143 msgid "" "Specifiy a working directory (should be the base of the installation, eg: c:" "\\Program Files\\Linphone)" @@ -126,19 +126,19 @@ msgstr "" "Spesifiser arbeidsmappe (bør være base for installasjonen, f.eks: c:" "\\Programfiler\\Linphone)" -#: ../gtk/main.c:158 +#: ../gtk/main.c:144 msgid "Configuration file" msgstr "" -#: ../gtk/main.c:165 +#: ../gtk/main.c:145 msgid "Run the audio assistant" msgstr "" -#: ../gtk/main.c:172 +#: ../gtk/main.c:146 msgid "Run self test and exit 0 if succeed" msgstr "" -#: ../gtk/main.c:1088 +#: ../gtk/main.c:1061 #, c-format msgid "" "%s would like to add you to his contact list.\n" @@ -151,66 +151,66 @@ msgstr "" "din kontaktliste?\n" "Hvis du svarer nei vil personen bli svartelyst midlertidig." -#: ../gtk/main.c:1165 +#: ../gtk/main.c:1138 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" msgstr "" -#: ../gtk/main.c:1286 +#: ../gtk/main.c:1259 msgid "Call error" msgstr "" -#: ../gtk/main.c:1289 ../coreapi/linphonecore.c:3787 +#: ../gtk/main.c:1262 ../coreapi/linphonecore.c:3791 msgid "Call ended" msgstr "Samtale avsluttet" -#: ../gtk/main.c:1292 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1265 ../coreapi/call_log.c:221 msgid "Incoming call" msgstr "Innkommende samtale" -#: ../gtk/main.c:1294 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1267 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 msgid "Answer" msgstr "Svarer" -#: ../gtk/main.c:1296 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1269 ../gtk/main.ui.h:6 msgid "Decline" msgstr "Avvis" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 msgid "Call paused" msgstr "" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 #, c-format msgid "by %s" msgstr "" -#: ../gtk/main.c:1372 +#: ../gtk/main.c:1345 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "" -#: ../gtk/main.c:1534 +#: ../gtk/main.c:1507 msgid "Website link" msgstr "Peker til nettsted" -#: ../gtk/main.c:1583 +#: ../gtk/main.c:1556 msgid "Linphone - a video internet phone" msgstr "Linphone - en video Internet telefon" -#: ../gtk/main.c:1675 +#: ../gtk/main.c:1648 #, c-format msgid "%s (Default)" msgstr "%s (Standard)" -#: ../gtk/main.c:2007 ../coreapi/callbacks.c:1027 +#: ../gtk/main.c:1980 ../coreapi/callbacks.c:1045 #, c-format msgid "We are transferred to %s" msgstr "Vi er overført til %s" -#: ../gtk/main.c:2017 +#: ../gtk/main.c:1990 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." @@ -218,7 +218,7 @@ msgstr "" "Klarte ikke å finne noe lydkort på denne datamaskinen.\n" "Du vil ikke kunne sende eller motta lydsamtaler." -#: ../gtk/main.c:2161 +#: ../gtk/main.c:2135 msgid "A free SIP video-phone" msgstr "En gratis SIP video-telefon" @@ -746,7 +746,7 @@ msgstr "" msgid "(Paused)" msgstr "" -#: ../gtk/loginframe.c:88 +#: ../gtk/loginframe.c:87 #, c-format msgid "Please enter login information for %s" msgstr "Skriv inn påloggingsinformasjon for %s:" @@ -1705,60 +1705,60 @@ msgstr "" msgid "Please wait while fetching configuration from server..." msgstr "" -#: ../coreapi/linphonecore.c:1508 +#: ../coreapi/linphonecore.c:1512 msgid "Ready" msgstr "Klar" -#: ../coreapi/linphonecore.c:2495 +#: ../coreapi/linphonecore.c:2499 msgid "Configuring" msgstr "" -#: ../coreapi/linphonecore.c:2669 +#: ../coreapi/linphonecore.c:2673 msgid "Looking for telephone number destination..." msgstr "Ser etter telefonnummer for destinasjonen..." -#: ../coreapi/linphonecore.c:2671 +#: ../coreapi/linphonecore.c:2675 msgid "Could not resolve this number." msgstr "Kan ikke tilkoble dette nummeret." #. must be known at that time -#: ../coreapi/linphonecore.c:2957 +#: ../coreapi/linphonecore.c:2961 msgid "Contacting" msgstr "Tilknytter" -#: ../coreapi/linphonecore.c:2962 +#: ../coreapi/linphonecore.c:2966 msgid "Could not call" msgstr "Kunne ikke ringe" -#: ../coreapi/linphonecore.c:3112 +#: ../coreapi/linphonecore.c:3116 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "Beklager, du har nådd maksimalt antall samtidige samtaler" -#: ../coreapi/linphonecore.c:3270 +#: ../coreapi/linphonecore.c:3274 msgid "is contacting you" msgstr "Kontakter deg." -#: ../coreapi/linphonecore.c:3271 +#: ../coreapi/linphonecore.c:3275 msgid " and asked autoanswer." msgstr " og ba om autosvar." -#: ../coreapi/linphonecore.c:3395 +#: ../coreapi/linphonecore.c:3399 msgid "Modifying call parameters..." msgstr "Endrer ringeparametre..." -#: ../coreapi/linphonecore.c:3743 +#: ../coreapi/linphonecore.c:3747 msgid "Connected." msgstr "Tilkoblet" -#: ../coreapi/linphonecore.c:3768 +#: ../coreapi/linphonecore.c:3772 msgid "Call aborted" msgstr "Samtale avbrutt" -#: ../coreapi/linphonecore.c:3958 +#: ../coreapi/linphonecore.c:3962 msgid "Could not pause the call" msgstr "Kunne ikke pause samtalen" -#: ../coreapi/linphonecore.c:3961 +#: ../coreapi/linphonecore.c:3965 msgid "Pausing the current call..." msgstr "Pauser nåværende samtale" @@ -1843,112 +1843,112 @@ msgstr "" msgid "Could not login as %s" msgstr "Ikke ikke logge inn som %s" -#: ../coreapi/callbacks.c:404 +#: ../coreapi/callbacks.c:419 msgid "Remote ringing." msgstr "Ringer hos motparten." -#: ../coreapi/callbacks.c:425 +#: ../coreapi/callbacks.c:431 msgid "Remote ringing..." msgstr "" -#: ../coreapi/callbacks.c:442 +#: ../coreapi/callbacks.c:448 msgid "Early media." msgstr "Tidlig media" -#: ../coreapi/callbacks.c:503 +#: ../coreapi/callbacks.c:521 #, c-format msgid "Call with %s is paused." msgstr "Samtalen med %s er pauset." -#: ../coreapi/callbacks.c:516 +#: ../coreapi/callbacks.c:534 #, c-format msgid "Call answered by %s - on hold." msgstr "Samtale besvart av %s - på vent." -#: ../coreapi/callbacks.c:526 +#: ../coreapi/callbacks.c:544 msgid "Call resumed." msgstr "Samtale gjenopptatt." -#: ../coreapi/callbacks.c:530 +#: ../coreapi/callbacks.c:548 #, c-format msgid "Call answered by %s." msgstr "Samtale besvart av %s." -#: ../coreapi/callbacks.c:553 +#: ../coreapi/callbacks.c:571 msgid "Incompatible, check codecs or security settings..." msgstr "" -#: ../coreapi/callbacks.c:558 ../coreapi/callbacks.c:870 +#: ../coreapi/callbacks.c:576 ../coreapi/callbacks.c:888 msgid "Incompatible media parameters." msgstr "" -#: ../coreapi/callbacks.c:588 +#: ../coreapi/callbacks.c:606 msgid "We have been resumed." msgstr "" #. we are being paused -#: ../coreapi/callbacks.c:596 +#: ../coreapi/callbacks.c:614 msgid "We are paused by other party." msgstr "" #. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:630 +#: ../coreapi/callbacks.c:648 msgid "Call is updated by remote." msgstr "" -#: ../coreapi/callbacks.c:746 +#: ../coreapi/callbacks.c:764 msgid "Call terminated." msgstr "Samtale avsluttet." -#: ../coreapi/callbacks.c:774 +#: ../coreapi/callbacks.c:792 msgid "User is busy." msgstr "Brukeren er opptatt." -#: ../coreapi/callbacks.c:775 +#: ../coreapi/callbacks.c:793 msgid "User is temporarily unavailable." msgstr "Brukeren er midlertidig ikke tilgjengelig." #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:777 +#: ../coreapi/callbacks.c:795 msgid "User does not want to be disturbed." msgstr "Brukeren vil ikke bli forstyrret." -#: ../coreapi/callbacks.c:778 +#: ../coreapi/callbacks.c:796 msgid "Call declined." msgstr "Samtale avvist." -#: ../coreapi/callbacks.c:793 +#: ../coreapi/callbacks.c:811 msgid "Request timeout." msgstr "" -#: ../coreapi/callbacks.c:824 +#: ../coreapi/callbacks.c:842 msgid "Redirected" msgstr "Omdirigert" -#: ../coreapi/callbacks.c:879 +#: ../coreapi/callbacks.c:897 msgid "Call failed." msgstr "Samtale feilet." -#: ../coreapi/callbacks.c:957 +#: ../coreapi/callbacks.c:975 #, c-format msgid "Registration on %s successful." msgstr "Registrering hos %s lykkes." -#: ../coreapi/callbacks.c:958 +#: ../coreapi/callbacks.c:976 #, c-format msgid "Unregistration on %s done." msgstr "Avregistrering hos %s lykkes." -#: ../coreapi/callbacks.c:976 +#: ../coreapi/callbacks.c:994 msgid "no response timeout" msgstr "ingen svar innen angitt tid" -#: ../coreapi/callbacks.c:979 +#: ../coreapi/callbacks.c:997 #, c-format msgid "Registration on %s failed: %s" msgstr "Registrering hos %s mislykkes: %s" -#: ../coreapi/callbacks.c:986 +#: ../coreapi/callbacks.c:1004 msgid "Service unavailable, retrying" msgstr "" @@ -1958,7 +1958,7 @@ msgstr "" msgid "Authentication token is %s" msgstr "" -#: ../coreapi/linphonecall.c:3492 +#: ../coreapi/linphonecall.c:3600 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." diff --git a/po/nl.po b/po/nl.po index 9724098a7..d11793325 100644 --- a/po/nl.po +++ b/po/nl.po @@ -3,14 +3,14 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# Heimen Stoffels , 2015 msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-02-17 12:28+0100\n" -"PO-Revision-Date: 2015-02-17 11:28+0000\n" -"Last-Translator: Belledonne Communications \n" +"POT-Creation-Date: 2015-03-11 16:26+0100\n" +"PO-Revision-Date: 2015-03-09 21:41+0000\n" +"Last-Translator: Heimen Stoffels \n" "Language-Team: Dutch (http://www.transifex.com/projects/p/linphone-gtk/" "language/nl/)\n" "Language: nl\n" @@ -22,47 +22,47 @@ msgstr "" #: ../gtk/calllogs.c:148 ../gtk/friendlist.c:974 #, c-format msgid "Call %s" -msgstr "" +msgstr "%s bellen" #: ../gtk/calllogs.c:149 ../gtk/friendlist.c:975 #, c-format msgid "Send text to %s" -msgstr "" +msgstr "SMS versturen aan %s" #: ../gtk/calllogs.c:232 #, c-format msgid "Recent calls (%i)" -msgstr "" +msgstr "Recent oproepen (%i)" #: ../gtk/calllogs.c:314 msgid "n/a" -msgstr "" +msgstr "n.v.t." #: ../gtk/calllogs.c:317 msgid "Aborted" -msgstr "" +msgstr "Afgebroken" #: ../gtk/calllogs.c:320 msgid "Missed" -msgstr "" +msgstr "Gemist" #: ../gtk/calllogs.c:323 msgid "Declined" -msgstr "" +msgstr "Geweigerd" #: ../gtk/calllogs.c:329 #, c-format msgid "%i minute" msgid_plural "%i minutes" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%i minuut" +msgstr[1] "%i minuten" #: ../gtk/calllogs.c:332 #, c-format msgid "%i second" msgid_plural "%i seconds" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%i seconde" +msgstr[1] "%i seconden" #: ../gtk/calllogs.c:337 #, c-format @@ -70,72 +70,78 @@ msgid "" "%s\tQuality: %s\n" "%s\t%s\t" msgstr "" +"%s\tKwaliteit: %s\n" +"%s\t%s\t" #: ../gtk/calllogs.c:341 #, c-format msgid "%s\t%s" -msgstr "" +msgstr "%s\t%s" #: ../gtk/conference.c:38 ../gtk/main.ui.h:13 msgid "Conference" -msgstr "" +msgstr "Vergadering" #: ../gtk/conference.c:46 msgid "Me" -msgstr "" +msgstr "Ik" #: ../gtk/support.c:49 ../gtk/support.c:73 ../gtk/support.c:102 #, c-format msgid "Couldn't find pixmap file: %s" -msgstr "Kon pixmap bestand %s niet vinden" +msgstr "Het pixmap-bestand %s kon niet worden gevonden" -#: ../gtk/chat.c:367 ../gtk/friendlist.c:924 +#: ../gtk/chat.c:374 ../gtk/friendlist.c:924 msgid "Invalid sip contact !" -msgstr "" - -#: ../gtk/main.c:109 -msgid "log to stdout some debug information while running." -msgstr "" - -#: ../gtk/main.c:116 -msgid "path to a file to write logs into." -msgstr "" - -#: ../gtk/main.c:123 -msgid "Start linphone with video disabled." -msgstr "" - -#: ../gtk/main.c:130 -msgid "Start only in the system tray, do not show the main interface." -msgstr "" +msgstr "Ongeldig SIP-contactpersoon" #: ../gtk/main.c:137 +msgid "log to stdout some debug information while running." +msgstr "" +"loggen naar stdout om wat foutopsporingsinformatie te verkrijgen tijdens " +"uitvoeren." + +#: ../gtk/main.c:138 +msgid "path to a file to write logs into." +msgstr "Pad naar een bestand om logbestanden heen te schrijven." + +#: ../gtk/main.c:139 +msgid "Start linphone with video disabled." +msgstr "Linphone opstarten met uitgeschakelde video." + +#: ../gtk/main.c:140 +msgid "Start only in the system tray, do not show the main interface." +msgstr "Alleen in het systeemvak opstarten, niet met venster en al." + +#: ../gtk/main.c:141 msgid "address to call right now" -msgstr "" +msgstr "adres om nu naar toe te bellen" -#: ../gtk/main.c:144 +#: ../gtk/main.c:142 msgid "if set automatically answer incoming calls" -msgstr "" +msgstr "als u dit inschakelt worden oproepen automatisch beantwoord" -#: ../gtk/main.c:151 +#: ../gtk/main.c:143 msgid "" "Specifiy a working directory (should be the base of the installation, eg: c:" "\\Program Files\\Linphone)" msgstr "" +"Specificeer een werkmap (dit moet de basis van uw installatie zijn, bijv.: C:" +"\\Program Files\\Linphone)" -#: ../gtk/main.c:158 +#: ../gtk/main.c:144 msgid "Configuration file" -msgstr "" +msgstr "Configuratiebestand" -#: ../gtk/main.c:165 +#: ../gtk/main.c:145 msgid "Run the audio assistant" -msgstr "" +msgstr "Doorloop de audio-instelwizard" -#: ../gtk/main.c:172 +#: ../gtk/main.c:146 msgid "Run self test and exit 0 if succeed" -msgstr "" +msgstr "Draai een zelftest en exit 0 wanneer succesvol" -#: ../gtk/main.c:1088 +#: ../gtk/main.c:1061 #, c-format msgid "" "%s would like to add you to his contact list.\n" @@ -143,79 +149,88 @@ msgid "" "list ?\n" "If you answer no, this person will be temporarily blacklisted." msgstr "" +"%s wil u toevoegen aan zijn/haar contactpersonenlijst.\n" +"Wilt u toestaan dat hij/zij uw aanwezigheidsstatus ziet of hem/haar " +"toevoegen aan uw contactpersonenljst?\n" +"Indien u nee antwoordt, zal deze persoon tijdelijk op de zwarte lijst worden " +"gezet." -#: ../gtk/main.c:1165 +#: ../gtk/main.c:1138 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" msgstr "" +"Vul uw wachtwoord in voor gebruikersnaam %s\n" +"op realm %s" -#: ../gtk/main.c:1286 +#: ../gtk/main.c:1259 msgid "Call error" -msgstr "" +msgstr "Oproepfout" -#: ../gtk/main.c:1289 ../coreapi/linphonecore.c:3787 +#: ../gtk/main.c:1262 ../coreapi/linphonecore.c:3791 msgid "Call ended" -msgstr "Oproep beeindigd" +msgstr "Oproep beëindigd" -#: ../gtk/main.c:1292 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1265 ../coreapi/call_log.c:221 msgid "Incoming call" msgstr "Inkomende oproep" -#: ../gtk/main.c:1294 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1267 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 msgid "Answer" -msgstr "" +msgstr "Opnemen" -#: ../gtk/main.c:1296 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1269 ../gtk/main.ui.h:6 msgid "Decline" -msgstr "" +msgstr "Weigeren" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 msgid "Call paused" -msgstr "" +msgstr "Oproep gepauzeerd" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 #, c-format msgid "by %s" -msgstr "" +msgstr "door %s" -#: ../gtk/main.c:1372 +#: ../gtk/main.c:1345 #, c-format msgid "%s proposed to start video. Do you accept ?" -msgstr "" +msgstr "%s stelt u voor om video in te schakelen. Wilt u dit accepteren?" -#: ../gtk/main.c:1534 +#: ../gtk/main.c:1507 msgid "Website link" -msgstr "" +msgstr "Websitelink" -#: ../gtk/main.c:1583 +#: ../gtk/main.c:1556 msgid "Linphone - a video internet phone" -msgstr "" +msgstr "Linphone - een video-internettelefoon" -#: ../gtk/main.c:1675 +#: ../gtk/main.c:1648 #, c-format msgid "%s (Default)" -msgstr "" +msgstr "%s (Standaard)" -#: ../gtk/main.c:2007 ../coreapi/callbacks.c:1027 +#: ../gtk/main.c:1980 ../coreapi/callbacks.c:1045 #, c-format msgid "We are transferred to %s" -msgstr "" +msgstr "We zijn overgeschakeld naar %s" -#: ../gtk/main.c:2017 +#: ../gtk/main.c:1990 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." msgstr "" +"Er zijn geluidskaarten aangetroffen op deze computer.\n" +"U zult niet in staat zijn om audio-oproepen te ontvangen of versturen." -#: ../gtk/main.c:2161 +#: ../gtk/main.c:2135 msgid "A free SIP video-phone" -msgstr "Een Vrije SIP video-telefoon" +msgstr "Een gratis SIP-videotelefoon" #: ../gtk/friendlist.c:505 msgid "Add to addressbook" -msgstr "" +msgstr "Toevoegen aan adresboek" #: ../gtk/friendlist.c:691 msgid "Presence status" @@ -227,36 +242,36 @@ msgstr "Naam" #: ../gtk/friendlist.c:721 msgid "Call" -msgstr "" +msgstr "Bellen" #: ../gtk/friendlist.c:726 msgid "Chat" -msgstr "" +msgstr "Chatten" #: ../gtk/friendlist.c:756 #, c-format msgid "Search in %s directory" -msgstr "" +msgstr "Zoeken in de map %s" #: ../gtk/friendlist.c:976 #, c-format msgid "Edit contact '%s'" -msgstr "" +msgstr "Contactpersoon '%s' bewerken" #: ../gtk/friendlist.c:977 #, c-format msgid "Delete contact '%s'" -msgstr "" +msgstr "Contactpersoon '%s' verwijderen" #: ../gtk/friendlist.c:978 #, c-format msgid "Delete chat history of '%s'" -msgstr "" +msgstr "Chatgeschiedenis van '%s' verwijderen" #: ../gtk/friendlist.c:1029 #, c-format msgid "Add new contact from %s directory" -msgstr "" +msgstr "Nieuw contactpersoon toevoegen vanuit de map %s" #: ../gtk/propertybox.c:558 msgid "Rate (Hz)" @@ -268,19 +283,19 @@ msgstr "Status" #: ../gtk/propertybox.c:570 msgid "IP Bitrate (kbit/s)" -msgstr "" +msgstr "IP-bitrate (kbit/s)" #: ../gtk/propertybox.c:577 msgid "Parameters" -msgstr "Parameters" +msgstr "Argumenten" #: ../gtk/propertybox.c:620 ../gtk/propertybox.c:763 msgid "Enabled" -msgstr "Aan" +msgstr "Ingeschakeld" #: ../gtk/propertybox.c:622 ../gtk/propertybox.c:763 ../gtk/parameters.ui.h:20 msgid "Disabled" -msgstr "Uit" +msgstr "Uitgeschakeld" #: ../gtk/propertybox.c:809 msgid "Account" @@ -288,80 +303,81 @@ msgstr "Account" #: ../gtk/propertybox.c:1072 msgid "English" -msgstr "" +msgstr "Engels" #: ../gtk/propertybox.c:1073 msgid "French" -msgstr "" +msgstr "Frans" #: ../gtk/propertybox.c:1074 msgid "Swedish" -msgstr "" +msgstr "Zweeds" #: ../gtk/propertybox.c:1075 msgid "Italian" -msgstr "" +msgstr "Italiaans" #: ../gtk/propertybox.c:1076 msgid "Spanish" -msgstr "" +msgstr "Spaans" #: ../gtk/propertybox.c:1077 msgid "Brazilian Portugese" -msgstr "" +msgstr "Braziliaans Portugees" #: ../gtk/propertybox.c:1078 msgid "Polish" -msgstr "" +msgstr "Pools" #: ../gtk/propertybox.c:1079 msgid "German" -msgstr "" +msgstr "Duits" #: ../gtk/propertybox.c:1080 msgid "Russian" -msgstr "" +msgstr "Russisch" #: ../gtk/propertybox.c:1081 msgid "Japanese" -msgstr "" +msgstr "Japans" #: ../gtk/propertybox.c:1082 msgid "Dutch" -msgstr "" +msgstr "Nederlands" #: ../gtk/propertybox.c:1083 msgid "Hungarian" -msgstr "" +msgstr "Hongaars" #: ../gtk/propertybox.c:1084 msgid "Czech" -msgstr "" +msgstr "Tjechisch" #: ../gtk/propertybox.c:1085 msgid "Chinese" -msgstr "" +msgstr "Chinees" #: ../gtk/propertybox.c:1086 msgid "Traditional Chinese" -msgstr "" +msgstr "Traditioneel Chinees" #: ../gtk/propertybox.c:1087 msgid "Norwegian" -msgstr "" +msgstr "Noors" #: ../gtk/propertybox.c:1088 msgid "Hebrew" -msgstr "" +msgstr "Hebreeuws" #: ../gtk/propertybox.c:1089 msgid "Serbian" -msgstr "" +msgstr "Servisch" #: ../gtk/propertybox.c:1156 msgid "" "You need to restart linphone for the new language selection to take effect." msgstr "" +"U moet linphone herstarten om de nieuw geselecteerde taal toe te passen." #: ../gtk/propertybox.c:1236 msgid "None" @@ -369,15 +385,15 @@ msgstr "Geen" #: ../gtk/propertybox.c:1240 msgid "SRTP" -msgstr "" +msgstr "SRTP" #: ../gtk/propertybox.c:1246 msgid "DTLS" -msgstr "" +msgstr "DTLS" #: ../gtk/propertybox.c:1253 msgid "ZRTP" -msgstr "" +msgstr "ZRTP" #: ../gtk/update.c:80 #, c-format @@ -385,125 +401,133 @@ msgid "" "A more recent version is availalble from %s.\n" "Would you like to open a browser to download it ?" msgstr "" +"Er is een nieuwere versie beschikbaar op %s.\n" +"Wilt een webbrowser openen en deze downloaden?" #: ../gtk/update.c:91 msgid "You are running the lastest version." -msgstr "" +msgstr "U gebruikt de nieuwste versie." #: ../gtk/buddylookup.c:85 msgid "Firstname, Lastname" -msgstr "" +msgstr "Voornaam, Achternaam" #: ../gtk/buddylookup.c:160 msgid "Error communicating with server." -msgstr "" +msgstr "Er is een fout opgetreden tijdens het communiceren met de server." #: ../gtk/buddylookup.c:164 msgid "Connecting..." -msgstr "" +msgstr "Bezig met verbinden..." #: ../gtk/buddylookup.c:168 msgid "Connected" -msgstr "" +msgstr "Verbonden" #: ../gtk/buddylookup.c:172 msgid "Receiving data..." -msgstr "" +msgstr "Bezig met ontvangen van gegevens..." #: ../gtk/buddylookup.c:180 #, c-format msgid "Found %i contact" msgid_plural "Found %i contacts" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%i contactpersoon gevonden" +msgstr[1] "%i contactpersonen gevonden" #: ../gtk/setupwizard.c:34 msgid "" "Welcome!\n" "This assistant will help you to use a SIP account for your calls." msgstr "" +"Welkom!\n" +"Deze instelwizard zal u begeleiden bij het gebruiken van een SIP-account " +"voor oproepen." #: ../gtk/setupwizard.c:43 msgid "Create an account on linphone.org" -msgstr "" +msgstr "Creëer een account op linphone.org" #: ../gtk/setupwizard.c:44 msgid "I have already a linphone.org account and I just want to use it" -msgstr "" +msgstr "Ik heb al een linphone.org-account en wil deze graag gebruiken" #: ../gtk/setupwizard.c:45 msgid "I have already a sip account and I just want to use it" -msgstr "" +msgstr "Ik heb al een SIP-account en wil deze graag gebruiken" #: ../gtk/setupwizard.c:46 msgid "I want to specify a remote configuration URI" -msgstr "" +msgstr "Ik wil een externe URI-configuratie opgeven" #: ../gtk/setupwizard.c:89 msgid "Enter your linphone.org username" -msgstr "" +msgstr "Vul uw linphone.org-gebruikersnaam in" #: ../gtk/setupwizard.c:102 ../gtk/parameters.ui.h:82 ../gtk/ldap.ui.h:4 msgid "Username:" -msgstr "" +msgstr "Gebruikersnaam:" #: ../gtk/setupwizard.c:104 ../gtk/password.ui.h:4 ../gtk/ldap.ui.h:5 msgid "Password:" -msgstr "" +msgstr "Wachtwoord:" #: ../gtk/setupwizard.c:124 msgid "Enter your account informations" -msgstr "" +msgstr "Vul uw accountinformatie in" #: ../gtk/setupwizard.c:140 msgid "Username*" -msgstr "" +msgstr "Gebruikersnaam*" #: ../gtk/setupwizard.c:141 msgid "Password*" -msgstr "" +msgstr "Wachtwoord*" #: ../gtk/setupwizard.c:144 msgid "Domain*" -msgstr "" +msgstr "Domeinnaam*" #: ../gtk/setupwizard.c:145 msgid "Proxy" -msgstr "" +msgstr "Proxy" #: ../gtk/setupwizard.c:317 msgid "(*) Required fields" -msgstr "" +msgstr "(*) Verplichte velden" #: ../gtk/setupwizard.c:318 msgid "Username: (*)" -msgstr "" +msgstr "Gebruikersnaam: (*)" #: ../gtk/setupwizard.c:320 msgid "Password: (*)" -msgstr "" +msgstr "Wachtwoord: (*)" #: ../gtk/setupwizard.c:322 msgid "Email: (*)" -msgstr "" +msgstr "E-mailadres: (*)" #: ../gtk/setupwizard.c:324 msgid "Confirm your password: (*)" -msgstr "" +msgstr "Bevestig uw wachtwoord: (*)" #: ../gtk/setupwizard.c:338 msgid "Keep me informed with linphone updates" -msgstr "" +msgstr "Houdt me op de hoogte van linphone-updates" #: ../gtk/setupwizard.c:394 msgid "" "Error, account not validated, username already used or server unreachable.\n" "Please go back and try again." msgstr "" +"Er is een fout opgetreden: uw account is niet gevalideerd, de gebruikersnaam " +"wordt al door iemand anders gebruikt of de server is onbereikbaar.\n" +"Ga terug en probeer het opnieuw." #: ../gtk/setupwizard.c:405 msgid "Thank you. Your account is now configured and ready for use." -msgstr "" +msgstr "Bedankt. Uw account is nu ingesteld en klaar voor gebruik." #: ../gtk/setupwizard.c:413 msgid "" @@ -511,104 +535,107 @@ msgid "" "email.\n" "Then come back here and press Next button." msgstr "" +"Valideer uw account door te klikken op de link die we zojuist naar uw e-" +"mailadres hebben verstuurd.\n" +"Kom dan terug naar dit venster en klik op de knop Volgende." #: ../gtk/setupwizard.c:602 msgid "SIP account configuration assistant" -msgstr "" +msgstr "SIP-account-instelwizard" #: ../gtk/setupwizard.c:620 msgid "Welcome to the account setup assistant" -msgstr "" +msgstr "Welkom bij de account-instelwizard" #: ../gtk/setupwizard.c:625 msgid "Account setup assistant" -msgstr "" +msgstr "Account-instelwizard" #: ../gtk/setupwizard.c:631 msgid "Configure your account (step 1/1)" -msgstr "" +msgstr "Uw account instellen (stap 1/1)" #: ../gtk/setupwizard.c:636 msgid "Enter your sip username (step 1/1)" -msgstr "" +msgstr "Vul uw SIP-gebruikersnaam in (stap 1/1)" #: ../gtk/setupwizard.c:640 msgid "Enter account information (step 1/2)" -msgstr "" +msgstr "Vul uw accountinformatie in (stap 1/2)" #: ../gtk/setupwizard.c:649 msgid "Validation (step 2/2)" -msgstr "" +msgstr "Geldigheid (stap 2/2)" #: ../gtk/setupwizard.c:654 msgid "Error" -msgstr "" +msgstr "Fout" #: ../gtk/setupwizard.c:658 ../gtk/audio_assistant.c:534 msgid "Terminating" -msgstr "" +msgstr "Bezig met vernietigen" #: ../gtk/incall_view.c:70 ../gtk/incall_view.c:94 #, c-format msgid "Call #%i" -msgstr "" +msgstr "#%i bellen" #: ../gtk/incall_view.c:155 #, c-format msgid "Transfer to call #%i with %s" -msgstr "" +msgstr "Overschakelen naar gesprek #%i met %s" #: ../gtk/incall_view.c:211 ../gtk/incall_view.c:214 msgid "Not used" -msgstr "" +msgstr "Niet in gebruik" #: ../gtk/incall_view.c:221 msgid "ICE not activated" -msgstr "" +msgstr "ICE is niet geactiveerd" #: ../gtk/incall_view.c:223 msgid "ICE failed" -msgstr "" +msgstr "ICE is mislukt" #: ../gtk/incall_view.c:225 msgid "ICE in progress" -msgstr "" +msgstr "ICE is bezig" #: ../gtk/incall_view.c:227 msgid "Going through one or more NATs" -msgstr "" +msgstr "Die door één of meer NATs gaan" #: ../gtk/incall_view.c:229 msgid "Direct" -msgstr "" +msgstr "Direct" #: ../gtk/incall_view.c:231 msgid "Through a relay server" -msgstr "" +msgstr "Via een relay-server" #: ../gtk/incall_view.c:239 msgid "uPnP not activated" -msgstr "" +msgstr "uPnP is niet geactiveerd" #: ../gtk/incall_view.c:241 msgid "uPnP in progress" -msgstr "" +msgstr "uPnP is bezig" #: ../gtk/incall_view.c:243 msgid "uPnp not available" -msgstr "" +msgstr "uPnP is niet beschikbaar" #: ../gtk/incall_view.c:245 msgid "uPnP is running" -msgstr "" +msgstr "uPnP wordt uitgevoerd" #: ../gtk/incall_view.c:247 msgid "uPnP failed" -msgstr "" +msgstr "uPnP is mislukt" #: ../gtk/incall_view.c:257 ../gtk/incall_view.c:258 msgid "Direct or through server" -msgstr "" +msgstr "Direct of via een server" #: ../gtk/incall_view.c:267 ../gtk/incall_view.c:279 #, c-format @@ -616,225 +643,230 @@ msgid "" "download: %f\n" "upload: %f (kbit/s)" msgstr "" +"download: %f\n" +"upload: %f (kbit/s)" #: ../gtk/incall_view.c:272 ../gtk/incall_view.c:274 #, c-format msgid "%ix%i @ %f fps" -msgstr "" +msgstr "%ix%i @ %f fps" #: ../gtk/incall_view.c:304 #, c-format msgid "%.3f seconds" -msgstr "" +msgstr "%.3f seconden" #: ../gtk/incall_view.c:407 ../gtk/main.ui.h:12 ../gtk/videowindow.c:235 msgid "Hang up" -msgstr "" +msgstr "Ophangen" #: ../gtk/incall_view.c:511 msgid "Calling..." -msgstr "" +msgstr "Bezig met bellen..." #: ../gtk/incall_view.c:514 ../gtk/incall_view.c:733 msgid "00::00::00" -msgstr "" +msgstr "00::00::00" #: ../gtk/incall_view.c:525 msgid "Incoming call" -msgstr "" +msgstr "Inkomende oproep" #: ../gtk/incall_view.c:562 msgid "good" -msgstr "" +msgstr "goed" #: ../gtk/incall_view.c:564 msgid "average" -msgstr "" +msgstr "gemiddeld" #: ../gtk/incall_view.c:566 msgid "poor" -msgstr "" +msgstr "slecht" #: ../gtk/incall_view.c:568 msgid "very poor" -msgstr "" +msgstr "erg slecht" #: ../gtk/incall_view.c:570 msgid "too bad" -msgstr "" +msgstr "verschrikkelijk" #: ../gtk/incall_view.c:571 ../gtk/incall_view.c:587 msgid "unavailable" -msgstr "" +msgstr "niet beschikbaar" #: ../gtk/incall_view.c:679 msgid "Secured by SRTP" -msgstr "" +msgstr "Beveiligd door SRTP" #: ../gtk/incall_view.c:685 msgid "Secured by DTLS" -msgstr "" +msgstr "Beveiligd door DTLS" #: ../gtk/incall_view.c:691 #, c-format msgid "Secured by ZRTP - [auth token: %s]" -msgstr "" +msgstr "Beveiligd door ZRTP - [authenticatiesleutel: %s]" #: ../gtk/incall_view.c:697 msgid "Set unverified" -msgstr "" +msgstr "Instellen als niet-geverifieerd" #: ../gtk/incall_view.c:697 ../gtk/main.ui.h:4 msgid "Set verified" -msgstr "" +msgstr "Instellen als geverifieerd" #: ../gtk/incall_view.c:728 msgid "In conference" -msgstr "" +msgstr "In een vergadering" #: ../gtk/incall_view.c:728 msgid "In call" -msgstr "" +msgstr "In gesprek" #: ../gtk/incall_view.c:764 msgid "Paused call" -msgstr "" +msgstr "Gepauzeerde oproep" #: ../gtk/incall_view.c:800 msgid "Call ended." -msgstr "" +msgstr "Oproep is beëindigd." #: ../gtk/incall_view.c:831 msgid "Transfer in progress" -msgstr "" +msgstr "De overdracht is bezig" #: ../gtk/incall_view.c:834 msgid "Transfer done." -msgstr "" +msgstr "De overdracht is voltooid." #: ../gtk/incall_view.c:837 msgid "Transfer failed." -msgstr "" +msgstr "De overdracht is mislukt." #: ../gtk/incall_view.c:881 msgid "Resume" -msgstr "" +msgstr "Hervatten" #: ../gtk/incall_view.c:888 ../gtk/main.ui.h:9 msgid "Pause" -msgstr "" +msgstr "Pauzeren" #: ../gtk/incall_view.c:954 #, c-format msgid "" "Recording into\n" "%s %s" -msgstr "" +msgstr "Bezig met opnemen naar%s %s" #: ../gtk/incall_view.c:954 msgid "(Paused)" -msgstr "" +msgstr "(Gepauzeerd)" -#: ../gtk/loginframe.c:88 +#: ../gtk/loginframe.c:87 #, c-format msgid "Please enter login information for %s" -msgstr "" +msgstr "Vul uw inloggegevens in voor %s" #: ../gtk/config-fetching.c:57 #, c-format msgid "fetching from %s" -msgstr "" +msgstr "bezig met ophalen van %s" #: ../gtk/config-fetching.c:73 #, c-format msgid "Downloading of remote configuration from %s failed." -msgstr "" +msgstr "Het downloaden van de externe configuratie van %s is mislukt." #: ../gtk/audio_assistant.c:98 msgid "No voice detected" -msgstr "" +msgstr "Er is geen stem gedetecteerd" #: ../gtk/audio_assistant.c:99 msgid "Too low" -msgstr "" +msgstr "Te zacht" #: ../gtk/audio_assistant.c:100 msgid "Good" -msgstr "" +msgstr "Goed" #: ../gtk/audio_assistant.c:101 msgid "Too loud" -msgstr "" +msgstr "Te hard" #: ../gtk/audio_assistant.c:183 msgid "Did you hear three beeps ?" -msgstr "" +msgstr "Heeft u drie pieptonen gehoord?" #: ../gtk/audio_assistant.c:292 ../gtk/audio_assistant.c:297 msgid "Sound preferences not found " -msgstr "" +msgstr "De geluidsvoorkeuren zijn niet gevonden" #: ../gtk/audio_assistant.c:306 msgid "Cannot launch system sound control " -msgstr "" +msgstr "Het systeemgeluidspaneel kon niet worden gestart" #: ../gtk/audio_assistant.c:318 msgid "" "Welcome!\n" "This assistant will help you to configure audio settings for Linphone" msgstr "" +"Welkom!\n" +"Deze instelwizard zal u begeleiden bij het instellen van de audio-" +"instellingen van Linphone" #: ../gtk/audio_assistant.c:328 msgid "Capture device" -msgstr "" +msgstr "Opname-apparaat" #: ../gtk/audio_assistant.c:329 msgid "Recorded volume" -msgstr "" +msgstr "Opgenomen volume" #: ../gtk/audio_assistant.c:333 msgid "No voice" -msgstr "" +msgstr "Geen stem" #: ../gtk/audio_assistant.c:334 ../gtk/audio_assistant.c:373 msgid "System sound preferences" -msgstr "" +msgstr "Systeemgeluidsinstellingen" #: ../gtk/audio_assistant.c:369 msgid "Playback device" -msgstr "" +msgstr "Afspeelapparaat" #: ../gtk/audio_assistant.c:370 msgid "Play three beeps" -msgstr "" +msgstr "Drie pieptonen afspelen" #: ../gtk/audio_assistant.c:403 msgid "Press the record button and say some words" -msgstr "" +msgstr "Klik op de opnameknop en zeg enkele woorden" #: ../gtk/audio_assistant.c:404 msgid "Listen to your record voice" -msgstr "" +msgstr "Luister naar uw opgenomen stem" #: ../gtk/audio_assistant.c:405 msgid "Record" -msgstr "" +msgstr "Opnemen" #: ../gtk/audio_assistant.c:406 msgid "Play" -msgstr "" +msgstr "Afspelen" #: ../gtk/audio_assistant.c:433 msgid "Let's start Linphone now" -msgstr "" +msgstr "Laten we nu Linphone opstarten" #: ../gtk/audio_assistant.c:503 msgid "Audio Assistant" -msgstr "" +msgstr "Audio-instelwizard" #: ../gtk/audio_assistant.c:513 ../gtk/main.ui.h:31 msgid "Audio assistant" -msgstr "" +msgstr "Audio-instelwizard" #: ../gtk/audio_assistant.c:518 msgid "Mic Gain calibration" @@ -846,43 +878,43 @@ msgstr "" #: ../gtk/audio_assistant.c:529 msgid "Record and Play" -msgstr "" +msgstr "Opnemen en afspelen" #: ../gtk/main.ui.h:1 msgid "Callee name" -msgstr "" +msgstr "Bellernaam" #: ../gtk/main.ui.h:2 msgid "Send" -msgstr "" +msgstr "Verzenden" #: ../gtk/main.ui.h:3 msgid "End conference" -msgstr "" +msgstr "Vergadering beëindigen" #: ../gtk/main.ui.h:7 msgid "Record this call to an audio file" -msgstr "" +msgstr "Deze oproep opnemen naar een audiobestand" #: ../gtk/main.ui.h:8 msgid "Video" -msgstr "" +msgstr "Video" #: ../gtk/main.ui.h:10 msgid "Mute" -msgstr "" +msgstr "Dempen" #: ../gtk/main.ui.h:11 msgid "Transfer" -msgstr "" +msgstr "Overdracht" #: ../gtk/main.ui.h:14 msgid "In call" -msgstr "" +msgstr "In gesprek" #: ../gtk/main.ui.h:15 msgid "Duration" -msgstr "" +msgstr "Duur" #: ../gtk/main.ui.h:16 msgid "Call quality rating" @@ -1488,7 +1520,7 @@ msgstr "" #: ../gtk/waiting.ui.h:1 msgid "Linphone" -msgstr "" +msgstr "Linphone" #: ../gtk/waiting.ui.h:2 msgid "Please wait" @@ -1692,60 +1724,60 @@ msgstr "" msgid "Please wait while fetching configuration from server..." msgstr "" -#: ../coreapi/linphonecore.c:1508 +#: ../coreapi/linphonecore.c:1512 msgid "Ready" msgstr "Gereed." -#: ../coreapi/linphonecore.c:2495 +#: ../coreapi/linphonecore.c:2499 msgid "Configuring" msgstr "" -#: ../coreapi/linphonecore.c:2669 +#: ../coreapi/linphonecore.c:2673 msgid "Looking for telephone number destination..." msgstr "Zoekt de lokatie van het telefoonnummer..." -#: ../coreapi/linphonecore.c:2671 +#: ../coreapi/linphonecore.c:2675 msgid "Could not resolve this number." msgstr "Kon dit nummer niet vinden." #. must be known at that time -#: ../coreapi/linphonecore.c:2957 +#: ../coreapi/linphonecore.c:2961 msgid "Contacting" msgstr "Verbinden" -#: ../coreapi/linphonecore.c:2962 +#: ../coreapi/linphonecore.c:2966 msgid "Could not call" msgstr "" -#: ../coreapi/linphonecore.c:3112 +#: ../coreapi/linphonecore.c:3116 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "" -#: ../coreapi/linphonecore.c:3270 +#: ../coreapi/linphonecore.c:3274 msgid "is contacting you" msgstr "" -#: ../coreapi/linphonecore.c:3271 +#: ../coreapi/linphonecore.c:3275 msgid " and asked autoanswer." msgstr "" -#: ../coreapi/linphonecore.c:3395 +#: ../coreapi/linphonecore.c:3399 msgid "Modifying call parameters..." msgstr "" -#: ../coreapi/linphonecore.c:3743 +#: ../coreapi/linphonecore.c:3747 msgid "Connected." msgstr "Verbonden." -#: ../coreapi/linphonecore.c:3768 +#: ../coreapi/linphonecore.c:3772 msgid "Call aborted" msgstr "" -#: ../coreapi/linphonecore.c:3958 +#: ../coreapi/linphonecore.c:3962 msgid "Could not pause the call" msgstr "" -#: ../coreapi/linphonecore.c:3961 +#: ../coreapi/linphonecore.c:3965 msgid "Pausing the current call..." msgstr "" @@ -1826,112 +1858,112 @@ msgstr "" msgid "Could not login as %s" msgstr "" -#: ../coreapi/callbacks.c:404 +#: ../coreapi/callbacks.c:419 msgid "Remote ringing." msgstr "" -#: ../coreapi/callbacks.c:425 +#: ../coreapi/callbacks.c:431 msgid "Remote ringing..." msgstr "" -#: ../coreapi/callbacks.c:442 +#: ../coreapi/callbacks.c:448 msgid "Early media." msgstr "" -#: ../coreapi/callbacks.c:503 +#: ../coreapi/callbacks.c:521 #, c-format msgid "Call with %s is paused." msgstr "" -#: ../coreapi/callbacks.c:516 +#: ../coreapi/callbacks.c:534 #, c-format msgid "Call answered by %s - on hold." msgstr "" -#: ../coreapi/callbacks.c:526 +#: ../coreapi/callbacks.c:544 msgid "Call resumed." msgstr "" -#: ../coreapi/callbacks.c:530 +#: ../coreapi/callbacks.c:548 #, c-format msgid "Call answered by %s." msgstr "" -#: ../coreapi/callbacks.c:553 +#: ../coreapi/callbacks.c:571 msgid "Incompatible, check codecs or security settings..." msgstr "" -#: ../coreapi/callbacks.c:558 ../coreapi/callbacks.c:870 +#: ../coreapi/callbacks.c:576 ../coreapi/callbacks.c:888 msgid "Incompatible media parameters." msgstr "" -#: ../coreapi/callbacks.c:588 +#: ../coreapi/callbacks.c:606 msgid "We have been resumed." msgstr "" #. we are being paused -#: ../coreapi/callbacks.c:596 +#: ../coreapi/callbacks.c:614 msgid "We are paused by other party." msgstr "" #. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:630 +#: ../coreapi/callbacks.c:648 msgid "Call is updated by remote." msgstr "" -#: ../coreapi/callbacks.c:746 +#: ../coreapi/callbacks.c:764 msgid "Call terminated." msgstr "Oproep beeindigd." -#: ../coreapi/callbacks.c:774 +#: ../coreapi/callbacks.c:792 msgid "User is busy." msgstr "Gebruiker is bezet." -#: ../coreapi/callbacks.c:775 +#: ../coreapi/callbacks.c:793 msgid "User is temporarily unavailable." msgstr "Gebruiker is tijdelijk niet beschikbaar." #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:777 +#: ../coreapi/callbacks.c:795 msgid "User does not want to be disturbed." msgstr "De gebruiker wenst niet gestoord te worden." -#: ../coreapi/callbacks.c:778 +#: ../coreapi/callbacks.c:796 msgid "Call declined." msgstr "Oproep geweigerd." -#: ../coreapi/callbacks.c:793 +#: ../coreapi/callbacks.c:811 msgid "Request timeout." msgstr "" -#: ../coreapi/callbacks.c:824 +#: ../coreapi/callbacks.c:842 msgid "Redirected" msgstr "" -#: ../coreapi/callbacks.c:879 +#: ../coreapi/callbacks.c:897 msgid "Call failed." msgstr "" -#: ../coreapi/callbacks.c:957 +#: ../coreapi/callbacks.c:975 #, c-format msgid "Registration on %s successful." msgstr "Registratie op %s gelukt." -#: ../coreapi/callbacks.c:958 +#: ../coreapi/callbacks.c:976 #, c-format msgid "Unregistration on %s done." msgstr "" -#: ../coreapi/callbacks.c:976 +#: ../coreapi/callbacks.c:994 msgid "no response timeout" msgstr "" -#: ../coreapi/callbacks.c:979 +#: ../coreapi/callbacks.c:997 #, c-format msgid "Registration on %s failed: %s" msgstr "" -#: ../coreapi/callbacks.c:986 +#: ../coreapi/callbacks.c:1004 msgid "Service unavailable, retrying" msgstr "" @@ -1941,7 +1973,7 @@ msgstr "" msgid "Authentication token is %s" msgstr "" -#: ../coreapi/linphonecall.c:3492 +#: ../coreapi/linphonecall.c:3600 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." diff --git a/po/pl.po b/po/pl.po index 595a29b8d..40787491c 100644 --- a/po/pl.po +++ b/po/pl.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-02-17 12:28+0100\n" +"POT-Creation-Date: 2015-03-11 16:26+0100\n" "PO-Revision-Date: 2015-02-17 11:28+0000\n" "Last-Translator: Belledonne Communications \n" @@ -92,53 +92,53 @@ msgstr "" msgid "Couldn't find pixmap file: %s" msgstr "Nie można znaleźć pixmapy: %s" -#: ../gtk/chat.c:367 ../gtk/friendlist.c:924 +#: ../gtk/chat.c:374 ../gtk/friendlist.c:924 msgid "Invalid sip contact !" msgstr "" -#: ../gtk/main.c:109 +#: ../gtk/main.c:137 msgid "log to stdout some debug information while running." msgstr "" -#: ../gtk/main.c:116 +#: ../gtk/main.c:138 msgid "path to a file to write logs into." msgstr "" -#: ../gtk/main.c:123 +#: ../gtk/main.c:139 msgid "Start linphone with video disabled." msgstr "" -#: ../gtk/main.c:130 +#: ../gtk/main.c:140 msgid "Start only in the system tray, do not show the main interface." msgstr "" -#: ../gtk/main.c:137 +#: ../gtk/main.c:141 msgid "address to call right now" msgstr "" -#: ../gtk/main.c:144 +#: ../gtk/main.c:142 msgid "if set automatically answer incoming calls" msgstr "" -#: ../gtk/main.c:151 +#: ../gtk/main.c:143 msgid "" "Specifiy a working directory (should be the base of the installation, eg: c:" "\\Program Files\\Linphone)" msgstr "" -#: ../gtk/main.c:158 +#: ../gtk/main.c:144 msgid "Configuration file" msgstr "" -#: ../gtk/main.c:165 +#: ../gtk/main.c:145 msgid "Run the audio assistant" msgstr "" -#: ../gtk/main.c:172 +#: ../gtk/main.c:146 msgid "Run self test and exit 0 if succeed" msgstr "" -#: ../gtk/main.c:1088 +#: ../gtk/main.c:1061 #, c-format msgid "" "%s would like to add you to his contact list.\n" @@ -147,72 +147,72 @@ msgid "" "If you answer no, this person will be temporarily blacklisted." msgstr "" -#: ../gtk/main.c:1165 +#: ../gtk/main.c:1138 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" msgstr "" -#: ../gtk/main.c:1286 +#: ../gtk/main.c:1259 msgid "Call error" msgstr "" -#: ../gtk/main.c:1289 ../coreapi/linphonecore.c:3787 +#: ../gtk/main.c:1262 ../coreapi/linphonecore.c:3791 msgid "Call ended" msgstr "" -#: ../gtk/main.c:1292 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1265 ../coreapi/call_log.c:221 msgid "Incoming call" msgstr "" -#: ../gtk/main.c:1294 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1267 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 msgid "Answer" msgstr "" -#: ../gtk/main.c:1296 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1269 ../gtk/main.ui.h:6 msgid "Decline" msgstr "" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 msgid "Call paused" msgstr "" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 #, c-format msgid "by %s" msgstr "" -#: ../gtk/main.c:1372 +#: ../gtk/main.c:1345 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "" -#: ../gtk/main.c:1534 +#: ../gtk/main.c:1507 msgid "Website link" msgstr "" -#: ../gtk/main.c:1583 +#: ../gtk/main.c:1556 msgid "Linphone - a video internet phone" msgstr "" -#: ../gtk/main.c:1675 +#: ../gtk/main.c:1648 #, c-format msgid "%s (Default)" msgstr "" -#: ../gtk/main.c:2007 ../coreapi/callbacks.c:1027 +#: ../gtk/main.c:1980 ../coreapi/callbacks.c:1045 #, c-format msgid "We are transferred to %s" msgstr "" -#: ../gtk/main.c:2017 +#: ../gtk/main.c:1990 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." msgstr "" -#: ../gtk/main.c:2161 +#: ../gtk/main.c:2135 msgid "A free SIP video-phone" msgstr "" @@ -739,7 +739,7 @@ msgstr "" msgid "(Paused)" msgstr "" -#: ../gtk/loginframe.c:88 +#: ../gtk/loginframe.c:87 #, c-format msgid "Please enter login information for %s" msgstr "" @@ -1696,60 +1696,60 @@ msgstr "" msgid "Please wait while fetching configuration from server..." msgstr "" -#: ../coreapi/linphonecore.c:1508 +#: ../coreapi/linphonecore.c:1512 msgid "Ready" msgstr "" -#: ../coreapi/linphonecore.c:2495 +#: ../coreapi/linphonecore.c:2499 msgid "Configuring" msgstr "" -#: ../coreapi/linphonecore.c:2669 +#: ../coreapi/linphonecore.c:2673 msgid "Looking for telephone number destination..." msgstr "" -#: ../coreapi/linphonecore.c:2671 +#: ../coreapi/linphonecore.c:2675 msgid "Could not resolve this number." msgstr "" #. must be known at that time -#: ../coreapi/linphonecore.c:2957 +#: ../coreapi/linphonecore.c:2961 msgid "Contacting" msgstr "" -#: ../coreapi/linphonecore.c:2962 +#: ../coreapi/linphonecore.c:2966 msgid "Could not call" msgstr "" -#: ../coreapi/linphonecore.c:3112 +#: ../coreapi/linphonecore.c:3116 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "" -#: ../coreapi/linphonecore.c:3270 +#: ../coreapi/linphonecore.c:3274 msgid "is contacting you" msgstr "" -#: ../coreapi/linphonecore.c:3271 +#: ../coreapi/linphonecore.c:3275 msgid " and asked autoanswer." msgstr "" -#: ../coreapi/linphonecore.c:3395 +#: ../coreapi/linphonecore.c:3399 msgid "Modifying call parameters..." msgstr "" -#: ../coreapi/linphonecore.c:3743 +#: ../coreapi/linphonecore.c:3747 msgid "Connected." msgstr "Połączony" -#: ../coreapi/linphonecore.c:3768 +#: ../coreapi/linphonecore.c:3772 msgid "Call aborted" msgstr "" -#: ../coreapi/linphonecore.c:3958 +#: ../coreapi/linphonecore.c:3962 msgid "Could not pause the call" msgstr "" -#: ../coreapi/linphonecore.c:3961 +#: ../coreapi/linphonecore.c:3965 msgid "Pausing the current call..." msgstr "" @@ -1830,112 +1830,112 @@ msgstr "" msgid "Could not login as %s" msgstr "" -#: ../coreapi/callbacks.c:404 +#: ../coreapi/callbacks.c:419 msgid "Remote ringing." msgstr "" -#: ../coreapi/callbacks.c:425 +#: ../coreapi/callbacks.c:431 msgid "Remote ringing..." msgstr "" -#: ../coreapi/callbacks.c:442 +#: ../coreapi/callbacks.c:448 msgid "Early media." msgstr "" -#: ../coreapi/callbacks.c:503 +#: ../coreapi/callbacks.c:521 #, c-format msgid "Call with %s is paused." msgstr "" -#: ../coreapi/callbacks.c:516 +#: ../coreapi/callbacks.c:534 #, c-format msgid "Call answered by %s - on hold." msgstr "" -#: ../coreapi/callbacks.c:526 +#: ../coreapi/callbacks.c:544 msgid "Call resumed." msgstr "" -#: ../coreapi/callbacks.c:530 +#: ../coreapi/callbacks.c:548 #, c-format msgid "Call answered by %s." msgstr "" -#: ../coreapi/callbacks.c:553 +#: ../coreapi/callbacks.c:571 msgid "Incompatible, check codecs or security settings..." msgstr "" -#: ../coreapi/callbacks.c:558 ../coreapi/callbacks.c:870 +#: ../coreapi/callbacks.c:576 ../coreapi/callbacks.c:888 msgid "Incompatible media parameters." msgstr "" -#: ../coreapi/callbacks.c:588 +#: ../coreapi/callbacks.c:606 msgid "We have been resumed." msgstr "" #. we are being paused -#: ../coreapi/callbacks.c:596 +#: ../coreapi/callbacks.c:614 msgid "We are paused by other party." msgstr "" #. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:630 +#: ../coreapi/callbacks.c:648 msgid "Call is updated by remote." msgstr "" -#: ../coreapi/callbacks.c:746 +#: ../coreapi/callbacks.c:764 msgid "Call terminated." msgstr "" -#: ../coreapi/callbacks.c:774 +#: ../coreapi/callbacks.c:792 msgid "User is busy." msgstr "Osoba jest zajęta." -#: ../coreapi/callbacks.c:775 +#: ../coreapi/callbacks.c:793 msgid "User is temporarily unavailable." msgstr "Osoba jest tymczasowo niedostępna." #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:777 +#: ../coreapi/callbacks.c:795 msgid "User does not want to be disturbed." msgstr "Osoba nie chce, aby jej przeszkadzać." -#: ../coreapi/callbacks.c:778 +#: ../coreapi/callbacks.c:796 msgid "Call declined." msgstr "Rozmowa odrzucona." -#: ../coreapi/callbacks.c:793 +#: ../coreapi/callbacks.c:811 msgid "Request timeout." msgstr "" -#: ../coreapi/callbacks.c:824 +#: ../coreapi/callbacks.c:842 msgid "Redirected" msgstr "" -#: ../coreapi/callbacks.c:879 +#: ../coreapi/callbacks.c:897 msgid "Call failed." msgstr "" -#: ../coreapi/callbacks.c:957 +#: ../coreapi/callbacks.c:975 #, c-format msgid "Registration on %s successful." msgstr "" -#: ../coreapi/callbacks.c:958 +#: ../coreapi/callbacks.c:976 #, c-format msgid "Unregistration on %s done." msgstr "" -#: ../coreapi/callbacks.c:976 +#: ../coreapi/callbacks.c:994 msgid "no response timeout" msgstr "" -#: ../coreapi/callbacks.c:979 +#: ../coreapi/callbacks.c:997 #, c-format msgid "Registration on %s failed: %s" msgstr "" -#: ../coreapi/callbacks.c:986 +#: ../coreapi/callbacks.c:1004 msgid "Service unavailable, retrying" msgstr "" @@ -1945,7 +1945,7 @@ msgstr "" msgid "Authentication token is %s" msgstr "" -#: ../coreapi/linphonecall.c:3492 +#: ../coreapi/linphonecall.c:3600 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." diff --git a/po/pt_BR.po b/po/pt_BR.po index 3c74b566d..77b5fc220 100644 --- a/po/pt_BR.po +++ b/po/pt_BR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-02-17 12:28+0100\n" +"POT-Creation-Date: 2015-03-11 16:26+0100\n" "PO-Revision-Date: 2015-02-17 11:28+0000\n" "Last-Translator: Belledonne Communications \n" @@ -89,53 +89,53 @@ msgstr "" msgid "Couldn't find pixmap file: %s" msgstr "Não é possível achar arquivo pixmap: %s" -#: ../gtk/chat.c:367 ../gtk/friendlist.c:924 +#: ../gtk/chat.c:374 ../gtk/friendlist.c:924 msgid "Invalid sip contact !" msgstr "" -#: ../gtk/main.c:109 +#: ../gtk/main.c:137 msgid "log to stdout some debug information while running." msgstr "" -#: ../gtk/main.c:116 +#: ../gtk/main.c:138 msgid "path to a file to write logs into." msgstr "" -#: ../gtk/main.c:123 +#: ../gtk/main.c:139 msgid "Start linphone with video disabled." msgstr "" -#: ../gtk/main.c:130 +#: ../gtk/main.c:140 msgid "Start only in the system tray, do not show the main interface." msgstr "" -#: ../gtk/main.c:137 +#: ../gtk/main.c:141 msgid "address to call right now" msgstr "" -#: ../gtk/main.c:144 +#: ../gtk/main.c:142 msgid "if set automatically answer incoming calls" msgstr "" -#: ../gtk/main.c:151 +#: ../gtk/main.c:143 msgid "" "Specifiy a working directory (should be the base of the installation, eg: c:" "\\Program Files\\Linphone)" msgstr "" -#: ../gtk/main.c:158 +#: ../gtk/main.c:144 msgid "Configuration file" msgstr "" -#: ../gtk/main.c:165 +#: ../gtk/main.c:145 msgid "Run the audio assistant" msgstr "" -#: ../gtk/main.c:172 +#: ../gtk/main.c:146 msgid "Run self test and exit 0 if succeed" msgstr "" -#: ../gtk/main.c:1088 +#: ../gtk/main.c:1061 #, c-format msgid "" "%s would like to add you to his contact list.\n" @@ -144,72 +144,72 @@ msgid "" "If you answer no, this person will be temporarily blacklisted." msgstr "" -#: ../gtk/main.c:1165 +#: ../gtk/main.c:1138 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" msgstr "" -#: ../gtk/main.c:1286 +#: ../gtk/main.c:1259 msgid "Call error" msgstr "" -#: ../gtk/main.c:1289 ../coreapi/linphonecore.c:3787 +#: ../gtk/main.c:1262 ../coreapi/linphonecore.c:3791 msgid "Call ended" msgstr "" -#: ../gtk/main.c:1292 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1265 ../coreapi/call_log.c:221 msgid "Incoming call" msgstr "Camadas recebidas" -#: ../gtk/main.c:1294 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1267 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 msgid "Answer" msgstr "" -#: ../gtk/main.c:1296 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1269 ../gtk/main.ui.h:6 msgid "Decline" msgstr "" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 msgid "Call paused" msgstr "" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 #, c-format msgid "by %s" msgstr "" -#: ../gtk/main.c:1372 +#: ../gtk/main.c:1345 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "" -#: ../gtk/main.c:1534 +#: ../gtk/main.c:1507 msgid "Website link" msgstr "" -#: ../gtk/main.c:1583 +#: ../gtk/main.c:1556 msgid "Linphone - a video internet phone" msgstr "" -#: ../gtk/main.c:1675 +#: ../gtk/main.c:1648 #, c-format msgid "%s (Default)" msgstr "" -#: ../gtk/main.c:2007 ../coreapi/callbacks.c:1027 +#: ../gtk/main.c:1980 ../coreapi/callbacks.c:1045 #, c-format msgid "We are transferred to %s" msgstr "" -#: ../gtk/main.c:2017 +#: ../gtk/main.c:1990 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." msgstr "" -#: ../gtk/main.c:2161 +#: ../gtk/main.c:2135 msgid "A free SIP video-phone" msgstr "" @@ -735,7 +735,7 @@ msgstr "" msgid "(Paused)" msgstr "" -#: ../gtk/loginframe.c:88 +#: ../gtk/loginframe.c:87 #, c-format msgid "Please enter login information for %s" msgstr "" @@ -1692,60 +1692,60 @@ msgstr "" msgid "Please wait while fetching configuration from server..." msgstr "" -#: ../coreapi/linphonecore.c:1508 +#: ../coreapi/linphonecore.c:1512 msgid "Ready" msgstr "" -#: ../coreapi/linphonecore.c:2495 +#: ../coreapi/linphonecore.c:2499 msgid "Configuring" msgstr "" -#: ../coreapi/linphonecore.c:2669 +#: ../coreapi/linphonecore.c:2673 msgid "Looking for telephone number destination..." msgstr "Procurando por telefone de destino..." -#: ../coreapi/linphonecore.c:2671 +#: ../coreapi/linphonecore.c:2675 msgid "Could not resolve this number." msgstr "Não foi possível encontrar este número." #. must be known at that time -#: ../coreapi/linphonecore.c:2957 +#: ../coreapi/linphonecore.c:2961 msgid "Contacting" msgstr "" -#: ../coreapi/linphonecore.c:2962 +#: ../coreapi/linphonecore.c:2966 msgid "Could not call" msgstr "" -#: ../coreapi/linphonecore.c:3112 +#: ../coreapi/linphonecore.c:3116 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "" -#: ../coreapi/linphonecore.c:3270 +#: ../coreapi/linphonecore.c:3274 msgid "is contacting you" msgstr "" -#: ../coreapi/linphonecore.c:3271 +#: ../coreapi/linphonecore.c:3275 msgid " and asked autoanswer." msgstr "" -#: ../coreapi/linphonecore.c:3395 +#: ../coreapi/linphonecore.c:3399 msgid "Modifying call parameters..." msgstr "" -#: ../coreapi/linphonecore.c:3743 +#: ../coreapi/linphonecore.c:3747 msgid "Connected." msgstr "Conectado." -#: ../coreapi/linphonecore.c:3768 +#: ../coreapi/linphonecore.c:3772 msgid "Call aborted" msgstr "" -#: ../coreapi/linphonecore.c:3958 +#: ../coreapi/linphonecore.c:3962 msgid "Could not pause the call" msgstr "" -#: ../coreapi/linphonecore.c:3961 +#: ../coreapi/linphonecore.c:3965 msgid "Pausing the current call..." msgstr "" @@ -1826,112 +1826,112 @@ msgstr "" msgid "Could not login as %s" msgstr "" -#: ../coreapi/callbacks.c:404 +#: ../coreapi/callbacks.c:419 msgid "Remote ringing." msgstr "" -#: ../coreapi/callbacks.c:425 +#: ../coreapi/callbacks.c:431 msgid "Remote ringing..." msgstr "" -#: ../coreapi/callbacks.c:442 +#: ../coreapi/callbacks.c:448 msgid "Early media." msgstr "" -#: ../coreapi/callbacks.c:503 +#: ../coreapi/callbacks.c:521 #, c-format msgid "Call with %s is paused." msgstr "" -#: ../coreapi/callbacks.c:516 +#: ../coreapi/callbacks.c:534 #, c-format msgid "Call answered by %s - on hold." msgstr "" -#: ../coreapi/callbacks.c:526 +#: ../coreapi/callbacks.c:544 msgid "Call resumed." msgstr "" -#: ../coreapi/callbacks.c:530 +#: ../coreapi/callbacks.c:548 #, c-format msgid "Call answered by %s." msgstr "" -#: ../coreapi/callbacks.c:553 +#: ../coreapi/callbacks.c:571 msgid "Incompatible, check codecs or security settings..." msgstr "" -#: ../coreapi/callbacks.c:558 ../coreapi/callbacks.c:870 +#: ../coreapi/callbacks.c:576 ../coreapi/callbacks.c:888 msgid "Incompatible media parameters." msgstr "" -#: ../coreapi/callbacks.c:588 +#: ../coreapi/callbacks.c:606 msgid "We have been resumed." msgstr "" #. we are being paused -#: ../coreapi/callbacks.c:596 +#: ../coreapi/callbacks.c:614 msgid "We are paused by other party." msgstr "" #. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:630 +#: ../coreapi/callbacks.c:648 msgid "Call is updated by remote." msgstr "" -#: ../coreapi/callbacks.c:746 +#: ../coreapi/callbacks.c:764 msgid "Call terminated." msgstr "" -#: ../coreapi/callbacks.c:774 +#: ../coreapi/callbacks.c:792 msgid "User is busy." msgstr "Usuário está ocupado." -#: ../coreapi/callbacks.c:775 +#: ../coreapi/callbacks.c:793 msgid "User is temporarily unavailable." msgstr "Usuário está temporáriamente indisponível." #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:777 +#: ../coreapi/callbacks.c:795 msgid "User does not want to be disturbed." msgstr "" -#: ../coreapi/callbacks.c:778 +#: ../coreapi/callbacks.c:796 msgid "Call declined." msgstr "" -#: ../coreapi/callbacks.c:793 +#: ../coreapi/callbacks.c:811 msgid "Request timeout." msgstr "" -#: ../coreapi/callbacks.c:824 +#: ../coreapi/callbacks.c:842 msgid "Redirected" msgstr "" -#: ../coreapi/callbacks.c:879 +#: ../coreapi/callbacks.c:897 msgid "Call failed." msgstr "" -#: ../coreapi/callbacks.c:957 +#: ../coreapi/callbacks.c:975 #, c-format msgid "Registration on %s successful." msgstr "" -#: ../coreapi/callbacks.c:958 +#: ../coreapi/callbacks.c:976 #, c-format msgid "Unregistration on %s done." msgstr "" -#: ../coreapi/callbacks.c:976 +#: ../coreapi/callbacks.c:994 msgid "no response timeout" msgstr "" -#: ../coreapi/callbacks.c:979 +#: ../coreapi/callbacks.c:997 #, c-format msgid "Registration on %s failed: %s" msgstr "" -#: ../coreapi/callbacks.c:986 +#: ../coreapi/callbacks.c:1004 msgid "Service unavailable, retrying" msgstr "" @@ -1941,7 +1941,7 @@ msgstr "" msgid "Authentication token is %s" msgstr "" -#: ../coreapi/linphonecall.c:3492 +#: ../coreapi/linphonecall.c:3600 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." diff --git a/po/ru.po b/po/ru.po index aeb106fc5..549b6e1ba 100644 --- a/po/ru.po +++ b/po/ru.po @@ -12,10 +12,9 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-02-17 12:28+0100\n" -"PO-Revision-Date: 2015-02-17 11:28+0000\n" -"Last-Translator: Belledonne Communications \n" +"POT-Creation-Date: 2015-03-11 16:26+0100\n" +"PO-Revision-Date: 2015-02-18 18:31+0000\n" +"Last-Translator: AlexL \n" "Language-Team: Russian (http://www.transifex.com/projects/p/linphone-gtk/" "language/ru/)\n" "Language: ru\n" @@ -99,37 +98,37 @@ msgstr "Мне" msgid "Couldn't find pixmap file: %s" msgstr "Невозможно найти графический файл: %s" -#: ../gtk/chat.c:367 ../gtk/friendlist.c:924 +#: ../gtk/chat.c:374 ../gtk/friendlist.c:924 msgid "Invalid sip contact !" msgstr "Неверный sip контакт!" -#: ../gtk/main.c:109 +#: ../gtk/main.c:137 msgid "log to stdout some debug information while running." msgstr "" "Вывод некоторой отладочной информации на устройство стандартного вывода во " "время работы." -#: ../gtk/main.c:116 +#: ../gtk/main.c:138 msgid "path to a file to write logs into." msgstr "Путь к файлу для записи логов." -#: ../gtk/main.c:123 +#: ../gtk/main.c:139 msgid "Start linphone with video disabled." msgstr "Запуск linphone с видео отключен." -#: ../gtk/main.c:130 +#: ../gtk/main.c:140 msgid "Start only in the system tray, do not show the main interface." msgstr "Показывать только в системном лотке, не запуская главное окно." -#: ../gtk/main.c:137 +#: ../gtk/main.c:141 msgid "address to call right now" msgstr "Адрес для звонка прямо сейчас." -#: ../gtk/main.c:144 +#: ../gtk/main.c:142 msgid "if set automatically answer incoming calls" msgstr "Если установлено, то автоматический приём входящих звонков." -#: ../gtk/main.c:151 +#: ../gtk/main.c:143 msgid "" "Specifiy a working directory (should be the base of the installation, eg: c:" "\\Program Files\\Linphone)" @@ -137,19 +136,19 @@ msgstr "" "Определить рабочий каталог (относительно каталога установки, например: c:" "\\Program Files\\Linphone)" -#: ../gtk/main.c:158 +#: ../gtk/main.c:144 msgid "Configuration file" msgstr "Файл конфигурации" -#: ../gtk/main.c:165 +#: ../gtk/main.c:145 msgid "Run the audio assistant" msgstr "Запустить помощника аудио" -#: ../gtk/main.c:172 +#: ../gtk/main.c:146 msgid "Run self test and exit 0 if succeed" msgstr "Запустить самотест и выйти при успехе со статусом 0" -#: ../gtk/main.c:1088 +#: ../gtk/main.c:1061 #, c-format msgid "" "%s would like to add you to his contact list.\n" @@ -162,7 +161,7 @@ msgstr "" "контактный лист?\n" "Если вы ответите Нет, эта персона будет временно в чёрном списке." -#: ../gtk/main.c:1165 +#: ../gtk/main.c:1138 #, c-format msgid "" "Please enter your password for username %s\n" @@ -171,59 +170,59 @@ msgstr "" "Пожалуйста, введите пароль для пользователя %s\n" " для реалм (рилм) %s:" -#: ../gtk/main.c:1286 +#: ../gtk/main.c:1259 msgid "Call error" msgstr "Ошибка звонка" -#: ../gtk/main.c:1289 ../coreapi/linphonecore.c:3787 +#: ../gtk/main.c:1262 ../coreapi/linphonecore.c:3791 msgid "Call ended" msgstr "Звонок окончен" -#: ../gtk/main.c:1292 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1265 ../coreapi/call_log.c:221 msgid "Incoming call" msgstr "Входящий звонок" -#: ../gtk/main.c:1294 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1267 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 msgid "Answer" msgstr "Ответ" -#: ../gtk/main.c:1296 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1269 ../gtk/main.ui.h:6 msgid "Decline" msgstr "Отклонить" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 msgid "Call paused" msgstr "Звонок приостановлен" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 #, c-format msgid "by %s" msgstr "%s" -#: ../gtk/main.c:1372 +#: ../gtk/main.c:1345 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "%s предложил запустить видео. Вы принимаете?" -#: ../gtk/main.c:1534 +#: ../gtk/main.c:1507 msgid "Website link" msgstr "Домашняя страница" -#: ../gtk/main.c:1583 +#: ../gtk/main.c:1556 msgid "Linphone - a video internet phone" msgstr "Linphone - интернет видео телефон" -#: ../gtk/main.c:1675 +#: ../gtk/main.c:1648 #, c-format msgid "%s (Default)" msgstr "%s (по умолчанию)" -#: ../gtk/main.c:2007 ../coreapi/callbacks.c:1027 +#: ../gtk/main.c:1980 ../coreapi/callbacks.c:1045 #, c-format msgid "We are transferred to %s" msgstr "Мы передали в %s" -#: ../gtk/main.c:2017 +#: ../gtk/main.c:1990 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." @@ -231,7 +230,7 @@ msgstr "" "Звуковые карты не были обнаружены на этом компьютере.\n" "Вы не сможете отправлять или получать аудио звонки." -#: ../gtk/main.c:2161 +#: ../gtk/main.c:2135 msgid "A free SIP video-phone" msgstr "Свободный SIP видео-телефон" @@ -397,7 +396,7 @@ msgstr "SRTP" #: ../gtk/propertybox.c:1246 msgid "DTLS" -msgstr "" +msgstr "DTLS" #: ../gtk/propertybox.c:1253 msgid "ZRTP" @@ -712,7 +711,7 @@ msgstr "Защищённые с помощью SRTP" #: ../gtk/incall_view.c:685 msgid "Secured by DTLS" -msgstr "" +msgstr "Защищённые с помощью DTLS" #: ../gtk/incall_view.c:691 #, c-format @@ -776,7 +775,7 @@ msgstr "" msgid "(Paused)" msgstr "(Пауза)" -#: ../gtk/loginframe.c:88 +#: ../gtk/loginframe.c:87 #, c-format msgid "Please enter login information for %s" msgstr "Пожалуйста, введите информацию для входа %s:" @@ -1756,61 +1755,61 @@ msgstr "Конфигурирование..." msgid "Please wait while fetching configuration from server..." msgstr "Пожалуйста, подождите пока получается конфигурация с сервера..." -#: ../coreapi/linphonecore.c:1508 +#: ../coreapi/linphonecore.c:1512 msgid "Ready" msgstr "Готов" -#: ../coreapi/linphonecore.c:2495 +#: ../coreapi/linphonecore.c:2499 msgid "Configuring" msgstr "Конфигурирование" -#: ../coreapi/linphonecore.c:2669 +#: ../coreapi/linphonecore.c:2673 msgid "Looking for telephone number destination..." msgstr "Поиск назначения для телефонного номера.." -#: ../coreapi/linphonecore.c:2671 +#: ../coreapi/linphonecore.c:2675 msgid "Could not resolve this number." msgstr "Не получилось принять решение по этому номеру." #. must be known at that time -#: ../coreapi/linphonecore.c:2957 +#: ../coreapi/linphonecore.c:2961 msgid "Contacting" msgstr "Соединение" -#: ../coreapi/linphonecore.c:2962 +#: ../coreapi/linphonecore.c:2966 msgid "Could not call" msgstr "Невозможно позвонить" -#: ../coreapi/linphonecore.c:3112 +#: ../coreapi/linphonecore.c:3116 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "" "К сожалению, мы достигли максимального количества одновременных звонков" -#: ../coreapi/linphonecore.c:3270 +#: ../coreapi/linphonecore.c:3274 msgid "is contacting you" msgstr "контактирует с вами" -#: ../coreapi/linphonecore.c:3271 +#: ../coreapi/linphonecore.c:3275 msgid " and asked autoanswer." msgstr "и спросил автоматический ответ." -#: ../coreapi/linphonecore.c:3395 +#: ../coreapi/linphonecore.c:3399 msgid "Modifying call parameters..." msgstr "Изменение параметров звонка..." -#: ../coreapi/linphonecore.c:3743 +#: ../coreapi/linphonecore.c:3747 msgid "Connected." msgstr "Соединён." -#: ../coreapi/linphonecore.c:3768 +#: ../coreapi/linphonecore.c:3772 msgid "Call aborted" msgstr "Звонок отменён" -#: ../coreapi/linphonecore.c:3958 +#: ../coreapi/linphonecore.c:3962 msgid "Could not pause the call" msgstr "Невозможно приостановить звонок" -#: ../coreapi/linphonecore.c:3961 +#: ../coreapi/linphonecore.c:3965 msgid "Pausing the current call..." msgstr "Приостановка текущего звонка..." @@ -1896,112 +1895,112 @@ msgstr "" msgid "Could not login as %s" msgstr "Невозможно зайти как: %s" -#: ../coreapi/callbacks.c:404 +#: ../coreapi/callbacks.c:419 msgid "Remote ringing." msgstr "Дистанционный звонок." -#: ../coreapi/callbacks.c:425 +#: ../coreapi/callbacks.c:431 msgid "Remote ringing..." msgstr "Дистанционный звонок..." -#: ../coreapi/callbacks.c:442 +#: ../coreapi/callbacks.c:448 msgid "Early media." msgstr "Предответное проключение." -#: ../coreapi/callbacks.c:503 +#: ../coreapi/callbacks.c:521 #, c-format msgid "Call with %s is paused." msgstr "Звонок с %s приостановлен." -#: ../coreapi/callbacks.c:516 +#: ../coreapi/callbacks.c:534 #, c-format msgid "Call answered by %s - on hold." msgstr "На звонок ответил %s - на удержании." -#: ../coreapi/callbacks.c:526 +#: ../coreapi/callbacks.c:544 msgid "Call resumed." msgstr "Звонок возобновлён." -#: ../coreapi/callbacks.c:530 +#: ../coreapi/callbacks.c:548 #, c-format msgid "Call answered by %s." msgstr "На звонок ответил %s." -#: ../coreapi/callbacks.c:553 +#: ../coreapi/callbacks.c:571 msgid "Incompatible, check codecs or security settings..." msgstr "Несовместимость, проверьте кодеки или параметры безопасности..." -#: ../coreapi/callbacks.c:558 ../coreapi/callbacks.c:870 +#: ../coreapi/callbacks.c:576 ../coreapi/callbacks.c:888 msgid "Incompatible media parameters." msgstr "Несовместимость медиа-параметров." -#: ../coreapi/callbacks.c:588 +#: ../coreapi/callbacks.c:606 msgid "We have been resumed." msgstr "Мы возобновили." #. we are being paused -#: ../coreapi/callbacks.c:596 +#: ../coreapi/callbacks.c:614 msgid "We are paused by other party." msgstr "Мы приостановлены другой стороной." #. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:630 +#: ../coreapi/callbacks.c:648 msgid "Call is updated by remote." msgstr "Звонок был дистанционно обновлён." -#: ../coreapi/callbacks.c:746 +#: ../coreapi/callbacks.c:764 msgid "Call terminated." msgstr "Звонок прерван." -#: ../coreapi/callbacks.c:774 +#: ../coreapi/callbacks.c:792 msgid "User is busy." msgstr "Пользователь занят." -#: ../coreapi/callbacks.c:775 +#: ../coreapi/callbacks.c:793 msgid "User is temporarily unavailable." msgstr "Пользователь временно недоступен." #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:777 +#: ../coreapi/callbacks.c:795 msgid "User does not want to be disturbed." msgstr "Пользователь не хочет чтобы его беспокоили." -#: ../coreapi/callbacks.c:778 +#: ../coreapi/callbacks.c:796 msgid "Call declined." msgstr "Звонок отклонён." -#: ../coreapi/callbacks.c:793 +#: ../coreapi/callbacks.c:811 msgid "Request timeout." msgstr "Таймаут запроса." -#: ../coreapi/callbacks.c:824 +#: ../coreapi/callbacks.c:842 msgid "Redirected" msgstr "Переадресован" -#: ../coreapi/callbacks.c:879 +#: ../coreapi/callbacks.c:897 msgid "Call failed." msgstr "Звонок не удался." -#: ../coreapi/callbacks.c:957 +#: ../coreapi/callbacks.c:975 #, c-format msgid "Registration on %s successful." msgstr "Регистрация на %s прошла успешно." -#: ../coreapi/callbacks.c:958 +#: ../coreapi/callbacks.c:976 #, c-format msgid "Unregistration on %s done." msgstr "Отмена регистрации на %s завершена." -#: ../coreapi/callbacks.c:976 +#: ../coreapi/callbacks.c:994 msgid "no response timeout" msgstr "время ожидания истекло" -#: ../coreapi/callbacks.c:979 +#: ../coreapi/callbacks.c:997 #, c-format msgid "Registration on %s failed: %s" msgstr "Регистрация на %s не удалась: %s" -#: ../coreapi/callbacks.c:986 +#: ../coreapi/callbacks.c:1004 msgid "Service unavailable, retrying" msgstr "Сервис недоступен, повтор" @@ -2011,7 +2010,7 @@ msgstr "Сервис недоступен, повтор" msgid "Authentication token is %s" msgstr "Маркер проверки подлинности: %s" -#: ../coreapi/linphonecall.c:3492 +#: ../coreapi/linphonecall.c:3600 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." diff --git a/po/sr.po b/po/sr.po index c27c803ee..ada4f8844 100644 --- a/po/sr.po +++ b/po/sr.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-02-17 12:28+0100\n" +"POT-Creation-Date: 2015-03-11 16:26+0100\n" "PO-Revision-Date: 2015-02-17 11:28+0000\n" "Last-Translator: Belledonne Communications \n" @@ -95,35 +95,35 @@ msgstr "Ја" msgid "Couldn't find pixmap file: %s" msgstr "Не могу да пронађем датотеку сличице: %s" -#: ../gtk/chat.c:367 ../gtk/friendlist.c:924 +#: ../gtk/chat.c:374 ../gtk/friendlist.c:924 msgid "Invalid sip contact !" msgstr "Неисправан сип контакт !" -#: ../gtk/main.c:109 +#: ../gtk/main.c:137 msgid "log to stdout some debug information while running." msgstr "бележи на стандардни излаз неке податке прочишћавања док ради." -#: ../gtk/main.c:116 +#: ../gtk/main.c:138 msgid "path to a file to write logs into." msgstr "путања до датотеке за уписивање дневника." -#: ../gtk/main.c:123 +#: ../gtk/main.c:139 msgid "Start linphone with video disabled." msgstr "Покреће линфон са искљученим видеом." -#: ../gtk/main.c:130 +#: ../gtk/main.c:140 msgid "Start only in the system tray, do not show the main interface." msgstr "Покреће се само у системској фиоци, не приказује главно сучеље." -#: ../gtk/main.c:137 +#: ../gtk/main.c:141 msgid "address to call right now" msgstr "адреса за позивање управо сада" -#: ../gtk/main.c:144 +#: ../gtk/main.c:142 msgid "if set automatically answer incoming calls" msgstr "ако је подешено сам ће се јављати на долазне позиве" -#: ../gtk/main.c:151 +#: ../gtk/main.c:143 msgid "" "Specifiy a working directory (should be the base of the installation, eg: c:" "\\Program Files\\Linphone)" @@ -131,19 +131,19 @@ msgstr "" "Наводи радни директоријум (треба да буде основа инсталације, нпр: „c:" "\\Program Files\\Linphone“)" -#: ../gtk/main.c:158 +#: ../gtk/main.c:144 msgid "Configuration file" msgstr "Датотека подешавања" -#: ../gtk/main.c:165 +#: ../gtk/main.c:145 msgid "Run the audio assistant" msgstr "Покреће помоћника звука" -#: ../gtk/main.c:172 +#: ../gtk/main.c:146 msgid "Run self test and exit 0 if succeed" msgstr "Покреће самоиспробавање и излази 0 ако је успешно" -#: ../gtk/main.c:1088 +#: ../gtk/main.c:1061 #, c-format msgid "" "%s would like to add you to his contact list.\n" @@ -157,7 +157,7 @@ msgstr "" "Ако одговорите са не, ова особа ће привремено бити стављена на списак " "забрана." -#: ../gtk/main.c:1165 +#: ../gtk/main.c:1138 #, c-format msgid "" "Please enter your password for username %s\n" @@ -166,59 +166,59 @@ msgstr "" "Унесите вашу лозинку за корисничко име %s\n" " на подручју %s:" -#: ../gtk/main.c:1286 +#: ../gtk/main.c:1259 msgid "Call error" msgstr "Грешка позива" -#: ../gtk/main.c:1289 ../coreapi/linphonecore.c:3787 +#: ../gtk/main.c:1262 ../coreapi/linphonecore.c:3791 msgid "Call ended" msgstr "Позив је завршен" -#: ../gtk/main.c:1292 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1265 ../coreapi/call_log.c:221 msgid "Incoming call" msgstr "Долазни позив" -#: ../gtk/main.c:1294 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1267 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 msgid "Answer" msgstr "Јави се" -#: ../gtk/main.c:1296 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1269 ../gtk/main.ui.h:6 msgid "Decline" msgstr "Одбиј" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 msgid "Call paused" msgstr "Позив је заустављен" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 #, c-format msgid "by %s" msgstr "од %s" -#: ../gtk/main.c:1372 +#: ../gtk/main.c:1345 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "%s предлаже да започнете видео. Да ли прихватате ?" -#: ../gtk/main.c:1534 +#: ../gtk/main.c:1507 msgid "Website link" msgstr "Веза веб сајта" -#: ../gtk/main.c:1583 +#: ../gtk/main.c:1556 msgid "Linphone - a video internet phone" msgstr "Линфон — интернет телефон са снимком" -#: ../gtk/main.c:1675 +#: ../gtk/main.c:1648 #, c-format msgid "%s (Default)" msgstr "%s (основно)" -#: ../gtk/main.c:2007 ../coreapi/callbacks.c:1027 +#: ../gtk/main.c:1980 ../coreapi/callbacks.c:1045 #, c-format msgid "We are transferred to %s" msgstr "Преселили смо се на %s" -#: ../gtk/main.c:2017 +#: ../gtk/main.c:1990 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." @@ -226,7 +226,7 @@ msgstr "" "Ниједна звучна картица није откривена на овом рачунару.\n" "Нећете бити у могућности да шаљете или да примате звучне позиве." -#: ../gtk/main.c:2161 +#: ../gtk/main.c:2135 msgid "A free SIP video-phone" msgstr "Слободан СИП телефон са снимком" @@ -768,7 +768,7 @@ msgstr "" msgid "(Paused)" msgstr "(Паузирано)" -#: ../gtk/loginframe.c:88 +#: ../gtk/loginframe.c:87 #, c-format msgid "Please enter login information for %s" msgstr "Унесите податке пријављивања за %s" @@ -1748,60 +1748,60 @@ msgstr "Подешавам..." msgid "Please wait while fetching configuration from server..." msgstr "Сачекајте док довучем подешавања са сервера..." -#: ../coreapi/linphonecore.c:1508 +#: ../coreapi/linphonecore.c:1512 msgid "Ready" msgstr "Спреман" -#: ../coreapi/linphonecore.c:2495 +#: ../coreapi/linphonecore.c:2499 msgid "Configuring" msgstr "Подешавам" -#: ../coreapi/linphonecore.c:2669 +#: ../coreapi/linphonecore.c:2673 msgid "Looking for telephone number destination..." msgstr "Тражим одредиште телефонског броја..." -#: ../coreapi/linphonecore.c:2671 +#: ../coreapi/linphonecore.c:2675 msgid "Could not resolve this number." msgstr "Не могу да решим овај број." #. must be known at that time -#: ../coreapi/linphonecore.c:2957 +#: ../coreapi/linphonecore.c:2961 msgid "Contacting" msgstr "Ступам у везу" -#: ../coreapi/linphonecore.c:2962 +#: ../coreapi/linphonecore.c:2966 msgid "Could not call" msgstr "Не могу да позовем" -#: ../coreapi/linphonecore.c:3112 +#: ../coreapi/linphonecore.c:3116 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "Извините, достигли смо највећи број истовремених позива" -#: ../coreapi/linphonecore.c:3270 +#: ../coreapi/linphonecore.c:3274 msgid "is contacting you" msgstr "вам се обраћа" -#: ../coreapi/linphonecore.c:3271 +#: ../coreapi/linphonecore.c:3275 msgid " and asked autoanswer." msgstr " и затражени само-одговор." -#: ../coreapi/linphonecore.c:3395 +#: ../coreapi/linphonecore.c:3399 msgid "Modifying call parameters..." msgstr "Мењам параметре позива..." -#: ../coreapi/linphonecore.c:3743 +#: ../coreapi/linphonecore.c:3747 msgid "Connected." msgstr "Повезан сам." -#: ../coreapi/linphonecore.c:3768 +#: ../coreapi/linphonecore.c:3772 msgid "Call aborted" msgstr "Позив је прекинут" -#: ../coreapi/linphonecore.c:3958 +#: ../coreapi/linphonecore.c:3962 msgid "Could not pause the call" msgstr "Не могу да зауставим позив" -#: ../coreapi/linphonecore.c:3961 +#: ../coreapi/linphonecore.c:3965 msgid "Pausing the current call..." msgstr "Заустављам тренутни позив..." @@ -1887,112 +1887,112 @@ msgstr "" msgid "Could not login as %s" msgstr "Не могу да се пријавим као %s" -#: ../coreapi/callbacks.c:404 +#: ../coreapi/callbacks.c:419 msgid "Remote ringing." msgstr "Удаљено звоњење." -#: ../coreapi/callbacks.c:425 +#: ../coreapi/callbacks.c:431 msgid "Remote ringing..." msgstr "Удаљено звоњење..." -#: ../coreapi/callbacks.c:442 +#: ../coreapi/callbacks.c:448 msgid "Early media." msgstr "Ранији медиј." -#: ../coreapi/callbacks.c:503 +#: ../coreapi/callbacks.c:521 #, c-format msgid "Call with %s is paused." msgstr "Позив са „%s“ је заустављен." -#: ../coreapi/callbacks.c:516 +#: ../coreapi/callbacks.c:534 #, c-format msgid "Call answered by %s - on hold." msgstr "Позив на који је одговорио „%s“ — на чекању." -#: ../coreapi/callbacks.c:526 +#: ../coreapi/callbacks.c:544 msgid "Call resumed." msgstr "Позив је настављен." -#: ../coreapi/callbacks.c:530 +#: ../coreapi/callbacks.c:548 #, c-format msgid "Call answered by %s." msgstr "На позив је одговорио „%s“." -#: ../coreapi/callbacks.c:553 +#: ../coreapi/callbacks.c:571 msgid "Incompatible, check codecs or security settings..." msgstr "Несагласно, проверите кодеке или безбедносна подешавања..." -#: ../coreapi/callbacks.c:558 ../coreapi/callbacks.c:870 +#: ../coreapi/callbacks.c:576 ../coreapi/callbacks.c:888 msgid "Incompatible media parameters." msgstr "Медијски параметри су несагласни." -#: ../coreapi/callbacks.c:588 +#: ../coreapi/callbacks.c:606 msgid "We have been resumed." msgstr "Наставили смо." #. we are being paused -#: ../coreapi/callbacks.c:596 +#: ../coreapi/callbacks.c:614 msgid "We are paused by other party." msgstr "Друга страна нас је паузирала." #. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:630 +#: ../coreapi/callbacks.c:648 msgid "Call is updated by remote." msgstr "Позив је освежен удаљеним." -#: ../coreapi/callbacks.c:746 +#: ../coreapi/callbacks.c:764 msgid "Call terminated." msgstr "Позив је завршен." -#: ../coreapi/callbacks.c:774 +#: ../coreapi/callbacks.c:792 msgid "User is busy." msgstr "Корисник је заузет." -#: ../coreapi/callbacks.c:775 +#: ../coreapi/callbacks.c:793 msgid "User is temporarily unavailable." msgstr "Корисник је привремено недоступан." #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:777 +#: ../coreapi/callbacks.c:795 msgid "User does not want to be disturbed." msgstr "Корисник не жели да буде узнемираван." -#: ../coreapi/callbacks.c:778 +#: ../coreapi/callbacks.c:796 msgid "Call declined." msgstr "Позив је одбијен." -#: ../coreapi/callbacks.c:793 +#: ../coreapi/callbacks.c:811 msgid "Request timeout." msgstr "Истекло је време захтева." -#: ../coreapi/callbacks.c:824 +#: ../coreapi/callbacks.c:842 msgid "Redirected" msgstr "Преусмерен" -#: ../coreapi/callbacks.c:879 +#: ../coreapi/callbacks.c:897 msgid "Call failed." msgstr "Позив није успео." -#: ../coreapi/callbacks.c:957 +#: ../coreapi/callbacks.c:975 #, c-format msgid "Registration on %s successful." msgstr "Уписивање на „%s“ је успело." -#: ../coreapi/callbacks.c:958 +#: ../coreapi/callbacks.c:976 #, c-format msgid "Unregistration on %s done." msgstr "Исписивање са „%s“ је обављено." -#: ../coreapi/callbacks.c:976 +#: ../coreapi/callbacks.c:994 msgid "no response timeout" msgstr "нема ограничења одговора" -#: ../coreapi/callbacks.c:979 +#: ../coreapi/callbacks.c:997 #, c-format msgid "Registration on %s failed: %s" msgstr "Уписивање на „%s“ није успело: %s" -#: ../coreapi/callbacks.c:986 +#: ../coreapi/callbacks.c:1004 msgid "Service unavailable, retrying" msgstr "Услуга није доступна, поново покушавам" @@ -2002,7 +2002,7 @@ msgstr "Услуга није доступна, поново покушавам" msgid "Authentication token is %s" msgstr "Симбол потврђивања идентитета је „%s“" -#: ../coreapi/linphonecall.c:3492 +#: ../coreapi/linphonecall.c:3600 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." diff --git a/po/sv.po b/po/sv.po index ddee3cf70..6e2ada759 100644 --- a/po/sv.po +++ b/po/sv.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-02-17 12:28+0100\n" +"POT-Creation-Date: 2015-03-11 16:26+0100\n" "PO-Revision-Date: 2015-02-17 11:28+0000\n" "Last-Translator: Belledonne Communications \n" @@ -89,35 +89,35 @@ msgstr "" msgid "Couldn't find pixmap file: %s" msgstr "Kunde inte hitta pixmap filen: %s" -#: ../gtk/chat.c:367 ../gtk/friendlist.c:924 +#: ../gtk/chat.c:374 ../gtk/friendlist.c:924 msgid "Invalid sip contact !" msgstr "ogiltig SIP kontakt!" -#: ../gtk/main.c:109 +#: ../gtk/main.c:137 msgid "log to stdout some debug information while running." msgstr "skriv loggning information under körning" -#: ../gtk/main.c:116 +#: ../gtk/main.c:138 msgid "path to a file to write logs into." msgstr "" -#: ../gtk/main.c:123 +#: ../gtk/main.c:139 msgid "Start linphone with video disabled." msgstr "" -#: ../gtk/main.c:130 +#: ../gtk/main.c:140 msgid "Start only in the system tray, do not show the main interface." msgstr "Starta ikonifierat, visa inte huvudfönstret" -#: ../gtk/main.c:137 +#: ../gtk/main.c:141 msgid "address to call right now" msgstr "Samtalsmottagare" -#: ../gtk/main.c:144 +#: ../gtk/main.c:142 msgid "if set automatically answer incoming calls" msgstr "Om på, besvara automatisk alla inkommande samtal" -#: ../gtk/main.c:151 +#: ../gtk/main.c:143 msgid "" "Specifiy a working directory (should be the base of the installation, eg: c:" "\\Program Files\\Linphone)" @@ -125,19 +125,19 @@ msgstr "" "Välj en arbetskatalog som ska vara basen för installationen, såsom C:" "\\Program\\Linphone" -#: ../gtk/main.c:158 +#: ../gtk/main.c:144 msgid "Configuration file" msgstr "" -#: ../gtk/main.c:165 +#: ../gtk/main.c:145 msgid "Run the audio assistant" msgstr "" -#: ../gtk/main.c:172 +#: ../gtk/main.c:146 msgid "Run self test and exit 0 if succeed" msgstr "" -#: ../gtk/main.c:1088 +#: ../gtk/main.c:1061 #, c-format msgid "" "%s would like to add you to his contact list.\n" @@ -150,72 +150,72 @@ msgstr "" "henne till din kontaktlista?\n" "Om du svarar nej, personen kommer att vara bannlyst." -#: ../gtk/main.c:1165 +#: ../gtk/main.c:1138 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" msgstr "" -#: ../gtk/main.c:1286 +#: ../gtk/main.c:1259 msgid "Call error" msgstr "" -#: ../gtk/main.c:1289 ../coreapi/linphonecore.c:3787 +#: ../gtk/main.c:1262 ../coreapi/linphonecore.c:3791 msgid "Call ended" msgstr "Samtalet slut" -#: ../gtk/main.c:1292 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1265 ../coreapi/call_log.c:221 msgid "Incoming call" msgstr "Inkommande samtal" -#: ../gtk/main.c:1294 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1267 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 msgid "Answer" msgstr "" -#: ../gtk/main.c:1296 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1269 ../gtk/main.ui.h:6 msgid "Decline" msgstr "Avböj" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 msgid "Call paused" msgstr "" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 #, c-format msgid "by %s" msgstr "" -#: ../gtk/main.c:1372 +#: ../gtk/main.c:1345 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "" -#: ../gtk/main.c:1534 +#: ../gtk/main.c:1507 msgid "Website link" msgstr "Webbsajt" -#: ../gtk/main.c:1583 +#: ../gtk/main.c:1556 msgid "Linphone - a video internet phone" msgstr "Linphone - en video Internet telefon" -#: ../gtk/main.c:1675 +#: ../gtk/main.c:1648 #, c-format msgid "%s (Default)" msgstr "%s (Default)" -#: ../gtk/main.c:2007 ../coreapi/callbacks.c:1027 +#: ../gtk/main.c:1980 ../coreapi/callbacks.c:1045 #, c-format msgid "We are transferred to %s" msgstr "" -#: ../gtk/main.c:2017 +#: ../gtk/main.c:1990 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." msgstr "" -#: ../gtk/main.c:2161 +#: ../gtk/main.c:2135 msgid "A free SIP video-phone" msgstr "En gratis SIP video-telefon" @@ -743,7 +743,7 @@ msgstr "" msgid "(Paused)" msgstr "" -#: ../gtk/loginframe.c:88 +#: ../gtk/loginframe.c:87 #, c-format msgid "Please enter login information for %s" msgstr "Mata in ditt lösenord för domänen %s:" @@ -1701,60 +1701,60 @@ msgstr "" msgid "Please wait while fetching configuration from server..." msgstr "" -#: ../coreapi/linphonecore.c:1508 +#: ../coreapi/linphonecore.c:1512 msgid "Ready" msgstr "Redo" -#: ../coreapi/linphonecore.c:2495 +#: ../coreapi/linphonecore.c:2499 msgid "Configuring" msgstr "" -#: ../coreapi/linphonecore.c:2669 +#: ../coreapi/linphonecore.c:2673 msgid "Looking for telephone number destination..." msgstr "Leta efter telefonnummer för destinationen..." -#: ../coreapi/linphonecore.c:2671 +#: ../coreapi/linphonecore.c:2675 msgid "Could not resolve this number." msgstr "Kan inte nå dett nummer." #. must be known at that time -#: ../coreapi/linphonecore.c:2957 +#: ../coreapi/linphonecore.c:2961 msgid "Contacting" msgstr "Kontaktar" -#: ../coreapi/linphonecore.c:2962 +#: ../coreapi/linphonecore.c:2966 msgid "Could not call" msgstr "" -#: ../coreapi/linphonecore.c:3112 +#: ../coreapi/linphonecore.c:3116 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "" -#: ../coreapi/linphonecore.c:3270 +#: ../coreapi/linphonecore.c:3274 msgid "is contacting you" msgstr "" -#: ../coreapi/linphonecore.c:3271 +#: ../coreapi/linphonecore.c:3275 msgid " and asked autoanswer." msgstr "" -#: ../coreapi/linphonecore.c:3395 +#: ../coreapi/linphonecore.c:3399 msgid "Modifying call parameters..." msgstr "" -#: ../coreapi/linphonecore.c:3743 +#: ../coreapi/linphonecore.c:3747 msgid "Connected." msgstr "Kopplad" -#: ../coreapi/linphonecore.c:3768 +#: ../coreapi/linphonecore.c:3772 msgid "Call aborted" msgstr "" -#: ../coreapi/linphonecore.c:3958 +#: ../coreapi/linphonecore.c:3962 msgid "Could not pause the call" msgstr "" -#: ../coreapi/linphonecore.c:3961 +#: ../coreapi/linphonecore.c:3965 msgid "Pausing the current call..." msgstr "" @@ -1839,112 +1839,112 @@ msgstr "" msgid "Could not login as %s" msgstr "Kunde inte logga in som %s" -#: ../coreapi/callbacks.c:404 +#: ../coreapi/callbacks.c:419 msgid "Remote ringing." msgstr "Ringer hos motparten." -#: ../coreapi/callbacks.c:425 +#: ../coreapi/callbacks.c:431 msgid "Remote ringing..." msgstr "" -#: ../coreapi/callbacks.c:442 +#: ../coreapi/callbacks.c:448 msgid "Early media." msgstr "Tidig media" -#: ../coreapi/callbacks.c:503 +#: ../coreapi/callbacks.c:521 #, c-format msgid "Call with %s is paused." msgstr "" -#: ../coreapi/callbacks.c:516 +#: ../coreapi/callbacks.c:534 #, c-format msgid "Call answered by %s - on hold." msgstr "" -#: ../coreapi/callbacks.c:526 +#: ../coreapi/callbacks.c:544 msgid "Call resumed." msgstr "" -#: ../coreapi/callbacks.c:530 +#: ../coreapi/callbacks.c:548 #, c-format msgid "Call answered by %s." msgstr "" -#: ../coreapi/callbacks.c:553 +#: ../coreapi/callbacks.c:571 msgid "Incompatible, check codecs or security settings..." msgstr "" -#: ../coreapi/callbacks.c:558 ../coreapi/callbacks.c:870 +#: ../coreapi/callbacks.c:576 ../coreapi/callbacks.c:888 msgid "Incompatible media parameters." msgstr "" -#: ../coreapi/callbacks.c:588 +#: ../coreapi/callbacks.c:606 msgid "We have been resumed." msgstr "" #. we are being paused -#: ../coreapi/callbacks.c:596 +#: ../coreapi/callbacks.c:614 msgid "We are paused by other party." msgstr "" #. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:630 +#: ../coreapi/callbacks.c:648 msgid "Call is updated by remote." msgstr "" -#: ../coreapi/callbacks.c:746 +#: ../coreapi/callbacks.c:764 msgid "Call terminated." msgstr "Samtalet slut." -#: ../coreapi/callbacks.c:774 +#: ../coreapi/callbacks.c:792 msgid "User is busy." msgstr "Användare upptagen." -#: ../coreapi/callbacks.c:775 +#: ../coreapi/callbacks.c:793 msgid "User is temporarily unavailable." msgstr "Användaren temporärt inte tillgänglig." #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:777 +#: ../coreapi/callbacks.c:795 msgid "User does not want to be disturbed." msgstr "Användaren vill inte bli störd." -#: ../coreapi/callbacks.c:778 +#: ../coreapi/callbacks.c:796 msgid "Call declined." msgstr "Samtalet avböjdes." -#: ../coreapi/callbacks.c:793 +#: ../coreapi/callbacks.c:811 msgid "Request timeout." msgstr "" -#: ../coreapi/callbacks.c:824 +#: ../coreapi/callbacks.c:842 msgid "Redirected" msgstr "" -#: ../coreapi/callbacks.c:879 +#: ../coreapi/callbacks.c:897 msgid "Call failed." msgstr "" -#: ../coreapi/callbacks.c:957 +#: ../coreapi/callbacks.c:975 #, c-format msgid "Registration on %s successful." msgstr "Registrering hos %s lyckades." -#: ../coreapi/callbacks.c:958 +#: ../coreapi/callbacks.c:976 #, c-format msgid "Unregistration on %s done." msgstr "Avregistrering hos %s lyckades." -#: ../coreapi/callbacks.c:976 +#: ../coreapi/callbacks.c:994 msgid "no response timeout" msgstr "Inget svar inom angiven tid" -#: ../coreapi/callbacks.c:979 +#: ../coreapi/callbacks.c:997 #, c-format msgid "Registration on %s failed: %s" msgstr "Registrering hos %s mislyckades: %s" -#: ../coreapi/callbacks.c:986 +#: ../coreapi/callbacks.c:1004 msgid "Service unavailable, retrying" msgstr "" @@ -1954,7 +1954,7 @@ msgstr "" msgid "Authentication token is %s" msgstr "" -#: ../coreapi/linphonecall.c:3492 +#: ../coreapi/linphonecall.c:3600 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." diff --git a/po/zh_CN.po b/po/zh_CN.po index 30e05bb15..67145f034 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-02-17 12:28+0100\n" +"POT-Creation-Date: 2015-03-11 16:26+0100\n" "PO-Revision-Date: 2015-02-17 11:28+0000\n" "Last-Translator: Belledonne Communications \n" @@ -87,53 +87,53 @@ msgstr "" msgid "Couldn't find pixmap file: %s" msgstr "无法打开位图文件:%s" -#: ../gtk/chat.c:367 ../gtk/friendlist.c:924 +#: ../gtk/chat.c:374 ../gtk/friendlist.c:924 msgid "Invalid sip contact !" msgstr "无效的 SIP 联系人!" -#: ../gtk/main.c:109 +#: ../gtk/main.c:137 msgid "log to stdout some debug information while running." msgstr "运行时向标准输出记录调试信息。" -#: ../gtk/main.c:116 +#: ../gtk/main.c:138 msgid "path to a file to write logs into." msgstr "" -#: ../gtk/main.c:123 +#: ../gtk/main.c:139 msgid "Start linphone with video disabled." msgstr "" -#: ../gtk/main.c:130 +#: ../gtk/main.c:140 msgid "Start only in the system tray, do not show the main interface." msgstr "启动到系统托盘,不显示主界面。" -#: ../gtk/main.c:137 +#: ../gtk/main.c:141 msgid "address to call right now" msgstr "现在呼叫的地址" -#: ../gtk/main.c:144 +#: ../gtk/main.c:142 msgid "if set automatically answer incoming calls" msgstr "是否设置呼叫自动应答" -#: ../gtk/main.c:151 +#: ../gtk/main.c:143 msgid "" "Specifiy a working directory (should be the base of the installation, eg: c:" "\\Program Files\\Linphone)" msgstr "指定工作目录(应为安装目录例如 C:\\Program Files\\Linphone)" -#: ../gtk/main.c:158 +#: ../gtk/main.c:144 msgid "Configuration file" msgstr "" -#: ../gtk/main.c:165 +#: ../gtk/main.c:145 msgid "Run the audio assistant" msgstr "" -#: ../gtk/main.c:172 +#: ../gtk/main.c:146 msgid "Run self test and exit 0 if succeed" msgstr "" -#: ../gtk/main.c:1088 +#: ../gtk/main.c:1061 #, c-format msgid "" "%s would like to add you to his contact list.\n" @@ -145,66 +145,66 @@ msgstr "" "您是否允许他看到您的在线状态或者将它加为您的联系人允许?\n" "如果您回答否,则会将该人临时性的放入黑名单" -#: ../gtk/main.c:1165 +#: ../gtk/main.c:1138 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" msgstr "" -#: ../gtk/main.c:1286 +#: ../gtk/main.c:1259 msgid "Call error" msgstr "" -#: ../gtk/main.c:1289 ../coreapi/linphonecore.c:3787 +#: ../gtk/main.c:1262 ../coreapi/linphonecore.c:3791 msgid "Call ended" msgstr "呼叫结束" -#: ../gtk/main.c:1292 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1265 ../coreapi/call_log.c:221 msgid "Incoming call" msgstr "呼入" -#: ../gtk/main.c:1294 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1267 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 msgid "Answer" msgstr "" -#: ../gtk/main.c:1296 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1269 ../gtk/main.ui.h:6 msgid "Decline" msgstr "拒绝" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 msgid "Call paused" msgstr "" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 #, c-format msgid "by %s" msgstr "" -#: ../gtk/main.c:1372 +#: ../gtk/main.c:1345 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "" -#: ../gtk/main.c:1534 +#: ../gtk/main.c:1507 msgid "Website link" msgstr "网站" -#: ../gtk/main.c:1583 +#: ../gtk/main.c:1556 msgid "Linphone - a video internet phone" msgstr "Linphone - 互联网视频电话" -#: ../gtk/main.c:1675 +#: ../gtk/main.c:1648 #, c-format msgid "%s (Default)" msgstr "%s (默认)" -#: ../gtk/main.c:2007 ../coreapi/callbacks.c:1027 +#: ../gtk/main.c:1980 ../coreapi/callbacks.c:1045 #, c-format msgid "We are transferred to %s" msgstr "" -#: ../gtk/main.c:2017 +#: ../gtk/main.c:1990 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." @@ -212,7 +212,7 @@ msgstr "" "未在此计算机上检测到声卡。\n" "您无法发送或接收音频呼叫。" -#: ../gtk/main.c:2161 +#: ../gtk/main.c:2135 msgid "A free SIP video-phone" msgstr "免费的 SIP 视频电话" @@ -739,7 +739,7 @@ msgstr "" msgid "(Paused)" msgstr "" -#: ../gtk/loginframe.c:88 +#: ../gtk/loginframe.c:87 #, c-format msgid "Please enter login information for %s" msgstr "请输入 %s 的登录信息" @@ -1696,60 +1696,60 @@ msgstr "" msgid "Please wait while fetching configuration from server..." msgstr "" -#: ../coreapi/linphonecore.c:1508 +#: ../coreapi/linphonecore.c:1512 msgid "Ready" msgstr "就绪" -#: ../coreapi/linphonecore.c:2495 +#: ../coreapi/linphonecore.c:2499 msgid "Configuring" msgstr "" -#: ../coreapi/linphonecore.c:2669 +#: ../coreapi/linphonecore.c:2673 msgid "Looking for telephone number destination..." msgstr "查询电话号码目的地..." -#: ../coreapi/linphonecore.c:2671 +#: ../coreapi/linphonecore.c:2675 msgid "Could not resolve this number." msgstr "该号码无法解析。" #. must be known at that time -#: ../coreapi/linphonecore.c:2957 +#: ../coreapi/linphonecore.c:2961 msgid "Contacting" msgstr "联系中" -#: ../coreapi/linphonecore.c:2962 +#: ../coreapi/linphonecore.c:2966 msgid "Could not call" msgstr "" -#: ../coreapi/linphonecore.c:3112 +#: ../coreapi/linphonecore.c:3116 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "" -#: ../coreapi/linphonecore.c:3270 +#: ../coreapi/linphonecore.c:3274 msgid "is contacting you" msgstr "正在联系您" -#: ../coreapi/linphonecore.c:3271 +#: ../coreapi/linphonecore.c:3275 msgid " and asked autoanswer." msgstr " 并询问了自动回答。" -#: ../coreapi/linphonecore.c:3395 +#: ../coreapi/linphonecore.c:3399 msgid "Modifying call parameters..." msgstr "" -#: ../coreapi/linphonecore.c:3743 +#: ../coreapi/linphonecore.c:3747 msgid "Connected." msgstr "已连接。" -#: ../coreapi/linphonecore.c:3768 +#: ../coreapi/linphonecore.c:3772 msgid "Call aborted" msgstr "" -#: ../coreapi/linphonecore.c:3958 +#: ../coreapi/linphonecore.c:3962 msgid "Could not pause the call" msgstr "" -#: ../coreapi/linphonecore.c:3961 +#: ../coreapi/linphonecore.c:3965 msgid "Pausing the current call..." msgstr "" @@ -1832,112 +1832,112 @@ msgstr "" msgid "Could not login as %s" msgstr "无法登录为 %s" -#: ../coreapi/callbacks.c:404 +#: ../coreapi/callbacks.c:419 msgid "Remote ringing." msgstr "响铃。" -#: ../coreapi/callbacks.c:425 +#: ../coreapi/callbacks.c:431 msgid "Remote ringing..." msgstr "" -#: ../coreapi/callbacks.c:442 +#: ../coreapi/callbacks.c:448 msgid "Early media." msgstr "" -#: ../coreapi/callbacks.c:503 +#: ../coreapi/callbacks.c:521 #, c-format msgid "Call with %s is paused." msgstr "" -#: ../coreapi/callbacks.c:516 +#: ../coreapi/callbacks.c:534 #, c-format msgid "Call answered by %s - on hold." msgstr "" -#: ../coreapi/callbacks.c:526 +#: ../coreapi/callbacks.c:544 msgid "Call resumed." msgstr "" -#: ../coreapi/callbacks.c:530 +#: ../coreapi/callbacks.c:548 #, c-format msgid "Call answered by %s." msgstr "" -#: ../coreapi/callbacks.c:553 +#: ../coreapi/callbacks.c:571 msgid "Incompatible, check codecs or security settings..." msgstr "" -#: ../coreapi/callbacks.c:558 ../coreapi/callbacks.c:870 +#: ../coreapi/callbacks.c:576 ../coreapi/callbacks.c:888 msgid "Incompatible media parameters." msgstr "" -#: ../coreapi/callbacks.c:588 +#: ../coreapi/callbacks.c:606 msgid "We have been resumed." msgstr "" #. we are being paused -#: ../coreapi/callbacks.c:596 +#: ../coreapi/callbacks.c:614 msgid "We are paused by other party." msgstr "" #. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:630 +#: ../coreapi/callbacks.c:648 msgid "Call is updated by remote." msgstr "" -#: ../coreapi/callbacks.c:746 +#: ../coreapi/callbacks.c:764 msgid "Call terminated." msgstr "通话结束。" -#: ../coreapi/callbacks.c:774 +#: ../coreapi/callbacks.c:792 msgid "User is busy." msgstr "被叫正忙。" -#: ../coreapi/callbacks.c:775 +#: ../coreapi/callbacks.c:793 msgid "User is temporarily unavailable." msgstr "您呼叫的用户暂时无法接通。" #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:777 +#: ../coreapi/callbacks.c:795 msgid "User does not want to be disturbed." msgstr "用户已开启免打扰功能。" -#: ../coreapi/callbacks.c:778 +#: ../coreapi/callbacks.c:796 msgid "Call declined." msgstr "呼叫被拒绝。" -#: ../coreapi/callbacks.c:793 +#: ../coreapi/callbacks.c:811 msgid "Request timeout." msgstr "" -#: ../coreapi/callbacks.c:824 +#: ../coreapi/callbacks.c:842 msgid "Redirected" msgstr "已重定向" -#: ../coreapi/callbacks.c:879 +#: ../coreapi/callbacks.c:897 msgid "Call failed." msgstr "呼叫失败。" -#: ../coreapi/callbacks.c:957 +#: ../coreapi/callbacks.c:975 #, c-format msgid "Registration on %s successful." msgstr "成功注册到 %s" -#: ../coreapi/callbacks.c:958 +#: ../coreapi/callbacks.c:976 #, c-format msgid "Unregistration on %s done." msgstr "已在 %s 解除注册。" -#: ../coreapi/callbacks.c:976 +#: ../coreapi/callbacks.c:994 msgid "no response timeout" msgstr "没有响应,超时" -#: ../coreapi/callbacks.c:979 +#: ../coreapi/callbacks.c:997 #, c-format msgid "Registration on %s failed: %s" msgstr "注册到 %s 失败: %s" -#: ../coreapi/callbacks.c:986 +#: ../coreapi/callbacks.c:1004 msgid "Service unavailable, retrying" msgstr "" @@ -1947,7 +1947,7 @@ msgstr "" msgid "Authentication token is %s" msgstr "" -#: ../coreapi/linphonecall.c:3492 +#: ../coreapi/linphonecall.c:3600 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." diff --git a/po/zh_TW.po b/po/zh_TW.po index 598b7acf3..e052ee316 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-02-17 12:28+0100\n" +"POT-Creation-Date: 2015-03-11 16:26+0100\n" "PO-Revision-Date: 2015-02-17 11:28+0000\n" "Last-Translator: Belledonne Communications \n" @@ -87,54 +87,54 @@ msgstr "" msgid "Couldn't find pixmap file: %s" msgstr "找不到 pixmap 檔:%s" -#: ../gtk/chat.c:367 ../gtk/friendlist.c:924 +#: ../gtk/chat.c:374 ../gtk/friendlist.c:924 msgid "Invalid sip contact !" msgstr "無效的 sip 連絡人!" -#: ../gtk/main.c:109 +#: ../gtk/main.c:137 msgid "log to stdout some debug information while running." msgstr "執行時將一些除錯資訊記錄到標準輸出。" -#: ../gtk/main.c:116 +#: ../gtk/main.c:138 msgid "path to a file to write logs into." msgstr "" -#: ../gtk/main.c:123 +#: ../gtk/main.c:139 msgid "Start linphone with video disabled." msgstr "" -#: ../gtk/main.c:130 +#: ../gtk/main.c:140 msgid "Start only in the system tray, do not show the main interface." msgstr "只在系統匣啟動,不要顯示主要介面。" -#: ../gtk/main.c:137 +#: ../gtk/main.c:141 msgid "address to call right now" msgstr "現在要打電話的位址" -#: ../gtk/main.c:144 +#: ../gtk/main.c:142 msgid "if set automatically answer incoming calls" msgstr "如啟用此項,將會自動接聽來電" -#: ../gtk/main.c:151 +#: ../gtk/main.c:143 msgid "" "Specifiy a working directory (should be the base of the installation, eg: c:" "\\Program Files\\Linphone)" msgstr "" "指定一個工作目錄(應該為安裝的根目錄,例如:c:\\Program Files\\Linphone)" -#: ../gtk/main.c:158 +#: ../gtk/main.c:144 msgid "Configuration file" msgstr "" -#: ../gtk/main.c:165 +#: ../gtk/main.c:145 msgid "Run the audio assistant" msgstr "" -#: ../gtk/main.c:172 +#: ../gtk/main.c:146 msgid "Run self test and exit 0 if succeed" msgstr "" -#: ../gtk/main.c:1088 +#: ../gtk/main.c:1061 #, c-format msgid "" "%s would like to add you to his contact list.\n" @@ -146,66 +146,66 @@ msgstr "" "您是否要允許他看見您的上線狀態或將他加入您的連絡人清單?\n" "如果您回答否,這個人會被暫時列入黑名單。" -#: ../gtk/main.c:1165 +#: ../gtk/main.c:1138 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" msgstr "" -#: ../gtk/main.c:1286 +#: ../gtk/main.c:1259 msgid "Call error" msgstr "" -#: ../gtk/main.c:1289 ../coreapi/linphonecore.c:3787 +#: ../gtk/main.c:1262 ../coreapi/linphonecore.c:3791 msgid "Call ended" msgstr "通話已結束" -#: ../gtk/main.c:1292 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1265 ../coreapi/call_log.c:221 msgid "Incoming call" msgstr "來電" -#: ../gtk/main.c:1294 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1267 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 msgid "Answer" msgstr "接聽" -#: ../gtk/main.c:1296 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1269 ../gtk/main.ui.h:6 msgid "Decline" msgstr "拒接" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 msgid "Call paused" msgstr "" -#: ../gtk/main.c:1302 +#: ../gtk/main.c:1275 #, c-format msgid "by %s" msgstr "" -#: ../gtk/main.c:1372 +#: ../gtk/main.c:1345 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "" -#: ../gtk/main.c:1534 +#: ../gtk/main.c:1507 msgid "Website link" msgstr "網站連結" -#: ../gtk/main.c:1583 +#: ../gtk/main.c:1556 msgid "Linphone - a video internet phone" msgstr "Linphone - 網路視訊電話" -#: ../gtk/main.c:1675 +#: ../gtk/main.c:1648 #, c-format msgid "%s (Default)" msgstr "%s (預設值)" -#: ../gtk/main.c:2007 ../coreapi/callbacks.c:1027 +#: ../gtk/main.c:1980 ../coreapi/callbacks.c:1045 #, c-format msgid "We are transferred to %s" msgstr "我們被轉接到 %s" -#: ../gtk/main.c:2017 +#: ../gtk/main.c:1990 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." @@ -213,7 +213,7 @@ msgstr "" "在這臺電腦中偵測不到音效卡。\n" "您將無法傳送或接收語音電話。" -#: ../gtk/main.c:2161 +#: ../gtk/main.c:2135 msgid "A free SIP video-phone" msgstr "自由的 SIP 視訊電話" @@ -740,7 +740,7 @@ msgstr "" msgid "(Paused)" msgstr "" -#: ../gtk/loginframe.c:88 +#: ../gtk/loginframe.c:87 #, c-format msgid "Please enter login information for %s" msgstr "請輸入 %s 的 登入資訊" @@ -1697,60 +1697,60 @@ msgstr "" msgid "Please wait while fetching configuration from server..." msgstr "" -#: ../coreapi/linphonecore.c:1508 +#: ../coreapi/linphonecore.c:1512 msgid "Ready" msgstr "準備就緒" -#: ../coreapi/linphonecore.c:2495 +#: ../coreapi/linphonecore.c:2499 msgid "Configuring" msgstr "" -#: ../coreapi/linphonecore.c:2669 +#: ../coreapi/linphonecore.c:2673 msgid "Looking for telephone number destination..." msgstr "尋找電話號碼目的端..." -#: ../coreapi/linphonecore.c:2671 +#: ../coreapi/linphonecore.c:2675 msgid "Could not resolve this number." msgstr "無法解析這個號碼。" #. must be known at that time -#: ../coreapi/linphonecore.c:2957 +#: ../coreapi/linphonecore.c:2961 msgid "Contacting" msgstr "正在連絡" -#: ../coreapi/linphonecore.c:2962 +#: ../coreapi/linphonecore.c:2966 msgid "Could not call" msgstr "無法通話" -#: ../coreapi/linphonecore.c:3112 +#: ../coreapi/linphonecore.c:3116 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "抱歉,我們已達瀏同步通話的最大數目" -#: ../coreapi/linphonecore.c:3270 +#: ../coreapi/linphonecore.c:3274 msgid "is contacting you" msgstr "正在連絡您" -#: ../coreapi/linphonecore.c:3271 +#: ../coreapi/linphonecore.c:3275 msgid " and asked autoanswer." msgstr "並要求自動接聽。" -#: ../coreapi/linphonecore.c:3395 +#: ../coreapi/linphonecore.c:3399 msgid "Modifying call parameters..." msgstr "修改通話參數..." -#: ../coreapi/linphonecore.c:3743 +#: ../coreapi/linphonecore.c:3747 msgid "Connected." msgstr "已連線。" -#: ../coreapi/linphonecore.c:3768 +#: ../coreapi/linphonecore.c:3772 msgid "Call aborted" msgstr "通話已放棄" -#: ../coreapi/linphonecore.c:3958 +#: ../coreapi/linphonecore.c:3962 msgid "Could not pause the call" msgstr "無法暫停通話" -#: ../coreapi/linphonecore.c:3961 +#: ../coreapi/linphonecore.c:3965 msgid "Pausing the current call..." msgstr "暫停目前的通話..." @@ -1834,112 +1834,112 @@ msgstr "" msgid "Could not login as %s" msgstr "無法以 %s 登入" -#: ../coreapi/callbacks.c:404 +#: ../coreapi/callbacks.c:419 msgid "Remote ringing." msgstr "遠端響鈴。" -#: ../coreapi/callbacks.c:425 +#: ../coreapi/callbacks.c:431 msgid "Remote ringing..." msgstr "遠端響鈴..." -#: ../coreapi/callbacks.c:442 +#: ../coreapi/callbacks.c:448 msgid "Early media." msgstr "早期媒體。" -#: ../coreapi/callbacks.c:503 +#: ../coreapi/callbacks.c:521 #, c-format msgid "Call with %s is paused." msgstr "和 %s 的通話已暫停。" -#: ../coreapi/callbacks.c:516 +#: ../coreapi/callbacks.c:534 #, c-format msgid "Call answered by %s - on hold." msgstr "通話由 %s 接聽 - 保留中。" -#: ../coreapi/callbacks.c:526 +#: ../coreapi/callbacks.c:544 msgid "Call resumed." msgstr "通話已繼續。" -#: ../coreapi/callbacks.c:530 +#: ../coreapi/callbacks.c:548 #, c-format msgid "Call answered by %s." msgstr "通話由 %s 接聽。" -#: ../coreapi/callbacks.c:553 +#: ../coreapi/callbacks.c:571 msgid "Incompatible, check codecs or security settings..." msgstr "" -#: ../coreapi/callbacks.c:558 ../coreapi/callbacks.c:870 +#: ../coreapi/callbacks.c:576 ../coreapi/callbacks.c:888 msgid "Incompatible media parameters." msgstr "" -#: ../coreapi/callbacks.c:588 +#: ../coreapi/callbacks.c:606 msgid "We have been resumed." msgstr "" #. we are being paused -#: ../coreapi/callbacks.c:596 +#: ../coreapi/callbacks.c:614 msgid "We are paused by other party." msgstr "" #. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:630 +#: ../coreapi/callbacks.c:648 msgid "Call is updated by remote." msgstr "" -#: ../coreapi/callbacks.c:746 +#: ../coreapi/callbacks.c:764 msgid "Call terminated." msgstr "通話已終止。" -#: ../coreapi/callbacks.c:774 +#: ../coreapi/callbacks.c:792 msgid "User is busy." msgstr "使用者現正忙碌。" -#: ../coreapi/callbacks.c:775 +#: ../coreapi/callbacks.c:793 msgid "User is temporarily unavailable." msgstr "使用者暫時無法聯繫。" #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:777 +#: ../coreapi/callbacks.c:795 msgid "User does not want to be disturbed." msgstr "使用者不想要被打擾。" -#: ../coreapi/callbacks.c:778 +#: ../coreapi/callbacks.c:796 msgid "Call declined." msgstr "通話被拒接。" -#: ../coreapi/callbacks.c:793 +#: ../coreapi/callbacks.c:811 msgid "Request timeout." msgstr "" -#: ../coreapi/callbacks.c:824 +#: ../coreapi/callbacks.c:842 msgid "Redirected" msgstr "已重新導向" -#: ../coreapi/callbacks.c:879 +#: ../coreapi/callbacks.c:897 msgid "Call failed." msgstr "通話失敗。" -#: ../coreapi/callbacks.c:957 +#: ../coreapi/callbacks.c:975 #, c-format msgid "Registration on %s successful." msgstr "在 %s 註冊成功。" -#: ../coreapi/callbacks.c:958 +#: ../coreapi/callbacks.c:976 #, c-format msgid "Unregistration on %s done." msgstr "在 %s 取消註冊完成。" -#: ../coreapi/callbacks.c:976 +#: ../coreapi/callbacks.c:994 msgid "no response timeout" msgstr "沒有回應逾時" -#: ../coreapi/callbacks.c:979 +#: ../coreapi/callbacks.c:997 #, c-format msgid "Registration on %s failed: %s" msgstr "在 %s 註冊失敗:%s" -#: ../coreapi/callbacks.c:986 +#: ../coreapi/callbacks.c:1004 msgid "Service unavailable, retrying" msgstr "" @@ -1949,7 +1949,7 @@ msgstr "" msgid "Authentication token is %s" msgstr "" -#: ../coreapi/linphonecall.c:3492 +#: ../coreapi/linphonecall.c:3600 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." diff --git a/tester/CMakeLists.txt b/tester/CMakeLists.txt index 3dfe85142..e9583b955 100644 --- a/tester/CMakeLists.txt +++ b/tester/CMakeLists.txt @@ -20,9 +20,14 @@ # ############################################################################ +if(WIN32) + set(GTK2_ADDITIONAL_SUFFIXES "../lib/glib-2.0/include" "../lib/gtk-2.0/include") +endif() find_package(GTK2 2.18 COMPONENTS gtk) set(SOURCE_FILES + common/bc_tester_utils.c + common/bc_tester_utils.h accountmanager.c call_tester.c dtmf_tester.c @@ -31,6 +36,7 @@ set(SOURCE_FILES liblinphone_tester.c log_collection_tester.c message_tester.c + multi_call.c multicast_call_tester.c offeranswer_tester.c player_tester.c @@ -46,7 +52,10 @@ set(SOURCE_FILES video_tester.c ) +add_definitions(-DBC_CONFIG_FILE="config.h") + add_executable(liblinphone_tester ${SOURCE_FILES}) +set_target_properties(liblinphone_tester PROPERTIES LINKER_LANGUAGE CXX) target_include_directories(liblinphone_tester PUBLIC ${CUNIT_INCLUDE_DIRS}) target_link_libraries(liblinphone_tester linphone ${CUNIT_LIBRARIES}) if (GTK2_FOUND) diff --git a/tester/Makefile.am b/tester/Makefile.am index c55c992e3..60a4b0899 100644 --- a/tester/Makefile.am +++ b/tester/Makefile.am @@ -10,32 +10,37 @@ liblinphone_HEADERS = liblinphone_tester.h lib_LTLIBRARIES = liblinphonetester.la -liblinphonetester_la_SOURCES = tester.c \ - setup_tester.c \ - register_tester.c \ - message_tester.c \ +liblinphonetester_la_SOURCES = \ + accountmanager.c \ call_tester.c \ - multicast_call_tester.c \ - presence_tester.c \ - upnp_tester.c \ + dtmf_tester.c \ eventapi_tester.c \ flexisip_tester.c \ - stun_tester.c \ - remote_provisioning_tester.c \ - quality_reporting_tester.c \ log_collection_tester.c \ - transport_tester.c \ - player_tester.c \ - dtmf_tester.c \ - accountmanager.c \ + message_tester.c \ + multi_call.c \ + multicast_call_tester.c \ offeranswer_tester.c \ - video_tester.c + player_tester.c \ + presence_tester.c \ + quality_reporting_tester.c \ + register_tester.c \ + remote_provisioning_tester.c \ + setup_tester.c \ + stun_tester.c \ + transport_tester.c \ + tester.c \ + upnp_tester.c \ + video_tester.c \ + common/bc_tester_utils.c +liblinphonetester_ladir = $(includedir)/linphone +liblinphonetester_la_HEADERS = common/bc_tester_utils.h liblinphonetester_la_LDFLAGS= -no-undefined liblinphonetester_la_LIBADD= ../coreapi/liblinphone.la $(CUNIT_LIBS) AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/coreapi -AM_CFLAGS = $(STRICT_OPTIONS) $(STRICT_OPTIONS_CC) -DIN_LINPHONE $(ORTP_CFLAGS) $(MEDIASTREAMER_CFLAGS) $(CUNIT_CFLAGS) $(BELLESIP_CFLAGS) $(LIBXML2_CFLAGS) $(SQLITE3_CFLAGS) +AM_CFLAGS = -DBC_CONFIG_FILE=\"config.h\" $(STRICT_OPTIONS) $(STRICT_OPTIONS_CC) -DIN_LINPHONE $(ORTP_CFLAGS) $(MEDIASTREAMER_CFLAGS) $(CUNIT_CFLAGS) $(BELLESIP_CFLAGS) $(LIBXML2_CFLAGS) $(SQLITE3_CFLAGS) if BUILD_GTK_UI diff --git a/tester/ZIDCache.xml b/tester/ZIDCache.xml new file mode 100644 index 000000000..6c96b40cc --- /dev/null +++ b/tester/ZIDCache.xml @@ -0,0 +1,2 @@ + +ef7692d0792a67491ae2d44e005dbe0399643d953a2202dd9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899pipo1@pipo.com963c57bb28e62068d2df23e8f9b771932d3c57bb28e62068d2df23e8f9b7719305d9ac653a83c4559cb0ae7394e7cd3b2d3c57bb28e62068d2df23e8f9b771935f9aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b7719302ffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b7719300000069000001e8011234567889643d953a2202ee9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899pipo1@pipo.com123456789012345678901234567890123456765431262068d2df23e8f9b7719325d9ac653a83c4559cb0ae7394e7cd3b2d3c57bb28e62068d2df23e8f9b77193f69aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b7719322ffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b77193000000010000000001 diff --git a/tester/ZIDCacheAlice.xml b/tester/ZIDCacheAlice.xml new file mode 100644 index 000000000..0edd84bd9 --- /dev/null +++ b/tester/ZIDCacheAlice.xml @@ -0,0 +1,2 @@ + +ef7692d0792a67491ae2d44e005dbe0399643d953a2202dd9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899sip:pauline@sip.example.org9111ebeb52e50edcc6fcb3eea1a2d3ae3c2c75d3668923e83c59d0f47245515060f020a3fe11dc2cc0e1e8ed9341b4cd14944db806ca4fc95456bbe45d95c43a5f9aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b77193bcffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b7719300000080000001cf011234567889643d953a2202ee9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899sip:pauline@sip.example.org72d80ab1cad243cf45634980c1d02cfb2df81ce0dd5dfcf1ebeacfc5345a917625d9ac653a83c4559cb0ae7394e7cd3b2d3c57bb28e62068d2df23e8f9b77193f69aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b7719322ffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b771930000000f00000000 diff --git a/tester/ZIDCacheBob.xml b/tester/ZIDCacheBob.xml new file mode 100644 index 000000000..3795074a2 --- /dev/null +++ b/tester/ZIDCacheBob.xml @@ -0,0 +1,4 @@ + +005dbe0399643d953a2202dd + ef7692d0792a67491ae2d44e9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899sip:marie@sip.example.org9111ebeb52e50edcc6fcb3eea1a2d3ae3c2c75d3668923e83c59d0f47245515060f020a3fe11dc2cc0e1e8ed9341b4cd14944db806ca4fc95456bbe45d95c43a5f9aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b77193bcffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b7719300000080000001cf01 + 1234567889643d953a2202ee9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899sip:marie@sip.example.org81e6e6362c34dc974263d1f77cbb9a8d6d6a718330994379099a8fa19fb12faa25d9ac653a83c4559cb0ae7394e7cd3b2d3c57bb28e62068d2df23e8f9b77193f69aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b7719322ffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b771930000002e0000000001 diff --git a/tester/accountmanager.c b/tester/accountmanager.c index 80bc7942e..d46c2064d 100644 --- a/tester/accountmanager.c +++ b/tester/accountmanager.c @@ -33,7 +33,7 @@ typedef struct _Account Account; Account *account_new(LinphoneAddress *identity, const char *unique_id){ char *modified_username; Account *obj=ms_new0(Account,1); - + /* we need to inhibit leak detector because the two LinphoneAddress will remain behond the scope of the test being run */ belle_sip_object_inhibit_leak_detector(TRUE); obj->identity=linphone_address_clone(identity); @@ -82,7 +82,7 @@ void account_manager_destroy(void){ Account *account_manager_get_account(AccountManager *m, const LinphoneAddress *identity){ MSList *it; - + for(it=m->accounts;it!=NULL;it=it->next){ Account *a=(Account*)it->data; if (linphone_address_weak_equal(a->identity,identity)){ @@ -120,15 +120,15 @@ void account_create_on_server(Account *account, const LinphoneProxyConfig *refcf char *tmp; LinphoneAddress *server_addr; LCSipTransports tr; - + vtable.registration_state_changed=account_created_on_server_cb; vtable.auth_info_requested=account_created_auth_requested_cb; - lc=configure_lc_from(&vtable,liblinphone_tester_file_prefix,NULL,account); + lc=configure_lc_from(&vtable,bc_tester_read_dir_prefix,NULL,account); tr.udp_port=LC_SIP_TRANSPORT_RANDOM; tr.tcp_port=LC_SIP_TRANSPORT_RANDOM; tr.tls_port=LC_SIP_TRANSPORT_RANDOM; linphone_core_set_sip_transports(lc,&tr); - + cfg=linphone_core_create_proxy_config(lc); linphone_address_set_secure(tmp_identity, FALSE); linphone_address_set_password(tmp_identity,account->password); @@ -137,7 +137,7 @@ void account_create_on_server(Account *account, const LinphoneProxyConfig *refcf linphone_proxy_config_set_identity(cfg,tmp); ms_free(tmp); linphone_address_unref(tmp_identity); - + server_addr=linphone_address_new(linphone_proxy_config_get_server_addr(refcfg)); linphone_address_set_secure(server_addr, FALSE); linphone_address_set_transport(server_addr,LinphoneTransportTcp); /*use tcp for account creation, we may not have certificates configured at this stage*/ @@ -147,9 +147,9 @@ void account_create_on_server(Account *account, const LinphoneProxyConfig *refcf ms_free(tmp); linphone_address_unref(server_addr); linphone_proxy_config_set_expires(cfg,3600); - + linphone_core_add_proxy_config(lc,cfg); - + if (wait_for_until(lc,NULL,&account->auth_requested,1,10000)==FALSE){ ms_fatal("Account for %s could not be created on server.", linphone_proxy_config_get_identity(refcfg)); } @@ -161,13 +161,13 @@ void account_create_on_server(Account *account, const LinphoneProxyConfig *refcf linphone_address_unref(tmp_identity); ms_free(tmp); linphone_proxy_config_done(cfg); - + ai=linphone_auth_info_new(linphone_address_get_username(account->modified_identity), NULL, account->password,NULL,NULL,linphone_address_get_domain(account->modified_identity)); linphone_core_add_auth_info(lc,ai); linphone_auth_info_destroy(ai); - + if (wait_for_until(lc,NULL,&account->created,1,3000)==FALSE){ ms_fatal("Account for %s is not working on server.", linphone_proxy_config_get_identity(refcfg)); } @@ -187,7 +187,7 @@ LinphoneAddress *account_manager_check_account(AccountManager *m, LinphoneProxyC LinphoneAuthInfo *ai; char *tmp; bool_t create_account=FALSE; - + if (!account){ account=account_new(id_addr,m->unique_id); ms_message("No account for %s exists, going to create one.",identity); @@ -199,7 +199,7 @@ LinphoneAddress *account_manager_check_account(AccountManager *m, LinphoneProxyC tmp=linphone_address_as_string(id_addr); linphone_proxy_config_set_identity(cfg,tmp); ms_free(tmp); - + if (create_account){ account_create_on_server(account,cfg); } @@ -208,7 +208,7 @@ LinphoneAddress *account_manager_check_account(AccountManager *m, LinphoneProxyC account->password,NULL,NULL,linphone_address_get_domain(account->modified_identity)); linphone_core_add_auth_info(lc,ai); linphone_auth_info_destroy(ai); - + linphone_address_unref(id_addr); return account->modified_identity; } diff --git a/tester/call_tester.c b/tester/call_tester.c index 7171e22b9..710696216 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -30,6 +30,9 @@ #ifdef WIN32 #define unlink _unlink +#ifndef F_OK +#define F_OK 00 /*visual studio does not define F_OK*/ +#endif #endif static void srtp_call(void); @@ -272,17 +275,21 @@ bool_t call_with_params2(LinphoneCoreManager* caller_mgr wait_for(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_callee.number_of_LinphoneCallStreamsRunning+1); if (linphone_core_get_media_encryption(caller_mgr->lc) != LinphoneMediaEncryptionNone - && linphone_core_get_media_encryption(callee_mgr->lc) != LinphoneMediaEncryptionNone) { + || linphone_core_get_media_encryption(callee_mgr->lc) != LinphoneMediaEncryptionNone) { /*wait for encryption to be on, in case of zrtp or dtls, it can take a few seconds*/ - if ((linphone_core_get_media_encryption(caller_mgr->lc) == LinphoneMediaEncryptionZRTP) || (linphone_core_get_media_encryption(caller_mgr->lc) == LinphoneMediaEncryptionDTLS)) + if ( (linphone_core_get_media_encryption(caller_mgr->lc) == LinphoneMediaEncryptionZRTP) + || (linphone_core_get_media_encryption(caller_mgr->lc) == LinphoneMediaEncryptionDTLS)) wait_for(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallEncryptedOn,initial_caller.number_of_LinphoneCallEncryptedOn+1); - if ((linphone_core_get_media_encryption(callee_mgr->lc) == LinphoneMediaEncryptionZRTP) || (linphone_core_get_media_encryption(callee_mgr->lc) == LinphoneMediaEncryptionDTLS)) + if ((linphone_core_get_media_encryption(callee_mgr->lc) == LinphoneMediaEncryptionZRTP) + || (linphone_core_get_media_encryption(callee_mgr->lc) == LinphoneMediaEncryptionDTLS) + || (linphone_core_get_media_encryption(caller_mgr->lc) == LinphoneMediaEncryptionDTLS) /*also take care of caller policy*/ ) wait_for(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallEncryptedOn,initial_callee.number_of_LinphoneCallEncryptedOn+1); { const LinphoneCallParams* call_param = linphone_call_get_current_params(linphone_core_get_current_call(callee_mgr->lc)); CU_ASSERT_EQUAL(linphone_call_params_get_media_encryption(call_param),linphone_core_get_media_encryption(caller_mgr->lc)); call_param = linphone_call_get_current_params(linphone_core_get_current_call(caller_mgr->lc)); - CU_ASSERT_EQUAL(linphone_call_params_get_media_encryption(call_param),linphone_core_get_media_encryption(callee_mgr->lc)); + CU_ASSERT_EQUAL(linphone_call_params_get_media_encryption(call_param),linphone_core_get_media_encryption(caller_mgr->lc)); + } } return result; @@ -384,9 +391,11 @@ void simple_call_base(bool_t enable_multicast_recv_side) { belle_sip_object_dump_active_objects(); } } + static void simple_call() { simple_call_base(FALSE); } + static void call_with_timeouted_bye(void) { int begin; int leaked_objects; @@ -429,6 +438,38 @@ static void call_with_timeouted_bye(void) { } } +static void phone_number_normalization(void){ + LinphoneCoreManager *marie = linphone_core_manager_new( "marie_rc"); + LinphoneProxyConfig *cfg = linphone_core_create_proxy_config(marie->lc); + char result[128]; + + linphone_proxy_config_set_dial_prefix(cfg, "33"); + linphone_proxy_config_normalize_number(cfg, "0952636505", result, sizeof(result)); + CU_ASSERT_STRING_EQUAL(result, "+33952636505"); + linphone_proxy_config_normalize_number(cfg, "09 52 63 65 05", result, sizeof(result)); + CU_ASSERT_STRING_EQUAL(result, "+33952636505"); + linphone_proxy_config_normalize_number(cfg, "09-52-63-65-05", result, sizeof(result)); + CU_ASSERT_STRING_EQUAL(result, "+33952636505"); + linphone_proxy_config_normalize_number(cfg, "+31952636505", result, sizeof(result)); + CU_ASSERT_STRING_EQUAL(result, "+31952636505"); + linphone_proxy_config_normalize_number(cfg, "0033952636505", result, sizeof(result)); + CU_ASSERT_STRING_EQUAL(result, "+33952636505"); + linphone_proxy_config_normalize_number(cfg, "0033952636505", result, sizeof(result)); + CU_ASSERT_STRING_EQUAL(result, "+33952636505"); + linphone_proxy_config_normalize_number(cfg, "toto", result, sizeof(result)); + CU_ASSERT_STRING_EQUAL(result, "toto"); + + linphone_proxy_config_set_dial_escape_plus(cfg, TRUE); + linphone_proxy_config_normalize_number(cfg, "0033952636505", result, sizeof(result)); + CU_ASSERT_STRING_EQUAL(result, "0033952636505"); + linphone_proxy_config_normalize_number(cfg, "0952636505", result, sizeof(result)); + CU_ASSERT_STRING_EQUAL(result, "0033952636505"); + linphone_proxy_config_normalize_number(cfg, "+34952636505", result, sizeof(result)); + CU_ASSERT_STRING_EQUAL(result, "0034952636505"); + + linphone_proxy_config_unref(cfg); + linphone_core_manager_destroy(marie); +} static void direct_call_over_ipv6(){ LinphoneCoreManager* marie; @@ -551,7 +592,7 @@ static void multiple_answers_call() { } #endif -static void multiple_answers_call_with_media_relay() { +static void multiple_answers_call_with_media_relay(void) { /* Scenario is this: pauline calls marie, which is registered 2 times. * Both linphones answer at the same time, and only one should get the @@ -1209,39 +1250,41 @@ static void call_paused_resumed_with_loss(void) { CU_ASSERT_TRUE(call(pauline,marie)); call_pauline = linphone_core_get_current_call(pauline->lc); - rtp_session_enable_network_simulation(call_pauline->audiostream->ms.sessions.rtp_session,¶ms); + if (call_pauline){ + rtp_session_enable_network_simulation(call_pauline->audiostream->ms.sessions.rtp_session,¶ms); - /*generate some traffic*/ - wait_for_until(pauline->lc, marie->lc, NULL, 5, 6000); - CHECK_CURRENT_LOSS_RATE(); + /*generate some traffic*/ + wait_for_until(pauline->lc, marie->lc, NULL, 5, 6000); + CHECK_CURRENT_LOSS_RATE(); - /*pause call*/ - linphone_core_pause_call(pauline->lc,call_pauline); - CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallPausing,1)); - CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallPausedByRemote,1)); - CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallPaused,1)); - /*stay in pause a little while in order to generate traffic*/ - wait_for_until(pauline->lc, marie->lc, NULL, 5, 5000); - CHECK_CURRENT_LOSS_RATE(); + /*pause call*/ + linphone_core_pause_call(pauline->lc,call_pauline); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallPausing,1)); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallPausedByRemote,1)); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallPaused,1)); + /*stay in pause a little while in order to generate traffic*/ + wait_for_until(pauline->lc, marie->lc, NULL, 5, 5000); + CHECK_CURRENT_LOSS_RATE(); - /*resume*/ - linphone_core_resume_call(pauline->lc,call_pauline); - CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2)); - CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,2)); - wait_for_until(pauline->lc, marie->lc, NULL, 5, 6000); + /*resume*/ + linphone_core_resume_call(pauline->lc,call_pauline); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2)); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,2)); + wait_for_until(pauline->lc, marie->lc, NULL, 5, 6000); - /*since stats are NOT totally reset during pause, the stats->packet_recv is computed from - the start of call. This test ensures that the loss rate is consistent during the entire call.*/ - CHECK_CURRENT_LOSS_RATE(); - linphone_core_terminate_all_calls(marie->lc); - CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + /*since stats are NOT totally reset during pause, the stats->packet_recv is computed from + the start of call. This test ensures that the loss rate is consistent during the entire call.*/ + CHECK_CURRENT_LOSS_RATE(); + linphone_core_terminate_all_calls(marie->lc); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + } linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } -static bool_t pause_call_1(LinphoneCoreManager* mgr_1,LinphoneCall* call_1,LinphoneCoreManager* mgr_2,LinphoneCall* call_2) { +bool_t pause_call_1(LinphoneCoreManager* mgr_1,LinphoneCall* call_1,LinphoneCoreManager* mgr_2,LinphoneCall* call_2) { stats initial_call_stat_1=mgr_1->stat; stats initial_call_stat_2=mgr_2->stat; linphone_core_pause_call(mgr_1->lc,call_1); @@ -1571,7 +1614,7 @@ static void call_with_declined_video_using_policy(void) { call_with_declined_video_base(TRUE); } -static void video_call_base(LinphoneCoreManager* pauline,LinphoneCoreManager* marie, bool_t using_policy,LinphoneMediaEncryption mode) { +static void video_call_base(LinphoneCoreManager* pauline,LinphoneCoreManager* marie, bool_t using_policy,LinphoneMediaEncryption mode, bool_t callee_video_enabled, bool_t caller_video_enabled) { LinphoneCallTestParams caller_test_params = {0}, callee_test_params = {0}; LinphoneCall* marie_call; LinphoneCall* pauline_call; @@ -1591,10 +1634,24 @@ static void video_call_base(LinphoneCoreManager* pauline,LinphoneCoreManager* ma linphone_core_set_video_policy(marie->lc,&marie_policy); linphone_core_set_video_policy(pauline->lc,&pauline_policy); } + if (callee_video_enabled) { + linphone_core_enable_video_display(marie->lc, TRUE); + linphone_core_enable_video_capture(marie->lc, TRUE); + } else { + linphone_core_enable_video_display(marie->lc, FALSE); + linphone_core_enable_video_capture(marie->lc, FALSE); + } + if (caller_video_enabled) { + linphone_core_enable_video_display(pauline->lc, TRUE); + linphone_core_enable_video_capture(pauline->lc, TRUE); + } else { + linphone_core_enable_video_display(pauline->lc, FALSE); + linphone_core_enable_video_capture(pauline->lc, FALSE); + } if (mode==LinphoneMediaEncryptionDTLS) { /* for DTLS we must access certificates or at least have a directory to store them */ - marie->lc->user_certificates_path = ms_strdup_printf("%s/certificates/marie", liblinphone_tester_file_prefix); - pauline->lc->user_certificates_path = ms_strdup_printf("%s/certificates/pauline", liblinphone_tester_file_prefix); + marie->lc->user_certificates_path = ms_strdup_printf("%s/certificates/marie", bc_tester_read_dir_prefix); + pauline->lc->user_certificates_path = ms_strdup_printf("%s/certificates/pauline", bc_tester_read_dir_prefix); } linphone_core_set_media_encryption(marie->lc,mode); @@ -1617,13 +1674,18 @@ static void video_call_base(LinphoneCoreManager* pauline,LinphoneCoreManager* ma if (callee_test_params.base) linphone_call_params_destroy(callee_test_params.base); if (marie_call && pauline_call ) { - CU_ASSERT_TRUE(linphone_call_log_video_enabled(linphone_call_get_call_log(marie_call))); - CU_ASSERT_TRUE(linphone_call_log_video_enabled(linphone_call_get_call_log(pauline_call))); + if (callee_video_enabled && caller_video_enabled) { + CU_ASSERT_TRUE(linphone_call_log_video_enabled(linphone_call_get_call_log(marie_call))); + CU_ASSERT_TRUE(linphone_call_log_video_enabled(linphone_call_get_call_log(pauline_call))); - /*check video path*/ - linphone_call_set_next_video_frame_decoded_callback(marie_call,linphone_call_cb,marie->lc); - linphone_call_send_vfu_request(marie_call); - CU_ASSERT_TRUE( wait_for(marie->lc,pauline->lc,&marie->stat.number_of_IframeDecoded,1)); + /*check video path*/ + linphone_call_set_next_video_frame_decoded_callback(marie_call,linphone_call_cb,marie->lc); + linphone_call_send_vfu_request(marie_call); + CU_ASSERT_TRUE( wait_for(marie->lc,pauline->lc,&marie->stat.number_of_IframeDecoded,1)); + } else { + CU_ASSERT_FALSE(linphone_call_log_video_enabled(linphone_call_get_call_log(marie_call))); + CU_ASSERT_FALSE(linphone_call_log_video_enabled(linphone_call_get_call_log(pauline_call))); + } liblinphone_tester_check_rtcp(marie,pauline); @@ -1636,7 +1698,7 @@ static void video_call_base(LinphoneCoreManager* pauline,LinphoneCoreManager* ma static void video_call(void) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - video_call_base(marie,pauline,FALSE,LinphoneMediaEncryptionNone); + video_call_base(marie,pauline,FALSE,LinphoneMediaEncryptionNone,TRUE,TRUE); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } @@ -1644,8 +1706,8 @@ static void video_call(void) { static void video_call_zrtp(void) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - if (linphone_core_media_encryption_supported(marie->lc,LinphoneMediaEncryptionDTLS)) { - video_call_base(marie,pauline,FALSE,LinphoneMediaEncryptionZRTP); + if (linphone_core_media_encryption_supported(marie->lc,LinphoneMediaEncryptionZRTP)) { + video_call_base(marie,pauline,FALSE,LinphoneMediaEncryptionZRTP,TRUE,TRUE); } else ms_message("Skipping video_call_zrtp"); linphone_core_manager_destroy(marie); @@ -1656,7 +1718,7 @@ static void video_call_dtls(void) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); if (linphone_core_media_encryption_supported(pauline->lc,LinphoneMediaEncryptionDTLS)) { - video_call_base(marie,pauline,FALSE,LinphoneMediaEncryptionDTLS); + video_call_base(marie,pauline,FALSE,LinphoneMediaEncryptionDTLS,TRUE,TRUE); } else ms_message("Skipping video_call_dtls"); linphone_core_manager_destroy(marie); @@ -1667,7 +1729,23 @@ static void video_call_dtls(void) { static void video_call_using_policy(void) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - video_call_base(marie,pauline,TRUE,LinphoneMediaEncryptionNone); + video_call_base(marie,pauline,TRUE,LinphoneMediaEncryptionNone,TRUE,TRUE); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +static void video_call_using_policy_with_callee_video_disabled(void) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + video_call_base(marie,pauline,TRUE,LinphoneMediaEncryptionNone,FALSE,TRUE); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +static void video_call_using_policy_with_caller_video_disabled(void) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + video_call_base(marie,pauline,TRUE,LinphoneMediaEncryptionNone,TRUE,FALSE); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } @@ -1676,7 +1754,7 @@ static void video_call_no_sdp(void) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); linphone_core_enable_sdp_200_ack(pauline->lc,TRUE); - video_call_base(pauline,marie,FALSE,LinphoneMediaEncryptionNone); + video_call_base(pauline,marie,FALSE,LinphoneMediaEncryptionNone,TRUE,TRUE); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } @@ -1778,6 +1856,22 @@ static void video_call_with_early_media_no_matching_audio_codecs(void) { linphone_core_manager_destroy(pauline); } +static void video_call_limited_bandwidth(void) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + + linphone_core_set_download_bandwidth(pauline->lc, 100); + video_call_base(marie,pauline,FALSE,LinphoneMediaEncryptionNone,TRUE,TRUE); + + /*just to sleep*/ + linphone_core_terminate_all_calls(pauline->lc); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + #endif /*VIDEO_ENABLED*/ static void _call_with_media_relay(bool_t random_ports) { @@ -1932,179 +2026,6 @@ static void call_with_privacy2(void) { linphone_core_manager_destroy(pauline); } -static void call_waiting_indication_with_param(bool_t enable_caller_privacy) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc"); - MSList *iterator; - MSList* lcs; - LinphoneCall* pauline_called_by_marie; - LinphoneCall* pauline_called_by_laure=NULL; - LinphoneCallParams *laure_params=linphone_core_create_default_call_parameters(laure->lc); - LinphoneCallParams *marie_params=linphone_core_create_default_call_parameters(marie->lc); - - if (enable_caller_privacy) - linphone_call_params_set_privacy(marie_params,LinphonePrivacyId); - - lcs=ms_list_append(NULL,marie->lc); - lcs=ms_list_append(lcs,pauline->lc); - lcs=ms_list_append(lcs,laure->lc); - - CU_ASSERT_TRUE(call_with_caller_params(marie,pauline,marie_params)); - pauline_called_by_marie=linphone_core_get_current_call(pauline->lc); - - if (enable_caller_privacy) - linphone_call_params_set_privacy(laure_params,LinphonePrivacyId); - - CU_ASSERT_PTR_NOT_NULL(linphone_core_invite_address_with_params(laure->lc,pauline->identity,laure_params)); - - CU_ASSERT_TRUE(wait_for(laure->lc - ,pauline->lc - ,&pauline->stat.number_of_LinphoneCallIncomingReceived - ,2)); - - CU_ASSERT_EQUAL(laure->stat.number_of_LinphoneCallOutgoingProgress,1); - - - CU_ASSERT_TRUE(wait_for(laure->lc - ,pauline->lc - ,&laure->stat.number_of_LinphoneCallOutgoingRinging - ,1)); - - for (iterator=(MSList *)linphone_core_get_calls(pauline->lc);iterator!=NULL;iterator=iterator->next) { - LinphoneCall *call=(LinphoneCall *)iterator->data; - if (call != pauline_called_by_marie) { - /*fine, this is the call waiting*/ - pauline_called_by_laure=call; - linphone_core_accept_call(pauline->lc,pauline_called_by_laure); - } - } - - CU_ASSERT_TRUE(wait_for(laure->lc - ,pauline->lc - ,&laure->stat.number_of_LinphoneCallConnected - ,1)); - - CU_ASSERT_TRUE(wait_for(pauline->lc - ,marie->lc - ,&marie->stat.number_of_LinphoneCallPausedByRemote - ,1)); - - if (pauline_called_by_laure && enable_caller_privacy ) - CU_ASSERT_EQUAL(linphone_call_params_get_privacy(linphone_call_get_current_params(pauline_called_by_laure)),LinphonePrivacyId); - /*wait a bit for ACK to be sent*/ - wait_for_list(lcs,NULL,0,1000); - linphone_core_terminate_all_calls(pauline->lc); - - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,10000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,10000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallEnd,1,10000)); - - - linphone_core_manager_destroy(marie); - linphone_core_manager_destroy(pauline); - linphone_core_manager_destroy(laure); - ms_list_free(lcs); -} -static void call_waiting_indication(void) { - call_waiting_indication_with_param(FALSE); -} - -static void call_waiting_indication_with_privacy(void) { - call_waiting_indication_with_param(TRUE); -} - -static void simple_conference_base(LinphoneCoreManager* marie, LinphoneCoreManager* pauline, LinphoneCoreManager* laure) { - - stats initial_marie_stat; - stats initial_pauline_stat; - stats initial_laure_stat; - - LinphoneCall* marie_call_pauline; - LinphoneCall* pauline_called_by_marie; - LinphoneCall* marie_call_laure; - - MSList* lcs=ms_list_append(NULL,marie->lc); - lcs=ms_list_append(lcs,pauline->lc); - lcs=ms_list_append(lcs,laure->lc); - - CU_ASSERT_TRUE(call(marie,pauline)); - marie_call_pauline=linphone_core_get_current_call(marie->lc); - pauline_called_by_marie=linphone_core_get_current_call(pauline->lc); - CU_ASSERT_TRUE(pause_call_1(marie,marie_call_pauline,pauline,pauline_called_by_marie)); - - CU_ASSERT_TRUE(call(marie,laure)); - initial_marie_stat=marie->stat; - initial_pauline_stat=pauline->stat; - initial_laure_stat=laure->stat; - - marie_call_laure=linphone_core_get_current_call(marie->lc); - - CU_ASSERT_PTR_NOT_NULL_FATAL(marie_call_laure); - linphone_core_add_to_conference(marie->lc,marie_call_laure); - CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallUpdating,initial_marie_stat.number_of_LinphoneCallUpdating+1,5000)); - - linphone_core_add_to_conference(marie->lc,marie_call_pauline); - - CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallResuming,initial_marie_stat.number_of_LinphoneCallResuming+1,2000)); - - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,initial_pauline_stat.number_of_LinphoneCallStreamsRunning+1,5000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallStreamsRunning,initial_laure_stat.number_of_LinphoneCallStreamsRunning+1,2000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,initial_marie_stat.number_of_LinphoneCallStreamsRunning+2,3000)); - - CU_ASSERT_TRUE(linphone_core_is_in_conference(marie->lc)); - CU_ASSERT_EQUAL(linphone_core_get_conference_size(marie->lc),3); - - /* - * FIXME: check_ice cannot work as it is today because there is no current call for the party that hosts the conference - if (linphone_core_get_firewall_policy(marie->lc) == LinphonePolicyUseIce) { - if (linphone_core_get_firewall_policy(pauline->lc) == LinphonePolicyUseIce) { - check_ice(marie,pauline,LinphoneIceStateHostConnection); - } - if (linphone_core_get_firewall_policy(laure->lc) == LinphonePolicyUseIce) { - check_ice(marie,laure,LinphoneIceStateHostConnection); - } - } - */ - - linphone_core_terminate_conference(marie->lc); - - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,10000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,10000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallEnd,1,10000)); - - - - ms_list_free(lcs); -} -static void simple_conference(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc"); - simple_conference_base(marie,pauline,laure); - linphone_core_manager_destroy(marie); - linphone_core_manager_destroy(pauline); - linphone_core_manager_destroy(laure); -} - -static void simple_conference_with_ice(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc"); - - linphone_core_set_firewall_policy(marie->lc,LinphonePolicyUseIce); - linphone_core_set_stun_server(marie->lc,"stun.linphone.org"); - linphone_core_set_firewall_policy(pauline->lc,LinphonePolicyUseIce); - linphone_core_set_stun_server(pauline->lc,"stun.linphone.org"); - linphone_core_set_firewall_policy(laure->lc,LinphonePolicyUseIce); - linphone_core_set_stun_server(laure->lc,"stun.linphone.org"); - - simple_conference_base(marie,pauline,laure); - linphone_core_manager_destroy(marie); - linphone_core_manager_destroy(pauline); - linphone_core_manager_destroy(laure); -} - static void srtp_call() { call_base(LinphoneMediaEncryptionSRTP,FALSE,FALSE,LinphonePolicyNoFirewall,FALSE); } @@ -2120,6 +2041,10 @@ static void dtls_srtp_call() { call_base(LinphoneMediaEncryptionDTLS,FALSE,FALSE,LinphonePolicyNoFirewall,FALSE); } +static void dtls_srtp_call_with_media_realy() { + call_base(LinphoneMediaEncryptionDTLS,FALSE,TRUE,LinphonePolicyNoFirewall,FALSE); +} + static void dtls_srtp_ice_call() { call_base(LinphoneMediaEncryptionDTLS,FALSE,FALSE,LinphonePolicyUseIce,FALSE); } @@ -2164,12 +2089,12 @@ static void call_with_file_player(void) { LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); LinphonePlayer *player; char hellopath[256]; - char *recordpath = create_filepath(liblinphone_tester_writable_dir_prefix, "record", "wav"); + char *recordpath = create_filepath(bc_tester_writable_dir_prefix, "record-call_with_file_player", "wav"); /*make sure the record file doesn't already exists, otherwise this test will append new samples to it*/ unlink(recordpath); - snprintf(hellopath,sizeof(hellopath), "%s/sounds/hello8000.wav", liblinphone_tester_file_prefix); + snprintf(hellopath,sizeof(hellopath), "%s/sounds/hello8000.wav", bc_tester_read_dir_prefix); /*caller uses files instead of soundcard in order to avoid mixing soundcard input with file played using call's player*/ linphone_core_use_files(marie->lc,TRUE); @@ -2232,19 +2157,22 @@ static void call_with_mkv_file_player(void) { char hellomkv[256]; char hellowav[256]; char *recordpath; +#if !defined(__arm__) && !defined(__arm64__) && !TARGET_IPHONE_SIMULATOR && !defined(ANDROID) double similar; const double threshold = 0.9; +#define DO_AUDIO_CMP +#endif if (!is_format_supported(marie->lc,"mkv")){ ms_warning("Test skipped, no mkv support."); goto end; } - recordpath = create_filepath(liblinphone_tester_writable_dir_prefix, "record", "wav"); + recordpath = create_filepath(bc_tester_writable_dir_prefix, "record-call_with_mkv_file_player", "wav"); /*make sure the record file doesn't already exists, otherwise this test will append new samples to it*/ unlink(recordpath); - snprintf(hellowav,sizeof(hellowav), "%s/sounds/hello8000_mkv_ref.wav", liblinphone_tester_file_prefix); - snprintf(hellomkv,sizeof(hellomkv), "%s/sounds/hello8000.mkv", liblinphone_tester_file_prefix); + snprintf(hellowav,sizeof(hellowav), "%s/sounds/hello8000_mkv_ref.wav", bc_tester_read_dir_prefix); + snprintf(hellomkv,sizeof(hellomkv), "%s/sounds/hello8000.mkv", bc_tester_read_dir_prefix); /*caller uses files instead of soundcard in order to avoid mixing soundcard input with file played using call's player*/ linphone_core_use_files(marie->lc,TRUE); @@ -2274,7 +2202,7 @@ static void call_with_mkv_file_player(void) { linphone_core_terminate_all_calls(marie->lc); CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); -#if !defined(__arm__) && !defined(__arm64__) && !TARGET_IPHONE_SIMULATOR && !defined(ANDROID) +#ifdef DO_AUDIO_CMP CU_ASSERT_TRUE(ms_audio_diff(hellowav,recordpath,&similar,NULL,NULL)==0); CU_ASSERT_TRUE(similar>threshold); CU_ASSERT_TRUE(similar<=1.0); @@ -2322,8 +2250,8 @@ void call_base(LinphoneMediaEncryption mode, bool_t enable_video,bool_t enable_r linphone_core_set_media_encryption(marie->lc,mode); linphone_core_set_media_encryption(pauline->lc,mode); if (mode==LinphoneMediaEncryptionDTLS) { /* for DTLS we must access certificates or at least have a directory to store them */ - marie->lc->user_certificates_path = ms_strdup_printf("%s/certificates/marie", liblinphone_tester_file_prefix); - pauline->lc->user_certificates_path = ms_strdup_printf("%s/certificates/pauline", liblinphone_tester_file_prefix); + marie->lc->user_certificates_path = ms_strdup_printf("%s/certificates/marie", bc_tester_read_dir_prefix); + pauline->lc->user_certificates_path = ms_strdup_printf("%s/certificates/pauline", bc_tester_read_dir_prefix); } linphone_core_set_firewall_policy(marie->lc,policy); @@ -2574,227 +2502,6 @@ static void early_media_call_with_codec_update(void){ early_media_call_with_update_base(TRUE); } -static void simple_call_transfer(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc"); - LinphoneCall* pauline_called_by_marie; - LinphoneCall *marie_calling_pauline; - LinphoneCall *marie_calling_laure; - - char* laure_identity=linphone_address_as_string(laure->identity); - MSList* lcs=ms_list_append(NULL,marie->lc); - lcs=ms_list_append(lcs,pauline->lc); - lcs=ms_list_append(lcs,laure->lc); - - - CU_ASSERT_TRUE(call(marie,pauline)); - marie_calling_pauline=linphone_core_get_current_call(marie->lc); - pauline_called_by_marie=linphone_core_get_current_call(pauline->lc); - - reset_counters(&marie->stat); - reset_counters(&pauline->stat); - reset_counters(&laure->stat); - - - linphone_core_transfer_call(pauline->lc,pauline_called_by_marie,laure_identity); - CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallRefered,1,2000)); - /*marie pausing pauline*/ - CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallPausing,1,2000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallPausedByRemote,1,2000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallPaused,1,2000)); - /*marie calling laure*/ - CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallOutgoingProgress,1,2000)); - - CU_ASSERT_PTR_NOT_NULL(linphone_call_get_transfer_target_call(marie_calling_pauline)); - - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneTransferCallOutgoingInit,1,2000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallIncomingReceived,1,2000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallOutgoingRinging,1,2000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneTransferCallOutgoingProgress,1,2000)); - linphone_core_accept_call(laure->lc,linphone_core_get_current_call(laure->lc)); - CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallConnected,1,2000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallStreamsRunning,1,2000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallConnected,1,2000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,2000)); - - marie_calling_laure=linphone_core_get_current_call(marie->lc); - CU_ASSERT_PTR_NOT_NULL_FATAL(marie_calling_laure); - CU_ASSERT_TRUE(linphone_call_get_transferer_call(marie_calling_laure)==marie_calling_pauline); - - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneTransferCallConnected,1,2000)); - - /*terminate marie to pauline call*/ - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,2000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,2000)); - - linphone_core_manager_destroy(marie); - linphone_core_manager_destroy(pauline); - linphone_core_manager_destroy(laure); - ms_list_free(lcs); -} - -static void unattended_call_transfer(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc"); - LinphoneCall* pauline_called_by_marie; - - char* laure_identity=linphone_address_as_string(laure->identity); - MSList* lcs=ms_list_append(NULL,marie->lc); - lcs=ms_list_append(lcs,pauline->lc); - lcs=ms_list_append(lcs,laure->lc); - - - CU_ASSERT_TRUE(call(marie,pauline)); - pauline_called_by_marie=linphone_core_get_current_call(marie->lc); - - reset_counters(&marie->stat); - reset_counters(&pauline->stat); - reset_counters(&laure->stat); - - linphone_core_transfer_call(marie->lc,pauline_called_by_marie,laure_identity); - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallRefered,1,2000)); - - /*marie ends the call */ - linphone_core_terminate_call(marie->lc,pauline_called_by_marie); - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,2000)); - - /*Pauline starts the transfer*/ - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingInit,1,2000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingProgress,1,2000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallIncomingReceived,1,2000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,2000)); - linphone_core_accept_call(laure->lc,linphone_core_get_current_call(laure->lc)); - CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallConnected,1,2000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallStreamsRunning,1,2000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,2000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,2000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,2000)); - - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,2000)); - - linphone_core_manager_destroy(marie); - linphone_core_manager_destroy(pauline); - linphone_core_manager_destroy(laure); - ms_list_free(lcs); -} - -static void unattended_call_transfer_with_error(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - LinphoneCall* pauline_called_by_marie; - bool_t call_ok=TRUE; - MSList* lcs=ms_list_append(NULL,marie->lc); - - lcs=ms_list_append(lcs,pauline->lc); - - CU_ASSERT_TRUE((call_ok=call(marie,pauline))); - if (call_ok){ - pauline_called_by_marie=linphone_core_get_current_call(marie->lc); - - reset_counters(&marie->stat); - reset_counters(&pauline->stat); - - linphone_core_transfer_call(marie->lc,pauline_called_by_marie,"unknown_user"); - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallRefered,1,2000)); - - /*Pauline starts the transfer*/ - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingInit,1,2000)); - /* and immediately get an error*/ - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallError,1,2000)); - - /*the error must be reported back to marie*/ - CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneTransferCallError,1,2000)); - - /*and pauline should resume the call automatically*/ - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallResuming,1,2000)); - - /*and call should be resumed*/ - CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,2000)); - } - - linphone_core_manager_destroy(marie); - linphone_core_manager_destroy(pauline); - ms_list_free(lcs); -} - - -static void call_transfer_existing_call_outgoing_call(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc"); - LinphoneCall* marie_call_pauline; - LinphoneCall* pauline_called_by_marie; - LinphoneCall* marie_call_laure; - LinphoneCall* laure_called_by_marie; - LinphoneCall* lcall; - bool_t call_ok=TRUE; - const MSList* calls; - MSList* lcs=ms_list_append(NULL,marie->lc); - - lcs=ms_list_append(lcs,pauline->lc); - lcs=ms_list_append(lcs,laure->lc); - - /*marie call pauline*/ - CU_ASSERT_TRUE((call_ok=call(marie,pauline))); - if (call_ok){ - marie_call_pauline=linphone_core_get_current_call(marie->lc); - pauline_called_by_marie=linphone_core_get_current_call(pauline->lc); - /*marie pause pauline*/ - CU_ASSERT_TRUE(pause_call_1(marie,marie_call_pauline,pauline,pauline_called_by_marie)); - - /*marie call laure*/ - CU_ASSERT_TRUE(call(marie,laure)); - marie_call_laure=linphone_core_get_current_call(marie->lc); - laure_called_by_marie=linphone_core_get_current_call(laure->lc); - /*marie pause laure*/ - CU_ASSERT_TRUE(pause_call_1(marie,marie_call_laure,laure,laure_called_by_marie)); - - reset_counters(&marie->stat); - reset_counters(&pauline->stat); - reset_counters(&laure->stat); - - - linphone_core_transfer_call_to_another(marie->lc,marie_call_pauline,marie_call_laure); - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallRefered,1,2000)); - - /*pauline pausing marie*/ - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallPausing,1,4000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallPaused,1,4000)); - /*pauline calling laure*/ - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingProgress,1,2000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneTransferCallOutgoingInit,1,2000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallIncomingReceived,1,2000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,2000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneTransferCallOutgoingProgress,1,2000)); - - /*laure accept call*/ - for(calls=linphone_core_get_calls(laure->lc);calls!=NULL;calls=calls->next) { - lcall = (LinphoneCall*)calls->data; - if (linphone_call_get_state(lcall) == LinphoneCallIncomingReceived) { - CU_ASSERT_EQUAL(linphone_call_get_replaced_call(lcall),laure_called_by_marie); - linphone_core_accept_call(laure->lc,lcall); - break; - } - } - CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallConnected,1,2000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallStreamsRunning,1,2000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,2000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,2000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneTransferCallConnected,1,2000)); - - /*terminate marie to pauline/laure call*/ - CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,2000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,2,2000)); - CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallEnd,1,2000)); - } - - linphone_core_manager_destroy(marie); - linphone_core_manager_destroy(pauline); - linphone_core_manager_destroy(laure); - ms_list_free(lcs); -} static void check_call_state(LinphoneCoreManager* mgr,LinphoneCallState state) { CU_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(mgr->lc)); @@ -2876,7 +2583,7 @@ static void call_established_with_rejected_incoming_reinvite(void) { bool_t call_ok=FALSE; CU_ASSERT_TRUE((call_ok=call(pauline,marie))); - + if (call_ok){ /*wait for ACK to be transmitted before going to reINVITE*/ @@ -2966,31 +2673,33 @@ static void call_redirect(void){ static void call_established_with_rejected_reinvite_with_error(void) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + bool_t call_ok=TRUE; - CU_ASSERT_TRUE(call(pauline,marie)); + CU_ASSERT_TRUE((call_ok=call(pauline,marie))); - linphone_core_enable_payload_type(pauline->lc,linphone_core_find_payload_type(pauline->lc,"PCMA",8000,1),TRUE); /*add PCMA*/ + if (call_ok){ + linphone_core_enable_payload_type(pauline->lc,linphone_core_find_payload_type(pauline->lc,"PCMA",8000,1),TRUE); /*add PCMA*/ + + sal_enable_unconditional_answer(marie->lc->sal,TRUE); + + linphone_core_update_call( pauline->lc + ,linphone_core_get_current_call(pauline->lc) + ,linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc))); - sal_enable_unconditional_answer(marie->lc->sal,TRUE); + CU_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2)); - linphone_core_update_call( pauline->lc - ,linphone_core_get_current_call(pauline->lc) - ,linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc))); + CU_ASSERT_EQUAL(linphone_call_get_reason(linphone_core_get_current_call(pauline->lc)),LinphoneReasonTemporarilyUnavailable); /*might be change later*/ + CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallStreamsRunning,1); + check_call_state(pauline,LinphoneCallStreamsRunning); + check_call_state(marie,LinphoneCallStreamsRunning); - CU_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2)); - - CU_ASSERT_EQUAL(linphone_call_get_reason(linphone_core_get_current_call(pauline->lc)),LinphoneReasonTemporarilyUnavailable); /*might be change later*/ - - CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallStreamsRunning,1); - check_call_state(pauline,LinphoneCallStreamsRunning); - check_call_state(marie,LinphoneCallStreamsRunning); - - /*just to sleep*/ - linphone_core_terminate_all_calls(pauline->lc); - CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + /*just to sleep*/ + linphone_core_terminate_all_calls(pauline->lc); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + } linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); @@ -3008,9 +2717,7 @@ static void call_rejected_because_wrong_credentials_with_params(const char* user linphone_core_set_user_agent(marie->lc,user_agent,NULL); } if (!enable_auth_req_cb) { - - ((LinphoneCoreVTable*)(marie->lc->vtables->data))->auth_info_requested=NULL; - + ((VTableReference*)(marie->lc->vtable_refs->data))->vtable->auth_info_requested=NULL; linphone_core_add_auth_info(marie->lc,wrong_auth_info); } @@ -3095,9 +2802,9 @@ static void multiple_early_media(void) { CU_ASSERT_PTR_NOT_NULL(pauline_call); CU_ASSERT_PTR_NOT_NULL(marie1_call); CU_ASSERT_PTR_NOT_NULL(marie2_call); - + if (pauline_call && marie1_call && marie2_call){ - + /*wait a bit that streams are established*/ wait_for_list(lcs,&dummy,1,6000); CU_ASSERT_TRUE(linphone_call_get_audio_stats(pauline_call)->download_bandwidth>70); @@ -3146,6 +2853,7 @@ static void record_call(const char *filename, bool_t enableVideo) { const char **formats, *format; char *filepath; int dummy=0, i; + bool_t call_succeeded = FALSE; #if defined(HAVE_OPENH264) && defined(ANDROID) ms_init(); @@ -3175,12 +2883,12 @@ static void record_call(const char *filename, bool_t enableVideo) { formats = linphone_core_get_supported_file_formats(marie->lc); for(i=0, format = formats[0]; format != NULL; i++, format = formats[i]) { - filepath = create_filepath(liblinphone_tester_writable_dir_prefix, filename, format); + filepath = create_filepath(bc_tester_writable_dir_prefix, filename, format); remove(filepath); linphone_call_params_set_record_file(marieParams, filepath); - if((CU_ASSERT_TRUE(call_with_params(marie, pauline, marieParams, paulineParams))) - && (CU_ASSERT_PTR_NOT_NULL(callInst = linphone_core_get_current_call(marie->lc)))) { - + CU_ASSERT_TRUE(call_succeeded = call_with_params(marie, pauline, marieParams, paulineParams)); + CU_ASSERT_PTR_NOT_NULL(callInst = linphone_core_get_current_call(marie->lc)); + if ((call_succeeded == TRUE) && (callInst != NULL)) { ms_message("call_recording(): start recording into %s", filepath); linphone_call_start_recording(callInst); wait_for_until(marie->lc,pauline->lc,&dummy,1,5000); @@ -3213,8 +2921,9 @@ static void video_call_snapshot(void) { LinphoneCallParams *marieParams = linphone_core_create_default_call_parameters(marie->lc); LinphoneCallParams *paulineParams = linphone_core_create_default_call_parameters(pauline->lc); LinphoneCall *callInst = NULL; - char *filename = create_filepath(liblinphone_tester_writable_dir_prefix, "snapshot", "jpeg"); + char *filename = create_filepath(bc_tester_writable_dir_prefix, "snapshot", "jpeg"); int dummy = 0; + bool_t call_succeeded = FALSE; linphone_core_enable_video_capture(marie->lc, TRUE); linphone_core_enable_video_display(marie->lc, TRUE); @@ -3223,8 +2932,9 @@ static void video_call_snapshot(void) { linphone_call_params_enable_video(marieParams, TRUE); linphone_call_params_enable_video(paulineParams, TRUE); - if((CU_ASSERT_TRUE(call_with_params(marie, pauline, marieParams, paulineParams))) - && (CU_ASSERT_PTR_NOT_NULL(callInst = linphone_core_get_current_call(marie->lc)))) { + CU_ASSERT_TRUE(call_succeeded = call_with_params(marie, pauline, marieParams, paulineParams)); + CU_ASSERT_PTR_NOT_NULL(callInst = linphone_core_get_current_call(marie->lc)); + if((call_succeeded == TRUE) && (callInst != NULL)) { linphone_call_take_video_snapshot(callInst, filename); wait_for_until(marie->lc, pauline->lc, &dummy, 1, 5000); CU_ASSERT_EQUAL(access(filename, F_OK), 0); @@ -3569,9 +3279,8 @@ static void call_with_paused_no_sdp_on_resume() { } } - -static void call_with_early_media_and_no_sdp_in_200(){ -LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); +static void early_media_without_sdp_in_200_base( bool_t use_video, bool_t use_ice ){ + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new("pauline_rc"); MSList* lcs = NULL; LinphoneCall* marie_call; @@ -3583,16 +3292,24 @@ LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); lcs = ms_list_append(lcs,marie->lc); lcs = ms_list_append(lcs,pauline->lc); + if (use_ice){ + linphone_core_set_firewall_policy(marie->lc, LinphonePolicyUseIce); + linphone_core_set_stun_server(marie->lc, "stun.linphone.org"); + } /* Marie calls Pauline, and after the call has rung, transitions to an early_media session */ params = linphone_core_create_default_call_parameters(marie->lc); - linphone_call_params_enable_video(params, TRUE); - linphone_core_enable_video_capture(pauline->lc, TRUE); - linphone_core_enable_video_display(pauline->lc, TRUE); - linphone_core_enable_video_capture(marie->lc, TRUE); - linphone_core_enable_video_display(marie->lc, FALSE); + if( use_video){ + + linphone_call_params_enable_video(params, TRUE); + + linphone_core_enable_video_capture(pauline->lc, TRUE); + linphone_core_enable_video_display(pauline->lc, TRUE); + linphone_core_enable_video_capture(marie->lc, TRUE); + linphone_core_enable_video_display(marie->lc, FALSE); + } marie_call = linphone_core_invite_address_with_params(marie->lc, pauline->identity, params); marie_call_log = linphone_call_get_call_log(marie_call); @@ -3619,8 +3336,6 @@ LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); connected_time=ms_get_cur_time_ms(); CU_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallStreamsRunning, 1,3000)); - ms_error("Streams running= %d", marie->stat.number_of_LinphoneCallStreamsRunning); - CU_ASSERT_EQUAL(marie_call, linphone_core_get_current_call(marie->lc)); liblinphone_tester_check_rtcp(marie, pauline); @@ -3640,14 +3355,26 @@ LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); linphone_core_manager_destroy(pauline); } +static void call_with_early_media_and_no_sdp_in_200_with_video(){ + early_media_without_sdp_in_200_base(TRUE, FALSE); +} + +static void call_with_early_media_and_no_sdp_in_200(){ + early_media_without_sdp_in_200_base(FALSE, FALSE); +} + +static void call_with_early_media_ice_and_no_sdp_in_200(){ + early_media_without_sdp_in_200_base(FALSE, TRUE); +} + static void call_with_generic_cn(void) { int begin; int leaked_objects; LinphoneCoreManager* marie; LinphoneCoreManager* pauline; LinphoneCall *pauline_call; - char *audio_file_with_silence=ms_strdup_printf("%s/%s",liblinphone_tester_file_prefix,"sounds/ahbahouaismaisbon.wav"); - char *recorded_file=ms_strdup_printf("%s/%s",liblinphone_tester_writable_dir_prefix,"result.wav"); + char *audio_file_with_silence=ms_strdup_printf("%s/%s",bc_tester_read_dir_prefix,"sounds/ahbahouaismaisbon.wav"); + char *recorded_file=ms_strdup_printf("%s/%s",bc_tester_writable_dir_prefix,"result.wav"); belle_sip_object_enable_leak_detector(TRUE); begin=belle_sip_object_get_object_count(); @@ -3709,6 +3436,18 @@ void static call_state_changed_2(LinphoneCore *lc, LinphoneCall *call, LinphoneC linphone_core_set_sip_transports(lc,&sip_tr); } } +void static call_state_changed_3(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *msg){ +/*just to check multi listener in such situation*/ + char* to=linphone_address_as_string(linphone_call_get_call_log(call)->to); + char* from=linphone_address_as_string(linphone_call_get_call_log(call)->from); + ms_message("Third call listener reports: %s call from [%s] to [%s], new state is [%s]" ,linphone_call_get_call_log(call)->dir==LinphoneCallIncoming?"Incoming":"Outgoing" + ,from + ,to + ,linphone_call_state_to_string(cstate)); + ms_free(to); + ms_free(from); +} + static void call_with_transport_change_base(bool_t succesfull_call) { int begin; @@ -3724,6 +3463,9 @@ static void call_with_transport_change_base(bool_t succesfull_call) { marie = linphone_core_manager_new("marie_rc"); pauline = linphone_core_manager_new( "pauline_rc"); linphone_core_add_listener(marie->lc,v_table); + v_table = linphone_core_v_table_new(); + v_table->call_state_changed=call_state_changed_3; + linphone_core_add_listener(marie->lc,v_table); sip_tr.udp_port = 0; sip_tr.tcp_port = 45875; @@ -3761,6 +3503,7 @@ static void unsucessfull_call_with_transport_change_after_released(void) { } test_t call_tests[] = { + { "Phone number normalization", phone_number_normalization }, { "Early declined call", early_declined_call }, { "Call declined", call_declined }, { "Cancelled call", cancelled_call }, @@ -3792,6 +3535,7 @@ test_t call_tests[] = { { "SRTP call", srtp_call }, { "ZRTP call",zrtp_call}, { "DTLS SRTP call",dtls_srtp_call}, + { "DTLS SRTP call with media relay", dtls_srtp_call_with_media_realy}, { "ZRTP video call",zrtp_video_call}, { "SRTP call with declined srtp", call_with_declined_srtp }, { "Call with file player", call_with_file_player}, @@ -3802,6 +3546,8 @@ test_t call_tests[] = { { "Simple ZRTP video call",video_call_zrtp}, { "Simple DTLS video call",video_call_dtls}, { "Simple video call using policy",video_call_using_policy}, + { "Video call using policy with callee video disabled", video_call_using_policy_with_callee_video_disabled }, + { "Video call using policy with caller video disabled", video_call_using_policy_with_caller_video_disabled }, { "Video call without SDP",video_call_no_sdp}, { "SRTP ice video call", srtp_video_ice_call }, { "ZRTP ice video call", zrtp_video_ice_call }, @@ -3820,6 +3566,7 @@ test_t call_tests[] = { { "DTLS SRTP video call",dtls_srtp_video_call}, { "DTLS SRTP ice video call",dtls_srtp_ice_video_call}, { "DTLS SRTP ice video call with relay",dtls_srtp_ice_video_call_with_relay}, + { "Video call with limited bandwidth", video_call_limited_bandwidth}, #endif { "SRTP ice call", srtp_ice_call }, { "ZRTP ice call", zrtp_ice_call }, @@ -3831,14 +3578,6 @@ test_t call_tests[] = { { "Call rejected because of wrong credential", call_rejected_because_wrong_credentials}, { "Call rejected without 403 because of wrong credential", call_rejected_without_403_because_wrong_credentials}, { "Call rejected without 403 because of wrong credential and no auth req cb", call_rejected_without_403_because_wrong_credentials_no_auth_req_cb}, - { "Call waiting indication", call_waiting_indication }, - { "Call waiting indication with privacy", call_waiting_indication_with_privacy }, - { "Simple conference", simple_conference }, - { "Simple conference with ICE",simple_conference_with_ice}, - { "Simple call transfer", simple_call_transfer }, - { "Unattended call transfer", unattended_call_transfer }, - { "Unattended call transfer with error", unattended_call_transfer_with_error }, - { "Call transfer existing call outgoing call", call_transfer_existing_call_outgoing_call }, { "Call with ICE", call_with_ice }, { "Call with ICE without SDP", call_with_ice_no_sdp }, { "Call with ICE (random ports)", call_with_ice_random_ports }, @@ -3855,7 +3594,9 @@ test_t call_tests[] = { { "Call with in-dialog codec change", call_with_in_dialog_codec_change }, { "Call with in-dialog codec change no sdp", call_with_in_dialog_codec_change_no_sdp }, { "Call with pause no SDP on resume", call_with_paused_no_sdp_on_resume }, - { "Call with early media and no SDP on 200 Ok", call_with_early_media_and_no_sdp_in_200 }, + { "Call with early media and no SDP in 200 Ok", call_with_early_media_and_no_sdp_in_200 }, + { "Call with early media and no SDP in 200 Ok with video", call_with_early_media_and_no_sdp_in_200_with_video }, + { "Call with ICE and no SDP in 200 OK", call_with_early_media_ice_and_no_sdp_in_200}, { "Call with custom supported tags", call_with_custom_supported_tags }, { "Call log from taken from asserted id",call_log_from_taken_from_p_asserted_id}, { "Incoming INVITE with invalid SDP",incoming_invite_with_invalid_sdp}, @@ -3868,7 +3609,7 @@ test_t call_tests[] = { }; test_suite_t call_test_suite = { - "Call", + "Single Call", NULL, NULL, sizeof(call_tests) / sizeof(call_tests[0]), diff --git a/tester/liblinphone_completion b/tester/common/bc_completion similarity index 91% rename from tester/liblinphone_completion rename to tester/common/bc_completion index a0d05f3e0..b155f0c85 100644 --- a/tester/liblinphone_completion +++ b/tester/common/bc_completion @@ -16,9 +16,9 @@ # Created by Gautier Pelloux-Prayer on 2014/10/24. # This script adds auto-completion for liblinphone_tester binary for Bash and -# zsh. To use it, just type: `source liblinphone_completion`, then use -# `./liblinphone_tester [tab] to get auto-completions. To use it permanently, -# source this file in your .rc file +# Zsh. To use it, just type: `source liblinphone_completion`, then for each +# supported exectuable (see end of file), you will get auto-completions. +# To use it permanently, source this file in your .rc file (.bashrc or .zshrc). _liblinphone_complete() { local completions command_requiring_argument prev_arg latest_arg available_tasks has_not_set_suite suite_name @@ -102,7 +102,9 @@ _liblinphone_complete() { fi } -for tester in liblinphone_tester mediastreamer2_tester belle_sip_tester; do +for tester in liblinphone_tester mediastreamer2_tester belle_sip_tester pcap_playback \ + bench mediastream msaudiocmp mtudiscover videodisplay linphone lpc2xml_test \ + lp-gen-wrappers xml2lpc_test; do if [ -n "$BASH_VERSION" ]; then complete -F _liblinphone_complete $tester elif [ -n "$ZSH_VERSION" ]; then diff --git a/tester/common/bc_tester_utils.c b/tester/common/bc_tester_utils.c new file mode 100644 index 000000000..b66ca7935 --- /dev/null +++ b/tester/common/bc_tester_utils.c @@ -0,0 +1,362 @@ +/* +tester - liblinphone test suite +Copyright (C) 2013 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, see . +*/ + + +/* this must be provided at compile time*/ +#include BC_CONFIG_FILE + +#include "bc_tester_utils.h" + +#include +#include +#include "CUnit/Automated.h" + +#if WINAPI_FAMILY_PHONE_APP +const char *bc_tester_read_dir_prefix="Assets"; +#elif defined(__QNX__) +const char *bc_tester_read_dir_prefix="./app/native/assets/"; +#else +const char *bc_tester_read_dir_prefix="."; +#endif + +/* TODO: have the same "static" for QNX and windows as above? */ +#ifdef ANDROID +const char *bc_tester_writable_dir_prefix = "/data/data/org.linphone.tester/cache"; +#else +const char *bc_tester_writable_dir_prefix = "."; +#endif + +static test_suite_t **test_suite = NULL; +static int nb_test_suites = 0; + +#ifdef HAVE_CU_CURSES +#include "CUnit/CUCurses.h" +static unsigned char curses = 0; +#endif + +char* xml_file = "CUnitAutomated-Results.xml"; +int xml_enabled = 0; +char * suite_name; +char * test_name; +void (*tester_printf_va)(int level, const char *fmt, va_list args); +int verbosity_info; +int verbosity_error; + +static void tester_printf(int level, const char *fmt, ...) { + va_list args; + va_start (args, fmt); + tester_printf_va(level, fmt, args); + va_end (args); +} + +int bc_tester_run_suite(test_suite_t *suite) { + int i; + + CU_pSuite pSuite = CU_add_suite(suite->name, suite->init_func, suite->cleanup_func); + + for (i = 0; i < suite->nb_tests; i++) { + if (NULL == CU_add_test(pSuite, suite->tests[i].name, suite->tests[i].func)) { + return CU_get_error(); + } + } + + return 0; +} + +const char * bc_tester_suite_name(int suite_index) { + if (suite_index >= nb_test_suites) return NULL; + return test_suite[suite_index]->name; +} + +int bc_tester_suite_index(const char *suite_name) { + int i; + + for (i = 0; i < nb_test_suites; i++) { + if ((strcmp(suite_name, test_suite[i]->name) == 0) && (strlen(suite_name) == strlen(test_suite[i]->name))) { + return i; + } + } + + return -1; +} + +int bc_tester_nb_suites() { + return nb_test_suites; +} + +const char * bc_tester_test_name(const char *suite_name, int test_index) { + int suite_index = bc_tester_suite_index(suite_name); + if ((suite_index < 0) || (suite_index >= nb_test_suites)) return NULL; + if (test_index >= test_suite[suite_index]->nb_tests) return NULL; + return test_suite[suite_index]->tests[test_index].name; +} + +int bc_tester_nb_tests(const char *suite_name) { + int i = bc_tester_suite_index(suite_name); + if (i < 0) return 0; + return test_suite[i]->nb_tests; +} + +void bc_tester_list_suites() { + int j; + for(j=0;jpName); +} + +static void suite_cleanup_failure_message_handler(const CU_pSuite pSuite) { + tester_printf(verbosity_error,"Suite cleanup failed for [%s].", pSuite->pName); +} + +#ifdef HAVE_CU_GET_SUITE +static void suite_start_message_handler(const CU_pSuite pSuite) { + tester_printf(verbosity_info,"Suite [%s] started\n", pSuite->pName); +} +static void suite_complete_message_handler(const CU_pSuite pSuite, const CU_pFailureRecord pFailure) { + tester_printf(verbosity_info,"Suite [%s] ended\n", pSuite->pName); +} + +static void test_start_message_handler(const CU_pTest pTest, const CU_pSuite pSuite) { + tester_printf(verbosity_info,"Suite [%s] Test [%s] started", pSuite->pName,pTest->pName); +} + +/*derivated from cunit*/ +static void test_complete_message_handler(const CU_pTest pTest, + const CU_pSuite pSuite, + const CU_pFailureRecord pFailureList) { + int i; + char * result = malloc(sizeof(char)*2048);//not very pretty but... + CU_pFailureRecord pFailure = pFailureList; + sprintf(result, "Suite [%s] Test [%s]", pSuite->pName, pTest->pName); + if (pFailure) { + strncat(result, " failed:", strlen(" failed:")); + for (i = 1 ; (NULL != pFailure) ; pFailure = pFailure->pNext, i++) { + sprintf(result, "%s\n %d. %s:%u - %s", result, i, + (NULL != pFailure->strFileName) ? pFailure->strFileName : "", + pFailure->uiLineNumber, + (NULL != pFailure->strCondition) ? pFailure->strCondition : ""); + } + } else { + strncat(result, " passed", strlen(" passed")); + } + tester_printf(verbosity_info,"%s\n", result); + free(result); +} +#endif + +int bc_tester_run_tests(const char *suite_name, const char *test_name) { + int i; + + /* initialize the CUnit test registry */ + if (CUE_SUCCESS != CU_initialize_registry()) + return CU_get_error(); + + for (i = 0; i < nb_test_suites; i++) { + bc_tester_run_suite(test_suite[i]); + } +#ifdef HAVE_CU_GET_SUITE + CU_set_suite_start_handler(suite_start_message_handler); + CU_set_suite_complete_handler(suite_complete_message_handler); + CU_set_test_start_handler(test_start_message_handler); + CU_set_test_complete_handler(test_complete_message_handler); +#endif + CU_set_all_test_complete_handler(all_complete_message_handler); + CU_set_suite_init_failure_handler(suite_init_failure_message_handler); + CU_set_suite_cleanup_failure_handler(suite_cleanup_failure_message_handler); + + if( xml_enabled != 0 ){ + CU_automated_run_tests(); + } else { + +#ifndef HAVE_CU_GET_SUITE + if( suite_name ){ + tester_printf(verbosity_info, "Tester compiled without CU_get_suite() function, running all tests instead of suite '%s'", suite_name); + } +#else + if (suite_name){ + CU_pSuite suite; + suite=CU_get_suite(suite_name); + if (!suite) { + tester_printf(verbosity_error, "Could not find suite '%s'. Available suites are:", suite_name); + bc_tester_list_suites(); + return -1; + } else if (test_name) { + CU_pTest test=CU_get_test_by_name(test_name, suite); + if (!test) { + tester_printf(verbosity_error, "Could not find test '%s' in suite '%s'. Available tests are:", test_name, suite_name); + // do not use suite_name here, since this method is case sensitive + bc_tester_list_tests(suite->pName); + return -2; + } else { + CU_ErrorCode err= CU_run_test(suite, test); + if (err != CUE_SUCCESS) tester_printf(verbosity_error, "CU_basic_run_test error %d", err); + } + } else { + CU_run_suite(suite); + } + } + else +#endif + { +#ifdef HAVE_CU_CURSES + if (curses) { + /* Run tests using the CUnit curses interface */ + CU_curses_run_tests(); + } + else +#endif + { + /* Run all tests using the CUnit Basic interface */ + CU_run_all_tests(); + } + } + } + return CU_get_number_of_tests_failed()!=0; + +} + + +void bc_tester_helper(const char *name, const char* additionnal_helper) { + fprintf(stdout,"%s --help\n" + "\t\t\t--list-suites\n" + "\t\t\t--list-tests \n" + "\t\t\t--suite \n" + "\t\t\t--test \n" +#ifdef HAVE_CU_CURSES + "\t\t\t--curses\n" +#endif + "\t\t\t--xml\n" + "\t\t\t--xml-file \n" + "And additionally:\n" + "%s" + , name + , additionnal_helper); +} + +void bc_tester_init(void (*ftester_printf)(int level, const char *fmt, va_list args), int iverbosity_info, int iverbosity_error) { + tester_printf_va = ftester_printf; + verbosity_error = iverbosity_error; + verbosity_info = iverbosity_info; +} + +int bc_tester_parse_args(int argc, char **argv, int argid) +{ + int i = argid; + + if (strcmp(argv[i],"--help")==0){ + return -1; + } else if (strcmp(argv[i],"--test")==0){ + CHECK_ARG("--test", ++i, argc); + test_name=argv[i]; + }else if (strcmp(argv[i],"--suite")==0){ + CHECK_ARG("--suite", ++i, argc); + suite_name=argv[i]; + } else if (strcmp(argv[i],"--list-suites")==0){ + bc_tester_list_suites(); + return 0; + } else if (strcmp(argv[i],"--list-tests")==0){ + CHECK_ARG("--list-tests", ++i, argc); + suite_name = argv[i]; + bc_tester_list_tests(suite_name); + return 0; + } else if (strcmp(argv[i], "--xml-file") == 0){ + CHECK_ARG("--xml-file", ++i, argc); + xml_file = argv[i]; + xml_enabled = 1; + } else if (strcmp(argv[i], "--xml") == 0){ + xml_enabled = 1; + }else { + fprintf(stderr, "Unknown option \"%s\"\n", argv[i]); + return -1; + } + + if( xml_enabled && (suite_name || test_name) ){ + fprintf(stderr, "Cannot use both XML and specific test suite\n"); + return -1; + } + + /* returns number of arguments read + 1 */ + return i - argid + 1; +} + +int bc_tester_start() { + int ret; + if( xml_enabled ){ + char * xml_tmp_file = malloc(sizeof(char) * (strlen(xml_file) + strlen(".tmp") + 1)); + sprintf(xml_tmp_file, "%s.tmp", xml_file); + CU_set_output_filename(xml_tmp_file); + free(xml_tmp_file); + } + + ret = bc_tester_run_tests(suite_name, test_name); + + return ret; +} +void bc_tester_add_suite(test_suite_t *suite) { + if (test_suite == NULL) { + test_suite = (test_suite_t **)malloc(10 * sizeof(test_suite_t *)); + } + test_suite[nb_test_suites] = suite; + nb_test_suites++; + if ((nb_test_suites % 10) == 0) { + test_suite = (test_suite_t **)realloc(test_suite, (nb_test_suites + 10) * sizeof(test_suite_t *)); + } +} + +void bc_tester_uninit() { + /* Redisplay list of failed tests on end */ + if (CU_get_number_of_failure_records()){ + CU_basic_show_failures(CU_get_failure_list()); + tester_printf(verbosity_info,""); /*add missing final newline*/ + } + CU_cleanup_registry(); + + if( xml_enabled ){ + /*create real xml file only if tester did not crash*/ + char * xml_tmp_file = malloc(sizeof(char) * (strlen(xml_file) + strlen(".tmp-Results.xml") + 1)); + sprintf(xml_tmp_file, "%s.tmp-Results.xml", xml_file); + rename(xml_tmp_file, xml_file); + free(xml_tmp_file); + } + + if (test_suite != NULL) { + free(test_suite); + test_suite = NULL; + nb_test_suites = 0; + } +} diff --git a/tester/common/bc_tester_utils.h b/tester/common/bc_tester_utils.h new file mode 100644 index 000000000..ef14d98fd --- /dev/null +++ b/tester/common/bc_tester_utils.h @@ -0,0 +1,77 @@ +/* + tester - liblinphone test suite + Copyright (C) 2013 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, see . +*/ + + +#ifndef TESTER_UTILS_H +#define TESTER_UTILS_H + +#include "CUnit/Basic.h" +#include + +extern const char *bc_tester_read_dir_prefix; +extern const char *bc_tester_writable_dir_prefix; + +typedef void (*test_function_t)(void); +typedef int (*test_suite_function_t)(const char *name); + +typedef struct { + const char *name; + test_function_t func; +} test_t; + +typedef struct { + const char *name; + CU_InitializeFunc init_func; + CU_CleanupFunc cleanup_func; + int nb_tests; + test_t *tests; +} test_suite_t; + +#ifdef __cplusplus +extern "C" { +#endif + + +#define CHECK_ARG(argument, index, argc) \ +if(index >= argc) { \ +fprintf(stderr, "Missing argument for \"%s\"\n", argument); \ +return -1; \ +} \ + +void bc_tester_init(void (*ftester_printf)(int level, const char *fmt, va_list args) + , int verbosity_info, int verbosity_error); +void bc_tester_helper(const char *name, const char* additionnal_helper); +int bc_tester_parse_args(int argc, char** argv, int argid); +int bc_tester_start(); +void bc_tester_add_suite(test_suite_t *suite); +void bc_tester_uninit(); + +int bc_tester_nb_suites(); +int bc_tester_nb_tests(const char* name); +void bc_tester_list_suites(); +void bc_tester_list_tests(const char *suite_name); +const char * bc_tester_suite_name(int suite_index); +const char * bc_tester_test_name(const char *suite_name, int test_index); +int bc_tester_run_suite(test_suite_t *suite); +int bc_tester_run_tests(const char *suite_name, const char *test_name); +int bc_tester_suite_index(const char *suite_name); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/tester/flexisip_tester.c b/tester/flexisip_tester.c index 948df8fba..a5e0f3803 100644 --- a/tester/flexisip_tester.c +++ b/tester/flexisip_tester.c @@ -31,7 +31,7 @@ static void subscribe_forking(void) { LinphoneEvent *lev; int expires= 600; MSList* lcs=ms_list_append(NULL,marie->lc); - + lcs=ms_list_append(lcs,pauline->lc); lcs=ms_list_append(lcs,pauline2->lc); @@ -39,9 +39,9 @@ static void subscribe_forking(void) { linphone_content_set_type(content,"application"); linphone_content_set_subtype(content,"somexml"); linphone_content_set_buffer(content, liblinphone_tester_get_subscribe_content(), strlen(liblinphone_tester_get_subscribe_content())); - + lev=linphone_core_subscribe(marie->lc,pauline->identity,"dodo",expires,content); - + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingInit,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,3000)); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline2->stat.number_of_LinphoneSubscriptionIncomingReceived,1,1000)); @@ -67,10 +67,10 @@ static void message_forking(void) { char* to = linphone_address_as_string(marie->identity); LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc,to); LinphoneChatMessage* message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu"); - + lcs=ms_list_append(lcs,pauline->lc); lcs=ms_list_append(lcs,marie2->lc); - + linphone_chat_room_send_message2(chat_room,message,liblinphone_tester_chat_message_state_change,pauline->lc); CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneMessageReceived,1,3000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneMessageReceived,1,1000)); @@ -92,15 +92,15 @@ static void message_forking_with_unreachable_recipients(void) { char* to = linphone_address_as_string(marie->identity); LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc,to); LinphoneChatMessage* message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu"); - + lcs=ms_list_append(lcs,pauline->lc); lcs=ms_list_append(lcs,marie2->lc); lcs=ms_list_append(lcs,marie3->lc); - + /*marie2 and marie3 go offline*/ linphone_core_set_network_reachable(marie2->lc,FALSE); linphone_core_set_network_reachable(marie3->lc,FALSE); - + linphone_chat_room_send_message2(chat_room,message,liblinphone_tester_chat_message_state_change,pauline->lc); CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneMessageReceived,1,3000)); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneMessageDelivered,1,1000)); @@ -110,14 +110,14 @@ static void message_forking_with_unreachable_recipients(void) { /*marie 2 goes online */ linphone_core_set_network_reachable(marie2->lc,TRUE); CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneMessageReceived,1,3000)); - + /*wait a long time so that all transactions are expired*/ wait_for_list(lcs,NULL,0,32000); - + /*marie 3 goes online now*/ linphone_core_set_network_reachable(marie3->lc,TRUE); CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneMessageReceived,1,3000)); - + linphone_core_manager_destroy(marie); linphone_core_manager_destroy(marie2); linphone_core_manager_destroy(pauline); @@ -134,40 +134,40 @@ static void message_forking_with_all_recipients_unreachable(void) { char* to = linphone_address_as_string(marie->identity); LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc,to); LinphoneChatMessage* message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu"); - + lcs=ms_list_append(lcs,pauline->lc); lcs=ms_list_append(lcs,marie2->lc); lcs=ms_list_append(lcs,marie3->lc); - + /*All marie's device go offline*/ linphone_core_set_network_reachable(marie->lc,FALSE); linphone_core_set_network_reachable(marie2->lc,FALSE); linphone_core_set_network_reachable(marie3->lc,FALSE); - + linphone_chat_room_send_message2(chat_room,message,liblinphone_tester_chat_message_state_change,pauline->lc); - + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneMessageInProgress,1,5000)); /*flexisip will accept the message with 202 after 16 seconds*/ CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneMessageDelivered,1,18000)); CU_ASSERT_TRUE( marie->stat.number_of_LinphoneMessageReceived==0); CU_ASSERT_TRUE( marie2->stat.number_of_LinphoneMessageReceived==0); CU_ASSERT_TRUE( marie3->stat.number_of_LinphoneMessageReceived==0); - + /*marie 1 goes online */ linphone_core_set_network_reachable(marie->lc,TRUE); CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneMessageReceived,1,3000)); - + /*marie 2 goes online */ linphone_core_set_network_reachable(marie2->lc,TRUE); CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneMessageReceived,1,3000)); - + /*wait a long time so that all transactions are expired*/ wait_for_list(lcs,NULL,0,32000); - + /*marie 3 goes online now*/ linphone_core_set_network_reachable(marie3->lc,TRUE); CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneMessageReceived,1,3000)); - + linphone_core_manager_destroy(marie); linphone_core_manager_destroy(marie2); linphone_core_manager_destroy(pauline); @@ -181,16 +181,16 @@ static void call_forking(void){ LinphoneCoreManager* marie2 = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* marie3 = linphone_core_manager_new( "marie_rc"); MSList* lcs=ms_list_append(NULL,pauline->lc); - + lcs=ms_list_append(lcs,marie->lc); lcs=ms_list_append(lcs,marie2->lc); lcs=ms_list_append(lcs,marie3->lc); - + linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL); linphone_core_set_user_agent(marie2->lc,"Natted Linphone",NULL); linphone_core_set_user_agent(marie3->lc,"Natted Linphone",NULL); linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL); - + linphone_core_invite_address(pauline->lc,marie->identity); /*pauline should hear ringback*/ CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,3000)); @@ -198,22 +198,22 @@ static void call_forking(void){ CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,3000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallIncomingReceived,1,3000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallIncomingReceived,1,3000)); - + /*marie accepts the call on its first device*/ linphone_core_accept_call(marie->lc,linphone_core_get_current_call(marie->lc)); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallConnected,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,1000)); - + /*other devices should stop ringing*/ CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallEnd,1,1000)); - + linphone_core_terminate_call(pauline->lc,linphone_core_get_current_call(pauline->lc)); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000)); - + linphone_core_manager_destroy(pauline); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(marie2); @@ -227,38 +227,38 @@ static void call_forking_with_urgent_reply(void){ LinphoneCoreManager* marie2 = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* marie3 = linphone_core_manager_new( "marie_rc"); MSList* lcs=ms_list_append(NULL,pauline->lc); - + lcs=ms_list_append(lcs,marie->lc); lcs=ms_list_append(lcs,marie2->lc); lcs=ms_list_append(lcs,marie3->lc); - + linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL); linphone_core_set_user_agent(marie2->lc,"Natted Linphone",NULL); linphone_core_set_user_agent(marie3->lc,"Natted Linphone",NULL); linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL); - + CU_ASSERT_TRUE(linphone_core_media_encryption_supported(pauline->lc,LinphoneMediaEncryptionSRTP)); linphone_core_set_media_encryption(pauline->lc,LinphoneMediaEncryptionSRTP); linphone_core_set_network_reachable(marie2->lc,FALSE); linphone_core_set_network_reachable(marie3->lc,FALSE); - + linphone_core_invite_address(pauline->lc,marie->identity); /*pauline should hear ringback, after 5 seconds, when it will retry without SRTP*/ CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,9000)); /*Marie should be ringing*/ CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,1000)); - + /*marie accepts the call on its first device*/ linphone_core_accept_call(marie->lc,linphone_core_get_current_call(marie->lc)); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallConnected,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,1000)); - + linphone_core_terminate_call(pauline->lc,linphone_core_get_current_call(pauline->lc)); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000)); - + linphone_core_manager_destroy(pauline); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(marie2); @@ -272,16 +272,16 @@ static void call_forking_cancelled(void){ LinphoneCoreManager* marie2 = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* marie3 = linphone_core_manager_new( "marie_rc"); MSList* lcs=ms_list_append(NULL,pauline->lc); - + lcs=ms_list_append(lcs,marie->lc); lcs=ms_list_append(lcs,marie2->lc); lcs=ms_list_append(lcs,marie3->lc); - + linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL); linphone_core_set_user_agent(marie2->lc,"Natted Linphone",NULL); linphone_core_set_user_agent(marie3->lc,"Natted Linphone",NULL); linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL); - + linphone_core_invite_address(pauline->lc,marie->identity); /*pauline should hear ringback*/ CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,3000)); @@ -289,16 +289,16 @@ static void call_forking_cancelled(void){ CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallIncomingReceived,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallIncomingReceived,1,1000)); - + /*pauline finally cancels the call*/ linphone_core_terminate_call(pauline->lc,linphone_core_get_current_call(pauline->lc)); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000)); - + /*all devices should stop ringing*/ CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallEnd,1,1000)); - + linphone_core_manager_destroy(pauline); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(marie2); @@ -312,16 +312,16 @@ static void call_forking_declined(bool_t declined_globaly){ LinphoneCoreManager* marie2 = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* marie3 = linphone_core_manager_new( "marie_rc"); MSList* lcs=ms_list_append(NULL,pauline->lc); - + lcs=ms_list_append(lcs,marie->lc); lcs=ms_list_append(lcs,marie2->lc); lcs=ms_list_append(lcs,marie3->lc); - + linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL); linphone_core_set_user_agent(marie2->lc,"Natted Linphone",NULL); linphone_core_set_user_agent(marie3->lc,"Natted Linphone",NULL); linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL); - + linphone_core_invite_address(pauline->lc,marie->identity); /*pauline should hear ringback*/ CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,3000)); @@ -329,12 +329,12 @@ static void call_forking_declined(bool_t declined_globaly){ CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallIncomingReceived,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallIncomingReceived,1,1000)); - + /*marie1 finally declines the call*/ linphone_core_decline_call(marie->lc,linphone_core_get_current_call(marie->lc), declined_globaly ? LinphoneReasonDeclined : LinphoneReasonBusy ); - + if (declined_globaly){ CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000)); /*all devices should stop ringing*/ @@ -353,7 +353,7 @@ static void call_forking_declined(bool_t declined_globaly){ CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,3000)); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,3000)); } - + linphone_core_manager_destroy(pauline); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(marie2); @@ -373,40 +373,40 @@ static void call_forking_with_push_notification_single(void){ MSList* lcs; LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - + linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL); linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL); - + lcs=ms_list_append(NULL,pauline->lc); - + lcs=ms_list_append(lcs,marie->lc); - + /*unfortunately marie gets unreachable due to crappy 3G operator or iOS bug...*/ linphone_core_set_network_reachable(marie->lc,FALSE); - + linphone_core_invite_address(pauline->lc,marie->identity); - + /*the server is expected to send a push notification to marie, this will wake up linphone, that will reconnect:*/ linphone_core_set_network_reachable(marie->lc,TRUE); - + /*Marie shall receive the call immediately*/ CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,5000)); /*pauline should hear ringback as well*/ CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,1000)); - + /*marie accepts the call*/ linphone_core_accept_call(marie->lc,linphone_core_get_current_call(marie->lc)); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,5000)); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallConnected,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,1000)); - + liblinphone_tester_check_rtcp(pauline,marie); - + linphone_core_terminate_call(pauline->lc,linphone_core_get_current_call(pauline->lc)); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,5000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,5000)); - + linphone_core_manager_destroy(pauline); linphone_core_manager_destroy(marie); ms_list_free(lcs); @@ -416,49 +416,49 @@ static void call_forking_with_push_notification_multiple(void){ LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* marie2 = linphone_core_manager_new( "marie_rc"); - + MSList* lcs=ms_list_append(NULL,pauline->lc); - + lcs=ms_list_append(lcs,marie->lc); lcs=ms_list_append(lcs,marie2->lc); - + linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL); linphone_core_set_user_agent(marie2->lc,"Natted Linphone",NULL); linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL); - + /*unfortunately marie gets unreachable due to crappy 3G operator or iOS bug...*/ linphone_core_set_network_reachable(marie2->lc,FALSE); - + linphone_core_invite_address(pauline->lc,marie->identity); - + /*marie1 will ring*/ CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,5000)); /*pauline should hear ringback as well*/ CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,1000)); - + /*the server is expected to send a push notification to marie2, this will wake up linphone, that will reconnect:*/ linphone_core_set_network_reachable(marie2->lc,TRUE); - + /*Marie shall receive the call immediately*/ CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallIncomingReceived,1,5000)); - + /*marie2 accepts the call*/ linphone_core_accept_call(marie2->lc,linphone_core_get_current_call(marie2->lc)); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallConnected,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallStreamsRunning,1,1000)); - + /*call to marie1 should be cancelled*/ CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000)); - + liblinphone_tester_check_rtcp(pauline,marie2); - + linphone_core_terminate_call(pauline->lc,linphone_core_get_current_call(pauline->lc)); - + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,1000)); - + linphone_core_manager_destroy(pauline); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(marie2); @@ -470,16 +470,16 @@ static void call_forking_not_responded(void){ LinphoneCoreManager* marie2 = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* marie3 = linphone_core_manager_new( "marie_rc"); MSList* lcs=ms_list_append(NULL,pauline->lc); - + lcs=ms_list_append(lcs,marie->lc); lcs=ms_list_append(lcs,marie2->lc); lcs=ms_list_append(lcs,marie3->lc); - + linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL); linphone_core_set_user_agent(marie2->lc,"Natted Linphone",NULL); linphone_core_set_user_agent(marie3->lc,"Natted Linphone",NULL); linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL); - + linphone_core_invite_address(pauline->lc,marie->identity); /*pauline should hear ringback*/ CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,3000)); @@ -487,14 +487,14 @@ static void call_forking_not_responded(void){ CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallIncomingReceived,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallIncomingReceived,1,1000)); - + /*nobody answers, flexisip should close the call after XX seconds*/ CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallError,1,22000)); /*all devices should stop ringing*/ CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallEnd,1,1000)); - + linphone_core_manager_destroy(pauline); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(marie2); @@ -516,28 +516,28 @@ static void early_media_call_forking(void) { pol.automatically_accept=1; pol.automatically_initiate=1; - + linphone_core_set_user_agent(marie1->lc,"Natted Linphone",NULL); linphone_core_set_user_agent(marie2->lc,"Natted Linphone",NULL); linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL); - + linphone_core_enable_video(pauline->lc,TRUE,TRUE); - + linphone_core_enable_video(marie1->lc,TRUE,TRUE); linphone_core_set_video_policy(marie1->lc,&pol); - + linphone_core_enable_video(marie2->lc,TRUE,TRUE); linphone_core_set_video_policy(marie2->lc,&pol); linphone_core_set_audio_port_range(marie2->lc,40200,40300); linphone_core_set_video_port_range(marie2->lc,40400,40500); - + lcs=ms_list_append(lcs,marie1->lc); lcs=ms_list_append(lcs,marie2->lc); lcs=ms_list_append(lcs,pauline->lc); linphone_call_params_enable_early_media_sending(params,TRUE); linphone_call_params_enable_video(params,TRUE); - + linphone_core_invite_address_with_params(pauline->lc,marie1->identity,params); linphone_call_params_destroy(params); @@ -545,11 +545,11 @@ static void early_media_call_forking(void) { CU_ASSERT_TRUE(wait_for_list(lcs, &marie2->stat.number_of_LinphoneCallIncomingEarlyMedia,1,3000)); CU_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallOutgoingEarlyMedia,1,3000)); CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallOutgoingEarlyMedia,1); - + pauline_call=linphone_core_get_current_call(pauline->lc); marie1_call=linphone_core_get_current_call(marie1->lc); marie2_call=linphone_core_get_current_call(marie2->lc); - + /*wait a bit that streams are established*/ wait_for_list(lcs,&dummy,1,6000); CU_ASSERT_TRUE(linphone_call_get_audio_stats(pauline_call)->download_bandwidth>60 @@ -558,21 +558,21 @@ static void early_media_call_forking(void) { && linphone_call_get_audio_stats(marie1_call)->download_bandwidth<99); CU_ASSERT_TRUE(linphone_call_get_audio_stats(marie2_call)->download_bandwidth>60 && linphone_call_get_audio_stats(marie2_call)->download_bandwidth<99); - + linphone_core_accept_call(marie1->lc,linphone_core_get_current_call(marie1->lc)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie1->stat.number_of_LinphoneCallStreamsRunning,1,3000)); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,3000)); - + /*marie2 should get her call terminated*/ CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,1000)); - + /*wait a bit that streams are established*/ wait_for_list(lcs,&dummy,1,3000); CU_ASSERT_TRUE(linphone_call_get_audio_stats(pauline_call)->download_bandwidth>60 && linphone_call_get_audio_stats(pauline_call)->download_bandwidth<99 ); CU_ASSERT_TRUE(linphone_call_get_audio_stats(marie1_call)->download_bandwidth>60 && linphone_call_get_audio_stats(marie1_call)->download_bandwidth<99 ); - + linphone_core_terminate_all_calls(pauline->lc); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,5000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie1->stat.number_of_LinphoneCallEnd,1,5000)); @@ -588,35 +588,35 @@ static void call_with_sips(void){ LinphoneCoreManager* pauline1 = linphone_core_manager_new( "pauline_sips_rc"); LinphoneCoreManager* pauline2 = linphone_core_manager_new( "pauline_tcp_rc"); MSList* lcs=ms_list_append(NULL,marie->lc); - + lcs=ms_list_append(lcs,pauline1->lc); lcs=ms_list_append(lcs,pauline2->lc); - + linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL); linphone_core_set_user_agent(pauline1->lc,"Natted Linphone",NULL); linphone_core_set_user_agent(pauline2->lc,"Natted Linphone",NULL); - + linphone_core_invite_address(marie->lc,pauline1->identity); /*marie should hear ringback*/ CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallOutgoingRinging,1,3000)); /*Only the sips registered device from pauline should ring*/ CU_ASSERT_TRUE(wait_for_list(lcs,&pauline1->stat.number_of_LinphoneCallIncomingReceived,1,1000)); - + /*pauline accepts the call */ linphone_core_accept_call(pauline1->lc,linphone_core_get_current_call(pauline1->lc)); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline1->stat.number_of_LinphoneCallConnected,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline1->stat.number_of_LinphoneCallStreamsRunning,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallConnected,1,1000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,1000)); - + /*pauline2 should not have ring*/ CU_ASSERT_TRUE(pauline2->stat.number_of_LinphoneCallIncomingReceived==0); - + linphone_core_terminate_call(pauline1->lc,linphone_core_get_current_call(pauline1->lc)); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline1->stat.number_of_LinphoneCallEnd,1,3000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,3000)); - + linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline1); linphone_core_manager_destroy(pauline2); @@ -631,11 +631,11 @@ static void call_with_sips_not_achievable(void){ LinphoneAddress *dest; LinphoneCall *call; const LinphoneErrorInfo *ei; - + lcs=ms_list_append(lcs,pauline1->lc); lcs=ms_list_append(lcs,pauline2->lc); - + dest=linphone_address_clone(pauline1->identity); linphone_address_set_secure(dest,TRUE); call=linphone_core_invite_address(marie->lc,dest); @@ -649,7 +649,7 @@ static void call_with_sips_not_achievable(void){ if (ei){ CU_ASSERT_EQUAL(linphone_error_info_get_reason(ei), LinphoneReasonTemporarilyUnavailable); } - + linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline1); linphone_core_manager_destroy(pauline2); @@ -665,12 +665,12 @@ static void call_with_ipv6(void) { /*calling ortp_init() here is done to have WSAStartup() done, otherwise liblinphone_tester_ipv6_available() will not work.*/ ortp_init(); - + if (!liblinphone_tester_ipv6_available()){ ms_warning("Call with ipv6 not tested, no ipv6 connectivity"); return; } - + belle_sip_object_enable_leak_detector(TRUE); begin=belle_sip_object_get_object_count(); @@ -687,7 +687,7 @@ static void call_with_ipv6(void) { /*check that the remote contact is IPv6*/ const char *contact=linphone_call_get_remote_contact(pauline_call); LinphoneAddress *ct_addr; - + CU_ASSERT_PTR_NOT_NULL(contact); if (contact){ ct_addr=linphone_address_new(contact); @@ -697,7 +697,7 @@ static void call_with_ipv6(void) { } linphone_address_destroy(ct_addr); } - + } liblinphone_tester_check_rtcp(marie,pauline); @@ -714,6 +714,150 @@ static void call_with_ipv6(void) { ortp_exit(); } +static void file_transfer_message_rcs_to_external_body_client(void) { + char* to; + LinphoneChatRoom* chat_room; + LinphoneChatMessage* message; + LinphoneChatMessageCbs *cbs; + LinphoneContent* content; + FILE *file_to_send = NULL; + size_t file_size; + char *send_filepath = ms_strdup_printf("%s/images/nowebcamCIF.jpg", bc_tester_read_dir_prefix); + char *receive_filepath = ms_strdup_printf("%s/receive_file.dump", bc_tester_writable_dir_prefix); + + LinphoneCoreManager* marie = linphone_core_manager_init( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_init( "pauline_rc"); + + linphone_proxy_config_set_custom_header(marie->lc->default_proxy, "Accept", "application/sdp"); + linphone_core_manager_start(marie, "marie_rc", TRUE); + + linphone_proxy_config_set_custom_header(pauline->lc->default_proxy, "Accept", "application/sdp, text/plain, application/vnd.gsma.rcs-ft-http+xml"); + linphone_core_manager_start(pauline, "pauline_rc", TRUE); + + reset_counters(&marie->stat); + reset_counters(&pauline->stat); + + file_to_send = fopen(send_filepath, "rb"); + fseek(file_to_send, 0, SEEK_END); + file_size = ftell(file_to_send); + fseek(file_to_send, 0, SEEK_SET); + + /* Globally configure an http file transfer server. */ + linphone_core_set_file_transfer_server(pauline->lc,"https://www.linphone.org:444/lft.php"); + + /* create a chatroom on pauline's side */ + to = linphone_address_as_string(marie->identity); + chat_room = linphone_core_create_chat_room(pauline->lc,to); + ms_free(to); + /* create a file transfer message */ + content = linphone_core_create_content(pauline->lc); + linphone_content_set_type(content,"image"); + linphone_content_set_subtype(content,"jpeg"); + linphone_content_set_size(content,file_size); /*total size to be transfered*/ + linphone_content_set_name(content,"nowebcamCIF.jpg"); + message = linphone_chat_room_create_file_transfer_message(chat_room, content); + linphone_chat_message_set_user_data(message, file_to_send); + cbs = linphone_chat_message_get_callbacks(message); + { + int dummy=0; + wait_for_until(marie->lc,pauline->lc,&dummy,1,100); /*just to have time to purge message stored in the server*/ + reset_counters(&marie->stat); + reset_counters(&pauline->stat); + } + linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed); + linphone_chat_message_cbs_set_file_transfer_send(cbs, file_transfer_send); + linphone_chat_room_send_chat_message(chat_room,message); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageExtBodyReceived,1)); + fclose(file_to_send); + if (marie->stat.last_received_chat_message ) { + cbs = linphone_chat_message_get_callbacks(marie->stat.last_received_chat_message); + linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed); + linphone_chat_message_cbs_set_file_transfer_recv(cbs, file_transfer_received); + linphone_chat_message_download_file(marie->stat.last_received_chat_message); + } + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageFileTransferDone,1)); + + CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1); + CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageDelivered,1); + CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageExtBodyReceived,1); + CU_ASSERT_TRUE(compare_files(send_filepath, receive_filepath)); + + linphone_content_unref(content); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + ms_free(send_filepath); + ms_free(receive_filepath); +} + +static void send_file_transfer_message_using_external_body_url(LinphoneCoreManager *marie, LinphoneCoreManager *pauline) { + char *to; + LinphoneChatMessageCbs *cbs; + LinphoneChatRoom *chat_room; + LinphoneChatMessage *message; + + /* create a chatroom on pauline's side */ + to = linphone_address_as_string(marie->identity); + chat_room = linphone_core_create_chat_room(pauline->lc,to); + + message = linphone_chat_room_create_message(chat_room, NULL); + + cbs = linphone_chat_message_get_callbacks(message); + linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed); + + linphone_chat_message_set_external_body_url(message, "https://www.linphone.org:444//tmp/54ec58280ace9_c30709218df8eaba61d1.jpg"); + linphone_chat_room_send_chat_message(chat_room, message); + + CU_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageReceived, 1)); + if (marie->stat.last_received_chat_message) { + linphone_chat_message_download_file(marie->stat.last_received_chat_message); + } + CU_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageExtBodyReceived, 1)); + + CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress, 1); + CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageExtBodyReceived, 1); +} + +static void file_transfer_message_external_body_to_external_body_client(void) { + LinphoneCoreManager* marie = linphone_core_manager_init( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_init( "pauline_rc"); + + linphone_proxy_config_set_custom_header(marie->lc->default_proxy, "Accept", "application/sdp"); + linphone_core_manager_start(marie, "marie_rc", TRUE); + + linphone_proxy_config_set_custom_header(pauline->lc->default_proxy, "Accept", "application/sdp"); + linphone_core_manager_start(pauline, "pauline_rc", TRUE); + + reset_counters(&marie->stat); + reset_counters(&pauline->stat); + + linphone_core_refresh_registers(marie->lc); + linphone_core_refresh_registers(pauline->lc); + + send_file_transfer_message_using_external_body_url(marie, pauline); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +static void file_transfer_message_external_body_to_rcs_client(void) { + LinphoneCoreManager* marie = linphone_core_manager_init( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_init( "pauline_rc"); + + linphone_proxy_config_set_custom_header(marie->lc->default_proxy, "Accept", "application/sdp"); + linphone_core_manager_start(marie, "marie_rc", TRUE); + + linphone_proxy_config_set_custom_header(pauline->lc->default_proxy, "Accept", "application/sdp, text/plain, application/vnd.gsma.rcs-ft-http+xml"); + linphone_core_manager_start(pauline, "pauline_rc", TRUE); + + reset_counters(&marie->stat); + reset_counters(&pauline->stat); + + send_file_transfer_message_using_external_body_url(marie, pauline); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + test_t flexisip_tests[] = { { "Subscribe forking", subscribe_forking }, { "Message forking", message_forking }, @@ -730,7 +874,10 @@ test_t flexisip_tests[] = { { "Early-media call forking", early_media_call_forking }, { "Call with sips", call_with_sips }, { "Call with sips not achievable", call_with_sips_not_achievable }, - { "Call with ipv6", call_with_ipv6 } + { "Call with ipv6", call_with_ipv6 }, + { "File transfer message rcs to external body client", file_transfer_message_rcs_to_external_body_client }, + { "File transfer message external body to rcs client", file_transfer_message_external_body_to_rcs_client }, + { "File transfer message external body to external body client", file_transfer_message_external_body_to_external_body_client } }; diff --git a/tester/liblinphone_tester.c b/tester/liblinphone_tester.c index 11e31e13b..f8528943f 100644 --- a/tester/liblinphone_tester.c +++ b/tester/liblinphone_tester.c @@ -28,7 +28,9 @@ #include #endif -extern int liblinphone_tester_use_log_file; + +static FILE * log_file = NULL; +static OrtpLogFunc ortp_log_handler; #ifdef ANDROID @@ -43,7 +45,7 @@ static const char* LogDomain = "liblinphone_tester"; int main(int argc, char** argv); -void linphone_android_log_handler(int prio, const char *fmt, va_list args) { +void liblinphone_android_log_handler(int prio, const char *fmt, va_list args) { char str[4096]; char *current; char *next; @@ -63,17 +65,17 @@ void linphone_android_log_handler(int prio, const char *fmt, va_list args) { } } -static void linphone_android_ortp_log_handler(OrtpLogLevel lev, const char *fmt, va_list args) { +static void liblinphone_android_ortp_log_handler(OrtpLogLevel lev, const char *fmt, va_list args) { int prio; switch(lev){ - case ORTP_DEBUG: prio = ANDROID_LOG_DEBUG; break; - case ORTP_MESSAGE: prio = ANDROID_LOG_INFO; break; - case ORTP_WARNING: prio = ANDROID_LOG_WARN; break; - case ORTP_ERROR: prio = ANDROID_LOG_ERROR; break; - case ORTP_FATAL: prio = ANDROID_LOG_FATAL; break; - default: prio = ANDROID_LOG_DEFAULT; break; + case ORTP_DEBUG: prio = ANDROID_LOG_DEBUG; break; + case ORTP_MESSAGE: prio = ANDROID_LOG_INFO; break; + case ORTP_WARNING: prio = ANDROID_LOG_WARN; break; + case ORTP_ERROR: prio = ANDROID_LOG_ERROR; break; + case ORTP_FATAL: prio = ANDROID_LOG_FATAL; break; + default: prio = ANDROID_LOG_DEFAULT; break; } - linphone_android_log_handler(prio, fmt, args); + liblinphone_android_log_handler(prio, fmt, args); } void cunit_android_trace_handler(int level, const char *fmt, va_list args) { @@ -121,7 +123,6 @@ JNIEXPORT void JNICALL Java_org_linphone_tester_Tester_keepAccounts(JNIEnv *env, JNIEXPORT void JNICALL Java_org_linphone_tester_Tester_clearAccounts(JNIEnv *env, jclass c) { liblinphone_tester_clear_accounts(); } - #endif /* ANDROID */ #ifdef __QNX__ @@ -130,48 +131,48 @@ static void liblinphone_tester_qnx_log_handler(OrtpLogLevel lev, const char *fmt } #endif /* __QNX__ */ - - -void helper(const char *name) { - liblinphone_tester_fprintf(stderr,"%s --help\n" - "\t\t\t--verbose\n" - "\t\t\t--silent\n" - "\t\t\t--list-suites\n" - "\t\t\t--list-tests \n" - "\t\t\t--config \n" - "\t\t\t--domain \n" - "\t\t\t--auth-domain \n" - "\t\t\t--suite \n" - "\t\t\t--test \n" - "\t\t\t--dns-hosts \n" - "\t\t\t--log-file \n" -#if HAVE_CU_CURSES - "\t\t\t--curses\n" -#endif - "\t\t\t--xml\n" - "\t\t\t--xml-file \n" - , name); +static void log_handler(int lev, const char *fmt, va_list args) { + ortp_set_log_file(stderr); + ortp_log_handler(lev, fmt, args); + if (log_file){ + ortp_set_log_file(log_file); + ortp_log_handler(lev, fmt, args); + } } -#define CHECK_ARG(argument, index, argc) \ -if(index >= argc) { \ -fprintf(stderr, "Missing argument for \"%s\"\n", argument); \ -return -1; \ -} \ +void liblinphone_tester_init(void) { + ortp_log_handler = ortp_get_log_handler(); +#if defined(ANDROID) + linphone_core_set_log_handler(liblinphone_android_ortp_log_handler); +#elif defined(__QNX__) + linphone_core_set_log_handler(liblinphone_tester_qnx_log_handler); +#else + linphone_core_set_log_handler(ortp_logv_out); +#endif -#ifndef WINAPI_FAMILY_PHONE_APP + bc_tester_init(log_handler, ORTP_MESSAGE, ORTP_ERROR); + liblinphone_tester_add_suites(); +} + +void liblinphone_tester_uninit(void) { + bc_tester_uninit(); +} +static const char* liblinphone_helper = + "\t\t\t--verbose\n" + "\t\t\t--silent\n" + "\t\t\t--log-file \n" + "\t\t\t--config \n" + "\t\t\t--domain \n" + "\t\t\t--auth-domain \n" + "\t\t\t--dns-hosts \n"; + +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) int main (int argc, char *argv[]) { int i; int ret; - const char *suite_name=NULL; - const char *test_name=NULL; - const char *xml_file="CUnitAutomated-Results.xml"; - char *xml_tmp_file=NULL; - int xml = 0; - FILE* log_file=NULL; #ifdef HAVE_GTK gtk_init(&argc, &argv); @@ -181,95 +182,48 @@ int main (int argc, char *argv[]) gdk_threads_init(); #endif -#if defined(ANDROID) - linphone_core_set_log_handler(linphone_android_ortp_log_handler); -#elif defined(__QNX__) - linphone_core_set_log_handler(liblinphone_tester_qnx_log_handler); -#else - linphone_core_set_log_file(NULL); -#endif - liblinphone_tester_init(); - for(i=1;i0) { + i += ret - 1; + continue; + } else if (ret<0) { + bc_tester_helper(argv[0], liblinphone_helper); } - - }else { - liblinphone_tester_fprintf(stderr, "Unknown option \"%s\"\n", argv[i]); \ - helper(argv[0]); - return -1; + return ret; } } - if( xml && (suite_name || test_name) ){ - printf("Cannot use both xml and specific test suite\n"); - return -1; - } - - if( xml ){ - xml_tmp_file = ms_strdup_printf("%s.tmp", xml_file); - liblinphone_tester_set_xml_output(xml_tmp_file); - } - liblinphone_tester_enable_xml(xml); - - ret = liblinphone_tester_run_tests(suite_name, test_name); + ret = bc_tester_start(); liblinphone_tester_uninit(); - - if ( xml ) { - /*create real xml file only if tester did not crash*/ - ms_strcat_printf(xml_tmp_file, "-Results.xml"); - rename(xml_tmp_file, xml_file); - ms_free(xml_tmp_file); - } return ret; } -#endif /* WINAPI_FAMILY_PHONE_APP */ - +#endif diff --git a/tester/liblinphone_tester.h b/tester/liblinphone_tester.h index c140a6453..9fd453f0d 100644 --- a/tester/liblinphone_tester.h +++ b/tester/liblinphone_tester.h @@ -22,34 +22,16 @@ -#include "CUnit/Basic.h" +#include "common/bc_tester_utils.h" #include "linphonecore.h" #ifdef HAVE_CONFIG_H #include "config.h" #endif -typedef void (*test_function_t)(void); -typedef int (*test_suite_function_t)(const char *name); - -typedef struct { - const char *name; - test_function_t func; -} test_t; - -typedef struct { - const char *name; - CU_InitializeFunc init_func; - CU_CleanupFunc cleanup_func; - int nb_tests; - test_t *tests; -} test_suite_t; - #ifdef __cplusplus extern "C" { #endif -extern const char *liblinphone_tester_file_prefix; -extern const char *liblinphone_tester_writable_dir_prefix; extern test_suite_t setup_test_suite; extern test_suite_t register_test_suite; extern test_suite_t call_test_suite; @@ -68,28 +50,11 @@ extern test_suite_t dtmf_test_suite; extern test_suite_t offeranswer_test_suite; extern test_suite_t video_test_suite; extern test_suite_t multicast_call_test_suite; +extern test_suite_t multi_call_test_suite; -extern int liblinphone_tester_nb_test_suites(void); -extern int liblinphone_tester_nb_tests(const char *suite_name); -extern const char * liblinphone_tester_test_suite_name(int suite_index); -extern int liblinphone_tester_test_suite_index(const char *suite_name); -extern void liblinphone_tester_list_suites(); -extern void liblinphone_tester_list_suite_tests(const char *suite_name); -extern const char * liblinphone_tester_test_name(const char *suite_name, int test_index); -extern int liblinphone_tester_test_index(const char *suite_name, const char *test_name); -extern void liblinphone_tester_init(void); -extern void liblinphone_tester_uninit(void); -extern int liblinphone_tester_run_tests(const char *suite_name, const char *test_name); -extern void liblinphone_tester_set_fileprefix(const char* file_prefix); -extern void liblinphone_tester_set_writable_dir_prefix(const char* writable_dir_prefix); extern int liblinphone_tester_ipv6_available(void); - -extern void liblinphone_tester_enable_xml( bool_t enable ); -extern void liblinphone_tester_set_xml_output(const char *xml_path ); -extern const char* liblinphone_tester_get_xml_output(void); - /** * @brief Tells the tester whether or not to clean the accounts it has created between runs. * @details Setting this to 1 will not clear the list of created accounts between successive @@ -166,6 +131,7 @@ typedef struct _stats { int number_of_LinphoneMessageInProgress; int number_of_LinphoneMessageDelivered; int number_of_LinphoneMessageNotDelivered; + int number_of_LinphoneMessageFileTransferDone; int number_of_LinphoneIsComposingActiveReceived; int number_of_LinphoneIsComposingIdleReceived; int progress_of_LinphoneFileTransfer; @@ -241,6 +207,11 @@ typedef struct _stats { int number_of_video_windows_created; + int number_of_LinphoneFileTransferDownloadSuccessful; + int number_of_LinphoneCoreLogCollectionUploadStateDelivered; + int number_of_LinphoneCoreLogCollectionUploadStateNotDelivered; + int number_of_LinphoneCoreLogCollectionUploadStateInProgress; + }stats; typedef struct _LinphoneCoreManager { @@ -259,6 +230,11 @@ typedef struct _LinphoneCallTestParams { bool_t sdp_simulate_error; } LinphoneCallTestParams; + +void liblinphone_tester_add_suites(); + +LinphoneCoreManager* linphone_core_manager_init(const char* rc_file); +void linphone_core_manager_start(LinphoneCoreManager *mgr, const char* rc_file, int check_for_proxies); LinphoneCoreManager* linphone_core_manager_new2(const char* rc_file, int check_for_proxies); LinphoneCoreManager* linphone_core_manager_new(const char* rc_file); void linphone_core_manager_stop(LinphoneCoreManager *mgr); @@ -318,13 +294,12 @@ void linphone_core_manager_check_accounts(LinphoneCoreManager *m); void account_manager_destroy(void); LinphoneCore* configure_lc_from(LinphoneCoreVTable* v_table, const char* path, const char* file, void* user_data); void liblinphone_tester_enable_ipv6(bool_t enabled); -#ifdef ANDROID -void cunit_android_trace_handler(int level, const char *fmt, va_list args) ; -#endif -int liblinphone_tester_fprintf(FILE * stream, const char * format, ...); void linphone_call_cb(LinphoneCall *call,void * user_data); void call_paused_resumed_base(bool_t multicast); void simple_call_base(bool_t enable_multicast_recv_side); void call_base(LinphoneMediaEncryption mode, bool_t enable_video,bool_t enable_relay,LinphoneFirewallPolicy policy,bool_t enable_tunnel); +bool_t call_with_caller_params(LinphoneCoreManager* caller_mgr,LinphoneCoreManager* callee_mgr, const LinphoneCallParams *params); +bool_t pause_call_1(LinphoneCoreManager* mgr_1,LinphoneCall* call_1,LinphoneCoreManager* mgr_2,LinphoneCall* call_2); +bool_t compare_files(const char *path1, const char *path2); #endif /* LIBLINPHONE_TESTER_H_ */ diff --git a/tester/log_collection_tester.c b/tester/log_collection_tester.c index 96531422a..4bd5cb55e 100644 --- a/tester/log_collection_tester.c +++ b/tester/log_collection_tester.c @@ -1,6 +1,6 @@ /* - belle-sip - SIP (RFC3261) library. - Copyright (C) 2010 Belledonne Communications SARL + Linphone + Copyright (C) 2014 Belledonne Communications SARL This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -67,7 +67,7 @@ static size_t getline(char **lineptr, size_t *n, FILE *stream) { p = bufptr; while(c != EOF) { size_t curpos = p-bufptr; - + if (curpos > (size - 1)) { size = size + 128; bufptr = realloc(bufptr, size); @@ -94,7 +94,7 @@ static size_t getline(char **lineptr, size_t *n, FILE *stream) { static LinphoneLogCollectionState old_collection_state; static void collect_init() { old_collection_state = linphone_core_log_collection_enabled(); - linphone_core_set_log_collection_path(liblinphone_tester_writable_dir_prefix); + linphone_core_set_log_collection_path(bc_tester_writable_dir_prefix); } static void collect_cleanup(LinphoneCoreManager *marie) { @@ -171,7 +171,7 @@ static time_t check_file(LinphoneCoreManager* mgr) { CU_ASSERT_PTR_NOT_NULL(file); if (!file) return 0; // 1) expect to find folder name in filename path - CU_ASSERT_PTR_NOT_NULL(strstr(filepath, liblinphone_tester_writable_dir_prefix)); + CU_ASSERT_PTR_NOT_NULL(strstr(filepath, bc_tester_writable_dir_prefix)); // 2) check file contents while (getline(&line, &line_size, file) != -1) { @@ -244,12 +244,54 @@ static void collect_files_changing_size() { collect_cleanup(marie); } +static void logCollectionUploadStateChangedCb(LinphoneCore *lc, LinphoneCoreLogCollectionUploadState state, const char *info) { + + stats* counters = get_stats(lc); + switch(state) { + case LinphoneCoreLogCollectionUploadStateInProgress: + counters->number_of_LinphoneCoreLogCollectionUploadStateInProgress++; + break; + case LinphoneCoreLogCollectionUploadStateDelivered: + counters->number_of_LinphoneCoreLogCollectionUploadStateDelivered++; + CU_ASSERT_TRUE(strlen(info)>0) + break; + case LinphoneCoreLogCollectionUploadStateNotDelivered: + counters->number_of_LinphoneCoreLogCollectionUploadStateNotDelivered++; + break; + } +} +static void upload_collected_traces() { + LinphoneCoreManager* marie = setup(TRUE); + int waiting = 100; + LinphoneCoreVTable *v_table = linphone_core_v_table_new(); + v_table->log_collection_upload_state_changed = logCollectionUploadStateChangedCb; + linphone_core_add_listener(marie->lc, v_table); + + linphone_core_set_log_collection_max_file_size(5000); + linphone_core_set_log_collection_upload_server_url(marie->lc,"https://www.linphone.org:444/lft.php"); + // Generate some logs + while (--waiting) ms_error("(test error)Waiting %d...", waiting); + linphone_core_compress_log_collection(marie->lc); + linphone_core_upload_log_collection(marie->lc); + CU_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphoneCoreLogCollectionUploadStateDelivered,1)); + + /*try 2 times*/ + waiting=100; + linphone_core_reset_log_collection(marie->lc); + while (--waiting) ms_error("(test error)Waiting %d...", waiting); + linphone_core_compress_log_collection(marie->lc); + linphone_core_upload_log_collection(marie->lc); + CU_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphoneCoreLogCollectionUploadStateDelivered,2)); + + collect_cleanup(marie); +} test_t log_collection_tests[] = { { "No file when disabled", collect_files_disabled}, { "Collect files filled when enabled", collect_files_filled}, { "Logs collected into small file", collect_files_small_size}, { "Logs collected when decreasing max size", collect_files_changing_size}, + { "Upload collected traces", upload_collected_traces} }; test_suite_t log_collection_test_suite = { diff --git a/tester/message_tester.c b/tester/message_tester.c index e2491048f..bddd40df2 100644 --- a/tester/message_tester.c +++ b/tester/message_tester.c @@ -22,6 +22,7 @@ #include "linphonecore.h" #include "private.h" #include "liblinphone_tester.h" +#include "lime.h" #ifdef MSG_STORAGE_ENABLED #include @@ -67,7 +68,7 @@ void file_transfer_received(LinphoneChatMessage *message, const LinphoneContent* char receive_file[256]; LinphoneChatRoom *cr = linphone_chat_message_get_chat_room(message); LinphoneCore *lc = linphone_chat_room_get_core(cr); - snprintf(receive_file,sizeof(receive_file), "%s/receive_file.dump", liblinphone_tester_writable_dir_prefix); + snprintf(receive_file,sizeof(receive_file), "%s/receive_file.dump", bc_tester_writable_dir_prefix); if (!linphone_chat_message_get_user_data(message)) { /*first chunk, creating file*/ file = fopen(receive_file,"wb"); @@ -78,7 +79,7 @@ void file_transfer_received(LinphoneChatMessage *message, const LinphoneContent* if (linphone_buffer_is_empty(buffer)) { /* tranfer complete */ stats* counters = get_stats(lc); - counters->number_of_LinphoneMessageExtBodyReceived++; + counters->number_of_LinphoneFileTransferDownloadSuccessful++; fclose(file); } else { /* store content on a file*/ if (fwrite(linphone_buffer_get_content(buffer),linphone_buffer_get_size(buffer),1,file)==-1){ @@ -87,7 +88,7 @@ void file_transfer_received(LinphoneChatMessage *message, const LinphoneContent* } } -static char big_file [128000]; /* a buffer to simulate a big file for the file transfer message test */ +char big_file[128000]; /* a buffer to simulate a big file for the file transfer message test */ /* * function called when the file transfer is initiated. file content should be feed into object LinphoneContent @@ -157,31 +158,39 @@ void liblinphone_tester_chat_message_msg_state_changed(LinphoneChatMessage *msg, LinphoneChatRoom *cr = linphone_chat_message_get_chat_room(msg); LinphoneCore *lc = linphone_chat_room_get_core(cr); stats* counters = get_stats(lc); - ms_message("Message [%s] [%s]",linphone_chat_message_get_text(msg), linphone_chat_message_state_to_string(state)); + const char *text = linphone_chat_message_get_text(msg); + if (!text) text = ""; + ms_message("Message [%s] [%s]",text, linphone_chat_message_state_to_string(state)); switch (state) { - case LinphoneChatMessageStateDelivered: - counters->number_of_LinphoneMessageDelivered++; - break; - case LinphoneChatMessageStateNotDelivered: - counters->number_of_LinphoneMessageNotDelivered++; - break; - case LinphoneChatMessageStateInProgress: - counters->number_of_LinphoneMessageInProgress++; - break; - case LinphoneChatMessageStateFileTransferError: - counters->number_of_LinphoneMessageNotDelivered++; - break; - default: - ms_error("Unexpected state [%s] for message [%p]",linphone_chat_message_state_to_string(state), msg); + case LinphoneChatMessageStateIdle: + return; + case LinphoneChatMessageStateDelivered: + counters->number_of_LinphoneMessageDelivered++; + return; + case LinphoneChatMessageStateNotDelivered: + counters->number_of_LinphoneMessageNotDelivered++; + return; + case LinphoneChatMessageStateInProgress: + counters->number_of_LinphoneMessageInProgress++; + return; + case LinphoneChatMessageStateFileTransferError: + counters->number_of_LinphoneMessageNotDelivered++; + return; + case LinphoneChatMessageStateFileTransferDone: + counters->number_of_LinphoneMessageFileTransferDone++; + return; } + ms_error("Unexpected state [%s] for message [%p]",linphone_chat_message_state_to_string(state), msg); } static void text_message(void) { LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + char* to; + LinphoneChatRoom* chat_room; - char* to = linphone_address_as_string(marie->identity); - LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc,to); + to = linphone_address_as_string(marie->identity); + chat_room = linphone_core_create_chat_room(pauline->lc,to); ms_free(to); { int dummy=0; @@ -269,11 +278,15 @@ static void text_message_with_credential_from_auth_cb(void) { } static void text_message_with_privacy(void) { + char *to; + LinphoneChatRoom* chat_room; + + LinphoneProxyConfig* pauline_proxy; LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - LinphoneProxyConfig* pauline_proxy; - char* to = linphone_address_as_string(marie->identity); - LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc,to); + + to = linphone_address_as_string(marie->identity); + chat_room = linphone_core_create_chat_room(pauline->lc,to); ms_free(to); /*test proxy config privacy*/ @@ -343,12 +356,16 @@ static void text_message_compatibility_mode(void) { static void text_message_with_ack(void) { int leaked_objects; int begin; + LinphoneCoreManager* marie; + LinphoneCoreManager* pauline; + belle_sip_object_enable_leak_detector(TRUE); begin=belle_sip_object_get_object_count(); + marie = linphone_core_manager_new( "marie_rc"); + pauline = linphone_core_manager_new( "pauline_rc"); + { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); char* to = linphone_address_as_string(marie->identity); LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc,to); LinphoneChatMessage* message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu"); @@ -362,7 +379,7 @@ static void text_message_with_ack(void) { CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1)); CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageDelivered,1)); CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1); - + ms_free(to); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } @@ -376,11 +393,13 @@ static void text_message_with_ack(void) { static void text_message_with_external_body(void) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - char* to = linphone_address_as_string(marie->identity); + char *to = linphone_address_as_string(marie->identity); LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc,to); LinphoneChatMessage* message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu"); LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(message); + linphone_chat_message_set_external_body_url(message,message_external_body_url="http://www.linphone.org"); + { int dummy=0; wait_for_until(marie->lc,pauline->lc,&dummy,1,100); /*just to have time to purge message stored in the server*/ @@ -404,38 +423,19 @@ static void text_message_with_external_body(void) { linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); + ms_free(to); } -static bool_t compare_files(const char *path1, const char *path2) { +bool_t compare_files(const char *path1, const char *path2) { bool_t res; size_t size1; size_t size2; uint8_t *buf1; uint8_t *buf2; - FILE *f1 = fopen(path1, "rb"); - FILE *f2 = fopen(path2, "rb"); - fseek(f1, 0, SEEK_END); - size1 = ftell(f1); - fseek(f1, 0, SEEK_SET); - fseek(f2, 0, SEEK_END); - size2 = ftell(f2); - fseek(f2, 0, SEEK_SET); - if (size1 != size2) { - fclose(f1); - fclose(f2); - return FALSE; - } - buf1 = ms_malloc(size1); - buf2 = ms_malloc(size2); - if (fread(buf1, size1, 1, f1)!=size1){ - ms_error("fread() error"); - } - if (fread(buf2, size2, 1, f2)!=size2){ - ms_error("fread() error"); - } - fclose(f1); - fclose(f2); - res = (memcmp(buf1, buf2, size1) == 0) ? TRUE : FALSE; + + buf1 = (uint8_t*)ms_load_path_content(path1, &size1); + buf2 = (uint8_t*)ms_load_path_content(path2, &size2); + res = buf1 && buf2 && (size1 == size2) && (memcmp(buf1, buf2, size1) == 0); ms_free(buf1); ms_free(buf2); return res; @@ -449,10 +449,11 @@ static void file_transfer_message(void) { LinphoneContent* content; FILE *file_to_send = NULL; size_t file_size; - char *send_filepath = ms_strdup_printf("%s/images/nowebcamCIF.jpg", liblinphone_tester_file_prefix); - char *receive_filepath = ms_strdup_printf("%s/receive_file.dump", liblinphone_tester_writable_dir_prefix); + char *send_filepath = ms_strdup_printf("%s/images/nowebcamCIF.jpg", bc_tester_read_dir_prefix); + char *receive_filepath = ms_strdup_printf("%s/receive_file.dump", bc_tester_writable_dir_prefix); LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + reset_counters(&marie->stat); reset_counters(&pauline->stat); @@ -494,11 +495,11 @@ static void file_transfer_message(void) { linphone_chat_message_cbs_set_file_transfer_recv(cbs, file_transfer_received); linphone_chat_message_download_file(marie->stat.last_received_chat_message); } - CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageExtBodyReceived,1)); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,1)); CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1); CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageDelivered,1); - CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageExtBodyReceived,1); + CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,1); CU_ASSERT_TRUE(compare_files(send_filepath, receive_filepath)); linphone_content_unref(content); @@ -560,17 +561,104 @@ static void small_file_transfer_message(void) { linphone_chat_message_cbs_set_file_transfer_recv(cbs, file_transfer_received); linphone_chat_message_download_file(marie->stat.last_received_chat_message); } - CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageExtBodyReceived,1)); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,1)); CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1); CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageDelivered,1); - CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageExtBodyReceived,1); + CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,1); linphone_content_unref(content); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } +static void lime_file_transfer_message(void) { + int i; + char *to; + FILE *ZIDCacheMarieFD, *ZIDCachePaulineFD; + LinphoneCoreManager *marie, *pauline; + LinphoneChatRoom *chat_room; + LinphoneContent *content; + LinphoneChatMessage *message; + LinphoneChatMessageCbs *cbs; + char *pauline_id, *marie_id; + + /* setting dummy file content to something */ + const char* big_file_content="big file"; + for (i=0;istat); + reset_counters(&pauline->stat); + + /* make sure lime is enabled */ + linphone_core_enable_lime(marie->lc, 1); + linphone_core_enable_lime(pauline->lc, 1); + + /* set the zid caches files : create two ZID cache from this valid one inserting the auto-generated sip URI for the peer account as keys in ZID cache are indexed by peer sip uri */ + ZIDCacheMarieFD = fopen("tmpZIDCacheMarie.xml", "wb"); + ZIDCachePaulineFD = fopen("tmpZIDCachePauline.xml", "wb"); + pauline_id = linphone_address_as_string_uri_only(pauline->identity); + marie_id = linphone_address_as_string_uri_only(marie->identity); + fprintf(ZIDCacheMarieFD, "\nef7692d0792a67491ae2d44e005dbe0399643d953a2202dd9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899%s08df5907d30959b8cb70f6fff2d8febd88fb41b0c8afc39e4b972f86dd5cfe2d60f020a3fe11dc2cc0e1e8ed9341b4cd14944db806ca4fc95456bbe45d95c43a5f9aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b77193bcffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b7719300000078000001cf011234567889643d953a2202ee9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778csal_set_uuid(lc->sal, account->instance_id);bdf31c605e2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899%s72d80ab1cad243cf45634980c1d02cfb2df81ce0dd5dfcf1ebeacfc5345a917625d9ac653a83c4559cb0ae7394e7cd3b2d3c57bb28e62068d2df23e8f9b77193f69aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b7719322ffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b771930000000f00000000", pauline_id, pauline_id); + fprintf(ZIDCachePaulineFD, "\n005dbe0399643d953a2202ddef7692d0792a67491ae2d44e9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899%s08df5907d30959b8cb70f6fff2d8febd88fb41b0c8afc39e4b972f86dd5cfe2d60f020a3fe11dc2cc0e1e8ed9341b4cd14944db806ca4fc95456bbe45d95c43a5f9aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b77193bcffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b7719300000078000001cf011234567889643d953a2202ee9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899%s81e6e6362c34dc974263d1f77cbb9a8d6d6a718330994379099a8fa19fb12faa25d9ac653a83c4559cb0ae7394e7cd3b2d3c57bb28e62068d2df23e8f9b77193f69aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b7719322ffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b771930000002e0000000001", marie_id, marie_id); + fclose(ZIDCacheMarieFD); + fclose(ZIDCachePaulineFD); + ms_free(marie_id); + ms_free(pauline_id); + linphone_core_set_zrtp_secrets_file(marie->lc, "tmpZIDCacheMarie.xml"); + linphone_core_set_zrtp_secrets_file(pauline->lc, "tmpZIDCachePauline.xml"); + + /* Globally configure an http file transfer server. */ + linphone_core_set_file_transfer_server(pauline->lc,"https://www.linphone.org:444/lft.php"); + + /* create a chatroom on pauline's side */ + to = linphone_address_as_string(marie->identity); + chat_room = linphone_core_create_chat_room(pauline->lc,to); + ms_free(to); + /* create a file transfer message */ + content = linphone_core_create_content(pauline->lc); + linphone_content_set_type(content,"text"); + linphone_content_set_subtype(content,"plain"); + linphone_content_set_size(content,sizeof(big_file)); /*total size to be transfered*/ + linphone_content_set_name(content,"big_file.txt"); + + message = linphone_chat_room_create_file_transfer_message(chat_room, content); + { + int dummy=0; + wait_for_until(marie->lc,pauline->lc,&dummy,1,100); /*just to have time to purge message stored in the server*/ + reset_counters(&marie->stat); + reset_counters(&pauline->stat); + } + + cbs = linphone_chat_message_get_callbacks(message); + linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed); + linphone_chat_message_cbs_set_file_transfer_send(cbs, memory_file_transfer_send); + linphone_chat_room_send_chat_message(chat_room,message); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,1)); + if (marie->stat.last_received_chat_message ) { + cbs = linphone_chat_message_get_callbacks(marie->stat.last_received_chat_message); + linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed); + linphone_chat_message_cbs_set_file_transfer_recv(cbs, file_transfer_received); + linphone_chat_message_download_file(marie->stat.last_received_chat_message); + } + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,1)); + + CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1); + CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageDelivered,1); + CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,1); + + linphone_content_unref(content); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + +} + static void file_transfer_message_io_error_upload(void) { int i; char* to; @@ -581,6 +669,7 @@ static void file_transfer_message_io_error_upload(void) { const char* big_file_content="big file"; /* setting dummy file content to something */ LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + reset_counters(&marie->stat); reset_counters(&pauline->stat); @@ -624,7 +713,7 @@ static void file_transfer_message_io_error_upload(void) { CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageNotDelivered,1)); CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageNotDelivered,1); - CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageExtBodyReceived,0); + CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,0); sal_set_send_error(pauline->lc->sal, 0); @@ -647,6 +736,7 @@ static void file_transfer_message_io_error_download(void) { const char* big_file_content="big file"; /* setting dummy file content to something */ LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + reset_counters(&marie->stat); reset_counters(&pauline->stat); @@ -663,6 +753,7 @@ static void file_transfer_message_io_error_download(void) { /* create a chatroom on pauline's side */ to = linphone_address_as_string(marie->identity); chat_room = linphone_core_create_chat_room(pauline->lc,to); + ms_free(to); /* create a file transfer message */ memset(&content,0,sizeof(content)); @@ -694,7 +785,7 @@ static void file_transfer_message_io_error_download(void) { CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1); CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageDelivered,1); CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageNotDelivered,1); - CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageExtBodyReceived,0); + CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,0); sal_set_recv_error(marie->lc->sal, 0); linphone_core_manager_destroy(marie); @@ -712,6 +803,7 @@ static void file_transfer_message_upload_cancelled(void) { const char* big_file_content="big file"; /* setting dummy file content to something */ LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + reset_counters(&marie->stat); reset_counters(&pauline->stat); @@ -755,7 +847,7 @@ static void file_transfer_message_upload_cancelled(void) { CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageNotDelivered,1)); CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageNotDelivered,1); - CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageExtBodyReceived,0); + CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,0); linphone_content_unref(content); linphone_core_manager_destroy(marie); @@ -772,6 +864,7 @@ static void file_transfer_message_download_cancelled(void) { const char* big_file_content="big file"; /* setting dummy file content to something */ LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + reset_counters(&marie->stat); reset_counters(&pauline->stat); @@ -818,7 +911,7 @@ static void file_transfer_message_download_cancelled(void) { CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1); CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageDelivered,1); - CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageExtBodyReceived,0); + CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,0); CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageNotDelivered,1); linphone_core_manager_destroy(marie); @@ -837,27 +930,29 @@ static void file_transfer_using_external_body_url(void) { reset_counters(&marie->stat); reset_counters(&pauline->stat); + /* make sure lime is disabled */ + linphone_core_enable_lime(marie->lc, FALSE); + linphone_core_enable_lime(pauline->lc, FALSE); + /* create a chatroom on pauline's side */ to = linphone_address_as_string(marie->identity); chat_room = linphone_core_create_chat_room(pauline->lc,to); - + message = linphone_chat_room_create_message(chat_room, NULL); - + cbs = linphone_chat_message_get_callbacks(message); linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed); - + linphone_chat_message_set_external_body_url(message, "https://www.linphone.org:444//tmp/54ec58280ace9_c30709218df8eaba61d1.jpg"); linphone_chat_room_send_chat_message(chat_room, message); - + CU_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageReceived, 1)); if (marie->stat.last_received_chat_message) { linphone_chat_message_download_file(marie->stat.last_received_chat_message); } CU_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageExtBodyReceived, 1)); - - CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress, 1); - CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageExtBodyReceived, 1); - + CU_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneMessageInProgress, 1)); + ms_free(to); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } @@ -865,7 +960,8 @@ static void file_transfer_using_external_body_url(void) { static void text_message_with_send_error(void) { LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - char* to = linphone_address_as_string(pauline->identity); + + char *to = linphone_address_as_string(pauline->identity); LinphoneChatRoom* chat_room = linphone_core_create_chat_room(marie->lc,to); LinphoneChatMessage* message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu"); LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(message); @@ -896,6 +992,7 @@ static void text_message_with_send_error(void) { CU_ASSERT_EQUAL(ms_list_size(chat_room->transient_messages), 0); sal_set_send_error(marie->lc->sal, 0); + ms_free(to); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } @@ -903,7 +1000,8 @@ static void text_message_with_send_error(void) { static void text_message_denied(void) { LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - char* to = linphone_address_as_string(pauline->identity); + + char *to = linphone_address_as_string(pauline->identity); LinphoneChatRoom* chat_room = linphone_core_create_chat_room(marie->lc,to); LinphoneChatMessage* message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu"); LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(message); @@ -921,7 +1019,7 @@ static void text_message_denied(void) { CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageNotDelivered,1)); CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageReceived,0); - + ms_free(to); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } @@ -941,12 +1039,13 @@ void info_message_received(LinphoneCore *lc, LinphoneCall* call, const LinphoneI static void info_message_with_args(bool_t with_content) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); LinphoneInfoMessage *info; const LinphoneContent *content; const char *hvalue; + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + CU_ASSERT_TRUE(call(pauline,marie)); info=linphone_core_create_info_message(marie->lc); @@ -1003,11 +1102,15 @@ static void info_message_with_body(){ } static void is_composing_notification(void) { + char* to; + LinphoneChatRoom* chat_room; + int dummy = 0; + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - char* to = linphone_address_as_string(marie->identity); - LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc, to); - int dummy = 0; + + to = linphone_address_as_string(marie->identity); + chat_room = linphone_core_create_chat_room(pauline->lc, to); ms_free(to); { @@ -1021,11 +1124,203 @@ static void is_composing_notification(void) { linphone_chat_room_send_message(chat_room, "Composing a message"); CU_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneIsComposingActiveReceived, 1)); CU_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneIsComposingIdleReceived, 2)); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +void printHex(char *title, uint8_t *data, uint32_t length) { + int i; + printf ("%s : ", title); + for (i=0; ipeerZID, 12); + printHex("key", associatedKeys.peerKeys[i]->key, 32); + printHex("sessionID", associatedKeys.peerKeys[i]->sessionId, 32); + printf("session index %d\n", associatedKeys.peerKeys[i]->sessionIndex); + } + + /* get data from cache : receiver */ + memcpy(associatedKey.peerZID, targetZID, 12); + retval = lime_getCachedRcvKeyByZid(cacheBuffer, &associatedKey); + printf("getCachedKey by ZID return %d\n", retval); + + printHex("Key", associatedKey.key, 32); + printHex("sessionID", associatedKey.sessionId, 32); + printf("session index %d\n", associatedKey.sessionIndex); + + /* encrypt/decrypt a message */ + lime_encryptMessage(associatedKeys.peerKeys[0], (uint8_t *)"bla Bla bla b! Pipo", 20, senderZID, encryptedMessage); + printHex("Ciphered", encryptedMessage, 32); + /* invert sender and receiverZID to decrypt/authenticate */ + memcpy(receiverZID, associatedKeys.peerKeys[0]->peerZID, 12); + memcpy(associatedKeys.peerKeys[0]->peerZID, senderZID, 12); + retval = lime_decryptMessage(associatedKeys.peerKeys[0], encryptedMessage, 36, receiverZID, plainMessage); + printf("Decrypt and auth returned %d\nPlain: %s\n", retval, plainMessage); + + /* update receiver data */ + associatedKey.sessionIndex++; + associatedKey.key[0]++; + associatedKey.sessionId[0]++; + retval = lime_setCachedKey(cacheBuffer, &associatedKey, LIME_RECEIVER); + printf("setCachedKey return %d\n", retval); + + /* update sender data */ + associatedKeys.peerKeys[0]->sessionIndex++; + associatedKeys.peerKeys[0]->key[0]++; + associatedKeys.peerKeys[0]->sessionId[0]++; + retval = lime_setCachedKey(cacheBuffer, associatedKeys.peerKeys[0], LIME_SENDER); + printf("setCachedKey return %d\n", retval); + + /* free memory */ + lime_freeKeys(associatedKeys); + + /* write the file */ + /* dump the xml document into a string */ + xmlDocDumpFormatMemoryEnc(cacheBuffer, &xmlStringOutput, &xmlStringLength, "UTF-8", 0); + /* write it to the file */ + CACHE = fopen("ZIDCache.xml", "w+"); + fwrite(xmlStringOutput, 1, xmlStringLength, CACHE); + xmlFree(xmlStringOutput); + fclose(CACHE); + xmlFreeDoc(cacheBuffer); +} + +static void lime_text_message(void) { + char* to; + FILE *ZIDCacheMarieFD, *ZIDCachePaulineFD; + LinphoneChatRoom* chat_room; + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + + /* make sure lime is enabled */ + linphone_core_enable_lime(marie->lc, 1); + linphone_core_enable_lime(pauline->lc, 1); + + /* set the zid caches files : create two ZID cache from this valid one inserting the auto-generated sip URI for the peer account as keys in ZID cache are indexed by peer sip uri */ + ZIDCacheMarieFD = fopen("tmpZIDCacheMarie.xml", "w"); + ZIDCachePaulineFD = fopen("tmpZIDCachePauline.xml", "w"); + fprintf(ZIDCacheMarieFD, "\nef7692d0792a67491ae2d44e005dbe0399643d953a2202dd9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899%s08df5907d30959b8cb70f6fff2d8febd88fb41b0c8afc39e4b972f86dd5cfe2d60f020a3fe11dc2cc0e1e8ed9341b4cd14944db806ca4fc95456bbe45d95c43a5f9aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b77193bcffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b7719300000078000001cf011234567889643d953a2202ee9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899%s72d80ab1cad243cf45634980c1d02cfb2df81ce0dd5dfcf1ebeacfc5345a917625d9ac653a83c4559cb0ae7394e7cd3b2d3c57bb28e62068d2df23e8f9b77193f69aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b7719322ffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b771930000000f00000000", linphone_address_as_string_uri_only(pauline->identity), linphone_address_as_string_uri_only(pauline->identity)); + fprintf(ZIDCachePaulineFD, "\n005dbe0399643d953a2202ddef7692d0792a67491ae2d44e9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899%s08df5907d30959b8cb70f6fff2d8febd88fb41b0c8afc39e4b972f86dd5cfe2d60f020a3fe11dc2cc0e1e8ed9341b4cd14944db806ca4fc95456bbe45d95c43a5f9aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b77193bcffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b7719300000078000001cf011234567889643d953a2202ee9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899%s81e6e6362c34dc974263d1f77cbb9a8d6d6a718330994379099a8fa19fb12faa25d9ac653a83c4559cb0ae7394e7cd3b2d3c57bb28e62068d2df23e8f9b77193f69aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b7719322ffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b771930000002e0000000001", linphone_address_as_string_uri_only(marie->identity), linphone_address_as_string_uri_only(marie->identity)); + fclose(ZIDCacheMarieFD); + fclose(ZIDCachePaulineFD); + linphone_core_set_zrtp_secrets_file(marie->lc, "tmpZIDCacheMarie.xml"); + linphone_core_set_zrtp_secrets_file(pauline->lc, "tmpZIDCachePauline.xml"); + + to = linphone_address_as_string(marie->identity); + chat_room = linphone_core_create_chat_room(pauline->lc,to); + ms_free(to); + + linphone_chat_room_send_message(chat_room,"Bla bla bla bla"); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1)); + CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageReceivedLegacy,1); + + CU_ASSERT_PTR_NOT_NULL(linphone_core_get_chat_room(marie->lc,pauline->identity)); + /* TODO : check the message arrived correctly deciphered */ linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } + #ifdef MSG_STORAGE_ENABLED /* @@ -1087,8 +1382,8 @@ static void message_storage_migration() { char src_db[256]; char tmp_db[256]; MSList* chatrooms; - snprintf(src_db,sizeof(src_db), "%s/messages.db", liblinphone_tester_file_prefix); - snprintf(tmp_db,sizeof(tmp_db), "%s/tmp.db", liblinphone_tester_writable_dir_prefix); + snprintf(src_db,sizeof(src_db), "%s/messages.db", bc_tester_read_dir_prefix); + snprintf(tmp_db,sizeof(tmp_db), "%s/tmp.db", bc_tester_writable_dir_prefix); CU_ASSERT_EQUAL_FATAL(message_tester_copy_file(src_db, tmp_db), 0); @@ -1127,8 +1422,8 @@ static void history_range_full_test(){ LinphoneChatRoom *chatroom; char src_db[256]; char tmp_db[256]; - snprintf(src_db,sizeof(src_db), "%s/messages.db", liblinphone_tester_file_prefix); - snprintf(tmp_db,sizeof(tmp_db), "%s/tmp.db", liblinphone_tester_writable_dir_prefix); + snprintf(src_db,sizeof(src_db), "%s/messages.db", bc_tester_read_dir_prefix); + snprintf(tmp_db,sizeof(tmp_db), "%s/tmp.db", bc_tester_writable_dir_prefix); CU_ASSERT_EQUAL_FATAL(message_tester_copy_file(src_db, tmp_db), 0); @@ -1169,8 +1464,8 @@ static void history_messages_count() { MSList *messages; char src_db[256]; char tmp_db[256]; - snprintf(src_db,sizeof(src_db), "%s/messages.db", liblinphone_tester_file_prefix); - snprintf(tmp_db,sizeof(tmp_db), "%s/tmp.db", liblinphone_tester_writable_dir_prefix); + snprintf(src_db,sizeof(src_db), "%s/messages.db", bc_tester_read_dir_prefix); + snprintf(tmp_db,sizeof(tmp_db), "%s/tmp.db", bc_tester_writable_dir_prefix); CU_ASSERT_EQUAL_FATAL(message_tester_copy_file(src_db, tmp_db), 0); @@ -1224,6 +1519,7 @@ static void history_messages_count() { #endif test_t message_tests[] = { + { "Lime Text Message", lime_text_message }, { "Text message", text_message }, { "Text message within call's dialog", text_message_within_dialog}, { "Text message with credentials from auth info cb", text_message_with_credential_from_auth_cb}, @@ -1238,11 +1534,13 @@ test_t message_tests[] = { /* { "File transfer message with io error at download", file_transfer_message_io_error_download },*/ { "File transfer message upload cancelled", file_transfer_message_upload_cancelled }, { "File transfer message download cancelled", file_transfer_message_download_cancelled }, + { "Lime File transfer message", lime_file_transfer_message }, { "File transfer message using external body url", file_transfer_using_external_body_url }, { "Text message denied", text_message_denied }, { "Info message", info_message }, { "Info message with body", info_message_with_body }, - { "IsComposing notification", is_composing_notification } + { "IsComposing notification", is_composing_notification }, + { "Lime Unitary", lime_unit } #ifdef MSG_STORAGE_ENABLED ,{ "Database migration", message_storage_migration } ,{ "History count", history_messages_count } diff --git a/tester/multi_call.c b/tester/multi_call.c new file mode 100644 index 000000000..14f0db9d1 --- /dev/null +++ b/tester/multi_call.c @@ -0,0 +1,449 @@ +/* + liblinphone_tester - liblinphone test suite + Copyright (C) 2013 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, see . +*/ + + +#include +#include +#include +#include "CUnit/Basic.h" +#include "linphonecore.h" +#include "lpconfig.h" +#include "private.h" +#include "liblinphone_tester.h" +#include "mediastreamer2/msutils.h" +#include "belle-sip/sipstack.h" + +#ifdef WIN32 +#define unlink _unlink +#endif + + +static void call_waiting_indication_with_param(bool_t enable_caller_privacy) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc"); + MSList *iterator; + MSList* lcs; + LinphoneCall* pauline_called_by_marie; + LinphoneCall* pauline_called_by_laure=NULL; + LinphoneCallParams *laure_params=linphone_core_create_default_call_parameters(laure->lc); + LinphoneCallParams *marie_params=linphone_core_create_default_call_parameters(marie->lc); + + if (enable_caller_privacy) + linphone_call_params_set_privacy(marie_params,LinphonePrivacyId); + + lcs=ms_list_append(NULL,marie->lc); + lcs=ms_list_append(lcs,pauline->lc); + lcs=ms_list_append(lcs,laure->lc); + + CU_ASSERT_TRUE(call_with_caller_params(marie,pauline,marie_params)); + pauline_called_by_marie=linphone_core_get_current_call(pauline->lc); + + if (enable_caller_privacy) + linphone_call_params_set_privacy(laure_params,LinphonePrivacyId); + + CU_ASSERT_PTR_NOT_NULL(linphone_core_invite_address_with_params(laure->lc,pauline->identity,laure_params)); + + CU_ASSERT_TRUE(wait_for(laure->lc + ,pauline->lc + ,&pauline->stat.number_of_LinphoneCallIncomingReceived + ,2)); + + CU_ASSERT_EQUAL(laure->stat.number_of_LinphoneCallOutgoingProgress,1); + + + CU_ASSERT_TRUE(wait_for(laure->lc + ,pauline->lc + ,&laure->stat.number_of_LinphoneCallOutgoingRinging + ,1)); + + for (iterator=(MSList *)linphone_core_get_calls(pauline->lc);iterator!=NULL;iterator=iterator->next) { + LinphoneCall *call=(LinphoneCall *)iterator->data; + if (call != pauline_called_by_marie) { + /*fine, this is the call waiting*/ + pauline_called_by_laure=call; + linphone_core_accept_call(pauline->lc,pauline_called_by_laure); + } + } + + CU_ASSERT_TRUE(wait_for(laure->lc + ,pauline->lc + ,&laure->stat.number_of_LinphoneCallConnected + ,1)); + + CU_ASSERT_TRUE(wait_for(pauline->lc + ,marie->lc + ,&marie->stat.number_of_LinphoneCallPausedByRemote + ,1)); + + if (pauline_called_by_laure && enable_caller_privacy ) + CU_ASSERT_EQUAL(linphone_call_params_get_privacy(linphone_call_get_current_params(pauline_called_by_laure)),LinphonePrivacyId); + /*wait a bit for ACK to be sent*/ + wait_for_list(lcs,NULL,0,1000); + linphone_core_terminate_all_calls(pauline->lc); + + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,10000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,10000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallEnd,1,10000)); + + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(laure); + ms_list_free(lcs); +} +static void call_waiting_indication(void) { + call_waiting_indication_with_param(FALSE); +} + +static void call_waiting_indication_with_privacy(void) { + call_waiting_indication_with_param(TRUE); +} + +static void simple_conference_base(LinphoneCoreManager* marie, LinphoneCoreManager* pauline, LinphoneCoreManager* laure) { + + stats initial_marie_stat; + stats initial_pauline_stat; + stats initial_laure_stat; + + LinphoneCall* marie_call_pauline; + LinphoneCall* pauline_called_by_marie; + LinphoneCall* marie_call_laure; + + MSList* lcs=ms_list_append(NULL,marie->lc); + lcs=ms_list_append(lcs,pauline->lc); + lcs=ms_list_append(lcs,laure->lc); + + CU_ASSERT_TRUE(call(marie,pauline)); + marie_call_pauline=linphone_core_get_current_call(marie->lc); + pauline_called_by_marie=linphone_core_get_current_call(pauline->lc); + CU_ASSERT_TRUE(pause_call_1(marie,marie_call_pauline,pauline,pauline_called_by_marie)); + + CU_ASSERT_TRUE(call(marie,laure)); + initial_marie_stat=marie->stat; + initial_pauline_stat=pauline->stat; + initial_laure_stat=laure->stat; + + marie_call_laure=linphone_core_get_current_call(marie->lc); + + CU_ASSERT_PTR_NOT_NULL_FATAL(marie_call_laure); + linphone_core_add_to_conference(marie->lc,marie_call_laure); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallUpdating,initial_marie_stat.number_of_LinphoneCallUpdating+1,5000)); + + linphone_core_add_to_conference(marie->lc,marie_call_pauline); + + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallResuming,initial_marie_stat.number_of_LinphoneCallResuming+1,2000)); + + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,initial_pauline_stat.number_of_LinphoneCallStreamsRunning+1,5000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallStreamsRunning,initial_laure_stat.number_of_LinphoneCallStreamsRunning+1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,initial_marie_stat.number_of_LinphoneCallStreamsRunning+2,3000)); + + CU_ASSERT_TRUE(linphone_core_is_in_conference(marie->lc)); + CU_ASSERT_EQUAL(linphone_core_get_conference_size(marie->lc),3); + + /* + * FIXME: check_ice cannot work as it is today because there is no current call for the party that hosts the conference + if (linphone_core_get_firewall_policy(marie->lc) == LinphonePolicyUseIce) { + if (linphone_core_get_firewall_policy(pauline->lc) == LinphonePolicyUseIce) { + check_ice(marie,pauline,LinphoneIceStateHostConnection); + } + if (linphone_core_get_firewall_policy(laure->lc) == LinphonePolicyUseIce) { + check_ice(marie,laure,LinphoneIceStateHostConnection); + } + } + */ + + linphone_core_terminate_conference(marie->lc); + + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,10000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,10000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallEnd,1,10000)); + + + + ms_list_free(lcs); +} +static void simple_conference(void) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc"); + simple_conference_base(marie,pauline,laure); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(laure); +} + +static void simple_conference_with_ice(void) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc"); + + linphone_core_set_firewall_policy(marie->lc,LinphonePolicyUseIce); + linphone_core_set_stun_server(marie->lc,"stun.linphone.org"); + linphone_core_set_firewall_policy(pauline->lc,LinphonePolicyUseIce); + linphone_core_set_stun_server(pauline->lc,"stun.linphone.org"); + linphone_core_set_firewall_policy(laure->lc,LinphonePolicyUseIce); + linphone_core_set_stun_server(laure->lc,"stun.linphone.org"); + + simple_conference_base(marie,pauline,laure); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(laure); +} + + +static void simple_call_transfer(void) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc"); + LinphoneCall* pauline_called_by_marie; + LinphoneCall *marie_calling_pauline; + LinphoneCall *marie_calling_laure; + + char* laure_identity=linphone_address_as_string(laure->identity); + MSList* lcs=ms_list_append(NULL,marie->lc); + lcs=ms_list_append(lcs,pauline->lc); + lcs=ms_list_append(lcs,laure->lc); + + + CU_ASSERT_TRUE(call(marie,pauline)); + marie_calling_pauline=linphone_core_get_current_call(marie->lc); + pauline_called_by_marie=linphone_core_get_current_call(pauline->lc); + + reset_counters(&marie->stat); + reset_counters(&pauline->stat); + reset_counters(&laure->stat); + + + linphone_core_transfer_call(pauline->lc,pauline_called_by_marie,laure_identity); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallRefered,1,2000)); + /*marie pausing pauline*/ + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallPausing,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallPausedByRemote,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallPaused,1,2000)); + /*marie calling laure*/ + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallOutgoingProgress,1,2000)); + + CU_ASSERT_PTR_NOT_NULL(linphone_call_get_transfer_target_call(marie_calling_pauline)); + + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneTransferCallOutgoingInit,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallIncomingReceived,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallOutgoingRinging,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneTransferCallOutgoingProgress,1,2000)); + linphone_core_accept_call(laure->lc,linphone_core_get_current_call(laure->lc)); + CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallConnected,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallStreamsRunning,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallConnected,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,2000)); + + marie_calling_laure=linphone_core_get_current_call(marie->lc); + CU_ASSERT_PTR_NOT_NULL_FATAL(marie_calling_laure); + CU_ASSERT_TRUE(linphone_call_get_transferer_call(marie_calling_laure)==marie_calling_pauline); + + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneTransferCallConnected,1,2000)); + + /*terminate marie to pauline call*/ + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,2000)); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(laure); + ms_list_free(lcs); +} + +static void unattended_call_transfer(void) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc"); + LinphoneCall* pauline_called_by_marie; + + char* laure_identity=linphone_address_as_string(laure->identity); + MSList* lcs=ms_list_append(NULL,marie->lc); + lcs=ms_list_append(lcs,pauline->lc); + lcs=ms_list_append(lcs,laure->lc); + + + CU_ASSERT_TRUE(call(marie,pauline)); + pauline_called_by_marie=linphone_core_get_current_call(marie->lc); + + reset_counters(&marie->stat); + reset_counters(&pauline->stat); + reset_counters(&laure->stat); + + linphone_core_transfer_call(marie->lc,pauline_called_by_marie,laure_identity); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallRefered,1,2000)); + + /*marie ends the call */ + linphone_core_terminate_call(marie->lc,pauline_called_by_marie); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,2000)); + + /*Pauline starts the transfer*/ + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingInit,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingProgress,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallIncomingReceived,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,2000)); + linphone_core_accept_call(laure->lc,linphone_core_get_current_call(laure->lc)); + CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallConnected,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallStreamsRunning,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,2000)); + + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,2000)); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(laure); + ms_list_free(lcs); +} + +static void unattended_call_transfer_with_error(void) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCall* pauline_called_by_marie; + bool_t call_ok=TRUE; + MSList* lcs=ms_list_append(NULL,marie->lc); + + lcs=ms_list_append(lcs,pauline->lc); + + CU_ASSERT_TRUE((call_ok=call(marie,pauline))); + if (call_ok){ + pauline_called_by_marie=linphone_core_get_current_call(marie->lc); + + reset_counters(&marie->stat); + reset_counters(&pauline->stat); + + linphone_core_transfer_call(marie->lc,pauline_called_by_marie,"unknown_user"); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallRefered,1,2000)); + + /*Pauline starts the transfer*/ + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingInit,1,2000)); + /* and immediately get an error*/ + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallError,1,2000)); + + /*the error must be reported back to marie*/ + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneTransferCallError,1,2000)); + + /*and pauline should resume the call automatically*/ + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallResuming,1,2000)); + + /*and call should be resumed*/ + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,2000)); + } + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + ms_list_free(lcs); +} + + +static void call_transfer_existing_call_outgoing_call(void) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc"); + LinphoneCall* marie_call_pauline; + LinphoneCall* pauline_called_by_marie; + LinphoneCall* marie_call_laure; + LinphoneCall* laure_called_by_marie; + LinphoneCall* lcall; + bool_t call_ok=TRUE; + const MSList* calls; + MSList* lcs=ms_list_append(NULL,marie->lc); + + lcs=ms_list_append(lcs,pauline->lc); + lcs=ms_list_append(lcs,laure->lc); + + /*marie call pauline*/ + CU_ASSERT_TRUE((call_ok=call(marie,pauline))); + if (call_ok){ + marie_call_pauline=linphone_core_get_current_call(marie->lc); + pauline_called_by_marie=linphone_core_get_current_call(pauline->lc); + /*marie pause pauline*/ + CU_ASSERT_TRUE(pause_call_1(marie,marie_call_pauline,pauline,pauline_called_by_marie)); + + /*marie call laure*/ + CU_ASSERT_TRUE(call(marie,laure)); + marie_call_laure=linphone_core_get_current_call(marie->lc); + laure_called_by_marie=linphone_core_get_current_call(laure->lc); + /*marie pause laure*/ + CU_ASSERT_TRUE(pause_call_1(marie,marie_call_laure,laure,laure_called_by_marie)); + + reset_counters(&marie->stat); + reset_counters(&pauline->stat); + reset_counters(&laure->stat); + + + linphone_core_transfer_call_to_another(marie->lc,marie_call_pauline,marie_call_laure); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallRefered,1,2000)); + + /*pauline pausing marie*/ + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallPausing,1,4000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallPaused,1,4000)); + /*pauline calling laure*/ + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingProgress,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneTransferCallOutgoingInit,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallIncomingReceived,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneTransferCallOutgoingProgress,1,2000)); + + /*laure accept call*/ + for(calls=linphone_core_get_calls(laure->lc);calls!=NULL;calls=calls->next) { + lcall = (LinphoneCall*)calls->data; + if (linphone_call_get_state(lcall) == LinphoneCallIncomingReceived) { + CU_ASSERT_EQUAL(linphone_call_get_replaced_call(lcall),laure_called_by_marie); + linphone_core_accept_call(laure->lc,lcall); + break; + } + } + CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallConnected,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallStreamsRunning,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneTransferCallConnected,1,2000)); + + /*terminate marie to pauline/laure call*/ + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,2,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallEnd,1,2000)); + } + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(laure); + ms_list_free(lcs); +} + +test_t multi_call_tests[] = { + { "Call waiting indication", call_waiting_indication }, + { "Call waiting indication with privacy", call_waiting_indication_with_privacy }, + { "Simple conference", simple_conference }, + { "Simple conference with ICE",simple_conference_with_ice}, + { "Simple call transfer", simple_call_transfer }, + { "Unattended call transfer", unattended_call_transfer }, + { "Unattended call transfer with error", unattended_call_transfer_with_error }, + { "Call transfer existing call outgoing call", call_transfer_existing_call_outgoing_call } +}; + +test_suite_t multi_call_test_suite = { + "Multi call", + NULL, + NULL, + sizeof(multi_call_tests) / sizeof(multi_call_tests[0]), + multi_call_tests +}; diff --git a/tester/offeranswer_tester.c b/tester/offeranswer_tester.c index b9de6a879..0a659aaf3 100644 --- a/tester/offeranswer_tester.c +++ b/tester/offeranswer_tester.c @@ -157,7 +157,7 @@ static void call_failed_because_of_codecs(void) { } -static void profile_call(bool_t avpf1, bool_t srtp1, bool_t avpf2, bool_t srtp2, const char *expected_profile) { +static void profile_call_base(bool_t avpf1, LinphoneMediaEncryption srtp1,bool_t avpf2, LinphoneMediaEncryption srtp2, bool_t encryption_mandatory, const char *expected_profile) { LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_rc"); LinphoneProxyConfig *lpc; @@ -173,15 +173,25 @@ static void profile_call(bool_t avpf1, bool_t srtp1, bool_t avpf2, bool_t srtp2, linphone_proxy_config_enable_avpf(lpc, TRUE); linphone_proxy_config_set_avpf_rr_interval(lpc, 3); } - if (srtp1) { - if (linphone_core_media_encryption_supported(marie->lc, LinphoneMediaEncryptionSRTP)) { - linphone_core_set_media_encryption(marie->lc, LinphoneMediaEncryptionSRTP); - } + + if (encryption_mandatory) { + linphone_core_set_media_encryption_mandatory(marie->lc,TRUE); + linphone_core_set_media_encryption_mandatory(pauline->lc,TRUE); } - if (srtp2) { - if (linphone_core_media_encryption_supported(pauline->lc, LinphoneMediaEncryptionSRTP)) { - linphone_core_set_media_encryption(pauline->lc, LinphoneMediaEncryptionSRTP); - } + + if (linphone_core_media_encryption_supported(marie->lc, srtp1)) { + linphone_core_set_media_encryption(marie->lc, srtp1); + } else { + ms_message("Unsupported [%s] encryption type, cannot test",linphone_media_encryption_to_string(srtp1)); + goto end; + + } + if (linphone_core_media_encryption_supported(pauline->lc, srtp2)) { + linphone_core_set_media_encryption(pauline->lc, srtp2); + }else { + ms_message("Unsupported [%s] encryption type, cannot test",linphone_media_encryption_to_string(srtp2)); + goto end; + } CU_ASSERT_TRUE(call(marie, pauline)); @@ -197,73 +207,94 @@ static void profile_call(bool_t avpf1, bool_t srtp1, bool_t avpf2, bool_t srtp2, CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallEnd, 1)); CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallConnected, 1); CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallConnected, 1); - +end: linphone_core_manager_destroy(pauline); linphone_core_manager_destroy(marie); } +static void profile_call(bool_t avpf1, LinphoneMediaEncryption srtp1, bool_t avpf2, LinphoneMediaEncryption srtp2, const char *expected_profile) { + return profile_call_base(avpf1, srtp1, avpf2,srtp2,FALSE,expected_profile); +} static void avp_to_avp_call(void) { - profile_call(FALSE, FALSE, FALSE, FALSE, "RTP/AVP"); + profile_call(FALSE, LinphoneMediaEncryptionNone, FALSE, LinphoneMediaEncryptionNone, "RTP/AVP"); } static void avp_to_avpf_call(void) { - profile_call(FALSE, FALSE, TRUE, FALSE, "RTP/AVP"); + profile_call(FALSE, LinphoneMediaEncryptionNone, TRUE, LinphoneMediaEncryptionNone, "RTP/AVP"); } static void avp_to_savp_call(void) { - profile_call(FALSE, FALSE, FALSE, TRUE, "RTP/AVP"); + profile_call(FALSE, LinphoneMediaEncryptionNone, FALSE, LinphoneMediaEncryptionSRTP, "RTP/AVP"); } static void avp_to_savpf_call(void) { - profile_call(FALSE, FALSE, TRUE, TRUE, "RTP/AVP"); + profile_call(FALSE, LinphoneMediaEncryptionNone, TRUE, LinphoneMediaEncryptionSRTP, "RTP/AVP"); } static void avpf_to_avp_call(void) { - profile_call(TRUE, FALSE, FALSE, FALSE, "RTP/AVPF"); + profile_call(TRUE, LinphoneMediaEncryptionNone, FALSE, LinphoneMediaEncryptionNone, "RTP/AVPF"); } static void avpf_to_avpf_call(void) { - profile_call(TRUE, FALSE, TRUE, FALSE, "RTP/AVPF"); + profile_call(TRUE, LinphoneMediaEncryptionNone, TRUE, LinphoneMediaEncryptionNone, "RTP/AVPF"); } static void avpf_to_savp_call(void) { - profile_call(TRUE, FALSE, FALSE, TRUE, "RTP/AVPF"); + profile_call(TRUE, LinphoneMediaEncryptionNone, FALSE, LinphoneMediaEncryptionSRTP, "RTP/AVPF"); } static void avpf_to_savpf_call(void) { - profile_call(TRUE, FALSE, TRUE, TRUE, "RTP/AVPF"); + profile_call(TRUE, LinphoneMediaEncryptionNone, TRUE, LinphoneMediaEncryptionSRTP, "RTP/AVPF"); } static void savp_to_avp_call(void) { - profile_call(FALSE, TRUE, FALSE, FALSE, "RTP/SAVP"); + profile_call(FALSE, LinphoneMediaEncryptionSRTP, FALSE, LinphoneMediaEncryptionNone, "RTP/SAVP"); } static void savp_to_avpf_call(void) { - profile_call(FALSE, TRUE, TRUE, FALSE, "RTP/SAVP"); + profile_call(FALSE, LinphoneMediaEncryptionSRTP, TRUE, LinphoneMediaEncryptionNone, "RTP/SAVP"); } static void savp_to_savp_call(void) { - profile_call(FALSE, TRUE, FALSE, TRUE, "RTP/SAVP"); + profile_call(FALSE, LinphoneMediaEncryptionSRTP, FALSE, LinphoneMediaEncryptionSRTP, "RTP/SAVP"); } static void savp_to_savpf_call(void) { - profile_call(FALSE, TRUE, TRUE, TRUE, "RTP/SAVP"); + profile_call(FALSE, LinphoneMediaEncryptionSRTP, TRUE, LinphoneMediaEncryptionSRTP, "RTP/SAVP"); } static void savpf_to_avp_call(void) { - profile_call(TRUE, TRUE, FALSE, FALSE, "RTP/SAVPF"); + profile_call(TRUE, LinphoneMediaEncryptionSRTP, FALSE, LinphoneMediaEncryptionNone, "RTP/SAVPF"); } static void savpf_to_avpf_call(void) { - profile_call(TRUE, TRUE, TRUE, FALSE, "RTP/SAVPF"); + profile_call(TRUE, LinphoneMediaEncryptionSRTP, TRUE, LinphoneMediaEncryptionNone, "RTP/SAVPF"); } static void savpf_to_savp_call(void) { - profile_call(TRUE, TRUE, FALSE, TRUE, "RTP/SAVPF"); + profile_call(TRUE, LinphoneMediaEncryptionSRTP, FALSE, LinphoneMediaEncryptionSRTP, "RTP/SAVPF"); } static void savpf_to_savpf_call(void) { - profile_call(TRUE, TRUE, TRUE, TRUE, "RTP/SAVPF"); + profile_call(TRUE, LinphoneMediaEncryptionSRTP, TRUE, LinphoneMediaEncryptionSRTP, "RTP/SAVPF"); +} + +static void savpf_dtls_to_savpf_dtls_call(void) { + profile_call(TRUE, LinphoneMediaEncryptionDTLS, TRUE, LinphoneMediaEncryptionDTLS, "UDP/TLS/RTP/SAVPF"); +} +static void savpf_dtls_to_savpf_dtls_encryption_mandatory_call(void) { + profile_call_base(TRUE, LinphoneMediaEncryptionDTLS, TRUE, LinphoneMediaEncryptionDTLS, TRUE, "UDP/TLS/RTP/SAVPF"); +} +static void savpf_dtls_to_savpf_encryption_mandatory_call(void) { + /*profile_call_base(TRUE, LinphoneMediaEncryptionDTLS, TRUE, LinphoneMediaEncryptionSRTP, TRUE, "UDP/TLS/RTP/SAVPF"); not sure of result*/ +} + +static void savpf_dtls_to_savpf_call(void) { + profile_call(TRUE, LinphoneMediaEncryptionDTLS, TRUE, LinphoneMediaEncryptionSRTP, "UDP/TLS/RTP/SAVPF"); +} + +static void savpf_dtls_to_avpf_call(void) { + profile_call(TRUE, LinphoneMediaEncryptionDTLS, TRUE, LinphoneMediaEncryptionNone, "UDP/TLS/RTP/SAVPF"); } static test_t offeranswer_tests[] = { @@ -286,6 +317,12 @@ static test_t offeranswer_tests[] = { { "SAVPF to AVPF call", savpf_to_avpf_call }, { "SAVPF to SAVP call", savpf_to_savp_call }, { "SAVPF to SAVPF call", savpf_to_savpf_call }, + { "SAVPF/DTLS to SAVPF/DTLS call", savpf_dtls_to_savpf_dtls_call}, + { "SAVPF/DTLS to SAVPF/DTLS encryption mandatory call", savpf_dtls_to_savpf_dtls_encryption_mandatory_call}, + { "SAVPF/DTLS to SAVPF call", savpf_dtls_to_savpf_call}, + { "SAVPF/DTLS to SAVPF encryption mandatory call", savpf_dtls_to_savpf_encryption_mandatory_call}, + { "SAVPF/DTLS to AVPF call", savpf_dtls_to_avpf_call}, + }; test_suite_t offeranswer_test_suite = { diff --git a/tester/player_tester.c b/tester/player_tester.c index beb6e9d19..e72cac9cd 100644 --- a/tester/player_tester.c +++ b/tester/player_tester.c @@ -71,7 +71,7 @@ static void play_file(const char *filename, bool_t unsupported_format, const cha } static void playing_test(void) { - char *filename = ms_strdup_printf("%s/sounds/hello_opus_h264.mkv", liblinphone_tester_file_prefix); + char *filename = ms_strdup_printf("%s/sounds/hello_opus_h264.mkv", bc_tester_read_dir_prefix); const char *audio_mime = "opus"; const char *video_mime = "h264"; play_file(filename, !linphone_local_player_matroska_supported(), audio_mime, video_mime); diff --git a/tester/register_tester.c b/tester/register_tester.c index b0687352d..ffd54f1a5 100644 --- a/tester/register_tester.c +++ b/tester/register_tester.c @@ -34,13 +34,13 @@ static void auth_info_requested(LinphoneCore *lc, const char *realm, const char static LinphoneCoreManager* create_lcm_with_auth(unsigned int with_auth) { LinphoneCoreManager* mgr=linphone_core_manager_new(NULL); - + if (with_auth) { LinphoneCoreVTable* vtable = linphone_core_v_table_new(); vtable->auth_info_requested=auth_info_requested; linphone_core_add_listener(mgr->lc,vtable); } - + /*to allow testing with 127.0.0.1*/ linphone_core_set_network_reachable(mgr->lc,TRUE); return mgr; @@ -195,12 +195,12 @@ static void register_with_custom_headers(void){ LinphoneProxyConfig *cfg=linphone_core_get_default_proxy_config(marie->lc); int initial_register_ok=marie->stat.number_of_LinphoneRegistrationOk; const char *value; - + linphone_core_set_network_reachable(marie->lc, FALSE); linphone_proxy_config_set_custom_header(cfg, "ah-bah-ouais", "...mais bon."); /*unfortunately it is difficult to programmatically check that sent custom headers are actually sent. * A server development would be required here.*/ - + linphone_core_set_network_reachable(marie->lc, TRUE); wait_for(marie->lc, NULL, &marie->stat.number_of_LinphoneRegistrationOk,initial_register_ok+1); value=linphone_proxy_config_get_custom_header(cfg, "Server"); @@ -336,11 +336,11 @@ static void authenticated_register_with_no_initial_credentials(){ LinphoneCoreVTable* vtable = linphone_core_v_table_new(); stats* counters; char route[256]; - + sprintf(route,"sip:%s",test_route); - + mgr = linphone_core_manager_new(NULL); - + vtable->auth_info_requested=auth_info_requested; linphone_core_add_listener(mgr->lc,vtable); @@ -357,9 +357,9 @@ static void authenticated_register_with_late_credentials(){ stats* counters; LCSipTransports transport = {5070,5070,0,5071}; char route[256]; - + sprintf(route,"sip:%s",test_route); - + mgr = linphone_core_manager_new(NULL); counters = get_stats(mgr->lc); @@ -397,9 +397,9 @@ static void authenticated_register_with_wrong_credentials_with_params_base(const LCSipTransports transport = {5070,5070,0,5071}; LinphoneAuthInfo *info=linphone_auth_info_new(test_username,NULL,"wrong passwd",NULL,auth_domain,NULL); /*create authentication structure from identity*/ char route[256]; - + sprintf(route,"sip:%s",test_route); - + sal_set_refresher_retry_after(mgr->lc->sal,500); if (user_agent) { linphone_core_set_user_agent(mgr->lc,user_agent,NULL); @@ -411,7 +411,7 @@ static void authenticated_register_with_wrong_credentials_with_params_base(const /*wait for retry*/ CU_ASSERT_TRUE(wait_for(mgr->lc,mgr->lc,&counters->number_of_auth_info_requested,4)); CU_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationFailed,1); - + /*check the detailed error info */ if (!user_agent || strcmp(user_agent,"tester-no-403")!=0){ LinphoneProxyConfig *cfg=NULL; @@ -425,7 +425,7 @@ static void authenticated_register_with_wrong_credentials_with_params_base(const CU_ASSERT_EQUAL(linphone_error_info_get_protocol_code(ei),403); CU_ASSERT_PTR_NULL(linphone_error_info_get_details(ei)); } - + } } static void authenticated_register_with_wrong_credentials_with_params(const char* user_agent) { @@ -474,7 +474,7 @@ static void network_state_change(){ stats *counters; LinphoneCoreManager *mgr=configure_lcm(); LinphoneCore *lc=mgr->lc; - + counters = get_stats(lc); register_ok=counters->number_of_LinphoneRegistrationOk; linphone_core_set_network_reachable(lc,FALSE); @@ -507,7 +507,7 @@ static void transport_change(){ int number_of_udp_proxy=0; int total_number_of_proxies; memset(&sip_tr,0,sizeof(sip_tr)); - + mgr=configure_lcm(); lc=mgr->lc; counters = get_stats(lc); @@ -630,7 +630,7 @@ static void io_recv_error(){ stats* counters ; int number_of_udp_proxy=0; - + mgr=configure_lcm(); lc=mgr->lc; counters = get_stats(lc); @@ -716,7 +716,7 @@ static void io_recv_error_without_active_register(){ mgr=configure_lcm(); lc=mgr->lc; counters = get_stats(lc); - + register_ok=counters->number_of_LinphoneRegistrationOk; number_of_udp_proxy=get_number_of_udp_proxy(lc); @@ -747,17 +747,17 @@ static void tls_certificate_failure(){ LinphoneCoreManager* mgr; LinphoneCore *lc; char rootcapath[256]; - + mgr=linphone_core_manager_new2("pauline_rc",FALSE); lc=mgr->lc; - snprintf(rootcapath,sizeof(rootcapath), "%s/certificates/cn/agent.pem", liblinphone_tester_file_prefix); /*bad root ca*/ + snprintf(rootcapath,sizeof(rootcapath), "%s/certificates/cn/agent.pem", bc_tester_read_dir_prefix); /*bad root ca*/ linphone_core_set_root_ca(mgr->lc,rootcapath); linphone_core_set_network_reachable(lc,TRUE); CU_ASSERT_TRUE(wait_for(mgr->lc,mgr->lc,&mgr->stat.number_of_LinphoneRegistrationFailed,1)); linphone_core_set_root_ca(mgr->lc,NULL); /*no root ca*/ linphone_core_refresh_registers(mgr->lc); CU_ASSERT_TRUE(wait_for(lc,lc,&mgr->stat.number_of_LinphoneRegistrationFailed,2)); - snprintf(rootcapath,sizeof(rootcapath), "%s/certificates/cn/cafile.pem", liblinphone_tester_file_prefix); /*goot root ca*/ + snprintf(rootcapath,sizeof(rootcapath), "%s/certificates/cn/cafile.pem", bc_tester_read_dir_prefix); /*goot root ca*/ linphone_core_set_root_ca(mgr->lc,rootcapath); linphone_core_refresh_registers(mgr->lc); CU_ASSERT_TRUE(wait_for(lc,lc,&mgr->stat.number_of_LinphoneRegistrationOk,1)); @@ -772,7 +772,7 @@ static void tls_with_non_tls_server(){ LinphoneAddress* addr; char tmp[256]; LinphoneCore *lc; - + mgr=linphone_core_manager_new2( "marie_rc", 0); lc=mgr->lc; sal_set_transport_timeout(lc->sal,3000); @@ -792,10 +792,10 @@ static void tls_alt_name_register(){ LinphoneCoreManager* mgr; LinphoneCore *lc; char rootcapath[256]; - + mgr=linphone_core_manager_new2("pauline_alt_rc",FALSE); lc=mgr->lc; - snprintf(rootcapath,sizeof(rootcapath), "%s/certificates/cn/cafile.pem", liblinphone_tester_file_prefix); + snprintf(rootcapath,sizeof(rootcapath), "%s/certificates/cn/cafile.pem", bc_tester_read_dir_prefix); linphone_core_set_root_ca(mgr->lc,rootcapath); linphone_core_refresh_registers(mgr->lc); CU_ASSERT_TRUE(wait_for(lc,lc,&mgr->stat.number_of_LinphoneRegistrationOk,1)); @@ -807,10 +807,10 @@ static void tls_wildcard_register(){ LinphoneCoreManager* mgr; LinphoneCore *lc; char rootcapath[256]; - + mgr=linphone_core_manager_new2("pauline_wild_rc",FALSE); lc=mgr->lc; - snprintf(rootcapath,sizeof(rootcapath), "%s/certificates/cn/cafile.pem", liblinphone_tester_file_prefix); + snprintf(rootcapath,sizeof(rootcapath), "%s/certificates/cn/cafile.pem", bc_tester_read_dir_prefix); linphone_core_set_root_ca(mgr->lc,rootcapath); linphone_core_refresh_registers(mgr->lc); CU_ASSERT_TRUE(wait_for(lc,lc,&mgr->stat.number_of_LinphoneRegistrationOk,2)); diff --git a/tester/setup_tester.c b/tester/setup_tester.c index 06d734d6a..03cb36a8b 100644 --- a/tester/setup_tester.c +++ b/tester/setup_tester.c @@ -128,7 +128,7 @@ static void linphone_lpconfig_from_buffer_zerolen_value(){ static void linphone_lpconfig_from_file_zerolen_value(){ /* parameters that have no value should return NULL, not "". */ const char* zero_rc_file = "zero_length_params_rc"; - char* rc_path = ms_strdup_printf("%s/rcfiles/%s", liblinphone_tester_file_prefix, zero_rc_file); + char* rc_path = ms_strdup_printf("%s/rcfiles/%s", bc_tester_read_dir_prefix, zero_rc_file); LpConfig* conf; /* not using lp_config_new() because it expects a readable file, and iOS (for instance) @@ -149,7 +149,7 @@ static void linphone_lpconfig_from_file_zerolen_value(){ static void linphone_lpconfig_from_xml_zerolen_value(){ const char* zero_xml_file = "remote_zero_length_params_rc"; - char* xml_path = ms_strdup_printf("%s/rcfiles/%s", liblinphone_tester_file_prefix, zero_xml_file); + char* xml_path = ms_strdup_printf("%s/rcfiles/%s", bc_tester_read_dir_prefix, zero_xml_file); LpConfig* conf; LinphoneCoreManager* mgr = linphone_core_manager_new2("empty_rc",FALSE); diff --git a/tester/tester.c b/tester/tester.c index aadfbee83..f63562f71 100644 --- a/tester/tester.c +++ b/tester/tester.c @@ -29,44 +29,18 @@ #include #endif -static test_suite_t **test_suite = NULL; -static int nb_test_suites = 0; - - -#if HAVE_CU_CURSES -static unsigned char curses = 0; -#endif + static bool_t liblinphone_tester_ipv6_enabled=FALSE; + static int liblinphone_tester_keep_accounts_flag = 0; + static int manager_count = 0; const char* test_domain="sipopen.example.org"; const char* auth_domain="sip.example.org"; const char* test_username="liblinphone_tester"; const char* test_password="secret"; const char* test_route="sip2.linphone.org"; -int liblinphone_tester_use_log_file=0; -static int liblinphone_tester_keep_accounts_flag = 0; -static bool_t liblinphone_tester_ipv6_enabled=FALSE; -static int manager_count = 0; - -static const char* liblinphone_tester_xml_file = NULL; -static int liblinphone_tester_xml_enabled = FALSE; - -#if WINAPI_FAMILY_PHONE_APP -const char *liblinphone_tester_file_prefix="Assets"; -#elif defined(__QNX__) -const char *liblinphone_tester_file_prefix="./app/native/assets/"; -#else -const char *liblinphone_tester_file_prefix="."; -#endif - -/* TODO: have the same "static" for QNX and windows as above? */ -#ifdef ANDROID -const char *liblinphone_tester_writable_dir_prefix = "/data/data/org.linphone.tester/cache"; -#else -const char *liblinphone_tester_writable_dir_prefix = "."; -#endif - const char *userhostsfile = "tester_hosts"; -static void network_reachable(LinphoneCore *lc, bool_t reachable) { + + static void network_reachable(LinphoneCore *lc, bool_t reachable) { stats* counters; ms_message("Network reachable [%s]",reachable?"TRUE":"FALSE"); counters = get_stats(lc); @@ -114,8 +88,6 @@ static void auth_info_requested(LinphoneCore *lc, const char *realm, const char counters->number_of_auth_info_requested++; } - - void reset_counters( stats* counters) { if (counters->last_received_chat_message) linphone_chat_message_unref(counters->last_received_chat_message); memset(counters,0,sizeof(stats)); @@ -252,11 +224,9 @@ LinphoneCoreManager *get_manager(LinphoneCore *lc){ return manager; } -LinphoneCoreManager* linphone_core_manager_new2(const char* rc_file, int check_for_proxies) { +LinphoneCoreManager* linphone_core_manager_init(const char* rc_file) { LinphoneCoreManager* mgr= ms_new0(LinphoneCoreManager,1); - LinphoneProxyConfig* proxy; char *rc_path = NULL; - int proxy_count; mgr->number_of_cunit_error_at_creation = CU_get_number_of_failures(); mgr->v_table.registration_state_changed=registration_state_changed; mgr->v_table.auth_info_requested=auth_info_requested; @@ -279,13 +249,8 @@ LinphoneCoreManager* linphone_core_manager_new2(const char* rc_file, int check_f reset_counters(&mgr->stat); if (rc_file) rc_path = ms_strdup_printf("rcfiles/%s", rc_file); - mgr->lc=configure_lc_from(&mgr->v_table, liblinphone_tester_file_prefix, rc_path, mgr); + mgr->lc=configure_lc_from(&mgr->v_table, bc_tester_read_dir_prefix, rc_path, mgr); linphone_core_manager_check_accounts(mgr); - /*CU_ASSERT_EQUAL(ms_list_size(linphone_core_get_proxy_config_list(lc)),proxy_count);*/ - if (check_for_proxies && rc_file) /**/ - proxy_count=ms_list_size(linphone_core_get_proxy_config_list(mgr->lc)); - else - proxy_count=0; manager_count++; @@ -296,15 +261,30 @@ LinphoneCoreManager* linphone_core_manager_new2(const char* rc_file, int check_f if( manager_count >= 2){ char hellopath[512]; - char *recordpath = ms_strdup_printf("%s/record_for_lc_%p.wav",liblinphone_tester_writable_dir_prefix,mgr->lc); + char *recordpath = ms_strdup_printf("%s/record_for_lc_%p.wav",bc_tester_writable_dir_prefix,mgr->lc); ms_message("Manager for '%s' using files", rc_file ? rc_file : "--"); linphone_core_use_files(mgr->lc, TRUE); - snprintf(hellopath,sizeof(hellopath), "%s/sounds/hello8000.wav", liblinphone_tester_file_prefix); + snprintf(hellopath,sizeof(hellopath), "%s/sounds/hello8000.wav", bc_tester_read_dir_prefix); linphone_core_set_play_file(mgr->lc,hellopath); linphone_core_set_record_file(mgr->lc,recordpath); ms_free(recordpath); } + if (rc_path) ms_free(rc_path); + + return mgr; +} + +void linphone_core_manager_start(LinphoneCoreManager *mgr, const char* rc_file, int check_for_proxies) { + LinphoneProxyConfig* proxy; + int proxy_count; + + /*CU_ASSERT_EQUAL(ms_list_size(linphone_core_get_proxy_config_list(lc)),proxy_count);*/ + if (check_for_proxies && rc_file) /**/ + proxy_count=ms_list_size(linphone_core_get_proxy_config_list(mgr->lc)); + else + proxy_count=0; + if (proxy_count){ #define REGISTER_TIMEOUT 20 /* seconds */ int success = wait_for_until(mgr->lc,NULL,&mgr->stat.number_of_LinphoneRegistrationOk, @@ -321,12 +301,18 @@ LinphoneCoreManager* linphone_core_manager_new2(const char* rc_file, int check_f mgr->identity = linphone_address_new(linphone_proxy_config_get_identity(proxy)); linphone_address_clean(mgr->identity); } - if (rc_path) ms_free(rc_path); - return mgr; } LinphoneCoreManager* linphone_core_manager_new( const char* rc_file) { - return linphone_core_manager_new2(rc_file, TRUE); + LinphoneCoreManager *manager = linphone_core_manager_init(rc_file); + linphone_core_manager_start(manager, rc_file, TRUE); + return manager; +} + +LinphoneCoreManager* linphone_core_manager_new2( const char* rc_file, int check_for_proxies) { + LinphoneCoreManager *manager = linphone_core_manager_init(rc_file); + linphone_core_manager_start(manager, rc_file, check_for_proxies); + return manager; } void linphone_core_manager_stop(LinphoneCoreManager *mgr){ @@ -355,294 +341,6 @@ void linphone_core_manager_destroy(LinphoneCoreManager* mgr) { ms_free(mgr); } - -static void add_test_suite(test_suite_t *suite) { - if (test_suite == NULL) { - test_suite = (test_suite_t **)malloc(10 * sizeof(test_suite_t *)); - } - test_suite[nb_test_suites] = suite; - nb_test_suites++; - if ((nb_test_suites % 10) == 0) { - test_suite = (test_suite_t **)realloc(test_suite, (nb_test_suites + 10) * sizeof(test_suite_t *)); - } -} - -static int run_test_suite(test_suite_t *suite) { - int i; - - CU_pSuite pSuite = CU_add_suite(suite->name, suite->init_func, suite->cleanup_func); - - for (i = 0; i < suite->nb_tests; i++) { - if (NULL == CU_add_test(pSuite, suite->tests[i].name, suite->tests[i].func)) { - return CU_get_error(); - } - } - - return 0; -} - -int liblinphone_tester_test_suite_index(const char *suite_name) { - int i; - - for (i = 0; i < liblinphone_tester_nb_test_suites(); i++) { - if ((strcmp(suite_name, test_suite[i]->name) == 0) && (strlen(suite_name) == strlen(test_suite[i]->name))) { - return i; - } - } - - return -1; -} - -void liblinphone_tester_list_suites() { - int j; - for(j=0;jnb_tests; i++) { - if ((strcmp(test_name, test_suite[j]->tests[i].name) == 0) && (strlen(test_name) == strlen(test_suite[j]->tests[i].name))) { - return i; - } - } - } - - return -1; -} - -int liblinphone_tester_nb_test_suites(void) { - return nb_test_suites; -} - -int liblinphone_tester_nb_tests(const char *suite_name) { - int i = liblinphone_tester_test_suite_index(suite_name); - if (i < 0) return 0; - return test_suite[i]->nb_tests; -} - -const char * liblinphone_tester_test_suite_name(int suite_index) { - if (suite_index >= liblinphone_tester_nb_test_suites()) return NULL; - return test_suite[suite_index]->name; -} - -const char * liblinphone_tester_test_name(const char *suite_name, int test_index) { - int suite_index = liblinphone_tester_test_suite_index(suite_name); - if ((suite_index < 0) || (suite_index >= liblinphone_tester_nb_test_suites())) return NULL; - if (test_index >= test_suite[suite_index]->nb_tests) return NULL; - return test_suite[suite_index]->tests[test_index].name; -} - -void liblinphone_tester_set_fileprefix(const char* file_prefix){ - liblinphone_tester_file_prefix = file_prefix; -} - -void liblinphone_tester_set_writable_dir_prefix(const char* writable_dir_prefix){ - liblinphone_tester_writable_dir_prefix = writable_dir_prefix; -} - - -void liblinphone_tester_init(void) { - add_test_suite(&setup_test_suite); - add_test_suite(®ister_test_suite); - add_test_suite(&offeranswer_test_suite); - add_test_suite(&call_test_suite); - add_test_suite(&message_test_suite); - add_test_suite(&presence_test_suite); -#ifdef UPNP - add_test_suite(&upnp_test_suite); -#endif - add_test_suite(&stun_test_suite); - add_test_suite(&event_test_suite); - add_test_suite(&flexisip_test_suite); - add_test_suite(&remote_provisioning_test_suite); - add_test_suite(&quality_reporting_test_suite); - add_test_suite(&log_collection_test_suite); - add_test_suite(&transport_test_suite); - add_test_suite(&player_test_suite); - add_test_suite(&dtmf_test_suite); -#if defined(VIDEO_ENABLED) && defined(HAVE_GTK) - add_test_suite(&video_test_suite); -#endif - add_test_suite(&multicast_call_test_suite); -} - -void liblinphone_tester_uninit(void) { - if (test_suite != NULL) { - free(test_suite); - test_suite = NULL; - nb_test_suites = 0; - } -} - -/*derivated from cunit*/ -static void test_complete_message_handler(const CU_pTest pTest, - const CU_pSuite pSuite, - const CU_pFailureRecord pFailureList) { - int i; - CU_pFailureRecord pFailure = pFailureList; - if (pFailure) { - if (liblinphone_tester_use_log_file) ms_warning("Suite [%s], Test [%s] had failures:", pSuite->pName, pTest->pName); - liblinphone_tester_fprintf(stdout,"\nSuite [%s], Test [%s] had failures:", pSuite->pName, pTest->pName); - } else { - if (liblinphone_tester_use_log_file) ms_warning(" passed"); - liblinphone_tester_fprintf(stdout," passed"); - } - for (i = 1 ; (NULL != pFailure) ; pFailure = pFailure->pNext, i++) { - if (liblinphone_tester_use_log_file) ms_warning("\n %d. %s:%u - %s", i, - (NULL != pFailure->strFileName) ? pFailure->strFileName : "", - pFailure->uiLineNumber, - (NULL != pFailure->strCondition) ? pFailure->strCondition : ""); - liblinphone_tester_fprintf(stdout,"\n %d. %s:%u - %s", i, - (NULL != pFailure->strFileName) ? pFailure->strFileName : "", - pFailure->uiLineNumber, - (NULL != pFailure->strCondition) ? pFailure->strCondition : ""); - } - } - - -static void test_all_tests_complete_message_handler(const CU_pFailureRecord pFailure) { - char * results = CU_get_run_results_string(); - if (liblinphone_tester_use_log_file) { - ms_warning("\n\n %s", results); - } - liblinphone_tester_fprintf(stdout,"\n\n %s",results); - ms_free(results); -} - -static void test_suite_init_failure_message_handler(const CU_pSuite pSuite) { - if (liblinphone_tester_use_log_file) ms_warning("Suite initialization failed for [%s].", pSuite->pName); - liblinphone_tester_fprintf(stdout,"Suite initialization failed for [%s].", pSuite->pName); -} - -static void test_suite_cleanup_failure_message_handler(const CU_pSuite pSuite) { - if (liblinphone_tester_use_log_file) ms_warning("Suite cleanup failed for '%s'.", pSuite->pName); - liblinphone_tester_fprintf(stdout,"Suite cleanup failed for [%s].", pSuite->pName); -} - -static void test_start_message_handler(const CU_pTest pTest, const CU_pSuite pSuite) { - if (liblinphone_tester_use_log_file) ms_warning("Suite [%s] Test [%s]", pSuite->pName,pTest->pName); - liblinphone_tester_fprintf(stdout,"\nSuite [%s] Test [%s]\n", pSuite->pName,pTest->pName); -} -static void test_suite_start_message_handler(const CU_pSuite pSuite) { - if (liblinphone_tester_use_log_file) ms_warning("Suite [%s]", pSuite->pName); - liblinphone_tester_fprintf(stdout,"\nSuite [%s]", pSuite->pName); -} - -int liblinphone_tester_run_tests(const char *suite_name, const char *test_name) { - int i; - int ret; - /* initialize the CUnit test registry */ - if (CUE_SUCCESS != CU_initialize_registry()) - return CU_get_error(); - - for (i = 0; i < liblinphone_tester_nb_test_suites(); i++) { - run_test_suite(test_suite[i]); - } - - CU_set_test_start_handler(test_start_message_handler); - CU_set_test_complete_handler(test_complete_message_handler); - CU_set_all_test_complete_handler(test_all_tests_complete_message_handler); - CU_set_suite_init_failure_handler(test_suite_init_failure_message_handler); - CU_set_suite_cleanup_failure_handler(test_suite_cleanup_failure_message_handler); - CU_set_suite_start_handler(test_suite_start_message_handler); - - - if( liblinphone_tester_xml_file != NULL ){ - CU_set_output_filename(liblinphone_tester_xml_file); - } - if( liblinphone_tester_xml_enabled != 0 ){ - CU_automated_run_tests(); - } else { - -#if !HAVE_CU_GET_SUITE - if( suite_name ){ - ms_warning("Tester compiled without CU_get_suite() function, running all tests instead of suite '%s'\n", suite_name); - } -#else - if (suite_name){ - CU_pSuite suite; - suite=CU_get_suite(suite_name); - if (!suite) { - ms_error("Could not find suite '%s'. Available suites are:", suite_name); - liblinphone_tester_list_suites(); - return -1; - } else if (test_name) { - CU_pTest test=CU_get_test_by_name(test_name, suite); - if (!test) { - ms_error("Could not find test '%s' in suite '%s'. Available tests are:", test_name, suite_name); - // do not use suite_name here, since this method is case sensitive - liblinphone_tester_list_suite_tests(suite->pName); - return -2; - } else { - CU_ErrorCode err= CU_run_test(suite, test); - if (err != CUE_SUCCESS) ms_error("CU_basic_run_test error %d", err); - } - } else { - CU_run_suite(suite); - } - } - else -#endif - { -#if HAVE_CU_CURSES - if (curses) { - /* Run tests using the CUnit curses interface */ - CU_curses_run_tests(); - } - else -#endif - { - /* Run all tests using the CUnit Basic interface */ - CU_run_all_tests(); - } - } - - } - ret=CU_get_number_of_tests_failed()!=0; - - /* Redisplay list of failed tests on end */ - if (CU_get_number_of_failure_records()){ - CU_basic_show_failures(CU_get_failure_list()); - liblinphone_tester_fprintf(stdout,"\n"); - } - - CU_cleanup_registry(); - - if( liblinphone_tester_keep_accounts_flag == 0){ - liblinphone_tester_clear_accounts(); - } - return ret; -} - -int liblinphone_tester_fprintf(FILE * stream, const char * format, ...) { - int result; - va_list args; - va_start(args, format); -#ifndef ANDROID - result = vfprintf(stream,format,args); - fflush(stream); -#else - /*used by liblinphone tester to retrieve suite list*/ - result = 0; - cunit_android_trace_handler(stream == stderr, format, args); -#endif - va_end(args); - return result; -} - int liblinphone_tester_ipv6_available(void){ struct addrinfo *ai=belle_sip_ip_address_to_addrinfo(AF_INET6,"2a01:e00::2",53); if (ai){ @@ -669,18 +367,28 @@ void liblinphone_tester_clear_accounts(void){ account_manager_destroy(); } -void liblinphone_tester_enable_xml( bool_t enable ){ - liblinphone_tester_xml_enabled = enable; +void liblinphone_tester_add_suites() { + bc_tester_add_suite(&setup_test_suite); + bc_tester_add_suite(®ister_test_suite); + bc_tester_add_suite(&offeranswer_test_suite); + bc_tester_add_suite(&call_test_suite); + bc_tester_add_suite(&multi_call_test_suite); + bc_tester_add_suite(&message_test_suite); + bc_tester_add_suite(&presence_test_suite); +#ifdef UPNP + bc_tester_add_suite(&upnp_test_suite); +#endif + bc_tester_add_suite(&stun_test_suite); + bc_tester_add_suite(&event_test_suite); + bc_tester_add_suite(&flexisip_test_suite); + bc_tester_add_suite(&remote_provisioning_test_suite); + bc_tester_add_suite(&quality_reporting_test_suite); + bc_tester_add_suite(&log_collection_test_suite); + bc_tester_add_suite(&transport_test_suite); + bc_tester_add_suite(&player_test_suite); + bc_tester_add_suite(&dtmf_test_suite); +#if defined(VIDEO_ENABLED) && defined(HAVE_GTK) + bc_tester_add_suite(&video_test_suite); +#endif + bc_tester_add_suite(&multicast_call_test_suite); } - -void liblinphone_tester_set_xml_output(const char *xml_path ) { - liblinphone_tester_xml_file = xml_path; -} - -const char* liblinphone_tester_get_xml_output( void ) { - return liblinphone_tester_xml_file; -} - - - - diff --git a/tester/video_tester.c b/tester/video_tester.c index 7e3809e31..f21e06989 100644 --- a/tester/video_tester.c +++ b/tester/video_tester.c @@ -55,7 +55,7 @@ static GtkWidget *create_video_window(LinphoneCall *call, LinphoneCallState csta GtkWidget *video_window; GdkDisplay *display; GdkColor color; - MSVideoSize vsize = MS_VIDEO_SIZE_CIF; + MSVideoSize vsize = { MS_VIDEO_SIZE_CIF_W, MS_VIDEO_SIZE_CIF_H }; const char *cstate_str; char *title; stats* counters = get_stats(call->core); @@ -131,6 +131,24 @@ static void early_media_video_call_state_changed(LinphoneCore *lc, LinphoneCall } } +static void early_media_video_call_state_changed_with_inactive_audio(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *msg) { + LinphoneCallParams *params; + + video_call_state_changed(lc, call, cstate, msg); + switch (cstate) { + case LinphoneCallIncomingReceived: + params = linphone_core_create_default_call_parameters(lc); + linphone_call_params_enable_video(params, TRUE); + linphone_call_params_set_audio_direction(params, LinphoneMediaDirectionInactive); + linphone_call_params_set_video_direction(params, LinphoneMediaDirectionRecvOnly); + linphone_core_accept_early_media_with_params(lc, call, params); + linphone_call_params_unref(params); + break; + default: + break; + } +} + bool_t wait_for_three_cores(LinphoneCore *lc1, LinphoneCore *lc2, LinphoneCore *lc3, int timeout) { MSList *lcs = NULL; bool_t result; @@ -216,6 +234,10 @@ static LinphoneCallParams * configure_for_early_media_video_receiving(LinphoneCo return _configure_for_video(manager, early_media_video_call_state_changed); } +static LinphoneCallParams * configure_for_early_media_video_receiving_with_inactive_audio(LinphoneCoreManager *manager) { + return _configure_for_video(manager, early_media_video_call_state_changed_with_inactive_audio); +} + static void early_media_video_during_video_call_test(void) { LinphoneCoreManager *marie; @@ -284,7 +306,7 @@ static void two_incoming_early_media_video_calls_test(void) { /* Configure early media audio to play ring during early-media and send remote ring back tone. */ linphone_core_set_ring_during_incoming_early_media(marie->lc, TRUE); - ringback_path = ms_strdup_printf("%s/sounds/ringback.wav", liblinphone_tester_file_prefix); + ringback_path = ms_strdup_printf("%s/sounds/ringback.wav", bc_tester_read_dir_prefix); linphone_core_set_remote_ringback_tone(marie->lc, ringback_path); ms_free(ringback_path); @@ -336,9 +358,46 @@ static void two_incoming_early_media_video_calls_test(void) { linphone_core_manager_destroy(laure); } +static void early_media_video_with_inactive_audio(void) { + LinphoneCoreManager *marie; + LinphoneCoreManager *pauline; + LinphoneCallParams *marie_params; + LinphoneCallParams *pauline_params; + + marie = linphone_core_manager_new("marie_rc"); + pauline = linphone_core_manager_new("pauline_rc"); + marie_params = configure_for_early_media_video_receiving_with_inactive_audio(marie); + pauline_params = configure_for_early_media_video_sending(pauline); + + /* Early media video call from pauline to marie. */ + CU_ASSERT_TRUE(video_call_with_params(pauline, marie, pauline_params, NULL, FALSE)); + + /* Wait for 2s. */ + wait_for_three_cores(marie->lc, pauline->lc, NULL, 2000); + + /* Check that we are in LinphoneCallOutgoingEarlyMedia state and that the ringstream is present meaning we are playing the ringback tone. */ + CU_ASSERT_EQUAL(linphone_call_get_state(linphone_core_get_current_call(pauline->lc)), LinphoneCallOutgoingEarlyMedia); + CU_ASSERT_PTR_NOT_NULL(pauline->lc->ringstream); + + linphone_core_terminate_all_calls(marie->lc); + CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1)); + CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallEnd, 1)); + CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallReleased, 1)); + CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallReleased, 1)); + + CU_ASSERT_EQUAL(marie->stat.number_of_video_windows_created, 1); + CU_ASSERT_EQUAL(pauline->stat.number_of_video_windows_created, 1); + + linphone_call_params_unref(marie_params); + linphone_call_params_unref(pauline_params); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + test_t video_tests[] = { { "Early-media video during video call", early_media_video_during_video_call_test }, - { "Two incoming early-media video calls", two_incoming_early_media_video_calls_test } + { "Two incoming early-media video calls", two_incoming_early_media_video_calls_test }, + { "Early-media video with inactive audio", early_media_video_with_inactive_audio } }; test_suite_t video_test_suite = { diff --git a/tools/generator.cc b/tools/generator.cc index 2b8ab0a39..c8763f1ef 100644 --- a/tools/generator.cc +++ b/tools/generator.cc @@ -25,6 +25,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifdef WIN32 #include + +#define strncasecmp _strnicmp #endif diff --git a/tools/genwrappers.cc b/tools/genwrappers.cc index 26ad7acc1..86a54d9b1 100644 --- a/tools/genwrappers.cc +++ b/tools/genwrappers.cc @@ -129,7 +129,7 @@ static Argument *parseArgument(XmlNode node, bool isReturn){ } static string classNameToPrefix(const std::string &classname){ - char tmp[classname.size()*2]; + char *tmp = new char[classname.size()*2]; char *w=tmp; size_t i; @@ -143,11 +143,13 @@ static string classNameToPrefix(const std::string &classname){ }else *w++=p; } *w++='\0'; - return tmp; + string ret(tmp); + delete[] tmp; + return ret; } static string makeMethodName(const string & suffix){ - char tmp[suffix.size()]; + char *tmp = new char[suffix.size()]; char *w=tmp; size_t i; bool useUpper=false; @@ -167,7 +169,9 @@ static string makeMethodName(const string & suffix){ } } *w++='\0'; - return tmp; + string ret(tmp); + delete[] tmp; + return ret; } static string extractMethodName(const string &c_name, const std::string& class_name){ diff --git a/tools/python/apixml2python/handwritten_definitions.mustache b/tools/python/apixml2python/handwritten_definitions.mustache index 13e27d873..4bd8f9f71 100644 --- a/tools/python/apixml2python/handwritten_definitions.mustache +++ b/tools/python/apixml2python/handwritten_definitions.mustache @@ -252,6 +252,9 @@ static void pylinphone_init_ms2_plugins(void) { #ifdef ENABLE_OPENH264 libmsopenh264_init(); #endif +#ifdef ENABLE_WASAPI + libmswasapi_init(); +#endif } static PyObject * pylinphone_Core_class_method_new(PyObject *cls, PyObject *args) { diff --git a/tools/software-desc.hh b/tools/software-desc.hh index 575f52fb0..51b526d71 100644 --- a/tools/software-desc.hh +++ b/tools/software-desc.hh @@ -21,10 +21,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef software_desc_hh #define software_desc_hh +#include #include #include #include #include +#include #include #include