diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000..769b266b1 --- /dev/null +++ b/.clang-format @@ -0,0 +1,64 @@ +--- +# BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: true +AlignEscapedNewlinesLeft: false +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: false +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: false +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: false +BinPackArguments: true +BinPackParameters: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +ColumnLimit: 120 +CommentPragmas: '^ IWYU pragma:' +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] +IndentCaseLabels: false +IndentFunctionDeclarationAfterType: false +IndentWidth: 4 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: true +Language: Cpp +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Right +SpaceAfterCStyleCast: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 4 +UseTab: Always +... diff --git a/.git-pre-commit b/.git-pre-commit new file mode 100755 index 000000000..69a71bea9 --- /dev/null +++ b/.git-pre-commit @@ -0,0 +1,51 @@ +#!/bin/bash + +# This hook purpose is to keep coding style consistent between all developers +# It is automatically installed in .git/hooks folder by cmake on first run. + +# From https://github.com/tatsuhiro-t/nghttp2/blob/master/pre-commit + +function invalid-format-detected { + cat git-clang-format.diff + echo "*****************" + echo "$0: Invalid coding style detected (see git-clang-format.diff for issues). Please correct it using one of the following:" + echo "1) Apply patch located at git-clang-format.diff using:" + echo " cd $(git rev-parse --show-toplevel) && $1" + echo "2) Use clang-format to correctly format source code using:" + echo " $2" + echo "3) Reformat these lines manually." + echo "*** Aborting commit.***" + exit 1 +} +function git-clang-format-diffing { + format_diff=$(which git-clang-format) + format_diff_options="--style=file" + + #only diffing commited files, ignored staged one + $format_diff $format_diff_options --diff $(git --no-pager diff --cached --name-status | grep -v '^D' | cut -f2) > git-clang-format.diff + + if ! grep -q -E '(no modified files to format|clang-format did not modify any files)' git-clang-format.diff; then + invalid-format-detected "git apply git-clang-format.diff" "clang-format $format_diff_options -i " + fi +} + +function clang-format-diff-diffing { + format_diff=$(find /usr/bin/ -name 'clang-format-diff*' -type f | tail -n1) + format_diff_options="-style file" + + git diff-index --cached --diff-filter=ACMR -p HEAD -- | $format_diff $format_diff_options -p1 > git-clang-format.diff + if [ -s git-clang-format.diff ]; then + invalid-format-detected "patch -p0 < git-clang-format.diff" "${format_diff/-diff/} $format_diff_options -i " + fi +} + +set -e +if which git-clang-format &>/dev/null; then + git-clang-format-diffing $@ +elif [ ! -z "$(find /usr/bin/ /usr/local/bin/ /opt/bin/ -name 'clang-format-diff*' -type f 2>/dev/null)" ]; then + # Warning! We need at least version 1.6... + clang-format-diff-diffing $@ +else + echo "$0: Please install clang-format (coding style checker) - could not find git-clang-format nor clang-format-diff in PATH. Skipping code verification..." + exit 0 +fi diff --git a/.gitignore b/.gitignore index 9420623d0..c34ffd5d9 100644 --- a/.gitignore +++ b/.gitignore @@ -50,6 +50,8 @@ coreapi/help/chatroom coreapi/help/doc/ coreapi/help/helloworld coreapi/help/registration +coreapi/help/realtimetext_receiver +coreapi/help/realtimetext_sender coreapi/test_ecc coreapi/test_lsd gtk/version_date.h @@ -68,6 +70,9 @@ specs.c *.swp .deps .libs +tools/test_ecc +tools/test_lsd +tools/test_numbers coreapi/help/notify share/fresh-rootca.pem tester/liblinphone_tester @@ -89,7 +94,12 @@ tester/linphone_log.gz.txt tools/auto_answer tools/lp-autoanswer build/macos/pkg-distribution.xml -tester/record_for_lc_*.wav +record_for_lc_*.wav tester/record-call_with_file_player.wav tester/ZIDCache*.xml +tester/stereo-record.wav +.dirstamp +git-clang-format.diff +*.log +.bc_tester_utils.tmp diff --git a/CMakeLists.txt b/CMakeLists.txt index b6c1d4a04..f4f45d39b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,12 +25,12 @@ project(LINPHONE C CXX) set(LINPHONE_MAJOR_VERSION "3") -set(LINPHONE_MINOR_VERSION "8") -set(LINPHONE_MICRO_VERSION "2") +set(LINPHONE_MINOR_VERSION "9") +set(LINPHONE_MICRO_VERSION "1") set(LINPHONE_VERSION "${LINPHONE_MAJOR_VERSION}.${LINPHONE_MINOR_VERSION}.${LINPHONE_MICRO_VERSION}") -set(LINPHONE_SO_VERSION "7") +set(LINPHONE_SO_VERSION "8") -file(GLOB LINPHONE_PO_FILES RELATIVE "${CMAKE_SOURCE_DIR}/po" "${CMAKE_SOURCE_DIR}/po/*.po") +file(GLOB LINPHONE_PO_FILES RELATIVE "${CMAKE_CURRENT_LIST_DIR}/po" "${CMAKE_CURRENT_LIST_DIR}/po/*.po") string(REGEX REPLACE "([a-zA-Z_]+)\\.po" "\\1" LINPHONE_ALL_LANGS_LIST "${LINPHONE_PO_FILES}") string(REPLACE ";" " " LINPHONE_ALL_LANGS "${LINPHONE_ALL_LANGS_LIST}") @@ -42,9 +42,11 @@ option(ENABLE_DATE "Use build date in internal version number." NO) option(ENABLE_DOC "Enable documentation generation with Doxygen." YES) option(ENABLE_GTK_UI "Turn on or off compilation of gtk interface." YES) option(ENABLE_LDAP "Enable LDAP support." NO) +option(ENABLE_LIME "Enable Instant Messaging Encryption." NO) option(ENABLE_MSG_STORAGE "Turn on compilation of message storage." YES) cmake_dependent_option(ENABLE_NOTIFY "Enable libnotify support." YES "ENABLE_GTK_UI" NO) option(ENABLE_RELATIVE_PREFIX "Find resources relatively to the installation directory." NO) +option(ENABLE_STRICT "Build with strict compile options." YES) option(ENABLE_TOOLS "Turn on or off compilation of tools." YES) option(ENABLE_TUNNEL "Turn on compilation of tunnel support." NO) option(ENABLE_TUTORIALS "Enable compilation of tutorials." YES) @@ -52,6 +54,25 @@ option(ENABLE_UNIT_TESTS "Enable compilation of unit tests." YES) option(ENABLE_UPNP "Build with uPnP support." YES) option(ENABLE_VIDEO "Build with video support." YES) cmake_dependent_option(ENABLE_ASSISTANT "Turn on assistant compiling." YES "ENABLE_GTK_UI" NO) +option(ENABLE_DEBUG_LOGS "Turn on or off debug level logs." NO) +option(ENABLE_NLS "Build with internationalisation support" YES) +option(ENABLE_CALL_LOGS_STORAGE "Turn on compilation of call logs storage." YES) + + +macro(apply_compile_flags SOURCE_FILES) + if(${SOURCE_FILES}) + set(options "") + foreach(a ${ARGV}) + if(STRICT_OPTIONS_${a}) + string(REPLACE ";" " " options_${a} "${STRICT_OPTIONS_${a}}") + set(options "${options} ${options_${a}}") + endif() + endforeach() + if(options) + set_source_files_properties(${${SOURCE_FILES}} PROPERTIES COMPILE_FLAGS "${options}") + endif() + endif() +endmacro() list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") @@ -62,39 +83,18 @@ include(CMakePushCheckState) set(MSVC_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include/MSVC") if(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(Mediastreamer2 REQUIRED) +# find_package should be invoked here to check for libraries - however do NOT +# call include_directories here (see below) + +if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS) + include("${EP_bellesip_CONFIG_DIR}/BelleSIPConfig.cmake") + include("${EP_ms2_CONFIG_DIR}/Mediastreamer2Config.cmake") +else() + find_package(BelleSIP REQUIRED) + find_package(Mediastreamer2 REQUIRED) +endif() find_package(XML2 REQUIRED) find_package(Zlib) if(ENABLE_UNIT_TESTS) @@ -112,7 +112,11 @@ if(ENABLE_UNIT_TESTS) endif() endif() if(ENABLE_TUNNEL) - find_package(Tunnel) + if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS) + include("${EP_tunnel_CONFIG_DIR}/TunnelConfig.cmake") + else() + find_package(Tunnel) + endif() if(NOT TUNNEL_FOUND) message(WARNING "Could not find the tunnel library!") set(ENABLE_TUNNEL OFF CACHE BOOL "Enable tunnel support." FORCE) @@ -130,18 +134,46 @@ if(ENABLE_NOTIFY) set(ENABLE_NOTIFY OFF CACHE BOOL "Enable libnotify support." FORCE) endif() endif() -if(ENABLE_ASSISTANT) - find_package(Soup) - if(SOUP_FOUND) - set(BUILD_WIZARD 1) - else() - message(WARNING "Could not find the soup library!") +if(ENABLE_GTK_UI) + if(WIN32) + set(GTK2_ADDITIONAL_SUFFIXES "../lib/glib-2.0/include" "../lib/gtk-2.0/include") + endif() + find_package(GTK2 2.18 REQUIRED gtk) + if(ENABLE_ASSISTANT AND GTK2_VERSION VERSION_LESS 2.22) + message(WARNING "You need at least GTK 2.22 to enable the assistant") set(ENABLE_ASSISTANT OFF CACHE BOOL "Turn on assistant compiling." FORCE) endif() + if(APPLE) + find_package(GtkMacIntegration) + if(GTKMACINTEGRATION_FOUND) + set(HAVE_GTK_OSX 1) + add_definitions("${GTKMACINTEGRATION_CPPFLAGS}") + else() + message(WARNING "gtk-mac-integration not found. Please install gtk-osx-application package.") + endif() + endif() +endif() +if(ENABLE_ASSISTANT) + set(BUILD_WIZARD 1) +endif() +if(ENABLE_NLS) + find_package(Gettext REQUIRED) + find_package(Intl REQUIRED) +endif() +if(ENABLE_CALL_LOGS_STORAGE) + find_package(Sqlite3 REQUIRED) +endif() +if(ENABLE_LIME) + set(HAVE_LIME 1) endif() -find_package(Gettext) +if(UNIX AND NOT APPLE) + include(CheckIncludeFiles) + check_include_files(libudev.h HAVE_LIBUDEV_H) +endif() +# include_directories must be called only UNDER THIS LINE in order to use our +# projects submodules first (we do NOT want to have system headers in first position) include_directories( include/ coreapi/ @@ -149,45 +181,60 @@ include_directories( ${CMAKE_CURRENT_BINARY_DIR}/coreapi/ ${BELLESIP_INCLUDE_DIRS} ${MEDIASTREAMER2_INCLUDE_DIRS} - ${XML2_INCLUDE_DIRS} ) +if(ENABLE_TUNNEL) + include_directories(${TUNNEL_INCLUDE_DIRS}) +endif() + +include_directories(${XML2_INCLUDE_DIRS}) + if(ZLIB_FOUND) include_directories(${ZLIB_INCLUDE_DIRS}) set(HAVE_ZLIB 1) endif() if(SQLITE3_FOUND) include_directories(${SQLITE3_INCLUDE_DIRS}) - add_definitions("-DMSG_STORAGE_ENABLED") + if(ENABLE_MSG_STORAGE) + add_definitions("-DMSG_STORAGE_ENABLED") + endif() + if(ENABLE_CALL_LOGS_STORAGE) + add_definitions("-DCALL_LOGS_STORAGE_ENABLED") + endif() endif() -if(ENABLE_TUNNEL) - include_directories(${TUNNEL_INCLUDE_DIRS}) -endif() -if(ENABLE_ASSISTANT) - include_directories(${SOUP_INCLUDE_DIRS}) +if(INTL_FOUND) + set(HAVE_INTL 1) + include_directories(${INTL_INCLUDE_DIRS}) endif() if(MSVC) include_directories(${MSVC_INCLUDE_DIR}) endif() add_definitions("-DIN_LINPHONE") +if(ENABLE_DEBUG_LOGS) + add_definitions("-DDEBUG") +endif() - -if(MSVC) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W3") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3") -else() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wuninitialized -Wdeclaration-after-statement -fno-strict-aliasing -Werror") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wuninitialized -Werror") +set(STRICT_OPTIONS_CPP ) +set(STRICT_OPTIONS_C ) +set(STRICT_OPTIONS_OBJC ) +if(NOT MSVC) + list(APPEND STRICT_OPTIONS_CPP "-Wall" "-Wuninitialized" "-Wno-error=deprecated-declarations") + list(APPEND STRICT_OPTIONS_C "-Wdeclaration-after-statement" "-Wstrict-prototypes" "-Wno-error=strict-prototypes") if(CMAKE_C_COMPILER_ID STREQUAL "Clang") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Qunused-arguments -Wno-array-bounds") - endif() - if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Qunused-arguments -Wno-array-bounds") + list(APPEND STRICT_OPTIONS_CPP "-Qunused-arguments" "-Wno-array-bounds") endif() if(APPLE) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error=unknown-warning-option -Wno-tautological-compare -Wno-unused-function") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=unknown-warning-option -Wno-tautological-compare -Wno-unused-function") + list(APPEND STRICT_OPTIONS_CPP "-Wno-error=unknown-warning-option" "-Qunused-arguments" "-Wno-tautological-compare" "-Wno-unused-function" "-Wno-array-bounds") endif() + if(ENABLE_STRICT) + list(APPEND STRICT_OPTIONS_CPP "-Werror" "-fno-strict-aliasing") + endif() +endif() +if(STRICT_OPTIONS_CPP) + list(REMOVE_DUPLICATES STRICT_OPTIONS_CPP) +endif() +if(STRICT_OPTIONS_C) + list(REMOVE_DUPLICATES STRICT_OPTIONS_C) endif() @@ -216,6 +263,13 @@ if(ENABLE_VIDEO) endif() +if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS) + set(EXPORT_TARGETS_NAME "LinphoneBuilder") +else() + set(EXPORT_TARGETS_NAME "Linphone") +endif() + + add_subdirectory(coreapi) add_subdirectory(share) if(ENABLE_CONSOLE_UI) @@ -240,9 +294,8 @@ write_basic_package_version_file( VERSION ${LINPHONE_VERSION} COMPATIBILITY AnyNewerVersion ) -export(EXPORT LinphoneTargets +export(EXPORT ${EXPORT_TARGETS_NAME}Targets FILE "${CMAKE_CURRENT_BINARY_DIR}/LinphoneTargets.cmake" - NAMESPACE BelledonneCommunications:: ) configure_file(cmake/LinphoneConfig.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/LinphoneConfig.cmake" @@ -250,9 +303,8 @@ configure_file(cmake/LinphoneConfig.cmake.in ) set(ConfigPackageLocation lib/cmake/Linphone) -install(EXPORT LinphoneTargets +install(EXPORT ${EXPORT_TARGETS_NAME}Targets FILE LinphoneTargets.cmake - NAMESPACE BelledonneCommunications:: DESTINATION ${ConfigPackageLocation} ) install(FILES diff --git a/Makefile.am b/Makefile.am index c8b69eec2..c3b462465 100644 --- a/Makefile.am +++ b/Makefile.am @@ -225,11 +225,7 @@ Linphone.app: MS2_PLUGINS_INSTALL_PREFIX=$(prefix) \ LINPHONE_ADDITIONAL_DEPENDENCIES_PREFIX=$(LINPHONE_ADDITIONAL_DEPENDENCIES_PREFIX) \ gtk-mac-bundler $(PACKAGE_BUNDLE_FILE) - printf "[Pango]\nModuleFiles=./etc/pango/pango.modules\n" \ - > $(BUNDLEDIR)/Contents/Resources/etc/pango/pangorc - cp -f $(BUNDLEDIR)/Contents/Resources/etc/pango/pango.modules $(BUNDLEDIR)/Contents/Resources/etc/pango/pango.modules.orig - sed -e 's:@executable_path.*/::g' $(BUNDLEDIR)/Contents/Resources/etc/pango/pango.modules.orig > $(BUNDLEDIR)/Contents/Resources/etc/pango/pango.modules - patch -R ${BUNDLEDIR}/Contents/Resources/share/themes/Quartz/gtk-2.0/gtkrc ${srcdir}/build/macos/quartz-theme-gtkrc.patch + patch ${BUNDLEDIR}/Contents/Resources/share/themes/Quartz/gtk-2.0/gtkrc ${srcdir}/build/macos/quartz-theme-gtkrc.patch rm -f ${BUNDLEDIR}/Contents/Resources/lib/libopenh264* bundle: $(MACAPPNAME) diff --git a/NEWS b/NEWS index 624ad27cb..4bc7aace8 100644 --- a/NEWS +++ b/NEWS @@ -1,9 +1,40 @@ +linphone-3.9.1 -- November 16th, 2015 + * Fix crash when recording video calls with the VP8 codec + * Fix H.264 codec support in Mac OS X package + * Fix translation of account assistant + * Bug fixes + +linphone-3.9.0 -- November 2nd, 2015 + * Video recording of calls in MKV format + * Clickable URLs in chat view + * Add buttons to change the record and playback volumes during a call + * Add button to start chatting without having to create a contact first + * Some icon changes + * Call logs now stored in database + * Bug fixes + +linphone-3.8.5 -- June 30th, 2015 + * Fix bug about status icon on MacOSX. Attention request worked only once + * Fix crash at the end of the audio assistant + * Fix crash when configuring a remote provisioning + * Fix regression in the codec view. Codec which are not usable because + bandwidth limits are to low were not greyed anymore + * Fix language selection on Windows and MacOSX + * Add translation for 'Arabic' and 'Turkish' items in the language selection + list + +linphone-3.8.4 -- June 9th, 2015 + * Add a built-in XMLRPC client. Linphone does not depend on libsoup anymore + +linphone-3.8.3 -- June 4th, 2015 + * Fix status icons on all platforms (Windows, MacOS, non-KDE Linux desktop environment) + linphone-3.8.2 -- May 7th, 2015 Application level improvements: * add support of the StatusNotifierItem standard to display a status icon on KDE5 * auto-answering can be set through the preferences panel * bug fixes - + Liblinphone level improvements: * fix audio bug with opus codec * fix ICE corner case not properly handled and resulting bad final ice status @@ -51,14 +82,14 @@ linphone-3.7.0 -- February 20th, 2014 * Keyboard can be used for DTMF input * Faster and higly responsive UI thanks to fully asynchronous operation of the liblinphone. * Addon of opus codec - * Possibility to specify a remote provisionning http URI for configuration + * Possibility to specify a remote provisioning http URI for configuration * LDAP search integration for Linux and MacOSX - * is-composing notification in chat area + * is-composing notification in chat area Liblinphone level improvements thanks to new "belle-sip" SIP stack: * multiple SIP transports simultaneously now allowed * IP dual stack: can use IPv6 and IPv4 simultaneously - * fully asynchronous behavior: no more lengthly DNS or connections + * fully asynchronous behavior: no more lengthly DNS or connections * +sip.instance parameter (RFC5626) * alias parameter (RFC5923) * better management of network disconnections @@ -76,7 +107,7 @@ linphone-3.7.0 -- February 20th, 2014 linphone-3.6.1 -- June 17, 2013 * fix memory leak with some video cameras on windows. - + Requires: mediastreamer2 = 2.9.1 and ortp = 0.22.0 linphone-3.6.0 -- May 27, 2013 @@ -141,9 +172,9 @@ linphone-3.4.1 -- February 17th, 2011 Requires mediastreamer-2.7.1 linphone-3.4.0 -- February 7th, 2011 - * implement multiple calls feature: + * implement multiple calls feature: - call hold (with possibility to play a music file) - - call resume + - call resume - acceptance of 2nd call while putting the others on hold - creation of another outgoing call while already in call - blind call transfer @@ -314,7 +345,7 @@ linphone-1.4.1 -- September 18, 2006 * do not change mixer settings at startup linphone-1.4.0 -- September 11, 2006 - * no more glib dependency at all + * no more glib dependency at all * new mediastreamer2 framework for audio/video streaming * stable video support with H.263-1998 * echo cancelation diff --git a/README b/README index 94ad9602a..7e0b97524 100644 --- a/README +++ b/README @@ -26,7 +26,6 @@ This is Linphone, a free (GPL) video softphone based on the SIP protocol. - theora (optional) + gsm codec (gsm source package or libgsm-dev or gsm-devel) (optional) + libreadline (optional: for convenient command line in linphonec) - + libsoup (optional: for wizard - account creation assistant) + libsqlite3 (optional : for a local history of chat messages) + if you want uPnP support (optional): - libupnp (version 1.6 branch (not patched with 18-url-upnpstrings.patch)) @@ -39,7 +38,7 @@ libglew1.6-dev libv4l-dev libxml2-dev + for optional library $ sudo apt-get install libreadline-dev libgsm1-dev libtheora-dev \ -libsoup2.4-dev libsqlite3-dev libupnp4-dev libsrtp-dev +libsqlite3-dev libupnp4-dev libsrtp-dev + Install zrtp (optional), for unbreakable call encryption $ git clone git://git.linphone.org:bzrtp diff --git a/README.macos.md b/README.macos.md index 89e3b3525..3460b14e2 100644 --- a/README.macos.md +++ b/README.macos.md @@ -24,24 +24,23 @@ In order to enable generation of bundle for older MacOS version, it is recommend ##### Linphone library (liblinphone) sudo port install automake autoconf libtool pkgconfig intltool wget cunit \ - antlr3 speex libvpx readline sqlite3 openldap libupnp \ + antlr3 speex readline sqlite3 openldap libupnp \ ffmpeg-devel -gpl2 ##### Linphone UI (GTK version) Install `GTK`. It is recommended to use the `quartz` backend for better integration. - sudo port install gtk2 +quartz +no_x11 libsoup - sudo port install gtk-osx-application +no_python + sudo port install gtk2 +quartz +no_x11 + sudo port install gtk-osx-application-gtk2 +no_python sudo port install hicolor-icon-theme #### Using HomeBrew ##### Linphone library (liblinphone) - brew tap Gui13/linphone brew install intltool libtool wget pkg-config automake libantlr3.4c \ - antlr3.2 gettext speex ffmpeg readline libvpx opus + homebrew/versions/antlr3 gettext speex ffmpeg readline libvpx opus ln -s /usr/local/bin/glibtoolize /usr/local/bin/libtoolize brew link --force gettext #readline is required from linphonec.c otherwise compilation will fail @@ -51,7 +50,7 @@ Install `GTK`. It is recommended to use the `quartz` backend for better integrat brew install cairo --without-x11 brew install gtk+ --without-x11 - brew install gtk-mac-integration libsoup hicolor-icon-theme + brew install gtk-mac-integration hicolor-icon-theme ### Building Linphone @@ -77,6 +76,27 @@ The next pieces need to be compiled manually. ./autogen.sh && ./configure --prefix=/opt/local && make sudo make install +* Install libvpx (Must be manualy build because the macport recipe does not support 'macosx_deployment_target') + + git clone https://chromium.googlesource.com/webm/libvpx -b v1.4.0 + cd libvpx + ./configure --prefix=/opt/local \ + --target=x86_64-darwin10-gcc \ + --enable-error-concealment \ + --enable-multithread \ + --enable-realtime-only \ + --enable-spatial-resampling \ + --enable-vp8 \ + --disable-vp9 \ + --enable-libs \ + --disable-install-docs \ + --disable-debug-libs \ + --disable-examples \ + --disable-unit-tests \ + --as=yasm + make + sudo make install + * Install belle-sip (sip stack) git clone git://git.linphone.org/belle-sip.git @@ -123,15 +143,12 @@ The next pieces need to be compiled manually. ### Generate portable bundle -If you want to generate a portable bundle, then install `gtk-mac-bundler`: +If you want to generate a portable bundle, then install `gtk-mac-bundler` linphone fork: - git clone https://github.com/jralls/gtk-mac-bundler.git - cd gtk-mac-bundler - git checkout 6e2ed855aaeae43c29436c342ae83568573b5636 + git clone git://git.linphone.org/gtk-mac-bundler.git + cd gtk-mac-bundler make install - export PATH=$PATH:~/.local/bin - # make this dummy charset.alias file for the bundler to be happy: - sudo touch /opt/local/lib/charset.alias + export PATH=$PATH:~/.local/bin # set writing right for owner on the libssl and libcrypto libraries in order gtk-mac-bundler # be able to rewrite their rpath sudo chmod u+w /opt/local/lib/libssl.1.0.0.dylib /opt/local/lib/libcrypto.1.0.0.dylib @@ -160,11 +177,11 @@ The resulting bundle is located in Linphone build directory, together with a zip * For a better appearance, you can install `gtk-quartz-engine` (a GTK theme) that makes GTK application more similar to other Mac applications (but not perfect). sudo port install gnome-common - git clone https://github.com/jralls/gtk-quartz-engine.git - cd gtk-quartz-engine - ./autogen.sh - ./configure --prefix=/opt/local CFLAGS="$CFLAGS -Wno-error" && make - sudo make install + git clone https://github.com/jralls/gtk-quartz-engine.git + cd gtk-quartz-engine + ./autogen.sh + ./configure --prefix=/opt/local CFLAGS="$CFLAGS -Wno-error" && make + sudo make install Generate a new bundle to have it included. diff --git a/autogen.sh b/autogen.sh index d5ec9ea80..b245167ec 100755 --- a/autogen.sh +++ b/autogen.sh @@ -16,19 +16,25 @@ else AUTOMAKE=automake-${AM_VERSION} fi -if test -f /opt/local/bin/glibtoolize ; then - # darwin - LIBTOOLIZE=/opt/local/bin/glibtoolize -else - LIBTOOLIZE=libtoolize -fi +LIBTOOLIZE="libtoolize" +for lt in glibtoolize libtoolize15 libtoolize14 libtoolize13 ; do + if test -x /usr/bin/$lt ; then + LIBTOOLIZE=$lt ; break + fi + if test -x /usr/local/bin/$lt ; then + LIBTOOLIZE=$lt ; break + fi + if test -x /opt/local/bin/$lt ; then + LIBTOOLIZE=$lt ; break + fi +done if test -d /opt/local/share/aclocal ; then - ACLOCAL_ARGS="-I /opt/local/share/aclocal" + ACLOCAL_ARGS="-I /opt/local/share/aclocal" fi if test -d /share/aclocal ; then - ACLOCAL_ARGS="$ACLOCAL_ARGS -I /share/aclocal" + ACLOCAL_ARGS="$ACLOCAL_ARGS -I /share/aclocal" fi INTLTOOLIZE=$(which intltoolize) @@ -49,6 +55,13 @@ $AUTOMAKE --force-missing --add-missing --copy autoconf set +x + +#install git pre-commit hooks if possible +if [ -d .git/hooks ] && [ ! -f .git/hooks/pre-commit ]; then + cp .git-pre-commit .git/hooks/pre-commit + chmod +x .git/hooks/pre-commit +fi + if [ "$srcdir" = "." ]; then if [ -x oRTP/autogen.sh ]; then echo "Generating build scripts in oRTP..." diff --git a/build/android/Android.mk b/build/android/Android.mk index 6a55fc92b..96fe57e16 100755 --- a/build/android/Android.mk +++ b/build/android/Android.mk @@ -26,6 +26,7 @@ include $(CLEAR_VARS) LOCAL_CPP_EXTENSION := .cc LOCAL_SRC_FILES := \ + account_creator.c \ address.c \ authentication.c \ bellesip_sal/sal_address_impl.c \ @@ -45,6 +46,7 @@ LOCAL_SRC_FILES := \ call_log.c \ call_params.c \ chat.c \ + chat_file_transfer.c \ conference.c \ content.c \ ec-calibrator.c \ @@ -73,6 +75,7 @@ LOCAL_SRC_FILES := \ sipsetup.c \ xml2lpc.c \ xml.c \ + xmlrpc.c \ vtables.c ifndef LIBLINPHONE_VERSION @@ -80,6 +83,7 @@ LIBLINPHONE_VERSION = "Devel" endif LOCAL_CFLAGS += \ + -Wno-error=deprecated-declarations \ -D_BYTE_ORDER=_LITTLE_ENDIAN \ -DORTP_INET6 \ -DINET6 \ @@ -116,6 +120,7 @@ LOCAL_C_INCLUDES += \ $(LOCAL_PATH)/../build/android \ $(LOCAL_PATH)/../oRTP/include \ $(LOCAL_PATH)/../mediastreamer2/include \ + $(LOCAL_PATH)/../mediastreamer2/src/audiofilters/ \ $(LOCAL_PATH)/../../belle-sip/include \ $(LOCAL_PATH)/../../../gen \ $(LOCAL_PATH)/../../externals/libxml2/include \ @@ -170,6 +175,11 @@ LOCAL_CFLAGS += -DHAVE_SILK LOCAL_STATIC_LIBRARIES += libmssilk endif +ifeq ($(BUILD_CODEC2),1) +LOCAL_CFLAGS += -DHAVE_CODEC2 +LOCAL_STATIC_LIBRARIES += libcodec2 libmscodec2 +endif + ifneq ($(BUILD_WEBRTC_AECM)$(BUILD_WEBRTC_ISAC),00) LOCAL_CFLAGS += -DHAVE_WEBRTC LOCAL_STATIC_LIBRARIES += libmswebrtc @@ -250,7 +260,7 @@ ifeq ($(BUILD_SRTP),1) endif ifeq ($(BUILD_SQLITE),1) -LOCAL_CFLAGS += -DMSG_STORAGE_ENABLED +LOCAL_CFLAGS += -DMSG_STORAGE_ENABLED -DCALL_LOGS_STORAGE_ENABLED LOCAL_STATIC_LIBRARIES += liblinsqlite LOCAL_C_INCLUDES += \ $(LOCAL_PATH)/../../externals/sqlite3/ @@ -274,6 +284,7 @@ include $(BUILD_SHARED_LIBRARY) LOCAL_CPPFLAGS=$(LOCAL_CFLAGS) LOCAL_CFLAGS += -Wdeclaration-after-statement +LOCAL_LDFLAGS := -Wl,-soname,$(LOCAL_MODULE_FILENAME).so $(call import-module,android/cpufeatures) diff --git a/build/android/config.h b/build/android/config.h index 0842116ab..d1532d47a 100644 --- a/build/android/config.h +++ b/build/android/config.h @@ -10,9 +10,6 @@ /* Define if wizard enabled */ /* #undef BUILD_WIZARD */ -/* Tells whether localisation is possible */ -/* #undef ENABLE_NLS */ - /* Defined when using gsm at nonstandard rates */ /* #undef ENABLE_NONSTANDARD_GSM */ @@ -60,7 +57,7 @@ /* #undef HAVE_GETIFADDRS */ /* Tells wheter localisation is possible */ -/* #undef HAVE_GETTEXT */ +/* #undef HAVE_INTL */ /* Define to 1 if you have the `get_current_dir_name' function. */ #define HAVE_GET_CURRENT_DIR_NAME 1 @@ -153,7 +150,7 @@ /* #undef LINPHONE_CONFIG_DIR */ /* path of liblinphone plugins, not mediastreamer2 plugins */ -/* #undef LINPHONE_PLUGINS_DIR */ +/* #undef LINPHONE_PLUGINS_DIR */ /* Linphone's version number */ /* #undef LINPHONE_VERSION */ @@ -205,11 +202,14 @@ /* #undef VERSION */ /* defined if video support is available */ -/* #undef VIDEO_ENABLED */ +/* #undef VIDEO_ENABLED */ /* Tell whether RSVP support should be compiled. */ /* #undef VINCENT_MAURY_RSVP */ +/* Defined when LIME support is compiled */ +#define HAVE_LIME 1 + /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD diff --git a/build/android/liblinphone_tester.mk b/build/android/liblinphone_tester.mk index e633116fc..8395df144 100644 --- a/build/android/liblinphone_tester.mk +++ b/build/android/liblinphone_tester.mk @@ -2,27 +2,28 @@ LOCAL_PATH := $(call my-dir)/../../tester common_SRC_FILES := \ common/bc_tester_utils.c \ - call_tester.c \ - liblinphone_tester.c \ - message_tester.c \ - presence_tester.c \ - register_tester.c \ - setup_tester.c \ - upnp_tester.c \ - eventapi_tester.c \ - stun_tester.c \ - flexisip_tester.c \ - 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 \ + call_tester.c \ + dtmf_tester.c \ + eventapi_tester.c \ + flexisip_tester.c \ + liblinphone_tester.c \ + log_collection_tester.c \ + message_tester.c \ + multi_call_tester.c \ offeranswer_tester.c \ + player_tester.c \ + presence_tester.c \ + proxy_config_tester.c \ + quality_reporting_tester.c \ + register_tester.c \ + remote_provisioning_tester.c \ + setup_tester.c \ + stun_tester.c \ + tester.c \ + tunnel_tester.c \ + upnp_tester.c \ multicast_call_tester.c \ - multi_call.c \ common_C_INCLUDES += \ $(LOCAL_PATH) \ diff --git a/build/macos/environment.sh b/build/macos/environment.sh index fae264e0e..879db36dc 100644 --- a/build/macos/environment.sh +++ b/build/macos/environment.sh @@ -3,6 +3,7 @@ export LINPHONE_WORKDIR="$bundle_res" export GIO_EXTRA_MODULES="$bundle_lib/gio/modules" export PANGO_LIBDIR="$bundle_lib" export PANGO_SYSCONFDIR="$bundle_etc" +export GDK_PIXBUF_MODULE_FILE="$bundle_lib/gdk-pixbuf-2.0/2.10.0/loaders.cache" #this is very important not to force a shared library path so that native frameworks can find their dependencies by themselves, #and not be forced to use the few libraries we have in the bundle that have the same name as native libs (ex: libiconv) @@ -23,4 +24,4 @@ esac export LANG -echo "LANG is $LANG" \ No newline at end of file +echo "LANG is $LANG" diff --git a/build/macos/linphone.bundle b/build/macos/linphone.bundle index 8109ff6cb..7d70bf8b2 100644 --- a/build/macos/linphone.bundle +++ b/build/macos/linphone.bundle @@ -17,6 +17,7 @@ ${env:MS2_PLUGINS_INSTALL_PREFIX} ${env:LINPHONE_ADDITIONAL_DEPENDENCIES_PREFIX} + - - ${prefix}/lib/gio/modules/libgiognutls.so + ${prefix}/lib/${gtkdir}/${pkg:${gtk}:gtk_binary_version}/printbackends/*.so - + + ${prefix}/lib/gdk-pixbuf-2.0/${pkg:${gtk}:gtk_binary_version}/loaders/libpixbufloader-bmp.so + + + ${prefix}/lib/gdk-pixbuf-2.0/${pkg:${gtk}:gtk_binary_version}/loaders/libpixbufloader-gif.so + + + ${prefix}/lib/gdk-pixbuf-2.0/${pkg:${gtk}:gtk_binary_version}/loaders/libpixbufloader-icns.so + + + ${prefix}/lib/gdk-pixbuf-2.0/${pkg:${gtk}:gtk_binary_version}/loaders/libpixbufloader-ico.so + + + ${prefix}/lib/gdk-pixbuf-2.0/${pkg:${gtk}:gtk_binary_version}/loaders/libpixbufloader-jpeg.so + + + ${prefix}/lib/gdk-pixbuf-2.0/${pkg:${gtk}:gtk_binary_version}/loaders/libpixbufloader-png.so + + + + + + + + - - ${prefix:linphone}/share/locale - - - ${prefix}/share/locale - - - ${prefix}/share/locale - ${prefix}/share/locale + + ${prefix:linphone}/share/locale + + + + ${prefix}/share/locale + + + + ${prefix}/share/locale + @@ -151,7 +175,6 @@ ${project}/../../pixmaps/linphone.icns - ${project}/environment.sh @@ -168,10 +191,14 @@ ${prefix:linphone}/share/sounds/linphone/rings/oldphone.wav + + ${prefix:linphone}/share/sounds/linphone/rings/toy-mono.wav + + ${prefix:linphone}/share/sounds/linphone/ringback.wav - + ${prefix:linphone}/share/sounds/linphone/incoming_chat.wav diff --git a/build/macos/quartz-theme-gtkrc.patch b/build/macos/quartz-theme-gtkrc.patch index 9099f2cac..ac7a48a98 100644 --- a/build/macos/quartz-theme-gtkrc.patch +++ b/build/macos/quartz-theme-gtkrc.patch @@ -1,4 +1,20 @@ -85c85 -< buttontype = "textured" ---- -> buttontype = "aqua" +--- /opt/local/share/themes/Quartz/gtk-2.0/gtkrc 2015-03-25 15:29:53.000000000 +0100 ++++ gtkrc 2015-10-29 13:43:15.000000000 +0100 +@@ -12,7 +12,7 @@ + gtk-menu-images = 0 + gtk-toolbar-style = 0 + gtk-enable-mnemonics = 0 +-gtk-icon-sizes = "gtk-small-toolbar=16,16:gtk-large-toolbar=22,22" ++gtk-icon-sizes = "gtk-menu=12,12:gtk-button=16,16:gtk-small-toolbar=16,16:gtk-large-toolbar=22,22" + gtk-toolbar-icon-size = large-toolbar + gtk-error-bell = 0 + gtk-show-input-method-menu = 0 +@@ -82,7 +82,7 @@ + + engine "quartz" + { +- buttontype = "aqua" ++ buttontype = "textured" + } + } + diff --git a/build/windows10/liblinphone-tester/App.xaml b/build/windows10/liblinphone-tester/App.xaml new file mode 100644 index 000000000..8ed2e3f95 --- /dev/null +++ b/build/windows10/liblinphone-tester/App.xaml @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/build/windows10/liblinphone-tester/App.xaml.cs b/build/windows10/liblinphone-tester/App.xaml.cs new file mode 100644 index 000000000..f3c4d0801 --- /dev/null +++ b/build/windows10/liblinphone-tester/App.xaml.cs @@ -0,0 +1,132 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices.WindowsRuntime; +using Windows.ApplicationModel; +using Windows.ApplicationModel.Activation; +using Windows.Foundation; +using Windows.Foundation.Collections; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Navigation; + +// The Blank Application template is documented at http://go.microsoft.com/fwlink/?LinkId=402347&clcid=0x409 + +namespace liblinphone_tester +{ + /// + /// Provides application-specific behavior to supplement the default Application class. + /// + sealed partial class App : Application + { + /// + /// Allows tracking page views, exceptions and other telemetry through the Microsoft Application Insights service. + /// + public static Microsoft.ApplicationInsights.TelemetryClient TelemetryClient; + + /// + /// Initializes the singleton application object. This is the first line of authored code + /// executed, and as such is the logical equivalent of main() or WinMain(). + /// + public App() + { + TelemetryClient = new Microsoft.ApplicationInsights.TelemetryClient(); + + this.InitializeComponent(); + this.Suspending += OnSuspending; + } + + /// + /// Invoked when the application is launched normally by the end user. Other entry points + /// will be used such as when the application is launched to open a specific file. + /// + /// Details about the launch request and process. + protected override void OnLaunched(LaunchActivatedEventArgs e) + { + +#if DEBUG + if (System.Diagnostics.Debugger.IsAttached) + { + this.DebugSettings.EnableFrameRateCounter = true; + } +#endif + + Frame rootFrame = Window.Current.Content as Frame; + + // Do not repeat app initialization when the Window already has content, + // just ensure that the window is active + if (rootFrame == null) + { + // Create a Frame to act as the navigation context and navigate to the first page + rootFrame = new Frame(); + + rootFrame.NavigationFailed += OnNavigationFailed; + + if (e.PreviousExecutionState == ApplicationExecutionState.Terminated) + { + //TODO: Load state from previously suspended application + } + + // Place the frame in the current Window + Window.Current.Content = rootFrame; + } + + if (rootFrame.Content == null) + { + // When the navigation stack isn't restored navigate to the first page, + // configuring the new page by passing required information as a navigation + // parameter + rootFrame.Navigate(typeof(MainPage), e.Arguments); + } + // Ensure the current window is active + Window.Current.Activate(); + } + + /// + /// Invoked when Navigation to a certain page fails + /// + /// The Frame which failed navigation + /// Details about the navigation failure + void OnNavigationFailed(object sender, NavigationFailedEventArgs e) + { + throw new Exception("Failed to load Page " + e.SourcePageType.FullName); + } + + /// + /// Invoked when application execution is being suspended. Application state is saved + /// without knowing whether the application will be terminated or resumed with the contents + /// of memory still intact. + /// + /// The source of the suspend request. + /// Details about the suspend request. + private void OnSuspending(object sender, SuspendingEventArgs e) + { + var deferral = e.SuspendingOperation.GetDeferral(); + //TODO: Save application state and stop any background activity + deferral.Complete(); + } + + protected override void OnActivated(IActivatedEventArgs args) + { + if (args.Kind == ActivationKind.Protocol) + { + var protocolArgs = (ProtocolActivatedEventArgs)args; + var uri = protocolArgs.Uri; + Frame rootFrame = Window.Current.Content as Frame; + if (rootFrame == null) + rootFrame = new Frame(); + + rootFrame.NavigationFailed += OnNavigationFailed; + rootFrame.Navigate(typeof(MainPage), uri); + Window.Current.Content = rootFrame; + Window.Current.Activate(); + } + base.OnActivated(args); + } + } +} diff --git a/build/windows10/liblinphone-tester/ApplicationInsights.config b/build/windows10/liblinphone-tester/ApplicationInsights.config new file mode 100644 index 000000000..8a6452a34 --- /dev/null +++ b/build/windows10/liblinphone-tester/ApplicationInsights.config @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build/windows10/liblinphone-tester/Assets/Logo.png b/build/windows10/liblinphone-tester/Assets/Logo.png new file mode 100644 index 000000000..ecfbad551 Binary files /dev/null and b/build/windows10/liblinphone-tester/Assets/Logo.png differ diff --git a/build/windows10/liblinphone-tester/Assets/SmallLogo.png b/build/windows10/liblinphone-tester/Assets/SmallLogo.png new file mode 100644 index 000000000..18c25f038 Binary files /dev/null and b/build/windows10/liblinphone-tester/Assets/SmallLogo.png differ diff --git a/build/windows10/liblinphone-tester/Assets/SplashScreen.png b/build/windows10/liblinphone-tester/Assets/SplashScreen.png new file mode 100644 index 000000000..0d83a7980 Binary files /dev/null and b/build/windows10/liblinphone-tester/Assets/SplashScreen.png differ diff --git a/build/windows10/liblinphone-tester/Assets/StoreLogo.png b/build/windows10/liblinphone-tester/Assets/StoreLogo.png new file mode 100644 index 000000000..bdbfc51e2 Binary files /dev/null and b/build/windows10/liblinphone-tester/Assets/StoreLogo.png differ diff --git a/build/windows10/liblinphone-tester/Assets/WideLogo.png b/build/windows10/liblinphone-tester/Assets/WideLogo.png new file mode 100644 index 000000000..85fd4db8f Binary files /dev/null and b/build/windows10/liblinphone-tester/Assets/WideLogo.png differ diff --git a/build/windows10/liblinphone-tester/DataModel/UnitTestDataSource.cs b/build/windows10/liblinphone-tester/DataModel/UnitTestDataSource.cs new file mode 100644 index 000000000..a5bc5bdc3 --- /dev/null +++ b/build/windows10/liblinphone-tester/DataModel/UnitTestDataSource.cs @@ -0,0 +1,251 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using liblinphone_tester_runtime_component; +using System.Collections.ObjectModel; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Media; +using System.ComponentModel; +using Windows.UI; +using Windows.UI.Xaml.Documents; +using Windows.UI.Core; + +namespace liblinphone_tester.DataModel +{ + public class OutputTrace + { + public OutputTrace(String lev, String msg) + { + Level = lev; + Msg = msg; + } + + public String Level { get; private set; } + public String Msg { get; private set; } + } + + public class UnitTestSuite + { + public UnitTestSuite(string name) + { + Name = name; + Cases = new ObservableCollection(); + Selected = false; + } + + public string Name { get; private set; } + public bool Selected + { + get { return Cases.All(x => x.Selected); } + set + { + foreach (UnitTestCase c in Cases) + { + c.Selected = value; + } + } + } + public ObservableCollection Cases { get; private set; } + } + + public enum UnitTestCaseState + { + NotRun, + Success, + Failure + } + + public class UnitTestCase : INotifyPropertyChanged + { + public UnitTestCase(UnitTestSuite suite, string name) + { + _suite = new WeakReference(suite); + Name = name; + Selected = false; + State = UnitTestCaseState.NotRun; + Traces = new ObservableCollection(); + } + + public UnitTestSuite Suite + { + get { return _suite.Target as UnitTestSuite; } + } + public string Name { get; private set; } + public bool Selected + { + get { return _selected; } + set + { + _selected = value; + RaisePropertyChanged("Selected"); + } + } + public UnitTestCaseState State + { + get { return _state; } + set + { + _state = value; + RaisePropertyChanged("State"); + } + } + public ObservableCollection Traces + { + get { return _traces; } + set + { + _traces = value; + RaisePropertyChanged("Traces"); + } + } + public CoreDispatcher Dispatcher { get; set; } + + public event PropertyChangedEventHandler PropertyChanged; + + protected void RaisePropertyChanged(string name) + { + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs(name)); + } + } + + private WeakReference _suite; + private bool _selected; + private UnitTestCaseState _state; + private ObservableCollection _traces; + } + + public sealed class UnitTestDataSource + { + private static UnitTestDataSource _unitTestDataSource = new UnitTestDataSource(); + private ObservableCollection _suites = new ObservableCollection(); + + public ObservableCollection Suites + { + get { return this._suites; } + } + + public static IEnumerable GetSuites(LibLinphoneTester tester) + { + return _unitTestDataSource.FillSuites(tester); + } + + private IEnumerable FillSuites(LibLinphoneTester tester) + { + if (this.Suites.Count != 0) return this.Suites; + for (int i = 0; i < tester.nbTestSuites(); i++) + { + UnitTestSuite suite = new UnitTestSuite(tester.testSuiteName(i)); + for (int j = 0; j < tester.nbTests(suite.Name); j++) + { + suite.Cases.Add(new UnitTestCase(suite, tester.testName(suite.Name, j))); + } + this.Suites.Add(suite); + } + return this.Suites; + } + } + + public sealed class UnitTestCaseStateToSymbolConverter : IValueConverter + { + object IValueConverter.Convert(object value, Type targetType, object parametr, string language) + { + if (!value.GetType().Equals(typeof(UnitTestCaseState))) + { + throw new ArgumentException("Only UnitTestCaseState is supported"); + } + if (targetType.Equals(typeof(Symbol))) + { + switch ((UnitTestCaseState)value) + { + case UnitTestCaseState.Success: + return Symbol.Like; + case UnitTestCaseState.Failure: + return Symbol.Dislike; + case UnitTestCaseState.NotRun: + default: + return Symbol.Help; + } + } + else + { + throw new ArgumentException(string.Format("Unsupported type {0}", targetType.FullName)); + } + } + + object IValueConverter.ConvertBack(object value, Type targetType, object parameter, string language) + { + throw new NotImplementedException(); + } + } + + public sealed class UnitTestCaseStateToSymbolColorConverter : IValueConverter + { + object IValueConverter.Convert(object value, Type targetType, object parameter, string language) + { + if (!value.GetType().Equals(typeof(UnitTestCaseState))) + { + throw new ArgumentException("Only UnitTestCaseState is supported"); + } + if (targetType.Equals(typeof(Brush))) + { + switch ((UnitTestCaseState)value) + { + case UnitTestCaseState.Success: + return new SolidColorBrush(Colors.ForestGreen); + case UnitTestCaseState.Failure: + return new SolidColorBrush(Colors.IndianRed); + case UnitTestCaseState.NotRun: + default: + return new SolidColorBrush(Colors.LightGray); + } + } + else + { + throw new ArgumentException(string.Format("Unsupported format {0}", targetType.FullName)); + } + } + + object IValueConverter.ConvertBack(object value, Type targetType, object parameter, string language) + { + throw new NotImplementedException(); + } + } + + public sealed class OutputTraceLevelToColorConverter : IValueConverter + { + object IValueConverter.Convert(object value, Type targetType, object parameter, string language) + { + if (!value.GetType().Equals(typeof(String))) + { + throw new ArgumentException("Only String is supported"); + } + if (targetType.Equals(typeof(Brush))) + { + if ((String)value == "Error") + { + return new SolidColorBrush(Colors.IndianRed); + } + else if ((String)value == "Warning") + { + return new SolidColorBrush(Colors.Orange); + } + return new SolidColorBrush(Colors.Black); + } + else + { + throw new ArgumentException(string.Format("Unsupported format {0}", targetType.FullName)); + } + } + + object IValueConverter.ConvertBack(object value, Type targetType, object parameter, string language) + { + throw new NotImplementedException(); + } + } +} diff --git a/build/windows10/liblinphone-tester/MainPage.xaml b/build/windows10/liblinphone-tester/MainPage.xaml new file mode 100644 index 000000000..2cdea219c --- /dev/null +++ b/build/windows10/liblinphone-tester/MainPage.xaml @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/windows10/liblinphone-tester/MainPage.xaml.cs b/build/windows10/liblinphone-tester/MainPage.xaml.cs new file mode 100644 index 000000000..930e6d5eb --- /dev/null +++ b/build/windows10/liblinphone-tester/MainPage.xaml.cs @@ -0,0 +1,200 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices.WindowsRuntime; +using Windows.Foundation; +using Windows.Foundation.Collections; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Navigation; +using liblinphone_tester.DataModel; +using liblinphone_tester_runtime_component; +using System.Threading.Tasks; +using Windows.UI.Core; +using Windows.UI.Xaml.Documents; +using Windows.Storage; + +// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 + +namespace liblinphone_tester +{ + /// + /// An empty page that can be used on its own or navigated to within a Frame. + /// + public sealed partial class MainPage : Page, OutputTraceListener + { + public MainPage() + { + this.InitializeComponent(); + } + + protected override void OnNavigatedTo(NavigationEventArgs e) + { + base.OnNavigatedTo(e); + if ((e.Parameter is Uri) && (e.Parameter.ToString().Equals("liblinphone-tester:autolaunch"))) + { + AutoLaunch(); + } + else + { + LibLinphoneTester.Instance.initialize(ApplicationData.Current.LocalFolder, true); + _suites = UnitTestDataSource.GetSuites(LibLinphoneTester.Instance); + } + } + + public IEnumerable Suites + { + get { return _suites; } + } + + private IEnumerable _suites; + + private void SelectAll_Click(object sender, RoutedEventArgs e) + { + bool allSelected = Suites.All(x => x.Selected); + foreach (UnitTestSuite suite in Suites) + { + suite.Selected = !allSelected; + } + } + + private void RunSelected_Click(object sender, RoutedEventArgs e) + { + int nbCases = 0; + foreach (UnitTestSuite suite in Suites) + { + foreach (UnitTestCase c in suite.Cases) + { + if (c.Selected) nbCases++; + } + } + if (nbCases == 0) return; + + PrepareRun(nbCases); + + var tup = new Tuple, bool?>(Suites, Verbose.IsChecked); + var t = Task.Factory.StartNew(async (object parameters) => + { + var p = parameters as Tuple, bool?>; + IEnumerable suites = p.Item1; + bool verbose = p.Item2 != null ? (bool)p.Item2 : false; + foreach (UnitTestSuite suite in suites) + { + foreach (UnitTestCase c in suite.Cases) + { + if (c.Selected) + { + await RunUnitTestCase(c, verbose); + } + } + } + }, tup); + } + + private void RunSingle_Click(object sender, RoutedEventArgs e) + { + PrepareRun(1); + + var tup = new Tuple(DisplayedTestCase, Verbose.IsChecked); + var t = Task.Factory.StartNew(async (object parameters) => + { + var p = parameters as Tuple; + UnitTestCase c = p.Item1; + bool verbose = p.Item2 != null ? (bool)p.Item2 : false; + await RunUnitTestCase(c, verbose); + }, tup); + } + + private void PrepareRun(int nbCases) + { + CommandBar.IsEnabled = false; + ProgressIndicator.IsEnabled = true; + ProgressIndicator.Minimum = 0; + ProgressIndicator.Maximum = nbCases; + ProgressIndicator.Value = 0; + LibLinphoneTester.Instance.setOutputTraceListener(this); + } + + private async Task RunUnitTestCase(UnitTestCase c, bool verbose) + { + UnitTestCaseState newState = UnitTestCaseState.NotRun; + await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => + { + RunningTestCase = c; + }); + await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => + { + c.Traces.Clear(); + }); + c.Dispatcher = Dispatcher; + if (LibLinphoneTester.Instance.run(c.Suite.Name, c.Name, verbose)) + { + newState = UnitTestCaseState.Failure; + } + else + { + newState = UnitTestCaseState.Success; + } + await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => + { + c.State = newState; + ProgressIndicator.Value += 1; + if (ProgressIndicator.Value == ProgressIndicator.Maximum) + { + UnprepareRun(); + } + }); + } + + private void UnprepareRun() + { + LibLinphoneTester.Instance.setOutputTraceListener(null); + RunningTestCase = null; + ProgressIndicator.IsEnabled = false; + CommandBar.IsEnabled = true; + } + + private void UnitTestCase_Click(object sender, ItemClickEventArgs e) + { + DisplayedTestCase = (e.ClickedItem as UnitTestCase); + TestResultPage.DataContext = DisplayedTestCase; + TestResultState.Visibility = Visibility.Visible; + TestResultRun.Visibility = Visibility.Visible; + } + + public async void outputTrace(String lev, String msg) + { + await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => + { + if (RunningTestCase != null) + { + RunningTestCase.Traces.Add(new OutputTrace(lev, msg)); + } + }); + } + + private void AutoLaunch() + { + CommandBar.IsEnabled = false; + ProgressIndicator.IsIndeterminate = true; + ProgressIndicator.IsEnabled = true; + LibLinphoneTester.Instance.initialize(ApplicationData.Current.LocalFolder, false); + LibLinphoneTester.Instance.runAllToXml(); + if (LibLinphoneTester.Instance.AsyncAction != null) + { + LibLinphoneTester.Instance.AsyncAction.Completed += (asyncInfo, asyncStatus) => { + App.Current.Exit(); + }; + } + } + + private UnitTestCase RunningTestCase; + private UnitTestCase DisplayedTestCase; + } +} diff --git a/build/windows10/liblinphone-tester/Package.appxmanifest b/build/windows10/liblinphone-tester/Package.appxmanifest new file mode 100644 index 000000000..b8acf8233 --- /dev/null +++ b/build/windows10/liblinphone-tester/Package.appxmanifest @@ -0,0 +1,37 @@ + + + + + + liblinphone-tester + Belledonne Communications + Assets\StoreLogo.png + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build/windows10/liblinphone-tester/Properties/AssemblyInfo.cs b/build/windows10/liblinphone-tester/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..d4b2a0c81 --- /dev/null +++ b/build/windows10/liblinphone-tester/Properties/AssemblyInfo.cs @@ -0,0 +1,29 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("liblinphone-tester")] +[assembly: AssemblyDescription("LibLinphone tester for Windows 10")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Belledonne Communications")] +[assembly: AssemblyProduct("liblinphone-tester-windows10")] +[assembly: AssemblyCopyright("Copyright © 2015 Belledonne Communications")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: ComVisible(false)] \ No newline at end of file diff --git a/build/windows10/liblinphone-tester/Properties/Default.rd.xml b/build/windows10/liblinphone-tester/Properties/Default.rd.xml new file mode 100644 index 000000000..80a960ce3 --- /dev/null +++ b/build/windows10/liblinphone-tester/Properties/Default.rd.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/build/windows10/liblinphone-tester/liblinphone-tester-runtime-component/liblinphone-tester-runtime-component.vcxproj b/build/windows10/liblinphone-tester/liblinphone-tester-runtime-component/liblinphone-tester-runtime-component.vcxproj new file mode 100644 index 000000000..c1c1fa623 --- /dev/null +++ b/build/windows10/liblinphone-tester/liblinphone-tester-runtime-component/liblinphone-tester-runtime-component.vcxproj @@ -0,0 +1,142 @@ + + + + + Debug + ARM + + + Debug + Win32 + + + Debug + x64 + + + Release + ARM + + + Release + Win32 + + + Release + x64 + + + + + + + + + + + {acf5ea95-d647-4d0c-8f97-2cd9aae8a2e0} + + + {74cad9d0-d8ae-4896-b71b-b2d9b48f30aa} + + + {8c1bc968-c5c8-4d4b-9ef3-d6a065fc7c97} + + + {6a18bbb9-08d1-41a8-be57-17fc992cc36f} + + + {bb8ebb21-f22c-4a68-99cb-67fa36c495e3} + + + {b84d5c3b-6de5-49c8-b3dd-5eb67b01a527} + + + {266b769a-c04e-424c-9033-7209f0425bc0} + + + {878cf9d3-9761-479e-a715-a1de9f99cb78} + + + {2d0e44c4-e51d-4911-b876-345d1e5e5209} + + + {a34f450d-392d-4660-9618-810bd695b3b0} + + + {545f846d-7f19-4d6d-a50b-172a7c9b61e7} + + + {9eb3fe8d-2d91-4d29-a3bb-98ddb51d45b7} + + + + {1ce10f06-8fad-437f-b3d7-3b7a8909a190} + WindowsRuntimeComponent + liblinphone-tester-runtime-component + liblinphone_tester_runtime_component + en-US + 14.0 + true + Windows Store + 10 + 10.0.10240.0 + 10.0.10069.0 + + + + DynamicLibrary + true + v140 + + + DynamicLibrary + false + true + v140 + + + + + + + + + + + + false + $(SolutionDir)$(Platform)\$(Configuration)\ + + + + NotUsing + IN_LINPHONE;_WINRT_DLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + $(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories) + /bigobj %(AdditionalOptions) + 28204 + $(ProjectDir)..\..\..\..\coreapi;$(ProjectDir)..\..\..\..\tester\common;$(ProjectDir)..\..\..\..\mediastreamer2\include;$(ProjectDir)..\..\..\..\oRTP\include;%(AdditionalIncludeDirectories) + + + Console + false + + + + + NotUsing + IN_LINPHONE;_WINRT_DLL;NDEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + $(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories) + /bigobj %(AdditionalOptions) + 28204 + $(ProjectDir)..\..\..\..\coreapi;$(ProjectDir)..\..\..\..\tester\common;$(ProjectDir)..\..\..\..\mediastreamer2\include;$(ProjectDir)..\..\..\..\oRTP\include;%(AdditionalIncludeDirectories) + + + Console + false + + + + + + \ No newline at end of file diff --git a/build/windows10/liblinphone-tester/liblinphone-tester-static/liblinphone-tester-static.vcxproj b/build/windows10/liblinphone-tester/liblinphone-tester-static/liblinphone-tester-static.vcxproj new file mode 100644 index 000000000..b5cb1b46c --- /dev/null +++ b/build/windows10/liblinphone-tester/liblinphone-tester-static/liblinphone-tester-static.vcxproj @@ -0,0 +1,130 @@ + + + + + Debug + ARM + + + Debug + Win32 + + + Debug + x64 + + + Release + ARM + + + Release + Win32 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {b6cdf482-7da3-43d4-9b12-70150106c191} + + + {025e28a8-9dfb-4015-ad56-19896aa6cc9b} + + + {88e3c241-eb6f-4c84-80dc-89b8961daf80} + + + {2e56b851-9d8d-40e5-84bb-e4ee63b71d25} + + + {c7139899-d8bc-48a3-a437-6844a8baabef} + + + + {9eb3fe8d-2d91-4d29-a3bb-98ddb51d45b7} + StaticLibrary + liblinphone-tester-static + liblinphone_tester_static + en-US + 14.0 + true + Windows Store + 10 + 10.0.10240.0 + 10.0.10069.0 + + + + StaticLibrary + true + v140 + + + StaticLibrary + false + true + v140 + + + + + + + + + + + + false + $(SolutionDir)$(Platform)\$(Configuration)\ + + + + NotUsing + false + true + $(SolutionDir)$(Platform)\$(Configuration)\include;$(ProjectDir)..\..\..\..\tester;$(ProjectDir)..\..\..\..\tester\common;$(ProjectDir)..\..\liblinphone;$(ProjectDir)..\..\..\..\coreapi;$(ProjectDir)..\..\..\..\include;$(ProjectDir)..\..\..\..\mediastreamer2\include;$(ProjectDir)..\..\..\..\oRTP\include;$(ProjectDir)..\..\..\..\..\belle-sip\include;$(ProjectDir)..\..\..\..\..\sqlite;$(ProjectDir)..\..\..\..\..\zlib;$(ProjectDir)..\..\..\..\..\cunit\build\windows10\cunit\$(Platform)\$(Configuration);%(AdditionalIncludeDirectories) + BC_CONFIG_FILE="config.h";IN_LINPHONE;MSG_STORAGE_ENABLED;VIDEO_ENABLED;HAVE_CU_GET_SUITE;HAVE_ZLIB;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions) + + + Console + false + false + + + + + + \ No newline at end of file diff --git a/build/windows10/liblinphone-tester/liblinphone-tester.csproj b/build/windows10/liblinphone-tester/liblinphone-tester.csproj new file mode 100644 index 000000000..ab018cc05 --- /dev/null +++ b/build/windows10/liblinphone-tester/liblinphone-tester.csproj @@ -0,0 +1,321 @@ + + + + + Debug + x86 + {EC78E1D3-6FD8-4CAF-8D3F-6F4F97093BE5} + AppContainerExe + Properties + liblinphone_tester + liblinphone-tester + en-US + UAP + 10.0.10240.0 + 10.0.10069.0 + 14 + true + 512 + {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + liblinphone-tester_TemporaryKey.pfx + + + true + bin\ARM\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + ARM + false + prompt + true + + + bin\ARM\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + ARM + false + prompt + true + true + + + true + bin\x64\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + x64 + false + prompt + true + + + bin\x64\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + x64 + false + prompt + true + true + + + true + bin\x86\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + x86 + false + prompt + true + + + bin\x86\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + x86 + false + prompt + true + true + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + + + App.xaml + + + + MainPage.xaml + + + + + + Designer + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + + {1ce10f06-8fad-437f-b3d7-3b7a8909a190} + liblinphone-tester-runtime-component + + + + + 14.0 + + + + XCopy /I /Y $(ProjectDir)..\..\..\tester\messages.db $(ProjectDir)Assets\ +XCopy /I /Y $(ProjectDir)..\..\..\tester\tester_hosts $(ProjectDir)Assets\ +XCopy /I /Y $(ProjectDir)..\..\..\tester\certificates\altname $(ProjectDir)Assets\certificates\altname +XCopy /I /Y $(ProjectDir)..\..\..\tester\certificates\cn $(ProjectDir)Assets\certificates\cn +XCopy /I /Y $(ProjectDir)..\..\..\tester\images $(ProjectDir)Assets\images +XCopy /I /Y $(ProjectDir)..\..\..\tester\rcfiles $(ProjectDir)Assets\rcfiles +XCopy /I /Y $(ProjectDir)..\..\..\tester\sounds $(ProjectDir)Assets\sounds + + + \ No newline at end of file diff --git a/build/windows10/liblinphone-tester/liblinphone-tester.sln b/build/windows10/liblinphone-tester/liblinphone-tester.sln new file mode 100644 index 000000000..376919bff --- /dev/null +++ b/build/windows10/liblinphone-tester/liblinphone-tester.sln @@ -0,0 +1,488 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.23107.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "liblinphone-tester", "liblinphone-tester.csproj", "{EC78E1D3-6FD8-4CAF-8D3F-6F4F97093BE5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblinphone-tester-static", "liblinphone-tester-static\liblinphone-tester-static.vcxproj", "{9EB3FE8D-2D91-4D29-A3BB-98DDB51D45B7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblinphone", "..\liblinphone\liblinphone.vcxproj", "{C7139899-D8BC-48A3-A437-6844A8BAABEF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mediastreamer2", "..\..\..\mediastreamer2\build\windows10\mediastreamer2\mediastreamer2.vcxproj", "{88E3C241-EB6F-4C84-80DC-89B8961DAF80}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ortp", "..\..\..\oRTP\build\windows10\ortp\ortp.vcxproj", "{2E56B851-9D8D-40E5-84BB-E4EE63B71D25}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "srtp", "..\..\..\..\srtp\build\windows10\srtp\srtp.vcxproj", "{59104E4F-A087-442E-ABD4-BCD2A1F0B0FE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xml2", "..\..\..\..\build\xml2\xml2.vcxproj", "{2B04DE79-4D33-4405-AC01-C89E0593A71D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "polarssl", "..\..\..\..\polarssl\build\windows10\polarssl\polarssl.vcxproj", "{88768DD9-5110-4AC8-8B0E-41CD7713E1A2}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "speex", "..\..\..\..\speex\build\windows10\speex\speex.vcxproj", "{971DD379-1C2D-44D2-9285-FDA556C48176}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "speexdsp", "..\..\..\..\speex\build\windows10\speexdsp\speexdsp.vcxproj", "{104BF91B-8314-4328-A996-90B8DF6052AF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opus", "..\..\..\..\opus\build\windows10\opus\opus.vcxproj", "{81AF1025-E0EE-4AD6-988D-2EF162778693}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bzrtp", "..\..\..\..\bzrtp\build\windows10\bzrtp\bzrtp.vcxproj", "{45C7723D-3107-4906-9633-F43ABE8A7147}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gsm", "..\..\..\..\gsm\build\windows10\gsm\gsm.vcxproj", "{EF1103C7-8AAC-464B-BA31-86B87246FA72}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "belle-sip", "..\..\..\..\belle-sip\build\windows10\belle-sip\belle-sip.vcxproj", "{B6CDF482-7DA3-43D4-9B12-70150106C191}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "antlr3c", "..\..\..\..\antlr3\runtime\C\build\windows10\antlr3c\antlr3c.vcxproj", "{01CCCCC9-CA0C-4528-92BC-5B8BE1D02D6D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\..\..\..\zlib\build\windows10\zlib\zlib.vcxproj", "{A34F450D-392D-4660-9618-810BD695B3B0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sqlite", "..\..\..\..\build\sqlite\sqlite.vcxproj", "{74CAD9D0-D8AE-4896-B71B-B2D9B48F30AA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblinphone-tester-runtime-component", "liblinphone-tester-runtime-component\liblinphone-tester-runtime-component.vcxproj", "{1CE10F06-8FAD-437F-B3D7-3B7A8909A190}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cunit", "..\..\..\..\cunit\build\windows10\cunit\cunit.vcxproj", "{025E28A8-9DFB-4015-AD56-19896AA6CC9B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmsamr", "..\..\..\..\msamr\build\windows10\libmsamr\libmsamr.vcxproj", "{8C1BC968-C5C8-4D4B-9EF3-D6A065FC7C97}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmsilbc", "..\..\..\..\msilbc\build\windows10\libmsilbc\libmsilbc.vcxproj", "{6A18BBB9-08D1-41A8-BE57-17FC992CC36F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmssilk", "..\..\..\..\mssilk\build\windows10\libmssilk\libmssilk.vcxproj", "{B84D5C3B-6DE5-49C8-B3DD-5EB67B01A527}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmswasapi", "..\..\..\..\mswasapi\windows10\libmswasapi\libmswasapi.vcxproj", "{266B769A-C04E-424C-9033-7209F0425BC0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmswebrtc", "..\..\..\..\mswebrtc\build\windows10\libmswebrtc\libmswebrtc.vcxproj", "{878CF9D3-9761-479E-A715-A1DE9F99CB78}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ilbc", "..\..\..\..\libilbc-rfc3951\build\windows10\ilbc\ilbc.vcxproj", "{995B01AF-C568-453E-9E5F-8AE81FB79B4B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opencore_amrnb", "..\..\..\..\msamr\build\windows10\opencore_amrnb\opencore_amrnb.vcxproj", "{71A5F1C8-F76D-4297-95AA-75E1C967DC79}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opencore_amrwb", "..\..\..\..\msamr\build\windows10\opencore_amrwb\opencore_amrwb.vcxproj", "{3CC91899-3E98-49FD-BED5-FA290A9A5C8E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vo-amrwbenc", "..\..\..\..\msamr\build\windows10\vo-amrwbenc\vo-amrwbenc.vcxproj", "{D829672F-3775-4718-A991-1ABC42CBA67C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "webrtc", "..\..\..\..\mswebrtc\webrtc\build\windows10\webrtc\webrtc.vcxproj", "{C5895B75-BDCF-406C-B803-9CB954E90F0C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmsbcg729", "..\..\..\..\bcg729\build\windows10\libmsbcg729\libmsbcg729.vcxproj", "{ACF5EA95-D647-4D0C-8F97-2CD9AAE8A2E0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmsopenh264", "..\..\..\..\msopenh264\build\windows10\libmsopenh264\libmsopenh264.vcxproj", "{BB8EBB21-F22C-4A68-99CB-67FA36C495E3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmswinrtvid", "..\..\..\..\mswinrtvid\windows10\libmswinrtvid\libmswinrtvid.vcxproj", "{2D0E44C4-E51D-4911-B876-345D1E5E5209}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mswinrtjpeg2yuv", "..\..\..\mediastreamer2\build\windows10\mswinrtjpeg2yuv\mswinrtjpeg2yuv.vcxproj", "{545F846D-7F19-4D6D-A50B-172A7C9B61E7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|ARM = Release|ARM + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {EC78E1D3-6FD8-4CAF-8D3F-6F4F97093BE5}.Debug|ARM.ActiveCfg = Debug|ARM + {EC78E1D3-6FD8-4CAF-8D3F-6F4F97093BE5}.Debug|ARM.Build.0 = Debug|ARM + {EC78E1D3-6FD8-4CAF-8D3F-6F4F97093BE5}.Debug|ARM.Deploy.0 = Debug|ARM + {EC78E1D3-6FD8-4CAF-8D3F-6F4F97093BE5}.Debug|x64.ActiveCfg = Debug|x64 + {EC78E1D3-6FD8-4CAF-8D3F-6F4F97093BE5}.Debug|x64.Build.0 = Debug|x64 + {EC78E1D3-6FD8-4CAF-8D3F-6F4F97093BE5}.Debug|x64.Deploy.0 = Debug|x64 + {EC78E1D3-6FD8-4CAF-8D3F-6F4F97093BE5}.Debug|x86.ActiveCfg = Debug|x86 + {EC78E1D3-6FD8-4CAF-8D3F-6F4F97093BE5}.Debug|x86.Build.0 = Debug|x86 + {EC78E1D3-6FD8-4CAF-8D3F-6F4F97093BE5}.Debug|x86.Deploy.0 = Debug|x86 + {EC78E1D3-6FD8-4CAF-8D3F-6F4F97093BE5}.Release|ARM.ActiveCfg = Release|ARM + {EC78E1D3-6FD8-4CAF-8D3F-6F4F97093BE5}.Release|ARM.Build.0 = Release|ARM + {EC78E1D3-6FD8-4CAF-8D3F-6F4F97093BE5}.Release|ARM.Deploy.0 = Release|ARM + {EC78E1D3-6FD8-4CAF-8D3F-6F4F97093BE5}.Release|x64.ActiveCfg = Release|x64 + {EC78E1D3-6FD8-4CAF-8D3F-6F4F97093BE5}.Release|x64.Build.0 = Release|x64 + {EC78E1D3-6FD8-4CAF-8D3F-6F4F97093BE5}.Release|x64.Deploy.0 = Release|x64 + {EC78E1D3-6FD8-4CAF-8D3F-6F4F97093BE5}.Release|x86.ActiveCfg = Release|x86 + {EC78E1D3-6FD8-4CAF-8D3F-6F4F97093BE5}.Release|x86.Build.0 = Release|x86 + {EC78E1D3-6FD8-4CAF-8D3F-6F4F97093BE5}.Release|x86.Deploy.0 = Release|x86 + {9EB3FE8D-2D91-4D29-A3BB-98DDB51D45B7}.Debug|ARM.ActiveCfg = Debug|ARM + {9EB3FE8D-2D91-4D29-A3BB-98DDB51D45B7}.Debug|ARM.Build.0 = Debug|ARM + {9EB3FE8D-2D91-4D29-A3BB-98DDB51D45B7}.Debug|x64.ActiveCfg = Debug|x64 + {9EB3FE8D-2D91-4D29-A3BB-98DDB51D45B7}.Debug|x64.Build.0 = Debug|x64 + {9EB3FE8D-2D91-4D29-A3BB-98DDB51D45B7}.Debug|x86.ActiveCfg = Debug|Win32 + {9EB3FE8D-2D91-4D29-A3BB-98DDB51D45B7}.Debug|x86.Build.0 = Debug|Win32 + {9EB3FE8D-2D91-4D29-A3BB-98DDB51D45B7}.Release|ARM.ActiveCfg = Release|ARM + {9EB3FE8D-2D91-4D29-A3BB-98DDB51D45B7}.Release|ARM.Build.0 = Release|ARM + {9EB3FE8D-2D91-4D29-A3BB-98DDB51D45B7}.Release|x64.ActiveCfg = Release|x64 + {9EB3FE8D-2D91-4D29-A3BB-98DDB51D45B7}.Release|x64.Build.0 = Release|x64 + {9EB3FE8D-2D91-4D29-A3BB-98DDB51D45B7}.Release|x86.ActiveCfg = Release|Win32 + {9EB3FE8D-2D91-4D29-A3BB-98DDB51D45B7}.Release|x86.Build.0 = Release|Win32 + {C7139899-D8BC-48A3-A437-6844A8BAABEF}.Debug|ARM.ActiveCfg = Debug|ARM + {C7139899-D8BC-48A3-A437-6844A8BAABEF}.Debug|ARM.Build.0 = Debug|ARM + {C7139899-D8BC-48A3-A437-6844A8BAABEF}.Debug|x64.ActiveCfg = Debug|x64 + {C7139899-D8BC-48A3-A437-6844A8BAABEF}.Debug|x64.Build.0 = Debug|x64 + {C7139899-D8BC-48A3-A437-6844A8BAABEF}.Debug|x86.ActiveCfg = Debug|Win32 + {C7139899-D8BC-48A3-A437-6844A8BAABEF}.Debug|x86.Build.0 = Debug|Win32 + {C7139899-D8BC-48A3-A437-6844A8BAABEF}.Release|ARM.ActiveCfg = Release|ARM + {C7139899-D8BC-48A3-A437-6844A8BAABEF}.Release|ARM.Build.0 = Release|ARM + {C7139899-D8BC-48A3-A437-6844A8BAABEF}.Release|x64.ActiveCfg = Release|x64 + {C7139899-D8BC-48A3-A437-6844A8BAABEF}.Release|x64.Build.0 = Release|x64 + {C7139899-D8BC-48A3-A437-6844A8BAABEF}.Release|x86.ActiveCfg = Release|Win32 + {C7139899-D8BC-48A3-A437-6844A8BAABEF}.Release|x86.Build.0 = Release|Win32 + {88E3C241-EB6F-4C84-80DC-89B8961DAF80}.Debug|ARM.ActiveCfg = Debug|ARM + {88E3C241-EB6F-4C84-80DC-89B8961DAF80}.Debug|ARM.Build.0 = Debug|ARM + {88E3C241-EB6F-4C84-80DC-89B8961DAF80}.Debug|x64.ActiveCfg = Debug|x64 + {88E3C241-EB6F-4C84-80DC-89B8961DAF80}.Debug|x64.Build.0 = Debug|x64 + {88E3C241-EB6F-4C84-80DC-89B8961DAF80}.Debug|x86.ActiveCfg = Debug|Win32 + {88E3C241-EB6F-4C84-80DC-89B8961DAF80}.Debug|x86.Build.0 = Debug|Win32 + {88E3C241-EB6F-4C84-80DC-89B8961DAF80}.Release|ARM.ActiveCfg = Release|ARM + {88E3C241-EB6F-4C84-80DC-89B8961DAF80}.Release|ARM.Build.0 = Release|ARM + {88E3C241-EB6F-4C84-80DC-89B8961DAF80}.Release|x64.ActiveCfg = Release|x64 + {88E3C241-EB6F-4C84-80DC-89B8961DAF80}.Release|x64.Build.0 = Release|x64 + {88E3C241-EB6F-4C84-80DC-89B8961DAF80}.Release|x86.ActiveCfg = Release|Win32 + {88E3C241-EB6F-4C84-80DC-89B8961DAF80}.Release|x86.Build.0 = Release|Win32 + {2E56B851-9D8D-40E5-84BB-E4EE63B71D25}.Debug|ARM.ActiveCfg = Debug|ARM + {2E56B851-9D8D-40E5-84BB-E4EE63B71D25}.Debug|ARM.Build.0 = Debug|ARM + {2E56B851-9D8D-40E5-84BB-E4EE63B71D25}.Debug|x64.ActiveCfg = Debug|x64 + {2E56B851-9D8D-40E5-84BB-E4EE63B71D25}.Debug|x64.Build.0 = Debug|x64 + {2E56B851-9D8D-40E5-84BB-E4EE63B71D25}.Debug|x86.ActiveCfg = Debug|Win32 + {2E56B851-9D8D-40E5-84BB-E4EE63B71D25}.Debug|x86.Build.0 = Debug|Win32 + {2E56B851-9D8D-40E5-84BB-E4EE63B71D25}.Release|ARM.ActiveCfg = Release|ARM + {2E56B851-9D8D-40E5-84BB-E4EE63B71D25}.Release|ARM.Build.0 = Release|ARM + {2E56B851-9D8D-40E5-84BB-E4EE63B71D25}.Release|x64.ActiveCfg = Release|x64 + {2E56B851-9D8D-40E5-84BB-E4EE63B71D25}.Release|x64.Build.0 = Release|x64 + {2E56B851-9D8D-40E5-84BB-E4EE63B71D25}.Release|x86.ActiveCfg = Release|Win32 + {2E56B851-9D8D-40E5-84BB-E4EE63B71D25}.Release|x86.Build.0 = Release|Win32 + {59104E4F-A087-442E-ABD4-BCD2A1F0B0FE}.Debug|ARM.ActiveCfg = Debug|ARM + {59104E4F-A087-442E-ABD4-BCD2A1F0B0FE}.Debug|ARM.Build.0 = Debug|ARM + {59104E4F-A087-442E-ABD4-BCD2A1F0B0FE}.Debug|x64.ActiveCfg = Debug|x64 + {59104E4F-A087-442E-ABD4-BCD2A1F0B0FE}.Debug|x64.Build.0 = Debug|x64 + {59104E4F-A087-442E-ABD4-BCD2A1F0B0FE}.Debug|x86.ActiveCfg = Debug|Win32 + {59104E4F-A087-442E-ABD4-BCD2A1F0B0FE}.Debug|x86.Build.0 = Debug|Win32 + {59104E4F-A087-442E-ABD4-BCD2A1F0B0FE}.Release|ARM.ActiveCfg = Release|ARM + {59104E4F-A087-442E-ABD4-BCD2A1F0B0FE}.Release|ARM.Build.0 = Release|ARM + {59104E4F-A087-442E-ABD4-BCD2A1F0B0FE}.Release|x64.ActiveCfg = Release|x64 + {59104E4F-A087-442E-ABD4-BCD2A1F0B0FE}.Release|x64.Build.0 = Release|x64 + {59104E4F-A087-442E-ABD4-BCD2A1F0B0FE}.Release|x86.ActiveCfg = Release|Win32 + {59104E4F-A087-442E-ABD4-BCD2A1F0B0FE}.Release|x86.Build.0 = Release|Win32 + {2B04DE79-4D33-4405-AC01-C89E0593A71D}.Debug|ARM.ActiveCfg = Debug|ARM + {2B04DE79-4D33-4405-AC01-C89E0593A71D}.Debug|ARM.Build.0 = Debug|ARM + {2B04DE79-4D33-4405-AC01-C89E0593A71D}.Debug|x64.ActiveCfg = Debug|x64 + {2B04DE79-4D33-4405-AC01-C89E0593A71D}.Debug|x64.Build.0 = Debug|x64 + {2B04DE79-4D33-4405-AC01-C89E0593A71D}.Debug|x86.ActiveCfg = Debug|Win32 + {2B04DE79-4D33-4405-AC01-C89E0593A71D}.Debug|x86.Build.0 = Debug|Win32 + {2B04DE79-4D33-4405-AC01-C89E0593A71D}.Release|ARM.ActiveCfg = Release|ARM + {2B04DE79-4D33-4405-AC01-C89E0593A71D}.Release|ARM.Build.0 = Release|ARM + {2B04DE79-4D33-4405-AC01-C89E0593A71D}.Release|x64.ActiveCfg = Release|x64 + {2B04DE79-4D33-4405-AC01-C89E0593A71D}.Release|x64.Build.0 = Release|x64 + {2B04DE79-4D33-4405-AC01-C89E0593A71D}.Release|x86.ActiveCfg = Release|Win32 + {2B04DE79-4D33-4405-AC01-C89E0593A71D}.Release|x86.Build.0 = Release|Win32 + {88768DD9-5110-4AC8-8B0E-41CD7713E1A2}.Debug|ARM.ActiveCfg = Debug|ARM + {88768DD9-5110-4AC8-8B0E-41CD7713E1A2}.Debug|ARM.Build.0 = Debug|ARM + {88768DD9-5110-4AC8-8B0E-41CD7713E1A2}.Debug|x64.ActiveCfg = Debug|x64 + {88768DD9-5110-4AC8-8B0E-41CD7713E1A2}.Debug|x64.Build.0 = Debug|x64 + {88768DD9-5110-4AC8-8B0E-41CD7713E1A2}.Debug|x86.ActiveCfg = Debug|Win32 + {88768DD9-5110-4AC8-8B0E-41CD7713E1A2}.Debug|x86.Build.0 = Debug|Win32 + {88768DD9-5110-4AC8-8B0E-41CD7713E1A2}.Release|ARM.ActiveCfg = Release|ARM + {88768DD9-5110-4AC8-8B0E-41CD7713E1A2}.Release|ARM.Build.0 = Release|ARM + {88768DD9-5110-4AC8-8B0E-41CD7713E1A2}.Release|x64.ActiveCfg = Release|x64 + {88768DD9-5110-4AC8-8B0E-41CD7713E1A2}.Release|x64.Build.0 = Release|x64 + {88768DD9-5110-4AC8-8B0E-41CD7713E1A2}.Release|x86.ActiveCfg = Release|Win32 + {88768DD9-5110-4AC8-8B0E-41CD7713E1A2}.Release|x86.Build.0 = Release|Win32 + {971DD379-1C2D-44D2-9285-FDA556C48176}.Debug|ARM.ActiveCfg = Debug|ARM + {971DD379-1C2D-44D2-9285-FDA556C48176}.Debug|ARM.Build.0 = Debug|ARM + {971DD379-1C2D-44D2-9285-FDA556C48176}.Debug|x64.ActiveCfg = Debug|x64 + {971DD379-1C2D-44D2-9285-FDA556C48176}.Debug|x64.Build.0 = Debug|x64 + {971DD379-1C2D-44D2-9285-FDA556C48176}.Debug|x86.ActiveCfg = Debug|Win32 + {971DD379-1C2D-44D2-9285-FDA556C48176}.Debug|x86.Build.0 = Debug|Win32 + {971DD379-1C2D-44D2-9285-FDA556C48176}.Release|ARM.ActiveCfg = Release|ARM + {971DD379-1C2D-44D2-9285-FDA556C48176}.Release|ARM.Build.0 = Release|ARM + {971DD379-1C2D-44D2-9285-FDA556C48176}.Release|x64.ActiveCfg = Release|x64 + {971DD379-1C2D-44D2-9285-FDA556C48176}.Release|x64.Build.0 = Release|x64 + {971DD379-1C2D-44D2-9285-FDA556C48176}.Release|x86.ActiveCfg = Release|Win32 + {971DD379-1C2D-44D2-9285-FDA556C48176}.Release|x86.Build.0 = Release|Win32 + {104BF91B-8314-4328-A996-90B8DF6052AF}.Debug|ARM.ActiveCfg = Debug|ARM + {104BF91B-8314-4328-A996-90B8DF6052AF}.Debug|ARM.Build.0 = Debug|ARM + {104BF91B-8314-4328-A996-90B8DF6052AF}.Debug|x64.ActiveCfg = Debug|x64 + {104BF91B-8314-4328-A996-90B8DF6052AF}.Debug|x64.Build.0 = Debug|x64 + {104BF91B-8314-4328-A996-90B8DF6052AF}.Debug|x86.ActiveCfg = Debug|Win32 + {104BF91B-8314-4328-A996-90B8DF6052AF}.Debug|x86.Build.0 = Debug|Win32 + {104BF91B-8314-4328-A996-90B8DF6052AF}.Release|ARM.ActiveCfg = Release|ARM + {104BF91B-8314-4328-A996-90B8DF6052AF}.Release|ARM.Build.0 = Release|ARM + {104BF91B-8314-4328-A996-90B8DF6052AF}.Release|x64.ActiveCfg = Release|x64 + {104BF91B-8314-4328-A996-90B8DF6052AF}.Release|x64.Build.0 = Release|x64 + {104BF91B-8314-4328-A996-90B8DF6052AF}.Release|x86.ActiveCfg = Release|Win32 + {104BF91B-8314-4328-A996-90B8DF6052AF}.Release|x86.Build.0 = Release|Win32 + {81AF1025-E0EE-4AD6-988D-2EF162778693}.Debug|ARM.ActiveCfg = Debug|ARM + {81AF1025-E0EE-4AD6-988D-2EF162778693}.Debug|ARM.Build.0 = Debug|ARM + {81AF1025-E0EE-4AD6-988D-2EF162778693}.Debug|x64.ActiveCfg = Debug|x64 + {81AF1025-E0EE-4AD6-988D-2EF162778693}.Debug|x64.Build.0 = Debug|x64 + {81AF1025-E0EE-4AD6-988D-2EF162778693}.Debug|x86.ActiveCfg = Debug|Win32 + {81AF1025-E0EE-4AD6-988D-2EF162778693}.Debug|x86.Build.0 = Debug|Win32 + {81AF1025-E0EE-4AD6-988D-2EF162778693}.Release|ARM.ActiveCfg = Release|ARM + {81AF1025-E0EE-4AD6-988D-2EF162778693}.Release|ARM.Build.0 = Release|ARM + {81AF1025-E0EE-4AD6-988D-2EF162778693}.Release|x64.ActiveCfg = Release|x64 + {81AF1025-E0EE-4AD6-988D-2EF162778693}.Release|x64.Build.0 = Release|x64 + {81AF1025-E0EE-4AD6-988D-2EF162778693}.Release|x86.ActiveCfg = Release|Win32 + {81AF1025-E0EE-4AD6-988D-2EF162778693}.Release|x86.Build.0 = Release|Win32 + {45C7723D-3107-4906-9633-F43ABE8A7147}.Debug|ARM.ActiveCfg = Debug|ARM + {45C7723D-3107-4906-9633-F43ABE8A7147}.Debug|ARM.Build.0 = Debug|ARM + {45C7723D-3107-4906-9633-F43ABE8A7147}.Debug|x64.ActiveCfg = Debug|x64 + {45C7723D-3107-4906-9633-F43ABE8A7147}.Debug|x64.Build.0 = Debug|x64 + {45C7723D-3107-4906-9633-F43ABE8A7147}.Debug|x86.ActiveCfg = Debug|Win32 + {45C7723D-3107-4906-9633-F43ABE8A7147}.Debug|x86.Build.0 = Debug|Win32 + {45C7723D-3107-4906-9633-F43ABE8A7147}.Release|ARM.ActiveCfg = Release|ARM + {45C7723D-3107-4906-9633-F43ABE8A7147}.Release|ARM.Build.0 = Release|ARM + {45C7723D-3107-4906-9633-F43ABE8A7147}.Release|x64.ActiveCfg = Release|x64 + {45C7723D-3107-4906-9633-F43ABE8A7147}.Release|x64.Build.0 = Release|x64 + {45C7723D-3107-4906-9633-F43ABE8A7147}.Release|x86.ActiveCfg = Release|Win32 + {45C7723D-3107-4906-9633-F43ABE8A7147}.Release|x86.Build.0 = Release|Win32 + {EF1103C7-8AAC-464B-BA31-86B87246FA72}.Debug|ARM.ActiveCfg = Debug|ARM + {EF1103C7-8AAC-464B-BA31-86B87246FA72}.Debug|ARM.Build.0 = Debug|ARM + {EF1103C7-8AAC-464B-BA31-86B87246FA72}.Debug|x64.ActiveCfg = Debug|x64 + {EF1103C7-8AAC-464B-BA31-86B87246FA72}.Debug|x64.Build.0 = Debug|x64 + {EF1103C7-8AAC-464B-BA31-86B87246FA72}.Debug|x86.ActiveCfg = Debug|Win32 + {EF1103C7-8AAC-464B-BA31-86B87246FA72}.Debug|x86.Build.0 = Debug|Win32 + {EF1103C7-8AAC-464B-BA31-86B87246FA72}.Release|ARM.ActiveCfg = Release|ARM + {EF1103C7-8AAC-464B-BA31-86B87246FA72}.Release|ARM.Build.0 = Release|ARM + {EF1103C7-8AAC-464B-BA31-86B87246FA72}.Release|x64.ActiveCfg = Release|x64 + {EF1103C7-8AAC-464B-BA31-86B87246FA72}.Release|x64.Build.0 = Release|x64 + {EF1103C7-8AAC-464B-BA31-86B87246FA72}.Release|x86.ActiveCfg = Release|Win32 + {EF1103C7-8AAC-464B-BA31-86B87246FA72}.Release|x86.Build.0 = Release|Win32 + {B6CDF482-7DA3-43D4-9B12-70150106C191}.Debug|ARM.ActiveCfg = Debug|ARM + {B6CDF482-7DA3-43D4-9B12-70150106C191}.Debug|ARM.Build.0 = Debug|ARM + {B6CDF482-7DA3-43D4-9B12-70150106C191}.Debug|x64.ActiveCfg = Debug|x64 + {B6CDF482-7DA3-43D4-9B12-70150106C191}.Debug|x64.Build.0 = Debug|x64 + {B6CDF482-7DA3-43D4-9B12-70150106C191}.Debug|x86.ActiveCfg = Debug|Win32 + {B6CDF482-7DA3-43D4-9B12-70150106C191}.Debug|x86.Build.0 = Debug|Win32 + {B6CDF482-7DA3-43D4-9B12-70150106C191}.Release|ARM.ActiveCfg = Release|ARM + {B6CDF482-7DA3-43D4-9B12-70150106C191}.Release|ARM.Build.0 = Release|ARM + {B6CDF482-7DA3-43D4-9B12-70150106C191}.Release|x64.ActiveCfg = Release|x64 + {B6CDF482-7DA3-43D4-9B12-70150106C191}.Release|x64.Build.0 = Release|x64 + {B6CDF482-7DA3-43D4-9B12-70150106C191}.Release|x86.ActiveCfg = Release|Win32 + {B6CDF482-7DA3-43D4-9B12-70150106C191}.Release|x86.Build.0 = Release|Win32 + {01CCCCC9-CA0C-4528-92BC-5B8BE1D02D6D}.Debug|ARM.ActiveCfg = Debug|ARM + {01CCCCC9-CA0C-4528-92BC-5B8BE1D02D6D}.Debug|ARM.Build.0 = Debug|ARM + {01CCCCC9-CA0C-4528-92BC-5B8BE1D02D6D}.Debug|x64.ActiveCfg = Debug|x64 + {01CCCCC9-CA0C-4528-92BC-5B8BE1D02D6D}.Debug|x64.Build.0 = Debug|x64 + {01CCCCC9-CA0C-4528-92BC-5B8BE1D02D6D}.Debug|x86.ActiveCfg = Debug|Win32 + {01CCCCC9-CA0C-4528-92BC-5B8BE1D02D6D}.Debug|x86.Build.0 = Debug|Win32 + {01CCCCC9-CA0C-4528-92BC-5B8BE1D02D6D}.Release|ARM.ActiveCfg = Release|ARM + {01CCCCC9-CA0C-4528-92BC-5B8BE1D02D6D}.Release|ARM.Build.0 = Release|ARM + {01CCCCC9-CA0C-4528-92BC-5B8BE1D02D6D}.Release|x64.ActiveCfg = Release|x64 + {01CCCCC9-CA0C-4528-92BC-5B8BE1D02D6D}.Release|x64.Build.0 = Release|x64 + {01CCCCC9-CA0C-4528-92BC-5B8BE1D02D6D}.Release|x86.ActiveCfg = Release|Win32 + {01CCCCC9-CA0C-4528-92BC-5B8BE1D02D6D}.Release|x86.Build.0 = Release|Win32 + {A34F450D-392D-4660-9618-810BD695B3B0}.Debug|ARM.ActiveCfg = Debug|ARM + {A34F450D-392D-4660-9618-810BD695B3B0}.Debug|ARM.Build.0 = Debug|ARM + {A34F450D-392D-4660-9618-810BD695B3B0}.Debug|x64.ActiveCfg = Debug|x64 + {A34F450D-392D-4660-9618-810BD695B3B0}.Debug|x64.Build.0 = Debug|x64 + {A34F450D-392D-4660-9618-810BD695B3B0}.Debug|x86.ActiveCfg = Debug|Win32 + {A34F450D-392D-4660-9618-810BD695B3B0}.Debug|x86.Build.0 = Debug|Win32 + {A34F450D-392D-4660-9618-810BD695B3B0}.Release|ARM.ActiveCfg = Release|ARM + {A34F450D-392D-4660-9618-810BD695B3B0}.Release|ARM.Build.0 = Release|ARM + {A34F450D-392D-4660-9618-810BD695B3B0}.Release|x64.ActiveCfg = Release|x64 + {A34F450D-392D-4660-9618-810BD695B3B0}.Release|x64.Build.0 = Release|x64 + {A34F450D-392D-4660-9618-810BD695B3B0}.Release|x86.ActiveCfg = Release|Win32 + {A34F450D-392D-4660-9618-810BD695B3B0}.Release|x86.Build.0 = Release|Win32 + {74CAD9D0-D8AE-4896-B71B-B2D9B48F30AA}.Debug|ARM.ActiveCfg = Debug|ARM + {74CAD9D0-D8AE-4896-B71B-B2D9B48F30AA}.Debug|ARM.Build.0 = Debug|ARM + {74CAD9D0-D8AE-4896-B71B-B2D9B48F30AA}.Debug|x64.ActiveCfg = Debug|x64 + {74CAD9D0-D8AE-4896-B71B-B2D9B48F30AA}.Debug|x64.Build.0 = Debug|x64 + {74CAD9D0-D8AE-4896-B71B-B2D9B48F30AA}.Debug|x86.ActiveCfg = Debug|Win32 + {74CAD9D0-D8AE-4896-B71B-B2D9B48F30AA}.Debug|x86.Build.0 = Debug|Win32 + {74CAD9D0-D8AE-4896-B71B-B2D9B48F30AA}.Release|ARM.ActiveCfg = Release|ARM + {74CAD9D0-D8AE-4896-B71B-B2D9B48F30AA}.Release|ARM.Build.0 = Release|ARM + {74CAD9D0-D8AE-4896-B71B-B2D9B48F30AA}.Release|x64.ActiveCfg = Release|x64 + {74CAD9D0-D8AE-4896-B71B-B2D9B48F30AA}.Release|x64.Build.0 = Release|x64 + {74CAD9D0-D8AE-4896-B71B-B2D9B48F30AA}.Release|x86.ActiveCfg = Release|Win32 + {74CAD9D0-D8AE-4896-B71B-B2D9B48F30AA}.Release|x86.Build.0 = Release|Win32 + {1CE10F06-8FAD-437F-B3D7-3B7A8909A190}.Debug|ARM.ActiveCfg = Debug|ARM + {1CE10F06-8FAD-437F-B3D7-3B7A8909A190}.Debug|ARM.Build.0 = Debug|ARM + {1CE10F06-8FAD-437F-B3D7-3B7A8909A190}.Debug|x64.ActiveCfg = Debug|x64 + {1CE10F06-8FAD-437F-B3D7-3B7A8909A190}.Debug|x64.Build.0 = Debug|x64 + {1CE10F06-8FAD-437F-B3D7-3B7A8909A190}.Debug|x86.ActiveCfg = Debug|Win32 + {1CE10F06-8FAD-437F-B3D7-3B7A8909A190}.Debug|x86.Build.0 = Debug|Win32 + {1CE10F06-8FAD-437F-B3D7-3B7A8909A190}.Release|ARM.ActiveCfg = Release|ARM + {1CE10F06-8FAD-437F-B3D7-3B7A8909A190}.Release|ARM.Build.0 = Release|ARM + {1CE10F06-8FAD-437F-B3D7-3B7A8909A190}.Release|x64.ActiveCfg = Release|x64 + {1CE10F06-8FAD-437F-B3D7-3B7A8909A190}.Release|x64.Build.0 = Release|x64 + {1CE10F06-8FAD-437F-B3D7-3B7A8909A190}.Release|x86.ActiveCfg = Release|Win32 + {1CE10F06-8FAD-437F-B3D7-3B7A8909A190}.Release|x86.Build.0 = Release|Win32 + {025E28A8-9DFB-4015-AD56-19896AA6CC9B}.Debug|ARM.ActiveCfg = Debug|ARM + {025E28A8-9DFB-4015-AD56-19896AA6CC9B}.Debug|ARM.Build.0 = Debug|ARM + {025E28A8-9DFB-4015-AD56-19896AA6CC9B}.Debug|x64.ActiveCfg = Debug|x64 + {025E28A8-9DFB-4015-AD56-19896AA6CC9B}.Debug|x64.Build.0 = Debug|x64 + {025E28A8-9DFB-4015-AD56-19896AA6CC9B}.Debug|x86.ActiveCfg = Debug|Win32 + {025E28A8-9DFB-4015-AD56-19896AA6CC9B}.Debug|x86.Build.0 = Debug|Win32 + {025E28A8-9DFB-4015-AD56-19896AA6CC9B}.Release|ARM.ActiveCfg = Release|ARM + {025E28A8-9DFB-4015-AD56-19896AA6CC9B}.Release|ARM.Build.0 = Release|ARM + {025E28A8-9DFB-4015-AD56-19896AA6CC9B}.Release|x64.ActiveCfg = Release|x64 + {025E28A8-9DFB-4015-AD56-19896AA6CC9B}.Release|x64.Build.0 = Release|x64 + {025E28A8-9DFB-4015-AD56-19896AA6CC9B}.Release|x86.ActiveCfg = Release|Win32 + {025E28A8-9DFB-4015-AD56-19896AA6CC9B}.Release|x86.Build.0 = Release|Win32 + {8C1BC968-C5C8-4D4B-9EF3-D6A065FC7C97}.Debug|ARM.ActiveCfg = Debug|ARM + {8C1BC968-C5C8-4D4B-9EF3-D6A065FC7C97}.Debug|ARM.Build.0 = Debug|ARM + {8C1BC968-C5C8-4D4B-9EF3-D6A065FC7C97}.Debug|x64.ActiveCfg = Debug|x64 + {8C1BC968-C5C8-4D4B-9EF3-D6A065FC7C97}.Debug|x64.Build.0 = Debug|x64 + {8C1BC968-C5C8-4D4B-9EF3-D6A065FC7C97}.Debug|x86.ActiveCfg = Debug|Win32 + {8C1BC968-C5C8-4D4B-9EF3-D6A065FC7C97}.Debug|x86.Build.0 = Debug|Win32 + {8C1BC968-C5C8-4D4B-9EF3-D6A065FC7C97}.Release|ARM.ActiveCfg = Release|ARM + {8C1BC968-C5C8-4D4B-9EF3-D6A065FC7C97}.Release|ARM.Build.0 = Release|ARM + {8C1BC968-C5C8-4D4B-9EF3-D6A065FC7C97}.Release|x64.ActiveCfg = Release|x64 + {8C1BC968-C5C8-4D4B-9EF3-D6A065FC7C97}.Release|x64.Build.0 = Release|x64 + {8C1BC968-C5C8-4D4B-9EF3-D6A065FC7C97}.Release|x86.ActiveCfg = Release|Win32 + {8C1BC968-C5C8-4D4B-9EF3-D6A065FC7C97}.Release|x86.Build.0 = Release|Win32 + {6A18BBB9-08D1-41A8-BE57-17FC992CC36F}.Debug|ARM.ActiveCfg = Debug|ARM + {6A18BBB9-08D1-41A8-BE57-17FC992CC36F}.Debug|ARM.Build.0 = Debug|ARM + {6A18BBB9-08D1-41A8-BE57-17FC992CC36F}.Debug|x64.ActiveCfg = Debug|x64 + {6A18BBB9-08D1-41A8-BE57-17FC992CC36F}.Debug|x64.Build.0 = Debug|x64 + {6A18BBB9-08D1-41A8-BE57-17FC992CC36F}.Debug|x86.ActiveCfg = Debug|Win32 + {6A18BBB9-08D1-41A8-BE57-17FC992CC36F}.Debug|x86.Build.0 = Debug|Win32 + {6A18BBB9-08D1-41A8-BE57-17FC992CC36F}.Release|ARM.ActiveCfg = Release|ARM + {6A18BBB9-08D1-41A8-BE57-17FC992CC36F}.Release|ARM.Build.0 = Release|ARM + {6A18BBB9-08D1-41A8-BE57-17FC992CC36F}.Release|x64.ActiveCfg = Release|x64 + {6A18BBB9-08D1-41A8-BE57-17FC992CC36F}.Release|x64.Build.0 = Release|x64 + {6A18BBB9-08D1-41A8-BE57-17FC992CC36F}.Release|x86.ActiveCfg = Release|Win32 + {6A18BBB9-08D1-41A8-BE57-17FC992CC36F}.Release|x86.Build.0 = Release|Win32 + {B84D5C3B-6DE5-49C8-B3DD-5EB67B01A527}.Debug|ARM.ActiveCfg = Debug|ARM + {B84D5C3B-6DE5-49C8-B3DD-5EB67B01A527}.Debug|ARM.Build.0 = Debug|ARM + {B84D5C3B-6DE5-49C8-B3DD-5EB67B01A527}.Debug|x64.ActiveCfg = Debug|x64 + {B84D5C3B-6DE5-49C8-B3DD-5EB67B01A527}.Debug|x64.Build.0 = Debug|x64 + {B84D5C3B-6DE5-49C8-B3DD-5EB67B01A527}.Debug|x86.ActiveCfg = Debug|Win32 + {B84D5C3B-6DE5-49C8-B3DD-5EB67B01A527}.Debug|x86.Build.0 = Debug|Win32 + {B84D5C3B-6DE5-49C8-B3DD-5EB67B01A527}.Release|ARM.ActiveCfg = Release|ARM + {B84D5C3B-6DE5-49C8-B3DD-5EB67B01A527}.Release|ARM.Build.0 = Release|ARM + {B84D5C3B-6DE5-49C8-B3DD-5EB67B01A527}.Release|x64.ActiveCfg = Release|x64 + {B84D5C3B-6DE5-49C8-B3DD-5EB67B01A527}.Release|x64.Build.0 = Release|x64 + {B84D5C3B-6DE5-49C8-B3DD-5EB67B01A527}.Release|x86.ActiveCfg = Release|Win32 + {B84D5C3B-6DE5-49C8-B3DD-5EB67B01A527}.Release|x86.Build.0 = Release|Win32 + {266B769A-C04E-424C-9033-7209F0425BC0}.Debug|ARM.ActiveCfg = Debug|ARM + {266B769A-C04E-424C-9033-7209F0425BC0}.Debug|ARM.Build.0 = Debug|ARM + {266B769A-C04E-424C-9033-7209F0425BC0}.Debug|x64.ActiveCfg = Debug|x64 + {266B769A-C04E-424C-9033-7209F0425BC0}.Debug|x64.Build.0 = Debug|x64 + {266B769A-C04E-424C-9033-7209F0425BC0}.Debug|x86.ActiveCfg = Debug|Win32 + {266B769A-C04E-424C-9033-7209F0425BC0}.Debug|x86.Build.0 = Debug|Win32 + {266B769A-C04E-424C-9033-7209F0425BC0}.Release|ARM.ActiveCfg = Release|ARM + {266B769A-C04E-424C-9033-7209F0425BC0}.Release|ARM.Build.0 = Release|ARM + {266B769A-C04E-424C-9033-7209F0425BC0}.Release|x64.ActiveCfg = Release|x64 + {266B769A-C04E-424C-9033-7209F0425BC0}.Release|x64.Build.0 = Release|x64 + {266B769A-C04E-424C-9033-7209F0425BC0}.Release|x86.ActiveCfg = Release|Win32 + {266B769A-C04E-424C-9033-7209F0425BC0}.Release|x86.Build.0 = Release|Win32 + {878CF9D3-9761-479E-A715-A1DE9F99CB78}.Debug|ARM.ActiveCfg = Debug|ARM + {878CF9D3-9761-479E-A715-A1DE9F99CB78}.Debug|ARM.Build.0 = Debug|ARM + {878CF9D3-9761-479E-A715-A1DE9F99CB78}.Debug|x64.ActiveCfg = Debug|x64 + {878CF9D3-9761-479E-A715-A1DE9F99CB78}.Debug|x64.Build.0 = Debug|x64 + {878CF9D3-9761-479E-A715-A1DE9F99CB78}.Debug|x86.ActiveCfg = Debug|Win32 + {878CF9D3-9761-479E-A715-A1DE9F99CB78}.Debug|x86.Build.0 = Debug|Win32 + {878CF9D3-9761-479E-A715-A1DE9F99CB78}.Release|ARM.ActiveCfg = Release|ARM + {878CF9D3-9761-479E-A715-A1DE9F99CB78}.Release|ARM.Build.0 = Release|ARM + {878CF9D3-9761-479E-A715-A1DE9F99CB78}.Release|x64.ActiveCfg = Release|x64 + {878CF9D3-9761-479E-A715-A1DE9F99CB78}.Release|x64.Build.0 = Release|x64 + {878CF9D3-9761-479E-A715-A1DE9F99CB78}.Release|x86.ActiveCfg = Release|Win32 + {878CF9D3-9761-479E-A715-A1DE9F99CB78}.Release|x86.Build.0 = Release|Win32 + {995B01AF-C568-453E-9E5F-8AE81FB79B4B}.Debug|ARM.ActiveCfg = Debug|ARM + {995B01AF-C568-453E-9E5F-8AE81FB79B4B}.Debug|ARM.Build.0 = Debug|ARM + {995B01AF-C568-453E-9E5F-8AE81FB79B4B}.Debug|x64.ActiveCfg = Debug|x64 + {995B01AF-C568-453E-9E5F-8AE81FB79B4B}.Debug|x64.Build.0 = Debug|x64 + {995B01AF-C568-453E-9E5F-8AE81FB79B4B}.Debug|x86.ActiveCfg = Debug|Win32 + {995B01AF-C568-453E-9E5F-8AE81FB79B4B}.Debug|x86.Build.0 = Debug|Win32 + {995B01AF-C568-453E-9E5F-8AE81FB79B4B}.Release|ARM.ActiveCfg = Release|ARM + {995B01AF-C568-453E-9E5F-8AE81FB79B4B}.Release|ARM.Build.0 = Release|ARM + {995B01AF-C568-453E-9E5F-8AE81FB79B4B}.Release|x64.ActiveCfg = Release|x64 + {995B01AF-C568-453E-9E5F-8AE81FB79B4B}.Release|x64.Build.0 = Release|x64 + {995B01AF-C568-453E-9E5F-8AE81FB79B4B}.Release|x86.ActiveCfg = Release|Win32 + {995B01AF-C568-453E-9E5F-8AE81FB79B4B}.Release|x86.Build.0 = Release|Win32 + {71A5F1C8-F76D-4297-95AA-75E1C967DC79}.Debug|ARM.ActiveCfg = Debug|ARM + {71A5F1C8-F76D-4297-95AA-75E1C967DC79}.Debug|ARM.Build.0 = Debug|ARM + {71A5F1C8-F76D-4297-95AA-75E1C967DC79}.Debug|x64.ActiveCfg = Debug|x64 + {71A5F1C8-F76D-4297-95AA-75E1C967DC79}.Debug|x64.Build.0 = Debug|x64 + {71A5F1C8-F76D-4297-95AA-75E1C967DC79}.Debug|x86.ActiveCfg = Debug|Win32 + {71A5F1C8-F76D-4297-95AA-75E1C967DC79}.Debug|x86.Build.0 = Debug|Win32 + {71A5F1C8-F76D-4297-95AA-75E1C967DC79}.Release|ARM.ActiveCfg = Release|ARM + {71A5F1C8-F76D-4297-95AA-75E1C967DC79}.Release|ARM.Build.0 = Release|ARM + {71A5F1C8-F76D-4297-95AA-75E1C967DC79}.Release|x64.ActiveCfg = Release|x64 + {71A5F1C8-F76D-4297-95AA-75E1C967DC79}.Release|x64.Build.0 = Release|x64 + {71A5F1C8-F76D-4297-95AA-75E1C967DC79}.Release|x86.ActiveCfg = Release|Win32 + {71A5F1C8-F76D-4297-95AA-75E1C967DC79}.Release|x86.Build.0 = Release|Win32 + {3CC91899-3E98-49FD-BED5-FA290A9A5C8E}.Debug|ARM.ActiveCfg = Debug|ARM + {3CC91899-3E98-49FD-BED5-FA290A9A5C8E}.Debug|ARM.Build.0 = Debug|ARM + {3CC91899-3E98-49FD-BED5-FA290A9A5C8E}.Debug|x64.ActiveCfg = Debug|x64 + {3CC91899-3E98-49FD-BED5-FA290A9A5C8E}.Debug|x64.Build.0 = Debug|x64 + {3CC91899-3E98-49FD-BED5-FA290A9A5C8E}.Debug|x86.ActiveCfg = Debug|Win32 + {3CC91899-3E98-49FD-BED5-FA290A9A5C8E}.Debug|x86.Build.0 = Debug|Win32 + {3CC91899-3E98-49FD-BED5-FA290A9A5C8E}.Release|ARM.ActiveCfg = Release|ARM + {3CC91899-3E98-49FD-BED5-FA290A9A5C8E}.Release|ARM.Build.0 = Release|ARM + {3CC91899-3E98-49FD-BED5-FA290A9A5C8E}.Release|x64.ActiveCfg = Release|x64 + {3CC91899-3E98-49FD-BED5-FA290A9A5C8E}.Release|x64.Build.0 = Release|x64 + {3CC91899-3E98-49FD-BED5-FA290A9A5C8E}.Release|x86.ActiveCfg = Release|Win32 + {3CC91899-3E98-49FD-BED5-FA290A9A5C8E}.Release|x86.Build.0 = Release|Win32 + {D829672F-3775-4718-A991-1ABC42CBA67C}.Debug|ARM.ActiveCfg = Debug|ARM + {D829672F-3775-4718-A991-1ABC42CBA67C}.Debug|ARM.Build.0 = Debug|ARM + {D829672F-3775-4718-A991-1ABC42CBA67C}.Debug|x64.ActiveCfg = Debug|x64 + {D829672F-3775-4718-A991-1ABC42CBA67C}.Debug|x64.Build.0 = Debug|x64 + {D829672F-3775-4718-A991-1ABC42CBA67C}.Debug|x86.ActiveCfg = Debug|Win32 + {D829672F-3775-4718-A991-1ABC42CBA67C}.Debug|x86.Build.0 = Debug|Win32 + {D829672F-3775-4718-A991-1ABC42CBA67C}.Release|ARM.ActiveCfg = Release|ARM + {D829672F-3775-4718-A991-1ABC42CBA67C}.Release|ARM.Build.0 = Release|ARM + {D829672F-3775-4718-A991-1ABC42CBA67C}.Release|x64.ActiveCfg = Release|x64 + {D829672F-3775-4718-A991-1ABC42CBA67C}.Release|x64.Build.0 = Release|x64 + {D829672F-3775-4718-A991-1ABC42CBA67C}.Release|x86.ActiveCfg = Release|Win32 + {D829672F-3775-4718-A991-1ABC42CBA67C}.Release|x86.Build.0 = Release|Win32 + {C5895B75-BDCF-406C-B803-9CB954E90F0C}.Debug|ARM.ActiveCfg = Debug|ARM + {C5895B75-BDCF-406C-B803-9CB954E90F0C}.Debug|ARM.Build.0 = Debug|ARM + {C5895B75-BDCF-406C-B803-9CB954E90F0C}.Debug|x64.ActiveCfg = Debug|x64 + {C5895B75-BDCF-406C-B803-9CB954E90F0C}.Debug|x64.Build.0 = Debug|x64 + {C5895B75-BDCF-406C-B803-9CB954E90F0C}.Debug|x86.ActiveCfg = Debug|Win32 + {C5895B75-BDCF-406C-B803-9CB954E90F0C}.Debug|x86.Build.0 = Debug|Win32 + {C5895B75-BDCF-406C-B803-9CB954E90F0C}.Release|ARM.ActiveCfg = Release|ARM + {C5895B75-BDCF-406C-B803-9CB954E90F0C}.Release|ARM.Build.0 = Release|ARM + {C5895B75-BDCF-406C-B803-9CB954E90F0C}.Release|x64.ActiveCfg = Release|x64 + {C5895B75-BDCF-406C-B803-9CB954E90F0C}.Release|x64.Build.0 = Release|x64 + {C5895B75-BDCF-406C-B803-9CB954E90F0C}.Release|x86.ActiveCfg = Release|Win32 + {C5895B75-BDCF-406C-B803-9CB954E90F0C}.Release|x86.Build.0 = Release|Win32 + {ACF5EA95-D647-4D0C-8F97-2CD9AAE8A2E0}.Debug|ARM.ActiveCfg = Debug|ARM + {ACF5EA95-D647-4D0C-8F97-2CD9AAE8A2E0}.Debug|ARM.Build.0 = Debug|ARM + {ACF5EA95-D647-4D0C-8F97-2CD9AAE8A2E0}.Debug|x64.ActiveCfg = Debug|x64 + {ACF5EA95-D647-4D0C-8F97-2CD9AAE8A2E0}.Debug|x64.Build.0 = Debug|x64 + {ACF5EA95-D647-4D0C-8F97-2CD9AAE8A2E0}.Debug|x86.ActiveCfg = Debug|Win32 + {ACF5EA95-D647-4D0C-8F97-2CD9AAE8A2E0}.Debug|x86.Build.0 = Debug|Win32 + {ACF5EA95-D647-4D0C-8F97-2CD9AAE8A2E0}.Release|ARM.ActiveCfg = Release|ARM + {ACF5EA95-D647-4D0C-8F97-2CD9AAE8A2E0}.Release|ARM.Build.0 = Release|ARM + {ACF5EA95-D647-4D0C-8F97-2CD9AAE8A2E0}.Release|x64.ActiveCfg = Release|x64 + {ACF5EA95-D647-4D0C-8F97-2CD9AAE8A2E0}.Release|x64.Build.0 = Release|x64 + {ACF5EA95-D647-4D0C-8F97-2CD9AAE8A2E0}.Release|x86.ActiveCfg = Release|Win32 + {ACF5EA95-D647-4D0C-8F97-2CD9AAE8A2E0}.Release|x86.Build.0 = Release|Win32 + {BB8EBB21-F22C-4A68-99CB-67FA36C495E3}.Debug|ARM.ActiveCfg = Debug|ARM + {BB8EBB21-F22C-4A68-99CB-67FA36C495E3}.Debug|ARM.Build.0 = Debug|ARM + {BB8EBB21-F22C-4A68-99CB-67FA36C495E3}.Debug|x64.ActiveCfg = Debug|x64 + {BB8EBB21-F22C-4A68-99CB-67FA36C495E3}.Debug|x64.Build.0 = Debug|x64 + {BB8EBB21-F22C-4A68-99CB-67FA36C495E3}.Debug|x86.ActiveCfg = Debug|Win32 + {BB8EBB21-F22C-4A68-99CB-67FA36C495E3}.Debug|x86.Build.0 = Debug|Win32 + {BB8EBB21-F22C-4A68-99CB-67FA36C495E3}.Release|ARM.ActiveCfg = Release|ARM + {BB8EBB21-F22C-4A68-99CB-67FA36C495E3}.Release|ARM.Build.0 = Release|ARM + {BB8EBB21-F22C-4A68-99CB-67FA36C495E3}.Release|x64.ActiveCfg = Release|x64 + {BB8EBB21-F22C-4A68-99CB-67FA36C495E3}.Release|x64.Build.0 = Release|x64 + {BB8EBB21-F22C-4A68-99CB-67FA36C495E3}.Release|x86.ActiveCfg = Release|Win32 + {BB8EBB21-F22C-4A68-99CB-67FA36C495E3}.Release|x86.Build.0 = Release|Win32 + {2D0E44C4-E51D-4911-B876-345D1E5E5209}.Debug|ARM.ActiveCfg = Debug|ARM + {2D0E44C4-E51D-4911-B876-345D1E5E5209}.Debug|ARM.Build.0 = Debug|ARM + {2D0E44C4-E51D-4911-B876-345D1E5E5209}.Debug|x64.ActiveCfg = Debug|x64 + {2D0E44C4-E51D-4911-B876-345D1E5E5209}.Debug|x64.Build.0 = Debug|x64 + {2D0E44C4-E51D-4911-B876-345D1E5E5209}.Debug|x86.ActiveCfg = Debug|Win32 + {2D0E44C4-E51D-4911-B876-345D1E5E5209}.Debug|x86.Build.0 = Debug|Win32 + {2D0E44C4-E51D-4911-B876-345D1E5E5209}.Release|ARM.ActiveCfg = Release|ARM + {2D0E44C4-E51D-4911-B876-345D1E5E5209}.Release|ARM.Build.0 = Release|ARM + {2D0E44C4-E51D-4911-B876-345D1E5E5209}.Release|x64.ActiveCfg = Release|x64 + {2D0E44C4-E51D-4911-B876-345D1E5E5209}.Release|x64.Build.0 = Release|x64 + {2D0E44C4-E51D-4911-B876-345D1E5E5209}.Release|x86.ActiveCfg = Release|Win32 + {2D0E44C4-E51D-4911-B876-345D1E5E5209}.Release|x86.Build.0 = Release|Win32 + {545F846D-7F19-4D6D-A50B-172A7C9B61E7}.Debug|ARM.ActiveCfg = Debug|ARM + {545F846D-7F19-4D6D-A50B-172A7C9B61E7}.Debug|ARM.Build.0 = Debug|ARM + {545F846D-7F19-4D6D-A50B-172A7C9B61E7}.Debug|x64.ActiveCfg = Debug|x64 + {545F846D-7F19-4D6D-A50B-172A7C9B61E7}.Debug|x64.Build.0 = Debug|x64 + {545F846D-7F19-4D6D-A50B-172A7C9B61E7}.Debug|x86.ActiveCfg = Debug|Win32 + {545F846D-7F19-4D6D-A50B-172A7C9B61E7}.Debug|x86.Build.0 = Debug|Win32 + {545F846D-7F19-4D6D-A50B-172A7C9B61E7}.Release|ARM.ActiveCfg = Release|ARM + {545F846D-7F19-4D6D-A50B-172A7C9B61E7}.Release|ARM.Build.0 = Release|ARM + {545F846D-7F19-4D6D-A50B-172A7C9B61E7}.Release|x64.ActiveCfg = Release|x64 + {545F846D-7F19-4D6D-A50B-172A7C9B61E7}.Release|x64.Build.0 = Release|x64 + {545F846D-7F19-4D6D-A50B-172A7C9B61E7}.Release|x86.ActiveCfg = Release|Win32 + {545F846D-7F19-4D6D-A50B-172A7C9B61E7}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/build/windows10/liblinphone-tester/liblinphone-tester_TemporaryKey.pfx b/build/windows10/liblinphone-tester/liblinphone-tester_TemporaryKey.pfx new file mode 100644 index 000000000..3aeb9f3b9 Binary files /dev/null and b/build/windows10/liblinphone-tester/liblinphone-tester_TemporaryKey.pfx differ diff --git a/build/windows10/liblinphone-tester/project.json b/build/windows10/liblinphone-tester/project.json new file mode 100644 index 000000000..e3b2dba25 --- /dev/null +++ b/build/windows10/liblinphone-tester/project.json @@ -0,0 +1,19 @@ +{ + "dependencies": { + "Microsoft.ApplicationInsights": "1.0.0", + "Microsoft.ApplicationInsights.PersistenceChannel": "1.0.0", + "Microsoft.ApplicationInsights.WindowsApps": "1.0.0", + "Microsoft.NETCore.UniversalWindowsPlatform": "5.0.0" + }, + "frameworks": { + "uap10.0": {} + }, + "runtimes": { + "win10-arm": {}, + "win10-arm-aot": {}, + "win10-x86": {}, + "win10-x86-aot": {}, + "win10-x64": {}, + "win10-x64-aot": {} + } +} \ No newline at end of file diff --git a/build/windows10/liblinphone/liblinphone.sln b/build/windows10/liblinphone/liblinphone.sln new file mode 100644 index 000000000..abfa15a85 --- /dev/null +++ b/build/windows10/liblinphone/liblinphone.sln @@ -0,0 +1,230 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.22823.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblinphone", "liblinphone.vcxproj", "{C7139899-D8BC-48A3-A437-6844A8BAABEF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mediastreamer2", "..\..\..\mediastreamer2\build\windows10\mediastreamer2\mediastreamer2.vcxproj", "{88E3C241-EB6F-4C84-80DC-89B8961DAF80}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ortp", "..\..\..\oRTP\build\windows10\ortp\ortp.vcxproj", "{2E56B851-9D8D-40E5-84BB-E4EE63B71D25}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "srtp", "..\..\..\..\srtp\build\windows10\srtp\srtp.vcxproj", "{59104E4F-A087-442E-ABD4-BCD2A1F0B0FE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xml2", "..\..\..\..\build\xml2\xml2.vcxproj", "{2B04DE79-4D33-4405-AC01-C89E0593A71D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "polarssl", "..\..\..\..\polarssl\build\windows10\polarssl\polarssl.vcxproj", "{88768DD9-5110-4AC8-8B0E-41CD7713E1A2}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "speex", "..\..\..\..\speex\build\windows10\speex\speex.vcxproj", "{971DD379-1C2D-44D2-9285-FDA556C48176}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "speexdsp", "..\..\..\..\speex\build\windows10\speexdsp\speexdsp.vcxproj", "{104BF91B-8314-4328-A996-90B8DF6052AF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opus", "..\..\..\..\opus\build\windows10\opus\opus.vcxproj", "{81AF1025-E0EE-4AD6-988D-2EF162778693}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bzrtp", "..\..\..\..\bzrtp\build\windows10\bzrtp\bzrtp.vcxproj", "{45C7723D-3107-4906-9633-F43ABE8A7147}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gsm", "..\..\..\..\gsm\build\windows10\gsm\gsm.vcxproj", "{EF1103C7-8AAC-464B-BA31-86B87246FA72}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "belle-sip", "..\..\..\..\belle-sip\build\windows10\belle-sip\belle-sip.vcxproj", "{B6CDF482-7DA3-43D4-9B12-70150106C191}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "antlr3c", "..\..\..\..\antlr3\runtime\C\build\windows10\antlr3c\antlr3c.vcxproj", "{01CCCCC9-CA0C-4528-92BC-5B8BE1D02D6D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\..\..\..\zlib\build\windows10\zlib\zlib.vcxproj", "{A34F450D-392D-4660-9618-810BD695B3B0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sqlite", "..\..\..\..\build\sqlite\sqlite.vcxproj", "{74CAD9D0-D8AE-4896-B71B-B2D9B48F30AA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|ARM = Release|ARM + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C7139899-D8BC-48A3-A437-6844A8BAABEF}.Debug|ARM.ActiveCfg = Debug|ARM + {C7139899-D8BC-48A3-A437-6844A8BAABEF}.Debug|ARM.Build.0 = Debug|ARM + {C7139899-D8BC-48A3-A437-6844A8BAABEF}.Debug|x64.ActiveCfg = Debug|x64 + {C7139899-D8BC-48A3-A437-6844A8BAABEF}.Debug|x64.Build.0 = Debug|x64 + {C7139899-D8BC-48A3-A437-6844A8BAABEF}.Debug|x86.ActiveCfg = Debug|Win32 + {C7139899-D8BC-48A3-A437-6844A8BAABEF}.Debug|x86.Build.0 = Debug|Win32 + {C7139899-D8BC-48A3-A437-6844A8BAABEF}.Release|ARM.ActiveCfg = Release|ARM + {C7139899-D8BC-48A3-A437-6844A8BAABEF}.Release|ARM.Build.0 = Release|ARM + {C7139899-D8BC-48A3-A437-6844A8BAABEF}.Release|x64.ActiveCfg = Release|x64 + {C7139899-D8BC-48A3-A437-6844A8BAABEF}.Release|x64.Build.0 = Release|x64 + {C7139899-D8BC-48A3-A437-6844A8BAABEF}.Release|x86.ActiveCfg = Release|Win32 + {C7139899-D8BC-48A3-A437-6844A8BAABEF}.Release|x86.Build.0 = Release|Win32 + {88E3C241-EB6F-4C84-80DC-89B8961DAF80}.Debug|ARM.ActiveCfg = Debug|ARM + {88E3C241-EB6F-4C84-80DC-89B8961DAF80}.Debug|ARM.Build.0 = Debug|ARM + {88E3C241-EB6F-4C84-80DC-89B8961DAF80}.Debug|x64.ActiveCfg = Debug|x64 + {88E3C241-EB6F-4C84-80DC-89B8961DAF80}.Debug|x64.Build.0 = Debug|x64 + {88E3C241-EB6F-4C84-80DC-89B8961DAF80}.Debug|x86.ActiveCfg = Debug|Win32 + {88E3C241-EB6F-4C84-80DC-89B8961DAF80}.Debug|x86.Build.0 = Debug|Win32 + {88E3C241-EB6F-4C84-80DC-89B8961DAF80}.Release|ARM.ActiveCfg = Release|ARM + {88E3C241-EB6F-4C84-80DC-89B8961DAF80}.Release|ARM.Build.0 = Release|ARM + {88E3C241-EB6F-4C84-80DC-89B8961DAF80}.Release|x64.ActiveCfg = Release|x64 + {88E3C241-EB6F-4C84-80DC-89B8961DAF80}.Release|x64.Build.0 = Release|x64 + {88E3C241-EB6F-4C84-80DC-89B8961DAF80}.Release|x86.ActiveCfg = Release|Win32 + {88E3C241-EB6F-4C84-80DC-89B8961DAF80}.Release|x86.Build.0 = Release|Win32 + {2E56B851-9D8D-40E5-84BB-E4EE63B71D25}.Debug|ARM.ActiveCfg = Debug|ARM + {2E56B851-9D8D-40E5-84BB-E4EE63B71D25}.Debug|ARM.Build.0 = Debug|ARM + {2E56B851-9D8D-40E5-84BB-E4EE63B71D25}.Debug|x64.ActiveCfg = Debug|x64 + {2E56B851-9D8D-40E5-84BB-E4EE63B71D25}.Debug|x64.Build.0 = Debug|x64 + {2E56B851-9D8D-40E5-84BB-E4EE63B71D25}.Debug|x86.ActiveCfg = Debug|Win32 + {2E56B851-9D8D-40E5-84BB-E4EE63B71D25}.Debug|x86.Build.0 = Debug|Win32 + {2E56B851-9D8D-40E5-84BB-E4EE63B71D25}.Release|ARM.ActiveCfg = Release|ARM + {2E56B851-9D8D-40E5-84BB-E4EE63B71D25}.Release|ARM.Build.0 = Release|ARM + {2E56B851-9D8D-40E5-84BB-E4EE63B71D25}.Release|x64.ActiveCfg = Release|x64 + {2E56B851-9D8D-40E5-84BB-E4EE63B71D25}.Release|x64.Build.0 = Release|x64 + {2E56B851-9D8D-40E5-84BB-E4EE63B71D25}.Release|x86.ActiveCfg = Release|Win32 + {2E56B851-9D8D-40E5-84BB-E4EE63B71D25}.Release|x86.Build.0 = Release|Win32 + {59104E4F-A087-442E-ABD4-BCD2A1F0B0FE}.Debug|ARM.ActiveCfg = Debug|ARM + {59104E4F-A087-442E-ABD4-BCD2A1F0B0FE}.Debug|ARM.Build.0 = Debug|ARM + {59104E4F-A087-442E-ABD4-BCD2A1F0B0FE}.Debug|x64.ActiveCfg = Debug|x64 + {59104E4F-A087-442E-ABD4-BCD2A1F0B0FE}.Debug|x64.Build.0 = Debug|x64 + {59104E4F-A087-442E-ABD4-BCD2A1F0B0FE}.Debug|x86.ActiveCfg = Debug|Win32 + {59104E4F-A087-442E-ABD4-BCD2A1F0B0FE}.Debug|x86.Build.0 = Debug|Win32 + {59104E4F-A087-442E-ABD4-BCD2A1F0B0FE}.Release|ARM.ActiveCfg = Release|ARM + {59104E4F-A087-442E-ABD4-BCD2A1F0B0FE}.Release|ARM.Build.0 = Release|ARM + {59104E4F-A087-442E-ABD4-BCD2A1F0B0FE}.Release|x64.ActiveCfg = Release|x64 + {59104E4F-A087-442E-ABD4-BCD2A1F0B0FE}.Release|x64.Build.0 = Release|x64 + {59104E4F-A087-442E-ABD4-BCD2A1F0B0FE}.Release|x86.ActiveCfg = Release|Win32 + {59104E4F-A087-442E-ABD4-BCD2A1F0B0FE}.Release|x86.Build.0 = Release|Win32 + {2B04DE79-4D33-4405-AC01-C89E0593A71D}.Debug|ARM.ActiveCfg = Debug|ARM + {2B04DE79-4D33-4405-AC01-C89E0593A71D}.Debug|ARM.Build.0 = Debug|ARM + {2B04DE79-4D33-4405-AC01-C89E0593A71D}.Debug|x64.ActiveCfg = Debug|x64 + {2B04DE79-4D33-4405-AC01-C89E0593A71D}.Debug|x64.Build.0 = Debug|x64 + {2B04DE79-4D33-4405-AC01-C89E0593A71D}.Debug|x86.ActiveCfg = Debug|Win32 + {2B04DE79-4D33-4405-AC01-C89E0593A71D}.Debug|x86.Build.0 = Debug|Win32 + {2B04DE79-4D33-4405-AC01-C89E0593A71D}.Release|ARM.ActiveCfg = Release|ARM + {2B04DE79-4D33-4405-AC01-C89E0593A71D}.Release|ARM.Build.0 = Release|ARM + {2B04DE79-4D33-4405-AC01-C89E0593A71D}.Release|x64.ActiveCfg = Release|x64 + {2B04DE79-4D33-4405-AC01-C89E0593A71D}.Release|x64.Build.0 = Release|x64 + {2B04DE79-4D33-4405-AC01-C89E0593A71D}.Release|x86.ActiveCfg = Release|Win32 + {2B04DE79-4D33-4405-AC01-C89E0593A71D}.Release|x86.Build.0 = Release|Win32 + {88768DD9-5110-4AC8-8B0E-41CD7713E1A2}.Debug|ARM.ActiveCfg = Debug|ARM + {88768DD9-5110-4AC8-8B0E-41CD7713E1A2}.Debug|ARM.Build.0 = Debug|ARM + {88768DD9-5110-4AC8-8B0E-41CD7713E1A2}.Debug|x64.ActiveCfg = Debug|x64 + {88768DD9-5110-4AC8-8B0E-41CD7713E1A2}.Debug|x64.Build.0 = Debug|x64 + {88768DD9-5110-4AC8-8B0E-41CD7713E1A2}.Debug|x86.ActiveCfg = Debug|Win32 + {88768DD9-5110-4AC8-8B0E-41CD7713E1A2}.Debug|x86.Build.0 = Debug|Win32 + {88768DD9-5110-4AC8-8B0E-41CD7713E1A2}.Release|ARM.ActiveCfg = Release|ARM + {88768DD9-5110-4AC8-8B0E-41CD7713E1A2}.Release|ARM.Build.0 = Release|ARM + {88768DD9-5110-4AC8-8B0E-41CD7713E1A2}.Release|x64.ActiveCfg = Release|x64 + {88768DD9-5110-4AC8-8B0E-41CD7713E1A2}.Release|x64.Build.0 = Release|x64 + {88768DD9-5110-4AC8-8B0E-41CD7713E1A2}.Release|x86.ActiveCfg = Release|Win32 + {88768DD9-5110-4AC8-8B0E-41CD7713E1A2}.Release|x86.Build.0 = Release|Win32 + {971DD379-1C2D-44D2-9285-FDA556C48176}.Debug|ARM.ActiveCfg = Debug|ARM + {971DD379-1C2D-44D2-9285-FDA556C48176}.Debug|ARM.Build.0 = Debug|ARM + {971DD379-1C2D-44D2-9285-FDA556C48176}.Debug|x64.ActiveCfg = Debug|x64 + {971DD379-1C2D-44D2-9285-FDA556C48176}.Debug|x64.Build.0 = Debug|x64 + {971DD379-1C2D-44D2-9285-FDA556C48176}.Debug|x86.ActiveCfg = Debug|Win32 + {971DD379-1C2D-44D2-9285-FDA556C48176}.Debug|x86.Build.0 = Debug|Win32 + {971DD379-1C2D-44D2-9285-FDA556C48176}.Release|ARM.ActiveCfg = Release|ARM + {971DD379-1C2D-44D2-9285-FDA556C48176}.Release|ARM.Build.0 = Release|ARM + {971DD379-1C2D-44D2-9285-FDA556C48176}.Release|x64.ActiveCfg = Release|x64 + {971DD379-1C2D-44D2-9285-FDA556C48176}.Release|x64.Build.0 = Release|x64 + {971DD379-1C2D-44D2-9285-FDA556C48176}.Release|x86.ActiveCfg = Release|Win32 + {971DD379-1C2D-44D2-9285-FDA556C48176}.Release|x86.Build.0 = Release|Win32 + {104BF91B-8314-4328-A996-90B8DF6052AF}.Debug|ARM.ActiveCfg = Debug|ARM + {104BF91B-8314-4328-A996-90B8DF6052AF}.Debug|ARM.Build.0 = Debug|ARM + {104BF91B-8314-4328-A996-90B8DF6052AF}.Debug|x64.ActiveCfg = Debug|x64 + {104BF91B-8314-4328-A996-90B8DF6052AF}.Debug|x64.Build.0 = Debug|x64 + {104BF91B-8314-4328-A996-90B8DF6052AF}.Debug|x86.ActiveCfg = Debug|Win32 + {104BF91B-8314-4328-A996-90B8DF6052AF}.Debug|x86.Build.0 = Debug|Win32 + {104BF91B-8314-4328-A996-90B8DF6052AF}.Release|ARM.ActiveCfg = Release|ARM + {104BF91B-8314-4328-A996-90B8DF6052AF}.Release|ARM.Build.0 = Release|ARM + {104BF91B-8314-4328-A996-90B8DF6052AF}.Release|x64.ActiveCfg = Release|x64 + {104BF91B-8314-4328-A996-90B8DF6052AF}.Release|x64.Build.0 = Release|x64 + {104BF91B-8314-4328-A996-90B8DF6052AF}.Release|x86.ActiveCfg = Release|Win32 + {104BF91B-8314-4328-A996-90B8DF6052AF}.Release|x86.Build.0 = Release|Win32 + {81AF1025-E0EE-4AD6-988D-2EF162778693}.Debug|ARM.ActiveCfg = Debug|ARM + {81AF1025-E0EE-4AD6-988D-2EF162778693}.Debug|ARM.Build.0 = Debug|ARM + {81AF1025-E0EE-4AD6-988D-2EF162778693}.Debug|x64.ActiveCfg = Debug|x64 + {81AF1025-E0EE-4AD6-988D-2EF162778693}.Debug|x64.Build.0 = Debug|x64 + {81AF1025-E0EE-4AD6-988D-2EF162778693}.Debug|x86.ActiveCfg = Debug|Win32 + {81AF1025-E0EE-4AD6-988D-2EF162778693}.Debug|x86.Build.0 = Debug|Win32 + {81AF1025-E0EE-4AD6-988D-2EF162778693}.Release|ARM.ActiveCfg = Release|ARM + {81AF1025-E0EE-4AD6-988D-2EF162778693}.Release|ARM.Build.0 = Release|ARM + {81AF1025-E0EE-4AD6-988D-2EF162778693}.Release|x64.ActiveCfg = Release|x64 + {81AF1025-E0EE-4AD6-988D-2EF162778693}.Release|x64.Build.0 = Release|x64 + {81AF1025-E0EE-4AD6-988D-2EF162778693}.Release|x86.ActiveCfg = Release|Win32 + {81AF1025-E0EE-4AD6-988D-2EF162778693}.Release|x86.Build.0 = Release|Win32 + {45C7723D-3107-4906-9633-F43ABE8A7147}.Debug|ARM.ActiveCfg = Debug|ARM + {45C7723D-3107-4906-9633-F43ABE8A7147}.Debug|ARM.Build.0 = Debug|ARM + {45C7723D-3107-4906-9633-F43ABE8A7147}.Debug|x64.ActiveCfg = Debug|x64 + {45C7723D-3107-4906-9633-F43ABE8A7147}.Debug|x64.Build.0 = Debug|x64 + {45C7723D-3107-4906-9633-F43ABE8A7147}.Debug|x86.ActiveCfg = Debug|Win32 + {45C7723D-3107-4906-9633-F43ABE8A7147}.Debug|x86.Build.0 = Debug|Win32 + {45C7723D-3107-4906-9633-F43ABE8A7147}.Release|ARM.ActiveCfg = Release|ARM + {45C7723D-3107-4906-9633-F43ABE8A7147}.Release|ARM.Build.0 = Release|ARM + {45C7723D-3107-4906-9633-F43ABE8A7147}.Release|x64.ActiveCfg = Release|x64 + {45C7723D-3107-4906-9633-F43ABE8A7147}.Release|x64.Build.0 = Release|x64 + {45C7723D-3107-4906-9633-F43ABE8A7147}.Release|x86.ActiveCfg = Release|Win32 + {45C7723D-3107-4906-9633-F43ABE8A7147}.Release|x86.Build.0 = Release|Win32 + {EF1103C7-8AAC-464B-BA31-86B87246FA72}.Debug|ARM.ActiveCfg = Debug|ARM + {EF1103C7-8AAC-464B-BA31-86B87246FA72}.Debug|ARM.Build.0 = Debug|ARM + {EF1103C7-8AAC-464B-BA31-86B87246FA72}.Debug|x64.ActiveCfg = Debug|x64 + {EF1103C7-8AAC-464B-BA31-86B87246FA72}.Debug|x64.Build.0 = Debug|x64 + {EF1103C7-8AAC-464B-BA31-86B87246FA72}.Debug|x86.ActiveCfg = Debug|Win32 + {EF1103C7-8AAC-464B-BA31-86B87246FA72}.Debug|x86.Build.0 = Debug|Win32 + {EF1103C7-8AAC-464B-BA31-86B87246FA72}.Release|ARM.ActiveCfg = Release|ARM + {EF1103C7-8AAC-464B-BA31-86B87246FA72}.Release|ARM.Build.0 = Release|ARM + {EF1103C7-8AAC-464B-BA31-86B87246FA72}.Release|x64.ActiveCfg = Release|x64 + {EF1103C7-8AAC-464B-BA31-86B87246FA72}.Release|x64.Build.0 = Release|x64 + {EF1103C7-8AAC-464B-BA31-86B87246FA72}.Release|x86.ActiveCfg = Release|Win32 + {EF1103C7-8AAC-464B-BA31-86B87246FA72}.Release|x86.Build.0 = Release|Win32 + {B6CDF482-7DA3-43D4-9B12-70150106C191}.Debug|ARM.ActiveCfg = Debug|ARM + {B6CDF482-7DA3-43D4-9B12-70150106C191}.Debug|ARM.Build.0 = Debug|ARM + {B6CDF482-7DA3-43D4-9B12-70150106C191}.Debug|x64.ActiveCfg = Debug|x64 + {B6CDF482-7DA3-43D4-9B12-70150106C191}.Debug|x64.Build.0 = Debug|x64 + {B6CDF482-7DA3-43D4-9B12-70150106C191}.Debug|x86.ActiveCfg = Debug|Win32 + {B6CDF482-7DA3-43D4-9B12-70150106C191}.Debug|x86.Build.0 = Debug|Win32 + {B6CDF482-7DA3-43D4-9B12-70150106C191}.Release|ARM.ActiveCfg = Release|ARM + {B6CDF482-7DA3-43D4-9B12-70150106C191}.Release|ARM.Build.0 = Release|ARM + {B6CDF482-7DA3-43D4-9B12-70150106C191}.Release|x64.ActiveCfg = Release|x64 + {B6CDF482-7DA3-43D4-9B12-70150106C191}.Release|x64.Build.0 = Release|x64 + {B6CDF482-7DA3-43D4-9B12-70150106C191}.Release|x86.ActiveCfg = Release|Win32 + {B6CDF482-7DA3-43D4-9B12-70150106C191}.Release|x86.Build.0 = Release|Win32 + {01CCCCC9-CA0C-4528-92BC-5B8BE1D02D6D}.Debug|ARM.ActiveCfg = Debug|ARM + {01CCCCC9-CA0C-4528-92BC-5B8BE1D02D6D}.Debug|ARM.Build.0 = Debug|ARM + {01CCCCC9-CA0C-4528-92BC-5B8BE1D02D6D}.Debug|x64.ActiveCfg = Debug|x64 + {01CCCCC9-CA0C-4528-92BC-5B8BE1D02D6D}.Debug|x64.Build.0 = Debug|x64 + {01CCCCC9-CA0C-4528-92BC-5B8BE1D02D6D}.Debug|x86.ActiveCfg = Debug|Win32 + {01CCCCC9-CA0C-4528-92BC-5B8BE1D02D6D}.Debug|x86.Build.0 = Debug|Win32 + {01CCCCC9-CA0C-4528-92BC-5B8BE1D02D6D}.Release|ARM.ActiveCfg = Release|ARM + {01CCCCC9-CA0C-4528-92BC-5B8BE1D02D6D}.Release|ARM.Build.0 = Release|ARM + {01CCCCC9-CA0C-4528-92BC-5B8BE1D02D6D}.Release|x64.ActiveCfg = Release|x64 + {01CCCCC9-CA0C-4528-92BC-5B8BE1D02D6D}.Release|x64.Build.0 = Release|x64 + {01CCCCC9-CA0C-4528-92BC-5B8BE1D02D6D}.Release|x86.ActiveCfg = Release|Win32 + {01CCCCC9-CA0C-4528-92BC-5B8BE1D02D6D}.Release|x86.Build.0 = Release|Win32 + {A34F450D-392D-4660-9618-810BD695B3B0}.Debug|ARM.ActiveCfg = Debug|ARM + {A34F450D-392D-4660-9618-810BD695B3B0}.Debug|ARM.Build.0 = Debug|ARM + {A34F450D-392D-4660-9618-810BD695B3B0}.Debug|x64.ActiveCfg = Debug|x64 + {A34F450D-392D-4660-9618-810BD695B3B0}.Debug|x64.Build.0 = Debug|x64 + {A34F450D-392D-4660-9618-810BD695B3B0}.Debug|x86.ActiveCfg = Debug|Win32 + {A34F450D-392D-4660-9618-810BD695B3B0}.Debug|x86.Build.0 = Debug|Win32 + {A34F450D-392D-4660-9618-810BD695B3B0}.Release|ARM.ActiveCfg = Release|ARM + {A34F450D-392D-4660-9618-810BD695B3B0}.Release|ARM.Build.0 = Release|ARM + {A34F450D-392D-4660-9618-810BD695B3B0}.Release|x64.ActiveCfg = Release|x64 + {A34F450D-392D-4660-9618-810BD695B3B0}.Release|x64.Build.0 = Release|x64 + {A34F450D-392D-4660-9618-810BD695B3B0}.Release|x86.ActiveCfg = Release|Win32 + {A34F450D-392D-4660-9618-810BD695B3B0}.Release|x86.Build.0 = Release|Win32 + {74CAD9D0-D8AE-4896-B71B-B2D9B48F30AA}.Debug|ARM.ActiveCfg = Debug|ARM + {74CAD9D0-D8AE-4896-B71B-B2D9B48F30AA}.Debug|ARM.Build.0 = Debug|ARM + {74CAD9D0-D8AE-4896-B71B-B2D9B48F30AA}.Debug|x64.ActiveCfg = Debug|x64 + {74CAD9D0-D8AE-4896-B71B-B2D9B48F30AA}.Debug|x64.Build.0 = Debug|x64 + {74CAD9D0-D8AE-4896-B71B-B2D9B48F30AA}.Debug|x86.ActiveCfg = Debug|Win32 + {74CAD9D0-D8AE-4896-B71B-B2D9B48F30AA}.Debug|x86.Build.0 = Debug|Win32 + {74CAD9D0-D8AE-4896-B71B-B2D9B48F30AA}.Release|ARM.ActiveCfg = Release|ARM + {74CAD9D0-D8AE-4896-B71B-B2D9B48F30AA}.Release|ARM.Build.0 = Release|ARM + {74CAD9D0-D8AE-4896-B71B-B2D9B48F30AA}.Release|x64.ActiveCfg = Release|x64 + {74CAD9D0-D8AE-4896-B71B-B2D9B48F30AA}.Release|x64.Build.0 = Release|x64 + {74CAD9D0-D8AE-4896-B71B-B2D9B48F30AA}.Release|x86.ActiveCfg = Release|Win32 + {74CAD9D0-D8AE-4896-B71B-B2D9B48F30AA}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/build/windows10/liblinphone/liblinphone.vcxproj b/build/windows10/liblinphone/liblinphone.vcxproj new file mode 100644 index 000000000..b5922519b --- /dev/null +++ b/build/windows10/liblinphone/liblinphone.vcxproj @@ -0,0 +1,192 @@ + + + + + Debug + ARM + + + Debug + Win32 + + + Debug + x64 + + + Release + ARM + + + Release + Win32 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {b6cdf482-7da3-43d4-9b12-70150106c191} + + + {74cad9d0-d8ae-4896-b71b-b2d9b48f30aa} + + + {2b04de79-4d33-4405-ac01-c89e0593a71d} + + + {a34f450d-392d-4660-9618-810bd695b3b0} + + + {88e3c241-eb6f-4c84-80dc-89b8961daf80} + + + {2e56b851-9d8d-40e5-84bb-e4ee63b71d25} + + + + {c7139899-d8bc-48a3-a437-6844a8baabef} + DynamicLibrary + liblinphone + liblinphone + en-US + 14.0 + true + Windows Store + 10 + 10.0.10240.0 + 10.0.10069.0 + + + + DynamicLibrary + true + v140 + + + DynamicLibrary + false + true + v140 + + + + + + + + + + + + false + false + $(SolutionDir)$(Platform)\$(Configuration)\ + + + + NotUsing + false + $(SolutionDir)$(Platform)\$(Configuration)\include;$(ProjectDir)..\..\..\include;$(ProjectDir)..\..\..\coreapi;$(ProjectDir)..\..\..\mediastreamer2\include;$(ProjectDir)..\..\..\..\belle-sip\include;$(ProjectDir)..\..\..\oRTP\include;$(ProjectDir)..\..\..\..\sqlite;$(ProjectDir)..\..\..\..\zlib;%(AdditionalIncludeDirectories) + HAVE_CONFIG_H;HAVE_ZLIB;MSG_STORAGE_ENABLED;VIDEO_ENABLED;IN_LINPHONE;LINPHONE_PLUGINS_DIR="\\linphone\\plugins";_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions) + 4996 + + + Console + false + false + + + version.bat + + + Batch script to get the git version + + + + + + \ No newline at end of file diff --git a/build/windows10/liblinphone/version.bat b/build/windows10/liblinphone/version.bat new file mode 100644 index 000000000..c015636e2 --- /dev/null +++ b/build/windows10/liblinphone/version.bat @@ -0,0 +1,22 @@ +@ECHO off + +SET gitlog= +FOR /f "delims=" %%a IN ('git log -1 "--pretty=format:%%H" ../../../configure.ac') DO SET gitlog=%%a + +IF [%gitlog%] == [] GOTO UnknownGitVersion + +FOR /f "delims=" %%a IN ('git describe --always') DO SET gitdescribe=%%a +GOTO End + +:UnknownGitVersion +SET gitdescribe=unknown + +:End +ECHO #define LIBLINPHONE_GIT_VERSION "%gitdescribe%" > liblinphone_gitversion.h + + +FOR /F "delims=" %%a IN ('findstr /B AC_INIT ..\..\..\configure.ac') DO ( + FOR /F "tokens=1,2,3 delims=[,]" %%1 IN ("%%a") DO ( + ECHO #define LIBLINPHONE_VERSION "%%3" > config.h + ) +) diff --git a/build/wp8/LibLinphone.vcxproj b/build/wp8/LibLinphone.vcxproj index 282d99c2b..3d1ecf83a 100644 --- a/build/wp8/LibLinphone.vcxproj +++ b/build/wp8/LibLinphone.vcxproj @@ -96,6 +96,7 @@ + @@ -144,6 +145,7 @@ + diff --git a/cmake/FindGtkMacIntegration.cmake b/cmake/FindGtkMacIntegration.cmake new file mode 100644 index 000000000..1c3069c3e --- /dev/null +++ b/cmake/FindGtkMacIntegration.cmake @@ -0,0 +1,54 @@ +############################################################################ +# FindGtkMacIntegration.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 libgtkmacintegration include file and library +# +# GTKMACINTEGRATION_FOUND - system has libgtkmacintegration +# GTKMACINTEGRATION_INCLUDE_DIRS - the libgtkmacintegration include directory +# GTKMACINTEGRATION_LIBRARIES - The libraries needed to use libgtkmacintegration +# GTKMACINTEGRATION_CPPFLAGS - The cflags needed to use libgtkmacintegration + +set(_GTKMACINTEGRATION_ROOT_PATHS + ${CMAKE_INSTALL_PREFIX} +) + +find_path(GTKMACINTEGRATION_INCLUDE_DIRS + NAMES gtkosxapplication.h + HINTS _GTKMACINTEGRATION_ROOT_PATHS + PATH_SUFFIXES include/gtkmacintegration-gtk2 include/gtkmacintegration +) + +find_library(GTKMACINTEGRATION_LIBRARIES + NAMES gtkmacintegration-gtk2 gtkmacintegration + HINTS ${_GTKMACINTEGRATION_ROOT_PATHS} + PATH_SUFFIXES bin lib +) + +set(GTKMACINTEGRATION_CPPFLAGS "-DMAC_INTEGRATION") + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(GTKMACINTEGRATION + DEFAULT_MSG + GTKMACINTEGRATION_INCLUDE_DIRS GTKMACINTEGRATION_LIBRARIES GTKMACINTEGRATION_CPPFLAGS +) + +mark_as_advanced(GTKMACINTEGRATION_INCLUDE_DIRS GTKMACINTEGRATION_LIBRARIES GTKMACINTEGRATION_CPPFLAGS) diff --git a/cmake/FindSoup.cmake b/cmake/FindSoup.cmake deleted file mode 100644 index 3aeffaefa..000000000 --- a/cmake/FindSoup.cmake +++ /dev/null @@ -1,65 +0,0 @@ -############################################################################ -# FindSoup.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 soup include file and library -# -# SOUP_FOUND - system has libsoup -# 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 - ${CMAKE_INSTALL_PREFIX} -) - -find_path(SOUP_INCLUDE_DIRS - NAMES libsoup/soup.h - HINTS _SOUP_ROOT_PATHS - PATH_SUFFIXES include/libsoup-2.4 -) - -if(SOUP_INCLUDE_DIRS) - set(HAVE_LIBSOUP_SOUP_H 1) - list(APPEND SOUP_INCLUDE_DIRS ${GTK2_INCLUDE_DIRS}) -endif() - -find_library(SOUP_LIBRARIES - NAMES soup-2.4 - HINTS ${_SOUP_ROOT_PATHS} - PATH_SUFFIXES bin lib -) - -if(SOUP_LIBRARIES) - list(APPEND SOUP_LIBRARIES ${GTK2_LIBRARIES}) -endif() - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(Soup - DEFAULT_MSG - SOUP_INCLUDE_DIRS SOUP_LIBRARIES HAVE_LIBSOUP_SOUP_H -) - -mark_as_advanced(SOUP_INCLUDE_DIRS SOUP_LIBRARIES HAVE_LIBSOUP_SOUP_H) diff --git a/cmake/FindZlib.cmake b/cmake/FindZlib.cmake index 86ebf913f..17b2d1e39 100644 --- a/cmake/FindZlib.cmake +++ b/cmake/FindZlib.cmake @@ -41,8 +41,13 @@ if(ZLIB_INCLUDE_DIRS) endif() if(ENABLE_STATIC) + if(IOS OR QNX) + set(_ZLIB_STATIC_NAMES z) + else() + set(_ZLIB_STATIC_NAMES zstatic zlibstatic zlibstaticd) + endif() find_library(ZLIB_LIBRARIES - NAMES zstatic zlibstatic zlibstaticd + NAMES ${_ZLIB_STATIC_NAMES} HINTS ${_ZLIB_ROOT_PATHS} PATH_SUFFIXES bin lib ) diff --git a/cmake/LinphoneConfig.cmake.in b/cmake/LinphoneConfig.cmake.in index d7aa6cc22..9bcd9dfa4 100644 --- a/cmake/LinphoneConfig.cmake.in +++ b/cmake/LinphoneConfig.cmake.in @@ -29,7 +29,10 @@ # 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") +if(NOT LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS) + include("${CMAKE_CURRENT_LIST_DIR}/LinphoneTargets.cmake") +endif() + find_package(Mediastreamer2 REQUIRED) find_package(BelleSIP REQUIRED) if(@ENABLE_TUNNEL@) @@ -38,7 +41,7 @@ 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_LIBRARIES 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}) diff --git a/config.h.cmake b/config.h.cmake index 3adb3cae4..3685d7eee 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -38,7 +38,11 @@ #define PACKAGE_SOUND_DIR "${PACKAGE_SOUND_DIR}" #cmakedefine BUILD_WIZARD +#cmakedefine HAVE_GTK_OSX 1 #cmakedefine HAVE_NOTIFY4 #cmakedefine HAVE_ZLIB 1 #cmakedefine HAVE_CU_GET_SUITE 1 #cmakedefine HAVE_CU_CURSES 1 +#cmakedefine HAVE_LIBUDEV_H 0 +#cmakedefine HAVE_LIME +#cmakedefine ENABLE_NLS 1 diff --git a/configure.ac b/configure.ac index 1d7fa01ef..ffd399813 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.8.2-linphone-daemon],[linphone-developers@nongnu.org]) +AC_INIT([linphone],[3.9.1-linphone-daemon],[linphone-developers@nongnu.org]) AC_CANONICAL_SYSTEM AC_CONFIG_SRCDIR([coreapi/linphonecore.c]) @@ -17,7 +17,7 @@ if test "$LINPHONE_EXTRA_VERSION" != "" ;then LINPHONE_VERSION=$LINPHONE_VERSION.${LINPHONE_EXTRA_VERSION} fi -LIBLINPHONE_SO_CURRENT=7 dnl increment this number when you add/change/remove an interface +LIBLINPHONE_SO_CURRENT=8 dnl increment this number when you add/change/remove an interface LIBLINPHONE_SO_REVISION=0 dnl increment this number when you change source code, without changing interfaces; set to 0 when incrementing CURRENT LIBLINPHONE_SO_AGE=0 dnl increment this number when you add an interface, set to 0 if you remove an interface @@ -132,7 +132,7 @@ AC_CONFIG_COMMANDS([libtool-hacking], dnl Add the languages which your application supports here. PKG_PROG_PKG_CONFIG -ALL_LINGUAS=$(cd po && echo *.po | sed 's/\.po//g') +ALL_LINGUAS=$(cd $srcdir/po && echo *.po | sed 's/\.po//g') AC_SUBST(ALL_LINGUAS) AC_DEFINE_UNQUOTED(LINPHONE_ALL_LANGS, "$ALL_LINGUAS", [All supported languages]) @@ -147,8 +147,7 @@ if test "$mingw_found" != "yes" ; then LIBS="$LIBS $LIBINTL" else if test "$USE_NLS" = "yes" ; then - AC_DEFINE(ENABLE_NLS,1,[Tells whether localisation is possible]) - AC_DEFINE(HAVE_GETTEXT,1,[Tells wheter localisation is possible]) + AC_DEFINE(HAVE_INTL,1,[Tells wheter localisation is possible]) LIBS="$LIBS -lintl" fi fi @@ -633,7 +632,7 @@ AC_ARG_ENABLE(zrtp, dnl this options are just for passing to mediastreamer2 subproject AC_ARG_ENABLE(dtls, - [AS_HELP_STRING([--enable-dtls], [Turn on dtls support - requires polarssl > 1.4])], + [AS_HELP_STRING([--enable-dtls], [Turn on srtp-dtls support - requires polarssl > 1.4])], [case "${enableval}" in yes) dtls=true ;; no) dtls=false ;; @@ -739,16 +738,6 @@ AC_ARG_ENABLE(assistant, [build_wizard=check] ) -dnl check libsoup (needed for wizard) -if test "$build_wizard" != "false" ; then - PKG_CHECK_MODULES(LIBSOUP, [libsoup-2.4 >= 2.26],[], - [if test "$build_wizard" = "true" ; then - AC_MSG_ERROR([Could not found libsoup, assistant cannot be compiled.]) - else - build_wizard=false - fi] - ) -fi if test "$build_wizard" != "false" ; then PKG_CHECK_MODULES(LIBGTKWIZARD, [gtk+-2.0 >= 2.22.0],[], [if test "$build_wizard" = "true" ; then @@ -758,8 +747,6 @@ if test "$build_wizard" != "false" ; then fi] ) fi -AC_SUBST(LIBSOUP_CFLAGS) -AC_SUBST(LIBSOUP_LIBS) AM_CONDITIONAL(BUILD_WIZARD, test x$build_wizard != xfalse) if test "$build_wizard" != "false" ; then build_wizard=true @@ -781,7 +768,7 @@ AC_ARG_ENABLE(strict, ) STRICT_OPTIONS="-Wall -Wuninitialized" -STRICT_OPTIONS_CC="-Wdeclaration-after-statement " +STRICT_OPTIONS_CC="-Wdeclaration-after-statement -Wstrict-prototypes" STRICT_OPTIONS_CXX="" #for clang @@ -804,7 +791,7 @@ case "$target_os" in ;; esac if test "$strictness" = "yes" ; then - STRICT_OPTIONS="$STRICT_OPTIONS -Werror" + STRICT_OPTIONS="$STRICT_OPTIONS -Werror -Wno-error=deprecated-declarations -Wno-error=strict-prototypes" CFLAGS="$CFLAGS -fno-strict-aliasing" fi @@ -907,7 +894,7 @@ if test x$enable_msg_storage != xfalse; then AC_CHECK_LIB(sqlite3, sqlite3_open, [SQLITE3_LIBS+=" -lsqlite3 "; found_sqlite=yes], [foo=bar]) fi if test "$found_sqlite" = "yes"; then - SQLITE3_CFLAGS+="-DMSG_STORAGE_ENABLED" + SQLITE3_CFLAGS+=" -DMSG_STORAGE_ENABLED" if test "$build_macos" = "yes" -o "$ios_found" = "yes"; then SQLITE3_LIBS+=" -liconv" fi @@ -925,6 +912,41 @@ fi AM_CONDITIONAL(BUILD_MSG_STORAGE, test x$enable_msg_storage = xtrue) +AC_ARG_ENABLE(call-logs-storage, + [AS_HELP_STRING([--enable-call-logs-storage=[yes/no]], [Turn on compilation of call logs storage (default=auto)])], + [case "${enableval}" in + yes) enable_call_logs_storage=true ;; + no) enable_call_logs_storage=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-call-logs-storage) ;; + esac], + [enable_call_logs_storage=auto] +) + +if test x$enable_call_logs_storage != xfalse; then + PKG_CHECK_MODULES(SQLITE3,[sqlite3 >= 3.6.0],[found_sqlite=yes],[found_sqlite=no]) + if test "$found_sqlite" = "no"; then + dnl Check the lib presence in case the PKG-CONFIG version is not found + AC_CHECK_LIB(sqlite3, sqlite3_open, [SQLITE3_LIBS+=" -lsqlite3 "; found_sqlite=yes], [foo=bar]) + fi + if test "$found_sqlite" = "yes"; then + SQLITE3_CFLAGS+=" -DCALL_LOGS_STORAGE_ENABLED" + if test "$build_macos" = "yes" -o "$ios_found" = "yes"; then + SQLITE3_LIBS+=" -liconv" + fi + enable_call_logs_storage=true + else + if test x$enable_call_logs_storage = xtrue; then + AC_MSG_ERROR([sqlite3, required for call logs storage, not found]) + fi + enable_call_logs_storage=false + fi + + AC_SUBST(SQLITE3_CFLAGS) + AC_SUBST(SQLITE3_LIBS) +fi + +AM_CONDITIONAL(BUILD_CALL_LOGS_STORAGE, test x$enable_call_logs_storage = xtrue) + PKG_CHECK_MODULES(BELLESIP, [belle-sip >= 1.4.0]) SIPSTACK_CFLAGS="$BELLESIP_CFLAGS" @@ -1019,12 +1041,12 @@ dnl ################################################## dnl # Check for doxygen dnl ################################################## -AC_ARG_ENABLE(doxygen, - [AS_HELP_STRING([--disable-documentation], [Disable documentation generation using doxygen (default=no)])], +AC_ARG_ENABLE(documentation, + [AS_HELP_STRING([--enable-documentation], [Documentation generation using doxygen (default=yes)])], [case "${enableval}" in yes) documentation_enabled=yes;; no) documentation_enabled=no;; - *) AC_MSG_ERROR("Bad value for --disable-documentation");; + *) AC_MSG_ERROR("Bad value for --enable-documentation");; esac], [documentation_enabled=yes] ) @@ -1035,6 +1057,11 @@ else fi AM_CONDITIONAL(HAVE_DOXYGEN, test "$DOXYGEN" != "false") +AC_PATH_PROG([SIPP],[sipp],[false]) +if test "x$SIPP" != "xfalse" ; then + AC_DEFINE(HAVE_SIPP,1,[defined when SIPP is available]) + AC_DEFINE_UNQUOTED(SIPP_COMMAND,"$SIPP",[defined when SIPP is available]) +fi AC_CONFIG_FILES([ Makefile @@ -1077,12 +1104,14 @@ printf "* %-30s %s\n" "Video support" $video printf "* %-30s %s\n" "GTK interface" $gtk_ui printf "* %-30s %s\n" "Account assistant" $build_wizard printf "* %-30s %s\n" "Console interface" $console_ui -printf "* %-30s %s\n" "Tools" $build_tools +printf "* %-30s %s\n" "Tools" $build_tools printf "* %-30s %s\n" "Message storage" $enable_msg_storage +printf "* %-30s %s\n" "Call logs storage" $enable_call_logs_storage printf "* %-30s %s\n" "IM encryption" $lime printf "* %-30s %s\n" "uPnP support" $build_upnp printf "* %-30s %s\n" "LDAP support" $enable_ldap printf "* %-30s %s\n" "ZLIB support" $found_zlib +printf "* %-30s %s\n" "Documentation" $documentation_enabled if test "$enable_tunnel" = "true" ; then printf "* %-30s %s\n" "Tunnel support" "true" diff --git a/console/CMakeLists.txt b/console/CMakeLists.txt index 328fdbcf2..4b7f4df24 100644 --- a/console/CMakeLists.txt +++ b/console/CMakeLists.txt @@ -29,6 +29,7 @@ set(LINPHONECSH_SOURCE_FILES shell.c ) +apply_compile_flags(LINPHONEC_SOURCE_FILES "CPP" "C") add_executable(linphonec ${LINPHONEC_SOURCE_FILES}) target_link_libraries(linphonec linphone) diff --git a/console/commands.c b/console/commands.c index d24bfa16b..f2c316325 100644 --- a/console/commands.c +++ b/console/commands.c @@ -564,7 +564,7 @@ lpc_cmd_call(LinphoneCore *lc, char *args) } { LinphoneCall *call; - LinphoneCallParams *cp=linphone_core_create_default_call_parameters (lc); + LinphoneCallParams *cp=linphone_core_create_call_params (lc, NULL); char *opt1,*opt2; if ( linphone_core_in_call(lc) ) { @@ -633,16 +633,16 @@ lpc_cmd_chat(LinphoneCore *lc, char *args) /* missing one parameter */ return 0; } - cr = linphone_core_create_chat_room(lc,arg1); + cr = linphone_core_get_chat_room_from_uri(lc,arg1); linphone_chat_room_send_message(cr,arg2); return 1; } -const char *linphonec_get_callee(){ +const char *linphonec_get_callee(void){ return callee_name; } -const char *linphonec_get_caller(){ +const char *linphonec_get_caller(void){ return caller_name; } @@ -2376,12 +2376,12 @@ static int lpc_cmd_rtp_no_xmit_on_audio_mute(LinphoneCore *lc, char *args) #ifdef VIDEO_ENABLED static int _lpc_cmd_video_window(LinphoneCore *lc, char *args, bool_t is_preview){ char subcommand[64]; - int a,b; + long a,b; int err; VideoParams *params=is_preview ? &lpc_preview_params : &lpc_video_params; if (!args) return 0; - err=sscanf(args,"%63s %i %i",subcommand,&a,&b); + err=sscanf(args,"%63s %ld %ld",subcommand,&a,&b); if (err>=1){ if (strcmp(subcommand,"pos")==0){ if (err<3) return 0; @@ -2403,15 +2403,15 @@ static int _lpc_cmd_video_window(LinphoneCore *lc, char *args, bool_t is_preview if (is_preview) linphone_core_enable_video_preview (lc,FALSE); }else if (strcmp(subcommand,"id")==0){ if (err == 1){ - linphonec_out("vwindow id: 0x%x\n",is_preview ? linphone_core_get_native_preview_window_id (lc) : + linphonec_out("vwindow id: 0x%p\n",is_preview ? linphone_core_get_native_preview_window_id (lc) : linphone_core_get_native_video_window_id (lc)); return 1; } else if (err != 2) return 0; - params->wid=a; + params->wid=(void *)a; if (is_preview) - linphone_core_set_native_preview_window_id (lc,a); + linphone_core_set_native_preview_window_id(lc, (void *)a); else - linphone_core_set_native_video_window_id(lc,a); + linphone_core_set_native_video_window_id(lc, (void *)a); }else if (is_preview==TRUE){ if (strcmp(subcommand,"integrated")==0){ linphone_core_use_preview_window (lc,FALSE); diff --git a/console/linphonec.c b/console/linphonec.c index fb3c9d1ba..709940269 100644 --- a/console/linphonec.c +++ b/console/linphonec.c @@ -65,15 +65,6 @@ #endif /*_WIN32_WCE*/ -#ifdef HAVE_GETTEXT -#include -#ifndef _ -#define _(String) gettext(String) -#endif -#else -#define _(something) (something) -#endif - #ifndef PACKAGE_DIR #define PACKAGE_DIR "" #endif @@ -164,7 +155,7 @@ static char zrtpsecrets[PATH_MAX]; static char usr_certificates_path[PATH_MAX]; static const char *factory_configfile_name=NULL; static char *sip_addr_to_call = NULL; /* for autocall */ -static int window_id = 0; /* 0=standalone window, or window id for embedding video */ +static void *window_id = NULL; /* NULL=standalone window, or window id for embedding video */ #if !defined(_WIN32_WCE) static ortp_pipe_t client_sock=ORTP_PIPE_INVALID; #endif /*_WIN32_WCE*/ @@ -368,7 +359,7 @@ static void linphonec_call_state_changed(LinphoneCore *lc, LinphoneCall *call, L if ( auto_answer) { answer_call=TRUE; } else if (real_early_media_sending) { - LinphoneCallParams* callparams = linphone_core_create_default_call_parameters(lc); + LinphoneCallParams* callparams = linphone_core_create_call_params(lc, call); linphonec_out("Sending early media using real hardware\n"); linphone_call_params_enable_early_media_sending(callparams, TRUE); if (vcap_enabled) linphone_call_params_enable_video(callparams, TRUE); @@ -602,7 +593,7 @@ void linphonec_set_autoanswer(bool_t enabled){ auto_answer=enabled; } -bool_t linphonec_get_autoanswer(){ +bool_t linphonec_get_autoanswer(void){ return auto_answer; } @@ -714,16 +705,6 @@ linphonec_init(int argc, char **argv) default: break; } -#ifdef ENABLE_NLS - if (NULL == bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR)) - perror ("bindtextdomain failed"); -#ifndef __ARM__ - bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); -#endif - textdomain (GETTEXT_PACKAGE); -#else - printf ("NLS disabled.\n"); -#endif linphonec_parse_cmdline(argc, argv); @@ -759,9 +740,9 @@ linphonec_init(int argc, char **argv) linphone_core_set_user_certificates_path(linphonec,usr_certificates_path); linphone_core_enable_video_capture(linphonec, vcap_enabled); linphone_core_enable_video_display(linphonec, display_enabled); - if (display_enabled && window_id != 0) + if (display_enabled && (window_id != NULL)) { - printf("Setting window_id: 0x%x\n", window_id); + printf("Setting window_id: 0x%p\n", window_id); linphone_core_set_native_video_window_id(linphonec,window_id); } @@ -984,29 +965,30 @@ static void x11_apply_video_params(VideoParams *params, Window window){ #endif -static void lpc_apply_video_params(){ - static unsigned long old_wid=0,old_pwid=0; - unsigned long wid=linphone_core_get_native_video_window_id (linphonec); - unsigned long pwid=linphone_core_get_native_preview_window_id (linphonec); +static void lpc_apply_video_params(void){ + static void *old_wid=NULL; + static void *old_pwid=NULL; + void *wid=linphone_core_get_native_video_window_id(linphonec); + void *pwid=linphone_core_get_native_preview_window_id(linphonec); - if (wid!=0 && (lpc_video_params.refresh || old_wid!=wid)){ + if (wid!=NULL && (lpc_video_params.refresh || old_wid!=wid)){ lpc_video_params.refresh=FALSE; #ifdef HAVE_X11_XLIB_H if (lpc_video_params.wid==0){ // do not manage window if embedded - x11_apply_video_params(&lpc_video_params,wid); + x11_apply_video_params(&lpc_video_params,(Window)wid); } else { linphone_core_show_video(linphonec, lpc_video_params.show); } #endif } old_wid=wid; - if (pwid!=0 && (lpc_preview_params.refresh || old_pwid!=pwid)){ + if (pwid!=NULL && (lpc_preview_params.refresh || old_pwid!=pwid)){ lpc_preview_params.refresh=FALSE; #ifdef HAVE_X11_XLIB_H - /*printf("wid=%lu pwid=%lu\n",wid,pwid);*/ - if (lpc_preview_params.wid==0){ // do not manage window if embedded + /*printf("wid=%p pwid=%p\n",wid,pwid);*/ + if (lpc_preview_params.wid==NULL){ // do not manage window if embedded printf("Refreshing\n"); - x11_apply_video_params(&lpc_preview_params,pwid); + x11_apply_video_params(&lpc_preview_params,(Window)pwid); } #endif } @@ -1303,7 +1285,7 @@ linphonec_parse_cmdline(int argc, char **argv) arg_num++; if (arg_num < argc) { char *tmp; - window_id = strtol( argv[arg_num], &tmp, 0 ); + window_id = (void *)strtol( argv[arg_num], &tmp, 0 ); lpc_video_params.wid = window_id; } } diff --git a/console/linphonec.h b/console/linphonec.h index 3265d42ac..975fcee90 100644 --- a/console/linphonec.h +++ b/console/linphonec.h @@ -99,7 +99,7 @@ typedef struct { typedef struct { int x,y,w,h; - unsigned long wid; + void *wid; bool_t show; bool_t refresh; } VideoParams; @@ -116,11 +116,11 @@ extern VideoParams lpc_preview_params; extern int linphonec_parse_command_line(LinphoneCore *lc, char *cl); extern char *linphonec_command_generator(const char *text, int state); -void linphonec_main_loop_exit(); +void linphonec_main_loop_exit(void); extern void linphonec_finish(int exit_status); extern char *linphonec_readline(char *prompt); void linphonec_set_autoanswer(bool_t enabled); -bool_t linphonec_get_autoanswer(); +bool_t linphonec_get_autoanswer(void); void linphonec_command_finished(void); void linphonec_set_caller(const char *caller); LinphoneCall *linphonec_get_call(long id); diff --git a/coreapi/CMakeLists.txt b/coreapi/CMakeLists.txt index b8b6b27cb..2f2d59712 100644 --- a/coreapi/CMakeLists.txt +++ b/coreapi/CMakeLists.txt @@ -20,17 +20,38 @@ # ############################################################################ -if(MSVC AND NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "WindowsPhone") +if(MSVC AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone") find_library(LIBGCC NAMES gcc) find_library(LIBMINGWEX NAMES mingwex) endif() if(NOT WIN32) - find_package(Iconv) + find_package(Iconv QUIET) endif() -set(SOURCE_FILES +set(LINPHONE_HEADER_FILES + account_creator.h + buffer.h + call_log.h + call_params.h + content.h + event.h + linphonecore.h + linphonecore_utils.h + linphonefriend.h + linphonepresence.h + linphone_proxy_config.h + linphone_tunnel.h + lpc2xml.h + lpconfig.h + sipsetup.h + xml2lpc.h + xmlrpc.h +) + +set(LINPHONE_SOURCE_FILES_C + account_creator.c address.c authentication.c bellesip_sal/sal_address_impl.c @@ -51,6 +72,7 @@ set(SOURCE_FILES call_log.c call_params.c chat.c + chat_file_transfer.c conference.c contactprovider.c content.c @@ -59,19 +81,15 @@ set(SOURCE_FILES enum.c enum.h event.c - event.h friend.c info.c ldap/ldapprovider.c lime.c linphonecall.c linphonecore.c - linphonecore.h - linphonecore_utils.h - linphonefriend.h linphone_tunnel_config.c - linphone_tunnel.h localplayer.c + lpc2xml.c lpconfig.c lpconfig.h lsd.c @@ -88,38 +106,37 @@ set(SOURCE_FILES sal.c siplogin.c sipsetup.c - sipsetup.h xml2lpc.c - xml2lpc.h xml.c + xmlrpc.c vtables.c ) +set(LINPHONE_SOURCE_FILES_CXX ) + if(ENABLE_TUNNEL) - list(APPEND SOURCE_FILES + list(APPEND LINPHONE_SOURCE_FILES_CXX linphone_tunnel.cc TunnelManager.cc ) add_definitions(-DTUNNEL_ENABLED) else() - list(APPEND SOURCE_FILES linphone_tunnel_stubs.c) -endif() -if(ENABLE_ASSISTANT) - list(APPEND SOURCE_FILES sipwizard.c) + list(APPEND LINPHONE_SOURCE_FILES_C linphone_tunnel_stubs.c) endif() -set(GENERATED_SOURCE_FILES - ${CMAKE_CURRENT_BINARY_DIR}/liblinphone_gitversion.h -) -set_source_files_properties(${GENERATED_SOURCE_FILES} PROPERTIES GENERATED TRUE) find_package(Git) -add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/liblinphone_gitversion.h - COMMAND ${CMAKE_COMMAND} -DGIT_EXECUTABLE=${GIT_EXECUTABLE} -DWORK_DIR=${CMAKE_CURRENT_SOURCE_DIR} -DOUTPUT_DIR=${CMAKE_CURRENT_BINARY_DIR} -P ${CMAKE_CURRENT_SOURCE_DIR}/gitversion.cmake) +add_custom_target(liblinphone-git-version + COMMAND ${CMAKE_COMMAND} -DGIT_EXECUTABLE=${GIT_EXECUTABLE} -DWORK_DIR=${CMAKE_CURRENT_SOURCE_DIR} -DOUTPUT_DIR=${CMAKE_CURRENT_BINARY_DIR} -P ${CMAKE_CURRENT_SOURCE_DIR}/gitversion.cmake + BYPRODUCTS "${CMAKE_CURRENT_BINARY_DIR}/liblinphone_gitversion.h" +) add_definitions( -DUSE_BELLESIP -DLIBLINPHONE_EXPORTS ) +apply_compile_flags(LINPHONE_SOURCE_FILES_C "CPP" "C") +apply_compile_flags(LINPHONE_SOURCE_FILES_CXX "CPP" "CXX") + set(LIBS ${BELLESIP_LIBRARIES} ${MEDIASTREAMER2_LIBRARIES} @@ -137,21 +154,21 @@ endif() if(ENABLE_TUNNEL) list(APPEND LIBS ${TUNNEL_LIBRARIES}) endif() -if(ENABLE_ASSISTANT) - list(APPEND LIBS ${SOUP_LIBRARIES}) -endif() -if(MSVC AND NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "WindowsPhone") +if(MSVC AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone") list(APPEND LIBS ${LIBGCC} ${LIBMINGWEX}) endif() -if(WIN32 AND NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "WindowsPhone") +if(WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone") list(APPEND LIBS shlwapi) endif() +if(INTL_FOUND) + list(APPEND LIBS ${INTL_LIBRARIES}) +endif() if(ENABLE_STATIC) - add_library(linphone STATIC ${SOURCE_FILES} ${GENERATED_SOURCE_FILES}) + add_library(linphone STATIC ${LINPHONE_HEADER_FILES} ${LINPHONE_SOURCE_FILES_C} ${LINPHONE_SOURCE_FILES_CXX}) target_link_libraries(linphone ${LIBS}) else() - add_library(linphone SHARED ${SOURCE_FILES} ${GENERATED_SOURCE_FILES}) + add_library(linphone SHARED ${LINPHONE_HEADER_FILES} ${LINPHONE_SOURCE_FILES_C} ${LINPHONE_SOURCE_FILES_CXX}) set_target_properties(linphone PROPERTIES VERSION ${LINPHONE_SO_VERSION} LINKER_LANGUAGE CXX) target_link_libraries(linphone ${LIBS}) if(MSVC) @@ -163,7 +180,8 @@ else() endif() endif() endif() -if(WIN32 AND "${CMAKE_SYSTEM_NAME}" STREQUAL "WindowsPhone") +add_dependencies(linphone liblinphone-git-version) +if(WIN32 AND CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone") set_target_properties(linphone PROPERTIES PREFIX "lib") endif() if(ICONV_FOUND) @@ -175,32 +193,14 @@ if(ICONV_FOUND) endif() endif() -install(TARGETS linphone EXPORT LinphoneTargets +install(TARGETS linphone EXPORT ${EXPORT_TARGETS_NAME}Targets RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE ) - -set(HEADER_FILES - buffer.h - call_log.h - call_params.h - content.h - event.h - linphonecore.h - linphonecore_utils.h - linphonefriend.h - linphonepresence.h - linphone_tunnel.h - lpc2xml.h - lpconfig.h - sipsetup.h - xml2lpc.h -) - -install(FILES ${HEADER_FILES} +install(FILES ${LINPHONE_HEADER_FILES} DESTINATION include/linphone PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ ) diff --git a/coreapi/Makefile.am b/coreapi/Makefile.am index 8582213c5..02c7f442d 100644 --- a/coreapi/Makefile.am +++ b/coreapi/Makefile.am @@ -25,6 +25,7 @@ CLEANFILES=$(GITVERSION_FILE) linphone_includedir=$(includedir)/linphone linphone_include_HEADERS=\ + account_creator.h \ buffer.h \ call_log.h \ call_params.h \ @@ -34,15 +35,18 @@ linphone_include_HEADERS=\ linphonecore_utils.h \ linphonefriend.h \ linphonepresence.h \ + linphone_proxy_config.h \ linphone_tunnel.h \ lpc2xml.h \ lpconfig.h \ sipsetup.h \ - xml2lpc.h + xml2lpc.h \ + xmlrpc.h lib_LTLIBRARIES=liblinphone.la liblinphone_la_SOURCES=\ + account_creator.c \ address.c \ authentication.c \ buffer.c \ @@ -50,23 +54,23 @@ liblinphone_la_SOURCES=\ call_log.c \ call_params.c \ chat.c \ + chat_file_transfer.c \ conference.c \ contactprovider.c contactprovider.h contact_providers_priv.h \ content.c \ dict.c \ ec-calibrator.c \ enum.c enum.h \ - event.c event.h \ + event.c \ friend.c \ info.c \ ldap/ldapprovider.c ldap/ldapprovider.h \ linphonecall.c \ - linphonecore.c linphonecore.h \ - linphonecore_utils.h \ + linphonecore.c \ localplayer.c \ lpc2xml.c \ lime.c lime.h\ - lpconfig.c lpconfig.h \ + lpconfig.c \ lsd.c \ message_storage.c \ misc.c \ @@ -79,9 +83,10 @@ liblinphone_la_SOURCES=\ remote_provisioning.c \ sal.c \ siplogin.c \ - sipsetup.c sipsetup.h \ + sipsetup.c \ xml2lpc.c \ xml.c \ + xmlrpc.c \ vtables.c \ $(GITVERSION_FILE) @@ -102,10 +107,6 @@ liblinphone_la_SOURCES+= bellesip_sal/sal_address_impl.c \ bellesip_sal/sal_op_info.c \ bellesip_sal/sal_op_events.c -if BUILD_WIZARD -liblinphone_la_SOURCES+=sipwizard.c -endif - liblinphone_la_SOURCES+=linphone_tunnel_config.c if BUILD_TUNNEL liblinphone_la_SOURCES+=linphone_tunnel.cc TunnelManager.cc TunnelManager.hh linphone_tunnel.h @@ -137,7 +138,6 @@ liblinphone_la_LIBADD= \ $(ORTP_LIBS) \ $(SIPSTACK_LIBS) \ $(TUNNEL_LIBS) \ - $(LIBSOUP_LIBS) \ $(SQLITE3_LIBS) \ $(LIBXML2_LIBS) \ $(LDAP_LIBS) \ @@ -145,22 +145,6 @@ liblinphone_la_LIBADD= \ $(ZLIB_LIBS) -if ENABLE_TESTS -noinst_PROGRAMS=test_lsd test_ecc test_numbers - -test_lsd_SOURCES=test_lsd.c - -test_lsd_LDADD=liblinphone.la $(liblinphone_la_LIBADD) - -test_ecc_SOURCES=test_ecc.c - -test_ecc_LDADD=liblinphone.la $(liblinphone_la_LIBADD) - -test_numbers_SOURCES=test_numbers.c - -test_numbers_LDADD=liblinphone.la $(liblinphone_la_LIBADD) -endif - AM_CPPFLAGS=\ -I$(top_srcdir) -I$(top_srcdir)/include -I$(builddir) \ $(ORTP_CFLAGS) \ @@ -170,7 +154,6 @@ COMMON_CFLAGS=\ $(STRICT_OPTIONS) \ -DIN_LINPHONE \ $(SIPSTACK_CFLAGS) \ - $(LIBSOUP_CFLAGS) \ -DENABLE_TRACE \ -DLOG_DOMAIN=\"LinphoneCore\" \ $(IPV6_CFLAGS) \ diff --git a/coreapi/TunnelManager.hh b/coreapi/TunnelManager.hh index fdda28beb..f8002ee5d 100644 --- a/coreapi/TunnelManager.hh +++ b/coreapi/TunnelManager.hh @@ -56,7 +56,7 @@ namespace belledonnecomm { * @param ip tunnel server ip address * @param port tunnel server tls port, recommended value is 443 * @param udpMirrorPort remote port on the tunnel server side used to test udp reachability - * @param delay udp packet round trip delay in ms considered as acceptable. recommanded value is 1000 ms. + * @param delay udp packet round trip delay in ms considered as acceptable. recommended value is 1000 ms. */ void addServer(const char *ip, int port,unsigned int udpMirrorPort,unsigned int delay); /** diff --git a/coreapi/account_creator.c b/coreapi/account_creator.c new file mode 100644 index 000000000..4646806f0 --- /dev/null +++ b/coreapi/account_creator.c @@ -0,0 +1,449 @@ +/* +linphone +Copyright (C) 2010-2015 Belledonne Communications SARL + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "account_creator.h" +#include "private.h" +#if !_WIN32 +#include "regex.h" +#endif + +BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneAccountCreatorCbs); + +BELLE_SIP_INSTANCIATE_VPTR(LinphoneAccountCreatorCbs, belle_sip_object_t, + NULL, // destroy + NULL, // clone + NULL, // marshal + FALSE +); + +static LinphoneAccountCreatorCbs * linphone_account_creator_cbs_new(void) { + return belle_sip_object_new(LinphoneAccountCreatorCbs); +} + +LinphoneAccountCreatorCbs * linphone_account_creator_cbs_ref(LinphoneAccountCreatorCbs *cbs) { + belle_sip_object_ref(cbs); + return cbs; +} + +void linphone_account_creator_cbs_unref(LinphoneAccountCreatorCbs *cbs) { + belle_sip_object_unref(cbs); +} + +void *linphone_account_creator_cbs_get_user_data(const LinphoneAccountCreatorCbs *cbs) { + return cbs->user_data; +} + +void linphone_account_creator_cbs_set_user_data(LinphoneAccountCreatorCbs *cbs, void *ud) { + cbs->user_data = ud; +} + +LinphoneAccountCreatorCbsExistenceTestedCb linphone_account_creator_cbs_get_existence_tested(const LinphoneAccountCreatorCbs *cbs) { + return cbs->existence_tested; +} + +void linphone_account_creator_cbs_set_existence_tested(LinphoneAccountCreatorCbs *cbs, LinphoneAccountCreatorCbsExistenceTestedCb cb) { + cbs->existence_tested = cb; +} + +LinphoneAccountCreatorCbsValidationTestedCb linphone_account_creator_cbs_get_validation_tested(const LinphoneAccountCreatorCbs *cbs) { + return cbs->validation_tested; +} + +void linphone_account_creator_cbs_set_validation_tested(LinphoneAccountCreatorCbs *cbs, LinphoneAccountCreatorCbsValidationTestedCb cb) { + cbs->validation_tested = cb; +} + +LinphoneAccountCreatorCbsCreateAccountCb linphone_account_creator_cbs_get_create_account(const LinphoneAccountCreatorCbs *cbs) { + return cbs->create_account; +} + +void linphone_account_creator_cbs_set_create_account(LinphoneAccountCreatorCbs *cbs, LinphoneAccountCreatorCbsCreateAccountCb cb) { + cbs->create_account = cb; +} + + +static void _linphone_account_creator_destroy(LinphoneAccountCreator *creator) { + linphone_xml_rpc_session_unref(creator->xmlrpc_session); + linphone_account_creator_cbs_unref(creator->callbacks); + if (creator->username) ms_free(creator->username); + if (creator->password) ms_free(creator->password); + if (creator->domain) ms_free(creator->domain); + if (creator->route) ms_free(creator->route); + if (creator->email) ms_free(creator->email); + if (creator->display_name) ms_free(creator->display_name); +} + +BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneAccountCreator); + +BELLE_SIP_INSTANCIATE_VPTR(LinphoneAccountCreator, belle_sip_object_t, + (belle_sip_object_destroy_t)_linphone_account_creator_destroy, + NULL, // clone + NULL, // marshal + FALSE +); + + +LinphoneAccountCreator * linphone_account_creator_new(LinphoneCore *core, const char *xmlrpc_url) { + LinphoneAccountCreator *creator; + const char* domain = lp_config_get_string(core->config, "assistant", "domain", NULL); + creator = belle_sip_object_new(LinphoneAccountCreator); + creator->callbacks = linphone_account_creator_cbs_new(); + creator->core = core; + creator->xmlrpc_session = linphone_xml_rpc_session_new(core, xmlrpc_url); + if (domain) { + linphone_account_creator_set_domain(creator, domain); + } + return creator; +} + +LinphoneAccountCreator * linphone_account_creator_ref(LinphoneAccountCreator *creator) { + belle_sip_object_ref(creator); + return creator; +} + +void linphone_account_creator_unref(LinphoneAccountCreator *creator) { + belle_sip_object_unref(creator); +} + +void *linphone_account_creator_get_user_data(const LinphoneAccountCreator *creator) { + return creator->user_data; +} + +void linphone_account_creator_set_user_data(LinphoneAccountCreator *creator, void *ud) { + creator->user_data = ud; +} + +static LinphoneAccountCreatorStatus validate_uri(const char* username, const char* domain, const char* route, const char* display_name) { + LinphoneProxyConfig* proxy = linphone_proxy_config_new(); + LinphoneAddress* addr; + + linphone_proxy_config_set_identity(proxy, "sip:user@domain.com"); + + if (route && linphone_proxy_config_set_route(proxy, route) != 0) { + linphone_proxy_config_destroy(proxy); + return LinphoneAccountCreatorRouteInvalid; + } + + if (username) { + addr = linphone_proxy_config_normalize_sip_uri(proxy, username); + } else { + addr = linphone_address_clone(linphone_proxy_config_get_identity_address(proxy)); + } + linphone_proxy_config_destroy(proxy); + + if (addr == NULL) { + return LinphoneAccountCreatorUsernameInvalid; + } + + if (domain) { + ms_error("TODO: detect invalid domain"); + linphone_address_set_domain(addr, domain); + } + + if (display_name) { + ms_error("TODO: detect invalid display name"); + linphone_address_set_display_name(addr, display_name); + } + + linphone_address_unref(addr); + return LinphoneAccountCreatorOK; +} + +static bool_t is_matching_regex(const char *entry, const char* regex) { +#if _WIN32 + return TRUE; +#else + regex_t regex_pattern; + char err_msg[256]; + int res; + res = regcomp(®ex_pattern, regex, REG_EXTENDED | REG_NOSUB); + if(res != 0) { + regerror(res, ®ex_pattern, err_msg, sizeof(err_msg)); + ms_error("Could not compile regex '%s: %s", regex, err_msg); + return FALSE; + } + res = regexec(®ex_pattern, entry, 0, NULL, 0); + regfree(®ex_pattern); + return (res != REG_NOMATCH); +#endif +} + +LinphoneAccountCreatorStatus linphone_account_creator_set_username(LinphoneAccountCreator *creator, const char *username) { + int min_length = lp_config_get_int(creator->core->config, "assistant", "username_min_length", 0); + int fixed_length = lp_config_get_int(creator->core->config, "assistant", "username_length", 0); + bool_t use_phone_number = lp_config_get_int(creator->core->config, "assistant", "use_phone_number", 0); + const char* regex = lp_config_get_string(creator->core->config, "assistant", "username_regex", 0); + LinphoneAccountCreatorStatus status; + if (min_length > 0 && strlen(username) < min_length) { + return LinphoneAccountCreatorUsernameTooShort; + } else if (fixed_length > 0 && strlen(username) != fixed_length) { + return LinphoneAccountCreatorUsernameInvalidSize; + } else if (use_phone_number && !linphone_proxy_config_is_phone_number(NULL, username)) { + return LinphoneAccountCreatorUsernameInvalid; + } else if (regex && !is_matching_regex(username, regex)) { + return LinphoneAccountCreatorUsernameInvalid; + } else if ((status = validate_uri(username, NULL, NULL, NULL)) != LinphoneAccountCreatorOK) { + return status; + } + set_string(&creator->username, username, TRUE); + return LinphoneAccountCreatorOK; +} + +const char * linphone_account_creator_get_username(const LinphoneAccountCreator *creator) { + return creator->username; +} + +LinphoneAccountCreatorStatus linphone_account_creator_set_password(LinphoneAccountCreator *creator, const char *password){ + int min_length = lp_config_get_int(creator->core->config, "assistant", "password_min_length", 0); + if (min_length > 0 && strlen(password) < min_length) { + return LinphoneAccountCreatorPasswordTooShort; + } + set_string(&creator->password, password, FALSE); + return LinphoneAccountCreatorOK; +} + +const char * linphone_account_creator_get_password(const LinphoneAccountCreator *creator) { + return creator->password; +} + +LinphoneAccountCreatorStatus linphone_account_creator_set_transport(LinphoneAccountCreator *creator, LinphoneTransportType transport){ + if (!linphone_core_sip_transport_supported(creator->core, transport)) { + return LinphoneAccountCreatorTransportNotSupported; + } + creator->transport = transport; + return LinphoneAccountCreatorOK; +} + +LinphoneTransportType linphone_account_creator_get_transport(const LinphoneAccountCreator *creator) { + return creator->transport; +} + +LinphoneAccountCreatorStatus linphone_account_creator_set_domain(LinphoneAccountCreator *creator, const char *domain){ + if (validate_uri(NULL, domain, NULL, NULL) != 0) { + return LinphoneAccountCreatorDomainInvalid; + } + set_string(&creator->domain, domain, TRUE); + return LinphoneAccountCreatorOK; +} + +const char * linphone_account_creator_get_domain(const LinphoneAccountCreator *creator) { + return creator->domain; +} + +LinphoneAccountCreatorStatus linphone_account_creator_set_route(LinphoneAccountCreator *creator, const char *route) { + if (validate_uri(NULL, NULL, route, NULL) != 0) { + return LinphoneAccountCreatorRouteInvalid; + } + set_string(&creator->route, route, TRUE); + return LinphoneAccountCreatorOK; +} + +const char * linphone_account_creator_get_route(const LinphoneAccountCreator *creator) { + return creator->route; +} + +LinphoneAccountCreatorStatus linphone_account_creator_set_display_name(LinphoneAccountCreator *creator, const char *display_name) { + if (validate_uri(NULL, NULL, NULL, display_name) != 0) { + return LinphoneAccountCreatorDisplayNameInvalid; + } + set_string(&creator->display_name, display_name, FALSE); + return LinphoneAccountCreatorOK; +} + +const char * linphone_account_creator_get_display_name(const LinphoneAccountCreator *creator) { + return creator->display_name; +} + +LinphoneAccountCreatorStatus linphone_account_creator_set_email(LinphoneAccountCreator *creator, const char *email) { + if (!is_matching_regex(email, "^.+@.+\\.[A-Za-z]{2}[A-Za-z]*$")) { + return LinphoneAccountCreatorEmailInvalid; + } + set_string(&creator->email, email, TRUE); + return LinphoneAccountCreatorOK; +} + +const char * linphone_account_creator_get_email(const LinphoneAccountCreator *creator) { + return creator->email; +} + +void linphone_account_creator_enable_newsletter_subscription(LinphoneAccountCreator *creator, bool_t subscribe) { + creator->subscribe_to_newsletter = subscribe; +} + +bool_t linphone_account_creator_newsletter_subscription_enabled(const LinphoneAccountCreator *creator) { + return creator->subscribe_to_newsletter; +} + +LinphoneAccountCreatorCbs * linphone_account_creator_get_callbacks(const LinphoneAccountCreator *creator) { + return creator->callbacks; +} + +static void _test_existence_cb(LinphoneXmlRpcRequest *request) { + LinphoneAccountCreator *creator = (LinphoneAccountCreator *)linphone_xml_rpc_request_get_user_data(request); + if (creator->callbacks->existence_tested != NULL) { + LinphoneAccountCreatorStatus status = LinphoneAccountCreatorReqFailed; + if (linphone_xml_rpc_request_get_status(request) == LinphoneXmlRpcStatusOk) { + int resp = linphone_xml_rpc_request_get_int_response(request); + status = (resp == 0) ? LinphoneAccountCreatorAccountNotExist : LinphoneAccountCreatorAccountExist; + } + creator->callbacks->existence_tested(creator, status); + } +} + +LinphoneAccountCreatorStatus linphone_account_creator_test_existence(LinphoneAccountCreator *creator) { + LinphoneXmlRpcRequest *request; + char *identity; + + if (!creator->username || !creator->domain) { + if (creator->callbacks->existence_tested != NULL) { + creator->callbacks->existence_tested(creator, LinphoneAccountCreatorReqFailed); + } + return LinphoneAccountCreatorReqFailed; + } + identity = ms_strdup_printf("%s@%s", creator->username, creator->domain); + request = linphone_xml_rpc_request_new_with_args("check_account", LinphoneXmlRpcArgInt, + LinphoneXmlRpcArgString, identity, + LinphoneXmlRpcArgNone); + linphone_xml_rpc_request_set_user_data(request, creator); + linphone_xml_rpc_request_cbs_set_response(linphone_xml_rpc_request_get_callbacks(request), _test_existence_cb); + linphone_xml_rpc_session_send_request(creator->xmlrpc_session, request); + linphone_xml_rpc_request_unref(request); + ms_free(identity); + return LinphoneAccountCreatorOK; +} + +static void _test_validation_cb(LinphoneXmlRpcRequest *request) { + LinphoneAccountCreator *creator = (LinphoneAccountCreator *)linphone_xml_rpc_request_get_user_data(request); + if (creator->callbacks->validation_tested != NULL) { + LinphoneAccountCreatorStatus status = LinphoneAccountCreatorReqFailed; + if (linphone_xml_rpc_request_get_status(request) == LinphoneXmlRpcStatusOk) { + int resp = linphone_xml_rpc_request_get_int_response(request); + status = (resp == 0) ? LinphoneAccountCreatorAccountNotValidated : LinphoneAccountCreatorAccountValidated; + } + creator->callbacks->validation_tested(creator, status); + } +} + +LinphoneAccountCreatorStatus linphone_account_creator_test_validation(LinphoneAccountCreator *creator) { + LinphoneXmlRpcRequest *request; + char *identity; + + if (!creator->username || !creator->domain) { + if (creator->callbacks->validation_tested != NULL) { + creator->callbacks->validation_tested(creator, LinphoneAccountCreatorReqFailed); + } + return LinphoneAccountCreatorReqFailed; + } + + identity = ms_strdup_printf("%s@%s", creator->username, creator->domain); + request = linphone_xml_rpc_request_new_with_args("check_account_validated", LinphoneXmlRpcArgInt, + LinphoneXmlRpcArgString, identity, + LinphoneXmlRpcArgNone); + linphone_xml_rpc_request_set_user_data(request, creator); + linphone_xml_rpc_request_cbs_set_response(linphone_xml_rpc_request_get_callbacks(request), _test_validation_cb); + linphone_xml_rpc_session_send_request(creator->xmlrpc_session, request); + linphone_xml_rpc_request_unref(request); + ms_free(identity); + return LinphoneAccountCreatorOK; +} + +static void _create_account_cb(LinphoneXmlRpcRequest *request) { + LinphoneAccountCreator *creator = (LinphoneAccountCreator *)linphone_xml_rpc_request_get_user_data(request); + if (creator->callbacks->create_account != NULL) { + LinphoneAccountCreatorStatus status = LinphoneAccountCreatorReqFailed; + if (linphone_xml_rpc_request_get_status(request) == LinphoneXmlRpcStatusOk) { + int resp = linphone_xml_rpc_request_get_int_response(request); + status = (resp == 0) ? LinphoneAccountCreatorAccountCreated : LinphoneAccountCreatorAccountNotCreated; + } + creator->callbacks->create_account(creator, status); + } +} + +LinphoneAccountCreatorStatus linphone_account_creator_create_account(LinphoneAccountCreator *creator) { + LinphoneXmlRpcRequest *request; + char *identity; + + if (!creator->username || !creator->domain || !creator->email) { + if (creator->callbacks->create_account != NULL) { + creator->callbacks->create_account(creator, LinphoneAccountCreatorReqFailed); + } + return LinphoneAccountCreatorReqFailed; + } + + identity = ms_strdup_printf("%s@%s", creator->username, creator->domain); + request = linphone_xml_rpc_request_new_with_args("create_account", LinphoneXmlRpcArgInt, + LinphoneXmlRpcArgString, identity, + LinphoneXmlRpcArgString, creator->password, + LinphoneXmlRpcArgString, creator->email, + LinphoneXmlRpcArgInt, (creator->subscribe_to_newsletter == TRUE) ? 1 : 0, + LinphoneXmlRpcArgNone); + linphone_xml_rpc_request_set_user_data(request, creator); + linphone_xml_rpc_request_cbs_set_response(linphone_xml_rpc_request_get_callbacks(request), _create_account_cb); + linphone_xml_rpc_session_send_request(creator->xmlrpc_session, request); + linphone_xml_rpc_request_unref(request); + ms_free(identity); + return LinphoneAccountCreatorOK; +} + +LinphoneProxyConfig * linphone_account_creator_configure(const LinphoneAccountCreator *creator) { + LinphoneAuthInfo *info; + LinphoneProxyConfig *cfg = linphone_core_create_proxy_config(creator->core); + char *identity_str = ms_strdup_printf("sip:%s@%s", creator->username, creator->domain); + LinphoneAddress *identity = linphone_address_new(identity_str); + if (creator->display_name) { + linphone_address_set_display_name(identity, creator->display_name); + } + + linphone_proxy_config_set_identity(cfg, linphone_address_as_string(identity)); + linphone_proxy_config_set_server_addr(cfg, creator->domain); + linphone_proxy_config_set_route(cfg, creator->route); + linphone_proxy_config_enable_publish(cfg, FALSE); + linphone_proxy_config_enable_register(cfg, TRUE); + ms_free(identity_str); + + if (strcmp(creator->domain, "sip.linphone.org") == 0) { + linphone_proxy_config_enable_avpf(cfg, TRUE); + // If account created on sip.linphone.org, we configure linphone to use TLS by default + if (linphone_core_sip_transport_supported(creator->core, LinphoneTransportTls)) { + LinphoneAddress *addr = linphone_address_new(linphone_proxy_config_get_server_addr(cfg)); + char *tmp; + linphone_address_set_transport(addr, LinphoneTransportTls); + tmp = linphone_address_as_string(addr); + linphone_proxy_config_set_server_addr(cfg, tmp); + linphone_proxy_config_set_route(cfg, tmp); + ms_free(tmp); + linphone_address_destroy(addr); + } + linphone_core_set_stun_server(creator->core, "stun.linphone.org"); + linphone_core_set_firewall_policy(creator->core, LinphonePolicyUseIce); + } + + info = linphone_auth_info_new(linphone_address_get_username(identity), NULL, creator->password, NULL, NULL, linphone_address_get_domain(identity)); + linphone_core_add_auth_info(creator->core, info); + linphone_address_destroy(identity); + + if (linphone_core_add_proxy_config(creator->core, cfg) != -1) { + linphone_core_set_default_proxy(creator->core, cfg); + return cfg; + } + + linphone_core_remove_auth_info(creator->core, info); + linphone_proxy_config_unref(cfg); + return NULL; +} diff --git a/coreapi/account_creator.h b/coreapi/account_creator.h new file mode 100644 index 000000000..fe6c46c3d --- /dev/null +++ b/coreapi/account_creator.h @@ -0,0 +1,361 @@ +/* +account_creator.h +Copyright (C) 2010-2015 Belledonne Communications SARL + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef LINPHONE_ACCOUNT_CREATOR_H_ +#define LINPHONE_ACCOUNT_CREATOR_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include "linphonecore.h" + +/** + * @addtogroup misc + * @{ + */ + +/** +* Enum describing the status of a LinphoneAccountCreator operation. +**/ +typedef enum _LinphoneAccountCreatorStatus { + LinphoneAccountCreatorOK, + LinphoneAccountCreatorReqFailed, + + LinphoneAccountCreatorAccountCreated, + LinphoneAccountCreatorAccountNotCreated, + + LinphoneAccountCreatorAccountExist, + LinphoneAccountCreatorAccountNotExist, + + LinphoneAccountCreatorAccountValidated, + LinphoneAccountCreatorAccountNotValidated, + + LinphoneAccountCreatorEmailInvalid, + LinphoneAccountCreatorUsernameInvalid, + LinphoneAccountCreatorUsernameTooShort, + LinphoneAccountCreatorUsernameInvalidSize, + LinphoneAccountCreatorPasswordTooShort, + LinphoneAccountCreatorDomainInvalid, + LinphoneAccountCreatorRouteInvalid, + LinphoneAccountCreatorDisplayNameInvalid, + LinphoneAccountCreatorTransportNotSupported, +} LinphoneAccountCreatorStatus; + +/** + * The LinphoneAccountCreator object used to create an account on a server via XML-RPC. +**/ +typedef struct _LinphoneAccountCreator LinphoneAccountCreator; + +/** + * An object to handle the callbacks for handling the LinphoneAccountCreator operations. +**/ +typedef struct _LinphoneAccountCreatorCbs LinphoneAccountCreatorCbs; + +/** + * Callback used to notify the end of a LinphoneAccountCreator test existence operation. + * @param[in] creator LinphoneAccountCreator object + * @param[in] status The status of the LinphoneAccountCreator test existence operation that has just finished +**/ +typedef void (*LinphoneAccountCreatorCbsExistenceTestedCb)(LinphoneAccountCreator *creator, LinphoneAccountCreatorStatus status); + +/** + * Callback used to notify the end of a LinphoneAccountCreator test validation operation. + * @param[in] creator LinphoneAccountCreator object + * @param[in] status The status of the LinphoneAccountCreator test validation operation that has just finished +**/ +typedef void (*LinphoneAccountCreatorCbsValidationTestedCb)(LinphoneAccountCreator *creator, LinphoneAccountCreatorStatus status); + +/** + * Callback used to notify the end of a LinphoneAccountCreator validate operation. + * @param[in] creator LinphoneAccountCreator object + * @param[in] status The status of the LinphoneAccountCreator validate operation that has just finished +**/ +typedef void (*LinphoneAccountCreatorCbsCreateAccountCb)(LinphoneAccountCreator *creator, LinphoneAccountCreatorStatus status); + +/** + * Create a LinphoneAccountCreator. + * @param[in] core The LinphoneCore used for the XML-RPC communication + * @param[in] xmlrpc_url The URL to the XML-RPC server. Must be NON NULL. + * @return The new LinphoneAccountCreator object +**/ +LINPHONE_PUBLIC LinphoneAccountCreator * linphone_account_creator_new(LinphoneCore *core, const char *xmlrpc_url); + +/** + * Acquire a reference to the LinphoneAccountCreator. + * @param[in] creator LinphoneAccountCreator object. + * @return The same LinphoneAccountCreator object. +**/ +LINPHONE_PUBLIC LinphoneAccountCreator * linphone_account_creator_ref(LinphoneAccountCreator *creator); + +/** + * Release reference to the LinphoneAccountCreator. + * @param[in] creator LinphoneAccountCreator object. +**/ +LINPHONE_PUBLIC void linphone_account_creator_unref(LinphoneAccountCreator *creator); + +/** + * Retrieve the user pointer associated with the LinphoneAccountCreator. + * @param[in] creator LinphoneAccountCreator object. + * @return The user pointer associated with the LinphoneAccountCreator. +**/ +LINPHONE_PUBLIC void *linphone_account_creator_get_user_data(const LinphoneAccountCreator *creator); + +/** + * Assign a user pointer to the LinphoneAccountCreator. + * @param[in] creator LinphoneAccountCreator object. + * @param[in] ud The user pointer to associate with the LinphoneAccountCreator. +**/ +LINPHONE_PUBLIC void linphone_account_creator_set_user_data(LinphoneAccountCreator *creator, void *ud); + +/** + * Set the username. + * @param[in] creator LinphoneAccountCreator object + * @param[in] username The username to set + * @return LinphoneAccountCreatorOk if everything is OK, or a specific error otherwise. +**/ +LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_set_username(LinphoneAccountCreator *creator, const char *username); + +/** + * Get the username. + * @param[in] creator LinphoneAccountCreator object + * @return The username of the LinphoneAccountCreator +**/ +LINPHONE_PUBLIC const char * linphone_account_creator_get_username(const LinphoneAccountCreator *creator); + +/** + * Set the password. + * @param[in] creator LinphoneAccountCreator object + * @param[in] password The password to set + * @return LinphoneAccountCreatorOk if everything is OK, or a specific error otherwise. +**/ +LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_set_password(LinphoneAccountCreator *creator, const char *password); + +/** + * Get the password. + * @param[in] creator LinphoneAccountCreator object + * @return The password of the LinphoneAccountCreator +**/ +LINPHONE_PUBLIC const char * linphone_account_creator_get_password(const LinphoneAccountCreator *creator); + +/** + * Set the transport. + * @param[in] creator LinphoneAccountCreator object + * @param[in] transport The transport to set + * @return LinphoneAccountCreatorOk if everything is OK, or a specific error if given transport is not supported by linphone core. +**/ +LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_set_transport(LinphoneAccountCreator *creator, LinphoneTransportType transport); + +/** + * Get the transport. + * @param[in] creator LinphoneAccountCreator object + * @return The transport of the LinphoneAccountCreator +**/ +LINPHONE_PUBLIC LinphoneTransportType linphone_account_creator_get_transport(const LinphoneAccountCreator *creator); + +/** + * Set the domain. + * @param[in] creator LinphoneAccountCreator object + * @param[in] domain The domain to set + * @return LinphoneAccountCreatorOk if everything is OK, or a specific error otherwise. +**/ +LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_set_domain(LinphoneAccountCreator *creator, const char *domain); + +/** + * Get the domain. + * @param[in] creator LinphoneAccountCreator object + * @return The domain of the LinphoneAccountCreator +**/ +LINPHONE_PUBLIC const char * linphone_account_creator_get_domain(const LinphoneAccountCreator *creator); + +/** + * Set the route. + * @param[in] creator LinphoneAccountCreator object + * @param[in] route The route to set + * @return LinphoneAccountCreatorOk if everything is OK, or a specific error otherwise. +**/ +LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_set_route(LinphoneAccountCreator *creator, const char *route); + +/** + * Get the route. + * @param[in] creator LinphoneAccountCreator object + * @return The route of the LinphoneAccountCreator +**/ +LINPHONE_PUBLIC const char * linphone_account_creator_get_route(const LinphoneAccountCreator *creator); + +/** + * Set the email. + * @param[in] creator LinphoneAccountCreator object + * @param[in] display_name The display name to set + * @return LinphoneAccountCreatorOk if everything is OK, or a specific error otherwise. +**/ +LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_set_display_name(LinphoneAccountCreator *creator, const char *display_name); + +/** + * Get the email. + * @param[in] creator LinphoneAccountCreator object + * @return The display name of the LinphoneAccountCreator +**/ +LINPHONE_PUBLIC const char * linphone_account_creator_get_display_name(const LinphoneAccountCreator *creator); + +/** + * Set the email. + * @param[in] creator LinphoneAccountCreator object + * @param[in] email The email to set + * @return LinphoneAccountCreatorOk if everything is OK, or a specific error otherwise. +**/ +LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_set_email(LinphoneAccountCreator *creator, const char *email); + +/** + * Get the email. + * @param[in] creator LinphoneAccountCreator object + * @return The email of the LinphoneAccountCreator +**/ +LINPHONE_PUBLIC const char * linphone_account_creator_get_email(const LinphoneAccountCreator *creator); + +/** + * Enable the newsletter subscription. + * @param[in] creator LinphoneAccountCreator object + * @param[in] subscribe A boolean telling whether to subscribe to the newsletter or not. +**/ +LINPHONE_PUBLIC void linphone_account_creator_enable_newsletter_subscription(LinphoneAccountCreator *creator, bool_t subscribe); + +/** + * Tell whether to subscribe to the newsletter or not. + * @param[in] creator LinphoneAccountCreator object + * @return A boolean telling whether to subscribe to the newsletter or not. +**/ +LINPHONE_PUBLIC bool_t linphone_account_creator_newsletter_subscription_enabled(const LinphoneAccountCreator *creator); + +/** + * Get the LinphoneAccountCreatorCbs object associated with a LinphoneAccountCreator. + * @param[in] creator LinphoneAccountCreator object + * @return The LinphoneAccountCreatorCbs object associated with the LinphoneAccountCreator. +**/ +LINPHONE_PUBLIC LinphoneAccountCreatorCbs * linphone_account_creator_get_callbacks(const LinphoneAccountCreator *creator); + +/** + * Send an XML-RPC request to test the existence of a Linphone account. + * @param[in] creator LinphoneAccountCreator object + * @return LinphoneAccountCreatorOk if the request has been sent, LinphoneAccountCreatorReqFailed otherwise +**/ +LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_test_existence(LinphoneAccountCreator *creator); + +/** + * Send an XML-RPC request to test the validation of a Linphone account. + * @param[in] creator LinphoneAccountCreator object + * @return LinphoneAccountCreatorOk if the request has been sent, LinphoneAccountCreatorReqFailed otherwise +**/ +LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_test_validation(LinphoneAccountCreator *creator); + +/** + * Send an XML-RPC request to create a Linphone account. + * @param[in] creator LinphoneAccountCreator object + * @return LinphoneAccountCreatorOk if the request has been sent, LinphoneAccountCreatorReqFailed otherwise +**/ +LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_create_account(LinphoneAccountCreator *creator); + +/** + * Configure an account (create a proxy config and authentication info for it). + * @param[in] creator LinphoneAccountCreator object + * @return A LinphoneProxyConfig object if successful, NULL otherwise +**/ +LINPHONE_PUBLIC LinphoneProxyConfig * linphone_account_creator_configure(const LinphoneAccountCreator *creator); + + +/** + * Acquire a reference to a LinphoneAccountCreatorCbs object. + * @param[in] cbs LinphoneAccountCreatorCbs object. + * @return The same LinphoneAccountCreatorCbs object. +**/ +LINPHONE_PUBLIC LinphoneAccountCreatorCbs * linphone_account_creator_cbs_ref(LinphoneAccountCreatorCbs *cbs); + +/** + * Release a reference to a LinphoneAccountCreatorCbs object. + * @param[in] cbs LinphoneAccountCreatorCbs object. +**/ +LINPHONE_PUBLIC void linphone_account_creator_cbs_unref(LinphoneAccountCreatorCbs *cbs); + +/** + * Retrieve the user pointer associated with a LinphoneAccountCreatorCbs object. + * @param[in] cbs LinphoneAccountCreatorCbs object. + * @return The user pointer associated with the LinphoneAccountCreatorCbs object. +**/ +LINPHONE_PUBLIC void *linphone_account_creator_cbs_get_user_data(const LinphoneAccountCreatorCbs *cbs); + +/** + * Assign a user pointer to a LinphoneAccountCreatorCbs object. + * @param[in] cbs LinphoneAccountCreatorCbs object. + * @param[in] ud The user pointer to associate with the LinphoneAccountCreatorCbs object. +**/ +LINPHONE_PUBLIC void linphone_account_creator_cbs_set_user_data(LinphoneAccountCreatorCbs *cbs, void *ud); + +/** + * Get the existence tested callback. + * @param[in] cbs LinphoneAccountCreatorCbs object. + * @return The current existence tested callback. +**/ +LINPHONE_PUBLIC LinphoneAccountCreatorCbsExistenceTestedCb linphone_account_creator_cbs_get_existence_tested(const LinphoneAccountCreatorCbs *cbs); + +/** + * Set the existence tested callback. + * @param[in] cbs LinphoneAccountCreatorCbs object. + * @param[in] cb The existence tested callback to be used. +**/ +LINPHONE_PUBLIC void linphone_account_creator_cbs_set_existence_tested(LinphoneAccountCreatorCbs *cbs, LinphoneAccountCreatorCbsExistenceTestedCb cb); + +/** + * Get the validation tested callback. + * @param[in] cbs LinphoneAccountCreatorCbs object. + * @return The current validation tested callback. +**/ +LINPHONE_PUBLIC LinphoneAccountCreatorCbsValidationTestedCb linphone_account_creator_cbs_get_validation_tested(const LinphoneAccountCreatorCbs *cbs); + +/** + * Set the validation tested callback. + * @param[in] cbs LinphoneAccountCreatorCbs object. + * @param[in] cb The validation tested callback to be used. +**/ +LINPHONE_PUBLIC void linphone_account_creator_cbs_set_validation_tested(LinphoneAccountCreatorCbs *cbs, LinphoneAccountCreatorCbsValidationTestedCb cb); + +/** + * Get the create account callback. + * @param[in] cbs LinphoneAccountCreatorCbs object. + * @return The current create account callback. +**/ +LINPHONE_PUBLIC LinphoneAccountCreatorCbsCreateAccountCb linphone_account_creator_cbs_get_create_account(const LinphoneAccountCreatorCbs *cbs); + +/** + * Set the create account callback. + * @param[in] cbs LinphoneAccountCreatorCbs object. + * @param[in] cb The create account callback to be used. +**/ +LINPHONE_PUBLIC void linphone_account_creator_cbs_set_create_account(LinphoneAccountCreatorCbs *cbs, LinphoneAccountCreatorCbsCreateAccountCb cb); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* LINPHONE_ACCOUNT_CREATOR_H_ */ diff --git a/coreapi/authentication.c b/coreapi/authentication.c index f0f5eec2e..5382347ad 100644 --- a/coreapi/authentication.c +++ b/coreapi/authentication.c @@ -141,13 +141,16 @@ void linphone_auth_info_destroy(LinphoneAuthInfo *obj){ void linphone_auth_info_write_config(LpConfig *config, LinphoneAuthInfo *obj, int pos) { char key[50]; + bool_t store_ha1_passwd = lp_config_get_int(config, "sip", "store_ha1_passwd", 1); + + sprintf(key,"auth_info_%i",pos); lp_config_clean_section(config,key); if (obj==NULL || lp_config_get_int(config, "sip", "store_auth_info", 1) == 0){ return; } - if (!obj->ha1 && obj->realm && obj->passwd && (obj->username||obj->userid) && lp_config_get_int(config, "sip", "store_ha1_passwd", 1) == 1) { + if (!obj->ha1 && obj->realm && obj->passwd && (obj->username||obj->userid) && store_ha1_passwd) { /*compute ha1 to avoid storing clear text password*/ obj->ha1=ms_malloc(33); sal_auth_compute_ha1(obj->userid?obj->userid:obj->username,obj->realm,obj->passwd,obj->ha1); @@ -160,8 +163,17 @@ void linphone_auth_info_write_config(LpConfig *config, LinphoneAuthInfo *obj, in } if (obj->ha1!=NULL){ lp_config_set_string(config,key,"ha1",obj->ha1); - } else if (obj->passwd!=NULL){ /*only write passwd if no ha1*/ - lp_config_set_string(config,key,"passwd",obj->passwd); + } + if (obj->passwd != NULL){ + if (store_ha1_passwd){ + if (obj->ha1){ + /*if we have our ha1 and store_ha1_passwd set to TRUE, then drop the clear text password for security*/ + linphone_auth_info_set_passwd(obj, NULL); + } + }else{ + /*we store clear text password only if store_ha1_passwd is FALSE*/ + lp_config_set_string(config,key,"passwd",obj->passwd); + } } if (obj->realm!=NULL){ lp_config_set_string(config,key,"realm",obj->realm); @@ -218,7 +230,7 @@ static bool_t realm_match(const char *realm1, const char *realm2){ return FALSE; } -static const LinphoneAuthInfo *find_auth_info(LinphoneCore *lc, const char *username, const char *realm, const char *domain){ +static const LinphoneAuthInfo *find_auth_info(LinphoneCore *lc, const char *username, const char *realm, const char *domain, bool_t ignore_realm){ MSList *elem; const LinphoneAuthInfo *ret=NULL; @@ -238,9 +250,9 @@ static const LinphoneAuthInfo *find_auth_info(LinphoneCore *lc, const char *user } ret=pinfo; } - } else if (domain && pinfo->domain && strcmp(domain,pinfo->domain)==0 && pinfo->ha1==NULL) { + } else if (domain && pinfo->domain && strcmp(domain,pinfo->domain)==0 && (pinfo->ha1==NULL || ignore_realm)) { return pinfo; - } else if (!domain && pinfo->ha1==NULL) { + } else if (!domain && (pinfo->ha1==NULL || ignore_realm)) { return pinfo; } } @@ -248,38 +260,49 @@ static const LinphoneAuthInfo *find_auth_info(LinphoneCore *lc, const char *user return ret; } -/** - * Find authentication info matching realm, username, domain criteria. - * First of all, (realm,username) pair are searched. If multiple results (which should not happen because realm are supposed to be unique), then domain is added to the search. - * @param lc the LinphoneCore - * @param realm the authentication 'realm' (optional) - * @param username the SIP username to be authenticated (mandatory) - * @param domain the SIP domain name (optional) - * @return a #LinphoneAuthInfo -**/ -const LinphoneAuthInfo *linphone_core_find_auth_info(LinphoneCore *lc, const char *realm, const char *username, const char *domain){ + +const LinphoneAuthInfo *_linphone_core_find_auth_info(LinphoneCore *lc, const char *realm, const char *username, const char *domain, bool_t ignore_realm){ const LinphoneAuthInfo *ai=NULL; if (realm){ - ai=find_auth_info(lc,username,realm,NULL); + ai=find_auth_info(lc,username,realm,NULL, FALSE); if (ai==NULL && domain){ - ai=find_auth_info(lc,username,realm,domain); + ai=find_auth_info(lc,username,realm,domain, FALSE); } } if (ai == NULL && domain != NULL) { - ai=find_auth_info(lc,username,NULL,domain); + ai=find_auth_info(lc,username,NULL,domain, ignore_realm); } if (ai==NULL){ - ai=find_auth_info(lc,username,NULL,NULL); + ai=find_auth_info(lc,username,NULL,NULL, ignore_realm); } - /*if (ai) ms_message("linphone_core_find_auth_info(): returning auth info username=%s, realm=%s", ai->username, ai->realm);*/ + if (ai) ms_message("linphone_core_find_auth_info(): returning auth info username=%s, realm=%s", ai->username ? ai->username : "", ai->realm ? ai->realm : ""); return ai; } +const LinphoneAuthInfo *linphone_core_find_auth_info(LinphoneCore *lc, const char *realm, const char *username, const char *domain){ + return _linphone_core_find_auth_info(lc, realm, username, domain, TRUE); +} + +/*the auth info is expected to be in the core's list*/ +void linphone_core_write_auth_info(LinphoneCore *lc, LinphoneAuthInfo *ai){ + int i; + MSList *elem = lc->auth_info; + + if (!lc->sip_conf.save_auth_info) return; + + for (i=0; elem != NULL; elem = elem->next, i++){ + if (ai == elem->data){ + linphone_auth_info_write_config(lc->config, ai, i); + } + } +} + static void write_auth_infos(LinphoneCore *lc){ MSList *elem; int i; if (!linphone_core_ready(lc)) return; + if (!lc->sip_conf.save_auth_info) return; for(elem=lc->auth_info,i=0;elem!=NULL;elem=ms_list_next(elem),i++){ LinphoneAuthInfo *ai=(LinphoneAuthInfo*)(elem->data); linphone_auth_info_write_config(lc->config,ai,i); @@ -321,7 +344,7 @@ void linphone_core_add_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *info) SalOp *op=(SalOp*)elem->data; LinphoneAuthInfo *ai; const SalAuthInfo *req_sai=sal_op_get_auth_requested(op); - ai=(LinphoneAuthInfo*)linphone_core_find_auth_info(lc,req_sai->realm,req_sai->username,req_sai->domain); + ai=(LinphoneAuthInfo*)_linphone_core_find_auth_info(lc,req_sai->realm,req_sai->username,req_sai->domain, FALSE); if (ai){ SalAuthInfo sai; MSList* proxy; @@ -353,7 +376,7 @@ void linphone_core_add_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *info) info->domain ? info->domain : ""); } ms_list_free(l); - if(lc->sip_conf.save_auth_info) write_auth_infos(lc); + write_auth_infos(lc); } @@ -373,7 +396,7 @@ void linphone_core_remove_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *in if (r){ lc->auth_info=ms_list_remove(lc->auth_info,r); linphone_auth_info_destroy(r); - if(lc->sip_conf.save_auth_info) write_auth_infos(lc); + write_auth_infos(lc); } } diff --git a/coreapi/bellesip_sal/sal_impl.c b/coreapi/bellesip_sal/sal_impl.c index 9829d22b3..c98dbec7f 100644 --- a/coreapi/bellesip_sal/sal_impl.c +++ b/coreapi/bellesip_sal/sal_impl.c @@ -87,12 +87,31 @@ void _belle_sip_log(belle_sip_log_level lev, const char *fmt, va_list args) { } } -void sal_enable_logs(){ - belle_sip_set_log_level(BELLE_SIP_LOG_MESSAGE); +void sal_enable_log(){ + sal_set_log_level(ORTP_MESSAGE); } -void sal_disable_logs() { - belle_sip_set_log_level(BELLE_SIP_LOG_ERROR); +void sal_disable_log() { + sal_set_log_level(ORTP_ERROR); +} + +void sal_set_log_level(OrtpLogLevel level) { + belle_sip_log_level belle_sip_level; + if ((level&ORTP_FATAL) != 0) { + belle_sip_level = BELLE_SIP_LOG_FATAL; + } else if ((level&ORTP_ERROR) != 0) { + belle_sip_level = BELLE_SIP_LOG_ERROR; + } else if ((level&ORTP_WARNING) != 0) { + belle_sip_level = BELLE_SIP_LOG_WARNING; + } else if ((level&ORTP_MESSAGE) != 0) { + belle_sip_level = BELLE_SIP_LOG_MESSAGE; + } else if (((level&ORTP_DEBUG) != 0) || ((level&ORTP_TRACE) != 0)) { + belle_sip_level = BELLE_SIP_LOG_DEBUG; + } else { + //well, this should never occurs but... + belle_sip_level = BELLE_SIP_LOG_MESSAGE; + } + belle_sip_set_log_level(belle_sip_level); } void sal_add_pending_auth(Sal *sal, SalOp *op){ @@ -221,6 +240,14 @@ static void process_request_event(void *ud, const belle_sip_request_event_t *eve return; } }else if (strcmp("INVITE",method)==0) { + /*handle the case where we are receiving a request with to tag but it is not belonging to any dialog*/ + belle_sip_header_to_t *to = belle_sip_message_get_header_by_type(req, belle_sip_header_to_t); + if (belle_sip_header_to_get_tag(to) != NULL){ + ms_warning("Receiving INVITE with to-tag but no know dialog here. Rejecting."); + resp=belle_sip_response_create_from_request(req,481); + belle_sip_provider_send_response(sal->prov,resp); + return; + } op=sal_op_new(sal); op->dir=SalOpDirIncoming; sal_op_call_fill_cbs(op); @@ -471,6 +498,7 @@ Sal * sal_init(){ sal->tls_verify_cn=TRUE; sal->refresher_retry_after=60000; /*default value in ms*/ sal->enable_sip_update=TRUE; + sal->pending_trans_checking=TRUE; return sal; } @@ -482,7 +510,7 @@ void *sal_get_user_pointer(const Sal *sal){ return sal->up; } -static void unimplemented_stub(){ +static void unimplemented_stub(void){ ms_warning("Unimplemented SAL callback"); } @@ -594,7 +622,9 @@ static int sal_add_listen_port(Sal *ctx, SalAddress* addr, bool_t is_tunneled){ if (lp) { belle_sip_listening_point_set_keep_alive(lp,ctx->keep_alive); result = belle_sip_provider_add_listening_point(ctx->prov,lp); - if (sal_address_get_transport(addr)==SalTransportTLS) set_tls_properties(ctx); + if (sal_address_get_transport(addr)==SalTransportTLS) { + set_tls_properties(ctx); + } } else { return -1; } @@ -749,9 +779,6 @@ MSList * sal_get_pending_auths(Sal *sal){ return ms_list_copy(sal->pending_auths); } -#define payload_type_set_number(pt,n) (pt)->user_data=(void*)((long)n); -#define payload_type_get_number(pt) ((int)(long)(pt)->user_data) - /*misc*/ void sal_get_default_local_ip(Sal *sal, int address_family, char *ip, size_t iplen){ strncpy(ip,address_family==AF_INET6 ? "::1" : "127.0.0.1",iplen); @@ -897,6 +924,40 @@ const SalCustomHeader *sal_op_get_recv_custom_header(SalOp *op){ return b->recv_custom_headers; } +SalCustomSdpAttribute * sal_custom_sdp_attribute_append(SalCustomSdpAttribute *csa, const char *name, const char *value) { + belle_sdp_session_description_t *desc = (belle_sdp_session_description_t *)csa; + belle_sdp_attribute_t *attr; + + if (desc == NULL) { + desc = (belle_sdp_session_description_t *)belle_sdp_session_description_new(); + belle_sip_object_ref(desc); + } + attr = BELLE_SDP_ATTRIBUTE(belle_sdp_raw_attribute_create(name, value)); + if (attr == NULL) { + belle_sip_error("Fail to create custom SDP attribute."); + return (SalCustomSdpAttribute*)desc; + } + belle_sdp_session_description_add_attribute(desc, attr); + return (SalCustomSdpAttribute *)desc; +} + +const char * sal_custom_sdp_attribute_find(const SalCustomSdpAttribute *csa, const char *name) { + if (csa) { + return belle_sdp_session_description_get_attribute_value((belle_sdp_session_description_t *)csa, name); + } + return NULL; +} + +void sal_custom_sdp_attribute_free(SalCustomSdpAttribute *csa) { + if (csa == NULL) return; + belle_sip_object_unref((belle_sdp_session_description_t *)csa); +} + +SalCustomSdpAttribute * sal_custom_sdp_attribute_clone(const SalCustomSdpAttribute *csa) { + if (csa == NULL) return NULL; + return (SalCustomSdpAttribute *)belle_sip_object_ref((belle_sdp_session_description_t *)csa); +} + void sal_set_uuid(Sal *sal, const char *uuid){ if (sal->uuid){ ms_free(sal->uuid); @@ -1153,3 +1214,28 @@ void sal_default_set_sdp_handling(Sal *sal, SalOpSDPHandling sdp_handling_method if (sdp_handling_method != SalOpSDPNormal ) ms_message("Enabling special SDP handling for all new SalOp in Sal[%p]!", sal); sal->default_sdp_handling = sdp_handling_method; } + +bool_t sal_pending_trans_checking_enabled(const Sal *sal) { + return sal->pending_trans_checking; +} + +int sal_enable_pending_trans_checking(Sal *sal, bool_t value) { + sal->pending_trans_checking = value; + return 0; +} +void sal_set_http_proxy_host(Sal *sal, const char *host) { + belle_sip_stack_set_http_proxy_host(sal->stack, host); +} + +void sal_set_http_proxy_port(Sal *sal, int port) { + belle_sip_stack_set_http_proxy_port(sal->stack, port); +} +const char *sal_get_http_proxy_host(const Sal *sal) { + return belle_sip_stack_get_http_proxy_host(sal->stack); +} + +int sal_get_http_proxy_port(const Sal *sal) { + return belle_sip_stack_get_http_proxy_port(sal->stack); +} + + diff --git a/coreapi/bellesip_sal/sal_impl.h b/coreapi/bellesip_sal/sal_impl.h index 4cceba127..bd942c9aa 100644 --- a/coreapi/bellesip_sal/sal_impl.h +++ b/coreapi/bellesip_sal/sal_impl.h @@ -51,6 +51,7 @@ struct Sal{ bool_t no_initial_route; bool_t enable_sip_update; /*true by default*/ SalOpSDPHandling default_sdp_handling; + bool_t pending_trans_checking; /*testing purpose*/ }; typedef enum SalOpState { @@ -92,7 +93,6 @@ struct SalOp{ belle_sip_header_referred_by_t *referred_by; SalMediaDescription *result; belle_sdp_session_description_t *sdp_answer; - bool_t supports_session_timers; SalOpState state; SalOpDir dir; belle_sip_refresher_t* refresher; @@ -100,14 +100,16 @@ struct SalOp{ SalOpType type; SalPrivacyMask privacy; belle_sip_header_t *event; /*used by SalOpSubscribe kinds*/ + SalOpSDPHandling sdp_handling; + int auth_requests; /*number of auth requested for this op*/ + bool_t cnx_ip_to_0000_if_sendonly_enabled; bool_t auto_answer_asked; bool_t sdp_offering; bool_t call_released; bool_t manual_refresher; bool_t has_auth_pending; - SalOpSDPHandling sdp_handling; - int auth_requests; /*number of auth requested for this op*/ - bool_t cnx_ip_to_0000_if_sendonly_enabled; /*for */ + bool_t supports_session_timers; + bool_t op_released; }; diff --git a/coreapi/bellesip_sal/sal_op_call.c b/coreapi/bellesip_sal/sal_op_call.c index acc629f39..076421aad 100644 --- a/coreapi/bellesip_sal/sal_op_call.c +++ b/coreapi/bellesip_sal/sal_op_call.c @@ -32,8 +32,9 @@ static void call_set_released(SalOp* op){ } } -static void call_set_error(SalOp* op,belle_sip_response_t* response){ +static void call_set_error(SalOp* op,belle_sip_response_t* response, bool_t fatal){ sal_op_set_error_info_from_response(op,response); + if (fatal) op->state = SalOpStateTerminating; op->base.root->callbacks.call_failure(op); } static void set_addr_to_0000(char value[]) { @@ -66,7 +67,7 @@ static void sdp_process(SalOp *h){ /*for backward compatibility purpose*/ if(h->cnx_ip_to_0000_if_sendonly_enabled && sal_media_description_has_dir(h->result,SalStreamSendOnly)) { set_addr_to_0000(h->result->addr); - for(i=0;iresult->nb_streams;++i){ + for(i=0;iresult->streams[i].dir == SalStreamSendOnly) set_addr_to_0000(h->result->streams[i].rtp_addr); set_addr_to_0000(h->result->streams[i].rtcp_addr); @@ -78,7 +79,7 @@ static void sdp_process(SalOp *h){ strcpy(h->result->addr,h->base.remote_media->addr); h->result->bandwidth=h->base.remote_media->bandwidth; - for(i=0;iresult->nb_streams;++i){ + for(i=0;iresult->streams[i].rtp_port!=0){ /*if stream was accepted*/ strcpy(h->result->streams[i].rtp_addr,h->base.remote_media->streams[i].rtp_addr); @@ -88,7 +89,7 @@ static void sdp_process(SalOp *h){ strcpy(h->result->streams[i].rtcp_addr,h->base.remote_media->streams[i].rtcp_addr); h->result->streams[i].rtcp_port=h->base.remote_media->streams[i].rtcp_port; - if ((h->result->streams[i].proto == SalProtoRtpSavpf) || (h->result->streams[i].proto == SalProtoRtpSavp)) { + if (sal_stream_description_has_srtp(&h->result->streams[i])) { h->result->streams[i].crypto[0] = h->base.remote_media->streams[i].crypto[0]; } } @@ -149,6 +150,7 @@ static void call_process_io_error(void *user_ctx, const belle_sip_io_error_event /*call terminated very early*/ sal_error_info_set(&op->error_info,SalReasonIOError,503,"IO error",NULL); op->base.root->callbacks.call_failure(op); + op->state = SalOpStateTerminating; call_set_released(op); } else { /*dialog will terminated shortly, nothing to do*/ @@ -162,6 +164,14 @@ static void process_dialog_terminated(void *ctx, const belle_sip_dialog_terminat ms_message("Dialog [%p] terminated for op [%p]",belle_sip_dialog_terminated_event_get_dialog(event),op); switch(belle_sip_dialog_get_previous_state(op->dialog)) { + case BELLE_SIP_DIALOG_EARLY: + case BELLE_SIP_DIALOG_NULL: + if (op->state!=SalOpStateTerminated && op->state!=SalOpStateTerminating) { + /*this is an early termination due to incorrect response received*/ + op->base.root->callbacks.call_failure(op); + op->state=SalOpStateTerminating; + } + break; case BELLE_SIP_DIALOG_CONFIRMED: if (op->state!=SalOpStateTerminated && op->state!=SalOpStateTerminating) { /*this is probably a normal termination from a BYE*/ @@ -201,7 +211,23 @@ static void cancelling_invite(SalOp* op ){ belle_sip_request_t* cancel; ms_message("Cancelling INVITE request from [%s] to [%s] ",sal_op_get_from(op), sal_op_get_to(op)); cancel = belle_sip_client_transaction_create_cancel(op->pending_client_trans); - sal_op_send_request(op,cancel); + if (cancel){ + sal_op_send_request(op,cancel); + }else if (op->dialog){ + belle_sip_dialog_state_t state = belle_sip_dialog_get_state(op->dialog);; + /*case where the response received is invalid (could not establish a dialog), but the transaction is not cancellable + * because already terminated*/ + switch(state){ + case BELLE_SIP_DIALOG_EARLY: + case BELLE_SIP_DIALOG_NULL: + /*force kill the dialog*/ + ms_warning("op [%p]: force kill of dialog [%p]", op, op->dialog); + belle_sip_dialog_delete(op->dialog); + break; + default: + break; + } + } op->state=SalOpStateTerminating; } @@ -263,7 +289,7 @@ static void call_process_response(void *op_base, const belle_sip_response_event_ } belle_sip_object_data_set(BELLE_SIP_OBJECT(dialog),"early_response",belle_sip_object_ref(response),belle_sip_object_unref); } else if (code>=300){ - call_set_error(op,response); + call_set_error(op, response, TRUE); if (op->dialog==NULL) call_set_released(op); } } else if (code >=200 @@ -295,17 +321,17 @@ static void call_process_response(void *op_base, const belle_sip_response_event_ op->base.root->callbacks.call_accepted(op); /*INVITE*/ op->state=SalOpStateActive; }else if (code >= 300){ - call_set_error(op,response); + call_set_error(op,response, FALSE); } }else if (strcmp("INFO",method)==0){ if (code == 491 && (header_content_type = belle_sip_message_get_header_by_type(req,belle_sip_header_content_type_t)) && strcmp("application",belle_sip_header_content_type_get_type(header_content_type))==0 && strcmp("media_control+xml",belle_sip_header_content_type_get_subtype(header_content_type))==0) { - unsigned int retry_in =1000*((float)rand()/RAND_MAX); - belle_sip_source_t *s=sal_create_timer(op->base.root,vfu_retry,sal_op_ref(op), retry_in, "vfu request retry"); - ms_message("Rejected vfu request on op [%p], just retry in [%ui] ms",op,retry_in); - belle_sip_object_unref(s); + unsigned int retry_in = (unsigned int)(1000*((float)rand()/RAND_MAX)); + belle_sip_source_t *s=sal_create_timer(op->base.root,vfu_retry,sal_op_ref(op), retry_in, "vfu request retry"); + ms_message("Rejected vfu request on op [%p], just retry in [%ui] ms",op,retry_in); + belle_sip_object_unref(s); }else { /*ignoring*/ } @@ -323,8 +349,8 @@ static void call_process_response(void *op_base, const belle_sip_response_event_ } break; case BELLE_SIP_DIALOG_TERMINATED: { - if (code >= 300){ - call_set_error(op,response); + if (strcmp("INVITE",method)==0 && code >= 300){ + call_set_error(op,response, TRUE); } } break; @@ -345,6 +371,7 @@ static void call_process_timeout(void *user_ctx, const belle_sip_timeout_event_t /*call terminated very early*/ sal_error_info_set(&op->error_info,SalReasonRequestTimeout,408,"Request timeout",NULL); op->base.root->callbacks.call_failure(op); + op->state = SalOpStateTerminating; call_set_released(op); } else { /*dialog will terminated shortly, nothing to do*/ @@ -357,6 +384,7 @@ static void call_process_transaction_terminated(void *user_ctx, const belle_sip_ belle_sip_server_transaction_t *server_transaction=belle_sip_transaction_terminated_event_get_server_transaction(event); belle_sip_request_t* req; belle_sip_response_t* resp; + int code = 0; bool_t release_call=FALSE; if (client_transaction) { @@ -366,12 +394,20 @@ static void call_process_transaction_terminated(void *user_ctx, const belle_sip_ req=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(server_transaction)); resp=belle_sip_transaction_get_response(BELLE_SIP_TRANSACTION(server_transaction)); } - if (op->state ==SalOpStateTerminating + if (resp) code = belle_sip_response_get_status_code(resp); + + if (op->state == SalOpStateTerminating && strcmp("BYE",belle_sip_request_get_method(req))==0 - && (!resp || (belle_sip_response_get_status_code(resp) !=401 - && belle_sip_response_get_status_code(resp) !=407)) + && (!resp || (belle_sip_response_get_status_code(resp) != 401 + && belle_sip_response_get_status_code(resp) != 407)) && op->dialog==NULL) { release_call=TRUE; + }else if (op->state == SalOpStateEarly && code < 200){ + /*call terminated early*/ + sal_error_info_set(&op->error_info,SalReasonIOError,503,"I/O error",NULL); + op->state = SalOpStateTerminating; + op->base.root->callbacks.call_failure(op); + release_call=TRUE; } if (server_transaction){ if (op->pending_server_trans==server_transaction){ @@ -388,6 +424,7 @@ static void call_process_transaction_terminated(void *user_ctx, const belle_sip_ static void call_terminated(SalOp* op,belle_sip_server_transaction_t* server_transaction, belle_sip_request_t* request,int status_code) { belle_sip_response_t* resp; + op->state = SalOpStateTerminating; op->base.root->callbacks.call_terminated(op,op->dir==SalOpDirIncoming?sal_op_get_from(op):sal_op_get_to(op)); resp=sal_op_create_response_from_request(op,request,status_code); belle_sip_server_transaction_send_response(server_transaction,resp); @@ -497,6 +534,7 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t belle_sip_header_t* call_info; const char *method=belle_sip_request_get_method(req); bool_t is_update=FALSE; + bool_t drop_op = FALSE; if (strcmp("ACK",method)!=0){ /*ACK does'nt create srv transaction*/ server_transaction = belle_sip_provider_create_server_transaction(op->base.root->prov,belle_sip_request_event_get_request(event)); @@ -540,12 +578,14 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t } } op->base.root->callbacks.call_received(op); + }else{ + /*the INVITE was declined by process_sdp_for_invite(). As we are not inside an established dialog, we can drop the op immediately*/ + drop_op = TRUE; } break; - } /* else same behavior as for EARLY state*/ + } /* else same behavior as for EARLY state, thus NO BREAK*/ } case BELLE_SIP_DIALOG_EARLY: { - //hmm probably a cancel if (strcmp("CANCEL",method)==0) { if(belle_sip_request_event_get_server_transaction(event)) { /*first answer 200 ok to cancel*/ @@ -578,22 +618,27 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t case BELLE_SIP_DIALOG_CONFIRMED: /*great ACK received*/ if (strcmp("ACK",method)==0) { - if (op->sdp_offering){ - SalReason reason; - if (extract_sdp(op,BELLE_SIP_MESSAGE(req),&sdp,&reason)==0){ - if (sdp){ - if (op->base.remote_media) - sal_media_description_unref(op->base.remote_media); - op->base.remote_media=sal_media_description_new(); - sdp_to_media_description(sdp,op->base.remote_media); - sdp_process(op); - belle_sip_object_unref(sdp); - }else{ - ms_warning("SDP expected in ACK but not found."); + if (!op->pending_client_trans || + !belle_sip_transaction_state_is_transient(belle_sip_transaction_get_state((belle_sip_transaction_t*)op->pending_client_trans))){ + if (op->sdp_offering){ + SalReason reason; + if (extract_sdp(op,BELLE_SIP_MESSAGE(req),&sdp,&reason)==0){ + if (sdp){ + if (op->base.remote_media) + sal_media_description_unref(op->base.remote_media); + op->base.remote_media=sal_media_description_new(); + sdp_to_media_description(sdp,op->base.remote_media); + sdp_process(op); + belle_sip_object_unref(sdp); + }else{ + ms_warning("SDP expected in ACK but not found."); + } } } + op->base.root->callbacks.call_ack(op); + }else{ + ms_message("Ignored received ack since a new client transaction has been started since."); } - op->base.root->callbacks.call_ack(op); } else if(strcmp("BYE",method)==0) { resp=sal_op_create_response_from_request(op,req,200); belle_sip_server_transaction_send_response(server_transaction,resp); @@ -662,7 +707,7 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t } if (server_transaction) belle_sip_object_unref(server_transaction); - + if (drop_op) sal_op_release(op); } @@ -855,6 +900,9 @@ int sal_call_accept(SalOp*h){ belle_sip_object_unref(h->pending_update_server_trans); h->pending_update_server_trans=NULL; } + if (h->state == SalOpStateEarly){ + h->state = SalOpStateActive; + } return 0; } @@ -889,6 +937,8 @@ int sal_call_decline(SalOp *op, SalReason reason, const char *redirection /*opti int sal_call_update(SalOp *op, const char *subject, bool_t no_user_consent){ belle_sip_request_t *update; belle_sip_dialog_state_t state=belle_sip_dialog_get_state(op->dialog); + belle_sip_dialog_enable_pending_trans_checking(op->dialog,op->base.root->pending_trans_checking); + /*check for dialog state*/ if ( state == BELLE_SIP_DIALOG_CONFIRMED) { if (no_user_consent) @@ -906,6 +956,11 @@ int sal_call_update(SalOp *op, const char *subject, bool_t no_user_consent){ sal_op_fill_invite(op, update); return sal_op_send_request(op,update); } + /*it failed why ?*/ + if (belle_sip_dialog_request_pending(op->dialog)) + sal_error_info_set(&op->error_info,SalReasonRequestPending,491,NULL,NULL); + else + sal_error_info_set(&op->error_info,SalReasonUnknown,500,NULL,NULL); return -1; } diff --git a/coreapi/bellesip_sal/sal_op_events.c b/coreapi/bellesip_sal/sal_op_events.c index d4a24bd9b..8b439eb9b 100644 --- a/coreapi/bellesip_sal/sal_op_events.c +++ b/coreapi/bellesip_sal/sal_op_events.c @@ -129,8 +129,7 @@ static void subscribe_process_request_event(void *op_base, const belle_sip_reque if (!op->dialog) { if (strcmp(method,"SUBSCRIBE")==0){ op->dialog=belle_sip_provider_create_dialog(op->base.root->prov,BELLE_SIP_TRANSACTION(server_transaction)); - belle_sip_dialog_set_application_data(op->dialog,op); - sal_op_ref(op); + belle_sip_dialog_set_application_data(op->dialog, sal_op_ref(op)); ms_message("new incoming subscription from [%s] to [%s]",sal_op_get_from(op),sal_op_get_to(op)); }else{ /*this is a NOTIFY*/ handle_notify(op,req,eventname,&body); diff --git a/coreapi/bellesip_sal/sal_op_impl.c b/coreapi/bellesip_sal/sal_op_impl.c index 796055a55..5a55d2900 100644 --- a/coreapi/bellesip_sal/sal_op_impl.c +++ b/coreapi/bellesip_sal/sal_op_impl.c @@ -38,6 +38,7 @@ void sal_op_release(SalOp *op){ if (op->refresher) { belle_sip_refresher_stop(op->refresher); } + op->op_released = TRUE; sal_op_unref(op); } @@ -72,7 +73,7 @@ void sal_op_authenticate(SalOp *op, const SalAuthInfo *info){ /*Registration authenticate is just about registering again*/ sal_register_refresh(op,-1); }else { - /*for sure auth info will be accesible from the provider*/ + /*for sure auth info will be accessible from the provider*/ sal_process_authentication(op); } return ; @@ -286,7 +287,7 @@ void _sal_op_add_custom_headers(SalOp *op, belle_sip_message_t *msg){ } } -static int _sal_op_send_request_with_contact(SalOp* op, belle_sip_request_t* request,bool_t add_contact) { +static int _sal_op_send_request_with_contact(SalOp* op, belle_sip_request_t* request, bool_t add_contact) { belle_sip_client_transaction_t* client_transaction; belle_sip_provider_t* prov=op->base.root->prov; belle_sip_uri_t* outbound_proxy=NULL; @@ -294,10 +295,10 @@ static int _sal_op_send_request_with_contact(SalOp* op, belle_sip_request_t* req int result =-1; belle_sip_uri_t *next_hop_uri=NULL; - if (add_contact) { + if (add_contact && !belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(request),belle_sip_header_contact_t)) { contact = sal_op_create_contact(op); belle_sip_message_set_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_HEADER(contact)); - } + } /*keep existing*/ _sal_op_add_custom_headers(op, (belle_sip_message_t*)request); @@ -464,6 +465,9 @@ SalReason sal_reason_to_sip_code(SalReason r){ case SalReasonBadGateway: ret=502; break; + case SalReasonInternalError: + ret=500; + break; } return ret; } @@ -508,6 +512,8 @@ SalReason _sal_reason_from_sip_code(int code) { return SalReasonNotAcceptable; case 491: return SalReasonRequestPending; + case 500: + return SalReasonInternalError; case 501: return SalReasonNotImplemented; case 502: @@ -608,7 +614,10 @@ void set_or_update_dialog(SalOp* op, belle_sip_dialog_t* dialog) { unlink_op_with_dialog(op,op->dialog); op->dialog=NULL; } - if (dialog) op->dialog=link_op_with_dialog(op,dialog); + if (dialog) { + op->dialog=link_op_with_dialog(op,dialog); + belle_sip_dialog_enable_pending_trans_checking(dialog,op->base.root->pending_trans_checking); + } } sal_op_unref(op); } @@ -806,6 +815,11 @@ void sal_call_set_sdp_handling(SalOp *h, SalOpSDPHandling handling) { void sal_op_cnx_ip_to_0000_if_sendonly_enable(SalOp *op,bool_t yesno) { op->cnx_ip_to_0000_if_sendonly_enabled = yesno; } + bool_t sal_op_cnx_ip_to_0000_if_sendonly_enabled(SalOp *op) { return op->cnx_ip_to_0000_if_sendonly_enabled; } + +bool_t sal_op_is_forked_of(const SalOp *op1, const SalOp *op2){ + return op1->base.call_id && op2->base.call_id && strcmp(op1->base.call_id, op2->base.call_id) == 0; +} diff --git a/coreapi/bellesip_sal/sal_op_info.c b/coreapi/bellesip_sal/sal_op_info.c index 9abc73818..3cffb8e55 100644 --- a/coreapi/bellesip_sal/sal_op_info.c +++ b/coreapi/bellesip_sal/sal_op_info.c @@ -21,7 +21,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. int sal_send_info(SalOp *op, const char *from, const char *to, const SalBody *body){ if (op->dialog){ - belle_sip_request_t *req=belle_sip_dialog_create_queued_request(op->dialog,"INFO"); + belle_sip_request_t *req; + belle_sip_dialog_enable_pending_trans_checking(op->dialog,op->base.root->pending_trans_checking); + req=belle_sip_dialog_create_queued_request(op->dialog,"INFO"); sal_op_add_body(op,(belle_sip_message_t*)req,body); return sal_op_send_request(op,req); } diff --git a/coreapi/bellesip_sal/sal_op_presence.c b/coreapi/bellesip_sal/sal_op_presence.c index 6de0a0fbf..f5ec79ad8 100644 --- a/coreapi/bellesip_sal/sal_op_presence.c +++ b/coreapi/bellesip_sal/sal_op_presence.c @@ -47,42 +47,41 @@ void sal_add_presence_info(SalOp *op, belle_sip_message_t *notify, SalPresenceMo } static void presence_process_io_error(void *user_ctx, const belle_sip_io_error_event_t *event){ - ms_error("presence_process_io_error not implemented yet"); + /*ms_error("presence_process_io_error not implemented yet");*/ } static void presence_process_dialog_terminated(void *ctx, const belle_sip_dialog_terminated_event_t *event) { SalOp* op= (SalOp*)ctx; if (op->dialog) { - sal_op_unref(op); - op->dialog=NULL; + if (belle_sip_dialog_is_server(op->dialog)){ + ms_message("Incoming subscribtion from [%s] terminated",sal_op_get_from(op)); + if (!op->op_released){ + op->base.root->callbacks.subscribe_presence_closed(op, sal_op_get_from(op)); + } + } + set_or_update_dialog(op, NULL); } } static void presence_refresher_listener(belle_sip_refresher_t* refresher, void* user_pointer, unsigned int status_code, const char* reason_phrase){ SalOp* op = (SalOp*)user_pointer; - switch(status_code){ - case 481: { - - ms_message("The server or remote ua lost the SUBSCRIBE dialog context. Let's restart a new one."); - belle_sip_refresher_stop(op->refresher); - if (op->dialog) { /*delete previous dialog if any*/ - belle_sip_dialog_set_application_data(op->dialog,NULL); - belle_sip_object_unref(op->dialog); - op->dialog=NULL; - } - - if (sal_op_get_contact_address(op)) { - /*contact is also probably not good*/ - SalAddress* contact=sal_address_clone(sal_op_get_contact_address(op)); - sal_address_set_port(contact,-1); - sal_address_set_domain(contact,NULL); - sal_op_set_contact_address(op,contact); - sal_address_destroy(contact); - } - - sal_subscribe_presence(op,NULL,NULL,-1); - break; + if (status_code >= 300) { + ms_message("The SUBSCRIBE dialog no longer works. Let's restart a new one."); + belle_sip_refresher_stop(op->refresher); + if (op->dialog) { /*delete previous dialog if any*/ + set_or_update_dialog(op, NULL); } + + if (sal_op_get_contact_address(op)) { + /*contact is also probably not good*/ + SalAddress* contact=sal_address_clone(sal_op_get_contact_address(op)); + sal_address_set_port(contact,-1); + sal_address_set_domain(contact,NULL); + sal_op_set_contact_address(op,contact); + sal_address_destroy(contact); + } + /*send a new SUBSCRIBE, that will attempt to establish a new dialog*/ + sal_subscribe_presence(op,NULL,NULL,-1); } } @@ -99,9 +98,13 @@ static void presence_response_event(void *op_base, const belle_sip_response_even sal_op_set_error_info_from_response(op,response); if (code>=300) { - ms_message("subscription to [%s] rejected",sal_op_get_to(op)); - op->base.root->callbacks.notify_presence(op,SalSubscribeTerminated, NULL,NULL); /*NULL = offline*/ - return; + if (strcmp("SUBSCRIBE",belle_sip_request_get_method(request))==0){ + ms_message("subscription to [%s] rejected",sal_op_get_to(op)); + if (!op->op_released){ + op->base.root->callbacks.notify_presence(op,SalSubscribeTerminated, NULL,NULL); /*NULL = offline*/ + } + return; + } } set_or_update_dialog(op_base,belle_sip_response_event_get_dialog(event)); if (!op->dialog) { @@ -144,11 +147,23 @@ static void presence_response_event(void *op_base, const belle_sip_response_even } /* no break */ } - - } + static void presence_process_timeout(void *user_ctx, const belle_sip_timeout_event_t *event) { - ms_error("presence_process_timeout not implemented yet"); + SalOp* op = (SalOp*)user_ctx; + belle_sip_client_transaction_t* client_transaction = belle_sip_timeout_event_get_client_transaction(event); + belle_sip_request_t* request; + + if (!client_transaction) return; + + request = belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(client_transaction)); + + if (strcmp("SUBSCRIBE",belle_sip_request_get_method(request))==0){ + ms_message("subscription to [%s] timeout",sal_op_get_to(op)); + if (!op->op_released){ + op->base.root->callbacks.notify_presence(op,SalSubscribeTerminated, NULL,NULL); /*NULL = offline*/ + } + } } static void presence_process_transaction_terminated(void *user_ctx, const belle_sip_transaction_terminated_event_t *event) { @@ -167,25 +182,30 @@ static SalPresenceModel * process_presence_notification(SalOp *op, belle_sip_req return NULL; if (body==NULL) return NULL; - - op->base.root->callbacks.parse_presence_requested(op, + if (!op->op_released){ + op->base.root->callbacks.parse_presence_requested(op, belle_sip_header_content_type_get_type(content_type), belle_sip_header_content_type_get_subtype(content_type), body, &result); + } return result; } -static void handle_notify(SalOp *op, belle_sip_request_t *req){ +static void handle_notify(SalOp *op, belle_sip_request_t *req, belle_sip_dialog_t *dialog){ belle_sip_response_t* resp=NULL; belle_sip_server_transaction_t* server_transaction=op->pending_server_trans; belle_sip_header_subscription_state_t* subscription_state_header=belle_sip_message_get_header_by_type(req,belle_sip_header_subscription_state_t); SalSubscribeStatus sub_state; - + if (strcmp("NOTIFY",belle_sip_request_get_method(req))==0) { SalPresenceModel *presence_model = NULL; const char* body = belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)); + + if (op->dialog !=NULL && dialog != op->dialog){ + ms_warning("Receiving a NOTIFY from a dialog we haven't stored (op->dialog=%p dialog=%p)", op->dialog, dialog); + } if (!subscription_state_header || strcasecmp(BELLE_SIP_SUBSCRIPTION_STATE_TERMINATED,belle_sip_header_subscription_state_get_state(subscription_state_header)) ==0) { sub_state=SalSubscribeTerminated; ms_message("Outgoing subscription terminated by remote [%s]",sal_op_get_to(op)); @@ -197,7 +217,9 @@ static void handle_notify(SalOp *op, belle_sip_request_t *req){ /* Presence notification body parsed successfully. */ resp = sal_op_create_response_from_request(op, req, 200); /*create first because the op may be destroyed by notify_presence */ - op->base.root->callbacks.notify_presence(op, sub_state, presence_model, NULL); + if (!op->op_released){ + op->base.root->callbacks.notify_presence(op, sub_state, presence_model, NULL); + } } else if (body){ /* Formatting error in presence notification body. */ ms_warning("Wrongly formatted presence document."); @@ -212,7 +234,6 @@ static void presence_process_request_event(void *op_base, const belle_sip_reques belle_sip_server_transaction_t* server_transaction = belle_sip_provider_create_server_transaction(op->base.root->prov,belle_sip_request_event_get_request(event)); belle_sip_request_t* req = belle_sip_request_event_get_request(event); belle_sip_dialog_state_t dialog_state; - belle_sip_header_expires_t* expires = belle_sip_message_get_header_by_type(req,belle_sip_header_expires_t); belle_sip_response_t* resp; const char *method=belle_sip_request_get_method(req); @@ -223,13 +244,12 @@ static void presence_process_request_event(void *op_base, const belle_sip_reques if (!op->dialog) { if (strcmp(method,"SUBSCRIBE")==0){ - op->dialog=belle_sip_provider_create_dialog(op->base.root->prov,BELLE_SIP_TRANSACTION(server_transaction)); - belle_sip_dialog_set_application_data(op->dialog,op); - sal_op_ref(op); + belle_sip_dialog_t *dialog = belle_sip_provider_create_dialog(op->base.root->prov,BELLE_SIP_TRANSACTION(server_transaction)); + set_or_update_dialog(op, dialog); ms_message("new incoming subscription from [%s] to [%s]",sal_op_get_from(op),sal_op_get_to(op)); }else{ /* this is a NOTIFY */ ms_message("Receiving out of dialog notify"); - handle_notify(op,req); + handle_notify(op, req, belle_sip_request_event_get_dialog(event)); return; } } @@ -245,16 +265,13 @@ static void presence_process_request_event(void *op_base, const belle_sip_reques case BELLE_SIP_DIALOG_CONFIRMED: if (strcmp("NOTIFY",method)==0) { - handle_notify(op,req); + handle_notify(op, req, belle_sip_request_event_get_dialog(event)); } else if (strcmp("SUBSCRIBE",method)==0) { - /*either a refresh or an unsubscribe*/ - if (expires && belle_sip_header_expires_get_expires(expires)>0) { - op->base.root->callbacks.subscribe_presence_received(op,sal_op_get_from(op)); - } else if(expires) { - ms_message("Unsubscribe received from [%s]",sal_op_get_from(op)); - resp=sal_op_create_response_from_request(op,req,200); - belle_sip_server_transaction_send_response(server_transaction,resp); - } + /*either a refresh or an unsubscribe. + If it is a refresh there is nothing to notify to the app. If it is an unSUBSCRIBE, then the dialog + will be terminated shortly, and this will be notified to the app through the dialog_terminated callback.*/ + resp=sal_op_create_response_from_request(op,req,200); + belle_sip_server_transaction_send_response(server_transaction,resp); } break; default: @@ -330,8 +347,8 @@ static int sal_op_check_dialog_state(SalOp *op) { return -1; } else return 0; - } + int sal_notify_presence(SalOp *op, SalPresenceModel *presence){ belle_sip_request_t* notify=NULL; if (sal_op_check_dialog_state(op)) { diff --git a/coreapi/bellesip_sal/sal_op_registration.c b/coreapi/bellesip_sal/sal_op_registration.c index d56587db2..961ba4a34 100644 --- a/coreapi/bellesip_sal/sal_op_registration.c +++ b/coreapi/bellesip_sal/sal_op_registration.c @@ -40,6 +40,7 @@ static void register_refresher_listener (belle_sip_refresher_t* refresher /*check service route rfc3608*/ belle_sip_header_service_route_t* service_route; belle_sip_header_address_t* service_route_address=NULL; + belle_sip_header_contact_t *contact = belle_sip_refresher_get_contact(refresher); if ((service_route=belle_sip_message_get_header_by_type(response,belle_sip_header_service_route_t))) { service_route_address=belle_sip_header_address_create(NULL,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(service_route))); } @@ -47,6 +48,9 @@ static void register_refresher_listener (belle_sip_refresher_t* refresher if (service_route_address) belle_sip_object_unref(service_route_address); sal_remove_pending_auth(op->base.root,op); /*just in case*/ + if (contact) { + sal_op_set_contact_address(op,(SalAddress*)(BELLE_SIP_HEADER_ADDRESS(contact))); /*update contact with real value*/ + } op->base.root->callbacks.register_success(op,belle_sip_refresher_get_expires(op->refresher)>0); } else if (status_code>=400) { /* from rfc3608, 6.1. @@ -71,7 +75,7 @@ static void register_refresher_listener (belle_sip_refresher_t* refresher } } -int sal_register(SalOp *op, const char *proxy, const char *from, int expires){ +int sal_register(SalOp *op, const char *proxy, const char *from, int expires,SalAddress* old_contact){ belle_sip_request_t *req; belle_sip_uri_t* req_uri; belle_sip_header_t* accept_header; @@ -96,6 +100,19 @@ int sal_register(SalOp *op, const char *proxy, const char *from, int expires){ accept_header = belle_sip_header_create("Accept", "application/sdp, text/plain, application/vnd.gsma.rcs-ft-http+xml"); belle_sip_message_add_header(BELLE_SIP_MESSAGE(req), accept_header); belle_sip_message_set_header(BELLE_SIP_MESSAGE(req),(belle_sip_header_t*)sal_op_create_contact(op)); + if (old_contact) { + belle_sip_header_contact_t *contact=belle_sip_header_contact_create((const belle_sip_header_address_t *)old_contact); + if (contact) { + char * tmp; + belle_sip_header_contact_set_expires(contact,0); /*remove old aor*/ + belle_sip_message_add_header(BELLE_SIP_MESSAGE(req), BELLE_SIP_HEADER(contact)); + tmp = belle_sip_object_to_string(contact); + ms_message("Clearing contact [%s] for op [%p]",tmp,op); + ms_free(tmp); + } else { + ms_error("Cannot add old contact header to op [%p]",op); + } + } return sal_op_send_and_create_refresher(op,req,expires,register_refresher_listener); } diff --git a/coreapi/bellesip_sal/sal_sdp.c b/coreapi/bellesip_sal/sal_sdp.c index b254c67d8..3d5934f1c 100644 --- a/coreapi/bellesip_sal/sal_sdp.c +++ b/coreapi/bellesip_sal/sal_sdp.c @@ -93,6 +93,14 @@ static void add_rtcp_fb_trr_int_attribute(belle_sdp_media_description_t *media_d belle_sdp_media_description_add_attribute(media_desc, BELLE_SDP_ATTRIBUTE(attribute)); } +static void add_rtcp_fb_ack_attribute(belle_sdp_media_description_t *media_desc, int8_t id, belle_sdp_rtcp_fb_val_param_t param) { + belle_sdp_rtcp_fb_attribute_t *attribute = belle_sdp_rtcp_fb_attribute_new(); + belle_sdp_rtcp_fb_attribute_set_id(attribute, id); + belle_sdp_rtcp_fb_attribute_set_type(attribute, BELLE_SDP_RTCP_FB_ACK); + belle_sdp_rtcp_fb_attribute_set_param(attribute, param); + belle_sdp_media_description_add_attribute(media_desc, BELLE_SDP_ATTRIBUTE(attribute)); +} + static void add_rtcp_fb_nack_attribute(belle_sdp_media_description_t *media_desc, int8_t id, belle_sdp_rtcp_fb_val_param_t param) { belle_sdp_rtcp_fb_attribute_t *attribute = belle_sdp_rtcp_fb_attribute_new(); belle_sdp_rtcp_fb_attribute_set_id(attribute, id); @@ -120,6 +128,12 @@ static void add_rtcp_fb_attributes(belle_sdp_media_description_t *media_desc, co if (general_trr_int == TRUE) { add_rtcp_fb_trr_int_attribute(media_desc, -1, trr_int); } + if (stream->rtcp_fb.generic_nack_enabled == TRUE) { + add_rtcp_fb_nack_attribute(media_desc, -1, BELLE_SDP_RTCP_FB_NONE); + } + if (stream->rtcp_fb.tmmbr_enabled == TRUE) { + add_rtcp_fb_ccm_attribute(media_desc, -1, BELLE_SDP_RTCP_FB_TMMBR); + } for (pt_it = stream->payloads; pt_it != NULL; pt_it = pt_it->next) { pt = (PayloadType *)pt_it->data; @@ -141,7 +155,11 @@ static void add_rtcp_fb_attributes(belle_sdp_media_description_t *media_desc, co add_rtcp_fb_nack_attribute(media_desc, payload_type_get_number(pt), BELLE_SDP_RTCP_FB_SLI); } if (avpf_params.features & PAYLOAD_TYPE_AVPF_RPSI) { - add_rtcp_fb_nack_attribute(media_desc, payload_type_get_number(pt), BELLE_SDP_RTCP_FB_RPSI); + if (avpf_params.rpsi_compatibility == TRUE) { + add_rtcp_fb_nack_attribute(media_desc, payload_type_get_number(pt), BELLE_SDP_RTCP_FB_RPSI); + } else { + add_rtcp_fb_ack_attribute(media_desc, payload_type_get_number(pt), BELLE_SDP_RTCP_FB_RPSI); + } } if (avpf_params.features & PAYLOAD_TYPE_AVPF_FIR) { add_rtcp_fb_ccm_attribute(media_desc, payload_type_get_number(pt), BELLE_SDP_RTCP_FB_FIR); @@ -232,7 +250,7 @@ static void stream_description_to_sdp ( belle_sdp_session_description_t *session if ( stream->bandwidth>0 ) belle_sdp_media_description_set_bandwidth ( media_desc,"AS",stream->bandwidth ); - if ((stream->proto == SalProtoRtpSavpf) || (stream->proto == SalProtoRtpSavp)) { + if (sal_stream_description_has_srtp(stream)) { /* add crypto lines */ for ( j=0; jproto == SalProtoUdpTlsRtpSavpf) || (stream->proto == SalProtoUdpTlsRtpSavp)) { - char* ssrc_attribute = ms_strdup_printf("%u cname:%s",htonl(stream->rtp_ssrc),stream->rtcp_cname); + char* ssrc_attribute = ms_strdup_printf("%u cname:%s",stream->rtp_ssrc,stream->rtcp_cname); if ((stream->dtls_role != SalDtlsRoleInvalid) && (strlen(stream->dtls_fingerprint)>0)) { switch(stream->dtls_role) { case SalDtlsRoleIsClient: @@ -265,7 +283,7 @@ static void stream_description_to_sdp ( belle_sdp_session_description_t *session } belle_sdp_media_description_add_attribute(media_desc, belle_sdp_attribute_create("fingerprint",stream->dtls_fingerprint)); } - belle_sdp_media_description_add_attribute(media_desc, belle_sdp_attribute_create("ssrc",ssrc_attribute)); /* truc de Jehan a virer? */ + belle_sdp_media_description_add_attribute(media_desc, belle_sdp_attribute_create("ssrc",ssrc_attribute)); ms_free(ssrc_attribute); } @@ -286,6 +304,10 @@ static void stream_description_to_sdp ( belle_sdp_session_description_t *session } if ( dir ) belle_sdp_media_description_add_attribute ( media_desc,belle_sdp_attribute_create ( dir,NULL ) ); + if (stream->rtcp_mux){ + belle_sdp_media_description_add_attribute(media_desc, belle_sdp_attribute_create ("rtcp-mux",NULL ) ); + } + if (rtp_port != 0) { different_rtp_and_rtcp_addr = (rtcp_addr[0] != '\0') && (strcmp(rtp_addr, rtcp_addr) != 0); if ((rtcp_port != (rtp_port + 1)) || (different_rtp_and_rtcp_addr == TRUE)) { @@ -313,7 +335,7 @@ static void stream_description_to_sdp ( belle_sdp_session_description_t *session } } - if ((rtp_port != 0) && ((stream->proto == SalProtoRtpAvpf) || (stream->proto == SalProtoRtpSavpf))) { + if ((rtp_port != 0) && sal_stream_description_has_avpf(stream)) { add_rtcp_fb_attributes(media_desc, md, stream); } @@ -337,6 +359,16 @@ static void stream_description_to_sdp ( belle_sdp_session_description_t *session belle_sip_object_unref((belle_sip_object_t*)media_attribute); } } + + if (stream->custom_sdp_attributes) { + belle_sdp_session_description_t *custom_desc = (belle_sdp_session_description_t *)stream->custom_sdp_attributes; + belle_sip_list_t *l = belle_sdp_session_description_get_attributes(custom_desc); + belle_sip_list_t *elem; + for (elem = l; elem != NULL; elem = elem->next) { + belle_sdp_media_description_add_attribute(media_desc, (belle_sdp_attribute_t *)elem->data); + } + } + /* * rfc5576 * 4.1. The "ssrc" Media Attribute @@ -397,6 +429,14 @@ belle_sdp_session_description_t * media_description_to_sdp ( const SalMediaDescr if (desc->rtcp_xr.enabled == TRUE) { belle_sdp_session_description_add_attribute(session_desc, create_rtcp_xr_attribute(&desc->rtcp_xr)); } + if (desc->custom_sdp_attributes) { + belle_sdp_session_description_t *custom_desc = (belle_sdp_session_description_t *)desc->custom_sdp_attributes; + belle_sip_list_t *l = belle_sdp_session_description_get_attributes(custom_desc); + belle_sip_list_t *elem; + for (elem = l; elem != NULL; elem = elem->next) { + belle_sdp_session_description_add_attribute(session_desc, (belle_sdp_attribute_t *)elem->data); + } + } for ( i=0; inb_streams; i++ ) { stream_description_to_sdp(session_desc, desc, &desc->streams[i]); @@ -538,9 +578,14 @@ static void enable_avpf_for_stream(SalStreamDescription *stream) { } } -static void apply_rtcp_fb_attribute_to_payload(belle_sdp_rtcp_fb_attribute_t *fb_attribute, PayloadType *pt) { +static void apply_rtcp_fb_attribute_to_payload(belle_sdp_rtcp_fb_attribute_t *fb_attribute, SalStreamDescription *stream, PayloadType *pt) { PayloadTypeAvpfParams avpf_params = payload_type_get_avpf_params(pt); switch (belle_sdp_rtcp_fb_attribute_get_type(fb_attribute)) { + case BELLE_SDP_RTCP_FB_ACK: + if (belle_sdp_rtcp_fb_attribute_get_param(fb_attribute) == BELLE_SDP_RTCP_FB_RPSI) { + avpf_params.features |= PAYLOAD_TYPE_AVPF_RPSI; + } + break; case BELLE_SDP_RTCP_FB_NACK: switch (belle_sdp_rtcp_fb_attribute_get_param(fb_attribute)) { case BELLE_SDP_RTCP_FB_PLI: @@ -550,9 +595,15 @@ static void apply_rtcp_fb_attribute_to_payload(belle_sdp_rtcp_fb_attribute_t *fb avpf_params.features |= PAYLOAD_TYPE_AVPF_SLI; break; case BELLE_SDP_RTCP_FB_RPSI: + /* Linphone uses positive feeback for RPSI. However first versions handling + * AVPF wrongly declared RPSI as negative feedback, so this is kept for compatibility + * with these versions but will probably be removed at some point in time. */ avpf_params.features |= PAYLOAD_TYPE_AVPF_RPSI; + avpf_params.rpsi_compatibility = TRUE; break; case BELLE_SDP_RTCP_FB_NONE: + stream->rtcp_fb.generic_nack_enabled = TRUE; + break; default: break; } @@ -565,11 +616,13 @@ static void apply_rtcp_fb_attribute_to_payload(belle_sdp_rtcp_fb_attribute_t *fb case BELLE_SDP_RTCP_FB_FIR: avpf_params.features |= PAYLOAD_TYPE_AVPF_FIR; break; + case BELLE_SDP_RTCP_FB_TMMBR: + stream->rtcp_fb.tmmbr_enabled = TRUE; + break; default: break; } break; - case BELLE_SDP_RTCP_FB_ACK: default: break; } @@ -584,15 +637,6 @@ static void sdp_parse_rtcp_fb_parameters(belle_sdp_media_description_t *media_de PayloadType *pt; int8_t pt_num; - /* Clear the AVPF features for all payload types. */ - for (pt_it = stream->payloads; pt_it != NULL; pt_it = pt_it->next) { - PayloadTypeAvpfParams avpf_params; - pt = (PayloadType *)pt_it->data; - avpf_params = payload_type_get_avpf_params(pt); - avpf_params.features = PAYLOAD_TYPE_AVPF_NONE; - payload_type_set_avpf_params(pt, avpf_params); - } - /* Handle rtcp-fb attributes that concern all payload types. */ for (it = belle_sdp_media_description_get_attributes(media_desc); it != NULL; it = it->next) { attribute = BELLE_SDP_ATTRIBUTE(it->data); @@ -601,7 +645,7 @@ static void sdp_parse_rtcp_fb_parameters(belle_sdp_media_description_t *media_de if (belle_sdp_rtcp_fb_attribute_get_id(fb_attribute) == -1) { for (pt_it = stream->payloads; pt_it != NULL; pt_it = pt_it->next) { pt = (PayloadType *)pt_it->data; - apply_rtcp_fb_attribute_to_payload(fb_attribute, pt); + apply_rtcp_fb_attribute_to_payload(fb_attribute, stream, pt); } } } @@ -616,7 +660,7 @@ static void sdp_parse_rtcp_fb_parameters(belle_sdp_media_description_t *media_de for (pt_it = stream->payloads; pt_it != NULL; pt_it = pt_it->next) { pt = (PayloadType *)pt_it->data; if (payload_type_get_number(pt) == (int)pt_num) { - apply_rtcp_fb_attribute_to_payload(fb_attribute, pt); + apply_rtcp_fb_attribute_to_payload(fb_attribute, stream, pt); } } } @@ -680,6 +724,7 @@ static SalStreamDescription * sdp_to_stream_description(SalMediaDescription *md, belle_sdp_connection_t* cnx; belle_sdp_media_t* media; belle_sdp_attribute_t* attribute; + belle_sip_list_t *custom_attribute_it; const char* value; const char *mtype,*proto; @@ -717,6 +762,8 @@ static SalStreamDescription * sdp_to_stream_description(SalMediaDescription *md, stream->type=SalAudio; } else if ( strcasecmp ( "video", mtype ) == 0 ) { stream->type=SalVideo; + } else if ( strcasecmp ( "text", mtype ) == 0 ) { + stream->type=SalText; } else { stream->type=SalOther; strncpy ( stream->typeother,mtype,sizeof ( stream->typeother )-1 ); @@ -738,6 +785,8 @@ static SalStreamDescription * sdp_to_stream_description(SalMediaDescription *md, stream->dir=md->dir; /*takes default value if not present*/ } + stream->rtcp_mux = belle_sdp_media_description_get_attribute(media_desc, "rtcp-mux") != NULL; + /* Get media payload types */ sdp_parse_payload_types(media_desc, stream); @@ -775,7 +824,7 @@ static SalStreamDescription * sdp_to_stream_description(SalMediaDescription *md, } /* Read crypto lines if any */ - if ((stream->proto == SalProtoRtpSavpf) || (stream->proto == SalProtoRtpSavp)) { + if (sal_stream_description_has_srtp(stream)) { sdp_parse_media_crypto_parameters(media_desc, stream); } @@ -783,7 +832,7 @@ static SalStreamDescription * sdp_to_stream_description(SalMediaDescription *md, sdp_parse_media_ice_parameters(media_desc, stream); /* Get RTCP-FB attributes if any */ - if ((stream->proto == SalProtoRtpAvpf) || (stream->proto == SalProtoRtpSavpf)) { + if (sal_stream_description_has_avpf(stream)) { enable_avpf_for_stream(stream); sdp_parse_rtcp_fb_parameters(media_desc, stream); } @@ -792,6 +841,12 @@ static SalStreamDescription * sdp_to_stream_description(SalMediaDescription *md, stream->rtcp_xr = md->rtcp_xr; // Use session parameters if no stream parameters are defined sdp_parse_media_rtcp_xr_parameters(media_desc, &stream->rtcp_xr); + /* Get the custom attributes */ + for (custom_attribute_it = belle_sdp_media_description_get_attributes(media_desc); custom_attribute_it != NULL; custom_attribute_it = custom_attribute_it->next) { + belle_sdp_attribute_t *attr = (belle_sdp_attribute_t *)custom_attribute_it->data; + stream->custom_sdp_attributes = sal_custom_sdp_attribute_append(stream->custom_sdp_attributes, belle_sdp_attribute_get_name(attr), belle_sdp_attribute_get_value(attr)); + } + md->nb_streams++; return stream; } @@ -802,6 +857,7 @@ int sdp_to_media_description ( belle_sdp_session_description_t *session_desc, S belle_sip_list_t* media_desc_it; belle_sdp_media_description_t* media_desc; belle_sdp_session_name_t *sname; + belle_sip_list_t *custom_attribute_it; const char* value; SalDtlsRole session_role=SalDtlsRoleInvalid; int i; @@ -863,6 +919,12 @@ int sdp_to_media_description ( belle_sdp_session_description_t *session_desc, S /* Get session RTCP-XR attributes if any */ sdp_parse_session_rtcp_xr_parameters(session_desc, &desc->rtcp_xr); + /* Get the custom attributes */ + for (custom_attribute_it = belle_sdp_session_description_get_attributes(session_desc); custom_attribute_it != NULL; custom_attribute_it = custom_attribute_it->next) { + belle_sdp_attribute_t *attr = (belle_sdp_attribute_t *)custom_attribute_it->data; + desc->custom_sdp_attributes = sal_custom_sdp_attribute_append(desc->custom_sdp_attributes, belle_sdp_attribute_get_name(attr), belle_sdp_attribute_get_value(attr)); + } + for ( media_desc_it=belle_sdp_session_description_get_media_descriptions ( session_desc ) ; media_desc_it!=NULL ; media_desc_it=media_desc_it->next ) { diff --git a/coreapi/call_log.c b/coreapi/call_log.c index d1750df56..2bf8d5b9f 100644 --- a/coreapi/call_log.c +++ b/coreapi/call_log.c @@ -22,6 +22,20 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include "private.h" +#ifdef CALL_LOGS_STORAGE_ENABLED +#ifndef _WIN32 +#if !defined(ANDROID) && !defined(__QNXNTO__) +# include +# include +# include +#endif +#else +#include +#endif + +#define MAX_PATH_SIZE 1024 +#include "sqlite3.h" +#endif /******************************************************************************* * Internal functions * @@ -33,7 +47,7 @@ static size_t my_strftime(char *s, size_t max, const char *fmt, const struct t } static time_t string_to_time(const char *date){ -#ifndef WIN32 +#ifndef _WIN32 struct tm tmtime={0}; strptime(date,"%c",&tmtime); return mktime(&tmtime); @@ -44,7 +58,7 @@ static time_t string_to_time(const char *date){ static void set_call_log_date(LinphoneCallLog *cl, time_t start_time){ struct tm loctime; -#ifdef WIN32 +#ifdef _WIN32 #if !defined(_WIN32_WCE) loctime=*localtime(&start_time); /*FIXME*/ @@ -260,16 +274,17 @@ void linphone_call_log_unref(LinphoneCallLog *cl) { * Constructor and destructor functions * ******************************************************************************/ -static void _linphone_call_log_destroy(LinphoneCallLog *cl){ +static void _linphone_call_log_destroy(LinphoneCallLog *cl) { if (cl->from!=NULL) linphone_address_destroy(cl->from); if (cl->to!=NULL) linphone_address_destroy(cl->to); if (cl->refkey!=NULL) ms_free(cl->refkey); if (cl->call_id) ms_free(cl->call_id); if (cl->reporting.reports[LINPHONE_CALL_STATS_AUDIO]!=NULL) linphone_reporting_destroy(cl->reporting.reports[LINPHONE_CALL_STATS_AUDIO]); if (cl->reporting.reports[LINPHONE_CALL_STATS_VIDEO]!=NULL) linphone_reporting_destroy(cl->reporting.reports[LINPHONE_CALL_STATS_VIDEO]); + if (cl->reporting.reports[LINPHONE_CALL_STATS_TEXT]!=NULL) linphone_reporting_destroy(cl->reporting.reports[LINPHONE_CALL_STATS_TEXT]); } -LinphoneCallLog * linphone_call_log_new(LinphoneCallDir dir, LinphoneAddress *from, LinphoneAddress *to){ +LinphoneCallLog * linphone_call_log_new(LinphoneCallDir dir, LinphoneAddress *from, LinphoneAddress *to) { LinphoneCallLog *cl=belle_sip_object_new(LinphoneCallLog); cl->dir=dir; cl->start_date_time=time(NULL); @@ -278,9 +293,11 @@ LinphoneCallLog * linphone_call_log_new(LinphoneCallDir dir, LinphoneAddress *fr cl->to=to; cl->status=LinphoneCallAborted; /*default status*/ cl->quality=-1; + cl->storage_id=0; cl->reporting.reports[LINPHONE_CALL_STATS_AUDIO]=linphone_reporting_new(); cl->reporting.reports[LINPHONE_CALL_STATS_VIDEO]=linphone_reporting_new(); + cl->reporting.reports[LINPHONE_CALL_STATS_TEXT]=linphone_reporting_new(); cl->connected_date_time=0; return cl; } @@ -298,3 +315,392 @@ BELLE_SIP_INSTANCIATE_VPTR(LinphoneCallLog, belle_sip_object_t, NULL, // marshal FALSE ); + + +/******************************************************************************* + * SQL storage related functions * + ******************************************************************************/ + +#ifdef CALL_LOGS_STORAGE_ENABLED + +static void linphone_create_table(sqlite3* db) { + char* errmsg=NULL; + int ret; + ret=sqlite3_exec(db,"CREATE TABLE IF NOT EXISTS call_history (" + "id INTEGER PRIMARY KEY AUTOINCREMENT," + "caller TEXT NOT NULL," // Can't name a field "from"... + "callee TEXT NOT NULL," + "direction INTEGER," + "duration INTEGER," + "start_time TEXT NOT NULL," + "connected_time TEXT NOT NULL," + "status INTEGER," + "videoEnabled INTEGER," + "quality REAL" + ");", + 0,0,&errmsg); + if(ret != SQLITE_OK) { + ms_error("Error in creation: %s.\n", errmsg); + sqlite3_free(errmsg); + } +} + +void linphone_update_call_log_table(sqlite3* db) { + char* errmsg=NULL; + int ret; + + // for image url storage + ret=sqlite3_exec(db,"ALTER TABLE call_history ADD COLUMN call_id TEXT;",NULL,NULL,&errmsg); + if(ret != SQLITE_OK) { + ms_message("Table already up to date: %s.", errmsg); + sqlite3_free(errmsg); + } else { + ret=sqlite3_exec(db,"ALTER TABLE call_history ADD COLUMN refkey TEXT;",NULL,NULL,&errmsg); + if(ret != SQLITE_OK) { + ms_message("Table already up to date: %s.", errmsg); + sqlite3_free(errmsg); + } else { + ms_debug("Table call_history updated successfully for call_id and refkey."); + } + } +} + +void linphone_core_call_log_storage_init(LinphoneCore *lc) { + int ret; + const char *errmsg; + sqlite3 *db; + + linphone_core_call_log_storage_close(lc); + + ret=_linphone_sqlite3_open(lc->logs_db_file, &db); + if(ret != SQLITE_OK) { + errmsg = sqlite3_errmsg(db); + ms_error("Error in the opening: %s.\n", errmsg); + sqlite3_close(db); + return; + } + + linphone_create_table(db); + linphone_update_call_log_table(db); + lc->logs_db = db; + + // Load the existing call logs + linphone_core_get_call_history(lc); +} + +void linphone_core_call_log_storage_close(LinphoneCore *lc) { + if (lc->logs_db){ + sqlite3_close(lc->logs_db); + lc->logs_db = NULL; + } +} + +/* DB layout: + * | 0 | storage_id + * | 1 | from + * | 2 | to + * | 3 | direction flag + * | 4 | duration + * | 5 | start date time (time_t) + * | 6 | connected date time (time_t) + * | 7 | status + * | 8 | video enabled (1 or 0) + * | 9 | quality + * | 10 | call_id + * | 11 | refkey + */ +static int create_call_log(void *data, int argc, char **argv, char **colName) { + MSList **list = (MSList **)data; + LinphoneAddress *from; + LinphoneAddress *to; + LinphoneCallDir dir; + LinphoneCallLog *log; + + unsigned int storage_id = atoi(argv[0]); + from = linphone_address_new(argv[1]); + to = linphone_address_new(argv[2]); + dir = (LinphoneCallDir) atoi(argv[3]); + log = linphone_call_log_new(dir, from, to); + + log->storage_id = storage_id; + log->duration = atoi(argv[4]); + log->start_date_time = (time_t)atol(argv[5]); + set_call_log_date(log,log->start_date_time); + log->connected_date_time = (time_t)atol(argv[6]); + log->status = (LinphoneCallStatus) atoi(argv[7]); + log->video_enabled = atoi(argv[8]) == 1; + log->quality = atof(argv[9]); + + if (argc > 10) { + if (argv[10] != NULL) { + log->call_id = ms_strdup(argv[10]); + } + if (argv[10] != NULL) { + log->refkey = ms_strdup(argv[11]); + } + } + + *list = ms_list_append(*list, log); + + return 0; +} + +void linphone_sql_request_call_log(sqlite3 *db, const char *stmt, MSList **list) { + char* errmsg = NULL; + int ret; + ret = sqlite3_exec(db, stmt, create_call_log, list, &errmsg); + if (ret != SQLITE_OK) { + ms_error("linphone_sql_request: statement %s -> error sqlite3_exec(): %s.", stmt, errmsg); + sqlite3_free(errmsg); + } +} + +int linphone_sql_request_generic(sqlite3* db, const char *stmt) { + char* errmsg = NULL; + int ret; + ret = sqlite3_exec(db, stmt, NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + ms_error("linphone_sql_request: statement %s -> error sqlite3_exec(): %s.", stmt, errmsg); + sqlite3_free(errmsg); + } + return ret; +} + +void linphone_core_store_call_log(LinphoneCore *lc, LinphoneCallLog *log) { + if (lc && lc->logs_db){ + char *from, *to; + char *buf; + + from = linphone_address_as_string(log->from); + to = linphone_address_as_string(log->to); + buf = sqlite3_mprintf("INSERT INTO call_history VALUES(NULL,%Q,%Q,%i,%i,%lld,%lld,%i,%i,%f,%Q,%Q);", + from, + to, + log->dir, + log->duration, + (int64_t)log->start_date_time, + (int64_t)log->connected_date_time, + log->status, + log->video_enabled ? 1 : 0, + log->quality, + log->call_id, + log->refkey + ); + linphone_sql_request_generic(lc->logs_db, buf); + sqlite3_free(buf); + ms_free(from); + ms_free(to); + + log->storage_id = sqlite3_last_insert_rowid(lc->logs_db); + } + + if (lc) { + lc->call_logs = ms_list_prepend(lc->call_logs, linphone_call_log_ref(log)); + } +} + +static void copy_user_data_from_existing_log(MSList *existing_logs, LinphoneCallLog *log) { + while (existing_logs) { + LinphoneCallLog *existing_log = (LinphoneCallLog *)existing_logs->data; + if (existing_log->storage_id == log->storage_id) { + log->user_data = existing_log->user_data; + break; + } + existing_logs = ms_list_next(existing_logs); + } +} + +static void copy_user_data_from_existing_logs(MSList *existing_logs, MSList *new_logs) { + while (new_logs) { + LinphoneCallLog *new_log = (LinphoneCallLog *)new_logs->data; + copy_user_data_from_existing_log(existing_logs, new_log); + new_logs = ms_list_next(new_logs); + } +} + +const MSList *linphone_core_get_call_history(LinphoneCore *lc) { + char *buf; + uint64_t begin,end; + MSList *result = NULL; + + if (!lc || lc->logs_db == NULL) return NULL; + + buf = sqlite3_mprintf("SELECT * FROM call_history ORDER BY id DESC LIMIT %i", lc->max_call_logs); + + begin = ortp_get_cur_time_ms(); + linphone_sql_request_call_log(lc->logs_db, buf, &result); + end = ortp_get_cur_time_ms(); + ms_message("%s(): completed in %i ms",__FUNCTION__, (int)(end-begin)); + sqlite3_free(buf); + + if (lc->call_logs) { + copy_user_data_from_existing_logs(lc->call_logs, result); + } + + lc->call_logs = ms_list_free_with_data(lc->call_logs, (void (*)(void*))linphone_call_log_unref); + lc->call_logs = result; + + return lc->call_logs; +} + +void linphone_core_delete_call_history(LinphoneCore *lc) { + char *buf; + + if (!lc || lc->logs_db == NULL) return ; + + buf = sqlite3_mprintf("DELETE FROM call_history"); + linphone_sql_request_generic(lc->logs_db, buf); + sqlite3_free(buf); +} + +void linphone_core_delete_call_log(LinphoneCore *lc, LinphoneCallLog *log) { + char *buf; + + if (!lc || lc->logs_db == NULL) return ; + + buf = sqlite3_mprintf("DELETE FROM call_history WHERE id = %i", log->storage_id); + linphone_sql_request_generic(lc->logs_db, buf); + sqlite3_free(buf); +} + +int linphone_core_get_call_history_size(LinphoneCore *lc) { + int numrows = 0; + char *buf; + sqlite3_stmt *selectStatement; + int returnValue; + + if (!lc || lc->logs_db == NULL) return 0; + + buf = sqlite3_mprintf("SELECT count(*) FROM call_history"); + returnValue = sqlite3_prepare_v2(lc->logs_db, buf, -1, &selectStatement, NULL); + if (returnValue == SQLITE_OK){ + if(sqlite3_step(selectStatement) == SQLITE_ROW){ + numrows = sqlite3_column_int(selectStatement, 0); + } + } + sqlite3_finalize(selectStatement); + sqlite3_free(buf); + + return numrows; +} + +MSList * linphone_core_get_call_history_for_address(LinphoneCore *lc, const LinphoneAddress *addr) { + char *buf; + char *sipAddress; + uint64_t begin,end; + MSList *result = NULL; + + if (!lc || lc->logs_db == NULL || addr == NULL) return NULL; + + /*since we want to append query parameters depending on arguments given, we use malloc instead of sqlite3_mprintf*/ + sipAddress = linphone_address_as_string_uri_only(addr); + buf = sqlite3_mprintf("SELECT * FROM call_history WHERE caller LIKE '%%%q%%' OR callee LIKE '%%%q%%' ORDER BY id DESC", sipAddress, sipAddress); // The '%%%q%%' takes care of the eventual presence of a display name + + begin = ortp_get_cur_time_ms(); + linphone_sql_request_call_log(lc->logs_db, buf, &result); + end = ortp_get_cur_time_ms(); + ms_message("%s(): completed in %i ms",__FUNCTION__, (int)(end-begin)); + sqlite3_free(buf); + ms_free(sipAddress); + + if (lc->call_logs) { + copy_user_data_from_existing_logs(lc->call_logs, result); + } + + return result; +} + +LinphoneCallLog * linphone_core_get_last_outgoing_call_log(LinphoneCore *lc) { + char *buf; + uint64_t begin,end; + MSList *list = NULL; + LinphoneCallLog* result = NULL; + + if (!lc || lc->logs_db == NULL) return NULL; + + /*since we want to append query parameters depending on arguments given, we use malloc instead of sqlite3_mprintf*/ + buf = sqlite3_mprintf("SELECT * FROM call_history WHERE direction = 0 ORDER BY id DESC LIMIT 1"); + + begin = ortp_get_cur_time_ms(); + linphone_sql_request_call_log(lc->logs_db, buf, &list); + end = ortp_get_cur_time_ms(); + ms_message("%s(): completed in %i ms",__FUNCTION__, (int)(end-begin)); + sqlite3_free(buf); + + if (list) { + result = (LinphoneCallLog*)list->data; + } + + if (lc->call_logs && result) { + copy_user_data_from_existing_log(lc->call_logs, result); + } + + return result; +} + +LinphoneCallLog * linphone_core_find_call_log_from_call_id(LinphoneCore *lc, const char *call_id) { + char *buf; + uint64_t begin,end; + MSList *list = NULL; + LinphoneCallLog* result = NULL; + + if (!lc || lc->logs_db == NULL) return NULL; + + /*since we want to append query parameters depending on arguments given, we use malloc instead of sqlite3_mprintf*/ + buf = sqlite3_mprintf("SELECT * FROM call_history WHERE call_id = '%q' ORDER BY id DESC LIMIT 1", call_id); + + begin = ortp_get_cur_time_ms(); + linphone_sql_request_call_log(lc->logs_db, buf, &list); + end = ortp_get_cur_time_ms(); + ms_message("%s(): completed in %i ms",__FUNCTION__, (int)(end-begin)); + sqlite3_free(buf); + + if (list) { + result = (LinphoneCallLog*)list->data; + } + + if (lc->call_logs && result) { + copy_user_data_from_existing_log(lc->call_logs, result); + } + + return result; +} + +#else + +void linphone_core_call_log_storage_init(LinphoneCore *lc) { +} + +void linphone_core_call_log_storage_close(LinphoneCore *lc) { +} + +void linphone_core_store_call_log(LinphoneCore *lc, LinphoneCallLog *log) { +} + +const MSList *linphone_core_get_call_history(LinphoneCore *lc) { + return NULL; +} + +void linphone_core_delete_call_history(LinphoneCore *lc) { +} + +void linphone_core_delete_call_log(LinphoneCore *lc, LinphoneCallLog *log) { +} + +int linphone_core_get_call_history_size(LinphoneCore *lc) { + return 0; +} + +MSList * linphone_core_get_call_history_for_address(LinphoneCore *lc, const LinphoneAddress *addr) { + return NULL; +} + +LinphoneCallLog * linphone_core_get_last_outgoing_call_log(LinphoneCore *lc) { + return NULL; +} + +LinphoneCallLog * linphone_core_find_call_log_from_call_id(LinphoneCore *lc, const char *call_id) { + return NULL; +} + +#endif diff --git a/coreapi/call_params.c b/coreapi/call_params.c index 828fba70c..823f14f54 100644 --- a/coreapi/call_params.c +++ b/coreapi/call_params.c @@ -43,6 +43,9 @@ SalStreamDir sal_dir_from_call_params_dir(LinphoneMediaDirection cpdir) { return SalStreamRecvOnly; case LinphoneMediaDirectionSendRecv: return SalStreamSendRecv; + case LinphoneMediaDirectionInvalid: + ms_error("LinphoneMediaDirectionInvalid shall not be used."); + return SalStreamInactive; } return SalStreamSendRecv; } @@ -69,6 +72,36 @@ SalStreamDir get_video_dir_from_call_params(const LinphoneCallParams *params) { return sal_dir_from_call_params_dir(linphone_call_params_get_video_direction(params)); } +void linphone_call_params_set_custom_headers(LinphoneCallParams *params, const SalCustomHeader *ch){ + if (params->custom_headers){ + sal_custom_header_free(params->custom_headers); + params->custom_headers = NULL; + } + if (ch){ + params->custom_headers = sal_custom_header_clone(ch); + } +} + +void linphone_call_params_set_custom_sdp_attributes(LinphoneCallParams *params, const SalCustomSdpAttribute *csa) { + if (params->custom_sdp_attributes) { + sal_custom_sdp_attribute_free(params->custom_sdp_attributes); + params->custom_sdp_attributes = NULL; + } + if (csa) { + params->custom_sdp_attributes = sal_custom_sdp_attribute_clone(csa); + } +} + +void linphone_call_params_set_custom_sdp_media_attributes(LinphoneCallParams *params, LinphoneStreamType type, const SalCustomSdpAttribute *csa) { + if (params->custom_sdp_media_attributes[type]) { + sal_custom_sdp_attribute_free(params->custom_sdp_media_attributes[type]); + params->custom_sdp_media_attributes[type] = NULL; + } + if (csa) { + params->custom_sdp_media_attributes[type] = sal_custom_sdp_attribute_clone(csa); + } +} + /******************************************************************************* * Public functions * @@ -78,7 +111,24 @@ void linphone_call_params_add_custom_header(LinphoneCallParams *params, const ch params->custom_headers=sal_custom_header_append(params->custom_headers,header_name,header_value); } +void linphone_call_params_add_custom_sdp_attribute(LinphoneCallParams *params, const char *attribute_name, const char *attribute_value) { + params->custom_sdp_attributes = sal_custom_sdp_attribute_append(params->custom_sdp_attributes, attribute_name, attribute_value); +} + +void linphone_call_params_add_custom_sdp_media_attribute(LinphoneCallParams *params, LinphoneStreamType type, const char *attribute_name, const char *attribute_value) { + params->custom_sdp_media_attributes[type] = sal_custom_sdp_attribute_append(params->custom_sdp_media_attributes[type], attribute_name, attribute_value); +} + +void linphone_call_params_clear_custom_sdp_attributes(LinphoneCallParams *params) { + linphone_call_params_set_custom_sdp_attributes(params, NULL); +} + +void linphone_call_params_clear_custom_sdp_media_attributes(LinphoneCallParams *params, LinphoneStreamType type) { + linphone_call_params_set_custom_sdp_media_attributes(params, type, NULL); +} + LinphoneCallParams * linphone_call_params_copy(const LinphoneCallParams *cp){ + unsigned int i; LinphoneCallParams *ncp=linphone_call_params_new(); memcpy(ncp,cp,sizeof(LinphoneCallParams)); if (cp->record_file) ncp->record_file=ms_strdup(cp->record_file); @@ -87,6 +137,10 @@ LinphoneCallParams * linphone_call_params_copy(const LinphoneCallParams *cp){ * The management of the custom headers is not optimal. We copy everything while ref counting would be more efficient. */ if (cp->custom_headers) ncp->custom_headers=sal_custom_header_clone(cp->custom_headers); + if (cp->custom_sdp_attributes) ncp->custom_sdp_attributes = sal_custom_sdp_attribute_clone(cp->custom_sdp_attributes); + for (i = 0; i < (unsigned int)LinphoneStreamTypeUnknown; i++) { + if (cp->custom_sdp_media_attributes[i]) ncp->custom_sdp_media_attributes[i] = sal_custom_sdp_attribute_clone(cp->custom_sdp_media_attributes[i]); + } return ncp; } @@ -103,6 +157,17 @@ void linphone_call_params_enable_low_bandwidth(LinphoneCallParams *cp, bool_t en cp->low_bandwidth=enabled; } +void linphone_call_params_enable_audio(LinphoneCallParams *cp, bool_t enabled){ + cp->has_audio=enabled; + if (enabled && cp->audio_dir==LinphoneMediaDirectionInactive) + cp->audio_dir=LinphoneMediaDirectionSendRecv; +} + +int linphone_call_params_enable_realtime_text(LinphoneCallParams *params, bool_t yesno) { + params->realtimetext_enabled=yesno; + return 0; +} + void linphone_call_params_enable_video(LinphoneCallParams *cp, bool_t enabled){ cp->has_video=enabled; if (enabled && cp->video_dir==LinphoneMediaDirectionInactive) @@ -113,6 +178,14 @@ const char *linphone_call_params_get_custom_header(const LinphoneCallParams *par return sal_custom_header_find(params->custom_headers,header_name); } +const char * linphone_call_params_get_custom_sdp_attribute(const LinphoneCallParams *params, const char *attribute_name) { + return sal_custom_sdp_attribute_find(params->custom_sdp_attributes, attribute_name); +} + +const char * linphone_call_params_get_custom_sdp_media_attribute(const LinphoneCallParams *params, LinphoneStreamType type, const char *attribute_name) { + return sal_custom_sdp_attribute_find(params->custom_sdp_media_attributes[type], attribute_name); +} + bool_t linphone_call_params_get_local_conference_mode(const LinphoneCallParams *cp){ return cp->in_conference; } @@ -161,6 +234,11 @@ const LinphonePayloadType* linphone_call_params_get_used_video_codec(const Linph return cp->video_codec; } +const LinphonePayloadType* linphone_call_params_get_used_text_codec(const LinphoneCallParams *cp) { + return cp->text_codec; +} + + bool_t linphone_call_params_low_bandwidth_enabled(const LinphoneCallParams *cp) { return cp->low_bandwidth; } @@ -193,6 +271,14 @@ void linphone_call_params_set_session_name(LinphoneCallParams *cp, const char *n if (name) cp->session_name=ms_strdup(name); } +bool_t linphone_call_params_audio_enabled(const LinphoneCallParams *cp){ + return cp->has_audio; +} + +bool_t linphone_call_params_realtime_text_enabled(const LinphoneCallParams *params) { + return params->realtimetext_enabled; +} + bool_t linphone_call_params_video_enabled(const LinphoneCallParams *cp){ return cp->has_video; } @@ -255,14 +341,22 @@ bool_t linphone_call_params_video_multicast_enabled(const LinphoneCallParams *pa ******************************************************************************/ static void _linphone_call_params_destroy(LinphoneCallParams *cp){ + unsigned int i; if (cp->record_file) ms_free(cp->record_file); if (cp->custom_headers) sal_custom_header_free(cp->custom_headers); + if (cp->custom_sdp_attributes) sal_custom_sdp_attribute_free(cp->custom_sdp_attributes); + for (i = 0; i < (unsigned int)LinphoneStreamTypeUnknown; i++) { + if (cp->custom_sdp_media_attributes[i]) sal_custom_sdp_attribute_free(cp->custom_sdp_media_attributes[i]); + } + if (cp->session_name) ms_free(cp->session_name); } LinphoneCallParams * linphone_call_params_new(void) { LinphoneCallParams *cp=belle_sip_object_new(LinphoneCallParams); cp->audio_dir=LinphoneMediaDirectionSendRecv; cp->video_dir=LinphoneMediaDirectionSendRecv; + cp->has_audio=TRUE; + cp->realtimetext_enabled = FALSE; return cp; } diff --git a/coreapi/call_params.h b/coreapi/call_params.h index 8f9182af1..e3e6d1ee4 100644 --- a/coreapi/call_params.h +++ b/coreapi/call_params.h @@ -34,11 +34,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Indicates for a given media the stream direction * */ enum _LinphoneMediaDirection { + LinphoneMediaDirectionInvalid = -1, LinphoneMediaDirectionInactive, /** No active media not supported yet*/ LinphoneMediaDirectionSendOnly, /** Send only mode*/ LinphoneMediaDirectionRecvOnly, /** recv only mode*/ - LinphoneMediaDirectionSendRecv, /*send receive mode not supported yet*/ - + LinphoneMediaDirectionSendRecv, /** send receive*/ }; /** * Typedef for enum @@ -101,6 +101,13 @@ LINPHONE_PUBLIC void linphone_call_params_enable_early_media_sending(LinphoneCal **/ LINPHONE_PUBLIC void linphone_call_params_enable_low_bandwidth(LinphoneCallParams *cp, bool_t enabled); +/** + * Enable audio stream. + * @param[in] cp LinphoneCallParams object + * @param[in] enabled A boolean value telling whether to enable audio or not. +**/ +LINPHONE_PUBLIC void linphone_call_params_enable_audio(LinphoneCallParams *cp, bool_t enabled); + /** * Enable video stream. * @param[in] cp LinphoneCallParams object @@ -201,6 +208,13 @@ LINPHONE_PUBLIC const LinphonePayloadType* linphone_call_params_get_used_audio_c **/ LINPHONE_PUBLIC const LinphonePayloadType* linphone_call_params_get_used_video_codec(const LinphoneCallParams *cp); +/** + * Get the text codec used in the call, described as a LinphonePayloadType structure. + * @param[in] cp LinphoneCallParams object + * @return The LinphonePayloadType object corresponding to the text codec being used in the call. +**/ +LINPHONE_PUBLIC const LinphonePayloadType* linphone_call_params_get_used_text_codec(const LinphoneCallParams *cp); + /** * Tell whether the call has been configured in low bandwidth mode or not. * This mode can be automatically discovered thanks to a stun server when activate_edge_workarounds=1 in section [net] of configuration file. @@ -254,6 +268,13 @@ LINPHONE_PUBLIC void linphone_call_params_set_record_file(LinphoneCallParams *cp **/ LINPHONE_PUBLIC void linphone_call_params_set_session_name(LinphoneCallParams *cp, const char *name); +/** + * Tell whether audio is enabled or not. + * @param[in] cp LinphoneCallParams object + * @return A boolean value telling whether audio is enabled or not. +**/ +LINPHONE_PUBLIC bool_t linphone_call_params_audio_enabled(const LinphoneCallParams *cp); + /** * Tell whether video is enabled or not. * @param[in] cp LinphoneCallParams object @@ -276,14 +297,14 @@ LINPHONE_PUBLIC LinphoneMediaDirection linphone_call_params_get_audio_direction LINPHONE_PUBLIC LinphoneMediaDirection linphone_call_params_get_video_direction(const LinphoneCallParams *cp); /** - * Set the audio stream direction. Only relevant for multicast + * Set the audio stream direction. * @param[in] cl LinphoneCallParams object * @param[in] The audio stream direction associated with this call params. **/ LINPHONE_PUBLIC void linphone_call_params_set_audio_direction(LinphoneCallParams *cp, LinphoneMediaDirection dir); /** - * Set the video stream direction. Only relevant for multicast + * Set the video stream direction. * @param[in] cl LinphoneCallParams object * @param[in] The video stream direction associated with this call params. **/ @@ -348,14 +369,84 @@ LINPHONE_PUBLIC bool_t linphone_call_params_audio_multicast_enabled(const Linpho * @param yesno if yes, subsequent outgoing calls will propose multicast ip set by #linphone_core_set_video_multicast_addr * @ingroup media_parameters **/ -LINPHONE_PUBLIC void linphone_call_params_enable_video_multicast(LinphoneCallParams *param, bool_t yesno); +LINPHONE_PUBLIC void linphone_call_params_enable_video_multicast(LinphoneCallParams *params, bool_t yesno); /** * Use to get multicast state of video stream. - * @param core #LinphoneCallParams + * @param params #LinphoneCallParams * @return true if subsequent calls will propose multicast ip set by #linphone_core_set_video_multicast_addr * @ingroup media_parameters **/ -LINPHONE_PUBLIC bool_t linphone_call_params_video_multicast_enabled(const LinphoneCallParams *param); +LINPHONE_PUBLIC bool_t linphone_call_params_video_multicast_enabled(const LinphoneCallParams *params); + +/** + * Use to enable real time text following rfc4103. + * If enabled, outgoing calls put a m=text line in SDP offer . + * @param params #LinphoneCallParams + * @param yesno if yes, subsequent outgoing calls will propose rtt + * @ingroup media_parameters +**/ +LINPHONE_PUBLIC int linphone_call_params_enable_realtime_text(LinphoneCallParams *params, bool_t yesno); + +/** + * Use to get real time text following rfc4103. + * @param params #LinphoneCallParams + * @returns returns true if call rtt is activated. + * @ingroup media_parameters +**/ +LINPHONE_PUBLIC bool_t linphone_call_params_realtime_text_enabled(const LinphoneCallParams *params); + +/** + * Add a custom attribute related to all the streams in the SDP exchanged within SIP messages during a call. + * @param[in] params The #LinphoneCallParams to add a custom SDP attribute to. + * @param[in] attribute_name The name of the attribute to add. + * @param[in] attribute_value The content value of the attribute to add. + * @ingroup media_parameters +**/ +LINPHONE_PUBLIC void linphone_call_params_add_custom_sdp_attribute(LinphoneCallParams *params, const char *attribute_name, const char *attribute_value); + +/** + * Add a custom attribute related to a specific stream in the SDP exchanged within SIP messages during a call. + * @param[in] params The #LinphoneCallParams to add a custom SDP attribute to. + * @param[in] type The type of the stream to add a custom SDP attribute to. + * @param[in] attribute_name The name of the attribute to add. + * @param[in] attribute_value The content value of the attribute to add. + * @ingroup media_parameters +**/ +LINPHONE_PUBLIC void linphone_call_params_add_custom_sdp_media_attribute(LinphoneCallParams *params, LinphoneStreamType type, const char *attribute_name, const char *attribute_value); + +/** + * Get a custom SDP attribute that is related to all the streams. + * @param[in] params The #LinphoneCallParams to get the custom SDP attribute from. + * @param[in] attribute_name The name of the attribute to get. + * @return The content value of the attribute or NULL if not found. + * @ingroup media_parameters +**/ +LINPHONE_PUBLIC const char * linphone_call_params_get_custom_sdp_attribute(const LinphoneCallParams *params, const char *attribute_name); + +/** + * Get a custom SDP attribute that is related to a specific stream. + * @param[in] params The #LinphoneCallParams to get the custom SDP attribute from. + * @param[in] type The type of the stream to add a custom SDP attribute to. + * @param[in] attribute_name The name of the attribute to get. + * @return The content value of the attribute or NULL if not found. + * @ingroup media_parameters +**/ +LINPHONE_PUBLIC const char * linphone_call_params_get_custom_sdp_media_attribute(const LinphoneCallParams *params, LinphoneStreamType type, const char *attribute_name); + +/** + * Clear the custom SDP attributes related to all the streams in the SDP exchanged within SIP messages during a call. + * @param[in] params The #LinphoneCallParams to clear the custom SDP attributes from. + * @ingroup media_parameters +**/ +LINPHONE_PUBLIC void linphone_call_params_clear_custom_sdp_attributes(LinphoneCallParams *params); + +/** + * Clear the custom SDP attributes related to a specific stream in the SDP exchanged within SIP messages during a call. + * @param[in] params The #LinphoneCallParams to clear the custom SDP attributes from. + * @param[in] type The type of the stream to clear the custom SDP attributes from. + * @ingroup media_parameters +**/ +LINPHONE_PUBLIC void linphone_call_params_clear_custom_sdp_media_attributes(LinphoneCallParams *params, LinphoneStreamType type); /******************************************************************************* diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 393bbd350..a0035d2ed 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -26,7 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "lpconfig.h" // stat -#ifndef WIN32 +#ifndef _WIN32 #include #include #include @@ -35,10 +35,19 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. static void register_failure(SalOp *op); static int media_parameters_changed(LinphoneCall *call, SalMediaDescription *oldmd, SalMediaDescription *newmd) { - if (call->params->in_conference != call->current_params->in_conference) return SAL_MEDIA_DESCRIPTION_CHANGED; - if (call->up_bw != linphone_core_get_upload_bandwidth(call->core)) return SAL_MEDIA_DESCRIPTION_CHANGED; - if (call->localdesc_changed) ms_message("Local description has changed: %i", call->localdesc_changed); - return call->localdesc_changed | sal_media_description_equals(oldmd, newmd); + int result=0; + int otherdesc_changed; + char *tmp1=NULL; + char *tmp2=NULL; + if (call->params->in_conference != call->current_params->in_conference) return SAL_MEDIA_DESCRIPTION_FORCE_STREAM_RECONSTRUCTION; + if (call->up_bw != linphone_core_get_upload_bandwidth(call->core)) return SAL_MEDIA_DESCRIPTION_FORCE_STREAM_RECONSTRUCTION; + if (call->localdesc_changed) ms_message("Local description has changed: %s", tmp1 = sal_media_description_print_differences(call->localdesc_changed)); + otherdesc_changed = sal_media_description_equals(oldmd, newmd); + if (otherdesc_changed) ms_message("Other description has changed: %s", tmp2 = sal_media_description_print_differences(otherdesc_changed)); + result = call->localdesc_changed | otherdesc_changed; + if (tmp1) ms_free(tmp1); + if (tmp2) ms_free(tmp2); + return result; } void linphone_core_update_streams_destinations(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription *old_md, SalMediaDescription *new_md) { @@ -47,7 +56,7 @@ void linphone_core_update_streams_destinations(LinphoneCore *lc, LinphoneCall *c char *rtp_addr, *rtcp_addr; int i; - for (i = 0; i < new_md->nb_streams; i++) { + for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) { if (!sal_stream_description_active(&new_md->streams[i])) continue; if (new_md->streams[i].type == SalAudio) { new_audiodesc = &new_md->streams[i]; @@ -109,18 +118,16 @@ void linphone_call_update_frozen_payloads(LinphoneCall *call, SalMediaDescriptio /*new codec, needs to be added to the list*/ local->streams[i].already_assigned_payloads=ms_list_append(local->streams[i].already_assigned_payloads, payload_type_clone(pt)); ms_message("LinphoneCall[%p] : payload type %i %s/%i fmtp=%s added to frozen list.", - call, payload_type_get_number(pt), pt->mime_type, pt->clock_rate, pt->recv_fmtp ? pt->recv_fmtp : NULL); + call, payload_type_get_number(pt), pt->mime_type, pt->clock_rate, pt->recv_fmtp ? pt->recv_fmtp : ""); } } } } -void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription *new_md){ +void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription *new_md, LinphoneCallState target_state){ SalMediaDescription *oldmd=call->resultdesc; - bool_t all_muted=FALSE; - bool_t send_ringbacktone=FALSE; int md_changed=0; - + if (!((call->state == LinphoneCallIncomingEarlyMedia) && (linphone_core_get_ring_during_incoming_early_media(lc)))) { linphone_core_stop_ringing(lc); @@ -129,20 +136,8 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia ms_error("linphone_core_update_streams() called with null media description"); return; } - if (call->biggestdesc==NULL || new_md->nb_streams>call->biggestdesc->nb_streams){ - /*we have been offered and now are ready to proceed, or we added a new stream*/ - /*store the media description to remember the mapping of calls*/ - if (call->biggestdesc){ - sal_media_description_unref(call->biggestdesc); - call->biggestdesc=NULL; - } - if (sal_call_is_offerer(call->op)) - call->biggestdesc=sal_media_description_ref(call->localdesc); - else - call->biggestdesc=sal_media_description_ref(sal_call_get_remote_media_description(call->op)); - } + linphone_call_update_biggest_desc(call, call->localdesc); sal_media_description_ref(new_md); - call->expect_media_in_ack=FALSE; call->resultdesc=new_md; if ((call->audiostream && call->audiostream->ms.state==MSStreamStarted) || (call->videostream && call->videostream->ms.state==MSStreamStarted)){ clear_early_media_destinations(call); @@ -152,7 +147,9 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia md_changed = media_parameters_changed(call, oldmd, new_md); if ((md_changed & ( SAL_MEDIA_DESCRIPTION_CODEC_CHANGED |SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED - |SAL_MEDIA_DESCRIPTION_NETWORK_XXXCAST_CHANGED))){ + |SAL_MEDIA_DESCRIPTION_NETWORK_XXXCAST_CHANGED + |SAL_MEDIA_DESCRIPTION_ICE_RESTART_DETECTED + |SAL_MEDIA_DESCRIPTION_FORCE_STREAM_RECONSTRUCTION ))){ 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."); @@ -188,8 +185,9 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia linphone_call_stop_media_streams (call); if (md_changed & SAL_MEDIA_DESCRIPTION_NETWORK_XXXCAST_CHANGED){ ms_message("Media ip type has changed, destroying sessions context on call [%p]",call); - ms_media_stream_sessions_uninit(&call->sessions[0]); - ms_media_stream_sessions_uninit(&call->sessions[1]); + ms_media_stream_sessions_uninit(&call->sessions[call->main_audio_stream_index]); + ms_media_stream_sessions_uninit(&call->sessions[call->main_video_stream_index]); + if (call->params->realtimetext_enabled) ms_media_stream_sessions_uninit(&call->sessions[call->main_text_stream_index]); } linphone_call_init_media_streams (call); } @@ -198,25 +196,11 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia /*this happens after pausing the call locally. The streams are destroyed and then we wait the 200Ok to recreate them*/ linphone_call_init_media_streams (call); } - if (call->state==LinphoneCallIncomingEarlyMedia && linphone_core_get_remote_ringback_tone (lc)!=NULL){ - send_ringbacktone=TRUE; - } - if ((call->state==LinphoneCallIncomingEarlyMedia || call->state==LinphoneCallOutgoingEarlyMedia) && !call->params->real_early_media){ - all_muted=TRUE; - } + if (call->params->real_early_media && call->state==LinphoneCallOutgoingEarlyMedia){ prepare_early_media_forking(call); } -#ifdef VIDEO_ENABLED - if (call->state==LinphoneCallPausing) { - /*change cam to noweb cam*/ - call->cam = get_nowebcam_device(); - } else if (call->state != LinphoneCallPaused) { - /*restaure web cam*/ - call->cam = lc->video_conf.device; - } -#endif /*VIDEO*/ - linphone_call_start_media_streams(call,all_muted,send_ringbacktone); + linphone_call_start_media_streams(call, target_state); if (call->state==LinphoneCallPausing && call->paused_by_app && ms_list_size(lc->calls)==1){ linphone_core_play_named_tone(lc,LinphoneToneCallOnHold); } @@ -343,7 +327,7 @@ static void call_received(SalOp *h){ call=linphone_call_new_incoming(lc,from_addr,to_addr,h); - linphone_call_make_local_media_description(lc,call); + linphone_call_make_local_media_description(call); sal_call_set_local_media_description(call->op,call->localdesc); md=sal_call_get_final_media_description(call->op); if (md){ @@ -359,7 +343,7 @@ static void call_received(SalOp *h){ linphone_call_ref(call); /*prevent the call from being destroyed while we are notifying, if the user declines within the state callback */ call->bg_task_id=sal_begin_background_task("liblinphone call notification", NULL, NULL); - + if ((linphone_core_get_firewall_policy(lc) == LinphonePolicyUseIce) && (call->ice_session != NULL)) { /* Defer ringing until the end of the ICE candidates gathering process. */ ms_message("Defer ringing to gather ICE candidates"); @@ -382,7 +366,7 @@ static void try_early_media_forking(LinphoneCall *call, SalMediaDescription *md) SalStreamDescription *ref_stream,*new_stream; ms_message("Early media response received from another branch, checking if media can be forked to this new destination."); - for (i=0;inb_streams;++i){ + for (i=0;istreams[i])) continue; ref_stream=&cur_md->streams[i]; new_stream=&md->streams[i]; @@ -451,6 +435,8 @@ static void call_ringing(SalOp *h){ linphone_core_notify_display_status(lc,_("Remote ringing...")); linphone_call_set_state(call,LinphoneCallOutgoingRinging,"Remote ringing"); }else{ + /*initialize the remote call params by invoking linphone_call_get_remote_params(). This is useful as the SDP may not be present in the 200Ok*/ + linphone_call_get_remote_params(call); /*accept early media */ if ((call->audiostream && audio_stream_started(call->audiostream)) #ifdef VIDEO_ENABLED @@ -473,7 +459,7 @@ static void call_ringing(SalOp *h){ linphone_call_set_state(call,LinphoneCallOutgoingEarlyMedia,"Early media"); linphone_core_stop_ringing(lc); ms_message("Doing early media..."); - linphone_core_update_streams(lc,call,md); + linphone_core_update_streams(lc,call,md, call->state); 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); @@ -481,24 +467,41 @@ static void call_ringing(SalOp *h){ } } -/* - * could be reach : - * - when the call is accepted - * - when a request is accepted (pause, resume) - */ -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, *rmd; - bool_t update_state=TRUE; +static void start_pending_refer(LinphoneCall *call){ + linphone_core_start_refered_call(call->core, call,NULL); +} - if (call==NULL){ - ms_warning("No call to accept."); - return ; +static void process_call_accepted(LinphoneCore *lc, LinphoneCall *call, SalOp *op){ + SalMediaDescription *md, *rmd; + LinphoneCallState next_state = LinphoneCallIdle; + const char *next_state_str = NULL; + LinphoneTaskList tl; + + switch (call->state){/*immediately notify the connected state, even if errors occur after*/ + case LinphoneCallOutgoingProgress: + case LinphoneCallOutgoingRinging: + case LinphoneCallOutgoingEarlyMedia: + /*immediately notify the connected state*/ + linphone_call_set_state(call,LinphoneCallConnected,"Connected"); + { + char *tmp=linphone_call_get_remote_address_as_string (call); + char *msg=ms_strdup_printf(_("Call answered by %s"),tmp); + linphone_core_notify_display_status(lc,msg); + ms_free(tmp); + ms_free(msg); + } + break; + default: + break; } + + linphone_task_list_init(&tl); rmd=sal_call_get_remote_media_description(op); /*set privacy*/ call->current_params->privacy=(LinphonePrivacyMask)sal_op_get_privacy(call->op); + /*reset the internal call update flag, so it doesn't risk to be copied and used in further re-INVITEs*/ + if (call->params->internal_call_update) + call->params->internal_call_update = FALSE; /* Handle remote ICE attributes if any. */ if (call->ice_session != NULL && rmd) { @@ -511,130 +514,108 @@ static void call_accepted(SalOp *op){ #endif //BUILD_UPNP md=sal_call_get_final_media_description(op); - - switch (call->state){ - case LinphoneCallOutgoingProgress: - case LinphoneCallOutgoingRinging: - case LinphoneCallOutgoingEarlyMedia: - linphone_call_set_state(call,LinphoneCallConnected,"Connected"); - if (call->referer) linphone_core_notify_refer_state(lc,call->referer,call); - break; - case LinphoneCallEarlyUpdating: - linphone_call_set_state(call,call->prevstate,"Early update accepted"); - update_state=FALSE; - break; - default: - break; + if (md == NULL && call->prevstate == LinphoneCallOutgoingEarlyMedia && call->resultdesc != NULL){ + ms_message("Using early media SDP since none was received with the 200 OK"); + md = call->resultdesc; } - - if( (call->prevstate == LinphoneCallOutgoingEarlyMedia) && (md == NULL || sal_media_description_empty(md)) ){ - /* media description is null or empty because no SDP was received in the 200 OK, we can possibly use the early-media SDP. */ - if( call->resultdesc != NULL){ - ms_message("Using early media SDP since none were received with the 200 OK"); - md = call->resultdesc; - } + if (md && (sal_media_description_empty(md) || linphone_core_incompatible_security(lc,md))){ + md = NULL; } - - if (md && !sal_media_description_empty(md) && !linphone_core_incompatible_security(lc,md)){ - linphone_call_update_remote_session_id_and_ver(call); - linphone_core_update_ice_state_in_call_stats(call); - if (sal_media_description_has_dir(md,SalStreamSendOnly) || - sal_media_description_has_dir(md,SalStreamInactive)){ - { - char *tmp=linphone_call_get_remote_address_as_string (call); - char *msg=ms_strdup_printf(_("Call with %s is paused."),tmp); - linphone_core_notify_display_status(lc,msg); - ms_free(tmp); - ms_free(msg); - } - linphone_core_update_streams (lc,call,md); - if (update_state) linphone_call_set_state(call,LinphoneCallPaused,"Call paused"); - if (call->refer_pending) - linphone_core_start_refered_call(lc,call,NULL); - }else if (sal_media_description_has_dir(md,SalStreamRecvOnly)){ - /*we are put on hold when the call is initially accepted */ - { - char *tmp=linphone_call_get_remote_address_as_string (call); - char *msg=ms_strdup_printf(_("Call answered by %s - on hold."),tmp); - linphone_core_notify_display_status(lc,msg); - ms_free(tmp); - ms_free(msg); - } - linphone_core_update_streams (lc,call,md); - if (update_state) linphone_call_set_state(call,LinphoneCallPausedByRemote,"Call paused by remote"); - }else{ - if (call->state!=LinphoneCallUpdating){ - if (call->state==LinphoneCallResuming){ - linphone_core_notify_display_status(lc,_("Call resumed.")); + if (md){ /*there is a valid SDP in the response, either offer or answer, and we're able to start/update the streams*/ + switch (call->state){ + case LinphoneCallResuming: + linphone_core_notify_display_status(lc,_("Call resumed.")); + /*intentionally no break*/ + case LinphoneCallConnected: + if (call->referer) linphone_core_notify_refer_state(lc,call->referer,call); + /*intentionally no break*/ + case LinphoneCallUpdating: + case LinphoneCallUpdatedByRemote: + if (!sal_media_description_has_dir(call->localdesc, SalStreamInactive) && + (sal_media_description_has_dir(md,SalStreamRecvOnly) || + sal_media_description_has_dir(md,SalStreamInactive))){ + next_state = LinphoneCallPausedByRemote; + next_state_str = "Call paused by remote"; }else{ - { - char *tmp=linphone_call_get_remote_address_as_string (call); - char *msg=ms_strdup_printf(_("Call answered by %s."),tmp); - linphone_core_notify_display_status(lc,msg); - ms_free(tmp); - ms_free(msg); - } + if (!call->params->in_conference) + lc->current_call=call; + next_state = LinphoneCallStreamsRunning; + next_state_str = "Streams running"; } - } - linphone_core_update_streams(lc,call,md); - /*also reflect the change if the "wished" params, in order to avoid to propose SAVP or video again - * further in the call, for example during pause,resume, conferencing reINVITEs*/ - linphone_call_fix_call_parameters(call); - if (!call->current_params->in_conference) - lc->current_call=call; - if (update_state) linphone_call_set_state(call, LinphoneCallStreamsRunning, "Streams running"); + break; + case LinphoneCallEarlyUpdating: + next_state_str = "Early update accepted"; + next_state = call->prevstate; + break; + case LinphoneCallPausing: + /*when we entered the pausing state, we always reach the paused state whatever the content of the remote SDP is. + Our streams are all send-only (with music), soundcard and camera are never used*/ + next_state = LinphoneCallPaused; + next_state_str = "Call paused"; + if (call->refer_pending) + linphone_task_list_add(&tl, (LinphoneCoreIterateHook)start_pending_refer, call); + break; + default: + ms_error("call_accepted(): don't know what to do in state [%s]", linphone_call_state_to_string(call->state)); + break; } - }else{ + + if (next_state != LinphoneCallIdle){ + linphone_call_update_remote_session_id_and_ver(call); + linphone_core_update_ice_state_in_call_stats(call); + linphone_core_update_streams(lc, call, md, next_state); + linphone_call_fix_call_parameters(call, rmd); + linphone_call_set_state(call, next_state, next_state_str); + }else{ + ms_error("BUG: next_state is not set in call_accepted(), current state is %s", linphone_call_state_to_string(call->state)); + } + }else{ /*invalid or no SDP*/ switch (call->prevstate){ - /*send a bye only in case of outgoing state*/ + /*send a bye only in case of early states*/ case LinphoneCallOutgoingInit: case LinphoneCallOutgoingProgress: case LinphoneCallOutgoingRinging: case LinphoneCallOutgoingEarlyMedia: - ms_error("Incompatible SDP offer received in 200 OK, need to abort the call"); + case LinphoneCallIncomingReceived: + case LinphoneCallIncomingEarlyMedia: + ms_error("Incompatible SDP answer received, need to abort the call"); linphone_core_abort_call(lc,call,_("Incompatible, check codecs or security settings...")); break; /*otherwise we are able to resume previous state*/ default: - ms_message("Incompatible SDP offer received in 200 OK, restoring previous state[%s]",linphone_call_state_to_string(call->prevstate)); + ms_message("Incompatible SDP answer received, restoring previous state [%s]",linphone_call_state_to_string(call->prevstate)); linphone_call_set_state(call,call->prevstate,_("Incompatible media parameters.")); break; } } + linphone_task_list_run(&tl); + linphone_task_list_free(&tl); } -static void call_ack(SalOp *op){ +/* + * could be reach : + * - when the call is accepted + * - when a request is accepted (pause, resume) + */ +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); - if (call==NULL){ - ms_warning("No call to be ACK'd"); + + if (call == NULL){ + ms_warning("call_accepted: call does no longer exist."); return ; } - if (call->expect_media_in_ack){ - SalMediaDescription *md=sal_call_get_final_media_description(op); - if (md && !sal_media_description_empty(md)){ - linphone_core_update_streams(lc,call,md); - linphone_call_set_state (call,LinphoneCallStreamsRunning,"Connected (streams running)"); - }else{ - /*send a bye*/ - ms_error("Incompatible SDP response received in ACK, need to abort the call"); - linphone_core_abort_call(lc,call,"No codec intersection"); - return; - } - } + process_call_accepted(lc, call, op); } static void call_resumed(LinphoneCore *lc, LinphoneCall *call){ - /*when we are resumed, increment session id, because sdp is changed (a=recvonly disapears)*/ - linphone_call_increment_local_media_description(call); linphone_core_notify_display_status(lc,_("We have been resumed.")); _linphone_core_accept_call_update(lc,call,NULL,LinphoneCallStreamsRunning,"Connected (streams running)"); } static void call_paused_by_remote(LinphoneCore *lc, LinphoneCall *call){ LinphoneCallParams *params; - /*when we are paused, increment session id, because sdp is changed (a=recvonly appears)*/ - linphone_call_increment_local_media_description(call); + /* we are being paused */ linphone_core_notify_display_status(lc,_("We are paused by other party.")); params = linphone_call_params_copy(call->params); @@ -645,106 +626,59 @@ static void call_paused_by_remote(LinphoneCore *lc, LinphoneCall *call){ linphone_call_params_unref(params); } -static void call_updated_by_remote(LinphoneCore *lc, LinphoneCall *call, bool_t is_update){ - /*first check if media capabilities are compatible*/ - SalMediaDescription *md; - SalMediaDescription *rmd=sal_call_get_remote_media_description(call->op); - SalMediaDescription *prev_result_desc=call->resultdesc; - - if (rmd!=NULL){ - if (call->state!=LinphoneCallPaused){ - /*in paused state, we must stay in paused state.*/ - linphone_call_make_local_media_description(lc,call); - sal_call_set_local_media_description(call->op,call->localdesc); +static void call_updated_by_remote(LinphoneCore *lc, LinphoneCall *call){ + linphone_core_notify_display_status(lc,_("Call is updated by remote.")); + linphone_call_set_state(call, LinphoneCallUpdatedByRemote,"Call updated by remote"); + if (call->defer_update == FALSE){ + linphone_core_accept_call_update(lc,call,NULL); + }else{ + if (call->state == LinphoneCallUpdatedByRemote){ + ms_message("LinphoneCall [%p]: UpdatedByRemoted was signaled but defered. LinphoneCore expects the application to call " + "linphone_core_accept_call_update() later.", call); } - md=sal_call_get_final_media_description(call->op); - if (md && (sal_media_description_empty(md) || linphone_core_incompatible_security(lc,md))){ - sal_call_decline(call->op,SalReasonNotAcceptable,NULL); - return; - } - if (is_update && prev_result_desc && md){ - int diff=sal_media_description_equals(prev_result_desc,md); - if (diff & (SAL_MEDIA_DESCRIPTION_CRYPTO_POLICY_CHANGED|SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED)){ - ms_warning("Cannot accept this update, it is changing parameters that require user approval"); - sal_call_decline(call->op,SalReasonNotAcceptable,NULL); /*FIXME should send 504 Cannot change the session parameters without prompting the user"*/ - return; - } - } - } - - if ( call->state == LinphoneCallStreamsRunning) { - /*reINVITE and in-dialogs UPDATE go here*/ - linphone_core_notify_display_status(lc,_("Call is updated by remote.")); - call->defer_update = lp_config_get_int(lc->config, "sip", "defer_update_default", FALSE); - linphone_call_set_state(call, LinphoneCallUpdatedByRemote,"Call updated by remote"); - if (call->defer_update==FALSE){ - linphone_core_accept_call_update(lc,call,NULL); - } - if (rmd==NULL){ - call->expect_media_in_ack=TRUE; - } - - } else if( call->state == LinphoneCallPausedByRemote ){ - /* Case where no SDP is present and we were paused by remote. - * We send back an ACK with our SDP and expect the remote to send its own. - * No state change here until an answer is received. */ - call->defer_update = lp_config_get_int(lc->config, "sip", "defer_update_default", FALSE); - if (call->defer_update==FALSE){ - _linphone_core_accept_call_update(lc,call,NULL,call->state,linphone_call_state_to_string(call->state)); - } - if (rmd==NULL){ - call->expect_media_in_ack=TRUE; - } - } else if (is_update){ /*SIP UPDATE case, can occur in early states*/ - linphone_call_set_state(call, LinphoneCallEarlyUpdatedByRemote, "EarlyUpdatedByRemote"); - _linphone_core_accept_call_update(lc,call,NULL,call->prevstate,linphone_call_state_to_string(call->prevstate)); } } /* this callback is called when an incoming re-INVITE/ SIP UPDATE modifies the session*/ -static void call_updating(SalOp *op, bool_t is_update){ - LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); - LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op); +static void call_updated(LinphoneCore *lc, LinphoneCall *call, SalOp *op, bool_t is_update){ SalMediaDescription *rmd=sal_call_get_remote_media_description(op); - if (rmd==NULL){ - /* case of a reINVITE or UPDATE without SDP */ - call_updated_by_remote(lc,call,is_update); - return; - } + call->defer_update = lp_config_get_int(lc->config, "sip", "defer_update_default", FALSE); switch(call->state){ case LinphoneCallPausedByRemote: if (sal_media_description_has_dir(rmd,SalStreamSendRecv) || sal_media_description_has_dir(rmd,SalStreamRecvOnly)){ call_resumed(lc,call); - }else call_updated_by_remote(lc,call,is_update); + }else{ + call_updated_by_remote(lc, call); + } break; /*SIP UPDATE CASE*/ case LinphoneCallOutgoingRinging: case LinphoneCallOutgoingEarlyMedia: case LinphoneCallIncomingEarlyMedia: - if (is_update) call_updated_by_remote(lc,call,is_update); + if (is_update) { + linphone_call_set_state(call, LinphoneCallEarlyUpdatedByRemote, "EarlyUpdatedByRemote"); + _linphone_core_accept_call_update(lc,call,NULL,call->prevstate,linphone_call_state_to_string(call->prevstate)); + } break; case LinphoneCallStreamsRunning: case LinphoneCallConnected: if (sal_media_description_has_dir(rmd,SalStreamSendOnly) || sal_media_description_has_dir(rmd,SalStreamInactive)){ call_paused_by_remote(lc,call); }else{ - call_updated_by_remote(lc,call,is_update); + call_updated_by_remote(lc, call); } break; case LinphoneCallPaused: - if (sal_media_description_has_dir(rmd,SalStreamSendOnly) || sal_media_description_has_dir(rmd,SalStreamInactive)){ - call_paused_by_remote(lc,call); - }else{ - call_updated_by_remote(lc,call,is_update); - } + /*we'll remain in pause state but accept the offer anyway according to default parameters*/ + _linphone_core_accept_call_update(lc,call,NULL,call->state,linphone_call_state_to_string(call->state)); break; case LinphoneCallUpdating: case LinphoneCallPausing: case LinphoneCallResuming: case LinphoneCallUpdatedByRemote: - sal_call_decline(call->op,SalReasonNotImplemented,NULL); + sal_call_decline(call->op,SalReasonInternalError,NULL); /*no break*/ case LinphoneCallIdle: case LinphoneCallOutgoingInit: @@ -761,6 +695,78 @@ static void call_updating(SalOp *op, bool_t is_update){ } } +/* this callback is called when an incoming re-INVITE/ SIP UPDATE modifies the session*/ +static void call_updating(SalOp *op, bool_t is_update){ + LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); + LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op); + SalMediaDescription *rmd=sal_call_get_remote_media_description(op); + + if (!call) { + ms_error("call_updating(): call doesn't exist anymore"); + return ; + } + linphone_call_fix_call_parameters(call, rmd); + if (call->state!=LinphoneCallPaused){ + /*Refresh the local description, but in paused state, we don't change anything.*/ + if (rmd == NULL && lp_config_get_int(call->core->config,"sip","sdp_200_ack_follow_video_policy",0)) { + LinphoneCallParams *p=linphone_core_create_call_params(lc, NULL); + ms_message("Applying default policy for offering SDP on call [%p]",call); + linphone_call_set_new_params(call, p); + linphone_call_params_destroy(p); + } + linphone_call_make_local_media_description(call); + sal_call_set_local_media_description(call->op,call->localdesc); + } + if (rmd == NULL){ + /* case of a reINVITE or UPDATE without SDP */ + call->expect_media_in_ack = TRUE; + sal_call_accept(op); /*respond with an offer*/ + /*don't do anything else in this case, wait for the ACK to receive to notify the app*/ + }else { + SalMediaDescription *md; + SalMediaDescription *prev_result_desc=call->resultdesc; + + call->expect_media_in_ack = FALSE; + + md=sal_call_get_final_media_description(call->op); + if (md && (sal_media_description_empty(md) || linphone_core_incompatible_security(lc,md))){ + sal_call_decline(call->op,SalReasonNotAcceptable,NULL); + return; + } + if (is_update && prev_result_desc && md){ + int diff=sal_media_description_equals(prev_result_desc,md); + if (diff & (SAL_MEDIA_DESCRIPTION_CRYPTO_POLICY_CHANGED|SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED)){ + ms_warning("Cannot accept this update, it is changing parameters that require user approval"); + sal_call_decline(call->op,SalReasonNotAcceptable,NULL); /*FIXME should send 504 Cannot change the session parameters without prompting the user"*/ + return; + } + } + call_updated(lc, call, op, is_update); + } +} + + +static void call_ack(SalOp *op){ + LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); + LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op); + + if (call == NULL){ + ms_warning("call_ack(): no call for which an ack is expected"); + return; + } + if (call->expect_media_in_ack){ + switch(call->state){ + case LinphoneCallStreamsRunning: + case LinphoneCallPausedByRemote: + linphone_call_set_state(call, LinphoneCallUpdatedByRemote, "UpdatedByRemote"); + break; + default: + break; + } + process_call_accepted(lc, call, op); + } +} + static void call_terminated(SalOp *op, const char *from){ LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op); @@ -770,7 +776,7 @@ static void call_terminated(SalOp *op, const char *from){ switch(linphone_call_get_state(call)){ case LinphoneCallEnd: case LinphoneCallError: - ms_warning("call_terminated: ignoring."); + ms_warning("call_terminated: already terminated, ignoring."); return; break; case LinphoneCallIncomingReceived: @@ -917,16 +923,11 @@ static void call_failure(SalOp *op){ msg=_("Incompatible media parameters."); linphone_core_notify_display_status(lc,msg); break; - case SalReasonRequestPending: - /*restore previous state, the application will decide to resubmit the action if relevant*/ - linphone_call_set_state(call,call->prevstate,msg); - return; - break; default: linphone_core_notify_display_status(lc,_("Call failed.")); } - /*some call error are not fatal*/ + /*some call errors are not fatal*/ switch (call->state) { case LinphoneCallUpdating: case LinphoneCallPausing: @@ -978,7 +979,7 @@ static void auth_failure(SalOp *op, SalAuthInfo* info) { LinphoneAuthInfo *ai=NULL; if( info != NULL ){ - ai = (LinphoneAuthInfo*)linphone_core_find_auth_info(lc,info->realm,info->username,info->domain); + ai = (LinphoneAuthInfo*)_linphone_core_find_auth_info(lc,info->realm,info->username,info->domain, TRUE); if (ai){ ms_message("%s/%s/%s authentication fails.",info->realm,info->username,info->domain); @@ -1057,6 +1058,7 @@ static void vfu_request(SalOp *op){ static void dtmf_received(SalOp *op, char dtmf){ LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op); + if (!call) return; linphone_core_notify_dtmf_received(lc, call, dtmf); } @@ -1116,6 +1118,7 @@ static void text_received(SalOp *op, const SalMessage *msg){ static void is_composing_received(SalOp *op, const SalIsComposing *is_composing) { LinphoneCore *lc = (LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); linphone_core_is_composing_received(lc, op, is_composing); + sal_op_release(op); } static void parse_presence_requested(SalOp *op, const char *content_type, const char *content_subtype, const char *body, SalPresenceModel **result) { @@ -1157,35 +1160,40 @@ static void ping_reply(SalOp *op){ } static bool_t fill_auth_info_with_client_certificate(LinphoneCore *lc, SalAuthInfo* sai) { - const char *chain_file = lp_config_get_string(lc->config,"sip","client_cert_chain", 0); - const char *key_file = lp_config_get_string(lc->config,"sip","client_cert_key", 0);; + const char *chain_file = lp_config_get_string(lc->config,"sip","client_cert_chain", 0); + const char *key_file = lp_config_get_string(lc->config,"sip","client_cert_key", 0);; -#ifndef WIN32 - { - // optinal check for files - struct stat st; - if (stat(key_file,&st)) { - ms_warning("No client certificate key found in %s", key_file); - return FALSE; - } - if (stat(chain_file,&st)) { - ms_warning("No client certificate chain found in %s", chain_file); - return FALSE; - } - } +#ifndef _WIN32 + { + // optinal check for files + struct stat st; + if (stat(key_file,&st)) { + ms_warning("No client certificate key found in %s", key_file); + return FALSE; + } + if (stat(chain_file,&st)) { + ms_warning("No client certificate chain found in %s", chain_file); + return FALSE; + } + } #endif - sal_certificates_chain_parse_file(sai, chain_file, SAL_CERTIFICATE_RAW_FORMAT_PEM ); - sal_signing_key_parse_file(sai, key_file, ""); - return sai->certificates && sai->key; + sal_certificates_chain_parse_file(sai, chain_file, SAL_CERTIFICATE_RAW_FORMAT_PEM ); + sal_signing_key_parse_file(sai, key_file, ""); + return sai->certificates && sai->key; } static bool_t fill_auth_info(LinphoneCore *lc, SalAuthInfo* sai) { - LinphoneAuthInfo *ai=(LinphoneAuthInfo*)linphone_core_find_auth_info(lc,sai->realm,sai->username,sai->domain); + LinphoneAuthInfo *ai=(LinphoneAuthInfo*)_linphone_core_find_auth_info(lc,sai->realm,sai->username,sai->domain, FALSE); if (ai) { sai->userid=ms_strdup(ai->userid?ai->userid:ai->username); sai->password=ai->passwd?ms_strdup(ai->passwd):NULL; sai->ha1=ai->ha1?ms_strdup(ai->ha1):NULL; + if (sai->realm && !ai->realm){ + /*if realm was not known, then set it so that ha1 may eventually be calculated and clear text password dropped*/ + linphone_auth_info_set_realm(ai, sai->realm); + linphone_core_write_auth_info(lc, ai); + } return TRUE; } else { return FALSE; @@ -1259,18 +1267,9 @@ static void text_delivery_update(SalOp *op, SalTextDeliveryStatus status){ // Do not handle delivery status for isComposing messages. return; } - - chat_msg->state=chatStatusSal2Linphone(status); - linphone_chat_message_update_state(chat_msg); - - if (chat_msg && (chat_msg->cb || (chat_msg->callbacks && linphone_chat_message_cbs_get_msg_state_changed(chat_msg->callbacks)))) { - ms_message("Notifying text delivery with status %i",chat_msg->state); - if (chat_msg->callbacks && linphone_chat_message_cbs_get_msg_state_changed(chat_msg->callbacks)) { - linphone_chat_message_cbs_get_msg_state_changed(chat_msg->callbacks)(chat_msg, chat_msg->state); - } else { - /* Legacy */ - chat_msg->cb(chat_msg,chat_msg->state,chat_msg->cb_ud); - } + // check that the message does not belong to an already destroyed chat room - if so, do not invoke callbacks + if (chat_msg->chat_room != NULL) { + linphone_chat_message_update_state(chat_msg, chatStatusSal2Linphone(status)); } if (status != SalTextDeliveryInProgress) { /*only release op if not in progress*/ linphone_chat_message_destroy(chat_msg); diff --git a/coreapi/chat.c b/coreapi/chat.c index c750c4f69..77d63d32d 100644 --- a/coreapi/chat.c +++ b/coreapi/chat.c @@ -26,7 +26,6 @@ #include "private.h" #include "lpconfig.h" #include "belle-sip/belle-sip.h" -#include "lime.h" #include "ortp/b64.h" #include @@ -37,488 +36,176 @@ #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); -} +static void linphone_chat_message_release(LinphoneChatMessage *msg); +static void linphone_chat_room_delete_composing_idle_timer(LinphoneChatRoom *cr); +static void linphone_chat_room_delete_composing_refresh_timer(LinphoneChatRoom *cr); +static void linphone_chat_room_delete_remote_composing_refresh_timer(LinphoneChatRoom *cr); +static void _linphone_chat_message_destroy(LinphoneChatMessage *msg); BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneChatMessageCbs); BELLE_SIP_INSTANCIATE_VPTR(LinphoneChatMessageCbs, belle_sip_object_t, - NULL, // destroy - NULL, // clone - NULL, // marshal - FALSE -); + NULL, // destroy + NULL, // clone + NULL, // marshal + FALSE); +LinphoneChatMessageCbs *linphone_chat_message_cbs_new(void) { + return belle_sip_object_new(LinphoneChatMessageCbs); +} -/** - * @addtogroup chatroom - * @{ - */ - -/** - * Acquire a reference to the LinphoneChatMessageCbs object. - * @param[in] cbs LinphoneChatMessageCbs object. - * @return The same LinphoneChatMessageCbs object. - */ -LinphoneChatMessageCbs * linphone_chat_message_cbs_ref(LinphoneChatMessageCbs *cbs) { +LinphoneChatMessageCbs *linphone_chat_message_cbs_ref(LinphoneChatMessageCbs *cbs) { belle_sip_object_ref(cbs); return cbs; } -/** - * Release reference to the LinphoneChatMessageCbs object. - * @param[in] cbs LinphoneChatMessageCbs object. - */ void linphone_chat_message_cbs_unref(LinphoneChatMessageCbs *cbs) { belle_sip_object_unref(cbs); } -/** - * Retrieve the user pointer associated with the LinphoneChatMessageCbs object. - * @param[in] cbs LinphoneChatMessageCbs object. - * @return The user pointer associated with the LinphoneChatMessageCbs object. - */ void *linphone_chat_message_cbs_get_user_data(const LinphoneChatMessageCbs *cbs) { return cbs->user_data; } -/** - * Assign a user pointer to the LinphoneChatMessageCbs object. - * @param[in] cbs LinphoneChatMessageCbs object. - * @param[in] ud The user pointer to associate with the LinphoneChatMessageCbs object. - */ void linphone_chat_message_cbs_set_user_data(LinphoneChatMessageCbs *cbs, void *ud) { cbs->user_data = ud; } -/** - * Get the message state changed callback. - * @param[in] cbs LinphoneChatMessageCbs object. - * @return The current message state changed callback. - */ -LinphoneChatMessageCbsMsgStateChangedCb linphone_chat_message_cbs_get_msg_state_changed(const LinphoneChatMessageCbs *cbs) { +LinphoneChatMessageCbsMsgStateChangedCb +linphone_chat_message_cbs_get_msg_state_changed(const LinphoneChatMessageCbs *cbs) { return cbs->msg_state_changed; } -/** - * Set the message state changed callback. - * @param[in] cbs LinphoneChatMessageCbs object. - * @param[in] cb The message state changed callback to be used. - */ -void linphone_chat_message_cbs_set_msg_state_changed(LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsMsgStateChangedCb cb) { +void linphone_chat_message_cbs_set_msg_state_changed(LinphoneChatMessageCbs *cbs, + LinphoneChatMessageCbsMsgStateChangedCb cb) { cbs->msg_state_changed = cb; } -/** - * Get the file transfer receive callback. - * @param[in] cbs LinphoneChatMessageCbs object. - * @return The current file transfer receive callback. - */ LinphoneChatMessageCbsFileTransferRecvCb linphone_chat_message_cbs_get_file_transfer_recv(const LinphoneChatMessageCbs *cbs) { return cbs->file_transfer_recv; } -/** - * Set the file transfer receive callback. - * @param[in] cbs LinphoneChatMessageCbs object. - * @param[in] cb The file transfer receive callback to be used. - */ -void linphone_chat_message_cbs_set_file_transfer_recv(LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsFileTransferRecvCb cb) { +void linphone_chat_message_cbs_set_file_transfer_recv(LinphoneChatMessageCbs *cbs, + LinphoneChatMessageCbsFileTransferRecvCb cb) { cbs->file_transfer_recv = cb; } -/** - * Get the file transfer send callback. - * @param[in] cbs LinphoneChatMessageCbs object. - * @return The current file transfer send callback. - */ LinphoneChatMessageCbsFileTransferSendCb linphone_chat_message_cbs_get_file_transfer_send(const LinphoneChatMessageCbs *cbs) { return cbs->file_transfer_send; } -/** - * Set the file transfer send callback. - * @param[in] cbs LinphoneChatMessageCbs object. - * @param[in] cb The file transfer send callback to be used. - */ -void linphone_chat_message_cbs_set_file_transfer_send(LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsFileTransferSendCb cb) { +void linphone_chat_message_cbs_set_file_transfer_send(LinphoneChatMessageCbs *cbs, + LinphoneChatMessageCbsFileTransferSendCb cb) { cbs->file_transfer_send = cb; } -/** - * Get the file transfer progress indication callback. - * @param[in] cbs LinphoneChatMessageCbs object. - * @return The current file transfer progress indication callback. - */ -LinphoneChatMessageCbsFileTransferProgressIndicationCb linphone_chat_message_cbs_get_file_transfer_progress_indication(const LinphoneChatMessageCbs *cbs) { +LinphoneChatMessageCbsFileTransferProgressIndicationCb +linphone_chat_message_cbs_get_file_transfer_progress_indication(const LinphoneChatMessageCbs *cbs) { return cbs->file_transfer_progress_indication; } -/** - * Set the file transfer progress indication callback. - * @param[in] cbs LinphoneChatMessageCbs object. - * @param[in] cb The file transfer progress indication callback to be used. - */ -void linphone_chat_message_cbs_set_file_transfer_progress_indication(LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsFileTransferProgressIndicationCb cb) { +void linphone_chat_message_cbs_set_file_transfer_progress_indication( + LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsFileTransferProgressIndicationCb cb) { cbs->file_transfer_progress_indication = cb; } -/** - * @} - */ - - - -static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage* msg); - -static void process_io_error_upload(void *data, const belle_sip_io_error_event_t *event){ - LinphoneChatMessage* msg=(LinphoneChatMessage *)data; - ms_error("I/O Error during file upload to %s - msg [%p] chat room[%p]", linphone_core_get_file_transfer_server(msg->chat_room->lc), msg, msg->chat_room); - 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); - } -} -static void process_auth_requested_upload(void *data, belle_sip_auth_event_t *event){ - LinphoneChatMessage* msg=(LinphoneChatMessage *)data; - ms_error("Error during file upload : auth requested to connect %s - msg [%p] chat room[%p]", linphone_core_get_file_transfer_server(msg->chat_room->lc), msg, msg->chat_room); - 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); - } -} - -static void process_io_error_download(void *data, const belle_sip_io_error_event_t *event){ - LinphoneChatMessage* msg=(LinphoneChatMessage *)data; - ms_error("I/O Error during file download %s - msg [%p] chat room[%p]", msg->external_body_url, msg, msg->chat_room); - if (msg->cb) { - msg->cb(msg, LinphoneChatMessageStateFileTransferError, 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, LinphoneChatMessageStateFileTransferError); - } -} -static void process_auth_requested_download(void *data, belle_sip_auth_event_t *event){ - LinphoneChatMessage* msg=(LinphoneChatMessage *)data; - ms_error("Error during file download : auth requested to get %s - msg [%p] chat room[%p]", msg->external_body_url, msg, msg->chat_room); - if (msg->cb) { - msg->cb(msg, LinphoneChatMessageStateFileTransferError, 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, LinphoneChatMessageStateFileTransferError); - } -} - -/** - * Callback called during upload or download of a file from server - * It is just forwarding the call and some parameters to the vtable defined callback - */ -static void linphone_chat_message_file_transfer_on_progress(belle_sip_body_handler_t *bh, belle_sip_message_t *msg, void *data, size_t offset, size_t total){ - LinphoneChatMessage* chatMsg=(LinphoneChatMessage *)data; - if (linphone_chat_message_cbs_get_file_transfer_progress_indication(chatMsg->callbacks)) { - linphone_chat_message_cbs_get_file_transfer_progress_indication(chatMsg->callbacks)(chatMsg, chatMsg->file_transfer_information, offset, total); - } else { - /* Legacy: call back given by application level */ - linphone_core_notify_file_transfer_progress_indication(chatMsg->chat_room->lc, chatMsg, chatMsg->file_transfer_information, offset, total); - } -} - -/** - * Callback called when posting a file to server (following rcs5.1 recommendation) - * - * @param bh the body handler - * @param msg the belle sip message - * @param data the user data associated to the handler, contains the linphoneChatMessage we're working on - * @param offset current position in the input buffer - * @param buffer the ouput buffer we to copy the data to be uploaded - * @param size size in byte of the data requested, as output it will contain the effective copied size - * - */ -static int linphone_chat_message_file_transfer_on_send_body(belle_sip_user_body_handler_t *bh, belle_sip_message_t *msg, void *data, size_t offset, uint8_t *buffer, size_t *size){ - LinphoneChatMessage* chatMsg=(LinphoneChatMessage *)data; - LinphoneCore *lc = chatMsg->chat_room->lc; - char *buf = (char *)buffer; - - /* if we've not reach the end of file yet, ask for more data*/ - if (offsetfile_transfer_information)){ - - 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 { - /* 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); - } - } - } - - return BELLE_SIP_CONTINUE; -} - -/** - * Callback function called when we have a response from server during a file upload to server (rcs5.1 recommandation) - * Note: The first post is empty and the server shall reply a 204 (No content) message, this will trigger a new post request to the server - * to upoad the file. The server response to this second post is processed by this same function - * - * @param data the user define pointer associated with the request, it contains the linphoneChatMessage we're trying to send - * @param event the response from server - */ -static void linphone_chat_message_process_response_from_post_file(void *data, const belle_http_response_event_t *event){ - LinphoneChatMessage* msg=(LinphoneChatMessage *)data; - - /* check the answer code */ - if (event->response){ - int code=belle_http_response_get_status_code(event->response); - if (code == 204) { /* this is the reply to the first post to the server - an empty message */ - /* start uploading the file */ - belle_http_request_listener_callbacks_t cbs={0}; - belle_http_request_listener_t *l; - belle_generic_uri_t *uri; - belle_sip_multipart_body_handler_t *bh; - char* ua; - char *first_part_header; - belle_sip_body_handler_t *first_part_bh; - - /* 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) { - first_part_bh=(belle_sip_body_handler_t *)belle_sip_file_body_handler_new(msg->file_transfer_filepath,NULL,msg); - } else if (linphone_content_get_buffer(msg->file_transfer_information) != NULL) { - first_part_bh=(belle_sip_body_handler_t *)belle_sip_memory_body_handler_new_from_buffer( - linphone_content_get_buffer(msg->file_transfer_information), - linphone_content_get_size(msg->file_transfer_information), - NULL,msg); - } else { - first_part_bh=(belle_sip_body_handler_t *)belle_sip_user_body_handler_new(linphone_content_get_size(msg->file_transfer_information),NULL,NULL,linphone_chat_message_file_transfer_on_send_body,msg); - } - belle_sip_body_handler_add_header(first_part_bh, belle_sip_header_create("Content-disposition", first_part_header)); - belle_sip_free(first_part_header); - belle_sip_body_handler_add_header(first_part_bh, (belle_sip_header_t *)belle_sip_header_content_type_create(linphone_content_get_type(msg->file_transfer_information), linphone_content_get_subtype(msg->file_transfer_information))); - - /* insert it in a multipart body handler which will manage the boundaries of multipart message */ - bh=belle_sip_multipart_body_handler_new(linphone_chat_message_file_transfer_on_progress, msg, first_part_bh); - - /* create the http request: do not include the message header at this point, it is done by bellesip when setting the multipart body handler in the message */ - ua = ms_strdup_printf("%s/%s", linphone_core_get_user_agent_name(), linphone_core_get_user_agent_version()); - uri=belle_generic_uri_parse(linphone_core_get_file_transfer_server(msg->chat_room->lc)); - if (msg->http_request) belle_sip_object_unref(msg->http_request); - msg->http_request=belle_http_request_create("POST", - uri, - belle_sip_header_create("User-Agent",ua), - NULL); - belle_sip_object_ref(msg->http_request); /* keep a reference to the http request to be able to cancel it during upload */ - ms_free(ua); - belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(msg->http_request),BELLE_SIP_BODY_HANDLER(bh)); - cbs.process_response=linphone_chat_message_process_response_from_post_file; - cbs.process_io_error=process_io_error_upload; - cbs.process_auth_requested=process_auth_requested_upload; - 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 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; - - /* 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); - } - if (linphone_chat_message_cbs_get_msg_state_changed(msg->callbacks)) { - linphone_chat_message_cbs_get_msg_state_changed(msg->callbacks)(msg, LinphoneChatMessageStateFileTransferDone); - } - _linphone_chat_room_send_message(msg->chat_room, msg); - } - } -} - - -static void _linphone_chat_message_destroy(LinphoneChatMessage* msg); BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneChatMessage); -BELLE_SIP_INSTANCIATE_VPTR(LinphoneChatMessage,belle_sip_object_t, - (belle_sip_object_destroy_t)_linphone_chat_message_destroy, - NULL, // clone - NULL, // marshal - FALSE -); - - -/** - * @addtogroup chatroom - * @{ - */ - -/** - * Inconditionnaly disable incoming chat messages. - * @param lc the core - * @param deny_reason the deny reason (#LinphoneReasonNone has no effect). -**/ -void linphone_core_disable_chat(LinphoneCore *lc, LinphoneReason deny_reason){ - lc->chat_deny_code=deny_reason; +static void _linphone_chat_room_destroy(LinphoneChatRoom *cr) { + ms_list_free_with_data(cr->transient_messages, (void (*)(void *))linphone_chat_message_release); + linphone_chat_room_delete_composing_idle_timer(cr); + linphone_chat_room_delete_composing_refresh_timer(cr); + linphone_chat_room_delete_remote_composing_refresh_timer(cr); + if (cr->lc != NULL) { + if (ms_list_find(cr->lc->chatrooms, cr)) { + ms_error("LinphoneChatRoom[%p] is destroyed while still being used by the LinphoneCore. This is abnormal." + " linphone_core_get_chat_room() doesn't give a reference, there is no need to call " + "linphone_chat_room_unref(). " + "In order to remove a chat room from the core, use linphone_core_delete_chat_room().", + cr); + cr->lc->chatrooms = ms_list_remove(cr->lc->chatrooms, cr); + } + } + linphone_address_destroy(cr->peer_url); + if (cr->pending_message) + linphone_chat_message_destroy(cr->pending_message); + ms_free(cr->peer); } -/** - * Enable reception of incoming chat messages. - * By default it is enabled but it can be disabled with linphone_core_disable_chat(). - * @param lc the core -**/ -void linphone_core_enable_chat(LinphoneCore *lc){ - lc->chat_deny_code=LinphoneReasonNone; +void linphone_chat_message_set_state(LinphoneChatMessage *msg, LinphoneChatMessageState state) { + /* do not invoke callbacks on orphan messages */ + if (state != msg->state && msg->chat_room != NULL) { + ms_message("Chat message %p: moving from state %s to %s", msg, linphone_chat_message_state_to_string(msg->state), + linphone_chat_message_state_to_string(state)); + msg->state = state; + if (msg->message_state_changed_cb) { + msg->message_state_changed_cb(msg, msg->state, msg->message_state_changed_user_data); + } + if (linphone_chat_message_cbs_get_msg_state_changed(msg->callbacks)) { + linphone_chat_message_cbs_get_msg_state_changed(msg->callbacks)(msg, msg->state); + } + } } -/** - * Returns whether chat is enabled. -**/ -bool_t linphone_core_chat_enabled(const LinphoneCore *lc){ - return lc->chat_deny_code!=LinphoneReasonNone; +BELLE_SIP_INSTANCIATE_VPTR(LinphoneChatMessage, belle_sip_object_t, + (belle_sip_object_destroy_t)_linphone_chat_message_destroy, + NULL, // clone + NULL, // marshal + FALSE); + +void linphone_core_disable_chat(LinphoneCore *lc, LinphoneReason deny_reason) { + lc->chat_deny_code = deny_reason; } -/** - * Returns an list of chat rooms - * @param[in] lc #LinphoneCore object - * @return \mslist{LinphoneChatRoom} -**/ -MSList* linphone_core_get_chat_rooms(LinphoneCore *lc) { +void linphone_core_enable_chat(LinphoneCore *lc) { + lc->chat_deny_code = LinphoneReasonNone; +} + +bool_t linphone_core_chat_enabled(const LinphoneCore *lc) { + return lc->chat_deny_code != LinphoneReasonNone; +} + +const MSList *linphone_core_get_chat_rooms(LinphoneCore *lc) { return lc->chatrooms; } -static bool_t linphone_chat_room_matches(LinphoneChatRoom *cr, const LinphoneAddress *from){ - return linphone_address_weak_equal(cr->peer_url,from); +static bool_t linphone_chat_room_matches(LinphoneChatRoom *cr, const LinphoneAddress *from) { + return linphone_address_weak_equal(cr->peer_url, from); } -static void _linphone_chat_room_destroy(LinphoneChatRoom *obj); - BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneChatRoom); BELLE_SIP_INSTANCIATE_VPTR(LinphoneChatRoom, belle_sip_object_t, - (belle_sip_object_destroy_t)_linphone_chat_room_destroy, - NULL, // clone - NULL, // marshal - FALSE -); + (belle_sip_object_destroy_t)_linphone_chat_room_destroy, + NULL, // clone + NULL, // marshal + FALSE); -static LinphoneChatRoom * _linphone_core_create_chat_room(LinphoneCore *lc, LinphoneAddress *addr) { +static LinphoneChatRoom *_linphone_core_create_chat_room_base(LinphoneCore *lc, LinphoneAddress *addr){ LinphoneChatRoom *cr = belle_sip_object_new(LinphoneChatRoom); cr->lc = lc; cr->peer = linphone_address_as_string(addr); cr->peer_url = addr; + cr->unread_count = -1; + cr->received_rtt_characters = NULL; + return cr; +} + +static LinphoneChatRoom *_linphone_core_create_chat_room(LinphoneCore *lc, LinphoneAddress *addr) { + LinphoneChatRoom *cr = _linphone_core_create_chat_room_base(lc, addr); lc->chatrooms = ms_list_append(lc->chatrooms, (void *)cr); return cr; } -static LinphoneChatRoom * _linphone_core_create_chat_room_from_url(LinphoneCore *lc, const char *to) { +LinphoneChatRoom *_linphone_core_create_chat_room_from_call(LinphoneCall *call){ + LinphoneChatRoom *cr = _linphone_core_create_chat_room_base(call->core, + linphone_address_clone(linphone_call_get_remote_address(call))); + cr->call = call; + return cr; +} + +static LinphoneChatRoom *_linphone_core_create_chat_room_from_url(LinphoneCore *lc, const char *to) { LinphoneAddress *parsed_url = NULL; if ((parsed_url = linphone_core_interpret_url(lc, to)) != NULL) { return _linphone_core_create_chat_room(lc, parsed_url); @@ -526,64 +213,36 @@ static LinphoneChatRoom * _linphone_core_create_chat_room_from_url(LinphoneCore return NULL; } -LinphoneChatRoom * _linphone_core_get_chat_room(LinphoneCore *lc, const LinphoneAddress *addr){ - LinphoneChatRoom *cr=NULL; +LinphoneChatRoom *_linphone_core_get_chat_room(LinphoneCore *lc, const LinphoneAddress *addr) { + LinphoneChatRoom *cr = NULL; MSList *elem; - for(elem=lc->chatrooms;elem!=NULL;elem=ms_list_next(elem)){ - cr=(LinphoneChatRoom*)elem->data; - if (linphone_chat_room_matches(cr,addr)){ + for (elem = lc->chatrooms; elem != NULL; elem = ms_list_next(elem)) { + cr = (LinphoneChatRoom *)elem->data; + if (linphone_chat_room_matches(cr, addr)) { break; } - cr=NULL; + cr = NULL; } return cr; } -static LinphoneChatRoom * _linphone_core_get_or_create_chat_room(LinphoneCore* lc, const char* to) { - LinphoneAddress *to_addr=linphone_core_interpret_url(lc,to); +static LinphoneChatRoom *_linphone_core_get_or_create_chat_room(LinphoneCore *lc, const char *to) { + LinphoneAddress *to_addr = linphone_core_interpret_url(lc, to); LinphoneChatRoom *ret; - if (to_addr==NULL){ - ms_error("linphone_core_get_or_create_chat_room(): Cannot make a valid address with %s",to); + if (to_addr == NULL) { + ms_error("linphone_core_get_or_create_chat_room(): Cannot make a valid address with %s", to); return NULL; } - ret=_linphone_core_get_chat_room(lc,to_addr); + ret = _linphone_core_get_chat_room(lc, to_addr); linphone_address_destroy(to_addr); - if (!ret){ - ret=_linphone_core_create_chat_room_from_url(lc,to); + if (!ret) { + ret = _linphone_core_create_chat_room_from_url(lc, to); } return ret; } -/** - * Create a new chat room for messaging from a sip uri like sip:joe@sip.linphone.org if not already existing, else return exisiting one - * @param lc #LinphoneCore object - * @param to destination address for messages - * @return #LinphoneChatRoom where messaging can take place. - * @deprecated Use linphone_core_get_chat_room() or linphone_core_get_chat_room_from_uri() instead. - */ -LinphoneChatRoom* linphone_core_get_or_create_chat_room(LinphoneCore* lc, const char* to) { - return _linphone_core_get_or_create_chat_room(lc, to); -} - -/** - * Create a new chat room for messaging from a sip uri like sip:joe@sip.linphone.org - * @param lc #LinphoneCore object - * @param to destination address for messages - * @return #LinphoneChatRoom where messaging can take place. - * @deprecated Use linphone_core_get_chat_room() or linphone_core_get_chat_room_from_uri() instead. - */ -LinphoneChatRoom * linphone_core_create_chat_room(LinphoneCore *lc, const char *to) { - return _linphone_core_get_or_create_chat_room(lc, to); -} - -/** - * Get a chat room whose peer is the supplied address. If it does not exist yet, it will be created. - * @param lc the linphone core - * @param addr a linphone address. - * @return #LinphoneChatRoom where messaging can take place. -**/ -LinphoneChatRoom *linphone_core_get_chat_room(LinphoneCore *lc, const LinphoneAddress *addr){ +LinphoneChatRoom *linphone_core_get_chat_room(LinphoneCore *lc, const LinphoneAddress *addr) { LinphoneChatRoom *ret = _linphone_core_get_chat_room(lc, addr); if (!ret) { ret = _linphone_core_create_chat_room(lc, linphone_address_clone(addr)); @@ -591,19 +250,23 @@ LinphoneChatRoom *linphone_core_get_chat_room(LinphoneCore *lc, const LinphoneAd return ret; } -/** - * Get a chat room for messaging from a sip uri like sip:joe@sip.linphone.org. If it does not exist yet, it will be created. - * @param lc The linphone core - * @param to The destination address for messages. - * @return #LinphoneChatRoom where messaging can take place. -**/ -LinphoneChatRoom * linphone_core_get_chat_room_from_uri(LinphoneCore *lc, const char *to) { +void linphone_core_delete_chat_room(LinphoneCore *lc, LinphoneChatRoom *cr) { + if (ms_list_find(lc->chatrooms, cr)) { + lc->chatrooms = ms_list_remove(cr->lc->chatrooms, cr); + linphone_chat_room_delete_history(cr); + linphone_chat_room_unref(cr); + } else { + ms_error("linphone_core_delete_chat_room(): chatroom [%p] isn't part of LinphoneCore.", cr); + } +} + +LinphoneChatRoom *linphone_core_get_chat_room_from_uri(LinphoneCore *lc, const char *to) { return _linphone_core_get_or_create_chat_room(lc, to); } static void linphone_chat_room_delete_composing_idle_timer(LinphoneChatRoom *cr) { if (cr->composing_idle_timer) { - if(cr-> lc && cr->lc->sal) + if (cr->lc && cr->lc->sal) sal_cancel_timer(cr->lc->sal, cr->composing_idle_timer); belle_sip_object_unref(cr->composing_idle_timer); cr->composing_idle_timer = NULL; @@ -612,7 +275,7 @@ static void linphone_chat_room_delete_composing_idle_timer(LinphoneChatRoom *cr) static void linphone_chat_room_delete_composing_refresh_timer(LinphoneChatRoom *cr) { if (cr->composing_refresh_timer) { - if(cr->lc && cr->lc->sal) + if (cr->lc && cr->lc->sal) sal_cancel_timer(cr->lc->sal, cr->composing_refresh_timer); belle_sip_object_unref(cr->composing_refresh_timer); cr->composing_refresh_timer = NULL; @@ -621,31 +284,17 @@ static void linphone_chat_room_delete_composing_refresh_timer(LinphoneChatRoom * static void linphone_chat_room_delete_remote_composing_refresh_timer(LinphoneChatRoom *cr) { if (cr->remote_composing_refresh_timer) { - if(cr->lc && cr->lc->sal) + if (cr->lc && cr->lc->sal) sal_cancel_timer(cr->lc->sal, cr->remote_composing_refresh_timer); belle_sip_object_unref(cr->remote_composing_refresh_timer); cr->remote_composing_refresh_timer = NULL; } } -static void _linphone_chat_room_destroy(LinphoneChatRoom *cr){ - ms_list_free_with_data(cr->transient_messages, (void (*)(void*))linphone_chat_message_unref); - linphone_chat_room_delete_composing_idle_timer(cr); - linphone_chat_room_delete_composing_refresh_timer(cr); - linphone_chat_room_delete_remote_composing_refresh_timer(cr); - if (cr->lc != NULL) { - cr->lc->chatrooms=ms_list_remove(cr->lc->chatrooms,(void *) cr); - } - linphone_address_destroy(cr->peer_url); - ms_free(cr->peer); -} - -/** - * Destroy a LinphoneChatRoom. - * @param cr #LinphoneChatRoom object - * @deprecated Use linphone_chat_room_unref() instead. - */ void linphone_chat_room_destroy(LinphoneChatRoom *cr) { + if (cr->received_rtt_characters) { + cr->received_rtt_characters = ms_list_free(cr->received_rtt_characters); + } linphone_chat_room_unref(cr); } @@ -654,7 +303,7 @@ void linphone_chat_room_release(LinphoneChatRoom *cr) { linphone_chat_room_unref(cr); } -LinphoneChatRoom * linphone_chat_room_ref(LinphoneChatRoom *cr) { +LinphoneChatRoom *linphone_chat_room_ref(LinphoneChatRoom *cr) { belle_sip_object_ref(cr); return cr; } @@ -663,7 +312,7 @@ void linphone_chat_room_unref(LinphoneChatRoom *cr) { belle_sip_object_unref(cr); } -void * linphone_chat_room_get_user_data(const LinphoneChatRoom *cr) { +void *linphone_chat_room_get_user_data(const LinphoneChatRoom *cr) { return cr->user_data; } @@ -671,186 +320,192 @@ void linphone_chat_room_set_user_data(LinphoneChatRoom *cr, void *ud) { cr->user_data = ud; } - -static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage* msg){ - SalOp *op=NULL; - LinphoneCall *call; - char* content_type; - const char *identity=NULL; - time_t t=time(NULL); - linphone_chat_message_ref(msg); - /* Check if we shall upload a file to a server */ - if (msg->file_transfer_information != NULL && msg->content_type == NULL) { - /* open a transaction with the server and send an empty request(RCS5.1 section 3.5.4.8.3.1) */ - belle_http_request_listener_callbacks_t cbs={0}; - belle_http_request_listener_t *l; - belle_generic_uri_t *uri; - const char *transfer_server = linphone_core_get_file_transfer_server(cr->lc); - - if (transfer_server == NULL) { - ms_warning("Cannot send file transfer message: no file transfer server configured."); - return; - } - uri=belle_generic_uri_parse(transfer_server); - - msg->http_request=belle_http_request_create("POST", - uri, - NULL, - NULL, - NULL); - belle_sip_object_ref(msg->http_request); /* keep a reference on the request to be able to cancel it */ - cbs.process_response=linphone_chat_message_process_response_from_post_file; - cbs.process_io_error=process_io_error_upload; - cbs.process_auth_requested=process_auth_requested_upload; - l=belle_http_request_listener_create_from_callbacks(&cbs,msg); /* give msg to listener to be able to start the actual file upload when server answer a 204 No content */ - belle_http_provider_send_request(cr->lc->http_provider,msg->http_request,l); +void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage *msg) { + /*stubed rtt text*/ + if (cr->call && linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(cr->call))) { + uint32_t new_line = 0x2028; + linphone_chat_message_put_char(msg, new_line); // New Line + linphone_chat_message_set_state(msg, LinphoneChatMessageStateDelivered); linphone_chat_message_unref(msg); return; } - if (lp_config_get_int(cr->lc->config,"sip","chat_use_call_dialogs",0)){ - if((call = linphone_core_get_call_by_remote_address(cr->lc,cr->peer))!=NULL){ - if (call->state==LinphoneCallConnected || - call->state==LinphoneCallStreamsRunning || - call->state==LinphoneCallPaused || - call->state==LinphoneCallPausing || - call->state==LinphoneCallPausedByRemote){ - ms_message("send SIP message through the existing call."); - op = call->op; - identity=linphone_core_find_best_identity(cr->lc,linphone_call_get_remote_address(call)); - } - } - } - msg->time=t; - if (op==NULL){ - LinphoneProxyConfig *proxy=linphone_core_lookup_known_proxy(cr->lc,cr->peer_url); - if (proxy){ - identity=linphone_proxy_config_get_identity(proxy); - }else identity=linphone_core_get_primary_contact(cr->lc); - /*sending out of calls*/ - msg->op = op = sal_op_new(cr->lc->sal); - 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, NULL); - ms_free(content_type); - } 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 { - 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); + msg->dir = LinphoneChatMessageOutgoing; // add to transient list cr->transient_messages = ms_list_append(cr->transient_messages, linphone_chat_message_ref(msg)); - if (cr->is_composing == LinphoneIsComposingActive) { - cr->is_composing = LinphoneIsComposingIdle; + /* Check if we shall upload a file to a server */ + if (msg->file_transfer_information != NULL && msg->content_type == NULL) { + /* open a transaction with the server and send an empty request(RCS5.1 section 3.5.4.8.3.1) */ + linphone_chat_room_upload_file(msg); + } else { + SalOp *op = NULL; + LinphoneCall *call; + char *content_type; + const char *identity = NULL; + msg->time = ms_time(0); + if (lp_config_get_int(cr->lc->config, "sip", "chat_use_call_dialogs", 0) != 0) { + if ((call = linphone_core_get_call_by_remote_address(cr->lc, cr->peer)) != NULL) { + if (call->state == LinphoneCallConnected || call->state == LinphoneCallStreamsRunning || + call->state == LinphoneCallPaused || call->state == LinphoneCallPausing || + call->state == LinphoneCallPausedByRemote) { + ms_message("send SIP msg through the existing call."); + op = call->op; + identity = linphone_core_find_best_identity(cr->lc, linphone_call_get_remote_address(call)); + } + } + } + if (op == NULL) { + LinphoneProxyConfig *proxy = linphone_core_lookup_known_proxy(cr->lc, cr->peer_url); + if (proxy) { + identity = linphone_proxy_config_get_identity(proxy); + } else + identity = linphone_core_get_primary_contact(cr->lc); + /*sending out of calls*/ + msg->op = op = sal_op_new(cr->lc->sal); + 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, NULL); + ms_free(content_type); + } else { + char *peer_uri = linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr)); + const char *content_type; + + if (linphone_core_lime_enabled(cr->lc)) { + /* ref the msg or it may be destroyed by callback if the encryption failed */ + if (msg->content_type && 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*/ + content_type = "application/cipher.vnd.gsma.rcs-ft-http+xml"; + } else { + content_type = "xml/cipher"; + } + } else { + content_type = msg->content_type; + } + + if (content_type == NULL) { + sal_text_send(op, identity, cr->peer, msg->message); + } else { + sal_message_send(op, identity, cr->peer, content_type, msg->message, peer_uri); + } + ms_free(peer_uri); + } + + if (msg->from){ + /* + * BUG + * the file transfer message constructor sets the from, but doesn't do it as well as here. + */ + linphone_address_destroy(msg->from); + } + msg->from = linphone_address_new(identity); + msg->storage_id = linphone_chat_message_store(msg); + + if (cr->unread_count >= 0 && !msg->is_read) + cr->unread_count++; + + if (cr->is_composing == LinphoneIsComposingActive) { + cr->is_composing = LinphoneIsComposingIdle; + } + linphone_chat_room_delete_composing_idle_timer(cr); + linphone_chat_room_delete_composing_refresh_timer(cr); + } - linphone_chat_room_delete_composing_idle_timer(cr); - linphone_chat_room_delete_composing_refresh_timer(cr); - linphone_chat_message_unref(msg); + linphone_chat_message_set_state(msg, LinphoneChatMessageStateInProgress); } -void linphone_chat_message_update_state(LinphoneChatMessage* chat_msg ) { - linphone_chat_message_store_state(chat_msg); +void linphone_chat_message_update_state(LinphoneChatMessage *msg, LinphoneChatMessageState new_state) { + linphone_chat_message_set_state(msg, new_state); + linphone_chat_message_store_state(msg); - if( chat_msg->state == LinphoneChatMessageStateDelivered - || chat_msg->state == LinphoneChatMessageStateNotDelivered ){ - // message is not transient anymore, we can remove it from our transient list and unref it : - chat_msg->chat_room->transient_messages = ms_list_remove(chat_msg->chat_room->transient_messages, chat_msg); - linphone_chat_message_unref(chat_msg); + if (msg->state == LinphoneChatMessageStateDelivered || msg->state == LinphoneChatMessageStateNotDelivered) { + // msg is not transient anymore, we can remove it from our transient list and unref it + msg->chat_room->transient_messages = ms_list_remove(msg->chat_room->transient_messages, msg); + linphone_chat_message_unref(msg); } } -/** - * Send a message to peer member of this chat room. - * @deprecated linphone_chat_room_send_message2() gives more control on the message expedition. - * @param cr #LinphoneChatRoom object - * @param msg message to be sent - */ void linphone_chat_room_send_message(LinphoneChatRoom *cr, const char *msg) { - _linphone_chat_room_send_message(cr,linphone_chat_room_create_message(cr,msg)); + _linphone_chat_room_send_message(cr, linphone_chat_room_create_message(cr, msg)); } -void linphone_chat_room_message_received(LinphoneChatRoom *cr, LinphoneCore *lc, LinphoneChatMessage *msg){ - if (msg->message){ +void linphone_chat_room_message_received(LinphoneChatRoom *cr, LinphoneCore *lc, LinphoneChatMessage *msg) { + if (msg->message) { /*legacy API*/ linphone_core_notify_text_message_received(lc, cr, msg->from, msg->message); } - linphone_core_notify_message_received(lc, cr,msg); + linphone_core_notify_message_received(lc, cr, msg); cr->remote_is_composing = LinphoneIsComposingIdle; linphone_core_notify_is_composing_received(cr->lc, cr); } -void linphone_core_message_received(LinphoneCore *lc, SalOp *op, const SalMessage *sal_msg){ - LinphoneChatRoom *cr=NULL; +void linphone_core_message_received(LinphoneCore *lc, SalOp *op, const SalMessage *sal_msg) { + LinphoneChatRoom *cr = NULL; LinphoneAddress *addr; - LinphoneChatMessage* msg; + LinphoneChatMessage *msg; const SalCustomHeader *ch; - addr=linphone_address_new(sal_msg->from); + addr = linphone_address_new(sal_msg->from); linphone_address_clean(addr); - cr=linphone_core_get_chat_room(lc,addr); + cr = linphone_core_get_chat_room(lc, addr); - if (sal_msg->content_type != NULL) { /* content_type field is, for now, used only for rcs file transfer but we shall strcmp it with "application/vnd.gsma.rcs-ft-http+xml" */ + if (sal_msg->content_type != + NULL) { /* content_type field is, for now, used only for rcs file transfer but we shall strcmp it with + "application/vnd.gsma.rcs-ft-http+xml" */ xmlChar *file_url = NULL; xmlDocPtr xmlMessageBody; xmlNodePtr cur; - msg = linphone_chat_room_create_message(cr, NULL); /* create a message with empty body */ - msg->content_type = ms_strdup(sal_msg->content_type); /* add the content_type "application/vnd.gsma.rcs-ft-http+xml" */ + msg = linphone_chat_room_create_message(cr, NULL); /* create a msg with empty body */ + msg->content_type = + ms_strdup(sal_msg->content_type); /* add the content_type "application/vnd.gsma.rcs-ft-http+xml" */ msg->file_transfer_information = linphone_content_new(); - /* parse the message body to get all informations from it */ + /* parse the msg body to get all informations from it */ xmlMessageBody = xmlParseDoc((const xmlChar *)sal_msg->text); 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 */ + 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 */ + if (!xmlStrcmp(typeAttribute, (const xmlChar *)"file")) { /* this is the node we are looking for */ cur = cur->xmlChildrenNode; /* now loop on the content of the file-info node */ - while (cur!=NULL) { + while (cur != NULL) { if (!xmlStrcmp(cur->name, (const xmlChar *)"file-size")) { xmlChar *fileSizeString = xmlNodeListGetString(xmlMessageBody, cur->xmlChildrenNode, 1); - linphone_content_set_size(msg->file_transfer_information, strtol((const char*)fileSizeString, NULL, 10)); + linphone_content_set_size(msg->file_transfer_information, + strtol((const char *)fileSizeString, NULL, 10)); xmlFree(fileSizeString); } if (!xmlStrcmp(cur->name, (const xmlChar *)"file-name")) { - linphone_content_set_name(msg->file_transfer_information, (const char *)xmlNodeListGetString(xmlMessageBody, cur->xmlChildrenNode, 1)); + xmlChar *filename = xmlNodeListGetString(xmlMessageBody, cur->xmlChildrenNode, 1); + linphone_content_set_name( + msg->file_transfer_information, + (char *)filename); + xmlFree(filename); } if (!xmlStrcmp(cur->name, (const xmlChar *)"content-type")) { xmlChar *contentType = xmlNodeListGetString(xmlMessageBody, cur->xmlChildrenNode, 1); int contentTypeIndex = 0; char *type; char *subtype; - while (contentType[contentTypeIndex]!='/' && contentType[contentTypeIndex]!='\0') { + while (contentType[contentTypeIndex] != '/' && contentType[contentTypeIndex] != '\0') { contentTypeIndex++; } type = ms_strndup((char *)contentType, contentTypeIndex); - subtype = ms_strdup(((char *)contentType+contentTypeIndex+1)); + subtype = ms_strdup(((char *)contentType + contentTypeIndex + 1)); linphone_content_set_type(msg->file_transfer_information, type); linphone_content_set_subtype(msg->file_transfer_information, subtype); ms_free(subtype); @@ -858,22 +513,26 @@ void linphone_core_message_received(LinphoneCore *lc, SalOp *op, const SalMessag xmlFree(contentType); } if (!xmlStrcmp(cur->name, (const xmlChar *)"data")) { - file_url = xmlGetProp(cur, (const xmlChar *)"url"); + 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 */ + if (!xmlStrcmp(cur->name, + (const xmlChar *)"file-key")) { /* there is a key in the msg: file has + been encrypted */ /* convert the key from base 64 */ xmlChar *keyb64 = xmlNodeListGetString(xmlMessageBody, cur->xmlChildrenNode, 1); - int keyLength = b64_decode((char *)keyb64, strlen((char *)keyb64), NULL, 0); + size_t 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 */ + 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; + cur = cur->next; } xmlFree(typeAttribute); break; @@ -887,31 +546,39 @@ void linphone_core_message_received(LinphoneCore *lc, SalOp *op, const SalMessag linphone_chat_message_set_external_body_url(msg, (const char *)file_url); xmlFree(file_url); - } else { /* message is not rcs file transfer, create it with provided sal_msg->text as ->message */ + } else { /* msg is not rcs file transfer, create it with provided sal_msg->text as ->msg */ msg = linphone_chat_room_create_message(cr, sal_msg->text); } linphone_chat_message_set_from(msg, cr->peer_url); { LinphoneAddress *to; - to=sal_op_get_to(op) ? linphone_address_new(sal_op_get_to(op)) : linphone_address_new(linphone_core_get_identity(lc)); - msg->to=to; + to = sal_op_get_to(op) ? linphone_address_new(sal_op_get_to(op)) + : linphone_address_new(linphone_core_get_identity(lc)); + msg->to = to; } - msg->time=sal_msg->time; - msg->state=LinphoneChatMessageStateDelivered; - msg->is_read=FALSE; - msg->dir=LinphoneChatMessageIncoming; - ch=sal_op_get_recv_custom_header(op); - if (ch) msg->custom_headers=sal_custom_header_clone(ch); + msg->time = sal_msg->time; + msg->state = LinphoneChatMessageStateDelivered; + msg->is_read = FALSE; + msg->dir = LinphoneChatMessageIncoming; + ch = sal_op_get_recv_custom_header(op); + if (ch) + msg->custom_headers = sal_custom_header_clone(ch); if (sal_msg->url) { linphone_chat_message_set_external_body_url(msg, sal_msg->url); } linphone_address_destroy(addr); - msg->storage_id=linphone_chat_message_store(msg); - linphone_chat_room_message_received(cr,lc,msg); + msg->storage_id = linphone_chat_message_store(msg); + + if (cr->unread_count < 0) + cr->unread_count = 1; + else + cr->unread_count++; + + linphone_chat_room_message_received(cr, lc, msg); linphone_chat_message_unref(msg); } @@ -931,22 +598,29 @@ static void process_im_is_composing_notification(LinphoneChatRoom *cr, xmlparsin xmlXPathObjectPtr iscomposing_object; const char *state_str = NULL; const char *refresh_str = NULL; - int refresh_duration = lp_config_get_int(cr->lc->config, "sip", "composing_remote_refresh_timeout", COMPOSING_DEFAULT_REMOTE_REFRESH_TIMEOUT); + int refresh_duration = lp_config_get_int(cr->lc->config, "sip", "composing_remote_refresh_timeout", + COMPOSING_DEFAULT_REMOTE_REFRESH_TIMEOUT); int i; LinphoneIsComposingState state = LinphoneIsComposingIdle; - if (linphone_create_xml_xpath_context(xml_ctx) < 0) return; + if (linphone_create_xml_xpath_context(xml_ctx) < 0) + return; - xmlXPathRegisterNs(xml_ctx->xpath_ctx, (const xmlChar *)"xsi", (const xmlChar *)"urn:ietf:params:xml:ns:im-iscomposing"); + xmlXPathRegisterNs(xml_ctx->xpath_ctx, (const xmlChar *)"xsi", + (const xmlChar *)"urn:ietf:params:xml:ns:im-iscomposing"); iscomposing_object = linphone_get_xml_xpath_object_for_node_list(xml_ctx, iscomposing_prefix); - if ((iscomposing_object != NULL) && (iscomposing_object->nodesetval != NULL)) { - for (i = 1; i <= iscomposing_object->nodesetval->nodeNr; i++) { - snprintf(xpath_str, sizeof(xpath_str), "%s[%i]/xsi:state", iscomposing_prefix, i); - state_str = linphone_get_xml_text_content(xml_ctx, xpath_str); - if (state_str == NULL) continue; - snprintf(xpath_str, sizeof(xpath_str), "%s[%i]/xsi:refresh", iscomposing_prefix, i); - refresh_str = linphone_get_xml_text_content(xml_ctx, xpath_str); + if (iscomposing_object != NULL) { + if (iscomposing_object->nodesetval != NULL) { + for (i = 1; i <= iscomposing_object->nodesetval->nodeNr; i++) { + snprintf(xpath_str, sizeof(xpath_str), "%s[%i]/xsi:state", iscomposing_prefix, i); + state_str = linphone_get_xml_text_content(xml_ctx, xpath_str); + if (state_str == NULL) + continue; + snprintf(xpath_str, sizeof(xpath_str), "%s[%i]/xsi:refresh", iscomposing_prefix, i); + refresh_str = linphone_get_xml_text_content(xml_ctx, xpath_str); + } } + xmlXPathFreeObject(iscomposing_object); } if (state_str != NULL) { @@ -956,7 +630,9 @@ static void process_im_is_composing_notification(LinphoneChatRoom *cr, xmlparsin refresh_duration = atoi(refresh_str); } if (!cr->remote_composing_refresh_timer) { - cr->remote_composing_refresh_timer = sal_create_timer(cr->lc->sal, linphone_chat_room_remote_refresh_composing_expired, cr, refresh_duration * 1000, "composing remote refresh timeout"); + cr->remote_composing_refresh_timer = + sal_create_timer(cr->lc->sal, linphone_chat_room_remote_refresh_composing_expired, cr, + refresh_duration * 1000, "composing remote refresh timeout"); } else { belle_sip_source_set_timeout(cr->remote_composing_refresh_timer, refresh_duration * 1000); } @@ -976,7 +652,7 @@ static void process_im_is_composing_notification(LinphoneChatRoom *cr, xmlparsin static void linphone_chat_room_notify_is_composing(LinphoneChatRoom *cr, const char *text) { xmlparsing_context_t *xml_ctx = linphone_xmlparsing_context_new(); xmlSetGenericErrorFunc(xml_ctx, linphone_xmlparsing_genericxml_error); - xml_ctx->doc = xmlReadDoc((const unsigned char*)text, 0, NULL, 0); + xml_ctx->doc = xmlReadDoc((const unsigned char *)text, 0, NULL, 0); if (xml_ctx->doc != NULL) { process_im_is_composing_notification(cr, xml_ctx); } else { @@ -986,125 +662,77 @@ static void linphone_chat_room_notify_is_composing(LinphoneChatRoom *cr, const c } void linphone_core_is_composing_received(LinphoneCore *lc, SalOp *op, const SalIsComposing *is_composing) { - LinphoneChatRoom *cr = linphone_core_get_or_create_chat_room(lc, is_composing->from); + LinphoneAddress *addr = linphone_address_new(is_composing->from); + LinphoneChatRoom *cr = _linphone_core_get_chat_room(lc, addr); if (cr != NULL) { linphone_chat_room_notify_is_composing(cr, is_composing->text); } + linphone_address_destroy(addr); } bool_t linphone_chat_room_is_remote_composing(const LinphoneChatRoom *cr) { return (cr->remote_is_composing == LinphoneIsComposingActive) ? TRUE : FALSE; } -/** - * Returns back pointer to LinphoneCore object. - * @deprecated use linphone_chat_room_get_core() -**/ -LinphoneCore* linphone_chat_room_get_lc(LinphoneChatRoom *cr){ +LinphoneCore *linphone_chat_room_get_lc(LinphoneChatRoom *cr) { return cr->lc; } -/** - * Returns back pointer to LinphoneCore object. -**/ -LinphoneCore* linphone_chat_room_get_core(LinphoneChatRoom *cr){ +LinphoneCore *linphone_chat_room_get_core(LinphoneChatRoom *cr) { return cr->lc; } -/** - * get peer address \link linphone_core_create_chat_room() associated to \endlink this #LinphoneChatRoom - * @param cr #LinphoneChatRoom object - * @return #LinphoneAddress peer address - */ -const LinphoneAddress* linphone_chat_room_get_peer_address(LinphoneChatRoom *cr) { +const LinphoneAddress *linphone_chat_room_get_peer_address(LinphoneChatRoom *cr) { return cr->peer_url; } -/** - * Create a message attached to a dedicated chat room; - * @param cr the chat room. - * @param message text message, NULL if absent. - * @return a new #LinphoneChatMessage - */ -LinphoneChatMessage* linphone_chat_room_create_message(LinphoneChatRoom *cr, const char* message) { - LinphoneChatMessage* msg = belle_sip_object_new(LinphoneChatMessage); - msg->callbacks=linphone_chat_message_cbs_new(); - msg->chat_room=(LinphoneChatRoom*)cr; - msg->message=message?ms_strdup(message):NULL; - msg->is_read=TRUE; - msg->content_type = NULL; /* this property is used only when transfering file */ +LinphoneChatMessage *linphone_chat_room_create_message(LinphoneChatRoom *cr, const char *message) { + LinphoneChatMessage *msg = belle_sip_object_new(LinphoneChatMessage); + msg->state = LinphoneChatMessageStateIdle; + msg->callbacks = linphone_chat_message_cbs_new(); + msg->chat_room = (LinphoneChatRoom *)cr; + msg->message = message ? ms_strdup(message) : NULL; + msg->is_read = TRUE; + msg->content_type = NULL; /* this property is used only when transfering file */ msg->file_transfer_information = NULL; /* this property is used only when transfering file */ msg->http_request = NULL; + msg->time = ms_time(0); return msg; } -/** - * Create a message attached to a dedicated chat room; - * @param cr the chat room. - * @param message text message, NULL if absent. - * @param external_body_url the URL given in external body or NULL. - * @param state the LinphoneChatMessage.State of the message. - * @param time the time_t at which the message has been received/sent. - * @param is_read TRUE if the message should be flagged as read, FALSE otherwise. - * @param is_incoming TRUE if the message has been received, FALSE otherwise. - * @return a new #LinphoneChatMessage - */ -LinphoneChatMessage* linphone_chat_room_create_message_2( - LinphoneChatRoom *cr, const char* message, const char* external_body_url, - LinphoneChatMessageState state, time_t time, bool_t is_read, bool_t is_incoming) { - LinphoneCore *lc=linphone_chat_room_get_lc(cr); - - LinphoneChatMessage* msg = belle_sip_object_new(LinphoneChatMessage); - msg->callbacks=linphone_chat_message_cbs_new(); - msg->chat_room=(LinphoneChatRoom*)cr; - msg->message=message?ms_strdup(message):NULL; - msg->external_body_url=external_body_url?ms_strdup(external_body_url):NULL; - msg->time=time; - msg->state=state; - msg->is_read=is_read; - msg->content_type = NULL; /* this property is used only when transfering file */ - msg->file_transfer_information = NULL; /* this property is used only when transfering file */ +LinphoneChatMessage *linphone_chat_room_create_message_2(LinphoneChatRoom *cr, const char *message, + const char *external_body_url, LinphoneChatMessageState state, + time_t time, bool_t is_read, bool_t is_incoming) { + LinphoneChatMessage *msg = linphone_chat_room_create_message(cr, message); + LinphoneCore *lc = linphone_chat_room_get_lc(cr); + msg->external_body_url = external_body_url ? ms_strdup(external_body_url) : NULL; + msg->time = time; + msg->is_read = is_read; + linphone_chat_message_set_state(msg, state); if (is_incoming) { - msg->dir=LinphoneChatMessageIncoming; + msg->dir = LinphoneChatMessageIncoming; linphone_chat_message_set_from(msg, linphone_chat_room_get_peer_address(cr)); - linphone_chat_message_set_to(msg, linphone_address_new(linphone_core_get_identity(lc))); + msg->to = linphone_address_new(linphone_core_get_identity(lc)); /*direct assignment*/ } else { - msg->dir=LinphoneChatMessageOutgoing; + msg->dir = LinphoneChatMessageOutgoing; linphone_chat_message_set_to(msg, linphone_chat_room_get_peer_address(cr)); - linphone_chat_message_set_from(msg, linphone_address_new(linphone_core_get_identity(lc))); + msg->from = linphone_address_new(linphone_core_get_identity(lc));/*direct assignment*/ } return msg; } -/** - * Send a message to peer member of this chat room. - * @param cr #LinphoneChatRoom object - * @param msg #LinphoneChatMessage message to be sent - * @param status_cb LinphoneChatMessageStateChangeCb status callback invoked when message is delivered or could not be delivered. May be NULL - * @param ud user data for the status cb. - * @deprecated Use linphone_chat_room_send_chat_message() instead. - * @note The LinphoneChatMessage must not be destroyed until the the callback is called. - */ -void linphone_chat_room_send_message2(LinphoneChatRoom *cr, LinphoneChatMessage* msg,LinphoneChatMessageStateChangedCb status_cb, void* ud) { - msg->cb=status_cb; - msg->cb_ud=ud; - msg->state=LinphoneChatMessageStateInProgress; +void linphone_chat_room_send_message2(LinphoneChatRoom *cr, LinphoneChatMessage *msg, + LinphoneChatMessageStateChangedCb status_cb, void *ud) { + msg->message_state_changed_cb = status_cb; + msg->message_state_changed_user_data = ud; _linphone_chat_room_send_message(cr, msg); } -/** - * Send a message to peer member of this chat room. - * @param[in] cr LinphoneChatRoom object - * @param[in] msg LinphoneChatMessage object - * The state of the message sending will be notified via the callbacks defined in the LinphoneChatMessageCbs object that can be obtained - * by calling linphone_chat_message_get_callbacks(). - */ void linphone_chat_room_send_chat_message(LinphoneChatRoom *cr, LinphoneChatMessage *msg) { - msg->state = LinphoneChatMessageStateInProgress; _linphone_chat_room_send_message(cr, msg); } -static char * linphone_chat_room_create_is_composing_xml(LinphoneChatRoom *cr) { +static char *linphone_chat_room_create_is_composing_xml(LinphoneChatRoom *cr) { xmlBufferPtr buf; xmlTextWriterPtr writer; int err; @@ -1123,23 +751,26 @@ static char * linphone_chat_room_create_is_composing_xml(LinphoneChatRoom *cr) { err = xmlTextWriterStartDocument(writer, "1.0", "UTF-8", NULL); if (err >= 0) { - err = xmlTextWriterStartElementNS(writer, NULL, (const xmlChar *)"isComposing", (const xmlChar *)"urn:ietf:params:xml:ns:im-iscomposing"); + err = xmlTextWriterStartElementNS(writer, NULL, (const xmlChar *)"isComposing", + (const xmlChar *)"urn:ietf:params:xml:ns:im-iscomposing"); } if (err >= 0) { - err = xmlTextWriterWriteAttributeNS(writer, (const xmlChar *)"xmlns", (const xmlChar *)"xsi", - NULL, (const xmlChar *)"http://www.w3.org/2001/XMLSchema-instance"); + err = xmlTextWriterWriteAttributeNS(writer, (const xmlChar *)"xmlns", (const xmlChar *)"xsi", NULL, + (const xmlChar *)"http://www.w3.org/2001/XMLSchema-instance"); } if (err >= 0) { - err = xmlTextWriterWriteAttributeNS(writer, (const xmlChar *)"xsi", (const xmlChar *)"schemaLocation", - NULL, (const xmlChar *)"urn:ietf:params:xml:ns:im-composing iscomposing.xsd"); + err = xmlTextWriterWriteAttributeNS(writer, (const xmlChar *)"xsi", (const xmlChar *)"schemaLocation", NULL, + (const xmlChar *)"urn:ietf:params:xml:ns:im-composing iscomposing.xsd"); } if (err >= 0) { err = xmlTextWriterWriteElement(writer, (const xmlChar *)"state", - (cr->is_composing == LinphoneIsComposingActive) ? (const xmlChar *)"active" : (const xmlChar *)"idle"); + (cr->is_composing == LinphoneIsComposingActive) ? (const xmlChar *)"active" + : (const xmlChar *)"idle"); } if ((err >= 0) && (cr->is_composing == LinphoneIsComposingActive)) { - char refresh_str[4] = { 0 }; - int refresh_timeout = lp_config_get_int(cr->lc->config, "sip", "composing_refresh_timeout", COMPOSING_DEFAULT_REFRESH_TIMEOUT); + char refresh_str[4] = {0}; + int refresh_timeout = + lp_config_get_int(cr->lc->config, "sip", "composing_refresh_timeout", COMPOSING_DEFAULT_REFRESH_TIMEOUT); snprintf(refresh_str, sizeof(refresh_str), "%u", refresh_timeout); err = xmlTextWriterWriteElement(writer, (const xmlChar *)"refresh", (const xmlChar *)refresh_str); } @@ -1161,40 +792,130 @@ static char * linphone_chat_room_create_is_composing_xml(LinphoneChatRoom *cr) { static void linphone_chat_room_send_is_composing_notification(LinphoneChatRoom *cr) { SalOp *op = NULL; - LinphoneCall *call; const char *identity = NULL; char *content = NULL; + LinphoneProxyConfig *proxy = linphone_core_lookup_known_proxy(cr->lc, cr->peer_url); + if (proxy) + identity = linphone_proxy_config_get_identity(proxy); + else + identity = linphone_core_get_primary_contact(cr->lc); + /*sending out of calls*/ + op = sal_op_new(cr->lc->sal); + linphone_configure_op(cr->lc, op, cr->peer_url, NULL, + lp_config_get_int(cr->lc->config, "sip", "chat_msg_with_contact", 0)); - if (lp_config_get_int(cr->lc->config, "sip", "chat_use_call_dialogs", 0)) { - if ((call = linphone_core_get_call_by_remote_address(cr->lc, cr->peer)) != NULL) { - if (call->state == LinphoneCallConnected || - call->state == LinphoneCallStreamsRunning || - call->state == LinphoneCallPaused || - call->state == LinphoneCallPausing || - call->state == LinphoneCallPausedByRemote) { - ms_message("send SIP message through the existing call."); - op = call->op; - identity = linphone_core_find_best_identity(cr->lc, linphone_call_get_remote_address(call)); - } - } - } - if (op == NULL) { - LinphoneProxyConfig *proxy = linphone_core_lookup_known_proxy(cr->lc, cr->peer_url); - if (proxy) - identity = linphone_proxy_config_get_identity(proxy); - else - identity = linphone_core_get_primary_contact(cr->lc); - /*sending out of calls*/ - op = sal_op_new(cr->lc->sal); - linphone_configure_op(cr->lc, op, cr->peer_url, NULL, lp_config_get_int(cr->lc->config, "sip", "chat_msg_with_contact", 0)); - } content = linphone_chat_room_create_is_composing_xml(cr); if (content != NULL) { sal_message_send(op, identity, cr->peer, "application/im-iscomposing+xml", content, NULL); ms_free(content); + sal_op_unref(op); } } +static char* utf8_to_char(uint32_t ic) { + char *result = ms_malloc(sizeof(char) * 5); + int size = 0; + if (ic < 0x80) { + result[0] = ic; + size = 1; + } else if (ic < 0x800) { + result[1] = 0x80 + ((ic & 0x3F)); + result[0] = 0xC0 + ((ic >> 6) & 0x1F); + size = 2; + } else if (ic < 0x100000) { + result[2] = 0x80 + (ic & 0x3F); + result[1] = 0x80 + ((ic >> 6) & 0x3F); + result[0] = 0xE0 + ((ic >> 12) & 0xF); + size = 3; + } else if (ic < 0x110000) { + result[3] = 0x80 + (ic & 0x3F); + result[2] = 0x80 + ((ic >> 6) & 0x3F); + result[1] = 0x80 + ((ic >> 12) & 0x3F); + result[0] = 0xF0 + ((ic >> 18) & 0x7); + size = 4; + } + result[size] = '\0'; + return result; +} + +void linphone_core_real_time_text_received(LinphoneCore *lc, LinphoneChatRoom *cr, uint32_t character, LinphoneCall *call) { + uint32_t new_line = 0x2028; + uint32_t crlf = 0x0D0A; + uint32_t lf = 0x0A; + + if (call && linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(call))) { + LinphoneChatMessageCharacter *cmc = ms_new0(LinphoneChatMessageCharacter, 1); + + if (cr->pending_message == NULL) { + cr->pending_message = linphone_chat_room_create_message(cr, ""); + } + + cmc->value = character; + cmc->has_been_read = FALSE; + cr->received_rtt_characters = ms_list_append(cr->received_rtt_characters, (void *)cmc); + + cr->remote_is_composing = LinphoneIsComposingActive; + linphone_core_notify_is_composing_received(cr->lc, cr); + + if (character == new_line || character == crlf || character == lf) { + // End of message + LinphoneChatMessage *msg = cr->pending_message; + ms_message("New line received, forge a message with content %s", cr->pending_message->message); + + linphone_chat_message_set_from(msg, cr->peer_url); + if (msg->to) + linphone_address_destroy(msg->to); + msg->to = call->dest_proxy ? linphone_address_clone(call->dest_proxy->identity_address) : + linphone_address_new(linphone_core_get_identity(lc)); + msg->time = ms_time(0); + msg->state = LinphoneChatMessageStateDelivered; + msg->is_read = FALSE; + msg->dir = LinphoneChatMessageIncoming; + msg->storage_id = linphone_chat_message_store(msg); + + if (cr->unread_count < 0) cr->unread_count = 1; + else cr->unread_count++; + + linphone_chat_room_message_received(cr, lc, msg); + linphone_chat_message_unref(msg); + cr->pending_message = NULL; + cr->received_rtt_characters = ms_list_free(cr->received_rtt_characters); + } else { + char *value = utf8_to_char(character); + cr->pending_message->message = ms_strcat_printf(cr->pending_message->message, value); + ms_message("Received RTT character: %s (%lu), pending text is %s", value, (unsigned long)character, cr->pending_message->message); + ms_free(value); + } + } +} + +uint32_t linphone_chat_room_get_char(const LinphoneChatRoom *cr) { + if (cr && cr->received_rtt_characters) { + MSList *characters = cr->received_rtt_characters; + while (characters != NULL) { + LinphoneChatMessageCharacter *cmc = (LinphoneChatMessageCharacter *)characters->data; + if (!cmc->has_been_read) { + cmc->has_been_read = TRUE; + return cmc->value; + } + characters = ms_list_next(characters); + } + } + return 0; +} + +int linphone_chat_message_put_char(LinphoneChatMessage *msg, uint32_t charater) { + LinphoneChatRoom *cr = linphone_chat_message_get_chat_room(msg); + LinphoneCall *call = cr->call; + + if (!call || !call->textstream) { + return -1; + } + + text_stream_putchar32(call->textstream, charater); + return 0; +} + static int linphone_chat_room_stop_composing(void *data, unsigned int revents) { LinphoneChatRoom *cr = (LinphoneChatRoom *)data; cr->is_composing = LinphoneIsComposingIdle; @@ -1212,445 +933,149 @@ static int linphone_chat_room_refresh_composing(void *data, unsigned int revents } void linphone_chat_room_compose(LinphoneChatRoom *cr) { - int idle_timeout = lp_config_get_int(cr->lc->config, "sip", "composing_idle_timeout", COMPOSING_DEFAULT_IDLE_TIMEOUT); - int refresh_timeout = lp_config_get_int(cr->lc->config, "sip", "composing_refresh_timeout", COMPOSING_DEFAULT_REFRESH_TIMEOUT); + int idle_timeout = + lp_config_get_int(cr->lc->config, "sip", "composing_idle_timeout", COMPOSING_DEFAULT_IDLE_TIMEOUT); + int refresh_timeout = + lp_config_get_int(cr->lc->config, "sip", "composing_refresh_timeout", COMPOSING_DEFAULT_REFRESH_TIMEOUT); if (cr->is_composing == LinphoneIsComposingIdle) { cr->is_composing = LinphoneIsComposingActive; linphone_chat_room_send_is_composing_notification(cr); if (!cr->composing_refresh_timer) { - cr->composing_refresh_timer = sal_create_timer(cr->lc->sal, linphone_chat_room_refresh_composing, cr, refresh_timeout * 1000, "composing refresh timeout"); + cr->composing_refresh_timer = sal_create_timer(cr->lc->sal, linphone_chat_room_refresh_composing, cr, + refresh_timeout * 1000, "composing refresh timeout"); } else { belle_sip_source_set_timeout(cr->composing_refresh_timer, refresh_timeout * 1000); } if (!cr->composing_idle_timer) { - cr->composing_idle_timer = sal_create_timer(cr->lc->sal, linphone_chat_room_stop_composing, cr, idle_timeout * 1000, "composing idle timeout"); + cr->composing_idle_timer = sal_create_timer(cr->lc->sal, linphone_chat_room_stop_composing, cr, + idle_timeout * 1000, "composing idle timeout"); } } belle_sip_source_set_timeout(cr->composing_idle_timer, idle_timeout * 1000); } -/** - * Returns a #LinphoneChatMessageState as a string. - */ -const char* linphone_chat_message_state_to_string(const LinphoneChatMessageState state) { +const char *linphone_chat_message_state_to_string(const LinphoneChatMessageState state) { switch (state) { - case LinphoneChatMessageStateIdle:return "LinphoneChatMessageStateIdle"; - case LinphoneChatMessageStateInProgress:return "LinphoneChatMessageStateInProgress"; - case LinphoneChatMessageStateDelivered:return "LinphoneChatMessageStateDelivered"; - case LinphoneChatMessageStateNotDelivered:return "LinphoneChatMessageStateNotDelivered"; - case LinphoneChatMessageStateFileTransferError:return "LinphoneChatMessageStateFileTransferError"; - default: return "Unknown state"; - } - -} - -/** - * Returns the chatroom this message belongs to. -**/ -LinphoneChatRoom* linphone_chat_message_get_chat_room(LinphoneChatMessage *msg){ - return msg->chat_room; -} - -/** - * Returns the peer (remote) address for the message. -**/ -const LinphoneAddress* linphone_chat_message_get_peer_address(LinphoneChatMessage *msg) { - return linphone_chat_room_get_peer_address(msg->chat_room); -} - -/** - *User pointer set function - */ -void linphone_chat_message_set_user_data(LinphoneChatMessage* message,void* ud) { - message->message_userdata=ud; -} - -/** - * User pointer get function - */ -void* linphone_chat_message_get_user_data(const LinphoneChatMessage* message) { - return message->message_userdata; -} - -/** - * Linphone message can carry external body as defined by rfc2017 - * @param message #LinphoneChatMessage - * @return external body url or NULL if not present. - */ -const char* linphone_chat_message_get_external_body_url(const LinphoneChatMessage* message) { - return message->external_body_url; -} - -/** - * Linphone message can carry external body as defined by rfc2017 - * - * @param message a LinphoneChatMessage - * @param url ex: access-type=URL; URL="http://www.foo.com/file" - */ -void linphone_chat_message_set_external_body_url(LinphoneChatMessage* message,const char* url) { - if (message->external_body_url) { - ms_free(message->external_body_url); - } - message->external_body_url=url?ms_strdup(url):NULL; -} - - -/** - * Linphone message has an app-specific field that can store a text. The application might want - * to use it for keeping data over restarts, like thumbnail image path. - * @param message #LinphoneChatMessage - * @return the application-specific data or NULL if none has been stored. - */ -const char* linphone_chat_message_get_appdata(const LinphoneChatMessage* message){ - return message->appdata; -} - -/** - * Linphone message has an app-specific field that can store a text. The application might want - * to use it for keeping data over restarts, like thumbnail image path. - * - * Invoking this function will attempt to update the message storage to reflect the changeif it is - * enabled. - * - * @param message #LinphoneChatMessage - * @param data the data to store into the message - */ -void linphone_chat_message_set_appdata(LinphoneChatMessage* message, const char* data){ - if( message->appdata ){ - ms_free(message->appdata); - } - message->appdata = data? ms_strdup(data) : NULL; - linphone_chat_message_store_appdata(message); -} - - -/** - * Get the file_transfer_information (used by call backs to recover informations during a rcs file transfer) - * - * @param message #LinphoneChatMessage - * @return a pointer to the LinphoneContent structure or NULL if not present. - */ -const LinphoneContent *linphone_chat_message_get_file_transfer_information(const LinphoneChatMessage*message) { - return message->file_transfer_information; -} - -static void on_recv_body(belle_sip_user_body_handler_t *bh, belle_sip_message_t *msg, void *data, size_t offset, const uint8_t *buffer, size_t size){ - LinphoneChatMessage* chatMsg=(LinphoneChatMessage *)data; - LinphoneCore *lc = chatMsg->chat_room->lc; - - /* 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; -} - - -static LinphoneContent* linphone_chat_create_file_transfer_information_from_headers(const belle_sip_message_t* message ){ - LinphoneContent *content = linphone_content_new(); - - belle_sip_header_content_length_t* content_length_hdr = BELLE_SIP_HEADER_CONTENT_LENGTH(belle_sip_message_get_header(message, "Content-Length")); - belle_sip_header_content_type_t* content_type_hdr = BELLE_SIP_HEADER_CONTENT_TYPE(belle_sip_message_get_header(message, "Content-Type")); - const char* type = NULL,*subtype = NULL; - - linphone_content_set_name(content, ""); - - if( content_type_hdr ){ - type = belle_sip_header_content_type_get_type(content_type_hdr); - subtype = belle_sip_header_content_type_get_subtype(content_type_hdr); - ms_message("Extracted content type %s / %s from header", type?type:"", subtype?subtype:""); - if( type ) linphone_content_set_type(content, type); - if( subtype ) linphone_content_set_subtype(content, subtype); - } - - if( content_length_hdr ){ - linphone_content_set_size(content, belle_sip_header_content_length_get_content_length(content_length_hdr)); - ms_message("Extracted content length %i from header", (int)linphone_content_get_size(content)); - } - - return content; -} - -static void linphone_chat_process_response_headers_from_get_file(void *data, const belle_http_response_event_t *event){ - if (event->response){ - /*we are receiving a response, set a specific body handler to acquire the response. - * if not done, belle-sip will create a memory body handler, the default*/ - LinphoneChatMessage *message=(LinphoneChatMessage *)belle_sip_object_data_get(BELLE_SIP_OBJECT(event->request),"message"); - belle_sip_message_t* response = BELLE_SIP_MESSAGE(event->response); - size_t body_size = 0; - - if( message->file_transfer_information == NULL ){ - ms_warning("No file transfer information for message %p: creating...", message); - message->file_transfer_information = linphone_chat_create_file_transfer_information_from_headers(response); - } - - if( message->file_transfer_information ){ - body_size = linphone_content_get_size(message->file_transfer_information); - } - - if (message->file_transfer_filepath == NULL) { - belle_sip_message_set_body_handler( - (belle_sip_message_t*)event->response, - (belle_sip_body_handler_t*)belle_sip_user_body_handler_new(body_size, linphone_chat_message_file_transfer_on_progress,on_recv_body,NULL,message) - ); - } else { - belle_sip_body_handler_t *bh = (belle_sip_body_handler_t *)belle_sip_file_body_handler_new(message->file_transfer_filepath, linphone_chat_message_file_transfer_on_progress, message); - if (belle_sip_body_handler_get_size(bh) == 0) { - /* If the size of the body has not been initialized from the file stat, use the one from the file_transfer_information. */ - belle_sip_body_handler_set_size(bh, body_size); - } - belle_sip_message_set_body_handler((belle_sip_message_t *)event->response, bh); - } - } -} - -static void linphone_chat_process_response_from_get_file(void *data, const belle_http_response_event_t *event){ - /* check the answer code */ - if (event->response){ - int code=belle_http_response_get_status_code(event->response); - 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(); - linphone_chat_message_cbs_get_file_transfer_recv(chatMsg->callbacks)(chatMsg, chatMsg->file_transfer_information, lb); - linphone_buffer_unref(lb); - } else { - linphone_core_notify_file_transfer_recv(lc, chatMsg, chatMsg->file_transfer_information, NULL, 0); - } - if (chatMsg->cb) { - chatMsg->cb(chatMsg, LinphoneChatMessageStateFileTransferDone, chatMsg->cb_ud); - } - if (linphone_chat_message_cbs_get_msg_state_changed(chatMsg->callbacks)) { - linphone_chat_message_cbs_get_msg_state_changed(chatMsg->callbacks)(chatMsg, LinphoneChatMessageStateFileTransferDone); - } - } - } -} - -/** - * Start the download of the file referenced in a LinphoneChatMessage from remote server. - * @param[in] message LinphoneChatMessage object. - */ -void linphone_chat_message_download_file(LinphoneChatMessage *message) { - belle_http_request_listener_callbacks_t cbs={0}; - belle_http_request_listener_t *l; - belle_generic_uri_t *uri; - const char *url=message->external_body_url; - 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", - uri, - belle_sip_header_create("User-Agent",ua), - NULL); - belle_sip_object_ref(message->http_request); /* keep a reference on the request to be able to cancel the download */ - ms_free(ua); - - cbs.process_response_headers=linphone_chat_process_response_headers_from_get_file; - cbs.process_response=linphone_chat_process_response_from_get_file; - cbs.process_io_error=process_io_error_download; - cbs.process_auth_requested=process_auth_requested_download; - l=belle_http_request_listener_create_from_callbacks(&cbs, (void *)message); - belle_sip_object_data_set(BELLE_SIP_OBJECT(message->http_request),"message",(void *)message,NULL); - message->state = LinphoneChatMessageStateInProgress; /* start the download, status is In Progress */ - belle_http_provider_send_request(message->chat_room->lc->http_provider,message->http_request,l); -} - -/** - * Start the download of the file from remote server - * - * @param message #LinphoneChatMessage - * @param status_cb LinphoneChatMessageStateChangeCb status callback invoked when file is downloaded or could not be downloaded - * @deprecated Use linphone_chat_message_download_file() instead. - */ -void linphone_chat_message_start_file_download(LinphoneChatMessage *message, LinphoneChatMessageStateChangedCb status_cb, void *ud) { - message->cb = status_cb; - message->cb_ud = ud; - linphone_chat_message_download_file(message); -} - -/** - * Cancel an ongoing file transfer attached to this message.(upload or download) - * @param msg #LinphoneChatMessage - */ -void linphone_chat_message_cancel_file_transfer(LinphoneChatMessage *msg) { - if (!belle_http_request_is_cancelled(msg->http_request)) { - ms_message("Cancelled file transfer %s - msg [%p] chat room[%p]", (msg->external_body_url==NULL)?linphone_core_get_file_transfer_server(msg->chat_room->lc):msg->external_body_url, msg, msg->chat_room); - belle_http_provider_cancel_request(msg->chat_room->lc->http_provider, msg->http_request); - belle_sip_object_unref(msg->http_request); - msg->http_request = NULL; - 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); - } - } -} - - -/** - * Set origin of the message - * @param[in] message #LinphoneChatMessage obj - * @param[in] from #LinphoneAddress origin of this message (copied) - */ -void linphone_chat_message_set_from_address(LinphoneChatMessage* message, const LinphoneAddress* from) { - if(message->from) linphone_address_destroy(message->from); - message->from=linphone_address_clone(from); -} - -/** - * Get origin of the message - * @param[in] message #LinphoneChatMessage obj - * @return #LinphoneAddress - */ -const LinphoneAddress* linphone_chat_message_get_from_address(const LinphoneChatMessage* message) { - return message->from; -} - -/** - * Set destination of the message - * @param[in] message #LinphoneChatMessage obj - * @param[in] to #LinphoneAddress destination of this message (copied) - */ -void linphone_chat_message_set_to_address(LinphoneChatMessage* message, const LinphoneAddress* to) { - if(message->to) linphone_address_destroy(message->to); - message->to=linphone_address_clone(to); -} - -/** - * Get destination of the message - * @param[in] message #LinphoneChatMessage obj - * @return #LinphoneAddress - */ -const LinphoneAddress* linphone_chat_message_get_to_address(const LinphoneChatMessage* message){ - if (message->to) return message->to; - if (message->dir==LinphoneChatMessageOutgoing){ - return message->chat_room->peer_url; + case LinphoneChatMessageStateIdle: + return "LinphoneChatMessageStateIdle"; + case LinphoneChatMessageStateInProgress: + return "LinphoneChatMessageStateInProgress"; + case LinphoneChatMessageStateDelivered: + return "LinphoneChatMessageStateDelivered"; + case LinphoneChatMessageStateNotDelivered: + return "LinphoneChatMessageStateNotDelivered"; + case LinphoneChatMessageStateFileTransferError: + return "LinphoneChatMessageStateFileTransferError"; + case LinphoneChatMessageStateFileTransferDone: + return "LinphoneChatMessageStateFileTransferDone "; } return NULL; } -/** - * Returns the origin address of a message if it was a outgoing message, or the destination address if it was an incoming message. - *@param message #LinphoneChatMessage obj - *@return #LinphoneAddress - */ -LinphoneAddress *linphone_chat_message_get_local_address(const LinphoneChatMessage* message){ - return message->dir==LinphoneChatMessageOutgoing ? message->from : message->to; +LinphoneChatRoom *linphone_chat_message_get_chat_room(LinphoneChatMessage *msg) { + return msg->chat_room; } -/** - * Get the time the message was sent. - */ -time_t linphone_chat_message_get_time(const LinphoneChatMessage* message) { - return message->time; +const LinphoneAddress *linphone_chat_message_get_peer_address(LinphoneChatMessage *msg) { + return linphone_chat_room_get_peer_address(msg->chat_room); } -/** - * Get the state of the message - *@param message #LinphoneChatMessage obj - *@return #LinphoneChatMessageState - */ -LinphoneChatMessageState linphone_chat_message_get_state(const LinphoneChatMessage* message) { - return message->state; +void linphone_chat_message_set_user_data(LinphoneChatMessage *msg, void *ud) { + msg->message_userdata = ud; } -/** - * Get text part of this message - * @return text or NULL if no text. - */ -const char * linphone_chat_message_get_text(const LinphoneChatMessage* message) { - return message->message; +void *linphone_chat_message_get_user_data(const LinphoneChatMessage *msg) { + return msg->message_userdata; } -/** - * Add custom headers to the message. - * @param message the message - * @param header_name name of the header_name - * @param header_value header value -**/ -void linphone_chat_message_add_custom_header(LinphoneChatMessage* message, const char *header_name, const char *header_value){ - message->custom_headers=sal_custom_header_append(message->custom_headers,header_name,header_value); +const char *linphone_chat_message_get_external_body_url(const LinphoneChatMessage *msg) { + return msg->external_body_url; } -/** - * Retrieve a custom header value given its name. - * @param message the message - * @param header_name header name searched -**/ -const char * linphone_chat_message_get_custom_header(LinphoneChatMessage* message, const char *header_name){ - return sal_custom_header_find(message->custom_headers,header_name); +void linphone_chat_message_set_external_body_url(LinphoneChatMessage *msg, const char *url) { + if (msg->external_body_url) { + ms_free(msg->external_body_url); + } + msg->external_body_url = url ? ms_strdup(url) : NULL; } -/** - * Returns TRUE if the message has been read, otherwise returns FALSE. - * @param message the message -**/ -bool_t linphone_chat_message_is_read(LinphoneChatMessage* message) { - return message->is_read; +const char *linphone_chat_message_get_appdata(const LinphoneChatMessage *msg) { + return msg->appdata; } -/** - * Returns TRUE if the message has been sent, returns FALSE if the message has been received. - * @param message the message -**/ -bool_t linphone_chat_message_is_outgoing(LinphoneChatMessage* message) { - return message->dir == LinphoneChatMessageOutgoing; +void linphone_chat_message_set_appdata(LinphoneChatMessage *msg, const char *data) { + if (msg->appdata) { + ms_free(msg->appdata); + } + msg->appdata = data ? ms_strdup(data) : NULL; + linphone_chat_message_store_appdata(msg); } -/** - * Returns the id used to identify this message in the storage database - * @param message the message - * @return the id - */ -unsigned int linphone_chat_message_get_storage_id(LinphoneChatMessage* message) { - return message->storage_id; +void linphone_chat_message_set_from_address(LinphoneChatMessage *msg, const LinphoneAddress *from) { + if (msg->from) + linphone_address_destroy(msg->from); + msg->from = linphone_address_clone(from); } -/** - * Duplicate a LinphoneChatMessage -**/ -LinphoneChatMessage* linphone_chat_message_clone(const LinphoneChatMessage* msg) { +const LinphoneAddress *linphone_chat_message_get_from_address(const LinphoneChatMessage *msg) { + return msg->from; +} + +void linphone_chat_message_set_to_address(LinphoneChatMessage *msg, const LinphoneAddress *to) { + if (msg->to) + linphone_address_destroy(msg->to); + msg->to = linphone_address_clone(to); +} + +const LinphoneAddress *linphone_chat_message_get_to_address(const LinphoneChatMessage *msg) { + if (msg->to) + return msg->to; + if (msg->dir == LinphoneChatMessageOutgoing) { + return msg->chat_room->peer_url; + } + return NULL; +} + +LinphoneAddress *linphone_chat_message_get_local_address(const LinphoneChatMessage *msg) { + return msg->dir == LinphoneChatMessageOutgoing ? msg->from : msg->to; +} + +time_t linphone_chat_message_get_time(const LinphoneChatMessage *msg) { + return msg->time; +} + +LinphoneChatMessageState linphone_chat_message_get_state(const LinphoneChatMessage *msg) { + return msg->state; +} + +const char *linphone_chat_message_get_text(const LinphoneChatMessage *msg) { + return msg->message; +} + +void linphone_chat_message_add_custom_header(LinphoneChatMessage *msg, const char *header_name, + const char *header_value) { + msg->custom_headers = sal_custom_header_append(msg->custom_headers, header_name, header_value); +} + +const char *linphone_chat_message_get_custom_header(LinphoneChatMessage *msg, const char *header_name) { + return sal_custom_header_find(msg->custom_headers, header_name); +} + +bool_t linphone_chat_message_is_read(LinphoneChatMessage *msg) { + return msg->is_read; +} + +bool_t linphone_chat_message_is_outgoing(LinphoneChatMessage *msg) { + return msg->dir == LinphoneChatMessageOutgoing; +} + +unsigned int linphone_chat_message_get_storage_id(LinphoneChatMessage *msg) { + return msg->storage_id; +} + +LinphoneChatMessage *linphone_chat_message_clone(const LinphoneChatMessage *msg) { /*struct _LinphoneChatMessage { - char* message; + char* msg; LinphoneChatRoom* chat_room; LinphoneChatMessageStateChangeCb cb; void* cb_ud; @@ -1661,137 +1086,88 @@ LinphoneChatMessage* linphone_chat_message_clone(const LinphoneChatMessage* msg) SalCustomHeader *custom_headers; LinphoneChatMessageState state; };*/ - LinphoneChatMessage* new_message = linphone_chat_room_create_message(msg->chat_room,msg->message); - if (msg->external_body_url) new_message->external_body_url=ms_strdup(msg->external_body_url); - if (msg->appdata) new_message->appdata = ms_strdup(msg->appdata); - new_message->cb=msg->cb; - new_message->cb_ud=msg->cb_ud; - new_message->message_userdata=msg->message_userdata; - new_message->cb=msg->cb; - new_message->time=msg->time; - new_message->state=msg->state; - new_message->storage_id=msg->storage_id; - if (msg->from) new_message->from=linphone_address_clone(msg->from); - if (msg->file_transfer_filepath) new_message->file_transfer_filepath=ms_strdup(msg->file_transfer_filepath); + LinphoneChatMessage *new_message = linphone_chat_room_create_message(msg->chat_room, msg->message); + if (msg->external_body_url) + new_message->external_body_url = ms_strdup(msg->external_body_url); + if (msg->appdata) + new_message->appdata = ms_strdup(msg->appdata); + new_message->message_state_changed_cb = msg->message_state_changed_cb; + new_message->message_state_changed_user_data = msg->message_state_changed_user_data; + new_message->message_userdata = msg->message_userdata; + new_message->time = msg->time; + new_message->state = msg->state; + new_message->storage_id = msg->storage_id; + if (msg->from) + new_message->from = linphone_address_clone(msg->from); + if (msg->file_transfer_filepath) + new_message->file_transfer_filepath = ms_strdup(msg->file_transfer_filepath); + if (msg->file_transfer_information) + new_message->file_transfer_information = linphone_content_copy(msg->file_transfer_information); return new_message; } -/** - * Destroys a LinphoneChatMessage. -**/ -void linphone_chat_message_destroy(LinphoneChatMessage* msg){ +void linphone_chat_message_destroy(LinphoneChatMessage *msg) { belle_sip_object_unref(msg); } - -/** - * Destroys a LinphoneChatMessage. -**/ -static void _linphone_chat_message_destroy(LinphoneChatMessage* msg) { - if (msg->op) sal_op_release(msg->op); - if (msg->message) ms_free(msg->message); - if (msg->external_body_url) ms_free(msg->external_body_url); - if (msg->appdata) ms_free(msg->appdata); - if (msg->from) linphone_address_destroy(msg->from); - if (msg->to) linphone_address_destroy(msg->to); - if (msg->custom_headers) sal_custom_header_free(msg->custom_headers); - if (msg->content_type) ms_free(msg->content_type); +static void _linphone_chat_message_destroy(LinphoneChatMessage *msg) { + if (msg->op) + sal_op_release(msg->op); + if (msg->message) + ms_free(msg->message); + if (msg->external_body_url) + ms_free(msg->external_body_url); + if (msg->appdata) + ms_free(msg->appdata); + if (msg->from) + linphone_address_destroy(msg->from); + if (msg->to) + linphone_address_destroy(msg->to); + if (msg->custom_headers) + sal_custom_header_free(msg->custom_headers); + if (msg->content_type) + ms_free(msg->content_type); if (msg->file_transfer_information) { linphone_content_unref(msg->file_transfer_information); } if (msg->file_transfer_filepath != NULL) { ms_free(msg->file_transfer_filepath); } - linphone_chat_message_cbs_unref(msg->callbacks); - ms_message("LinphoneChatMessage [%p] destroyed.",msg); + if (msg->callbacks) { + linphone_chat_message_cbs_unref(msg->callbacks); + } } - -/** - * Acquire a reference to the chat message. - * @param msg the chat message - * @return the same chat message -**/ -LinphoneChatMessage * linphone_chat_message_ref(LinphoneChatMessage *msg){ +LinphoneChatMessage *linphone_chat_message_ref(LinphoneChatMessage *msg) { belle_sip_object_ref(msg); return msg; } -/** - * Release reference to the chat message. - * @param msg the chat message. -**/ -void linphone_chat_message_unref(LinphoneChatMessage *msg){ +void linphone_chat_message_unref(LinphoneChatMessage *msg) { belle_sip_object_unref(msg); } -/** - * Get full details about delivery error of a chat message. - * @param msg a LinphoneChatMessage - * @return a LinphoneErrorInfo describing the details. -**/ -const LinphoneErrorInfo *linphone_chat_message_get_error_info(const LinphoneChatMessage *msg){ +static void linphone_chat_message_release(LinphoneChatMessage *msg) { + /*mark the chat msg as orphan (it has no chat room anymore), and unref it*/ + msg->chat_room = NULL; + if (msg->file_transfer_information != NULL) { + linphone_chat_message_cancel_file_transfer(msg); + } + linphone_chat_message_unref(msg); +} + +const LinphoneErrorInfo *linphone_chat_message_get_error_info(const LinphoneChatMessage *msg) { return linphone_error_info_from_sal_op(msg->op); } -LinphoneReason linphone_chat_message_get_reason(LinphoneChatMessage* msg) { +LinphoneReason linphone_chat_message_get_reason(LinphoneChatMessage *msg) { return linphone_error_info_get_reason(linphone_chat_message_get_error_info(msg)); } - -/** - * Set the path to the file to read from or write to during the file transfer. - * @param[in] msg LinphoneChatMessage object - * @param[in] filepath The path to the file to use for the file transfer. - */ -void linphone_chat_message_set_file_transfer_filepath(LinphoneChatMessage *msg, const char *filepath) { - if (msg->file_transfer_filepath != NULL) { - ms_free(msg->file_transfer_filepath); - } - msg->file_transfer_filepath = ms_strdup(filepath); -} - -/** - * Get the path to the file to read from or write to during the file transfer. - * @param[in] msg LinphoneChatMessage object - * @return The path to the file to use for the file transfer. - */ -const char * linphone_chat_message_get_file_transfer_filepath(LinphoneChatMessage *msg) { - return msg->file_transfer_filepath; -} - -/** - * Get the LinphoneChatMessageCbs object associated with the LinphoneChatMessage. - * @param[in] msg LinphoneChatMessage object - * @return The LinphoneChatMessageCbs object associated with the LinphoneChatMessage. - */ -LinphoneChatMessageCbs * linphone_chat_message_get_callbacks(const LinphoneChatMessage *msg) { +LinphoneChatMessageCbs *linphone_chat_message_get_callbacks(const LinphoneChatMessage *msg) { return msg->callbacks; } - -/** - * Create a message attached to a dedicated chat room with a particular content. Use #linphone_chat_room_send_message2 to initiate the transfer - * @param cr the chat room. - * @param initial_content #LinphoneContent initial content. #LinphoneCoreVTable.file_transfer_send is invoked later to notify file transfer progress and collect next chunk of the message if #LinphoneContent.data is NULL. - * @return a new #LinphoneChatMessage - */ - -LinphoneChatMessage* linphone_chat_room_create_file_transfer_message(LinphoneChatRoom *cr, LinphoneContent* initial_content) { - LinphoneChatMessage* msg = belle_sip_object_new(LinphoneChatMessage); - msg->callbacks=linphone_chat_message_cbs_new(); - msg->chat_room=(LinphoneChatRoom*)cr; - msg->message = NULL; - msg->is_read=TRUE; - msg->file_transfer_information = linphone_content_copy(initial_content); - msg->dir=LinphoneChatMessageOutgoing; - linphone_chat_message_set_to(msg, linphone_chat_room_get_peer_address(cr)); - linphone_chat_message_set_from(msg, linphone_address_new(linphone_core_get_identity(cr->lc))); - msg->content_type=NULL; /* this will be set to application/vnd.gsma.rcs-ft-http+xml when we will transfer the xml reply from server to the peers */ - msg->http_request=NULL; /* this will store the http request during file upload to the server */ - return msg; +LinphoneCall *linphone_chat_room_get_call(const LinphoneChatRoom *room) { + return room->call; } - -/** - * @} - */ diff --git a/coreapi/chat_file_transfer.c b/coreapi/chat_file_transfer.c new file mode 100644 index 000000000..03190ce7f --- /dev/null +++ b/coreapi/chat_file_transfer.c @@ -0,0 +1,592 @@ +/*************************************************************************** + * chat_file_transfer.c + * + * Sun Jun 5 19:34:18 2005 + * Copyright 2005 Simon Morlat + * Email simon dot morlat at linphone dot org + ****************************************************************************/ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "linphonecore.h" +#include "private.h" +#include "lime.h" +#include "ortp/b64.h" + +#define FILE_TRANSFER_KEY_SIZE 32 + +static bool_t file_transfer_in_progress_and_valid(LinphoneChatMessage* msg) { + return (msg->chat_room && msg->http_request && !belle_http_request_is_cancelled(msg->http_request)); +} + +static void _release_http_request(LinphoneChatMessage* msg) { + if (msg->http_request) { + belle_sip_object_unref(msg->http_request); + msg->http_request = NULL; + if (msg->http_listener){ + belle_sip_object_unref(msg->http_listener); + msg->http_listener = NULL; + // unhold the reference that the listener was holding on the message + linphone_chat_message_unref(msg); + } + } +} + +static void linphone_chat_message_process_io_error_upload(void *data, const belle_sip_io_error_event_t *event) { + LinphoneChatMessage *msg = (LinphoneChatMessage *)data; + ms_error("I/O Error during file upload of msg [%p]", msg); + linphone_chat_message_set_state(msg, LinphoneChatMessageStateNotDelivered); + _release_http_request(msg); +} + +static void linphone_chat_message_process_auth_requested_upload(void *data, belle_sip_auth_event_t *event) { + LinphoneChatMessage *msg = (LinphoneChatMessage *)data; + ms_error("Error during file upload: auth requested for msg [%p]", msg); + linphone_chat_message_set_state(msg, LinphoneChatMessageStateNotDelivered); + _release_http_request(msg); +} + +static void linphone_chat_message_process_io_error_download(void *data, const belle_sip_io_error_event_t *event) { + LinphoneChatMessage *msg = (LinphoneChatMessage *)data; + ms_error("I/O Error during file download msg [%p]", msg); + linphone_chat_message_set_state(msg, LinphoneChatMessageStateFileTransferError); + _release_http_request(msg); +} +static void linphone_chat_message_process_auth_requested_download(void *data, belle_sip_auth_event_t *event) { + LinphoneChatMessage *msg = (LinphoneChatMessage *)data; + ms_error("Error during file download : auth requested for msg [%p]", msg); + linphone_chat_message_set_state(msg, LinphoneChatMessageStateFileTransferError); + _release_http_request(msg); +} + +static void linphone_chat_message_file_transfer_on_progress(belle_sip_body_handler_t *bh, belle_sip_message_t *m, + void *data, size_t offset, size_t total) { + LinphoneChatMessage *msg = (LinphoneChatMessage *)data; + if (msg->http_request && !file_transfer_in_progress_and_valid(msg)) { + ms_warning("Cancelled request for %s msg [%p], ignoring %s", msg->chat_room?"":"ORPHAN", msg, __FUNCTION__); + _release_http_request(msg); + return; + } + if (linphone_chat_message_cbs_get_file_transfer_progress_indication(msg->callbacks)) { + linphone_chat_message_cbs_get_file_transfer_progress_indication(msg->callbacks)( + msg, msg->file_transfer_information, offset, total); + } else { + /* Legacy: call back given by application level */ + linphone_core_notify_file_transfer_progress_indication(msg->chat_room->lc, msg, msg->file_transfer_information, + offset, total); + } +} + +static int linphone_chat_message_file_transfer_on_send_body(belle_sip_user_body_handler_t *bh, belle_sip_message_t *m, + void *data, size_t offset, uint8_t *buffer, size_t *size) { + LinphoneChatMessage *msg = (LinphoneChatMessage *)data; + LinphoneCore *lc = NULL; + char *buf = (char *)buffer; + + if (msg->http_request && !file_transfer_in_progress_and_valid(msg)) { + ms_warning("Cancelled request for %s msg [%p], ignoring %s", msg->chat_room?"":"ORPHAN", msg, __FUNCTION__); + _release_http_request(msg); + return BELLE_SIP_STOP; + } + + lc = msg->chat_room->lc; + /* if we've not reach the end of file yet, ask for more data*/ + if (offset < linphone_content_get_size(msg->file_transfer_information)) { + char *plainBuffer = NULL; + + if (linphone_content_get_key(msg->file_transfer_information) != + NULL) { /* if we have a key to cipher the msg, use it! */ + /* 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(msg->file_transfer_information)) { + *size -= (*size % 16); + } + plainBuffer = (char *)ms_malloc0(*size); + } + + /* get data from call back */ + if (linphone_chat_message_cbs_get_file_transfer_send(msg->callbacks)) { + LinphoneBuffer *lb = linphone_chat_message_cbs_get_file_transfer_send(msg->callbacks)( + msg, msg->file_transfer_information, offset, *size); + if (lb == NULL) { + *size = 0; + } else { + *size = linphone_buffer_get_size(lb); + memcpy(plainBuffer ? plainBuffer : buf, linphone_buffer_get_content(lb), *size); + linphone_buffer_unref(lb); + } + } else { + /* Legacy */ + linphone_core_notify_file_transfer_send(lc, msg, msg->file_transfer_information, + plainBuffer ? plainBuffer : buf, size); + } + + if (linphone_content_get_key(msg->file_transfer_information) != + NULL) { /* if we have a key to cipher the msg, use it! */ + lime_encryptFile(linphone_content_get_cryptoContext_address(msg->file_transfer_information), + (unsigned char *)linphone_content_get_key(msg->file_transfer_information), *size, + plainBuffer, (char *)buffer); + ms_free(plainBuffer); + /* check if we reach the end of file */ + if (offset + *size >= linphone_content_get_size(msg->file_transfer_information)) { + /* conclude file ciphering by calling it context with a zero size */ + lime_encryptFile(linphone_content_get_cryptoContext_address(msg->file_transfer_information), NULL, 0, + NULL, NULL); + } + } + } + + return BELLE_SIP_CONTINUE; +} + +static void linphone_chat_message_process_response_from_post_file(void *data, + const belle_http_response_event_t *event) { + LinphoneChatMessage *msg = (LinphoneChatMessage *)data; + + if (msg->http_request && !file_transfer_in_progress_and_valid(msg)) { + ms_warning("Cancelled request for %s msg [%p], ignoring %s", msg->chat_room?"":"ORPHAN", msg, __FUNCTION__); + _release_http_request(msg); + return; + } + + /* check the answer code */ + if (event->response) { + int code = belle_http_response_get_status_code(event->response); + if (code == 204) { /* this is the reply to the first post to the server - an empty msg */ + /* start uploading the file */ + belle_sip_multipart_body_handler_t *bh; + char *first_part_header; + belle_sip_body_handler_t *first_part_bh; + + /* shall we encrypt the file */ + if (linphone_core_lime_for_file_sharing_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 msg */ + 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 msg + * 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) { + first_part_bh = + (belle_sip_body_handler_t *)belle_sip_file_body_handler_new(msg->file_transfer_filepath, NULL, msg); + } else if (linphone_content_get_buffer(msg->file_transfer_information) != NULL) { + first_part_bh = (belle_sip_body_handler_t *)belle_sip_memory_body_handler_new_from_buffer( + linphone_content_get_buffer(msg->file_transfer_information), + linphone_content_get_size(msg->file_transfer_information), NULL, msg); + } else { + first_part_bh = (belle_sip_body_handler_t *)belle_sip_user_body_handler_new( + linphone_content_get_size(msg->file_transfer_information), NULL, NULL, + linphone_chat_message_file_transfer_on_send_body, msg); + } + belle_sip_body_handler_add_header(first_part_bh, + belle_sip_header_create("Content-disposition", first_part_header)); + belle_sip_free(first_part_header); + belle_sip_body_handler_add_header(first_part_bh, + (belle_sip_header_t *)belle_sip_header_content_type_create( + linphone_content_get_type(msg->file_transfer_information), + linphone_content_get_subtype(msg->file_transfer_information))); + + /* insert it in a multipart body handler which will manage the boundaries of multipart msg */ + bh = belle_sip_multipart_body_handler_new(linphone_chat_message_file_transfer_on_progress, msg, first_part_bh, NULL); + + linphone_chat_message_ref(msg); + _release_http_request(msg); + linphone_chat_room_upload_file(msg); + belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(msg->http_request), BELLE_SIP_BODY_HANDLER(bh)); + linphone_chat_message_unref(msg); + } else 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); + if (body && strlen(body) > 0) { + /* if we have an encryption key for the file, we must insert it into the msg and restore the correct + * filename */ + if (linphone_content_get_key(msg->file_transfer_information) != NULL) { + /* parse the msg 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 */ + size_t b64Size = b64_encode(NULL, FILE_TRANSFER_KEY_SIZE, NULL, 0); + char *keyb64 = (char *)ms_malloc0(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); + ms_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 msg sent by server */ + msg->message = ms_strdup(body); + } + msg->content_type = ms_strdup("application/vnd.gsma.rcs-ft-http+xml"); + linphone_chat_message_set_state(msg, LinphoneChatMessageStateFileTransferDone); + linphone_chat_message_ref(msg); + _release_http_request(msg); + _linphone_chat_room_send_message(msg->chat_room, msg); + linphone_chat_message_unref(msg); + } else { + ms_warning("Received empty response from server, file transfer failed"); + linphone_chat_message_set_state(msg, LinphoneChatMessageStateNotDelivered); + _release_http_request(msg); + } + } else { + ms_warning("Unhandled HTTP code response %d for file transfer", code); + linphone_chat_message_set_state(msg, LinphoneChatMessageStateNotDelivered); + _release_http_request(msg); + } + } +} + +const LinphoneContent *linphone_chat_message_get_file_transfer_information(const LinphoneChatMessage *msg) { + return msg->file_transfer_information; +} + +static void on_recv_body(belle_sip_user_body_handler_t *bh, belle_sip_message_t *m, void *data, size_t offset, + const uint8_t *buffer, size_t size) { + LinphoneChatMessage *msg = (LinphoneChatMessage *)data; + LinphoneCore *lc = msg->chat_room->lc; + + + if (!msg->http_request || belle_http_request_is_cancelled(msg->http_request)) { + ms_warning("Cancelled request for msg [%p], ignoring %s", msg, __FUNCTION__); + return; + } + + if (!msg->chat_room) { + linphone_chat_message_cancel_file_transfer(msg); + } + + /* first call may be with a zero size, ignore it */ + if (size == 0) { + return; + } + + if (linphone_content_get_key(msg->file_transfer_information) != + NULL) { /* we have a key, we must decrypt the file */ + /* get data from callback to a plainBuffer */ + char *plainBuffer = (char *)ms_malloc0(size); + lime_decryptFile(linphone_content_get_cryptoContext_address(msg->file_transfer_information), + (unsigned char *)linphone_content_get_key(msg->file_transfer_information), size, plainBuffer, + (char *)buffer); + if (linphone_chat_message_cbs_get_file_transfer_recv(msg->callbacks)) { + LinphoneBuffer *lb = linphone_buffer_new_from_data((unsigned char *)plainBuffer, size); + linphone_chat_message_cbs_get_file_transfer_recv(msg->callbacks)(msg, msg->file_transfer_information, lb); + linphone_buffer_unref(lb); + } else { + /* legacy: call back given by application level */ + linphone_core_notify_file_transfer_recv(lc, msg, msg->file_transfer_information, plainBuffer, size); + } + ms_free(plainBuffer); + } else { /* regular file, no deciphering */ + if (linphone_chat_message_cbs_get_file_transfer_recv(msg->callbacks)) { + LinphoneBuffer *lb = linphone_buffer_new_from_data(buffer, size); + linphone_chat_message_cbs_get_file_transfer_recv(msg->callbacks)(msg, msg->file_transfer_information, lb); + linphone_buffer_unref(lb); + } else { + /* Legacy: call back given by application level */ + linphone_core_notify_file_transfer_recv(lc, msg, msg->file_transfer_information, (char *)buffer, size); + } + } + + return; +} + +static LinphoneContent *linphone_chat_create_file_transfer_information_from_headers(const belle_sip_message_t *m) { + LinphoneContent *content = linphone_content_new(); + + belle_sip_header_content_length_t *content_length_hdr = + BELLE_SIP_HEADER_CONTENT_LENGTH(belle_sip_message_get_header(m, "Content-Length")); + belle_sip_header_content_type_t *content_type_hdr = + BELLE_SIP_HEADER_CONTENT_TYPE(belle_sip_message_get_header(m, "Content-Type")); + const char *type = NULL, *subtype = NULL; + + linphone_content_set_name(content, ""); + + if (content_type_hdr) { + type = belle_sip_header_content_type_get_type(content_type_hdr); + subtype = belle_sip_header_content_type_get_subtype(content_type_hdr); + ms_message("Extracted content type %s / %s from header", type ? type : "", subtype ? subtype : ""); + if (type) + linphone_content_set_type(content, type); + if (subtype) + linphone_content_set_subtype(content, subtype); + } + + if (content_length_hdr) { + linphone_content_set_size(content, belle_sip_header_content_length_get_content_length(content_length_hdr)); + ms_message("Extracted content length %i from header", (int)linphone_content_get_size(content)); + } + + return content; +} + +static void linphone_chat_process_response_headers_from_get_file(void *data, const belle_http_response_event_t *event) { + LinphoneChatMessage *msg = (LinphoneChatMessage *)data; + if (event->response) { + /*we are receiving a response, set a specific body handler to acquire the response. + * if not done, belle-sip will create a memory body handler, the default*/ + belle_sip_message_t *response = BELLE_SIP_MESSAGE(event->response); + size_t body_size = 0; + + if (msg->file_transfer_information == NULL) { + ms_warning("No file transfer information for msg %p: creating...", msg); + msg->file_transfer_information = linphone_chat_create_file_transfer_information_from_headers(response); + } + + if (msg->file_transfer_information) { + body_size = linphone_content_get_size(msg->file_transfer_information); + } + + if (msg->file_transfer_filepath == NULL) { + belle_sip_message_set_body_handler( + (belle_sip_message_t *)event->response, + (belle_sip_body_handler_t *)belle_sip_user_body_handler_new( + body_size, linphone_chat_message_file_transfer_on_progress, on_recv_body, NULL, msg)); + } else { + belle_sip_body_handler_t *bh = (belle_sip_body_handler_t *)belle_sip_file_body_handler_new( + msg->file_transfer_filepath, linphone_chat_message_file_transfer_on_progress, msg); + if (belle_sip_body_handler_get_size(bh) == 0) { + /* If the size of the body has not been initialized from the file stat, use the one from the + * file_transfer_information. */ + belle_sip_body_handler_set_size(bh, body_size); + } + belle_sip_message_set_body_handler((belle_sip_message_t *)event->response, bh); + } + } +} + +static void linphone_chat_process_response_from_get_file(void *data, const belle_http_response_event_t *event) { + LinphoneChatMessage *msg = (LinphoneChatMessage *)data; + /* check the answer code */ + if (event->response) { + int code = belle_http_response_get_status_code(event->response); + if (code == 200) { + LinphoneCore *lc = msg->chat_room->lc; + /* if the file was encrypted, finish the decryption and free context */ + if (linphone_content_get_key(msg->file_transfer_information) != NULL) { + lime_decryptFile(linphone_content_get_cryptoContext_address(msg->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(msg->callbacks)) { + LinphoneBuffer *lb = linphone_buffer_new(); + linphone_chat_message_cbs_get_file_transfer_recv(msg->callbacks)(msg, msg->file_transfer_information, + lb); + linphone_buffer_unref(lb); + } else { + linphone_core_notify_file_transfer_recv(lc, msg, msg->file_transfer_information, NULL, 0); + } + linphone_chat_message_set_state(msg, LinphoneChatMessageStateFileTransferDone); + } else if (code >= 400 && code < 500) { + ms_warning("File transfer failed with code %d", code); + linphone_chat_message_set_state(msg, LinphoneChatMessageStateFileTransferError); + } else { + ms_warning("Unhandled HTTP code response %d for file transfer", code); + } + _release_http_request(msg); + } +} + +int _linphone_chat_room_start_http_transfer(LinphoneChatMessage *msg, const char* url, const char* action, const belle_http_request_listener_callbacks_t *cbs) { + belle_generic_uri_t *uri = NULL; + char* ua; + + if (url == NULL) { + ms_warning("Cannot process file transfer msg: no file remote URI configured."); + goto error; + } + uri = belle_generic_uri_parse(url); + if (uri == NULL || belle_generic_uri_get_host(uri)==NULL) { + ms_warning("Cannot process file transfer msg: incorrect file remote URI configured '%s'.", url); + goto error; + } + + ua = ms_strdup_printf("%s/%s", linphone_core_get_user_agent_name(), linphone_core_get_user_agent_version()); + msg->http_request = belle_http_request_create(action, uri, belle_sip_header_create("User-Agent", ua), NULL); + ms_free(ua); + + if (msg->http_request == NULL) { + ms_warning("Could not create http request for uri %s", url); + goto error; + } + /* keep a reference to the http request to be able to cancel it during upload */ + belle_sip_object_ref(msg->http_request); + + /* give msg to listener to be able to start the actual file upload when server answer a 204 No content */ + msg->http_listener = belle_http_request_listener_create_from_callbacks(cbs, linphone_chat_message_ref(msg)); + belle_http_provider_send_request(msg->chat_room->lc->http_provider, msg->http_request, msg->http_listener); + return 0; +error: + if (uri) { + belle_sip_object_unref(uri); + } + return -1; +} + +int linphone_chat_room_upload_file(LinphoneChatMessage *msg) { + belle_http_request_listener_callbacks_t cbs = {0}; + int err; + + if (msg->http_request){ + ms_error("linphone_chat_room_upload_file(): there is already an upload in progress."); + return -1; + } + + cbs.process_response = linphone_chat_message_process_response_from_post_file; + cbs.process_io_error = linphone_chat_message_process_io_error_upload; + cbs.process_auth_requested = linphone_chat_message_process_auth_requested_upload; + err = _linphone_chat_room_start_http_transfer(msg, linphone_core_get_file_transfer_server(msg->chat_room->lc), "POST", &cbs); + if (err == -1){ + linphone_chat_message_set_state(msg, LinphoneChatMessageStateNotDelivered); + } + return err; +} + +int linphone_chat_message_download_file(LinphoneChatMessage *msg) { + belle_http_request_listener_callbacks_t cbs = {0}; + int err; + + if (msg->http_request){ + ms_error("linphone_chat_message_download_file(): there is already a download in progress"); + return -1; + } + cbs.process_response_headers = linphone_chat_process_response_headers_from_get_file; + cbs.process_response = linphone_chat_process_response_from_get_file; + cbs.process_io_error = linphone_chat_message_process_io_error_download; + cbs.process_auth_requested = linphone_chat_message_process_auth_requested_download; + err = _linphone_chat_room_start_http_transfer(msg, msg->external_body_url, "GET", &cbs); + if (err == -1) return -1; + /* start the download, status is In Progress */ + linphone_chat_message_set_state(msg, LinphoneChatMessageStateInProgress); + return 0; +} + +void linphone_chat_message_start_file_download(LinphoneChatMessage *msg, + LinphoneChatMessageStateChangedCb status_cb, void *ud) { + msg->message_state_changed_cb = status_cb; + msg->message_state_changed_user_data = ud; + linphone_chat_message_download_file(msg); +} + +void linphone_chat_message_cancel_file_transfer(LinphoneChatMessage *msg) { + if (msg->http_request) { + if (msg->state == LinphoneChatMessageStateInProgress) { + linphone_chat_message_set_state(msg, LinphoneChatMessageStateNotDelivered); + } + if (!belle_http_request_is_cancelled(msg->http_request)) { + if (msg->chat_room) { + ms_message("Canceling file transfer %s - msg [%p] chat room[%p]" + , (msg->external_body_url == NULL) ? linphone_core_get_file_transfer_server(msg->chat_room->lc) : msg->external_body_url + , msg + , msg->chat_room); + belle_http_provider_cancel_request(msg->chat_room->lc->http_provider, msg->http_request); + } else { + ms_message("Warning: http request still running for ORPHAN msg [%p]: this is a memory leak", msg); + } + } + _release_http_request(msg); + } else { + ms_message("No existing file transfer - nothing to cancel"); + } +} + +void linphone_chat_message_set_file_transfer_filepath(LinphoneChatMessage *msg, const char *filepath) { + if (msg->file_transfer_filepath != NULL) { + ms_free(msg->file_transfer_filepath); + } + msg->file_transfer_filepath = ms_strdup(filepath); +} + +const char *linphone_chat_message_get_file_transfer_filepath(LinphoneChatMessage *msg) { + return msg->file_transfer_filepath; +} + +LinphoneChatMessage *linphone_chat_room_create_file_transfer_message(LinphoneChatRoom *cr, + const LinphoneContent *initial_content) { + LinphoneChatMessage *msg = belle_sip_object_new(LinphoneChatMessage); + msg->callbacks = linphone_chat_message_cbs_new(); + msg->chat_room = (LinphoneChatRoom *)cr; + msg->message = NULL; + msg->is_read = TRUE; + msg->file_transfer_information = linphone_content_copy(initial_content); + msg->dir = LinphoneChatMessageOutgoing; + linphone_chat_message_set_to(msg, linphone_chat_room_get_peer_address(cr)); + msg->from = linphone_address_new(linphone_core_get_identity(cr->lc)); /*direct assignment*/ + /* this will be set to application/vnd.gsma.rcs-ft-http+xml when we will transfer the xml reply from server to the peers */ + msg->content_type = NULL; + /* this will store the http request during file upload to the server */ + msg->http_request = NULL; + msg->time = ms_time(0); + return msg; +} diff --git a/coreapi/conference.c b/coreapi/conference.c index 75f451736..66898d9a2 100644 --- a/coreapi/conference.c +++ b/coreapi/conference.c @@ -22,7 +22,7 @@ * 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" #include "lpconfig.h" @@ -87,7 +87,7 @@ void linphone_core_conference_check_uninit(LinphoneCore *lc){ ctx->record_endpoint=NULL; } } - + if (ms_audio_conference_get_size(ctx->conf)==0){ ms_audio_conference_destroy(ctx->conf); ctx->conf=NULL; @@ -110,7 +110,7 @@ void linphone_call_add_to_conf(LinphoneCall *call, bool_t muted){ void linphone_call_remove_from_conf(LinphoneCall *call){ LinphoneCore *lc=call->core; LinphoneConference *conf=&lc->conf_ctx; - + ms_audio_conference_remove_member(conf->conf,call->endpoint); ms_audio_endpoint_release_from_stream(call->endpoint); call->endpoint=NULL; @@ -128,12 +128,12 @@ static void add_local_endpoint(LinphoneConference *conf,LinphoneCore *lc){ /*create a dummy audiostream in order to extract the local part of it */ /* network address and ports have no meaning and are not used here. */ AudioStream *st=audio_stream_new(65000,65001,FALSE); - MSSndCard *playcard=lc->sound_conf.lsd_card ? + MSSndCard *playcard=lc->sound_conf.lsd_card ? lc->sound_conf.lsd_card : lc->sound_conf.play_sndcard; MSSndCard *captcard=lc->sound_conf.capt_sndcard; const MSAudioConferenceParams *params=ms_audio_conference_get_params(conf->conf); conf->local_dummy_profile=make_dummy_profile(params->samplerate); - + audio_stream_start_full(st, conf->local_dummy_profile, "127.0.0.1", 65000, @@ -151,7 +151,7 @@ static void add_local_endpoint(LinphoneConference *conf,LinphoneCore *lc){ conf->local_participant=st; conf->local_endpoint=ms_audio_endpoint_get_from_stream(st,FALSE); ms_audio_conference_add_member(conf->conf,conf->local_endpoint); - + } /** @@ -166,7 +166,7 @@ float linphone_core_get_conference_local_input_volume(LinphoneCore *lc){ float vol=0; ms_filter_call_method(st->volsend,MS_VOLUME_GET,&vol); return vol; - + } return LINPHONE_VOLUME_DB_LOWEST; } @@ -175,22 +175,22 @@ float linphone_core_get_conference_local_input_volume(LinphoneCore *lc){ * Merge a call into a conference. * @param lc the linphone core * @param call an established call, either in LinphoneCallStreamsRunning or LinphoneCallPaused state. - * + * * If this is the first call that enters the conference, the virtual conference will be created automatically. * If the local user was actively part of the call (ie not in paused state), then the local user is automatically entered into the conference. * If the call was in paused state, then it is automatically resumed when entering into the conference. - * + * * @return 0 if successful, -1 otherwise. **/ int linphone_core_add_to_conference(LinphoneCore *lc, LinphoneCall *call){ LinphoneConference *conf=&lc->conf_ctx; - + if (call->current_params->in_conference){ ms_error("Already in conference"); return -1; } conference_check_init(&lc->conf_ctx, lp_config_get_int(lc->config, "sound","conference_rate",16000)); - + if (call->state==LinphoneCallPaused){ call->params->in_conference=TRUE; call->params->has_video=FALSE; @@ -199,7 +199,7 @@ int linphone_core_add_to_conference(LinphoneCore *lc, LinphoneCall *call){ LinphoneCallParams *params=linphone_call_params_copy(linphone_call_get_current_params(call)); params->in_conference=TRUE; params->has_video=FALSE; - + if (call->audiostream || call->videostream){ linphone_call_stop_media_streams(call); /*free the audio & video local resources*/ linphone_call_init_media_streams(call); @@ -276,21 +276,6 @@ static int convert_conference_to_call(LinphoneCore *lc){ return err; } -/** - * Remove a call from the conference. - * @param lc the linphone core - * @param call a call that has been previously merged into the conference. - * - * After removing the remote participant belonging to the supplied call, the call becomes a normal call in paused state. - * If one single remote participant is left alone together with the local user in the conference after the removal, then the conference is - * automatically transformed into a simple call in StreamsRunning state. - * The conference's resources are then automatically destroyed. - * - * In other words, unless linphone_core_leave_conference() is explicitely called, the last remote participant of a conference is automatically - * put in a simple call in running state. - * - * @return 0 if successful, -1 otherwise. - **/ int linphone_core_remove_from_conference(LinphoneCore *lc, LinphoneCall *call){ int err; char * str=linphone_call_get_remote_address_as_string(call); @@ -311,11 +296,6 @@ int linphone_core_remove_from_conference(LinphoneCore *lc, LinphoneCall *call){ return err; } -/** - * Indicates whether the local participant is part of the conference. - * @param lc the linphone core - * @return TRUE if the local participant is in the conference, FALSE otherwise. -**/ bool_t linphone_core_is_in_conference(const LinphoneCore *lc){ return lc->conf_ctx.local_participant!=NULL; } @@ -336,12 +316,12 @@ int linphone_core_leave_conference(LinphoneCore *lc){ /** * Moves the local participant inside the conference. * @param lc the linphone core - * - * Makes the local participant to join the conference. + * + * Makes the local participant to join the conference. * Typically, the local participant is by default always part of the conference when joining an active call into a conference. * However, by calling linphone_core_leave_conference() and linphone_core_enter_conference() the application can decide to temporarily * move out and in the local participant from the conference. - * + * * @return 0 if successful, -1 otherwise **/ int linphone_core_enter_conference(LinphoneCore *lc){ @@ -360,9 +340,9 @@ int linphone_core_enter_conference(LinphoneCore *lc){ /** * Add all calls into a conference. * @param lc the linphone core - * + * * Merge all established calls (either in LinphoneCallStreamsRunning or LinphoneCallPaused) into a conference. - * + * * @return 0 if successful, -1 otherwise **/ int linphone_core_add_all_to_conference(LinphoneCore *lc) { @@ -381,9 +361,9 @@ int linphone_core_add_all_to_conference(LinphoneCore *lc) { /** * Terminates the conference and the calls associated with it. * @param lc the linphone core - * + * * All the calls that were merged to the conference are terminated, and the conference resources are destroyed. - * + * * @return 0 if successful, -1 otherwise **/ int linphone_core_terminate_conference(LinphoneCore *lc) { @@ -404,10 +384,10 @@ int linphone_core_terminate_conference(LinphoneCore *lc) { /** * Returns the number of participants to the conference, including the local participant. * @param lc the linphone core - * + * * Typically, after merging two calls into the conference, there is total of 3 participants: * the local participant (or local user), and two remote participants that were the destinations of the two previously establised calls. - * + * * @return the number of participants to the conference **/ int linphone_core_get_conference_size(LinphoneCore *lc) { diff --git a/coreapi/dict.c b/coreapi/dict.c index 417bb33f0..adc50d480 100644 --- a/coreapi/dict.c +++ b/coreapi/dict.c @@ -103,7 +103,7 @@ int linphone_dictionary_haskey(const LinphoneDictionary* obj, const char* key) void linphone_dictionary_foreach(const LinphoneDictionary* obj, void (*apply_func)(const char*, void*, void*), void* userdata) { - return belle_sip_dict_foreach(obj, apply_func, userdata); + belle_sip_dict_foreach(obj, apply_func, userdata); } struct lp_config_to_dict { diff --git a/coreapi/ec-calibrator.c b/coreapi/ec-calibrator.c index bff0a00f1..e5ad7ed09 100644 --- a/coreapi/ec-calibrator.c +++ b/coreapi/ec-calibrator.c @@ -114,8 +114,10 @@ static void ecc_deinit_filters(EcCalibrator *ecc){ static void on_tone_sent(void *data, MSFilter *f, unsigned int event_id, void *arg){ MSDtmfGenEvent *ev=(MSDtmfGenEvent*)arg; EcCalibrator *ecc=(EcCalibrator*)data; - ecc->acc-=ev->tone_start_time; - ms_message("Sent tone at %u",(unsigned int)ev->tone_start_time); + if (ev->tone_name[0] != '\0'){ + ecc->acc-=ev->tone_start_time; + ms_message("Sent tone at %u",(unsigned int)ev->tone_start_time); + } } static bool_t is_valid_tone(EcCalibrator *ecc, MSToneDetectorEvent *ev){ @@ -159,23 +161,23 @@ static void ecc_play_tones(EcCalibrator *ecc){ /* configure the tones to be scanned */ strncpy(expected_tone.tone_name,"freq1",sizeof(expected_tone.tone_name)); - expected_tone.frequency=2000; + expected_tone.frequency=(int)2349.32; expected_tone.min_duration=40; - expected_tone.min_amplitude=0.1; + expected_tone.min_amplitude=0.1f; ms_filter_call_method (ecc->det,MS_TONE_DETECTOR_ADD_SCAN,&expected_tone); strncpy(expected_tone.tone_name,"freq2",sizeof(expected_tone.tone_name)); - expected_tone.frequency=2300; + expected_tone.frequency=(int)2637.02; expected_tone.min_duration=40; - expected_tone.min_amplitude=0.1; + expected_tone.min_amplitude=0.1f; ms_filter_call_method (ecc->det,MS_TONE_DETECTOR_ADD_SCAN,&expected_tone); strncpy(expected_tone.tone_name,"freq3",sizeof(expected_tone.tone_name)); - expected_tone.frequency=2500; + expected_tone.frequency=(int)2093; expected_tone.min_duration=40; - expected_tone.min_amplitude=0.1; + expected_tone.min_amplitude=0.1f; ms_filter_call_method (ecc->det,MS_TONE_DETECTOR_ADD_SCAN,&expected_tone); @@ -191,24 +193,40 @@ static void ecc_play_tones(EcCalibrator *ecc){ ms_filter_add_notify_callback(ecc->gen,on_tone_sent,ecc,TRUE); /* play the three tones*/ - - tone.frequencies[0]=2000; + strncpy(tone.tone_name, "D", sizeof(tone.tone_name)); + tone.frequencies[0]=(int)2349.32; tone.duration=100; ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone); ms_usleep(300000); - tone.frequencies[0]=2300; + strncpy(tone.tone_name, "E", sizeof(tone.tone_name)); + tone.frequencies[0]=(int)2637.02; tone.duration=100; ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone); ms_usleep(300000); - tone.frequencies[0]=2500; + strncpy(tone.tone_name, "C", sizeof(tone.tone_name)); + tone.frequencies[0]=(int)2093; tone.duration=100; ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone); + ms_usleep(300000); + + /*these two next ones are for lyrism*/ + + tone.tone_name[0]='\0'; + tone.frequencies[0]=(int)1046.5; + tone.duration=400; + ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone); + ms_usleep(300000); + + tone.tone_name[0]='\0'; + tone.frequencies[0]=(int)1567.98; + tone.duration=400; + ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone); ms_sleep(1); if (ecc->freq1 && ecc->freq2 && ecc->freq3) { - int delay=ecc->acc/3; + int delay=(int)(ecc->acc/3); if (delay<0){ ms_error("Quite surprising calibration result, delay=%i",delay); ecc->status=LinphoneEcCalibratorFailed; diff --git a/coreapi/enum.c b/coreapi/enum.c index 8818ae6ee..419e7000e 100644 --- a/coreapi/enum.c +++ b/coreapi/enum.c @@ -31,10 +31,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. static char *create_enum_domain(const char *number){ - int len=strlen(number); + size_t len=strlen(number); char *domain=ms_malloc((len*2)+10); - int i,j; - + long i,j; + for (i=0,j=len-1;j>=0;j--){ domain[i]=number[j]; i++; @@ -105,11 +105,11 @@ int enum_lookup(const char *enum_domain, enum_lookup_res_t **res){ /* ns_msg handle; int count; - + memset(&handle,0,sizeof(handle)); *res=NULL; ms_message("Resolving %s...",enum_domain); - + err=res_search(enum_domain,ns_c_in,ns_t_naptr,dns_answer,DNS_ANSWER_MAX_SIZE); if (err<0){ ms_warning("Error resolving enum:",herror(h_errno)); @@ -117,7 +117,7 @@ int enum_lookup(const char *enum_domain, enum_lookup_res_t **res){ } ns_initparse(dns_answer,DNS_ANSWER_MAX_SIZE,&handle); count=ns_msg_count(handle,ns_s_an); - + for(i=0;idir!=LinphoneSubscriptionOutgoing){ ms_error("linphone_event_send_subscribe(): cannot send or update something that is not an outgoing subscription."); return -1; @@ -173,12 +173,12 @@ int linphone_event_send_subscribe(LinphoneEvent *lev, const LinphoneContent *bod /*those states are ok*/ break; } - + if (lev->send_custom_headers){ sal_op_set_sent_custom_header(lev->op,lev->send_custom_headers); lev->send_custom_headers=NULL; }else sal_op_set_sent_custom_header(lev->op,NULL); - + err=sal_subscribe(lev->op,NULL,NULL,lev->name,lev->expires,sal_body_from_content(&salbody,body)); if (err==0){ if (lev->subscription_state==LinphoneSubscriptionNone) @@ -238,7 +238,7 @@ LinphoneEvent *linphone_core_create_publish(LinphoneCore *lc, const LinphoneAddr static int _linphone_event_send_publish(LinphoneEvent *lev, const LinphoneContent *body, bool_t notify_err){ SalBody salbody; int err; - + if (lev->dir!=LinphoneSubscriptionInvalidDir){ ms_error("linphone_event_update_publish(): this is not a PUBLISH event."); return -1; @@ -276,7 +276,6 @@ int linphone_event_update_publish(LinphoneEvent* lev, const LinphoneContent* bod return linphone_event_send_publish(lev,body); } - void linphone_event_set_user_data(LinphoneEvent *ev, void *up){ ev->userdata=up; } @@ -302,7 +301,7 @@ void linphone_event_terminate(LinphoneEvent *lev){ }else if (lev->dir==LinphoneSubscriptionOutgoing){ sal_unsubscribe(lev->op); } - + if (lev->publish_state!=LinphonePublishNone){ if (lev->publish_state==LinphonePublishOk && lev->expires!=-1){ sal_publish(lev->op,NULL,NULL,NULL,0,NULL); @@ -310,7 +309,7 @@ void linphone_event_terminate(LinphoneEvent *lev){ linphone_event_set_publish_state(lev,LinphonePublishCleared); return; } - + if (lev->subscription_state!=LinphoneSubscriptionNone){ linphone_event_set_state(lev,LinphoneSubscriptionTerminated); return; diff --git a/coreapi/friend.c b/coreapi/friend.c index e6c429bee..487cfd2a4 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -92,7 +92,7 @@ LinphoneFriend *linphone_find_friend_by_inc_subscribe(MSList *l, SalOp *op){ MSList *elem; for (elem=l;elem!=NULL;elem=elem->next){ LinphoneFriend *lf=(LinphoneFriend*)elem->data; - if (lf->insub==op) return lf; + if (ms_list_find(lf->insubs, op)) return lf; } return NULL; } @@ -102,7 +102,7 @@ LinphoneFriend *linphone_find_friend_by_out_subscribe(MSList *l, SalOp *op){ LinphoneFriend *lf; for (elem=l;elem!=NULL;elem=elem->next){ lf=(LinphoneFriend*)elem->data; - if (lf->outsub==op) return lf; + if (lf->outsub && (lf->outsub == op || sal_op_is_forked_of(lf->outsub, op))) return lf; } return NULL; } @@ -227,12 +227,29 @@ int linphone_friend_set_inc_subscribe_policy(LinphoneFriend *fr, LinphoneSubscri } void linphone_friend_notify(LinphoneFriend *lf, LinphonePresenceModel *presence){ - char *addr=linphone_address_as_string(linphone_friend_get_address(lf)); - ms_message("Want to notify %s, insub=%p",addr,lf->insub); - ms_free(addr); - if (lf->insub!=NULL){ - sal_notify_presence(lf->insub,(SalPresenceModel *)presence); + MSList *elem; + if (lf->insubs){ + char *addr=linphone_address_as_string(linphone_friend_get_address(lf)); + ms_message("Want to notify %s",addr); + ms_free(addr); } + for(elem=lf->insubs; elem!=NULL; elem=elem->next){ + SalOp *op = (SalOp*)elem->data; + sal_notify_presence(op,(SalPresenceModel *)presence); + } +} + +void linphone_friend_add_incoming_subscription(LinphoneFriend *lf, SalOp *op){ + /*ownership of the op is transfered from sal to the LinphoneFriend*/ + lf->insubs = ms_list_append(lf->insubs, op); +} + +void linphone_friend_remove_incoming_subscription(LinphoneFriend *lf, SalOp *op){ + if (ms_list_find(lf->insubs, op)){ + sal_op_release(op); + lf->insubs = ms_list_remove(lf->insubs, op); + } + } static void linphone_friend_unsubscribe(LinphoneFriend *lf){ @@ -260,17 +277,12 @@ static void linphone_friend_invalidate_subscription(LinphoneFriend *lf){ void linphone_friend_close_subscriptions(LinphoneFriend *lf){ linphone_friend_unsubscribe(lf); - if (lf->insub){ - sal_notify_presence_close(lf->insub); - - } + ms_list_for_each(lf->insubs, (MSIterateFunc) sal_notify_presence_close); + lf->insubs = ms_list_free_with_data(lf->insubs, (MSIterateFunc)sal_op_release); } static void _linphone_friend_destroy(LinphoneFriend *lf){ - if (lf->insub) { - sal_op_release(lf->insub); - lf->insub=NULL; - } + lf->insubs = ms_list_free_with_data(lf->insubs, (MSIterateFunc) sal_op_release); if (lf->outsub){ sal_op_release(lf->outsub); lf->outsub=NULL; @@ -280,6 +292,17 @@ static void _linphone_friend_destroy(LinphoneFriend *lf){ if (lf->info!=NULL) buddy_info_free(lf->info); } +static belle_sip_error_code _linphone_friend_marshall(belle_sip_object_t *obj, char* buff, size_t buff_size, size_t *offset) { + LinphoneFriend *lf = (LinphoneFriend*)obj; + belle_sip_error_code err = BELLE_SIP_OK; + if (lf->uri){ + char *tmp = linphone_address_as_string(lf->uri); + err = belle_sip_snprintf(buff, buff_size, offset, "%s", tmp); + ms_free(tmp); + } + return err; +} + const LinphoneAddress *linphone_friend_get_address(const LinphoneFriend *lf){ return lf->uri; } @@ -366,7 +389,7 @@ LinphoneOnlineStatus linphone_friend_get_status(const LinphoneFriend *lf){ break; case LinphonePresenceActivityOnline: /* Should not happen! */ - ms_warning("LinphonePresenceActivityOnline should not happen here!"); + /*ms_warning("LinphonePresenceActivityOnline should not happen here!");*/ break; case LinphonePresenceActivityOffline: online_status = LinphoneStatusOffline; @@ -481,6 +504,11 @@ void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *lf) return ; } lc->friends=ms_list_append(lc->friends,linphone_friend_ref(lf)); + if (ms_list_find(lc->subscribers, lf)){ + /*if this friend was in the pending subscriber list, now remove it from this list*/ + lc->subscribers = ms_list_remove(lc->subscribers, lf); + linphone_friend_unref(lf); + } lf->lc=lc; if ( linphone_core_ready(lc)) linphone_friend_apply(lf,lc); else lf->commit=TRUE; @@ -490,7 +518,7 @@ void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *lf) void linphone_core_remove_friend(LinphoneCore *lc, LinphoneFriend* fl){ MSList *el=ms_list_find(lc->friends,fl); if (el!=NULL){ - linphone_friend_destroy((LinphoneFriend*)el->data); + linphone_friend_unref((LinphoneFriend*)el->data); lc->friends=ms_list_remove_link(lc->friends,el); linphone_core_write_friends_config(lc); }else{ @@ -703,6 +731,6 @@ BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneFriend); BELLE_SIP_INSTANCIATE_VPTR(LinphoneFriend, belle_sip_object_t, (belle_sip_object_destroy_t) _linphone_friend_destroy, NULL, // clone - NULL, // marshal + _linphone_friend_marshall, FALSE ); \ No newline at end of file diff --git a/coreapi/gitversion.cmake b/coreapi/gitversion.cmake index 23fecb10c..eb0f99e3c 100644 --- a/coreapi/gitversion.cmake +++ b/coreapi/gitversion.cmake @@ -27,13 +27,8 @@ if(GIT_EXECUTABLE) OUTPUT_VARIABLE GIT_REVISION OUTPUT_STRIP_TRAILING_WHITESPACE ) - execute_process( - COMMAND ${CMAKE_COMMAND} -E echo "#define LIBLINPHONE_GIT_VERSION \"${GIT_REVISION}\"" - OUTPUT_FILE ${OUTPUT_DIR}/liblinphone_gitversion.h - ) else() - execute_process( - COMMAND ${CMAKE_COMMAND} -E echo "#define LIBLINPHONE_GIT_VERSION \"unknown\"" - OUTPUT_FILE ${OUTPUT_DIR}/liblinphone_gitversion.h - ) + set(GIT_REVISION "unknown") endif() + +configure_file("${WORK_DIR}/gitversion.h.in" "${OUTPUT_DIR}/liblinphone_gitversion.h" @ONLY) diff --git a/coreapi/gitversion.h.in b/coreapi/gitversion.h.in new file mode 100644 index 000000000..493b4bcb1 --- /dev/null +++ b/coreapi/gitversion.h.in @@ -0,0 +1,21 @@ +/* +linphone +Copyright (C) 2010-2014 Belledonne Communications SARL + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + + +#define LIBLINPHONE_GIT_VERSION "@GIT_REVISION@" \ No newline at end of file diff --git a/coreapi/help/CMakeLists.txt b/coreapi/help/CMakeLists.txt index fa6915d8f..3a550e294 100644 --- a/coreapi/help/CMakeLists.txt +++ b/coreapi/help/CMakeLists.txt @@ -24,7 +24,7 @@ find_package(Doxygen) if(DOXYGEN_FOUND) if(DOXYGEN_DOT_FOUND) - set(top_srcdir ${CMAKE_SOURCE_DIR}) + set(top_srcdir "${CMAKE_CURRENT_LIST_DIR}/../../") configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) file(GLOB DOC_INPUT_FILES [^.]*.c @@ -36,7 +36,7 @@ if(DOXYGEN_FOUND) COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile ${DOC_INPUT_FILES} ) - add_custom_target(doc ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/doc/html/index.html") + add_custom_target(linphone-doc ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/doc/html/index.html") install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/doc/html" "${CMAKE_CURRENT_BINARY_DIR}/doc/xml" DESTINATION "share/doc/linphone-${LINPHONE_VERSION}") else() diff --git a/coreapi/help/Makefile.am b/coreapi/help/Makefile.am index 479d2b31d..895b1e99b 100644 --- a/coreapi/help/Makefile.am +++ b/coreapi/help/Makefile.am @@ -46,7 +46,7 @@ clean-local: if ENABLE_TUTORIALS -noinst_PROGRAMS=helloworld registration buddy_status chatroom notify filetransfer +noinst_PROGRAMS=helloworld registration buddy_status chatroom notify filetransfer realtimetext_sender realtimetext_receiver helloworld_SOURCES=helloworld.c LINPHONE_TUTOS=$(helloworld_SOURCES) @@ -81,6 +81,16 @@ LINPHONE_TUTOS+=$(filetransfer_SOURCES) filetransfer_LDADD=$(helloworld_LDADD) +realtimetext_sender_SOURCES=realtimetext_sender.c +LINPHONE_TUTOS+=$(realtimetext_sender_SOURCES) + +realtimetext_sender_LDADD=$(helloworld_LDADD) + +realtimetext_receiver_SOURCES=realtimetext_receiver.c +LINPHONE_TUTOS+=$(realtimetext_receiver_SOURCES) + +realtimetext_receiver_LDADD=$(helloworld_LDADD) + AM_CFLAGS=\ -I$(top_srcdir)/coreapi \ $(STRICT_OPTIONS) \ diff --git a/coreapi/help/chatroom.c b/coreapi/help/chatroom.c index 1f0f200a0..62d75bab9 100644 --- a/coreapi/help/chatroom.c +++ b/coreapi/help/chatroom.c @@ -81,7 +81,7 @@ int main(int argc, char *argv[]){ /*Next step is to create a chat root*/ - chat_room = linphone_core_create_chat_room(lc,dest_friend); + chat_room = linphone_core_get_chat_room_from_uri(lc,dest_friend); linphone_chat_room_send_message(chat_room,"Hello world"); /*sending message*/ @@ -92,7 +92,6 @@ int main(int argc, char *argv[]){ } printf("Shutting down...\n"); - linphone_chat_room_destroy(chat_room); linphone_core_destroy(lc); printf("Exited\n"); return 0; diff --git a/coreapi/help/filetransfer.c b/coreapi/help/filetransfer.c index 570e22692..21cb19115 100644 --- a/coreapi/help/filetransfer.c +++ b/coreapi/help/filetransfer.c @@ -160,7 +160,7 @@ int main(int argc, char *argv[]){ /*Next step is to create a chat room*/ - chat_room = linphone_core_create_chat_room(lc,dest_friend); + chat_room = linphone_core_get_chat_room_from_uri(lc,dest_friend); content = linphone_core_create_content(lc); linphone_content_set_type(content,"text"); @@ -196,7 +196,6 @@ int main(int argc, char *argv[]){ printf("Shutting down...\n"); linphone_content_unref(content); - linphone_chat_room_destroy(chat_room); linphone_core_destroy(lc); printf("Exited\n"); return 0; diff --git a/coreapi/help/java/org/linphone/core/tutorials/TutorialBuddyStatus.java b/coreapi/help/java/org/linphone/core/tutorials/TutorialBuddyStatus.java index 22a850b36..82a094183 100644 --- a/coreapi/help/java/org/linphone/core/tutorials/TutorialBuddyStatus.java +++ b/coreapi/help/java/org/linphone/core/tutorials/TutorialBuddyStatus.java @@ -104,7 +104,6 @@ public class TutorialBuddyStatus implements LinphoneCoreListener { public void displayMessage(LinphoneCore lc, String message) {} public void displayWarning(LinphoneCore lc, String message) {} public void globalState(LinphoneCore lc, GlobalState state, String message) {} - public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from, String message) {} public void callState(LinphoneCore lc, LinphoneCall call, State cstate, String msg) {} public void callStatsUpdated(LinphoneCore lc, LinphoneCall call, LinphoneCallStats stats) {} public void ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status,int delay_ms, Object data) {} diff --git a/coreapi/help/java/org/linphone/core/tutorials/TutorialChatRoom.java b/coreapi/help/java/org/linphone/core/tutorials/TutorialChatRoom.java index e8a7da936..11e436213 100644 --- a/coreapi/help/java/org/linphone/core/tutorials/TutorialChatRoom.java +++ b/coreapi/help/java/org/linphone/core/tutorials/TutorialChatRoom.java @@ -90,10 +90,6 @@ public class TutorialChatRoom implements LinphoneCoreListener, LinphoneChatMessa public void callEncryptionChanged(LinphoneCore lc, LinphoneCall call,boolean encrypted, String authenticationToken) {} public void notifyReceived(LinphoneCore lc, LinphoneCall call, LinphoneAddress from, byte[] event){} public void dtmfReceived(LinphoneCore lc, LinphoneCall call, int dtmf) {} - - public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from, String message) { - //Deprecated - } diff --git a/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java b/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java index 44c432271..5a2db2568 100644 --- a/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java +++ b/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java @@ -88,7 +88,6 @@ public class TutorialRegistration implements LinphoneCoreListener { public void globalState(LinphoneCore lc, GlobalState state, String message) {} public void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf,String url) {} public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf) {} - public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from, String message) {} public void callState(LinphoneCore lc, LinphoneCall call, State cstate, String msg) {} public void callStatsUpdated(LinphoneCore lc, LinphoneCall call, LinphoneCallStats stats) {} public void ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status,int delay_ms, Object data) {} diff --git a/coreapi/help/realtimetext_receiver.c b/coreapi/help/realtimetext_receiver.c new file mode 100644 index 000000000..63801c516 --- /dev/null +++ b/coreapi/help/realtimetext_receiver.c @@ -0,0 +1,115 @@ + +/* +linphone +Copyright (C) 2015 Belledonne Communications SARL + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/** + * @defgroup real_time_text Real Time Text Receiver + * @ingroup tutorials + This program is able to receive chat message in real time on port 5060. Use realtimetext_sender to generate chat message + usage: ./realtimetext_receiver + + @include realtimetext_sender.c + */ +#ifdef IN_LINPHONE +#include "linphonecore.h" +#else +#include "linphone/linphonecore.h" +#endif + +#include + +static bool_t running=TRUE; + +static void stop(int signum){ + running=FALSE; +} + +/* + * Call state notification callback + */ +static void call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *msg){ + switch(cstate){ + case LinphoneCallIncomingReceived: + printf("It is now ringing remotely !\n"); + linphone_core_accept_call(lc,call); + break; + case LinphoneCallReleased: + printf("call terminated, exit...\n"); + running=FALSE; + break; + default: + printf("Unhandled notification %i\n",cstate); + } +} + +/* + * Completed message received + */ +static void message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *message) { + char *from=linphone_address_as_string(linphone_chat_room_get_peer_address(room)); + printf(" Message [%s] received from [%s] \n",linphone_chat_message_get_text(message),from); + ms_free(from); +} + +/* + * + * Remote is typing + */ +static void is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room) { + LinphoneCall *call = linphone_chat_room_get_call(room); /*get corresponding call*/ + if (call && linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(call))) /*check if realtime text enabled for this call*/ + printf("%c",linphone_chat_room_get_char(room)); + /*else ignored*/ +} + +int main(int argc, char *argv[]){ + LinphoneCoreVTable vtable={0}; + LinphoneCore *lc; + + + signal(SIGINT,stop); + +#ifdef DEBUG + linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/ +#endif + /* + Fill the LinphoneCoreVTable with application callbacks. + All are optional. Here we only use the call_state_changed callbacks + in order to get notifications about the progress of the call. + */ + vtable.call_state_changed=call_state_changed; /*to receive incoming call*/ + vtable.message_received=message_received; /*to receive committed messages*/ + vtable.is_composing_received=is_composing_received; /*to receive char in real time*/ + /* + Instanciate a LinphoneCore object given the LinphoneCoreVTable + */ + lc=linphone_core_new(&vtable,NULL,NULL,NULL); + + /* main loop for receiving notifications and doing background linphonecore work: */ + while(running){ + linphone_core_iterate(lc); + ms_usleep(50000); + } + + printf("Shutting down...\n"); + linphone_core_destroy(lc); + printf("Exited\n"); + return 0; +} + diff --git a/coreapi/help/realtimetext_sender.c b/coreapi/help/realtimetext_sender.c new file mode 100644 index 000000000..29a738fb2 --- /dev/null +++ b/coreapi/help/realtimetext_sender.c @@ -0,0 +1,158 @@ + +/* +linphone +Copyright (C) 2015 Belledonne Communications SARL + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/** + * @defgroup real_time_text Real Time Text Sender + * @ingroup tutorials + This program just send chat message in real time to dest uri. Use realtimetext_receiver to receive message. + usage: ./realtimetext_sender sip:localhost:5060 + + + @include realtimetext_sender.c + */ +#ifdef IN_LINPHONE +#include "linphonecore.h" +#else +#include "linphone/linphonecore.h" +#endif + +#include + +static bool_t running=TRUE; + +static void stop(int signum){ + running=FALSE; +} + + + +int main(int argc, char *argv[]){ + LinphoneCoreVTable vtable={0}; + LinphoneCore *lc; + LinphoneCall *call=NULL; + LinphoneChatRoom *chat_room; + LinphoneChatMessage *chat_message=NULL; + const char *dest=NULL; + LCSipTransports tp; + tp.udp_port=LC_SIP_TRANSPORT_RANDOM; + tp.tcp_port=LC_SIP_TRANSPORT_RANDOM; + tp.tls_port=LC_SIP_TRANSPORT_RANDOM; + + /* take the destination sip uri from the command line arguments */ + if (argc>1){ + dest=argv[1]; + } + + signal(SIGINT,stop); + +#ifdef DEBUG + linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/ +#endif + + /* + Instanciate a LinphoneCore object given the LinphoneCoreVTable + */ + lc=linphone_core_new(&vtable,NULL,NULL,NULL); + + + linphone_core_set_sip_transports(lc,&tp); /*to avoid port colliding with receiver*/ + if (dest){ + /* + Place an outgoing call with rtt enabled + */ + LinphoneCallParams *cp = linphone_core_create_call_params(lc, NULL); + linphone_call_params_enable_realtime_text(cp,TRUE); /*enable real time text*/ + call=linphone_core_invite_with_params(lc,dest,cp); + linphone_call_params_destroy(cp); + if (call==NULL){ + printf("Could not place call to %s\n",dest); + goto end; + }else printf("Call to %s is in progress...",dest); + linphone_call_ref(call); + + } + /*wait for call to be established*/ + while (running && (linphone_call_get_state(call) == LinphoneCallOutgoingProgress + || linphone_call_get_state(call) == LinphoneCallOutgoingInit)) { + linphone_core_iterate(lc); + ms_usleep(50000); + } + /*check if call is established*/ + switch (linphone_call_get_state(call)) { + case LinphoneCallError: + case LinphoneCallReleased: + case LinphoneCallEnd: + printf("Could not place call to %s\n",dest); + goto end; + break; + default: + break; + /*continue*/ + } + + chat_room=linphone_call_get_chat_room(call); /*create a chat room associated to this call*/ + + /* main loop for sending message and doing background linphonecore work: */ + while(running){ + char character; + /*to disable terminal buffering*/ + if (system ("/bin/stty raw") == -1){ + ms_error("/bin/stty error"); + } + character = getchar(); + if (system("/bin/stty cooked") == -1){ + ms_error("/bin/stty error"); + } + if (character==0x03) {/*CTRL C*/ + running=0; + break; + } + if (character != EOF) { + /* user has typed something*/ + if (chat_message == NULL) { + /*create a new message*/ + chat_message = linphone_chat_room_create_message(chat_room,""); /*create an empty message*/ + } + if (character == '\r') { + /*new line, committing message*/ + linphone_chat_room_send_chat_message(chat_room,chat_message); + chat_message = NULL; /*reset message*/ + } else { + linphone_chat_message_put_char(chat_message,character); /*send char in realtime*/ + } + } + linphone_core_iterate(lc); + ms_usleep(50000); + } + if (call && linphone_call_get_state(call)!=LinphoneCallEnd){ + /* terminate the call */ + printf("Terminating the call...\n"); + linphone_core_terminate_call(lc,call); + /*at this stage we don't need the call object */ + linphone_call_unref(call); + } + +end: + printf("Shutting down...\n"); + linphone_core_destroy(lc); + printf("Exited\n"); + return 0; +} + diff --git a/coreapi/ldap/ldapprovider.h b/coreapi/ldap/ldapprovider.h index 066ab7ba8..d45721e7b 100644 --- a/coreapi/ldap/ldapprovider.h +++ b/coreapi/ldap/ldapprovider.h @@ -38,4 +38,4 @@ LINPHONE_PUBLIC unsigned int linphone_ldap_contact_provider_get_ LINPHONE_PUBLIC LinphoneLDAPContactProvider* linphone_ldap_contact_provider_ref( void* obj ); void linphone_ldap_contact_provider_unref( void* obj ); LinphoneLDAPContactProvider* linphone_ldap_contact_provider_cast( void* obj ); -LINPHONE_PUBLIC int linphone_ldap_contact_provider_available(); +LINPHONE_PUBLIC int linphone_ldap_contact_provider_available(void); diff --git a/coreapi/lime.h b/coreapi/lime.h index c196a6410..a5da93e34 100644 --- a/coreapi/lime.h +++ b/coreapi/lime.h @@ -182,5 +182,5 @@ LINPHONE_PUBLIC char *lime_error_code_to_string(int errorCode); * * @return TRUE if Lime is available, FALSE if not */ -LINPHONE_PUBLIC bool_t lime_is_available(); +LINPHONE_PUBLIC bool_t lime_is_available(void); #endif /* LIME_H */ diff --git a/coreapi/linphone_proxy_config.h b/coreapi/linphone_proxy_config.h new file mode 100644 index 000000000..f28de3df7 --- /dev/null +++ b/coreapi/linphone_proxy_config.h @@ -0,0 +1,535 @@ +/* +Copyright (C) 2010-2015 Belledonne Communications SARL + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef LINPHONE_PROXY_CONFIG_H +#define LINPHONE_PROXY_CONFIG_H + +/** + * @addtogroup proxies + * @{ +**/ + +/** + * Creates an empty proxy config. + * @deprecated, use #linphone_core_create_proxy_config instead +**/ +LINPHONE_PUBLIC LinphoneProxyConfig *linphone_proxy_config_new(void); + +/** + * Acquire a reference to the proxy config. + * @param[in] cfg #LinphoneProxyConfig object. + * @return The same proxy config. +**/ +LINPHONE_PUBLIC LinphoneProxyConfig *linphone_proxy_config_ref(LinphoneProxyConfig *cfg); + +/** + * Release reference to the proxy config. + * @param[in] cfg #LinphoneProxyConfig object. +**/ +LINPHONE_PUBLIC void linphone_proxy_config_unref(LinphoneProxyConfig *cfg); + +/** + * Retrieve the user pointer associated with the proxy config. + * @param[in] cfg #LinphoneProxyConfig object. + * @return The user pointer associated with the proxy config. +**/ +LINPHONE_PUBLIC void *linphone_proxy_config_get_user_data(const LinphoneProxyConfig *cfg); + +/** + * Assign a user pointer to the proxy config. + * @param[in] cfg #LinphoneProxyConfig object. + * @param[in] ud The user pointer to associate with the proxy config. +**/ +LINPHONE_PUBLIC void linphone_proxy_config_set_user_data(LinphoneProxyConfig *cfg, void *ud); + +/** + * Sets the proxy address + * + * Examples of valid sip proxy address are: + * - IP address: sip:87.98.157.38 + * - IP address with port: sip:87.98.157.38:5062 + * - hostnames : sip:sip.example.net +**/ +LINPHONE_PUBLIC int linphone_proxy_config_set_server_addr(LinphoneProxyConfig *cfg, const char *server_addr); + +/** + * @deprecated Use linphone_proxy_config_set_identity_address() +**/ +LINPHONE_PUBLIC int linphone_proxy_config_set_identity(LinphoneProxyConfig *cfg, const char *identity); + +/** + * Sets the user identity as a SIP address. + * + * This identity is normally formed with display name, username and domain, such + * as: + * Alice + * The REGISTER messages will have from and to set to this identity. + * +**/ +LINPHONE_PUBLIC int linphone_proxy_config_set_identity_address(LinphoneProxyConfig *cfg, const LinphoneAddress *identity); + +/** + * Sets a SIP route. + * When a route is set, all outgoing calls will go to the route's destination if this proxy + * is the default one (see linphone_core_set_default_proxy() ). + * @Return -1 if route is invalid, 0 otherwise. +**/ +LINPHONE_PUBLIC int linphone_proxy_config_set_route(LinphoneProxyConfig *cfg, const char *route); + +/** + * Sets the registration expiration time in seconds. +**/ +LINPHONE_PUBLIC void linphone_proxy_config_set_expires(LinphoneProxyConfig *cfg, int expires); + +#define linphone_proxy_config_expires linphone_proxy_config_set_expires + +/** + * Indicates either or not, REGISTRATION must be issued for this #LinphoneProxyConfig . + *
In case this #LinphoneProxyConfig has been added to #LinphoneCore, follows the linphone_proxy_config_edit() rule. + * @param[in] cfg #LinphoneProxyConfig object. + * @param val if true, registration will be engaged + */ +LINPHONE_PUBLIC void linphone_proxy_config_enable_register(LinphoneProxyConfig *cfg, bool_t val); + +#define linphone_proxy_config_enableregister linphone_proxy_config_enable_register + +/** + * Starts editing a proxy configuration. + * + * Because proxy configuration must be consistent, applications MUST + * call linphone_proxy_config_edit() before doing any attempts to modify + * proxy configuration (such as identity, proxy address and so on). + * Once the modifications are done, then the application must call + * linphone_proxy_config_done() to commit the changes. +**/ +LINPHONE_PUBLIC void linphone_proxy_config_edit(LinphoneProxyConfig *cfg); + +/** + * Commits modification made to the proxy configuration. +**/ +LINPHONE_PUBLIC int linphone_proxy_config_done(LinphoneProxyConfig *cfg); + +/** + * Indicates either or not, PUBLISH must be issued for this #LinphoneProxyConfig . + *
In case this #LinphoneProxyConfig has been added to #LinphoneCore, follows the linphone_proxy_config_edit() rule. + * @param[in] cfg #LinphoneProxyConfig object. + * @param val if true, publish will be engaged + * + */ +LINPHONE_PUBLIC void linphone_proxy_config_enable_publish(LinphoneProxyConfig *cfg, bool_t val); + +/** + * Set the publish expiration time in second. + * @param[in] cfg #LinphoneProxyConfig object. + * @param expires in second + * */ +LINPHONE_PUBLIC void linphone_proxy_config_set_publish_expires(LinphoneProxyConfig *cfg, int expires); + +/** + * get the publish expiration time in second. Default value is the registration expiration value. + * @param[in] cfg #LinphoneProxyConfig object. + * @return expires in second + * */ +LINPHONE_PUBLIC int linphone_proxy_config_get_publish_expires(const LinphoneProxyConfig *cfg); + +/** + * Sets whether liblinphone should replace "+" by international calling prefix in dialed numbers (passed to + * #linphone_core_invite ). +**/ +LINPHONE_PUBLIC void linphone_proxy_config_set_dial_escape_plus(LinphoneProxyConfig *cfg, bool_t val); + +/** + * 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, without "+". + * +**/ +LINPHONE_PUBLIC void linphone_proxy_config_set_dial_prefix(LinphoneProxyConfig *cfg, const char *prefix); + + /** + * Indicates whether quality statistics during call should be stored and sent to a collector according to RFC 6035. + * @param[in] cfg #LinphoneProxyConfig object. + * @param[in] enable True to sotre quality statistics and sent them to the collector, false to disable it. + */ +LINPHONE_PUBLIC void linphone_proxy_config_enable_quality_reporting(LinphoneProxyConfig *cfg, bool_t enable); + +/** + * Indicates whether quality statistics during call should be stored and sent to a collector according to RFC 6035. + * @param[in] cfg #LinphoneProxyConfig object. + * @return True if quality repotring is enabled, false otherwise. + */ +LINPHONE_PUBLIC bool_t linphone_proxy_config_quality_reporting_enabled(LinphoneProxyConfig *cfg); + + /** + * Set the route of the collector end-point when using quality reporting. This SIP address + * should be used on server-side to process packets directly before discarding packets. Collector address + * should be a non existing account and will not receive any messages. + * If NULL, reports will be send to the proxy domain. + * @param[in] cfg #LinphoneProxyConfig object. + * @param[in] collector route of the collector end-point, if NULL PUBLISH will be sent to the proxy domain. + */ +LINPHONE_PUBLIC void linphone_proxy_config_set_quality_reporting_collector(LinphoneProxyConfig *cfg, const char *collector); + + /** + * Get the route of the collector end-point when using quality reporting. This SIP address + * should be used on server-side to process packets directly before discarding packets. Collector address + * should be a non existing account and will not receive any messages. + * If NULL, reports will be send to the proxy domain. + * @param[in] cfg #LinphoneProxyConfig object. + * @return The SIP address of the collector end-point. + */ +LINPHONE_PUBLIC const char *linphone_proxy_config_get_quality_reporting_collector(const LinphoneProxyConfig *cfg); + +/** + * Set the interval between 2 interval reports sending when using quality reporting. If call exceed interval size, an + * interval report will be sent to the collector. On call termination, a session report will be sent + * for the remaining period. Value must be 0 (disabled) or positive. + * @param[in] cfg #LinphoneProxyConfig object. + * @param[in] interval The interval in seconds, 0 means interval reports are disabled. + */ +LINPHONE_PUBLIC void linphone_proxy_config_set_quality_reporting_interval(LinphoneProxyConfig *cfg, uint8_t interval); + +/** + * Get the interval between interval reports when using quality reporting. + * @param[in] cfg #LinphoneProxyConfig object. + * @return The interval in seconds, 0 means interval reports are disabled. + */ + +LINPHONE_PUBLIC int linphone_proxy_config_get_quality_reporting_interval(LinphoneProxyConfig *cfg); + +/** + * Get the registration state of the given proxy config. + * @param[in] cfg #LinphoneProxyConfig object. + * @return The registration state of the proxy config. +**/ +LINPHONE_PUBLIC LinphoneRegistrationState linphone_proxy_config_get_state(const LinphoneProxyConfig *cfg); + +/** + * @return a boolean indicating that the user is sucessfully registered on the proxy. + * @deprecated Use linphone_proxy_config_get_state() instead. +**/ +LINPHONE_PUBLIC bool_t linphone_proxy_config_is_registered(const LinphoneProxyConfig *cfg); + +/** + * Get the domain name of the given proxy config. + * @param[in] cfg #LinphoneProxyConfig object. + * @return The domain name of the proxy config. +**/ +LINPHONE_PUBLIC const char *linphone_proxy_config_get_domain(const LinphoneProxyConfig *cfg); + +/** + * Get the realm of the given proxy config. + * @param[in] cfg #LinphoneProxyConfig object. + * @return The realm of the proxy config. +**/ +LINPHONE_PUBLIC const char *linphone_proxy_config_get_realm(const LinphoneProxyConfig *cfg); + +/** + * Set the realm of the given proxy config. + * @param[in] cfg #LinphoneProxyConfig object. + * @param[in] realm New realm value. + * @return The realm of the proxy config. +**/ +LINPHONE_PUBLIC void linphone_proxy_config_set_realm(LinphoneProxyConfig *cfg, const char * realm); + +/** + * @return the route set for this proxy configuration. +**/ +LINPHONE_PUBLIC const char *linphone_proxy_config_get_route(const LinphoneProxyConfig *cfg); + +/** + * @return the SIP identity that belongs to this proxy configuration. +**/ +LINPHONE_PUBLIC const LinphoneAddress *linphone_proxy_config_get_identity_address(const LinphoneProxyConfig *cfg); + +/** + * @deprecated use linphone_proxy_config_get_identity_address() +**/ +LINPHONE_PUBLIC const char *linphone_proxy_config_get_identity(const LinphoneProxyConfig *cfg); + +/** + * @return TRUE if PUBLISH request is enabled for this proxy. +**/ +LINPHONE_PUBLIC bool_t linphone_proxy_config_publish_enabled(const LinphoneProxyConfig *cfg); + +/** + * @return the proxy's SIP address. +**/ +LINPHONE_PUBLIC const char *linphone_proxy_config_get_server_addr(const LinphoneProxyConfig *cfg); + +#define linphone_proxy_config_get_addr linphone_proxy_config_get_server_addr + +/** + * @return the duration of registration. +**/ +LINPHONE_PUBLIC int linphone_proxy_config_get_expires(const LinphoneProxyConfig *cfg); + +/** + * @return TRUE if registration to the proxy is enabled. +**/ +LINPHONE_PUBLIC bool_t linphone_proxy_config_register_enabled(const LinphoneProxyConfig *cfg); + +/** + * Refresh a proxy registration. + * This is useful if for example you resuming from suspend, thus IP address may have changed. +**/ +LINPHONE_PUBLIC void linphone_proxy_config_refresh_register(LinphoneProxyConfig *cfg); + +/** + * Prevent a proxy config from refreshing its registration. + * This is useful to let registrations to expire naturally (or) when the application wants to keep control on when + * refreshes are sent. + * However, linphone_core_set_network_reachable(lc,TRUE) will always request the proxy configs to refresh their registrations. + * The refreshing operations can be resumed with linphone_proxy_config_refresh_register(). + * @param[in] cfg #LinphoneProxyConfig object. +**/ +LINPHONE_PUBLIC void linphone_proxy_config_pause_register(LinphoneProxyConfig *cfg); + +LINPHONE_PUBLIC const LinphoneAddress* linphone_proxy_config_get_contact(const LinphoneProxyConfig *cfg); + +/** + * @return previously set contact parameters. +**/ +LINPHONE_PUBLIC const char *linphone_proxy_config_get_contact_parameters(const LinphoneProxyConfig *cfg); + +/** + * Set optional contact parameters that will be added to the contact information sent in the registration. + * @param[in] cfg #LinphoneProxyConfig object. + * @param contact_params a string contaning the additional parameters in text form, like "myparam=something;myparam2=something_else" + * + * The main use case for this function is provide the proxy additional information regarding the user agent, like for example unique identifier or apple push id. + * As an example, the contact address in the SIP register sent will look like ;apple-push-id=43143-DFE23F-2323-FA2232. +**/ +LINPHONE_PUBLIC void linphone_proxy_config_set_contact_parameters(LinphoneProxyConfig *cfg, const char *contact_params); + +/** + * Set optional contact parameters that will be added to the contact information sent in the registration, inside the URI. + * @param[in] cfg #LinphoneProxyConfig object. + * @param contact_uri_params a string containing the additional parameters in text form, like "myparam=something;myparam2=something_else" + * + * The main use case for this function is provide the proxy additional information regarding the user agent, like for example unique identifier or apple push id. + * As an example, the contact address in the SIP register sent will look like . +**/ +LINPHONE_PUBLIC void linphone_proxy_config_set_contact_uri_parameters(LinphoneProxyConfig *cfg, const char *contact_uri_params); + +/** + * @return previously set contact URI parameters. +**/ +LINPHONE_PUBLIC const char* linphone_proxy_config_get_contact_uri_parameters(const LinphoneProxyConfig *cfg); + +/** + * Get the #LinphoneCore object to which is associated the #LinphoneProxyConfig. + * @param[in] cfg #LinphoneProxyConfig object. + * @return The #LinphoneCore object to which is associated the #LinphoneProxyConfig. +**/ +LINPHONE_PUBLIC LinphoneCore * linphone_proxy_config_get_core(const LinphoneProxyConfig *cfg); + +/** + * @return whether liblinphone should replace "+" by "00" in dialed numbers (passed to + * #linphone_core_invite ). + * +**/ +LINPHONE_PUBLIC bool_t linphone_proxy_config_get_dial_escape_plus(const LinphoneProxyConfig *cfg); + +/** + * @return dialing prefix. +**/ +LINPHONE_PUBLIC const char * linphone_proxy_config_get_dial_prefix(const LinphoneProxyConfig *cfg); + +/** + * Get the reason why registration failed when the proxy config state is LinphoneRegistrationFailed. + * @param[in] cfg #LinphoneProxyConfig object. + * @return The reason why registration failed for this proxy config. +**/ +LINPHONE_PUBLIC LinphoneReason linphone_proxy_config_get_error(const LinphoneProxyConfig *cfg); + +/** + * Get detailed information why registration failed when the proxy config state is LinphoneRegistrationFailed. + * @param[in] cfg #LinphoneProxyConfig object. + * @return The details why registration failed for this proxy config. +**/ +LINPHONE_PUBLIC const LinphoneErrorInfo *linphone_proxy_config_get_error_info(const LinphoneProxyConfig *cfg); + +/** + * Get the transport from either service route, route or addr. + * @param[in] cfg #LinphoneProxyConfig object. + * @return The transport as a string (I.E udp, tcp, tls, dtls) +**/ +LINPHONE_PUBLIC const char* linphone_proxy_config_get_transport(const LinphoneProxyConfig *cfg); + +/** + * Destroys a proxy config. + * @deprecated + * + * @note: LinphoneProxyConfig that have been removed from LinphoneCore with + * linphone_core_remove_proxy_config() must not be freed. +**/ +LINPHONE_PUBLIC void linphone_proxy_config_destroy(LinphoneProxyConfig *cfg); + +LINPHONE_PUBLIC void linphone_proxy_config_set_sip_setup(LinphoneProxyConfig *cfg, const char *type); +LINPHONE_PUBLIC SipSetupContext *linphone_proxy_config_get_sip_setup_context(LinphoneProxyConfig *cfg); +LINPHONE_PUBLIC SipSetup *linphone_proxy_config_get_sip_setup(LinphoneProxyConfig *cfg); + +/** + * Detect if the given input is a phone number or not. + * @param proxy #LinphoneProxyConfig argument, unused yet but may contain useful data. Can be NULL. + * @param username string to parse. + * @return TRUE if input is a phone number, FALSE otherwise. +**/ +LINPHONE_PUBLIC bool_t linphone_proxy_config_is_phone_number(LinphoneProxyConfig *proxy, const char *username); + +/** + * Normalize a human readable phone number into a basic string. 888-444-222 becomes 888444222 + * or +33888444222 depending on the #LinphoneProxyConfig object. However this argument is OPTIONNAL + * and if not provided, a default one will be used. + * This function will always generate a normalized username; if input is not a phone number, output will be a copy of input. + * @param proxy #LinphoneProxyConfig object containing country code and/or escape symbol. If NULL passed, will use default configuration. + * @param username the string to parse + * @param result the newly normalized number + * @param result_len the size of the normalized number \a result + * @return TRUE if a phone number was recognized, FALSE otherwise. + * @deprecated use linphone_proxy_config_normalize_phone_number() + */ +LINPHONE_PUBLIC bool_t linphone_proxy_config_normalize_number(LinphoneProxyConfig *proxy, const char *username, char *result, size_t result_len); + +/** + * Normalize a human readable phone number into a basic string. 888-444-222 becomes 888444222 + * or +33888444222 depending on the #LinphoneProxyConfig object. However this argument is OPTIONNAL + * and if not provided, a default one will be used. + * This function will always generate a normalized username; if input is not a phone number, output will be a copy of input. + * @param proxy #LinphoneProxyConfig object containing country code and/or escape symbol. If NULL passed, will use default configuration. + * @param username the string to parse + * @return NULL if invalid phone number, normalized phone number from username input otherwise. +*/ +LINPHONE_PUBLIC char* linphone_proxy_config_normalize_phone_number(LinphoneProxyConfig *proxy, const char *username); + +/** + * Normalize a human readable sip uri into a fully qualified LinphoneAddress. + * A sip address should look like DisplayName \ . + * Basically this function performs the following tasks + * - if a phone number is entered, prepend country prefix and eventually escape the '+' by 00 of the proxy config. + * - if no domain part is supplied, append the domain name of the proxy config. Returns NULL if no proxy is provided at this point. + * - if no sip: is present, prepend it. + * + * The result is a syntactically correct SIP address. + * @param proxy #LinphoneProxyConfig object containing country code, escape symbol and/or domain name. Can be NULL if domain is already provided. + * @param username the string to parse + * @return NULL if invalid input, normalized sip address otherwise. +*/ +LINPHONE_PUBLIC LinphoneAddress* linphone_proxy_config_normalize_sip_uri(LinphoneProxyConfig *proxy, const char *username); + +/** + * Set default privacy policy for all calls routed through this proxy. + * @param[in] cfg #LinphoneProxyConfig object. + * @param privacy LinphonePrivacy to configure privacy + * */ +LINPHONE_PUBLIC void linphone_proxy_config_set_privacy(LinphoneProxyConfig *cfg, LinphonePrivacyMask privacy); + +/** + * Get default privacy policy for all calls routed through this proxy. + * @param[in] cfg #LinphoneProxyConfig object. + * @return Privacy mode + * */ +LINPHONE_PUBLIC LinphonePrivacyMask linphone_proxy_config_get_privacy(const LinphoneProxyConfig *cfg); + +/** + * Set the http file transfer server to be used for content type application/vnd.gsma.rcs-ft-http+xml + * @param[in] cfg #LinphoneProxyConfig object. + * @param server_url URL of the file server like https://file.linphone.org/upload.php + * */ +LINPHONE_PUBLIC void linphone_proxy_config_set_file_transfer_server(LinphoneProxyConfig *cfg, const char * server_url); + +/** + * Get the http file transfer server to be used for content type application/vnd.gsma.rcs-ft-http+xml + * @param[in] cfg #LinphoneProxyConfig object. + * @return URL of the file server like https://file.linphone.org/upload.php + * */ +LINPHONE_PUBLIC const char* linphone_proxy_config_get_file_transfer_server(const LinphoneProxyConfig *cfg); + +/** + * Indicates whether AVPF/SAVPF must be used for calls using this proxy config. + * @param[in] cfg #LinphoneProxyConfig object. + * @param[in] enable True to enable AVPF/SAVF, false to disable it. + * @deprecated use linphone_proxy_config_set_avpf_mode() + */ +LINPHONE_PUBLIC void linphone_proxy_config_enable_avpf(LinphoneProxyConfig *cfg, bool_t enable); + +/** + * Indicates whether AVPF/SAVPF is being used for calls using this proxy config. + * @param[in] cfg #LinphoneProxyConfig object. + * @return True if AVPF/SAVPF is enabled, false otherwise. + * @deprecated use linphone_proxy_config_set_avpf_mode() + */ +LINPHONE_PUBLIC bool_t linphone_proxy_config_avpf_enabled(LinphoneProxyConfig *cfg); + +/** + * Set the interval between regular RTCP reports when using AVPF/SAVPF. + * @param[in] cfg #LinphoneProxyConfig object. + * @param[in] interval The interval in seconds (between 0 and 5 seconds). + */ +LINPHONE_PUBLIC void linphone_proxy_config_set_avpf_rr_interval(LinphoneProxyConfig *cfg, uint8_t interval); + +/** + * Get the interval between regular RTCP reports when using AVPF/SAVPF. + * @param[in] cfg #LinphoneProxyConfig object. + * @return The interval in seconds. + */ +LINPHONE_PUBLIC uint8_t linphone_proxy_config_get_avpf_rr_interval(const LinphoneProxyConfig *cfg); + +/** + * Get enablement status of RTCP feedback (also known as AVPF profile). + * @param[in] cfg #LinphoneProxyConfig object. + * @return the enablement mode, which can be LinphoneAVPFDefault (use LinphoneCore's mode), LinphoneAVPFEnabled (avpf is enabled), or LinphoneAVPFDisabled (disabled). +**/ +LINPHONE_PUBLIC LinphoneAVPFMode linphone_proxy_config_get_avpf_mode(const LinphoneProxyConfig *cfg); + +/** + * Enable the use of RTCP feedback (also known as AVPF profile). + * @param[in] cfg #LinphoneProxyConfig object. + * @param[in] mode the enablement mode, which can be LinphoneAVPFDefault (use LinphoneCore's mode), LinphoneAVPFEnabled (avpf is enabled), or LinphoneAVPFDisabled (disabled). +**/ +LINPHONE_PUBLIC void linphone_proxy_config_set_avpf_mode(LinphoneProxyConfig *cfg, LinphoneAVPFMode mode); + +/** + * Obtain the value of a header sent by the server in last answer to REGISTER. + * @param[in] cfg #LinphoneProxyConfig object. + * @param header_name the header name for which to fetch corresponding value + * @return the value of the queried header. +**/ +LINPHONE_PUBLIC const char *linphone_proxy_config_get_custom_header(LinphoneProxyConfig *cfg, const char *header_name); + +/** + * Set the value of a custom header sent to the server in REGISTERs request. + * @param[in] cfg #LinphoneProxyConfig object. + * @param header_name the header name + * @param header_value the header's value +**/ +LINPHONE_PUBLIC void linphone_proxy_config_set_custom_header(LinphoneProxyConfig *cfg, const char *header_name, const char *header_value); + +/** + * Find authentication info matching proxy config, if any, similarly to linphone_core_find_auth_info. + * @param[in] cfg #LinphoneProxyConfig object. + * @return a #LinphoneAuthInfo matching proxy config criteria if possible, NULL if nothing can be found. +**/ +LINPHONE_PUBLIC const struct _LinphoneAuthInfo* linphone_proxy_config_find_auth_info(const LinphoneProxyConfig *cfg); + +/** + * @} + */ + +#endif diff --git a/coreapi/linphone_tunnel.cc b/coreapi/linphone_tunnel.cc index 7dd27d890..6cedfc2fd 100644 --- a/coreapi/linphone_tunnel.cc +++ b/coreapi/linphone_tunnel.cc @@ -162,7 +162,7 @@ static void linphone_tunnel_add_server_intern(LinphoneTunnel *tunnel, LinphoneTu linphone_tunnel_config_get_remote_udp_mirror_port(tunnel_config), linphone_tunnel_config_get_delay(tunnel_config)); } - tunnel->config_list = ms_list_append(tunnel->config_list, tunnel_config); + tunnel->config_list = ms_list_append(tunnel->config_list, linphone_tunnel_config_ref(tunnel_config)); } @@ -211,7 +211,7 @@ void linphone_tunnel_remove_server(LinphoneTunnel *tunnel, LinphoneTunnelConfig MSList *elem = ms_list_find(tunnel->config_list, tunnel_config); if(elem != NULL) { tunnel->config_list = ms_list_remove(tunnel->config_list, tunnel_config); - linphone_tunnel_config_destroy(tunnel_config); + linphone_tunnel_config_unref(tunnel_config); linphone_tunnel_refresh_config(tunnel); linphone_tunnel_save_config(tunnel); } diff --git a/coreapi/linphone_tunnel.h b/coreapi/linphone_tunnel.h index ecaaf2227..f95701b80 100644 --- a/coreapi/linphone_tunnel.h +++ b/coreapi/linphone_tunnel.h @@ -176,12 +176,40 @@ LINPHONE_PUBLIC void linphone_tunnel_config_set_delay(LinphoneTunnelConfig *tunn */ LINPHONE_PUBLIC int linphone_tunnel_config_get_delay(const LinphoneTunnelConfig *tunnel); +/** + * Increment the refcount of LinphoneTunnelConfig object. + * @param cfg the LinphoneTunnelConfig object. + * @return the same cfg object. +**/ +LINPHONE_PUBLIC LinphoneTunnelConfig * linphone_tunnel_config_ref(LinphoneTunnelConfig *cfg); + + +/** + * Decrement the refcount of LinphoneTunnelConfig object. + * @param cfg the LinphoneTunnelConfig object. +**/ +LINPHONE_PUBLIC void linphone_tunnel_config_unref(LinphoneTunnelConfig *cfg); /** * Destroy a tunnel configuration * @param tunnel LinphoneTunnelConfig object + * @deprecated use linphone_tunnel_config_unref(). */ LINPHONE_PUBLIC void linphone_tunnel_config_destroy(LinphoneTunnelConfig *tunnel); +/** + * Store a user data in the tunnel config object + * @param cfg the tunnel config + * @param ud the user data +**/ +LINPHONE_PUBLIC void linphone_tunnel_config_set_user_data(LinphoneTunnelConfig *cfg, void *ud); + +/** + * Retrieve user data from the tunnel config + * @param cfg the tunnel config + * @return the user data +**/ +LINPHONE_PUBLIC void *linphone_tunnel_config_get_user_data(LinphoneTunnelConfig *cfg); + /** * Add a tunnel server configuration. * @param tunnel LinphoneTunnel object diff --git a/coreapi/linphone_tunnel_config.c b/coreapi/linphone_tunnel_config.c index f38568016..988b114a1 100644 --- a/coreapi/linphone_tunnel_config.c +++ b/coreapi/linphone_tunnel_config.c @@ -21,18 +21,23 @@ */ #include "linphone_tunnel.h" +#include "private.h" + struct _LinphoneTunnelConfig { + belle_sip_object_t base; char *host; int port; int remote_udp_mirror_port; - int delay; + int delay; + void *user_data; }; LinphoneTunnelConfig *linphone_tunnel_config_new() { - LinphoneTunnelConfig *ltc = ms_new0(LinphoneTunnelConfig,1); + LinphoneTunnelConfig *ltc = belle_sip_object_new(LinphoneTunnelConfig); ltc->remote_udp_mirror_port = 12345; ltc->delay = 1000; + ltc->port = 443; return ltc; } @@ -74,10 +79,40 @@ int linphone_tunnel_config_get_delay(const LinphoneTunnelConfig *tunnel) { return tunnel->delay; } -void linphone_tunnel_config_destroy(LinphoneTunnelConfig *tunnel) { +static void _linphone_tunnel_config_destroy(LinphoneTunnelConfig *tunnel) { if(tunnel->host != NULL) { ms_free(tunnel->host); } - ms_free(tunnel); } +LinphoneTunnelConfig * linphone_tunnel_config_ref(LinphoneTunnelConfig *cfg){ + return (LinphoneTunnelConfig*)belle_sip_object_ref(cfg); +} + +void linphone_tunnel_config_unref(LinphoneTunnelConfig *cfg){ + belle_sip_object_unref(cfg); +} + +void linphone_tunnel_config_destroy(LinphoneTunnelConfig *tunnel){ + linphone_tunnel_config_unref(tunnel); +} + +void linphone_tunnel_config_set_user_data(LinphoneTunnelConfig *cfg, void *ud){ + cfg->user_data = ud; +} + +void *linphone_tunnel_config_get_user_data(LinphoneTunnelConfig *cfg){ + return cfg->user_data; +} + +BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneTunnelConfig); + +BELLE_SIP_INSTANCIATE_VPTR(LinphoneTunnelConfig, belle_sip_object_t, + (belle_sip_object_destroy_t)_linphone_tunnel_config_destroy, + NULL, // clone + NULL, // marshal + FALSE +); + + + diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index fa21303f6..269b71095 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -18,7 +18,7 @@ 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. */ -#ifdef WIN32 +#ifdef _WIN32 #include #endif #include "linphonecore.h" @@ -36,21 +36,28 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "mediastreamer2/msjpegwriter.h" #include "mediastreamer2/mseventqueue.h" #include "mediastreamer2/mssndcard.h" +#include "mediastreamer2/msrtt4103.h" static const char *EC_STATE_STORE = ".linphone.ecstate"; #define EC_STATE_MAX_LEN 1048576 // 1Mo static void linphone_call_stats_uninit(LinphoneCallStats *stats); static void linphone_call_get_local_ip(LinphoneCall *call, const LinphoneAddress *remote_addr); +static void _linphone_call_set_next_video_frame_decoded_trigger(LinphoneCall *call); +void linphone_call_handle_stream_events(LinphoneCall *call, int stream_index); + -#ifdef VIDEO_ENABLED MSWebCam *get_nowebcam_device(){ +#ifdef VIDEO_ENABLED return ms_web_cam_manager_get_cam(ms_web_cam_manager_get(),"StaticImage: Static picture"); -} +#else + return NULL; #endif +} -static bool_t generate_b64_crypto_key(int key_length, char* key_out, size_t key_out_size) { - int b64_size; + +static bool_t generate_b64_crypto_key(size_t key_length, char* key_out, size_t key_out_size) { + size_t b64_size; uint8_t* tmp = (uint8_t*) ms_malloc0(key_length); if (sal_get_random_bytes(tmp, key_length)==NULL) { ms_error("Failed to generate random key"); @@ -100,20 +107,30 @@ bool_t linphone_call_get_authentication_token_verified(LinphoneCall *call){ return call->auth_token_verified; } +static bool_t at_least_one_stream_started(const LinphoneCall *call){ + return (call->audiostream && media_stream_get_state((MediaStream *)call->audiostream) == MSStreamStarted ) + || (call->videostream && media_stream_get_state((MediaStream *)call->videostream) == MSStreamStarted) + || (call->textstream && media_stream_get_state((MediaStream *)call->textstream) == MSStreamStarted); +} + static bool_t linphone_call_all_streams_encrypted(const LinphoneCall *call) { int number_of_encrypted_stream = 0; int number_of_active_stream = 0; - if (call) { - if (call->audiostream && media_stream_get_state((MediaStream *)call->audiostream) == MSStreamStarted) { - number_of_active_stream++; - if(media_stream_secured((MediaStream *)call->audiostream)) - number_of_encrypted_stream++; - } - if (call->videostream && media_stream_get_state((MediaStream *)call->videostream) == MSStreamStarted) { - number_of_active_stream++; - if (media_stream_secured((MediaStream *)call->videostream)) - number_of_encrypted_stream++; - } + + if (call->audiostream && media_stream_get_state((MediaStream *)call->audiostream) == MSStreamStarted) { + number_of_active_stream++; + if(media_stream_secured((MediaStream *)call->audiostream)) + number_of_encrypted_stream++; + } + if (call->videostream && media_stream_get_state((MediaStream *)call->videostream) == MSStreamStarted) { + number_of_active_stream++; + if (media_stream_secured((MediaStream *)call->videostream)) + number_of_encrypted_stream++; + } + if (call->textstream && media_stream_get_state((MediaStream *)call->textstream) == MSStreamStarted) { + number_of_active_stream++; + if (media_stream_secured((MediaStream *)call->textstream)) + number_of_encrypted_stream++; } return number_of_active_stream>0 && number_of_active_stream==number_of_encrypted_stream; } @@ -281,6 +298,8 @@ bool_t is_payload_type_number_available(const MSList *l, int number, const Paylo static void linphone_core_assign_payload_type_numbers(LinphoneCore *lc, MSList *codecs){ MSList *elem; int dyn_number=lc->codecs_conf.dyn_pt; + PayloadType *red = NULL, *t140 = NULL; + for (elem=codecs; elem!=NULL; elem=elem->next){ PayloadType *pt=(PayloadType*)elem->data; int number=payload_type_get_number(pt); @@ -307,6 +326,18 @@ static void linphone_core_assign_payload_type_numbers(LinphoneCore *lc, MSList * payload_type_set_enable(pt, FALSE); } } + + if (strcmp(pt->mime_type, payload_type_t140_red.mime_type) == 0) { + red = pt; + } else if (strcmp(pt->mime_type, payload_type_t140.mime_type) == 0) { + t140 = pt; + } + } + + if (t140 && red) { + int t140_payload_type_number = payload_type_get_number(t140); + const char *red_fmtp = ms_strdup_printf("%i/%i/%i", t140_payload_type_number, t140_payload_type_number, t140_payload_type_number); + payload_type_set_recv_fmtp(red, red_fmtp); } } @@ -366,8 +397,9 @@ static MSList *make_codec_list(LinphoneCore *lc, CodecConstraints * hints, SalSt PayloadType *pt=(PayloadType*)it->data; int num; - if (!(pt->flags & PAYLOAD_TYPE_ENABLED)) + if (!payload_type_enabled(pt)) { continue; + } if (hints->bandwidth_limit>0 && !linphone_core_is_payload_type_usable_for_bandwidth(lc,pt,hints->bandwidth_limit)){ ms_message("Codec %s/%i eliminated because of audio bandwidth constraint of %i kbit/s", pt->mime_type,pt->clock_rate,hints->bandwidth_limit); @@ -397,26 +429,28 @@ static MSList *make_codec_list(LinphoneCore *lc, CodecConstraints * hints, SalSt return l; } -static void update_media_description_from_stun(SalMediaDescription *md, const StunCandidate *ac, const StunCandidate *vc){ +static void update_media_description_from_stun(SalMediaDescription *md, const StunCandidate *ac, const StunCandidate *vc, const StunCandidate *tc){ int i; - for (i = 0; i < md->nb_streams; i++) { + for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) { if (!sal_stream_description_active(&md->streams[i])) continue; if ((md->streams[i].type == SalAudio) && (ac->port != 0)) { - strcpy(md->streams[0].rtp_addr,ac->addr); - md->streams[0].rtp_port=ac->port; + strcpy(md->streams[i].rtp_addr,ac->addr); + md->streams[i].rtp_port=ac->port; if ((ac->addr[0]!='\0' && vc->addr[0]!='\0' && strcmp(ac->addr,vc->addr)==0) || sal_media_description_get_nb_active_streams(md)==1){ strcpy(md->addr,ac->addr); } - } - if ((md->streams[i].type == SalVideo) && (vc->port != 0)) { - strcpy(md->streams[1].rtp_addr,vc->addr); - md->streams[1].rtp_port=vc->port; + } else if ((md->streams[i].type == SalVideo) && (vc->port != 0)) { + strcpy(md->streams[i].rtp_addr,vc->addr); + md->streams[i].rtp_port=vc->port; + } else if ((md->streams[i].type == SalText) && (tc->port != 0)) { + strcpy(md->streams[i].rtp_addr,tc->addr); + md->streams[i].rtp_port=tc->port; } } } static int setup_encryption_key(SalSrtpCryptoAlgo *crypto, MSCryptoSuite suite, unsigned int tag){ - int keylen=0; + size_t keylen=0; crypto->tag=tag; crypto->algo=suite; switch(suite){ @@ -433,7 +467,7 @@ static int setup_encryption_key(SalSrtpCryptoAlgo *crypto, MSCryptoSuite suite, case MS_CRYPTO_SUITE_INVALID: break; } - if (keylen==0 || !generate_b64_crypto_key(30, crypto->master_key, SAL_SRTP_KEY_SIZE)){ + if (keylen==0 || !generate_b64_crypto_key(keylen, crypto->master_key, SAL_SRTP_KEY_SIZE)){ ms_error("Could not generate SRTP key."); crypto->algo = 0; return -1; @@ -442,7 +476,7 @@ static int setup_encryption_key(SalSrtpCryptoAlgo *crypto, MSCryptoSuite suite, } static void setup_dtls_keys(LinphoneCall *call, SalMediaDescription *md){ int i; - for(i=0; inb_streams; i++) { + for(i=0; istreams[i])) continue; /* if media encryption is set to DTLS check presence of fingerprint in the call which shall have been set at stream init but it may have failed when retrieving certificate resulting in no fingerprint present and then DTLS not usable */ if (sal_stream_description_has_dtls(&md->streams[i]) == TRUE) { @@ -462,7 +496,7 @@ static void setup_encryption_keys(LinphoneCall *call, SalMediaDescription *md){ SalMediaDescription *old_md=call->localdesc; bool_t keep_srtp_keys=lp_config_get_int(lc->config,"sip","keep_srtp_keys",1); - for(i=0; inb_streams; i++) { + for(i=0; istreams[i])) continue; if (sal_stream_description_has_srtp(&md->streams[i]) == TRUE) { if (keep_srtp_keys && old_md && (sal_stream_description_active(&old_md->streams[i]) == TRUE) && (sal_stream_description_has_srtp(&old_md->streams[i]) == TRUE)) { @@ -485,10 +519,13 @@ static void setup_rtcp_fb(LinphoneCall *call, SalMediaDescription *md) { MSList *pt_it; PayloadType *pt; PayloadTypeAvpfParams avpf_params; + LinphoneCore *lc = call->core; int i; - for (i = 0; i < md->nb_streams; i++) { + for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) { if (!sal_stream_description_active(&md->streams[i])) continue; + md->streams[i].rtcp_fb.generic_nack_enabled = lp_config_get_int(lc->config, "rtp", "rtcp_fb_generic_nack_enabled", 0); + md->streams[i].rtcp_fb.tmmbr_enabled = lp_config_get_int(lc->config, "rtp", "rtcp_fb_tmmbr_enabled", 0); for (pt_it = md->streams[i].payloads; pt_it != NULL; pt_it = pt_it->next) { pt = (PayloadType *)pt_it->data; if (call->params->avpf_enabled == TRUE) { @@ -523,7 +560,7 @@ static void setup_rtcp_xr(LinphoneCall *call, SalMediaDescription *md) { } md->rtcp_xr.voip_metrics_enabled = lp_config_get_int(lc->config, "rtp", "rtcp_xr_voip_metrics_enabled", 1); } - for (i = 0; i < md->nb_streams; i++) { + for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) { if (!sal_stream_description_active(&md->streams[i])) continue; memcpy(&md->streams[i].rtcp_xr, &md->rtcp_xr, sizeof(md->streams[i].rtcp_xr)); } @@ -549,7 +586,7 @@ void linphone_call_update_local_media_description_from_ice_or_upnp(LinphoneCall static void transfer_already_assigned_payload_types(SalMediaDescription *old, SalMediaDescription *md){ int i; - for(i=0;inb_streams;++i){ + for(i=0;istreams[i].already_assigned_payloads=old->streams[i].already_assigned_payloads; old->streams[i].already_assigned_payloads=NULL; } @@ -575,41 +612,76 @@ static const char *linphone_call_get_public_ip_for_stream(LinphoneCall *call, in return public_ip; } -void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *call) { - linphone_call_make_local_media_description_with_params(lc, call, call->params); +void linphone_call_update_biggest_desc(LinphoneCall *call, SalMediaDescription *md){ + if (call->biggestdesc==NULL || md->nb_streams>call->biggestdesc->nb_streams){ + /*we have been offered and now are ready to proceed, or we added a new stream*/ + /*store the media description to remember the mapping of calls*/ + if (call->biggestdesc){ + sal_media_description_unref(call->biggestdesc); + call->biggestdesc=NULL; + } + call->biggestdesc=sal_media_description_ref(md); + } } -void linphone_call_make_local_media_description_with_params(LinphoneCore *lc, LinphoneCall *call, LinphoneCallParams *params) { +static void force_streams_dir_according_to_state(LinphoneCall *call, SalMediaDescription *md){ + int i; + + switch (call->state){ + case LinphoneCallPausing: + case LinphoneCallPaused: + break; + default: + return; + break; + } + + for (i=0; istreams[i]; + if (sd->dir != SalStreamInactive) { + sd->dir = SalStreamSendOnly; + if (sd->type == SalVideo){ + if (lp_config_get_int(call->core->config, "sip", "inactive_video_on_pause", 0)) { + sd->dir = SalStreamInactive; + } + } + } + } +} + +void linphone_call_make_local_media_description(LinphoneCall *call) { MSList *l; SalMediaDescription *old_md=call->localdesc; int i; - int nb_active_streams = 0; - const char *me; + int max_index = 0; SalMediaDescription *md=sal_media_description_new(); LinphoneAddress *addr; const char *subject; CodecConstraints codec_hints={0}; + LinphoneCallParams *params = call->params; + LinphoneCore *lc = call->core; + bool_t rtcp_mux = lp_config_get_int(lc->config, "rtp", "rtcp_mux", 0); /*multicast is only set in case of outgoing call*/ if (call->dir == LinphoneCallOutgoing && linphone_call_params_audio_multicast_enabled(params)) { - md->streams[0].ttl=linphone_core_get_audio_multicast_ttl(lc); - md->streams[0].multicast_role = SalMulticastSender; + md->streams[call->main_audio_stream_index].ttl=linphone_core_get_audio_multicast_ttl(lc); + md->streams[call->main_audio_stream_index].multicast_role = SalMulticastSender; } if (call->dir == LinphoneCallOutgoing && linphone_call_params_video_multicast_enabled(params)) { - md->streams[1].ttl=linphone_core_get_video_multicast_ttl(lc); - md->streams[1].multicast_role = SalMulticastSender; + md->streams[call->main_video_stream_index].ttl=linphone_core_get_video_multicast_ttl(lc); + md->streams[call->main_video_stream_index].multicast_role = SalMulticastSender; } subject=linphone_call_params_get_session_name(params); linphone_core_adapt_to_network(lc,call->ping_time,params); - if (call->dest_proxy) - me=linphone_proxy_config_get_identity(call->dest_proxy); - else - me=linphone_core_get_identity(lc); - addr=linphone_address_new(me); + if (call->dest_proxy) { + addr=linphone_address_clone(linphone_proxy_config_get_identity_address(call->dest_proxy)); + } else { + addr=linphone_address_new(linphone_core_get_identity(lc)); + } md->session_id=(old_md ? old_md->session_id : (rand() & 0xfff)); md->session_ver=(old_md ? (old_md->session_ver+1) : (rand() & 0xfff)); @@ -626,84 +698,132 @@ void linphone_call_make_local_media_description_with_params(LinphoneCore *lc, Li md->bandwidth=params->down_bw; else md->bandwidth=linphone_core_get_download_bandwidth(lc); - /*set audio capabilities */ - strncpy(md->streams[0].rtp_addr,linphone_call_get_public_ip_for_stream(call,0),sizeof(md->streams[0].rtp_addr)); - strncpy(md->streams[0].rtcp_addr,linphone_call_get_public_ip_for_stream(call,0),sizeof(md->streams[0].rtcp_addr)); - strncpy(md->streams[0].name,"Audio",sizeof(md->streams[0].name)-1); - md->streams[0].rtp_port=call->media_ports[0].rtp_port; - md->streams[0].rtcp_port=call->media_ports[0].rtcp_port; - md->streams[0].proto=get_proto_from_call_params(params); - md->streams[0].dir=get_audio_dir_from_call_params(params); - md->streams[0].type=SalAudio; - if (params->down_ptime) - md->streams[0].ptime=params->down_ptime; - else - md->streams[0].ptime=linphone_core_get_download_ptime(lc); - codec_hints.bandwidth_limit=params->audio_bw; - codec_hints.max_codecs=-1; - codec_hints.previously_used=old_md ? old_md->streams[0].already_assigned_payloads : NULL; - l=make_codec_list(lc, &codec_hints, SalAudio, lc->codecs_conf.audio_codecs); - md->streams[0].max_rate=get_max_codec_sample_rate(l); - md->streams[0].payloads=l; - if (call->audiostream && call->audiostream->ms.sessions.rtp_session) { - char* me = linphone_address_as_string_uri_only(call->me); - md->streams[0].rtp_ssrc=rtp_session_get_send_ssrc(call->audiostream->ms.sessions.rtp_session); - strncpy(md->streams[0].rtcp_cname,me,sizeof(md->streams[0].rtcp_cname)); - ms_free(me); - } - else - ms_warning("Cannot get audio local ssrc for call [%p]",call); - nb_active_streams++; + if (params->custom_sdp_attributes) + md->custom_sdp_attributes = sal_custom_sdp_attribute_clone(params->custom_sdp_attributes); - if (params->has_video && (!params->internal_call_update || !call->current_params->video_declined)){ - strncpy(md->streams[1].rtp_addr,linphone_call_get_public_ip_for_stream(call,1),sizeof(md->streams[1].rtp_addr)); - strncpy(md->streams[1].rtcp_addr,linphone_call_get_public_ip_for_stream(call,1),sizeof(md->streams[1].rtcp_addr)); - strncpy(md->streams[1].name,"Video",sizeof(md->streams[1].name)-1); - md->streams[1].rtp_port=call->media_ports[1].rtp_port; - md->streams[1].rtcp_port=call->media_ports[1].rtcp_port; - md->streams[1].proto=md->streams[0].proto; - md->streams[1].dir=get_video_dir_from_call_params(params); - md->streams[1].type=SalVideo; + /*set audio capabilities */ + if (params->has_audio) { + strncpy(md->streams[call->main_audio_stream_index].rtp_addr,linphone_call_get_public_ip_for_stream(call,call->main_audio_stream_index),sizeof(md->streams[call->main_audio_stream_index].rtp_addr)); + strncpy(md->streams[call->main_audio_stream_index].rtcp_addr,linphone_call_get_public_ip_for_stream(call,call->main_audio_stream_index),sizeof(md->streams[call->main_audio_stream_index].rtcp_addr)); + strncpy(md->streams[call->main_audio_stream_index].name,"Audio",sizeof(md->streams[call->main_audio_stream_index].name)-1); + md->streams[call->main_audio_stream_index].rtp_port=call->media_ports[call->main_audio_stream_index].rtp_port; + md->streams[call->main_audio_stream_index].rtcp_port=call->media_ports[call->main_audio_stream_index].rtcp_port; + md->streams[call->main_audio_stream_index].proto=get_proto_from_call_params(params); + md->streams[call->main_audio_stream_index].dir=get_audio_dir_from_call_params(params); + md->streams[call->main_audio_stream_index].type=SalAudio; + md->streams[call->main_audio_stream_index].rtcp_mux = rtcp_mux; + if (params->down_ptime) + md->streams[call->main_audio_stream_index].ptime=params->down_ptime; + else + md->streams[call->main_audio_stream_index].ptime=linphone_core_get_download_ptime(lc); + codec_hints.bandwidth_limit=params->audio_bw; + codec_hints.max_codecs=-1; + codec_hints.previously_used=old_md ? old_md->streams[call->main_audio_stream_index].already_assigned_payloads : NULL; + l=make_codec_list(lc, &codec_hints, SalAudio, lc->codecs_conf.audio_codecs); + md->streams[call->main_audio_stream_index].max_rate=get_max_codec_sample_rate(l); + md->streams[call->main_audio_stream_index].payloads=l; + if (call->audiostream && call->audiostream->ms.sessions.rtp_session) { + char* me = linphone_address_as_string_uri_only(call->me); + md->streams[call->main_audio_stream_index].rtp_ssrc=rtp_session_get_send_ssrc(call->audiostream->ms.sessions.rtp_session); + strncpy(md->streams[call->main_audio_stream_index].rtcp_cname,me,sizeof(md->streams[call->main_audio_stream_index].rtcp_cname)); + ms_free(me); + } + else + ms_warning("Cannot get audio local ssrc for call [%p]",call); + if (call->main_audio_stream_index > max_index) + max_index = call->main_audio_stream_index; + } else { + ms_message("Don't put audio stream on local offer for call [%p]",call); + md->streams[call->main_audio_stream_index].dir = SalStreamInactive; + } + if (params->custom_sdp_media_attributes[LinphoneStreamTypeAudio]) + md->streams[call->main_audio_stream_index].custom_sdp_attributes = sal_custom_sdp_attribute_clone(params->custom_sdp_media_attributes[LinphoneStreamTypeAudio]); + + md->streams[call->main_video_stream_index].proto=md->streams[call->main_audio_stream_index].proto; + md->streams[call->main_video_stream_index].dir=get_video_dir_from_call_params(params); + md->streams[call->main_video_stream_index].type=SalVideo; + md->streams[call->main_video_stream_index].rtcp_mux = rtcp_mux; + strncpy(md->streams[call->main_video_stream_index].name,"Video",sizeof(md->streams[call->main_video_stream_index].name)-1); + + if (params->has_video){ + strncpy(md->streams[call->main_video_stream_index].rtp_addr,linphone_call_get_public_ip_for_stream(call,call->main_video_stream_index),sizeof(md->streams[call->main_video_stream_index].rtp_addr)); + strncpy(md->streams[call->main_video_stream_index].rtcp_addr,linphone_call_get_public_ip_for_stream(call,call->main_video_stream_index),sizeof(md->streams[call->main_video_stream_index].rtcp_addr)); + md->streams[call->main_video_stream_index].rtp_port=call->media_ports[call->main_video_stream_index].rtp_port; + md->streams[call->main_video_stream_index].rtcp_port=call->media_ports[call->main_video_stream_index].rtcp_port; codec_hints.bandwidth_limit=0; codec_hints.max_codecs=-1; - codec_hints.previously_used=old_md ? old_md->streams[1].already_assigned_payloads : NULL; + codec_hints.previously_used=old_md ? old_md->streams[call->main_video_stream_index].already_assigned_payloads : NULL; l=make_codec_list(lc, &codec_hints, SalVideo, lc->codecs_conf.video_codecs); - md->streams[1].payloads=l; + md->streams[call->main_video_stream_index].payloads=l; if (call->videostream && call->videostream->ms.sessions.rtp_session) { char* me = linphone_address_as_string_uri_only(call->me); - md->streams[1].rtp_ssrc=rtp_session_get_send_ssrc(call->videostream->ms.sessions.rtp_session); - strncpy(md->streams[1].rtcp_cname,me,sizeof(md->streams[1].rtcp_cname)); + md->streams[call->main_video_stream_index].rtp_ssrc=rtp_session_get_send_ssrc(call->videostream->ms.sessions.rtp_session); + strncpy(md->streams[call->main_video_stream_index].rtcp_cname,me,sizeof(md->streams[call->main_video_stream_index].rtcp_cname)); ms_free(me); } else ms_warning("Cannot get video local ssrc for call [%p]",call); - nb_active_streams++; + if (call->main_video_stream_index > max_index) + max_index = call->main_video_stream_index; } else { ms_message("Don't put video stream on local offer for call [%p]",call); + md->streams[call->main_video_stream_index].dir = SalStreamInactive; } + if (params->custom_sdp_media_attributes[LinphoneStreamTypeVideo]) + md->streams[call->main_video_stream_index].custom_sdp_attributes = sal_custom_sdp_attribute_clone(params->custom_sdp_media_attributes[LinphoneStreamTypeVideo]); - if (md->nb_streams < nb_active_streams) - md->nb_streams = nb_active_streams; + md->streams[call->main_text_stream_index].proto=md->streams[call->main_audio_stream_index].proto; + md->streams[call->main_text_stream_index].dir=SalStreamSendRecv; + md->streams[call->main_text_stream_index].type=SalText; + md->streams[call->main_text_stream_index].rtcp_mux = rtcp_mux; + strncpy(md->streams[call->main_text_stream_index].name,"Text",sizeof(md->streams[call->main_text_stream_index].name)-1); + if (params->realtimetext_enabled) { + strncpy(md->streams[call->main_text_stream_index].rtp_addr,linphone_call_get_public_ip_for_stream(call,call->main_text_stream_index),sizeof(md->streams[call->main_text_stream_index].rtp_addr)); + strncpy(md->streams[call->main_text_stream_index].rtcp_addr,linphone_call_get_public_ip_for_stream(call,call->main_text_stream_index),sizeof(md->streams[call->main_text_stream_index].rtcp_addr)); + + md->streams[call->main_text_stream_index].rtp_port=call->media_ports[call->main_text_stream_index].rtp_port; + md->streams[call->main_text_stream_index].rtcp_port=call->media_ports[call->main_text_stream_index].rtcp_port; - /* Deactivate inactive streams. */ - for (i = nb_active_streams; i < md->nb_streams; i++) { - md->streams[i].rtp_port = 0; - md->streams[i].rtcp_port = 0; - md->streams[i].proto = call->biggestdesc->streams[i].proto; - md->streams[i].type = call->biggestdesc->streams[i].type; - md->streams[i].dir = SalStreamInactive; codec_hints.bandwidth_limit=0; - codec_hints.max_codecs=1; - codec_hints.previously_used=NULL; - l = make_codec_list(lc, &codec_hints, SalVideo, lc->codecs_conf.video_codecs); - md->streams[i].payloads = l; + codec_hints.max_codecs=-1; + codec_hints.previously_used=old_md ? old_md->streams[call->main_text_stream_index].already_assigned_payloads : NULL; + l=make_codec_list(lc, &codec_hints, SalText, lc->codecs_conf.text_codecs); + md->streams[call->main_text_stream_index].payloads=l; + if (call->textstream && call->textstream->ms.sessions.rtp_session) { + char* me = linphone_address_as_string_uri_only(call->me); + md->streams[call->main_text_stream_index].rtp_ssrc=rtp_session_get_send_ssrc(call->textstream->ms.sessions.rtp_session); + strncpy(md->streams[call->main_text_stream_index].rtcp_cname,me,sizeof(md->streams[call->main_text_stream_index].rtcp_cname)); + ms_free(me); + } + else + ms_warning("Cannot get text local ssrc for call [%p]",call); + if (call->main_text_stream_index > max_index) + max_index = call->main_text_stream_index; + } else { + ms_message("Don't put text stream on local offer for call [%p]",call); + md->streams[call->main_text_stream_index].dir = SalStreamInactive; + } + if (params->custom_sdp_media_attributes[LinphoneStreamTypeText]) + md->streams[call->main_text_stream_index].custom_sdp_attributes = sal_custom_sdp_attribute_clone(params->custom_sdp_media_attributes[LinphoneStreamTypeText]); + + md->nb_streams = MAX(md->nb_streams,max_index+1); + + /* Deactivate unused streams. */ + for (i = md->nb_streams; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) { + if (md->streams[i].rtp_port == 0) { + md->streams[i].dir = SalStreamInactive; + if (call->biggestdesc && i < call->biggestdesc->nb_streams) { + md->streams[i].proto = call->biggestdesc->streams[i].proto; + md->streams[i].type = call->biggestdesc->streams[i].type; + } + } } setup_encryption_keys(call,md); setup_dtls_keys(call,md); setup_rtcp_fb(call, md); setup_rtcp_xr(call, md); - update_media_description_from_stun(md,&call->ac,&call->vc); + update_media_description_from_stun(md, &call->ac, &call->vc, &call->tc); call->localdesc=md; linphone_call_update_local_media_description_from_ice_or_upnp(call); linphone_address_destroy(addr); @@ -712,6 +832,7 @@ void linphone_call_make_local_media_description_with_params(LinphoneCore *lc, Li call->localdesc_changed=sal_media_description_equals(md,old_md); sal_media_description_unref(old_md); } + force_streams_dir_according_to_state(call, md); } static int find_port_offset(LinphoneCore *lc, int stream_index, int base_port){ @@ -748,7 +869,7 @@ static int select_random_port(LinphoneCore *lc, int stream_index, int min_port, int existing_port = 0; bool_t already_used = FALSE; - tried_port = (rand() % (max_port - min_port) + min_port) & ~0x1; + tried_port = (ortp_random() % (max_port - min_port) + min_port) & ~0x1; if (tried_port < min_port) tried_port = min_port + 2; for (nb_tries = 0; nb_tries < 100; nb_tries++) { for (elem = lc->calls; elem != NULL; elem = elem->next) { @@ -795,6 +916,9 @@ static void port_config_set(LinphoneCall *call, int stream_index, int min_port, static void linphone_call_init_common(LinphoneCall *call, LinphoneAddress *from, LinphoneAddress *to){ int min_port, max_port; ms_message("New LinphoneCall [%p] initialized (LinphoneCore version: %s)",call,linphone_core_get_version()); + call->main_audio_stream_index = LINPHONE_CALL_STATS_AUDIO; + call->main_video_stream_index = LINPHONE_CALL_STATS_VIDEO; + call->main_text_stream_index = LINPHONE_CALL_STATS_TEXT; call->state=LinphoneCallIdle; call->transfer_state = LinphoneCallIdle; call->log=linphone_call_log_new(call->dir, from, to); @@ -809,16 +933,17 @@ static void linphone_call_init_common(LinphoneCall *call, LinphoneAddress *from, linphone_address_ref(call->me); linphone_core_get_audio_port_range(call->core, &min_port, &max_port); - port_config_set(call,0,min_port,max_port); + port_config_set(call,call->main_audio_stream_index,min_port,max_port); linphone_core_get_video_port_range(call->core, &min_port, &max_port); - port_config_set(call,1,min_port,max_port); + port_config_set(call,call->main_video_stream_index,min_port,max_port); + + linphone_core_get_text_port_range(call->core, &min_port, &max_port); + port_config_set(call,call->main_text_stream_index,min_port,max_port); 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); -#ifdef VIDEO_ENABLED - call->cam = call->core->video_conf.device; -#endif + linphone_call_init_stats(&call->stats[LINPHONE_CALL_STATS_TEXT], LINPHONE_CALL_STATS_TEXT); } void linphone_call_init_stats(LinphoneCallStats *stats, int type) { @@ -935,17 +1060,18 @@ BELLE_SIP_INSTANCIATE_VPTR(LinphoneCall, belle_sip_object_t, ); void linphone_call_fill_media_multicast_addr(LinphoneCall *call) { if (linphone_call_params_audio_multicast_enabled(call->params)){ - strncpy(call->media_ports[0].multicast_ip, - linphone_core_get_audio_multicast_addr(call->core), sizeof(call->media_ports[0].multicast_ip)); + strncpy(call->media_ports[call->main_audio_stream_index].multicast_ip, + linphone_core_get_audio_multicast_addr(call->core), sizeof(call->media_ports[call->main_audio_stream_index].multicast_ip)); } else - call->media_ports[0].multicast_ip[0]='\0'; + call->media_ports[call->main_audio_stream_index].multicast_ip[0]='\0'; if (linphone_call_params_video_multicast_enabled(call->params)){ - strncpy(call->media_ports[1].multicast_ip, - linphone_core_get_video_multicast_addr(call->core), sizeof(call->media_ports[1].multicast_ip)); + strncpy(call->media_ports[call->main_video_stream_index].multicast_ip, + linphone_core_get_video_multicast_addr(call->core), sizeof(call->media_ports[call->main_video_stream_index].multicast_ip)); } else - call->media_ports[1].multicast_ip[0]='\0'; + call->media_ports[call->main_video_stream_index].multicast_ip[0]='\0'; } + LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, const LinphoneCallParams *params, LinphoneProxyConfig *cfg){ LinphoneCall *call = belle_sip_object_new(LinphoneCall); @@ -953,8 +1079,8 @@ LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddr call->core=lc; linphone_call_outgoing_select_ip_version(call,to,cfg); linphone_call_get_local_ip(call, to); - linphone_call_init_common(call,from,to); call->params = linphone_call_params_copy(params); + linphone_call_init_common(call, from, to); linphone_call_fill_media_multicast_addr(call); @@ -993,7 +1119,7 @@ static void linphone_call_incoming_select_ip_version(LinphoneCall *call){ /** * Fix call parameters on incoming call to eg. enable AVPF if the incoming call propose it and it is not enabled locally. */ -void linphone_call_set_compatible_incoming_call_parameters(LinphoneCall *call, const SalMediaDescription *md) { +void linphone_call_set_compatible_incoming_call_parameters(LinphoneCall *call, SalMediaDescription *md) { /* Handle AVPF, SRTP and DTLS. */ call->params->avpf_enabled = sal_media_description_has_avpf(md); if (call->params->avpf_enabled == TRUE) { @@ -1010,7 +1136,106 @@ void linphone_call_set_compatible_incoming_call_parameters(LinphoneCall *call, c }else if (call->params->media_encryption != LinphoneMediaEncryptionZRTP){ call->params->media_encryption = LinphoneMediaEncryptionNone; } + linphone_call_fix_call_parameters(call, md); +} +static void linphone_call_compute_streams_indexes(LinphoneCall *call, const SalMediaDescription *md) { + int i, j; + bool_t audio_found = FALSE, video_found = FALSE, text_found = FALSE; + + for (i = 0; i < md->nb_streams; i++) { + if (md->streams[i].type == SalAudio) { + if (!audio_found) { + call->main_audio_stream_index = i; + audio_found = TRUE; + ms_message("audio stream index found: %i, updating main audio stream index", i); + } else { + ms_message("audio stream index found: %i, but main audio stream already set to %i", i, call->main_audio_stream_index); + } + + // Check that the default value of a another stream doesn't match the new one + if (i == call->main_video_stream_index) { + for (j = 0; j < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; j++) { + if (sal_stream_description_active(&md->streams[j])) continue; + if (j != call->main_video_stream_index && j != call->main_text_stream_index) { + ms_message("%i was used for video stream ; now using %i", i, j); + call->main_video_stream_index = j; + break; + } + } + } + if (i == call->main_text_stream_index) { + for (j = 0; j < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; j++) { + if (sal_stream_description_active(&md->streams[j])) continue; + if (j != call->main_video_stream_index && j != call->main_text_stream_index) { + ms_message("%i was used for text stream ; now using %i", i, j); + call->main_text_stream_index = j; + break; + } + } + } + } else if (md->streams[i].type == SalVideo) { + if (!video_found) { + call->main_video_stream_index = i; + video_found = TRUE; + ms_message("video stream index found: %i, updating main video stream index", i); + } else { + ms_message("video stream index found: %i, but main video stream already set to %i", i, call->main_video_stream_index); + } + + // Check that the default value of a another stream doesn't match the new one + if (i == call->main_audio_stream_index) { + for (j = 0; j < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; j++) { + if (sal_stream_description_active(&md->streams[j])) continue; + if (j != call->main_audio_stream_index && j != call->main_text_stream_index) { + ms_message("%i was used for audio stream ; now using %i", i, j); + call->main_audio_stream_index = j; + break; + } + } + } + if (i == call->main_text_stream_index) { + for (j = 0; j < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; j++) { + if (sal_stream_description_active(&md->streams[j])) continue; + if (j != call->main_audio_stream_index && j != call->main_text_stream_index) { + ms_message("%i was used for text stream ; now using %i", i, j); + call->main_text_stream_index = j; + break; + } + } + } + } else if (md->streams[i].type == SalText) { + if (!text_found) { + call->main_text_stream_index = i; + text_found = TRUE; + ms_message("text stream index found: %i, updating main text stream index", i); + } else { + ms_message("text stream index found: %i, but main text stream already set to %i", i, call->main_text_stream_index); + } + + // Check that the default value of a another stream doesn't match the new one + if (i == call->main_audio_stream_index) { + for (j = 0; j < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; j++) { + if (sal_stream_description_active(&md->streams[j])) continue; + if (j != call->main_video_stream_index && j != call->main_audio_stream_index) { + ms_message("%i was used for audio stream ; now using %i", i, j); + call->main_audio_stream_index = j; + break; + } + } + } + if (i == call->main_video_stream_index) { + for (j = 0; j < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; j++) { + if (sal_stream_description_active(&md->streams[j])) continue; + if (j != call->main_video_stream_index && j != call->main_audio_stream_index) { + ms_message("%i was used for video stream ; now using %i", i, j); + call->main_video_stream_index = j; + break; + } + } + } + } + } } LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, SalOp *op){ @@ -1028,6 +1253,8 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro sal_op_cnx_ip_to_0000_if_sendonly_enable(op,lp_config_get_default_int(lc->config,"sip","cnx_ip_to_0000_if_sendonly_enabled",0)); + md = sal_call_get_remote_media_description(op); + if (lc->sip_conf.ping_with_options){ #ifdef BUILD_UPNP if (lc->upnp != NULL && linphone_core_get_firewall_policy(lc)==LinphonePolicyUseUpnp && @@ -1050,8 +1277,8 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro linphone_address_clean(from); linphone_call_get_local_ip(call, from); - linphone_call_init_common(call, from, to); call->params = linphone_call_params_new(); + linphone_call_init_common(call, from, to); call->log->call_id=ms_strdup(sal_op_get_call_id(op)); /*must be known at that time*/ call->dest_proxy = linphone_core_lookup_known_proxy(call->core, to); linphone_core_init_default_params(lc, call->params); @@ -1063,17 +1290,22 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro /*set privacy*/ call->current_params->privacy=(LinphonePrivacyMask)sal_op_get_privacy(call->op); /*set video support */ - md=sal_call_get_remote_media_description(op); call->params->has_video = linphone_core_video_enabled(lc) && lc->video_policy.automatically_accept; if (md) { // It is licit to receive an INVITE without SDP // In this case WE chose the media parameters according to policy. linphone_call_set_compatible_incoming_call_parameters(call, md); - /* set multicast role & address if any*/ - for (i=0;inb_streams;i++){ - if (!sal_call_is_offerer(op) && ms_is_multicast(md->streams[i].rtp_addr)){ - md->streams[i].multicast_role = SalMulticastReceiver; - strncpy(call->media_ports[i].multicast_ip,md->streams[i].rtp_addr,sizeof(call->media_ports[i].multicast_ip)); + /* set multicast role & address if any*/ + if (!sal_call_is_offerer(op)){ + for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) { + if (md->streams[i].dir == SalStreamInactive) { + continue; + } + + if (md->streams[i].rtp_addr[0]!='\0' && ms_is_multicast(md->streams[i].rtp_addr)){ + md->streams[i].multicast_role = SalMulticastReceiver; + strncpy(call->media_ports[i].multicast_ip,md->streams[i].rtp_addr,sizeof(call->media_ports[i].multicast_ip)); + } } } } @@ -1131,12 +1363,14 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro */ void linphone_call_free_media_resources(LinphoneCall *call){ linphone_call_stop_media_streams(call); - ms_media_stream_sessions_uninit(&call->sessions[0]); - ms_media_stream_sessions_uninit(&call->sessions[1]); + ms_media_stream_sessions_uninit(&call->sessions[call->main_audio_stream_index]); + ms_media_stream_sessions_uninit(&call->sessions[call->main_video_stream_index]); + if (call->params->realtimetext_enabled) ms_media_stream_sessions_uninit(&call->sessions[call->main_text_stream_index]); linphone_call_delete_upnp_session(call); linphone_call_delete_ice_session(call); - linphone_call_stats_uninit(&call->stats[0]); - linphone_call_stats_uninit(&call->stats[1]); + linphone_call_stats_uninit(&call->stats[LINPHONE_CALL_STATS_AUDIO]); + linphone_call_stats_uninit(&call->stats[LINPHONE_CALL_STATS_VIDEO]); + linphone_call_stats_uninit(&call->stats[LINPHONE_CALL_STATS_TEXT]); } /* @@ -1163,6 +1397,10 @@ static void linphone_call_set_released(LinphoneCall *call){ linphone_call_unref(call->transfer_target); call->transfer_target=NULL; } + if (call->chat_room){ + linphone_chat_room_unref(call->chat_room); + call->chat_room = NULL; + } linphone_call_unref(call); } @@ -1191,13 +1429,42 @@ static void linphone_call_set_terminated(LinphoneCall *call){ linphone_core_stop_dtmf(lc); call->ringing_beep=FALSE; } + if (call->chat_room){ + call->chat_room->call = NULL; + } } -void linphone_call_fix_call_parameters(LinphoneCall *call){ - if (sal_call_is_offerer(call->op)) { - /*get remote params*/ - const LinphoneCallParams* rcp = linphone_call_get_remote_params(call); - call->current_params->video_declined = call->params->has_video && !rcp->has_video; +/*function to be called at each incoming reINVITE, in order to adjust various local parameters to what is being offered by remote: + * - the video enablement parameter according to what is offered and our local policy. + * Fixing the call->params to proper values avoid request video by accident during internal call updates, pauses and resumes + * - the stream indexes. + */ +void linphone_call_fix_call_parameters(LinphoneCall *call, SalMediaDescription *rmd){ + const LinphoneCallParams* rcp; + + if (rmd) { + linphone_call_compute_streams_indexes(call, rmd); + linphone_call_update_biggest_desc(call, rmd); + } + rcp = linphone_call_get_remote_params(call); + if (rcp){ + if (call->params->has_audio && !rcp->has_audio){ + ms_message("Call [%p]: disabling audio in our call params because the remote doesn't want it.", call); + call->params->has_audio = FALSE; + } + if (call->params->has_video && !rcp->has_video){ + ms_message("Call [%p]: disabling video in our call params because the remote doesn't want it.", call); + call->params->has_video = FALSE; + } + + if (rcp->has_video && call->core->video_policy.automatically_accept && linphone_core_video_enabled(call->core) && !call->params->has_video){ + ms_message("Call [%p]: re-enabling video in our call params because the remote wants it and the policy allows to automatically accept.", call); + linphone_call_params_enable_video(call->params, TRUE); + } + + if (rcp->realtimetext_enabled && !call->params->realtimetext_enabled) { + call->params->realtimetext_enabled = TRUE; + } } } @@ -1256,7 +1523,7 @@ void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const call->prevstate=call->state; if (call->state==LinphoneCallEnd || call->state==LinphoneCallError){ if (cstate!=LinphoneCallReleased){ - ms_warning("Spurious call state change from %s to %s, ignored." ,linphone_call_state_to_string(call->state) + ms_fatal("Spurious call state change from %s to %s, ignored." ,linphone_call_state_to_string(call->state) ,linphone_call_state_to_string(cstate)); return; } @@ -1282,11 +1549,11 @@ void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const break; case LinphoneCallEnd: case LinphoneCallError: - switch(call->non_op_error.reason){ - case SalReasonDeclined: + switch(linphone_error_info_get_reason(linphone_call_get_error_info(call))) { + case LinphoneReasonDeclined: call->log->status=LinphoneCallDeclined; break; - case SalReasonRequestTimeout: + case LinphoneReasonNotAnswered: call->log->status=LinphoneCallMissed; break; default: @@ -1296,7 +1563,7 @@ void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const break; case LinphoneCallConnected: call->log->status=LinphoneCallSuccess; - call->log->connected_date_time=time(NULL); + call->log->connected_date_time = ms_time(NULL); break; case LinphoneCallReleased: #ifdef ANDROID @@ -1307,7 +1574,15 @@ void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const break; case LinphoneCallStreamsRunning: if (call->prevstate == LinphoneCallUpdating || call->prevstate == LinphoneCallUpdatedByRemote) { - linphone_core_notify_display_status(lc,_("Call parameters were successfully modified.")); + LinphoneReason reason = linphone_call_get_reason(call); + char *msg; + if (reason != LinphoneReasonNone) { + msg = ms_strdup_printf(_("Call parameters could not be modified: %s."), linphone_reason_to_string(reason)); + } else { + msg = ms_strdup(_("Call parameters were successfully modified.")); + } + linphone_core_notify_display_status(lc, msg); + ms_free(msg); } break; default: @@ -1320,12 +1595,17 @@ void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const linphone_call_cancel_dtmfs(call); } } - linphone_core_notify_call_state_changed(lc,call,cstate,message); + if (!message) { + ms_error("%s(): You must fill a reason when changing call state (from %s o %s)." + , __FUNCTION__ + , linphone_call_state_to_string(call->prevstate) + , linphone_call_state_to_string(call->state)); + } + linphone_core_notify_call_state_changed(lc,call,cstate,message?message:""); linphone_reporting_call_state_updated(call); if (cstate==LinphoneCallReleased) {/*shall be performed after app notification*/ linphone_call_set_released(call); } - linphone_core_soundcard_hint_check(lc); } } @@ -1414,13 +1694,14 @@ LinphoneCall * linphone_call_ref(LinphoneCall *obj){ void linphone_call_unref(LinphoneCall *obj){ belle_sip_object_unref(obj); } + static unsigned int linphone_call_get_n_active_streams(const LinphoneCall *call) { SalMediaDescription *md=NULL; if (call->op) md = sal_call_get_remote_media_description(call->op); if (!md) return 0; - return sal_media_description_nb_active_streams_of_type(md, SalAudio) + sal_media_description_nb_active_streams_of_type(md, SalVideo); + return sal_media_description_nb_active_streams_of_type(md, SalAudio) + sal_media_description_nb_active_streams_of_type(md, SalVideo) + sal_media_description_nb_active_streams_of_type(md, SalText); } /** @@ -1428,6 +1709,7 @@ static unsigned int linphone_call_get_n_active_streams(const LinphoneCall *call) **/ const LinphoneCallParams * linphone_call_get_current_params(LinphoneCall *call){ SalMediaDescription *md=call->resultdesc; + int all_streams_encrypted = 0; #ifdef VIDEO_ENABLED VideoStream *vstream; #endif @@ -1454,19 +1736,27 @@ const LinphoneCallParams * linphone_call_get_current_params(LinphoneCall *call){ switch (call->params->media_encryption) { case LinphoneMediaEncryptionZRTP: - if (linphone_call_all_streams_encrypted(call) && linphone_call_get_authentication_token(call)) { - call->current_params->media_encryption=LinphoneMediaEncryptionZRTP; - } else { - call->current_params->media_encryption=LinphoneMediaEncryptionNone; - } + if (at_least_one_stream_started(call)){ + if ((all_streams_encrypted = linphone_call_all_streams_encrypted(call)) && linphone_call_get_authentication_token(call)) { + call->current_params->media_encryption=LinphoneMediaEncryptionZRTP; + } else { + ms_message("Encryption was requested to be %s, but isn't effective (all_streams_encrypted=%i, auth_token=%s)", + linphone_media_encryption_to_string(call->params->media_encryption), all_streams_encrypted, call->auth_token == NULL ? "" : call->auth_token); + call->current_params->media_encryption=LinphoneMediaEncryptionNone; + } + }//else don't update the state if all streams are shutdown. break; case LinphoneMediaEncryptionDTLS: case LinphoneMediaEncryptionSRTP: - if (linphone_call_get_n_active_streams(call)==0 || linphone_call_all_streams_encrypted(call)) { - call->current_params->media_encryption = call->params->media_encryption; - } else { - call->current_params->media_encryption=LinphoneMediaEncryptionNone; - } + if (at_least_one_stream_started(call)){ + if (linphone_call_get_n_active_streams(call)==0 || (all_streams_encrypted = linphone_call_all_streams_encrypted(call))) { + call->current_params->media_encryption = call->params->media_encryption; + } else { + ms_message("Encryption was requested to be %s, but isn't effective (all_streams_encrypted=%i)", + linphone_media_encryption_to_string(call->params->media_encryption), all_streams_encrypted); + call->current_params->media_encryption=LinphoneMediaEncryptionNone; + } + }//else don't update the state if all streams are shutdown. break; case LinphoneMediaEncryptionNone: call->current_params->media_encryption=LinphoneMediaEncryptionNone; @@ -1497,6 +1787,8 @@ const LinphoneCallParams * linphone_call_get_current_params(LinphoneCall *call){ call->current_params->video_multicast_enabled = ms_is_multicast(rtp_addr); } else call->current_params->video_multicast_enabled = FALSE; + + sd=sal_media_description_find_best_stream(md,SalText); } return call->current_params; @@ -1512,14 +1804,17 @@ const LinphoneCallParams * linphone_call_get_remote_params(LinphoneCall *call){ if (call->op){ LinphoneCallParams *cp; SalMediaDescription *md; - if (call->remote_params != NULL) linphone_call_params_unref(call->remote_params); - cp = call->remote_params = linphone_call_params_new(); + const SalCustomHeader *ch; + md=sal_call_get_remote_media_description(call->op); if (md) { SalStreamDescription *sd; unsigned int i; unsigned int nb_audio_streams = sal_media_description_nb_active_streams_of_type(md, SalAudio); unsigned int nb_video_streams = sal_media_description_nb_active_streams_of_type(md, SalVideo); + unsigned int nb_text_streams = sal_media_description_nb_active_streams_of_type(md, SalText); + if (call->remote_params != NULL) linphone_call_params_unref(call->remote_params); + cp = call->remote_params = linphone_call_params_new(); for (i = 0; i < nb_video_streams; i++) { sd = sal_media_description_get_active_stream_of_type(md, SalVideo, i); @@ -1530,15 +1825,30 @@ const LinphoneCallParams * linphone_call_get_remote_params(LinphoneCall *call){ sd = sal_media_description_get_active_stream_of_type(md, SalAudio, i); if (sal_stream_description_has_srtp(sd) == TRUE) cp->media_encryption = LinphoneMediaEncryptionSRTP; } + for (i = 0; i < nb_text_streams; i++) { + sd = sal_media_description_get_active_stream_of_type(md, SalText, i); + if (sal_stream_description_has_srtp(sd) == TRUE) cp->media_encryption = LinphoneMediaEncryptionSRTP; + cp->realtimetext_enabled = TRUE; + } if (!cp->has_video){ if (md->bandwidth>0 && md->bandwidth<=linphone_core_get_edge_bw(call->core)){ cp->low_bandwidth=TRUE; } } if (md->name[0]!='\0') linphone_call_params_set_session_name(cp,md->name); + + linphone_call_params_set_custom_sdp_attributes(call->remote_params, md->custom_sdp_attributes); + linphone_call_params_set_custom_sdp_media_attributes(call->remote_params, LinphoneStreamTypeAudio, md->streams[call->main_audio_stream_index].custom_sdp_attributes); + linphone_call_params_set_custom_sdp_media_attributes(call->remote_params, LinphoneStreamTypeVideo, md->streams[call->main_video_stream_index].custom_sdp_attributes); + linphone_call_params_set_custom_sdp_media_attributes(call->remote_params, LinphoneStreamTypeText, md->streams[call->main_text_stream_index].custom_sdp_attributes); } - cp->custom_headers=sal_custom_header_clone((SalCustomHeader*)sal_op_get_recv_custom_header(call->op)); - return cp; + ch = sal_op_get_recv_custom_header(call->op); + if (ch){ + /*instanciate a remote_params only if a SIP message was received before (custom headers indicates this).*/ + if (call->remote_params == NULL) call->remote_params = linphone_call_params_new(); + linphone_call_params_set_custom_headers(call->remote_params, ch); + } + return call->remote_params; } return NULL; } @@ -1684,7 +1994,7 @@ bool_t linphone_call_has_transfer_pending(const LinphoneCall *call){ **/ int linphone_call_get_duration(const LinphoneCall *call){ if (call->log->connected_date_time==0) return 0; - return time(NULL)-call->log->connected_date_time; + return (int)(ms_time(NULL) - call->log->connected_date_time); } /** @@ -1831,8 +2141,11 @@ static void video_stream_event_cb(void *user_pointer, const MSFilter *f, const u break; case MS_VIDEO_DECODER_FIRST_IMAGE_DECODED: ms_message("First video frame decoded successfully"); - if (call->nextVideoFrameDecoded._func != NULL) + if (call->nextVideoFrameDecoded._func != NULL){ call->nextVideoFrameDecoded._func(call, call->nextVideoFrameDecoded._user_data); + call->nextVideoFrameDecoded._func = NULL; + call->nextVideoFrameDecoded._user_data = NULL; + } break; case MS_VIDEO_DECODER_SEND_PLI: case MS_VIDEO_DECODER_SEND_SLI: @@ -1846,13 +2159,17 @@ static void video_stream_event_cb(void *user_pointer, const MSFilter *f, const u } #endif +static void _linphone_call_set_next_video_frame_decoded_trigger(LinphoneCall *call){ +#ifdef VIDEO_ENABLED + if (call->nextVideoFrameDecoded._func && call->videostream && call->videostream->ms.decoder) + ms_filter_call_method_noarg(call->videostream->ms.decoder, MS_VIDEO_DECODER_RESET_FIRST_IMAGE_NOTIFICATION); +#endif +} + void linphone_call_set_next_video_frame_decoded_callback(LinphoneCall *call, LinphoneCallCbFunc cb, void* user_data) { call->nextVideoFrameDecoded._func = cb; call->nextVideoFrameDecoded._user_data = user_data; -#ifdef VIDEO_ENABLED - if (call->videostream && call->videostream->ms.decoder) - ms_filter_call_method_noarg(call->videostream->ms.decoder, MS_VIDEO_DECODER_RESET_FIRST_IMAGE_NOTIFICATION); -#endif + _linphone_call_set_next_video_frame_decoded_trigger(call); } static void port_config_set_random_choosed(LinphoneCall *call, int stream_index, RtpSession *session){ @@ -1861,7 +2178,7 @@ static void port_config_set_random_choosed(LinphoneCall *call, int stream_index, } static void _linphone_call_prepare_ice_for_stream(LinphoneCall *call, int stream_index, bool_t create_checklist){ - MediaStream *ms=stream_index == 0 ? (MediaStream*)call->audiostream : (MediaStream*)call->videostream; + MediaStream *ms = stream_index == call->main_audio_stream_index ? (MediaStream*)call->audiostream : stream_index == call->main_video_stream_index ? (MediaStream*)call->videostream : (MediaStream*)call->textstream; if ((linphone_core_get_firewall_policy(call->core) == LinphonePolicyUseIce) && (call->ice_session != NULL)){ IceCheckList *cl; rtp_session_set_pktinfo(ms->sessions.rtp_session, TRUE); @@ -1888,8 +2205,9 @@ int linphone_call_prepare_ice(LinphoneCall *call, bool_t incoming_offer){ has_video=linphone_core_video_enabled(call->core) && linphone_core_media_description_contains_video_stream(remote); }else has_video=call->params->has_video; - _linphone_call_prepare_ice_for_stream(call,0,TRUE); - if (has_video) _linphone_call_prepare_ice_for_stream(call,1,TRUE); + _linphone_call_prepare_ice_for_stream(call,call->main_audio_stream_index,TRUE); + if (has_video) _linphone_call_prepare_ice_for_stream(call,call->main_video_stream_index,TRUE); + if (call->params->realtimetext_enabled) _linphone_call_prepare_ice_for_stream(call,call->main_text_stream_index,TRUE); /*start ICE gathering*/ if (incoming_offer) linphone_call_update_ice_from_remote_media_description(call,remote); /*this may delete the ice session*/ @@ -1901,6 +2219,10 @@ int linphone_call_prepare_ice(LinphoneCall *call, bool_t incoming_offer){ video_stream_prepare_video(call->videostream); } #endif + if (call->params->realtimetext_enabled) { + text_stream_prepare_text(call->textstream); + } + if (linphone_core_gather_ice_candidates(call->core,call)<0) { /* Ice candidates gathering failed, proceed with the call anyway. */ linphone_call_delete_ice_session(call); @@ -1949,6 +2271,31 @@ static SalMulticastRole linphone_call_get_multicast_role(const LinphoneCall *cal } +static void setup_dtls_params(LinphoneCall *call, MediaStream* stream) { + LinphoneCore *lc=call->core; + if (call->params->media_encryption==LinphoneMediaEncryptionDTLS) { + MSDtlsSrtpParams params; + char *certificate, *key; + memset(¶ms,0,sizeof(MSDtlsSrtpParams)); + /* TODO : search for a certificate with CNAME=sip uri(retrieved from variable me) or default : linphone-dtls-default-identity */ + /* This will parse the directory to find a matching fingerprint or generate it if not found */ + /* returned string must be freed */ + sal_certificates_chain_parse_directory(&certificate, &key, &call->dtls_certificate_fingerprint, lc->user_certificates_path, "linphone-dtls-default-identity", SAL_CERTIFICATE_RAW_FORMAT_PEM, TRUE, TRUE); + + if (key!= NULL && certificate!=NULL) { + params.pem_certificate = (char *)certificate; + params.pem_pkey = (char *)key; + params.role = MSDtlsSrtpRoleUnset; /* default is unset, then check if we have a result SalMediaDescription */ + media_stream_enable_dtls(stream,¶ms); + ms_free(certificate); + ms_free(key); + } else { + ms_error("Unable to retrieve or generate DTLS certificate and key - DTLS disabled"); + /* TODO : check if encryption forced, if yes, stop call */ + } + } +} + void linphone_call_init_audio_stream(LinphoneCall *call){ LinphoneCore *lc=call->core; AudioStream *audiostream; @@ -1957,11 +2304,10 @@ void linphone_call_init_audio_stream(LinphoneCall *call){ char rtcp_tool[128]={0}; char* cname; - snprintf(rtcp_tool,sizeof(rtcp_tool)-1,"%s-%s",linphone_core_get_user_agent_name(),linphone_core_get_user_agent_version()); if (call->audiostream != NULL) return; - if (call->sessions[0].rtp_session==NULL){ + if (call->sessions[call->main_audio_stream_index].rtp_session==NULL){ SalMulticastRole multicast_role = linphone_call_get_multicast_role(call,SalAudio); SalMediaDescription *remotedesc=NULL; SalStreamDescription *stream_desc = NULL; @@ -1969,43 +2315,24 @@ void linphone_call_init_audio_stream(LinphoneCall *call){ if (remotedesc) stream_desc = sal_media_description_find_best_stream(remotedesc, SalAudio); - call->audiostream=audiostream=audio_stream_new2(linphone_call_get_bind_ip_for_stream(call,0), - multicast_role == SalMulticastReceiver ? stream_desc->rtp_port : call->media_ports[0].rtp_port, - multicast_role == SalMulticastReceiver ? 0 /*disabled for now*/ : call->media_ports[0].rtcp_port); + call->audiostream=audiostream=audio_stream_new2(linphone_call_get_bind_ip_for_stream(call,call->main_audio_stream_index), + multicast_role == SalMulticastReceiver ? stream_desc->rtp_port : call->media_ports[call->main_audio_stream_index].rtp_port, + multicast_role == SalMulticastReceiver ? 0 /*disabled for now*/ : call->media_ports[call->main_audio_stream_index].rtcp_port); if (multicast_role == SalMulticastReceiver) - linphone_call_join_multicast_group(call, 0, &audiostream->ms); + linphone_call_join_multicast_group(call, call->main_audio_stream_index, &audiostream->ms); rtp_session_enable_network_simulation(call->audiostream->ms.sessions.rtp_session, &lc->net_conf.netsim_params); cname = linphone_address_as_string_uri_only(call->me); audio_stream_set_rtcp_information(call->audiostream, cname, rtcp_tool); ms_free(cname); rtp_session_set_symmetric_rtp(audiostream->ms.sessions.rtp_session,linphone_core_symmetric_rtp_enabled(lc)); - if (call->params->media_encryption==LinphoneMediaEncryptionDTLS) { - MSDtlsSrtpParams params; - char *certificate, *key; - memset(¶ms,0,sizeof(MSDtlsSrtpParams)); - /* TODO : search for a certificate with CNAME=sip uri(retrieved from variable me) or default : linphone-dtls-default-identity */ - /* This will parse the directory to find a matching fingerprint or generate it if not found */ - /* returned string must be freed */ - sal_certificates_chain_parse_directory(&certificate, &key, &call->dtls_certificate_fingerprint, lc->user_certificates_path, "linphone-dtls-default-identity", SAL_CERTIFICATE_RAW_FORMAT_PEM, TRUE, TRUE); - - if (key!= NULL && certificate!=NULL) { - params.pem_certificate = (char *)certificate; - params.pem_pkey = (char *)key; - params.role = MSDtlsSrtpRoleUnset; /* default is unset, then check if we have a result SalMediaDescription */ - audio_stream_enable_dtls(call->audiostream,¶ms); - ms_free(certificate); - ms_free(key); - } else { - ms_error("Unable to retrieve or generate DTLS certificate and key - DTLS disabled"); - /* TODO : check if encryption forced, if yes, stop call */ - } - } + setup_dtls_params(call, &audiostream->ms); + media_stream_reclaim_sessions(&audiostream->ms, &call->sessions[call->main_audio_stream_index]); }else{ - call->audiostream=audio_stream_new_with_sessions(&call->sessions[0]); + call->audiostream=audio_stream_new_with_sessions(&call->sessions[call->main_audio_stream_index]); } audiostream=call->audiostream; - if (call->media_ports[0].rtp_port==-1){ - port_config_set_random_choosed(call,0,audiostream->ms.sessions.rtp_session); + if (call->media_ports[call->main_audio_stream_index].rtp_port==-1){ + port_config_set_random_choosed(call,call->main_audio_stream_index,audiostream->ms.sessions.rtp_session); } dscp=linphone_core_get_audio_dscp(lc); if (dscp!=-1) @@ -2054,27 +2381,25 @@ void linphone_call_init_audio_stream(LinphoneCall *call){ rtp_session_get_transports(audiostream->ms.sessions.rtp_session,&meta_rtp,&meta_rtcp); if (meta_rtp_transport_get_endpoint(meta_rtp) == NULL) { - meta_rtp_transport_set_endpoint(meta_rtp,lc->rtptf->audio_rtp_func(lc->rtptf->audio_rtp_func_data, call->media_ports[0].rtp_port)); + meta_rtp_transport_set_endpoint(meta_rtp,lc->rtptf->audio_rtp_func(lc->rtptf->audio_rtp_func_data, call->media_ports[call->main_audio_stream_index].rtp_port)); } if (meta_rtp_transport_get_endpoint(meta_rtcp) == NULL) { - meta_rtp_transport_set_endpoint(meta_rtcp,lc->rtptf->audio_rtcp_func(lc->rtptf->audio_rtcp_func_data, call->media_ports[0].rtcp_port)); + meta_rtp_transport_set_endpoint(meta_rtcp,lc->rtptf->audio_rtcp_func(lc->rtptf->audio_rtcp_func_data, call->media_ports[call->main_audio_stream_index].rtcp_port)); } } call->audiostream_app_evq = ortp_ev_queue_new(); rtp_session_register_event_queue(audiostream->ms.sessions.rtp_session,call->audiostream_app_evq); - _linphone_call_prepare_ice_for_stream(call,0,FALSE); + _linphone_call_prepare_ice_for_stream(call,call->main_audio_stream_index,FALSE); } - void linphone_call_init_video_stream(LinphoneCall *call){ #ifdef VIDEO_ENABLED LinphoneCore *lc=call->core; char* cname; char rtcp_tool[128]; - snprintf(rtcp_tool,sizeof(rtcp_tool)-1,"%s-%s",linphone_core_get_user_agent_name(),linphone_core_get_user_agent_version()); if (call->videostream == NULL){ @@ -2082,7 +2407,7 @@ void linphone_call_init_video_stream(LinphoneCall *call){ int dscp=linphone_core_get_video_dscp(lc); const char *display_filter=linphone_core_get_video_display_filter(lc); - if (call->sessions[1].rtp_session==NULL){ + if (call->sessions[call->main_video_stream_index].rtp_session==NULL){ SalMulticastRole multicast_role = linphone_call_get_multicast_role(call,SalVideo); SalMediaDescription *remotedesc=NULL; SalStreamDescription *stream_desc = NULL; @@ -2090,44 +2415,24 @@ void linphone_call_init_video_stream(LinphoneCall *call){ if (remotedesc) stream_desc = sal_media_description_find_best_stream(remotedesc, SalVideo); - call->videostream=video_stream_new2(linphone_call_get_bind_ip_for_stream(call,1), - multicast_role == SalMulticastReceiver ? stream_desc->rtp_port : call->media_ports[1].rtp_port, - multicast_role == SalMulticastReceiver ? 0 /*disabled for now*/ : call->media_ports[1].rtcp_port); + call->videostream=video_stream_new2(linphone_call_get_bind_ip_for_stream(call,call->main_video_stream_index), + multicast_role == SalMulticastReceiver ? stream_desc->rtp_port : call->media_ports[call->main_video_stream_index].rtp_port, + multicast_role == SalMulticastReceiver ? 0 /*disabled for now*/ : call->media_ports[call->main_video_stream_index].rtcp_port); if (multicast_role == SalMulticastReceiver) - linphone_call_join_multicast_group(call, 1, &call->videostream->ms); + linphone_call_join_multicast_group(call, call->main_video_stream_index, &call->videostream->ms); rtp_session_enable_network_simulation(call->videostream->ms.sessions.rtp_session, &lc->net_conf.netsim_params); cname = linphone_address_as_string_uri_only(call->me); video_stream_set_rtcp_information(call->videostream, cname, rtcp_tool); ms_free(cname); rtp_session_set_symmetric_rtp(call->videostream->ms.sessions.rtp_session,linphone_core_symmetric_rtp_enabled(lc)); - - if (call->params->media_encryption==LinphoneMediaEncryptionDTLS) { - MSDtlsSrtpParams params; - char *certificate, *key; - memset(¶ms,0,sizeof(MSDtlsSrtpParams)); - /* TODO : search for a certificate with CNAME=sip uri(retrieved from variable me) or default : linphone-dtls-default-identity */ - /* This will parse the directory to find a matching fingerprint or generate it if not found */ - /* returned string must be freed */ - sal_certificates_chain_parse_directory(&certificate, &key, &call->dtls_certificate_fingerprint, lc->user_certificates_path, "linphone-dtls-default-identity", SAL_CERTIFICATE_RAW_FORMAT_PEM, TRUE, TRUE); - - if (key!= NULL && certificate!=NULL) { - params.pem_certificate = (char *)certificate; - params.pem_pkey = (char *)key; - params.role = MSDtlsSrtpRoleUnset; /* default is unset, then check if we have a result SalMediaDescription */ - video_stream_enable_dtls(call->videostream,¶ms); - ms_free(certificate); - ms_free(key); - } else { - ms_error("Unable to retrieve or generate DTLS certificate and key - DTLS disabled"); - /* TODO : check if encryption forced, if yes, stop call */ - } - } + setup_dtls_params(call, &call->videostream->ms); + media_stream_reclaim_sessions(&call->videostream->ms, &call->sessions[call->main_video_stream_index]); }else{ - call->videostream=video_stream_new_with_sessions(&call->sessions[1]); + call->videostream=video_stream_new_with_sessions(&call->sessions[call->main_video_stream_index]); } - if (call->media_ports[1].rtp_port==-1){ - port_config_set_random_choosed(call,1,call->videostream->ms.sessions.rtp_session); + if (call->media_ports[call->main_video_stream_index].rtp_port==-1){ + port_config_set_random_choosed(call,call->main_video_stream_index,call->videostream->ms.sessions.rtp_session); } if (dscp!=-1) video_stream_set_dscp(call->videostream,dscp); @@ -2144,15 +2449,15 @@ void linphone_call_init_video_stream(LinphoneCall *call){ rtp_session_get_transports(call->videostream->ms.sessions.rtp_session,&meta_rtp,&meta_rtcp); if (meta_rtp_transport_get_endpoint(meta_rtp) == NULL) { - meta_rtp_transport_set_endpoint(meta_rtp,lc->rtptf->video_rtp_func(lc->rtptf->video_rtp_func_data, call->media_ports[1].rtp_port)); + meta_rtp_transport_set_endpoint(meta_rtp,lc->rtptf->video_rtp_func(lc->rtptf->video_rtp_func_data, call->media_ports[call->main_video_stream_index].rtp_port)); } if (meta_rtp_transport_get_endpoint(meta_rtcp) == NULL) { - meta_rtp_transport_set_endpoint(meta_rtcp,lc->rtptf->video_rtcp_func(lc->rtptf->video_rtcp_func_data, call->media_ports[1].rtcp_port)); + meta_rtp_transport_set_endpoint(meta_rtcp,lc->rtptf->video_rtcp_func(lc->rtptf->video_rtcp_func_data, call->media_ports[call->main_video_stream_index].rtcp_port)); } } call->videostream_app_evq = ortp_ev_queue_new(); rtp_session_register_event_queue(call->videostream->ms.sessions.rtp_session,call->videostream_app_evq); - _linphone_call_prepare_ice_for_stream(call,1,FALSE); + _linphone_call_prepare_ice_for_stream(call,call->main_video_stream_index,FALSE); #ifdef TEST_EXT_RENDERER video_stream_set_render_callback(call->videostream,rendercb,NULL); #endif @@ -2162,20 +2467,72 @@ void linphone_call_init_video_stream(LinphoneCall *call){ #endif } +void linphone_call_init_text_stream(LinphoneCall *call){ + TextStream *textstream; + LinphoneCore *lc=call->core; + char* cname; + + if (call->textstream != NULL || !call->params->realtimetext_enabled) return; + if (call->sessions[call->main_text_stream_index].rtp_session == NULL) { + SalMulticastRole multicast_role = linphone_call_get_multicast_role(call, SalText); + SalMediaDescription *remotedesc = NULL; + SalStreamDescription *stream_desc = NULL; + if (call->op) remotedesc = sal_call_get_remote_media_description(call->op); + if (remotedesc) stream_desc = sal_media_description_find_best_stream(remotedesc, SalText); + + call->textstream = textstream = text_stream_new2(linphone_call_get_bind_ip_for_stream(call,call->main_text_stream_index), + multicast_role == SalMulticastReceiver ? stream_desc->rtp_port : call->media_ports[call->main_text_stream_index].rtp_port, + multicast_role == SalMulticastReceiver ? 0 /*disabled for now*/ : call->media_ports[call->main_text_stream_index].rtcp_port); + if (multicast_role == SalMulticastReceiver) + linphone_call_join_multicast_group(call, call->main_text_stream_index, &textstream->ms); + rtp_session_enable_network_simulation(call->textstream->ms.sessions.rtp_session, &lc->net_conf.netsim_params); + cname = linphone_address_as_string_uri_only(call->me); + ms_free(cname); + rtp_session_set_symmetric_rtp(textstream->ms.sessions.rtp_session,linphone_core_symmetric_rtp_enabled(lc)); + setup_dtls_params(call, &textstream->ms); + media_stream_reclaim_sessions(&textstream->ms, &call->sessions[call->main_text_stream_index]); + } else { + call->textstream = text_stream_new_with_sessions(&call->sessions[call->main_text_stream_index]); + } + textstream = call->textstream; + if (call->media_ports[call->main_text_stream_index].rtp_port == -1) { + port_config_set_random_choosed(call, call->main_text_stream_index, textstream->ms.sessions.rtp_session); + } + + if (lc->rtptf){ + RtpTransport *meta_rtp; + RtpTransport *meta_rtcp; + + rtp_session_get_transports(textstream->ms.sessions.rtp_session, &meta_rtp, &meta_rtcp); + if (meta_rtp_transport_get_endpoint(meta_rtp) == NULL) { + meta_rtp_transport_set_endpoint(meta_rtp,lc->rtptf->audio_rtp_func(lc->rtptf->audio_rtp_func_data, call->media_ports[call->main_text_stream_index].rtp_port)); + } + if (meta_rtp_transport_get_endpoint(meta_rtcp) == NULL) { + meta_rtp_transport_set_endpoint(meta_rtcp,lc->rtptf->audio_rtcp_func(lc->rtptf->audio_rtcp_func_data, call->media_ports[call->main_text_stream_index].rtcp_port)); + } + } + + call->textstream_app_evq = ortp_ev_queue_new(); + rtp_session_register_event_queue(textstream->ms.sessions.rtp_session, call->textstream_app_evq); + + _linphone_call_prepare_ice_for_stream(call, call->main_text_stream_index, FALSE); +} + void linphone_call_init_media_streams(LinphoneCall *call){ linphone_call_init_audio_stream(call); linphone_call_init_video_stream(call); + linphone_call_init_text_stream(call); } static int dtmf_tab[16]={'0','1','2','3','4','5','6','7','8','9','*','#','A','B','C','D'}; -static void linphone_core_dtmf_received(LinphoneCore *lc, int dtmf){ +static void linphone_core_dtmf_received(LinphoneCall *call, int dtmf){ if (dtmf<0 || dtmf>15){ ms_warning("Bad dtmf value %i",dtmf); return; } - linphone_core_notify_dtmf_received(lc, linphone_core_get_current_call(lc), dtmf_tab[dtmf]); + linphone_core_notify_dtmf_received(call->core, call, dtmf_tab[dtmf]); } static void parametrize_equalizer(LinphoneCore *lc, AudioStream *st){ @@ -2215,7 +2572,7 @@ void _post_configure_audio_stream(AudioStream *st, LinphoneCore *lc, bool_t mute float mic_gain=lc->sound_conf.soft_mic_lev; float thres = 0; float recv_gain; - float ng_thres=lp_config_get_float(lc->config,"sound","ng_thres",0.05); + float ng_thres=lp_config_get_float(lc->config,"sound","ng_thres",0.05f); float ng_floorgain=lp_config_get_float(lc->config,"sound","ng_floorgain",0); int dc_removal=lp_config_get_int(lc->config,"sound","dc_removal",0); float speed; @@ -2244,7 +2601,7 @@ void _post_configure_audio_stream(AudioStream *st, LinphoneCore *lc, bool_t mute sustain=lp_config_get_int(lc->config,"sound","el_sustain",-1); transmit_thres=lp_config_get_float(lc->config,"sound","el_transmit_thres",-1); f=st->volsend; - if (speed==-1) speed=0.03; + if (speed==-1) speed=0.03f; if (force==-1) force=25; ms_filter_call_method(f,MS_VOLUME_SET_EA_SPEED,&speed); ms_filter_call_method(f,MS_VOLUME_SET_EA_FORCE,&force); @@ -2260,7 +2617,7 @@ void _post_configure_audio_stream(AudioStream *st, LinphoneCore *lc, bool_t mute } if (st->volrecv){ /* parameters for a limited noise-gate effect, using echo limiter threshold */ - floorgain = 1/pow(10,(mic_gain)/10); + floorgain = (float)(1/pow(10,mic_gain/10)); spk_agc=lp_config_get_int(lc->config,"sound","speaker_agc_enabled",0); ms_filter_call_method(st->volrecv, MS_VOLUME_ENABLE_AGC, &spk_agc); ms_filter_call_method(st->volrecv,MS_VOLUME_SET_NOISE_GATE_THRESHOLD,&ng_thres); @@ -2341,6 +2698,8 @@ static RtpProfile *make_profile(LinphoneCall *call, const SalMediaDescription *m bw=get_ideal_audio_bw(call,md,desc); else if (desc->type==SalVideo) bw=get_video_bw(call,md,desc); + //else if (desc->type== SalText) + for(elem=desc->payloads;elem!=NULL;elem=elem->next){ PayloadType *pt=(PayloadType*)elem->data; @@ -2407,8 +2766,29 @@ static int find_crypto_index_from_tag(const SalSrtpCryptoAlgo crypto[],unsigned return -1; } +static void configure_rtp_session_for_rtcp_fb(LinphoneCall *call, const SalStreamDescription *stream) { + RtpSession *session = NULL; + + if (stream->type == SalAudio) { + session = call->audiostream->ms.sessions.rtp_session; + } else if (stream->type == SalVideo) { + session = call->videostream->ms.sessions.rtp_session; + } else { + // Do nothing for streams that are not audio or video + return; + } + if (stream->rtcp_fb.generic_nack_enabled) + rtp_session_enable_avpf_feature(session, ORTP_AVPF_FEATURE_GENERIC_NACK, TRUE); + else + rtp_session_enable_avpf_feature(session, ORTP_AVPF_FEATURE_GENERIC_NACK, FALSE); + if (stream->rtcp_fb.tmmbr_enabled) + rtp_session_enable_avpf_feature(session, ORTP_AVPF_FEATURE_TMMBR, TRUE); + else + rtp_session_enable_avpf_feature(session, ORTP_AVPF_FEATURE_TMMBR, FALSE); +} + static void configure_rtp_session_for_rtcp_xr(LinphoneCore *lc, LinphoneCall *call, SalStreamType type) { - RtpSession *session; + RtpSession *session = NULL; const OrtpRtcpXrConfiguration *localconfig; const OrtpRtcpXrConfiguration *remoteconfig; OrtpRtcpXrConfiguration currentconfig; @@ -2436,8 +2816,10 @@ static void configure_rtp_session_for_rtcp_xr(LinphoneCore *lc, LinphoneCall *ca } if (type == SalAudio) { session = call->audiostream->ms.sessions.rtp_session; - } else { + } else if (type == SalVideo) { session = call->videostream->ms.sessions.rtp_session; + } else if (type == SalText) { + session = call->textstream->ms.sessions.rtp_session; } rtp_session_configure_rtcp_xr(session, ¤tconfig); } @@ -2473,6 +2855,10 @@ void static start_dtls_on_all_streams(LinphoneCall *call) { ,sal_media_description_find_best_stream(result_desc,SalVideo) ,sal_media_description_find_best_stream(remote_desc,SalVideo)); #endif + if (call->textstream && (media_stream_get_state((const MediaStream *)call->textstream) == MSStreamStarted))/*dtls must start at the end of ice*/ + start_dtls(&call->textstream->ms.sessions + ,sal_media_description_find_best_stream(result_desc,SalText) + ,sal_media_description_find_best_stream(remote_desc,SalText)); return; } @@ -2508,12 +2894,53 @@ void static set_dtls_fingerprint_on_all_streams(LinphoneCall *call) { ,sal_media_description_find_best_stream(result_desc,SalVideo) ,sal_media_description_find_best_stream(remote_desc,SalVideo)); #endif + if (call->textstream && (media_stream_get_state((const MediaStream *)call->textstream) == MSStreamStarted))/*dtls must start at the end of ice*/ + set_dtls_fingerprint(&call->textstream->ms.sessions + ,sal_media_description_find_best_stream(result_desc,SalText) + ,sal_media_description_find_best_stream(remote_desc,SalText)); return; } -static void linphone_call_start_audio_stream(LinphoneCall *call, bool_t muted, bool_t send_ringbacktone, bool_t use_arc){ +static RtpSession * create_audio_rtp_io_session(LinphoneCall *call) { + PayloadType *pt; + LinphoneCore *lc = call->core; + const char *local_ip = lp_config_get_string(lc->config, "sound", "rtp_local_addr", "127.0.0.1"); + const char *remote_ip = lp_config_get_string(lc->config, "sound", "rtp_remote_addr", "127.0.0.1"); + int local_port = lp_config_get_int(lc->config, "sound", "rtp_local_port", 17076); + int remote_port = lp_config_get_int(lc->config, "sound", "rtp_remote_port", 17078); + int ptnum = lp_config_get_int(lc->config, "sound", "rtp_ptnum", 0); + const char *rtpmap = lp_config_get_string(lc->config, "sound", "rtp_map", "pcmu/8000/1"); + int symmetric = lp_config_get_int(lc->config, "sound", "rtp_symmetric", 0); + int jittcomp = lp_config_get_int(lc->config, "sound", "rtp_jittcomp", 0); /* 0 means no jitter buffer*/ + RtpSession *rtp_session = NULL; + pt = rtp_profile_get_payload_from_rtpmap(call->audio_profile, rtpmap); + if (pt != NULL) { + call->rtp_io_audio_profile = rtp_profile_new("RTP IO audio profile"); + rtp_profile_set_payload(call->rtp_io_audio_profile, ptnum, payload_type_clone(pt)); + rtp_session = ms_create_duplex_rtp_session(local_ip, local_port, -1); + rtp_session_set_profile(rtp_session, call->rtp_io_audio_profile); + rtp_session_set_remote_addr_and_port(rtp_session, remote_ip, remote_port, -1); + rtp_session_enable_rtcp(rtp_session, FALSE); + rtp_session_set_payload_type(rtp_session, ptnum); + rtp_session_set_jitter_compensation(rtp_session, jittcomp); + rtp_session_enable_jitter_buffer(rtp_session, jittcomp>0); + rtp_session_set_symmetric_rtp(rtp_session, (bool_t)symmetric); + } + return rtp_session; +} + +static void linphone_call_set_on_hold_file(LinphoneCall *call, const char *file){ + if (call->onhold_file){ + ms_free(call->onhold_file); + call->onhold_file = NULL; + } + if (file){ + call->onhold_file = ms_strdup(file); + } +} + +static void linphone_call_start_audio_stream(LinphoneCall *call, LinphoneCallState next_state, bool_t use_arc){ LinphoneCore *lc=call->core; - LpConfig* conf; int used_pt=-1; char rtcp_tool[128]={0}; const SalStreamDescription *stream; @@ -2523,8 +2950,11 @@ static void linphone_call_start_audio_stream(LinphoneCall *call, bool_t muted, b bool_t mute; const char *playfile; const char *recfile; + const char *file_to_play = NULL; const SalStreamDescription *local_st_desc; int crypto_idx; + MSMediaStreamIO io = MS_MEDIA_STREAM_IO_INITIALIZER; + bool_t use_rtp_io = lp_config_get_int(lc->config, "sound", "rtp_io", FALSE); snprintf(rtcp_tool,sizeof(rtcp_tool)-1,"%s-%s",linphone_core_get_user_agent_name(),linphone_core_get_user_agent_version()); @@ -2540,6 +2970,7 @@ static void linphone_call_start_audio_stream(LinphoneCall *call, bool_t muted, b call->audio_profile=make_profile(call,call->resultdesc,stream,&used_pt); if (used_pt!=-1){ + bool_t ok = TRUE; call->current_params->audio_codec = rtp_profile_get_payload(call->audio_profile, used_pt); if (playcard==NULL) { ms_warning("No card defined for playback !"); @@ -2547,31 +2978,30 @@ static void linphone_call_start_audio_stream(LinphoneCall *call, bool_t muted, b if (captcard==NULL) { ms_warning("No card defined for capture !"); } - /*Replace soundcard filters by inactive file players or recorders - when placed in recvonly or sendonly mode*/ + /*Don't use file or soundcard capture when placed in recv-only mode*/ if (stream->rtp_port==0 || stream->dir==SalStreamRecvOnly || (stream->multicast_role == SalMulticastReceiver && is_multicast)){ captcard=NULL; playfile=NULL; - }else if (stream->dir==SalStreamSendOnly){ + } + if (next_state == LinphoneCallPaused){ + /*in paused state, we never use soundcard*/ playcard=NULL; captcard=NULL; recfile=NULL; /*And we will eventually play "playfile" if set by the user*/ - /*playfile=NULL;*/ } - if (send_ringbacktone){ - conf = linphone_core_get_config(lc); + if (call->playing_ringbacktone){ captcard=NULL; playfile=NULL;/* it is setup later*/ - if( conf && lp_config_get_int(conf,"sound","send_ringback_without_playback", 0) == 1){ + if (lp_config_get_int(lc->config,"sound","send_ringback_without_playback", 0) == 1){ playcard = NULL; recfile = NULL; } } /*if playfile are supplied don't use soundcards*/ - if (lc->use_files) { + if (lc->use_files || use_rtp_io) { captcard=NULL; playcard=NULL; } @@ -2584,12 +3014,15 @@ static void linphone_call_start_audio_stream(LinphoneCall *call, bool_t muted, b captcard=playcard=NULL; } use_ec=captcard==NULL ? FALSE : linphone_core_echo_cancellation_enabled(lc); + audio_stream_enable_echo_canceller(call->audiostream, use_ec); if (playcard && stream->max_rate>0) ms_snd_card_set_preferred_sample_rate(playcard, stream->max_rate); if (captcard && stream->max_rate>0) ms_snd_card_set_preferred_sample_rate(captcard, stream->max_rate); audio_stream_enable_adaptive_bitrate_control(call->audiostream,use_arc); media_stream_set_adaptive_bitrate_algorithm(&call->audiostream->ms, - ms_qos_analyzer_algorithm_from_string(linphone_core_get_adaptive_rate_algorithm(lc))); + ms_qos_analyzer_algorithm_from_string(linphone_core_get_adaptive_rate_algorithm(lc))); audio_stream_enable_adaptive_jittcomp(call->audiostream, linphone_core_audio_adaptive_jittcomp_enabled(lc)); + rtp_session_set_jitter_compensation(call->audiostream->ms.sessions.rtp_session,linphone_core_get_audio_jittcomp(lc)); + rtp_session_enable_rtcp_mux(call->audiostream->ms.sessions.rtp_session, stream->rtcp_mux); if (!call->params->in_conference && call->params->record_file){ audio_stream_mixed_record_open(call->audiostream,call->params->record_file); call->current_params->record_file=ms_strdup(call->params->record_file); @@ -2600,69 +3033,121 @@ static void linphone_call_start_audio_stream(LinphoneCall *call, bool_t muted, b crypto_idx = find_crypto_index_from_tag(local_st_desc->crypto, stream->crypto_local_tag); if (crypto_idx >= 0) { - media_stream_set_srtp_recv_key_b64(&(call->audiostream->ms.sessions),stream->crypto[0].algo,stream->crypto[0].master_key); - media_stream_set_srtp_send_key_b64(&(call->audiostream->ms.sessions),stream->crypto[0].algo,local_st_desc->crypto[crypto_idx].master_key); + ms_media_stream_sessions_set_srtp_recv_key_b64(&call->audiostream->ms.sessions, stream->crypto[0].algo,stream->crypto[0].master_key); + ms_media_stream_sessions_set_srtp_send_key_b64(&call->audiostream->ms.sessions, stream->crypto[0].algo,local_st_desc->crypto[crypto_idx].master_key); } else { ms_warning("Failed to find local crypto algo with tag: %d", stream->crypto_local_tag); } } + configure_rtp_session_for_rtcp_fb(call, stream); 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, - rtp_addr, - stream->rtp_port, - stream->rtcp_addr[0]!='\0' ? stream->rtcp_addr : call->resultdesc->addr, - (linphone_core_rtcp_enabled(lc) && !is_multicast) ? (stream->rtcp_port ? stream->rtcp_port : stream->rtp_port+1) : 0, - used_pt, - linphone_core_get_audio_jittcomp(lc), - playfile, - recfile, - playcard, - captcard, - use_ec - ); - post_configure_audio_streams(call, muted && !send_ringbacktone); + if (use_rtp_io) { + io.input.type = io.output.type = MSResourceRtp; + io.input.session = io.output.session = create_audio_rtp_io_session(call); + if (io.input.session == NULL) { + ok = FALSE; + } + }else { + if (playcard){ + io.output.type = MSResourceSoundcard; + io.output.soundcard = playcard; + }else{ + io.output.type = MSResourceFile; + io.output.file = recfile; + } + if (captcard){ + io.input.type = MSResourceSoundcard; + io.input.soundcard = captcard; + }else{ + io.input.type = MSResourceFile; + file_to_play = playfile; + io.input.file = NULL; /*we prefer to use the remote_play api, that allows to play multimedia files */ + } - media_stream_session_encryption_mandatory_enable(&call->audiostream->ms.sessions,linphone_core_is_media_encryption_mandatory(call->core)); + } + if (ok == TRUE) { + int err = audio_stream_start_from_io(call->audiostream, + call->audio_profile, + rtp_addr, + stream->rtp_port, + stream->rtcp_addr[0]!='\0' ? stream->rtcp_addr : call->resultdesc->addr, + (linphone_core_rtcp_enabled(lc) && !is_multicast) ? (stream->rtcp_port ? stream->rtcp_port : stream->rtp_port+1) : 0, + used_pt, + &io); + if (err == 0){ + post_configure_audio_streams(call, (call->all_muted || call->audio_muted) && !call->playing_ringbacktone); + } + } - if (stream->dir==SalStreamSendOnly && playfile!=NULL){ + ms_media_stream_sessions_set_encryption_mandatory(&call->audiostream->ms.sessions,linphone_core_is_media_encryption_mandatory(call->core)); + + if (next_state == LinphoneCallPaused && captcard == NULL && playfile != NULL){ int pause_time=500; ms_filter_call_method(call->audiostream->soundread,MS_FILE_PLAYER_LOOP,&pause_time); } - if (send_ringbacktone){ + if (call->playing_ringbacktone){ setup_ring_player(lc,call); } if (call->params->in_conference){ /*transform the graph to connect it to the conference filter */ - mute=stream->dir==SalStreamRecvOnly; + mute = stream->dir==SalStreamRecvOnly; linphone_call_add_to_conf(call, mute); } call->current_params->in_conference=call->params->in_conference; call->current_params->low_bandwidth=call->params->low_bandwidth; }else ms_warning("No audio stream accepted ?"); } + linphone_call_set_on_hold_file(call, file_to_play); } -static void linphone_call_start_video_stream(LinphoneCall *call, bool_t all_inputs_muted){ +#ifdef VIDEO_ENABLED +static RtpSession * create_video_rtp_io_session(LinphoneCall *call) { + PayloadType *pt; + LinphoneCore *lc = call->core; + const char *local_ip = lp_config_get_string(lc->config, "video", "rtp_local_addr", "127.0.0.1"); + const char *remote_ip = lp_config_get_string(lc->config, "video", "rtp_remote_addr", "127.0.0.1"); + int local_port = lp_config_get_int(lc->config, "video", "rtp_local_port", 19076); + int remote_port = lp_config_get_int(lc->config, "video", "rtp_remote_port", 19078); + int ptnum = lp_config_get_int(lc->config, "video", "rtp_ptnum", 0); + const char *rtpmap = lp_config_get_string(lc->config, "video", "rtp_map", "vp8/90000/1"); + int symmetric = lp_config_get_int(lc->config, "video", "rtp_symmetric", 0); + int jittcomp = lp_config_get_int(lc->config, "video", "rtp_jittcomp", 0); /* 0 means no jitter buffer*/ + RtpSession *rtp_session = NULL; + pt = rtp_profile_get_payload_from_rtpmap(call->video_profile, rtpmap); + if (pt != NULL) { + call->rtp_io_video_profile = rtp_profile_new("RTP IO video profile"); + rtp_profile_set_payload(call->rtp_io_video_profile, ptnum, payload_type_clone(pt)); + rtp_session = ms_create_duplex_rtp_session(local_ip, local_port, -1); + rtp_session_set_profile(rtp_session, call->rtp_io_video_profile); + rtp_session_set_remote_addr_and_port(rtp_session, remote_ip, remote_port, -1); + rtp_session_enable_rtcp(rtp_session, FALSE); + rtp_session_set_payload_type(rtp_session, ptnum); + rtp_session_set_symmetric_rtp(rtp_session, (bool_t)symmetric); + rtp_session_set_jitter_compensation(rtp_session, jittcomp); + rtp_session_enable_jitter_buffer(rtp_session, jittcomp>0); + } + return rtp_session; +} +#endif + +static void linphone_call_start_video_stream(LinphoneCall *call, LinphoneCallState next_state){ #ifdef VIDEO_ENABLED LinphoneCore *lc=call->core; int used_pt=-1; const SalStreamDescription *vstream; MSFilter* source = NULL; bool_t reused_preview = FALSE; - + bool_t use_rtp_io = lp_config_get_int(lc->config, "video", "rtp_io", FALSE); + MSMediaStreamIO io = MS_MEDIA_STREAM_IO_INITIALIZER; /* shutdown preview */ if (lc->previewstream!=NULL) { - if( lc->video_conf.reuse_preview_source == FALSE) video_preview_stop(lc->previewstream); else source = video_preview_stop_reuse_source(lc->previewstream); - lc->previewstream=NULL; } @@ -2675,9 +3160,10 @@ static void linphone_call_start_video_stream(LinphoneCall *call, bool_t all_inpu call->video_profile=make_profile(call,call->resultdesc,vstream,&used_pt); if (used_pt!=-1){ - VideoStreamDir dir=VideoStreamSendRecv; + MediaStreamDir dir= MediaStreamSendRecv; bool_t is_inactive=FALSE; MSWebCam *cam; + call->current_params->video_codec = rtp_profile_get_payload(call->video_profile, used_pt); call->current_params->has_video=TRUE; @@ -2686,64 +3172,66 @@ static void linphone_call_start_video_stream(LinphoneCall *call, bool_t all_inpu media_stream_set_adaptive_bitrate_algorithm(&call->videostream->ms, ms_qos_analyzer_algorithm_from_string(linphone_core_get_adaptive_rate_algorithm(lc))); video_stream_enable_adaptive_jittcomp(call->videostream, linphone_core_video_adaptive_jittcomp_enabled(lc)); + rtp_session_set_jitter_compensation(call->videostream->ms.sessions.rtp_session, linphone_core_get_video_jittcomp(lc)); + rtp_session_enable_rtcp_mux(call->videostream->ms.sessions.rtp_session, vstream->rtcp_mux); if (lc->video_conf.preview_vsize.width!=0) video_stream_set_preview_size(call->videostream,lc->video_conf.preview_vsize); video_stream_set_fps(call->videostream,linphone_core_get_preferred_framerate(lc)); + if (lp_config_get_int(lc->config, "video", "nowebcam_uses_normal_fps", 0)) + call->videostream->staticimage_webcam_fps_optimization = FALSE; video_stream_set_sent_video_size(call->videostream,linphone_core_get_preferred_video_size(lc)); video_stream_enable_self_view(call->videostream,lc->video_conf.selfview); - if (call->video_window_id != 0) - video_stream_set_native_window_id(call->videostream,call->video_window_id); - else if (lc->video_window_id!=0) - video_stream_set_native_window_id(call->videostream,lc->video_window_id); - if (lc->preview_window_id!=0) - video_stream_set_native_preview_window_id (call->videostream,lc->preview_window_id); + if (call->video_window_id != NULL) + video_stream_set_native_window_id(call->videostream, call->video_window_id); + else if (lc->video_window_id != NULL) + video_stream_set_native_window_id(call->videostream, lc->video_window_id); + if (lc->preview_window_id != NULL) + video_stream_set_native_preview_window_id(call->videostream, lc->preview_window_id); video_stream_use_preview_video_window (call->videostream,lc->use_preview_window); if (is_multicast){ if (vstream->multicast_role == SalMulticastReceiver) - dir=VideoStreamRecvOnly; + dir=MediaStreamRecvOnly; else - dir=VideoStreamSendOnly; + dir=MediaStreamSendOnly; } else if (vstream->dir==SalStreamSendOnly && lc->video_conf.capture ){ - dir=VideoStreamSendOnly; + dir=MediaStreamSendOnly; }else if (vstream->dir==SalStreamRecvOnly && lc->video_conf.display ){ - dir=VideoStreamRecvOnly; + dir=MediaStreamRecvOnly; }else if (vstream->dir==SalStreamSendRecv){ if (lc->video_conf.display && lc->video_conf.capture) - dir=VideoStreamSendRecv; + dir=MediaStreamSendRecv; else if (lc->video_conf.display) - dir=VideoStreamRecvOnly; + dir=MediaStreamRecvOnly; else - dir=VideoStreamSendOnly; + dir=MediaStreamSendOnly; }else{ ms_warning("video stream is inactive."); /*either inactive or incompatible with local capabilities*/ is_inactive=TRUE; } - if (all_inputs_muted){ - cam=get_nowebcam_device(); - } else { - cam = linphone_call_get_video_device(call); - } + cam = linphone_call_get_video_device(call); if (!is_inactive){ if (sal_stream_description_has_srtp(vstream) == TRUE) { int crypto_idx = find_crypto_index_from_tag(local_st_desc->crypto, vstream->crypto_local_tag); if (crypto_idx >= 0) { - media_stream_set_srtp_recv_key_b64(&(call->videostream->ms.sessions),vstream->crypto[0].algo,vstream->crypto[0].master_key); - media_stream_set_srtp_send_key_b64(&(call->videostream->ms.sessions),vstream->crypto[0].algo,local_st_desc->crypto[crypto_idx].master_key); + ms_media_stream_sessions_set_srtp_recv_key_b64(&call->videostream->ms.sessions, vstream->crypto[0].algo,vstream->crypto[0].master_key); + ms_media_stream_sessions_set_srtp_send_key_b64(&call->videostream->ms.sessions, vstream->crypto[0].algo,local_st_desc->crypto[crypto_idx].master_key); } } + configure_rtp_session_for_rtcp_fb(call, vstream); configure_rtp_session_for_rtcp_xr(lc, call, SalVideo); call->log->video_enabled = TRUE; video_stream_set_direction (call->videostream, dir); ms_message("%s lc rotation:%d\n", __FUNCTION__, lc->device_rotation); video_stream_set_device_rotation(call->videostream, lc->device_rotation); - video_stream_set_freeze_on_error(call->videostream, lp_config_get_int(lc->config, "video", "freeze_on_error", 0)); + video_stream_set_freeze_on_error(call->videostream, lp_config_get_int(lc->config, "video", "freeze_on_error", 1)); if (is_multicast) rtp_session_set_multicast_ttl(call->videostream->ms.sessions.rtp_session,vstream->ttl); - if( lc->video_conf.reuse_preview_source && source ){ + video_stream_use_video_preset(call->videostream, lp_config_get_string(lc->config, "video", "preset", NULL)); + if (lc->video_conf.reuse_preview_source && source) { ms_message("video_stream_start_with_source kept: %p", source); video_stream_start_with_source(call->videostream, call->video_profile, rtp_addr, vstream->rtp_port, @@ -2752,13 +3240,29 @@ static void linphone_call_start_video_stream(LinphoneCall *call, bool_t all_inpu used_pt, linphone_core_get_video_jittcomp(lc), cam, source); reused_preview = TRUE; } else { - video_stream_start(call->videostream, - call->video_profile, rtp_addr, vstream->rtp_port, - rtcp_addr, - (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); + bool_t ok = TRUE; + if (use_rtp_io) { + io.input.type = io.output.type = MSResourceRtp; + io.input.session = io.output.session = create_video_rtp_io_session(call); + if (io.input.session == NULL) { + ok = FALSE; + ms_warning("Cannot create video RTP IO session"); + } + } else { + io.input.type = MSResourceCamera; + io.input.camera = cam; + io.output.type = MSResourceDefault; + } + if (ok) { + video_stream_start_from_io(call->videostream, + call->video_profile, rtp_addr, vstream->rtp_port, + rtcp_addr, + (linphone_core_rtcp_enabled(lc) && !is_multicast) ? (vstream->rtcp_port ? vstream->rtcp_port : vstream->rtp_port+1) : 0, + used_pt, &io); + } } - media_stream_session_encryption_mandatory_enable(&call->videostream->ms.sessions,linphone_core_is_media_encryption_mandatory(call->core)); + ms_media_stream_sessions_set_encryption_mandatory(&call->videostream->ms.sessions,linphone_core_is_media_encryption_mandatory(call->core)); + _linphone_call_set_next_video_frame_decoded_trigger(call); } }else ms_warning("No video stream accepted."); }else{ @@ -2772,6 +3276,56 @@ static void linphone_call_start_video_stream(LinphoneCall *call, bool_t all_inpu #endif } +static void real_time_text_character_received(void *userdata, struct _MSFilter *f, unsigned int id, void *arg) { + if (id == MS_RTT_4103_RECEIVED_CHAR) { + LinphoneCall *call = (LinphoneCall *)userdata; + RealtimeTextReceivedCharacter *data = (RealtimeTextReceivedCharacter *)arg; + LinphoneChatRoom * chat_room = linphone_call_get_chat_room(call); + linphone_core_real_time_text_received(call->core, chat_room, data->character, call); + } +} + +static void linphone_call_start_text_stream(LinphoneCall *call) { + LinphoneCore *lc = call->core; + int used_pt = -1; + const SalStreamDescription *tstream; + + tstream = sal_media_description_find_best_stream(call->resultdesc, SalText); + if (tstream != NULL && tstream->dir != SalStreamInactive && tstream->rtp_port != 0) { + const char *rtp_addr = tstream->rtp_addr[0] != '\0' ? tstream->rtp_addr : call->resultdesc->addr; + const char *rtcp_addr = tstream->rtcp_addr[0] != '\0' ? tstream->rtcp_addr : call->resultdesc->addr; + const SalStreamDescription *local_st_desc = sal_media_description_find_stream(call->localdesc, tstream->proto, SalText); + bool_t is_multicast = ms_is_multicast(rtp_addr); + call->text_profile = make_profile(call, call->resultdesc, tstream, &used_pt); + + if (used_pt != -1) { + call->current_params->text_codec = rtp_profile_get_payload(call->text_profile, used_pt); + call->current_params->realtimetext_enabled = TRUE; + + if (sal_stream_description_has_srtp(tstream) == TRUE) { + int crypto_idx = find_crypto_index_from_tag(local_st_desc->crypto, tstream->crypto_local_tag); + if (crypto_idx >= 0) { + ms_media_stream_sessions_set_srtp_recv_key_b64(&call->textstream->ms.sessions, tstream->crypto[0].algo, tstream->crypto[0].master_key); + ms_media_stream_sessions_set_srtp_send_key_b64(&call->textstream->ms.sessions, tstream->crypto[0].algo, local_st_desc->crypto[crypto_idx].master_key); + } + } + + configure_rtp_session_for_rtcp_fb(call, tstream); + configure_rtp_session_for_rtcp_xr(lc, call, SalText); + rtp_session_enable_rtcp_mux(call->textstream->ms.sessions.rtp_session, tstream->rtcp_mux); + + if (is_multicast) rtp_session_set_multicast_ttl(call->textstream->ms.sessions.rtp_session,tstream->ttl); + + text_stream_start(call->textstream, call->text_profile, rtp_addr, tstream->rtp_port, rtcp_addr, (linphone_core_rtcp_enabled(lc) && !is_multicast) ? (tstream->rtcp_port ? tstream->rtcp_port : tstream->rtp_port + 1) : 0, used_pt); + ms_filter_add_notify_callback(call->textstream->rttsink, real_time_text_character_received, call, FALSE); + + ms_media_stream_sessions_set_encryption_mandatory(&call->textstream->ms.sessions,linphone_core_is_media_encryption_mandatory(call->core)); + } else ms_warning("No text stream accepted."); + } else { + ms_message("No valid text stream defined."); + } +} + static void setZrtpCryptoTypesParameters(MSZrtpParams *params, LinphoneCore *lc) { int i; @@ -2827,20 +3381,39 @@ static void setZrtpCryptoTypesParameters(MSZrtpParams *params, LinphoneCore *lc) params->keyAgreementsCount = linphone_core_get_zrtp_key_agreement_suites(lc, params->keyAgreements); } -void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_muted, bool_t send_ringbacktone){ +void linphone_call_start_media_streams(LinphoneCall *call, LinphoneCallState next_state){ LinphoneCore *lc=call->core; - bool_t use_arc=linphone_core_adaptive_rate_control_enabled(lc); + bool_t use_arc = linphone_core_adaptive_rate_control_enabled(lc); #ifdef VIDEO_ENABLED const SalStreamDescription *vstream=sal_media_description_find_best_stream(call->resultdesc,SalVideo); #endif + switch (next_state){ + case LinphoneCallIncomingEarlyMedia: + if (linphone_core_get_remote_ringback_tone(lc)){ + call->playing_ringbacktone = TRUE; + } + case LinphoneCallOutgoingEarlyMedia: + if (!call->params->real_early_media){ + call->all_muted = TRUE; + } + break; + default: + call->playing_ringbacktone = FALSE; + call->all_muted = FALSE; + break; + } + call->current_params->audio_codec = NULL; call->current_params->video_codec = NULL; + call->current_params->text_codec = NULL; if ((call->audiostream == NULL) && (call->videostream == NULL)) { ms_fatal("start_media_stream() called without prior init !"); return; } + + call->nb_media_starts++; #if defined(VIDEO_ENABLED) if (vstream!=NULL && vstream->dir!=SalStreamInactive && vstream->payloads!=NULL){ /*when video is used, do not make adaptive rate control on audio, it is stupid.*/ @@ -2851,18 +3424,23 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut call, linphone_core_get_upload_bandwidth(lc),linphone_core_get_download_bandwidth(lc)); if (call->audiostream!=NULL) { - linphone_call_start_audio_stream(call,all_inputs_muted||call->audio_muted,send_ringbacktone,use_arc); + linphone_call_start_audio_stream(call, next_state, use_arc); } else { ms_warning("DTLS no audio stream!"); } call->current_params->has_video=FALSE; if (call->videostream!=NULL) { if (call->audiostream) audio_stream_link_video(call->audiostream,call->videostream); - linphone_call_start_video_stream(call,all_inputs_muted); + linphone_call_start_video_stream(call, next_state); + } + /*the onhold file is to be played once both audio and video are ready.*/ + if (call->onhold_file && !call->params->in_conference && call->audiostream){ + MSFilter *player = audio_stream_open_remote_play(call->audiostream, call->onhold_file); + if (player){ + ms_filter_call_method_noarg(player, MS_PLAYER_START); + } } - call->all_muted=all_inputs_muted; - call->playing_ringbacktone=send_ringbacktone; call->up_bw=linphone_core_get_upload_bandwidth(lc); /*might be moved in audio/video stream_start*/ @@ -2883,6 +3461,10 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut #endif } + if (call->params->realtimetext_enabled) { + linphone_call_start_text_stream(call); + } + set_dtls_fingerprint_on_all_streams(call); if ((call->ice_session != NULL) && (ice_session_state(call->ice_session) != IS_Completed)) { @@ -2901,15 +3483,18 @@ void linphone_call_stop_media_streams_for_ice_gathering(LinphoneCall *call){ video_stream_unprepare_video(call->videostream); } #endif + if (call->textstream && call->textstream->ms.state == MSStreamPreparing) { + text_stream_unprepare_text(call->textstream); + } } static bool_t update_stream_crypto_params(LinphoneCall *call, const SalStreamDescription *local_st_desc, SalStreamDescription *old_stream, SalStreamDescription *new_stream, MediaStream *ms){ int crypto_idx = find_crypto_index_from_tag(local_st_desc->crypto, new_stream->crypto_local_tag); if (crypto_idx >= 0) { if (call->localdesc_changed & SAL_MEDIA_DESCRIPTION_CRYPTO_KEYS_CHANGED) - media_stream_set_srtp_send_key_b64(&(ms->sessions),new_stream->crypto[0].algo,local_st_desc->crypto[crypto_idx].master_key); + ms_media_stream_sessions_set_srtp_send_key_b64(&ms->sessions, new_stream->crypto[0].algo,local_st_desc->crypto[crypto_idx].master_key); if (strcmp(old_stream->crypto[0].master_key,new_stream->crypto[0].master_key)!=0){ - media_stream_set_srtp_recv_key_b64(&(ms->sessions),new_stream->crypto[0].algo,new_stream->crypto[0].master_key); + ms_media_stream_sessions_set_srtp_recv_key_b64(&ms->sessions, new_stream->crypto[0].algo,new_stream->crypto[0].master_key); } return TRUE; } else { @@ -2930,6 +3515,13 @@ void linphone_call_update_crypto_parameters(LinphoneCall *call, SalMediaDescript update_stream_crypto_params(call,local_st_desc,old_stream,new_stream,&call->audiostream->ms)){ } + local_st_desc = sal_media_description_find_secure_stream_of_type(call->localdesc, SalText); + old_stream = sal_media_description_find_secure_stream_of_type(old_md, SalText); + new_stream = sal_media_description_find_secure_stream_of_type(new_md, SalText); + if (call->textstream && local_st_desc && old_stream && new_stream && + update_stream_crypto_params(call,local_st_desc,old_stream,new_stream,&call->textstream->ms)){ + } + start_dtls_on_all_streams(call); #ifdef VIDEO_ENABLED @@ -2956,8 +3548,10 @@ void linphone_call_delete_ice_session(LinphoneCall *call){ call->ice_session = NULL; if (call->audiostream != NULL) call->audiostream->ms.ice_check_list = NULL; if (call->videostream != NULL) call->videostream->ms.ice_check_list = NULL; + if (call->textstream != NULL) call->textstream->ms.ice_check_list = NULL; call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateNotActivated; call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateNotActivated; + call->stats[LINPHONE_CALL_STATS_TEXT].ice_state = LinphoneIceStateNotActivated; } } @@ -2976,18 +3570,29 @@ static void linphone_call_log_fill_stats(LinphoneCallLog *log, MediaStream *st){ float quality=media_stream_get_average_quality_rating(st); if (quality>=0){ if (log->quality!=-1){ - log->quality*=quality/5.0; + log->quality*=quality/5.0f; }else log->quality=quality; } } +static void update_rtp_stats(LinphoneCall *call, int stream_index) { + if (stream_index >= linphone_call_get_stream_count(call)) { + return; + } + + if (call->sessions[stream_index].rtp_session) { + const rtp_stats_t *stats = rtp_session_get_stats(call->sessions[stream_index].rtp_session); + memcpy(&call->stats[stream_index].rtp_stats, stats, sizeof(*stats)); + } +} + static void linphone_call_stop_audio_stream(LinphoneCall *call) { if (call->audiostream!=NULL) { linphone_reporting_update_media_info(call, LINPHONE_CALL_STATS_AUDIO); - media_stream_reclaim_sessions(&call->audiostream->ms,&call->sessions[0]); + media_stream_reclaim_sessions(&call->audiostream->ms,&call->sessions[call->main_audio_stream_index]); if (call->audiostream->ec){ - const char *state_str=NULL; + char *state_str=NULL; ms_filter_call_method(call->audiostream->ec,MS_ECHO_CANCELLER_GET_STATE_STRING,&state_str); if (state_str){ ms_message("Writing echo canceler state, %i bytes",(int)strlen(state_str)); @@ -2999,12 +3604,15 @@ static void linphone_call_stop_audio_stream(LinphoneCall *call) { if (call->endpoint){ linphone_call_remove_from_conf(call); } + update_rtp_stats(call, call->main_audio_stream_index); audio_stream_stop(call->audiostream); - rtp_session_unregister_event_queue(call->sessions[0].rtp_session, call->audiostream_app_evq); + call->audiostream=NULL; + linphone_call_handle_stream_events(call, call->main_audio_stream_index); + rtp_session_unregister_event_queue(call->sessions[call->main_audio_stream_index].rtp_session, call->audiostream_app_evq); ortp_ev_queue_flush(call->audiostream_app_evq); ortp_ev_queue_destroy(call->audiostream_app_evq); call->audiostream_app_evq=NULL; - call->audiostream=NULL; + call->current_params->audio_codec = NULL; } } @@ -3013,11 +3621,13 @@ static void linphone_call_stop_video_stream(LinphoneCall *call) { #ifdef VIDEO_ENABLED if (call->videostream!=NULL){ linphone_reporting_update_media_info(call, LINPHONE_CALL_STATS_VIDEO); - media_stream_reclaim_sessions(&call->videostream->ms,&call->sessions[1]); + media_stream_reclaim_sessions(&call->videostream->ms,&call->sessions[call->main_video_stream_index]); linphone_call_log_fill_stats(call->log,(MediaStream*)call->videostream); + update_rtp_stats(call, call->main_video_stream_index); video_stream_stop(call->videostream); call->videostream=NULL; - rtp_session_unregister_event_queue(call->sessions[1].rtp_session, call->videostream_app_evq); + linphone_call_handle_stream_events(call, call->main_video_stream_index); + rtp_session_unregister_event_queue(call->sessions[call->main_video_stream_index].rtp_session, call->videostream_app_evq); ortp_ev_queue_flush(call->videostream_app_evq); ortp_ev_queue_destroy(call->videostream_app_evq); call->videostream_app_evq=NULL; @@ -3031,12 +3641,30 @@ static void unset_rtp_profile(LinphoneCall *call, int i){ rtp_session_set_profile(call->sessions[i].rtp_session,&av_profile); } +static void linphone_call_stop_text_stream(LinphoneCall *call) { + if (call->textstream != NULL) { + linphone_reporting_update_media_info(call, LINPHONE_CALL_STATS_TEXT); + media_stream_reclaim_sessions(&call->textstream->ms, &call->sessions[call->main_text_stream_index]); + linphone_call_log_fill_stats(call->log, (MediaStream*)call->textstream); + text_stream_stop(call->textstream); + call->textstream = NULL; + update_rtp_stats(call, call->main_text_stream_index); + linphone_call_handle_stream_events(call, call->main_video_stream_index); + rtp_session_unregister_event_queue(call->sessions[call->main_text_stream_index].rtp_session, call->textstream_app_evq); + ortp_ev_queue_flush(call->textstream_app_evq); + ortp_ev_queue_destroy(call->textstream_app_evq); + call->textstream_app_evq = NULL; + call->current_params->text_codec = NULL; + } +} + void linphone_call_stop_media_streams(LinphoneCall *call){ - if (call->audiostream || call->videostream) { + if (call->audiostream || call->videostream || call->textstream) { if (call->audiostream && call->videostream) audio_stream_unlink_video(call->audiostream, call->videostream); linphone_call_stop_audio_stream(call); linphone_call_stop_video_stream(call); + linphone_call_stop_text_stream(call); if (call->core->msevq != NULL) { ms_event_queue_skip(call->core->msevq); @@ -3046,13 +3674,28 @@ void linphone_call_stop_media_streams(LinphoneCall *call){ if (call->audio_profile){ rtp_profile_destroy(call->audio_profile); call->audio_profile=NULL; - unset_rtp_profile(call,0); + unset_rtp_profile(call,call->main_audio_stream_index); } if (call->video_profile){ rtp_profile_destroy(call->video_profile); call->video_profile=NULL; - unset_rtp_profile(call,1); + unset_rtp_profile(call,call->main_video_stream_index); } + if (call->text_profile){ + rtp_profile_destroy(call->text_profile); + call->text_profile=NULL; + unset_rtp_profile(call,call->main_text_stream_index); + } + if (call->rtp_io_audio_profile) { + rtp_profile_destroy(call->rtp_io_audio_profile); + call->rtp_io_audio_profile = NULL; + } + if (call->rtp_io_video_profile) { + rtp_profile_destroy(call->rtp_io_video_profile); + call->rtp_io_video_profile = NULL; + } + + linphone_core_soundcard_hint_check(call->core); } @@ -3130,6 +3773,32 @@ float linphone_call_get_record_volume(LinphoneCall *call){ return LINPHONE_VOLUME_DB_LOWEST; } +float linphone_call_get_speaker_volume_gain(const LinphoneCall *call) { + if(call->audiostream) return audio_stream_get_sound_card_output_gain(call->audiostream); + else { + ms_error("Could not get playback volume: no audio stream"); + return -1.0f; + } +} + +void linphone_call_set_speaker_volume_gain(LinphoneCall *call, float volume) { + if(call->audiostream) audio_stream_set_sound_card_output_gain(call->audiostream, volume); + else ms_error("Could not set playback volume: no audio stream"); +} + +float linphone_call_get_microphone_volume_gain(const LinphoneCall *call) { + if(call->audiostream) return audio_stream_get_sound_card_input_gain(call->audiostream); + else { + ms_error("Could not get record volume: no audio stream"); + return -1.0f; + } +} + +void linphone_call_set_microphone_volume_gain(LinphoneCall *call, float volume) { + if(call->audiostream) audio_stream_set_sound_card_input_gain(call->audiostream, volume); + else ms_error("Could not set record volume: no audio stream"); +} + /** * Obtain real-time quality rating of the call * @@ -3148,19 +3817,19 @@ float linphone_call_get_record_volume(LinphoneCall *call){ * active audio stream exist. Otherwise it returns the quality rating. **/ float linphone_call_get_current_quality(LinphoneCall *call){ - float audio_rating=-1; - float video_rating=-1; + float audio_rating=-1.f; + float video_rating=-1.f; float result; if (call->audiostream){ - audio_rating=media_stream_get_quality_rating((MediaStream*)call->audiostream)/5.0; + audio_rating=media_stream_get_quality_rating((MediaStream*)call->audiostream)/5.0f; } if (call->videostream){ - video_rating=media_stream_get_quality_rating((MediaStream*)call->videostream)/5.0; + video_rating=media_stream_get_quality_rating((MediaStream*)call->videostream)/5.0f; } if (audio_rating<0 && video_rating<0) result=-1; - else if (audio_rating<0) result=video_rating*5.0; - else if (video_rating<0) result=audio_rating*5.0; - else result=audio_rating*video_rating*5.0; + else if (audio_rating<0) result=video_rating*5.0f; + else if (video_rating<0) result=audio_rating*5.0f; + else result=audio_rating*video_rating*5.0f; return result; } @@ -3176,19 +3845,20 @@ float linphone_call_get_average_quality(LinphoneCall *call){ return -1; } -static void update_local_stats(LinphoneCallStats *stats, MediaStream *stream){ - const MSQualityIndicator *qi=media_stream_get_quality_indicator(stream); +static void update_local_stats(LinphoneCallStats *stats, MediaStream *stream) { + const MSQualityIndicator *qi = media_stream_get_quality_indicator(stream); if (qi) { stats->local_late_rate=ms_quality_indicator_get_local_late_rate(qi); stats->local_loss_rate=ms_quality_indicator_get_local_loss_rate(qi); } + media_stream_get_local_rtp_stats(stream, &stats->rtp_stats); } /** * Access last known statistics for audio stream, for a given call. **/ const LinphoneCallStats *linphone_call_get_audio_stats(LinphoneCall *call) { - LinphoneCallStats *stats=&call->stats[LINPHONE_CALL_STATS_AUDIO]; + LinphoneCallStats *stats = &call->stats[LINPHONE_CALL_STATS_AUDIO]; if (call->audiostream){ update_local_stats(stats,(MediaStream*)call->audiostream); } @@ -3199,13 +3869,24 @@ const LinphoneCallStats *linphone_call_get_audio_stats(LinphoneCall *call) { * Access last known statistics for video stream, for a given call. **/ const LinphoneCallStats *linphone_call_get_video_stats(LinphoneCall *call) { - LinphoneCallStats *stats=&call->stats[LINPHONE_CALL_STATS_VIDEO]; + LinphoneCallStats *stats = &call->stats[LINPHONE_CALL_STATS_VIDEO]; if (call->videostream){ update_local_stats(stats,(MediaStream*)call->videostream); } return stats; } +/** + * Access last known statistics for video stream, for a given call. +**/ +const LinphoneCallStats *linphone_call_get_text_stats(LinphoneCall *call) { + LinphoneCallStats *stats = &call->stats[LINPHONE_CALL_STATS_TEXT]; + if (call->textstream){ + update_local_stats(stats,(MediaStream*)call->textstream); + } + return stats; +} + static bool_t ice_in_progress(LinphoneCallStats *stats){ return stats->ice_state==LinphoneIceStateInProgress; } @@ -3221,7 +3902,7 @@ static bool_t ice_in_progress(LinphoneCallStats *stats){ **/ bool_t linphone_call_media_in_progress(LinphoneCall *call){ bool_t ret=FALSE; - if (ice_in_progress(&call->stats[LINPHONE_CALL_STATS_AUDIO]) || ice_in_progress(&call->stats[LINPHONE_CALL_STATS_VIDEO])) + if (ice_in_progress(&call->stats[LINPHONE_CALL_STATS_AUDIO]) || ice_in_progress(&call->stats[LINPHONE_CALL_STATS_VIDEO]) || ice_in_progress(&call->stats[LINPHONE_CALL_STATS_TEXT])) ret=TRUE; /*TODO: could check zrtp state, upnp state*/ return ret; @@ -3245,7 +3926,7 @@ float linphone_call_stats_get_sender_loss_rate(const LinphoneCallStats *stats) { srb = rtcp_RR_get_report_block(stats->sent_rtcp, 0); if (!srb) return 0.0; - return 100.0 * report_block_get_fraction_lost(srb) / 256.0; + return 100.0f * report_block_get_fraction_lost(srb) / 256.0f; } /** @@ -3266,7 +3947,7 @@ float linphone_call_stats_get_receiver_loss_rate(const LinphoneCallStats *stats) rrb = rtcp_SR_get_report_block(stats->received_rtcp, 0); if (!rrb) return 0.0; - return 100.0 * report_block_get_fraction_lost(rrb) / 256.0; + return 100.0f * report_block_get_fraction_lost(rrb) / 256.0f; } /** @@ -3333,18 +4014,14 @@ float linphone_call_stats_get_receiver_interarrival_jitter(const LinphoneCallSta return (float)report_block_get_interarrival_jitter(rrb) / (float)pt->clock_rate; } -rtp_stats_t linphone_call_stats_get_rtp_stats(const LinphoneCallStats *stats, LinphoneCall *call) { +rtp_stats_t linphone_call_stats_get_rtp_stats(const LinphoneCallStats *stats) { rtp_stats_t rtp_stats; memset(&rtp_stats, 0, sizeof(rtp_stats)); - if (stats && call) { - if (stats->type == LINPHONE_CALL_STATS_AUDIO && call->audiostream != NULL) - audio_stream_get_local_rtp_stats(call->audiostream, &rtp_stats); - #ifdef VIDEO_ENABLED - else if (call->videostream != NULL) - video_stream_get_local_rtp_stats(call->videostream, &rtp_stats); - #endif + if (stats) { + memcpy(&rtp_stats, &stats->rtp_stats, sizeof(stats->rtp_stats)); } + return rtp_stats; } @@ -3353,7 +4030,7 @@ rtp_stats_t linphone_call_stats_get_rtp_stats(const LinphoneCallStats *stats, Li * @return The cumulative number of late packets **/ uint64_t linphone_call_stats_get_late_packets_cumulative_number(const LinphoneCallStats *stats, LinphoneCall *call) { - return linphone_call_stats_get_rtp_stats(stats, call).outoftime; + return linphone_call_stats_get_rtp_stats(stats).outoftime; } /** @@ -3421,58 +4098,80 @@ void linphone_call_stop_recording(LinphoneCall *call){ * @} **/ -static void report_bandwidth(LinphoneCall *call, MediaStream *as, MediaStream *vs){ +static void report_bandwidth(LinphoneCall *call, MediaStream *as, MediaStream *vs, MediaStream *ts){ bool_t as_active = as ? (media_stream_get_state(as) == MSStreamStarted) : FALSE; bool_t vs_active = vs ? (media_stream_get_state(vs) == MSStreamStarted) : FALSE; + bool_t ts_active = ts ? (media_stream_get_state(ts) == 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; - call->stats[LINPHONE_CALL_STATS_VIDEO].upload_bandwidth=(vs_active) ? (media_stream_get_up_bw(vs)*1e-3) : 0; - call->stats[LINPHONE_CALL_STATS_AUDIO].rtcp_download_bandwidth=(as_active) ? (media_stream_get_rtcp_down_bw(as)*1e-3) : 0; - call->stats[LINPHONE_CALL_STATS_AUDIO].rtcp_upload_bandwidth=(as_active) ? (media_stream_get_rtcp_up_bw(as)*1e-3) : 0; - 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; - if (as_active) { - call->stats[LINPHONE_CALL_STATS_AUDIO].updated|=LINPHONE_CALL_STATS_PERIODICAL_UPDATE; - linphone_core_notify_call_stats_updated(call->core, call, &call->stats[LINPHONE_CALL_STATS_AUDIO]); - call->stats[LINPHONE_CALL_STATS_AUDIO].updated=0; - } - if (vs_active) { - call->stats[LINPHONE_CALL_STATS_VIDEO].updated|=LINPHONE_CALL_STATS_PERIODICAL_UPDATE; - linphone_core_notify_call_stats_updated(call->core, call, &call->stats[LINPHONE_CALL_STATS_VIDEO]); - call->stats[LINPHONE_CALL_STATS_VIDEO].updated=0; + call->stats[LINPHONE_CALL_STATS_AUDIO].download_bandwidth=(as_active) ? (float)(media_stream_get_down_bw(as)*1e-3) : 0.f; + call->stats[LINPHONE_CALL_STATS_AUDIO].upload_bandwidth=(as_active) ? (float)(media_stream_get_up_bw(as)*1e-3) : 0.f; + call->stats[LINPHONE_CALL_STATS_VIDEO].download_bandwidth=(vs_active) ? (float)(media_stream_get_down_bw(vs)*1e-3) : 0.f; + call->stats[LINPHONE_CALL_STATS_VIDEO].upload_bandwidth=(vs_active) ? (float)(media_stream_get_up_bw(vs)*1e-3) : 0.f; + call->stats[LINPHONE_CALL_STATS_TEXT].download_bandwidth=(ts_active) ? (float)(media_stream_get_down_bw(ts)*1e-3) : 0.f; + call->stats[LINPHONE_CALL_STATS_TEXT].upload_bandwidth=(ts_active) ? (float)(media_stream_get_up_bw(ts)*1e-3) : 0.f; + call->stats[LINPHONE_CALL_STATS_AUDIO].rtcp_download_bandwidth=(as_active) ? (float)(media_stream_get_rtcp_down_bw(as)*1e-3) : 0.f; + call->stats[LINPHONE_CALL_STATS_AUDIO].rtcp_upload_bandwidth=(as_active) ? (float)(media_stream_get_rtcp_up_bw(as)*1e-3) : 0.f; + call->stats[LINPHONE_CALL_STATS_VIDEO].rtcp_download_bandwidth=(vs_active) ? (float)(media_stream_get_rtcp_down_bw(vs)*1e-3) : 0.f; + call->stats[LINPHONE_CALL_STATS_VIDEO].rtcp_upload_bandwidth=(vs_active) ? (float)(media_stream_get_rtcp_up_bw(vs)*1e-3) : 0.f; + call->stats[LINPHONE_CALL_STATS_TEXT].rtcp_download_bandwidth=(ts_active) ? (float)(media_stream_get_rtcp_down_bw(ts)*1e-3) : 0.f; + call->stats[LINPHONE_CALL_STATS_TEXT].rtcp_upload_bandwidth=(ts_active) ? (float)(media_stream_get_rtcp_up_bw(ts)*1e-3) : 0.f; + + call->stats[LINPHONE_CALL_STATS_AUDIO].updated|=LINPHONE_CALL_STATS_PERIODICAL_UPDATE; + linphone_core_notify_call_stats_updated(call->core, call, &call->stats[LINPHONE_CALL_STATS_AUDIO]); + call->stats[LINPHONE_CALL_STATS_AUDIO].updated=0; + if (as) update_local_stats(&call->stats[LINPHONE_CALL_STATS_AUDIO], as); + + call->stats[LINPHONE_CALL_STATS_VIDEO].updated|=LINPHONE_CALL_STATS_PERIODICAL_UPDATE; + linphone_core_notify_call_stats_updated(call->core, call, &call->stats[LINPHONE_CALL_STATS_VIDEO]); + call->stats[LINPHONE_CALL_STATS_VIDEO].updated=0; + if (vs) update_local_stats(&call->stats[LINPHONE_CALL_STATS_VIDEO], vs); + + call->stats[LINPHONE_CALL_STATS_TEXT].updated|=LINPHONE_CALL_STATS_PERIODICAL_UPDATE; + linphone_core_notify_call_stats_updated(call->core, call, &call->stats[LINPHONE_CALL_STATS_TEXT]); + call->stats[LINPHONE_CALL_STATS_TEXT].updated=0; + if (ts) update_local_stats(&call->stats[LINPHONE_CALL_STATS_TEXT], ts); - } 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", + "\tRTP audio=[d=%5.1f,u=%5.1f], video=[d=%5.1f,u=%5.1f], text=[d=%5.1f,u=%5.1f] kbits/sec\n" + "\tRTCP audio=[d=%5.1f,u=%5.1f], video=[d=%5.1f,u=%5.1f], text=[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_TEXT].download_bandwidth, + call->stats[LINPHONE_CALL_STATS_TEXT].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 + call->stats[LINPHONE_CALL_STATS_VIDEO].rtcp_upload_bandwidth, + call->stats[LINPHONE_CALL_STATS_TEXT].rtcp_download_bandwidth, + call->stats[LINPHONE_CALL_STATS_TEXT].rtcp_upload_bandwidth ); } -static void linphone_core_disconnected(LinphoneCore *lc, LinphoneCall *call){ - char temp[256]={0}; +static void linphone_call_lost(LinphoneCall *call, LinphoneReason reason){ + LinphoneCore *lc = call->core; + char *temp = NULL; char *from=NULL; from = linphone_call_get_remote_address_as_string(call); - snprintf(temp,sizeof(temp)-1,"Remote end %s seems to have disconnected, the call is going to be closed.",from ? from : ""); + switch(reason){ + case LinphoneReasonIOError: + temp = ms_strdup_printf("Call with %s disconnected because of network, it is going to be closed.", from ? from : "?"); + break; + default: + temp = ms_strdup_printf("Media connectivity with %s is lost, call is going to be closed.", from ? from : "?"); + break; + } if (from) ms_free(from); - - ms_message("On call [%p]: %s",call,temp); - linphone_core_notify_display_warning(lc,temp); + ms_message("LinphoneCall [%p]: %s",call, temp); + linphone_core_notify_display_warning(lc, temp); linphone_core_terminate_call(lc,call); linphone_core_play_named_tone(lc,LinphoneToneCallLost); + ms_free(temp); } static void change_ice_media_destinations(LinphoneCall *call) { @@ -3482,8 +4181,8 @@ static void change_ice_media_destinations(LinphoneCall *call) { int rtcp_port; bool_t result; - if (call->audiostream && ice_session_check_list(call->ice_session, 0)) { - result = ice_check_list_selected_valid_remote_candidate(ice_session_check_list(call->ice_session, 0), &rtp_addr, &rtp_port, &rtcp_addr, &rtcp_port); + if (call->audiostream && ice_session_check_list(call->ice_session, call->main_audio_stream_index)) { + result = ice_check_list_selected_valid_remote_candidate(ice_session_check_list(call->ice_session, call->main_audio_stream_index), &rtp_addr, &rtp_port, &rtcp_addr, &rtcp_port); if (result == TRUE) { ms_message("Change audio stream destination: RTP=%s:%d RTCP=%s:%d", rtp_addr, rtp_port, rtcp_addr, rtcp_port); rtp_session_set_symmetric_rtp(call->audiostream->ms.sessions.rtp_session, FALSE); @@ -3491,8 +4190,8 @@ static void change_ice_media_destinations(LinphoneCall *call) { } } #ifdef VIDEO_ENABLED - if (call->videostream && ice_session_check_list(call->ice_session, 1)) { - result = ice_check_list_selected_valid_remote_candidate(ice_session_check_list(call->ice_session, 1), &rtp_addr, &rtp_port, &rtcp_addr, &rtcp_port); + if (call->videostream && ice_session_check_list(call->ice_session, call->main_video_stream_index)) { + result = ice_check_list_selected_valid_remote_candidate(ice_session_check_list(call->ice_session, call->main_video_stream_index), &rtp_addr, &rtp_port, &rtcp_addr, &rtcp_port); if (result == TRUE) { ms_message("Change video stream destination: RTP=%s:%d RTCP=%s:%d", rtp_addr, rtp_port, rtcp_addr, rtcp_port); rtp_session_set_symmetric_rtp(call->videostream->ms.sessions.rtp_session, FALSE); @@ -3500,12 +4199,34 @@ static void change_ice_media_destinations(LinphoneCall *call) { } } #endif + if (call->textstream && ice_session_check_list(call->ice_session, call->main_text_stream_index)) { + result = ice_check_list_selected_valid_remote_candidate(ice_session_check_list(call->ice_session, call->main_text_stream_index), &rtp_addr, &rtp_port, &rtcp_addr, &rtcp_port); + if (result == TRUE) { + ms_message("Change text stream destination: RTP=%s:%d RTCP=%s:%d", rtp_addr, rtp_port, rtcp_addr, rtcp_port); + rtp_session_set_symmetric_rtp(call->textstream->ms.sessions.rtp_session, FALSE); + rtp_session_set_remote_addr_full(call->textstream->ms.sessions.rtp_session, rtp_addr, rtp_port, rtcp_addr, rtcp_port); + } + } +} + +static void linphone_call_on_ice_gathering_finished(LinphoneCall *call){ + int ping_time; + const SalMediaDescription *rmd = sal_call_get_remote_media_description(call->op); + if (rmd){ + linphone_call_clear_unused_ice_candidates(call, rmd); + } + ice_session_compute_candidates_foundations(call->ice_session); + ice_session_eliminate_redundant_candidates(call->ice_session); + ice_session_choose_default_candidates(call->ice_session); + ping_time = ice_session_average_gathering_round_trip_time(call->ice_session); + if (ping_time >=0) { + call->ping_time=ping_time; + } } static void handle_ice_events(LinphoneCall *call, OrtpEvent *ev){ OrtpEventType evt=ortp_event_get_type(ev); OrtpEventData *evd=ortp_event_get_data(ev); - int ping_time; if (evt == ORTP_EVENT_ICE_SESSION_PROCESSING_FINISHED) { LinphoneCallParams *params = linphone_call_params_copy(call->current_params); @@ -3550,13 +4271,7 @@ static void handle_ice_events(LinphoneCall *call, OrtpEvent *ev){ } else if (evt == ORTP_EVENT_ICE_GATHERING_FINISHED) { if (evd->info.ice_processing_successful==TRUE) { - ice_session_compute_candidates_foundations(call->ice_session); - ice_session_eliminate_redundant_candidates(call->ice_session); - ice_session_choose_default_candidates(call->ice_session); - ping_time = ice_session_average_gathering_round_trip_time(call->ice_session); - if (ping_time >=0) { - call->ping_time=ping_time; - } + linphone_call_on_ice_gathering_finished(call); } else { ms_warning("No STUN answer from [%s], disabling ICE",linphone_core_get_stun_server(call->core)); linphone_call_delete_ice_session(call); @@ -3604,6 +4319,7 @@ void linphone_call_stats_fill(LinphoneCallStats *stats, MediaStream *ms, OrtpEve if(stats->received_rtcp != NULL) freemsg(stats->received_rtcp); stats->received_rtcp = evd->packet; + stats->rtcp_received_via_mux = evd->info.socket_type == OrtpRTPSocket; evd->packet = NULL; stats->updated = LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE; update_local_stats(stats,ms); @@ -3630,15 +4346,16 @@ void linphone_call_stats_uninit(LinphoneCallStats *stats){ } void linphone_call_notify_stats_updated(LinphoneCall *call, int stream_index){ - LinphoneCallStats *stats=&call->stats[stream_index]; - LinphoneCore *lc=call->core; + LinphoneCallStats *stats = &call->stats[stream_index]; + LinphoneCore *lc = call->core; if (stats->updated){ switch(stats->updated) { case LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE: case LINPHONE_CALL_STATS_SENT_RTCP_UPDATE: - linphone_reporting_on_rtcp_update(call, stream_index); + linphone_reporting_on_rtcp_update(call, stream_index == call->main_audio_stream_index ? SalAudio : stream_index == call->main_video_stream_index ? SalVideo : SalText); + break; + default: break; - default:break; } linphone_core_notify_call_stats_updated(lc, call, stats); stats->updated = 0; @@ -3646,54 +4363,59 @@ void linphone_call_notify_stats_updated(LinphoneCall *call, int stream_index){ } void linphone_call_handle_stream_events(LinphoneCall *call, int stream_index){ - MediaStream *ms=stream_index==0 ? (MediaStream *)call->audiostream : (MediaStream *)call->videostream; /*assumption to remove*/ + MediaStream *ms = stream_index == call->main_audio_stream_index ? (MediaStream *)call->audiostream : (stream_index == call->main_video_stream_index ? (MediaStream *)call->videostream : (MediaStream *)call->textstream); OrtpEvQueue *evq; OrtpEvent *ev; - if (ms==NULL) return; - /* Ensure there is no dangling ICE check list. */ - if (call->ice_session == NULL) ms->ice_check_list = NULL; + if (ms){ + /* Ensure there is no dangling ICE check list. */ + if (call->ice_session == NULL) ms->ice_check_list = NULL; - switch(ms->type){ - case AudioStreamType: - audio_stream_iterate((AudioStream*)ms); - break; - case VideoStreamType: -#ifdef VIDEO_ENABLED - video_stream_iterate((VideoStream*)ms); -#endif - break; - default: - ms_error("linphone_call_handle_stream_events(): unsupported stream type."); - return; - break; + switch(ms->type){ + case MSAudio: + audio_stream_iterate((AudioStream*)ms); + break; + case MSVideo: + #ifdef VIDEO_ENABLED + video_stream_iterate((VideoStream*)ms); + #endif + break; + case MSText: + text_stream_iterate((TextStream*)ms); + break; + default: + ms_error("linphone_call_handle_stream_events(): unsupported stream type."); + return; + break; + } } /*yes the event queue has to be taken at each iteration, because ice events may perform operations re-creating the streams*/ - while ((evq=stream_index==0 ? call->audiostream_app_evq : call->videostream_app_evq) && (NULL != (ev=ortp_ev_queue_get(evq)))){ + while ((evq = stream_index == call->main_audio_stream_index ? call->audiostream_app_evq : (stream_index == call->main_video_stream_index ? call->videostream_app_evq : call->textstream_app_evq)) && (NULL != (ev=ortp_ev_queue_get(evq)))){ OrtpEventType evt=ortp_event_get_type(ev); OrtpEventData *evd=ortp_event_get_data(ev); - linphone_call_stats_fill(&call->stats[stream_index],ms,ev); - linphone_call_notify_stats_updated(call,stream_index); + int stats_index = stream_index == call->main_audio_stream_index ? LINPHONE_CALL_STATS_AUDIO : (stream_index == call->main_video_stream_index ? LINPHONE_CALL_STATS_VIDEO : LINPHONE_CALL_STATS_TEXT); + if (ms) linphone_call_stats_fill(&call->stats[stats_index],ms,ev); + linphone_call_notify_stats_updated(call,stats_index); if (evt == ORTP_EVENT_ZRTP_ENCRYPTION_CHANGED){ - if (ms->type==AudioStreamType) + if (stream_index == call->main_audio_stream_index) linphone_call_audiostream_encryption_changed(call, evd->info.zrtp_stream_encrypted); - else if (ms->type==VideoStreamType) + else if (stream_index == call->main_video_stream_index) propagate_encryption_changed(call); } else if (evt == ORTP_EVENT_ZRTP_SAS_READY) { - if (ms->type==AudioStreamType) + if (stream_index == call->main_audio_stream_index) linphone_call_audiostream_auth_token_ready(call, evd->info.zrtp_sas.sas, evd->info.zrtp_sas.verified); } else if (evt == ORTP_EVENT_DTLS_ENCRYPTION_CHANGED) { - if (ms->type==AudioStreamType) + if (stream_index == call->main_audio_stream_index) linphone_call_audiostream_encryption_changed(call, evd->info.dtls_stream_encrypted); - else if (ms->type==VideoStreamType) + else if (stream_index == call->main_video_stream_index) propagate_encryption_changed(call); }else if ((evt == ORTP_EVENT_ICE_SESSION_PROCESSING_FINISHED) || (evt == ORTP_EVENT_ICE_GATHERING_FINISHED) || (evt == ORTP_EVENT_ICE_LOSING_PAIRS_COMPLETED) || (evt == ORTP_EVENT_ICE_RESTART_NEEDED)) { - handle_ice_events(call, ev); + if (ms) handle_ice_events(call, ev); } else if (evt==ORTP_EVENT_TELEPHONE_EVENT){ - linphone_core_dtmf_received(call->core,evd->info.telephone_event); + linphone_core_dtmf_received(call,evd->info.telephone_event); } ortp_event_destroy(ev); } @@ -3710,17 +4432,21 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse case LinphoneCallPausedByRemote: case LinphoneCallPaused: if (one_second_elapsed){ - float audio_load=0, video_load=0; - if (call->audiostream!=NULL){ + float audio_load=0, video_load=0, text_load=0; + if (call->audiostream != NULL) { if (call->audiostream->ms.sessions.ticker) - audio_load=ms_ticker_get_average_load(call->audiostream->ms.sessions.ticker); + audio_load = ms_ticker_get_average_load(call->audiostream->ms.sessions.ticker); } - if (call->videostream!=NULL){ + if (call->videostream != NULL) { if (call->videostream->ms.sessions.ticker) - video_load=ms_ticker_get_average_load(call->videostream->ms.sessions.ticker); + video_load = ms_ticker_get_average_load(call->videostream->ms.sessions.ticker); } - report_bandwidth(call,(MediaStream*)call->audiostream,(MediaStream*)call->videostream); - ms_message("Thread processing load: audio=%f\tvideo=%f",audio_load,video_load); + if (call->textstream != NULL) { + if (call->textstream->ms.sessions.ticker) + text_load = ms_ticker_get_average_load(call->textstream->ms.sessions.ticker); + } + report_bandwidth(call, (MediaStream*)call->audiostream, (MediaStream*)call->videostream, (MediaStream*)call->textstream); + ms_message("Thread processing load: audio=%f\tvideo=%f\ttext=%f", audio_load, video_load, text_load); } break; default: @@ -3732,17 +4458,20 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse linphone_upnp_call_process(call); #endif //BUILD_UPNP - linphone_call_handle_stream_events(call,0); - linphone_call_handle_stream_events(call,1); - if (call->state==LinphoneCallStreamsRunning && one_second_elapsed && call->audiostream!=NULL + linphone_call_handle_stream_events(call, call->main_audio_stream_index); + linphone_call_handle_stream_events(call, call->main_video_stream_index); + linphone_call_handle_stream_events(call, call->main_text_stream_index); + if ((call->state == LinphoneCallStreamsRunning || + call->state == LinphoneCallPausedByRemote) && one_second_elapsed && call->audiostream!=NULL && call->audiostream->ms.state==MSStreamStarted && disconnect_timeout>0 ) disconnected=!audio_stream_alive(call->audiostream,disconnect_timeout); if (disconnected) - linphone_core_disconnected(call->core,call); + linphone_call_lost(call, LinphoneReasonUnknown); } void linphone_call_log_completed(LinphoneCall *call){ LinphoneCore *lc=call->core; + bool_t call_logs_sqlite_db_found = FALSE; call->log->duration=linphone_call_get_duration(call); /*store duration since connected*/ @@ -3755,19 +4484,28 @@ void linphone_call_log_completed(LinphoneCall *call){ linphone_core_notify_display_status(lc,info); ms_free(info); } - lc->call_logs=ms_list_prepend(lc->call_logs,linphone_call_log_ref(call->log)); - if (ms_list_size(lc->call_logs)>lc->max_call_logs){ - MSList *elem,*prevelem=NULL; - /*find the last element*/ - for(elem=lc->call_logs;elem!=NULL;elem=elem->next){ - prevelem=elem; + +#ifdef CALL_LOGS_STORAGE_ENABLED + if (lc->logs_db) { + call_logs_sqlite_db_found = TRUE; + linphone_core_store_call_log(lc, call->log); + } +#endif + if (!call_logs_sqlite_db_found) { + lc->call_logs=ms_list_prepend(lc->call_logs,linphone_call_log_ref(call->log)); + if (ms_list_size(lc->call_logs)>lc->max_call_logs){ + MSList *elem,*prevelem=NULL; + /*find the last element*/ + for(elem=lc->call_logs;elem!=NULL;elem=elem->next){ + prevelem=elem; + } + elem=prevelem; + linphone_call_log_unref((LinphoneCallLog*)elem->data); + lc->call_logs=ms_list_remove_link(lc->call_logs,elem); } - elem=prevelem; - linphone_call_log_unref((LinphoneCallLog*)elem->data); - lc->call_logs=ms_list_remove_link(lc->call_logs,elem); + call_logs_write_to_config_file(lc); } linphone_core_notify_call_log_updated(lc,call->log); - call_logs_write_to_config_file(lc); } /** @@ -3810,7 +4548,7 @@ void linphone_call_zoom_video(LinphoneCall* call, float zoom_factor, float* cx, if (zoom_factor < 1) zoom_factor = 1; - halfsize = 0.5 * 1.0 / zoom_factor; + halfsize = 0.5f * 1.0f / zoom_factor; if ((*cx - halfsize) < 0) *cx = 0 + halfsize; @@ -3967,7 +4705,7 @@ void linphone_call_cancel_dtmfs(LinphoneCall *call) { } } -unsigned long linphone_call_get_native_video_window_id(const LinphoneCall *call) { +void * linphone_call_get_native_video_window_id(const LinphoneCall *call) { if (call->video_window_id) { /* The video id was previously set by the app. */ return call->video_window_id; @@ -3981,7 +4719,7 @@ unsigned long linphone_call_get_native_video_window_id(const LinphoneCall *call) return 0; } -void linphone_call_set_native_video_window_id(LinphoneCall *call, unsigned long id) { +void linphone_call_set_native_video_window_id(LinphoneCall *call, void *id) { call->video_window_id = id; #ifdef VIDEO_ENABLED if (call->videostream) { @@ -3989,11 +4727,140 @@ void linphone_call_set_native_video_window_id(LinphoneCall *call, unsigned long } #endif } -#ifdef VIDEO_ENABLED + MSWebCam *linphone_call_get_video_device(const LinphoneCall *call) { - if (call->camera_enabled==FALSE) + LinphoneCallState state = linphone_call_get_state(call); + bool_t paused = (state == LinphoneCallPausing) || (state == LinphoneCallPaused); + if (paused || call->all_muted || (call->camera_enabled == FALSE)) return get_nowebcam_device(); else - return call->cam; + return call->core->video_conf.device; } + + +void linphone_call_set_audio_route(LinphoneCall *call, LinphoneAudioRoute route) { + if (call != NULL && call->audiostream != NULL){ + audio_stream_set_audio_route(call->audiostream, (MSAudioRoute) route); + } +} + +LinphoneChatRoom * linphone_call_get_chat_room(LinphoneCall *call) { + if (!call->chat_room){ + if (call->state != LinphoneCallReleased && call->state != LinphoneCallEnd){ + call->chat_room = _linphone_core_create_chat_room_from_call(call); + } + } + return call->chat_room; +} + +int linphone_call_get_stream_count(LinphoneCall *call) { + // Revisit when multiple media streams will be implemented +#ifdef VIDEO_ENABLED + if (linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(call))) { + return 3; + } + return 2; +#else + if (linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(call))) { + return 2; + } + return 1; #endif +} + +MSFormatType linphone_call_get_stream_type(LinphoneCall *call, int stream_index) { + // Revisit when multiple media streams will be implemented + if (stream_index == call->main_video_stream_index) { + return MSVideo; + } else if (stream_index == call->main_text_stream_index) { + return MSText; + } + return MSAudio; +} + +RtpTransport* linphone_call_get_meta_rtp_transport(LinphoneCall *call, int stream_index) { + RtpTransport *meta_rtp; + RtpTransport *meta_rtcp; + + if (!call || stream_index < 0 || stream_index >= linphone_call_get_stream_count(call)) { + return NULL; + } + + rtp_session_get_transports(call->sessions[stream_index].rtp_session, &meta_rtp, &meta_rtcp); + return meta_rtp; +} + +RtpTransport* linphone_call_get_meta_rtcp_transport(LinphoneCall *call, int stream_index) { + RtpTransport *meta_rtp; + RtpTransport *meta_rtcp; + + if (!call || stream_index < 0 || stream_index >= linphone_call_get_stream_count(call)) { + return NULL; + } + + rtp_session_get_transports(call->sessions[stream_index].rtp_session, &meta_rtp, &meta_rtcp); + return meta_rtcp; +} + +void linphone_call_set_broken(LinphoneCall *call){ + switch(call->state){ + /*for all the early states, we prefer to drop the call*/ + case LinphoneCallOutgoingInit: + case LinphoneCallOutgoingRinging: + case LinphoneCallOutgoingEarlyMedia: + case LinphoneCallIncomingReceived: + case LinphoneCallIncomingEarlyMedia: + /*during the early states, the SAL layer reports the failure from the dialog or transaction layer, + * hence, there is nothing special to do*/ + break; + case LinphoneCallStreamsRunning: + case LinphoneCallPaused: + case LinphoneCallPausedByRemote: + /*during these states, the dialog is established. A failure of a transaction is not expected to close it. + * Instead we have to repair the dialog by sending a reINVITE*/ + call->broken = TRUE; + break; + default: + ms_error("linphone_call_set_broken() unimplemented case."); + break; + } +} + +void linphone_call_repair_if_broken(LinphoneCall *call){ + LinphoneCallParams *params; + + if (!call->broken) return; + + /*First, make sure that the proxy from which we received this call, or to which we routed this call is registered*/ + if (!call->dest_proxy || linphone_proxy_config_get_state(call->dest_proxy) != LinphoneRegistrationOk) return; + + + switch (call->state){ + case LinphoneCallStreamsRunning: + case LinphoneCallPaused: + case LinphoneCallPausedByRemote: + ms_message("LinphoneCall[%p] is going to be updated (reINVITE) in order to recover from lost connectivity", call); + if (call->ice_session){ + ice_session_restart(call->ice_session); + ice_session_set_role(call->ice_session, IR_Controlling); + } + params = linphone_core_create_call_params(call->core, call); + linphone_core_update_call(call->core, call, params); + linphone_call_params_unref(params); + break; + default: + ms_error("linphone_call_resume_if_broken(): don't know what to do in state [%s]", linphone_call_state_to_string(call->state)); + break; + } +} + +void linphone_call_refresh_sockets(LinphoneCall *call){ + int i; + for (i=0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; ++i){ + MSMediaStreamSessions *mss = &call->sessions[i]; + if (mss->rtp_session){ + rtp_session_refresh_sockets(mss->rtp_session); + } + } +} + diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index c58b3a281..c6bebdb9f 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -38,7 +38,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "mediastreamer2/dtmfgen.h" #ifdef INET6 -#ifndef WIN32 +#ifndef _WIN32 #include #endif #endif @@ -60,9 +60,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifdef HAVE_ZLIB #define COMPRESSED_LOG_COLLECTION_EXTENSION "gz" -#ifdef WIN32 +#ifdef _WIN32 #include #include +#ifndef fileno +#define fileno _fileno +#endif +#define unlink _unlink #define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) #else #define SET_BINARY_MODE(file) @@ -93,10 +97,11 @@ static char * liblinphone_log_collection_path = NULL; static char * liblinphone_log_collection_prefix = NULL; static int liblinphone_log_collection_max_file_size = LOG_COLLECTION_DEFAULT_MAX_FILE_SIZE; static ortp_mutex_t liblinphone_log_collection_mutex; +static FILE * liblinphone_log_collection_file = NULL; +static size_t liblinphone_log_collection_file_size = 0; static bool_t liblinphone_serialize_logs = FALSE; static void set_network_reachable(LinphoneCore* lc,bool_t isReachable, time_t curtime); static void linphone_core_run_hooks(LinphoneCore *lc); -static void linphone_core_free_hooks(LinphoneCore *lc); #include "enum.h" #include "contact_providers_priv.h" @@ -105,10 +110,10 @@ static void linphone_core_free_hooks(LinphoneCore *lc); const char *linphone_core_get_nat_address_resolved(LinphoneCore *lc); static void toggle_video_preview(LinphoneCore *lc, bool_t val); -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) -#define SOUNDS_PREFIX -#else +#if defined(LINPHONE_WINDOWS_PHONE) || defined(LINPHONE_WINDOWS_UNIVERSAL) #define SOUNDS_PREFIX "Assets/Sounds/" +#else +#define SOUNDS_PREFIX #endif /* relative path where is stored local ring*/ #define LOCAL_RING SOUNDS_PREFIX "rings/oldphone.wav" @@ -171,31 +176,100 @@ void linphone_core_set_log_file(FILE *file) { } void linphone_core_set_log_level(OrtpLogLevel loglevel) { - linphone_core_set_log_level_mask(loglevel); + OrtpLogLevel mask = loglevel; + switch (loglevel) { + case ORTP_TRACE: + case ORTP_DEBUG: + mask |= ORTP_DEBUG; + case ORTP_MESSAGE: + mask |= ORTP_MESSAGE; + case ORTP_WARNING: + mask |= ORTP_WARNING; + case ORTP_ERROR: + mask |= ORTP_ERROR; + case ORTP_FATAL: + mask |= ORTP_FATAL; + break; + case ORTP_LOGLEV_END: + break; + } + linphone_core_set_log_level_mask(mask); } void linphone_core_set_log_level_mask(OrtpLogLevel loglevel) { ortp_set_log_level_mask(loglevel); if (loglevel == 0) { - sal_disable_logs(); + sal_disable_log(); } else { - sal_enable_logs(); + sal_enable_log(); + } +} + +static int _open_log_collection_file_with_idx(int idx) { + struct stat statbuf; + char *log_filename; + + log_filename = ortp_strdup_printf("%s/%s%d.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, + idx); + liblinphone_log_collection_file = fopen(log_filename, "a"); + ortp_free(log_filename); + if (liblinphone_log_collection_file == NULL) return -1; + + fstat(fileno(liblinphone_log_collection_file), &statbuf); + if (statbuf.st_size > liblinphone_log_collection_max_file_size) { + fclose(liblinphone_log_collection_file); + return -1; + } + + liblinphone_log_collection_file_size = statbuf.st_size; + return 0; +} + +static void _rotate_log_collection_files(void) { + char *log_filename1; + char *log_filename2; + + log_filename1 = ortp_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); + log_filename2 = ortp_strdup_printf("%s/%s2.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); + unlink(log_filename1); + rename(log_filename2, log_filename1); + ortp_free(log_filename1); + ortp_free(log_filename2); +} + +static void _open_log_collection_file(void) { + if (_open_log_collection_file_with_idx(1) < 0) { + if (_open_log_collection_file_with_idx(2) < 0) { + _rotate_log_collection_files(); + _open_log_collection_file_with_idx(2); + } + } +} + +static void _close_log_collection_file(void) { + if (liblinphone_log_collection_file) { + fclose(liblinphone_log_collection_file); + liblinphone_log_collection_file = NULL; + liblinphone_log_collection_file_size = 0; } } static void linphone_core_log_collection_handler(OrtpLogLevel level, const char *fmt, va_list args) { const char *lname="undef"; char *msg; - char *log_filename1; - char *log_filename2; - FILE *log_file; struct timeval tp; struct tm *lt; time_t tt; - struct stat statbuf; + int ret; if (liblinphone_log_func != NULL) { -#ifndef WIN32 +#ifndef _WIN32 va_list args_copy; va_copy(args_copy, args); liblinphone_log_func(level, fmt, args_copy); @@ -231,34 +305,26 @@ static void linphone_core_log_collection_handler(OrtpLogLevel level, const char } msg = ortp_strdup_vprintf(fmt, args); - log_filename1 = ortp_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); - log_filename2 = ortp_strdup_printf("%s/%s2.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); - ortp_mutex_lock(&liblinphone_log_collection_mutex); - log_file = fopen(log_filename1, "a"); - fstat(fileno(log_file), &statbuf); - if (statbuf.st_size > liblinphone_log_collection_max_file_size) { - fclose(log_file); - log_file = fopen(log_filename2, "a"); - fstat(fileno(log_file), &statbuf); - if (statbuf.st_size > liblinphone_log_collection_max_file_size) { - fclose(log_file); - unlink(log_filename1); - rename(log_filename2, log_filename1); - log_file = fopen(log_filename2, "a"); - } + if (liblinphone_log_collection_file == NULL) { + ortp_mutex_lock(&liblinphone_log_collection_mutex); + _open_log_collection_file(); + ortp_mutex_unlock(&liblinphone_log_collection_mutex); + } + if (liblinphone_log_collection_file) { + ortp_mutex_lock(&liblinphone_log_collection_mutex); + ret = fprintf(liblinphone_log_collection_file,"%i-%.2i-%.2i %.2i:%.2i:%.2i:%.3i %s %s\n", + 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec, (int)(tp.tv_usec / 1000), lname, msg); + fflush(liblinphone_log_collection_file); + if (ret > 0) { + liblinphone_log_collection_file_size += ret; + if (liblinphone_log_collection_file_size > liblinphone_log_collection_max_file_size) { + _close_log_collection_file(); + _open_log_collection_file(); + } + } + ortp_mutex_unlock(&liblinphone_log_collection_mutex); } - fprintf(log_file,"%i-%.2i-%.2i %.2i:%.2i:%.2i:%.3i %s %s\n", - 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec, (int)(tp.tv_usec / 1000), lname, msg); - fflush(log_file); - fclose(log_file); - ortp_mutex_unlock(&liblinphone_log_collection_mutex); - ortp_free(log_filename1); - ortp_free(log_filename2); ortp_free(msg); } @@ -390,13 +456,21 @@ static int log_collection_upload_on_send_body(belle_sip_user_body_handler_t *bh, #else FILE *log_file = fopen(log_filename, "r"); #endif - fseek(log_file, offset, SEEK_SET); - *size = fread(buffer, 1, *size, log_file); + if (fseek(log_file, (long)offset, SEEK_SET)) { + ms_error("Cannot seek file [%s] at position [%lu] errno [%s]",log_filename,(unsigned long)offset,strerror(errno)); + + } else { + *size = fread(buffer, 1, *size, log_file); + } fclose(log_file); ms_free(log_filename); + return BELLE_SIP_CONTINUE; + } else { + *size=0; + return BELLE_SIP_STOP; } - return BELLE_SIP_CONTINUE; + } /** @@ -446,7 +520,7 @@ static void process_response_from_post_file_log_collection(void *data, const bel (belle_sip_header_t *)belle_sip_header_content_type_create(linphone_content_get_type(core->log_collection_upload_information), linphone_content_get_subtype(core->log_collection_upload_information))); /* Insert it in a multipart body handler which will manage the boundaries of multipart message */ - bh = belle_sip_multipart_body_handler_new(log_collection_upload_on_progress, core, (belle_sip_body_handler_t *)first_part_bh); + bh = belle_sip_multipart_body_handler_new(log_collection_upload_on_progress, core, (belle_sip_body_handler_t *)first_part_bh, NULL); ua = ms_strdup_printf("%s/%s", linphone_core_get_user_agent_name(), linphone_core_get_user_agent_version()); uri = belle_generic_uri_parse(linphone_core_get_log_collection_upload_server_url(core)); req = belle_http_request_create("POST", uri, belle_sip_header_create("User-Agent", ua), NULL); @@ -509,18 +583,19 @@ static void process_response_from_post_file_log_collection(void *data, const bel */ static int compress_file(FILE *input_file, COMPRESS_FILE_PTR output_file) { char buffer[131072]; /* 128kB */ - int bytes; + size_t bytes; + size_t total_bytes = 0; while ((bytes = fread(buffer, 1, sizeof(buffer), input_file)) > 0) { - if (bytes < 0) return bytes; #ifdef HAVE_ZLIB - bytes = gzwrite(output_file, buffer, bytes); + int res = gzwrite(output_file, buffer, (unsigned int)bytes); + if (res < 0) return 0; + total_bytes += (size_t)res; #else - bytes = fwrite(buffer, 1, bytes, output_file); + total_bytes += fwrite(buffer, 1, bytes, output_file); #endif - if (bytes < 0) return bytes; } - return 0; + return total_bytes; } static int prepare_log_collection_file_to_upload(const char *filename) { @@ -541,7 +616,7 @@ static int prepare_log_collection_file_to_upload(const char *filename) { input_file = fopen(input_filename, "r"); if (input_file == NULL) goto error; ret = compress_file(input_file, output_file); - if (ret < 0) goto error; + if (ret <= 0) goto error; fclose(input_file); ms_free(input_filename); input_filename = ms_strdup_printf("%s/%s2.log", @@ -550,7 +625,7 @@ static int prepare_log_collection_file_to_upload(const char *filename) { input_file = fopen(input_filename, "r"); if (input_file != NULL) { ret = compress_file(input_file, output_file); - if (ret < 0) goto error; + if (ret <= 0) goto error; } error: @@ -595,7 +670,11 @@ void linphone_core_upload_log_collection(LinphoneCore *core) { liblinphone_log_collection_prefix ? liblinphone_log_collection_prefix : LOG_COLLECTION_DEFAULT_PREFIX, COMPRESSED_LOG_COLLECTION_EXTENSION); linphone_content_set_name(core->log_collection_upload_information, name); - if (prepare_log_collection_file_to_upload(name) < 0) return; + if (prepare_log_collection_file_to_upload(name) <= 0) { + ms_free(core->log_collection_upload_information); + core->log_collection_upload_information = NULL; + return; + } linphone_content_set_size(core->log_collection_upload_information, get_size_of_file_to_upload(name)); uri = belle_generic_uri_parse(linphone_core_get_log_collection_upload_server_url(core)); req = belle_http_request_create("POST", uri, NULL, NULL, NULL); @@ -608,13 +687,13 @@ void linphone_core_upload_log_collection(LinphoneCore *core) { } } -char * linphone_core_compress_log_collection() { +char * linphone_core_compress_log_collection(void) { char *filename = NULL; if (liblinphone_log_collection_state == LinphoneLogCollectionDisabled) return NULL; filename = ms_strdup_printf("%s_log.%s", liblinphone_log_collection_prefix ? liblinphone_log_collection_prefix : LOG_COLLECTION_DEFAULT_PREFIX, COMPRESSED_LOG_COLLECTION_EXTENSION); - if (prepare_log_collection_file_to_upload(filename) < 0) { + if (prepare_log_collection_file_to_upload(filename) <= 0) { ms_free(filename); return NULL; } @@ -625,7 +704,7 @@ char * linphone_core_compress_log_collection() { COMPRESSED_LOG_COLLECTION_EXTENSION); } -void linphone_core_reset_log_collection() { +void linphone_core_reset_log_collection(void) { char *filename; ortp_mutex_lock(&liblinphone_log_collection_mutex); clean_log_collection_upload_context(NULL); @@ -639,6 +718,8 @@ void linphone_core_reset_log_collection() { liblinphone_log_collection_prefix ? liblinphone_log_collection_prefix : LOG_COLLECTION_DEFAULT_PREFIX); unlink(filename); ms_free(filename); + liblinphone_log_collection_file = NULL; + liblinphone_log_collection_file_size = 0; ortp_mutex_unlock(&liblinphone_log_collection_mutex); } @@ -654,8 +735,7 @@ void linphone_core_reset_log_collection() { void linphone_core_enable_logs(FILE *file){ if (file==NULL) file=stdout; ortp_set_log_file(file); - ortp_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL); - sal_enable_logs(); + linphone_core_set_log_level(ORTP_MESSAGE); } /** @@ -669,9 +749,8 @@ void linphone_core_enable_logs(FILE *file){ * **/ void linphone_core_enable_logs_with_cb(OrtpLogFunc logfunc){ - ortp_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL); + linphone_core_set_log_level(ORTP_MESSAGE); linphone_core_set_log_handler(logfunc); - sal_enable_logs(); } /** @@ -681,8 +760,7 @@ void linphone_core_enable_logs_with_cb(OrtpLogFunc logfunc){ * @deprecated Use #linphone_core_set_log_level instead. **/ void linphone_core_disable_logs(void){ - ortp_set_log_level_mask(ORTP_ERROR|ORTP_FATAL); - sal_disable_logs(); + linphone_core_set_log_level(ORTP_ERROR); } void linphone_core_serialize_logs(void) { @@ -845,7 +923,13 @@ static void certificates_config_read(LinphoneCore *lc) { const char *rootca; #ifdef __linux + struct stat sb; rootca=lp_config_get_string(lc->config,"sip","root_ca", "/etc/ssl/certs"); + if (stat("/etc/ssl/certs", &sb) != 0 || !S_ISDIR(sb.st_mode)) + { + ms_warning("/etc/ssl/certs not found, using %s instead", ROOT_CA_FILE); + rootca=lp_config_get_string(lc->config,"sip","root_ca", ROOT_CA_FILE); + } #else rootca=lp_config_get_string(lc->config,"sip","root_ca", ROOT_CA_FILE); #endif @@ -899,7 +983,7 @@ static void sip_config_read(LinphoneCore *lc) if (hostname==NULL) hostname="unknown-host"; if (username==NULL){ - username="toto"; + username="linphone"; } contact=ortp_strdup_printf("sip:%s@%s",username,hostname); linphone_core_set_primary_contact(lc,contact); @@ -996,6 +1080,15 @@ static void rtp_config_read(LinphoneCore *lc) linphone_core_set_video_port(lc, min_port); } + if (lp_config_get_range(lc->config, "rtp", "text_rtp_port", &min_port, &max_port, 11078, 11078) == TRUE) { + if (min_port <= 0) min_port = 1; + if (max_port > 65535) max_port = 65535; + linphone_core_set_text_port_range(lc, min_port, max_port); + } else { + min_port = lp_config_get_int(lc->config, "rtp", "text_rtp_port", 11078); + linphone_core_set_text_port(lc, min_port); + } + jitt_comp=lp_config_get_int(lc->config,"rtp","audio_jitt_comp",60); linphone_core_set_audio_jittcomp(lc,jitt_comp); jitt_comp=lp_config_get_int(lc->config,"rtp","video_jitt_comp",60); @@ -1074,6 +1167,16 @@ static PayloadType* find_payload_type_from_list(const char* type, int rate, int return NULL; } +static bool_t linphone_core_codec_supported(LinphoneCore *lc, SalStreamType type, const char *mime){ + if (type == SalVideo && lp_config_get_int(lc->config, "video", "rtp_io", FALSE)){ + return TRUE; /*in rtp io mode, we don't transcode video, thus we can support a format for which we have no encoder nor decoder.*/ + } else if (type == SalText) { + return TRUE; + } + return ms_filter_codec_supported(mime); +} + + static bool_t get_codec(LinphoneCore *lc, SalStreamType type, int index, PayloadType **ret){ char codeckey[50]; const char *mime,*fmtp; @@ -1082,7 +1185,7 @@ static bool_t get_codec(LinphoneCore *lc, SalStreamType type, int index, Payload LpConfig *config=lc->config; *ret=NULL; - snprintf(codeckey,50,"%s_codec_%i",type==SalAudio ? "audio" : "video", index); + snprintf(codeckey,50,"%s_codec_%i",type == SalAudio ? "audio" : type == SalVideo ? "video" : "text", index); mime=lp_config_get_string(config,codeckey,"mime",NULL); if (mime==NULL || strlen(mime)==0 ) return FALSE; @@ -1090,19 +1193,21 @@ static bool_t get_codec(LinphoneCore *lc, SalStreamType type, int index, Payload fmtp=lp_config_get_string(config,codeckey,"recv_fmtp",NULL); channels=lp_config_get_int(config,codeckey,"channels",0); enabled=lp_config_get_int(config,codeckey,"enabled",1); - if (!ms_filter_codec_supported(mime)){ + if (!linphone_core_codec_supported(lc, type, mime)){ ms_warning("Codec %s/%i read from conf is not supported by mediastreamer2, ignored.",mime,rate); return TRUE; } - pt=find_payload(type==SalAudio ? lc->default_audio_codecs : lc->default_video_codecs,mime,rate,channels,fmtp); + pt = find_payload(type == SalAudio ? lc->default_audio_codecs : type == SalVideo ? lc->default_video_codecs : lc->default_text_codecs ,mime,rate,channels,fmtp); if (!pt){ - MSList **default_list=(type==SalAudio) ? &lc->default_audio_codecs : &lc->default_video_codecs; - if (type==SalAudio) + MSList **default_list = (type==SalAudio) ? &lc->default_audio_codecs : type == SalVideo ? &lc->default_video_codecs : &lc->default_text_codecs; + if (type == SalAudio) ms_warning("Codec %s/%i/%i read from conf is not in the default list.",mime,rate,channels); - else + else if (type == SalVideo) ms_warning("Codec %s/%i read from conf is not in the default list.",mime,rate); + else + ms_warning("Codec %s read from conf is not in the default list.",mime); pt=payload_type_new(); - pt->type=(type==SalAudio) ? PAYLOAD_AUDIO_PACKETIZED : PAYLOAD_VIDEO; + pt->type=(type==SalAudio) ? PAYLOAD_AUDIO_PACKETIZED : type == SalVideo ? PAYLOAD_VIDEO : PAYLOAD_TEXT; pt->mime_type=ortp_strdup(mime); pt->clock_rate=rate; pt->channels=channels; @@ -1160,6 +1265,7 @@ static void codecs_config_read(LinphoneCore *lc) PayloadType *pt; MSList *audio_codecs=NULL; MSList *video_codecs=NULL; + MSList *text_codecs=NULL; lc->codecs_conf.dyn_pt=96; lc->codecs_conf.telephone_event_pt=lp_config_get_int(lc->config,"misc","telephone_event_pt",101); @@ -1181,8 +1287,17 @@ static void codecs_config_read(LinphoneCore *lc) if( lp_config_get_int(lc->config, "misc", "add_missing_video_codecs", 1) == 1 ){ video_codecs=add_missing_codecs(lc->default_video_codecs,video_codecs); } + + for (i=0;get_codec(lc,SalText,i,&pt);i++){ + if (pt){ + text_codecs=codec_append_if_new(text_codecs, pt); + } + } + text_codecs = add_missing_codecs(lc->default_text_codecs, text_codecs); + linphone_core_set_audio_codecs(lc,audio_codecs); linphone_core_set_video_codecs(lc,video_codecs); + linphone_core_set_text_codecs(lc, text_codecs); linphone_core_update_allocated_audio_bandwidth(lc); } @@ -1255,6 +1370,7 @@ static void ui_config_read(LinphoneCore *lc) linphone_core_add_friend(lc,lf); linphone_friend_unref(lf); } + call_logs_read_from_config_file(lc); } @@ -1279,49 +1395,18 @@ bool_t linphone_core_tunnel_available(void){ #endif } -/** - * Enable adaptive rate control. - * - * @ingroup media_parameters - * - * Adaptive rate control consists in using RTCP feedback provided information to dynamically - * control the output bitrate of the audio and video encoders, so that we can adapt to the network conditions and - * available bandwidth. Control of the audio encoder is done in case of audio-only call, and control of the video encoder is done for audio & video calls. - * Adaptive rate control feature is enabled by default. -**/ void linphone_core_enable_adaptive_rate_control(LinphoneCore *lc, bool_t enabled){ lp_config_set_int(lc->config,"net","adaptive_rate_control",(int)enabled); } -/** - * Returns whether adaptive rate control is enabled. - * - * @ingroup media_parameters - * - * See linphone_core_enable_adaptive_rate_control(). -**/ bool_t linphone_core_adaptive_rate_control_enabled(const LinphoneCore *lc){ return lp_config_get_int(lc->config,"net","adaptive_rate_control",TRUE); } -/** - * Sets adaptive rate algorithm. It will be used for each new calls starting from - * now. Calls already started will not be updated. - * - * @ingroup media_parameters - * -**/ void linphone_core_set_adaptive_rate_algorithm(LinphoneCore *lc, const char* algorithm){ lp_config_set_string(lc->config,"net","adaptive_rate_algorithm",algorithm); } -/** - * Returns which adaptive rate algorithm is currently configured for future calls. - * - * @ingroup media_parameters - * - * 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"); } @@ -1330,36 +1415,12 @@ bool_t linphone_core_rtcp_enabled(const LinphoneCore *lc){ return lp_config_get_int(lc->config,"rtp","rtcp_enabled",TRUE); } -/** - * Sets maximum available download bandwidth - * This is IP bandwidth, in kbit/s. - * This information is used signaled to other parties during - * calls (within SDP messages) so that the remote end can have - * sufficient knowledge to properly configure its audio & video - * codec output bitrate to not overflow available bandwidth. - * - * @ingroup media_parameters - * - * @param lc the LinphoneCore object - * @param bw the bandwidth in kbits/s, 0 for infinite - */ void linphone_core_set_download_bandwidth(LinphoneCore *lc, int bw){ lc->net_conf.download_bw=bw; linphone_core_update_allocated_audio_bandwidth(lc); if (linphone_core_ready(lc)) lp_config_set_int(lc->config,"net","download_bw",bw); } -/** - * Sets maximum available upload bandwidth - * This is IP bandwidth, in kbit/s. - * This information is used by liblinphone together with remote - * side available bandwidth signaled in SDP messages to properly - * configure audio & video codec's output bitrate. - * - * @param lc the LinphoneCore object - * @param bw the bandwidth in kbits/s, 0 for infinite - * @ingroup media_parameters - */ void linphone_core_set_upload_bandwidth(LinphoneCore *lc, int bw){ lc->net_conf.upload_bw=bw; linphone_core_update_allocated_audio_bandwidth(lc); @@ -1386,77 +1447,36 @@ bool_t linphone_core_dns_srv_enabled(const LinphoneCore *lc) { return sal_dns_srv_enabled(lc->sal); } -/** - * Retrieve the maximum available download bandwidth. - * This value was set by linphone_core_set_download_bandwidth(). - * @ingroup media_parameters -**/ int linphone_core_get_download_bandwidth(const LinphoneCore *lc){ return lc->net_conf.download_bw; } -/** - * Retrieve the maximum available upload bandwidth. - * This value was set by linphone_core_set_upload_bandwidth(). - * @ingroup media_parameters -**/ int linphone_core_get_upload_bandwidth(const LinphoneCore *lc){ return lc->net_conf.upload_bw; } -/** - * Set audio packetization time linphone expects to receive from peer. - * A value of zero means that ptime is not specified. - * @ingroup media_parameters - */ void linphone_core_set_download_ptime(LinphoneCore *lc, int ptime) { lp_config_set_int(lc->config,"rtp","download_ptime",ptime); } -/** - * Get audio packetization time linphone expects to receive from peer. - * A value of zero means that ptime is not specified. - * @ingroup media_parameters - */ int linphone_core_get_download_ptime(LinphoneCore *lc) { return lp_config_get_int(lc->config,"rtp","download_ptime",0); } -/** - * Set audio packetization time linphone will send (in absence of requirement from peer) - * A value of 0 stands for the current codec default packetization time. - * - * @ingroup media_parameters -**/ void linphone_core_set_upload_ptime(LinphoneCore *lc, int ptime){ lp_config_set_int(lc->config,"rtp","upload_ptime",ptime); } -/** - * Set audio packetization time linphone will send (in absence of requirement from peer) - * A value of 0 stands for the current codec default packetization time. - * - * - * @ingroup media_parameters -**/ int linphone_core_get_upload_ptime(LinphoneCore *lc){ return lp_config_get_int(lc->config,"rtp","upload_ptime",0); } - - -/** - * Returns liblinphone's version as a string. - * - * @ingroup misc - * -**/ const char * linphone_core_get_version(void){ return liblinphone_version; } static void linphone_core_register_payload_type(LinphoneCore *lc, const PayloadType *const_pt, const char *recv_fmtp, bool_t enabled){ - MSList **codec_list=const_pt->type==PAYLOAD_VIDEO ? &lc->default_video_codecs : &lc->default_audio_codecs; - if (ms_filter_codec_supported(const_pt->mime_type)){ + MSList **codec_list = const_pt->type==PAYLOAD_VIDEO ? &lc->default_video_codecs : const_pt->type==PAYLOAD_TEXT ? &lc->default_text_codecs : &lc->default_audio_codecs; + if (linphone_core_codec_supported(lc, (const_pt->type == PAYLOAD_VIDEO) ? SalVideo : const_pt->type == PAYLOAD_TEXT ? SalText : SalAudio, const_pt->mime_type)){ PayloadType *pt=payload_type_clone(const_pt); int number=-1; payload_type_set_enable(pt,enabled); @@ -1482,8 +1502,8 @@ static void linphone_core_register_static_payloads(LinphoneCore *lc){ if (pt->type==PAYLOAD_VIDEO) continue; #endif if (find_payload_type_from_list( - pt->mime_type, pt->clock_rate, pt->type!=PAYLOAD_VIDEO ? pt->channels : LINPHONE_FIND_PAYLOAD_IGNORE_CHANNELS, - pt->type==PAYLOAD_VIDEO ? lc->default_video_codecs : lc->default_audio_codecs)==NULL){ + pt->mime_type, pt->clock_rate, pt->type == PAYLOAD_VIDEO || pt->type == PAYLOAD_TEXT ? LINPHONE_FIND_PAYLOAD_IGNORE_CHANNELS : pt->channels, + pt->type == PAYLOAD_VIDEO ? lc->default_video_codecs : pt->type == PAYLOAD_TEXT ? lc->default_text_codecs : lc->default_audio_codecs)==NULL){ linphone_core_register_payload_type(lc,pt,NULL,FALSE); } } @@ -1493,6 +1513,7 @@ static void linphone_core_register_static_payloads(LinphoneCore *lc){ static void linphone_core_free_payload_types(LinphoneCore *lc){ ms_list_free_with_data(lc->default_audio_codecs, (void (*)(void*))payload_type_destroy); ms_list_free_with_data(lc->default_video_codecs, (void (*)(void*))payload_type_destroy); + ms_list_free_with_data(lc->default_text_codecs, (void (*)(void*))payload_type_destroy); } void linphone_core_set_state(LinphoneCore *lc, LinphoneGlobalState gstate, const char *message){ @@ -1548,10 +1569,14 @@ void linphone_configuring_terminated(LinphoneCore *lc, LinphoneConfiguringState if (linphone_core_is_provisioning_transient(lc) == TRUE) linphone_core_set_provisioning_uri(lc, NULL); } - + if (lc->provisioning_http_listener){ + belle_sip_object_unref(lc->provisioning_http_listener); + lc->provisioning_http_listener = NULL; + } linphone_core_start(lc); } + static int linphone_core_serialization_ref = 0; static void linphone_core_activate_log_serialization_if_needed(void) { @@ -1578,13 +1603,17 @@ static void linphone_core_register_default_codecs(LinphoneCore *lc){ /*hack for opus, that needs to be disabed by default on ARM single processor, otherwise there is no cpu left for video processing*/ if (ms_get_cpu_count()==1) opus_enabled=FALSE; #endif - linphone_core_register_payload_type(lc,&payload_type_opus,"useinbandfec=1; stereo=0; sprop-stereo=0",opus_enabled); + linphone_core_register_payload_type(lc,&payload_type_opus,"useinbandfec=1",opus_enabled); linphone_core_register_payload_type(lc,&payload_type_silk_wb,NULL,TRUE); linphone_core_register_payload_type(lc,&payload_type_speex_wb,"vbr=on",TRUE); linphone_core_register_payload_type(lc,&payload_type_speex_nb,"vbr=on",TRUE); linphone_core_register_payload_type(lc,&payload_type_pcmu8000,NULL,TRUE); linphone_core_register_payload_type(lc,&payload_type_pcma8000,NULL,TRUE); + /* Text codecs in order or preference (RED first (more robust), then T140) */ + linphone_core_register_payload_type(lc, &payload_type_t140_red, NULL, TRUE); + linphone_core_register_payload_type(lc, &payload_type_t140, NULL, TRUE); + /*other audio codecs, not enabled by default, in order of preference*/ linphone_core_register_payload_type(lc,&payload_type_gsm,NULL,FALSE); linphone_core_register_payload_type(lc,&payload_type_g722,NULL,FALSE); @@ -1620,7 +1649,7 @@ static void linphone_core_register_default_codecs(LinphoneCore *lc){ linphone_core_register_payload_type(lc,&payload_type_aal2_g726_24,NULL,FALSE); linphone_core_register_payload_type(lc,&payload_type_aal2_g726_32,NULL,FALSE); linphone_core_register_payload_type(lc,&payload_type_aal2_g726_40,NULL,FALSE); - + linphone_core_register_payload_type(lc,&payload_type_codec2,NULL,FALSE); #ifdef VIDEO_ENABLED @@ -1643,7 +1672,7 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab lc->config=lp_config_ref(config); lc->data=userdata; lc->ringstream_autorelease=TRUE; - + linphone_task_list_init(&lc->hooks); memcpy(local_vtable,vtable,sizeof(LinphoneCoreVTable)); _linphone_core_add_listener(lc, local_vtable, TRUE); @@ -1655,11 +1684,14 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab ms_init(); linphone_core_register_default_codecs(lc); + linphone_core_register_offer_answer_providers(lc); /* Get the mediastreamer2 event queue */ /* This allows to run event's callback in linphone_core_iterate() */ - lc->msevq=ms_factory_get_event_queue(ms_factory_get_fallback()); + lc->msevq=ms_factory_create_event_queue(ms_factory_get_fallback()); lc->sal=sal_init(); + sal_set_http_proxy_host(lc->sal, linphone_core_get_http_proxy_host(lc)); + sal_set_http_proxy_port(lc->sal, linphone_core_get_http_proxy_port(lc)); sal_set_user_pointer(lc->sal,lc); sal_set_callbacks(lc->sal,&linphone_sal_callbacks); @@ -1683,25 +1715,6 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab } // else linphone_core_start will be called after the remote provisioning (see linphone_core_iterate) } -/** - * Instanciates a LinphoneCore object. - * @ingroup initializing - * - * The LinphoneCore object is the primary handle for doing all phone actions. - * It should be unique within your application. - * @param vtable a LinphoneCoreVTable structure holding your application callbacks - * @param config_path a path to a config file. If it does not exists it will be created. - * The config file is used to store all settings, call logs, friends, proxies... so that all these settings - * become persistent over the life of the LinphoneCore object. - * It is allowed to set a NULL config file. In that case LinphoneCore will not store any settings. - * @param factory_config_path a path to a read-only config file that can be used to - * to store hard-coded preference such as proxy settings or internal preferences. - * The settings in this factory file always override the one in the normal config file. - * It is OPTIONAL, use NULL if unneeded. - * @param userdata an opaque user pointer that can be retrieved at any time (for example in - * callbacks) using linphone_core_get_user_data(). - * @see linphone_core_new_with_config -**/ LinphoneCore *linphone_core_new(const LinphoneCoreVTable *vtable, const char *config_path, const char *factory_config_path, void * userdata) { @@ -1719,45 +1732,21 @@ LinphoneCore *linphone_core_new_with_config(const LinphoneCoreVTable *vtable, st return core; } -/** - * Returns the list of available audio codecs. - * @param[in] lc The LinphoneCore object - * @return \mslist{PayloadType} - * - * This list is unmodifiable. The ->data field of the MSList points a PayloadType - * structure holding the codec information. - * It is possible to make copy of the list with ms_list_copy() in order to modify it - * (such as the order of codecs). - * @ingroup media_parameters -**/ const MSList *linphone_core_get_audio_codecs(const LinphoneCore *lc) { return lc->codecs_conf.audio_codecs; } -/** - * Returns the list of available video codecs. - * @param[in] lc The LinphoneCore object - * @return \mslist{PayloadType} - * - * This list is unmodifiable. The ->data field of the MSList points a PayloadType - * structure holding the codec information. - * It is possible to make copy of the list with ms_list_copy() in order to modify it - * (such as the order of codecs). - * @ingroup media_parameters -**/ const MSList *linphone_core_get_video_codecs(const LinphoneCore *lc) { return lc->codecs_conf.video_codecs; } -/** - * Sets the local "from" identity. - * - * @ingroup proxies - * This data is used in absence of any proxy configuration or when no - * default proxy configuration is set. See LinphoneProxyConfig -**/ +const MSList *linphone_core_get_text_codecs(const LinphoneCore *lc) +{ + return lc->codecs_conf.text_codecs; +} + int linphone_core_set_primary_contact(LinphoneCore *lc, const char *contact) { LinphoneAddress *ctt; @@ -1812,11 +1801,6 @@ static void update_primary_contact(LinphoneCore *lc){ linphone_address_destroy(url); } -/** - * Returns the default identity when no proxy configuration is used. - * - * @ingroup proxies -**/ const char *linphone_core_get_primary_contact(LinphoneCore *lc){ char *identity; @@ -1831,28 +1815,14 @@ const char *linphone_core_get_primary_contact(LinphoneCore *lc){ return identity; } -/** - * Tells LinphoneCore to guess local hostname automatically in primary contact. - * - * @ingroup proxies -**/ void linphone_core_set_guess_hostname(LinphoneCore *lc, bool_t val){ lc->sip_conf.guess_hostname=val; } -/** - * Returns TRUE if hostname part of primary contact is guessed automatically. - * - * @ingroup proxies -**/ 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); @@ -1863,12 +1833,10 @@ bool_t linphone_core_lime_enabled(const LinphoneCore *lc){ return (lp_config_get_int(lc->config,"sip", "lime", FALSE) && lime_is_available()); } -/** - * Same as linphone_core_get_primary_contact() but the result is a LinphoneAddress object - * instead of const char* - * - * @ingroup proxies -**/ +bool_t linphone_core_lime_for_file_sharing_enabled(const LinphoneCore *lc){ + return linphone_core_lime_enabled(lc) && (lp_config_get_int(lc->config,"sip", "lime_for_file_sharing", TRUE) && lime_is_available()); +} + LinphoneAddress *linphone_core_get_primary_contact_parsed(LinphoneCore *lc){ return linphone_address_new(linphone_core_get_primary_contact(lc)); } @@ -1908,6 +1876,15 @@ int linphone_core_set_video_codecs(LinphoneCore *lc, MSList *codecs){ return 0; } +int linphone_core_set_text_codecs(LinphoneCore *lc, MSList *codecs) { + if (lc->codecs_conf.text_codecs != NULL) + ms_list_free(lc->codecs_conf.text_codecs); + + lc->codecs_conf.text_codecs = codecs; + _linphone_core_codec_config_write(lc); + return 0; +} + /** * Enable RFC3389 generic confort noise algorithm (CN payload type). * It is disabled by default, because this algorithm is only relevant for legacy codecs (PCMU, PCMA, G722). @@ -2013,6 +1990,24 @@ void linphone_core_get_video_port_range(const LinphoneCore *lc, int *min_port, i *max_port = lc->rtp_conf.video_rtp_max_port; } +/** + * Returns the UDP port used for text streaming. + * + * @ingroup network_parameters +**/ +int linphone_core_get_text_port(const LinphoneCore *lc) { + return lc->rtp_conf.text_rtp_min_port; +} + +/** + * Get the video port range from which is randomly chosen the UDP port used for text streaming. + * + * @ingroup network_parameters + */ +void linphone_core_get_text_port_range(const LinphoneCore *lc, int *min_port, int *max_port) { + *min_port = lc->rtp_conf.text_rtp_min_port; + *max_port = lc->rtp_conf.text_rtp_max_port; +} /** * Returns the value in seconds of the no-rtp timeout. @@ -2054,30 +2049,16 @@ static void apply_jitter_value(LinphoneCore *lc, int value, MSFormatType stype){ } } -/** - * Sets the nominal audio jitter buffer size in milliseconds. - * The value takes effect immediately for all running and pending calls, if any. - * A value of 0 disables the jitter buffer. - * - * @ingroup media_parameters -**/ -void linphone_core_set_audio_jittcomp(LinphoneCore *lc, int value) +void linphone_core_set_audio_jittcomp(LinphoneCore *lc, int milliseconds) { - lc->rtp_conf.audio_jitt_comp=value; - apply_jitter_value(lc, value, MSAudio); + lc->rtp_conf.audio_jitt_comp=milliseconds; + apply_jitter_value(lc, milliseconds, MSAudio); } -/** - * Sets the nominal video jitter buffer size in milliseconds. - * The value takes effect immediately for all running and pending calls, if any. - * A value of 0 disables the jitter buffer. - * - * @ingroup media_parameters -**/ -void linphone_core_set_video_jittcomp(LinphoneCore *lc, int value) +void linphone_core_set_video_jittcomp(LinphoneCore *lc, int milliseconds) { - lc->rtp_conf.video_jitt_comp=value; - apply_jitter_value(lc, value, MSVideo); + lc->rtp_conf.video_jitt_comp=milliseconds; + apply_jitter_value(lc, milliseconds, MSVideo); } void linphone_core_set_rtp_no_xmit_on_audio_mute(LinphoneCore *lc,bool_t rtp_no_xmit_on_audio_mute){ @@ -2127,6 +2108,26 @@ void linphone_core_set_video_port_range(LinphoneCore *lc, int min_port, int max_ lc->rtp_conf.video_rtp_max_port=max_port; } +/** + * Sets the UDP port used for text streaming. + * A value if -1 will request the system to allocate the local port randomly. + * This is recommended in order to avoid firewall warnings. + * + * @ingroup network_parameters +**/ +void linphone_core_set_text_port(LinphoneCore *lc, int port) { + lc->rtp_conf.text_rtp_min_port = lc->rtp_conf.text_rtp_max_port = port; +} + +/** + * Sets the UDP port range from which to randomly select the port used for text streaming. + * @ingroup media_parameters + */ +void linphone_core_set_text_port_range(LinphoneCore *lc, int min_port, int max_port) { + lc->rtp_conf.text_rtp_min_port = min_port; + lc->rtp_conf.text_rtp_max_port = max_port; +} + /** * Sets the no-rtp timeout value in seconds. * @@ -2252,7 +2253,10 @@ int _linphone_core_apply_transports(LinphoneCore *lc){ sal_unlisten_ports(sal); listening_address = lp_config_get_string(lc->config,"sip","bind_address",anyaddr); - + if (linphone_core_get_http_proxy_host(lc)) { + sal_set_http_proxy_host(sal, linphone_core_get_http_proxy_host(lc)); + sal_set_http_proxy_port(sal,linphone_core_get_http_proxy_port(lc)); + } if (lc->tunnel && linphone_tunnel_sip_enabled(lc->tunnel) && linphone_tunnel_get_activated(lc->tunnel)){ if (sal_listen_port(sal,anyaddr,tr->udp_port,SalTransportUDP,TRUE)!=0){ transport_error(lc,"udp+tunnel",tr->udp_port); @@ -2533,10 +2537,13 @@ static void linphone_core_do_plugin_tasks(LinphoneCore *lc){ void linphone_core_iterate(LinphoneCore *lc){ MSList *calls; LinphoneCall *call; - time_t curtime=time(NULL); + uint64_t curtime_ms = ms_get_cur_time_ms(); /*monotonic time*/ int elapsed; + time_t current_real_time = ms_time(NULL); + int64_t diff_time; bool_t one_second_elapsed=FALSE; const char *remote_provisioning_uri = NULL; + if (lc->network_reachable_to_be_notified) { lc->network_reachable_to_be_notified=FALSE; linphone_core_notify_network_reachable(lc,lc->network_reachable); @@ -2546,6 +2553,7 @@ void linphone_core_iterate(LinphoneCore *lc){ belle_tls_verify_policy_t *tls_policy = belle_tls_verify_policy_new(); belle_tls_verify_policy_set_root_ca(tls_policy, sal_get_root_ca(lc->sal)); belle_http_provider_set_tls_verify_policy(lc->http_provider, tls_policy); + belle_sip_object_unref(tls_policy); } linphone_core_notify_display_status(lc, _("Configuring")); @@ -2559,10 +2567,18 @@ void linphone_core_iterate(LinphoneCore *lc){ } } // else linphone_configuring_terminated has already been called in linphone_core_init } - - if (curtime-lc->prevtime>=1){ - lc->prevtime=curtime; + if (lc->prevtime_ms == 0){ + lc->prevtime_ms = curtime_ms; + } + if ((diff_time=curtime_ms-lc->prevtime_ms) >= 1000){ one_second_elapsed=TRUE; + if (diff_time>3000){ + /*since monotonic time doesn't increment while machine is sleeping, we don't want to catchup too much*/ + lc->prevtime_ms = curtime_ms; + }else{ + lc->prevtime_ms += 1000; + + } } if (lc->ecc!=NULL){ @@ -2593,7 +2609,7 @@ void linphone_core_iterate(LinphoneCore *lc){ } if (lc->ringstream && lc->ringstream_autorelease && lc->dmfs_playing_start_time!=0 - && (curtime-lc->dmfs_playing_start_time)>5){ + && (curtime_ms/1000 - lc->dmfs_playing_start_time)>5){ MSPlayerState state; bool_t stop=TRUE; if (lc->ringstream->source && ms_filter_call_method(lc->ringstream->source,MS_PLAYER_GET_STATE,&state)==0){ @@ -2607,15 +2623,15 @@ void linphone_core_iterate(LinphoneCore *lc){ sal_iterate(lc->sal); if (lc->msevq) ms_event_queue_pump(lc->msevq); - if (lc->auto_net_state_mon) monitor_network_state(lc,curtime); + if (lc->auto_net_state_mon) monitor_network_state(lc, current_real_time); proxy_update(lc); //we have to iterate for each call - calls= lc->calls; + calls = lc->calls; while(calls!= NULL){ call = (LinphoneCall *)calls->data; - elapsed = curtime-call->log->start_date_time; + elapsed = (int)(current_real_time - call->log->start_date_time); /* get immediately a reference to next one in case the one we are going to examine is destroy and removed during linphone_core_start_invite() */ @@ -2650,7 +2666,7 @@ void linphone_core_iterate(LinphoneCore *lc){ } if ( (lc->sip_conf.in_call_timeout > 0) && (call->log->connected_date_time != 0) - && ((curtime - call->log->connected_date_time) > lc->sip_conf.in_call_timeout)) + && ((current_real_time - call->log->connected_date_time) > lc->sip_conf.in_call_timeout)) { ms_message("in call timeout (%i)",lc->sip_conf.in_call_timeout); linphone_core_terminate_call(lc,call); @@ -2671,7 +2687,7 @@ void linphone_core_iterate(LinphoneCore *lc){ linphone_core_run_hooks(lc); linphone_core_do_plugin_tasks(lc); - if (lc->network_reachable && lc->netup_time!=0 && (curtime-lc->netup_time)>3){ + if (lc->network_reachable && lc->netup_time!=0 && (current_real_time-lc->netup_time)>3){ /*not do that immediately, take your time.*/ linphone_core_send_initial_subscribes(lc); } @@ -2687,87 +2703,9 @@ void linphone_core_iterate(LinphoneCore *lc){ } } -static LinphoneAddress* _linphone_core_destroy_addr_if_not_sip( LinphoneAddress* addr ){ - if( linphone_address_is_sip(addr) ) { - return addr; - } else { - linphone_address_destroy(addr); - return NULL; - } -} - -/** - * Interpret a call destination as supplied by the user, and returns a fully qualified - * LinphoneAddress. - * - * @ingroup call_control - * - * A sip address should look like DisplayName \ . - * Basically this function performs the following tasks - * - if a phone number is entered, prepend country prefix of the default proxy - * configuration, eventually escape the '+' by 00. - * - if no domain part is supplied, append the domain name of the default proxy - * - if no sip: is present, prepend it - * - * The result is a syntaxically correct SIP address. -**/ - LinphoneAddress * linphone_core_interpret_url(LinphoneCore *lc, const char *url){ - enum_lookup_res_t *enumres=NULL; - char *enum_domain=NULL; - LinphoneProxyConfig *proxy=lc->default_proxy; - char *tmpurl; - LinphoneAddress *uri; - - if (*url=='\0') return NULL; - - if (is_enum(url,&enum_domain)){ - linphone_core_notify_display_status(lc,_("Looking for telephone number destination...")); - if (enum_lookup(enum_domain,&enumres)<0){ - linphone_core_notify_display_status(lc,_("Could not resolve this number.")); - ms_free(enum_domain); - return NULL; - } - ms_free(enum_domain); - tmpurl=enumres->sip_address[0]; - uri=linphone_address_new(tmpurl); - enum_lookup_res_free(enumres); - return _linphone_core_destroy_addr_if_not_sip(uri); - } - /* check if we have a "sip:" or a "sips:" */ - if ( (strstr(url,"sip:")==NULL) && (strstr(url,"sips:")==NULL) ){ - /* this doesn't look like a true sip uri */ - if (strchr(url,'@')!=NULL){ - /* seems like sip: is missing !*/ - tmpurl=ms_strdup_printf("sip:%s",url); - uri=linphone_address_new(tmpurl); - ms_free(tmpurl); - if (uri){ - return _linphone_core_destroy_addr_if_not_sip(uri); - } - } - - if (proxy!=NULL){ - /* append the proxy domain suffix */ - const char *identity=linphone_proxy_config_get_identity(proxy); - char normalized_username[128]; - uri=linphone_address_new(identity); - if (uri==NULL){ - return NULL; - } - linphone_address_set_display_name(uri,NULL); - linphone_proxy_config_normalize_number(proxy,url,normalized_username, - sizeof(normalized_username)); - linphone_address_set_username(uri,normalized_username); - return _linphone_core_destroy_addr_if_not_sip(uri); - }else return NULL; - } - uri=linphone_address_new(url); - if (uri!=NULL){ - return _linphone_core_destroy_addr_if_not_sip(uri); - } - - return NULL; + LinphoneProxyConfig *proxy = linphone_core_get_default_proxy_config(lc); + return linphone_proxy_config_normalize_sip_uri(proxy, url); } /** @@ -2811,7 +2749,7 @@ const char * linphone_core_get_route(LinphoneCore *lc){ * @return a LinphoneCall corresponding to the new call that is attempted to the transfer destination. **/ LinphoneCall * linphone_core_start_refered_call(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params){ - LinphoneCallParams *cp=params ? linphone_call_params_copy(params) : linphone_core_create_default_call_parameters(lc); + LinphoneCallParams *cp=params ? linphone_call_params_copy(params) : linphone_core_create_call_params(lc, NULL); LinphoneCall *newcall; if (call->state!=LinphoneCallPaused){ @@ -2821,6 +2759,7 @@ LinphoneCall * linphone_core_start_refered_call(LinphoneCore *lc, LinphoneCall * } if (!params){ + cp->has_audio = call->current_params->has_audio; cp->has_video = call->current_params->has_video; /*start the call to refer-target with video enabled if original call had video*/ } cp->referer=call; @@ -2969,8 +2908,9 @@ int linphone_core_proceed_with_invite_if_ready(LinphoneCore *lc, LinphoneCall *c int linphone_core_restart_invite(LinphoneCore *lc, LinphoneCall *call){ linphone_call_create_op(call); linphone_call_stop_media_streams(call); - ms_media_stream_sessions_uninit(&call->sessions[0]); - ms_media_stream_sessions_uninit(&call->sessions[1]); + ms_media_stream_sessions_uninit(&call->sessions[call->main_audio_stream_index]); + ms_media_stream_sessions_uninit(&call->sessions[call->main_video_stream_index]); + if (call->params->realtimetext_enabled) ms_media_stream_sessions_uninit(&call->sessions[call->main_text_stream_index]); linphone_call_init_media_streams(call); return linphone_core_start_invite(lc,call, NULL); } @@ -2983,7 +2923,7 @@ int linphone_core_start_invite(LinphoneCore *lc, LinphoneCall *call, const Linph linphone_call_set_contact_op(call); linphone_core_stop_dtmf_stream(lc); - linphone_call_make_local_media_description(lc,call); + linphone_call_make_local_media_description(call); if (lc->ringstream==NULL) { if (lc->sound_conf.play_sndcard && lc->sound_conf.capt_sndcard){ @@ -2991,7 +2931,8 @@ int linphone_core_start_invite(LinphoneCore *lc, LinphoneCall *call, const Linph if (call->localdesc->streams[0].max_rate>0) { ms_snd_card_set_preferred_sample_rate(lc->sound_conf.play_sndcard, call->localdesc->streams[0].max_rate); } - audio_stream_prepare_sound(call->audiostream,lc->sound_conf.play_sndcard,lc->sound_conf.capt_sndcard); + if (!lc->use_files) + audio_stream_prepare_sound(call->audiostream,lc->sound_conf.play_sndcard,lc->sound_conf.capt_sndcard); } } real_url=linphone_address_as_string( destination ? destination : call->log->to); @@ -3040,7 +2981,7 @@ int linphone_core_start_invite(LinphoneCore *lc, LinphoneCall *call, const Linph **/ LinphoneCall * linphone_core_invite(LinphoneCore *lc, const char *url){ LinphoneCall *call; - LinphoneCallParams *p=linphone_core_create_default_call_parameters (lc); + LinphoneCallParams *p=linphone_core_create_call_params(lc, NULL); p->has_video &= !!lc->video_policy.automatically_initiate; call=linphone_core_invite_with_params(lc,url,p); linphone_call_params_destroy(p); @@ -3088,7 +3029,7 @@ LinphoneCall * linphone_core_invite_with_params(LinphoneCore *lc, const char *ur **/ LinphoneCall * linphone_core_invite_address(LinphoneCore *lc, const LinphoneAddress *addr){ LinphoneCall *call; - LinphoneCallParams *p=linphone_core_create_default_call_parameters(lc); + LinphoneCallParams *p=linphone_core_create_call_params(lc, NULL); p->has_video &= !!lc->video_policy.automatically_initiate; call=linphone_core_invite_address_with_params (lc,addr,p); linphone_call_params_destroy(p); @@ -3138,21 +3079,6 @@ void linphone_configure_op(LinphoneCore *lc, SalOp *op, const LinphoneAddress *d sal_op_cnx_ip_to_0000_if_sendonly_enable(op,lp_config_get_default_int(lc->config,"sip","cnx_ip_to_0000_if_sendonly_enabled",0)); /*also set in linphone_call_new_incoming*/ } -/** - * Initiates an outgoing call given a destination LinphoneAddress - * - * @ingroup call_control - * @param lc the LinphoneCore object - * @param addr the destination of the call (sip address). - @param params call parameters - * - * The LinphoneAddress can be constructed directly using linphone_address_new(), or - * created by linphone_core_interpret_url(). - * The application doesn't own a reference to the returned LinphoneCall object. - * Use linphone_call_ref() to safely keep the LinphoneCall pointer valid within your application. - * - * @return a LinphoneCall object or NULL in case of failure -**/ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const LinphoneAddress *addr, const LinphoneCallParams *params) { const char *from=NULL; @@ -3400,16 +3326,16 @@ int linphone_core_accept_early_media_with_params(LinphoneCore* lc, LinphoneCall* // if parameters are passed, update the media description if ( params ) { linphone_call_set_new_params(call,params); - linphone_call_make_local_media_description ( lc,call ); + linphone_call_make_local_media_description (call); sal_call_set_local_media_description ( call->op,call->localdesc ); sal_op_set_sent_custom_header ( call->op,params->custom_headers ); } - sal_call_notify_ringing(call->op,TRUE); + sal_call_notify_ringing(call->op, TRUE); linphone_call_set_state(call,LinphoneCallIncomingEarlyMedia,"Incoming call early media"); md=sal_call_get_final_media_description(call->op); - if (md) linphone_core_update_streams(lc,call,md); + if (md) linphone_core_update_streams(lc, call, md, call->state); return 0; }else{ ms_error("Bad state %s for linphone_core_accept_early_media_with_params()", linphone_call_state_to_string(call->state)); @@ -3438,7 +3364,7 @@ int linphone_core_start_update_call(LinphoneCore *lc, LinphoneCall *call){ linphone_call_fill_media_multicast_addr(call); - if (!no_user_consent) linphone_call_make_local_media_description(lc,call); + if (!no_user_consent) linphone_call_make_local_media_description(call); #ifdef BUILD_UPNP if(call->upnp_session != NULL) { linphone_core_update_local_media_description_from_upnp(call->localdesc, call->upnp_session); @@ -3486,12 +3412,13 @@ int linphone_core_start_update_call(LinphoneCore *lc, LinphoneCall *call){ **/ int linphone_core_update_call(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params){ int err=0; - LinphoneCallState nextstate; + LinphoneCallState nextstate, initial_state; + #if defined(VIDEO_ENABLED) && defined(BUILD_UPNP) bool_t has_video = FALSE; #endif - switch(call->state){ + switch(initial_state=call->state){ case LinphoneCallIncomingReceived: case LinphoneCallIncomingEarlyMedia: case LinphoneCallOutgoingRinging: @@ -3499,6 +3426,8 @@ int linphone_core_update_call(LinphoneCore *lc, LinphoneCall *call, const Linpho nextstate=LinphoneCallEarlyUpdating; break; case LinphoneCallStreamsRunning: + case LinphoneCallPaused: + case LinphoneCallPausedByRemote: nextstate=LinphoneCallUpdating; break; default: @@ -3507,6 +3436,7 @@ int linphone_core_update_call(LinphoneCore *lc, LinphoneCall *call, const Linpho } if (params!=NULL){ + call->broken = FALSE; linphone_call_set_state(call,nextstate,"Updating call"); #if defined(VIDEO_ENABLED) && defined(BUILD_UPNP) has_video = call->params->has_video; @@ -3544,14 +3474,18 @@ int linphone_core_update_call(LinphoneCore *lc, LinphoneCall *call, const Linpho } } #endif //defined(VIDEO_ENABLED) && defined(BUILD_UPNP) - err = linphone_core_start_update_call(lc, call); + if ((err = linphone_core_start_update_call(lc, call)) && call->state!=initial_state) { + /*Restore initial state*/ + linphone_call_set_state(call,initial_state,"Restore initial state"); + } + }else{ #ifdef VIDEO_ENABLED if ((call->videostream != NULL) && (call->state == LinphoneCallStreamsRunning)) { video_stream_set_sent_video_size(call->videostream,linphone_core_get_preferred_video_size(lc)); video_stream_set_fps(call->videostream, linphone_core_get_preferred_framerate(lc)); if (call->camera_enabled && call->videostream->cam!=lc->video_conf.device){ - video_stream_change_camera(call->videostream,lc->video_conf.device); + video_stream_change_camera(call->videostream, lc->video_conf.device); }else video_stream_update_video_params(call->videostream); } #endif @@ -3573,14 +3507,23 @@ int linphone_core_update_call(LinphoneCore *lc, LinphoneCall *call, const Linpho * Then, when the user responds to dialog prompt, it becomes possible to call linphone_core_accept_call_update() to answer * the reINVITE, with eventually video enabled in the LinphoneCallParams argument. * - * @return 0 if successful, -1 if the linphone_core_defer_call_update() was done outside a #LinphoneCallUpdatedByRemote notification, which is illegal. + * The #LinphoneCallUpdatedByRemote notification can also arrive when receiving an INVITE without SDP. In such case, an unchanged offer is made + * in the 200Ok, and when the ACK containing the SDP answer is received, #LinphoneCallUpdatedByRemote is triggered to notify the application of possible + * changes in the media session. However in such case defering the update has no meaning since we just generating an offer. + * + * @return 0 if successful, -1 if the linphone_core_defer_call_update() was done outside a valid #LinphoneCallUpdatedByRemote notification. **/ int linphone_core_defer_call_update(LinphoneCore *lc, LinphoneCall *call){ if (call->state==LinphoneCallUpdatedByRemote){ + if (call->expect_media_in_ack){ + ms_error("linphone_core_defer_call_update() is not possible during a late offer incoming reINVITE (INVITE without SDP)"); + return -1; + } call->defer_update=TRUE; return 0; + }else{ + ms_error("linphone_core_defer_call_update() not done in state LinphoneCallUpdatedByRemote"); } - ms_error("linphone_core_defer_call_update() not done in state LinphoneCallUpdatedByRemote"); return -1; } @@ -3592,16 +3535,15 @@ int linphone_core_start_accept_call_update(LinphoneCore *lc, LinphoneCall *call, return 0; } } - linphone_call_make_local_media_description(lc,call); + linphone_call_make_local_media_description(call); linphone_call_update_remote_session_id_and_ver(call); - linphone_call_stop_ice_for_inactive_streams(call); sal_call_set_local_media_description(call->op,call->localdesc); sal_call_accept(call->op); md=sal_call_get_final_media_description(call->op); + linphone_call_stop_ice_for_inactive_streams(call, md); if (md && !sal_media_description_empty(md)){ - linphone_core_update_streams (lc,call,md); - linphone_call_fix_call_parameters(call); + linphone_core_update_streams(lc, call, md, next_state); } linphone_call_set_state(call,next_state,state_info); return 0; @@ -3627,11 +3569,15 @@ int linphone_core_start_accept_call_update(LinphoneCore *lc, LinphoneCall *call, * @return 0 if successful, -1 otherwise (actually when this function call is performed outside ot #LinphoneCallUpdatedByRemote state). **/ int linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params){ - if (call->state!=LinphoneCallUpdatedByRemote){ + if (call->state != LinphoneCallUpdatedByRemote){ ms_error("linphone_core_accept_update(): invalid state %s to call this function.", linphone_call_state_to_string(call->state)); return -1; } + if (call->expect_media_in_ack){ + ms_error("linphone_core_accept_call_update() is not possible during a late offer incoming reINVITE (INVITE without SDP)"); + return -1; + } return _linphone_core_accept_call_update(lc, call, params, call->prevstate, linphone_call_state_to_string(call->prevstate)); } @@ -3652,7 +3598,6 @@ int _linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, cons return 0; } if (params==NULL){ - linphone_call_params_enable_video(call->params, lc->video_policy.automatically_accept || call->current_params->has_video); if (!sal_call_is_offerer(call->op)) { /*reset call param for multicast because this param is only relevant when offering*/ linphone_call_params_enable_audio_multicast(call->params,FALSE); @@ -3731,7 +3676,7 @@ int linphone_core_accept_call_with_params(LinphoneCore *lc, LinphoneCall *call, SalOp *replaced; SalMediaDescription *new_md; bool_t was_ringing=FALSE; - MSList * iterator; + MSList * iterator, *copy; if (call==NULL){ //if just one call is present answer the only one ... @@ -3753,26 +3698,24 @@ int linphone_core_accept_call_with_params(LinphoneCore *lc, LinphoneCall *call, } - for (iterator=ms_list_copy(linphone_core_get_calls(lc));iterator!=NULL;iterator=iterator->next) { + for (iterator=copy=ms_list_copy(linphone_core_get_calls(lc));iterator!=NULL;iterator=iterator->next) { LinphoneCall *a_call=(LinphoneCall*)iterator->data; if (a_call==call) continue; switch(a_call->state){ - case LinphoneCallOutgoingInit: - case LinphoneCallOutgoingProgress: - case LinphoneCallOutgoingRinging: - case LinphoneCallOutgoingEarlyMedia: - - ms_message("Already existing call [%p] in state [%s], canceling it before accepting new call [%p]" ,a_call - ,linphone_call_state_to_string(a_call->state) - ,call); + case LinphoneCallOutgoingInit: + case LinphoneCallOutgoingProgress: + case LinphoneCallOutgoingRinging: + case LinphoneCallOutgoingEarlyMedia: + ms_message("Already existing call [%p] in state [%s], canceling it before accepting new call [%p]",a_call + ,linphone_call_state_to_string(a_call->state) + ,call); linphone_core_terminate_call(lc,a_call); break; default: break; /*nothing to do*/ } - } - if (iterator) ms_list_free(iterator); + ms_list_free(copy); /* check if this call is supposed to replace an already running one*/ replaced=sal_call_get_replaces(call->op); @@ -3803,15 +3746,9 @@ int linphone_core_accept_call_with_params(LinphoneCore *lc, LinphoneCall *call, /*try to be best-effort in giving real local or routable contact address */ linphone_call_set_contact_op(call); if (params){ - const SalMediaDescription *md = sal_call_get_remote_media_description(call->op); linphone_call_set_new_params(call,params); - // There might not be a md if the INVITE was lacking an SDP - // In this case we use the parameters as is. - if (md) { - linphone_call_set_compatible_incoming_call_parameters(call, md); - } linphone_call_prepare_ice(call,TRUE); - linphone_call_make_local_media_description(lc,call); + linphone_call_make_local_media_description(call); sal_call_set_local_media_description(call->op,call->localdesc); sal_op_set_sent_custom_header(call->op,params->custom_headers); } @@ -3825,20 +3762,20 @@ int linphone_core_accept_call_with_params(LinphoneCore *lc, LinphoneCall *call, ms_snd_card_set_preferred_sample_rate(lc->sound_conf.capt_sndcard, call->localdesc->streams[0].max_rate); } - if (!was_ringing && call->audiostream->ms.state==MSStreamInitialized){ + if (!was_ringing && call->audiostream->ms.state==MSStreamInitialized && !lc->use_files){ audio_stream_prepare_sound(call->audiostream,lc->sound_conf.play_sndcard,lc->sound_conf.capt_sndcard); } linphone_call_update_remote_session_id_and_ver(call); - linphone_call_stop_ice_for_inactive_streams(call); + sal_call_accept(call->op); linphone_core_notify_display_status(lc,_("Connected.")); lc->current_call=call; linphone_call_set_state(call,LinphoneCallConnected,"Connected"); new_md=sal_call_get_final_media_description(call->op); + linphone_call_stop_ice_for_inactive_streams(call, new_md); if (new_md){ - linphone_core_update_streams(lc, call, new_md); - linphone_call_fix_call_parameters(call); + linphone_core_update_streams(lc, call, new_md, LinphoneCallStreamsRunning); linphone_call_set_state(call,LinphoneCallStreamsRunning,"Connected (streams running)"); }else call->expect_media_in_ack=TRUE; @@ -3916,9 +3853,11 @@ int linphone_core_terminate_call(LinphoneCore *lc, LinphoneCall *the_call) { call = the_call; } + ms_message("Terminate call [%p] which is currently in state %s", call, linphone_call_state_to_string(call->state)); switch (call->state) { case LinphoneCallReleased: case LinphoneCallEnd: + case LinphoneCallError: ms_warning("No need to terminate a call [%p] in state [%s]",call,linphone_call_state_to_string(call->state)); return -1; case LinphoneCallIncomingReceived: @@ -4021,10 +3960,8 @@ int linphone_core_pause_call(LinphoneCore *lc, LinphoneCall *call){ } /* Internal version that does not play tone indication*/ -int _linphone_core_pause_call(LinphoneCore *lc, LinphoneCall *call) -{ +int _linphone_core_pause_call(LinphoneCore *lc, LinphoneCall *call){ const char *subject=NULL; - LinphoneCallParams *params; if (call->state!=LinphoneCallStreamsRunning && call->state!=LinphoneCallPausedByRemote){ ms_warning("Cannot pause this call, it is not active."); @@ -4038,15 +3975,8 @@ int _linphone_core_pause_call(LinphoneCore *lc, LinphoneCall *call) ms_error("No reason to pause this call, it is already paused or inactive."); return -1; } - params = linphone_call_params_copy(call->params); - linphone_call_params_set_audio_direction(params, LinphoneMediaDirectionSendOnly); - if (lp_config_get_int(lc->config, "sip", "inactive_video_on_pause", 0)) { - linphone_call_params_set_video_direction(params, LinphoneMediaDirectionInactive); - } else { - linphone_call_params_set_video_direction(params, LinphoneMediaDirectionSendOnly); - } - linphone_call_make_local_media_description_with_params(lc, call, params); - linphone_call_params_unref(params); + linphone_call_set_state(call, LinphoneCallPausing, "Pausing call"); + linphone_call_make_local_media_description(call); #ifdef BUILD_UPNP if(call->upnp_session != NULL) { linphone_core_update_local_media_description_from_upnp(call->localdesc, call->upnp_session); @@ -4058,9 +3988,8 @@ int _linphone_core_pause_call(LinphoneCore *lc, LinphoneCall *call) } lc->current_call=NULL; linphone_core_notify_display_status(lc,_("Pausing the current call...")); - if (call->audiostream || call->videostream) + if (call->audiostream || call->videostream || call->textstream) linphone_call_stop_media_streams (call); - linphone_call_set_state(call,LinphoneCallPausing,"Pausing call"); call->paused_by_app=FALSE; return 0; } @@ -4127,7 +4056,7 @@ int linphone_core_resume_call(LinphoneCore *lc, LinphoneCall *call){ prevents the participants to hear it while the 200OK comes back.*/ if (call->audiostream) audio_stream_play(call->audiostream, NULL); - linphone_call_make_local_media_description(lc,call); + linphone_call_make_local_media_description(call); #ifdef BUILD_UPNP if(call->upnp_session != NULL) { linphone_core_update_local_media_description_from_upnp(call->localdesc, call->upnp_session); @@ -4179,7 +4108,7 @@ LinphoneCall *linphone_core_get_call_by_remote_address(LinphoneCore *lc, const c } return call; } -LinphoneCall *linphone_core_get_call_by_remote_address2(LinphoneCore *lc, LinphoneAddress *raddr){ +LinphoneCall *linphone_core_get_call_by_remote_address2(LinphoneCore *lc, const LinphoneAddress *raddr){ MSList *elem=ms_list_find_custom(lc->calls,(int (*)(const void*,const void *))remote_address_compare,raddr); if (elem) return (LinphoneCall*) elem->data; @@ -4913,7 +4842,7 @@ static void linphone_core_mute_audio_stream(LinphoneCore *lc, AudioStream *st, b } 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); } @@ -5154,15 +5083,42 @@ LinphoneFirewallPolicy linphone_core_get_firewall_policy(const LinphoneCore *lc) * Call log related functions * ******************************************************************************/ -const MSList * linphone_core_get_call_logs(LinphoneCore *lc){ +void linphone_core_set_call_logs_database_path(LinphoneCore *lc, const char *path) { + if (lc->logs_db_file){ + ms_free(lc->logs_db_file); + lc->logs_db_file = NULL; + } + if (path) { + lc->logs_db_file = ms_strdup(path); + linphone_core_call_log_storage_init(lc); + + linphone_core_migrate_logs_from_rc_to_db(lc); + } +} + +const MSList* linphone_core_get_call_logs(LinphoneCore *lc) { +#ifdef CALL_LOGS_STORAGE_ENABLED + if (lc->logs_db) { + linphone_core_get_call_history(lc); + } +#endif return lc->call_logs; } -void linphone_core_clear_call_logs(LinphoneCore *lc){ +void linphone_core_clear_call_logs(LinphoneCore *lc) { + bool_t call_logs_sqlite_db_found = FALSE; lc->missed_calls=0; - ms_list_for_each(lc->call_logs,(void (*)(void*))linphone_call_log_unref); - lc->call_logs=ms_list_free(lc->call_logs); - call_logs_write_to_config_file(lc); +#ifdef CALL_LOGS_STORAGE_ENABLED + if (lc->logs_db) { + call_logs_sqlite_db_found = TRUE; + linphone_core_delete_call_history(lc); + } +#endif + if (!call_logs_sqlite_db_found) { + ms_list_for_each(lc->call_logs, (void (*)(void*))linphone_call_log_unref); + lc->call_logs = ms_list_free(lc->call_logs); + call_logs_write_to_config_file(lc); + } } int linphone_core_get_missed_calls_count(LinphoneCore *lc) { @@ -5173,13 +5129,85 @@ void linphone_core_reset_missed_calls_count(LinphoneCore *lc) { lc->missed_calls=0; } -void linphone_core_remove_call_log(LinphoneCore *lc, LinphoneCallLog *cl){ - lc->call_logs = ms_list_remove(lc->call_logs, cl); - call_logs_write_to_config_file(lc); - linphone_call_log_unref(cl); +void linphone_core_remove_call_log(LinphoneCore *lc, LinphoneCallLog *cl) { + bool_t call_logs_sqlite_db_found = FALSE; +#ifdef CALL_LOGS_STORAGE_ENABLED + if (lc->logs_db) { + call_logs_sqlite_db_found = TRUE; + linphone_core_delete_call_log(lc, cl); + } +#endif + if (!call_logs_sqlite_db_found) { + lc->call_logs = ms_list_remove(lc->call_logs, cl); + call_logs_write_to_config_file(lc); + linphone_call_log_unref(cl); + } +} + +void linphone_core_migrate_logs_from_rc_to_db(LinphoneCore *lc) { + MSList *logs_to_migrate = NULL; + LpConfig *lpc = NULL; + int original_logs_count, migrated_logs_count; + int i; + +#ifndef CALL_LOGS_STORAGE_ENABLED + ms_warning("linphone has been compiled without sqlite, can't migrate call logs"); + return; +#endif + if (!lc) { + return; + } + + lpc = linphone_core_get_config(lc); + if (!lpc) { + ms_warning("this core has been started without a rc file, nothing to migrate"); + return; + } + if (lp_config_get_int(lpc, "misc", "call_logs_migration_done", 0) == 1) { + ms_warning("the call logs migration has already been done, skipping..."); + return; + } + + // This is because there must have been a call previously to linphone_core_call_log_storage_init + lc->call_logs = ms_list_free_with_data(lc->call_logs, (void (*)(void*))linphone_call_log_unref); + + call_logs_read_from_config_file(lc); + if (!lc->call_logs) { + ms_warning("nothing to migrate, skipping..."); + return; + } + + logs_to_migrate = lc->call_logs; + lc->call_logs = NULL; + // We can't use ms_list_for_each because logs_to_migrate are listed in the wrong order (latest first), and we want to store the logs latest last + for (i = ms_list_size(logs_to_migrate) - 1; i >= 0; i--) { + LinphoneCallLog *log = (LinphoneCallLog *) ms_list_nth_data(logs_to_migrate, i); + linphone_core_store_call_log(lc, log); + } + + original_logs_count = ms_list_size(logs_to_migrate); + migrated_logs_count = ms_list_size(lc->call_logs); + if (original_logs_count == migrated_logs_count) { + int i = 0; + ms_debug("call logs migration successful: %i logs migrated", ms_list_size(lc->call_logs)); + lp_config_set_int(lpc, "misc", "call_logs_migration_done", 1); + + for (; i < original_logs_count; i++) { + char logsection[32]; + snprintf(logsection, sizeof(logsection), "call_log_%i", i); + lp_config_clean_section(lpc, logsection); + } + } else { + ms_error("not as many logs saved in db has logs read from rc (%i in rc against %i in db)!", original_logs_count, migrated_logs_count); + } + + ms_list_free_with_data(logs_to_migrate, (void (*)(void*))linphone_call_log_unref); } +/******************************************************************************* + * Video related functions * + ******************************************************************************/ static void toggle_video_preview(LinphoneCore *lc, bool_t val){ @@ -5192,7 +5220,7 @@ static void toggle_video_preview(LinphoneCore *lc, bool_t val){ video_preview_set_size(lc->previewstream,vsize); if (display_filter) video_preview_set_display_filter_name(lc->previewstream,display_filter); - if (lc->preview_window_id!=0) + if (lc->preview_window_id != NULL) video_preview_set_native_window_id(lc->previewstream,lc->preview_window_id); video_preview_set_fps(lc->previewstream,linphone_core_get_preferred_framerate(lc)); video_preview_start(lc->previewstream,lc->video_conf.device); @@ -5492,7 +5520,7 @@ float linphone_core_get_static_picture_fps(LinphoneCore *lc) { * * @ingroup media_parameters **/ -unsigned long linphone_core_get_native_video_window_id(const LinphoneCore *lc){ +void * linphone_core_get_native_video_window_id(const LinphoneCore *lc){ if (lc->video_window_id) { /* case where the video id was previously set by the app*/ return lc->video_window_id; @@ -5508,13 +5536,17 @@ unsigned long linphone_core_get_native_video_window_id(const LinphoneCore *lc){ } /* unsets the video id for all calls (indeed it may be kept by filters or videostream object itself by paused calls)*/ -static void unset_video_window_id(LinphoneCore *lc, bool_t preview, unsigned long id){ +static void unset_video_window_id(LinphoneCore *lc, bool_t preview, void *id){ #ifdef VIDEO_ENABLED LinphoneCall *call; MSList *elem; #endif - if (id!=0 && id!=-1) { + if ((id != NULL) +#ifndef _WIN32 + && ((unsigned long)id != (unsigned long)-1) +#endif + ){ ms_error("Invalid use of unset_video_window_id()"); return; } @@ -5531,13 +5563,12 @@ static void unset_video_window_id(LinphoneCore *lc, bool_t preview, unsigned lon #endif } -/** - * @ingroup media_parameters - * Set the native video window id where the video is to be displayed. - * For MacOS, Linux, Windows: if not set or zero the core will create its own window, unless the special id -1 is given. -**/ -void linphone_core_set_native_video_window_id(LinphoneCore *lc, unsigned long id){ - if (id==0 || id==(unsigned long)-1){ +void linphone_core_set_native_video_window_id(LinphoneCore *lc, void *id){ + if ((id == NULL) +#ifndef _WIN32 + || ((unsigned long)id == (unsigned long)-1) +#endif + ){ unset_video_window_id(lc,FALSE,id); } lc->video_window_id=id; @@ -5556,7 +5587,7 @@ void linphone_core_set_native_video_window_id(LinphoneCore *lc, unsigned long id * * @ingroup media_parameters **/ -unsigned long linphone_core_get_native_preview_window_id(const LinphoneCore *lc){ +void * linphone_core_get_native_preview_window_id(const LinphoneCore *lc){ if (lc->preview_window_id){ /*case where the id was set by the app previously*/ return lc->preview_window_id; @@ -5579,8 +5610,12 @@ unsigned long linphone_core_get_native_preview_window_id(const LinphoneCore *lc) * This has to be used in conjonction with linphone_core_use_preview_window(). * MacOS, Linux, Windows: if not set or zero the core will create its own window, unless the special id -1 is given. **/ -void linphone_core_set_native_preview_window_id(LinphoneCore *lc, unsigned long id){ - if (id==0 || id==(unsigned long)-1){ +void linphone_core_set_native_preview_window_id(LinphoneCore *lc, void *id){ + if ((id == NULL) +#ifndef _WIN32 + || ((unsigned long)id == (unsigned long)-1) +#endif + ) { unset_video_window_id(lc,TRUE,id); } lc->preview_window_id=id; @@ -5681,11 +5716,6 @@ static MSVideoSizeDef supported_resolutions[]={ { { 0,0 } , NULL } }; -/** - * Returns the zero terminated table of supported video resolutions. - * - * @ingroup media_parameters -**/ const MSVideoSizeDef *linphone_core_get_supported_video_sizes(LinphoneCore *lc){ return supported_resolutions; } @@ -5736,13 +5766,6 @@ static void update_preview_size(LinphoneCore *lc, MSVideoSize oldvsize, MSVideoS } } -/** - * Sets the preferred video size. - * - * @ingroup media_parameters - * This applies only to the stream that is captured and sent to the remote party, - * since we accept all standard video size on the receive path. -**/ void linphone_core_set_preferred_video_size(LinphoneCore *lc, MSVideoSize vsize){ if (video_size_supported(vsize)){ MSVideoSize oldvsize=lc->video_conf.preview_vsize; @@ -5758,15 +5781,6 @@ void linphone_core_set_preferred_video_size(LinphoneCore *lc, MSVideoSize vsize) } } -/** - * Sets the video size for the captured (preview) video. - * This method is for advanced usage where a video capture must be set independently of the size of the stream actually sent through the call. - * This allows for example to have the preview window with HD resolution even if due to bandwidth constraint the sent video size is small. - * Using this feature increases the CPU consumption, since a rescaling will be done internally. - * @ingroup media_parameters - * @param lc the linphone core - * @param vsize the video resolution choosed for capuring and previewing. It can be (0,0) to not request any specific preview size and let the core optimize the processing. -**/ void linphone_core_set_preview_video_size(LinphoneCore *lc, MSVideoSize vsize){ MSVideoSize oldvsize; if (vsize.width==0 && vsize.height==0){ @@ -5786,25 +5800,10 @@ void linphone_core_set_preview_video_size(LinphoneCore *lc, MSVideoSize vsize){ lp_config_set_string(lc->config,"video","preview_size",video_size_get_name(vsize)); } -/** - * Returns video size for the captured video if it was previously set by linphone_core_set_preview_video_size(), otherwise returns a 0,0 size. - * @see linphone_core_set_preview_video_size() - * @ingroup media_parameters - * @param lc the core - * @return a MSVideoSize -**/ MSVideoSize linphone_core_get_preview_video_size(const LinphoneCore *lc){ return lc->video_conf.preview_vsize; } -/** - * Returns the effective video size for the captured video as provided by the camera. - * When preview is disabled or not yet started, this function returns a zeroed video size. - * @see linphone_core_set_preview_video_size() - * @ingroup media_parameters - * @param lc the core - * @return a MSVideoSize -**/ MSVideoSize linphone_core_get_current_preview_video_size(const LinphoneCore *lc){ MSVideoSize ret={0}; #ifndef VIDEO_ENABLED @@ -5817,25 +5816,11 @@ MSVideoSize linphone_core_get_current_preview_video_size(const LinphoneCore *lc) return ret; } -/** - * Sets the preview video size by its name. See linphone_core_set_preview_video_size() for more information about this feature. - * - * @ingroup media_parameters - * Video resolution names are: qcif, svga, cif, vga, 4cif, svga ... -**/ void linphone_core_set_preview_video_size_by_name(LinphoneCore *lc, const char *name){ MSVideoSize vsize=video_size_get_by_name(name); linphone_core_set_preview_video_size(lc,vsize); } -/** - * Sets the preferred video size by its name. - * - * @ingroup media_parameters - * This is identical to linphone_core_set_preferred_video_size() except - * that it takes the name of the video resolution as input. - * Video resolution names are: qcif, svga, cif, vga, 4cif, svga ... -**/ void linphone_core_set_preferred_video_size_by_name(LinphoneCore *lc, const char *name){ MSVideoSize vsize=video_size_get_by_name(name); MSVideoSize default_vsize={MS_VIDEO_SIZE_CIF_W,MS_VIDEO_SIZE_CIF_H}; @@ -5843,11 +5828,6 @@ void linphone_core_set_preferred_video_size_by_name(LinphoneCore *lc, const char else linphone_core_set_preferred_video_size(lc,default_vsize); } -/** - * Returns the current preferred video size for sending. - * - * @ingroup media_parameters -**/ MSVideoSize linphone_core_get_preferred_video_size(const LinphoneCore *lc){ return lc->video_conf.vsize; } @@ -5856,37 +5836,17 @@ char * linphone_core_get_preferred_video_size_name(const LinphoneCore *lc) { return ms_strdup(video_size_get_name(lc->video_conf.vsize)); } -/** - * Set the preferred frame rate for video. - * Based on the available bandwidth constraints and network conditions, the video encoder - * remains free to lower the framerate. There is no warranty that the preferred frame rate be the actual framerate. - * used during a call. Default value is 0, which means "use encoder's default fps value". - * @ingroup media_parameters - * @param lc the LinphoneCore - * @param fps the target frame rate in number of frames per seconds. -**/ void linphone_core_set_preferred_framerate(LinphoneCore *lc, float fps){ lc->video_conf.fps=fps; if (linphone_core_ready(lc)) lp_config_set_float(lc->config,"video","framerate",fps); } -/** - * Returns the preferred video framerate, previously set by linphone_core_set_preferred_framerate(). - * @ingroup media_parameters - * @param lc the linphone core - * @return frame rate in number of frames per seconds. -**/ + float linphone_core_get_preferred_framerate(LinphoneCore *lc){ return lc->video_conf.fps; } -/** - * Ask the core to stream audio from and to files, instead of using the soundcard. - * @ingroup media_parameters - * @param[in] lc LinphoneCore object - * @param[in] yesno A boolean value asking to stream audio from and to files or not. -**/ void linphone_core_set_use_files(LinphoneCore *lc, bool_t yesno){ lc->use_files=yesno; } @@ -5895,15 +5855,6 @@ const char * linphone_core_get_play_file(const LinphoneCore *lc) { return lc->play_file; } -/** - * Sets a wav file to be played when putting somebody on hold, - * or when files are used instead of soundcards (see linphone_core_set_use_files()). - * - * The file must be a 16 bit linear wav file. - * @ingroup media_parameters - * @param[in] lc LinphoneCore object - * @param[in] file The path to the file to be played when putting somebody on hold. -**/ void linphone_core_set_play_file(LinphoneCore *lc, const char *file){ LinphoneCall *call=linphone_core_get_current_call(lc); if (lc->play_file!=NULL){ @@ -5921,16 +5872,6 @@ const char * linphone_core_get_record_file(const LinphoneCore *lc) { return lc->rec_file; } -/** - * Sets a wav file where incoming stream is to be recorded, - * when files are used instead of soundcards (see linphone_core_set_use_files()). - * - * This feature is different from call recording (linphone_call_params_set_record_file()) - * The file will be a 16 bit linear wav file. - * @ingroup media_parameters - * @param[in] lc LinphoneCore object - * @param[in] file The path to the file where incoming stream is to be recorded. -**/ void linphone_core_set_record_file(LinphoneCore *lc, const char *file){ LinphoneCall *call=linphone_core_get_current_call(lc); if (lc->rec_file!=NULL){ @@ -5964,18 +5905,18 @@ static MSFilter *get_audio_resource(LinphoneCore *lc, LinphoneAudioResourceType return NULL; } if (lc->ringstream==NULL){ - float amp=lp_config_get_float(lc->config,"sound","dtmf_player_amp",0.1); + float amp=lp_config_get_float(lc->config,"sound","dtmf_player_amp",0.1f); MSSndCard *ringcard=lc->sound_conf.lsd_card ?lc->sound_conf.lsd_card : lc->sound_conf.ring_sndcard; if (ringcard == NULL) return NULL; ringstream=lc->ringstream=ring_start(NULL,0,ringcard); ms_filter_call_method(lc->ringstream->gendtmf,MS_DTMF_GEN_SET_DEFAULT_AMPLITUDE,&); - lc->dmfs_playing_start_time=time(NULL); + lc->dmfs_playing_start_time = ms_get_cur_time_ms()/1000; }else{ ringstream=lc->ringstream; if (lc->dmfs_playing_start_time!=0) - lc->dmfs_playing_start_time=time(NULL); + lc->dmfs_playing_start_time = ms_get_cur_time_ms()/1000; } if (rtype==LinphoneToneGenerator) return ringstream->gendtmf; if (rtype==LinphoneLocalPlayer) return ringstream->source; @@ -6241,7 +6182,8 @@ void sip_config_uninit(LinphoneCore *lc) sal_iterate(lc->sal); for(elem=config->proxies;elem!=NULL;elem=ms_list_next(elem)){ LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)(elem->data); - still_registered|=linphone_proxy_config_is_registered(cfg); + LinphoneRegistrationState state = linphone_proxy_config_get_state(cfg); + still_registered|=(state==LinphoneRegistrationOk||state==LinphoneRegistrationProgress); } ms_usleep(100000); } @@ -6298,6 +6240,11 @@ void rtp_config_uninit(LinphoneCore *lc) } else { lp_config_set_range(lc->config, "rtp", "video_rtp_port", config->video_rtp_min_port, config->video_rtp_max_port); } + if (config->text_rtp_min_port == config->text_rtp_max_port) { + lp_config_set_int(lc->config, "rtp", "text_rtp_port", config->text_rtp_min_port); + } else { + lp_config_set_range(lc->config, "rtp", "text_rtp_port", config->text_rtp_min_port, config->text_rtp_max_port); + } lp_config_set_int(lc->config,"rtp","audio_jitt_comp",config->audio_jitt_comp); lp_config_set_int(lc->config,"rtp","video_jitt_comp",config->video_jitt_comp); lp_config_set_int(lc->config,"rtp","nortp_timeout",config->nortp_timeout); @@ -6371,15 +6318,17 @@ static void codecs_config_uninit(LinphoneCore *lc) _linphone_core_codec_config_write(lc); ms_list_free_with_data(lc->codecs_conf.audio_codecs, (void (*)(void*))payload_type_destroy); ms_list_free_with_data(lc->codecs_conf.video_codecs, (void (*)(void*))payload_type_destroy); + ms_list_free_with_data(lc->codecs_conf.text_codecs, (void (*)(void*))payload_type_destroy); } void ui_config_uninit(LinphoneCore* lc) { ms_message("Destroying friends."); if (lc->friends){ - ms_list_for_each(lc->friends,(void (*)(void *))linphone_friend_unref); - ms_list_free(lc->friends); - lc->friends=NULL; + lc->friends = ms_list_free_with_data(lc->friends, (void (*)(void *))linphone_friend_unref); + } + if (lc->subscribers){ + lc->subscribers = ms_list_free_with_data(lc->subscribers, (void (*)(void *))linphone_friend_unref); } if (lc->presence_model) { linphone_presence_model_unref(lc->presence_model); @@ -6406,7 +6355,7 @@ LpConfig * linphone_core_create_lp_config(LinphoneCore *lc, const char *filename static void linphone_core_uninit(LinphoneCore *lc) { - linphone_core_free_hooks(lc); + linphone_task_list_free(&lc->hooks); lc->video_conf.show_local = FALSE; while(lc->calls) @@ -6419,6 +6368,9 @@ static void linphone_core_uninit(LinphoneCore *lc) if (lc->friends) /* FIXME we should wait until subscription to complete*/ ms_list_for_each(lc->friends,(void (*)(void *))linphone_friend_close_subscriptions); + + lc->chatrooms = ms_list_free_with_data(lc->chatrooms, (MSIterateFunc)linphone_chat_room_release); + linphone_core_set_state(lc,LinphoneGlobalShutdown,"Shutting down"); #ifdef VIDEO_ENABLED if (lc->previewstream!=NULL){ @@ -6447,9 +6399,6 @@ static void linphone_core_uninit(LinphoneCore *lc) } #endif //BUILD_UPNP - ms_list_for_each(lc->chatrooms, (MSIterateFunc)linphone_chat_room_release); - lc->chatrooms = ms_list_free(lc->chatrooms); - if (lp_config_needs_commit(lc->config)) lp_config_sync(lc->config); lp_config_destroy(lc->config); lc->config = NULL; /* Mark the config as NULL to block further calls */ @@ -6475,12 +6424,10 @@ static void linphone_core_uninit(LinphoneCore *lc) if (lc->chat_db_file){ ms_free(lc->chat_db_file); } - if(lc->presence_model){ - linphone_presence_model_unref(lc->presence_model); - } linphone_core_free_payload_types(lc); if (lc->supported_formats) ms_free(lc->supported_formats); linphone_core_message_storage_close(lc); + linphone_core_call_log_storage_close(lc); ms_exit(); linphone_core_set_state(lc,LinphoneGlobalOff,"Off"); linphone_core_deactivate_log_serialization_if_needed(); @@ -6511,8 +6458,13 @@ static void set_network_reachable(LinphoneCore* lc,bool_t isReachable, time_t cu if (!lc->network_reachable){ linphone_core_invalidate_friend_subscriptions(lc); sal_reset_transports(lc->sal); + /*mark all calls as broken, so that they can be either dropped immediately or restaured when network will be back*/ + ms_list_for_each(lc->calls, (MSIterateFunc) linphone_call_set_broken); }else{ linphone_core_resolve_stun_server(lc); + if (lp_config_get_int(lc->config, "net", "recreate_sockets_when_network_is_up", 0)){ + ms_list_for_each(lc->calls, (MSIterateFunc)linphone_call_refresh_sockets); + } } #ifdef BUILD_UPNP if(lc->upnp == NULL) { @@ -6611,6 +6563,7 @@ void linphone_core_soundcard_hint_check( LinphoneCore* lc){ MSList* the_calls = lc->calls; LinphoneCall* call = NULL; bool_t dont_need_sound = TRUE; + bool_t use_rtp_io = lp_config_get_int(lc->config, "sound", "rtp_io", FALSE); /* check if the remaining calls are paused */ while( the_calls ){ @@ -6623,7 +6576,7 @@ void linphone_core_soundcard_hint_check( LinphoneCore* lc){ } /* if no more calls or all calls are paused, we can free the soundcard */ - if ( (lc->calls==NULL || dont_need_sound) && !lc->use_files){ + if ( (lc->calls==NULL || dont_need_sound) && !lc->use_files && !use_rtp_io){ ms_message("Notifying soundcard that we don't need it anymore for calls."); notify_soundcard_usage(lc,FALSE); } @@ -6694,6 +6647,21 @@ LinphonePayloadType* linphone_core_find_payload_type(LinphoneCore* lc, const cha return NULL; } +const char* linphone_configuring_state_to_string(LinphoneConfiguringState cs){ + switch(cs){ + case LinphoneConfiguringSuccessful: + return "LinphoneConfiguringSuccessful"; + break; + case LinphoneConfiguringFailed: + return "LinphoneConfiguringFailed"; + break; + case LinphoneConfiguringSkipped: + return "LinphoneConfiguringSkipped"; + break; + } + return NULL; +} + const char *linphone_global_state_to_string(LinphoneGlobalState gs){ switch(gs){ case LinphoneGlobalOff: @@ -6718,12 +6686,14 @@ LinphoneGlobalState linphone_core_get_global_state(const LinphoneCore *lc){ return lc->state; } -LinphoneCallParams *linphone_core_create_default_call_parameters(LinphoneCore *lc){ + +static LinphoneCallParams *_create_call_params(LinphoneCore *lc){ LinphoneCallParams *p=linphone_call_params_new(); linphone_core_init_default_params(lc, p); return p; } + /** * Create a LinphoneCallParams suitable for linphone_core_invite_with_params(), linphone_core_accept_call_with_params(), linphone_core_accept_early_media_with_params(), * linphone_core_accept_call_update(). @@ -6734,8 +6704,12 @@ LinphoneCallParams *linphone_core_create_default_call_parameters(LinphoneCore *l * @ingroup call_control */ LinphoneCallParams *linphone_core_create_call_params(LinphoneCore *lc, LinphoneCall *call){ - if (!call) return linphone_core_create_default_call_parameters(lc); - return linphone_call_params_copy(call->params); + if (!call) return _create_call_params(lc); + if (call->params){ + return linphone_call_params_copy(call->params); + } + ms_error("linphone_core_create_call_params(): call [%p] is not in a state where call params can be created or used.", call); + return NULL; } const char *linphone_reason_to_string(LinphoneReason err){ @@ -6759,7 +6733,7 @@ const char *linphone_reason_to_string(LinphoneReason err){ case LinphoneReasonIOError: return "IO error"; case LinphoneReasonDoNotDisturb: - return "Do not distrub"; + return "Do not disturb"; case LinphoneReasonUnauthorized: return "Unauthorized"; case LinphoneReasonNotAcceptable: @@ -6852,47 +6826,18 @@ void linphone_core_set_max_calls(LinphoneCore *lc, int max) { lc->max_calls=max; } -typedef struct Hook{ - LinphoneCoreIterateHook fun; - void *data; -}Hook; - -static Hook *hook_new(LinphoneCoreIterateHook hook, void *hook_data){ - Hook *h=ms_new0(Hook,1); - h->fun=hook; - h->data=hook_data; - return h; -} - -static void hook_invoke(Hook *h){ - h->fun(h->data); -} void linphone_core_add_iterate_hook(LinphoneCore *lc, LinphoneCoreIterateHook hook, void *hook_data){ - lc->hooks=ms_list_append(lc->hooks,hook_new(hook,hook_data)); + linphone_task_list_add(&lc->hooks, hook, hook_data); } static void linphone_core_run_hooks(LinphoneCore *lc){ - ms_list_for_each(lc->hooks,(void (*)(void*))hook_invoke); -} - -static void linphone_core_free_hooks(LinphoneCore *lc){ - ms_list_for_each(lc->hooks,(void (*)(void*))ms_free); - ms_list_free(lc->hooks); - lc->hooks=NULL; + linphone_task_list_run(&lc->hooks); } void linphone_core_remove_iterate_hook(LinphoneCore *lc, LinphoneCoreIterateHook hook, void *hook_data){ - MSList *elem; - for(elem=lc->hooks;elem!=NULL;elem=elem->next){ - Hook *h=(Hook*)elem->data; - if (h->fun==hook && h->data==hook_data){ - lc->hooks = ms_list_remove_link(lc->hooks,elem); - ms_free(h); - return; - } - } - ms_error("linphone_core_remove_iterate_hook(): No such hook found."); + linphone_task_list_remove(&lc->hooks, hook, hook_data); + } void linphone_core_set_zrtp_secrets_file(LinphoneCore *lc, const char* file){ @@ -7006,27 +6951,44 @@ bool_t linphone_core_media_encryption_supported(const LinphoneCore *lc, Linphone int linphone_core_set_media_encryption(LinphoneCore *lc, LinphoneMediaEncryption menc) { const char *type="none"; - int ret=0; - if (menc == LinphoneMediaEncryptionSRTP){ - if (!ms_srtp_supported()){ - ms_warning("SRTP not supported by library."); - type="none"; - ret=-1; - }else type="srtp"; - }else if (menc == LinphoneMediaEncryptionZRTP){ - if (!ms_zrtp_available()){ - ms_warning("ZRTP not supported by library."); - type="none"; - ret=-1; - }else type="zrtp"; - }else if (menc == LinphoneMediaEncryptionDTLS){ - if (!ms_dtls_srtp_available()){ - ms_warning("DTLS not supported by library."); - type="none"; - ret=-1; - }else type="dtls"; - } + int ret=-1; + switch(menc){ + case LinphoneMediaEncryptionSRTP: + if (!ms_srtp_supported()){ + ms_warning("SRTP not supported by library."); + type="none"; + ret=-1; + }else{ + type="srtp"; + ret = 0; + } + break; + case LinphoneMediaEncryptionZRTP: + if (!ms_zrtp_available()){ + ms_warning("ZRTP not supported by library."); + type="none"; + ret=-1; + }else { + type="zrtp"; + ret = 0; + } + break; + case LinphoneMediaEncryptionDTLS: + if (!ms_dtls_srtp_available()){ + ms_warning("DTLS not supported by library."); + type="none"; + ret=-1; + }else { + type="dtls"; + ret = 0; + } + break; + case LinphoneMediaEncryptionNone: + type = "none"; + ret = 0; + break; + } lp_config_set_string(lc->config,"sip","media_encryption",type); return ret; } @@ -7055,11 +7017,13 @@ void linphone_core_set_media_encryption_mandatory(LinphoneCore *lc, bool_t m) { } void linphone_core_init_default_params(LinphoneCore*lc, LinphoneCallParams *params) { + params->has_audio = TRUE; params->has_video=linphone_core_video_enabled(lc) && lc->video_policy.automatically_initiate; params->media_encryption=linphone_core_get_media_encryption(lc); params->in_conference=FALSE; + params->realtimetext_enabled = linphone_core_realtime_text_enabled(lc); params->privacy=LinphonePrivacyDefault; - params->avpf_enabled=FALSE; + params->avpf_enabled=linphone_core_get_avpf_mode(lc); params->audio_dir=LinphoneMediaDirectionSendRecv; params->video_dir=LinphoneMediaDirectionSendRecv; params->real_early_media=lp_config_get_int(lc->config,"misc","real_early_media",FALSE); @@ -7343,6 +7307,14 @@ bool_t linphone_core_video_multicast_enabled(const LinphoneCore *lc) { return lc->rtp_conf.video_multicast_enabled; } +void linphone_core_set_video_preset(LinphoneCore *lc, const char *preset) { + lp_config_set_string(lc->config, "video", "preset", preset); +} + +const char * linphone_core_get_video_preset(const LinphoneCore *lc) { + return lp_config_get_string(lc->config, "video", "preset", NULL); +} + #ifdef ANDROID static int linphone_core_call_void_method(jobject obj, jmethodID id) { JNIEnv *env=ms_get_jni_env(); @@ -7374,3 +7346,55 @@ void linphone_core_multicast_lock_release(LinphoneCore *lc) { ms_warning("No wifi lock configured or not usable for core [%p]",lc); } #endif + + +LINPHONE_PUBLIC const char *linphone_core_log_collection_upload_state_to_string(const LinphoneCoreLogCollectionUploadState lcus) { + switch (lcus) { + case LinphoneCoreLogCollectionUploadStateInProgress : return "LinphoneCoreLogCollectionUploadStateInProgress"; + case LinphoneCoreLogCollectionUploadStateDelivered : return "LinphoneCoreLogCollectionUploadStateDelivered"; + case LinphoneCoreLogCollectionUploadStateNotDelivered : return "LinphoneCoreLogCollectionUploadStateNotDelivered"; + } + return "UNKNOWN"; +} + +bool_t linphone_core_realtime_text_enabled(LinphoneCore *lc) { + return lc->text_conf.enabled; +} +void linphone_core_set_http_proxy_host(LinphoneCore *lc, const char *host) { + lp_config_set_string(lc->config,"sip","http_proxy_host",host); + if (lc->sal) { + sal_set_http_proxy_host(lc->sal,host); + sal_set_http_proxy_port(lc->sal,linphone_core_get_http_proxy_port(lc)); /*to make sure default value is set*/ + } +} + +void linphone_core_set_http_proxy_port(LinphoneCore *lc, int port) { + lp_config_set_int(lc->config,"sip","http_proxy_port",port); + if (lc->sal) + sal_set_http_proxy_port(lc->sal,port); +} +const char *linphone_core_get_http_proxy_host(const LinphoneCore *lc) { + return lp_config_get_string(lc->config,"sip","http_proxy_host",NULL); +} + +int linphone_core_get_http_proxy_port(const LinphoneCore *lc) { + return lp_config_get_int(lc->config,"sip","http_proxy_port",3128); +} + +const char* linphone_transport_to_string(LinphoneTransportType transport) { + return sal_transport_to_string((SalTransport)transport); +} + +LinphoneTransportType linphone_transport_parse(const char* transport) { + return (LinphoneTransportType)sal_transport_parse(transport); +} + +const char *linphone_stream_type_to_string(const LinphoneStreamType type) { + switch (type) { + case LinphoneStreamTypeAudio: return "LinphoneStreamTypeAudio"; + case LinphoneStreamTypeVideo: return "LinphoneStreamTypeVideo"; + case LinphoneStreamTypeText: return "LinphoneStreamTypeText"; + case LinphoneStreamTypeUnknown: return "LinphoneStreamTypeUnknown"; + } + return "INVALID"; +} diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 22788939a..6d6444f03 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -41,11 +41,25 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define LINPHONE_PUBLIC MS2_PUBLIC #endif +#ifndef LINPHONE_DEPRECATED +#if defined(_MSC_VER) + #define LINPHONE_DEPRECATED __declspec(deprecated) +#else + #define LINPHONE_DEPRECATED __attribute__ ((deprecated)) +#endif +#endif + + #ifdef __cplusplus extern "C" { #endif struct _LinphoneCore; +struct _LinphoneChatRoom; +struct _LinphoneAuthInfo; +struct _SipSetupContext; +struct _LinphoneInfoMessage; + /** * Linphone core main object created by function linphone_core_new() . * @ingroup initializing @@ -109,6 +123,30 @@ enum _LinphoneTransportType{ **/ typedef enum _LinphoneTransportType LinphoneTransportType; +/** + * Enum describing the stream types. + * @ingroup initializing +**/ +enum _LinphoneStreamType { + LinphoneStreamTypeAudio, + LinphoneStreamTypeVideo, + LinphoneStreamTypeText, + LinphoneStreamTypeUnknown /* WARNING: Make sure this value remains the last one in the list */ +}; + +/** + * Enum describing the stream types. + * @ingroup initializing +**/ +typedef enum _LinphoneStreamType LinphoneStreamType; +/** + * Function returning a humain readable value for LinphoneStreamType. + * @param LinphoneStreamType + * @returns + * @ingroup initializing + **/ + +LINPHONE_PUBLIC const char *linphone_stream_type_to_string(const LinphoneStreamType); /** * Object that represents a SIP address. * @@ -373,6 +411,7 @@ LINPHONE_PUBLIC const char* linphone_privacy_to_string(LinphonePrivacy privacy); #include "content.h" #include "event.h" #include "linphonefriend.h" +#include "xmlrpc.h" #else #include "linphone/buffer.h" #include "linphone/call_log.h" @@ -380,6 +419,7 @@ LINPHONE_PUBLIC const char* linphone_privacy_to_string(LinphonePrivacy privacy); #include "linphone/content.h" #include "linphone/event.h" #include "linphone/linphonefriend.h" +#include "linphone/xmlrpc.h" #endif LINPHONE_PUBLIC LinphoneAddress * linphone_address_new(const char *addr); @@ -421,10 +461,6 @@ LINPHONE_PUBLIC void linphone_address_destroy(LinphoneAddress *u); */ LINPHONE_PUBLIC LinphoneAddress * linphone_core_create_address(LinphoneCore *lc, const char *address); -struct _SipSetupContext; - - -struct _LinphoneInfoMessage; /** * The LinphoneInfoMessage is an object representing an informational message sent or received by the core. **/ @@ -465,8 +501,9 @@ typedef struct _LinphoneVideoPolicy LinphoneVideoPolicy; * @{ **/ -#define LINPHONE_CALL_STATS_AUDIO 0 -#define LINPHONE_CALL_STATS_VIDEO 1 +#define LINPHONE_CALL_STATS_AUDIO ((int)LinphoneStreamTypeAudio) +#define LINPHONE_CALL_STATS_VIDEO ((int)LinphoneStreamTypeVideo) +#define LINPHONE_CALL_STATS_TEXT ((int)LinphoneStreamTypeText) /** * Enum describing ICE states. @@ -515,7 +552,6 @@ typedef enum _LinphoneUpnpState LinphoneUpnpState; #define LINPHONE_CALL_STATS_SENT_RTCP_UPDATE (1 << 1) /**< sent_rtcp field of LinphoneCallStats object has been updated */ #define LINPHONE_CALL_STATS_PERIODICAL_UPDATE (1 << 2) /**< Every seconds LinphoneCallStats object has been updated */ - /** * The LinphoneCallStats objects carries various statistic informations regarding quality of audio or video streams. * @@ -549,6 +585,8 @@ struct _LinphoneCallStats { int updated; /**< Tell which RTCP packet has been updated (received_rtcp or sent_rtcp). Can be either LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE or LINPHONE_CALL_STATS_SENT_RTCP_UPDATE */ float rtcp_download_bandwidth; /** In case this #LinphoneProxyConfig has been added to #LinphoneCore, follows the linphone_proxy_config_edit() rule. - * @param obj object pointer - * @param val if true, registration will be engaged - */ -LINPHONE_PUBLIC void linphone_proxy_config_enable_register(LinphoneProxyConfig *obj, bool_t val); -#define linphone_proxy_config_enableregister linphone_proxy_config_enable_register -LINPHONE_PUBLIC void linphone_proxy_config_edit(LinphoneProxyConfig *obj); -LINPHONE_PUBLIC int linphone_proxy_config_done(LinphoneProxyConfig *obj); -/** - * Indicates either or not, PUBLISH must be issued for this #LinphoneProxyConfig . - *
In case this #LinphoneProxyConfig has been added to #LinphoneCore, follows the linphone_proxy_config_edit() rule. - * @param obj object pointer - * @param val if true, publish will be engaged - * - */ -LINPHONE_PUBLIC void linphone_proxy_config_enable_publish(LinphoneProxyConfig *obj, bool_t val); -/** - * Set the publish expiration time in second. - * @param obj proxy config - * @param expires in second - * */ - -LINPHONE_PUBLIC void linphone_proxy_config_set_publish_expires(LinphoneProxyConfig *obj, int expires); -/** - * get the publish expiration time in second. Default value is the registration expiration value. - * @param obj proxy config - * @return expires in second - * */ - -LINPHONE_PUBLIC int linphone_proxy_config_get_publish_expires(const LinphoneProxyConfig *obj); - -LINPHONE_PUBLIC void linphone_proxy_config_set_dial_escape_plus(LinphoneProxyConfig *cfg, bool_t val); -LINPHONE_PUBLIC void linphone_proxy_config_set_dial_prefix(LinphoneProxyConfig *cfg, const char *prefix); - - /** - * Indicates whether quality statistics during call should be stored and sent to a collector according to RFC 6035. - * @param[in] cfg #LinphoneProxyConfig object - * @param[in] enable True to sotre quality statistics and sent them to the collector, false to disable it. - */ -LINPHONE_PUBLIC void linphone_proxy_config_enable_quality_reporting(LinphoneProxyConfig *cfg, bool_t enable); - -/** - * Indicates whether quality statistics during call should be stored and sent to a collector according to RFC 6035. - * @param[in] cfg #LinphoneProxyConfig object - * @return True if quality repotring is enabled, false otherwise. - */ -LINPHONE_PUBLIC bool_t linphone_proxy_config_quality_reporting_enabled(LinphoneProxyConfig *cfg); - - /** - * Set the SIP address of the collector end-point when using quality reporting. This SIP address - * should be used on server-side to process packets directly then discard packets. Collector address - * should be a non existing account and should not received any packets. - * @param[in] cfg #LinphoneProxyConfig object - * @param[in] collector SIP address of the collector end-point. - */ -LINPHONE_PUBLIC void linphone_proxy_config_set_quality_reporting_collector(LinphoneProxyConfig *cfg, const char *collector); - - /** - * Get the SIP address of the collector end-point when using quality reporting. This SIP address - * should be used on server-side to process packets directly then discard packets. Collector address - * should be a non existing account and should not received any packets. - * @param[in] cfg #LinphoneProxyConfig object - * @return The SIP address of the collector end-point. - */ -LINPHONE_PUBLIC const char *linphone_proxy_config_get_quality_reporting_collector(const LinphoneProxyConfig *cfg); - -/** - * Set the interval between 2 interval reports sending when using quality reporting. If call exceed interval size, an - * interval report will be sent to the collector. On call termination, a session report will be sent - * for the remaining period. Value must be 0 (disabled) or positive. - * @param[in] cfg #LinphoneProxyConfig object - * @param[in] interval The interval in seconds, 0 means interval reports are disabled. - */ -LINPHONE_PUBLIC void linphone_proxy_config_set_quality_reporting_interval(LinphoneProxyConfig *cfg, uint8_t interval); - -/** - * Get the interval between interval reports when using quality reporting. - * @param[in] cfg #LinphoneProxyConfig object - * @return The interval in seconds, 0 means interval reports are disabled. - */ - -LINPHONE_PUBLIC int linphone_proxy_config_get_quality_reporting_interval(LinphoneProxyConfig *cfg); - -/** - * Get the registration state of the given proxy config. - * @param[in] obj #LinphoneProxyConfig object. - * @return The registration state of the proxy config. -**/ -LINPHONE_PUBLIC LinphoneRegistrationState linphone_proxy_config_get_state(const LinphoneProxyConfig *obj); - -LINPHONE_PUBLIC bool_t linphone_proxy_config_is_registered(const LinphoneProxyConfig *obj); - -/** - * Get the domain name of the given proxy config. - * @param[in] cfg #LinphoneProxyConfig object. - * @return The domain name of the proxy config. -**/ -LINPHONE_PUBLIC const char *linphone_proxy_config_get_domain(const LinphoneProxyConfig *cfg); - -/** - * Get the realm of the given proxy config. - * @param[in] cfg #LinphoneProxyConfig object. - * @return The realm of the proxy config. -**/ -LINPHONE_PUBLIC const char *linphone_proxy_config_get_realm(const LinphoneProxyConfig *cfg); -/** - * Set the realm of the given proxy config. - * @param[in] cfg #LinphoneProxyConfig object. - * @param[in] realm New realm value. - * @return The realm of the proxy config. -**/ -LINPHONE_PUBLIC void linphone_proxy_config_set_realm(LinphoneProxyConfig *cfg, const char * realm); - -LINPHONE_PUBLIC const char *linphone_proxy_config_get_route(const LinphoneProxyConfig *obj); -LINPHONE_PUBLIC const char *linphone_proxy_config_get_identity(const LinphoneProxyConfig *obj); -LINPHONE_PUBLIC bool_t linphone_proxy_config_publish_enabled(const LinphoneProxyConfig *obj); -LINPHONE_PUBLIC const char *linphone_proxy_config_get_server_addr(const LinphoneProxyConfig *obj); -#define linphone_proxy_config_get_addr linphone_proxy_config_get_server_addr -LINPHONE_PUBLIC int linphone_proxy_config_get_expires(const LinphoneProxyConfig *obj); -LINPHONE_PUBLIC bool_t linphone_proxy_config_register_enabled(const LinphoneProxyConfig *obj); -LINPHONE_PUBLIC void linphone_proxy_config_refresh_register(LinphoneProxyConfig *obj); -LINPHONE_PUBLIC void linphone_proxy_config_pause_register(LinphoneProxyConfig *obj); -LINPHONE_PUBLIC const char *linphone_proxy_config_get_contact_parameters(const LinphoneProxyConfig *obj); -LINPHONE_PUBLIC void linphone_proxy_config_set_contact_parameters(LinphoneProxyConfig *obj, const char *contact_params); -LINPHONE_PUBLIC void linphone_proxy_config_set_contact_uri_parameters(LinphoneProxyConfig *obj, const char *contact_uri_params); -LINPHONE_PUBLIC const char* linphone_proxy_config_get_contact_uri_parameters(const LinphoneProxyConfig *obj); - -/** - * Get the #LinphoneCore object to which is associated the #LinphoneProxyConfig. - * @param[in] obj #LinphoneProxyConfig object. - * @return The #LinphoneCore object to which is associated the #LinphoneProxyConfig. -**/ -LINPHONE_PUBLIC LinphoneCore * linphone_proxy_config_get_core(const LinphoneProxyConfig *obj); - -LINPHONE_PUBLIC bool_t linphone_proxy_config_get_dial_escape_plus(const LinphoneProxyConfig *cfg); -LINPHONE_PUBLIC const char * linphone_proxy_config_get_dial_prefix(const LinphoneProxyConfig *cfg); - -/** - * Get the reason why registration failed when the proxy config state is LinphoneRegistrationFailed. - * @param[in] cfg #LinphoneProxyConfig object. - * @return The reason why registration failed for this proxy config. -**/ -LINPHONE_PUBLIC LinphoneReason linphone_proxy_config_get_error(const LinphoneProxyConfig *cfg); - -/** - * Get detailed information why registration failed when the proxy config state is LinphoneRegistrationFailed. - * @param[in] cfg #LinphoneProxyConfig object. - * @return The details why registration failed for this proxy config. -**/ -LINPHONE_PUBLIC const LinphoneErrorInfo *linphone_proxy_config_get_error_info(const LinphoneProxyConfig *cfg); - -/** - * Get the transport from either service route, route or addr. - * @param[in] cfg #LinphoneProxyConfig object. - * @return The transport as a string (I.E udp, tcp, tls, dtls) -**/ -LINPHONE_PUBLIC const char* linphone_proxy_config_get_transport(const LinphoneProxyConfig *cfg); - - -/* 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); -LINPHONE_PUBLIC SipSetupContext *linphone_proxy_config_get_sip_setup_context(LinphoneProxyConfig *cfg); -LINPHONE_PUBLIC SipSetup *linphone_proxy_config_get_sip_setup(LinphoneProxyConfig *cfg); - -/** - * Detect if the given input is a phone number or not. - * @param proxy #LinphoneProxyConfig argument, unused yet but may contain useful data. Can be NULL. - * @param username string to parse. - * @return TRUE if input is a phone number, FALSE otherwise. -**/ -LINPHONE_PUBLIC bool_t linphone_proxy_config_is_phone_number(LinphoneProxyConfig *proxy, const char *username); - -/** - * Normalize a human readable phone number into a basic string. 888-444-222 becomes 888444222 - * or +33888444222 depending on the #LinphoneProxyConfig object. However this argument is OPTIONNAL - * and if not provided, a default one will be used. - * This function will always generate a normalized username; if input is not a phone number, output will be a copy of input. - * @param proxy #LinphoneProxyConfig object containing country code and/or escape symbol. If NULL passed, will use default configuration. - * @param username the string to parse - * @param result the newly normalized number - * @param result_len the size of the normalized number \a result - * @return TRUE if a phone number was recognized, FALSE otherwise. - */ -LINPHONE_PUBLIC bool_t linphone_proxy_config_normalize_number(LinphoneProxyConfig *proxy, const char *username, - char *result, size_t result_len); - -/** - * Set default privacy policy for all calls routed through this proxy. - * @param cfg #LinphoneProxyConfig object to be modified - * @param privacy LinphonePrivacy to configure privacy - * */ -LINPHONE_PUBLIC void linphone_proxy_config_set_privacy(LinphoneProxyConfig *cfg, LinphonePrivacyMask privacy); -/** - * Get default privacy policy for all calls routed through this proxy. - * @param cfg #LinphoneProxyConfig object - * @return Privacy mode - * */ -LINPHONE_PUBLIC LinphonePrivacyMask linphone_proxy_config_get_privacy(const LinphoneProxyConfig *cfg); -/** - * Set the http file transfer server to be used for content type application/vnd.gsma.rcs-ft-http+xml - * @param cfg #LinphoneProxyConfig object to be modified - * @param server_url URL of the file server like https://file.linphone.org/upload.php - * */ -LINPHONE_PUBLIC void linphone_proxy_config_set_file_transfer_server(LinphoneProxyConfig *cfg, const char * server_url); -/** - * Get the http file transfer server to be used for content type application/vnd.gsma.rcs-ft-http+xml - * @param cfg #LinphoneProxyConfig object - * @return URL of the file server like https://file.linphone.org/upload.php - * */ -LINPHONE_PUBLIC const char* linphone_proxy_config_get_file_transfer_server(const LinphoneProxyConfig *cfg); - -/** - * Indicates whether AVPF/SAVPF must be used for calls using this proxy config. - * @param[in] cfg #LinphoneProxyConfig object - * @param[in] enable True to enable AVPF/SAVF, false to disable it. - * @deprecated use linphone_proxy_config_set_avpf_mode() - */ -LINPHONE_PUBLIC void linphone_proxy_config_enable_avpf(LinphoneProxyConfig *cfg, bool_t enable); - -/** - * Indicates whether AVPF/SAVPF is being used for calls using this proxy config. - * @param[in] cfg #LinphoneProxyConfig object - * @return True if AVPF/SAVPF is enabled, false otherwise. - * @deprecated use linphone_proxy_config_set_avpf_mode() - */ -LINPHONE_PUBLIC bool_t linphone_proxy_config_avpf_enabled(LinphoneProxyConfig *cfg); - -/** - * Set the interval between regular RTCP reports when using AVPF/SAVPF. - * @param[in] cfg #LinphoneProxyConfig object - * @param[in] interval The interval in seconds (between 0 and 5 seconds). - */ -LINPHONE_PUBLIC void linphone_proxy_config_set_avpf_rr_interval(LinphoneProxyConfig *cfg, uint8_t interval); - -/** - * Get the interval between regular RTCP reports when using AVPF/SAVPF. - * @param[in] cfg #LinphoneProxyConfig object - * @return The interval in seconds. - */ -LINPHONE_PUBLIC uint8_t linphone_proxy_config_get_avpf_rr_interval(const LinphoneProxyConfig *cfg); - -/** - * Get enablement status of RTCP feedback (also known as AVPF profile). - * @param[in] cfg the proxy config - * @return the enablement mode, which can be LinphoneAVPFDefault (use LinphoneCore's mode), LinphoneAVPFEnabled (avpf is enabled), or LinphoneAVPFDisabled (disabled). -**/ -LINPHONE_PUBLIC LinphoneAVPFMode linphone_proxy_config_get_avpf_mode(const LinphoneProxyConfig *cfg); - -/** - * Enable the use of RTCP feedback (also known as AVPF profile). - * @param[in] cfg the proxy config - * @param[in] mode the enablement mode, which can be LinphoneAVPFDefault (use LinphoneCore's mode), LinphoneAVPFEnabled (avpf is enabled), or LinphoneAVPFDisabled (disabled). -**/ -LINPHONE_PUBLIC void linphone_proxy_config_set_avpf_mode(LinphoneProxyConfig *cfg, LinphoneAVPFMode mode); - -/** - * Obtain the value of a header sent by the server in last answer to REGISTER. - * @param cfg the proxy config object - * @param header_name the header name for which to fetch corresponding value - * @return the value of the queried header. -**/ -LINPHONE_PUBLIC const char *linphone_proxy_config_get_custom_header(LinphoneProxyConfig *cfg, const char *header_name); - -/** - * Set the value of a custom header sent to the server in REGISTERs request. - * @param cfg the proxy config object - * @param header_name the header name - * @param header_value the header's value -**/ -LINPHONE_PUBLIC void linphone_proxy_config_set_custom_header(LinphoneProxyConfig *cfg, const char *header_name, const char *header_value); /** * @} -**/ + */ -typedef struct _LinphoneAccountCreator{ - LinphoneCore *lc; - struct _SipSetupContext *ssctx; - char *username; - char *password; - char *domain; - char *route; - char *email; - int suscribe; - bool_t succeeded; -}LinphoneAccountCreator; - -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; +#include "linphone_proxy_config.h" /** * @addtogroup authentication @@ -1358,7 +1190,13 @@ LINPHONE_PUBLIC LinphoneAuthInfo * linphone_auth_info_new_from_config_file(LpCon */ -struct _LinphoneChatRoom; +#ifdef IN_LINPHONE +#include "account_creator.h" +#else +#include "linphone/account_creator.h" +#endif + + /** * @addtogroup chatroom * @{ @@ -1400,7 +1238,7 @@ typedef enum _LinphoneChatMessageState { * @param ud application user data * @deprecated */ -typedef void (*LinphoneChatMessageStateChangedCb)(LinphoneChatMessage* msg,LinphoneChatMessageState state,void* ud); +typedef LINPHONE_DEPRECATED void (*LinphoneChatMessageStateChangedCb)(LinphoneChatMessage* msg,LinphoneChatMessageState state,void* ud); /** * Call back used to notify message delivery status @@ -1437,15 +1275,72 @@ typedef LinphoneBuffer * (*LinphoneChatMessageCbsFileTransferSendCb)(LinphoneCha typedef void (*LinphoneChatMessageCbsFileTransferProgressIndicationCb)(LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t total); LINPHONE_PUBLIC void linphone_core_set_chat_database_path(LinphoneCore *lc, const char *path); -LINPHONE_PUBLIC LinphoneChatRoom * linphone_core_create_chat_room(LinphoneCore *lc, const char *to); -LINPHONE_PUBLIC LinphoneChatRoom * linphone_core_get_or_create_chat_room(LinphoneCore *lc, const char *to); + + +/** + * Get a chat room whose peer is the supplied address. If it does not exist yet, it will be created. + * No reference is transfered to the application. The LinphoneCore keeps a reference on the chat room. + * @param lc the linphone core + * @param addr a linphone address. + * @return #LinphoneChatRoom where messaging can take place. +**/ LINPHONE_PUBLIC LinphoneChatRoom *linphone_core_get_chat_room(LinphoneCore *lc, const LinphoneAddress *addr); +/** + * Get a chat room for messaging from a sip uri like sip:joe@sip.linphone.org. If it does not exist yet, it will be created. + * No reference is transfered to the application. The LinphoneCore keeps a reference on the chat room. + * @param lc The linphone core + * @param to The destination address for messages. + * @return #LinphoneChatRoom where messaging can take place. +**/ LINPHONE_PUBLIC LinphoneChatRoom *linphone_core_get_chat_room_from_uri(LinphoneCore *lc, const char *to); + +/** + * Removes a chatroom including all message history from the LinphoneCore. + * @param lc The linphone core + * @param to The chatroom. +**/ +LINPHONE_PUBLIC void linphone_core_delete_chat_room(LinphoneCore *lc, LinphoneChatRoom *cr); + +/** + * Inconditionnaly disable incoming chat messages. + * @param lc the core + * @param deny_reason the deny reason (#LinphoneReasonNone has no effect). +**/ LINPHONE_PUBLIC void linphone_core_disable_chat(LinphoneCore *lc, LinphoneReason deny_reason); +/** + * Enable reception of incoming chat messages. + * By default it is enabled but it can be disabled with linphone_core_disable_chat(). + * @param lc the core +**/ LINPHONE_PUBLIC void linphone_core_enable_chat(LinphoneCore *lc); +/** + * Returns whether chat is enabled. +**/ LINPHONE_PUBLIC bool_t linphone_core_chat_enabled(const LinphoneCore *lc); -LINPHONE_PUBLIC void linphone_chat_room_destroy(LinphoneChatRoom *cr); +/** + * Destroy a LinphoneChatRoom. + * @param cr #LinphoneChatRoom object + * @deprecated Use linphone_chat_room_unref() instead. + */ +LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_chat_room_destroy(LinphoneChatRoom *cr); +/** + * Create a message attached to a dedicated chat room; + * @param cr the chat room. + * @param message text message, NULL if absent. + * @return a new #LinphoneChatMessage + */ LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_message(LinphoneChatRoom *cr,const char* message); +/** + * Create a message attached to a dedicated chat room; + * @param cr the chat room. + * @param message text message, NULL if absent. + * @param external_body_url the URL given in external body or NULL. + * @param state the LinphoneChatMessage.State of the message. + * @param time the time_t at which the message has been received/sent. + * @param is_read TRUE if the message should be flagged as read, FALSE otherwise. + * @param is_incoming TRUE if the message has been received, FALSE otherwise. + * @return a new #LinphoneChatMessage + */ LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_message_2(LinphoneChatRoom *cr, const char* message, const char* external_body_url, LinphoneChatMessageState state, time_t time, bool_t is_read, bool_t is_incoming); /** @@ -1475,20 +1370,43 @@ LINPHONE_PUBLIC void *linphone_chat_room_get_user_data(const LinphoneChatRoom *c **/ LINPHONE_PUBLIC void linphone_chat_room_set_user_data(LinphoneChatRoom *cr, void *ud); -/** - * Create a message attached to a dedicated chat room with a particular content. Use #linphone_chat_room_file_transfer_send to initiate the transfer - * @param[in] cr the chat room. - * @param[in] initial_content #LinphoneContent initial content. #LinphoneCoreVTable.file_transfer_send is invoked later to notify file transfer progress and collect next chunk of the message if #LinphoneContentSourceType.src_type is set to LINPHONE_CONTENT_SOURCE_CHUNKED_BUFFER. + /** + * Create a message attached to a dedicated chat room with a particular content. + * Use #linphone_chat_room_send_message to initiate the transfer + * @param cr the chat room. + * @param initial_content #LinphoneContent initial content. #LinphoneCoreVTable.file_transfer_send is invoked later to notify file transfer progress and collect next chunk of the message if #LinphoneContent.data is NULL. * @return a new #LinphoneChatMessage */ -LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_file_transfer_message(LinphoneChatRoom *cr, LinphoneContent* initial_content); +LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_file_transfer_message(LinphoneChatRoom *cr, const LinphoneContent* initial_content); LINPHONE_PUBLIC const LinphoneAddress* linphone_chat_room_get_peer_address(LinphoneChatRoom *cr); -LINPHONE_PUBLIC void linphone_chat_room_send_message(LinphoneChatRoom *cr, const char *msg); -LINPHONE_PUBLIC void linphone_chat_room_send_message2(LinphoneChatRoom *cr, LinphoneChatMessage* msg,LinphoneChatMessageStateChangedCb status_cb,void* ud); +/** + * Send a message to peer member of this chat room. + * @deprecated Use linphone_chat_room_send_chat_message() instead. + * @param cr #LinphoneChatRoom object + * @param msg message to be sent + */ +LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_chat_room_send_message(LinphoneChatRoom *cr, const char *msg); +/** + * Send a message to peer member of this chat room. + * @param cr #LinphoneChatRoom object + * @param msg #LinphoneChatMessage message to be sent + * @param status_cb LinphoneChatMessageStateChangeCb status callback invoked when message is delivered or could not be delivered. May be NULL + * @param ud user data for the status cb. + * @deprecated Use linphone_chat_room_send_chat_message() instead. + * @note The LinphoneChatMessage must not be destroyed until the the callback is called. + * The LinphoneChatMessage reference is transfered to the function and thus doesn't need to be unref'd by the application. + */ +LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_chat_room_send_message2(LinphoneChatRoom *cr, LinphoneChatMessage* msg,LinphoneChatMessageStateChangedCb status_cb,void* ud); +/** + * Send a message to peer member of this chat room. + * @param[in] cr LinphoneChatRoom object + * @param[in] msg LinphoneChatMessage object + * The state of the message sending will be notified via the callbacks defined in the LinphoneChatMessageCbs object that can be obtained + * by calling linphone_chat_message_get_callbacks(). + * The LinphoneChatMessage reference is transfered to the function and thus doesn't need to be unref'd by the application. + */ LINPHONE_PUBLIC void linphone_chat_room_send_chat_message(LinphoneChatRoom *cr, LinphoneChatMessage *msg); -LINPHONE_PUBLIC void linphone_chat_room_update_url(LinphoneChatRoom *cr, LinphoneChatMessage *msg); -LINPHONE_PUBLIC MSList *linphone_chat_room_get_history(LinphoneChatRoom *cr,int nb_message); /** * Mark all messages of the conversation as read @@ -1514,6 +1432,14 @@ LINPHONE_PUBLIC void linphone_chat_room_delete_history(LinphoneChatRoom *cr); */ LINPHONE_PUBLIC int linphone_chat_room_get_history_size(LinphoneChatRoom *cr); +/** + * Gets nb_message most recent messages from cr chat room, sorted from oldest to most recent. + * @param[in] cr The #LinphoneChatRoom object corresponding to the conversation for which messages should be retrieved + * @param[in] nb_message Number of message to retrieve. 0 means everything. + * @return \mslist{LinphoneChatMessage} + */ +LINPHONE_PUBLIC MSList *linphone_chat_room_get_history(LinphoneChatRoom *cr,int nb_message); + /** * Gets the partial list of messages in the given range, sorted from oldest to most recent. * @param[in] cr The #LinphoneChatRoom object corresponding to the conversation for which messages should be retrieved @@ -1542,66 +1468,328 @@ LINPHONE_PUBLIC bool_t linphone_chat_room_is_remote_composing(const LinphoneChat * @return the number of unread messages. */ LINPHONE_PUBLIC int linphone_chat_room_get_unread_messages_count(LinphoneChatRoom *cr); -LINPHONE_PUBLIC LinphoneCore* linphone_chat_room_get_lc(LinphoneChatRoom *cr); +/** + * Returns back pointer to LinphoneCore object. + * @deprecated use linphone_chat_room_get_core() +**/ +LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneCore* linphone_chat_room_get_lc(LinphoneChatRoom *cr); +/** + * Returns back pointer to LinphoneCore object. +**/ LINPHONE_PUBLIC LinphoneCore* linphone_chat_room_get_core(LinphoneChatRoom *cr); -LINPHONE_PUBLIC MSList* linphone_core_get_chat_rooms(LinphoneCore *lc); + +/** + * When realtime text is enabled #linphone_call_params_realtime_text_enabled, #LinphoneCoreIsComposingReceivedCb is call everytime a char is received from peer. + * At the end of remote typing a regular #LinphoneChatMessage is received with committed data from #LinphoneCoreMessageReceivedCb. + * @param[in] msg LinphoneChatMessage + * @returns RFC 4103/T.140 char + */ +LINPHONE_PUBLIC uint32_t linphone_chat_room_get_char(const LinphoneChatRoom *cr); + +/** + * Returns an list of chat rooms + * @param[in] lc #LinphoneCore object + * @return \mslist{LinphoneChatRoom} +**/ +LINPHONE_PUBLIC const MSList* linphone_core_get_chat_rooms(LinphoneCore *lc); LINPHONE_PUBLIC unsigned int linphone_chat_message_store(LinphoneChatMessage *msg); +/** + * Returns a #LinphoneChatMessageState as a string. + */ LINPHONE_PUBLIC const char* linphone_chat_message_state_to_string(const LinphoneChatMessageState state); +/** + * Get the state of the message + *@param message #LinphoneChatMessage obj + *@return #LinphoneChatMessageState + */ LINPHONE_PUBLIC LinphoneChatMessageState linphone_chat_message_get_state(const LinphoneChatMessage* message); +/** + * Duplicate a LinphoneChatMessage +**/ LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_message_clone(const LinphoneChatMessage* message); +/** + * Acquire a reference to the chat message. + * @param msg the chat message + * @return the same chat message +**/ LINPHONE_PUBLIC LinphoneChatMessage * linphone_chat_message_ref(LinphoneChatMessage *msg); +/** + * Release reference to the chat message. + * @param msg the chat message. +**/ LINPHONE_PUBLIC void linphone_chat_message_unref(LinphoneChatMessage *msg); +/** + * Destroys a LinphoneChatMessage. +**/ LINPHONE_PUBLIC void linphone_chat_message_destroy(LinphoneChatMessage* msg); /** @deprecated Use linphone_chat_message_set_from_address() instead. */ #define linphone_chat_message_set_from(msg, addr) linphone_chat_message_set_from_address(msg, addr) +/** + * Set origin of the message + * @param[in] message #LinphoneChatMessage obj + * @param[in] from #LinphoneAddress origin of this message (copied) + */ LINPHONE_PUBLIC void linphone_chat_message_set_from_address(LinphoneChatMessage* message, const LinphoneAddress* addr); /** @deprecated Use linphone_chat_message_get_from_address() instead. */ #define linphone_chat_message_get_from(msg) linphone_chat_message_get_from_address(msg) +/** + * Get origin of the message + * @param[in] message #LinphoneChatMessage obj + * @return #LinphoneAddress + */ LINPHONE_PUBLIC const LinphoneAddress* linphone_chat_message_get_from_address(const LinphoneChatMessage* message); #define linphone_chat_message_set_to(msg, addr) linphone_chat_message_set_to_address(msg, addr) +/** + * Set destination of the message + * @param[in] message #LinphoneChatMessage obj + * @param[in] to #LinphoneAddress destination of this message (copied) + */ LINPHONE_PUBLIC void linphone_chat_message_set_to_address(LinphoneChatMessage* message, const LinphoneAddress* addr); /** @deprecated Use linphone_chat_message_get_to_address() instead. */ #define linphone_chat_message_get_to(msg) linphone_chat_message_get_to_address(msg) +/** + * Get destination of the message + * @param[in] message #LinphoneChatMessage obj + * @return #LinphoneAddress + */ LINPHONE_PUBLIC const LinphoneAddress* linphone_chat_message_get_to_address(const LinphoneChatMessage* message); +/** + * Linphone message can carry external body as defined by rfc2017 + * @param message #LinphoneChatMessage + * @return external body url or NULL if not present. + */ LINPHONE_PUBLIC const char* linphone_chat_message_get_external_body_url(const LinphoneChatMessage* message); +/** + * Linphone message can carry external body as defined by rfc2017 + * + * @param message a LinphoneChatMessage + * @param url ex: access-type=URL; URL="http://www.foo.com/file" + */ LINPHONE_PUBLIC void linphone_chat_message_set_external_body_url(LinphoneChatMessage* message,const char* url); +/** + * Get the file_transfer_information (used by call backs to recover informations during a rcs file transfer) + * + * @param message #LinphoneChatMessage + * @return a pointer to the LinphoneContent structure or NULL if not present. + */ LINPHONE_PUBLIC const LinphoneContent* linphone_chat_message_get_file_transfer_information(const LinphoneChatMessage* message); -LINPHONE_PUBLIC void linphone_chat_message_start_file_download(LinphoneChatMessage* message, LinphoneChatMessageStateChangedCb status_cb, void* ud); -LINPHONE_PUBLIC void linphone_chat_message_download_file(LinphoneChatMessage *message); +/** + * Start the download of the file from remote server + * + * @param message #LinphoneChatMessage + * @param status_cb LinphoneChatMessageStateChangeCb status callback invoked when file is downloaded or could not be downloaded + * @deprecated Use linphone_chat_message_download_file() instead. + */ +LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_chat_message_start_file_download(LinphoneChatMessage* message, LinphoneChatMessageStateChangedCb status_cb, void* ud); +/** + * Start the download of the file referenced in a LinphoneChatMessage from remote server. + * @param[in] message LinphoneChatMessage object. + */ +LINPHONE_PUBLIC int linphone_chat_message_download_file(LinphoneChatMessage *message); +/** + * Cancel an ongoing file transfer attached to this message.(upload or download) + * @param msg #LinphoneChatMessage + */ LINPHONE_PUBLIC void linphone_chat_message_cancel_file_transfer(LinphoneChatMessage* msg); +/** + * Linphone message has an app-specific field that can store a text. The application might want + * to use it for keeping data over restarts, like thumbnail image path. + * @param message #LinphoneChatMessage + * @return the application-specific data or NULL if none has been stored. + */ LINPHONE_PUBLIC const char* linphone_chat_message_get_appdata(const LinphoneChatMessage* message); +/** + * Linphone message has an app-specific field that can store a text. The application might want + * to use it for keeping data over restarts, like thumbnail image path. + * + * Invoking this function will attempt to update the message storage to reflect the changeif it is + * enabled. + * + * @param message #LinphoneChatMessage + * @param data the data to store into the message + */ LINPHONE_PUBLIC void linphone_chat_message_set_appdata(LinphoneChatMessage* message, const char* data); +/** + * Get text part of this message + * @return text or NULL if no text. + */ LINPHONE_PUBLIC const char* linphone_chat_message_get_text(const LinphoneChatMessage* message); +/** + * Get the time the message was sent. + */ LINPHONE_PUBLIC time_t linphone_chat_message_get_time(const LinphoneChatMessage* message); +/** + * User pointer get function + */ LINPHONE_PUBLIC void* linphone_chat_message_get_user_data(const LinphoneChatMessage* message); +/** + *User pointer set function + */ LINPHONE_PUBLIC void linphone_chat_message_set_user_data(LinphoneChatMessage* message,void*); +/** + * Returns the chatroom this message belongs to. +**/ LINPHONE_PUBLIC LinphoneChatRoom* linphone_chat_message_get_chat_room(LinphoneChatMessage *msg); +/** + * get peer address \link linphone_core_get_chat_room() associated to \endlink this #LinphoneChatRoom + * @param cr #LinphoneChatRoom object + * @return #LinphoneAddress peer address + */ LINPHONE_PUBLIC const LinphoneAddress* linphone_chat_message_get_peer_address(LinphoneChatMessage *msg); +/** + * Returns the origin address of a message if it was a outgoing message, or the destination address if it was an incoming message. + *@param message #LinphoneChatMessage obj + *@return #LinphoneAddress + */ LINPHONE_PUBLIC LinphoneAddress *linphone_chat_message_get_local_address(const LinphoneChatMessage* message); +/** + * Add custom headers to the message. + * @param message the message + * @param header_name name of the header_name + * @param header_value header value +**/ LINPHONE_PUBLIC void linphone_chat_message_add_custom_header(LinphoneChatMessage* message, const char *header_name, const char *header_value); +/** + * Retrieve a custom header value given its name. + * @param message the message + * @param header_name header name searched +**/ LINPHONE_PUBLIC const char * linphone_chat_message_get_custom_header(LinphoneChatMessage* message, const char *header_name); +/** + * Returns TRUE if the message has been read, otherwise returns FALSE. + * @param message the message +**/ LINPHONE_PUBLIC bool_t linphone_chat_message_is_read(LinphoneChatMessage* message); +/** + * Returns TRUE if the message has been sent, returns FALSE if the message has been received. + * @param message the message +**/ LINPHONE_PUBLIC bool_t linphone_chat_message_is_outgoing(LinphoneChatMessage* message); +/** + * Returns the id used to identify this message in the storage database + * @param message the message + * @return the id + */ LINPHONE_PUBLIC unsigned int linphone_chat_message_get_storage_id(LinphoneChatMessage* message); LINPHONE_PUBLIC LinphoneReason linphone_chat_message_get_reason(LinphoneChatMessage* msg); +/** + * Get full details about delivery error of a chat message. + * @param msg a LinphoneChatMessage + * @return a LinphoneErrorInfo describing the details. +**/ LINPHONE_PUBLIC const LinphoneErrorInfo *linphone_chat_message_get_error_info(const LinphoneChatMessage *msg); +/** + * Set the path to the file to read from or write to during the file transfer. + * @param[in] msg LinphoneChatMessage object + * @param[in] filepath The path to the file to use for the file transfer. + */ LINPHONE_PUBLIC void linphone_chat_message_set_file_transfer_filepath(LinphoneChatMessage *msg, const char *filepath); +/** + * Get the path to the file to read from or write to during the file transfer. + * @param[in] msg LinphoneChatMessage object + * @return The path to the file to use for the file transfer. + */ LINPHONE_PUBLIC const char * linphone_chat_message_get_file_transfer_filepath(LinphoneChatMessage *msg); + + + +/** + * Fulfill a chat message char by char. Message linked to a Real Time Text Call send char in realtime following RFC 4103/T.140 + * To commit a message, use #linphone_chat_room_send_message + * @param[in] msg LinphoneChatMessage + * @param[in] character T.140 char + * @returns 0 if succeed. + */ +LINPHONE_PUBLIC int linphone_chat_message_put_char(LinphoneChatMessage *msg,uint32_t charater); + +/** + * get Curent Call associated to this chatroom if any + * To commit a message, use #linphone_chat_room_send_message + * @param[in] room LinphoneChatRomm + * @returns LinphoneCall or NULL. + */ +LINPHONE_PUBLIC LinphoneCall *linphone_chat_room_get_call(const LinphoneChatRoom *room); + + +/** + * Get the LinphoneChatMessageCbs object associated with the LinphoneChatMessage. + * @param[in] msg LinphoneChatMessage object + * @return The LinphoneChatMessageCbs object associated with the LinphoneChatMessage. + */ LINPHONE_PUBLIC LinphoneChatMessageCbs * linphone_chat_message_get_callbacks(const LinphoneChatMessage *msg); +/** + * Acquire a reference to the LinphoneChatMessageCbs object. + * @param[in] cbs LinphoneChatMessageCbs object. + * @return The same LinphoneChatMessageCbs object. + */ LINPHONE_PUBLIC LinphoneChatMessageCbs * linphone_chat_message_cbs_ref(LinphoneChatMessageCbs *cbs); +/** + * Release reference to the LinphoneChatMessageCbs object. + * @param[in] cbs LinphoneChatMessageCbs object. + */ LINPHONE_PUBLIC void linphone_chat_message_cbs_unref(LinphoneChatMessageCbs *cbs); +/** + * Retrieve the user pointer associated with the LinphoneChatMessageCbs object. + * @param[in] cbs LinphoneChatMessageCbs object. + * @return The user pointer associated with the LinphoneChatMessageCbs object. + */ LINPHONE_PUBLIC void *linphone_chat_message_cbs_get_user_data(const LinphoneChatMessageCbs *cbs); +/** + * Assign a user pointer to the LinphoneChatMessageCbs object. + * @param[in] cbs LinphoneChatMessageCbs object. + * @param[in] ud The user pointer to associate with the LinphoneChatMessageCbs object. + */ LINPHONE_PUBLIC void linphone_chat_message_cbs_set_user_data(LinphoneChatMessageCbs *cbs, void *ud); +/** + * Get the message state changed callback. + * @param[in] cbs LinphoneChatMessageCbs object. + * @return The current message state changed callback. + */ LINPHONE_PUBLIC LinphoneChatMessageCbsMsgStateChangedCb linphone_chat_message_cbs_get_msg_state_changed(const LinphoneChatMessageCbs *cbs); +/** + * Set the message state changed callback. + * @param[in] cbs LinphoneChatMessageCbs object. + * @param[in] cb The message state changed callback to be used. + */ LINPHONE_PUBLIC void linphone_chat_message_cbs_set_msg_state_changed(LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsMsgStateChangedCb cb); +/** + * Get the file transfer receive callback. + * @param[in] cbs LinphoneChatMessageCbs object. + * @return The current file transfer receive callback. + */ LINPHONE_PUBLIC LinphoneChatMessageCbsFileTransferRecvCb linphone_chat_message_cbs_get_file_transfer_recv(const LinphoneChatMessageCbs *cbs); +/** + * Set the file transfer receive callback. + * @param[in] cbs LinphoneChatMessageCbs object. + * @param[in] cb The file transfer receive callback to be used. + */ LINPHONE_PUBLIC void linphone_chat_message_cbs_set_file_transfer_recv(LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsFileTransferRecvCb cb); +/** + * Get the file transfer send callback. + * @param[in] cbs LinphoneChatMessageCbs object. + * @return The current file transfer send callback. + */ LINPHONE_PUBLIC LinphoneChatMessageCbsFileTransferSendCb linphone_chat_message_cbs_get_file_transfer_send(const LinphoneChatMessageCbs *cbs); +/** + * Set the file transfer send callback. + * @param[in] cbs LinphoneChatMessageCbs object. + * @param[in] cb The file transfer send callback to be used. + */ LINPHONE_PUBLIC void linphone_chat_message_cbs_set_file_transfer_send(LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsFileTransferSendCb cb); +/** + * Get the file transfer progress indication callback. + * @param[in] cbs LinphoneChatMessageCbs object. + * @return The current file transfer progress indication callback. + */ LINPHONE_PUBLIC LinphoneChatMessageCbsFileTransferProgressIndicationCb linphone_chat_message_cbs_get_file_transfer_progress_indication(const LinphoneChatMessageCbs *cbs); -LINPHONE_PUBLIC void linphone_chat_message_cbs_set_file_transfer_progress_indication(LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsFileTransferProgressIndicationCb cb); +/** + * Set the file transfer progress indication callback. + * @param[in] cbs LinphoneChatMessageCbs object. + * @param[in] cb The file transfer progress indication callback to be used. + */ + LINPHONE_PUBLIC void linphone_chat_message_cbs_set_file_transfer_progress_indication(LinphoneChatMessageCbs *cbs, LinphoneChatMessageCbsFileTransferProgressIndicationCb cb); /** * @} @@ -1636,6 +1824,8 @@ typedef enum _LinphoneCoreLogCollectionUploadState { LinphoneCoreLogCollectionUploadStateNotDelivered, /**< Log collection upload was not delivered */ } LinphoneCoreLogCollectionUploadState; +LINPHONE_PUBLIC const char *linphone_core_log_collection_upload_state_to_string(const LinphoneCoreLogCollectionUploadState lcus); + /** * Global state notification callback. * @param lc @@ -1648,7 +1838,7 @@ typedef void (*LinphoneCoreGlobalStateChangedCb)(LinphoneCore *lc, LinphoneGloba * @param lc the LinphoneCore * @param call the call object whose state is changed. * @param cstate the new state of the call - * @param message an informational message about the state. + * @param message a non NULL informational message about the state. */ typedef void (*LinphoneCoreCallStateChangedCb)(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *message); @@ -1664,23 +1854,23 @@ typedef void (*LinphoneCoreCallEncryptionChangedCb)(LinphoneCore *lc, LinphoneCa /** @ingroup Proxies * Registration state notification callback prototype * */ -typedef void (*LinphoneCoreRegistrationStateChangedCb)(LinphoneCore *lc, LinphoneProxyConfig *cfg, LinphoneRegistrationState cstate, const char *message); +typedef void (*LinphoneCoreRegistrationStateChangedCb)(LinphoneCore *lc, LinphoneProxyConfig *cfg, LinphoneRegistrationState cstate, const char *message) ; /** Callback prototype * @deprecated */ -typedef void (*ShowInterfaceCb)(LinphoneCore *lc); +typedef void (*ShowInterfaceCb)(LinphoneCore *lc) ; /** Callback prototype * @deprecated */ -typedef void (*DisplayStatusCb)(LinphoneCore *lc, const char *message); +typedef void (*DisplayStatusCb)(LinphoneCore *lc, const char *message) ; /** Callback prototype * @deprecated */ -typedef void (*DisplayMessageCb)(LinphoneCore *lc, const char *message); +typedef void (*DisplayMessageCb)(LinphoneCore *lc, const char *message) ; /** Callback prototype * @deprecated */ -typedef void (*DisplayUrlCb)(LinphoneCore *lc, const char *message, const char *url); +typedef void (*DisplayUrlCb)(LinphoneCore *lc, const char *message, const char *url) ; /** Callback prototype */ typedef void (*LinphoneCoreCbFunc)(LinphoneCore *lc,void * user_data); @@ -1827,6 +2017,12 @@ typedef enum _LinphoneConfiguringState { LinphoneConfiguringSkipped } LinphoneConfiguringState; +/** + * Converts a _LinphoneConfiguringState enum to a string. + * @ingroup misc +**/ +LINPHONE_PUBLIC const char *linphone_configuring_state_to_string(LinphoneConfiguringState cs); + /** * Callback prototype for configuring status changes notification * @param lc the LinphoneCore @@ -1881,15 +2077,15 @@ typedef struct _LinphoneCoreVTable{ LinphoneCoreNotifyReceivedCb notify_received; /**< Notifies a an event notification, see linphone_core_subscribe() */ LinphoneCorePublishStateChangedCb publish_state_changed;/**Notifies publish state change (only from #LinphoneEvent api)*/ LinphoneCoreConfiguringStatusCb configuring_status; /** Notifies configuring status changes */ - DisplayStatusCb display_status; /**< @deprecated Callback that notifies various events with human readable text.*/ - DisplayMessageCb display_message;/**< @deprecated Callback to display a message to the user */ - DisplayMessageCb display_warning;/**< @deprecated Callback to display a warning to the user */ - DisplayUrlCb display_url; /**< @deprecated */ - ShowInterfaceCb show; /**< @deprecated Notifies the application that it should show up*/ - LinphoneCoreTextMessageReceivedCb text_received; /**< @deprecated, use #message_received instead
A text message has been received */ - LinphoneCoreFileTransferRecvCb file_transfer_recv; /**< @deprecated Callback to store file received attached to a #LinphoneChatMessage */ - LinphoneCoreFileTransferSendCb file_transfer_send; /**< @deprecated Callback to collect file chunk to be sent for a #LinphoneChatMessage */ - LinphoneCoreFileTransferProgressIndicationCb file_transfer_progress_indication; /**< @deprecated Callback to indicate file transfer progress */ + LINPHONE_DEPRECATED DisplayStatusCb display_status; /**< @deprecated Callback that notifies various events with human readable text.*/ + LINPHONE_DEPRECATED DisplayMessageCb display_message;/**< @deprecated Callback to display a message to the user */ + LINPHONE_DEPRECATED DisplayMessageCb display_warning;/**< @deprecated Callback to display a warning to the user */ + LINPHONE_DEPRECATED DisplayUrlCb display_url; /**< @deprecated */ + LINPHONE_DEPRECATED ShowInterfaceCb show; /**< @deprecated Notifies the application that it should show up*/ + LINPHONE_DEPRECATED LinphoneCoreTextMessageReceivedCb text_received; /**< @deprecated, use #message_received instead
A text message has been received */ + LINPHONE_DEPRECATED LinphoneCoreFileTransferRecvCb file_transfer_recv; /**< @deprecated Callback to store file received attached to a #LinphoneChatMessage */ + LINPHONE_DEPRECATED LinphoneCoreFileTransferSendCb file_transfer_send; /**< @deprecated Callback to collect file chunk to be sent for a #LinphoneChatMessage */ + LINPHONE_DEPRECATED LinphoneCoreFileTransferProgressIndicationCb file_transfer_progress_indication; /**< @deprecated Callback to indicate file transfer progress */ 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 */ @@ -1900,7 +2096,7 @@ typedef struct _LinphoneCoreVTable{ * Instantiate a vtable with all arguments set to NULL * @return newly allocated vtable */ -LINPHONE_PUBLIC LinphoneCoreVTable *linphone_core_v_table_new(); +LINPHONE_PUBLIC LinphoneCoreVTable *linphone_core_v_table_new(void); /** * Sets a user data pointer in the vtable. @@ -2049,13 +2245,13 @@ LINPHONE_PUBLIC void linphone_core_upload_log_collection(LinphoneCore *core); * @ingroup misc * @return The path of the compressed log collection file (to be freed calling ms_free()). */ -LINPHONE_PUBLIC char * linphone_core_compress_log_collection(); +LINPHONE_PUBLIC char * linphone_core_compress_log_collection(void); /** * Reset the log collection by removing the log files. * @ingroup misc */ -LINPHONE_PUBLIC void linphone_core_reset_log_collection(); +LINPHONE_PUBLIC void linphone_core_reset_log_collection(void); /** * Define a log handler. @@ -2077,12 +2273,13 @@ LINPHONE_PUBLIC void linphone_core_set_log_handler(OrtpLogFunc logfunc); LINPHONE_PUBLIC void linphone_core_set_log_file(FILE *file); /** - * @deprecated Use #linphone_core_set_log_level_mask instead, which is exactly the - * same function.. + * Define the minimum level for logging. + * + * @param loglevel Minimum level for logging messages. **/ LINPHONE_PUBLIC void linphone_core_set_log_level(OrtpLogLevel loglevel); /** - * Define the log level. + * Define the log level using mask. * * @ingroup misc * @@ -2103,17 +2300,42 @@ LINPHONE_PUBLIC void linphone_core_disable_logs(void); */ LINPHONE_PUBLIC void linphone_core_serialize_logs(void); +/** + * Returns liblinphone's version as a string. + * + * @ingroup misc + * +**/ LINPHONE_PUBLIC const char *linphone_core_get_version(void); LINPHONE_PUBLIC const char *linphone_core_get_user_agent(LinphoneCore *lc); /** * @deprecated Use #linphone_core_get_user_agent instead. **/ -LINPHONE_PUBLIC const char *linphone_core_get_user_agent_name(void); +LINPHONE_PUBLIC LINPHONE_DEPRECATED const char *linphone_core_get_user_agent_name(void); /** * @deprecated Use #linphone_core_get_user_agent instead. **/ -LINPHONE_PUBLIC const char *linphone_core_get_user_agent_version(void); +LINPHONE_PUBLIC LINPHONE_DEPRECATED const char *linphone_core_get_user_agent_version(void); +/** + * Instanciates a LinphoneCore object. + * @ingroup initializing + * + * The LinphoneCore object is the primary handle for doing all phone actions. + * It should be unique within your application. + * @param vtable a LinphoneCoreVTable structure holding your application callbacks + * @param config_path a path to a config file. If it does not exists it will be created. + * The config file is used to store all settings, call logs, friends, proxies... so that all these settings + * become persistent over the life of the LinphoneCore object. + * It is allowed to set a NULL config file. In that case LinphoneCore will not store any settings. + * @param factory_config_path a path to a read-only config file that can be used to + * to store hard-coded preference such as proxy settings or internal preferences. + * The settings in this factory file always override the one in the normal config file. + * It is OPTIONAL, use NULL if unneeded. + * @param userdata an opaque user pointer that can be retrieved at any time (for example in + * callbacks) using linphone_core_get_user_data(). + * @see linphone_core_new_with_config +**/ LINPHONE_PUBLIC LinphoneCore *linphone_core_new(const LinphoneCoreVTable *vtable, const char *config_path, const char *factory_config, void* userdata); @@ -2158,6 +2380,8 @@ LINPHONE_PUBLIC void linphone_core_remove_listener(LinphoneCore *lc, const Linph /*sets the user-agent string in sip messages, ideally called just after linphone_core_new() or linphone_core_init() */ LINPHONE_PUBLIC void linphone_core_set_user_agent(LinphoneCore *lc, const char *ua_name, const char *version); +/** See linphone_proxy_config_normalize_sip_uri for documentation. Default proxy config is used to parse +the address. */ LINPHONE_PUBLIC LinphoneAddress * linphone_core_interpret_url(LinphoneCore *lc, const char *url); LINPHONE_PUBLIC LinphoneCall * linphone_core_invite(LinphoneCore *lc, const char *url); @@ -2166,6 +2390,21 @@ LINPHONE_PUBLIC LinphoneCall * linphone_core_invite_address(LinphoneCore *lc, co LINPHONE_PUBLIC LinphoneCall * linphone_core_invite_with_params(LinphoneCore *lc, const char *url, const LinphoneCallParams *params); +/** + * Initiates an outgoing call given a destination LinphoneAddress + * + * @ingroup call_control + * @param lc the LinphoneCore object + * @param addr the destination of the call (sip address). + @param params call parameters + * + * The LinphoneAddress can be constructed directly using linphone_address_new(), or + * created by linphone_core_interpret_url(). + * The application doesn't own a reference to the returned LinphoneCall object. + * Use linphone_call_ref() to safely keep the LinphoneCall pointer valid within your application. + * + * @return a LinphoneCall object or NULL in case of failure +**/ LINPHONE_PUBLIC LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const LinphoneAddress *addr, const LinphoneCallParams *params); LINPHONE_PUBLIC int linphone_core_transfer_call(LinphoneCore *lc, LinphoneCall *call, const char *refer_to); @@ -2224,14 +2463,6 @@ LINPHONE_PUBLIC int linphone_core_update_call(LinphoneCore *lc, LinphoneCall *ca LINPHONE_PUBLIC int linphone_core_defer_call_update(LinphoneCore *lc, LinphoneCall *call); LINPHONE_PUBLIC int linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params); -/** - * @ingroup media_parameters - * Get default call parameters reflecting current linphone core configuration - * @param lc LinphoneCore object - * @return LinphoneCallParams - * @deprecated use linphone_core_create_call_params() - */ -LINPHONE_PUBLIC LinphoneCallParams *linphone_core_create_default_call_parameters(LinphoneCore *lc); LINPHONE_PUBLIC LinphoneCallParams *linphone_core_create_call_params(LinphoneCore *lc, LinphoneCall *call); @@ -2245,7 +2476,7 @@ LINPHONE_PUBLIC LinphoneCall *linphone_core_get_call_by_remote_address(LinphoneC * * @ingroup call_control */ -LINPHONE_PUBLIC LinphoneCall *linphone_core_get_call_by_remote_address2(LinphoneCore *lc, LinphoneAddress *remote_address); +LINPHONE_PUBLIC LinphoneCall *linphone_core_get_call_by_remote_address2(LinphoneCore *lc, const LinphoneAddress *remote_address); /** @@ -2258,43 +2489,163 @@ LINPHONE_PUBLIC LinphoneCall *linphone_core_get_call_by_remote_address2(Linphone * @param dtmf The dtmf name specified as a char, such as '0', '#' etc... * **/ -LINPHONE_PUBLIC void linphone_core_send_dtmf(LinphoneCore *lc,char dtmf); +LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_core_send_dtmf(LinphoneCore *lc,char dtmf); +/** + * Sets the local "from" identity. + * + * @ingroup proxies + * This data is used in absence of any proxy configuration or when no + * default proxy configuration is set. See LinphoneProxyConfig +**/ LINPHONE_PUBLIC int linphone_core_set_primary_contact(LinphoneCore *lc, const char *contact); +/** + * Returns the default identity when no proxy configuration is used. + * + * @ingroup proxies +**/ LINPHONE_PUBLIC const char *linphone_core_get_primary_contact(LinphoneCore *lc); LINPHONE_PUBLIC const char * linphone_core_get_identity(LinphoneCore *lc); +/** + * Tells LinphoneCore to guess local hostname automatically in primary contact. + * + * @ingroup proxies +**/ LINPHONE_PUBLIC void linphone_core_set_guess_hostname(LinphoneCore *lc, bool_t val); +/** + * Returns TRUE if hostname part of primary contact is guessed automatically. + * + * @ingroup proxies +**/ LINPHONE_PUBLIC bool_t linphone_core_get_guess_hostname(LinphoneCore *lc); +/** + * Tells to LinphoneCore to use Linphone Instant Messaging encryption + * + */ LINPHONE_PUBLIC void linphone_core_enable_lime(LinphoneCore *lc, bool_t val); LINPHONE_PUBLIC bool_t linphone_core_lime_enabled(const LinphoneCore *lc); LINPHONE_PUBLIC bool_t linphone_core_ipv6_enabled(LinphoneCore *lc); LINPHONE_PUBLIC void linphone_core_enable_ipv6(LinphoneCore *lc, bool_t val); +/** + * Same as linphone_core_get_primary_contact() but the result is a LinphoneAddress object + * instead of const char* + * + * @ingroup proxies +**/ LINPHONE_PUBLIC LinphoneAddress *linphone_core_get_primary_contact_parsed(LinphoneCore *lc); LINPHONE_PUBLIC const char * linphone_core_get_identity(LinphoneCore *lc); -/*0= no bandwidth limit*/ +/** + * Sets maximum available download bandwidth + * This is IP bandwidth, in kbit/s. + * This information is used signaled to other parties during + * calls (within SDP messages) so that the remote end can have + * sufficient knowledge to properly configure its audio & video + * codec output bitrate to not overflow available bandwidth. + * + * @ingroup media_parameters + * + * @param lc the LinphoneCore object + * @param bw the bandwidth in kbits/s, 0 for infinite + */ LINPHONE_PUBLIC void linphone_core_set_download_bandwidth(LinphoneCore *lc, int bw); +/** + * Sets maximum available upload bandwidth + * This is IP bandwidth, in kbit/s. + * This information is used by liblinphone together with remote + * side available bandwidth signaled in SDP messages to properly + * configure audio & video codec's output bitrate. + * + * @param lc the LinphoneCore object + * @param bw the bandwidth in kbits/s, 0 for infinite + * @ingroup media_parameters + */ LINPHONE_PUBLIC void linphone_core_set_upload_bandwidth(LinphoneCore *lc, int bw); +/** + * Retrieve the maximum available download bandwidth. + * This value was set by linphone_core_set_download_bandwidth(). + * @ingroup media_parameters +**/ LINPHONE_PUBLIC int linphone_core_get_download_bandwidth(const LinphoneCore *lc); +/** + * Retrieve the maximum available upload bandwidth. + * This value was set by linphone_core_set_upload_bandwidth(). + * @ingroup media_parameters +**/ LINPHONE_PUBLIC int linphone_core_get_upload_bandwidth(const LinphoneCore *lc); +/** + * Enable adaptive rate control. + * + * @ingroup media_parameters + * + * Adaptive rate control consists in using RTCP feedback provided information to dynamically + * control the output bitrate of the audio and video encoders, so that we can adapt to the network conditions and + * available bandwidth. Control of the audio encoder is done in case of audio-only call, and control of the video encoder is done for audio & video calls. + * Adaptive rate control feature is enabled by default. +**/ LINPHONE_PUBLIC void linphone_core_enable_adaptive_rate_control(LinphoneCore *lc, bool_t enabled); + +/** + * Returns whether adaptive rate control is enabled. + * + * @ingroup media_parameters + * + * See linphone_core_enable_adaptive_rate_control(). +**/ LINPHONE_PUBLIC bool_t linphone_core_adaptive_rate_control_enabled(const LinphoneCore *lc); +/** + * Sets adaptive rate algorithm. It will be used for each new calls starting from + * now. Calls already started will not be updated. + * + * @ingroup media_parameters + * +**/ LINPHONE_PUBLIC void linphone_core_set_adaptive_rate_algorithm(LinphoneCore *lc, const char *algorithm); +/** + * Returns which adaptive rate algorithm is currently configured for future calls. + * + * @ingroup media_parameters + * + * See linphone_core_set_adaptive_rate_algorithm(). +**/ LINPHONE_PUBLIC const char* linphone_core_get_adaptive_rate_algorithm(const LinphoneCore *lc); +/** + * Set audio packetization time linphone expects to receive from peer. + * A value of zero means that ptime is not specified. + * @ingroup media_parameters + */ LINPHONE_PUBLIC void linphone_core_set_download_ptime(LinphoneCore *lc, int ptime); +/** + * Get audio packetization time linphone expects to receive from peer. + * A value of zero means that ptime is not specified. + * @ingroup media_parameters + */ LINPHONE_PUBLIC int linphone_core_get_download_ptime(LinphoneCore *lc); +/** + * Set audio packetization time linphone will send (in absence of requirement from peer) + * A value of 0 stands for the current codec default packetization time. + * + * @ingroup media_parameters +**/ LINPHONE_PUBLIC void linphone_core_set_upload_ptime(LinphoneCore *lc, int ptime); +/** + * Set audio packetization time linphone will send (in absence of requirement from peer) + * A value of 0 stands for the current codec default packetization time. + * + * + * @ingroup media_parameters +**/ LINPHONE_PUBLIC int linphone_core_get_upload_ptime(LinphoneCore *lc); /** @@ -2303,7 +2654,7 @@ LINPHONE_PUBLIC int linphone_core_get_upload_ptime(LinphoneCore *lc); * @param[in] timeout_ms The SIP transport timeout in milliseconds. * @ingroup media_parameters */ -void linphone_core_set_sip_transport_timeout(LinphoneCore *lc, int timeout_ms); +LINPHONE_PUBLIC void linphone_core_set_sip_transport_timeout(LinphoneCore *lc, int timeout_ms); /** * Get the SIP transport timeout. @@ -2329,15 +2680,52 @@ LINPHONE_PUBLIC void linphone_core_enable_dns_srv(LinphoneCore *lc, bool_t enabl */ LINPHONE_PUBLIC bool_t linphone_core_dns_srv_enabled(const LinphoneCore *lc); -/* returns a MSList of PayloadType */ +/** + * Returns the list of available audio codecs. + * @param[in] lc The LinphoneCore object + * @return \mslist{PayloadType} + * + * This list is unmodifiable. The ->data field of the MSList points a PayloadType + * structure holding the codec information. + * It is possible to make copy of the list with ms_list_copy() in order to modify it + * (such as the order of codecs). + * @ingroup media_parameters +**/ LINPHONE_PUBLIC const MSList *linphone_core_get_audio_codecs(const LinphoneCore *lc); LINPHONE_PUBLIC int linphone_core_set_audio_codecs(LinphoneCore *lc, MSList *codecs); -/* returns a MSList of PayloadType */ + +/** + * Returns the list of available video codecs. + * @param[in] lc The LinphoneCore object + * @return \mslist{PayloadType} + * + * This list is unmodifiable. The ->data field of the MSList points a PayloadType + * structure holding the codec information. + * It is possible to make copy of the list with ms_list_copy() in order to modify it + * (such as the order of codecs). + * @ingroup media_parameters +**/ LINPHONE_PUBLIC const MSList *linphone_core_get_video_codecs(const LinphoneCore *lc); LINPHONE_PUBLIC int linphone_core_set_video_codecs(LinphoneCore *lc, MSList *codecs); +/** + * Returns the list of available text codecs. + * @param[in] lc The LinphoneCore object + * @return \mslist{PayloadType} + * + * This list is unmodifiable. The ->data field of the MSList points a PayloadType + * structure holding the codec information. + * It is possible to make copy of the list with ms_list_copy() in order to modify it + * (such as the order of codecs). + * @ingroup media_parameters +**/ +LINPHONE_PUBLIC const MSList *linphone_core_get_text_codecs(const LinphoneCore *lc); + + +LINPHONE_PUBLIC int linphone_core_set_text_codecs(LinphoneCore *lc, MSList *codecs); + LINPHONE_PUBLIC void linphone_core_enable_generic_confort_noise(LinphoneCore *lc, bool_t enabled); LINPHONE_PUBLIC bool_t linphone_core_generic_confort_noise_enabled(const LinphoneCore *lc); @@ -2423,37 +2811,81 @@ LINPHONE_PUBLIC int linphone_core_get_payload_type_number(LinphoneCore *lc, cons **/ LINPHONE_PUBLIC void linphone_core_set_payload_type_number(LinphoneCore *lc, PayloadType *pt, int number); -LINPHONE_PUBLIC const char *linphone_core_get_payload_type_description(LinphoneCore *lc, PayloadType *pt); +LINPHONE_PUBLIC const char *linphone_core_get_payload_type_description(LinphoneCore *lc, PayloadType *pt); -LINPHONE_PUBLIC bool_t linphone_core_check_payload_type_usability(LinphoneCore *lc, const PayloadType *pt); +LINPHONE_PUBLIC bool_t linphone_core_check_payload_type_usability(LinphoneCore *lc, const PayloadType *pt); + +/** + * @addtogroup proxies + * @{ + */ /** * Create a proxy config with default values from Linphone core. * @param[in] lc #LinphoneCore object * @return #LinphoneProxyConfig with default values set - * @ingroup proxy */ -LINPHONE_PUBLIC LinphoneProxyConfig * linphone_core_create_proxy_config(LinphoneCore *lc); +LINPHONE_PUBLIC LinphoneProxyConfig * linphone_core_create_proxy_config(LinphoneCore *lc); -LINPHONE_PUBLIC int linphone_core_add_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *config); +/** + * Add a proxy configuration. + * This will start registration on the proxy, if registration is enabled. +**/ +LINPHONE_PUBLIC int linphone_core_add_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *config); -LINPHONE_PUBLIC void linphone_core_clear_proxy_config(LinphoneCore *lc); +/** + * Erase all proxies from config. +**/ +LINPHONE_PUBLIC void linphone_core_clear_proxy_config(LinphoneCore *lc); -LINPHONE_PUBLIC void linphone_core_remove_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *config); +/** + * Removes a proxy configuration. + * + * LinphoneCore will then automatically unregister and place the proxy configuration + * on a deleted list. For that reason, a removed proxy does NOT need to be freed. +**/ +LINPHONE_PUBLIC void linphone_core_remove_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *config); -LINPHONE_PUBLIC const MSList *linphone_core_get_proxy_config_list(const LinphoneCore *lc); +/** + * Returns an unmodifiable list of entered proxy configurations. + * @param[in] lc The LinphoneCore object + * @return \mslist{LinphoneProxyConfig} +**/ +LINPHONE_PUBLIC const MSList *linphone_core_get_proxy_config_list(const LinphoneCore *lc); /** @deprecated Use linphone_core_set_default_proxy_config() instead. */ #define linphone_core_set_default_proxy(lc, config) linphone_core_set_default_proxy_config(lc, config) LINPHONE_PUBLIC void linphone_core_set_default_proxy_index(LinphoneCore *lc, int index); -LINPHONE_PUBLIC int linphone_core_get_default_proxy(LinphoneCore *lc, LinphoneProxyConfig **config); +/** + * @return the default proxy configuration, that is the one used to determine the current identity. + * @deprecated Use linphone_core_get_default_proxy_config() instead. +**/ +LINPHONE_PUBLIC LINPHONE_DEPRECATED int linphone_core_get_default_proxy(LinphoneCore *lc, LinphoneProxyConfig **config); +/** + * @return the default proxy configuration, that is the one used to determine the current identity. + * @param[in] lc LinphoneCore object + * @return The default proxy configuration. +**/ LINPHONE_PUBLIC LinphoneProxyConfig * linphone_core_get_default_proxy_config(LinphoneCore *lc); +/** + * Sets the default proxy. + * + * This default proxy must be part of the list of already entered LinphoneProxyConfig. + * Toggling it as default will make LinphoneCore use the identity associated with + * the proxy configuration in all incoming and outgoing calls. + * @param[in] lc LinphoneCore object + * @param[in] config The proxy configuration to use as the default one. +**/ LINPHONE_PUBLIC void linphone_core_set_default_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *config); +/** + * @} + */ + /** * Create an authentication information with default values from Linphone core. * @param[in] lc #LinphoneCore object @@ -2474,6 +2906,15 @@ LINPHONE_PUBLIC void linphone_core_remove_auth_info(LinphoneCore *lc, const Linp LINPHONE_PUBLIC const MSList *linphone_core_get_auth_info_list(const LinphoneCore *lc); +/** + * Find authentication info matching realm, username, domain criteria. + * First of all, (realm,username) pair are searched. If multiple results (which should not happen because realm are supposed to be unique), then domain is added to the search. + * @param lc the LinphoneCore + * @param realm the authentication 'realm' (optional) + * @param username the SIP username to be authenticated (mandatory) + * @param domain the SIP domain name (optional) + * @return a #LinphoneAuthInfo +**/ LINPHONE_PUBLIC const LinphoneAuthInfo *linphone_core_find_auth_info(LinphoneCore *lc, const char *realm, const char *username, const char *sip_domain); LINPHONE_PUBLIC void linphone_core_abort_authentication(LinphoneCore *lc, LinphoneAuthInfo *info); @@ -2498,7 +2939,14 @@ LINPHONE_PUBLIC bool_t linphone_core_audio_adaptive_jittcomp_enabled(LinphoneCor LINPHONE_PUBLIC int linphone_core_get_audio_jittcomp(LinphoneCore *lc); -LINPHONE_PUBLIC void linphone_core_set_audio_jittcomp(LinphoneCore *lc, int value); +/** + * Sets the nominal audio jitter buffer size in milliseconds. + * The value takes effect immediately for all running and pending calls, if any. + * A value of 0 disables the jitter buffer. + * + * @ingroup media_parameters +**/ +LINPHONE_PUBLIC void linphone_core_set_audio_jittcomp(LinphoneCore *lc, int milliseconds); /** * Enable or disable the video adaptive jitter compensation. @@ -2518,7 +2966,14 @@ LINPHONE_PUBLIC bool_t linphone_core_video_adaptive_jittcomp_enabled(LinphoneCor LINPHONE_PUBLIC int linphone_core_get_video_jittcomp(LinphoneCore *lc); -LINPHONE_PUBLIC void linphone_core_set_video_jittcomp(LinphoneCore *lc, int value); +/** + * Sets the nominal video jitter buffer size in milliseconds. + * The value takes effect immediately for all running and pending calls, if any. + * A value of 0 disables the jitter buffer. + * + * @ingroup media_parameters +**/ +LINPHONE_PUBLIC void linphone_core_set_video_jittcomp(LinphoneCore *lc, int milliseconds); LINPHONE_PUBLIC int linphone_core_get_audio_port(const LinphoneCore *lc); @@ -2528,6 +2983,10 @@ LINPHONE_PUBLIC int linphone_core_get_video_port(const LinphoneCore *lc); LINPHONE_PUBLIC void linphone_core_get_video_port_range(const LinphoneCore *lc, int *min_port, int *max_port); +LINPHONE_PUBLIC int linphone_core_get_text_port(const LinphoneCore *lc); + +LINPHONE_PUBLIC void linphone_core_get_text_port_range(const LinphoneCore *lc, int *min_port, int *max_port); + LINPHONE_PUBLIC int linphone_core_get_nortp_timeout(const LinphoneCore *lc); LINPHONE_PUBLIC void linphone_core_set_audio_port(LinphoneCore *lc, int port); @@ -2538,7 +2997,11 @@ LINPHONE_PUBLIC void linphone_core_set_video_port(LinphoneCore *lc, int port); LINPHONE_PUBLIC void linphone_core_set_video_port_range(LinphoneCore *lc, int min_port, int max_port); -LINPHONE_PUBLIC void linphone_core_set_nortp_timeout(LinphoneCore *lc, int port); +LINPHONE_PUBLIC void linphone_core_set_text_port(LinphoneCore *lc, int port); + +LINPHONE_PUBLIC void linphone_core_set_text_port_range(LinphoneCore *lc, int min_port, int max_port); + +LINPHONE_PUBLIC void linphone_core_set_nortp_timeout(LinphoneCore *lc, int seconds); LINPHONE_PUBLIC void linphone_core_set_use_info_for_dtmf(LinphoneCore *lc, bool_t use_info); @@ -2559,6 +3022,7 @@ LINPHONE_PUBLIC int linphone_core_get_sip_transports(LinphoneCore *lc, LCSipTran LINPHONE_PUBLIC void linphone_core_get_sip_transports_used(LinphoneCore *lc, LCSipTransports *tr); LINPHONE_PUBLIC bool_t linphone_core_sip_transport_supported(const LinphoneCore *lc, LinphoneTransportType tp); + /** * * Give access to the UDP sip socket. Can be useful to configure this socket as persistent I.E kCFStreamNetworkServiceType set to kCFStreamNetworkServiceTypeVoIP) @@ -2759,13 +3223,13 @@ bool_t linphone_core_agc_enabled(const LinphoneCore *lc); /** * @deprecated Use #linphone_core_enable_mic instead. **/ -LINPHONE_PUBLIC void linphone_core_mute_mic(LinphoneCore *lc, bool_t muted); +LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_core_mute_mic(LinphoneCore *lc, bool_t muted); /** * Get mic state. * @deprecated Use #linphone_core_mic_enabled instead **/ -LINPHONE_PUBLIC bool_t linphone_core_is_mic_muted(LinphoneCore *lc); +LINPHONE_PUBLIC LINPHONE_DEPRECATED bool_t linphone_core_is_mic_muted(LinphoneCore *lc); /** * Enable or disable the microphone. @@ -2805,6 +3269,29 @@ LINPHONE_PUBLIC void linphone_core_set_rtp_no_xmit_on_audio_mute(LinphoneCore *l **/ LINPHONE_PUBLIC const MSList * linphone_core_get_call_logs(LinphoneCore *lc); +/** + * Get the list of call logs (past calls) that matches the given #LinphoneAddress. + * At the contrary of linphone_core_get_call_logs, it is your responsability to unref the logs and free this list once you are done using it. + * @param[in] lc LinphoneCore object + * @return \mslist{LinphoneCallLog} +**/ +LINPHONE_PUBLIC MSList * linphone_core_get_call_history_for_address(LinphoneCore *lc, const LinphoneAddress *addr); + +/** + * Get the latest outgoing call log. + * @param[in] lc LinphoneCore object + * @return {LinphoneCallLog} +**/ +LINPHONE_PUBLIC LinphoneCallLog * linphone_core_get_last_outgoing_call_log(LinphoneCore *lc); + +/** + * Get the call log matching the call id, or NULL if can't be found. + * @param[in] lc LinphoneCore object + * @param[in] call_id Call id of the call log to find + * @return {LinphoneCallLog} +**/ +LINPHONE_PUBLIC LinphoneCallLog * linphone_core_find_call_log_from_call_id(LinphoneCore *lc, const char *call_id); + /** * Erase the call log. * @param[in] lc LinphoneCore object @@ -2833,6 +3320,22 @@ LINPHONE_PUBLIC void linphone_core_reset_missed_calls_count(LinphoneCore *lc); **/ LINPHONE_PUBLIC void linphone_core_remove_call_log(LinphoneCore *lc, LinphoneCallLog *call_log); +/** + * Sets the database filename where call logs will be stored. + * If the file does not exist, it will be created. + * @ingroup initializing + * @param lc the linphone core + * @param path filesystem path +**/ +LINPHONE_PUBLIC void linphone_core_set_call_logs_database_path(LinphoneCore *lc, const char *path); + +/** + * Migrates the call logs from the linphonerc to the database if not done yet + * @ingroup initializing + * @param lc the linphone core +**/ +LINPHONE_PUBLIC void linphone_core_migrate_logs_from_rc_to_db(LinphoneCore *lc); + /** * @} **/ @@ -2854,14 +3357,14 @@ LINPHONE_PUBLIC bool_t linphone_core_video_supported(LinphoneCore *lc); * @ingroup media_parameters * @deprecated Use #linphone_core_enable_video_capture and #linphone_core_enable_video_display instead. **/ -LINPHONE_PUBLIC void linphone_core_enable_video(LinphoneCore *lc, bool_t vcap_enabled, bool_t display_enabled); +LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_core_enable_video(LinphoneCore *lc, bool_t vcap_enabled, bool_t display_enabled); /** - * Returns TRUE if video is enabled, FALSE otherwise. + * Returns TRUE if either capture or display is enabled, FALSE otherwise. + * same as ( #linphone_core_video_capture_enabled | #linphone_core_video_display_enabled ) * @ingroup media_parameters - * @deprecated Use #linphone_core_video_capture_enabled and #linphone_core_video_display_enabled instead. **/ -LINPHONE_PUBLIC bool_t linphone_core_video_enabled(LinphoneCore *lc); +LINPHONE_PUBLIC bool_t linphone_core_video_enabled(LinphoneCore *lc); /** * Enable or disable video capture. @@ -2926,13 +3429,59 @@ typedef struct MSVideoSizeDef{ MSVideoSize vsize; const char *name; }MSVideoSizeDef; -/* returns a zero terminated table of MSVideoSizeDef*/ +/** + * Returns the zero terminated table of supported video resolutions. + * + * @ingroup media_parameters +**/ LINPHONE_PUBLIC const MSVideoSizeDef *linphone_core_get_supported_video_sizes(LinphoneCore *lc); -LINPHONE_PUBLIC void linphone_core_set_preferred_video_size(LinphoneCore *lc, MSVideoSize vsize); + +/** + * Sets the preferred video size. + * + * @ingroup media_parameters + * This applies only to the stream that is captured and sent to the remote party, + * since we accept all standard video size on the receive path. +**/LINPHONE_PUBLIC void linphone_core_set_preferred_video_size(LinphoneCore *lc, MSVideoSize vsize); +/** + * Sets the video size for the captured (preview) video. + * This method is for advanced usage where a video capture must be set independently of the size of the stream actually sent through the call. + * This allows for example to have the preview window with HD resolution even if due to bandwidth constraint the sent video size is small. + * Using this feature increases the CPU consumption, since a rescaling will be done internally. + * @ingroup media_parameters + * @param lc the linphone core + * @param vsize the video resolution choosed for capuring and previewing. It can be (0,0) to not request any specific preview size and let the core optimize the processing. +**/ LINPHONE_PUBLIC void linphone_core_set_preview_video_size(LinphoneCore *lc, MSVideoSize vsize); +/** + * Sets the preview video size by its name. See linphone_core_set_preview_video_size() for more information about this feature. + * + * @ingroup media_parameters + * Video resolution names are: qcif, svga, cif, vga, 4cif, svga ... +**/ LINPHONE_PUBLIC void linphone_core_set_preview_video_size_by_name(LinphoneCore *lc, const char *name); +/** + * Returns video size for the captured video if it was previously set by linphone_core_set_preview_video_size(), otherwise returns a 0,0 size. + * @see linphone_core_set_preview_video_size() + * @ingroup media_parameters + * @param lc the core + * @return a MSVideoSize +**/ LINPHONE_PUBLIC MSVideoSize linphone_core_get_preview_video_size(const LinphoneCore *lc); +/** + * Returns the effective video size for the captured video as provided by the camera. + * When preview is disabled or not yet started, this function returns a zeroed video size. + * @see linphone_core_set_preview_video_size() + * @ingroup media_parameters + * @param lc the core + * @return a MSVideoSize +**/ LINPHONE_PUBLIC MSVideoSize linphone_core_get_current_preview_video_size(const LinphoneCore *lc); +/** + * Returns the current preferred video size for sending. + * + * @ingroup media_parameters +**/ LINPHONE_PUBLIC MSVideoSize linphone_core_get_preferred_video_size(const LinphoneCore *lc); /** @@ -2941,8 +3490,31 @@ LINPHONE_PUBLIC MSVideoSize linphone_core_get_preferred_video_size(const Linphon * @return A string containing the name of the current preferred video size (to be freed with ms_free()). */ LINPHONE_PUBLIC char * linphone_core_get_preferred_video_size_name(const LinphoneCore *lc); +/** + * Sets the preferred video size by its name. + * + * @ingroup media_parameters + * This is identical to linphone_core_set_preferred_video_size() except + * that it takes the name of the video resolution as input. + * Video resolution names are: qcif, svga, cif, vga, 4cif, svga ... +**/ LINPHONE_PUBLIC void linphone_core_set_preferred_video_size_by_name(LinphoneCore *lc, const char *name); +/** + * Set the preferred frame rate for video. + * Based on the available bandwidth constraints and network conditions, the video encoder + * remains free to lower the framerate. There is no warranty that the preferred frame rate be the actual framerate. + * used during a call. Default value is 0, which means "use encoder's default fps value". + * @ingroup media_parameters + * @param lc the LinphoneCore + * @param fps the target frame rate in number of frames per seconds. +**/ LINPHONE_PUBLIC void linphone_core_set_preferred_framerate(LinphoneCore *lc, float fps); +/** + * Returns the preferred video framerate, previously set by linphone_core_set_preferred_framerate(). + * @ingroup media_parameters + * @param lc the linphone core + * @return frame rate in number of frames per seconds. +**/ LINPHONE_PUBLIC float linphone_core_get_preferred_framerate(LinphoneCore *lc); LINPHONE_PUBLIC void linphone_core_enable_video_preview(LinphoneCore *lc, bool_t val); LINPHONE_PUBLIC bool_t linphone_core_video_preview_enabled(const LinphoneCore *lc); @@ -3000,11 +3572,28 @@ LINPHONE_PUBLIC int linphone_core_set_static_picture_fps(LinphoneCore *lc, float LINPHONE_PUBLIC float linphone_core_get_static_picture_fps(LinphoneCore *lc); /*function to be used for eventually setting window decorations (icons, title...)*/ -LINPHONE_PUBLIC unsigned long linphone_core_get_native_video_window_id(const LinphoneCore *lc); -LINPHONE_PUBLIC void linphone_core_set_native_video_window_id(LinphoneCore *lc, unsigned long id); +LINPHONE_PUBLIC void * linphone_core_get_native_video_window_id(const LinphoneCore *lc); -LINPHONE_PUBLIC unsigned long linphone_core_get_native_preview_window_id(const LinphoneCore *lc); -LINPHONE_PUBLIC void linphone_core_set_native_preview_window_id(LinphoneCore *lc, unsigned long id); +/** + * @ingroup media_parameters + * For MacOS, Linux, Windows: core will create its own window + * */ +#define LINPHONE_VIDEO_DISPLAY_AUTO (void*)((unsigned long) 0) +/** + * @ingroup media_parameters + * For MacOS, Linux, Windows: do nothing + * */ + +#define LINPHONE_VIDEO_DISPLAY_NONE (void*)((unsigned long) -1) +/** + * @ingroup media_parameters + * Set the native video window id where the video is to be displayed. + * For MacOS, Linux, Windows: if not set or LINPHONE_VIDEO_DISPLAY_AUTO the core will create its own window, unless the special id LINPHONE_VIDEO_DISPLAY_NONE is given. +**/ +LINPHONE_PUBLIC void linphone_core_set_native_video_window_id(LinphoneCore *lc, void *id); + +LINPHONE_PUBLIC void * linphone_core_get_native_preview_window_id(const LinphoneCore *lc); +LINPHONE_PUBLIC void linphone_core_set_native_preview_window_id(LinphoneCore *lc, void *id); /** * Tells the core to use a separate window for local camera preview video, instead of @@ -3034,7 +3623,12 @@ void linphone_core_show_video(LinphoneCore *lc, bool_t show); /** @deprecated Use linphone_core_set_use_files() instead. */ #define linphone_core_use_files(lc, yesno) linphone_core_set_use_files(lc, yesno) -/*play/record support: use files instead of soundcard*/ +/** + * Ask the core to stream audio from and to files, instead of using the soundcard. + * @ingroup media_parameters + * @param[in] lc LinphoneCore object + * @param[in] yesno A boolean value asking to stream audio from and to files or not. +**/ LINPHONE_PUBLIC void linphone_core_set_use_files(LinphoneCore *lc, bool_t yesno); /** @@ -3048,6 +3642,15 @@ LINPHONE_PUBLIC void linphone_core_set_use_files(LinphoneCore *lc, bool_t yesno) */ LINPHONE_PUBLIC const char * linphone_core_get_play_file(const LinphoneCore *lc); +/** + * Sets a wav file to be played when putting somebody on hold, + * or when files are used instead of soundcards (see linphone_core_set_use_files()). + * + * The file must be a 16 bit linear wav file. + * @ingroup media_parameters + * @param[in] lc LinphoneCore object + * @param[in] file The path to the file to be played when putting somebody on hold. +**/ LINPHONE_PUBLIC void linphone_core_set_play_file(LinphoneCore *lc, const char *file); /** @@ -3062,6 +3665,16 @@ LINPHONE_PUBLIC void linphone_core_set_play_file(LinphoneCore *lc, const char *f **/ LINPHONE_PUBLIC const char * linphone_core_get_record_file(const LinphoneCore *lc); +/** + * Sets a wav file where incoming stream is to be recorded, + * when files are used instead of soundcards (see linphone_core_set_use_files()). + * + * This feature is different from call recording (linphone_call_params_set_record_file()) + * The file will be a 16 bit linear wav file. + * @ingroup media_parameters + * @param[in] lc LinphoneCore object + * @param[in] file The path to the file where incoming stream is to be recorded. +**/ LINPHONE_PUBLIC void linphone_core_set_record_file(LinphoneCore *lc, const char *file); LINPHONE_PUBLIC void linphone_core_play_dtmf(LinphoneCore *lc, char dtmf, int duration_ms); @@ -3192,7 +3805,27 @@ LINPHONE_PUBLIC LinphoneCall* linphone_core_find_call_from_uri(const LinphoneCor LINPHONE_PUBLIC int linphone_core_add_to_conference(LinphoneCore *lc, LinphoneCall *call); LINPHONE_PUBLIC int linphone_core_add_all_to_conference(LinphoneCore *lc); -LINPHONE_PUBLIC int linphone_core_remove_from_conference(LinphoneCore *lc, LinphoneCall *call); +/** + * Remove a call from the conference. + * @param lc the linphone core + * @param call a call that has been previously merged into the conference. + * + * After removing the remote participant belonging to the supplied call, the call becomes a normal call in paused state. + * If one single remote participant is left alone together with the local user in the conference after the removal, then the conference is + * automatically transformed into a simple call in StreamsRunning state. + * The conference's resources are then automatically destroyed. + * + * In other words, unless linphone_core_leave_conference() is explicitly called, the last remote participant of a conference is automatically + * put in a simple call in running state. + * + * @return 0 if successful, -1 otherwise. + **/ + LINPHONE_PUBLIC int linphone_core_remove_from_conference(LinphoneCore *lc, LinphoneCall *call); +/** + * Indicates whether the local participant is part of a conference. + * @param lc the linphone core + * @return TRUE if the local participant is in a conference, FALSE otherwise. +**/ LINPHONE_PUBLIC bool_t linphone_core_is_in_conference(const LinphoneCore *lc); LINPHONE_PUBLIC int linphone_core_enter_conference(LinphoneCore *lc); LINPHONE_PUBLIC int linphone_core_leave_conference(LinphoneCore *lc); @@ -3318,10 +3951,11 @@ typedef void (*ContactSearchCallback)( LinphoneContactSearch* id, MSList* friend * Calling this function does not load the configuration. It will write the value into configuration so that configuration * from remote URI will take place at next LinphoneCore start. * @param lc the linphone core - * @param uri the http or https uri to use in order to download the configuration. + * @param uri the http or https uri to use in order to download the configuration. Passing NULL will disable remote provisioning. + * @return -1 if uri could not be parsed, 0 otherwise. Note that this does not check validity of URI endpoint nor scheme and download may still fail. * @ingroup initializing **/ -LINPHONE_PUBLIC void linphone_core_set_provisioning_uri(LinphoneCore *lc, const char*uri); +LINPHONE_PUBLIC int linphone_core_set_provisioning_uri(LinphoneCore *lc, const char*uri); /** * Get provisioning URI. @@ -3536,6 +4170,79 @@ LINPHONE_PUBLIC int linphone_core_set_network_simulator_params(LinphoneCore *lc, **/ LINPHONE_PUBLIC const OrtpNetworkSimulatorParams *linphone_core_get_network_simulator_params(const LinphoneCore *lc); +/** + * Set the video preset to be used for video calls. + * @param[in] lc LinphoneCore object + * @param[in] preset The name of the video preset to be used (can be NULL to use the default video preset). + */ +LINPHONE_PUBLIC void linphone_core_set_video_preset(LinphoneCore *lc, const char *preset); + +/** + * Get the video preset used for video calls. + * @param[in] lc LinphoneCore object + * @return The name of the video preset used for video calls (can be NULL if the default video preset is used). + */ +LINPHONE_PUBLIC const char * linphone_core_get_video_preset(const LinphoneCore *lc); + +/** + * Gets if realtime text is enabled or not + * @param[in] lc LinphoneCore object + * @return true if realtime text is enabled, false otherwise + */ +LINPHONE_PUBLIC bool_t linphone_core_realtime_text_enabled(LinphoneCore *lc); + +/** + * Set http proxy address to be used for signaling during next channel connection. Use #linphone_core_set_network_reachable FASLE/TRUE to force channel restart. + * @param[in] lc LinphoneCore object + * @param[in] hostname of IP adress of the http proxy (can be NULL to disable). + */ +LINPHONE_PUBLIC void linphone_core_set_http_proxy_host(LinphoneCore *lc, const char *host) ; + +/** + * Set http proxy port to be used for signaling. + * @param[in] lc LinphoneCore object + * @param[in] port of the http proxy. + */ +LINPHONE_PUBLIC void linphone_core_set_http_proxy_port(LinphoneCore *lc, int port) ; + +/** + * Get http proxy address to be used for signaling. + * @param[in] lc LinphoneCore object + * @return hostname of IP adress of the http proxy (can be NULL to disable). + */ +LINPHONE_PUBLIC const char *linphone_core_get_http_proxy_host(const LinphoneCore *lc); + +/** + * Get http proxy port to be used for signaling. + * @param[in] lc LinphoneCore object + * @return port of the http proxy. + */ +LINPHONE_PUBLIC int linphone_core_get_http_proxy_port(const LinphoneCore *lc); + +/** + * Converts a LinphoneTransportType enum to a lowercase string. + * @ingroup misc +**/ +LINPHONE_PUBLIC const char* linphone_transport_to_string(LinphoneTransportType transport); + +/** + * Converts a lowercase string to a LinphoneTransportType enum. + * @ingroup misc + * @return Transport matching input, or LinphoneTransportUdp if nothing is found +**/ +LINPHONE_PUBLIC LinphoneTransportType linphone_transport_parse(const char* transport); + + +/** + * @ingroup media_parameters + * Get default call parameters reflecting current linphone core configuration + * @param lc LinphoneCore object + * @return LinphoneCallParams + * @deprecated use linphone_core_create_call_params() + */ +LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneCallParams *linphone_core_create_default_call_parameters(LinphoneCore *lc); + + #ifdef __cplusplus } #endif diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index b310ac543..92a648b60 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -29,6 +29,7 @@ extern "C" { #include "mediastreamer2/mscommon.h" #include "mediastreamer2/msmediaplayer.h" #include "mediastreamer2/msutils.h" +#include "devices.h" } #include "mediastreamer2/msjava.h" #include "private.h" @@ -57,6 +58,9 @@ extern "C" void libmsbcg729_init(); #ifdef HAVE_WEBRTC extern "C" void libmswebrtc_init(); #endif +#ifdef HAVE_CODEC2 +extern "C" void libmscodec2_init(); +#endif #include #endif /*ANDROID*/ @@ -86,6 +90,7 @@ static jobject handler_obj=NULL; static jobject create_java_linphone_content(JNIEnv *env, const LinphoneContent *content); static jobject create_java_linphone_buffer(JNIEnv *env, const LinphoneBuffer *buffer); static LinphoneBuffer* create_c_linphone_buffer_from_java_linphone_buffer(JNIEnv *env, jobject jbuffer); +static jobject getTunnelConfig(JNIEnv *env, LinphoneTunnelConfig *cfg); #ifdef ANDROID void linphone_android_log_handler(int prio, char *str) { @@ -136,12 +141,18 @@ static void linphone_android_ortp_log_handler(OrtpLogLevel lev, const char *fmt, int dumbMethodForAllowingUsageOfCpuFeaturesFromStaticLibMediastream() { return (android_getCpuFamily() == ANDROID_CPU_FAMILY_ARM && (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0); } + +int dumbMethodForAllowingUsageOfMsAudioDiffFromStaticLibMediastream() { + return ms_audio_diff(NULL, NULL, NULL, 0, NULL, NULL); +} #endif /*ANDROID*/ + JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *ajvm, void *reserved) { #ifdef ANDROID ms_set_jvm(ajvm); + #endif /*ANDROID*/ jvm=ajvm; return JNI_VERSION_1_2; @@ -161,6 +172,14 @@ extern "C" void Java_org_linphone_core_LinphoneCoreFactoryImpl_setDebugMode(JNIE } } +extern "C" jobject Java_org_linphone_core_LinphoneCoreFactoryImpl__1createTunnelConfig(JNIEnv* env, jobject thiz){ + jobject jobj; + LinphoneTunnelConfig *cfg = linphone_tunnel_config_new(); + jobj = getTunnelConfig(env, cfg); //this will take a ref. + linphone_tunnel_config_unref(cfg); + return jobj; +} + extern "C" void Java_org_linphone_core_LinphoneCoreFactoryImpl_enableLogCollection(JNIEnv* env ,jobject thiz ,jboolean enable) { @@ -177,177 +196,36 @@ extern "C" void Java_org_linphone_core_LinphoneCoreFactoryImpl_setLogCollectionP } // LinphoneCore -/* - * returns the java LinphoneProxyConfig associated with a C LinphoneProxyConfig. -**/ -jobject getProxy(JNIEnv *env, LinphoneProxyConfig *proxy, jobject core){ - jobject jobj=0; - - if (proxy!=NULL){ - jclass proxyClass = (jclass)env->FindClass("org/linphone/core/LinphoneProxyConfigImpl"); - jmethodID proxyCtrId = env->GetMethodID(proxyClass,"", "(Lorg/linphone/core/LinphoneCoreImpl;J)V"); - - void *up=linphone_proxy_config_get_user_data(proxy); - - if (up==NULL){ - jobj=env->NewObject(proxyClass,proxyCtrId,core,(jlong)proxy); - linphone_proxy_config_set_user_data(proxy,(void*)env->NewWeakGlobalRef(jobj)); - linphone_proxy_config_ref(proxy); - }else{ - //promote the weak ref to local ref - jobj=env->NewLocalRef((jobject)up); - if (jobj == NULL){ - //the weak ref was dead - jobj=env->NewObject(proxyClass,proxyCtrId,core,(jlong)proxy); - linphone_proxy_config_set_user_data(proxy,(void*)env->NewWeakGlobalRef(jobj)); - } - } - env->DeleteLocalRef(proxyClass); - } - return jobj; -} - -jobject getCall(JNIEnv *env, LinphoneCall *call){ - jobject jobj=0; - - if (call!=NULL){ - jclass callClass = (jclass)env->FindClass("org/linphone/core/LinphoneCallImpl"); - jmethodID callCtrId = env->GetMethodID(callClass,"", "(J)V"); - - void *up=linphone_call_get_user_pointer(call); - - if (up==NULL){ - jobj=env->NewObject(callClass,callCtrId,(jlong)call); - jobj=env->NewGlobalRef(jobj); - linphone_call_set_user_pointer(call,(void*)jobj); - linphone_call_ref(call); - }else{ - jobj=(jobject)up; - } - env->DeleteLocalRef(callClass); - } - return jobj; -} - -jobject getChatMessage(JNIEnv *env, LinphoneChatMessage *msg){ - jobject jobj = 0; - - if (msg != NULL){ - jclass chatMessageClass = (jclass)env->FindClass("org/linphone/core/LinphoneChatMessageImpl"); - jmethodID chatMessageCtrId = env->GetMethodID(chatMessageClass,"", "(J)V"); - - void *up = linphone_chat_message_get_user_data(msg); - - if (up == NULL) { - jobj = env->NewObject(chatMessageClass,chatMessageCtrId,(jlong)linphone_chat_message_ref(msg)); - jobj = env->NewGlobalRef(jobj); - linphone_chat_message_set_user_data(msg,(void*)jobj); - } else { - jobj = (jobject)up; - } - env->DeleteLocalRef(chatMessageClass); - } - return jobj; -} - -jobject getFriend(JNIEnv *env, LinphoneFriend *lfriend){ - jobject jobj=0; - - if (lfriend != NULL){ - jclass friendClass = (jclass)env->FindClass("org/linphone/core/LinphoneFriendImpl"); - jmethodID friendCtrId = env->GetMethodID(friendClass,"", "(J)V"); - - void *up=linphone_friend_get_user_data(lfriend); - - if (up == NULL){ - jobj=env->NewObject(friendClass,friendCtrId,(jlong)lfriend); - linphone_friend_set_user_data(lfriend,(void*)env->NewWeakGlobalRef(jobj)); - linphone_friend_ref(lfriend); - }else{ - - jobj=env->NewLocalRef((jobject)up); - if (jobj == NULL){ - jobj=env->NewObject(friendClass,friendCtrId,(jlong)lfriend); - linphone_friend_set_user_data(lfriend,(void*)env->NewWeakGlobalRef(jobj)); - } - } - env->DeleteLocalRef(friendClass); - } - return jobj; -} - -jobject getEvent(JNIEnv *env, LinphoneEvent *lev){ - if (lev==NULL) return NULL; - jobject jev=(jobject)linphone_event_get_user_data(lev); - if (jev==NULL){ - jclass linphoneEventClass = (jclass)env->FindClass("org/linphone/core/LinphoneEventImpl"); - jmethodID linphoneEventCtrId = env->GetMethodID(linphoneEventClass,"", "(J)V"); - - jev=env->NewObject(linphoneEventClass,linphoneEventCtrId,(jlong)linphone_event_ref(lev)); - jev=env->NewGlobalRef(jev); - linphone_event_set_user_data(lev,jev); - - env->DeleteLocalRef(linphoneEventClass); - } - return jev; -} - -class LinphoneCoreData { +class LinphoneJavaBindings { public: - LinphoneCoreData(JNIEnv *env, jobject lc, LinphoneCoreVTable *vTable, jobject alistener) { - core = env->NewGlobalRef(lc); - listener = env->NewGlobalRef(alistener); - - memset(vTable, 0, sizeof(LinphoneCoreVTable)); - - listenerClass = (jclass)env->NewGlobalRef(env->GetObjectClass(alistener)); - + LinphoneJavaBindings(JNIEnv *env) { + listenerClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCoreListener")); + /*displayStatus(LinphoneCore lc,String message);*/ displayStatusId = env->GetMethodID(listenerClass,"displayStatus","(Lorg/linphone/core/LinphoneCore;Ljava/lang/String;)V"); - if (displayStatusId) { - vTable->display_status = displayStatusCb; - } /*void generalState(LinphoneCore lc,int state); */ globalStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$GlobalState")); globalStateFromIntId = env->GetStaticMethodID(globalStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCore$GlobalState;"); globalStateId = env->GetMethodID(listenerClass,"globalState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCore$GlobalState;Ljava/lang/String;)V"); - if (globalStateId) { - vTable->global_state_changed = globalStateChange; - } /*registrationState(LinphoneCore lc, LinphoneProxyConfig cfg, LinphoneCore.RegistrationState cstate, String smessage);*/ registrationStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$RegistrationState")); registrationStateFromIntId = env->GetStaticMethodID(registrationStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCore$RegistrationState;"); registrationStateId = env->GetMethodID(listenerClass,"registrationState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneProxyConfig;Lorg/linphone/core/LinphoneCore$RegistrationState;Ljava/lang/String;)V"); - if (registrationStateId) { - vTable->registration_state_changed = registrationStateChange; - } /*callState(LinphoneCore lc, LinphoneCall call, LinphoneCall.State cstate,String message);*/ callStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCall$State")); callStateFromIntId = env->GetStaticMethodID(callStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCall$State;"); callStateId = env->GetMethodID(listenerClass,"callState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;Lorg/linphone/core/LinphoneCall$State;Ljava/lang/String;)V"); - if (callStateId) { - vTable->call_state_changed = callStateChange; - } transferStateId = env->GetMethodID(listenerClass,"transferState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;Lorg/linphone/core/LinphoneCall$State;)V"); - if (transferStateId) { - vTable->transfer_state_changed = transferStateChanged; - } /*callStatsUpdated(LinphoneCore lc, LinphoneCall call, LinphoneCallStats stats);*/ callStatsUpdatedId = env->GetMethodID(listenerClass, "callStatsUpdated", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;Lorg/linphone/core/LinphoneCallStats;)V"); - if (callStatsUpdatedId) { - vTable->call_stats_updated = callStatsUpdated; - } /*callEncryption(LinphoneCore lc, LinphoneCall call, boolean encrypted,String auth_token);*/ callEncryptionChangedId = env->GetMethodID(listenerClass,"callEncryptionChanged","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;ZLjava/lang/String;)V"); - if (callEncryptionChangedId) { - vTable->call_encryption_changed = callEncryptionChange; - } /*void ecCalibrationStatus(LinphoneCore.EcCalibratorStatus status, int delay_ms, Object data);*/ ecCalibratorStatusClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$EcCalibratorStatus")); @@ -356,98 +234,44 @@ public: /*void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf, String url)*/ newSubscriptionRequestId = env->GetMethodID(listenerClass,"newSubscriptionRequest","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneFriend;Ljava/lang/String;)V"); - if (newSubscriptionRequestId) { - vTable->new_subscription_requested = new_subscription_requested; - } authInfoRequestedId = env->GetMethodID(listenerClass,"authInfoRequested","(Lorg/linphone/core/LinphoneCore;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"); - if (authInfoRequestedId) { - vTable->auth_info_requested = authInfoRequested; - } /*void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf);*/ notifyPresenceReceivedId = env->GetMethodID(listenerClass,"notifyPresenceReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneFriend;)V"); - if (notifyPresenceReceivedId) { - vTable->notify_presence_received = notify_presence_received; - } - - /*void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from,String message);*/ - textReceivedId = env->GetMethodID(listenerClass,"textReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatRoom;Lorg/linphone/core/LinphoneAddress;Ljava/lang/String;)V"); - if (textReceivedId) { - vTable->text_received = text_received; - } messageReceivedId = env->GetMethodID(listenerClass,"messageReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatRoom;Lorg/linphone/core/LinphoneChatMessage;)V"); - if (messageReceivedId) { - vTable->message_received = message_received; - } isComposingReceivedId = env->GetMethodID(listenerClass,"isComposingReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatRoom;)V"); - if (isComposingReceivedId) { - vTable->is_composing_received = is_composing_received; - } dtmfReceivedId = env->GetMethodID(listenerClass,"dtmfReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;I)V"); - if (dtmfReceivedId) { - vTable->dtmf_received = dtmf_received; - } infoReceivedId = env->GetMethodID(listenerClass,"infoReceived", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;Lorg/linphone/core/LinphoneInfoMessage;)V"); - if (infoReceivedId) { - vTable->info_received = infoReceived; - } subscriptionStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/SubscriptionState")); subscriptionStateFromIntId = env->GetStaticMethodID(subscriptionStateClass,"fromInt","(I)Lorg/linphone/core/SubscriptionState;"); subscriptionStateId = env->GetMethodID(listenerClass,"subscriptionStateChanged", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneEvent;Lorg/linphone/core/SubscriptionState;)V"); - if (subscriptionStateId) { - vTable->subscription_state_changed = subscriptionStateChanged; - } publishStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/PublishState")); publishStateFromIntId = env->GetStaticMethodID(publishStateClass,"fromInt","(I)Lorg/linphone/core/PublishState;"); publishStateId = env->GetMethodID(listenerClass,"publishStateChanged", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneEvent;Lorg/linphone/core/PublishState;)V"); - if (publishStateId) { - vTable->publish_state_changed = publishStateChanged; - } notifyRecvId = env->GetMethodID(listenerClass,"notifyReceived", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneEvent;Ljava/lang/String;Lorg/linphone/core/LinphoneContent;)V"); - if (notifyRecvId) { - vTable->notify_received = notifyReceived; - } configuringStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$RemoteProvisioningState")); configuringStateFromIntId = env->GetStaticMethodID(configuringStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCore$RemoteProvisioningState;"); configuringStateId = env->GetMethodID(listenerClass,"configuringStatus","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCore$RemoteProvisioningState;Ljava/lang/String;)V"); - if (configuringStateId) { - vTable->configuring_status = configuringStatus; - } fileTransferProgressIndicationId = env->GetMethodID(listenerClass, "fileTransferProgressIndication", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneContent;I)V"); - if (fileTransferProgressIndicationId) { - vTable->file_transfer_progress_indication = fileTransferProgressIndication; - } fileTransferSendId = env->GetMethodID(listenerClass, "fileTransferSend", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneContent;Ljava/nio/ByteBuffer;I)I"); - if (fileTransferSendId) { - vTable->file_transfer_send = fileTransferSend; - } fileTransferRecvId = env->GetMethodID(listenerClass, "fileTransferRecv", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneContent;[BI)V"); - if (fileTransferRecvId) { - vTable->file_transfer_recv = fileTransferRecv; - } logCollectionUploadStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$LogCollectionUploadState")); logCollectionUploadStateFromIntId = env->GetStaticMethodID(logCollectionUploadStateClass, "fromInt", "(I)Lorg/linphone/core/LinphoneCore$LogCollectionUploadState;"); logCollectionUploadProgressId = env->GetMethodID(listenerClass, "uploadProgressIndication", "(Lorg/linphone/core/LinphoneCore;II)V"); - if (logCollectionUploadProgressId) { - vTable->log_collection_upload_progress_indication = logCollectionUploadProgressIndication; - } logCollectionUploadStateId = env->GetMethodID(listenerClass, "uploadStateChanged", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCore$LogCollectionUploadState;Ljava/lang/String;)V"); - if (logCollectionUploadStateId) { - vTable->log_collection_upload_state_changed = logCollectionUploadStateChange; - } chatMessageStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneChatMessage$State")); chatMessageStateFromIntId = env->GetStaticMethodID(chatMessageStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneChatMessage$State;"); @@ -486,12 +310,18 @@ public: subscriptionDirClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/SubscriptionDir")); subscriptionDirFromIntId = env->GetStaticMethodID(subscriptionDirClass,"fromInt","(I)Lorg/linphone/core/SubscriptionDir;"); } + + void setCore(jobject c) { + core = c; + } + + jobject getCore() { + return core; + } - ~LinphoneCoreData() { + ~LinphoneJavaBindings() { JNIEnv *env = 0; jvm->AttachCurrentThread(&env,NULL); - env->DeleteGlobalRef(core); - env->DeleteGlobalRef(listener); env->DeleteGlobalRef(listenerClass); env->DeleteGlobalRef(globalStateClass); env->DeleteGlobalRef(configuringStateClass); @@ -509,14 +339,13 @@ public: env->DeleteGlobalRef(subscriptionDirClass); env->DeleteGlobalRef(logCollectionUploadStateClass); } + jobject core; - jobject listener; jclass listenerClass; jmethodID displayStatusId; jmethodID newSubscriptionRequestId; jmethodID notifyPresenceReceivedId; - jmethodID textReceivedId; jmethodID messageReceivedId; jmethodID isComposingReceivedId; jmethodID dtmfReceivedId; @@ -599,6 +428,227 @@ public: jmethodID logCollectionUploadStateId; jmethodID logCollectionUploadStateFromIntId; jmethodID logCollectionUploadProgressId; +}; + +/* + * returns the java LinphoneProxyConfig associated with a C LinphoneProxyConfig. +**/ +jobject getProxy(JNIEnv *env, LinphoneProxyConfig *proxy, jobject core){ + jobject jobj=0; + + if (proxy!=NULL){ + LinphoneCore *lc = linphone_proxy_config_get_core(proxy); + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); + + void *up=linphone_proxy_config_get_user_data(proxy); + + if (up==NULL){ + jobj=env->NewObject(ljb->proxyClass, ljb->proxyCtrId, core, (jlong)proxy); + linphone_proxy_config_set_user_data(proxy,(void*)env->NewWeakGlobalRef(jobj)); + linphone_proxy_config_ref(proxy); + }else{ + //promote the weak ref to local ref + jobj=env->NewLocalRef((jobject)up); + if (jobj == NULL){ + //the weak ref was dead + jobj=env->NewObject(ljb->proxyClass, ljb->proxyCtrId, core, (jlong)proxy); + linphone_proxy_config_set_user_data(proxy,(void*)env->NewWeakGlobalRef(jobj)); + } + } + } + return jobj; +} + +jobject getCall(JNIEnv *env, LinphoneCall *call){ + jobject jobj=0; + + if (call!=NULL){ + LinphoneCore *lc = linphone_call_get_core(call); + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); + + void *up=linphone_call_get_user_pointer(call); + + if (up==NULL){ + jobj=env->NewObject(ljb->callClass, ljb->callCtrId, (jlong)call); + jobj=env->NewGlobalRef(jobj); + linphone_call_set_user_pointer(call,(void*)jobj); + linphone_call_ref(call); + }else{ + jobj=(jobject)up; + } + } + return jobj; +} + +jobject getChatMessage(JNIEnv *env, LinphoneChatMessage *msg){ + jobject jobj = 0; + + if (msg != NULL){ + LinphoneChatRoom *room = linphone_chat_message_get_chat_room(msg); + LinphoneCore *lc = linphone_chat_room_get_core(room); + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); + + void *up = linphone_chat_message_get_user_data(msg); + + if (up == NULL) { + jobj = env->NewObject(ljb->chatMessageClass, ljb->chatMessageCtrId, (jlong)linphone_chat_message_ref(msg)); + jobj = env->NewGlobalRef(jobj); + linphone_chat_message_set_user_data(msg,(void*)jobj); + } else { + jobj = (jobject)up; + } + } + return jobj; +} + +jobject getFriend(JNIEnv *env, LinphoneFriend *lfriend){ + jobject jobj=0; + + if (lfriend != NULL){ + LinphoneCore *lc = linphone_friend_get_core(lfriend); + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); + + void *up=linphone_friend_get_user_data(lfriend); + + if (up == NULL){ + jobj=env->NewObject(ljb->friendClass, ljb->friendCtrId, (jlong)lfriend); + linphone_friend_set_user_data(lfriend,(void*)env->NewWeakGlobalRef(jobj)); + linphone_friend_ref(lfriend); + }else{ + + jobj=env->NewLocalRef((jobject)up); + if (jobj == NULL){ + jobj=env->NewObject(ljb->friendClass, ljb->friendCtrId, (jlong)lfriend); + linphone_friend_set_user_data(lfriend,(void*)env->NewWeakGlobalRef(jobj)); + } + } + } + return jobj; +} + +jobject getEvent(JNIEnv *env, LinphoneEvent *lev){ + if (lev==NULL) return NULL; + jobject jev=(jobject)linphone_event_get_user_data(lev); + if (jev==NULL){ + LinphoneCore *lc = linphone_event_get_core(lev); + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); + + jev=env->NewObject(ljb->linphoneEventClass, ljb->linphoneEventCtrId, (jlong)linphone_event_ref(lev)); + jev=env->NewGlobalRef(jev); + linphone_event_set_user_data(lev,jev); + } + return jev; +} + +class LinphoneCoreData { +public: + LinphoneCoreData(JNIEnv *env, jobject lc, LinphoneCoreVTable *vTable, jobject alistener, LinphoneJavaBindings *ljb) { + core = env->NewGlobalRef(lc); + listener = env->NewGlobalRef(alistener); + + memset(vTable, 0, sizeof(LinphoneCoreVTable)); + + if (ljb->displayStatusId) { + vTable->display_status = displayStatusCb; + } + + if (ljb->globalStateId) { + vTable->global_state_changed = globalStateChange; + } + + if (ljb->registrationStateId) { + vTable->registration_state_changed = registrationStateChange; + } + + if (ljb->callStateId) { + vTable->call_state_changed = callStateChange; + } + + if (ljb->transferStateId) { + vTable->transfer_state_changed = transferStateChanged; + } + + if (ljb->callStatsUpdatedId) { + vTable->call_stats_updated = callStatsUpdated; + } + + if (ljb->callEncryptionChangedId) { + vTable->call_encryption_changed = callEncryptionChange; + } + + if (ljb->newSubscriptionRequestId) { + vTable->new_subscription_requested = new_subscription_requested; + } + + if (ljb->authInfoRequestedId) { + vTable->auth_info_requested = authInfoRequested; + } + + if (ljb->notifyPresenceReceivedId) { + vTable->notify_presence_received = notify_presence_received; + } + + if (ljb->messageReceivedId) { + vTable->message_received = message_received; + } + + if (ljb->isComposingReceivedId) { + vTable->is_composing_received = is_composing_received; + } + + if (ljb->dtmfReceivedId) { + vTable->dtmf_received = dtmf_received; + } + + if (ljb->infoReceivedId) { + vTable->info_received = infoReceived; + } + + if (ljb->subscriptionStateId) { + vTable->subscription_state_changed = subscriptionStateChanged; + } + + if (ljb->publishStateId) { + vTable->publish_state_changed = publishStateChanged; + } + + if (ljb->notifyRecvId) { + vTable->notify_received = notifyReceived; + } + + if (ljb->configuringStateId) { + vTable->configuring_status = configuringStatus; + } + + if (ljb->fileTransferProgressIndicationId) { + vTable->file_transfer_progress_indication = fileTransferProgressIndication; + } + + if (ljb->fileTransferSendId) { + vTable->file_transfer_send = fileTransferSend; + } + + if (ljb->fileTransferRecvId) { + vTable->file_transfer_recv = fileTransferRecv; + } + + if (ljb->logCollectionUploadProgressId) { + vTable->log_collection_upload_progress_indication = logCollectionUploadProgressIndication; + } + if (ljb->logCollectionUploadStateId) { + vTable->log_collection_upload_state_changed = logCollectionUploadStateChange; + } + } + + ~LinphoneCoreData() { + JNIEnv *env = 0; + jvm->AttachCurrentThread(&env,NULL); + env->DeleteGlobalRef(core); + env->DeleteGlobalRef(listener); + } + + jobject core; + jobject listener; LinphoneCoreVTable vTable; @@ -609,10 +659,13 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); jstring msg = message ? env->NewStringUTF(message) : NULL; - env->CallVoidMethod(lcData->listener,lcData->displayStatusId,lcData->core,msg); + env->CallVoidMethod(lcData->listener,ljb->displayStatusId,lcData->core,msg); + handle_possible_java_exception(env, lcData->listener); if (msg) { env->DeleteLocalRef(msg); } @@ -624,17 +677,20 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); jstring r = realm ? env->NewStringUTF(realm) : NULL; jstring u = username ? env->NewStringUTF(username) : NULL; jstring d = domain ? env->NewStringUTF(domain) : NULL; env->CallVoidMethod(lcData->listener, - lcData->authInfoRequestedId, + ljb->authInfoRequestedId, lcData->core, r, u, d); + handle_possible_java_exception(env, lcData->listener); if (r) { env->DeleteLocalRef(r); } @@ -645,6 +701,15 @@ public: env->DeleteLocalRef(d); } } + static void setCoreIfNotDone(JNIEnv *env, jobject jcore, LinphoneCore *lc){ + jclass objClass = env->GetObjectClass(jcore); + jfieldID myFieldID = env->GetFieldID(objClass, "nativePtr", "J"); + jlong fieldVal = env->GetLongField(jcore, myFieldID); + if (fieldVal == 0){ + env->SetLongField(jcore, myFieldID, (jlong)lc); + } + } + static void globalStateChange(LinphoneCore *lc, LinphoneGlobalState gstate,const char* message) { JNIEnv *env = 0; jint result = jvm->AttachCurrentThread(&env,NULL); @@ -652,18 +717,22 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); + + jobject jcore = lcData->core; + /*at this stage, the java object may not be aware of its C object, because linphone_core_new() hasn't returned yet.*/ + setCoreIfNotDone(env,jcore, lc); + jstring msg = message ? env->NewStringUTF(message) : NULL; env->CallVoidMethod(lcData->listener - ,lcData->globalStateId + ,ljb->globalStateId ,lcData->core - ,env->CallStaticObjectMethod(lcData->globalStateClass,lcData->globalStateFromIntId,(jint)gstate), + ,env->CallStaticObjectMethod(ljb->globalStateClass,ljb->globalStateFromIntId,(jint)gstate), msg); - if (env->ExceptionCheck()) { - ms_error("Listener %p raised an exception",lcData->listener); - env->ExceptionClear(); - } + handle_possible_java_exception(env, lcData->listener); if (msg) { env->DeleteLocalRef(msg); } @@ -676,19 +745,18 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); jstring msg = message ? env->NewStringUTF(message) : NULL; env->CallVoidMethod(lcData->listener - ,lcData->registrationStateId + ,ljb->registrationStateId ,lcData->core ,(jproxy=getProxy(env,proxy,lcData->core)) - ,env->CallStaticObjectMethod(lcData->registrationStateClass,lcData->registrationStateFromIntId,(jint)state), + ,env->CallStaticObjectMethod(ljb->registrationStateClass,ljb->registrationStateFromIntId,(jint)state), msg); - if (env->ExceptionCheck()) { - ms_error("Listener %p raised an exception",lcData->listener); - env->ExceptionClear(); - } + handle_possible_java_exception(env, lcData->listener); if (msg) { env->DeleteLocalRef(msg); } @@ -702,19 +770,18 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); jstring msg = message ? env->NewStringUTF(message) : NULL; env->CallVoidMethod(lcData->listener - ,lcData->callStateId + ,ljb->callStateId ,lcData->core ,(jcall=getCall(env,call)) - ,env->CallStaticObjectMethod(lcData->callStateClass,lcData->callStateFromIntId,(jint)state), + ,env->CallStaticObjectMethod(ljb->callStateClass,ljb->callStateFromIntId,(jint)state), msg); - if (env->ExceptionCheck()) { - ms_error("Listener %p raised an exception",lcData->listener); - env->ExceptionClear(); - } + handle_possible_java_exception(env, lcData->listener); if (state==LinphoneCallReleased) { linphone_call_set_user_pointer(call,NULL); env->DeleteGlobalRef(jcall); @@ -730,18 +797,17 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); env->CallVoidMethod(lcData->listener - ,lcData->callEncryptionChangedId + ,ljb->callEncryptionChangedId ,lcData->core ,getCall(env,call) ,encrypted ,authentication_token ? env->NewStringUTF(authentication_token) : NULL); - if (env->ExceptionCheck()) { - ms_error("Listener %p raised an exception",lcData->listener); - env->ExceptionClear(); - } + handle_possible_java_exception(env, lcData->listener); } static void notify_presence_received(LinphoneCore *lc, LinphoneFriend *my_friend) { JNIEnv *env = 0; @@ -750,16 +816,15 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); env->CallVoidMethod(lcData->listener - ,lcData->notifyPresenceReceivedId + ,ljb->notifyPresenceReceivedId ,lcData->core ,getFriend(env,my_friend)); - if (env->ExceptionCheck()) { - ms_error("Listener %p raised an exception",lcData->listener); - env->ExceptionClear(); - } + handle_possible_java_exception(env, lcData->listener); } static void new_subscription_requested(LinphoneCore *lc, LinphoneFriend *my_friend, const char* url) { JNIEnv *env = 0; @@ -768,17 +833,16 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); env->CallVoidMethod(lcData->listener - ,lcData->newSubscriptionRequestId + ,ljb->newSubscriptionRequestId ,lcData->core ,getFriend(env,my_friend) ,url ? env->NewStringUTF(url) : NULL); - if (env->ExceptionCheck()) { - ms_error("Listener %p raised an exception",lcData->listener); - env->ExceptionClear(); - } + handle_possible_java_exception(env, lcData->listener); } static void dtmf_received(LinphoneCore *lc, LinphoneCall *call, int dtmf) { JNIEnv *env = 0; @@ -787,37 +851,16 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); env->CallVoidMethod(lcData->listener - ,lcData->dtmfReceivedId + ,ljb->dtmfReceivedId ,lcData->core ,getCall(env,call) ,dtmf); - if (env->ExceptionCheck()) { - ms_error("Listener %p raised an exception",lcData->listener); - env->ExceptionClear(); - } - } - static void text_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from, const char *message) { - JNIEnv *env = 0; - jint result = jvm->AttachCurrentThread(&env,NULL); - if (result != 0) { - ms_error("cannot attach VM"); - return; - } - LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); - LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); - env->CallVoidMethod(lcData->listener - ,lcData->textReceivedId - ,lcData->core - ,env->NewObject(lcData->chatRoomClass,lcData->chatRoomCtrId,(jlong)room) - ,env->NewObject(lcData->addressClass,lcData->addressCtrId,(jlong)from) - ,message ? env->NewStringUTF(message) : NULL); - if (env->ExceptionCheck()) { - ms_error("Listener %p raised an exception",lcData->listener); - env->ExceptionClear(); - } + handle_possible_java_exception(env, lcData->listener); } static void message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *msg) { JNIEnv *env = 0; @@ -827,18 +870,17 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); /*note: we call linphone_chat_message_ref() because the application does not acquire the object when invoked from a callback*/ env->CallVoidMethod(lcData->listener - ,lcData->messageReceivedId + ,ljb->messageReceivedId ,lcData->core - ,env->NewObject(lcData->chatRoomClass,lcData->chatRoomCtrId,(jlong)room) + ,env->NewObject(ljb->chatRoomClass,ljb->chatRoomCtrId,(jlong)room) ,(jmsg = getChatMessage(env, msg))); - if (env->ExceptionCheck()) { - ms_error("Listener %p raised an exception",lcData->listener); - env->ExceptionClear(); - } + handle_possible_java_exception(env, lcData->listener); } static void is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room) { JNIEnv *env = 0; @@ -847,16 +889,15 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); env->CallVoidMethod(lcData->listener - ,lcData->isComposingReceivedId + ,ljb->isComposingReceivedId ,lcData->core - ,env->NewObject(lcData->chatRoomClass,lcData->chatRoomCtrId,(jlong)room)); - if (env->ExceptionCheck()) { - ms_error("Listener %p raised an exception",lcData->listener); - env->ExceptionClear(); - } + ,env->NewObject(ljb->chatRoomClass,ljb->chatRoomCtrId,(jlong)room)); + handle_possible_java_exception(env, lcData->listener); } static void ecCalibrationStatus(LinphoneCore *lc, LinphoneEcCalibratorStatus status, int delay_ms, void *data) { JNIEnv *env = 0; @@ -866,17 +907,19 @@ public: return; } + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = (LinphoneCoreVTable*) data; - if (table) { + if (table && ljb) { LinphoneCoreData* lcData = (LinphoneCoreData*) linphone_core_v_table_get_user_data(table); - if (lcData->ecCalibrationStatusId) { - jobject state = env->CallStaticObjectMethod(lcData->ecCalibratorStatusClass, lcData->ecCalibratorStatusFromIntId, (jint)status); + if (ljb->ecCalibrationStatusId) { + jobject state = env->CallStaticObjectMethod(ljb->ecCalibratorStatusClass, ljb->ecCalibratorStatusFromIntId, (jint)status); env->CallVoidMethod(lcData->listener - ,lcData->ecCalibrationStatusId + ,ljb->ecCalibrationStatusId ,lcData->core ,state ,delay_ms ,NULL); + handle_possible_java_exception(env, lcData->listener); } if (status != LinphoneEcCalibratorInProgress) { linphone_core_v_table_destroy(table); @@ -893,19 +936,19 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); - statsobj = env->NewObject(lcData->callStatsClass, lcData->callStatsId, (jlong)call, (jlong)stats); + statsobj = env->NewObject(ljb->callStatsClass, ljb->callStatsId, (jlong)call, (jlong)stats); callobj = getCall(env, call); if (stats->type == LINPHONE_CALL_STATS_AUDIO) - env->CallVoidMethod(callobj, lcData->callSetAudioStatsId, statsobj); + env->CallVoidMethod(callobj, ljb->callSetAudioStatsId, statsobj); else - env->CallVoidMethod(callobj, lcData->callSetVideoStatsId, statsobj); - env->CallVoidMethod(lcData->listener, lcData->callStatsUpdatedId, lcData->core, callobj, statsobj); - if (env->ExceptionCheck()) { - ms_error("Listener %p raised an exception",lcData->listener); - env->ExceptionClear(); - } + env->CallVoidMethod(callobj, ljb->callSetVideoStatsId, statsobj); + env->CallVoidMethod(lcData->listener, ljb->callStatsUpdatedId, lcData->core, callobj, statsobj); + handle_possible_java_exception(env, lcData->listener); + if (statsobj) env->DeleteLocalRef(statsobj); } static void transferStateChanged(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState remote_call_state){ JNIEnv *env = 0; @@ -915,18 +958,17 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); env->CallVoidMethod(lcData->listener - ,lcData->transferStateId + ,ljb->transferStateId ,lcData->core ,(jcall=getCall(env,call)) - ,env->CallStaticObjectMethod(lcData->callStateClass,lcData->callStateFromIntId,(jint)remote_call_state) + ,env->CallStaticObjectMethod(ljb->callStateClass,ljb->callStateFromIntId,(jint)remote_call_state) ); - if (env->ExceptionCheck()) { - ms_error("Listener %p raised an exception",lcData->listener); - env->ExceptionClear(); - } + handle_possible_java_exception(env, lcData->listener); } static void infoReceived(LinphoneCore *lc, LinphoneCall*call, const LinphoneInfoMessage *info){ JNIEnv *env = 0; @@ -935,19 +977,18 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneInfoMessage *copy_info=linphone_info_message_copy(info); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); env->CallVoidMethod(lcData->listener - ,lcData->infoReceivedId + ,ljb->infoReceivedId ,lcData->core ,getCall(env,call) - ,env->NewObject(lcData->infoMessageClass,lcData->infoMessageCtor,(jlong)copy_info) + ,env->NewObject(ljb->infoMessageClass,ljb->infoMessageCtor,(jlong)copy_info) ); - if (env->ExceptionCheck()) { - ms_error("Listener %p raised an exception",lcData->listener); - env->ExceptionClear(); - } + handle_possible_java_exception(env, lcData->listener); } static void subscriptionStateChanged(LinphoneCore *lc, LinphoneEvent *ev, LinphoneSubscriptionState state){ JNIEnv *env = 0; @@ -958,20 +999,19 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); jevent=getEvent(env,ev); - jstate=env->CallStaticObjectMethod(lcData->subscriptionStateClass,lcData->subscriptionStateFromIntId,(jint)state); + jstate=env->CallStaticObjectMethod(ljb->subscriptionStateClass,ljb->subscriptionStateFromIntId,(jint)state); env->CallVoidMethod(lcData->listener - ,lcData->subscriptionStateId + ,ljb->subscriptionStateId ,lcData->core ,jevent ,jstate ); - if (env->ExceptionCheck()) { - ms_error("Listener %p raised an exception",lcData->listener); - env->ExceptionClear(); - } + handle_possible_java_exception(env, lcData->listener); if (state==LinphoneSubscriptionTerminated){ /*loose the java reference */ linphone_event_set_user_data(ev,NULL); @@ -987,20 +1027,19 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); jevent=getEvent(env,ev); - jstate=env->CallStaticObjectMethod(lcData->publishStateClass,lcData->publishStateFromIntId,(jint)state); + jstate=env->CallStaticObjectMethod(ljb->publishStateClass,ljb->publishStateFromIntId,(jint)state); env->CallVoidMethod(lcData->listener - ,lcData->publishStateId + ,ljb->publishStateId ,lcData->core ,jevent ,jstate ); - if (env->ExceptionCheck()) { - ms_error("Listener %p raised an exception",lcData->listener); - env->ExceptionClear(); - } + handle_possible_java_exception(env, lcData->listener); } static void notifyReceived(LinphoneCore *lc, LinphoneEvent *ev, const char *evname, const LinphoneContent *content){ JNIEnv *env = 0; @@ -1010,20 +1049,19 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); jevent=getEvent(env,ev); env->CallVoidMethod(lcData->listener - ,lcData->notifyRecvId + ,ljb->notifyRecvId ,lcData->core ,jevent ,env->NewStringUTF(evname) ,content ? create_java_linphone_content(env,content) : NULL ); - if (env->ExceptionCheck()) { - ms_error("Listener %p raised an exception",lcData->listener); - env->ExceptionClear(); - } + handle_possible_java_exception(env, lcData->listener); } static void configuringStatus(LinphoneCore *lc, LinphoneConfiguringState status, const char *message) { @@ -1033,9 +1071,12 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); - env->CallVoidMethod(lcData->listener, lcData->configuringStateId, lcData->core, env->CallStaticObjectMethod(lcData->configuringStateClass,lcData->configuringStateFromIntId,(jint)status), message ? env->NewStringUTF(message) : NULL); + env->CallVoidMethod(lcData->listener, ljb->configuringStateId, lcData->core, env->CallStaticObjectMethod(ljb->configuringStateClass,ljb->configuringStateFromIntId,(jint)status), message ? env->NewStringUTF(message) : NULL); + handle_possible_java_exception(env, lcData->listener); } static void fileTransferProgressIndication(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t total) { @@ -1047,11 +1088,13 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); jobject jcontent = content ? create_java_linphone_content(env, content) : NULL; env->CallVoidMethod(lcData->listener, - lcData->fileTransferProgressIndicationId, + ljb->fileTransferProgressIndicationId, lcData->core, (jmsg = getChatMessage(env, message)), jcontent, @@ -1059,6 +1102,7 @@ public: if (jcontent) { env->DeleteLocalRef(jcontent); } + handle_possible_java_exception(env, lcData->listener); } static void fileTransferSend(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, char* buff, size_t* size) { @@ -1070,12 +1114,14 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); jobject jcontent = content ? create_java_linphone_content(env, content) : NULL; jobject jbuffer = buff ? env->NewDirectByteBuffer(buff, asking) : NULL; *size = env->CallIntMethod(lcData->listener, - lcData->fileTransferSendId, + ljb->fileTransferSendId, lcData->core, (jmsg = getChatMessage(env, message)), jcontent, @@ -1087,6 +1133,7 @@ public: if (jbuffer) { env->DeleteLocalRef(jbuffer); } + handle_possible_java_exception(env, lcData->listener); } static void fileTransferRecv(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, const char* buff, size_t size) { @@ -1097,6 +1144,8 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); @@ -1105,7 +1154,7 @@ public: jobject jcontent = content ? create_java_linphone_content(env, content) : NULL; env->CallVoidMethod(lcData->listener, - lcData->fileTransferRecvId, + ljb->fileTransferRecvId, lcData->core, (jmsg = getChatMessage(env, message)), jcontent, @@ -1114,6 +1163,7 @@ public: if (jcontent) { env->DeleteLocalRef(jcontent); } + handle_possible_java_exception(env, lcData->listener); } static void logCollectionUploadProgressIndication(LinphoneCore *lc, size_t offset, size_t total) { JNIEnv *env = 0; @@ -1122,17 +1172,16 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); env->CallVoidMethod(lcData->listener - ,lcData->logCollectionUploadProgressId + ,ljb->logCollectionUploadProgressId ,lcData->core ,(jlong)offset ,(jlong)total); - if (env->ExceptionCheck()) { - ms_error("Listener %p raised an exception",lcData->listener); - env->ExceptionClear(); - } + handle_possible_java_exception(env, lcData->listener); } static void logCollectionUploadStateChange(LinphoneCore *lc, LinphoneCoreLogCollectionUploadState state, const char *info) { JNIEnv *env = 0; @@ -1141,22 +1190,31 @@ public: ms_error("cannot attach VM"); return; } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); jstring msg = info ? env->NewStringUTF(info) : NULL; env->CallVoidMethod(lcData->listener - ,lcData->logCollectionUploadStateId + ,ljb->logCollectionUploadStateId ,lcData->core - ,env->CallStaticObjectMethod(lcData->logCollectionUploadStateClass,lcData->logCollectionUploadStateFromIntId,(jint)state), + ,env->CallStaticObjectMethod(ljb->logCollectionUploadStateClass,ljb->logCollectionUploadStateFromIntId,(jint)state), msg); - if (env->ExceptionCheck()) { - ms_error("Listener %p raised an exception",lcData->listener); - env->ExceptionClear(); - } + handle_possible_java_exception(env, lcData->listener); if (msg) { env->DeleteLocalRef(msg); } } + +private: + static inline void handle_possible_java_exception(JNIEnv *env, jobject listener) + { + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + env->ExceptionClear(); + ms_error("Listener %p raised an exception",listener); + } + } }; extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_newLinphoneCore(JNIEnv* env @@ -1169,8 +1227,10 @@ extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_newLinphoneCore(JNIEnv* const char* userConfig = juserConfig?env->GetStringUTFChars(juserConfig, NULL):NULL; const char* factoryConfig = jfactoryConfig?env->GetStringUTFChars(jfactoryConfig, NULL):NULL; + LinphoneJavaBindings *ljb = new LinphoneJavaBindings(env); + LinphoneCoreVTable *vTable = linphone_core_v_table_new(); - LinphoneCoreData* ldata = new LinphoneCoreData(env, thiz, vTable, jlistener); + LinphoneCoreData* ldata = new LinphoneCoreData(env, thiz, vTable, jlistener, ljb); linphone_core_v_table_set_user_data(vTable, ldata); ms_init(); // Initialize mediastreamer2 before loading the plugins @@ -1196,9 +1256,14 @@ extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_newLinphoneCore(JNIEnv* #ifdef HAVE_WEBRTC libmswebrtc_init(); #endif +#ifdef HAVE_CODEC2 + libmscodec2_init(); +#endif jobject core = env->NewGlobalRef(thiz); - jlong nativePtr = (jlong)linphone_core_new(vTable, userConfig, factoryConfig, core); + ljb->setCore(core); + LinphoneCore *lc = linphone_core_new(vTable, userConfig, factoryConfig, ljb); + jlong nativePtr = (jlong)lc; if (userConfig) env->ReleaseStringUTFChars(juserConfig, userConfig); if (factoryConfig) env->ReleaseStringUTFChars(jfactoryConfig, factoryConfig); @@ -1206,7 +1271,7 @@ extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_newLinphoneCore(JNIEnv* } extern "C" void Java_org_linphone_core_LinphoneCoreImpl_delete(JNIEnv* env, jobject thiz, jlong native_ptr) { LinphoneCore *lc=(LinphoneCore*)native_ptr; - jobject core = (jobject)linphone_core_get_user_data(lc); + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); jobject multicast_lock = lc->multicast_lock; jobject multicast_lock_class = lc->multicast_lock_class; @@ -1221,14 +1286,19 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_delete(JNIEnv* env, jobj if (multicast_lock) env->DeleteGlobalRef(multicast_lock); if (multicast_lock_class) env->DeleteGlobalRef(multicast_lock_class); - if (core) { - env->DeleteGlobalRef(core); + if (ljb) { + jobject core = ljb->getCore(); + if (core) { + env->DeleteGlobalRef(core); + } + delete ljb; } } extern "C" void Java_org_linphone_core_LinphoneCoreImpl_addListener(JNIEnv* env, jobject thiz, jlong lc, jobject jlistener) { + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *) linphone_core_get_user_data((LinphoneCore *)lc); LinphoneCoreVTable *vTable = linphone_core_v_table_new(); - LinphoneCoreData* ldata = new LinphoneCoreData(env, thiz, vTable, jlistener); + LinphoneCoreData* ldata = new LinphoneCoreData(env, thiz, vTable, jlistener, ljb); linphone_core_v_table_set_user_data(vTable, ldata); linphone_core_add_listener((LinphoneCore*)lc, vTable); } @@ -1291,6 +1361,12 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setChatDatabasePath(JNIE env->ReleaseStringUTFChars(jpath, path); } +extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setCallLogsDatabasePath( JNIEnv* env, jobject thiz, jlong lc, jstring jpath) { + const char* path = env->GetStringUTFChars(jpath, NULL); + linphone_core_set_call_logs_database_path((LinphoneCore*)lc, path); + env->ReleaseStringUTFChars(jpath, path); +} + extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setPrimaryContact2(JNIEnv* env, jobject thiz, jlong lc, jstring jcontact) { const char* contact = env->GetStringUTFChars(jcontact, NULL); linphone_core_set_primary_contact((LinphoneCore*)lc, contact); @@ -1358,8 +1434,8 @@ extern "C" jobject Java_org_linphone_core_LinphoneCoreImpl_getDefaultProxyConfig extern "C" jobjectArray Java_org_linphone_core_LinphoneCoreImpl_getProxyConfigList(JNIEnv* env, jobject thiz, jlong lc) { const MSList* proxies = linphone_core_get_proxy_config_list((LinphoneCore*)lc); int proxyCount = ms_list_size(proxies); - jclass cls = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneProxyConfigImpl")); - jobjectArray jProxies = env->NewObjectArray(proxyCount,cls,NULL); + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data((LinphoneCore *)lc); + jobjectArray jProxies = env->NewObjectArray(proxyCount,ljb->proxyClass,NULL); for (int i = 0; i < proxyCount; i++ ) { LinphoneProxyConfig* proxy = (LinphoneProxyConfig*)proxies->data; @@ -1369,7 +1445,7 @@ extern "C" jobjectArray Java_org_linphone_core_LinphoneCoreImpl_getProxyConfigLi } proxies = proxies->next; } - env->DeleteGlobalRef(cls); + return jProxies; } @@ -1544,6 +1620,17 @@ extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_getNumberOfCallLogs( JNI ,jlong lc) { return (jint)ms_list_size(linphone_core_get_call_logs((LinphoneCore*)lc)); } +extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_getLastOutgoingCallLog( JNIEnv* env + ,jobject thiz + ,jlong lc) { + return (jlong)linphone_core_get_last_outgoing_call_log((LinphoneCore*)lc); +} + +extern "C" void Java_org_linphone_core_LinphoneCoreImpl_migrateCallLogs(JNIEnv* env + ,jobject thiz + ,jlong lc) { + linphone_core_migrate_logs_from_rc_to_db((LinphoneCore *)lc); +} extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setMtu(JNIEnv* env ,jobject thiz @@ -1857,8 +1944,8 @@ extern "C" jobjectArray Java_org_linphone_core_LinphoneCoreImpl_getFriendList(JN ,jlong lc) { const MSList* friends = linphone_core_get_friend_list((LinphoneCore*)lc); int friendsSize = ms_list_size(friends); - jclass cls = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneFriendImpl")); - jobjectArray jFriends = env->NewObjectArray(friendsSize,cls,NULL); + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data((LinphoneCore *)lc); + jobjectArray jFriends = env->NewObjectArray(friendsSize,ljb->friendClass,NULL); for (int i = 0; i < friendsSize; i++) { LinphoneFriend* lfriend = (LinphoneFriend*)friends->data; @@ -1868,8 +1955,7 @@ extern "C" jobjectArray Java_org_linphone_core_LinphoneCoreImpl_getFriendList(JN } friends = friends->next; } - - env->DeleteGlobalRef(cls); + return jFriends; } extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setPresenceInfo(JNIEnv* env @@ -1915,11 +2001,19 @@ extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_getOrCreateChatRoom(JNI ,jstring jto) { const char* to = env->GetStringUTFChars(jto, NULL); - LinphoneChatRoom* lResult = linphone_core_get_or_create_chat_room((LinphoneCore*)lc,to); + LinphoneChatRoom* lResult = linphone_core_get_chat_room_from_uri((LinphoneCore*)lc,to); env->ReleaseStringUTFChars(jto, to); return (jlong)lResult; } +extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_getChatRoom(JNIEnv* env + ,jobject thiz + ,jlong lc + ,jlong to) { + LinphoneChatRoom* lResult = linphone_core_get_chat_room((LinphoneCore*)lc,(LinphoneAddress *)to); + return (jlong)lResult; +} + extern "C" void Java_org_linphone_core_LinphoneCoreImpl_enableVideo(JNIEnv* env ,jobject thiz ,jlong lc @@ -2005,6 +2099,22 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setRingback(JNIEnv* env } +extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setProvisioningUri(JNIEnv* env + ,jobject thiz + ,jlong lc + ,jstring jpath) { + const char* path = jpath?env->GetStringUTFChars(jpath, NULL):NULL; + linphone_core_set_provisioning_uri((LinphoneCore*)lc,path); + if (path) env->ReleaseStringUTFChars(jpath, path); +} + +extern "C" jstring Java_org_linphone_core_LinphoneCoreImpl_getProvisioningUri(JNIEnv* env + ,jobject thiz + ,jlong lc) { + const char* path = linphone_core_get_provisioning_uri((LinphoneCore*)lc); + return path ? env->NewStringUTF(path) : NULL; +} + extern "C" void Java_org_linphone_core_LinphoneCoreImpl_enableKeepAlive(JNIEnv* env ,jobject thiz ,jlong lc @@ -2022,8 +2132,9 @@ extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_startEchoCalibration(JNI ,jobject thiz ,jlong lc ,jobject data) { + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *) linphone_core_get_user_data((LinphoneCore *)lc); LinphoneCoreVTable *vTable = linphone_core_v_table_new(); - LinphoneCoreData* ldata = new LinphoneCoreData(env, thiz, vTable, data); + LinphoneCoreData* ldata = new LinphoneCoreData(env, thiz, vTable, data, ljb); linphone_core_v_table_set_user_data(vTable, ldata); return (jint)linphone_core_start_echo_calibration((LinphoneCore*)lc, ldata->ecCalibrationStatus, NULL, NULL, vTable); @@ -2039,24 +2150,29 @@ extern "C" jboolean Java_org_linphone_core_LinphoneCoreImpl_needsEchoCalibration ms_error("Could not get soundcard %s", card); return TRUE; } - + + SoundDeviceDescription *sound_description = sound_device_description_get(); + if(sound_description != NULL && sound_description == &genericSoundDeviceDescriptor){ + 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) { +extern "C" jboolean Java_org_linphone_core_LinphoneCoreImpl_hasBuiltInEchoCanceler(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; + return FALSE; } - - if (ms_snd_card_get_capabilities(sndcard) & MS_SND_CARD_CAP_BUILTIN_ECHO_CANCELLER) return FALSE; - return TRUE; + + if (ms_snd_card_get_capabilities(sndcard) & MS_SND_CARD_CAP_BUILTIN_ECHO_CANCELLER) return TRUE; + return FALSE; } extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_getMediaEncryption(JNIEnv* env @@ -2122,7 +2238,6 @@ extern "C" JNIEXPORT jboolean JNICALL Java_org_linphone_core_LinphoneCoreImpl_ch return (jboolean) linphone_core_chat_enabled((LinphoneCore*)ptr); } - //ProxyConfig extern "C" jlong Java_org_linphone_core_LinphoneProxyConfigImpl_createProxyConfig(JNIEnv* env, jobject thiz, jlong lc) { @@ -2152,6 +2267,12 @@ extern "C" jstring Java_org_linphone_core_LinphoneProxyConfigImpl_getIdentity(JN return NULL; } } +extern "C" jlong Java_org_linphone_core_LinphoneProxyConfigImpl_getAddress(JNIEnv* env, jobject thiz, jlong proxyCfg) { + return (jlong) linphone_proxy_config_get_identity_address((LinphoneProxyConfig*)proxyCfg); +} +extern "C" void Java_org_linphone_core_LinphoneProxyConfigImpl_setAddress(JNIEnv* env,jobject thiz,jlong proxyCfg,jlong jidentity) { + linphone_proxy_config_set_identity_address((LinphoneProxyConfig*)proxyCfg, (LinphoneAddress*) jidentity); +} extern "C" jint Java_org_linphone_core_LinphoneProxyConfigImpl_setProxy(JNIEnv* env,jobject thiz,jlong proxyCfg,jstring jproxy) { const char* proxy = env->GetStringUTFChars(jproxy, NULL); jint err=linphone_proxy_config_set_server_addr((LinphoneProxyConfig*)proxyCfg,proxy); @@ -2225,18 +2346,25 @@ extern "C" jstring Java_org_linphone_core_LinphoneProxyConfigImpl_normalizePhone if (jnumber == 0) { ms_error("cannot normalized null number"); } + char * normalized_phone; const char* number = env->GetStringUTFChars(jnumber, NULL); int len = env->GetStringLength(jnumber); if (len == 0) { ms_warning("cannot normalize empty number"); return jnumber; } - char targetBuff[2*len];// returned number can be greater than origin (specially in case of prefix insertion - linphone_proxy_config_normalize_number((LinphoneProxyConfig*)proxyCfg,number,targetBuff,sizeof(targetBuff)); - jstring normalizedNumber = env->NewStringUTF(targetBuff); + normalized_phone = linphone_proxy_config_normalize_phone_number((LinphoneProxyConfig*)proxyCfg,number); + jstring normalizedNumber = env->NewStringUTF(normalized_phone ? normalized_phone : number); env->ReleaseStringUTFChars(jnumber, number); + ms_free(normalized_phone); return normalizedNumber; } +extern "C" jlong Java_org_linphone_core_LinphoneProxyConfigImpl_normalizeSipUri(JNIEnv* env,jobject thiz,jlong proxyCfg,jstring jusername) { + const char* username = env->GetStringUTFChars(jusername, NULL); + LinphoneAddress *addr = linphone_proxy_config_normalize_sip_uri((LinphoneProxyConfig*)proxyCfg, username); + env->ReleaseStringUTFChars(jusername, username); + return (jlong) addr; +} extern "C" jint Java_org_linphone_core_LinphoneProxyConfigImpl_lookupCCCFromIso(JNIEnv* env, jobject thiz, jlong proxyCfg, jstring jiso) { const char* iso = env->GetStringUTFChars(jiso, NULL); int prefix = linphone_dial_plan_lookup_ccc_from_iso(iso); @@ -2748,6 +2876,24 @@ extern "C" jlong Java_org_linphone_core_LinphoneCallImpl_getCallLog( JNIEnv* en return (jlong)linphone_call_get_call_log((LinphoneCall*)ptr); } +extern "C" jlongArray Java_org_linphone_core_LinphoneCoreImpl_getCallLogs(JNIEnv* env + ,jobject thiz + ,jlong lc) { + const MSList *logs = linphone_core_get_call_logs((LinphoneCore *) lc); + int logsCount = ms_list_size(logs); + jlongArray jLogs = env->NewLongArray(logsCount); + jlong *jInternalArray = env->GetLongArrayElements(jLogs, NULL); + + for (int i = 0; i < logsCount; i++) { + jInternalArray[i] = (unsigned long) (logs->data); + logs = logs->next; + } + + env->ReleaseLongArrayElements(jLogs, jInternalArray, 0); + + return jLogs; +} + extern "C" void Java_org_linphone_core_LinphoneCallImpl_takeSnapshot( JNIEnv* env ,jobject thiz ,jlong ptr, jstring path) { @@ -2951,7 +3097,8 @@ extern "C" jobject Java_org_linphone_core_LinphoneFriendImpl_getCore(JNIEnv* en ,jlong ptr) { LinphoneCore *lc=linphone_friend_get_core((LinphoneFriend*)ptr); if (lc!=NULL){ - jobject core = (jobject)linphone_core_get_user_data(lc); + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); + jobject core = ljb->getCore(); return core; } return NULL; @@ -3128,18 +3275,6 @@ extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_markAsRead(JNIEnv* linphone_chat_room_mark_as_read((LinphoneChatRoom*)ptr); } -extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_updateUrl(JNIEnv* env - ,jobject thiz - ,jlong room - ,jlong msg) { - linphone_chat_room_update_url((LinphoneChatRoom*)room, (LinphoneChatMessage*)msg); -} - -extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_destroy(JNIEnv* env - ,jobject thiz - ,jlong ptr) { - linphone_chat_room_destroy((LinphoneChatRoom*)ptr); -} extern "C" jlong Java_org_linphone_core_LinphoneChatRoomImpl_createFileTransferMessage(JNIEnv* env, jobject thiz, jlong ptr, jstring jname, jstring jtype, jstring jsubtype, jint data_size) { LinphoneContentPrivate content = {0}; @@ -3314,10 +3449,10 @@ extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_setFileTransferFi env->ReleaseStringUTFChars(jpath, path); } -extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_downloadFile(JNIEnv* env +extern "C" jint Java_org_linphone_core_LinphoneChatMessageImpl_downloadFile(JNIEnv* env ,jobject thiz ,jlong ptr) { - linphone_chat_message_download_file((LinphoneChatMessage*)ptr); + return (jint) linphone_chat_message_download_file((LinphoneChatMessage*)ptr); } static void message_state_changed(LinphoneChatMessage* msg, LinphoneChatMessageState state) { @@ -3328,20 +3463,26 @@ static void message_state_changed(LinphoneChatMessage* msg, LinphoneChatMessageS return; } - jobject listener = (jobject) msg->cb_ud; + jobject listener = (jobject) msg->message_state_changed_user_data; + + if (listener == NULL) { + ms_error("message_state_changed() notification without listener"); + return ; + } 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); env->DeleteLocalRef(clazz); - - jclass chatMessageStateClass = (jclass)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)); + + LinphoneChatRoom *room = linphone_chat_message_get_chat_room(msg); + LinphoneCore *lc = linphone_chat_room_get_core(room); + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); + env->CallVoidMethod(listener, method, jmessage, env->CallStaticObjectMethod(ljb->chatMessageStateClass, ljb->chatMessageStateFromIntId, (jint)state)); if (state == LinphoneChatMessageStateDelivered || state == LinphoneChatMessageStateNotDelivered) { env->DeleteGlobalRef(listener); + msg->message_state_changed_user_data = NULL; } - env->DeleteLocalRef(chatMessageStateClass); } static void file_transfer_progress_indication(LinphoneChatMessage *msg, const LinphoneContent* content, size_t offset, size_t total) { @@ -3352,7 +3493,7 @@ static void file_transfer_progress_indication(LinphoneChatMessage *msg, const Li return; } - jobject listener = (jobject) msg->cb_ud; + jobject listener = (jobject) msg->message_state_changed_user_data; jclass clazz = (jclass) env->GetObjectClass(listener); jmethodID method = env->GetMethodID(clazz, "onLinphoneChatMessageFileTransferProgressChanged", "(Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneContent;II)V"); env->DeleteLocalRef(clazz); @@ -3372,11 +3513,11 @@ static void file_transfer_recv(LinphoneChatMessage *msg, const LinphoneContent* return; } - jobject listener = (jobject) msg->cb_ud; + jobject listener = (jobject) msg->message_state_changed_user_data; 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"); env->DeleteLocalRef(clazz); - + jobject jmessage = getChatMessage(env, msg); jobject jbuffer = buffer ? create_java_linphone_buffer(env, buffer) : NULL; jobject jcontent = content ? create_java_linphone_content(env, content) : NULL; @@ -3398,11 +3539,11 @@ static LinphoneBuffer* file_transfer_send(LinphoneChatMessage *msg, const Linph return buffer; } - jobject listener = (jobject) msg->cb_ud; + jobject listener = (jobject) msg->message_state_changed_user_data; 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"); env->DeleteLocalRef(clazz); - + jobject jmessage = getChatMessage(env, msg); jobject jbuffer = create_java_linphone_buffer(env, NULL); jobject jcontent = content ? create_java_linphone_content(env, content) : NULL; @@ -3410,7 +3551,7 @@ static LinphoneBuffer* file_transfer_send(LinphoneChatMessage *msg, const Linph if (jcontent) { env->DeleteLocalRef(jcontent); } - + buffer = create_c_linphone_buffer_from_java_linphone_buffer(env, jbuffer); env->DeleteLocalRef(jbuffer); return buffer; @@ -3420,8 +3561,8 @@ extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_setListener(JNIEn jobject listener = env->NewGlobalRef(jlistener); LinphoneChatMessage *message = (LinphoneChatMessage *)ptr; LinphoneChatMessageCbs *cbs; - - message->cb_ud = listener; + + message->message_state_changed_user_data = 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); @@ -3438,7 +3579,7 @@ extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_unref(JNIEnv* en extern "C" jlongArray Java_org_linphone_core_LinphoneCoreImpl_getChatRooms(JNIEnv* env ,jobject thiz ,jlong ptr) { - MSList* chats = linphone_core_get_chat_rooms((LinphoneCore*)ptr); + const MSList* chats = linphone_core_get_chat_rooms((LinphoneCore*)ptr); int chatsSize = ms_list_size(chats); jlongArray jChats = env->NewLongArray(chatsSize); jlong *jInternalArray = env->GetLongArrayElements(jChats, NULL); @@ -3475,18 +3616,18 @@ static void chat_room_impl_callback(LinphoneChatMessage* msg, LinphoneChatMessag jmethodID method = env->GetMethodID(clazz, "onLinphoneChatMessageStateChanged","(Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneChatMessage$State;)V"); jobject jmessage=(jobject)linphone_chat_message_get_user_data(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;"); + LinphoneChatRoom *room = linphone_chat_message_get_chat_room(msg); + LinphoneCore *lc = linphone_chat_room_get_core(room); + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); env->CallVoidMethod( listener, method, jmessage, - env->CallStaticObjectMethod(chatMessageStateClass,chatMessageStateFromIntId,(jint)state)); + env->CallStaticObjectMethod(ljb->chatMessageStateClass,ljb->chatMessageStateFromIntId,(jint)state)); if (state == LinphoneChatMessageStateDelivered || state == LinphoneChatMessageStateNotDelivered) { env->DeleteGlobalRef(listener); env->DeleteGlobalRef(jmessage); - env->DeleteGlobalRef(chatMessageStateClass); linphone_chat_message_set_user_data(msg,NULL); } } @@ -3495,7 +3636,8 @@ extern "C" jobject Java_org_linphone_core_LinphoneChatRoomImpl_getCore(JNIEnv* ,jobject thiz ,jlong chatroom_ptr){ LinphoneCore *lc=linphone_chat_room_get_core((LinphoneChatRoom*)chatroom_ptr); - jobject core = (jobject)linphone_core_get_user_data(lc); + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); + jobject core = ljb->getCore(); return core; } @@ -3532,7 +3674,7 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setVideoWindowId(JNIEnv* obj = env->NewGlobalRef(obj); ms_message("Java_org_linphone_core_LinphoneCoreImpl_setVideoWindowId(): NewGlobalRef(%p)",obj); }else ms_message("Java_org_linphone_core_LinphoneCoreImpl_setVideoWindowId(): setting to NULL"); - linphone_core_set_native_video_window_id((LinphoneCore*)lc,(unsigned long)obj); + linphone_core_set_native_video_window_id((LinphoneCore*)lc,(void *)obj); if (oldWindow != NULL) { ms_message("Java_org_linphone_core_LinphoneCoreImpl_setVideoWindowId(): DeleteGlobalRef(%p)",oldWindow); env->DeleteGlobalRef(oldWindow); @@ -3548,7 +3690,7 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setPreviewWindowId(JNIEn obj = env->NewGlobalRef(obj); ms_message("Java_org_linphone_core_LinphoneCoreImpl_setPreviewWindowId(): NewGlobalRef(%p)",obj); }else ms_message("Java_org_linphone_core_LinphoneCoreImpl_setPreviewWindowId(): setting to NULL"); - linphone_core_set_native_preview_window_id((LinphoneCore*)lc,(unsigned long)obj); + linphone_core_set_native_preview_window_id((LinphoneCore*)lc,(void *)obj); if (oldWindow != NULL) { ms_message("Java_org_linphone_core_LinphoneCoreImpl_setPreviewWindowId(): DeleteGlobalRef(%p)",oldWindow); env->DeleteGlobalRef(oldWindow); @@ -3704,6 +3846,44 @@ extern "C" void Java_org_linphone_core_LinphoneCallParamsImpl_addCustomHeader(JN env->ReleaseStringUTFChars(jheader_value, header_value); } +JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneCallParamsImpl_addCustomSdpAttribute(JNIEnv *env, jobject thiz, jlong ptr, jstring jname, jstring jvalue) { + const char *name = env->GetStringUTFChars(jname, NULL); + const char *value = env->GetStringUTFChars(jvalue, NULL); + linphone_call_params_add_custom_sdp_attribute((LinphoneCallParams *)ptr, name, value); + env->ReleaseStringUTFChars(jname, name); + env->ReleaseStringUTFChars(jvalue, value); +} + +JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneCallParamsImpl_addCustomSdpMediaAttribute(JNIEnv *env, jobject thiz, jlong ptr, jint jtype, jstring jname, jstring jvalue) { + const char *name = env->GetStringUTFChars(jname, NULL); + const char *value = env->GetStringUTFChars(jvalue, NULL); + linphone_call_params_add_custom_sdp_media_attribute((LinphoneCallParams *)ptr, (LinphoneStreamType)jtype, name, value); + env->ReleaseStringUTFChars(jname, name); + env->ReleaseStringUTFChars(jvalue, value); +} + +JNIEXPORT jstring JNICALL Java_org_linphone_core_LinphoneCallParamsImpl_getCustomSdpAttribute(JNIEnv *env, jobject thiz, jlong ptr, jstring jname) { + const char *name = env->GetStringUTFChars(jname, NULL); + const char *value = linphone_call_params_get_custom_sdp_attribute((LinphoneCallParams *)ptr, name); + env->ReleaseStringUTFChars(jname, name); + return value ? env->NewStringUTF(value) : NULL; +} + +JNIEXPORT jstring JNICALL Java_org_linphone_core_LinphoneCallParamsImpl_getCustomSdpMediaAttribute(JNIEnv *env, jobject thiz, jlong ptr, jint jtype, jstring jname) { + const char *name = env->GetStringUTFChars(jname, NULL); + const char *value = linphone_call_params_get_custom_sdp_media_attribute((LinphoneCallParams *)ptr, (LinphoneStreamType)jtype, name); + env->ReleaseStringUTFChars(jname, name); + return value ? env->NewStringUTF(value) : NULL; +} + +JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneCallParamsImpl_clearCustomSdpAttributes(JNIEnv *env, jobject thiz, jlong ptr) { + linphone_call_params_clear_custom_sdp_attributes((LinphoneCallParams *)ptr); +} + +JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneCallParamsImpl_clearCustomSdpMediaAttributes(JNIEnv *env, jobject thiz, jlong ptr, jint jtype) { + linphone_call_params_clear_custom_sdp_media_attributes((LinphoneCallParams *)ptr, (LinphoneStreamType)jtype); +} + extern "C" void Java_org_linphone_core_LinphoneCallParamsImpl_setRecordFile(JNIEnv *env, jobject thiz, jlong lcp, jstring jrecord_file){ if (jrecord_file){ const char* record_file=env->GetStringUTFChars(jrecord_file, NULL); @@ -3730,11 +3910,34 @@ extern "C" jintArray Java_org_linphone_core_LinphoneCallParamsImpl_getReceivedVi return arr; } +JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneCallParamsImpl_getAudioDirection(JNIEnv *env, jobject thiz, jlong ptr) { + return (jint)linphone_call_params_get_audio_direction((LinphoneCallParams *)ptr); +} + +JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneCallParamsImpl_getVideoDirection(JNIEnv *env, jobject thiz, jlong ptr) { + return (jint)linphone_call_params_get_video_direction((LinphoneCallParams *)ptr); +} + +JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneCallParamsImpl_setAudioDirection(JNIEnv *env, jobject thiz, jlong ptr, jint jdir) { + linphone_call_params_set_audio_direction((LinphoneCallParams *)ptr, (LinphoneMediaDirection)jdir); +} + +JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneCallParamsImpl_setVideoDirection(JNIEnv *env, jobject thiz, jlong ptr, jint jdir) { + linphone_call_params_set_video_direction((LinphoneCallParams *)ptr, (LinphoneMediaDirection)jdir); +} + + extern "C" void Java_org_linphone_core_LinphoneCallParamsImpl_destroy(JNIEnv *env, jobject thiz, jlong lc){ return linphone_call_params_destroy((LinphoneCallParams*)lc); } -extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_createDefaultCallParams(JNIEnv *env, jobject thiz, jlong lc){ - return (jlong) linphone_core_create_default_call_parameters((LinphoneCore*)lc); + +/* + * Class: org_linphone_core_LinphoneCoreImpl + * Method: createCallParams + * Signature: (JJ)J + */ +JNIEXPORT jlong JNICALL Java_org_linphone_core_LinphoneCoreImpl_createCallParams(JNIEnv *env, jobject jcore, jlong coreptr, jlong callptr){ + return (jlong)linphone_core_create_call_params((LinphoneCore*)coreptr, (LinphoneCall*)callptr); } extern "C" jlong Java_org_linphone_core_LinphoneCallImpl_getRemoteParams(JNIEnv *env, jobject thiz, jlong lc){ @@ -3805,10 +4008,18 @@ extern "C" jintArray Java_org_linphone_core_LinphoneCoreImpl_getPreferredVideoSi return arr; } +JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneCoreImpl_getDownloadBandwidth(JNIEnv *env, jobject thiz, jlong lc) { + return (jint) linphone_core_get_download_bandwidth((LinphoneCore *)lc); +} + extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setDownloadBandwidth(JNIEnv *env, jobject thiz, jlong lc, jint bw){ linphone_core_set_download_bandwidth((LinphoneCore *)lc, (int) bw); } +JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneCoreImpl_getUploadBandwidth(JNIEnv *env, jobject thiz, jlong lc) { + return (jint) linphone_core_get_upload_bandwidth((LinphoneCore *)lc); +} + extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setUploadBandwidth(JNIEnv *env, jobject thiz, jlong lc, jint bw){ linphone_core_set_upload_bandwidth((LinphoneCore *)lc, (int) bw); } @@ -3940,6 +4151,10 @@ extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_getSipDscp(JNIEnv* env,j return linphone_core_get_sip_dscp((LinphoneCore*)ptr); } +extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_getGlobalState(JNIEnv* env,jobject thiz,jlong ptr){ + return linphone_core_get_global_state((LinphoneCore*)ptr); +} + extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_getSignalingTransportPort(JNIEnv* env,jobject thiz,jlong ptr, jint code) { LCSipTransports tr; linphone_core_get_sip_transports((LinphoneCore *) ptr, &tr); @@ -4194,27 +4409,15 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_tunnelAddServerAndMirror env->ReleaseStringUTFChars(jHost, cHost); } -extern "C" void Java_org_linphone_core_LinphoneCoreImpl_tunnelAddServer(JNIEnv *env, jobject thiz, jlong pCore, jobject config) { +extern "C" void Java_org_linphone_core_LinphoneCoreImpl_tunnelAddServer(JNIEnv *env, jobject thiz, jlong pCore, jlong tunnelconfigptr) { LinphoneTunnel *tunnel = linphone_core_get_tunnel((LinphoneCore *)pCore); if(tunnel != NULL) { - jclass TunnelConfigClass = env->FindClass("org/linphone/core/TunnelConfig"); - jmethodID getHostMethod = env->GetMethodID(TunnelConfigClass, "getHost", "()Ljava/lang/String;"); - jmethodID getPortMethod = env->GetMethodID(TunnelConfigClass, "getPort", "()I"); - jmethodID getRemoteUdpMirrorPortMethod = env->GetMethodID(TunnelConfigClass, "getRemoteUdpMirrorPort", "()I"); - jmethodID getDelayMethod = env->GetMethodID(TunnelConfigClass, "getDelay", "()I"); - jstring hostString = (jstring)env->CallObjectMethod(config, getHostMethod); - const char *host = env->GetStringUTFChars(hostString, NULL); - if(host == NULL || strlen(host)==0) { - ms_error("LinphoneCore.tunnelAddServer(): no tunnel host defined"); + LinphoneTunnelConfig *cfg = (LinphoneTunnelConfig*) tunnelconfigptr; + if (cfg) { + linphone_tunnel_add_server(tunnel, cfg); + }else{ + ms_error("Java TunnelConfig object has no associated C object"); } - LinphoneTunnelConfig *tunnelConfig = linphone_tunnel_config_new(); - linphone_tunnel_config_set_host(tunnelConfig, host); - linphone_tunnel_config_set_port(tunnelConfig, env->CallIntMethod(config, getPortMethod)); - linphone_tunnel_config_set_remote_udp_mirror_port(tunnelConfig, env->CallIntMethod(config, getRemoteUdpMirrorPortMethod)); - linphone_tunnel_config_set_delay(tunnelConfig, env->CallIntMethod(config, getDelayMethod)); - linphone_tunnel_add_server(tunnel, tunnelConfig); - env->ReleaseStringUTFChars(hostString, host); - env->DeleteLocalRef(TunnelConfigClass); } else { ms_error("LinphoneCore.tunnelAddServer(): tunnel feature is not enabled"); } @@ -4222,31 +4425,22 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_tunnelAddServer(JNIEnv * extern "C" jobjectArray Java_org_linphone_core_LinphoneCoreImpl_tunnelGetServers(JNIEnv *env, jobject thiz, jlong pCore) { LinphoneTunnel *tunnel = linphone_core_get_tunnel((LinphoneCore *)pCore); - jclass TunnelConfigClass = env->FindClass("org/linphone/core/TunnelConfig"); - jmethodID setHostMethod = env->GetMethodID(TunnelConfigClass, "setHost", "(Ljava/lang/String;)V"); - jmethodID setPortMethod = env->GetMethodID(TunnelConfigClass, "setPort", "(I)V"); - jmethodID setRemoteUdpMirrorPortMethod = env->GetMethodID(TunnelConfigClass, "setRemoteUdpMirrorPort", "(I)V"); - jmethodID setDelayMethod = env->GetMethodID(TunnelConfigClass, "setDelay", "(I)V"); + jclass tunnelConfigClass = env->FindClass("org/linphone/core/TunnelConfigImpl"); jobjectArray tunnelConfigArray = NULL; if(tunnel != NULL) { const MSList *servers = linphone_tunnel_get_servers(tunnel); const MSList *it; int i; - ms_message("servers=%p", (void *)servers); - ms_message("taille=%i", ms_list_size(servers)); - tunnelConfigArray = env->NewObjectArray(ms_list_size(servers), TunnelConfigClass, NULL); + + tunnelConfigArray = env->NewObjectArray(ms_list_size(servers), tunnelConfigClass, NULL); for(it = servers, i=0; it != NULL; it = it->next, i++) { - const LinphoneTunnelConfig *conf = (const LinphoneTunnelConfig *)it->data; - jobject elt = env->AllocObject(TunnelConfigClass); - env->CallVoidMethod(elt, setHostMethod, env->NewStringUTF(linphone_tunnel_config_get_host(conf))); - env->CallVoidMethod(elt, setPortMethod, linphone_tunnel_config_get_port(conf)); - env->CallVoidMethod(elt, setRemoteUdpMirrorPortMethod, linphone_tunnel_config_get_remote_udp_mirror_port(conf)); - env->CallVoidMethod(elt, setDelayMethod, linphone_tunnel_config_get_delay(conf)); + LinphoneTunnelConfig *conf = (LinphoneTunnelConfig *)it->data; + jobject elt = getTunnelConfig(env, conf); env->SetObjectArrayElement(tunnelConfigArray, i, elt); - env->DeleteLocalRef(TunnelConfigClass); } } + env->DeleteLocalRef(tunnelConfigClass); return tunnelConfigArray; } @@ -4691,7 +4885,7 @@ static jobject create_java_linphone_content(JNIEnv *env, const LinphoneContent * } jobject jobj = env->NewObject(contentClass, ctor, jname, jtype, jsubtype, jdata, jencoding, jsize); - + env->DeleteLocalRef(contentClass); env->DeleteLocalRef(jtype); env->DeleteLocalRef(jsubtype); @@ -4701,7 +4895,7 @@ static jobject create_java_linphone_content(JNIEnv *env, const LinphoneContent * if (jname) { env->DeleteLocalRef(jname); } - + return jobj; } @@ -4737,7 +4931,7 @@ static LinphoneBuffer* create_c_linphone_buffer_from_java_linphone_buffer(JNIEnv bufferClass = (jclass)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); @@ -4747,7 +4941,7 @@ static LinphoneBuffer* create_c_linphone_buffer_from_java_linphone_buffer(JNIEnv env->ReleaseByteArrayElements(jcontent, (jbyte*)content, JNI_ABORT); } env->DeleteLocalRef(bufferClass); - + return buffer; } @@ -4837,7 +5031,8 @@ JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneCoreFactoryImpl__1setLogHa JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneEventImpl_getCore(JNIEnv *env, jobject jobj, jlong evptr){ LinphoneCore *lc=linphone_event_get_core((LinphoneEvent*)evptr); - jobject core = (jobject)linphone_core_get_user_data(lc); + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); + jobject core = ljb->getCore(); return core; } @@ -6067,7 +6262,7 @@ extern "C" void Java_org_linphone_core_LinphonePlayerImpl_destroy(JNIEnv *env, j extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_createLocalPlayer(JNIEnv *env, jobject jobj, jlong ptr, jobject window) { jobject window_ref = NULL; window_ref = env->NewGlobalRef(window); - LinphonePlayer *player = linphone_core_create_local_player((LinphoneCore *)ptr, NULL, "MSAndroidDisplay", (unsigned long)window_ref); + LinphonePlayer *player = linphone_core_create_local_player((LinphoneCore *)ptr, NULL, "MSAndroidDisplay", (void *)window_ref); if(player == NULL) { ms_error("Fails to create a player"); if(window_ref) env->DeleteGlobalRef(window_ref); @@ -6215,3 +6410,281 @@ JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneCoreImpl_enableDnsSrv(JNIE JNIEXPORT jboolean JNICALL Java_org_linphone_core_LinphoneCoreImpl_dnsSrvEnabled(JNIEnv *env, jobject thiz, jlong lc) { return linphone_core_dns_srv_enabled((LinphoneCore *)lc); } + +JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneCoreImpl_setVideoPreset(JNIEnv *env, jobject thiz, jlong lc, jstring preset) { + const char *char_preset = preset ? env->GetStringUTFChars(preset, NULL) : NULL; + linphone_core_set_video_preset((LinphoneCore *)lc, char_preset); + if (char_preset) env->ReleaseStringUTFChars(preset, char_preset); +} + +JNIEXPORT jstring JNICALL Java_org_linphone_core_LinphoneCoreImpl_getVideoPreset(JNIEnv *env, jobject thiz, jlong lc) { + const char *tmp = linphone_core_get_video_preset((LinphoneCore *)lc); + return tmp ? env->NewStringUTF(tmp) : NULL; +} + +extern "C" jlong Java_org_linphone_core_LinphoneCallImpl_getChatRoom(JNIEnv* env ,jobject thiz, jlong ptr) { + return (jlong) linphone_call_get_chat_room((LinphoneCall *) ptr); +} + +extern "C" void Java_org_linphone_core_LinphoneCallParamsImpl_enableRealTimeText(JNIEnv* env ,jobject thiz, jlong ptr, jboolean yesno) { + linphone_call_params_enable_realtime_text((LinphoneCallParams *)ptr, yesno); +} + +extern "C" jboolean Java_org_linphone_core_LinphoneCallParamsImpl_realTimeTextEnabled(JNIEnv* env ,jobject thiz, jlong ptr) { + return linphone_call_params_realtime_text_enabled((LinphoneCallParams *)ptr); +} + +extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_putChar(JNIEnv* env ,jobject thiz, jlong ptr, jlong character) { + linphone_chat_message_put_char((LinphoneChatMessage *)ptr, character); +} + +extern "C" jobject Java_org_linphone_core_LinphoneChatRoomImpl_getCall(JNIEnv* env ,jobject thiz, jlong ptr) { + return getCall(env, linphone_chat_room_get_call((LinphoneChatRoom *)ptr)); +} + +extern "C" jlong Java_org_linphone_core_LinphoneChatRoomImpl_getChar(JNIEnv* env ,jobject thiz, jlong ptr) { + return linphone_chat_room_get_char((LinphoneChatRoom *)ptr); +} + +static void _next_video_frame_decoded_callback(LinphoneCall *call, void *user_data) { + JNIEnv *env = 0; + jint result = jvm->AttachCurrentThread(&env,NULL); + + if (result != 0) { + ms_error("cannot attach VM\n"); + return; + } + + jobject listener = (jobject) user_data; + jclass clazz = (jclass) env->GetObjectClass(listener); + jmethodID method = env->GetMethodID(clazz, "onNextVideoFrameDecoded","(Lorg/linphone/core/LinphoneCall;)V"); + env->DeleteLocalRef(clazz); + + jobject jcall = getCall(env, call); + env->CallVoidMethod(listener, method, jcall); +} + +JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneCallImpl_setListener(JNIEnv* env, jobject thiz, jlong ptr, jobject jlistener) { + jobject listener = env->NewGlobalRef(jlistener); + LinphoneCall *call = (LinphoneCall *)ptr; + linphone_call_set_next_video_frame_decoded_callback(call, _next_video_frame_decoded_callback, listener); +} + + +/* + * returns the java TunnelConfig associated with a C LinphoneTunnelConfig. +**/ +static jobject getTunnelConfig(JNIEnv *env, LinphoneTunnelConfig *cfg){ + jobject jobj=0; + + if (cfg != NULL){ + jclass tunnelConfigClass = env->FindClass("org/linphone/core/TunnelConfigImpl"); + jmethodID ctor = env->GetMethodID(tunnelConfigClass,"", "(J)V"); + + void *up=linphone_tunnel_config_get_user_data(cfg); + + if (up==NULL){ + jobj=env->NewObject(tunnelConfigClass,ctor,(jlong)cfg); + linphone_tunnel_config_set_user_data(cfg,(void*)env->NewWeakGlobalRef(jobj)); + linphone_tunnel_config_ref(cfg); + }else{ + //promote the weak ref to local ref + jobj=env->NewLocalRef((jobject)up); + if (jobj == NULL){ + //the weak ref was dead + jobj=env->NewObject(tunnelConfigClass,ctor,(jlong)cfg); + linphone_tunnel_config_set_user_data(cfg,(void*)env->NewWeakGlobalRef(jobj)); + } + } + env->DeleteLocalRef(tunnelConfigClass); + } + return jobj; +} + + +/* + * Class: org_linphone_core_TunnelConfigImpl + * Method: getHost + * Signature: (J)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_linphone_core_TunnelConfigImpl_getHost(JNIEnv *env, jobject obj, jlong ptr){ + LinphoneTunnelConfig *cfg = (LinphoneTunnelConfig *)ptr; + const char *host = linphone_tunnel_config_get_host(cfg); + if (host){ + return env->NewStringUTF(host); + } + return NULL; +} + +/* + * Class: org_linphone_core_TunnelConfigImpl + * Method: setHost + * Signature: (JLjava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_org_linphone_core_TunnelConfigImpl_setHost(JNIEnv *env, jobject obj, jlong ptr, jstring jstr){ + LinphoneTunnelConfig *cfg = (LinphoneTunnelConfig *)ptr; + const char* host = jstr ? env->GetStringUTFChars(jstr, NULL) : NULL; + linphone_tunnel_config_set_host(cfg, host); + if (jstr) env->ReleaseStringUTFChars(jstr, host); +} + +/* + * Class: org_linphone_core_TunnelConfigImpl + * Method: getPort + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_linphone_core_TunnelConfigImpl_getPort(JNIEnv *env, jobject jobj, jlong ptr){ + LinphoneTunnelConfig *cfg = (LinphoneTunnelConfig *)ptr; + return linphone_tunnel_config_get_port(cfg); +} + +/* + * Class: org_linphone_core_TunnelConfigImpl + * Method: setPort + * Signature: (JI)V + */ +JNIEXPORT void JNICALL Java_org_linphone_core_TunnelConfigImpl_setPort(JNIEnv *env, jobject jobj, jlong ptr, jint port){ + LinphoneTunnelConfig *cfg = (LinphoneTunnelConfig *)ptr; + linphone_tunnel_config_set_port(cfg, port); +} + +/* + * Class: org_linphone_core_TunnelConfigImpl + * Method: getRemoteUdpMirrorPort + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_linphone_core_TunnelConfigImpl_getRemoteUdpMirrorPort(JNIEnv *env, jobject jobj, jlong ptr){ + LinphoneTunnelConfig *cfg = (LinphoneTunnelConfig *)ptr; + return linphone_tunnel_config_get_remote_udp_mirror_port(cfg); +} + +/* + * Class: org_linphone_core_TunnelConfigImpl + * Method: setRemoteUdpMirrorPort + * Signature: (JI)V + */ +JNIEXPORT void JNICALL Java_org_linphone_core_TunnelConfigImpl_setRemoteUdpMirrorPort(JNIEnv *env, jobject jobj, jlong ptr, jint port){ + LinphoneTunnelConfig *cfg = (LinphoneTunnelConfig *)ptr; + linphone_tunnel_config_set_remote_udp_mirror_port(cfg, port); +} + +/* + * Class: org_linphone_core_TunnelConfigImpl + * Method: getDelay + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_linphone_core_TunnelConfigImpl_getDelay(JNIEnv *env, jobject jobj, jlong ptr){ + LinphoneTunnelConfig *cfg = (LinphoneTunnelConfig *)ptr; + return linphone_tunnel_config_get_delay(cfg); +} + +/* + * Class: org_linphone_core_TunnelConfigImpl + * Method: setDelay + * Signature: (JI)I + */ +JNIEXPORT void JNICALL Java_org_linphone_core_TunnelConfigImpl_setDelay(JNIEnv *env, jobject jobj, jlong ptr, jint delay){ + LinphoneTunnelConfig *cfg = (LinphoneTunnelConfig *)ptr; + linphone_tunnel_config_set_delay(cfg, delay); +} + +/* + * Class: org_linphone_core_TunnelConfigImpl + * Method: destroy + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_org_linphone_core_TunnelConfigImpl_destroy(JNIEnv *env, jobject jobj, jlong ptr){ + LinphoneTunnelConfig *cfg = (LinphoneTunnelConfig *)ptr; + linphone_tunnel_config_set_user_data(cfg, NULL); + linphone_tunnel_config_unref(cfg); +} + + +/* + * Class: org_linphone_core_LinphoneCallLogImpl + * Method: getCallId + * Signature: (J)I + */ +JNIEXPORT jstring JNICALL Java_org_linphone_core_LinphoneCallLogImpl_getCallId(JNIEnv *env, jobject jobj, jlong pcl){ + const char *str = linphone_call_log_get_call_id((LinphoneCallLog*)pcl); + return str ? env->NewStringUTF(str) : NULL; +} + +/* + * Class: org_linphone_core_LinphoneCoreImpl + * Method: setHttpProxyHost + * Signature: (JLjava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneCoreImpl_setHttpProxyHost(JNIEnv *env, jobject jobj, jlong core, jstring jhost){ + const char *host = jhost ? env->GetStringUTFChars(jhost, NULL) : NULL; + linphone_core_set_http_proxy_host((LinphoneCore*)core, host); + if (host) env->ReleaseStringUTFChars(jhost, host); +} + +/* + * Class: org_linphone_core_LinphoneCoreImpl + * Method: setHttpProxyPort + * Signature: (JI)V + */ +JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneCoreImpl_setHttpProxyPort(JNIEnv *env, jobject jobj, jlong core, jint port){ + linphone_core_set_http_proxy_port((LinphoneCore*)core, port); +} + +/* + * Class: org_linphone_core_LinphoneCoreImpl + * Method: getHttpProxyHost + * Signature: (J)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_linphone_core_LinphoneCoreImpl_getHttpProxyHost(JNIEnv *env , jobject jobj, jlong core){ + const char * host = linphone_core_get_http_proxy_host((LinphoneCore *)core); + return host ? env->NewStringUTF(host) : NULL; +} + +/* + * Class: org_linphone_core_LinphoneCoreImpl + * Method: getHttpProxyPort + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneCoreImpl_getHttpProxyPort(JNIEnv *env, jobject jobj, jlong core){ + return linphone_core_get_http_proxy_port((LinphoneCore *)core); +} + + +/* + * Class: org_linphone_core_LinphoneCoreImpl + * Method: setSipTransportTimeout + * Signature: (JI)V + */ +JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneCoreImpl_setSipTransportTimeout(JNIEnv *env, jobject jobj, jlong pcore, jint timeout){ + linphone_core_set_sip_transport_timeout((LinphoneCore*)pcore, timeout); +} + +/* + * Class: org_linphone_core_LinphoneCoreImpl + * Method: getSipTransportTimeout + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneCoreImpl_getSipTransportTimeout(JNIEnv *env, jobject jobj, jlong pcore){ + return linphone_core_get_sip_transport_timeout((LinphoneCore*)pcore); +} + +/* + * Class: org_linphone_core_LinphoneCoreImpl + * Method: setNortpTimeout + * Signature: (JI)V + */ +JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneCoreImpl_setNortpTimeout(JNIEnv *env, jobject obj, jlong core, jint timeout){ + linphone_core_set_nortp_timeout((LinphoneCore*)core, timeout); +} + +/* + * Class: org_linphone_core_LinphoneCoreImpl + * Method: getNortpTimeout + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneCoreImpl_getNortpTimeout(JNIEnv *env, jobject obj, jlong core){ + return linphone_core_get_nortp_timeout((LinphoneCore*)core); +} + + + diff --git a/coreapi/localplayer.c b/coreapi/localplayer.c index 964c1c920..eb53eb640 100644 --- a/coreapi/localplayer.c +++ b/coreapi/localplayer.c @@ -32,7 +32,7 @@ static void _local_player_close(LinphonePlayer *obj); static void _local_player_destroy(LinphonePlayer *obj); static void _local_player_eof_callback(void *user_data); -LinphonePlayer *linphone_core_create_local_player(LinphoneCore *lc, MSSndCard *snd_card, const char *video_out, unsigned long window_id) { +LinphonePlayer *linphone_core_create_local_player(LinphoneCore *lc, MSSndCard *snd_card, const char *video_out, void *window_id) { LinphonePlayer *obj = ms_new0(LinphonePlayer, 1); if(snd_card == NULL) snd_card = lc->sound_conf.ring_sndcard; if(video_out == NULL) video_out = linphone_core_get_video_display_filter(lc); diff --git a/coreapi/lpc2xml.c b/coreapi/lpc2xml.c index 1446a94cc..ed63669d0 100644 --- a/coreapi/lpc2xml.c +++ b/coreapi/lpc2xml.c @@ -74,7 +74,7 @@ static void lpc2xml_log(lpc2xml_context *xmlCtx, int level, const char *fmt, ... static void lpc2xml_genericxml_error(void *ctx, const char *fmt, ...) { lpc2xml_context *xmlCtx = (lpc2xml_context *)ctx; - int sl = strlen(xmlCtx->errorBuffer); + size_t sl = strlen(xmlCtx->errorBuffer); va_list args; va_start(args, fmt); vsnprintf(xmlCtx->errorBuffer + sl, LPC2XML_BZ-sl, fmt, args); @@ -101,6 +101,10 @@ static int processEntry(const char *section, const char *entry, xmlNode *node, l lpc2xml_log(ctx, LPC2XML_MESSAGE, "Set %s|%s = %s", section, entry, content); xmlNodeSetContent(node, (const xmlChar *) content); + + if (lp_config_get_overwrite_flag_for_entry(ctx->lpc, section, entry) || lp_config_get_overwrite_flag_for_section(ctx->lpc, section)) { + xmlSetProp(node, (const xmlChar *)"overwrite", (const xmlChar *) "true"); + } return 0; } diff --git a/coreapi/lpconfig.c b/coreapi/lpconfig.c index d1be24dc7..9973bde9c 100644 --- a/coreapi/lpconfig.c +++ b/coreapi/lpconfig.c @@ -40,28 +40,29 @@ #endif /*_WIN32_WCE*/ #ifdef _MSC_VER -#ifdef WINAPI_FAMILY_PHONE_APP -#include -#else +#ifdef LINPHONE_WINDOWS_DESKTOP #include +#else +#include #endif #else #include #endif -#ifdef WIN32 +#ifdef _WIN32 #define RENAME_REQUIRES_NONEXISTENT_NEW_PATH 1 #endif #define lp_new0(type,n) (type*)calloc(sizeof(type),n) #include "lpconfig.h" - +#include "lpc2xml.h" typedef struct _LpItem{ char *key; char *value; int is_comment; + bool_t overwrite; // If set to true, will add overwrite=true when converted to xml } LpItem; typedef struct _LpSectionParam{ @@ -73,6 +74,7 @@ typedef struct _LpSection{ char *name; MSList *items; MSList *params; + bool_t overwrite; // If set to true, will add overwrite=true to all items of this section when converted to xml } LpSection; struct _LpConfig{ @@ -85,6 +87,17 @@ struct _LpConfig{ int readonly; }; +char* lp_realpath(const char* file, char* name) { +#if defined(_WIN32) || defined(__QNX__) || defined(ANDROID) + return ms_strdup(file); +#else + char * output = realpath(file, name); + char * msoutput = ms_strdup(output); + free(output); + return msoutput; +#endif +} + LpItem * lp_item_new(const char *key, const char *value){ LpItem *item=lp_new0(LpItem,1); item->key=ortp_strdup(key); @@ -160,6 +173,11 @@ void lp_config_remove_section(LpConfig *lpconfig, LpSection *section){ lp_section_destroy(section); } +void lp_section_remove_item(LpSection *sec, LpItem *item){ + sec->items=ms_list_remove(sec->items,(void *)item); + lp_item_destroy(item); +} + static bool_t is_first_char(const char *start, const char *pos){ const char *p; for(p=start;pitems;elem!=NULL;elem=ms_list_next(elem)){ + item=(LpItem*)elem->data; + if (item->is_comment && strcmp(item->value,comment)==0) { + /*printf("Item %s found\n",name);*/ + return item; + } + } + return NULL; +} + LpItem *lp_section_find_item(const LpSection *sec, const char *name){ MSList *elem; LpItem *item; @@ -220,7 +252,7 @@ static LpSection* lp_config_parse_line(LpConfig* lpconfig, const char* line, LpS LpSectionParam *params = NULL; char *pos1,*pos2; int nbs; - int size=strlen(line)+1; + size_t size=strlen(line)+1; char *secname=ms_malloc(size); char *key=ms_malloc(size); char *value=ms_malloc(size); @@ -272,6 +304,10 @@ static LpSection* lp_config_parse_line(LpConfig* lpconfig, const char* line, LpS if (is_a_comment(line)){ if (cur){ LpItem *comment=lp_comment_new(line); + item=lp_section_find_comment(cur,comment->value); + if (item!=NULL) { + lp_section_remove_item(cur, item); + } lp_section_add_item(cur,comment); } }else{ @@ -359,22 +395,30 @@ LpConfig *lp_config_new_with_factory(const char *config_filename, const char *fa LpConfig *lpconfig=lp_new0(LpConfig,1); lpconfig->refcnt=1; if (config_filename!=NULL){ - ms_message("Using (r/w) config information from %s", config_filename); - lpconfig->filename=ortp_strdup(config_filename); - lpconfig->tmpfilename=ortp_strdup_printf("%s.tmp",config_filename); + if(ortp_file_exist(config_filename) == 0) { + lpconfig->filename=lp_realpath(config_filename, NULL); + if(lpconfig->filename == NULL) { + ms_error("Could not find the real path of %s: %s", config_filename, strerror(errno)); + goto fail; + } + } else { + lpconfig->filename = ms_strdup(config_filename); + } + lpconfig->tmpfilename=ortp_strdup_printf("%s.tmp",lpconfig->filename); + ms_message("Using (r/w) config information from %s", lpconfig->filename); -#if !defined(WIN32) +#if !defined(_WIN32) { struct stat fileStat; - if ((stat(config_filename,&fileStat) == 0) && (S_ISREG(fileStat.st_mode))) { + if ((stat(lpconfig->filename,&fileStat) == 0) && (S_ISREG(fileStat.st_mode))) { /* make existing configuration files non-group/world-accessible */ - if (chmod(config_filename, S_IRUSR | S_IWUSR) == -1) { + if (chmod(lpconfig->filename, S_IRUSR | S_IWUSR) == -1) { ms_warning("unable to correct permissions on " "configuration file: %s", strerror(errno)); } } } -#endif /*WIN32*/ +#endif /*_WIN32*/ /*open with r+ to check if we can write on it later*/ lpconfig->file=fopen(lpconfig->filename,"r+"); #ifdef RENAME_REQUIRES_NONEXISTENT_NEW_PATH @@ -397,17 +441,24 @@ LpConfig *lp_config_new_with_factory(const char *config_filename, const char *fa lp_config_read_file(lpconfig, factory_config_filename); } return lpconfig; + +fail: + ms_free(lpconfig); + return NULL; } int lp_config_read_file(LpConfig *lpconfig, const char *filename){ - FILE* f=fopen(filename,"r"); + char* path = lp_realpath(filename, NULL); + FILE* f=fopen(path,"r"); if (f!=NULL){ - ms_message("Reading config information from %s", filename); + ms_message("Reading config information from %s", path); lp_config_parse(lpconfig,f); fclose(f); + ms_free(path); return 0; } - ms_warning("Fail to open file %s",filename); + ms_warning("Fail to open file %s",path); + ms_free(path); return -1; } @@ -441,11 +492,6 @@ void lp_config_destroy(LpConfig *lpconfig){ lp_config_unref(lpconfig); } -void lp_section_remove_item(LpSection *sec, LpItem *item){ - sec->items=ms_list_remove(sec->items,(void *)item); - lp_item_destroy(item); -} - const char *lp_config_get_section_param_string(const LpConfig *lpconfig, const char *section, const char *key, const char *default_value){ LpSection *sec; LpSectionParam *param; @@ -505,7 +551,7 @@ int lp_config_get_int(const LpConfig *lpconfig,const char *section, const char * int64_t lp_config_get_int64(const LpConfig *lpconfig,const char *section, const char *key, int64_t default_value){ const char *str=lp_config_get_string(lpconfig,section,key,NULL); if (str!=NULL) { -#ifdef WIN32 +#ifdef _WIN32 return (int64_t)_atoi64(str); #else return atoll(str); @@ -522,6 +568,26 @@ float lp_config_get_float(const LpConfig *lpconfig,const char *section, const ch return ret; } +bool_t lp_config_get_overwrite_flag_for_entry(const LpConfig *lpconfig, const char *section, const char *key) { + LpSection *sec; + LpItem *item; + sec = lp_config_find_section(lpconfig, section); + if (sec != NULL){ + item = lp_section_find_item(sec, key); + if (item != NULL) return item->overwrite; + } + return 0; +} + +bool_t lp_config_get_overwrite_flag_for_section(const LpConfig *lpconfig, const char *section) { + LpSection *sec; + sec = lp_config_find_section(lpconfig, section); + if (sec != NULL){ + return sec->overwrite; + } + return 0; +} + void lp_config_set_string(LpConfig *lpconfig,const char *section, const char *key, const char *value){ LpItem *item; LpSection *sec=lp_config_find_section(lpconfig,section); @@ -574,6 +640,24 @@ void lp_config_set_float(LpConfig *lpconfig,const char *section, const char *key lp_config_set_string(lpconfig,section,key,tmp); } +void lp_config_set_overwrite_flag_for_entry(LpConfig *lpconfig, const char *section, const char *key, bool_t value) { + LpSection *sec; + LpItem *item; + sec = lp_config_find_section(lpconfig, section); + if (sec != NULL) { + item = lp_section_find_item(sec, key); + if (item != NULL) item->overwrite = value; + } +} + +void lp_config_set_overwrite_flag_for_section(LpConfig *lpconfig, const char *section, bool_t value) { + LpSection *sec; + sec = lp_config_find_section(lpconfig, section); + if (sec != NULL) { + sec->overwrite = value; + } +} + void lp_item_write(LpItem *item, FILE *file){ if (item->is_comment) fprintf(file,"%s\n",item->value); @@ -604,7 +688,7 @@ int lp_config_sync(LpConfig *lpconfig){ FILE *file; if (lpconfig->filename==NULL) return -1; if (lpconfig->readonly) return 0; -#ifndef WIN32 +#ifndef _WIN32 /* don't create group/world-accessible files */ (void) umask(S_IRWXG | S_IRWXO); #endif @@ -703,19 +787,30 @@ const char* lp_config_get_default_string(const LpConfig *lpconfig, const char *s return lp_config_get_string(lpconfig, default_section, key, default_value); } -static char *_lp_config_dirname(char *path) { +/* + * WARNING: this function is very dangerous. + * Read carefuly the folowing notices: + * 1. The 'path' parameter may be modify by + * the function. Be care to keep a copy of + * the original string. + * 2. The return pointer may points on a part of + * 'path'. So, be care to not free the string + * pointed by 'path' before the last used of + * the returned pointer. + * 3. Do not feed it after midnight + */ +static const char *_lp_config_dirname(char *path) { #ifdef _MSC_VER char drive[_MAX_DRIVE]; char dir[_MAX_DIR]; char fname[_MAX_FNAME]; char ext[_MAX_EXT]; + static char dirname[_MAX_DRIVE + _MAX_DIR]; _splitpath(path, drive, dir, fname, ext); - return ms_strdup_printf("%s%s", drive, dir); + snprintf(dirname, sizeof(dirname), "%s%s", drive, dir); + return dirname; #else - char *tmp = ms_strdup(path); - char *dir = ms_strdup(dirname(tmp)); - ms_free(tmp); - return dir; + return dirname(path); #endif } @@ -723,11 +818,19 @@ bool_t lp_config_relative_file_exists(const LpConfig *lpconfig, const char *file if (lpconfig->filename == NULL) { return FALSE; } else { - char *dir = _lp_config_dirname(lpconfig->filename); + char *filename = ms_strdup(lpconfig->filename); + const char *dir = _lp_config_dirname(filename); char *filepath = ms_strdup_printf("%s/%s", dir, filename); - FILE *file = fopen(filepath, "r"); - ms_free(dir); + char *realfilepath = lp_realpath(filepath, NULL); + FILE *file; + + ms_free(filename); ms_free(filepath); + + if(realfilepath == NULL) return FALSE; + + file = fopen(realfilepath, "r"); + ms_free(realfilepath); if (file) { fclose(file); } @@ -736,49 +839,110 @@ bool_t lp_config_relative_file_exists(const LpConfig *lpconfig, const char *file } void lp_config_write_relative_file(const LpConfig *lpconfig, const char *filename, const char *data) { + char *dup_config_file = NULL; + const char *dir = NULL; + char *filepath = NULL; + char *realfilepath = NULL; + FILE *file; + if (lpconfig->filename == NULL) return; - if(strlen(data) > 0) { - char *dir = _lp_config_dirname(lpconfig->filename); - char *filepath = ms_strdup_printf("%s/%s", dir, filename); - FILE *file = fopen(filepath, "w"); - if(file != NULL) { - fprintf(file, "%s", data); - fclose(file); - } else { - ms_error("Could not open %s for write", filepath); - } - ms_free(dir); - ms_free(filepath); - } else { + + if(strlen(data) == 0) { ms_warning("%s has not been created because there is no data to write", filename); + return; } + + dup_config_file = ms_strdup(lpconfig->filename); + dir = _lp_config_dirname(dup_config_file); + filepath = ms_strdup_printf("%s/%s", dir, filename); + realfilepath = lp_realpath(filepath, NULL); + if(realfilepath == NULL) { + ms_error("Could not resolv %s: %s", filepath, strerror(errno)); + goto end; + } + + file = fopen(realfilepath, "w"); + if(file == NULL) { + ms_error("Could not open %s for write", realfilepath); + goto end; + } + + fprintf(file, "%s", data); + fclose(file); + +end: + ms_free(dup_config_file); + ms_free(filepath); + if(realfilepath) ms_free(realfilepath); } int lp_config_read_relative_file(const LpConfig *lpconfig, const char *filename, char *data, size_t max_length) { - char *dir; - char *filepath; - FILE *file; + char *dup_config_file = NULL; + const char *dir = NULL; + char *filepath = NULL; + FILE *file = NULL; + char* realfilepath = NULL; if (lpconfig->filename == NULL) return -1; - dir = _lp_config_dirname(lpconfig->filename); + + dup_config_file = ms_strdup(lpconfig->filename); + dir = _lp_config_dirname(dup_config_file); filepath = ms_strdup_printf("%s/%s", dir, filename); - file = fopen(filepath, "r"); - if(file != NULL) { - if(fread(data, 1, max_length, file)<=0) { - ms_error("%s could not be loaded. %s", filepath, strerror(errno)); - goto err; - } - fclose(file); - } else { - ms_error("Could not open %s for read. %s", filepath, strerror(errno)); + realfilepath = lp_realpath(filepath, NULL); + if(realfilepath == NULL) { + ms_error("Could not resolv %s: %s", filepath, strerror(errno)); goto err; } - ms_free(dir); + + file = fopen(realfilepath, "r"); + if(file == NULL) { + ms_error("Could not open %s for read. %s", realfilepath, strerror(errno)); + goto err; + } + + if(fread(data, 1, max_length, file)<=0) { + ms_error("%s could not be loaded. %s", realfilepath, strerror(errno)); + goto err; + } + fclose(file); + + ms_free(dup_config_file); ms_free(filepath); + ms_free(realfilepath); return 0; err: - ms_free(dir); ms_free(filepath); + ms_free(filepath); + if(realfilepath) ms_free(realfilepath); return -1; } + +const char** lp_config_get_sections_names(LpConfig *lpconfig) { + const char **sections_names; + const MSList *sections = lpconfig->sections; + int ndev; + int i; + + ndev = ms_list_size(sections); + sections_names = ms_malloc((ndev + 1) * sizeof(const char *)); + + for (i = 0; sections != NULL; sections = sections->next, i++) { + LpSection *section = (LpSection *)sections->data; + sections_names[i] = ms_strdup(section->name); + } + + sections_names[ndev] = NULL; + return sections_names; +} + +char* lp_config_dump_as_xml(const LpConfig *lpconfig) { + char *buffer; + + lpc2xml_context *ctx = lpc2xml_context_new(NULL, NULL); + lpc2xml_set_lpc(ctx, lpconfig); + lpc2xml_convert_string(ctx, &buffer); + lpc2xml_context_destroy(ctx); + + return buffer; +} \ No newline at end of file diff --git a/coreapi/lpconfig.h b/coreapi/lpconfig.h index b03bfa57f..49e2bb50d 100644 --- a/coreapi/lpconfig.h +++ b/coreapi/lpconfig.h @@ -200,6 +200,13 @@ LINPHONE_PUBLIC int lp_config_has_section(const LpConfig *lpconfig, const char * **/ LINPHONE_PUBLIC void lp_config_clean_section(LpConfig *lpconfig, const char *section); +/** + * Returns the list of sections' names in the LpConfig. + * @param[in] lpconfig The LpConfig object + * @return a null terminated static array of strings +**/ +LINPHONE_PUBLIC const char** lp_config_get_sections_names(LpConfig *lpconfig); + /** * Call a function for each section present in the configuration. * @@ -295,6 +302,43 @@ LINPHONE_PUBLIC int lp_config_read_relative_file(const LpConfig *lpconfig, const **/ LINPHONE_PUBLIC bool_t lp_config_relative_file_exists(const LpConfig *lpconfig, const char *filename); +/** + * Dumps the LpConfig as XML into a buffer + * @param[in] lpconfig The LpConfig object + * @return The buffer that contains the XML dump + * + * @ingroup misc +**/ +LINPHONE_PUBLIC char* lp_config_dump_as_xml(const LpConfig *lpconfig); + +/** + * Retrieves the overwrite flag for a config item + * + * @ingroup misc +**/ +LINPHONE_PUBLIC bool_t lp_config_get_overwrite_flag_for_entry(const LpConfig *lpconfig, const char *section, const char *key); + +/** + * Sets the overwrite flag for a config item (used when dumping config as xml) + * + * @ingroup misc +**/ +LINPHONE_PUBLIC void lp_config_set_overwrite_flag_for_entry(LpConfig *lpconfig, const char *section, const char *key, bool_t value); + +/** + * Retrieves the overwrite flag for a config section + * + * @ingroup misc +**/ +LINPHONE_PUBLIC bool_t lp_config_get_overwrite_flag_for_section(const LpConfig *lpconfig, const char *section); + +/** + * Sets the overwrite flag for a config section (used when dumping config as xml) + * + * @ingroup misc +**/ +LINPHONE_PUBLIC void lp_config_set_overwrite_flag_for_section(LpConfig *lpconfig, const char *section, bool_t value); + #ifdef __cplusplus } #endif diff --git a/coreapi/message_storage.c b/coreapi/message_storage.c index 69a71c544..3bf74f6ea 100644 --- a/coreapi/message_storage.c +++ b/coreapi/message_storage.c @@ -20,12 +20,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "private.h" #include "linphonecore.h" -#ifdef MSG_STORAGE_ENABLED + +#if defined(MSG_STORAGE_ENABLED) || defined(CALL_LOGS_STORAGE_ENABLED) + #ifndef PRIu64 #define PRIu64 "I64u" #endif -#ifndef WIN32 +#ifndef _WIN32 #if !defined(ANDROID) && !defined(__QNXNTO__) # include # include @@ -38,6 +40,63 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define MAX_PATH_SIZE 1024 #include "sqlite3.h" +#include + +int _linphone_sqlite3_open(const char *db_file, sqlite3 **db) { + char* errmsg = NULL; + int ret; +#if defined(ANDROID) || defined(__QNXNTO__) + ret = sqlite3_open(db_file, db); +#elif TARGET_OS_IPHONE + /* the secured filesystem of the iPHone doesn't allow writing while the app is in background mode, which is problematic. + * We workaround by asking that the open is made with no protection*/ + ret = sqlite3_open_v2(db_file, db, SQLITE_OPEN_FILEPROTECTION_NONE|SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, NULL); +#elif defined(_WIN32) + wchar_t db_file_utf16[MAX_PATH_SIZE]; + ret = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, db_file, -1, db_file_utf16, MAX_PATH_SIZE); + if(ret == 0) db_file_utf16[0] = '\0'; + ret = sqlite3_open16(db_file_utf16, db); +#else + char db_file_locale[MAX_PATH_SIZE] = {'\0'}; + char db_file_utf8[MAX_PATH_SIZE] = ""; + char *inbuf=db_file_locale, *outbuf=db_file_utf8; + size_t inbyteleft = MAX_PATH_SIZE, outbyteleft = MAX_PATH_SIZE; + iconv_t cb; + + strncpy(db_file_locale, db_file, MAX_PATH_SIZE-1); + cb = iconv_open("UTF-8", nl_langinfo(CODESET)); + if(cb != (iconv_t)-1) { + int ret; + ret = iconv(cb, &inbuf, &inbyteleft, &outbuf, &outbyteleft); + if(ret == -1) db_file_utf8[0] = '\0'; + iconv_close(cb); + } + ret = sqlite3_open(db_file_utf8, db); +#endif + if (ret != SQLITE_OK) return ret; + // Some platforms do not provide a way to create temporary files which are needed + // for transactions... so we work in memory only + // see http ://www.sqlite.org/compile.html#temp_store + ret = sqlite3_exec(*db, "PRAGMA temp_store=MEMORY", NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + ms_error("Cannot set sqlite3 temporary store to memory: %s.", errmsg); + sqlite3_free(errmsg); + } +#if TARGET_OS_IPHONE + ret = sqlite3_exec(*db, "PRAGMA journal_mode = OFF", NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + ms_error("Cannot set sqlite3 journal_mode to off: %s.", errmsg); + sqlite3_free(errmsg); + } +#endif + return ret; +} +#endif + + + +#ifdef MSG_STORAGE_ENABLED + static ORTP_INLINE LinphoneChatMessage* get_transient_message(LinphoneChatRoom* cr, unsigned int storage_id){ MSList* transients = cr->transient_messages; @@ -93,6 +152,20 @@ static void fetch_content_from_database(sqlite3 *db, LinphoneChatMessage *messag sqlite3_free(buf); } + + +// Called when fetching all conversations from database +static int callback_all(void *data, int argc, char **argv, char **colName){ + LinphoneCore* lc = (LinphoneCore*) data; + char* address = argv[0]; + LinphoneAddress *addr = linphone_address_new(address); + if (addr){ + linphone_core_get_chat_room(lc, addr); + linphone_address_destroy(addr); + } + return 0; +} + /* DB layout: * | 0 | storage_id * | 1 | localContact @@ -105,47 +178,35 @@ static void fetch_content_from_database(sqlite3 *db, LinphoneChatMessage *messag * | 8 | external body url * | 9 | utc timestamp * | 10 | app data text - * | 11 | linphone content + * | 11 | linphone content id */ -static void create_chat_message(char **argv, void *data){ +static int create_chat_message(void *data, int argc, char **argv, char **colName){ LinphoneChatRoom *cr = (LinphoneChatRoom *)data; - LinphoneAddress *from; - LinphoneAddress *to; - unsigned int storage_id = atoi(argv[0]); // check if the message exists in the transient list, in which case we should return that one. LinphoneChatMessage* new_message = get_transient_message(cr, storage_id); if( new_message == NULL ){ + LinphoneAddress *local_addr=linphone_address_new(argv[1]); new_message = linphone_chat_room_create_message(cr, argv[4]); if(atoi(argv[3])==LinphoneChatMessageIncoming){ new_message->dir=LinphoneChatMessageIncoming; - from=linphone_address_new(argv[2]); - to=linphone_address_new(argv[1]); + linphone_chat_message_set_from(new_message,linphone_chat_room_get_peer_address(cr)); + linphone_chat_message_set_to(new_message,local_addr); } else { new_message->dir=LinphoneChatMessageOutgoing; - from=linphone_address_new(argv[1]); - to=linphone_address_new(argv[2]); - } - linphone_chat_message_set_from(new_message,from); - linphone_address_destroy(from); - if (to){ - linphone_chat_message_set_to(new_message,to); - linphone_address_destroy(to); - } - - if( argv[9] != NULL ){ - new_message->time = (time_t)atol(argv[9]); - } else { - new_message->time = time(NULL); + linphone_chat_message_set_from(new_message,local_addr); + linphone_chat_message_set_to(new_message,linphone_chat_room_get_peer_address(cr)); } + linphone_address_destroy(local_addr); + new_message->time = (time_t)atol(argv[9]); new_message->is_read=atoi(argv[6]); new_message->state=atoi(argv[7]); new_message->storage_id=storage_id; - new_message->external_body_url= argv[8] ? ms_strdup(argv[8]) : NULL; - new_message->appdata = argv[10]? ms_strdup(argv[10]) : NULL; + new_message->external_body_url= ms_strdup(argv[8]); + new_message->appdata = ms_strdup(argv[10]); if (argv[11] != NULL) { int id = atoi(argv[11]); @@ -155,25 +216,14 @@ static void create_chat_message(char **argv, void *data){ } } cr->messages_hist=ms_list_prepend(cr->messages_hist,new_message); -} -// Called when fetching all conversations from database -static int callback_all(void *data, int argc, char **argv, char **colName){ - LinphoneCore* lc = (LinphoneCore*) data; - char* address = argv[0]; - linphone_core_get_or_create_chat_room(lc, address); - return 0; -} - -static int callback(void *data, int argc, char **argv, char **colName){ - create_chat_message(argv,data); return 0; } void linphone_sql_request_message(sqlite3 *db,const char *stmt,LinphoneChatRoom *cr){ char* errmsg=NULL; int ret; - ret=sqlite3_exec(db,stmt,callback,cr,&errmsg); + ret=sqlite3_exec(db,stmt,create_chat_message,cr,&errmsg); if(ret != SQLITE_OK) { ms_error("Error in creation: %s.", errmsg); sqlite3_free(errmsg); @@ -287,12 +337,17 @@ void linphone_chat_room_mark_as_read(LinphoneChatRoom *cr){ if (lc->db==NULL) return ; + // optimization: do not modify the database if no message is marked as unread + if(linphone_chat_room_get_unread_messages_count(cr) == 0) return; + peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr)); buf=sqlite3_mprintf("UPDATE history SET read=%i WHERE remoteContact = %Q;", read,peer); linphone_sql_request(lc->db,buf); sqlite3_free(buf); ms_free(peer); + + cr->unread_count = 0; } void linphone_chat_room_update_url(LinphoneChatRoom *cr, LinphoneChatMessage *msg) { @@ -316,6 +371,9 @@ static int linphone_chat_room_get_messages_count(LinphoneChatRoom *cr, bool_t un if (lc->db==NULL) return 0; + // optimization: do not read database if the count is already available in memory + if(unread_only && cr->unread_count >= 0) return cr->unread_count; + peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr)); buf=sqlite3_mprintf("SELECT count(*) FROM history WHERE remoteContact = %Q %s;",peer,unread_only?"AND read = 0":""); returnValue = sqlite3_prepare_v2(lc->db,buf,-1,&selectStatement,NULL); @@ -327,6 +385,11 @@ static int linphone_chat_room_get_messages_count(LinphoneChatRoom *cr, bool_t un sqlite3_finalize(selectStatement); sqlite3_free(buf); ms_free(peer); + + /* no need to test the sign of cr->unread_count here + * because it has been tested above */ + if(unread_only) cr->unread_count = numrows; + return numrows; } @@ -347,6 +410,10 @@ void linphone_chat_room_delete_message(LinphoneChatRoom *cr, LinphoneChatMessage buf=sqlite3_mprintf("DELETE FROM history WHERE id = %i;", msg->storage_id); linphone_sql_request(lc->db,buf); sqlite3_free(buf); + + /* Invalidate unread_count when we modify the database, so that next + time we need it it will be recomputed from latest database state */ + cr->unread_count = -1; } void linphone_chat_room_delete_history(LinphoneChatRoom *cr){ @@ -361,6 +428,8 @@ void linphone_chat_room_delete_history(LinphoneChatRoom *cr){ linphone_sql_request(lc->db,buf); sqlite3_free(buf); ms_free(peer); + + if(cr->unread_count > 0) cr->unread_count = 0; } MSList *linphone_chat_room_get_history_range(LinphoneChatRoom *cr, int startm, int endm){ @@ -415,11 +484,6 @@ MSList *linphone_chat_room_get_history(LinphoneChatRoom *cr,int nb_message){ return linphone_chat_room_get_history_range(cr, 0, nb_message-1); } - -void linphone_close_storage(sqlite3* db){ - sqlite3_close(db); -} - void linphone_create_table(sqlite3* db){ char* errmsg=NULL; int ret; @@ -591,34 +655,6 @@ void linphone_core_message_storage_set_debug(LinphoneCore *lc, bool_t debug){ } } -static int _linphone_sqlite3_open(const char *db_file, sqlite3 **db) { -#if defined(ANDROID) || defined(__QNXNTO__) - return sqlite3_open(db_file, db); -#elif defined(WIN32) - int ret; - wchar_t db_file_utf16[MAX_PATH_SIZE]; - ret = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, db_file, MAX_PATH_SIZE, db_file_utf16, MAX_PATH_SIZE); - if(ret == 0) db_file_utf16[0] = '\0'; - return sqlite3_open16(db_file_utf16, db); -#else - char db_file_locale[MAX_PATH_SIZE] = {'\0'}; - char db_file_utf8[MAX_PATH_SIZE] = ""; - char *inbuf=db_file_locale, *outbuf=db_file_utf8; - size_t inbyteleft = MAX_PATH_SIZE, outbyteleft = MAX_PATH_SIZE; - iconv_t cb; - - strncpy(db_file_locale, db_file, MAX_PATH_SIZE-1); - cb = iconv_open("UTF-8", nl_langinfo(CODESET)); - if(cb != (iconv_t)-1) { - int ret; - ret = iconv(cb, &inbuf, &inbyteleft, &outbuf, &outbyteleft); - if(ret == -1) db_file_utf8[0] = '\0'; - iconv_close(cb); - } - return sqlite3_open(db_file_utf8, db); -#endif -} - void linphone_core_message_storage_init(LinphoneCore *lc){ int ret; const char *errmsg; diff --git a/coreapi/misc.c b/coreapi/misc.c index 83a732365..e3a7f3daa 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -62,7 +62,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. static void clear_ice_check_list(LinphoneCall *call, IceCheckList *removed); bool_t linphone_core_payload_type_enabled(LinphoneCore *lc, const LinphonePayloadType *pt){ - if (ms_list_find(lc->codecs_conf.audio_codecs, (PayloadType*) pt) || ms_list_find(lc->codecs_conf.video_codecs, (PayloadType*)pt)){ + if (ms_list_find(lc->codecs_conf.audio_codecs, (PayloadType*) pt) || ms_list_find(lc->codecs_conf.video_codecs, (PayloadType*)pt) || ms_list_find(lc->codecs_conf.text_codecs, (PayloadType*)pt)){ return payload_type_enabled(pt); } ms_error("Getting enablement status of codec not in audio or video list of PayloadType !"); @@ -75,7 +75,7 @@ bool_t linphone_core_payload_type_is_vbr(LinphoneCore *lc, const LinphonePayload } int linphone_core_enable_payload_type(LinphoneCore *lc, LinphonePayloadType *pt, bool_t enabled){ - if (ms_list_find(lc->codecs_conf.audio_codecs,pt) || ms_list_find(lc->codecs_conf.video_codecs,pt)){ + if (ms_list_find(lc->codecs_conf.audio_codecs,pt) || ms_list_find(lc->codecs_conf.video_codecs,pt) || ms_list_find(lc->codecs_conf.text_codecs,pt)){ payload_type_set_enable(pt,enabled); _linphone_core_codec_config_write(lc); linphone_core_update_allocated_audio_bandwidth(lc); @@ -106,7 +106,7 @@ const char *linphone_core_get_payload_type_description(LinphoneCore *lc, Payload } void linphone_core_set_payload_type_bitrate(LinphoneCore *lc, LinphonePayloadType *pt, int bitrate){ - if (ms_list_find(lc->codecs_conf.audio_codecs, (PayloadType*) pt) || ms_list_find(lc->codecs_conf.video_codecs, (PayloadType*)pt)){ + if (ms_list_find(lc->codecs_conf.audio_codecs, (PayloadType*) pt) || ms_list_find(lc->codecs_conf.video_codecs, (PayloadType*)pt) || ms_list_find(lc->codecs_conf.text_codecs, (PayloadType*)pt)){ if (pt->type==PAYLOAD_VIDEO || pt->flags & PAYLOAD_TYPE_IS_VBR){ pt->normal_bitrate=bitrate*1000; pt->flags|=PAYLOAD_TYPE_BITRATE_OVERRIDE; @@ -224,33 +224,38 @@ void linphone_core_update_allocated_audio_bandwidth(LinphoneCore *lc){ } } -bool_t linphone_core_is_payload_type_usable_for_bandwidth(LinphoneCore *lc, const PayloadType *pt, int bandwidth_limit) -{ +bool_t linphone_core_is_payload_type_usable_for_bandwidth(LinphoneCore *lc, const PayloadType *pt, int bandwidth_limit){ double codec_band; + const int video_enablement_limit = 99; bool_t ret=FALSE; switch (pt->type){ case PAYLOAD_AUDIO_CONTINUOUS: case PAYLOAD_AUDIO_PACKETIZED: codec_band=get_audio_payload_bandwidth(lc,pt,bandwidth_limit); - ret=bandwidth_is_greater(bandwidth_limit*1000,codec_band); - //ms_message("Payload %s: %g",pt->mime_type,codec_band); + ret=bandwidth_is_greater(bandwidth_limit,(int)codec_band); + /*ms_message("Payload %s: codec_bandwidth=%g, bandwidth_limit=%i",pt->mime_type,codec_band,bandwidth_limit);*/ break; case PAYLOAD_VIDEO: - if (bandwidth_limit!=0) {/* infinite (-1) or strictly positive*/ + if (bandwidth_limit<=0 || bandwidth_limit >= video_enablement_limit) {/* infinite or greater than video_enablement_limit*/ ret=TRUE; } else ret=FALSE; break; + case PAYLOAD_TEXT: + ret=TRUE; + break; } return ret; } /* return TRUE if codec can be used with bandwidth, FALSE else*/ bool_t linphone_core_check_payload_type_usability(LinphoneCore *lc, const PayloadType *pt){ - bool_t ret=linphone_core_is_payload_type_usable_for_bandwidth(lc, pt, linphone_core_get_payload_type_bitrate(lc,pt)); + int maxbw=get_min_bandwidth(linphone_core_get_download_bandwidth(lc), + linphone_core_get_upload_bandwidth(lc)); + bool_t ret=linphone_core_is_payload_type_usable_for_bandwidth(lc, pt, maxbw); if ((pt->type==PAYLOAD_AUDIO_CONTINUOUS || pt->type==PAYLOAD_AUDIO_PACKETIZED) - && lc->sound_conf.capt_sndcard + && lc->sound_conf.capt_sndcard && !(ms_snd_card_get_capabilities(lc->sound_conf.capt_sndcard) & MS_SND_CARD_CAP_BUILTIN_ECHO_CANCELLER) && linphone_core_echo_cancellation_enabled(lc) && (pt->clock_rate!=16000 && pt->clock_rate!=8000) @@ -264,7 +269,7 @@ bool_t linphone_core_check_payload_type_usability(LinphoneCore *lc, const Payloa } bool_t lp_spawn_command_line_sync(const char *command, char **result,int *command_ret){ -#if !defined(_WIN32_WCE) +#if !defined(_WIN32_WCE) && !defined(LINPHONE_WINDOWS_UNIVERSAL) FILE *f=popen(command,"r"); if (f!=NULL){ int err; @@ -376,7 +381,7 @@ int parse_hostname_to_addr(const char *server, struct sockaddr_storage *ss, sock } if (!res) return -1; memcpy(ss,res->ai_addr,res->ai_addrlen); - *socklen=res->ai_addrlen; + *socklen=(socklen_t)res->ai_addrlen; freeaddrinfo(res); return 0; } @@ -407,22 +412,23 @@ int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){ const char *server=linphone_core_get_stun_server(lc); StunCandidate *ac=&call->ac; StunCandidate *vc=&call->vc; + StunCandidate *tc=&call->tc; if (lc->sip_conf.ipv6_enabled){ ms_warning("stun support is not implemented for ipv6"); return -1; } - if (call->media_ports[0].rtp_port==-1){ + if (call->media_ports[call->main_audio_stream_index].rtp_port==-1){ ms_warning("Stun-only support not available for system random port"); return -1; } if (server!=NULL){ const struct addrinfo *ai=linphone_core_get_stun_server_addrinfo(lc); - ortp_socket_t sock1=-1, sock2=-1; + ortp_socket_t sock1=-1, sock2=-1, sock3=-1; int loops=0; bool_t video_enabled=linphone_core_video_enabled(lc); - bool_t got_audio,got_video; - bool_t cone_audio=FALSE,cone_video=FALSE; + bool_t got_audio,got_video,got_text; + bool_t cone_audio=FALSE,cone_video=FALSE,cone_text=FALSE; struct timeval init,cur; double elapsed; int ret=0; @@ -434,25 +440,33 @@ int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){ linphone_core_notify_display_status(lc,_("Stun lookup in progress...")); /*create the two audio and video RTP sockets, and send STUN message to our stun server */ - sock1=create_socket(call->media_ports[0].rtp_port); + sock1=create_socket(call->media_ports[call->main_audio_stream_index].rtp_port); if (sock1==-1) return -1; if (video_enabled){ - sock2=create_socket(call->media_ports[1].rtp_port); + sock2=create_socket(call->media_ports[call->main_video_stream_index].rtp_port); if (sock2==-1) return -1; } + sock3=create_socket(call->media_ports[call->main_text_stream_index].rtp_port); + if (sock3==-1) return -1; + got_audio=FALSE; got_video=FALSE; + got_text=FALSE; ortp_gettimeofday(&init,NULL); do{ int id; if (loops%20==0){ ms_message("Sending stun requests..."); - sendStunRequest(sock1,ai->ai_addr,ai->ai_addrlen,11,TRUE); - sendStunRequest(sock1,ai->ai_addr,ai->ai_addrlen,1,FALSE); + sendStunRequest((int)sock1,ai->ai_addr,(socklen_t)ai->ai_addrlen,11,TRUE); + sendStunRequest((int)sock1,ai->ai_addr,(socklen_t)ai->ai_addrlen,1,FALSE); if (sock2!=-1){ - sendStunRequest(sock2,ai->ai_addr,ai->ai_addrlen,22,TRUE); - sendStunRequest(sock2,ai->ai_addr,ai->ai_addrlen,2,FALSE); + sendStunRequest((int)sock2,ai->ai_addr,(socklen_t)ai->ai_addrlen,22,TRUE); + sendStunRequest((int)sock2,ai->ai_addr,(socklen_t)ai->ai_addrlen,2,FALSE); + } + if (sock3!=-1){ + sendStunRequest((int)sock3,ai->ai_addr,(socklen_t)ai->ai_addrlen,33,TRUE); + sendStunRequest((int)sock3,ai->ai_addr,(socklen_t)ai->ai_addrlen,3,FALSE); } } ms_usleep(10000); @@ -475,6 +489,15 @@ int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){ cone_video=TRUE; got_video=TRUE; } + if (recvStunResponse(sock3,tc->addr, + &tc->port,&id)>0){ + ms_message("STUN test result: local text port maps to %s:%i", + tc->addr, + tc->port); + if (id==33) + cone_text=TRUE; + got_text=TRUE; + } ortp_gettimeofday(&cur,NULL); elapsed=((cur.tv_sec-init.tv_sec)*1000.0) + ((cur.tv_usec-init.tv_usec)/1000.0); if (elapsed>2000) { @@ -483,7 +506,7 @@ int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){ break; } loops++; - }while(!(got_audio && (got_video||sock2==-1) ) ); + }while(!(got_audio && (got_video||sock2==-1) && (got_text||sock3==-1) ) ); if (ret==0) ret=(int)elapsed; if (!got_audio){ ms_error("No stun server response for audio port."); @@ -501,8 +524,18 @@ int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){ } } } + if (sock3!=-1){ + if (!got_text){ + ms_error("No stun server response for text port."); + }else{ + if (!cone_text) { + ms_message("NAT is symmetric for text port."); + } + } + } close_socket(sock1); if (sock2!=-1) close_socket(sock2); + if (sock3!=-1) close_socket(sock3); return ret; } return -1; @@ -596,11 +629,13 @@ int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call) const struct addrinfo *ai; IceCheckList *audio_check_list; IceCheckList *video_check_list; + IceCheckList *text_check_list; const char *server = linphone_core_get_stun_server(lc); if ((server == NULL) || (call->ice_session == NULL)) return -1; - audio_check_list = ice_session_check_list(call->ice_session, 0); - video_check_list = ice_session_check_list(call->ice_session, 1); + audio_check_list = ice_session_check_list(call->ice_session, call->main_audio_stream_index); + video_check_list = ice_session_check_list(call->ice_session, call->main_video_stream_index); + text_check_list = ice_session_check_list(call->ice_session, call->main_text_stream_index); if (audio_check_list == NULL) return -1; if (call->af==AF_INET6){ @@ -620,20 +655,26 @@ int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call) return -1; } if ((ice_check_list_state(audio_check_list) != ICL_Completed) && (ice_check_list_candidates_gathered(audio_check_list) == FALSE)) { - ice_add_local_candidate(audio_check_list, "host", local_addr, call->media_ports[0].rtp_port, 1, NULL); - ice_add_local_candidate(audio_check_list, "host", local_addr, call->media_ports[0].rtcp_port, 2, NULL); + ice_add_local_candidate(audio_check_list, "host", local_addr, call->media_ports[call->main_audio_stream_index].rtp_port, 1, NULL); + ice_add_local_candidate(audio_check_list, "host", local_addr, call->media_ports[call->main_audio_stream_index].rtcp_port, 2, NULL); call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateInProgress; } if (linphone_core_video_enabled(lc) && (video_check_list != NULL) && (ice_check_list_state(video_check_list) != ICL_Completed) && (ice_check_list_candidates_gathered(video_check_list) == FALSE)) { - ice_add_local_candidate(video_check_list, "host", local_addr, call->media_ports[1].rtp_port, 1, NULL); - ice_add_local_candidate(video_check_list, "host", local_addr, call->media_ports[1].rtcp_port, 2, NULL); + ice_add_local_candidate(video_check_list, "host", local_addr, call->media_ports[call->main_video_stream_index].rtp_port, 1, NULL); + ice_add_local_candidate(video_check_list, "host", local_addr, call->media_ports[call->main_video_stream_index].rtcp_port, 2, NULL); call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateInProgress; } + if (call->params->realtimetext_enabled && (text_check_list != NULL) + && (ice_check_list_state(text_check_list) != ICL_Completed) && (ice_check_list_candidates_gathered(text_check_list) == FALSE)) { + ice_add_local_candidate(text_check_list, "host", local_addr, call->media_ports[call->main_text_stream_index].rtp_port, 1, NULL); + ice_add_local_candidate(text_check_list, "host", local_addr, call->media_ports[call->main_text_stream_index].rtcp_port, 2, NULL); + call->stats[LINPHONE_CALL_STATS_TEXT].ice_state = LinphoneIceStateInProgress; + } ms_message("ICE: gathering candidate from [%s]",server); /* Gather local srflx candidates. */ - ice_session_gather_candidates(call->ice_session, ai->ai_addr, ai->ai_addrlen); + ice_session_gather_candidates(call->ice_session, ai->ai_addr, (socklen_t)ai->ai_addrlen); return 0; } @@ -659,31 +700,36 @@ void linphone_core_update_ice_state_in_call_stats(LinphoneCall *call) { IceCheckList *audio_check_list; IceCheckList *video_check_list; + IceCheckList *text_check_list; IceSessionState session_state; if (call->ice_session == NULL) return; - audio_check_list = ice_session_check_list(call->ice_session, 0); - video_check_list = ice_session_check_list(call->ice_session, 1); + audio_check_list = ice_session_check_list(call->ice_session, call->main_audio_stream_index); + video_check_list = ice_session_check_list(call->ice_session, call->main_video_stream_index); + text_check_list = ice_session_check_list(call->ice_session, call->main_text_stream_index); if (audio_check_list == NULL) return; session_state = ice_session_state(call->ice_session); if ((session_state == IS_Completed) || ((session_state == IS_Failed) && (ice_session_has_completed_check_list(call->ice_session) == TRUE))) { - if (ice_check_list_state(audio_check_list) == ICL_Completed) { - switch (ice_check_list_selected_valid_candidate_type(audio_check_list)) { - case ICT_HostCandidate: - call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateHostConnection; - break; - case ICT_ServerReflexiveCandidate: - case ICT_PeerReflexiveCandidate: - call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateReflexiveConnection; - break; - case ICT_RelayedCandidate: - call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateRelayConnection; - break; + if (call->params->has_audio && (audio_check_list != NULL)) { + if (ice_check_list_state(audio_check_list) == ICL_Completed) { + switch (ice_check_list_selected_valid_candidate_type(audio_check_list)) { + case ICT_HostCandidate: + call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateHostConnection; + break; + case ICT_ServerReflexiveCandidate: + case ICT_PeerReflexiveCandidate: + call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateReflexiveConnection; + break; + case ICT_RelayedCandidate: + call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateRelayConnection; + break; + } + } else { + call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateFailed; } - } else { - call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateFailed; - } + }else call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateNotActivated; + if (call->params->has_video && (video_check_list != NULL)) { if (ice_check_list_state(video_check_list) == ICL_Completed) { switch (ice_check_list_selected_valid_candidate_type(video_check_list)) { @@ -702,30 +748,54 @@ void linphone_core_update_ice_state_in_call_stats(LinphoneCall *call) call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateFailed; } }else call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateNotActivated; + + if (call->params->realtimetext_enabled && (text_check_list != NULL)) { + if (ice_check_list_state(text_check_list) == ICL_Completed) { + switch (ice_check_list_selected_valid_candidate_type(text_check_list)) { + case ICT_HostCandidate: + call->stats[LINPHONE_CALL_STATS_TEXT].ice_state = LinphoneIceStateHostConnection; + break; + case ICT_ServerReflexiveCandidate: + case ICT_PeerReflexiveCandidate: + call->stats[LINPHONE_CALL_STATS_TEXT].ice_state = LinphoneIceStateReflexiveConnection; + break; + case ICT_RelayedCandidate: + call->stats[LINPHONE_CALL_STATS_TEXT].ice_state = LinphoneIceStateRelayConnection; + break; + } + } else { + call->stats[LINPHONE_CALL_STATS_TEXT].ice_state = LinphoneIceStateFailed; + } + }else call->stats[LINPHONE_CALL_STATS_TEXT].ice_state = LinphoneIceStateNotActivated; } else if (session_state == IS_Running) { call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateInProgress; if (call->params->has_video && (video_check_list != NULL)) { call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateInProgress; } + if (call->params->realtimetext_enabled && (text_check_list != NULL)) { + call->stats[LINPHONE_CALL_STATS_TEXT].ice_state = LinphoneIceStateInProgress; + } } else { call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateFailed; if (call->params->has_video && (video_check_list != NULL)) { call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateFailed; } + if (call->params->realtimetext_enabled && (text_check_list != NULL)) { + call->stats[LINPHONE_CALL_STATS_TEXT].ice_state = LinphoneIceStateFailed; + } } - ms_message("Call [%p] New ICE state: audio: [%s] video: [%s]", call, - linphone_ice_state_to_string(call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state), linphone_ice_state_to_string(call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state)); + ms_message("Call [%p] New ICE state: audio: [%s] video: [%s] text: [%s]", call, + linphone_ice_state_to_string(call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state), linphone_ice_state_to_string(call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state), linphone_ice_state_to_string(call->stats[LINPHONE_CALL_STATS_TEXT].ice_state)); } -void linphone_call_stop_ice_for_inactive_streams(LinphoneCall *call) { +void linphone_call_stop_ice_for_inactive_streams(LinphoneCall *call, SalMediaDescription *desc) { int i; IceSession *session = call->ice_session; - SalMediaDescription *desc = call->localdesc; - + if (session == NULL) return; if (ice_session_state(session) == IS_Completed) return; - for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) { + for (i = 0; i < desc->nb_streams; i++) { IceCheckList *cl = ice_session_check_list(session, i); if (!sal_stream_description_active(&desc->streams[i]) && cl) { ice_session_remove_check_list(session, cl); @@ -854,19 +924,44 @@ static void clear_ice_check_list(LinphoneCall *call, IceCheckList *removed){ call->audiostream->ms.ice_check_list=NULL; if (call->videostream && call->videostream->ms.ice_check_list==removed) call->videostream->ms.ice_check_list=NULL; + if (call->textstream && call->textstream->ms.ice_check_list==removed) + call->textstream->ms.ice_check_list=NULL; +} + +void linphone_call_clear_unused_ice_candidates(LinphoneCall *call, const SalMediaDescription *md){ + int i; + + if (!call->localdesc) return; + for (i = 0; i < md->nb_streams; i++) { + const SalStreamDescription *local_stream = &call->localdesc->streams[i]; + const SalStreamDescription *stream = &md->streams[i]; + IceCheckList *cl = ice_session_check_list(call->ice_session, i); + if (!cl || !local_stream) continue; + + if (stream->rtcp_mux && local_stream->rtcp_mux){ + ice_check_list_remove_rtcp_candidates(cl); + } + } } void linphone_call_update_ice_from_remote_media_description(LinphoneCall *call, const SalMediaDescription *md) { + const SalStreamDescription *stream; + IceCheckList *cl = NULL; + bool_t default_candidate = FALSE; + const char *addr = NULL; + int port = 0; + int componentID = 0; bool_t ice_restarted = FALSE; bool_t ice_params_found=FALSE; + int i, j; + if ((md->ice_pwd[0] != '\0') && (md->ice_ufrag[0] != '\0')) { ice_params_found=TRUE; } else { - int i; for (i = 0; i < md->nb_streams; i++) { - const SalStreamDescription *stream = &md->streams[i]; - IceCheckList *cl = ice_session_check_list(call->ice_session, i); + stream = &md->streams[i]; + cl = ice_session_check_list(call->ice_session, i); if (cl) { if ((stream->ice_pwd[0] != '\0') && (stream->ice_ufrag[0] != '\0')) { ice_params_found=TRUE; @@ -878,16 +973,14 @@ void linphone_call_update_ice_from_remote_media_description(LinphoneCall *call, } } if (ice_params_found) { - int i, j; - /* Check for ICE restart and set remote credentials. */ if ((strcmp(md->addr, "0.0.0.0") == 0) || (strcmp(md->addr, "::0") == 0)) { ice_session_restart(call->ice_session); ice_restarted = TRUE; } else { for (i = 0; i < md->nb_streams; i++) { - const SalStreamDescription *stream = &md->streams[i]; - IceCheckList *cl = ice_session_check_list(call->ice_session, i); + stream = &md->streams[i]; + cl = ice_session_check_list(call->ice_session, i); if (cl && (strcmp(stream->rtp_addr, "0.0.0.0") == 0)) { ice_session_restart(call->ice_session); ice_restarted = TRUE; @@ -905,8 +998,8 @@ void linphone_call_update_ice_from_remote_media_description(LinphoneCall *call, ice_session_set_remote_credentials(call->ice_session, md->ice_ufrag, md->ice_pwd); } for (i = 0; i < md->nb_streams; i++) { - const SalStreamDescription *stream = &md->streams[i]; - IceCheckList *cl = ice_session_check_list(call->ice_session, i); + stream = &md->streams[i]; + cl = ice_session_check_list(call->ice_session, i); if (cl && (stream->ice_pwd[0] != '\0') && (stream->ice_ufrag[0] != '\0')) { if (ice_check_list_remote_credentials_changed(cl, stream->ice_ufrag, stream->ice_pwd)) { if (ice_restarted == FALSE @@ -924,24 +1017,9 @@ void linphone_call_update_ice_from_remote_media_description(LinphoneCall *call, /* Create ICE check lists if needed and parse ICE attributes. */ for (i = 0; i < md->nb_streams; i++) { - const SalStreamDescription *stream = &md->streams[i]; - IceCheckList *cl = ice_session_check_list(call->ice_session, i); - /* - if ((cl == NULL) && (i < md->n_active_streams)) { - cl = ice_check_list_new(); - ice_session_add_check_list(call->ice_session, cl); - switch (stream->type) { - case SalAudio: - if (call->audiostream != NULL) call->audiostream->ms.ice_check_list = cl; - break; - case SalVideo: - if (call->videostream != NULL) call->videostream->ms.ice_check_list = cl; - break; - default: - break; - } - } - */ + stream = &md->streams[i]; + cl = ice_session_check_list(call->ice_session, i); + if (cl==NULL) continue; if (stream->ice_mismatch == TRUE) { ice_check_list_set_state(cl, ICL_Failed); @@ -953,9 +1031,9 @@ void linphone_call_update_ice_from_remote_media_description(LinphoneCall *call, ice_check_list_set_remote_credentials(cl, stream->ice_ufrag, stream->ice_pwd); for (j = 0; j < SAL_MEDIA_DESCRIPTION_MAX_ICE_CANDIDATES; j++) { const SalIceCandidate *candidate = &stream->ice_candidates[j]; - bool_t default_candidate = FALSE; - const char *addr = NULL; - int port = 0; + default_candidate = FALSE; + addr = NULL; + port = 0; if (candidate->addr[0] == '\0') break; if ((candidate->componentID == 0) || (candidate->componentID > 2)) continue; get_default_addr_and_port(candidate->componentID, md, stream, &addr, &port); @@ -966,18 +1044,18 @@ void linphone_call_update_ice_from_remote_media_description(LinphoneCall *call, } if (ice_restarted == FALSE) { bool_t losing_pairs_added = FALSE; - for (j = 0; j < SAL_MEDIA_DESCRIPTION_MAX_ICE_REMOTE_CANDIDATES; j++) { - const SalIceRemoteCandidate *candidate = &stream->ice_remote_candidates[j]; - const char *addr = NULL; - int port = 0; - int componentID = j + 1; - if (candidate->addr[0] == '\0') break; + for (j = 0; j < SAL_MEDIA_DESCRIPTION_MAX_ICE_CANDIDATES; j++) { + const SalIceRemoteCandidate *remote_candidate = &stream->ice_remote_candidates[j]; + addr = NULL; + port = 0; + componentID = j + 1; + if (remote_candidate->addr[0] == '\0') break; get_default_addr_and_port(componentID, md, stream, &addr, &port); if (j == 0) { /* If we receive a re-invite and we finished ICE processing on our side, use the candidates given by the remote. */ ice_check_list_unselect_valid_pairs(cl); } - ice_add_losing_pair(cl, j + 1, candidate->addr, candidate->port, addr, port); + ice_add_losing_pair(cl, j + 1, remote_candidate->addr, remote_candidate->port, addr, port); losing_pairs_added = TRUE; } if (losing_pairs_added == TRUE) ice_check_list_check_completed(cl); @@ -985,12 +1063,16 @@ void linphone_call_update_ice_from_remote_media_description(LinphoneCall *call, } } for (i = 0; i < md->nb_streams; i++) { - IceCheckList * cl = ice_session_check_list(call->ice_session, i); - if (!sal_stream_description_active(&md->streams[i]) && (cl != NULL)) { + stream = &md->streams[i]; + cl = ice_session_check_list(call->ice_session, i); + if (!cl) continue; + + if (!sal_stream_description_active(stream)) { ice_session_remove_check_list_from_idx(call->ice_session, i); clear_ice_check_list(call, cl); } } + linphone_call_clear_unused_ice_candidates(call, md); ice_session_check_mismatch(call->ice_session); } else { /* Response from remote does not contain mandatory ICE attributes, delete the session. */ @@ -1125,7 +1207,7 @@ static int get_local_ip_for_with_connect(int type, const char *dest, char *resul if (err<0){ ms_warning("Error in setsockopt: %s",strerror(errno)); } - err=connect(sock,res->ai_addr,res->ai_addrlen); + err=connect(sock,res->ai_addr,(int)res->ai_addrlen); if (err<0) { /*the network isn't reachable*/ if (getSocketErrorCode()!=ENETUNREACH) ms_error("Error in connect: %s",strerror(errno)); @@ -1272,6 +1354,7 @@ LinphoneReason linphone_reason_from_sal(SalReason r){ ret=LinphoneReasonIOError; break; case SalReasonUnknown: + case SalReasonInternalError: ret=LinphoneReasonUnknown; break; case SalReasonBusy: @@ -1302,7 +1385,7 @@ LinphoneReason linphone_reason_from_sal(SalReason r){ ret=LinphoneReasonIOError; break; case SalReasonRequestPending: - ret=LinphoneReasonNone; + ret=LinphoneReasonTemporarilyUnavailable; /*might not be exactly the perfect matching, but better than LinphoneReasonNone*/ break; case SalReasonUnauthorized: ret=LinphoneReasonUnauthorized; @@ -1625,8 +1708,8 @@ MsZrtpCryptoTypesCount linphone_core_get_zrtp_key_agreement_suites(LinphoneCore if (zrtpConfig == NULL) { return 0; } - - origPtr = strdup(zrtpConfig); + + origPtr = ms_strdup(zrtpConfig); zrtpConfig = origPtr; while ((entry = seperate_string_list(&zrtpConfig))) { const MSZrtpKeyAgreement agreement = ms_zrtp_key_agreement_from_string(entry); @@ -1636,7 +1719,7 @@ MsZrtpCryptoTypesCount linphone_core_get_zrtp_key_agreement_suites(LinphoneCore } } - free(origPtr); + ms_free(origPtr); return key_agreements_count; } @@ -1647,8 +1730,8 @@ MsZrtpCryptoTypesCount linphone_core_get_zrtp_cipher_suites(LinphoneCore *lc, MS if (zrtpConfig == NULL) { return 0; } - - origPtr = strdup(zrtpConfig); + + origPtr = ms_strdup(zrtpConfig); zrtpConfig = origPtr; while ((entry = seperate_string_list(&zrtpConfig))) { const MSZrtpCipher cipher = ms_zrtp_cipher_from_string(entry); @@ -1658,7 +1741,7 @@ MsZrtpCryptoTypesCount linphone_core_get_zrtp_cipher_suites(LinphoneCore *lc, MS } } - free(origPtr); + ms_free(origPtr); return cipher_count; } @@ -1670,7 +1753,7 @@ MsZrtpCryptoTypesCount linphone_core_get_zrtp_hash_suites(LinphoneCore *lc, MSZr return 0; } - origPtr = strdup(zrtpConfig); + origPtr = ms_strdup(zrtpConfig); zrtpConfig = origPtr; while ((entry = seperate_string_list(&zrtpConfig))) { const MSZrtpHash hash = ms_zrtp_hash_from_string(entry); @@ -1680,7 +1763,7 @@ MsZrtpCryptoTypesCount linphone_core_get_zrtp_hash_suites(LinphoneCore *lc, MSZr } } - free(origPtr); + ms_free(origPtr); return hash_count; } @@ -1692,7 +1775,7 @@ MsZrtpCryptoTypesCount linphone_core_get_zrtp_auth_suites(LinphoneCore *lc, MSZr return 0; } - origPtr = strdup(zrtpConfig); + origPtr = ms_strdup(zrtpConfig); zrtpConfig = origPtr; while ((entry = seperate_string_list(&zrtpConfig))) { const MSZrtpAuthTag authTag = ms_zrtp_auth_tag_from_string(entry); @@ -1702,7 +1785,7 @@ MsZrtpCryptoTypesCount linphone_core_get_zrtp_auth_suites(LinphoneCore *lc, MSZr } } - free(origPtr); + ms_free(origPtr); return auth_tag_count; } @@ -1714,7 +1797,7 @@ MsZrtpCryptoTypesCount linphone_core_get_zrtp_sas_suites(LinphoneCore *lc, MSZrt return 0; } - origPtr = strdup(zrtpConfig); + origPtr = ms_strdup(zrtpConfig); zrtpConfig = origPtr; while ((entry = seperate_string_list(&zrtpConfig))) { const MSZrtpSasType type = ms_zrtp_sas_type_from_string(entry); @@ -1724,7 +1807,7 @@ MsZrtpCryptoTypesCount linphone_core_get_zrtp_sas_suites(LinphoneCore *lc, MSZrt } } - free(origPtr); + ms_free(origPtr); return sas_count; } @@ -1785,3 +1868,48 @@ const char *linphone_tunnel_mode_to_string(LinphoneTunnelMode mode) { return "invalid"; } + +typedef struct Hook{ + LinphoneCoreIterateHook fun; + void *data; +}Hook; + +void linphone_task_list_init(LinphoneTaskList *t){ + t->hooks = NULL; +} + +static Hook *hook_new(LinphoneCoreIterateHook hook, void *hook_data){ + Hook *h=ms_new0(Hook,1); + h->fun=hook; + h->data=hook_data; + return h; +} + +static void hook_invoke(Hook *h){ + h->fun(h->data); +} + +void linphone_task_list_add(LinphoneTaskList *t, LinphoneCoreIterateHook hook, void *hook_data){ + t->hooks = ms_list_append(t->hooks,hook_new(hook,hook_data)); +} + +void linphone_task_list_remove(LinphoneTaskList *t, LinphoneCoreIterateHook hook, void *hook_data){ + MSList *elem; + for(elem=t->hooks;elem!=NULL;elem=elem->next){ + Hook *h=(Hook*)elem->data; + if (h->fun==hook && h->data==hook_data){ + t->hooks = ms_list_remove_link(t->hooks,elem); + ms_free(h); + return; + } + } + ms_error("linphone_task_list_remove(): No such hook found."); +} + +void linphone_task_list_run(LinphoneTaskList *t){ + ms_list_for_each(t->hooks,(void (*)(void*))hook_invoke); +} + +void linphone_task_list_free(LinphoneTaskList *t){ + t->hooks = ms_list_free_with_data(t->hooks, (void (*)(void*))ms_free); +} diff --git a/coreapi/offeranswer.c b/coreapi/offeranswer.c index a74105963..0fc099460 100644 --- a/coreapi/offeranswer.c +++ b/coreapi/offeranswer.c @@ -31,17 +31,13 @@ static bool_t only_telephone_event(const MSList *l){ return TRUE; } -typedef struct _PayloadTypeMatcher{ - const char *mime_type; - PayloadType *(*match_func)(const MSList *l, const PayloadType *refpt); -}PayloadTypeMatcher; -static PayloadType * opus_match(const MSList *l, const PayloadType *refpt){ +static PayloadType * opus_match(MSOfferAnswerContext *ctx, const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads, bool_t reading_response){ PayloadType *pt; const MSList *elem; PayloadType *candidate=NULL; - for (elem=l;elem!=NULL;elem=elem->next){ + for (elem=local_payloads;elem!=NULL;elem=elem->next){ pt=(PayloadType*)elem->data; /*workaround a bug in earlier versions of linphone where opus/48000/1 is offered, which is uncompliant with opus rtp draft*/ @@ -50,94 +46,125 @@ static PayloadType * opus_match(const MSList *l, const PayloadType *refpt){ pt->channels=1; /*so that we respond with same number of channels */ candidate=pt; }else if (refpt->channels==2){ - return pt; + return payload_type_clone(pt); } } } - return candidate; + return candidate ? payload_type_clone(candidate) : NULL; } +static MSOfferAnswerContext *opus_offer_answer_create_context(void){ + static MSOfferAnswerContext opus_oa = {opus_match, NULL}; + return &opus_oa; +} + +MSOfferAnswerProvider opus_offer_answer_provider={ + "opus", + opus_offer_answer_create_context +}; + /* the reason for this matcher is for some stupid uncompliant phone that offer G729a mime type !*/ -static PayloadType * g729A_match(const MSList *l, const PayloadType *refpt){ +static PayloadType * g729A_match(MSOfferAnswerContext *ctx, const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads, bool_t reading_response){ PayloadType *pt; const MSList *elem; PayloadType *candidate=NULL; - for (elem=l;elem!=NULL;elem=elem->next){ + for (elem=local_payloads;elem!=NULL;elem=elem->next){ pt=(PayloadType*)elem->data; if (strcasecmp(pt->mime_type,"G729")==0 && refpt->channels==pt->channels){ candidate=pt; } } - return candidate; + return candidate ? payload_type_clone(candidate) : NULL; } -static PayloadType * amr_match(const MSList *l, const PayloadType *refpt){ - PayloadType *pt; - char value[10]; - const MSList *elem; - PayloadType *candidate=NULL; +static MSOfferAnswerContext *g729a_offer_answer_create_context(void){ + static MSOfferAnswerContext g729_oa = {g729A_match, NULL}; + return &g729_oa; +} - for (elem=l;elem!=NULL;elem=elem->next){ - pt=(PayloadType*)elem->data; +MSOfferAnswerProvider g729a_offer_answer_provider={ + "G729A", + g729a_offer_answer_create_context +}; + +static PayloadType * red_match(MSOfferAnswerContext *ctx, const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads, bool_t reading_response) { + const MSList *elem_local, *elem_remote; + PayloadType *red = NULL; + + for (elem_local = local_payloads; elem_local != NULL; elem_local = elem_local->next) { + PayloadType *pt = (PayloadType*)elem_local->data; - if ( pt->mime_type && refpt->mime_type - && strcasecmp(pt->mime_type, refpt->mime_type)==0 - && pt->clock_rate==refpt->clock_rate - && pt->channels==refpt->channels) { - int octedalign1=0,octedalign2=0; - if (pt->recv_fmtp!=NULL && fmtp_get_value(pt->recv_fmtp,"octet-align",value,sizeof(value))){ - octedalign1=atoi(value); - } - if (refpt->send_fmtp!=NULL && fmtp_get_value(refpt->send_fmtp,"octet-align",value,sizeof(value))){ - octedalign2=atoi(value); - } - if (octedalign1==octedalign2) { - candidate=pt; - break; /*exact match */ + if (strcasecmp(pt->mime_type, payload_type_t140_red.mime_type) == 0) { + red = payload_type_clone(pt); + + for (elem_remote = remote_payloads; elem_remote != NULL; elem_remote = elem_remote->next) { + PayloadType *pt2 = (PayloadType*)elem_remote->data; + if (strcasecmp(pt2->mime_type, payload_type_t140.mime_type) == 0) { + int t140_payload_number = payload_type_get_number(pt2); + char *red_fmtp = ms_strdup_printf("%i/%i/%i", t140_payload_number, t140_payload_number, t140_payload_number); + /*modify the local payload and the return value*/ + payload_type_set_recv_fmtp(pt, red_fmtp); + payload_type_set_recv_fmtp(red, red_fmtp); + ms_free(red_fmtp); + break; + } } + break; } } - return candidate; + return red; } -static PayloadType * generic_match(const MSList *l, const PayloadType *refpt){ +static MSOfferAnswerContext *red_offer_answer_create_context(void){ + static MSOfferAnswerContext red_oa = {red_match, NULL}; + return &red_oa; +} + +MSOfferAnswerProvider red_offer_answer_provider={ + "red", + red_offer_answer_create_context +}; + +static PayloadType * generic_match(const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads){ PayloadType *pt; const MSList *elem; - for (elem=l;elem!=NULL;elem=elem->next){ + for (elem=local_payloads;elem!=NULL;elem=elem->next){ pt=(PayloadType*)elem->data; if ( pt->mime_type && refpt->mime_type && strcasecmp(pt->mime_type, refpt->mime_type)==0 && pt->clock_rate==refpt->clock_rate && pt->channels==refpt->channels) - return pt; + return payload_type_clone(pt); } return NULL; } -static PayloadTypeMatcher matchers[]={ - {"opus", opus_match}, - {"G729A", g729A_match}, - {"AMR", amr_match}, - {"AMR-WB", amr_match}, - {NULL, NULL} -}; +void linphone_core_register_offer_answer_providers(LinphoneCore *lc){ + MSFactory *factory = ms_factory_get_fallback(); + ms_factory_register_offer_answer_provider(factory, &red_offer_answer_provider); + ms_factory_register_offer_answer_provider(factory, &g729a_offer_answer_provider); + ms_factory_register_offer_answer_provider(factory, &opus_offer_answer_provider); +} /* * Returns a PayloadType from the local list that matches a PayloadType offered or answered in the remote list */ -static PayloadType * find_payload_type_best_match(const MSList *l, const PayloadType *refpt){ - PayloadTypeMatcher *m; - for(m=matchers;m->mime_type!=NULL;++m){ - if (refpt->mime_type && strcasecmp(m->mime_type,refpt->mime_type)==0){ - return m->match_func(l,refpt); - } +static PayloadType * find_payload_type_best_match(const MSList *local_payloads, const PayloadType *refpt, + const MSList *remote_payloads, bool_t reading_response){ + PayloadType *ret = NULL; + MSOfferAnswerContext *ctx = ms_factory_create_offer_answer_context(ms_factory_get_fallback(), refpt->mime_type); + if (ctx){ + ms_message("Doing offer/answer processing with specific provider for codec [%s]", refpt->mime_type); + ret = ms_offer_answer_context_match_payload(ctx, local_payloads, refpt, remote_payloads, reading_response); + ms_offer_answer_context_destroy(ctx); + return ret; } - return generic_match(l,refpt); + return generic_match(local_payloads, refpt, remote_payloads); } @@ -149,9 +176,8 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t for(e2=remote;e2!=NULL;e2=e2->next){ PayloadType *p2=(PayloadType*)e2->data; - matched=find_payload_type_best_match(local,p2); + matched=find_payload_type_best_match(local, p2, remote, reading_response); if (matched){ - PayloadType *newp; int local_number=payload_type_get_number(matched); int remote_number=payload_type_get_number(p2); @@ -163,35 +189,36 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t } } - newp=payload_type_clone(matched); if (p2->send_fmtp){ - payload_type_append_send_fmtp(newp,p2->send_fmtp); + payload_type_append_send_fmtp(matched,p2->send_fmtp); } - newp->flags|=PAYLOAD_TYPE_FLAG_CAN_RECV|PAYLOAD_TYPE_FLAG_CAN_SEND; + matched->flags|=PAYLOAD_TYPE_FLAG_CAN_RECV|PAYLOAD_TYPE_FLAG_CAN_SEND; if (p2->flags & PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED) { - newp->flags |= PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED; - newp->avpf = payload_type_get_avpf_params(p2); /* Take remote AVPF features */ + matched->flags |= PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED; + /* Negotiation of AVPF features (keep common features) */ + matched->avpf.features &= p2->avpf.features; + matched->avpf.rpsi_compatibility = p2->avpf.rpsi_compatibility; /* Take bigger AVPF trr interval */ if (p2->avpf.trr_interval < matched->avpf.trr_interval) { - newp->avpf.trr_interval = matched->avpf.trr_interval; + matched->avpf.trr_interval = matched->avpf.trr_interval; } } - res=ms_list_append(res,newp); + res=ms_list_append(res,matched); /* we should use the remote numbering even when parsing a response */ - payload_type_set_number(newp,remote_number); - payload_type_set_flag(newp, PAYLOAD_TYPE_FROZEN_NUMBER); + payload_type_set_number(matched,remote_number); + payload_type_set_flag(matched, PAYLOAD_TYPE_FROZEN_NUMBER); if (reading_response && remote_number!=local_number){ ms_warning("For payload type %s, proposed number was %i but the remote phone answered %i", - newp->mime_type, local_number, remote_number); + matched->mime_type, local_number, remote_number); /* We must add this payload type with our local numbering in order to be able to receive it. Indeed despite we must sent with the remote numbering, we must be able to receive with our local one. */ - newp=payload_type_clone(newp); - payload_type_set_number(newp,local_number); - payload_type_set_flag(newp, PAYLOAD_TYPE_FROZEN_NUMBER); - res=ms_list_append(res,newp); + matched=payload_type_clone(matched); + payload_type_set_number(matched,local_number); + payload_type_set_flag(matched, PAYLOAD_TYPE_FROZEN_NUMBER); + res=ms_list_append(res,matched); } }else{ if (p2->channels>0) @@ -308,67 +335,66 @@ static void initiate_outgoing(const SalStreamDescription *local_offer, result->type=local_offer->type; if (local_offer->rtp_addr[0]!='\0' && ms_is_multicast(local_offer->rtp_addr)) { - /*6.2 Multicast Streams - ... - If a multicast stream is accepted, the address and port information - in the answer MUST match that of the offer. Similarly, the - directionality information in the answer (sendonly, recvonly, or - sendrecv) MUST equal that of the offer. This is because all - participants in a multicast session need to have equivalent views of - the parameters of the session, an underlying assumption of the - multicast bias of RFC 2327.*/ - if (strcmp(local_offer->rtp_addr,remote_answer->rtp_addr) !=0 ) { - ms_message("Remote answered IP [%s] does not match offered [%s] for local stream description [%p]" - ,remote_answer->rtp_addr - ,local_offer->rtp_addr - ,local_offer); - result->rtp_port=0; - return; - } - if (local_offer->rtp_port!=remote_answer->rtp_port) { - ms_message("Remote answered rtp port [%i] does not match offered [%i] for local stream description [%p]" - ,remote_answer->rtp_port - ,local_offer->rtp_port - ,local_offer); - result->rtp_port=0; - return; - } - if (local_offer->dir!=remote_answer->dir) { - ms_message("Remote answered dir [%s] does not match offered [%s] for local stream description [%p]" - ,sal_stream_dir_to_string(remote_answer->dir) - ,sal_stream_dir_to_string(local_offer->dir) - ,local_offer); - result->rtp_port=0; - return; - } - if (local_offer->bandwidth!=remote_answer->bandwidth) { - ms_message("Remote answered bandwidth [%i] does not match offered [%i] for local stream description [%p]" - ,remote_answer->bandwidth - ,local_offer->bandwidth - ,local_offer); - result->rtp_port=0; - return; - } - if (local_offer->ptime > 0 && local_offer->ptime!=remote_answer->ptime) { - ms_message("Remote answered ptime [%i] does not match offered [%i] for local stream description [%p]" - ,remote_answer->ptime - ,local_offer->ptime - ,local_offer); - result->rtp_port=0; - return; - } - if (local_offer->ttl > 0 && local_offer->ttl!=remote_answer->ttl) { - ms_message("Remote answered ttl [%i] does not match offered [%i] for local stream description [%p]" - ,remote_answer->ttl - ,local_offer->ttl - ,local_offer); - result->rtp_port=0; - return; - } - result->ttl=local_offer->ttl; - result->dir=local_offer->dir; - result->multicast_role = SalMulticastSender; - + /*6.2 Multicast Streams + ... + If a multicast stream is accepted, the address and port information + in the answer MUST match that of the offer. Similarly, the + directionality information in the answer (sendonly, recvonly, or + sendrecv) MUST equal that of the offer. This is because all + participants in a multicast session need to have equivalent views of + the parameters of the session, an underlying assumption of the + multicast bias of RFC 2327.*/ + if (strcmp(local_offer->rtp_addr,remote_answer->rtp_addr) !=0 ) { + ms_message("Remote answered IP [%s] does not match offered [%s] for local stream description [%p]" + ,remote_answer->rtp_addr + ,local_offer->rtp_addr + ,local_offer); + result->rtp_port=0; + return; + } + if (local_offer->rtp_port!=remote_answer->rtp_port) { + ms_message("Remote answered rtp port [%i] does not match offered [%i] for local stream description [%p]" + ,remote_answer->rtp_port + ,local_offer->rtp_port + ,local_offer); + result->rtp_port=0; + return; + } + if (local_offer->dir!=remote_answer->dir) { + ms_message("Remote answered dir [%s] does not match offered [%s] for local stream description [%p]" + ,sal_stream_dir_to_string(remote_answer->dir) + ,sal_stream_dir_to_string(local_offer->dir) + ,local_offer); + result->rtp_port=0; + return; + } + if (local_offer->bandwidth!=remote_answer->bandwidth) { + ms_message("Remote answered bandwidth [%i] does not match offered [%i] for local stream description [%p]" + ,remote_answer->bandwidth + ,local_offer->bandwidth + ,local_offer); + result->rtp_port=0; + return; + } + if (local_offer->ptime > 0 && local_offer->ptime!=remote_answer->ptime) { + ms_message("Remote answered ptime [%i] does not match offered [%i] for local stream description [%p]" + ,remote_answer->ptime + ,local_offer->ptime + ,local_offer); + result->rtp_port=0; + return; + } + if (local_offer->ttl > 0 && local_offer->ttl!=remote_answer->ttl) { + ms_message("Remote answered ttl [%i] does not match offered [%i] for local stream description [%p]" + ,remote_answer->ttl + ,local_offer->ttl + ,local_offer); + result->rtp_port=0; + return; + } + result->ttl=local_offer->ttl; + result->dir=local_offer->dir; + result->multicast_role = SalMulticastSender; } else { result->dir=compute_dir_outgoing(local_offer->dir,remote_answer->dir); } @@ -407,8 +433,7 @@ static void initiate_outgoing(const SalStreamDescription *local_offer, result->dtls_fingerprint[0] = '\0'; result->dtls_role = SalDtlsRoleInvalid; } - - + result->rtcp_mux = remote_answer->rtcp_mux && local_offer->rtcp_mux; } @@ -419,7 +444,7 @@ static void initiate_incoming(const SalStreamDescription *local_cap, result->proto=remote_offer->proto; result->type=local_cap->type; result->dir=compute_dir_incoming(local_cap->dir,remote_offer->dir); - if (!result->payloads || only_telephone_event(result->payloads) || remote_offer->rtp_port==0 || remote_offer->dir==SalStreamRecvOnly){ + if (!result->payloads || only_telephone_event(result->payloads) || remote_offer->rtp_port==0){ result->rtp_port=0; return; } @@ -476,8 +501,7 @@ static void initiate_incoming(const SalStreamDescription *local_cap, result->dtls_fingerprint[0] = '\0'; result->dtls_role = SalDtlsRoleInvalid; } - - + result->rtcp_mux = remote_offer->rtcp_mux && local_cap->rtcp_mux; } @@ -488,26 +512,29 @@ static void initiate_incoming(const SalStreamDescription *local_cap, int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer, const SalMediaDescription *remote_answer, SalMediaDescription *result){ - int i,j; + int i; const SalStreamDescription *ls,*rs; - for(i=0,j=0;inb_streams;++i){ + for(i=0;inb_streams;++i){ ms_message("Processing for stream %i",i); ls=&local_offer->streams[i]; - rs=sal_media_description_find_stream((SalMediaDescription*)remote_answer,ls->proto,ls->type); - if (rs) { - initiate_outgoing(ls,rs,&result->streams[j]); + rs=&remote_answer->streams[i]; + if (rs && ls->proto == rs->proto && rs->type == ls->type) { + initiate_outgoing(ls,rs,&result->streams[i]); memcpy(&result->streams[i].rtcp_xr, &ls->rtcp_xr, sizeof(result->streams[i].rtcp_xr)); if ((ls->rtcp_xr.enabled == TRUE) && (rs->rtcp_xr.enabled == FALSE)) { result->streams[i].rtcp_xr.enabled = FALSE; } - ++j; + result->streams[i].rtcp_fb.generic_nack_enabled = ls->rtcp_fb.generic_nack_enabled & rs->rtcp_fb.generic_nack_enabled; + result->streams[i].rtcp_fb.tmmbr_enabled = ls->rtcp_fb.tmmbr_enabled & rs->rtcp_fb.tmmbr_enabled; } else ms_warning("No matching stream for %i",i); } result->nb_streams=local_offer->nb_streams; result->bandwidth=remote_answer->bandwidth; strcpy(result->addr,remote_answer->addr); + strcpy(result->ice_pwd, local_offer->ice_pwd); + strcpy(result->ice_ufrag, local_offer->ice_ufrag); memcpy(&result->rtcp_xr, &local_offer->rtcp_xr, sizeof(result->rtcp_xr)); if ((local_offer->rtcp_xr.enabled == TRUE) && (remote_answer->rtcp_xr.enabled == FALSE)) { result->rtcp_xr.enabled = FALSE; @@ -516,39 +543,6 @@ int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer, return 0; } -static bool_t local_stream_not_already_used(const SalMediaDescription *result, const SalStreamDescription *stream){ - int i; - for(i=0;inb_streams;++i){ - const SalStreamDescription *ss=&result->streams[i]; - if (strcmp(ss->name,stream->name)==0){ - ms_message("video stream already used in answer"); - return FALSE; - } - } - return TRUE; -} - -/*in answering mode, we consider that if we are able to make AVPF/SAVP/SAVPF, then we can do AVP as well*/ -static bool_t proto_compatible(SalMediaProto local, SalMediaProto remote) { - if (local == remote) return TRUE; - if ((remote == SalProtoRtpAvp) && ((local == SalProtoRtpSavp) || (local == SalProtoRtpSavpf))) return TRUE; - if ((remote == SalProtoRtpAvp) && ((local == SalProtoUdpTlsRtpSavp) || (local == SalProtoUdpTlsRtpSavpf))) return TRUE; - if ((remote == SalProtoRtpAvpf) && (local == SalProtoRtpSavpf)) return TRUE; - if ((remote == SalProtoRtpAvpf) && (local == SalProtoUdpTlsRtpSavpf)) return TRUE; - return FALSE; -} - -static const SalStreamDescription *find_local_matching_stream(const SalMediaDescription *result, const SalMediaDescription *local_capabilities, const SalStreamDescription *remote_stream){ - int i; - for(i=0;inb_streams;++i){ - const SalStreamDescription *ss=&local_capabilities->streams[i]; - if (!sal_stream_description_active(ss)) continue; - if (ss->type==remote_stream->type && proto_compatible(ss->proto,remote_stream->proto) - && local_stream_not_already_used(result,ss)) return ss; - } - return NULL; -} - /** * Returns a media description to run the streams with, based on the local capabilities and * and the received offer. @@ -561,12 +555,13 @@ int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities const SalStreamDescription *ls=NULL,*rs; for(i=0;inb_streams;++i){ - rs=&remote_offer->streams[i]; - if (rs->proto!=SalProtoOther){ - ls=find_local_matching_stream(result,local_capabilities,rs); - }else ms_warning("Unknown protocol for mline %i, declining",i); - if (ls){ + rs = &remote_offer->streams[i]; + ls = &local_capabilities->streams[i]; + if (ls && rs->type == ls->type && rs->proto == ls->proto){ initiate_incoming(ls,rs,&result->streams[i],one_matching_codec); + // Handle global RTCP FB attributes + result->streams[i].rtcp_fb.generic_nack_enabled = rs->rtcp_fb.generic_nack_enabled; + result->streams[i].rtcp_fb.tmmbr_enabled = rs->rtcp_fb.tmmbr_enabled; // Handle media RTCP XR attribute memset(&result->streams[i].rtcp_xr, 0, sizeof(result->streams[i].rtcp_xr)); if (rs->rtcp_xr.enabled == TRUE) { @@ -593,6 +588,7 @@ int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities strncpy(result->streams[i].proto_other,rs->proto_other,sizeof(rs->proto_other)-1); } } + result->streams[i].custom_sdp_attributes = sal_custom_sdp_attribute_clone(ls->custom_sdp_attributes); } result->nb_streams=i; strcpy(result->username, local_capabilities->username); @@ -604,6 +600,7 @@ int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities strcpy(result->ice_ufrag, local_capabilities->ice_ufrag); result->ice_lite = local_capabilities->ice_lite; result->ice_completed = local_capabilities->ice_completed; + result->custom_sdp_attributes = sal_custom_sdp_attribute_clone(local_capabilities->custom_sdp_attributes); strcpy(result->name,local_capabilities->name); diff --git a/coreapi/player.c b/coreapi/player.c index 1b2a01022..668b91c01 100644 --- a/coreapi/player.c +++ b/coreapi/player.c @@ -94,7 +94,7 @@ int linphone_player_get_current_position(LinphonePlayer *obj) { * @param obj the player. **/ void linphone_player_close(LinphonePlayer *obj){ - return obj->close(obj); + obj->close(obj); } /** diff --git a/coreapi/plugins/buddylookup/src/lookup.c b/coreapi/plugins/buddylookup/src/lookup.c index 48a8d3bb2..736e7aa35 100644 --- a/coreapi/plugins/buddylookup/src/lookup.c +++ b/coreapi/plugins/buddylookup/src/lookup.c @@ -81,7 +81,7 @@ static void fill_buddy_info(BLReq *blreq, BuddyInfo *bi, GHashTable *ht){ }else{ strncpy(bi->sip_uri,tmp,sizeof(bi->sip_uri)-1); } - + fill_item(ht,"street",bi->address.street,sizeof(bi->address.street)); fill_item(ht,"zip",bi->address.zip,sizeof(bi->address.zip)); fill_item(ht,"city",bi->address.town,sizeof(bi->address.town)); @@ -105,7 +105,7 @@ static void fill_buddy_info(BLReq *blreq, BuddyInfo *bi, GHashTable *ht){ ms_error("Fail to fetch the image %i",status); } } - + } static MSList * make_buddy_list(BLReq *blreq, GValue *retval){ @@ -156,7 +156,7 @@ static int xml_rpc_parse_response(BLReq *blreq, SoupMessage *sm){ #if SERIALIZE_HTTPS /*on windows libsoup support for threads with gnutls is not yet functionnal (only in git) -This will come in next release of libsoup, probably. +This will come in next release of libsoup, probably. In the meantime, we are forced to serialize all soup https processing with a big ugly global mutex...*/ @@ -191,27 +191,26 @@ static int lookup_buddy(SipSetupContext *ctx, BLReq *req){ LinphoneProxyConfig *cfg=sip_setup_context_get_proxy_config(ctx); LinphoneCore *lc=linphone_proxy_config_get_core(cfg); LpConfig *config=linphone_core_get_config(lc); - const char *identity=linphone_proxy_config_get_identity(cfg); + LinphoneAddress *from=linphone_proxy_config_get_identity_address(cfg); const char *url=lp_config_get_string(config,"BuddyLookup","url",NULL); - const LinphoneAuthInfo *aa; + const LinphoneAuthInfo *auth_info; SoupMessage *sm; - LinphoneAddress *from; - + char *identity; + if (url==NULL){ ms_error("No url defined for BuddyLookup in config file, aborting search."); return -1; } - - from=linphone_address_new(identity); - if (from==NULL){ - ms_error("Could not parse identity %s",identity); - return -1; + auth_info=linphone_core_find_auth_info(lc,linphone_address_get_domain(from),linphone_address_get_username(from)); + if (auth_info) { + ms_message("There is a password: %s",auth_info->passwd); + } else { + ms_message("No password for %s on %s",linphone_address_get_username(from),linphone_address_get_domain(from)); } - aa=linphone_core_find_auth_info(lc,linphone_address_get_domain(from),linphone_address_get_username(from)); - if (aa) ms_message("There is a password: %s",aa->passwd); - else ms_message("No password for %s on %s",linphone_address_get_username(from),linphone_address_get_domain(from)); - sm=build_xmlrpc_request(identity, aa ? aa->passwd : NULL, req->base.key, linphone_address_get_domain(from), url, req->base.max_results); - linphone_address_destroy(from); + + identity=linphone_proxy_config_get_identity(cfg); + sm=build_xmlrpc_request(identity, auth_info ? auth_info->passwd : NULL, req->base.key, linphone_address_get_domain(from), url, req->base.max_results); + ms_free(identity); req->msg=sm; ortp_thread_create(&req->th,NULL,process_xml_rpc_request,req); if (!sm) return -1; diff --git a/coreapi/presence.c b/coreapi/presence.c index e944d3a45..f69ddec6e 100644 --- a/coreapi/presence.c +++ b/coreapi/presence.c @@ -157,6 +157,11 @@ static void presence_activity_delete(LinphonePresenceActivity *activity) { static time_t parse_timestamp(const char *timestamp) { struct tm ret; time_t seconds; +#ifdef LINPHONE_WINDOWS_UNIVERSAL + long adjust_timezone; +#else + time_t adjust_timezone; +#endif memset(&ret, 0, sizeof(ret)); sscanf(timestamp, "%d-%d-%dT%d:%d:%d", @@ -169,13 +174,18 @@ static time_t parse_timestamp(const char *timestamp) { ms_error("mktime() failed: %s", strerror(errno)); return (time_t)-1; } - return seconds - timezone; +#ifdef LINPHONE_WINDOWS_UNIVERSAL + _get_timezone(&adjust_timezone); +#else + adjust_timezone = timezone; +#endif + return seconds - (time_t)adjust_timezone; } char * linphone_timestamp_to_rfc3339_string(time_t timestamp) { char timestamp_str[22]; struct tm *ret; -#ifndef WIN32 +#ifndef _WIN32 struct tm gmt; ret = gmtime_r(×tamp,&gmt); #else @@ -1434,16 +1444,19 @@ static LinphonePresenceModel * process_pidf_xml_presence_notification(xmlparsing void linphone_core_add_subscriber(LinphoneCore *lc, const char *subscriber, SalOp *op){ LinphoneFriend *fl=linphone_friend_new_with_address(subscriber); + char *tmp; + if (fl==NULL) return ; - fl->insub=op; + linphone_friend_add_incoming_subscription(fl, op); linphone_friend_set_inc_subscribe_policy(fl,LinphoneSPAccept); fl->inc_subscribe_pending=TRUE; - lc->subscribers=ms_list_append(lc->subscribers,(void *)fl); - { - char *tmp=linphone_address_as_string(fl->uri); - linphone_core_notify_new_subscription_requested(lc,fl,tmp); - ms_free(tmp); - } + /* the newly created "not yet" friend ownership is transfered to the lc->subscribers list*/ + lc->subscribers=ms_list_append(lc->subscribers,fl); + + tmp = linphone_address_as_string(fl->uri); + linphone_core_notify_new_subscription_requested(lc,fl,tmp); + ms_free(tmp); + } void linphone_core_reject_subscriber(LinphoneCore *lc, LinphoneFriend *lf){ @@ -1458,9 +1471,7 @@ void linphone_core_notify_all_friends(LinphoneCore *lc, LinphonePresenceModel *p if (activity_str != NULL) ms_free(activity_str); for(elem=lc->friends;elem!=NULL;elem=elem->next){ LinphoneFriend *lf=(LinphoneFriend *)elem->data; - if (lf->insub){ - linphone_friend_notify(lf,presence); - } + linphone_friend_notify(lf,presence); } } @@ -1468,26 +1479,15 @@ void linphone_subscription_new(LinphoneCore *lc, SalOp *op, const char *from){ LinphoneFriend *lf=NULL; char *tmp; LinphoneAddress *uri; - LinphoneProxyConfig *cfg; uri=linphone_address_new(from); linphone_address_clean(uri); tmp=linphone_address_as_string(uri); ms_message("Receiving new subscription from %s.",from); - cfg=linphone_core_lookup_known_proxy(lc,uri); - if (cfg!=NULL){ - if (cfg->op){ - if (sal_op_get_contact_address(cfg->op)) { - sal_op_set_contact_address (op,sal_op_get_contact_address(cfg->op)); - ms_message("Contact for next subscribe answer has been fixed using proxy "/*to %s",fixed_contact*/); - } - } - } - /* check if we answer to this subscription */ if (linphone_find_friend_by_address(lc->friends,uri,&lf)!=NULL){ - lf->insub=op; + linphone_friend_add_incoming_subscription(lf, op); lf->inc_subscribe_pending=TRUE; sal_subscribe_accept(op); linphone_friend_done(lf); /*this will do all necessary actions */ @@ -1500,7 +1500,7 @@ void linphone_subscription_new(LinphoneCore *lc, SalOp *op, const char *from){ } else { /* else it is in wait for approval state, because otherwise it is in the friend list.*/ - ms_message("New subscriber found in friend list, in %s state.",__policy_enum_to_str(lf->pol)); + ms_message("New subscriber found in subscriber list, in %s state.",__policy_enum_to_str(lf->pol)); } }else { sal_subscribe_accept(op); @@ -1876,15 +1876,29 @@ void linphone_notify_recv(LinphoneCore *lc, SalOp *op, SalSubscribeStatus ss, Sa lf->subscribe_active=TRUE; linphone_core_notify_notify_presence_received(lc,(LinphoneFriend*)lf); ms_free(tmp); + if (op != lf->outsub){ + /*case of a NOTIFY received out of any dialog*/ + sal_op_release(op); + return; + } }else{ ms_message("But this person is not part of our friend list, so we don't care."); linphone_presence_model_unref(presence); + sal_op_release(op); + return ; } if (ss==SalSubscribeTerminated){ - sal_op_release(op); if (lf){ - lf->outsub=NULL; + if (lf->outsub != op){ + sal_op_release(op); + } + if (lf->outsub){ + sal_op_release(lf->outsub); + lf->outsub=NULL; + } lf->subscribe_active=FALSE; + }else{ + sal_op_release(op); } } } @@ -1892,11 +1906,13 @@ void linphone_notify_recv(LinphoneCore *lc, SalOp *op, SalSubscribeStatus ss, Sa void linphone_subscription_closed(LinphoneCore *lc, SalOp *op){ LinphoneFriend *lf; lf=linphone_find_friend_by_inc_subscribe(lc->friends,op); - sal_op_release(op); + if (lf!=NULL){ - lf->insub=NULL; + /*this will release the op*/ + linphone_friend_remove_incoming_subscription(lf, op); }else{ - ms_warning("Receiving unsuscribe for unknown in-subscribtion from %s", sal_op_get_from(op)); + /*case of an op that we already released because the friend was destroyed*/ + ms_message("Receiving unsuscribe for unknown in-subscribtion from %s", sal_op_get_from(op)); } } diff --git a/coreapi/private.h b/coreapi/private.h index 8faa8ad35..27420aabb 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -39,6 +39,8 @@ extern "C" { #include #include +#include + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -65,8 +67,21 @@ extern "C" { #define PACKAGE_DATA_DIR "." #endif -#ifdef HAVE_GETTEXT +#ifdef ENABLE_NLS + +#ifdef _MSC_VER +// prevent libintl.h from re-defining fprintf and vfprintf +#ifndef fprintf +#define fprintf fprintf +#endif +#ifndef vfprintf +#define vfprintf vfprintf +#endif +#define _GL_STDIO_H +#endif + #include + #ifndef _ #define _(String) dgettext(GETTEXT_PACKAGE,String) #endif @@ -82,6 +97,20 @@ extern "C" { #include #endif +#ifdef _WIN32 +#if defined(__MINGW32__) || !defined(WINAPI_FAMILY_PARTITION) || !defined(WINAPI_PARTITION_DESKTOP) +#define LINPHONE_WINDOWS_DESKTOP 1 +#elif defined(WINAPI_FAMILY_PARTITION) +#if defined(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#define LINPHONE_WINDOWS_DESKTOP 1 +#elif defined(WINAPI_PARTITION_PHONE_APP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) +#define LINPHONE_WINDOWS_PHONE 1 +#elif defined(WINAPI_PARTITION_APP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) +#define LINPHONE_WINDOWS_UNIVERSAL 1 +#endif +#endif +#endif + struct _LinphoneCallParams{ belle_sip_object_t base; void *user_data; @@ -90,6 +119,7 @@ struct _LinphoneCallParams{ LinphoneMediaEncryption media_encryption; PayloadType *audio_codec; /*audio codec currently in use */ PayloadType *video_codec; /*video codec currently in use */ + PayloadType *text_codec; /*text codec currently in use */ MSVideoSize sent_vsize; /* Size of the video currently being sent */ MSVideoSize recv_vsize; /* Size of the video currently being received */ float received_fps,sent_fps; @@ -100,27 +130,32 @@ struct _LinphoneCallParams{ char *record_file; char *session_name; SalCustomHeader *custom_headers; + SalCustomSdpAttribute *custom_sdp_attributes; + SalCustomSdpAttribute *custom_sdp_media_attributes[LinphoneStreamTypeUnknown]; + LinphonePrivacyMask privacy; + LinphoneMediaDirection audio_dir; + LinphoneMediaDirection video_dir; + bool_t has_audio; bool_t has_video; bool_t avpf_enabled; /* RTCP feedback messages are enabled */ bool_t real_early_media; /*send real media even during early media (for outgoing calls)*/ bool_t in_conference; /*in conference mode */ + bool_t low_bandwidth; bool_t no_user_consent;/*when set to TRUE an UPDATE request will be used instead of reINVITE*/ uint16_t avpf_rr_interval; /*in milliseconds*/ - LinphonePrivacyMask privacy; - LinphoneMediaDirection audio_dir; - LinphoneMediaDirection video_dir; - bool_t video_declined; /*use to keep traces of declined video to avoid to re-offer video in case of automatic RE-INVITE*/ - bool_t internal_call_update; /*use mark that call update was requested internally (might be by ice)*/ + + bool_t internal_call_update; /*use mark that call update was requested internally (might be by ice) - unused for the moment*/ bool_t video_multicast_enabled; bool_t audio_multicast_enabled; + bool_t realtimetext_enabled; }; BELLE_SIP_DECLARE_VPTR(LinphoneCallParams); struct _LinphoneQualityReporting{ - reporting_session_report_t * reports[2]; /**Store information on audio and video media streams (RFC 6035) */ + reporting_session_report_t * reports[3]; /**Store information on audio and video media streams (RFC 6035) */ bool_t was_video_running; /*Keep video state since last check in order to detect its (de)activation*/ LinphoneQualityReportingReportSendCb on_report_sent; }; @@ -144,6 +179,7 @@ struct _LinphoneCallLog{ char* call_id; /**unique id of a call*/ struct _LinphoneQualityReporting reporting; bool_t video_enabled; + unsigned int storage_id; }; BELLE_SIP_DECLARE_VPTR(LinphoneCallLog); @@ -177,8 +213,7 @@ struct _LinphoneChatMessage { LinphoneChatMessageCbs *callbacks; LinphoneChatMessageDir dir; char* message; - LinphoneChatMessageStateChangedCb cb; - void* cb_ud; + void* message_state_changed_user_data; void* message_userdata; char* appdata; char* external_body_url; @@ -193,7 +228,17 @@ struct _LinphoneChatMessage { LinphoneContent *file_transfer_information; /**< used to store file transfer information when the message is of file transfer type */ char *content_type; /**< is used to specified the type of message to be sent, used only for file transfer message */ belle_http_request_t *http_request; /**< keep a reference to the http_request in case of file transfer in order to be able to cancel the transfer */ + belle_http_request_listener_t *http_listener; /* our listener, only owned by us*/ char *file_transfer_filepath; + +#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4) +#pragma GCC diagnostic push +#endif +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + LinphoneChatMessageStateChangedCb message_state_changed_cb; +#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4) +#pragma GCC diagnostic pop +#endif }; BELLE_SIP_DECLARE_VPTR(LinphoneChatMessage); @@ -222,6 +267,9 @@ struct _LinphoneCall{ SalMediaDescription *resultdesc; struct _RtpProfile *audio_profile; struct _RtpProfile *video_profile; + struct _RtpProfile *text_profile; + struct _RtpProfile *rtp_io_audio_profile; + struct _RtpProfile *rtp_io_video_profile; struct _LinphoneCallLog *log; LinphoneAddress *me; /*Either from or to based on call dir*/ SalOp *op; @@ -231,12 +279,14 @@ struct _LinphoneCall{ LinphoneCallState prevstate; LinphoneCallState transfer_state; /*idle if no transfer*/ LinphoneProxyConfig *dest_proxy; - PortConfig media_ports[2]; - MSMediaStreamSessions sessions[2]; /*the rtp, srtp, zrtp contexts for each stream*/ - StunCandidate ac,vc; /*audio video ip/port discovered by STUN*/ + int main_audio_stream_index, main_video_stream_index, main_text_stream_index; + PortConfig media_ports[SAL_MEDIA_DESCRIPTION_MAX_STREAMS]; + MSMediaStreamSessions sessions[SAL_MEDIA_DESCRIPTION_MAX_STREAMS]; /*the rtp, srtp, zrtp contexts for each stream*/ + StunCandidate ac, vc, tc; /*audio video text ip/port discovered by STUN*/ struct _AudioStream *audiostream; /**/ struct _VideoStream *videostream; - unsigned long video_window_id; + struct _TextStream *textstream; + void *video_window_id; MSAudioEndpoint *endpoint; /*used for conferencing*/ char *refer_to; LinphoneCallParams *params; @@ -247,8 +297,9 @@ struct _LinphoneCall{ OrtpEvQueue *audiostream_app_evq; char *auth_token; OrtpEvQueue *videostream_app_evq; + OrtpEvQueue *textstream_app_evq; CallCallbackObj nextVideoFrameDecoded; - LinphoneCallStats stats[2]; + LinphoneCallStats stats[3]; /* audio, video, text */ #ifdef BUILD_UPNP UpnpSession *upnp_session; #endif //BUILD_UPNP @@ -261,11 +312,14 @@ struct _LinphoneCall{ int localdesc_changed;/*not a boolean, contains a mask representing changes*/ LinphonePlayer *player; unsigned long bg_task_id; /*used to prevent device to suspend app while a call is received in background*/ + unsigned int nb_media_starts; char *dtmf_sequence; /*DTMF sequence needed to be sent using #dtmfs_timer*/ belle_sip_source_t *dtmfs_timer; /*DTMF timer needed to send a DTMF sequence*/ char *dtls_certificate_fingerprint; /**> This fingerprint is computed during stream init and is stored in call to be used when making local media description */ + char *onhold_file; /*set if a on-hold file is to be played*/ + LinphoneChatRoom *chat_room; bool_t refer_pending; bool_t expect_media_in_ack; bool_t audio_muted; @@ -282,8 +336,7 @@ struct _LinphoneCall{ bool_t record_active; bool_t paused_by_app; - - MSWebCam *cam; /*webcam use for this call*/ + bool_t broken; /*set to TRUE when the call is in broken state due to network disconnection or transport */ }; BELLE_SIP_DECLARE_VPTR(LinphoneCall); @@ -294,20 +347,26 @@ LinphoneCall * linphone_call_new_incoming(struct _LinphoneCore *lc, LinphoneAddr void linphone_call_set_new_params(LinphoneCall *call, const LinphoneCallParams *params); void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const char *message); void linphone_call_set_contact_op(LinphoneCall* call); -void linphone_call_set_compatible_incoming_call_parameters(LinphoneCall *call, const SalMediaDescription *md); +void linphone_call_set_compatible_incoming_call_parameters(LinphoneCall *call, SalMediaDescription *md); /* private: */ LinphoneCallLog * linphone_call_log_new(LinphoneCallDir dir, LinphoneAddress *local, LinphoneAddress * remote); void linphone_call_log_completed(LinphoneCall *call); void linphone_call_log_destroy(LinphoneCallLog *cl); void linphone_call_set_transfer_state(LinphoneCall* call, LinphoneCallState state); LinphonePlayer *linphone_call_build_player(LinphoneCall*call); +void linphone_call_refresh_sockets(LinphoneCall *call); LinphoneCallParams * linphone_call_params_new(void); SalMediaProto get_proto_from_call_params(const LinphoneCallParams *params); SalStreamDir get_audio_dir_from_call_params(const LinphoneCallParams *params); SalStreamDir get_video_dir_from_call_params(const LinphoneCallParams *params); +void linphone_call_params_set_custom_headers(LinphoneCallParams *params, const SalCustomHeader *ch); +void linphone_call_params_set_custom_sdp_attributes(LinphoneCallParams *params, const SalCustomSdpAttribute *csa); +void linphone_call_params_set_custom_sdp_media_attributes(LinphoneCallParams *params, LinphoneStreamType type, const SalCustomSdpAttribute *csa); void linphone_auth_info_write_config(struct _LpConfig *config, LinphoneAuthInfo *obj, int pos); +void linphone_core_write_auth_info(LinphoneCore *lc, LinphoneAuthInfo *ai); +const LinphoneAuthInfo *_linphone_core_find_auth_info(LinphoneCore *lc, const char *realm, const char *username, const char *domain, bool_t ignore_realm); void linphone_core_update_proxy_register(LinphoneCore *lc); void linphone_core_refresh_subscribes(LinphoneCore *lc); @@ -324,11 +383,12 @@ void _linphone_proxy_config_release(LinphoneProxyConfig *cfg); * Can be NULL * */ const LinphoneAddress* linphone_proxy_config_get_service_route(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); void linphone_friend_notify(LinphoneFriend *lf, LinphonePresenceModel *presence); +void linphone_friend_add_incoming_subscription(LinphoneFriend *lf, SalOp *op); +void linphone_friend_remove_incoming_subscription(LinphoneFriend *lf, SalOp *op); LinphoneFriend *linphone_find_friend_by_inc_subscribe(MSList *l, SalOp *op); LinphoneFriend *linphone_find_friend_by_out_subscribe(MSList *l, SalOp *op); MSList *linphone_find_friend_by_address(MSList *fl, const LinphoneAddress *addr, LinphoneFriend **lf); @@ -337,7 +397,7 @@ void linphone_core_update_friends_subscriptions(LinphoneCore *lc, LinphoneProxyC int parse_hostname_to_addr(const char *server, struct sockaddr_storage *ss, socklen_t *socklen, int default_port); -bool_t host_has_ipv6_network(); +bool_t host_has_ipv6_network(void); bool_t lp_spawn_command_line_sync(const char *command, char **result,int *command_ret); static MS2_INLINE int get_min_bandwidth(int dbw, int ubw){ @@ -347,23 +407,29 @@ static MS2_INLINE int get_min_bandwidth(int dbw, int ubw){ } static MS2_INLINE bool_t bandwidth_is_greater(int bw1, int bw2){ - if (bw1<0) return TRUE; - else if (bw2<0) return FALSE; + if (bw1<=0) return TRUE; + else if (bw2<=0) return FALSE; else return bw1>=bw2; } static MS2_INLINE int get_remaining_bandwidth_for_video(int total, int audio){ - if (total<=0) return 0; - return total-audio-10; + int ret = total-audio-10; + if (ret < 0) ret = 0; + return ret; } -static MS2_INLINE void set_string(char **dest, const char *src){ +static MS2_INLINE void set_string(char **dest, const char *src, bool_t lowercase){ if (*dest){ ms_free(*dest); *dest=NULL; } - if (src) + if (src) { *dest=ms_strdup(src); + if (lowercase) { + char *cur = *dest; + for (; *cur; cur++) *cur = tolower(*cur); + } + } } #define PAYLOAD_TYPE_ENABLED PAYLOAD_TYPE_USER_FLAG_0 @@ -389,15 +455,16 @@ void linphone_core_update_allocated_audio_bandwidth_in_call(LinphoneCall *call, LINPHONE_PUBLIC int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call); void linphone_core_resolve_stun_server(LinphoneCore *lc); -const struct addrinfo *linphone_core_get_stun_server_addrinfo(LinphoneCore *lc); +LINPHONE_PUBLIC const struct addrinfo *linphone_core_get_stun_server_addrinfo(LinphoneCore *lc); void linphone_core_adapt_to_network(LinphoneCore *lc, int ping_time_ms, LinphoneCallParams *params); int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call); void linphone_core_update_ice_state_in_call_stats(LinphoneCall *call); void linphone_call_stats_fill(LinphoneCallStats *stats, MediaStream *ms, OrtpEvent *ev); -void linphone_call_stop_ice_for_inactive_streams(LinphoneCall *call); +void linphone_call_stop_ice_for_inactive_streams(LinphoneCall *call, SalMediaDescription *result); void _update_local_media_description_from_ice(SalMediaDescription *desc, IceSession *session); void linphone_call_update_local_media_description_from_ice_or_upnp(LinphoneCall *call); void linphone_call_update_ice_from_remote_media_description(LinphoneCall *call, const SalMediaDescription *md); +void linphone_call_clear_unused_ice_candidates(LinphoneCall *call, const SalMediaDescription *md); bool_t linphone_core_media_description_contains_video_stream(const SalMediaDescription *md); void linphone_core_send_initial_subscribes(LinphoneCore *lc); @@ -416,13 +483,15 @@ void linphone_proxy_config_write_to_config_file(struct _LpConfig* config,Linphon void linphone_core_message_received(LinphoneCore *lc, SalOp *op, const SalMessage *msg); void linphone_core_is_composing_received(LinphoneCore *lc, SalOp *op, const SalIsComposing *is_composing); +void linphone_core_real_time_text_received(LinphoneCore *lc, LinphoneChatRoom *cr, uint32_t character, LinphoneCall *call); void linphone_call_init_stats(LinphoneCallStats *stats, int type); -void linphone_call_fix_call_parameters(LinphoneCall *call); +void linphone_call_fix_call_parameters(LinphoneCall *call, SalMediaDescription *rmd); void linphone_call_init_audio_stream(LinphoneCall *call); void linphone_call_init_video_stream(LinphoneCall *call); +void linphone_call_init_text_stream(LinphoneCall *call); void linphone_call_init_media_streams(LinphoneCall *call); -void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_muted, bool_t send_ringbacktone); +void linphone_call_start_media_streams(LinphoneCall *call, LinphoneCallState target_state); void linphone_call_start_media_streams_for_ice_gathering(LinphoneCall *call); void linphone_call_stop_media_streams(LinphoneCall *call); void linphone_call_delete_ice_session(LinphoneCall *call); @@ -461,13 +530,21 @@ typedef enum _LinphoneProxyConfigAddressComparisonResult{ LINPHONE_PUBLIC LinphoneProxyConfigAddressComparisonResult linphone_proxy_config_address_equal(const LinphoneAddress *a, const LinphoneAddress *b); LINPHONE_PUBLIC LinphoneProxyConfigAddressComparisonResult linphone_proxy_config_is_server_config_changed(const LinphoneProxyConfig* obj); +/** + * unregister without moving the register_enable flag + */ void _linphone_proxy_config_unregister(LinphoneProxyConfig *obj); void _linphone_proxy_config_release_ops(LinphoneProxyConfig *obj); /*chat*/ void linphone_chat_room_release(LinphoneChatRoom *cr); void linphone_chat_message_destroy(LinphoneChatMessage* msg); -void linphone_chat_message_update_state(LinphoneChatMessage* chat_msg ); +void linphone_chat_message_update_state(LinphoneChatMessage *msg, LinphoneChatMessageState new_state); +void linphone_chat_message_set_state(LinphoneChatMessage *msg, LinphoneChatMessageState state); +int linphone_chat_room_upload_file(LinphoneChatMessage *msg); +void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage *msg); +LinphoneChatMessageCbs *linphone_chat_message_cbs_new(void); +LinphoneChatRoom *_linphone_core_create_chat_room_from_call(LinphoneCall *call); /**/ struct _LinphoneProxyConfig @@ -477,9 +554,9 @@ struct _LinphoneProxyConfig struct _LinphoneCore *lc; char *reg_proxy; char *reg_identity; + LinphoneAddress* identity_address; char *reg_route; char *quality_reporting_collector; - char *domain; char *realm; char *contact_params; char *contact_uri_params; @@ -511,6 +588,7 @@ struct _LinphoneProxyConfig LinphoneAddress *saved_proxy; LinphoneAddress *saved_identity; /*---*/ + LinphoneAddress *pending_contact; /*use to store previous contact in case of network failure*/ }; @@ -539,13 +617,22 @@ struct _LinphoneChatRoom{ LinphoneAddress *peer_url; MSList *messages_hist; MSList *transient_messages; + int unread_count; LinphoneIsComposingState remote_is_composing; LinphoneIsComposingState is_composing; belle_sip_source_t *remote_composing_refresh_timer; belle_sip_source_t *composing_idle_timer; belle_sip_source_t *composing_refresh_timer; + LinphoneCall *call; + LinphoneChatMessage *pending_message; + MSList *received_rtt_characters; }; +typedef struct _LinphoneChatMessageCharacter { + uint32_t value; + bool_t has_been_read; +} LinphoneChatMessageCharacter; + BELLE_SIP_DECLARE_VPTR(LinphoneChatRoom); @@ -553,7 +640,7 @@ struct _LinphoneFriend{ belle_sip_object_t base; void *user_data; LinphoneAddress *uri; - SalOp *insub; + MSList *insubs; /*list of SalOp. There can be multiple instances of a same Friend that subscribe to our presence*/ SalOp *outsub; LinphoneSubscribePolicy pol; LinphonePresenceModel *presence; @@ -617,6 +704,8 @@ typedef struct rtp_config char* video_multicast_addr; int video_multicast_ttl; bool_t video_multicast_enabled; + int text_rtp_min_port; + int text_rtp_max_port; }rtp_config_t; @@ -662,6 +751,7 @@ typedef struct codecs_config { MSList *audio_codecs; /* list of audio codecs in order of preference*/ MSList *video_codecs; + MSList *text_codecs; int dyn_pt; int telephone_event_pt; }codecs_config_t; @@ -679,6 +769,10 @@ typedef struct video_config{ bool_t reuse_preview_source; }video_config_t; +typedef struct text_config{ + bool_t enabled; +}text_config_t; + typedef struct ui_config { int is_daemon; @@ -724,6 +818,16 @@ const char *linphone_core_get_tone_file(const LinphoneCore *lc, LinphoneToneID i int _linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params, LinphoneCallState next_state, const char *state_info); typedef struct _LinphoneConference LinphoneConference; +typedef struct _LinphoneTaskList{ + MSList *hooks; +}LinphoneTaskList; + +void linphone_task_list_init(LinphoneTaskList *t); +void linphone_task_list_add(LinphoneTaskList *t, LinphoneCoreIterateHook hook, void *hook_data); +void linphone_task_list_remove(LinphoneTaskList *t, LinphoneCoreIterateHook hook, void *hook_data); +void linphone_task_list_run(LinphoneTaskList *t); +void linphone_task_list_free(LinphoneTaskList *t); + struct _LinphoneCore { MSList* vtable_refs; @@ -732,11 +836,13 @@ struct _LinphoneCore struct _LpConfig *config; MSList *default_audio_codecs; MSList *default_video_codecs; + MSList *default_text_codecs; net_config_t net_conf; sip_config_t sip_conf; rtp_config_t rtp_conf; sound_config_t sound_conf; video_config_t video_conf; + text_config_t text_conf; codecs_config_t codecs_conf; ui_config_t ui_conf; autoreplier_config_t autoreplier_conf; @@ -763,15 +869,15 @@ struct _LinphoneCore void *data; char *play_file; char *rec_file; - time_t prevtime; + uint64_t prevtime_ms; int audio_bw; /*IP bw consumed by audio codec, set as soon as used codec is known, its purpose is to know the remaining bw for video*/ LinphoneCoreWaitingCallback wait_cb; void *wait_ctx; - unsigned long video_window_id; - unsigned long preview_window_id; + void *video_window_id; + void *preview_window_id; time_t netup_time; /*time when network went reachable */ struct _EcCalibrator *ecc; - MSList *hooks; + LinphoneTaskList hooks; /*tasks periodically executed in linphone_core_iterate()*/ LinphoneConference conf_ctx; char* zrtp_secrets_cache; char* user_certificates_path; @@ -802,12 +908,17 @@ struct _LinphoneCore #ifdef MSG_STORAGE_ENABLED sqlite3 *db; bool_t debug_storage; +#endif + char *logs_db_file; +#ifdef CALL_LOGS_STORAGE_ENABLED + sqlite3 *logs_db; #endif #ifdef BUILD_UPNP UpnpContext *upnp; #endif //BUILD_UPNP belle_http_provider_t *http_provider; belle_tls_verify_policy_t *http_verify_policy; + belle_http_request_listener_t *provisioning_http_listener; MSList *tones; LinphoneReason chat_deny_code; char *file_transfer_server; @@ -851,20 +962,20 @@ void linphone_tunnel_enable_logs_with_handler(LinphoneTunnel *tunnel, bool_t ena bool_t linphone_core_can_we_add_call(LinphoneCore *lc); int linphone_core_add_call( LinphoneCore *lc, LinphoneCall *call); int linphone_core_del_call( LinphoneCore *lc, LinphoneCall *call); -int linphone_core_set_as_current_call(LinphoneCore *lc, LinphoneCall *call); int linphone_core_get_calls_nb(const LinphoneCore *lc); void linphone_core_set_state(LinphoneCore *lc, LinphoneGlobalState gstate, const char *message); -void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *call); +void linphone_call_update_biggest_desc(LinphoneCall *call, SalMediaDescription *md); +void linphone_call_make_local_media_description(LinphoneCall *call); void linphone_call_make_local_media_description_with_params(LinphoneCore *lc, LinphoneCall *call, LinphoneCallParams *params); void linphone_call_increment_local_media_description(LinphoneCall *call); void linphone_call_fill_media_multicast_addr(LinphoneCall *call); -void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription *new_md); +void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription *new_md, LinphoneCallState target_state); bool_t linphone_core_is_payload_type_usable_for_bandwidth(LinphoneCore *lc, const PayloadType *pt, int bandwidth_limit); #define linphone_core_ready(lc) ((lc)->state==LinphoneGlobalOn || (lc)->state==LinphoneGlobalShutdown) -void _linphone_core_configure_resolver(); +void _linphone_core_configure_resolver(void); struct _EcCalibrator{ ms_thread_t thread; @@ -891,6 +1002,8 @@ LinphoneEcCalibratorStatus ec_calibrator_get_status(EcCalibrator *ecc); void ec_calibrator_destroy(EcCalibrator *ecc); void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapsed); +void linphone_call_set_broken(LinphoneCall *call); +void linphone_call_repair_if_broken(LinphoneCall *call); void linphone_core_preempt_sound_resources(LinphoneCore *lc); int _linphone_core_pause_call(LinphoneCore *lc, LinphoneCall *call); @@ -916,8 +1029,15 @@ void _linphone_core_codec_config_write(LinphoneCore *lc); #ifndef NB_MAX_CALLS #define NB_MAX_CALLS (10) #endif -void call_logs_read_from_config_file(LinphoneCore *lc); +LINPHONE_PUBLIC void call_logs_read_from_config_file(LinphoneCore *lc); void call_logs_write_to_config_file(LinphoneCore *lc); +void linphone_core_call_log_storage_init(LinphoneCore *lc); +void linphone_core_call_log_storage_close(LinphoneCore *lc); +void linphone_core_store_call_log(LinphoneCore *lc, LinphoneCallLog *log); +const MSList *linphone_core_get_call_history(LinphoneCore *lc); +LINPHONE_PUBLIC void linphone_core_delete_call_history(LinphoneCore *lc); +LINPHONE_PUBLIC void linphone_core_delete_call_log(LinphoneCore *lc, LinphoneCallLog *log); +LINPHONE_PUBLIC int linphone_core_get_call_history_size(LinphoneCore *lc); int linphone_core_get_edge_bw(LinphoneCore *lc); int linphone_core_get_edge_ptime(LinphoneCore *lc); @@ -925,8 +1045,12 @@ int linphone_core_get_edge_ptime(LinphoneCore *lc); int linphone_upnp_init(LinphoneCore *lc); void linphone_upnp_destroy(LinphoneCore *lc); +#if defined(MSG_STORAGE_ENABLED) || defined(CALL_LOGS_STORAGE_ENABLED) +int _linphone_sqlite3_open(const char *db_file, sqlite3 **db); +#endif + #ifdef MSG_STORAGE_ENABLED -sqlite3 * linphone_message_storage_init(); +sqlite3 * linphone_message_storage_init(void); void linphone_message_storage_init_chat_rooms(LinphoneCore *lc); #endif void linphone_chat_message_store_state(LinphoneChatMessage *msg); @@ -958,6 +1082,7 @@ void linphone_event_set_publish_state(LinphoneEvent *lev, LinphonePublishState s LinphoneSubscriptionState linphone_subscription_state_from_sal(SalSubscribeStatus ss); LinphoneContent *linphone_content_from_sal_body(const SalBody *ref); void linphone_core_invalidate_friend_subscriptions(LinphoneCore *lc); +void linphone_core_register_offer_answer_providers(LinphoneCore *lc); struct _LinphoneContent { @@ -979,6 +1104,83 @@ struct _LinphoneBuffer { BELLE_SIP_DECLARE_VPTR(LinphoneBuffer); +/***************************************************************************** + * XML-RPC interface * + ****************************************************************************/ + +typedef struct _LinphoneXmlRpcArg { + LinphoneXmlRpcArgType type; + union { + int i; + char *s; + } data; +} LinphoneXmlRpcArg; + +struct _LinphoneXmlRpcRequestCbs { + belle_sip_object_t base; + void *user_data; + LinphoneXmlRpcRequestCbsResponseCb response; +}; + +BELLE_SIP_DECLARE_VPTR(LinphoneXmlRpcRequestCbs); + +struct _LinphoneXmlRpcRequest { + belle_sip_object_t base; + void *user_data; + LinphoneXmlRpcRequestCbs *callbacks; + belle_sip_list_t *arg_list; + char *content; /**< The string representation of the XML-RPC request */ + char *method; + LinphoneXmlRpcStatus status; + LinphoneXmlRpcArg response; +}; + +BELLE_SIP_DECLARE_VPTR(LinphoneXmlRpcRequest); + +struct _LinphoneXmlRpcSession { + belle_sip_object_t base; + void *user_data; + LinphoneCore *core; + char *url; +}; + +BELLE_SIP_DECLARE_VPTR(LinphoneXmlRpcSession); + + +/***************************************************************************** + * Account creator interface * + ****************************************************************************/ + +struct _LinphoneAccountCreatorCbs { + belle_sip_object_t base; + void *user_data; + LinphoneAccountCreatorCbsExistenceTestedCb existence_tested; + LinphoneAccountCreatorCbsValidationTestedCb validation_tested; + LinphoneAccountCreatorCbsCreateAccountCb create_account; +}; + +BELLE_SIP_DECLARE_VPTR(LinphoneAccountCreatorCbs); + +struct _LinphoneAccountCreator { + belle_sip_object_t base; + void *user_data; + LinphoneAccountCreatorCbs *callbacks; + LinphoneXmlRpcSession *xmlrpc_session; + LinphoneCore *core; + char *xmlrpc_url; + char *username; + char *password; + char *domain; + char *route; + char *email; + bool_t subscribe_to_newsletter; + char *display_name; + LinphoneTransportType transport; +}; + +BELLE_SIP_DECLARE_VPTR(LinphoneAccountCreator); + + /***************************************************************************** * REMOTE PROVISIONING FUNCTIONS * ****************************************************************************/ @@ -1070,6 +1272,8 @@ MsZrtpCryptoTypesCount linphone_core_get_zrtp_sas_suites(LinphoneCore *lc, MSZrt */ BELLE_SIP_DECLARE_TYPES_BEGIN(linphone,10000) +BELLE_SIP_TYPE_ID(LinphoneAccountCreator), +BELLE_SIP_TYPE_ID(LinphoneAccountCreatorCbs), BELLE_SIP_TYPE_ID(LinphoneBuffer), BELLE_SIP_TYPE_ID(LinphoneContactProvider), BELLE_SIP_TYPE_ID(LinphoneContactSearch), @@ -1083,7 +1287,11 @@ BELLE_SIP_TYPE_ID(LinphoneContent), BELLE_SIP_TYPE_ID(LinphoneLDAPContactProvider), BELLE_SIP_TYPE_ID(LinphoneLDAPContactSearch), BELLE_SIP_TYPE_ID(LinphoneProxyConfig), -BELLE_SIP_TYPE_ID(LinphoneFriend) +BELLE_SIP_TYPE_ID(LinphoneFriend), +BELLE_SIP_TYPE_ID(LinphoneXmlRpcRequest), +BELLE_SIP_TYPE_ID(LinphoneXmlRpcRequestCbs), +BELLE_SIP_TYPE_ID(LinphoneXmlRpcSession), +BELLE_SIP_TYPE_ID(LinphoneTunnelConfig) BELLE_SIP_DECLARE_TYPES_END @@ -1181,9 +1389,15 @@ void v_table_reference_destroy(VTableReference *ref); void _linphone_core_add_listener(LinphoneCore *lc, LinphoneCoreVTable *vtable, bool_t autorelease); #ifdef VIDEO_ENABLED -MSWebCam *linphone_call_get_video_device(const LinphoneCall *call); -MSWebCam *get_nowebcam_device(); +LINPHONE_PUBLIC MSWebCam *linphone_call_get_video_device(const LinphoneCall *call); +MSWebCam *get_nowebcam_device(void); #endif +bool_t linphone_core_lime_for_file_sharing_enabled(const LinphoneCore *lc); + +BELLE_SIP_DECLARE_VPTR(LinphoneTunnelConfig); + +int linphone_core_get_default_proxy_config_index(LinphoneCore *lc); + #ifdef __cplusplus } #endif diff --git a/coreapi/proxy.c b/coreapi/proxy.c index 4283712d9..5bd819b9f 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -23,22 +23,23 @@ Copyright (C) 2000 Simon MORLAT (simon.morlat@linphone.org) #include "lpconfig.h" #include "private.h" #include "mediastreamer2/mediastream.h" +#include "enum.h" #include /*store current config related to server location*/ -static void linphone_proxy_config_store_server_config(LinphoneProxyConfig* obj) { - if (obj->saved_identity) linphone_address_destroy(obj->saved_identity); - if (obj->reg_identity) - obj->saved_identity = linphone_address_new(obj->reg_identity); +static void linphone_proxy_config_store_server_config(LinphoneProxyConfig* cfg) { + if (cfg->saved_identity) linphone_address_destroy(cfg->saved_identity); + if (cfg->identity_address) + cfg->saved_identity = linphone_address_clone(cfg->identity_address); else - obj->saved_identity = NULL; + cfg->saved_identity = NULL; - if (obj->saved_proxy) linphone_address_destroy(obj->saved_proxy); - if (obj->reg_proxy) - obj->saved_proxy = linphone_address_new(obj->reg_proxy); + if (cfg->saved_proxy) linphone_address_destroy(cfg->saved_proxy); + if (cfg->reg_proxy) + cfg->saved_proxy = linphone_address_new(cfg->reg_proxy); else - obj->saved_proxy = NULL; + cfg->saved_proxy = NULL; } LinphoneProxyConfigAddressComparisonResult linphone_proxy_config_address_equal(const LinphoneAddress *a, const LinphoneAddress *b) { @@ -59,17 +60,16 @@ LinphoneProxyConfigAddressComparisonResult linphone_proxy_config_address_equal(c return LinphoneProxyConfigAddressDifferent; /*either username, domain or port ar not equals*/ } -LinphoneProxyConfigAddressComparisonResult linphone_proxy_config_is_server_config_changed(const LinphoneProxyConfig* obj) { - LinphoneAddress *current_identity=obj->reg_identity?linphone_address_new(obj->reg_identity):NULL; - LinphoneAddress *current_proxy=obj->reg_proxy?linphone_address_new(obj->reg_proxy):NULL; +LinphoneProxyConfigAddressComparisonResult linphone_proxy_config_is_server_config_changed(const LinphoneProxyConfig* cfg) { + LinphoneAddress *current_proxy=cfg->reg_proxy?linphone_address_new(cfg->reg_proxy):NULL; LinphoneProxyConfigAddressComparisonResult result_identity; LinphoneProxyConfigAddressComparisonResult result; - result = linphone_proxy_config_address_equal(obj->saved_identity,current_identity); + result = linphone_proxy_config_address_equal(cfg->saved_identity,cfg->identity_address); if (result == LinphoneProxyConfigAddressDifferent) goto end; result_identity = result; - result = linphone_proxy_config_address_equal(obj->saved_proxy,current_proxy); + result = linphone_proxy_config_address_equal(cfg->saved_proxy,current_proxy); if (result == LinphoneProxyConfigAddressDifferent) goto end; /** If the proxies are equal use the result of the difference between the identities, * otherwise the result is weak-equal and so weak-equal must be returned even if the @@ -78,7 +78,6 @@ LinphoneProxyConfigAddressComparisonResult linphone_proxy_config_is_server_confi if (result == LinphoneProxyConfigAddressEqual) result = result_identity; end: - if (current_identity) linphone_address_destroy(current_identity); if (current_proxy) linphone_address_destroy(current_proxy); return result; } @@ -94,10 +93,10 @@ void linphone_proxy_config_write_all_to_config_file(LinphoneCore *lc){ } /*to ensure removed configs are erased:*/ linphone_proxy_config_write_to_config_file(lc->config,NULL,i); - lp_config_set_int(lc->config,"sip","default_proxy",linphone_core_get_default_proxy(lc,NULL)); + lp_config_set_int(lc->config,"sip","default_proxy",linphone_core_get_default_proxy_config_index(lc)); } -static void linphone_proxy_config_init(LinphoneCore* lc, LinphoneProxyConfig *obj) { +static void linphone_proxy_config_init(LinphoneCore* lc, LinphoneProxyConfig *cfg) { const char *dial_prefix = lc ? lp_config_get_default_string(lc->config,"proxy","dial_prefix",NULL) : NULL; const char *identity = lc ? lp_config_get_default_string(lc->config, "proxy", "reg_identity", NULL) : NULL; const char *proxy = lc ? lp_config_get_default_string(lc->config, "proxy", "reg_proxy", NULL) : NULL; @@ -107,40 +106,31 @@ static void linphone_proxy_config_init(LinphoneCore* lc, LinphoneProxyConfig *ob const char *contact_params = lc ? lp_config_get_default_string(lc->config, "proxy", "contact_parameters", NULL) : NULL; const char *contact_uri_params = lc ? lp_config_get_default_string(lc->config, "proxy", "contact_uri_parameters", NULL) : NULL; - obj->expires = lc ? lp_config_get_default_int(lc->config, "proxy", "reg_expires", 3600) : 3600; - obj->reg_sendregister = lc ? lp_config_get_default_int(lc->config, "proxy", "reg_sendregister", 1) : 1; - obj->dial_prefix = dial_prefix ? ms_strdup(dial_prefix) : NULL; - obj->dial_escape_plus = lc ? lp_config_get_default_int(lc->config, "proxy", "dial_escape_plus", 0) : 0; - obj->privacy = lc ? lp_config_get_default_int(lc->config, "proxy", "privacy", LinphonePrivacyDefault) : LinphonePrivacyDefault; - obj->reg_identity = identity ? ms_strdup(identity) : NULL; - obj->reg_proxy = proxy ? ms_strdup(proxy) : NULL; - obj->reg_route = route ? ms_strdup(route) : NULL; - obj->domain = NULL; - obj->realm = realm ? ms_strdup(realm) : NULL; - obj->quality_reporting_enabled = lc ? lp_config_get_default_int(lc->config, "proxy", "quality_reporting_enabled", 0) : 0; - obj->quality_reporting_collector = quality_reporting_collector ? ms_strdup(quality_reporting_collector) : NULL; - obj->quality_reporting_interval = lc ? lp_config_get_default_int(lc->config, "proxy", "quality_reporting_interval", 0) : 0; - obj->contact_params = contact_params ? ms_strdup(contact_params) : NULL; - obj->contact_uri_params = contact_uri_params ? ms_strdup(contact_uri_params) : NULL; - obj->avpf_mode = lc ? lp_config_get_default_int(lc->config, "proxy", "avpf", LinphoneAVPFDefault) : LinphoneAVPFDefault; - obj->avpf_rr_interval = lc ? lp_config_get_default_int(lc->config, "proxy", "avpf_rr_interval", 5) : 5; - obj->publish_expires=-1; + cfg->expires = lc ? lp_config_get_default_int(lc->config, "proxy", "reg_expires", 3600) : 3600; + cfg->reg_sendregister = lc ? lp_config_get_default_int(lc->config, "proxy", "reg_sendregister", 1) : 1; + cfg->dial_prefix = dial_prefix ? ms_strdup(dial_prefix) : NULL; + cfg->dial_escape_plus = lc ? lp_config_get_default_int(lc->config, "proxy", "dial_escape_plus", 0) : 0; + cfg->privacy = lc ? lp_config_get_default_int(lc->config, "proxy", "privacy", LinphonePrivacyDefault) : LinphonePrivacyDefault; + cfg->identity_address = identity ? linphone_address_new(identity) : NULL; + cfg->reg_identity = cfg->identity_address ? linphone_address_as_string(cfg->identity_address) : NULL; + cfg->reg_proxy = proxy ? ms_strdup(proxy) : NULL; + cfg->reg_route = route ? ms_strdup(route) : NULL; + cfg->realm = realm ? ms_strdup(realm) : NULL; + cfg->quality_reporting_enabled = lc ? lp_config_get_default_int(lc->config, "proxy", "quality_reporting_enabled", 0) : 0; + cfg->quality_reporting_collector = quality_reporting_collector ? ms_strdup(quality_reporting_collector) : NULL; + cfg->quality_reporting_interval = lc ? lp_config_get_default_int(lc->config, "proxy", "quality_reporting_interval", 0) : 0; + cfg->contact_params = contact_params ? ms_strdup(contact_params) : NULL; + cfg->contact_uri_params = contact_uri_params ? ms_strdup(contact_uri_params) : NULL; + cfg->avpf_mode = lc ? lp_config_get_default_int(lc->config, "proxy", "avpf", LinphoneAVPFDefault) : LinphoneAVPFDefault; + cfg->avpf_rr_interval = lc ? lp_config_get_default_int(lc->config, "proxy", "avpf_rr_interval", 5) : 5; + cfg->publish_expires=-1; } -/** - * @addtogroup proxies - * @{ -**/ - -/** - * @deprecated, use #linphone_core_create_proxy_config instead - *Creates an empty proxy config. -**/ LinphoneProxyConfig *linphone_proxy_config_new() { return linphone_core_create_proxy_config(NULL); } -static void _linphone_proxy_config_destroy(LinphoneProxyConfig *obj); +static void _linphone_proxy_config_destroy(LinphoneProxyConfig *cfg); BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneProxyConfig); @@ -152,47 +142,41 @@ BELLE_SIP_INSTANCIATE_VPTR(LinphoneProxyConfig, belle_sip_object_t, ); LinphoneProxyConfig * linphone_core_create_proxy_config(LinphoneCore *lc) { - LinphoneProxyConfig *obj = belle_sip_object_new(LinphoneProxyConfig); - linphone_proxy_config_init(lc,obj); - return obj; + LinphoneProxyConfig *cfg = belle_sip_object_new(LinphoneProxyConfig); + linphone_proxy_config_init(lc,cfg); + return cfg; } -void _linphone_proxy_config_release_ops(LinphoneProxyConfig *obj){ - if (obj->op) { - sal_op_release(obj->op); - obj->op=NULL; +void _linphone_proxy_config_release_ops(LinphoneProxyConfig *cfg){ + if (cfg->op) { + sal_op_release(cfg->op); + cfg->op=NULL; } - if (obj->publish_op){ - sal_op_release(obj->publish_op); - obj->publish_op=NULL; + if (cfg->publish_op){ + sal_op_release(cfg->publish_op); + cfg->publish_op=NULL; } } -void _linphone_proxy_config_destroy(LinphoneProxyConfig *obj){ - if (obj->reg_proxy!=NULL) ms_free(obj->reg_proxy); - if (obj->reg_identity!=NULL) ms_free(obj->reg_identity); - if (obj->reg_route!=NULL) ms_free(obj->reg_route); - if (obj->quality_reporting_collector!=NULL) ms_free(obj->quality_reporting_collector); - if (obj->ssctx!=NULL) sip_setup_context_free(obj->ssctx); - if (obj->domain!=NULL) ms_free(obj->domain); - if (obj->realm!=NULL) ms_free(obj->realm); - if (obj->type!=NULL) ms_free(obj->type); - if (obj->dial_prefix!=NULL) ms_free(obj->dial_prefix); - if (obj->contact_params) ms_free(obj->contact_params); - if (obj->contact_uri_params) ms_free(obj->contact_uri_params); - if (obj->saved_proxy!=NULL) linphone_address_destroy(obj->saved_proxy); - if (obj->saved_identity!=NULL) linphone_address_destroy(obj->saved_identity); - if (obj->sent_headers!=NULL) sal_custom_header_free(obj->sent_headers); - _linphone_proxy_config_release_ops(obj); +void _linphone_proxy_config_destroy(LinphoneProxyConfig *cfg){ + if (cfg->reg_proxy!=NULL) ms_free(cfg->reg_proxy); + if (cfg->reg_identity!=NULL) ms_free(cfg->reg_identity); + if (cfg->identity_address!=NULL) linphone_address_destroy(cfg->identity_address); + if (cfg->reg_route!=NULL) ms_free(cfg->reg_route); + if (cfg->quality_reporting_collector!=NULL) ms_free(cfg->quality_reporting_collector); + if (cfg->ssctx!=NULL) sip_setup_context_free(cfg->ssctx); + if (cfg->realm!=NULL) ms_free(cfg->realm); + if (cfg->type!=NULL) ms_free(cfg->type); + if (cfg->dial_prefix!=NULL) ms_free(cfg->dial_prefix); + if (cfg->contact_params) ms_free(cfg->contact_params); + if (cfg->contact_uri_params) ms_free(cfg->contact_uri_params); + if (cfg->saved_proxy!=NULL) linphone_address_destroy(cfg->saved_proxy); + if (cfg->saved_identity!=NULL) linphone_address_destroy(cfg->saved_identity); + if (cfg->sent_headers!=NULL) sal_custom_header_free(cfg->sent_headers); + if (cfg->pending_contact) linphone_address_unref(cfg->pending_contact); + _linphone_proxy_config_release_ops(cfg); } -/** - * Destroys a proxy config. - * @deprecated - * - * @note: LinphoneProxyConfig that have been removed from LinphoneCore with - * linphone_core_remove_proxy_config() must not be freed. -**/ void linphone_proxy_config_destroy(LinphoneProxyConfig *cfg) { belle_sip_object_unref(cfg); } @@ -211,28 +195,16 @@ void linphone_proxy_config_unref(LinphoneProxyConfig *cfg) { belle_sip_object_unref(cfg); } -/** - * Returns a boolean indicating that the user is sucessfully registered on the proxy. - * @deprecated Use linphone_proxy_config_get_state() instead. -**/ -bool_t linphone_proxy_config_is_registered(const LinphoneProxyConfig *obj){ - return obj->state == LinphoneRegistrationOk; +bool_t linphone_proxy_config_is_registered(const LinphoneProxyConfig *cfg){ + return cfg->state == LinphoneRegistrationOk; } -/** - * Sets the proxy address - * - * Examples of valid sip proxy address are: - * - IP address: sip:87.98.157.38 - * - IP address with port: sip:87.98.157.38:5062 - * - hostnames : sip:sip.example.net -**/ -int linphone_proxy_config_set_server_addr(LinphoneProxyConfig *obj, const char *server_addr){ +int linphone_proxy_config_set_server_addr(LinphoneProxyConfig *cfg, const char *server_addr){ LinphoneAddress *addr=NULL; char *modified=NULL; - if (obj->reg_proxy!=NULL) ms_free(obj->reg_proxy); - obj->reg_proxy=NULL; + if (cfg->reg_proxy!=NULL) ms_free(cfg->reg_proxy); + cfg->reg_proxy=NULL; if (server_addr!=NULL && strlen(server_addr)>0){ if (strstr(server_addr,"sip:")==NULL && strstr(server_addr,"sips:")==NULL){ @@ -243,7 +215,7 @@ int linphone_proxy_config_set_server_addr(LinphoneProxyConfig *obj, const char * if (addr==NULL) addr=linphone_address_new(server_addr); if (addr){ - obj->reg_proxy=linphone_address_as_string(addr); + cfg->reg_proxy=linphone_address_as_string(addr); linphone_address_destroy(addr); }else{ ms_warning("Could not parse %s",server_addr); @@ -253,55 +225,45 @@ int linphone_proxy_config_set_server_addr(LinphoneProxyConfig *obj, const char * return 0; } -/** - * Sets the user identity as a SIP address. - * - * This identity is normally formed with display name, username and domain, such - * as: - * Alice - * The REGISTER messages will have from and to set to this identity. - * -**/ -int linphone_proxy_config_set_identity(LinphoneProxyConfig *obj, const char *identity){ - LinphoneAddress *addr; + +int linphone_proxy_config_set_identity_address(LinphoneProxyConfig *cfg, const LinphoneAddress *addr){ + if (!addr || linphone_address_get_username(addr)==NULL){ + char* as_string = addr ? linphone_address_as_string(addr) : ms_strdup("NULL"); + ms_warning("Invalid sip identity: %s", as_string); + ms_free(as_string); + return -1; + } + if (cfg->identity_address != NULL) { + linphone_address_destroy(cfg->identity_address); + } + cfg->identity_address=linphone_address_clone(addr); + + if (cfg->reg_identity!=NULL) { + ms_free(cfg->reg_identity); + } + cfg->reg_identity= linphone_address_as_string(cfg->identity_address); + return 0; +} + +int linphone_proxy_config_set_identity(LinphoneProxyConfig *cfg, const char *identity){ if (identity!=NULL && strlen(identity)>0){ - addr=linphone_address_new(identity); - if (!addr || linphone_address_get_username(addr)==NULL){ - ms_warning("Invalid sip identity: %s",identity); - if (addr) - linphone_address_destroy(addr); - return -1; - }else{ - if (obj->reg_identity!=NULL) { - ms_free(obj->reg_identity); - obj->reg_identity=NULL; - } - obj->reg_identity=ms_strdup(identity); - if (obj->domain){ - ms_free(obj->domain); - } - obj->domain=ms_strdup(linphone_address_get_domain(addr)); - linphone_address_destroy(addr); - return 0; - } + LinphoneAddress *addr=linphone_address_new(identity); + int ret=linphone_proxy_config_set_identity_address(cfg, addr); + if (addr) linphone_address_destroy(addr); + return ret; } return -1; } const char *linphone_proxy_config_get_domain(const LinphoneProxyConfig *cfg){ - return cfg->domain; + return cfg->identity_address ? linphone_address_get_domain(cfg->identity_address) : NULL; } -/** - * Sets a SIP route. - * When a route is set, all outgoing calls will go to the route's destination if this proxy - * is the default one (see linphone_core_set_default_proxy() ). -**/ -int linphone_proxy_config_set_route(LinphoneProxyConfig *obj, const char *route) +int linphone_proxy_config_set_route(LinphoneProxyConfig *cfg, const char *route) { - if (obj->reg_route!=NULL){ - ms_free(obj->reg_route); - obj->reg_route=NULL; + if (cfg->reg_route!=NULL){ + ms_free(cfg->reg_route); + cfg->reg_route=NULL; } if (route!=NULL && route[0] !='\0'){ SalAddress *addr; @@ -313,23 +275,25 @@ int linphone_proxy_config_set_route(LinphoneProxyConfig *obj, const char *route) addr=sal_address_new(tmp); if (addr!=NULL){ sal_address_destroy(addr); + cfg->reg_route=tmp; + return 0; }else{ ms_free(tmp); - tmp=NULL; + return -1; } - obj->reg_route=tmp; + } else { + return 0; } - return 0; } -bool_t linphone_proxy_config_check(LinphoneCore *lc, LinphoneProxyConfig *obj){ - if (obj->reg_proxy==NULL){ +bool_t linphone_proxy_config_check(LinphoneCore *lc, LinphoneProxyConfig *cfg){ + if (cfg->reg_proxy==NULL){ if (lc) linphone_core_notify_display_warning(lc,_("The sip proxy address you entered is invalid, it must start with \"sip:\"" " followed by a hostname.")); return FALSE; } - if (obj->reg_identity==NULL){ + if (cfg->identity_address==NULL){ if (lc) linphone_core_notify_display_warning(lc,_("The sip identity you entered is invalid.\nIt should look like " "sip:username@proxydomain, such as sip:alice@example.net")); @@ -338,79 +302,68 @@ bool_t linphone_proxy_config_check(LinphoneCore *lc, LinphoneProxyConfig *obj){ return TRUE; } -/** - * Indicates whether a REGISTER request must be sent to the proxy. -**/ -void linphone_proxy_config_enableregister(LinphoneProxyConfig *obj, bool_t val){ - obj->reg_sendregister=val; +void linphone_proxy_config_enableregister(LinphoneProxyConfig *cfg, bool_t val){ + cfg->reg_sendregister=val; } -/** - * Sets the registration expiration time in seconds. -**/ -void linphone_proxy_config_set_expires(LinphoneProxyConfig *obj, int val){ +void linphone_proxy_config_set_expires(LinphoneProxyConfig *cfg, int val){ if (val<0) val=600; - obj->expires=val; + cfg->expires=val; } -void linphone_proxy_config_enable_publish(LinphoneProxyConfig *obj, bool_t val){ - obj->publish=val; +void linphone_proxy_config_enable_publish(LinphoneProxyConfig *cfg, bool_t val){ + cfg->publish=val; } -/** - * Prevent a proxy config from refreshing its registration. - * This is useful to let registrations to expire naturally (or) when the application wants to keep control on when - * refreshes are sent. - * However, linphone_core_set_network_reachable(lc,TRUE) will always request the proxy configs to refresh their registrations. - * The refreshing operations can be resumed with linphone_proxy_config_refresh_register(). - * @param obj the proxy config -**/ -void linphone_proxy_config_pause_register(LinphoneProxyConfig *obj){ - if (obj->op) sal_op_stop_refreshing(obj->op); +void linphone_proxy_config_pause_register(LinphoneProxyConfig *cfg){ + if (cfg->op) sal_op_stop_refreshing(cfg->op); } -/** - * Starts editing a proxy configuration. - * - * Because proxy configuration must be consistent, applications MUST - * call linphone_proxy_config_edit() before doing any attempts to modify - * proxy configuration (such as identity, proxy address and so on). - * Once the modifications are done, then the application must call - * linphone_proxy_config_done() to commit the changes. -**/ -void linphone_proxy_config_edit(LinphoneProxyConfig *obj){ - if (obj->publish && obj->publish_op){ - /*unpublish*/ - sal_publish_presence(obj->publish_op,NULL,NULL,0,(SalPresenceModel *)NULL); - sal_op_release(obj->publish_op); - obj->publish_op=NULL; +void linphone_proxy_config_edit(LinphoneProxyConfig *cfg){ + if (cfg->publish && cfg->publish_op){ + /*unpublish*/ + sal_publish_presence(cfg->publish_op,NULL,NULL,0,(SalPresenceModel *)NULL); + sal_op_release(cfg->publish_op); + cfg->publish_op=NULL; } /*store current config related to server location*/ - linphone_proxy_config_store_server_config(obj); + linphone_proxy_config_store_server_config(cfg); /*stop refresher in any case*/ - linphone_proxy_config_pause_register(obj); + linphone_proxy_config_pause_register(cfg); } -void linphone_proxy_config_apply(LinphoneProxyConfig *obj,LinphoneCore *lc){ - obj->lc=lc; - linphone_proxy_config_done(obj); +void linphone_proxy_config_apply(LinphoneProxyConfig *cfg,LinphoneCore *lc){ + cfg->lc=lc; + linphone_proxy_config_done(cfg); } -void linphone_proxy_config_stop_refreshing(LinphoneProxyConfig *obj){ - if (obj->publish_op){ - sal_op_release(obj->publish_op); - obj->publish_op=NULL; +void linphone_proxy_config_stop_refreshing(LinphoneProxyConfig * cfg){ + LinphoneAddress *contact_addr=NULL; + if ( cfg->op + && cfg->state == LinphoneRegistrationOk + && (contact_addr = (LinphoneAddress*)sal_op_get_contact_address(cfg->op)) + && linphone_address_get_transport(contact_addr) != LinphoneTransportUdp /*with udp, there is a risk of port reuse, so I prefer to not do anything for now*/) { + /*need to save current contact in order to reset is later*/ + linphone_address_ref(contact_addr); + if (cfg->pending_contact) + linphone_address_unref(cfg->pending_contact); + cfg->pending_contact=contact_addr; + } - if (obj->op){ - sal_op_release(obj->op); - obj->op=NULL; + if (cfg->publish_op){ + sal_op_release(cfg->publish_op); + cfg->publish_op=NULL; + } + if (cfg->op){ + sal_op_release(cfg->op); + cfg->op=NULL; } } -LinphoneAddress *guess_contact_for_register(LinphoneProxyConfig *obj){ +LinphoneAddress *guess_contact_for_register(LinphoneProxyConfig *cfg){ LinphoneAddress *ret=NULL; - LinphoneAddress *proxy=linphone_address_new(obj->reg_proxy); + LinphoneAddress *proxy=linphone_address_new(cfg->reg_proxy); const char *host; if (proxy==NULL) return NULL; @@ -418,22 +371,22 @@ LinphoneAddress *guess_contact_for_register(LinphoneProxyConfig *obj){ if (host!=NULL){ int localport = -1; const char *localip = NULL; - LinphoneAddress *contact=linphone_address_new(obj->reg_identity); + LinphoneAddress *contact=linphone_address_clone(cfg->identity_address); linphone_address_clean(contact); - if (obj->contact_params) { + if (cfg->contact_params) { // We want to add a list of contacts params to the linphone address - sal_address_set_params(contact,obj->contact_params); + sal_address_set_params(contact,cfg->contact_params); } - if (obj->contact_uri_params){ - sal_address_set_uri_params(contact,obj->contact_uri_params); + if (cfg->contact_uri_params){ + sal_address_set_uri_params(contact,cfg->contact_uri_params); } #ifdef BUILD_UPNP - if (obj->lc->upnp != NULL && linphone_core_get_firewall_policy(obj->lc)==LinphonePolicyUseUpnp && - linphone_upnp_context_get_state(obj->lc->upnp) == LinphoneUpnpStateOk) { - localip = linphone_upnp_context_get_external_ipaddress(obj->lc->upnp); - localport = linphone_upnp_context_get_external_port(obj->lc->upnp); + if (cfg->lc->upnp != NULL && linphone_core_get_firewall_policy(cfg->lc)==LinphonePolicyUseUpnp && + linphone_upnp_context_get_state(cfg->lc->upnp) == LinphoneUpnpStateOk) { + localip = linphone_upnp_context_get_external_ipaddress(cfg->lc->upnp); + localport = linphone_upnp_context_get_external_port(cfg->lc->upnp); } #endif //BUILD_UPNP linphone_address_set_port(contact,localport); @@ -446,73 +399,65 @@ LinphoneAddress *guess_contact_for_register(LinphoneProxyConfig *obj){ return ret; } -/** - * unregister without moving the register_enable flag - */ void _linphone_proxy_config_unregister(LinphoneProxyConfig *obj) { - if (obj->op && obj->state == LinphoneRegistrationOk) { + if (obj->op && (obj->state == LinphoneRegistrationOk || + (obj->state == LinphoneRegistrationProgress && obj->expires != 0))) { sal_unregister(obj->op); } } -static void linphone_proxy_config_register(LinphoneProxyConfig *obj){ - if (obj->reg_sendregister){ - LinphoneAddress* proxy=linphone_address_new(obj->reg_proxy); - LinphoneAddress* to=linphone_address_new(obj->reg_identity); +static void linphone_proxy_config_register(LinphoneProxyConfig *cfg){ + if (cfg->reg_sendregister){ + LinphoneAddress* proxy=linphone_address_new(cfg->reg_proxy); char* proxy_string; + char * from = linphone_address_as_string(cfg->identity_address); LinphoneAddress *contact; - ms_message("LinphoneProxyConfig [%p] about to register (LinphoneCore version: %s)",obj,linphone_core_get_version()); + ms_message("LinphoneProxyConfig [%p] about to register (LinphoneCore version: %s)",cfg,linphone_core_get_version()); proxy_string=linphone_address_as_string_uri_only(proxy); linphone_address_destroy(proxy); - if (obj->op) - sal_op_release(obj->op); - obj->op=sal_op_new(obj->lc->sal); + if (cfg->op) + sal_op_release(cfg->op); + cfg->op=sal_op_new(cfg->lc->sal); - linphone_configure_op(obj->lc, obj->op, to, obj->sent_headers, FALSE); - linphone_address_destroy(to); + linphone_configure_op(cfg->lc, cfg->op, cfg->identity_address, cfg->sent_headers, FALSE); - if ((contact=guess_contact_for_register(obj))) { - sal_op_set_contact_address(obj->op,contact); + if ((contact=guess_contact_for_register(cfg))) { + sal_op_set_contact_address(cfg->op,contact); linphone_address_destroy(contact); } - sal_op_set_user_pointer(obj->op,obj); + sal_op_set_user_pointer(cfg->op,cfg); - if (sal_register(obj->op,proxy_string,obj->reg_identity,obj->expires)==0) { - linphone_proxy_config_set_state(obj,LinphoneRegistrationProgress,"Registration in progress"); + if (sal_register(cfg->op,proxy_string, cfg->reg_identity, cfg->expires, cfg->pending_contact)==0) { + if (cfg->pending_contact) { + linphone_address_unref(cfg->pending_contact); + cfg->pending_contact=NULL; + } + linphone_proxy_config_set_state(cfg,LinphoneRegistrationProgress,"Registration in progress"); } else { - linphone_proxy_config_set_state(obj,LinphoneRegistrationFailed,"Registration failed"); + linphone_proxy_config_set_state(cfg,LinphoneRegistrationFailed,"Registration failed"); } ms_free(proxy_string); + ms_free(from); } else { /* unregister if registered*/ - if (obj->state == LinphoneRegistrationProgress) { - linphone_proxy_config_set_state(obj,LinphoneRegistrationCleared,"Registration cleared"); + if (cfg->state == LinphoneRegistrationProgress) { + linphone_proxy_config_set_state(cfg,LinphoneRegistrationCleared,"Registration cleared"); } - _linphone_proxy_config_unregister(obj); + _linphone_proxy_config_unregister(cfg); } } -/** - * Refresh a proxy registration. - * This is useful if for example you resuming from suspend, thus IP address may have changed. -**/ -void linphone_proxy_config_refresh_register(LinphoneProxyConfig *obj){ - if (obj->reg_sendregister && obj->op && obj->state!=LinphoneRegistrationProgress){ - if (sal_register_refresh(obj->op,obj->expires) == 0) { - linphone_proxy_config_set_state(obj,LinphoneRegistrationProgress, "Refresh registration"); +void linphone_proxy_config_refresh_register(LinphoneProxyConfig *cfg){ + if (cfg->reg_sendregister && cfg->op && cfg->state!=LinphoneRegistrationProgress){ + if (sal_register_refresh(cfg->op,cfg->expires) == 0) { + linphone_proxy_config_set_state(cfg,LinphoneRegistrationProgress, "Refresh registration"); } } } -/** - * 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, without "+". - * -**/ void linphone_proxy_config_set_dial_prefix(LinphoneProxyConfig *cfg, const char *prefix){ if (cfg->dial_prefix!=NULL){ ms_free(cfg->dial_prefix); @@ -521,29 +466,14 @@ void linphone_proxy_config_set_dial_prefix(LinphoneProxyConfig *cfg, const char if (prefix && prefix[0]!='\0') cfg->dial_prefix=ms_strdup(prefix); } -/** - * Returns dialing prefix. - * - * -**/ const char *linphone_proxy_config_get_dial_prefix(const LinphoneProxyConfig *cfg){ return cfg->dial_prefix; } -/** - * Sets whether liblinphone should replace "+" by international calling prefix in dialed numbers (passed to - * #linphone_core_invite ). - * -**/ void linphone_proxy_config_set_dial_escape_plus(LinphoneProxyConfig *cfg, bool_t val){ cfg->dial_escape_plus=val; } -/** - * Returns whether liblinphone should replace "+" by "00" in dialed numbers (passed to - * #linphone_core_invite ). - * -**/ bool_t linphone_proxy_config_get_dial_escape_plus(const LinphoneProxyConfig *cfg){ return cfg->dial_escape_plus; } @@ -553,8 +483,7 @@ void linphone_proxy_config_enable_quality_reporting(LinphoneProxyConfig *cfg, bo } bool_t linphone_proxy_config_quality_reporting_enabled(LinphoneProxyConfig *cfg){ - // ensure that collector address is set too! - return cfg->quality_reporting_enabled && cfg->quality_reporting_collector != NULL; + return cfg->quality_reporting_enabled; } void linphone_proxy_config_set_quality_reporting_interval(LinphoneProxyConfig *cfg, uint8_t interval) { @@ -568,7 +497,7 @@ int linphone_proxy_config_get_quality_reporting_interval(LinphoneProxyConfig *cf void linphone_proxy_config_set_quality_reporting_collector(LinphoneProxyConfig *cfg, const char *collector){ if (collector!=NULL && strlen(collector)>0){ LinphoneAddress *addr=linphone_address_new(collector); - if (!addr || linphone_address_get_username(addr)==NULL){ + if (!addr){ ms_error("Invalid SIP collector URI: %s. Quality reporting will be DISABLED.",collector); } else { if (cfg->quality_reporting_collector != NULL){ @@ -601,9 +530,8 @@ typedef struct dial_plan{ }dial_plan_t; -/* TODO: fill with information for all countries over the world*/ - static dial_plan_t const dial_plans[]={ + //Country , iso country code, e164 country calling code, number length, international usual prefix {"Afghanistan" ,"AF" , "93" , 9 , "00" }, {"Albania" ,"AL" , "355" , 9 , "00" }, {"Algeria" ,"DZ" , "213" , 9 , "00" }, @@ -651,7 +579,7 @@ static dial_plan_t const dial_plans[]={ {"Congo Democratic Republic" ,"CD" , "243" , 9 , "00" }, {"Cook Islands" ,"CK" , "682" , 5 , "00" }, {"Costa Rica" ,"CR" , "506" , 8 , "00" }, - {"C�te d'Ivoire" ,"AD" , "225" , 8 , "00" }, + {"Cote d'Ivoire" ,"AD" , "225" , 8 , "00" }, {"Croatia" ,"HR" , "385" , 9 , "00" }, {"Cuba" ,"CU" , "53" , 8 , "119" }, {"Cyprus" ,"CY" , "357" , 8 , "00" }, @@ -701,6 +629,7 @@ static dial_plan_t const dial_plans[]={ {"Ireland" ,"IE" , "353" , 9 , "00" }, {"Israel" ,"IL" , "972" , 9 , "00" }, {"Italy" ,"IT" , "39" , 10 , "00" }, +/* {"Jersey" ,"JE" , "44" , 10 , "00" },*/ {"Jamaica" ,"JM" , "1" , 10 , "011" }, {"Japan" ,"JP" , "81" , 10 , "010" }, {"Jordan" ,"JO" , "962" , 9 , "00" }, @@ -780,7 +709,7 @@ static dial_plan_t const dial_plans[]={ {"Saint Vincent and the Grenadines","VC" , "1" , 10 , "011" }, {"Samoa" ,"WS" , "685" , 7 , "0" }, {"San Marino" ,"SM" , "378" , 10 , "00" }, - {"S�o Tom� and Pr�ncipe" ,"ST" , "239" , 7 , "00" }, + {"Sao Tome and Principe" ,"ST" , "239" , 7 , "00" }, {"Saudi Arabia" ,"SA" , "966" , 9 , "00" }, {"Senegal" ,"SN" , "221" , 9 , "00" }, {"Serbia" ,"RS" , "381" , 9 , "00" }, @@ -816,7 +745,8 @@ static dial_plan_t const dial_plans[]={ {"Uganda" ,"UG" , "256" , 9 , "000" }, {"Ukraine" ,"UA" , "380" , 9 , "00" }, {"United Arab Emirates" ,"AE" , "971" , 9 , "00" }, - {"United Kingdom" ,"UK" , "44" , 10 , "00" }, + {"United Kingdom" ,"GB" , "44" , 10 , "00" }, +/* {"United Kingdom" ,"UK" , "44" , 10 , "00" },*/ {"United States" ,"US" , "1" , 10 , "011" }, {"Uruguay" ,"UY" , "598" , 8 , "00" }, {"Uzbekistan" ,"UZ" , "998" , 9 , "8" }, @@ -867,38 +797,41 @@ int linphone_dial_plan_lookup_ccc_from_iso(const char* iso) { return -1; } -static void lookup_dial_plan(const char *ccc, dial_plan_t *plan){ +static bool_t lookup_dial_plan_by_ccc(const char *ccc, dial_plan_t *plan){ int i; for(i=0;dial_plans[i].country!=NULL;++i){ if (strcmp(ccc,dial_plans[i].ccc)==0){ *plan=dial_plans[i]; - return; + return TRUE; } } /*else return a generic "most common" dial plan*/ *plan=most_common_dialplan; strcpy(plan->ccc,ccc); + return FALSE; } bool_t linphone_proxy_config_is_phone_number(LinphoneProxyConfig *proxy, const char *username){ const char *p; for(p=username;*p!='\0';++p){ if (isdigit(*p) || - *p==' ' || - *p=='.' || - *p=='-' || - *p==')' || + *p==' ' || + *p=='.' || + *p=='-' || + *p==')' || *p=='(' || *p=='/' || *p=='+' || - (unsigned char)*p== 0xca // non-breakable space (iOS uses it to format contacts phone number) - ) + (unsigned char)*p==0xca || (unsigned char)*p==0xc2 || (unsigned char)*p==0xa0 // non-breakable space (iOS uses it to format contacts phone number) + ) { continue; + } return FALSE; } return TRUE; } +//remove anything but [0-9] and + static char *flatten_number(const char *number){ char *result=ms_malloc0(strlen(number)+1); char *w=result; @@ -912,116 +845,165 @@ static char *flatten_number(const char *number){ return result; } -static void replace_plus(const char *src, char *dest, size_t destlen, const char *icp){ - int i=0; - - if (icp && src[0]=='+' && (destlen>(i=strlen(icp))) ){ - src++; - 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-1); - }else{ - dial_plan_t dialplan; - lookup_dial_plan(proxy->dial_prefix,&dialplan); - ms_debug("Using dialplan '%s'",dialplan.country); - if (flatten[0]=='+'){ - /* the number has international prefix or +, so nothing to do*/ +char* linphone_proxy_config_normalize_phone_number(LinphoneProxyConfig *proxy, const char *username) { + LinphoneProxyConfig *tmpproxy = proxy ? proxy : linphone_proxy_config_new(); + char* result = NULL; + if (linphone_proxy_config_is_phone_number(tmpproxy, username)){ + dial_plan_t dialplan = {0}; + char * flatten=flatten_number(username); + ms_debug("Flattened number is '%s' for '%s'",flatten, username); + + /*if proxy has a dial prefix, modify phonenumber accordingly*/ + if (tmpproxy->dial_prefix!=NULL && tmpproxy->dial_prefix[0]!='\0'){ + lookup_dial_plan_by_ccc(tmpproxy->dial_prefix,&dialplan); + ms_debug("Using dial plan '%s'",dialplan.country); + /* the number already starts with + or international prefix*/ + if (flatten[0]=='+'||strstr(flatten,dialplan.icp)==flatten){ ms_debug("Prefix already present."); - /*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); - }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); + if (tmpproxy->dial_escape_plus) { + result = replace_plus_with_icp(flatten,dialplan.icp); + } else { + result = replace_icp_with_plus(flatten,dialplan.icp); + } }else{ - int numlen; - int i=0; - int skip; - numlen=strlen(flatten); - /*keep at most national number significant digits */ - skip=numlen-dialplan.nnl; - if (skip<0) skip=0; - /*first prepend international calling prefix or +*/ - if (proxy->dial_escape_plus){ - strncpy(result,dialplan.icp,result_len); - i+=strlen(dialplan.icp); - }else{ - strncpy(result,"+",result_len); - i+=1; - } - /*add prefix*/ - if (result_len-i>strlen(dialplan.ccc)){ - strcpy(result+i,dialplan.ccc); - i+=strlen(dialplan.ccc); - } - /*add user digits */ - strncpy(result+i,flatten+skip,result_len-i-1); + /*0. keep at most national number significant digits */ + char* flatten_start = flatten + MAX(0, (int)strlen(flatten) - (int)dialplan.nnl); + ms_debug("Prefix not present. Keeping at most %d digits: %s", dialplan.nnl, flatten_start); + + /*1. First prepend international calling prefix or +*/ + /*2. Second add prefix*/ + /*3. Finally add user digits */ + result = ms_strdup_printf("%s%s%s" + , tmpproxy->dial_escape_plus ? dialplan.icp : "+" + , dialplan.ccc + , flatten_start); + ms_debug("Prepended prefix resulted in %s", result); } } - ms_free(flatten); - ret = TRUE; - } else { - strncpy(result,username,result_len-1); - ret = FALSE; + if (result==NULL) { + result = flatten; + } else { + ms_free(flatten); + } } - if (inproxy==NULL) ms_free(proxy); - return ret; + if (proxy==NULL) linphone_proxy_config_destroy(tmpproxy); + return result; +} + +static LinphoneAddress* _linphone_core_destroy_addr_if_not_sip( LinphoneAddress* addr ){ + if( linphone_address_is_sip(addr) ) { + return addr; + } else { + linphone_address_destroy(addr); + return NULL; + } +} + +LinphoneAddress* linphone_proxy_config_normalize_sip_uri(LinphoneProxyConfig *proxy, const char *username) { + enum_lookup_res_t *enumres=NULL; + char *enum_domain=NULL; + char *tmpurl; + LinphoneAddress *uri; + + if (!username || *username=='\0') return NULL; + + if (is_enum(username,&enum_domain)){ + if (proxy) { + linphone_core_notify_display_status(proxy->lc,_("Looking for telephone number destination...")); + } + if (enum_lookup(enum_domain,&enumres)<0){ + if (proxy) { + linphone_core_notify_display_status(proxy->lc,_("Could not resolve this number.")); + } + ms_free(enum_domain); + return NULL; + } + ms_free(enum_domain); + tmpurl=enumres->sip_address[0]; + uri=linphone_address_new(tmpurl); + enum_lookup_res_free(enumres); + return _linphone_core_destroy_addr_if_not_sip(uri); + } + /* check if we have a "sip:" or a "sips:" */ + if ( (strstr(username,"sip:")==NULL) && (strstr(username,"sips:")==NULL) ){ + /* this doesn't look like a true sip uri */ + if (strchr(username,'@')!=NULL){ + /* seems like sip: is missing !*/ + tmpurl=ms_strdup_printf("sip:%s",username); + uri=linphone_address_new(tmpurl); + ms_free(tmpurl); + if (uri){ + return _linphone_core_destroy_addr_if_not_sip(uri); + } + } + + if (proxy!=NULL){ + /* append the proxy domain suffix but remove any custom parameters/headers */ + LinphoneAddress *uri=linphone_address_clone(linphone_proxy_config_get_identity_address(proxy)); + linphone_address_clean(uri); + if (uri==NULL){ + return NULL; + } else { + char* normalized_phone = linphone_proxy_config_normalize_phone_number(proxy,username); + linphone_address_set_display_name(uri,NULL); + linphone_address_set_username(uri,normalized_phone ? normalized_phone : username); + ms_free(normalized_phone); + return _linphone_core_destroy_addr_if_not_sip(uri); + } + } else { + return NULL; + } + } + uri=linphone_address_new(username); + if (uri!=NULL){ + return _linphone_core_destroy_addr_if_not_sip(uri); + } + + return NULL; } /** * Commits modification made to the proxy configuration. **/ -int linphone_proxy_config_done(LinphoneProxyConfig *obj) +int linphone_proxy_config_done(LinphoneProxyConfig *cfg) { LinphoneProxyConfigAddressComparisonResult res; - if (!linphone_proxy_config_check(obj->lc,obj)) + if (!linphone_proxy_config_check(cfg->lc,cfg)) return -1; /*check if server address as changed*/ - res = linphone_proxy_config_is_server_config_changed(obj); + res = linphone_proxy_config_is_server_config_changed(cfg); if (res != LinphoneProxyConfigAddressEqual) { /* server config has changed, need to unregister from previous first*/ - if (obj->op) { + if (cfg->op) { if (res == LinphoneProxyConfigAddressDifferent) { - _linphone_proxy_config_unregister(obj); + _linphone_proxy_config_unregister(cfg); } - sal_op_set_user_pointer(obj->op,NULL); /*we don't want to receive status for this un register*/ - sal_op_unref(obj->op); /*but we keep refresher to handle authentication if needed*/ - obj->op=NULL; + sal_op_set_user_pointer(cfg->op,NULL); /*we don't want to receive status for this un register*/ + sal_op_unref(cfg->op); /*but we keep refresher to handle authentication if needed*/ + cfg->op=NULL; } } - obj->commit=TRUE; - linphone_proxy_config_write_all_to_config_file(obj->lc); + cfg->commit=TRUE; + linphone_proxy_config_write_all_to_config_file(cfg->lc); return 0; } @@ -1042,19 +1024,14 @@ int linphone_proxy_config_send_publish(LinphoneProxyConfig *proxy, LinphonePrese if (proxy->state==LinphoneRegistrationOk || proxy->state==LinphoneRegistrationCleared){ if (proxy->publish_op==NULL){ - LinphoneAddress *to=linphone_address_new(linphone_proxy_config_get_identity(proxy)); + const LinphoneAddress *to=linphone_proxy_config_get_identity_address(proxy); proxy->publish_op=sal_op_new(proxy->lc->sal); linphone_configure_op(proxy->lc, proxy->publish_op, to, NULL, FALSE); - if (to!=NULL){ - linphone_address_destroy(to); - } if (lp_config_get_int(proxy->lc->config,"sip","publish_msg_with_contact",0)){ - SalAddress *addr=sal_address_new(linphone_proxy_config_get_identity(proxy)); - sal_op_set_contact_address(proxy->publish_op,addr); - sal_address_unref(addr); + sal_op_set_contact_address(proxy->publish_op,linphone_proxy_config_get_identity_address(proxy)); } } err=sal_publish_presence(proxy->publish_op @@ -1066,102 +1043,67 @@ int linphone_proxy_config_send_publish(LinphoneProxyConfig *proxy, LinphonePrese return err; } -/** - * Returns the route set for this proxy configuration. -**/ -const char *linphone_proxy_config_get_route(const LinphoneProxyConfig *obj){ - return obj->reg_route; +const char *linphone_proxy_config_get_route(const LinphoneProxyConfig *cfg){ + return cfg->reg_route; +} + +const LinphoneAddress *linphone_proxy_config_get_identity_address(const LinphoneProxyConfig *cfg){ + return cfg->identity_address; +} + +const char *linphone_proxy_config_get_identity(const LinphoneProxyConfig *cfg){ + return cfg->reg_identity; +} + +bool_t linphone_proxy_config_publish_enabled(const LinphoneProxyConfig *cfg){ + return cfg->publish; +} + +const char *linphone_proxy_config_get_server_addr(const LinphoneProxyConfig *cfg){ + return cfg->reg_proxy; } /** - * Returns the SIP identity that belongs to this proxy configuration. - * - * The SIP identity is a SIP address (Display Name ) + * @return the duration of registration. **/ -const char *linphone_proxy_config_get_identity(const LinphoneProxyConfig *obj){ - return obj->reg_identity; +int linphone_proxy_config_get_expires(const LinphoneProxyConfig *cfg){ + return cfg->expires; } -/** - * Returns TRUE if PUBLISH request is enabled for this proxy. -**/ -bool_t linphone_proxy_config_publish_enabled(const LinphoneProxyConfig *obj){ - return obj->publish; +bool_t linphone_proxy_config_register_enabled(const LinphoneProxyConfig *cfg){ + return cfg->reg_sendregister; } -/** - * Returns the proxy's SIP address. -**/ -const char *linphone_proxy_config_get_server_addr(const LinphoneProxyConfig *obj){ - return obj->reg_proxy; -} - -/** - * Returns the duration of registration. -**/ -int linphone_proxy_config_get_expires(const LinphoneProxyConfig *obj){ - return obj->expires; -} - -/** - * Returns TRUE if registration to the proxy is enabled. -**/ -bool_t linphone_proxy_config_register_enabled(const LinphoneProxyConfig *obj){ - return obj->reg_sendregister; -} - -/** - * Set optional contact parameters that will be added to the contact information sent in the registration. - * @param obj the proxy config object - * @param contact_params a string contaning the additional parameters in text form, like "myparam=something;myparam2=something_else" - * - * The main use case for this function is provide the proxy additional information regarding the user agent, like for example unique identifier or apple push id. - * As an example, the contact address in the SIP register sent will look like ;apple-push-id=43143-DFE23F-2323-FA2232. -**/ -void linphone_proxy_config_set_contact_parameters(LinphoneProxyConfig *obj, const char *contact_params){ - if (obj->contact_params) { - ms_free(obj->contact_params); - obj->contact_params=NULL; +void linphone_proxy_config_set_contact_parameters(LinphoneProxyConfig *cfg, const char *contact_params){ + if (cfg->contact_params) { + ms_free(cfg->contact_params); + cfg->contact_params=NULL; } if (contact_params){ - obj->contact_params=ms_strdup(contact_params); + cfg->contact_params=ms_strdup(contact_params); } } -/** - * Set optional contact parameters that will be added to the contact information sent in the registration, inside the URI. - * @param obj the proxy config object - * @param contact_uri_params a string containing the additional parameters in text form, like "myparam=something;myparam2=something_else" - * - * The main use case for this function is provide the proxy additional information regarding the user agent, like for example unique identifier or apple push id. - * As an example, the contact address in the SIP register sent will look like . -**/ -void linphone_proxy_config_set_contact_uri_parameters(LinphoneProxyConfig *obj, const char *contact_uri_params){ - if (obj->contact_uri_params) { - ms_free(obj->contact_uri_params); - obj->contact_uri_params=NULL; +void linphone_proxy_config_set_contact_uri_parameters(LinphoneProxyConfig *cfg, const char *contact_uri_params){ + if (cfg->contact_uri_params) { + ms_free(cfg->contact_uri_params); + cfg->contact_uri_params=NULL; } if (contact_uri_params){ - obj->contact_uri_params=ms_strdup(contact_uri_params); + cfg->contact_uri_params=ms_strdup(contact_uri_params); } } -/** - * Returns previously set contact parameters. -**/ -const char *linphone_proxy_config_get_contact_parameters(const LinphoneProxyConfig *obj){ - return obj->contact_params; +const char *linphone_proxy_config_get_contact_parameters(const LinphoneProxyConfig *cfg){ + return cfg->contact_params; } -/** - * Returns previously set contact URI parameters. -**/ -const char *linphone_proxy_config_get_contact_uri_parameters(const LinphoneProxyConfig *obj){ - return obj->contact_uri_params; +const char *linphone_proxy_config_get_contact_uri_parameters(const LinphoneProxyConfig *cfg){ + return cfg->contact_uri_params; } -struct _LinphoneCore * linphone_proxy_config_get_core(const LinphoneProxyConfig *obj){ - return obj->lc; +struct _LinphoneCore * linphone_proxy_config_get_core(const LinphoneProxyConfig *cfg){ + return cfg->lc; } const char *linphone_proxy_config_get_custom_header(LinphoneProxyConfig *cfg, const char *header_name){ @@ -1175,10 +1117,6 @@ void linphone_proxy_config_set_custom_header(LinphoneProxyConfig *cfg, const cha cfg->sent_headers=sal_custom_header_append(cfg->sent_headers, header_name, header_value); } -/** - * Add a proxy configuration. - * This will start registration on the proxy, if registration is enabled. -**/ int linphone_core_add_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *cfg){ if (!linphone_proxy_config_check(lc,cfg)) { return -1; @@ -1192,12 +1130,6 @@ int linphone_core_add_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *cfg){ return 0; } -/** - * Removes a proxy configuration. - * - * LinphoneCore will then automatically unregister and place the proxy configuration - * on a deleted list. For that reason, a removed proxy does NOT need to be freed. -**/ void linphone_core_remove_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *cfg){ /* check this proxy config is in the list before doing more*/ if (ms_list_find(lc->sip_conf.proxies,cfg)==NULL){ @@ -1207,24 +1139,24 @@ void linphone_core_remove_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *cf lc->sip_conf.proxies=ms_list_remove(lc->sip_conf.proxies,cfg); /* add to the list of destroyed proxies, so that the possible unREGISTER request can succeed authentication */ lc->sip_conf.deleted_proxies=ms_list_append(lc->sip_conf.deleted_proxies,cfg); + + if (lc->default_proxy==cfg){ + lc->default_proxy=NULL; + } + cfg->deletion_date=ms_time(NULL); if (cfg->state==LinphoneRegistrationOk){ - /* unREGISTER */ + /* UNREGISTER */ linphone_proxy_config_edit(cfg); linphone_proxy_config_enable_register(cfg,FALSE); linphone_proxy_config_done(cfg); linphone_proxy_config_update(cfg); - } - if (lc->default_proxy==cfg){ - lc->default_proxy=NULL; + } else if (cfg->state != LinphoneRegistrationNone) { + linphone_proxy_config_set_state(cfg, LinphoneRegistrationNone,"Registration disabled"); } linphone_proxy_config_write_all_to_config_file(lc); } -/** - * Erase all proxies from config. - * - * @ingroup proxy -**/ + void linphone_core_clear_proxy_config(LinphoneCore *lc){ MSList* list=ms_list_copy(linphone_core_get_proxy_config_list((const LinphoneCore*)lc)); MSList* copy=list; @@ -1235,7 +1167,7 @@ void linphone_core_clear_proxy_config(LinphoneCore *lc){ linphone_proxy_config_write_all_to_config_file(lc); } -static int linphone_core_get_default_proxy_config_index(LinphoneCore *lc) { +int linphone_core_get_default_proxy_config_index(LinphoneCore *lc) { int pos = -1; if (lc->default_proxy != NULL) { pos = ms_list_position(lc->sip_conf.proxies, ms_list_find(lc->sip_conf.proxies, (void *)lc->default_proxy)); @@ -1243,15 +1175,6 @@ static int linphone_core_get_default_proxy_config_index(LinphoneCore *lc) { return pos; } -/** - * Sets the default proxy. - * - * This default proxy must be part of the list of already entered LinphoneProxyConfig. - * Toggling it as default will make LinphoneCore use the identity associated with - * the proxy configuration in all incoming and outgoing calls. - * @param[in] lc LinphoneCore object - * @param[in] config The proxy configuration to use as the default one. -**/ void linphone_core_set_default_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *config){ /* check if this proxy is in our list */ if (config!=NULL){ @@ -1271,91 +1194,77 @@ void linphone_core_set_default_proxy_index(LinphoneCore *lc, int index){ else linphone_core_set_default_proxy(lc,ms_list_nth_data(lc->sip_conf.proxies,index)); } -/** - * Returns the default proxy configuration, that is the one used to determine the current identity. - * @deprecated Use linphone_core_get_default_proxy_config() instead. -**/ int linphone_core_get_default_proxy(LinphoneCore *lc, LinphoneProxyConfig **config){ if (config!=NULL) *config=lc->default_proxy; return linphone_core_get_default_proxy_config_index(lc); } -/** - * Returns the default proxy configuration, that is the one used to determine the current identity. - * @param[in] lc LinphoneCore object - * @return The default proxy configuration. -**/ LinphoneProxyConfig * linphone_core_get_default_proxy_config(LinphoneCore *lc) { return lc->default_proxy; } -/** - * Returns an unmodifiable list of entered proxy configurations. - * @param[in] lc The LinphoneCore object - * @return \mslist{LinphoneProxyConfig} -**/ const MSList *linphone_core_get_proxy_config_list(const LinphoneCore *lc){ return lc->sip_conf.proxies; } -void linphone_proxy_config_write_to_config_file(LpConfig *config, LinphoneProxyConfig *obj, int index) +void linphone_proxy_config_write_to_config_file(LpConfig *config, LinphoneProxyConfig *cfg, int index) { char key[50]; sprintf(key,"proxy_%i",index); lp_config_clean_section(config,key); - if (obj==NULL){ + if (cfg==NULL){ return; } - if (obj->type!=NULL){ - lp_config_set_string(config,key,"type",obj->type); + if (cfg->type!=NULL){ + lp_config_set_string(config,key,"type",cfg->type); } - if (obj->reg_proxy!=NULL){ - lp_config_set_string(config,key,"reg_proxy",obj->reg_proxy); + if (cfg->reg_proxy!=NULL){ + lp_config_set_string(config,key,"reg_proxy",cfg->reg_proxy); } - if (obj->reg_route!=NULL){ - lp_config_set_string(config,key,"reg_route",obj->reg_route); + if (cfg->reg_route!=NULL){ + lp_config_set_string(config,key,"reg_route",cfg->reg_route); } - if (obj->reg_identity!=NULL){ - lp_config_set_string(config,key,"reg_identity",obj->reg_identity); + if (cfg->reg_identity!=NULL){ + lp_config_set_string(config,key,"reg_identity",cfg->reg_identity); } - if (obj->realm!=NULL){ - lp_config_set_string(config,key,"realm",obj->realm); + if (cfg->realm!=NULL){ + lp_config_set_string(config,key,"realm",cfg->realm); } - if (obj->contact_params!=NULL){ - lp_config_set_string(config,key,"contact_parameters",obj->contact_params); + if (cfg->contact_params!=NULL){ + lp_config_set_string(config,key,"contact_parameters",cfg->contact_params); } - if (obj->contact_uri_params!=NULL){ - lp_config_set_string(config,key,"contact_uri_parameters",obj->contact_uri_params); + if (cfg->contact_uri_params!=NULL){ + lp_config_set_string(config,key,"contact_uri_parameters",cfg->contact_uri_params); } - if (obj->quality_reporting_collector!=NULL){ - lp_config_set_string(config,key,"quality_reporting_collector",obj->quality_reporting_collector); + if (cfg->quality_reporting_collector!=NULL){ + lp_config_set_string(config,key,"quality_reporting_collector",cfg->quality_reporting_collector); } - lp_config_set_int(config,key,"quality_reporting_enabled",obj->quality_reporting_enabled); - lp_config_set_int(config,key,"quality_reporting_interval",obj->quality_reporting_interval); - lp_config_set_int(config,key,"reg_expires",obj->expires); - lp_config_set_int(config,key,"reg_sendregister",obj->reg_sendregister); - lp_config_set_int(config,key,"publish",obj->publish); - lp_config_set_int(config, key, "avpf", obj->avpf_mode); - lp_config_set_int(config, key, "avpf_rr_interval", obj->avpf_rr_interval); - lp_config_set_int(config,key,"dial_escape_plus",obj->dial_escape_plus); - lp_config_set_string(config,key,"dial_prefix",obj->dial_prefix); - lp_config_set_int(config,key,"privacy",obj->privacy); + lp_config_set_int(config,key,"quality_reporting_enabled",cfg->quality_reporting_enabled); + lp_config_set_int(config,key,"quality_reporting_interval",cfg->quality_reporting_interval); + lp_config_set_int(config,key,"reg_expires",cfg->expires); + lp_config_set_int(config,key,"reg_sendregister",cfg->reg_sendregister); + lp_config_set_int(config,key,"publish",cfg->publish); + lp_config_set_int(config, key, "avpf", cfg->avpf_mode); + lp_config_set_int(config, key, "avpf_rr_interval", cfg->avpf_rr_interval); + lp_config_set_int(config,key,"dial_escape_plus",cfg->dial_escape_plus); + lp_config_set_string(config,key,"dial_prefix",cfg->dial_prefix); + lp_config_set_int(config,key,"privacy",cfg->privacy); } -#define CONFIGURE_STRING_VALUE(obj,config,key,param,param_name) \ +#define CONFIGURE_STRING_VALUE(cfg,config,key,param,param_name) \ {\ - char* default_value = linphone_proxy_config_get_##param(obj)?ms_strdup(linphone_proxy_config_get_##param(obj)):NULL;\ - linphone_proxy_config_set_##param(obj,lp_config_get_string(config,key,param_name,default_value)); \ + char* default_value = linphone_proxy_config_get_##param(cfg)?ms_strdup(linphone_proxy_config_get_##param(cfg)):NULL;\ + linphone_proxy_config_set_##param(cfg,lp_config_get_string(config,key,param_name,default_value)); \ if ( default_value) ms_free(default_value); \ } -#define CONFIGURE_BOOL_VALUE(obj,config,key,param,param_name) \ - linphone_proxy_config_enable_##param(obj,lp_config_get_int(config,key,param_name,linphone_proxy_config_##param##_enabled(obj))); +#define CONFIGURE_BOOL_VALUE(cfg,config,key,param,param_name) \ + linphone_proxy_config_enable_##param(cfg,lp_config_get_int(config,key,param_name,linphone_proxy_config_##param##_enabled(cfg))); -#define CONFIGURE_INT_VALUE(obj,config,key,param,param_name) \ - linphone_proxy_config_set_##param(obj,lp_config_get_int(config,key,param_name,linphone_proxy_config_get_##param(obj))); +#define CONFIGURE_INT_VALUE(cfg,config,key,param,param_name) \ + linphone_proxy_config_set_##param(cfg,lp_config_get_int(config,key,param_name,linphone_proxy_config_get_##param(cfg))); LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(LinphoneCore* lc, int index) { @@ -1490,102 +1399,6 @@ SipSetupContext *linphone_proxy_config_get_sip_setup_context(LinphoneProxyConfig return cfg->ssctx; } -/** - * @} -**/ - -LinphoneAccountCreator *linphone_account_creator_new(struct _LinphoneCore *core, const char *type){ - LinphoneAccountCreator *obj; - LinphoneProxyConfig *cfg; - SipSetup *ss=sip_setup_lookup(type); - SipSetupContext *ssctx; - if (!ss){ - return NULL; - } - if (!(sip_setup_get_capabilities(ss) & SIP_SETUP_CAP_ACCOUNT_MANAGER)){ - ms_error("%s cannot manage accounts.",type); - return NULL; - } - obj=ms_new0(LinphoneAccountCreator,1); - cfg=linphone_proxy_config_new(); - ssctx=sip_setup_context_new(ss,cfg); - obj->lc=core; - obj->ssctx=ssctx; - set_string(&obj->domain,sip_setup_context_get_domains(ssctx)[0]); - cfg->lc=core; - return obj; -} - -void linphone_account_creator_set_username(LinphoneAccountCreator *obj, const char *username){ - set_string(&obj->username,username); -} - -void linphone_account_creator_set_password(LinphoneAccountCreator *obj, const char *password){ - set_string(&obj->password,password); -} - -void linphone_account_creator_set_domain(LinphoneAccountCreator *obj, const char *domain){ - set_string(&obj->domain,domain); -} - -void linphone_account_creator_set_route(LinphoneAccountCreator *obj, const char *route) { - set_string(&obj->route,route); -} - -void linphone_account_creator_set_email(LinphoneAccountCreator *obj, const char *email) { - set_string(&obj->email,email); -} - -void linphone_account_creator_set_suscribe(LinphoneAccountCreator *obj, int suscribe) { - obj->suscribe = suscribe; -} - -const char * linphone_account_creator_get_username(LinphoneAccountCreator *obj){ - return obj->username; -} - -const char * linphone_account_creator_get_domain(LinphoneAccountCreator *obj){ - return obj->domain; -} - -int linphone_account_creator_test_existence(LinphoneAccountCreator *obj){ - SipSetupContext *ssctx=obj->ssctx; - char *uri=ms_strdup_printf("%s@%s",obj->username,obj->domain); - int err=sip_setup_context_account_exists(ssctx,uri); - ms_free(uri); - return err; -} - -int linphone_account_creator_test_validation(LinphoneAccountCreator *obj) { - SipSetupContext *ssctx=obj->ssctx; - int err=sip_setup_context_account_validated(ssctx,obj->username); - return err; -} - -LinphoneProxyConfig * linphone_account_creator_validate(LinphoneAccountCreator *obj){ - SipSetupContext *ssctx=obj->ssctx; - char *uri=ms_strdup_printf("%s@%s",obj->username,obj->domain); - int err=sip_setup_context_create_account(ssctx, uri, obj->password, obj->email, obj->suscribe); - ms_free(uri); - if (err==0) { - obj->succeeded=TRUE; - return sip_setup_context_get_proxy_config(ssctx); - } - return NULL; -} - -void linphone_account_creator_destroy(LinphoneAccountCreator *obj){ - if (obj->username) - ms_free(obj->username); - if (obj->password) - ms_free(obj->password); - if (obj->domain) - ms_free(obj->domain); - if (!obj->succeeded){ - linphone_proxy_config_destroy(sip_setup_context_get_proxy_config(obj->ssctx)); - } -} - void linphone_proxy_config_set_user_data(LinphoneProxyConfig *cfg, void *ud) { cfg->user_data = ud; } @@ -1598,6 +1411,13 @@ void linphone_proxy_config_set_state(LinphoneProxyConfig *cfg, LinphoneRegistrat LinphoneCore *lc=cfg->lc; bool_t update_friends=FALSE; + if (state==LinphoneRegistrationProgress) { + char *msg=ortp_strdup_printf(_("Refreshing on %s..."), linphone_proxy_config_get_identity(cfg)); + linphone_core_notify_display_status(lc,msg); + ms_free(msg); + + } + if (cfg->state!=state || state==LinphoneRegistrationOk) { /*allow multiple notification of LinphoneRegistrationOk for refreshing*/ ms_message("Proxy config [%p] for identity [%s] moving from state [%s] to [%s]" , cfg, linphone_proxy_config_get_identity(cfg), @@ -1612,8 +1432,13 @@ void linphone_proxy_config_set_state(LinphoneProxyConfig *cfg, LinphoneRegistrat if (update_friends){ linphone_core_update_friends_subscriptions(lc,cfg,TRUE); } - if (lc) + if (lc){ linphone_core_notify_registration_state_changed(lc,cfg,state,message); + if (lc->calls && lp_config_get_int(lc->config, "sip", "repair_broken_calls", 1)){ + /*if we are registered and there were broken calls due to a past network disconnection, attempt to repair them*/ + ms_list_for_each(lc->calls, (MSIterateFunc) linphone_call_repair_if_broken); + } + } } else { /*state already reported*/ } @@ -1670,9 +1495,11 @@ const char* linphone_proxy_config_get_transport(const LinphoneProxyConfig *cfg) return NULL; } - if ((route_addr || (route_addr=sal_address_new(addr))) && sal_address_get_transport(route_addr)) { + if (route_addr || (route_addr=sal_address_new(addr))) { ret=sal_transport_to_string(sal_address_get_transport(route_addr)); - if (!linphone_proxy_config_get_service_route(cfg)) sal_address_destroy(route_addr); /*destroy except for service route*/ + if (!linphone_proxy_config_get_service_route(cfg)) { + sal_address_destroy(route_addr); + } } return ret; @@ -1683,16 +1510,15 @@ void linphone_proxy_config_set_privacy(LinphoneProxyConfig *params, LinphonePriv LinphonePrivacyMask linphone_proxy_config_get_privacy(const LinphoneProxyConfig *params) { return params->privacy; } -void linphone_proxy_config_set_publish_expires(LinphoneProxyConfig *obj, int expires) { - obj->publish_expires=expires; +void linphone_proxy_config_set_publish_expires(LinphoneProxyConfig *cfg, int expires) { + cfg->publish_expires=expires; } -int linphone_proxy_config_get_publish_expires(const LinphoneProxyConfig *obj) { - if (obj->publish_expires<0) { - return obj->expires; /*default value is same as register*/ +int linphone_proxy_config_get_publish_expires(const LinphoneProxyConfig *cfg) { + if (cfg->publish_expires<0) { + return cfg->expires; /*default value is same as register*/ } else { - return obj->publish_expires; + return cfg->publish_expires; } - } void linphone_proxy_config_enable_avpf(LinphoneProxyConfig *cfg, bool_t enable) { @@ -1723,6 +1549,12 @@ uint8_t linphone_proxy_config_get_avpf_rr_interval(const LinphoneProxyConfig *cf return cfg->avpf_rr_interval; } -char* linphone_proxy_config_get_contact(const LinphoneProxyConfig *cfg) { - return sal_op_get_public_uri(cfg->op); +const LinphoneAddress* linphone_proxy_config_get_contact(const LinphoneProxyConfig *cfg) { + return sal_op_get_contact_address(cfg->op); +} + +const struct _LinphoneAuthInfo* linphone_proxy_config_find_auth_info(const LinphoneProxyConfig *cfg) { + const char* username = cfg->identity_address ? linphone_address_get_username(cfg->identity_address) : NULL; + const char* domain = cfg->identity_address ? linphone_address_get_domain(cfg->identity_address) : NULL; + return _linphone_core_find_auth_info(cfg->lc, cfg->realm, username, domain, TRUE); } diff --git a/coreapi/quality_reporting.c b/coreapi/quality_reporting.c index e22f7229c..bebade118 100644 --- a/coreapi/quality_reporting.c +++ b/coreapi/quality_reporting.c @@ -28,6 +28,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include +#if TARGET_OS_IPHONE +#include +#endif + #define STR_REASSIGN(dest, src) {\ if (dest != NULL) \ ms_free(dest); \ @@ -40,7 +44,7 @@ static char * float_to_one_decimal_string(float f) { float rounded_f = floorf(f * 10 + .5f) / 10; int floor_part = (int) rounded_f; - int one_decimal_part = floorf (10 * (rounded_f - floor_part) + .5f); + int one_decimal_part = (int)floorf(10 * (rounded_f - floor_part) + .5f); return ms_strdup_printf("%d.%d", floor_part, one_decimal_part); } @@ -49,7 +53,7 @@ static void append_to_buffer_valist(char **buff, size_t *buff_size, size_t *offs belle_sip_error_code ret; size_t prevoffset = *offset; - #ifndef WIN32 + #ifndef _WIN32 va_list cap;/*copy of our argument list: a va_list cannot be re-used (SIGSEGV on linux 64 bits)*/ va_copy(cap,args); ret = belle_sip_snprintf_valist(*buff, *buff_size, offset, fmt, cap); @@ -109,7 +113,6 @@ static void reset_avg_metrics(reporting_session_report_t * report){ #define METRICS_JITTER_BUFFER 1 << 3 #define METRICS_DELAY 1 << 4 #define METRICS_SIGNAL 1 << 5 -#define METRICS_ADAPTIVE_ALGORITHM 1 << 6 static uint8_t are_metrics_filled(const reporting_content_metrics_t rm) { uint8_t ret = 0; @@ -157,6 +160,9 @@ static bool_t media_report_enabled(LinphoneCall * call, int stats_type){ if (stats_type == LINPHONE_CALL_STATS_VIDEO && !linphone_call_params_video_enabled(linphone_call_get_current_params(call))) return FALSE; + if (stats_type == LINPHONE_CALL_STATS_TEXT && !linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(call))) + return FALSE; + return (call->log->reporting.reports[stats_type] != NULL); } @@ -257,13 +263,16 @@ static void append_metrics_to_buffer(char ** buffer, size_t * size, size_t * off } static int send_report(LinphoneCall* call, reporting_session_report_t * report, const char * report_event) { - LinphoneContent *content = linphone_content_new(); - LinphoneAddress *addr; + LinphoneContent *content; int expires = -1; size_t offset = 0; size_t size = 2048; char * buffer; int ret = 0; + LinphoneEvent *lev; + LinphoneAddress *request_uri; + char * domain; + const char* route; /*if we are on a low bandwidth network, do not send reports to not overload it*/ if (linphone_call_params_low_bandwidth_enabled(linphone_call_get_current_params(call))){ @@ -286,15 +295,8 @@ static int send_report(LinphoneCall* call, reporting_session_report_t * report, goto end; } - addr = linphone_address_new(linphone_proxy_config_get_quality_reporting_collector(call->dest_proxy)); - if (addr == NULL) { - ms_warning("QualityReporting[%p]: Asked to submit reporting statistics but no collector address found" - , call); - ret = 3; - goto end; - } - buffer = (char *) belle_sip_malloc(size); + content = linphone_content_new(); linphone_content_set_type(content, "application"); linphone_content_set_subtype(content, "vq-rtcpxr"); @@ -331,17 +333,39 @@ static int send_report(LinphoneCall* call, reporting_session_report_t * report, append_to_buffer(&buffer, &size, &offset, "\r\n"); } +#if TARGET_OS_IPHONE + { + size_t namesize; + char *machine; + sysctlbyname("hw.machine", NULL, &namesize, NULL, 0); + machine = malloc(namesize); + sysctlbyname("hw.machine", machine, &namesize, NULL, 0); + APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, "Device: %s\r\n", machine); + } +#endif + linphone_content_set_buffer(content, buffer, strlen(buffer)); ms_free(buffer); - if (call->log->reporting.on_report_sent != NULL){ - call->log->reporting.on_report_sent( - call, - (report==call->log->reporting.reports[0])?LINPHONE_CALL_STATS_AUDIO:LINPHONE_CALL_STATS_VIDEO, - content); + if (call->log->reporting.on_report_sent != NULL) { + SalStreamType type = report == call->log->reporting.reports[0] ? LINPHONE_CALL_STATS_AUDIO : report == call->log->reporting.reports[1] ? LINPHONE_CALL_STATS_VIDEO : LINPHONE_CALL_STATS_TEXT; + call->log->reporting.on_report_sent(call, type, content); } - if (! linphone_core_publish(call->core, addr, "vq-rtcpxr", expires, content)){ + + route = linphone_proxy_config_get_quality_reporting_collector(call->dest_proxy); + domain = ms_strdup_printf("sip:%s", linphone_proxy_config_get_domain(call->dest_proxy)); + request_uri = linphone_address_new(route ? route : domain); + ms_free(domain); + lev=linphone_core_create_publish(call->core, request_uri, "vq-rtcpxr", expires); + if (route) { + ms_message("Publishing report with custom route %s", route); + sal_op_set_route(lev->op, route); + } + + if (linphone_event_send_publish(lev, content) != 0){ + linphone_event_unref(lev); + lev=NULL; ret=4; } else { reset_avg_metrics(report); @@ -352,8 +376,7 @@ static int send_report(LinphoneCall* call, reporting_session_report_t * report, STR_REASSIGN(report->qos_analyzer.output, NULL); } - linphone_address_destroy(addr); - + linphone_address_destroy(request_uri); linphone_content_unref(content); end: @@ -369,8 +392,8 @@ static int send_report(LinphoneCall* call, reporting_session_report_t * report, static const SalStreamDescription * get_media_stream_for_desc(const SalMediaDescription * smd, SalStreamType sal_stream_type) { int count; if (smd != NULL) { - for (count = 0; count < smd->nb_streams; ++count) { - if (smd->streams[count].type == sal_stream_type) { + for (count = 0; count < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; ++count) { + if (sal_stream_description_active(&smd->streams[count]) && smd->streams[count].type == sal_stream_type) { return &smd->streams[count]; } } @@ -379,7 +402,7 @@ static const SalStreamDescription * get_media_stream_for_desc(const SalMediaDesc } static void update_ip(LinphoneCall * call, int stats_type) { - SalStreamType sal_stream_type = (stats_type == LINPHONE_CALL_STATS_AUDIO) ? SalAudio : SalVideo; + SalStreamType sal_stream_type = stats_type == LINPHONE_CALL_STATS_AUDIO ? SalAudio : stats_type == LINPHONE_CALL_STATS_VIDEO ? SalVideo : SalText; const SalStreamDescription * local_desc = get_media_stream_for_desc(call->localdesc, sal_stream_type); const SalStreamDescription * remote_desc = get_media_stream_for_desc(sal_call_get_remote_media_description(call->op), sal_stream_type); @@ -411,20 +434,20 @@ static void qos_analyzer_on_action_suggested(void *user_data, int datac, const c char * appendbuf; int i; int ptime = -1; - int bitrate[2] = {-1, -1}; - int up_bw[2] = {-1, -1}; - int down_bw[2] = {-1, -1}; - MediaStream *streams[2] = {(MediaStream*) call->audiostream, (MediaStream *) call->videostream}; - for (i=0;i<2;i++){ - if (streams[i]!=NULL){ - if (streams[i]->encoder!=NULL){ + int bitrate[3] = {-1, -1, -1}; + int up_bw[3] = {-1, -1, -1}; + int down_bw[3] = {-1, -1, -1}; + MediaStream *streams[3] = { (MediaStream*) call->audiostream, (MediaStream *) call->videostream, (MediaStream *) call->textstream }; + for (i = 0; i < 3; i++){ + if (streams[i] != NULL){ + if (streams[i]->encoder != NULL){ if (ms_filter_has_method(streams[i]->encoder,MS_FILTER_GET_BITRATE)){ ms_filter_call_method(streams[i]->encoder,MS_FILTER_GET_BITRATE,&bitrate[i]); - bitrate[i] /= 1000.f; + bitrate[i] /= 1000; } } - up_bw[i] = media_stream_get_up_bw(streams[i])/1000.f; - down_bw[i] = media_stream_get_down_bw(streams[i])/1000.f; + up_bw[i] = (int)(media_stream_get_up_bw(streams[i])/1000.f); + down_bw[i] = (int)(media_stream_get_down_bw(streams[i])/1000.f); } } if (call->audiostream!=NULL){ @@ -438,9 +461,9 @@ static void qos_analyzer_on_action_suggested(void *user_data, int datac, const c appendbuf=ms_strdup_printf("%s%d;", report->qos_analyzer.timestamp?report->qos_analyzer.timestamp:"", ms_time(0)); STR_REASSIGN(report->qos_analyzer.timestamp,appendbuf); - STR_REASSIGN(report->qos_analyzer.input_leg, ms_strdup_printf("%s aenc_ptime aenc_br a_dbw a_ubw venc_br v_dbw v_ubw", datav[0])); - appendbuf=ms_strdup_printf("%s%s %d %d %d %d %d %d %d;", report->qos_analyzer.input?report->qos_analyzer.input:"", datav[1], - ptime, bitrate[0], down_bw[0], up_bw[0], bitrate[1], down_bw[1], up_bw[1] ); + STR_REASSIGN(report->qos_analyzer.input_leg, ms_strdup_printf("%s aenc_ptime aenc_br a_dbw a_ubw venc_br v_dbw v_ubw tenc_br t_dbw t_ubw", datav[0])); + appendbuf=ms_strdup_printf("%s%s %d %d %d %d %d %d %d %d %d %d;", report->qos_analyzer.input?report->qos_analyzer.input:"", datav[1], + ptime, bitrate[0], down_bw[0], up_bw[0], bitrate[1], down_bw[1], up_bw[1], bitrate[2], down_bw[2], up_bw[2]); STR_REASSIGN(report->qos_analyzer.input,appendbuf); STR_REASSIGN(report->qos_analyzer.output_leg, ms_strdup(datav[2])); appendbuf=ms_strdup_printf("%s%s;", report->qos_analyzer.output?report->qos_analyzer.output:"", datav[3]); @@ -450,6 +473,7 @@ static void qos_analyzer_on_action_suggested(void *user_data, int datac, const c void linphone_reporting_update_ip(LinphoneCall * call) { update_ip(call, LINPHONE_CALL_STATS_AUDIO); update_ip(call, LINPHONE_CALL_STATS_VIDEO); + update_ip(call, LINPHONE_CALL_STATS_TEXT); } void linphone_reporting_update_media_info(LinphoneCall * call, int stats_type) { @@ -460,7 +484,8 @@ void linphone_reporting_update_media_info(LinphoneCall * call, int stats_type) { reporting_session_report_t * report = call->log->reporting.reports[stats_type]; char * dialog_id; - if (!media_report_enabled(call, stats_type)) + // call->op might be already released if hanging up in state LinphoneCallOutgoingInit + if (!media_report_enabled(call, stats_type) || call->op == NULL) return; dialog_id = sal_op_get_dialog_id(call->op); @@ -473,15 +498,15 @@ void linphone_reporting_update_media_info(LinphoneCall * call, int stats_type) { // RFC states: "LocalGroupID provides the identification for the purposes // of aggregation for the local endpoint.". STR_REASSIGN(report->info.local_addr.group, ms_strdup_printf("%s-%s-%s" - , dialog_id + , dialog_id ? dialog_id : "" , "local" - , report->local_metrics.user_agent + , report->local_metrics.user_agent ? report->local_metrics.user_agent : "" ) ); STR_REASSIGN(report->info.remote_addr.group, ms_strdup_printf("%s-%s-%s" - , dialog_id + , dialog_id ? dialog_id : "" , "remote" - , report->remote_metrics.user_agent + , report->remote_metrics.user_agent ? report->remote_metrics.user_agent : "" ) ); @@ -514,6 +539,10 @@ void linphone_reporting_update_media_info(LinphoneCall * call, int stats_type) { stream = &call->videostream->ms; local_payload = linphone_call_params_get_used_video_codec(current_params); remote_payload = local_payload; + } else if (stats_type == LINPHONE_CALL_STATS_TEXT && call->textstream != NULL) { + stream = &call->textstream->ms; + local_payload = linphone_call_params_get_used_text_codec(current_params); + remote_payload = local_payload; } if (stream != NULL) { @@ -530,7 +559,7 @@ void linphone_reporting_update_media_info(LinphoneCall * call, int stats_type) { } } - STR_REASSIGN(report->dialog_id, ms_strdup_printf("%s;%u", dialog_id, report->info.local_addr.ssrc)); + STR_REASSIGN(report->dialog_id, ms_strdup_printf("%s;%u", dialog_id ? dialog_id : "", report->info.local_addr.ssrc)); if (local_payload != NULL) { report->local_metrics.session_description.payload_type = local_payload->type; @@ -554,7 +583,7 @@ static float reporting_rand(float t){ return t * (.2f * (rand() / (RAND_MAX * 1.0f)) + 0.9f); } -void linphone_reporting_on_rtcp_update(LinphoneCall *call, int stats_type) { +void linphone_reporting_on_rtcp_update(LinphoneCall *call, SalStreamType stats_type) { reporting_session_report_t * report = call->log->reporting.reports[stats_type]; reporting_content_metrics_t * metrics = NULL; LinphoneCallStats stats = call->stats[stats_type]; @@ -605,14 +634,14 @@ void linphone_reporting_on_rtcp_update(LinphoneCall *call, int stats_type) { if (rtt > 1e-6){ metrics->rtcp_sr_count++; - metrics->delay.round_trip_delay += 1000*rtt; + metrics->delay.round_trip_delay += (int)(1000*rtt); } } }while(rtcp_next_packet(block)); /* check if we should send an interval report - use a random sending time to dispatch reports and avoid sending them too close from each other */ - if (report_interval>0 && ms_time(NULL)-report->last_report_date>reporting_rand(report_interval)){ + if ((report_interval > 0) && ((float)(ms_time(NULL) - report->last_report_date) > reporting_rand((float)report_interval))) { linphone_reporting_update_media_info(call, stats_type); send_report(call, report, "VQIntervalReport"); } @@ -621,11 +650,12 @@ void linphone_reporting_on_rtcp_update(LinphoneCall *call, int stats_type) { static int publish_report(LinphoneCall *call, const char *event_type){ int ret = 0; int i; - for (i = 0; i < 2; i++){ - if (media_report_enabled(call, i)){ + for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++){ + int stream_index = i == call->main_audio_stream_index ? LINPHONE_CALL_STATS_AUDIO : call->main_video_stream_index ? LINPHONE_CALL_STATS_VIDEO : LINPHONE_CALL_STATS_TEXT; + if (media_report_enabled(call, stream_index)) { int sndret; - linphone_reporting_update_media_info(call, i); - sndret=send_report(call, call->log->reporting.reports[i], event_type); + linphone_reporting_update_media_info(call, stream_index); + sndret=send_report(call, call->log->reporting.reports[stream_index], event_type); if (sndret>0){ ret += 10+(i+1)*sndret; } @@ -645,54 +675,46 @@ int linphone_reporting_publish_interval_report(LinphoneCall* call) { return publish_report(call, "VQIntervalReport"); } +static bool_t set_on_action_suggested_cb(MediaStream *stream,void (*on_action_suggested)(void*,int,const char**),void* u) { + if (stream&&stream->rc){ + MSQosAnalyzer *analyzer=ms_bitrate_controller_get_qos_analyzer(stream->rc); + if (analyzer){ + ms_qos_analyzer_set_on_action_suggested(analyzer, + on_action_suggested, + u); + return TRUE; + } + } + return FALSE; +} + void linphone_reporting_call_state_updated(LinphoneCall *call){ LinphoneCallState state=linphone_call_get_state(call); - MSQosAnalyzer *analyzer; - int i; - if (state == LinphoneCallReleased||!quality_reporting_enabled(call)){ return; } switch (state){ case LinphoneCallStreamsRunning:{ - bool_t video_enabled=media_report_enabled(call, LINPHONE_CALL_STATS_VIDEO); - MediaStream *streams[2] = {(MediaStream*) call->audiostream, (MediaStream *) call->videostream}; - for (i=0;i<2;i++){ - - if (streams[i]==NULL||streams[i]->rc==NULL){ - ms_message("QualityReporting[%p] Cannot set on_action_suggested" - " callback for %s stream because something is null", call, i?"video":"audio"); - continue; - } - - analyzer=ms_bitrate_controller_get_qos_analyzer(streams[i]->rc); - if (analyzer){ - call->log->reporting.reports[i]->call=call; - STR_REASSIGN(call->log->reporting.reports[i]->qos_analyzer.name, ms_strdup(ms_qos_analyzer_get_name(analyzer))); - - ms_qos_analyzer_set_on_action_suggested(analyzer, - qos_analyzer_on_action_suggested, - call->log->reporting.reports[i]); + int i = 0; + MediaStream *streams[3] = { (MediaStream*) call->audiostream, (MediaStream *) call->videostream, (MediaStream *) call->textstream }; + for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) { + int stream_index = i == call->main_audio_stream_index ? LINPHONE_CALL_STATS_AUDIO : call->main_video_stream_index ? LINPHONE_CALL_STATS_VIDEO : LINPHONE_CALL_STATS_TEXT; + bool_t enabled = media_report_enabled(call, stream_index); + if (enabled && set_on_action_suggested_cb(streams[stream_index], qos_analyzer_on_action_suggested, call->log->reporting.reports[stream_index])) { + call->log->reporting.reports[stream_index]->call=call; + STR_REASSIGN(call->log->reporting.reports[stream_index]->qos_analyzer.name, ms_strdup(ms_qos_analyzer_get_name(ms_bitrate_controller_get_qos_analyzer(streams[stream_index]->rc)))); } } linphone_reporting_update_ip(call); - if (!video_enabled && call->log->reporting.was_video_running){ + if (!media_report_enabled(call, LINPHONE_CALL_STATS_VIDEO) && call->log->reporting.was_video_running){ send_report(call, call->log->reporting.reports[LINPHONE_CALL_STATS_VIDEO], "VQSessionReport"); } - call->log->reporting.was_video_running=video_enabled; + call->log->reporting.was_video_running=media_report_enabled(call, LINPHONE_CALL_STATS_VIDEO); break; } case LinphoneCallEnd:{ - MediaStream *streams[2] = {(MediaStream*) call->audiostream, (MediaStream *) call->videostream}; - for (i=0;i<2;i++){ - if (streams[i]==NULL||streams[i]->rc==NULL){ - continue; - } - analyzer=ms_bitrate_controller_get_qos_analyzer(streams[i]->rc); - if (analyzer){ - ms_qos_analyzer_set_on_action_suggested(analyzer, NULL, NULL); - } - } + set_on_action_suggested_cb(&call->audiostream->ms, NULL, NULL); + set_on_action_suggested_cb(&call->videostream->ms, NULL, NULL); if (call->log->status==LinphoneCallSuccess || call->log->status==LinphoneCallAborted){ linphone_reporting_publish_session_report(call, TRUE); } diff --git a/coreapi/quality_reporting.h b/coreapi/quality_reporting.h index 794c78288..7e30dafff 100644 --- a/coreapi/quality_reporting.h +++ b/coreapi/quality_reporting.h @@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define quality_reporting_h #include "linphonecore.h" +#include "sal/sal.h" #ifdef __cplusplus extern "C"{ @@ -41,7 +42,7 @@ typedef struct reporting_addr { } reporting_addr_t; /** - * Linphone quality report sub object storing media metrics information as required by RFC035. + * Linphone quality report sub object storing media metrics information as required by RFC6035. */ typedef struct reporting_content_metrics { @@ -141,9 +142,9 @@ typedef struct reporting_session_report { } reporting_session_report_t; -typedef void (*LinphoneQualityReportingReportSendCb)(const LinphoneCall *call, int stream_type, const LinphoneContent *content); +typedef void (*LinphoneQualityReportingReportSendCb)(const LinphoneCall *call, SalStreamType stream_type, const LinphoneContent *content); -reporting_session_report_t * linphone_reporting_new(); +reporting_session_report_t * linphone_reporting_new(void); void linphone_reporting_destroy(reporting_session_report_t * report); /** @@ -186,10 +187,10 @@ int linphone_reporting_publish_interval_report(LinphoneCall* call); /** * Update publish reports with newly sent/received RTCP-XR packets (if available). * @param call #LinphoneCall object to consider - * @param stats_type the media type (LINPHONE_CALL_STATS_AUDIO or LINPHONE_CALL_STATS_VIDEO) + * @param stats_type the media type * */ -void linphone_reporting_on_rtcp_update(LinphoneCall *call, int stats_type); +void linphone_reporting_on_rtcp_update(LinphoneCall *call, SalStreamType stats_type); /** * Update publish reports on call state change. diff --git a/coreapi/remote_provisioning.c b/coreapi/remote_provisioning.c index c206b5828..d79598758 100644 --- a/coreapi/remote_provisioning.c +++ b/coreapi/remote_provisioning.c @@ -103,15 +103,17 @@ int linphone_remote_provisioning_download_and_apply(LinphoneCore *lc, const char belle_generic_uri_t *uri=belle_generic_uri_parse(remote_provisioning_uri); const char* scheme = uri ? belle_generic_uri_get_scheme(uri) : NULL; + const char *host = uri ? belle_generic_uri_get_host(uri) : NULL; if( scheme && (strcmp(scheme,"file") == 0) ){ // We allow for 'local remote-provisioning' in case the file is to be opened from the hard drive. const char* file_path = remote_provisioning_uri + strlen("file://"); // skip scheme + if (uri) { + belle_sip_object_unref(uri); + } return linphone_remote_provisioning_load_file(lc, file_path); - - } else if( scheme && strncmp(scheme, "http", 4) == 0 ) { + } else if( scheme && strncmp(scheme, "http", 4) == 0 && host && strlen(host) > 0) { belle_http_request_listener_callbacks_t belle_request_listener={0}; - belle_http_request_listener_t *listener; belle_http_request_t *request; belle_request_listener.process_response=belle_request_process_response_event; @@ -119,18 +121,32 @@ int linphone_remote_provisioning_download_and_apply(LinphoneCore *lc, const char belle_request_listener.process_io_error=belle_request_process_io_error; belle_request_listener.process_timeout=belle_request_process_timeout; - listener = belle_http_request_listener_create_from_callbacks(&belle_request_listener, lc); + lc->provisioning_http_listener = belle_http_request_listener_create_from_callbacks(&belle_request_listener, lc); request=belle_http_request_create("GET",uri, NULL); - return belle_http_provider_send_request(lc->http_provider, request, listener); + + return belle_http_provider_send_request(lc->http_provider, request, lc->provisioning_http_listener); } else { - ms_error("Invalid provisioning URI [%s] (missing scheme?)",remote_provisioning_uri); + ms_error("Invalid provisioning URI [%s] (missing scheme or host ?)",remote_provisioning_uri); + if (uri) { + belle_sip_object_unref(uri); + } return -1; } } -void linphone_core_set_provisioning_uri(LinphoneCore *lc, const char *uri) { - lp_config_set_string(lc->config,"misc","config-uri",uri); +int linphone_core_set_provisioning_uri(LinphoneCore *lc, const char *remote_provisioning_uri) { + belle_generic_uri_t *uri=remote_provisioning_uri?belle_generic_uri_parse(remote_provisioning_uri):NULL; + if (!remote_provisioning_uri||uri) { + lp_config_set_string(lc->config,"misc","config-uri",remote_provisioning_uri); + if (uri) { + belle_sip_object_unref(uri); + } + return 0; + } + ms_error("Invalid provisioning URI [%s] (could not be parsed)",remote_provisioning_uri); + return -1; + } const char*linphone_core_get_provisioning_uri(const LinphoneCore *lc){ diff --git a/coreapi/sal.c b/coreapi/sal.c index 2d6ed1dde..2c858298a 100644 --- a/coreapi/sal.c +++ b/coreapi/sal.c @@ -55,7 +55,13 @@ SalTransport sal_transport_parse(const char* param) { SalMediaDescription *sal_media_description_new(){ SalMediaDescription *md=ms_new0(SalMediaDescription,1); + int i; md->refcount=1; + for(i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) { + md->streams[i].dir=SalStreamInactive; + md->streams[i].rtp_port = 0; + md->streams[i].rtcp_port = 0; + } return md; } @@ -66,7 +72,9 @@ static void sal_media_description_destroy(SalMediaDescription *md){ ms_list_free_with_data(md->streams[i].already_assigned_payloads,(void (*)(void *))payload_type_destroy); md->streams[i].payloads=NULL; md->streams[i].already_assigned_payloads=NULL; + sal_custom_sdp_attribute_free(md->streams[i].custom_sdp_attributes); } + sal_custom_sdp_attribute_free(md->custom_sdp_attributes); ms_free(md); } @@ -82,10 +90,9 @@ void sal_media_description_unref(SalMediaDescription *md){ } } -SalStreamDescription *sal_media_description_find_stream(SalMediaDescription *md, - SalMediaProto proto, SalStreamType type){ +SalStreamDescription *sal_media_description_find_stream(SalMediaDescription *md, SalMediaProto proto, SalStreamType type){ int i; - for(i=0;inb_streams;++i){ + for(i=0;istreams[i]; if (!sal_stream_description_active(ss)) continue; if (ss->proto==proto && ss->type==type) return ss; @@ -96,7 +103,7 @@ SalStreamDescription *sal_media_description_find_stream(SalMediaDescription *md, unsigned int sal_media_description_nb_active_streams_of_type(SalMediaDescription *md, SalStreamType type) { unsigned int i; unsigned int nb = 0; - for (i = 0; i < md->nb_streams; ++i) { + for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; ++i) { if (!sal_stream_description_active(&md->streams[i])) continue; if (md->streams[i].type == type) nb++; } @@ -105,7 +112,7 @@ unsigned int sal_media_description_nb_active_streams_of_type(SalMediaDescription SalStreamDescription * sal_media_description_get_active_stream_of_type(SalMediaDescription *md, SalStreamType type, unsigned int idx) { unsigned int i; - for (i = 0; i < md->nb_streams; ++i) { + for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; ++i) { if (!sal_stream_description_active(&md->streams[i])) continue; if (md->streams[i].type == type) { if (idx-- == 0) return &md->streams[i]; @@ -137,7 +144,7 @@ bool_t sal_media_description_empty(const SalMediaDescription *md){ void sal_media_description_set_dir(SalMediaDescription *md, SalStreamDir stream_dir){ int i; - for(i=0;inb_streams;++i){ + for(i=0;istreams[i]; if (!sal_stream_description_active(ss)) continue; ss->dir=stream_dir; @@ -147,13 +154,12 @@ void sal_media_description_set_dir(SalMediaDescription *md, SalStreamDir stream_ int sal_media_description_get_nb_active_streams(const SalMediaDescription *md) { int i; int nb = 0; - for (i = 0; i < md->nb_streams; i++) { + for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) { if (sal_stream_description_active(&md->streams[i])) nb++; } return nb; } - static bool_t is_null_address(const char *addr){ return strcmp(addr,"0.0.0.0")==0 || strcmp(addr,"::0")==0; } @@ -161,26 +167,27 @@ static bool_t is_null_address(const char *addr){ /*check for the presence of at least one stream with requested direction */ static bool_t has_dir(const SalMediaDescription *md, SalStreamDir stream_dir){ int i; - + /* we are looking for at least one stream with requested direction, inactive streams are ignored*/ - for(i=0;inb_streams;++i){ + for(i=0;istreams[i]; if (!sal_stream_description_active(ss)) continue; - if (ss->dir==stream_dir) return TRUE; - /*compatibility check for phones that only used the null address and no attributes */ - if (ss->dir==SalStreamSendRecv && stream_dir==SalStreamSendOnly && (is_null_address(md->addr) || is_null_address(ss->rtp_addr))) + if (ss->dir==stream_dir) { return TRUE; + } + /*compatibility check for phones that only used the null address and no attributes */ + if (ss->dir==SalStreamSendRecv && stream_dir==SalStreamSendOnly && (is_null_address(md->addr) || is_null_address(ss->rtp_addr))){ + return TRUE; + } } return FALSE; } bool_t sal_media_description_has_dir(const SalMediaDescription *md, SalStreamDir stream_dir){ if (stream_dir==SalStreamRecvOnly){ - if (has_dir(md,SalStreamSendOnly) || has_dir(md,SalStreamSendRecv)) return FALSE; - else return TRUE; + return has_dir(md, SalStreamRecvOnly) && !(has_dir(md,SalStreamSendOnly) || has_dir(md,SalStreamSendRecv)); }else if (stream_dir==SalStreamSendOnly){ - if (has_dir(md,SalStreamRecvOnly) || has_dir(md,SalStreamSendRecv)) return FALSE; - else return TRUE; + return has_dir(md, SalStreamSendOnly) && !(has_dir(md,SalStreamRecvOnly) || has_dir(md,SalStreamSendRecv)); }else if (stream_dir==SalStreamSendRecv){ return has_dir(md,SalStreamSendRecv); }else{ @@ -196,22 +203,57 @@ bool_t sal_stream_description_active(const SalStreamDescription *sd) { return (sd->rtp_port > 0); } +/*these are switch case, so that when a new proto is added we can't forget to modify this function*/ bool_t sal_stream_description_has_avpf(const SalStreamDescription *sd) { - return ((sd->proto == SalProtoRtpAvpf) || (sd->proto == SalProtoRtpSavpf) || (sd->proto == SalProtoUdpTlsRtpSavpf)); + switch (sd->proto){ + case SalProtoRtpAvpf: + case SalProtoRtpSavpf: + case SalProtoUdpTlsRtpSavpf: + return TRUE; + case SalProtoRtpAvp: + case SalProtoRtpSavp: + case SalProtoUdpTlsRtpSavp: + case SalProtoOther: + return FALSE; + } + return FALSE; } +/*these are switch case, so that when a new proto is added we can't forget to modify this function*/ bool_t sal_stream_description_has_srtp(const SalStreamDescription *sd) { - return ((sd->proto == SalProtoRtpSavp) || (sd->proto == SalProtoRtpSavpf)); + switch (sd->proto){ + case SalProtoRtpSavp: + case SalProtoRtpSavpf: + return TRUE; + case SalProtoRtpAvp: + case SalProtoRtpAvpf: + case SalProtoUdpTlsRtpSavpf: + case SalProtoUdpTlsRtpSavp: + case SalProtoOther: + return FALSE; + } + return FALSE; } bool_t sal_stream_description_has_dtls(const SalStreamDescription *sd) { - return ((sd->proto == SalProtoUdpTlsRtpSavp) || (sd->proto == SalProtoUdpTlsRtpSavpf)); + switch (sd->proto){ + case SalProtoUdpTlsRtpSavpf: + case SalProtoUdpTlsRtpSavp: + return TRUE; + case SalProtoRtpSavp: + case SalProtoRtpSavpf: + case SalProtoRtpAvp: + case SalProtoRtpAvpf: + case SalProtoOther: + return FALSE; + } + return FALSE; } bool_t sal_media_description_has_avpf(const SalMediaDescription *md) { int i; if (md->nb_streams == 0) return FALSE; - for (i = 0; i < md->nb_streams; i++) { + for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) { if (!sal_stream_description_active(&md->streams[i])) continue; if (sal_stream_description_has_avpf(&md->streams[i]) != TRUE) return FALSE; } @@ -221,7 +263,7 @@ bool_t sal_media_description_has_avpf(const SalMediaDescription *md) { bool_t sal_media_description_has_srtp(const SalMediaDescription *md) { int i; if (md->nb_streams == 0) return FALSE; - for (i = 0; i < md->nb_streams; i++) { + for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) { if (!sal_stream_description_active(&md->streams[i])) continue; if (sal_stream_description_has_srtp(&md->streams[i]) != TRUE) return FALSE; } @@ -231,7 +273,7 @@ bool_t sal_media_description_has_srtp(const SalMediaDescription *md) { bool_t sal_media_description_has_dtls(const SalMediaDescription *md) { int i; if (md->nb_streams == 0) return FALSE; - for (i = 0; i < md->nb_streams; i++) { + for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) { if (!sal_stream_description_active(&md->streams[i])) continue; if (sal_stream_description_has_dtls(&md->streams[i]) != TRUE) return FALSE; } @@ -320,6 +362,10 @@ int sal_stream_description_equals(const SalStreamDescription *sd1, const SalStre if (sd1->ptime != sd2->ptime) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED; if (sd1->dir != sd2->dir) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED; + /* ICE */ + if (strcmp(sd1->ice_ufrag, sd2->ice_ufrag) != 0) result |= SAL_MEDIA_DESCRIPTION_ICE_RESTART_DETECTED; + if (strcmp(sd1->ice_pwd, sd2->ice_pwd) != 0) result |= SAL_MEDIA_DESCRIPTION_ICE_RESTART_DETECTED; + /*DTLS*/ if (sd1->dtls_role != sd2->dtls_role) result |= SAL_MEDIA_DESCRIPTION_CRYPTO_KEYS_CHANGED; if (strcmp(sd1->dtls_fingerprint, sd2->dtls_fingerprint) != 0) result |= SAL_MEDIA_DESCRIPTION_CRYPTO_KEYS_CHANGED; @@ -327,6 +373,47 @@ int sal_stream_description_equals(const SalStreamDescription *sd1, const SalStre return result; } +char * sal_media_description_print_differences(int result){ + char *out = NULL; + if (result & SAL_MEDIA_DESCRIPTION_CODEC_CHANGED){ + out = ms_strcat_printf(out, "%s ", "CODEC_CHANGED"); + result &= ~SAL_MEDIA_DESCRIPTION_CODEC_CHANGED; + } + if (result & SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED){ + out = ms_strcat_printf(out, "%s ", "NETWORK_CHANGED"); + result &= ~SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED; + } + if (result & SAL_MEDIA_DESCRIPTION_ICE_RESTART_DETECTED){ + out = ms_strcat_printf(out, "%s ", "ICE_RESTART_DETECTED"); + result &= ~SAL_MEDIA_DESCRIPTION_ICE_RESTART_DETECTED; + } + if (result & SAL_MEDIA_DESCRIPTION_CRYPTO_KEYS_CHANGED){ + out = ms_strcat_printf(out, "%s ", "CRYPTO_KEYS_CHANGED"); + result &= ~SAL_MEDIA_DESCRIPTION_CRYPTO_KEYS_CHANGED; + } + if (result & SAL_MEDIA_DESCRIPTION_NETWORK_XXXCAST_CHANGED){ + out = ms_strcat_printf(out, "%s ", "NETWORK_XXXCAST_CHANGED"); + result &= ~SAL_MEDIA_DESCRIPTION_NETWORK_XXXCAST_CHANGED; + } + if (result & SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED){ + out = ms_strcat_printf(out, "%s ", "STREAMS_CHANGED"); + result &= ~SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED; + } + if (result & SAL_MEDIA_DESCRIPTION_CRYPTO_POLICY_CHANGED){ + out = ms_strcat_printf(out, "%s ", "CRYPTO_POLICY_CHANGED"); + result &= ~SAL_MEDIA_DESCRIPTION_CRYPTO_POLICY_CHANGED; + } + if (result & SAL_MEDIA_DESCRIPTION_FORCE_STREAM_RECONSTRUCTION){ + out = ms_strcat_printf(out, "%s ", "FORCE_STREAM_RECONSTRUCTION"); + result &= ~SAL_MEDIA_DESCRIPTION_FORCE_STREAM_RECONSTRUCTION; + } + if (result){ + ms_fatal("There are unhandled result bitmasks in sal_media_description_print_differences(), fix it"); + } + if (!out) out = ms_strdup("NONE"); + return out; +} + int sal_media_description_equals(const SalMediaDescription *md1, const SalMediaDescription *md2) { int result = SAL_MEDIA_DESCRIPTION_UNCHANGED; int i; @@ -336,11 +423,18 @@ int sal_media_description_equals(const SalMediaDescription *md1, const SalMediaD result |= SAL_MEDIA_DESCRIPTION_NETWORK_XXXCAST_CHANGED; if (md1->nb_streams != md2->nb_streams) result |= SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED; if (md1->bandwidth != md2->bandwidth) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED; - for(i = 0; i < md1->nb_streams; ++i){ + + /* ICE */ + if (strcmp(md1->ice_ufrag, md2->ice_ufrag) != 0) result |= SAL_MEDIA_DESCRIPTION_ICE_RESTART_DETECTED; + if (strcmp(md1->ice_pwd, md2->ice_pwd) != 0) result |= SAL_MEDIA_DESCRIPTION_ICE_RESTART_DETECTED; + + for(i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; ++i){ + if (!sal_stream_description_active(&md1->streams[i]) && !sal_stream_description_active(&md2->streams[i])) continue; result |= sal_stream_description_equals(&md1->streams[i], &md2->streams[i]); } return result; } + static void assign_address(SalAddress** address, const char *value){ if (*address){ sal_address_destroy(*address); @@ -617,8 +711,9 @@ void sal_auth_info_delete(SalAuthInfo* auth_info) { const char* sal_stream_type_to_string(SalStreamType type) { switch (type) { - case SalAudio:return "audio"; - case SalVideo:return "video"; + case SalAudio: return "audio"; + case SalVideo: return "video"; + case SalText: return "text"; default: return "other"; } } @@ -712,14 +807,14 @@ const char* sal_privacy_to_string(SalPrivacy privacy) { } static void remove_trailing_spaces(char *line){ - int i; + size_t i; for(i=strlen(line)-1;i>=0;--i){ if (isspace(line[i])) line[i]='\0'; else break; } } -static int line_get_value(const char *input, const char *key, char *value, size_t value_size, int *read){ +static int line_get_value(const char *input, const char *key, char *value, size_t value_size, size_t *read){ const char *end=strchr(input,'\n'); char line[256]={0}; char key_candidate[256]; @@ -744,7 +839,7 @@ static int line_get_value(const char *input, const char *key, char *value, size_ } int sal_lines_get_value(const char *data, const char *key, char *value, size_t value_size){ - int read=0; + size_t read=0; do{ if (line_get_value(data,key,value,value_size,&read)) diff --git a/coreapi/sipsetup.c b/coreapi/sipsetup.c index bf1b411e8..29ffd46fc 100644 --- a/coreapi/sipsetup.c +++ b/coreapi/sipsetup.c @@ -24,14 +24,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "linphonecore.h" extern SipSetup linphone_sip_login; -#ifdef BUILD_WIZARD -extern SipSetup linphone_sip_wizard; -#endif static SipSetup *all_sip_setups[]={ &linphone_sip_login, -#ifdef BUILD_WIZARD - &linphone_sip_wizard, -#endif NULL }; @@ -82,6 +76,7 @@ void sip_setup_unregister_all(void){ ss->initialized=FALSE; } } + registered_sip_setups = ms_list_free(registered_sip_setups); } void buddy_lookup_request_set_key(BuddyLookupRequest *req, const char *key){ diff --git a/coreapi/sipsetup.h b/coreapi/sipsetup.h index 2cbe24036..63d71d5f1 100644 --- a/coreapi/sipsetup.h +++ b/coreapi/sipsetup.h @@ -31,10 +31,13 @@ struct _SipSetup; struct _BuddyInfo; +struct _LinphoneXmlRpcSession; + struct _SipSetupContext{ struct _SipSetup *funcs; struct _LinphoneProxyConfig *cfg; + struct _LinphoneXmlRpcSession *xmlrpc_session; char domain[128]; char username[128]; void *data; diff --git a/coreapi/sipwizard.c b/coreapi/sipwizard.c deleted file mode 100644 index 879b9942a..000000000 --- a/coreapi/sipwizard.c +++ /dev/null @@ -1,266 +0,0 @@ -/* -sipwizard.c -Copyright (C) 2011 Belledonne Communication, 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. -*/ - -#include "linphonecore.h" -#include "private.h" -#include -#include - -typedef struct _BLReq{ - int status; - int result; - SoupMessage *msg; - SoupSession *session; - ortp_thread_t th; -}BLReq; - -static const int XMLRPC_FAILED = -1; -static const int XMLRPC_OK = 0; -static const char *XMLRPC_URL = "https://www.linphone.org/wizard.php"; - -static void sip_wizard_init_instance(SipSetupContext *ctx){ - LinphoneProxyConfig *cfg=sip_setup_context_get_proxy_config(ctx); - /*disable registration until the user logs in*/ - linphone_proxy_config_enable_register(cfg,FALSE); -} - -static const char ** sip_wizard_get_domains(SipSetupContext *ctx) { - LinphoneProxyConfig *cfg=sip_setup_context_get_proxy_config(ctx); - const char **domains = (const char**) &cfg->reg_proxy; - return domains; -} - - -static int xml_rpc_parse_response(BLReq *blreq, SoupMessage *sm){ - SoupBuffer *sb; - GValue retval; - GError *error=NULL; - sb=soup_message_body_flatten(sm->response_body); - ms_message("This the xml-rpc response:\n%s\n",sb->data); - if (soup_xmlrpc_parse_method_response(sb->data,sb->length,&retval,&error)==FALSE){ - if (error!=NULL){ - ms_error("xmlrpc fault: %s",error->message); - g_error_free(error); - }else{ - ms_error("Could not parse xml-rpc response !"); - } - blreq->status=XMLRPC_FAILED; - }else{ - ms_message("Extracting values from return type..."); - blreq->result = g_value_get_int(&retval); - g_value_unset(&retval); - blreq->status=XMLRPC_OK; - } - soup_buffer_free(sb); - return blreq->status; -} - -static void got_headers(BLReq *blreq, SoupMessage*msg){ - ms_message("Got headers !"); - blreq->status=XMLRPC_OK; -} - -#if SERIALIZE_HTTPS -/*on windows libsoup support for threads with gnutls is not yet functionnal (only in git) -This will come in next release of libsoup, probably. -In the meantime, we are forced to serialize all soup https processing with a big -ugly global mutex...*/ - -static GStaticMutex big_mutex = G_STATIC_MUTEX_INIT; -#endif - -static void * process_xml_rpc_request(void *up){ - BLReq *blreq=(BLReq*)up; - SoupMessage *sm=blreq->msg; - int code; - g_signal_connect_swapped(G_OBJECT(sm),"got-headers",(GCallback)got_headers,blreq); - blreq->status=XMLRPC_OK; -#if SERIALIZE_HTTPS - g_static_mutex_lock(&big_mutex); -#endif - code=soup_session_send_message(blreq->session,sm); - if (code==200){ - xml_rpc_parse_response(blreq,sm); - }else{ - ms_error("request failed, error-code=%i (%s)",code,soup_status_get_phrase(code)); - blreq->status=XMLRPC_FAILED; - } -#if SERIALIZE_HTTPS - g_static_mutex_unlock(&big_mutex); -#endif - return NULL; -} - - -static int do_simple_xmlrpc_request(SoupMessage *msg) { - int ret=-1; - BLReq *req; - - if (!msg){ - ms_error("Fail to create SoupMessage !"); - return -1; - }else{ - SoupBuffer *sb=soup_message_body_flatten(msg->request_body); - ms_message("This is the XML-RPC request we are going to send:\n%s\n",sb->data); - soup_buffer_free(sb); - } - - req=ms_new0(BLReq, 1); - req->session=soup_session_sync_new(); - req->msg=msg; - - process_xml_rpc_request(req); - - if (req->status == XMLRPC_OK) { - ret=req->result; - } - - // Freeing allocated structures lead to a crash (why?) - //g_free(req->session); - //g_free(msg); - ms_free(req); - - return ret; -} - -/* - * Return 1 if account already exists - * 0 if account doesn't exists - * -1 if information isn't available - */ -static int sip_wizard_account_exists(SipSetupContext *ctx, const char *identity) { - SoupMessage *msg=soup_xmlrpc_request_new(XMLRPC_URL, - "check_account", - G_TYPE_STRING, identity, - G_TYPE_INVALID); - return do_simple_xmlrpc_request(msg); -} - -static int sip_wizard_account_validated(SipSetupContext *ctx, const char *identity) { - SoupMessage *msg=soup_xmlrpc_request_new(XMLRPC_URL, - "check_account_validated", - G_TYPE_STRING, identity, - G_TYPE_INVALID); - return do_simple_xmlrpc_request(msg); -} - -static int sip_wizard_create_account(SipSetupContext *ctx, const char *identity, const char *passwd, const char *email, int suscribe) { - SoupMessage *msg=soup_xmlrpc_request_new(XMLRPC_URL, - "create_account", - G_TYPE_STRING, identity, - G_TYPE_STRING, passwd, - G_TYPE_STRING, email, - G_TYPE_INT, suscribe, - G_TYPE_INVALID); - return do_simple_xmlrpc_request(msg); -} - -static void guess_display_name(LinphoneAddress *from){ - const char *username=linphone_address_get_username(from); - char *dn=(char*)ms_malloc(strlen(username)+1); - const char *it; - char *wptr=dn; - bool_t begin=TRUE; - bool_t surname=FALSE; - for(it=username;*it!='\0';++it){ - if (begin){ - *wptr=toupper(*it); - begin=FALSE; - }else if (*it=='.'){ - if (surname) break; - *wptr=' '; - begin=TRUE; - surname=TRUE; - }else { - *wptr=*it; - } - wptr++; - } - *wptr='\0'; - linphone_address_set_display_name(from,dn); - ms_free(dn); -} - -static int sip_wizard_do_login(SipSetupContext * ctx, const char *uri, const char *passwd, const char *userid){ - LinphoneProxyConfig *cfg=sip_setup_context_get_proxy_config(ctx); - LinphoneCore *lc=linphone_proxy_config_get_core(cfg); - LinphoneAuthInfo *auth; - LinphoneAddress *parsed_uri; - char *tmp; - - parsed_uri=linphone_address_new(uri); - if (parsed_uri==NULL){ - return -1; - } - if (linphone_address_get_display_name(parsed_uri)!=NULL){ - guess_display_name(parsed_uri); - } - tmp=linphone_address_as_string(parsed_uri); - linphone_proxy_config_set_identity(cfg,tmp); - if (passwd) { - auth=linphone_auth_info_new(linphone_address_get_username(parsed_uri),NULL,passwd,NULL,NULL,NULL); - linphone_core_add_auth_info(lc,auth); - } - linphone_proxy_config_enable_register(cfg,TRUE); - linphone_proxy_config_done(cfg); - ms_free(tmp); - linphone_address_destroy(parsed_uri); - return 0; -} - -/* a simple SipSetup built-in plugin to allow creating accounts at runtime*/ - -#ifndef _MSC_VER - -SipSetup linphone_sip_wizard={ - .name="SipWizard", - .capabilities=SIP_SETUP_CAP_ACCOUNT_MANAGER, - .init_instance=sip_wizard_init_instance, - .account_exists=sip_wizard_account_exists, - .create_account=sip_wizard_create_account, - .login_account=sip_wizard_do_login, - .get_domains=sip_wizard_get_domains, - .account_validated=sip_wizard_account_validated -}; - -#else -SipSetup linphone_sip_wizard={ - "SipWizard", - SIP_SETUP_CAP_ACCOUNT_MANAGER, - 0, - NULL, - NULL, - sip_wizard_init_instance, - NULL, - sip_wizard_account_exists, - sip_wizard_create_account, - sip_wizard_do_login, - NULL, - NULL, - NULL, - NULL, - sip_wizard_get_domains, - NULL, - NULL, - sip_wizard_account_validated -}; - - - -#endif diff --git a/coreapi/test_lsd.c b/coreapi/test_lsd.c deleted file mode 100644 index a4e78ea11..000000000 --- a/coreapi/test_lsd.c +++ /dev/null @@ -1,104 +0,0 @@ -/* -linphone -Copyright (C) 2010 Simon MORLAT (simon.morlat@linphone.org) - -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. -*/ - -/* Linphone Sound Daemon: is a lightweight utility to play sounds to speaker during a conversation. - This is useful for embedded platforms, where sound apis are not performant enough to allow - simultaneous sound access. - - This file is a test program that plays several sound files and places a call simultatenously. -*/ - -#include "linphonecore_utils.h" - - -static void play_finished(LsdPlayer *p){ - const char *filename=(const char *)lsd_player_get_user_pointer (p); - ms_message("Playing of %s is finished.",filename); - if (!lsd_player_loop_enabled (p)){ - linphone_sound_daemon_release_player (lsd_player_get_daemon(p),p); - } -} - -static void wait_a_bit(LinphoneCore *lc, int seconds){ - time_t orig=ms_time(NULL); - while(ms_time(NULL)-orig1){ - linphone_core_invite(lc,argv[1]); - wait_a_bit(lc,10); - linphone_core_terminate_call(lc,NULL); - } - linphone_core_use_sound_daemon(lc,NULL); - linphone_sound_daemon_destroy(lsd); - linphone_core_destroy(lc); - - return 0; -} diff --git a/coreapi/test_numbers.c b/coreapi/test_numbers.c deleted file mode 100644 index da1f22b6f..000000000 --- a/coreapi/test_numbers.c +++ /dev/null @@ -1,48 +0,0 @@ -/* -linphone -Copyright (C) 2012 Belledonne Communications SARL -Author: Simon MORLAT (simon.morlat@linphone.org) - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - - -#include "linphonecore.h" -#include "linphonecore_utils.h" - -int main(int argc , char *argv[]){ - LinphoneProxyConfig *cfg; - char normalized_number[32]; - if (argc<2){ - fprintf(stderr,"Usage:\n%s [] [--escape-plus]\nReturns normalized number.", argv[0]); - return -1; - } - linphone_core_enable_logs(stderr); - cfg=linphone_proxy_config_new(); - if (argc>2) - linphone_proxy_config_set_dial_prefix(cfg,argv[2]); - if (argc>3 && strcmp(argv[3],"--escape-plus")==0) - linphone_proxy_config_set_dial_escape_plus(cfg,TRUE); - linphone_proxy_config_normalize_number(cfg,argv[1],normalized_number,sizeof(normalized_number)); - - printf("Normalized number is %s\n",normalized_number); - /*check extracted ccc*/ - if (linphone_dial_plan_lookup_ccc_from_e164(normalized_number) != atoi(linphone_proxy_config_get_dial_prefix(cfg))) { - printf("Error ccc [%i] not correctly parsed\n",linphone_dial_plan_lookup_ccc_from_e164(normalized_number)); - } else { - printf("Extracted ccc is [%i] \n",linphone_dial_plan_lookup_ccc_from_e164(normalized_number)); - } - return 0; -} diff --git a/coreapi/upnp.c b/coreapi/upnp.c index 68b82e2ed..72257ac60 100644 --- a/coreapi/upnp.c +++ b/coreapi/upnp.c @@ -698,19 +698,19 @@ int linphone_core_update_upnp_audio_video(LinphoneCall *call, bool_t audio, bool * Audio part */ linphone_upnp_update_port_binding(lupnp, &call->upnp_session->audio->rtp, - UPNP_IGD_IP_PROTOCOL_UDP, (audio)? call->media_ports[0].rtp_port:0, UPNP_CALL_RETRY_DELAY); + UPNP_IGD_IP_PROTOCOL_UDP, (audio)? call->media_ports[call->main_audio_stream_index].rtp_port:0, UPNP_CALL_RETRY_DELAY); linphone_upnp_update_port_binding(lupnp, &call->upnp_session->audio->rtcp, - UPNP_IGD_IP_PROTOCOL_UDP, (audio)? call->media_ports[0].rtcp_port:0, UPNP_CALL_RETRY_DELAY); + UPNP_IGD_IP_PROTOCOL_UDP, (audio)? call->media_ports[call->main_audio_stream_index].rtcp_port:0, UPNP_CALL_RETRY_DELAY); /* * Video part */ linphone_upnp_update_port_binding(lupnp, &call->upnp_session->video->rtp, - UPNP_IGD_IP_PROTOCOL_UDP, (video)? call->media_ports[1].rtp_port:0, UPNP_CALL_RETRY_DELAY); + UPNP_IGD_IP_PROTOCOL_UDP, (video)? call->media_ports[call->main_video_stream_index].rtp_port:0, UPNP_CALL_RETRY_DELAY); linphone_upnp_update_port_binding(lupnp, &call->upnp_session->video->rtcp, - UPNP_IGD_IP_PROTOCOL_UDP, (video)? call->media_ports[1].rtcp_port:0, UPNP_CALL_RETRY_DELAY); + UPNP_IGD_IP_PROTOCOL_UDP, (video)? call->media_ports[call->main_video_stream_index].rtcp_port:0, UPNP_CALL_RETRY_DELAY); } ms_mutex_unlock(&lupnp->mutex); @@ -731,8 +731,9 @@ int linphone_core_update_upnp_from_remote_media_description(LinphoneCall *call, int i; const SalStreamDescription *stream; - for (i = 0; i < md->nb_streams; i++) { + for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) { stream = &md->streams[i]; + if (!sal_stream_description_active(stream)) continue; if(stream->type == SalAudio) { audio = TRUE; } else if(stream->type == SalVideo) { @@ -1060,7 +1061,7 @@ int linphone_core_update_local_media_description_from_upnp(SalMediaDescription * SalStreamDescription *stream; UpnpStream *upnpStream; - for (i = 0; i < desc->nb_streams; i++) { + for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++) { stream = &desc->streams[i]; if (!sal_stream_description_active(stream)) continue; upnpStream = NULL; diff --git a/coreapi/vtables.c b/coreapi/vtables.c index 3a5672509..b01a91f08 100644 --- a/coreapi/vtables.c +++ b/coreapi/vtables.c @@ -55,111 +55,131 @@ static void cleanup_dead_vtable_refs(LinphoneCore *lc){ } } -#define NOTIFY_IF_EXIST(function_name) \ +#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 + bool_t has_cb = FALSE; \ + 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(__VA_ARGS__);\ + has_cb = TRUE;\ + }\ + if (has_cb) ms_message("Linphone core [%p] notifying [%s]",lc,#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); + 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); + 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); + 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); + NOTIFY_IF_EXIST(registration_state_changed, lc,cfg,cstate,message); cleanup_dead_vtable_refs(lc); } - +#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4) +#pragma GCC diagnostic push +#endif +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" void linphone_core_notify_show_interface(LinphoneCore *lc){ - NOTIFY_IF_EXIST(show)(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); + 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); + 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); + 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); + NOTIFY_IF_EXIST(display_url, lc,message,url); cleanup_dead_vtable_refs(lc); } - +#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4) +#pragma GCC diagnostic pop +#endif void linphone_core_notify_notify_presence_received(LinphoneCore *lc, LinphoneFriend * lf){ - NOTIFY_IF_EXIST(notify_presence_received)(lc,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); + 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); + 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); + NOTIFY_IF_EXIST(call_log_updated, lc,newcl); cleanup_dead_vtable_refs(lc); } +#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4) +#pragma GCC diagnostic push +#endif +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" 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); + NOTIFY_IF_EXIST(text_received, lc,room,from,message); cleanup_dead_vtable_refs(lc); } +#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4) +#pragma GCC diagnostic pop +#endif void linphone_core_notify_message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *message){ - NOTIFY_IF_EXIST(message_received)(lc,room,message); + NOTIFY_IF_EXIST(message_received, lc,room,message); cleanup_dead_vtable_refs(lc); } - +#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4) +#pragma GCC diagnostic push +#endif +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" 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); + 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); + 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); + NOTIFY_IF_EXIST(file_transfer_progress_indication, lc,message,content,offset,total); cleanup_dead_vtable_refs(lc); } - +#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4) +#pragma GCC diagnostic pop +#endif void linphone_core_notify_is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room) { - NOTIFY_IF_EXIST(is_composing_received)(lc,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); + NOTIFY_IF_EXIST(dtmf_received, lc,call,dtmf); cleanup_dead_vtable_refs(lc); } @@ -174,62 +194,62 @@ bool_t linphone_core_dtmf_received_has_listener(const LinphoneCore* lc) { } void linphone_core_notify_refer_received(LinphoneCore *lc, const char *refer_to) { - NOTIFY_IF_EXIST(refer_received)(lc,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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + NOTIFY_IF_EXIST(log_collection_upload_progress_indication, lc, offset, total); cleanup_dead_vtable_refs(lc); } diff --git a/coreapi/xml.c b/coreapi/xml.c index b4b994174..8c7c3beaf 100644 --- a/coreapi/xml.c +++ b/coreapi/xml.c @@ -51,7 +51,7 @@ void linphone_xmlparsing_context_destroy(xmlparsing_context_t *ctx) { void linphone_xmlparsing_genericxml_error(void *ctx, const char *fmt, ...) { xmlparsing_context_t *xmlCtx = (xmlparsing_context_t *)ctx; - int sl = strlen(xmlCtx->errorBuffer); + size_t sl = strlen(xmlCtx->errorBuffer); va_list args; va_start(args, fmt); vsnprintf(xmlCtx->errorBuffer + sl, XMLPARSING_BUFFER_LEN - sl, fmt, args); diff --git a/coreapi/xml2lpc.c b/coreapi/xml2lpc.c index 57380bcd2..21437e61f 100644 --- a/coreapi/xml2lpc.c +++ b/coreapi/xml2lpc.c @@ -80,7 +80,7 @@ static void xml2lpc_log(xml2lpc_context *xmlCtx, int level, const char *fmt, ... static void xml2lpc_genericxml_error(void *ctx, const char *fmt, ...) { xml2lpc_context *xmlCtx = (xml2lpc_context *)ctx; - int sl = strlen(xmlCtx->errorBuffer); + size_t sl = strlen(xmlCtx->errorBuffer); va_list args; va_start(args, fmt); vsnprintf(xmlCtx->errorBuffer + sl, XML2LPC_BZ-sl, fmt, args); @@ -89,7 +89,7 @@ static void xml2lpc_genericxml_error(void *ctx, const char *fmt, ...) { static void xml2lpc_genericxml_warning(void *ctx, const char *fmt, ...) { xml2lpc_context *xmlCtx = (xml2lpc_context *)ctx; - int sl = strlen(xmlCtx->warningBuffer); + size_t sl = strlen(xmlCtx->warningBuffer); va_list args; va_start(args, fmt); vsnprintf(xmlCtx->warningBuffer + sl, XML2LPC_BZ-sl, fmt, args); diff --git a/coreapi/xmlrpc.c b/coreapi/xmlrpc.c new file mode 100644 index 000000000..f2173e510 --- /dev/null +++ b/coreapi/xmlrpc.c @@ -0,0 +1,429 @@ +/* +linphone +Copyright (C) 2010-2015 Belledonne Communications SARL + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "linphonecore.h" +#include "private.h" + +#include +#include +#include + + + +BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneXmlRpcRequestCbs); + +BELLE_SIP_INSTANCIATE_VPTR(LinphoneXmlRpcRequestCbs, belle_sip_object_t, + NULL, // destroy + NULL, // clone + NULL, // marshal + FALSE +); + +static LinphoneXmlRpcRequestCbs * linphone_xml_rpc_request_cbs_new(void) { + return belle_sip_object_new(LinphoneXmlRpcRequestCbs); +} + +LinphoneXmlRpcRequestCbs * linphone_xml_rpc_request_cbs_ref(LinphoneXmlRpcRequestCbs *cbs) { + belle_sip_object_ref(cbs); + return cbs; +} + +void linphone_xml_rpc_request_cbs_unref(LinphoneXmlRpcRequestCbs *cbs) { + belle_sip_object_unref(cbs); +} + +void *linphone_xml_rpc_request_cbs_get_user_data(const LinphoneXmlRpcRequestCbs *cbs) { + return cbs->user_data; +} + +void linphone_xml_rpc_request_cbs_set_user_data(LinphoneXmlRpcRequestCbs *cbs, void *ud) { + cbs->user_data = ud; +} + +LinphoneXmlRpcRequestCbsResponseCb linphone_xml_rpc_request_cbs_get_response(const LinphoneXmlRpcRequestCbs *cbs) { + return cbs->response; +} + +void linphone_xml_rpc_request_cbs_set_response(LinphoneXmlRpcRequestCbs *cbs, LinphoneXmlRpcRequestCbsResponseCb cb) { + cbs->response = cb; +} + + +static void format_request(LinphoneXmlRpcRequest *request) { + char si[64]; + belle_sip_list_t *arg_ptr = request->arg_list; + xmlBufferPtr buf; + xmlTextWriterPtr writer; + int err; + + if (request->content != NULL) { + belle_sip_free(request->content); + request->content = NULL; + } + + buf = xmlBufferCreate(); + if (buf == NULL) { + ms_error("Error creating the XML buffer"); + return; + } + writer = xmlNewTextWriterMemory(buf, 0); + if (writer == NULL) { + ms_error("Error creating the XML writer"); + return; + } + + err = xmlTextWriterStartDocument(writer, "1.0", "UTF-8", NULL); + if (err >= 0) { + err = xmlTextWriterStartElement(writer, (const xmlChar *)"methodCall"); + } + if (err >= 0) { + err = xmlTextWriterWriteElement(writer, (const xmlChar *)"methodName", (const xmlChar *)request->method); + } + if (err >= 0) { + err = xmlTextWriterStartElement(writer, (const xmlChar *)"params"); + } + while (arg_ptr != NULL) { + LinphoneXmlRpcArg *arg = (LinphoneXmlRpcArg *)arg_ptr->data; + if (err >= 0) { + err = xmlTextWriterStartElement(writer, (const xmlChar *)"param"); + } + if (err >= 0) { + err = xmlTextWriterStartElement(writer, (const xmlChar *)"value"); + } + switch (arg->type) { + case LinphoneXmlRpcArgNone: + break; + case LinphoneXmlRpcArgInt: + memset(si, 0, sizeof(si)); + snprintf(si, sizeof(si), "%i", arg->data.i); + err = xmlTextWriterWriteElement(writer, (const xmlChar *)"int", (const xmlChar *)si); + break; + case LinphoneXmlRpcArgString: + err = xmlTextWriterWriteElement(writer, (const xmlChar *)"string", (const xmlChar *)arg->data.s); + break; + } + if (err >= 0) { + /* Close the "value" element. */ + err = xmlTextWriterEndElement(writer); + } + if (err >= 0) { + /* Close the "param" element. */ + err = xmlTextWriterEndElement(writer); + } + arg_ptr = arg_ptr->next; + } + if (err >= 0) { + /* Close the "params" element. */ + err = xmlTextWriterEndElement(writer); + } + if (err >= 0) { + /* Close the "methodCall" element. */ + err = xmlTextWriterEndElement(writer); + } + if (err >= 0) { + err = xmlTextWriterEndDocument(writer); + } + if (err > 0) { + /* xmlTextWriterEndDocument returns the size of the content. */ + request->content = belle_sip_strdup((const char *)buf->content); + } + xmlFreeTextWriter(writer); + xmlBufferFree(buf); +} + +static void free_arg(LinphoneXmlRpcArg *arg) { + if ((arg->type == LinphoneXmlRpcArgString) && (arg->data.s != NULL)) { + belle_sip_free(arg->data.s); + } + belle_sip_free(arg); +} + +static void process_io_error_from_post_xml_rpc_request(void *data, const belle_sip_io_error_event_t *event) { + LinphoneXmlRpcRequest *request = (LinphoneXmlRpcRequest *)data; + ms_error("I/O Error during XML-RPC request sending"); + request->status = LinphoneXmlRpcStatusFailed; + if (request->callbacks->response != NULL) { + request->callbacks->response(request); + } + linphone_xml_rpc_request_unref(request); +} + +static void process_auth_requested_from_post_xml_rpc_request(void *data, belle_sip_auth_event_t *event) { + LinphoneXmlRpcRequest *request = (LinphoneXmlRpcRequest *)data; + ms_error("Authentication error during XML-RPC request sending"); + request->status = LinphoneXmlRpcStatusFailed; + if (request->callbacks->response != NULL) { + request->callbacks->response(request); + } + linphone_xml_rpc_request_unref(request); +} + +static void parse_valid_xml_rpc_response(LinphoneXmlRpcRequest *request, const char *response_body) { + xmlparsing_context_t *xml_ctx = linphone_xmlparsing_context_new(); + xmlSetGenericErrorFunc(xml_ctx, linphone_xmlparsing_genericxml_error); + request->status = LinphoneXmlRpcStatusFailed; + xml_ctx->doc = xmlReadDoc((const unsigned char*)response_body, 0, NULL, 0); + if (xml_ctx->doc != NULL) { + const char *response_str = NULL; + if (linphone_create_xml_xpath_context(xml_ctx) < 0) goto end; + switch (request->response.type) { + case LinphoneXmlRpcArgInt: + response_str = linphone_get_xml_text_content(xml_ctx, "/methodResponse/params/param/value/int"); + if (response_str != NULL) { + request->response.data.i = atoi(response_str); + request->status = LinphoneXmlRpcStatusOk; + } + break; + case LinphoneXmlRpcArgString: + response_str = linphone_get_xml_text_content(xml_ctx, "/methodResponse/params/param/value/string"); + if (response_str != NULL) { + request->response.data.s = belle_sip_strdup(response_str); + request->status = LinphoneXmlRpcStatusOk; + } + break; + default: + break; + } + if (response_str) linphone_free_xml_text_content(response_str); + } else { + ms_warning("Wrongly formatted XML-RPC response: %s", xml_ctx->errorBuffer); + } +end: + linphone_xmlparsing_context_destroy(xml_ctx); + if (request->callbacks->response != NULL) { + request->callbacks->response(request); + } +} + +static void notify_xml_rpc_error(LinphoneXmlRpcRequest *request) { + request->status = LinphoneXmlRpcStatusOk; + if (request->callbacks->response != NULL) { + request->callbacks->response(request); + } +} + +static void process_response_from_post_xml_rpc_request(void *data, const belle_http_response_event_t *event) { + LinphoneXmlRpcRequest *request = (LinphoneXmlRpcRequest *)data; + + /* Check the answer code */ + if (event->response) { + int code = belle_http_response_get_status_code(event->response); + if (code == 200) { /* Valid response from the server. */ + parse_valid_xml_rpc_response(request, belle_sip_message_get_body((belle_sip_message_t *)event->response)); + } else { + notify_xml_rpc_error(request); + } + } + linphone_xml_rpc_request_unref(request); +} + + +static LinphoneXmlRpcRequest * _linphone_xml_rpc_request_new(const char *method, LinphoneXmlRpcArgType return_type) { + LinphoneXmlRpcRequest *request = belle_sip_object_new(LinphoneXmlRpcRequest); + request->callbacks = linphone_xml_rpc_request_cbs_new(); + request->status = LinphoneXmlRpcStatusPending; + request->response.type = return_type; + request->method = belle_sip_strdup(method); + return request; +} + +static void _linphone_xml_rpc_request_add_int_arg(LinphoneXmlRpcRequest *request, int value) { + LinphoneXmlRpcArg *arg = belle_sip_malloc0(sizeof(LinphoneXmlRpcArg)); + arg->type = LinphoneXmlRpcArgInt; + arg->data.i = value; + request->arg_list = belle_sip_list_append(request->arg_list, arg); +} + +static void _linphone_xml_rpc_request_add_string_arg(LinphoneXmlRpcRequest *request, const char *value) { + LinphoneXmlRpcArg *arg = belle_sip_malloc0(sizeof(LinphoneXmlRpcArg)); + arg->type = LinphoneXmlRpcArgString; + arg->data.s = belle_sip_strdup(value); + request->arg_list = belle_sip_list_append(request->arg_list, arg); +} + +static void _linphone_xml_rpc_request_destroy(LinphoneXmlRpcRequest *request) { + belle_sip_list_free_with_data(request->arg_list, (void (*)(void*))free_arg); + if ((request->response.type == LinphoneXmlRpcArgString) && (request->response.data.s != NULL)) { + belle_sip_free(request->response.data.s); + } + if (request->content) belle_sip_free(request->content); + belle_sip_free(request->method); + linphone_xml_rpc_request_cbs_unref(request->callbacks); +} + +static void _linphone_xml_rpc_session_destroy(LinphoneXmlRpcSession *session) { + belle_sip_free(session->url); +} + +BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneXmlRpcRequest); +BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneXmlRpcSession); + +BELLE_SIP_INSTANCIATE_VPTR(LinphoneXmlRpcRequest, belle_sip_object_t, + (belle_sip_object_destroy_t)_linphone_xml_rpc_request_destroy, + NULL, // clone + NULL, // marshal + FALSE +); + +BELLE_SIP_INSTANCIATE_VPTR(LinphoneXmlRpcSession, belle_sip_object_t, + (belle_sip_object_destroy_t)_linphone_xml_rpc_session_destroy, + NULL, // clone + NULL, // marshal + FALSE +); + + +LinphoneXmlRpcRequest * linphone_xml_rpc_request_new(const char *method, LinphoneXmlRpcArgType return_type) { + LinphoneXmlRpcRequest *request = _linphone_xml_rpc_request_new(method, return_type); + format_request(request); + return request; +} + +LinphoneXmlRpcRequest * linphone_xml_rpc_request_new_with_args(const char *method, LinphoneXmlRpcArgType return_type, ...) { + bool_t cont = TRUE; + va_list args; + LinphoneXmlRpcArgType arg_type; + LinphoneXmlRpcRequest *request = _linphone_xml_rpc_request_new(method, return_type); + va_start(args, return_type); + while (cont) { + arg_type = va_arg(args, LinphoneXmlRpcArgType); + switch (arg_type) { + case LinphoneXmlRpcArgNone: + cont = FALSE; + break; + case LinphoneXmlRpcArgInt: + _linphone_xml_rpc_request_add_int_arg(request, va_arg(args, int)); + break; + case LinphoneXmlRpcArgString: + _linphone_xml_rpc_request_add_string_arg(request, va_arg(args, char *)); + break; + } + } + va_end(args); + format_request(request); + return request; +} + +LinphoneXmlRpcRequest * linphone_xml_rpc_request_ref(LinphoneXmlRpcRequest *request) { + belle_sip_object_ref(request); + return request; +} + +void linphone_xml_rpc_request_unref(LinphoneXmlRpcRequest *request) { + belle_sip_object_unref(request); +} + +void *linphone_xml_rpc_request_get_user_data(const LinphoneXmlRpcRequest *request) { + return request->user_data; +} + +void linphone_xml_rpc_request_set_user_data(LinphoneXmlRpcRequest *request, void *ud) { + request->user_data = ud; +} + +void linphone_xml_rpc_request_add_int_arg(LinphoneXmlRpcRequest *request, int value) { + _linphone_xml_rpc_request_add_int_arg(request, value); + format_request(request); +} + +void linphone_xml_rpc_request_add_string_arg(LinphoneXmlRpcRequest *request, const char *value) { + _linphone_xml_rpc_request_add_string_arg(request, value); + format_request(request); +} + +LinphoneXmlRpcRequestCbs * linphone_xml_rpc_request_get_callbacks(const LinphoneXmlRpcRequest *request) { + return request->callbacks; +} + +const char * linphone_xml_rpc_request_get_content(const LinphoneXmlRpcRequest *request) { + return request->content; +} + +LinphoneXmlRpcStatus linphone_xml_rpc_request_get_status(const LinphoneXmlRpcRequest *request) { + return request->status; +} + +int linphone_xml_rpc_request_get_int_response(const LinphoneXmlRpcRequest *request) { + return request->response.data.i; +} + +const char * linphone_xml_rpc_request_get_string_response(const LinphoneXmlRpcRequest *request) { + return request->response.data.s; +} + + +LinphoneXmlRpcSession * linphone_xml_rpc_session_new(LinphoneCore *core, const char *url) { + LinphoneXmlRpcSession *session = belle_sip_object_new(LinphoneXmlRpcSession); + session->core = core; + session->url = belle_sip_strdup(url); + return session; +} + +LinphoneXmlRpcSession * linphone_xml_rpc_session_ref(LinphoneXmlRpcSession *session) { + belle_sip_object_ref(session); + return session; +} + +void linphone_xml_rpc_session_unref(LinphoneXmlRpcSession *session) { + belle_sip_object_unref(session); +} + +void *linphone_xml_rpc_session_get_user_data(const LinphoneXmlRpcSession *session) { + return session->user_data; +} + +void linphone_xml_rpc_session_set_user_data(LinphoneXmlRpcSession *session, void *ud) { + session->user_data = ud; +} + +void linphone_xml_rpc_session_send_request(LinphoneXmlRpcSession *session, LinphoneXmlRpcRequest *request) { + belle_http_request_listener_callbacks_t cbs = { 0 }; + belle_http_request_listener_t *l; + belle_generic_uri_t *uri; + belle_http_request_t *req; + belle_sip_memory_body_handler_t *bh; + const char *data; + LinphoneContent *content; + linphone_xml_rpc_request_ref(request); + + uri = belle_generic_uri_parse(session->url); + if (!uri) { + ms_error("Could not send request, URL %s is invalid", session->url); + process_io_error_from_post_xml_rpc_request(request, NULL); + return; + } + req = belle_http_request_create("POST", uri, belle_sip_header_content_type_create("text", "xml"), NULL); + if (!req) { + belle_sip_object_unref(uri); + process_io_error_from_post_xml_rpc_request(request, NULL); + } + content = linphone_content_new(); + linphone_content_set_type(content, "text"); + linphone_content_set_subtype(content, "xml"); + linphone_content_set_string_buffer(content, linphone_xml_rpc_request_get_content(request)); + data = linphone_xml_rpc_request_get_content(request); + bh = belle_sip_memory_body_handler_new_copy_from_buffer(data, strlen(data), NULL, NULL); + belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(req), BELLE_SIP_BODY_HANDLER(bh)); + cbs.process_response = process_response_from_post_xml_rpc_request; + cbs.process_io_error = process_io_error_from_post_xml_rpc_request; + cbs.process_auth_requested = process_auth_requested_from_post_xml_rpc_request; + l = belle_http_request_listener_create_from_callbacks(&cbs, request); + belle_http_provider_send_request(session->core->http_provider, req, l); + linphone_content_unref(content); +} diff --git a/coreapi/xmlrpc.h b/coreapi/xmlrpc.h new file mode 100644 index 000000000..b985359c5 --- /dev/null +++ b/coreapi/xmlrpc.h @@ -0,0 +1,260 @@ +/* +xmlrpc.h +Copyright (C) 2010-2015 Belledonne Communications SARL + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef LINPHONE_XMLRPC_H_ +#define LINPHONE_XMLRPC_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @addtogroup misc + * @{ + */ + +/** +* Enum describing the types of argument for LinphoneXmlRpcRequest. +**/ +typedef enum _LinphoneXmlRpcArgType { + LinphoneXmlRpcArgNone, + LinphoneXmlRpcArgInt, + LinphoneXmlRpcArgString +} LinphoneXmlRpcArgType; + +/** +* Enum describing the status of a LinphoneXmlRpcRequest. +**/ +typedef enum _LinphoneXmlRpcStatus { + LinphoneXmlRpcStatusPending, + LinphoneXmlRpcStatusOk, + LinphoneXmlRpcStatusFailed +} LinphoneXmlRpcStatus; + +/** + * The LinphoneXmlRpcRequest object representing a XML-RPC request to be sent. +**/ +typedef struct _LinphoneXmlRpcRequest LinphoneXmlRpcRequest; + +/** + * An object to handle the callbacks for handling the LinphoneXmlRpcRequest operations. +**/ +typedef struct _LinphoneXmlRpcRequestCbs LinphoneXmlRpcRequestCbs; + +/** + * The LinphoneXmlRpcSession object used to send XML-RPC requests and handle their responses. +**/ +typedef struct _LinphoneXmlRpcSession LinphoneXmlRpcSession; + +/** + * Callback used to notify the response to an XML-RPC request. + * @param[in] request LinphoneXmlRpcRequest object +**/ +typedef void (*LinphoneXmlRpcRequestCbsResponseCb)(LinphoneXmlRpcRequest *request); + + +/** + * Create a new LinphoneXmlRpcRequest object. + * @param[in] method The XML-RPC method to call. + * @param[in] return_type The expected XML-RPC response type. + * @return A new LinphoneXmlRpcRequest object. +**/ +LINPHONE_PUBLIC LinphoneXmlRpcRequest * linphone_xml_rpc_request_new(const char *method, LinphoneXmlRpcArgType return_type); + +/** + * Create a new LinphoneXmlRpcRequest object giving the arguments to the method call. + * @param[in] method The XML-RPC method to call. + * @param[in] return_type The expected XML-RPC response type. + * @return A new LinphoneXmlRpcRequest object. +**/ +LINPHONE_PUBLIC LinphoneXmlRpcRequest * linphone_xml_rpc_request_new_with_args(const char *method, LinphoneXmlRpcArgType return_type, ...); + +/** + * Acquire a reference to the XML-RPC request. + * @param[in] request LinphoneXmlRpcRequest object. + * @return The same LinphoneXmlRpcRequest object. +**/ +LINPHONE_PUBLIC LinphoneXmlRpcRequest * linphone_xml_rpc_request_ref(LinphoneXmlRpcRequest *request); + +/** + * Release reference to the XML-RPC request. + * @param[in] request LinphoneXmlRpcRequest object. +**/ +LINPHONE_PUBLIC void linphone_xml_rpc_request_unref(LinphoneXmlRpcRequest *request); + +/** + * Retrieve the user pointer associated with the XML-RPC request. + * @param[in] request LinphoneXmlRpcRequest object. + * @return The user pointer associated with the XML-RPC request. +**/ +LINPHONE_PUBLIC void *linphone_xml_rpc_request_get_user_data(const LinphoneXmlRpcRequest *request); + +/** + * Assign a user pointer to the XML-RPC request. + * @param[in] request LinphoneXmlRpcRequest object. + * @param[in] ud The user pointer to associate with the XML-RPC request. +**/ +LINPHONE_PUBLIC void linphone_xml_rpc_request_set_user_data(LinphoneXmlRpcRequest *request, void *ud); + +/** + * Add an integer argument to an XML-RPC request. + * @param[in] request LinphoneXmlRpcRequest object. + * @param[in] value The integer value of the added argument. +**/ +LINPHONE_PUBLIC void linphone_xml_rpc_request_add_int_arg(LinphoneXmlRpcRequest *request, int value); + +/** + * Add a string argument to an XML-RPC request. + * @param[in] request LinphoneXmlRpcRequest object. + * @param[in] value The string value of the added argument. +**/ +LINPHONE_PUBLIC void linphone_xml_rpc_request_add_string_arg(LinphoneXmlRpcRequest *request, const char *value); + +/** + * Get the LinphoneXmlRpcRequestCbs object associated with a LinphoneXmlRpcRequest. + * @param[in] request LinphoneXmlRpcRequest object + * @return The LinphoneXmlRpcRequestCbs object associated with the LinphoneXmlRpcRequest. +**/ +LINPHONE_PUBLIC LinphoneXmlRpcRequestCbs * linphone_xml_rpc_request_get_callbacks(const LinphoneXmlRpcRequest *request); + +/** + * Get the content of the XML-RPC request. + * @param[in] request LinphoneXmlRpcRequest object. + * @return The string representation of the content of the XML-RPC request. + */ +LINPHONE_PUBLIC const char * linphone_xml_rpc_request_get_content(const LinphoneXmlRpcRequest *request); + +/** + * Get the status of the XML-RPC request. + * @param[in] request LinphoneXmlRpcRequest object. + * @return The status of the XML-RPC request. +**/ +LINPHONE_PUBLIC LinphoneXmlRpcStatus linphone_xml_rpc_request_get_status(const LinphoneXmlRpcRequest *request); + +/** + * Get the response to an XML-RPC request sent with linphone_xml_rpc_session_send_request() and returning an integer response. + * @param[in] request LinphoneXmlRpcRequest object. + * @return The integer response to the XML-RPC request. +**/ +LINPHONE_PUBLIC int linphone_xml_rpc_request_get_int_response(const LinphoneXmlRpcRequest *request); + +/** +* Get the response to an XML-RPC request sent with linphone_xml_rpc_session_send_request() and returning a string response. +* @param[in] request LinphoneXmlRpcRequest object. +* @return The string response to the XML-RPC request. +**/ +LINPHONE_PUBLIC const char * linphone_xml_rpc_request_get_string_response(const LinphoneXmlRpcRequest *request); + + +/** + * Create a new LinphoneXmlRpcSession object. + * @param[in] core The LinphoneCore object used to send the XML-RPC requests. + * @param[in] url The URL of the XML-RPC server to send the XML-RPC requests to. + * @return A new LinphoneXmlRpcSession object. + */ +LINPHONE_PUBLIC LinphoneXmlRpcSession * linphone_xml_rpc_session_new(LinphoneCore *core, const char *url); + +/** + * Acquire a reference to the XML-RPC session. + * @param[in] session LinphoneXmlRpcSession object. + * @return The same LinphoneXmlRpcSession object. +**/ +LINPHONE_PUBLIC LinphoneXmlRpcSession * linphone_xml_rpc_session_ref(LinphoneXmlRpcSession *session); + +/** + * Release reference to the XML-RPC session. + * @param[in] session LinphoneXmlRpcSession object. +**/ +LINPHONE_PUBLIC void linphone_xml_rpc_session_unref(LinphoneXmlRpcSession *session); + +/** + * Retrieve the user pointer associated with the XML-RPC session. + * @param[in] session LinphoneXmlRpcSession object. + * @return The user pointer associated with the XML-RPC session. +**/ +LINPHONE_PUBLIC void *linphone_xml_rpc_session_get_user_data(const LinphoneXmlRpcSession *session); + +/** + * Assign a user pointer to the XML-RPC session. + * @param[in] session LinphoneXmlRpcSession object. + * @param[in] ud The user pointer to associate with the XML-RPC session. +**/ +LINPHONE_PUBLIC void linphone_xml_rpc_session_set_user_data(LinphoneXmlRpcSession *session, void *ud); + +/** + * Send an XML-RPC request. + * @param[in] session LinphoneXmlRpcSession object. + * @param[in] request The LinphoneXmlRpcRequest to be sent. +**/ +LINPHONE_PUBLIC void linphone_xml_rpc_session_send_request(LinphoneXmlRpcSession *session, LinphoneXmlRpcRequest *request); + + +/** + * Acquire a reference to a LinphoneXmlRpcRequestCbs object. + * @param[in] cbs LinphoneXmlRpcRequestCbs object. + * @return The same LinphoneXmlRpcRequestCbs object. +**/ +LINPHONE_PUBLIC LinphoneXmlRpcRequestCbs * linphone_xml_rpc_request_cbs_ref(LinphoneXmlRpcRequestCbs *cbs); + +/** + * Release a reference to a LinphoneXmlRpcRequestCbs object. + * @param[in] cbs LinphoneXmlRpcRequestCbs object. +**/ +LINPHONE_PUBLIC void linphone_xml_rpc_request_cbs_unref(LinphoneXmlRpcRequestCbs *cbs); + +/** + * Retrieve the user pointer associated with a LinphoneXmlRpcRequestCbs object. + * @param[in] cbs LinphoneXmlRpcRequestCbs object. + * @return The user pointer associated with the LinphoneXmlRpcRequestCbs object. +**/ +LINPHONE_PUBLIC void *linphone_xml_rpc_request_cbs_get_user_data(const LinphoneXmlRpcRequestCbs *cbs); + +/** + * Assign a user pointer to a LinphoneXmlRpcRequestCbs object. + * @param[in] cbs LinphoneXmlRpcRequestCbs object. + * @param[in] ud The user pointer to associate with the LinphoneXmlRpcRequestCbs object. +**/ +LINPHONE_PUBLIC void linphone_xml_rpc_request_cbs_set_user_data(LinphoneXmlRpcRequestCbs *cbs, void *ud); + +/** + * Get the response callback. + * @param[in] cbs LinphoneXmlRpcRequestCbs object. + * @return The current response callback. +**/ +LINPHONE_PUBLIC LinphoneXmlRpcRequestCbsResponseCb linphone_xml_rpc_request_cbs_get_response(const LinphoneXmlRpcRequestCbs *cbs); + +/** + * Set the response callback. + * @param[in] cbs LinphoneXmlRpcRequestCbs object. + * @param[in] cb The response callback to be used. +**/ +LINPHONE_PUBLIC void linphone_xml_rpc_request_cbs_set_response(LinphoneXmlRpcRequestCbs *cbs, LinphoneXmlRpcRequestCbsResponseCb cb); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* LINPHONE_XMLRPC_H_ */ diff --git a/gtk/CMakeLists.txt b/gtk/CMakeLists.txt index 848a872b9..6ac8f33b1 100644 --- a/gtk/CMakeLists.txt +++ b/gtk/CMakeLists.txt @@ -20,28 +20,28 @@ # ############################################################################ -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 audio_assistant.ui buddylookup.ui + callee_frame.ui call_logs.ui call_statistics.ui + chatroom_frame.ui + conf_frame.ui config-uri.ui contact.ui dscp_settings.ui + in_call_frame.ui keypad.ui ldap.ui + login_frame.ui log.ui main.ui parameters.ui password.ui provisioning-fetch.ui + setup_wizard.ui sip_account.ui tunnel_config.ui waiting.ui @@ -71,18 +71,14 @@ set(SOURCE_FILES utils.c videowindow.c ) +if(ENABLE_ASSISTANT) + list(APPEND SOURCE_FILES setupwizard.c) +endif() if(WIN32) list(APPEND SOURCE_FILES linphone.rc) endif() -if(ENABLE_ASSISTANT) - list(APPEND SOURCE_FILES setupwizard.c) -endif() - -if(GETTEXT_FOUND) - add_definitions("-DENABLE_NLS") -endif() - +apply_compile_flags(SOURCE_FILES "CPP" "C") if(WIN32) add_executable(linphone-gtk WIN32 ${SOURCE_FILES}) else() @@ -91,7 +87,7 @@ 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) +if(INTL_FOUND) target_link_libraries(linphone-gtk ${INTL_LIBRARIES}) endif() if(WIN32) @@ -101,8 +97,12 @@ if(ENABLE_NOTIFY) target_include_directories(linphone-gtk PUBLIC ${NOTIFY_INCLUDE_DIRS}) target_link_libraries(linphone-gtk ${NOTIFY_LIBRARIES}) endif() -if(ENABLE_ASSISTANT) - target_link_libraries(linphone-gtk ${SOUP_LIBRARIES}) +if(HAVE_LIBUDEV_H) + target_link_libraries(linphone-gtk udev) +endif() +if(GTKMACINTEGRATION_FOUND) + target_include_directories(linphone-gtk PUBLIC ${GTKMACINTEGRATION_INCLUDE_DIRS}) + target_link_libraries(linphone-gtk ${GTKMACINTEGRATION_LIBRARIES}) endif() install(TARGETS linphone-gtk diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 32656c993..37bd7f7ee 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -15,7 +15,13 @@ UI_FILES= about.ui \ ldap.ui \ config-uri.ui \ provisioning-fetch.ui \ - audio_assistant.ui + audio_assistant.ui \ + chatroom_frame.ui \ + in_call_frame.ui \ + conf_frame.ui \ + callee_frame.ui \ + login_frame.ui \ + setup_wizard.ui PIXMAPS= \ stock_people.png @@ -23,13 +29,12 @@ PIXMAPS= \ LINPHONE_ICO_RC_FILE=linphone.rc LINPHONE_ICO_FILE=linphone.ico -EXTRA_DIST= $(PIXMAPS) \ - $(UI_FILES) \ - linphone.iss \ - $(LINPHONE_ICO_RC_FILE) \ - $(LINPHONE_ICO_FILE) - gtkrc \ - gtkrc.mac +EXTRA_DIST= \ + linphone.iss \ + $(LINPHONE_ICO_RC_FILE) \ + $(LINPHONE_ICO_FILE) + gtkrc \ + gtkrc.mac if BUILD_GTK_UI @@ -56,7 +61,12 @@ linphone_SOURCES= \ audio_assistant.c \ videowindow.c \ status_icon.c status_icon.h \ - linphone.h + linphone.h regex.h + +if BUILD_WIZARD +linphone_SOURCES+= \ + setupwizard.c setupwizard.h +endif if BUILD_STATUS_NOTIFIER linphone_SOURCES+= \ @@ -64,11 +74,6 @@ linphone_SOURCES+= \ status_notifier.h endif -if BUILD_WIZARD -linphone_SOURCES+= \ - setupwizard.c -endif - linphone_LDADD= $(top_builddir)/coreapi/liblinphone.la \ $(LIBGTK_LIBS) $(NOTIFY1_LIBS) $(NOTIFY4_LIBS) $(LIBGTKMAC_LIBS) $(INTLLIBS) $(SQLITE3_LIBS) $(BELLESIP_LIBS) @@ -85,12 +90,12 @@ linphone_LDFLAGS=-export-dynamic endif uidir=$(datadir)/linphone -ui_DATA=$(UI_FILES) $(PIXMAPS) $(top_srcdir)/COPYING +dist_ui_DATA=$(UI_FILES) $(PIXMAPS) $(top_srcdir)/COPYING endif -AM_CFLAGS= -DIN_LINPHONE -I$(top_srcdir)/coreapi/ \ +AM_CFLAGS= -DIN_LINPHONE -I$(top_srcdir)/coreapi/ -I$(top_builddir)/coreapi/ \ $(MEDIASTREAMER_CFLAGS) \ $(ORTP_CFLAGS) $(BELLESIP_CFLAGS) \ $(STRICT_OPTIONS) $(STRICT_OPTIONS_CC) $(LIBGTK_CFLAGS) $(LIBGTKMAC_CFLAGS) $(IPV6_CFLAGS) \ diff --git a/gtk/audio_assistant.c b/gtk/audio_assistant.c index 815752a2d..b10a2c93a 100644 --- a/gtk/audio_assistant.c +++ b/gtk/audio_assistant.c @@ -57,7 +57,12 @@ static void activate_play_button(gboolean is_active){ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(play_button),is_active); } -static gchar *get_record_file(){ +static gboolean deactivate_play_button(void){ + activate_play_button(FALSE); + return FALSE; +} + +static gchar *get_record_file(void){ char filename[256]={0}; char date[64]={0}; time_t curtime=time(NULL); @@ -239,7 +244,9 @@ static void endoffile_cb(void *ud, MSFilter *f, unsigned int ev,void * arg){ switch (ev) { case MS_PLAYER_EOF: { ms_message("EndOfFile received"); - activate_play_button(FALSE); + /*workaround for a mediastreamer2 bug. Don't deactivate the play button, because it will stop the graph from the end of file callback, + * which is sometimes crashing. On master branch it is fixed in mediastreamer2, the workaround is only valid in 3.8.x branch*/ + g_timeout_add(0, (GSourceFunc)deactivate_play_button, NULL); break; } break; @@ -284,7 +291,7 @@ void display_popup(GtkMessageType type,const gchar *message){ gtk_widget_show(dialog); } -static void open_mixer(){ +static void open_mixer(void){ GError *error = NULL; #ifdef WIN32 @@ -313,7 +320,7 @@ static void open_mixer(){ #endif } -static GtkWidget *create_intro(){ +static GtkWidget *create_intro(void){ GtkWidget *vbox=gtk_vbox_new(FALSE,2); GtkWidget *label=gtk_label_new(_("Welcome!\nThis assistant will help you to configure audio settings for Linphone")); gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 2); @@ -321,7 +328,7 @@ static GtkWidget *create_intro(){ return vbox; } -static GtkWidget *create_mic_page(){ +static GtkWidget *create_mic_page(void){ GtkWidget *vbox=gtk_table_new(3,2,FALSE); LinphoneCore *lc=linphone_gtk_get_core(); const char **sound_devices; @@ -362,7 +369,7 @@ static GtkWidget *create_mic_page(){ return vbox; } -static GtkWidget *create_speaker_page(){ +static GtkWidget *create_speaker_page(void){ GtkWidget *vbox=gtk_table_new(3,2,FALSE); LinphoneCore *lc=linphone_gtk_get_core(); @@ -398,7 +405,7 @@ static GtkWidget *create_speaker_page(){ return vbox; } -static GtkWidget *create_play_record_page(){ +static GtkWidget *create_play_record_page(void){ GtkWidget *vbox=gtk_table_new(2,2,FALSE); GtkWidget *labelRecord=gtk_label_new(_("Press the record button and say some words")); GtkWidget *labelPlay=gtk_label_new(_("Listen to your record voice")); @@ -428,7 +435,7 @@ static GtkWidget *create_play_record_page(){ return vbox; } -static GtkWidget *create_end_page(){ +static GtkWidget *create_end_page(void){ GtkWidget *vbox=gtk_vbox_new(FALSE,2); GtkWidget *label=gtk_label_new(_("Let's start Linphone now")); gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 2); @@ -497,7 +504,7 @@ void linphone_gtk_show_audio_assistant(void){ GtkWidget *end_page; if(audio_assistant!=NULL) return; - w=audio_assistant=linphone_gtk_create_window("audio_assistant"); + w=audio_assistant=linphone_gtk_create_window("audio_assistant", linphone_gtk_get_main_window()); gtk_window_set_resizable (GTK_WINDOW(w), FALSE); gtk_window_set_title(GTK_WINDOW(w),_("Audio Assistant")); diff --git a/gtk/buddylookup.c b/gtk/buddylookup.c index 4a6cb8d7a..3251611d2 100644 --- a/gtk/buddylookup.c +++ b/gtk/buddylookup.c @@ -71,7 +71,7 @@ GtkWidget * linphone_gtk_show_buddy_lookup_window(SipSetupContext *ctx){ GtkCellRenderer *renderer,*pbuf_renderer; GtkTreeViewColumn *column; GtkTreeSelection *select; - GtkWidget *w=linphone_gtk_create_window("buddylookup"); + GtkWidget *w=linphone_gtk_create_window("buddylookup", NULL); GtkWidget *results=linphone_gtk_get_widget(w,"search_results"); GtkProgressBar *pb=GTK_PROGRESS_BAR(linphone_gtk_get_widget(w,"progressbar")); diff --git a/gtk/callee_frame.ui b/gtk/callee_frame.ui new file mode 100644 index 000000000..4ae4d90ef --- /dev/null +++ b/gtk/callee_frame.ui @@ -0,0 +1,84 @@ + + + + + + True + False + 0 + none + + + True + False + 12 + + + True + False + 12 + + + True + False + + + True + False + + + True + True + + + False + False + 0 + + + + + False + True + 0 + + + + + True + False + <b>Callee name</b> + True + right + end + + + True + True + 1 + + + + + 90 + 30 + True + False + + + False + True + 2 + + + + + + + + + + + + + diff --git a/gtk/calllogs.c b/gtk/calllogs.c index 51fcb260b..713ed6e96 100644 --- a/gtk/calllogs.c +++ b/gtk/calllogs.c @@ -19,12 +19,40 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "linphone.h" +#define CONFIG_FILE ".linphone-call-history.db" + +char *linphone_gtk_call_logs_storage_get_db_file(const char *filename){ + const int path_max=1024; + char *db_file=NULL; + + db_file=(char *)g_malloc(path_max*sizeof(char)); + if (filename==NULL) filename=CONFIG_FILE; + /*try accessing a local file first if exists*/ + if (access(CONFIG_FILE,F_OK)==0){ + snprintf(db_file,path_max,"%s",filename); + }else{ +#ifdef WIN32 + const char *appdata=getenv("APPDATA"); + if (appdata){ + snprintf(db_file,path_max,"%s\\%s",appdata,LINPHONE_CONFIG_DIR); + CreateDirectory(db_file,NULL); + snprintf(db_file,path_max,"%s\\%s\\%s",appdata,LINPHONE_CONFIG_DIR,filename); + } +#else + const char *home=getenv("HOME"); + if (home==NULL) home="."; + snprintf(db_file,path_max,"%s/%s",home,filename); +#endif + } + return db_file; +} + static void fill_renderers(GtkTreeView *v){ GtkTreeViewColumn *c; GtkCellRenderer *r; - r=gtk_cell_renderer_pixbuf_new(); - c=gtk_tree_view_column_new_with_attributes("icon",r,"pixbuf",0,NULL); + r=gtk_cell_renderer_pixbuf_new(); + c=gtk_tree_view_column_new_with_attributes("icon",r,"icon-name",0,NULL); gtk_tree_view_append_column (v,c); r=gtk_cell_renderer_text_new (); @@ -70,6 +98,7 @@ void linphone_gtk_call_log_chat_selected(GtkWidget *w){ } void linphone_gtk_call_log_add_contact(GtkWidget *w){ + GtkWidget *main_window = gtk_widget_get_toplevel(w); GtkTreeSelection *select; GtkTreeIter iter; @@ -87,7 +116,7 @@ void linphone_gtk_call_log_add_contact(GtkWidget *w){ if (la != NULL){ char *uri=linphone_address_as_string(la); lf=linphone_friend_new_with_address(uri); - linphone_gtk_show_contact(lf); + linphone_gtk_show_contact(lf, main_window); ms_free(uri); } } @@ -125,10 +154,11 @@ static void linphone_gtk_call_selected(GtkTreeView *treeview){ } static GtkWidget *linphone_gtk_create_call_log_menu(GtkWidget *call_log){ - GtkWidget *menu=gtk_menu_new(); + GtkWidget *menu=NULL; GtkWidget *menu_item; gchar *call_label=NULL; gchar *text_label=NULL; + gchar *add_contact_label=NULL; gchar *name=NULL; GtkWidget *image; GtkTreeSelection *select; @@ -147,34 +177,46 @@ static GtkWidget *linphone_gtk_create_call_log_menu(GtkWidget *call_log){ name=linphone_address_as_string(la); call_label=g_strdup_printf(_("Call %s"),name); text_label=g_strdup_printf(_("Send text to %s"),name); + if (!linphone_gtk_is_friend(linphone_gtk_get_core(), name)) { + add_contact_label=g_strdup_printf(_("Add %s to your contact list"),name); + } ms_free(name); + menu=gtk_menu_new(); } } - if (call_label){ + if (menu && call_label){ menu_item=gtk_image_menu_item_new_with_label(call_label); - image=gtk_image_new_from_stock(GTK_STOCK_NETWORK,GTK_ICON_SIZE_MENU); + image=gtk_image_new_from_icon_name("linphone-start-call",GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item),image); gtk_widget_show(image); gtk_widget_show(menu_item); gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item); g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_call_selected,call_log); } - if (text_label){ + if (menu && text_label){ menu_item=gtk_image_menu_item_new_with_label(text_label); - image=gtk_image_new_from_stock(GTK_STOCK_NETWORK,GTK_ICON_SIZE_MENU); + image=gtk_image_new_from_icon_name("linphone-start-chat",GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item),image); gtk_widget_show(image); gtk_widget_show(menu_item); gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item); g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_call_log_chat_selected,call_log); } - menu_item=gtk_image_menu_item_new_from_stock(GTK_STOCK_ADD,NULL); - gtk_widget_show(menu_item); - gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item); - g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_call_log_add_contact,call_log); - gtk_widget_show(menu); - gtk_menu_attach_to_widget(GTK_MENU(menu),call_log, NULL); + if (menu && add_contact_label){ + menu_item=gtk_image_menu_item_new_with_label(add_contact_label); + image=gtk_image_new_from_icon_name("linphone-contact-add",GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item),image); + gtk_widget_show(image); + gtk_widget_show(menu_item); + gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item); + g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_call_log_add_contact,call_log); + } + if (menu) { + gtk_widget_show(menu); + gtk_menu_attach_to_widget(GTK_MENU(menu),call_log, NULL); + } + if (add_contact_label) g_free(add_contact_label); if (call_label) g_free(call_label); if (text_label) g_free(text_label); return menu; @@ -182,9 +224,12 @@ static GtkWidget *linphone_gtk_create_call_log_menu(GtkWidget *call_log){ gboolean linphone_gtk_call_log_popup_contact(GtkWidget *list, GdkEventButton *event){ GtkWidget *m=linphone_gtk_create_call_log_menu(list); - gtk_menu_popup (GTK_MENU (m), NULL, NULL, NULL, NULL, - event ? event->button : 0, event ? event->time : gtk_get_current_event_time()); - return TRUE; + if (m) { + gtk_menu_popup (GTK_MENU (m), NULL, NULL, NULL, NULL, + event ? event->button : 0, event ? event->time : gtk_get_current_event_time()); + return TRUE; + } + return FALSE; } gboolean linphone_gtk_call_log_button_pressed(GtkWidget *widget, GdkEventButton *event){ @@ -194,20 +239,10 @@ gboolean linphone_gtk_call_log_button_pressed(GtkWidget *widget, GdkEventButton return FALSE; } -void linphone_gtk_call_log_clear_missed_call(){ - GtkWidget *mw=linphone_gtk_get_main_window(); - GtkNotebook *notebook=GTK_NOTEBOOK(linphone_gtk_get_widget(mw,"viewswitch")); - GtkWidget *page=gtk_notebook_get_nth_page(notebook,0); - GtkWidget *box=gtk_hbox_new(FALSE,0); - GtkWidget *image=gtk_image_new_from_stock(GTK_STOCK_REFRESH,GTK_ICON_SIZE_MENU); - GtkWidget *l; - const gchar*text=gtk_label_get_text(GTK_LABEL(linphone_gtk_get_widget(mw,"label3"))); - - l=gtk_label_new(text); - gtk_box_pack_start(GTK_BOX(box),image,FALSE,FALSE,0); - gtk_box_pack_start(GTK_BOX(box),l,FALSE,FALSE,0); - gtk_notebook_set_tab_label(notebook,page,box); - gtk_widget_show_all(box); +void linphone_gtk_call_log_clear_missed_call(void){ + GtkWidget *mw = linphone_gtk_get_main_window(); + GtkWidget *label = linphone_gtk_get_widget(mw, "history_tab_label"); + gtk_label_set_text(GTK_LABEL(label), _("Recent calls")); } gboolean linphone_gtk_call_log_reset_missed_call(GtkWidget *w, GdkEvent *event,gpointer user_data){ @@ -220,25 +255,10 @@ gboolean linphone_gtk_call_log_reset_missed_call(GtkWidget *w, GdkEvent *event,g } void linphone_gtk_call_log_display_missed_call(int nb){ - GtkWidget *mw=linphone_gtk_get_main_window(); - GtkNotebook *notebook=GTK_NOTEBOOK(linphone_gtk_get_widget(mw,"viewswitch")); - GtkWidget *page=gtk_notebook_get_nth_page(notebook,0); - GtkWidget *ebox=gtk_event_box_new(); - GtkWidget *box=gtk_hbox_new(FALSE,0); - GtkWidget *image=gtk_image_new_from_stock(GTK_STOCK_REFRESH,GTK_ICON_SIZE_MENU); - GtkWidget *l; - gchar *buf; - - buf=g_markup_printf_escaped(_("Recent calls (%i)"),nb); - l=gtk_label_new(NULL); - gtk_label_set_markup(GTK_LABEL(l),buf); - gtk_box_pack_start(GTK_BOX(box),image,FALSE,FALSE,0); - gtk_box_pack_start(GTK_BOX(box),l,FALSE,FALSE,0); - gtk_container_add(GTK_CONTAINER(ebox),box); - gtk_notebook_set_tab_label(notebook,page,ebox); - gtk_widget_add_events(ebox,GDK_BUTTON_PRESS_MASK); - g_signal_connect(G_OBJECT(ebox),"button_press_event",(GCallback)linphone_gtk_call_log_reset_missed_call,NULL); - gtk_widget_show_all(ebox); + GtkWidget *mw = linphone_gtk_get_main_window(); + GtkWidget *label = linphone_gtk_get_widget(mw, "history_tab_label"); + gchar *buf = g_markup_printf_escaped(_("Recent calls (%i)"), nb); + gtk_label_set_markup(GTK_LABEL(label), buf); } void linphone_gtk_call_log_update(GtkWidget *w){ @@ -251,7 +271,7 @@ void linphone_gtk_call_log_update(GtkWidget *w){ store=(GtkTreeStore*)gtk_tree_view_get_model(v); if (store==NULL){ - store=gtk_tree_store_new(3,GDK_TYPE_PIXBUF,G_TYPE_STRING,G_TYPE_POINTER,G_TYPE_STRING); + store=gtk_tree_store_new(3,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_POINTER,G_TYPE_STRING); gtk_tree_view_set_model(v,GTK_TREE_MODEL(store)); g_object_unref(G_OBJECT(store)); fill_renderers(GTK_TREE_VIEW(linphone_gtk_get_widget(w,"logs_view"))); @@ -260,8 +280,6 @@ void linphone_gtk_call_log_update(GtkWidget *w){ g_signal_connect_swapped(G_OBJECT(select),"changed",(GCallback)call_log_selection_changed,v); g_signal_connect(G_OBJECT(notebook),"focus-tab",(GCallback)linphone_gtk_call_log_reset_missed_call,NULL); g_signal_connect(G_OBJECT(v),"button-press-event",(GCallback)linphone_gtk_call_log_button_pressed,NULL); -// gtk_button_set_image(GTK_BUTTON(linphone_gtk_get_widget(w,"call_back_button")), -// create_pixmap (linphone_gtk_get_ui_config("callback_button","status-green.png"))); } nb=linphone_core_get_missed_calls_count(linphone_gtk_get_core()); if(nb > 0) @@ -281,8 +299,7 @@ void linphone_gtk_call_log_update(GtkWidget *w){ LinphoneFriend *lf=NULL; int duration=linphone_call_log_get_duration(cl); time_t start_date_time=linphone_call_log_get_start_date(cl); - GdkPixbuf *incoming; - GdkPixbuf *outgoing; + const gchar *call_status_icon_name; #if GLIB_CHECK_VERSION(2,26,0) if (start_date_time){ @@ -347,11 +364,10 @@ void linphone_gtk_call_log_update(GtkWidget *w){ g_free(seconds); if (start_date) g_free(start_date); gtk_tree_store_append (store,&iter,NULL); - - incoming = create_pixbuf("call_status_incoming.png"); - outgoing = create_pixbuf("call_status_outgoing.png"); + call_status_icon_name = linphone_call_log_get_dir(cl) == LinphoneCallOutgoing ? + "linphone-call-status-outgoing" : "linphone-call-status-incoming"; gtk_tree_store_set (store,&iter, - 0, linphone_call_log_get_dir(cl)==LinphoneCallOutgoing ? outgoing : incoming, + 0, call_status_icon_name, 1, headtxt,2,cl,-1); gtk_tree_store_append (store,&iter2,&iter); gtk_tree_store_set (store,&iter2,1,logtxt,-1); @@ -397,19 +413,3 @@ void linphone_gtk_call_log_response(GtkWidget *w, guint response_id){ g_object_set_data(G_OBJECT(mw),"call_logs",NULL); gtk_widget_destroy(w); } - -GtkWidget * linphone_gtk_show_call_logs(void){ - GtkWidget *mw=linphone_gtk_get_main_window(); - - GtkWidget *w=(GtkWidget*)g_object_get_data(G_OBJECT(linphone_gtk_get_main_window()),"call_logs"); - if (w==NULL){ - w=linphone_gtk_create_window("call_logs"); -// gtk_button_set_image(GTK_BUTTON(linphone_gtk_get_widget(w,"call_back_button")), -// create_pixmap (linphone_gtk_get_ui_config("callback_button","status-green.png"))); - g_object_set_data(G_OBJECT(mw),"call_logs",w); - g_signal_connect(G_OBJECT(w),"response",(GCallback)linphone_gtk_call_log_response,NULL); - gtk_widget_show(w); - linphone_gtk_call_log_update(w); - }else gtk_window_present(GTK_WINDOW(w)); - return w; -} diff --git a/gtk/chat.c b/gtk/chat.c index 5479b7330..ccae62bd0 100644 --- a/gtk/chat.c +++ b/gtk/chat.c @@ -31,13 +31,35 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define CONFIG_FILE ".linphone-history.db" -const char *linphone_gtk_message_storage_get_db_file(const char *filename){ +#include "regex.h" + +GRegex *uri_regex = NULL; + +static void free_uri_regex(void) { + if(uri_regex) g_regex_unref(uri_regex); +} + +static const GRegex *get_uri_regex(void) { + const gchar *pattern = BC_REGEX_URI; + GError *error = NULL; + if(uri_regex == NULL) { + uri_regex = g_regex_new(pattern, G_REGEX_OPTIMIZE, 0, &error); + if(error) { + g_warning("Could not parse regex pattern for URIs: %s", error->message); + g_error_free(error); + uri_regex = NULL; + return NULL; + } + atexit(free_uri_regex); + } + return uri_regex; +} + +char *linphone_gtk_message_storage_get_db_file(const char *filename){ const int path_max=1024; - static char *db_file=NULL; + char *db_file=NULL; - if (db_file) return db_file; - - db_file=(char *)malloc(path_max*sizeof(char)); + db_file=(char *)g_malloc(path_max*sizeof(char)); if (filename==NULL) filename=CONFIG_FILE; /*try accessing a local file first if exists*/ if (access(CONFIG_FILE,F_OK)==0){ @@ -66,19 +88,16 @@ void linphone_gtk_quit_chatroom(LinphoneChatRoom *cr) { GtkWidget *friendlist=linphone_gtk_get_widget(main_window,"contact_list"); GtkWidget *w=g_object_get_data(G_OBJECT(friendlist),"chatview"); gchar *from; - GHashTable *table=g_object_get_data(G_OBJECT(w),"table"); g_return_if_fail(w!=NULL); gtk_notebook_remove_page(GTK_NOTEBOOK(nb),gtk_notebook_page_num(GTK_NOTEBOOK(nb),w)); linphone_chat_room_mark_as_read(cr); - linphone_gtk_friend_list_update_chat_picture(); g_object_set_data(G_OBJECT(friendlist),"chatview",NULL); from=g_object_get_data(G_OBJECT(w),"from_message"); if (from){ g_object_set_data(G_OBJECT(w),"from_message",NULL); g_free(from); } - g_hash_table_destroy(table); g_object_set_data(G_OBJECT(w),"cr",NULL); linphone_gtk_friend_list_set_active_address(NULL); gtk_widget_destroy(w); @@ -93,44 +112,16 @@ const char* get_display_name(const LinphoneAddress *from){ return display; } -GtkWidget *create_tab_chat_header(LinphoneChatRoom *cr,const LinphoneAddress *uri){ - GtkWidget *w=gtk_hbox_new (FALSE,0); - GtkWidget *i=create_pixmap ("chat.png"); - GtkWidget *l; - GtkWidget *image=gtk_image_new_from_stock(GTK_STOCK_CLOSE,GTK_ICON_SIZE_MENU); - GtkWidget *b=gtk_button_new(); - - gtk_button_set_image(GTK_BUTTON(b),image); - gtk_button_set_relief(GTK_BUTTON(b),GTK_RELIEF_NONE); - gtk_widget_set_size_request(b,25,20); - g_signal_connect_swapped(G_OBJECT(b),"clicked",G_CALLBACK(linphone_gtk_quit_chatroom),cr); - l=gtk_label_new(get_display_name(uri)); - gtk_box_pack_start (GTK_BOX(w),i,FALSE,FALSE,0); - gtk_box_pack_start (GTK_BOX(w),l,FALSE,FALSE,0); - gtk_box_pack_end(GTK_BOX(w),b,TRUE,TRUE,0); - gtk_widget_show_all(w); - return w; +GtkWidget *create_tab_chat_header(LinphoneChatRoom *cr, const LinphoneAddress *uri){ + GtkWidget *tab_header = linphone_gtk_make_tab_header(get_display_name(uri), "linphone-start-chat", TRUE, G_CALLBACK(linphone_gtk_quit_chatroom), cr); + gtk_widget_show_all(tab_header); + return tab_header; } -void udpate_tab_chat_header(GtkWidget *chat_view,const LinphoneAddress *uri,LinphoneChatRoom *cr){ - GtkWidget *main_window=linphone_gtk_get_main_window(); - GtkNotebook *notebook=GTK_NOTEBOOK(linphone_gtk_get_widget(main_window,"viewswitch")); - GtkWidget *w=gtk_hbox_new (FALSE,0); - GtkWidget *i=create_pixmap ("chat.png"); - GtkWidget *l; - GtkWidget *image=gtk_image_new_from_stock(GTK_STOCK_CLOSE,GTK_ICON_SIZE_MENU); - GtkWidget *b=gtk_button_new(); - - gtk_button_set_image(GTK_BUTTON(b),image); - gtk_button_set_relief(GTK_BUTTON(b),GTK_RELIEF_NONE); - gtk_widget_set_size_request(b,25,20); - g_signal_connect_swapped(G_OBJECT(b),"clicked",G_CALLBACK(linphone_gtk_quit_chatroom),cr); - l=gtk_label_new (get_display_name(uri)); - gtk_box_pack_start (GTK_BOX(w),i,FALSE,FALSE,0); - gtk_box_pack_start (GTK_BOX(w),l,FALSE,FALSE,0); - gtk_box_pack_end(GTK_BOX(w),b,TRUE,TRUE,0); - gtk_notebook_set_tab_label(notebook,chat_view,w); - gtk_widget_show_all(w); +void update_chat_header(GtkNotebook *notebook, GtkWidget *chat_view, LinphoneChatRoom *cr, const LinphoneAddress *uri) { + GtkWidget *header = linphone_gtk_make_tab_header(get_display_name(uri), "linphone-start-chat", TRUE, G_CALLBACK(linphone_gtk_quit_chatroom), cr); + gtk_widget_show_all(header); + gtk_notebook_set_tab_label(notebook, chat_view, header); } static gboolean scroll_to_end(GtkTextView *w){ @@ -143,56 +134,69 @@ static gboolean scroll_to_end(GtkTextView *w){ return FALSE; } +static void write_body(GtkTextBuffer *buffer, GtkTextIter *iter, const gchar *text, gint len, gboolean is_me, gboolean is_link) { + const char *me_tag_name = is_me ? "me" : NULL; + const char *link_tag_name = is_link ? "link" : NULL; + if(me_tag_name) { + gtk_text_buffer_insert_with_tags_by_name(buffer, iter, text, len, "body", me_tag_name, link_tag_name, NULL); + } else { + gtk_text_buffer_insert_with_tags_by_name(buffer, iter, text, len, "body", link_tag_name, NULL); + } +} + void linphone_gtk_push_text(GtkWidget *w, const LinphoneAddress *from, gboolean me,LinphoneChatRoom *cr,LinphoneChatMessage *msg, gboolean hist){ GtkTextView *text=GTK_TEXT_VIEW(linphone_gtk_get_widget(w,"textview")); GtkTextBuffer *buffer=gtk_text_view_get_buffer(text); - GtkTextIter iter,begin; - int off; + GtkTextIter iter; char *from_str=linphone_address_as_string_uri_only(from); gchar *from_message=(gchar *)g_object_get_data(G_OBJECT(w),"from_message"); GHashTable *table=(GHashTable*)g_object_get_data(G_OBJECT(w),"table"); + const GRegex *uri_regex = get_uri_regex(); + GMatchInfo *match_info = NULL; + const char *message = linphone_chat_message_get_text(msg); time_t t; char buf[80]; time_t tnow; struct tm *tm; int tnow_day; int tnow_year; + int pos = 0, start, end; - gtk_text_buffer_get_start_iter(buffer,&begin); - gtk_text_buffer_get_end_iter(buffer,&iter); - off=gtk_text_iter_get_offset(&iter); - if(g_strcmp0(from_message,from_str)!=0){ - gtk_text_buffer_get_iter_at_offset(buffer,&iter,off); - gtk_text_buffer_get_end_iter(buffer,&iter); + gtk_text_buffer_get_end_iter(buffer, &iter); + if (g_strcmp0(from_message,from_str)!=0){ gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, get_display_name(from), -1, - "bold", me ? "bg" : NULL, me ? "font_black" : NULL, NULL); - gtk_text_buffer_get_end_iter(buffer,&iter); + "from", me ? "me" : NULL, NULL); gtk_text_buffer_insert_with_tags_by_name(buffer,&iter, " : ", -1, - "bold", me ? "bg" : NULL, me ? "font_black" : NULL, NULL); - gtk_text_buffer_get_end_iter(buffer,&iter); + "from", me ? "me" : NULL, NULL); gtk_text_buffer_insert(buffer,&iter,"\n",-1); g_free(from_message); g_object_set_data(G_OBJECT(w),"from_message",g_strdup(from_str)); } - gtk_text_buffer_get_end_iter(buffer,&iter); - gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, linphone_chat_message_get_text(msg), -1, - "margin", me ? "bg" : NULL, me ? "font_black" : NULL, NULL); - gtk_text_buffer_get_end_iter(buffer,&iter); - gtk_text_buffer_insert(buffer,&iter,"\n",-1); - gtk_text_buffer_get_end_iter(buffer,&iter); - t=linphone_chat_message_get_time(msg); + ms_free(from_str); + + // Inserts message body and tags URIs as hypertext links + if(message) { + g_regex_match(uri_regex, message, 0, &match_info); + while(g_match_info_matches(match_info)) { + g_match_info_fetch_pos(match_info, 0, &start, &end); + if(pos < start) write_body(buffer, &iter, &message[pos], start-pos, me, FALSE); + write_body(buffer, &iter, &message[start], end-start, me, TRUE); + pos = end; + g_match_info_next(match_info, NULL); + } + if(pos < strlen(message)) write_body(buffer, &iter, &message[pos], -1, me, FALSE); + gtk_text_buffer_insert(buffer,&iter,"\n",-1); + g_match_info_free(match_info); + } + + g_hash_table_insert(table,GUINT_TO_POINTER(linphone_chat_message_get_storage_id(msg)),GINT_TO_POINTER(gtk_text_iter_get_line(&iter))); switch (linphone_chat_message_get_state (msg)){ case LinphoneChatMessageStateInProgress: - { - g_hash_table_insert(table,(gpointer)msg,GINT_TO_POINTER(gtk_text_iter_get_line(&iter))); - gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,"Sending ..",-1, - "right","small","italic","font_grey","bg",NULL); - g_object_set_data(G_OBJECT(w),"table",table); + gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,_("Sending..."),-1,"status", me ? "me" : NULL, NULL); break; - } case LinphoneChatMessageStateDelivered: - { + t=linphone_chat_message_get_time(msg); tnow=time(NULL); tm=localtime(&tnow); tnow_day=tm->tm_yday; @@ -203,29 +207,16 @@ void linphone_gtk_push_text(GtkWidget *w, const LinphoneAddress *from, } else { strftime(buf,80,"%H:%M",tm); } - gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,buf,-1, - "right","small","italic","font_grey",me ? "bg":NULL,NULL); + gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,buf,-1,"status", me ? "me" : NULL, NULL); + break; + case LinphoneChatMessageStateNotDelivered: + gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,_("Message not sent"),-1,"status", me ? "me" : NULL, NULL); + break; + default: break; - } - case LinphoneChatMessageStateNotDelivered: - gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,"Message not sent",-1, - "right","small","italic","font_grey",me ? "bg":NULL,NULL); - break; - default : gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,"Sending ..",-1, - "right","small","italic","font_grey",me ? "bg":NULL,NULL); } - gtk_text_buffer_get_end_iter(buffer,&iter); gtk_text_buffer_insert(buffer,&iter,"\n",-1); g_idle_add((GSourceFunc)scroll_to_end,text); - ms_free(from_str); -} - -const LinphoneAddress* linphone_gtk_get_used_identity(){ - LinphoneCore *lc=linphone_gtk_get_core(); - LinphoneProxyConfig *cfg; - linphone_core_get_default_proxy(lc,&cfg); - if (cfg) return linphone_address_new(linphone_proxy_config_get_identity(cfg)); - else return linphone_core_get_primary_contact_parsed(lc); } void update_chat_state_message(LinphoneChatMessageState state,LinphoneChatMessage *msg){ @@ -234,52 +225,47 @@ void update_chat_state_message(LinphoneChatMessageState state,LinphoneChatMessag GtkWidget *page=(GtkWidget*)g_object_get_data(G_OBJECT(friendlist),"chatview"); GHashTable *table=(GHashTable*)g_object_get_data(G_OBJECT(page),"table"); - if(page!=NULL){ + if (page!=NULL) { + char buf[80]; + time_t t; + struct tm *tm; GtkTextView *text=GTK_TEXT_VIEW(linphone_gtk_get_widget(page,"textview")); GtkTextBuffer *b=gtk_text_view_get_buffer(text); GtkTextIter iter; GtkTextIter end; GtkTextIter start; - gchar *result; gint line; - line=GPOINTER_TO_INT(g_hash_table_lookup(table,msg)); - - gtk_text_buffer_get_iter_at_line(b,&iter,line); - if(gtk_text_iter_get_chars_in_line(&iter) >0) { - gtk_text_buffer_get_iter_at_line_offset(b,&start,line, - gtk_text_iter_get_chars_in_line(&iter)-1); - }else{ - gtk_text_buffer_get_iter_at_line_offset(b,&start,line,0); - } - gtk_text_buffer_get_iter_at_line_offset(b,&end,line,0); - gtk_text_buffer_delete(b,&start,&end); - gtk_text_buffer_get_iter_at_line(b,&iter,line); - - switch (state) { - case LinphoneChatMessageStateInProgress: - result="Sending .."; - break; - case LinphoneChatMessageStateDelivered: - { - time_t t=time(NULL); - struct tm *tm=localtime(&t); - char buf[80]; - strftime(buf,80,"%H:%M",tm); - result=buf; - g_hash_table_remove(table,msg); - break; + gpointer hash_table_ptr = g_hash_table_lookup(table,GUINT_TO_POINTER(linphone_chat_message_get_storage_id(msg))); + if (hash_table_ptr != NULL) { + line = GPOINTER_TO_INT(hash_table_ptr); + gtk_text_buffer_get_iter_at_line(b,&iter,line); + if(gtk_text_iter_get_chars_in_line(&iter) >0) { + gtk_text_buffer_get_iter_at_line_offset(b,&start,line, + gtk_text_iter_get_chars_in_line(&iter)-1); + }else{ + gtk_text_buffer_get_iter_at_line_offset(b,&start,line,0); } - case LinphoneChatMessageStateNotDelivered: - { - result="Message not sent"; - g_hash_table_remove(table,msg); - break; + gtk_text_buffer_get_iter_at_line_offset(b,&end,line,0); + gtk_text_buffer_delete(b,&start,&end); + gtk_text_buffer_get_iter_at_line(b,&iter,line); + + switch (state) { + case LinphoneChatMessageStateInProgress: + gtk_text_buffer_insert_with_tags_by_name(b,&iter,_("Sending..."),-1,"status", "me", NULL); + break; + case LinphoneChatMessageStateDelivered: + t=time(NULL); + tm=localtime(&t); + strftime(buf,80,"%H:%M",tm); + gtk_text_buffer_insert_with_tags_by_name(b,&iter,(gchar*)buf,-1,"status", "me", NULL); + break; + case LinphoneChatMessageStateNotDelivered: + gtk_text_buffer_insert_with_tags_by_name(b,&iter,_("Message not sent"),-1,"status", "me", NULL); + break; + default: + break; } - default : result="Sending .."; } - gtk_text_buffer_insert_with_tags_by_name(b,&iter,result,-1, - "right","small","italic","font_grey","bg",NULL); - g_object_set_data(G_OBJECT(page),"table",table); } } @@ -295,11 +281,11 @@ void linphone_gtk_compose_text(void) { if (cr) { linphone_chat_room_compose(cr); linphone_chat_room_mark_as_read(cr); - linphone_gtk_friend_list_update_chat_picture(); + linphone_gtk_friend_list_update_button_display(GTK_TREE_VIEW(friendlist)); } } -void linphone_gtk_send_text(){ +void linphone_gtk_send_text(void){ GtkWidget *main_window=linphone_gtk_get_main_window(); GtkWidget *friendlist=linphone_gtk_get_widget(main_window,"contact_list"); GtkWidget *w=(GtkWidget*)g_object_get_data(G_OBJECT(friendlist),"chatview"); @@ -334,7 +320,7 @@ void linphone_gtk_free_list(MSList *messages){ } void display_history_message(GtkWidget *chat_view,MSList *messages,const LinphoneAddress *with){ - if(messages != NULL){ + if (messages != NULL){ MSList *it; char *from_str; char *with_str; @@ -347,14 +333,15 @@ void display_history_message(GtkWidget *chat_view,MSList *messages,const Linphon linphone_chat_message_get_from(msg), strcmp(from_str,with_str)==0? FALSE : TRUE, linphone_chat_message_get_chat_room(msg),msg,TRUE); + ms_free(from_str); + ms_free(with_str); } tmp=g_object_get_data(G_OBJECT(chat_view),"from_message"); if (tmp){ g_object_set_data(G_OBJECT(chat_view),"from_message",NULL); g_free(tmp); } - ms_free(from_str); - ms_free(with_str); + linphone_gtk_free_list(messages); } } @@ -375,8 +362,100 @@ static void linphone_gtk_chat_add_contact(const LinphoneAddress *addr){ linphone_gtk_show_friends(); } +static GdkColor *_linphone_gtk_chatroom_get_link_color(GtkWidget *chatview) { + GValue color_value = {0}; + g_value_init(&color_value, GDK_TYPE_COLOR); + gtk_style_get_style_property( + gtk_widget_get_style(chatview), + G_OBJECT_TYPE(chatview), + "link-color", &color_value); + + return (GdkColor *)g_value_get_boxed(&color_value); +} + +static gboolean link_event_handler(GtkTextTag *tag, GObject *text_view,GdkEvent *event, GtkTextIter *iter, GtkWidget *chat_view) { + if(event->type == GDK_BUTTON_PRESS) { + GtkTextIter uri_begin = *iter; + GtkTextIter uri_end = *iter; + gchar *uri = NULL; + LinphoneChatRoom *chat_room = (LinphoneChatRoom *)g_object_get_data(G_OBJECT(chat_view), "cr"); + GtkWidget *main_window = linphone_gtk_get_main_window(); + GtkWidget *friendlist = linphone_gtk_get_widget(main_window, "contact_list"); + + gtk_text_iter_backward_to_tag_toggle(&uri_begin, tag); + gtk_text_iter_forward_to_tag_toggle(&uri_end, tag); + uri = gtk_text_iter_get_slice(&uri_begin, &uri_end); + if(((GdkEventButton *)event)->button == 1) { + linphone_gtk_open_browser(uri); + } else if(((GdkEventButton *)event)->button == 3) { + GtkMenu *menu = GTK_MENU(g_object_get_data(text_view, "link_ctx_menu")); + g_object_set_data_full(G_OBJECT(menu), "uri", g_strdup(uri), g_free); + gtk_menu_popup(menu, NULL, NULL, NULL, NULL, 3, gdk_event_get_time(event)); + } + g_free(uri); + + linphone_chat_room_mark_as_read(chat_room); + linphone_gtk_friend_list_update_button_display(GTK_TREE_VIEW(friendlist)); + + return TRUE; + } + return FALSE; +} + +static void chatroom_enable_hand_cursor(GdkWindow *window, gboolean hand_cursor_enabled) { +#if GTK_CHECK_VERSION(2,22,0) + GdkCursor *cursor = gdk_window_get_cursor(window); + GdkCursor *new_cursor = NULL; + if(!hand_cursor_enabled && gdk_cursor_get_cursor_type(cursor) != GDK_XTERM) { + new_cursor = gdk_cursor_new(GDK_XTERM); + } else if(hand_cursor_enabled && gdk_cursor_get_cursor_type(cursor) != GDK_HAND1) { + new_cursor = gdk_cursor_new(GDK_HAND1); + } + if(new_cursor) { + gdk_window_set_cursor(window, new_cursor); + gdk_cursor_unref(new_cursor); + } +#endif +} + +static gboolean chatroom_event(GtkWidget *widget, GdkEvent *event, gpointer user_data) { + gint wx, wy, bx, by; + GtkTextView *chatroom = GTK_TEXT_VIEW(widget); + GtkTextBuffer *buffer = gtk_text_view_get_buffer(chatroom); + GtkTextTag *link_tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(buffer), "link"); + GdkWindow *window = gtk_text_view_get_window(chatroom, GTK_TEXT_WINDOW_TEXT); + GtkTextIter iter; + if(event->type == GDK_MOTION_NOTIFY) { + GdkEventMotion *motion_ev = (GdkEventMotion *)event; + wx = motion_ev->x; + wy = motion_ev->y; + gtk_text_view_window_to_buffer_coords(chatroom, GTK_TEXT_WINDOW_TEXT, wx, wy, &bx, &by); + gtk_text_view_get_iter_at_location(chatroom, &iter, bx, by); + if(gtk_text_iter_has_tag(&iter, link_tag)) { + chatroom_enable_hand_cursor(window, TRUE); + } else { + chatroom_enable_hand_cursor(window, FALSE); + } + } + return FALSE; +} + +static gboolean copy_uri_into_clipboard_handler(GtkMenuItem *menuitem, gpointer user_data) { + GtkWidget *menu = gtk_widget_get_parent(GTK_WIDGET(menuitem)); + const gchar *uri = (const gchar *)g_object_get_data(G_OBJECT(menu), "uri"); + GtkClipboard *clipboard = NULL; + GdkAtom clipboard_atom = gdk_atom_intern("CLIPBOARD", TRUE); + if(clipboard_atom == GDK_NONE) { + g_warning("Could not find CLIPBOARD atom"); + return FALSE; + } + clipboard = gtk_clipboard_get(clipboard_atom); + if(uri) gtk_clipboard_set_text(clipboard, uri, -1); + return FALSE; +} + GtkWidget* linphone_gtk_init_chatroom(LinphoneChatRoom *cr, const LinphoneAddress *with){ - GtkWidget *chat_view=linphone_gtk_create_widget("main","chatroom_frame"); + GtkWidget *chat_view=linphone_gtk_create_widget("chatroom_frame"); GtkWidget *main_window=linphone_gtk_get_main_window(); GtkNotebook *notebook=(GtkNotebook *)linphone_gtk_get_widget(main_window,"viewswitch"); GtkWidget *text=linphone_gtk_get_widget(chat_view,"textview"); @@ -388,12 +467,10 @@ GtkWidget* linphone_gtk_init_chatroom(LinphoneChatRoom *cr, const LinphoneAddres GtkWidget *entry = linphone_gtk_get_widget(chat_view,"text_entry"); MSList *messages; GHashTable *table; - char *with_str; + GtkTextTag *tmp_tag; + GtkWidget *link_ctx_menu = gtk_menu_new(); + GtkWidget *link_ctx_menu_copy_item = gtk_menu_item_new_with_label(_("Copy")); - with_str=linphone_address_as_string_uri_only(with); - gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text),GTK_WRAP_WORD_CHAR); - gtk_text_view_set_editable(GTK_TEXT_VIEW(text),FALSE); - gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(text),FALSE); gtk_notebook_append_page(notebook,chat_view,create_tab_chat_header(cr,with)); idx = gtk_notebook_page_num(notebook, chat_view); gtk_notebook_set_current_page(notebook, idx); @@ -401,25 +478,50 @@ GtkWidget* linphone_gtk_init_chatroom(LinphoneChatRoom *cr, const LinphoneAddres table=g_hash_table_new_full(g_direct_hash,g_direct_equal,NULL,NULL); g_object_set_data(G_OBJECT(chat_view),"cr",cr); g_object_set_data(G_OBJECT(chat_view),"from_message",NULL); - g_object_set_data(G_OBJECT(chat_view),"table",table); - gtk_text_buffer_create_tag(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), - "right","justification", GTK_JUSTIFY_RIGHT,NULL); - gtk_text_buffer_create_tag(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), - "left","justification", GTK_JUSTIFY_LEFT,NULL); - gtk_text_buffer_create_tag(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), - "bold","weight", PANGO_WEIGHT_BOLD,NULL); - gtk_text_buffer_create_tag(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), - "italic","style", PANGO_STYLE_ITALIC,NULL); - gtk_text_buffer_create_tag(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), - "small","size",9*PANGO_SCALE,NULL); - gtk_text_buffer_create_tag(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), - "font_grey","foreground-gdk",&color_grey,NULL); - gtk_text_buffer_create_tag(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), - "font_black","foreground-gdk",&color_black,NULL); - gtk_text_buffer_create_tag(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), - "margin","indent",10,NULL); - gtk_text_buffer_create_tag(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), - "bg","paragraph-background-gdk",&color_light_grey,NULL); + g_object_set_data_full(G_OBJECT(chat_view),"table",table,(GDestroyNotify)g_hash_table_destroy); + + gtk_text_buffer_create_tag( + gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), + "me", + "foreground_gdk", &color_black, + "paragraph-background-gdk", &color_light_grey, + NULL); + + gtk_text_buffer_create_tag( + gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), + "from", + "weight", PANGO_WEIGHT_BOLD, + NULL); + + gtk_text_buffer_create_tag( + gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), + "body", + "indent", 10, + NULL); + + gtk_text_buffer_create_tag( + gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), + "status", + "size-points", 9.0, + "foreground_gdk", &color_grey, + "style", PANGO_STYLE_ITALIC, + "justification", GTK_JUSTIFY_RIGHT, + NULL); + + tmp_tag = gtk_text_buffer_create_tag( + gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), + "link", + "underline", PANGO_UNDERLINE_SINGLE, + "foreground_gdk", _linphone_gtk_chatroom_get_link_color(chat_view), + NULL); + g_signal_connect(G_OBJECT(tmp_tag), "event", G_CALLBACK(link_event_handler), chat_view); + g_signal_connect(G_OBJECT(text), "event", G_CALLBACK(chatroom_event), NULL); + gtk_menu_shell_append(GTK_MENU_SHELL(link_ctx_menu), link_ctx_menu_copy_item); + g_signal_connect(G_OBJECT(link_ctx_menu_copy_item), "activate", G_CALLBACK(copy_uri_into_clipboard_handler), NULL); + gtk_widget_show_all(link_ctx_menu); + g_object_set_data_full(G_OBJECT(text), "link_ctx_menu", link_ctx_menu, g_object_unref); + g_object_ref_sink(G_OBJECT(link_ctx_menu)); + messages = linphone_chat_room_get_history(cr,NB_MSG_HIST); display_history_message(chat_view,messages,with); button = linphone_gtk_get_widget(chat_view,"send"); @@ -428,19 +530,17 @@ GtkWidget* linphone_gtk_init_chatroom(LinphoneChatRoom *cr, const LinphoneAddres g_signal_connect_swapped(G_OBJECT(entry),"activate",(GCallback)linphone_gtk_send_text,NULL); g_signal_connect_swapped(G_OBJECT(entry),"changed",(GCallback)linphone_gtk_compose_text,NULL); g_signal_connect(G_OBJECT(notebook),"switch_page",(GCallback)linphone_gtk_notebook_tab_select,NULL); - ms_free(with_str); return chat_view; } LinphoneChatRoom * linphone_gtk_create_chatroom(const LinphoneAddress *with){ - char *tmp=linphone_address_as_string(with); - LinphoneChatRoom *cr=linphone_core_get_or_create_chat_room(linphone_gtk_get_core(),tmp); - ms_free(tmp); + LinphoneChatRoom *cr=linphone_core_get_chat_room(linphone_gtk_get_core(), with); return cr; } void linphone_gtk_load_chatroom(LinphoneChatRoom *cr,const LinphoneAddress *uri,GtkWidget *chat_view){ GtkWidget *main_window=linphone_gtk_get_main_window (); + GtkWidget *notebook = linphone_gtk_get_widget(main_window, "viewswitch"); LinphoneChatRoom *cr2=(LinphoneChatRoom *)g_object_get_data(G_OBJECT(chat_view),"cr"); const LinphoneAddress *from=linphone_chat_room_get_peer_address(cr2); char *from_str=linphone_address_as_string_uri_only(from); @@ -457,7 +557,7 @@ void linphone_gtk_load_chatroom(LinphoneChatRoom *cr,const LinphoneAddress *uri, text_buffer=gtk_text_view_get_buffer(text_view); gtk_text_buffer_get_bounds(text_buffer, &start, &end); gtk_text_buffer_delete (text_buffer, &start, &end); - udpate_tab_chat_header(chat_view,uri,cr); + update_chat_header(GTK_NOTEBOOK(notebook), chat_view, cr, uri); g_object_set_data(G_OBJECT(chat_view),"cr",cr); g_object_set_data(G_OBJECT(linphone_gtk_get_widget(main_window,"contact_list")),"chatview",(gpointer)chat_view); messages=linphone_chat_room_get_history(cr,NB_MSG_HIST); @@ -520,7 +620,7 @@ void linphone_gtk_text_received ( LinphoneCore *lc, LinphoneChatRoom *room, #else if ( !gtk_window_is_active ( GTK_WINDOW ( main_window ) ) ) { if ( !GPOINTER_TO_INT ( g_object_get_data ( G_OBJECT ( w ),"is_notified" ) ) ) { - linphone_gtk_notify ( NULL,linphone_chat_message_get_text ( msg ) ); + linphone_gtk_notify ( NULL, msg, NULL ); g_object_set_data ( G_OBJECT ( w ),"is_notified",GINT_TO_POINTER ( TRUE ) ); } else { g_object_set_data ( G_OBJECT ( w ),"is_notified",GINT_TO_POINTER ( FALSE ) ); @@ -537,5 +637,7 @@ void linphone_gtk_text_received ( LinphoneCore *lc, LinphoneChatRoom *room, } void linphone_gtk_is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room) { - linphone_gtk_friend_list_update_chat_picture(); + GtkWidget *main_window = linphone_gtk_get_main_window(); + GtkWidget *friendlist = linphone_gtk_get_widget(main_window, "contact_list"); + linphone_gtk_friend_list_update_button_display(GTK_TREE_VIEW(friendlist)); } diff --git a/gtk/chatroom_frame.ui b/gtk/chatroom_frame.ui new file mode 100644 index 000000000..9f5b66ef7 --- /dev/null +++ b/gtk/chatroom_frame.ui @@ -0,0 +1,113 @@ + + + + + + True + False + 0 + none + + + True + False + + + True + True + never + + + True + True + 4 + False + word-char + False + + + + + True + True + 0 + + + + + True + False + + + True + True + + True + False + False + True + True + + + True + True + 0 + + + + + True + True + True + + + True + False + + + True + False + linphone-chat-send + + + True + True + 0 + + + + + True + False + Send + + + True + True + 7 + 1 + + + + + + + False + False + 1 + + + + + False + False + 1 + + + + + + + + + diff --git a/gtk/conf_frame.ui b/gtk/conf_frame.ui new file mode 100644 index 000000000..c9503e7f6 --- /dev/null +++ b/gtk/conf_frame.ui @@ -0,0 +1,85 @@ + + + + + + True + False + 0 + none + + + True + False + + + True + False + + + End conference + True + True + True + + + False + False + end + 0 + + + + + True + True + end + 0 + + + + + True + False + + + Record + True + True + True + + + + False + False + 0 + + + + + True + False + True + char + + + True + True + 1 + + + + + False + False + end + 1 + + + + + + + + + diff --git a/gtk/conference.c b/gtk/conference.c index 1bfee3afc..175cfc482 100644 --- a/gtk/conference.c +++ b/gtk/conference.c @@ -34,7 +34,7 @@ static GtkWidget *create_conference_label(void){ GtkWidget *box=gtk_hbox_new(FALSE,0); - gtk_box_pack_start(GTK_BOX(box),gtk_image_new_from_stock(GTK_STOCK_ADD,GTK_ICON_SIZE_MENU),FALSE,FALSE,0); + gtk_box_pack_start(GTK_BOX(box),gtk_image_new_from_icon_name("linphone-conference-start",GTK_ICON_SIZE_MENU),FALSE,FALSE,0); gtk_box_pack_end(GTK_BOX(box),gtk_label_new(_("Conference")),TRUE,FALSE,0); gtk_widget_show_all(box); return box; @@ -81,20 +81,22 @@ static GtkWidget *find_conferencee_from_call(LinphoneCall *call){ static GtkWidget * create_conference_panel(void){ GtkWidget *mw=linphone_gtk_get_main_window(); - GtkWidget *conf_frame=linphone_gtk_create_widget("main","conf_frame"); + GtkWidget *conf_frame=linphone_gtk_create_widget("conf_frame"); GtkWidget *conf_box=linphone_gtk_get_widget(conf_frame,"conf_box"); GtkWidget *button_conf=linphone_gtk_get_widget(conf_frame,"terminate_conf"); - GtkWidget *image=create_pixmap("stopcall-small.png"); + GtkWidget *image=gtk_image_new_from_icon_name("linphone-stop-call", GTK_ICON_SIZE_BUTTON); GtkWidget *box; GtkWidget *viewswitch=linphone_gtk_get_widget(mw,"viewswitch"); GtkWidget *participant; + GtkWidget *record = linphone_gtk_get_widget(conf_frame, "conf_record_button"); + gtk_button_set_image(GTK_BUTTON(record), gtk_image_new_from_icon_name("linphone-record", GTK_ICON_SIZE_BUTTON)); gtk_button_set_image(GTK_BUTTON(button_conf),image); g_signal_connect_swapped(G_OBJECT(button_conf),"clicked",(GCallback)linphone_gtk_terminate_call,NULL); g_object_set_data(G_OBJECT(mw),"conf_frame",(gpointer)conf_frame); box=gtk_vbox_new(FALSE,0); - participant=linphone_gtk_create_widget("main","callee_frame"); + participant=linphone_gtk_create_widget("callee_frame"); gtk_widget_show(participant); gtk_box_set_homogeneous(GTK_BOX(box),TRUE); init_local_participant(participant); @@ -126,7 +128,7 @@ void linphone_gtk_set_in_conference(LinphoneCall *call){ const LinphoneAddress *addr=linphone_call_get_remote_address(call); gchar *markup; - participant=linphone_gtk_create_widget("main","callee_frame"); + participant=linphone_gtk_create_widget("callee_frame"); gtk_widget_show(participant); if (linphone_address_get_display_name(addr)!=NULL){ markup=g_strdup_printf("%s",linphone_address_get_display_name(addr)); diff --git a/gtk/config-fetching.c b/gtk/config-fetching.c index e275662e1..b1794eea9 100644 --- a/gtk/config-fetching.c +++ b/gtk/config-fetching.c @@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. void linphone_gtk_set_configuration_uri(void){ - GtkWidget *w=linphone_gtk_create_window("config-uri"); + GtkWidget *w=linphone_gtk_create_window("config-uri", linphone_gtk_get_main_window()); GtkWidget *entry=linphone_gtk_get_widget(w,"uri_entry"); const char *uri=linphone_core_get_provisioning_uri(linphone_gtk_get_core()); if (uri) gtk_entry_set_text(GTK_ENTRY(entry),uri); @@ -52,7 +52,7 @@ void linphone_gtk_config_uri_cancel(GtkWidget *button){ GtkWidget * linphone_gtk_show_config_fetching(void){ LinphoneCore *lc=linphone_gtk_get_core(); - GtkWidget *w=linphone_gtk_create_window("provisioning-fetch"); + GtkWidget *w=linphone_gtk_create_window("provisioning-fetch", linphone_gtk_get_main_window()); g_message("Fetching started"); gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(w),_("fetching from %s"),linphone_core_get_provisioning_uri(lc)); #if GTK_CHECK_VERSION(2,20,0) diff --git a/gtk/friendlist.c b/gtk/friendlist.c index 3aafb3187..41bc18ee1 100644 --- a/gtk/friendlist.c +++ b/gtk/friendlist.c @@ -17,7 +17,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include #include "linphone.h" static GtkWidget *linphone_gtk_create_contact_menu(GtkWidget *contact_list); @@ -25,13 +24,12 @@ static GtkWidget *linphone_gtk_create_contact_menu(GtkWidget *contact_list); enum{ FRIEND_PRESENCE_IMG, FRIEND_NAME, - FRIEND_PRESENCE_STATUS, FRIEND_ID, FRIEND_CHATROOM, FRIEND_SIP_ADDRESS, - FRIEND_ICON, - FRIEND_CALL, FRIEND_CHAT, + FRIEND_CALL_BUTTON_VISIBLE, + FRIEND_CHAT_BUTTON_VISIBLE, FRIEND_LIST_NCOL }; @@ -41,88 +39,38 @@ typedef struct _status_picture_tab_t{ } status_picture_tab_t; status_picture_tab_t status_picture_tab[]={ - { LinphoneStatusOnline, "status-green.png" }, - { LinphoneStatusBusy, "status-orange.png" }, - { LinphoneStatusBeRightBack, "status-orange.png" }, - { LinphoneStatusAway, "status-orange.png" }, - { LinphoneStatusOnThePhone, "status-orange.png" }, - { LinphoneStatusOutToLunch, "status-orange.png" }, - { LinphoneStatusDoNotDisturb, "status-red.png" }, - { LinphoneStatusMoved, "status-orange.png" }, - { LinphoneStatusAltService, "status-orange.png" }, - { LinphoneStatusOffline, "status-offline.png" }, - { LinphoneStatusPending, "status-offline.png" }, - { LinphoneStatusEnd, NULL }, + { LinphoneStatusOnline , "linphone-status-online" }, + { LinphoneStatusBusy , "linphone-status-away" }, + { LinphoneStatusBeRightBack , "linphone-status-away" }, + { LinphoneStatusAway , "linphone-status-away" }, + { LinphoneStatusOnThePhone , "linphone-status-away" }, + { LinphoneStatusOutToLunch , "linphone-status-away" }, + { LinphoneStatusDoNotDisturb , "linphone-status-donotdisturb" }, + { LinphoneStatusMoved , "linphone-status-away" }, + { LinphoneStatusAltService , "linphone-status-away" }, + { LinphoneStatusOffline , "linphone-status-offline" }, + { LinphoneStatusPending , "linphone-status-offline" }, + { LinphoneStatusEnd , NULL } }; -static GdkPixbuf *create_status_picture(LinphoneOnlineStatus ss){ +static const char *status_to_icon_name(LinphoneOnlineStatus ss) { status_picture_tab_t *t=status_picture_tab; while(t->img!=NULL){ - if (ss==t->status){ - GdkPixbuf *pixbuf; - pixbuf = create_pixbuf(t->img); - return pixbuf; + if (ss==t->status) { + return t->img; } ++t; } - g_error("No pixmap defined for status %i",ss); + g_error("No icon name defined for status %i",ss); return NULL; } -static GdkPixbuf *create_call_picture(){ - GdkPixbuf *pixbuf; - pixbuf = create_pixbuf("call.png"); - return pixbuf; +static GtkWidget *create_status_picture(LinphoneOnlineStatus ss, GtkIconSize icon_size){ + const char *icon_name = status_to_icon_name(ss); + if(icon_name) return gtk_image_new_from_icon_name(icon_name, icon_size); + else return NULL; } -static GdkPixbuf *create_unread_msg(){ - GdkPixbuf *pixbuf; - pixbuf = create_pixbuf("active_chat.png"); - return pixbuf; -} - -static GdkPixbuf *create_chat_picture(){ - GdkPixbuf *pixbuf; - pixbuf = create_pixbuf("chat.png"); - return pixbuf; -} - -static GdkPixbuf *create_composing_unread_msg(){ - GdkPixbuf *pixbuf; - pixbuf = create_pixbuf("composing_active_chat.png"); - return pixbuf; -} - -static GdkPixbuf *create_composing_chat_picture(){ - GdkPixbuf *pixbuf; - pixbuf = create_pixbuf("composing_chat.png"); - return pixbuf; -} - -/* -void linphone_gtk_set_friend_status(GtkWidget *friendlist , LinphoneFriend * fid, const gchar *url, const gchar *status, const gchar *img){ - GtkTreeIter iter; - LinphoneFriend *tmp=0; - - GtkTreeModel *model=gtk_tree_view_get_model(GTK_TREE_VIEW(friendlist)); - if (gtk_tree_model_get_iter_first(model,&iter)) { - do{ - gtk_tree_model_get(model,&iter,FRIEND_ID,&tmp,-1); - //printf("tmp=%i, fid=%i",tmp,fid); - if (fid==tmp) { - GdkPixbuf *pixbuf; - gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_PRESENCE_STATUS,status,-1); - pixbuf = create_pixbuf(img); - if (pixbuf) - { - gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_PRESENCE_IMG, pixbuf,-1); - } - } - }while(gtk_tree_model_iter_next(model,&iter)); - } -} -*/ - gboolean linphone_gtk_friend_list_is_contact(const LinphoneAddress *addr){ LinphoneFriend *lf; char *addr_str=linphone_address_as_string(addr); @@ -149,7 +97,7 @@ static void linphone_gtk_set_selection_to_uri_bar(GtkTreeView *treeview){ } void linphone_gtk_add_contact(void){ - GtkWidget *w=linphone_gtk_create_window("contact"); + GtkWidget *w=linphone_gtk_create_window("contact", linphone_gtk_get_main_window()); int presence_enabled=linphone_gtk_get_ui_config_int("use_subscribe_notify",1); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"show_presence")),presence_enabled); @@ -168,7 +116,7 @@ void linphone_gtk_edit_contact(GtkWidget *button){ if (gtk_tree_selection_get_selected (select, &model, &iter)) { gtk_tree_model_get (model, &iter,FRIEND_ID , &lf, -1); - linphone_gtk_show_contact(lf); + linphone_gtk_show_contact(lf, w); } } @@ -233,32 +181,55 @@ static void linphone_gtk_call_selected(GtkTreeView *treeview){ "start_call")); } -void linphone_gtk_friend_list_update_chat_picture(){ - GtkTreeIter iter; - GtkWidget *w = linphone_gtk_get_main_window(); - GtkWidget *friendlist=linphone_gtk_get_widget(w,"contact_list"); - GtkTreeModel *model=gtk_tree_view_get_model(GTK_TREE_VIEW(friendlist)); +void linphone_gtk_friend_list_update_button_display(GtkTreeView *friendlist){ + GtkTreeIter iter, selected_iter; + GtkTreeModel *model=gtk_tree_view_get_model(friendlist); + GtkTreeSelection *select=gtk_tree_view_get_selection(friendlist); LinphoneChatRoom *cr=NULL; - bool_t is_composing; + gboolean is_composing; int nbmsg=0; + GtkTreePath *selected_path = NULL; + GtkTreePath *hovered_row = (GtkTreePath *)g_object_get_data(G_OBJECT(friendlist), "hovered_row"); + + if (gtk_tree_selection_get_selected(select, &model, &selected_iter)){ + selected_path = gtk_tree_model_get_path(model, &selected_iter); + } + if (gtk_tree_model_get_iter_first(model,&iter)) { do{ + const char *icon_name = NULL; + gboolean show_chat_button = FALSE; + gboolean show_call_button = FALSE; + GtkTreePath *path = gtk_tree_model_get_path(model, &iter); + gtk_tree_model_get (model, &iter,FRIEND_CHATROOM , &cr, -1); nbmsg=linphone_chat_room_get_unread_messages_count(cr); is_composing=linphone_chat_room_is_remote_composing(cr); if(nbmsg != 0){ - if (is_composing == TRUE) - gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_CHAT,create_composing_unread_msg(),-1); - else - gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_CHAT,create_unread_msg(),-1); + if (is_composing) icon_name = "linphone-chat-new-message-and-writing"; + else icon_name = "linphone-chat-new-message"; + show_chat_button = TRUE; } else { - if (is_composing == TRUE) - gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_CHAT,create_composing_chat_picture(),-1); - else - gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_CHAT,create_chat_picture(),-1); + if (is_composing) { + icon_name = "linphone-chat-writing"; + show_chat_button = TRUE; + } else { + icon_name = "linphone-chat-nothing"; + } } + if ((selected_path && gtk_tree_path_compare(path, selected_path) == 0) + || (hovered_row && gtk_tree_path_compare(path, hovered_row) == 0)){ + show_chat_button = TRUE; + show_call_button = TRUE; + } + gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_CHAT,icon_name, + FRIEND_CHAT_BUTTON_VISIBLE, show_chat_button, -1); + gtk_list_store_set(GTK_LIST_STORE(model), &iter, FRIEND_CALL_BUTTON_VISIBLE, show_call_button, -1); + + gtk_tree_path_free(path); }while(gtk_tree_model_iter_next(model,&iter)); } + if (selected_path) gtk_tree_path_free(selected_path); } static gboolean grab_focus(GtkWidget *w){ @@ -269,9 +240,7 @@ static gboolean grab_focus(GtkWidget *w){ void linphone_gtk_friend_list_set_active_address(const LinphoneAddress *addr){ GtkWidget *w=linphone_gtk_get_main_window(); GtkWidget *friendlist=linphone_gtk_get_widget(w,"contact_list"); - LinphoneAddress *old_addr=(LinphoneAddress*)g_object_get_data(G_OBJECT(friendlist),"from"); - g_object_set_data(G_OBJECT(friendlist),"from", addr ? linphone_address_clone(addr) : NULL); - if (old_addr) linphone_address_unref(old_addr); + g_object_set_data_full(G_OBJECT(friendlist),"from", addr ? linphone_address_clone(addr) : NULL, (GDestroyNotify)linphone_address_destroy); } const LinphoneAddress *linphone_gtk_friend_list_get_active_address(void){ @@ -290,20 +259,12 @@ void linphone_gtk_friend_list_set_chat_conversation(const LinphoneAddress *la){ LinphoneFriend *lf=NULL; LinphoneChatRoom *cr=NULL; GtkNotebook *notebook=(GtkNotebook *)linphone_gtk_get_widget(w,"viewswitch"); + GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(friendlist)); lf=linphone_core_find_friend(linphone_gtk_get_core(),la); if(lf==NULL){ cr=linphone_gtk_create_chatroom(la); linphone_gtk_friend_list_set_active_address(la); - if(chat_view==NULL){ - chat_view=linphone_gtk_init_chatroom(cr,la); - g_object_set_data(G_OBJECT(friendlist),"chatview",(gpointer)chat_view); - } else { - linphone_gtk_load_chatroom(cr,la,chat_view); - } - gtk_notebook_set_current_page(notebook,gtk_notebook_page_num(notebook,chat_view)); - linphone_gtk_friend_list_update_chat_picture(); - g_idle_add((GSourceFunc)grab_focus,linphone_gtk_get_widget(chat_view,"text_entry")); } else { store=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(friendlist))); if (gtk_tree_model_get_iter_first(model,&iter)) { @@ -318,20 +279,22 @@ void linphone_gtk_friend_list_set_chat_conversation(const LinphoneAddress *la){ gtk_list_store_set(store,&iter,FRIEND_CHATROOM,cr,-1); } linphone_gtk_friend_list_set_active_address(uri); - if(chat_view==NULL){ - chat_view=linphone_gtk_init_chatroom(cr,uri); - g_object_set_data(G_OBJECT(friendlist),"chatview",(gpointer)chat_view); - } else { - linphone_gtk_load_chatroom(cr,uri,chat_view); - } - gtk_notebook_set_current_page(notebook,gtk_notebook_page_num(notebook,chat_view)); - linphone_gtk_friend_list_update_chat_picture(); - g_idle_add((GSourceFunc)grab_focus,linphone_gtk_get_widget(chat_view,"text_entry")); + gtk_tree_selection_select_iter(selection, &iter); break; } }while(gtk_tree_model_iter_next(model,&iter)); } } + if(cr) { + if(chat_view == NULL){ + chat_view=linphone_gtk_init_chatroom(cr,la); + g_object_set_data(G_OBJECT(friendlist),"chatview",(gpointer)chat_view); + } else { + linphone_gtk_load_chatroom(cr,la,chat_view); + } + gtk_notebook_set_current_page(notebook,gtk_notebook_page_num(notebook,chat_view)); + g_idle_add((GSourceFunc)grab_focus,linphone_gtk_get_widget(chat_view,"text_entry")); + } } void linphone_gtk_notebook_tab_select(GtkNotebook *notebook,GtkWidget *page,guint page_num, gpointer data){ @@ -375,7 +338,7 @@ void linphone_gtk_chat_selected(GtkWidget *item){ cr=linphone_gtk_create_chatroom(uri); gtk_list_store_set(store,&iter,FRIEND_CHATROOM,cr,-1); } - page=(GtkWidget*)g_object_get_data(G_OBJECT(friendlist),"chatview"); + page=GTK_WIDGET(g_object_get_data(G_OBJECT(friendlist),"chatview")); linphone_gtk_friend_list_set_active_address(uri); if(page==NULL){ page=linphone_gtk_init_chatroom(cr,uri); @@ -385,29 +348,25 @@ void linphone_gtk_chat_selected(GtkWidget *item){ } linphone_chat_room_mark_as_read(cr); gtk_notebook_set_current_page(notebook,gtk_notebook_page_num(notebook,page)); - linphone_gtk_friend_list_update_chat_picture(); g_idle_add((GSourceFunc)grab_focus,linphone_gtk_get_widget(page,"text_entry")); } } -void linphone_gtk_contact_activated(GtkTreeView *treeview, - GtkTreePath *path, - GtkTreeViewColumn *column, - gpointer user_data) -{ - //linphone_gtk_call_selected(treeview); -} - -void linphone_gtk_contact_clicked(GtkTreeView *treeview){ - linphone_gtk_set_selection_to_uri_bar(treeview); - if(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(treeview),"numcol"))==1){ - linphone_gtk_call_selected(treeview); +void linphone_gtk_contact_clicked(GtkTreeSelection *selection){ + GtkTreeView *friendlist = gtk_tree_selection_get_tree_view(selection); + GtkWidget *mw = linphone_gtk_get_main_window(); + GtkWidget *edit_button = linphone_gtk_get_widget(mw, "edit_button"); + GtkWidget *remove_button = linphone_gtk_get_widget(mw, "remove_button"); + + linphone_gtk_set_selection_to_uri_bar(friendlist); + linphone_gtk_friend_list_update_button_display(friendlist); + if(gtk_tree_selection_get_selected(selection, NULL, NULL)) { + gtk_widget_set_sensitive(edit_button, TRUE); + gtk_widget_set_sensitive(remove_button, TRUE); } else { - if(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(treeview),"numcol"))==2){ - linphone_gtk_chat_selected(GTK_WIDGET(treeview)); - } + gtk_widget_set_sensitive(edit_button, FALSE); + gtk_widget_set_sensitive(remove_button, FALSE); } - g_object_set_data(G_OBJECT(treeview),"numcol",GINT_TO_POINTER(0)); } @@ -423,20 +382,17 @@ void linphone_gtk_remove_button_clicked(GtkWidget *button){ linphone_gtk_remove_contact(button); } -static GtkWidget * create_presence_menu(){ +static GtkWidget * create_presence_menu(void){ GtkWidget *menu=gtk_menu_new(); GtkWidget *menu_item; - GdkPixbuf *pbuf; status_picture_tab_t *t; for(t=status_picture_tab;t->img!=NULL;++t){ if (t->status==LinphoneStatusPending){ continue; } menu_item=gtk_image_menu_item_new_with_label(linphone_online_status_to_string(t->status)); - pbuf=create_status_picture(t->status); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item), - gtk_image_new_from_pixbuf(pbuf)); - g_object_unref(G_OBJECT(pbuf)); + gtk_image_new_from_icon_name(t->img, GTK_ICON_SIZE_LARGE_TOOLBAR)); gtk_widget_show(menu_item); gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item); g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_set_my_presence,GINT_TO_POINTER(t->status)); @@ -446,10 +402,9 @@ static GtkWidget * create_presence_menu(){ void linphone_gtk_set_my_presence(LinphoneOnlineStatus ss){ GtkWidget *button=linphone_gtk_get_widget(linphone_gtk_get_main_window(),"presence_button"); - GdkPixbuf *pbuf=create_status_picture(ss); - GtkWidget *image=gtk_image_new_from_pixbuf(pbuf); + GtkWidget *image=create_status_picture(ss, GTK_ICON_SIZE_LARGE_TOOLBAR); GtkWidget *menu; - g_object_unref(G_OBJECT(pbuf)); + gtk_widget_set_tooltip_text(button,linphone_online_status_to_string(ss)); gtk_button_set_image(GTK_BUTTON(button),image); /*prepare menu*/ @@ -471,6 +426,7 @@ void linphone_gtk_my_presence_clicked(GtkWidget *button){ } static void icon_press_handler(GtkEntry *entry){ + GtkWidget *w = gtk_widget_get_toplevel(GTK_WIDGET(entry)); const char *text=gtk_entry_get_text(entry); if (text && strlen(text)>0){ LinphoneAddress *addr; @@ -487,57 +443,38 @@ static void icon_press_handler(GtkEntry *entry){ lf=linphone_friend_new(); if (lf!=NULL){ linphone_friend_set_address(lf,addr); - linphone_gtk_show_contact(lf); + linphone_gtk_show_contact(lf, w); } linphone_address_destroy(addr); } } static void update_star(GtkEntry *entry, gboolean is_known){ - GdkPixbuf *active,*starred,*unstarred; - active=gtk_entry_get_icon_pixbuf(entry,GTK_ENTRY_ICON_SECONDARY); - starred=g_object_get_data(G_OBJECT(entry),"starred_icon"); - unstarred=g_object_get_data(G_OBJECT(entry),"unstarred_icon"); - if (is_known && (active==unstarred)){ - gtk_entry_set_icon_from_pixbuf(entry,GTK_ENTRY_ICON_SECONDARY,starred); + if (is_known){ + gtk_entry_set_icon_from_icon_name(entry,GTK_ENTRY_ICON_SECONDARY,NULL); + gtk_entry_set_icon_sensitive(GTK_ENTRY(entry),GTK_ENTRY_ICON_SECONDARY,FALSE); gtk_entry_set_icon_tooltip_text(GTK_ENTRY(entry),GTK_ENTRY_ICON_SECONDARY,NULL); - }else if ((!is_known) && (active==starred)){ + }else{ + gtk_entry_set_icon_from_icon_name(entry,GTK_ENTRY_ICON_SECONDARY,"linphone-contact-add"); + gtk_entry_set_icon_sensitive(GTK_ENTRY(entry),GTK_ENTRY_ICON_SECONDARY,TRUE); gtk_entry_set_icon_tooltip_text(GTK_ENTRY(entry),GTK_ENTRY_ICON_SECONDARY,_("Add to addressbook")); - gtk_entry_set_icon_from_pixbuf(entry,GTK_ENTRY_ICON_SECONDARY,unstarred); } } static void check_contact(GtkEditable *editable, LinphoneCore *lc){ - char *tmp=gtk_editable_get_chars(editable,0,-1); - if (tmp!=NULL){ - if (strlen(tmp)>0){ - LinphoneAddress *addr=linphone_core_interpret_url(lc,tmp); - if (addr){ - char *uri=linphone_address_as_string_uri_only(addr); - LinphoneFriend *lf=linphone_core_get_friend_by_address(lc,uri); - ms_free(uri); - linphone_address_destroy(addr); - if (lf) { - update_star(GTK_ENTRY(editable),TRUE); - g_free(tmp); - return; - } - } + bool_t known = TRUE; + char *tmp = gtk_editable_get_chars(editable, 0, -1); + if (tmp != NULL) { + if (strlen(tmp) > 0) { + known = linphone_gtk_is_friend(lc, tmp); } g_free(tmp); } - update_star(GTK_ENTRY(editable),FALSE); + update_star(GTK_ENTRY(editable), known); } static void linphone_gtk_init_bookmark_icon(void){ - GtkWidget *mw=linphone_gtk_get_main_window(); - GtkWidget *entry=linphone_gtk_get_widget(mw,"uribar"); - GdkPixbuf *pbuf=create_pixbuf("contact_unstarred.png"); - gtk_entry_set_icon_from_pixbuf(GTK_ENTRY(entry),GTK_ENTRY_ICON_SECONDARY,pbuf); - g_object_set_data_full(G_OBJECT(entry),"unstarred_icon",pbuf,g_object_unref); - pbuf=create_pixbuf("contact_starred.png"); - g_object_set_data_full(G_OBJECT(entry),"starred_icon",pbuf,g_object_unref); - gtk_entry_set_icon_activatable(GTK_ENTRY(entry),GTK_ENTRY_ICON_SECONDARY,TRUE); + GtkWidget *entry = linphone_gtk_get_widget(linphone_gtk_get_main_window(), "uribar"); g_signal_connect(G_OBJECT(entry),"icon-release",(GCallback)icon_press_handler,NULL); g_signal_connect(G_OBJECT(GTK_EDITABLE(entry)),"changed",(GCallback)check_contact,linphone_gtk_get_core()); } @@ -579,7 +516,7 @@ static gint friend_sort(GtkTreeModel *model, GtkTreeIter *a,GtkTreeIter *b,gpoin return ret; } -static void on_name_column_clicked(GtkTreeModel *model){ +void linphone_gtk_friend_list_on_name_column_clicked(GtkTreeModel *model){ GtkSortType st; gint column; @@ -645,7 +582,8 @@ static MSList *sort_friend_list(const MSList *friends){ return ret; } -static void on_presence_column_clicked(GtkTreeModel *model){ +#if 0 +void linphone_gtk_friend_list_on_presence_column_clicked(GtkTreeModel *model){ GtkSortType st; gint column; @@ -656,87 +594,19 @@ static void on_presence_column_clicked(GtkTreeModel *model){ }else st=GTK_SORT_ASCENDING; gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model),FRIEND_ID,st); } - -void create_button(){ - GtkWidget *main_window = linphone_gtk_get_main_window (); - GtkWidget *button_add = linphone_gtk_get_widget(main_window,"add_button"); - GtkWidget *image; - - image=gtk_image_new_from_stock(GTK_STOCK_ADD,GTK_ICON_SIZE_MENU); - gtk_container_add (GTK_CONTAINER (button_add), image); -} - -static void linphone_gtk_friend_list_init(GtkWidget *friendlist){ - GtkListStore *store; - GtkCellRenderer *renderer; - GtkTreeViewColumn *column; - GtkTreeSelection *select; - - linphone_gtk_init_bookmark_icon(); - - store = gtk_list_store_new(FRIEND_LIST_NCOL,GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, - G_TYPE_POINTER, G_TYPE_STRING, GDK_TYPE_PIXBUF, GDK_TYPE_PIXBUF, GDK_TYPE_PIXBUF); - - gtk_tree_view_set_model(GTK_TREE_VIEW(friendlist),GTK_TREE_MODEL(store)); - g_object_unref(G_OBJECT(store)); - - /* Tree specification*/ - gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(friendlist),FALSE); - gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(friendlist),friend_search_func,NULL,NULL); - gtk_tree_view_set_search_column(GTK_TREE_VIEW(friendlist),FRIEND_NAME); - gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store),FRIEND_NAME,friend_sort,NULL,NULL); - - /*Name and presence column*/ - renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes (_("Presence status"), - renderer, - "text", FRIEND_PRESENCE_STATUS, - NULL); - g_object_set (G_OBJECT(column), "resizable", TRUE, NULL); - g_signal_connect_swapped(G_OBJECT(column),"clicked",(GCallback)on_presence_column_clicked,GTK_TREE_MODEL(store)); - gtk_tree_view_column_set_clickable(column,TRUE); - gtk_tree_view_column_set_visible(column,linphone_gtk_get_ui_config_int("friendlist_status",1)); - gtk_tree_view_column_set_min_width(column,50); - - renderer = gtk_cell_renderer_pixbuf_new(); - gtk_tree_view_column_pack_start(column,renderer,TRUE); - gtk_tree_view_column_add_attribute (column,renderer, - "pixbuf", - FRIEND_PRESENCE_IMG); - gtk_tree_view_append_column (GTK_TREE_VIEW (friendlist), column); - - renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes (_("Name"), - renderer, - "text", FRIEND_NAME,NULL); - g_object_set (G_OBJECT(column), "resizable", TRUE, NULL); - g_signal_connect_swapped(G_OBJECT(column),"clicked",(GCallback)on_name_column_clicked,GTK_TREE_MODEL(store)); - gtk_tree_view_column_set_clickable(column,TRUE); - gtk_tree_view_column_set_expand(column,TRUE); - gtk_tree_view_column_set_max_width(column,60); - gtk_tree_view_append_column (GTK_TREE_VIEW (friendlist), column); - - /* Call column*/ - renderer = gtk_cell_renderer_pixbuf_new(); - column = gtk_tree_view_column_new_with_attributes (_("Call"),renderer,"pixbuf",FRIEND_CALL,NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (friendlist), column); - - /* Chat column*/ - renderer = gtk_cell_renderer_pixbuf_new(); - column = gtk_tree_view_column_new_with_attributes (_("Chat"),renderer,"pixbuf",FRIEND_CHAT,NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (friendlist), column); - - select = gtk_tree_view_get_selection (GTK_TREE_VIEW (friendlist)); - gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE); - - gtk_tree_view_set_grid_lines(GTK_TREE_VIEW(friendlist),GTK_TREE_VIEW_GRID_LINES_NONE); -#if GTK_CHECK_VERSION(2,12,0) - gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW(friendlist),FRIEND_SIP_ADDRESS); #endif - gtk_widget_set_size_request(friendlist,200,120); - /*gtk_combo_box_set_active(GTK_COMBO_BOX(linphone_gtk_get_widget( - gtk_widget_get_toplevel(friendlist),"show_category")),0);*/ +static void linphone_gtk_friend_list_init(GtkWidget *friendlist){ + GtkTreeModel *store = gtk_tree_view_get_model(GTK_TREE_VIEW(friendlist)); + GtkTreeSelection *select = gtk_tree_view_get_selection (GTK_TREE_VIEW (friendlist)); + + linphone_gtk_init_bookmark_icon(); + gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(friendlist),friend_search_func,NULL,NULL); + gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store),FRIEND_NAME,friend_sort,NULL,NULL); + gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE); + g_signal_connect(G_OBJECT(select), "changed", G_CALLBACK(linphone_gtk_contact_clicked), NULL); + + g_object_set_data(G_OBJECT(friendlist), "friendlist_initialized", (gpointer)TRUE); } void linphone_gtk_show_directory_search(void){ @@ -782,7 +652,7 @@ gboolean linphone_gtk_directory_search_focus_in(GtkWidget *entry){ void linphone_gtk_directory_search_activate(GtkWidget *entry){ LinphoneProxyConfig *cfg; GtkWidget *w; - linphone_core_get_default_proxy(linphone_gtk_get_core(),&cfg); + cfg = linphone_core_get_default_proxy_config(linphone_gtk_get_core()); w=linphone_gtk_show_buddy_lookup_window(linphone_proxy_config_get_sip_setup_context(cfg)); if (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(entry),"active"))==1) linphone_gtk_buddy_lookup_set_keyword(w,gtk_entry_get_text(GTK_ENTRY(entry))); @@ -799,26 +669,18 @@ void linphone_gtk_show_friends(void){ GtkListStore *store=NULL; GtkTreeIter iter; const MSList *itf; - //GtkWidget *filter=linphone_gtk_get_widget(mw,"search_bar"); LinphoneCore *core=linphone_gtk_get_core(); - //const gchar *search=NULL; - //gboolean lookup=FALSE; MSList *sorted; LinphoneChatRoom *cr=NULL; linphone_gtk_show_directory_search(); - if (gtk_tree_view_get_model(GTK_TREE_VIEW(friendlist))==NULL){ + if (!g_object_get_data(G_OBJECT(friendlist), "friendlist_initialized")) { linphone_gtk_friend_list_init(friendlist); } store=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(friendlist))); gtk_list_store_clear(store); - //search=gtk_entry_get_text(GTK_ENTRY(filter)); - //if (search==NULL || search[0]=='\0') - // lookup=FALSE; - //else lookup=TRUE; - sorted=sort_friend_list(linphone_core_get_friend_list(core)); for(itf=sorted;itf!=NULL;itf=ms_list_next(itf)){ @@ -828,15 +690,8 @@ void linphone_gtk_show_friends(void){ const char *name=linphone_address_get_display_name(f_uri); const char *display=name; char *escaped=NULL; - //char buf[26]={0}; int nbmsg=0; - /*if (lookup){ - if (strstr(uri,search)==NULL){ - ms_free(uri); - continue; - } - }*/ //BuddyInfo *bi; gboolean send_subscribe=linphone_friend_get_send_subscribe(lf); if (name==NULL || name[0]=='\0') { @@ -844,33 +699,24 @@ void linphone_gtk_show_friends(void){ } gtk_list_store_append(store,&iter); gtk_list_store_set(store,&iter,FRIEND_NAME, display,FRIEND_ID,lf, - FRIEND_PRESENCE_IMG, send_subscribe ? create_status_picture(linphone_friend_get_status(lf)) : NULL, - FRIEND_CHAT,create_chat_picture(),FRIEND_CALL,create_call_picture(),-1); + FRIEND_PRESENCE_IMG, send_subscribe ? status_to_icon_name(linphone_friend_get_status(lf)) : NULL, + FRIEND_CHAT,"linphone-chat-nothing", -1); cr=linphone_gtk_create_chatroom(f_uri); gtk_list_store_set(store,&iter,FRIEND_CHATROOM,cr,-1); nbmsg=linphone_chat_room_get_unread_messages_count(cr); if(nbmsg != 0){ - gtk_list_store_set(store,&iter,FRIEND_CHAT,create_unread_msg(),-1); + gtk_list_store_set(store,&iter,FRIEND_CHAT,"linphone-chat-new-message",-1); } escaped=g_markup_escape_text(uri,-1); gtk_list_store_set(store,&iter,FRIEND_SIP_ADDRESS,escaped,-1); g_free(escaped); - //bi=linphone_friend_get_info(lf); - /*if (bi!=NULL && bi->image_data!=NULL){ - GdkPixbuf *pbuf= - _gdk_pixbuf_new_from_memory_at_scale(bi->image_data,bi->image_length,-1,40,TRUE); - if (pbuf) { - //gtk_list_store_set(store,&iter,FRIEND_ICON,pbuf,-1); - g_object_unref(G_OBJECT(pbuf)); - } - }*/ ms_free(uri); } ms_list_free(sorted); } -void linphone_gtk_show_contact(LinphoneFriend *lf){ - GtkWidget *w=linphone_gtk_create_window("contact"); +void linphone_gtk_show_contact(LinphoneFriend *lf, GtkWidget *parent){ + GtkWidget *w=linphone_gtk_create_window("contact", parent); char *uri; const char *name; const LinphoneAddress *f_uri=linphone_friend_get_address(lf); @@ -888,6 +734,7 @@ void linphone_gtk_show_contact(LinphoneFriend *lf){ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"allow_presence")), linphone_friend_get_inc_subscribe_policy(lf)==LinphoneSPAccept); g_object_set_data(G_OBJECT(w),"friend_ref",(gpointer)lf); + gtk_widget_show(w); } @@ -948,11 +795,10 @@ void linphone_gtk_contact_ok(GtkWidget *button){ static GtkWidget *linphone_gtk_create_contact_menu(GtkWidget *contact_list){ GtkWidget *menu=gtk_menu_new(); GtkWidget *menu_item; - gchar *call_label=NULL; - gchar *text_label=NULL; gchar *edit_label=NULL; gchar *delete_label=NULL; gchar *delete_hist_label=NULL; + gchar *add_contact_label=NULL; gchar *name=NULL; GtkTreeSelection *select; GtkTreeIter iter; @@ -961,44 +807,27 @@ static GtkWidget *linphone_gtk_create_contact_menu(GtkWidget *contact_list){ LinphoneCore *lc=linphone_gtk_get_core(); LinphoneProxyConfig *cfg=NULL; SipSetupContext * ssc=NULL; + bool_t show_menu_separator=FALSE; - linphone_core_get_default_proxy(lc,&cfg); + cfg = linphone_core_get_default_proxy_config(lc); if (cfg){ ssc=linphone_proxy_config_get_sip_setup_context(cfg); } g_signal_connect(G_OBJECT(menu), "selection-done", G_CALLBACK (gtk_widget_destroy), NULL); select = gtk_tree_view_get_selection(GTK_TREE_VIEW(contact_list)); + add_contact_label=g_strdup_printf(_("Add a new contact")); if (gtk_tree_selection_get_selected (select, &model, &iter)){ gtk_tree_model_get(model, &iter,FRIEND_NAME , &name, -1); - call_label=g_strdup_printf(_("Call %s"),name); - text_label=g_strdup_printf(_("Send text to %s"),name); edit_label=g_strdup_printf(_("Edit contact '%s'"),name); delete_label=g_strdup_printf(_("Delete contact '%s'"),name); delete_hist_label=g_strdup_printf(_("Delete chat history of '%s'"),name); g_free(name); - } - if (call_label){ - menu_item=gtk_image_menu_item_new_with_label(call_label); - image=gtk_image_new_from_stock(GTK_STOCK_NETWORK,GTK_ICON_SIZE_MENU); - gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item),image); - gtk_widget_show(image); - gtk_widget_show(menu_item); - gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item); - g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_call_selected,contact_list); - } - if (text_label){ - menu_item=gtk_image_menu_item_new_with_label(text_label); - image=gtk_image_new_from_stock(GTK_STOCK_NETWORK,GTK_ICON_SIZE_MENU); - gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item),image); - gtk_widget_show(image); - gtk_widget_show(menu_item); - gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item); - g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_chat_selected,contact_list); + show_menu_separator=TRUE; } if (edit_label){ menu_item=gtk_image_menu_item_new_with_label(edit_label); - image=gtk_image_new_from_stock(GTK_STOCK_EDIT,GTK_ICON_SIZE_MENU); + image=gtk_image_new_from_icon_name("linphone-edit",GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item),image); gtk_widget_show(image); gtk_widget_show(menu_item); @@ -1007,7 +836,7 @@ static GtkWidget *linphone_gtk_create_contact_menu(GtkWidget *contact_list){ } if (delete_label){ menu_item=gtk_image_menu_item_new_with_label(delete_label); - image=gtk_image_new_from_stock(GTK_STOCK_DELETE,GTK_ICON_SIZE_MENU); + image=gtk_image_new_from_icon_name("linphone-delete",GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item),image); gtk_widget_show(image); gtk_widget_show(menu_item); @@ -1016,8 +845,11 @@ static GtkWidget *linphone_gtk_create_contact_menu(GtkWidget *contact_list){ } if (delete_hist_label){ + GtkWidget *menu_item_separator=gtk_separator_menu_item_new(); + gtk_widget_show(menu_item_separator); + gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item_separator); menu_item=gtk_image_menu_item_new_with_label(delete_hist_label); - image=gtk_image_new_from_stock(GTK_STOCK_CLEAR,GTK_ICON_SIZE_MENU); + image=gtk_image_new_from_icon_name("linphone-delete",GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item),image); gtk_widget_show(image); gtk_widget_show(menu_item); @@ -1029,24 +861,31 @@ static GtkWidget *linphone_gtk_create_contact_menu(GtkWidget *contact_list){ gchar *tmp=g_strdup_printf(_("Add new contact from %s directory"),linphone_proxy_config_get_domain(cfg)); menu_item=gtk_image_menu_item_new_with_label(tmp); g_free(tmp); - image=gtk_image_new_from_stock(GTK_STOCK_ADD,GTK_ICON_SIZE_MENU); + image=gtk_image_new_from_icon_name("linphone-contact-add",GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item),image); gtk_widget_show(image); gtk_widget_show(menu_item); gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item); g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_show_buddy_lookup_window,ssc); - gtk_widget_show(menu); } - menu_item=gtk_image_menu_item_new_from_stock(GTK_STOCK_ADD,NULL); + if (show_menu_separator) { + GtkWidget *menu_item_separator=gtk_separator_menu_item_new(); + gtk_widget_show(menu_item_separator); + gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item_separator); + } + + menu_item=gtk_image_menu_item_new_with_label(add_contact_label); + image=gtk_image_new_from_icon_name("linphone-contact-add",GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item),image); + gtk_widget_show(image); gtk_widget_show(menu_item); gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item); g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_add_contact,contact_list); gtk_widget_show(menu); gtk_menu_attach_to_widget (GTK_MENU (menu), contact_list, NULL); - if (call_label) g_free(call_label); - if (text_label) g_free(text_label); + g_free(add_contact_label); if (edit_label) g_free(edit_label); if (delete_label) g_free(delete_label); return menu; @@ -1059,61 +898,88 @@ gboolean linphone_gtk_popup_contact_menu(GtkWidget *list, GdkEventButton *event) return TRUE; } -gint get_col_number_from_tree_view_column (GtkTreeViewColumn *col){ - GList *cols; - gint num; - g_return_val_if_fail ( col != NULL, -1 ); - g_return_val_if_fail ( col->tree_view != NULL, -1 ); - cols = gtk_tree_view_get_columns(GTK_TREE_VIEW(col->tree_view)); - num = g_list_index(cols, (gpointer) col); - g_list_free(cols); - - return num; +static int get_column_index(GtkTreeView *friendlist, const GtkTreeViewColumn *column) { + GList *columns = gtk_tree_view_get_columns(friendlist); + int i = g_list_index(columns, column); + g_list_free(columns); + return i; } -static gint tree_view_get_cell_from_pos(GtkTreeView *view, guint x, guint y){ - GtkTreeViewColumn *col = NULL; - GList *node, *columns; - gint colx = 0; +static void select_row(GtkTreeView *treeview, GtkTreePath *path) { + GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview); + gtk_tree_selection_select_path(selection, path); +} + +gboolean linphone_gtk_contact_list_button_pressed(GtkTreeView *friendlist, GdkEventButton *event){ + /* Ignore double-clicks and triple-clicks */ + gboolean ret = FALSE; + int x_bin, y_bin; GtkTreePath *path; - GtkTreeViewDropPosition pos; - - g_return_val_if_fail ( view != NULL, 0 ); - columns = gtk_tree_view_get_columns(view); - - gtk_tree_view_get_dest_row_at_pos(view,x,y,&path,&pos); - if(path != NULL){ - for (node = columns; node != NULL && col == NULL; node = node->next){ - GtkTreeViewColumn *checkcol = (GtkTreeViewColumn*) node->data; - if (x >= colx && x < (colx + checkcol->width)){ - col = checkcol; - return get_col_number_from_tree_view_column(col); - } else { - colx += checkcol->width; + GtkTreeViewColumn *column; + GtkTreeSelection *selection = gtk_tree_view_get_selection(friendlist); + + gtk_tree_view_convert_widget_to_bin_window_coords(friendlist, event->x, event->y, &x_bin, &y_bin); + gtk_tree_view_get_path_at_pos(friendlist, x_bin, y_bin, &path, &column, NULL, NULL); + + if (event->button == 3 && event->type == GDK_BUTTON_PRESS) { + if(path) gtk_tree_selection_select_path(selection, path); + ret = linphone_gtk_popup_contact_menu(GTK_WIDGET(friendlist), event); + } else if(event->button == 1 && event->type == GDK_BUTTON_PRESS){ + if(path && column) { + int numcol = get_column_index(friendlist, column); + if(numcol == 2) { + select_row(friendlist, path); + linphone_gtk_call_selected(friendlist); + ret = TRUE; + } else if(numcol == 3) { + select_row(friendlist, path); + linphone_gtk_chat_selected(GTK_WIDGET(friendlist)); + ret = TRUE; } } } - g_list_free(columns); - return 0; -} - -gboolean linphone_gtk_contact_list_button_pressed(GtkWidget *widget, GdkEventButton *event){ - /* Ignore double-clicks and triple-clicks */ - if (event->button == 3 && event->type == GDK_BUTTON_PRESS) - { - return linphone_gtk_popup_contact_menu(widget, event); - } else if(event->button == 1 && event->type == GDK_BUTTON_PRESS){ - gint numcol = tree_view_get_cell_from_pos(GTK_TREE_VIEW(widget),event->x,event->y); - if(numcol==2){ - g_object_set_data(G_OBJECT(widget),"numcol",GINT_TO_POINTER(1)); - } else if(numcol==3){ - g_object_set_data(G_OBJECT(widget),"numcol",GINT_TO_POINTER(2)); - } - } - return FALSE; + if(path) gtk_tree_path_free(path); + return ret; } void linphone_gtk_buddy_info_updated(LinphoneCore *lc, LinphoneFriend *lf){ /*refresh the entire list*/ linphone_gtk_show_friends(); } + +static gboolean update_hovered_row_path(GtkTreeView *friendlist, int x_window, int y_window) { + int x_bin, y_bin; + GtkTreePath *new_path; + GtkTreePath *old_path = (GtkTreePath *)g_object_get_data(G_OBJECT(friendlist), "hovered_row"); + gtk_tree_view_convert_widget_to_bin_window_coords(friendlist, x_window, y_window, &x_bin, &y_bin); + gtk_tree_view_get_path_at_pos(friendlist, x_bin, y_bin, &new_path, NULL, NULL, NULL); + if((new_path == NULL && old_path == NULL) || (new_path && old_path && gtk_tree_path_compare(new_path, old_path) == 0)) { + if(new_path) gtk_tree_path_free(new_path); + return FALSE; + } else { + g_object_set_data_full(G_OBJECT(friendlist), "hovered_row", new_path, (GDestroyNotify)gtk_tree_path_free); + return TRUE; + } +} + +gboolean linphone_gtk_friend_list_enter_event_handler(GtkTreeView *friendlist, GdkEventCrossing *event) { + gboolean path_has_changed = update_hovered_row_path(friendlist, event->x, event->y); + if(path_has_changed) linphone_gtk_friend_list_update_button_display(friendlist); + return FALSE; +} + +gboolean linphone_gtk_friend_list_leave_event_handler(GtkTreeView *friendlist, GdkEventCrossing *event) { + GtkTreePath *hovered_row = (GtkTreePath *)g_object_get_data(G_OBJECT(friendlist), "hovered_row"); + if(hovered_row) { + g_object_set_data(G_OBJECT(friendlist), "hovered_row", NULL); + linphone_gtk_friend_list_update_button_display(friendlist); + } + return FALSE; +} + +gboolean linphone_gtk_friend_list_motion_event_handler(GtkTreeView *friendlist, GdkEventMotion *event) { + gboolean path_has_changed = update_hovered_row_path(friendlist, event->x, event->y); + if(path_has_changed) linphone_gtk_friend_list_update_button_display(friendlist); + return FALSE; +} + diff --git a/gtk/in_call_frame.ui b/gtk/in_call_frame.ui new file mode 100644 index 000000000..1e713d19c --- /dev/null +++ b/gtk/in_call_frame.ui @@ -0,0 +1,433 @@ + + + + + + True + False + 16 + linphone-security-pending + + + False + cursor + 0.5 + none + + + True + False + 12 + 12 + + + True + False + + + True + False + center + + + True + True + 0 + + + + + True + False + + + + + + False + False + 1 + + + + + False + + + True + True + True + zrtp_button_icon + none + + + + True + False + 0 + + + + + False + False + 2 + + + + + False + 4 + + + True + False + 1 + 16 + linphone-security-ok + + + True + True + 0 + + + + + True + False + 0 + Encryption status + + + True + True + 1 + + + + + True + True + 3 + + + + + True + False + + + True + False + + + True + True + True + True + none + False + vertical + linphone-micro-enabled + + + False + False + 5 + 0 + + + + + True + False + + + False + False + 5 + 1 + + + + + True + False + 10 + 0 + + + + + True + False + + + True + True + True + True + Click here to set the speakers volume + none + False + vertical + linphone-speaker-enabled + + + False + False + 5 + 0 + + + + + True + False + + + False + False + 5 + 1 + + + + + True + False + 10 + 1 + + + + + False + False + 5 + 4 + + + + + False + spread + + + Answer + True + True + True + + + + False + False + 0 + + + + + Decline + True + True + True + + + + False + False + 1 + + + + + False + False + 5 + + + + + False + + + Record + True + True + True + Record this call to an audio file + + + + False + False + 0 + + + + + True + False + True + char + + + True + True + 1 + + + + + False + False + 6 + + + + + True + False + 2 + 3 + True + + + Video + True + True + True + + + + + Pause + True + True + True + + + + 1 + 2 + + + + + Mute + True + True + True + + + + 2 + 3 + + + + + Transfer + True + True + True + + + 1 + 2 + + + + + Hang up + True + True + True + + + + 1 + 2 + 1 + 2 + + + + + Conference + True + True + True + + + 2 + 3 + 1 + 2 + + + + + False + False + 7 + 7 + + + + + + + + + True + False + True + + + True + False + In call + True + center + + + True + True + 0 + + + + + True + False + Duration + center + + + True + True + 1 + + + + + 90 + 10 + True + False + GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK + Call quality rating + + + False + False + 2 + + + + + + diff --git a/gtk/incall_view.c b/gtk/incall_view.c index f291afcb5..5c7620840 100644 --- a/gtk/incall_view.c +++ b/gtk/incall_view.c @@ -29,8 +29,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "linphone.h" - -gboolean linphone_gtk_use_in_call_view(){ +gboolean linphone_gtk_use_in_call_view(void){ static int val=-1; if (val==-1) val=linphone_gtk_get_ui_config_int("use_incall_view",1); return val; @@ -64,15 +63,9 @@ LinphoneCall *linphone_gtk_get_currently_displayed_call(gboolean *is_conf){ } static GtkWidget *make_tab_header(int number){ - GtkWidget *w=gtk_hbox_new (FALSE,0); - GtkWidget *i=create_pixmap ("startcall-small.png"); - GtkWidget *l; - gchar *text=g_strdup_printf(_("Call #%i"),number); - l=gtk_label_new (text); - gtk_box_pack_start (GTK_BOX(w),i,FALSE,FALSE,0); - gtk_box_pack_end(GTK_BOX(w),l,TRUE,TRUE,0); - gtk_widget_show_all(w); - return w; + gchar text[20]; + g_snprintf(text, sizeof(text), _("Call #%i"), number); + return linphone_gtk_make_tab_header(text, "linphone-start-call", FALSE, NULL, NULL); } void linphone_gtk_call_update_tab_header(LinphoneCall *call,gboolean pause){ @@ -86,9 +79,9 @@ void linphone_gtk_call_update_tab_header(LinphoneCall *call,gboolean pause){ gchar *text; if(pause){ - i=gtk_image_new_from_stock(GTK_STOCK_MEDIA_PAUSE,GTK_ICON_SIZE_SMALL_TOOLBAR); + i=gtk_image_new_from_icon_name("linphone-hold-off",GTK_ICON_SIZE_BUTTON); } else { - i=create_pixmap ("startcall-small.png"); + i=gtk_image_new_from_icon_name("linphone-start-call", GTK_ICON_SIZE_BUTTON); } text=g_strdup_printf(_("Call #%i"),call_index); @@ -101,18 +94,15 @@ void linphone_gtk_call_update_tab_header(LinphoneCall *call,gboolean pause){ g_free(text); } -static void linphone_gtk_in_call_set_animation_image(GtkWidget *callview, const char *image_name, gboolean is_stock){ +static void linphone_gtk_in_call_set_animation_image(GtkWidget *callview, const char *image_name){ GtkWidget *container=linphone_gtk_get_widget(callview,"in_call_animation"); GList *elem=gtk_container_get_children(GTK_CONTAINER(container)); GtkWidget *image; - if (!is_stock){ - if (image_name==NULL){ - gtk_widget_hide(container); - } - image=create_pixmap(image_name); - }else - image=gtk_image_new_from_stock(image_name,GTK_ICON_SIZE_DND); + if (image_name==NULL){ + gtk_widget_hide(container); + } + image=gtk_image_new_from_icon_name(image_name,GTK_ICON_SIZE_DIALOG); if (elem) gtk_widget_destroy((GtkWidget*)elem->data); gtk_widget_show(image); @@ -153,10 +143,11 @@ void transfer_button_clicked(GtkWidget *button, gpointer call_ref){ int call_index=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(call_view),"call_index")); char *remote_uri=linphone_call_get_remote_address_as_string (other_call); char *text=g_strdup_printf(_("Transfer to call #%i with %s"),call_index,remote_uri); + GtkWidget *image = gtk_image_new_from_icon_name("linphone-start-call", GTK_ICON_SIZE_MENU); menu_item=gtk_image_menu_item_new_with_label(text); ms_free(remote_uri); g_free(text); - gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item),create_pixmap("status-green.png")); + gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item), image); gtk_widget_show(menu_item); gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item); g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_transfer_call,other_call); @@ -338,7 +329,7 @@ static void linphone_gtk_show_call_stats(LinphoneCall *call){ GtkWidget *call_stats=(GtkWidget*)g_object_get_data(G_OBJECT(w),"call_stats"); if (call_stats==NULL){ guint tid; - call_stats=linphone_gtk_create_window("call_statistics"); + call_stats=linphone_gtk_create_window("call_statistics", NULL); g_object_set_data(G_OBJECT(w),"call_stats",call_stats); g_object_set_data(G_OBJECT(call_stats),"call",linphone_call_ref(call)); tid=g_timeout_add(1000,(GSourceFunc)refresh_call_stats,call_stats); @@ -360,18 +351,68 @@ void linphone_gtk_enable_video_button(LinphoneCall *call, gboolean sensitive, gb gtk_widget_set_visible(GTK_WIDGET(button),sensitive); } + +typedef enum { VOLUME_CTRL_PLAYBACK, VOLUME_CTRL_RECORD } VolumeControlType; + +static void volume_control_value_changed(GtkScaleButton *button, gdouble value, gpointer user_data) { + LinphoneCall *call = (LinphoneCall *)g_object_get_data(G_OBJECT(button), "call"); + VolumeControlType type = (VolumeControlType)GPOINTER_TO_INT(g_object_get_data(G_OBJECT(button), "type")); + + if(type == VOLUME_CTRL_PLAYBACK) { + linphone_call_set_speaker_volume_gain(call, value); + } else if(type == VOLUME_CTRL_RECORD) { + linphone_call_set_microphone_volume_gain(call, value); + } +} + +static gboolean volume_control_button_update_value(GtkWidget *widget) { + LinphoneCall *call = (LinphoneCall *)g_object_get_data(G_OBJECT(widget), "call"); + VolumeControlType type = (VolumeControlType)GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "type")); + float gain = -1; + + if(type == VOLUME_CTRL_PLAYBACK) { + gain = linphone_call_get_speaker_volume_gain(call); + } else if(type == VOLUME_CTRL_RECORD) { + gain = linphone_call_get_microphone_volume_gain(call); + } + if(gain >= 0.0f) { + gtk_scale_button_set_value(GTK_SCALE_BUTTON(widget), gain); + return TRUE; + } else { + return FALSE; + } +} + +static gboolean volume_control_button_enter_event_handler(GtkWidget *widget) { + volume_control_button_update_value(widget); + return FALSE; +} + +static void volume_control_init(GtkWidget *vol_ctrl, VolumeControlType type, LinphoneCall *call) { + g_object_set_data(G_OBJECT(vol_ctrl), "call", call); + g_object_set_data(G_OBJECT(vol_ctrl), "type", GINT_TO_POINTER(type)); + if(!volume_control_button_update_value(vol_ctrl)) { + gtk_widget_set_sensitive(vol_ctrl, FALSE); + } else { + gtk_widget_set_sensitive(vol_ctrl, TRUE); + g_signal_connect(G_OBJECT(vol_ctrl), "enter-notify-event", G_CALLBACK(volume_control_button_enter_event_handler), NULL); + g_signal_connect(G_OBJECT(vol_ctrl), "value-changed", G_CALLBACK(volume_control_value_changed), NULL); + } +} + void linphone_gtk_create_in_call_view(LinphoneCall *call){ - GtkWidget *call_view=linphone_gtk_create_widget("main","in_call_frame"); + GtkWidget *call_view=linphone_gtk_create_widget("in_call_frame"); GtkWidget *main_window=linphone_gtk_get_main_window (); GtkNotebook *notebook=(GtkNotebook *)linphone_gtk_get_widget(main_window,"viewswitch"); + GtkWidget *audio_bar = linphone_gtk_get_widget(call_view, "incall_audioview"); static int call_index=1; int idx; + GtkWidget *record; GtkWidget *transfer; GtkWidget *conf; GtkWidget *button; GtkWidget *image; - if (ms_list_size(linphone_core_get_calls(linphone_gtk_get_core()))==1){ /*this is the only call at this time */ call_index=1; @@ -391,23 +432,30 @@ void linphone_gtk_create_in_call_view(LinphoneCall *call){ linphone_gtk_enable_mute_button( GTK_BUTTON(linphone_gtk_get_widget(call_view,"incall_mute")),FALSE); + record = linphone_gtk_get_widget(call_view, "record_button"); + gtk_button_set_image(GTK_BUTTON(record), gtk_image_new_from_icon_name("linphone-record", GTK_ICON_SIZE_BUTTON)); + gtk_widget_hide(record); transfer = linphone_gtk_get_widget(call_view,"transfer_button"); - gtk_button_set_image(GTK_BUTTON(transfer),gtk_image_new_from_stock - (GTK_STOCK_GO_FORWARD,GTK_ICON_SIZE_BUTTON)); + gtk_button_set_image(GTK_BUTTON(transfer),gtk_image_new_from_icon_name("linphone-call-transfer",GTK_ICON_SIZE_BUTTON)); g_signal_connect(G_OBJECT(transfer),"clicked",(GCallback)transfer_button_clicked,call); gtk_widget_hide(transfer); conf = linphone_gtk_get_widget(call_view,"conference_button"); - gtk_button_set_image(GTK_BUTTON(conf),gtk_image_new_from_stock (GTK_STOCK_ADD,GTK_ICON_SIZE_BUTTON)); + gtk_button_set_image(GTK_BUTTON(conf),gtk_image_new_from_icon_name("linphone-conference-start",GTK_ICON_SIZE_BUTTON)); g_signal_connect(G_OBJECT(conf),"clicked",(GCallback)conference_button_clicked,call); gtk_widget_hide(conf); button=linphone_gtk_get_widget(call_view,"terminate_call"); - image=create_pixmap (linphone_gtk_get_ui_config("stop_call_icon","stopcall-small.png")); + image=gtk_image_new_from_icon_name( + linphone_gtk_get_ui_config("stop_call_icon_name","linphone-stop-call"), + GTK_ICON_SIZE_BUTTON + ); gtk_button_set_label(GTK_BUTTON(button),_("Hang up")); gtk_button_set_image(GTK_BUTTON(button),image); gtk_widget_show(image); g_signal_connect_swapped(G_OBJECT(linphone_gtk_get_widget(call_view,"quality_indicator")),"button-press-event",(GCallback)linphone_gtk_show_call_stats,call); + + gtk_widget_hide(audio_bar); } static void video_button_clicked(GtkWidget *button, LinphoneCall *call){ @@ -432,7 +480,7 @@ void linphone_gtk_update_video_button(LinphoneCall *call){ button=linphone_gtk_get_widget(call_view,"video_button"); gtk_button_set_image(GTK_BUTTON(button), - gtk_image_new_from_stock(has_video ? GTK_STOCK_REMOVE : GTK_STOCK_ADD,GTK_ICON_SIZE_BUTTON)); + gtk_image_new_from_icon_name(has_video ? "linphone-camera-disabled" : "linphone-camera-enabled",GTK_ICON_SIZE_BUTTON)); g_object_set_data(G_OBJECT(button),"adding_video",GINT_TO_POINTER(!has_video)); if (!linphone_core_video_supported(linphone_call_get_core(call))){ gtk_widget_set_sensitive(button,FALSE); @@ -511,7 +559,7 @@ void linphone_gtk_in_call_view_set_calling(LinphoneCall *call){ gtk_label_set_markup(GTK_LABEL(status),_("Calling...")); display_peer_name_in_label(callee,linphone_call_get_remote_address (call)); - gtk_label_set_text(GTK_LABEL(duration),_("00::00::00")); + gtk_label_set_text(GTK_LABEL(duration),_("00:00:00")); linphone_gtk_in_call_set_animation_spinner(callview); } @@ -528,16 +576,16 @@ void linphone_gtk_in_call_view_set_incoming(LinphoneCall *call){ display_peer_name_in_label(callee,linphone_call_get_remote_address (call)); answer_button=linphone_gtk_get_widget(callview,"accept_call"); - image=create_pixmap (linphone_gtk_get_ui_config("start_call_icon","startcall-small.png")); + image=gtk_image_new_from_icon_name("linphone-start-call", GTK_ICON_SIZE_BUTTON); gtk_button_set_label(GTK_BUTTON(answer_button),_("Answer")); gtk_button_set_image(GTK_BUTTON(answer_button),image); gtk_widget_show(image); - image=create_pixmap (linphone_gtk_get_ui_config("stop_call_icon","stopcall-small.png")); + image=gtk_image_new_from_icon_name("linphone-stop-call", GTK_ICON_SIZE_BUTTON); gtk_button_set_image(GTK_BUTTON(linphone_gtk_get_widget(callview,"decline_call")),image); gtk_widget_show(image); - linphone_gtk_in_call_set_animation_image(callview,GTK_STOCK_DIALOG_INFO,TRUE); + linphone_gtk_in_call_set_animation_image(callview,"linphone-call-status-incoming"); } static void rating_to_color(float rating, GdkColor *color){ @@ -608,10 +656,12 @@ static gboolean update_audio_meter(volume_ctx_t *ctx){ return TRUE; } -static void on_audio_meter_destroy(guint task_id){ +static void on_audio_meter_destroy(GtkWidget *w, gpointer data){ + guint task_id = GPOINTER_TO_INT(data); g_source_remove(task_id); } + void linphone_gtk_init_audio_meter(GtkWidget *w, get_volume_t get_volume, void *data){ guint task_id=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w),"task_id")); if (task_id==0){ @@ -622,7 +672,8 @@ void linphone_gtk_init_audio_meter(GtkWidget *w, get_volume_t get_volume, void * ctx->last_value=0; g_object_set_data_full(G_OBJECT(w),"ctx",ctx,g_free); task_id=g_timeout_add(50,(GSourceFunc)update_audio_meter,ctx); - g_object_set_data_full(G_OBJECT(w),"task_id",GINT_TO_POINTER(task_id),(GDestroyNotify)on_audio_meter_destroy); + g_object_set_data(G_OBJECT(w), "task_id", GINT_TO_POINTER(task_id)); + g_signal_connect(G_OBJECT(w), "destroy", (GCallback)on_audio_meter_destroy, GINT_TO_POINTER(task_id)); } } @@ -631,25 +682,23 @@ void linphone_gtk_uninit_audio_meter(GtkWidget *w){ if (task_id!=0){ g_object_set_data(G_OBJECT(w),"ctx",NULL); g_object_set_data(G_OBJECT(w),"task_id",NULL); + g_source_remove(task_id); } } void linphone_gtk_in_call_view_enable_audio_view(LinphoneCall *call, gboolean val){ GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call); GtkWidget *audio_view=linphone_gtk_get_widget(callview,"incall_audioview"); - GtkWidget *mic=linphone_gtk_get_widget(callview,"incall_mic_icon"); - GtkWidget *spk=linphone_gtk_get_widget(callview,"incall_spk_icon"); GtkWidget *mic_level=linphone_gtk_get_widget(callview,"mic_audiolevel"); GtkWidget *spk_level=linphone_gtk_get_widget(callview,"spk_audiolevel"); - GdkPixbuf *pbuf; + GtkWidget *mic_ctrl = linphone_gtk_get_widget(callview, "incall_mic_vol_ctrl_button"); + GtkWidget *spk_ctrl = linphone_gtk_get_widget(callview, "incall_spk_vol_ctrl_button"); - gtk_image_set_from_pixbuf(GTK_IMAGE(mic),(pbuf=create_pixbuf("mic_active.png"))); - g_object_unref(pbuf); if (val){ - gtk_image_set_from_pixbuf(GTK_IMAGE(spk),(pbuf=create_pixbuf("speaker.png"))); - g_object_unref(pbuf); linphone_gtk_init_audio_meter(mic_level,(get_volume_t)linphone_call_get_record_volume,call); linphone_gtk_init_audio_meter(spk_level,(get_volume_t)linphone_call_get_play_volume,call); + volume_control_init(mic_ctrl, VOLUME_CTRL_RECORD, call); + volume_control_init(spk_ctrl, VOLUME_CTRL_PLAYBACK, call); gtk_widget_show_all(audio_view); }else{ linphone_gtk_uninit_audio_meter(mic_level); @@ -666,51 +715,61 @@ void linphone_gtk_auth_token_verified_clicked(GtkButton *button){ } void linphone_gtk_in_call_view_show_encryption(LinphoneCall *call){ - GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call); - GtkWidget *encryption_box=linphone_gtk_get_widget(callview,"encryption_box"); - GtkWidget *label=linphone_gtk_get_widget(callview,"encryption_label"); - GtkWidget *status_icon=linphone_gtk_get_widget(callview,"encryption_status_icon"); - GtkWidget *verify_button=linphone_gtk_get_widget(callview,"encryption_verify_button"); - LinphoneMediaEncryption me=linphone_call_params_get_media_encryption(linphone_call_get_current_params(call)); - bool_t verified=linphone_call_get_authentication_token_verified(call); - switch(me){ + GtkWidget *callview = (GtkWidget*)linphone_call_get_user_pointer(call); + GtkWidget *encryption_status_box = linphone_gtk_get_widget(callview, "encryption_status_box"); + GtkWidget *encryption_status_label = linphone_gtk_get_widget(callview, "encryption_status_label"); + GtkWidget *encryption_status_icon = linphone_gtk_get_widget(callview, "encryption_status_icon"); + GtkWidget *zrtp_box = linphone_gtk_get_widget(callview, "zrtp_box"); + GtkWidget *zrtp_button = linphone_gtk_get_widget(callview, "zrtp_button"); + GtkWidget *zrtp_status_icon = gtk_button_get_image(GTK_BUTTON(zrtp_button)); + LinphoneMediaEncryption me = linphone_call_params_get_media_encryption(linphone_call_get_current_params(call)); + + switch (me) { case LinphoneMediaEncryptionSRTP: - gtk_widget_show_all(encryption_box); - gtk_label_set_markup(GTK_LABEL(label),_("Secured by SRTP")); - gtk_widget_hide(status_icon); - gtk_widget_hide(verify_button); - break; + gtk_widget_hide_all(zrtp_box); + gtk_widget_show_all(encryption_status_box); + gtk_label_set_markup(GTK_LABEL(encryption_status_label), _("Secured by SRTP")); + gtk_image_set_from_icon_name(GTK_IMAGE(encryption_status_icon), "linphone-security-ok", GTK_ICON_SIZE_MENU); + break; case LinphoneMediaEncryptionDTLS: - gtk_widget_show_all(encryption_box); - gtk_label_set_markup(GTK_LABEL(label),_("Secured by DTLS")); - gtk_widget_hide(status_icon); - gtk_widget_hide(verify_button); - break; + gtk_widget_hide_all(zrtp_box); + gtk_widget_show_all(encryption_status_box); + gtk_label_set_markup(GTK_LABEL(encryption_status_label), _("Secured by DTLS")); + gtk_image_set_from_icon_name(GTK_IMAGE(encryption_status_icon), "linphone-security-ok", GTK_ICON_SIZE_MENU); + break; case LinphoneMediaEncryptionZRTP: { - gchar *text=g_strdup_printf(_("Secured by ZRTP - [auth token: %s]"),linphone_call_get_authentication_token(call)); - gtk_label_set_markup(GTK_LABEL(label),text); + bool_t verified = linphone_call_get_authentication_token_verified(call); + gchar *text = g_strdup_printf(_("Secured by ZRTP - [auth token: %s]"), linphone_call_get_authentication_token(call)); + gtk_button_set_label(GTK_BUTTON(zrtp_button), text); g_free(text); - gtk_image_set_from_stock(GTK_IMAGE(status_icon), - verified ? GTK_STOCK_APPLY : GTK_STOCK_DIALOG_WARNING,GTK_ICON_SIZE_MENU); - gtk_button_set_label(GTK_BUTTON(verify_button), - verified ? _("Set unverified") : _("Set verified")); - gtk_widget_show_all(encryption_box); + gtk_image_set_from_icon_name(GTK_IMAGE(zrtp_status_icon), verified ? "linphone-security-ok" : "linphone-security-pending", GTK_ICON_SIZE_MENU); + gtk_widget_set_tooltip_text(zrtp_button, verified ? _("Set unverified") : _("Set verified")); + gtk_widget_hide_all(encryption_status_box); + gtk_widget_show_all(zrtp_box); } break; default: - gtk_widget_hide_all(encryption_box); + gtk_widget_hide_all(encryption_status_box); + gtk_widget_hide_all(zrtp_box); + break; } } +void linphone_gtk_in_call_view_hide_encryption(LinphoneCall *call) { + GtkWidget *callview = (GtkWidget*)linphone_call_get_user_pointer(call); + GtkWidget *encryption_status_box = linphone_gtk_get_widget(callview, "encryption_status_box"); + GtkWidget *zrtp_box = linphone_gtk_get_widget(callview, "zrtp_box"); + gtk_widget_hide_all(encryption_status_box); + gtk_widget_hide_all(zrtp_box); +} + char *linphone_gtk_address(const LinphoneAddress *addr){ const char *displayname=linphone_address_get_display_name(addr); if (!displayname) return linphone_address_as_string_uri_only(addr); return ms_strdup(displayname); } - - void linphone_gtk_in_call_view_set_in_call(LinphoneCall *call){ GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call); GtkWidget *status=linphone_gtk_get_widget(callview,"in_call_status"); @@ -730,8 +789,8 @@ void linphone_gtk_in_call_view_set_in_call(LinphoneCall *call){ gtk_widget_set_sensitive(linphone_gtk_get_widget(callview,"conference_button"),!in_conf); gtk_widget_set_sensitive(linphone_gtk_get_widget(callview,"transfer_button"),!in_conf); - gtk_label_set_text(GTK_LABEL(duration),_("00::00::00")); - linphone_gtk_in_call_set_animation_image(callview,GTK_STOCK_MEDIA_PLAY,TRUE); + gtk_label_set_text(GTK_LABEL(duration),_("00:00:00")); + linphone_gtk_in_call_set_animation_image(callview,"linphone-media-play"); linphone_gtk_call_update_tab_header(call,FALSE); linphone_gtk_enable_mute_button( GTK_BUTTON(linphone_gtk_get_widget(callview,"incall_mute")),TRUE); @@ -760,10 +819,12 @@ void linphone_gtk_in_call_view_set_in_call(LinphoneCall *call){ void linphone_gtk_in_call_view_set_paused(LinphoneCall *call){ GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call); GtkWidget *status=linphone_gtk_get_widget(callview,"in_call_status"); + GtkWidget *record_bar = linphone_gtk_get_widget(callview, "record_hbox"); gtk_widget_hide(linphone_gtk_get_widget(callview,"answer_decline_panel")); gtk_label_set_markup(GTK_LABEL(status),_("Paused call")); linphone_gtk_in_call_show_video(call); - linphone_gtk_in_call_set_animation_image(callview,GTK_STOCK_MEDIA_PAUSE,TRUE); + linphone_gtk_in_call_set_animation_image(callview,"linphone-media-pause"); + gtk_widget_show_all(record_bar); } void linphone_gtk_in_call_view_update_duration(LinphoneCall *call){ @@ -774,7 +835,7 @@ void linphone_gtk_in_call_view_update_duration(LinphoneCall *call){ int seconds=duration%60; int minutes=(duration/60)%60; int hours=duration/3600; - snprintf(tmp,sizeof(tmp)-1,"%02i::%02i::%02i",hours,minutes,seconds); + snprintf(tmp,sizeof(tmp)-1,"%02i:%02i:%02i",hours,minutes,seconds); gtk_label_set_text(GTK_LABEL(duration_label),tmp); } @@ -803,8 +864,8 @@ void linphone_gtk_in_call_view_terminate(LinphoneCall *call, const char *error_m gtk_label_set_markup(GTK_LABEL(status),msg); g_free(msg); } - linphone_gtk_in_call_set_animation_image(callview, - linphone_gtk_get_ui_config("stop_call_icon","stopcall-red.png"),FALSE); + linphone_gtk_in_call_set_animation_image(callview, linphone_gtk_get_ui_config("stop_call_icon_name","linphone-stop-call")); + linphone_gtk_in_call_view_hide_encryption(call); gtk_widget_hide(linphone_gtk_get_widget(callview,"answer_decline_panel")); gtk_widget_hide(linphone_gtk_get_widget(callview,"record_hbox")); @@ -844,27 +905,16 @@ void linphone_gtk_in_call_view_set_transfer_status(LinphoneCall *call,LinphoneCa } void linphone_gtk_draw_mute_button(GtkButton *button, gboolean active){ + const char *icon_name = active ? "linphone-micro-muted" : "linphone-micro-enabled"; + GtkWidget *image = gtk_image_new_from_icon_name(icon_name, GTK_ICON_SIZE_BUTTON); + gtk_button_set_image(button, image); + gtk_widget_show(image); g_object_set_data(G_OBJECT(button),"active",GINT_TO_POINTER(active)); - if (active){ - GtkWidget *image=create_pixmap("mic_muted.png"); - /*gtk_button_set_label(GTK_BUTTON(button),_("Unmute"));*/ - if (image!=NULL) { - gtk_button_set_image(GTK_BUTTON(button),image); - gtk_widget_show(image); - } - }else{ - GtkWidget *image=create_pixmap("mic_active.png"); - /*gtk_button_set_label(GTK_BUTTON(button),_("Mute"));*/ - if (image!=NULL) { - gtk_button_set_image(GTK_BUTTON(button),image); - gtk_widget_show(image); - } - } } void linphone_gtk_mute_clicked(GtkButton *button){ int active=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(button),"active")); - linphone_core_mute_mic(linphone_gtk_get_core(),!active); + linphone_core_enable_mic(linphone_gtk_get_core(),active); linphone_gtk_draw_mute_button(button,!active); } @@ -875,22 +925,13 @@ void linphone_gtk_enable_mute_button(GtkButton *button, gboolean sensitive){ } void linphone_gtk_draw_hold_button(GtkButton *button, gboolean active){ + const gchar *icon_name = active ? "linphone-hold-on" : "linphone-hold-off"; + const gchar *label = active ? _("Resume") : _("Pause"); + GtkWidget *image = gtk_image_new_from_icon_name(icon_name, GTK_ICON_SIZE_BUTTON); g_object_set_data(G_OBJECT(button),"active",GINT_TO_POINTER(active)); - if (active){ - GtkWidget *image=create_pixmap("hold_off.png"); - gtk_button_set_label(GTK_BUTTON(button),_("Resume")); - if (image!=NULL) { - gtk_button_set_image(GTK_BUTTON(button),image); - gtk_widget_show(image); - } - }else{ - GtkWidget *image=create_pixmap("hold_on.png"); - gtk_button_set_label(GTK_BUTTON(button),_("Pause")); - if (image!=NULL) { - gtk_button_set_image(GTK_BUTTON(button),image); - gtk_widget_show(image); - } - } + gtk_button_set_label(GTK_BUTTON(button),label); + gtk_button_set_image(GTK_BUTTON(button),image); + gtk_widget_show(image); } void linphone_gtk_hold_clicked(GtkButton *button){ diff --git a/gtk/keypad.ui b/gtk/keypad.ui index 86c957531..020204f2b 100644 --- a/gtk/keypad.ui +++ b/gtk/keypad.ui @@ -4,6 +4,7 @@ False + True @@ -29,12 +30,11 @@ True - D + D True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False 3 @@ -45,12 +45,11 @@ - # + # True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False 2 @@ -61,12 +60,11 @@ - 0 + 0 True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False 1 @@ -77,12 +75,11 @@ - * + * True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False 3 @@ -91,12 +88,11 @@ - C + C True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False 3 @@ -107,12 +103,11 @@ - 9 + 9 True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False 2 @@ -123,12 +118,11 @@ - 8 + 8 True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False 1 @@ -139,12 +133,11 @@ - 7 + 7 True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False 2 @@ -153,12 +146,11 @@ - B + B True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False 3 @@ -169,12 +161,11 @@ - 6 + 6 True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False 2 @@ -185,12 +176,11 @@ - 5 + 5 True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False 1 @@ -201,12 +191,11 @@ - 4 + 4 True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False 1 @@ -215,12 +204,11 @@ - A + A True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False 3 @@ -229,12 +217,11 @@ - 3 + 3 True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False 2 @@ -243,12 +230,11 @@ - 2 + 2 True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False 1 @@ -257,14 +243,13 @@ - 1 + 1 40 40 True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False diff --git a/gtk/linphone.h b/gtk/linphone.h index a4b87ce25..f337770fb 100644 --- a/gtk/linphone.h +++ b/gtk/linphone.h @@ -21,7 +21,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "config.h" #endif +#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4) +#pragma GCC diagnostic push +#endif +#pragma GCC diagnostic ignored "-Wstrict-prototypes" + #include + +#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4) +#pragma GCC diagnostic pop +#endif + #ifdef WIN32 // alloca is already defined by gtk #undef alloca @@ -31,13 +41,25 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "ldap/ldapprovider.h" #ifdef ENABLE_NLS + +#ifdef _MSC_VER +// prevent libintl.h from re-defining fprintf and vfprintf +#ifndef fprintf +#define fprintf fprintf +#endif +#ifndef vfprintf +#define vfprintf vfprintf +#endif +#define _GL_STDIO_H +#endif + # include # undef _ # define _(String) dgettext (GETTEXT_PACKAGE,String) #else # define _(String) (String) # define ngettext(singular,plural,number) ((number>1) ? (plural) : (singular) ) -#endif +#endif // ENABLE_NLS #undef N_ #define N_(str) (str) @@ -48,7 +70,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define LINPHONE_VERSION LINPHONE_VERSION_DATE #endif +#include "setupwizard.h" + #define LINPHONE_ICON "linphone.png" +#define LINPHONE_ICON_NAME "linphone" enum { COMPLETION_HISTORY, @@ -84,19 +109,19 @@ GtkWidget *_gtk_image_new_from_memory_at_scale(const void *data, gint len, gint GdkPixbuf *_gdk_pixbuf_new_from_memory_at_scale(const void *data, gint len, gint w, gint h, gboolean preserve_ratio); 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_create_window(const char *window_name, GtkWidget *parent); 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); +LINPHONE_PUBLIC GtkWidget *linphone_gtk_create_widget(const char* widget_name); +LINPHONE_PUBLIC GtkWidget *linphone_gtk_make_tab_header(const gchar *label, const gchar *icon_name, gboolean show_quit_button, GCallback cb, gpointer user_data); -const char *linphone_gtk_message_storage_get_db_file(const char *filename); -LINPHONE_PUBLIC void linphone_gtk_show_assistant(void); +char *linphone_gtk_message_storage_get_db_file(const char *filename); +char *linphone_gtk_call_logs_storage_get_db_file(const char *filename); LINPHONE_PUBLIC void linphone_gtk_close_assistant(void); LINPHONE_PUBLIC LinphoneCore *linphone_gtk_get_core(void); -LINPHONE_PUBLIC GtkWidget *linphone_gtk_get_main_window(); +LINPHONE_PUBLIC GtkWidget *linphone_gtk_get_main_window(void); 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_call_terminated(LinphoneCall *call, const char *error); 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); @@ -109,7 +134,7 @@ 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 gboolean linphone_gtk_check_logs(void); 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); @@ -131,27 +156,31 @@ 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); +LINPHONE_PUBLIC void linphone_gtk_notify(LinphoneCall *call, LinphoneChatMessage *chat_message, const char *msg); LINPHONE_PUBLIC void linphone_gtk_load_chatroom(LinphoneChatRoom *cr, const LinphoneAddress *uri, GtkWidget *chat_view); -LINPHONE_PUBLIC void linphone_gtk_send_text(); +LINPHONE_PUBLIC void linphone_gtk_send_text(void); 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); -LINPHONE_PUBLIC void linphone_gtk_friend_list_update_chat_picture(); +LINPHONE_PUBLIC void linphone_gtk_friend_list_update_button_display(GtkTreeView *friendlist); 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 gboolean linphone_gtk_friend_list_enter_event_handler(GtkTreeView *friendlist, GdkEventCrossing *event); +LINPHONE_PUBLIC gboolean linphone_gtk_friend_list_leave_event_handler(GtkTreeView *friendlist, GdkEventCrossing *event); +LINPHONE_PUBLIC gboolean linphone_gtk_friend_list_motion_event_handler(GtkTreeView *friendlist, GdkEventMotion *event); +LINPHONE_PUBLIC void linphone_gtk_friend_list_on_name_column_clicked(GtkTreeModel *model); 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_show_contact(LinphoneFriend *lf, GtkWidget *parent); LINPHONE_PUBLIC void linphone_gtk_buddy_info_updated(LinphoneCore *lc, LinphoneFriend *lf); /*functions controlling the different views*/ -LINPHONE_PUBLIC gboolean linphone_gtk_use_in_call_view(); +LINPHONE_PUBLIC gboolean linphone_gtk_use_in_call_view(void); 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); @@ -171,6 +200,7 @@ 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_in_call_view_hide_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); @@ -179,7 +209,7 @@ LINPHONE_PUBLIC void linphone_gtk_show_login_frame(LinphoneProxyConfig *cfg, gbo LINPHONE_PUBLIC void linphone_gtk_exit_login_frame(void); LINPHONE_PUBLIC void linphone_gtk_set_ui_config(const char *key, const char *value); -LINPHONE_PUBLIC void linphone_gtk_log_uninit(); +LINPHONE_PUBLIC void linphone_gtk_log_uninit(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); @@ -201,22 +231,21 @@ 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 void linphone_gtk_login_frame_connect_clicked(GtkWidget *button, GtkWidget *login_frame); 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_contact_clicked(GtkTreeSelection *selection); 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 gboolean linphone_gtk_contact_list_button_pressed(GtkTreeView* firendlist, 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); @@ -228,6 +257,7 @@ 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_start_chat(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); @@ -238,7 +268,8 @@ 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_show_keypad_checked(GtkCheckMenuItem *check_menu_item); +LINPHONE_PUBLIC gboolean linphone_gtk_keypad_destroyed_handler(void); LINPHONE_PUBLIC void linphone_gtk_keyword_changed(GtkEditable *e); LINPHONE_PUBLIC void linphone_gtk_buddy_lookup_contact_activated(GtkWidget *treeview); @@ -291,17 +322,23 @@ 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_video_preset_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_show_sip_accounts(GtkWidget *w); 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_audio_codec_up(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_audio_codec_down(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_audio_codec_enable(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_audio_codec_disable(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_video_codec_up(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_video_codec_down(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_video_codec_enable(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_video_codec_disable(GtkWidget *button); +LINPHONE_PUBLIC void linphone_gtk_video_framerate_changed(GtkWidget *w); 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); @@ -316,3 +353,10 @@ 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); +LINPHONE_PUBLIC void linphone_gtk_notebook_current_page_changed(GtkNotebook *notebook, GtkWidget *page, guint page_num, gpointer user_data); +LINPHONE_PUBLIC void linphone_gtk_reload_sound_devices(void); +LINPHONE_PUBLIC void linphone_gtk_reload_video_devices(void); +LINPHONE_PUBLIC bool_t linphone_gtk_is_friend(LinphoneCore *lc, const char *contact); +LINPHONE_PUBLIC gboolean linphone_gtk_auto_answer_enabled(void); +LINPHONE_PUBLIC void linphone_gtk_update_status_bar_icons(void); +LINPHONE_PUBLIC void linphone_gtk_enable_auto_answer(GtkToggleButton *checkbox, gpointer user_data); diff --git a/gtk/logging.c b/gtk/logging.c index c91f51138..59a99e0d7 100644 --- a/gtk/logging.c +++ b/gtk/logging.c @@ -57,7 +57,7 @@ static FILE *_logfile = NULL; /* Called on exit, print out the marker, close the file and avoid to continue logging. */ -void linphone_gtk_log_uninit() +void linphone_gtk_log_uninit(void) { if (_logfile != NULL) { fprintf(_logfile, "%s\n", LOGFILE_MARKER_STOP); @@ -70,7 +70,7 @@ void linphone_gtk_log_uninit() perform rotation, insert the start marker and return the pointer to the file that should be used for logging, or NULL on errors or if disabled. */ -static FILE *linphone_gtk_log_init() +static FILE *linphone_gtk_log_init(void) { static char _logdir[1024]; static char _logfname[1024]; @@ -209,7 +209,7 @@ void linphone_gtk_log_hide(void){ void linphone_gtk_create_log_window(void){ GtkTextBuffer *b; - log_window=linphone_gtk_create_window("log"); + log_window=linphone_gtk_create_window("log", NULL); b=gtk_text_view_get_buffer(GTK_TEXT_VIEW(linphone_gtk_get_widget(log_window,"textview"))); gtk_text_buffer_create_tag(b,"red","foreground","red",NULL); gtk_text_buffer_create_tag(b,"orange","foreground","orange",NULL); @@ -302,7 +302,7 @@ void linphone_gtk_log_scroll_to_end(GtkToggleButton *button){ /* * called from Gtk main loop. **/ -gboolean linphone_gtk_check_logs(){ +gboolean linphone_gtk_check_logs(void){ GList *elem; GtkTextView *v=NULL; if (log_window) v=GTK_TEXT_VIEW(linphone_gtk_get_widget(log_window,"textview")); diff --git a/gtk/login_frame.ui b/gtk/login_frame.ui new file mode 100644 index 000000000..f65229f14 --- /dev/null +++ b/gtk/login_frame.ui @@ -0,0 +1,250 @@ + + + + + + False + 0 + etched-out + + + True + False + 12 + + + True + False + + + True + False + gtk-missing-image + + + True + True + 0 + + + + + True + False + 0 + none + + + True + False + 12 + 12 + + + True + False + 5 + 2 + + + + + + True + False + Username + + + + + True + False + Password + + + 1 + 2 + + + + + False + Internet connection: + + + 3 + 4 + + + + + True + True + + True + False + False + True + True + + + 1 + 2 + + + + + True + True + False + + True + False + False + True + True + + + 1 + 2 + 1 + 2 + + + + + False + 0 + + + + 0 + + + + + 1 + 2 + 3 + 4 + + + + + Automatically log me in + True + True + False + True + + + 1 + 2 + 4 + 5 + + + + + False + UserID + + + 2 + 3 + + + + + True + + True + False + False + True + True + + + 1 + 2 + 2 + 3 + + + + + + + + + True + False + Login information + True + + + + + True + True + 10 + 1 + + + + + True + False + + + gtk-connect + True + True + True + True + + + + False + False + 0 + + + + + + + + True + True + 2 + + + + + + + + + True + False + <b>Welcome!</b> + True + + + + + + + + + + + ADSL + + + Fiber Channel + + + + diff --git a/gtk/loginframe.c b/gtk/loginframe.c index 727a746d1..fabd89c67 100644 --- a/gtk/loginframe.c +++ b/gtk/loginframe.c @@ -39,7 +39,7 @@ static gboolean do_login_noprompt(LinphoneProxyConfig *cfg){ linphone_gtk_show_login_frame(cfg,TRUE); return FALSE; } - addr=linphone_address_new(linphone_proxy_config_get_identity(cfg)); + addr=linphone_address_clone(linphone_proxy_config_get_identity_address(cfg)); linphone_address_set_username(addr,username); tmp=linphone_address_as_string (addr); do_login(ssctx,tmp,NULL,NULL); @@ -48,75 +48,94 @@ static gboolean do_login_noprompt(LinphoneProxyConfig *cfg){ return FALSE; } -void linphone_gtk_show_login_frame(LinphoneProxyConfig *cfg, gboolean disable_auto_login){ - GtkWidget *mw=linphone_gtk_get_main_window(); - GtkWidget *label=linphone_gtk_get_widget(mw,"login_label"); - const LinphoneAuthInfo *ai; +static void linphone_gtk_init_login_frame(GtkWidget *login_frame, LinphoneProxyConfig *cfg) { + gboolean auto_login=linphone_gtk_get_ui_config_int("automatic_login",0); + const char *login_image=linphone_gtk_get_ui_config("login_image","linphone-banner.png"); + GtkWidget *label=linphone_gtk_get_widget(login_frame,"login_label"); + LinphoneCore *lc=linphone_gtk_get_core(); gchar *str; LinphoneAddress *from; - LinphoneCore *lc=linphone_gtk_get_core(); + const LinphoneAuthInfo *ai; const char *passwd=NULL; const char *userid=NULL; - gboolean auto_login=linphone_gtk_get_ui_config_int("automatic_login",0); - if (auto_login && !disable_auto_login){ - g_timeout_add(250,(GSourceFunc)do_login_noprompt,cfg); - return; - } - - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(mw,"automatic_login")),auto_login); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(login_frame, "automatic_login")),auto_login); - { - const char *login_image=linphone_gtk_get_ui_config("login_image","linphone-banner.png"); - if (login_image){ - GdkPixbuf *pbuf=create_pixbuf (login_image); - gtk_image_set_from_pixbuf (GTK_IMAGE(linphone_gtk_get_widget(mw,"login_image")), - pbuf); - g_object_unref(G_OBJECT(pbuf)); - } + if (login_image){ + GdkPixbuf *pbuf=create_pixbuf (login_image); + gtk_image_set_from_pixbuf (GTK_IMAGE(linphone_gtk_get_widget(login_frame, "login_image")), pbuf); + g_object_unref(G_OBJECT(pbuf)); } - - gtk_widget_hide(linphone_gtk_get_widget(mw,"disconnect_item")); - gtk_widget_hide(linphone_gtk_get_widget(mw,"main_frame")); - gtk_widget_show(linphone_gtk_get_widget(mw,"login_frame")); + if (linphone_gtk_get_ui_config_int("login_needs_userid",FALSE)){ - gtk_widget_show(linphone_gtk_get_widget(mw,"userid")); - gtk_widget_show(linphone_gtk_get_widget(mw,"login_userid")); + gtk_widget_show(linphone_gtk_get_widget(login_frame,"userid")); + gtk_widget_show(linphone_gtk_get_widget(login_frame,"login_userid")); } - gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"options_menu"),FALSE); + str=g_strdup_printf(_("Please enter login information for %s"),linphone_proxy_config_get_domain(cfg)); gtk_label_set_text(GTK_LABEL(label),str); - g_object_set_data(G_OBJECT(mw),"login_proxy_config",cfg); + g_object_set_data(G_OBJECT(login_frame),"login_proxy_config",cfg); g_free(str); - + from=linphone_address_new(linphone_proxy_config_get_identity(cfg)); if (linphone_address_get_username(from)[0]=='?'){ const char *username=linphone_gtk_get_ui_config ("login_username",NULL); if (username) linphone_address_set_username(from,username); } - + ai=linphone_core_find_auth_info(lc,linphone_proxy_config_get_domain(cfg),linphone_address_get_username(from),NULL); /*display the last entered username, if not '?????'*/ if (linphone_address_get_username(from)[0]!='?') - gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(mw,"login_username")), + gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(login_frame,"login_username")), linphone_address_get_username(from)); if (ai) { passwd=linphone_auth_info_get_passwd(ai); userid=linphone_auth_info_get_userid(ai); } - gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(mw,"login_password")), + gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(login_frame,"login_password")), passwd!=NULL ? passwd : ""); - gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(mw,"login_userid")), + gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(login_frame,"login_userid")), userid ? userid : ""); - + linphone_address_destroy(from); } +void linphone_gtk_show_login_frame(LinphoneProxyConfig *cfg, gboolean disable_auto_login){ + GtkWidget *mw=linphone_gtk_get_main_window(); + gboolean auto_login=linphone_gtk_get_ui_config_int("automatic_login",0); + GtkWidget *main_frame = linphone_gtk_get_widget(mw, "main_frame"); + GtkWidget *main_layout = linphone_gtk_get_widget(mw, "main_layout"); + GtkWidget *login_frame; + + if (auto_login && !disable_auto_login){ + g_timeout_add(250,(GSourceFunc)do_login_noprompt,cfg); + return; + } + + login_frame = linphone_gtk_create_widget("login_frame"); + linphone_gtk_init_login_frame(login_frame, cfg); + g_object_set_data_full(G_OBJECT(mw), "main_frame", g_object_ref(main_frame), g_object_unref); + g_object_set_data(G_OBJECT(mw), "login_frame", login_frame); + gtk_container_remove(GTK_CONTAINER(main_layout), main_frame); + gtk_box_pack_start(GTK_BOX(main_layout), login_frame, TRUE, TRUE, 0); + gtk_widget_show(login_frame); + + gtk_widget_hide(linphone_gtk_get_widget(mw,"disconnect_item")); + gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"options_menu"),FALSE); +} + void linphone_gtk_exit_login_frame(void){ GtkWidget *mw=linphone_gtk_get_main_window(); - gtk_widget_show(linphone_gtk_get_widget(mw,"main_frame")); - gtk_widget_hide(linphone_gtk_get_widget(mw,"login_frame")); + GtkWidget *main_layout = linphone_gtk_get_widget(mw, "main_layout"); + GtkWidget *main_frame = GTK_WIDGET(g_object_get_data(G_OBJECT(mw), "main_frame")); + GtkWidget *login_frame = GTK_WIDGET(g_object_get_data(G_OBJECT(mw), "login_frame")); + + gtk_container_remove(GTK_CONTAINER(main_layout), login_frame); + gtk_box_pack_start(GTK_BOX(main_layout), main_frame, TRUE, TRUE, 0); + g_object_set_data(G_OBJECT(mw), "login_frame", NULL); + g_object_set_data(G_OBJECT(mw), "main_frame", NULL); + gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"options_menu"),TRUE); gtk_widget_show(linphone_gtk_get_widget(mw,"disconnect_item")); } @@ -124,7 +143,7 @@ void linphone_gtk_exit_login_frame(void){ void linphone_gtk_logout_clicked(void){ LinphoneCore *lc=linphone_gtk_get_core(); LinphoneProxyConfig *cfg=NULL; - linphone_core_get_default_proxy(lc,&cfg); + cfg = linphone_core_get_default_proxy_config(lc); if (cfg){ SipSetupContext *ss=linphone_proxy_config_get_sip_setup_context(cfg); if (ss){ @@ -136,25 +155,24 @@ void linphone_gtk_logout_clicked(void){ -void linphone_gtk_login_frame_connect_clicked(GtkWidget *button){ - GtkWidget *mw=gtk_widget_get_toplevel(button); +void linphone_gtk_login_frame_connect_clicked(GtkWidget *button, GtkWidget *login_frame){ const char *username; const char *password; const char *userid; char *identity; gboolean autologin; - LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)g_object_get_data(G_OBJECT(mw),"login_proxy_config"); + LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)g_object_get_data(G_OBJECT(login_frame),"login_proxy_config"); LinphoneAddress *from; SipSetupContext *ssctx=linphone_proxy_config_get_sip_setup_context(cfg); - username=gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(mw,"login_username"))); - password=gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(mw,"login_password"))); - userid=gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(mw,"login_userid"))); - + username=gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(login_frame,"login_username"))); + password=gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(login_frame,"login_password"))); + userid=gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(login_frame,"login_userid"))); + if (username==NULL || username[0]=='\0') return; - autologin=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(mw,"automatic_login"))); + autologin=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(login_frame,"automatic_login"))); linphone_gtk_set_ui_config_int("automatic_login",autologin); linphone_gtk_set_ui_config("login_username",username); diff --git a/gtk/main.c b/gtk/main.c index c73c57ec2..ba91fd3b3 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -69,11 +69,7 @@ static void linphone_gtk_registration_state_changed(LinphoneCore *lc, LinphonePr static void linphone_gtk_notify_recv(LinphoneCore *lc, LinphoneFriend * fid); static void linphone_gtk_new_unknown_subscriber(LinphoneCore *lc, LinphoneFriend *lf, const char *url); static void linphone_gtk_auth_info_requested(LinphoneCore *lc, const char *realm, const char *username, const char *domain); -static void linphone_gtk_display_status(LinphoneCore *lc, const char *status); static void linphone_gtk_configuring_status(LinphoneCore *lc, LinphoneConfiguringState status, const char *message); -static void linphone_gtk_display_message(LinphoneCore *lc, const char *msg); -static void linphone_gtk_display_warning(LinphoneCore *lc, const char *warning); -static void linphone_gtk_display_url(LinphoneCore *lc, const char *msg, const char *url); static void linphone_gtk_call_log_updated(LinphoneCore *lc, LinphoneCallLog *cl); static void linphone_gtk_call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cs, const char *msg); static void linphone_gtk_call_encryption_changed(LinphoneCore *lc, LinphoneCall *call, bool_t enabled, const char *token); @@ -98,6 +94,7 @@ static int start_option = START_LINPHONE; static gboolean no_video=FALSE; static gboolean iconified=FALSE; static gboolean run_audio_assistant=FALSE; +static gboolean version=FALSE; static gboolean selftest=FALSE; static gchar *workingdir=NULL; static char *progpath=NULL; @@ -135,6 +132,7 @@ static GtkWidget *config_fetching_dialog=NULL; static GOptionEntry linphone_options[]={ LINPHONE_OPTION("verbose", '\0', G_OPTION_ARG_NONE, (gpointer)&verbose, N_("log to stdout some debug information while running.")), + LINPHONE_OPTION("version", '\0', G_OPTION_ARG_NONE, (gpointer)&version, N_("display version and exit.")), 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.")), @@ -164,10 +162,7 @@ char *linphone_gtk_get_config_file(const char *filename){ const int path_max=1024; char *config_file=g_malloc0(path_max); if (filename==NULL) filename=CONFIG_FILE; - /*try accessing a local file first if exists*/ - if (access(CONFIG_FILE,F_OK)==0){ - snprintf(config_file,path_max,"%s",filename); - } else if (g_path_is_absolute(filename)) { + if (g_path_is_absolute(filename)) { snprintf(config_file,path_max,"%s",filename); } else{ #ifdef WIN32 @@ -188,11 +183,11 @@ char *linphone_gtk_get_config_file(const char *filename){ #define FACTORY_CONFIG_FILE "linphonerc.factory" static char _factory_config_file[1024]; -static const char *linphone_gtk_get_factory_config_file(){ +static const char *linphone_gtk_get_factory_config_file(void){ + char* path = NULL; /*try accessing a local file first if exists*/ if (access(FACTORY_CONFIG_FILE,F_OK)==0){ - snprintf(_factory_config_file,sizeof(_factory_config_file), - "%s",FACTORY_CONFIG_FILE); + path = ms_strdup(FACTORY_CONFIG_FILE); } else { char *progdir; @@ -204,33 +199,31 @@ static const char *linphone_gtk_get_factory_config_file(){ if (basename != NULL) { basename ++; *basename = '\0'; - snprintf(_factory_config_file, sizeof(_factory_config_file), - "%s\\..\\%s", progdir, FACTORY_CONFIG_FILE); - } else { - if (workingdir!=NULL) { - snprintf(_factory_config_file, sizeof(_factory_config_file), - "%s\\%s", workingdir, FACTORY_CONFIG_FILE); - } else { - free(progdir); - return NULL; - } + path = ms_strdup_printf("%s\\..\\%s", progdir, FACTORY_CONFIG_FILE); + } else if (workingdir!=NULL) { + path = ms_strdup_printf("%s\\%s", workingdir, FACTORY_CONFIG_FILE); } #else basename = strrchr(progdir, '/'); if (basename != NULL) { basename ++; *basename = '\0'; - snprintf(_factory_config_file, sizeof(_factory_config_file), - "%s/../share/linphone/%s", progdir, FACTORY_CONFIG_FILE); - } else { - free(progdir); - return NULL; + path = ms_strdup_printf("%s/../share/linphone/%s", progdir, FACTORY_CONFIG_FILE); } #endif free(progdir); } } - return _factory_config_file; + if (path) { + //use factory file only if it exists + if (access(path,F_OK)==0){ + snprintf(_factory_config_file, sizeof(_factory_config_file), "%s", path); + ms_free(path); + return _factory_config_file; + } + ms_free(path); + } + return NULL; } LinphoneLDAPContactProvider* linphone_gtk_get_ldap(void){ @@ -259,7 +252,7 @@ gboolean linphone_gtk_get_audio_assistant_option(void){ } static void linphone_gtk_init_liblinphone(const char *config_file, - const char *factory_config_file, const char *db_file) { + const char *factory_config_file, const char *chat_messages_db_file, const char *call_logs_db_file) { LinphoneCoreVTable vtable={0}; gchar *secrets_file=linphone_gtk_get_config_file(SECRETS_FILE); gchar *user_certificates_dir=linphone_gtk_get_config_file(CERTIFICATES_PATH); @@ -270,12 +263,7 @@ static void linphone_gtk_init_liblinphone(const char *config_file, vtable.notify_presence_received=linphone_gtk_notify_recv; vtable.new_subscription_requested=linphone_gtk_new_unknown_subscriber; vtable.auth_info_requested=linphone_gtk_auth_info_requested; - vtable.display_status=linphone_gtk_display_status; - vtable.display_message=linphone_gtk_display_message; - vtable.display_warning=linphone_gtk_display_warning; - vtable.display_url=linphone_gtk_display_url; vtable.call_log_updated=linphone_gtk_call_log_updated; - //vtable.text_received=linphone_gtk_text_received; vtable.message_received=linphone_gtk_text_received; vtable.is_composing_received=linphone_gtk_is_composing_received; vtable.refer_received=linphone_gtk_refer_received; @@ -304,29 +292,29 @@ static void linphone_gtk_init_liblinphone(const char *config_file, g_free(user_certificates_dir); linphone_core_enable_video_capture(the_core, TRUE); linphone_core_enable_video_display(the_core, TRUE); - linphone_core_set_native_video_window_id(the_core,-1);/*don't create the window*/ + linphone_core_set_native_video_window_id(the_core,LINPHONE_VIDEO_DISPLAY_NONE);/*don't create the window*/ if (no_video) { _linphone_gtk_enable_video(FALSE); linphone_gtk_set_ui_config_int("videoselfview",0); } - if (db_file) linphone_core_set_chat_database_path(the_core,db_file); + if (chat_messages_db_file) linphone_core_set_chat_database_path(the_core,chat_messages_db_file); + if (call_logs_db_file) linphone_core_set_call_logs_database_path(the_core, call_logs_db_file); } LinphoneCore *linphone_gtk_get_core(void){ return the_core; } -GtkWidget *linphone_gtk_get_main_window(){ +GtkWidget *linphone_gtk_get_main_window(void){ return the_ui; } -void linphone_gtk_destroy_main_window() { +void linphone_gtk_destroy_main_window(void) { linphone_gtk_destroy_window(the_ui); the_ui = NULL; } static void linphone_gtk_configure_window(GtkWidget *w, const char *window_name){ - static const char *icon_path=NULL; static const char *hiddens=NULL; static const char *shown=NULL; static bool_t config_loaded=FALSE; @@ -334,28 +322,10 @@ static void linphone_gtk_configure_window(GtkWidget *w, const char *window_name) if (config_loaded==FALSE){ hiddens=linphone_gtk_get_ui_config("hidden_widgets",NULL); shown=linphone_gtk_get_ui_config("shown_widgets",NULL); - icon_path=linphone_gtk_get_ui_config("icon",LINPHONE_ICON); config_loaded=TRUE; } - if (hiddens) - linphone_gtk_visibility_set(hiddens,window_name,w,FALSE); - if (shown) - linphone_gtk_visibility_set(shown,window_name,w,TRUE); - if (icon_path) { - GdkPixbuf *pbuf=create_pixbuf(icon_path); - if(pbuf) { - GList *pbuf_list = NULL; - GdkPixbuf *pbuf_16=gdk_pixbuf_scale_simple(pbuf, 16, 16, GDK_INTERP_BILINEAR); - GdkPixbuf *pbuf_32=gdk_pixbuf_scale_simple(pbuf, 32, 32, GDK_INTERP_BILINEAR); - pbuf_list = g_list_append(pbuf_list, pbuf); - pbuf_list = g_list_append(pbuf_list, pbuf_16); - pbuf_list = g_list_append(pbuf_list, pbuf_32); - gtk_window_set_icon_list(GTK_WINDOW(w), pbuf_list); - gtk_window_set_default_icon_list(pbuf_list); - g_list_foreach(pbuf_list, (GFunc)g_object_unref,NULL); - g_list_free(pbuf_list); - } - } + if (hiddens) linphone_gtk_visibility_set(hiddens,window_name,w,FALSE); + if (shown) linphone_gtk_visibility_set(shown,window_name,w,TRUE); } static int get_ui_file(const char *name, char *path, int pathsize){ @@ -377,60 +347,47 @@ void linphone_gtk_destroy_window(GtkWidget *widget) { g_object_unref (G_OBJECT (builder)); } -GtkWidget *linphone_gtk_create_window(const char *window_name){ - GError* error = NULL; - GtkBuilder* builder = gtk_builder_new (); - char path[512]; - GtkWidget *w; +GtkWidget *linphone_gtk_create_widget(const char *widget_name) { + char path[2048]; + GtkBuilder *builder = gtk_builder_new(); + GError *error = NULL; + GObject *obj; - if (get_ui_file(window_name,path,sizeof(path))==-1) return NULL; + if(get_ui_file(widget_name, path, sizeof(path)) == -1) goto fail; - gtk_builder_set_translation_domain(builder,GETTEXT_PACKAGE); + gtk_builder_set_translation_domain(builder, GETTEXT_PACKAGE); - if (!gtk_builder_add_from_file (builder, path, &error)){ + if(gtk_builder_add_from_file(builder, path, &error) == 0) { g_error("Couldn't load builder file: %s", error->message); - g_error_free (error); - return NULL; + g_error_free(error); + goto fail; } - w=GTK_WIDGET(gtk_builder_get_object (builder,window_name)); - if (w==NULL){ - g_error("Could not retrieve '%s' window from xml file",window_name); - return NULL; + + obj = gtk_builder_get_object(builder, widget_name); + if(obj == NULL) { + g_error("'%s' widget not found", widget_name); + goto fail; } - g_object_set_data(G_OBJECT(w), "builder",builder); - gtk_builder_connect_signals(builder,w); - linphone_gtk_configure_window(w,window_name); - return w; + g_object_set_data(G_OBJECT(obj), "builder", builder); + g_signal_connect_data(G_OBJECT(obj),"destroy",(GCallback)g_object_unref,builder, NULL, G_CONNECT_AFTER|G_CONNECT_SWAPPED); + gtk_builder_connect_signals(builder, obj); + + return GTK_WIDGET(obj); + +fail: + g_object_unref(builder); + return NULL; } -GtkWidget *linphone_gtk_create_widget(const char *filename, const char *widget_name){ - char path[2048]; - GtkWidget *w; - GtkBuilder* builder = gtk_builder_new (); - GError *error=NULL; - gchar *object_ids[2]; - object_ids[0]=g_strdup(widget_name); - object_ids[1]=NULL; - - if (get_ui_file(filename,path,sizeof(path))==-1) return NULL; - - gtk_builder_set_translation_domain(builder,GETTEXT_PACKAGE); - - if (!gtk_builder_add_objects_from_file(builder,path,object_ids,&error)){ - g_error("Couldn't load %s from builder file %s: %s", widget_name,path,error->message); - g_error_free (error); - g_free(object_ids[0]); - return NULL; +GtkWidget *linphone_gtk_create_window(const char *window_name, GtkWidget *parent){ + GtkWidget *w = linphone_gtk_create_widget(window_name); + if(w) { + linphone_gtk_configure_window(w,window_name); + if(parent) { + gtk_window_set_transient_for(GTK_WINDOW(w), GTK_WINDOW(parent)); + gtk_window_set_position(GTK_WINDOW(w), GTK_WIN_POS_CENTER_ON_PARENT); + } } - g_free(object_ids[0]); - w=GTK_WIDGET(gtk_builder_get_object (builder,widget_name)); - if (w==NULL){ - g_error("Could not retrieve '%s' window from xml file",widget_name); - return NULL; - } - g_object_set_data(G_OBJECT(w),"builder",builder); - g_signal_connect_swapped(G_OBJECT(w),"destroy",(GCallback)g_object_unref,builder); - gtk_builder_connect_signals(builder,w); return w; } @@ -475,16 +432,16 @@ void linphone_gtk_display_something(GtkMessageType type,const gchar *message){ /* draw a question box. link to dialog_click callback */ dialog = gtk_message_dialog_new ( GTK_WINDOW(main_window), - GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, - GTK_BUTTONS_YES_NO, - "%s", + GTK_BUTTONS_YES_NO, + "%s", (const gchar*)message); /* connect to some callback : REVISIT */ /* g_signal_connect_swapped (G_OBJECT (dialog), "response", - G_CALLBACK (dialog_click), - G_OBJECT (dialog)); + G_CALLBACK (dialog_click), + G_OBJECT (dialog)); */ /* actually show the box */ gtk_widget_show(dialog); @@ -492,15 +449,15 @@ void linphone_gtk_display_something(GtkMessageType type,const gchar *message){ else { dialog = gtk_message_dialog_new (GTK_WINDOW(main_window), - GTK_DIALOG_DESTROY_WITH_PARENT, - type, - GTK_BUTTONS_CLOSE, - "%s", - (const gchar*)message); + GTK_DIALOG_DESTROY_WITH_PARENT, + type, + GTK_BUTTONS_CLOSE, + "%s", + (const gchar*)message); /* Destroy the dialog when the user responds to it (e.g. clicks a button) */ g_signal_connect_swapped (G_OBJECT (dialog), "response", - G_CALLBACK (gtk_widget_destroy), - G_OBJECT (dialog)); + G_CALLBACK (gtk_widget_destroy), + G_OBJECT (dialog)); gtk_widget_show(dialog); } } @@ -522,11 +479,13 @@ void linphone_gtk_show_about(void){ GtkWidget *about; const char *tmp; GdkPixbuf *logo=create_pixbuf( - linphone_gtk_get_ui_config("logo","linphone-banner.png")); + linphone_gtk_get_ui_config("logo","linphone-banner.png")); static const char *defcfg="defcfg"; - about=linphone_gtk_create_window("about"); + about=linphone_gtk_create_window("about", the_ui); + gtk_about_dialog_set_url_hook(about_url_clicked,NULL,NULL); + memset(&filestat,0,sizeof(filestat)); if (stat(license_file,&filestat)!=0){ license_file="COPYING"; @@ -582,8 +541,7 @@ static gboolean linphone_gtk_iterate(LinphoneCore *lc){ if (addr_to_call!=NULL){ /*make sure we are not showing the login screen*/ GtkWidget *mw=linphone_gtk_get_main_window(); - GtkWidget *login_frame=linphone_gtk_get_widget(mw,"login_frame"); - if (!GTK_WIDGET_VISIBLE(login_frame)){ + if (g_object_get_data(G_OBJECT(mw), "login_frame") == NULL){ GtkWidget *uri_bar=linphone_gtk_get_widget(mw,"uribar"); gtk_entry_set_text(GTK_ENTRY(uri_bar),addr_to_call); addr_to_call=NULL; @@ -597,23 +555,19 @@ static gboolean linphone_gtk_iterate(LinphoneCore *lc){ static gboolean uribar_completion_matchfunc(GtkEntryCompletion *completion, const gchar *key, GtkTreeIter *iter, gpointer user_data){ char* address = NULL; gboolean ret = FALSE; - gchar *tmp= NULL; gtk_tree_model_get(gtk_entry_completion_get_model(completion),iter,0,&address,-1); - tmp = g_utf8_casefold(address,-1); - if (tmp){ - if (strstr(tmp,key)) - ret=TRUE; + if(address) { + gchar *tmp = g_utf8_casefold(address,-1); + if (strstr(tmp,key)) ret=TRUE; g_free(tmp); - } - - if( address) g_free(address); + } return ret; } -static void load_uri_history(){ +static void load_uri_history(void){ GtkEntry *uribar=GTK_ENTRY(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"uribar")); char key[20]; int i; @@ -640,7 +594,7 @@ static void load_uri_history(){ g_signal_connect (G_OBJECT (uribar), "changed", G_CALLBACK(linphone_gtk_on_uribar_changed), NULL); } -static void save_uri_history(){ +static void save_uri_history(void){ LinphoneCore *lc=linphone_gtk_get_core(); LpConfig *cfg=linphone_core_get_config(lc); GtkEntry *uribar=GTK_ENTRY(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"uribar")); @@ -815,6 +769,12 @@ bool_t linphone_gtk_video_enabled(void){ void linphone_gtk_show_main_window(){ GtkWidget *w=linphone_gtk_get_main_window(); +#ifdef HAVE_GTK_OSX + GtkWidget *icon = linphone_gtk_get_widget(w, "history_tab_icon"); + GtkWidget *label = linphone_gtk_get_widget(w, "history_tab_label"); + gtk_misc_set_alignment(GTK_MISC(icon), 0.5f, 0.25f); + gtk_misc_set_alignment(GTK_MISC(label), 0.5f, 0.f); +#endif gtk_widget_show(w); gtk_window_present(GTK_WINDOW(w)); } @@ -822,7 +782,7 @@ void linphone_gtk_show_main_window(){ void linphone_gtk_call_terminated(LinphoneCall *call, const char *error){ GtkWidget *mw=linphone_gtk_get_main_window(); if (linphone_core_get_calls(linphone_gtk_get_core())==NULL){ - gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"start_call"),TRUE); + gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"start_call"),TRUE); } if (linphone_gtk_use_in_call_view() && call) linphone_gtk_in_call_view_terminate(call,error); @@ -833,29 +793,20 @@ static void linphone_gtk_update_call_buttons(LinphoneCall *call){ GtkWidget *mw=linphone_gtk_get_main_window(); const MSList *calls=linphone_core_get_calls(lc); GtkWidget *button; - bool_t start_active=TRUE; - //bool_t stop_active=FALSE; - bool_t add_call=FALSE; + bool_t add_call=(calls!=NULL); int call_list_size=ms_list_size(calls); GtkWidget *conf_frame; - if (calls==NULL){ - start_active=TRUE; - //stop_active=FALSE; - }else{ - //stop_active=TRUE; - start_active=TRUE; - add_call=TRUE; - } button=linphone_gtk_get_widget(mw,"start_call"); - gtk_widget_set_sensitive(button,start_active); + gtk_widget_set_sensitive(button,TRUE); gtk_widget_set_visible(button,!add_call); button=linphone_gtk_get_widget(mw,"add_call"); + if (linphone_core_sound_resources_locked(lc) || (call && linphone_call_get_state(call)==LinphoneCallIncomingReceived)) { gtk_widget_set_sensitive(button,FALSE); } else { - gtk_widget_set_sensitive(button,start_active); + gtk_widget_set_sensitive(button,TRUE); } gtk_widget_set_visible(button,add_call); @@ -924,7 +875,7 @@ static gboolean linphone_gtk_start_call_do(GtkWidget *uri_bar){ LinphoneAddress *addr=linphone_core_interpret_url(lc,entered); if (addr!=NULL){ - LinphoneCallParams *params=linphone_core_create_default_call_parameters(lc); + LinphoneCallParams *params=linphone_core_create_call_params(lc, NULL); gchar *record_file=linphone_gtk_get_record_path(addr,FALSE); linphone_call_params_set_record_file(params,record_file); linphone_core_invite_address_with_params(lc,addr,params); @@ -941,7 +892,7 @@ static gboolean linphone_gtk_start_call_do(GtkWidget *uri_bar){ static void accept_incoming_call(LinphoneCall *call){ LinphoneCore *lc=linphone_gtk_get_core(); - LinphoneCallParams *params=linphone_core_create_default_call_parameters(lc); + LinphoneCallParams *params = linphone_core_create_call_params(lc, call); gchar *record_file=linphone_gtk_get_record_path(linphone_call_get_remote_address(call),FALSE); linphone_call_params_set_record_file(params,record_file); linphone_core_accept_call_with_params(lc,call,params); @@ -974,6 +925,18 @@ void linphone_gtk_start_call(GtkWidget *w){ } +void linphone_gtk_start_chat(GtkWidget *w){ + GtkWidget *mw=gtk_widget_get_toplevel(w); + GtkWidget *uri_bar=linphone_gtk_get_widget(mw,"uribar"); + const char *entered=gtk_entry_get_text(GTK_ENTRY(uri_bar)); + LinphoneCore *lc=linphone_gtk_get_core(); + LinphoneAddress *addr=linphone_core_interpret_url(lc,entered); + if (addr) { + linphone_gtk_friend_list_set_chat_conversation(addr); + linphone_address_destroy(addr); + } +} + void linphone_gtk_uri_bar_activate(GtkWidget *w){ linphone_gtk_start_call(w); } @@ -1051,7 +1014,7 @@ static void linphone_gtk_notify_recv(LinphoneCore *lc, LinphoneFriend * fid){ static void linphone_gtk_new_subscriber_response(GtkWidget *dialog, guint response_id, LinphoneFriend *lf){ switch(response_id){ case GTK_RESPONSE_YES: - linphone_gtk_show_contact(lf); + linphone_gtk_show_contact(lf, the_ui); break; default: linphone_core_reject_subscriber(linphone_gtk_get_core(),lf); @@ -1068,13 +1031,13 @@ static void linphone_gtk_new_unknown_subscriber(LinphoneCore *lc, LinphoneFriend return; } - message=g_strdup_printf(_("%s would like to add you to his contact list.\nWould you allow him to see your presence status or add him to your contact list ?\nIf you answer no, this person will be temporarily blacklisted."),url); + message=g_strdup_printf(_("%s would like to add you to his/her contact list.\nWould you add him/her to your contact list and allow him/her to see your presence status?\nIf you answer no, this person will be temporarily blacklisted."),url); dialog = gtk_message_dialog_new ( GTK_WINDOW(linphone_gtk_get_main_window()), - GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, - GTK_BUTTONS_YES_NO, - "%s", + GTK_BUTTONS_YES_NO, + "%s", message); g_free(message); g_signal_connect(G_OBJECT (dialog), "response", @@ -1133,13 +1096,13 @@ void linphone_gtk_password_ok(GtkWidget *w){ } static void linphone_gtk_auth_info_requested(LinphoneCore *lc, const char *realm, const char *username, const char *domain){ - GtkWidget *w=linphone_gtk_create_window("password"); + GtkWidget *w=linphone_gtk_create_window("password", the_ui); GtkWidget *label=linphone_gtk_get_widget(w,"message"); LinphoneAuthInfo *info; gchar *msg; GtkWidget *mw=linphone_gtk_get_main_window(); - if (mw && GTK_WIDGET_VISIBLE(linphone_gtk_get_widget(mw,"login_frame"))){ + if (mw && g_object_get_data(G_OBJECT(mw), "login_frame") != NULL){ /*don't prompt for authentication when login frame is visible*/ linphone_core_abort_authentication(lc,NULL); return; @@ -1161,34 +1124,12 @@ static void linphone_gtk_dtmf_received(LinphoneCore *lc, LinphoneCall *call, int ms_message("Dtmf %c received.",dtmf); } -static void linphone_gtk_display_status(LinphoneCore *lc, const char *status){ - GtkWidget *w=linphone_gtk_get_main_window(); - GtkWidget *status_bar=linphone_gtk_get_widget(w,"status_bar"); - - gtk_statusbar_push(GTK_STATUSBAR(status_bar), - gtk_statusbar_get_context_id(GTK_STATUSBAR(status_bar),""), - status); -} static void linphone_gtk_configuring_status(LinphoneCore *lc, LinphoneConfiguringState status, const char *message) { if (config_fetching_dialog) linphone_gtk_close_config_fetching(config_fetching_dialog, status); config_fetching_dialog=NULL; } -static void linphone_gtk_display_message(LinphoneCore *lc, const char *msg){ - linphone_gtk_display_something(GTK_MESSAGE_INFO,msg); -} - -static void linphone_gtk_display_warning(LinphoneCore *lc, const char *warning){ - linphone_gtk_display_something(GTK_MESSAGE_WARNING,warning); -} - -static void linphone_gtk_display_url(LinphoneCore *lc, const char *msg, const char *url){ - char richtext[4096]; - snprintf(richtext,sizeof(richtext),"%s %s",msg,url); - linphone_gtk_display_something(GTK_MESSAGE_INFO,richtext); -} - static void linphone_gtk_call_log_updated(LinphoneCore *lc, LinphoneCallLog *cl){ GtkWidget *w=(GtkWidget*)g_object_get_data(G_OBJECT(linphone_gtk_get_main_window()),"call_logs"); if (w) linphone_gtk_call_log_update(w); @@ -1196,7 +1137,7 @@ static void linphone_gtk_call_log_updated(LinphoneCore *lc, LinphoneCallLog *cl) } #ifdef HAVE_NOTIFY -static bool_t notify_actions_supported() { +static bool_t notify_actions_supported(void) { bool_t accepts_actions = FALSE; GList *capabilities = notify_get_server_caps(); GList *c; @@ -1221,10 +1162,14 @@ static NotifyNotification* build_notification(const char *title, const char *bod ); #ifndef HAVE_NOTIFY1 { - const char *icon_path = linphone_gtk_get_ui_config("icon", LINPHONE_ICON); - GdkPixbuf *pbuf = create_pixbuf(icon_path); - /*with notify1, this function makes the notification crash the app with obscure dbus glib critical errors*/ - notify_notification_set_icon_from_pixbuf(n, pbuf); + GError *error = NULL; + const char *icon_name = linphone_gtk_get_ui_config("icon_name", LINPHONE_ICON_NAME); + GdkPixbuf *pbuf = gtk_icon_theme_load_icon(gtk_icon_theme_get_default(), icon_name, 48, 0, &error); + if(error) { + g_warning("Could not load '%s' icon: %s", icon_name, error->message); + g_error_free(error); + } + notify_notification_set_image_from_pixbuf(n, pbuf); } #endif return n; @@ -1241,25 +1186,31 @@ static void make_notification(const char *title, const char *body){ #endif -void linphone_gtk_notify(LinphoneCall *call, const char *msg){ +void linphone_gtk_notify(LinphoneCall *call, LinphoneChatMessage *chat_message, const char *msg){ #ifdef HAVE_NOTIFY if (!notify_is_initted()) if (!notify_init ("Linphone")) ms_error("Libnotify failed to init."); #endif if (!call) { - #ifdef HAVE_NOTIFY - if (!notify_notification_show(notify_notification_new("Linphone",msg,NULL + if (chat_message) { + const LinphoneAddress *address = linphone_chat_message_get_peer_address(chat_message); + char *remote = linphone_address_as_string(address); + make_notification(remote, linphone_chat_message_get_text(chat_message)); + } else { + if (!notify_notification_show(notify_notification_new("Linphone",msg,NULL #ifdef HAVE_NOTIFY1 - ,NULL + ,NULL #endif -),NULL)) - + ),NULL)) { ms_error("Failed to send notification."); + } + } #else linphone_gtk_show_main_window(); #endif } else if (!gtk_window_is_active((GtkWindow*)linphone_gtk_get_main_window())) { + gboolean show_main_window = FALSE; #ifdef HAVE_NOTIFY char *body=NULL; char *remote=call!=NULL ? linphone_call_get_remote_address_as_string(call) : NULL; @@ -1273,13 +1224,15 @@ void linphone_gtk_notify(LinphoneCall *call, const char *msg){ break; case LinphoneCallIncomingReceived: n=build_notification(_("Incoming call"),body=g_markup_printf_escaped("%s",remote)); - if (notify_actions_supported()) { - notify_notification_add_action (n,"answer", _("Answer"), - NOTIFY_ACTION_CALLBACK(linphone_gtk_answer_clicked),NULL,NULL); - notify_notification_add_action (n,"decline",_("Decline"), - NOTIFY_ACTION_CALLBACK(linphone_gtk_decline_clicked),NULL,NULL); - } - show_notification(n); + if (n){ + if (notify_actions_supported()) { + notify_notification_add_action (n,"answer", _("Answer"), + NOTIFY_ACTION_CALLBACK(linphone_gtk_answer_clicked),NULL,NULL); + notify_notification_add_action (n,"decline",_("Decline"), + NOTIFY_ACTION_CALLBACK(linphone_gtk_decline_clicked),NULL,NULL); + } + show_notification(n); + }else show_main_window = TRUE; break; case LinphoneCallPausedByRemote: make_notification(_("Call paused"),body=g_markup_printf_escaped(_("by %s"),remote)); @@ -1289,7 +1242,11 @@ void linphone_gtk_notify(LinphoneCall *call, const char *msg){ } if (body) g_free(body); if (remote) g_free(remote); +#else + if (linphone_call_get_state(call) == LinphoneCallIncomingReceived) + show_main_window = TRUE; #endif + if (show_main_window) linphone_gtk_show_main_window(); } } @@ -1339,7 +1296,7 @@ static void linphone_gtk_call_updated_by_remote(LinphoneCall *call){ gboolean video_requested=linphone_call_params_video_enabled(rparams); gboolean video_used=linphone_call_params_video_enabled(current_params); g_message("Video used=%i, video requested=%i, automatically_accept=%i", - video_used,video_requested,pol->automatically_accept); + video_used,video_requested,pol->automatically_accept); if (!video_used && video_requested && !pol->automatically_accept){ linphone_core_defer_call_update(lc,call); { @@ -1349,13 +1306,13 @@ static void linphone_gtk_call_updated_by_remote(LinphoneCall *call){ if (dname==NULL) dname=linphone_address_get_username(addr); if (dname==NULL) dname=linphone_address_get_domain(addr); dialog=gtk_message_dialog_new(GTK_WINDOW(linphone_gtk_get_main_window()), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_WARNING, - GTK_BUTTONS_YES_NO, - _("%s proposed to start video. Do you accept ?"),dname); + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_WARNING, + GTK_BUTTONS_YES_NO, + _("%s proposed to start video. Do you accept ?"),dname); g_object_set_data_full(G_OBJECT(dialog), "call", linphone_call_ref(call), (GDestroyNotify)linphone_call_unref); - g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(on_call_updated_response), NULL); - g_timeout_add(20000,(GSourceFunc)on_call_updated_timeout,dialog); + g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(on_call_updated_response), NULL); + g_timeout_add(20000,(GSourceFunc)on_call_updated_timeout,dialog); gtk_widget_show(dialog); } } @@ -1386,7 +1343,7 @@ static void linphone_gtk_call_state_changed(LinphoneCore *lc, LinphoneCall *call linphone_gtk_create_in_call_view(call); linphone_gtk_in_call_view_set_incoming(call); linphone_gtk_status_icon_set_blinking(TRUE); - if (linphone_gtk_get_ui_config_int("auto_answer", 0)) { + if (linphone_gtk_auto_answer_enabled()) { int delay = linphone_gtk_get_ui_config_int("auto_answer_delay", 2000); linphone_call_ref(call); g_timeout_add(delay, (GSourceFunc)linphone_gtk_auto_answer, call); @@ -1410,7 +1367,7 @@ static void linphone_gtk_call_state_changed(LinphoneCore *lc, LinphoneCall *call default: break; } - linphone_gtk_notify(call, msg); + linphone_gtk_notify(call, NULL, msg); linphone_gtk_update_call_buttons (call); } @@ -1427,7 +1384,7 @@ static void update_registration_status(LinphoneProxyConfig *cfg, LinphoneRegistr GtkTreeModel *model=gtk_combo_box_get_model(box); GtkTreeIter iter; gboolean found=FALSE; - const char *stock_id=NULL; + const char *icon_name=NULL; if (gtk_tree_model_get_iter_first(model,&iter)){ gpointer p; @@ -1445,25 +1402,25 @@ static void update_registration_status(LinphoneProxyConfig *cfg, LinphoneRegistr } switch (rs){ case LinphoneRegistrationOk: - stock_id=GTK_STOCK_YES; + icon_name="linphone-ok"; break; case LinphoneRegistrationProgress: - stock_id=GTK_STOCK_REFRESH; + icon_name="linphone-inprogress"; break; case LinphoneRegistrationCleared: - stock_id=NULL; + icon_name=NULL; break; case LinphoneRegistrationFailed: - stock_id=GTK_STOCK_DIALOG_WARNING; + icon_name="linphone-failed"; break; default: break; } - gtk_list_store_set(GTK_LIST_STORE(model),&iter,1,stock_id,-1); + gtk_list_store_set(GTK_LIST_STORE(model),&iter,1,icon_name,-1); } static void linphone_gtk_registration_state_changed(LinphoneCore *lc, LinphoneProxyConfig *cfg, - LinphoneRegistrationState rs, const char *msg){ + LinphoneRegistrationState rs, const char *msg){ switch (rs){ case LinphoneRegistrationOk: if (cfg){ @@ -1479,18 +1436,29 @@ static void linphone_gtk_registration_state_changed(LinphoneCore *lc, LinphonePr update_registration_status(cfg,rs); } -void linphone_gtk_open_browser(const char *url){ - /*in gtk 2.16, gtk_show_uri does not work...*/ -#ifndef WIN32 -#if GTK_CHECK_VERSION(2,18,3) - gtk_show_uri(NULL,url,GDK_CURRENT_TIME,NULL); +void linphone_gtk_open_browser(const char *uri) { +#ifdef __APPLE__ + GError *error = NULL; + char cmd_line[256]; + + g_snprintf(cmd_line, sizeof(cmd_line), "%s %s", "/usr/bin/open", uri); + g_spawn_command_line_async(cmd_line, &error); + if (error) { + g_warning("Could not open %s: %s", uri, error->message); + g_error_free(error); + } +#elif defined(WIN32) + HINSTANCE instance = ShellExecute(NULL, "open", uri, NULL, NULL, SW_SHOWNORMAL); + if ((int)instance <= 32) { + g_warning("Could not open %s (error #%i)", uri, (int)instance); + } #else - char cl[255]; - snprintf(cl,sizeof(cl),"/usr/bin/x-www-browser %s",url); - g_spawn_command_line_async(cl,NULL); -#endif -#else /*WIN32*/ - ShellExecute(0,"open",url,NULL,NULL,1); + GError *error = NULL; + gtk_show_uri(NULL, uri, GDK_CURRENT_TIME, &error); + if (error) { + g_warning("Could not open %s: %s", uri, error->message); + g_error_free(error); + } #endif } @@ -1499,7 +1467,7 @@ void linphone_gtk_link_to_website(GtkWidget *item){ linphone_gtk_open_browser(home); } -static GtkWidget *create_icon_menu(){ +static GtkWidget *create_icon_menu(void){ GtkWidget *menu=gtk_menu_new(); GtkWidget *menu_item; GtkWidget *image; @@ -1534,7 +1502,7 @@ static GtkWidget *create_icon_menu(){ #ifndef HAVE_GTK_OSX void linphone_gtk_save_main_window_position(GtkWindow* mw, GdkEvent *event, gpointer data){ - gtk_window_get_position(GTK_WINDOW(mw), &main_window_x, &main_window_y); + gtk_window_get_position(GTK_WINDOW(mw), &main_window_x, &main_window_y); } #endif @@ -1569,11 +1537,11 @@ static void linphone_gtk_init_status_icon(void) { linphone_status_icon_params_set_title(params, _("Linphone")); linphone_status_icon_params_set_description(params, _("A video internet phone")); linphone_status_icon_params_set_on_click_cb(params, handle_icon_click, NULL); - + if(linphone_status_icon_init( (LinphoneStatusIconReadyCb)linphone_gtk_status_icon_initialised_cb, params)) { - + LinphoneStatusIcon *icon = linphone_status_icon_get(); if(icon) { linphone_status_icon_start(icon, params); @@ -1604,7 +1572,7 @@ static void init_identity_combo(GtkComboBox *box){ gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(box),(r1=gtk_cell_renderer_text_new()),TRUE); gtk_cell_layout_pack_end(GTK_CELL_LAYOUT(box),(r2=gtk_cell_renderer_pixbuf_new()),FALSE); gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(box),r1,"text",0); - gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(box),r2,"stock-id",1); + gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(box),r2,"icon-name",1); g_object_set(G_OBJECT(r1),"ellipsize",PANGO_ELLIPSIZE_END,NULL); gtk_combo_box_set_model(box,GTK_TREE_MODEL(store)); } @@ -1625,7 +1593,7 @@ void linphone_gtk_load_identities(void){ store=GTK_LIST_STORE(gtk_combo_box_get_model(box)); } gtk_list_store_clear(store); - linphone_core_get_default_proxy(linphone_gtk_get_core(),&def); + def = linphone_core_get_default_proxy_config(linphone_gtk_get_core()); def_identity=g_strdup_printf(_("%s (Default)"),linphone_core_get_primary_contact(linphone_gtk_get_core())); gtk_list_store_append(store,&iter); gtk_list_store_set(store,&iter,0,def_identity,1,NULL,2,NULL,-1); @@ -1636,8 +1604,8 @@ void linphone_gtk_load_identities(void){ LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)elem->data; gtk_list_store_append(store,&iter); gtk_list_store_set(store,&iter,0,linphone_proxy_config_get_identity(cfg),1, - linphone_proxy_config_is_registered(cfg) ? GTK_STOCK_YES : NULL, - 2,cfg,-1); + linphone_proxy_config_is_registered(cfg) ? "linphone-ok" : NULL, + 2,cfg,-1); if (cfg==def) { def_index=i; } @@ -1652,7 +1620,7 @@ static void linphone_gtk_dtmf_pressed(GtkButton *button){ gtk_editable_insert_text(GTK_EDITABLE(uri_bar),label,1,&pos); linphone_core_play_dtmf (linphone_gtk_get_core(),label[0],-1); if (linphone_core_in_call(linphone_gtk_get_core())){ - linphone_core_send_dtmf(linphone_gtk_get_core(),label[0]); + linphone_call_send_dtmf(linphone_core_get_current_call(linphone_gtk_get_core()),label[0]); } } @@ -1682,7 +1650,7 @@ static void linphone_gtk_check_menu_items(void){ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(selfview_item),selfview); } -static gboolean linphone_gtk_can_manage_accounts(){ +static gboolean linphone_gtk_can_manage_accounts(void){ LinphoneCore *lc=linphone_gtk_get_core(); const MSList *elem; for(elem=linphone_core_get_sip_setups(lc);elem!=NULL;elem=elem->next){ @@ -1694,26 +1662,20 @@ static gboolean linphone_gtk_can_manage_accounts(){ return FALSE; } -static void linphone_gtk_configure_main_window(){ +static void linphone_gtk_configure_main_window(void){ static gboolean config_loaded=FALSE; static const char *title; static const char *home; - static const char *start_call_icon; - static const char *add_call_icon; static const char *search_icon; static gboolean update_check_menu; - static gboolean buttons_have_borders; static gboolean show_abcd; GtkWidget *w=linphone_gtk_get_main_window(); if (!config_loaded){ title=linphone_gtk_get_ui_config("title","Linphone"); home=linphone_gtk_get_ui_config("home","http://www.linphone.org"); - start_call_icon=linphone_gtk_get_ui_config("start_call_icon","startcall-green.png"); - add_call_icon=linphone_gtk_get_ui_config("add_call_icon","addcall-green.png"); search_icon=linphone_gtk_get_ui_config("directory_search_icon",NULL); update_check_menu=linphone_gtk_get_ui_config_int("update_check_menu",0); - buttons_have_borders=linphone_gtk_get_ui_config_int("buttons_border",1); show_abcd=linphone_gtk_get_ui_config_int("show_abcd",1); config_loaded=TRUE; } @@ -1721,18 +1683,6 @@ static void linphone_gtk_configure_main_window(){ if (title) { gtk_window_set_title(GTK_WINDOW(w),title); } - if (start_call_icon){ - gtk_button_set_image(GTK_BUTTON(linphone_gtk_get_widget(w,"start_call")), - create_pixmap (start_call_icon)); - if (!buttons_have_borders) - gtk_button_set_relief(GTK_BUTTON(linphone_gtk_get_widget(w,"start_call")),GTK_RELIEF_NONE); - } - if (add_call_icon){ - gtk_button_set_image(GTK_BUTTON(linphone_gtk_get_widget(w,"add_call")), - create_pixmap (add_call_icon)); - if (!buttons_have_borders) - gtk_button_set_relief(GTK_BUTTON(linphone_gtk_get_widget(w,"add_call")),GTK_RELIEF_NONE); - } if (search_icon){ GdkPixbuf *pbuf=create_pixbuf(search_icon); if(pbuf) { @@ -1744,24 +1694,7 @@ static void linphone_gtk_configure_main_window(){ gchar *tmp; GtkWidget *menu_item=linphone_gtk_get_widget(w,"home_item"); tmp=g_strdup(home); - g_object_set_data(G_OBJECT(menu_item),"home",tmp); - } - { - /* - GdkPixbuf *pbuf=create_pixbuf("contact-orange.png"); - if (pbuf) { - gtk_image_set_from_pixbuf(GTK_IMAGE(linphone_gtk_get_widget(w,"contact_tab_icon")),pbuf); - g_object_unref(G_OBJECT(pbuf)); - } - */ - } - { - GdkPixbuf *pbuf=create_pixbuf("dialer.png"); - if (pbuf) { - GtkButton *button=GTK_BUTTON(linphone_gtk_get_widget(w,"keypad")); - gtk_button_set_image(button,gtk_image_new_from_pixbuf (pbuf)); - g_object_unref(pbuf); - } + g_object_set_data_full(G_OBJECT(menu_item),"home",tmp, (GDestroyNotify)g_free); } if (linphone_gtk_can_manage_accounts()) { gtk_widget_show(linphone_gtk_get_widget(w,"assistant_item")); @@ -1774,8 +1707,7 @@ static void linphone_gtk_configure_main_window(){ void linphone_gtk_manage_login(void){ LinphoneCore *lc=linphone_gtk_get_core(); - LinphoneProxyConfig *cfg=NULL; - linphone_core_get_default_proxy(lc,&cfg); + LinphoneProxyConfig *cfg=linphone_core_get_default_proxy_config(lc); if (cfg){ SipSetup *ss=linphone_proxy_config_get_sip_setup(cfg); if (ss && (sip_setup_get_capabilities(ss) & SIP_SETUP_CAP_LOGIN)){ @@ -1862,17 +1794,17 @@ void linphone_gtk_keypad_key_released(GtkWidget *w, GdkEvent *event, gpointer us } } -void linphone_gtk_create_keypad(GtkWidget *button){ +static void linphone_gtk_show_keypad(void){ GtkWidget *mw=linphone_gtk_get_main_window(); GtkWidget *k=(GtkWidget *)g_object_get_data(G_OBJECT(mw),"keypad"); GtkWidget *keypad; if(k!=NULL){ gtk_widget_destroy(k); } - keypad=linphone_gtk_create_window("keypad"); + keypad=linphone_gtk_create_window("keypad", NULL); linphone_gtk_connect_digits(keypad); linphone_gtk_init_dtmf_table(keypad); - g_object_set_data(G_OBJECT(mw),"keypad",(gpointer)keypad); + g_object_set_data(G_OBJECT(mw),"keypad", keypad); if(!GPOINTER_TO_INT(g_object_get_data(G_OBJECT(mw),"show_abcd"))){ gtk_widget_hide(linphone_gtk_get_widget(keypad,"dtmf_A")); gtk_widget_hide(linphone_gtk_get_widget(keypad,"dtmf_B")); @@ -1883,17 +1815,50 @@ void linphone_gtk_create_keypad(GtkWidget *button){ gtk_widget_show(keypad); } -static void linphone_gtk_init_main_window(){ +static void linphone_gtk_destroy_keypad(void) { + GtkWidget *mw = linphone_gtk_get_main_window(); + GtkWidget *keypad = GTK_WIDGET(g_object_get_data(G_OBJECT(mw), "keypad")); + if(keypad) { + gtk_widget_destroy(keypad); + g_object_set_data(G_OBJECT(mw), "keypad", NULL); + } +} + +void linphone_gtk_show_keypad_checked(GtkCheckMenuItem *check_menu_item) { + if(gtk_check_menu_item_get_active(check_menu_item)) { + linphone_gtk_show_keypad(); + } else { + linphone_gtk_destroy_keypad(); + } +} + +gboolean linphone_gtk_keypad_destroyed_handler(void) { + GtkWidget *mw = linphone_gtk_get_main_window(); + GtkWidget *show_keypad_item = linphone_gtk_get_widget(mw, "show_keypad_menu_item"); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(show_keypad_item), FALSE); + return FALSE; +} + +void linphone_gtk_update_status_bar_icons(void) { + GtkWidget *mw = linphone_gtk_get_main_window(); + GtkWidget *icon = linphone_gtk_get_widget(mw, "autoanswer_icon"); + gtk_widget_set_visible(icon, linphone_gtk_auto_answer_enabled()); +} + +static void linphone_gtk_init_main_window(void){ GtkWidget *main_window; linphone_gtk_configure_main_window(); linphone_gtk_manage_login(); - load_uri_history(); linphone_gtk_load_identities(); linphone_gtk_set_my_presence(linphone_core_get_presence_info(linphone_gtk_get_core())); linphone_gtk_show_friends(); + linphone_gtk_update_status_bar_icons(); + load_uri_history(); linphone_core_reset_missed_calls_count(linphone_gtk_get_core()); main_window=linphone_gtk_get_main_window(); +#ifndef CALL_LOGS_STORAGE_ENABLED linphone_gtk_call_log_update(main_window); +#endif linphone_gtk_update_call_buttons (NULL); g_object_set_data(G_OBJECT(main_window),"keypad",NULL); @@ -1913,6 +1878,11 @@ static void linphone_gtk_init_main_window(){ #endif linphone_gtk_check_menu_items(); linphone_core_enable_video_preview(linphone_gtk_get_core(),FALSE); +#ifdef BUILD_WIZARD + gtk_widget_set_visible(linphone_gtk_get_widget(main_window, "assistant_item"), TRUE); +#else + gtk_widget_set_visible(linphone_gtk_get_widget(main_window, "assistant_item"), FALSE); +#endif } void linphone_gtk_log_handler(OrtpLogLevel lev, const char *fmt, va_list args){ @@ -1959,13 +1929,13 @@ void linphone_gtk_refer_received(LinphoneCore *lc, const char *refer_to){ GtkEntry * uri_bar =GTK_ENTRY(linphone_gtk_get_widget( linphone_gtk_get_main_window(), "uribar")); char *text; - linphone_gtk_notify(NULL,(text=ms_strdup_printf(_("We are transferred to %s"),refer_to))); + linphone_gtk_notify(NULL,NULL,(text=ms_strdup_printf(_("We are transferred to %s"),refer_to))); g_free(text); gtk_entry_set_text(uri_bar, refer_to); linphone_gtk_start_call(linphone_gtk_get_main_window()); } -static void linphone_gtk_check_soundcards(){ +static void linphone_gtk_check_soundcards(void){ const char **devices=linphone_core_get_sound_devices(linphone_gtk_get_core()); if (devices==NULL || devices[0]==NULL){ linphone_gtk_display_something(GTK_MESSAGE_WARNING, @@ -2043,16 +2013,41 @@ static void linphone_gtk_init_ui(void){ linphone_gtk_monitor_usb(); } +static void sigint_handler(int signum){ + gtk_main_quit(); +} + +static void populate_xdg_data_dirs_envvar(void) { +#ifndef WIN32 + int i; + gchar *value; + gchar **paths; + + if(g_getenv("XDG_DATA_DIRS") == NULL) { + value = g_strdup("/usr/share:/usr/local/share:/opt/local/share"); + } else { + value = g_strdup(g_getenv("XDG_DATA_DIRS")); + } + paths = g_strsplit(value, ":", -1); + for(i=0; paths[i] && strcmp(paths[i], PACKAGE_DATA_DIR) != 0; i++); + if(paths[i] == NULL) { + gchar *new_value = g_strdup_printf("%s:%s", PACKAGE_DATA_DIR, value); + g_setenv("XDG_DATA_DIRS", new_value, TRUE); + g_free(new_value); + } + g_strfreev(paths); +#endif +} + int main(int argc, char *argv[]){ char *config_file; const char *factory_config_file; const char *lang; GtkSettings *settings; - const char *icon_path=LINPHONE_ICON; - GdkPixbuf *pbuf; + const char *icon_name=LINPHONE_ICON_NAME; const char *app_name="Linphone"; LpConfig *factory; - const char *db_file; + char *chat_messages_db_file, *call_logs_db_file; GError *error=NULL; const char *tmp; @@ -2071,6 +2066,8 @@ int main(int argc, char *argv[]){ /*for pulseaudio:*/ g_setenv("PULSE_PROP_media.role", "phone", TRUE); #endif + + populate_xdg_data_dirs_envvar(); lang=linphone_gtk_get_lang(config_file); if (lang == NULL || lang[0]=='\0'){ @@ -2107,6 +2104,11 @@ int main(int argc, char *argv[]){ g_critical("%s", error->message); return -1; } + if(version) { + g_message("Linphone version %s.", LIBLINPHONE_GIT_VERSION); + return 0; + } + if (config_file) g_free(config_file); if (custom_config_file && !g_path_is_absolute(custom_config_file)) { gchar *res = g_get_current_dir(); @@ -2153,14 +2155,10 @@ int main(int argc, char *argv[]){ factory=lp_config_new(NULL); lp_config_read_file(factory,factory_config_file); app_name=lp_config_get_string(factory,"GtkUi","title","Linphone"); - icon_path=lp_config_get_string(factory,"GtkUi","icon",LINPHONE_ICON); + icon_name=lp_config_get_string(factory,"GtkUi","icon_name",LINPHONE_ICON_NAME); } g_set_application_name(app_name); - pbuf=create_pixbuf(icon_path); - if (pbuf) { - gtk_window_set_default_icon(pbuf); - g_object_unref(pbuf); - } + gtk_window_set_default_icon_name(icon_name); #ifdef HAVE_GTK_OSX GtkosxApplication *theMacApp = gtkosx_application_get(); @@ -2178,21 +2176,29 @@ core_start: return 0; } - the_ui=linphone_gtk_create_window("main"); + the_ui=linphone_gtk_create_window("main", NULL); g_object_set_data(G_OBJECT(the_ui),"is_created",GINT_TO_POINTER(FALSE)); linphone_gtk_create_log_window(); linphone_core_enable_logs_with_cb(linphone_gtk_log_handler); - db_file=linphone_gtk_message_storage_get_db_file(NULL); + chat_messages_db_file=linphone_gtk_message_storage_get_db_file(NULL); + call_logs_db_file = linphone_gtk_call_logs_storage_get_db_file(NULL); + linphone_gtk_init_liblinphone(config_file, factory_config_file, chat_messages_db_file, call_logs_db_file); + g_free(chat_messages_db_file); + g_free(call_logs_db_file); - linphone_gtk_init_liblinphone(config_file, factory_config_file, db_file); +#ifdef CALL_LOGS_STORAGE_ENABLED + linphone_gtk_call_log_update(the_ui); +#endif /* do not lower timeouts under 30 ms because it exhibits a bug on gtk+/win32, with cpu running 20% all the time...*/ gtk_timeout_add(30,(GtkFunction)linphone_gtk_iterate,(gpointer)linphone_gtk_get_core()); gtk_timeout_add(30,(GtkFunction)linphone_gtk_check_logs,(gpointer)linphone_gtk_get_core()); + signal(SIGINT, sigint_handler); + gtk_main(); linphone_gtk_quit(); @@ -2215,3 +2221,34 @@ int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi return main(__argc, __argv); } #endif + +GtkWidget *linphone_gtk_make_tab_header(const gchar *label, const gchar *icon_name, gboolean show_quit_button, GCallback cb, gpointer user_data) { + GtkWidget *tab_header=gtk_hbox_new (FALSE,0); + GtkWidget *label_widget = gtk_label_new (label); + + if(icon_name) { + GtkWidget *icon=gtk_image_new_from_icon_name(icon_name, GTK_ICON_SIZE_MENU); +#ifdef HAVE_GTK_OSX + gtk_misc_set_alignment(GTK_MISC(icon), 0.5f, 0.25f); +#endif + gtk_box_pack_start (GTK_BOX(tab_header),icon,FALSE,FALSE,4); + } +#ifdef HAVE_GTK_OSX + gtk_misc_set_alignment(GTK_MISC(label_widget), 0.5f, 0.f); +#endif + gtk_box_pack_start (GTK_BOX(tab_header),label_widget,FALSE,FALSE,0); + if(show_quit_button) { + GtkWidget *button = gtk_button_new(); + GtkWidget *button_image=gtk_image_new_from_stock(GTK_STOCK_CLOSE,GTK_ICON_SIZE_MENU); + gtk_button_set_image(GTK_BUTTON(button),button_image); + gtk_button_set_relief(GTK_BUTTON(button),GTK_RELIEF_NONE); +#ifdef HAVE_GTK_OSX + gtk_misc_set_alignment(GTK_MISC(button_image), 0.5f, 0.f); +#endif + g_signal_connect_swapped(G_OBJECT(button),"clicked",cb,user_data); + gtk_box_pack_end(GTK_BOX(tab_header),button,FALSE,FALSE,4); + g_object_set_data(G_OBJECT(tab_header), "button", button); + } + g_object_set_data(G_OBJECT(tab_header), "label", label_widget); + return tab_header; +} diff --git a/gtk/main.ui b/gtk/main.ui index 48e5a61d6..98dc3400a 100644 --- a/gtk/main.ui +++ b/gtk/main.ui @@ -1,739 +1,100 @@ - + - + + True False - gtk-add + 2 + 30 + linphone-add-call + + + True + False + linphone-contact-add + + + True + False + 4 + linphone-delete True False gtk-connect + 1 - - False - - - True - False - 0 - none - - - True - False - 12 - - - True - False - 12 - - - True - False - - - True - False - - - True - True - - - False - False - 0 - - - - - False - True - 0 - - - - - True - False - <b>Callee name</b> - True - right - end - - - True - True - 1 - - - - - 90 - 30 - True - False - - - False - True - 2 - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + linphone-status-online + Toto + toto@sip.linphone.org + linphone-chat-nothing + False + False + + + linphone-status-offline + Toto2 + toto2@sip.linphone.org + linphone-chat-nothing + False + False + + + linphone-status-offline + Toto3 + toto3@sip.linphone.org + linphone-chat-nothing + False + False + + - - False - - - True - False - 0 - none - - - True - False - - - True - True - never - - - True - True - 4 - - - - - True - True - 0 - - - - - True - False - - - True - True - True - - False - False - True - True - - - True - True - 0 - - - - - True - True - True - - - True - False - - - True - False - gtk-ok - - - True - True - 0 - - - - - True - False - Send - - - True - True - 7 - 1 - - - - - - - False - False - 1 - - - - - False - False - 1 - - - - - - - - - - - - False - - - True - False - 0 - none - - - True - False - - - True - False - - - End conference - True - True - True - - - False - False - end - 0 - - - - - True - True - end - 0 - - - - - True - False - - - gtk-media-record - True - True - True - True - - - - False - False - 0 - - - - - True - False - True - char - - - True - True - 1 - - - - - False - False - end - 1 - - - - - - - - - - - - False - - - False - cursor - 0.5 - none - - - True - False - 12 - 12 - - - True - False - - - True - False - center - - - True - True - 0 - - - - - True - False - - - - - - False - False - 1 - - - - - False - - - True - False - gtk-dialog-authentication - 1 - - - False - False - 0 - - - - - True - False - gtk-apply - - - False - False - 1 - - - - - True - False - - - True - True - 2 - 2 - - - - - Set verified - True - True - True - - - - False - False - 3 - - - - - False - True - 2 - - - - - False - True - - - True - False - gtk-missing-image - 1 - - - False - False - 0 - - - - - 90 - 10 - True - False - - - False - False - 1 - - - - - True - False - gtk-missing-image - 0 - - - False - False - 2 - - - - - 90 - 10 - True - False - - - False - False - 1 - end - 3 - - - - - False - False - 2 - 3 - - - - - False - spread - - - Answer - True - True - True - - - - False - False - 0 - - - - - Decline - True - True - True - - - - False - False - 1 - - - - - False - False - 4 - - - - - False - - - gtk-media-record - True - True - True - Record this call to an audio file - True - - - - False - False - 0 - - - - - True - False - True - char - - - True - True - 1 - - - - - False - False - 5 - - - - - True - False - 2 - 3 - True - - - Video - True - True - True - - - - - Pause - True - True - True - - - - 1 - 2 - - - - - Mute - True - True - True - - - - 2 - 3 - - - - - Transfer - True - True - True - - - 1 - 2 - - - - - Hang up - True - True - True - - - - 1 - 2 - 1 - 2 - - - - - Conference - True - True - True - - - 2 - 3 - 1 - 2 - - - - - False - False - 7 - 6 - - - - - - - - - True - False - True - - - True - False - In call - True - center - - - True - True - 0 - - - - - True - False - Duration - center - - - True - True - 1 - - - - - 90 - 10 - True - False - GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK - Call quality rating - - - False - False - 2 - - - - - - - - + True False - gtk-edit + linphone-edit True False gtk-execute + 1 True False gtk-home + 1 True False gtk-info - - - - - - - - - All users - - - Online users - - - - - - - - - - - ADSL - - - Fiber Channel - - + 1 @@ -746,39 +107,41 @@ - - - - - - - - ADSL - - - Fiber Channel - - - True False - 0.49000000953674316 gtk-properties + 1 - + True False Delete - gtk-remove + linphone-delete + + + True + False + 2 + 30 + linphone-start-call + + + True + False + 2 + 30 + linphone-start-chat + 640 + 480 False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 660 450 - + True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK @@ -808,7 +171,7 @@ - + True False Set configuration URI @@ -850,6 +213,15 @@ + + + True + False + Show keypad + True + + + True @@ -862,6 +234,7 @@ False True True + @@ -896,6 +269,7 @@ False info_image False + @@ -951,234 +325,281 @@ - + True False + 8 - + True False - 8 - + True False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + none - + True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 0 - none + 5 + 5 - + True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 5 - 5 - + True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - True - True - - True - False - False - True - True - - - - True - True - 0 - - + True + + True + linphone-contact-add + False + True + True + False + + + True + True + 0 + - - + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + SIP address or phone number: + True + + + + + True + True + 2 + 0 + + + + + True + True + Initiate a new call + add_call_image + + + + False + False + 1 + + + + + True + True + True + start_call_image + + + + False + True + 2 + + + + + True + True + True + start_chat_image + + + + False + True + end + 3 + + + + + False + True + 8 + 0 + + + + + True + True + 200 + True + + + True + False + 4 + + + True + False + GDK_POINTER_MOTION_MASK | GDK_STRUCTURE_MASK + 0 + Contacts + True + + + False + False + 3 + 0 + + + + + True + True + automatic + automatic + + True - False + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - SIP address or phone number: - True + contact_list_model + False + True + 1 + 4 + + + + + + + + + + 3 + + + 0 + + + + + + + 60 + True + + + + 1 + + + + + + + + + linphone-start-call2 + 3 + + + 6 + + + + + + + + + 3 + + + 7 + 5 + + + + True True - 2 - 0 - - - - - True - True - Initiate a new call - - - - False - False - 6 - end 1 - - True - True - True - - - - False - True - 6 - end - 2 - - - - - True - True - True - - - - False - False - 3 - - - - - - - - - - - False - True - 8 - 0 - - - - - True - True - - + True False - 4 + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 2 - + + 32 + 32 True - False - GDK_POINTER_MOTION_MASK | GDK_STRUCTURE_MASK - 0 - Contacts - True + True + True + immediate + add_image1 + False False - 3 0 - + + 32 + 32 True + False True - automatic - automatic - - - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - True - False - 1 - - - - - - + True + edit_image1 + - True - True + False + False 1 - + + 32 + 32 True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - True - True - True - immediate - add_image - 1 - - - - False - False - 0 - - - - - True - True - True - edit_image - - - - False - False - 1 - - - - - True - True - True - remove_image - - - - False - False - 2 - - + False + True + True + remove_image1 + False @@ -1188,167 +609,169 @@ - False - False + False + False + 4 + 2 + + + True + True + + + + + True + True - + + + + + + + True - True + False - - - - - - - + True False + 2 - + True - False - 2 + True + never - + + 350 True True - never + False + False + + + + + + + True + True + 0 + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + False + 0 + none - - 350 + + False + + + True + True + + True + False + False + True + True + + + True + True + 0 + + + + + True + True + True + none + + + + True + False + + + True + False + gtk-find + + + True + True + 0 + + + + + True + False + Search + + + True + True + 1 + + + + + + + False + True + 1 + + + + + + True - True - False - - + False + <b>Add contacts from directory</b> + True - True - True + False + False + 5 0 - + True False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - False - 0 - none - - - False - - - True - True - - True - False - False - True - True - - - True - True - 0 - - - - - True - True - True - none - - - - True - False - - - True - False - gtk-find - - - True - True - 0 - - - - - True - False - Search - - - True - True - 1 - - - - - - - False - True - 1 - - - - - - - True - False - <b>Add contacts from directory</b> - True - - + + Add contact + True + True + False False - 5 0 - - - True - False - - - Add contact - True - True - - - - False - False - 0 - - - - - False - False - 1 - - False @@ -1356,74 +779,81 @@ 1 + + + False + False + 1 + + + + + True + False + end - + + Clear call history True - False - end - - - gtk-clear - True - True - True - True - - - - False - False - 0 - - - - - - - - + True + True + clear_call_history_image + False - True - 2 + False + 0 - True + False True - 0 + 2 - 1 + True + True + 0 - - + + + 1 + + + + + True + False + GDK_BUTTON_PRESS_MASK | GDK_STRUCTURE_MASK + False + + + True False - True False - gtk-refresh + linphone-history 1 True True + 4 0 - + True False - 0.49000000953674316 Recent calls @@ -1433,364 +863,123 @@ - - 1 - False - - - - - - - - True - True + 1 + False - - - True - True - 1 - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 0 - none - - True - False - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - model3 - 0 - - - - - 0 - - - - - True - True - 0 - - - - - True - True - True - none - - - - False - True - 5 - 1 - - - + - - - True - False - 5 - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - My current identity: - True - - - True - True - 0 - - - - - True - True - True - none - - - - True - True - 1 - - - + + - False - False - 2 + True + True - - True - True - 0 - - - - - False - 0 - etched-out - - - True - False - 12 - - - True - False - - - True - False - gtk-missing-image - - - True - True - 0 - - - - - True - False - 0 - none - - - True - False - 12 - 12 - - - True - False - 5 - 2 - - - - - - True - False - Username - - - - - True - False - Password - - - 1 - 2 - - - - - False - Internet connection: - - - 3 - 4 - - - - - True - True - - False - False - True - True - - - 1 - 2 - - - - - True - True - False - - False - False - True - True - - - 1 - 2 - 1 - 2 - - - - - False - model4 - 0 - - - - 0 - - - - - 1 - 2 - 3 - 4 - - - - - Automatically log me in - True - True - False - True - - - 1 - 2 - 4 - 5 - - - - - False - UserID - - - 2 - 3 - - - - - True - - False - False - True - True - - - 1 - 2 - 2 - 3 - - - - - - - - - True - False - Login information - True - - - - - True - True - 10 - 1 - - - - - True - False - - - gtk-connect - True - True - True - True - - - - False - False - 0 - - - - - - - - True - True - 2 - - - - - - - - - True - False - <b>Welcome!</b> - True - - - True True 1 + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + none + + + True + False + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + model3 + 0 + + + + + 0 + + + + + True + True + 0 + + + + + True + True + True + none + + + + False + True + 5 + 1 + + + + + + + True + False + 5 + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + My current identity: + True + + + True + True + 0 + + + + + True + True + True + none + + + + True + True + 1 + + + + + + + False + False + 2 + + True @@ -1799,10 +988,35 @@ - + True False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False + + + True + True + 0 + + + + + False + Autoanswer is enabled + 16 + linphone-warning + + + False + True + 1 + + False diff --git a/gtk/parameters.ui b/gtk/parameters.ui index c40537c8f..6043663ab 100644 --- a/gtk/parameters.ui +++ b/gtk/parameters.ui @@ -47,6 +47,11 @@ 1 10 + + 30 + 1 + 10 + 60000 2000 @@ -174,6 +179,23 @@ 1 9.9999999995529656 + + + + + + + + default + + + high-fps + + + custom + + + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK @@ -189,11 +211,1269 @@ True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 10 + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + This section defines your SIP address when not using a SIP account + 0 + none + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 3 + 2 + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Your display name (eg: John Doe): + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False + False + True + True + + + + 1 + 2 + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Your username: + + + 1 + 2 + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Your resulting SIP address: + + + 2 + 3 + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False + False + True + True + + + + 1 + 2 + 1 + 2 + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False + False + False + True + True + + + 1 + 2 + 2 + 3 + + + + + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + <b>Default identity</b> + True + + + + + True + True + 0 + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + none + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + + True + True + 0 + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + True + True + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-add + + + True + True + 0 + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Wizard + + + True + True + 1 + + + + + + + False + False + 0 + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-add + + + True + True + 0 + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Add + + + True + True + 1 + + + + + + + False + False + 1 + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-edit + + + True + True + 0 + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Edit + + + True + True + 1 + + + + + + + False + False + 2 + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-delete + + + True + True + 0 + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Remove + + + True + True + 1 + + + + + + + False + False + 3 + + + + + False + False + 1 + + + + + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + <b>Proxy accounts</b> + True + + + + + True + True + 1 + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + none + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-delete + + + True + True + 0 + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Erase all passwords + + + True + True + 1 + + + + + + + False + False + 0 + + + + + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + <b>Privacy</b> + True + + + + + True + True + 2 + + + + + True + False + 0 + none + + + True + False + 12 + + + True + False + 2 + 2 + + + Automatically answer when a call is received + True + True + False + True + + + + 2 + + + + + True + False + Delay before answering (ms) + + + 1 + 2 + + + + + True + True + + False + False + True + True + ajustment_auto_answer_delay + True + + + + 1 + 2 + 1 + 2 + + + + + + + + + True + False + <b>Auto-answer</b> + True + + + + + True + True + 3 + + + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + stock_people.png + + + True + True + 0 + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Manage SIP Accounts + + + True + True + 1 + + + + + 2 + False + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 10 + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + none + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 6 + 2 + + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + True + True + 0 + + + + + gtk-media-play + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + + + + True + True + 1 + + + + + 1 + 2 + 4 + 5 + GTK_FILL + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Ring sound: + right + + + 4 + 5 + GTK_FILL + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False + False + True + True + + + + 1 + 2 + 3 + 4 + GTK_FILL + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + model1 + + + + end + 80 + + + 0 + + + + + 1 + 2 + 2 + 3 + GTK_FILL + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + model2 + + + + end + 80 + + + 0 + + + + + 1 + 2 + 1 + 2 + GTK_FILL + + + + + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + ALSA special device (optional): + right + + + 3 + 4 + GTK_FILL + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Capture device: + right + + + 2 + 3 + GTK_FILL + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Ring device: + right + + + 1 + 2 + GTK_FILL + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Playback device: + right + + + GTK_FILL + GTK_FILL + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + model3 + + + + end + 80 + + + 0 + + + + + 1 + 2 + GTK_FILL + GTK_FILL + + + + + Enable echo cancellation + True + True + False + True + + + + 1 + 2 + 5 + 6 + + + + + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + <b>Audio</b> + True + + + + + True + True + 0 + + + + + True + False + 0 + none + + + True + False + 12 + + + True + False + 5 + 3 + + + True + False + Video input device: + right + + + GTK_EXPAND + + + + + True + False + model4 + + + + + 0 + + + + + 1 + 2 + GTK_EXPAND + + + + + True + False + Preferred video resolution: + + + 3 + 4 + + + + + True + False + model5 + 0 + + + + + 0 + + + + + 1 + 2 + 3 + 4 + + + + + True + False + Video output method: + right + + + 1 + 2 + GTK_EXPAND + + + + + True + False + + + + + 0 + + + + + 1 + 2 + 1 + 2 + GTK_EXPAND + + + + + Show camera preview + True + True + True + + + + 2 + 3 + 5 + + GTK_EXPAND + 10 + + + + + True + False + Video preset: + + + 2 + 3 + + + + + True + False + video_preset_model + 0 + + + + + 0 + + + + + 1 + 2 + 2 + 3 + + + + + True + False + Preferred video framerate: + + + 4 + 5 + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 stands for "unlimited" + + False + False + True + True + adjustment_video_framerate + + + + 1 + 2 + 4 + 5 + GTK_FILL + GTK_EXPAND + + + + + + + + + True + False + <b>Video</b> + True + + + + + True + False + 1 + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + none + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 3 + 2 + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 stands for "unlimited" + + False + False + True + True + adjustment_upload_bw + + + + 1 + 2 + 1 + 2 + GTK_FILL + + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 stands for "unlimited" + + False + False + True + True + adjustment_download_bw + + + + 1 + 2 + GTK_FILL + GTK_EXPAND + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Upload speed limit in Kbit/sec: + right + + + 1 + 2 + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Download speed limit in Kbit/sec: + right + + + + + Enable adaptive rate control + True + True + False + 0 + True + + + + 1 + 2 + 2 + 3 + GTK_FILL + + + + + + True + False + <i>Adaptive rate control is a technique to dynamically guess the available bandwidth during a call.</i> + True + True + + + 2 + 3 + GTK_FILL + + + + + + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + <b>Bandwidth control</b> + True + + + + + True + True + 2 + + + + + 1 + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-media-play + 1 + + + True + True + 0 + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Multimedia settings + + + True + True + 1 + + + + + 1 + False + + True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 10 True @@ -957,6 +2237,9 @@ + + 2 + @@ -992,614 +2275,46 @@ + 2 False - + True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 10 - + True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 none - + True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 12 - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 6 - 2 - - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - - True - True - 0 - - - - - gtk-media-play - True - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - True - - - - True - True - 1 - - - - - 1 - 2 - 4 - 5 - GTK_FILL - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Ring sound: - right - - - 4 - 5 - GTK_FILL - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False - False - True - True - - - - 1 - 2 - 3 - 4 - GTK_FILL - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - model1 - - - - - 0 - - - - - 1 - 2 - 2 - 3 - GTK_FILL - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - model2 - - - - - 0 - - - - - 1 - 2 - 1 - 2 - GTK_FILL - - - - - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - ALSA special device (optional): - right - - - 3 - 4 - GTK_FILL - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Capture device: - right - - - 2 - 3 - GTK_FILL - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Ring device: - right - - - 1 - 2 - GTK_FILL - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Playback device: - right - - - GTK_FILL - GTK_FILL - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - model3 - - - - - 0 - - - - - 1 - 2 - GTK_FILL - GTK_FILL - - - - - Enable echo cancellation - True - True - False - True - - - - 1 - 2 - 5 - 6 - - - - - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - <b>Audio</b> - True - - - - - True - True - 0 - - - - - True - False - 0 - none - - - True - False - 12 - - - True - False - 4 - 2 - - - True - False - Video input device: - right - - - GTK_EXPAND - - - - - True - False - model4 - - - - - 0 - - - - - 1 - 2 - GTK_EXPAND - - - - - True - False - Prefered video resolution: - - - 1 - 2 - - - - - True - False - model5 - 0 - - - - - 0 - - - - - 1 - 2 - 1 - 2 - - - - - True - False - Video output method: - right - - - 2 - 3 - GTK_EXPAND - - - - - True - False - - - - - 0 - - - - - 1 - 2 - 2 - 3 - GTK_EXPAND - - - - - Show camera preview - True - True - True - - - - 2 - 3 - 4 - GTK_EXPAND - - - - - - - - - True - False - <b>Video</b> - True - - - - - True - False - 1 - - - - - 1 - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - gtk-media-play - 1 - - - True - True - 0 - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Multimedia settings - - - True - True - 1 - - - - - 1 - False - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - This section defines your SIP address when not using a SIP account - 0 - none - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 12 - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 3 - 2 - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Your display name (eg: John Doe): - - - - - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False - False - True - True - - - - 1 - 2 - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Your username: - - - 1 - 2 - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Your resulting SIP address: - - - 2 - 3 - - - - - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False - False - True - True - - - - 1 - 2 - 1 - 2 - - - - - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False - False - False - True - True - - - 1 - 2 - 2 - 3 - - - - - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - <b>Default identity</b> - True - - - - - True - True - 0 - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 0 - none - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 12 - - + True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + out - + True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True @@ -1610,49 +2325,21 @@ - + True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 10 + center - + + gtk-go-up True True True - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - gtk-add - - - True - True - 0 - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Wizard - - - True - True - 1 - - - - + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + False @@ -1661,45 +2348,14 @@ - + + gtk-go-down True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - gtk-add - - - True - True - 0 - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Add - - - True - True - 1 - - - - + True + False @@ -1708,23 +2364,23 @@ - + True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + - + True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - gtk-edit + gtk-yes True @@ -1733,11 +2389,11 @@ - + True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Edit + Enable True @@ -1755,23 +2411,23 @@ - + True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + - + True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - gtk-delete + gtk-no True @@ -1780,11 +2436,11 @@ - + True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Remove + Disable True @@ -1804,448 +2460,6 @@ False - False - 1 - - - - - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - <b>Proxy accounts</b> - True - - - - - True - True - 1 - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 0 - none - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 12 - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - True - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - gtk-delete - - - True - True - 0 - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Erase all passwords - - - True - True - 1 - - - - - - - False - False - 0 - - - - - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - <b>Privacy</b> - True - - - - - True - True - 2 - - - - - True - False - 0 - none - - - True - False - 12 - - - True - False - 2 - 2 - - - Automatically answer when a call is received - True - True - False - True - - - - 2 - - - - - True - False - Delay before answering (ms) - - - 1 - 2 - - - - - True - True - - False - False - True - True - ajustment_auto_answer_delay - True - - - - 1 - 2 - 1 - 2 - - - - - - - - - True - False - <b>Auto-answer</b> - True - - - - - True - True - 3 - - - - - 2 - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - stock_people.png - - - True - True - 0 - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Manage SIP Accounts - - - True - True - 1 - - - - - 2 - False - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 0 - none - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 12 - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - model6 - 0 - - - - - 0 - - - - - False - True - 0 - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - out - - - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - True - - - - - True - True - 0 - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - gtk-go-up - True - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - True - - - - False - False - 0 - - - - - gtk-go-down - True - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - True - - - - False - False - 1 - - - - - True - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - gtk-yes - - - True - True - 0 - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Enable - - - True - True - 1 - - - - - - - False - False - 2 - - - - - True - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - gtk-no - - - True - True - 0 - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Disable - - - True - True - 1 - - - - - - - False - False - 3 - - - - - False - True - 1 - - - - - True True 1 @@ -2259,7 +2473,7 @@ True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - <b>Codecs</b> + <b>Audio codecs</b> True @@ -2271,121 +2485,182 @@ - + True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 0 none - + True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 12 - + True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 3 - 2 - + True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 0 stands for "unlimited" - False - False - True - True - adjustment_upload_bw - + out + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + + - 1 - 2 - 1 - 2 - GTK_FILL - + True + True + 0 - - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 0 stands for "unlimited" - False - False - True - True - adjustment_download_bw - - - - 1 - 2 - GTK_FILL - GTK_EXPAND - - - - + True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Upload speed limit in Kbit/sec: - right + 10 + center + + + gtk-go-up + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + + + + False + False + 0 + + + + + gtk-go-down + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + + + + False + False + 1 + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-yes + + + True + True + 0 + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Enable + + + True + True + 1 + + + + + + + False + False + 2 + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-no + + + True + True + 0 + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Disable + + + True + True + 1 + + + + + + + False + False + 3 + + - 1 - 2 - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Download speed limit in Kbit/sec: - right - - - - - Enable adaptive rate control - True - True - False - 0 - True - - - - 1 - 2 - 2 - 3 - GTK_FILL - - - - - - True - False - <i>Adaptive rate control is a technique to dynamically guess the available bandwidth during a call.</i> - True - True - - - 2 - 3 - GTK_FILL - + False + True + 1 @@ -2393,17 +2668,17 @@ - + True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - <b>Bandwidth control</b> + <b>Video codecs</b> True - True + False True 1 @@ -2455,6 +2730,7 @@ True False + 10 True @@ -2579,6 +2855,7 @@ True False + 10 True diff --git a/gtk/password.ui b/gtk/password.ui index a355c1848..d9ce720aa 100644 --- a/gtk/password.ui +++ b/gtk/password.ui @@ -9,7 +9,6 @@ True center-on-parent dialog - False True diff --git a/gtk/propertybox.c b/gtk/propertybox.c index 6f4816ece..b996a5378 100644 --- a/gtk/propertybox.c +++ b/gtk/propertybox.c @@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "linphone.h" #include "linphone_tunnel.h" #include "lpconfig.h" +#include "config.h" void linphone_gtk_fill_combo_box(GtkWidget *combo, const char **devices, const char *selected, DeviceCap cap){ const char **p=devices; @@ -153,7 +154,7 @@ static void linphone_gtk_ldap_load_settings(GtkWidget* param) void linphone_gtk_show_ldap_config(GtkWidget* button) { GtkWidget* param = gtk_widget_get_toplevel(button); - GtkWidget* ldap_config = linphone_gtk_create_window("ldap"); + GtkWidget* ldap_config = linphone_gtk_create_window("ldap", param); linphone_gtk_ldap_load_settings(ldap_config); // to refresh parameters when the ldap config is destroyed @@ -266,6 +267,7 @@ void linphone_gtk_fill_video_sizes(GtkWidget *combo){ void linphone_gtk_parameters_closed(GtkWidget *button){ GtkWidget *pb=gtk_widget_get_toplevel(button); gtk_widget_destroy(pb); + linphone_gtk_update_status_bar_icons(); } void linphone_gtk_update_my_contact(GtkWidget *w){ @@ -485,6 +487,26 @@ void linphone_gtk_video_renderer_changed(GtkWidget *w){ } } +void linphone_gtk_video_preset_changed(GtkWidget *w) { + gchar *sel = gtk_combo_box_get_active_text(GTK_COMBO_BOX(w)); + GtkSpinButton *framerate = GTK_SPIN_BUTTON(linphone_gtk_get_widget(gtk_widget_get_toplevel(w), "video_framerate")); + LinphoneCore *lc = linphone_gtk_get_core(); + if (g_strcmp0(sel, "default") == 0) { + linphone_core_set_video_preset(lc, NULL); + gtk_spin_button_set_value(framerate, 0); + gtk_widget_set_sensitive(GTK_WIDGET(framerate), FALSE); + } else if (g_strcmp0(sel, "high-fps") == 0) { + linphone_core_set_video_preset(lc, "high-fps"); + gtk_spin_button_set_value(framerate, 0); + gtk_widget_set_sensitive(GTK_WIDGET(framerate), FALSE); + } else if (g_strcmp0(sel, "custom") == 0) { + linphone_core_set_video_preset(lc, "custom"); + gtk_spin_button_set_value(framerate, 30); + gtk_widget_set_sensitive(GTK_WIDGET(framerate), TRUE); + } + g_free(sel); +} + void linphone_gtk_ring_file_set(GtkWidget *w){ gchar *file=gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(w)); linphone_core_set_ring(linphone_gtk_get_core(),file); @@ -536,9 +558,9 @@ static void bitrate_edited(GtkCellRendererText *renderer, gchar *path, gchar *ne GtkListStore *store=(GtkListStore*)userdata; GtkTreeIter iter; float newbitrate=0; - + if (!new_text) return; - + if (sscanf(new_text, "%f", &newbitrate)!=1) return; if (gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(store),&iter,path)){ @@ -553,6 +575,7 @@ static void linphone_gtk_init_codec_list(GtkTreeView *listview){ GtkCellRenderer *renderer; GtkTreeViewColumn *column; GtkTreeSelection *select; + GValue editable = {0}; GtkListStore *store = gtk_list_store_new (CODEC_NCOLUMNS, G_TYPE_STRING,G_TYPE_INT, G_TYPE_FLOAT, @@ -584,26 +607,34 @@ static void linphone_gtk_init_codec_list(GtkTreeView *listview){ "foreground",CODEC_COLOR, NULL); gtk_tree_view_append_column (listview, column); - column = gtk_tree_view_column_new_with_attributes (_("IP Bitrate (kbit/s)"), - renderer, - "text", CODEC_BITRATE, - "foreground",CODEC_COLOR, - "editable",TRUE, - NULL); + + g_value_init(&editable, G_TYPE_BOOLEAN); + g_value_set_boolean(&editable, TRUE); + + renderer = gtk_cell_renderer_text_new (); + g_object_set_property(G_OBJECT(renderer), "editable", &editable); + column = gtk_tree_view_column_new_with_attributes ( + _("IP Bitrate (kbit/s)"), + renderer, + "text", CODEC_BITRATE, + "foreground",CODEC_COLOR, + NULL); g_signal_connect(G_OBJECT(renderer),"edited",G_CALLBACK(bitrate_edited),store); gtk_tree_view_append_column (listview, column); + renderer = gtk_cell_renderer_text_new (); - column = gtk_tree_view_column_new_with_attributes (_("Parameters"), - renderer, - "text", CODEC_PARAMS, - "foreground",CODEC_COLOR, - "editable",TRUE, - NULL); + g_object_set_property(G_OBJECT(renderer), "editable", &editable); + column = gtk_tree_view_column_new_with_attributes ( + _("Parameters"), + renderer, + "text", CODEC_PARAMS, + "foreground",CODEC_COLOR, + NULL); g_signal_connect(G_OBJECT(renderer),"edited",G_CALLBACK(fmtp_edited),store); gtk_tree_view_append_column (listview, column); /* Setup the selection handler */ select = gtk_tree_view_get_selection (listview); - gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE); + gtk_tree_selection_set_mode (select, GTK_SELECTION_MULTIPLE); } @@ -622,7 +653,7 @@ static void linphone_gtk_show_codecs(GtkTreeView *listview, const MSList *codecl const MSList *elem; GtkTreeIter iter; GtkListStore *store=GTK_LIST_STORE(gtk_tree_view_get_model(listview)); - GtkTreeSelection *selection; +// GtkTreeSelection *selection; gtk_list_store_clear(store); @@ -659,8 +690,8 @@ static void linphone_gtk_show_codecs(GtkTreeView *listview, const MSList *codecl /* Setup the selection handler */ - selection = gtk_tree_view_get_selection (listview); - gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); +// selection = gtk_tree_view_get_selection (listview); +// gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); //gtk_tree_view_columns_autosize(GTK_TREE_VIEW (sec->interfaces)); #if GTK_CHECK_VERSION(2,12,0) gtk_tree_view_set_tooltip_column(listview,CODEC_INFO); @@ -708,24 +739,27 @@ static void linphone_gtk_draw_codec_list(GtkTreeView *v, int type){ /* 0=audio, linphone_gtk_show_codecs(v,list); } -void linphone_gtk_codec_view_changed(GtkWidget *w){ - GtkWidget *listview=linphone_gtk_get_widget(gtk_widget_get_toplevel(w),"codec_list"); - int active=gtk_combo_box_get_active(GTK_COMBO_BOX(w)); - linphone_gtk_draw_codec_list(GTK_TREE_VIEW(listview),active); -} - void linphone_gtk_download_bw_changed(GtkWidget *w){ - GtkTreeView *v=GTK_TREE_VIEW(linphone_gtk_get_widget(gtk_widget_get_toplevel(w),"codec_list")); + GtkTreeView *audiov=GTK_TREE_VIEW(linphone_gtk_get_widget(gtk_widget_get_toplevel(w),"audio_codec_list")); + GtkTreeView *videov=GTK_TREE_VIEW(linphone_gtk_get_widget(gtk_widget_get_toplevel(w),"video_codec_list")); linphone_core_set_download_bandwidth(linphone_gtk_get_core(), (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w))); - linphone_gtk_check_codec_bandwidth(v); + linphone_gtk_check_codec_bandwidth(audiov); + linphone_gtk_check_codec_bandwidth(videov); } void linphone_gtk_upload_bw_changed(GtkWidget *w){ - GtkTreeView *v=GTK_TREE_VIEW(linphone_gtk_get_widget(gtk_widget_get_toplevel(w),"codec_list")); + GtkTreeView *audiov=GTK_TREE_VIEW(linphone_gtk_get_widget(gtk_widget_get_toplevel(w),"audio_codec_list")); + GtkTreeView *videov=GTK_TREE_VIEW(linphone_gtk_get_widget(gtk_widget_get_toplevel(w),"video_codec_list")); linphone_core_set_upload_bandwidth(linphone_gtk_get_core(), (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w))); - linphone_gtk_check_codec_bandwidth(v); + linphone_gtk_check_codec_bandwidth(audiov); + linphone_gtk_check_codec_bandwidth(videov); +} + +void linphone_gtk_video_framerate_changed(GtkWidget *w) { + linphone_core_set_preferred_framerate(linphone_gtk_get_core(), + (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w))); } void linphone_gtk_adaptive_rate_control_toggled(GtkToggleButton *button){ @@ -733,17 +767,32 @@ void linphone_gtk_adaptive_rate_control_toggled(GtkToggleButton *button){ linphone_core_enable_adaptive_rate_control(linphone_gtk_get_core(),active); } -static void linphone_gtk_codec_move(GtkWidget *button, int dir){ - GtkTreeView *v=GTK_TREE_VIEW(linphone_gtk_get_widget(gtk_widget_get_toplevel(button),"codec_list")); - GtkTreeSelection *sel=gtk_tree_view_get_selection(v); +static void _g_list_func_destroy_tree_path(gpointer data, gpointer user_data) { + GtkTreePath *tree_path = (GtkTreePath *)data; + gtk_tree_path_free(tree_path); +} + +static void linphone_gtk_codec_move(GtkWidget *button, int dir, int type){ /* 0=audio, 1=video*/ + GtkTreeView *v; + GtkTreeSelection *sel; GtkTreeModel *mod; GtkTreeIter iter; PayloadType *pt=NULL; LinphoneCore *lc=linphone_gtk_get_core(); - if (gtk_tree_selection_get_selected(sel,&mod,&iter)){ + + if (type == 0) v=GTK_TREE_VIEW(linphone_gtk_get_widget(gtk_widget_get_toplevel(button),"audio_codec_list")); + else v=GTK_TREE_VIEW(linphone_gtk_get_widget(gtk_widget_get_toplevel(button),"video_codec_list")); + sel=gtk_tree_view_get_selection(v); + if (gtk_tree_selection_count_selected_rows(sel) == 1){ MSList *sel_elem,*before; MSList *codec_list; + + GList *selected_rows = gtk_tree_selection_get_selected_rows(sel, &mod); + gtk_tree_model_get_iter(mod, &iter, (GtkTreePath *)g_list_nth_data(selected_rows, 0)); gtk_tree_model_get(mod,&iter,CODEC_PRIVDATA,&pt,-1); + g_list_foreach(selected_rows, _g_list_func_destroy_tree_path, NULL); + g_list_free(selected_rows); + if (pt->type==PAYLOAD_VIDEO) codec_list=ms_list_copy(linphone_core_get_video_codecs(lc)); else codec_list=ms_list_copy(linphone_core_get_audio_codecs(lc)); @@ -767,37 +816,59 @@ static void linphone_gtk_codec_move(GtkWidget *button, int dir){ } } -static void linphone_gtk_codec_set_enable(GtkWidget *button, gboolean enabled){ - GtkTreeView *v=GTK_TREE_VIEW(linphone_gtk_get_widget(gtk_widget_get_toplevel(button),"codec_list")); - GtkTreeSelection *sel=gtk_tree_view_get_selection(v); - GtkTreeModel *mod; - GtkListStore *store; - GtkTreeIter iter; +static void linphone_gtk_codec_set_enable(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { PayloadType *pt=NULL; + gboolean *enabled = (gboolean *)data; + gtk_tree_model_get(model, iter, CODEC_PRIVDATA, &pt, -1); + linphone_core_enable_payload_type(linphone_gtk_get_core(), pt, *enabled); + gtk_list_store_set(GTK_LIST_STORE(model), iter, CODEC_STATUS, *enabled ? _("Enabled") : _("Disabled"), + CODEC_COLOR,(gpointer)get_codec_color(linphone_gtk_get_core(),pt), -1); +} - if (gtk_tree_selection_get_selected(sel,&mod,&iter)){ - store=GTK_LIST_STORE(mod); - gtk_tree_model_get(mod,&iter,CODEC_PRIVDATA,&pt,-1); - linphone_core_enable_payload_type(linphone_gtk_get_core(),pt,enabled); - gtk_list_store_set(store,&iter,CODEC_STATUS, enabled ? _("Enabled") : _("Disabled"), - CODEC_COLOR,(gpointer)get_codec_color(linphone_gtk_get_core(),pt), -1); +static void linphone_gtk_codec_set_enable_all_selected(GtkWidget *button, gboolean enabled, int type){ /* 0=audio, 1=video*/ + GtkTreeView *v; + GtkTreeSelection *sel; + if (type == 0) v=GTK_TREE_VIEW(linphone_gtk_get_widget(gtk_widget_get_toplevel(button),"audio_codec_list")); + else v=GTK_TREE_VIEW(linphone_gtk_get_widget(gtk_widget_get_toplevel(button),"video_codec_list")); + sel=gtk_tree_view_get_selection(v); + gtk_tree_selection_selected_foreach(sel, linphone_gtk_codec_set_enable, &enabled); + if (type == 0){ + /*activating audio and video codecs has consequences on video bandwidth*/ + GtkTreeView *videov=GTK_TREE_VIEW(linphone_gtk_get_widget(gtk_widget_get_toplevel(button),"video_codec_list")); + linphone_gtk_check_codec_bandwidth(videov); } } -void linphone_gtk_codec_up(GtkWidget *button){ - linphone_gtk_codec_move(button,+1); +void linphone_gtk_audio_codec_up(GtkWidget *button){ + linphone_gtk_codec_move(button,+1,0); } -void linphone_gtk_codec_down(GtkWidget *button){ - linphone_gtk_codec_move(button,-1); +void linphone_gtk_audio_codec_down(GtkWidget *button){ + linphone_gtk_codec_move(button,-1,0); } -void linphone_gtk_codec_enable(GtkWidget *button){ - linphone_gtk_codec_set_enable(button,TRUE); +void linphone_gtk_audio_codec_enable(GtkWidget *button){ + linphone_gtk_codec_set_enable_all_selected(button,TRUE,0); } -void linphone_gtk_codec_disable(GtkWidget *button){ - linphone_gtk_codec_set_enable(button,FALSE); +void linphone_gtk_audio_codec_disable(GtkWidget *button){ + linphone_gtk_codec_set_enable_all_selected(button,FALSE,0); +} + +void linphone_gtk_video_codec_up(GtkWidget *button){ + linphone_gtk_codec_move(button,+1,1); +} + +void linphone_gtk_video_codec_down(GtkWidget *button){ + linphone_gtk_codec_move(button,-1,1); +} + +void linphone_gtk_video_codec_enable(GtkWidget *button){ + linphone_gtk_codec_set_enable_all_selected(button,TRUE,1); +} + +void linphone_gtk_video_codec_disable(GtkWidget *button){ + linphone_gtk_codec_set_enable_all_selected(button,FALSE,1); } void linphone_gtk_clear_passwords(GtkWidget *button){ @@ -815,6 +886,9 @@ void linphone_gtk_show_sip_accounts(GtkWidget *w){ GtkTreeModel *model=gtk_tree_view_get_model(v); GtkListStore *store; GtkTreeSelection *select; + const LinphoneProxyConfig *default_pc = linphone_core_get_default_proxy_config(linphone_gtk_get_core()); + GtkTreePath *default_pc_path = NULL; + const MSList *elem; if (!model){ GtkCellRenderer *renderer; @@ -844,6 +918,11 @@ void linphone_gtk_show_sip_accounts(GtkWidget *w){ gtk_list_store_append(store,&iter); gtk_list_store_set(store,&iter,PROXY_CONFIG_IDENTITY,linphone_proxy_config_get_identity(cfg), PROXY_CONFIG_REF,cfg,-1); + if(cfg == default_pc) default_pc_path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter); + } + if(default_pc_path) { + gtk_tree_selection_select_path(gtk_tree_view_get_selection(v), default_pc_path); + gtk_tree_path_free(default_pc_path); } } @@ -929,7 +1008,7 @@ void linphone_gtk_proxy_address_changed(GtkEditable *editable){ } void linphone_gtk_show_proxy_config(GtkWidget *pb, LinphoneProxyConfig *cfg){ - GtkWidget *w=linphone_gtk_create_window("sip_account"); + GtkWidget *w=linphone_gtk_create_window("sip_account", gtk_widget_get_toplevel(pb)); const char *tmp; gboolean is_new=FALSE; @@ -1106,6 +1185,8 @@ static LangCodes supported_langs[]={ { "nb_NO" , N_("Norwegian") }, { "he" , N_("Hebrew") }, { "sr" , N_("Serbian") }, + { "ar" , N_("Arabic") }, + { "tr" , N_("Turkish") }, { NULL , NULL } }; @@ -1130,12 +1211,7 @@ static void linphone_gtk_fill_langs(GtkWidget *pb){ int i=0,index=0; int cur_lang_index=-1; char text[256]={0}; - const char *cur_lang; - #if defined(WIN32) || defined(__APPLE__) - cur_lang=getenv("LANG"); - #else - cur_lang=getenv("LANGUAGE"); - #endif + const char *cur_lang = g_getenv("LANGUAGE"); if (cur_lang==NULL) cur_lang="C"; /* glade creates a combo box without list model and text renderer, unless we fill it with a dummy text. @@ -1157,18 +1233,13 @@ static void linphone_gtk_fill_langs(GtkWidget *pb){ void linphone_gtk_lang_changed(GtkComboBox *combo){ const char *selected=gtk_combo_box_get_active_text(combo); char code[10]; - const char *cur_lang; - #if defined(WIN32) || defined(__APPLE__) - cur_lang=getenv("LANG"); - #else - cur_lang=getenv("LANGUAGE"); - #endif + const char *cur_lang=g_getenv("LANGUAGE"); if (selected!=NULL){ sscanf(selected,"%s",code); if (cur_lang==NULL) cur_lang="C"; if (!lang_equals(cur_lang,code)){ GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(combo))), - GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, "%s", @@ -1185,9 +1256,9 @@ void linphone_gtk_lang_changed(GtkComboBox *combo){ static void linphone_gtk_ui_level_adapt(GtkWidget *top) { gboolean ui_advanced; - const char *simple_ui = linphone_gtk_get_ui_config("simple_ui", "parameters.codec_tab parameters.transport_frame parameters.ports_frame"); + const char *simple_ui = linphone_gtk_get_ui_config("simple_ui", "parameters.codec_tab parameters.transport_frame parameters.ports_frame parameters.bandwidth_frame"); - ui_advanced = linphone_gtk_get_ui_config_int("advanced_ui", TRUE); + ui_advanced = linphone_gtk_get_ui_config_int("advanced_ui", FALSE); if (ui_advanced) { linphone_gtk_visibility_set(simple_ui, "parameters", top, TRUE); } else { @@ -1381,6 +1452,29 @@ void linphone_gtk_fill_video_renderers(GtkWidget *pb){ #endif } +void linphone_gtk_fill_video_presets(GtkWidget *pb) { + GtkComboBox *combo = GTK_COMBO_BOX(linphone_gtk_get_widget(pb, "video_preset")); + const char *preset = linphone_core_get_video_preset(linphone_gtk_get_core()); + if (preset == NULL) { + gtk_combo_box_set_active(combo, -1); + gtk_combo_box_set_active(combo, 0); + } else { + gboolean valid; + GtkTreeIter iter; + gchar *str_data; + GtkTreeModel *model = gtk_combo_box_get_model(combo); + valid = gtk_tree_model_get_iter_first(model, &iter); + while (valid) { + gtk_tree_model_get(model, &iter, 0, &str_data, -1); + if (g_strcmp0(preset, str_data) == 0) { + gtk_combo_box_set_active_iter(combo, &iter); + break; + } + valid = gtk_tree_model_iter_next(model, &iter); + } + } +} + typedef struct { guint timeout_id; LCSipTransports tp; @@ -1402,7 +1496,7 @@ static gboolean apply_transports(PortConfigCtx *ctx){ return FALSE; } -static PortConfigCtx* get_port_config() { +static PortConfigCtx* get_port_config(void) { GtkWidget *mw=linphone_gtk_get_main_window(); PortConfigCtx *cfg=(PortConfigCtx*)g_object_get_data(G_OBJECT(mw),"port_config"); if (cfg==NULL){ @@ -1481,20 +1575,22 @@ void linphone_gtk_show_parameters(void){ const char *tmp; LinphoneAddress *contact; LinphoneFirewallPolicy pol; - GtkWidget *codec_list; + GtkWidget *audio_codec_list; + GtkWidget *video_codec_list; int mtu; int ui_advanced; LCSipTransports tr; int min_port = 0, max_port = 0; if (pb==NULL) { - pb=linphone_gtk_create_window("parameters"); + pb=linphone_gtk_create_window("parameters", linphone_gtk_get_main_window()); g_object_set_data(G_OBJECT(mw),"parameters",pb); }else { gtk_widget_show(pb); return; } - codec_list=linphone_gtk_get_widget(pb,"codec_list"); + audio_codec_list=linphone_gtk_get_widget(pb,"audio_codec_list"); + video_codec_list=linphone_gtk_get_widget(pb,"video_codec_list"); /* NETWORK CONFIG */ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"ipv6_enabled")), @@ -1567,12 +1663,17 @@ void linphone_gtk_show_parameters(void){ linphone_gtk_fill_soundcards(pb); linphone_gtk_fill_webcams(pb); linphone_gtk_fill_video_renderers(pb); + linphone_gtk_fill_video_presets(pb); linphone_gtk_fill_video_sizes(linphone_gtk_get_widget(pb,"video_size")); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"video_framerate")), + linphone_core_get_preferred_framerate(lc)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"echo_cancelation")), linphone_core_echo_cancellation_enabled(lc)); gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(linphone_gtk_get_widget(pb,"ring_chooser")), linphone_core_get_ring(lc)); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"adaptive_rate_control")), + linphone_core_adaptive_rate_control_enabled(lc)); /* SIP CONFIG */ contact=linphone_core_get_primary_contact_parsed(lc); if (contact){ @@ -1591,18 +1692,17 @@ void linphone_gtk_show_parameters(void){ #endif linphone_gtk_show_sip_accounts(pb); /* CODECS CONFIG */ - linphone_gtk_init_codec_list(GTK_TREE_VIEW(codec_list)); - linphone_gtk_draw_codec_list(GTK_TREE_VIEW(codec_list),0); - gtk_combo_box_set_active(GTK_COMBO_BOX(linphone_gtk_get_widget(pb,"codec_view")),0); + linphone_gtk_init_codec_list(GTK_TREE_VIEW(audio_codec_list)); + linphone_gtk_init_codec_list(GTK_TREE_VIEW(video_codec_list)); + linphone_gtk_draw_codec_list(GTK_TREE_VIEW(audio_codec_list), 0); + linphone_gtk_draw_codec_list(GTK_TREE_VIEW(video_codec_list), 1); gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"download_bw")), linphone_core_get_download_bandwidth(lc)); gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"upload_bw")), linphone_core_get_upload_bandwidth(lc)); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"adaptive_rate_control")), - linphone_core_adaptive_rate_control_enabled(lc)); /* CALL PARAMS CONFIG */ - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb, "auto_answer_checkbox")), linphone_gtk_get_ui_config_int("auto_answer", 0)); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb, "auto_answer_checkbox")), linphone_gtk_auto_answer_enabled()); gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb, "auto_answer_delay_spinbutton")), linphone_gtk_get_ui_config_int("auto_answer_delay", 2000)); /* UI CONFIG */ @@ -1667,7 +1767,7 @@ void linphone_gtk_edit_tunnel_closed(GtkWidget *button){ } void linphone_gtk_edit_tunnel(GtkButton *button){ - GtkWidget *w=linphone_gtk_create_window("tunnel_config"); + GtkWidget *w=linphone_gtk_create_window("tunnel_config", gtk_widget_get_toplevel(GTK_WIDGET(button))); LinphoneCore *lc=linphone_gtk_get_core(); LinphoneTunnel *tunnel=linphone_core_get_tunnel(lc); const MSList *configs; @@ -1765,7 +1865,7 @@ static int read_dscp(GtkWidget *entry){ void linphone_gtk_dscp_edit(void){ LinphoneCore *lc=linphone_gtk_get_core(); - GtkWidget *widget=linphone_gtk_create_window("dscp_settings"); + GtkWidget *widget=linphone_gtk_create_window("dscp_settings", linphone_gtk_get_main_window()); show_dscp(linphone_gtk_get_widget(widget,"sip_dscp"), linphone_core_get_sip_dscp(lc)); show_dscp(linphone_gtk_get_widget(widget,"audio_dscp"), @@ -1798,7 +1898,23 @@ void linphone_gtk_enable_auto_answer(GtkToggleButton *checkbox, gpointer user_da linphone_gtk_set_ui_config_int("auto_answer", auto_answer_enabled ? 1 : 0); } +gboolean linphone_gtk_auto_answer_enabled(void) { + return (gboolean)linphone_gtk_get_ui_config_int("auto_answer", 0); +} + void linphone_gtk_auto_answer_delay_changed(GtkSpinButton *spinbutton, gpointer user_data) { int delay = gtk_spin_button_get_value(spinbutton); linphone_gtk_set_ui_config_int("auto_answer_delay", delay); } + +void linphone_gtk_notebook_current_page_changed (GtkNotebook *notebook, GtkWidget *page, guint page_num, gpointer user_data) { +#ifndef HAVE_LIBUDEV_H + if (page_num == 1) { + // Multimedia settings - we reload audio and video devices to detect + // hot-plugged devices + g_message("Opened multimedia page... reloading audio and video devices!"); + linphone_gtk_reload_sound_devices(); + linphone_gtk_reload_video_devices(); + } +#endif +} diff --git a/gtk/regex.h b/gtk/regex.h new file mode 100644 index 000000000..2118447cc --- /dev/null +++ b/gtk/regex.h @@ -0,0 +1,67 @@ +/* +linphone, gtk-glade interface. +Copyright (C) 2015 Belledonne Communications + +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. +*/ + +/* + * Regex matching with any URI that respects the RFC 3986 + */ +#define BC_REGEX_URI_PCT_ENCODED "(%[[:xdigit:]]{2})" +#define BC_REGEX_URI_SUB_DELIMS "[!$&'()*+,;=]" +#define BC_REGEX_URI_UNRESERVED "[[:alnum:]\\-._~]" +#define BC_REGEX_URI_PCHAR "(" BC_REGEX_URI_UNRESERVED "|" BC_REGEX_URI_PCT_ENCODED "|" BC_REGEX_URI_SUB_DELIMS "|" "[:@]" ")" +#define BC_REGEX_URI_SCHEME "(" "[[:alpha:]][[:alnum:]+\\-.]*" ")" +#define BC_REGEX_URI_USERINFO "(" "(" BC_REGEX_URI_UNRESERVED "|" BC_REGEX_URI_PCT_ENCODED "|" BC_REGEX_URI_SUB_DELIMS "|" ":" ")*" ")" +#define BC_REGEX_URI_HOST "(" "(" BC_REGEX_URI_UNRESERVED "|" BC_REGEX_URI_PCT_ENCODED "|" BC_REGEX_URI_SUB_DELIMS ")*" ")" +#define BC_REGEX_URI_PORT "(" "[\\d]*" ")" +#define BC_REGEX_URI_AUTHORITY "(" "(" BC_REGEX_URI_USERINFO "@" ")?" BC_REGEX_URI_HOST "(" ":" BC_REGEX_URI_PORT ")?" ")" +#define BC_REGEX_URI_SEGMENT "(" BC_REGEX_URI_PCHAR "*" ")" +#define BC_REGEX_URI_SEGMENT_NZ "(" BC_REGEX_URI_PCHAR "+" ")" +#define BC_REGEX_URI_PATH_ABEMPTY "(" "(" "/" BC_REGEX_URI_SEGMENT ")*" ")" +#define BC_REGEX_URI_PATH_ABSOLUTE "(" "/" "(" BC_REGEX_URI_SEGMENT_NZ "(" "/" BC_REGEX_URI_SEGMENT ")*" ")?" ")" +#define BC_REGEX_URI_PATH_ROOTLESS "(" BC_REGEX_URI_SEGMENT_NZ "(" "/" BC_REGEX_URI_SEGMENT ")*" ")" +#define BC_REGEX_URI_HIER_PART "(" "//" BC_REGEX_URI_AUTHORITY BC_REGEX_URI_PATH_ABEMPTY "|" BC_REGEX_URI_PATH_ABSOLUTE "|" BC_REGEX_URI_PATH_ROOTLESS ")" +#define BC_REGEX_URI_QUERY "(" "(" BC_REGEX_URI_PCHAR "|" "[/?]" ")*" ")" +#define BC_REGEX_URI_FRAGMENT "(" "(" BC_REGEX_URI_PCHAR "|" "[/?]" ")*" ")" +#define BC_REGEX_URI "(" BC_REGEX_URI_SCHEME ":" BC_REGEX_URI_HIER_PART "(" "\\?" BC_REGEX_URI_QUERY ")?" "(" "#" BC_REGEX_URI_FRAGMENT ")?" ")" + +/* + * Regex matching with any domain name (RFC 1034) + */ +#define BC_REGEX_DOMAIN_LDH "[[:alnum:]-]" +#define BC_REGEX_DOMAIN_LABEL "(" "[[:alpha:]]" "(" BC_REGEX_DOMAIN_LDH "*" "[[:alnum:]]" ")?" ")" +#define BC_REGEX_DOMAIN "(" BC_REGEX_DOMAIN_LABEL "(" "\\." BC_REGEX_DOMAIN_LABEL ")*" ")" + +/* + * Regex matching with email addresses (RFC 5322) + */ +#define BC_REGEX_EMAIL_ATEXT "[[:alnum:]!#$%&'*+\\-/=?\\^_`{}|~]" +#define BC_REGEX_EMAIL_DOT_ATOM_TEXT "(" BC_REGEX_EMAIL_ATEXT "+" "(" "." BC_REGEX_EMAIL_ATEXT "+" ")*" ")" +#define BC_REGEX_EMAIL_LOCAL_PART BC_REGEX_EMAIL_DOT_ATOM_TEXT +#define BC_REGEX_EMAIL_DTEXT_NO_OBS "[!-Z\\^-~]" +#define BC_REGEX_EMAIL_DOMAIN "(" BC_REGEX_EMAIL_DOT_ATOM_TEXT "|" "\\[" BC_REGEX_EMAIL_DTEXT_NO_OBS "*" "\\]" ")" +#define BC_REGEX_EMAIL_ADDR_SPEC "(" BC_REGEX_EMAIL_LOCAL_PART "@" BC_REGEX_EMAIL_DOMAIN ")" + +/* + * Regex matching with email addresses but with more constraints than RFC 5322. + * The additionnal constraints are the folowings: + * + the domain part is a domain name as describe in RFC 1034 + * + the domain part must have two label at least + * + the last label of the domain part must have two letter (without digit and hyphen) at least. + */ +#define BC_REGEX_RESTRICTIVE_EMAIL_TLD "(" "[[:alpha:]]" BC_REGEX_DOMAIN_LDH "*" "[[:alnum:]]" ")" +#define BC_REGEX_RESTRICTIVE_EMAIL_ADDR "(" BC_REGEX_EMAIL_LOCAL_PART "@" "(" BC_REGEX_DOMAIN_LABEL "\\." ")+" BC_REGEX_RESTRICTIVE_EMAIL_TLD ")" diff --git a/gtk/setup_wizard.ui b/gtk/setup_wizard.ui new file mode 100644 index 000000000..337163f3d --- /dev/null +++ b/gtk/setup_wizard.ui @@ -0,0 +1,736 @@ + + + + + + False + 8 + SIP account configuration assistant + False + + + + + + + + + + + + + + + + + + + + + + + + + + + True + False + Welcome! +This assistant will help you to use a SIP account for your calls. + + + intro + Welcome to the account setup assistant + True + + + + + True + False + 20 + 30 + 30 + + + True + False + True + + + Create an account on linphone.org + True + True + False + True + True + + + False + True + 0 + + + + + I have already a linphone.org account and I just want to use it + True + True + False + True + radio_create_account + + + False + True + 1 + + + + + I have already a sip account and I just want to use it + True + True + False + True + radio_create_account + + + False + True + 2 + + + + + I want to specify a remote configuration URI + True + True + False + True + radio_create_account + + + False + True + 3 + + + + + + + Account setup assistant + True + + + + + True + False + 0 + 0 + 0.5 + 30 + 10 + 30 + + + True + False + 6 + 2 + 8 + 4 + + + True + False + 8 + Enter your account information + + + 2 + GTK_FILL + + + + + True + False + 1 + Username* + + + 1 + 2 + GTK_FILL + GTK_FILL + + + + + True + True + + True + False + False + True + True + + + + 1 + 2 + 1 + 2 + GTK_FILL + + + + + True + False + 1 + Password* + + + 2 + 3 + GTK_FILL + GTK_FILL + + + + + True + True + False + + True + False + False + True + True + + + + 1 + 2 + 2 + 3 + GTK_FILL + + + + + True + False + 1 + Domain* + + + 3 + 4 + GTK_FILL + GTK_FILL + + + + + True + True + + True + False + False + True + True + + + + 1 + 2 + 3 + 4 + GTK_FILL + + + + + True + False + 1 + Proxy + + + 4 + 5 + GTK_FILL + GTK_FILL + + + + + True + True + + True + False + False + True + True + + + + 1 + 2 + 4 + 5 + GTK_FILL + GTK_FILL + + + + + True + False + + + + + + 2 + 5 + 6 + GTK_FILL + + + + + + + confirm + Configure your account (step 1/1) + + + + + True + False + 0 + 0.5 + 30 + 10 + 30 + 30 + + + True + False + 8 + 3 + 2 + 8 + 4 + + + True + False + 8 + Enter your linphone.org username + + + 2 + GTK_FILL + + + + + True + False + 1 + Username: + + + 1 + 2 + GTK_FILL + GTK_FILL + + + + + True + True + + True + False + False + True + True + + + + 1 + 2 + 1 + 2 + GTK_FILL + + + + + True + False + 1 + Password: + + + 2 + 3 + GTK_FILL + GTK_FILL + + + + + True + True + False + + True + False + False + True + True + + + 1 + 2 + 2 + 3 + GTK_FILL + + + + + + + confirm + Enter your sip username (step 1/1) + + + + + True + False + 0 + 0.5 + 10 + 10 + 30 + 30 + + + True + False + 8 + 7 + 3 + 8 + 4 + + + True + False + (*) Required fields + + + 3 + 8 + + + + + True + False + 1 + Email: (*) + + + 1 + 2 + GTK_FILL + GTK_FILL + + + + + True + True + + True + False + False + True + True + + + + 1 + 2 + 1 + 2 + GTK_FILL + + + + + True + False + gtk-no + 3 + + + 2 + 3 + 1 + 2 + GTK_FILL + GTK_FILL + + + + + True + False + 1 + Username: (*) + + + 2 + 3 + GTK_FILL + GTK_FILL + + + + + True + True + + True + False + False + True + True + + + + 1 + 2 + 2 + 3 + GTK_FILL + + + + + True + False + gtk-no + 3 + + + 2 + 3 + 2 + 3 + + + + + + + True + False + 1 + Password: (*) + + + 3 + 4 + GTK_FILL + GTK_FILL + + + + + True + True + False + + True + False + False + True + True + + + + 1 + 2 + 3 + 4 + GTK_FILL + + + + + True + False + 1 + Confirm your password: (*) + + + 4 + 5 + GTK_FILL + GTK_FILL + + + + + True + True + False + + True + False + False + True + True + + + + 1 + 2 + 4 + 5 + GTK_FILL + + + + + True + False + gtk-no + 3 + + + 2 + 3 + 3 + 5 + + + + + + + True + False + + + + + + 3 + 5 + 6 + + + + + Keep me informed with linphone updates + True + True + False + True + + + 3 + 6 + 7 + + + + + + + confirm + Enter account information (step 1/2) + + + + + True + False + Your account is being created, please wait. + + + progress + Account creation in progress + + + + + True + False + Please validate your account by clicking on the link we just sent you by email. +Then come back here and press Next button. + + + Validation (step 2/2) + True + + + + + True + False + Checking if your account is been validated, please wait. + + + progress + Account validation check in progress + True + + + + + True + False + Error, account not validated, username already used or server unreachable. +Please go back and try again. + + + Error + + + + + True + False + Thank you. Your account is now configured and ready for use. + + + summary + Terminating + True + + + + diff --git a/gtk/setupwizard.c b/gtk/setupwizard.c index 335062a01..63b6cec6f 100644 --- a/gtk/setupwizard.c +++ b/gtk/setupwizard.c @@ -18,469 +18,74 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "linphone.h" +#include "regex.h" #include #include -static LinphoneAccountCreator *linphone_gtk_assistant_get_creator(GtkWidget*w); static const int PASSWORD_MIN_SIZE = 6; static const int LOGIN_MIN_SIZE = 4; +static GtkWidget *the_assistant = NULL; -static GtkWidget *the_assistant=NULL; -static GtkWidget *create_intro(){ - GtkWidget *vbox=gtk_vbox_new(FALSE,2); - GtkWidget *label=gtk_label_new(_("Welcome!\nThis assistant will help you to use a SIP account for your calls.")); - gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 2); - g_object_set_data(G_OBJECT(vbox),"label",label); - gtk_widget_show_all(vbox); - return vbox; +static LinphoneAccountCreator * linphone_gtk_assistant_get_creator(GtkWidget *w) { + return (LinphoneAccountCreator *)g_object_get_data(G_OBJECT(w), "creator"); } -static GtkWidget *create_setup_signin_choice(){ - GtkWidget *vbox=gtk_vbox_new(FALSE,2); - GtkWidget *t1=gtk_radio_button_new_with_label(NULL,_("Create an account on linphone.org")); - GtkWidget *t2=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(t1),_("I have already a linphone.org account and I just want to use it")); - GtkWidget *t3=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(t1),_("I have already a sip account and I just want to use it")); - GtkWidget *t4=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(t1),_("I want to specify a remote configuration URI")); - - gtk_box_pack_start (GTK_BOX (vbox), t1, TRUE, TRUE, 2); - gtk_box_pack_start (GTK_BOX (vbox), t2, TRUE, TRUE, 2); - gtk_box_pack_start (GTK_BOX (vbox), t3, TRUE, TRUE, 2); - gtk_box_pack_start (GTK_BOX (vbox), t4, TRUE, TRUE, 2); - gtk_widget_show_all(vbox); - g_object_set_data(G_OBJECT(vbox),"create_account",t1); - g_object_set_data(G_OBJECT(vbox),"setup_linphone_account",t2); - g_object_set_data(G_OBJECT(vbox),"setup_account",t3); - g_object_set_data(G_OBJECT(vbox),"config-uri",t4); - return vbox; -} - -static int all_account_information_entered(GtkWidget *w) { - GtkEntry* username = GTK_ENTRY(g_object_get_data(G_OBJECT(w),"username")); - GtkEntry* domain = GTK_ENTRY(g_object_get_data(G_OBJECT(w),"domain")); - - if (gtk_entry_get_text_length(username) > 0 && - gtk_entry_get_text_length(domain) > 0 && - g_regex_match_simple("^[a-zA-Z0-9]+[a-zA-Z0-9.\\-_]{2,}$", gtk_entry_get_text(username), 0, 0) && - g_regex_match_simple("^(sip:)?([a-zA-Z0-9]+([\\.-][a-zA-Z0-9]+)*)$", gtk_entry_get_text(domain), 0, 0)) { - return 1; +static void linphone_gtk_create_account_cb(LinphoneAccountCreator *creator, LinphoneAccountCreatorStatus status) { + GtkWidget *assistant = (GtkWidget *)linphone_account_creator_get_user_data(creator); + if (status == LinphoneAccountCreatorAccountCreated) { + // Go to page_6_linphone_account_validation_wait + gtk_assistant_set_current_page(GTK_ASSISTANT(assistant), 6); + } else { // Error when attempting to create the account + // Go to page_8_error + gtk_assistant_set_current_page(GTK_ASSISTANT(assistant), 8); } - return 0; + gtk_assistant_commit(GTK_ASSISTANT(assistant)); } -static void account_informations_changed(GtkEntry *entry, GtkWidget *w) { - GtkWidget *assistant=gtk_widget_get_toplevel(w); - gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant),w, - all_account_information_entered(w)>0); +static void create_account(GtkWidget *assistant) { + LinphoneAccountCreator *creator = linphone_gtk_assistant_get_creator(assistant); + linphone_account_creator_create_account(creator); } -static void linphone_account_informations_changed(GtkEntry *entry, GtkWidget *w) { - GtkWidget *assistant=gtk_widget_get_toplevel(w); - GtkEntry* username = GTK_ENTRY(g_object_get_data(G_OBJECT(w),"username")); - - gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant),w, - gtk_entry_get_text_length(username) > 0); -} - -static GtkWidget *create_linphone_account_informations_page() { - GtkWidget *vbox=gtk_table_new(3, 2, TRUE); - GtkWidget *label=gtk_label_new(_("Enter your linphone.org username")); - - GdkColor color; - GtkWidget *labelEmpty; - GtkWidget *labelUsername; - GtkWidget *entryUsername; - GtkWidget *labelPassword; - GtkWidget *entryPassword; - - gdk_color_parse ("red", &color); - labelEmpty=gtk_label_new(NULL); - gtk_widget_modify_fg(labelEmpty, GTK_STATE_NORMAL, &color); - - labelUsername=gtk_label_new(_("Username:")); - entryUsername=gtk_entry_new(); - labelPassword=gtk_label_new(_("Password:")); - entryPassword=gtk_entry_new(); - gtk_entry_set_visibility(GTK_ENTRY(entryPassword), FALSE); - - gtk_table_attach_defaults(GTK_TABLE(vbox), label, 0, 2, 0, 1); - gtk_table_attach_defaults(GTK_TABLE(vbox), labelUsername, 0, 1, 1, 2); - gtk_table_attach_defaults(GTK_TABLE(vbox), entryUsername, 1, 2, 1, 2); - gtk_table_attach_defaults(GTK_TABLE(vbox), labelPassword, 0, 1, 2, 3); - gtk_table_attach_defaults(GTK_TABLE(vbox), entryPassword, 1, 2, 2, 3); - - gtk_widget_show_all(vbox); - g_object_set_data(G_OBJECT(vbox),"username",entryUsername); - g_object_set_data(G_OBJECT(vbox),"password",entryPassword); - g_object_set_data(G_OBJECT(vbox),"errorstring",labelEmpty); - g_signal_connect(G_OBJECT(entryUsername),"changed",(GCallback)linphone_account_informations_changed,vbox); - return vbox; -} - -static GtkWidget *create_account_informations_page() { - GtkWidget *vbox=gtk_table_new(6, 2, FALSE); - GtkWidget *label=gtk_label_new(_("Enter your account informations")); - - GdkColor color; - GtkWidget *labelEmpty; - GtkWidget *labelUsername; - GtkWidget *labelPassword; - GtkWidget *entryPassword; - GtkWidget *labelDomain; - GtkWidget *labelProxy; - GtkWidget *entryUsername; - GtkWidget *entryDomain; - GtkWidget *entryRoute; - gdk_color_parse ("red", &color); - labelEmpty=gtk_label_new(NULL); - gtk_widget_modify_fg(labelEmpty, GTK_STATE_NORMAL, &color); - - labelUsername=gtk_label_new(_("Username*")); - labelPassword=gtk_label_new(_("Password*")); - entryPassword=gtk_entry_new(); - gtk_entry_set_visibility(GTK_ENTRY(entryPassword), FALSE); - labelDomain=gtk_label_new(_("Domain*")); - labelProxy=gtk_label_new(_("Proxy")); - entryUsername=gtk_entry_new(); - entryDomain=gtk_entry_new(); - entryRoute=gtk_entry_new(); - - gtk_table_attach_defaults(GTK_TABLE(vbox), label, 0, 2, 0, 1); - gtk_table_attach_defaults(GTK_TABLE(vbox), labelUsername, 0, 1, 1, 2); - gtk_table_attach_defaults(GTK_TABLE(vbox), entryUsername, 1, 2, 1, 2); - gtk_table_attach_defaults(GTK_TABLE(vbox), labelPassword, 0, 1, 2, 3); - gtk_table_attach_defaults(GTK_TABLE(vbox), entryPassword, 1, 2, 2, 3); - gtk_table_attach_defaults(GTK_TABLE(vbox), labelDomain, 0, 1, 3, 4); - gtk_table_attach_defaults(GTK_TABLE(vbox), entryDomain, 1, 2, 3, 4); - gtk_table_attach_defaults(GTK_TABLE(vbox), labelProxy, 0, 1, 4, 5); - gtk_table_attach_defaults(GTK_TABLE(vbox), entryRoute, 1, 2, 4, 5); - gtk_table_attach_defaults(GTK_TABLE(vbox), labelEmpty, 0, 2, 5, 6); - gtk_widget_show_all(vbox); - - g_object_set_data(G_OBJECT(vbox),"username",entryUsername); - g_object_set_data(G_OBJECT(vbox),"password",entryPassword); - g_object_set_data(G_OBJECT(vbox),"domain",entryDomain); - g_object_set_data(G_OBJECT(vbox),"proxy",entryRoute); - g_object_set_data(G_OBJECT(vbox),"errorstring",labelEmpty); - g_signal_connect(G_OBJECT(entryUsername),"changed",(GCallback)account_informations_changed,vbox); - g_signal_connect(G_OBJECT(entryDomain),"changed",(GCallback)account_informations_changed,vbox); - g_signal_connect(G_OBJECT(entryRoute),"changed",(GCallback)account_informations_changed,vbox); - - return vbox; -} - -static int create_account(GtkWidget *page) { - LinphoneAccountCreator *creator=linphone_gtk_assistant_get_creator(gtk_widget_get_toplevel(page)); - LinphoneProxyConfig *res=linphone_account_creator_validate(creator); - if (res) { - if (!g_regex_match_simple("^sip:[a-zA-Z]+[a-zA-Z0-9.\\-_]{2,}@sip.linphone.org$",creator->username, 0, 0)) { - gchar identity[128]; - g_snprintf(identity, sizeof(identity), "sip:%s@sip.linphone.org", creator->username); - linphone_account_creator_set_username(creator, identity); - linphone_account_creator_set_domain(creator, "sip:sip.linphone.org"); - } - return 1; - } - return 0; -} - -static int is_account_information_correct(GtkWidget *w) { - int is_username_available = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w),"is_username_available")); - int is_email_correct = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w),"is_email_correct")); - int is_password_correct = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w),"is_password_correct")); - - if (is_username_available == 1 && is_email_correct == 1 && is_password_correct == 1) { - return 1; - } - return 0; -} - -static void account_email_changed(GtkEntry *entry, GtkWidget *w) { - // Verifying if email entered is correct, and if form is correctly filled, let the user go next page - - GtkEntry* email = GTK_ENTRY(g_object_get_data(G_OBJECT(w),"email")); - GtkImage* isEmailOk = GTK_IMAGE(g_object_get_data(G_OBJECT(w),"emailOk")); - GtkWidget *assistant=gtk_widget_get_toplevel(w); - - if (g_regex_match_simple("^[a-z0-9]+([_\\.-][a-z0-9]+)*@([a-z0-9]+([\\.-][a-z0-9]+)*)+\\.[a-z]{2,}$", gtk_entry_get_text(email), 0, 0)) { - GdkPixbuf *ok = GDK_PIXBUF(g_object_get_data(G_OBJECT(the_assistant), "ok")); - g_object_set_data(G_OBJECT(w),"is_email_correct",GINT_TO_POINTER(1)); - gtk_image_set_from_pixbuf(isEmailOk, ok); - } - else { - GdkPixbuf *notok = GDK_PIXBUF(g_object_get_data(G_OBJECT(the_assistant), "notok")); - g_object_set_data(G_OBJECT(w),"is_email_correct",GINT_TO_POINTER(0)); - gtk_image_set_from_pixbuf(isEmailOk, notok); - } - gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant),w, - is_account_information_correct(w)>0); -} - -static void account_password_changed(GtkEntry *entry, GtkWidget *w) { - // Verifying if passwords entered match, and if form is correctly filled, let the user go next page - - GtkEntry* password = GTK_ENTRY(g_object_get_data(G_OBJECT(w),"password")); - GtkImage* isPasswordOk = GTK_IMAGE(g_object_get_data(G_OBJECT(w),"passwordOk")); - GtkEntry* password_confirm = GTK_ENTRY(g_object_get_data(G_OBJECT(w),"password_confirm")); - GtkWidget *assistant=gtk_widget_get_toplevel(w); - GtkLabel* passwordError = GTK_LABEL(g_object_get_data(G_OBJECT(w),"error")); - - if (gtk_entry_get_text_length(password) >= PASSWORD_MIN_SIZE && - g_ascii_strcasecmp(gtk_entry_get_text(password), gtk_entry_get_text(password_confirm)) == 0) { - GdkPixbuf *ok = GDK_PIXBUF(g_object_get_data(G_OBJECT(the_assistant), "ok")); - g_object_set_data(G_OBJECT(w),"is_password_correct",GINT_TO_POINTER(1)); - gtk_image_set_from_pixbuf(isPasswordOk, ok); - gtk_label_set_text(passwordError, ""); - } - else { - GdkPixbuf *notok = GDK_PIXBUF(g_object_get_data(G_OBJECT(the_assistant), "notok")); - if (gtk_entry_get_text_length(password) < PASSWORD_MIN_SIZE) { - gtk_label_set_text(passwordError, "Password is too short !"); - } - else if (!g_ascii_strcasecmp(gtk_entry_get_text(password), gtk_entry_get_text(password_confirm)) == 0) { - gtk_label_set_text(passwordError, "Passwords don't match !"); - } - g_object_set_data(G_OBJECT(w),"is_password_correct",GINT_TO_POINTER(0)); - gtk_image_set_from_pixbuf(isPasswordOk, notok); - } - gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant),w, - is_account_information_correct(w)>0); -} - -gboolean update_interface_with_username_availability(gpointer *w) { - GtkWidget *assistant = gtk_widget_get_toplevel(GTK_WIDGET(w)); - GtkImage* isUsernameOk = GTK_IMAGE(g_object_get_data(G_OBJECT(w),"usernameOk")); - GtkLabel* usernameError = GTK_LABEL(g_object_get_data(G_OBJECT(w),"error")); - int account_existing = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w),"is_username_used")); - - if (account_existing == 0) { - GdkPixbuf *ok = GDK_PIXBUF(g_object_get_data(G_OBJECT(the_assistant), "ok")); - g_object_set_data(G_OBJECT(w),"is_username_available",GINT_TO_POINTER(1)); - gtk_image_set_from_pixbuf(isUsernameOk, ok); - gtk_label_set_text(usernameError, ""); - } - else { - GdkPixbuf *notok = GDK_PIXBUF(g_object_get_data(G_OBJECT(the_assistant), "notok")); - gtk_label_set_text(usernameError, "Username is already in use !"); - g_object_set_data(G_OBJECT(w),"is_username_available",GINT_TO_POINTER(0)); - gtk_image_set_from_pixbuf(isUsernameOk, notok); - } - - gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant),GTK_WIDGET(w), - is_account_information_correct(GTK_WIDGET(w))>0); - - return FALSE; -} - -void* check_username_availability(void* w) { - LinphoneAccountCreator *creator=linphone_gtk_assistant_get_creator(gtk_widget_get_toplevel(GTK_WIDGET(w))); - - int account_existing = linphone_account_creator_test_existence(creator); - - g_object_set_data(G_OBJECT(w),"is_username_used",GINT_TO_POINTER(account_existing)); - gdk_threads_add_idle((GSourceFunc)update_interface_with_username_availability, (void*)w); - - return NULL; -} - -static void account_username_changed(GtkEntry *entry, GtkWidget *w) { - // Verifying if username choosed is available, and if form is correctly filled, let the user go next page - GtkWidget *assistant = gtk_widget_get_toplevel(GTK_WIDGET(w)); - GtkEntry* username = GTK_ENTRY(g_object_get_data(G_OBJECT(w),"username")); - GtkImage* isUsernameOk = GTK_IMAGE(g_object_get_data(G_OBJECT(w),"usernameOk")); - GtkLabel* usernameError = GTK_LABEL(g_object_get_data(G_OBJECT(w),"error")); - - LinphoneAccountCreator *creator=linphone_gtk_assistant_get_creator(assistant); - linphone_account_creator_set_username(creator, gtk_entry_get_text(username)); - - if (g_regex_match_simple("^[a-zA-Z]+[a-zA-Z0-9.\\-_]{3,}$", gtk_entry_get_text(username), 0, 0)) { -#if !GLIB_CHECK_VERSION(2, 31, 0) - g_thread_create(check_username_availability, (void*)w, FALSE, NULL); -#else - g_thread_new(NULL, check_username_availability, w); -#endif - } - else { - GdkPixbuf *notok = GDK_PIXBUF(g_object_get_data(G_OBJECT(the_assistant), "notok")); - if (gtk_entry_get_text_length(username) < LOGIN_MIN_SIZE) { - gtk_label_set_text(usernameError, "Username is too short"); - } - else if (!g_regex_match_simple("^[a-zA-Z]+[a-zA-Z0-9.\\-_]{3,}$", gtk_entry_get_text(username), 0, 0)) { - gtk_label_set_text(usernameError, "Unauthorized username"); - } - g_object_set_data(G_OBJECT(w),"is_username_available",GINT_TO_POINTER(0)); - gtk_image_set_from_pixbuf(isUsernameOk, notok); - - gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant),w, - is_account_information_correct(w)>0); +static void linphone_gtk_test_account_validation_cb(LinphoneAccountCreator *creator, LinphoneAccountCreatorStatus status) { + GtkWidget *assistant = (GtkWidget *)linphone_account_creator_get_user_data(creator); + if (status == LinphoneAccountCreatorAccountValidated) { + // Go to page_9_finish + gtk_assistant_set_current_page(GTK_ASSISTANT(assistant), 9); + } else { + // Go to page_8_error + gtk_assistant_set_current_page(GTK_ASSISTANT(assistant), 8); } } -static GtkWidget *create_account_information_page() { - GtkWidget *vbox=gtk_table_new(7, 3, FALSE); - GdkPixbuf *notok = GDK_PIXBUF(g_object_get_data(G_OBJECT(the_assistant), "notok")); - GtkWidget *label=gtk_label_new(_("(*) Required fields")); - GtkWidget *labelUsername=gtk_label_new(_("Username: (*)")); - GtkWidget *isUsernameOk=gtk_image_new_from_pixbuf(notok); - GtkWidget *labelPassword=gtk_label_new(_("Password: (*)")); - GtkWidget *isPasswordOk=gtk_image_new_from_pixbuf(notok); - GtkWidget *labelEmail=gtk_label_new(_("Email: (*)")); - GtkWidget *isEmailOk=gtk_image_new_from_pixbuf(notok); - GtkWidget *labelPassword2=gtk_label_new(_("Confirm your password: (*)")); - GtkWidget *entryUsername=gtk_entry_new(); - GtkWidget *entryPassword=gtk_entry_new(); - GtkWidget *entryEmail; - GtkWidget *entryPassword2; - GtkWidget *checkNewsletter; - GtkWidget *labelError; - GtkWidget *passwordVbox1; - GtkWidget *passwordVbox2; - GdkColor color; - gtk_entry_set_visibility(GTK_ENTRY(entryPassword), FALSE); - entryEmail=gtk_entry_new(); - entryPassword2=gtk_entry_new(); - gtk_entry_set_visibility(GTK_ENTRY(entryPassword2), FALSE); - checkNewsletter=gtk_check_button_new_with_label(_("Keep me informed with linphone updates")); - - gdk_color_parse ("red", &color); - labelError=gtk_label_new(NULL); - gtk_widget_modify_fg(labelError, GTK_STATE_NORMAL, &color); - - passwordVbox1=gtk_vbox_new(FALSE,2); - passwordVbox2=gtk_vbox_new(FALSE,2); - gtk_box_pack_start (GTK_BOX (passwordVbox1), labelPassword, TRUE, FALSE, 2); - gtk_box_pack_start (GTK_BOX (passwordVbox1), labelPassword2, TRUE, FALSE, 2); - gtk_box_pack_start (GTK_BOX (passwordVbox2), entryPassword, TRUE, FALSE, 2); - gtk_box_pack_start (GTK_BOX (passwordVbox2), entryPassword2, TRUE, FALSE, 2); - - gtk_table_attach_defaults(GTK_TABLE(vbox), label, 0, 3, 0, 1); - gtk_table_attach_defaults(GTK_TABLE(vbox), labelEmail, 0, 1, 1, 2); - gtk_table_attach_defaults(GTK_TABLE(vbox), entryEmail, 1, 2, 1, 2); - gtk_table_attach_defaults(GTK_TABLE(vbox), isEmailOk, 2, 3, 1, 2); - gtk_table_attach_defaults(GTK_TABLE(vbox), labelUsername, 0, 1, 2, 3); - gtk_table_attach_defaults(GTK_TABLE(vbox), entryUsername, 1, 2, 2, 3); - gtk_table_attach_defaults(GTK_TABLE(vbox), isUsernameOk, 2, 3, 2, 3); - gtk_table_attach_defaults(GTK_TABLE(vbox), passwordVbox1, 0, 1, 3, 4); - gtk_table_attach_defaults(GTK_TABLE(vbox), passwordVbox2, 1, 2, 3, 4); - gtk_table_attach_defaults(GTK_TABLE(vbox), isPasswordOk, 2, 3, 3, 4); - gtk_table_attach_defaults(GTK_TABLE(vbox), labelError, 1, 4, 5, 6); - gtk_table_attach_defaults(GTK_TABLE(vbox), checkNewsletter, 0, 3, 6, 7); - - gtk_widget_show_all(vbox); - g_object_set_data(G_OBJECT(vbox),"username",entryUsername); - g_object_set_data(G_OBJECT(vbox),"password",entryPassword); - g_object_set_data(G_OBJECT(vbox),"email",entryEmail); - g_object_set_data(G_OBJECT(vbox),"usernameOk",isUsernameOk); - g_object_set_data(G_OBJECT(vbox),"passwordOk",isPasswordOk); - g_object_set_data(G_OBJECT(vbox),"emailOk",isEmailOk); - g_object_set_data(G_OBJECT(vbox),"password_confirm",entryPassword2); - g_object_set_data(G_OBJECT(vbox),"newsletter",checkNewsletter); - g_object_set_data(G_OBJECT(vbox),"error",labelError); - g_signal_connect(G_OBJECT(entryUsername),"changed",(GCallback)account_username_changed,vbox); - g_signal_connect(G_OBJECT(entryPassword),"changed",(GCallback)account_password_changed,vbox); - g_signal_connect(G_OBJECT(entryEmail),"changed",(GCallback)account_email_changed,vbox); - g_signal_connect(G_OBJECT(entryPassword2),"changed",(GCallback)account_password_changed,vbox); - return vbox; +static void check_account_validation(GtkWidget *assistant) { + LinphoneAccountCreator *creator = linphone_gtk_assistant_get_creator(assistant); + linphone_account_creator_test_validation(creator); } -/* -static GtkWidget *create_confirmation_page(){ - GtkWidget *vbox=gtk_vbox_new(FALSE,2); - GtkWidget *label=gtk_label_new(NULL); - gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 2); - g_object_set_data(G_OBJECT(vbox),"label",label); - gtk_widget_show_all(vbox); - return vbox; -} -*/ - -static GtkWidget *create_error_page(){ - GtkWidget *vbox=gtk_table_new(2, 1, FALSE); - GtkWidget *label=gtk_label_new(_("Error, account not validated, username already used or server unreachable.\nPlease go back and try again.")); - - gtk_table_attach(GTK_TABLE(vbox), label, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND, 0, 100); - - g_object_set_data(G_OBJECT(vbox),"label",label); - gtk_widget_show_all(vbox); - return vbox; -} - -static GtkWidget *create_finish_page(){ - GtkWidget *vbox=gtk_vbox_new(FALSE,2); - GtkWidget *label=gtk_label_new(_("Thank you. Your account is now configured and ready for use.")); - gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 2); - gtk_widget_show_all(vbox); - return vbox; -} - -static GtkWidget *wait_for_activation() { - GtkWidget *vbox=gtk_table_new(2, 1, FALSE); - GtkWidget *label=gtk_label_new(_("Please validate your account by clicking on the link we just sent you by email.\n" - "Then come back here and press Next button.")); - - gtk_table_attach(GTK_TABLE(vbox), label, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND, 0, 100); - - g_object_set_data(G_OBJECT(vbox),"label",label); - gtk_widget_show_all(vbox); - return vbox; -} - -static int is_account_validated(GtkWidget *page) { - LinphoneAccountCreator *creator=linphone_gtk_assistant_get_creator(gtk_widget_get_toplevel(page)); - return linphone_account_creator_test_validation(creator); -} - -static void linphone_gtk_assistant_closed(GtkWidget *w){ +void linphone_gtk_assistant_closed(GtkWidget *w) { linphone_gtk_close_assistant(); } -static void linphone_gtk_assistant_prepare(GtkWidget *assistant, GtkWidget *page){ - int pagenum=gtk_assistant_get_current_page(GTK_ASSISTANT(assistant)); +void linphone_gtk_assistant_prepare(GtkWidget *assistant) { + int pagenum = gtk_assistant_get_current_page(GTK_ASSISTANT(assistant)); - if (pagenum == 5) { - gtk_assistant_commit(GTK_ASSISTANT(assistant)); - } else if (pagenum == gtk_assistant_get_n_pages(GTK_ASSISTANT(assistant)) - 1) { - LinphoneAddress *identity; - LinphoneAuthInfo *info; - // Saving the account and making it default - LinphoneAccountCreator *creator=linphone_gtk_assistant_get_creator(assistant); - LinphoneProxyConfig *cfg=linphone_proxy_config_new(); - linphone_proxy_config_set_identity(cfg, creator->username); - linphone_proxy_config_set_server_addr(cfg, creator->domain); - linphone_proxy_config_set_route(cfg, creator->route); - linphone_proxy_config_set_expires(cfg, 3600); - linphone_proxy_config_enable_publish(cfg, FALSE); - linphone_proxy_config_enable_register(cfg, TRUE); - - identity = linphone_address_new(creator->username); - info=linphone_auth_info_new(linphone_address_get_username(identity), NULL, creator->password, NULL, NULL, linphone_address_get_domain(identity)); - linphone_core_add_auth_info(linphone_gtk_get_core(),info); - linphone_address_destroy(identity); - - if (strcmp(creator->domain, "sip:sip.linphone.org") == 0) { - linphone_proxy_config_enable_avpf(cfg,TRUE); - // If account created on sip.linphone.org, we configure linphone to use TLS by default - if (linphone_core_sip_transport_supported(linphone_gtk_get_core(),LinphoneTransportTls)) { - LinphoneAddress *addr=linphone_address_new(creator->domain); - char *tmp; - linphone_address_set_transport(addr, LinphoneTransportTls); - tmp=linphone_address_as_string(addr); - linphone_proxy_config_set_server_addr(cfg,tmp); - linphone_proxy_config_set_route(cfg,tmp); - ms_free(tmp); - linphone_address_destroy(addr); + switch (pagenum) { + case 5: + create_account(assistant); + break; + case 7: + check_account_validation(assistant); + break; + case 9: + if (linphone_account_creator_configure(linphone_gtk_assistant_get_creator(assistant)) != NULL) { + linphone_gtk_load_identities(); } - linphone_core_set_stun_server(linphone_gtk_get_core(), "stun.linphone.org"); - linphone_core_set_firewall_policy(linphone_gtk_get_core(), LinphonePolicyUseIce); - } - - if (linphone_core_add_proxy_config(linphone_gtk_get_core(),cfg)==-1) - return; - - linphone_core_set_default_proxy(linphone_gtk_get_core(),cfg); - linphone_gtk_load_identities(); - - + gtk_assistant_commit(GTK_ASSISTANT(assistant)); + break; + default: + break; } } @@ -490,187 +95,262 @@ static gint destroy_assistant(GtkWidget* w){ return FALSE; } -static int linphone_gtk_assistant_forward(int curpage, gpointer data){ - GtkWidget *w=(GtkWidget*)data; - GtkWidget *box=gtk_assistant_get_nth_page(GTK_ASSISTANT(w),curpage); - if (curpage==1){ - GtkWidget *create_button=(GtkWidget*)g_object_get_data(G_OBJECT(box),"create_account"); - GtkWidget *setup_linphone_account=(GtkWidget*)g_object_get_data(G_OBJECT(box),"setup_linphone_account"); - GtkWidget *setup_account=(GtkWidget*)g_object_get_data(G_OBJECT(box),"setup_account"); - GtkWidget *config_uri=(GtkWidget*)g_object_get_data(G_OBJECT(box),"config-uri"); +static int linphone_gtk_assistant_forward(int curpage, gpointer data) { + GtkWidget *w = GTK_WIDGET(data); + LinphoneAccountCreator *creator = linphone_gtk_assistant_get_creator(w); - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(create_button))) { - curpage += 3; // Going to P33 - } - else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(setup_linphone_account))) { - curpage += 2; // Going to P32 - } - else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(setup_account))) { - curpage += 1; // Going to P31 - } - else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(config_uri))) { - /*destroy the assistant and popup config-uri dialog*/ - gtk_widget_hide(w); - linphone_gtk_set_configuration_uri(); - curpage=0; - g_idle_add((GSourceFunc)destroy_assistant,w); - } - } - else if (curpage == 2) { // Account's informations entered - LinphoneAccountCreator *c=linphone_gtk_assistant_get_creator(w); - gchar identity[128]; - gchar proxy[128]; - g_snprintf(identity, sizeof(identity), "sip:%s@%s", gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"username"))), gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"domain")))); + switch (curpage) { + case 0: + curpage = 1; // Go to page_1_choice + break; + case 1: + { + GtkWidget *create_button = linphone_gtk_get_widget(w, "radio_create_account"); + GtkWidget *setup_linphone_account = linphone_gtk_get_widget(w, "radio_setup_lp_account"); + GtkWidget *setup_account = linphone_gtk_get_widget(w, "radio_setup_account"); + GtkWidget *config_uri = linphone_gtk_get_widget(w, "radio_config_uri"); - g_snprintf(proxy, sizeof(proxy), "sip:%s", gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"domain")))); - - linphone_account_creator_set_username(c, identity); - linphone_account_creator_set_domain(c, proxy); - linphone_account_creator_set_route(c, gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"proxy")))); - linphone_account_creator_set_password(c,gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"password")))); - curpage = gtk_assistant_get_n_pages(GTK_ASSISTANT(w)) - 1; // Going to the last page - } - else if (curpage == 3) { // Linphone Account's informations entered - LinphoneAccountCreator *c=linphone_gtk_assistant_get_creator(w); - gchar identity[128]; - g_snprintf(identity, sizeof(identity), "sip:%s@sip.linphone.org", gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"username")))); - linphone_account_creator_set_username(c, identity); - linphone_account_creator_set_domain(c, "sip:sip.linphone.org"); - linphone_account_creator_set_password(c,gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"password")))); - curpage = gtk_assistant_get_n_pages(GTK_ASSISTANT(w)) - 1; // Going to the last page - } - else if (curpage == 4) { // Password & Email entered - LinphoneAccountCreator *c=linphone_gtk_assistant_get_creator(w); - linphone_account_creator_set_username(c, gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"username")))); - linphone_account_creator_set_password(c,gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"password")))); - linphone_account_creator_set_email(c,gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"email")))); - linphone_account_creator_set_suscribe(c,gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(g_object_get_data(G_OBJECT(box),"newsletter")))); - if (create_account(w) == 1) { - curpage += 1; - } else { // Error when attempting to create the account - curpage += 2; + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(create_button))) { + curpage = 4; // Go to page_4_linphone_account_creation_configuration + } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(setup_linphone_account))) { + curpage = 3; // Go to page_3_linphone_account_configuration + } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(setup_account))) { + curpage = 2; // Go to page_2_external_account_configuration + } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(config_uri))) { + /* Destroy the assistant and popup config-uri dialog */ + gtk_widget_hide(w); + linphone_gtk_set_configuration_uri(); + curpage = 0; + g_idle_add((GSourceFunc)destroy_assistant, w); + } + } + break; + case 2: + { + GtkEntry *username_entry = GTK_ENTRY(linphone_gtk_get_widget(w, "p2_entry_username")); + GtkEntry *domain_entry = GTK_ENTRY(linphone_gtk_get_widget(w, "p2_entry_domain")); + GtkEntry *proxy_entry = GTK_ENTRY(linphone_gtk_get_widget(w, "p2_entry_proxy")); + GtkEntry *password_entry = GTK_ENTRY(linphone_gtk_get_widget(w, "p2_entry_password")); + linphone_account_creator_set_username(creator, gtk_entry_get_text(username_entry)); + linphone_account_creator_set_domain(creator, gtk_entry_get_text(domain_entry)); + linphone_account_creator_set_route(creator, gtk_entry_get_text(proxy_entry)); + linphone_account_creator_set_password(creator, gtk_entry_get_text(password_entry)); + curpage = 9; // Go to page_9_finish + break; } - } - else if (curpage == 5) { // Waiting for account validation - if (is_account_validated(w) == 1) { - curpage += 2; // Going to the last page - } else { - curpage += 1; + case 3: + { + GtkEntry *username_entry = GTK_ENTRY(linphone_gtk_get_widget(w, "p3_entry_username")); + GtkEntry *password_entry = GTK_ENTRY(linphone_gtk_get_widget(w, "p3_entry_password")); + linphone_account_creator_set_username(creator, gtk_entry_get_text(username_entry)); + linphone_account_creator_set_domain(creator, "sip.linphone.org"); + linphone_account_creator_set_route(creator, "sip.linphone.org"); + linphone_account_creator_set_password(creator, gtk_entry_get_text(password_entry)); + curpage = 9; // Go to page_9_finish + break; } - } - else { - curpage += 1; + case 4: + { + GtkEntry *password_entry = GTK_ENTRY(linphone_gtk_get_widget(w, "p4_entry_password1")); + GtkEntry *username_entry = GTK_ENTRY(linphone_gtk_get_widget(w, "p4_entry_username")); + GtkEntry *email_entry = GTK_ENTRY(linphone_gtk_get_widget(w, "p4_entry_email")); + GtkToggleButton *newsletter = GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w, "p4_check_newsletter")); + linphone_account_creator_set_username(creator, gtk_entry_get_text(username_entry)); + linphone_account_creator_set_password(creator, gtk_entry_get_text(password_entry)); + linphone_account_creator_set_email(creator, gtk_entry_get_text(email_entry)); + linphone_account_creator_enable_newsletter_subscription(creator, gtk_toggle_button_get_active(newsletter)); + curpage = 5; // Go to page_5_linphone_account_creation_in_progress + break; + } + case 6: + curpage = 7; // Go to page_7_linphone_account_validation_check_in_progress + break; + default: + break; } return curpage; } -static LinphoneAccountCreator * linphone_gtk_assistant_init(GtkWidget *w){ - const MSList *elem; - LinphoneCore *lc=linphone_gtk_get_core(); - for(elem=linphone_core_get_sip_setups(lc);elem!=NULL;elem=elem->next){ - SipSetup *ss=(SipSetup*)elem->data; - if (sip_setup_get_capabilities(ss) & SIP_SETUP_CAP_ACCOUNT_MANAGER){ - LinphoneAccountCreator *creator=linphone_account_creator_new(lc,ss->name); - g_object_set_data(G_OBJECT(w),"creator",creator); - return creator; - } +static int external_account_configuration_complete(GtkWidget *page) { + GtkWidget *assistant = gtk_widget_get_toplevel(page); + GtkEntry* username = GTK_ENTRY(linphone_gtk_get_widget(assistant, "p2_entry_username")); + GtkEntry* domain = GTK_ENTRY(linphone_gtk_get_widget(assistant, "p2_entry_domain")); + + if ((gtk_entry_get_text_length(username) > 0) + && (gtk_entry_get_text_length(domain) > 0) + && (g_regex_match_simple("^[a-zA-Z0-9+]+[a-zA-Z0-9.\\+\\-_]{2,}$", gtk_entry_get_text(username), 0, 0)) + && (g_regex_match_simple("^(sip:)?([a-zA-Z0-9\\+]+([\\.-][a-zA-Z0-9+]+)*)$", gtk_entry_get_text(domain), 0, 0))) { + return 1; } - return NULL; + return 0; } -static LinphoneAccountCreator *linphone_gtk_assistant_get_creator(GtkWidget*w){ - return (LinphoneAccountCreator*)g_object_get_data(G_OBJECT(w),"creator"); +void linphone_gtk_external_account_configuration_changed(GtkEntry *entry) { + GtkWidget *assistant = gtk_widget_get_toplevel(GTK_WIDGET(entry)); + gint current_page_num = gtk_assistant_get_current_page(GTK_ASSISTANT(assistant)); + GtkWidget *page = gtk_assistant_get_nth_page(GTK_ASSISTANT(assistant), current_page_num); + gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant), page, external_account_configuration_complete(page) > 0); } -void linphone_gtk_close_assistant(void){ - if(the_assistant==NULL) +void linphone_gtk_account_configuration_changed(GtkEntry *entry, GtkAssistant *assistant) { + gboolean complete = (gtk_entry_get_text_length(entry) > 0); + GtkWidget *page = gtk_assistant_get_nth_page(assistant, gtk_assistant_get_current_page(assistant)); + gtk_assistant_set_page_complete(assistant, page, complete); +} + +static gboolean linphone_account_creation_configuration_correct(GtkWidget *w) { + gint is_username_available = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w), "is_username_available")); + gint is_email_correct = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w), "is_email_correct")); + gint is_password_correct = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w), "is_password_correct")); + return (is_username_available && is_email_correct && is_password_correct); +} + +static gboolean update_interface_with_username_availability(GtkWidget *page) { + GtkWidget *assistant = gtk_widget_get_toplevel(page); + GtkImage* isUsernameOk = GTK_IMAGE(linphone_gtk_get_widget(assistant, "p4_image_username_ok")); + GtkLabel* usernameError = GTK_LABEL(linphone_gtk_get_widget(assistant, "p4_label_error")); + int account_status = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(page), "is_username_used")); + + if (account_status == LinphoneAccountCreatorAccountNotExist) { + g_object_set_data(G_OBJECT(page), "is_username_available", GINT_TO_POINTER(1)); + gtk_image_set_from_stock(isUsernameOk, GTK_STOCK_OK, GTK_ICON_SIZE_LARGE_TOOLBAR); + gtk_label_set_text(usernameError, ""); + } else if (account_status == LinphoneAccountCreatorAccountExist) { + gtk_label_set_text(usernameError, _("Username is already in use!")); + g_object_set_data(G_OBJECT(page), "is_username_available", GINT_TO_POINTER(0)); + gtk_image_set_from_stock(isUsernameOk, GTK_STOCK_NO, GTK_ICON_SIZE_LARGE_TOOLBAR); + } else { + gtk_label_set_text(usernameError, _("Failed to check username availability. Please try again later.")); + g_object_set_data(G_OBJECT(page), "is_username_available", GINT_TO_POINTER(0)); + gtk_image_set_from_stock(isUsernameOk, GTK_STOCK_NO, GTK_ICON_SIZE_LARGE_TOOLBAR); + } + gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant), page, linphone_account_creation_configuration_correct(page) > 0); + return FALSE; +} + +static void linphone_gtk_test_account_existence_cb(LinphoneAccountCreator *creator, LinphoneAccountCreatorStatus status) { + GtkWidget *assistant = (GtkWidget *)linphone_account_creator_get_user_data(creator); + GtkWidget *page = gtk_assistant_get_nth_page(GTK_ASSISTANT(assistant), gtk_assistant_get_current_page(GTK_ASSISTANT(assistant))); + g_object_set_data(G_OBJECT(page), "is_username_used", GINT_TO_POINTER(status)); + gdk_threads_add_idle((GSourceFunc)update_interface_with_username_availability, page); +} + +static gboolean check_username_availability(GtkWidget *assistant) { + LinphoneAccountCreator *creator = linphone_gtk_assistant_get_creator(assistant); + GtkWidget *page = gtk_assistant_get_nth_page(GTK_ASSISTANT(assistant), gtk_assistant_get_current_page(GTK_ASSISTANT(assistant))); + g_object_set_data(G_OBJECT(page), "usernameAvailabilityTimerID", GUINT_TO_POINTER(0)); + linphone_account_creator_test_existence(creator); + return FALSE; +} + +void linphone_gtk_account_creation_username_changed(GtkEntry *entry) { + GtkWidget *assistant = gtk_widget_get_toplevel(GTK_WIDGET(entry)); + GtkEntry* username = GTK_ENTRY(linphone_gtk_get_widget(assistant, "p4_entry_username")); + GtkImage* isUsernameOk = GTK_IMAGE(linphone_gtk_get_widget(assistant, "p4_image_username_ok")); + GtkLabel* usernameError = GTK_LABEL(linphone_gtk_get_widget(assistant, "p4_label_error")); + gint current_page_num = gtk_assistant_get_current_page(GTK_ASSISTANT(assistant)); + GtkWidget *page = gtk_assistant_get_nth_page(GTK_ASSISTANT(assistant), current_page_num); + + LinphoneAccountCreator *creator = linphone_gtk_assistant_get_creator(assistant); + linphone_account_creator_set_username(creator, gtk_entry_get_text(username)); + linphone_account_creator_set_domain(creator, "sip.linphone.org"); + linphone_account_creator_set_route(creator, "sip.linphone.org"); + + if (g_regex_match_simple("^[a-zA-Z]+[a-zA-Z0-9.\\-_]{3,}$", gtk_entry_get_text(username), 0, 0)) { + guint timerID = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(page), "usernameAvailabilityTimerID")); + if (timerID > 0) { + g_source_remove(timerID); + } + timerID = g_timeout_add(500, (GSourceFunc)check_username_availability, assistant); + g_object_set_data(G_OBJECT(page), "usernameAvailabilityTimerID", GUINT_TO_POINTER(timerID)); + } else { + if (gtk_entry_get_text_length(username) < LOGIN_MIN_SIZE) { + gtk_label_set_text(usernameError, "Username is too short"); + } else if (!g_regex_match_simple("^[a-zA-Z]+[a-zA-Z0-9.\\-_]{3,}$", gtk_entry_get_text(username), 0, 0)) { + gtk_label_set_text(usernameError, "Unauthorized username"); + } + g_object_set_data(G_OBJECT(page), "is_username_available", GINT_TO_POINTER(0)); + gtk_image_set_from_stock(isUsernameOk, GTK_STOCK_NO, GTK_ICON_SIZE_LARGE_TOOLBAR); + gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant), page, linphone_account_creation_configuration_correct(page) > 0); + } +} + +void linphone_gtk_account_creation_email_changed(GtkEntry *entry) { + GtkWidget *assistant = gtk_widget_get_toplevel(GTK_WIDGET(entry)); + GtkEntry* email = GTK_ENTRY(linphone_gtk_get_widget(assistant, "p4_entry_email")); + GtkImage* isEmailOk = GTK_IMAGE(linphone_gtk_get_widget(assistant, "p4_image_email_ok")); + gint current_page_num = gtk_assistant_get_current_page(GTK_ASSISTANT(assistant)); + GtkWidget *page = gtk_assistant_get_nth_page(GTK_ASSISTANT(assistant), current_page_num); + + if (g_regex_match_simple("^" BC_REGEX_RESTRICTIVE_EMAIL_ADDR "$", gtk_entry_get_text(email), 0, 0)) { + g_object_set_data(G_OBJECT(page), "is_email_correct", GINT_TO_POINTER(1)); + gtk_image_set_from_stock(isEmailOk, GTK_STOCK_OK, GTK_ICON_SIZE_LARGE_TOOLBAR); + } else { + g_object_set_data(G_OBJECT(page), "is_email_correct", GINT_TO_POINTER(0)); + gtk_image_set_from_stock(isEmailOk, GTK_STOCK_NO, GTK_ICON_SIZE_LARGE_TOOLBAR); + } + gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant), page, linphone_account_creation_configuration_correct(page) > 0); +} + +void linphone_gtk_account_creation_password_changed(GtkEntry *entry) { + GtkWidget *assistant = gtk_widget_get_toplevel(GTK_WIDGET(entry)); + GtkEntry* password = GTK_ENTRY(linphone_gtk_get_widget(assistant, "p4_entry_password1")); + GtkEntry* password_confirm = GTK_ENTRY(linphone_gtk_get_widget(assistant, "p4_entry_password2")); + GtkImage* isPasswordOk = GTK_IMAGE(linphone_gtk_get_widget(assistant, "p4_image_password_ok")); + GtkLabel* passwordError = GTK_LABEL(linphone_gtk_get_widget(assistant, "p4_label_error")); + gint current_page_num = gtk_assistant_get_current_page(GTK_ASSISTANT(assistant)); + GtkWidget *page = gtk_assistant_get_nth_page(GTK_ASSISTANT(assistant), current_page_num); + + if ((gtk_entry_get_text_length(password) >= PASSWORD_MIN_SIZE) + && (g_ascii_strcasecmp(gtk_entry_get_text(password), gtk_entry_get_text(password_confirm)) == 0)) { + g_object_set_data(G_OBJECT(page), "is_password_correct", GINT_TO_POINTER(1)); + gtk_image_set_from_stock(isPasswordOk, GTK_STOCK_OK, GTK_ICON_SIZE_LARGE_TOOLBAR); + gtk_label_set_text(passwordError, ""); + } else { + if (gtk_entry_get_text_length(password) < PASSWORD_MIN_SIZE) { + gtk_label_set_text(passwordError, "Password is too short !"); + } else if (!g_ascii_strcasecmp(gtk_entry_get_text(password), gtk_entry_get_text(password_confirm)) == 0) { + gtk_label_set_text(passwordError, "Passwords don't match !"); + } + g_object_set_data(G_OBJECT(page), "is_password_correct", GINT_TO_POINTER(0)); + gtk_image_set_from_stock(isPasswordOk, GTK_STOCK_NO, GTK_ICON_SIZE_LARGE_TOOLBAR); + } + gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant), page, linphone_account_creation_configuration_correct(page) > 0); +} + +static void linphone_gtk_assistant_init(GtkWidget *w) { + LinphoneAccountCreator *creator = linphone_account_creator_new(linphone_gtk_get_core(), "https://www.linphone.org/wizard.php"); + LinphoneAccountCreatorCbs *cbs = linphone_account_creator_get_callbacks(creator); + linphone_account_creator_set_user_data(creator, w); + linphone_account_creator_cbs_set_existence_tested(cbs, linphone_gtk_test_account_existence_cb); + linphone_account_creator_cbs_set_validation_tested(cbs, linphone_gtk_test_account_validation_cb); + linphone_account_creator_cbs_set_create_account(cbs, linphone_gtk_create_account_cb); + g_object_set_data(G_OBJECT(w), "creator", creator); + + gtk_assistant_set_forward_page_func(GTK_ASSISTANT(w), linphone_gtk_assistant_forward, w, NULL); +} + +void linphone_gtk_show_assistant(void) { + if (the_assistant != NULL) return; + the_assistant = linphone_gtk_create_window("setup_wizard", linphone_gtk_get_main_window()); + linphone_gtk_assistant_init(the_assistant); + gtk_widget_show(the_assistant); +} + +void linphone_gtk_close_assistant(void) { + GtkWidget *mw; + if (the_assistant == NULL) { return; + } gtk_widget_destroy(the_assistant); the_assistant = NULL; + + //reload list of proxy configs because a new one was probably created... + mw=linphone_gtk_get_main_window(); + if (mw) { + GtkWidget* pb = (GtkWidget*)g_object_get_data(G_OBJECT(mw),"parameters"); + if (pb) { + linphone_gtk_show_sip_accounts(pb); + } + } } - -void linphone_gtk_show_assistant(void){ - GtkWidget *w; - GtkWidget *p1; - GtkWidget *p2; - GtkWidget *p31; - GtkWidget *p32; - GtkWidget *p33; - //GtkWidget *confirm; - GtkWidget *validate; - GtkWidget *error; - GtkWidget *end; - GdkPixbuf *ok; - GdkPixbuf *notok; - if(the_assistant!=NULL) - return; - w=the_assistant=gtk_assistant_new(); - gtk_window_set_resizable (GTK_WINDOW(w), FALSE); - gtk_window_set_title(GTK_WINDOW(w),_("SIP account configuration assistant")); - - ok = create_pixbuf(linphone_gtk_get_ui_config("ok","ok.png")); - g_object_set_data_full(G_OBJECT(the_assistant), "ok", ok, g_object_unref); - notok = create_pixbuf(linphone_gtk_get_ui_config("notok","notok.png")); - g_object_set_data_full(G_OBJECT(the_assistant), "notok", notok, g_object_unref); - - p1=create_intro(); - p2=create_setup_signin_choice(); - p31=create_account_informations_page(); - p32=create_linphone_account_informations_page(); - p33=create_account_information_page(); - //confirm=create_confirmation_page(); - validate=wait_for_activation(); - error=create_error_page(); - end=create_finish_page(); - - linphone_gtk_assistant_init(w); - gtk_assistant_append_page(GTK_ASSISTANT(w),p1); - gtk_assistant_set_page_type(GTK_ASSISTANT(w),p1,GTK_ASSISTANT_PAGE_INTRO); - gtk_assistant_set_page_title(GTK_ASSISTANT(w),p1,_("Welcome to the account setup assistant")); - gtk_assistant_set_page_complete(GTK_ASSISTANT(w),p1,TRUE); - - gtk_assistant_append_page(GTK_ASSISTANT(w),p2); - gtk_assistant_set_page_type(GTK_ASSISTANT(w),p2,GTK_ASSISTANT_PAGE_CONTENT); - gtk_assistant_set_page_title(GTK_ASSISTANT(w),p2,_("Account setup assistant")); - gtk_assistant_set_page_complete(GTK_ASSISTANT(w),p2,TRUE); - - gtk_assistant_append_page(GTK_ASSISTANT(w),p31); - gtk_assistant_set_page_type(GTK_ASSISTANT(w),p31,GTK_ASSISTANT_PAGE_CONFIRM); - gtk_assistant_set_page_complete(GTK_ASSISTANT(w),p31,FALSE); - gtk_assistant_set_page_title(GTK_ASSISTANT(w),p31,_("Configure your account (step 1/1)")); - - gtk_assistant_append_page(GTK_ASSISTANT(w),p32); - gtk_assistant_set_page_type(GTK_ASSISTANT(w),p32,GTK_ASSISTANT_PAGE_CONFIRM); - gtk_assistant_set_page_complete(GTK_ASSISTANT(w),p32,FALSE); - gtk_assistant_set_page_title(GTK_ASSISTANT(w),p32,_("Enter your sip username (step 1/1)")); - - gtk_assistant_append_page(GTK_ASSISTANT(w),p33); - gtk_assistant_set_page_type(GTK_ASSISTANT(w),p33,GTK_ASSISTANT_PAGE_CONFIRM); - gtk_assistant_set_page_title(GTK_ASSISTANT(w),p33,_("Enter account information (step 1/2)")); - - /*gtk_assistant_append_page(GTK_ASSISTANT(w),confirm); - gtk_assistant_set_page_type(GTK_ASSISTANT(w),confirm,GTK_ASSISTANT_PAGE_CONFIRM); - gtk_assistant_set_page_title(GTK_ASSISTANT(w),confirm,_("Confirmation (step 2/2)")); - gtk_assistant_set_page_complete(GTK_ASSISTANT(w),confirm,TRUE);*/ - - gtk_assistant_append_page(GTK_ASSISTANT(w),validate); - gtk_assistant_set_page_type(GTK_ASSISTANT(w),validate,GTK_ASSISTANT_PAGE_CONTENT); - gtk_assistant_set_page_title(GTK_ASSISTANT(w),validate,_("Validation (step 2/2)")); - gtk_assistant_set_page_complete(GTK_ASSISTANT(w),validate,TRUE); - - gtk_assistant_append_page(GTK_ASSISTANT(w),error); - gtk_assistant_set_page_type(GTK_ASSISTANT(w),error,GTK_ASSISTANT_PAGE_CONTENT); - gtk_assistant_set_page_title(GTK_ASSISTANT(w),error,_("Error")); - - gtk_assistant_append_page(GTK_ASSISTANT(w),end); - gtk_assistant_set_page_type(GTK_ASSISTANT(w),end,GTK_ASSISTANT_PAGE_SUMMARY); - gtk_assistant_set_page_title(GTK_ASSISTANT(w),end,_("Terminating")); - - gtk_assistant_set_forward_page_func(GTK_ASSISTANT(w),linphone_gtk_assistant_forward,w,NULL); - g_signal_connect(G_OBJECT(w),"close",(GCallback)linphone_gtk_assistant_closed,NULL); - g_signal_connect(G_OBJECT(w),"cancel",(GCallback)linphone_gtk_assistant_closed,NULL); - g_signal_connect(G_OBJECT(w),"prepare",(GCallback)linphone_gtk_assistant_prepare,NULL); - - gtk_widget_show(w); -} - diff --git a/gtk/setupwizard.h b/gtk/setupwizard.h new file mode 100644 index 000000000..c88e1ee05 --- /dev/null +++ b/gtk/setupwizard.h @@ -0,0 +1,35 @@ +/* +linphone, gtk-glade interface. +Copyright (C) 2008 Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef SETUP_WIZARD_H +#define SETUP_WIZARD_H + +#include "sipsetup.h" + +LINPHONE_PUBLIC void linphone_gtk_show_assistant(void); +LINPHONE_PUBLIC void linphone_gtk_assistant_prepare(GtkWidget *assistant); +LINPHONE_PUBLIC void linphone_gtk_assistant_closed(GtkWidget *w); + +LINPHONE_PUBLIC void linphone_gtk_external_account_configuration_changed(GtkEntry* entry); +LINPHONE_PUBLIC void linphone_gtk_account_configuration_changed(GtkEntry *entry, GtkAssistant *assistant); +LINPHONE_PUBLIC void linphone_gtk_account_creation_username_changed(GtkEntry *entry); +LINPHONE_PUBLIC void linphone_gtk_account_creation_password_changed(GtkEntry *entry); +LINPHONE_PUBLIC void linphone_gtk_account_creation_email_changed(GtkEntry *entry); + +#endif \ No newline at end of file diff --git a/gtk/status_icon.c b/gtk/status_icon.c index ba16e28ea..588611a40 100644 --- a/gtk/status_icon.c +++ b/gtk/status_icon.c @@ -29,6 +29,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #endif #include "status_notifier.h" +#include typedef struct __LinphoneStatusIconDesc _LinphoneStatusIconDesc; @@ -116,7 +117,7 @@ static gboolean _linphone_status_icon_desc_is_supported( gboolean *result, LinphoneStatusIconDescIsSupportedResultCb cb, void *user_data) { - + return desc->is_supported(desc, result, cb, user_data); } @@ -130,21 +131,29 @@ static void _linphone_status_icon_desc_is_supported_result_cb( const _LinphoneStatusIconDesc *desc, gboolean result, _LinphoneStatusIconDescSearchCtx *ctx) { - + if(!result) { - ; + ctx->i = g_slist_next(ctx->i); for(; ctx->i; ctx->i = g_slist_next(ctx->i)) { if(_linphone_status_icon_desc_is_supported( (const _LinphoneStatusIconDesc *)g_slist_nth_data(ctx->i, 0), &result, (LinphoneStatusIconDescIsSupportedResultCb)_linphone_status_icon_desc_is_supported_result_cb, ctx)) { - + if(result) break; } else return; } } - if(ctx->cb) ctx->cb((const _LinphoneStatusIconDesc *)g_slist_nth_data(ctx->i, 0), ctx->user_data); + + if(ctx->i) { + const _LinphoneStatusIconDesc *desc = (const _LinphoneStatusIconDesc *)g_slist_nth_data(ctx->i, 0); + ms_message("StatusIcon: found implementation: %s", desc->impl_name); + if(ctx->cb) ctx->cb(desc, ctx->user_data); + } else { + g_warning("StatusIcon: no implementation found"); + } + g_free(ctx); } @@ -152,29 +161,33 @@ static gboolean _linphone_status_icon_find_first_available_impl( const _LinphoneStatusIconDesc **desc, LinphoneStatusIconDescFindResultCb cb, void *user_data) { - + gboolean result; _LinphoneStatusIconDescSearchCtx *ctx = g_new0(_LinphoneStatusIconDescSearchCtx, 1); ctx->cb = cb; ctx->user_data = user_data; - + + ms_message("StatusIcon: looking for implementation..."); + for(ctx->i=_linphone_status_icon_impls; ctx->i; ctx->i = g_slist_next(ctx->i)) { if(_linphone_status_icon_desc_is_supported( (const _LinphoneStatusIconDesc *)g_slist_nth_data(ctx->i, 0), &result, (LinphoneStatusIconDescIsSupportedResultCb)_linphone_status_icon_desc_is_supported_result_cb, ctx)) { - + if(result) { *desc = (const _LinphoneStatusIconDesc *)g_slist_nth_data(ctx->i, 0); + ms_message("StatusIcon: found implementation: %s", (*desc)->impl_name); goto sync_return; } } else { return 0; } } + g_warning("StatusIcon: no implementation found"); *desc = NULL; - + sync_return: g_free(ctx); return 1; @@ -195,7 +208,7 @@ static LinphoneStatusIcon *_linphone_status_icon_new(const _LinphoneStatusIconDe } static void _linphone_status_icon_free(LinphoneStatusIcon *obj) { - if(obj->desc->uninit) obj->desc->uninit(obj->data); + if(obj->desc->uninit) obj->desc->uninit(obj); if(obj->params) linphone_status_icon_params_unref(obj->params); g_free(obj); } @@ -205,11 +218,13 @@ const char *linphone_status_icon_get_implementation_name(const LinphoneStatusIco } void linphone_status_icon_start(LinphoneStatusIcon *obj, LinphoneStatusIconParams *params) { + ms_message("StatusIcon: starting status icon"); obj->params = linphone_status_icon_params_ref(params); if(obj->desc->start) obj->desc->start(obj); } void linphone_status_icon_enable_blinking(LinphoneStatusIcon *obj, gboolean enable) { + ms_message("StatusIcon: blinking set to %s", enable ? "TRUE" : "FALSE"); if(obj->desc->enable_blinking) obj->desc->enable_blinking(obj, enable); } @@ -251,12 +266,15 @@ void _linphone_status_icon_create_implementations_list(void) { gboolean linphone_status_icon_init(LinphoneStatusIconReadyCb ready_cb, void *user_data) { const _LinphoneStatusIconDesc *desc; void **ctx; - + + ms_message("StatusIcon: Initialising"); + _linphone_status_icon_create_implementations_list(); - + ctx = g_new(void *, 2); ctx[0] = ready_cb; ctx[1] = user_data; + if(_linphone_status_icon_find_first_available_impl(&desc, _linphone_status_icon_init_cb, ctx)) { _linphone_status_icon_selected_desc = desc; g_free(ctx); @@ -265,13 +283,21 @@ gboolean linphone_status_icon_init(LinphoneStatusIconReadyCb ready_cb, void *use } void linphone_status_icon_uninit(void) { - if(_linphone_status_icon_instance) _linphone_status_icon_free(_linphone_status_icon_instance); - if(_linphone_status_icon_impls) g_slist_free(_linphone_status_icon_impls); + if(_linphone_status_icon_instance) { + _linphone_status_icon_free(_linphone_status_icon_instance); + _linphone_status_icon_instance = NULL; + } + if(_linphone_status_icon_impls) { + g_slist_free(_linphone_status_icon_impls); + _linphone_status_icon_impls = NULL; + } + _linphone_status_icon_selected_desc = NULL; } LinphoneStatusIcon *linphone_status_icon_get(void) { if(_linphone_status_icon_instance == NULL) { if(_linphone_status_icon_selected_desc) + ms_message("StatusIcon: instanciating singleton"); _linphone_status_icon_instance = _linphone_status_icon_new(_linphone_status_icon_selected_desc); } return _linphone_status_icon_instance; @@ -290,17 +316,13 @@ static void _linphone_status_icon_impl_gtk_popup_menu(GtkStatusIcon *status_icon } static void _linphone_status_icon_impl_gtk_init(LinphoneStatusIcon *si) { - const char *icon_path=linphone_gtk_get_ui_config("icon",LINPHONE_ICON); - const char *call_icon_path=linphone_gtk_get_ui_config("start_call_icon","startcall-green.png"); - GdkPixbuf *pbuf=create_pixbuf(icon_path); - GtkStatusIcon *icon=gtk_status_icon_new_from_pixbuf(pbuf); + const char *icon_name=linphone_gtk_get_ui_config("icon_name",LINPHONE_ICON_NAME); + const char *blinking_icon_name=linphone_gtk_get_ui_config("binking_status_icon_name","linphone-start-call"); + GtkStatusIcon *icon=gtk_status_icon_new_from_icon_name(icon_name); g_signal_connect_swapped(G_OBJECT(icon),"activate", G_CALLBACK(_linphone_status_icon_impl_gtk_on_click_cb), si); g_signal_connect(G_OBJECT(icon), "popup-menu", G_CALLBACK(_linphone_status_icon_impl_gtk_popup_menu), si); - g_object_set_data_full(G_OBJECT(icon),"icon",pbuf, g_object_unref); - g_object_unref(pbuf); - pbuf=create_pixbuf(call_icon_path); - g_object_set_data_full(G_OBJECT(icon),"call_icon",pbuf, g_object_unref); - g_object_unref(pbuf); + g_object_set_data_full(G_OBJECT(icon), "icon", g_strdup(icon_name), g_free); + g_object_set_data_full(G_OBJECT(icon), "call_icon", g_strdup(blinking_icon_name), g_free); si->data = icon; } @@ -320,13 +342,13 @@ static void _linphone_status_icon_impl_gtk_start(LinphoneStatusIcon *si) { } static gboolean _linphone_status_icon_impl_gtk_do_icon_blink_cb(GtkStatusIcon *gi){ - GdkPixbuf *call_icon=g_object_get_data(G_OBJECT(gi),"call_icon"); - GdkPixbuf *normal_icon=g_object_get_data(G_OBJECT(gi),"icon"); - GdkPixbuf *cur_icon=gtk_status_icon_get_pixbuf(gi); - if (cur_icon==call_icon){ - gtk_status_icon_set_from_pixbuf(gi,normal_icon); + const gchar *call_icon = (const gchar *)g_object_get_data(G_OBJECT(gi),"call_icon"); + const gchar *normal_icon = (const gchar *)g_object_get_data(G_OBJECT(gi),"icon"); + const gchar *cur_icon = (const gchar *)gtk_status_icon_get_icon_name(gi); + if (cur_icon == call_icon){ + gtk_status_icon_set_from_icon_name(gi,normal_icon); }else{ - gtk_status_icon_set_from_pixbuf(gi,call_icon); + gtk_status_icon_set_from_icon_name(gi,call_icon); } return TRUE; } @@ -339,10 +361,10 @@ static void _linphone_status_icon_impl_enable_blinking(LinphoneStatusIcon *si, g tout=g_timeout_add(500,(GSourceFunc)_linphone_status_icon_impl_gtk_do_icon_blink_cb,icon); g_object_set_data(G_OBJECT(icon),"timeout",GINT_TO_POINTER(tout)); }else if (!val && tout!=0){ - GdkPixbuf *normal_icon=g_object_get_data(G_OBJECT(icon),"icon"); + const gchar *normal_icon = (const gchar *)g_object_get_data(G_OBJECT(icon),"icon"); g_source_remove(tout); g_object_set_data(G_OBJECT(icon),"timeout",NULL); - gtk_status_icon_set_from_pixbuf(icon,normal_icon); + gtk_status_icon_set_from_icon_name(icon,normal_icon); } } @@ -351,7 +373,7 @@ static gboolean _linphone_status_icon_impl_is_supported( gboolean *result, LinphoneStatusIconDescIsSupportedResultCb cb, void *user_data) { - + *result = 1; return 1; } @@ -372,9 +394,9 @@ static const _LinphoneStatusIconDesc _linphone_status_icon_impl_gtk_desc = { static void _linphone_status_icon_impl_gtkosx_app_enable_blinking(LinphoneStatusIcon *si, gboolean val) { GtkosxApplication *theMacApp=gtkosx_application_get(); gint *attention_id = (gint *)&si->data; - if (val && *attention_id == 0) { - *attention_id=gtkosx_application_attention_request(theMacApp,CRITICAL_REQUEST); - } else if(!val && *attention_id != 0) { + if (val) { + *attention_id=gtkosx_application_attention_request(theMacApp, CRITICAL_REQUEST); + } else if (*attention_id != 0) { gtkosx_application_cancel_attention_request(theMacApp, *attention_id); *attention_id = 0; } @@ -385,7 +407,7 @@ static gboolean _linphone_status_icon_impl_gtkosx_app_is_supported( gboolean *result, LinphoneStatusIconDescIsSupportedResultCb cb, void *user_data) { - + *result = 1; return 1; } @@ -412,9 +434,9 @@ static void _linphone_status_icon_impl_sn_init(LinphoneStatusIcon *si) { si->data = bc_status_notifier_new(); } -static void _linphone_status_icon_impl_sn_uninit(LinphoneStatusIcon *si) { - bc_status_notifier_unref((BcStatusNotifier *)si->data); -} +// static void _linphone_status_icon_impl_sn_uninit(LinphoneStatusIcon *si) { +// bc_status_notifier_unref((BcStatusNotifier *)si->data); +// } static void _linphone_status_icon_impl_sn_activated_cb(BcStatusNotifier *sn, int x, int y, void *user_data) { LinphoneStatusIcon *si = (LinphoneStatusIcon *)user_data; @@ -448,10 +470,10 @@ static void _linphone_status_icon_impl_sn_start(LinphoneStatusIcon *si) { BcStatusNotifierParams *params; BcStatusNotifierToolTip *tooltip = bc_status_notifier_tool_tip_new("linphone", si->params->title, si->params->desc); BcStatusNotifierSignalsVTable vtable = {NULL}; - + vtable.activate_called_cb = _linphone_status_icon_impl_sn_activated_cb; vtable.context_menu_called_cb = _linphone_status_icon_impl_sn_menu_called_cb; - + params = bc_status_notifier_params_new(); bc_status_notifier_params_set_dbus_prefix(params, "org.kde"); bc_status_notifier_params_set_category(params, BcStatusNotifierCategoryCommunications); @@ -460,15 +482,15 @@ static void _linphone_status_icon_impl_sn_start(LinphoneStatusIcon *si) { bc_status_notifier_params_set_icon_name(params, "linphone"); bc_status_notifier_params_set_tool_tip(params, tooltip); bc_status_notifier_params_set_vtable(params, &vtable, si); - + bc_status_notifier_start(sn, params, NULL, NULL); - + bc_status_notifier_tool_tip_unref(tooltip); bc_status_notifier_params_unref(params); } static void _linphone_status_icon_impl_sn_enable_blinking(LinphoneStatusIcon *si, gboolean val) { - BcStatusNotifier *sn = (BcStatusNotifier *)si->data; + BcStatusNotifier *sn = (BcStatusNotifier *)si->data; if(val) { bc_status_notifier_update_status(sn, BcStatusNotifierStatusNeedsAttention); } else { @@ -489,11 +511,19 @@ static gboolean _linphone_status_icon_impl_sn_is_supported( gboolean *result, LinphoneStatusIconDescIsSupportedResultCb cb, void *user_data) { - - _LinphoneStatusIconDesc *desc2 = g_new(_LinphoneStatusIconDesc, 1); - void **data = g_new(void *, 3); - + + _LinphoneStatusIconDesc *desc2; + void **data; + const char *desktop = g_getenv("XDG_CURRENT_DESKTOP"); + + if(desktop == NULL || g_strcmp0(desktop, "KDE") != 0) { + *result = FALSE; + return TRUE; + } + + desc2 = g_new(_LinphoneStatusIconDesc, 1); *desc2 = *desc; + data = g_new(void *, 3); data[0] = desc2; data[1] = cb; data[2] = user_data; @@ -502,13 +532,13 @@ static gboolean _linphone_status_icon_impl_sn_is_supported( (BcStatusNotifierSupportDetectionCb)_linphone_status_icon_impl_is_supported_cb, data ); - return 0; + return FALSE; } static const _LinphoneStatusIconDesc _linphone_status_icon_impl_status_notifier = { .impl_name = "status_notifier", .init = _linphone_status_icon_impl_sn_init, - .uninit = _linphone_status_icon_impl_sn_uninit, + .uninit = NULL, .start = _linphone_status_icon_impl_sn_start, .enable_blinking = _linphone_status_icon_impl_sn_enable_blinking, .is_supported = _linphone_status_icon_impl_sn_is_supported diff --git a/gtk/status_icon.h b/gtk/status_icon.h index 233733724..2e4455659 100644 --- a/gtk/status_icon.h +++ b/gtk/status_icon.h @@ -22,9 +22,19 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * technology used to manage the status icon. */ +#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4) +#pragma GCC diagnostic push +#endif +#pragma GCC diagnostic ignored "-Wstrict-prototypes" + #include #include +#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4) +#pragma GCC diagnostic pop +#endif + + struct _LinphoneStatusIcon; typedef void (*LinphoneStatusIconOnClickCallback)(struct _LinphoneStatusIcon *si, void *user_data); diff --git a/gtk/support.c b/gtk/support.c index 615ac6562..ebb61c33d 100644 --- a/gtk/support.c +++ b/gtk/support.c @@ -155,30 +155,13 @@ const char *linphone_gtk_get_lang(const char *config_file){ void linphone_gtk_set_lang(const char *code){ LpConfig *cfg=linphone_core_get_config(linphone_gtk_get_core()); - const char *curlang; - - #ifdef WIN32 - char tmp[128]; - #endif - - #if defined(WIN32) || defined(__APPLE__) - curlang=getenv("LANG"); - #else - curlang=getenv("LANGUAGE"); - #endif + const char *curlang=g_getenv("LANGUAGE"); if (curlang!=NULL && strncmp(curlang,code,2)==0) { /* do not loose the _territory@encoding part*/ return; } lp_config_set_string(cfg,"GtkUi","lang",code); -#ifdef WIN32 - snprintf(tmp,sizeof(tmp),"LANG=%s",code); - _putenv(tmp); -#elif __APPLE__ - setenv("LANG",code,1); -#else - setenv("LANGUAGE",code,1); -#endif + g_setenv("LANGUAGE",code,1); } const gchar *linphone_gtk_get_ui_config(const char *key, const char *def){ diff --git a/gtk/update.c b/gtk/update.c index 34cff9995..26769c2b6 100644 --- a/gtk/update.c +++ b/gtk/update.c @@ -87,7 +87,7 @@ static gboolean popup_new_version(const char *download_site){ return FALSE; } -static gboolean popup_version_ok(){ +static gboolean popup_version_ok(void){ linphone_gtk_display_something(GTK_MESSAGE_INFO,_("You are running the lastest version.")); return FALSE; } diff --git a/gtk/utils.c b/gtk/utils.c index c03ea462b..0d0ae64d0 100644 --- a/gtk/utils.c +++ b/gtk/utils.c @@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "linphone.h" -static void run_gtk(){ +static void run_gtk(void){ while (gtk_events_pending ()) gtk_main_iteration (); @@ -30,7 +30,7 @@ void *linphone_gtk_wait(LinphoneCore *lc, void *ctx, LinphoneWaitingState ws, co switch(ws){ case LinphoneWaitingStart: gdk_threads_enter(); - w=linphone_gtk_create_window("waiting"); + w=linphone_gtk_create_window("waiting", NULL); gtk_window_set_transient_for(GTK_WINDOW(w),GTK_WINDOW(linphone_gtk_get_main_window())); gtk_window_set_position(GTK_WINDOW(w),GTK_WIN_POS_CENTER_ON_PARENT); if (purpose) { @@ -112,6 +112,17 @@ void linphone_gtk_reload_video_devices(void){ if (pb) linphone_gtk_fill_webcams(pb); } +bool_t linphone_gtk_is_friend(LinphoneCore *lc, const char *contact) { + LinphoneAddress *addr = linphone_core_interpret_url(lc, contact); + if (addr) { + char *uri = linphone_address_as_string_uri_only(addr); + LinphoneFriend *lf = linphone_core_get_friend_by_address(lc, uri); + linphone_address_destroy(addr); + if (lf) return TRUE; + } + return FALSE; +} + #ifdef HAVE_LIBUDEV_H static struct udev *udevroot=NULL; diff --git a/gtk/videowindow.c b/gtk/videowindow.c index 07a22bf29..c4a10d970 100644 --- a/gtk/videowindow.c +++ b/gtk/videowindow.c @@ -94,13 +94,13 @@ static gboolean drag_drop(GtkWidget *widget, GdkDragContext *drag_context, gint return TRUE; } -static unsigned long get_native_handle(GdkWindow *gdkw){ +static void *get_native_handle(GdkWindow *gdkw){ #ifdef GDK_WINDOWING_X11 - return (unsigned long)GDK_WINDOW_XID(gdkw); + return (void *)GDK_WINDOW_XID(gdkw); #elif defined(WIN32) - return (unsigned long)GDK_WINDOW_HWND(gdkw); + return (void *)GDK_WINDOW_HWND(gdkw); #elif defined(__APPLE__) - return (unsigned long)gdk_quartz_window_get_nsview(gdkw); + return (void *)gdk_quartz_window_get_nsview(gdkw); #endif g_warning("No way to get the native handle from gdk window"); return 0; @@ -132,7 +132,7 @@ static gint resize_video_window(LinphoneCall *call){ static void on_video_window_destroy(GtkWidget *w, guint timeout){ g_source_remove(timeout); - linphone_core_set_native_video_window_id(linphone_gtk_get_core(),(unsigned long)-1); + linphone_core_set_native_video_window_id(linphone_gtk_get_core(),LINPHONE_VIDEO_DISPLAY_NONE); } static void video_window_set_fullscreen(GtkWidget *w, gboolean val){ @@ -227,13 +227,14 @@ static GtkWidget *show_video_controls(GtkWidget *video_window){ gboolean isfullscreen=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(video_window),"fullscreen")); const char *stock_button=isfullscreen ? GTK_STOCK_LEAVE_FULLSCREEN : GTK_STOCK_FULLSCREEN; gint response_id=isfullscreen ? GTK_RESPONSE_NO : GTK_RESPONSE_YES ; + GtkWidget *image = gtk_image_new_from_icon_name(linphone_gtk_get_ui_config("stop_call_icon_name","linphone-stop-call"), GTK_ICON_SIZE_BUTTON); gint timeout; GtkWidget *button; w=gtk_dialog_new_with_buttons("",GTK_WINDOW(video_window),GTK_DIALOG_DESTROY_WITH_PARENT,stock_button,response_id,NULL); gtk_window_set_opacity(GTK_WINDOW(w),0.5); gtk_window_set_decorated(GTK_WINDOW(w),FALSE); button=gtk_button_new_with_label(_("Hang up")); - gtk_button_set_image(GTK_BUTTON(button),create_pixmap (linphone_gtk_get_ui_config("stop_call_icon","stopcall-small.png"))); + gtk_button_set_image(GTK_BUTTON(button), image); gtk_widget_show(button); gtk_dialog_add_action_widget(GTK_DIALOG(w),button,GTK_RESPONSE_REJECT); g_signal_connect(w,"response",(GCallback)on_controls_response,video_window); @@ -264,6 +265,7 @@ static GtkWidget *create_video_window(LinphoneCall *call){ addr=linphone_call_get_remote_address(call); remote=linphone_gtk_address(addr); video_window=gtk_window_new(GTK_WINDOW_TOPLEVEL); + /*gtk_window_set_transient_for(GTK_WINDOW(video_window), GTK_WINDOW(linphone_gtk_get_main_window()));*/ title=g_strdup_printf("%s - Video call with %s",linphone_gtk_get_ui_config("title","Linphone"),remote); ms_free(remote); gtk_window_set_title(GTK_WINDOW(video_window),title); @@ -292,17 +294,20 @@ void linphone_gtk_in_call_show_video(LinphoneCall *call){ GtkWidget *video_window=(GtkWidget*)g_object_get_data(G_OBJECT(callview),"video_window"); const LinphoneCallParams *params=linphone_call_get_current_params(call); LinphoneCore *lc=linphone_gtk_get_core(); - - if (linphone_call_get_state(call)!=LinphoneCallPaused && params && linphone_call_params_video_enabled(params)){ - if (video_window==NULL){ - video_window=create_video_window(call); - g_object_set_data(G_OBJECT(callview),"video_window",video_window); - } - linphone_core_set_native_video_window_id(lc,get_native_handle(gtk_widget_get_window(video_window))); - }else{ - if (video_window){ - gtk_widget_destroy(video_window); - g_object_set_data(G_OBJECT(callview),"video_window",NULL); + + if (((bool_t)lp_config_get_int(linphone_core_get_config(lc), "video", "rtp_io", FALSE)) == FALSE) { + if (linphone_call_get_state(call)!=LinphoneCallPaused && params && linphone_call_params_video_enabled(params)){ + if (video_window==NULL){ + video_window=create_video_window(call); + g_object_set_data(G_OBJECT(callview),"video_window",video_window); + } + linphone_core_set_native_video_window_id(lc,get_native_handle(gtk_widget_get_window(video_window))); + gtk_window_present(GTK_WINDOW(video_window)); + }else{ + if (video_window){ + gtk_widget_destroy(video_window); + g_object_set_data(G_OBJECT(callview),"video_window",NULL); + } } } } @@ -312,7 +317,7 @@ static void on_video_preview_destroyed(GtkWidget *video_preview, GtkWidget *mw){ guint timeout_id=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(video_preview),"timeout-id")); g_object_set_data(G_OBJECT(mw),"video_preview",NULL); linphone_core_enable_video_preview(lc,FALSE); - linphone_core_set_native_preview_window_id(lc,-1); + linphone_core_set_native_preview_window_id(lc,(void *)(unsigned long)-1); g_source_remove(timeout_id); } diff --git a/include/sal/sal.h b/include/sal/sal.h index ac0aed989..6e1c4d068 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -59,6 +59,10 @@ struct SalCustomHeader; typedef struct SalCustomHeader SalCustomHeader; +struct SalCustomSdpAttribute; + +typedef struct SalCustomSdpAttribute SalCustomSdpAttribute; + struct addrinfo; typedef enum { @@ -68,20 +72,17 @@ typedef enum { SalTransportDTLS, /*DTLS*/ }SalTransport; -#define SAL_MEDIA_DESCRIPTION_UNCHANGED 0x00 -#define SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED (1) -#define SAL_MEDIA_DESCRIPTION_CODEC_CHANGED (1<<1) -#define SAL_MEDIA_DESCRIPTION_CRYPTO_KEYS_CHANGED (1<<2) -#define SAL_MEDIA_DESCRIPTION_CRYPTO_POLICY_CHANGED (1<<3) -#define SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED (1<<4) -#define SAL_MEDIA_DESCRIPTION_NETWORK_XXXCAST_CHANGED (1<<5) /* use to notify when switching from multicast to unicast*/ +#define SAL_MEDIA_DESCRIPTION_UNCHANGED 0x00 +#define SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED (1) +#define SAL_MEDIA_DESCRIPTION_CODEC_CHANGED (1<<1) +#define SAL_MEDIA_DESCRIPTION_CRYPTO_KEYS_CHANGED (1<<2) +#define SAL_MEDIA_DESCRIPTION_CRYPTO_POLICY_CHANGED (1<<3) +#define SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED (1<<4) +#define SAL_MEDIA_DESCRIPTION_NETWORK_XXXCAST_CHANGED (1<<5) /* use to notify when switching from multicast to unicast*/ +#define SAL_MEDIA_DESCRIPTION_FORCE_STREAM_RECONSTRUCTION (1<<6) /* use force graph reconstruction*/ +#define SAL_MEDIA_DESCRIPTION_ICE_RESTART_DETECTED (1<<7) + -#define SAL_MEDIA_DESCRIPTION_CHANGED (SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED \ - |SAL_MEDIA_DESCRIPTION_CODEC_CHANGED \ - |SAL_MEDIA_DESCRIPTION_CRYPTO_KEYS_CHANGED \ - |SAL_MEDIA_DESCRIPTION_CRYPTO_POLICY_CHANGED \ - |SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED \ - |SAL_MEDIA_DESCRIPTION_NETWORK_XXXCAST_CHANGED) const char* sal_transport_to_string(SalTransport transport); SalTransport sal_transport_parse(const char*); @@ -121,8 +122,8 @@ void sal_address_set_password(SalAddress *addr, const char *passwd); const char *sal_address_get_password(const SalAddress *addr); void sal_address_set_header(SalAddress *addr, const char *header_name, const char *header_value); -Sal * sal_init(); -void sal_uninit(Sal* sal); +LINPHONE_PUBLIC Sal * sal_init(void); +LINPHONE_PUBLIC void sal_uninit(Sal* sal); void sal_set_user_pointer(Sal *sal, void *user_data); void *sal_get_user_pointer(const Sal *sal); @@ -130,6 +131,7 @@ void *sal_get_user_pointer(const Sal *sal); typedef enum { SalAudio, SalVideo, + SalText, SalOther } SalStreamType; const char* sal_stream_type_to_string(SalStreamType type); @@ -223,7 +225,7 @@ typedef struct SalStreamDescription{ char rtp_addr[64]; char rtcp_addr[64]; unsigned int rtp_ssrc; - char rtcp_cname[255]; + char rtcp_cname[256]; int rtp_port; int rtcp_port; MSList *payloads; /*user_data=(void*)((long)n); -#define payload_type_get_number(pt) ((int)(long)(pt)->user_data) +#define payload_type_set_number(pt,n) (pt)->user_data=(void*)((intptr_t)n); +#define payload_type_get_number(pt) ((int)(intptr_t)(pt)->user_data) /*misc*/ void sal_get_default_local_ip(Sal *sal, int address_family, char *ip, size_t iplen); @@ -782,8 +790,17 @@ const SalCustomHeader *sal_op_get_recv_custom_header(SalOp *op); void sal_op_set_sent_custom_header(SalOp *op, SalCustomHeader* ch); -void sal_enable_logs(); -void sal_disable_logs(); + +SalCustomSdpAttribute * sal_custom_sdp_attribute_append(SalCustomSdpAttribute *csa, const char *name, const char *value); +const char * sal_custom_sdp_attribute_find(const SalCustomSdpAttribute *csa, const char *name); +void sal_custom_sdp_attribute_free(SalCustomSdpAttribute *csa); +SalCustomSdpAttribute * sal_custom_sdp_attribute_clone(const SalCustomSdpAttribute *csa); + +/** deprecated. use sal_set_log_level instead **/ +void sal_enable_log(void); +/** deprecated. use sal_set_log_level instead **/ +void sal_disable_log(void); +void sal_set_log_level(OrtpLogLevel level); /*internal API */ void __sal_op_init(SalOp *b, Sal *sal); @@ -801,6 +818,11 @@ LINPHONE_PUBLIC void sal_set_recv_error(Sal *sal,int value); /*always answer 480 if value=true*/ LINPHONE_PUBLIC void sal_enable_unconditional_answer(Sal *sal,int value); +LINPHONE_PUBLIC bool_t sal_pending_trans_checking_enabled(const Sal *sal) ; +LINPHONE_PUBLIC int sal_enable_pending_trans_checking(Sal *sal, bool_t value) ; + + + /*refresher retry after value in ms*/ LINPHONE_PUBLIC void sal_set_refresher_retry_after(Sal *sal,int value); LINPHONE_PUBLIC int sal_get_refresher_retry_after(const Sal *sal); @@ -836,6 +858,12 @@ void sal_end_background_task(unsigned long id); void sal_op_cnx_ip_to_0000_if_sendonly_enable(SalOp *sal,bool_t yesno); bool_t sal_op_cnx_ip_to_0000_if_sendonly_enabled(SalOp *sal); +void sal_set_http_proxy_host(Sal *sal, const char *host) ; +void sal_set_http_proxy_port(Sal *sal, int port) ; +const char *sal_get_http_proxy_host(const Sal *sal); +int sal_get_http_proxy_port(const Sal *sal); + + #endif diff --git a/java/common/org/linphone/core/LinphoneCall.java b/java/common/org/linphone/core/LinphoneCall.java index cd74b6d07..ad10b96b1 100644 --- a/java/common/org/linphone/core/LinphoneCall.java +++ b/java/common/org/linphone/core/LinphoneCall.java @@ -26,6 +26,13 @@ import java.util.Vector; */ public interface LinphoneCall { + /** + * LinphoneCall listener + */ + interface LinphoneCallListener { + void onNextVideoFrameDecoded(LinphoneCall call); + } + /** * Linphone call states * @@ -359,5 +366,15 @@ public interface LinphoneCall { * @return A player */ public LinphonePlayer getPlayer(); + + /** + * Create a new chat room for messaging from a call if not already existing, else return existing one + * @return LinphoneChatRoom where messaging can take place. + */ + public LinphoneChatRoom getChatRoom() ; + /** + * Set the callbacks associated with the LinphoneCall. + */ + void setListener(LinphoneCall.LinphoneCallListener listener); } diff --git a/java/common/org/linphone/core/LinphoneCallLog.java b/java/common/org/linphone/core/LinphoneCallLog.java index f1dd742b3..67b1977e1 100644 --- a/java/common/org/linphone/core/LinphoneCallLog.java +++ b/java/common/org/linphone/core/LinphoneCallLog.java @@ -118,7 +118,7 @@ public interface LinphoneCallLog { public int getCallDuration(); /** * Call id from signaling - * @return int + * @return the SIP call-id. */ - public int getCallId(); + public String getCallId(); } diff --git a/java/common/org/linphone/core/LinphoneCallParams.java b/java/common/org/linphone/core/LinphoneCallParams.java index fa827faa2..cd8c67712 100644 --- a/java/common/org/linphone/core/LinphoneCallParams.java +++ b/java/common/org/linphone/core/LinphoneCallParams.java @@ -17,7 +17,9 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.linphone.core; +import org.linphone.core.LinphoneCore.MediaDirection; import org.linphone.core.LinphoneCore.MediaEncryption; +import org.linphone.core.LinphoneCore.StreamType; /** * The LinphoneCallParams is an object containing various call related parameters. * It can be used to retrieve parameters from a currently running call or modify the call's characteristics @@ -96,7 +98,48 @@ public interface LinphoneCallParams { * @return value for the header, or null if it doesn't exist. */ String getCustomHeader(String name); - + + /** + * Add a custom attribute related to all the streams in the SDP exchanged within SIP messages during a call. + * @param name The name of the attribute to add. + * @param value The content value of the attribute to add. + **/ + void addCustomSdpAttribute(String name, String value); + + /** + * Add a custom attribute related to a specific stream in the SDP exchanged within SIP messages during a call. + * @param type The type of the stream to add a custom SDP attribute to. + * @param name The name of the attribute to add. + * @param value The content value of the attribute to add. + **/ + void addCustomSdpMediaAttribute(StreamType type, String name, String value); + + /** + * Get a custom SDP attribute that is related to all the streams. + * @param name The name of the attribute to get. + * @return The content value of the attribute or null if not found. + **/ + String getCustomSdpAttribute(String name); + + /** + * Get a custom SDP attribute that is related to a specific stream. + * @param type The type of the stream to add a custom SDP attribute to. + * @param name The name of the attribute to get. + * @return The content value of the attribute or null if not found. + **/ + String getCustomSdpMediaAttribute(StreamType type, String name); + + /** + * Clear the custom SDP attributes related to all the streams in the SDP exchanged within SIP messages during a call. + **/ + void clearCustomSdpAttributes(); + + /** + * Clear the custom SDP attributes related to a specific stream in the SDP exchanged within SIP messages during a call. + * @param type The type of the stream to clear custom SDP attributes from. + **/ + void clearCustomSdpMediaAttributes(StreamType type); + /** * Set the privacy for the call. * @param privacy_mask a or'd int of values defined in interface {@link org.linphone.core.Privacy} @@ -158,4 +201,40 @@ public interface LinphoneCallParams { **/ boolean videoMulticastEnabled(); + /** + * Use to enable real time text following rfc4103. + * If enabled, outgoing calls put a m=text line in SDP offer . + * @param yesno if yes, subsequent outgoing calls will propose rtt + * + **/ + void enableRealTimeText(boolean yesno); + /** + * Use to get real time text following rfc4103. + * @returns returns true if call rtt is activated. + **/ + boolean realTimeTextEnabled(); + + /** + * Get the audio stream direction. + * @return The audio stream direction associated with the call params. + **/ + MediaDirection getAudioDirection(); + + /** + * Get the video stream direction. + * @return The video stream direction associated with the call params. + **/ + MediaDirection getVideoDirection(); + + /** + * Set the audio stream direction. + * @param The audio stream direction associated with this call params. + **/ + void setAudioDirection(MediaDirection dir); + + /** + * Set the video stream direction. + * @param The video stream direction associated with this call params. + **/ + void setVideoDirection(MediaDirection dir); } diff --git a/java/common/org/linphone/core/LinphoneCallStats.java b/java/common/org/linphone/core/LinphoneCallStats.java index 295c99484..7a17bb142 100644 --- a/java/common/org/linphone/core/LinphoneCallStats.java +++ b/java/common/org/linphone/core/LinphoneCallStats.java @@ -32,6 +32,10 @@ public interface LinphoneCallStats { * Video */ static public MediaType Video = new MediaType(1, "Video"); + /** + * Text + */ + static public MediaType Text = new MediaType(2, "Text"); protected final int mValue; private final String mStringValue; diff --git a/java/common/org/linphone/core/LinphoneChatMessage.java b/java/common/org/linphone/core/LinphoneChatMessage.java index b80c3a070..aaef154ab 100644 --- a/java/common/org/linphone/core/LinphoneChatMessage.java +++ b/java/common/org/linphone/core/LinphoneChatMessage.java @@ -221,10 +221,18 @@ public interface LinphoneChatMessage { /** * Start the download of the file referenced in a LinphoneChatMessage from remote server. */ - void downloadFile(); + int downloadFile(); /** * Set the callbacks associated with the LinphoneChatMessage. */ void setListener(LinphoneChatMessage.LinphoneChatMessageListener listener); + /** + * Fulfill a chat message char by char. Message linked to a Real Time Text Call send char in realtime following RFC 4103/T.140 + * To commit a message, use #linphone_chat_room_send_message + * @param[in] character T.140 char + * @throw LinphoneCoreExeption . + */ + void putChar(long character) throws LinphoneCoreException; + } diff --git a/java/common/org/linphone/core/LinphoneChatRoom.java b/java/common/org/linphone/core/LinphoneChatRoom.java index f94f4e764..9b717d942 100644 --- a/java/common/org/linphone/core/LinphoneChatRoom.java +++ b/java/common/org/linphone/core/LinphoneChatRoom.java @@ -76,11 +76,6 @@ public interface LinphoneChatRoom { */ LinphoneChatMessage[] getHistoryRange(int begin, int end); - /** - * Destroys a LinphoneChatRoom. - */ - void destroy(); - /** * Returns the amount of unread messages associated with the peer of this chatRoom. * @return the amount of unread messages @@ -120,12 +115,6 @@ public interface LinphoneChatRoom { */ void deleteMessage(LinphoneChatMessage message); - /** - * Update the value stored in the database for the external_body_url field - * @param message to update - */ - void updateUrl(LinphoneChatMessage message); - /** * Create a LinphoneChatMessage * @return LinphoneChatMessage object @@ -150,4 +139,19 @@ public interface LinphoneChatRoom { * @param message */ void sendChatMessage(LinphoneChatMessage message); + + /** + * get Curent Call associated to this chatroom if any + * To commit a message, use #linphone_chat_room_send_message + * @returns LinphoneCall or NULL. + */ + public LinphoneCall getCall(); + /** + * When realtime text is enabled LinphoneCallParams.realTimeTextEnabled, LinphoneCoreListener.isComposingReceived is call every time a char is received from peer. + * At the end of remote typing a regular LinphoneChatMessage is received with committed data from LinphoneCoreListener.messageReceived . + * @returns RFC 4103/T.140 char + */ + long getChar(); + + } diff --git a/java/common/org/linphone/core/LinphoneCore.java b/java/common/org/linphone/core/LinphoneCore.java index 33f917b7c..af0de0501 100644 --- a/java/common/org/linphone/core/LinphoneCore.java +++ b/java/common/org/linphone/core/LinphoneCore.java @@ -250,6 +250,94 @@ public interface LinphoneCore { return "udp["+udp+"] tcp["+tcp+"] tls["+tls+"]"; } } + /** + * Stream type enum-like. + * + */ + static public final class StreamType { + + static private Vector values = new Vector(); + /** + * Audio + */ + static public final StreamType Audio = new StreamType(0, "Audio"); + /** + * Video + */ + static public final StreamType Video = new StreamType(1, "Video"); + /** + * Text + */ + static public final StreamType Text = new StreamType(2, "Text"); + /** + * Unknown + */ + static public final StreamType Unknown = new StreamType(3, "Unknown"); + protected final int mValue; + private final String mStringValue; + + private StreamType(int value, String stringValue) { + mValue = value; + values.addElement(this); + mStringValue = stringValue; + } + public static StreamType fromInt(int value) { + for (int i = 0; i < values.size(); i++) { + StreamType stype = (StreamType) values.elementAt(i); + if (stype.mValue == value) return stype; + } + throw new RuntimeException("StreamType not found [" + value + "]"); + } + public String toString() { + return mStringValue; + } + } + /** + * Stream type enum-like. + * + */ + static public final class MediaDirection { + + static private Vector values = new Vector(); + /** + * Invalid + */ + static public final MediaDirection Invalid = new MediaDirection(-1, "Invalid"); + /** + * Inactive + */ + static public final MediaDirection Inactive = new MediaDirection(0, "Inactive"); + /** + * SendOnly + */ + static public final MediaDirection SendOnly = new MediaDirection(1, "SendOnly"); + /** + * RecvOnly + */ + static public final MediaDirection RecvOnly = new MediaDirection(2, "RecvOnly"); + /** + * SendRecv + */ + static public final MediaDirection SendRecv = new MediaDirection(3, "SendRecv"); + protected final int mValue; + private final String mStringValue; + + private MediaDirection(int value, String stringValue) { + mValue = value; + values.addElement(this); + mStringValue = stringValue; + } + public static MediaDirection fromInt(int value) { + for (int i = 0; i < values.size(); i++) { + MediaDirection dir = (MediaDirection) values.elementAt(i); + if (dir.mValue == value) return dir; + } + throw new RuntimeException("MediaDirection not found [" + value + "]"); + } + public String toString() { + return mStringValue; + } + } /** * Media (RTP) encryption enum-like. * @@ -479,6 +567,11 @@ public interface LinphoneCore { */ public void setContext(Object context); + /** + * Get the LinphoneCore's global state. + **/ + public GlobalState getGlobalState(); + /** * clear all added proxy configs */ @@ -569,7 +662,7 @@ public interface LinphoneCore { * @param call the LinphoneCall, must be in the {@link LinphoneCall.State#IncomingReceived} state. * @param reason the reason for rejecting the call: {@link Reason#Declined} or {@link Reason#Busy} */ - public void declineCall(LinphoneCall aCall, Reason reason); + public void declineCall(LinphoneCall call, Reason reason); /** * Returns The LinphoneCall the current call if one is in call * @@ -653,12 +746,17 @@ public interface LinphoneCore { */ public LinphoneCallLog[] getCallLogs(); + /** + * @return the latest outgoing call log. + */ + public LinphoneCallLog getLastOutgoingCallLog(); + /** * This method is called by the application to notify the Linphone core library when network is reachable. * Calling this method with true trigger Linphone to initiate a registration process for all proxy * configuration with parameter register set to enable. * This method disable the automatic registration mode. It means you must call this method after each network state changes - * @param network state + * @param isReachable network state * */ public void setNetworkReachable(boolean isReachable); @@ -705,7 +803,7 @@ public interface LinphoneCore { /** * Initiate a dtmf signal if in call - * @param send dtmf ['0'..'9'] | '#', '*' + * @param number send dtmf ['0'..'9'] | '#', '*' */ void sendDtmf(char number); /** @@ -758,7 +856,7 @@ public interface LinphoneCore { /** * Enable payload type * @param pt payload type to enable, can be retrieve from {@link #findPayloadType} - * @param true if enabled + * @param enable for enable or disable the payload type * @exception LinphoneCoreException * */ @@ -866,6 +964,18 @@ public interface LinphoneCore { */ void setSipDscp(int dscp); + /** + * Set the timeout in milliseconds for SIP transport (TCP or TLS connection establishment maximum time). + * @param timeout_ms + **/ + void setSipTransportTimeout(int timeout_ms); + + /** + * Get the current SIP transport timeout. + * @param timeout_ms + **/ + int getSipTransportTimeout(); + /** * Get DSCP used for SIP socket. * @return the DSCP value used for the SIP socket. @@ -926,6 +1036,13 @@ public interface LinphoneCore { * @return {@link LinphoneChatRoom} where messaging can take place. */ LinphoneChatRoom getOrCreateChatRoom(String to); + /** + * Create a new chat room for messaging from a linphone address + * @param to destination address for messages + * + * @return {@link LinphoneChatRoom} where messaging can take place. + */ + LinphoneChatRoom getChatRoom(LinphoneAddress to); /** * Set the native video window id where the video is to be displayed. * On Android, it must be of type {@link AndroidVideoWindowImpl} @@ -1029,12 +1146,17 @@ public interface LinphoneCore { * @return 0 if successful, -1 otherwise. **/ int updateCall(LinphoneCall call, LinphoneCallParams params); - /** - * Get default call parameters reflecting current linphone core configuration - * @return LinphoneCallParams - */ - LinphoneCallParams createDefaultCallParameters(); + /** + * Create a LinphoneCallParams suitable to be used for a new incoming call or an established call, in + * methods LinphoneCore.inviteAddressWithParams(), LinphoneCore.updateCall(), LinphoneCore.acceptCallWithParams(), LinphoneCore.acceptCallUpdate(). + * The call parameter is optional: when creating a LinphoneCallParams for an outgoing call that is about to be created, + * it shall be set to null. + * @param call (optional) + * @return a LinphoneCallParams object, representing the call settings guessed from the current LinphoneCore and compatible with the call object if any. + */ + LinphoneCallParams createCallParams(LinphoneCall call); + /** * Sets the path to a wav file used for ringing. * @@ -1064,7 +1186,18 @@ public interface LinphoneCore { */ void setRingback(String path); + /** + * Retrieve the maximum available upload bandwidth. + **/ + int getUploadBandwidth(); + void setUploadBandwidth(int bw); + + /** + * Retrieve the maximum available download bandwidth. + **/ + int getDownloadBandwidth(); + /** * Sets maximum available download bandwidth * @@ -1175,7 +1308,7 @@ public interface LinphoneCore { * 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(); + boolean hasBuiltInEchoCanceler(); void enableIpv6(boolean enable); @@ -1757,6 +1890,12 @@ public interface LinphoneCore { */ public void setChatDatabasePath(String path); + /** + * Sets the path to the database where the logs will be stored (if enabled) + * @param path the database where the logs will be stored. + */ + public void setCallLogsDatabasePath(String path); + /** * Gets the chat rooms * @return an array of LinphoneChatRoom @@ -1779,6 +1918,11 @@ public interface LinphoneCore { */ public int migrateToMultiTransport(); + /** + * Migrates the call logs from the linphonerc to the database if not done yet + **/ + public void migrateCallLogs(); + /** * When receiving an incoming, accept to start a media session as early-media. * This means the call is not accepted but audio & video streams can be established if the remote party supports early media. @@ -1795,8 +1939,8 @@ public interface LinphoneCore { * Accept an early media session for an incoming call. * This is identical as calling linphone_core_accept_early_media_with_params() with NULL call parameters. * @see linphone_core_accept_early_media_with_params() - * @param lc the core * @param call the incoming call + * @param params * @return true if successful, false otherwise. */ public boolean acceptEarlyMediaWithParams(LinphoneCall call, LinphoneCallParams params); @@ -2035,4 +2179,56 @@ public interface LinphoneCore { */ public boolean dnsSrvEnabled(); + /** + * Set the video preset to be used for video calls. + * @param lc LinphoneCore object + * @param preset The name of the video preset to be used (can be null to use the default video preset). + */ + public void setVideoPreset(String preset); + + /** + * Get the video preset used for video calls. + * @param lc LinphoneCore object + * @return The name of the video preset used for video calls (can be null if the default video preset is used). + */ + public String getVideoPreset(); + + /** + * Set a provisioning URI to fetch an xml linphonerc config file from, at next LinphoneCore instantiation. + **/ + public void setProvisioningUri(String uri); + + /** + * Get the provisioning URI previously set. + **/ + public String getProvisioningUri(); + + /** + * Set an http proxy hostname or IP address to use for SIP connection. + */ + public void setHttpProxyHost(String host); + /** + * Set an http proxy port to use for SIP connection. + */ + public void setHttpProxyPort(int port); + /** + * Get the http proxy host previously set. + **/ + public String getHttpProxyHost(); + /** + * Get the http proxy port previously set. + **/ + public int getHttpProxyPort(); + + /* + * Set the nortp timeout (timeout after which call is closed if no RTP or RTCP packets are received). + */ + public void setNortpTimeout(int seconds); + + /** + * Get the nortp timeout. + * @return + */ + public int getNortpTimeout(); + } diff --git a/java/common/org/linphone/core/LinphoneCoreFactory.java b/java/common/org/linphone/core/LinphoneCoreFactory.java index 8019ec7bd..88a7651e4 100644 --- a/java/common/org/linphone/core/LinphoneCoreFactory.java +++ b/java/common/org/linphone/core/LinphoneCoreFactory.java @@ -167,4 +167,9 @@ abstract public class LinphoneCoreFactory { abstract public PresenceModel createPresenceModel(); abstract public PresenceModel createPresenceModel(PresenceActivityType type, String description); abstract public PresenceModel createPresenceModel(PresenceActivityType type, String description, String note, String lang); + + /* + * Create TunnelConfig object, used to configure voip anti blocking extension. + */ + abstract public TunnelConfig createTunnelConfig(); } diff --git a/java/common/org/linphone/core/LinphoneCoreListener.java b/java/common/org/linphone/core/LinphoneCoreListener.java index 4067380a0..b7457a777 100644 --- a/java/common/org/linphone/core/LinphoneCoreListener.java +++ b/java/common/org/linphone/core/LinphoneCoreListener.java @@ -53,15 +53,6 @@ public interface LinphoneCoreListener { */ void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf); - /** - * invoked when a new text message is received - * @param lc LinphoneCore - * @param room LinphoneChatRoom involved in this conversation. Can be be created by the framework in case the from is not present in any chat room. - * @param from LinphoneAddress from - * @param message incoming message - */ - void textReceived(LinphoneCore lc, LinphoneChatRoom cr, LinphoneAddress from, String message); - /** * invoked when a new dtmf is received * @param lc LinphoneCore diff --git a/java/common/org/linphone/core/LinphoneCoreListenerBase.java b/java/common/org/linphone/core/LinphoneCoreListenerBase.java index 158a871af..a7db59c11 100644 --- a/java/common/org/linphone/core/LinphoneCoreListenerBase.java +++ b/java/common/org/linphone/core/LinphoneCoreListenerBase.java @@ -38,13 +38,6 @@ public class LinphoneCoreListenerBase implements LinphoneCoreListener { } - @Override - public void textReceived(LinphoneCore lc, LinphoneChatRoom cr, - LinphoneAddress from, String message) { - // TODO Auto-generated method stub - - } - @Override public void dtmfReceived(LinphoneCore lc, LinphoneCall call, int dtmf) { // TODO Auto-generated method stub diff --git a/java/common/org/linphone/core/LinphoneProxyConfig.java b/java/common/org/linphone/core/LinphoneProxyConfig.java index e5381701e..12c6b1c1b 100644 --- a/java/common/org/linphone/core/LinphoneProxyConfig.java +++ b/java/common/org/linphone/core/LinphoneProxyConfig.java @@ -37,7 +37,7 @@ public interface LinphoneProxyConfig { public void done(); /** * Sets the user identity as a SIP address. - * @param identy This identity is normally formed with display name, username and domain, such as: Alice The REGISTER messages will have from and to set to this identity. + * @param identity This identity is normally formed with display name, username and domain, such as: Alice The REGISTER messages will have from and to set to this identity. */ public void setIdentity(String identity) throws LinphoneCoreException; /** @@ -46,6 +46,17 @@ public interface LinphoneProxyConfig { * @return The SIP identity is a SIP address (Display Name ) */ public String getIdentity(); + /** + * Sets the address of the proxy configuration + * @param address + */ + public void setAddress(LinphoneAddress address) throws LinphoneCoreException; + /** + *get linphoneAddress that belongs to this proxy configuration. + * + * @return LinphoneAddress + */ + public LinphoneAddress getAddress(); /** *Sets the proxy address * Examples of valid sip proxy address are: @@ -78,6 +89,13 @@ public interface LinphoneProxyConfig { * @return */ public String normalizePhoneNumber(String number); + /** + * Normalize a human readable sip uri into a fully qualified LinphoneAddress. + * A sip address should look like DisplayName \ . + * @param username the string to parse + * @return NULL if invalid input, normalized sip address otherwise. + */ + public LinphoneAddress normalizeSipUri(String username); /** * Useful function to automatically add international prefix to e164 phone numbers * @param prefix @@ -126,8 +144,7 @@ public interface LinphoneProxyConfig { /** * Indicates either or not, PUBLISH must be issued for this #LinphoneProxyConfig . *
In case this #LinphoneProxyConfig has been added to #LinphoneCore, follows the linphone_proxy_config_edit() rule. - * @param obj object pointer - * @param val if true, publish will be engaged + * @param enable if true, publish will be engaged * */ public void enablePublish(boolean enable); @@ -227,7 +244,7 @@ public interface LinphoneProxyConfig { /** * Set the outbound proxy realm. It is used in digest authentication to avoid * re-authentication if a previous token has already been provided. - * @param The new outbound proxy realm. + * @param realm The new outbound proxy realm. */ void setRealm(String realm); @@ -269,7 +286,7 @@ public interface LinphoneProxyConfig { /** * Return the international prefix for the given country - * @param country iso code + * @param iso code */ public int lookupCCCFromIso(String iso); diff --git a/java/common/org/linphone/core/TunnelConfig.java b/java/common/org/linphone/core/TunnelConfig.java new file mode 100644 index 000000000..a7eb28c3f --- /dev/null +++ b/java/common/org/linphone/core/TunnelConfig.java @@ -0,0 +1,53 @@ +package org.linphone.core; + +/** + * The TunnelConfig interface allows to configure information about a tunnel server (voip anti blocking). + * @author smorlat + * + */ +public interface TunnelConfig { + /** + * Get the hostname of the tunnel server + * @return + */ + String getHost(); + /** + * Set the hostname (or ip address) of the tunnel server. + * @param host + */ + void setHost(String host); + /** + * Get the port where to connect. + * @return + */ + int getPort(); + /** + * Set the port where to connect to the tunnel server. + * When not set, the default value is used (443). + * @param port + */ + void setPort(int port); + /** + * Get the remote udp mirror port, which is used to check udp connectivity of the network. + * @return + */ + int getRemoteUdpMirrorPort(); + /** + * Set the udp mirror port, which is used to check udp connectivity. + * When not set, a default value of 12345 is used. + * @param remoteUdpMirrorPort + */ + void setRemoteUdpMirrorPort(int remoteUdpMirrorPort); + /** + * Get the maximum amount of time for waiting for UDP packets to come back during + * the UDP connectivity check, in milliseconds. + * + * @return + */ + int getDelay(); + /** + * Set the maximum amount of time for waiting for UDP packets to come back during + * the UDP connectivity check, in milliseconds. + */ + void setDelay(int delay); +} diff --git a/java/impl/org/linphone/core/LinphoneCallImpl.java b/java/impl/org/linphone/core/LinphoneCallImpl.java index de9e25364..f04ce86d8 100644 --- a/java/impl/org/linphone/core/LinphoneCallImpl.java +++ b/java/impl/org/linphone/core/LinphoneCallImpl.java @@ -44,6 +44,7 @@ class LinphoneCallImpl implements LinphoneCall { private native float getCurrentQuality(long nativePtr); private native float getAverageQuality(long nativePtr); private native boolean mediaInProgress(long nativePtr); + private native void setListener(long ptr, LinphoneCallListener listener); /* * This method must always be called from JNI, nothing else. @@ -254,5 +255,15 @@ class LinphoneCallImpl implements LinphoneCall { public LinphonePlayer getPlayer() { return new LinphonePlayerImpl(getPlayer(nativePtr)); } + + private native long getChatRoom(long nativePtr); + @Override + public LinphoneChatRoom getChatRoom() { + return new LinphoneChatRoomImpl(getChatRoom(nativePtr)); + } + @Override + public void setListener(LinphoneCallListener listener) { + setListener(nativePtr, listener); + } } diff --git a/java/impl/org/linphone/core/LinphoneCallLogImpl.java b/java/impl/org/linphone/core/LinphoneCallLogImpl.java index 7078a2a9f..3c78e4046 100644 --- a/java/impl/org/linphone/core/LinphoneCallLogImpl.java +++ b/java/impl/org/linphone/core/LinphoneCallLogImpl.java @@ -29,7 +29,7 @@ class LinphoneCallLogImpl implements LinphoneCallLog { private native int getStatus(long nativePtr); private native String getStartDate(long nativePtr); private native int getCallDuration(long nativePtr); - private native int getCallId(long nativePtr); + private native String getCallId(long nativePtr); private native long getTimestamp(long nativePtr); LinphoneCallLogImpl(long aNativePtr) { @@ -62,7 +62,7 @@ class LinphoneCallLogImpl implements LinphoneCallLog { public int getCallDuration() { return getCallDuration(nativePtr); } - public int getCallId() { + public String getCallId() { return getCallId(nativePtr); } diff --git a/java/impl/org/linphone/core/LinphoneCallParamsImpl.java b/java/impl/org/linphone/core/LinphoneCallParamsImpl.java index c4b356fa7..7a76d82f3 100644 --- a/java/impl/org/linphone/core/LinphoneCallParamsImpl.java +++ b/java/impl/org/linphone/core/LinphoneCallParamsImpl.java @@ -18,7 +18,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.linphone.core; +import org.linphone.core.LinphoneCore.MediaDirection; import org.linphone.core.LinphoneCore.MediaEncryption; +import org.linphone.core.LinphoneCore.StreamType; public class LinphoneCallParamsImpl implements LinphoneCallParams { protected final long nativePtr; @@ -107,6 +109,42 @@ public class LinphoneCallParamsImpl implements LinphoneCallParams { return getCustomHeader(nativePtr,name); } + private native void addCustomSdpAttribute(long nativePtr, String name, String value); + @Override + public void addCustomSdpAttribute(String name, String value) { + addCustomSdpAttribute(nativePtr, name, value); + } + + private native void addCustomSdpMediaAttribute(long nativePtr, int type, String name, String value); + @Override + public void addCustomSdpMediaAttribute(StreamType type, String name, String value) { + addCustomSdpMediaAttribute(nativePtr, type.mValue, name, value); + } + + private native String getCustomSdpAttribute(long nativePtr, String name); + @Override + public String getCustomSdpAttribute(String name) { + return getCustomSdpAttribute(nativePtr, name); + } + + private native String getCustomSdpMediaAttribute(long nativePtr, int type, String name); + @Override + public String getCustomSdpMediaAttribute(StreamType type, String name) { + return getCustomSdpMediaAttribute(nativePtr, type.mValue, name); + } + + private native void clearCustomSdpAttributes(long nativePtr); + @Override + public void clearCustomSdpAttributes() { + clearCustomSdpAttributes(nativePtr); + } + + private native void clearCustomSdpMediaAttributes(long nativePtr, int type); + @Override + public void clearCustomSdpMediaAttributes(StreamType type) { + clearCustomSdpMediaAttributes(nativePtr, type.mValue); + } + private native void setPrivacy(long nativePtr, int mask); @Override public void setPrivacy(int privacy_mask) { @@ -171,4 +209,40 @@ public class LinphoneCallParamsImpl implements LinphoneCallParams { public boolean videoMulticastEnabled() { return videoMulticastEnabled(nativePtr); } + + private native void enableRealTimeText(long nativePtr, boolean yesno); + @Override + public void enableRealTimeText(boolean yesno) { + enableRealTimeText(nativePtr, yesno); + } + + private native boolean realTimeTextEnabled(long nativePtr); + @Override + public boolean realTimeTextEnabled() { + return realTimeTextEnabled(nativePtr); + } + + private native int getAudioDirection(long nativePtr); + @Override + public MediaDirection getAudioDirection() { + return MediaDirection.fromInt(getAudioDirection(nativePtr)); + } + + private native int getVideoDirection(long nativePtr); + @Override + public MediaDirection getVideoDirection() { + return MediaDirection.fromInt(getVideoDirection(nativePtr)); + } + + private native void setAudioDirection(long nativePtr, int direction); + @Override + public void setAudioDirection(MediaDirection direction) { + setAudioDirection(nativePtr, direction.mValue); + } + + private native void setVideoDirection(long nativePtr, int direction); + @Override + public void setVideoDirection(MediaDirection direction) { + setVideoDirection(nativePtr, direction.mValue); + } } diff --git a/java/impl/org/linphone/core/LinphoneChatMessageImpl.java b/java/impl/org/linphone/core/LinphoneChatMessageImpl.java index 8665e4049..d71ffc6a5 100644 --- a/java/impl/org/linphone/core/LinphoneChatMessageImpl.java +++ b/java/impl/org/linphone/core/LinphoneChatMessageImpl.java @@ -16,7 +16,7 @@ public class LinphoneChatMessageImpl implements LinphoneChatMessage { private native void store(long ptr); private native int getStorageId(long ptr); private native void setFileTransferFilepath(long ptr, String path); - private native void downloadFile(long ptr); + private native int downloadFile(long ptr); private native void setListener(long ptr, LinphoneChatMessageListener listener); private native void unref(long ptr); @@ -146,12 +146,18 @@ public class LinphoneChatMessageImpl implements LinphoneChatMessage { } @Override - public void downloadFile() { - downloadFile(nativePtr); + public int downloadFile() { + return downloadFile(nativePtr); } @Override public void setListener(LinphoneChatMessageListener listener) { setListener(nativePtr, listener); } + + private native void putChar(long nativePtr, long character); + @Override + public void putChar(long character) throws LinphoneCoreException { + putChar(nativePtr, character); + } } diff --git a/java/impl/org/linphone/core/LinphoneChatRoomImpl.java b/java/impl/org/linphone/core/LinphoneChatRoomImpl.java index cfda7b6e2..18d294502 100644 --- a/java/impl/org/linphone/core/LinphoneChatRoomImpl.java +++ b/java/impl/org/linphone/core/LinphoneChatRoomImpl.java @@ -20,6 +20,7 @@ package org.linphone.core; import org.linphone.core.LinphoneChatMessage.State; import org.linphone.core.LinphoneChatMessage.StateListener; +import org.linphone.core.LinphoneCall; @SuppressWarnings("deprecation") class LinphoneChatRoomImpl implements LinphoneChatRoom { @@ -38,7 +39,6 @@ class LinphoneChatRoomImpl implements LinphoneChatRoom { private native boolean isRemoteComposing(long ptr); private native void markAsRead(long ptr); private native void deleteMessage(long room, long message); - private native void updateUrl(long room, long message); private native long createLinphoneChatMessage2(long ptr, String message, String url, int state, long timestamp, boolean isRead, boolean isIncoming); @@ -92,10 +92,6 @@ class LinphoneChatRoomImpl implements LinphoneChatRoom { } } - public void destroy() { - destroy(nativePtr); - } - public int getUnreadMessagesCount() { synchronized(getCore()){ return getUnreadMessagesCount(nativePtr); @@ -139,13 +135,6 @@ class LinphoneChatRoomImpl implements LinphoneChatRoom { } } - public void updateUrl(LinphoneChatMessage message) { - synchronized(getCore()){ - if (message != null) - updateUrl(nativePtr, ((LinphoneChatMessageImpl)message).getNativePtr()); - } - } - @Override public LinphoneChatMessage createLinphoneChatMessage(String message, String url, State state, long timestamp, boolean isRead, @@ -182,4 +171,16 @@ class LinphoneChatRoomImpl implements LinphoneChatRoom { public void sendChatMessage(LinphoneChatMessage message) { sendChatMessage(nativePtr, message, ((LinphoneChatMessageImpl)message).getNativePtr()); } + + private native Object getCall(long nativePtr); + @Override + public LinphoneCall getCall() { + return (LinphoneCall) getCall(nativePtr); + } + + private native long getChar(long nativePtr); + @Override + public long getChar() { + return getChar(nativePtr); + } } diff --git a/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java b/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java index 0d6fc777b..7bb174ed4 100644 --- a/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java +++ b/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java @@ -193,4 +193,10 @@ public class LinphoneCoreFactoryImpl extends LinphoneCoreFactory { public PresenceModel createPresenceModel(PresenceActivityType type, String description, String note, String lang) { return new PresenceModelImpl(type, description, note, lang); } + + private native Object _createTunnelConfig(); + @Override + public TunnelConfig createTunnelConfig() { + return (TunnelConfig)_createTunnelConfig(); + } } diff --git a/java/impl/org/linphone/core/LinphoneCoreImpl.java b/java/impl/org/linphone/core/LinphoneCoreImpl.java index 3e7fd1910..535d1dad7 100644 --- a/java/impl/org/linphone/core/LinphoneCoreImpl.java +++ b/java/impl/org/linphone/core/LinphoneCoreImpl.java @@ -62,7 +62,9 @@ class LinphoneCoreImpl implements LinphoneCore { private native boolean isInComingInvitePending(long nativePtr); private native void acceptCall(long nativePtr, long call); private native long getCallLog(long nativePtr,int position); + native private long[] getCallLogs(long nativePtr); private native int getNumberOfCallLogs(long nativePtr); + private native long getLastOutgoingCallLog(long nativePtr); private native void delete(long nativePtr); private native void setNetworkStateReachable(long nativePtr,boolean isReachable); private native boolean isNetworkStateReachable(long nativePtr); @@ -98,6 +100,7 @@ class LinphoneCoreImpl implements LinphoneCore { private native void setPresenceModel(long nativePtr, long presencePtr); private native Object getPresenceModel(long nativePtr); private native long getOrCreateChatRoom(long nativePtr,String to); + private native long getChatRoom(long nativePtr,long to); private native void enableVideo(long nativePtr,boolean vcap_enabled,boolean display_enabled); private native boolean isVideoEnabled(long nativePtr); private native boolean isVideoSupported(long nativePtr); @@ -105,9 +108,10 @@ class LinphoneCoreImpl implements LinphoneCore { private native int getFirewallPolicy(long nativePtr); private native void setStunServer(long nativePtr, String stun_server); private native String getStunServer(long nativePtr); - private native long createDefaultCallParams(long nativePtr); private native int updateCall(long ptrLc, long ptrCall, long ptrParams); + private native int getUploadBandwidth(long nativePtr); private native void setUploadBandwidth(long nativePtr, int bw); + private native int getDownloadBandwidth(long nativePtr); private native void setDownloadBandwidth(long nativePtr, int bw); private native void setPreferredVideoSize(long nativePtr, int width, int heigth); private native void setPreferredVideoSizeByName(long nativePtr, String name); @@ -159,8 +163,10 @@ class LinphoneCoreImpl implements LinphoneCore { private native String getPrimaryContactUsername(long nativePtr); private native String getPrimaryContactDisplayName(long nativePtr); private native void setChatDatabasePath(long nativePtr, String path); + private native void setCallLogsDatabasePath(long nativePtr, String path); private native long[] getChatRooms(long nativePtr); private native int migrateToMultiTransport(long nativePtr); + private native void migrateCallLogs(long nativePtr); private native void setCallErrorTone(long nativePtr, int reason, String path); private native void enableSdp200Ack(long nativePtr,boolean enable); private native boolean isSdp200AckEnabled(long nativePtr); @@ -205,7 +211,7 @@ class LinphoneCoreImpl implements LinphoneCore { WifiManager wifiManager=(WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); MulticastLock lock = wifiManager.createMulticastLock("linphonecore ["+ nativePtr+"] multicast-lock"); lock.setReferenceCounted(true); - setAndroidMulticastLock(nativePtr,lock); + setAndroidMulticastLock(nativePtr, lock); } } @@ -216,7 +222,7 @@ class LinphoneCoreImpl implements LinphoneCore { public synchronized void removeAuthInfo(LinphoneAuthInfo info) { isValid(); - removeAuthInfo(nativePtr,((LinphoneAuthInfoImpl)info).nativePtr); + removeAuthInfo(nativePtr, ((LinphoneAuthInfoImpl) info).nativePtr); } public synchronized LinphoneProxyConfig getDefaultProxyConfig() { @@ -281,16 +287,23 @@ class LinphoneCoreImpl implements LinphoneCore { } public synchronized void acceptCall(LinphoneCall aCall) { isValid(); - acceptCall(nativePtr,((LinphoneCallImpl)aCall).nativePtr); + acceptCall(nativePtr, ((LinphoneCallImpl) aCall).nativePtr); } public synchronized LinphoneCallLog[] getCallLogs() { - isValid(); - LinphoneCallLog[] logs = new LinphoneCallLog[getNumberOfCallLogs(nativePtr)]; - for (int i=0;i < getNumberOfCallLogs(nativePtr);i++) { - logs[i] = new LinphoneCallLogImpl(getCallLog(nativePtr, i)); + long[] typesPtr = getCallLogs(nativePtr); + if (typesPtr == null) return null; + isValid(); + LinphoneCallLog[] logs = new LinphoneCallLog[typesPtr.length]; + for (int i=0;i < logs.length; i++) { + logs[i] = new LinphoneCallLogImpl(typesPtr[i]); } return logs; } + public synchronized LinphoneCallLog getLastOutgoingCallLog(){ + isValid(); + long callLog = getLastOutgoingCallLog(nativePtr); + return new LinphoneCallLogImpl(callLog); + } public synchronized void destroy() { setAndroidPowerManager(null); delete(nativePtr); @@ -458,6 +471,9 @@ class LinphoneCoreImpl implements LinphoneCore { public synchronized LinphoneChatRoom getOrCreateChatRoom(String to) { return new LinphoneChatRoomImpl(getOrCreateChatRoom(nativePtr,to)); } + public synchronized LinphoneChatRoom getChatRoom(LinphoneAddress to) { + return new LinphoneChatRoomImpl(getChatRoom(nativePtr,((LinphoneAddressImpl)to).nativePtr)); + } public synchronized void setPreviewWindow(Object w) { setPreviewWindowId(nativePtr,w); } @@ -490,10 +506,6 @@ class LinphoneCoreImpl implements LinphoneCore { setStunServer(nativePtr,stunServer); } - public synchronized LinphoneCallParams createDefaultCallParameters() { - return new LinphoneCallParamsImpl(createDefaultCallParams(nativePtr)); - } - public synchronized LinphoneCall inviteAddressWithParams(LinphoneAddress to, LinphoneCallParams params) throws LinphoneCoreException { long ptrDestination = ((LinphoneAddressImpl)to).nativePtr; long ptrParams =((LinphoneCallParamsImpl)params).nativePtr; @@ -512,10 +524,19 @@ class LinphoneCoreImpl implements LinphoneCore { return updateCall(nativePtr, ptrCall, ptrParams); } + + public synchronized int getUploadBandwidth() { + return getUploadBandwidth(nativePtr); + } + public synchronized void setUploadBandwidth(int bw) { setUploadBandwidth(nativePtr, bw); } + public synchronized int getDownloadBandwidth() { + return getDownloadBandwidth(nativePtr); + } + public synchronized void setDownloadBandwidth(int bw) { setDownloadBandwidth(nativePtr, bw); } @@ -803,10 +824,10 @@ class LinphoneCoreImpl implements LinphoneCore { tunnelAddServerAndMirror(nativePtr, host, port, mirror, ms); } - private native void tunnelAddServer(long nativePtr, TunnelConfig config); + private native void tunnelAddServer(long nativePtr, long configPtr); @Override public synchronized void tunnelAddServer(TunnelConfig config) { - tunnelAddServer(nativePtr, config); + tunnelAddServer(nativePtr, ((TunnelConfigImpl)config).mNativePtr); } private native final TunnelConfig[] tunnelGetServers(long nativePtr); @@ -1046,10 +1067,10 @@ class LinphoneCoreImpl implements LinphoneCore { public synchronized boolean needsEchoCalibration() { return needsEchoCalibration(nativePtr); } - private native boolean needsEchoCanceler(long ptr); + private native boolean hasBuiltInEchoCanceler(long ptr); @Override - public synchronized boolean needsEchoCanceler() { - return needsEchoCanceler(nativePtr); + public synchronized boolean hasBuiltInEchoCanceler() { + return hasBuiltInEchoCanceler(nativePtr); } private native void declineCall(long coreptr, long callptr, int reason); @Override @@ -1090,7 +1111,7 @@ class LinphoneCoreImpl implements LinphoneCore { private native void setSipDscp(long nativePtr, int dscp); @Override public synchronized void setSipDscp(int dscp) { - setSipDscp(nativePtr,dscp); + setSipDscp(nativePtr, dscp); } private native int getSipDscp(long nativePtr); @@ -1162,6 +1183,10 @@ class LinphoneCoreImpl implements LinphoneCore { setChatDatabasePath(nativePtr, path); } + public synchronized void setCallLogsDatabasePath(String path) { + setCallLogsDatabasePath(nativePtr, path); + } + public synchronized LinphoneChatRoom[] getChatRooms() { long[] typesPtr = getChatRooms(nativePtr); if (typesPtr == null) return null; @@ -1213,6 +1238,11 @@ class LinphoneCoreImpl implements LinphoneCore { return migrateToMultiTransport(nativePtr); } + @Override + public synchronized void migrateCallLogs() { + migrateCallLogs(nativePtr); + } + private native boolean acceptEarlyMedia(long lc, long call); @Override public synchronized boolean acceptEarlyMedia(LinphoneCall call) { @@ -1246,7 +1276,7 @@ class LinphoneCoreImpl implements LinphoneCore { private native void setMtu(long nativePtr, int mtu); @Override public synchronized void setMtu(int mtu) { - setMtu(nativePtr,mtu); + setMtu(nativePtr, mtu); } private native int getMtu(long nativePtr); @Override @@ -1255,7 +1285,7 @@ class LinphoneCoreImpl implements LinphoneCore { } @Override public synchronized void enableSdp200Ack(boolean enable) { - enableSdp200Ack(nativePtr,enable); + enableSdp200Ack(nativePtr, enable); } @Override public synchronized boolean isSdp200AckEnabled() { @@ -1310,7 +1340,7 @@ class LinphoneCoreImpl implements LinphoneCore { @Override public synchronized void enableAdaptiveRateControl(boolean enable) { - enableAdaptiveRateControl(nativePtr,enable); + enableAdaptiveRateControl(nativePtr, enable); } @Override @@ -1393,7 +1423,7 @@ class LinphoneCoreImpl implements LinphoneCore { private native void setPreferredFramerate(long nativePtr, float fps); @Override public void setPreferredFramerate(float fps) { - setPreferredFramerate(nativePtr,fps); + setPreferredFramerate(nativePtr, fps); } private native float getPreferredFramerate(long nativePtr); @Override @@ -1479,4 +1509,84 @@ class LinphoneCoreImpl implements LinphoneCore { public boolean dnsSrvEnabled() { return dnsSrvEnabled(nativePtr); } + + private native void setVideoPreset(long nativePtr, String preset); + @Override + public void setVideoPreset(String preset) { + setVideoPreset(nativePtr, preset); + } + + private native String getVideoPreset(long nativePtr); + @Override + public String getVideoPreset() { + return getVideoPreset(nativePtr); + } + private native long createCallParams(long nativePtr, long callPtr); + @Override + public LinphoneCallParams createCallParams(LinphoneCall call) { + long callptr = 0; + if (call!=null) callptr = ((LinphoneCallImpl)call).nativePtr; + long ptr = createCallParams(nativePtr, callptr); + return new LinphoneCallParamsImpl(ptr); + } + private native void setProvisioningUri(long nativePtr, String uri); + @Override + public void setProvisioningUri(String uri){ + setProvisioningUri(nativePtr, uri); + } + + private native String getProvisioningUri(long nativePtr); + @Override + public String getProvisioningUri(){ + return getProvisioningUri(nativePtr); + } + private native int getGlobalState(long nativePtr); + public GlobalState getGlobalState(){ + return GlobalState.fromInt(getGlobalState(nativePtr)); + } + private native void setHttpProxyHost(long nativePtr, String host); + @Override + public void setHttpProxyHost(String host){ + setHttpProxyHost(nativePtr, host); + } + + private native void setHttpProxyPort(long nativePtr, int port); + @Override + public void setHttpProxyPort(int port){ + setHttpProxyPort(nativePtr, port); + } + + private native String getHttpProxyHost(long nativePtr); + @Override + public String getHttpProxyHost(){ + return getHttpProxyHost(nativePtr); + } + + private native int getHttpProxyPort(long nativePtr); + @Override + public int getHttpProxyPort(){ + return getHttpProxyPort(nativePtr); + } + private native void setSipTransportTimeout(long nativePtr, int timeout_ms); + @Override + public void setSipTransportTimeout(int timeout_ms){ + setSipTransportTimeout(nativePtr, timeout_ms); + } + + private native int getSipTransportTimeout(long nativePtr); + @Override + public int getSipTransportTimeout(){ + return getSipTransportTimeout(nativePtr); + } + private native void setNortpTimeout(long nativePtr, int timeout); + @Override + public void setNortpTimeout(int timeout){ + setNortpTimeout(nativePtr, timeout); + } + + private native int getNortpTimeout(long nativePtr); + @Override + public int getNortpTimeout(){ + return getNortpTimeout(nativePtr); + } } diff --git a/java/impl/org/linphone/core/LinphoneProxyConfigImpl.java b/java/impl/org/linphone/core/LinphoneProxyConfigImpl.java index 33ac36f8f..e887f4eac 100644 --- a/java/impl/org/linphone/core/LinphoneProxyConfigImpl.java +++ b/java/impl/org/linphone/core/LinphoneProxyConfigImpl.java @@ -70,6 +70,8 @@ class LinphoneProxyConfigImpl implements LinphoneProxyConfig { private native void setIdentity(long ptr,String identity); private native String getIdentity(long ptr); + private native void setAddress(long ptr, long address); + private native long getAddress(long ptr); private native int setProxy(long ptr,String proxy); private native String getProxy(long ptr); @@ -82,6 +84,7 @@ class LinphoneProxyConfigImpl implements LinphoneProxyConfig { private native String getDialPrefix(long ptr); private native String normalizePhoneNumber(long ptr,String number); + private native long normalizeSipUri(long ptr,String username); private native String getDomain(long ptr); @@ -125,6 +128,11 @@ class LinphoneProxyConfigImpl implements LinphoneProxyConfig { setIdentity(nativePtr,identity); } + public void setAddress(LinphoneAddress address) throws LinphoneCoreException { + isValid(); + setAddress(nativePtr,((LinphoneAddressImpl)address).nativePtr); + } + public void setProxy(String proxyUri) throws LinphoneCoreException { isValid(); if (setProxy(nativePtr,proxyUri)!=0) { @@ -135,6 +143,15 @@ class LinphoneProxyConfigImpl implements LinphoneProxyConfig { isValid(); return normalizePhoneNumber(nativePtr,number); } + public LinphoneAddress normalizeSipUri(String username) { + isValid(); + long ptr = normalizeSipUri(nativePtr,username); + if (ptr==0) { + return null; + } else { + return new LinphoneAddressImpl(ptr,LinphoneAddressImpl.WrapMode.FromConst); + } + } public void setDialPrefix(String prefix) { isValid(); setDialPrefix(nativePtr, prefix); @@ -159,6 +176,15 @@ class LinphoneProxyConfigImpl implements LinphoneProxyConfig { isValid(); return getIdentity(nativePtr); } + public LinphoneAddress getAddress() { + isValid(); + long ptr = getAddress(nativePtr); + if (ptr==0) { + return null; + } else { + return new LinphoneAddressImpl(ptr,LinphoneAddressImpl.WrapMode.FromConst); + } + } public String getProxy() { isValid(); return getProxy(nativePtr); diff --git a/java/impl/org/linphone/core/TunnelConfig.java b/java/impl/org/linphone/core/TunnelConfig.java deleted file mode 100644 index 9801f0fbd..000000000 --- a/java/impl/org/linphone/core/TunnelConfig.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.linphone.core; - -public class TunnelConfig { - private String host = null; - private int port = 443; - private int remoteUdpMirrorPort = 12345; - private int delay = 1000; - - public String getHost() { - return host; - } - - public void setHost(String host) { - this.host = host; - } - - public int getPort() { - return port; - } - - public void setPort(int port) { - this.port = port; - } - - public int getRemoteUdpMirrorPort() { - return remoteUdpMirrorPort; - } - - public void setRemoteUdpMirrorPort(int remoteUdpMirrorPort) { - this.remoteUdpMirrorPort = remoteUdpMirrorPort; - } - - public int getDelay() { - return delay; - } - - public void setDelay(int delay) { - this.delay = delay; - } -} diff --git a/java/impl/org/linphone/core/TunnelConfigImpl.java b/java/impl/org/linphone/core/TunnelConfigImpl.java new file mode 100644 index 000000000..d7fd0c873 --- /dev/null +++ b/java/impl/org/linphone/core/TunnelConfigImpl.java @@ -0,0 +1,53 @@ +package org.linphone.core; + +public class TunnelConfigImpl implements TunnelConfig{ + long mNativePtr; + protected TunnelConfigImpl(long nativePtr){ + mNativePtr = nativePtr; + } + private native String getHost(long nativePtr); + @Override + public String getHost() { + return getHost(mNativePtr); + } + private native void setHost(long nativePtr, String host); + @Override + public void setHost(String host) { + setHost(mNativePtr, host); + } + private native int getPort(long nativePtr); + @Override + public int getPort() { + return getPort(mNativePtr); + } + private native void setPort(long nativePtr, int port); + @Override + public void setPort(int port) { + setPort(mNativePtr, port); + } + private native int getRemoteUdpMirrorPort(long nativePtr); + @Override + public int getRemoteUdpMirrorPort() { + return getRemoteUdpMirrorPort(mNativePtr); + } + private native void setRemoteUdpMirrorPort(long nativePtr, int remoteUdpMirrorPort); + @Override + public void setRemoteUdpMirrorPort(int remoteUdpMirrorPort) { + setRemoteUdpMirrorPort(mNativePtr, remoteUdpMirrorPort); + } + private native int getDelay(long nativePtr); + @Override + public int getDelay() { + return getDelay(mNativePtr); + } + private native void setDelay(long nativePtr, int delay); + @Override + public void setDelay(int delay) { + setDelay(mNativePtr, delay); + } + private native void enableSip(long nativePtr, boolean enabled); + private native void destroy(long nativePtr); + protected void finalize() throws Throwable { + if (mNativePtr!=0) destroy(mNativePtr); + } +} diff --git a/linphone.spec.in b/linphone.spec.in index f9e954945..fa5541a0a 100644 --- a/linphone.spec.in +++ b/linphone.spec.in @@ -80,7 +80,11 @@ rm -rf $RPM_BUILD_ROOT %files -f %{name}.lang %defattr(-,root,root) %doc AUTHORS ChangeLog COPYING NEWS README TODO -%{_bindir}/* +%{_bindir}/linphone +%{_bindir}/linphonec +%{_bindir}/linphonecsh +%{_bindir}/lp-autoanswer +%{_bindir}/lp-test-ecc %{_libdir}/*.so.* %{_mandir}/* %{_datadir}/applications/%{name}.desktop @@ -93,6 +97,9 @@ rm -rf $RPM_BUILD_ROOT %files devel %defattr(-,root,root) +%{_bindir}/lpc2xml_test +%{_bindir}/xml2lpc_test +%{_bindir}/lp-gen-wrappers %{_includedir}/linphone %{_libdir}/*.a %{_libdir}/*.la diff --git a/m4/readline.m4 b/m4/readline.m4 index 16065e348..24cb1d71e 100644 --- a/m4/readline.m4 +++ b/m4/readline.m4 @@ -12,7 +12,7 @@ AC_ARG_WITH( readline, [ readline_prefix="/usr" ] ) -if test "$readline_prefix" != "none"; then +if test "$readline_prefix" != "none" -a "$readline_prefix" != "no"; then if test "$readline_prefix" != "/usr"; then READLINE_CFLAGS="-I$readline_prefix/include" diff --git a/pixmaps/CMakeLists.txt b/pixmaps/CMakeLists.txt index 301a6a442..c055425a8 100644 --- a/pixmaps/CMakeLists.txt +++ b/pixmaps/CMakeLists.txt @@ -20,50 +20,120 @@ # ############################################################################ -set(PIXMAPS - active_chat.png - addcall-green.png - call.png - call_status_incoming.png - call_status_outgoing.png - chat_message_delivered.png - chat_message_inprogress.png - chat_message_not_delivered.png - chat.png - composing_active_chat.png - composing_chat.png - contact-orange.png - contact_starred.png - contact_unstarred.png - dialer-orange.png - dialer.png - history-orange.png - hold_off.png - hold_on.png - linphone-banner.png - linphone.icns - linphone.png - mic_active.png - mic_muted.png - notok.png - ok.png - speaker.png - startcall-green.png - startcall-small.png - status-green.png - status-offline.png - status-orange.png - status-red.png - stopcall-red.png - stopcall-small.png -) +set(ICONS_INSTALL_DIR ${PACKAGE_DATA_DIR}/icons/hicolor) -install(FILES ${PIXMAPS} +install(FILES "linphone.icns" "linphone-banner.png" DESTINATION ${PACKAGE_DATA_DIR}/pixmaps/linphone PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ ) +install(FILES + svg/linphone-micro-muted.svg + svg/linphone-speaker-muted.svg + svg/linphone-micro-enabled.svg + svg/linphone-speaker-enabled.svg + svg/linphone-status-online.svg + svg/linphone-status-away.svg + svg/linphone-status-donotdisturb.svg + svg/linphone-status-offline.svg + svg/linphone-call-status-incoming.svg + svg/linphone-call-status-missed.svg + svg/linphone-call-status-outgoing.svg + svg/linphone-chat-new-message-and-writing.svg + svg/linphone-chat-new-message.svg + svg/linphone-chat-nothing.svg + svg/linphone-chat-writing.svg + svg/linphone-ok.svg + svg/linphone-inprogress.svg + svg/linphone-failed.svg + svg/linphone-camera-enabled.svg + svg/linphone-camera-disabled.svg + svg/linphone-security-ok.svg + svg/linphone-security-pending.svg + svg/linphone-media-play.svg + svg/linphone-media-pause.svg + svg/linphone-warning.svg + DESTINATION ${ICONS_INSTALL_DIR}/scalable/status + PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ +) + +install(FILES + svg/linphone-start-call.svg + svg/linphone-add-call.svg + svg/linphone-hold-off.svg + svg/linphone-hold-on.svg + svg/linphone-start-call2.svg + svg/linphone-start-chat.svg + svg/linphone-history.svg + svg/linphone-edit.svg + svg/linphone-delete.svg + svg/linphone-contact-add.svg + svg/linphone-conference-start.svg + svg/linphone-call-transfer.svg + svg/linphone-record.svg + svg/linphone-chat-send.svg + DESTINATION ${ICONS_INSTALL_DIR}/scalable/actions + PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ +) + +install(FILES + linphone-micro-muted.png + linphone-speaker-muted.png + linphone-micro-enabled.png + linphone-speaker-enabled.png + linphone-status-online.png + linphone-status-away.png + linphone-status-donotdisturb.png + linphone-status-offline.png + linphone-chat-nothing.png + linphone-chat-new-message.png + linphone-chat-writing.png + linphone-chat-new-message-and-writing.png + linphone-call-status-incoming.png + linphone-call-status-outgoing.png + linphone-call-status-missed.png + linphone-ok.png + linphone-inprogress.png + linphone-failed.png + linphone-camera-enabled.png + linphone-camera-disabled.png + linphone-security-ok.png + linphone-security-pending.png + linphone-media-play.png + linphone-media-pause.png + linphone-warning.png + DESTINATION ${ICONS_INSTALL_DIR}/48x48/status + PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ +) + +install(FILES + linphone-start-call2.png + linphone-add-call.png + linphone-start-call.png + linphone-start-chat.png + linphone-stop-call.png + linphone-hold-on.png + linphone-hold-off.png + linphone-history.png + linphone-edit.png + linphone-delete.png + linphone-contact-add.png + linphone-conference-start.png + linphone-call-transfer.png + linphone-record.png + linphone-chat-send.png + DESTINATION ${ICONS_INSTALL_DIR}/48x48/actions + PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ +) + install(FILES linphone.png - DESTINATION ${PACKAGE_DATA_DIR}/icons/hicolor/48x48/apps + DESTINATION ${ICONS_INSTALL_DIR}/48x48/apps PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ ) + +if(WIN32) + install(FILES index.theme + DESTINATION ${ICONS_INSTALL_DIR} + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ + ) +endif() diff --git a/pixmaps/Makefile.am b/pixmaps/Makefile.am index 10ad6856c..96ded8baa 100644 --- a/pixmaps/Makefile.am +++ b/pixmaps/Makefile.am @@ -1,29 +1,103 @@ pixmapdir=$(datadir)/pixmaps/linphone +dist_pixmap_DATA= \ + linphone-banner.png \ + linphone.icns -pixmap_DATA= \ - hold_on.png hold_off.png \ - mic_muted.png mic_active.png \ - linphone.png linphone-banner.png \ - status-green.png \ - status-orange.png \ - status-red.png \ - status-offline.png \ - call.png \ - chat.png active_chat.png composing_chat.png composing_active_chat.png\ - chat_message_inprogress.png chat_message_delivered.png chat_message_not_delivered.png\ - contact-orange.png dialer-orange.png history-orange.png\ - startcall-green.png startcall-small.png stopcall-red.png stopcall-small.png addcall-green.png linphone.icns \ - contact_starred.png contact_unstarred.png \ - speaker.png \ - call_status_incoming.png call_status_outgoing.png \ - ok.png \ - dialer.png \ - notok.png +iconsdir=$(datadir)/icons/hicolor +if BUILD_WIN32 + dist_icons_DATA=index.theme +endif +appiconsdir=$(iconsdir)/48x48/apps +dist_appicons_DATA= linphone.png -iconsdir=$(datadir)/icons/hicolor/48x48/apps +status48iconsdir=$(iconsdir)/48x48/status +dist_status48icons_DATA= \ + linphone-micro-muted.png \ + linphone-speaker-muted.png \ + linphone-micro-enabled.png \ + linphone-speaker-enabled.png \ + linphone-status-online.png \ + linphone-status-away.png \ + linphone-status-donotdisturb.png \ + linphone-status-offline.png \ + linphone-chat-nothing.png \ + linphone-chat-new-message.png \ + linphone-chat-writing.png \ + linphone-chat-new-message-and-writing.png \ + linphone-call-status-incoming.png \ + linphone-call-status-outgoing.png \ + linphone-call-status-missed.png \ + linphone-ok.png \ + linphone-inprogress.png \ + linphone-failed.png \ + linphone-camera-enabled.png \ + linphone-camera-disabled.png \ + linphone-security-ok.png \ + linphone-security-pending.png \ + linphone-media-play.png \ + linphone-media-pause.png \ + linphone-warning.png -icons_DATA= linphone.png +statussvgiconsdir=$(iconsdir)/scalable/status +dist_statussvgicons_DATA= \ + svg/linphone-micro-muted.svg \ + svg/linphone-speaker-muted.svg \ + svg/linphone-micro-enabled.svg \ + svg/linphone-speaker-enabled.svg \ + svg/linphone-status-online.svg \ + svg/linphone-status-away.svg \ + svg/linphone-status-donotdisturb.svg \ + svg/linphone-status-offline.svg \ + svg/linphone-call-status-incoming.svg \ + svg/linphone-call-status-missed.svg \ + svg/linphone-call-status-outgoing.svg \ + svg/linphone-chat-new-message-and-writing.svg \ + svg/linphone-chat-new-message.svg \ + svg/linphone-chat-nothing.svg \ + svg/linphone-chat-writing.svg \ + svg/linphone-ok.svg \ + svg/linphone-inprogress.svg \ + svg/linphone-failed.svg \ + svg/linphone-camera-enabled.svg \ + svg/linphone-camera-disabled.svg \ + svg/linphone-security-ok.svg \ + svg/linphone-security-pending.svg \ + svg/linphone-media-play.svg \ + svg/linphone-media-pause.svg \ + svg/linphone-warning.svg +actions48iconsdir=$(iconsdir)/48x48/actions +dist_actions48icons_DATA= \ + linphone-start-call2.png \ + linphone-add-call.png \ + linphone-start-call.png \ + linphone-start-chat.png \ + linphone-stop-call.png \ + linphone-hold-on.png \ + linphone-hold-off.png \ + linphone-history.png \ + linphone-edit.png \ + linphone-delete.png \ + linphone-contact-add.png \ + linphone-conference-start.png \ + linphone-call-transfer.png \ + linphone-record.png \ + linphone-chat-send.png -EXTRA_DIST=$(pixmap_DATA) $(icons_DATA) +actionssvgiconsdir=$(iconsdir)/scalable/actions +dist_actionssvgicons_DATA= \ + svg/linphone-start-call.svg \ + svg/linphone-add-call.svg \ + svg/linphone-hold-off.svg \ + svg/linphone-hold-on.svg \ + svg/linphone-start-call2.svg \ + svg/linphone-start-chat.svg \ + svg/linphone-history.svg \ + svg/linphone-edit.svg \ + svg/linphone-delete.svg \ + svg/linphone-contact-add.svg \ + svg/linphone-conference-start.svg \ + svg/linphone-call-transfer.svg \ + svg/linphone-record.svg \ + svg/linphone-chat-send.svg diff --git a/pixmaps/active_chat.png b/pixmaps/active_chat.png deleted file mode 100644 index ef3cedd1d..000000000 Binary files a/pixmaps/active_chat.png and /dev/null differ diff --git a/pixmaps/addcall-green.png b/pixmaps/addcall-green.png deleted file mode 100644 index 9de8463ca..000000000 Binary files a/pixmaps/addcall-green.png and /dev/null differ diff --git a/pixmaps/call.png b/pixmaps/call.png deleted file mode 100644 index 7edf53556..000000000 Binary files a/pixmaps/call.png and /dev/null differ diff --git a/pixmaps/call_status_incoming.png b/pixmaps/call_status_incoming.png deleted file mode 100644 index 72ca1330e..000000000 Binary files a/pixmaps/call_status_incoming.png and /dev/null differ diff --git a/pixmaps/call_status_outgoing.png b/pixmaps/call_status_outgoing.png deleted file mode 100644 index aa15b3bea..000000000 Binary files a/pixmaps/call_status_outgoing.png and /dev/null differ diff --git a/pixmaps/chat.png b/pixmaps/chat.png deleted file mode 100644 index 50a23af57..000000000 Binary files a/pixmaps/chat.png and /dev/null differ diff --git a/pixmaps/chat_message_delivered.png b/pixmaps/chat_message_delivered.png deleted file mode 100644 index 5cb746551..000000000 Binary files a/pixmaps/chat_message_delivered.png and /dev/null differ diff --git a/pixmaps/chat_message_inprogress.png b/pixmaps/chat_message_inprogress.png deleted file mode 100644 index 2ffcbca35..000000000 Binary files a/pixmaps/chat_message_inprogress.png and /dev/null differ diff --git a/pixmaps/chat_message_not_delivered.png b/pixmaps/chat_message_not_delivered.png deleted file mode 100644 index cf9c610c0..000000000 Binary files a/pixmaps/chat_message_not_delivered.png and /dev/null differ diff --git a/pixmaps/composing_active_chat.png b/pixmaps/composing_active_chat.png deleted file mode 100644 index 77da9e37f..000000000 Binary files a/pixmaps/composing_active_chat.png and /dev/null differ diff --git a/pixmaps/composing_chat.png b/pixmaps/composing_chat.png deleted file mode 100644 index 2d329ed21..000000000 Binary files a/pixmaps/composing_chat.png and /dev/null differ diff --git a/pixmaps/contact-orange.png b/pixmaps/contact-orange.png deleted file mode 100644 index 53ba07ed8..000000000 Binary files a/pixmaps/contact-orange.png and /dev/null differ diff --git a/pixmaps/contact_starred.png b/pixmaps/contact_starred.png deleted file mode 100644 index 45b5d6206..000000000 Binary files a/pixmaps/contact_starred.png and /dev/null differ diff --git a/pixmaps/contact_unstarred.png b/pixmaps/contact_unstarred.png deleted file mode 100644 index 38fdbbb77..000000000 Binary files a/pixmaps/contact_unstarred.png and /dev/null differ diff --git a/pixmaps/dialer-orange.png b/pixmaps/dialer-orange.png deleted file mode 100644 index 2d715eac0..000000000 Binary files a/pixmaps/dialer-orange.png and /dev/null differ diff --git a/pixmaps/dialer.png b/pixmaps/dialer.png deleted file mode 100644 index 5da3ad70d..000000000 Binary files a/pixmaps/dialer.png and /dev/null differ diff --git a/pixmaps/history-orange.png b/pixmaps/history-orange.png deleted file mode 100644 index dc9bbf60a..000000000 Binary files a/pixmaps/history-orange.png and /dev/null differ diff --git a/pixmaps/hold_off.png b/pixmaps/hold_off.png deleted file mode 100644 index 3ba6746fb..000000000 Binary files a/pixmaps/hold_off.png and /dev/null differ diff --git a/pixmaps/hold_on.png b/pixmaps/hold_on.png deleted file mode 100644 index 776d5ddd4..000000000 Binary files a/pixmaps/hold_on.png and /dev/null differ diff --git a/pixmaps/index.theme b/pixmaps/index.theme new file mode 100644 index 000000000..d17354741 --- /dev/null +++ b/pixmaps/index.theme @@ -0,0 +1,1836 @@ +[Icon Theme] +Name=Hicolor +Comment=Fallback icon theme +Hidden=true +Directories=16x16/actions,16x16/animations,16x16/apps,16x16/categories,16x16/devices,16x16/emblems,16x16/emotes,16x16/filesystems,16x16/intl,16x16/mimetypes,16x16/places,16x16/status,16x16/stock/chart,16x16/stock/code,16x16/stock/data,16x16/stock/form,16x16/stock/image,16x16/stock/io,16x16/stock/media,16x16/stock/navigation,16x16/stock/net,16x16/stock/object,16x16/stock/table,16x16/stock/text,22x22/actions,22x22/animations,22x22/apps,22x22/categories,22x22/devices,22x22/emblems,22x22/emotes,22x22/filesystems,22x22/intl,22x22/mimetypes,22x22/places,22x22/status,22x22/stock/chart,22x22/stock/code,22x22/stock/data,22x22/stock/form,22x22/stock/image,22x22/stock/io,22x22/stock/media,22x22/stock/navigation,22x22/stock/net,22x22/stock/object,22x22/stock/table,22x22/stock/text,24x24/actions,24x24/animations,24x24/apps,24x24/categories,24x24/devices,24x24/emblems,24x24/emotes,24x24/filesystems,24x24/intl,24x24/mimetypes,24x24/places,24x24/status,24x24/stock/chart,24x24/stock/code,24x24/stock/data,24x24/stock/form,24x24/stock/image,24x24/stock/io,24x24/stock/media,24x24/stock/navigation,24x24/stock/net,24x24/stock/object,24x24/stock/table,24x24/stock/text,32x32/actions,32x32/animations,32x32/apps,32x32/categories,32x32/devices,32x32/emblems,32x32/emotes,32x32/filesystems,32x32/intl,32x32/mimetypes,32x32/places,32x32/status,32x32/stock/chart,32x32/stock/code,32x32/stock/data,32x32/stock/form,32x32/stock/image,32x32/stock/io,32x32/stock/media,32x32/stock/navigation,32x32/stock/net,32x32/stock/object,32x32/stock/table,32x32/stock/text,36x36/actions,36x36/animations,36x36/apps,36x36/categories,36x36/devices,36x36/emblems,36x36/emotes,36x36/filesystems,36x36/intl,36x36/mimetypes,36x36/places,36x36/status,36x36/stock/chart,36x36/stock/code,36x36/stock/data,36x36/stock/form,36x36/stock/image,36x36/stock/io,36x36/stock/media,36x36/stock/navigation,36x36/stock/net,36x36/stock/object,36x36/stock/table,36x36/stock/text,48x48/actions,48x48/animations,48x48/apps,48x48/categories,48x48/devices,48x48/emblems,48x48/emotes,48x48/filesystems,48x48/intl,48x48/mimetypes,48x48/places,48x48/status,48x48/stock/chart,48x48/stock/code,48x48/stock/data,48x48/stock/form,48x48/stock/image,48x48/stock/io,48x48/stock/media,48x48/stock/navigation,48x48/stock/net,48x48/stock/object,48x48/stock/table,48x48/stock/text,64x64/actions,64x64/animations,64x64/apps,64x64/categories,64x64/devices,64x64/emblems,64x64/emotes,64x64/filesystems,64x64/intl,64x64/mimetypes,64x64/places,64x64/status,64x64/stock/chart,64x64/stock/code,64x64/stock/data,64x64/stock/form,64x64/stock/image,64x64/stock/io,64x64/stock/media,64x64/stock/navigation,64x64/stock/net,64x64/stock/object,64x64/stock/table,64x64/stock/text,72x72/actions,72x72/animations,72x72/apps,72x72/categories,72x72/devices,72x72/emblems,72x72/emotes,72x72/filesystems,72x72/intl,72x72/mimetypes,72x72/places,72x72/status,72x72/stock/chart,72x72/stock/code,72x72/stock/data,72x72/stock/form,72x72/stock/image,72x72/stock/io,72x72/stock/media,72x72/stock/navigation,72x72/stock/net,72x72/stock/object,72x72/stock/table,72x72/stock/text,96x96/actions,96x96/animations,96x96/apps,96x96/categories,96x96/devices,96x96/emblems,96x96/emotes,96x96/filesystems,96x96/intl,96x96/mimetypes,96x96/places,96x96/status,96x96/stock/chart,96x96/stock/code,96x96/stock/data,96x96/stock/form,96x96/stock/image,96x96/stock/io,96x96/stock/media,96x96/stock/navigation,96x96/stock/net,96x96/stock/object,96x96/stock/table,96x96/stock/text,128x128/actions,128x128/animations,128x128/apps,128x128/categories,128x128/devices,128x128/emblems,128x128/emotes,128x128/filesystems,128x128/intl,128x128/mimetypes,128x128/places,128x128/status,128x128/stock/chart,128x128/stock/code,128x128/stock/data,128x128/stock/form,128x128/stock/image,128x128/stock/io,128x128/stock/media,128x128/stock/navigation,128x128/stock/net,128x128/stock/object,128x128/stock/table,128x128/stock/text,192x192/actions,192x192/animations,192x192/apps,192x192/categories,192x192/devices,192x192/emblems,192x192/emotes,192x192/filesystems,192x192/intl,192x192/mimetypes,192x192/places,192x192/status,192x192/stock/chart,192x192/stock/code,192x192/stock/data,192x192/stock/form,192x192/stock/image,192x192/stock/io,192x192/stock/media,192x192/stock/navigation,192x192/stock/net,192x192/stock/object,192x192/stock/table,192x192/stock/text,256x256/actions,256x256/animations,256x256/apps,256x256/categories,256x256/devices,256x256/emblems,256x256/emotes,256x256/filesystems,256x256/intl,256x256/mimetypes,256x256/places,256x256/status,256x256/stock/chart,256x256/stock/code,256x256/stock/data,256x256/stock/form,256x256/stock/image,256x256/stock/io,256x256/stock/media,256x256/stock/navigation,256x256/stock/net,256x256/stock/object,256x256/stock/table,256x256/stock/text,512x512/actions,512x512/animations,512x512/apps,512x512/categories,512x512/devices,512x512/emblems,512x512/emotes,512x512/filesystems,512x512/intl,512x512/mimetypes,512x512/places,512x512/status,512x512/stock/chart,512x512/stock/code,512x512/stock/data,512x512/stock/form,512x512/stock/image,512x512/stock/io,512x512/stock/media,512x512/stock/navigation,512x512/stock/net,512x512/stock/object,512x512/stock/table,512x512/stock/text,scalable/actions,scalable/animations,scalable/apps,scalable/categories,scalable/devices,scalable/emblems,scalable/emotes,scalable/filesystems,scalable/intl,scalable/mimetypes,scalable/places,scalable/status,scalable/stock/chart,scalable/stock/code,scalable/stock/data,scalable/stock/form,scalable/stock/image,scalable/stock/io,scalable/stock/media,scalable/stock/navigation,scalable/stock/net,scalable/stock/object,scalable/stock/table,scalable/stock/text,symbolic/apps + + +[16x16/actions] +Size=16 +Context=Actions +Type=Threshold + +[16x16/animations] +Size=16 +Context=Animations +Type=Threshold + +[16x16/apps] +Size=16 +Context=Applications +Type=Threshold + +[16x16/categories] +Size=16 +Context=Categories +Type=Threshold + +[16x16/devices] +Size=16 +Context=Devices +Type=Threshold + +[16x16/emblems] +Size=16 +Context=Emblems +Type=Threshold + +[16x16/emotes] +Size=16 +Context=Emotes +Type=Threshold + +[16x16/filesystems] +Size=16 +Context=FileSystems +Type=Threshold + +[16x16/intl] +Size=16 +Context=International +Type=Threshold + +[16x16/mimetypes] +Size=16 +Context=MimeTypes +Type=Threshold + +[16x16/places] +Size=16 +Context=Places +Type=Threshold + +[16x16/status] +Size=16 +Context=Status +Type=Threshold + +[16x16/stock/chart] +Size=16 +Context=Stock +Type=Threshold + +[16x16/stock/code] +Size=16 +Context=Stock +Type=Threshold + +[16x16/stock/data] +Size=16 +Context=Stock +Type=Threshold + +[16x16/stock/form] +Size=16 +Context=Stock +Type=Threshold + +[16x16/stock/image] +Size=16 +Context=Stock +Type=Threshold + +[16x16/stock/io] +Size=16 +Context=Stock +Type=Threshold + +[16x16/stock/media] +Size=16 +Context=Stock +Type=Threshold + +[16x16/stock/navigation] +Size=16 +Context=Stock +Type=Threshold + +[16x16/stock/net] +Size=16 +Context=Stock +Type=Threshold + +[16x16/stock/object] +Size=16 +Context=Stock +Type=Threshold + +[16x16/stock/table] +Size=16 +Context=Stock +Type=Threshold + +[16x16/stock/text] +Size=16 +Context=Stock +Type=Threshold + +[22x22/actions] +Size=22 +Context=Actions +Type=Threshold + +[22x22/animations] +Size=22 +Context=Animations +Type=Threshold + +[22x22/apps] +Size=22 +Context=Applications +Type=Threshold + +[22x22/categories] +Size=22 +Context=Categories +Type=Threshold + +[22x22/devices] +Size=22 +Context=Devices +Type=Threshold + +[22x22/emblems] +Size=22 +Context=Emblems +Type=Threshold + +[22x22/emotes] +Size=22 +Context=Emotes +Type=Threshold + +[22x22/filesystems] +Size=22 +Context=FileSystems +Type=Threshold + +[22x22/intl] +Size=22 +Context=International +Type=Threshold + +[22x22/mimetypes] +Size=22 +Context=MimeTypes +Type=Threshold + +[22x22/places] +Size=22 +Context=Places +Type=Threshold + +[22x22/status] +Size=22 +Context=Status +Type=Threshold + +[22x22/stock/chart] +Size=22 +Context=Stock +Type=Threshold + +[22x22/stock/code] +Size=22 +Context=Stock +Type=Threshold + +[22x22/stock/data] +Size=22 +Context=Stock +Type=Threshold + +[22x22/stock/form] +Size=22 +Context=Stock +Type=Threshold + +[22x22/stock/image] +Size=22 +Context=Stock +Type=Threshold + +[22x22/stock/io] +Size=22 +Context=Stock +Type=Threshold + +[22x22/stock/media] +Size=22 +Context=Stock +Type=Threshold + +[22x22/stock/navigation] +Size=22 +Context=Stock +Type=Threshold + +[22x22/stock/net] +Size=22 +Context=Stock +Type=Threshold + +[22x22/stock/object] +Size=22 +Context=Stock +Type=Threshold + +[22x22/stock/table] +Size=22 +Context=Stock +Type=Threshold + +[22x22/stock/text] +Size=22 +Context=Stock +Type=Threshold + +[24x24/actions] +Size=24 +Context=Actions +Type=Threshold + +[24x24/animations] +Size=24 +Context=Animations +Type=Threshold + +[24x24/apps] +Size=24 +Context=Applications +Type=Threshold + +[24x24/categories] +Size=24 +Context=Categories +Type=Threshold + +[24x24/devices] +Size=24 +Context=Devices +Type=Threshold + +[24x24/emblems] +Size=24 +Context=Emblems +Type=Threshold + +[24x24/emotes] +Size=24 +Context=Emotes +Type=Threshold + +[24x24/filesystems] +Size=24 +Context=FileSystems +Type=Threshold + +[24x24/intl] +Size=24 +Context=International +Type=Threshold + +[24x24/mimetypes] +Size=24 +Context=MimeTypes +Type=Threshold + +[24x24/places] +Size=24 +Context=Places +Type=Threshold + +[24x24/status] +Size=24 +Context=Status +Type=Threshold + +[24x24/stock/chart] +Size=24 +Context=Stock +Type=Threshold + +[24x24/stock/code] +Size=24 +Context=Stock +Type=Threshold + +[24x24/stock/data] +Size=24 +Context=Stock +Type=Threshold + +[24x24/stock/form] +Size=24 +Context=Stock +Type=Threshold + +[24x24/stock/image] +Size=24 +Context=Stock +Type=Threshold + +[24x24/stock/io] +Size=24 +Context=Stock +Type=Threshold + +[24x24/stock/media] +Size=24 +Context=Stock +Type=Threshold + +[24x24/stock/navigation] +Size=24 +Context=Stock +Type=Threshold + +[24x24/stock/net] +Size=24 +Context=Stock +Type=Threshold + +[24x24/stock/object] +Size=24 +Context=Stock +Type=Threshold + +[24x24/stock/table] +Size=24 +Context=Stock +Type=Threshold + +[24x24/stock/text] +Size=24 +Context=Stock +Type=Threshold + +[32x32/actions] +Size=32 +Context=Actions +Type=Threshold + +[32x32/animations] +Size=32 +Context=Animations +Type=Threshold + +[32x32/apps] +Size=32 +Context=Applications +Type=Threshold + +[32x32/categories] +Size=32 +Context=Categories +Type=Threshold + +[32x32/devices] +Size=32 +Context=Devices +Type=Threshold + +[32x32/emblems] +Size=32 +Context=Emblems +Type=Threshold + +[32x32/emotes] +Size=32 +Context=Emotes +Type=Threshold + +[32x32/filesystems] +Size=32 +Context=FileSystems +Type=Threshold + +[32x32/intl] +Size=32 +Context=International +Type=Threshold + +[32x32/mimetypes] +Size=32 +Context=MimeTypes +Type=Threshold + +[32x32/places] +Size=32 +Context=Places +Type=Threshold + +[32x32/status] +Size=32 +Context=Status +Type=Threshold + +[32x32/stock/chart] +Size=32 +Context=Stock +Type=Threshold + +[32x32/stock/code] +Size=32 +Context=Stock +Type=Threshold + +[32x32/stock/data] +Size=32 +Context=Stock +Type=Threshold + +[32x32/stock/form] +Size=32 +Context=Stock +Type=Threshold + +[32x32/stock/image] +Size=32 +Context=Stock +Type=Threshold + +[32x32/stock/io] +Size=32 +Context=Stock +Type=Threshold + +[32x32/stock/media] +Size=32 +Context=Stock +Type=Threshold + +[32x32/stock/navigation] +Size=32 +Context=Stock +Type=Threshold + +[32x32/stock/net] +Size=32 +Context=Stock +Type=Threshold + +[32x32/stock/object] +Size=32 +Context=Stock +Type=Threshold + +[32x32/stock/table] +Size=32 +Context=Stock +Type=Threshold + +[32x32/stock/text] +Size=32 +Context=Stock +Type=Threshold + +[36x36/actions] +Size=36 +Context=Actions +Type=Threshold + +[36x36/animations] +Size=36 +Context=Animations +Type=Threshold + +[36x36/apps] +Size=36 +Context=Applications +Type=Threshold + +[36x36/categories] +Size=36 +Context=Categories +Type=Threshold + +[36x36/devices] +Size=36 +Context=Devices +Type=Threshold + +[36x36/emblems] +Size=36 +Context=Emblems +Type=Threshold + +[36x36/emotes] +Size=36 +Context=Emotes +Type=Threshold + +[36x36/filesystems] +Size=36 +Context=FileSystems +Type=Threshold + +[36x36/intl] +Size=36 +Context=International +Type=Threshold + +[36x36/mimetypes] +Size=36 +Context=MimeTypes +Type=Threshold + +[36x36/places] +Size=36 +Context=Places +Type=Threshold + +[36x36/status] +Size=36 +Context=Status +Type=Threshold + +[36x36/stock/chart] +Size=36 +Context=Stock +Type=Threshold + +[36x36/stock/code] +Size=36 +Context=Stock +Type=Threshold + +[36x36/stock/data] +Size=36 +Context=Stock +Type=Threshold + +[36x36/stock/form] +Size=36 +Context=Stock +Type=Threshold + +[36x36/stock/image] +Size=36 +Context=Stock +Type=Threshold + +[36x36/stock/io] +Size=36 +Context=Stock +Type=Threshold + +[36x36/stock/media] +Size=36 +Context=Stock +Type=Threshold + +[36x36/stock/navigation] +Size=36 +Context=Stock +Type=Threshold + +[36x36/stock/net] +Size=36 +Context=Stock +Type=Threshold + +[36x36/stock/object] +Size=36 +Context=Stock +Type=Threshold + +[36x36/stock/table] +Size=36 +Context=Stock +Type=Threshold + +[36x36/stock/text] +Size=36 +Context=Stock +Type=Threshold + +[48x48/actions] +Size=48 +Context=Actions +Type=Threshold + +[48x48/animations] +Size=48 +Context=Animations +Type=Threshold + +[48x48/apps] +Size=48 +Context=Applications +Type=Threshold + +[48x48/categories] +Size=48 +Context=Categories +Type=Threshold + +[48x48/devices] +Size=48 +Context=Devices +Type=Threshold + +[48x48/emblems] +Size=48 +Context=Emblems +Type=Threshold + +[48x48/emotes] +Size=48 +Context=Emotes +Type=Threshold + +[48x48/filesystems] +Size=48 +Context=FileSystems +Type=Threshold + +[48x48/intl] +Size=48 +Context=International +Type=Threshold + +[48x48/mimetypes] +Size=48 +Context=MimeTypes +Type=Threshold + +[48x48/places] +Size=48 +Context=Places +Type=Threshold + +[48x48/status] +Size=48 +Context=Status +Type=Threshold + +[48x48/stock/chart] +Size=48 +Context=Stock +Type=Threshold + +[48x48/stock/code] +Size=48 +Context=Stock +Type=Threshold + +[48x48/stock/data] +Size=48 +Context=Stock +Type=Threshold + +[48x48/stock/form] +Size=48 +Context=Stock +Type=Threshold + +[48x48/stock/image] +Size=48 +Context=Stock +Type=Threshold + +[48x48/stock/io] +Size=48 +Context=Stock +Type=Threshold + +[48x48/stock/media] +Size=48 +Context=Stock +Type=Threshold + +[48x48/stock/navigation] +Size=48 +Context=Stock +Type=Threshold + +[48x48/stock/net] +Size=48 +Context=Stock +Type=Threshold + +[48x48/stock/object] +Size=48 +Context=Stock +Type=Threshold + +[48x48/stock/table] +Size=48 +Context=Stock +Type=Threshold + +[48x48/stock/text] +Size=48 +Context=Stock +Type=Threshold + +[64x64/actions] +Size=64 +Context=Actions +Type=Threshold + +[64x64/animations] +Size=64 +Context=Animations +Type=Threshold + +[64x64/apps] +Size=64 +Context=Applications +Type=Threshold + +[64x64/categories] +Size=64 +Context=Categories +Type=Threshold + +[64x64/devices] +Size=64 +Context=Devices +Type=Threshold + +[64x64/emblems] +Size=64 +Context=Emblems +Type=Threshold + +[64x64/emotes] +Size=64 +Context=Emotes +Type=Threshold + +[64x64/filesystems] +Size=64 +Context=FileSystems +Type=Threshold + +[64x64/intl] +Size=64 +Context=International +Type=Threshold + +[64x64/mimetypes] +Size=64 +Context=MimeTypes +Type=Threshold + +[64x64/places] +Size=64 +Context=Places +Type=Threshold + +[64x64/status] +Size=64 +Context=Status +Type=Threshold + +[64x64/stock/chart] +Size=64 +Context=Stock +Type=Threshold + +[64x64/stock/code] +Size=64 +Context=Stock +Type=Threshold + +[64x64/stock/data] +Size=64 +Context=Stock +Type=Threshold + +[64x64/stock/form] +Size=64 +Context=Stock +Type=Threshold + +[64x64/stock/image] +Size=64 +Context=Stock +Type=Threshold + +[64x64/stock/io] +Size=64 +Context=Stock +Type=Threshold + +[64x64/stock/media] +Size=64 +Context=Stock +Type=Threshold + +[64x64/stock/navigation] +Size=64 +Context=Stock +Type=Threshold + +[64x64/stock/net] +Size=64 +Context=Stock +Type=Threshold + +[64x64/stock/object] +Size=64 +Context=Stock +Type=Threshold + +[64x64/stock/table] +Size=64 +Context=Stock +Type=Threshold + +[64x64/stock/text] +Size=64 +Context=Stock +Type=Threshold +[72x72/actions] +Size=72 +Context=Actions +Type=Threshold + +[72x72/animations] +Size=72 +Context=Animations +Type=Threshold + +[72x72/apps] +Size=72 +Context=Applications +Type=Threshold + +[72x72/categories] +Size=72 +Context=Categories +Type=Threshold + +[72x72/devices] +Size=72 +Context=Devices +Type=Threshold + +[72x72/emblems] +Size=72 +Context=Emblems +Type=Threshold + +[72x72/emotes] +Size=72 +Context=Emotes +Type=Threshold + +[72x72/filesystems] +Size=72 +Context=FileSystems +Type=Threshold + +[72x72/intl] +Size=72 +Context=International +Type=Threshold + +[72x72/mimetypes] +Size=72 +Context=MimeTypes +Type=Threshold + +[72x72/places] +Size=72 +Context=Places +Type=Threshold + +[72x72/status] +Size=72 +Context=Status +Type=Threshold + +[72x72/stock/chart] +Size=72 +Context=Stock +Type=Threshold + +[72x72/stock/code] +Size=72 +Context=Stock +Type=Threshold + +[72x72/stock/data] +Size=72 +Context=Stock +Type=Threshold + +[72x72/stock/form] +Size=72 +Context=Stock +Type=Threshold + +[72x72/stock/image] +Size=72 +Context=Stock +Type=Threshold + +[72x72/stock/io] +Size=72 +Context=Stock +Type=Threshold + +[72x72/stock/media] +Size=72 +Context=Stock +Type=Threshold + +[72x72/stock/navigation] +Size=72 +Context=Stock +Type=Threshold + +[72x72/stock/net] +Size=72 +Context=Stock +Type=Threshold + +[72x72/stock/object] +Size=72 +Context=Stock +Type=Threshold + +[72x72/stock/table] +Size=72 +Context=Stock +Type=Threshold + +[72x72/stock/text] +Size=72 +Context=Stock +Type=Threshold + +[96x96/actions] +Size=96 +Context=Actions +Type=Threshold + +[96x96/animations] +Size=96 +Context=Animations +Type=Threshold + +[96x96/apps] +Size=96 +Context=Applications +Type=Threshold + +[96x96/categories] +Size=96 +Context=Categories +Type=Threshold + +[96x96/devices] +Size=96 +Context=Devices +Type=Threshold + +[96x96/emblems] +Size=96 +Context=Emblems +Type=Threshold + +[96x96/emotes] +Size=96 +Context=Emotes +Type=Threshold + +[96x96/filesystems] +Size=96 +Context=FileSystems +Type=Threshold + +[96x96/intl] +Size=96 +Context=International +Type=Threshold + +[96x96/mimetypes] +Size=96 +Context=MimeTypes +Type=Threshold + +[96x96/places] +Size=96 +Context=Places +Type=Threshold + +[96x96/status] +Size=96 +Context=Status +Type=Threshold + +[96x96/stock/chart] +Size=96 +Context=Stock +Type=Threshold + +[96x96/stock/code] +Size=96 +Context=Stock +Type=Threshold + +[96x96/stock/data] +Size=96 +Context=Stock +Type=Threshold + +[96x96/stock/form] +Size=96 +Context=Stock +Type=Threshold + +[96x96/stock/image] +Size=96 +Context=Stock +Type=Threshold + +[96x96/stock/io] +Size=96 +Context=Stock +Type=Threshold + +[96x96/stock/media] +Size=96 +Context=Stock +Type=Threshold + +[96x96/stock/navigation] +Size=96 +Context=Stock +Type=Threshold + +[96x96/stock/net] +Size=96 +Context=Stock +Type=Threshold + +[96x96/stock/object] +Size=96 +Context=Stock +Type=Threshold + +[96x96/stock/table] +Size=96 +Context=Stock +Type=Threshold + +[96x96/stock/text] +Size=96 +Context=Stock +Type=Threshold + +[128x128/actions] +Size=128 +Context=Actions +Type=Threshold + +[128x128/animations] +Size=128 +Context=Animations +Type=Threshold + +[128x128/apps] +Size=128 +Context=Applications +Type=Threshold + +[128x128/categories] +Size=128 +Context=Categories +Type=Threshold + +[128x128/devices] +Size=128 +Context=Devices +Type=Threshold + +[128x128/emblems] +Size=128 +Context=Emblems +Type=Threshold + +[128x128/emotes] +Size=128 +Context=Emotes +Type=Threshold + +[128x128/filesystems] +Size=128 +Context=FileSystems +Type=Threshold + +[128x128/intl] +Size=128 +Context=International +Type=Threshold + +[128x128/mimetypes] +Size=128 +Context=MimeTypes +Type=Threshold + +[128x128/places] +Size=128 +Context=Places +Type=Threshold + +[128x128/status] +Size=128 +Context=Status +Type=Threshold + +[128x128/stock/chart] +Size=128 +Context=Stock +Type=Threshold + +[128x128/stock/code] +Size=128 +Context=Stock +Type=Threshold + +[128x128/stock/data] +Size=128 +Context=Stock +Type=Threshold + +[128x128/stock/form] +Size=128 +Context=Stock +Type=Threshold + +[128x128/stock/image] +Size=128 +Context=Stock +Type=Threshold + +[128x128/stock/io] +Size=128 +Context=Stock +Type=Threshold + +[128x128/stock/media] +Size=128 +Context=Stock +Type=Threshold + +[128x128/stock/navigation] +Size=128 +Context=Stock +Type=Threshold + +[128x128/stock/net] +Size=128 +Context=Stock +Type=Threshold + +[128x128/stock/object] +Size=128 +Context=Stock +Type=Threshold + +[128x128/stock/table] +Size=128 +Context=Stock +Type=Threshold + +[128x128/stock/text] +Size=128 +Context=Stock +Type=Threshold + +[192x192/actions] +Size=192 +Context=Actions +Type=Threshold + +[192x192/animations] +Size=192 +Context=Animations +Type=Threshold + +[192x192/apps] +Size=192 +Context=Applications +Type=Threshold + +[192x192/categories] +Size=192 +Context=Categories +Type=Threshold + +[192x192/devices] +Size=192 +Context=Devices +Type=Threshold + +[192x192/emblems] +Size=192 +Context=Emblems +Type=Threshold + +[192x192/emotes] +Size=192 +Context=Emotes +Type=Threshold + +[192x192/filesystems] +Size=192 +Context=FileSystems +Type=Threshold + +[192x192/intl] +Size=192 +Context=International +Type=Threshold + +[192x192/mimetypes] +Size=192 +Context=MimeTypes +Type=Threshold + +[192x192/places] +Size=192 +Context=Places +Type=Threshold + +[192x192/status] +Size=192 +Context=Status +Type=Threshold + +[192x192/stock/chart] +Size=192 +Context=Stock +Type=Threshold + +[192x192/stock/code] +Size=192 +Context=Stock +Type=Threshold + +[192x192/stock/data] +Size=192 +Context=Stock +Type=Threshold + +[192x192/stock/form] +Size=192 +Context=Stock +Type=Threshold + +[192x192/stock/image] +Size=192 +Context=Stock +Type=Threshold + +[192x192/stock/io] +Size=192 +Context=Stock +Type=Threshold + +[192x192/stock/media] +Size=192 +Context=Stock +Type=Threshold + +[192x192/stock/navigation] +Size=192 +Context=Stock +Type=Threshold + +[192x192/stock/net] +Size=192 +Context=Stock +Type=Threshold + +[192x192/stock/object] +Size=192 +Context=Stock +Type=Threshold + +[192x192/stock/table] +Size=192 +Context=Stock +Type=Threshold + +[192x192/stock/text] +Size=192 +Context=Stock +Type=Threshold + +[256x256/actions] +MinSize=64 +Size=256 +MaxSize=256 +Context=Actions +Type=Scalable + +[256x256/animations] +MinSize=64 +Size=256 +MaxSize=256 +Context=Animations +Type=Scalable + +[256x256/apps] +MinSize=64 +Size=256 +MaxSize=256 +Context=Applications +Type=Scalable + +[256x256/categories] +MinSize=64 +Size=256 +MaxSize=256 +Context=Categories +Type=Scalable + +[256x256/devices] +MinSize=64 +Size=256 +MaxSize=256 +Context=Devices +Type=Scalable + +[256x256/emblems] +MinSize=64 +Size=256 +MaxSize=256 +Context=Emblems +Type=Scalable + +[256x256/emotes] +MinSize=64 +Size=256 +MaxSize=256 +Context=Emotes +Type=Scalable + +[256x256/filesystems] +MinSize=64 +Size=256 +MaxSize=256 +Context=FileSystems +Type=Scalable + +[256x256/intl] +MinSize=64 +Size=256 +MaxSize=256 +Context=International +Type=Scalable + +[256x256/mimetypes] +MinSize=64 +Size=256 +MaxSize=256 +Context=MimeTypes +Type=Scalable + +[256x256/places] +MinSize=64 +Size=256 +MaxSize=256 +Context=Places +Type=Scalable + +[256x256/status] +MinSize=64 +Size=256 +MaxSize=256 +Context=Status +Type=Scalable + +[256x256/stock/chart] +MinSize=64 +Size=256 +MaxSize=256 +Context=Stock +Type=Scalable + +[256x256/stock/code] +MinSize=64 +Size=256 +MaxSize=256 +Context=Stock +Type=Scalable + +[256x256/stock/data] +MinSize=64 +Size=256 +MaxSize=256 +Context=Stock +Type=Scalable + +[256x256/stock/form] +MinSize=64 +Size=256 +MaxSize=256 +Context=Stock +Type=Scalable + +[256x256/stock/image] +MinSize=64 +Size=256 +MaxSize=256 +Context=Stock +Type=Scalable + +[256x256/stock/io] +MinSize=64 +Size=256 +MaxSize=256 +Context=Stock +Type=Scalable + +[256x256/stock/media] +MinSize=64 +Size=256 +MaxSize=256 +Context=Stock +Type=Scalable + +[256x256/stock/navigation] +MinSize=64 +Size=256 +MaxSize=256 +Context=Stock +Type=Scalable + +[256x256/stock/net] +MinSize=64 +Size=256 +MaxSize=256 +Context=Stock +Type=Scalable + +[256x256/stock/object] +MinSize=64 +Size=256 +MaxSize=256 +Context=Stock +Type=Scalable + +[256x256/stock/table] +MinSize=64 +Size=256 +MaxSize=256 +Context=Stock +Type=Scalable + +[256x256/stock/text] +MinSize=64 +Size=256 +MaxSize=256 +Context=Stock +Type=Scalable + +[512x512/actions] +MinSize=64 +Size=512 +MaxSize=512 +Context=Actions +Type=Scalable + +[512x512/animations] +MinSize=64 +Size=512 +MaxSize=512 +Context=Animations +Type=Scalable + +[512x512/apps] +MinSize=64 +Size=512 +MaxSize=512 +Context=Applications +Type=Scalable + +[512x512/categories] +MinSize=64 +Size=512 +MaxSize=512 +Context=Categories +Type=Scalable + +[512x512/devices] +MinSize=64 +Size=512 +MaxSize=512 +Context=Devices +Type=Scalable + +[512x512/emblems] +MinSize=64 +Size=512 +MaxSize=512 +Context=Emblems +Type=Scalable + +[512x512/emotes] +MinSize=64 +Size=512 +MaxSize=512 +Context=Emotes +Type=Scalable + +[512x512/filesystems] +MinSize=64 +Size=512 +MaxSize=512 +Context=FileSystems +Type=Scalable + +[512x512/intl] +MinSize=64 +Size=512 +MaxSize=512 +Context=International +Type=Scalable + +[512x512/mimetypes] +MinSize=64 +Size=512 +MaxSize=512 +Context=MimeTypes +Type=Scalable + +[512x512/places] +MinSize=64 +Size=512 +MaxSize=512 +Context=Places +Type=Scalable + +[512x512/status] +MinSize=64 +Size=512 +MaxSize=512 +Context=Status +Type=Scalable + +[512x512/stock/chart] +MinSize=64 +Size=512 +MaxSize=512 +Context=Stock +Type=Scalable + +[512x512/stock/code] +MinSize=64 +Size=512 +MaxSize=512 +Context=Stock +Type=Scalable + +[512x512/stock/data] +MinSize=64 +Size=512 +MaxSize=512 +Context=Stock +Type=Scalable + +[512x512/stock/form] +MinSize=64 +Size=512 +MaxSize=512 +Context=Stock +Type=Scalable + +[512x512/stock/image] +MinSize=64 +Size=512 +MaxSize=512 +Context=Stock +Type=Scalable + +[512x512/stock/io] +MinSize=64 +Size=512 +MaxSize=512 +Context=Stock +Type=Scalable + +[512x512/stock/media] +MinSize=64 +Size=512 +MaxSize=512 +Context=Stock +Type=Scalable + +[512x512/stock/navigation] +MinSize=64 +Size=512 +MaxSize=512 +Context=Stock +Type=Scalable + +[512x512/stock/net] +MinSize=64 +Size=512 +MaxSize=512 +Context=Stock +Type=Scalable + +[512x512/stock/object] +MinSize=64 +Size=512 +MaxSize=512 +Context=Stock +Type=Scalable + +[512x512/stock/table] +MinSize=64 +Size=512 +MaxSize=512 +Context=Stock +Type=Scalable + +[512x512/stock/text] +MinSize=64 +Size=512 +MaxSize=512 +Context=Stock +Type=Scalable + +[scalable/actions] +MinSize=1 +Size=128 +MaxSize=256 +Context=Actions +Type=Scalable + +[scalable/animations] +MinSize=1 +Size=128 +MaxSize=256 +Context=Animations +Type=Scalable + +[scalable/apps] +MinSize=1 +Size=128 +MaxSize=256 +Context=Applications +Type=Scalable + +[scalable/categories] +MinSize=1 +Size=128 +MaxSize=256 +Context=Categories +Type=Scalable + +[scalable/devices] +MinSize=1 +Size=128 +MaxSize=512 +Context=Devices +Type=Scalable + +[scalable/emblems] +MinSize=1 +Size=128 +MaxSize=256 +Context=Emblems +Type=Scalable + +[scalable/emotes] +MinSize=1 +Size=128 +MaxSize=512 +Context=Emotes +Type=Scalable + +[scalable/filesystems] +MinSize=1 +Size=128 +MaxSize=256 +Context=FileSystems +Type=Scalable + +[scalable/intl] +MinSize=1 +Size=128 +MaxSize=512 +Context=International +Type=Scalable + +[scalable/mimetypes] +MinSize=1 +Size=128 +MaxSize=256 +Context=MimeTypes +Type=Scalable + +[scalable/places] +MinSize=1 +Size=128 +MaxSize=512 +Context=Places +Type=Scalable + +[scalable/status] +MinSize=1 +Size=128 +MaxSize=256 +Context=Status +Type=Scalable + +[scalable/stock/chart] +MinSize=1 +Size=128 +MaxSize=512 +Context=Stock +Type=Scalable + +[scalable/stock/code] +MinSize=1 +Size=128 +MaxSize=256 +Context=Stock +Type=Scalable + +[scalable/stock/data] +MinSize=1 +Size=128 +MaxSize=512 +Context=Stock +Type=Scalable + +[scalable/stock/form] +MinSize=1 +Size=128 +MaxSize=256 +Context=Stock +Type=Scalable + +[scalable/stock/image] +MinSize=1 +Size=128 +MaxSize=512 +Context=Stock +Type=Scalable + +[scalable/stock/io] +MinSize=1 +Size=128 +MaxSize=256 +Context=Stock +Type=Scalable + +[scalable/stock/media] +MinSize=1 +Size=128 +MaxSize=512 +Context=Stock +Type=Scalable + +[scalable/stock/navigation] +MinSize=1 +Size=128 +MaxSize=256 +Context=Stock +Type=Scalable + +[scalable/stock/net] +MinSize=1 +Size=128 +MaxSize=512 +Context=Stock +Type=Scalable + +[scalable/stock/object] +MinSize=1 +Size=128 +MaxSize=256 +Context=Stock +Type=Scalable + +[scalable/stock/table] +MinSize=1 +Size=128 +MaxSize=512 +Context=Stock +Type=Scalable + +[scalable/stock/text] +MinSize=1 +Size=128 +MaxSize=256 +Context=Stock +Type=Scalable + +[symbolic/apps] +MinSize=8 +Size=16 +MaxSize=512 +Context=Applications +Type=Scalable diff --git a/pixmaps/linphone-add-call.png b/pixmaps/linphone-add-call.png new file mode 100644 index 000000000..9c9edeef8 Binary files /dev/null and b/pixmaps/linphone-add-call.png differ diff --git a/pixmaps/linphone-call-status-incoming.png b/pixmaps/linphone-call-status-incoming.png new file mode 100644 index 000000000..58bf8633c Binary files /dev/null and b/pixmaps/linphone-call-status-incoming.png differ diff --git a/pixmaps/linphone-call-status-missed.png b/pixmaps/linphone-call-status-missed.png new file mode 100644 index 000000000..ba6bee6ee Binary files /dev/null and b/pixmaps/linphone-call-status-missed.png differ diff --git a/pixmaps/linphone-call-status-outgoing.png b/pixmaps/linphone-call-status-outgoing.png new file mode 100644 index 000000000..73587dc7a Binary files /dev/null and b/pixmaps/linphone-call-status-outgoing.png differ diff --git a/pixmaps/linphone-call-transfer.png b/pixmaps/linphone-call-transfer.png new file mode 100644 index 000000000..4dc24ce42 Binary files /dev/null and b/pixmaps/linphone-call-transfer.png differ diff --git a/pixmaps/linphone-camera-disabled.png b/pixmaps/linphone-camera-disabled.png new file mode 100644 index 000000000..dfcc711cd Binary files /dev/null and b/pixmaps/linphone-camera-disabled.png differ diff --git a/pixmaps/linphone-camera-enabled.png b/pixmaps/linphone-camera-enabled.png new file mode 100644 index 000000000..4c929b52b Binary files /dev/null and b/pixmaps/linphone-camera-enabled.png differ diff --git a/pixmaps/linphone-chat-new-message-and-writing.png b/pixmaps/linphone-chat-new-message-and-writing.png new file mode 100644 index 000000000..f64f525bb Binary files /dev/null and b/pixmaps/linphone-chat-new-message-and-writing.png differ diff --git a/pixmaps/linphone-chat-new-message.png b/pixmaps/linphone-chat-new-message.png new file mode 100644 index 000000000..61341af11 Binary files /dev/null and b/pixmaps/linphone-chat-new-message.png differ diff --git a/pixmaps/linphone-chat-nothing.png b/pixmaps/linphone-chat-nothing.png new file mode 100644 index 000000000..9f6e1adc2 Binary files /dev/null and b/pixmaps/linphone-chat-nothing.png differ diff --git a/pixmaps/linphone-chat-send.png b/pixmaps/linphone-chat-send.png new file mode 100644 index 000000000..9a9f9d731 Binary files /dev/null and b/pixmaps/linphone-chat-send.png differ diff --git a/pixmaps/linphone-chat-writing.png b/pixmaps/linphone-chat-writing.png new file mode 100644 index 000000000..74c1a8269 Binary files /dev/null and b/pixmaps/linphone-chat-writing.png differ diff --git a/pixmaps/linphone-conference-start.png b/pixmaps/linphone-conference-start.png new file mode 100644 index 000000000..23dabbc35 Binary files /dev/null and b/pixmaps/linphone-conference-start.png differ diff --git a/pixmaps/linphone-contact-add.png b/pixmaps/linphone-contact-add.png new file mode 100644 index 000000000..f78852d01 Binary files /dev/null and b/pixmaps/linphone-contact-add.png differ diff --git a/pixmaps/linphone-delete.png b/pixmaps/linphone-delete.png new file mode 100644 index 000000000..d8ff8da4a Binary files /dev/null and b/pixmaps/linphone-delete.png differ diff --git a/pixmaps/linphone-edit.png b/pixmaps/linphone-edit.png new file mode 100644 index 000000000..772770988 Binary files /dev/null and b/pixmaps/linphone-edit.png differ diff --git a/pixmaps/linphone-failed.png b/pixmaps/linphone-failed.png new file mode 100644 index 000000000..f72412139 Binary files /dev/null and b/pixmaps/linphone-failed.png differ diff --git a/pixmaps/linphone-history.png b/pixmaps/linphone-history.png new file mode 100644 index 000000000..825bdeb68 Binary files /dev/null and b/pixmaps/linphone-history.png differ diff --git a/pixmaps/linphone-hold-off.png b/pixmaps/linphone-hold-off.png new file mode 100644 index 000000000..b008a6896 Binary files /dev/null and b/pixmaps/linphone-hold-off.png differ diff --git a/pixmaps/linphone-hold-on.png b/pixmaps/linphone-hold-on.png new file mode 100644 index 000000000..1590a63b0 Binary files /dev/null and b/pixmaps/linphone-hold-on.png differ diff --git a/pixmaps/linphone-inprogress.png b/pixmaps/linphone-inprogress.png new file mode 100644 index 000000000..4a4371430 Binary files /dev/null and b/pixmaps/linphone-inprogress.png differ diff --git a/pixmaps/linphone-media-pause.png b/pixmaps/linphone-media-pause.png new file mode 100644 index 000000000..f9e062f38 Binary files /dev/null and b/pixmaps/linphone-media-pause.png differ diff --git a/pixmaps/linphone-media-play.png b/pixmaps/linphone-media-play.png new file mode 100644 index 000000000..382d07760 Binary files /dev/null and b/pixmaps/linphone-media-play.png differ diff --git a/pixmaps/linphone-micro-enabled.png b/pixmaps/linphone-micro-enabled.png new file mode 100644 index 000000000..44ba551af Binary files /dev/null and b/pixmaps/linphone-micro-enabled.png differ diff --git a/pixmaps/linphone-micro-muted.png b/pixmaps/linphone-micro-muted.png new file mode 100644 index 000000000..cf666ebd0 Binary files /dev/null and b/pixmaps/linphone-micro-muted.png differ diff --git a/pixmaps/linphone-ok.png b/pixmaps/linphone-ok.png new file mode 100644 index 000000000..4bcd6f634 Binary files /dev/null and b/pixmaps/linphone-ok.png differ diff --git a/pixmaps/linphone-record.png b/pixmaps/linphone-record.png new file mode 100644 index 000000000..4ef4b064d Binary files /dev/null and b/pixmaps/linphone-record.png differ diff --git a/pixmaps/linphone-security-ok.png b/pixmaps/linphone-security-ok.png new file mode 100644 index 000000000..38d2ec61c Binary files /dev/null and b/pixmaps/linphone-security-ok.png differ diff --git a/pixmaps/linphone-security-pending.png b/pixmaps/linphone-security-pending.png new file mode 100644 index 000000000..d61faa39a Binary files /dev/null and b/pixmaps/linphone-security-pending.png differ diff --git a/pixmaps/linphone-speaker-enabled.png b/pixmaps/linphone-speaker-enabled.png new file mode 100644 index 000000000..0c8d7a951 Binary files /dev/null and b/pixmaps/linphone-speaker-enabled.png differ diff --git a/pixmaps/linphone-speaker-muted.png b/pixmaps/linphone-speaker-muted.png new file mode 100644 index 000000000..91e96eddb Binary files /dev/null and b/pixmaps/linphone-speaker-muted.png differ diff --git a/pixmaps/linphone-start-call.png b/pixmaps/linphone-start-call.png new file mode 100644 index 000000000..ade0e15a4 Binary files /dev/null and b/pixmaps/linphone-start-call.png differ diff --git a/pixmaps/linphone-start-call2.png b/pixmaps/linphone-start-call2.png new file mode 100644 index 000000000..097271ce2 Binary files /dev/null and b/pixmaps/linphone-start-call2.png differ diff --git a/pixmaps/linphone-start-chat.png b/pixmaps/linphone-start-chat.png new file mode 100644 index 000000000..15b050f6f Binary files /dev/null and b/pixmaps/linphone-start-chat.png differ diff --git a/pixmaps/linphone-status-away.png b/pixmaps/linphone-status-away.png new file mode 100644 index 000000000..56c7fb367 Binary files /dev/null and b/pixmaps/linphone-status-away.png differ diff --git a/pixmaps/linphone-status-donotdisturb.png b/pixmaps/linphone-status-donotdisturb.png new file mode 100644 index 000000000..d5a1391de Binary files /dev/null and b/pixmaps/linphone-status-donotdisturb.png differ diff --git a/pixmaps/linphone-status-offline.png b/pixmaps/linphone-status-offline.png new file mode 100644 index 000000000..c4f236f55 Binary files /dev/null and b/pixmaps/linphone-status-offline.png differ diff --git a/pixmaps/linphone-status-online.png b/pixmaps/linphone-status-online.png new file mode 100644 index 000000000..7fb4a1276 Binary files /dev/null and b/pixmaps/linphone-status-online.png differ diff --git a/pixmaps/linphone-stop-call.png b/pixmaps/linphone-stop-call.png new file mode 100644 index 000000000..da1a2eab5 Binary files /dev/null and b/pixmaps/linphone-stop-call.png differ diff --git a/pixmaps/linphone-warning.png b/pixmaps/linphone-warning.png new file mode 100644 index 000000000..044bcd8f0 Binary files /dev/null and b/pixmaps/linphone-warning.png differ diff --git a/pixmaps/linphone.icns b/pixmaps/linphone.icns index 056461b38..3b8f1bd0a 100644 Binary files a/pixmaps/linphone.icns and b/pixmaps/linphone.icns differ diff --git a/pixmaps/mic_active.png b/pixmaps/mic_active.png deleted file mode 100644 index ee6b9038c..000000000 Binary files a/pixmaps/mic_active.png and /dev/null differ diff --git a/pixmaps/mic_muted.png b/pixmaps/mic_muted.png deleted file mode 100644 index 60fd18761..000000000 Binary files a/pixmaps/mic_muted.png and /dev/null differ diff --git a/pixmaps/notok.png b/pixmaps/notok.png deleted file mode 100644 index 84813bc2d..000000000 Binary files a/pixmaps/notok.png and /dev/null differ diff --git a/pixmaps/ok.png b/pixmaps/ok.png deleted file mode 100644 index 769986fb7..000000000 Binary files a/pixmaps/ok.png and /dev/null differ diff --git a/pixmaps/pausecall.png b/pixmaps/pausecall.png deleted file mode 100644 index 9ab5bae92..000000000 Binary files a/pixmaps/pausecall.png and /dev/null differ diff --git a/pixmaps/resumecall.png b/pixmaps/resumecall.png deleted file mode 100644 index b8a2d50cd..000000000 Binary files a/pixmaps/resumecall.png and /dev/null differ diff --git a/pixmaps/speaker.png b/pixmaps/speaker.png deleted file mode 100644 index acc92dbcf..000000000 Binary files a/pixmaps/speaker.png and /dev/null differ diff --git a/pixmaps/startcall-green.png b/pixmaps/startcall-green.png deleted file mode 100644 index 56cf6e136..000000000 Binary files a/pixmaps/startcall-green.png and /dev/null differ diff --git a/pixmaps/startcall-small.png b/pixmaps/startcall-small.png deleted file mode 100644 index d5726e12c..000000000 Binary files a/pixmaps/startcall-small.png and /dev/null differ diff --git a/pixmaps/status-green.png b/pixmaps/status-green.png deleted file mode 100644 index 1a39a4242..000000000 Binary files a/pixmaps/status-green.png and /dev/null differ diff --git a/pixmaps/status-offline.png b/pixmaps/status-offline.png deleted file mode 100644 index 243c5c069..000000000 Binary files a/pixmaps/status-offline.png and /dev/null differ diff --git a/pixmaps/status-orange.png b/pixmaps/status-orange.png deleted file mode 100644 index f2e66d34d..000000000 Binary files a/pixmaps/status-orange.png and /dev/null differ diff --git a/pixmaps/status-red.png b/pixmaps/status-red.png deleted file mode 100644 index e7a0ec98a..000000000 Binary files a/pixmaps/status-red.png and /dev/null differ diff --git a/pixmaps/stopcall-red.png b/pixmaps/stopcall-red.png deleted file mode 100644 index 8bd957935..000000000 Binary files a/pixmaps/stopcall-red.png and /dev/null differ diff --git a/pixmaps/stopcall-small.png b/pixmaps/stopcall-small.png deleted file mode 100644 index de77592c7..000000000 Binary files a/pixmaps/stopcall-small.png and /dev/null differ diff --git a/pixmaps/svg/.directory b/pixmaps/svg/.directory new file mode 100644 index 000000000..c99a6191a --- /dev/null +++ b/pixmaps/svg/.directory @@ -0,0 +1,4 @@ +[Dolphin] +PreviewsShown=true +Timestamp=2015,8,3,13,7,36 +Version=3 diff --git a/pixmaps/svg/callkeybackground.svg b/pixmaps/svg/callkeybackground.svg deleted file mode 100644 index 4d86f7fd4..000000000 --- a/pixmaps/svg/callkeybackground.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - diff --git a/pixmaps/svg/contact.svg b/pixmaps/svg/contact.svg deleted file mode 100644 index f094b7a0a..000000000 --- a/pixmaps/svg/contact.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - diff --git a/pixmaps/svg/dialer.svg b/pixmaps/svg/dialer.svg deleted file mode 100644 index fef344bc3..000000000 --- a/pixmaps/svg/dialer.svg +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/pixmaps/svg/history.svg b/pixmaps/svg/history.svg deleted file mode 100644 index 11ba3a203..000000000 --- a/pixmaps/svg/history.svg +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/pixmaps/svg/linphone-add-call.svg b/pixmaps/svg/linphone-add-call.svg new file mode 100644 index 000000000..ed8da23bc --- /dev/null +++ b/pixmaps/svg/linphone-add-call.svg @@ -0,0 +1,89 @@ + + + + + + image/svg+xml + + options_add_call + Rectangle 250 Copy 19 + + + + + + options_add_call + Rectangle 250 Copy 19 + Created with Sketch. + + + + + + + + diff --git a/pixmaps/svg/linphone-call-status-incoming.svg b/pixmaps/svg/linphone-call-status-incoming.svg new file mode 100644 index 000000000..af9dd9bf6 --- /dev/null +++ b/pixmaps/svg/linphone-call-status-incoming.svg @@ -0,0 +1,80 @@ + + + + + + image/svg+xml + + + + + + + call_status_incoming + Created with Sketch. + + + + + + + diff --git a/pixmaps/svg/linphone-call-status-missed.svg b/pixmaps/svg/linphone-call-status-missed.svg new file mode 100644 index 000000000..abb146cf1 --- /dev/null +++ b/pixmaps/svg/linphone-call-status-missed.svg @@ -0,0 +1,86 @@ + + + + + + image/svg+xml + + call_status_missed + + + + + + call_status_missed + Created with Sketch. + + + + + + + + diff --git a/pixmaps/svg/linphone-call-status-outgoing.svg b/pixmaps/svg/linphone-call-status-outgoing.svg new file mode 100644 index 000000000..cc8c66efb --- /dev/null +++ b/pixmaps/svg/linphone-call-status-outgoing.svg @@ -0,0 +1,78 @@ + + + + + + image/svg+xml + + call_status_outgoing + + + + + + call_status_outgoing + Created with Sketch. + + + + + diff --git a/pixmaps/svg/linphone-call-transfer.svg b/pixmaps/svg/linphone-call-transfer.svg new file mode 100644 index 000000000..357ccfad7 --- /dev/null +++ b/pixmaps/svg/linphone-call-transfer.svg @@ -0,0 +1,104 @@ + + + + + + image/svg+xml + + call_transfer + + + + + + call_transfer + Created with Sketch. + + + + + + + + + + + + + + + + + diff --git a/pixmaps/svg/linphone-camera-disabled.svg b/pixmaps/svg/linphone-camera-disabled.svg new file mode 100644 index 000000000..f5ddde244 --- /dev/null +++ b/pixmaps/svg/linphone-camera-disabled.svg @@ -0,0 +1,95 @@ + + + + + + image/svg+xml + + camera_default + + + + + + camera_default + Created with Sketch. + + + + + + + + + + + diff --git a/pixmaps/svg/linphone-camera-enabled.svg b/pixmaps/svg/linphone-camera-enabled.svg new file mode 100644 index 000000000..5138510e3 --- /dev/null +++ b/pixmaps/svg/linphone-camera-enabled.svg @@ -0,0 +1,90 @@ + + + + + + image/svg+xml + + camera_default + + + + + + camera_default + Created with Sketch. + + + + + + + + + + diff --git a/pixmaps/svg/linphone-chat-new-message-and-writing.svg b/pixmaps/svg/linphone-chat-new-message-and-writing.svg new file mode 100644 index 000000000..9cd538ea3 --- /dev/null +++ b/pixmaps/svg/linphone-chat-new-message-and-writing.svg @@ -0,0 +1,76 @@ + + + + + + image/svg+xml + + + + + + + chat_start_body_over + Created with Sketch. + + + + + + diff --git a/pixmaps/svg/linphone-chat-new-message.svg b/pixmaps/svg/linphone-chat-new-message.svg new file mode 100644 index 000000000..8ad456ca2 --- /dev/null +++ b/pixmaps/svg/linphone-chat-new-message.svg @@ -0,0 +1,69 @@ + + + + + + image/svg+xml + + + + + + + chat_start_body_over + Created with Sketch. + + + + diff --git a/pixmaps/svg/linphone-chat-nothing.svg b/pixmaps/svg/linphone-chat-nothing.svg new file mode 100644 index 000000000..4835b5255 --- /dev/null +++ b/pixmaps/svg/linphone-chat-nothing.svg @@ -0,0 +1,69 @@ + + + + + + image/svg+xml + + + + + + + chat_start_body_over + Created with Sketch. + + + + diff --git a/pixmaps/svg/linphone-chat-send.svg b/pixmaps/svg/linphone-chat-send.svg new file mode 100644 index 000000000..4f0924ab7 --- /dev/null +++ b/pixmaps/svg/linphone-chat-send.svg @@ -0,0 +1,70 @@ + + + + + + image/svg+xml + + chat_send + + + + + + chat_send + Created with Sketch. + + + + diff --git a/pixmaps/svg/linphone-chat-writing.svg b/pixmaps/svg/linphone-chat-writing.svg new file mode 100644 index 000000000..7183818a1 --- /dev/null +++ b/pixmaps/svg/linphone-chat-writing.svg @@ -0,0 +1,73 @@ + + + + + + image/svg+xml + + + + + + + chat_start_body_over + Created with Sketch. + + + + + + diff --git a/pixmaps/svg/linphone-conference-start.svg b/pixmaps/svg/linphone-conference-start.svg new file mode 100644 index 000000000..eedb7136b --- /dev/null +++ b/pixmaps/svg/linphone-conference-start.svg @@ -0,0 +1,66 @@ + + + + + + image/svg+xml + + conference_start + + + + + + conference_start + Created with Sketch. + + + diff --git a/pixmaps/svg/linphone-contact-add.svg b/pixmaps/svg/linphone-contact-add.svg new file mode 100644 index 000000000..08882723a --- /dev/null +++ b/pixmaps/svg/linphone-contact-add.svg @@ -0,0 +1,17 @@ + + + + contact_add + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/pixmaps/svg/linphone-delete.svg b/pixmaps/svg/linphone-delete.svg new file mode 100644 index 000000000..51b051ac0 --- /dev/null +++ b/pixmaps/svg/linphone-delete.svg @@ -0,0 +1,17 @@ + + + + delete + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/pixmaps/svg/linphone-edit.svg b/pixmaps/svg/linphone-edit.svg new file mode 100644 index 000000000..21d72cfbc --- /dev/null +++ b/pixmaps/svg/linphone-edit.svg @@ -0,0 +1,15 @@ + + + + edit + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/pixmaps/svg/linphone-failed.svg b/pixmaps/svg/linphone-failed.svg new file mode 100644 index 000000000..98e3fc67f --- /dev/null +++ b/pixmaps/svg/linphone-failed.svg @@ -0,0 +1,73 @@ + + + + + + image/svg+xml + + call_missed + + + + + + call_missed + Created with Sketch. + + + + + + diff --git a/pixmaps/svg/linphone-history.svg b/pixmaps/svg/linphone-history.svg new file mode 100644 index 000000000..c4b4f4936 --- /dev/null +++ b/pixmaps/svg/linphone-history.svg @@ -0,0 +1,96 @@ + + + + + + image/svg+xml + + + + + + + footer_history + Created with Sketch. + + + + + + + + + + diff --git a/pixmaps/svg/linphone-hold-off.svg b/pixmaps/svg/linphone-hold-off.svg new file mode 100644 index 000000000..bd44bbf3a --- /dev/null +++ b/pixmaps/svg/linphone-hold-off.svg @@ -0,0 +1,66 @@ + + + + + + image/svg+xml + + pause_big_default + + + + + + pause_big_default + Created with Sketch. + + + diff --git a/pixmaps/svg/linphone-hold-on.svg b/pixmaps/svg/linphone-hold-on.svg new file mode 100644 index 000000000..b25a411fd --- /dev/null +++ b/pixmaps/svg/linphone-hold-on.svg @@ -0,0 +1,65 @@ + + + + + + image/svg+xml + + + + + + + pause_small_over_selected + Created with Sketch. + + + diff --git a/pixmaps/svg/linphone-inprogress.svg b/pixmaps/svg/linphone-inprogress.svg new file mode 100644 index 000000000..871be13b5 --- /dev/null +++ b/pixmaps/svg/linphone-inprogress.svg @@ -0,0 +1,66 @@ + + + + + + image/svg+xml + + chat_message_inprogress + + + + + + chat_message_inprogress + Created with Sketch. + + + diff --git a/pixmaps/svg/linphone-media-pause.svg b/pixmaps/svg/linphone-media-pause.svg new file mode 100644 index 000000000..0e8ed0de7 --- /dev/null +++ b/pixmaps/svg/linphone-media-pause.svg @@ -0,0 +1,72 @@ + + + + + + image/svg+xml + + pause_big_default + + + + + + pause_big_default + Created with Sketch. + + + + diff --git a/pixmaps/svg/linphone-media-play.svg b/pixmaps/svg/linphone-media-play.svg new file mode 100644 index 000000000..3eb7f0066 --- /dev/null +++ b/pixmaps/svg/linphone-media-play.svg @@ -0,0 +1,73 @@ + + + + + + image/svg+xml + + pause_big_default + + + + + + pause_big_default + Created with Sketch. + + + + diff --git a/pixmaps/svg/linphone-micro-enabled.svg b/pixmaps/svg/linphone-micro-enabled.svg new file mode 100644 index 000000000..a23354bc1 --- /dev/null +++ b/pixmaps/svg/linphone-micro-enabled.svg @@ -0,0 +1,78 @@ + + + + + + image/svg+xml + + micro_default + + + + + + micro_default + Created with Sketch. + + + + + + diff --git a/pixmaps/svg/linphone-micro-muted.svg b/pixmaps/svg/linphone-micro-muted.svg new file mode 100644 index 000000000..09d505c59 --- /dev/null +++ b/pixmaps/svg/linphone-micro-muted.svg @@ -0,0 +1,90 @@ + + + + + + image/svg+xml + + micro_default + + + + + + micro_default + Created with Sketch. + + + + + + + + + + diff --git a/pixmaps/svg/linphone-ok.svg b/pixmaps/svg/linphone-ok.svg new file mode 100644 index 000000000..db08198f7 --- /dev/null +++ b/pixmaps/svg/linphone-ok.svg @@ -0,0 +1,95 @@ + + + + + + image/svg+xml + + valid + valid + + + + + + valid + Created with Sketch. + + + + + + + + + + + + diff --git a/pixmaps/svg/linphone-record.svg b/pixmaps/svg/linphone-record.svg new file mode 100644 index 000000000..8709e9509 --- /dev/null +++ b/pixmaps/svg/linphone-record.svg @@ -0,0 +1,78 @@ + + + + + + image/svg+xml + + status_busy + + + + + + status_busy + Created with Sketch. + + + + + diff --git a/pixmaps/svg/linphone-security-ok.svg b/pixmaps/svg/linphone-security-ok.svg new file mode 100644 index 000000000..83e518e9b --- /dev/null +++ b/pixmaps/svg/linphone-security-ok.svg @@ -0,0 +1,76 @@ + + + + + + image/svg+xml + + security_ok + + + + + + security_ok + Created with Sketch. + + + + + + diff --git a/pixmaps/svg/linphone-security-pending.svg b/pixmaps/svg/linphone-security-pending.svg new file mode 100644 index 000000000..084755a29 --- /dev/null +++ b/pixmaps/svg/linphone-security-pending.svg @@ -0,0 +1,76 @@ + + + + + + image/svg+xml + + security_pending + + + + + + security_pending + Created with Sketch. + + + + + + diff --git a/pixmaps/svg/linphone-speaker-enabled.svg b/pixmaps/svg/linphone-speaker-enabled.svg new file mode 100644 index 000000000..8a122795d --- /dev/null +++ b/pixmaps/svg/linphone-speaker-enabled.svg @@ -0,0 +1,87 @@ + + + + + + image/svg+xml + + speaker_default + + + + + + speaker_default + Created with Sketch. + + + + + + + + + + diff --git a/pixmaps/svg/linphone-speaker-muted.svg b/pixmaps/svg/linphone-speaker-muted.svg new file mode 100644 index 000000000..1e85b85be --- /dev/null +++ b/pixmaps/svg/linphone-speaker-muted.svg @@ -0,0 +1,76 @@ + + + + + + image/svg+xml + + speaker_default + + + + + + speaker_default + Created with Sketch. + + + + + diff --git a/pixmaps/svg/linphone-start-call.svg b/pixmaps/svg/linphone-start-call.svg new file mode 100644 index 000000000..b7783041a --- /dev/null +++ b/pixmaps/svg/linphone-start-call.svg @@ -0,0 +1,73 @@ + + + + + + image/svg+xml + + + + + + + call_alt_start + Created with Sketch. + + + + diff --git a/pixmaps/svg/linphone-start-call2.svg b/pixmaps/svg/linphone-start-call2.svg new file mode 100644 index 000000000..4e6f22d9a --- /dev/null +++ b/pixmaps/svg/linphone-start-call2.svg @@ -0,0 +1,69 @@ + + + + + + image/svg+xml + + + + + + + call_start_body_over + Created with Sketch. + + + + diff --git a/pixmaps/svg/linphone-start-chat.svg b/pixmaps/svg/linphone-start-chat.svg new file mode 100644 index 000000000..aa71e6c0f --- /dev/null +++ b/pixmaps/svg/linphone-start-chat.svg @@ -0,0 +1,77 @@ + + + + + + image/svg+xml + + footer_chat + + + + + + footer_chat + Created with Sketch. + + + + + + diff --git a/pixmaps/svg/linphone-status-away.svg b/pixmaps/svg/linphone-status-away.svg new file mode 100644 index 000000000..46beec033 --- /dev/null +++ b/pixmaps/svg/linphone-status-away.svg @@ -0,0 +1,66 @@ + + + + + + image/svg+xml + + statut_absent + + + + + + statut_absent + Created with Sketch. + + + diff --git a/pixmaps/svg/linphone-status-donotdisturb.svg b/pixmaps/svg/linphone-status-donotdisturb.svg new file mode 100644 index 000000000..54e2ef8fe --- /dev/null +++ b/pixmaps/svg/linphone-status-donotdisturb.svg @@ -0,0 +1,72 @@ + + + + + + image/svg+xml + + + + + + + led_error + Created with Sketch. + + + + diff --git a/pixmaps/svg/linphone-status-offline.svg b/pixmaps/svg/linphone-status-offline.svg new file mode 100644 index 000000000..890ee2f7f --- /dev/null +++ b/pixmaps/svg/linphone-status-offline.svg @@ -0,0 +1,72 @@ + + + + + + image/svg+xml + + + + + + + led_disconnected + Created with Sketch. + + + + diff --git a/pixmaps/svg/linphone-status-online.svg b/pixmaps/svg/linphone-status-online.svg new file mode 100644 index 000000000..5f7149e4d --- /dev/null +++ b/pixmaps/svg/linphone-status-online.svg @@ -0,0 +1,66 @@ + + + + + + image/svg+xml + + status_available + + + + + + status_available + Created with Sketch. + + + diff --git a/pixmaps/svg/linphone-stop-call.svg b/pixmaps/svg/linphone-stop-call.svg new file mode 100644 index 000000000..ab4fa3b28 --- /dev/null +++ b/pixmaps/svg/linphone-stop-call.svg @@ -0,0 +1,70 @@ + + + + + + image/svg+xml + + call_hangup + + + + + + call_hangup + Created with Sketch. + + + + + diff --git a/pixmaps/svg/linphone-warning.svg b/pixmaps/svg/linphone-warning.svg new file mode 100644 index 000000000..e1cbb91d9 --- /dev/null +++ b/pixmaps/svg/linphone-warning.svg @@ -0,0 +1,106 @@ + + + + + + image/svg+xml + + chat_message_not_delivered + + + + + + chat_message_not_delivered + Created with Sketch. + + + + + + + + + + + + + + diff --git a/pixmaps/svg/more.svg b/pixmaps/svg/more.svg deleted file mode 100644 index a9d1c50c3..000000000 --- a/pixmaps/svg/more.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/pixmaps/svg/startcall-green.svg b/pixmaps/svg/startcall-green.svg deleted file mode 100644 index dac2c713b..000000000 --- a/pixmaps/svg/startcall-green.svg +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/pixmaps/svg/status-green.svg b/pixmaps/svg/status-green.svg deleted file mode 100644 index d875488b8..000000000 --- a/pixmaps/svg/status-green.svg +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/pixmaps/svg/status-offline.svg b/pixmaps/svg/status-offline.svg deleted file mode 100644 index 1576f034c..000000000 --- a/pixmaps/svg/status-offline.svg +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pixmaps/svg/status-orange.svg b/pixmaps/svg/status-orange.svg deleted file mode 100644 index 9fbd47226..000000000 --- a/pixmaps/svg/status-orange.svg +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pixmaps/svg/status-red.svg b/pixmaps/svg/status-red.svg deleted file mode 100644 index eb47308a2..000000000 --- a/pixmaps/svg/status-red.svg +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pixmaps/svg/stopcall-red.svg b/pixmaps/svg/stopcall-red.svg deleted file mode 100644 index c3616ae7c..000000000 --- a/pixmaps/svg/stopcall-red.svg +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/po/POTFILES.in b/po/POTFILES.in index 19003b0f6..c44eab3a2 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -14,24 +14,30 @@ gtk/incall_view.c gtk/loginframe.c gtk/config-fetching.c gtk/audio_assistant.c -[type: gettext/glade]gtk/main.ui [type: gettext/glade]gtk/about.ui -[type: gettext/glade]gtk/contact.ui -[type: gettext/glade]gtk/log.ui -[type: gettext/glade]gtk/password.ui -[type: gettext/glade]gtk/call_logs.ui -[type: gettext/glade]gtk/main.ui -[type: gettext/glade]gtk/sip_account.ui -[type: gettext/glade]gtk/parameters.ui +[type: gettext/glade]gtk/audio_assistant.ui [type: gettext/glade]gtk/buddylookup.ui -[type: gettext/glade]gtk/waiting.ui -[type: gettext/glade]gtk/dscp_settings.ui +[type: gettext/glade]gtk/callee_frame.ui +[type: gettext/glade]gtk/call_logs.ui [type: gettext/glade]gtk/call_statistics.ui -[type: gettext/glade]gtk/tunnel_config.ui +[type: gettext/glade]gtk/chatroom_frame.ui +[type: gettext/glade]gtk/conf_frame.ui +[type: gettext/glade]gtk/config-uri.ui +[type: gettext/glade]gtk/contact.ui +[type: gettext/glade]gtk/dscp_settings.ui +[type: gettext/glade]gtk/in_call_frame.ui [type: gettext/glade]gtk/keypad.ui [type: gettext/glade]gtk/ldap.ui -[type: gettext/glade]gtk/config-uri.ui +[type: gettext/glade]gtk/login_frame.ui +[type: gettext/glade]gtk/log.ui +[type: gettext/glade]gtk/main.ui +[type: gettext/glade]gtk/parameters.ui +[type: gettext/glade]gtk/password.ui [type: gettext/glade]gtk/provisioning-fetch.ui +[type: gettext/glade]gtk/setup_wizard.ui +[type: gettext/glade]gtk/sip_account.ui +[type: gettext/glade]gtk/tunnel_config.ui +[type: gettext/glade]gtk/waiting.ui coreapi/linphonecore.c coreapi/misc.c coreapi/presence.c diff --git a/po/POTFILES.skip b/po/POTFILES.skip index 32dcd19f2..c85434453 100755 --- a/po/POTFILES.skip +++ b/po/POTFILES.skip @@ -10,6 +10,7 @@ mediastreamer2/src/audiofilters/dtmfgen.c mediastreamer2/src/audiofilters/equalizer.c mediastreamer2/src/audiofilters/gsm.c mediastreamer2/src/audiofilters/genericplc.c +mediastreamer2/src/audiofilters/msgenericplc.c mediastreamer2/src/audiofilters/macsnd.c mediastreamer2/src/audiofilters/msconf.c mediastreamer2/src/audiofilters/msfileplayer.c diff --git a/po/ar.po b/po/ar.po index d5b7711d4..995cfa132 100644 --- a/po/ar.po +++ b/po/ar.po @@ -9,48 +9,57 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-04-30 10:13+0200\n" -"PO-Revision-Date: 2015-04-30 08:13+0000\n" +"POT-Creation-Date: 2015-11-10 15:16+0100\n" +"PO-Revision-Date: 2015-11-10 14:16+0000\n" "Last-Translator: Belledonne Communications \n" -"Language-Team: Arabic (http://www.transifex.com/projects/p/linphone-gtk/language/ar/)\n" +"Language-Team: Arabic (http://www.transifex.com/belledonne-communications/linphone-gtk/language/ar/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: ar\n" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" -#: ../gtk/calllogs.c:148 ../gtk/friendlist.c:974 +#: ../gtk/calllogs.c:178 #, c-format msgid "Call %s" msgstr "اتصل بـ %s" -#: ../gtk/calllogs.c:149 ../gtk/friendlist.c:975 +#: ../gtk/calllogs.c:179 #, c-format msgid "Send text to %s" msgstr "أرسل رسالة إلى %s" -#: ../gtk/calllogs.c:232 +#: ../gtk/calllogs.c:181 +#, c-format +msgid "Add %s to your contact list" +msgstr "إضافة %s إلى قائمة جهات اتصالك" + +#: ../gtk/calllogs.c:245 ../gtk/main.ui.h:21 +msgid "Recent calls" +msgstr "المكالمات السابقة" + +#: ../gtk/calllogs.c:260 #, c-format msgid "Recent calls (%i)" msgstr "المكالمات الفائتة (%i)" -#: ../gtk/calllogs.c:314 +#: ../gtk/calllogs.c:331 msgid "n/a" msgstr "—" -#: ../gtk/calllogs.c:317 +#: ../gtk/calllogs.c:334 msgid "Aborted" msgstr "أُلغيت" -#: ../gtk/calllogs.c:320 +#: ../gtk/calllogs.c:337 msgid "Missed" msgstr "فائتة" -#: ../gtk/calllogs.c:323 +#: ../gtk/calllogs.c:340 msgid "Declined" msgstr "مرفوضة" -#: ../gtk/calllogs.c:329 +#: ../gtk/calllogs.c:346 #, c-format msgid "%i minute" msgid_plural "%i minutes" @@ -61,7 +70,7 @@ msgstr[3] "%i دقائق" msgstr[4] "%i دقيقة" msgstr[5] "%i دقيقة" -#: ../gtk/calllogs.c:332 +#: ../gtk/calllogs.c:349 #, c-format msgid "%i second" msgid_plural "%i seconds" @@ -72,19 +81,19 @@ msgstr[3] "%i ثوان" msgstr[4] "%i ثانية" msgstr[5] "%i ثانية" -#: ../gtk/calllogs.c:337 +#: ../gtk/calllogs.c:354 #, c-format msgid "" "%s\tQuality: %s\n" "%s\t%s\t" msgstr "%s\tالجودة : %s\n%s\t%s\t" -#: ../gtk/calllogs.c:341 +#: ../gtk/calllogs.c:358 #, c-format msgid "%s\t%s" msgstr "%s\t%s" -#: ../gtk/conference.c:38 ../gtk/main.ui.h:13 +#: ../gtk/conference.c:38 ../gtk/in_call_frame.ui.h:11 msgid "Conference" msgstr "اجتماع" @@ -97,297 +106,314 @@ msgstr "أنا" msgid "Couldn't find pixmap file: %s" msgstr "أيقونة غير موجودة : %s" -#: ../gtk/main.c:137 +#: ../gtk/chat.c:196 ../gtk/chat.c:254 +msgid "Sending..." +msgstr "يجري الإرسال...‏" + +#: ../gtk/chat.c:213 ../gtk/chat.c:263 +msgid "Message not sent" +msgstr "لم تُرسَل الرسالة" + +#: ../gtk/chat.c:472 +msgid "Copy" +msgstr "نسخ" + +#: ../gtk/main.c:138 msgid "log to stdout some debug information while running." msgstr "أظهِرْ بعض معلومات التنقيح خلال التشغيل." -#: ../gtk/main.c:138 +#: ../gtk/main.c:139 +msgid "display version and exit." +msgstr "عرض الإصدار ثم المغادرة" + +#: ../gtk/main.c:140 msgid "path to a file to write logs into." msgstr "الدليل إلى الملف الذي سيُكتَب فيه سجل الوقائع." -#: ../gtk/main.c:139 +#: ../gtk/main.c:141 msgid "Start linphone with video disabled." msgstr "ابدأ لِنْفُونْ لكن دون تفعيل الفيديو." -#: ../gtk/main.c:140 +#: ../gtk/main.c:142 msgid "Start only in the system tray, do not show the main interface." msgstr "شغِّله مُصغَّرا، ولا تُظهِر الواجهة الرئيسية." -#: ../gtk/main.c:141 +#: ../gtk/main.c:143 msgid "address to call right now" msgstr "العنوان المُراد الاتصال به الآن" -#: ../gtk/main.c:142 +#: ../gtk/main.c:144 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:143 +#: ../gtk/main.c:145 msgid "Configuration file" msgstr "ملف التهيئة" -#: ../gtk/main.c:144 +#: ../gtk/main.c:146 msgid "Run the audio assistant" msgstr "ابدأ مرشد الصوت" -#: ../gtk/main.c:145 +#: ../gtk/main.c:147 msgid "Run self test and exit 0 if succeed" msgstr "شغِّل الاختبار الذاتي ثم اخرِجْ 0 إذا نجح" -#: ../gtk/main.c:1070 +#: ../gtk/main.c:1046 #, c-format msgid "" -"%s would like to add you to his contact list.\n" -"Would you allow him to see your presence status or add him to your contact list ?\n" +"%s would like to add you to his/her contact list.\n" +"Would you add him/her to your contact list and allow him/her to see your presence status?\n" "If you answer no, this person will be temporarily blacklisted." -msgstr "%s يريد إضافتك إلى جهة اتصاله.\nهل تريد السماح له برؤية معلومات حضورك وكذا إضافته إلى جهة اتصالك أيضا ؟ إذا أجبت بلا، سيُحظَر هذا الشخص مؤقتا." +msgstr "يود %s إضافتك إلى جهات اتصاله.\nهل تريد إضافته إلى جهات اتصالك والسماح له برؤية حالة حضورك ؟\nإن كان الجواب بالرفض، سوف يجري حظر هذا الشخص مؤقتا." -#: ../gtk/main.c:1147 +#: ../gtk/main.c:1123 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" msgstr "ادخل كلمة السر لـ %s\n في نطاق %s:" -#: ../gtk/main.c:1268 +#: ../gtk/main.c:1253 msgid "Call error" msgstr "خطأ في المكالمة" -#: ../gtk/main.c:1271 ../coreapi/linphonecore.c:3846 +#: ../gtk/main.c:1256 ../coreapi/linphonecore.c:3813 msgid "Call ended" msgstr "إنتهت المكالمة" -#: ../gtk/main.c:1274 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1259 ../coreapi/call_log.c:235 msgid "Incoming call" msgstr "مكالمة واردة" -#: ../gtk/main.c:1276 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1261 ../gtk/incall_view.c:580 ../gtk/in_call_frame.ui.h:2 msgid "Answer" msgstr "أجِبْ" -#: ../gtk/main.c:1278 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1263 ../gtk/in_call_frame.ui.h:3 msgid "Decline" msgstr "ارفضْ" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 msgid "Call paused" msgstr "المكالمة متوقفة" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 #, c-format msgid "by %s" msgstr "بواسطة %s" -#: ../gtk/main.c:1354 +#: ../gtk/main.c:1339 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "يود %s تشغيل الفيديو. هل تقبل ذلك ؟" -#: ../gtk/main.c:1509 +#: ../gtk/main.c:1505 msgid "Website link" msgstr "وصلة إلى الموقع وِبْ" -#: ../gtk/main.c:1568 ../gtk/waiting.ui.h:1 +#: ../gtk/main.c:1564 ../gtk/waiting.ui.h:1 msgid "Linphone" msgstr "لِنْفُونْ" -#: ../gtk/main.c:1569 +#: ../gtk/main.c:1565 msgid "A video internet phone" -msgstr "" +msgstr "الهاتف المرئي عبر الإنترنت" -#: ../gtk/main.c:1629 +#: ../gtk/main.c:1624 #, c-format msgid "%s (Default)" msgstr "%s (افتراضي)" -#: ../gtk/main.c:1962 ../coreapi/callbacks.c:1063 +#: ../gtk/main.c:1960 ../coreapi/callbacks.c:1075 #, c-format msgid "We are transferred to %s" msgstr "التحويل إلى %s" -#: ../gtk/main.c:1972 +#: ../gtk/main.c:1970 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." msgstr "لا وجود للوحة الصوت على هذا الحاسوب.\nلن تتمكن من تلقي أو إجراء أي مكالمة." -#: ../gtk/main.c:2117 +#: ../gtk/main.c:2129 msgid "A free SIP video-phone" msgstr "هاتف SIP المرئي الحر" -#: ../gtk/main.c:2221 +#: ../gtk/main.c:2242 #, c-format msgid "Hello\n" msgstr "أهلا\n" -#: ../gtk/friendlist.c:505 +#: ../gtk/friendlist.c:461 msgid "Add to addressbook" msgstr "أضف إلى دفتر العناوين" -#: ../gtk/friendlist.c:691 -msgid "Presence status" -msgstr "معلومة الحضور" - -#: ../gtk/friendlist.c:709 ../gtk/propertybox.c:569 ../gtk/contact.ui.h:1 -msgid "Name" -msgstr "الاسم" - -#: ../gtk/friendlist.c:721 -msgid "Call" -msgstr "اتصل" - -#: ../gtk/friendlist.c:726 -msgid "Chat" -msgstr "محادثة" - -#: ../gtk/friendlist.c:756 +#: ../gtk/friendlist.c:627 #, c-format msgid "Search in %s directory" msgstr "ابحث في دليل %s" -#: ../gtk/friendlist.c:924 +#: ../gtk/friendlist.c:772 msgid "Invalid sip contact !" msgstr "جهة اتصال sip غير صالحة !" -#: ../gtk/friendlist.c:976 +#: ../gtk/friendlist.c:820 +#, c-format +msgid "Add a new contact" +msgstr "إضافة جهة الاتصال جديدة" + +#: ../gtk/friendlist.c:823 #, c-format msgid "Edit contact '%s'" msgstr "حرر جهة الاتصال '%s'" -#: ../gtk/friendlist.c:977 +#: ../gtk/friendlist.c:824 #, c-format msgid "Delete contact '%s'" msgstr "احذف جهة الاتصال '%s'" -#: ../gtk/friendlist.c:978 +#: ../gtk/friendlist.c:825 #, c-format msgid "Delete chat history of '%s'" msgstr "احذف تاريخ دردشات '%s'" -#: ../gtk/friendlist.c:1029 +#: ../gtk/friendlist.c:862 #, c-format msgid "Add new contact from %s directory" msgstr "اضف جهة اتصال انطلاقا من الدليل %s" -#: ../gtk/propertybox.c:575 +#: ../gtk/propertybox.c:592 ../gtk/contact.ui.h:1 +msgid "Name" +msgstr "الاسم" + +#: ../gtk/propertybox.c:598 msgid "Rate (Hz)" msgstr "التردد (هرتز)" -#: ../gtk/propertybox.c:581 +#: ../gtk/propertybox.c:604 msgid "Status" msgstr "الحالة" -#: ../gtk/propertybox.c:587 +#: ../gtk/propertybox.c:617 msgid "IP Bitrate (kbit/s)" msgstr "صبيب IP (ك.بِتْ/ثانية)" -#: ../gtk/propertybox.c:596 +#: ../gtk/propertybox.c:628 msgid "Parameters" msgstr "الإعدادات" -#: ../gtk/propertybox.c:639 ../gtk/propertybox.c:782 +#: ../gtk/propertybox.c:670 ../gtk/propertybox.c:824 msgid "Enabled" msgstr "مفعَّل" -#: ../gtk/propertybox.c:641 ../gtk/propertybox.c:782 ../gtk/parameters.ui.h:20 +#: ../gtk/propertybox.c:672 ../gtk/propertybox.c:824 ../gtk/parameters.ui.h:60 msgid "Disabled" msgstr "غير مفعَّل" -#: ../gtk/propertybox.c:828 +#: ../gtk/propertybox.c:902 msgid "Account" msgstr "الحساب" -#: ../gtk/propertybox.c:1091 +#: ../gtk/propertybox.c:1170 msgid "English" -msgstr "الإنجليزية" +msgstr "English" -#: ../gtk/propertybox.c:1092 +#: ../gtk/propertybox.c:1171 msgid "French" -msgstr "الفرنسية" +msgstr "Français" -#: ../gtk/propertybox.c:1093 +#: ../gtk/propertybox.c:1172 msgid "Swedish" -msgstr "السويدية" +msgstr "Svenska" -#: ../gtk/propertybox.c:1094 +#: ../gtk/propertybox.c:1173 msgid "Italian" -msgstr "الإيطالية" +msgstr "Italiano" -#: ../gtk/propertybox.c:1095 +#: ../gtk/propertybox.c:1174 msgid "Spanish" -msgstr "الإسبانية" - -#: ../gtk/propertybox.c:1096 -msgid "Brazilian Portugese" -msgstr "البرتغالية البرازيلية" - -#: ../gtk/propertybox.c:1097 -msgid "Polish" -msgstr "البولونية" - -#: ../gtk/propertybox.c:1098 -msgid "German" -msgstr "الألمانية" - -#: ../gtk/propertybox.c:1099 -msgid "Russian" -msgstr "الروسية" - -#: ../gtk/propertybox.c:1100 -msgid "Japanese" -msgstr "اليابانية" - -#: ../gtk/propertybox.c:1101 -msgid "Dutch" -msgstr "الهولندية" - -#: ../gtk/propertybox.c:1102 -msgid "Hungarian" -msgstr "الهنغارية" - -#: ../gtk/propertybox.c:1103 -msgid "Czech" -msgstr "التشيكية" - -#: ../gtk/propertybox.c:1104 -msgid "Chinese" -msgstr "الصينية المبسَّطة" - -#: ../gtk/propertybox.c:1105 -msgid "Traditional Chinese" -msgstr "الصينية التقليدية" - -#: ../gtk/propertybox.c:1106 -msgid "Norwegian" -msgstr "النرويجية" - -#: ../gtk/propertybox.c:1107 -msgid "Hebrew" -msgstr "العبرية" - -#: ../gtk/propertybox.c:1108 -msgid "Serbian" -msgstr "الصربية" +msgstr "Español" #: ../gtk/propertybox.c:1175 +msgid "Brazilian Portugese" +msgstr "Português do Brasil" + +#: ../gtk/propertybox.c:1176 +msgid "Polish" +msgstr "Polski" + +#: ../gtk/propertybox.c:1177 +msgid "German" +msgstr "Deutsch" + +#: ../gtk/propertybox.c:1178 +msgid "Russian" +msgstr "Русский" + +#: ../gtk/propertybox.c:1179 +msgid "Japanese" +msgstr "日本語" + +#: ../gtk/propertybox.c:1180 +msgid "Dutch" +msgstr "Nederlands" + +#: ../gtk/propertybox.c:1181 +msgid "Hungarian" +msgstr "Magyar" + +#: ../gtk/propertybox.c:1182 +msgid "Czech" +msgstr "Čeština" + +#: ../gtk/propertybox.c:1183 +msgid "Chinese" +msgstr "简体中文" + +#: ../gtk/propertybox.c:1184 +msgid "Traditional Chinese" +msgstr "繁体中文" + +#: ../gtk/propertybox.c:1185 +msgid "Norwegian" +msgstr "Norsk bokmål" + +#: ../gtk/propertybox.c:1186 +msgid "Hebrew" +msgstr "עברית" + +#: ../gtk/propertybox.c:1187 +msgid "Serbian" +msgstr "Српски" + +#: ../gtk/propertybox.c:1188 +msgid "Arabic" +msgstr "العربية" + +#: ../gtk/propertybox.c:1189 +msgid "Turkish" +msgstr "Türkçe" + +#: ../gtk/propertybox.c:1246 msgid "" "You need to restart linphone for the new language selection to take effect." msgstr "يجب إعادة تشغيل لِنْفُونْ لكي تٌفعَّل اللغة المختارة." -#: ../gtk/propertybox.c:1255 +#: ../gtk/propertybox.c:1326 msgid "None" msgstr "بدون" -#: ../gtk/propertybox.c:1259 +#: ../gtk/propertybox.c:1330 msgid "SRTP" msgstr "SRTP" -#: ../gtk/propertybox.c:1265 +#: ../gtk/propertybox.c:1336 msgid "DTLS" msgstr "DTLS" -#: ../gtk/propertybox.c:1272 +#: ../gtk/propertybox.c:1343 msgid "ZRTP" msgstr "ZRTP" @@ -433,324 +459,195 @@ msgstr[3] "عُثِر على %i جهات اتصال" msgstr[4] "عُثِر على %i جهة اتصال" msgstr[5] "عُثِر على %i جهة اتصال" -#: ../gtk/setupwizard.c:32 -msgid "" -"Welcome!\n" -"This assistant will help you to use a SIP account for your calls." -msgstr "مرحبا !\nسيمكنك هذا المرشد من إعداد حسابك SIP لإجراء المكالمات." - -#: ../gtk/setupwizard.c:41 -msgid "Create an account on linphone.org" -msgstr "إنشاء حساب في linphone.org" - -#: ../gtk/setupwizard.c:42 -msgid "I have already a linphone.org account and I just want to use it" -msgstr "أتوفر مسبقا على حساب في linphone.org وأريد فقط استخدامه" - -#: ../gtk/setupwizard.c:43 -msgid "I have already a sip account and I just want to use it" -msgstr "أتوفر مسبقا على حساب sip وأريد فقط استخدامه" - -#: ../gtk/setupwizard.c:44 -msgid "I want to specify a remote configuration URI" -msgstr "أريد تحديد عنوان التهيئة عن بعد" - -#: ../gtk/setupwizard.c:87 -msgid "Enter your linphone.org username" -msgstr "أدخِل اسم المستخدم في linphone.org" - -#: ../gtk/setupwizard.c:100 ../gtk/parameters.ui.h:85 ../gtk/ldap.ui.h:4 -msgid "Username:" -msgstr "اسم المستخدم :" - -#: ../gtk/setupwizard.c:102 ../gtk/password.ui.h:4 ../gtk/ldap.ui.h:5 -msgid "Password:" -msgstr "كلمة السر :" - -#: ../gtk/setupwizard.c:122 -msgid "Enter your account informations" -msgstr "أدخل معلومات حسابك" - -#: ../gtk/setupwizard.c:138 -msgid "Username*" -msgstr "اسم المستخدم*" - -#: ../gtk/setupwizard.c:139 -msgid "Password*" -msgstr "كلمة السر*" - -#: ../gtk/setupwizard.c:142 -msgid "Domain*" -msgstr "النطاق*" - -#: ../gtk/setupwizard.c:143 -msgid "Proxy" -msgstr "الوكيل" - -#: ../gtk/setupwizard.c:322 -msgid "(*) Required fields" -msgstr "(*) حقول ضرورية" - -#: ../gtk/setupwizard.c:323 -msgid "Username: (*)" -msgstr "اسم المستخدم* : (*)" - -#: ../gtk/setupwizard.c:325 -msgid "Password: (*)" -msgstr "كلمة السر* : (*)" - -#: ../gtk/setupwizard.c:327 -msgid "Email: (*)" -msgstr "البريد الالكتروني : (*)" - -#: ../gtk/setupwizard.c:329 -msgid "Confirm your password: (*)" -msgstr "أكِّد كلمة السر : (*)" - -#: ../gtk/setupwizard.c:343 -msgid "Keep me informed with linphone updates" -msgstr "أحطني علما بتحديثات لِنْفُونْ" - -#: ../gtk/setupwizard.c:399 -msgid "" -"Error, account not validated, username already used or server unreachable.\n" -"Please go back and try again." -msgstr "خطأ، لم يتم تأكيد الحساب، سبق استخدام اسم المستخدم أو تعذر الوصول للخادم.\nيُرجى إعادة المحاولة لاحقا." - -#: ../gtk/setupwizard.c:410 -msgid "Thank you. Your account is now configured and ready for use." -msgstr "شكرا لك، لقد جرت تهيئة حسابك وهو الآن قابل للاستخدام." - -#: ../gtk/setupwizard.c:418 -msgid "" -"Please validate your account by clicking on the link we just sent you by email.\n" -"Then come back here and press Next button." -msgstr "يُرجى تأكيد حسابك وذلك بالضغط على الوصلة التي أرسلناها لك بالبريد الإلكتروني.\nثم ارجع إلى هنا واضغط على زر التالي." - -#: ../gtk/setupwizard.c:609 -msgid "SIP account configuration assistant" -msgstr "مرشد تهيئة حساب SIP" - -#: ../gtk/setupwizard.c:629 -msgid "Welcome to the account setup assistant" -msgstr "مرحبا بك في مرشد إعداد الحساب" - -#: ../gtk/setupwizard.c:634 -msgid "Account setup assistant" -msgstr "مرشد تهيئة الحساب" - -#: ../gtk/setupwizard.c:640 -msgid "Configure your account (step 1/1)" -msgstr "تهيئة حسابك (المرحلة 1/1)" - -#: ../gtk/setupwizard.c:645 -msgid "Enter your sip username (step 1/1)" -msgstr "أدخل اسم المستخدم SIP (المرحلة 1/1)" - -#: ../gtk/setupwizard.c:649 -msgid "Enter account information (step 1/2)" -msgstr "أدخل معلومات حسابك (المرحلة 1/2)" - -#: ../gtk/setupwizard.c:658 -msgid "Validation (step 2/2)" -msgstr "تأكيد (المرحلة 2/2)" - -#: ../gtk/setupwizard.c:663 -msgid "Error" -msgstr "خطأ" - -#: ../gtk/setupwizard.c:667 ../gtk/audio_assistant.c:534 -msgid "Terminating" -msgstr "في طور الإنهاء" - -#: ../gtk/incall_view.c:70 ../gtk/incall_view.c:94 +#: ../gtk/incall_view.c:67 ../gtk/incall_view.c:87 #, c-format msgid "Call #%i" msgstr "مكالمة #%i" -#: ../gtk/incall_view.c:155 +#: ../gtk/incall_view.c:145 #, c-format msgid "Transfer to call #%i with %s" msgstr "حوِّل إلى المكالمة #%i مع %s" -#: ../gtk/incall_view.c:211 ../gtk/incall_view.c:214 +#: ../gtk/incall_view.c:202 ../gtk/incall_view.c:205 msgid "Not used" msgstr "غير مستخدَم" -#: ../gtk/incall_view.c:221 +#: ../gtk/incall_view.c:212 msgid "ICE not activated" msgstr "ICE غير مفعَّل" -#: ../gtk/incall_view.c:223 +#: ../gtk/incall_view.c:214 msgid "ICE failed" msgstr "فَشِل ICE" -#: ../gtk/incall_view.c:225 +#: ../gtk/incall_view.c:216 msgid "ICE in progress" msgstr "تجري مساومة ICE" -#: ../gtk/incall_view.c:227 +#: ../gtk/incall_view.c:218 msgid "Going through one or more NATs" msgstr "المرور عبد واحد أو عدة NAT" -#: ../gtk/incall_view.c:229 +#: ../gtk/incall_view.c:220 msgid "Direct" msgstr "مباشر" -#: ../gtk/incall_view.c:231 +#: ../gtk/incall_view.c:222 msgid "Through a relay server" msgstr "عبر خادم بديل" -#: ../gtk/incall_view.c:239 +#: ../gtk/incall_view.c:230 msgid "uPnP not activated" msgstr "uPnP غير مفعَّل" -#: ../gtk/incall_view.c:241 +#: ../gtk/incall_view.c:232 msgid "uPnP in progress" msgstr "يجري uPnP" -#: ../gtk/incall_view.c:243 +#: ../gtk/incall_view.c:234 msgid "uPnp not available" msgstr "uPnP غير متوفر" -#: ../gtk/incall_view.c:245 +#: ../gtk/incall_view.c:236 msgid "uPnP is running" msgstr "uPnP مشغَّل" -#: ../gtk/incall_view.c:247 +#: ../gtk/incall_view.c:238 msgid "uPnP failed" msgstr "فَشِل uPnP" -#: ../gtk/incall_view.c:257 ../gtk/incall_view.c:258 +#: ../gtk/incall_view.c:248 ../gtk/incall_view.c:249 msgid "Direct or through server" msgstr "مباشرة أو عبر خادم" -#: ../gtk/incall_view.c:267 ../gtk/incall_view.c:279 +#: ../gtk/incall_view.c:258 ../gtk/incall_view.c:270 #, c-format msgid "" "download: %f\n" "upload: %f (kbit/s)" msgstr "التنزيل % f\nالرفع : %f (ك.بِتْ/الثانية)" -#: ../gtk/incall_view.c:272 ../gtk/incall_view.c:274 +#: ../gtk/incall_view.c:263 ../gtk/incall_view.c:265 #, c-format msgid "%ix%i @ %f fps" msgstr "%ix%i @ %f fps" -#: ../gtk/incall_view.c:304 +#: ../gtk/incall_view.c:295 #, c-format msgid "%.3f seconds" msgstr "%.3f ثانية" -#: ../gtk/incall_view.c:407 ../gtk/main.ui.h:12 ../gtk/videowindow.c:235 +#: ../gtk/incall_view.c:453 ../gtk/in_call_frame.ui.h:10 +#: ../gtk/videowindow.c:236 msgid "Hang up" msgstr "ضع السماعة" -#: ../gtk/incall_view.c:511 +#: ../gtk/incall_view.c:559 msgid "Calling..." msgstr "يجري الاتصال..." -#: ../gtk/incall_view.c:514 ../gtk/incall_view.c:733 -msgid "00::00::00" -msgstr "00::00::00" +#: ../gtk/incall_view.c:562 ../gtk/incall_view.c:792 +msgid "00:00:00" +msgstr "00:00:00" -#: ../gtk/incall_view.c:525 +#: ../gtk/incall_view.c:573 msgid "Incoming call" msgstr "المكالمة الواردة" -#: ../gtk/incall_view.c:562 +#: ../gtk/incall_view.c:610 msgid "good" msgstr "جيدة" -#: ../gtk/incall_view.c:564 +#: ../gtk/incall_view.c:612 msgid "average" msgstr "متوسطة" -#: ../gtk/incall_view.c:566 +#: ../gtk/incall_view.c:614 msgid "poor" msgstr "ضعيفة" -#: ../gtk/incall_view.c:568 +#: ../gtk/incall_view.c:616 msgid "very poor" msgstr "ضعيفة جدا" -#: ../gtk/incall_view.c:570 +#: ../gtk/incall_view.c:618 msgid "too bad" msgstr "سيِّئة جيدا" -#: ../gtk/incall_view.c:571 ../gtk/incall_view.c:587 +#: ../gtk/incall_view.c:619 ../gtk/incall_view.c:635 msgid "unavailable" msgstr "غير متاحة" -#: ../gtk/incall_view.c:679 +#: ../gtk/incall_view.c:731 msgid "Secured by SRTP" msgstr "آمن بواسطة SRTP" -#: ../gtk/incall_view.c:685 +#: ../gtk/incall_view.c:737 msgid "Secured by DTLS" msgstr "مُؤمَّن بواسطة DTLS" -#: ../gtk/incall_view.c:691 +#: ../gtk/incall_view.c:743 #, c-format msgid "Secured by ZRTP - [auth token: %s]" msgstr "آمن بواسطة ZRTP - [شارة الهوية : %s]" -#: ../gtk/incall_view.c:697 +#: ../gtk/incall_view.c:747 msgid "Set unverified" msgstr "أكِّدْ عدم تحقُّقك" -#: ../gtk/incall_view.c:697 ../gtk/main.ui.h:4 +#: ../gtk/incall_view.c:747 msgid "Set verified" msgstr "أكِّدْ تحقُّقَك" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In conference" msgstr "في اجتماع" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In call" msgstr "المكالمة جارية" -#: ../gtk/incall_view.c:764 +#: ../gtk/incall_view.c:824 msgid "Paused call" msgstr "المكالمة متوقفة مؤقتا" -#: ../gtk/incall_view.c:800 +#: ../gtk/incall_view.c:861 msgid "Call ended." msgstr "إنتهت المكالمة." -#: ../gtk/incall_view.c:831 +#: ../gtk/incall_view.c:892 msgid "Transfer in progress" msgstr "يجري الإرسال" -#: ../gtk/incall_view.c:834 +#: ../gtk/incall_view.c:895 msgid "Transfer done." msgstr "انتهى الإرسال." -#: ../gtk/incall_view.c:837 +#: ../gtk/incall_view.c:898 msgid "Transfer failed." msgstr "فَشِل الإرسال." -#: ../gtk/incall_view.c:881 +#: ../gtk/incall_view.c:929 msgid "Resume" msgstr "استأنِفْ" -#: ../gtk/incall_view.c:888 ../gtk/main.ui.h:9 +#: ../gtk/incall_view.c:929 ../gtk/in_call_frame.ui.h:7 msgid "Pause" msgstr "إيقاف مؤقت" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 #, c-format msgid "" "Recording into\n" "%s %s" msgstr "يسجل في\n%s %s" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 msgid "(Paused)" msgstr "(متوقف)" -#: ../gtk/loginframe.c:87 +#: ../gtk/loginframe.c:75 #, c-format msgid "Please enter login information for %s" msgstr "يُرجى إدخال معلومات الولوج ل %s" @@ -765,263 +662,108 @@ msgstr "يجلب من %s" msgid "Downloading of remote configuration from %s failed." msgstr "فَشِل تنزيل التهيئة عن بعد من %s ." -#: ../gtk/audio_assistant.c:98 +#: ../gtk/audio_assistant.c:103 msgid "No voice detected" msgstr "لم يكتشف صوتاً" -#: ../gtk/audio_assistant.c:99 +#: ../gtk/audio_assistant.c:104 msgid "Too low" msgstr "خافِت" -#: ../gtk/audio_assistant.c:100 +#: ../gtk/audio_assistant.c:105 msgid "Good" msgstr "جيد" -#: ../gtk/audio_assistant.c:101 +#: ../gtk/audio_assistant.c:106 msgid "Too loud" msgstr "صاخب" -#: ../gtk/audio_assistant.c:183 +#: ../gtk/audio_assistant.c:188 msgid "Did you hear three beeps ?" msgstr "هل سمعت ثلاث رنات ؟" -#: ../gtk/audio_assistant.c:292 ../gtk/audio_assistant.c:297 +#: ../gtk/audio_assistant.c:299 ../gtk/audio_assistant.c:304 msgid "Sound preferences not found " msgstr "لم يعثر على تفضيلات الصوت" -#: ../gtk/audio_assistant.c:306 +#: ../gtk/audio_assistant.c:313 msgid "Cannot launch system sound control " msgstr "لم يتمكن من تشغيل التحكم في الصوت للنظام" -#: ../gtk/audio_assistant.c:318 +#: ../gtk/audio_assistant.c:325 msgid "" "Welcome!\n" "This assistant will help you to configure audio settings for Linphone" msgstr "مرحبا !\nسيمكنك هذا المرشد من تهيئة إعدادات الصوت من أجل لِنْفُونْ" -#: ../gtk/audio_assistant.c:328 +#: ../gtk/audio_assistant.c:335 msgid "Capture device" msgstr "جهاز الالتقاط" -#: ../gtk/audio_assistant.c:329 +#: ../gtk/audio_assistant.c:336 msgid "Recorded volume" msgstr "الحجم المسجَّل" -#: ../gtk/audio_assistant.c:333 +#: ../gtk/audio_assistant.c:340 msgid "No voice" msgstr "صامت" -#: ../gtk/audio_assistant.c:334 ../gtk/audio_assistant.c:373 +#: ../gtk/audio_assistant.c:341 ../gtk/audio_assistant.c:380 msgid "System sound preferences" msgstr "تفضيلات الصوت للنظام" -#: ../gtk/audio_assistant.c:369 +#: ../gtk/audio_assistant.c:376 msgid "Playback device" msgstr "جهاز السماع" -#: ../gtk/audio_assistant.c:370 +#: ../gtk/audio_assistant.c:377 msgid "Play three beeps" msgstr "شغِّل ثلاث رنَّات" -#: ../gtk/audio_assistant.c:403 +#: ../gtk/audio_assistant.c:410 msgid "Press the record button and say some words" msgstr "اضغط على زر التسجيل وانطق ببعض الكلمات" -#: ../gtk/audio_assistant.c:404 +#: ../gtk/audio_assistant.c:411 msgid "Listen to your record voice" msgstr "استمع لصوتك المسجَّل" -#: ../gtk/audio_assistant.c:405 +#: ../gtk/audio_assistant.c:412 ../gtk/conf_frame.ui.h:2 +#: ../gtk/in_call_frame.ui.h:4 msgid "Record" msgstr "تسجيل" -#: ../gtk/audio_assistant.c:406 +#: ../gtk/audio_assistant.c:413 msgid "Play" msgstr "تشغيل" -#: ../gtk/audio_assistant.c:433 +#: ../gtk/audio_assistant.c:440 msgid "Let's start Linphone now" msgstr "لنُشغِّل لِنْفُونْ الآن" -#: ../gtk/audio_assistant.c:503 +#: ../gtk/audio_assistant.c:510 msgid "Audio Assistant" msgstr "مرشد الصوت" -#: ../gtk/audio_assistant.c:513 ../gtk/main.ui.h:32 +#: ../gtk/audio_assistant.c:520 ../gtk/main.ui.h:13 msgid "Audio assistant" msgstr "مرشد الصوت" -#: ../gtk/audio_assistant.c:518 +#: ../gtk/audio_assistant.c:525 msgid "Mic Gain calibration" msgstr "معايرة كسب الميكروفون" -#: ../gtk/audio_assistant.c:524 +#: ../gtk/audio_assistant.c:531 msgid "Speaker volume calibration" msgstr "معايرة شدة مكبر الصوت" -#: ../gtk/audio_assistant.c:529 +#: ../gtk/audio_assistant.c:536 msgid "Record and Play" msgstr "سَجِّل واقرأ " -#: ../gtk/main.ui.h:1 -msgid "Callee name" -msgstr "اسم المنادَى" - -#: ../gtk/main.ui.h:2 -msgid "Send" -msgstr "أرسِلْ" - -#: ../gtk/main.ui.h:3 -msgid "End conference" -msgstr "أنْهِ الاجتماع" - -#: ../gtk/main.ui.h:7 -msgid "Record this call to an audio file" -msgstr "سَجِّل هذه المكالمة في ملف صوتي" - -#: ../gtk/main.ui.h:8 -msgid "Video" -msgstr "مرئي" - -#: ../gtk/main.ui.h:10 -msgid "Mute" -msgstr "اصمُتْ" - -#: ../gtk/main.ui.h:11 -msgid "Transfer" -msgstr "إرسال" - -#: ../gtk/main.ui.h:14 -msgid "In call" -msgstr "المكالمة جارية" - -#: ../gtk/main.ui.h:15 -msgid "Duration" -msgstr "المدة" - -#: ../gtk/main.ui.h:16 -msgid "Call quality rating" -msgstr "تقييم جودة المكالمة" - -#: ../gtk/main.ui.h:17 -msgid "All users" -msgstr "كل المستخدمين" - -#: ../gtk/main.ui.h:18 -msgid "Online users" -msgstr "المستخدمون المتصلون" - -#: ../gtk/main.ui.h:19 -msgid "ADSL" -msgstr "ADSL" - -#: ../gtk/main.ui.h:20 -msgid "Fiber Channel" -msgstr "قناة الألياف الضوئية" - -#: ../gtk/main.ui.h:21 -msgid "Default" -msgstr "افتراضي" - -#: ../gtk/main.ui.h:22 -msgid "Delete" -msgstr "احذف" - -#: ../gtk/main.ui.h:23 -msgid "_Options" -msgstr "الخ_يارات" - -#: ../gtk/main.ui.h:24 -msgid "Set configuration URI" -msgstr "عنوان URI للتهيئة" - -#: ../gtk/main.ui.h:25 -msgid "Always start video" -msgstr "شغِّل الفيديو دائما" - -#: ../gtk/main.ui.h:26 -msgid "Enable self-view" -msgstr "فعِّل رؤية نفسي" - -#: ../gtk/main.ui.h:27 -msgid "_Help" -msgstr "ال_مساعدة" - -#: ../gtk/main.ui.h:28 -msgid "Show debug window" -msgstr "أظهِر نافذة التنقيح" - -#: ../gtk/main.ui.h:29 -msgid "_Homepage" -msgstr "موق_ع الوِبْ" - -#: ../gtk/main.ui.h:30 -msgid "Check _Updates" -msgstr "تحقق من التح_ديثات" - -#: ../gtk/main.ui.h:31 -msgid "Account assistant" -msgstr "مرشد الحساب" - -#: ../gtk/main.ui.h:33 -msgid "SIP address or phone number:" -msgstr "عنوان SIP أو رقم الهاتف :" - -#: ../gtk/main.ui.h:34 -msgid "Initiate a new call" -msgstr "ابدأ مكالمة جديدة" - -#: ../gtk/main.ui.h:35 -msgid "Contacts" -msgstr "جهات الاتصال" - -#: ../gtk/main.ui.h:36 -msgid "Search" -msgstr "بحث" - -#: ../gtk/main.ui.h:37 -msgid "Add contacts from directory" -msgstr "إضافة جهات الاتصال من الدليل" - -#: ../gtk/main.ui.h:38 -msgid "Add contact" -msgstr "إضافة جهة الاتصال" - -#: ../gtk/main.ui.h:39 -msgid "Recent calls" -msgstr "المكالمات السابقة" - -#: ../gtk/main.ui.h:40 -msgid "My current identity:" -msgstr "هويتي الحالية :" - -#: ../gtk/main.ui.h:41 ../gtk/tunnel_config.ui.h:7 -msgid "Username" -msgstr "اسم المستخدم" - -#: ../gtk/main.ui.h:42 ../gtk/tunnel_config.ui.h:8 -msgid "Password" -msgstr "كلمة السر" - -#: ../gtk/main.ui.h:43 -msgid "Internet connection:" -msgstr "الاتصال بالإنترنت :" - -#: ../gtk/main.ui.h:44 -msgid "Automatically log me in" -msgstr "سَجِّل دخولي تلقائيا" - -#: ../gtk/main.ui.h:45 ../gtk/password.ui.h:3 -msgid "UserID" -msgstr "مُعرِّف المستخدم" - -#: ../gtk/main.ui.h:46 -msgid "Login information" -msgstr "معلومات الولوج" - -#: ../gtk/main.ui.h:47 -msgid "Welcome!" -msgstr "مرحبا !" +#: ../gtk/audio_assistant.c:541 ../gtk/setup_wizard.ui.h:38 +msgid "Terminating" +msgstr "في طور الإنهاء" #: ../gtk/about.ui.h:1 msgid "About Linphone" @@ -1051,456 +793,6 @@ msgid "" "he: Eli Zaretskii \n" msgstr "fr: Simon Morlat\nen: Simon Morlat and Delphine Perreau\nit: Alberto Zanoni \nde: Jean-Jacques Sarton \nsv: Daniel Nylander \nes: Jesus Benitez \nja: YAMAGUCHI YOSHIYA \npt_BR: Rafael Caesar Lenzi \npl: Robert Nasiadek \ncs: Petr Pisar \nhu: anonymous\nhe: Eli Zaretskii \nar: Muhiyeddine Cherik \n" -#: ../gtk/contact.ui.h:2 -msgid "SIP Address" -msgstr "عنوان SIP" - -#: ../gtk/contact.ui.h:3 -msgid "Show this contact presence status" -msgstr "رؤية حالة حضور جهة الاتصال هذه" - -#: ../gtk/contact.ui.h:4 -msgid "Allow this contact to see my presence status" -msgstr "السماح لجهة الاتصال هذه برؤية حالة حضوري" - -#: ../gtk/contact.ui.h:5 -msgid "Contact information" -msgstr "معلومات جهة الاتصال" - -#: ../gtk/log.ui.h:1 -msgid "Linphone debug window" -msgstr "نافذة تنقيح لِنْفُونْ" - -#: ../gtk/log.ui.h:2 -msgid "Scroll to end" -msgstr "مرِّر إلى الآخر" - -#: ../gtk/password.ui.h:1 -msgid "Linphone - Authentication required" -msgstr "لِنْفُونْ - يجب التحقق من الهوية" - -#: ../gtk/password.ui.h:2 -msgid "Please enter the domain password" -msgstr "أدخل كلمة سر النطاق" - -#: ../gtk/call_logs.ui.h:1 -msgid "Call history" -msgstr "تاريخ المكالمات" - -#: ../gtk/call_logs.ui.h:2 -msgid "Clear all" -msgstr "أفْرِغ الكل" - -#: ../gtk/call_logs.ui.h:3 -msgid "Call back" -msgstr "إعادة الاتصال" - -#: ../gtk/sip_account.ui.h:1 -msgid "Linphone - Configure a SIP account" -msgstr "لِنْفُونْ - تهيئة حساب SIP" - -#: ../gtk/sip_account.ui.h:2 -msgid "Your SIP identity:" -msgstr "هوية SIP لديك :" - -#: ../gtk/sip_account.ui.h:3 -msgid "Looks like sip:@" -msgstr "يشبه sip:@" - -#: ../gtk/sip_account.ui.h:4 -msgid "sip:" -msgstr "sip:" - -#: ../gtk/sip_account.ui.h:5 -msgid "SIP Proxy address:" -msgstr "عنوان وكيل SIP :" - -#: ../gtk/sip_account.ui.h:6 -msgid "Looks like sip:" -msgstr "يشبه sip:" - -#: ../gtk/sip_account.ui.h:7 -msgid "Registration duration (sec):" -msgstr "مدة التسجيل (بالثواني) :" - -#: ../gtk/sip_account.ui.h:8 -msgid "Contact params (optional):" -msgstr "إعدادات جهة الاتصال (اختيارية) :" - -#: ../gtk/sip_account.ui.h:9 -msgid "AVPF regular RTCP interval (sec):" -msgstr "مجال RTCP الاعتيادي ل AVPF (بالثواني) :" - -#: ../gtk/sip_account.ui.h:10 -msgid "Route (optional):" -msgstr "التوجيه (اختياري) :" - -#: ../gtk/sip_account.ui.h:11 -msgid "Transport" -msgstr "النقل" - -#: ../gtk/sip_account.ui.h:12 -msgid "Register" -msgstr "التسجيل" - -#: ../gtk/sip_account.ui.h:13 -msgid "Publish presence information" -msgstr "انشر معلومات الحضور" - -#: ../gtk/sip_account.ui.h:14 -msgid "Enable AVPF" -msgstr "فعِّل AVPF " - -#: ../gtk/sip_account.ui.h:15 -msgid "Configure a SIP account" -msgstr "تهيئة حساب SIP" - -#: ../gtk/parameters.ui.h:1 -msgid "anonymous" -msgstr "مجهول" - -#: ../gtk/parameters.ui.h:2 -msgid "GSSAPI" -msgstr "GSSAPI" - -#: ../gtk/parameters.ui.h:3 -msgid "SASL" -msgstr "SASL" - -#: ../gtk/parameters.ui.h:4 -msgid "default soundcard" -msgstr "لوحة الصوت الافتراضية" - -#: ../gtk/parameters.ui.h:5 -msgid "a sound card" -msgstr "لوحة الصوت" - -#: ../gtk/parameters.ui.h:6 -msgid "default camera" -msgstr "الكاميرا الافتراضية" - -#: ../gtk/parameters.ui.h:7 -msgid "CIF" -msgstr "CIF" - -#: ../gtk/parameters.ui.h:8 -msgid "Audio codecs" -msgstr "مرمازات الصوت" - -#: ../gtk/parameters.ui.h:9 -msgid "Video codecs" -msgstr "مرمازات الفيديو" - -#: ../gtk/parameters.ui.h:10 -msgid "C" -msgstr "C" - -#: ../gtk/parameters.ui.h:11 -msgid "SIP (UDP)" -msgstr "SIP (UDP)" - -#: ../gtk/parameters.ui.h:12 -msgid "SIP (TCP)" -msgstr "SIP (TCP)" - -#: ../gtk/parameters.ui.h:13 -msgid "SIP (TLS)" -msgstr "SIP (TLS)" - -#: ../gtk/parameters.ui.h:14 -msgid "Settings" -msgstr "الإعدادات" - -#: ../gtk/parameters.ui.h:15 -msgid "Set Maximum Transmission Unit:" -msgstr "حدِّد Maximum Transmission Unit :" - -#: ../gtk/parameters.ui.h:16 -msgid "Send DTMFs as SIP info" -msgstr "أرسِل الأرقام الهاتفية على هيئة SIP INFO" - -#: ../gtk/parameters.ui.h:17 -msgid "Allow IPv6" -msgstr "السماح باستخدام IPv6" - -#: ../gtk/parameters.ui.h:18 -msgid "Transport" -msgstr "النقل" - -#: ../gtk/parameters.ui.h:19 -msgid "SIP/UDP port" -msgstr "منفذ SIP/UDP" - -#: ../gtk/parameters.ui.h:21 -msgid "Random" -msgstr "عشوائي" - -#: ../gtk/parameters.ui.h:22 -msgid "SIP/TCP port" -msgstr "منفذ SIP/TCP" - -#: ../gtk/parameters.ui.h:23 -msgid "Audio RTP/UDP:" -msgstr "صوت RTP/UDP :" - -#: ../gtk/parameters.ui.h:24 -msgid "Fixed" -msgstr "ثابت" - -#: ../gtk/parameters.ui.h:25 -msgid "Video RTP/UDP:" -msgstr "فيديو RTP/UDP :" - -#: ../gtk/parameters.ui.h:26 -msgid "Media encryption type" -msgstr "نوع وسيط التعمية" - -#: ../gtk/parameters.ui.h:27 -msgid "Media encryption is mandatory" -msgstr "وسيط التعمية إجباري" - -#: ../gtk/parameters.ui.h:28 -msgid "Tunnel" -msgstr "النفق" - -#: ../gtk/parameters.ui.h:29 -msgid "DSCP fields" -msgstr "حقول DSCP" - -#: ../gtk/parameters.ui.h:30 -msgid "Network protocol and ports" -msgstr "بروتوكول الشبكة والمنافذ" - -#: ../gtk/parameters.ui.h:31 -msgid "Direct connection to the Internet" -msgstr "الاتصال مباشر بالإنترنت" - -#: ../gtk/parameters.ui.h:32 -msgid "Behind NAT / Firewall (specify gateway IP )" -msgstr "وراء جدار ناري (حدِّد عنوان IP البوابة)" - -#: ../gtk/parameters.ui.h:33 -msgid "Behind NAT / Firewall (use STUN to resolve)" -msgstr "وراء جدار ناري (استخدم STUN)" - -#: ../gtk/parameters.ui.h:34 -msgid "Behind NAT / Firewall (use ICE)" -msgstr "وراء جدار ناري (استخدم ICE)" - -#: ../gtk/parameters.ui.h:35 -msgid "Behind NAT / Firewall (use uPnP)" -msgstr "وراء جدار ناري (استخدم uPnP)" - -#: ../gtk/parameters.ui.h:36 -msgid "Public IP address:" -msgstr "عنوان IP العمومي :" - -#: ../gtk/parameters.ui.h:37 -msgid "Stun server:" -msgstr "خادم STUN :" - -#: ../gtk/parameters.ui.h:38 -msgid "NAT and Firewall" -msgstr "إعدادات حول الجدار الناري" - -#: ../gtk/parameters.ui.h:39 -msgid "Network settings" -msgstr "إعدادات الشبكة" - -#: ../gtk/parameters.ui.h:40 -msgid "Ring sound:" -msgstr "صوت الجرس :" - -#: ../gtk/parameters.ui.h:41 -msgid "ALSA special device (optional):" -msgstr "عتاد ALSA الخصوصي (اختياري) :" - -#: ../gtk/parameters.ui.h:42 -msgid "Capture device:" -msgstr "جهاز الالتقاط :" - -#: ../gtk/parameters.ui.h:43 -msgid "Ring device:" -msgstr "جهاز الرنين :" - -#: ../gtk/parameters.ui.h:44 -msgid "Playback device:" -msgstr "جهاز السمع :" - -#: ../gtk/parameters.ui.h:45 -msgid "Enable echo cancellation" -msgstr "فعِّل إزالة الصدى" - -#: ../gtk/parameters.ui.h:46 -msgid "Audio" -msgstr "الصوت" - -#: ../gtk/parameters.ui.h:47 -msgid "Video input device:" -msgstr "جهاز إدخال الفيديو :" - -#: ../gtk/parameters.ui.h:48 -msgid "Prefered video resolution:" -msgstr "المقدار المُراد لدقة الفيديو :" - -#: ../gtk/parameters.ui.h:49 -msgid "Video output method:" -msgstr "طريقة إخراج الفيديو :" - -#: ../gtk/parameters.ui.h:50 -msgid "Show camera preview" -msgstr "اظهر معاينة الكاميرا" - -#: ../gtk/parameters.ui.h:51 -msgid "Video" -msgstr "الفيديو" - -#: ../gtk/parameters.ui.h:52 -msgid "Multimedia settings" -msgstr "إعدادات الوسائط المتعددة" - -#: ../gtk/parameters.ui.h:53 -msgid "This section defines your SIP address when not using a SIP account" -msgstr "هذه الفقرة تحدد عنوانك SIP إن كنت لا تستخدم حساب SIP" - -#: ../gtk/parameters.ui.h:54 -msgid "Your display name (eg: John Doe):" -msgstr "اسمك المعروض (مثلا : زيد عمرو) :" - -#: ../gtk/parameters.ui.h:55 -msgid "Your username:" -msgstr "اسم المستخدم :" - -#: ../gtk/parameters.ui.h:56 -msgid "Your resulting SIP address:" -msgstr "عنوانك SIP :" - -#: ../gtk/parameters.ui.h:57 -msgid "Default identity" -msgstr "الهوية الافتراضية" - -#: ../gtk/parameters.ui.h:58 -msgid "Wizard" -msgstr "المرشد" - -#: ../gtk/parameters.ui.h:59 -msgid "Add" -msgstr "إضافة" - -#: ../gtk/parameters.ui.h:60 -msgid "Edit" -msgstr "حرر" - -#: ../gtk/parameters.ui.h:61 -msgid "Remove" -msgstr "أزل" - -#: ../gtk/parameters.ui.h:62 -msgid "Proxy accounts" -msgstr "حسابات الوكيل" - -#: ../gtk/parameters.ui.h:63 -msgid "Erase all passwords" -msgstr "احذف جميع كلمات السر" - -#: ../gtk/parameters.ui.h:64 -msgid "Privacy" -msgstr "الأمان" - -#: ../gtk/parameters.ui.h:65 -msgid "Automatically answer when a call is received" -msgstr "الإجابة تلقائيا فور تلقي المكالمة" - -#: ../gtk/parameters.ui.h:66 -msgid "Delay before answering (ms)" -msgstr "التأخير قبل الإجابة (ميلي ث,)" - -#: ../gtk/parameters.ui.h:67 -msgid "Auto-answer" -msgstr "الإجابة تلقائيا" - -#: ../gtk/parameters.ui.h:68 -msgid "Manage SIP Accounts" -msgstr "إدارة حسابات SIP" - -#: ../gtk/parameters.ui.h:69 ../gtk/tunnel_config.ui.h:4 -msgid "Enable" -msgstr "فعِّل" - -#: ../gtk/parameters.ui.h:70 ../gtk/tunnel_config.ui.h:5 -msgid "Disable" -msgstr "إلغاء التفعيل" - -#: ../gtk/parameters.ui.h:71 -msgid "Codecs" -msgstr "المراميز" - -#: ../gtk/parameters.ui.h:72 -msgid "0 stands for \"unlimited\"" -msgstr "حدِّد 0 لعدم وضع أي حد" - -#: ../gtk/parameters.ui.h:73 -msgid "Upload speed limit in Kbit/sec:" -msgstr "حد سرعة الرفع بالكيلوبِتْ/الثانية :" - -#: ../gtk/parameters.ui.h:74 -msgid "Download speed limit in Kbit/sec:" -msgstr "حد سرعة التنزيل بالكيلوبِتْ/الثانية :" - -#: ../gtk/parameters.ui.h:75 -msgid "Enable adaptive rate control" -msgstr "فعِّل التحكم المتكيف مع الصبيب" - -#: ../gtk/parameters.ui.h:76 -msgid "" -"Adaptive rate control is a technique to dynamically guess the available " -"bandwidth during a call." -msgstr "التحكم المتكيف مع الصبيب هو تقنية لملائمة جودة الصوت والصورة بناءً على سعة قناة الاتصال المتاحة خلال المكالمة." - -#: ../gtk/parameters.ui.h:77 -msgid "Bandwidth control" -msgstr "إدارة سعة القناة" - -#: ../gtk/parameters.ui.h:78 -msgid "Codecs" -msgstr "المراميز" - -#: ../gtk/parameters.ui.h:79 -msgid "Language" -msgstr "اللغة" - -#: ../gtk/parameters.ui.h:80 -msgid "Show advanced settings" -msgstr "أظهر الإعدادات المتقدمة" - -#: ../gtk/parameters.ui.h:81 -msgid "Level" -msgstr "المستوى" - -#: ../gtk/parameters.ui.h:82 -msgid "User interface" -msgstr "واجهة المستخدم" - -#: ../gtk/parameters.ui.h:83 ../gtk/ldap.ui.h:2 -msgid "Server address:" -msgstr "عنوان الخادم :" - -#: ../gtk/parameters.ui.h:84 ../gtk/ldap.ui.h:3 -msgid "Authentication method:" -msgstr "طريقة التحقق من الهوية :" - -#: ../gtk/parameters.ui.h:86 -msgid "LDAP Account setup" -msgstr "تهيئة LDAP" - -#: ../gtk/parameters.ui.h:87 -msgid "LDAP" -msgstr "LDAP" - -#: ../gtk/parameters.ui.h:88 -msgid "Done" -msgstr "أغلق" - #: ../gtk/buddylookup.ui.h:1 msgid "Search contacts in directory" msgstr "البحث عن جهات الاتصال في الدليل" @@ -1513,29 +805,21 @@ msgstr "الإضافة إلى قائمتي" msgid "Search somebody" msgstr "البحث عن شخص" -#: ../gtk/waiting.ui.h:2 -msgid "Please wait" -msgstr "يُرجى الانتظار" +#: ../gtk/callee_frame.ui.h:1 +msgid "Callee name" +msgstr "اسم المنادَى" -#: ../gtk/dscp_settings.ui.h:1 -msgid "DSCP settings" -msgstr "إعدادات DSCP" +#: ../gtk/call_logs.ui.h:1 +msgid "Call history" +msgstr "تاريخ المكالمات" -#: ../gtk/dscp_settings.ui.h:2 -msgid "SIP" -msgstr "SIP" +#: ../gtk/call_logs.ui.h:2 +msgid "Clear all" +msgstr "أفْرِغ الكل" -#: ../gtk/dscp_settings.ui.h:3 -msgid "Audio RTP stream" -msgstr "تدفق RTP الصوتي" - -#: ../gtk/dscp_settings.ui.h:4 -msgid "Video RTP stream" -msgstr "تدفق RTP المرئي" - -#: ../gtk/dscp_settings.ui.h:5 -msgid "Set DSCP values (in hexadecimal)" -msgstr "حدد قيم DSCP (بالنظام الست-عشري)" +#: ../gtk/call_logs.ui.h:3 +msgid "Call back" +msgstr "إعادة الاتصال" #: ../gtk/call_statistics.ui.h:1 msgid "Call statistics" @@ -1585,30 +869,112 @@ msgstr "تشكيلة RTP" msgid "Call statistics and information" msgstr "إحصاء المكالمات والمعلومات" -#: ../gtk/tunnel_config.ui.h:1 -msgid "Configure VoIP tunnel" -msgstr "تهيئة نفق VoIP" +#: ../gtk/chatroom_frame.ui.h:1 +msgid "Send" +msgstr "أرسِلْ" -#: ../gtk/tunnel_config.ui.h:2 -msgid "Host" -msgstr "المضيف" +#: ../gtk/conf_frame.ui.h:1 +msgid "End conference" +msgstr "أنْهِ الاجتماع" -#: ../gtk/tunnel_config.ui.h:3 -msgid "Port" -msgstr "المنفذ" +#: ../gtk/config-uri.ui.h:1 +msgid "Specifying a remote configuration URI" +msgstr "تحديد عنوان URI التهيئة عن بعد" -#: ../gtk/tunnel_config.ui.h:6 -msgid "Configure tunnel" -msgstr "تهيئة النفق" +#: ../gtk/config-uri.ui.h:2 +msgid "" +"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" +"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " +msgstr "يسمح لك مربع الحوار هذا بإعداد عنوان http أو https الذي من خلاله تود جلب التهيئة عند بدء البرنامج.\nأدخل العنوان أسفله. بعد تأكيد الأمر، ستجري إعادة تشغيل لِنْفُونْ تلقائيا من أجل جلب والأخذ بعين الاعتبار الإعدادات الحديثة." -#: ../gtk/tunnel_config.ui.h:9 -msgid "Configure http proxy (optional)" -msgstr "تهيئة وكيل http (اختياري)" +#: ../gtk/contact.ui.h:2 +msgid "SIP Address" +msgstr "عنوان SIP" + +#: ../gtk/contact.ui.h:3 +msgid "Show this contact presence status" +msgstr "رؤية حالة حضور جهة الاتصال هذه" + +#: ../gtk/contact.ui.h:4 +msgid "Allow this contact to see my presence status" +msgstr "السماح لجهة الاتصال هذه برؤية حالة حضوري" + +#: ../gtk/contact.ui.h:5 +msgid "Contact information" +msgstr "معلومات جهة الاتصال" + +#: ../gtk/dscp_settings.ui.h:1 +msgid "DSCP settings" +msgstr "إعدادات DSCP" + +#: ../gtk/dscp_settings.ui.h:2 +msgid "SIP" +msgstr "SIP" + +#: ../gtk/dscp_settings.ui.h:3 +msgid "Audio RTP stream" +msgstr "تدفق RTP الصوتي" + +#: ../gtk/dscp_settings.ui.h:4 +msgid "Video RTP stream" +msgstr "تدفق RTP المرئي" + +#: ../gtk/dscp_settings.ui.h:5 +msgid "Set DSCP values (in hexadecimal)" +msgstr "حدد قيم DSCP (بالنظام الست-عشري)" + +#: ../gtk/in_call_frame.ui.h:1 +msgid "Click here to set the speakers volume" +msgstr "اضغط هنا لتحديد شدة مكبر الصوت" + +#: ../gtk/in_call_frame.ui.h:5 +msgid "Record this call to an audio file" +msgstr "سَجِّل هذه المكالمة في ملف صوتي" + +#: ../gtk/in_call_frame.ui.h:6 +msgid "Video" +msgstr "مرئي" + +#: ../gtk/in_call_frame.ui.h:8 +msgid "Mute" +msgstr "اصمُتْ" + +#: ../gtk/in_call_frame.ui.h:9 +msgid "Transfer" +msgstr "إرسال" + +#: ../gtk/in_call_frame.ui.h:12 +msgid "In call" +msgstr "المكالمة جارية" + +#: ../gtk/in_call_frame.ui.h:13 +msgid "Duration" +msgstr "المدة" + +#: ../gtk/in_call_frame.ui.h:14 +msgid "Call quality rating" +msgstr "تقييم جودة المكالمة" #: ../gtk/ldap.ui.h:1 msgid "LDAP Settings" msgstr "إعدادات LDAP" +#: ../gtk/ldap.ui.h:2 ../gtk/parameters.ui.h:89 +msgid "Server address:" +msgstr "عنوان الخادم :" + +#: ../gtk/ldap.ui.h:3 ../gtk/parameters.ui.h:90 +msgid "Authentication method:" +msgstr "طريقة التحقق من الهوية :" + +#: ../gtk/ldap.ui.h:4 ../gtk/parameters.ui.h:91 ../gtk/setup_wizard.ui.h:17 +msgid "Username:" +msgstr "اسم المستخدم :" + +#: ../gtk/ldap.ui.h:5 ../gtk/password.ui.h:4 ../gtk/setup_wizard.ui.h:18 +msgid "Password:" +msgstr "كلمة السر :" + #: ../gtk/ldap.ui.h:6 msgid "Use TLS Connection" msgstr "استخدم TLS" @@ -1694,15 +1060,503 @@ msgstr "DIGEST-MD5" msgid "NTLM" msgstr "NTLM" -#: ../gtk/config-uri.ui.h:1 -msgid "Specifying a remote configuration URI" -msgstr "تحديد عنوان URI التهيئة عن بعد" +#: ../gtk/login_frame.ui.h:1 ../gtk/tunnel_config.ui.h:7 +msgid "Username" +msgstr "اسم المستخدم" -#: ../gtk/config-uri.ui.h:2 +#: ../gtk/login_frame.ui.h:2 ../gtk/tunnel_config.ui.h:8 +msgid "Password" +msgstr "كلمة السر" + +#: ../gtk/login_frame.ui.h:3 +msgid "Internet connection:" +msgstr "الاتصال بالإنترنت :" + +#: ../gtk/login_frame.ui.h:4 +msgid "Automatically log me in" +msgstr "سَجِّل دخولي تلقائيا" + +#: ../gtk/login_frame.ui.h:5 ../gtk/password.ui.h:3 +msgid "UserID" +msgstr "مُعرِّف المستخدم" + +#: ../gtk/login_frame.ui.h:6 +msgid "Login information" +msgstr "معلومات الولوج" + +#: ../gtk/login_frame.ui.h:7 +msgid "Welcome!" +msgstr "مرحبا !" + +#: ../gtk/login_frame.ui.h:8 +msgid "ADSL" +msgstr "ADSL" + +#: ../gtk/login_frame.ui.h:9 +msgid "Fiber Channel" +msgstr "قناة الألياف الضوئية" + +#: ../gtk/log.ui.h:1 +msgid "Linphone debug window" +msgstr "نافذة تنقيح لِنْفُونْ" + +#: ../gtk/log.ui.h:2 +msgid "Scroll to end" +msgstr "مرِّر إلى الآخر" + +#: ../gtk/main.ui.h:1 +msgid "Default" +msgstr "افتراضي" + +#: ../gtk/main.ui.h:2 +msgid "Delete" +msgstr "احذف" + +#: ../gtk/main.ui.h:3 +msgid "_Options" +msgstr "الخ_يارات" + +#: ../gtk/main.ui.h:4 +msgid "Set configuration URI" +msgstr "عنوان URI للتهيئة" + +#: ../gtk/main.ui.h:5 +msgid "Always start video" +msgstr "شغِّل الفيديو دائما" + +#: ../gtk/main.ui.h:6 +msgid "Enable self-view" +msgstr "فعِّل رؤية نفسي" + +#: ../gtk/main.ui.h:7 +msgid "Show keypad" +msgstr "إظهار لوحة الأرقام" + +#: ../gtk/main.ui.h:8 +msgid "_Help" +msgstr "ال_مساعدة" + +#: ../gtk/main.ui.h:9 +msgid "Show debug window" +msgstr "أظهِر نافذة التنقيح" + +#: ../gtk/main.ui.h:10 +msgid "_Homepage" +msgstr "موق_ع الوِبْ" + +#: ../gtk/main.ui.h:11 +msgid "Check _Updates" +msgstr "تحقق من التح_ديثات" + +#: ../gtk/main.ui.h:12 +msgid "Account assistant" +msgstr "مرشد الحساب" + +#: ../gtk/main.ui.h:14 +msgid "SIP address or phone number:" +msgstr "عنوان SIP أو رقم الهاتف :" + +#: ../gtk/main.ui.h:15 +msgid "Initiate a new call" +msgstr "ابدأ مكالمة جديدة" + +#: ../gtk/main.ui.h:16 +msgid "Contacts" +msgstr "جهات الاتصال" + +#: ../gtk/main.ui.h:17 +msgid "Search" +msgstr "بحث" + +#: ../gtk/main.ui.h:18 +msgid "Add contacts from directory" +msgstr "إضافة جهات الاتصال من الدليل" + +#: ../gtk/main.ui.h:19 +msgid "Add contact" +msgstr "إضافة جهة الاتصال" + +#: ../gtk/main.ui.h:20 +msgid "Clear call history" +msgstr "محو تاريخ المكالمات" + +#: ../gtk/main.ui.h:22 +msgid "My current identity:" +msgstr "هويتي الحالية :" + +#: ../gtk/main.ui.h:23 +msgid "Autoanswer is enabled" +msgstr "الإجابة التلقائية مُفعَّلة" + +#: ../gtk/parameters.ui.h:1 +msgid "anonymous" +msgstr "مجهول" + +#: ../gtk/parameters.ui.h:2 +msgid "GSSAPI" +msgstr "GSSAPI" + +#: ../gtk/parameters.ui.h:3 +msgid "SASL" +msgstr "SASL" + +#: ../gtk/parameters.ui.h:4 +msgid "default soundcard" +msgstr "لوحة الصوت الافتراضية" + +#: ../gtk/parameters.ui.h:5 +msgid "a sound card" +msgstr "لوحة الصوت" + +#: ../gtk/parameters.ui.h:6 +msgid "default camera" +msgstr "الكاميرا الافتراضية" + +#: ../gtk/parameters.ui.h:7 +msgid "CIF" +msgstr "CIF" + +#: ../gtk/parameters.ui.h:8 +msgid "Audio codecs" +msgstr "مرمازات الصوت" + +#: ../gtk/parameters.ui.h:9 +msgid "Video codecs" +msgstr "مرمازات الفيديو" + +#: ../gtk/parameters.ui.h:10 +msgid "C" +msgstr "C" + +#: ../gtk/parameters.ui.h:11 +msgid "SIP (UDP)" +msgstr "SIP (UDP)" + +#: ../gtk/parameters.ui.h:12 +msgid "SIP (TCP)" +msgstr "SIP (TCP)" + +#: ../gtk/parameters.ui.h:13 +msgid "SIP (TLS)" +msgstr "SIP (TLS)" + +#: ../gtk/parameters.ui.h:14 +msgid "default" +msgstr "افتراضي" + +#: ../gtk/parameters.ui.h:15 +msgid "high-fps" +msgstr "صبيب الإطارات مرتفع" + +#: ../gtk/parameters.ui.h:16 +msgid "custom" +msgstr "مخصص" + +#: ../gtk/parameters.ui.h:17 +msgid "Settings" +msgstr "الإعدادات" + +#: ../gtk/parameters.ui.h:18 +msgid "This section defines your SIP address when not using a SIP account" +msgstr "هذه الفقرة تحدد عنوانك SIP إن كنت لا تستخدم حساب SIP" + +#: ../gtk/parameters.ui.h:19 +msgid "Your display name (eg: John Doe):" +msgstr "اسمك المعروض (مثلا : زيد عمرو) :" + +#: ../gtk/parameters.ui.h:20 +msgid "Your username:" +msgstr "اسم المستخدم :" + +#: ../gtk/parameters.ui.h:21 +msgid "Your resulting SIP address:" +msgstr "عنوانك SIP :" + +#: ../gtk/parameters.ui.h:22 +msgid "Default identity" +msgstr "الهوية الافتراضية" + +#: ../gtk/parameters.ui.h:23 +msgid "Wizard" +msgstr "المرشد" + +#: ../gtk/parameters.ui.h:24 +msgid "Add" +msgstr "إضافة" + +#: ../gtk/parameters.ui.h:25 +msgid "Edit" +msgstr "حرر" + +#: ../gtk/parameters.ui.h:26 +msgid "Remove" +msgstr "أزل" + +#: ../gtk/parameters.ui.h:27 +msgid "Proxy accounts" +msgstr "حسابات الوكيل" + +#: ../gtk/parameters.ui.h:28 +msgid "Erase all passwords" +msgstr "احذف جميع كلمات السر" + +#: ../gtk/parameters.ui.h:29 +msgid "Privacy" +msgstr "الأمان" + +#: ../gtk/parameters.ui.h:30 +msgid "Automatically answer when a call is received" +msgstr "الإجابة تلقائيا فور تلقي المكالمة" + +#: ../gtk/parameters.ui.h:31 +msgid "Delay before answering (ms)" +msgstr "التأخير قبل الإجابة (ميلي ث,)" + +#: ../gtk/parameters.ui.h:32 +msgid "Auto-answer" +msgstr "الإجابة تلقائيا" + +#: ../gtk/parameters.ui.h:33 +msgid "Manage SIP Accounts" +msgstr "إدارة حسابات SIP" + +#: ../gtk/parameters.ui.h:34 +msgid "Ring sound:" +msgstr "صوت الجرس :" + +#: ../gtk/parameters.ui.h:35 +msgid "ALSA special device (optional):" +msgstr "عتاد ALSA الخصوصي (اختياري) :" + +#: ../gtk/parameters.ui.h:36 +msgid "Capture device:" +msgstr "جهاز الالتقاط :" + +#: ../gtk/parameters.ui.h:37 +msgid "Ring device:" +msgstr "جهاز الرنين :" + +#: ../gtk/parameters.ui.h:38 +msgid "Playback device:" +msgstr "جهاز السمع :" + +#: ../gtk/parameters.ui.h:39 +msgid "Enable echo cancellation" +msgstr "فعِّل إزالة الصدى" + +#: ../gtk/parameters.ui.h:40 +msgid "Audio" +msgstr "الصوت" + +#: ../gtk/parameters.ui.h:41 +msgid "Video input device:" +msgstr "جهاز إدخال الفيديو :" + +#: ../gtk/parameters.ui.h:42 +msgid "Preferred video resolution:" +msgstr "المقدار المُراد لدقة الفيديو :" + +#: ../gtk/parameters.ui.h:43 +msgid "Video output method:" +msgstr "طريقة إخراج الفيديو :" + +#: ../gtk/parameters.ui.h:44 +msgid "Show camera preview" +msgstr "اظهر معاينة الكاميرا" + +#: ../gtk/parameters.ui.h:45 +msgid "Video preset:" +msgstr "الفيديو المُسبَق :" + +#: ../gtk/parameters.ui.h:46 +msgid "Preferred video framerate:" +msgstr "المقدار المُراد لمعدل إطارات الفيديو :" + +#: ../gtk/parameters.ui.h:47 +msgid "0 stands for \"unlimited\"" +msgstr "حدِّد 0 لعدم وضع أي حد" + +#: ../gtk/parameters.ui.h:48 +msgid "Video" +msgstr "الفيديو" + +#: ../gtk/parameters.ui.h:49 +msgid "Upload speed limit in Kbit/sec:" +msgstr "حد سرعة الرفع بالكيلوبِتْ/الثانية :" + +#: ../gtk/parameters.ui.h:50 +msgid "Download speed limit in Kbit/sec:" +msgstr "حد سرعة التنزيل بالكيلوبِتْ/الثانية :" + +#: ../gtk/parameters.ui.h:51 +msgid "Enable adaptive rate control" +msgstr "فعِّل التحكم المتكيف مع الصبيب" + +#: ../gtk/parameters.ui.h:52 msgid "" -"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" -"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " -msgstr "يسمح لك مربع الحوار هذا بإعداد عنوان http أو https الذي من خلاله تود جلب التهيئة عند بدء البرنامج.\nأدخل العنوان أسفله. بعد تأكيد الأمر، ستجري إعادة تشغيل لِنْفُونْ تلقائيا من أجل جلب والأخذ بعين الاعتبار الإعدادات الحديثة." +"Adaptive rate control is a technique to dynamically guess the available " +"bandwidth during a call." +msgstr "التحكم المتكيف مع الصبيب هو تقنية لملائمة جودة الصوت والصورة بناءً على سعة قناة الاتصال المتاحة خلال المكالمة." + +#: ../gtk/parameters.ui.h:53 +msgid "Bandwidth control" +msgstr "إدارة سعة القناة" + +#: ../gtk/parameters.ui.h:54 +msgid "Multimedia settings" +msgstr "إعدادات الوسائط المتعددة" + +#: ../gtk/parameters.ui.h:55 +msgid "Set Maximum Transmission Unit:" +msgstr "حدِّد Maximum Transmission Unit :" + +#: ../gtk/parameters.ui.h:56 +msgid "Send DTMFs as SIP info" +msgstr "أرسِل الأرقام الهاتفية على هيئة SIP INFO" + +#: ../gtk/parameters.ui.h:57 +msgid "Allow IPv6" +msgstr "السماح باستخدام IPv6" + +#: ../gtk/parameters.ui.h:58 +msgid "Transport" +msgstr "النقل" + +#: ../gtk/parameters.ui.h:59 +msgid "SIP/UDP port" +msgstr "منفذ SIP/UDP" + +#: ../gtk/parameters.ui.h:61 +msgid "Random" +msgstr "عشوائي" + +#: ../gtk/parameters.ui.h:62 +msgid "SIP/TCP port" +msgstr "منفذ SIP/TCP" + +#: ../gtk/parameters.ui.h:63 +msgid "Audio RTP/UDP:" +msgstr "صوت RTP/UDP :" + +#: ../gtk/parameters.ui.h:64 +msgid "Fixed" +msgstr "ثابت" + +#: ../gtk/parameters.ui.h:65 +msgid "Video RTP/UDP:" +msgstr "فيديو RTP/UDP :" + +#: ../gtk/parameters.ui.h:66 +msgid "Media encryption type" +msgstr "نوع وسيط التعمية" + +#: ../gtk/parameters.ui.h:67 +msgid "Media encryption is mandatory" +msgstr "وسيط التعمية إجباري" + +#: ../gtk/parameters.ui.h:68 +msgid "Tunnel" +msgstr "النفق" + +#: ../gtk/parameters.ui.h:69 +msgid "DSCP fields" +msgstr "حقول DSCP" + +#: ../gtk/parameters.ui.h:70 +msgid "Network protocol and ports" +msgstr "بروتوكول الشبكة والمنافذ" + +#: ../gtk/parameters.ui.h:71 +msgid "Direct connection to the Internet" +msgstr "الاتصال مباشر بالإنترنت" + +#: ../gtk/parameters.ui.h:72 +msgid "Behind NAT / Firewall (specify gateway IP )" +msgstr "وراء جدار ناري (حدِّد عنوان IP البوابة)" + +#: ../gtk/parameters.ui.h:73 +msgid "Behind NAT / Firewall (use STUN to resolve)" +msgstr "وراء جدار ناري (استخدم STUN)" + +#: ../gtk/parameters.ui.h:74 +msgid "Behind NAT / Firewall (use ICE)" +msgstr "وراء جدار ناري (استخدم ICE)" + +#: ../gtk/parameters.ui.h:75 +msgid "Behind NAT / Firewall (use uPnP)" +msgstr "وراء جدار ناري (استخدم uPnP)" + +#: ../gtk/parameters.ui.h:76 +msgid "Public IP address:" +msgstr "عنوان IP العمومي :" + +#: ../gtk/parameters.ui.h:77 +msgid "Stun server:" +msgstr "خادم STUN :" + +#: ../gtk/parameters.ui.h:78 +msgid "NAT and Firewall" +msgstr "إعدادات حول الجدار الناري" + +#: ../gtk/parameters.ui.h:79 +msgid "Network settings" +msgstr "إعدادات الشبكة" + +#: ../gtk/parameters.ui.h:80 ../gtk/tunnel_config.ui.h:4 +msgid "Enable" +msgstr "فعِّل" + +#: ../gtk/parameters.ui.h:81 ../gtk/tunnel_config.ui.h:5 +msgid "Disable" +msgstr "إلغاء التفعيل" + +#: ../gtk/parameters.ui.h:82 +msgid "Audio codecs" +msgstr "مرمازات الصوت" + +#: ../gtk/parameters.ui.h:83 +msgid "Video codecs" +msgstr "مرمازات الفيديو" + +#: ../gtk/parameters.ui.h:84 +msgid "Codecs" +msgstr "المراميز" + +#: ../gtk/parameters.ui.h:85 +msgid "Language" +msgstr "اللغة" + +#: ../gtk/parameters.ui.h:86 +msgid "Show advanced settings" +msgstr "أظهر الإعدادات المتقدمة" + +#: ../gtk/parameters.ui.h:87 +msgid "Level" +msgstr "المستوى" + +#: ../gtk/parameters.ui.h:88 +msgid "User interface" +msgstr "واجهة المستخدم" + +#: ../gtk/parameters.ui.h:92 +msgid "LDAP Account setup" +msgstr "تهيئة LDAP" + +#: ../gtk/parameters.ui.h:93 +msgid "LDAP" +msgstr "LDAP" + +#: ../gtk/parameters.ui.h:94 +msgid "Done" +msgstr "أغلق" + +#: ../gtk/password.ui.h:1 +msgid "Linphone - Authentication required" +msgstr "لِنْفُونْ - يجب التحقق من الهوية" + +#: ../gtk/password.ui.h:2 +msgid "Please enter the domain password" +msgstr "أدخل كلمة سر النطاق" #: ../gtk/provisioning-fetch.ui.h:1 msgid "Configuring..." @@ -1712,68 +1566,278 @@ msgstr "تجري التهيئة..." msgid "Please wait while fetching configuration from server..." msgstr "رجاءً انتظر ريثما ينتهي من جلب الإعدادات من الخادم..." -#: ../coreapi/linphonecore.c:1539 +#: ../gtk/setup_wizard.ui.h:1 +msgid "SIP account configuration assistant" +msgstr "مرشد تهيئة حساب SIP" + +#: ../gtk/setup_wizard.ui.h:2 +msgid "" +"Welcome!\n" +"This assistant will help you to use a SIP account for your calls." +msgstr "مرحبا !\nسيمكنك هذا المرشد من إعداد حسابك SIP لإجراء المكالمات." + +#: ../gtk/setup_wizard.ui.h:4 +msgid "Welcome to the account setup assistant" +msgstr "مرحبا بك في مرشد إعداد الحساب" + +#: ../gtk/setup_wizard.ui.h:5 +msgid "Create an account on linphone.org" +msgstr "إنشاء حساب في linphone.org" + +#: ../gtk/setup_wizard.ui.h:6 +msgid "I have already a linphone.org account and I just want to use it" +msgstr "أتوفر مسبقا على حساب في linphone.org وأريد فقط استخدامه" + +#: ../gtk/setup_wizard.ui.h:7 +msgid "I have already a sip account and I just want to use it" +msgstr "أتوفر مسبقا على حساب sip وأريد فقط استخدامه" + +#: ../gtk/setup_wizard.ui.h:8 +msgid "I want to specify a remote configuration URI" +msgstr "أريد تحديد عنوان التهيئة عن بعد" + +#: ../gtk/setup_wizard.ui.h:9 +msgid "Account setup assistant" +msgstr "مرشد تهيئة الحساب" + +#: ../gtk/setup_wizard.ui.h:10 +msgid "Enter your account information" +msgstr "ادخل معلومات حسابك" + +#: ../gtk/setup_wizard.ui.h:11 +msgid "Username*" +msgstr "اسم المستخدم*" + +#: ../gtk/setup_wizard.ui.h:12 +msgid "Password*" +msgstr "كلمة السر*" + +#: ../gtk/setup_wizard.ui.h:13 +msgid "Domain*" +msgstr "النطاق*" + +#: ../gtk/setup_wizard.ui.h:14 +msgid "Proxy" +msgstr "الوكيل" + +#: ../gtk/setup_wizard.ui.h:15 +msgid "Configure your account (step 1/1)" +msgstr "تهيئة حسابك (المرحلة 1/1)" + +#: ../gtk/setup_wizard.ui.h:16 +msgid "Enter your linphone.org username" +msgstr "أدخِل اسم المستخدم في linphone.org" + +#: ../gtk/setup_wizard.ui.h:19 +msgid "Enter your sip username (step 1/1)" +msgstr "أدخل اسم المستخدم SIP (المرحلة 1/1)" + +#: ../gtk/setup_wizard.ui.h:20 +msgid "(*) Required fields" +msgstr "(*) حقول ضرورية" + +#: ../gtk/setup_wizard.ui.h:21 +msgid "Email: (*)" +msgstr "البريد الالكتروني : (*)" + +#: ../gtk/setup_wizard.ui.h:22 +msgid "Username: (*)" +msgstr "اسم المستخدم* : (*)" + +#: ../gtk/setup_wizard.ui.h:23 +msgid "Password: (*)" +msgstr "كلمة السر* : (*)" + +#: ../gtk/setup_wizard.ui.h:24 +msgid "Confirm your password: (*)" +msgstr "أكِّد كلمة السر : (*)" + +#: ../gtk/setup_wizard.ui.h:25 +msgid "Keep me informed with linphone updates" +msgstr "أحطني علما بتحديثات لِنْفُونْ" + +#: ../gtk/setup_wizard.ui.h:26 +msgid "Enter account information (step 1/2)" +msgstr "أدخل معلومات حسابك (المرحلة 1/2)" + +#: ../gtk/setup_wizard.ui.h:27 +msgid "Your account is being created, please wait." +msgstr "يُرجى الانتظار، يجري الآن إنشاء حسابك." + +#: ../gtk/setup_wizard.ui.h:28 +msgid "Account creation in progress" +msgstr "إنشاء الحساب في تقدم" + +#: ../gtk/setup_wizard.ui.h:29 +msgid "" +"Please validate your account by clicking on the link we just sent you by email.\n" +"Then come back here and press Next button." +msgstr "يُرجى تأكيد حسابك وذلك بالضغط على الوصلة التي أرسلناها لك بالبريد الإلكتروني.\nثم ارجع إلى هنا واضغط على زر التالي." + +#: ../gtk/setup_wizard.ui.h:31 +msgid "Validation (step 2/2)" +msgstr "تأكيد (المرحلة 2/2)" + +#: ../gtk/setup_wizard.ui.h:32 +msgid "Checking if your account is been validated, please wait." +msgstr "يُرجى الانتظار، يجري الآن فحص التحقق من صحة حسابك." + +#: ../gtk/setup_wizard.ui.h:33 +msgid "Account validation check in progress" +msgstr "التحقق من الحساب في تقدم" + +#: ../gtk/setup_wizard.ui.h:34 +msgid "" +"Error, account not validated, username already used or server unreachable.\n" +"Please go back and try again." +msgstr "خطأ، لم يتم تأكيد الحساب، سبق استخدام اسم المستخدم أو تعذر الوصول للخادم.\nيُرجى إعادة المحاولة لاحقا." + +#: ../gtk/setup_wizard.ui.h:36 +msgid "Error" +msgstr "خطأ" + +#: ../gtk/setup_wizard.ui.h:37 +msgid "Thank you. Your account is now configured and ready for use." +msgstr "شكرا لك، لقد جرت تهيئة حسابك وهو الآن قابل للاستخدام." + +#: ../gtk/sip_account.ui.h:1 +msgid "Linphone - Configure a SIP account" +msgstr "لِنْفُونْ - تهيئة حساب SIP" + +#: ../gtk/sip_account.ui.h:2 +msgid "Your SIP identity:" +msgstr "هوية SIP لديك :" + +#: ../gtk/sip_account.ui.h:3 +msgid "Looks like sip:@" +msgstr "يشبه sip:@" + +#: ../gtk/sip_account.ui.h:4 +msgid "sip:" +msgstr "sip:" + +#: ../gtk/sip_account.ui.h:5 +msgid "SIP Proxy address:" +msgstr "عنوان وكيل SIP :" + +#: ../gtk/sip_account.ui.h:6 +msgid "Looks like sip:" +msgstr "يشبه sip:" + +#: ../gtk/sip_account.ui.h:7 +msgid "Registration duration (sec):" +msgstr "مدة التسجيل (بالثواني) :" + +#: ../gtk/sip_account.ui.h:8 +msgid "Contact params (optional):" +msgstr "إعدادات جهة الاتصال (اختيارية) :" + +#: ../gtk/sip_account.ui.h:9 +msgid "AVPF regular RTCP interval (sec):" +msgstr "مجال RTCP الاعتيادي ل AVPF (بالثواني) :" + +#: ../gtk/sip_account.ui.h:10 +msgid "Route (optional):" +msgstr "التوجيه (اختياري) :" + +#: ../gtk/sip_account.ui.h:11 +msgid "Transport" +msgstr "النقل" + +#: ../gtk/sip_account.ui.h:12 +msgid "Register" +msgstr "التسجيل" + +#: ../gtk/sip_account.ui.h:13 +msgid "Publish presence information" +msgstr "انشر معلومات الحضور" + +#: ../gtk/sip_account.ui.h:14 +msgid "Enable AVPF" +msgstr "فعِّل AVPF " + +#: ../gtk/sip_account.ui.h:15 +msgid "Configure a SIP account" +msgstr "تهيئة حساب SIP" + +#: ../gtk/tunnel_config.ui.h:1 +msgid "Configure VoIP tunnel" +msgstr "تهيئة نفق VoIP" + +#: ../gtk/tunnel_config.ui.h:2 +msgid "Host" +msgstr "المضيف" + +#: ../gtk/tunnel_config.ui.h:3 +msgid "Port" +msgstr "المنفذ" + +#: ../gtk/tunnel_config.ui.h:6 +msgid "Configure tunnel" +msgstr "تهيئة النفق" + +#: ../gtk/tunnel_config.ui.h:9 +msgid "Configure http proxy (optional)" +msgstr "تهيئة وكيل http (اختياري)" + +#: ../gtk/waiting.ui.h:2 +msgid "Please wait" +msgstr "يُرجى الانتظار" + +#: ../coreapi/linphonecore.c:1560 msgid "Ready" msgstr "جاهز" -#: ../coreapi/linphonecore.c:2551 +#: ../coreapi/linphonecore.c:2556 msgid "Configuring" msgstr "تجري التهيئة" -#: ../coreapi/linphonecore.c:2725 -msgid "Looking for telephone number destination..." -msgstr "يجري البحث عن وجهة رقم الهاتف..." - -#: ../coreapi/linphonecore.c:2727 -msgid "Could not resolve this number." -msgstr "لم يتمكن من إيجاد هذا الرقم." - #. must be known at that time -#: ../coreapi/linphonecore.c:3013 +#: ../coreapi/linphonecore.c:2951 msgid "Contacting" msgstr "يتصل ب" -#: ../coreapi/linphonecore.c:3018 +#: ../coreapi/linphonecore.c:2956 msgid "Could not call" msgstr "لم يتمكن من الاتصال" -#: ../coreapi/linphonecore.c:3169 +#: ../coreapi/linphonecore.c:3092 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "آسف، وصل عدد المكالمات الآنية إلى حده الأقصى" -#: ../coreapi/linphonecore.c:3327 +#: ../coreapi/linphonecore.c:3250 msgid "is contacting you" msgstr "يتصل بك" -#: ../coreapi/linphonecore.c:3328 +#: ../coreapi/linphonecore.c:3251 msgid " and asked autoanswer." msgstr "ويطلب ردا تلقائيا." -#: ../coreapi/linphonecore.c:3452 +#: ../coreapi/linphonecore.c:3377 msgid "Modifying call parameters..." msgstr "يجري تعديل إعدادات المكالمة..." -#: ../coreapi/linphonecore.c:3802 +#: ../coreapi/linphonecore.c:3769 msgid "Connected." msgstr "متصل." -#: ../coreapi/linphonecore.c:3827 +#: ../coreapi/linphonecore.c:3794 msgid "Call aborted" msgstr "أُلغيت المكالمة" -#: ../coreapi/linphonecore.c:4024 +#: ../coreapi/linphonecore.c:3983 msgid "Could not pause the call" msgstr "لم يتمكن من توقيف المكالمة مؤقتا" -#: ../coreapi/linphonecore.c:4027 +#: ../coreapi/linphonecore.c:3986 msgid "Pausing the current call..." msgstr "وضع المكالمة قيد الانتظار..." -#: ../coreapi/misc.c:434 +#: ../coreapi/misc.c:440 msgid "Stun lookup in progress..." msgstr "يجري بحث STUN..." -#: ../coreapi/misc.c:615 +#: ../coreapi/misc.c:650 msgid "ICE local candidates gathering in progress..." msgstr "يجري جلب مرشَّحي ICE المحلين..." @@ -1829,143 +1893,150 @@ msgstr "في عطلة" msgid "Unknown status" msgstr "حالة مجهولة" -#: ../coreapi/proxy.c:328 +#: ../coreapi/proxy.c:292 msgid "" "The sip proxy address you entered is invalid, it must start with \"sip:\" " "followed by a hostname." msgstr "إن عنوان SIP الذي أدخلت غير صحيح، يجب أن يبدأ بـ \"sip:‎\" متبوعا باسم المضيف." -#: ../coreapi/proxy.c:334 +#: ../coreapi/proxy.c:298 msgid "" "The sip identity you entered is invalid.\n" "It should look like sip:username@proxydomain, such as sip:alice@example.net" msgstr "إن هوية SIP التي أدخلت غير صحيحة.\nيجب أن تكون بهذا النمط sip:username@proxydomain، مثلا sip:alice@example.net" -#: ../coreapi/proxy.c:1416 +#: ../coreapi/proxy.c:927 +msgid "Looking for telephone number destination..." +msgstr "يجري البحث عن وجهة رقم الهاتف..." + +#: ../coreapi/proxy.c:931 +msgid "Could not resolve this number." +msgstr "لم يتمكن من إيجاد هذا الرقم." + +#: ../coreapi/proxy.c:1324 #, c-format msgid "Could not login as %s" msgstr "تعذر الولوج بالهوية %s" -#: ../coreapi/callbacks.c:428 +#: ../coreapi/proxy.c:1411 +#, c-format +msgid "Refreshing on %s..." +msgstr "‫يجري إنعاش في %s...‬" + +#: ../coreapi/callbacks.c:423 msgid "Remote ringing." msgstr "يرن الجرس عن بعد..." -#: ../coreapi/callbacks.c:440 +#: ../coreapi/callbacks.c:435 msgid "Remote ringing..." msgstr "يرن الجرس عن بعد..." -#: ../coreapi/callbacks.c:461 +#: ../coreapi/callbacks.c:458 msgid "Early media." msgstr "أخذ المكالمة مبكرا." -#: ../coreapi/callbacks.c:534 +#: ../coreapi/callbacks.c:488 #, c-format -msgid "Call with %s is paused." -msgstr "المكاملة مع %s متوقفة." +msgid "Call answered by %s" +msgstr "‫أجاب عن المكالمة %s‬" -#: ../coreapi/callbacks.c:547 -#, c-format -msgid "Call answered by %s - on hold." -msgstr "يجيب %s عن المكالمة - في وضع الانتظار." - -#: ../coreapi/callbacks.c:557 +#: ../coreapi/callbacks.c:527 msgid "Call resumed." msgstr "استُعيدت المكالمة." -#: ../coreapi/callbacks.c:561 -#, c-format -msgid "Call answered by %s." -msgstr "أجاب عن المكالمة %s." - -#: ../coreapi/callbacks.c:584 +#: ../coreapi/callbacks.c:582 msgid "Incompatible, check codecs or security settings..." msgstr "غير موائم، تحقق من المراميز أو إعدادات الأمان..." -#: ../coreapi/callbacks.c:589 ../coreapi/callbacks.c:906 +#: ../coreapi/callbacks.c:587 ../coreapi/callbacks.c:923 msgid "Incompatible media parameters." msgstr "إعدادات الوسائط غير موائمة." -#: ../coreapi/callbacks.c:619 +#: ../coreapi/callbacks.c:612 msgid "We have been resumed." msgstr "استُأنِفت المكالمة." #. we are being paused -#: ../coreapi/callbacks.c:628 +#: ../coreapi/callbacks.c:620 msgid "We are paused by other party." msgstr "وُقِّفت المكالمة مؤقتا من طرف آخر." -#. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:666 +#: ../coreapi/callbacks.c:630 msgid "Call is updated by remote." msgstr "حُدِّث الاتصال من البعيد." -#: ../coreapi/callbacks.c:782 +#: ../coreapi/callbacks.c:799 msgid "Call terminated." msgstr "أُنهيت المكالمة." -#: ../coreapi/callbacks.c:810 +#: ../coreapi/callbacks.c:827 msgid "User is busy." msgstr "المستخدم مشغول." -#: ../coreapi/callbacks.c:811 +#: ../coreapi/callbacks.c:828 msgid "User is temporarily unavailable." msgstr "المستخدم غير متاح مؤقتا." #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:813 +#: ../coreapi/callbacks.c:830 msgid "User does not want to be disturbed." msgstr "لا يريد المستخدم أي إزعاج." -#: ../coreapi/callbacks.c:814 +#: ../coreapi/callbacks.c:831 msgid "Call declined." msgstr "تم تجاهل المكالمة." -#: ../coreapi/callbacks.c:829 +#: ../coreapi/callbacks.c:846 msgid "Request timeout." msgstr "انتهت مهلة الطلب." -#: ../coreapi/callbacks.c:860 +#: ../coreapi/callbacks.c:877 msgid "Redirected" msgstr "مُوجَّه" -#: ../coreapi/callbacks.c:915 +#: ../coreapi/callbacks.c:927 msgid "Call failed." msgstr "فشل الاتصال." -#: ../coreapi/callbacks.c:993 +#: ../coreapi/callbacks.c:1005 #, c-format msgid "Registration on %s successful." msgstr "تم التسجيل في %s بنجاح." -#: ../coreapi/callbacks.c:994 +#: ../coreapi/callbacks.c:1006 #, c-format msgid "Unregistration on %s done." msgstr "أُلغي التسجيل في %s ." -#: ../coreapi/callbacks.c:1012 +#: ../coreapi/callbacks.c:1024 msgid "no response timeout" msgstr "لا إجابة قبل انتهاء المهلة" -#: ../coreapi/callbacks.c:1015 +#: ../coreapi/callbacks.c:1027 #, c-format msgid "Registration on %s failed: %s" msgstr "فَشِل التسجيل في %s: %s" -#: ../coreapi/callbacks.c:1022 +#: ../coreapi/callbacks.c:1034 msgid "Service unavailable, retrying" msgstr "خدمة غير متاحة، تجري الإعادة" #. if encryption is DTLS, no status to be displayed -#: ../coreapi/linphonecall.c:180 +#: ../coreapi/linphonecall.c:197 #, c-format msgid "Authentication token is %s" msgstr "شارة التحقق من الهوية هي %s" -#: ../coreapi/linphonecall.c:1310 +#: ../coreapi/linphonecall.c:1561 +#, c-format +msgid "Call parameters could not be modified: %s." +msgstr "‫لم تُعدَّل معاملات المكالمات : %s.‬" + +#: ../coreapi/linphonecall.c:1563 msgid "Call parameters were successfully modified." msgstr "عُدِّلت معاملات المكالمات بنجاج." -#: ../coreapi/linphonecall.c:3686 +#: ../coreapi/linphonecall.c:4396 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." @@ -1976,23 +2047,23 @@ msgstr[3] "فاتتك %i مكالمات." msgstr[4] "فاتتك %i مكالمة." msgstr[5] "فاتتك %i مكالمة." -#: ../coreapi/call_log.c:209 +#: ../coreapi/call_log.c:223 msgid "aborted" msgstr "أُجهِضت" -#: ../coreapi/call_log.c:212 +#: ../coreapi/call_log.c:226 msgid "completed" msgstr "اكتملت" -#: ../coreapi/call_log.c:215 +#: ../coreapi/call_log.c:229 msgid "missed" msgstr "فاتت" -#: ../coreapi/call_log.c:218 +#: ../coreapi/call_log.c:232 msgid "unknown" msgstr "مجهول" -#: ../coreapi/call_log.c:220 +#: ../coreapi/call_log.c:234 #, c-format msgid "" "%s at %s\n" @@ -2002,7 +2073,7 @@ msgid "" "Duration: %i mn %i sec\n" msgstr "%s في %s\nمن : %s\nإلى : %s\nالحالة : %s\nالمدة : %i دقيقة %i ثانية\n" -#: ../coreapi/call_log.c:221 +#: ../coreapi/call_log.c:235 msgid "Outgoing call" msgstr "المكالمة الصادرة" diff --git a/po/cs.po b/po/cs.po index cdb192696..80e442b8b 100644 --- a/po/cs.po +++ b/po/cs.po @@ -9,48 +9,57 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-04-30 10:13+0200\n" -"PO-Revision-Date: 2015-04-30 08:13+0000\n" +"POT-Creation-Date: 2015-11-10 15:16+0100\n" +"PO-Revision-Date: 2015-11-10 14:16+0000\n" "Last-Translator: Belledonne Communications \n" -"Language-Team: Czech (http://www.transifex.com/projects/p/linphone-gtk/language/cs/)\n" +"Language-Team: Czech (http://www.transifex.com/belledonne-communications/linphone-gtk/language/cs/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: cs\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -#: ../gtk/calllogs.c:148 ../gtk/friendlist.c:974 +#: ../gtk/calllogs.c:178 #, c-format msgid "Call %s" msgstr "Volat komu: %s" -#: ../gtk/calllogs.c:149 ../gtk/friendlist.c:975 +#: ../gtk/calllogs.c:179 #, c-format msgid "Send text to %s" msgstr "Poslat text komu: %s" -#: ../gtk/calllogs.c:232 +#: ../gtk/calllogs.c:181 +#, c-format +msgid "Add %s to your contact list" +msgstr "" + +#: ../gtk/calllogs.c:245 ../gtk/main.ui.h:21 +msgid "Recent calls" +msgstr "Nedávné hovory" + +#: ../gtk/calllogs.c:260 #, c-format msgid "Recent calls (%i)" msgstr "Nedávné hovory (%i)" -#: ../gtk/calllogs.c:314 +#: ../gtk/calllogs.c:331 msgid "n/a" msgstr "–" -#: ../gtk/calllogs.c:317 +#: ../gtk/calllogs.c:334 msgid "Aborted" msgstr "Přerušen" -#: ../gtk/calllogs.c:320 +#: ../gtk/calllogs.c:337 msgid "Missed" msgstr "Zmeškán" -#: ../gtk/calllogs.c:323 +#: ../gtk/calllogs.c:340 msgid "Declined" msgstr "Odmítnut" -#: ../gtk/calllogs.c:329 +#: ../gtk/calllogs.c:346 #, c-format msgid "%i minute" msgid_plural "%i minutes" @@ -58,7 +67,7 @@ msgstr[0] "%i minuta" msgstr[1] "%i minuty" msgstr[2] "%i minut" -#: ../gtk/calllogs.c:332 +#: ../gtk/calllogs.c:349 #, c-format msgid "%i second" msgid_plural "%i seconds" @@ -66,19 +75,19 @@ msgstr[0] "%i sekunda" msgstr[1] "%i sekundy" msgstr[2] "%i sekund" -#: ../gtk/calllogs.c:337 +#: ../gtk/calllogs.c:354 #, c-format msgid "" "%s\tQuality: %s\n" "%s\t%s\t" msgstr "%s\tKvalita: %s\n%s\t%s\t" -#: ../gtk/calllogs.c:341 +#: ../gtk/calllogs.c:358 #, c-format msgid "%s\t%s" msgstr "%s\t%s" -#: ../gtk/conference.c:38 ../gtk/main.ui.h:13 +#: ../gtk/conference.c:38 ../gtk/in_call_frame.ui.h:11 msgid "Conference" msgstr "Konference" @@ -91,297 +100,314 @@ msgstr "Já" msgid "Couldn't find pixmap file: %s" msgstr "Nelze najít soubor s obrázkem: %s" -#: ../gtk/main.c:137 +#: ../gtk/chat.c:196 ../gtk/chat.c:254 +msgid "Sending..." +msgstr "" + +#: ../gtk/chat.c:213 ../gtk/chat.c:263 +msgid "Message not sent" +msgstr "" + +#: ../gtk/chat.c:472 +msgid "Copy" +msgstr "" + +#: ../gtk/main.c:138 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:138 +#: ../gtk/main.c:139 +msgid "display version and exit." +msgstr "" + +#: ../gtk/main.c:140 msgid "path to a file to write logs into." msgstr "Soubor, kam zapisovat protokol." -#: ../gtk/main.c:139 +#: ../gtk/main.c:141 msgid "Start linphone with video disabled." msgstr "Spustí linphone se zakázaným obrazem." -#: ../gtk/main.c:140 +#: ../gtk/main.c:142 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:141 +#: ../gtk/main.c:143 msgid "address to call right now" msgstr "Zavolá právě teď na tuto adresu" -#: ../gtk/main.c:142 +#: ../gtk/main.c:144 msgid "" "Specifiy a working directory (should be the base of the installation, eg: " "c:\\Program Files\\Linphone)" msgstr "Zadejte pracovní adresář (měl by být základní instalační adresář, například c:\\Program Files\\Linphone)" -#: ../gtk/main.c:143 +#: ../gtk/main.c:145 msgid "Configuration file" msgstr "" -#: ../gtk/main.c:144 +#: ../gtk/main.c:146 msgid "Run the audio assistant" msgstr "" -#: ../gtk/main.c:145 +#: ../gtk/main.c:147 msgid "Run self test and exit 0 if succeed" msgstr "" -#: ../gtk/main.c:1070 +#: ../gtk/main.c:1046 #, c-format msgid "" -"%s would like to add you to his contact list.\n" -"Would you allow him to see your presence status or add him to your contact list ?\n" +"%s would like to add you to his/her contact list.\n" +"Would you add him/her to your contact list and allow him/her to see your presence status?\n" "If you answer no, this person will be temporarily blacklisted." -msgstr "%s si vás chce přidat do svého adresáře.\nDovolíte mu, aby viděl váš stav přítomnosti, nebo si ho také chcete přidat do svého adresáře?\nOdpovíte-li ne, tato osobo bude dočasně blokována." +msgstr "" -#: ../gtk/main.c:1147 +#: ../gtk/main.c:1123 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" msgstr "" -#: ../gtk/main.c:1268 +#: ../gtk/main.c:1253 msgid "Call error" msgstr "Chyba hovoru" -#: ../gtk/main.c:1271 ../coreapi/linphonecore.c:3846 +#: ../gtk/main.c:1256 ../coreapi/linphonecore.c:3813 msgid "Call ended" msgstr "Hovor ukončen" -#: ../gtk/main.c:1274 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1259 ../coreapi/call_log.c:235 msgid "Incoming call" msgstr "Příchozí hovor" -#: ../gtk/main.c:1276 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1261 ../gtk/incall_view.c:580 ../gtk/in_call_frame.ui.h:2 msgid "Answer" msgstr "Odpovědět" -#: ../gtk/main.c:1278 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1263 ../gtk/in_call_frame.ui.h:3 msgid "Decline" msgstr "Odmítnout" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 msgid "Call paused" msgstr "Hovor odložen" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 #, c-format msgid "by %s" msgstr "kým: %s" -#: ../gtk/main.c:1354 +#: ../gtk/main.c:1339 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "%s navrhuje začít videohovor. Přijímáte?" -#: ../gtk/main.c:1509 +#: ../gtk/main.c:1505 msgid "Website link" msgstr "Odkaz na webovou stránku" -#: ../gtk/main.c:1568 ../gtk/waiting.ui.h:1 +#: ../gtk/main.c:1564 ../gtk/waiting.ui.h:1 msgid "Linphone" msgstr "Linphone" -#: ../gtk/main.c:1569 +#: ../gtk/main.c:1565 msgid "A video internet phone" msgstr "" -#: ../gtk/main.c:1629 +#: ../gtk/main.c:1624 #, c-format msgid "%s (Default)" msgstr "%s (Výchozí)" -#: ../gtk/main.c:1962 ../coreapi/callbacks.c:1063 +#: ../gtk/main.c:1960 ../coreapi/callbacks.c:1075 #, c-format msgid "We are transferred to %s" msgstr "Byly jsme přepojeni na %s" -#: ../gtk/main.c:1972 +#: ../gtk/main.c:1970 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." msgstr "Na tomto počítači nebyla objevena žádná zvuková karta.\nNebudete moci vytáčet a přijímat a zvukové hovory." -#: ../gtk/main.c:2117 +#: ../gtk/main.c:2129 msgid "A free SIP video-phone" msgstr "Volný SIP videofon" -#: ../gtk/main.c:2221 +#: ../gtk/main.c:2242 #, c-format msgid "Hello\n" msgstr "" -#: ../gtk/friendlist.c:505 +#: ../gtk/friendlist.c:461 msgid "Add to addressbook" msgstr "Přidat do adresáře" -#: ../gtk/friendlist.c:691 -msgid "Presence status" -msgstr "Stav" - -#: ../gtk/friendlist.c:709 ../gtk/propertybox.c:569 ../gtk/contact.ui.h:1 -msgid "Name" -msgstr "Jméno" - -#: ../gtk/friendlist.c:721 -msgid "Call" -msgstr "Zavolat" - -#: ../gtk/friendlist.c:726 -msgid "Chat" -msgstr "Diskuze" - -#: ../gtk/friendlist.c:756 +#: ../gtk/friendlist.c:627 #, c-format msgid "Search in %s directory" msgstr "Hledat v adresáři %s" -#: ../gtk/friendlist.c:924 +#: ../gtk/friendlist.c:772 msgid "Invalid sip contact !" msgstr "Neplatný sipový kontakt!" -#: ../gtk/friendlist.c:976 +#: ../gtk/friendlist.c:820 +#, c-format +msgid "Add a new contact" +msgstr "" + +#: ../gtk/friendlist.c:823 #, c-format msgid "Edit contact '%s'" msgstr "Upravit kontakt „%s“" -#: ../gtk/friendlist.c:977 +#: ../gtk/friendlist.c:824 #, c-format msgid "Delete contact '%s'" msgstr "Odstranit kontakt „%s“" -#: ../gtk/friendlist.c:978 +#: ../gtk/friendlist.c:825 #, c-format msgid "Delete chat history of '%s'" msgstr "Odstranit historii diskuze u kontaktu „%s“" -#: ../gtk/friendlist.c:1029 +#: ../gtk/friendlist.c:862 #, c-format msgid "Add new contact from %s directory" msgstr "Přidat nový kontakt z adresáře %s" -#: ../gtk/propertybox.c:575 +#: ../gtk/propertybox.c:592 ../gtk/contact.ui.h:1 +msgid "Name" +msgstr "Jméno" + +#: ../gtk/propertybox.c:598 msgid "Rate (Hz)" msgstr "Kmitočet (Hz)" -#: ../gtk/propertybox.c:581 +#: ../gtk/propertybox.c:604 msgid "Status" msgstr "Stav" -#: ../gtk/propertybox.c:587 +#: ../gtk/propertybox.c:617 msgid "IP Bitrate (kbit/s)" msgstr "" -#: ../gtk/propertybox.c:596 +#: ../gtk/propertybox.c:628 msgid "Parameters" msgstr "Parametry" -#: ../gtk/propertybox.c:639 ../gtk/propertybox.c:782 +#: ../gtk/propertybox.c:670 ../gtk/propertybox.c:824 msgid "Enabled" msgstr "Povoleno" -#: ../gtk/propertybox.c:641 ../gtk/propertybox.c:782 ../gtk/parameters.ui.h:20 +#: ../gtk/propertybox.c:672 ../gtk/propertybox.c:824 ../gtk/parameters.ui.h:60 msgid "Disabled" msgstr "Zakázáno" -#: ../gtk/propertybox.c:828 +#: ../gtk/propertybox.c:902 msgid "Account" msgstr "Účet" -#: ../gtk/propertybox.c:1091 +#: ../gtk/propertybox.c:1170 msgid "English" msgstr "angličtina" -#: ../gtk/propertybox.c:1092 +#: ../gtk/propertybox.c:1171 msgid "French" msgstr "francouzština" -#: ../gtk/propertybox.c:1093 +#: ../gtk/propertybox.c:1172 msgid "Swedish" msgstr "švédština" -#: ../gtk/propertybox.c:1094 +#: ../gtk/propertybox.c:1173 msgid "Italian" msgstr "italština" -#: ../gtk/propertybox.c:1095 +#: ../gtk/propertybox.c:1174 msgid "Spanish" msgstr "španělština" -#: ../gtk/propertybox.c:1096 +#: ../gtk/propertybox.c:1175 msgid "Brazilian Portugese" msgstr "brazilská portugalština" -#: ../gtk/propertybox.c:1097 +#: ../gtk/propertybox.c:1176 msgid "Polish" msgstr "polština" -#: ../gtk/propertybox.c:1098 +#: ../gtk/propertybox.c:1177 msgid "German" msgstr "němčina" -#: ../gtk/propertybox.c:1099 +#: ../gtk/propertybox.c:1178 msgid "Russian" msgstr "ruština" -#: ../gtk/propertybox.c:1100 +#: ../gtk/propertybox.c:1179 msgid "Japanese" msgstr "japonština" -#: ../gtk/propertybox.c:1101 +#: ../gtk/propertybox.c:1180 msgid "Dutch" msgstr "dánština" -#: ../gtk/propertybox.c:1102 +#: ../gtk/propertybox.c:1181 msgid "Hungarian" msgstr "maďarština" -#: ../gtk/propertybox.c:1103 +#: ../gtk/propertybox.c:1182 msgid "Czech" msgstr "čeština" -#: ../gtk/propertybox.c:1104 +#: ../gtk/propertybox.c:1183 msgid "Chinese" msgstr "čínština" -#: ../gtk/propertybox.c:1105 +#: ../gtk/propertybox.c:1184 msgid "Traditional Chinese" msgstr "tradiční čínština" -#: ../gtk/propertybox.c:1106 +#: ../gtk/propertybox.c:1185 msgid "Norwegian" msgstr "norština" -#: ../gtk/propertybox.c:1107 +#: ../gtk/propertybox.c:1186 msgid "Hebrew" msgstr "hebrejština" -#: ../gtk/propertybox.c:1108 +#: ../gtk/propertybox.c:1187 msgid "Serbian" msgstr "srbština" -#: ../gtk/propertybox.c:1175 +#: ../gtk/propertybox.c:1188 +msgid "Arabic" +msgstr "" + +#: ../gtk/propertybox.c:1189 +msgid "Turkish" +msgstr "" + +#: ../gtk/propertybox.c:1246 msgid "" "You need to restart linphone for the new language selection to take effect." msgstr "Aby se projevil výběr nového jazyka, je nutné znovu spustit linphone." -#: ../gtk/propertybox.c:1255 +#: ../gtk/propertybox.c:1326 msgid "None" msgstr "Žádné" -#: ../gtk/propertybox.c:1259 +#: ../gtk/propertybox.c:1330 msgid "SRTP" msgstr "SRTP" -#: ../gtk/propertybox.c:1265 +#: ../gtk/propertybox.c:1336 msgid "DTLS" msgstr "" -#: ../gtk/propertybox.c:1272 +#: ../gtk/propertybox.c:1343 msgid "ZRTP" msgstr "ZRTP" @@ -424,324 +450,195 @@ msgstr[0] "Nalezen %i kontakt" msgstr[1] "Nalezeny %i kontakty" msgstr[2] "Nalezeno %i kontaktů" -#: ../gtk/setupwizard.c:32 -msgid "" -"Welcome!\n" -"This assistant will help you to use a SIP account for your calls." -msgstr "" - -#: ../gtk/setupwizard.c:41 -msgid "Create an account on linphone.org" -msgstr "Vytvořit účet na linphone.org" - -#: ../gtk/setupwizard.c:42 -msgid "I have already a linphone.org account and I just want to use it" -msgstr "Účet na linphone.org již mám a chci jej použít" - -#: ../gtk/setupwizard.c:43 -msgid "I have already a sip account and I just want to use it" -msgstr "SIP účet již mám a chci jej použít" - -#: ../gtk/setupwizard.c:44 -msgid "I want to specify a remote configuration URI" -msgstr "" - -#: ../gtk/setupwizard.c:87 -msgid "Enter your linphone.org username" -msgstr "Zadejte uživatelské jméno na linphone.org" - -#: ../gtk/setupwizard.c:100 ../gtk/parameters.ui.h:85 ../gtk/ldap.ui.h:4 -msgid "Username:" -msgstr "Uživatelské jméno:" - -#: ../gtk/setupwizard.c:102 ../gtk/password.ui.h:4 ../gtk/ldap.ui.h:5 -msgid "Password:" -msgstr "Heslo:" - -#: ../gtk/setupwizard.c:122 -msgid "Enter your account informations" -msgstr "Zadejte údaje o vašem účtu" - -#: ../gtk/setupwizard.c:138 -msgid "Username*" -msgstr "Uživatelské jméno*" - -#: ../gtk/setupwizard.c:139 -msgid "Password*" -msgstr "Heslo*" - -#: ../gtk/setupwizard.c:142 -msgid "Domain*" -msgstr "Doména*" - -#: ../gtk/setupwizard.c:143 -msgid "Proxy" -msgstr "Proxy" - -#: ../gtk/setupwizard.c:322 -msgid "(*) Required fields" -msgstr "(*) Povinné položky" - -#: ../gtk/setupwizard.c:323 -msgid "Username: (*)" -msgstr "Uživatelské jméno: (*)" - -#: ../gtk/setupwizard.c:325 -msgid "Password: (*)" -msgstr "Heslo: (*)" - -#: ../gtk/setupwizard.c:327 -msgid "Email: (*)" -msgstr "E-mail: (*)" - -#: ../gtk/setupwizard.c:329 -msgid "Confirm your password: (*)" -msgstr "Potvrďte heslo: (*)" - -#: ../gtk/setupwizard.c:343 -msgid "Keep me informed with linphone updates" -msgstr "" - -#: ../gtk/setupwizard.c:399 -msgid "" -"Error, account not validated, username already used or server unreachable.\n" -"Please go back and try again." -msgstr "Došlo k chybě (účet nebyl ověřen, uživatelské jméno již existuje nebo server není dostupný).\nProsím, vraťte se a zkoste to znovu." - -#: ../gtk/setupwizard.c:410 -msgid "Thank you. Your account is now configured and ready for use." -msgstr "Děkujeme vám. Váš účet je nyní nastaven a připraven k použití." - -#: ../gtk/setupwizard.c:418 -msgid "" -"Please validate your account by clicking on the link we just sent you by email.\n" -"Then come back here and press Next button." -msgstr "Prosím, ověřte svůj účet tak, že kliknete na odkaz, který jsme vám právě zaslali e-mailem.\nPak se sem vraťte a stiskněte tlačítko Další." - -#: ../gtk/setupwizard.c:609 -msgid "SIP account configuration assistant" -msgstr "" - -#: ../gtk/setupwizard.c:629 -msgid "Welcome to the account setup assistant" -msgstr "Vítejte v průvodci nastavení účtu" - -#: ../gtk/setupwizard.c:634 -msgid "Account setup assistant" -msgstr "Průvodce nastavením účtu" - -#: ../gtk/setupwizard.c:640 -msgid "Configure your account (step 1/1)" -msgstr "Nastavit účet (krok 1/1)" - -#: ../gtk/setupwizard.c:645 -msgid "Enter your sip username (step 1/1)" -msgstr "Zadejte vaše sipové uživatelské jméno (krok 1/1)" - -#: ../gtk/setupwizard.c:649 -msgid "Enter account information (step 1/2)" -msgstr "Zadejte údaje o účtu (krok 1/2)" - -#: ../gtk/setupwizard.c:658 -msgid "Validation (step 2/2)" -msgstr "Ověření (krok 2/2)" - -#: ../gtk/setupwizard.c:663 -msgid "Error" -msgstr "Chyba" - -#: ../gtk/setupwizard.c:667 ../gtk/audio_assistant.c:534 -msgid "Terminating" -msgstr "Ukončuje se" - -#: ../gtk/incall_view.c:70 ../gtk/incall_view.c:94 +#: ../gtk/incall_view.c:67 ../gtk/incall_view.c:87 #, c-format msgid "Call #%i" msgstr "Hovor č. %i" -#: ../gtk/incall_view.c:155 +#: ../gtk/incall_view.c:145 #, c-format msgid "Transfer to call #%i with %s" msgstr "Přepojit hovor č. %i s %s" -#: ../gtk/incall_view.c:211 ../gtk/incall_view.c:214 +#: ../gtk/incall_view.c:202 ../gtk/incall_view.c:205 msgid "Not used" msgstr "Nepoužito" -#: ../gtk/incall_view.c:221 +#: ../gtk/incall_view.c:212 msgid "ICE not activated" msgstr "ICE není zapnuto" -#: ../gtk/incall_view.c:223 +#: ../gtk/incall_view.c:214 msgid "ICE failed" msgstr "ICE selhalo" -#: ../gtk/incall_view.c:225 +#: ../gtk/incall_view.c:216 msgid "ICE in progress" msgstr "Probíhá ICE" -#: ../gtk/incall_view.c:227 +#: ../gtk/incall_view.c:218 msgid "Going through one or more NATs" msgstr "Prochází se jedním nebo více NATy" -#: ../gtk/incall_view.c:229 +#: ../gtk/incall_view.c:220 msgid "Direct" msgstr "Přímé" -#: ../gtk/incall_view.c:231 +#: ../gtk/incall_view.c:222 msgid "Through a relay server" msgstr "Skrze relay server" -#: ../gtk/incall_view.c:239 +#: ../gtk/incall_view.c:230 msgid "uPnP not activated" msgstr "UPnP není zapnuto" -#: ../gtk/incall_view.c:241 +#: ../gtk/incall_view.c:232 msgid "uPnP in progress" msgstr "Probíhá UPnP" -#: ../gtk/incall_view.c:243 +#: ../gtk/incall_view.c:234 msgid "uPnp not available" msgstr "UPnP není nedostupné" -#: ../gtk/incall_view.c:245 +#: ../gtk/incall_view.c:236 msgid "uPnP is running" msgstr "UPnP běží" -#: ../gtk/incall_view.c:247 +#: ../gtk/incall_view.c:238 msgid "uPnP failed" msgstr "UPnP selhalo" -#: ../gtk/incall_view.c:257 ../gtk/incall_view.c:258 +#: ../gtk/incall_view.c:248 ../gtk/incall_view.c:249 msgid "Direct or through server" msgstr "Přímé nebo skrze server" -#: ../gtk/incall_view.c:267 ../gtk/incall_view.c:279 +#: ../gtk/incall_view.c:258 ../gtk/incall_view.c:270 #, c-format msgid "" "download: %f\n" "upload: %f (kbit/s)" msgstr "příchozí: %f\nodchozí: %f (kb/s)" -#: ../gtk/incall_view.c:272 ../gtk/incall_view.c:274 +#: ../gtk/incall_view.c:263 ../gtk/incall_view.c:265 #, c-format msgid "%ix%i @ %f fps" msgstr "" -#: ../gtk/incall_view.c:304 +#: ../gtk/incall_view.c:295 #, c-format msgid "%.3f seconds" msgstr "%.3f sekund" -#: ../gtk/incall_view.c:407 ../gtk/main.ui.h:12 ../gtk/videowindow.c:235 +#: ../gtk/incall_view.c:453 ../gtk/in_call_frame.ui.h:10 +#: ../gtk/videowindow.c:236 msgid "Hang up" msgstr "Zavěsit" -#: ../gtk/incall_view.c:511 +#: ../gtk/incall_view.c:559 msgid "Calling..." msgstr "Volá se…" -#: ../gtk/incall_view.c:514 ../gtk/incall_view.c:733 -msgid "00::00::00" -msgstr "00:00:00" +#: ../gtk/incall_view.c:562 ../gtk/incall_view.c:792 +msgid "00:00:00" +msgstr "" -#: ../gtk/incall_view.c:525 +#: ../gtk/incall_view.c:573 msgid "Incoming call" msgstr "Příchozí hovor" -#: ../gtk/incall_view.c:562 +#: ../gtk/incall_view.c:610 msgid "good" msgstr "dobrá" -#: ../gtk/incall_view.c:564 +#: ../gtk/incall_view.c:612 msgid "average" msgstr "průměrná" -#: ../gtk/incall_view.c:566 +#: ../gtk/incall_view.c:614 msgid "poor" msgstr "slabá" -#: ../gtk/incall_view.c:568 +#: ../gtk/incall_view.c:616 msgid "very poor" msgstr "velmi slabá" -#: ../gtk/incall_view.c:570 +#: ../gtk/incall_view.c:618 msgid "too bad" msgstr "příliš špatná" -#: ../gtk/incall_view.c:571 ../gtk/incall_view.c:587 +#: ../gtk/incall_view.c:619 ../gtk/incall_view.c:635 msgid "unavailable" msgstr "nedostupná" -#: ../gtk/incall_view.c:679 +#: ../gtk/incall_view.c:731 msgid "Secured by SRTP" msgstr "Zabezpečeno pomocí SRTP" -#: ../gtk/incall_view.c:685 +#: ../gtk/incall_view.c:737 msgid "Secured by DTLS" msgstr "" -#: ../gtk/incall_view.c:691 +#: ../gtk/incall_view.c:743 #, c-format msgid "Secured by ZRTP - [auth token: %s]" msgstr "Zabezpečeno pomocí ZRTP – [ověřovací klíč: %s]" -#: ../gtk/incall_view.c:697 +#: ../gtk/incall_view.c:747 msgid "Set unverified" msgstr "Nastavit na neověřeno" -#: ../gtk/incall_view.c:697 ../gtk/main.ui.h:4 +#: ../gtk/incall_view.c:747 msgid "Set verified" msgstr "Nastavit na ověřeno" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In conference" msgstr "Probíhá konference" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In call" msgstr "Probíhá hovor" -#: ../gtk/incall_view.c:764 +#: ../gtk/incall_view.c:824 msgid "Paused call" msgstr "Odložený hovor" -#: ../gtk/incall_view.c:800 +#: ../gtk/incall_view.c:861 msgid "Call ended." msgstr "Hovor skončil." -#: ../gtk/incall_view.c:831 +#: ../gtk/incall_view.c:892 msgid "Transfer in progress" msgstr "Probíhá přepojení" -#: ../gtk/incall_view.c:834 +#: ../gtk/incall_view.c:895 msgid "Transfer done." msgstr "Přepojení dokončeno." -#: ../gtk/incall_view.c:837 +#: ../gtk/incall_view.c:898 msgid "Transfer failed." msgstr "Přepojení selhalo." -#: ../gtk/incall_view.c:881 +#: ../gtk/incall_view.c:929 msgid "Resume" msgstr "Obnovit" -#: ../gtk/incall_view.c:888 ../gtk/main.ui.h:9 +#: ../gtk/incall_view.c:929 ../gtk/in_call_frame.ui.h:7 msgid "Pause" msgstr "Odložit" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 #, c-format msgid "" "Recording into\n" "%s %s" msgstr "Nahrává se do\n%s %s" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 msgid "(Paused)" msgstr "(Odloženo)" -#: ../gtk/loginframe.c:87 +#: ../gtk/loginframe.c:75 #, c-format msgid "Please enter login information for %s" msgstr "Prosím, zadejte své přihlašovací jméno pro %s:" @@ -756,263 +653,108 @@ msgstr "" msgid "Downloading of remote configuration from %s failed." msgstr "" -#: ../gtk/audio_assistant.c:98 +#: ../gtk/audio_assistant.c:103 msgid "No voice detected" msgstr "" -#: ../gtk/audio_assistant.c:99 +#: ../gtk/audio_assistant.c:104 msgid "Too low" msgstr "" -#: ../gtk/audio_assistant.c:100 +#: ../gtk/audio_assistant.c:105 msgid "Good" msgstr "" -#: ../gtk/audio_assistant.c:101 +#: ../gtk/audio_assistant.c:106 msgid "Too loud" msgstr "" -#: ../gtk/audio_assistant.c:183 +#: ../gtk/audio_assistant.c:188 msgid "Did you hear three beeps ?" msgstr "" -#: ../gtk/audio_assistant.c:292 ../gtk/audio_assistant.c:297 +#: ../gtk/audio_assistant.c:299 ../gtk/audio_assistant.c:304 msgid "Sound preferences not found " msgstr "" -#: ../gtk/audio_assistant.c:306 +#: ../gtk/audio_assistant.c:313 msgid "Cannot launch system sound control " msgstr "" -#: ../gtk/audio_assistant.c:318 +#: ../gtk/audio_assistant.c:325 msgid "" "Welcome!\n" "This assistant will help you to configure audio settings for Linphone" msgstr "" -#: ../gtk/audio_assistant.c:328 +#: ../gtk/audio_assistant.c:335 msgid "Capture device" msgstr "" -#: ../gtk/audio_assistant.c:329 +#: ../gtk/audio_assistant.c:336 msgid "Recorded volume" msgstr "" -#: ../gtk/audio_assistant.c:333 +#: ../gtk/audio_assistant.c:340 msgid "No voice" msgstr "" -#: ../gtk/audio_assistant.c:334 ../gtk/audio_assistant.c:373 +#: ../gtk/audio_assistant.c:341 ../gtk/audio_assistant.c:380 msgid "System sound preferences" msgstr "" -#: ../gtk/audio_assistant.c:369 +#: ../gtk/audio_assistant.c:376 msgid "Playback device" msgstr "" -#: ../gtk/audio_assistant.c:370 +#: ../gtk/audio_assistant.c:377 msgid "Play three beeps" msgstr "" -#: ../gtk/audio_assistant.c:403 +#: ../gtk/audio_assistant.c:410 msgid "Press the record button and say some words" msgstr "" -#: ../gtk/audio_assistant.c:404 +#: ../gtk/audio_assistant.c:411 msgid "Listen to your record voice" msgstr "" -#: ../gtk/audio_assistant.c:405 +#: ../gtk/audio_assistant.c:412 ../gtk/conf_frame.ui.h:2 +#: ../gtk/in_call_frame.ui.h:4 msgid "Record" msgstr "" -#: ../gtk/audio_assistant.c:406 +#: ../gtk/audio_assistant.c:413 msgid "Play" msgstr "" -#: ../gtk/audio_assistant.c:433 +#: ../gtk/audio_assistant.c:440 msgid "Let's start Linphone now" msgstr "" -#: ../gtk/audio_assistant.c:503 +#: ../gtk/audio_assistant.c:510 msgid "Audio Assistant" msgstr "" -#: ../gtk/audio_assistant.c:513 ../gtk/main.ui.h:32 +#: ../gtk/audio_assistant.c:520 ../gtk/main.ui.h:13 msgid "Audio assistant" msgstr "" -#: ../gtk/audio_assistant.c:518 +#: ../gtk/audio_assistant.c:525 msgid "Mic Gain calibration" msgstr "" -#: ../gtk/audio_assistant.c:524 +#: ../gtk/audio_assistant.c:531 msgid "Speaker volume calibration" msgstr "" -#: ../gtk/audio_assistant.c:529 +#: ../gtk/audio_assistant.c:536 msgid "Record and Play" msgstr "" -#: ../gtk/main.ui.h:1 -msgid "Callee name" -msgstr "Jméno volaného" - -#: ../gtk/main.ui.h:2 -msgid "Send" -msgstr "Odeslat" - -#: ../gtk/main.ui.h:3 -msgid "End conference" -msgstr "Ukončit konferenci" - -#: ../gtk/main.ui.h:7 -msgid "Record this call to an audio file" -msgstr "Nahrát tento hovor do zvukového souboru" - -#: ../gtk/main.ui.h:8 -msgid "Video" -msgstr "Obraz" - -#: ../gtk/main.ui.h:10 -msgid "Mute" -msgstr "Ztišit" - -#: ../gtk/main.ui.h:11 -msgid "Transfer" -msgstr "Přepojit" - -#: ../gtk/main.ui.h:14 -msgid "In call" -msgstr "Telefonuje se" - -#: ../gtk/main.ui.h:15 -msgid "Duration" -msgstr "Délka" - -#: ../gtk/main.ui.h:16 -msgid "Call quality rating" -msgstr "Hodnocení kvality hovoru" - -#: ../gtk/main.ui.h:17 -msgid "All users" -msgstr "všech uživatelích" - -#: ../gtk/main.ui.h:18 -msgid "Online users" -msgstr "připojených uživatelích" - -#: ../gtk/main.ui.h:19 -msgid "ADSL" -msgstr "ADSL" - -#: ../gtk/main.ui.h:20 -msgid "Fiber Channel" -msgstr "Fiber Channel" - -#: ../gtk/main.ui.h:21 -msgid "Default" -msgstr "Výchozí" - -#: ../gtk/main.ui.h:22 -msgid "Delete" -msgstr "Smazat" - -#: ../gtk/main.ui.h:23 -msgid "_Options" -msgstr "V_olby" - -#: ../gtk/main.ui.h:24 -msgid "Set configuration URI" -msgstr "" - -#: ../gtk/main.ui.h:25 -msgid "Always start video" -msgstr "Vždy spustit obraz" - -#: ../gtk/main.ui.h:26 -msgid "Enable self-view" -msgstr "Zobrazovat sám sebe" - -#: ../gtk/main.ui.h:27 -msgid "_Help" -msgstr "Nápo_věda" - -#: ../gtk/main.ui.h:28 -msgid "Show debug window" -msgstr "Zobrazit ladicí okno" - -#: ../gtk/main.ui.h:29 -msgid "_Homepage" -msgstr "_Domovská stránka" - -#: ../gtk/main.ui.h:30 -msgid "Check _Updates" -msgstr "Vyhledat akt_ualizace" - -#: ../gtk/main.ui.h:31 -msgid "Account assistant" -msgstr "Průvodce účtem" - -#: ../gtk/main.ui.h:33 -msgid "SIP address or phone number:" -msgstr "SIP adresa nebo telefonní číslo:" - -#: ../gtk/main.ui.h:34 -msgid "Initiate a new call" -msgstr "Zahájit nový hovor" - -#: ../gtk/main.ui.h:35 -msgid "Contacts" -msgstr "Kontakty" - -#: ../gtk/main.ui.h:36 -msgid "Search" -msgstr "Hledat" - -#: ../gtk/main.ui.h:37 -msgid "Add contacts from directory" -msgstr "Přidat kontakty z adresáře" - -#: ../gtk/main.ui.h:38 -msgid "Add contact" -msgstr "Přidat kontakt" - -#: ../gtk/main.ui.h:39 -msgid "Recent calls" -msgstr "Nedávné hovory" - -#: ../gtk/main.ui.h:40 -msgid "My current identity:" -msgstr "Moje současná totožnost:" - -#: ../gtk/main.ui.h:41 ../gtk/tunnel_config.ui.h:7 -msgid "Username" -msgstr "Uživatelské jméno" - -#: ../gtk/main.ui.h:42 ../gtk/tunnel_config.ui.h:8 -msgid "Password" -msgstr "Heslo" - -#: ../gtk/main.ui.h:43 -msgid "Internet connection:" -msgstr "Připojení k Internetu:" - -#: ../gtk/main.ui.h:44 -msgid "Automatically log me in" -msgstr "Přihlašovat mě automaticky" - -#: ../gtk/main.ui.h:45 ../gtk/password.ui.h:3 -msgid "UserID" -msgstr "Identifikátor uživatele" - -#: ../gtk/main.ui.h:46 -msgid "Login information" -msgstr "Informace o přihlášení" - -#: ../gtk/main.ui.h:47 -msgid "Welcome!" -msgstr "" +#: ../gtk/audio_assistant.c:541 ../gtk/setup_wizard.ui.h:38 +msgid "Terminating" +msgstr "Ukončuje se" #: ../gtk/about.ui.h:1 msgid "About Linphone" @@ -1042,456 +784,6 @@ msgid "" "he: Eli Zaretskii \n" msgstr "" -#: ../gtk/contact.ui.h:2 -msgid "SIP Address" -msgstr "SIP adresa" - -#: ../gtk/contact.ui.h:3 -msgid "Show this contact presence status" -msgstr "U tohoto kontaktu zobrazovat stav přítomnosti" - -#: ../gtk/contact.ui.h:4 -msgid "Allow this contact to see my presence status" -msgstr "Dovolit tomuto kontaktu, aby viděl můj stav přítomnosti" - -#: ../gtk/contact.ui.h:5 -msgid "Contact information" -msgstr "Informace o kontaktu" - -#: ../gtk/log.ui.h:1 -msgid "Linphone debug window" -msgstr "Ladicí okno Linphonu" - -#: ../gtk/log.ui.h:2 -msgid "Scroll to end" -msgstr "Přejít na konec" - -#: ../gtk/password.ui.h:1 -msgid "Linphone - Authentication required" -msgstr "Linphone – Ověření totožnosti vyžadováno" - -#: ../gtk/password.ui.h:2 -msgid "Please enter the domain password" -msgstr "Prosím, zadejte heslo pro doménu" - -#: ../gtk/call_logs.ui.h:1 -msgid "Call history" -msgstr "Historie volání" - -#: ../gtk/call_logs.ui.h:2 -msgid "Clear all" -msgstr "Vše smazat" - -#: ../gtk/call_logs.ui.h:3 -msgid "Call back" -msgstr "Zavolat zpátky" - -#: ../gtk/sip_account.ui.h:1 -msgid "Linphone - Configure a SIP account" -msgstr "Linphone – Nastav SIP účet" - -#: ../gtk/sip_account.ui.h:2 -msgid "Your SIP identity:" -msgstr "Vaše SIP totožnost:" - -#: ../gtk/sip_account.ui.h:3 -msgid "Looks like sip:@" -msgstr "Vypadá jako sip:@" - -#: ../gtk/sip_account.ui.h:4 -msgid "sip:" -msgstr "sip:" - -#: ../gtk/sip_account.ui.h:5 -msgid "SIP Proxy address:" -msgstr "Adresa SIP proxy:" - -#: ../gtk/sip_account.ui.h:6 -msgid "Looks like sip:" -msgstr "Vypadá jako sip:" - -#: ../gtk/sip_account.ui.h:7 -msgid "Registration duration (sec):" -msgstr "Registrační období (s):" - -#: ../gtk/sip_account.ui.h:8 -msgid "Contact params (optional):" -msgstr "" - -#: ../gtk/sip_account.ui.h:9 -msgid "AVPF regular RTCP interval (sec):" -msgstr "" - -#: ../gtk/sip_account.ui.h:10 -msgid "Route (optional):" -msgstr "Směrování (volitelné):" - -#: ../gtk/sip_account.ui.h:11 -msgid "Transport" -msgstr "" - -#: ../gtk/sip_account.ui.h:12 -msgid "Register" -msgstr "Zaregistrovat se" - -#: ../gtk/sip_account.ui.h:13 -msgid "Publish presence information" -msgstr "Zveřejnit stav přítomnosti" - -#: ../gtk/sip_account.ui.h:14 -msgid "Enable AVPF" -msgstr "" - -#: ../gtk/sip_account.ui.h:15 -msgid "Configure a SIP account" -msgstr "Nastavit SIP účet" - -#: ../gtk/parameters.ui.h:1 -msgid "anonymous" -msgstr "" - -#: ../gtk/parameters.ui.h:2 -msgid "GSSAPI" -msgstr "" - -#: ../gtk/parameters.ui.h:3 -msgid "SASL" -msgstr "" - -#: ../gtk/parameters.ui.h:4 -msgid "default soundcard" -msgstr "implicitní zvuková karta" - -#: ../gtk/parameters.ui.h:5 -msgid "a sound card" -msgstr "zvuková karta" - -#: ../gtk/parameters.ui.h:6 -msgid "default camera" -msgstr "implicitní kamera" - -#: ../gtk/parameters.ui.h:7 -msgid "CIF" -msgstr "CIF" - -#: ../gtk/parameters.ui.h:8 -msgid "Audio codecs" -msgstr "Kodeky zvuku" - -#: ../gtk/parameters.ui.h:9 -msgid "Video codecs" -msgstr "Kodeky obrazu" - -#: ../gtk/parameters.ui.h:10 -msgid "C" -msgstr "C" - -#: ../gtk/parameters.ui.h:11 -msgid "SIP (UDP)" -msgstr "SIP (UDP)" - -#: ../gtk/parameters.ui.h:12 -msgid "SIP (TCP)" -msgstr "SIP (TCP)" - -#: ../gtk/parameters.ui.h:13 -msgid "SIP (TLS)" -msgstr "SIP (TLS)" - -#: ../gtk/parameters.ui.h:14 -msgid "Settings" -msgstr "Nastavení" - -#: ../gtk/parameters.ui.h:15 -msgid "Set Maximum Transmission Unit:" -msgstr "Nastavit MTU (největší přenositelná zpráva):" - -#: ../gtk/parameters.ui.h:16 -msgid "Send DTMFs as SIP info" -msgstr "Odesílat tóny DTMF jako SIP INFO zprávy" - -#: ../gtk/parameters.ui.h:17 -msgid "Allow IPv6" -msgstr "" - -#: ../gtk/parameters.ui.h:18 -msgid "Transport" -msgstr "Přenos" - -#: ../gtk/parameters.ui.h:19 -msgid "SIP/UDP port" -msgstr "" - -#: ../gtk/parameters.ui.h:21 -msgid "Random" -msgstr "" - -#: ../gtk/parameters.ui.h:22 -msgid "SIP/TCP port" -msgstr "" - -#: ../gtk/parameters.ui.h:23 -msgid "Audio RTP/UDP:" -msgstr "Zvukový RTP/UDP:" - -#: ../gtk/parameters.ui.h:24 -msgid "Fixed" -msgstr "Stálý" - -#: ../gtk/parameters.ui.h:25 -msgid "Video RTP/UDP:" -msgstr "Obrazový RTP/UDP:" - -#: ../gtk/parameters.ui.h:26 -msgid "Media encryption type" -msgstr "Druh šifrování médií" - -#: ../gtk/parameters.ui.h:27 -msgid "Media encryption is mandatory" -msgstr "Šifrování médií je povinné" - -#: ../gtk/parameters.ui.h:28 -msgid "Tunnel" -msgstr "Tunel" - -#: ../gtk/parameters.ui.h:29 -msgid "DSCP fields" -msgstr "Položky DSCP" - -#: ../gtk/parameters.ui.h:30 -msgid "Network protocol and ports" -msgstr "Síťové protokoly a porty" - -#: ../gtk/parameters.ui.h:31 -msgid "Direct connection to the Internet" -msgstr "Přímé připojení do Internetu" - -#: ../gtk/parameters.ui.h:32 -msgid "Behind NAT / Firewall (specify gateway IP )" -msgstr "" - -#: ../gtk/parameters.ui.h:33 -msgid "Behind NAT / Firewall (use STUN to resolve)" -msgstr "Za NAT/firewallem (adresu určí STUN)" - -#: ../gtk/parameters.ui.h:34 -msgid "Behind NAT / Firewall (use ICE)" -msgstr "Za NAT/firewallem (adresu určí ICE)" - -#: ../gtk/parameters.ui.h:35 -msgid "Behind NAT / Firewall (use uPnP)" -msgstr "Za NAT/firewallem (adresu určí UPnP)" - -#: ../gtk/parameters.ui.h:36 -msgid "Public IP address:" -msgstr "Veřejná IP adresa:" - -#: ../gtk/parameters.ui.h:37 -msgid "Stun server:" -msgstr "STUN server:" - -#: ../gtk/parameters.ui.h:38 -msgid "NAT and Firewall" -msgstr "NAT a firewall" - -#: ../gtk/parameters.ui.h:39 -msgid "Network settings" -msgstr "Nastavení sítě" - -#: ../gtk/parameters.ui.h:40 -msgid "Ring sound:" -msgstr "Vyzvánění:" - -#: ../gtk/parameters.ui.h:41 -msgid "ALSA special device (optional):" -msgstr "Zvláštní ALSA zařízení (volitelné):" - -#: ../gtk/parameters.ui.h:42 -msgid "Capture device:" -msgstr "Zařízení pro nahrávání:" - -#: ../gtk/parameters.ui.h:43 -msgid "Ring device:" -msgstr "Zařízení pro vyzvánění:" - -#: ../gtk/parameters.ui.h:44 -msgid "Playback device:" -msgstr "Zařízení pro přehrávání:" - -#: ../gtk/parameters.ui.h:45 -msgid "Enable echo cancellation" -msgstr "Zapnout potlačení ozvěny" - -#: ../gtk/parameters.ui.h:46 -msgid "Audio" -msgstr "Zvuk" - -#: ../gtk/parameters.ui.h:47 -msgid "Video input device:" -msgstr "Vstupní zařízení obrazu:" - -#: ../gtk/parameters.ui.h:48 -msgid "Prefered video resolution:" -msgstr "Upřednostňované rozlišení obrazu:" - -#: ../gtk/parameters.ui.h:49 -msgid "Video output method:" -msgstr "" - -#: ../gtk/parameters.ui.h:50 -msgid "Show camera preview" -msgstr "" - -#: ../gtk/parameters.ui.h:51 -msgid "Video" -msgstr "Obraz" - -#: ../gtk/parameters.ui.h:52 -msgid "Multimedia settings" -msgstr "Nastavení multimédií" - -#: ../gtk/parameters.ui.h:53 -msgid "This section defines your SIP address when not using a SIP account" -msgstr "Tento oddíl určuje vaši SIP adresu, když se nepoužívá žádný účet" - -#: ../gtk/parameters.ui.h:54 -msgid "Your display name (eg: John Doe):" -msgstr "Vaše zobrazované jméno (např. Jan Novák):" - -#: ../gtk/parameters.ui.h:55 -msgid "Your username:" -msgstr "Vaše uživatelské jméno:" - -#: ../gtk/parameters.ui.h:56 -msgid "Your resulting SIP address:" -msgstr "Vaše výsledná SIP adresa:" - -#: ../gtk/parameters.ui.h:57 -msgid "Default identity" -msgstr "Implicitní totožnost" - -#: ../gtk/parameters.ui.h:58 -msgid "Wizard" -msgstr "Průvodce" - -#: ../gtk/parameters.ui.h:59 -msgid "Add" -msgstr "Přidat" - -#: ../gtk/parameters.ui.h:60 -msgid "Edit" -msgstr "Upravit" - -#: ../gtk/parameters.ui.h:61 -msgid "Remove" -msgstr "Odstranit" - -#: ../gtk/parameters.ui.h:62 -msgid "Proxy accounts" -msgstr "Proxy účty" - -#: ../gtk/parameters.ui.h:63 -msgid "Erase all passwords" -msgstr "Vymazat všechna hesla" - -#: ../gtk/parameters.ui.h:64 -msgid "Privacy" -msgstr "Soukromí" - -#: ../gtk/parameters.ui.h:65 -msgid "Automatically answer when a call is received" -msgstr "" - -#: ../gtk/parameters.ui.h:66 -msgid "Delay before answering (ms)" -msgstr "" - -#: ../gtk/parameters.ui.h:67 -msgid "Auto-answer" -msgstr "" - -#: ../gtk/parameters.ui.h:68 -msgid "Manage SIP Accounts" -msgstr "Nastavení SIP účtů" - -#: ../gtk/parameters.ui.h:69 ../gtk/tunnel_config.ui.h:4 -msgid "Enable" -msgstr "Povolit" - -#: ../gtk/parameters.ui.h:70 ../gtk/tunnel_config.ui.h:5 -msgid "Disable" -msgstr "Zakázat" - -#: ../gtk/parameters.ui.h:71 -msgid "Codecs" -msgstr "Kodeky" - -#: ../gtk/parameters.ui.h:72 -msgid "0 stands for \"unlimited\"" -msgstr "0 znamená „neomezeno“" - -#: ../gtk/parameters.ui.h:73 -msgid "Upload speed limit in Kbit/sec:" -msgstr "Omezení odchozí rychlosti (kb/s):" - -#: ../gtk/parameters.ui.h:74 -msgid "Download speed limit in Kbit/sec:" -msgstr "Omezení příchozí rychlosti (kb/s):" - -#: ../gtk/parameters.ui.h:75 -msgid "Enable adaptive rate control" -msgstr "Zapnout přizpůsobující se řízení rychlosti" - -#: ../gtk/parameters.ui.h:76 -msgid "" -"Adaptive rate control is a technique to dynamically guess the available " -"bandwidth during a call." -msgstr "Přizpůsobující se řízení rychlosti je technika dynamického odhadu dostupného pásma během hovoru." - -#: ../gtk/parameters.ui.h:77 -msgid "Bandwidth control" -msgstr "Využití šířky pásma" - -#: ../gtk/parameters.ui.h:78 -msgid "Codecs" -msgstr "Kodeky" - -#: ../gtk/parameters.ui.h:79 -msgid "Language" -msgstr "Jazyk" - -#: ../gtk/parameters.ui.h:80 -msgid "Show advanced settings" -msgstr "Zobrazit podrobnější nastavení" - -#: ../gtk/parameters.ui.h:81 -msgid "Level" -msgstr "Úroveň" - -#: ../gtk/parameters.ui.h:82 -msgid "User interface" -msgstr "Uživatelské rozhraní" - -#: ../gtk/parameters.ui.h:83 ../gtk/ldap.ui.h:2 -msgid "Server address:" -msgstr "" - -#: ../gtk/parameters.ui.h:84 ../gtk/ldap.ui.h:3 -msgid "Authentication method:" -msgstr "" - -#: ../gtk/parameters.ui.h:86 -msgid "LDAP Account setup" -msgstr "" - -#: ../gtk/parameters.ui.h:87 -msgid "LDAP" -msgstr "" - -#: ../gtk/parameters.ui.h:88 -msgid "Done" -msgstr "Hotovo" - #: ../gtk/buddylookup.ui.h:1 msgid "Search contacts in directory" msgstr "Hledat kontakty v adresáři" @@ -1504,29 +796,21 @@ msgstr "Přidat na svůj seznam" msgid "Search somebody" msgstr "Hledat někoho" -#: ../gtk/waiting.ui.h:2 -msgid "Please wait" -msgstr "Prosím, čekejte" +#: ../gtk/callee_frame.ui.h:1 +msgid "Callee name" +msgstr "Jméno volaného" -#: ../gtk/dscp_settings.ui.h:1 -msgid "DSCP settings" -msgstr "" +#: ../gtk/call_logs.ui.h:1 +msgid "Call history" +msgstr "Historie volání" -#: ../gtk/dscp_settings.ui.h:2 -msgid "SIP" -msgstr "SIP" +#: ../gtk/call_logs.ui.h:2 +msgid "Clear all" +msgstr "Vše smazat" -#: ../gtk/dscp_settings.ui.h:3 -msgid "Audio RTP stream" -msgstr "RTP proud zvuku" - -#: ../gtk/dscp_settings.ui.h:4 -msgid "Video RTP stream" -msgstr "RTP proud obrazu" - -#: ../gtk/dscp_settings.ui.h:5 -msgid "Set DSCP values (in hexadecimal)" -msgstr "Nastavit hodnoty DSCP (šestnáctkově)" +#: ../gtk/call_logs.ui.h:3 +msgid "Call back" +msgstr "Zavolat zpátky" #: ../gtk/call_statistics.ui.h:1 msgid "Call statistics" @@ -1576,30 +860,112 @@ msgstr "" msgid "Call statistics and information" msgstr "Statistické a ostatní údaje o hovoru" -#: ../gtk/tunnel_config.ui.h:1 -msgid "Configure VoIP tunnel" -msgstr "Nastavit VoIP tunel" +#: ../gtk/chatroom_frame.ui.h:1 +msgid "Send" +msgstr "Odeslat" -#: ../gtk/tunnel_config.ui.h:2 -msgid "Host" -msgstr "Stroj" +#: ../gtk/conf_frame.ui.h:1 +msgid "End conference" +msgstr "Ukončit konferenci" -#: ../gtk/tunnel_config.ui.h:3 -msgid "Port" -msgstr "Port" +#: ../gtk/config-uri.ui.h:1 +msgid "Specifying a remote configuration URI" +msgstr "" -#: ../gtk/tunnel_config.ui.h:6 -msgid "Configure tunnel" -msgstr "Nastavit tunel" +#: ../gtk/config-uri.ui.h:2 +msgid "" +"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" +"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " +msgstr "" -#: ../gtk/tunnel_config.ui.h:9 -msgid "Configure http proxy (optional)" -msgstr "Nastavit HTTP proxy (volitelné)" +#: ../gtk/contact.ui.h:2 +msgid "SIP Address" +msgstr "SIP adresa" + +#: ../gtk/contact.ui.h:3 +msgid "Show this contact presence status" +msgstr "U tohoto kontaktu zobrazovat stav přítomnosti" + +#: ../gtk/contact.ui.h:4 +msgid "Allow this contact to see my presence status" +msgstr "Dovolit tomuto kontaktu, aby viděl můj stav přítomnosti" + +#: ../gtk/contact.ui.h:5 +msgid "Contact information" +msgstr "Informace o kontaktu" + +#: ../gtk/dscp_settings.ui.h:1 +msgid "DSCP settings" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:2 +msgid "SIP" +msgstr "SIP" + +#: ../gtk/dscp_settings.ui.h:3 +msgid "Audio RTP stream" +msgstr "RTP proud zvuku" + +#: ../gtk/dscp_settings.ui.h:4 +msgid "Video RTP stream" +msgstr "RTP proud obrazu" + +#: ../gtk/dscp_settings.ui.h:5 +msgid "Set DSCP values (in hexadecimal)" +msgstr "Nastavit hodnoty DSCP (šestnáctkově)" + +#: ../gtk/in_call_frame.ui.h:1 +msgid "Click here to set the speakers volume" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:5 +msgid "Record this call to an audio file" +msgstr "Nahrát tento hovor do zvukového souboru" + +#: ../gtk/in_call_frame.ui.h:6 +msgid "Video" +msgstr "Obraz" + +#: ../gtk/in_call_frame.ui.h:8 +msgid "Mute" +msgstr "Ztišit" + +#: ../gtk/in_call_frame.ui.h:9 +msgid "Transfer" +msgstr "Přepojit" + +#: ../gtk/in_call_frame.ui.h:12 +msgid "In call" +msgstr "Telefonuje se" + +#: ../gtk/in_call_frame.ui.h:13 +msgid "Duration" +msgstr "Délka" + +#: ../gtk/in_call_frame.ui.h:14 +msgid "Call quality rating" +msgstr "Hodnocení kvality hovoru" #: ../gtk/ldap.ui.h:1 msgid "LDAP Settings" msgstr "" +#: ../gtk/ldap.ui.h:2 ../gtk/parameters.ui.h:89 +msgid "Server address:" +msgstr "" + +#: ../gtk/ldap.ui.h:3 ../gtk/parameters.ui.h:90 +msgid "Authentication method:" +msgstr "" + +#: ../gtk/ldap.ui.h:4 ../gtk/parameters.ui.h:91 ../gtk/setup_wizard.ui.h:17 +msgid "Username:" +msgstr "Uživatelské jméno:" + +#: ../gtk/ldap.ui.h:5 ../gtk/password.ui.h:4 ../gtk/setup_wizard.ui.h:18 +msgid "Password:" +msgstr "Heslo:" + #: ../gtk/ldap.ui.h:6 msgid "Use TLS Connection" msgstr "" @@ -1685,16 +1051,504 @@ msgstr "" msgid "NTLM" msgstr "" -#: ../gtk/config-uri.ui.h:1 -msgid "Specifying a remote configuration URI" +#: ../gtk/login_frame.ui.h:1 ../gtk/tunnel_config.ui.h:7 +msgid "Username" +msgstr "Uživatelské jméno" + +#: ../gtk/login_frame.ui.h:2 ../gtk/tunnel_config.ui.h:8 +msgid "Password" +msgstr "Heslo" + +#: ../gtk/login_frame.ui.h:3 +msgid "Internet connection:" +msgstr "Připojení k Internetu:" + +#: ../gtk/login_frame.ui.h:4 +msgid "Automatically log me in" +msgstr "Přihlašovat mě automaticky" + +#: ../gtk/login_frame.ui.h:5 ../gtk/password.ui.h:3 +msgid "UserID" +msgstr "Identifikátor uživatele" + +#: ../gtk/login_frame.ui.h:6 +msgid "Login information" +msgstr "Informace o přihlášení" + +#: ../gtk/login_frame.ui.h:7 +msgid "Welcome!" msgstr "" -#: ../gtk/config-uri.ui.h:2 -msgid "" -"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" -"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " +#: ../gtk/login_frame.ui.h:8 +msgid "ADSL" +msgstr "ADSL" + +#: ../gtk/login_frame.ui.h:9 +msgid "Fiber Channel" +msgstr "Fiber Channel" + +#: ../gtk/log.ui.h:1 +msgid "Linphone debug window" +msgstr "Ladicí okno Linphonu" + +#: ../gtk/log.ui.h:2 +msgid "Scroll to end" +msgstr "Přejít na konec" + +#: ../gtk/main.ui.h:1 +msgid "Default" +msgstr "Výchozí" + +#: ../gtk/main.ui.h:2 +msgid "Delete" +msgstr "Smazat" + +#: ../gtk/main.ui.h:3 +msgid "_Options" +msgstr "V_olby" + +#: ../gtk/main.ui.h:4 +msgid "Set configuration URI" msgstr "" +#: ../gtk/main.ui.h:5 +msgid "Always start video" +msgstr "Vždy spustit obraz" + +#: ../gtk/main.ui.h:6 +msgid "Enable self-view" +msgstr "Zobrazovat sám sebe" + +#: ../gtk/main.ui.h:7 +msgid "Show keypad" +msgstr "" + +#: ../gtk/main.ui.h:8 +msgid "_Help" +msgstr "Nápo_věda" + +#: ../gtk/main.ui.h:9 +msgid "Show debug window" +msgstr "Zobrazit ladicí okno" + +#: ../gtk/main.ui.h:10 +msgid "_Homepage" +msgstr "_Domovská stránka" + +#: ../gtk/main.ui.h:11 +msgid "Check _Updates" +msgstr "Vyhledat akt_ualizace" + +#: ../gtk/main.ui.h:12 +msgid "Account assistant" +msgstr "Průvodce účtem" + +#: ../gtk/main.ui.h:14 +msgid "SIP address or phone number:" +msgstr "SIP adresa nebo telefonní číslo:" + +#: ../gtk/main.ui.h:15 +msgid "Initiate a new call" +msgstr "Zahájit nový hovor" + +#: ../gtk/main.ui.h:16 +msgid "Contacts" +msgstr "Kontakty" + +#: ../gtk/main.ui.h:17 +msgid "Search" +msgstr "Hledat" + +#: ../gtk/main.ui.h:18 +msgid "Add contacts from directory" +msgstr "Přidat kontakty z adresáře" + +#: ../gtk/main.ui.h:19 +msgid "Add contact" +msgstr "Přidat kontakt" + +#: ../gtk/main.ui.h:20 +msgid "Clear call history" +msgstr "" + +#: ../gtk/main.ui.h:22 +msgid "My current identity:" +msgstr "Moje současná totožnost:" + +#: ../gtk/main.ui.h:23 +msgid "Autoanswer is enabled" +msgstr "" + +#: ../gtk/parameters.ui.h:1 +msgid "anonymous" +msgstr "" + +#: ../gtk/parameters.ui.h:2 +msgid "GSSAPI" +msgstr "" + +#: ../gtk/parameters.ui.h:3 +msgid "SASL" +msgstr "" + +#: ../gtk/parameters.ui.h:4 +msgid "default soundcard" +msgstr "implicitní zvuková karta" + +#: ../gtk/parameters.ui.h:5 +msgid "a sound card" +msgstr "zvuková karta" + +#: ../gtk/parameters.ui.h:6 +msgid "default camera" +msgstr "implicitní kamera" + +#: ../gtk/parameters.ui.h:7 +msgid "CIF" +msgstr "CIF" + +#: ../gtk/parameters.ui.h:8 +msgid "Audio codecs" +msgstr "Kodeky zvuku" + +#: ../gtk/parameters.ui.h:9 +msgid "Video codecs" +msgstr "Kodeky obrazu" + +#: ../gtk/parameters.ui.h:10 +msgid "C" +msgstr "C" + +#: ../gtk/parameters.ui.h:11 +msgid "SIP (UDP)" +msgstr "SIP (UDP)" + +#: ../gtk/parameters.ui.h:12 +msgid "SIP (TCP)" +msgstr "SIP (TCP)" + +#: ../gtk/parameters.ui.h:13 +msgid "SIP (TLS)" +msgstr "SIP (TLS)" + +#: ../gtk/parameters.ui.h:14 +msgid "default" +msgstr "" + +#: ../gtk/parameters.ui.h:15 +msgid "high-fps" +msgstr "" + +#: ../gtk/parameters.ui.h:16 +msgid "custom" +msgstr "" + +#: ../gtk/parameters.ui.h:17 +msgid "Settings" +msgstr "Nastavení" + +#: ../gtk/parameters.ui.h:18 +msgid "This section defines your SIP address when not using a SIP account" +msgstr "Tento oddíl určuje vaši SIP adresu, když se nepoužívá žádný účet" + +#: ../gtk/parameters.ui.h:19 +msgid "Your display name (eg: John Doe):" +msgstr "Vaše zobrazované jméno (např. Jan Novák):" + +#: ../gtk/parameters.ui.h:20 +msgid "Your username:" +msgstr "Vaše uživatelské jméno:" + +#: ../gtk/parameters.ui.h:21 +msgid "Your resulting SIP address:" +msgstr "Vaše výsledná SIP adresa:" + +#: ../gtk/parameters.ui.h:22 +msgid "Default identity" +msgstr "Implicitní totožnost" + +#: ../gtk/parameters.ui.h:23 +msgid "Wizard" +msgstr "Průvodce" + +#: ../gtk/parameters.ui.h:24 +msgid "Add" +msgstr "Přidat" + +#: ../gtk/parameters.ui.h:25 +msgid "Edit" +msgstr "Upravit" + +#: ../gtk/parameters.ui.h:26 +msgid "Remove" +msgstr "Odstranit" + +#: ../gtk/parameters.ui.h:27 +msgid "Proxy accounts" +msgstr "Proxy účty" + +#: ../gtk/parameters.ui.h:28 +msgid "Erase all passwords" +msgstr "Vymazat všechna hesla" + +#: ../gtk/parameters.ui.h:29 +msgid "Privacy" +msgstr "Soukromí" + +#: ../gtk/parameters.ui.h:30 +msgid "Automatically answer when a call is received" +msgstr "" + +#: ../gtk/parameters.ui.h:31 +msgid "Delay before answering (ms)" +msgstr "" + +#: ../gtk/parameters.ui.h:32 +msgid "Auto-answer" +msgstr "" + +#: ../gtk/parameters.ui.h:33 +msgid "Manage SIP Accounts" +msgstr "Nastavení SIP účtů" + +#: ../gtk/parameters.ui.h:34 +msgid "Ring sound:" +msgstr "Vyzvánění:" + +#: ../gtk/parameters.ui.h:35 +msgid "ALSA special device (optional):" +msgstr "Zvláštní ALSA zařízení (volitelné):" + +#: ../gtk/parameters.ui.h:36 +msgid "Capture device:" +msgstr "Zařízení pro nahrávání:" + +#: ../gtk/parameters.ui.h:37 +msgid "Ring device:" +msgstr "Zařízení pro vyzvánění:" + +#: ../gtk/parameters.ui.h:38 +msgid "Playback device:" +msgstr "Zařízení pro přehrávání:" + +#: ../gtk/parameters.ui.h:39 +msgid "Enable echo cancellation" +msgstr "Zapnout potlačení ozvěny" + +#: ../gtk/parameters.ui.h:40 +msgid "Audio" +msgstr "Zvuk" + +#: ../gtk/parameters.ui.h:41 +msgid "Video input device:" +msgstr "Vstupní zařízení obrazu:" + +#: ../gtk/parameters.ui.h:42 +msgid "Preferred video resolution:" +msgstr "" + +#: ../gtk/parameters.ui.h:43 +msgid "Video output method:" +msgstr "" + +#: ../gtk/parameters.ui.h:44 +msgid "Show camera preview" +msgstr "" + +#: ../gtk/parameters.ui.h:45 +msgid "Video preset:" +msgstr "" + +#: ../gtk/parameters.ui.h:46 +msgid "Preferred video framerate:" +msgstr "" + +#: ../gtk/parameters.ui.h:47 +msgid "0 stands for \"unlimited\"" +msgstr "0 znamená „neomezeno“" + +#: ../gtk/parameters.ui.h:48 +msgid "Video" +msgstr "Obraz" + +#: ../gtk/parameters.ui.h:49 +msgid "Upload speed limit in Kbit/sec:" +msgstr "Omezení odchozí rychlosti (kb/s):" + +#: ../gtk/parameters.ui.h:50 +msgid "Download speed limit in Kbit/sec:" +msgstr "Omezení příchozí rychlosti (kb/s):" + +#: ../gtk/parameters.ui.h:51 +msgid "Enable adaptive rate control" +msgstr "Zapnout přizpůsobující se řízení rychlosti" + +#: ../gtk/parameters.ui.h:52 +msgid "" +"Adaptive rate control is a technique to dynamically guess the available " +"bandwidth during a call." +msgstr "Přizpůsobující se řízení rychlosti je technika dynamického odhadu dostupného pásma během hovoru." + +#: ../gtk/parameters.ui.h:53 +msgid "Bandwidth control" +msgstr "Využití šířky pásma" + +#: ../gtk/parameters.ui.h:54 +msgid "Multimedia settings" +msgstr "Nastavení multimédií" + +#: ../gtk/parameters.ui.h:55 +msgid "Set Maximum Transmission Unit:" +msgstr "Nastavit MTU (největší přenositelná zpráva):" + +#: ../gtk/parameters.ui.h:56 +msgid "Send DTMFs as SIP info" +msgstr "Odesílat tóny DTMF jako SIP INFO zprávy" + +#: ../gtk/parameters.ui.h:57 +msgid "Allow IPv6" +msgstr "" + +#: ../gtk/parameters.ui.h:58 +msgid "Transport" +msgstr "Přenos" + +#: ../gtk/parameters.ui.h:59 +msgid "SIP/UDP port" +msgstr "" + +#: ../gtk/parameters.ui.h:61 +msgid "Random" +msgstr "" + +#: ../gtk/parameters.ui.h:62 +msgid "SIP/TCP port" +msgstr "" + +#: ../gtk/parameters.ui.h:63 +msgid "Audio RTP/UDP:" +msgstr "Zvukový RTP/UDP:" + +#: ../gtk/parameters.ui.h:64 +msgid "Fixed" +msgstr "Stálý" + +#: ../gtk/parameters.ui.h:65 +msgid "Video RTP/UDP:" +msgstr "Obrazový RTP/UDP:" + +#: ../gtk/parameters.ui.h:66 +msgid "Media encryption type" +msgstr "Druh šifrování médií" + +#: ../gtk/parameters.ui.h:67 +msgid "Media encryption is mandatory" +msgstr "Šifrování médií je povinné" + +#: ../gtk/parameters.ui.h:68 +msgid "Tunnel" +msgstr "Tunel" + +#: ../gtk/parameters.ui.h:69 +msgid "DSCP fields" +msgstr "Položky DSCP" + +#: ../gtk/parameters.ui.h:70 +msgid "Network protocol and ports" +msgstr "Síťové protokoly a porty" + +#: ../gtk/parameters.ui.h:71 +msgid "Direct connection to the Internet" +msgstr "Přímé připojení do Internetu" + +#: ../gtk/parameters.ui.h:72 +msgid "Behind NAT / Firewall (specify gateway IP )" +msgstr "" + +#: ../gtk/parameters.ui.h:73 +msgid "Behind NAT / Firewall (use STUN to resolve)" +msgstr "Za NAT/firewallem (adresu určí STUN)" + +#: ../gtk/parameters.ui.h:74 +msgid "Behind NAT / Firewall (use ICE)" +msgstr "Za NAT/firewallem (adresu určí ICE)" + +#: ../gtk/parameters.ui.h:75 +msgid "Behind NAT / Firewall (use uPnP)" +msgstr "Za NAT/firewallem (adresu určí UPnP)" + +#: ../gtk/parameters.ui.h:76 +msgid "Public IP address:" +msgstr "Veřejná IP adresa:" + +#: ../gtk/parameters.ui.h:77 +msgid "Stun server:" +msgstr "STUN server:" + +#: ../gtk/parameters.ui.h:78 +msgid "NAT and Firewall" +msgstr "NAT a firewall" + +#: ../gtk/parameters.ui.h:79 +msgid "Network settings" +msgstr "Nastavení sítě" + +#: ../gtk/parameters.ui.h:80 ../gtk/tunnel_config.ui.h:4 +msgid "Enable" +msgstr "Povolit" + +#: ../gtk/parameters.ui.h:81 ../gtk/tunnel_config.ui.h:5 +msgid "Disable" +msgstr "Zakázat" + +#: ../gtk/parameters.ui.h:82 +msgid "Audio codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:83 +msgid "Video codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:84 +msgid "Codecs" +msgstr "Kodeky" + +#: ../gtk/parameters.ui.h:85 +msgid "Language" +msgstr "Jazyk" + +#: ../gtk/parameters.ui.h:86 +msgid "Show advanced settings" +msgstr "Zobrazit podrobnější nastavení" + +#: ../gtk/parameters.ui.h:87 +msgid "Level" +msgstr "Úroveň" + +#: ../gtk/parameters.ui.h:88 +msgid "User interface" +msgstr "Uživatelské rozhraní" + +#: ../gtk/parameters.ui.h:92 +msgid "LDAP Account setup" +msgstr "" + +#: ../gtk/parameters.ui.h:93 +msgid "LDAP" +msgstr "" + +#: ../gtk/parameters.ui.h:94 +msgid "Done" +msgstr "Hotovo" + +#: ../gtk/password.ui.h:1 +msgid "Linphone - Authentication required" +msgstr "Linphone – Ověření totožnosti vyžadováno" + +#: ../gtk/password.ui.h:2 +msgid "Please enter the domain password" +msgstr "Prosím, zadejte heslo pro doménu" + #: ../gtk/provisioning-fetch.ui.h:1 msgid "Configuring..." msgstr "" @@ -1703,68 +1557,278 @@ msgstr "" msgid "Please wait while fetching configuration from server..." msgstr "" -#: ../coreapi/linphonecore.c:1539 +#: ../gtk/setup_wizard.ui.h:1 +msgid "SIP account configuration assistant" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:2 +msgid "" +"Welcome!\n" +"This assistant will help you to use a SIP account for your calls." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:4 +msgid "Welcome to the account setup assistant" +msgstr "Vítejte v průvodci nastavení účtu" + +#: ../gtk/setup_wizard.ui.h:5 +msgid "Create an account on linphone.org" +msgstr "Vytvořit účet na linphone.org" + +#: ../gtk/setup_wizard.ui.h:6 +msgid "I have already a linphone.org account and I just want to use it" +msgstr "Účet na linphone.org již mám a chci jej použít" + +#: ../gtk/setup_wizard.ui.h:7 +msgid "I have already a sip account and I just want to use it" +msgstr "SIP účet již mám a chci jej použít" + +#: ../gtk/setup_wizard.ui.h:8 +msgid "I want to specify a remote configuration URI" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:9 +msgid "Account setup assistant" +msgstr "Průvodce nastavením účtu" + +#: ../gtk/setup_wizard.ui.h:10 +msgid "Enter your account information" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:11 +msgid "Username*" +msgstr "Uživatelské jméno*" + +#: ../gtk/setup_wizard.ui.h:12 +msgid "Password*" +msgstr "Heslo*" + +#: ../gtk/setup_wizard.ui.h:13 +msgid "Domain*" +msgstr "Doména*" + +#: ../gtk/setup_wizard.ui.h:14 +msgid "Proxy" +msgstr "Proxy" + +#: ../gtk/setup_wizard.ui.h:15 +msgid "Configure your account (step 1/1)" +msgstr "Nastavit účet (krok 1/1)" + +#: ../gtk/setup_wizard.ui.h:16 +msgid "Enter your linphone.org username" +msgstr "Zadejte uživatelské jméno na linphone.org" + +#: ../gtk/setup_wizard.ui.h:19 +msgid "Enter your sip username (step 1/1)" +msgstr "Zadejte vaše sipové uživatelské jméno (krok 1/1)" + +#: ../gtk/setup_wizard.ui.h:20 +msgid "(*) Required fields" +msgstr "(*) Povinné položky" + +#: ../gtk/setup_wizard.ui.h:21 +msgid "Email: (*)" +msgstr "E-mail: (*)" + +#: ../gtk/setup_wizard.ui.h:22 +msgid "Username: (*)" +msgstr "Uživatelské jméno: (*)" + +#: ../gtk/setup_wizard.ui.h:23 +msgid "Password: (*)" +msgstr "Heslo: (*)" + +#: ../gtk/setup_wizard.ui.h:24 +msgid "Confirm your password: (*)" +msgstr "Potvrďte heslo: (*)" + +#: ../gtk/setup_wizard.ui.h:25 +msgid "Keep me informed with linphone updates" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:26 +msgid "Enter account information (step 1/2)" +msgstr "Zadejte údaje o účtu (krok 1/2)" + +#: ../gtk/setup_wizard.ui.h:27 +msgid "Your account is being created, please wait." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:28 +msgid "Account creation in progress" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:29 +msgid "" +"Please validate your account by clicking on the link we just sent you by email.\n" +"Then come back here and press Next button." +msgstr "Prosím, ověřte svůj účet tak, že kliknete na odkaz, který jsme vám právě zaslali e-mailem.\nPak se sem vraťte a stiskněte tlačítko Další." + +#: ../gtk/setup_wizard.ui.h:31 +msgid "Validation (step 2/2)" +msgstr "Ověření (krok 2/2)" + +#: ../gtk/setup_wizard.ui.h:32 +msgid "Checking if your account is been validated, please wait." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:33 +msgid "Account validation check in progress" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:34 +msgid "" +"Error, account not validated, username already used or server unreachable.\n" +"Please go back and try again." +msgstr "Došlo k chybě (účet nebyl ověřen, uživatelské jméno již existuje nebo server není dostupný).\nProsím, vraťte se a zkoste to znovu." + +#: ../gtk/setup_wizard.ui.h:36 +msgid "Error" +msgstr "Chyba" + +#: ../gtk/setup_wizard.ui.h:37 +msgid "Thank you. Your account is now configured and ready for use." +msgstr "Děkujeme vám. Váš účet je nyní nastaven a připraven k použití." + +#: ../gtk/sip_account.ui.h:1 +msgid "Linphone - Configure a SIP account" +msgstr "Linphone – Nastav SIP účet" + +#: ../gtk/sip_account.ui.h:2 +msgid "Your SIP identity:" +msgstr "Vaše SIP totožnost:" + +#: ../gtk/sip_account.ui.h:3 +msgid "Looks like sip:@" +msgstr "Vypadá jako sip:@" + +#: ../gtk/sip_account.ui.h:4 +msgid "sip:" +msgstr "sip:" + +#: ../gtk/sip_account.ui.h:5 +msgid "SIP Proxy address:" +msgstr "Adresa SIP proxy:" + +#: ../gtk/sip_account.ui.h:6 +msgid "Looks like sip:" +msgstr "Vypadá jako sip:" + +#: ../gtk/sip_account.ui.h:7 +msgid "Registration duration (sec):" +msgstr "Registrační období (s):" + +#: ../gtk/sip_account.ui.h:8 +msgid "Contact params (optional):" +msgstr "" + +#: ../gtk/sip_account.ui.h:9 +msgid "AVPF regular RTCP interval (sec):" +msgstr "" + +#: ../gtk/sip_account.ui.h:10 +msgid "Route (optional):" +msgstr "Směrování (volitelné):" + +#: ../gtk/sip_account.ui.h:11 +msgid "Transport" +msgstr "" + +#: ../gtk/sip_account.ui.h:12 +msgid "Register" +msgstr "Zaregistrovat se" + +#: ../gtk/sip_account.ui.h:13 +msgid "Publish presence information" +msgstr "Zveřejnit stav přítomnosti" + +#: ../gtk/sip_account.ui.h:14 +msgid "Enable AVPF" +msgstr "" + +#: ../gtk/sip_account.ui.h:15 +msgid "Configure a SIP account" +msgstr "Nastavit SIP účet" + +#: ../gtk/tunnel_config.ui.h:1 +msgid "Configure VoIP tunnel" +msgstr "Nastavit VoIP tunel" + +#: ../gtk/tunnel_config.ui.h:2 +msgid "Host" +msgstr "Stroj" + +#: ../gtk/tunnel_config.ui.h:3 +msgid "Port" +msgstr "Port" + +#: ../gtk/tunnel_config.ui.h:6 +msgid "Configure tunnel" +msgstr "Nastavit tunel" + +#: ../gtk/tunnel_config.ui.h:9 +msgid "Configure http proxy (optional)" +msgstr "Nastavit HTTP proxy (volitelné)" + +#: ../gtk/waiting.ui.h:2 +msgid "Please wait" +msgstr "Prosím, čekejte" + +#: ../coreapi/linphonecore.c:1560 msgid "Ready" msgstr "Připraven." -#: ../coreapi/linphonecore.c:2551 +#: ../coreapi/linphonecore.c:2556 msgid "Configuring" msgstr "" -#: ../coreapi/linphonecore.c:2725 -msgid "Looking for telephone number destination..." -msgstr "Vyhledává se umístění čísla…" - -#: ../coreapi/linphonecore.c:2727 -msgid "Could not resolve this number." -msgstr "Toto číslo nelze vyhledat." - #. must be known at that time -#: ../coreapi/linphonecore.c:3013 +#: ../coreapi/linphonecore.c:2951 msgid "Contacting" msgstr "Navazuje se spojení" -#: ../coreapi/linphonecore.c:3018 +#: ../coreapi/linphonecore.c:2956 msgid "Could not call" msgstr "Nelze volat" -#: ../coreapi/linphonecore.c:3169 +#: ../coreapi/linphonecore.c:3092 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:3327 +#: ../coreapi/linphonecore.c:3250 msgid "is contacting you" msgstr "vás volá" -#: ../coreapi/linphonecore.c:3328 +#: ../coreapi/linphonecore.c:3251 msgid " and asked autoanswer." msgstr " a požaduje automatickou zvednutí." -#: ../coreapi/linphonecore.c:3452 +#: ../coreapi/linphonecore.c:3377 msgid "Modifying call parameters..." msgstr "Upravují se parametry hovoru…" -#: ../coreapi/linphonecore.c:3802 +#: ../coreapi/linphonecore.c:3769 msgid "Connected." msgstr "Připojeno." -#: ../coreapi/linphonecore.c:3827 +#: ../coreapi/linphonecore.c:3794 msgid "Call aborted" msgstr "Hovor přerušen" -#: ../coreapi/linphonecore.c:4024 +#: ../coreapi/linphonecore.c:3983 msgid "Could not pause the call" msgstr "Hovor nebylo možné odložit" -#: ../coreapi/linphonecore.c:4027 +#: ../coreapi/linphonecore.c:3986 msgid "Pausing the current call..." msgstr "Současný hovor se odkládá…" -#: ../coreapi/misc.c:434 +#: ../coreapi/misc.c:440 msgid "Stun lookup in progress..." msgstr "Hledá se adresa pomocí STUN…" -#: ../coreapi/misc.c:615 +#: ../coreapi/misc.c:650 msgid "ICE local candidates gathering in progress..." msgstr "Shromažďují se místní kandidáti ICE…" @@ -1820,143 +1884,150 @@ msgstr "" msgid "Unknown status" msgstr "" -#: ../coreapi/proxy.c:328 +#: ../coreapi/proxy.c:292 msgid "" "The sip proxy address you entered is invalid, it must start with \"sip:\" " "followed by a hostname." msgstr "Adresa SIP proxy, kterou jste zadali, není platná. Musí začínat na „sip:“ a pak musí následovat jméno stroje." -#: ../coreapi/proxy.c:334 +#: ../coreapi/proxy.c:298 msgid "" "The sip identity you entered is invalid.\n" "It should look like sip:username@proxydomain, such as sip:alice@example.net" msgstr "SIP identita, kterou jste zadali, není platná.\nMěla by mít tvar sip:uživatel@proxydoména, například sip:alice@example.net" -#: ../coreapi/proxy.c:1416 +#: ../coreapi/proxy.c:927 +msgid "Looking for telephone number destination..." +msgstr "Vyhledává se umístění čísla…" + +#: ../coreapi/proxy.c:931 +msgid "Could not resolve this number." +msgstr "Toto číslo nelze vyhledat." + +#: ../coreapi/proxy.c:1324 #, c-format msgid "Could not login as %s" msgstr "Nelze se přihlásit jako %s" -#: ../coreapi/callbacks.c:428 +#: ../coreapi/proxy.c:1411 +#, c-format +msgid "Refreshing on %s..." +msgstr "" + +#: ../coreapi/callbacks.c:423 msgid "Remote ringing." msgstr "Vyzvání na druhé straně." -#: ../coreapi/callbacks.c:440 +#: ../coreapi/callbacks.c:435 msgid "Remote ringing..." msgstr "Vyzvání na druhé straně…" -#: ../coreapi/callbacks.c:461 +#: ../coreapi/callbacks.c:458 msgid "Early media." msgstr "Časná média." -#: ../coreapi/callbacks.c:534 +#: ../coreapi/callbacks.c:488 #, c-format -msgid "Call with %s is paused." -msgstr "Hovor s %s je odložen." +msgid "Call answered by %s" +msgstr "" -#: ../coreapi/callbacks.c:547 -#, c-format -msgid "Call answered by %s - on hold." -msgstr "Hovor přijat kým: %s – odložen." - -#: ../coreapi/callbacks.c:557 +#: ../coreapi/callbacks.c:527 msgid "Call resumed." msgstr "Hovor obnoven." -#: ../coreapi/callbacks.c:561 -#, c-format -msgid "Call answered by %s." -msgstr "Hovor přijat kým: %s." - -#: ../coreapi/callbacks.c:584 +#: ../coreapi/callbacks.c:582 msgid "Incompatible, check codecs or security settings..." msgstr "Není slučitelné. Zkontrolujte nastavení kodeků a zabezpečení…" -#: ../coreapi/callbacks.c:589 ../coreapi/callbacks.c:906 +#: ../coreapi/callbacks.c:587 ../coreapi/callbacks.c:923 msgid "Incompatible media parameters." msgstr "Neslučitelné parametry médií." -#: ../coreapi/callbacks.c:619 +#: ../coreapi/callbacks.c:612 msgid "We have been resumed." msgstr "Byli jsme obnoveni." #. we are being paused -#: ../coreapi/callbacks.c:628 +#: ../coreapi/callbacks.c:620 msgid "We are paused by other party." msgstr "Byli jsme odloženi protistranou." -#. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:666 +#: ../coreapi/callbacks.c:630 msgid "Call is updated by remote." msgstr "Hovor byl aktualizován protistranou." -#: ../coreapi/callbacks.c:782 +#: ../coreapi/callbacks.c:799 msgid "Call terminated." msgstr "Hovor ukončen." -#: ../coreapi/callbacks.c:810 +#: ../coreapi/callbacks.c:827 msgid "User is busy." msgstr "Uživatel je zaneprázdněn." -#: ../coreapi/callbacks.c:811 +#: ../coreapi/callbacks.c:828 msgid "User is temporarily unavailable." msgstr "Uživatel je dočasně nedostupný." #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:813 +#: ../coreapi/callbacks.c:830 msgid "User does not want to be disturbed." msgstr "Uživatel si nepřeje být rušen." -#: ../coreapi/callbacks.c:814 +#: ../coreapi/callbacks.c:831 msgid "Call declined." msgstr "Volání odmítnuto." -#: ../coreapi/callbacks.c:829 +#: ../coreapi/callbacks.c:846 msgid "Request timeout." msgstr "" -#: ../coreapi/callbacks.c:860 +#: ../coreapi/callbacks.c:877 msgid "Redirected" msgstr "Přesměrováno" -#: ../coreapi/callbacks.c:915 +#: ../coreapi/callbacks.c:927 msgid "Call failed." msgstr "Volání se nezdařilo." -#: ../coreapi/callbacks.c:993 +#: ../coreapi/callbacks.c:1005 #, c-format msgid "Registration on %s successful." msgstr "Registrace na %s byla úspěšná." -#: ../coreapi/callbacks.c:994 +#: ../coreapi/callbacks.c:1006 #, c-format msgid "Unregistration on %s done." msgstr "Odregistrování z %s hotovo." -#: ../coreapi/callbacks.c:1012 +#: ../coreapi/callbacks.c:1024 msgid "no response timeout" msgstr "odpověď nedorazila včas" -#: ../coreapi/callbacks.c:1015 +#: ../coreapi/callbacks.c:1027 #, c-format msgid "Registration on %s failed: %s" msgstr "Registrace na %s selhala: %s" -#: ../coreapi/callbacks.c:1022 +#: ../coreapi/callbacks.c:1034 msgid "Service unavailable, retrying" msgstr "" #. if encryption is DTLS, no status to be displayed -#: ../coreapi/linphonecall.c:180 +#: ../coreapi/linphonecall.c:197 #, c-format msgid "Authentication token is %s" msgstr "Klíč k ověření totožnosti je %s" -#: ../coreapi/linphonecall.c:1310 +#: ../coreapi/linphonecall.c:1561 +#, c-format +msgid "Call parameters could not be modified: %s." +msgstr "" + +#: ../coreapi/linphonecall.c:1563 msgid "Call parameters were successfully modified." msgstr "" -#: ../coreapi/linphonecall.c:3686 +#: ../coreapi/linphonecall.c:4396 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." @@ -1964,23 +2035,23 @@ msgstr[0] "Máte %i zmeškaný hovor." msgstr[1] "Máte %i zmeškané hovory." msgstr[2] "Máte %i zmeškaných hovorů." -#: ../coreapi/call_log.c:209 +#: ../coreapi/call_log.c:223 msgid "aborted" msgstr "" -#: ../coreapi/call_log.c:212 +#: ../coreapi/call_log.c:226 msgid "completed" msgstr "" -#: ../coreapi/call_log.c:215 +#: ../coreapi/call_log.c:229 msgid "missed" msgstr "" -#: ../coreapi/call_log.c:218 +#: ../coreapi/call_log.c:232 msgid "unknown" msgstr "" -#: ../coreapi/call_log.c:220 +#: ../coreapi/call_log.c:234 #, c-format msgid "" "%s at %s\n" @@ -1990,7 +2061,7 @@ msgid "" "Duration: %i mn %i sec\n" msgstr "" -#: ../coreapi/call_log.c:221 +#: ../coreapi/call_log.c:235 msgid "Outgoing call" msgstr "" diff --git a/po/de.po b/po/de.po index 6a6e30e83..34487194e 100644 --- a/po/de.po +++ b/po/de.po @@ -5,80 +5,90 @@ # Translators: # andreas, 2014 # andreas, 2014 +# Ettore Atalan , 2015 # Gerhard Stengel , 2011-2012 # Simon Morlat , 2001 msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-04-30 10:13+0200\n" -"PO-Revision-Date: 2015-04-30 08:13+0000\n" +"POT-Creation-Date: 2015-11-10 15:16+0100\n" +"PO-Revision-Date: 2015-11-10 14:16+0000\n" "Last-Translator: Belledonne Communications \n" -"Language-Team: German (http://www.transifex.com/projects/p/linphone-gtk/language/de/)\n" +"Language-Team: German (http://www.transifex.com/belledonne-communications/linphone-gtk/language/de/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: de\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ../gtk/calllogs.c:148 ../gtk/friendlist.c:974 +#: ../gtk/calllogs.c:178 #, c-format msgid "Call %s" msgstr "„%s“ anrufen" -#: ../gtk/calllogs.c:149 ../gtk/friendlist.c:975 +#: ../gtk/calllogs.c:179 #, c-format msgid "Send text to %s" msgstr "Text zu „%s“ schicken" -#: ../gtk/calllogs.c:232 +#: ../gtk/calllogs.c:181 +#, c-format +msgid "Add %s to your contact list" +msgstr "%s zu Ihrer Kontaktliste hinzufügen" + +#: ../gtk/calllogs.c:245 ../gtk/main.ui.h:21 +msgid "Recent calls" +msgstr "Letzte Gespräche" + +#: ../gtk/calllogs.c:260 #, c-format msgid "Recent calls (%i)" -msgstr "letzte Anrufe (%i)" +msgstr "Letzte Anrufe (%i)" -#: ../gtk/calllogs.c:314 +#: ../gtk/calllogs.c:331 msgid "n/a" -msgstr "nicht verfügbar" +msgstr "n/v" -#: ../gtk/calllogs.c:317 +#: ../gtk/calllogs.c:334 msgid "Aborted" msgstr "Abgebrochen" -#: ../gtk/calllogs.c:320 +#: ../gtk/calllogs.c:337 msgid "Missed" -msgstr "Entgangen" +msgstr "Verpasst" -#: ../gtk/calllogs.c:323 +#: ../gtk/calllogs.c:340 msgid "Declined" msgstr "Abgewiesen" -#: ../gtk/calllogs.c:329 +#: ../gtk/calllogs.c:346 #, c-format msgid "%i minute" msgid_plural "%i minutes" msgstr[0] "%i Minute" msgstr[1] "%i Minuten" -#: ../gtk/calllogs.c:332 +#: ../gtk/calllogs.c:349 #, c-format msgid "%i second" msgid_plural "%i seconds" msgstr[0] "%i Sekunde" msgstr[1] "%i Sekunden" -#: ../gtk/calllogs.c:337 +#: ../gtk/calllogs.c:354 #, c-format msgid "" "%s\tQuality: %s\n" "%s\t%s\t" msgstr "%s\tQualität: %s\n%s\t%s\t" -#: ../gtk/calllogs.c:341 +#: ../gtk/calllogs.c:358 #, c-format msgid "%s\t%s" msgstr "%s\t%s" -#: ../gtk/conference.c:38 ../gtk/main.ui.h:13 +#: ../gtk/conference.c:38 ../gtk/in_call_frame.ui.h:11 msgid "Conference" msgstr "Konferenz" @@ -91,297 +101,314 @@ msgstr "Eigenes Telefon" msgid "Couldn't find pixmap file: %s" msgstr "Pixmapdatei %s kann nicht gefunden werden." -#: ../gtk/main.c:137 +#: ../gtk/chat.c:196 ../gtk/chat.c:254 +msgid "Sending..." +msgstr "Sendevorgang..." + +#: ../gtk/chat.c:213 ../gtk/chat.c:263 +msgid "Message not sent" +msgstr "Nachricht nicht gesendet" + +#: ../gtk/chat.c:472 +msgid "Copy" +msgstr "Kopieren" + +#: ../gtk/main.c:138 msgid "log to stdout some debug information while running." msgstr "Ausgabe von Debug-Informationen auf stdout während der Laufzeit" -#: ../gtk/main.c:138 +#: ../gtk/main.c:139 +msgid "display version and exit." +msgstr "Version anzeigen und beenden." + +#: ../gtk/main.c:140 msgid "path to a file to write logs into." msgstr "Pfad zu einer Datei, in die Protokolle geschrieben werden." -#: ../gtk/main.c:139 +#: ../gtk/main.c:141 msgid "Start linphone with video disabled." msgstr "Linphone mit ausgeschaltetem Video starten." -#: ../gtk/main.c:140 +#: ../gtk/main.c:142 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:141 +#: ../gtk/main.c:143 msgid "address to call right now" msgstr "Im Moment anzurufende Adresse" -#: ../gtk/main.c:142 +#: ../gtk/main.c:144 msgid "" "Specifiy a working directory (should be the base of the installation, eg: " "c:\\Program Files\\Linphone)" msgstr "Geben Sie einen Arbeitsordner an (sollte der Installationsordner sein, z. B. C:\\Programme\\Linphone)" -#: ../gtk/main.c:143 +#: ../gtk/main.c:145 msgid "Configuration file" msgstr "Konfigurationsdatei" -#: ../gtk/main.c:144 +#: ../gtk/main.c:146 msgid "Run the audio assistant" msgstr "Starte den Audio-Assistent" -#: ../gtk/main.c:145 +#: ../gtk/main.c:147 msgid "Run self test and exit 0 if succeed" -msgstr "" +msgstr "Selbsttest ausführen und mit 0 beenden, wenn erfolgreich" -#: ../gtk/main.c:1070 +#: ../gtk/main.c:1046 #, c-format msgid "" -"%s would like to add you to his contact list.\n" -"Would you allow him to see your presence status or add him to your contact list ?\n" +"%s would like to add you to his/her contact list.\n" +"Would you add him/her to your contact list and allow him/her to see your presence status?\n" "If you answer no, this person will be temporarily blacklisted." -msgstr "%s möchte Sie zu seiner Kontaktliste hinzufügen.\nMöchten Sie ihm erlauben, Ihren Anwesenheitsstatus zu sehen, oder ihn zu Ihrer Kontaktliste hinzufügen?\nWenn Sie mit Nein antworten, wird diese Person vorläufig blockiert." +msgstr "" -#: ../gtk/main.c:1147 +#: ../gtk/main.c:1123 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" msgstr "Bitte geben Sie Ihr Passwort für den Benutzernamen %s\n für Bereich %s ein:" -#: ../gtk/main.c:1268 +#: ../gtk/main.c:1253 msgid "Call error" msgstr "Anruf fehlgeschlagen" -#: ../gtk/main.c:1271 ../coreapi/linphonecore.c:3846 +#: ../gtk/main.c:1256 ../coreapi/linphonecore.c:3813 msgid "Call ended" msgstr "Anruf beendet" -#: ../gtk/main.c:1274 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1259 ../coreapi/call_log.c:235 msgid "Incoming call" msgstr "Eingehender Anruf" -#: ../gtk/main.c:1276 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1261 ../gtk/incall_view.c:580 ../gtk/in_call_frame.ui.h:2 msgid "Answer" msgstr "Annehmen" -#: ../gtk/main.c:1278 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1263 ../gtk/in_call_frame.ui.h:3 msgid "Decline" msgstr "Abweisen" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 msgid "Call paused" msgstr "Anruf wird gehalten" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 #, c-format msgid "by %s" msgstr "von %s" -#: ../gtk/main.c:1354 +#: ../gtk/main.c:1339 #, 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:1509 +#: ../gtk/main.c:1505 msgid "Website link" msgstr "Website-Verknüpfung" -#: ../gtk/main.c:1568 ../gtk/waiting.ui.h:1 +#: ../gtk/main.c:1564 ../gtk/waiting.ui.h:1 msgid "Linphone" msgstr "Linphone" -#: ../gtk/main.c:1569 +#: ../gtk/main.c:1565 msgid "A video internet phone" -msgstr "" +msgstr "Ein Internet-Video-Telefon" -#: ../gtk/main.c:1629 +#: ../gtk/main.c:1624 #, c-format msgid "%s (Default)" msgstr "%s (Vorgabe)" -#: ../gtk/main.c:1962 ../coreapi/callbacks.c:1063 +#: ../gtk/main.c:1960 ../coreapi/callbacks.c:1075 #, c-format msgid "We are transferred to %s" msgstr "Vermittlung nach %s" -#: ../gtk/main.c:1972 +#: ../gtk/main.c:1970 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." msgstr "Auf diesem Rechner können keine Soundkarten gefunden werden.\nSie können keine Audio-Anrufe tätigen oder entgegennehmen." -#: ../gtk/main.c:2117 +#: ../gtk/main.c:2129 msgid "A free SIP video-phone" msgstr "Ein freies SIP-Video-Telefon" -#: ../gtk/main.c:2221 +#: ../gtk/main.c:2242 #, c-format msgid "Hello\n" -msgstr "" +msgstr "Hallo\n" -#: ../gtk/friendlist.c:505 +#: ../gtk/friendlist.c:461 msgid "Add to addressbook" msgstr "Zum Adressbuch hinzufügen" -#: ../gtk/friendlist.c:691 -msgid "Presence status" -msgstr "Anwesenheitsstatus" - -#: ../gtk/friendlist.c:709 ../gtk/propertybox.c:569 ../gtk/contact.ui.h:1 -msgid "Name" -msgstr "Name" - -#: ../gtk/friendlist.c:721 -msgid "Call" -msgstr "Anrufen" - -#: ../gtk/friendlist.c:726 -msgid "Chat" -msgstr "Chat" - -#: ../gtk/friendlist.c:756 +#: ../gtk/friendlist.c:627 #, c-format msgid "Search in %s directory" msgstr "Im %s-Verzeichnis suchen" -#: ../gtk/friendlist.c:924 +#: ../gtk/friendlist.c:772 msgid "Invalid sip contact !" msgstr "Ungültiger SIP-Kontakt!" -#: ../gtk/friendlist.c:976 +#: ../gtk/friendlist.c:820 +#, c-format +msgid "Add a new contact" +msgstr "Neuen Kontakt hinzufügen" + +#: ../gtk/friendlist.c:823 #, c-format msgid "Edit contact '%s'" msgstr "Kontakt „%s“ bearbeiten" -#: ../gtk/friendlist.c:977 +#: ../gtk/friendlist.c:824 #, c-format msgid "Delete contact '%s'" msgstr "Kontakt „%s“ löschen" -#: ../gtk/friendlist.c:978 +#: ../gtk/friendlist.c:825 #, c-format msgid "Delete chat history of '%s'" msgstr "Lösche Gesprächshistorie von '%s'" -#: ../gtk/friendlist.c:1029 +#: ../gtk/friendlist.c:862 #, c-format msgid "Add new contact from %s directory" msgstr "Einen neuen Kontakt aus dem %s-Verzeichnis hinzufügen" -#: ../gtk/propertybox.c:575 +#: ../gtk/propertybox.c:592 ../gtk/contact.ui.h:1 +msgid "Name" +msgstr "Name" + +#: ../gtk/propertybox.c:598 msgid "Rate (Hz)" msgstr "Rate (Hz)" -#: ../gtk/propertybox.c:581 +#: ../gtk/propertybox.c:604 msgid "Status" msgstr "Status" -#: ../gtk/propertybox.c:587 +#: ../gtk/propertybox.c:617 msgid "IP Bitrate (kbit/s)" msgstr "IP Bit-Rate (kbit/s)" -#: ../gtk/propertybox.c:596 +#: ../gtk/propertybox.c:628 msgid "Parameters" msgstr "Parameter" -#: ../gtk/propertybox.c:639 ../gtk/propertybox.c:782 +#: ../gtk/propertybox.c:670 ../gtk/propertybox.c:824 msgid "Enabled" msgstr "Freigegeben" -#: ../gtk/propertybox.c:641 ../gtk/propertybox.c:782 ../gtk/parameters.ui.h:20 +#: ../gtk/propertybox.c:672 ../gtk/propertybox.c:824 ../gtk/parameters.ui.h:60 msgid "Disabled" msgstr "Gesperrt" -#: ../gtk/propertybox.c:828 +#: ../gtk/propertybox.c:902 msgid "Account" msgstr "Konto" -#: ../gtk/propertybox.c:1091 +#: ../gtk/propertybox.c:1170 msgid "English" msgstr "Englisch" -#: ../gtk/propertybox.c:1092 +#: ../gtk/propertybox.c:1171 msgid "French" msgstr "Französisch" -#: ../gtk/propertybox.c:1093 +#: ../gtk/propertybox.c:1172 msgid "Swedish" msgstr "Schwedisch" -#: ../gtk/propertybox.c:1094 +#: ../gtk/propertybox.c:1173 msgid "Italian" msgstr "Italienisch" -#: ../gtk/propertybox.c:1095 +#: ../gtk/propertybox.c:1174 msgid "Spanish" msgstr "Spanisch" -#: ../gtk/propertybox.c:1096 +#: ../gtk/propertybox.c:1175 msgid "Brazilian Portugese" msgstr "Brasilianisches Portugiesisch" -#: ../gtk/propertybox.c:1097 +#: ../gtk/propertybox.c:1176 msgid "Polish" msgstr "Polnisch" -#: ../gtk/propertybox.c:1098 +#: ../gtk/propertybox.c:1177 msgid "German" msgstr "Deutsch" -#: ../gtk/propertybox.c:1099 +#: ../gtk/propertybox.c:1178 msgid "Russian" msgstr "Russisch" -#: ../gtk/propertybox.c:1100 +#: ../gtk/propertybox.c:1179 msgid "Japanese" msgstr "Japanisch" -#: ../gtk/propertybox.c:1101 +#: ../gtk/propertybox.c:1180 msgid "Dutch" msgstr "Niederländisch" -#: ../gtk/propertybox.c:1102 +#: ../gtk/propertybox.c:1181 msgid "Hungarian" msgstr "Ungarisch" -#: ../gtk/propertybox.c:1103 +#: ../gtk/propertybox.c:1182 msgid "Czech" msgstr "Tschechisch" -#: ../gtk/propertybox.c:1104 +#: ../gtk/propertybox.c:1183 msgid "Chinese" msgstr "Chinesisch" -#: ../gtk/propertybox.c:1105 +#: ../gtk/propertybox.c:1184 msgid "Traditional Chinese" msgstr "Traditionelles Chinesisch" -#: ../gtk/propertybox.c:1106 +#: ../gtk/propertybox.c:1185 msgid "Norwegian" msgstr "Norwegisch" -#: ../gtk/propertybox.c:1107 +#: ../gtk/propertybox.c:1186 msgid "Hebrew" msgstr "Hebräisch" -#: ../gtk/propertybox.c:1108 +#: ../gtk/propertybox.c:1187 msgid "Serbian" msgstr "Serbisch" -#: ../gtk/propertybox.c:1175 +#: ../gtk/propertybox.c:1188 +msgid "Arabic" +msgstr "Arabisch" + +#: ../gtk/propertybox.c:1189 +msgid "Turkish" +msgstr "Türkisch" + +#: ../gtk/propertybox.c:1246 msgid "" "You need to restart linphone for the new language selection to take effect." msgstr "Linphone muss neu gestartet werden, damit die neue Spracheinstellung wirksam wird." -#: ../gtk/propertybox.c:1255 +#: ../gtk/propertybox.c:1326 msgid "None" msgstr "Keinen" -#: ../gtk/propertybox.c:1259 +#: ../gtk/propertybox.c:1330 msgid "SRTP" msgstr "SRTP" -#: ../gtk/propertybox.c:1265 +#: ../gtk/propertybox.c:1336 msgid "DTLS" -msgstr "" +msgstr "DTLS" -#: ../gtk/propertybox.c:1272 +#: ../gtk/propertybox.c:1343 msgid "ZRTP" msgstr "ZRTP" @@ -423,324 +450,195 @@ msgid_plural "Found %i contacts" msgstr[0] "%i Kontakt gefunden" msgstr[1] "%i Kontakte gefunden" -#: ../gtk/setupwizard.c:32 -msgid "" -"Welcome!\n" -"This assistant will help you to use a SIP account for your calls." -msgstr "Willkommen!\nDieser Assistent hilft Ihnen dabei ein SIP-Konto einzurichten." - -#: ../gtk/setupwizard.c:41 -msgid "Create an account on linphone.org" -msgstr "Ein Konto bei linphone.org erstellen." - -#: ../gtk/setupwizard.c:42 -msgid "I have already a linphone.org account and I just want to use it" -msgstr "Ich habe bereits ein Konto bei linphone.org und möchte es jetzt benutzen." - -#: ../gtk/setupwizard.c:43 -msgid "I have already a sip account and I just want to use it" -msgstr "Ich habe bereits ein SIP-Konto und möchte es jetzt benutzen." - -#: ../gtk/setupwizard.c:44 -msgid "I want to specify a remote configuration URI" -msgstr "Ich möchte eine URI zur Fernkonfiguration angeben" - -#: ../gtk/setupwizard.c:87 -msgid "Enter your linphone.org username" -msgstr "Geben Sie Ihren Benutzernamen bei linphone.org ein." - -#: ../gtk/setupwizard.c:100 ../gtk/parameters.ui.h:85 ../gtk/ldap.ui.h:4 -msgid "Username:" -msgstr "Benutzername:" - -#: ../gtk/setupwizard.c:102 ../gtk/password.ui.h:4 ../gtk/ldap.ui.h:5 -msgid "Password:" -msgstr "Passwort:" - -#: ../gtk/setupwizard.c:122 -msgid "Enter your account informations" -msgstr "Geben Sie Ihre Zugangsdaten ein." - -#: ../gtk/setupwizard.c:138 -msgid "Username*" -msgstr "Benutzername*" - -#: ../gtk/setupwizard.c:139 -msgid "Password*" -msgstr "Passwort*" - -#: ../gtk/setupwizard.c:142 -msgid "Domain*" -msgstr "Domäne*" - -#: ../gtk/setupwizard.c:143 -msgid "Proxy" -msgstr "Proxy" - -#: ../gtk/setupwizard.c:322 -msgid "(*) Required fields" -msgstr "(*) erforderliche Felder" - -#: ../gtk/setupwizard.c:323 -msgid "Username: (*)" -msgstr "Benutzername: (*)" - -#: ../gtk/setupwizard.c:325 -msgid "Password: (*)" -msgstr "Passwort: (*)" - -#: ../gtk/setupwizard.c:327 -msgid "Email: (*)" -msgstr "E-Mail: (*)" - -#: ../gtk/setupwizard.c:329 -msgid "Confirm your password: (*)" -msgstr "Bestätigen Sie Ihr Passwort: (*)" - -#: ../gtk/setupwizard.c:343 -msgid "Keep me informed with linphone updates" -msgstr "Halte mich über linphone Aktualisierungen auf dem laufenden" - -#: ../gtk/setupwizard.c:399 -msgid "" -"Error, account not validated, username already used or server unreachable.\n" -"Please go back and try again." -msgstr "Fehler, Konto kann nicht bestätigt werden. Der Benutzername wird bereits\nverwendet oder der Server ist unerreichbar.\nBitte gehen Sie zurück und versuchen Sie es noch einmal." - -#: ../gtk/setupwizard.c:410 -msgid "Thank you. Your account is now configured and ready for use." -msgstr "Danke. Ihr Konto ist nun fertig eingerichtet und kann verwendet werden." - -#: ../gtk/setupwizard.c:418 -msgid "" -"Please validate your account by clicking on the link we just sent you by email.\n" -"Then come back here and press Next button." -msgstr "Bitte bestätigen Sie Ihr Konto, indem Sie auf die Verknüpfung klicken, die wir Ihnen soeben per E-Mail geschickt haben.\nDanach gehen Sie hierher zurück und drücken auf „Vor“." - -#: ../gtk/setupwizard.c:609 -msgid "SIP account configuration assistant" -msgstr "SIP-Konto-Einrichtungsassistent" - -#: ../gtk/setupwizard.c:629 -msgid "Welcome to the account setup assistant" -msgstr "Willkommen zum Konto-Einrichtungsassistenten" - -#: ../gtk/setupwizard.c:634 -msgid "Account setup assistant" -msgstr "Konto-Einrichtungsassistent" - -#: ../gtk/setupwizard.c:640 -msgid "Configure your account (step 1/1)" -msgstr "Konto einrichten (Schritt 1/1)" - -#: ../gtk/setupwizard.c:645 -msgid "Enter your sip username (step 1/1)" -msgstr "Geben Sie Ihren SIP-Benutzernamen ein (Schritt 1/1)" - -#: ../gtk/setupwizard.c:649 -msgid "Enter account information (step 1/2)" -msgstr "Geben Sie Ihre Zugangsdaten ein (Schritt 1/2)" - -#: ../gtk/setupwizard.c:658 -msgid "Validation (step 2/2)" -msgstr "Bestätigung (Schritt 2/2)" - -#: ../gtk/setupwizard.c:663 -msgid "Error" -msgstr "Fehler" - -#: ../gtk/setupwizard.c:667 ../gtk/audio_assistant.c:534 -msgid "Terminating" -msgstr "Fertigstellen" - -#: ../gtk/incall_view.c:70 ../gtk/incall_view.c:94 +#: ../gtk/incall_view.c:67 ../gtk/incall_view.c:87 #, c-format msgid "Call #%i" msgstr "Anruf #%i" -#: ../gtk/incall_view.c:155 +#: ../gtk/incall_view.c:145 #, c-format msgid "Transfer to call #%i with %s" msgstr "Vermittlung zum Anruf #%i mit %s" -#: ../gtk/incall_view.c:211 ../gtk/incall_view.c:214 +#: ../gtk/incall_view.c:202 ../gtk/incall_view.c:205 msgid "Not used" msgstr "Nicht verwendet" -#: ../gtk/incall_view.c:221 +#: ../gtk/incall_view.c:212 msgid "ICE not activated" msgstr "ICE nicht aktiviert" -#: ../gtk/incall_view.c:223 +#: ../gtk/incall_view.c:214 msgid "ICE failed" msgstr "ICE fehlgeschlagen" -#: ../gtk/incall_view.c:225 +#: ../gtk/incall_view.c:216 msgid "ICE in progress" msgstr "ICE läuft" -#: ../gtk/incall_view.c:227 +#: ../gtk/incall_view.c:218 msgid "Going through one or more NATs" msgstr "Ein oder mehrere NATs werden durchquert" -#: ../gtk/incall_view.c:229 +#: ../gtk/incall_view.c:220 msgid "Direct" msgstr "Direkt" -#: ../gtk/incall_view.c:231 +#: ../gtk/incall_view.c:222 msgid "Through a relay server" msgstr "Über einen Relay-Server" -#: ../gtk/incall_view.c:239 +#: ../gtk/incall_view.c:230 msgid "uPnP not activated" msgstr "uPnP nicht aktiviert" -#: ../gtk/incall_view.c:241 +#: ../gtk/incall_view.c:232 msgid "uPnP in progress" msgstr "uPnP läuft" -#: ../gtk/incall_view.c:243 +#: ../gtk/incall_view.c:234 msgid "uPnp not available" msgstr "uPnp nicht verfügbar" -#: ../gtk/incall_view.c:245 +#: ../gtk/incall_view.c:236 msgid "uPnP is running" msgstr "uPnP läuft" -#: ../gtk/incall_view.c:247 +#: ../gtk/incall_view.c:238 msgid "uPnP failed" msgstr "uPnP fehlgeschlagen" -#: ../gtk/incall_view.c:257 ../gtk/incall_view.c:258 +#: ../gtk/incall_view.c:248 ../gtk/incall_view.c:249 msgid "Direct or through server" msgstr "Direkt oder über Server" -#: ../gtk/incall_view.c:267 ../gtk/incall_view.c:279 +#: ../gtk/incall_view.c:258 ../gtk/incall_view.c:270 #, c-format msgid "" "download: %f\n" "upload: %f (kbit/s)" msgstr "Herunterladen: %f\nHochladen: %f (kbit/s)" -#: ../gtk/incall_view.c:272 ../gtk/incall_view.c:274 +#: ../gtk/incall_view.c:263 ../gtk/incall_view.c:265 #, c-format msgid "%ix%i @ %f fps" msgstr "%ix%i @ %f bps" -#: ../gtk/incall_view.c:304 +#: ../gtk/incall_view.c:295 #, c-format msgid "%.3f seconds" msgstr "%.3f Sekunden" -#: ../gtk/incall_view.c:407 ../gtk/main.ui.h:12 ../gtk/videowindow.c:235 +#: ../gtk/incall_view.c:453 ../gtk/in_call_frame.ui.h:10 +#: ../gtk/videowindow.c:236 msgid "Hang up" msgstr "Auflegen" -#: ../gtk/incall_view.c:511 +#: ../gtk/incall_view.c:559 msgid "Calling..." msgstr "Verbindungsaufbau..." -#: ../gtk/incall_view.c:514 ../gtk/incall_view.c:733 -msgid "00::00::00" -msgstr "00::00::00" +#: ../gtk/incall_view.c:562 ../gtk/incall_view.c:792 +msgid "00:00:00" +msgstr "00:00:00" -#: ../gtk/incall_view.c:525 +#: ../gtk/incall_view.c:573 msgid "Incoming call" msgstr "Eingehender Anruf" -#: ../gtk/incall_view.c:562 +#: ../gtk/incall_view.c:610 msgid "good" msgstr "gut" -#: ../gtk/incall_view.c:564 +#: ../gtk/incall_view.c:612 msgid "average" msgstr "durchschnittlich" -#: ../gtk/incall_view.c:566 +#: ../gtk/incall_view.c:614 msgid "poor" msgstr "schlecht" -#: ../gtk/incall_view.c:568 +#: ../gtk/incall_view.c:616 msgid "very poor" msgstr "sehr schlecht" -#: ../gtk/incall_view.c:570 +#: ../gtk/incall_view.c:618 msgid "too bad" msgstr "zu schlecht" -#: ../gtk/incall_view.c:571 ../gtk/incall_view.c:587 +#: ../gtk/incall_view.c:619 ../gtk/incall_view.c:635 msgid "unavailable" msgstr "nicht verfügbar" -#: ../gtk/incall_view.c:679 +#: ../gtk/incall_view.c:731 msgid "Secured by SRTP" msgstr "Gesichert durch SRTP" -#: ../gtk/incall_view.c:685 +#: ../gtk/incall_view.c:737 msgid "Secured by DTLS" -msgstr "" +msgstr "Gesichert durch DTLS" -#: ../gtk/incall_view.c:691 +#: ../gtk/incall_view.c:743 #, c-format msgid "Secured by ZRTP - [auth token: %s]" msgstr "Gesichert durch ZRTP - [Auth.-Token: %s]" -#: ../gtk/incall_view.c:697 +#: ../gtk/incall_view.c:747 msgid "Set unverified" msgstr "Auf „Ungeprüft“ setzen" -#: ../gtk/incall_view.c:697 ../gtk/main.ui.h:4 +#: ../gtk/incall_view.c:747 msgid "Set verified" msgstr "Auf „Geprüft“ setzen" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In conference" msgstr "In Konferenz" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In call" msgstr "Im Gespräch" -#: ../gtk/incall_view.c:764 +#: ../gtk/incall_view.c:824 msgid "Paused call" msgstr "Gehaltener Anruf" -#: ../gtk/incall_view.c:800 +#: ../gtk/incall_view.c:861 msgid "Call ended." msgstr "Anruf beendet." -#: ../gtk/incall_view.c:831 +#: ../gtk/incall_view.c:892 msgid "Transfer in progress" msgstr "Vermittlung läuft" -#: ../gtk/incall_view.c:834 +#: ../gtk/incall_view.c:895 msgid "Transfer done." msgstr "Vermittlung abgeschlossen." -#: ../gtk/incall_view.c:837 +#: ../gtk/incall_view.c:898 msgid "Transfer failed." msgstr "Vermittlung fehlgeschlagen." -#: ../gtk/incall_view.c:881 +#: ../gtk/incall_view.c:929 msgid "Resume" msgstr "Fortsetzen" -#: ../gtk/incall_view.c:888 ../gtk/main.ui.h:9 +#: ../gtk/incall_view.c:929 ../gtk/in_call_frame.ui.h:7 msgid "Pause" msgstr "Halten" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 #, c-format msgid "" "Recording into\n" "%s %s" msgstr "Recording into\n%s %s" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 msgid "(Paused)" msgstr "(pausiert)" -#: ../gtk/loginframe.c:87 +#: ../gtk/loginframe.c:75 #, c-format msgid "Please enter login information for %s" msgstr "Bitte geben Sie die Anmeldeinformationen für %s ein." @@ -755,263 +653,108 @@ msgstr "abrufen von %s" msgid "Downloading of remote configuration from %s failed." msgstr "Herunterladen der Fernkonfiguration von %s fehlgeschlagen" -#: ../gtk/audio_assistant.c:98 +#: ../gtk/audio_assistant.c:103 msgid "No voice detected" msgstr "Keine Stimme ermittelt" -#: ../gtk/audio_assistant.c:99 +#: ../gtk/audio_assistant.c:104 msgid "Too low" msgstr "zu gering" -#: ../gtk/audio_assistant.c:100 +#: ../gtk/audio_assistant.c:105 msgid "Good" msgstr "gut" -#: ../gtk/audio_assistant.c:101 +#: ../gtk/audio_assistant.c:106 msgid "Too loud" msgstr "zu laut" -#: ../gtk/audio_assistant.c:183 +#: ../gtk/audio_assistant.c:188 msgid "Did you hear three beeps ?" -msgstr "" +msgstr "Haben Sie die drei Signaltöne gehört?" -#: ../gtk/audio_assistant.c:292 ../gtk/audio_assistant.c:297 +#: ../gtk/audio_assistant.c:299 ../gtk/audio_assistant.c:304 msgid "Sound preferences not found " -msgstr "" +msgstr "Toneinstellungen nicht gefunden" -#: ../gtk/audio_assistant.c:306 +#: ../gtk/audio_assistant.c:313 msgid "Cannot launch system sound control " -msgstr "" +msgstr "Systemtonsteuerung kann nicht gestartet werden" -#: ../gtk/audio_assistant.c:318 +#: ../gtk/audio_assistant.c:325 msgid "" "Welcome!\n" "This assistant will help you to configure audio settings for Linphone" msgstr "Willkommen!\nDieser Assistent hilft Ihnen die Audioeinstellungen für Linphone einzurichten." -#: ../gtk/audio_assistant.c:328 +#: ../gtk/audio_assistant.c:335 msgid "Capture device" msgstr "Aufnahmegerät" -#: ../gtk/audio_assistant.c:329 +#: ../gtk/audio_assistant.c:336 msgid "Recorded volume" msgstr "aufgenommene Lautstärke" -#: ../gtk/audio_assistant.c:333 +#: ../gtk/audio_assistant.c:340 msgid "No voice" msgstr "Keine Stimme" -#: ../gtk/audio_assistant.c:334 ../gtk/audio_assistant.c:373 +#: ../gtk/audio_assistant.c:341 ../gtk/audio_assistant.c:380 msgid "System sound preferences" -msgstr "" +msgstr "Systemtoneinstellungen" -#: ../gtk/audio_assistant.c:369 +#: ../gtk/audio_assistant.c:376 msgid "Playback device" msgstr "Wiedergabegerät" -#: ../gtk/audio_assistant.c:370 +#: ../gtk/audio_assistant.c:377 msgid "Play three beeps" msgstr "spiele drei Pieptöne ab" -#: ../gtk/audio_assistant.c:403 +#: ../gtk/audio_assistant.c:410 msgid "Press the record button and say some words" msgstr "Drücken Sie den Aufnahmeknopf und sagen Sie etwas" -#: ../gtk/audio_assistant.c:404 +#: ../gtk/audio_assistant.c:411 msgid "Listen to your record voice" msgstr "Hören Sie das Aufgenommene" -#: ../gtk/audio_assistant.c:405 +#: ../gtk/audio_assistant.c:412 ../gtk/conf_frame.ui.h:2 +#: ../gtk/in_call_frame.ui.h:4 msgid "Record" -msgstr "" +msgstr "Aufnahme" -#: ../gtk/audio_assistant.c:406 +#: ../gtk/audio_assistant.c:413 msgid "Play" -msgstr "" +msgstr "Wiedergabe" -#: ../gtk/audio_assistant.c:433 +#: ../gtk/audio_assistant.c:440 msgid "Let's start Linphone now" msgstr "Linphone jetzt starten" -#: ../gtk/audio_assistant.c:503 +#: ../gtk/audio_assistant.c:510 msgid "Audio Assistant" msgstr "Audio-Assistant" -#: ../gtk/audio_assistant.c:513 ../gtk/main.ui.h:32 +#: ../gtk/audio_assistant.c:520 ../gtk/main.ui.h:13 msgid "Audio assistant" msgstr "Audio-Assistant" -#: ../gtk/audio_assistant.c:518 +#: ../gtk/audio_assistant.c:525 msgid "Mic Gain calibration" msgstr "Einrichtung MIkrofonverstärker" -#: ../gtk/audio_assistant.c:524 +#: ../gtk/audio_assistant.c:531 msgid "Speaker volume calibration" msgstr "Einrichtung Lautstärke" -#: ../gtk/audio_assistant.c:529 +#: ../gtk/audio_assistant.c:536 msgid "Record and Play" msgstr "aufnehmen und abspielen" -#: ../gtk/main.ui.h:1 -msgid "Callee name" -msgstr "Name des Angerufenen" - -#: ../gtk/main.ui.h:2 -msgid "Send" -msgstr "Senden" - -#: ../gtk/main.ui.h:3 -msgid "End conference" -msgstr "Konferenz beenden" - -#: ../gtk/main.ui.h:7 -msgid "Record this call to an audio file" -msgstr "Speichere den Anruf in eine Audio-Datei" - -#: ../gtk/main.ui.h:8 -msgid "Video" -msgstr "Video" - -#: ../gtk/main.ui.h:10 -msgid "Mute" -msgstr "Stumm" - -#: ../gtk/main.ui.h:11 -msgid "Transfer" -msgstr "Vermittlung" - -#: ../gtk/main.ui.h:14 -msgid "In call" -msgstr "Im Gespräch" - -#: ../gtk/main.ui.h:15 -msgid "Duration" -msgstr "Dauer" - -#: ../gtk/main.ui.h:16 -msgid "Call quality rating" -msgstr "Bewertung der Verbindungsqualität" - -#: ../gtk/main.ui.h:17 -msgid "All users" -msgstr "Alle Teilnehmer" - -#: ../gtk/main.ui.h:18 -msgid "Online users" -msgstr "Angemeldete Teilnehmer" - -#: ../gtk/main.ui.h:19 -msgid "ADSL" -msgstr "ADSL" - -#: ../gtk/main.ui.h:20 -msgid "Fiber Channel" -msgstr "Glasfaserkabel" - -#: ../gtk/main.ui.h:21 -msgid "Default" -msgstr "Vorgabe" - -#: ../gtk/main.ui.h:22 -msgid "Delete" -msgstr "Löschen" - -#: ../gtk/main.ui.h:23 -msgid "_Options" -msgstr "_Optionen" - -#: ../gtk/main.ui.h:24 -msgid "Set configuration URI" -msgstr "Konfigurations URI angeben" - -#: ../gtk/main.ui.h:25 -msgid "Always start video" -msgstr "Video immer starten" - -#: ../gtk/main.ui.h:26 -msgid "Enable self-view" -msgstr "Selbstansicht ein" - -#: ../gtk/main.ui.h:27 -msgid "_Help" -msgstr "_Hilfe" - -#: ../gtk/main.ui.h:28 -msgid "Show debug window" -msgstr "Debug-Fenster anzeigen" - -#: ../gtk/main.ui.h:29 -msgid "_Homepage" -msgstr "_Homepage" - -#: ../gtk/main.ui.h:30 -msgid "Check _Updates" -msgstr "Auf _Aktualisierungen überprüfen" - -#: ../gtk/main.ui.h:31 -msgid "Account assistant" -msgstr "Konto-Einrichtungsassistent" - -#: ../gtk/main.ui.h:33 -msgid "SIP address or phone number:" -msgstr "SIP-Adresse oder Telefonnummer:" - -#: ../gtk/main.ui.h:34 -msgid "Initiate a new call" -msgstr "Einen neuen Anruf beginnen" - -#: ../gtk/main.ui.h:35 -msgid "Contacts" -msgstr "Kontakte" - -#: ../gtk/main.ui.h:36 -msgid "Search" -msgstr "Suchen" - -#: ../gtk/main.ui.h:37 -msgid "Add contacts from directory" -msgstr "Kontakte aus einem Verzeichnis hinzufügen" - -#: ../gtk/main.ui.h:38 -msgid "Add contact" -msgstr "Kontakt hinzufügen" - -#: ../gtk/main.ui.h:39 -msgid "Recent calls" -msgstr "Letzte Gespräche" - -#: ../gtk/main.ui.h:40 -msgid "My current identity:" -msgstr "Aktuelle Identität:" - -#: ../gtk/main.ui.h:41 ../gtk/tunnel_config.ui.h:7 -msgid "Username" -msgstr "Benutzername" - -#: ../gtk/main.ui.h:42 ../gtk/tunnel_config.ui.h:8 -msgid "Password" -msgstr "Passwort" - -#: ../gtk/main.ui.h:43 -msgid "Internet connection:" -msgstr "Internetverbindung:" - -#: ../gtk/main.ui.h:44 -msgid "Automatically log me in" -msgstr "Automatisch anmelden" - -#: ../gtk/main.ui.h:45 ../gtk/password.ui.h:3 -msgid "UserID" -msgstr "Benutzer-ID" - -#: ../gtk/main.ui.h:46 -msgid "Login information" -msgstr "Anmeldeinformationen" - -#: ../gtk/main.ui.h:47 -msgid "Welcome!" -msgstr "Willkommen!" +#: ../gtk/audio_assistant.c:541 ../gtk/setup_wizard.ui.h:38 +msgid "Terminating" +msgstr "Fertigstellen" #: ../gtk/about.ui.h:1 msgid "About Linphone" @@ -1041,37 +784,21 @@ msgid "" "he: Eli Zaretskii \n" msgstr "fr: Simon Morlat\nen: Simon Morlat and Delphine Perreau\nit: Alberto Zanoni \nde: Jean-Jacques Sarton \nsv: Daniel Nylander \nes: Jesus Benitez \nja: YAMAGUCHI YOSHIYA \npt_BR: Rafael Caesar Lenzi \npl: Robert Nasiadek \ncs: Petr Pisar \nhu: anonymous\nhe: Eli Zaretskii \n" -#: ../gtk/contact.ui.h:2 -msgid "SIP Address" -msgstr "SIP-Adresse" +#: ../gtk/buddylookup.ui.h:1 +msgid "Search contacts in directory" +msgstr "Kontakte im Verzeichnis suchen" -#: ../gtk/contact.ui.h:3 -msgid "Show this contact presence status" -msgstr "Anwesenheitsstatus dieses Kontakts zeigen" +#: ../gtk/buddylookup.ui.h:2 +msgid "Add to my list" +msgstr "Zur Kontaktliste hinzufügen" -#: ../gtk/contact.ui.h:4 -msgid "Allow this contact to see my presence status" -msgstr "Diesem Kontakt erlauben, meinen Anwesenheitsstatus zu sehen" +#: ../gtk/buddylookup.ui.h:3 +msgid "Search somebody" +msgstr "Kontaktsuche" -#: ../gtk/contact.ui.h:5 -msgid "Contact information" -msgstr "Kontaktinformationen" - -#: ../gtk/log.ui.h:1 -msgid "Linphone debug window" -msgstr "Linphone Debug-Fenster" - -#: ../gtk/log.ui.h:2 -msgid "Scroll to end" -msgstr "Ans Ende rollen" - -#: ../gtk/password.ui.h:1 -msgid "Linphone - Authentication required" -msgstr "Linphone - Authentifikation erforderlich" - -#: ../gtk/password.ui.h:2 -msgid "Please enter the domain password" -msgstr "Bitte das Passwort der Domäne eingeben" +#: ../gtk/callee_frame.ui.h:1 +msgid "Callee name" +msgstr "Name des Angerufenen" #: ../gtk/call_logs.ui.h:1 msgid "Call history" @@ -1085,459 +812,17 @@ msgstr "Alle löschen" msgid "Call back" msgstr "Anrufen" -#: ../gtk/sip_account.ui.h:1 -msgid "Linphone - Configure a SIP account" -msgstr "Linphone - SIP-Konto einrichten" - -#: ../gtk/sip_account.ui.h:2 -msgid "Your SIP identity:" -msgstr "Ihre SIP-Identität:" - -#: ../gtk/sip_account.ui.h:3 -msgid "Looks like sip:@" -msgstr "Sieht aus wie sip:@" - -#: ../gtk/sip_account.ui.h:4 -msgid "sip:" -msgstr "sip:" - -#: ../gtk/sip_account.ui.h:5 -msgid "SIP Proxy address:" -msgstr "SIP-Proxy-Adresse:" - -#: ../gtk/sip_account.ui.h:6 -msgid "Looks like sip:" -msgstr "Sieht aus wie sip:" - -#: ../gtk/sip_account.ui.h:7 -msgid "Registration duration (sec):" -msgstr "Registrierungsdauer (sec):" - -#: ../gtk/sip_account.ui.h:8 -msgid "Contact params (optional):" -msgstr "Kontaktdetails (optional)" - -#: ../gtk/sip_account.ui.h:9 -msgid "AVPF regular RTCP interval (sec):" -msgstr "AVPF Standard RTCP Interval (sek):" - -#: ../gtk/sip_account.ui.h:10 -msgid "Route (optional):" -msgstr "Route (optional):" - -#: ../gtk/sip_account.ui.h:11 -msgid "Transport" -msgstr "Übertragung" - -#: ../gtk/sip_account.ui.h:12 -msgid "Register" -msgstr "Registrieren" - -#: ../gtk/sip_account.ui.h:13 -msgid "Publish presence information" -msgstr "Anwesenheitsstatus veröffentlichen" - -#: ../gtk/sip_account.ui.h:14 -msgid "Enable AVPF" -msgstr "Aktiviere AVPF" - -#: ../gtk/sip_account.ui.h:15 -msgid "Configure a SIP account" -msgstr "SIP-Konto einrichten" - -#: ../gtk/parameters.ui.h:1 -msgid "anonymous" -msgstr "Anonym" - -#: ../gtk/parameters.ui.h:2 -msgid "GSSAPI" -msgstr "GSSAPI" - -#: ../gtk/parameters.ui.h:3 -msgid "SASL" -msgstr "SASL" - -#: ../gtk/parameters.ui.h:4 -msgid "default soundcard" -msgstr "Standard-Soundkarte" - -#: ../gtk/parameters.ui.h:5 -msgid "a sound card" -msgstr "eine Soundkarte" - -#: ../gtk/parameters.ui.h:6 -msgid "default camera" -msgstr "Standard-Kamera" - -#: ../gtk/parameters.ui.h:7 -msgid "CIF" -msgstr "CIF" - -#: ../gtk/parameters.ui.h:8 -msgid "Audio codecs" -msgstr "Audio-Codecs" - -#: ../gtk/parameters.ui.h:9 -msgid "Video codecs" -msgstr "Video-Codecs" - -#: ../gtk/parameters.ui.h:10 -msgid "C" -msgstr "C" - -#: ../gtk/parameters.ui.h:11 -msgid "SIP (UDP)" -msgstr "SIP (UDP)" - -#: ../gtk/parameters.ui.h:12 -msgid "SIP (TCP)" -msgstr "SIP (TCP)" - -#: ../gtk/parameters.ui.h:13 -msgid "SIP (TLS)" -msgstr "SIP (TLS)" - -#: ../gtk/parameters.ui.h:14 -msgid "Settings" -msgstr "Einstellungen" - -#: ../gtk/parameters.ui.h:15 -msgid "Set Maximum Transmission Unit:" -msgstr "Maximum Transmission Unit setzen:" - -#: ../gtk/parameters.ui.h:16 -msgid "Send DTMFs as SIP info" -msgstr "DTMFs als SIP-Info senden" - -#: ../gtk/parameters.ui.h:17 -msgid "Allow IPv6" -msgstr "" - -#: ../gtk/parameters.ui.h:18 -msgid "Transport" -msgstr "Übertragung" - -#: ../gtk/parameters.ui.h:19 -msgid "SIP/UDP port" -msgstr "SIP/UDP Port" - -#: ../gtk/parameters.ui.h:21 -msgid "Random" -msgstr "" - -#: ../gtk/parameters.ui.h:22 -msgid "SIP/TCP port" -msgstr "SIP/TCP Port" - -#: ../gtk/parameters.ui.h:23 -msgid "Audio RTP/UDP:" -msgstr "Audio RTP/UDP:" - -#: ../gtk/parameters.ui.h:24 -msgid "Fixed" -msgstr "Fest" - -#: ../gtk/parameters.ui.h:25 -msgid "Video RTP/UDP:" -msgstr "Video RTP/UDP:" - -#: ../gtk/parameters.ui.h:26 -msgid "Media encryption type" -msgstr "Verschlüsselungstyp der Medien" - -#: ../gtk/parameters.ui.h:27 -msgid "Media encryption is mandatory" -msgstr "Medienverschlüsselung erzwingen" - -#: ../gtk/parameters.ui.h:28 -msgid "Tunnel" -msgstr "Tunnel" - -#: ../gtk/parameters.ui.h:29 -msgid "DSCP fields" -msgstr "DSCP-Felder" - -#: ../gtk/parameters.ui.h:30 -msgid "Network protocol and ports" -msgstr "Netzwerkprotokoll und Ports" - -#: ../gtk/parameters.ui.h:31 -msgid "Direct connection to the Internet" -msgstr "Direkte Verbindung ins Internet" - -#: ../gtk/parameters.ui.h:32 -msgid "Behind NAT / Firewall (specify gateway IP )" -msgstr "Hinter NAT / Firewall (Gateway IP angeben)" - -#: ../gtk/parameters.ui.h:33 -msgid "Behind NAT / Firewall (use STUN to resolve)" -msgstr "Hinter NAT / Firewall (STUN verwenden)" - -#: ../gtk/parameters.ui.h:34 -msgid "Behind NAT / Firewall (use ICE)" -msgstr "Hinter NAT / Firewall (ICE verwenden)" - -#: ../gtk/parameters.ui.h:35 -msgid "Behind NAT / Firewall (use uPnP)" -msgstr "Hinter NAT / Firewall (uPnP verwenden)" - -#: ../gtk/parameters.ui.h:36 -msgid "Public IP address:" -msgstr "Öffentliche IP-Adresse:" - -#: ../gtk/parameters.ui.h:37 -msgid "Stun server:" -msgstr "STUN-Server:" - -#: ../gtk/parameters.ui.h:38 -msgid "NAT and Firewall" -msgstr "NAT und Firewall" - -#: ../gtk/parameters.ui.h:39 -msgid "Network settings" -msgstr "Netzwerkeinstellungen" - -#: ../gtk/parameters.ui.h:40 -msgid "Ring sound:" -msgstr "Klingelton:" - -#: ../gtk/parameters.ui.h:41 -msgid "ALSA special device (optional):" -msgstr "Spezielles ALSA-Gerät (optional):" - -#: ../gtk/parameters.ui.h:42 -msgid "Capture device:" -msgstr "Aufnahmegerät:" - -#: ../gtk/parameters.ui.h:43 -msgid "Ring device:" -msgstr "Gerät für Klingelton:" - -#: ../gtk/parameters.ui.h:44 -msgid "Playback device:" -msgstr "Wiedergabegerät:" - -#: ../gtk/parameters.ui.h:45 -msgid "Enable echo cancellation" -msgstr "Echounterdrückung ein" - -#: ../gtk/parameters.ui.h:46 -msgid "Audio" -msgstr "Audio" - -#: ../gtk/parameters.ui.h:47 -msgid "Video input device:" -msgstr "Video-Aufnahmegerät:" - -#: ../gtk/parameters.ui.h:48 -msgid "Prefered video resolution:" -msgstr "Bevorzugte Video-Auflösung:" - -#: ../gtk/parameters.ui.h:49 -msgid "Video output method:" -msgstr "Methode zur Videoausgabe" - -#: ../gtk/parameters.ui.h:50 -msgid "Show camera preview" -msgstr "" - -#: ../gtk/parameters.ui.h:51 -msgid "Video" -msgstr "Video" - -#: ../gtk/parameters.ui.h:52 -msgid "Multimedia settings" -msgstr "Multimedia-Einstellungen" - -#: ../gtk/parameters.ui.h:53 -msgid "This section defines your SIP address when not using a SIP account" -msgstr "In diesem Bereich legen Sie Ihre SIP-Adresse fest, wenn Sie kein SIP-Konto verwenden." - -#: ../gtk/parameters.ui.h:54 -msgid "Your display name (eg: John Doe):" -msgstr "Ihr angezeigter Name (z. B. Heinz Müller):" - -#: ../gtk/parameters.ui.h:55 -msgid "Your username:" -msgstr "Ihr Benutzername:" - -#: ../gtk/parameters.ui.h:56 -msgid "Your resulting SIP address:" -msgstr "Sich ergebende SIP-Adresse:" - -#: ../gtk/parameters.ui.h:57 -msgid "Default identity" -msgstr "Standard-Identität" - -#: ../gtk/parameters.ui.h:58 -msgid "Wizard" -msgstr "Assistent" - -#: ../gtk/parameters.ui.h:59 -msgid "Add" -msgstr "Hinzufügen" - -#: ../gtk/parameters.ui.h:60 -msgid "Edit" -msgstr "Bearbeiten" - -#: ../gtk/parameters.ui.h:61 -msgid "Remove" -msgstr "Entfernen" - -#: ../gtk/parameters.ui.h:62 -msgid "Proxy accounts" -msgstr "Proxy-Konten" - -#: ../gtk/parameters.ui.h:63 -msgid "Erase all passwords" -msgstr "Alle Passwörter löschen" - -#: ../gtk/parameters.ui.h:64 -msgid "Privacy" -msgstr "Privatsphäre" - -#: ../gtk/parameters.ui.h:65 -msgid "Automatically answer when a call is received" -msgstr "" - -#: ../gtk/parameters.ui.h:66 -msgid "Delay before answering (ms)" -msgstr "" - -#: ../gtk/parameters.ui.h:67 -msgid "Auto-answer" -msgstr "" - -#: ../gtk/parameters.ui.h:68 -msgid "Manage SIP Accounts" -msgstr "SIP-Konten verwalten" - -#: ../gtk/parameters.ui.h:69 ../gtk/tunnel_config.ui.h:4 -msgid "Enable" -msgstr "Freigeben" - -#: ../gtk/parameters.ui.h:70 ../gtk/tunnel_config.ui.h:5 -msgid "Disable" -msgstr "Sperren" - -#: ../gtk/parameters.ui.h:71 -msgid "Codecs" -msgstr "Codecs" - -#: ../gtk/parameters.ui.h:72 -msgid "0 stands for \"unlimited\"" -msgstr "0 bedeutet „unbegrenzt“" - -#: ../gtk/parameters.ui.h:73 -msgid "Upload speed limit in Kbit/sec:" -msgstr "Upload-Bandbreite (kbit/sec):" - -#: ../gtk/parameters.ui.h:74 -msgid "Download speed limit in Kbit/sec:" -msgstr "Download-Bandbreite (kbit/sec):" - -#: ../gtk/parameters.ui.h:75 -msgid "Enable adaptive rate control" -msgstr "Adaptive Ratenregelung ein" - -#: ../gtk/parameters.ui.h:76 -msgid "" -"Adaptive rate control is a technique to dynamically guess the available " -"bandwidth during a call." -msgstr "Adaptive Ratenregelung ist eine Technik zur dynamischen Abschätzung der zur Verfügung stehenden Bandbreite während eines Anrufs." - -#: ../gtk/parameters.ui.h:77 -msgid "Bandwidth control" -msgstr "Bandbreiten-Einstellungen" - -#: ../gtk/parameters.ui.h:78 -msgid "Codecs" -msgstr "Codecs" - -#: ../gtk/parameters.ui.h:79 -msgid "Language" -msgstr "Sprache" - -#: ../gtk/parameters.ui.h:80 -msgid "Show advanced settings" -msgstr "Fortgeschrittene Einstellungen anzeigen" - -#: ../gtk/parameters.ui.h:81 -msgid "Level" -msgstr "Detaillierung" - -#: ../gtk/parameters.ui.h:82 -msgid "User interface" -msgstr "Benutzeroberfläche" - -#: ../gtk/parameters.ui.h:83 ../gtk/ldap.ui.h:2 -msgid "Server address:" -msgstr "Server-Adresse" - -#: ../gtk/parameters.ui.h:84 ../gtk/ldap.ui.h:3 -msgid "Authentication method:" -msgstr "Authentifizierungsmethode" - -#: ../gtk/parameters.ui.h:86 -msgid "LDAP Account setup" -msgstr "LDAP-Kontoeinrichtung" - -#: ../gtk/parameters.ui.h:87 -msgid "LDAP" -msgstr "LDAP" - -#: ../gtk/parameters.ui.h:88 -msgid "Done" -msgstr "Fertig" - -#: ../gtk/buddylookup.ui.h:1 -msgid "Search contacts in directory" -msgstr "Kontakte im Verzeichnis suchen" - -#: ../gtk/buddylookup.ui.h:2 -msgid "Add to my list" -msgstr "Zur Kontaktliste hinzufügen" - -#: ../gtk/buddylookup.ui.h:3 -msgid "Search somebody" -msgstr "Kontaktsuche" - -#: ../gtk/waiting.ui.h:2 -msgid "Please wait" -msgstr "Bitte warten" - -#: ../gtk/dscp_settings.ui.h:1 -msgid "DSCP settings" -msgstr "DSCP-Einstellungen" - -#: ../gtk/dscp_settings.ui.h:2 -msgid "SIP" -msgstr "SIP" - -#: ../gtk/dscp_settings.ui.h:3 -msgid "Audio RTP stream" -msgstr "Audio-RTP-Datenstrom" - -#: ../gtk/dscp_settings.ui.h:4 -msgid "Video RTP stream" -msgstr "Video-RTP-Datenstrom" - -#: ../gtk/dscp_settings.ui.h:5 -msgid "Set DSCP values (in hexadecimal)" -msgstr "DSCP-Werte setzen (hexadezimal)" - #: ../gtk/call_statistics.ui.h:1 msgid "Call statistics" msgstr "Anrufstatistik" #: ../gtk/call_statistics.ui.h:2 msgid "Audio codec" -msgstr "Audio-Codec" +msgstr "Audiocodec" #: ../gtk/call_statistics.ui.h:3 msgid "Video codec" -msgstr "Video-Codec" +msgstr "Videocodec" #: ../gtk/call_statistics.ui.h:4 msgid "Audio IP bandwidth usage" @@ -1575,30 +860,112 @@ msgstr "RTP-Profil" msgid "Call statistics and information" msgstr "Anrufstatistik und -informationen" -#: ../gtk/tunnel_config.ui.h:1 -msgid "Configure VoIP tunnel" -msgstr "VoIP-Tunnel einrichten" +#: ../gtk/chatroom_frame.ui.h:1 +msgid "Send" +msgstr "Senden" -#: ../gtk/tunnel_config.ui.h:2 -msgid "Host" -msgstr "Host" +#: ../gtk/conf_frame.ui.h:1 +msgid "End conference" +msgstr "Konferenz beenden" -#: ../gtk/tunnel_config.ui.h:3 -msgid "Port" -msgstr "Port" +#: ../gtk/config-uri.ui.h:1 +msgid "Specifying a remote configuration URI" +msgstr "Eine URI zur FErnkonfiguration angeben" -#: ../gtk/tunnel_config.ui.h:6 -msgid "Configure tunnel" -msgstr "Tunnel einrichten" +#: ../gtk/config-uri.ui.h:2 +msgid "" +"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" +"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " +msgstr "Diese Maske erlaubt Ihnen für das Laden der Konfiguration beim Programmstart eine http- oder https-Adresse anzugeben.\nBitte geben Sie unten die Konfigurations-URI ein oder ändern diese. Nach dem Bestätigen mit OK wird Linphone automatisch neustarten, um die neuen Einstellungen zu übernehmen." -#: ../gtk/tunnel_config.ui.h:9 -msgid "Configure http proxy (optional)" -msgstr "Configure http proxy (optional)" +#: ../gtk/contact.ui.h:2 +msgid "SIP Address" +msgstr "SIP-Adresse" + +#: ../gtk/contact.ui.h:3 +msgid "Show this contact presence status" +msgstr "Anwesenheitsstatus dieses Kontakts zeigen" + +#: ../gtk/contact.ui.h:4 +msgid "Allow this contact to see my presence status" +msgstr "Diesem Kontakt erlauben, meinen Anwesenheitsstatus zu sehen" + +#: ../gtk/contact.ui.h:5 +msgid "Contact information" +msgstr "Kontaktinformationen" + +#: ../gtk/dscp_settings.ui.h:1 +msgid "DSCP settings" +msgstr "DSCP-Einstellungen" + +#: ../gtk/dscp_settings.ui.h:2 +msgid "SIP" +msgstr "SIP" + +#: ../gtk/dscp_settings.ui.h:3 +msgid "Audio RTP stream" +msgstr "Audio-RTP-Datenstrom" + +#: ../gtk/dscp_settings.ui.h:4 +msgid "Video RTP stream" +msgstr "Video-RTP-Datenstrom" + +#: ../gtk/dscp_settings.ui.h:5 +msgid "Set DSCP values (in hexadecimal)" +msgstr "DSCP-Werte setzen (hexadezimal)" + +#: ../gtk/in_call_frame.ui.h:1 +msgid "Click here to set the speakers volume" +msgstr "Klicken Sie hier, um die Lautsprecherlautstärke festzulegen" + +#: ../gtk/in_call_frame.ui.h:5 +msgid "Record this call to an audio file" +msgstr "Speichere den Anruf in eine Audio-Datei" + +#: ../gtk/in_call_frame.ui.h:6 +msgid "Video" +msgstr "Video" + +#: ../gtk/in_call_frame.ui.h:8 +msgid "Mute" +msgstr "Stumm" + +#: ../gtk/in_call_frame.ui.h:9 +msgid "Transfer" +msgstr "Vermittlung" + +#: ../gtk/in_call_frame.ui.h:12 +msgid "In call" +msgstr "Im Gespräch" + +#: ../gtk/in_call_frame.ui.h:13 +msgid "Duration" +msgstr "Dauer" + +#: ../gtk/in_call_frame.ui.h:14 +msgid "Call quality rating" +msgstr "Bewertung der Verbindungsqualität" #: ../gtk/ldap.ui.h:1 msgid "LDAP Settings" msgstr "LDAP-Einstellungen" +#: ../gtk/ldap.ui.h:2 ../gtk/parameters.ui.h:89 +msgid "Server address:" +msgstr "Server-Adresse" + +#: ../gtk/ldap.ui.h:3 ../gtk/parameters.ui.h:90 +msgid "Authentication method:" +msgstr "Authentifizierungsmethode" + +#: ../gtk/ldap.ui.h:4 ../gtk/parameters.ui.h:91 ../gtk/setup_wizard.ui.h:17 +msgid "Username:" +msgstr "Benutzername:" + +#: ../gtk/ldap.ui.h:5 ../gtk/password.ui.h:4 ../gtk/setup_wizard.ui.h:18 +msgid "Password:" +msgstr "Passwort:" + #: ../gtk/ldap.ui.h:6 msgid "Use TLS Connection" msgstr "TLS-Verbindung verwenden" @@ -1684,15 +1051,503 @@ msgstr "DIGEST-MD5" msgid "NTLM" msgstr "NTLM" -#: ../gtk/config-uri.ui.h:1 -msgid "Specifying a remote configuration URI" -msgstr "Eine URI zur FErnkonfiguration angeben" +#: ../gtk/login_frame.ui.h:1 ../gtk/tunnel_config.ui.h:7 +msgid "Username" +msgstr "Benutzername" -#: ../gtk/config-uri.ui.h:2 +#: ../gtk/login_frame.ui.h:2 ../gtk/tunnel_config.ui.h:8 +msgid "Password" +msgstr "Passwort" + +#: ../gtk/login_frame.ui.h:3 +msgid "Internet connection:" +msgstr "Internetverbindung:" + +#: ../gtk/login_frame.ui.h:4 +msgid "Automatically log me in" +msgstr "Automatisch anmelden" + +#: ../gtk/login_frame.ui.h:5 ../gtk/password.ui.h:3 +msgid "UserID" +msgstr "Benutzer-ID" + +#: ../gtk/login_frame.ui.h:6 +msgid "Login information" +msgstr "Anmeldeinformationen" + +#: ../gtk/login_frame.ui.h:7 +msgid "Welcome!" +msgstr "Willkommen!" + +#: ../gtk/login_frame.ui.h:8 +msgid "ADSL" +msgstr "ADSL" + +#: ../gtk/login_frame.ui.h:9 +msgid "Fiber Channel" +msgstr "Glasfaserkabel" + +#: ../gtk/log.ui.h:1 +msgid "Linphone debug window" +msgstr "Linphone Debug-Fenster" + +#: ../gtk/log.ui.h:2 +msgid "Scroll to end" +msgstr "Ans Ende rollen" + +#: ../gtk/main.ui.h:1 +msgid "Default" +msgstr "Vorgabe" + +#: ../gtk/main.ui.h:2 +msgid "Delete" +msgstr "Löschen" + +#: ../gtk/main.ui.h:3 +msgid "_Options" +msgstr "_Optionen" + +#: ../gtk/main.ui.h:4 +msgid "Set configuration URI" +msgstr "Konfigurations URI angeben" + +#: ../gtk/main.ui.h:5 +msgid "Always start video" +msgstr "Video immer starten" + +#: ../gtk/main.ui.h:6 +msgid "Enable self-view" +msgstr "Selbstansicht ein" + +#: ../gtk/main.ui.h:7 +msgid "Show keypad" +msgstr "Tastatur anzeigen" + +#: ../gtk/main.ui.h:8 +msgid "_Help" +msgstr "_Hilfe" + +#: ../gtk/main.ui.h:9 +msgid "Show debug window" +msgstr "Debug-Fenster anzeigen" + +#: ../gtk/main.ui.h:10 +msgid "_Homepage" +msgstr "_Homepage" + +#: ../gtk/main.ui.h:11 +msgid "Check _Updates" +msgstr "Auf _Aktualisierungen überprüfen" + +#: ../gtk/main.ui.h:12 +msgid "Account assistant" +msgstr "Konto-Einrichtungsassistent" + +#: ../gtk/main.ui.h:14 +msgid "SIP address or phone number:" +msgstr "SIP-Adresse oder Telefonnummer:" + +#: ../gtk/main.ui.h:15 +msgid "Initiate a new call" +msgstr "Einen neuen Anruf beginnen" + +#: ../gtk/main.ui.h:16 +msgid "Contacts" +msgstr "Kontakte" + +#: ../gtk/main.ui.h:17 +msgid "Search" +msgstr "Suchen" + +#: ../gtk/main.ui.h:18 +msgid "Add contacts from directory" +msgstr "Kontakte aus einem Verzeichnis hinzufügen" + +#: ../gtk/main.ui.h:19 +msgid "Add contact" +msgstr "Kontakt hinzufügen" + +#: ../gtk/main.ui.h:20 +msgid "Clear call history" +msgstr "Anrufchronik löschen" + +#: ../gtk/main.ui.h:22 +msgid "My current identity:" +msgstr "Aktuelle Identität:" + +#: ../gtk/main.ui.h:23 +msgid "Autoanswer is enabled" +msgstr "Automatische Antwort ist aktiviert" + +#: ../gtk/parameters.ui.h:1 +msgid "anonymous" +msgstr "Anonym" + +#: ../gtk/parameters.ui.h:2 +msgid "GSSAPI" +msgstr "GSSAPI" + +#: ../gtk/parameters.ui.h:3 +msgid "SASL" +msgstr "SASL" + +#: ../gtk/parameters.ui.h:4 +msgid "default soundcard" +msgstr "Standard-Soundkarte" + +#: ../gtk/parameters.ui.h:5 +msgid "a sound card" +msgstr "eine Soundkarte" + +#: ../gtk/parameters.ui.h:6 +msgid "default camera" +msgstr "Standard-Kamera" + +#: ../gtk/parameters.ui.h:7 +msgid "CIF" +msgstr "CIF" + +#: ../gtk/parameters.ui.h:8 +msgid "Audio codecs" +msgstr "Audiocodecs" + +#: ../gtk/parameters.ui.h:9 +msgid "Video codecs" +msgstr "Videocodecs" + +#: ../gtk/parameters.ui.h:10 +msgid "C" +msgstr "C" + +#: ../gtk/parameters.ui.h:11 +msgid "SIP (UDP)" +msgstr "SIP (UDP)" + +#: ../gtk/parameters.ui.h:12 +msgid "SIP (TCP)" +msgstr "SIP (TCP)" + +#: ../gtk/parameters.ui.h:13 +msgid "SIP (TLS)" +msgstr "SIP (TLS)" + +#: ../gtk/parameters.ui.h:14 +msgid "default" +msgstr "Vorgabe" + +#: ../gtk/parameters.ui.h:15 +msgid "high-fps" +msgstr "hohe-BpS" + +#: ../gtk/parameters.ui.h:16 +msgid "custom" +msgstr "Benutzerdefiniert" + +#: ../gtk/parameters.ui.h:17 +msgid "Settings" +msgstr "Einstellungen" + +#: ../gtk/parameters.ui.h:18 +msgid "This section defines your SIP address when not using a SIP account" +msgstr "In diesem Bereich legen Sie Ihre SIP-Adresse fest, wenn Sie kein SIP-Konto verwenden." + +#: ../gtk/parameters.ui.h:19 +msgid "Your display name (eg: John Doe):" +msgstr "Ihr angezeigter Name (z. B. Heinz Müller):" + +#: ../gtk/parameters.ui.h:20 +msgid "Your username:" +msgstr "Ihr Benutzername:" + +#: ../gtk/parameters.ui.h:21 +msgid "Your resulting SIP address:" +msgstr "Sich ergebende SIP-Adresse:" + +#: ../gtk/parameters.ui.h:22 +msgid "Default identity" +msgstr "Standard-Identität" + +#: ../gtk/parameters.ui.h:23 +msgid "Wizard" +msgstr "Assistent" + +#: ../gtk/parameters.ui.h:24 +msgid "Add" +msgstr "Hinzufügen" + +#: ../gtk/parameters.ui.h:25 +msgid "Edit" +msgstr "Bearbeiten" + +#: ../gtk/parameters.ui.h:26 +msgid "Remove" +msgstr "Entfernen" + +#: ../gtk/parameters.ui.h:27 +msgid "Proxy accounts" +msgstr "Proxy-Konten" + +#: ../gtk/parameters.ui.h:28 +msgid "Erase all passwords" +msgstr "Alle Passwörter löschen" + +#: ../gtk/parameters.ui.h:29 +msgid "Privacy" +msgstr "Privatsphäre" + +#: ../gtk/parameters.ui.h:30 +msgid "Automatically answer when a call is received" +msgstr "Automatisch antworten, wenn ein Anruf eingeht" + +#: ../gtk/parameters.ui.h:31 +msgid "Delay before answering (ms)" +msgstr "Verzögerung vor der Beantwortung (ms)" + +#: ../gtk/parameters.ui.h:32 +msgid "Auto-answer" +msgstr "Automatische Antwort" + +#: ../gtk/parameters.ui.h:33 +msgid "Manage SIP Accounts" +msgstr "SIP-Konten verwalten" + +#: ../gtk/parameters.ui.h:34 +msgid "Ring sound:" +msgstr "Klingelton:" + +#: ../gtk/parameters.ui.h:35 +msgid "ALSA special device (optional):" +msgstr "Spezielles ALSA-Gerät (optional):" + +#: ../gtk/parameters.ui.h:36 +msgid "Capture device:" +msgstr "Aufnahmegerät:" + +#: ../gtk/parameters.ui.h:37 +msgid "Ring device:" +msgstr "Gerät für Klingelton:" + +#: ../gtk/parameters.ui.h:38 +msgid "Playback device:" +msgstr "Wiedergabegerät:" + +#: ../gtk/parameters.ui.h:39 +msgid "Enable echo cancellation" +msgstr "Echounterdrückung ein" + +#: ../gtk/parameters.ui.h:40 +msgid "Audio" +msgstr "Audio" + +#: ../gtk/parameters.ui.h:41 +msgid "Video input device:" +msgstr "Video-Aufnahmegerät:" + +#: ../gtk/parameters.ui.h:42 +msgid "Preferred video resolution:" +msgstr "Bevorzugte Videoauflösung:" + +#: ../gtk/parameters.ui.h:43 +msgid "Video output method:" +msgstr "Methode zur Videoausgabe" + +#: ../gtk/parameters.ui.h:44 +msgid "Show camera preview" +msgstr "Kameravorschau anzeigen" + +#: ../gtk/parameters.ui.h:45 +msgid "Video preset:" +msgstr "Videovoreinstellung:" + +#: ../gtk/parameters.ui.h:46 +msgid "Preferred video framerate:" +msgstr "Bevorzugte Videobildfrequenz:" + +#: ../gtk/parameters.ui.h:47 +msgid "0 stands for \"unlimited\"" +msgstr "0 bedeutet „unbegrenzt“" + +#: ../gtk/parameters.ui.h:48 +msgid "Video" +msgstr "Video" + +#: ../gtk/parameters.ui.h:49 +msgid "Upload speed limit in Kbit/sec:" +msgstr "Upload-Bandbreite (kbit/sec):" + +#: ../gtk/parameters.ui.h:50 +msgid "Download speed limit in Kbit/sec:" +msgstr "Download-Bandbreite (kbit/sec):" + +#: ../gtk/parameters.ui.h:51 +msgid "Enable adaptive rate control" +msgstr "Adaptive Ratenregelung ein" + +#: ../gtk/parameters.ui.h:52 msgid "" -"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" -"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " -msgstr "Diese Maske erlaubt Ihnen für das Laden der Konfiguration beim Programmstart eine http- oder https-Adresse anzugeben.\nBitte geben Sie unten die Konfigurations-URI ein oder ändern diese. Nach dem Bestätigen mit OK wird Linphone automatisch neustarten, um die neuen Einstellungen zu übernehmen." +"Adaptive rate control is a technique to dynamically guess the available " +"bandwidth during a call." +msgstr "Adaptive Ratenregelung ist eine Technik zur dynamischen Abschätzung der zur Verfügung stehenden Bandbreite während eines Anrufs." + +#: ../gtk/parameters.ui.h:53 +msgid "Bandwidth control" +msgstr "Bandbreiten-Einstellungen" + +#: ../gtk/parameters.ui.h:54 +msgid "Multimedia settings" +msgstr "Multimedia-Einstellungen" + +#: ../gtk/parameters.ui.h:55 +msgid "Set Maximum Transmission Unit:" +msgstr "Maximum Transmission Unit setzen:" + +#: ../gtk/parameters.ui.h:56 +msgid "Send DTMFs as SIP info" +msgstr "DTMFs als SIP-Info senden" + +#: ../gtk/parameters.ui.h:57 +msgid "Allow IPv6" +msgstr "IPv6 erlauben" + +#: ../gtk/parameters.ui.h:58 +msgid "Transport" +msgstr "Übertragung" + +#: ../gtk/parameters.ui.h:59 +msgid "SIP/UDP port" +msgstr "SIP/UDP Port" + +#: ../gtk/parameters.ui.h:61 +msgid "Random" +msgstr "Zufällig" + +#: ../gtk/parameters.ui.h:62 +msgid "SIP/TCP port" +msgstr "SIP/TCP Port" + +#: ../gtk/parameters.ui.h:63 +msgid "Audio RTP/UDP:" +msgstr "Audio RTP/UDP:" + +#: ../gtk/parameters.ui.h:64 +msgid "Fixed" +msgstr "Fest" + +#: ../gtk/parameters.ui.h:65 +msgid "Video RTP/UDP:" +msgstr "Video RTP/UDP:" + +#: ../gtk/parameters.ui.h:66 +msgid "Media encryption type" +msgstr "Verschlüsselungstyp der Medien" + +#: ../gtk/parameters.ui.h:67 +msgid "Media encryption is mandatory" +msgstr "Medienverschlüsselung erzwingen" + +#: ../gtk/parameters.ui.h:68 +msgid "Tunnel" +msgstr "Tunnel" + +#: ../gtk/parameters.ui.h:69 +msgid "DSCP fields" +msgstr "DSCP-Felder" + +#: ../gtk/parameters.ui.h:70 +msgid "Network protocol and ports" +msgstr "Netzwerkprotokoll und Ports" + +#: ../gtk/parameters.ui.h:71 +msgid "Direct connection to the Internet" +msgstr "Direkte Verbindung ins Internet" + +#: ../gtk/parameters.ui.h:72 +msgid "Behind NAT / Firewall (specify gateway IP )" +msgstr "Hinter NAT / Firewall (Gateway IP angeben)" + +#: ../gtk/parameters.ui.h:73 +msgid "Behind NAT / Firewall (use STUN to resolve)" +msgstr "Hinter NAT / Firewall (STUN verwenden)" + +#: ../gtk/parameters.ui.h:74 +msgid "Behind NAT / Firewall (use ICE)" +msgstr "Hinter NAT / Firewall (ICE verwenden)" + +#: ../gtk/parameters.ui.h:75 +msgid "Behind NAT / Firewall (use uPnP)" +msgstr "Hinter NAT / Firewall (uPnP verwenden)" + +#: ../gtk/parameters.ui.h:76 +msgid "Public IP address:" +msgstr "Öffentliche IP-Adresse:" + +#: ../gtk/parameters.ui.h:77 +msgid "Stun server:" +msgstr "STUN-Server:" + +#: ../gtk/parameters.ui.h:78 +msgid "NAT and Firewall" +msgstr "NAT und Firewall" + +#: ../gtk/parameters.ui.h:79 +msgid "Network settings" +msgstr "Netzwerkeinstellungen" + +#: ../gtk/parameters.ui.h:80 ../gtk/tunnel_config.ui.h:4 +msgid "Enable" +msgstr "Freigeben" + +#: ../gtk/parameters.ui.h:81 ../gtk/tunnel_config.ui.h:5 +msgid "Disable" +msgstr "Sperren" + +#: ../gtk/parameters.ui.h:82 +msgid "Audio codecs" +msgstr "Audiocodecs" + +#: ../gtk/parameters.ui.h:83 +msgid "Video codecs" +msgstr "Videocodecs" + +#: ../gtk/parameters.ui.h:84 +msgid "Codecs" +msgstr "Codecs" + +#: ../gtk/parameters.ui.h:85 +msgid "Language" +msgstr "Sprache" + +#: ../gtk/parameters.ui.h:86 +msgid "Show advanced settings" +msgstr "Fortgeschrittene Einstellungen anzeigen" + +#: ../gtk/parameters.ui.h:87 +msgid "Level" +msgstr "Detaillierung" + +#: ../gtk/parameters.ui.h:88 +msgid "User interface" +msgstr "Benutzeroberfläche" + +#: ../gtk/parameters.ui.h:92 +msgid "LDAP Account setup" +msgstr "LDAP-Kontoeinrichtung" + +#: ../gtk/parameters.ui.h:93 +msgid "LDAP" +msgstr "LDAP" + +#: ../gtk/parameters.ui.h:94 +msgid "Done" +msgstr "Fertig" + +#: ../gtk/password.ui.h:1 +msgid "Linphone - Authentication required" +msgstr "Linphone - Authentifikation erforderlich" + +#: ../gtk/password.ui.h:2 +msgid "Please enter the domain password" +msgstr "Bitte das Passwort der Domäne eingeben" #: ../gtk/provisioning-fetch.ui.h:1 msgid "Configuring..." @@ -1702,68 +1557,278 @@ msgstr "Einstellen..." msgid "Please wait while fetching configuration from server..." msgstr "Bitte warten Sie während die Einstellungen vom Server abgerufen werden..." -#: ../coreapi/linphonecore.c:1539 +#: ../gtk/setup_wizard.ui.h:1 +msgid "SIP account configuration assistant" +msgstr "SIP-Konto-Einrichtungsassistent" + +#: ../gtk/setup_wizard.ui.h:2 +msgid "" +"Welcome!\n" +"This assistant will help you to use a SIP account for your calls." +msgstr "Willkommen!\nDieser Assistent hilft Ihnen dabei ein SIP-Konto einzurichten." + +#: ../gtk/setup_wizard.ui.h:4 +msgid "Welcome to the account setup assistant" +msgstr "Willkommen zum Konto-Einrichtungsassistenten" + +#: ../gtk/setup_wizard.ui.h:5 +msgid "Create an account on linphone.org" +msgstr "Ein Konto bei linphone.org erstellen." + +#: ../gtk/setup_wizard.ui.h:6 +msgid "I have already a linphone.org account and I just want to use it" +msgstr "Ich habe bereits ein Konto bei linphone.org und möchte es jetzt benutzen." + +#: ../gtk/setup_wizard.ui.h:7 +msgid "I have already a sip account and I just want to use it" +msgstr "Ich habe bereits ein SIP-Konto und möchte es jetzt benutzen." + +#: ../gtk/setup_wizard.ui.h:8 +msgid "I want to specify a remote configuration URI" +msgstr "Ich möchte eine URI zur Fernkonfiguration angeben" + +#: ../gtk/setup_wizard.ui.h:9 +msgid "Account setup assistant" +msgstr "Konto-Einrichtungsassistent" + +#: ../gtk/setup_wizard.ui.h:10 +msgid "Enter your account information" +msgstr "Geben Sie Ihre Zugangsdaten ein" + +#: ../gtk/setup_wizard.ui.h:11 +msgid "Username*" +msgstr "Benutzername*" + +#: ../gtk/setup_wizard.ui.h:12 +msgid "Password*" +msgstr "Passwort*" + +#: ../gtk/setup_wizard.ui.h:13 +msgid "Domain*" +msgstr "Domäne*" + +#: ../gtk/setup_wizard.ui.h:14 +msgid "Proxy" +msgstr "Proxy" + +#: ../gtk/setup_wizard.ui.h:15 +msgid "Configure your account (step 1/1)" +msgstr "Konto einrichten (Schritt 1/1)" + +#: ../gtk/setup_wizard.ui.h:16 +msgid "Enter your linphone.org username" +msgstr "Geben Sie Ihren Benutzernamen bei linphone.org ein." + +#: ../gtk/setup_wizard.ui.h:19 +msgid "Enter your sip username (step 1/1)" +msgstr "Geben Sie Ihren SIP-Benutzernamen ein (Schritt 1/1)" + +#: ../gtk/setup_wizard.ui.h:20 +msgid "(*) Required fields" +msgstr "(*) erforderliche Felder" + +#: ../gtk/setup_wizard.ui.h:21 +msgid "Email: (*)" +msgstr "E-Mail: (*)" + +#: ../gtk/setup_wizard.ui.h:22 +msgid "Username: (*)" +msgstr "Benutzername: (*)" + +#: ../gtk/setup_wizard.ui.h:23 +msgid "Password: (*)" +msgstr "Passwort: (*)" + +#: ../gtk/setup_wizard.ui.h:24 +msgid "Confirm your password: (*)" +msgstr "Bestätigen Sie Ihr Passwort: (*)" + +#: ../gtk/setup_wizard.ui.h:25 +msgid "Keep me informed with linphone updates" +msgstr "Halte mich über linphone Aktualisierungen auf dem laufenden" + +#: ../gtk/setup_wizard.ui.h:26 +msgid "Enter account information (step 1/2)" +msgstr "Geben Sie Ihre Zugangsdaten ein (Schritt 1/2)" + +#: ../gtk/setup_wizard.ui.h:27 +msgid "Your account is being created, please wait." +msgstr "Ihr Konto wird erstellt, bitte warten." + +#: ../gtk/setup_wizard.ui.h:28 +msgid "Account creation in progress" +msgstr "Kontoerstellung läuft" + +#: ../gtk/setup_wizard.ui.h:29 +msgid "" +"Please validate your account by clicking on the link we just sent you by email.\n" +"Then come back here and press Next button." +msgstr "Bitte bestätigen Sie Ihr Konto, indem Sie auf die Verknüpfung klicken, die wir Ihnen soeben per E-Mail geschickt haben.\nDanach gehen Sie hierher zurück und drücken auf „Vor“." + +#: ../gtk/setup_wizard.ui.h:31 +msgid "Validation (step 2/2)" +msgstr "Bestätigung (Schritt 2/2)" + +#: ../gtk/setup_wizard.ui.h:32 +msgid "Checking if your account is been validated, please wait." +msgstr "Es wird überprüft, ob Ihr Konto gültig ist, bitte warten." + +#: ../gtk/setup_wizard.ui.h:33 +msgid "Account validation check in progress" +msgstr "Kontogültigkeitsprüfung läuft" + +#: ../gtk/setup_wizard.ui.h:34 +msgid "" +"Error, account not validated, username already used or server unreachable.\n" +"Please go back and try again." +msgstr "Fehler, Konto kann nicht bestätigt werden. Der Benutzername wird bereits\nverwendet oder der Server ist unerreichbar.\nBitte gehen Sie zurück und versuchen Sie es noch einmal." + +#: ../gtk/setup_wizard.ui.h:36 +msgid "Error" +msgstr "Fehler" + +#: ../gtk/setup_wizard.ui.h:37 +msgid "Thank you. Your account is now configured and ready for use." +msgstr "Danke. Ihr Konto ist nun fertig eingerichtet und kann verwendet werden." + +#: ../gtk/sip_account.ui.h:1 +msgid "Linphone - Configure a SIP account" +msgstr "Linphone - SIP-Konto einrichten" + +#: ../gtk/sip_account.ui.h:2 +msgid "Your SIP identity:" +msgstr "Ihre SIP-Identität:" + +#: ../gtk/sip_account.ui.h:3 +msgid "Looks like sip:@" +msgstr "Sieht aus wie sip:@" + +#: ../gtk/sip_account.ui.h:4 +msgid "sip:" +msgstr "sip:" + +#: ../gtk/sip_account.ui.h:5 +msgid "SIP Proxy address:" +msgstr "SIP-Proxy-Adresse:" + +#: ../gtk/sip_account.ui.h:6 +msgid "Looks like sip:" +msgstr "Sieht aus wie sip:" + +#: ../gtk/sip_account.ui.h:7 +msgid "Registration duration (sec):" +msgstr "Registrierungsdauer (sec):" + +#: ../gtk/sip_account.ui.h:8 +msgid "Contact params (optional):" +msgstr "Kontaktdetails (optional)" + +#: ../gtk/sip_account.ui.h:9 +msgid "AVPF regular RTCP interval (sec):" +msgstr "AVPF Standard RTCP Interval (sek):" + +#: ../gtk/sip_account.ui.h:10 +msgid "Route (optional):" +msgstr "Route (optional):" + +#: ../gtk/sip_account.ui.h:11 +msgid "Transport" +msgstr "Übertragung" + +#: ../gtk/sip_account.ui.h:12 +msgid "Register" +msgstr "Registrieren" + +#: ../gtk/sip_account.ui.h:13 +msgid "Publish presence information" +msgstr "Anwesenheitsstatus veröffentlichen" + +#: ../gtk/sip_account.ui.h:14 +msgid "Enable AVPF" +msgstr "Aktiviere AVPF" + +#: ../gtk/sip_account.ui.h:15 +msgid "Configure a SIP account" +msgstr "SIP-Konto einrichten" + +#: ../gtk/tunnel_config.ui.h:1 +msgid "Configure VoIP tunnel" +msgstr "VoIP-Tunnel einrichten" + +#: ../gtk/tunnel_config.ui.h:2 +msgid "Host" +msgstr "Host" + +#: ../gtk/tunnel_config.ui.h:3 +msgid "Port" +msgstr "Port" + +#: ../gtk/tunnel_config.ui.h:6 +msgid "Configure tunnel" +msgstr "Tunnel einrichten" + +#: ../gtk/tunnel_config.ui.h:9 +msgid "Configure http proxy (optional)" +msgstr "Configure http proxy (optional)" + +#: ../gtk/waiting.ui.h:2 +msgid "Please wait" +msgstr "Bitte warten" + +#: ../coreapi/linphonecore.c:1560 msgid "Ready" msgstr "Bereit" -#: ../coreapi/linphonecore.c:2551 +#: ../coreapi/linphonecore.c:2556 msgid "Configuring" msgstr "Einstellen" -#: ../coreapi/linphonecore.c:2725 -msgid "Looking for telephone number destination..." -msgstr "Telefonnummernziel wird gesucht..." - -#: ../coreapi/linphonecore.c:2727 -msgid "Could not resolve this number." -msgstr "Diese Nummer kann nicht aufgelöst werden." - #. must be known at that time -#: ../coreapi/linphonecore.c:3013 +#: ../coreapi/linphonecore.c:2951 msgid "Contacting" msgstr "Verbindungsaufbau" -#: ../coreapi/linphonecore.c:3018 +#: ../coreapi/linphonecore.c:2956 msgid "Could not call" msgstr "Anruf kann nicht getätigt werden." -#: ../coreapi/linphonecore.c:3169 +#: ../coreapi/linphonecore.c:3092 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "Die maximale Anzahl der gleichzeitigen Anrufe ist erreicht." -#: ../coreapi/linphonecore.c:3327 +#: ../coreapi/linphonecore.c:3250 msgid "is contacting you" msgstr "ruft Sie an" -#: ../coreapi/linphonecore.c:3328 +#: ../coreapi/linphonecore.c:3251 msgid " and asked autoanswer." msgstr " und fragt nach automatischer Antwort." -#: ../coreapi/linphonecore.c:3452 +#: ../coreapi/linphonecore.c:3377 msgid "Modifying call parameters..." msgstr "Die Anrufparameter werden verändert..." -#: ../coreapi/linphonecore.c:3802 +#: ../coreapi/linphonecore.c:3769 msgid "Connected." msgstr "Verbunden." -#: ../coreapi/linphonecore.c:3827 +#: ../coreapi/linphonecore.c:3794 msgid "Call aborted" msgstr "Anruf abgebrochen" -#: ../coreapi/linphonecore.c:4024 +#: ../coreapi/linphonecore.c:3983 msgid "Could not pause the call" msgstr "Anruf kann nicht gehalten werden" -#: ../coreapi/linphonecore.c:4027 +#: ../coreapi/linphonecore.c:3986 msgid "Pausing the current call..." msgstr "Aktueller Anruf wird gehalten..." -#: ../coreapi/misc.c:434 +#: ../coreapi/misc.c:440 msgid "Stun lookup in progress..." msgstr "STUN-Ermittlung läuft..." -#: ../coreapi/misc.c:615 +#: ../coreapi/misc.c:650 msgid "ICE local candidates gathering in progress..." msgstr "Lokale Kandidaten für ICE werden zusammengestellt..." @@ -1819,166 +1884,173 @@ msgstr "Urlaub" msgid "Unknown status" msgstr "Unbekannter Status" -#: ../coreapi/proxy.c:328 +#: ../coreapi/proxy.c:292 msgid "" "The sip proxy address you entered is invalid, it must start with \"sip:\" " "followed by a hostname." msgstr "Die von Ihnen eingegebene SIP-Proxy-Adresse ist ungültig, sie muss mit „sip:“ gefolgt vom Hostnamen beginnen." -#: ../coreapi/proxy.c:334 +#: ../coreapi/proxy.c:298 msgid "" "The sip identity you entered is invalid.\n" "It should look like sip:username@proxydomain, such as sip:alice@example.net" msgstr "Die von Ihnen eingegebene SIP-Identität ist ungültig.\nSie sollte wie sip:benutzername@proxydomain aussehen, also z.B. sip:alice@beispiel.net" -#: ../coreapi/proxy.c:1416 +#: ../coreapi/proxy.c:927 +msgid "Looking for telephone number destination..." +msgstr "Telefonnummernziel wird gesucht..." + +#: ../coreapi/proxy.c:931 +msgid "Could not resolve this number." +msgstr "Diese Nummer kann nicht aufgelöst werden." + +#: ../coreapi/proxy.c:1324 #, c-format msgid "Could not login as %s" msgstr "Anmeldung als %s fehlgeschlagen" -#: ../coreapi/callbacks.c:428 +#: ../coreapi/proxy.c:1411 +#, c-format +msgid "Refreshing on %s..." +msgstr "Wird auf %s aktualisiert..." + +#: ../coreapi/callbacks.c:423 msgid "Remote ringing." msgstr "Klingeln bei der Gegenseite." -#: ../coreapi/callbacks.c:440 +#: ../coreapi/callbacks.c:435 msgid "Remote ringing..." msgstr "Klingeln bei der Gegenseite..." -#: ../coreapi/callbacks.c:461 +#: ../coreapi/callbacks.c:458 msgid "Early media." msgstr "nicht kompatibel, prüfe Codecs oder Sicherheitseinstellungen..." -#: ../coreapi/callbacks.c:534 +#: ../coreapi/callbacks.c:488 #, c-format -msgid "Call with %s is paused." -msgstr "Anruf mit %s wird gehalten." +msgid "Call answered by %s" +msgstr "Anruf wird von %s entgegengenommen" -#: ../coreapi/callbacks.c:547 -#, c-format -msgid "Call answered by %s - on hold." -msgstr "Der von %s entgegengenommene Anruf wird gehalten." - -#: ../coreapi/callbacks.c:557 +#: ../coreapi/callbacks.c:527 msgid "Call resumed." msgstr "Anruf fortgesetzt." -#: ../coreapi/callbacks.c:561 -#, c-format -msgid "Call answered by %s." -msgstr "Anruf wird von %s entgegengenommen." - -#: ../coreapi/callbacks.c:584 +#: ../coreapi/callbacks.c:582 msgid "Incompatible, check codecs or security settings..." -msgstr "Inkompatibel, prüfe Codecs oder Sicherheitseinstellungen..." +msgstr "Inkompatibel, überprüfen Sie die Codecs oder die Sicherheitseinstellungen..." -#: ../coreapi/callbacks.c:589 ../coreapi/callbacks.c:906 +#: ../coreapi/callbacks.c:587 ../coreapi/callbacks.c:923 msgid "Incompatible media parameters." msgstr "Inkompatible Medienparameter." -#: ../coreapi/callbacks.c:619 +#: ../coreapi/callbacks.c:612 msgid "We have been resumed." msgstr "Anruf wird fortgesetzt." #. we are being paused -#: ../coreapi/callbacks.c:628 +#: ../coreapi/callbacks.c:620 msgid "We are paused by other party." msgstr "Anruf wird von der Gegenseite gehalten." -#. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:666 +#: ../coreapi/callbacks.c:630 msgid "Call is updated by remote." msgstr "Anruf ist von der Gegenseite aktualisiert worden." -#: ../coreapi/callbacks.c:782 +#: ../coreapi/callbacks.c:799 msgid "Call terminated." msgstr "Anruf beendet." -#: ../coreapi/callbacks.c:810 +#: ../coreapi/callbacks.c:827 msgid "User is busy." msgstr "Teilnehmer ist besetzt." -#: ../coreapi/callbacks.c:811 +#: ../coreapi/callbacks.c:828 msgid "User is temporarily unavailable." msgstr "Teilnehmer zur Zeit nicht verfügbar." #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:813 +#: ../coreapi/callbacks.c:830 msgid "User does not want to be disturbed." msgstr "Teilnehmer möchte nicht gestört werden." -#: ../coreapi/callbacks.c:814 +#: ../coreapi/callbacks.c:831 msgid "Call declined." msgstr "Anruf abgewiesen" -#: ../coreapi/callbacks.c:829 +#: ../coreapi/callbacks.c:846 msgid "Request timeout." msgstr "Zeitüberschreitung bei der Anfrage" -#: ../coreapi/callbacks.c:860 +#: ../coreapi/callbacks.c:877 msgid "Redirected" msgstr "Umgeleitet" -#: ../coreapi/callbacks.c:915 +#: ../coreapi/callbacks.c:927 msgid "Call failed." msgstr "Anruf fehlgeschlagen." -#: ../coreapi/callbacks.c:993 +#: ../coreapi/callbacks.c:1005 #, c-format msgid "Registration on %s successful." msgstr "Registrierung auf %s erfolgreich." -#: ../coreapi/callbacks.c:994 +#: ../coreapi/callbacks.c:1006 #, c-format msgid "Unregistration on %s done." msgstr "Abmeldung von %s ist erfolgt." -#: ../coreapi/callbacks.c:1012 +#: ../coreapi/callbacks.c:1024 msgid "no response timeout" msgstr "Zeitüberschreitung bei der Antwort" -#: ../coreapi/callbacks.c:1015 +#: ../coreapi/callbacks.c:1027 #, c-format msgid "Registration on %s failed: %s" msgstr "Registrierung auf %s fehlgeschlagen: %s" -#: ../coreapi/callbacks.c:1022 +#: ../coreapi/callbacks.c:1034 msgid "Service unavailable, retrying" msgstr "Service nicht verfügbar, versuche erneut" #. if encryption is DTLS, no status to be displayed -#: ../coreapi/linphonecall.c:180 +#: ../coreapi/linphonecall.c:197 #, c-format msgid "Authentication token is %s" msgstr "Authentifizierungs-Token ist %s" -#: ../coreapi/linphonecall.c:1310 -msgid "Call parameters were successfully modified." -msgstr "" +#: ../coreapi/linphonecall.c:1561 +#, c-format +msgid "Call parameters could not be modified: %s." +msgstr "Anrufparameter konnten nicht geändert werden: %s." -#: ../coreapi/linphonecall.c:3686 +#: ../coreapi/linphonecall.c:1563 +msgid "Call parameters were successfully modified." +msgstr "Anrufparameter wurden erfolgreich geändert." + +#: ../coreapi/linphonecall.c:4396 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." msgstr[0] "Sie haben %i Anruf in Abwesenheit." msgstr[1] "Sie haben %i Anrufe in Abwesenheit." -#: ../coreapi/call_log.c:209 +#: ../coreapi/call_log.c:223 msgid "aborted" -msgstr "" +msgstr "abgebrochen" -#: ../coreapi/call_log.c:212 +#: ../coreapi/call_log.c:226 msgid "completed" -msgstr "" +msgstr "abgeschlossen" -#: ../coreapi/call_log.c:215 +#: ../coreapi/call_log.c:229 msgid "missed" -msgstr "" +msgstr "verpasst" -#: ../coreapi/call_log.c:218 +#: ../coreapi/call_log.c:232 msgid "unknown" -msgstr "" +msgstr "unbekannt" -#: ../coreapi/call_log.c:220 +#: ../coreapi/call_log.c:234 #, c-format msgid "" "%s at %s\n" @@ -1986,13 +2058,13 @@ msgid "" "To: %s\n" "Status: %s\n" "Duration: %i mn %i sec\n" -msgstr "" +msgstr "%s um %s\nVon: %s\nAn: %s\nStatus: %s\nDauer: %i Min. %i Sek.\n" -#: ../coreapi/call_log.c:221 +#: ../coreapi/call_log.c:235 msgid "Outgoing call" -msgstr "" +msgstr "Ausgehender Anruf" #: ../gtk/videowindow.c:66 #, c-format msgid "Cannot play %s." -msgstr "" +msgstr "Kann %s nicht wiedergeben." diff --git a/po/es.po b/po/es.po index 54548cf24..23ef01360 100644 --- a/po/es.po +++ b/po/es.po @@ -7,74 +7,83 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-04-30 10:13+0200\n" -"PO-Revision-Date: 2015-04-30 08:13+0000\n" +"POT-Creation-Date: 2015-11-10 15:16+0100\n" +"PO-Revision-Date: 2015-11-10 14:16+0000\n" "Last-Translator: Belledonne Communications \n" -"Language-Team: Spanish (http://www.transifex.com/projects/p/linphone-gtk/language/es/)\n" +"Language-Team: Spanish (http://www.transifex.com/belledonne-communications/linphone-gtk/language/es/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: es\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ../gtk/calllogs.c:148 ../gtk/friendlist.c:974 +#: ../gtk/calllogs.c:178 #, c-format msgid "Call %s" msgstr "Llamar a %s" -#: ../gtk/calllogs.c:149 ../gtk/friendlist.c:975 +#: ../gtk/calllogs.c:179 #, c-format msgid "Send text to %s" msgstr "Enviar mensaje a %s" -#: ../gtk/calllogs.c:232 +#: ../gtk/calllogs.c:181 +#, c-format +msgid "Add %s to your contact list" +msgstr "" + +#: ../gtk/calllogs.c:245 ../gtk/main.ui.h:21 +msgid "Recent calls" +msgstr "" + +#: ../gtk/calllogs.c:260 #, c-format msgid "Recent calls (%i)" msgstr "" -#: ../gtk/calllogs.c:314 +#: ../gtk/calllogs.c:331 msgid "n/a" msgstr "n/a" -#: ../gtk/calllogs.c:317 +#: ../gtk/calllogs.c:334 msgid "Aborted" msgstr "" -#: ../gtk/calllogs.c:320 +#: ../gtk/calllogs.c:337 msgid "Missed" msgstr "" -#: ../gtk/calllogs.c:323 +#: ../gtk/calllogs.c:340 msgid "Declined" msgstr "" -#: ../gtk/calllogs.c:329 +#: ../gtk/calllogs.c:346 #, c-format msgid "%i minute" msgid_plural "%i minutes" msgstr[0] "%i minuto" msgstr[1] "%i minutos" -#: ../gtk/calllogs.c:332 +#: ../gtk/calllogs.c:349 #, c-format msgid "%i second" msgid_plural "%i seconds" msgstr[0] "%i segundo" msgstr[1] "%i segundos" -#: ../gtk/calllogs.c:337 +#: ../gtk/calllogs.c:354 #, c-format msgid "" "%s\tQuality: %s\n" "%s\t%s\t" msgstr "" -#: ../gtk/calllogs.c:341 +#: ../gtk/calllogs.c:358 #, c-format msgid "%s\t%s" msgstr "" -#: ../gtk/conference.c:38 ../gtk/main.ui.h:13 +#: ../gtk/conference.c:38 ../gtk/in_call_frame.ui.h:11 msgid "Conference" msgstr "Conferencia" @@ -87,297 +96,314 @@ msgstr "Yo" msgid "Couldn't find pixmap file: %s" msgstr "No se pudo encontrar el archivo pixmap: %s" -#: ../gtk/main.c:137 +#: ../gtk/chat.c:196 ../gtk/chat.c:254 +msgid "Sending..." +msgstr "" + +#: ../gtk/chat.c:213 ../gtk/chat.c:263 +msgid "Message not sent" +msgstr "" + +#: ../gtk/chat.c:472 +msgid "Copy" +msgstr "" + +#: ../gtk/main.c:138 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:138 -msgid "path to a file to write logs into." -msgstr "ruta a un fichero donde escribir logs." - #: ../gtk/main.c:139 -msgid "Start linphone with video disabled." +msgid "display version and exit." msgstr "" #: ../gtk/main.c:140 +msgid "path to a file to write logs into." +msgstr "ruta a un fichero donde escribir logs." + +#: ../gtk/main.c:141 +msgid "Start linphone with video disabled." +msgstr "" + +#: ../gtk/main.c:142 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:141 +#: ../gtk/main.c:143 msgid "address to call right now" msgstr "dirección a la que llamar inmediatamente" -#: ../gtk/main.c:142 +#: ../gtk/main.c:144 msgid "" "Specifiy a working directory (should be the base of the installation, eg: " "c:\\Program Files\\Linphone)" 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:143 +#: ../gtk/main.c:145 msgid "Configuration file" msgstr "" -#: ../gtk/main.c:144 +#: ../gtk/main.c:146 msgid "Run the audio assistant" msgstr "" -#: ../gtk/main.c:145 +#: ../gtk/main.c:147 msgid "Run self test and exit 0 if succeed" msgstr "" -#: ../gtk/main.c:1070 +#: ../gtk/main.c:1046 #, c-format msgid "" -"%s would like to add you to his contact list.\n" -"Would you allow him to see your presence status or add him to your contact list ?\n" +"%s would like to add you to his/her contact list.\n" +"Would you add him/her to your contact list and allow him/her to see your presence status?\n" "If you answer no, this person will be temporarily blacklisted." -msgstr "%s desea añadirle a su lista de contactos.\n¿Desea permitirle ver su estado de presencia o añadirle a su lista de contactos?\nSi responde no, esta persona será bloqueada temporalmente." +msgstr "" -#: ../gtk/main.c:1147 +#: ../gtk/main.c:1123 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" msgstr "" -#: ../gtk/main.c:1268 +#: ../gtk/main.c:1253 msgid "Call error" msgstr "" -#: ../gtk/main.c:1271 ../coreapi/linphonecore.c:3846 +#: ../gtk/main.c:1256 ../coreapi/linphonecore.c:3813 msgid "Call ended" msgstr "" -#: ../gtk/main.c:1274 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1259 ../coreapi/call_log.c:235 msgid "Incoming call" msgstr "Llamada entrante" -#: ../gtk/main.c:1276 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1261 ../gtk/incall_view.c:580 ../gtk/in_call_frame.ui.h:2 msgid "Answer" msgstr "Contestar" -#: ../gtk/main.c:1278 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1263 ../gtk/in_call_frame.ui.h:3 msgid "Decline" msgstr "" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 msgid "Call paused" msgstr "" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 #, c-format msgid "by %s" msgstr "" -#: ../gtk/main.c:1354 +#: ../gtk/main.c:1339 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "" -#: ../gtk/main.c:1509 +#: ../gtk/main.c:1505 msgid "Website link" msgstr "Enlace a la Web" -#: ../gtk/main.c:1568 ../gtk/waiting.ui.h:1 +#: ../gtk/main.c:1564 ../gtk/waiting.ui.h:1 msgid "Linphone" msgstr "" -#: ../gtk/main.c:1569 +#: ../gtk/main.c:1565 msgid "A video internet phone" msgstr "" -#: ../gtk/main.c:1629 +#: ../gtk/main.c:1624 #, c-format msgid "%s (Default)" msgstr "%s (Opción predeterminada)" -#: ../gtk/main.c:1962 ../coreapi/callbacks.c:1063 +#: ../gtk/main.c:1960 ../coreapi/callbacks.c:1075 #, c-format msgid "We are transferred to %s" msgstr "Somos transferidos a %s" -#: ../gtk/main.c:1972 +#: ../gtk/main.c:1970 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." msgstr "No se ha encontrado una tarjeta de sonido en este equipo.\nNo será posible realizar o recibir llamadas de audio." -#: ../gtk/main.c:2117 +#: ../gtk/main.c:2129 msgid "A free SIP video-phone" msgstr "Un video-teléfono SIP gratuito" -#: ../gtk/main.c:2221 +#: ../gtk/main.c:2242 #, c-format msgid "Hello\n" msgstr "" -#: ../gtk/friendlist.c:505 +#: ../gtk/friendlist.c:461 msgid "Add to addressbook" msgstr "" -#: ../gtk/friendlist.c:691 -msgid "Presence status" -msgstr "" - -#: ../gtk/friendlist.c:709 ../gtk/propertybox.c:569 ../gtk/contact.ui.h:1 -msgid "Name" -msgstr "Nombre" - -#: ../gtk/friendlist.c:721 -msgid "Call" -msgstr "" - -#: ../gtk/friendlist.c:726 -msgid "Chat" -msgstr "" - -#: ../gtk/friendlist.c:756 +#: ../gtk/friendlist.c:627 #, c-format msgid "Search in %s directory" msgstr "Buscar en el directorio %s" -#: ../gtk/friendlist.c:924 +#: ../gtk/friendlist.c:772 msgid "Invalid sip contact !" msgstr "¡Contacto SIP no válido!" -#: ../gtk/friendlist.c:976 +#: ../gtk/friendlist.c:820 +#, c-format +msgid "Add a new contact" +msgstr "" + +#: ../gtk/friendlist.c:823 #, c-format msgid "Edit contact '%s'" msgstr "" -#: ../gtk/friendlist.c:977 +#: ../gtk/friendlist.c:824 #, c-format msgid "Delete contact '%s'" msgstr "Eliminar contacto '%s'" -#: ../gtk/friendlist.c:978 +#: ../gtk/friendlist.c:825 #, c-format msgid "Delete chat history of '%s'" msgstr "" -#: ../gtk/friendlist.c:1029 +#: ../gtk/friendlist.c:862 #, c-format msgid "Add new contact from %s directory" msgstr "Añadir nuevo contacto desde el directorio %s" -#: ../gtk/propertybox.c:575 +#: ../gtk/propertybox.c:592 ../gtk/contact.ui.h:1 +msgid "Name" +msgstr "Nombre" + +#: ../gtk/propertybox.c:598 msgid "Rate (Hz)" msgstr "Frecuencia (Hz)" -#: ../gtk/propertybox.c:581 +#: ../gtk/propertybox.c:604 msgid "Status" msgstr "Estado" -#: ../gtk/propertybox.c:587 +#: ../gtk/propertybox.c:617 msgid "IP Bitrate (kbit/s)" msgstr "" -#: ../gtk/propertybox.c:596 +#: ../gtk/propertybox.c:628 msgid "Parameters" msgstr "Parámetros" -#: ../gtk/propertybox.c:639 ../gtk/propertybox.c:782 +#: ../gtk/propertybox.c:670 ../gtk/propertybox.c:824 msgid "Enabled" msgstr "Activado" -#: ../gtk/propertybox.c:641 ../gtk/propertybox.c:782 ../gtk/parameters.ui.h:20 +#: ../gtk/propertybox.c:672 ../gtk/propertybox.c:824 ../gtk/parameters.ui.h:60 msgid "Disabled" msgstr "Desactivado" -#: ../gtk/propertybox.c:828 +#: ../gtk/propertybox.c:902 msgid "Account" msgstr "Cuenta" -#: ../gtk/propertybox.c:1091 +#: ../gtk/propertybox.c:1170 msgid "English" msgstr "Inglés" -#: ../gtk/propertybox.c:1092 +#: ../gtk/propertybox.c:1171 msgid "French" msgstr "Francés" -#: ../gtk/propertybox.c:1093 +#: ../gtk/propertybox.c:1172 msgid "Swedish" msgstr "Sueco" -#: ../gtk/propertybox.c:1094 +#: ../gtk/propertybox.c:1173 msgid "Italian" msgstr "Italiano" -#: ../gtk/propertybox.c:1095 +#: ../gtk/propertybox.c:1174 msgid "Spanish" msgstr "Español" -#: ../gtk/propertybox.c:1096 +#: ../gtk/propertybox.c:1175 msgid "Brazilian Portugese" msgstr "Portugués de Brasil" -#: ../gtk/propertybox.c:1097 +#: ../gtk/propertybox.c:1176 msgid "Polish" msgstr "Polaco" -#: ../gtk/propertybox.c:1098 +#: ../gtk/propertybox.c:1177 msgid "German" msgstr "Alemán" -#: ../gtk/propertybox.c:1099 +#: ../gtk/propertybox.c:1178 msgid "Russian" msgstr "Ruso" -#: ../gtk/propertybox.c:1100 +#: ../gtk/propertybox.c:1179 msgid "Japanese" msgstr "Japonés" -#: ../gtk/propertybox.c:1101 +#: ../gtk/propertybox.c:1180 msgid "Dutch" msgstr "Holandés" -#: ../gtk/propertybox.c:1102 +#: ../gtk/propertybox.c:1181 msgid "Hungarian" msgstr "Húngaro" -#: ../gtk/propertybox.c:1103 +#: ../gtk/propertybox.c:1182 msgid "Czech" msgstr "Checo" -#: ../gtk/propertybox.c:1104 +#: ../gtk/propertybox.c:1183 msgid "Chinese" msgstr "Chino" -#: ../gtk/propertybox.c:1105 +#: ../gtk/propertybox.c:1184 msgid "Traditional Chinese" msgstr "Chino Tradicional" -#: ../gtk/propertybox.c:1106 +#: ../gtk/propertybox.c:1185 msgid "Norwegian" msgstr "Noruego" -#: ../gtk/propertybox.c:1107 +#: ../gtk/propertybox.c:1186 msgid "Hebrew" msgstr "" -#: ../gtk/propertybox.c:1108 +#: ../gtk/propertybox.c:1187 msgid "Serbian" msgstr "" -#: ../gtk/propertybox.c:1175 +#: ../gtk/propertybox.c:1188 +msgid "Arabic" +msgstr "" + +#: ../gtk/propertybox.c:1189 +msgid "Turkish" +msgstr "" + +#: ../gtk/propertybox.c:1246 msgid "" "You need to restart linphone for the new language selection to take effect." msgstr "Deberá reiniciar linphone para aplicar la nueva selección de lenguaje" -#: ../gtk/propertybox.c:1255 +#: ../gtk/propertybox.c:1326 msgid "None" msgstr "" -#: ../gtk/propertybox.c:1259 +#: ../gtk/propertybox.c:1330 msgid "SRTP" msgstr "SRTP" -#: ../gtk/propertybox.c:1265 +#: ../gtk/propertybox.c:1336 msgid "DTLS" msgstr "" -#: ../gtk/propertybox.c:1272 +#: ../gtk/propertybox.c:1343 msgid "ZRTP" msgstr "ZRTP" @@ -419,324 +445,195 @@ msgid_plural "Found %i contacts" msgstr[0] "Se encontró %i contacto" msgstr[1] "Se encontraron %i contactos" -#: ../gtk/setupwizard.c:32 -msgid "" -"Welcome!\n" -"This assistant will help you to use a SIP account for your calls." -msgstr "" - -#: ../gtk/setupwizard.c:41 -msgid "Create an account on linphone.org" -msgstr "" - -#: ../gtk/setupwizard.c:42 -msgid "I have already a linphone.org account and I just want to use it" -msgstr "" - -#: ../gtk/setupwizard.c:43 -msgid "I have already a sip account and I just want to use it" -msgstr "" - -#: ../gtk/setupwizard.c:44 -msgid "I want to specify a remote configuration URI" -msgstr "" - -#: ../gtk/setupwizard.c:87 -msgid "Enter your linphone.org username" -msgstr "" - -#: ../gtk/setupwizard.c:100 ../gtk/parameters.ui.h:85 ../gtk/ldap.ui.h:4 -msgid "Username:" -msgstr "" - -#: ../gtk/setupwizard.c:102 ../gtk/password.ui.h:4 ../gtk/ldap.ui.h:5 -msgid "Password:" -msgstr "" - -#: ../gtk/setupwizard.c:122 -msgid "Enter your account informations" -msgstr "" - -#: ../gtk/setupwizard.c:138 -msgid "Username*" -msgstr "" - -#: ../gtk/setupwizard.c:139 -msgid "Password*" -msgstr "" - -#: ../gtk/setupwizard.c:142 -msgid "Domain*" -msgstr "" - -#: ../gtk/setupwizard.c:143 -msgid "Proxy" -msgstr "" - -#: ../gtk/setupwizard.c:322 -msgid "(*) Required fields" -msgstr "" - -#: ../gtk/setupwizard.c:323 -msgid "Username: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:325 -msgid "Password: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:327 -msgid "Email: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:329 -msgid "Confirm your password: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:343 -msgid "Keep me informed with linphone updates" -msgstr "" - -#: ../gtk/setupwizard.c:399 -msgid "" -"Error, account not validated, username already used or server unreachable.\n" -"Please go back and try again." -msgstr "" - -#: ../gtk/setupwizard.c:410 -msgid "Thank you. Your account is now configured and ready for use." -msgstr "Gracias. Su cuenta está configurada y lista para su utilización." - -#: ../gtk/setupwizard.c:418 -msgid "" -"Please validate your account by clicking on the link we just sent you by email.\n" -"Then come back here and press Next button." -msgstr "" - -#: ../gtk/setupwizard.c:609 -msgid "SIP account configuration assistant" -msgstr "" - -#: ../gtk/setupwizard.c:629 -msgid "Welcome to the account setup assistant" -msgstr "Bienvenido al asistente de configuración de cuenta" - -#: ../gtk/setupwizard.c:634 -msgid "Account setup assistant" -msgstr "Asistente de configuración de cuenta" - -#: ../gtk/setupwizard.c:640 -msgid "Configure your account (step 1/1)" -msgstr "" - -#: ../gtk/setupwizard.c:645 -msgid "Enter your sip username (step 1/1)" -msgstr "" - -#: ../gtk/setupwizard.c:649 -msgid "Enter account information (step 1/2)" -msgstr "" - -#: ../gtk/setupwizard.c:658 -msgid "Validation (step 2/2)" -msgstr "" - -#: ../gtk/setupwizard.c:663 -msgid "Error" -msgstr "" - -#: ../gtk/setupwizard.c:667 ../gtk/audio_assistant.c:534 -msgid "Terminating" -msgstr "" - -#: ../gtk/incall_view.c:70 ../gtk/incall_view.c:94 +#: ../gtk/incall_view.c:67 ../gtk/incall_view.c:87 #, c-format msgid "Call #%i" msgstr "" -#: ../gtk/incall_view.c:155 +#: ../gtk/incall_view.c:145 #, c-format msgid "Transfer to call #%i with %s" msgstr "Transferir a llamada #%i con %s" -#: ../gtk/incall_view.c:211 ../gtk/incall_view.c:214 +#: ../gtk/incall_view.c:202 ../gtk/incall_view.c:205 msgid "Not used" msgstr "" -#: ../gtk/incall_view.c:221 +#: ../gtk/incall_view.c:212 msgid "ICE not activated" msgstr "" -#: ../gtk/incall_view.c:223 +#: ../gtk/incall_view.c:214 msgid "ICE failed" msgstr "" -#: ../gtk/incall_view.c:225 +#: ../gtk/incall_view.c:216 msgid "ICE in progress" msgstr "" -#: ../gtk/incall_view.c:227 +#: ../gtk/incall_view.c:218 msgid "Going through one or more NATs" msgstr "" -#: ../gtk/incall_view.c:229 +#: ../gtk/incall_view.c:220 msgid "Direct" msgstr "" -#: ../gtk/incall_view.c:231 +#: ../gtk/incall_view.c:222 msgid "Through a relay server" msgstr "" -#: ../gtk/incall_view.c:239 +#: ../gtk/incall_view.c:230 msgid "uPnP not activated" msgstr "" -#: ../gtk/incall_view.c:241 +#: ../gtk/incall_view.c:232 msgid "uPnP in progress" msgstr "" -#: ../gtk/incall_view.c:243 +#: ../gtk/incall_view.c:234 msgid "uPnp not available" msgstr "" -#: ../gtk/incall_view.c:245 +#: ../gtk/incall_view.c:236 msgid "uPnP is running" msgstr "" -#: ../gtk/incall_view.c:247 +#: ../gtk/incall_view.c:238 msgid "uPnP failed" msgstr "" -#: ../gtk/incall_view.c:257 ../gtk/incall_view.c:258 +#: ../gtk/incall_view.c:248 ../gtk/incall_view.c:249 msgid "Direct or through server" msgstr "" -#: ../gtk/incall_view.c:267 ../gtk/incall_view.c:279 +#: ../gtk/incall_view.c:258 ../gtk/incall_view.c:270 #, c-format msgid "" "download: %f\n" "upload: %f (kbit/s)" msgstr "" -#: ../gtk/incall_view.c:272 ../gtk/incall_view.c:274 +#: ../gtk/incall_view.c:263 ../gtk/incall_view.c:265 #, c-format msgid "%ix%i @ %f fps" msgstr "" -#: ../gtk/incall_view.c:304 +#: ../gtk/incall_view.c:295 #, c-format msgid "%.3f seconds" msgstr "" -#: ../gtk/incall_view.c:407 ../gtk/main.ui.h:12 ../gtk/videowindow.c:235 +#: ../gtk/incall_view.c:453 ../gtk/in_call_frame.ui.h:10 +#: ../gtk/videowindow.c:236 msgid "Hang up" msgstr "" -#: ../gtk/incall_view.c:511 +#: ../gtk/incall_view.c:559 msgid "Calling..." msgstr "" -#: ../gtk/incall_view.c:514 ../gtk/incall_view.c:733 -msgid "00::00::00" -msgstr "00::00::00" +#: ../gtk/incall_view.c:562 ../gtk/incall_view.c:792 +msgid "00:00:00" +msgstr "" -#: ../gtk/incall_view.c:525 +#: ../gtk/incall_view.c:573 msgid "Incoming call" msgstr "" -#: ../gtk/incall_view.c:562 +#: ../gtk/incall_view.c:610 msgid "good" msgstr "buena" -#: ../gtk/incall_view.c:564 +#: ../gtk/incall_view.c:612 msgid "average" msgstr "media" -#: ../gtk/incall_view.c:566 +#: ../gtk/incall_view.c:614 msgid "poor" msgstr "mala" -#: ../gtk/incall_view.c:568 +#: ../gtk/incall_view.c:616 msgid "very poor" msgstr "muy mala" -#: ../gtk/incall_view.c:570 +#: ../gtk/incall_view.c:618 msgid "too bad" msgstr "demasiado mala" -#: ../gtk/incall_view.c:571 ../gtk/incall_view.c:587 +#: ../gtk/incall_view.c:619 ../gtk/incall_view.c:635 msgid "unavailable" msgstr "no disponible" -#: ../gtk/incall_view.c:679 +#: ../gtk/incall_view.c:731 msgid "Secured by SRTP" msgstr "Cifrada con SRTP" -#: ../gtk/incall_view.c:685 +#: ../gtk/incall_view.c:737 msgid "Secured by DTLS" msgstr "" -#: ../gtk/incall_view.c:691 +#: ../gtk/incall_view.c:743 #, c-format msgid "Secured by ZRTP - [auth token: %s]" msgstr "Cifrada con ZRTP - [token de autenticación: %s]" -#: ../gtk/incall_view.c:697 +#: ../gtk/incall_view.c:747 msgid "Set unverified" msgstr "Set sin verificar" -#: ../gtk/incall_view.c:697 ../gtk/main.ui.h:4 +#: ../gtk/incall_view.c:747 msgid "Set verified" msgstr "Set verificado" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In conference" msgstr "En conferencia" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In call" msgstr "" -#: ../gtk/incall_view.c:764 +#: ../gtk/incall_view.c:824 msgid "Paused call" msgstr "" -#: ../gtk/incall_view.c:800 +#: ../gtk/incall_view.c:861 msgid "Call ended." msgstr "" -#: ../gtk/incall_view.c:831 +#: ../gtk/incall_view.c:892 msgid "Transfer in progress" msgstr "" -#: ../gtk/incall_view.c:834 +#: ../gtk/incall_view.c:895 msgid "Transfer done." msgstr "" -#: ../gtk/incall_view.c:837 +#: ../gtk/incall_view.c:898 msgid "Transfer failed." msgstr "" -#: ../gtk/incall_view.c:881 +#: ../gtk/incall_view.c:929 msgid "Resume" msgstr "Reanudar" -#: ../gtk/incall_view.c:888 ../gtk/main.ui.h:9 +#: ../gtk/incall_view.c:929 ../gtk/in_call_frame.ui.h:7 msgid "Pause" msgstr "Pausar" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 #, c-format msgid "" "Recording into\n" "%s %s" msgstr "" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 msgid "(Paused)" msgstr "" -#: ../gtk/loginframe.c:87 +#: ../gtk/loginframe.c:75 #, c-format msgid "Please enter login information for %s" msgstr "Por favor, introduzca los datos de inicio de sesión para %s" @@ -751,262 +648,107 @@ msgstr "" msgid "Downloading of remote configuration from %s failed." msgstr "" -#: ../gtk/audio_assistant.c:98 +#: ../gtk/audio_assistant.c:103 msgid "No voice detected" msgstr "" -#: ../gtk/audio_assistant.c:99 +#: ../gtk/audio_assistant.c:104 msgid "Too low" msgstr "" -#: ../gtk/audio_assistant.c:100 +#: ../gtk/audio_assistant.c:105 msgid "Good" msgstr "" -#: ../gtk/audio_assistant.c:101 +#: ../gtk/audio_assistant.c:106 msgid "Too loud" msgstr "" -#: ../gtk/audio_assistant.c:183 +#: ../gtk/audio_assistant.c:188 msgid "Did you hear three beeps ?" msgstr "" -#: ../gtk/audio_assistant.c:292 ../gtk/audio_assistant.c:297 +#: ../gtk/audio_assistant.c:299 ../gtk/audio_assistant.c:304 msgid "Sound preferences not found " msgstr "" -#: ../gtk/audio_assistant.c:306 +#: ../gtk/audio_assistant.c:313 msgid "Cannot launch system sound control " msgstr "" -#: ../gtk/audio_assistant.c:318 +#: ../gtk/audio_assistant.c:325 msgid "" "Welcome!\n" "This assistant will help you to configure audio settings for Linphone" msgstr "" -#: ../gtk/audio_assistant.c:328 +#: ../gtk/audio_assistant.c:335 msgid "Capture device" msgstr "" -#: ../gtk/audio_assistant.c:329 +#: ../gtk/audio_assistant.c:336 msgid "Recorded volume" msgstr "" -#: ../gtk/audio_assistant.c:333 +#: ../gtk/audio_assistant.c:340 msgid "No voice" msgstr "" -#: ../gtk/audio_assistant.c:334 ../gtk/audio_assistant.c:373 +#: ../gtk/audio_assistant.c:341 ../gtk/audio_assistant.c:380 msgid "System sound preferences" msgstr "" -#: ../gtk/audio_assistant.c:369 +#: ../gtk/audio_assistant.c:376 msgid "Playback device" msgstr "" -#: ../gtk/audio_assistant.c:370 +#: ../gtk/audio_assistant.c:377 msgid "Play three beeps" msgstr "" -#: ../gtk/audio_assistant.c:403 +#: ../gtk/audio_assistant.c:410 msgid "Press the record button and say some words" msgstr "" -#: ../gtk/audio_assistant.c:404 +#: ../gtk/audio_assistant.c:411 msgid "Listen to your record voice" msgstr "" -#: ../gtk/audio_assistant.c:405 +#: ../gtk/audio_assistant.c:412 ../gtk/conf_frame.ui.h:2 +#: ../gtk/in_call_frame.ui.h:4 msgid "Record" msgstr "" -#: ../gtk/audio_assistant.c:406 +#: ../gtk/audio_assistant.c:413 msgid "Play" msgstr "" -#: ../gtk/audio_assistant.c:433 +#: ../gtk/audio_assistant.c:440 msgid "Let's start Linphone now" msgstr "" -#: ../gtk/audio_assistant.c:503 +#: ../gtk/audio_assistant.c:510 msgid "Audio Assistant" msgstr "" -#: ../gtk/audio_assistant.c:513 ../gtk/main.ui.h:32 +#: ../gtk/audio_assistant.c:520 ../gtk/main.ui.h:13 msgid "Audio assistant" msgstr "" -#: ../gtk/audio_assistant.c:518 +#: ../gtk/audio_assistant.c:525 msgid "Mic Gain calibration" msgstr "" -#: ../gtk/audio_assistant.c:524 +#: ../gtk/audio_assistant.c:531 msgid "Speaker volume calibration" msgstr "" -#: ../gtk/audio_assistant.c:529 +#: ../gtk/audio_assistant.c:536 msgid "Record and Play" msgstr "" -#: ../gtk/main.ui.h:1 -msgid "Callee name" -msgstr "" - -#: ../gtk/main.ui.h:2 -msgid "Send" -msgstr "" - -#: ../gtk/main.ui.h:3 -msgid "End conference" -msgstr "" - -#: ../gtk/main.ui.h:7 -msgid "Record this call to an audio file" -msgstr "" - -#: ../gtk/main.ui.h:8 -msgid "Video" -msgstr "" - -#: ../gtk/main.ui.h:10 -msgid "Mute" -msgstr "" - -#: ../gtk/main.ui.h:11 -msgid "Transfer" -msgstr "Transferir" - -#: ../gtk/main.ui.h:14 -msgid "In call" -msgstr "" - -#: ../gtk/main.ui.h:15 -msgid "Duration" -msgstr "" - -#: ../gtk/main.ui.h:16 -msgid "Call quality rating" -msgstr "Calidad de la llamada" - -#: ../gtk/main.ui.h:17 -msgid "All users" -msgstr "Todos los usuarios" - -#: ../gtk/main.ui.h:18 -msgid "Online users" -msgstr "" - -#: ../gtk/main.ui.h:19 -msgid "ADSL" -msgstr "ADSL" - -#: ../gtk/main.ui.h:20 -msgid "Fiber Channel" -msgstr "Canal de Fibra" - -#: ../gtk/main.ui.h:21 -msgid "Default" -msgstr "" - -#: ../gtk/main.ui.h:22 -msgid "Delete" -msgstr "" - -#: ../gtk/main.ui.h:23 -msgid "_Options" -msgstr "_Opciones" - -#: ../gtk/main.ui.h:24 -msgid "Set configuration URI" -msgstr "" - -#: ../gtk/main.ui.h:25 -msgid "Always start video" -msgstr "" - -#: ../gtk/main.ui.h:26 -msgid "Enable self-view" -msgstr "" - -#: ../gtk/main.ui.h:27 -msgid "_Help" -msgstr "_Ayuda" - -#: ../gtk/main.ui.h:28 -msgid "Show debug window" -msgstr "" - -#: ../gtk/main.ui.h:29 -msgid "_Homepage" -msgstr "_Pagina_de_Inicio" - -#: ../gtk/main.ui.h:30 -msgid "Check _Updates" -msgstr "Buscar_Actualizaciones" - -#: ../gtk/main.ui.h:31 -msgid "Account assistant" -msgstr "" - -#: ../gtk/main.ui.h:33 -msgid "SIP address or phone number:" -msgstr "" - -#: ../gtk/main.ui.h:34 -msgid "Initiate a new call" -msgstr "Iniciar nueva llamada" - -#: ../gtk/main.ui.h:35 -msgid "Contacts" -msgstr "" - -#: ../gtk/main.ui.h:36 -msgid "Search" -msgstr "Buscar" - -#: ../gtk/main.ui.h:37 -msgid "Add contacts from directory" -msgstr "" - -#: ../gtk/main.ui.h:38 -msgid "Add contact" -msgstr "" - -#: ../gtk/main.ui.h:39 -msgid "Recent calls" -msgstr "" - -#: ../gtk/main.ui.h:40 -msgid "My current identity:" -msgstr "" - -#: ../gtk/main.ui.h:41 ../gtk/tunnel_config.ui.h:7 -msgid "Username" -msgstr "" - -#: ../gtk/main.ui.h:42 ../gtk/tunnel_config.ui.h:8 -msgid "Password" -msgstr "" - -#: ../gtk/main.ui.h:43 -msgid "Internet connection:" -msgstr "Conexión a Internet" - -#: ../gtk/main.ui.h:44 -msgid "Automatically log me in" -msgstr "Iniciar sesión automáticamente" - -#: ../gtk/main.ui.h:45 ../gtk/password.ui.h:3 -msgid "UserID" -msgstr "UserID" - -#: ../gtk/main.ui.h:46 -msgid "Login information" -msgstr "" - -#: ../gtk/main.ui.h:47 -msgid "Welcome!" +#: ../gtk/audio_assistant.c:541 ../gtk/setup_wizard.ui.h:38 +msgid "Terminating" msgstr "" #: ../gtk/about.ui.h:1 @@ -1037,456 +779,6 @@ msgid "" "he: Eli Zaretskii \n" msgstr "" -#: ../gtk/contact.ui.h:2 -msgid "SIP Address" -msgstr "" - -#: ../gtk/contact.ui.h:3 -msgid "Show this contact presence status" -msgstr "Mostrar el estado de presencia de este contacto" - -#: ../gtk/contact.ui.h:4 -msgid "Allow this contact to see my presence status" -msgstr "Permitir que este contacto vea mi estado de presencia" - -#: ../gtk/contact.ui.h:5 -msgid "Contact information" -msgstr "" - -#: ../gtk/log.ui.h:1 -msgid "Linphone debug window" -msgstr "" - -#: ../gtk/log.ui.h:2 -msgid "Scroll to end" -msgstr "" - -#: ../gtk/password.ui.h:1 -msgid "Linphone - Authentication required" -msgstr "" - -#: ../gtk/password.ui.h:2 -msgid "Please enter the domain password" -msgstr "Por favor introduzca la contraseña del dominio" - -#: ../gtk/call_logs.ui.h:1 -msgid "Call history" -msgstr "Registro de llamadas" - -#: ../gtk/call_logs.ui.h:2 -msgid "Clear all" -msgstr "Borrar todos" - -#: ../gtk/call_logs.ui.h:3 -msgid "Call back" -msgstr "Devolver llamada" - -#: ../gtk/sip_account.ui.h:1 -msgid "Linphone - Configure a SIP account" -msgstr "Linphone - Configurar una cuenta SIP" - -#: ../gtk/sip_account.ui.h:2 -msgid "Your SIP identity:" -msgstr "" - -#: ../gtk/sip_account.ui.h:3 -msgid "Looks like sip:@" -msgstr "Del tipo sip:@" - -#: ../gtk/sip_account.ui.h:4 -msgid "sip:" -msgstr "sip:" - -#: ../gtk/sip_account.ui.h:5 -msgid "SIP Proxy address:" -msgstr "" - -#: ../gtk/sip_account.ui.h:6 -msgid "Looks like sip:" -msgstr "Del tipo sip:" - -#: ../gtk/sip_account.ui.h:7 -msgid "Registration duration (sec):" -msgstr "" - -#: ../gtk/sip_account.ui.h:8 -msgid "Contact params (optional):" -msgstr "" - -#: ../gtk/sip_account.ui.h:9 -msgid "AVPF regular RTCP interval (sec):" -msgstr "" - -#: ../gtk/sip_account.ui.h:10 -msgid "Route (optional):" -msgstr "Ruta (opcional):" - -#: ../gtk/sip_account.ui.h:11 -msgid "Transport" -msgstr "" - -#: ../gtk/sip_account.ui.h:12 -msgid "Register" -msgstr "Registrarse" - -#: ../gtk/sip_account.ui.h:13 -msgid "Publish presence information" -msgstr "" - -#: ../gtk/sip_account.ui.h:14 -msgid "Enable AVPF" -msgstr "" - -#: ../gtk/sip_account.ui.h:15 -msgid "Configure a SIP account" -msgstr "Configurar una cuenta SIP" - -#: ../gtk/parameters.ui.h:1 -msgid "anonymous" -msgstr "" - -#: ../gtk/parameters.ui.h:2 -msgid "GSSAPI" -msgstr "" - -#: ../gtk/parameters.ui.h:3 -msgid "SASL" -msgstr "" - -#: ../gtk/parameters.ui.h:4 -msgid "default soundcard" -msgstr "tarjeta de sonido predeterminada" - -#: ../gtk/parameters.ui.h:5 -msgid "a sound card" -msgstr "una tarjeta de sonido" - -#: ../gtk/parameters.ui.h:6 -msgid "default camera" -msgstr "cámara predeterminada" - -#: ../gtk/parameters.ui.h:7 -msgid "CIF" -msgstr "CIF" - -#: ../gtk/parameters.ui.h:8 -msgid "Audio codecs" -msgstr "" - -#: ../gtk/parameters.ui.h:9 -msgid "Video codecs" -msgstr "" - -#: ../gtk/parameters.ui.h:10 -msgid "C" -msgstr "C" - -#: ../gtk/parameters.ui.h:11 -msgid "SIP (UDP)" -msgstr "SIP (UDP)" - -#: ../gtk/parameters.ui.h:12 -msgid "SIP (TCP)" -msgstr "SIP (TCP)" - -#: ../gtk/parameters.ui.h:13 -msgid "SIP (TLS)" -msgstr "SIP (TLS)" - -#: ../gtk/parameters.ui.h:14 -msgid "Settings" -msgstr "Configuración" - -#: ../gtk/parameters.ui.h:15 -msgid "Set Maximum Transmission Unit:" -msgstr "Fijar Unidad de Transmisión Máxima:" - -#: ../gtk/parameters.ui.h:16 -msgid "Send DTMFs as SIP info" -msgstr "Enviar DTMFs como información SIP" - -#: ../gtk/parameters.ui.h:17 -msgid "Allow IPv6" -msgstr "" - -#: ../gtk/parameters.ui.h:18 -msgid "Transport" -msgstr "" - -#: ../gtk/parameters.ui.h:19 -msgid "SIP/UDP port" -msgstr "" - -#: ../gtk/parameters.ui.h:21 -msgid "Random" -msgstr "" - -#: ../gtk/parameters.ui.h:22 -msgid "SIP/TCP port" -msgstr "" - -#: ../gtk/parameters.ui.h:23 -msgid "Audio RTP/UDP:" -msgstr "Audio RTP/UDP:" - -#: ../gtk/parameters.ui.h:24 -msgid "Fixed" -msgstr "" - -#: ../gtk/parameters.ui.h:25 -msgid "Video RTP/UDP:" -msgstr "Vídeo RTP/UDP" - -#: ../gtk/parameters.ui.h:26 -msgid "Media encryption type" -msgstr "Tipo de cifrado de medios" - -#: ../gtk/parameters.ui.h:27 -msgid "Media encryption is mandatory" -msgstr "" - -#: ../gtk/parameters.ui.h:28 -msgid "Tunnel" -msgstr "" - -#: ../gtk/parameters.ui.h:29 -msgid "DSCP fields" -msgstr "" - -#: ../gtk/parameters.ui.h:30 -msgid "Network protocol and ports" -msgstr "Protocolo de red y puertos" - -#: ../gtk/parameters.ui.h:31 -msgid "Direct connection to the Internet" -msgstr "Conexión directa a Internet" - -#: ../gtk/parameters.ui.h:32 -msgid "Behind NAT / Firewall (specify gateway IP )" -msgstr "" - -#: ../gtk/parameters.ui.h:33 -msgid "Behind NAT / Firewall (use STUN to resolve)" -msgstr "Tras un NAT/Firewall (utilizar STUN para resolver)" - -#: ../gtk/parameters.ui.h:34 -msgid "Behind NAT / Firewall (use ICE)" -msgstr "" - -#: ../gtk/parameters.ui.h:35 -msgid "Behind NAT / Firewall (use uPnP)" -msgstr "" - -#: ../gtk/parameters.ui.h:36 -msgid "Public IP address:" -msgstr "" - -#: ../gtk/parameters.ui.h:37 -msgid "Stun server:" -msgstr "" - -#: ../gtk/parameters.ui.h:38 -msgid "NAT and Firewall" -msgstr "" - -#: ../gtk/parameters.ui.h:39 -msgid "Network settings" -msgstr "" - -#: ../gtk/parameters.ui.h:40 -msgid "Ring sound:" -msgstr "" - -#: ../gtk/parameters.ui.h:41 -msgid "ALSA special device (optional):" -msgstr "Dispositivo especial ALSA (opcional):" - -#: ../gtk/parameters.ui.h:42 -msgid "Capture device:" -msgstr "" - -#: ../gtk/parameters.ui.h:43 -msgid "Ring device:" -msgstr "" - -#: ../gtk/parameters.ui.h:44 -msgid "Playback device:" -msgstr "" - -#: ../gtk/parameters.ui.h:45 -msgid "Enable echo cancellation" -msgstr "Activar cancelación de eco" - -#: ../gtk/parameters.ui.h:46 -msgid "Audio" -msgstr "" - -#: ../gtk/parameters.ui.h:47 -msgid "Video input device:" -msgstr "" - -#: ../gtk/parameters.ui.h:48 -msgid "Prefered video resolution:" -msgstr "Resolución de vídeo preferida:" - -#: ../gtk/parameters.ui.h:49 -msgid "Video output method:" -msgstr "" - -#: ../gtk/parameters.ui.h:50 -msgid "Show camera preview" -msgstr "" - -#: ../gtk/parameters.ui.h:51 -msgid "Video" -msgstr "" - -#: ../gtk/parameters.ui.h:52 -msgid "Multimedia settings" -msgstr "Configuración multimedia" - -#: ../gtk/parameters.ui.h:53 -msgid "This section defines your SIP address when not using a SIP account" -msgstr "Esta sección define su dirección SIP cuando no utiliza una cuenta SIP" - -#: ../gtk/parameters.ui.h:54 -msgid "Your display name (eg: John Doe):" -msgstr "Su nombre a mostrar (x ej: Pepito Pérez):" - -#: ../gtk/parameters.ui.h:55 -msgid "Your username:" -msgstr "" - -#: ../gtk/parameters.ui.h:56 -msgid "Your resulting SIP address:" -msgstr "" - -#: ../gtk/parameters.ui.h:57 -msgid "Default identity" -msgstr "" - -#: ../gtk/parameters.ui.h:58 -msgid "Wizard" -msgstr "" - -#: ../gtk/parameters.ui.h:59 -msgid "Add" -msgstr "Añadir" - -#: ../gtk/parameters.ui.h:60 -msgid "Edit" -msgstr "Editar" - -#: ../gtk/parameters.ui.h:61 -msgid "Remove" -msgstr "Eliminar" - -#: ../gtk/parameters.ui.h:62 -msgid "Proxy accounts" -msgstr "" - -#: ../gtk/parameters.ui.h:63 -msgid "Erase all passwords" -msgstr "Borrar todas las contraseñas" - -#: ../gtk/parameters.ui.h:64 -msgid "Privacy" -msgstr "" - -#: ../gtk/parameters.ui.h:65 -msgid "Automatically answer when a call is received" -msgstr "" - -#: ../gtk/parameters.ui.h:66 -msgid "Delay before answering (ms)" -msgstr "" - -#: ../gtk/parameters.ui.h:67 -msgid "Auto-answer" -msgstr "" - -#: ../gtk/parameters.ui.h:68 -msgid "Manage SIP Accounts" -msgstr "Gestionar cuentas SIP" - -#: ../gtk/parameters.ui.h:69 ../gtk/tunnel_config.ui.h:4 -msgid "Enable" -msgstr "Activar" - -#: ../gtk/parameters.ui.h:70 ../gtk/tunnel_config.ui.h:5 -msgid "Disable" -msgstr "Desactivar" - -#: ../gtk/parameters.ui.h:71 -msgid "Codecs" -msgstr "" - -#: ../gtk/parameters.ui.h:72 -msgid "0 stands for \"unlimited\"" -msgstr "0 significa \"ilimitado\"" - -#: ../gtk/parameters.ui.h:73 -msgid "Upload speed limit in Kbit/sec:" -msgstr "Velocidad límite de subida en Kbit/seg" - -#: ../gtk/parameters.ui.h:74 -msgid "Download speed limit in Kbit/sec:" -msgstr "Velocidad límite de descarga en Kbit/seg:" - -#: ../gtk/parameters.ui.h:75 -msgid "Enable adaptive rate control" -msgstr "Activar control de frecuencia adaptativo" - -#: ../gtk/parameters.ui.h:76 -msgid "" -"Adaptive rate control is a technique to dynamically guess the available " -"bandwidth during a call." -msgstr "Control de frecuencia adaptativo es una técnica que estima dinámicamente el ancho de banda disponible durante la llamada." - -#: ../gtk/parameters.ui.h:77 -msgid "Bandwidth control" -msgstr "Control de ancho de banda" - -#: ../gtk/parameters.ui.h:78 -msgid "Codecs" -msgstr "" - -#: ../gtk/parameters.ui.h:79 -msgid "Language" -msgstr "" - -#: ../gtk/parameters.ui.h:80 -msgid "Show advanced settings" -msgstr "Mostrar opciones avanzadas" - -#: ../gtk/parameters.ui.h:81 -msgid "Level" -msgstr "" - -#: ../gtk/parameters.ui.h:82 -msgid "User interface" -msgstr "" - -#: ../gtk/parameters.ui.h:83 ../gtk/ldap.ui.h:2 -msgid "Server address:" -msgstr "" - -#: ../gtk/parameters.ui.h:84 ../gtk/ldap.ui.h:3 -msgid "Authentication method:" -msgstr "" - -#: ../gtk/parameters.ui.h:86 -msgid "LDAP Account setup" -msgstr "" - -#: ../gtk/parameters.ui.h:87 -msgid "LDAP" -msgstr "" - -#: ../gtk/parameters.ui.h:88 -msgid "Done" -msgstr "" - #: ../gtk/buddylookup.ui.h:1 msgid "Search contacts in directory" msgstr "" @@ -1499,29 +791,21 @@ msgstr "Añadir a mi lista" msgid "Search somebody" msgstr "" -#: ../gtk/waiting.ui.h:2 -msgid "Please wait" -msgstr "Espere por favor" - -#: ../gtk/dscp_settings.ui.h:1 -msgid "DSCP settings" +#: ../gtk/callee_frame.ui.h:1 +msgid "Callee name" msgstr "" -#: ../gtk/dscp_settings.ui.h:2 -msgid "SIP" -msgstr "SIP" +#: ../gtk/call_logs.ui.h:1 +msgid "Call history" +msgstr "Registro de llamadas" -#: ../gtk/dscp_settings.ui.h:3 -msgid "Audio RTP stream" -msgstr "" +#: ../gtk/call_logs.ui.h:2 +msgid "Clear all" +msgstr "Borrar todos" -#: ../gtk/dscp_settings.ui.h:4 -msgid "Video RTP stream" -msgstr "" - -#: ../gtk/dscp_settings.ui.h:5 -msgid "Set DSCP values (in hexadecimal)" -msgstr "" +#: ../gtk/call_logs.ui.h:3 +msgid "Call back" +msgstr "Devolver llamada" #: ../gtk/call_statistics.ui.h:1 msgid "Call statistics" @@ -1571,30 +855,112 @@ msgstr "" msgid "Call statistics and information" msgstr "" -#: ../gtk/tunnel_config.ui.h:1 -msgid "Configure VoIP tunnel" +#: ../gtk/chatroom_frame.ui.h:1 +msgid "Send" msgstr "" -#: ../gtk/tunnel_config.ui.h:2 -msgid "Host" +#: ../gtk/conf_frame.ui.h:1 +msgid "End conference" msgstr "" -#: ../gtk/tunnel_config.ui.h:3 -msgid "Port" +#: ../gtk/config-uri.ui.h:1 +msgid "Specifying a remote configuration URI" msgstr "" -#: ../gtk/tunnel_config.ui.h:6 -msgid "Configure tunnel" +#: ../gtk/config-uri.ui.h:2 +msgid "" +"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" +"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " msgstr "" -#: ../gtk/tunnel_config.ui.h:9 -msgid "Configure http proxy (optional)" +#: ../gtk/contact.ui.h:2 +msgid "SIP Address" msgstr "" +#: ../gtk/contact.ui.h:3 +msgid "Show this contact presence status" +msgstr "Mostrar el estado de presencia de este contacto" + +#: ../gtk/contact.ui.h:4 +msgid "Allow this contact to see my presence status" +msgstr "Permitir que este contacto vea mi estado de presencia" + +#: ../gtk/contact.ui.h:5 +msgid "Contact information" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:1 +msgid "DSCP settings" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:2 +msgid "SIP" +msgstr "SIP" + +#: ../gtk/dscp_settings.ui.h:3 +msgid "Audio RTP stream" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:4 +msgid "Video RTP stream" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:5 +msgid "Set DSCP values (in hexadecimal)" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:1 +msgid "Click here to set the speakers volume" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:5 +msgid "Record this call to an audio file" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:6 +msgid "Video" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:8 +msgid "Mute" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:9 +msgid "Transfer" +msgstr "Transferir" + +#: ../gtk/in_call_frame.ui.h:12 +msgid "In call" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:13 +msgid "Duration" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:14 +msgid "Call quality rating" +msgstr "Calidad de la llamada" + #: ../gtk/ldap.ui.h:1 msgid "LDAP Settings" msgstr "" +#: ../gtk/ldap.ui.h:2 ../gtk/parameters.ui.h:89 +msgid "Server address:" +msgstr "" + +#: ../gtk/ldap.ui.h:3 ../gtk/parameters.ui.h:90 +msgid "Authentication method:" +msgstr "" + +#: ../gtk/ldap.ui.h:4 ../gtk/parameters.ui.h:91 ../gtk/setup_wizard.ui.h:17 +msgid "Username:" +msgstr "" + +#: ../gtk/ldap.ui.h:5 ../gtk/password.ui.h:4 ../gtk/setup_wizard.ui.h:18 +msgid "Password:" +msgstr "" + #: ../gtk/ldap.ui.h:6 msgid "Use TLS Connection" msgstr "" @@ -1680,16 +1046,504 @@ msgstr "" msgid "NTLM" msgstr "" -#: ../gtk/config-uri.ui.h:1 -msgid "Specifying a remote configuration URI" +#: ../gtk/login_frame.ui.h:1 ../gtk/tunnel_config.ui.h:7 +msgid "Username" msgstr "" -#: ../gtk/config-uri.ui.h:2 -msgid "" -"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" -"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " +#: ../gtk/login_frame.ui.h:2 ../gtk/tunnel_config.ui.h:8 +msgid "Password" msgstr "" +#: ../gtk/login_frame.ui.h:3 +msgid "Internet connection:" +msgstr "Conexión a Internet" + +#: ../gtk/login_frame.ui.h:4 +msgid "Automatically log me in" +msgstr "Iniciar sesión automáticamente" + +#: ../gtk/login_frame.ui.h:5 ../gtk/password.ui.h:3 +msgid "UserID" +msgstr "UserID" + +#: ../gtk/login_frame.ui.h:6 +msgid "Login information" +msgstr "" + +#: ../gtk/login_frame.ui.h:7 +msgid "Welcome!" +msgstr "" + +#: ../gtk/login_frame.ui.h:8 +msgid "ADSL" +msgstr "ADSL" + +#: ../gtk/login_frame.ui.h:9 +msgid "Fiber Channel" +msgstr "Canal de Fibra" + +#: ../gtk/log.ui.h:1 +msgid "Linphone debug window" +msgstr "" + +#: ../gtk/log.ui.h:2 +msgid "Scroll to end" +msgstr "" + +#: ../gtk/main.ui.h:1 +msgid "Default" +msgstr "" + +#: ../gtk/main.ui.h:2 +msgid "Delete" +msgstr "" + +#: ../gtk/main.ui.h:3 +msgid "_Options" +msgstr "_Opciones" + +#: ../gtk/main.ui.h:4 +msgid "Set configuration URI" +msgstr "" + +#: ../gtk/main.ui.h:5 +msgid "Always start video" +msgstr "" + +#: ../gtk/main.ui.h:6 +msgid "Enable self-view" +msgstr "" + +#: ../gtk/main.ui.h:7 +msgid "Show keypad" +msgstr "" + +#: ../gtk/main.ui.h:8 +msgid "_Help" +msgstr "_Ayuda" + +#: ../gtk/main.ui.h:9 +msgid "Show debug window" +msgstr "" + +#: ../gtk/main.ui.h:10 +msgid "_Homepage" +msgstr "_Pagina_de_Inicio" + +#: ../gtk/main.ui.h:11 +msgid "Check _Updates" +msgstr "Buscar_Actualizaciones" + +#: ../gtk/main.ui.h:12 +msgid "Account assistant" +msgstr "" + +#: ../gtk/main.ui.h:14 +msgid "SIP address or phone number:" +msgstr "" + +#: ../gtk/main.ui.h:15 +msgid "Initiate a new call" +msgstr "Iniciar nueva llamada" + +#: ../gtk/main.ui.h:16 +msgid "Contacts" +msgstr "" + +#: ../gtk/main.ui.h:17 +msgid "Search" +msgstr "Buscar" + +#: ../gtk/main.ui.h:18 +msgid "Add contacts from directory" +msgstr "" + +#: ../gtk/main.ui.h:19 +msgid "Add contact" +msgstr "" + +#: ../gtk/main.ui.h:20 +msgid "Clear call history" +msgstr "" + +#: ../gtk/main.ui.h:22 +msgid "My current identity:" +msgstr "" + +#: ../gtk/main.ui.h:23 +msgid "Autoanswer is enabled" +msgstr "" + +#: ../gtk/parameters.ui.h:1 +msgid "anonymous" +msgstr "" + +#: ../gtk/parameters.ui.h:2 +msgid "GSSAPI" +msgstr "" + +#: ../gtk/parameters.ui.h:3 +msgid "SASL" +msgstr "" + +#: ../gtk/parameters.ui.h:4 +msgid "default soundcard" +msgstr "tarjeta de sonido predeterminada" + +#: ../gtk/parameters.ui.h:5 +msgid "a sound card" +msgstr "una tarjeta de sonido" + +#: ../gtk/parameters.ui.h:6 +msgid "default camera" +msgstr "cámara predeterminada" + +#: ../gtk/parameters.ui.h:7 +msgid "CIF" +msgstr "CIF" + +#: ../gtk/parameters.ui.h:8 +msgid "Audio codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:9 +msgid "Video codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:10 +msgid "C" +msgstr "C" + +#: ../gtk/parameters.ui.h:11 +msgid "SIP (UDP)" +msgstr "SIP (UDP)" + +#: ../gtk/parameters.ui.h:12 +msgid "SIP (TCP)" +msgstr "SIP (TCP)" + +#: ../gtk/parameters.ui.h:13 +msgid "SIP (TLS)" +msgstr "SIP (TLS)" + +#: ../gtk/parameters.ui.h:14 +msgid "default" +msgstr "" + +#: ../gtk/parameters.ui.h:15 +msgid "high-fps" +msgstr "" + +#: ../gtk/parameters.ui.h:16 +msgid "custom" +msgstr "" + +#: ../gtk/parameters.ui.h:17 +msgid "Settings" +msgstr "Configuración" + +#: ../gtk/parameters.ui.h:18 +msgid "This section defines your SIP address when not using a SIP account" +msgstr "Esta sección define su dirección SIP cuando no utiliza una cuenta SIP" + +#: ../gtk/parameters.ui.h:19 +msgid "Your display name (eg: John Doe):" +msgstr "Su nombre a mostrar (x ej: Pepito Pérez):" + +#: ../gtk/parameters.ui.h:20 +msgid "Your username:" +msgstr "" + +#: ../gtk/parameters.ui.h:21 +msgid "Your resulting SIP address:" +msgstr "" + +#: ../gtk/parameters.ui.h:22 +msgid "Default identity" +msgstr "" + +#: ../gtk/parameters.ui.h:23 +msgid "Wizard" +msgstr "" + +#: ../gtk/parameters.ui.h:24 +msgid "Add" +msgstr "Añadir" + +#: ../gtk/parameters.ui.h:25 +msgid "Edit" +msgstr "Editar" + +#: ../gtk/parameters.ui.h:26 +msgid "Remove" +msgstr "Eliminar" + +#: ../gtk/parameters.ui.h:27 +msgid "Proxy accounts" +msgstr "" + +#: ../gtk/parameters.ui.h:28 +msgid "Erase all passwords" +msgstr "Borrar todas las contraseñas" + +#: ../gtk/parameters.ui.h:29 +msgid "Privacy" +msgstr "" + +#: ../gtk/parameters.ui.h:30 +msgid "Automatically answer when a call is received" +msgstr "" + +#: ../gtk/parameters.ui.h:31 +msgid "Delay before answering (ms)" +msgstr "" + +#: ../gtk/parameters.ui.h:32 +msgid "Auto-answer" +msgstr "" + +#: ../gtk/parameters.ui.h:33 +msgid "Manage SIP Accounts" +msgstr "Gestionar cuentas SIP" + +#: ../gtk/parameters.ui.h:34 +msgid "Ring sound:" +msgstr "" + +#: ../gtk/parameters.ui.h:35 +msgid "ALSA special device (optional):" +msgstr "Dispositivo especial ALSA (opcional):" + +#: ../gtk/parameters.ui.h:36 +msgid "Capture device:" +msgstr "" + +#: ../gtk/parameters.ui.h:37 +msgid "Ring device:" +msgstr "" + +#: ../gtk/parameters.ui.h:38 +msgid "Playback device:" +msgstr "" + +#: ../gtk/parameters.ui.h:39 +msgid "Enable echo cancellation" +msgstr "Activar cancelación de eco" + +#: ../gtk/parameters.ui.h:40 +msgid "Audio" +msgstr "" + +#: ../gtk/parameters.ui.h:41 +msgid "Video input device:" +msgstr "" + +#: ../gtk/parameters.ui.h:42 +msgid "Preferred video resolution:" +msgstr "" + +#: ../gtk/parameters.ui.h:43 +msgid "Video output method:" +msgstr "" + +#: ../gtk/parameters.ui.h:44 +msgid "Show camera preview" +msgstr "" + +#: ../gtk/parameters.ui.h:45 +msgid "Video preset:" +msgstr "" + +#: ../gtk/parameters.ui.h:46 +msgid "Preferred video framerate:" +msgstr "" + +#: ../gtk/parameters.ui.h:47 +msgid "0 stands for \"unlimited\"" +msgstr "0 significa \"ilimitado\"" + +#: ../gtk/parameters.ui.h:48 +msgid "Video" +msgstr "" + +#: ../gtk/parameters.ui.h:49 +msgid "Upload speed limit in Kbit/sec:" +msgstr "Velocidad límite de subida en Kbit/seg" + +#: ../gtk/parameters.ui.h:50 +msgid "Download speed limit in Kbit/sec:" +msgstr "Velocidad límite de descarga en Kbit/seg:" + +#: ../gtk/parameters.ui.h:51 +msgid "Enable adaptive rate control" +msgstr "Activar control de frecuencia adaptativo" + +#: ../gtk/parameters.ui.h:52 +msgid "" +"Adaptive rate control is a technique to dynamically guess the available " +"bandwidth during a call." +msgstr "Control de frecuencia adaptativo es una técnica que estima dinámicamente el ancho de banda disponible durante la llamada." + +#: ../gtk/parameters.ui.h:53 +msgid "Bandwidth control" +msgstr "Control de ancho de banda" + +#: ../gtk/parameters.ui.h:54 +msgid "Multimedia settings" +msgstr "Configuración multimedia" + +#: ../gtk/parameters.ui.h:55 +msgid "Set Maximum Transmission Unit:" +msgstr "Fijar Unidad de Transmisión Máxima:" + +#: ../gtk/parameters.ui.h:56 +msgid "Send DTMFs as SIP info" +msgstr "Enviar DTMFs como información SIP" + +#: ../gtk/parameters.ui.h:57 +msgid "Allow IPv6" +msgstr "" + +#: ../gtk/parameters.ui.h:58 +msgid "Transport" +msgstr "" + +#: ../gtk/parameters.ui.h:59 +msgid "SIP/UDP port" +msgstr "" + +#: ../gtk/parameters.ui.h:61 +msgid "Random" +msgstr "" + +#: ../gtk/parameters.ui.h:62 +msgid "SIP/TCP port" +msgstr "" + +#: ../gtk/parameters.ui.h:63 +msgid "Audio RTP/UDP:" +msgstr "Audio RTP/UDP:" + +#: ../gtk/parameters.ui.h:64 +msgid "Fixed" +msgstr "" + +#: ../gtk/parameters.ui.h:65 +msgid "Video RTP/UDP:" +msgstr "Vídeo RTP/UDP" + +#: ../gtk/parameters.ui.h:66 +msgid "Media encryption type" +msgstr "Tipo de cifrado de medios" + +#: ../gtk/parameters.ui.h:67 +msgid "Media encryption is mandatory" +msgstr "" + +#: ../gtk/parameters.ui.h:68 +msgid "Tunnel" +msgstr "" + +#: ../gtk/parameters.ui.h:69 +msgid "DSCP fields" +msgstr "" + +#: ../gtk/parameters.ui.h:70 +msgid "Network protocol and ports" +msgstr "Protocolo de red y puertos" + +#: ../gtk/parameters.ui.h:71 +msgid "Direct connection to the Internet" +msgstr "Conexión directa a Internet" + +#: ../gtk/parameters.ui.h:72 +msgid "Behind NAT / Firewall (specify gateway IP )" +msgstr "" + +#: ../gtk/parameters.ui.h:73 +msgid "Behind NAT / Firewall (use STUN to resolve)" +msgstr "Tras un NAT/Firewall (utilizar STUN para resolver)" + +#: ../gtk/parameters.ui.h:74 +msgid "Behind NAT / Firewall (use ICE)" +msgstr "" + +#: ../gtk/parameters.ui.h:75 +msgid "Behind NAT / Firewall (use uPnP)" +msgstr "" + +#: ../gtk/parameters.ui.h:76 +msgid "Public IP address:" +msgstr "" + +#: ../gtk/parameters.ui.h:77 +msgid "Stun server:" +msgstr "" + +#: ../gtk/parameters.ui.h:78 +msgid "NAT and Firewall" +msgstr "" + +#: ../gtk/parameters.ui.h:79 +msgid "Network settings" +msgstr "" + +#: ../gtk/parameters.ui.h:80 ../gtk/tunnel_config.ui.h:4 +msgid "Enable" +msgstr "Activar" + +#: ../gtk/parameters.ui.h:81 ../gtk/tunnel_config.ui.h:5 +msgid "Disable" +msgstr "Desactivar" + +#: ../gtk/parameters.ui.h:82 +msgid "Audio codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:83 +msgid "Video codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:84 +msgid "Codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:85 +msgid "Language" +msgstr "" + +#: ../gtk/parameters.ui.h:86 +msgid "Show advanced settings" +msgstr "Mostrar opciones avanzadas" + +#: ../gtk/parameters.ui.h:87 +msgid "Level" +msgstr "" + +#: ../gtk/parameters.ui.h:88 +msgid "User interface" +msgstr "" + +#: ../gtk/parameters.ui.h:92 +msgid "LDAP Account setup" +msgstr "" + +#: ../gtk/parameters.ui.h:93 +msgid "LDAP" +msgstr "" + +#: ../gtk/parameters.ui.h:94 +msgid "Done" +msgstr "" + +#: ../gtk/password.ui.h:1 +msgid "Linphone - Authentication required" +msgstr "" + +#: ../gtk/password.ui.h:2 +msgid "Please enter the domain password" +msgstr "Por favor introduzca la contraseña del dominio" + #: ../gtk/provisioning-fetch.ui.h:1 msgid "Configuring..." msgstr "" @@ -1698,68 +1552,278 @@ msgstr "" msgid "Please wait while fetching configuration from server..." msgstr "" -#: ../coreapi/linphonecore.c:1539 +#: ../gtk/setup_wizard.ui.h:1 +msgid "SIP account configuration assistant" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:2 +msgid "" +"Welcome!\n" +"This assistant will help you to use a SIP account for your calls." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:4 +msgid "Welcome to the account setup assistant" +msgstr "Bienvenido al asistente de configuración de cuenta" + +#: ../gtk/setup_wizard.ui.h:5 +msgid "Create an account on linphone.org" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:6 +msgid "I have already a linphone.org account and I just want to use it" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:7 +msgid "I have already a sip account and I just want to use it" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:8 +msgid "I want to specify a remote configuration URI" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:9 +msgid "Account setup assistant" +msgstr "Asistente de configuración de cuenta" + +#: ../gtk/setup_wizard.ui.h:10 +msgid "Enter your account information" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:11 +msgid "Username*" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:12 +msgid "Password*" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:13 +msgid "Domain*" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:14 +msgid "Proxy" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:15 +msgid "Configure your account (step 1/1)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:16 +msgid "Enter your linphone.org username" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:19 +msgid "Enter your sip username (step 1/1)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:20 +msgid "(*) Required fields" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:21 +msgid "Email: (*)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:22 +msgid "Username: (*)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:23 +msgid "Password: (*)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:24 +msgid "Confirm your password: (*)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:25 +msgid "Keep me informed with linphone updates" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:26 +msgid "Enter account information (step 1/2)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:27 +msgid "Your account is being created, please wait." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:28 +msgid "Account creation in progress" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:29 +msgid "" +"Please validate your account by clicking on the link we just sent you by email.\n" +"Then come back here and press Next button." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:31 +msgid "Validation (step 2/2)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:32 +msgid "Checking if your account is been validated, please wait." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:33 +msgid "Account validation check in progress" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:34 +msgid "" +"Error, account not validated, username already used or server unreachable.\n" +"Please go back and try again." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:36 +msgid "Error" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:37 +msgid "Thank you. Your account is now configured and ready for use." +msgstr "Gracias. Su cuenta está configurada y lista para su utilización." + +#: ../gtk/sip_account.ui.h:1 +msgid "Linphone - Configure a SIP account" +msgstr "Linphone - Configurar una cuenta SIP" + +#: ../gtk/sip_account.ui.h:2 +msgid "Your SIP identity:" +msgstr "" + +#: ../gtk/sip_account.ui.h:3 +msgid "Looks like sip:@" +msgstr "Del tipo sip:@" + +#: ../gtk/sip_account.ui.h:4 +msgid "sip:" +msgstr "sip:" + +#: ../gtk/sip_account.ui.h:5 +msgid "SIP Proxy address:" +msgstr "" + +#: ../gtk/sip_account.ui.h:6 +msgid "Looks like sip:" +msgstr "Del tipo sip:" + +#: ../gtk/sip_account.ui.h:7 +msgid "Registration duration (sec):" +msgstr "" + +#: ../gtk/sip_account.ui.h:8 +msgid "Contact params (optional):" +msgstr "" + +#: ../gtk/sip_account.ui.h:9 +msgid "AVPF regular RTCP interval (sec):" +msgstr "" + +#: ../gtk/sip_account.ui.h:10 +msgid "Route (optional):" +msgstr "Ruta (opcional):" + +#: ../gtk/sip_account.ui.h:11 +msgid "Transport" +msgstr "" + +#: ../gtk/sip_account.ui.h:12 +msgid "Register" +msgstr "Registrarse" + +#: ../gtk/sip_account.ui.h:13 +msgid "Publish presence information" +msgstr "" + +#: ../gtk/sip_account.ui.h:14 +msgid "Enable AVPF" +msgstr "" + +#: ../gtk/sip_account.ui.h:15 +msgid "Configure a SIP account" +msgstr "Configurar una cuenta SIP" + +#: ../gtk/tunnel_config.ui.h:1 +msgid "Configure VoIP tunnel" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:2 +msgid "Host" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:3 +msgid "Port" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:6 +msgid "Configure tunnel" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:9 +msgid "Configure http proxy (optional)" +msgstr "" + +#: ../gtk/waiting.ui.h:2 +msgid "Please wait" +msgstr "Espere por favor" + +#: ../coreapi/linphonecore.c:1560 msgid "Ready" msgstr "" -#: ../coreapi/linphonecore.c:2551 +#: ../coreapi/linphonecore.c:2556 msgid "Configuring" msgstr "" -#: ../coreapi/linphonecore.c:2725 -msgid "Looking for telephone number destination..." -msgstr "Buscando el número de teléfono del destinatario…" - -#: ../coreapi/linphonecore.c:2727 -msgid "Could not resolve this number." -msgstr "No se ha podido resolver este número." - #. must be known at that time -#: ../coreapi/linphonecore.c:3013 +#: ../coreapi/linphonecore.c:2951 msgid "Contacting" msgstr "" -#: ../coreapi/linphonecore.c:3018 +#: ../coreapi/linphonecore.c:2956 msgid "Could not call" msgstr "" -#: ../coreapi/linphonecore.c:3169 +#: ../coreapi/linphonecore.c:3092 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:3327 +#: ../coreapi/linphonecore.c:3250 msgid "is contacting you" msgstr "" -#: ../coreapi/linphonecore.c:3328 +#: ../coreapi/linphonecore.c:3251 msgid " and asked autoanswer." msgstr "y ha solicitado auto respuesta." -#: ../coreapi/linphonecore.c:3452 +#: ../coreapi/linphonecore.c:3377 msgid "Modifying call parameters..." msgstr "Modificando parámetros de llamada…" -#: ../coreapi/linphonecore.c:3802 +#: ../coreapi/linphonecore.c:3769 msgid "Connected." msgstr "Conectado." -#: ../coreapi/linphonecore.c:3827 +#: ../coreapi/linphonecore.c:3794 msgid "Call aborted" msgstr "" -#: ../coreapi/linphonecore.c:4024 +#: ../coreapi/linphonecore.c:3983 msgid "Could not pause the call" msgstr "No se pudo pausar la llamada" -#: ../coreapi/linphonecore.c:4027 +#: ../coreapi/linphonecore.c:3986 msgid "Pausing the current call..." msgstr "Pausando la llamada actual..." -#: ../coreapi/misc.c:434 +#: ../coreapi/misc.c:440 msgid "Stun lookup in progress..." msgstr "Búsqueda STUN en proceso…" -#: ../coreapi/misc.c:615 +#: ../coreapi/misc.c:650 msgid "ICE local candidates gathering in progress..." msgstr "" @@ -1815,166 +1879,173 @@ msgstr "" msgid "Unknown status" msgstr "" -#: ../coreapi/proxy.c:328 +#: ../coreapi/proxy.c:292 msgid "" "The sip proxy address you entered is invalid, it must start with \"sip:\" " "followed by a hostname." msgstr "La dirección del Proxy SIP que ha introducido no es válida, debe empezar con \"sip:\" seguido del hostname." -#: ../coreapi/proxy.c:334 +#: ../coreapi/proxy.c:298 msgid "" "The sip identity you entered is invalid.\n" "It should look like sip:username@proxydomain, such as sip:alice@example.net" msgstr "La identidad SIP que ha introducido no es válida.\nDebe ser del tipo sip:username@proxydomain, como por ejemplo sip:alice@example.net" -#: ../coreapi/proxy.c:1416 +#: ../coreapi/proxy.c:927 +msgid "Looking for telephone number destination..." +msgstr "Buscando el número de teléfono del destinatario…" + +#: ../coreapi/proxy.c:931 +msgid "Could not resolve this number." +msgstr "No se ha podido resolver este número." + +#: ../coreapi/proxy.c:1324 #, c-format msgid "Could not login as %s" msgstr "" -#: ../coreapi/callbacks.c:428 +#: ../coreapi/proxy.c:1411 +#, c-format +msgid "Refreshing on %s..." +msgstr "" + +#: ../coreapi/callbacks.c:423 msgid "Remote ringing." msgstr "" -#: ../coreapi/callbacks.c:440 +#: ../coreapi/callbacks.c:435 msgid "Remote ringing..." msgstr "" -#: ../coreapi/callbacks.c:461 +#: ../coreapi/callbacks.c:458 msgid "Early media." msgstr "Medios iniciales." -#: ../coreapi/callbacks.c:534 +#: ../coreapi/callbacks.c:488 #, c-format -msgid "Call with %s is paused." -msgstr "La llamada con %s está puesta en pausa." +msgid "Call answered by %s" +msgstr "" -#: ../coreapi/callbacks.c:547 -#, c-format -msgid "Call answered by %s - on hold." -msgstr "Llamada respondida por %s - en espera." - -#: ../coreapi/callbacks.c:557 +#: ../coreapi/callbacks.c:527 msgid "Call resumed." msgstr "" -#: ../coreapi/callbacks.c:561 -#, c-format -msgid "Call answered by %s." -msgstr "" - -#: ../coreapi/callbacks.c:584 +#: ../coreapi/callbacks.c:582 msgid "Incompatible, check codecs or security settings..." msgstr "" -#: ../coreapi/callbacks.c:589 ../coreapi/callbacks.c:906 +#: ../coreapi/callbacks.c:587 ../coreapi/callbacks.c:923 msgid "Incompatible media parameters." msgstr "" -#: ../coreapi/callbacks.c:619 +#: ../coreapi/callbacks.c:612 msgid "We have been resumed." msgstr "" #. we are being paused -#: ../coreapi/callbacks.c:628 +#: ../coreapi/callbacks.c:620 msgid "We are paused by other party." msgstr "" -#. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:666 +#: ../coreapi/callbacks.c:630 msgid "Call is updated by remote." msgstr "" -#: ../coreapi/callbacks.c:782 +#: ../coreapi/callbacks.c:799 msgid "Call terminated." msgstr "" -#: ../coreapi/callbacks.c:810 +#: ../coreapi/callbacks.c:827 msgid "User is busy." msgstr "El usuario está ocupado." -#: ../coreapi/callbacks.c:811 +#: ../coreapi/callbacks.c:828 msgid "User is temporarily unavailable." msgstr "El usuario no está disponible temporalmente." #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:813 +#: ../coreapi/callbacks.c:830 msgid "User does not want to be disturbed." msgstr "El usuario no quiere que le molesten." -#: ../coreapi/callbacks.c:814 +#: ../coreapi/callbacks.c:831 msgid "Call declined." msgstr "Llamada rechazada." -#: ../coreapi/callbacks.c:829 +#: ../coreapi/callbacks.c:846 msgid "Request timeout." msgstr "" -#: ../coreapi/callbacks.c:860 +#: ../coreapi/callbacks.c:877 msgid "Redirected" msgstr "Redigirida" -#: ../coreapi/callbacks.c:915 +#: ../coreapi/callbacks.c:927 msgid "Call failed." msgstr "" -#: ../coreapi/callbacks.c:993 +#: ../coreapi/callbacks.c:1005 #, c-format msgid "Registration on %s successful." msgstr "" -#: ../coreapi/callbacks.c:994 +#: ../coreapi/callbacks.c:1006 #, c-format msgid "Unregistration on %s done." msgstr "" -#: ../coreapi/callbacks.c:1012 +#: ../coreapi/callbacks.c:1024 msgid "no response timeout" msgstr "timeout sin respuesta" -#: ../coreapi/callbacks.c:1015 +#: ../coreapi/callbacks.c:1027 #, c-format msgid "Registration on %s failed: %s" msgstr "" -#: ../coreapi/callbacks.c:1022 +#: ../coreapi/callbacks.c:1034 msgid "Service unavailable, retrying" msgstr "" #. if encryption is DTLS, no status to be displayed -#: ../coreapi/linphonecall.c:180 +#: ../coreapi/linphonecall.c:197 #, c-format msgid "Authentication token is %s" msgstr "" -#: ../coreapi/linphonecall.c:1310 +#: ../coreapi/linphonecall.c:1561 +#, c-format +msgid "Call parameters could not be modified: %s." +msgstr "" + +#: ../coreapi/linphonecall.c:1563 msgid "Call parameters were successfully modified." msgstr "" -#: ../coreapi/linphonecall.c:3686 +#: ../coreapi/linphonecall.c:4396 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." msgstr[0] "Tiene %i llamada perdida." msgstr[1] "Tiene %i llamadas perdidas." -#: ../coreapi/call_log.c:209 +#: ../coreapi/call_log.c:223 msgid "aborted" msgstr "" -#: ../coreapi/call_log.c:212 +#: ../coreapi/call_log.c:226 msgid "completed" msgstr "" -#: ../coreapi/call_log.c:215 +#: ../coreapi/call_log.c:229 msgid "missed" msgstr "" -#: ../coreapi/call_log.c:218 +#: ../coreapi/call_log.c:232 msgid "unknown" msgstr "" -#: ../coreapi/call_log.c:220 +#: ../coreapi/call_log.c:234 #, c-format msgid "" "%s at %s\n" @@ -1984,7 +2055,7 @@ msgid "" "Duration: %i mn %i sec\n" msgstr "" -#: ../coreapi/call_log.c:221 +#: ../coreapi/call_log.c:235 msgid "Outgoing call" msgstr "" diff --git a/po/fr.po b/po/fr.po index 652612561..4649a4b50 100644 --- a/po/fr.po +++ b/po/fr.po @@ -12,74 +12,83 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-04-30 10:13+0200\n" -"PO-Revision-Date: 2015-04-30 08:35+0000\n" +"POT-Creation-Date: 2015-11-10 15:16+0100\n" +"PO-Revision-Date: 2015-11-10 14:16+0000\n" "Last-Translator: Belledonne Communications \n" -"Language-Team: French (http://www.transifex.com/projects/p/linphone-gtk/language/fr/)\n" +"Language-Team: French (http://www.transifex.com/belledonne-communications/linphone-gtk/language/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: fr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: ../gtk/calllogs.c:148 ../gtk/friendlist.c:974 +#: ../gtk/calllogs.c:178 #, c-format msgid "Call %s" msgstr "Appeler %s" -#: ../gtk/calllogs.c:149 ../gtk/friendlist.c:975 +#: ../gtk/calllogs.c:179 #, c-format msgid "Send text to %s" msgstr "Chatter avec %s" -#: ../gtk/calllogs.c:232 +#: ../gtk/calllogs.c:181 +#, c-format +msgid "Add %s to your contact list" +msgstr "Ajouter %s à la liste de contacts" + +#: ../gtk/calllogs.c:245 ../gtk/main.ui.h:21 +msgid "Recent calls" +msgstr "Appels récents" + +#: ../gtk/calllogs.c:260 #, c-format msgid "Recent calls (%i)" msgstr "Appels récents (%i)" -#: ../gtk/calllogs.c:314 +#: ../gtk/calllogs.c:331 msgid "n/a" msgstr "inconnu" -#: ../gtk/calllogs.c:317 +#: ../gtk/calllogs.c:334 msgid "Aborted" msgstr "Abandonné" -#: ../gtk/calllogs.c:320 +#: ../gtk/calllogs.c:337 msgid "Missed" msgstr "Manqué" -#: ../gtk/calllogs.c:323 +#: ../gtk/calllogs.c:340 msgid "Declined" msgstr "Refusé" -#: ../gtk/calllogs.c:329 +#: ../gtk/calllogs.c:346 #, c-format msgid "%i minute" msgid_plural "%i minutes" msgstr[0] "%i minute" msgstr[1] "%i minutes" -#: ../gtk/calllogs.c:332 +#: ../gtk/calllogs.c:349 #, c-format msgid "%i second" msgid_plural "%i seconds" msgstr[0] "%i seconde" msgstr[1] "%i secondes" -#: ../gtk/calllogs.c:337 +#: ../gtk/calllogs.c:354 #, c-format msgid "" "%s\tQuality: %s\n" "%s\t%s\t" msgstr "%s\tQualité: %s\n%s\t%s\t" -#: ../gtk/calllogs.c:341 +#: ../gtk/calllogs.c:358 #, c-format msgid "%s\t%s" msgstr "%s\t%s" -#: ../gtk/conference.c:38 ../gtk/main.ui.h:13 +#: ../gtk/conference.c:38 ../gtk/in_call_frame.ui.h:11 msgid "Conference" msgstr "Conférence" @@ -92,297 +101,314 @@ msgstr "Moi" msgid "Couldn't find pixmap file: %s" msgstr "Icone non trouvée: %s" -#: ../gtk/main.c:137 +#: ../gtk/chat.c:196 ../gtk/chat.c:254 +msgid "Sending..." +msgstr "Envoi en cours..." + +#: ../gtk/chat.c:213 ../gtk/chat.c:263 +msgid "Message not sent" +msgstr "Message non envoyé" + +#: ../gtk/chat.c:472 +msgid "Copy" +msgstr "Copier" + +#: ../gtk/main.c:138 msgid "log to stdout some debug information while running." msgstr "affiche des informations de debogage" -#: ../gtk/main.c:138 +#: ../gtk/main.c:139 +msgid "display version and exit." +msgstr "Afficher la version et quitter." + +#: ../gtk/main.c:140 msgid "path to a file to write logs into." msgstr "chemin vers le fichier de logs." -#: ../gtk/main.c:139 +#: ../gtk/main.c:141 msgid "Start linphone with video disabled." msgstr "Démarrer linphone avec la vidéo désactivée." -#: ../gtk/main.c:140 +#: ../gtk/main.c:142 msgid "Start only in the system tray, do not show the main interface." msgstr "Démarre iconifié, sans interface principale." -#: ../gtk/main.c:141 +#: ../gtk/main.c:143 msgid "address to call right now" msgstr "adresse à appeler maintenant" -#: ../gtk/main.c:142 +#: ../gtk/main.c:144 msgid "" "Specifiy a working directory (should be the base of the installation, eg: " "c:\\Program Files\\Linphone)" 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:143 +#: ../gtk/main.c:145 msgid "Configuration file" msgstr "Ficher de configuration" -#: ../gtk/main.c:144 +#: ../gtk/main.c:146 msgid "Run the audio assistant" msgstr "Démarre l'assistant audio" -#: ../gtk/main.c:145 +#: ../gtk/main.c:147 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:1070 +#: ../gtk/main.c:1046 #, c-format msgid "" -"%s would like to add you to his contact list.\n" -"Would you allow him to see your presence status or add him to your contact list ?\n" +"%s would like to add you to his/her contact list.\n" +"Would you add him/her to your contact list and allow him/her to see your presence status?\n" "If you answer no, this person will be temporarily blacklisted." -msgstr "%s souhaite vous ajouter à sa liste de contact.\nSouhaitez vous l'autoriser à voir votre information de présence et l'ajouter à votre liste également ?\nSi vous répondez non, cette personne sera mise temporairement sur liste noire." +msgstr "%s souhaite vous ajouter à sa liste de contact.\nSouhaitez vous l'ajouter à votre liste également et l'autoriser à voir votre information de présence ?\nSi vous répondez non, cette personne sera mise temporairement sur liste noire." -#: ../gtk/main.c:1147 +#: ../gtk/main.c:1123 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" msgstr "Entrez le mot de passe pour %s\n sur le domaine %s:" -#: ../gtk/main.c:1268 +#: ../gtk/main.c:1253 msgid "Call error" msgstr "Erreur lors de l'appel" -#: ../gtk/main.c:1271 ../coreapi/linphonecore.c:3846 +#: ../gtk/main.c:1256 ../coreapi/linphonecore.c:3813 msgid "Call ended" msgstr "Appel terminé." -#: ../gtk/main.c:1274 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1259 ../coreapi/call_log.c:235 msgid "Incoming call" msgstr "Appel entrant" -#: ../gtk/main.c:1276 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1261 ../gtk/incall_view.c:580 ../gtk/in_call_frame.ui.h:2 msgid "Answer" msgstr "Répondre" -#: ../gtk/main.c:1278 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1263 ../gtk/in_call_frame.ui.h:3 msgid "Decline" msgstr "Refuser" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 msgid "Call paused" msgstr "Appel en pause" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 #, c-format msgid "by %s" msgstr "b>par %s" -#: ../gtk/main.c:1354 +#: ../gtk/main.c:1339 #, 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:1509 +#: ../gtk/main.c:1505 msgid "Website link" msgstr "Lien site web" -#: ../gtk/main.c:1568 ../gtk/waiting.ui.h:1 +#: ../gtk/main.c:1564 ../gtk/waiting.ui.h:1 msgid "Linphone" msgstr "Linphone" -#: ../gtk/main.c:1569 +#: ../gtk/main.c:1565 msgid "A video internet phone" msgstr "Appels vidéo via internet" -#: ../gtk/main.c:1629 +#: ../gtk/main.c:1624 #, c-format msgid "%s (Default)" msgstr "%s (par défaut)" -#: ../gtk/main.c:1962 ../coreapi/callbacks.c:1063 +#: ../gtk/main.c:1960 ../coreapi/callbacks.c:1075 #, c-format msgid "We are transferred to %s" msgstr "Transfert vers %s" -#: ../gtk/main.c:1972 +#: ../gtk/main.c:1970 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." msgstr "Aucune carte son n'a été détectée sur cet ordinateur.\nVous ne pourrez pas effectuer d'appels audio." -#: ../gtk/main.c:2117 +#: ../gtk/main.c:2129 msgid "A free SIP video-phone" msgstr "Un visiophone libre" -#: ../gtk/main.c:2221 +#: ../gtk/main.c:2242 #, c-format msgid "Hello\n" msgstr "Bonjour\n" -#: ../gtk/friendlist.c:505 +#: ../gtk/friendlist.c:461 msgid "Add to addressbook" msgstr "Ajouter au carnet d'adresse" -#: ../gtk/friendlist.c:691 -msgid "Presence status" -msgstr "Info de présence" - -#: ../gtk/friendlist.c:709 ../gtk/propertybox.c:569 ../gtk/contact.ui.h:1 -msgid "Name" -msgstr "Nom" - -#: ../gtk/friendlist.c:721 -msgid "Call" -msgstr "Appeler" - -#: ../gtk/friendlist.c:726 -msgid "Chat" -msgstr "Chat" - -#: ../gtk/friendlist.c:756 +#: ../gtk/friendlist.c:627 #, c-format msgid "Search in %s directory" msgstr "Rechercher dans l'annuaire de %s" -#: ../gtk/friendlist.c:924 +#: ../gtk/friendlist.c:772 msgid "Invalid sip contact !" msgstr "Contact sip invalide !" -#: ../gtk/friendlist.c:976 +#: ../gtk/friendlist.c:820 +#, c-format +msgid "Add a new contact" +msgstr "Ajouter un nouveau contact" + +#: ../gtk/friendlist.c:823 #, c-format msgid "Edit contact '%s'" msgstr "Editer le contact '%s'" -#: ../gtk/friendlist.c:977 +#: ../gtk/friendlist.c:824 #, c-format msgid "Delete contact '%s'" msgstr "Supprimer le contact '%s'" -#: ../gtk/friendlist.c:978 +#: ../gtk/friendlist.c:825 #, c-format msgid "Delete chat history of '%s'" msgstr "Supprimer l'historique de chat de '%s'" -#: ../gtk/friendlist.c:1029 +#: ../gtk/friendlist.c:862 #, c-format msgid "Add new contact from %s directory" msgstr "Ajouter un contact depuis l'annuaire %s" -#: ../gtk/propertybox.c:575 +#: ../gtk/propertybox.c:592 ../gtk/contact.ui.h:1 +msgid "Name" +msgstr "Nom" + +#: ../gtk/propertybox.c:598 msgid "Rate (Hz)" msgstr "Fréquence (Hz)" -#: ../gtk/propertybox.c:581 +#: ../gtk/propertybox.c:604 msgid "Status" msgstr "Etat" -#: ../gtk/propertybox.c:587 +#: ../gtk/propertybox.c:617 msgid "IP Bitrate (kbit/s)" msgstr "Débit IP (kbit/s)" -#: ../gtk/propertybox.c:596 +#: ../gtk/propertybox.c:628 msgid "Parameters" msgstr "Paramètres" -#: ../gtk/propertybox.c:639 ../gtk/propertybox.c:782 +#: ../gtk/propertybox.c:670 ../gtk/propertybox.c:824 msgid "Enabled" msgstr "Activé" -#: ../gtk/propertybox.c:641 ../gtk/propertybox.c:782 ../gtk/parameters.ui.h:20 +#: ../gtk/propertybox.c:672 ../gtk/propertybox.c:824 ../gtk/parameters.ui.h:60 msgid "Disabled" msgstr "Désactivé" -#: ../gtk/propertybox.c:828 +#: ../gtk/propertybox.c:902 msgid "Account" msgstr "Compte" -#: ../gtk/propertybox.c:1091 +#: ../gtk/propertybox.c:1170 msgid "English" msgstr "Anglais" -#: ../gtk/propertybox.c:1092 +#: ../gtk/propertybox.c:1171 msgid "French" msgstr "Français" -#: ../gtk/propertybox.c:1093 +#: ../gtk/propertybox.c:1172 msgid "Swedish" msgstr "Suédois" -#: ../gtk/propertybox.c:1094 +#: ../gtk/propertybox.c:1173 msgid "Italian" msgstr "Italien" -#: ../gtk/propertybox.c:1095 +#: ../gtk/propertybox.c:1174 msgid "Spanish" msgstr "Espagnol" -#: ../gtk/propertybox.c:1096 +#: ../gtk/propertybox.c:1175 msgid "Brazilian Portugese" msgstr "Portugais brésilien" -#: ../gtk/propertybox.c:1097 +#: ../gtk/propertybox.c:1176 msgid "Polish" msgstr "Polonais" -#: ../gtk/propertybox.c:1098 +#: ../gtk/propertybox.c:1177 msgid "German" msgstr "Allemand" -#: ../gtk/propertybox.c:1099 +#: ../gtk/propertybox.c:1178 msgid "Russian" msgstr "Russe" -#: ../gtk/propertybox.c:1100 +#: ../gtk/propertybox.c:1179 msgid "Japanese" msgstr "日本語" -#: ../gtk/propertybox.c:1101 +#: ../gtk/propertybox.c:1180 msgid "Dutch" msgstr "Néérlandais" -#: ../gtk/propertybox.c:1102 +#: ../gtk/propertybox.c:1181 msgid "Hungarian" msgstr "Hongrois" -#: ../gtk/propertybox.c:1103 +#: ../gtk/propertybox.c:1182 msgid "Czech" msgstr "Tchèque" -#: ../gtk/propertybox.c:1104 +#: ../gtk/propertybox.c:1183 msgid "Chinese" msgstr "简体中文" -#: ../gtk/propertybox.c:1105 +#: ../gtk/propertybox.c:1184 msgid "Traditional Chinese" msgstr "Chinois traditionnel" -#: ../gtk/propertybox.c:1106 +#: ../gtk/propertybox.c:1185 msgid "Norwegian" msgstr "Norvégien" -#: ../gtk/propertybox.c:1107 +#: ../gtk/propertybox.c:1186 msgid "Hebrew" msgstr "Hébreu" -#: ../gtk/propertybox.c:1108 +#: ../gtk/propertybox.c:1187 msgid "Serbian" msgstr "Serbe" -#: ../gtk/propertybox.c:1175 +#: ../gtk/propertybox.c:1188 +msgid "Arabic" +msgstr "Arabe" + +#: ../gtk/propertybox.c:1189 +msgid "Turkish" +msgstr "Turc" + +#: ../gtk/propertybox.c:1246 msgid "" "You need to restart linphone for the new language selection to take effect." msgstr "La nouvelle selection de langue prendra effet au prochain démarrage de linphone." -#: ../gtk/propertybox.c:1255 +#: ../gtk/propertybox.c:1326 msgid "None" msgstr "Aucun" -#: ../gtk/propertybox.c:1259 +#: ../gtk/propertybox.c:1330 msgid "SRTP" msgstr "SRTP" -#: ../gtk/propertybox.c:1265 +#: ../gtk/propertybox.c:1336 msgid "DTLS" msgstr "DTLS" -#: ../gtk/propertybox.c:1272 +#: ../gtk/propertybox.c:1343 msgid "ZRTP" msgstr "ZRTP" @@ -424,324 +450,195 @@ msgid_plural "Found %i contacts" msgstr[0] "%i contact trouvé." msgstr[1] "%i contacts trouvés." -#: ../gtk/setupwizard.c:32 -msgid "" -"Welcome!\n" -"This assistant will help you to use a SIP account for your calls." -msgstr "Bienvenue !\nCet assistant va vous aider à utiliser un compte SIP pour vos appels." - -#: ../gtk/setupwizard.c:41 -msgid "Create an account on linphone.org" -msgstr "Créer un compte sur linphone.org" - -#: ../gtk/setupwizard.c:42 -msgid "I have already a linphone.org account and I just want to use it" -msgstr "J'ai déjà un compte linphone.org et je souhaite l'utiliser" - -#: ../gtk/setupwizard.c:43 -msgid "I have already a sip account and I just want to use it" -msgstr "J'ai déjà un compte Sip et je souhaite l'utiliser" - -#: ../gtk/setupwizard.c:44 -msgid "I want to specify a remote configuration URI" -msgstr "Je veux spécifier une URI de configuration" - -#: ../gtk/setupwizard.c:87 -msgid "Enter your linphone.org username" -msgstr "Entrez votre identifiant linphone.org" - -#: ../gtk/setupwizard.c:100 ../gtk/parameters.ui.h:85 ../gtk/ldap.ui.h:4 -msgid "Username:" -msgstr "Nom d'utilisateur:" - -#: ../gtk/setupwizard.c:102 ../gtk/password.ui.h:4 ../gtk/ldap.ui.h:5 -msgid "Password:" -msgstr "Mot de passe:" - -#: ../gtk/setupwizard.c:122 -msgid "Enter your account informations" -msgstr "Entrez les informations concernant votre compte" - -#: ../gtk/setupwizard.c:138 -msgid "Username*" -msgstr "Nom d'utilisateur*" - -#: ../gtk/setupwizard.c:139 -msgid "Password*" -msgstr "Mot de passe*" - -#: ../gtk/setupwizard.c:142 -msgid "Domain*" -msgstr "Domaine*" - -#: ../gtk/setupwizard.c:143 -msgid "Proxy" -msgstr "Proxy" - -#: ../gtk/setupwizard.c:322 -msgid "(*) Required fields" -msgstr "(*) Champs requis" - -#: ../gtk/setupwizard.c:323 -msgid "Username: (*)" -msgstr "Nom d'utilisateur: (*)" - -#: ../gtk/setupwizard.c:325 -msgid "Password: (*)" -msgstr "Mot de passe: (*)" - -#: ../gtk/setupwizard.c:327 -msgid "Email: (*)" -msgstr "Email : (*)" - -#: ../gtk/setupwizard.c:329 -msgid "Confirm your password: (*)" -msgstr "Confirmez votre mot de passe: (*)" - -#: ../gtk/setupwizard.c:343 -msgid "Keep me informed with linphone updates" -msgstr "Me tenir informer des mises à jour de Linphone " - -#: ../gtk/setupwizard.c:399 -msgid "" -"Error, account not validated, username already used or server unreachable.\n" -"Please go back and try again." -msgstr "Erreur, le compte n'est pas validé, l'identifiant est déjà utilisé ou le serveur n'est pas accessible.\nMerci d'essayer à nouveau." - -#: ../gtk/setupwizard.c:410 -msgid "Thank you. Your account is now configured and ready for use." -msgstr "Merci. Votre compte est maintenant configuré et prêt à être utilisé." - -#: ../gtk/setupwizard.c:418 -msgid "" -"Please validate your account by clicking on the link we just sent you by email.\n" -"Then come back here and press Next button." -msgstr "Merci de valider votre compte en cliquant sur le lien que nous avons envoyé par email.\nPuis appuyez sur suivant." - -#: ../gtk/setupwizard.c:609 -msgid "SIP account configuration assistant" -msgstr "Assistant de configuration de compte." - -#: ../gtk/setupwizard.c:629 -msgid "Welcome to the account setup assistant" -msgstr "Bienvenue dans l'assistant de configuration de compte." - -#: ../gtk/setupwizard.c:634 -msgid "Account setup assistant" -msgstr "Assistant de configuration de compte." - -#: ../gtk/setupwizard.c:640 -msgid "Configure your account (step 1/1)" -msgstr "Configurez votre compte (étape 1/1)" - -#: ../gtk/setupwizard.c:645 -msgid "Enter your sip username (step 1/1)" -msgstr "Entrez votre identifiant sip (étape 1/1)" - -#: ../gtk/setupwizard.c:649 -msgid "Enter account information (step 1/2)" -msgstr "Entrez les informations concernant votre compte (étape 1/2)" - -#: ../gtk/setupwizard.c:658 -msgid "Validation (step 2/2)" -msgstr "Validation (étape 2/2)" - -#: ../gtk/setupwizard.c:663 -msgid "Error" -msgstr "Erreur" - -#: ../gtk/setupwizard.c:667 ../gtk/audio_assistant.c:534 -msgid "Terminating" -msgstr "En cours d’arrêt." - -#: ../gtk/incall_view.c:70 ../gtk/incall_view.c:94 +#: ../gtk/incall_view.c:67 ../gtk/incall_view.c:87 #, c-format msgid "Call #%i" msgstr "Appel #%i" -#: ../gtk/incall_view.c:155 +#: ../gtk/incall_view.c:145 #, c-format msgid "Transfer to call #%i with %s" msgstr "Transférer vers l'appel #%i avec %s" -#: ../gtk/incall_view.c:211 ../gtk/incall_view.c:214 +#: ../gtk/incall_view.c:202 ../gtk/incall_view.c:205 msgid "Not used" msgstr "Non utilisé" -#: ../gtk/incall_view.c:221 +#: ../gtk/incall_view.c:212 msgid "ICE not activated" msgstr "ICE non activé" -#: ../gtk/incall_view.c:223 +#: ../gtk/incall_view.c:214 msgid "ICE failed" msgstr "Erreur ICE" -#: ../gtk/incall_view.c:225 +#: ../gtk/incall_view.c:216 msgid "ICE in progress" msgstr "Négociation ICE en cours" -#: ../gtk/incall_view.c:227 +#: ../gtk/incall_view.c:218 msgid "Going through one or more NATs" msgstr "Via un ou plusieurs NATs" -#: ../gtk/incall_view.c:229 +#: ../gtk/incall_view.c:220 msgid "Direct" msgstr "En direct" -#: ../gtk/incall_view.c:231 +#: ../gtk/incall_view.c:222 msgid "Through a relay server" msgstr "Via un serveur relais" -#: ../gtk/incall_view.c:239 +#: ../gtk/incall_view.c:230 msgid "uPnP not activated" msgstr "uPnP non activé" -#: ../gtk/incall_view.c:241 +#: ../gtk/incall_view.c:232 msgid "uPnP in progress" msgstr "uPnP en cours" -#: ../gtk/incall_view.c:243 +#: ../gtk/incall_view.c:234 msgid "uPnp not available" msgstr "uPnP est indisponible" -#: ../gtk/incall_view.c:245 +#: ../gtk/incall_view.c:236 msgid "uPnP is running" msgstr "uPnP en cours d’exécution" -#: ../gtk/incall_view.c:247 +#: ../gtk/incall_view.c:238 msgid "uPnP failed" msgstr "uPnP a échoué." -#: ../gtk/incall_view.c:257 ../gtk/incall_view.c:258 +#: ../gtk/incall_view.c:248 ../gtk/incall_view.c:249 msgid "Direct or through server" msgstr "Directe ou via un serveur" -#: ../gtk/incall_view.c:267 ../gtk/incall_view.c:279 +#: ../gtk/incall_view.c:258 ../gtk/incall_view.c:270 #, c-format msgid "" "download: %f\n" "upload: %f (kbit/s)" msgstr "débit descendant : %f\ndébit ascendant : %f (kbits/s)" -#: ../gtk/incall_view.c:272 ../gtk/incall_view.c:274 +#: ../gtk/incall_view.c:263 ../gtk/incall_view.c:265 #, c-format msgid "%ix%i @ %f fps" msgstr "%ix%i @ %f fps" -#: ../gtk/incall_view.c:304 +#: ../gtk/incall_view.c:295 #, c-format msgid "%.3f seconds" msgstr "%.3f secondes" -#: ../gtk/incall_view.c:407 ../gtk/main.ui.h:12 ../gtk/videowindow.c:235 +#: ../gtk/incall_view.c:453 ../gtk/in_call_frame.ui.h:10 +#: ../gtk/videowindow.c:236 msgid "Hang up" msgstr "Raccrocher" -#: ../gtk/incall_view.c:511 +#: ../gtk/incall_view.c:559 msgid "Calling..." msgstr "Tentative d'appel..." -#: ../gtk/incall_view.c:514 ../gtk/incall_view.c:733 -msgid "00::00::00" -msgstr "00::00::00" +#: ../gtk/incall_view.c:562 ../gtk/incall_view.c:792 +msgid "00:00:00" +msgstr "00:00:00" -#: ../gtk/incall_view.c:525 +#: ../gtk/incall_view.c:573 msgid "Incoming call" msgstr "Appel entrant" -#: ../gtk/incall_view.c:562 +#: ../gtk/incall_view.c:610 msgid "good" msgstr "bon" -#: ../gtk/incall_view.c:564 +#: ../gtk/incall_view.c:612 msgid "average" msgstr "moyen" -#: ../gtk/incall_view.c:566 +#: ../gtk/incall_view.c:614 msgid "poor" msgstr "faible" -#: ../gtk/incall_view.c:568 +#: ../gtk/incall_view.c:616 msgid "very poor" msgstr "très faible" -#: ../gtk/incall_view.c:570 +#: ../gtk/incall_view.c:618 msgid "too bad" msgstr "nulle" -#: ../gtk/incall_view.c:571 ../gtk/incall_view.c:587 +#: ../gtk/incall_view.c:619 ../gtk/incall_view.c:635 msgid "unavailable" msgstr "indisponible" -#: ../gtk/incall_view.c:679 +#: ../gtk/incall_view.c:731 msgid "Secured by SRTP" msgstr "Sécurisé par SRTP" -#: ../gtk/incall_view.c:685 +#: ../gtk/incall_view.c:737 msgid "Secured by DTLS" msgstr "Sécurisé par DTLS" -#: ../gtk/incall_view.c:691 +#: ../gtk/incall_view.c:743 #, c-format msgid "Secured by ZRTP - [auth token: %s]" msgstr "Sécurisé par ZRTP- [jeton: %s]" -#: ../gtk/incall_view.c:697 +#: ../gtk/incall_view.c:747 msgid "Set unverified" msgstr "Marquer comme non vérifié" -#: ../gtk/incall_view.c:697 ../gtk/main.ui.h:4 +#: ../gtk/incall_view.c:747 msgid "Set verified" msgstr "Marquer comme vérifié" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In conference" msgstr "En conférence" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In call" msgstr "Appel en cours" -#: ../gtk/incall_view.c:764 +#: ../gtk/incall_view.c:824 msgid "Paused call" msgstr "Appel en attente" -#: ../gtk/incall_view.c:800 +#: ../gtk/incall_view.c:861 msgid "Call ended." msgstr "Appel terminé." -#: ../gtk/incall_view.c:831 +#: ../gtk/incall_view.c:892 msgid "Transfer in progress" msgstr "Transfert en cours" -#: ../gtk/incall_view.c:834 +#: ../gtk/incall_view.c:895 msgid "Transfer done." msgstr "Transfert terminé" -#: ../gtk/incall_view.c:837 +#: ../gtk/incall_view.c:898 msgid "Transfer failed." msgstr "Transfert échoué" -#: ../gtk/incall_view.c:881 +#: ../gtk/incall_view.c:929 msgid "Resume" msgstr "Reprendre" -#: ../gtk/incall_view.c:888 ../gtk/main.ui.h:9 +#: ../gtk/incall_view.c:929 ../gtk/in_call_frame.ui.h:7 msgid "Pause" msgstr "Pause" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 #, c-format msgid "" "Recording into\n" "%s %s" msgstr "Enregistrement dans\n%s %s" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 msgid "(Paused)" msgstr "(en attente)" -#: ../gtk/loginframe.c:87 +#: ../gtk/loginframe.c:75 #, c-format msgid "Please enter login information for %s" msgstr "Entrez vos identifiants pour %s" @@ -756,263 +653,108 @@ msgstr "chargement depuis %s" msgid "Downloading of remote configuration from %s failed." msgstr "Le chargement de la configuration depuis %s a échoué." -#: ../gtk/audio_assistant.c:98 +#: ../gtk/audio_assistant.c:103 msgid "No voice detected" msgstr "Voix non détectée" -#: ../gtk/audio_assistant.c:99 +#: ../gtk/audio_assistant.c:104 msgid "Too low" msgstr "Trop bas" -#: ../gtk/audio_assistant.c:100 +#: ../gtk/audio_assistant.c:105 msgid "Good" msgstr "Bien" -#: ../gtk/audio_assistant.c:101 +#: ../gtk/audio_assistant.c:106 msgid "Too loud" msgstr "Trop bruyant" -#: ../gtk/audio_assistant.c:183 +#: ../gtk/audio_assistant.c:188 msgid "Did you hear three beeps ?" msgstr "Avez-vous entendu trois bips ?" -#: ../gtk/audio_assistant.c:292 ../gtk/audio_assistant.c:297 +#: ../gtk/audio_assistant.c:299 ../gtk/audio_assistant.c:304 msgid "Sound preferences not found " msgstr "Préférences son non trouvé" -#: ../gtk/audio_assistant.c:306 +#: ../gtk/audio_assistant.c:313 msgid "Cannot launch system sound control " msgstr "Impossible de démarrer le contrôleur système du son" -#: ../gtk/audio_assistant.c:318 +#: ../gtk/audio_assistant.c:325 msgid "" "Welcome!\n" "This assistant will help you to configure audio settings for Linphone" msgstr "Bienvenue !\nCet assistant va vous aider à régler les paramètres audio de votre ordinateur pour une utilisation optimale avec Linphone." -#: ../gtk/audio_assistant.c:328 +#: ../gtk/audio_assistant.c:335 msgid "Capture device" msgstr "Périphérique de capture" -#: ../gtk/audio_assistant.c:329 +#: ../gtk/audio_assistant.c:336 msgid "Recorded volume" msgstr "Volume enregistré" -#: ../gtk/audio_assistant.c:333 +#: ../gtk/audio_assistant.c:340 msgid "No voice" msgstr "Silencieux" -#: ../gtk/audio_assistant.c:334 ../gtk/audio_assistant.c:373 +#: ../gtk/audio_assistant.c:341 ../gtk/audio_assistant.c:380 msgid "System sound preferences" msgstr "Préférences son système" -#: ../gtk/audio_assistant.c:369 +#: ../gtk/audio_assistant.c:376 msgid "Playback device" msgstr "Périphérique d'écoute" -#: ../gtk/audio_assistant.c:370 +#: ../gtk/audio_assistant.c:377 msgid "Play three beeps" msgstr "Joue trois bips" -#: ../gtk/audio_assistant.c:403 +#: ../gtk/audio_assistant.c:410 msgid "Press the record button and say some words" msgstr "Appuyer sur le bouton enregistrer et dites quelques mots" -#: ../gtk/audio_assistant.c:404 +#: ../gtk/audio_assistant.c:411 msgid "Listen to your record voice" msgstr "Ecoutez votre voix enregistrée" -#: ../gtk/audio_assistant.c:405 +#: ../gtk/audio_assistant.c:412 ../gtk/conf_frame.ui.h:2 +#: ../gtk/in_call_frame.ui.h:4 msgid "Record" msgstr "Enregistrer" -#: ../gtk/audio_assistant.c:406 +#: ../gtk/audio_assistant.c:413 msgid "Play" msgstr "Jouer" -#: ../gtk/audio_assistant.c:433 +#: ../gtk/audio_assistant.c:440 msgid "Let's start Linphone now" msgstr "Démarrons Linphone maintenant" -#: ../gtk/audio_assistant.c:503 +#: ../gtk/audio_assistant.c:510 msgid "Audio Assistant" msgstr "Assistant audio" -#: ../gtk/audio_assistant.c:513 ../gtk/main.ui.h:32 +#: ../gtk/audio_assistant.c:520 ../gtk/main.ui.h:13 msgid "Audio assistant" msgstr "Assistant audio" -#: ../gtk/audio_assistant.c:518 +#: ../gtk/audio_assistant.c:525 msgid "Mic Gain calibration" msgstr "Calibration du gain du microphone" -#: ../gtk/audio_assistant.c:524 +#: ../gtk/audio_assistant.c:531 msgid "Speaker volume calibration" msgstr "Calibration du volume du haut parleur" -#: ../gtk/audio_assistant.c:529 +#: ../gtk/audio_assistant.c:536 msgid "Record and Play" msgstr "Enregistrer et joue" -#: ../gtk/main.ui.h:1 -msgid "Callee name" -msgstr "Nom du correspondant" - -#: ../gtk/main.ui.h:2 -msgid "Send" -msgstr "Envoyer" - -#: ../gtk/main.ui.h:3 -msgid "End conference" -msgstr "Fin de conférence" - -#: ../gtk/main.ui.h:7 -msgid "Record this call to an audio file" -msgstr "Enregistrement de l'appel dans un fichier audio." - -#: ../gtk/main.ui.h:8 -msgid "Video" -msgstr "Vidéo" - -#: ../gtk/main.ui.h:10 -msgid "Mute" -msgstr "Couper le son" - -#: ../gtk/main.ui.h:11 -msgid "Transfer" -msgstr "Transfert" - -#: ../gtk/main.ui.h:14 -msgid "In call" -msgstr "Appel en cours" - -#: ../gtk/main.ui.h:15 -msgid "Duration" -msgstr "Durée" - -#: ../gtk/main.ui.h:16 -msgid "Call quality rating" -msgstr "Qualité de l'appel" - -#: ../gtk/main.ui.h:17 -msgid "All users" -msgstr "Tous" - -#: ../gtk/main.ui.h:18 -msgid "Online users" -msgstr "En ligne" - -#: ../gtk/main.ui.h:19 -msgid "ADSL" -msgstr "ADSL" - -#: ../gtk/main.ui.h:20 -msgid "Fiber Channel" -msgstr "Fibre optique" - -#: ../gtk/main.ui.h:21 -msgid "Default" -msgstr "Par défaut" - -#: ../gtk/main.ui.h:22 -msgid "Delete" -msgstr "Supprimer" - -#: ../gtk/main.ui.h:23 -msgid "_Options" -msgstr "_Options" - -#: ../gtk/main.ui.h:24 -msgid "Set configuration URI" -msgstr "URI de configuration" - -#: ../gtk/main.ui.h:25 -msgid "Always start video" -msgstr "Toujours démarrer la vidéo" - -#: ../gtk/main.ui.h:26 -msgid "Enable self-view" -msgstr "Se voir" - -#: ../gtk/main.ui.h:27 -msgid "_Help" -msgstr "_Aide" - -#: ../gtk/main.ui.h:28 -msgid "Show debug window" -msgstr "Fenêtre de débogage" - -#: ../gtk/main.ui.h:29 -msgid "_Homepage" -msgstr "_Site web" - -#: ../gtk/main.ui.h:30 -msgid "Check _Updates" -msgstr "_Mises à jour" - -#: ../gtk/main.ui.h:31 -msgid "Account assistant" -msgstr "Assistant de compte" - -#: ../gtk/main.ui.h:33 -msgid "SIP address or phone number:" -msgstr "Adresse SIP ou numéro" - -#: ../gtk/main.ui.h:34 -msgid "Initiate a new call" -msgstr "Démarrer un nouvel appel" - -#: ../gtk/main.ui.h:35 -msgid "Contacts" -msgstr "Contacts" - -#: ../gtk/main.ui.h:36 -msgid "Search" -msgstr "Rechercher" - -#: ../gtk/main.ui.h:37 -msgid "Add contacts from directory" -msgstr "Ajouter un contact depuis l'annuaire" - -#: ../gtk/main.ui.h:38 -msgid "Add contact" -msgstr "Ajouter un contact." - -#: ../gtk/main.ui.h:39 -msgid "Recent calls" -msgstr "Appels récents" - -#: ../gtk/main.ui.h:40 -msgid "My current identity:" -msgstr "Mon identité SIP :" - -#: ../gtk/main.ui.h:41 ../gtk/tunnel_config.ui.h:7 -msgid "Username" -msgstr "Nom d'utilisateur" - -#: ../gtk/main.ui.h:42 ../gtk/tunnel_config.ui.h:8 -msgid "Password" -msgstr "Mot de passe" - -#: ../gtk/main.ui.h:43 -msgid "Internet connection:" -msgstr "Connexion internet:" - -#: ../gtk/main.ui.h:44 -msgid "Automatically log me in" -msgstr "Me connecter automatiquement" - -#: ../gtk/main.ui.h:45 ../gtk/password.ui.h:3 -msgid "UserID" -msgstr "ID utilisateur" - -#: ../gtk/main.ui.h:46 -msgid "Login information" -msgstr "Information de login" - -#: ../gtk/main.ui.h:47 -msgid "Welcome!" -msgstr "Bienvenue !" +#: ../gtk/audio_assistant.c:541 ../gtk/setup_wizard.ui.h:38 +msgid "Terminating" +msgstr "En cours d’arrêt." #: ../gtk/about.ui.h:1 msgid "About Linphone" @@ -1042,456 +784,6 @@ msgid "" "he: Eli Zaretskii \n" msgstr "fr: Simon Morlat\nen: Simon Morlat and Delphine Perreau\nit: Alberto Zanoni \nde: Jean-Jacques Sarton \nsv: Daniel Nylander \nes: Jesus Benitez \nja: YAMAGUCHI YOSHIYA \npt_BR: Rafael Caesar Lenzi \npl: Robert Nasiadek \ncs: Petr Pisar \nhu: anonymous\nhe: Eli Zaretskii \n" -#: ../gtk/contact.ui.h:2 -msgid "SIP Address" -msgstr "Adresse SIP" - -#: ../gtk/contact.ui.h:3 -msgid "Show this contact presence status" -msgstr "Voir l'état de présence de ce contact" - -#: ../gtk/contact.ui.h:4 -msgid "Allow this contact to see my presence status" -msgstr "Autoriser ce contact à voir ma présence" - -#: ../gtk/contact.ui.h:5 -msgid "Contact information" -msgstr "Information sur le contact" - -#: ../gtk/log.ui.h:1 -msgid "Linphone debug window" -msgstr "Fenêtre de débogage de linphone" - -#: ../gtk/log.ui.h:2 -msgid "Scroll to end" -msgstr "Défiler jusqu'à la fin" - -#: ../gtk/password.ui.h:1 -msgid "Linphone - Authentication required" -msgstr "Linphone - Authentification demandée" - -#: ../gtk/password.ui.h:2 -msgid "Please enter the domain password" -msgstr "Entrez votre mot de passe pour le domaine" - -#: ../gtk/call_logs.ui.h:1 -msgid "Call history" -msgstr "Historique des appels" - -#: ../gtk/call_logs.ui.h:2 -msgid "Clear all" -msgstr "Tout vider" - -#: ../gtk/call_logs.ui.h:3 -msgid "Call back" -msgstr "Rappeler" - -#: ../gtk/sip_account.ui.h:1 -msgid "Linphone - Configure a SIP account" -msgstr "Linphone - Configurer un compte SIP" - -#: ../gtk/sip_account.ui.h:2 -msgid "Your SIP identity:" -msgstr "Votre identité SIP :" - -#: ../gtk/sip_account.ui.h:3 -msgid "Looks like sip:@" -msgstr "De la forme sip:@" - -#: ../gtk/sip_account.ui.h:4 -msgid "sip:" -msgstr "sip:" - -#: ../gtk/sip_account.ui.h:5 -msgid "SIP Proxy address:" -msgstr "Adresse du proxy SIP:" - -#: ../gtk/sip_account.ui.h:6 -msgid "Looks like sip:" -msgstr "De la forme sip:" - -#: ../gtk/sip_account.ui.h:7 -msgid "Registration duration (sec):" -msgstr "Période d'enregistrement (secondes):" - -#: ../gtk/sip_account.ui.h:8 -msgid "Contact params (optional):" -msgstr "Paramètres de contact (optionnel):" - -#: ../gtk/sip_account.ui.h:9 -msgid "AVPF regular RTCP interval (sec):" -msgstr "Intervalle standard RTCP AVPF (sec) :" - -#: ../gtk/sip_account.ui.h:10 -msgid "Route (optional):" -msgstr "Route (optionnel):" - -#: ../gtk/sip_account.ui.h:11 -msgid "Transport" -msgstr "Transport" - -#: ../gtk/sip_account.ui.h:12 -msgid "Register" -msgstr "S'enregistrer" - -#: ../gtk/sip_account.ui.h:13 -msgid "Publish presence information" -msgstr "Publier la présence" - -#: ../gtk/sip_account.ui.h:14 -msgid "Enable AVPF" -msgstr "Activer AVPF" - -#: ../gtk/sip_account.ui.h:15 -msgid "Configure a SIP account" -msgstr "Configurer un compte SIP" - -#: ../gtk/parameters.ui.h:1 -msgid "anonymous" -msgstr "anonyme" - -#: ../gtk/parameters.ui.h:2 -msgid "GSSAPI" -msgstr "GSSAPI" - -#: ../gtk/parameters.ui.h:3 -msgid "SASL" -msgstr "SASL" - -#: ../gtk/parameters.ui.h:4 -msgid "default soundcard" -msgstr "Carte son par défaut" - -#: ../gtk/parameters.ui.h:5 -msgid "a sound card" -msgstr "une carte son" - -#: ../gtk/parameters.ui.h:6 -msgid "default camera" -msgstr "camera par défaut" - -#: ../gtk/parameters.ui.h:7 -msgid "CIF" -msgstr "CIF" - -#: ../gtk/parameters.ui.h:8 -msgid "Audio codecs" -msgstr "Codecs audio" - -#: ../gtk/parameters.ui.h:9 -msgid "Video codecs" -msgstr "Codecs vidéo" - -#: ../gtk/parameters.ui.h:10 -msgid "C" -msgstr "C" - -#: ../gtk/parameters.ui.h:11 -msgid "SIP (UDP)" -msgstr "SIP (UDP)" - -#: ../gtk/parameters.ui.h:12 -msgid "SIP (TCP)" -msgstr "SIP (TCP)" - -#: ../gtk/parameters.ui.h:13 -msgid "SIP (TLS)" -msgstr "SIP (TLS)" - -#: ../gtk/parameters.ui.h:14 -msgid "Settings" -msgstr "Réglages" - -#: ../gtk/parameters.ui.h:15 -msgid "Set Maximum Transmission Unit:" -msgstr "Spécifier la Maximum Transmission Unit" - -#: ../gtk/parameters.ui.h:16 -msgid "Send DTMFs as SIP info" -msgstr "Envoyer les digits en tant que SIP INFO" - -#: ../gtk/parameters.ui.h:17 -msgid "Allow IPv6" -msgstr "Utiliser IPv6" - -#: ../gtk/parameters.ui.h:18 -msgid "Transport" -msgstr "Transport" - -#: ../gtk/parameters.ui.h:19 -msgid "SIP/UDP port" -msgstr "Port SIP / UDP" - -#: ../gtk/parameters.ui.h:21 -msgid "Random" -msgstr "Aléatoire" - -#: ../gtk/parameters.ui.h:22 -msgid "SIP/TCP port" -msgstr "Port SIP / TCP" - -#: ../gtk/parameters.ui.h:23 -msgid "Audio RTP/UDP:" -msgstr "Audio RTP / UDP :" - -#: ../gtk/parameters.ui.h:24 -msgid "Fixed" -msgstr "Fixe" - -#: ../gtk/parameters.ui.h:25 -msgid "Video RTP/UDP:" -msgstr "Vidéo RTP / UDP :" - -#: ../gtk/parameters.ui.h:26 -msgid "Media encryption type" -msgstr "Type d'encryption media" - -#: ../gtk/parameters.ui.h:27 -msgid "Media encryption is mandatory" -msgstr "Le chiffrement media est obligatoire" - -#: ../gtk/parameters.ui.h:28 -msgid "Tunnel" -msgstr "Tunnel" - -#: ../gtk/parameters.ui.h:29 -msgid "DSCP fields" -msgstr "Champs DSCP" - -#: ../gtk/parameters.ui.h:30 -msgid "Network protocol and ports" -msgstr "Protocoles réseaux et ports" - -#: ../gtk/parameters.ui.h:31 -msgid "Direct connection to the Internet" -msgstr "Connexion directe à l'Internet" - -#: ../gtk/parameters.ui.h:32 -msgid "Behind NAT / Firewall (specify gateway IP )" -msgstr "Derrière un pare-feu (spécifier la passerelle ci dessous)" - -#: ../gtk/parameters.ui.h:33 -msgid "Behind NAT / Firewall (use STUN to resolve)" -msgstr "Derrière un pare-feu (utiliser STUN)" - -#: ../gtk/parameters.ui.h:34 -msgid "Behind NAT / Firewall (use ICE)" -msgstr "Derrière un pare-feu (utiliser ICE)" - -#: ../gtk/parameters.ui.h:35 -msgid "Behind NAT / Firewall (use uPnP)" -msgstr "Derrière un pare-feu (utiliser uPnP)" - -#: ../gtk/parameters.ui.h:36 -msgid "Public IP address:" -msgstr "Adresse IP publique:" - -#: ../gtk/parameters.ui.h:37 -msgid "Stun server:" -msgstr "Serveur STUN:" - -#: ../gtk/parameters.ui.h:38 -msgid "NAT and Firewall" -msgstr "Paramètres liés au pare-feu" - -#: ../gtk/parameters.ui.h:39 -msgid "Network settings" -msgstr "Paramètres réseau" - -#: ../gtk/parameters.ui.h:40 -msgid "Ring sound:" -msgstr "Sonnerie:" - -#: ../gtk/parameters.ui.h:41 -msgid "ALSA special device (optional):" -msgstr "Appareil ALSA spécifique (optionnel) :" - -#: ../gtk/parameters.ui.h:42 -msgid "Capture device:" -msgstr "Périphérique de capture:" - -#: ../gtk/parameters.ui.h:43 -msgid "Ring device:" -msgstr "Périphérique de sonnerie:" - -#: ../gtk/parameters.ui.h:44 -msgid "Playback device:" -msgstr "Périphérique d'écoute:" - -#: ../gtk/parameters.ui.h:45 -msgid "Enable echo cancellation" -msgstr "Activer l'annulation d'écho" - -#: ../gtk/parameters.ui.h:46 -msgid "Audio" -msgstr "Son" - -#: ../gtk/parameters.ui.h:47 -msgid "Video input device:" -msgstr "Périphérique d'entrée vidéo" - -#: ../gtk/parameters.ui.h:48 -msgid "Prefered video resolution:" -msgstr "Résolution de vidéo préférée:" - -#: ../gtk/parameters.ui.h:49 -msgid "Video output method:" -msgstr "Type de rendu video:" - -#: ../gtk/parameters.ui.h:50 -msgid "Show camera preview" -msgstr "Afficher la vidéo" - -#: ../gtk/parameters.ui.h:51 -msgid "Video" -msgstr "Video" - -#: ../gtk/parameters.ui.h:52 -msgid "Multimedia settings" -msgstr "Paramètres multimedia" - -#: ../gtk/parameters.ui.h:53 -msgid "This section defines your SIP address when not using a SIP account" -msgstr "Cette rubrique permet de définir son adresse SIP lorsqu'on ne possède pas de compte SIP" - -#: ../gtk/parameters.ui.h:54 -msgid "Your display name (eg: John Doe):" -msgstr "Votre nom d'affichage (ex: John Doe)" - -#: ../gtk/parameters.ui.h:55 -msgid "Your username:" -msgstr "Votre nom d'utilisateur:" - -#: ../gtk/parameters.ui.h:56 -msgid "Your resulting SIP address:" -msgstr "Votre adresse SIP:" - -#: ../gtk/parameters.ui.h:57 -msgid "Default identity" -msgstr "Identité par défaut" - -#: ../gtk/parameters.ui.h:58 -msgid "Wizard" -msgstr "Assistant" - -#: ../gtk/parameters.ui.h:59 -msgid "Add" -msgstr "Ajouter" - -#: ../gtk/parameters.ui.h:60 -msgid "Edit" -msgstr "Editer" - -#: ../gtk/parameters.ui.h:61 -msgid "Remove" -msgstr "Enlever" - -#: ../gtk/parameters.ui.h:62 -msgid "Proxy accounts" -msgstr "Comptes SIP via des proxy" - -#: ../gtk/parameters.ui.h:63 -msgid "Erase all passwords" -msgstr "Effacer tous les mots de passe" - -#: ../gtk/parameters.ui.h:64 -msgid "Privacy" -msgstr "Sécurité" - -#: ../gtk/parameters.ui.h:65 -msgid "Automatically answer when a call is received" -msgstr "Répondre automatiquement aux appels entrants" - -#: ../gtk/parameters.ui.h:66 -msgid "Delay before answering (ms)" -msgstr "Temps d'attente avant réponse (ms)" - -#: ../gtk/parameters.ui.h:67 -msgid "Auto-answer" -msgstr "Décrochage automatique" - -#: ../gtk/parameters.ui.h:68 -msgid "Manage SIP Accounts" -msgstr "Gérer mes comptes SIP" - -#: ../gtk/parameters.ui.h:69 ../gtk/tunnel_config.ui.h:4 -msgid "Enable" -msgstr "Activer" - -#: ../gtk/parameters.ui.h:70 ../gtk/tunnel_config.ui.h:5 -msgid "Disable" -msgstr "Désactiver" - -#: ../gtk/parameters.ui.h:71 -msgid "Codecs" -msgstr "Codecs" - -#: ../gtk/parameters.ui.h:72 -msgid "0 stands for \"unlimited\"" -msgstr "Indiquez 0 pour ne pas mettre de limite" - -#: ../gtk/parameters.ui.h:73 -msgid "Upload speed limit in Kbit/sec:" -msgstr "Limite de débit montant en kbits/sec:" - -#: ../gtk/parameters.ui.h:74 -msgid "Download speed limit in Kbit/sec:" -msgstr "Limite de débit descendant en kbits/sec:" - -#: ../gtk/parameters.ui.h:75 -msgid "Enable adaptive rate control" -msgstr "Activer le control de débit adaptatif." - -#: ../gtk/parameters.ui.h:76 -msgid "" -"Adaptive rate control is a technique to dynamically guess the available " -"bandwidth during a call." -msgstr "Le control de débit adaptatif est une technique pour adapter la qualité de l'audio et de la video en fonction de la bande passante disponible, durant l'appel." - -#: ../gtk/parameters.ui.h:77 -msgid "Bandwidth control" -msgstr "Gestion de la bande passante" - -#: ../gtk/parameters.ui.h:78 -msgid "Codecs" -msgstr "Codecs" - -#: ../gtk/parameters.ui.h:79 -msgid "Language" -msgstr "Langue" - -#: ../gtk/parameters.ui.h:80 -msgid "Show advanced settings" -msgstr "Montrer les réglages avancés" - -#: ../gtk/parameters.ui.h:81 -msgid "Level" -msgstr "Niveau" - -#: ../gtk/parameters.ui.h:82 -msgid "User interface" -msgstr "Interface utilisateur" - -#: ../gtk/parameters.ui.h:83 ../gtk/ldap.ui.h:2 -msgid "Server address:" -msgstr "Adresse du serveur:" - -#: ../gtk/parameters.ui.h:84 ../gtk/ldap.ui.h:3 -msgid "Authentication method:" -msgstr "Méthode d'authentification:" - -#: ../gtk/parameters.ui.h:86 -msgid "LDAP Account setup" -msgstr "Configuration LDAP" - -#: ../gtk/parameters.ui.h:87 -msgid "LDAP" -msgstr "LDAP" - -#: ../gtk/parameters.ui.h:88 -msgid "Done" -msgstr "Fermer" - #: ../gtk/buddylookup.ui.h:1 msgid "Search contacts in directory" msgstr "Rechercher dans l'annuaire" @@ -1504,29 +796,21 @@ msgstr "Ajouter à ma liste" msgid "Search somebody" msgstr "Rechercher une personne" -#: ../gtk/waiting.ui.h:2 -msgid "Please wait" -msgstr "En attente" +#: ../gtk/callee_frame.ui.h:1 +msgid "Callee name" +msgstr "Nom du correspondant" -#: ../gtk/dscp_settings.ui.h:1 -msgid "DSCP settings" -msgstr "Réglages DSCP" +#: ../gtk/call_logs.ui.h:1 +msgid "Call history" +msgstr "Historique des appels" -#: ../gtk/dscp_settings.ui.h:2 -msgid "SIP" -msgstr "SIP" +#: ../gtk/call_logs.ui.h:2 +msgid "Clear all" +msgstr "Tout vider" -#: ../gtk/dscp_settings.ui.h:3 -msgid "Audio RTP stream" -msgstr "Flux RTP audio" - -#: ../gtk/dscp_settings.ui.h:4 -msgid "Video RTP stream" -msgstr "Flux RTP vidéo" - -#: ../gtk/dscp_settings.ui.h:5 -msgid "Set DSCP values (in hexadecimal)" -msgstr "Indiquez les valeurs DSCP (en hexacdécimal)" +#: ../gtk/call_logs.ui.h:3 +msgid "Call back" +msgstr "Rappeler" #: ../gtk/call_statistics.ui.h:1 msgid "Call statistics" @@ -1576,30 +860,112 @@ msgstr "Profil RTP" msgid "Call statistics and information" msgstr "Statistiques de l'appel et informations" -#: ../gtk/tunnel_config.ui.h:1 -msgid "Configure VoIP tunnel" -msgstr "Configuer le mode tunnel" +#: ../gtk/chatroom_frame.ui.h:1 +msgid "Send" +msgstr "Envoyer" -#: ../gtk/tunnel_config.ui.h:2 -msgid "Host" -msgstr "Hôte" +#: ../gtk/conf_frame.ui.h:1 +msgid "End conference" +msgstr "Fin de conférence" -#: ../gtk/tunnel_config.ui.h:3 -msgid "Port" -msgstr "Port" +#: ../gtk/config-uri.ui.h:1 +msgid "Specifying a remote configuration URI" +msgstr "Spécifier une URI de configuration" -#: ../gtk/tunnel_config.ui.h:6 -msgid "Configure tunnel" -msgstr "Configuration du tunnel" +#: ../gtk/config-uri.ui.h:2 +msgid "" +"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" +"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " +msgstr "Cette boite de dialogue vous permet de spécifier une addresse http ou https où la configuration doit être téléchargée au démarrage.\nVeuillez entrer l'URI http(s) ci dessous. Après avoir validé, Linphone va redémarrer automatiquement pour charger et prendre en compte la nouvelle configuration." -#: ../gtk/tunnel_config.ui.h:9 -msgid "Configure http proxy (optional)" -msgstr "Configuration d'un proxy http (optionel)" +#: ../gtk/contact.ui.h:2 +msgid "SIP Address" +msgstr "Adresse SIP" + +#: ../gtk/contact.ui.h:3 +msgid "Show this contact presence status" +msgstr "Voir l'état de présence de ce contact" + +#: ../gtk/contact.ui.h:4 +msgid "Allow this contact to see my presence status" +msgstr "Autoriser ce contact à voir ma présence" + +#: ../gtk/contact.ui.h:5 +msgid "Contact information" +msgstr "Information sur le contact" + +#: ../gtk/dscp_settings.ui.h:1 +msgid "DSCP settings" +msgstr "Réglages DSCP" + +#: ../gtk/dscp_settings.ui.h:2 +msgid "SIP" +msgstr "SIP" + +#: ../gtk/dscp_settings.ui.h:3 +msgid "Audio RTP stream" +msgstr "Flux RTP audio" + +#: ../gtk/dscp_settings.ui.h:4 +msgid "Video RTP stream" +msgstr "Flux RTP vidéo" + +#: ../gtk/dscp_settings.ui.h:5 +msgid "Set DSCP values (in hexadecimal)" +msgstr "Indiquez les valeurs DSCP (en hexacdécimal)" + +#: ../gtk/in_call_frame.ui.h:1 +msgid "Click here to set the speakers volume" +msgstr "Cliquer ici pour modifier le volume des haut-parleurs" + +#: ../gtk/in_call_frame.ui.h:5 +msgid "Record this call to an audio file" +msgstr "Enregistrement de l'appel dans un fichier audio." + +#: ../gtk/in_call_frame.ui.h:6 +msgid "Video" +msgstr "Vidéo" + +#: ../gtk/in_call_frame.ui.h:8 +msgid "Mute" +msgstr "Couper le micro" + +#: ../gtk/in_call_frame.ui.h:9 +msgid "Transfer" +msgstr "Transférer" + +#: ../gtk/in_call_frame.ui.h:12 +msgid "In call" +msgstr "Appel en cours" + +#: ../gtk/in_call_frame.ui.h:13 +msgid "Duration" +msgstr "Durée" + +#: ../gtk/in_call_frame.ui.h:14 +msgid "Call quality rating" +msgstr "Qualité de l'appel" #: ../gtk/ldap.ui.h:1 msgid "LDAP Settings" msgstr "Paramètres LDAP" +#: ../gtk/ldap.ui.h:2 ../gtk/parameters.ui.h:89 +msgid "Server address:" +msgstr "Adresse du serveur:" + +#: ../gtk/ldap.ui.h:3 ../gtk/parameters.ui.h:90 +msgid "Authentication method:" +msgstr "Méthode d'authentification:" + +#: ../gtk/ldap.ui.h:4 ../gtk/parameters.ui.h:91 ../gtk/setup_wizard.ui.h:17 +msgid "Username:" +msgstr "Nom d'utilisateur:" + +#: ../gtk/ldap.ui.h:5 ../gtk/password.ui.h:4 ../gtk/setup_wizard.ui.h:18 +msgid "Password:" +msgstr "Mot de passe:" + #: ../gtk/ldap.ui.h:6 msgid "Use TLS Connection" msgstr "Utiliser TLS" @@ -1685,15 +1051,503 @@ msgstr "DIGEST-MD5" msgid "NTLM" msgstr "NTLM" -#: ../gtk/config-uri.ui.h:1 -msgid "Specifying a remote configuration URI" -msgstr "Spécifier une URI de configuration" +#: ../gtk/login_frame.ui.h:1 ../gtk/tunnel_config.ui.h:7 +msgid "Username" +msgstr "Nom d'utilisateur" -#: ../gtk/config-uri.ui.h:2 +#: ../gtk/login_frame.ui.h:2 ../gtk/tunnel_config.ui.h:8 +msgid "Password" +msgstr "Mot de passe" + +#: ../gtk/login_frame.ui.h:3 +msgid "Internet connection:" +msgstr "Connexion internet:" + +#: ../gtk/login_frame.ui.h:4 +msgid "Automatically log me in" +msgstr "Me connecter automatiquement" + +#: ../gtk/login_frame.ui.h:5 ../gtk/password.ui.h:3 +msgid "UserID" +msgstr "ID utilisateur" + +#: ../gtk/login_frame.ui.h:6 +msgid "Login information" +msgstr "Information de login" + +#: ../gtk/login_frame.ui.h:7 +msgid "Welcome!" +msgstr "Bienvenue !" + +#: ../gtk/login_frame.ui.h:8 +msgid "ADSL" +msgstr "ADSL" + +#: ../gtk/login_frame.ui.h:9 +msgid "Fiber Channel" +msgstr "Fibre optique" + +#: ../gtk/log.ui.h:1 +msgid "Linphone debug window" +msgstr "Fenêtre de débogage de linphone" + +#: ../gtk/log.ui.h:2 +msgid "Scroll to end" +msgstr "Défiler jusqu'à la fin" + +#: ../gtk/main.ui.h:1 +msgid "Default" +msgstr "Par défaut" + +#: ../gtk/main.ui.h:2 +msgid "Delete" +msgstr "Supprimer" + +#: ../gtk/main.ui.h:3 +msgid "_Options" +msgstr "_Options" + +#: ../gtk/main.ui.h:4 +msgid "Set configuration URI" +msgstr "URI de configuration" + +#: ../gtk/main.ui.h:5 +msgid "Always start video" +msgstr "Toujours activer la vidéo" + +#: ../gtk/main.ui.h:6 +msgid "Enable self-view" +msgstr "Se voir" + +#: ../gtk/main.ui.h:7 +msgid "Show keypad" +msgstr "Afficher le pavé numérique" + +#: ../gtk/main.ui.h:8 +msgid "_Help" +msgstr "_Aide" + +#: ../gtk/main.ui.h:9 +msgid "Show debug window" +msgstr "Fenêtre de débogage" + +#: ../gtk/main.ui.h:10 +msgid "_Homepage" +msgstr "_Site web" + +#: ../gtk/main.ui.h:11 +msgid "Check _Updates" +msgstr "_Mises à jour" + +#: ../gtk/main.ui.h:12 +msgid "Account assistant" +msgstr "Assistant de compte" + +#: ../gtk/main.ui.h:14 +msgid "SIP address or phone number:" +msgstr "Adresse SIP ou numéro" + +#: ../gtk/main.ui.h:15 +msgid "Initiate a new call" +msgstr "Démarrer un nouvel appel" + +#: ../gtk/main.ui.h:16 +msgid "Contacts" +msgstr "Contacts" + +#: ../gtk/main.ui.h:17 +msgid "Search" +msgstr "Rechercher" + +#: ../gtk/main.ui.h:18 +msgid "Add contacts from directory" +msgstr "Ajouter un contact depuis l'annuaire" + +#: ../gtk/main.ui.h:19 +msgid "Add contact" +msgstr "Ajouter un contact." + +#: ../gtk/main.ui.h:20 +msgid "Clear call history" +msgstr "Effacer l'historique d'appel" + +#: ../gtk/main.ui.h:22 +msgid "My current identity:" +msgstr "Mon identité SIP :" + +#: ../gtk/main.ui.h:23 +msgid "Autoanswer is enabled" +msgstr "Décrochage automatique activé" + +#: ../gtk/parameters.ui.h:1 +msgid "anonymous" +msgstr "anonyme" + +#: ../gtk/parameters.ui.h:2 +msgid "GSSAPI" +msgstr "GSSAPI" + +#: ../gtk/parameters.ui.h:3 +msgid "SASL" +msgstr "SASL" + +#: ../gtk/parameters.ui.h:4 +msgid "default soundcard" +msgstr "Carte son par défaut" + +#: ../gtk/parameters.ui.h:5 +msgid "a sound card" +msgstr "une carte son" + +#: ../gtk/parameters.ui.h:6 +msgid "default camera" +msgstr "camera par défaut" + +#: ../gtk/parameters.ui.h:7 +msgid "CIF" +msgstr "CIF" + +#: ../gtk/parameters.ui.h:8 +msgid "Audio codecs" +msgstr "Codecs audio" + +#: ../gtk/parameters.ui.h:9 +msgid "Video codecs" +msgstr "Codecs vidéo" + +#: ../gtk/parameters.ui.h:10 +msgid "C" +msgstr "C" + +#: ../gtk/parameters.ui.h:11 +msgid "SIP (UDP)" +msgstr "SIP (UDP)" + +#: ../gtk/parameters.ui.h:12 +msgid "SIP (TCP)" +msgstr "SIP (TCP)" + +#: ../gtk/parameters.ui.h:13 +msgid "SIP (TLS)" +msgstr "SIP (TLS)" + +#: ../gtk/parameters.ui.h:14 +msgid "default" +msgstr "Par défaut" + +#: ../gtk/parameters.ui.h:15 +msgid "high-fps" +msgstr "Fréquence d'images élevée" + +#: ../gtk/parameters.ui.h:16 +msgid "custom" +msgstr "Personnalisé" + +#: ../gtk/parameters.ui.h:17 +msgid "Settings" +msgstr "Réglages" + +#: ../gtk/parameters.ui.h:18 +msgid "This section defines your SIP address when not using a SIP account" +msgstr "Cette rubrique permet de définir son adresse SIP lorsqu'on ne possède pas de compte SIP" + +#: ../gtk/parameters.ui.h:19 +msgid "Your display name (eg: John Doe):" +msgstr "Votre nom d'affichage (ex: John Doe)" + +#: ../gtk/parameters.ui.h:20 +msgid "Your username:" +msgstr "Votre nom d'utilisateur:" + +#: ../gtk/parameters.ui.h:21 +msgid "Your resulting SIP address:" +msgstr "Votre adresse SIP:" + +#: ../gtk/parameters.ui.h:22 +msgid "Default identity" +msgstr "Identité par défaut" + +#: ../gtk/parameters.ui.h:23 +msgid "Wizard" +msgstr "Assistant" + +#: ../gtk/parameters.ui.h:24 +msgid "Add" +msgstr "Ajouter" + +#: ../gtk/parameters.ui.h:25 +msgid "Edit" +msgstr "Editer" + +#: ../gtk/parameters.ui.h:26 +msgid "Remove" +msgstr "Enlever" + +#: ../gtk/parameters.ui.h:27 +msgid "Proxy accounts" +msgstr "Comptes SIP via des proxy" + +#: ../gtk/parameters.ui.h:28 +msgid "Erase all passwords" +msgstr "Effacer tous les mots de passe" + +#: ../gtk/parameters.ui.h:29 +msgid "Privacy" +msgstr "Sécurité" + +#: ../gtk/parameters.ui.h:30 +msgid "Automatically answer when a call is received" +msgstr "Répondre automatiquement aux appels entrants" + +#: ../gtk/parameters.ui.h:31 +msgid "Delay before answering (ms)" +msgstr "Temps d'attente avant réponse (ms)" + +#: ../gtk/parameters.ui.h:32 +msgid "Auto-answer" +msgstr "Décrochage automatique" + +#: ../gtk/parameters.ui.h:33 +msgid "Manage SIP Accounts" +msgstr "Gérer mes comptes SIP" + +#: ../gtk/parameters.ui.h:34 +msgid "Ring sound:" +msgstr "Sonnerie:" + +#: ../gtk/parameters.ui.h:35 +msgid "ALSA special device (optional):" +msgstr "Appareil ALSA spécifique (optionnel) :" + +#: ../gtk/parameters.ui.h:36 +msgid "Capture device:" +msgstr "Périphérique de capture:" + +#: ../gtk/parameters.ui.h:37 +msgid "Ring device:" +msgstr "Périphérique de sonnerie:" + +#: ../gtk/parameters.ui.h:38 +msgid "Playback device:" +msgstr "Périphérique d'écoute:" + +#: ../gtk/parameters.ui.h:39 +msgid "Enable echo cancellation" +msgstr "Activer l'annulation d'écho" + +#: ../gtk/parameters.ui.h:40 +msgid "Audio" +msgstr "Son" + +#: ../gtk/parameters.ui.h:41 +msgid "Video input device:" +msgstr "Périphérique d'entrée vidéo" + +#: ../gtk/parameters.ui.h:42 +msgid "Preferred video resolution:" +msgstr "Résolution vidéo préférée :" + +#: ../gtk/parameters.ui.h:43 +msgid "Video output method:" +msgstr "Type de rendu video:" + +#: ../gtk/parameters.ui.h:44 +msgid "Show camera preview" +msgstr "Afficher la vidéo" + +#: ../gtk/parameters.ui.h:45 +msgid "Video preset:" +msgstr "Profile vidéo:" + +#: ../gtk/parameters.ui.h:46 +msgid "Preferred video framerate:" +msgstr "Fréquence d'images préférée" + +#: ../gtk/parameters.ui.h:47 +msgid "0 stands for \"unlimited\"" +msgstr "Indiquez 0 pour ne pas mettre de limite" + +#: ../gtk/parameters.ui.h:48 +msgid "Video" +msgstr "Video" + +#: ../gtk/parameters.ui.h:49 +msgid "Upload speed limit in Kbit/sec:" +msgstr "Limite de débit montant en kbits/sec:" + +#: ../gtk/parameters.ui.h:50 +msgid "Download speed limit in Kbit/sec:" +msgstr "Limite de débit descendant en kbits/sec:" + +#: ../gtk/parameters.ui.h:51 +msgid "Enable adaptive rate control" +msgstr "Activer le control de débit adaptatif." + +#: ../gtk/parameters.ui.h:52 msgid "" -"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" -"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " -msgstr "Cette boite de dialogue vous permet de spécifier une addresse http ou https où la configuration doit être téléchargée au démarrage.\nVeuillez entrer l'URI http(s) ci dessous. Après avoir validé, Linphone va redémarrer automatiquement pour charger et prendre en compte la nouvelle configuration." +"Adaptive rate control is a technique to dynamically guess the available " +"bandwidth during a call." +msgstr "Le control de débit adaptatif est une technique pour adapter la qualité de l'audio et de la video en fonction de la bande passante disponible, durant l'appel." + +#: ../gtk/parameters.ui.h:53 +msgid "Bandwidth control" +msgstr "Gestion de la bande passante" + +#: ../gtk/parameters.ui.h:54 +msgid "Multimedia settings" +msgstr "Paramètres multimedia" + +#: ../gtk/parameters.ui.h:55 +msgid "Set Maximum Transmission Unit:" +msgstr "Spécifier la Maximum Transmission Unit" + +#: ../gtk/parameters.ui.h:56 +msgid "Send DTMFs as SIP info" +msgstr "Envoyer les digits en tant que SIP INFO" + +#: ../gtk/parameters.ui.h:57 +msgid "Allow IPv6" +msgstr "Utiliser IPv6" + +#: ../gtk/parameters.ui.h:58 +msgid "Transport" +msgstr "Transport" + +#: ../gtk/parameters.ui.h:59 +msgid "SIP/UDP port" +msgstr "Port SIP / UDP" + +#: ../gtk/parameters.ui.h:61 +msgid "Random" +msgstr "Aléatoire" + +#: ../gtk/parameters.ui.h:62 +msgid "SIP/TCP port" +msgstr "Port SIP / TCP" + +#: ../gtk/parameters.ui.h:63 +msgid "Audio RTP/UDP:" +msgstr "Audio RTP / UDP :" + +#: ../gtk/parameters.ui.h:64 +msgid "Fixed" +msgstr "Fixe" + +#: ../gtk/parameters.ui.h:65 +msgid "Video RTP/UDP:" +msgstr "Vidéo RTP / UDP :" + +#: ../gtk/parameters.ui.h:66 +msgid "Media encryption type" +msgstr "Type d'encryption media" + +#: ../gtk/parameters.ui.h:67 +msgid "Media encryption is mandatory" +msgstr "Le chiffrement media est obligatoire" + +#: ../gtk/parameters.ui.h:68 +msgid "Tunnel" +msgstr "Tunnel" + +#: ../gtk/parameters.ui.h:69 +msgid "DSCP fields" +msgstr "Champs DSCP" + +#: ../gtk/parameters.ui.h:70 +msgid "Network protocol and ports" +msgstr "Protocoles réseaux et ports" + +#: ../gtk/parameters.ui.h:71 +msgid "Direct connection to the Internet" +msgstr "Connexion directe à l'Internet" + +#: ../gtk/parameters.ui.h:72 +msgid "Behind NAT / Firewall (specify gateway IP )" +msgstr "Derrière un pare-feu (spécifier la passerelle ci dessous)" + +#: ../gtk/parameters.ui.h:73 +msgid "Behind NAT / Firewall (use STUN to resolve)" +msgstr "Derrière un pare-feu (utiliser STUN)" + +#: ../gtk/parameters.ui.h:74 +msgid "Behind NAT / Firewall (use ICE)" +msgstr "Derrière un pare-feu (utiliser ICE)" + +#: ../gtk/parameters.ui.h:75 +msgid "Behind NAT / Firewall (use uPnP)" +msgstr "Derrière un pare-feu (utiliser uPnP)" + +#: ../gtk/parameters.ui.h:76 +msgid "Public IP address:" +msgstr "Adresse IP publique:" + +#: ../gtk/parameters.ui.h:77 +msgid "Stun server:" +msgstr "Serveur STUN:" + +#: ../gtk/parameters.ui.h:78 +msgid "NAT and Firewall" +msgstr "Paramètres liés au pare-feu" + +#: ../gtk/parameters.ui.h:79 +msgid "Network settings" +msgstr "Paramètres réseau" + +#: ../gtk/parameters.ui.h:80 ../gtk/tunnel_config.ui.h:4 +msgid "Enable" +msgstr "Activer" + +#: ../gtk/parameters.ui.h:81 ../gtk/tunnel_config.ui.h:5 +msgid "Disable" +msgstr "Désactiver" + +#: ../gtk/parameters.ui.h:82 +msgid "Audio codecs" +msgstr "Codecs audio" + +#: ../gtk/parameters.ui.h:83 +msgid "Video codecs" +msgstr "Codecs vidéo" + +#: ../gtk/parameters.ui.h:84 +msgid "Codecs" +msgstr "Codecs" + +#: ../gtk/parameters.ui.h:85 +msgid "Language" +msgstr "Langue" + +#: ../gtk/parameters.ui.h:86 +msgid "Show advanced settings" +msgstr "Montrer les réglages avancés" + +#: ../gtk/parameters.ui.h:87 +msgid "Level" +msgstr "Niveau" + +#: ../gtk/parameters.ui.h:88 +msgid "User interface" +msgstr "Interface utilisateur" + +#: ../gtk/parameters.ui.h:92 +msgid "LDAP Account setup" +msgstr "Configuration LDAP" + +#: ../gtk/parameters.ui.h:93 +msgid "LDAP" +msgstr "LDAP" + +#: ../gtk/parameters.ui.h:94 +msgid "Done" +msgstr "Fermer" + +#: ../gtk/password.ui.h:1 +msgid "Linphone - Authentication required" +msgstr "Linphone - Authentification demandée" + +#: ../gtk/password.ui.h:2 +msgid "Please enter the domain password" +msgstr "Entrez votre mot de passe pour le domaine" #: ../gtk/provisioning-fetch.ui.h:1 msgid "Configuring..." @@ -1703,68 +1557,278 @@ msgstr "Configuration en cours" msgid "Please wait while fetching configuration from server..." msgstr "Veuillez patenter un instant pendant le chargement de la configuration distante..." -#: ../coreapi/linphonecore.c:1539 +#: ../gtk/setup_wizard.ui.h:1 +msgid "SIP account configuration assistant" +msgstr "Assistant de configuration de compte." + +#: ../gtk/setup_wizard.ui.h:2 +msgid "" +"Welcome!\n" +"This assistant will help you to use a SIP account for your calls." +msgstr "Bienvenue !\nCet assistant va vous aider à utiliser un compte SIP pour vos appels." + +#: ../gtk/setup_wizard.ui.h:4 +msgid "Welcome to the account setup assistant" +msgstr "Bienvenue dans l'assistant de configuration de compte." + +#: ../gtk/setup_wizard.ui.h:5 +msgid "Create an account on linphone.org" +msgstr "Créer un compte sur linphone.org" + +#: ../gtk/setup_wizard.ui.h:6 +msgid "I have already a linphone.org account and I just want to use it" +msgstr "J'ai déjà un compte linphone.org et je souhaite l'utiliser" + +#: ../gtk/setup_wizard.ui.h:7 +msgid "I have already a sip account and I just want to use it" +msgstr "J'ai déjà un compte Sip et je souhaite l'utiliser" + +#: ../gtk/setup_wizard.ui.h:8 +msgid "I want to specify a remote configuration URI" +msgstr "Je veux spécifier une URI de configuration" + +#: ../gtk/setup_wizard.ui.h:9 +msgid "Account setup assistant" +msgstr "Assistant de configuration de compte." + +#: ../gtk/setup_wizard.ui.h:10 +msgid "Enter your account information" +msgstr "Entrez vos paramètres de compte" + +#: ../gtk/setup_wizard.ui.h:11 +msgid "Username*" +msgstr "Nom d'utilisateur*" + +#: ../gtk/setup_wizard.ui.h:12 +msgid "Password*" +msgstr "Mot de passe*" + +#: ../gtk/setup_wizard.ui.h:13 +msgid "Domain*" +msgstr "Domaine*" + +#: ../gtk/setup_wizard.ui.h:14 +msgid "Proxy" +msgstr "Proxy" + +#: ../gtk/setup_wizard.ui.h:15 +msgid "Configure your account (step 1/1)" +msgstr "Configurez votre compte (étape 1/1)" + +#: ../gtk/setup_wizard.ui.h:16 +msgid "Enter your linphone.org username" +msgstr "Entrez votre identifiant linphone.org" + +#: ../gtk/setup_wizard.ui.h:19 +msgid "Enter your sip username (step 1/1)" +msgstr "Entrez votre identifiant sip (étape 1/1)" + +#: ../gtk/setup_wizard.ui.h:20 +msgid "(*) Required fields" +msgstr "(*) Champs requis" + +#: ../gtk/setup_wizard.ui.h:21 +msgid "Email: (*)" +msgstr "Email : (*)" + +#: ../gtk/setup_wizard.ui.h:22 +msgid "Username: (*)" +msgstr "Nom d'utilisateur: (*)" + +#: ../gtk/setup_wizard.ui.h:23 +msgid "Password: (*)" +msgstr "Mot de passe: (*)" + +#: ../gtk/setup_wizard.ui.h:24 +msgid "Confirm your password: (*)" +msgstr "Confirmez votre mot de passe: (*)" + +#: ../gtk/setup_wizard.ui.h:25 +msgid "Keep me informed with linphone updates" +msgstr "Me tenir informé des mises à jour de Linphone " + +#: ../gtk/setup_wizard.ui.h:26 +msgid "Enter account information (step 1/2)" +msgstr "Entrez les informations concernant votre compte (étape 1/2)" + +#: ../gtk/setup_wizard.ui.h:27 +msgid "Your account is being created, please wait." +msgstr "Votre compte est en cours de création. Veuillez patienter." + +#: ../gtk/setup_wizard.ui.h:28 +msgid "Account creation in progress" +msgstr "Création du compte en cours" + +#: ../gtk/setup_wizard.ui.h:29 +msgid "" +"Please validate your account by clicking on the link we just sent you by email.\n" +"Then come back here and press Next button." +msgstr "Merci de valider votre compte en cliquant sur le lien que nous avons envoyé par email.\nPuis appuyez sur suivant." + +#: ../gtk/setup_wizard.ui.h:31 +msgid "Validation (step 2/2)" +msgstr "Validation (étape 2/2)" + +#: ../gtk/setup_wizard.ui.h:32 +msgid "Checking if your account is been validated, please wait." +msgstr "Vérification que le compte a été validé. Veuillez patienter." + +#: ../gtk/setup_wizard.ui.h:33 +msgid "Account validation check in progress" +msgstr "Vérification de la validité du compte en cours" + +#: ../gtk/setup_wizard.ui.h:34 +msgid "" +"Error, account not validated, username already used or server unreachable.\n" +"Please go back and try again." +msgstr "Erreur, le compte n'est pas validé, l'identifiant est déjà utilisé ou le serveur n'est pas accessible.\nMerci d'essayer à nouveau." + +#: ../gtk/setup_wizard.ui.h:36 +msgid "Error" +msgstr "Erreur" + +#: ../gtk/setup_wizard.ui.h:37 +msgid "Thank you. Your account is now configured and ready for use." +msgstr "Merci. Votre compte est maintenant configuré et prêt à être utilisé." + +#: ../gtk/sip_account.ui.h:1 +msgid "Linphone - Configure a SIP account" +msgstr "Linphone - Configurer un compte SIP" + +#: ../gtk/sip_account.ui.h:2 +msgid "Your SIP identity:" +msgstr "Votre identité SIP :" + +#: ../gtk/sip_account.ui.h:3 +msgid "Looks like sip:@" +msgstr "De la forme sip:@" + +#: ../gtk/sip_account.ui.h:4 +msgid "sip:" +msgstr "sip:" + +#: ../gtk/sip_account.ui.h:5 +msgid "SIP Proxy address:" +msgstr "Adresse du proxy SIP:" + +#: ../gtk/sip_account.ui.h:6 +msgid "Looks like sip:" +msgstr "De la forme sip:" + +#: ../gtk/sip_account.ui.h:7 +msgid "Registration duration (sec):" +msgstr "Période d'enregistrement (secondes):" + +#: ../gtk/sip_account.ui.h:8 +msgid "Contact params (optional):" +msgstr "Paramètres de contact (optionnel):" + +#: ../gtk/sip_account.ui.h:9 +msgid "AVPF regular RTCP interval (sec):" +msgstr "Intervalle standard RTCP AVPF (sec) :" + +#: ../gtk/sip_account.ui.h:10 +msgid "Route (optional):" +msgstr "Route (optionnel):" + +#: ../gtk/sip_account.ui.h:11 +msgid "Transport" +msgstr "Transport" + +#: ../gtk/sip_account.ui.h:12 +msgid "Register" +msgstr "S'enregistrer" + +#: ../gtk/sip_account.ui.h:13 +msgid "Publish presence information" +msgstr "Publier la présence" + +#: ../gtk/sip_account.ui.h:14 +msgid "Enable AVPF" +msgstr "Activer AVPF" + +#: ../gtk/sip_account.ui.h:15 +msgid "Configure a SIP account" +msgstr "Configurer un compte SIP" + +#: ../gtk/tunnel_config.ui.h:1 +msgid "Configure VoIP tunnel" +msgstr "Configuer le mode tunnel" + +#: ../gtk/tunnel_config.ui.h:2 +msgid "Host" +msgstr "Hôte" + +#: ../gtk/tunnel_config.ui.h:3 +msgid "Port" +msgstr "Port" + +#: ../gtk/tunnel_config.ui.h:6 +msgid "Configure tunnel" +msgstr "Configuration du tunnel" + +#: ../gtk/tunnel_config.ui.h:9 +msgid "Configure http proxy (optional)" +msgstr "Configuration d'un proxy http (optionel)" + +#: ../gtk/waiting.ui.h:2 +msgid "Please wait" +msgstr "En attente" + +#: ../coreapi/linphonecore.c:1560 msgid "Ready" msgstr "Prêt." -#: ../coreapi/linphonecore.c:2551 +#: ../coreapi/linphonecore.c:2556 msgid "Configuring" msgstr "Configuration en cours" -#: ../coreapi/linphonecore.c:2725 -msgid "Looking for telephone number destination..." -msgstr "Recherche de la destination du numéro de téléphone..." - -#: ../coreapi/linphonecore.c:2727 -msgid "Could not resolve this number." -msgstr "La destination n'a pu être trouvée." - #. must be known at that time -#: ../coreapi/linphonecore.c:3013 +#: ../coreapi/linphonecore.c:2951 msgid "Contacting" msgstr "Appel de" -#: ../coreapi/linphonecore.c:3018 +#: ../coreapi/linphonecore.c:2956 msgid "Could not call" msgstr "Echec de l'appel" -#: ../coreapi/linphonecore.c:3169 +#: ../coreapi/linphonecore.c:3092 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:3327 +#: ../coreapi/linphonecore.c:3250 msgid "is contacting you" msgstr "vous appelle" -#: ../coreapi/linphonecore.c:3328 +#: ../coreapi/linphonecore.c:3251 msgid " and asked autoanswer." msgstr "et sollicite un décrochage automatique." -#: ../coreapi/linphonecore.c:3452 +#: ../coreapi/linphonecore.c:3377 msgid "Modifying call parameters..." msgstr "Modifications des paramètres d'appels..." -#: ../coreapi/linphonecore.c:3802 +#: ../coreapi/linphonecore.c:3769 msgid "Connected." msgstr "En ligne." -#: ../coreapi/linphonecore.c:3827 +#: ../coreapi/linphonecore.c:3794 msgid "Call aborted" msgstr "Appel abandonné" -#: ../coreapi/linphonecore.c:4024 +#: ../coreapi/linphonecore.c:3983 msgid "Could not pause the call" msgstr "La mise en attente a échoué" -#: ../coreapi/linphonecore.c:4027 +#: ../coreapi/linphonecore.c:3986 msgid "Pausing the current call..." msgstr "Mise en attente de l'appel..." -#: ../coreapi/misc.c:434 +#: ../coreapi/misc.c:440 msgid "Stun lookup in progress..." msgstr "Découverte STUN en cours" -#: ../coreapi/misc.c:615 +#: ../coreapi/misc.c:650 msgid "ICE local candidates gathering in progress..." msgstr "Collection des candidats locaux ICE en cours..." @@ -1820,166 +1884,173 @@ msgstr "En congé" msgid "Unknown status" msgstr "Status inconnu" -#: ../coreapi/proxy.c:328 +#: ../coreapi/proxy.c:292 msgid "" "The sip proxy address you entered is invalid, it must start with \"sip:\" " "followed by a hostname." msgstr "L'adresse SIP du proxy est invalide. Elle doit commencer par \"sip:\" suivie par un nom de domaine." -#: ../coreapi/proxy.c:334 +#: ../coreapi/proxy.c:298 msgid "" "The sip identity you entered is invalid.\n" "It should look like sip:username@proxydomain, such as sip:alice@example.net" msgstr "L'identité SIP que vous avez fourni est invalide.\nElle doit être de la forme sip:utilisateur@domaine, comme par exemple sip:alice@example.net" -#: ../coreapi/proxy.c:1416 +#: ../coreapi/proxy.c:927 +msgid "Looking for telephone number destination..." +msgstr "Recherche de la destination du numéro de téléphone..." + +#: ../coreapi/proxy.c:931 +msgid "Could not resolve this number." +msgstr "La destination n'a pu être trouvée." + +#: ../coreapi/proxy.c:1324 #, c-format msgid "Could not login as %s" msgstr "Echec de la connexion en tant que %s" -#: ../coreapi/callbacks.c:428 +#: ../coreapi/proxy.c:1411 +#, c-format +msgid "Refreshing on %s..." +msgstr "Rafraichissement de %s..." + +#: ../coreapi/callbacks.c:423 msgid "Remote ringing." msgstr "Sonnerie distante." -#: ../coreapi/callbacks.c:440 +#: ../coreapi/callbacks.c:435 msgid "Remote ringing..." msgstr "Sonnerie distante..." -#: ../coreapi/callbacks.c:461 +#: ../coreapi/callbacks.c:458 msgid "Early media." msgstr "Prise d'appel anticipée." -#: ../coreapi/callbacks.c:534 +#: ../coreapi/callbacks.c:488 #, c-format -msgid "Call with %s is paused." -msgstr "%s est maintenant en attente." +msgid "Call answered by %s" +msgstr "Appel répondu par %s" -#: ../coreapi/callbacks.c:547 -#, c-format -msgid "Call answered by %s - on hold." -msgstr "Appel répondu par %s - en attente" - -#: ../coreapi/callbacks.c:557 +#: ../coreapi/callbacks.c:527 msgid "Call resumed." msgstr "Appel repris." -#: ../coreapi/callbacks.c:561 -#, c-format -msgid "Call answered by %s." -msgstr "Appel répondu par %s." - -#: ../coreapi/callbacks.c:584 +#: ../coreapi/callbacks.c:582 msgid "Incompatible, check codecs or security settings..." msgstr "Incompatible, vérfiez les codecs ou les paramètres de sécurité..." -#: ../coreapi/callbacks.c:589 ../coreapi/callbacks.c:906 +#: ../coreapi/callbacks.c:587 ../coreapi/callbacks.c:923 msgid "Incompatible media parameters." msgstr "Paramètres media incompatibles." -#: ../coreapi/callbacks.c:619 +#: ../coreapi/callbacks.c:612 msgid "We have been resumed." msgstr "Appel repris." #. we are being paused -#: ../coreapi/callbacks.c:628 +#: ../coreapi/callbacks.c:620 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:666 +#: ../coreapi/callbacks.c:630 msgid "Call is updated by remote." msgstr "L'appel est modifié par la partie distante." -#: ../coreapi/callbacks.c:782 +#: ../coreapi/callbacks.c:799 msgid "Call terminated." msgstr "Appel terminé." -#: ../coreapi/callbacks.c:810 +#: ../coreapi/callbacks.c:827 msgid "User is busy." msgstr "Occupé..." -#: ../coreapi/callbacks.c:811 +#: ../coreapi/callbacks.c:828 msgid "User is temporarily unavailable." msgstr "L'usager est temporairement indisponible." #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:813 +#: ../coreapi/callbacks.c:830 msgid "User does not want to be disturbed." msgstr "L'usager ne souhaite pas être dérangé" -#: ../coreapi/callbacks.c:814 +#: ../coreapi/callbacks.c:831 msgid "Call declined." msgstr "Appel décliné." -#: ../coreapi/callbacks.c:829 +#: ../coreapi/callbacks.c:846 msgid "Request timeout." msgstr "Délai d'attente de la requête dépassé." -#: ../coreapi/callbacks.c:860 +#: ../coreapi/callbacks.c:877 msgid "Redirected" msgstr "Redirection" -#: ../coreapi/callbacks.c:915 +#: ../coreapi/callbacks.c:927 msgid "Call failed." msgstr "L'appel a échoué." -#: ../coreapi/callbacks.c:993 +#: ../coreapi/callbacks.c:1005 #, c-format msgid "Registration on %s successful." msgstr "Enregistrement sur %s effectué." -#: ../coreapi/callbacks.c:994 +#: ../coreapi/callbacks.c:1006 #, c-format msgid "Unregistration on %s done." msgstr "Désenregistrement sur %s effectué." -#: ../coreapi/callbacks.c:1012 +#: ../coreapi/callbacks.c:1024 msgid "no response timeout" msgstr "Pas de réponse" -#: ../coreapi/callbacks.c:1015 +#: ../coreapi/callbacks.c:1027 #, c-format msgid "Registration on %s failed: %s" msgstr "Echec de l'enregistrement sur %s: %s" -#: ../coreapi/callbacks.c:1022 +#: ../coreapi/callbacks.c:1034 msgid "Service unavailable, retrying" msgstr "Service indisponible, nouvelle tentative" #. if encryption is DTLS, no status to be displayed -#: ../coreapi/linphonecall.c:180 +#: ../coreapi/linphonecall.c:197 #, c-format msgid "Authentication token is %s" msgstr "Le jeton d'authentification est %s" -#: ../coreapi/linphonecall.c:1310 +#: ../coreapi/linphonecall.c:1561 +#, c-format +msgid "Call parameters could not be modified: %s." +msgstr "Les paramètres d'appel n'ont pas pu être modifiés : %s." + +#: ../coreapi/linphonecall.c:1563 msgid "Call parameters were successfully modified." msgstr "Les paramètres d'appel ont été modifiés avec succès." -#: ../coreapi/linphonecall.c:3686 +#: ../coreapi/linphonecall.c:4396 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." msgstr[0] "Vous avez manqué %i appel" msgstr[1] "Vous avez manqué %i appels" -#: ../coreapi/call_log.c:209 +#: ../coreapi/call_log.c:223 msgid "aborted" msgstr "interrompu" -#: ../coreapi/call_log.c:212 +#: ../coreapi/call_log.c:226 msgid "completed" msgstr "terminé" -#: ../coreapi/call_log.c:215 +#: ../coreapi/call_log.c:229 msgid "missed" msgstr "manqué" -#: ../coreapi/call_log.c:218 +#: ../coreapi/call_log.c:232 msgid "unknown" msgstr "inconnu" -#: ../coreapi/call_log.c:220 +#: ../coreapi/call_log.c:234 #, c-format msgid "" "%s at %s\n" @@ -1989,7 +2060,7 @@ msgid "" "Duration: %i mn %i sec\n" msgstr "%s à %s\nDe : %s\nVers : %s\nStatus : %s\nDurée : %i min %i sec\n" -#: ../coreapi/call_log.c:221 +#: ../coreapi/call_log.c:235 msgid "Outgoing call" msgstr "Appel sortant" diff --git a/po/he.po b/po/he.po index 08c49042c..7d524b57a 100644 --- a/po/he.po +++ b/po/he.po @@ -12,74 +12,83 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-04-30 10:13+0200\n" -"PO-Revision-Date: 2015-04-30 08:13+0000\n" +"POT-Creation-Date: 2015-11-10 15:16+0100\n" +"PO-Revision-Date: 2015-11-10 14:16+0000\n" "Last-Translator: Belledonne Communications \n" -"Language-Team: Hebrew (http://www.transifex.com/projects/p/linphone-gtk/language/he/)\n" +"Language-Team: Hebrew (http://www.transifex.com/belledonne-communications/linphone-gtk/language/he/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: he\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ../gtk/calllogs.c:148 ../gtk/friendlist.c:974 +#: ../gtk/calllogs.c:178 #, c-format msgid "Call %s" msgstr "התקשר אל %s" -#: ../gtk/calllogs.c:149 ../gtk/friendlist.c:975 +#: ../gtk/calllogs.c:179 #, c-format msgid "Send text to %s" msgstr "שלח טקסט אל %s" -#: ../gtk/calllogs.c:232 +#: ../gtk/calllogs.c:181 +#, c-format +msgid "Add %s to your contact list" +msgstr "" + +#: ../gtk/calllogs.c:245 ../gtk/main.ui.h:21 +msgid "Recent calls" +msgstr "שיחות אחרונות" + +#: ../gtk/calllogs.c:260 #, c-format msgid "Recent calls (%i)" msgstr "שיחות אחרונות (%i)" -#: ../gtk/calllogs.c:314 +#: ../gtk/calllogs.c:331 msgid "n/a" msgstr "לא זמין (n/a)" -#: ../gtk/calllogs.c:317 +#: ../gtk/calllogs.c:334 msgid "Aborted" msgstr "ננטשה" -#: ../gtk/calllogs.c:320 +#: ../gtk/calllogs.c:337 msgid "Missed" msgstr "הוחמצה" -#: ../gtk/calllogs.c:323 +#: ../gtk/calllogs.c:340 msgid "Declined" msgstr "נדחתה" -#: ../gtk/calllogs.c:329 +#: ../gtk/calllogs.c:346 #, c-format msgid "%i minute" msgid_plural "%i minutes" msgstr[0] "דקה %i" msgstr[1] "%i דקות" -#: ../gtk/calllogs.c:332 +#: ../gtk/calllogs.c:349 #, c-format msgid "%i second" msgid_plural "%i seconds" msgstr[0] "שניה %i" msgstr[1] "%i שניות" -#: ../gtk/calllogs.c:337 +#: ../gtk/calllogs.c:354 #, c-format msgid "" "%s\tQuality: %s\n" "%s\t%s\t" msgstr "%s\tאיכות: %s\n%s\t%s\t" -#: ../gtk/calllogs.c:341 +#: ../gtk/calllogs.c:358 #, c-format msgid "%s\t%s" msgstr "" -#: ../gtk/conference.c:38 ../gtk/main.ui.h:13 +#: ../gtk/conference.c:38 ../gtk/in_call_frame.ui.h:11 msgid "Conference" msgstr "ועידה" @@ -92,297 +101,314 @@ msgstr "אני" msgid "Couldn't find pixmap file: %s" msgstr "לא ניתן למצוא קובץ ‫pixmap: ‫%s" -#: ../gtk/main.c:137 -msgid "log to stdout some debug information while running." +#: ../gtk/chat.c:196 ../gtk/chat.c:254 +msgid "Sending..." +msgstr "" + +#: ../gtk/chat.c:213 ../gtk/chat.c:263 +msgid "Message not sent" +msgstr "" + +#: ../gtk/chat.c:472 +msgid "Copy" msgstr "" #: ../gtk/main.c:138 -msgid "path to a file to write logs into." +msgid "log to stdout some debug information while running." msgstr "" #: ../gtk/main.c:139 -msgid "Start linphone with video disabled." +msgid "display version and exit." msgstr "" #: ../gtk/main.c:140 -msgid "Start only in the system tray, do not show the main interface." +msgid "path to a file to write logs into." msgstr "" #: ../gtk/main.c:141 -msgid "address to call right now" +msgid "Start linphone with video disabled." msgstr "" #: ../gtk/main.c:142 +msgid "Start only in the system tray, do not show the main interface." +msgstr "" + +#: ../gtk/main.c:143 +msgid "address to call right now" +msgstr "" + +#: ../gtk/main.c:144 msgid "" "Specifiy a working directory (should be the base of the installation, eg: " "c:\\Program Files\\Linphone)" msgstr "" -#: ../gtk/main.c:143 +#: ../gtk/main.c:145 msgid "Configuration file" msgstr "" -#: ../gtk/main.c:144 +#: ../gtk/main.c:146 msgid "Run the audio assistant" msgstr "" -#: ../gtk/main.c:145 +#: ../gtk/main.c:147 msgid "Run self test and exit 0 if succeed" msgstr "" -#: ../gtk/main.c:1070 +#: ../gtk/main.c:1046 #, c-format msgid "" -"%s would like to add you to his contact list.\n" -"Would you allow him to see your presence status or add him to your contact list ?\n" +"%s would like to add you to his/her contact list.\n" +"Would you add him/her to your contact list and allow him/her to see your presence status?\n" "If you answer no, this person will be temporarily blacklisted." -msgstr "‫%s מעוניין להוסיפך אל רשימת אנשי הקשר שלו.\nהאם ברצונך להרשות להם לראות את מצב נוכחותך או להוסיפם אל רשימת אנשי הקשר שלך ?\nהיה ותשובתך תהיה לא, אדם זה יהיה מסומן באופן זמני ברשימה השחורה." +msgstr "" -#: ../gtk/main.c:1147 +#: ../gtk/main.c:1123 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" msgstr "אנא הזן סיסמה עבור משתמש %s\nבמתחם %s:" -#: ../gtk/main.c:1268 +#: ../gtk/main.c:1253 msgid "Call error" msgstr "שגיאת קריאה" -#: ../gtk/main.c:1271 ../coreapi/linphonecore.c:3846 +#: ../gtk/main.c:1256 ../coreapi/linphonecore.c:3813 msgid "Call ended" msgstr "שיחה הסתיימה" -#: ../gtk/main.c:1274 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1259 ../coreapi/call_log.c:235 msgid "Incoming call" msgstr "קריאה נכנסת" -#: ../gtk/main.c:1276 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1261 ../gtk/incall_view.c:580 ../gtk/in_call_frame.ui.h:2 msgid "Answer" msgstr "לענות" -#: ../gtk/main.c:1278 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1263 ../gtk/in_call_frame.ui.h:3 msgid "Decline" msgstr "לדחות" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 msgid "Call paused" msgstr "שיחה הושהתה" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 #, c-format msgid "by %s" msgstr "על ידי %s" -#: ../gtk/main.c:1354 +#: ../gtk/main.c:1339 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "‏%s רוצה להתחיל וידאו. האם אתה מסכים ?" -#: ../gtk/main.c:1509 +#: ../gtk/main.c:1505 msgid "Website link" msgstr "קישור אתר רשת" -#: ../gtk/main.c:1568 ../gtk/waiting.ui.h:1 +#: ../gtk/main.c:1564 ../gtk/waiting.ui.h:1 msgid "Linphone" msgstr "Linphone" -#: ../gtk/main.c:1569 +#: ../gtk/main.c:1565 msgid "A video internet phone" msgstr "" -#: ../gtk/main.c:1629 +#: ../gtk/main.c:1624 #, c-format msgid "%s (Default)" msgstr "‫%s (ברירת מחדל)" -#: ../gtk/main.c:1962 ../coreapi/callbacks.c:1063 +#: ../gtk/main.c:1960 ../coreapi/callbacks.c:1075 #, c-format msgid "We are transferred to %s" msgstr "אנחנו מועברים אל %s" -#: ../gtk/main.c:1972 +#: ../gtk/main.c:1970 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." msgstr "לא אותרו כרטיסי קול במחשב זה.\nלא תהיה ביכולתך לשלוח או לקבל שיחות אודיו." -#: ../gtk/main.c:2117 +#: ../gtk/main.c:2129 msgid "A free SIP video-phone" msgstr "וידאופון SIP חופשי" -#: ../gtk/main.c:2221 +#: ../gtk/main.c:2242 #, c-format msgid "Hello\n" msgstr "" -#: ../gtk/friendlist.c:505 +#: ../gtk/friendlist.c:461 msgid "Add to addressbook" msgstr "הוסף אל ספר כתובות" -#: ../gtk/friendlist.c:691 -msgid "Presence status" -msgstr "מצב נוכחות" - -#: ../gtk/friendlist.c:709 ../gtk/propertybox.c:569 ../gtk/contact.ui.h:1 -msgid "Name" -msgstr "שם" - -#: ../gtk/friendlist.c:721 -msgid "Call" -msgstr "קריאה" - -#: ../gtk/friendlist.c:726 -msgid "Chat" -msgstr "שיחה" - -#: ../gtk/friendlist.c:756 +#: ../gtk/friendlist.c:627 #, c-format msgid "Search in %s directory" msgstr "חיפוש במדור %s" -#: ../gtk/friendlist.c:924 +#: ../gtk/friendlist.c:772 msgid "Invalid sip contact !" msgstr "כתובת sip לא תקפה !" -#: ../gtk/friendlist.c:976 +#: ../gtk/friendlist.c:820 +#, c-format +msgid "Add a new contact" +msgstr "" + +#: ../gtk/friendlist.c:823 #, c-format msgid "Edit contact '%s'" msgstr "ערוך איש קשר '%s'" -#: ../gtk/friendlist.c:977 +#: ../gtk/friendlist.c:824 #, c-format msgid "Delete contact '%s'" msgstr "מחק איש קשר '%s'" -#: ../gtk/friendlist.c:978 +#: ../gtk/friendlist.c:825 #, c-format msgid "Delete chat history of '%s'" msgstr "מחק היסטוריית שיחה של '%s'" -#: ../gtk/friendlist.c:1029 +#: ../gtk/friendlist.c:862 #, c-format msgid "Add new contact from %s directory" msgstr "הוסף איש קשר חדש מן מדור %s" -#: ../gtk/propertybox.c:575 +#: ../gtk/propertybox.c:592 ../gtk/contact.ui.h:1 +msgid "Name" +msgstr "שם" + +#: ../gtk/propertybox.c:598 msgid "Rate (Hz)" msgstr "שיעור (הרץ)" -#: ../gtk/propertybox.c:581 +#: ../gtk/propertybox.c:604 msgid "Status" msgstr "מצב" -#: ../gtk/propertybox.c:587 +#: ../gtk/propertybox.c:617 msgid "IP Bitrate (kbit/s)" msgstr "" -#: ../gtk/propertybox.c:596 +#: ../gtk/propertybox.c:628 msgid "Parameters" msgstr "פרמטרים" -#: ../gtk/propertybox.c:639 ../gtk/propertybox.c:782 +#: ../gtk/propertybox.c:670 ../gtk/propertybox.c:824 msgid "Enabled" msgstr "מופעל" -#: ../gtk/propertybox.c:641 ../gtk/propertybox.c:782 ../gtk/parameters.ui.h:20 +#: ../gtk/propertybox.c:672 ../gtk/propertybox.c:824 ../gtk/parameters.ui.h:60 msgid "Disabled" msgstr "לא מופעל" -#: ../gtk/propertybox.c:828 +#: ../gtk/propertybox.c:902 msgid "Account" msgstr "חשבון" -#: ../gtk/propertybox.c:1091 +#: ../gtk/propertybox.c:1170 msgid "English" msgstr "English" -#: ../gtk/propertybox.c:1092 +#: ../gtk/propertybox.c:1171 msgid "French" msgstr "Français" -#: ../gtk/propertybox.c:1093 +#: ../gtk/propertybox.c:1172 msgid "Swedish" msgstr "Svenska" -#: ../gtk/propertybox.c:1094 +#: ../gtk/propertybox.c:1173 msgid "Italian" msgstr "Italiano" -#: ../gtk/propertybox.c:1095 +#: ../gtk/propertybox.c:1174 msgid "Spanish" msgstr "Español" -#: ../gtk/propertybox.c:1096 +#: ../gtk/propertybox.c:1175 msgid "Brazilian Portugese" msgstr "português brasileiro" -#: ../gtk/propertybox.c:1097 +#: ../gtk/propertybox.c:1176 msgid "Polish" msgstr "Polski" -#: ../gtk/propertybox.c:1098 +#: ../gtk/propertybox.c:1177 msgid "German" msgstr "Deutsch" -#: ../gtk/propertybox.c:1099 +#: ../gtk/propertybox.c:1178 msgid "Russian" msgstr "Русский" -#: ../gtk/propertybox.c:1100 +#: ../gtk/propertybox.c:1179 msgid "Japanese" msgstr "日本語" -#: ../gtk/propertybox.c:1101 +#: ../gtk/propertybox.c:1180 msgid "Dutch" msgstr "Nederlands" -#: ../gtk/propertybox.c:1102 +#: ../gtk/propertybox.c:1181 msgid "Hungarian" msgstr "Magyar" -#: ../gtk/propertybox.c:1103 +#: ../gtk/propertybox.c:1182 msgid "Czech" msgstr "Česky" -#: ../gtk/propertybox.c:1104 +#: ../gtk/propertybox.c:1183 msgid "Chinese" msgstr "中文" -#: ../gtk/propertybox.c:1105 +#: ../gtk/propertybox.c:1184 msgid "Traditional Chinese" msgstr "繁體字" -#: ../gtk/propertybox.c:1106 +#: ../gtk/propertybox.c:1185 msgid "Norwegian" msgstr "norsk" -#: ../gtk/propertybox.c:1107 +#: ../gtk/propertybox.c:1186 msgid "Hebrew" msgstr "עברית" -#: ../gtk/propertybox.c:1108 +#: ../gtk/propertybox.c:1187 msgid "Serbian" msgstr "српски srpski" -#: ../gtk/propertybox.c:1175 +#: ../gtk/propertybox.c:1188 +msgid "Arabic" +msgstr "" + +#: ../gtk/propertybox.c:1189 +msgid "Turkish" +msgstr "" + +#: ../gtk/propertybox.c:1246 msgid "" "You need to restart linphone for the new language selection to take effect." msgstr "עליך לאתחל את לינפון כדי שהשפה החדשה תיכנס לתוקף." -#: ../gtk/propertybox.c:1255 +#: ../gtk/propertybox.c:1326 msgid "None" msgstr "ללא" -#: ../gtk/propertybox.c:1259 +#: ../gtk/propertybox.c:1330 msgid "SRTP" msgstr "" -#: ../gtk/propertybox.c:1265 +#: ../gtk/propertybox.c:1336 msgid "DTLS" msgstr "" -#: ../gtk/propertybox.c:1272 +#: ../gtk/propertybox.c:1343 msgid "ZRTP" msgstr "" @@ -424,324 +450,195 @@ msgid_plural "Found %i contacts" msgstr[0] "נמצא איש קשר %i" msgstr[1] "נמצאו %i אנשי קשר" -#: ../gtk/setupwizard.c:32 -msgid "" -"Welcome!\n" -"This assistant will help you to use a SIP account for your calls." -msgstr "" - -#: ../gtk/setupwizard.c:41 -msgid "Create an account on linphone.org" -msgstr "צור חשבון אצל linphone.org" - -#: ../gtk/setupwizard.c:42 -msgid "I have already a linphone.org account and I just want to use it" -msgstr "כבר קיים חשבון linphone.org ברשותי וברצוני לעשות בו שימוש" - -#: ../gtk/setupwizard.c:43 -msgid "I have already a sip account and I just want to use it" -msgstr "כבר קיים חשבון sip ברשותי וברצוני לעשות בו שימוש" - -#: ../gtk/setupwizard.c:44 -msgid "I want to specify a remote configuration URI" -msgstr "" - -#: ../gtk/setupwizard.c:87 -msgid "Enter your linphone.org username" -msgstr "הזן את שם משתמשך אצל linphone.org" - -#: ../gtk/setupwizard.c:100 ../gtk/parameters.ui.h:85 ../gtk/ldap.ui.h:4 -msgid "Username:" -msgstr "שם משתמש:" - -#: ../gtk/setupwizard.c:102 ../gtk/password.ui.h:4 ../gtk/ldap.ui.h:5 -msgid "Password:" -msgstr "סיסמה:" - -#: ../gtk/setupwizard.c:122 -msgid "Enter your account informations" -msgstr "הזן את מידע חשבונך" - -#: ../gtk/setupwizard.c:138 -msgid "Username*" -msgstr "שם משתמש*" - -#: ../gtk/setupwizard.c:139 -msgid "Password*" -msgstr "סיסמה*" - -#: ../gtk/setupwizard.c:142 -msgid "Domain*" -msgstr "מתחם*" - -#: ../gtk/setupwizard.c:143 -msgid "Proxy" -msgstr "פרוקסי" - -#: ../gtk/setupwizard.c:322 -msgid "(*) Required fields" -msgstr "(*) שדות חובה" - -#: ../gtk/setupwizard.c:323 -msgid "Username: (*)" -msgstr "שם משתמש: (*)" - -#: ../gtk/setupwizard.c:325 -msgid "Password: (*)" -msgstr "סיסמה: (*)" - -#: ../gtk/setupwizard.c:327 -msgid "Email: (*)" -msgstr "דוא״ל: (*)" - -#: ../gtk/setupwizard.c:329 -msgid "Confirm your password: (*)" -msgstr "אימות סיסמתך: (*)" - -#: ../gtk/setupwizard.c:343 -msgid "Keep me informed with linphone updates" -msgstr "" - -#: ../gtk/setupwizard.c:399 -msgid "" -"Error, account not validated, username already used or server unreachable.\n" -"Please go back and try again." -msgstr "שגיאה, חשבון לא אומת, שם משתמש כבר בשימוש או שרת לא ניתן להשגה.\nנא לחזור ולנסות שוב." - -#: ../gtk/setupwizard.c:410 -msgid "Thank you. Your account is now configured and ready for use." -msgstr "תודה לך. חשבונך מוגדר ומוכן לשימוש כעת." - -#: ../gtk/setupwizard.c:418 -msgid "" -"Please validate your account by clicking on the link we just sent you by email.\n" -"Then come back here and press Next button." -msgstr "נא לאמת את חשבונך באמצעות הקלקה על הקישור ששלחנו לך עתה באמצעות דוא״ל.\nאחרי כן נא לחזור לכאן וללחוץ על הלחצן 'קדימה'." - -#: ../gtk/setupwizard.c:609 -msgid "SIP account configuration assistant" -msgstr "" - -#: ../gtk/setupwizard.c:629 -msgid "Welcome to the account setup assistant" -msgstr "ברוך בואך אל אשף הגדרת החשבון" - -#: ../gtk/setupwizard.c:634 -msgid "Account setup assistant" -msgstr "אשף הגדרת חשבון" - -#: ../gtk/setupwizard.c:640 -msgid "Configure your account (step 1/1)" -msgstr "הגדרת חשבונך (צעד 1/1)" - -#: ../gtk/setupwizard.c:645 -msgid "Enter your sip username (step 1/1)" -msgstr "הזנת שם משתמש sip (צעד 1/1)" - -#: ../gtk/setupwizard.c:649 -msgid "Enter account information (step 1/2)" -msgstr "הזנת מידע חשבון (צעד 1/2)" - -#: ../gtk/setupwizard.c:658 -msgid "Validation (step 2/2)" -msgstr "אימות (צעד 2/2)" - -#: ../gtk/setupwizard.c:663 -msgid "Error" -msgstr "שגיאה" - -#: ../gtk/setupwizard.c:667 ../gtk/audio_assistant.c:534 -msgid "Terminating" -msgstr "מסיים כעת" - -#: ../gtk/incall_view.c:70 ../gtk/incall_view.c:94 +#: ../gtk/incall_view.c:67 ../gtk/incall_view.c:87 #, c-format msgid "Call #%i" msgstr "שיחה מס׳ %i" -#: ../gtk/incall_view.c:155 +#: ../gtk/incall_view.c:145 #, c-format msgid "Transfer to call #%i with %s" msgstr "העברה אל שיחה מס׳ %i עם %s" -#: ../gtk/incall_view.c:211 ../gtk/incall_view.c:214 +#: ../gtk/incall_view.c:202 ../gtk/incall_view.c:205 msgid "Not used" msgstr "לא בשימוש" -#: ../gtk/incall_view.c:221 +#: ../gtk/incall_view.c:212 msgid "ICE not activated" msgstr "‏ICE לא מופעלת" -#: ../gtk/incall_view.c:223 +#: ../gtk/incall_view.c:214 msgid "ICE failed" msgstr "‏ICE נכשלה" -#: ../gtk/incall_view.c:225 +#: ../gtk/incall_view.c:216 msgid "ICE in progress" msgstr "‏ICE מצויה כעת בעיצומה" -#: ../gtk/incall_view.c:227 +#: ../gtk/incall_view.c:218 msgid "Going through one or more NATs" msgstr "עובר דרך NAT אחד או יותר" -#: ../gtk/incall_view.c:229 +#: ../gtk/incall_view.c:220 msgid "Direct" msgstr "ישיר" -#: ../gtk/incall_view.c:231 +#: ../gtk/incall_view.c:222 msgid "Through a relay server" msgstr "דרך שרת ממסר" -#: ../gtk/incall_view.c:239 +#: ../gtk/incall_view.c:230 msgid "uPnP not activated" msgstr "‏uPnP לא מופעלת" -#: ../gtk/incall_view.c:241 +#: ../gtk/incall_view.c:232 msgid "uPnP in progress" msgstr "‏uPnP מצויה כעת בעיצומה" -#: ../gtk/incall_view.c:243 +#: ../gtk/incall_view.c:234 msgid "uPnp not available" msgstr "‏uPnp לא זמינה" -#: ../gtk/incall_view.c:245 +#: ../gtk/incall_view.c:236 msgid "uPnP is running" msgstr "‏uPnP מורצת כעת" -#: ../gtk/incall_view.c:247 +#: ../gtk/incall_view.c:238 msgid "uPnP failed" msgstr "‏uPnP נכשלה" -#: ../gtk/incall_view.c:257 ../gtk/incall_view.c:258 +#: ../gtk/incall_view.c:248 ../gtk/incall_view.c:249 msgid "Direct or through server" msgstr "ישיר או דרך שרת" -#: ../gtk/incall_view.c:267 ../gtk/incall_view.c:279 +#: ../gtk/incall_view.c:258 ../gtk/incall_view.c:270 #, c-format msgid "" "download: %f\n" "upload: %f (kbit/s)" msgstr "הורדה: %f\nהעלאה: %f (קי״ב/שנ׳)" -#: ../gtk/incall_view.c:272 ../gtk/incall_view.c:274 +#: ../gtk/incall_view.c:263 ../gtk/incall_view.c:265 #, c-format msgid "%ix%i @ %f fps" msgstr "" -#: ../gtk/incall_view.c:304 +#: ../gtk/incall_view.c:295 #, c-format msgid "%.3f seconds" msgstr "%.3f שניות" -#: ../gtk/incall_view.c:407 ../gtk/main.ui.h:12 ../gtk/videowindow.c:235 +#: ../gtk/incall_view.c:453 ../gtk/in_call_frame.ui.h:10 +#: ../gtk/videowindow.c:236 msgid "Hang up" msgstr "נתק" -#: ../gtk/incall_view.c:511 +#: ../gtk/incall_view.c:559 msgid "Calling..." msgstr "מתקשר כעת..." -#: ../gtk/incall_view.c:514 ../gtk/incall_view.c:733 -msgid "00::00::00" -msgstr "‭00::00::00" +#: ../gtk/incall_view.c:562 ../gtk/incall_view.c:792 +msgid "00:00:00" +msgstr "" -#: ../gtk/incall_view.c:525 +#: ../gtk/incall_view.c:573 msgid "Incoming call" msgstr "קריאה נכנסת" -#: ../gtk/incall_view.c:562 +#: ../gtk/incall_view.c:610 msgid "good" msgstr "טובה" -#: ../gtk/incall_view.c:564 +#: ../gtk/incall_view.c:612 msgid "average" msgstr "ממוצעת" -#: ../gtk/incall_view.c:566 +#: ../gtk/incall_view.c:614 msgid "poor" msgstr "דלה" -#: ../gtk/incall_view.c:568 +#: ../gtk/incall_view.c:616 msgid "very poor" msgstr "דלה מאוד" -#: ../gtk/incall_view.c:570 +#: ../gtk/incall_view.c:618 msgid "too bad" msgstr "גרועה מדי" -#: ../gtk/incall_view.c:571 ../gtk/incall_view.c:587 +#: ../gtk/incall_view.c:619 ../gtk/incall_view.c:635 msgid "unavailable" msgstr "לא זמינה" -#: ../gtk/incall_view.c:679 +#: ../gtk/incall_view.c:731 msgid "Secured by SRTP" msgstr "מאובטחת על ידי SRTP" -#: ../gtk/incall_view.c:685 +#: ../gtk/incall_view.c:737 msgid "Secured by DTLS" msgstr "" -#: ../gtk/incall_view.c:691 +#: ../gtk/incall_view.c:743 #, c-format msgid "Secured by ZRTP - [auth token: %s]" msgstr "מאובטחת על ידי ZRTP - [אות אימות: %s]" -#: ../gtk/incall_view.c:697 +#: ../gtk/incall_view.c:747 msgid "Set unverified" msgstr "הגדר כלא מאומתת" -#: ../gtk/incall_view.c:697 ../gtk/main.ui.h:4 +#: ../gtk/incall_view.c:747 msgid "Set verified" msgstr "הגדר כמאומתת" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In conference" msgstr "בשיחת ועידה" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In call" msgstr "בשיחה כעת" -#: ../gtk/incall_view.c:764 +#: ../gtk/incall_view.c:824 msgid "Paused call" msgstr "שיחה מושהית" -#: ../gtk/incall_view.c:800 +#: ../gtk/incall_view.c:861 msgid "Call ended." msgstr "שיחה הסתיימה." -#: ../gtk/incall_view.c:831 +#: ../gtk/incall_view.c:892 msgid "Transfer in progress" msgstr "העברה מצויה כעת בעיצומה" -#: ../gtk/incall_view.c:834 +#: ../gtk/incall_view.c:895 msgid "Transfer done." msgstr "העברה הסתיימה." -#: ../gtk/incall_view.c:837 +#: ../gtk/incall_view.c:898 msgid "Transfer failed." msgstr "העברה נכשלה." -#: ../gtk/incall_view.c:881 +#: ../gtk/incall_view.c:929 msgid "Resume" msgstr "חזור" -#: ../gtk/incall_view.c:888 ../gtk/main.ui.h:9 +#: ../gtk/incall_view.c:929 ../gtk/in_call_frame.ui.h:7 msgid "Pause" msgstr "השהה" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 #, c-format msgid "" "Recording into\n" "%s %s" msgstr "מקליט אל תוך\n%s %s" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 msgid "(Paused)" msgstr "(מושהה)" -#: ../gtk/loginframe.c:87 +#: ../gtk/loginframe.c:75 #, c-format msgid "Please enter login information for %s" msgstr "נא להזין מידע התחברות עבור %s" @@ -756,263 +653,108 @@ msgstr "" msgid "Downloading of remote configuration from %s failed." msgstr "" -#: ../gtk/audio_assistant.c:98 +#: ../gtk/audio_assistant.c:103 msgid "No voice detected" msgstr "" -#: ../gtk/audio_assistant.c:99 +#: ../gtk/audio_assistant.c:104 msgid "Too low" msgstr "נמוך מדי" -#: ../gtk/audio_assistant.c:100 +#: ../gtk/audio_assistant.c:105 msgid "Good" msgstr "טוב" -#: ../gtk/audio_assistant.c:101 +#: ../gtk/audio_assistant.c:106 msgid "Too loud" msgstr "חזק מדי" -#: ../gtk/audio_assistant.c:183 +#: ../gtk/audio_assistant.c:188 msgid "Did you hear three beeps ?" msgstr "" -#: ../gtk/audio_assistant.c:292 ../gtk/audio_assistant.c:297 +#: ../gtk/audio_assistant.c:299 ../gtk/audio_assistant.c:304 msgid "Sound preferences not found " msgstr "" -#: ../gtk/audio_assistant.c:306 +#: ../gtk/audio_assistant.c:313 msgid "Cannot launch system sound control " msgstr "" -#: ../gtk/audio_assistant.c:318 +#: ../gtk/audio_assistant.c:325 msgid "" "Welcome!\n" "This assistant will help you to configure audio settings for Linphone" msgstr "" -#: ../gtk/audio_assistant.c:328 +#: ../gtk/audio_assistant.c:335 msgid "Capture device" msgstr "התקן לכידה" -#: ../gtk/audio_assistant.c:329 +#: ../gtk/audio_assistant.c:336 msgid "Recorded volume" msgstr "" -#: ../gtk/audio_assistant.c:333 +#: ../gtk/audio_assistant.c:340 msgid "No voice" msgstr "אין קול" -#: ../gtk/audio_assistant.c:334 ../gtk/audio_assistant.c:373 +#: ../gtk/audio_assistant.c:341 ../gtk/audio_assistant.c:380 msgid "System sound preferences" msgstr "" -#: ../gtk/audio_assistant.c:369 +#: ../gtk/audio_assistant.c:376 msgid "Playback device" msgstr "התקן השמעה" -#: ../gtk/audio_assistant.c:370 +#: ../gtk/audio_assistant.c:377 msgid "Play three beeps" msgstr "נגן שלושה צפצופים" -#: ../gtk/audio_assistant.c:403 +#: ../gtk/audio_assistant.c:410 msgid "Press the record button and say some words" msgstr "" -#: ../gtk/audio_assistant.c:404 +#: ../gtk/audio_assistant.c:411 msgid "Listen to your record voice" msgstr "" -#: ../gtk/audio_assistant.c:405 +#: ../gtk/audio_assistant.c:412 ../gtk/conf_frame.ui.h:2 +#: ../gtk/in_call_frame.ui.h:4 msgid "Record" msgstr "" -#: ../gtk/audio_assistant.c:406 +#: ../gtk/audio_assistant.c:413 msgid "Play" msgstr "" -#: ../gtk/audio_assistant.c:433 +#: ../gtk/audio_assistant.c:440 msgid "Let's start Linphone now" msgstr "הבא נתחיל את Linphone עכשיו" -#: ../gtk/audio_assistant.c:503 +#: ../gtk/audio_assistant.c:510 msgid "Audio Assistant" msgstr "" -#: ../gtk/audio_assistant.c:513 ../gtk/main.ui.h:32 +#: ../gtk/audio_assistant.c:520 ../gtk/main.ui.h:13 msgid "Audio assistant" msgstr "" -#: ../gtk/audio_assistant.c:518 +#: ../gtk/audio_assistant.c:525 msgid "Mic Gain calibration" msgstr "" -#: ../gtk/audio_assistant.c:524 +#: ../gtk/audio_assistant.c:531 msgid "Speaker volume calibration" msgstr "" -#: ../gtk/audio_assistant.c:529 +#: ../gtk/audio_assistant.c:536 msgid "Record and Play" msgstr "" -#: ../gtk/main.ui.h:1 -msgid "Callee name" -msgstr "שם מקבל" - -#: ../gtk/main.ui.h:2 -msgid "Send" -msgstr "שלח" - -#: ../gtk/main.ui.h:3 -msgid "End conference" -msgstr "סיים ועידה" - -#: ../gtk/main.ui.h:7 -msgid "Record this call to an audio file" -msgstr "הקלט את שיחה זו אל קובץ אודיו" - -#: ../gtk/main.ui.h:8 -msgid "Video" -msgstr "וידאו" - -#: ../gtk/main.ui.h:10 -msgid "Mute" -msgstr "השתק" - -#: ../gtk/main.ui.h:11 -msgid "Transfer" -msgstr "העבר" - -#: ../gtk/main.ui.h:14 -msgid "In call" -msgstr "בשיחה כעת" - -#: ../gtk/main.ui.h:15 -msgid "Duration" -msgstr "משך זמן" - -#: ../gtk/main.ui.h:16 -msgid "Call quality rating" -msgstr "אומדן איכות שיחה" - -#: ../gtk/main.ui.h:17 -msgid "All users" -msgstr "כל המשתמשים" - -#: ../gtk/main.ui.h:18 -msgid "Online users" -msgstr "משתמשים מקוונים" - -#: ../gtk/main.ui.h:19 -msgid "ADSL" -msgstr "‫ADSL" - -#: ../gtk/main.ui.h:20 -msgid "Fiber Channel" -msgstr "ערוץ סיב" - -#: ../gtk/main.ui.h:21 -msgid "Default" -msgstr "ברירת מחדל" - -#: ../gtk/main.ui.h:22 -msgid "Delete" -msgstr "מחק" - -#: ../gtk/main.ui.h:23 -msgid "_Options" -msgstr "_אפשרויות" - -#: ../gtk/main.ui.h:24 -msgid "Set configuration URI" -msgstr "" - -#: ../gtk/main.ui.h:25 -msgid "Always start video" -msgstr "התחל תמיד וידאו" - -#: ../gtk/main.ui.h:26 -msgid "Enable self-view" -msgstr "אפשר ראות-עצמית" - -#: ../gtk/main.ui.h:27 -msgid "_Help" -msgstr "_עזרה" - -#: ../gtk/main.ui.h:28 -msgid "Show debug window" -msgstr "הצג חלון ניפוי שגיאות" - -#: ../gtk/main.ui.h:29 -msgid "_Homepage" -msgstr "_עמוד הבית" - -#: ../gtk/main.ui.h:30 -msgid "Check _Updates" -msgstr "בדיקת _עדכונים" - -#: ../gtk/main.ui.h:31 -msgid "Account assistant" -msgstr "אשף חשבון" - -#: ../gtk/main.ui.h:33 -msgid "SIP address or phone number:" -msgstr "כתובת SIP או מספר טלפון" - -#: ../gtk/main.ui.h:34 -msgid "Initiate a new call" -msgstr "התחל שיחה חדשה" - -#: ../gtk/main.ui.h:35 -msgid "Contacts" -msgstr "אנשי קשר" - -#: ../gtk/main.ui.h:36 -msgid "Search" -msgstr "חיפוש" - -#: ../gtk/main.ui.h:37 -msgid "Add contacts from directory" -msgstr "הוסף אנשי קשר מן מדור" - -#: ../gtk/main.ui.h:38 -msgid "Add contact" -msgstr "הוסף איש קשר" - -#: ../gtk/main.ui.h:39 -msgid "Recent calls" -msgstr "שיחות אחרונות" - -#: ../gtk/main.ui.h:40 -msgid "My current identity:" -msgstr "זהותי הנוכחית:" - -#: ../gtk/main.ui.h:41 ../gtk/tunnel_config.ui.h:7 -msgid "Username" -msgstr "שם משתמש" - -#: ../gtk/main.ui.h:42 ../gtk/tunnel_config.ui.h:8 -msgid "Password" -msgstr "סיסמה" - -#: ../gtk/main.ui.h:43 -msgid "Internet connection:" -msgstr "חיבור אינטרנט:" - -#: ../gtk/main.ui.h:44 -msgid "Automatically log me in" -msgstr "חבר אותי אוטומטית" - -#: ../gtk/main.ui.h:45 ../gtk/password.ui.h:3 -msgid "UserID" -msgstr "מזהה משתמש" - -#: ../gtk/main.ui.h:46 -msgid "Login information" -msgstr "מידע התחברות" - -#: ../gtk/main.ui.h:47 -msgid "Welcome!" -msgstr "" +#: ../gtk/audio_assistant.c:541 ../gtk/setup_wizard.ui.h:38 +msgid "Terminating" +msgstr "מסיים כעת" #: ../gtk/about.ui.h:1 msgid "About Linphone" @@ -1042,456 +784,6 @@ msgid "" "he: Eli Zaretskii \n" msgstr "" -#: ../gtk/contact.ui.h:2 -msgid "SIP Address" -msgstr "כתובת ‫SIP" - -#: ../gtk/contact.ui.h:3 -msgid "Show this contact presence status" -msgstr "הצג את מצב נוכחותו של איש קשר זה" - -#: ../gtk/contact.ui.h:4 -msgid "Allow this contact to see my presence status" -msgstr "הרשה לאיש קשר זה לראות את מצב הנוכחות שלי" - -#: ../gtk/contact.ui.h:5 -msgid "Contact information" -msgstr "מידע איש קשר" - -#: ../gtk/log.ui.h:1 -msgid "Linphone debug window" -msgstr "חלון ניפוי שגיאות ‫Linphone" - -#: ../gtk/log.ui.h:2 -msgid "Scroll to end" -msgstr "גלול אוטומטית לסוף" - -#: ../gtk/password.ui.h:1 -msgid "Linphone - Authentication required" -msgstr "‫Linphone - נדרש אימות" - -#: ../gtk/password.ui.h:2 -msgid "Please enter the domain password" -msgstr "נא להזין את סיסמת המתחם" - -#: ../gtk/call_logs.ui.h:1 -msgid "Call history" -msgstr "היסטוריית שיחות" - -#: ../gtk/call_logs.ui.h:2 -msgid "Clear all" -msgstr "טיהור מוחלט" - -#: ../gtk/call_logs.ui.h:3 -msgid "Call back" -msgstr "חיוג חוזר" - -#: ../gtk/sip_account.ui.h:1 -msgid "Linphone - Configure a SIP account" -msgstr "‫Linphone - הגדרת חשבון ‫SIP" - -#: ../gtk/sip_account.ui.h:2 -msgid "Your SIP identity:" -msgstr "זהות ה־SIP שלך:" - -#: ../gtk/sip_account.ui.h:3 -msgid "Looks like sip:@" -msgstr "נראה כמו ‪sip:@" - -#: ../gtk/sip_account.ui.h:4 -msgid "sip:" -msgstr "" - -#: ../gtk/sip_account.ui.h:5 -msgid "SIP Proxy address:" -msgstr "כתובת SIP Proxy:" - -#: ../gtk/sip_account.ui.h:6 -msgid "Looks like sip:" -msgstr "נראה כמו ‪sip:" - -#: ../gtk/sip_account.ui.h:7 -msgid "Registration duration (sec):" -msgstr "משך רישום (בשניות):" - -#: ../gtk/sip_account.ui.h:8 -msgid "Contact params (optional):" -msgstr "" - -#: ../gtk/sip_account.ui.h:9 -msgid "AVPF regular RTCP interval (sec):" -msgstr "" - -#: ../gtk/sip_account.ui.h:10 -msgid "Route (optional):" -msgstr "ניתוב (רשות):" - -#: ../gtk/sip_account.ui.h:11 -msgid "Transport" -msgstr "טרנספורט" - -#: ../gtk/sip_account.ui.h:12 -msgid "Register" -msgstr "רישום" - -#: ../gtk/sip_account.ui.h:13 -msgid "Publish presence information" -msgstr "פרסם מידע נוכחות" - -#: ../gtk/sip_account.ui.h:14 -msgid "Enable AVPF" -msgstr "אפשר AVPF" - -#: ../gtk/sip_account.ui.h:15 -msgid "Configure a SIP account" -msgstr "הגדרת חשבון ‫SIP" - -#: ../gtk/parameters.ui.h:1 -msgid "anonymous" -msgstr "" - -#: ../gtk/parameters.ui.h:2 -msgid "GSSAPI" -msgstr "" - -#: ../gtk/parameters.ui.h:3 -msgid "SASL" -msgstr "" - -#: ../gtk/parameters.ui.h:4 -msgid "default soundcard" -msgstr "כרטיס קול משתמט" - -#: ../gtk/parameters.ui.h:5 -msgid "a sound card" -msgstr "כרטיס קול" - -#: ../gtk/parameters.ui.h:6 -msgid "default camera" -msgstr "מצלמה משתמטת" - -#: ../gtk/parameters.ui.h:7 -msgid "CIF" -msgstr "" - -#: ../gtk/parameters.ui.h:8 -msgid "Audio codecs" -msgstr "קודקים של אודיו" - -#: ../gtk/parameters.ui.h:9 -msgid "Video codecs" -msgstr "קודקים של וידאו" - -#: ../gtk/parameters.ui.h:10 -msgid "C" -msgstr "" - -#: ../gtk/parameters.ui.h:11 -msgid "SIP (UDP)" -msgstr "‏SIP ‏(UDP)" - -#: ../gtk/parameters.ui.h:12 -msgid "SIP (TCP)" -msgstr "‏SIP ‏(TCP)" - -#: ../gtk/parameters.ui.h:13 -msgid "SIP (TLS)" -msgstr "‏SIP ‏(TLS)" - -#: ../gtk/parameters.ui.h:14 -msgid "Settings" -msgstr "הגדרות" - -#: ../gtk/parameters.ui.h:15 -msgid "Set Maximum Transmission Unit:" -msgstr "הגדר יחידת תמסורת מרבית:" - -#: ../gtk/parameters.ui.h:16 -msgid "Send DTMFs as SIP info" -msgstr "שלח טזמ״תים (DTMFs) כמידע SIP" - -#: ../gtk/parameters.ui.h:17 -msgid "Allow IPv6" -msgstr "" - -#: ../gtk/parameters.ui.h:18 -msgid "Transport" -msgstr "טרנספורט" - -#: ../gtk/parameters.ui.h:19 -msgid "SIP/UDP port" -msgstr "" - -#: ../gtk/parameters.ui.h:21 -msgid "Random" -msgstr "" - -#: ../gtk/parameters.ui.h:22 -msgid "SIP/TCP port" -msgstr "" - -#: ../gtk/parameters.ui.h:23 -msgid "Audio RTP/UDP:" -msgstr "אודיו RTP/UDP:" - -#: ../gtk/parameters.ui.h:24 -msgid "Fixed" -msgstr "מקובע" - -#: ../gtk/parameters.ui.h:25 -msgid "Video RTP/UDP:" -msgstr "וידאו RTP/UDP:" - -#: ../gtk/parameters.ui.h:26 -msgid "Media encryption type" -msgstr "סוג הצפנת מדיה" - -#: ../gtk/parameters.ui.h:27 -msgid "Media encryption is mandatory" -msgstr "הצפנת מדיה הינה מנדטורית" - -#: ../gtk/parameters.ui.h:28 -msgid "Tunnel" -msgstr "מינהור" - -#: ../gtk/parameters.ui.h:29 -msgid "DSCP fields" -msgstr "שדות DSCP" - -#: ../gtk/parameters.ui.h:30 -msgid "Network protocol and ports" -msgstr "פרוטוקולי רשת תקשורת ופורטים" - -#: ../gtk/parameters.ui.h:31 -msgid "Direct connection to the Internet" -msgstr "חיבור ישיר אל האינטרנט" - -#: ../gtk/parameters.ui.h:32 -msgid "Behind NAT / Firewall (specify gateway IP )" -msgstr "" - -#: ../gtk/parameters.ui.h:33 -msgid "Behind NAT / Firewall (use STUN to resolve)" -msgstr "מאחורי NAT / חומת אש (בעזרת STUN לפתירה)" - -#: ../gtk/parameters.ui.h:34 -msgid "Behind NAT / Firewall (use ICE)" -msgstr "מאחורי NAT / חומת אש (בעזרת ICE)" - -#: ../gtk/parameters.ui.h:35 -msgid "Behind NAT / Firewall (use uPnP)" -msgstr "מאחורי NAT / חומת אש (בעזרת uPnP)" - -#: ../gtk/parameters.ui.h:36 -msgid "Public IP address:" -msgstr "כתובת IP פומבית:" - -#: ../gtk/parameters.ui.h:37 -msgid "Stun server:" -msgstr "שרת STUN:" - -#: ../gtk/parameters.ui.h:38 -msgid "NAT and Firewall" -msgstr "‫NAT וחומת אש" - -#: ../gtk/parameters.ui.h:39 -msgid "Network settings" -msgstr "הגדרות רשת תקשורת" - -#: ../gtk/parameters.ui.h:40 -msgid "Ring sound:" -msgstr "צליל צלצול:" - -#: ../gtk/parameters.ui.h:41 -msgid "ALSA special device (optional):" -msgstr "התקן ALSA מיוחד (רשות):" - -#: ../gtk/parameters.ui.h:42 -msgid "Capture device:" -msgstr "התקן לכידה:" - -#: ../gtk/parameters.ui.h:43 -msgid "Ring device:" -msgstr "התקן צלצול:" - -#: ../gtk/parameters.ui.h:44 -msgid "Playback device:" -msgstr "התקן פס קול:" - -#: ../gtk/parameters.ui.h:45 -msgid "Enable echo cancellation" -msgstr "אפשר ביטול הד" - -#: ../gtk/parameters.ui.h:46 -msgid "Audio" -msgstr "אודיו" - -#: ../gtk/parameters.ui.h:47 -msgid "Video input device:" -msgstr "התקן קלט וידאו:" - -#: ../gtk/parameters.ui.h:48 -msgid "Prefered video resolution:" -msgstr "רזולוציית וידאו מועדפת:" - -#: ../gtk/parameters.ui.h:49 -msgid "Video output method:" -msgstr "" - -#: ../gtk/parameters.ui.h:50 -msgid "Show camera preview" -msgstr "" - -#: ../gtk/parameters.ui.h:51 -msgid "Video" -msgstr "וידאו" - -#: ../gtk/parameters.ui.h:52 -msgid "Multimedia settings" -msgstr "הגדרות מולטימדיה" - -#: ../gtk/parameters.ui.h:53 -msgid "This section defines your SIP address when not using a SIP account" -msgstr "חלק זה מגדיר את כתובת ה־SIP כאשר אינך עושה שימוש בחשבון SIP" - -#: ../gtk/parameters.ui.h:54 -msgid "Your display name (eg: John Doe):" -msgstr "שם התצוגה שלך (למשל: יורם יהודה):" - -#: ../gtk/parameters.ui.h:55 -msgid "Your username:" -msgstr "שם המשתמש שלך:" - -#: ../gtk/parameters.ui.h:56 -msgid "Your resulting SIP address:" -msgstr "כתובת SIP נובעת:" - -#: ../gtk/parameters.ui.h:57 -msgid "Default identity" -msgstr "זהות משתמטת" - -#: ../gtk/parameters.ui.h:58 -msgid "Wizard" -msgstr "אשף" - -#: ../gtk/parameters.ui.h:59 -msgid "Add" -msgstr "הוסף" - -#: ../gtk/parameters.ui.h:60 -msgid "Edit" -msgstr "ערוך" - -#: ../gtk/parameters.ui.h:61 -msgid "Remove" -msgstr "הסר" - -#: ../gtk/parameters.ui.h:62 -msgid "Proxy accounts" -msgstr "חשבונות Proxy" - -#: ../gtk/parameters.ui.h:63 -msgid "Erase all passwords" -msgstr "מחק סיסמאות" - -#: ../gtk/parameters.ui.h:64 -msgid "Privacy" -msgstr "פרטיות" - -#: ../gtk/parameters.ui.h:65 -msgid "Automatically answer when a call is received" -msgstr "" - -#: ../gtk/parameters.ui.h:66 -msgid "Delay before answering (ms)" -msgstr "" - -#: ../gtk/parameters.ui.h:67 -msgid "Auto-answer" -msgstr "" - -#: ../gtk/parameters.ui.h:68 -msgid "Manage SIP Accounts" -msgstr "ניהול חשבונות ‫SIP" - -#: ../gtk/parameters.ui.h:69 ../gtk/tunnel_config.ui.h:4 -msgid "Enable" -msgstr "אפשר" - -#: ../gtk/parameters.ui.h:70 ../gtk/tunnel_config.ui.h:5 -msgid "Disable" -msgstr "נטרל" - -#: ../gtk/parameters.ui.h:71 -msgid "Codecs" -msgstr "קודקים" - -#: ../gtk/parameters.ui.h:72 -msgid "0 stands for \"unlimited\"" -msgstr "0 מסמל \"בלי הגבלה\"" - -#: ../gtk/parameters.ui.h:73 -msgid "Upload speed limit in Kbit/sec:" -msgstr "מגבלת מהירות העלאה בקי״ב/שנ׳:" - -#: ../gtk/parameters.ui.h:74 -msgid "Download speed limit in Kbit/sec:" -msgstr "מגבלת מהירות הורדה בקי״ב/שנ׳:" - -#: ../gtk/parameters.ui.h:75 -msgid "Enable adaptive rate control" -msgstr "אפשר בקרת קצב מסתגלת" - -#: ../gtk/parameters.ui.h:76 -msgid "" -"Adaptive rate control is a technique to dynamically guess the available " -"bandwidth during a call." -msgstr "בקרת קצב מסתגלת הינה טכניקה להשערה דינמית של רוחב הפס הזמין במהלך שיחה." - -#: ../gtk/parameters.ui.h:77 -msgid "Bandwidth control" -msgstr "בקרת רוחב פס" - -#: ../gtk/parameters.ui.h:78 -msgid "Codecs" -msgstr "קודקים" - -#: ../gtk/parameters.ui.h:79 -msgid "Language" -msgstr "שפה" - -#: ../gtk/parameters.ui.h:80 -msgid "Show advanced settings" -msgstr "הצג הגדרות מתקדמות" - -#: ../gtk/parameters.ui.h:81 -msgid "Level" -msgstr "רמה" - -#: ../gtk/parameters.ui.h:82 -msgid "User interface" -msgstr "ממשק משתמש" - -#: ../gtk/parameters.ui.h:83 ../gtk/ldap.ui.h:2 -msgid "Server address:" -msgstr "" - -#: ../gtk/parameters.ui.h:84 ../gtk/ldap.ui.h:3 -msgid "Authentication method:" -msgstr "" - -#: ../gtk/parameters.ui.h:86 -msgid "LDAP Account setup" -msgstr "" - -#: ../gtk/parameters.ui.h:87 -msgid "LDAP" -msgstr "" - -#: ../gtk/parameters.ui.h:88 -msgid "Done" -msgstr "סיום" - #: ../gtk/buddylookup.ui.h:1 msgid "Search contacts in directory" msgstr "חיפוש אנשי קשר בתוך מדור" @@ -1504,29 +796,21 @@ msgstr "הוסף אל הרשימה שלי" msgid "Search somebody" msgstr "חיפוש אחר מישהו" -#: ../gtk/waiting.ui.h:2 -msgid "Please wait" -msgstr "נא להמתין" +#: ../gtk/callee_frame.ui.h:1 +msgid "Callee name" +msgstr "שם מקבל" -#: ../gtk/dscp_settings.ui.h:1 -msgid "DSCP settings" -msgstr "אפשרויות DSCP" +#: ../gtk/call_logs.ui.h:1 +msgid "Call history" +msgstr "היסטוריית שיחות" -#: ../gtk/dscp_settings.ui.h:2 -msgid "SIP" -msgstr "" +#: ../gtk/call_logs.ui.h:2 +msgid "Clear all" +msgstr "טיהור מוחלט" -#: ../gtk/dscp_settings.ui.h:3 -msgid "Audio RTP stream" -msgstr "זרם RTP אודיו" - -#: ../gtk/dscp_settings.ui.h:4 -msgid "Video RTP stream" -msgstr "זרם RTP וידאו" - -#: ../gtk/dscp_settings.ui.h:5 -msgid "Set DSCP values (in hexadecimal)" -msgstr "קבע ערכי DSCP (בהקסדצימלי)" +#: ../gtk/call_logs.ui.h:3 +msgid "Call back" +msgstr "חיוג חוזר" #: ../gtk/call_statistics.ui.h:1 msgid "Call statistics" @@ -1576,30 +860,112 @@ msgstr "" msgid "Call statistics and information" msgstr "סטטיסטיקות ומידע שיחה" -#: ../gtk/tunnel_config.ui.h:1 -msgid "Configure VoIP tunnel" -msgstr "הגדר תיעול VoIP" +#: ../gtk/chatroom_frame.ui.h:1 +msgid "Send" +msgstr "שלח" -#: ../gtk/tunnel_config.ui.h:2 -msgid "Host" -msgstr "מארח" +#: ../gtk/conf_frame.ui.h:1 +msgid "End conference" +msgstr "סיים ועידה" -#: ../gtk/tunnel_config.ui.h:3 -msgid "Port" -msgstr "פורט" +#: ../gtk/config-uri.ui.h:1 +msgid "Specifying a remote configuration URI" +msgstr "" -#: ../gtk/tunnel_config.ui.h:6 -msgid "Configure tunnel" -msgstr "הגדר מינהור" +#: ../gtk/config-uri.ui.h:2 +msgid "" +"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" +"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " +msgstr "" -#: ../gtk/tunnel_config.ui.h:9 -msgid "Configure http proxy (optional)" -msgstr "הגדר http proxy (רשות)" +#: ../gtk/contact.ui.h:2 +msgid "SIP Address" +msgstr "כתובת ‫SIP" + +#: ../gtk/contact.ui.h:3 +msgid "Show this contact presence status" +msgstr "הצג את מצב נוכחותו של איש קשר זה" + +#: ../gtk/contact.ui.h:4 +msgid "Allow this contact to see my presence status" +msgstr "הרשה לאיש קשר זה לראות את מצב הנוכחות שלי" + +#: ../gtk/contact.ui.h:5 +msgid "Contact information" +msgstr "מידע איש קשר" + +#: ../gtk/dscp_settings.ui.h:1 +msgid "DSCP settings" +msgstr "אפשרויות DSCP" + +#: ../gtk/dscp_settings.ui.h:2 +msgid "SIP" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:3 +msgid "Audio RTP stream" +msgstr "זרם RTP אודיו" + +#: ../gtk/dscp_settings.ui.h:4 +msgid "Video RTP stream" +msgstr "זרם RTP וידאו" + +#: ../gtk/dscp_settings.ui.h:5 +msgid "Set DSCP values (in hexadecimal)" +msgstr "קבע ערכי DSCP (בהקסדצימלי)" + +#: ../gtk/in_call_frame.ui.h:1 +msgid "Click here to set the speakers volume" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:5 +msgid "Record this call to an audio file" +msgstr "הקלט את שיחה זו אל קובץ אודיו" + +#: ../gtk/in_call_frame.ui.h:6 +msgid "Video" +msgstr "וידאו" + +#: ../gtk/in_call_frame.ui.h:8 +msgid "Mute" +msgstr "השתק" + +#: ../gtk/in_call_frame.ui.h:9 +msgid "Transfer" +msgstr "העבר" + +#: ../gtk/in_call_frame.ui.h:12 +msgid "In call" +msgstr "בשיחה כעת" + +#: ../gtk/in_call_frame.ui.h:13 +msgid "Duration" +msgstr "משך זמן" + +#: ../gtk/in_call_frame.ui.h:14 +msgid "Call quality rating" +msgstr "אומדן איכות שיחה" #: ../gtk/ldap.ui.h:1 msgid "LDAP Settings" msgstr "" +#: ../gtk/ldap.ui.h:2 ../gtk/parameters.ui.h:89 +msgid "Server address:" +msgstr "" + +#: ../gtk/ldap.ui.h:3 ../gtk/parameters.ui.h:90 +msgid "Authentication method:" +msgstr "" + +#: ../gtk/ldap.ui.h:4 ../gtk/parameters.ui.h:91 ../gtk/setup_wizard.ui.h:17 +msgid "Username:" +msgstr "שם משתמש:" + +#: ../gtk/ldap.ui.h:5 ../gtk/password.ui.h:4 ../gtk/setup_wizard.ui.h:18 +msgid "Password:" +msgstr "סיסמה:" + #: ../gtk/ldap.ui.h:6 msgid "Use TLS Connection" msgstr "" @@ -1685,16 +1051,504 @@ msgstr "" msgid "NTLM" msgstr "" -#: ../gtk/config-uri.ui.h:1 -msgid "Specifying a remote configuration URI" +#: ../gtk/login_frame.ui.h:1 ../gtk/tunnel_config.ui.h:7 +msgid "Username" +msgstr "שם משתמש" + +#: ../gtk/login_frame.ui.h:2 ../gtk/tunnel_config.ui.h:8 +msgid "Password" +msgstr "סיסמה" + +#: ../gtk/login_frame.ui.h:3 +msgid "Internet connection:" +msgstr "חיבור אינטרנט:" + +#: ../gtk/login_frame.ui.h:4 +msgid "Automatically log me in" +msgstr "חבר אותי אוטומטית" + +#: ../gtk/login_frame.ui.h:5 ../gtk/password.ui.h:3 +msgid "UserID" +msgstr "מזהה משתמש" + +#: ../gtk/login_frame.ui.h:6 +msgid "Login information" +msgstr "מידע התחברות" + +#: ../gtk/login_frame.ui.h:7 +msgid "Welcome!" msgstr "" -#: ../gtk/config-uri.ui.h:2 -msgid "" -"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" -"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " +#: ../gtk/login_frame.ui.h:8 +msgid "ADSL" +msgstr "‫ADSL" + +#: ../gtk/login_frame.ui.h:9 +msgid "Fiber Channel" +msgstr "ערוץ סיב" + +#: ../gtk/log.ui.h:1 +msgid "Linphone debug window" +msgstr "חלון ניפוי שגיאות ‫Linphone" + +#: ../gtk/log.ui.h:2 +msgid "Scroll to end" +msgstr "גלול אוטומטית לסוף" + +#: ../gtk/main.ui.h:1 +msgid "Default" +msgstr "ברירת מחדל" + +#: ../gtk/main.ui.h:2 +msgid "Delete" +msgstr "מחק" + +#: ../gtk/main.ui.h:3 +msgid "_Options" +msgstr "_אפשרויות" + +#: ../gtk/main.ui.h:4 +msgid "Set configuration URI" msgstr "" +#: ../gtk/main.ui.h:5 +msgid "Always start video" +msgstr "התחל תמיד וידאו" + +#: ../gtk/main.ui.h:6 +msgid "Enable self-view" +msgstr "אפשר ראות-עצמית" + +#: ../gtk/main.ui.h:7 +msgid "Show keypad" +msgstr "" + +#: ../gtk/main.ui.h:8 +msgid "_Help" +msgstr "_עזרה" + +#: ../gtk/main.ui.h:9 +msgid "Show debug window" +msgstr "הצג חלון ניפוי שגיאות" + +#: ../gtk/main.ui.h:10 +msgid "_Homepage" +msgstr "_עמוד הבית" + +#: ../gtk/main.ui.h:11 +msgid "Check _Updates" +msgstr "בדיקת _עדכונים" + +#: ../gtk/main.ui.h:12 +msgid "Account assistant" +msgstr "אשף חשבון" + +#: ../gtk/main.ui.h:14 +msgid "SIP address or phone number:" +msgstr "כתובת SIP או מספר טלפון" + +#: ../gtk/main.ui.h:15 +msgid "Initiate a new call" +msgstr "התחל שיחה חדשה" + +#: ../gtk/main.ui.h:16 +msgid "Contacts" +msgstr "אנשי קשר" + +#: ../gtk/main.ui.h:17 +msgid "Search" +msgstr "חיפוש" + +#: ../gtk/main.ui.h:18 +msgid "Add contacts from directory" +msgstr "הוסף אנשי קשר מן מדור" + +#: ../gtk/main.ui.h:19 +msgid "Add contact" +msgstr "הוסף איש קשר" + +#: ../gtk/main.ui.h:20 +msgid "Clear call history" +msgstr "" + +#: ../gtk/main.ui.h:22 +msgid "My current identity:" +msgstr "זהותי הנוכחית:" + +#: ../gtk/main.ui.h:23 +msgid "Autoanswer is enabled" +msgstr "" + +#: ../gtk/parameters.ui.h:1 +msgid "anonymous" +msgstr "" + +#: ../gtk/parameters.ui.h:2 +msgid "GSSAPI" +msgstr "" + +#: ../gtk/parameters.ui.h:3 +msgid "SASL" +msgstr "" + +#: ../gtk/parameters.ui.h:4 +msgid "default soundcard" +msgstr "כרטיס קול משתמט" + +#: ../gtk/parameters.ui.h:5 +msgid "a sound card" +msgstr "כרטיס קול" + +#: ../gtk/parameters.ui.h:6 +msgid "default camera" +msgstr "מצלמה משתמטת" + +#: ../gtk/parameters.ui.h:7 +msgid "CIF" +msgstr "" + +#: ../gtk/parameters.ui.h:8 +msgid "Audio codecs" +msgstr "קודקים של אודיו" + +#: ../gtk/parameters.ui.h:9 +msgid "Video codecs" +msgstr "קודקים של וידאו" + +#: ../gtk/parameters.ui.h:10 +msgid "C" +msgstr "" + +#: ../gtk/parameters.ui.h:11 +msgid "SIP (UDP)" +msgstr "‏SIP ‏(UDP)" + +#: ../gtk/parameters.ui.h:12 +msgid "SIP (TCP)" +msgstr "‏SIP ‏(TCP)" + +#: ../gtk/parameters.ui.h:13 +msgid "SIP (TLS)" +msgstr "‏SIP ‏(TLS)" + +#: ../gtk/parameters.ui.h:14 +msgid "default" +msgstr "" + +#: ../gtk/parameters.ui.h:15 +msgid "high-fps" +msgstr "" + +#: ../gtk/parameters.ui.h:16 +msgid "custom" +msgstr "" + +#: ../gtk/parameters.ui.h:17 +msgid "Settings" +msgstr "הגדרות" + +#: ../gtk/parameters.ui.h:18 +msgid "This section defines your SIP address when not using a SIP account" +msgstr "חלק זה מגדיר את כתובת ה־SIP כאשר אינך עושה שימוש בחשבון SIP" + +#: ../gtk/parameters.ui.h:19 +msgid "Your display name (eg: John Doe):" +msgstr "שם התצוגה שלך (למשל: יורם יהודה):" + +#: ../gtk/parameters.ui.h:20 +msgid "Your username:" +msgstr "שם המשתמש שלך:" + +#: ../gtk/parameters.ui.h:21 +msgid "Your resulting SIP address:" +msgstr "כתובת SIP נובעת:" + +#: ../gtk/parameters.ui.h:22 +msgid "Default identity" +msgstr "זהות משתמטת" + +#: ../gtk/parameters.ui.h:23 +msgid "Wizard" +msgstr "אשף" + +#: ../gtk/parameters.ui.h:24 +msgid "Add" +msgstr "הוסף" + +#: ../gtk/parameters.ui.h:25 +msgid "Edit" +msgstr "ערוך" + +#: ../gtk/parameters.ui.h:26 +msgid "Remove" +msgstr "הסר" + +#: ../gtk/parameters.ui.h:27 +msgid "Proxy accounts" +msgstr "חשבונות Proxy" + +#: ../gtk/parameters.ui.h:28 +msgid "Erase all passwords" +msgstr "מחק סיסמאות" + +#: ../gtk/parameters.ui.h:29 +msgid "Privacy" +msgstr "פרטיות" + +#: ../gtk/parameters.ui.h:30 +msgid "Automatically answer when a call is received" +msgstr "" + +#: ../gtk/parameters.ui.h:31 +msgid "Delay before answering (ms)" +msgstr "" + +#: ../gtk/parameters.ui.h:32 +msgid "Auto-answer" +msgstr "" + +#: ../gtk/parameters.ui.h:33 +msgid "Manage SIP Accounts" +msgstr "ניהול חשבונות ‫SIP" + +#: ../gtk/parameters.ui.h:34 +msgid "Ring sound:" +msgstr "צליל צלצול:" + +#: ../gtk/parameters.ui.h:35 +msgid "ALSA special device (optional):" +msgstr "התקן ALSA מיוחד (רשות):" + +#: ../gtk/parameters.ui.h:36 +msgid "Capture device:" +msgstr "התקן לכידה:" + +#: ../gtk/parameters.ui.h:37 +msgid "Ring device:" +msgstr "התקן צלצול:" + +#: ../gtk/parameters.ui.h:38 +msgid "Playback device:" +msgstr "התקן פס קול:" + +#: ../gtk/parameters.ui.h:39 +msgid "Enable echo cancellation" +msgstr "אפשר ביטול הד" + +#: ../gtk/parameters.ui.h:40 +msgid "Audio" +msgstr "אודיו" + +#: ../gtk/parameters.ui.h:41 +msgid "Video input device:" +msgstr "התקן קלט וידאו:" + +#: ../gtk/parameters.ui.h:42 +msgid "Preferred video resolution:" +msgstr "" + +#: ../gtk/parameters.ui.h:43 +msgid "Video output method:" +msgstr "" + +#: ../gtk/parameters.ui.h:44 +msgid "Show camera preview" +msgstr "" + +#: ../gtk/parameters.ui.h:45 +msgid "Video preset:" +msgstr "" + +#: ../gtk/parameters.ui.h:46 +msgid "Preferred video framerate:" +msgstr "" + +#: ../gtk/parameters.ui.h:47 +msgid "0 stands for \"unlimited\"" +msgstr "0 מסמל \"בלי הגבלה\"" + +#: ../gtk/parameters.ui.h:48 +msgid "Video" +msgstr "וידאו" + +#: ../gtk/parameters.ui.h:49 +msgid "Upload speed limit in Kbit/sec:" +msgstr "מגבלת מהירות העלאה בקי״ב/שנ׳:" + +#: ../gtk/parameters.ui.h:50 +msgid "Download speed limit in Kbit/sec:" +msgstr "מגבלת מהירות הורדה בקי״ב/שנ׳:" + +#: ../gtk/parameters.ui.h:51 +msgid "Enable adaptive rate control" +msgstr "אפשר בקרת קצב מסתגלת" + +#: ../gtk/parameters.ui.h:52 +msgid "" +"Adaptive rate control is a technique to dynamically guess the available " +"bandwidth during a call." +msgstr "בקרת קצב מסתגלת הינה טכניקה להשערה דינמית של רוחב הפס הזמין במהלך שיחה." + +#: ../gtk/parameters.ui.h:53 +msgid "Bandwidth control" +msgstr "בקרת רוחב פס" + +#: ../gtk/parameters.ui.h:54 +msgid "Multimedia settings" +msgstr "הגדרות מולטימדיה" + +#: ../gtk/parameters.ui.h:55 +msgid "Set Maximum Transmission Unit:" +msgstr "הגדר יחידת תמסורת מרבית:" + +#: ../gtk/parameters.ui.h:56 +msgid "Send DTMFs as SIP info" +msgstr "שלח טזמ״תים (DTMFs) כמידע SIP" + +#: ../gtk/parameters.ui.h:57 +msgid "Allow IPv6" +msgstr "" + +#: ../gtk/parameters.ui.h:58 +msgid "Transport" +msgstr "טרנספורט" + +#: ../gtk/parameters.ui.h:59 +msgid "SIP/UDP port" +msgstr "" + +#: ../gtk/parameters.ui.h:61 +msgid "Random" +msgstr "" + +#: ../gtk/parameters.ui.h:62 +msgid "SIP/TCP port" +msgstr "" + +#: ../gtk/parameters.ui.h:63 +msgid "Audio RTP/UDP:" +msgstr "אודיו RTP/UDP:" + +#: ../gtk/parameters.ui.h:64 +msgid "Fixed" +msgstr "מקובע" + +#: ../gtk/parameters.ui.h:65 +msgid "Video RTP/UDP:" +msgstr "וידאו RTP/UDP:" + +#: ../gtk/parameters.ui.h:66 +msgid "Media encryption type" +msgstr "סוג הצפנת מדיה" + +#: ../gtk/parameters.ui.h:67 +msgid "Media encryption is mandatory" +msgstr "הצפנת מדיה הינה מנדטורית" + +#: ../gtk/parameters.ui.h:68 +msgid "Tunnel" +msgstr "מינהור" + +#: ../gtk/parameters.ui.h:69 +msgid "DSCP fields" +msgstr "שדות DSCP" + +#: ../gtk/parameters.ui.h:70 +msgid "Network protocol and ports" +msgstr "פרוטוקולי רשת תקשורת ופורטים" + +#: ../gtk/parameters.ui.h:71 +msgid "Direct connection to the Internet" +msgstr "חיבור ישיר אל האינטרנט" + +#: ../gtk/parameters.ui.h:72 +msgid "Behind NAT / Firewall (specify gateway IP )" +msgstr "" + +#: ../gtk/parameters.ui.h:73 +msgid "Behind NAT / Firewall (use STUN to resolve)" +msgstr "מאחורי NAT / חומת אש (בעזרת STUN לפתירה)" + +#: ../gtk/parameters.ui.h:74 +msgid "Behind NAT / Firewall (use ICE)" +msgstr "מאחורי NAT / חומת אש (בעזרת ICE)" + +#: ../gtk/parameters.ui.h:75 +msgid "Behind NAT / Firewall (use uPnP)" +msgstr "מאחורי NAT / חומת אש (בעזרת uPnP)" + +#: ../gtk/parameters.ui.h:76 +msgid "Public IP address:" +msgstr "כתובת IP פומבית:" + +#: ../gtk/parameters.ui.h:77 +msgid "Stun server:" +msgstr "שרת STUN:" + +#: ../gtk/parameters.ui.h:78 +msgid "NAT and Firewall" +msgstr "‫NAT וחומת אש" + +#: ../gtk/parameters.ui.h:79 +msgid "Network settings" +msgstr "הגדרות רשת תקשורת" + +#: ../gtk/parameters.ui.h:80 ../gtk/tunnel_config.ui.h:4 +msgid "Enable" +msgstr "אפשר" + +#: ../gtk/parameters.ui.h:81 ../gtk/tunnel_config.ui.h:5 +msgid "Disable" +msgstr "נטרל" + +#: ../gtk/parameters.ui.h:82 +msgid "Audio codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:83 +msgid "Video codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:84 +msgid "Codecs" +msgstr "קודקים" + +#: ../gtk/parameters.ui.h:85 +msgid "Language" +msgstr "שפה" + +#: ../gtk/parameters.ui.h:86 +msgid "Show advanced settings" +msgstr "הצג הגדרות מתקדמות" + +#: ../gtk/parameters.ui.h:87 +msgid "Level" +msgstr "רמה" + +#: ../gtk/parameters.ui.h:88 +msgid "User interface" +msgstr "ממשק משתמש" + +#: ../gtk/parameters.ui.h:92 +msgid "LDAP Account setup" +msgstr "" + +#: ../gtk/parameters.ui.h:93 +msgid "LDAP" +msgstr "" + +#: ../gtk/parameters.ui.h:94 +msgid "Done" +msgstr "סיום" + +#: ../gtk/password.ui.h:1 +msgid "Linphone - Authentication required" +msgstr "‫Linphone - נדרש אימות" + +#: ../gtk/password.ui.h:2 +msgid "Please enter the domain password" +msgstr "נא להזין את סיסמת המתחם" + #: ../gtk/provisioning-fetch.ui.h:1 msgid "Configuring..." msgstr "" @@ -1703,68 +1557,278 @@ msgstr "" msgid "Please wait while fetching configuration from server..." msgstr "" -#: ../coreapi/linphonecore.c:1539 +#: ../gtk/setup_wizard.ui.h:1 +msgid "SIP account configuration assistant" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:2 +msgid "" +"Welcome!\n" +"This assistant will help you to use a SIP account for your calls." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:4 +msgid "Welcome to the account setup assistant" +msgstr "ברוך בואך אל אשף הגדרת החשבון" + +#: ../gtk/setup_wizard.ui.h:5 +msgid "Create an account on linphone.org" +msgstr "צור חשבון אצל linphone.org" + +#: ../gtk/setup_wizard.ui.h:6 +msgid "I have already a linphone.org account and I just want to use it" +msgstr "כבר קיים חשבון linphone.org ברשותי וברצוני לעשות בו שימוש" + +#: ../gtk/setup_wizard.ui.h:7 +msgid "I have already a sip account and I just want to use it" +msgstr "כבר קיים חשבון sip ברשותי וברצוני לעשות בו שימוש" + +#: ../gtk/setup_wizard.ui.h:8 +msgid "I want to specify a remote configuration URI" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:9 +msgid "Account setup assistant" +msgstr "אשף הגדרת חשבון" + +#: ../gtk/setup_wizard.ui.h:10 +msgid "Enter your account information" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:11 +msgid "Username*" +msgstr "שם משתמש*" + +#: ../gtk/setup_wizard.ui.h:12 +msgid "Password*" +msgstr "סיסמה*" + +#: ../gtk/setup_wizard.ui.h:13 +msgid "Domain*" +msgstr "מתחם*" + +#: ../gtk/setup_wizard.ui.h:14 +msgid "Proxy" +msgstr "פרוקסי" + +#: ../gtk/setup_wizard.ui.h:15 +msgid "Configure your account (step 1/1)" +msgstr "הגדרת חשבונך (צעד 1/1)" + +#: ../gtk/setup_wizard.ui.h:16 +msgid "Enter your linphone.org username" +msgstr "הזן את שם משתמשך אצל linphone.org" + +#: ../gtk/setup_wizard.ui.h:19 +msgid "Enter your sip username (step 1/1)" +msgstr "הזנת שם משתמש sip (צעד 1/1)" + +#: ../gtk/setup_wizard.ui.h:20 +msgid "(*) Required fields" +msgstr "(*) שדות חובה" + +#: ../gtk/setup_wizard.ui.h:21 +msgid "Email: (*)" +msgstr "דוא״ל: (*)" + +#: ../gtk/setup_wizard.ui.h:22 +msgid "Username: (*)" +msgstr "שם משתמש: (*)" + +#: ../gtk/setup_wizard.ui.h:23 +msgid "Password: (*)" +msgstr "סיסמה: (*)" + +#: ../gtk/setup_wizard.ui.h:24 +msgid "Confirm your password: (*)" +msgstr "אימות סיסמתך: (*)" + +#: ../gtk/setup_wizard.ui.h:25 +msgid "Keep me informed with linphone updates" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:26 +msgid "Enter account information (step 1/2)" +msgstr "הזנת מידע חשבון (צעד 1/2)" + +#: ../gtk/setup_wizard.ui.h:27 +msgid "Your account is being created, please wait." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:28 +msgid "Account creation in progress" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:29 +msgid "" +"Please validate your account by clicking on the link we just sent you by email.\n" +"Then come back here and press Next button." +msgstr "נא לאמת את חשבונך באמצעות הקלקה על הקישור ששלחנו לך עתה באמצעות דוא״ל.\nאחרי כן נא לחזור לכאן וללחוץ על הלחצן 'קדימה'." + +#: ../gtk/setup_wizard.ui.h:31 +msgid "Validation (step 2/2)" +msgstr "אימות (צעד 2/2)" + +#: ../gtk/setup_wizard.ui.h:32 +msgid "Checking if your account is been validated, please wait." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:33 +msgid "Account validation check in progress" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:34 +msgid "" +"Error, account not validated, username already used or server unreachable.\n" +"Please go back and try again." +msgstr "שגיאה, חשבון לא אומת, שם משתמש כבר בשימוש או שרת לא ניתן להשגה.\nנא לחזור ולנסות שוב." + +#: ../gtk/setup_wizard.ui.h:36 +msgid "Error" +msgstr "שגיאה" + +#: ../gtk/setup_wizard.ui.h:37 +msgid "Thank you. Your account is now configured and ready for use." +msgstr "תודה לך. חשבונך מוגדר ומוכן לשימוש כעת." + +#: ../gtk/sip_account.ui.h:1 +msgid "Linphone - Configure a SIP account" +msgstr "‫Linphone - הגדרת חשבון ‫SIP" + +#: ../gtk/sip_account.ui.h:2 +msgid "Your SIP identity:" +msgstr "זהות ה־SIP שלך:" + +#: ../gtk/sip_account.ui.h:3 +msgid "Looks like sip:@" +msgstr "נראה כמו ‪sip:@" + +#: ../gtk/sip_account.ui.h:4 +msgid "sip:" +msgstr "" + +#: ../gtk/sip_account.ui.h:5 +msgid "SIP Proxy address:" +msgstr "כתובת SIP Proxy:" + +#: ../gtk/sip_account.ui.h:6 +msgid "Looks like sip:" +msgstr "נראה כמו ‪sip:" + +#: ../gtk/sip_account.ui.h:7 +msgid "Registration duration (sec):" +msgstr "משך רישום (בשניות):" + +#: ../gtk/sip_account.ui.h:8 +msgid "Contact params (optional):" +msgstr "" + +#: ../gtk/sip_account.ui.h:9 +msgid "AVPF regular RTCP interval (sec):" +msgstr "" + +#: ../gtk/sip_account.ui.h:10 +msgid "Route (optional):" +msgstr "ניתוב (רשות):" + +#: ../gtk/sip_account.ui.h:11 +msgid "Transport" +msgstr "טרנספורט" + +#: ../gtk/sip_account.ui.h:12 +msgid "Register" +msgstr "רישום" + +#: ../gtk/sip_account.ui.h:13 +msgid "Publish presence information" +msgstr "פרסם מידע נוכחות" + +#: ../gtk/sip_account.ui.h:14 +msgid "Enable AVPF" +msgstr "אפשר AVPF" + +#: ../gtk/sip_account.ui.h:15 +msgid "Configure a SIP account" +msgstr "הגדרת חשבון ‫SIP" + +#: ../gtk/tunnel_config.ui.h:1 +msgid "Configure VoIP tunnel" +msgstr "הגדר תיעול VoIP" + +#: ../gtk/tunnel_config.ui.h:2 +msgid "Host" +msgstr "מארח" + +#: ../gtk/tunnel_config.ui.h:3 +msgid "Port" +msgstr "פורט" + +#: ../gtk/tunnel_config.ui.h:6 +msgid "Configure tunnel" +msgstr "הגדר מינהור" + +#: ../gtk/tunnel_config.ui.h:9 +msgid "Configure http proxy (optional)" +msgstr "הגדר http proxy (רשות)" + +#: ../gtk/waiting.ui.h:2 +msgid "Please wait" +msgstr "נא להמתין" + +#: ../coreapi/linphonecore.c:1560 msgid "Ready" msgstr "מוכן" -#: ../coreapi/linphonecore.c:2551 +#: ../coreapi/linphonecore.c:2556 msgid "Configuring" msgstr "" -#: ../coreapi/linphonecore.c:2725 -msgid "Looking for telephone number destination..." -msgstr "מחפש כעת עבור יעד מספר טלפון..." - -#: ../coreapi/linphonecore.c:2727 -msgid "Could not resolve this number." -msgstr "לא ניתן לפתור את מספר זה." - #. must be known at that time -#: ../coreapi/linphonecore.c:3013 +#: ../coreapi/linphonecore.c:2951 msgid "Contacting" msgstr "מתקשר כעת" -#: ../coreapi/linphonecore.c:3018 +#: ../coreapi/linphonecore.c:2956 msgid "Could not call" msgstr "לא ניתן להתקשר" -#: ../coreapi/linphonecore.c:3169 +#: ../coreapi/linphonecore.c:3092 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "הגענו אל המספר המרבי של שיחות מקבילות, עמך הסליחה" -#: ../coreapi/linphonecore.c:3327 +#: ../coreapi/linphonecore.c:3250 msgid "is contacting you" msgstr "מתקשר/ת אליך" -#: ../coreapi/linphonecore.c:3328 +#: ../coreapi/linphonecore.c:3251 msgid " and asked autoanswer." msgstr " ומבקש/ת מענה אוטומטי." -#: ../coreapi/linphonecore.c:3452 +#: ../coreapi/linphonecore.c:3377 msgid "Modifying call parameters..." msgstr "מתאים כעת פרמטרים של שיחה..." -#: ../coreapi/linphonecore.c:3802 +#: ../coreapi/linphonecore.c:3769 msgid "Connected." msgstr "מקושר." -#: ../coreapi/linphonecore.c:3827 +#: ../coreapi/linphonecore.c:3794 msgid "Call aborted" msgstr "קריאה בוטלה" -#: ../coreapi/linphonecore.c:4024 +#: ../coreapi/linphonecore.c:3983 msgid "Could not pause the call" msgstr "לא ניתן להשהות את השיחה" -#: ../coreapi/linphonecore.c:4027 +#: ../coreapi/linphonecore.c:3986 msgid "Pausing the current call..." msgstr "משהה כעת שיחה נוכחית..." -#: ../coreapi/misc.c:434 +#: ../coreapi/misc.c:440 msgid "Stun lookup in progress..." msgstr "בדיקת STUN מצויה כעת בעיצומה..." -#: ../coreapi/misc.c:615 +#: ../coreapi/misc.c:650 msgid "ICE local candidates gathering in progress..." msgstr "צבירת מועמדים מקומיים של ICE מצויה כעת בעיצומה..." @@ -1820,166 +1884,173 @@ msgstr "" msgid "Unknown status" msgstr "" -#: ../coreapi/proxy.c:328 +#: ../coreapi/proxy.c:292 msgid "" "The sip proxy address you entered is invalid, it must start with \"sip:\" " "followed by a hostname." msgstr "כתובת sip proxy שהזנת הינה שגויה, זו צריכה להתחיל עם‭\"sip:\" ‬ לאחר שם מארח." -#: ../coreapi/proxy.c:334 +#: ../coreapi/proxy.c:298 msgid "" "The sip identity you entered is invalid.\n" "It should look like sip:username@proxydomain, such as sip:alice@example.net" msgstr "זהות sip שהוזנה הינה שגויה.\nזו צריכה להיראות כמו sip:username@proxydomain, למשל sip:alice@example.net" -#: ../coreapi/proxy.c:1416 +#: ../coreapi/proxy.c:927 +msgid "Looking for telephone number destination..." +msgstr "מחפש כעת עבור יעד מספר טלפון..." + +#: ../coreapi/proxy.c:931 +msgid "Could not resolve this number." +msgstr "לא ניתן לפתור את מספר זה." + +#: ../coreapi/proxy.c:1324 #, c-format msgid "Could not login as %s" msgstr "לא ניתן להתחבר בזהות %s" -#: ../coreapi/callbacks.c:428 +#: ../coreapi/proxy.c:1411 +#, c-format +msgid "Refreshing on %s..." +msgstr "" + +#: ../coreapi/callbacks.c:423 msgid "Remote ringing." msgstr "צלצול מרוחק." -#: ../coreapi/callbacks.c:440 +#: ../coreapi/callbacks.c:435 msgid "Remote ringing..." msgstr "צלצול מרוחק..." -#: ../coreapi/callbacks.c:461 +#: ../coreapi/callbacks.c:458 msgid "Early media." msgstr "מדיה מוקדמת." -#: ../coreapi/callbacks.c:534 +#: ../coreapi/callbacks.c:488 #, c-format -msgid "Call with %s is paused." -msgstr "שיחה עם %s מושהית." +msgid "Call answered by %s" +msgstr "" -#: ../coreapi/callbacks.c:547 -#, c-format -msgid "Call answered by %s - on hold." -msgstr "קריאה נענתה על ידי %s - בהמתנה." - -#: ../coreapi/callbacks.c:557 +#: ../coreapi/callbacks.c:527 msgid "Call resumed." msgstr "קריאה חודשה." -#: ../coreapi/callbacks.c:561 -#, c-format -msgid "Call answered by %s." -msgstr "קריאה נענתה על ידי %s." - -#: ../coreapi/callbacks.c:584 +#: ../coreapi/callbacks.c:582 msgid "Incompatible, check codecs or security settings..." msgstr "חוסר תאימות, בדוק קודקים או הגדרות אבטחה..." -#: ../coreapi/callbacks.c:589 ../coreapi/callbacks.c:906 +#: ../coreapi/callbacks.c:587 ../coreapi/callbacks.c:923 msgid "Incompatible media parameters." msgstr "פרמטריי מדיה חסרי תואמים." -#: ../coreapi/callbacks.c:619 +#: ../coreapi/callbacks.c:612 msgid "We have been resumed." msgstr "חזרנו." #. we are being paused -#: ../coreapi/callbacks.c:628 +#: ../coreapi/callbacks.c:620 msgid "We are paused by other party." msgstr "אנו מושהים על ידי צד אחר." -#. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:666 +#: ../coreapi/callbacks.c:630 msgid "Call is updated by remote." msgstr "שיחה עודכנה מרחוק." -#: ../coreapi/callbacks.c:782 +#: ../coreapi/callbacks.c:799 msgid "Call terminated." msgstr "קריאה הסתיימה." -#: ../coreapi/callbacks.c:810 +#: ../coreapi/callbacks.c:827 msgid "User is busy." msgstr "משתמש עסוק כעת." -#: ../coreapi/callbacks.c:811 +#: ../coreapi/callbacks.c:828 msgid "User is temporarily unavailable." msgstr "משתמש לא זמין זמנית." #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:813 +#: ../coreapi/callbacks.c:830 msgid "User does not want to be disturbed." msgstr "משתמש לא מעוניין שיפריעו לו." -#: ../coreapi/callbacks.c:814 +#: ../coreapi/callbacks.c:831 msgid "Call declined." msgstr "קריאה סורבה." -#: ../coreapi/callbacks.c:829 +#: ../coreapi/callbacks.c:846 msgid "Request timeout." msgstr "" -#: ../coreapi/callbacks.c:860 +#: ../coreapi/callbacks.c:877 msgid "Redirected" msgstr "מכוון מחדש" -#: ../coreapi/callbacks.c:915 +#: ../coreapi/callbacks.c:927 msgid "Call failed." msgstr "קריאה נכשלה." -#: ../coreapi/callbacks.c:993 +#: ../coreapi/callbacks.c:1005 #, c-format msgid "Registration on %s successful." msgstr "רישום אצל %s הושלם בהצלחה." -#: ../coreapi/callbacks.c:994 +#: ../coreapi/callbacks.c:1006 #, c-format msgid "Unregistration on %s done." msgstr "אי רישום אצל %s סוים." -#: ../coreapi/callbacks.c:1012 +#: ../coreapi/callbacks.c:1024 msgid "no response timeout" msgstr "אין היענות תוך זמן מוגדר" -#: ../coreapi/callbacks.c:1015 +#: ../coreapi/callbacks.c:1027 #, c-format msgid "Registration on %s failed: %s" msgstr "רישום אצל %s נכשל: %s" -#: ../coreapi/callbacks.c:1022 +#: ../coreapi/callbacks.c:1034 msgid "Service unavailable, retrying" msgstr "" #. if encryption is DTLS, no status to be displayed -#: ../coreapi/linphonecall.c:180 +#: ../coreapi/linphonecall.c:197 #, c-format msgid "Authentication token is %s" msgstr "אות האימות הינה %s" -#: ../coreapi/linphonecall.c:1310 +#: ../coreapi/linphonecall.c:1561 +#, c-format +msgid "Call parameters could not be modified: %s." +msgstr "" + +#: ../coreapi/linphonecall.c:1563 msgid "Call parameters were successfully modified." msgstr "" -#: ../coreapi/linphonecall.c:3686 +#: ../coreapi/linphonecall.c:4396 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." msgstr[0] "החמצת שיחה %i." msgstr[1] "החמצת %i שיחות." -#: ../coreapi/call_log.c:209 +#: ../coreapi/call_log.c:223 msgid "aborted" msgstr "" -#: ../coreapi/call_log.c:212 +#: ../coreapi/call_log.c:226 msgid "completed" msgstr "" -#: ../coreapi/call_log.c:215 +#: ../coreapi/call_log.c:229 msgid "missed" msgstr "" -#: ../coreapi/call_log.c:218 +#: ../coreapi/call_log.c:232 msgid "unknown" msgstr "" -#: ../coreapi/call_log.c:220 +#: ../coreapi/call_log.c:234 #, c-format msgid "" "%s at %s\n" @@ -1989,7 +2060,7 @@ msgid "" "Duration: %i mn %i sec\n" msgstr "" -#: ../coreapi/call_log.c:221 +#: ../coreapi/call_log.c:235 msgid "Outgoing call" msgstr "" diff --git a/po/hu.po b/po/hu.po index 1a20cf6c7..71d2a5020 100644 --- a/po/hu.po +++ b/po/hu.po @@ -3,78 +3,88 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# Free Bill , 2015 msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-04-30 10:13+0200\n" -"PO-Revision-Date: 2015-04-30 08:13+0000\n" +"POT-Creation-Date: 2015-11-10 15:16+0100\n" +"PO-Revision-Date: 2015-11-10 14:16+0000\n" "Last-Translator: Belledonne Communications \n" -"Language-Team: Hungarian (http://www.transifex.com/projects/p/linphone-gtk/language/hu/)\n" +"Language-Team: Hungarian (http://www.transifex.com/belledonne-communications/linphone-gtk/language/hu/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: hu\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ../gtk/calllogs.c:148 ../gtk/friendlist.c:974 +#: ../gtk/calllogs.c:178 #, c-format msgid "Call %s" msgstr "%s hívása" -#: ../gtk/calllogs.c:149 ../gtk/friendlist.c:975 +#: ../gtk/calllogs.c:179 #, c-format msgid "Send text to %s" msgstr "Szöveg küldése a következőnek: %s" -#: ../gtk/calllogs.c:232 +#: ../gtk/calllogs.c:181 +#, c-format +msgid "Add %s to your contact list" +msgstr "" + +#: ../gtk/calllogs.c:245 ../gtk/main.ui.h:21 +msgid "Recent calls" +msgstr "Legutóbbi hívások" + +#: ../gtk/calllogs.c:260 #, c-format msgid "Recent calls (%i)" msgstr "" -#: ../gtk/calllogs.c:314 +#: ../gtk/calllogs.c:331 msgid "n/a" msgstr "-" -#: ../gtk/calllogs.c:317 +#: ../gtk/calllogs.c:334 msgid "Aborted" msgstr "Megszakítva" -#: ../gtk/calllogs.c:320 +#: ../gtk/calllogs.c:337 msgid "Missed" msgstr "Nem fogadott" -#: ../gtk/calllogs.c:323 +#: ../gtk/calllogs.c:340 msgid "Declined" msgstr "Elutasítva" -#: ../gtk/calllogs.c:329 +#: ../gtk/calllogs.c:346 #, c-format msgid "%i minute" msgid_plural "%i minutes" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%i perc" +msgstr[1] "%i perc" -#: ../gtk/calllogs.c:332 +#: ../gtk/calllogs.c:349 #, c-format msgid "%i second" msgid_plural "%i seconds" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%i másodperc" +msgstr[1] "%i másodperc" -#: ../gtk/calllogs.c:337 +#: ../gtk/calllogs.c:354 #, c-format msgid "" "%s\tQuality: %s\n" "%s\t%s\t" -msgstr "" +msgstr "%s\tMinőség: %s\n%s\t%s\t" -#: ../gtk/calllogs.c:341 +#: ../gtk/calllogs.c:358 #, c-format msgid "%s\t%s" -msgstr "" +msgstr "%s\t%s" -#: ../gtk/conference.c:38 ../gtk/main.ui.h:13 +#: ../gtk/conference.c:38 ../gtk/in_call_frame.ui.h:11 msgid "Conference" msgstr "Konferencia" @@ -87,297 +97,314 @@ msgstr "én" msgid "Couldn't find pixmap file: %s" msgstr "Nemtalálható a pixmap fájl: %s" -#: ../gtk/main.c:137 +#: ../gtk/chat.c:196 ../gtk/chat.c:254 +msgid "Sending..." +msgstr "" + +#: ../gtk/chat.c:213 ../gtk/chat.c:263 +msgid "Message not sent" +msgstr "" + +#: ../gtk/chat.c:472 +msgid "Copy" +msgstr "" + +#: ../gtk/main.c:138 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:138 +#: ../gtk/main.c:139 +msgid "display version and exit." +msgstr "" + +#: ../gtk/main.c:140 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:139 +#: ../gtk/main.c:141 msgid "Start linphone with video disabled." msgstr "Linphone indítása, videó kikpacsolva. " -#: ../gtk/main.c:140 +#: ../gtk/main.c:142 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:141 +#: ../gtk/main.c:143 msgid "address to call right now" msgstr "Cím azonnali híváshoz" -#: ../gtk/main.c:142 +#: ../gtk/main.c:144 msgid "" "Specifiy a working directory (should be the base of the installation, eg: " "c:\\Program Files\\Linphone)" 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:143 +#: ../gtk/main.c:145 msgid "Configuration file" msgstr "" -#: ../gtk/main.c:144 +#: ../gtk/main.c:146 msgid "Run the audio assistant" msgstr "" -#: ../gtk/main.c:145 +#: ../gtk/main.c:147 msgid "Run self test and exit 0 if succeed" msgstr "" -#: ../gtk/main.c:1070 +#: ../gtk/main.c:1046 #, c-format msgid "" -"%s would like to add you to his contact list.\n" -"Would you allow him to see your presence status or add him to your contact list ?\n" +"%s would like to add you to his/her contact list.\n" +"Would you add him/her to your contact list and allow him/her to see your presence status?\n" "If you answer no, this person will be temporarily blacklisted." -msgstr "%s szeretné Önt hozzáadni partnerlistájához.\nSzeretné megengedni neki, hogy lássa az Ön jelenlétét, illetve hozzá szeretné adni a partnerlistához?\nHa nemmel válaszol, ez a személy átmenetileg tiltólistára kerül." +msgstr "" -#: ../gtk/main.c:1147 +#: ../gtk/main.c:1123 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" msgstr "" -#: ../gtk/main.c:1268 +#: ../gtk/main.c:1253 msgid "Call error" msgstr "Hiba a hívás közben" -#: ../gtk/main.c:1271 ../coreapi/linphonecore.c:3846 +#: ../gtk/main.c:1256 ../coreapi/linphonecore.c:3813 msgid "Call ended" msgstr "Hívás vége" -#: ../gtk/main.c:1274 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1259 ../coreapi/call_log.c:235 msgid "Incoming call" msgstr "Beérkező hívás" -#: ../gtk/main.c:1276 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1261 ../gtk/incall_view.c:580 ../gtk/in_call_frame.ui.h:2 msgid "Answer" msgstr "Hívás fogadása" -#: ../gtk/main.c:1278 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1263 ../gtk/in_call_frame.ui.h:3 msgid "Decline" msgstr "Elutasítás" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 msgid "Call paused" msgstr "Hívás várakoztatva" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 #, c-format msgid "by %s" msgstr "a következő által: %s" -#: ../gtk/main.c:1354 +#: ../gtk/main.c:1339 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "%s szerené elidítani a videót. Elfogadja?" -#: ../gtk/main.c:1509 +#: ../gtk/main.c:1505 msgid "Website link" msgstr "Internetes oldal" -#: ../gtk/main.c:1568 ../gtk/waiting.ui.h:1 +#: ../gtk/main.c:1564 ../gtk/waiting.ui.h:1 msgid "Linphone" msgstr "Linphone" -#: ../gtk/main.c:1569 +#: ../gtk/main.c:1565 msgid "A video internet phone" msgstr "" -#: ../gtk/main.c:1629 +#: ../gtk/main.c:1624 #, c-format msgid "%s (Default)" msgstr "%s (Alapértelmezett)" -#: ../gtk/main.c:1962 ../coreapi/callbacks.c:1063 +#: ../gtk/main.c:1960 ../coreapi/callbacks.c:1075 #, c-format msgid "We are transferred to %s" msgstr "Át vagyunk irányítva ide: %s" -#: ../gtk/main.c:1972 +#: ../gtk/main.c:1970 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." msgstr "Hangkártya nincs érzékelve ezen a számítógépen.\nNem fog tudni hang hívásokat küldeni vagy fogadni." -#: ../gtk/main.c:2117 +#: ../gtk/main.c:2129 msgid "A free SIP video-phone" msgstr "Egy ingyenes SIP video-telefon" -#: ../gtk/main.c:2221 +#: ../gtk/main.c:2242 #, c-format msgid "Hello\n" msgstr "" -#: ../gtk/friendlist.c:505 +#: ../gtk/friendlist.c:461 msgid "Add to addressbook" msgstr "Hozzáadás címjegyzékhez" -#: ../gtk/friendlist.c:691 -msgid "Presence status" -msgstr "Jelenlét státusz" - -#: ../gtk/friendlist.c:709 ../gtk/propertybox.c:569 ../gtk/contact.ui.h:1 -msgid "Name" -msgstr "Név" - -#: ../gtk/friendlist.c:721 -msgid "Call" -msgstr "Hivás" - -#: ../gtk/friendlist.c:726 -msgid "Chat" -msgstr "Csevegés" - -#: ../gtk/friendlist.c:756 +#: ../gtk/friendlist.c:627 #, c-format msgid "Search in %s directory" msgstr "Keresés ebben a könyvtárban: %s" -#: ../gtk/friendlist.c:924 +#: ../gtk/friendlist.c:772 msgid "Invalid sip contact !" msgstr "Érvénytelen sip partner !" -#: ../gtk/friendlist.c:976 +#: ../gtk/friendlist.c:820 +#, c-format +msgid "Add a new contact" +msgstr "" + +#: ../gtk/friendlist.c:823 #, c-format msgid "Edit contact '%s'" msgstr "Kapcsolatinformációk szerkesztése: '%s'" -#: ../gtk/friendlist.c:977 +#: ../gtk/friendlist.c:824 #, c-format msgid "Delete contact '%s'" msgstr "'%s' partner törlése" -#: ../gtk/friendlist.c:978 +#: ../gtk/friendlist.c:825 #, c-format msgid "Delete chat history of '%s'" msgstr "" -#: ../gtk/friendlist.c:1029 +#: ../gtk/friendlist.c:862 #, c-format msgid "Add new contact from %s directory" msgstr "Új partner hozzáadása ebből a könyvtárból: %s" -#: ../gtk/propertybox.c:575 +#: ../gtk/propertybox.c:592 ../gtk/contact.ui.h:1 +msgid "Name" +msgstr "Név" + +#: ../gtk/propertybox.c:598 msgid "Rate (Hz)" msgstr "Érték (Hz)" -#: ../gtk/propertybox.c:581 +#: ../gtk/propertybox.c:604 msgid "Status" msgstr "Állapot" -#: ../gtk/propertybox.c:587 +#: ../gtk/propertybox.c:617 msgid "IP Bitrate (kbit/s)" msgstr "" -#: ../gtk/propertybox.c:596 +#: ../gtk/propertybox.c:628 msgid "Parameters" msgstr "Paraméterek" -#: ../gtk/propertybox.c:639 ../gtk/propertybox.c:782 +#: ../gtk/propertybox.c:670 ../gtk/propertybox.c:824 msgid "Enabled" msgstr "Engedélyezve" -#: ../gtk/propertybox.c:641 ../gtk/propertybox.c:782 ../gtk/parameters.ui.h:20 +#: ../gtk/propertybox.c:672 ../gtk/propertybox.c:824 ../gtk/parameters.ui.h:60 msgid "Disabled" msgstr "Tiltva" -#: ../gtk/propertybox.c:828 +#: ../gtk/propertybox.c:902 msgid "Account" msgstr "Hozzáférés" -#: ../gtk/propertybox.c:1091 +#: ../gtk/propertybox.c:1170 msgid "English" msgstr "angol" -#: ../gtk/propertybox.c:1092 +#: ../gtk/propertybox.c:1171 msgid "French" msgstr "francia" -#: ../gtk/propertybox.c:1093 +#: ../gtk/propertybox.c:1172 msgid "Swedish" msgstr "svéd" -#: ../gtk/propertybox.c:1094 +#: ../gtk/propertybox.c:1173 msgid "Italian" msgstr "olasz" -#: ../gtk/propertybox.c:1095 +#: ../gtk/propertybox.c:1174 msgid "Spanish" msgstr "spanyol" -#: ../gtk/propertybox.c:1096 +#: ../gtk/propertybox.c:1175 msgid "Brazilian Portugese" msgstr "brazil-portugál" -#: ../gtk/propertybox.c:1097 +#: ../gtk/propertybox.c:1176 msgid "Polish" msgstr "lengyel" -#: ../gtk/propertybox.c:1098 +#: ../gtk/propertybox.c:1177 msgid "German" msgstr "német" -#: ../gtk/propertybox.c:1099 +#: ../gtk/propertybox.c:1178 msgid "Russian" msgstr "orosz" -#: ../gtk/propertybox.c:1100 +#: ../gtk/propertybox.c:1179 msgid "Japanese" msgstr "japán" -#: ../gtk/propertybox.c:1101 +#: ../gtk/propertybox.c:1180 msgid "Dutch" msgstr "holland" -#: ../gtk/propertybox.c:1102 +#: ../gtk/propertybox.c:1181 msgid "Hungarian" msgstr "magyar" -#: ../gtk/propertybox.c:1103 +#: ../gtk/propertybox.c:1182 msgid "Czech" msgstr "cseh" -#: ../gtk/propertybox.c:1104 +#: ../gtk/propertybox.c:1183 msgid "Chinese" msgstr "egyszerúsített kínai" -#: ../gtk/propertybox.c:1105 +#: ../gtk/propertybox.c:1184 msgid "Traditional Chinese" msgstr "tradícionális kínai" -#: ../gtk/propertybox.c:1106 +#: ../gtk/propertybox.c:1185 msgid "Norwegian" msgstr "norvég" -#: ../gtk/propertybox.c:1107 +#: ../gtk/propertybox.c:1186 msgid "Hebrew" msgstr "héber" -#: ../gtk/propertybox.c:1108 +#: ../gtk/propertybox.c:1187 msgid "Serbian" -msgstr "" +msgstr "szerb" -#: ../gtk/propertybox.c:1175 +#: ../gtk/propertybox.c:1188 +msgid "Arabic" +msgstr "arab" + +#: ../gtk/propertybox.c:1189 +msgid "Turkish" +msgstr "török" + +#: ../gtk/propertybox.c:1246 msgid "" "You need to restart linphone for the new language selection to take effect." msgstr "Újra kell indítania a linphone-t, hogy az új nyelv kiválasztása érvényre jusson. " -#: ../gtk/propertybox.c:1255 +#: ../gtk/propertybox.c:1326 msgid "None" msgstr "Nincs" -#: ../gtk/propertybox.c:1259 +#: ../gtk/propertybox.c:1330 msgid "SRTP" msgstr "SRTP" -#: ../gtk/propertybox.c:1265 +#: ../gtk/propertybox.c:1336 msgid "DTLS" msgstr "" -#: ../gtk/propertybox.c:1272 +#: ../gtk/propertybox.c:1343 msgid "ZRTP" msgstr "ZRTP" @@ -419,324 +446,195 @@ msgid_plural "Found %i contacts" msgstr[0] "" msgstr[1] "" -#: ../gtk/setupwizard.c:32 -msgid "" -"Welcome!\n" -"This assistant will help you to use a SIP account for your calls." -msgstr "" - -#: ../gtk/setupwizard.c:41 -msgid "Create an account on linphone.org" -msgstr "Fiók létrehozása a linphone.org -on" - -#: ../gtk/setupwizard.c:42 -msgid "I have already a linphone.org account and I just want to use it" -msgstr "Már rendelkezem linphone.org fiókkal, azt szeretném használni" - -#: ../gtk/setupwizard.c:43 -msgid "I have already a sip account and I just want to use it" -msgstr "Már rendelkezem sip fiókkal, azt szeretném használni" - -#: ../gtk/setupwizard.c:44 -msgid "I want to specify a remote configuration URI" -msgstr "" - -#: ../gtk/setupwizard.c:87 -msgid "Enter your linphone.org username" -msgstr "Adja meg linphone.org felhasználónevét" - -#: ../gtk/setupwizard.c:100 ../gtk/parameters.ui.h:85 ../gtk/ldap.ui.h:4 -msgid "Username:" -msgstr "Felhasználónév:" - -#: ../gtk/setupwizard.c:102 ../gtk/password.ui.h:4 ../gtk/ldap.ui.h:5 -msgid "Password:" -msgstr "Jelszó:" - -#: ../gtk/setupwizard.c:122 -msgid "Enter your account informations" -msgstr "Írja be fiókinformációit" - -#: ../gtk/setupwizard.c:138 -msgid "Username*" -msgstr "Felhasználónév*" - -#: ../gtk/setupwizard.c:139 -msgid "Password*" -msgstr "Jelszó*" - -#: ../gtk/setupwizard.c:142 -msgid "Domain*" -msgstr "Tartomány" - -#: ../gtk/setupwizard.c:143 -msgid "Proxy" -msgstr "Proxy" - -#: ../gtk/setupwizard.c:322 -msgid "(*) Required fields" -msgstr "(*) Mező kitöltése szükséges" - -#: ../gtk/setupwizard.c:323 -msgid "Username: (*)" -msgstr "Felhasználónév: (*)" - -#: ../gtk/setupwizard.c:325 -msgid "Password: (*)" -msgstr "Jelszó: (*)" - -#: ../gtk/setupwizard.c:327 -msgid "Email: (*)" -msgstr "E-mail: (*)" - -#: ../gtk/setupwizard.c:329 -msgid "Confirm your password: (*)" -msgstr "Jelszó megerősítése: (*)" - -#: ../gtk/setupwizard.c:343 -msgid "Keep me informed with linphone updates" -msgstr "" - -#: ../gtk/setupwizard.c:399 -msgid "" -"Error, account not validated, username already used or server unreachable.\n" -"Please go back and try again." -msgstr "Hiba, a fiók nincs érvényesítve. Valaki már használja ezt a felhasználónevet vagy a kiszolgáló nem elérhető.\nKérjük, lépjen vissza és próbálja újra." - -#: ../gtk/setupwizard.c:410 -msgid "Thank you. Your account is now configured and ready for use." -msgstr "Köszönjük! Az Ön fiókját beállítottuk és használatra kész." - -#: ../gtk/setupwizard.c:418 -msgid "" -"Please validate your account by clicking on the link we just sent you by email.\n" -"Then come back here and press Next button." -msgstr "Kérjük, érvényesítse fiókját az általunk elektronikus levélben küldött hivatkozásra kattintva.\nAzután térjen vissza ide és kattintson a Következő gombra." - -#: ../gtk/setupwizard.c:609 -msgid "SIP account configuration assistant" -msgstr "" - -#: ../gtk/setupwizard.c:629 -msgid "Welcome to the account setup assistant" -msgstr "A fiók beállítása varázsló üdvözli Önt" - -#: ../gtk/setupwizard.c:634 -msgid "Account setup assistant" -msgstr "Fiók beállítása varázsló" - -#: ../gtk/setupwizard.c:640 -msgid "Configure your account (step 1/1)" -msgstr "Az Ön fiókjának beállítása (1/1 lépés)" - -#: ../gtk/setupwizard.c:645 -msgid "Enter your sip username (step 1/1)" -msgstr "Adja meg sip felhasználónevét (1/2 lépés)" - -#: ../gtk/setupwizard.c:649 -msgid "Enter account information (step 1/2)" -msgstr "Adja meg a fiókinformációt (1/2 lépés)" - -#: ../gtk/setupwizard.c:658 -msgid "Validation (step 2/2)" -msgstr "Érvényesítés (2/2 lépés)" - -#: ../gtk/setupwizard.c:663 -msgid "Error" -msgstr "Hiba" - -#: ../gtk/setupwizard.c:667 ../gtk/audio_assistant.c:534 -msgid "Terminating" -msgstr "Befejezés" - -#: ../gtk/incall_view.c:70 ../gtk/incall_view.c:94 +#: ../gtk/incall_view.c:67 ../gtk/incall_view.c:87 #, c-format msgid "Call #%i" msgstr "Hívás #%i" -#: ../gtk/incall_view.c:155 +#: ../gtk/incall_view.c:145 #, c-format msgid "Transfer to call #%i with %s" msgstr "Átirányítás #%i híváshoz ezzel: %s " -#: ../gtk/incall_view.c:211 ../gtk/incall_view.c:214 +#: ../gtk/incall_view.c:202 ../gtk/incall_view.c:205 msgid "Not used" msgstr "Nem használt" -#: ../gtk/incall_view.c:221 +#: ../gtk/incall_view.c:212 msgid "ICE not activated" msgstr "ICE nincs aktiválva" -#: ../gtk/incall_view.c:223 +#: ../gtk/incall_view.c:214 msgid "ICE failed" msgstr "ICE nem sikerült" -#: ../gtk/incall_view.c:225 +#: ../gtk/incall_view.c:216 msgid "ICE in progress" msgstr "ICE folyamatban" -#: ../gtk/incall_view.c:227 +#: ../gtk/incall_view.c:218 msgid "Going through one or more NATs" msgstr "Átmegy egy vagy több NAT-on" -#: ../gtk/incall_view.c:229 +#: ../gtk/incall_view.c:220 msgid "Direct" msgstr "Közvetlen" -#: ../gtk/incall_view.c:231 +#: ../gtk/incall_view.c:222 msgid "Through a relay server" msgstr "Közvetítő kiszolgálón keresztül" -#: ../gtk/incall_view.c:239 +#: ../gtk/incall_view.c:230 msgid "uPnP not activated" msgstr "uPnP nincs aktiválva" -#: ../gtk/incall_view.c:241 +#: ../gtk/incall_view.c:232 msgid "uPnP in progress" msgstr "uPnP folyamatban" -#: ../gtk/incall_view.c:243 +#: ../gtk/incall_view.c:234 msgid "uPnp not available" msgstr "uPnP nem elérhető" -#: ../gtk/incall_view.c:245 +#: ../gtk/incall_view.c:236 msgid "uPnP is running" msgstr "uPnP fut" -#: ../gtk/incall_view.c:247 +#: ../gtk/incall_view.c:238 msgid "uPnP failed" msgstr "uPnP nem sikerült" -#: ../gtk/incall_view.c:257 ../gtk/incall_view.c:258 +#: ../gtk/incall_view.c:248 ../gtk/incall_view.c:249 msgid "Direct or through server" msgstr "közvetlen vagy kiszolgálón keresztül" -#: ../gtk/incall_view.c:267 ../gtk/incall_view.c:279 +#: ../gtk/incall_view.c:258 ../gtk/incall_view.c:270 #, c-format msgid "" "download: %f\n" "upload: %f (kbit/s)" msgstr "letöltés: %f\nfeltöltés: %f (kbit/mp)" -#: ../gtk/incall_view.c:272 ../gtk/incall_view.c:274 +#: ../gtk/incall_view.c:263 ../gtk/incall_view.c:265 #, c-format msgid "%ix%i @ %f fps" msgstr "" -#: ../gtk/incall_view.c:304 +#: ../gtk/incall_view.c:295 #, c-format msgid "%.3f seconds" msgstr "%.3f másodperc" -#: ../gtk/incall_view.c:407 ../gtk/main.ui.h:12 ../gtk/videowindow.c:235 +#: ../gtk/incall_view.c:453 ../gtk/in_call_frame.ui.h:10 +#: ../gtk/videowindow.c:236 msgid "Hang up" msgstr "Befejezés" -#: ../gtk/incall_view.c:511 +#: ../gtk/incall_view.c:559 msgid "Calling..." msgstr "Hívás folyamatban..." -#: ../gtk/incall_view.c:514 ../gtk/incall_view.c:733 -msgid "00::00::00" -msgstr "00::00::00" +#: ../gtk/incall_view.c:562 ../gtk/incall_view.c:792 +msgid "00:00:00" +msgstr "00:00:00" -#: ../gtk/incall_view.c:525 +#: ../gtk/incall_view.c:573 msgid "Incoming call" msgstr "Beérkező hívás" -#: ../gtk/incall_view.c:562 +#: ../gtk/incall_view.c:610 msgid "good" msgstr "jó" -#: ../gtk/incall_view.c:564 +#: ../gtk/incall_view.c:612 msgid "average" msgstr "közepes" -#: ../gtk/incall_view.c:566 +#: ../gtk/incall_view.c:614 msgid "poor" msgstr "gyenge" -#: ../gtk/incall_view.c:568 +#: ../gtk/incall_view.c:616 msgid "very poor" msgstr "nagyon gyenge" -#: ../gtk/incall_view.c:570 +#: ../gtk/incall_view.c:618 msgid "too bad" msgstr "rossz" -#: ../gtk/incall_view.c:571 ../gtk/incall_view.c:587 +#: ../gtk/incall_view.c:619 ../gtk/incall_view.c:635 msgid "unavailable" msgstr "nem elérhető" -#: ../gtk/incall_view.c:679 +#: ../gtk/incall_view.c:731 msgid "Secured by SRTP" msgstr "SRTP-vel titkosítva" -#: ../gtk/incall_view.c:685 +#: ../gtk/incall_view.c:737 msgid "Secured by DTLS" msgstr "" -#: ../gtk/incall_view.c:691 +#: ../gtk/incall_view.c:743 #, c-format msgid "Secured by ZRTP - [auth token: %s]" msgstr "ZRTP-vel titkosítva - [hitelesítési jel: %s]" -#: ../gtk/incall_view.c:697 +#: ../gtk/incall_view.c:747 msgid "Set unverified" msgstr "Beállítás ellenőrizetlenként" -#: ../gtk/incall_view.c:697 ../gtk/main.ui.h:4 +#: ../gtk/incall_view.c:747 msgid "Set verified" msgstr "Beállítás ellenőrzöttként" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In conference" msgstr "Konferencián" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In call" msgstr "vonalban" -#: ../gtk/incall_view.c:764 +#: ../gtk/incall_view.c:824 msgid "Paused call" msgstr "Várakoztatott hívás" -#: ../gtk/incall_view.c:800 +#: ../gtk/incall_view.c:861 msgid "Call ended." msgstr "Hívás vége." -#: ../gtk/incall_view.c:831 +#: ../gtk/incall_view.c:892 msgid "Transfer in progress" msgstr "Átvitel folyamatban" -#: ../gtk/incall_view.c:834 +#: ../gtk/incall_view.c:895 msgid "Transfer done." msgstr "Átvitel befejezve." -#: ../gtk/incall_view.c:837 +#: ../gtk/incall_view.c:898 msgid "Transfer failed." msgstr "Az átvitel sikertelen." -#: ../gtk/incall_view.c:881 +#: ../gtk/incall_view.c:929 msgid "Resume" msgstr "Visszatérés" -#: ../gtk/incall_view.c:888 ../gtk/main.ui.h:9 +#: ../gtk/incall_view.c:929 ../gtk/in_call_frame.ui.h:7 msgid "Pause" msgstr "Várakoztatás" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 #, c-format msgid "" "Recording into\n" "%s %s" msgstr "Felvétel a következőbe\n%s %s" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 msgid "(Paused)" msgstr "(Várakoztatva)" -#: ../gtk/loginframe.c:87 +#: ../gtk/loginframe.c:75 #, c-format msgid "Please enter login information for %s" msgstr "Kérem, adja meg a bejelentkezési információt %s -hoz" @@ -751,263 +649,108 @@ msgstr "" msgid "Downloading of remote configuration from %s failed." msgstr "" -#: ../gtk/audio_assistant.c:98 +#: ../gtk/audio_assistant.c:103 msgid "No voice detected" msgstr "" -#: ../gtk/audio_assistant.c:99 +#: ../gtk/audio_assistant.c:104 msgid "Too low" msgstr "" -#: ../gtk/audio_assistant.c:100 +#: ../gtk/audio_assistant.c:105 msgid "Good" -msgstr "" +msgstr "Jó" -#: ../gtk/audio_assistant.c:101 +#: ../gtk/audio_assistant.c:106 msgid "Too loud" msgstr "" -#: ../gtk/audio_assistant.c:183 +#: ../gtk/audio_assistant.c:188 msgid "Did you hear three beeps ?" msgstr "" -#: ../gtk/audio_assistant.c:292 ../gtk/audio_assistant.c:297 +#: ../gtk/audio_assistant.c:299 ../gtk/audio_assistant.c:304 msgid "Sound preferences not found " msgstr "" -#: ../gtk/audio_assistant.c:306 +#: ../gtk/audio_assistant.c:313 msgid "Cannot launch system sound control " msgstr "" -#: ../gtk/audio_assistant.c:318 +#: ../gtk/audio_assistant.c:325 msgid "" "Welcome!\n" "This assistant will help you to configure audio settings for Linphone" msgstr "" -#: ../gtk/audio_assistant.c:328 +#: ../gtk/audio_assistant.c:335 msgid "Capture device" msgstr "" -#: ../gtk/audio_assistant.c:329 +#: ../gtk/audio_assistant.c:336 msgid "Recorded volume" msgstr "" -#: ../gtk/audio_assistant.c:333 +#: ../gtk/audio_assistant.c:340 msgid "No voice" msgstr "" -#: ../gtk/audio_assistant.c:334 ../gtk/audio_assistant.c:373 +#: ../gtk/audio_assistant.c:341 ../gtk/audio_assistant.c:380 msgid "System sound preferences" msgstr "" -#: ../gtk/audio_assistant.c:369 +#: ../gtk/audio_assistant.c:376 msgid "Playback device" msgstr "" -#: ../gtk/audio_assistant.c:370 +#: ../gtk/audio_assistant.c:377 msgid "Play three beeps" msgstr "" -#: ../gtk/audio_assistant.c:403 +#: ../gtk/audio_assistant.c:410 msgid "Press the record button and say some words" msgstr "" -#: ../gtk/audio_assistant.c:404 +#: ../gtk/audio_assistant.c:411 msgid "Listen to your record voice" msgstr "" -#: ../gtk/audio_assistant.c:405 +#: ../gtk/audio_assistant.c:412 ../gtk/conf_frame.ui.h:2 +#: ../gtk/in_call_frame.ui.h:4 msgid "Record" msgstr "" -#: ../gtk/audio_assistant.c:406 +#: ../gtk/audio_assistant.c:413 msgid "Play" msgstr "" -#: ../gtk/audio_assistant.c:433 +#: ../gtk/audio_assistant.c:440 msgid "Let's start Linphone now" msgstr "" -#: ../gtk/audio_assistant.c:503 +#: ../gtk/audio_assistant.c:510 msgid "Audio Assistant" msgstr "" -#: ../gtk/audio_assistant.c:513 ../gtk/main.ui.h:32 +#: ../gtk/audio_assistant.c:520 ../gtk/main.ui.h:13 msgid "Audio assistant" msgstr "" -#: ../gtk/audio_assistant.c:518 +#: ../gtk/audio_assistant.c:525 msgid "Mic Gain calibration" msgstr "" -#: ../gtk/audio_assistant.c:524 +#: ../gtk/audio_assistant.c:531 msgid "Speaker volume calibration" msgstr "" -#: ../gtk/audio_assistant.c:529 +#: ../gtk/audio_assistant.c:536 msgid "Record and Play" msgstr "" -#: ../gtk/main.ui.h:1 -msgid "Callee name" -msgstr "Hívott neve" - -#: ../gtk/main.ui.h:2 -msgid "Send" -msgstr "Küld" - -#: ../gtk/main.ui.h:3 -msgid "End conference" -msgstr "Konferencia vége" - -#: ../gtk/main.ui.h:7 -msgid "Record this call to an audio file" -msgstr "Beszélgetés felvétele hangfájlba" - -#: ../gtk/main.ui.h:8 -msgid "Video" -msgstr "Videó" - -#: ../gtk/main.ui.h:10 -msgid "Mute" -msgstr "Elnémítás" - -#: ../gtk/main.ui.h:11 -msgid "Transfer" -msgstr "Átvitel" - -#: ../gtk/main.ui.h:14 -msgid "In call" -msgstr "vonalban" - -#: ../gtk/main.ui.h:15 -msgid "Duration" -msgstr "Időtartam" - -#: ../gtk/main.ui.h:16 -msgid "Call quality rating" -msgstr "Hívásminőség" - -#: ../gtk/main.ui.h:17 -msgid "All users" -msgstr "Minden felhasználó" - -#: ../gtk/main.ui.h:18 -msgid "Online users" -msgstr "Elérhető" - -#: ../gtk/main.ui.h:19 -msgid "ADSL" -msgstr "ADSL" - -#: ../gtk/main.ui.h:20 -msgid "Fiber Channel" -msgstr "Fiber csatorna" - -#: ../gtk/main.ui.h:21 -msgid "Default" -msgstr "Alapértelmezett" - -#: ../gtk/main.ui.h:22 -msgid "Delete" -msgstr "Törlés" - -#: ../gtk/main.ui.h:23 -msgid "_Options" -msgstr "_Beállítások" - -#: ../gtk/main.ui.h:24 -msgid "Set configuration URI" -msgstr "" - -#: ../gtk/main.ui.h:25 -msgid "Always start video" -msgstr "Videó indítása mindig" - -#: ../gtk/main.ui.h:26 -msgid "Enable self-view" -msgstr "Saját nézet" - -#: ../gtk/main.ui.h:27 -msgid "_Help" -msgstr "_Segítség" - -#: ../gtk/main.ui.h:28 -msgid "Show debug window" -msgstr "Hibakeresési ablak mutatása" - -#: ../gtk/main.ui.h:29 -msgid "_Homepage" -msgstr "_Honlap" - -#: ../gtk/main.ui.h:30 -msgid "Check _Updates" -msgstr "Frissítések keresése" - -#: ../gtk/main.ui.h:31 -msgid "Account assistant" -msgstr "Fiók varázsló" - -#: ../gtk/main.ui.h:33 -msgid "SIP address or phone number:" -msgstr "Adja meg a SIP címet vagy a telefonszámot:" - -#: ../gtk/main.ui.h:34 -msgid "Initiate a new call" -msgstr "Új hívás kezdeményezése" - -#: ../gtk/main.ui.h:35 -msgid "Contacts" -msgstr "Partnerek" - -#: ../gtk/main.ui.h:36 -msgid "Search" -msgstr "Keresés" - -#: ../gtk/main.ui.h:37 -msgid "Add contacts from directory" -msgstr "Partnerek hozzáadása könyvtárból" - -#: ../gtk/main.ui.h:38 -msgid "Add contact" -msgstr "Partner hozzáadása" - -#: ../gtk/main.ui.h:39 -msgid "Recent calls" -msgstr "Legutóbbi hívások" - -#: ../gtk/main.ui.h:40 -msgid "My current identity:" -msgstr "Jelenlegi identitásom:" - -#: ../gtk/main.ui.h:41 ../gtk/tunnel_config.ui.h:7 -msgid "Username" -msgstr "Felhasználónév" - -#: ../gtk/main.ui.h:42 ../gtk/tunnel_config.ui.h:8 -msgid "Password" -msgstr "Jelszó" - -#: ../gtk/main.ui.h:43 -msgid "Internet connection:" -msgstr "Internet kapcsolat:" - -#: ../gtk/main.ui.h:44 -msgid "Automatically log me in" -msgstr "Jelentkeztessen be automatikusan" - -#: ../gtk/main.ui.h:45 ../gtk/password.ui.h:3 -msgid "UserID" -msgstr "Felhasználó azonosító" - -#: ../gtk/main.ui.h:46 -msgid "Login information" -msgstr "Bejelentkezési információ" - -#: ../gtk/main.ui.h:47 -msgid "Welcome!" -msgstr "" +#: ../gtk/audio_assistant.c:541 ../gtk/setup_wizard.ui.h:38 +msgid "Terminating" +msgstr "Befejezés" #: ../gtk/about.ui.h:1 msgid "About Linphone" @@ -1037,456 +780,6 @@ msgid "" "he: Eli Zaretskii \n" msgstr "" -#: ../gtk/contact.ui.h:2 -msgid "SIP Address" -msgstr "SIP cím" - -#: ../gtk/contact.ui.h:3 -msgid "Show this contact presence status" -msgstr "A partner jelenlétének mutatása" - -#: ../gtk/contact.ui.h:4 -msgid "Allow this contact to see my presence status" -msgstr "Megengedem ennek a partnernek, hogy lássa a jelenlétemet" - -#: ../gtk/contact.ui.h:5 -msgid "Contact information" -msgstr "Partner információ" - -#: ../gtk/log.ui.h:1 -msgid "Linphone debug window" -msgstr "Linphone Hibakereső Ablak" - -#: ../gtk/log.ui.h:2 -msgid "Scroll to end" -msgstr "Görgetés a végéhez" - -#: ../gtk/password.ui.h:1 -msgid "Linphone - Authentication required" -msgstr "Linphone - Hitelesítés szükséges" - -#: ../gtk/password.ui.h:2 -msgid "Please enter the domain password" -msgstr "Kérem adja meg a tartomány jelszavát" - -#: ../gtk/call_logs.ui.h:1 -msgid "Call history" -msgstr "Híváselőzmények" - -#: ../gtk/call_logs.ui.h:2 -msgid "Clear all" -msgstr "Mind törlése" - -#: ../gtk/call_logs.ui.h:3 -msgid "Call back" -msgstr "Visszahívás" - -#: ../gtk/sip_account.ui.h:1 -msgid "Linphone - Configure a SIP account" -msgstr "Linphone - SIP fiók beállítása" - -#: ../gtk/sip_account.ui.h:2 -msgid "Your SIP identity:" -msgstr "Az Ön SIP azonosítója:" - -#: ../gtk/sip_account.ui.h:3 -msgid "Looks like sip:@" -msgstr "Így néz ki: sip:@" - -#: ../gtk/sip_account.ui.h:4 -msgid "sip:" -msgstr "sip:" - -#: ../gtk/sip_account.ui.h:5 -msgid "SIP Proxy address:" -msgstr "SIP Proxy cím:" - -#: ../gtk/sip_account.ui.h:6 -msgid "Looks like sip:" -msgstr "Így néz ki: sip:" - -#: ../gtk/sip_account.ui.h:7 -msgid "Registration duration (sec):" -msgstr "Regisztrálási Időköz (mp):" - -#: ../gtk/sip_account.ui.h:8 -msgid "Contact params (optional):" -msgstr "" - -#: ../gtk/sip_account.ui.h:9 -msgid "AVPF regular RTCP interval (sec):" -msgstr "" - -#: ../gtk/sip_account.ui.h:10 -msgid "Route (optional):" -msgstr "Út (nem kötelező):" - -#: ../gtk/sip_account.ui.h:11 -msgid "Transport" -msgstr "" - -#: ../gtk/sip_account.ui.h:12 -msgid "Register" -msgstr "Regisztráció" - -#: ../gtk/sip_account.ui.h:13 -msgid "Publish presence information" -msgstr "Jelenléti információ közlése" - -#: ../gtk/sip_account.ui.h:14 -msgid "Enable AVPF" -msgstr "" - -#: ../gtk/sip_account.ui.h:15 -msgid "Configure a SIP account" -msgstr "SIP fiók beállítása" - -#: ../gtk/parameters.ui.h:1 -msgid "anonymous" -msgstr "" - -#: ../gtk/parameters.ui.h:2 -msgid "GSSAPI" -msgstr "" - -#: ../gtk/parameters.ui.h:3 -msgid "SASL" -msgstr "" - -#: ../gtk/parameters.ui.h:4 -msgid "default soundcard" -msgstr "alapértelmezett hangkártya" - -#: ../gtk/parameters.ui.h:5 -msgid "a sound card" -msgstr "egy hangkártya" - -#: ../gtk/parameters.ui.h:6 -msgid "default camera" -msgstr "alapértelmezett kamera" - -#: ../gtk/parameters.ui.h:7 -msgid "CIF" -msgstr "CIF" - -#: ../gtk/parameters.ui.h:8 -msgid "Audio codecs" -msgstr "Audió kódekek" - -#: ../gtk/parameters.ui.h:9 -msgid "Video codecs" -msgstr "Videó kódekek" - -#: ../gtk/parameters.ui.h:10 -msgid "C" -msgstr "C" - -#: ../gtk/parameters.ui.h:11 -msgid "SIP (UDP)" -msgstr "SIP (UDP)" - -#: ../gtk/parameters.ui.h:12 -msgid "SIP (TCP)" -msgstr "SIP (TCP)" - -#: ../gtk/parameters.ui.h:13 -msgid "SIP (TLS)" -msgstr "SIP (TLS)" - -#: ../gtk/parameters.ui.h:14 -msgid "Settings" -msgstr "Beállítások" - -#: ../gtk/parameters.ui.h:15 -msgid "Set Maximum Transmission Unit:" -msgstr "Maximum Továbbítási Egység beállítása:" - -#: ../gtk/parameters.ui.h:16 -msgid "Send DTMFs as SIP info" -msgstr "DTMF küldése SIP infóként" - -#: ../gtk/parameters.ui.h:17 -msgid "Allow IPv6" -msgstr "" - -#: ../gtk/parameters.ui.h:18 -msgid "Transport" -msgstr "Átvitel" - -#: ../gtk/parameters.ui.h:19 -msgid "SIP/UDP port" -msgstr "" - -#: ../gtk/parameters.ui.h:21 -msgid "Random" -msgstr "" - -#: ../gtk/parameters.ui.h:22 -msgid "SIP/TCP port" -msgstr "" - -#: ../gtk/parameters.ui.h:23 -msgid "Audio RTP/UDP:" -msgstr "Audió RTP/UDP:" - -#: ../gtk/parameters.ui.h:24 -msgid "Fixed" -msgstr "Javítva" - -#: ../gtk/parameters.ui.h:25 -msgid "Video RTP/UDP:" -msgstr "Videó RTP/UDP:" - -#: ../gtk/parameters.ui.h:26 -msgid "Media encryption type" -msgstr "Média titkosítás típusa" - -#: ../gtk/parameters.ui.h:27 -msgid "Media encryption is mandatory" -msgstr "Média titkosítás kötelező" - -#: ../gtk/parameters.ui.h:28 -msgid "Tunnel" -msgstr "Alagút" - -#: ../gtk/parameters.ui.h:29 -msgid "DSCP fields" -msgstr "DSCP mezők" - -#: ../gtk/parameters.ui.h:30 -msgid "Network protocol and ports" -msgstr "Hálózati protokoll és port" - -#: ../gtk/parameters.ui.h:31 -msgid "Direct connection to the Internet" -msgstr "Közvetlen Internet kapcsolat" - -#: ../gtk/parameters.ui.h:32 -msgid "Behind NAT / Firewall (specify gateway IP )" -msgstr "" - -#: ../gtk/parameters.ui.h:33 -msgid "Behind NAT / Firewall (use STUN to resolve)" -msgstr "NAT / tűzfal mögött (STUN használata a feloldáshoz)" - -#: ../gtk/parameters.ui.h:34 -msgid "Behind NAT / Firewall (use ICE)" -msgstr "NAT / tűzfal mögött (ICE használata)" - -#: ../gtk/parameters.ui.h:35 -msgid "Behind NAT / Firewall (use uPnP)" -msgstr "NAT / tűzfal mögött (uPnP használata)" - -#: ../gtk/parameters.ui.h:36 -msgid "Public IP address:" -msgstr "Publikus IP cím:" - -#: ../gtk/parameters.ui.h:37 -msgid "Stun server:" -msgstr "STUN kiszolgáló:" - -#: ../gtk/parameters.ui.h:38 -msgid "NAT and Firewall" -msgstr "NAT és tűzfal" - -#: ../gtk/parameters.ui.h:39 -msgid "Network settings" -msgstr "Hálózati beállítások" - -#: ../gtk/parameters.ui.h:40 -msgid "Ring sound:" -msgstr "Csengőhang:" - -#: ../gtk/parameters.ui.h:41 -msgid "ALSA special device (optional):" -msgstr "Különleges ALSA eszköz (nem kötelező):" - -#: ../gtk/parameters.ui.h:42 -msgid "Capture device:" -msgstr "Felvevő hang eszköz:" - -#: ../gtk/parameters.ui.h:43 -msgid "Ring device:" -msgstr "Csengőhang eszköz:" - -#: ../gtk/parameters.ui.h:44 -msgid "Playback device:" -msgstr "Lejátszó hang eszköz:" - -#: ../gtk/parameters.ui.h:45 -msgid "Enable echo cancellation" -msgstr "Visszhang-elnyomás engedélyezése" - -#: ../gtk/parameters.ui.h:46 -msgid "Audio" -msgstr "Audió" - -#: ../gtk/parameters.ui.h:47 -msgid "Video input device:" -msgstr "Videó bemeneti eszköz:" - -#: ../gtk/parameters.ui.h:48 -msgid "Prefered video resolution:" -msgstr "Kívánt videó felbontás:" - -#: ../gtk/parameters.ui.h:49 -msgid "Video output method:" -msgstr "" - -#: ../gtk/parameters.ui.h:50 -msgid "Show camera preview" -msgstr "" - -#: ../gtk/parameters.ui.h:51 -msgid "Video" -msgstr "Videó" - -#: ../gtk/parameters.ui.h:52 -msgid "Multimedia settings" -msgstr "Multimédia beállítások" - -#: ../gtk/parameters.ui.h:53 -msgid "This section defines your SIP address when not using a SIP account" -msgstr "Ez a rész határozza meg az Ön SIP címét, amikor nem használ SIP fiókot" - -#: ../gtk/parameters.ui.h:54 -msgid "Your display name (eg: John Doe):" -msgstr "Az Ön megjelenített neve (pl. Kis József):" - -#: ../gtk/parameters.ui.h:55 -msgid "Your username:" -msgstr "Az Ön felhasználóneve:" - -#: ../gtk/parameters.ui.h:56 -msgid "Your resulting SIP address:" -msgstr "Az Ön így keletkezett SIP címe:" - -#: ../gtk/parameters.ui.h:57 -msgid "Default identity" -msgstr "Alapértelmezett identitás" - -#: ../gtk/parameters.ui.h:58 -msgid "Wizard" -msgstr "Varázsló" - -#: ../gtk/parameters.ui.h:59 -msgid "Add" -msgstr "Hozzáadás" - -#: ../gtk/parameters.ui.h:60 -msgid "Edit" -msgstr "Szerkesztés" - -#: ../gtk/parameters.ui.h:61 -msgid "Remove" -msgstr "Eltávolítás" - -#: ../gtk/parameters.ui.h:62 -msgid "Proxy accounts" -msgstr "Proxy fiókok" - -#: ../gtk/parameters.ui.h:63 -msgid "Erase all passwords" -msgstr "Minden kulcsszó törlése" - -#: ../gtk/parameters.ui.h:64 -msgid "Privacy" -msgstr "Titoktartás" - -#: ../gtk/parameters.ui.h:65 -msgid "Automatically answer when a call is received" -msgstr "" - -#: ../gtk/parameters.ui.h:66 -msgid "Delay before answering (ms)" -msgstr "" - -#: ../gtk/parameters.ui.h:67 -msgid "Auto-answer" -msgstr "" - -#: ../gtk/parameters.ui.h:68 -msgid "Manage SIP Accounts" -msgstr "SIP fiókok beállítása" - -#: ../gtk/parameters.ui.h:69 ../gtk/tunnel_config.ui.h:4 -msgid "Enable" -msgstr "Engedélyezés" - -#: ../gtk/parameters.ui.h:70 ../gtk/tunnel_config.ui.h:5 -msgid "Disable" -msgstr "Tiltás" - -#: ../gtk/parameters.ui.h:71 -msgid "Codecs" -msgstr "Kódekek" - -#: ../gtk/parameters.ui.h:72 -msgid "0 stands for \"unlimited\"" -msgstr "A 0 jelentése \"végtelen\"" - -#: ../gtk/parameters.ui.h:73 -msgid "Upload speed limit in Kbit/sec:" -msgstr "Feltöltési sebesség korlát (kbit/mp):" - -#: ../gtk/parameters.ui.h:74 -msgid "Download speed limit in Kbit/sec:" -msgstr "Letöltési sebesség korlát (kbit/mp):" - -#: ../gtk/parameters.ui.h:75 -msgid "Enable adaptive rate control" -msgstr "Alkalmazkodó mérték-szabályozás engedélyezése" - -#: ../gtk/parameters.ui.h:76 -msgid "" -"Adaptive rate control is a technique to dynamically guess the available " -"bandwidth during a call." -msgstr "Az alkalmazkodó mérték-szabályozás egy módszer, mely erőteljesen próbálja megállapítani a rendelkezésre álló sávszélességet hívás alatt." - -#: ../gtk/parameters.ui.h:77 -msgid "Bandwidth control" -msgstr "Sávszélesség szabályozása" - -#: ../gtk/parameters.ui.h:78 -msgid "Codecs" -msgstr "Kódekek" - -#: ../gtk/parameters.ui.h:79 -msgid "Language" -msgstr "Nyelv" - -#: ../gtk/parameters.ui.h:80 -msgid "Show advanced settings" -msgstr "Haladó beállítások megjelenítése" - -#: ../gtk/parameters.ui.h:81 -msgid "Level" -msgstr "Szint" - -#: ../gtk/parameters.ui.h:82 -msgid "User interface" -msgstr "Felhasználói környezet" - -#: ../gtk/parameters.ui.h:83 ../gtk/ldap.ui.h:2 -msgid "Server address:" -msgstr "" - -#: ../gtk/parameters.ui.h:84 ../gtk/ldap.ui.h:3 -msgid "Authentication method:" -msgstr "" - -#: ../gtk/parameters.ui.h:86 -msgid "LDAP Account setup" -msgstr "" - -#: ../gtk/parameters.ui.h:87 -msgid "LDAP" -msgstr "" - -#: ../gtk/parameters.ui.h:88 -msgid "Done" -msgstr "Kész" - #: ../gtk/buddylookup.ui.h:1 msgid "Search contacts in directory" msgstr "Partnerek keresése könyvtárban" @@ -1499,29 +792,21 @@ msgstr "Hozzáadása a listámhoz" msgid "Search somebody" msgstr "Keres valakit" -#: ../gtk/waiting.ui.h:2 -msgid "Please wait" -msgstr "Kérem várjon" +#: ../gtk/callee_frame.ui.h:1 +msgid "Callee name" +msgstr "Hívott neve" -#: ../gtk/dscp_settings.ui.h:1 -msgid "DSCP settings" -msgstr "" +#: ../gtk/call_logs.ui.h:1 +msgid "Call history" +msgstr "Híváselőzmények" -#: ../gtk/dscp_settings.ui.h:2 -msgid "SIP" -msgstr "SIP" +#: ../gtk/call_logs.ui.h:2 +msgid "Clear all" +msgstr "Mind törlése" -#: ../gtk/dscp_settings.ui.h:3 -msgid "Audio RTP stream" -msgstr "Audió RTP folyam" - -#: ../gtk/dscp_settings.ui.h:4 -msgid "Video RTP stream" -msgstr "Videó RTP folyam" - -#: ../gtk/dscp_settings.ui.h:5 -msgid "Set DSCP values (in hexadecimal)" -msgstr "DSCP értékek beállítása (hexadecimális)" +#: ../gtk/call_logs.ui.h:3 +msgid "Call back" +msgstr "Visszahívás" #: ../gtk/call_statistics.ui.h:1 msgid "Call statistics" @@ -1571,30 +856,112 @@ msgstr "" msgid "Call statistics and information" msgstr "Hívási statisztika és információ" -#: ../gtk/tunnel_config.ui.h:1 -msgid "Configure VoIP tunnel" -msgstr "VoIP alagút beállítása" +#: ../gtk/chatroom_frame.ui.h:1 +msgid "Send" +msgstr "Küld" -#: ../gtk/tunnel_config.ui.h:2 -msgid "Host" -msgstr "Hoszt" +#: ../gtk/conf_frame.ui.h:1 +msgid "End conference" +msgstr "Konferencia vége" -#: ../gtk/tunnel_config.ui.h:3 -msgid "Port" -msgstr "Port" +#: ../gtk/config-uri.ui.h:1 +msgid "Specifying a remote configuration URI" +msgstr "" -#: ../gtk/tunnel_config.ui.h:6 -msgid "Configure tunnel" -msgstr "Alagút beállítása" +#: ../gtk/config-uri.ui.h:2 +msgid "" +"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" +"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " +msgstr "" -#: ../gtk/tunnel_config.ui.h:9 -msgid "Configure http proxy (optional)" -msgstr "http proxy beállítása (nem kötelező)" +#: ../gtk/contact.ui.h:2 +msgid "SIP Address" +msgstr "SIP cím" + +#: ../gtk/contact.ui.h:3 +msgid "Show this contact presence status" +msgstr "A partner jelenlétének mutatása" + +#: ../gtk/contact.ui.h:4 +msgid "Allow this contact to see my presence status" +msgstr "Megengedem ennek a partnernek, hogy lássa a jelenlétemet" + +#: ../gtk/contact.ui.h:5 +msgid "Contact information" +msgstr "Partner információ" + +#: ../gtk/dscp_settings.ui.h:1 +msgid "DSCP settings" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:2 +msgid "SIP" +msgstr "SIP" + +#: ../gtk/dscp_settings.ui.h:3 +msgid "Audio RTP stream" +msgstr "Audió RTP folyam" + +#: ../gtk/dscp_settings.ui.h:4 +msgid "Video RTP stream" +msgstr "Videó RTP folyam" + +#: ../gtk/dscp_settings.ui.h:5 +msgid "Set DSCP values (in hexadecimal)" +msgstr "DSCP értékek beállítása (hexadecimális)" + +#: ../gtk/in_call_frame.ui.h:1 +msgid "Click here to set the speakers volume" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:5 +msgid "Record this call to an audio file" +msgstr "Beszélgetés felvétele hangfájlba" + +#: ../gtk/in_call_frame.ui.h:6 +msgid "Video" +msgstr "Videó" + +#: ../gtk/in_call_frame.ui.h:8 +msgid "Mute" +msgstr "Elnémítás" + +#: ../gtk/in_call_frame.ui.h:9 +msgid "Transfer" +msgstr "Átvitel" + +#: ../gtk/in_call_frame.ui.h:12 +msgid "In call" +msgstr "vonalban" + +#: ../gtk/in_call_frame.ui.h:13 +msgid "Duration" +msgstr "Időtartam" + +#: ../gtk/in_call_frame.ui.h:14 +msgid "Call quality rating" +msgstr "Hívásminőség" #: ../gtk/ldap.ui.h:1 msgid "LDAP Settings" msgstr "" +#: ../gtk/ldap.ui.h:2 ../gtk/parameters.ui.h:89 +msgid "Server address:" +msgstr "" + +#: ../gtk/ldap.ui.h:3 ../gtk/parameters.ui.h:90 +msgid "Authentication method:" +msgstr "" + +#: ../gtk/ldap.ui.h:4 ../gtk/parameters.ui.h:91 ../gtk/setup_wizard.ui.h:17 +msgid "Username:" +msgstr "Felhasználónév:" + +#: ../gtk/ldap.ui.h:5 ../gtk/password.ui.h:4 ../gtk/setup_wizard.ui.h:18 +msgid "Password:" +msgstr "Jelszó:" + #: ../gtk/ldap.ui.h:6 msgid "Use TLS Connection" msgstr "" @@ -1680,16 +1047,504 @@ msgstr "" msgid "NTLM" msgstr "" -#: ../gtk/config-uri.ui.h:1 -msgid "Specifying a remote configuration URI" +#: ../gtk/login_frame.ui.h:1 ../gtk/tunnel_config.ui.h:7 +msgid "Username" +msgstr "Felhasználónév" + +#: ../gtk/login_frame.ui.h:2 ../gtk/tunnel_config.ui.h:8 +msgid "Password" +msgstr "Jelszó" + +#: ../gtk/login_frame.ui.h:3 +msgid "Internet connection:" +msgstr "Internet kapcsolat:" + +#: ../gtk/login_frame.ui.h:4 +msgid "Automatically log me in" +msgstr "Jelentkeztessen be automatikusan" + +#: ../gtk/login_frame.ui.h:5 ../gtk/password.ui.h:3 +msgid "UserID" +msgstr "Felhasználó azonosító" + +#: ../gtk/login_frame.ui.h:6 +msgid "Login information" +msgstr "Bejelentkezési információ" + +#: ../gtk/login_frame.ui.h:7 +msgid "Welcome!" msgstr "" -#: ../gtk/config-uri.ui.h:2 -msgid "" -"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" -"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " +#: ../gtk/login_frame.ui.h:8 +msgid "ADSL" +msgstr "ADSL" + +#: ../gtk/login_frame.ui.h:9 +msgid "Fiber Channel" +msgstr "Fiber csatorna" + +#: ../gtk/log.ui.h:1 +msgid "Linphone debug window" +msgstr "Linphone Hibakereső Ablak" + +#: ../gtk/log.ui.h:2 +msgid "Scroll to end" +msgstr "Görgetés a végéhez" + +#: ../gtk/main.ui.h:1 +msgid "Default" +msgstr "Alapértelmezett" + +#: ../gtk/main.ui.h:2 +msgid "Delete" +msgstr "Törlés" + +#: ../gtk/main.ui.h:3 +msgid "_Options" +msgstr "_Beállítások" + +#: ../gtk/main.ui.h:4 +msgid "Set configuration URI" msgstr "" +#: ../gtk/main.ui.h:5 +msgid "Always start video" +msgstr "Videó indítása mindig" + +#: ../gtk/main.ui.h:6 +msgid "Enable self-view" +msgstr "Saját nézet" + +#: ../gtk/main.ui.h:7 +msgid "Show keypad" +msgstr "" + +#: ../gtk/main.ui.h:8 +msgid "_Help" +msgstr "_Segítség" + +#: ../gtk/main.ui.h:9 +msgid "Show debug window" +msgstr "Hibakeresési ablak mutatása" + +#: ../gtk/main.ui.h:10 +msgid "_Homepage" +msgstr "_Honlap" + +#: ../gtk/main.ui.h:11 +msgid "Check _Updates" +msgstr "Frissítések keresése" + +#: ../gtk/main.ui.h:12 +msgid "Account assistant" +msgstr "Fiók varázsló" + +#: ../gtk/main.ui.h:14 +msgid "SIP address or phone number:" +msgstr "Adja meg a SIP címet vagy a telefonszámot:" + +#: ../gtk/main.ui.h:15 +msgid "Initiate a new call" +msgstr "Új hívás kezdeményezése" + +#: ../gtk/main.ui.h:16 +msgid "Contacts" +msgstr "Partnerek" + +#: ../gtk/main.ui.h:17 +msgid "Search" +msgstr "Keresés" + +#: ../gtk/main.ui.h:18 +msgid "Add contacts from directory" +msgstr "Partnerek hozzáadása könyvtárból" + +#: ../gtk/main.ui.h:19 +msgid "Add contact" +msgstr "Partner hozzáadása" + +#: ../gtk/main.ui.h:20 +msgid "Clear call history" +msgstr "" + +#: ../gtk/main.ui.h:22 +msgid "My current identity:" +msgstr "Jelenlegi identitásom:" + +#: ../gtk/main.ui.h:23 +msgid "Autoanswer is enabled" +msgstr "" + +#: ../gtk/parameters.ui.h:1 +msgid "anonymous" +msgstr "" + +#: ../gtk/parameters.ui.h:2 +msgid "GSSAPI" +msgstr "" + +#: ../gtk/parameters.ui.h:3 +msgid "SASL" +msgstr "" + +#: ../gtk/parameters.ui.h:4 +msgid "default soundcard" +msgstr "alapértelmezett hangkártya" + +#: ../gtk/parameters.ui.h:5 +msgid "a sound card" +msgstr "egy hangkártya" + +#: ../gtk/parameters.ui.h:6 +msgid "default camera" +msgstr "alapértelmezett kamera" + +#: ../gtk/parameters.ui.h:7 +msgid "CIF" +msgstr "CIF" + +#: ../gtk/parameters.ui.h:8 +msgid "Audio codecs" +msgstr "Audió kódekek" + +#: ../gtk/parameters.ui.h:9 +msgid "Video codecs" +msgstr "Videó kódekek" + +#: ../gtk/parameters.ui.h:10 +msgid "C" +msgstr "C" + +#: ../gtk/parameters.ui.h:11 +msgid "SIP (UDP)" +msgstr "SIP (UDP)" + +#: ../gtk/parameters.ui.h:12 +msgid "SIP (TCP)" +msgstr "SIP (TCP)" + +#: ../gtk/parameters.ui.h:13 +msgid "SIP (TLS)" +msgstr "SIP (TLS)" + +#: ../gtk/parameters.ui.h:14 +msgid "default" +msgstr "" + +#: ../gtk/parameters.ui.h:15 +msgid "high-fps" +msgstr "" + +#: ../gtk/parameters.ui.h:16 +msgid "custom" +msgstr "" + +#: ../gtk/parameters.ui.h:17 +msgid "Settings" +msgstr "Beállítások" + +#: ../gtk/parameters.ui.h:18 +msgid "This section defines your SIP address when not using a SIP account" +msgstr "Ez a rész határozza meg az Ön SIP címét, amikor nem használ SIP fiókot" + +#: ../gtk/parameters.ui.h:19 +msgid "Your display name (eg: John Doe):" +msgstr "Az Ön megjelenített neve (pl. Kis József):" + +#: ../gtk/parameters.ui.h:20 +msgid "Your username:" +msgstr "Az Ön felhasználóneve:" + +#: ../gtk/parameters.ui.h:21 +msgid "Your resulting SIP address:" +msgstr "Az Ön így keletkezett SIP címe:" + +#: ../gtk/parameters.ui.h:22 +msgid "Default identity" +msgstr "Alapértelmezett identitás" + +#: ../gtk/parameters.ui.h:23 +msgid "Wizard" +msgstr "Varázsló" + +#: ../gtk/parameters.ui.h:24 +msgid "Add" +msgstr "Hozzáadás" + +#: ../gtk/parameters.ui.h:25 +msgid "Edit" +msgstr "Szerkesztés" + +#: ../gtk/parameters.ui.h:26 +msgid "Remove" +msgstr "Eltávolítás" + +#: ../gtk/parameters.ui.h:27 +msgid "Proxy accounts" +msgstr "Proxy fiókok" + +#: ../gtk/parameters.ui.h:28 +msgid "Erase all passwords" +msgstr "Minden kulcsszó törlése" + +#: ../gtk/parameters.ui.h:29 +msgid "Privacy" +msgstr "Titoktartás" + +#: ../gtk/parameters.ui.h:30 +msgid "Automatically answer when a call is received" +msgstr "" + +#: ../gtk/parameters.ui.h:31 +msgid "Delay before answering (ms)" +msgstr "" + +#: ../gtk/parameters.ui.h:32 +msgid "Auto-answer" +msgstr "" + +#: ../gtk/parameters.ui.h:33 +msgid "Manage SIP Accounts" +msgstr "SIP fiókok beállítása" + +#: ../gtk/parameters.ui.h:34 +msgid "Ring sound:" +msgstr "Csengőhang:" + +#: ../gtk/parameters.ui.h:35 +msgid "ALSA special device (optional):" +msgstr "Különleges ALSA eszköz (nem kötelező):" + +#: ../gtk/parameters.ui.h:36 +msgid "Capture device:" +msgstr "Felvevő hang eszköz:" + +#: ../gtk/parameters.ui.h:37 +msgid "Ring device:" +msgstr "Csengőhang eszköz:" + +#: ../gtk/parameters.ui.h:38 +msgid "Playback device:" +msgstr "Lejátszó hang eszköz:" + +#: ../gtk/parameters.ui.h:39 +msgid "Enable echo cancellation" +msgstr "Visszhang-elnyomás engedélyezése" + +#: ../gtk/parameters.ui.h:40 +msgid "Audio" +msgstr "Audió" + +#: ../gtk/parameters.ui.h:41 +msgid "Video input device:" +msgstr "Videó bemeneti eszköz:" + +#: ../gtk/parameters.ui.h:42 +msgid "Preferred video resolution:" +msgstr "" + +#: ../gtk/parameters.ui.h:43 +msgid "Video output method:" +msgstr "" + +#: ../gtk/parameters.ui.h:44 +msgid "Show camera preview" +msgstr "" + +#: ../gtk/parameters.ui.h:45 +msgid "Video preset:" +msgstr "" + +#: ../gtk/parameters.ui.h:46 +msgid "Preferred video framerate:" +msgstr "" + +#: ../gtk/parameters.ui.h:47 +msgid "0 stands for \"unlimited\"" +msgstr "A 0 jelentése \"végtelen\"" + +#: ../gtk/parameters.ui.h:48 +msgid "Video" +msgstr "Videó" + +#: ../gtk/parameters.ui.h:49 +msgid "Upload speed limit in Kbit/sec:" +msgstr "Feltöltési sebesség korlát (kbit/mp):" + +#: ../gtk/parameters.ui.h:50 +msgid "Download speed limit in Kbit/sec:" +msgstr "Letöltési sebesség korlát (kbit/mp):" + +#: ../gtk/parameters.ui.h:51 +msgid "Enable adaptive rate control" +msgstr "Alkalmazkodó mérték-szabályozás engedélyezése" + +#: ../gtk/parameters.ui.h:52 +msgid "" +"Adaptive rate control is a technique to dynamically guess the available " +"bandwidth during a call." +msgstr "Az alkalmazkodó mérték-szabályozás egy módszer, mely erőteljesen próbálja megállapítani a rendelkezésre álló sávszélességet hívás alatt." + +#: ../gtk/parameters.ui.h:53 +msgid "Bandwidth control" +msgstr "Sávszélesség szabályozása" + +#: ../gtk/parameters.ui.h:54 +msgid "Multimedia settings" +msgstr "Multimédia beállítások" + +#: ../gtk/parameters.ui.h:55 +msgid "Set Maximum Transmission Unit:" +msgstr "Maximum Továbbítási Egység beállítása:" + +#: ../gtk/parameters.ui.h:56 +msgid "Send DTMFs as SIP info" +msgstr "DTMF küldése SIP infóként" + +#: ../gtk/parameters.ui.h:57 +msgid "Allow IPv6" +msgstr "" + +#: ../gtk/parameters.ui.h:58 +msgid "Transport" +msgstr "Átvitel" + +#: ../gtk/parameters.ui.h:59 +msgid "SIP/UDP port" +msgstr "" + +#: ../gtk/parameters.ui.h:61 +msgid "Random" +msgstr "" + +#: ../gtk/parameters.ui.h:62 +msgid "SIP/TCP port" +msgstr "" + +#: ../gtk/parameters.ui.h:63 +msgid "Audio RTP/UDP:" +msgstr "Audió RTP/UDP:" + +#: ../gtk/parameters.ui.h:64 +msgid "Fixed" +msgstr "Javítva" + +#: ../gtk/parameters.ui.h:65 +msgid "Video RTP/UDP:" +msgstr "Videó RTP/UDP:" + +#: ../gtk/parameters.ui.h:66 +msgid "Media encryption type" +msgstr "Média titkosítás típusa" + +#: ../gtk/parameters.ui.h:67 +msgid "Media encryption is mandatory" +msgstr "Média titkosítás kötelező" + +#: ../gtk/parameters.ui.h:68 +msgid "Tunnel" +msgstr "Alagút" + +#: ../gtk/parameters.ui.h:69 +msgid "DSCP fields" +msgstr "DSCP mezők" + +#: ../gtk/parameters.ui.h:70 +msgid "Network protocol and ports" +msgstr "Hálózati protokoll és port" + +#: ../gtk/parameters.ui.h:71 +msgid "Direct connection to the Internet" +msgstr "Közvetlen Internet kapcsolat" + +#: ../gtk/parameters.ui.h:72 +msgid "Behind NAT / Firewall (specify gateway IP )" +msgstr "" + +#: ../gtk/parameters.ui.h:73 +msgid "Behind NAT / Firewall (use STUN to resolve)" +msgstr "NAT / tűzfal mögött (STUN használata a feloldáshoz)" + +#: ../gtk/parameters.ui.h:74 +msgid "Behind NAT / Firewall (use ICE)" +msgstr "NAT / tűzfal mögött (ICE használata)" + +#: ../gtk/parameters.ui.h:75 +msgid "Behind NAT / Firewall (use uPnP)" +msgstr "NAT / tűzfal mögött (uPnP használata)" + +#: ../gtk/parameters.ui.h:76 +msgid "Public IP address:" +msgstr "Publikus IP cím:" + +#: ../gtk/parameters.ui.h:77 +msgid "Stun server:" +msgstr "STUN kiszolgáló:" + +#: ../gtk/parameters.ui.h:78 +msgid "NAT and Firewall" +msgstr "NAT és tűzfal" + +#: ../gtk/parameters.ui.h:79 +msgid "Network settings" +msgstr "Hálózati beállítások" + +#: ../gtk/parameters.ui.h:80 ../gtk/tunnel_config.ui.h:4 +msgid "Enable" +msgstr "Engedélyezés" + +#: ../gtk/parameters.ui.h:81 ../gtk/tunnel_config.ui.h:5 +msgid "Disable" +msgstr "Tiltás" + +#: ../gtk/parameters.ui.h:82 +msgid "Audio codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:83 +msgid "Video codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:84 +msgid "Codecs" +msgstr "Kódekek" + +#: ../gtk/parameters.ui.h:85 +msgid "Language" +msgstr "Nyelv" + +#: ../gtk/parameters.ui.h:86 +msgid "Show advanced settings" +msgstr "Haladó beállítások megjelenítése" + +#: ../gtk/parameters.ui.h:87 +msgid "Level" +msgstr "Szint" + +#: ../gtk/parameters.ui.h:88 +msgid "User interface" +msgstr "Felhasználói környezet" + +#: ../gtk/parameters.ui.h:92 +msgid "LDAP Account setup" +msgstr "" + +#: ../gtk/parameters.ui.h:93 +msgid "LDAP" +msgstr "" + +#: ../gtk/parameters.ui.h:94 +msgid "Done" +msgstr "Kész" + +#: ../gtk/password.ui.h:1 +msgid "Linphone - Authentication required" +msgstr "Linphone - Hitelesítés szükséges" + +#: ../gtk/password.ui.h:2 +msgid "Please enter the domain password" +msgstr "Kérem adja meg a tartomány jelszavát" + #: ../gtk/provisioning-fetch.ui.h:1 msgid "Configuring..." msgstr "" @@ -1698,68 +1553,278 @@ msgstr "" msgid "Please wait while fetching configuration from server..." msgstr "" -#: ../coreapi/linphonecore.c:1539 +#: ../gtk/setup_wizard.ui.h:1 +msgid "SIP account configuration assistant" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:2 +msgid "" +"Welcome!\n" +"This assistant will help you to use a SIP account for your calls." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:4 +msgid "Welcome to the account setup assistant" +msgstr "A fiók beállítása varázsló üdvözli Önt" + +#: ../gtk/setup_wizard.ui.h:5 +msgid "Create an account on linphone.org" +msgstr "Fiók létrehozása a linphone.org -on" + +#: ../gtk/setup_wizard.ui.h:6 +msgid "I have already a linphone.org account and I just want to use it" +msgstr "Már rendelkezem linphone.org fiókkal, azt szeretném használni" + +#: ../gtk/setup_wizard.ui.h:7 +msgid "I have already a sip account and I just want to use it" +msgstr "Már rendelkezem sip fiókkal, azt szeretném használni" + +#: ../gtk/setup_wizard.ui.h:8 +msgid "I want to specify a remote configuration URI" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:9 +msgid "Account setup assistant" +msgstr "Fiók beállítása varázsló" + +#: ../gtk/setup_wizard.ui.h:10 +msgid "Enter your account information" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:11 +msgid "Username*" +msgstr "Felhasználónév*" + +#: ../gtk/setup_wizard.ui.h:12 +msgid "Password*" +msgstr "Jelszó*" + +#: ../gtk/setup_wizard.ui.h:13 +msgid "Domain*" +msgstr "Tartomány" + +#: ../gtk/setup_wizard.ui.h:14 +msgid "Proxy" +msgstr "Proxy" + +#: ../gtk/setup_wizard.ui.h:15 +msgid "Configure your account (step 1/1)" +msgstr "Az Ön fiókjának beállítása (1/1 lépés)" + +#: ../gtk/setup_wizard.ui.h:16 +msgid "Enter your linphone.org username" +msgstr "Adja meg linphone.org felhasználónevét" + +#: ../gtk/setup_wizard.ui.h:19 +msgid "Enter your sip username (step 1/1)" +msgstr "Adja meg sip felhasználónevét (1/2 lépés)" + +#: ../gtk/setup_wizard.ui.h:20 +msgid "(*) Required fields" +msgstr "(*) Mező kitöltése szükséges" + +#: ../gtk/setup_wizard.ui.h:21 +msgid "Email: (*)" +msgstr "E-mail: (*)" + +#: ../gtk/setup_wizard.ui.h:22 +msgid "Username: (*)" +msgstr "Felhasználónév: (*)" + +#: ../gtk/setup_wizard.ui.h:23 +msgid "Password: (*)" +msgstr "Jelszó: (*)" + +#: ../gtk/setup_wizard.ui.h:24 +msgid "Confirm your password: (*)" +msgstr "Jelszó megerősítése: (*)" + +#: ../gtk/setup_wizard.ui.h:25 +msgid "Keep me informed with linphone updates" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:26 +msgid "Enter account information (step 1/2)" +msgstr "Adja meg a fiókinformációt (1/2 lépés)" + +#: ../gtk/setup_wizard.ui.h:27 +msgid "Your account is being created, please wait." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:28 +msgid "Account creation in progress" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:29 +msgid "" +"Please validate your account by clicking on the link we just sent you by email.\n" +"Then come back here and press Next button." +msgstr "Kérjük, érvényesítse fiókját az általunk elektronikus levélben küldött hivatkozásra kattintva.\nAzután térjen vissza ide és kattintson a Következő gombra." + +#: ../gtk/setup_wizard.ui.h:31 +msgid "Validation (step 2/2)" +msgstr "Érvényesítés (2/2 lépés)" + +#: ../gtk/setup_wizard.ui.h:32 +msgid "Checking if your account is been validated, please wait." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:33 +msgid "Account validation check in progress" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:34 +msgid "" +"Error, account not validated, username already used or server unreachable.\n" +"Please go back and try again." +msgstr "Hiba, a fiók nincs érvényesítve. Valaki már használja ezt a felhasználónevet vagy a kiszolgáló nem elérhető.\nKérjük, lépjen vissza és próbálja újra." + +#: ../gtk/setup_wizard.ui.h:36 +msgid "Error" +msgstr "Hiba" + +#: ../gtk/setup_wizard.ui.h:37 +msgid "Thank you. Your account is now configured and ready for use." +msgstr "Köszönjük! Az Ön fiókját beállítottuk és használatra kész." + +#: ../gtk/sip_account.ui.h:1 +msgid "Linphone - Configure a SIP account" +msgstr "Linphone - SIP fiók beállítása" + +#: ../gtk/sip_account.ui.h:2 +msgid "Your SIP identity:" +msgstr "Az Ön SIP azonosítója:" + +#: ../gtk/sip_account.ui.h:3 +msgid "Looks like sip:@" +msgstr "Így néz ki: sip:@" + +#: ../gtk/sip_account.ui.h:4 +msgid "sip:" +msgstr "sip:" + +#: ../gtk/sip_account.ui.h:5 +msgid "SIP Proxy address:" +msgstr "SIP Proxy cím:" + +#: ../gtk/sip_account.ui.h:6 +msgid "Looks like sip:" +msgstr "Így néz ki: sip:" + +#: ../gtk/sip_account.ui.h:7 +msgid "Registration duration (sec):" +msgstr "Regisztrálási Időköz (mp):" + +#: ../gtk/sip_account.ui.h:8 +msgid "Contact params (optional):" +msgstr "" + +#: ../gtk/sip_account.ui.h:9 +msgid "AVPF regular RTCP interval (sec):" +msgstr "" + +#: ../gtk/sip_account.ui.h:10 +msgid "Route (optional):" +msgstr "Út (nem kötelező):" + +#: ../gtk/sip_account.ui.h:11 +msgid "Transport" +msgstr "" + +#: ../gtk/sip_account.ui.h:12 +msgid "Register" +msgstr "Regisztráció" + +#: ../gtk/sip_account.ui.h:13 +msgid "Publish presence information" +msgstr "Jelenléti információ közlése" + +#: ../gtk/sip_account.ui.h:14 +msgid "Enable AVPF" +msgstr "" + +#: ../gtk/sip_account.ui.h:15 +msgid "Configure a SIP account" +msgstr "SIP fiók beállítása" + +#: ../gtk/tunnel_config.ui.h:1 +msgid "Configure VoIP tunnel" +msgstr "VoIP alagút beállítása" + +#: ../gtk/tunnel_config.ui.h:2 +msgid "Host" +msgstr "Hoszt" + +#: ../gtk/tunnel_config.ui.h:3 +msgid "Port" +msgstr "Port" + +#: ../gtk/tunnel_config.ui.h:6 +msgid "Configure tunnel" +msgstr "Alagút beállítása" + +#: ../gtk/tunnel_config.ui.h:9 +msgid "Configure http proxy (optional)" +msgstr "http proxy beállítása (nem kötelező)" + +#: ../gtk/waiting.ui.h:2 +msgid "Please wait" +msgstr "Kérem várjon" + +#: ../coreapi/linphonecore.c:1560 msgid "Ready" msgstr "Kész" -#: ../coreapi/linphonecore.c:2551 +#: ../coreapi/linphonecore.c:2556 msgid "Configuring" msgstr "" -#: ../coreapi/linphonecore.c:2725 -msgid "Looking for telephone number destination..." -msgstr "Telefonszám-cél keresése..." - -#: ../coreapi/linphonecore.c:2727 -msgid "Could not resolve this number." -msgstr "Nem sikkerült értelmezni a számot." - #. must be known at that time -#: ../coreapi/linphonecore.c:3013 +#: ../coreapi/linphonecore.c:2951 msgid "Contacting" msgstr "Kapcsolódás" -#: ../coreapi/linphonecore.c:3018 +#: ../coreapi/linphonecore.c:2956 msgid "Could not call" msgstr "Nem sikerült hívni" -#: ../coreapi/linphonecore.c:3169 +#: ../coreapi/linphonecore.c:3092 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:3327 +#: ../coreapi/linphonecore.c:3250 msgid "is contacting you" msgstr "kapcsolatba lépett veled." -#: ../coreapi/linphonecore.c:3328 +#: ../coreapi/linphonecore.c:3251 msgid " and asked autoanswer." msgstr "és automatikus választ kért." -#: ../coreapi/linphonecore.c:3452 +#: ../coreapi/linphonecore.c:3377 msgid "Modifying call parameters..." msgstr "A hívási jellemzők módosítása..." -#: ../coreapi/linphonecore.c:3802 +#: ../coreapi/linphonecore.c:3769 msgid "Connected." msgstr "Kapcsolódva." -#: ../coreapi/linphonecore.c:3827 +#: ../coreapi/linphonecore.c:3794 msgid "Call aborted" msgstr "Hívás megszakítva" -#: ../coreapi/linphonecore.c:4024 +#: ../coreapi/linphonecore.c:3983 msgid "Could not pause the call" msgstr "Nem sikerült várakoztatni a hívást" -#: ../coreapi/linphonecore.c:4027 +#: ../coreapi/linphonecore.c:3986 msgid "Pausing the current call..." msgstr "Jelenlegi hívás várakoztatásának aktiválása..." -#: ../coreapi/misc.c:434 +#: ../coreapi/misc.c:440 msgid "Stun lookup in progress..." msgstr "Stun keresés folyamatban..." -#: ../coreapi/misc.c:615 +#: ../coreapi/misc.c:650 msgid "ICE local candidates gathering in progress..." msgstr "ICE helyi jelentkezők begyűjtése folyamatban..." @@ -1815,166 +1880,173 @@ msgstr "" msgid "Unknown status" msgstr "" -#: ../coreapi/proxy.c:328 +#: ../coreapi/proxy.c:292 msgid "" "The sip proxy address you entered is invalid, it must start with \"sip:\" " "followed by a hostname." msgstr "Az Ön által megadott SIP proxy cím érvénytelen. \"sip:\"-tal kell kezdődnie, ezt egy hosztnév követi." -#: ../coreapi/proxy.c:334 +#: ../coreapi/proxy.c:298 msgid "" "The sip identity you entered is invalid.\n" "It should look like sip:username@proxydomain, such as sip:alice@example.net" msgstr "Az Ön által megadott SIP identitás érvénytelen.\nÍgy kéne kinéznie: sip:felhasznalonev@proxytartomany, például sip:aladar@pelda.hu" -#: ../coreapi/proxy.c:1416 +#: ../coreapi/proxy.c:927 +msgid "Looking for telephone number destination..." +msgstr "Telefonszám-cél keresése..." + +#: ../coreapi/proxy.c:931 +msgid "Could not resolve this number." +msgstr "Nem sikkerült értelmezni a számot." + +#: ../coreapi/proxy.c:1324 #, c-format msgid "Could not login as %s" msgstr "Nem sikerült belépni ezzel: %s" -#: ../coreapi/callbacks.c:428 +#: ../coreapi/proxy.c:1411 +#, c-format +msgid "Refreshing on %s..." +msgstr "" + +#: ../coreapi/callbacks.c:423 msgid "Remote ringing." msgstr "Távoli csengés." -#: ../coreapi/callbacks.c:440 +#: ../coreapi/callbacks.c:435 msgid "Remote ringing..." msgstr "Távoli csengés..." -#: ../coreapi/callbacks.c:461 +#: ../coreapi/callbacks.c:458 msgid "Early media." msgstr "Korai médiák." -#: ../coreapi/callbacks.c:534 +#: ../coreapi/callbacks.c:488 #, c-format -msgid "Call with %s is paused." -msgstr "A hívás a következővel: %s várakoztatva" +msgid "Call answered by %s" +msgstr "" -#: ../coreapi/callbacks.c:547 -#, c-format -msgid "Call answered by %s - on hold." -msgstr "%s fogadta a hívást - várakoztatva." - -#: ../coreapi/callbacks.c:557 +#: ../coreapi/callbacks.c:527 msgid "Call resumed." msgstr "Hívás visszatért" -#: ../coreapi/callbacks.c:561 -#, c-format -msgid "Call answered by %s." -msgstr "%s válaszolt a hívásra." - -#: ../coreapi/callbacks.c:584 +#: ../coreapi/callbacks.c:582 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:589 ../coreapi/callbacks.c:906 +#: ../coreapi/callbacks.c:587 ../coreapi/callbacks.c:923 msgid "Incompatible media parameters." msgstr "Nem kompatibilis médiajellemzők." -#: ../coreapi/callbacks.c:619 +#: ../coreapi/callbacks.c:612 msgid "We have been resumed." msgstr "Visszatértünk." #. we are being paused -#: ../coreapi/callbacks.c:628 +#: ../coreapi/callbacks.c:620 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:666 +#: ../coreapi/callbacks.c:630 msgid "Call is updated by remote." msgstr "A hívás távolról frissítve." -#: ../coreapi/callbacks.c:782 +#: ../coreapi/callbacks.c:799 msgid "Call terminated." msgstr "A hívás befejezve." -#: ../coreapi/callbacks.c:810 +#: ../coreapi/callbacks.c:827 msgid "User is busy." msgstr "A felhasználó foglalt." -#: ../coreapi/callbacks.c:811 +#: ../coreapi/callbacks.c:828 msgid "User is temporarily unavailable." msgstr "A felhasználó ideiglenesen nem elérhető" #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:813 +#: ../coreapi/callbacks.c:830 msgid "User does not want to be disturbed." msgstr "A felhasználó nem akarja, hogy zavarják." -#: ../coreapi/callbacks.c:814 +#: ../coreapi/callbacks.c:831 msgid "Call declined." msgstr "Hívás elutasítva" -#: ../coreapi/callbacks.c:829 +#: ../coreapi/callbacks.c:846 msgid "Request timeout." msgstr "" -#: ../coreapi/callbacks.c:860 +#: ../coreapi/callbacks.c:877 msgid "Redirected" msgstr "Átirányítva" -#: ../coreapi/callbacks.c:915 +#: ../coreapi/callbacks.c:927 msgid "Call failed." msgstr "Nem sikerült a hívás." -#: ../coreapi/callbacks.c:993 +#: ../coreapi/callbacks.c:1005 #, c-format msgid "Registration on %s successful." msgstr "A regisztáció a %s -n sikerült." -#: ../coreapi/callbacks.c:994 +#: ../coreapi/callbacks.c:1006 #, c-format msgid "Unregistration on %s done." msgstr "A kiregisztrálás kész a következőn: %s ." -#: ../coreapi/callbacks.c:1012 +#: ../coreapi/callbacks.c:1024 msgid "no response timeout" msgstr "időtúllépés után nincs válasz" -#: ../coreapi/callbacks.c:1015 +#: ../coreapi/callbacks.c:1027 #, c-format msgid "Registration on %s failed: %s" msgstr "A regisztáció a %s -n nem sikerült: %s" -#: ../coreapi/callbacks.c:1022 +#: ../coreapi/callbacks.c:1034 msgid "Service unavailable, retrying" msgstr "" #. if encryption is DTLS, no status to be displayed -#: ../coreapi/linphonecall.c:180 +#: ../coreapi/linphonecall.c:197 #, c-format msgid "Authentication token is %s" msgstr "Hitelesítési jel: %s" -#: ../coreapi/linphonecall.c:1310 +#: ../coreapi/linphonecall.c:1561 +#, c-format +msgid "Call parameters could not be modified: %s." +msgstr "" + +#: ../coreapi/linphonecall.c:1563 msgid "Call parameters were successfully modified." msgstr "" -#: ../coreapi/linphonecall.c:3686 +#: ../coreapi/linphonecall.c:4396 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." msgstr[0] "" msgstr[1] "" -#: ../coreapi/call_log.c:209 +#: ../coreapi/call_log.c:223 msgid "aborted" msgstr "" -#: ../coreapi/call_log.c:212 +#: ../coreapi/call_log.c:226 msgid "completed" msgstr "" -#: ../coreapi/call_log.c:215 +#: ../coreapi/call_log.c:229 msgid "missed" msgstr "" -#: ../coreapi/call_log.c:218 +#: ../coreapi/call_log.c:232 msgid "unknown" msgstr "" -#: ../coreapi/call_log.c:220 +#: ../coreapi/call_log.c:234 #, c-format msgid "" "%s at %s\n" @@ -1984,7 +2056,7 @@ msgid "" "Duration: %i mn %i sec\n" msgstr "" -#: ../coreapi/call_log.c:221 +#: ../coreapi/call_log.c:235 msgid "Outgoing call" msgstr "" diff --git a/po/it.po b/po/it.po index a801a9acf..4d5a78f3d 100644 --- a/po/it.po +++ b/po/it.po @@ -3,394 +3,422 @@ # This file is distributed under the same license as the PACKAGE package. # # Translators: +# Daniele , 2015 +# Fabrizio Carrai, 2015 msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-04-30 10:13+0200\n" -"PO-Revision-Date: 2015-04-30 08:13+0000\n" +"POT-Creation-Date: 2015-11-10 15:16+0100\n" +"PO-Revision-Date: 2015-11-10 14:16+0000\n" "Last-Translator: Belledonne Communications \n" -"Language-Team: Italian (http://www.transifex.com/projects/p/linphone-gtk/language/it/)\n" +"Language-Team: Italian (http://www.transifex.com/belledonne-communications/linphone-gtk/language/it/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: it\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ../gtk/calllogs.c:148 ../gtk/friendlist.c:974 +#: ../gtk/calllogs.c:178 #, c-format msgid "Call %s" -msgstr "Chiamata %s" +msgstr "Chiama %s" -#: ../gtk/calllogs.c:149 ../gtk/friendlist.c:975 +#: ../gtk/calllogs.c:179 #, c-format msgid "Send text to %s" -msgstr "Invia testo a %s" +msgstr "Invia messaggio a %s" -#: ../gtk/calllogs.c:232 +#: ../gtk/calllogs.c:181 +#, c-format +msgid "Add %s to your contact list" +msgstr "Aggiungi %s alla tua lista dei contatti" + +#: ../gtk/calllogs.c:245 ../gtk/main.ui.h:21 +msgid "Recent calls" +msgstr "Chiamate recenti" + +#: ../gtk/calllogs.c:260 #, c-format msgid "Recent calls (%i)" -msgstr "" +msgstr "Chiamate recenti (%i)" -#: ../gtk/calllogs.c:314 +#: ../gtk/calllogs.c:331 msgid "n/a" -msgstr "" +msgstr "n/d" -#: ../gtk/calllogs.c:317 +#: ../gtk/calllogs.c:334 msgid "Aborted" -msgstr "" +msgstr "Annullata" -#: ../gtk/calllogs.c:320 +#: ../gtk/calllogs.c:337 msgid "Missed" -msgstr "" +msgstr "Persa" -#: ../gtk/calllogs.c:323 +#: ../gtk/calllogs.c:340 msgid "Declined" -msgstr "" +msgstr "Rifiutata" -#: ../gtk/calllogs.c:329 +#: ../gtk/calllogs.c:346 #, c-format msgid "%i minute" msgid_plural "%i minutes" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%i minuto" +msgstr[1] "%i minuti" -#: ../gtk/calllogs.c:332 +#: ../gtk/calllogs.c:349 #, c-format msgid "%i second" msgid_plural "%i seconds" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%i secondo" +msgstr[1] "%i secondi" -#: ../gtk/calllogs.c:337 +#: ../gtk/calllogs.c:354 #, c-format msgid "" "%s\tQuality: %s\n" "%s\t%s\t" -msgstr "" +msgstr "%s\tQualità: %s\n%s\t%s\t" -#: ../gtk/calllogs.c:341 +#: ../gtk/calllogs.c:358 #, c-format msgid "%s\t%s" -msgstr "" +msgstr "%s\t%s" -#: ../gtk/conference.c:38 ../gtk/main.ui.h:13 +#: ../gtk/conference.c:38 ../gtk/in_call_frame.ui.h:11 msgid "Conference" -msgstr "" +msgstr "Conferenza" #: ../gtk/conference.c:46 msgid "Me" -msgstr "" +msgstr "Me" #: ../gtk/support.c:49 ../gtk/support.c:73 ../gtk/support.c:102 #, c-format msgid "Couldn't find pixmap file: %s" -msgstr "" +msgstr "Impossibile trovare il file pixmap %s" -#: ../gtk/main.c:137 -msgid "log to stdout some debug information while running." -msgstr "" +#: ../gtk/chat.c:196 ../gtk/chat.c:254 +msgid "Sending..." +msgstr "Invio in corso..." + +#: ../gtk/chat.c:213 ../gtk/chat.c:263 +msgid "Message not sent" +msgstr "Messaggio non inviato" + +#: ../gtk/chat.c:472 +msgid "Copy" +msgstr "Copia" #: ../gtk/main.c:138 -msgid "path to a file to write logs into." -msgstr "" +msgid "log to stdout some debug information while running." +msgstr "alcune informazioni di debug verranno registrate sullo stdout durante l'esecuzione" #: ../gtk/main.c:139 -msgid "Start linphone with video disabled." -msgstr "" +msgid "display version and exit." +msgstr "mostra la versione e termina." #: ../gtk/main.c:140 -msgid "Start only in the system tray, do not show the main interface." -msgstr "" +msgid "path to a file to write logs into." +msgstr "percorso del file di log." #: ../gtk/main.c:141 -msgid "address to call right now" -msgstr "" +msgid "Start linphone with video disabled." +msgstr "Avvia linphone con il video disabilitato." #: ../gtk/main.c:142 +msgid "Start only in the system tray, do not show the main interface." +msgstr "Avvia solo nel system tray, non mostrare l'interfaccia principale." + +#: ../gtk/main.c:143 +msgid "address to call right now" +msgstr "indirizzo da chiamare adesso" + +#: ../gtk/main.c:144 msgid "" "Specifiy a working directory (should be the base of the installation, eg: " "c:\\Program Files\\Linphone)" -msgstr "" - -#: ../gtk/main.c:143 -msgid "Configuration file" -msgstr "" - -#: ../gtk/main.c:144 -msgid "Run the audio assistant" -msgstr "" +msgstr "Specificare una directory di lavoro (dovrebbe essere quella di installazione, es: c:\\Program Files\\Linphone)" #: ../gtk/main.c:145 -msgid "Run self test and exit 0 if succeed" -msgstr "" +msgid "Configuration file" +msgstr "File di configurazione" -#: ../gtk/main.c:1070 +#: ../gtk/main.c:146 +msgid "Run the audio assistant" +msgstr "Avvia l'assistente audio" + +#: ../gtk/main.c:147 +msgid "Run self test and exit 0 if succeed" +msgstr "Esegui il self test e esci con 0 in caso di successo" + +#: ../gtk/main.c:1046 #, c-format msgid "" -"%s would like to add you to his contact list.\n" -"Would you allow him to see your presence status or add him to your contact list ?\n" +"%s would like to add you to his/her contact list.\n" +"Would you add him/her to your contact list and allow him/her to see your presence status?\n" "If you answer no, this person will be temporarily blacklisted." -msgstr "%s voui aggiungere il tuo contatto alla sua listaVoui permettere che lui veda il tuo stato o aggiungerlo alla tua lista dei contatti Se rispondi no questo utente sarà momentaneamente bloccato." +msgstr "%s vorrebbe aggiungerti alla sua lista dei contatti.\nVuoi aggiungerlo/a ai tuoi contatti e pemettergli di conoscere la tua presenza?\nSe rispondi NO questa persona verrà temporaneamente bloccata." -#: ../gtk/main.c:1147 +#: ../gtk/main.c:1123 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" -msgstr "" +msgstr "Digitare la password per l'utente %s\nnel dominio %s:" -#: ../gtk/main.c:1268 +#: ../gtk/main.c:1253 msgid "Call error" -msgstr "" +msgstr "Errore durante la chiamata" -#: ../gtk/main.c:1271 ../coreapi/linphonecore.c:3846 +#: ../gtk/main.c:1256 ../coreapi/linphonecore.c:3813 msgid "Call ended" msgstr "Chiamata terminata" -#: ../gtk/main.c:1274 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1259 ../coreapi/call_log.c:235 msgid "Incoming call" -msgstr "Chimata in entrata" +msgstr "Chiamata in arrivo" -#: ../gtk/main.c:1276 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1261 ../gtk/incall_view.c:580 ../gtk/in_call_frame.ui.h:2 msgid "Answer" -msgstr "" +msgstr "Risposta" -#: ../gtk/main.c:1278 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1263 ../gtk/in_call_frame.ui.h:3 msgid "Decline" msgstr "Rifiuta" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 msgid "Call paused" -msgstr "" +msgstr "Chiamata in pausa" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 #, c-format msgid "by %s" -msgstr "" +msgstr "da %s" -#: ../gtk/main.c:1354 +#: ../gtk/main.c:1339 #, c-format msgid "%s proposed to start video. Do you accept ?" -msgstr "" +msgstr "%s chiede di avviare il video. Accetti ?" -#: ../gtk/main.c:1509 +#: ../gtk/main.c:1505 msgid "Website link" -msgstr "" +msgstr "Collegamento al sito web" -#: ../gtk/main.c:1568 ../gtk/waiting.ui.h:1 +#: ../gtk/main.c:1564 ../gtk/waiting.ui.h:1 msgid "Linphone" msgstr "Linphone" -#: ../gtk/main.c:1569 +#: ../gtk/main.c:1565 msgid "A video internet phone" -msgstr "" +msgstr "Un videotelefono su internet" -#: ../gtk/main.c:1629 +#: ../gtk/main.c:1624 #, c-format msgid "%s (Default)" msgstr "%s (Default)" -#: ../gtk/main.c:1962 ../coreapi/callbacks.c:1063 +#: ../gtk/main.c:1960 ../coreapi/callbacks.c:1075 #, c-format msgid "We are transferred to %s" -msgstr "" +msgstr "Siamo trasferiti verso %s" -#: ../gtk/main.c:1972 +#: ../gtk/main.c:1970 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." -msgstr "" +msgstr "Non è stata trovata nessuna scheda audio.\nNon sarà possibile effettuare o ricevere chiamate in voce." -#: ../gtk/main.c:2117 +#: ../gtk/main.c:2129 msgid "A free SIP video-phone" -msgstr "" +msgstr "Un videotelefono SIP free" -#: ../gtk/main.c:2221 +#: ../gtk/main.c:2242 #, c-format msgid "Hello\n" -msgstr "" +msgstr "Salve\n" -#: ../gtk/friendlist.c:505 +#: ../gtk/friendlist.c:461 msgid "Add to addressbook" -msgstr "" +msgstr "Aggiungi alla rubrica" -#: ../gtk/friendlist.c:691 -msgid "Presence status" -msgstr "Presenza" - -#: ../gtk/friendlist.c:709 ../gtk/propertybox.c:569 ../gtk/contact.ui.h:1 -msgid "Name" -msgstr "Nome" - -#: ../gtk/friendlist.c:721 -msgid "Call" -msgstr "" - -#: ../gtk/friendlist.c:726 -msgid "Chat" -msgstr "" - -#: ../gtk/friendlist.c:756 +#: ../gtk/friendlist.c:627 #, c-format msgid "Search in %s directory" msgstr "Cerca contatti nella directory %s" -#: ../gtk/friendlist.c:924 +#: ../gtk/friendlist.c:772 msgid "Invalid sip contact !" msgstr "Contatto SIP non valido" -#: ../gtk/friendlist.c:976 +#: ../gtk/friendlist.c:820 +#, c-format +msgid "Add a new contact" +msgstr "Aggiungi un nuovo contatto" + +#: ../gtk/friendlist.c:823 #, c-format msgid "Edit contact '%s'" msgstr "Modifica contatto %s" -#: ../gtk/friendlist.c:977 +#: ../gtk/friendlist.c:824 #, c-format msgid "Delete contact '%s'" -msgstr "Elimina contatto %s" +msgstr "Elimina il contatto %s" -#: ../gtk/friendlist.c:978 +#: ../gtk/friendlist.c:825 #, c-format msgid "Delete chat history of '%s'" -msgstr "" +msgstr "Cancella la cronologia della chat con '%s'" -#: ../gtk/friendlist.c:1029 +#: ../gtk/friendlist.c:862 #, c-format msgid "Add new contact from %s directory" msgstr "Aggiungi nuovo contatto dalla directory %s" -#: ../gtk/propertybox.c:575 -msgid "Rate (Hz)" -msgstr "" +#: ../gtk/propertybox.c:592 ../gtk/contact.ui.h:1 +msgid "Name" +msgstr "Nome" -#: ../gtk/propertybox.c:581 +#: ../gtk/propertybox.c:598 +msgid "Rate (Hz)" +msgstr "Frequenza (Hz)" + +#: ../gtk/propertybox.c:604 msgid "Status" msgstr "Stato" -#: ../gtk/propertybox.c:587 +#: ../gtk/propertybox.c:617 msgid "IP Bitrate (kbit/s)" -msgstr "" +msgstr "IP Bitrate (kbit/s)" -#: ../gtk/propertybox.c:596 +#: ../gtk/propertybox.c:628 msgid "Parameters" msgstr "Parametri" -#: ../gtk/propertybox.c:639 ../gtk/propertybox.c:782 +#: ../gtk/propertybox.c:670 ../gtk/propertybox.c:824 msgid "Enabled" msgstr "Attivato" -#: ../gtk/propertybox.c:641 ../gtk/propertybox.c:782 ../gtk/parameters.ui.h:20 +#: ../gtk/propertybox.c:672 ../gtk/propertybox.c:824 ../gtk/parameters.ui.h:60 msgid "Disabled" msgstr "Disattivato" -#: ../gtk/propertybox.c:828 +#: ../gtk/propertybox.c:902 msgid "Account" msgstr "Account" -#: ../gtk/propertybox.c:1091 +#: ../gtk/propertybox.c:1170 msgid "English" msgstr "Inglese" -#: ../gtk/propertybox.c:1092 +#: ../gtk/propertybox.c:1171 msgid "French" msgstr "Francese" -#: ../gtk/propertybox.c:1093 +#: ../gtk/propertybox.c:1172 msgid "Swedish" msgstr "Svedese" -#: ../gtk/propertybox.c:1094 +#: ../gtk/propertybox.c:1173 msgid "Italian" msgstr "Italiano" -#: ../gtk/propertybox.c:1095 +#: ../gtk/propertybox.c:1174 msgid "Spanish" msgstr "Spagnolo" -#: ../gtk/propertybox.c:1096 +#: ../gtk/propertybox.c:1175 msgid "Brazilian Portugese" -msgstr "" +msgstr "Portoghese brasiliano" -#: ../gtk/propertybox.c:1097 +#: ../gtk/propertybox.c:1176 msgid "Polish" msgstr "Polacco" -#: ../gtk/propertybox.c:1098 +#: ../gtk/propertybox.c:1177 msgid "German" msgstr "Tedesco" -#: ../gtk/propertybox.c:1099 +#: ../gtk/propertybox.c:1178 msgid "Russian" msgstr "Russo" -#: ../gtk/propertybox.c:1100 +#: ../gtk/propertybox.c:1179 msgid "Japanese" msgstr "Giapponese" -#: ../gtk/propertybox.c:1101 +#: ../gtk/propertybox.c:1180 msgid "Dutch" msgstr "Olandese" -#: ../gtk/propertybox.c:1102 +#: ../gtk/propertybox.c:1181 msgid "Hungarian" msgstr "Ungherese" -#: ../gtk/propertybox.c:1103 +#: ../gtk/propertybox.c:1182 msgid "Czech" msgstr "Ceco" -#: ../gtk/propertybox.c:1104 +#: ../gtk/propertybox.c:1183 msgid "Chinese" -msgstr "" +msgstr "Cinese" -#: ../gtk/propertybox.c:1105 +#: ../gtk/propertybox.c:1184 msgid "Traditional Chinese" -msgstr "" +msgstr "Cinese tradizionale" -#: ../gtk/propertybox.c:1106 +#: ../gtk/propertybox.c:1185 msgid "Norwegian" -msgstr "" +msgstr "Norvegese" -#: ../gtk/propertybox.c:1107 +#: ../gtk/propertybox.c:1186 msgid "Hebrew" -msgstr "" +msgstr "Ebraico" -#: ../gtk/propertybox.c:1108 +#: ../gtk/propertybox.c:1187 msgid "Serbian" -msgstr "" +msgstr "Serbo" -#: ../gtk/propertybox.c:1175 +#: ../gtk/propertybox.c:1188 +msgid "Arabic" +msgstr "Arabo" + +#: ../gtk/propertybox.c:1189 +msgid "Turkish" +msgstr "Turco" + +#: ../gtk/propertybox.c:1246 msgid "" "You need to restart linphone for the new language selection to take effect." msgstr "Riavviare il software per utilizzare la nuova lingua selezionata" -#: ../gtk/propertybox.c:1255 +#: ../gtk/propertybox.c:1326 msgid "None" -msgstr "" +msgstr "Nessuno" -#: ../gtk/propertybox.c:1259 +#: ../gtk/propertybox.c:1330 msgid "SRTP" -msgstr "" +msgstr "SRTP" -#: ../gtk/propertybox.c:1265 +#: ../gtk/propertybox.c:1336 msgid "DTLS" -msgstr "" +msgstr "DTLS" -#: ../gtk/propertybox.c:1272 +#: ../gtk/propertybox.c:1343 msgid "ZRTP" -msgstr "" +msgstr "ZRTP" #: ../gtk/update.c:80 #, c-format msgid "" "A more recent version is availalble from %s.\n" "Would you like to open a browser to download it ?" -msgstr "Una versione più recente è disponibile da %s.\nVuoi aprire un browser per eseguire il download ?" +msgstr "Una versione più recente è disponibile su %s.\nVuoi aprire un browser per eseguire il download ?" #: ../gtk/update.c:91 msgid "You are running the lastest version." -msgstr "Non è stato trovato alcun aggiornamento" +msgstr "Stai eseguendo la versione più aggiornata." #: ../gtk/buddylookup.c:85 msgid "Firstname, Lastname" @@ -398,7 +426,7 @@ msgstr "Nome, Cognome" #: ../gtk/buddylookup.c:160 msgid "Error communicating with server." -msgstr "Errore di comunicazione" +msgstr "Errore di comunicazione con il server." #: ../gtk/buddylookup.c:164 msgid "Connecting..." @@ -406,337 +434,208 @@ msgstr "In connessione..." #: ../gtk/buddylookup.c:168 msgid "Connected" -msgstr "Connessione" +msgstr "Connesso" #: ../gtk/buddylookup.c:172 msgid "Receiving data..." -msgstr "Ricezione data..." +msgstr "Ricezione dei dati..." #: ../gtk/buddylookup.c:180 #, c-format msgid "Found %i contact" msgid_plural "Found %i contacts" msgstr[0] "Trovato %i contatto" -msgstr[1] "Trovato %i contatti" +msgstr[1] "Trovati %i contatti" -#: ../gtk/setupwizard.c:32 -msgid "" -"Welcome!\n" -"This assistant will help you to use a SIP account for your calls." -msgstr "" - -#: ../gtk/setupwizard.c:41 -msgid "Create an account on linphone.org" -msgstr "" - -#: ../gtk/setupwizard.c:42 -msgid "I have already a linphone.org account and I just want to use it" -msgstr "" - -#: ../gtk/setupwizard.c:43 -msgid "I have already a sip account and I just want to use it" -msgstr "" - -#: ../gtk/setupwizard.c:44 -msgid "I want to specify a remote configuration URI" -msgstr "" - -#: ../gtk/setupwizard.c:87 -msgid "Enter your linphone.org username" -msgstr "" - -#: ../gtk/setupwizard.c:100 ../gtk/parameters.ui.h:85 ../gtk/ldap.ui.h:4 -msgid "Username:" -msgstr "Manuale utente" - -#: ../gtk/setupwizard.c:102 ../gtk/password.ui.h:4 ../gtk/ldap.ui.h:5 -msgid "Password:" -msgstr "Password:" - -#: ../gtk/setupwizard.c:122 -msgid "Enter your account informations" -msgstr "" - -#: ../gtk/setupwizard.c:138 -msgid "Username*" -msgstr "" - -#: ../gtk/setupwizard.c:139 -msgid "Password*" -msgstr "" - -#: ../gtk/setupwizard.c:142 -msgid "Domain*" -msgstr "" - -#: ../gtk/setupwizard.c:143 -msgid "Proxy" -msgstr "" - -#: ../gtk/setupwizard.c:322 -msgid "(*) Required fields" -msgstr "" - -#: ../gtk/setupwizard.c:323 -msgid "Username: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:325 -msgid "Password: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:327 -msgid "Email: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:329 -msgid "Confirm your password: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:343 -msgid "Keep me informed with linphone updates" -msgstr "" - -#: ../gtk/setupwizard.c:399 -msgid "" -"Error, account not validated, username already used or server unreachable.\n" -"Please go back and try again." -msgstr "" - -#: ../gtk/setupwizard.c:410 -msgid "Thank you. Your account is now configured and ready for use." -msgstr "Grazie. Il tuo account è configurato e pronto all'uso" - -#: ../gtk/setupwizard.c:418 -msgid "" -"Please validate your account by clicking on the link we just sent you by email.\n" -"Then come back here and press Next button." -msgstr "" - -#: ../gtk/setupwizard.c:609 -msgid "SIP account configuration assistant" -msgstr "" - -#: ../gtk/setupwizard.c:629 -msgid "Welcome to the account setup assistant" -msgstr "Benvenuto nel configuratore di account" - -#: ../gtk/setupwizard.c:634 -msgid "Account setup assistant" -msgstr "Configuratore di account" - -#: ../gtk/setupwizard.c:640 -msgid "Configure your account (step 1/1)" -msgstr "" - -#: ../gtk/setupwizard.c:645 -msgid "Enter your sip username (step 1/1)" -msgstr "" - -#: ../gtk/setupwizard.c:649 -msgid "Enter account information (step 1/2)" -msgstr "" - -#: ../gtk/setupwizard.c:658 -msgid "Validation (step 2/2)" -msgstr "" - -#: ../gtk/setupwizard.c:663 -msgid "Error" -msgstr "" - -#: ../gtk/setupwizard.c:667 ../gtk/audio_assistant.c:534 -msgid "Terminating" -msgstr "" - -#: ../gtk/incall_view.c:70 ../gtk/incall_view.c:94 +#: ../gtk/incall_view.c:67 ../gtk/incall_view.c:87 #, c-format msgid "Call #%i" -msgstr "" +msgstr "Chiamata #%i" -#: ../gtk/incall_view.c:155 +#: ../gtk/incall_view.c:145 #, c-format msgid "Transfer to call #%i with %s" -msgstr "" +msgstr "Trasferimento per chiamare #%i con %s" -#: ../gtk/incall_view.c:211 ../gtk/incall_view.c:214 +#: ../gtk/incall_view.c:202 ../gtk/incall_view.c:205 msgid "Not used" -msgstr "" +msgstr "Non usato" -#: ../gtk/incall_view.c:221 +#: ../gtk/incall_view.c:212 msgid "ICE not activated" -msgstr "" +msgstr "ICE non attivato" -#: ../gtk/incall_view.c:223 +#: ../gtk/incall_view.c:214 msgid "ICE failed" -msgstr "" +msgstr "ICE fallito" -#: ../gtk/incall_view.c:225 +#: ../gtk/incall_view.c:216 msgid "ICE in progress" -msgstr "" +msgstr "ICE in corso" -#: ../gtk/incall_view.c:227 +#: ../gtk/incall_view.c:218 msgid "Going through one or more NATs" -msgstr "" +msgstr "Attraversando uno o più NAT" -#: ../gtk/incall_view.c:229 +#: ../gtk/incall_view.c:220 msgid "Direct" -msgstr "" +msgstr "Diretto" -#: ../gtk/incall_view.c:231 +#: ../gtk/incall_view.c:222 msgid "Through a relay server" -msgstr "" +msgstr "Attraverso un relay server" -#: ../gtk/incall_view.c:239 +#: ../gtk/incall_view.c:230 msgid "uPnP not activated" -msgstr "" +msgstr "uPnP non attivo" -#: ../gtk/incall_view.c:241 +#: ../gtk/incall_view.c:232 msgid "uPnP in progress" -msgstr "" +msgstr "uPnP in corso" -#: ../gtk/incall_view.c:243 +#: ../gtk/incall_view.c:234 msgid "uPnp not available" -msgstr "" +msgstr "uPnP non disponibile" -#: ../gtk/incall_view.c:245 +#: ../gtk/incall_view.c:236 msgid "uPnP is running" -msgstr "" +msgstr "uPnP in esecuzione" -#: ../gtk/incall_view.c:247 +#: ../gtk/incall_view.c:238 msgid "uPnP failed" -msgstr "" +msgstr "uPnP ha fallito" -#: ../gtk/incall_view.c:257 ../gtk/incall_view.c:258 +#: ../gtk/incall_view.c:248 ../gtk/incall_view.c:249 msgid "Direct or through server" -msgstr "" +msgstr "Diretto o attraverso un server" -#: ../gtk/incall_view.c:267 ../gtk/incall_view.c:279 +#: ../gtk/incall_view.c:258 ../gtk/incall_view.c:270 #, c-format msgid "" "download: %f\n" "upload: %f (kbit/s)" -msgstr "" +msgstr "download: %f\nupload: %f (kbit/s)" -#: ../gtk/incall_view.c:272 ../gtk/incall_view.c:274 +#: ../gtk/incall_view.c:263 ../gtk/incall_view.c:265 #, c-format msgid "%ix%i @ %f fps" -msgstr "" +msgstr "%ix%i @ %f fps" -#: ../gtk/incall_view.c:304 +#: ../gtk/incall_view.c:295 #, c-format msgid "%.3f seconds" -msgstr "" +msgstr "%.3f secondi" -#: ../gtk/incall_view.c:407 ../gtk/main.ui.h:12 ../gtk/videowindow.c:235 +#: ../gtk/incall_view.c:453 ../gtk/in_call_frame.ui.h:10 +#: ../gtk/videowindow.c:236 msgid "Hang up" -msgstr "" +msgstr "Riagganciare" -#: ../gtk/incall_view.c:511 +#: ../gtk/incall_view.c:559 msgid "Calling..." -msgstr "" +msgstr "Chiamando..." -#: ../gtk/incall_view.c:514 ../gtk/incall_view.c:733 -msgid "00::00::00" -msgstr "" +#: ../gtk/incall_view.c:562 ../gtk/incall_view.c:792 +msgid "00:00:00" +msgstr "00:00:00" -#: ../gtk/incall_view.c:525 +#: ../gtk/incall_view.c:573 msgid "Incoming call" -msgstr "" +msgstr "Chiamata in ingresso" -#: ../gtk/incall_view.c:562 +#: ../gtk/incall_view.c:610 msgid "good" -msgstr "" +msgstr "bene" -#: ../gtk/incall_view.c:564 +#: ../gtk/incall_view.c:612 msgid "average" -msgstr "" +msgstr "media" -#: ../gtk/incall_view.c:566 +#: ../gtk/incall_view.c:614 msgid "poor" -msgstr "" +msgstr "ridotto" -#: ../gtk/incall_view.c:568 +#: ../gtk/incall_view.c:616 msgid "very poor" -msgstr "" +msgstr "molto poco" -#: ../gtk/incall_view.c:570 +#: ../gtk/incall_view.c:618 msgid "too bad" -msgstr "" +msgstr "troppo brutto" -#: ../gtk/incall_view.c:571 ../gtk/incall_view.c:587 +#: ../gtk/incall_view.c:619 ../gtk/incall_view.c:635 msgid "unavailable" -msgstr "" +msgstr "non disponibile" -#: ../gtk/incall_view.c:679 +#: ../gtk/incall_view.c:731 msgid "Secured by SRTP" -msgstr "" +msgstr "Trasmissione sicura con SRTP" -#: ../gtk/incall_view.c:685 +#: ../gtk/incall_view.c:737 msgid "Secured by DTLS" -msgstr "" +msgstr "Trasmissione sicura con DTLS" -#: ../gtk/incall_view.c:691 +#: ../gtk/incall_view.c:743 #, c-format msgid "Secured by ZRTP - [auth token: %s]" -msgstr "" +msgstr "Trasmissione sicura con ZRTP - [auth token: %s]" -#: ../gtk/incall_view.c:697 +#: ../gtk/incall_view.c:747 msgid "Set unverified" -msgstr "" +msgstr "Marcato come non verificato" -#: ../gtk/incall_view.c:697 ../gtk/main.ui.h:4 +#: ../gtk/incall_view.c:747 msgid "Set verified" -msgstr "" +msgstr "Marcato come verificato" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In conference" -msgstr "" +msgstr "In conferenza" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In call" -msgstr "" +msgstr "Chiamata in corso" -#: ../gtk/incall_view.c:764 +#: ../gtk/incall_view.c:824 msgid "Paused call" -msgstr "" +msgstr "Chiamata sospesa" -#: ../gtk/incall_view.c:800 +#: ../gtk/incall_view.c:861 msgid "Call ended." msgstr "Chiamata terminata." -#: ../gtk/incall_view.c:831 +#: ../gtk/incall_view.c:892 msgid "Transfer in progress" -msgstr "" +msgstr "Trasferimento in corso" -#: ../gtk/incall_view.c:834 +#: ../gtk/incall_view.c:895 msgid "Transfer done." -msgstr "" +msgstr "Trasferimento completato." -#: ../gtk/incall_view.c:837 +#: ../gtk/incall_view.c:898 msgid "Transfer failed." -msgstr "" +msgstr "Trasferimento fallito." -#: ../gtk/incall_view.c:881 +#: ../gtk/incall_view.c:929 msgid "Resume" -msgstr "" +msgstr "Riprendere" -#: ../gtk/incall_view.c:888 ../gtk/main.ui.h:9 +#: ../gtk/incall_view.c:929 ../gtk/in_call_frame.ui.h:7 msgid "Pause" -msgstr "" +msgstr "Pausa" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 #, c-format msgid "" "Recording into\n" "%s %s" -msgstr "" +msgstr "Registrare in\n%s %s" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 msgid "(Paused)" -msgstr "" +msgstr "(Sospeso)" -#: ../gtk/loginframe.c:87 +#: ../gtk/loginframe.c:75 #, c-format msgid "Please enter login information for %s" msgstr "Prego inserire le proprie credenziali di accesso per %s" @@ -744,282 +643,127 @@ msgstr "Prego inserire le proprie credenziali di accesso per %s" #: ../gtk/config-fetching.c:57 #, c-format msgid "fetching from %s" -msgstr "" +msgstr "prelevando da %s" #: ../gtk/config-fetching.c:73 #, c-format msgid "Downloading of remote configuration from %s failed." -msgstr "" +msgstr "Il trasferimento della configurazione remota da %s è fallito." -#: ../gtk/audio_assistant.c:98 +#: ../gtk/audio_assistant.c:103 msgid "No voice detected" -msgstr "" +msgstr "Non è stata riconosciuta nessuna voce" -#: ../gtk/audio_assistant.c:99 +#: ../gtk/audio_assistant.c:104 msgid "Too low" -msgstr "" +msgstr "Troppo basso" -#: ../gtk/audio_assistant.c:100 +#: ../gtk/audio_assistant.c:105 msgid "Good" -msgstr "" +msgstr "Bene" -#: ../gtk/audio_assistant.c:101 +#: ../gtk/audio_assistant.c:106 msgid "Too loud" -msgstr "" +msgstr "Troppo forte" -#: ../gtk/audio_assistant.c:183 +#: ../gtk/audio_assistant.c:188 msgid "Did you hear three beeps ?" -msgstr "" +msgstr "Hai sentito tre segnali ?" -#: ../gtk/audio_assistant.c:292 ../gtk/audio_assistant.c:297 +#: ../gtk/audio_assistant.c:299 ../gtk/audio_assistant.c:304 msgid "Sound preferences not found " -msgstr "" +msgstr "Le preferenze sui suoni non sono state trovate" -#: ../gtk/audio_assistant.c:306 +#: ../gtk/audio_assistant.c:313 msgid "Cannot launch system sound control " -msgstr "" +msgstr "Non è possibile eseguire il controllo dell'audio di sistema" -#: ../gtk/audio_assistant.c:318 +#: ../gtk/audio_assistant.c:325 msgid "" "Welcome!\n" "This assistant will help you to configure audio settings for Linphone" -msgstr "" +msgstr "Benvenuto!\nL'assistente ti aiuterà a configurare i settaggi audio di Linphone" -#: ../gtk/audio_assistant.c:328 +#: ../gtk/audio_assistant.c:335 msgid "Capture device" -msgstr "" +msgstr "Dispositivo di acquisizione" -#: ../gtk/audio_assistant.c:329 +#: ../gtk/audio_assistant.c:336 msgid "Recorded volume" -msgstr "" +msgstr "Volume di registrazione" -#: ../gtk/audio_assistant.c:333 +#: ../gtk/audio_assistant.c:340 msgid "No voice" -msgstr "" +msgstr "Nessuna voce" -#: ../gtk/audio_assistant.c:334 ../gtk/audio_assistant.c:373 +#: ../gtk/audio_assistant.c:341 ../gtk/audio_assistant.c:380 msgid "System sound preferences" -msgstr "" +msgstr "Preferenze per l'audio di sistema" -#: ../gtk/audio_assistant.c:369 +#: ../gtk/audio_assistant.c:376 msgid "Playback device" -msgstr "" +msgstr "Dispositivo di riproduzione" -#: ../gtk/audio_assistant.c:370 +#: ../gtk/audio_assistant.c:377 msgid "Play three beeps" -msgstr "" +msgstr "Riproduci tre segnali" -#: ../gtk/audio_assistant.c:403 +#: ../gtk/audio_assistant.c:410 msgid "Press the record button and say some words" -msgstr "" +msgstr "Premere il pulsante registrazione e parlare" -#: ../gtk/audio_assistant.c:404 +#: ../gtk/audio_assistant.c:411 msgid "Listen to your record voice" -msgstr "" +msgstr "Ascoltare la voce registrata" -#: ../gtk/audio_assistant.c:405 +#: ../gtk/audio_assistant.c:412 ../gtk/conf_frame.ui.h:2 +#: ../gtk/in_call_frame.ui.h:4 msgid "Record" -msgstr "" +msgstr "Registra" -#: ../gtk/audio_assistant.c:406 +#: ../gtk/audio_assistant.c:413 msgid "Play" -msgstr "" +msgstr "Riproduci" -#: ../gtk/audio_assistant.c:433 +#: ../gtk/audio_assistant.c:440 msgid "Let's start Linphone now" -msgstr "" +msgstr "Ora è possibile usare Linphone" -#: ../gtk/audio_assistant.c:503 +#: ../gtk/audio_assistant.c:510 msgid "Audio Assistant" -msgstr "" +msgstr "Assistente Audio" -#: ../gtk/audio_assistant.c:513 ../gtk/main.ui.h:32 +#: ../gtk/audio_assistant.c:520 ../gtk/main.ui.h:13 msgid "Audio assistant" -msgstr "" +msgstr "Assistente Audio" -#: ../gtk/audio_assistant.c:518 +#: ../gtk/audio_assistant.c:525 msgid "Mic Gain calibration" -msgstr "" +msgstr "Calibrazione del guadagano del microfono" -#: ../gtk/audio_assistant.c:524 +#: ../gtk/audio_assistant.c:531 msgid "Speaker volume calibration" -msgstr "" +msgstr "Calibrazione del volume di riproduzione" -#: ../gtk/audio_assistant.c:529 +#: ../gtk/audio_assistant.c:536 msgid "Record and Play" -msgstr "" +msgstr "Registra e Riproduci" -#: ../gtk/main.ui.h:1 -msgid "Callee name" -msgstr "" - -#: ../gtk/main.ui.h:2 -msgid "Send" -msgstr "Invia" - -#: ../gtk/main.ui.h:3 -msgid "End conference" -msgstr "" - -#: ../gtk/main.ui.h:7 -msgid "Record this call to an audio file" -msgstr "" - -#: ../gtk/main.ui.h:8 -msgid "Video" -msgstr "" - -#: ../gtk/main.ui.h:10 -msgid "Mute" -msgstr "" - -#: ../gtk/main.ui.h:11 -msgid "Transfer" -msgstr "" - -#: ../gtk/main.ui.h:14 -msgid "In call" -msgstr "In chiamata" - -#: ../gtk/main.ui.h:15 -msgid "Duration" -msgstr "Durata" - -#: ../gtk/main.ui.h:16 -msgid "Call quality rating" -msgstr "" - -#: ../gtk/main.ui.h:17 -msgid "All users" -msgstr "" - -#: ../gtk/main.ui.h:18 -msgid "Online users" -msgstr "" - -#: ../gtk/main.ui.h:19 -msgid "ADSL" -msgstr "" - -#: ../gtk/main.ui.h:20 -msgid "Fiber Channel" -msgstr "" - -#: ../gtk/main.ui.h:21 -msgid "Default" -msgstr "Default" - -#: ../gtk/main.ui.h:22 -msgid "Delete" -msgstr "" - -#: ../gtk/main.ui.h:23 -msgid "_Options" -msgstr "" - -#: ../gtk/main.ui.h:24 -msgid "Set configuration URI" -msgstr "" - -#: ../gtk/main.ui.h:25 -msgid "Always start video" -msgstr "" - -#: ../gtk/main.ui.h:26 -msgid "Enable self-view" -msgstr "Self-view abilitato" - -#: ../gtk/main.ui.h:27 -msgid "_Help" -msgstr "" - -#: ../gtk/main.ui.h:28 -msgid "Show debug window" -msgstr "" - -#: ../gtk/main.ui.h:29 -msgid "_Homepage" -msgstr "" - -#: ../gtk/main.ui.h:30 -msgid "Check _Updates" -msgstr "" - -#: ../gtk/main.ui.h:31 -msgid "Account assistant" -msgstr "" - -#: ../gtk/main.ui.h:33 -msgid "SIP address or phone number:" -msgstr "Indirizzo sip o numero." - -#: ../gtk/main.ui.h:34 -msgid "Initiate a new call" -msgstr "" - -#: ../gtk/main.ui.h:35 -msgid "Contacts" -msgstr "" - -#: ../gtk/main.ui.h:36 -msgid "Search" -msgstr "" - -#: ../gtk/main.ui.h:37 -msgid "Add contacts from directory" -msgstr "" - -#: ../gtk/main.ui.h:38 -msgid "Add contact" -msgstr "" - -#: ../gtk/main.ui.h:39 -msgid "Recent calls" -msgstr "" - -#: ../gtk/main.ui.h:40 -msgid "My current identity:" -msgstr "Identità corrente" - -#: ../gtk/main.ui.h:41 ../gtk/tunnel_config.ui.h:7 -msgid "Username" -msgstr "Username" - -#: ../gtk/main.ui.h:42 ../gtk/tunnel_config.ui.h:8 -msgid "Password" -msgstr "Password" - -#: ../gtk/main.ui.h:43 -msgid "Internet connection:" -msgstr "Connessione Internet:" - -#: ../gtk/main.ui.h:44 -msgid "Automatically log me in" -msgstr "Login Automatico" - -#: ../gtk/main.ui.h:45 ../gtk/password.ui.h:3 -msgid "UserID" -msgstr "" - -#: ../gtk/main.ui.h:46 -msgid "Login information" -msgstr "Credenziali di accesso" - -#: ../gtk/main.ui.h:47 -msgid "Welcome!" -msgstr "" +#: ../gtk/audio_assistant.c:541 ../gtk/setup_wizard.ui.h:38 +msgid "Terminating" +msgstr "Procedura completata" #: ../gtk/about.ui.h:1 msgid "About Linphone" -msgstr "" +msgstr "Su Linphone" #: ../gtk/about.ui.h:2 msgid "(C) Belledonne Communications, 2010\n" -msgstr "" +msgstr "(C) Belledonne Communications, 2010\n" #: ../gtk/about.ui.h:4 msgid "An internet video phone using the standard SIP (rfc3261) protocol." -msgstr "" +msgstr "Un videotelefono con protocollo standard SIP (RFC 3261) " #: ../gtk/about.ui.h:5 msgid "" @@ -1035,457 +779,7 @@ msgid "" "cs: Petr Pisar \n" "hu: anonymous\n" "he: Eli Zaretskii \n" -msgstr "" - -#: ../gtk/contact.ui.h:2 -msgid "SIP Address" -msgstr "Rubrica" - -#: ../gtk/contact.ui.h:3 -msgid "Show this contact presence status" -msgstr "Mostra lo stato di presenza del contatto" - -#: ../gtk/contact.ui.h:4 -msgid "Allow this contact to see my presence status" -msgstr "Permitti al contatto di vedere il mio stato di presenza" - -#: ../gtk/contact.ui.h:5 -msgid "Contact information" -msgstr "Contact informazioni" - -#: ../gtk/log.ui.h:1 -msgid "Linphone debug window" -msgstr "Linphone debug window" - -#: ../gtk/log.ui.h:2 -msgid "Scroll to end" -msgstr "" - -#: ../gtk/password.ui.h:1 -msgid "Linphone - Authentication required" -msgstr "" - -#: ../gtk/password.ui.h:2 -msgid "Please enter the domain password" -msgstr "Prego inserire la password di dominio" - -#: ../gtk/call_logs.ui.h:1 -msgid "Call history" -msgstr "Cronologia" - -#: ../gtk/call_logs.ui.h:2 -msgid "Clear all" -msgstr "" - -#: ../gtk/call_logs.ui.h:3 -msgid "Call back" -msgstr "" - -#: ../gtk/sip_account.ui.h:1 -msgid "Linphone - Configure a SIP account" -msgstr "Linphone - Configurazione SIP account" - -#: ../gtk/sip_account.ui.h:2 -msgid "Your SIP identity:" -msgstr "Identità SIP" - -#: ../gtk/sip_account.ui.h:3 -msgid "Looks like sip:@" -msgstr "" - -#: ../gtk/sip_account.ui.h:4 -msgid "sip:" -msgstr "sip:" - -#: ../gtk/sip_account.ui.h:5 -msgid "SIP Proxy address:" -msgstr "Indirizzo sip proxy:" - -#: ../gtk/sip_account.ui.h:6 -msgid "Looks like sip:" -msgstr "" - -#: ../gtk/sip_account.ui.h:7 -msgid "Registration duration (sec):" -msgstr "Durata registrazione (sec)" - -#: ../gtk/sip_account.ui.h:8 -msgid "Contact params (optional):" -msgstr "" - -#: ../gtk/sip_account.ui.h:9 -msgid "AVPF regular RTCP interval (sec):" -msgstr "" - -#: ../gtk/sip_account.ui.h:10 -msgid "Route (optional):" -msgstr "Rotta (opzionale)" - -#: ../gtk/sip_account.ui.h:11 -msgid "Transport" -msgstr "" - -#: ../gtk/sip_account.ui.h:12 -msgid "Register" -msgstr "" - -#: ../gtk/sip_account.ui.h:13 -msgid "Publish presence information" -msgstr "Pubblica stato della presenza" - -#: ../gtk/sip_account.ui.h:14 -msgid "Enable AVPF" -msgstr "" - -#: ../gtk/sip_account.ui.h:15 -msgid "Configure a SIP account" -msgstr "Configurazione SIP account" - -#: ../gtk/parameters.ui.h:1 -msgid "anonymous" -msgstr "" - -#: ../gtk/parameters.ui.h:2 -msgid "GSSAPI" -msgstr "" - -#: ../gtk/parameters.ui.h:3 -msgid "SASL" -msgstr "" - -#: ../gtk/parameters.ui.h:4 -msgid "default soundcard" -msgstr "default scheda audio" - -#: ../gtk/parameters.ui.h:5 -msgid "a sound card" -msgstr "" - -#: ../gtk/parameters.ui.h:6 -msgid "default camera" -msgstr "default videocamera" - -#: ../gtk/parameters.ui.h:7 -msgid "CIF" -msgstr "CIF" - -#: ../gtk/parameters.ui.h:8 -msgid "Audio codecs" -msgstr "" - -#: ../gtk/parameters.ui.h:9 -msgid "Video codecs" -msgstr "" - -#: ../gtk/parameters.ui.h:10 -msgid "C" -msgstr "C" - -#: ../gtk/parameters.ui.h:11 -msgid "SIP (UDP)" -msgstr "" - -#: ../gtk/parameters.ui.h:12 -msgid "SIP (TCP)" -msgstr "" - -#: ../gtk/parameters.ui.h:13 -msgid "SIP (TLS)" -msgstr "" - -#: ../gtk/parameters.ui.h:14 -msgid "Settings" -msgstr "Preferenze" - -#: ../gtk/parameters.ui.h:15 -msgid "Set Maximum Transmission Unit:" -msgstr "Imposta Maximum Transmission Unit:" - -#: ../gtk/parameters.ui.h:16 -msgid "Send DTMFs as SIP info" -msgstr "Invia DTMF come SIP info" - -#: ../gtk/parameters.ui.h:17 -msgid "Allow IPv6" -msgstr "" - -#: ../gtk/parameters.ui.h:18 -msgid "Transport" -msgstr "Transporto" - -#: ../gtk/parameters.ui.h:19 -msgid "SIP/UDP port" -msgstr "" - -#: ../gtk/parameters.ui.h:21 -msgid "Random" -msgstr "" - -#: ../gtk/parameters.ui.h:22 -msgid "SIP/TCP port" -msgstr "" - -#: ../gtk/parameters.ui.h:23 -msgid "Audio RTP/UDP:" -msgstr "Audio RTP/UDP:" - -#: ../gtk/parameters.ui.h:24 -msgid "Fixed" -msgstr "" - -#: ../gtk/parameters.ui.h:25 -msgid "Video RTP/UDP:" -msgstr "Video RTP/UDP" - -#: ../gtk/parameters.ui.h:26 -msgid "Media encryption type" -msgstr "" - -#: ../gtk/parameters.ui.h:27 -msgid "Media encryption is mandatory" -msgstr "" - -#: ../gtk/parameters.ui.h:28 -msgid "Tunnel" -msgstr "" - -#: ../gtk/parameters.ui.h:29 -msgid "DSCP fields" -msgstr "" - -#: ../gtk/parameters.ui.h:30 -msgid "Network protocol and ports" -msgstr "" - -#: ../gtk/parameters.ui.h:31 -msgid "Direct connection to the Internet" -msgstr "Connessione diretta a internet" - -#: ../gtk/parameters.ui.h:32 -msgid "Behind NAT / Firewall (specify gateway IP )" -msgstr "" - -#: ../gtk/parameters.ui.h:33 -msgid "Behind NAT / Firewall (use STUN to resolve)" -msgstr "Dietro NAT / Firewall (utilizza STUN)" - -#: ../gtk/parameters.ui.h:34 -msgid "Behind NAT / Firewall (use ICE)" -msgstr "" - -#: ../gtk/parameters.ui.h:35 -msgid "Behind NAT / Firewall (use uPnP)" -msgstr "" - -#: ../gtk/parameters.ui.h:36 -msgid "Public IP address:" -msgstr "Indirizzo ip pubblico:" - -#: ../gtk/parameters.ui.h:37 -msgid "Stun server:" -msgstr "Stun server:" - -#: ../gtk/parameters.ui.h:38 -msgid "NAT and Firewall" -msgstr "NAT and Firewall" - -#: ../gtk/parameters.ui.h:39 -msgid "Network settings" -msgstr "Impostazioni di rete" - -#: ../gtk/parameters.ui.h:40 -msgid "Ring sound:" -msgstr "Suoneria:" - -#: ../gtk/parameters.ui.h:41 -msgid "ALSA special device (optional):" -msgstr "Dispositivo ALSA (optional):" - -#: ../gtk/parameters.ui.h:42 -msgid "Capture device:" -msgstr "Dispositivo microfono:" - -#: ../gtk/parameters.ui.h:43 -msgid "Ring device:" -msgstr "Dispositivo squillo:" - -#: ../gtk/parameters.ui.h:44 -msgid "Playback device:" -msgstr "Dispositivo uscita audio:" - -#: ../gtk/parameters.ui.h:45 -msgid "Enable echo cancellation" -msgstr "Attiva cancellazione eco" - -#: ../gtk/parameters.ui.h:46 -msgid "Audio" -msgstr "Audio" - -#: ../gtk/parameters.ui.h:47 -msgid "Video input device:" -msgstr "Dispositivo Video:" - -#: ../gtk/parameters.ui.h:48 -msgid "Prefered video resolution:" -msgstr "Risoluzione video preferita" - -#: ../gtk/parameters.ui.h:49 -msgid "Video output method:" -msgstr "" - -#: ../gtk/parameters.ui.h:50 -msgid "Show camera preview" -msgstr "" - -#: ../gtk/parameters.ui.h:51 -msgid "Video" -msgstr "Video" - -#: ../gtk/parameters.ui.h:52 -msgid "Multimedia settings" -msgstr "Impostazioni multimediali" - -#: ../gtk/parameters.ui.h:53 -msgid "This section defines your SIP address when not using a SIP account" -msgstr "questa sezione definisce il tuo indirizzo SIP se non hai account attivi" - -#: ../gtk/parameters.ui.h:54 -msgid "Your display name (eg: John Doe):" -msgstr "Nome visualizzato (es: Mario Rossi):" - -#: ../gtk/parameters.ui.h:55 -msgid "Your username:" -msgstr "Username" - -#: ../gtk/parameters.ui.h:56 -msgid "Your resulting SIP address:" -msgstr "Il tuo indirizzo sip:" - -#: ../gtk/parameters.ui.h:57 -msgid "Default identity" -msgstr "Identità di default" - -#: ../gtk/parameters.ui.h:58 -msgid "Wizard" -msgstr "" - -#: ../gtk/parameters.ui.h:59 -msgid "Add" -msgstr "Aggiungi" - -#: ../gtk/parameters.ui.h:60 -msgid "Edit" -msgstr "Edita" - -#: ../gtk/parameters.ui.h:61 -msgid "Remove" -msgstr "Rimuovi" - -#: ../gtk/parameters.ui.h:62 -msgid "Proxy accounts" -msgstr "Account proxy" - -#: ../gtk/parameters.ui.h:63 -msgid "Erase all passwords" -msgstr "Cancella tutte le password" - -#: ../gtk/parameters.ui.h:64 -msgid "Privacy" -msgstr "Privacy" - -#: ../gtk/parameters.ui.h:65 -msgid "Automatically answer when a call is received" -msgstr "" - -#: ../gtk/parameters.ui.h:66 -msgid "Delay before answering (ms)" -msgstr "" - -#: ../gtk/parameters.ui.h:67 -msgid "Auto-answer" -msgstr "" - -#: ../gtk/parameters.ui.h:68 -msgid "Manage SIP Accounts" -msgstr "Gestici SIP Account" - -#: ../gtk/parameters.ui.h:69 ../gtk/tunnel_config.ui.h:4 -msgid "Enable" -msgstr "Attivato" - -#: ../gtk/parameters.ui.h:70 ../gtk/tunnel_config.ui.h:5 -msgid "Disable" -msgstr "Disattivato" - -#: ../gtk/parameters.ui.h:71 -msgid "Codecs" -msgstr "Codecs" - -#: ../gtk/parameters.ui.h:72 -msgid "0 stands for \"unlimited\"" -msgstr "0 sta per illimitato" - -#: ../gtk/parameters.ui.h:73 -msgid "Upload speed limit in Kbit/sec:" -msgstr "Velocità massima in upload Kbit/sec:" - -#: ../gtk/parameters.ui.h:74 -msgid "Download speed limit in Kbit/sec:" -msgstr "Velocita massima in Dowload Kbit/sec" - -#: ../gtk/parameters.ui.h:75 -msgid "Enable adaptive rate control" -msgstr "" - -#: ../gtk/parameters.ui.h:76 -msgid "" -"Adaptive rate control is a technique to dynamically guess the available " -"bandwidth during a call." -msgstr "" - -#: ../gtk/parameters.ui.h:77 -msgid "Bandwidth control" -msgstr "Gestione banda" - -#: ../gtk/parameters.ui.h:78 -msgid "Codecs" -msgstr "Codec" - -#: ../gtk/parameters.ui.h:79 -msgid "Language" -msgstr "Linguaggio" - -#: ../gtk/parameters.ui.h:80 -msgid "Show advanced settings" -msgstr "" - -#: ../gtk/parameters.ui.h:81 -msgid "Level" -msgstr "" - -#: ../gtk/parameters.ui.h:82 -msgid "User interface" -msgstr "Interfaccia utente" - -#: ../gtk/parameters.ui.h:83 ../gtk/ldap.ui.h:2 -msgid "Server address:" -msgstr "" - -#: ../gtk/parameters.ui.h:84 ../gtk/ldap.ui.h:3 -msgid "Authentication method:" -msgstr "" - -#: ../gtk/parameters.ui.h:86 -msgid "LDAP Account setup" -msgstr "" - -#: ../gtk/parameters.ui.h:87 -msgid "LDAP" -msgstr "" - -#: ../gtk/parameters.ui.h:88 -msgid "Done" -msgstr "Fatto" +msgstr "fr: Simon Morlat\nen: Simon Morlat and Delphine Perreau\nit: Alberto Zanoni \nit: Fabrizio Carrai\nde: Jean-Jacques Sarton \nsv: Daniel Nylander \nes: Jesus Benitez \nja: YAMAGUCHI YOSHIYA \npt_BR: Rafael Caesar Lenzi \npl: Robert Nasiadek \ncs: Petr Pisar \nhu: anonymous\nhe: Eli Zaretskii \n" #: ../gtk/buddylookup.ui.h:1 msgid "Search contacts in directory" @@ -1499,273 +793,1045 @@ msgstr "Aggiungi alla mia lista" msgid "Search somebody" msgstr "Cerca" -#: ../gtk/waiting.ui.h:2 -msgid "Please wait" -msgstr "Prego attendere" +#: ../gtk/callee_frame.ui.h:1 +msgid "Callee name" +msgstr "Nome del chiamato" -#: ../gtk/dscp_settings.ui.h:1 -msgid "DSCP settings" -msgstr "" +#: ../gtk/call_logs.ui.h:1 +msgid "Call history" +msgstr "Cronologia" -#: ../gtk/dscp_settings.ui.h:2 -msgid "SIP" -msgstr "" +#: ../gtk/call_logs.ui.h:2 +msgid "Clear all" +msgstr "Pulisci tutto" -#: ../gtk/dscp_settings.ui.h:3 -msgid "Audio RTP stream" -msgstr "" - -#: ../gtk/dscp_settings.ui.h:4 -msgid "Video RTP stream" -msgstr "" - -#: ../gtk/dscp_settings.ui.h:5 -msgid "Set DSCP values (in hexadecimal)" -msgstr "" +#: ../gtk/call_logs.ui.h:3 +msgid "Call back" +msgstr "Richiamata" #: ../gtk/call_statistics.ui.h:1 msgid "Call statistics" -msgstr "" +msgstr "Statistiche della chiamata" #: ../gtk/call_statistics.ui.h:2 msgid "Audio codec" -msgstr "" +msgstr "Codec audio" #: ../gtk/call_statistics.ui.h:3 msgid "Video codec" -msgstr "" +msgstr "Codec video" #: ../gtk/call_statistics.ui.h:4 msgid "Audio IP bandwidth usage" -msgstr "" +msgstr "Banda IP impiegata per l'audio" #: ../gtk/call_statistics.ui.h:5 msgid "Audio Media connectivity" -msgstr "" +msgstr "Supporto audio" #: ../gtk/call_statistics.ui.h:6 msgid "Video IP bandwidth usage" -msgstr "" +msgstr "Banda IP impiegata per il video" #: ../gtk/call_statistics.ui.h:7 msgid "Video Media connectivity" -msgstr "" +msgstr "Supporto video" #: ../gtk/call_statistics.ui.h:8 msgid "Round trip time" -msgstr "" +msgstr "Tempo di andata/ritorno" #: ../gtk/call_statistics.ui.h:9 msgid "Video resolution received" -msgstr "" +msgstr "Risoluzione video ricevuta" #: ../gtk/call_statistics.ui.h:10 msgid "Video resolution sent" -msgstr "" +msgstr "Risoluzione video trasmessa" #: ../gtk/call_statistics.ui.h:11 msgid "RTP profile" -msgstr "" +msgstr "Profilo RTP" #: ../gtk/call_statistics.ui.h:12 msgid "Call statistics and information" -msgstr "" +msgstr "Statistiche della chiamata e informazioni" -#: ../gtk/tunnel_config.ui.h:1 -msgid "Configure VoIP tunnel" -msgstr "" +#: ../gtk/chatroom_frame.ui.h:1 +msgid "Send" +msgstr "Invia" -#: ../gtk/tunnel_config.ui.h:2 -msgid "Host" -msgstr "" - -#: ../gtk/tunnel_config.ui.h:3 -msgid "Port" -msgstr "" - -#: ../gtk/tunnel_config.ui.h:6 -msgid "Configure tunnel" -msgstr "" - -#: ../gtk/tunnel_config.ui.h:9 -msgid "Configure http proxy (optional)" -msgstr "" - -#: ../gtk/ldap.ui.h:1 -msgid "LDAP Settings" -msgstr "" - -#: ../gtk/ldap.ui.h:6 -msgid "Use TLS Connection" -msgstr "" - -#: ../gtk/ldap.ui.h:7 -msgid "Not yet available" -msgstr "" - -#: ../gtk/ldap.ui.h:8 -msgid "Connection" -msgstr "" - -#: ../gtk/ldap.ui.h:9 -msgid "Bind DN" -msgstr "" - -#: ../gtk/ldap.ui.h:10 -msgid "Authname" -msgstr "" - -#: ../gtk/ldap.ui.h:11 -msgid "Realm" -msgstr "" - -#: ../gtk/ldap.ui.h:12 -msgid "SASL" -msgstr "" - -#: ../gtk/ldap.ui.h:13 -msgid "Base object:" -msgstr "" - -#: ../gtk/ldap.ui.h:15 -#, no-c-format -msgid "Filter (%s for name):" -msgstr "" - -#: ../gtk/ldap.ui.h:16 -msgid "Name Attribute:" -msgstr "" - -#: ../gtk/ldap.ui.h:17 -msgid "SIP address attribute:" -msgstr "" - -#: ../gtk/ldap.ui.h:18 -msgid "Attributes to query:" -msgstr "" - -#: ../gtk/ldap.ui.h:19 -msgid "Search" -msgstr "" - -#: ../gtk/ldap.ui.h:20 -msgid "Timeout for search:" -msgstr "" - -#: ../gtk/ldap.ui.h:21 -msgid "Max results:" -msgstr "" - -#: ../gtk/ldap.ui.h:22 -msgid "Follow Aliases" -msgstr "" - -#: ../gtk/ldap.ui.h:23 -msgid "Miscellaneous" -msgstr "" - -#: ../gtk/ldap.ui.h:24 -msgid "ANONYMOUS" -msgstr "" - -#: ../gtk/ldap.ui.h:25 -msgid "SIMPLE" -msgstr "" - -#: ../gtk/ldap.ui.h:26 -msgid "DIGEST-MD5" -msgstr "" - -#: ../gtk/ldap.ui.h:27 -msgid "NTLM" -msgstr "" +#: ../gtk/conf_frame.ui.h:1 +msgid "End conference" +msgstr "Fine della conferenza" #: ../gtk/config-uri.ui.h:1 msgid "Specifying a remote configuration URI" -msgstr "" +msgstr "Specificare un URI per la configurazione remota" #: ../gtk/config-uri.ui.h:2 msgid "" "This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" "Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " -msgstr "" +msgstr "Questo modulo permette di impostare un indirizzo http o https da cui prelevare la configurazione all'avvio.\nDi seguito inserire o modificare l' URI della configurazione. Dopo aver selezionato OK Linphone verrà automaticamente riavvato per leggere ed usare la nuova configurazione." + +#: ../gtk/contact.ui.h:2 +msgid "SIP Address" +msgstr "Indirizzo SIP" + +#: ../gtk/contact.ui.h:3 +msgid "Show this contact presence status" +msgstr "Mostra lo stato di presenza del contatto" + +#: ../gtk/contact.ui.h:4 +msgid "Allow this contact to see my presence status" +msgstr "Permetti al contatto di vedere il mio stato di presenza" + +#: ../gtk/contact.ui.h:5 +msgid "Contact information" +msgstr "Informazioni sul contatto" + +#: ../gtk/dscp_settings.ui.h:1 +msgid "DSCP settings" +msgstr "Configurazione DSCP" + +#: ../gtk/dscp_settings.ui.h:2 +msgid "SIP" +msgstr "SIP" + +#: ../gtk/dscp_settings.ui.h:3 +msgid "Audio RTP stream" +msgstr "Stream audio RTP" + +#: ../gtk/dscp_settings.ui.h:4 +msgid "Video RTP stream" +msgstr "Stream video RTP" + +#: ../gtk/dscp_settings.ui.h:5 +msgid "Set DSCP values (in hexadecimal)" +msgstr "Valore DSCP (in esadecimale)" + +#: ../gtk/in_call_frame.ui.h:1 +msgid "Click here to set the speakers volume" +msgstr "Selezionare qui per regolare il volume" + +#: ../gtk/in_call_frame.ui.h:5 +msgid "Record this call to an audio file" +msgstr "Registra questa chiamata su un file audio" + +#: ../gtk/in_call_frame.ui.h:6 +msgid "Video" +msgstr "Video" + +#: ../gtk/in_call_frame.ui.h:8 +msgid "Mute" +msgstr "Silenzia" + +#: ../gtk/in_call_frame.ui.h:9 +msgid "Transfer" +msgstr "Trasferimento" + +#: ../gtk/in_call_frame.ui.h:12 +msgid "In call" +msgstr "In chiamata" + +#: ../gtk/in_call_frame.ui.h:13 +msgid "Duration" +msgstr "Durata" + +#: ../gtk/in_call_frame.ui.h:14 +msgid "Call quality rating" +msgstr "Giudizio della qualità della chiamata" + +#: ../gtk/ldap.ui.h:1 +msgid "LDAP Settings" +msgstr "Configurazione LDAP" + +#: ../gtk/ldap.ui.h:2 ../gtk/parameters.ui.h:89 +msgid "Server address:" +msgstr "Indirizzo del server:" + +#: ../gtk/ldap.ui.h:3 ../gtk/parameters.ui.h:90 +msgid "Authentication method:" +msgstr "Metodo di autenticazione" + +#: ../gtk/ldap.ui.h:4 ../gtk/parameters.ui.h:91 ../gtk/setup_wizard.ui.h:17 +msgid "Username:" +msgstr "Nome utente:" + +#: ../gtk/ldap.ui.h:5 ../gtk/password.ui.h:4 ../gtk/setup_wizard.ui.h:18 +msgid "Password:" +msgstr "Password:" + +#: ../gtk/ldap.ui.h:6 +msgid "Use TLS Connection" +msgstr "Usa connessione TLS" + +#: ../gtk/ldap.ui.h:7 +msgid "Not yet available" +msgstr "Not ancora disponibile" + +#: ../gtk/ldap.ui.h:8 +msgid "Connection" +msgstr "Connessione" + +#: ../gtk/ldap.ui.h:9 +msgid "Bind DN" +msgstr "Bind DN" + +#: ../gtk/ldap.ui.h:10 +msgid "Authname" +msgstr "Authname" + +#: ../gtk/ldap.ui.h:11 +msgid "Realm" +msgstr "Dominio" + +#: ../gtk/ldap.ui.h:12 +msgid "SASL" +msgstr "SASL" + +#: ../gtk/ldap.ui.h:13 +msgid "Base object:" +msgstr "Oggetto di base" + +#: ../gtk/ldap.ui.h:15 +#, no-c-format +msgid "Filter (%s for name):" +msgstr "Filtro (%s per il nome):" + +#: ../gtk/ldap.ui.h:16 +msgid "Name Attribute:" +msgstr "Attributo Nome:" + +#: ../gtk/ldap.ui.h:17 +msgid "SIP address attribute:" +msgstr "Attributo SIP address" + +#: ../gtk/ldap.ui.h:18 +msgid "Attributes to query:" +msgstr "Attributo da cercare:" + +#: ../gtk/ldap.ui.h:19 +msgid "Search" +msgstr "Ricerca" + +#: ../gtk/ldap.ui.h:20 +msgid "Timeout for search:" +msgstr "Tempo limite per la ricerca:" + +#: ../gtk/ldap.ui.h:21 +msgid "Max results:" +msgstr "Massimo numero di risultati:" + +#: ../gtk/ldap.ui.h:22 +msgid "Follow Aliases" +msgstr "Segui gli Aliases" + +#: ../gtk/ldap.ui.h:23 +msgid "Miscellaneous" +msgstr "Varie" + +#: ../gtk/ldap.ui.h:24 +msgid "ANONYMOUS" +msgstr "ANONYMOUS" + +#: ../gtk/ldap.ui.h:25 +msgid "SIMPLE" +msgstr "SEMPLICE" + +#: ../gtk/ldap.ui.h:26 +msgid "DIGEST-MD5" +msgstr "DIGEST-MD5" + +#: ../gtk/ldap.ui.h:27 +msgid "NTLM" +msgstr "NTLM" + +#: ../gtk/login_frame.ui.h:1 ../gtk/tunnel_config.ui.h:7 +msgid "Username" +msgstr "Nome utente" + +#: ../gtk/login_frame.ui.h:2 ../gtk/tunnel_config.ui.h:8 +msgid "Password" +msgstr "Password" + +#: ../gtk/login_frame.ui.h:3 +msgid "Internet connection:" +msgstr "Connessione Internet:" + +#: ../gtk/login_frame.ui.h:4 +msgid "Automatically log me in" +msgstr "Login Automatico" + +#: ../gtk/login_frame.ui.h:5 ../gtk/password.ui.h:3 +msgid "UserID" +msgstr "Identificativo utente" + +#: ../gtk/login_frame.ui.h:6 +msgid "Login information" +msgstr "Credenziali di accesso" + +#: ../gtk/login_frame.ui.h:7 +msgid "Welcome!" +msgstr "Benvenuto!" + +#: ../gtk/login_frame.ui.h:8 +msgid "ADSL" +msgstr "ADSL" + +#: ../gtk/login_frame.ui.h:9 +msgid "Fiber Channel" +msgstr "Fibra ottica" + +#: ../gtk/log.ui.h:1 +msgid "Linphone debug window" +msgstr "Linphone debug window" + +#: ../gtk/log.ui.h:2 +msgid "Scroll to end" +msgstr "Vai in fondo" + +#: ../gtk/main.ui.h:1 +msgid "Default" +msgstr "Default" + +#: ../gtk/main.ui.h:2 +msgid "Delete" +msgstr "Cancellare" + +#: ../gtk/main.ui.h:3 +msgid "_Options" +msgstr "_Opzioni" + +#: ../gtk/main.ui.h:4 +msgid "Set configuration URI" +msgstr "Imposta l' URI di configurazione" + +#: ../gtk/main.ui.h:5 +msgid "Always start video" +msgstr "Avvia sempre il video" + +#: ../gtk/main.ui.h:6 +msgid "Enable self-view" +msgstr "Self-view abilitato" + +#: ../gtk/main.ui.h:7 +msgid "Show keypad" +msgstr "Mostra il tastierino" + +#: ../gtk/main.ui.h:8 +msgid "_Help" +msgstr "_Aiuto" + +#: ../gtk/main.ui.h:9 +msgid "Show debug window" +msgstr "Mostra la finestra di debug" + +#: ../gtk/main.ui.h:10 +msgid "_Homepage" +msgstr "_Homepage" + +#: ../gtk/main.ui.h:11 +msgid "Check _Updates" +msgstr "Check _Updates" + +#: ../gtk/main.ui.h:12 +msgid "Account assistant" +msgstr "Assistente per l'account" + +#: ../gtk/main.ui.h:14 +msgid "SIP address or phone number:" +msgstr "Indirizzo sip o numero." + +#: ../gtk/main.ui.h:15 +msgid "Initiate a new call" +msgstr "Inizia una nuova chiamata" + +#: ../gtk/main.ui.h:16 +msgid "Contacts" +msgstr "Contatti" + +#: ../gtk/main.ui.h:17 +msgid "Search" +msgstr "Ricerca" + +#: ../gtk/main.ui.h:18 +msgid "Add contacts from directory" +msgstr "Aggiungi contatti dalla directory" + +#: ../gtk/main.ui.h:19 +msgid "Add contact" +msgstr "Aggiungi un contatto" + +#: ../gtk/main.ui.h:20 +msgid "Clear call history" +msgstr "Cancella la cronologia della chiamate" + +#: ../gtk/main.ui.h:22 +msgid "My current identity:" +msgstr "Identità corrente" + +#: ../gtk/main.ui.h:23 +msgid "Autoanswer is enabled" +msgstr "Risponditore automatico attivato" + +#: ../gtk/parameters.ui.h:1 +msgid "anonymous" +msgstr "anonimo" + +#: ../gtk/parameters.ui.h:2 +msgid "GSSAPI" +msgstr "GSSAPI" + +#: ../gtk/parameters.ui.h:3 +msgid "SASL" +msgstr "SASL" + +#: ../gtk/parameters.ui.h:4 +msgid "default soundcard" +msgstr "default scheda audio" + +#: ../gtk/parameters.ui.h:5 +msgid "a sound card" +msgstr "una scheda audio" + +#: ../gtk/parameters.ui.h:6 +msgid "default camera" +msgstr "default videocamera" + +#: ../gtk/parameters.ui.h:7 +msgid "CIF" +msgstr "CIF" + +#: ../gtk/parameters.ui.h:8 +msgid "Audio codecs" +msgstr "Codificatori audio" + +#: ../gtk/parameters.ui.h:9 +msgid "Video codecs" +msgstr "Codificatori video" + +#: ../gtk/parameters.ui.h:10 +msgid "C" +msgstr "C" + +#: ../gtk/parameters.ui.h:11 +msgid "SIP (UDP)" +msgstr "SIP (UDP)" + +#: ../gtk/parameters.ui.h:12 +msgid "SIP (TCP)" +msgstr "SIP (TCP)" + +#: ../gtk/parameters.ui.h:13 +msgid "SIP (TLS)" +msgstr "SIP (TLS)" + +#: ../gtk/parameters.ui.h:14 +msgid "default" +msgstr "default" + +#: ../gtk/parameters.ui.h:15 +msgid "high-fps" +msgstr "high-fps" + +#: ../gtk/parameters.ui.h:16 +msgid "custom" +msgstr "custom" + +#: ../gtk/parameters.ui.h:17 +msgid "Settings" +msgstr "Preferenze" + +#: ../gtk/parameters.ui.h:18 +msgid "This section defines your SIP address when not using a SIP account" +msgstr "questa sezione definisce il tuo indirizzo SIP se non hai account attivi" + +#: ../gtk/parameters.ui.h:19 +msgid "Your display name (eg: John Doe):" +msgstr "Nome visualizzato (es: Mario Rossi):" + +#: ../gtk/parameters.ui.h:20 +msgid "Your username:" +msgstr "Nome utente:" + +#: ../gtk/parameters.ui.h:21 +msgid "Your resulting SIP address:" +msgstr "Il tuo indirizzo sip:" + +#: ../gtk/parameters.ui.h:22 +msgid "Default identity" +msgstr "Identità di default" + +#: ../gtk/parameters.ui.h:23 +msgid "Wizard" +msgstr "Wizard" + +#: ../gtk/parameters.ui.h:24 +msgid "Add" +msgstr "Aggiungi" + +#: ../gtk/parameters.ui.h:25 +msgid "Edit" +msgstr "Edita" + +#: ../gtk/parameters.ui.h:26 +msgid "Remove" +msgstr "Rimuovi" + +#: ../gtk/parameters.ui.h:27 +msgid "Proxy accounts" +msgstr "Account proxy" + +#: ../gtk/parameters.ui.h:28 +msgid "Erase all passwords" +msgstr "Cancella tutte le password" + +#: ../gtk/parameters.ui.h:29 +msgid "Privacy" +msgstr "Privacy" + +#: ../gtk/parameters.ui.h:30 +msgid "Automatically answer when a call is received" +msgstr "Rispondi automaticamente alla chiamata in arrivo" + +#: ../gtk/parameters.ui.h:31 +msgid "Delay before answering (ms)" +msgstr "Ritardo prima della risposta (ms)" + +#: ../gtk/parameters.ui.h:32 +msgid "Auto-answer" +msgstr "Risposta automatica" + +#: ../gtk/parameters.ui.h:33 +msgid "Manage SIP Accounts" +msgstr "Gestici SIP Account" + +#: ../gtk/parameters.ui.h:34 +msgid "Ring sound:" +msgstr "Suoneria:" + +#: ../gtk/parameters.ui.h:35 +msgid "ALSA special device (optional):" +msgstr "Dispositivo ALSA (optional):" + +#: ../gtk/parameters.ui.h:36 +msgid "Capture device:" +msgstr "Dispositivo microfono:" + +#: ../gtk/parameters.ui.h:37 +msgid "Ring device:" +msgstr "Dispositivo squillo:" + +#: ../gtk/parameters.ui.h:38 +msgid "Playback device:" +msgstr "Dispositivo uscita audio:" + +#: ../gtk/parameters.ui.h:39 +msgid "Enable echo cancellation" +msgstr "Attiva cancellazione eco" + +#: ../gtk/parameters.ui.h:40 +msgid "Audio" +msgstr "Audio" + +#: ../gtk/parameters.ui.h:41 +msgid "Video input device:" +msgstr "Dispositivo Video:" + +#: ../gtk/parameters.ui.h:42 +msgid "Preferred video resolution:" +msgstr "Risoluzione video preferita:" + +#: ../gtk/parameters.ui.h:43 +msgid "Video output method:" +msgstr "Modalità video in uscita:" + +#: ../gtk/parameters.ui.h:44 +msgid "Show camera preview" +msgstr "Mostra il preview della videocamera" + +#: ../gtk/parameters.ui.h:45 +msgid "Video preset:" +msgstr "Preconfigurazione del video:" + +#: ../gtk/parameters.ui.h:46 +msgid "Preferred video framerate:" +msgstr "Frame rate video preferito:" + +#: ../gtk/parameters.ui.h:47 +msgid "0 stands for \"unlimited\"" +msgstr "0 sta per illimitato" + +#: ../gtk/parameters.ui.h:48 +msgid "Video" +msgstr "Video" + +#: ../gtk/parameters.ui.h:49 +msgid "Upload speed limit in Kbit/sec:" +msgstr "Velocità massima in upload Kbit/sec:" + +#: ../gtk/parameters.ui.h:50 +msgid "Download speed limit in Kbit/sec:" +msgstr "Velocita massima in Dowload Kbit/sec" + +#: ../gtk/parameters.ui.h:51 +msgid "Enable adaptive rate control" +msgstr "Abilita il controllo adattivo del rate" + +#: ../gtk/parameters.ui.h:52 +msgid "" +"Adaptive rate control is a technique to dynamically guess the available " +"bandwidth during a call." +msgstr "Il controllo adattivo del rate è una tecnica per la stima dinamica della banda disponibile durante una chiamata" + +#: ../gtk/parameters.ui.h:53 +msgid "Bandwidth control" +msgstr "Gestione banda" + +#: ../gtk/parameters.ui.h:54 +msgid "Multimedia settings" +msgstr "Impostazioni multimediali" + +#: ../gtk/parameters.ui.h:55 +msgid "Set Maximum Transmission Unit:" +msgstr "Imposta Maximum Transmission Unit:" + +#: ../gtk/parameters.ui.h:56 +msgid "Send DTMFs as SIP info" +msgstr "Invia DTMF come SIP info" + +#: ../gtk/parameters.ui.h:57 +msgid "Allow IPv6" +msgstr "Permetti IPv6" + +#: ../gtk/parameters.ui.h:58 +msgid "Transport" +msgstr "Transporto" + +#: ../gtk/parameters.ui.h:59 +msgid "SIP/UDP port" +msgstr "Porta SIP/UDP" + +#: ../gtk/parameters.ui.h:61 +msgid "Random" +msgstr "Casuale" + +#: ../gtk/parameters.ui.h:62 +msgid "SIP/TCP port" +msgstr "Porta SIP/TCP" + +#: ../gtk/parameters.ui.h:63 +msgid "Audio RTP/UDP:" +msgstr "Audio RTP/UDP:" + +#: ../gtk/parameters.ui.h:64 +msgid "Fixed" +msgstr "Fissa" + +#: ../gtk/parameters.ui.h:65 +msgid "Video RTP/UDP:" +msgstr "Video RTP/UDP:" + +#: ../gtk/parameters.ui.h:66 +msgid "Media encryption type" +msgstr "Tipo di cifratura" + +#: ../gtk/parameters.ui.h:67 +msgid "Media encryption is mandatory" +msgstr "La cifratura è obbligatoria" + +#: ../gtk/parameters.ui.h:68 +msgid "Tunnel" +msgstr "Tunnel" + +#: ../gtk/parameters.ui.h:69 +msgid "DSCP fields" +msgstr "Campi DSCP" + +#: ../gtk/parameters.ui.h:70 +msgid "Network protocol and ports" +msgstr "Protocollo di rete e porte" + +#: ../gtk/parameters.ui.h:71 +msgid "Direct connection to the Internet" +msgstr "Connessione diretta a internet" + +#: ../gtk/parameters.ui.h:72 +msgid "Behind NAT / Firewall (specify gateway IP )" +msgstr "Dietro ad un NAT / Firewall (specificare IP del gateway)" + +#: ../gtk/parameters.ui.h:73 +msgid "Behind NAT / Firewall (use STUN to resolve)" +msgstr "Dietro NAT / Firewall (utilizza STUN)" + +#: ../gtk/parameters.ui.h:74 +msgid "Behind NAT / Firewall (use ICE)" +msgstr "Dietro ad un NAT / Firewall (usa ICE)" + +#: ../gtk/parameters.ui.h:75 +msgid "Behind NAT / Firewall (use uPnP)" +msgstr "Dietro ad un NAT / Fiewall (usa uPnP)" + +#: ../gtk/parameters.ui.h:76 +msgid "Public IP address:" +msgstr "Indirizzo IP pubblico:" + +#: ../gtk/parameters.ui.h:77 +msgid "Stun server:" +msgstr "Server STUN:" + +#: ../gtk/parameters.ui.h:78 +msgid "NAT and Firewall" +msgstr "NAT and Firewall" + +#: ../gtk/parameters.ui.h:79 +msgid "Network settings" +msgstr "Impostazioni di rete" + +#: ../gtk/parameters.ui.h:80 ../gtk/tunnel_config.ui.h:4 +msgid "Enable" +msgstr "Attivato" + +#: ../gtk/parameters.ui.h:81 ../gtk/tunnel_config.ui.h:5 +msgid "Disable" +msgstr "Disattivato" + +#: ../gtk/parameters.ui.h:82 +msgid "Audio codecs" +msgstr "Codificatori audio" + +#: ../gtk/parameters.ui.h:83 +msgid "Video codecs" +msgstr "Codificatori video" + +#: ../gtk/parameters.ui.h:84 +msgid "Codecs" +msgstr "Codec" + +#: ../gtk/parameters.ui.h:85 +msgid "Language" +msgstr "Linguaggio" + +#: ../gtk/parameters.ui.h:86 +msgid "Show advanced settings" +msgstr "Mostra la configurazione avanzata" + +#: ../gtk/parameters.ui.h:87 +msgid "Level" +msgstr "Livello" + +#: ../gtk/parameters.ui.h:88 +msgid "User interface" +msgstr "Interfaccia utente" + +#: ../gtk/parameters.ui.h:92 +msgid "LDAP Account setup" +msgstr "Configurazione dell' account LDAP" + +#: ../gtk/parameters.ui.h:93 +msgid "LDAP" +msgstr "LDAP" + +#: ../gtk/parameters.ui.h:94 +msgid "Done" +msgstr "Fatto" + +#: ../gtk/password.ui.h:1 +msgid "Linphone - Authentication required" +msgstr "Linphone - E' richiesta l'autenticazione" + +#: ../gtk/password.ui.h:2 +msgid "Please enter the domain password" +msgstr "Prego inserire la password di dominio" #: ../gtk/provisioning-fetch.ui.h:1 msgid "Configuring..." -msgstr "" +msgstr "Configurando..." #: ../gtk/provisioning-fetch.ui.h:2 msgid "Please wait while fetching configuration from server..." -msgstr "" +msgstr "Caricamento della configurazione dal server, attendere..." -#: ../coreapi/linphonecore.c:1539 +#: ../gtk/setup_wizard.ui.h:1 +msgid "SIP account configuration assistant" +msgstr "Assistente per la configurazione di un account SIP" + +#: ../gtk/setup_wizard.ui.h:2 +msgid "" +"Welcome!\n" +"This assistant will help you to use a SIP account for your calls." +msgstr "Benvenuto!\nL'assistente vi aiuterà ad usare un indirizzo SIP per le vostre chiamate." + +#: ../gtk/setup_wizard.ui.h:4 +msgid "Welcome to the account setup assistant" +msgstr "Benvenuto nel configuratore di account" + +#: ../gtk/setup_wizard.ui.h:5 +msgid "Create an account on linphone.org" +msgstr "Creare un account su linphone.org" + +#: ../gtk/setup_wizard.ui.h:6 +msgid "I have already a linphone.org account and I just want to use it" +msgstr "Ho già un account su linphone.org che voglio usare." + +#: ../gtk/setup_wizard.ui.h:7 +msgid "I have already a sip account and I just want to use it" +msgstr "Ho già un account SIP e voglio usarlo" + +#: ../gtk/setup_wizard.ui.h:8 +msgid "I want to specify a remote configuration URI" +msgstr "Voglio specificare un URI per la configurazione remota" + +#: ../gtk/setup_wizard.ui.h:9 +msgid "Account setup assistant" +msgstr "Configuratore di account" + +#: ../gtk/setup_wizard.ui.h:10 +msgid "Enter your account information" +msgstr "Inserire i dati del vostro account" + +#: ../gtk/setup_wizard.ui.h:11 +msgid "Username*" +msgstr "Nome utente*" + +#: ../gtk/setup_wizard.ui.h:12 +msgid "Password*" +msgstr "Password*" + +#: ../gtk/setup_wizard.ui.h:13 +msgid "Domain*" +msgstr "Dominio*" + +#: ../gtk/setup_wizard.ui.h:14 +msgid "Proxy" +msgstr "Proxy" + +#: ../gtk/setup_wizard.ui.h:15 +msgid "Configure your account (step 1/1)" +msgstr "Configurare il tuo account (passo 1/1)" + +#: ../gtk/setup_wizard.ui.h:16 +msgid "Enter your linphone.org username" +msgstr "Immettere il vostro nome utente su linphone.org" + +#: ../gtk/setup_wizard.ui.h:19 +msgid "Enter your sip username (step 1/1)" +msgstr "Introdurre il vostro nome utente SIP (passo 1/1)" + +#: ../gtk/setup_wizard.ui.h:20 +msgid "(*) Required fields" +msgstr "(*) Campi obbligatori" + +#: ../gtk/setup_wizard.ui.h:21 +msgid "Email: (*)" +msgstr "Email: (*)" + +#: ../gtk/setup_wizard.ui.h:22 +msgid "Username: (*)" +msgstr "Nome utente: (*)" + +#: ../gtk/setup_wizard.ui.h:23 +msgid "Password: (*)" +msgstr "Password: (*)" + +#: ../gtk/setup_wizard.ui.h:24 +msgid "Confirm your password: (*)" +msgstr "Confermare la password: (*)" + +#: ../gtk/setup_wizard.ui.h:25 +msgid "Keep me informed with linphone updates" +msgstr "Mantenetemi aggiornato sugli aggiornamenti di linphone" + +#: ../gtk/setup_wizard.ui.h:26 +msgid "Enter account information (step 1/2)" +msgstr "Introdurre le informazioni dell'account (passo 1/2)" + +#: ../gtk/setup_wizard.ui.h:27 +msgid "Your account is being created, please wait." +msgstr "Il vostro account è stato creato, attendere." + +#: ../gtk/setup_wizard.ui.h:28 +msgid "Account creation in progress" +msgstr "Creazione dell'account in corso" + +#: ../gtk/setup_wizard.ui.h:29 +msgid "" +"Please validate your account by clicking on the link we just sent you by email.\n" +"Then come back here and press Next button." +msgstr "Attivate il vostro account cin il link che vi è appena stato inviato per posta elettronica.\nQuindi tornare qui e premere il tasto \"Avanti\"." + +#: ../gtk/setup_wizard.ui.h:31 +msgid "Validation (step 2/2)" +msgstr "Validazione (passo 2/2)" + +#: ../gtk/setup_wizard.ui.h:32 +msgid "Checking if your account is been validated, please wait." +msgstr "Verifica della validazione dell'account, attendere." + +#: ../gtk/setup_wizard.ui.h:33 +msgid "Account validation check in progress" +msgstr "Controllo della validazione dell'account in corso" + +#: ../gtk/setup_wizard.ui.h:34 +msgid "" +"Error, account not validated, username already used or server unreachable.\n" +"Please go back and try again." +msgstr "Errore, account non valido, nome utente già in uso o server non raggiungibile.\nTornare indietro e riprovare." + +#: ../gtk/setup_wizard.ui.h:36 +msgid "Error" +msgstr "Errore" + +#: ../gtk/setup_wizard.ui.h:37 +msgid "Thank you. Your account is now configured and ready for use." +msgstr "Grazie. Il tuo account è configurato e pronto all'uso" + +#: ../gtk/sip_account.ui.h:1 +msgid "Linphone - Configure a SIP account" +msgstr "Linphone - Configurazione SIP account" + +#: ../gtk/sip_account.ui.h:2 +msgid "Your SIP identity:" +msgstr "Identità SIP" + +#: ../gtk/sip_account.ui.h:3 +msgid "Looks like sip:@" +msgstr "Simile a sip:@" + +#: ../gtk/sip_account.ui.h:4 +msgid "sip:" +msgstr "sip:" + +#: ../gtk/sip_account.ui.h:5 +msgid "SIP Proxy address:" +msgstr "Indirizzo sip proxy:" + +#: ../gtk/sip_account.ui.h:6 +msgid "Looks like sip:" +msgstr "Simile a sip:" + +#: ../gtk/sip_account.ui.h:7 +msgid "Registration duration (sec):" +msgstr "Durata registrazione (sec)" + +#: ../gtk/sip_account.ui.h:8 +msgid "Contact params (optional):" +msgstr "Parametri del contatto (opzionali)" + +#: ../gtk/sip_account.ui.h:9 +msgid "AVPF regular RTCP interval (sec):" +msgstr "AVPF regular RTCP interval (sec):" + +#: ../gtk/sip_account.ui.h:10 +msgid "Route (optional):" +msgstr "Rotta (opzionale)" + +#: ../gtk/sip_account.ui.h:11 +msgid "Transport" +msgstr "Trasporto" + +#: ../gtk/sip_account.ui.h:12 +msgid "Register" +msgstr "Registro" + +#: ../gtk/sip_account.ui.h:13 +msgid "Publish presence information" +msgstr "Pubblica stato della presenza" + +#: ../gtk/sip_account.ui.h:14 +msgid "Enable AVPF" +msgstr "Abilita AVPF" + +#: ../gtk/sip_account.ui.h:15 +msgid "Configure a SIP account" +msgstr "Configurazione SIP account" + +#: ../gtk/tunnel_config.ui.h:1 +msgid "Configure VoIP tunnel" +msgstr "Configurare il tunnel VoIP" + +#: ../gtk/tunnel_config.ui.h:2 +msgid "Host" +msgstr "Host" + +#: ../gtk/tunnel_config.ui.h:3 +msgid "Port" +msgstr "Porta" + +#: ../gtk/tunnel_config.ui.h:6 +msgid "Configure tunnel" +msgstr "Configurazione del tunnel" + +#: ../gtk/tunnel_config.ui.h:9 +msgid "Configure http proxy (optional)" +msgstr "Configurazione del proxy http (opzionale)" + +#: ../gtk/waiting.ui.h:2 +msgid "Please wait" +msgstr "Prego attendere" + +#: ../coreapi/linphonecore.c:1560 msgid "Ready" msgstr "Pronto" -#: ../coreapi/linphonecore.c:2551 +#: ../coreapi/linphonecore.c:2556 msgid "Configuring" -msgstr "" - -#: ../coreapi/linphonecore.c:2725 -msgid "Looking for telephone number destination..." -msgstr "Ricerca numero destinazione..." - -#: ../coreapi/linphonecore.c:2727 -msgid "Could not resolve this number." -msgstr "Impossibile risolvere il numero." +msgstr "Configurando" #. must be known at that time -#: ../coreapi/linphonecore.c:3013 +#: ../coreapi/linphonecore.c:2951 msgid "Contacting" msgstr "In connessione" -#: ../coreapi/linphonecore.c:3018 +#: ../coreapi/linphonecore.c:2956 msgid "Could not call" -msgstr "" +msgstr "Impossibile chiamare" -#: ../coreapi/linphonecore.c:3169 +#: ../coreapi/linphonecore.c:3092 msgid "Sorry, we have reached the maximum number of simultaneous calls" -msgstr "" +msgstr "Spiacenti, è stato raggiunto il massimo numero di chiamate simultanee" -#: ../coreapi/linphonecore.c:3327 +#: ../coreapi/linphonecore.c:3250 msgid "is contacting you" -msgstr "" +msgstr "ti sta contattando" -#: ../coreapi/linphonecore.c:3328 +#: ../coreapi/linphonecore.c:3251 msgid " and asked autoanswer." -msgstr "" +msgstr "e ha richiesto la risposta automatica" -#: ../coreapi/linphonecore.c:3452 +#: ../coreapi/linphonecore.c:3377 msgid "Modifying call parameters..." -msgstr "" +msgstr "Modificando i parametri di chiamata..." -#: ../coreapi/linphonecore.c:3802 +#: ../coreapi/linphonecore.c:3769 msgid "Connected." msgstr "Connessione" -#: ../coreapi/linphonecore.c:3827 +#: ../coreapi/linphonecore.c:3794 msgid "Call aborted" -msgstr "" +msgstr "Chiamata annullata" -#: ../coreapi/linphonecore.c:4024 +#: ../coreapi/linphonecore.c:3983 msgid "Could not pause the call" -msgstr "" +msgstr "Impossibile sospendere la chiamata" -#: ../coreapi/linphonecore.c:4027 +#: ../coreapi/linphonecore.c:3986 msgid "Pausing the current call..." -msgstr "" +msgstr "Sospensione della chiamata in corso..." -#: ../coreapi/misc.c:434 +#: ../coreapi/misc.c:440 msgid "Stun lookup in progress..." msgstr "Ricerca Stun in progresso ..." -#: ../coreapi/misc.c:615 +#: ../coreapi/misc.c:650 msgid "ICE local candidates gathering in progress..." -msgstr "" +msgstr "Raccolta dei candidati ICE locali in corso..." #: ../coreapi/friend.c:33 msgid "Online" -msgstr "Onlinea" +msgstr "In linea" #: ../coreapi/friend.c:36 msgid "Busy" @@ -1793,11 +1859,11 @@ msgstr "Non disturbare" #: ../coreapi/friend.c:54 msgid "Moved" -msgstr "Mosso" +msgstr "Trasferito" #: ../coreapi/friend.c:57 msgid "Using another messaging service" -msgstr "Utilizza una altro servizio di meesaggistica" +msgstr "Utilizza una altro servizio di messaggistica" #: ../coreapi/friend.c:60 msgid "Offline" @@ -1809,172 +1875,179 @@ msgstr "Pendente" #: ../coreapi/friend.c:66 msgid "Vacation" -msgstr "" +msgstr "Assente" #: ../coreapi/friend.c:68 msgid "Unknown status" -msgstr "" +msgstr "Stato sconosciuto" -#: ../coreapi/proxy.c:328 +#: ../coreapi/proxy.c:292 msgid "" "The sip proxy address you entered is invalid, it must start with \"sip:\" " "followed by a hostname." msgstr "L'indirizzo sip proxy utilizzato è invalido, deve iniziare con \"sip:\" seguito dall' hostaname." -#: ../coreapi/proxy.c:334 +#: ../coreapi/proxy.c:298 msgid "" "The sip identity you entered is invalid.\n" "It should look like sip:username@proxydomain, such as sip:alice@example.net" msgstr "L'identità sip utilizza è invalida.\nDovrebbre essere sip:username@proxydomain, esempio: sip:alice@example.net" -#: ../coreapi/proxy.c:1416 +#: ../coreapi/proxy.c:927 +msgid "Looking for telephone number destination..." +msgstr "Ricerca numero destinazione..." + +#: ../coreapi/proxy.c:931 +msgid "Could not resolve this number." +msgstr "Impossibile risolvere il numero." + +#: ../coreapi/proxy.c:1324 #, c-format msgid "Could not login as %s" msgstr "impossibile login come %s" -#: ../coreapi/callbacks.c:428 +#: ../coreapi/proxy.c:1411 +#, c-format +msgid "Refreshing on %s..." +msgstr "Aggiornamento da %s..." + +#: ../coreapi/callbacks.c:423 msgid "Remote ringing." -msgstr "" +msgstr "Il chiamato sta squillando." -#: ../coreapi/callbacks.c:440 +#: ../coreapi/callbacks.c:435 msgid "Remote ringing..." -msgstr "" +msgstr "Il chiamato sta squillando..." -#: ../coreapi/callbacks.c:461 +#: ../coreapi/callbacks.c:458 msgid "Early media." -msgstr "" +msgstr "Early media." -#: ../coreapi/callbacks.c:534 +#: ../coreapi/callbacks.c:488 #, c-format -msgid "Call with %s is paused." -msgstr "" +msgid "Call answered by %s" +msgstr "Risposta da %s." -#: ../coreapi/callbacks.c:547 -#, c-format -msgid "Call answered by %s - on hold." -msgstr "" - -#: ../coreapi/callbacks.c:557 +#: ../coreapi/callbacks.c:527 msgid "Call resumed." -msgstr "" +msgstr "Prosecuzione della chiamata." -#: ../coreapi/callbacks.c:561 -#, c-format -msgid "Call answered by %s." -msgstr "" - -#: ../coreapi/callbacks.c:584 +#: ../coreapi/callbacks.c:582 msgid "Incompatible, check codecs or security settings..." -msgstr "" +msgstr "Incompatibile, controllare i codecs o i parametri della sicurezza..." -#: ../coreapi/callbacks.c:589 ../coreapi/callbacks.c:906 +#: ../coreapi/callbacks.c:587 ../coreapi/callbacks.c:923 msgid "Incompatible media parameters." -msgstr "" +msgstr "Parametri di comunicazione incompatibili." -#: ../coreapi/callbacks.c:619 +#: ../coreapi/callbacks.c:612 msgid "We have been resumed." -msgstr "" +msgstr "La comunicazione è stata ripresa." #. we are being paused -#: ../coreapi/callbacks.c:628 +#: ../coreapi/callbacks.c:620 msgid "We are paused by other party." -msgstr "" +msgstr "L'interlocutore ci ha messi in attesa." -#. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:666 +#: ../coreapi/callbacks.c:630 msgid "Call is updated by remote." -msgstr "" +msgstr "Aggiornamento della chiamata dalla parte remota." -#: ../coreapi/callbacks.c:782 +#: ../coreapi/callbacks.c:799 msgid "Call terminated." msgstr "Chiamata terminata." -#: ../coreapi/callbacks.c:810 +#: ../coreapi/callbacks.c:827 msgid "User is busy." msgstr "Utente occupato" -#: ../coreapi/callbacks.c:811 +#: ../coreapi/callbacks.c:828 msgid "User is temporarily unavailable." msgstr "Utente non disponibile" #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:813 +#: ../coreapi/callbacks.c:830 msgid "User does not want to be disturbed." msgstr "L'utente non vuole essere disturbato" -#: ../coreapi/callbacks.c:814 +#: ../coreapi/callbacks.c:831 msgid "Call declined." msgstr "Chiamata rifiutata" -#: ../coreapi/callbacks.c:829 +#: ../coreapi/callbacks.c:846 msgid "Request timeout." -msgstr "" +msgstr "Richiesta scaduta" -#: ../coreapi/callbacks.c:860 +#: ../coreapi/callbacks.c:877 msgid "Redirected" -msgstr "" +msgstr "Trasferito" -#: ../coreapi/callbacks.c:915 +#: ../coreapi/callbacks.c:927 msgid "Call failed." -msgstr "" +msgstr "Chiamata non riuscita." -#: ../coreapi/callbacks.c:993 +#: ../coreapi/callbacks.c:1005 #, c-format msgid "Registration on %s successful." msgstr "Registrazione su %s attiva" -#: ../coreapi/callbacks.c:994 +#: ../coreapi/callbacks.c:1006 #, c-format msgid "Unregistration on %s done." msgstr "Unregistrazione su %s" -#: ../coreapi/callbacks.c:1012 +#: ../coreapi/callbacks.c:1024 msgid "no response timeout" msgstr "timeout no risposta" -#: ../coreapi/callbacks.c:1015 +#: ../coreapi/callbacks.c:1027 #, c-format msgid "Registration on %s failed: %s" msgstr "Registrazione su %s fallita: %s" -#: ../coreapi/callbacks.c:1022 +#: ../coreapi/callbacks.c:1034 msgid "Service unavailable, retrying" -msgstr "" +msgstr "Servizio non disponibile, nuovo tentativo in corso" #. if encryption is DTLS, no status to be displayed -#: ../coreapi/linphonecall.c:180 +#: ../coreapi/linphonecall.c:197 #, c-format msgid "Authentication token is %s" -msgstr "" +msgstr "Il codice di autenticazione è %s" -#: ../coreapi/linphonecall.c:1310 +#: ../coreapi/linphonecall.c:1561 +#, c-format +msgid "Call parameters could not be modified: %s." +msgstr "I parametri della chiamata sono stati modificati con successo: %s." + +#: ../coreapi/linphonecall.c:1563 msgid "Call parameters were successfully modified." -msgstr "" +msgstr "I parametri della chiamata sono stati modificati con successo." -#: ../coreapi/linphonecall.c:3686 +#: ../coreapi/linphonecall.c:4396 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%i chiamata persa." +msgstr[1] "%i chiamate perse." -#: ../coreapi/call_log.c:209 +#: ../coreapi/call_log.c:223 msgid "aborted" -msgstr "" +msgstr "annulata" -#: ../coreapi/call_log.c:212 +#: ../coreapi/call_log.c:226 msgid "completed" -msgstr "" +msgstr "completata" -#: ../coreapi/call_log.c:215 +#: ../coreapi/call_log.c:229 msgid "missed" -msgstr "" +msgstr "persa" -#: ../coreapi/call_log.c:218 +#: ../coreapi/call_log.c:232 msgid "unknown" -msgstr "" +msgstr "sconosciuto" -#: ../coreapi/call_log.c:220 +#: ../coreapi/call_log.c:234 #, c-format msgid "" "%s at %s\n" @@ -1982,13 +2055,13 @@ msgid "" "To: %s\n" "Status: %s\n" "Duration: %i mn %i sec\n" -msgstr "" +msgstr "%s a %s\nDa: %s\nA: %s\nStato: %s\nDurata: %i min %i sec\n" -#: ../coreapi/call_log.c:221 +#: ../coreapi/call_log.c:235 msgid "Outgoing call" -msgstr "" +msgstr "chiamata in uscita" #: ../gtk/videowindow.c:66 #, c-format msgid "Cannot play %s." -msgstr "" +msgstr "Impossibile riprodurre %s." diff --git a/po/ja.po b/po/ja.po index 3707eeab9..566b0b0d1 100644 --- a/po/ja.po +++ b/po/ja.po @@ -9,72 +9,81 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-04-30 10:13+0200\n" -"PO-Revision-Date: 2015-04-30 08:13+0000\n" +"POT-Creation-Date: 2015-11-10 15:16+0100\n" +"PO-Revision-Date: 2015-11-10 14:16+0000\n" "Last-Translator: Belledonne Communications \n" -"Language-Team: Japanese (http://www.transifex.com/projects/p/linphone-gtk/language/ja/)\n" +"Language-Team: Japanese (http://www.transifex.com/belledonne-communications/linphone-gtk/language/ja/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: ja\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: ../gtk/calllogs.c:148 ../gtk/friendlist.c:974 +#: ../gtk/calllogs.c:178 #, c-format msgid "Call %s" msgstr "%s を呼び出し中" -#: ../gtk/calllogs.c:149 ../gtk/friendlist.c:975 +#: ../gtk/calllogs.c:179 #, c-format msgid "Send text to %s" msgstr "%s に文章を送信" -#: ../gtk/calllogs.c:232 +#: ../gtk/calllogs.c:181 +#, c-format +msgid "Add %s to your contact list" +msgstr "%sを連絡先に追加" + +#: ../gtk/calllogs.c:245 ../gtk/main.ui.h:21 +msgid "Recent calls" +msgstr "通話時間" + +#: ../gtk/calllogs.c:260 #, c-format msgid "Recent calls (%i)" msgstr "通話時間 (%i)" -#: ../gtk/calllogs.c:314 +#: ../gtk/calllogs.c:331 msgid "n/a" msgstr "n/a" -#: ../gtk/calllogs.c:317 +#: ../gtk/calllogs.c:334 msgid "Aborted" msgstr "中断" -#: ../gtk/calllogs.c:320 +#: ../gtk/calllogs.c:337 msgid "Missed" msgstr "失敗" -#: ../gtk/calllogs.c:323 +#: ../gtk/calllogs.c:340 msgid "Declined" msgstr "辞退" -#: ../gtk/calllogs.c:329 +#: ../gtk/calllogs.c:346 #, c-format msgid "%i minute" msgid_plural "%i minutes" msgstr[0] "%i 分" -#: ../gtk/calllogs.c:332 +#: ../gtk/calllogs.c:349 #, c-format msgid "%i second" msgid_plural "%i seconds" msgstr[0] "%i 秒" -#: ../gtk/calllogs.c:337 +#: ../gtk/calllogs.c:354 #, c-format msgid "" "%s\tQuality: %s\n" "%s\t%s\t" msgstr "%s品質: %s\n%s⇥%s⇥" -#: ../gtk/calllogs.c:341 +#: ../gtk/calllogs.c:358 #, c-format msgid "%s\t%s" msgstr "%s⇥%s" -#: ../gtk/conference.c:38 ../gtk/main.ui.h:13 +#: ../gtk/conference.c:38 ../gtk/in_call_frame.ui.h:11 msgid "Conference" msgstr "会議" @@ -87,297 +96,314 @@ msgstr "自分" msgid "Couldn't find pixmap file: %s" msgstr "pixmapファイルが見つかりません %s" -#: ../gtk/main.c:137 +#: ../gtk/chat.c:196 ../gtk/chat.c:254 +msgid "Sending..." +msgstr "" + +#: ../gtk/chat.c:213 ../gtk/chat.c:263 +msgid "Message not sent" +msgstr "" + +#: ../gtk/chat.c:472 +msgid "Copy" +msgstr "コピー" + +#: ../gtk/main.c:138 msgid "log to stdout some debug information while running." msgstr "実行中にいくつかのデバッグ情報をstdoutに送信します。" -#: ../gtk/main.c:138 +#: ../gtk/main.c:139 +msgid "display version and exit." +msgstr "バージョン表示と退出" + +#: ../gtk/main.c:140 msgid "path to a file to write logs into." msgstr "ログを書き込むファイルへのパス。" -#: ../gtk/main.c:139 +#: ../gtk/main.c:141 msgid "Start linphone with video disabled." msgstr "ビデオを無効にしてLinphoneを開始します。" -#: ../gtk/main.c:140 +#: ../gtk/main.c:142 msgid "Start only in the system tray, do not show the main interface." msgstr "主なインターフェイスを表示しないでシステムトレイに移動します。" -#: ../gtk/main.c:141 +#: ../gtk/main.c:143 msgid "address to call right now" msgstr "今すぐに呼び出す" -#: ../gtk/main.c:142 +#: ../gtk/main.c:144 msgid "" "Specifiy a working directory (should be the base of the installation, eg: " "c:\\Program Files\\Linphone)" msgstr "作業ディレクトリをSpecifiy (インストールした時のベースである必要があります。例:c:\\Program Files\\Linphone)" -#: ../gtk/main.c:143 +#: ../gtk/main.c:145 msgid "Configuration file" msgstr "設定ファイル" -#: ../gtk/main.c:144 +#: ../gtk/main.c:146 msgid "Run the audio assistant" msgstr "オーディオアシスタントを実行" -#: ../gtk/main.c:145 +#: ../gtk/main.c:147 msgid "Run self test and exit 0 if succeed" -msgstr "" +msgstr "セルフテストは0で終了したら成功です" -#: ../gtk/main.c:1070 +#: ../gtk/main.c:1046 #, c-format msgid "" -"%s would like to add you to his contact list.\n" -"Would you allow him to see your presence status or add him to your contact list ?\n" +"%s would like to add you to his/her contact list.\n" +"Would you add him/her to your contact list and allow him/her to see your presence status?\n" "If you answer no, this person will be temporarily blacklisted." -msgstr "%s が連絡相手にあなたを追加しようとしています。\nあなたのステータスを参照させるか、もしくは連絡先リストに追加することができます。\nあなたが拒否すると、この人は一時的にブラックリストへ登録されます。" +msgstr "相手が自分の連絡先に%sを追加したいそうです。\nあなたが自分の連絡先に相手を追加したらできるようになり相手のステータスも表示されるようになります。\n拒否した場合その相手は一時的にブラックリストに登録されます。" -#: ../gtk/main.c:1147 +#: ../gtk/main.c:1123 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" -msgstr "" +msgstr "パスワードを入力してください %s\nrealm %s:" -#: ../gtk/main.c:1268 +#: ../gtk/main.c:1253 msgid "Call error" msgstr "呼出エラー" -#: ../gtk/main.c:1271 ../coreapi/linphonecore.c:3846 +#: ../gtk/main.c:1256 ../coreapi/linphonecore.c:3813 msgid "Call ended" msgstr "呼出終了" -#: ../gtk/main.c:1274 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1259 ../coreapi/call_log.c:235 msgid "Incoming call" msgstr "着信" -#: ../gtk/main.c:1276 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1261 ../gtk/incall_view.c:580 ../gtk/in_call_frame.ui.h:2 msgid "Answer" msgstr "応答" -#: ../gtk/main.c:1278 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1263 ../gtk/in_call_frame.ui.h:3 msgid "Decline" msgstr "拒否" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 msgid "Call paused" msgstr "呼び出しの一時停止" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 #, c-format msgid "by %s" msgstr "%s" -#: ../gtk/main.c:1354 +#: ../gtk/main.c:1339 #, c-format msgid "%s proposed to start video. Do you accept ?" -msgstr "" +msgstr "%sがテレビ電話をしたいそうですが受け入れますか?" -#: ../gtk/main.c:1509 +#: ../gtk/main.c:1505 msgid "Website link" msgstr "ウェブサイトリンク" -#: ../gtk/main.c:1568 ../gtk/waiting.ui.h:1 +#: ../gtk/main.c:1564 ../gtk/waiting.ui.h:1 msgid "Linphone" msgstr "Linphone" -#: ../gtk/main.c:1569 +#: ../gtk/main.c:1565 msgid "A video internet phone" -msgstr "" +msgstr "テレビ電話" -#: ../gtk/main.c:1629 +#: ../gtk/main.c:1624 #, c-format msgid "%s (Default)" msgstr "%s (デフォルト)" -#: ../gtk/main.c:1962 ../coreapi/callbacks.c:1063 +#: ../gtk/main.c:1960 ../coreapi/callbacks.c:1075 #, c-format msgid "We are transferred to %s" msgstr "%s に転送しました" -#: ../gtk/main.c:1972 +#: ../gtk/main.c:1970 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." -msgstr "" +msgstr "サウンドカードが検出されていません。\n音声通話の送受信はできません。" -#: ../gtk/main.c:2117 +#: ../gtk/main.c:2129 msgid "A free SIP video-phone" msgstr "無料 SIP ビデオ-電話" -#: ../gtk/main.c:2221 +#: ../gtk/main.c:2242 #, c-format msgid "Hello\n" -msgstr "" +msgstr "こんにちは\n" -#: ../gtk/friendlist.c:505 +#: ../gtk/friendlist.c:461 msgid "Add to addressbook" msgstr "電話帳に追加する" -#: ../gtk/friendlist.c:691 -msgid "Presence status" -msgstr "状態のステータス" - -#: ../gtk/friendlist.c:709 ../gtk/propertybox.c:569 ../gtk/contact.ui.h:1 -msgid "Name" -msgstr "名前" - -#: ../gtk/friendlist.c:721 -msgid "Call" -msgstr "通話" - -#: ../gtk/friendlist.c:726 -msgid "Chat" -msgstr "チャット" - -#: ../gtk/friendlist.c:756 +#: ../gtk/friendlist.c:627 #, c-format msgid "Search in %s directory" msgstr "%s のディレクトリ内を検索" -#: ../gtk/friendlist.c:924 +#: ../gtk/friendlist.c:772 msgid "Invalid sip contact !" msgstr "無効なSIP接続です!" -#: ../gtk/friendlist.c:976 +#: ../gtk/friendlist.c:820 +#, c-format +msgid "Add a new contact" +msgstr "新しい連絡先を追加する" + +#: ../gtk/friendlist.c:823 #, c-format msgid "Edit contact '%s'" msgstr "'%s' の連絡先を編集" -#: ../gtk/friendlist.c:977 +#: ../gtk/friendlist.c:824 #, c-format msgid "Delete contact '%s'" msgstr "'%s' の連絡先を削除" -#: ../gtk/friendlist.c:978 +#: ../gtk/friendlist.c:825 #, c-format msgid "Delete chat history of '%s'" msgstr "'%s' のチャット履歴を削除" -#: ../gtk/friendlist.c:1029 +#: ../gtk/friendlist.c:862 #, c-format msgid "Add new contact from %s directory" -msgstr "" +msgstr "フォルダ %s から連絡先を追加する" -#: ../gtk/propertybox.c:575 +#: ../gtk/propertybox.c:592 ../gtk/contact.ui.h:1 +msgid "Name" +msgstr "名前" + +#: ../gtk/propertybox.c:598 msgid "Rate (Hz)" msgstr "レート (Hz)" -#: ../gtk/propertybox.c:581 +#: ../gtk/propertybox.c:604 msgid "Status" msgstr "状態" -#: ../gtk/propertybox.c:587 +#: ../gtk/propertybox.c:617 msgid "IP Bitrate (kbit/s)" msgstr "IP ビットレート (kbit/s)" -#: ../gtk/propertybox.c:596 +#: ../gtk/propertybox.c:628 msgid "Parameters" msgstr "パラメーター" -#: ../gtk/propertybox.c:639 ../gtk/propertybox.c:782 +#: ../gtk/propertybox.c:670 ../gtk/propertybox.c:824 msgid "Enabled" msgstr "使用する" -#: ../gtk/propertybox.c:641 ../gtk/propertybox.c:782 ../gtk/parameters.ui.h:20 +#: ../gtk/propertybox.c:672 ../gtk/propertybox.c:824 ../gtk/parameters.ui.h:60 msgid "Disabled" msgstr "使用しない" -#: ../gtk/propertybox.c:828 +#: ../gtk/propertybox.c:902 msgid "Account" msgstr "アカウント" -#: ../gtk/propertybox.c:1091 +#: ../gtk/propertybox.c:1170 msgid "English" msgstr "English" -#: ../gtk/propertybox.c:1092 +#: ../gtk/propertybox.c:1171 msgid "French" msgstr "Français" -#: ../gtk/propertybox.c:1093 +#: ../gtk/propertybox.c:1172 msgid "Swedish" msgstr "Svenska" -#: ../gtk/propertybox.c:1094 +#: ../gtk/propertybox.c:1173 msgid "Italian" msgstr "Italiano" -#: ../gtk/propertybox.c:1095 +#: ../gtk/propertybox.c:1174 msgid "Spanish" msgstr "Español" -#: ../gtk/propertybox.c:1096 +#: ../gtk/propertybox.c:1175 msgid "Brazilian Portugese" msgstr "Português do Brasil" -#: ../gtk/propertybox.c:1097 +#: ../gtk/propertybox.c:1176 msgid "Polish" msgstr "Polski" -#: ../gtk/propertybox.c:1098 +#: ../gtk/propertybox.c:1177 msgid "German" msgstr "Deutsch" -#: ../gtk/propertybox.c:1099 +#: ../gtk/propertybox.c:1178 msgid "Russian" msgstr "Pусский" -#: ../gtk/propertybox.c:1100 +#: ../gtk/propertybox.c:1179 msgid "Japanese" msgstr "日本語" -#: ../gtk/propertybox.c:1101 +#: ../gtk/propertybox.c:1180 msgid "Dutch" msgstr "Nederlands" -#: ../gtk/propertybox.c:1102 +#: ../gtk/propertybox.c:1181 msgid "Hungarian" msgstr "Magyar" -#: ../gtk/propertybox.c:1103 +#: ../gtk/propertybox.c:1182 msgid "Czech" msgstr "čeština" -#: ../gtk/propertybox.c:1104 +#: ../gtk/propertybox.c:1183 msgid "Chinese" msgstr "简体中文" -#: ../gtk/propertybox.c:1105 +#: ../gtk/propertybox.c:1184 msgid "Traditional Chinese" msgstr "繁体中文" -#: ../gtk/propertybox.c:1106 +#: ../gtk/propertybox.c:1185 msgid "Norwegian" msgstr "Norsk" -#: ../gtk/propertybox.c:1107 +#: ../gtk/propertybox.c:1186 msgid "Hebrew" msgstr "עברית" -#: ../gtk/propertybox.c:1108 +#: ../gtk/propertybox.c:1187 msgid "Serbian" msgstr "Cрпски" -#: ../gtk/propertybox.c:1175 +#: ../gtk/propertybox.c:1188 +msgid "Arabic" +msgstr "アラビア語" + +#: ../gtk/propertybox.c:1189 +msgid "Turkish" +msgstr "トルコ語" + +#: ../gtk/propertybox.c:1246 msgid "" "You need to restart linphone for the new language selection to take effect." msgstr "言語の選択を有効にするには、 Linphoneを再起動する必要があります。" -#: ../gtk/propertybox.c:1255 +#: ../gtk/propertybox.c:1326 msgid "None" msgstr "なし" -#: ../gtk/propertybox.c:1259 +#: ../gtk/propertybox.c:1330 msgid "SRTP" msgstr "SRTP" -#: ../gtk/propertybox.c:1265 +#: ../gtk/propertybox.c:1336 msgid "DTLS" -msgstr "" +msgstr "DTLS" -#: ../gtk/propertybox.c:1272 +#: ../gtk/propertybox.c:1343 msgid "ZRTP" msgstr "ZRTP" @@ -418,595 +444,311 @@ msgid "Found %i contact" msgid_plural "Found %i contacts" msgstr[0] "%i 件発見" -#: ../gtk/setupwizard.c:32 -msgid "" -"Welcome!\n" -"This assistant will help you to use a SIP account for your calls." -msgstr "ようこそ!\nあなたの通話のためのSIPアカウント設定をお手伝いします。" - -#: ../gtk/setupwizard.c:41 -msgid "Create an account on linphone.org" -msgstr "linphone.orgのアカウントを作成" - -#: ../gtk/setupwizard.c:42 -msgid "I have already a linphone.org account and I just want to use it" -msgstr "linphone.orgのアカウントを持っているのでそれを使います" - -#: ../gtk/setupwizard.c:43 -msgid "I have already a sip account and I just want to use it" -msgstr "SIPアカウントを持っているのでそれを使います" - -#: ../gtk/setupwizard.c:44 -msgid "I want to specify a remote configuration URI" -msgstr "" - -#: ../gtk/setupwizard.c:87 -msgid "Enter your linphone.org username" -msgstr "linphone.orgで取得したユーザー名を入力" - -#: ../gtk/setupwizard.c:100 ../gtk/parameters.ui.h:85 ../gtk/ldap.ui.h:4 -msgid "Username:" -msgstr "ユーザー名:" - -#: ../gtk/setupwizard.c:102 ../gtk/password.ui.h:4 ../gtk/ldap.ui.h:5 -msgid "Password:" -msgstr "パスワード:" - -#: ../gtk/setupwizard.c:122 -msgid "Enter your account informations" -msgstr "アカウント情報を入力" - -#: ../gtk/setupwizard.c:138 -msgid "Username*" -msgstr "ユーザー名*" - -#: ../gtk/setupwizard.c:139 -msgid "Password*" -msgstr "パスワード*" - -#: ../gtk/setupwizard.c:142 -msgid "Domain*" -msgstr "ドメイン*" - -#: ../gtk/setupwizard.c:143 -msgid "Proxy" -msgstr "プロキシ*" - -#: ../gtk/setupwizard.c:322 -msgid "(*) Required fields" -msgstr "(*) 必須" - -#: ../gtk/setupwizard.c:323 -msgid "Username: (*)" -msgstr "ユーザー名: (*)" - -#: ../gtk/setupwizard.c:325 -msgid "Password: (*)" -msgstr "パスワード: (*)" - -#: ../gtk/setupwizard.c:327 -msgid "Email: (*)" -msgstr "メールアドレス: (*)" - -#: ../gtk/setupwizard.c:329 -msgid "Confirm your password: (*)" -msgstr "パスワードを再入力: (*)" - -#: ../gtk/setupwizard.c:343 -msgid "Keep me informed with linphone updates" -msgstr "アップデートでLinphoneを常に最新にする" - -#: ../gtk/setupwizard.c:399 -msgid "" -"Error, account not validated, username already used or server unreachable.\n" -"Please go back and try again." -msgstr "" - -#: ../gtk/setupwizard.c:410 -msgid "Thank you. Your account is now configured and ready for use." -msgstr "ありがとう。あなたのアカウントは無事に設定され、使用する準備ができました。" - -#: ../gtk/setupwizard.c:418 -msgid "" -"Please validate your account by clicking on the link we just sent you by email.\n" -"Then come back here and press Next button." -msgstr "送信されたメールの本文内にあるリンクをクリックしてアカウントを有効にしてください。\nその後こちらへ戻って「次へ」を押してください。" - -#: ../gtk/setupwizard.c:609 -msgid "SIP account configuration assistant" -msgstr "SIPアカウント設定アシスタント" - -#: ../gtk/setupwizard.c:629 -msgid "Welcome to the account setup assistant" -msgstr "アカウント設定アシスタントへようこそ" - -#: ../gtk/setupwizard.c:634 -msgid "Account setup assistant" -msgstr "アカウント設定アシスタント" - -#: ../gtk/setupwizard.c:640 -msgid "Configure your account (step 1/1)" -msgstr "アカウントを設定します (1/1)" - -#: ../gtk/setupwizard.c:645 -msgid "Enter your sip username (step 1/1)" -msgstr "SIPのユーザー名を入力してください (1/1)" - -#: ../gtk/setupwizard.c:649 -msgid "Enter account information (step 1/2)" -msgstr "アカウント情報を入力してください (1/2)" - -#: ../gtk/setupwizard.c:658 -msgid "Validation (step 2/2)" -msgstr "検証します (2/2)" - -#: ../gtk/setupwizard.c:663 -msgid "Error" -msgstr "エラー" - -#: ../gtk/setupwizard.c:667 ../gtk/audio_assistant.c:534 -msgid "Terminating" -msgstr "終了" - -#: ../gtk/incall_view.c:70 ../gtk/incall_view.c:94 +#: ../gtk/incall_view.c:67 ../gtk/incall_view.c:87 #, c-format msgid "Call #%i" msgstr "呼び出し #%i" -#: ../gtk/incall_view.c:155 +#: ../gtk/incall_view.c:145 #, c-format msgid "Transfer to call #%i with %s" -msgstr "" +msgstr "通話 #%i を %s に転送する" -#: ../gtk/incall_view.c:211 ../gtk/incall_view.c:214 +#: ../gtk/incall_view.c:202 ../gtk/incall_view.c:205 msgid "Not used" msgstr "使用しない" -#: ../gtk/incall_view.c:221 +#: ../gtk/incall_view.c:212 msgid "ICE not activated" msgstr "ICE 未認証" -#: ../gtk/incall_view.c:223 +#: ../gtk/incall_view.c:214 msgid "ICE failed" msgstr "ICE 失敗" -#: ../gtk/incall_view.c:225 +#: ../gtk/incall_view.c:216 msgid "ICE in progress" msgstr "ICE 進行中" -#: ../gtk/incall_view.c:227 +#: ../gtk/incall_view.c:218 msgid "Going through one or more NATs" -msgstr "" +msgstr "NATを通ります" -#: ../gtk/incall_view.c:229 +#: ../gtk/incall_view.c:220 msgid "Direct" msgstr "直接" -#: ../gtk/incall_view.c:231 +#: ../gtk/incall_view.c:222 msgid "Through a relay server" msgstr "間接的にリレーサーバーを使う" -#: ../gtk/incall_view.c:239 +#: ../gtk/incall_view.c:230 msgid "uPnP not activated" msgstr "uPnPは作動しておりません" -#: ../gtk/incall_view.c:241 +#: ../gtk/incall_view.c:232 msgid "uPnP in progress" msgstr "uPnPを使用中" -#: ../gtk/incall_view.c:243 +#: ../gtk/incall_view.c:234 msgid "uPnp not available" msgstr "uPnPは利用できません" -#: ../gtk/incall_view.c:245 +#: ../gtk/incall_view.c:236 msgid "uPnP is running" msgstr "uPnP作動中" -#: ../gtk/incall_view.c:247 +#: ../gtk/incall_view.c:238 msgid "uPnP failed" msgstr "uPnP失敗" -#: ../gtk/incall_view.c:257 ../gtk/incall_view.c:258 +#: ../gtk/incall_view.c:248 ../gtk/incall_view.c:249 msgid "Direct or through server" -msgstr "" +msgstr "直接またはサーバー経由" -#: ../gtk/incall_view.c:267 ../gtk/incall_view.c:279 +#: ../gtk/incall_view.c:258 ../gtk/incall_view.c:270 #, c-format msgid "" "download: %f\n" "upload: %f (kbit/s)" msgstr "ダウンロード: %f\nアップロード: %f (kbit/s)" -#: ../gtk/incall_view.c:272 ../gtk/incall_view.c:274 +#: ../gtk/incall_view.c:263 ../gtk/incall_view.c:265 #, c-format msgid "%ix%i @ %f fps" msgstr "%ix%i @ %f fps" -#: ../gtk/incall_view.c:304 +#: ../gtk/incall_view.c:295 #, c-format msgid "%.3f seconds" msgstr "%.3f 秒" -#: ../gtk/incall_view.c:407 ../gtk/main.ui.h:12 ../gtk/videowindow.c:235 +#: ../gtk/incall_view.c:453 ../gtk/in_call_frame.ui.h:10 +#: ../gtk/videowindow.c:236 msgid "Hang up" -msgstr "" +msgstr "電話を切る" -#: ../gtk/incall_view.c:511 +#: ../gtk/incall_view.c:559 msgid "Calling..." msgstr "かけています…" -#: ../gtk/incall_view.c:514 ../gtk/incall_view.c:733 -msgid "00::00::00" -msgstr "00::00::00" +#: ../gtk/incall_view.c:562 ../gtk/incall_view.c:792 +msgid "00:00:00" +msgstr "00:00:00" -#: ../gtk/incall_view.c:525 +#: ../gtk/incall_view.c:573 msgid "Incoming call" msgstr "着信" -#: ../gtk/incall_view.c:562 +#: ../gtk/incall_view.c:610 msgid "good" msgstr "良い" -#: ../gtk/incall_view.c:564 +#: ../gtk/incall_view.c:612 msgid "average" msgstr "アベレージ" -#: ../gtk/incall_view.c:566 +#: ../gtk/incall_view.c:614 msgid "poor" msgstr "悪い" -#: ../gtk/incall_view.c:568 +#: ../gtk/incall_view.c:616 msgid "very poor" msgstr "非常にプアな" -#: ../gtk/incall_view.c:570 +#: ../gtk/incall_view.c:618 msgid "too bad" msgstr "非常にバッドな" -#: ../gtk/incall_view.c:571 ../gtk/incall_view.c:587 +#: ../gtk/incall_view.c:619 ../gtk/incall_view.c:635 msgid "unavailable" msgstr "利用できません" -#: ../gtk/incall_view.c:679 +#: ../gtk/incall_view.c:731 msgid "Secured by SRTP" msgstr "SRTPのセキュリティ" -#: ../gtk/incall_view.c:685 +#: ../gtk/incall_view.c:737 msgid "Secured by DTLS" -msgstr "" +msgstr "DTLSセキュリティ" -#: ../gtk/incall_view.c:691 +#: ../gtk/incall_view.c:743 #, c-format msgid "Secured by ZRTP - [auth token: %s]" msgstr "ZRTP によるセキュリティ - [auth token: %s]" -#: ../gtk/incall_view.c:697 +#: ../gtk/incall_view.c:747 msgid "Set unverified" msgstr "セット未検証" -#: ../gtk/incall_view.c:697 ../gtk/main.ui.h:4 +#: ../gtk/incall_view.c:747 msgid "Set verified" msgstr "セット検証済" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In conference" msgstr "会議で" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In call" msgstr "呼び出し中" -#: ../gtk/incall_view.c:764 +#: ../gtk/incall_view.c:824 msgid "Paused call" msgstr "呼び出し停止" -#: ../gtk/incall_view.c:800 +#: ../gtk/incall_view.c:861 msgid "Call ended." msgstr "呼び出し終了" -#: ../gtk/incall_view.c:831 +#: ../gtk/incall_view.c:892 msgid "Transfer in progress" msgstr "進行中の転送" -#: ../gtk/incall_view.c:834 +#: ../gtk/incall_view.c:895 msgid "Transfer done." msgstr "転送完了。" -#: ../gtk/incall_view.c:837 +#: ../gtk/incall_view.c:898 msgid "Transfer failed." msgstr "転送失敗。" -#: ../gtk/incall_view.c:881 +#: ../gtk/incall_view.c:929 msgid "Resume" msgstr "レジューム" -#: ../gtk/incall_view.c:888 ../gtk/main.ui.h:9 +#: ../gtk/incall_view.c:929 ../gtk/in_call_frame.ui.h:7 msgid "Pause" msgstr "一時停止" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 #, c-format msgid "" "Recording into\n" "%s %s" -msgstr "" +msgstr "記録\n%s %s" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 msgid "(Paused)" msgstr "(停止中)" -#: ../gtk/loginframe.c:87 +#: ../gtk/loginframe.c:75 #, c-format msgid "Please enter login information for %s" -msgstr "" +msgstr "%sの情報はログインしてご確認ください" #: ../gtk/config-fetching.c:57 #, c-format msgid "fetching from %s" -msgstr "" +msgstr "%sからのフェッチ" #: ../gtk/config-fetching.c:73 #, c-format msgid "Downloading of remote configuration from %s failed." msgstr "" -#: ../gtk/audio_assistant.c:98 +#: ../gtk/audio_assistant.c:103 msgid "No voice detected" msgstr "音声が検出できません" -#: ../gtk/audio_assistant.c:99 +#: ../gtk/audio_assistant.c:104 msgid "Too low" msgstr "小さい" -#: ../gtk/audio_assistant.c:100 +#: ../gtk/audio_assistant.c:105 msgid "Good" msgstr "丁度よい" -#: ../gtk/audio_assistant.c:101 +#: ../gtk/audio_assistant.c:106 msgid "Too loud" msgstr "大きい" -#: ../gtk/audio_assistant.c:183 +#: ../gtk/audio_assistant.c:188 msgid "Did you hear three beeps ?" msgstr "3回のビープ音が聞こえましたか?" -#: ../gtk/audio_assistant.c:292 ../gtk/audio_assistant.c:297 +#: ../gtk/audio_assistant.c:299 ../gtk/audio_assistant.c:304 msgid "Sound preferences not found " msgstr "音声の設定が見つかりません" -#: ../gtk/audio_assistant.c:306 +#: ../gtk/audio_assistant.c:313 msgid "Cannot launch system sound control " msgstr "音声制御システムを起動できません" -#: ../gtk/audio_assistant.c:318 +#: ../gtk/audio_assistant.c:325 msgid "" "Welcome!\n" "This assistant will help you to configure audio settings for Linphone" msgstr "" -#: ../gtk/audio_assistant.c:328 +#: ../gtk/audio_assistant.c:335 msgid "Capture device" msgstr "キャプチャーデバイス" -#: ../gtk/audio_assistant.c:329 +#: ../gtk/audio_assistant.c:336 msgid "Recorded volume" msgstr "録音音量" -#: ../gtk/audio_assistant.c:333 +#: ../gtk/audio_assistant.c:340 msgid "No voice" msgstr "音声なし" -#: ../gtk/audio_assistant.c:334 ../gtk/audio_assistant.c:373 +#: ../gtk/audio_assistant.c:341 ../gtk/audio_assistant.c:380 msgid "System sound preferences" msgstr "システムサウンド設定" -#: ../gtk/audio_assistant.c:369 +#: ../gtk/audio_assistant.c:376 msgid "Playback device" msgstr "" -#: ../gtk/audio_assistant.c:370 +#: ../gtk/audio_assistant.c:377 msgid "Play three beeps" msgstr "3回分のビープ音を再生する" -#: ../gtk/audio_assistant.c:403 +#: ../gtk/audio_assistant.c:410 msgid "Press the record button and say some words" msgstr "" -#: ../gtk/audio_assistant.c:404 +#: ../gtk/audio_assistant.c:411 msgid "Listen to your record voice" msgstr "録音した音声を聞く" -#: ../gtk/audio_assistant.c:405 +#: ../gtk/audio_assistant.c:412 ../gtk/conf_frame.ui.h:2 +#: ../gtk/in_call_frame.ui.h:4 msgid "Record" msgstr "録音" -#: ../gtk/audio_assistant.c:406 +#: ../gtk/audio_assistant.c:413 msgid "Play" msgstr "再生" -#: ../gtk/audio_assistant.c:433 +#: ../gtk/audio_assistant.c:440 msgid "Let's start Linphone now" msgstr "Linphoneをはじめる" -#: ../gtk/audio_assistant.c:503 +#: ../gtk/audio_assistant.c:510 msgid "Audio Assistant" msgstr "音声アシスタント" -#: ../gtk/audio_assistant.c:513 ../gtk/main.ui.h:32 +#: ../gtk/audio_assistant.c:520 ../gtk/main.ui.h:13 msgid "Audio assistant" msgstr "音声アシスタント" -#: ../gtk/audio_assistant.c:518 +#: ../gtk/audio_assistant.c:525 msgid "Mic Gain calibration" msgstr "マイクのゲイン測定" -#: ../gtk/audio_assistant.c:524 +#: ../gtk/audio_assistant.c:531 msgid "Speaker volume calibration" msgstr "スピーカーの音量測定" -#: ../gtk/audio_assistant.c:529 +#: ../gtk/audio_assistant.c:536 msgid "Record and Play" msgstr "録音して再生" -#: ../gtk/main.ui.h:1 -msgid "Callee name" -msgstr "" - -#: ../gtk/main.ui.h:2 -msgid "Send" -msgstr "送信" - -#: ../gtk/main.ui.h:3 -msgid "End conference" -msgstr "会議を終了する" - -#: ../gtk/main.ui.h:7 -msgid "Record this call to an audio file" -msgstr "この通話をファイルに録音する" - -#: ../gtk/main.ui.h:8 -msgid "Video" -msgstr "ビデオ" - -#: ../gtk/main.ui.h:10 -msgid "Mute" -msgstr "消音" - -#: ../gtk/main.ui.h:11 -msgid "Transfer" -msgstr "転送" - -#: ../gtk/main.ui.h:14 -msgid "In call" -msgstr "着信" - -#: ../gtk/main.ui.h:15 -msgid "Duration" -msgstr "期限" - -#: ../gtk/main.ui.h:16 -msgid "Call quality rating" -msgstr "" - -#: ../gtk/main.ui.h:17 -msgid "All users" -msgstr "すべての利用者" - -#: ../gtk/main.ui.h:18 -msgid "Online users" -msgstr "オンラインの利用者" - -#: ../gtk/main.ui.h:19 -msgid "ADSL" -msgstr "ADSL" - -#: ../gtk/main.ui.h:20 -msgid "Fiber Channel" -msgstr "" - -#: ../gtk/main.ui.h:21 -msgid "Default" -msgstr "デフォルト" - -#: ../gtk/main.ui.h:22 -msgid "Delete" -msgstr "削除" - -#: ../gtk/main.ui.h:23 -msgid "_Options" -msgstr "_オプション" - -#: ../gtk/main.ui.h:24 -msgid "Set configuration URI" -msgstr "" - -#: ../gtk/main.ui.h:25 -msgid "Always start video" -msgstr "いつでもビデオをスタートする" - -#: ../gtk/main.ui.h:26 -msgid "Enable self-view" -msgstr "セルフビューを有効にする" - -#: ../gtk/main.ui.h:27 -msgid "_Help" -msgstr "_ヘルプ" - -#: ../gtk/main.ui.h:28 -msgid "Show debug window" -msgstr "デバッグウインドウを見る" - -#: ../gtk/main.ui.h:29 -msgid "_Homepage" -msgstr "_ホームページ" - -#: ../gtk/main.ui.h:30 -msgid "Check _Updates" -msgstr "チェック _アップデート" - -#: ../gtk/main.ui.h:31 -msgid "Account assistant" -msgstr "アカウントのアシスタント" - -#: ../gtk/main.ui.h:33 -msgid "SIP address or phone number:" -msgstr "SIPアドレスもしくは電話番号:" - -#: ../gtk/main.ui.h:34 -msgid "Initiate a new call" -msgstr "" - -#: ../gtk/main.ui.h:35 -msgid "Contacts" -msgstr "" - -#: ../gtk/main.ui.h:36 -msgid "Search" -msgstr "検索" - -#: ../gtk/main.ui.h:37 -msgid "Add contacts from directory" -msgstr "" - -#: ../gtk/main.ui.h:38 -msgid "Add contact" -msgstr "連絡相手に追加する" - -#: ../gtk/main.ui.h:39 -msgid "Recent calls" -msgstr "" - -#: ../gtk/main.ui.h:40 -msgid "My current identity:" -msgstr "" - -#: ../gtk/main.ui.h:41 ../gtk/tunnel_config.ui.h:7 -msgid "Username" -msgstr "ユーザー名" - -#: ../gtk/main.ui.h:42 ../gtk/tunnel_config.ui.h:8 -msgid "Password" -msgstr "パスワード" - -#: ../gtk/main.ui.h:43 -msgid "Internet connection:" -msgstr "インターネット接続:" - -#: ../gtk/main.ui.h:44 -msgid "Automatically log me in" -msgstr "自動的にログインする" - -#: ../gtk/main.ui.h:45 ../gtk/password.ui.h:3 -msgid "UserID" -msgstr "ユーザーID" - -#: ../gtk/main.ui.h:46 -msgid "Login information" -msgstr "ログイン情報" - -#: ../gtk/main.ui.h:47 -msgid "Welcome!" -msgstr "" +#: ../gtk/audio_assistant.c:541 ../gtk/setup_wizard.ui.h:38 +msgid "Terminating" +msgstr "終了" #: ../gtk/about.ui.h:1 msgid "About Linphone" @@ -1036,456 +778,6 @@ msgid "" "he: Eli Zaretskii \n" msgstr "fr: Simon Morlat\nen: Simon Morlat and Delphine Perreau\nit: Alberto Zanoni \nde: Jean-Jacques Sarton \nsv: Daniel Nylander \nes: Jesus Benitez \nja: YAMAGUCHI YOSHIYA \npt_BR: Rafael Caesar Lenzi \npl: Robert Nasiadek \ncs: Petr Pisar \nhu: anonymous\nhe: Eli Zaretskii \n" -#: ../gtk/contact.ui.h:2 -msgid "SIP Address" -msgstr "SIPアドレス" - -#: ../gtk/contact.ui.h:3 -msgid "Show this contact presence status" -msgstr "" - -#: ../gtk/contact.ui.h:4 -msgid "Allow this contact to see my presence status" -msgstr "" - -#: ../gtk/contact.ui.h:5 -msgid "Contact information" -msgstr "" - -#: ../gtk/log.ui.h:1 -msgid "Linphone debug window" -msgstr "Linphoneデバッグウインドウ" - -#: ../gtk/log.ui.h:2 -msgid "Scroll to end" -msgstr "" - -#: ../gtk/password.ui.h:1 -msgid "Linphone - Authentication required" -msgstr "" - -#: ../gtk/password.ui.h:2 -msgid "Please enter the domain password" -msgstr "" - -#: ../gtk/call_logs.ui.h:1 -msgid "Call history" -msgstr "呼出履歴" - -#: ../gtk/call_logs.ui.h:2 -msgid "Clear all" -msgstr "すべて消去する" - -#: ../gtk/call_logs.ui.h:3 -msgid "Call back" -msgstr "" - -#: ../gtk/sip_account.ui.h:1 -msgid "Linphone - Configure a SIP account" -msgstr "" - -#: ../gtk/sip_account.ui.h:2 -msgid "Your SIP identity:" -msgstr "" - -#: ../gtk/sip_account.ui.h:3 -msgid "Looks like sip:@" -msgstr "" - -#: ../gtk/sip_account.ui.h:4 -msgid "sip:" -msgstr "sip:" - -#: ../gtk/sip_account.ui.h:5 -msgid "SIP Proxy address:" -msgstr "SIP プロキシ:" - -#: ../gtk/sip_account.ui.h:6 -msgid "Looks like sip:" -msgstr "" - -#: ../gtk/sip_account.ui.h:7 -msgid "Registration duration (sec):" -msgstr "" - -#: ../gtk/sip_account.ui.h:8 -msgid "Contact params (optional):" -msgstr "" - -#: ../gtk/sip_account.ui.h:9 -msgid "AVPF regular RTCP interval (sec):" -msgstr "" - -#: ../gtk/sip_account.ui.h:10 -msgid "Route (optional):" -msgstr "" - -#: ../gtk/sip_account.ui.h:11 -msgid "Transport" -msgstr "転送" - -#: ../gtk/sip_account.ui.h:12 -msgid "Register" -msgstr "登録" - -#: ../gtk/sip_account.ui.h:13 -msgid "Publish presence information" -msgstr "パブリッシュ情報" - -#: ../gtk/sip_account.ui.h:14 -msgid "Enable AVPF" -msgstr "AVPFを有効にする" - -#: ../gtk/sip_account.ui.h:15 -msgid "Configure a SIP account" -msgstr "" - -#: ../gtk/parameters.ui.h:1 -msgid "anonymous" -msgstr "anonymous" - -#: ../gtk/parameters.ui.h:2 -msgid "GSSAPI" -msgstr "GSSAPI" - -#: ../gtk/parameters.ui.h:3 -msgid "SASL" -msgstr "SASL" - -#: ../gtk/parameters.ui.h:4 -msgid "default soundcard" -msgstr "" - -#: ../gtk/parameters.ui.h:5 -msgid "a sound card" -msgstr "サウンドカード" - -#: ../gtk/parameters.ui.h:6 -msgid "default camera" -msgstr "デフォルトのカメラ" - -#: ../gtk/parameters.ui.h:7 -msgid "CIF" -msgstr "CIF" - -#: ../gtk/parameters.ui.h:8 -msgid "Audio codecs" -msgstr "オーディオのコーデック" - -#: ../gtk/parameters.ui.h:9 -msgid "Video codecs" -msgstr "ビデオのコーデック" - -#: ../gtk/parameters.ui.h:10 -msgid "C" -msgstr "C" - -#: ../gtk/parameters.ui.h:11 -msgid "SIP (UDP)" -msgstr "SIP (UDP)" - -#: ../gtk/parameters.ui.h:12 -msgid "SIP (TCP)" -msgstr "SIP (TCP)" - -#: ../gtk/parameters.ui.h:13 -msgid "SIP (TLS)" -msgstr "SIP (TLS)" - -#: ../gtk/parameters.ui.h:14 -msgid "Settings" -msgstr "設定" - -#: ../gtk/parameters.ui.h:15 -msgid "Set Maximum Transmission Unit:" -msgstr "" - -#: ../gtk/parameters.ui.h:16 -msgid "Send DTMFs as SIP info" -msgstr "DTMFをSIP情報で送信する" - -#: ../gtk/parameters.ui.h:17 -msgid "Allow IPv6" -msgstr "" - -#: ../gtk/parameters.ui.h:18 -msgid "Transport" -msgstr "転送" - -#: ../gtk/parameters.ui.h:19 -msgid "SIP/UDP port" -msgstr "SIP/UDP ポート" - -#: ../gtk/parameters.ui.h:21 -msgid "Random" -msgstr "" - -#: ../gtk/parameters.ui.h:22 -msgid "SIP/TCP port" -msgstr "SIP/TCP ポート" - -#: ../gtk/parameters.ui.h:23 -msgid "Audio RTP/UDP:" -msgstr "オーディオ RTP/UDP:" - -#: ../gtk/parameters.ui.h:24 -msgid "Fixed" -msgstr "" - -#: ../gtk/parameters.ui.h:25 -msgid "Video RTP/UDP:" -msgstr "ビデオ RTP/UDP:" - -#: ../gtk/parameters.ui.h:26 -msgid "Media encryption type" -msgstr "メディアの暗号化の種類" - -#: ../gtk/parameters.ui.h:27 -msgid "Media encryption is mandatory" -msgstr "" - -#: ../gtk/parameters.ui.h:28 -msgid "Tunnel" -msgstr "トンネル" - -#: ../gtk/parameters.ui.h:29 -msgid "DSCP fields" -msgstr "DSCP値" - -#: ../gtk/parameters.ui.h:30 -msgid "Network protocol and ports" -msgstr "ネットワークのプロトコルとポート" - -#: ../gtk/parameters.ui.h:31 -msgid "Direct connection to the Internet" -msgstr "" - -#: ../gtk/parameters.ui.h:32 -msgid "Behind NAT / Firewall (specify gateway IP )" -msgstr "" - -#: ../gtk/parameters.ui.h:33 -msgid "Behind NAT / Firewall (use STUN to resolve)" -msgstr "" - -#: ../gtk/parameters.ui.h:34 -msgid "Behind NAT / Firewall (use ICE)" -msgstr "" - -#: ../gtk/parameters.ui.h:35 -msgid "Behind NAT / Firewall (use uPnP)" -msgstr "" - -#: ../gtk/parameters.ui.h:36 -msgid "Public IP address:" -msgstr "パブリック IP アドレス:" - -#: ../gtk/parameters.ui.h:37 -msgid "Stun server:" -msgstr "Stunサーバー:" - -#: ../gtk/parameters.ui.h:38 -msgid "NAT and Firewall" -msgstr "NAT と ファイヤーウォール" - -#: ../gtk/parameters.ui.h:39 -msgid "Network settings" -msgstr "ネットワーク設定" - -#: ../gtk/parameters.ui.h:40 -msgid "Ring sound:" -msgstr "鳴動音:" - -#: ../gtk/parameters.ui.h:41 -msgid "ALSA special device (optional):" -msgstr "" - -#: ../gtk/parameters.ui.h:42 -msgid "Capture device:" -msgstr "" - -#: ../gtk/parameters.ui.h:43 -msgid "Ring device:" -msgstr "" - -#: ../gtk/parameters.ui.h:44 -msgid "Playback device:" -msgstr "" - -#: ../gtk/parameters.ui.h:45 -msgid "Enable echo cancellation" -msgstr "エコーキャンセラーを有効にする" - -#: ../gtk/parameters.ui.h:46 -msgid "Audio" -msgstr "オーディオ" - -#: ../gtk/parameters.ui.h:47 -msgid "Video input device:" -msgstr "" - -#: ../gtk/parameters.ui.h:48 -msgid "Prefered video resolution:" -msgstr "" - -#: ../gtk/parameters.ui.h:49 -msgid "Video output method:" -msgstr "" - -#: ../gtk/parameters.ui.h:50 -msgid "Show camera preview" -msgstr "" - -#: ../gtk/parameters.ui.h:51 -msgid "Video" -msgstr "ビデオ" - -#: ../gtk/parameters.ui.h:52 -msgid "Multimedia settings" -msgstr "マルチメディア設定" - -#: ../gtk/parameters.ui.h:53 -msgid "This section defines your SIP address when not using a SIP account" -msgstr "" - -#: ../gtk/parameters.ui.h:54 -msgid "Your display name (eg: John Doe):" -msgstr "あなたの表示名 (例: John Doe):" - -#: ../gtk/parameters.ui.h:55 -msgid "Your username:" -msgstr "あなたのユーザー名:" - -#: ../gtk/parameters.ui.h:56 -msgid "Your resulting SIP address:" -msgstr "" - -#: ../gtk/parameters.ui.h:57 -msgid "Default identity" -msgstr "" - -#: ../gtk/parameters.ui.h:58 -msgid "Wizard" -msgstr "ウィザード" - -#: ../gtk/parameters.ui.h:59 -msgid "Add" -msgstr "追加する" - -#: ../gtk/parameters.ui.h:60 -msgid "Edit" -msgstr "編集する" - -#: ../gtk/parameters.ui.h:61 -msgid "Remove" -msgstr "削除する" - -#: ../gtk/parameters.ui.h:62 -msgid "Proxy accounts" -msgstr "プロキシアカウント" - -#: ../gtk/parameters.ui.h:63 -msgid "Erase all passwords" -msgstr "すべてのパスワードを消去する" - -#: ../gtk/parameters.ui.h:64 -msgid "Privacy" -msgstr "プライバシー" - -#: ../gtk/parameters.ui.h:65 -msgid "Automatically answer when a call is received" -msgstr "" - -#: ../gtk/parameters.ui.h:66 -msgid "Delay before answering (ms)" -msgstr "" - -#: ../gtk/parameters.ui.h:67 -msgid "Auto-answer" -msgstr "" - -#: ../gtk/parameters.ui.h:68 -msgid "Manage SIP Accounts" -msgstr "" - -#: ../gtk/parameters.ui.h:69 ../gtk/tunnel_config.ui.h:4 -msgid "Enable" -msgstr "使用する" - -#: ../gtk/parameters.ui.h:70 ../gtk/tunnel_config.ui.h:5 -msgid "Disable" -msgstr "使用しない" - -#: ../gtk/parameters.ui.h:71 -msgid "Codecs" -msgstr "コーデック" - -#: ../gtk/parameters.ui.h:72 -msgid "0 stands for \"unlimited\"" -msgstr "" - -#: ../gtk/parameters.ui.h:73 -msgid "Upload speed limit in Kbit/sec:" -msgstr "アップロード速度制限 Kbit/sec:" - -#: ../gtk/parameters.ui.h:74 -msgid "Download speed limit in Kbit/sec:" -msgstr "ダウンロード速度制限 Kbit/sec:" - -#: ../gtk/parameters.ui.h:75 -msgid "Enable adaptive rate control" -msgstr "" - -#: ../gtk/parameters.ui.h:76 -msgid "" -"Adaptive rate control is a technique to dynamically guess the available " -"bandwidth during a call." -msgstr "" - -#: ../gtk/parameters.ui.h:77 -msgid "Bandwidth control" -msgstr "帯域幅制御" - -#: ../gtk/parameters.ui.h:78 -msgid "Codecs" -msgstr "コーデック" - -#: ../gtk/parameters.ui.h:79 -msgid "Language" -msgstr "言語" - -#: ../gtk/parameters.ui.h:80 -msgid "Show advanced settings" -msgstr "拡張設定を表示する" - -#: ../gtk/parameters.ui.h:81 -msgid "Level" -msgstr "レベル" - -#: ../gtk/parameters.ui.h:82 -msgid "User interface" -msgstr "ユーザーインターフェイス" - -#: ../gtk/parameters.ui.h:83 ../gtk/ldap.ui.h:2 -msgid "Server address:" -msgstr "サーバーアドレス:" - -#: ../gtk/parameters.ui.h:84 ../gtk/ldap.ui.h:3 -msgid "Authentication method:" -msgstr "" - -#: ../gtk/parameters.ui.h:86 -msgid "LDAP Account setup" -msgstr "" - -#: ../gtk/parameters.ui.h:87 -msgid "LDAP" -msgstr "LDAP" - -#: ../gtk/parameters.ui.h:88 -msgid "Done" -msgstr "完了" - #: ../gtk/buddylookup.ui.h:1 msgid "Search contacts in directory" msgstr "" @@ -1498,28 +790,20 @@ msgstr "" msgid "Search somebody" msgstr "" -#: ../gtk/waiting.ui.h:2 -msgid "Please wait" -msgstr "お待ちください" +#: ../gtk/callee_frame.ui.h:1 +msgid "Callee name" +msgstr "" -#: ../gtk/dscp_settings.ui.h:1 -msgid "DSCP settings" -msgstr "DSCP設定" +#: ../gtk/call_logs.ui.h:1 +msgid "Call history" +msgstr "呼出履歴" -#: ../gtk/dscp_settings.ui.h:2 -msgid "SIP" -msgstr "SIP" +#: ../gtk/call_logs.ui.h:2 +msgid "Clear all" +msgstr "すべて消去する" -#: ../gtk/dscp_settings.ui.h:3 -msgid "Audio RTP stream" -msgstr "オーディオのRTP" - -#: ../gtk/dscp_settings.ui.h:4 -msgid "Video RTP stream" -msgstr "ビデオのRTP" - -#: ../gtk/dscp_settings.ui.h:5 -msgid "Set DSCP values (in hexadecimal)" +#: ../gtk/call_logs.ui.h:3 +msgid "Call back" msgstr "" #: ../gtk/call_statistics.ui.h:1 @@ -1552,7 +836,7 @@ msgstr "接続しているビデオ用メディア" #: ../gtk/call_statistics.ui.h:8 msgid "Round trip time" -msgstr "" +msgstr "RTT" #: ../gtk/call_statistics.ui.h:9 msgid "Video resolution received" @@ -1570,30 +854,112 @@ msgstr "RTPプロファイル" msgid "Call statistics and information" msgstr "" -#: ../gtk/tunnel_config.ui.h:1 -msgid "Configure VoIP tunnel" +#: ../gtk/chatroom_frame.ui.h:1 +msgid "Send" +msgstr "送信" + +#: ../gtk/conf_frame.ui.h:1 +msgid "End conference" +msgstr "会議を終了する" + +#: ../gtk/config-uri.ui.h:1 +msgid "Specifying a remote configuration URI" msgstr "" -#: ../gtk/tunnel_config.ui.h:2 -msgid "Host" -msgstr "ホスト" - -#: ../gtk/tunnel_config.ui.h:3 -msgid "Port" -msgstr "ポート" - -#: ../gtk/tunnel_config.ui.h:6 -msgid "Configure tunnel" +#: ../gtk/config-uri.ui.h:2 +msgid "" +"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" +"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " msgstr "" -#: ../gtk/tunnel_config.ui.h:9 -msgid "Configure http proxy (optional)" +#: ../gtk/contact.ui.h:2 +msgid "SIP Address" +msgstr "SIPアドレス" + +#: ../gtk/contact.ui.h:3 +msgid "Show this contact presence status" +msgstr "" + +#: ../gtk/contact.ui.h:4 +msgid "Allow this contact to see my presence status" +msgstr "" + +#: ../gtk/contact.ui.h:5 +msgid "Contact information" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:1 +msgid "DSCP settings" +msgstr "DSCP設定" + +#: ../gtk/dscp_settings.ui.h:2 +msgid "SIP" +msgstr "SIP" + +#: ../gtk/dscp_settings.ui.h:3 +msgid "Audio RTP stream" +msgstr "オーディオのRTP" + +#: ../gtk/dscp_settings.ui.h:4 +msgid "Video RTP stream" +msgstr "ビデオのRTP" + +#: ../gtk/dscp_settings.ui.h:5 +msgid "Set DSCP values (in hexadecimal)" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:1 +msgid "Click here to set the speakers volume" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:5 +msgid "Record this call to an audio file" +msgstr "この通話をファイルに録音する" + +#: ../gtk/in_call_frame.ui.h:6 +msgid "Video" +msgstr "ビデオ" + +#: ../gtk/in_call_frame.ui.h:8 +msgid "Mute" +msgstr "消音" + +#: ../gtk/in_call_frame.ui.h:9 +msgid "Transfer" +msgstr "転送" + +#: ../gtk/in_call_frame.ui.h:12 +msgid "In call" +msgstr "着信" + +#: ../gtk/in_call_frame.ui.h:13 +msgid "Duration" +msgstr "期限" + +#: ../gtk/in_call_frame.ui.h:14 +msgid "Call quality rating" msgstr "" #: ../gtk/ldap.ui.h:1 msgid "LDAP Settings" msgstr "LDAP設定" +#: ../gtk/ldap.ui.h:2 ../gtk/parameters.ui.h:89 +msgid "Server address:" +msgstr "サーバーアドレス:" + +#: ../gtk/ldap.ui.h:3 ../gtk/parameters.ui.h:90 +msgid "Authentication method:" +msgstr "" + +#: ../gtk/ldap.ui.h:4 ../gtk/parameters.ui.h:91 ../gtk/setup_wizard.ui.h:17 +msgid "Username:" +msgstr "ユーザー名:" + +#: ../gtk/ldap.ui.h:5 ../gtk/password.ui.h:4 ../gtk/setup_wizard.ui.h:18 +msgid "Password:" +msgstr "パスワード:" + #: ../gtk/ldap.ui.h:6 msgid "Use TLS Connection" msgstr "TLS接続を使用する" @@ -1679,14 +1045,502 @@ msgstr "ダイジェスト-MD5" msgid "NTLM" msgstr "NTLM" -#: ../gtk/config-uri.ui.h:1 -msgid "Specifying a remote configuration URI" +#: ../gtk/login_frame.ui.h:1 ../gtk/tunnel_config.ui.h:7 +msgid "Username" +msgstr "ユーザー名" + +#: ../gtk/login_frame.ui.h:2 ../gtk/tunnel_config.ui.h:8 +msgid "Password" +msgstr "パスワード" + +#: ../gtk/login_frame.ui.h:3 +msgid "Internet connection:" +msgstr "インターネット接続:" + +#: ../gtk/login_frame.ui.h:4 +msgid "Automatically log me in" +msgstr "自動的にログインする" + +#: ../gtk/login_frame.ui.h:5 ../gtk/password.ui.h:3 +msgid "UserID" +msgstr "ユーザーID" + +#: ../gtk/login_frame.ui.h:6 +msgid "Login information" +msgstr "ログイン情報" + +#: ../gtk/login_frame.ui.h:7 +msgid "Welcome!" +msgstr "ようこそ!" + +#: ../gtk/login_frame.ui.h:8 +msgid "ADSL" +msgstr "ADSL" + +#: ../gtk/login_frame.ui.h:9 +msgid "Fiber Channel" msgstr "" -#: ../gtk/config-uri.ui.h:2 +#: ../gtk/log.ui.h:1 +msgid "Linphone debug window" +msgstr "Linphoneデバッグウインドウ" + +#: ../gtk/log.ui.h:2 +msgid "Scroll to end" +msgstr "最下部までスクロールする" + +#: ../gtk/main.ui.h:1 +msgid "Default" +msgstr "デフォルト" + +#: ../gtk/main.ui.h:2 +msgid "Delete" +msgstr "削除" + +#: ../gtk/main.ui.h:3 +msgid "_Options" +msgstr "_オプション" + +#: ../gtk/main.ui.h:4 +msgid "Set configuration URI" +msgstr "" + +#: ../gtk/main.ui.h:5 +msgid "Always start video" +msgstr "いつでもビデオをスタートする" + +#: ../gtk/main.ui.h:6 +msgid "Enable self-view" +msgstr "セルフビューを有効にする" + +#: ../gtk/main.ui.h:7 +msgid "Show keypad" +msgstr "キーパッドを表示する" + +#: ../gtk/main.ui.h:8 +msgid "_Help" +msgstr "_ヘルプ" + +#: ../gtk/main.ui.h:9 +msgid "Show debug window" +msgstr "デバッグウインドウを見る" + +#: ../gtk/main.ui.h:10 +msgid "_Homepage" +msgstr "_ホームページ" + +#: ../gtk/main.ui.h:11 +msgid "Check _Updates" +msgstr "チェック _アップデート" + +#: ../gtk/main.ui.h:12 +msgid "Account assistant" +msgstr "アカウントのアシスタント" + +#: ../gtk/main.ui.h:14 +msgid "SIP address or phone number:" +msgstr "SIPアドレスもしくは電話番号:" + +#: ../gtk/main.ui.h:15 +msgid "Initiate a new call" +msgstr "" + +#: ../gtk/main.ui.h:16 +msgid "Contacts" +msgstr "連絡相手" + +#: ../gtk/main.ui.h:17 +msgid "Search" +msgstr "検索" + +#: ../gtk/main.ui.h:18 +msgid "Add contacts from directory" +msgstr "" + +#: ../gtk/main.ui.h:19 +msgid "Add contact" +msgstr "連絡相手に追加する" + +#: ../gtk/main.ui.h:20 +msgid "Clear call history" +msgstr "通話履歴を削除する" + +#: ../gtk/main.ui.h:22 +msgid "My current identity:" +msgstr "" + +#: ../gtk/main.ui.h:23 +msgid "Autoanswer is enabled" +msgstr "" + +#: ../gtk/parameters.ui.h:1 +msgid "anonymous" +msgstr "anonymous" + +#: ../gtk/parameters.ui.h:2 +msgid "GSSAPI" +msgstr "GSSAPI" + +#: ../gtk/parameters.ui.h:3 +msgid "SASL" +msgstr "SASL" + +#: ../gtk/parameters.ui.h:4 +msgid "default soundcard" +msgstr "" + +#: ../gtk/parameters.ui.h:5 +msgid "a sound card" +msgstr "サウンドカード" + +#: ../gtk/parameters.ui.h:6 +msgid "default camera" +msgstr "デフォルトのカメラ" + +#: ../gtk/parameters.ui.h:7 +msgid "CIF" +msgstr "CIF" + +#: ../gtk/parameters.ui.h:8 +msgid "Audio codecs" +msgstr "オーディオのコーデック" + +#: ../gtk/parameters.ui.h:9 +msgid "Video codecs" +msgstr "ビデオのコーデック" + +#: ../gtk/parameters.ui.h:10 +msgid "C" +msgstr "C" + +#: ../gtk/parameters.ui.h:11 +msgid "SIP (UDP)" +msgstr "SIP (UDP)" + +#: ../gtk/parameters.ui.h:12 +msgid "SIP (TCP)" +msgstr "SIP (TCP)" + +#: ../gtk/parameters.ui.h:13 +msgid "SIP (TLS)" +msgstr "SIP (TLS)" + +#: ../gtk/parameters.ui.h:14 +msgid "default" +msgstr "" + +#: ../gtk/parameters.ui.h:15 +msgid "high-fps" +msgstr "" + +#: ../gtk/parameters.ui.h:16 +msgid "custom" +msgstr "カスタム" + +#: ../gtk/parameters.ui.h:17 +msgid "Settings" +msgstr "設定" + +#: ../gtk/parameters.ui.h:18 +msgid "This section defines your SIP address when not using a SIP account" +msgstr "" + +#: ../gtk/parameters.ui.h:19 +msgid "Your display name (eg: John Doe):" +msgstr "あなたの表示名 (例: John Doe):" + +#: ../gtk/parameters.ui.h:20 +msgid "Your username:" +msgstr "あなたのユーザー名:" + +#: ../gtk/parameters.ui.h:21 +msgid "Your resulting SIP address:" +msgstr "" + +#: ../gtk/parameters.ui.h:22 +msgid "Default identity" +msgstr "" + +#: ../gtk/parameters.ui.h:23 +msgid "Wizard" +msgstr "ウィザード" + +#: ../gtk/parameters.ui.h:24 +msgid "Add" +msgstr "追加する" + +#: ../gtk/parameters.ui.h:25 +msgid "Edit" +msgstr "編集する" + +#: ../gtk/parameters.ui.h:26 +msgid "Remove" +msgstr "削除する" + +#: ../gtk/parameters.ui.h:27 +msgid "Proxy accounts" +msgstr "プロキシアカウント" + +#: ../gtk/parameters.ui.h:28 +msgid "Erase all passwords" +msgstr "すべてのパスワードを消去する" + +#: ../gtk/parameters.ui.h:29 +msgid "Privacy" +msgstr "プライバシー" + +#: ../gtk/parameters.ui.h:30 +msgid "Automatically answer when a call is received" +msgstr "" + +#: ../gtk/parameters.ui.h:31 +msgid "Delay before answering (ms)" +msgstr "" + +#: ../gtk/parameters.ui.h:32 +msgid "Auto-answer" +msgstr "" + +#: ../gtk/parameters.ui.h:33 +msgid "Manage SIP Accounts" +msgstr "" + +#: ../gtk/parameters.ui.h:34 +msgid "Ring sound:" +msgstr "鳴動音:" + +#: ../gtk/parameters.ui.h:35 +msgid "ALSA special device (optional):" +msgstr "" + +#: ../gtk/parameters.ui.h:36 +msgid "Capture device:" +msgstr "" + +#: ../gtk/parameters.ui.h:37 +msgid "Ring device:" +msgstr "" + +#: ../gtk/parameters.ui.h:38 +msgid "Playback device:" +msgstr "" + +#: ../gtk/parameters.ui.h:39 +msgid "Enable echo cancellation" +msgstr "エコーキャンセラーを有効にする" + +#: ../gtk/parameters.ui.h:40 +msgid "Audio" +msgstr "オーディオ" + +#: ../gtk/parameters.ui.h:41 +msgid "Video input device:" +msgstr "" + +#: ../gtk/parameters.ui.h:42 +msgid "Preferred video resolution:" +msgstr "" + +#: ../gtk/parameters.ui.h:43 +msgid "Video output method:" +msgstr "" + +#: ../gtk/parameters.ui.h:44 +msgid "Show camera preview" +msgstr "" + +#: ../gtk/parameters.ui.h:45 +msgid "Video preset:" +msgstr "" + +#: ../gtk/parameters.ui.h:46 +msgid "Preferred video framerate:" +msgstr "" + +#: ../gtk/parameters.ui.h:47 +msgid "0 stands for \"unlimited\"" +msgstr "0で制限なしになります" + +#: ../gtk/parameters.ui.h:48 +msgid "Video" +msgstr "ビデオ" + +#: ../gtk/parameters.ui.h:49 +msgid "Upload speed limit in Kbit/sec:" +msgstr "アップロード速度制限 Kbit/sec:" + +#: ../gtk/parameters.ui.h:50 +msgid "Download speed limit in Kbit/sec:" +msgstr "ダウンロード速度制限 Kbit/sec:" + +#: ../gtk/parameters.ui.h:51 +msgid "Enable adaptive rate control" +msgstr "" + +#: ../gtk/parameters.ui.h:52 msgid "" -"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" -"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " +"Adaptive rate control is a technique to dynamically guess the available " +"bandwidth during a call." +msgstr "" + +#: ../gtk/parameters.ui.h:53 +msgid "Bandwidth control" +msgstr "帯域幅制御" + +#: ../gtk/parameters.ui.h:54 +msgid "Multimedia settings" +msgstr "マルチメディア設定" + +#: ../gtk/parameters.ui.h:55 +msgid "Set Maximum Transmission Unit:" +msgstr "" + +#: ../gtk/parameters.ui.h:56 +msgid "Send DTMFs as SIP info" +msgstr "DTMFをSIP情報で送信する" + +#: ../gtk/parameters.ui.h:57 +msgid "Allow IPv6" +msgstr "IPv6を有効にする" + +#: ../gtk/parameters.ui.h:58 +msgid "Transport" +msgstr "転送" + +#: ../gtk/parameters.ui.h:59 +msgid "SIP/UDP port" +msgstr "SIP/UDP ポート" + +#: ../gtk/parameters.ui.h:61 +msgid "Random" +msgstr "ランダム" + +#: ../gtk/parameters.ui.h:62 +msgid "SIP/TCP port" +msgstr "SIP/TCP ポート" + +#: ../gtk/parameters.ui.h:63 +msgid "Audio RTP/UDP:" +msgstr "オーディオ RTP/UDP:" + +#: ../gtk/parameters.ui.h:64 +msgid "Fixed" +msgstr "" + +#: ../gtk/parameters.ui.h:65 +msgid "Video RTP/UDP:" +msgstr "ビデオ RTP/UDP:" + +#: ../gtk/parameters.ui.h:66 +msgid "Media encryption type" +msgstr "メディアの暗号化の種類" + +#: ../gtk/parameters.ui.h:67 +msgid "Media encryption is mandatory" +msgstr "" + +#: ../gtk/parameters.ui.h:68 +msgid "Tunnel" +msgstr "トンネル" + +#: ../gtk/parameters.ui.h:69 +msgid "DSCP fields" +msgstr "DSCP値" + +#: ../gtk/parameters.ui.h:70 +msgid "Network protocol and ports" +msgstr "ネットワークのプロトコルとポート" + +#: ../gtk/parameters.ui.h:71 +msgid "Direct connection to the Internet" +msgstr "" + +#: ../gtk/parameters.ui.h:72 +msgid "Behind NAT / Firewall (specify gateway IP )" +msgstr "" + +#: ../gtk/parameters.ui.h:73 +msgid "Behind NAT / Firewall (use STUN to resolve)" +msgstr "" + +#: ../gtk/parameters.ui.h:74 +msgid "Behind NAT / Firewall (use ICE)" +msgstr "NAT / ファイヤーウォール (ICEを使う)" + +#: ../gtk/parameters.ui.h:75 +msgid "Behind NAT / Firewall (use uPnP)" +msgstr "NAT / ファイヤーウォール (uPnPを使う)" + +#: ../gtk/parameters.ui.h:76 +msgid "Public IP address:" +msgstr "パブリック IP アドレス:" + +#: ../gtk/parameters.ui.h:77 +msgid "Stun server:" +msgstr "Stunサーバー:" + +#: ../gtk/parameters.ui.h:78 +msgid "NAT and Firewall" +msgstr "NAT と ファイヤーウォール" + +#: ../gtk/parameters.ui.h:79 +msgid "Network settings" +msgstr "ネットワーク設定" + +#: ../gtk/parameters.ui.h:80 ../gtk/tunnel_config.ui.h:4 +msgid "Enable" +msgstr "使用する" + +#: ../gtk/parameters.ui.h:81 ../gtk/tunnel_config.ui.h:5 +msgid "Disable" +msgstr "使用しない" + +#: ../gtk/parameters.ui.h:82 +msgid "Audio codecs" +msgstr "音声コーデック" + +#: ../gtk/parameters.ui.h:83 +msgid "Video codecs" +msgstr "動画コーデック" + +#: ../gtk/parameters.ui.h:84 +msgid "Codecs" +msgstr "コーデック" + +#: ../gtk/parameters.ui.h:85 +msgid "Language" +msgstr "言語" + +#: ../gtk/parameters.ui.h:86 +msgid "Show advanced settings" +msgstr "拡張設定を表示する" + +#: ../gtk/parameters.ui.h:87 +msgid "Level" +msgstr "レベル" + +#: ../gtk/parameters.ui.h:88 +msgid "User interface" +msgstr "ユーザーインターフェイス" + +#: ../gtk/parameters.ui.h:92 +msgid "LDAP Account setup" +msgstr "" + +#: ../gtk/parameters.ui.h:93 +msgid "LDAP" +msgstr "LDAP" + +#: ../gtk/parameters.ui.h:94 +msgid "Done" +msgstr "完了" + +#: ../gtk/password.ui.h:1 +msgid "Linphone - Authentication required" +msgstr "" + +#: ../gtk/password.ui.h:2 +msgid "Please enter the domain password" msgstr "" #: ../gtk/provisioning-fetch.ui.h:1 @@ -1697,68 +1551,278 @@ msgstr "" msgid "Please wait while fetching configuration from server..." msgstr "" -#: ../coreapi/linphonecore.c:1539 +#: ../gtk/setup_wizard.ui.h:1 +msgid "SIP account configuration assistant" +msgstr "SIPアカウント設定アシスタント" + +#: ../gtk/setup_wizard.ui.h:2 +msgid "" +"Welcome!\n" +"This assistant will help you to use a SIP account for your calls." +msgstr "ようこそ!\nあなたの通話のためのSIPアカウント設定をお手伝いします。" + +#: ../gtk/setup_wizard.ui.h:4 +msgid "Welcome to the account setup assistant" +msgstr "アカウント設定アシスタントへようこそ" + +#: ../gtk/setup_wizard.ui.h:5 +msgid "Create an account on linphone.org" +msgstr "linphone.orgのアカウントを作成" + +#: ../gtk/setup_wizard.ui.h:6 +msgid "I have already a linphone.org account and I just want to use it" +msgstr "linphone.orgのアカウントを持っているのでそれを使います" + +#: ../gtk/setup_wizard.ui.h:7 +msgid "I have already a sip account and I just want to use it" +msgstr "SIPアカウントを持っているのでそれを使います" + +#: ../gtk/setup_wizard.ui.h:8 +msgid "I want to specify a remote configuration URI" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:9 +msgid "Account setup assistant" +msgstr "アカウント設定アシスタント" + +#: ../gtk/setup_wizard.ui.h:10 +msgid "Enter your account information" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:11 +msgid "Username*" +msgstr "ユーザー名*" + +#: ../gtk/setup_wizard.ui.h:12 +msgid "Password*" +msgstr "パスワード*" + +#: ../gtk/setup_wizard.ui.h:13 +msgid "Domain*" +msgstr "ドメイン*" + +#: ../gtk/setup_wizard.ui.h:14 +msgid "Proxy" +msgstr "プロキシ*" + +#: ../gtk/setup_wizard.ui.h:15 +msgid "Configure your account (step 1/1)" +msgstr "アカウントを設定します (1/1)" + +#: ../gtk/setup_wizard.ui.h:16 +msgid "Enter your linphone.org username" +msgstr "linphone.orgで取得したユーザー名を入力" + +#: ../gtk/setup_wizard.ui.h:19 +msgid "Enter your sip username (step 1/1)" +msgstr "SIPのユーザー名を入力してください (1/1)" + +#: ../gtk/setup_wizard.ui.h:20 +msgid "(*) Required fields" +msgstr "(*) 必須" + +#: ../gtk/setup_wizard.ui.h:21 +msgid "Email: (*)" +msgstr "メールアドレス: (*)" + +#: ../gtk/setup_wizard.ui.h:22 +msgid "Username: (*)" +msgstr "ユーザー名: (*)" + +#: ../gtk/setup_wizard.ui.h:23 +msgid "Password: (*)" +msgstr "パスワード: (*)" + +#: ../gtk/setup_wizard.ui.h:24 +msgid "Confirm your password: (*)" +msgstr "パスワードを再入力: (*)" + +#: ../gtk/setup_wizard.ui.h:25 +msgid "Keep me informed with linphone updates" +msgstr "アップデートでLinphoneを常に最新にする" + +#: ../gtk/setup_wizard.ui.h:26 +msgid "Enter account information (step 1/2)" +msgstr "アカウント情報を入力してください (1/2)" + +#: ../gtk/setup_wizard.ui.h:27 +msgid "Your account is being created, please wait." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:28 +msgid "Account creation in progress" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:29 +msgid "" +"Please validate your account by clicking on the link we just sent you by email.\n" +"Then come back here and press Next button." +msgstr "送信されたメールの本文内にあるリンクをクリックしてアカウントを有効にしてください。\nその後こちらへ戻って「次へ」を押してください。" + +#: ../gtk/setup_wizard.ui.h:31 +msgid "Validation (step 2/2)" +msgstr "検証します (2/2)" + +#: ../gtk/setup_wizard.ui.h:32 +msgid "Checking if your account is been validated, please wait." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:33 +msgid "Account validation check in progress" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:34 +msgid "" +"Error, account not validated, username already used or server unreachable.\n" +"Please go back and try again." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:36 +msgid "Error" +msgstr "エラー" + +#: ../gtk/setup_wizard.ui.h:37 +msgid "Thank you. Your account is now configured and ready for use." +msgstr "ありがとう。あなたのアカウントは無事に設定され、使用する準備ができました。" + +#: ../gtk/sip_account.ui.h:1 +msgid "Linphone - Configure a SIP account" +msgstr "Linphone - SIPアカウントを設定します" + +#: ../gtk/sip_account.ui.h:2 +msgid "Your SIP identity:" +msgstr "" + +#: ../gtk/sip_account.ui.h:3 +msgid "Looks like sip:@" +msgstr "" + +#: ../gtk/sip_account.ui.h:4 +msgid "sip:" +msgstr "sip:" + +#: ../gtk/sip_account.ui.h:5 +msgid "SIP Proxy address:" +msgstr "SIP プロキシ:" + +#: ../gtk/sip_account.ui.h:6 +msgid "Looks like sip:" +msgstr "" + +#: ../gtk/sip_account.ui.h:7 +msgid "Registration duration (sec):" +msgstr "" + +#: ../gtk/sip_account.ui.h:8 +msgid "Contact params (optional):" +msgstr "" + +#: ../gtk/sip_account.ui.h:9 +msgid "AVPF regular RTCP interval (sec):" +msgstr "" + +#: ../gtk/sip_account.ui.h:10 +msgid "Route (optional):" +msgstr "" + +#: ../gtk/sip_account.ui.h:11 +msgid "Transport" +msgstr "転送" + +#: ../gtk/sip_account.ui.h:12 +msgid "Register" +msgstr "登録" + +#: ../gtk/sip_account.ui.h:13 +msgid "Publish presence information" +msgstr "パブリッシュ情報" + +#: ../gtk/sip_account.ui.h:14 +msgid "Enable AVPF" +msgstr "AVPFを有効にする" + +#: ../gtk/sip_account.ui.h:15 +msgid "Configure a SIP account" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:1 +msgid "Configure VoIP tunnel" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:2 +msgid "Host" +msgstr "ホスト" + +#: ../gtk/tunnel_config.ui.h:3 +msgid "Port" +msgstr "ポート" + +#: ../gtk/tunnel_config.ui.h:6 +msgid "Configure tunnel" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:9 +msgid "Configure http proxy (optional)" +msgstr "" + +#: ../gtk/waiting.ui.h:2 +msgid "Please wait" +msgstr "お待ちください" + +#: ../coreapi/linphonecore.c:1560 msgid "Ready" msgstr "準備" -#: ../coreapi/linphonecore.c:2551 +#: ../coreapi/linphonecore.c:2556 msgid "Configuring" msgstr "" -#: ../coreapi/linphonecore.c:2725 -msgid "Looking for telephone number destination..." -msgstr "" - -#: ../coreapi/linphonecore.c:2727 -msgid "Could not resolve this number." -msgstr "" - #. must be known at that time -#: ../coreapi/linphonecore.c:3013 +#: ../coreapi/linphonecore.c:2951 msgid "Contacting" msgstr "" -#: ../coreapi/linphonecore.c:3018 +#: ../coreapi/linphonecore.c:2956 msgid "Could not call" msgstr "" -#: ../coreapi/linphonecore.c:3169 +#: ../coreapi/linphonecore.c:3092 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "" -#: ../coreapi/linphonecore.c:3327 +#: ../coreapi/linphonecore.c:3250 msgid "is contacting you" msgstr "" -#: ../coreapi/linphonecore.c:3328 +#: ../coreapi/linphonecore.c:3251 msgid " and asked autoanswer." msgstr "と自動応答を尋ねる" -#: ../coreapi/linphonecore.c:3452 +#: ../coreapi/linphonecore.c:3377 msgid "Modifying call parameters..." msgstr "コールパラメーターの変更..." -#: ../coreapi/linphonecore.c:3802 +#: ../coreapi/linphonecore.c:3769 msgid "Connected." msgstr "接続しました。" -#: ../coreapi/linphonecore.c:3827 +#: ../coreapi/linphonecore.c:3794 msgid "Call aborted" msgstr "呼び出しを打ち切る" -#: ../coreapi/linphonecore.c:4024 +#: ../coreapi/linphonecore.c:3983 msgid "Could not pause the call" msgstr "呼び出しを一時停止できませんでした" -#: ../coreapi/linphonecore.c:4027 +#: ../coreapi/linphonecore.c:3986 msgid "Pausing the current call..." msgstr "現在の通話を一時停止..." -#: ../coreapi/misc.c:434 +#: ../coreapi/misc.c:440 msgid "Stun lookup in progress..." msgstr "Stunによるルックアップの進行中…" -#: ../coreapi/misc.c:615 +#: ../coreapi/misc.c:650 msgid "ICE local candidates gathering in progress..." msgstr "" @@ -1814,165 +1878,172 @@ msgstr "休暇中" msgid "Unknown status" msgstr "不明なステータス" -#: ../coreapi/proxy.c:328 +#: ../coreapi/proxy.c:292 msgid "" "The sip proxy address you entered is invalid, it must start with \"sip:\" " "followed by a hostname." msgstr "" -#: ../coreapi/proxy.c:334 +#: ../coreapi/proxy.c:298 msgid "" "The sip identity you entered is invalid.\n" "It should look like sip:username@proxydomain, such as sip:alice@example.net" msgstr "" -#: ../coreapi/proxy.c:1416 +#: ../coreapi/proxy.c:927 +msgid "Looking for telephone number destination..." +msgstr "" + +#: ../coreapi/proxy.c:931 +msgid "Could not resolve this number." +msgstr "" + +#: ../coreapi/proxy.c:1324 #, c-format msgid "Could not login as %s" msgstr "" -#: ../coreapi/callbacks.c:428 +#: ../coreapi/proxy.c:1411 +#, c-format +msgid "Refreshing on %s..." +msgstr "" + +#: ../coreapi/callbacks.c:423 msgid "Remote ringing." msgstr "" -#: ../coreapi/callbacks.c:440 +#: ../coreapi/callbacks.c:435 msgid "Remote ringing..." msgstr "" -#: ../coreapi/callbacks.c:461 +#: ../coreapi/callbacks.c:458 msgid "Early media." msgstr "Early media." -#: ../coreapi/callbacks.c:534 +#: ../coreapi/callbacks.c:488 #, c-format -msgid "Call with %s is paused." +msgid "Call answered by %s" msgstr "" -#: ../coreapi/callbacks.c:547 -#, c-format -msgid "Call answered by %s - on hold." -msgstr "" - -#: ../coreapi/callbacks.c:557 +#: ../coreapi/callbacks.c:527 msgid "Call resumed." msgstr "" -#: ../coreapi/callbacks.c:561 -#, c-format -msgid "Call answered by %s." -msgstr "" - -#: ../coreapi/callbacks.c:584 +#: ../coreapi/callbacks.c:582 msgid "Incompatible, check codecs or security settings..." msgstr "" -#: ../coreapi/callbacks.c:589 ../coreapi/callbacks.c:906 +#: ../coreapi/callbacks.c:587 ../coreapi/callbacks.c:923 msgid "Incompatible media parameters." msgstr "" -#: ../coreapi/callbacks.c:619 +#: ../coreapi/callbacks.c:612 msgid "We have been resumed." msgstr "" #. we are being paused -#: ../coreapi/callbacks.c:628 +#: ../coreapi/callbacks.c:620 msgid "We are paused by other party." msgstr "" -#. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:666 +#: ../coreapi/callbacks.c:630 msgid "Call is updated by remote." msgstr "" -#: ../coreapi/callbacks.c:782 +#: ../coreapi/callbacks.c:799 msgid "Call terminated." msgstr "呼び出し終了。" -#: ../coreapi/callbacks.c:810 +#: ../coreapi/callbacks.c:827 msgid "User is busy." msgstr "相手はビジーです。" -#: ../coreapi/callbacks.c:811 +#: ../coreapi/callbacks.c:828 msgid "User is temporarily unavailable." msgstr "相手は、今出られません。" #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:813 +#: ../coreapi/callbacks.c:830 msgid "User does not want to be disturbed." msgstr "相手は手が離せないようです。" -#: ../coreapi/callbacks.c:814 +#: ../coreapi/callbacks.c:831 msgid "Call declined." msgstr "通話は拒否されました。" -#: ../coreapi/callbacks.c:829 +#: ../coreapi/callbacks.c:846 msgid "Request timeout." msgstr "リクエストは時間切れです。" -#: ../coreapi/callbacks.c:860 +#: ../coreapi/callbacks.c:877 msgid "Redirected" msgstr "" -#: ../coreapi/callbacks.c:915 +#: ../coreapi/callbacks.c:927 msgid "Call failed." msgstr "" -#: ../coreapi/callbacks.c:993 +#: ../coreapi/callbacks.c:1005 #, c-format msgid "Registration on %s successful." msgstr "" -#: ../coreapi/callbacks.c:994 +#: ../coreapi/callbacks.c:1006 #, c-format msgid "Unregistration on %s done." msgstr "" -#: ../coreapi/callbacks.c:1012 +#: ../coreapi/callbacks.c:1024 msgid "no response timeout" msgstr "" -#: ../coreapi/callbacks.c:1015 +#: ../coreapi/callbacks.c:1027 #, c-format msgid "Registration on %s failed: %s" msgstr "" -#: ../coreapi/callbacks.c:1022 +#: ../coreapi/callbacks.c:1034 msgid "Service unavailable, retrying" msgstr "" #. if encryption is DTLS, no status to be displayed -#: ../coreapi/linphonecall.c:180 +#: ../coreapi/linphonecall.c:197 #, c-format msgid "Authentication token is %s" msgstr "" -#: ../coreapi/linphonecall.c:1310 +#: ../coreapi/linphonecall.c:1561 +#, c-format +msgid "Call parameters could not be modified: %s." +msgstr "" + +#: ../coreapi/linphonecall.c:1563 msgid "Call parameters were successfully modified." msgstr "" -#: ../coreapi/linphonecall.c:3686 +#: ../coreapi/linphonecall.c:4396 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." msgstr[0] "" -#: ../coreapi/call_log.c:209 +#: ../coreapi/call_log.c:223 msgid "aborted" msgstr "" -#: ../coreapi/call_log.c:212 +#: ../coreapi/call_log.c:226 msgid "completed" msgstr "" -#: ../coreapi/call_log.c:215 +#: ../coreapi/call_log.c:229 msgid "missed" msgstr "" -#: ../coreapi/call_log.c:218 +#: ../coreapi/call_log.c:232 msgid "unknown" msgstr "不明" -#: ../coreapi/call_log.c:220 +#: ../coreapi/call_log.c:234 #, c-format msgid "" "%s at %s\n" @@ -1982,7 +2053,7 @@ msgid "" "Duration: %i mn %i sec\n" msgstr "" -#: ../coreapi/call_log.c:221 +#: ../coreapi/call_log.c:235 msgid "Outgoing call" msgstr "" diff --git a/po/lt.po b/po/lt.po new file mode 100644 index 000000000..3f35679e7 --- /dev/null +++ b/po/lt.po @@ -0,0 +1,2070 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Translators: +# Moo, 2015 +msgid "" +msgstr "" +"Project-Id-Version: linphone-gtk\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-11-10 15:16+0100\n" +"PO-Revision-Date: 2015-11-10 18:53+0000\n" +"Last-Translator: Moo\n" +"Language-Team: Lithuanian (http://www.transifex.com/belledonne-communications/linphone-gtk/language/lt/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: lt\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#: ../gtk/calllogs.c:178 +#, c-format +msgid "Call %s" +msgstr "Skambinti %s" + +#: ../gtk/calllogs.c:179 +#, c-format +msgid "Send text to %s" +msgstr "Siųsti tekstą į %s" + +#: ../gtk/calllogs.c:181 +#, c-format +msgid "Add %s to your contact list" +msgstr "Pridėti %s į jūsų kontaktų sąrašą" + +#: ../gtk/calllogs.c:245 ../gtk/main.ui.h:21 +msgid "Recent calls" +msgstr "Paskiausi skambučiai" + +#: ../gtk/calllogs.c:260 +#, c-format +msgid "Recent calls (%i)" +msgstr "Paskiausi skambučiai (%i)" + +#: ../gtk/calllogs.c:331 +msgid "n/a" +msgstr "" + +#: ../gtk/calllogs.c:334 +msgid "Aborted" +msgstr "Nutrauktas" + +#: ../gtk/calllogs.c:337 +msgid "Missed" +msgstr "Praleistas" + +#: ../gtk/calllogs.c:340 +msgid "Declined" +msgstr "Atmestas" + +#: ../gtk/calllogs.c:346 +#, c-format +msgid "%i minute" +msgid_plural "%i minutes" +msgstr[0] "%i minutė" +msgstr[1] "%i minutės" +msgstr[2] "%i minučių" + +#: ../gtk/calllogs.c:349 +#, c-format +msgid "%i second" +msgid_plural "%i seconds" +msgstr[0] "%i sekundė" +msgstr[1] "%i sekundės" +msgstr[2] "%i sekundžių" + +#: ../gtk/calllogs.c:354 +#, c-format +msgid "" +"%s\tQuality: %s\n" +"%s\t%s\t" +msgstr "%s\tKokybė: %s\n%s\t%s\t" + +#: ../gtk/calllogs.c:358 +#, c-format +msgid "%s\t%s" +msgstr "%s\t%s" + +#: ../gtk/conference.c:38 ../gtk/in_call_frame.ui.h:11 +msgid "Conference" +msgstr "Konferencija" + +#: ../gtk/conference.c:46 +msgid "Me" +msgstr "" + +#: ../gtk/support.c:49 ../gtk/support.c:73 ../gtk/support.c:102 +#, c-format +msgid "Couldn't find pixmap file: %s" +msgstr "" + +#: ../gtk/chat.c:196 ../gtk/chat.c:254 +msgid "Sending..." +msgstr "Siunčiama..." + +#: ../gtk/chat.c:213 ../gtk/chat.c:263 +msgid "Message not sent" +msgstr "Pranešimas neišsiųstas" + +#: ../gtk/chat.c:472 +msgid "Copy" +msgstr "Kopijuoti" + +#: ../gtk/main.c:138 +msgid "log to stdout some debug information while running." +msgstr "kol vykdoma, registruoti į stdout kai kurią derinimo informaciją." + +#: ../gtk/main.c:139 +msgid "display version and exit." +msgstr "parodyti versiją ir išeiti." + +#: ../gtk/main.c:140 +msgid "path to a file to write logs into." +msgstr "kelias į failą, į kurį rašyti žurnalus." + +#: ../gtk/main.c:141 +msgid "Start linphone with video disabled." +msgstr "Paleisti linphone su išjungtu vaizdu." + +#: ../gtk/main.c:142 +msgid "Start only in the system tray, do not show the main interface." +msgstr "Paleisti tik sistemos dėkle, nerodyti pagrindinės sąsajos." + +#: ../gtk/main.c:143 +msgid "address to call right now" +msgstr "adresas, į kurį tuoj pat skambinti" + +#: ../gtk/main.c:144 +msgid "" +"Specifiy a working directory (should be the base of the installation, eg: " +"c:\\Program Files\\Linphone)" +msgstr "Nurodyti darbinį katalogą (turėtų būti diegimo bazė, pvz.,: c:\\Program Files\\Linphone)" + +#: ../gtk/main.c:145 +msgid "Configuration file" +msgstr "Konfigūracijos failas" + +#: ../gtk/main.c:146 +msgid "Run the audio assistant" +msgstr "Vykdyti garso pagelbiklį" + +#: ../gtk/main.c:147 +msgid "Run self test and exit 0 if succeed" +msgstr "Vykdyti savikontrolę ir išeiti 0, jei pavyks" + +#: ../gtk/main.c:1046 +#, c-format +msgid "" +"%s would like to add you to his/her contact list.\n" +"Would you add him/her to your contact list and allow him/her to see your presence status?\n" +"If you answer no, this person will be temporarily blacklisted." +msgstr "%s norėtų jus pridėti į savo kontaktų sąrašą.\nAr jūs norėtumėte taip pat pridėti jį/ją į savo kontaktų sąrašą ir leisti jam/jai matyti jūsų prisijungimo būseną?\nJeigu atsakysite ne, šis asmuo bus laikinai pridėtas į juodąjį sąrašą." + +#: ../gtk/main.c:1123 +#, c-format +msgid "" +"Please enter your password for username %s\n" +" at realm %s:" +msgstr "" + +#: ../gtk/main.c:1253 +msgid "Call error" +msgstr "Skambučio klaida" + +#: ../gtk/main.c:1256 ../coreapi/linphonecore.c:3813 +msgid "Call ended" +msgstr "Skambutis užbaigtas" + +#: ../gtk/main.c:1259 ../coreapi/call_log.c:235 +msgid "Incoming call" +msgstr "Įeinantis skambutis" + +#: ../gtk/main.c:1261 ../gtk/incall_view.c:580 ../gtk/in_call_frame.ui.h:2 +msgid "Answer" +msgstr "Atsiliepti" + +#: ../gtk/main.c:1263 ../gtk/in_call_frame.ui.h:3 +msgid "Decline" +msgstr "Atmesti" + +#: ../gtk/main.c:1269 +msgid "Call paused" +msgstr "Skambutis pristabdytas" + +#: ../gtk/main.c:1269 +#, c-format +msgid "by %s" +msgstr "naudotojo %s" + +#: ../gtk/main.c:1339 +#, c-format +msgid "%s proposed to start video. Do you accept ?" +msgstr "%s pasiūlė pradėti vaizdą. Jūs sutinkate ?" + +#: ../gtk/main.c:1505 +msgid "Website link" +msgstr "Svetainės nuoroda" + +#: ../gtk/main.c:1564 ../gtk/waiting.ui.h:1 +msgid "Linphone" +msgstr "Linphone" + +#: ../gtk/main.c:1565 +msgid "A video internet phone" +msgstr "Internetinis vaizdo telefonas" + +#: ../gtk/main.c:1624 +#, c-format +msgid "%s (Default)" +msgstr "" + +#: ../gtk/main.c:1960 ../coreapi/callbacks.c:1075 +#, c-format +msgid "We are transferred to %s" +msgstr "" + +#: ../gtk/main.c:1970 +msgid "" +"No sound cards have been detected on this computer.\n" +"You won't be able to send or receive audio calls." +msgstr "Šiame kompiuteryje nebuvo aptikta jokių garso plokščių.\nJūs negalėsite siųsti ir priimti garso skambučių." + +#: ../gtk/main.c:2129 +msgid "A free SIP video-phone" +msgstr "Nemokamas SIP vaizdo telefonas" + +#: ../gtk/main.c:2242 +#, c-format +msgid "Hello\n" +msgstr "Sveiki\n" + +#: ../gtk/friendlist.c:461 +msgid "Add to addressbook" +msgstr "Pridėti į adresų knygą" + +#: ../gtk/friendlist.c:627 +#, c-format +msgid "Search in %s directory" +msgstr "" + +#: ../gtk/friendlist.c:772 +msgid "Invalid sip contact !" +msgstr "Netaisyklingas sip kontaktas !" + +#: ../gtk/friendlist.c:820 +#, c-format +msgid "Add a new contact" +msgstr "Pridėti naują kontaktą" + +#: ../gtk/friendlist.c:823 +#, c-format +msgid "Edit contact '%s'" +msgstr "Redaguoti kontaktą \"%s\"" + +#: ../gtk/friendlist.c:824 +#, c-format +msgid "Delete contact '%s'" +msgstr "Ištrinti kontaktą \"%s\"" + +#: ../gtk/friendlist.c:825 +#, c-format +msgid "Delete chat history of '%s'" +msgstr "Ištrinti \"%s\" pokalbių istoriją" + +#: ../gtk/friendlist.c:862 +#, c-format +msgid "Add new contact from %s directory" +msgstr "" + +#: ../gtk/propertybox.c:592 ../gtk/contact.ui.h:1 +msgid "Name" +msgstr "Vardas" + +#: ../gtk/propertybox.c:598 +msgid "Rate (Hz)" +msgstr "Sparta (Hz)" + +#: ../gtk/propertybox.c:604 +msgid "Status" +msgstr "Būsena" + +#: ../gtk/propertybox.c:617 +msgid "IP Bitrate (kbit/s)" +msgstr "IP Pralaidumas (kbit/s)" + +#: ../gtk/propertybox.c:628 +msgid "Parameters" +msgstr "Parametrai" + +#: ../gtk/propertybox.c:670 ../gtk/propertybox.c:824 +msgid "Enabled" +msgstr "Įjungta" + +#: ../gtk/propertybox.c:672 ../gtk/propertybox.c:824 ../gtk/parameters.ui.h:60 +msgid "Disabled" +msgstr "Išjungta" + +#: ../gtk/propertybox.c:902 +msgid "Account" +msgstr "Paskyra" + +#: ../gtk/propertybox.c:1170 +msgid "English" +msgstr "Anglų" + +#: ../gtk/propertybox.c:1171 +msgid "French" +msgstr "Prancūzų" + +#: ../gtk/propertybox.c:1172 +msgid "Swedish" +msgstr "Švedų" + +#: ../gtk/propertybox.c:1173 +msgid "Italian" +msgstr "Italų" + +#: ../gtk/propertybox.c:1174 +msgid "Spanish" +msgstr "Ispanų" + +#: ../gtk/propertybox.c:1175 +msgid "Brazilian Portugese" +msgstr "Brazilijos Portugalų" + +#: ../gtk/propertybox.c:1176 +msgid "Polish" +msgstr "Lenkų" + +#: ../gtk/propertybox.c:1177 +msgid "German" +msgstr "Vokiečių" + +#: ../gtk/propertybox.c:1178 +msgid "Russian" +msgstr "Rusų" + +#: ../gtk/propertybox.c:1179 +msgid "Japanese" +msgstr "Japonų" + +#: ../gtk/propertybox.c:1180 +msgid "Dutch" +msgstr "Olandų" + +#: ../gtk/propertybox.c:1181 +msgid "Hungarian" +msgstr "Vengrų" + +#: ../gtk/propertybox.c:1182 +msgid "Czech" +msgstr "Čekų" + +#: ../gtk/propertybox.c:1183 +msgid "Chinese" +msgstr "Kinų" + +#: ../gtk/propertybox.c:1184 +msgid "Traditional Chinese" +msgstr "Tradicinė Kinų" + +#: ../gtk/propertybox.c:1185 +msgid "Norwegian" +msgstr "Norvegų" + +#: ../gtk/propertybox.c:1186 +msgid "Hebrew" +msgstr "Hebrajų" + +#: ../gtk/propertybox.c:1187 +msgid "Serbian" +msgstr "Serbų" + +#: ../gtk/propertybox.c:1188 +msgid "Arabic" +msgstr "Arabų" + +#: ../gtk/propertybox.c:1189 +msgid "Turkish" +msgstr "Turkų" + +#: ../gtk/propertybox.c:1246 +msgid "" +"You need to restart linphone for the new language selection to take effect." +msgstr "Tam, kad įsigaliotų naujas kalbos pasirinkimas, turite iš naujo paleisti programą linphone." + +#: ../gtk/propertybox.c:1326 +msgid "None" +msgstr "Nėra" + +#: ../gtk/propertybox.c:1330 +msgid "SRTP" +msgstr "SRTP" + +#: ../gtk/propertybox.c:1336 +msgid "DTLS" +msgstr "DTLS" + +#: ../gtk/propertybox.c:1343 +msgid "ZRTP" +msgstr "ZRTP" + +#: ../gtk/update.c:80 +#, c-format +msgid "" +"A more recent version is availalble from %s.\n" +"Would you like to open a browser to download it ?" +msgstr "Yra prieinama naujesnė versija iš %s.\nAr norėtumėte atverti naršyklę ir ją atsisiųsti?" + +#: ../gtk/update.c:91 +msgid "You are running the lastest version." +msgstr "Jūs naudojatės paskiausia versija." + +#: ../gtk/buddylookup.c:85 +msgid "Firstname, Lastname" +msgstr "Vardas, Pavardė" + +#: ../gtk/buddylookup.c:160 +msgid "Error communicating with server." +msgstr "Klaida, susisiekiant su serveriu." + +#: ../gtk/buddylookup.c:164 +msgid "Connecting..." +msgstr "Jungiamasi..." + +#: ../gtk/buddylookup.c:168 +msgid "Connected" +msgstr "Prisijungta" + +#: ../gtk/buddylookup.c:172 +msgid "Receiving data..." +msgstr "Gaunami duomenys..." + +#: ../gtk/buddylookup.c:180 +#, c-format +msgid "Found %i contact" +msgid_plural "Found %i contacts" +msgstr[0] "Rastas %i kontaktas" +msgstr[1] "Rasti %i kontaktai" +msgstr[2] "Rasta %i kontaktų" + +#: ../gtk/incall_view.c:67 ../gtk/incall_view.c:87 +#, c-format +msgid "Call #%i" +msgstr "Skambutis #%i" + +#: ../gtk/incall_view.c:145 +#, c-format +msgid "Transfer to call #%i with %s" +msgstr "" + +#: ../gtk/incall_view.c:202 ../gtk/incall_view.c:205 +msgid "Not used" +msgstr "Nenaudojama" + +#: ../gtk/incall_view.c:212 +msgid "ICE not activated" +msgstr "ICE neaktyvuota" + +#: ../gtk/incall_view.c:214 +msgid "ICE failed" +msgstr "ICE nepavyko" + +#: ../gtk/incall_view.c:216 +msgid "ICE in progress" +msgstr "ICE yra eigoje" + +#: ../gtk/incall_view.c:218 +msgid "Going through one or more NATs" +msgstr "" + +#: ../gtk/incall_view.c:220 +msgid "Direct" +msgstr "" + +#: ../gtk/incall_view.c:222 +msgid "Through a relay server" +msgstr "" + +#: ../gtk/incall_view.c:230 +msgid "uPnP not activated" +msgstr "uPnP neaktyvuota" + +#: ../gtk/incall_view.c:232 +msgid "uPnP in progress" +msgstr "uPnP yra eigoje" + +#: ../gtk/incall_view.c:234 +msgid "uPnp not available" +msgstr "uPnp neprieinama" + +#: ../gtk/incall_view.c:236 +msgid "uPnP is running" +msgstr "uPnP yra vykdoma" + +#: ../gtk/incall_view.c:238 +msgid "uPnP failed" +msgstr "uPnP nepavyko" + +#: ../gtk/incall_view.c:248 ../gtk/incall_view.c:249 +msgid "Direct or through server" +msgstr "" + +#: ../gtk/incall_view.c:258 ../gtk/incall_view.c:270 +#, c-format +msgid "" +"download: %f\n" +"upload: %f (kbit/s)" +msgstr "atsiuntimas: %f\nišsiuntimas: %f (kbit/s)" + +#: ../gtk/incall_view.c:263 ../gtk/incall_view.c:265 +#, c-format +msgid "%ix%i @ %f fps" +msgstr "%ix%i @ %f kadr./s" + +#: ../gtk/incall_view.c:295 +#, c-format +msgid "%.3f seconds" +msgstr "%.3f sekundžių" + +#: ../gtk/incall_view.c:453 ../gtk/in_call_frame.ui.h:10 +#: ../gtk/videowindow.c:236 +msgid "Hang up" +msgstr "Padėti ragelį" + +#: ../gtk/incall_view.c:559 +msgid "Calling..." +msgstr "Skambinama..." + +#: ../gtk/incall_view.c:562 ../gtk/incall_view.c:792 +msgid "00:00:00" +msgstr "00:00:00" + +#: ../gtk/incall_view.c:573 +msgid "Incoming call" +msgstr "Įeinantis skambutis" + +#: ../gtk/incall_view.c:610 +msgid "good" +msgstr "geras" + +#: ../gtk/incall_view.c:612 +msgid "average" +msgstr "vidutinis" + +#: ../gtk/incall_view.c:614 +msgid "poor" +msgstr "žemas" + +#: ../gtk/incall_view.c:616 +msgid "very poor" +msgstr "labai žemas" + +#: ../gtk/incall_view.c:618 +msgid "too bad" +msgstr "pernelyg blogas" + +#: ../gtk/incall_view.c:619 ../gtk/incall_view.c:635 +msgid "unavailable" +msgstr "neprieinama" + +#: ../gtk/incall_view.c:731 +msgid "Secured by SRTP" +msgstr "" + +#: ../gtk/incall_view.c:737 +msgid "Secured by DTLS" +msgstr "" + +#: ../gtk/incall_view.c:743 +#, c-format +msgid "Secured by ZRTP - [auth token: %s]" +msgstr "" + +#: ../gtk/incall_view.c:747 +msgid "Set unverified" +msgstr "" + +#: ../gtk/incall_view.c:747 +msgid "Set verified" +msgstr "" + +#: ../gtk/incall_view.c:787 +msgid "In conference" +msgstr "Konferencijoje" + +#: ../gtk/incall_view.c:787 +msgid "In call" +msgstr "Skambutyje" + +#: ../gtk/incall_view.c:824 +msgid "Paused call" +msgstr "Skambutis pristabdytas" + +#: ../gtk/incall_view.c:861 +msgid "Call ended." +msgstr "Skambutis užbaigtas." + +#: ../gtk/incall_view.c:892 +msgid "Transfer in progress" +msgstr "" + +#: ../gtk/incall_view.c:895 +msgid "Transfer done." +msgstr "" + +#: ../gtk/incall_view.c:898 +msgid "Transfer failed." +msgstr "" + +#: ../gtk/incall_view.c:929 +msgid "Resume" +msgstr "Tęsti" + +#: ../gtk/incall_view.c:929 ../gtk/in_call_frame.ui.h:7 +msgid "Pause" +msgstr "Pristabdyti" + +#: ../gtk/incall_view.c:995 +#, c-format +msgid "" +"Recording into\n" +"%s %s" +msgstr "Įrašoma į\n%s %s" + +#: ../gtk/incall_view.c:995 +msgid "(Paused)" +msgstr "(Pristabdyta)" + +#: ../gtk/loginframe.c:75 +#, c-format +msgid "Please enter login information for %s" +msgstr "Prašome įvesti %s prisijungimo informaciją" + +#: ../gtk/config-fetching.c:57 +#, c-format +msgid "fetching from %s" +msgstr "gaunama iš %s" + +#: ../gtk/config-fetching.c:73 +#, c-format +msgid "Downloading of remote configuration from %s failed." +msgstr "Nuotolinės konfigūracijos atsiuntimas iš %s nepavyko." + +#: ../gtk/audio_assistant.c:103 +msgid "No voice detected" +msgstr "Neaptikta jokio balso" + +#: ../gtk/audio_assistant.c:104 +msgid "Too low" +msgstr "Per tyliai" + +#: ../gtk/audio_assistant.c:105 +msgid "Good" +msgstr "Gerai" + +#: ../gtk/audio_assistant.c:106 +msgid "Too loud" +msgstr "Per garsiai" + +#: ../gtk/audio_assistant.c:188 +msgid "Did you hear three beeps ?" +msgstr "Ar girdėjote tris byptelėjimus?" + +#: ../gtk/audio_assistant.c:299 ../gtk/audio_assistant.c:304 +msgid "Sound preferences not found " +msgstr "Garso nuostatos nerastos" + +#: ../gtk/audio_assistant.c:313 +msgid "Cannot launch system sound control " +msgstr "Nepavyko paleisti sistemos garso valdymą" + +#: ../gtk/audio_assistant.c:325 +msgid "" +"Welcome!\n" +"This assistant will help you to configure audio settings for Linphone" +msgstr "Sveiki!\nŠis pagelbiklis padės jums sukonfigūruoti Linphone garso nustatymus" + +#: ../gtk/audio_assistant.c:335 +msgid "Capture device" +msgstr "Mikrofonas" + +#: ../gtk/audio_assistant.c:336 +msgid "Recorded volume" +msgstr "Įrašomas garsis" + +#: ../gtk/audio_assistant.c:340 +msgid "No voice" +msgstr "Nėra balso" + +#: ../gtk/audio_assistant.c:341 ../gtk/audio_assistant.c:380 +msgid "System sound preferences" +msgstr "Sistemos garso nuostatos" + +#: ../gtk/audio_assistant.c:376 +msgid "Playback device" +msgstr "Atkūrimo įrenginys" + +#: ../gtk/audio_assistant.c:377 +msgid "Play three beeps" +msgstr "Groti tris byptelėjimus" + +#: ../gtk/audio_assistant.c:410 +msgid "Press the record button and say some words" +msgstr "Spustelėkite įrašymo mygtuką ir tarkite kelis žodžius" + +#: ../gtk/audio_assistant.c:411 +msgid "Listen to your record voice" +msgstr "Klausytis savo įrašyto balso" + +#: ../gtk/audio_assistant.c:412 ../gtk/conf_frame.ui.h:2 +#: ../gtk/in_call_frame.ui.h:4 +msgid "Record" +msgstr "Įrašyti" + +#: ../gtk/audio_assistant.c:413 +msgid "Play" +msgstr "Groti" + +#: ../gtk/audio_assistant.c:440 +msgid "Let's start Linphone now" +msgstr "Dabar, paleiskime Linphone" + +#: ../gtk/audio_assistant.c:510 +msgid "Audio Assistant" +msgstr "Garso Pagelbiklis" + +#: ../gtk/audio_assistant.c:520 ../gtk/main.ui.h:13 +msgid "Audio assistant" +msgstr "Garso pagelbiklis" + +#: ../gtk/audio_assistant.c:525 +msgid "Mic Gain calibration" +msgstr "Mikrofono stiprinimo gradavimas" + +#: ../gtk/audio_assistant.c:531 +msgid "Speaker volume calibration" +msgstr "Garsiakalbių garsio gradavimas" + +#: ../gtk/audio_assistant.c:536 +msgid "Record and Play" +msgstr "Įrašykite ir Grokite" + +#: ../gtk/audio_assistant.c:541 ../gtk/setup_wizard.ui.h:38 +msgid "Terminating" +msgstr "Baigiama" + +#: ../gtk/about.ui.h:1 +msgid "About Linphone" +msgstr "Apie Linphone" + +#: ../gtk/about.ui.h:2 +msgid "(C) Belledonne Communications, 2010\n" +msgstr "(C) Belledonne Communications, 2010\n" + +#: ../gtk/about.ui.h:4 +msgid "An internet video phone using the standard SIP (rfc3261) protocol." +msgstr "Internetinis vaizdo telefonas, naudojantis standartinį SIP (rfc3261) protokolą." + +#: ../gtk/about.ui.h:5 +msgid "" +"fr: Simon Morlat\n" +"en: Simon Morlat and Delphine Perreau\n" +"it: Alberto Zanoni \n" +"de: Jean-Jacques Sarton \n" +"sv: Daniel Nylander \n" +"es: Jesus Benitez \n" +"ja: YAMAGUCHI YOSHIYA \n" +"pt_BR: Rafael Caesar Lenzi \n" +"pl: Robert Nasiadek \n" +"cs: Petr Pisar \n" +"hu: anonymous\n" +"he: Eli Zaretskii \n" +msgstr "fr: Simon Morlat\nen: Simon Morlat and Delphine Perreau\nit: Alberto Zanoni \nde: Jean-Jacques Sarton \nsv: Daniel Nylander \nes: Jesus Benitez \nja: YAMAGUCHI YOSHIYA \npt_BR: Rafael Caesar Lenzi \npl: Robert Nasiadek \ncs: Petr Pisar \nhu: anonymous\nhe: Eli Zaretskii \n" + +#: ../gtk/buddylookup.ui.h:1 +msgid "Search contacts in directory" +msgstr "" + +#: ../gtk/buddylookup.ui.h:2 +msgid "Add to my list" +msgstr "Pridėti į mano sąrašą" + +#: ../gtk/buddylookup.ui.h:3 +msgid "Search somebody" +msgstr "" + +#: ../gtk/callee_frame.ui.h:1 +msgid "Callee name" +msgstr "" + +#: ../gtk/call_logs.ui.h:1 +msgid "Call history" +msgstr "" + +#: ../gtk/call_logs.ui.h:2 +msgid "Clear all" +msgstr "" + +#: ../gtk/call_logs.ui.h:3 +msgid "Call back" +msgstr "" + +#: ../gtk/call_statistics.ui.h:1 +msgid "Call statistics" +msgstr "Skambučio statistika" + +#: ../gtk/call_statistics.ui.h:2 +msgid "Audio codec" +msgstr "Garso kodekas" + +#: ../gtk/call_statistics.ui.h:3 +msgid "Video codec" +msgstr "Vaizdo kodekas" + +#: ../gtk/call_statistics.ui.h:4 +msgid "Audio IP bandwidth usage" +msgstr "Garso IP pralaidumo naudojimas" + +#: ../gtk/call_statistics.ui.h:5 +msgid "Audio Media connectivity" +msgstr "" + +#: ../gtk/call_statistics.ui.h:6 +msgid "Video IP bandwidth usage" +msgstr "Vaizdo IP pralaidumo naudojimas" + +#: ../gtk/call_statistics.ui.h:7 +msgid "Video Media connectivity" +msgstr "" + +#: ../gtk/call_statistics.ui.h:8 +msgid "Round trip time" +msgstr "" + +#: ../gtk/call_statistics.ui.h:9 +msgid "Video resolution received" +msgstr "" + +#: ../gtk/call_statistics.ui.h:10 +msgid "Video resolution sent" +msgstr "" + +#: ../gtk/call_statistics.ui.h:11 +msgid "RTP profile" +msgstr "" + +#: ../gtk/call_statistics.ui.h:12 +msgid "Call statistics and information" +msgstr "Skambučio statistika ir informacija" + +#: ../gtk/chatroom_frame.ui.h:1 +msgid "Send" +msgstr "Siųsti" + +#: ../gtk/conf_frame.ui.h:1 +msgid "End conference" +msgstr "Užbaigti konferenciją" + +#: ../gtk/config-uri.ui.h:1 +msgid "Specifying a remote configuration URI" +msgstr "Nuotolinės konfigūracijos URI nurodymas" + +#: ../gtk/config-uri.ui.h:2 +msgid "" +"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" +"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " +msgstr "Šis dialogas leidžia nustatyti http ar https adresą, kai konfigūracija bus gaunama paleisties metu.\nPrašome žemiau įvesti ar pakeisti konfigūracijos URI. Po to, kai nuspausite mygtuką Gerai, programa Linphone bus automatiškai paleista iš naujo, kad gautų ir naudotų naująją konfigūraciją." + +#: ../gtk/contact.ui.h:2 +msgid "SIP Address" +msgstr "SIP adresas" + +#: ../gtk/contact.ui.h:3 +msgid "Show this contact presence status" +msgstr "Rodyti šio kontakto prisijungimo būseną" + +#: ../gtk/contact.ui.h:4 +msgid "Allow this contact to see my presence status" +msgstr "Leisti šiam kontaktui matyti mano prisijungimo būseną" + +#: ../gtk/contact.ui.h:5 +msgid "Contact information" +msgstr "Kontakto informacija" + +#: ../gtk/dscp_settings.ui.h:1 +msgid "DSCP settings" +msgstr "DSCP nustatymai" + +#: ../gtk/dscp_settings.ui.h:2 +msgid "SIP" +msgstr "SIP" + +#: ../gtk/dscp_settings.ui.h:3 +msgid "Audio RTP stream" +msgstr "Garso RTP srautas" + +#: ../gtk/dscp_settings.ui.h:4 +msgid "Video RTP stream" +msgstr "Vaizdo RTP srautas" + +#: ../gtk/dscp_settings.ui.h:5 +msgid "Set DSCP values (in hexadecimal)" +msgstr "Nustatykite DSCP reikšmes (šešioliktainiais)" + +#: ../gtk/in_call_frame.ui.h:1 +msgid "Click here to set the speakers volume" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:5 +msgid "Record this call to an audio file" +msgstr "Įrašyti šį skambutį į garso įrašo failą" + +#: ../gtk/in_call_frame.ui.h:6 +msgid "Video" +msgstr "Vaizdas" + +#: ../gtk/in_call_frame.ui.h:8 +msgid "Mute" +msgstr "Nutildyti" + +#: ../gtk/in_call_frame.ui.h:9 +msgid "Transfer" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:12 +msgid "In call" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:13 +msgid "Duration" +msgstr "Trukmė" + +#: ../gtk/in_call_frame.ui.h:14 +msgid "Call quality rating" +msgstr "Skambučio kokybės įvertinimas" + +#: ../gtk/ldap.ui.h:1 +msgid "LDAP Settings" +msgstr "LDAP nustatymai" + +#: ../gtk/ldap.ui.h:2 ../gtk/parameters.ui.h:89 +msgid "Server address:" +msgstr "Serverio adresas:" + +#: ../gtk/ldap.ui.h:3 ../gtk/parameters.ui.h:90 +msgid "Authentication method:" +msgstr "" + +#: ../gtk/ldap.ui.h:4 ../gtk/parameters.ui.h:91 ../gtk/setup_wizard.ui.h:17 +msgid "Username:" +msgstr "Naudotojo vardas:" + +#: ../gtk/ldap.ui.h:5 ../gtk/password.ui.h:4 ../gtk/setup_wizard.ui.h:18 +msgid "Password:" +msgstr "Slaptažodis:" + +#: ../gtk/ldap.ui.h:6 +msgid "Use TLS Connection" +msgstr "" + +#: ../gtk/ldap.ui.h:7 +msgid "Not yet available" +msgstr "" + +#: ../gtk/ldap.ui.h:8 +msgid "Connection" +msgstr "" + +#: ../gtk/ldap.ui.h:9 +msgid "Bind DN" +msgstr "" + +#: ../gtk/ldap.ui.h:10 +msgid "Authname" +msgstr "" + +#: ../gtk/ldap.ui.h:11 +msgid "Realm" +msgstr "" + +#: ../gtk/ldap.ui.h:12 +msgid "SASL" +msgstr "SASL" + +#: ../gtk/ldap.ui.h:13 +msgid "Base object:" +msgstr "" + +#: ../gtk/ldap.ui.h:15 +#, no-c-format +msgid "Filter (%s for name):" +msgstr "" + +#: ../gtk/ldap.ui.h:16 +msgid "Name Attribute:" +msgstr "" + +#: ../gtk/ldap.ui.h:17 +msgid "SIP address attribute:" +msgstr "" + +#: ../gtk/ldap.ui.h:18 +msgid "Attributes to query:" +msgstr "" + +#: ../gtk/ldap.ui.h:19 +msgid "Search" +msgstr "" + +#: ../gtk/ldap.ui.h:20 +msgid "Timeout for search:" +msgstr "" + +#: ../gtk/ldap.ui.h:21 +msgid "Max results:" +msgstr "" + +#: ../gtk/ldap.ui.h:22 +msgid "Follow Aliases" +msgstr "" + +#: ../gtk/ldap.ui.h:23 +msgid "Miscellaneous" +msgstr "" + +#: ../gtk/ldap.ui.h:24 +msgid "ANONYMOUS" +msgstr "" + +#: ../gtk/ldap.ui.h:25 +msgid "SIMPLE" +msgstr "" + +#: ../gtk/ldap.ui.h:26 +msgid "DIGEST-MD5" +msgstr "" + +#: ../gtk/ldap.ui.h:27 +msgid "NTLM" +msgstr "NTLM" + +#: ../gtk/login_frame.ui.h:1 ../gtk/tunnel_config.ui.h:7 +msgid "Username" +msgstr "Naudotojo vardas" + +#: ../gtk/login_frame.ui.h:2 ../gtk/tunnel_config.ui.h:8 +msgid "Password" +msgstr "Slaptažodis" + +#: ../gtk/login_frame.ui.h:3 +msgid "Internet connection:" +msgstr "Interneto ryšys:" + +#: ../gtk/login_frame.ui.h:4 +msgid "Automatically log me in" +msgstr "Prijungti mane automatiškai" + +#: ../gtk/login_frame.ui.h:5 ../gtk/password.ui.h:3 +msgid "UserID" +msgstr "Naudotojo ID" + +#: ../gtk/login_frame.ui.h:6 +msgid "Login information" +msgstr "" + +#: ../gtk/login_frame.ui.h:7 +msgid "Welcome!" +msgstr "Sveiki!" + +#: ../gtk/login_frame.ui.h:8 +msgid "ADSL" +msgstr "ADSL" + +#: ../gtk/login_frame.ui.h:9 +msgid "Fiber Channel" +msgstr "" + +#: ../gtk/log.ui.h:1 +msgid "Linphone debug window" +msgstr "Linphone derinimo langas" + +#: ../gtk/log.ui.h:2 +msgid "Scroll to end" +msgstr "Slinkti į pabaigą" + +#: ../gtk/main.ui.h:1 +msgid "Default" +msgstr "" + +#: ../gtk/main.ui.h:2 +msgid "Delete" +msgstr "Ištrinti" + +#: ../gtk/main.ui.h:3 +msgid "_Options" +msgstr "_Parinktys" + +#: ../gtk/main.ui.h:4 +msgid "Set configuration URI" +msgstr "Nustatyti konfigūracijos URI" + +#: ../gtk/main.ui.h:5 +msgid "Always start video" +msgstr "Visada pradėti vaizdą" + +#: ../gtk/main.ui.h:6 +msgid "Enable self-view" +msgstr "" + +#: ../gtk/main.ui.h:7 +msgid "Show keypad" +msgstr "Rodyti pagalbinę klaviatūrą" + +#: ../gtk/main.ui.h:8 +msgid "_Help" +msgstr "P_agalba" + +#: ../gtk/main.ui.h:9 +msgid "Show debug window" +msgstr "Rodyti derinimo langą" + +#: ../gtk/main.ui.h:10 +msgid "_Homepage" +msgstr "_Internetinė svetainė" + +#: ../gtk/main.ui.h:11 +msgid "Check _Updates" +msgstr "Tikrinti ar yra at_naujinimų" + +#: ../gtk/main.ui.h:12 +msgid "Account assistant" +msgstr "Paskyros pagelbiklis" + +#: ../gtk/main.ui.h:14 +msgid "SIP address or phone number:" +msgstr "SIP adresas arba telefono numeris:" + +#: ../gtk/main.ui.h:15 +msgid "Initiate a new call" +msgstr "Inicijuoti naują skambutį" + +#: ../gtk/main.ui.h:16 +msgid "Contacts" +msgstr "Kontaktai" + +#: ../gtk/main.ui.h:17 +msgid "Search" +msgstr "" + +#: ../gtk/main.ui.h:18 +msgid "Add contacts from directory" +msgstr "" + +#: ../gtk/main.ui.h:19 +msgid "Add contact" +msgstr "Pridėti kontaktą" + +#: ../gtk/main.ui.h:20 +msgid "Clear call history" +msgstr "Išvalyti skambučių istoriją" + +#: ../gtk/main.ui.h:22 +msgid "My current identity:" +msgstr "Mano esama tapatybė:" + +#: ../gtk/main.ui.h:23 +msgid "Autoanswer is enabled" +msgstr "Automatinis atsiliepimas yra įjungtas" + +#: ../gtk/parameters.ui.h:1 +msgid "anonymous" +msgstr "" + +#: ../gtk/parameters.ui.h:2 +msgid "GSSAPI" +msgstr "GSSAPI" + +#: ../gtk/parameters.ui.h:3 +msgid "SASL" +msgstr "SASL" + +#: ../gtk/parameters.ui.h:4 +msgid "default soundcard" +msgstr "numatytoji garso plokštė" + +#: ../gtk/parameters.ui.h:5 +msgid "a sound card" +msgstr "garso plokštė" + +#: ../gtk/parameters.ui.h:6 +msgid "default camera" +msgstr "numatytoji kamera" + +#: ../gtk/parameters.ui.h:7 +msgid "CIF" +msgstr "CIF" + +#: ../gtk/parameters.ui.h:8 +msgid "Audio codecs" +msgstr "Garso kodekai" + +#: ../gtk/parameters.ui.h:9 +msgid "Video codecs" +msgstr "Vaizdo kodekai" + +#: ../gtk/parameters.ui.h:10 +msgid "C" +msgstr "C" + +#: ../gtk/parameters.ui.h:11 +msgid "SIP (UDP)" +msgstr "SIP (UDP)" + +#: ../gtk/parameters.ui.h:12 +msgid "SIP (TCP)" +msgstr "SIP (TCP)" + +#: ../gtk/parameters.ui.h:13 +msgid "SIP (TLS)" +msgstr "SIP (TLS)" + +#: ../gtk/parameters.ui.h:14 +msgid "default" +msgstr "numatytoji" + +#: ../gtk/parameters.ui.h:15 +msgid "high-fps" +msgstr "daug kadr./s" + +#: ../gtk/parameters.ui.h:16 +msgid "custom" +msgstr "tinkinta" + +#: ../gtk/parameters.ui.h:17 +msgid "Settings" +msgstr "Nustatymai" + +#: ../gtk/parameters.ui.h:18 +msgid "This section defines your SIP address when not using a SIP account" +msgstr "" + +#: ../gtk/parameters.ui.h:19 +msgid "Your display name (eg: John Doe):" +msgstr "Jūsų rodomas vardas (pvz., Džonas Do):" + +#: ../gtk/parameters.ui.h:20 +msgid "Your username:" +msgstr "Jūsų naudotojo vardas:" + +#: ../gtk/parameters.ui.h:21 +msgid "Your resulting SIP address:" +msgstr "Jūsų galutinis SIP adresas:" + +#: ../gtk/parameters.ui.h:22 +msgid "Default identity" +msgstr "Numatytoji tapatybė" + +#: ../gtk/parameters.ui.h:23 +msgid "Wizard" +msgstr "Vediklis" + +#: ../gtk/parameters.ui.h:24 +msgid "Add" +msgstr "Pridėti" + +#: ../gtk/parameters.ui.h:25 +msgid "Edit" +msgstr "Keisti" + +#: ../gtk/parameters.ui.h:26 +msgid "Remove" +msgstr "Šalinti" + +#: ../gtk/parameters.ui.h:27 +msgid "Proxy accounts" +msgstr "Įgaliotojo serverio paskyros" + +#: ../gtk/parameters.ui.h:28 +msgid "Erase all passwords" +msgstr "Ištrinti visus slaptažodžius" + +#: ../gtk/parameters.ui.h:29 +msgid "Privacy" +msgstr "Privatumas" + +#: ../gtk/parameters.ui.h:30 +msgid "Automatically answer when a call is received" +msgstr "Automatiškai atsiliepti, kai yra gaunamas skambutis" + +#: ../gtk/parameters.ui.h:31 +msgid "Delay before answering (ms)" +msgstr "Delsa, prieš atsiliepiant (ms)" + +#: ../gtk/parameters.ui.h:32 +msgid "Auto-answer" +msgstr "Automatinis atsiliepimas" + +#: ../gtk/parameters.ui.h:33 +msgid "Manage SIP Accounts" +msgstr "Tvarkyti SIP Paskyras" + +#: ../gtk/parameters.ui.h:34 +msgid "Ring sound:" +msgstr "Skambinimo garsas:" + +#: ../gtk/parameters.ui.h:35 +msgid "ALSA special device (optional):" +msgstr "Specialus ALSA įrenginys (nebūtina):" + +#: ../gtk/parameters.ui.h:36 +msgid "Capture device:" +msgstr "Mikrofonas:" + +#: ../gtk/parameters.ui.h:37 +msgid "Ring device:" +msgstr "Skambinimo įrenginys:" + +#: ../gtk/parameters.ui.h:38 +msgid "Playback device:" +msgstr "Atkūrimo įrenginys:" + +#: ../gtk/parameters.ui.h:39 +msgid "Enable echo cancellation" +msgstr "Įjungti aido panaikinimą" + +#: ../gtk/parameters.ui.h:40 +msgid "Audio" +msgstr "Garsas" + +#: ../gtk/parameters.ui.h:41 +msgid "Video input device:" +msgstr "Vaizdo įvesties įrenginys:" + +#: ../gtk/parameters.ui.h:42 +msgid "Preferred video resolution:" +msgstr "Pageidaujama vaizdo raiška:" + +#: ../gtk/parameters.ui.h:43 +msgid "Video output method:" +msgstr "Vaizdo išvesties metodas:" + +#: ../gtk/parameters.ui.h:44 +msgid "Show camera preview" +msgstr "Rodyti kameros peržiūrą" + +#: ../gtk/parameters.ui.h:45 +msgid "Video preset:" +msgstr "Vaizdo išankstinė parinktis:" + +#: ../gtk/parameters.ui.h:46 +msgid "Preferred video framerate:" +msgstr "Pageidaujamas vaizdo kadrų dažnis:" + +#: ../gtk/parameters.ui.h:47 +msgid "0 stands for \"unlimited\"" +msgstr "0 reiškia \"neribota\"" + +#: ../gtk/parameters.ui.h:48 +msgid "Video" +msgstr "Vaizdas" + +#: ../gtk/parameters.ui.h:49 +msgid "Upload speed limit in Kbit/sec:" +msgstr "Išsiuntimo greičio riba, Kbit/sek.:" + +#: ../gtk/parameters.ui.h:50 +msgid "Download speed limit in Kbit/sec:" +msgstr "Atsiuntimo greičio riba, Kbit/sek.:" + +#: ../gtk/parameters.ui.h:51 +msgid "Enable adaptive rate control" +msgstr "Įjungti adaptyvų spartos valdymą" + +#: ../gtk/parameters.ui.h:52 +msgid "" +"Adaptive rate control is a technique to dynamically guess the available " +"bandwidth during a call." +msgstr "Adaptyvus spartos valdymas yra technika, skirta, skambučio metu, dinamiškai atspėti prieinamą pralaidumą." + +#: ../gtk/parameters.ui.h:53 +msgid "Bandwidth control" +msgstr "Pralaidumo valdymas" + +#: ../gtk/parameters.ui.h:54 +msgid "Multimedia settings" +msgstr "Multimedijos nustatymai" + +#: ../gtk/parameters.ui.h:55 +msgid "Set Maximum Transmission Unit:" +msgstr "Nustatyti didžiausią duomenų persiuntimo įtaisą:" + +#: ../gtk/parameters.ui.h:56 +msgid "Send DTMFs as SIP info" +msgstr "Siųsti DTMF kaip SIP informaciją" + +#: ../gtk/parameters.ui.h:57 +msgid "Allow IPv6" +msgstr "Leisti IPv6" + +#: ../gtk/parameters.ui.h:58 +msgid "Transport" +msgstr "Perdavimas" + +#: ../gtk/parameters.ui.h:59 +msgid "SIP/UDP port" +msgstr "SIP/UDP prievadas" + +#: ../gtk/parameters.ui.h:61 +msgid "Random" +msgstr "Atsitiktinis" + +#: ../gtk/parameters.ui.h:62 +msgid "SIP/TCP port" +msgstr "SIP/TCP prievadas" + +#: ../gtk/parameters.ui.h:63 +msgid "Audio RTP/UDP:" +msgstr "Garso RTP/UDP:" + +#: ../gtk/parameters.ui.h:64 +msgid "Fixed" +msgstr "Fiksuotas" + +#: ../gtk/parameters.ui.h:65 +msgid "Video RTP/UDP:" +msgstr "Vaizdo RTP/UDP:" + +#: ../gtk/parameters.ui.h:66 +msgid "Media encryption type" +msgstr "Medijos šifravimo tipas" + +#: ../gtk/parameters.ui.h:67 +msgid "Media encryption is mandatory" +msgstr "Medijos šifravimas yra privalomas" + +#: ../gtk/parameters.ui.h:68 +msgid "Tunnel" +msgstr "" + +#: ../gtk/parameters.ui.h:69 +msgid "DSCP fields" +msgstr "DSCP laukai" + +#: ../gtk/parameters.ui.h:70 +msgid "Network protocol and ports" +msgstr "Tinklo protokolas ir prievadai" + +#: ../gtk/parameters.ui.h:71 +msgid "Direct connection to the Internet" +msgstr "Tiesioginis sujungimas su internetu" + +#: ../gtk/parameters.ui.h:72 +msgid "Behind NAT / Firewall (specify gateway IP )" +msgstr "Už NAT / Užkardos (nurodyti tinklų sietuvo IP )" + +#: ../gtk/parameters.ui.h:73 +msgid "Behind NAT / Firewall (use STUN to resolve)" +msgstr "Už NAT / Užkardos (naudoti STUN, siekiant išspręsti)" + +#: ../gtk/parameters.ui.h:74 +msgid "Behind NAT / Firewall (use ICE)" +msgstr "Už NAT / Užkardos (naudoti ICE)" + +#: ../gtk/parameters.ui.h:75 +msgid "Behind NAT / Firewall (use uPnP)" +msgstr "Už NAT / Užkardos (naudoti uPnP)" + +#: ../gtk/parameters.ui.h:76 +msgid "Public IP address:" +msgstr "Viešas IP adresas:" + +#: ../gtk/parameters.ui.h:77 +msgid "Stun server:" +msgstr "Stun serveris:" + +#: ../gtk/parameters.ui.h:78 +msgid "NAT and Firewall" +msgstr "NAT ir Užkarda" + +#: ../gtk/parameters.ui.h:79 +msgid "Network settings" +msgstr "Tinklo nustatymai" + +#: ../gtk/parameters.ui.h:80 ../gtk/tunnel_config.ui.h:4 +msgid "Enable" +msgstr "Įjungti" + +#: ../gtk/parameters.ui.h:81 ../gtk/tunnel_config.ui.h:5 +msgid "Disable" +msgstr "Išjungti" + +#: ../gtk/parameters.ui.h:82 +msgid "Audio codecs" +msgstr "Garso kodekai" + +#: ../gtk/parameters.ui.h:83 +msgid "Video codecs" +msgstr "Vaizdo kodekai" + +#: ../gtk/parameters.ui.h:84 +msgid "Codecs" +msgstr "Kodekai" + +#: ../gtk/parameters.ui.h:85 +msgid "Language" +msgstr "Kalba" + +#: ../gtk/parameters.ui.h:86 +msgid "Show advanced settings" +msgstr "Rodyti išplėstinius nustatymus" + +#: ../gtk/parameters.ui.h:87 +msgid "Level" +msgstr "Lygmuo" + +#: ../gtk/parameters.ui.h:88 +msgid "User interface" +msgstr "Naudotojo sąsaja" + +#: ../gtk/parameters.ui.h:92 +msgid "LDAP Account setup" +msgstr "LDAP paskyros sąranka" + +#: ../gtk/parameters.ui.h:93 +msgid "LDAP" +msgstr "LDAP" + +#: ../gtk/parameters.ui.h:94 +msgid "Done" +msgstr "Atlikta" + +#: ../gtk/password.ui.h:1 +msgid "Linphone - Authentication required" +msgstr "Linphone - Reikalingas tapatybės nustatymas" + +#: ../gtk/password.ui.h:2 +msgid "Please enter the domain password" +msgstr "Prašome įvesti srities slaptažodį" + +#: ../gtk/provisioning-fetch.ui.h:1 +msgid "Configuring..." +msgstr "Konfigūruojama..." + +#: ../gtk/provisioning-fetch.ui.h:2 +msgid "Please wait while fetching configuration from server..." +msgstr "Prašome palaukti kol iš serverio yra gaunama konfigūracija..." + +#: ../gtk/setup_wizard.ui.h:1 +msgid "SIP account configuration assistant" +msgstr "SIP paskyros konfigūravimo pagelbiklis" + +#: ../gtk/setup_wizard.ui.h:2 +msgid "" +"Welcome!\n" +"This assistant will help you to use a SIP account for your calls." +msgstr "Sveiki!\nŠis pagelbiklis padės jums savo skambučiams naudoti SIP paskyrą." + +#: ../gtk/setup_wizard.ui.h:4 +msgid "Welcome to the account setup assistant" +msgstr "Sveiki atvykę į paskyros sąrankos pagelbiklį" + +#: ../gtk/setup_wizard.ui.h:5 +msgid "Create an account on linphone.org" +msgstr "Susikurti linphone.org paskyrą" + +#: ../gtk/setup_wizard.ui.h:6 +msgid "I have already a linphone.org account and I just want to use it" +msgstr "Aš jau turiu linphone.org paskyrą ir, tiesiog, noriu ją naudoti" + +#: ../gtk/setup_wizard.ui.h:7 +msgid "I have already a sip account and I just want to use it" +msgstr "Aš jau turiu sip paskyrą ir, tiesiog, noriu ją naudoti" + +#: ../gtk/setup_wizard.ui.h:8 +msgid "I want to specify a remote configuration URI" +msgstr "Aš noriu nurodyti nuotolinės konfigūracijos URI" + +#: ../gtk/setup_wizard.ui.h:9 +msgid "Account setup assistant" +msgstr "Paskyros sąrankos pagelbiklis" + +#: ../gtk/setup_wizard.ui.h:10 +msgid "Enter your account information" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:11 +msgid "Username*" +msgstr "Naudotojo vardas*" + +#: ../gtk/setup_wizard.ui.h:12 +msgid "Password*" +msgstr "Slaptažodis*" + +#: ../gtk/setup_wizard.ui.h:13 +msgid "Domain*" +msgstr "Sritis*" + +#: ../gtk/setup_wizard.ui.h:14 +msgid "Proxy" +msgstr "Įgaliotasis serveris" + +#: ../gtk/setup_wizard.ui.h:15 +msgid "Configure your account (step 1/1)" +msgstr "Konfigūruokite savo paskyrą (žingsnis 1/1)" + +#: ../gtk/setup_wizard.ui.h:16 +msgid "Enter your linphone.org username" +msgstr "Įveskite savo linphone.org naudotojo vardą" + +#: ../gtk/setup_wizard.ui.h:19 +msgid "Enter your sip username (step 1/1)" +msgstr "Įveskite savo sip paskyros naudotojo vardą (žingsnis 1/1)" + +#: ../gtk/setup_wizard.ui.h:20 +msgid "(*) Required fields" +msgstr "(*) Būtini laukai" + +#: ../gtk/setup_wizard.ui.h:21 +msgid "Email: (*)" +msgstr "El. paštas: (*)" + +#: ../gtk/setup_wizard.ui.h:22 +msgid "Username: (*)" +msgstr "Naudotojo vardas: (*)" + +#: ../gtk/setup_wizard.ui.h:23 +msgid "Password: (*)" +msgstr "Slaptažodis: (*)" + +#: ../gtk/setup_wizard.ui.h:24 +msgid "Confirm your password: (*)" +msgstr "Patvirtinkite savo slaptažodį: (*)" + +#: ../gtk/setup_wizard.ui.h:25 +msgid "Keep me informed with linphone updates" +msgstr "Informuokite mane apie linphone atnaujinimus" + +#: ../gtk/setup_wizard.ui.h:26 +msgid "Enter account information (step 1/2)" +msgstr "Įveskite paskyros informaciją (žingsnis 1/2)" + +#: ../gtk/setup_wizard.ui.h:27 +msgid "Your account is being created, please wait." +msgstr "Jūsų paskyra yra kuriama, prašome palaukti." + +#: ../gtk/setup_wizard.ui.h:28 +msgid "Account creation in progress" +msgstr "Paskyra kūrimo eigoje" + +#: ../gtk/setup_wizard.ui.h:29 +msgid "" +"Please validate your account by clicking on the link we just sent you by email.\n" +"Then come back here and press Next button." +msgstr "Prašome patvirtinti savo paskyrą, nuspaudžiant nuorodą, kurią ką tik atsiuntėme jums el. paštu.\nTuomet grįžkite čia ir spauskite mygtuką Pirmyn." + +#: ../gtk/setup_wizard.ui.h:31 +msgid "Validation (step 2/2)" +msgstr "Patvirtinimas (žingsnis 2/2)" + +#: ../gtk/setup_wizard.ui.h:32 +msgid "Checking if your account is been validated, please wait." +msgstr "Tikrinama ar jūsų paskyra buvo patvirtinta, prašome palaukti." + +#: ../gtk/setup_wizard.ui.h:33 +msgid "Account validation check in progress" +msgstr "Pakyros patvirtinimo patikrinimas eigoje" + +#: ../gtk/setup_wizard.ui.h:34 +msgid "" +"Error, account not validated, username already used or server unreachable.\n" +"Please go back and try again." +msgstr "Klaida, paskyra nepatvirtinta, naudotojo vardas jau yra naudojamas arba serveris nepasiekiamas.\nPrašome grįžti atgal ir bandyti dar kartą." + +#: ../gtk/setup_wizard.ui.h:36 +msgid "Error" +msgstr "Klaida" + +#: ../gtk/setup_wizard.ui.h:37 +msgid "Thank you. Your account is now configured and ready for use." +msgstr "Dėkojame. Jūsų paskyra yra sukonfigūruota ir paruošta naudoti." + +#: ../gtk/sip_account.ui.h:1 +msgid "Linphone - Configure a SIP account" +msgstr "Linphone - SIP paskyros konfigūravimas" + +#: ../gtk/sip_account.ui.h:2 +msgid "Your SIP identity:" +msgstr "Jūsų SIP tapatybė:" + +#: ../gtk/sip_account.ui.h:3 +msgid "Looks like sip:@" +msgstr "Atrodo taip sip:@" + +#: ../gtk/sip_account.ui.h:4 +msgid "sip:" +msgstr "sip:" + +#: ../gtk/sip_account.ui.h:5 +msgid "SIP Proxy address:" +msgstr "SIP Įgaliotojo serverio adresas:" + +#: ../gtk/sip_account.ui.h:6 +msgid "Looks like sip:" +msgstr "" + +#: ../gtk/sip_account.ui.h:7 +msgid "Registration duration (sec):" +msgstr "Registravimo trukmė (sek.):" + +#: ../gtk/sip_account.ui.h:8 +msgid "Contact params (optional):" +msgstr "Kontakto parametrai (nebūtinai):" + +#: ../gtk/sip_account.ui.h:9 +msgid "AVPF regular RTCP interval (sec):" +msgstr "AVPF reguliarus RTCP intervalas (sek.):" + +#: ../gtk/sip_account.ui.h:10 +msgid "Route (optional):" +msgstr "Maršrutas (nebūtinai):" + +#: ../gtk/sip_account.ui.h:11 +msgid "Transport" +msgstr "Perdavimas" + +#: ../gtk/sip_account.ui.h:12 +msgid "Register" +msgstr "Registruoti" + +#: ../gtk/sip_account.ui.h:13 +msgid "Publish presence information" +msgstr "Skelbti prisijungimo būsenos informaciją" + +#: ../gtk/sip_account.ui.h:14 +msgid "Enable AVPF" +msgstr "Įjungti AVPF" + +#: ../gtk/sip_account.ui.h:15 +msgid "Configure a SIP account" +msgstr "Konfigūruokite SIP paskyrą" + +#: ../gtk/tunnel_config.ui.h:1 +msgid "Configure VoIP tunnel" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:2 +msgid "Host" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:3 +msgid "Port" +msgstr "Prievadas" + +#: ../gtk/tunnel_config.ui.h:6 +msgid "Configure tunnel" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:9 +msgid "Configure http proxy (optional)" +msgstr "" + +#: ../gtk/waiting.ui.h:2 +msgid "Please wait" +msgstr "Prašome palaukti" + +#: ../coreapi/linphonecore.c:1560 +msgid "Ready" +msgstr "Pasiruošę" + +#: ../coreapi/linphonecore.c:2556 +msgid "Configuring" +msgstr "" + +#. must be known at that time +#: ../coreapi/linphonecore.c:2951 +msgid "Contacting" +msgstr "" + +#: ../coreapi/linphonecore.c:2956 +msgid "Could not call" +msgstr "" + +#: ../coreapi/linphonecore.c:3092 +msgid "Sorry, we have reached the maximum number of simultaneous calls" +msgstr "" + +#: ../coreapi/linphonecore.c:3250 +msgid "is contacting you" +msgstr "bando su jumis susisiekti" + +#: ../coreapi/linphonecore.c:3251 +msgid " and asked autoanswer." +msgstr "" + +#: ../coreapi/linphonecore.c:3377 +msgid "Modifying call parameters..." +msgstr "Modifikuojami skambučio parametrai..." + +#: ../coreapi/linphonecore.c:3769 +msgid "Connected." +msgstr "Prisijungta." + +#: ../coreapi/linphonecore.c:3794 +msgid "Call aborted" +msgstr "Skambutis nutrauktas" + +#: ../coreapi/linphonecore.c:3983 +msgid "Could not pause the call" +msgstr "Nepavyko pristabdyti skambučio" + +#: ../coreapi/linphonecore.c:3986 +msgid "Pausing the current call..." +msgstr "Pristabdomas esamas skambutis..." + +#: ../coreapi/misc.c:440 +msgid "Stun lookup in progress..." +msgstr "" + +#: ../coreapi/misc.c:650 +msgid "ICE local candidates gathering in progress..." +msgstr "" + +#: ../coreapi/friend.c:33 +msgid "Online" +msgstr "Prisijungęs" + +#: ../coreapi/friend.c:36 +msgid "Busy" +msgstr "Užimtas" + +#: ../coreapi/friend.c:39 +msgid "Be right back" +msgstr "Netrukus sugrįš" + +#: ../coreapi/friend.c:42 +msgid "Away" +msgstr "Pasišalinęs" + +#: ../coreapi/friend.c:45 +msgid "On the phone" +msgstr "Kalba telefonu" + +#: ../coreapi/friend.c:48 +msgid "Out to lunch" +msgstr "Pietauja" + +#: ../coreapi/friend.c:51 +msgid "Do not disturb" +msgstr "Netrukdyti" + +#: ../coreapi/friend.c:54 +msgid "Moved" +msgstr "Perkeltas" + +#: ../coreapi/friend.c:57 +msgid "Using another messaging service" +msgstr "Naudoja kitą pokalbių tarnybą" + +#: ../coreapi/friend.c:60 +msgid "Offline" +msgstr "Atsijungęs" + +#: ../coreapi/friend.c:63 +msgid "Pending" +msgstr "" + +#: ../coreapi/friend.c:66 +msgid "Vacation" +msgstr "" + +#: ../coreapi/friend.c:68 +msgid "Unknown status" +msgstr "Nežinoma būsena" + +#: ../coreapi/proxy.c:292 +msgid "" +"The sip proxy address you entered is invalid, it must start with \"sip:\" " +"followed by a hostname." +msgstr "" + +#: ../coreapi/proxy.c:298 +msgid "" +"The sip identity you entered is invalid.\n" +"It should look like sip:username@proxydomain, such as sip:alice@example.net" +msgstr "jūsų įvesta sip tapatybė yra neteisinga.\nJi turėtų atrodyti taip sip:naudotojovardas@įgaliotojoserveriosritis, kaip, pavyzdžiui, sip:alice@example.net" + +#: ../coreapi/proxy.c:927 +msgid "Looking for telephone number destination..." +msgstr "" + +#: ../coreapi/proxy.c:931 +msgid "Could not resolve this number." +msgstr "" + +#: ../coreapi/proxy.c:1324 +#, c-format +msgid "Could not login as %s" +msgstr "Nepavyko prisijungti kaip %s" + +#: ../coreapi/proxy.c:1411 +#, c-format +msgid "Refreshing on %s..." +msgstr "" + +#: ../coreapi/callbacks.c:423 +msgid "Remote ringing." +msgstr "" + +#: ../coreapi/callbacks.c:435 +msgid "Remote ringing..." +msgstr "" + +#: ../coreapi/callbacks.c:458 +msgid "Early media." +msgstr "" + +#: ../coreapi/callbacks.c:488 +#, c-format +msgid "Call answered by %s" +msgstr "%s atsiliepė į skambutį" + +#: ../coreapi/callbacks.c:527 +msgid "Call resumed." +msgstr "Skambutis pratęstas." + +#: ../coreapi/callbacks.c:582 +msgid "Incompatible, check codecs or security settings..." +msgstr "Nesuderinama, patikrinkite kodekus ar saugos nustatymus..." + +#: ../coreapi/callbacks.c:587 ../coreapi/callbacks.c:923 +msgid "Incompatible media parameters." +msgstr "Nesuderinami medijos parametrai." + +#: ../coreapi/callbacks.c:612 +msgid "We have been resumed." +msgstr "Mūsų skambutis yra pratęstas." + +#. we are being paused +#: ../coreapi/callbacks.c:620 +msgid "We are paused by other party." +msgstr "Kita šalis pristabdė skambutį." + +#: ../coreapi/callbacks.c:630 +msgid "Call is updated by remote." +msgstr "" + +#: ../coreapi/callbacks.c:799 +msgid "Call terminated." +msgstr "Skambutis baigtas." + +#: ../coreapi/callbacks.c:827 +msgid "User is busy." +msgstr "Naudotojas yra užimtas." + +#: ../coreapi/callbacks.c:828 +msgid "User is temporarily unavailable." +msgstr "Naudotojas laikinai neprieinamas." + +#. char *retrymsg=_("%s. Retry after %i minute(s)."); +#: ../coreapi/callbacks.c:830 +msgid "User does not want to be disturbed." +msgstr "Naudotojas nenori būti trukdomas." + +#: ../coreapi/callbacks.c:831 +msgid "Call declined." +msgstr "Skambutis atmestas." + +#: ../coreapi/callbacks.c:846 +msgid "Request timeout." +msgstr "Baigėsi užklausos laikas." + +#: ../coreapi/callbacks.c:877 +msgid "Redirected" +msgstr "" + +#: ../coreapi/callbacks.c:927 +msgid "Call failed." +msgstr "Skambutis nepavyko." + +#: ../coreapi/callbacks.c:1005 +#, c-format +msgid "Registration on %s successful." +msgstr "" + +#: ../coreapi/callbacks.c:1006 +#, c-format +msgid "Unregistration on %s done." +msgstr "" + +#: ../coreapi/callbacks.c:1024 +msgid "no response timeout" +msgstr "" + +#: ../coreapi/callbacks.c:1027 +#, c-format +msgid "Registration on %s failed: %s" +msgstr "" + +#: ../coreapi/callbacks.c:1034 +msgid "Service unavailable, retrying" +msgstr "Paslauga neprieinama, bandoma iš naujo" + +#. if encryption is DTLS, no status to be displayed +#: ../coreapi/linphonecall.c:197 +#, c-format +msgid "Authentication token is %s" +msgstr "" + +#: ../coreapi/linphonecall.c:1561 +#, c-format +msgid "Call parameters could not be modified: %s." +msgstr "Nepavyko modifikuoti skambučio parametrų: %s." + +#: ../coreapi/linphonecall.c:1563 +msgid "Call parameters were successfully modified." +msgstr "Skambučio parametrai buvo sėkmingai modifikuoti." + +#: ../coreapi/linphonecall.c:4396 +#, c-format +msgid "You have missed %i call." +msgid_plural "You have missed %i calls." +msgstr[0] "Jūs turite %i praleistą skambutį." +msgstr[1] "Jūs turite %i praleistus skambučius." +msgstr[2] "Jūs turite %i praleistų skambučių." + +#: ../coreapi/call_log.c:223 +msgid "aborted" +msgstr "" + +#: ../coreapi/call_log.c:226 +msgid "completed" +msgstr "" + +#: ../coreapi/call_log.c:229 +msgid "missed" +msgstr "" + +#: ../coreapi/call_log.c:232 +msgid "unknown" +msgstr "nežinoma" + +#: ../coreapi/call_log.c:234 +#, c-format +msgid "" +"%s at %s\n" +"From: %s\n" +"To: %s\n" +"Status: %s\n" +"Duration: %i mn %i sec\n" +msgstr "" + +#: ../coreapi/call_log.c:235 +msgid "Outgoing call" +msgstr "" + +#: ../gtk/videowindow.c:66 +#, c-format +msgid "Cannot play %s." +msgstr "Nepavyksta groti %s." diff --git a/po/nb_NO.po b/po/nb_NO.po index 0d6edd4df..e87247434 100644 --- a/po/nb_NO.po +++ b/po/nb_NO.po @@ -8,74 +8,83 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-04-30 10:13+0200\n" -"PO-Revision-Date: 2015-04-30 08:13+0000\n" +"POT-Creation-Date: 2015-11-10 15:16+0100\n" +"PO-Revision-Date: 2015-11-10 14:16+0000\n" "Last-Translator: Belledonne Communications \n" -"Language-Team: Norwegian Bokmål (Norway) (http://www.transifex.com/projects/p/linphone-gtk/language/nb_NO/)\n" +"Language-Team: Norwegian Bokmål (Norway) (http://www.transifex.com/belledonne-communications/linphone-gtk/language/nb_NO/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: nb_NO\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ../gtk/calllogs.c:148 ../gtk/friendlist.c:974 +#: ../gtk/calllogs.c:178 #, c-format msgid "Call %s" msgstr "Ring %s" -#: ../gtk/calllogs.c:149 ../gtk/friendlist.c:975 +#: ../gtk/calllogs.c:179 #, c-format msgid "Send text to %s" msgstr "Send tekst til %s" -#: ../gtk/calllogs.c:232 +#: ../gtk/calllogs.c:181 +#, c-format +msgid "Add %s to your contact list" +msgstr "" + +#: ../gtk/calllogs.c:245 ../gtk/main.ui.h:21 +msgid "Recent calls" +msgstr "" + +#: ../gtk/calllogs.c:260 #, c-format msgid "Recent calls (%i)" msgstr "" -#: ../gtk/calllogs.c:314 +#: ../gtk/calllogs.c:331 msgid "n/a" msgstr "" -#: ../gtk/calllogs.c:317 +#: ../gtk/calllogs.c:334 msgid "Aborted" msgstr "" -#: ../gtk/calllogs.c:320 +#: ../gtk/calllogs.c:337 msgid "Missed" msgstr "" -#: ../gtk/calllogs.c:323 +#: ../gtk/calllogs.c:340 msgid "Declined" msgstr "" -#: ../gtk/calllogs.c:329 +#: ../gtk/calllogs.c:346 #, c-format msgid "%i minute" msgid_plural "%i minutes" msgstr[0] "" msgstr[1] "" -#: ../gtk/calllogs.c:332 +#: ../gtk/calllogs.c:349 #, c-format msgid "%i second" msgid_plural "%i seconds" msgstr[0] "" msgstr[1] "" -#: ../gtk/calllogs.c:337 +#: ../gtk/calllogs.c:354 #, c-format msgid "" "%s\tQuality: %s\n" "%s\t%s\t" msgstr "" -#: ../gtk/calllogs.c:341 +#: ../gtk/calllogs.c:358 #, c-format msgid "%s\t%s" msgstr "" -#: ../gtk/conference.c:38 ../gtk/main.ui.h:13 +#: ../gtk/conference.c:38 ../gtk/in_call_frame.ui.h:11 msgid "Conference" msgstr "" @@ -88,297 +97,314 @@ msgstr "" msgid "Couldn't find pixmap file: %s" msgstr "Fant ikke pixmap fli: %s" -#: ../gtk/main.c:137 +#: ../gtk/chat.c:196 ../gtk/chat.c:254 +msgid "Sending..." +msgstr "" + +#: ../gtk/chat.c:213 ../gtk/chat.c:263 +msgid "Message not sent" +msgstr "" + +#: ../gtk/chat.c:472 +msgid "Copy" +msgstr "" + +#: ../gtk/main.c:138 msgid "log to stdout some debug information while running." msgstr "skriv logg-informasjon under kjøring" -#: ../gtk/main.c:138 -msgid "path to a file to write logs into." -msgstr "" - #: ../gtk/main.c:139 -msgid "Start linphone with video disabled." +msgid "display version and exit." msgstr "" #: ../gtk/main.c:140 +msgid "path to a file to write logs into." +msgstr "" + +#: ../gtk/main.c:141 +msgid "Start linphone with video disabled." +msgstr "" + +#: ../gtk/main.c:142 msgid "Start only in the system tray, do not show the main interface." msgstr "Start skjult i systemkurven, ikke vis programbildet." -#: ../gtk/main.c:141 +#: ../gtk/main.c:143 msgid "address to call right now" msgstr "address som skal ringes nå" -#: ../gtk/main.c:142 +#: ../gtk/main.c:144 msgid "" "Specifiy a working directory (should be the base of the installation, eg: " "c:\\Program Files\\Linphone)" msgstr "Spesifiser arbeidsmappe (bør være base for installasjonen, f.eks: c:\\Programfiler\\Linphone)" -#: ../gtk/main.c:143 +#: ../gtk/main.c:145 msgid "Configuration file" msgstr "" -#: ../gtk/main.c:144 +#: ../gtk/main.c:146 msgid "Run the audio assistant" msgstr "" -#: ../gtk/main.c:145 +#: ../gtk/main.c:147 msgid "Run self test and exit 0 if succeed" msgstr "" -#: ../gtk/main.c:1070 +#: ../gtk/main.c:1046 #, c-format msgid "" -"%s would like to add you to his contact list.\n" -"Would you allow him to see your presence status or add him to your contact list ?\n" +"%s would like to add you to his/her contact list.\n" +"Would you add him/her to your contact list and allow him/her to see your presence status?\n" "If you answer no, this person will be temporarily blacklisted." -msgstr "%s vil legge deg til i hans/hennes kontaktliste.\nVil du tillate vedkommende å se din tilstedestatus eller legge vedkommende i din kontaktliste?\nHvis du svarer nei vil personen bli svartelyst midlertidig." +msgstr "" -#: ../gtk/main.c:1147 +#: ../gtk/main.c:1123 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" msgstr "" -#: ../gtk/main.c:1268 +#: ../gtk/main.c:1253 msgid "Call error" msgstr "" -#: ../gtk/main.c:1271 ../coreapi/linphonecore.c:3846 +#: ../gtk/main.c:1256 ../coreapi/linphonecore.c:3813 msgid "Call ended" msgstr "Samtale avsluttet" -#: ../gtk/main.c:1274 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1259 ../coreapi/call_log.c:235 msgid "Incoming call" msgstr "Innkommende samtale" -#: ../gtk/main.c:1276 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1261 ../gtk/incall_view.c:580 ../gtk/in_call_frame.ui.h:2 msgid "Answer" msgstr "Svarer" -#: ../gtk/main.c:1278 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1263 ../gtk/in_call_frame.ui.h:3 msgid "Decline" msgstr "Avvis" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 msgid "Call paused" msgstr "" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 #, c-format msgid "by %s" msgstr "" -#: ../gtk/main.c:1354 +#: ../gtk/main.c:1339 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "" -#: ../gtk/main.c:1509 +#: ../gtk/main.c:1505 msgid "Website link" msgstr "Peker til nettsted" -#: ../gtk/main.c:1568 ../gtk/waiting.ui.h:1 +#: ../gtk/main.c:1564 ../gtk/waiting.ui.h:1 msgid "Linphone" msgstr "Linphone" -#: ../gtk/main.c:1569 +#: ../gtk/main.c:1565 msgid "A video internet phone" msgstr "" -#: ../gtk/main.c:1629 +#: ../gtk/main.c:1624 #, c-format msgid "%s (Default)" msgstr "%s (Standard)" -#: ../gtk/main.c:1962 ../coreapi/callbacks.c:1063 +#: ../gtk/main.c:1960 ../coreapi/callbacks.c:1075 #, c-format msgid "We are transferred to %s" msgstr "Vi er overført til %s" -#: ../gtk/main.c:1972 +#: ../gtk/main.c:1970 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." msgstr "Klarte ikke å finne noe lydkort på denne datamaskinen.\nDu vil ikke kunne sende eller motta lydsamtaler." -#: ../gtk/main.c:2117 +#: ../gtk/main.c:2129 msgid "A free SIP video-phone" msgstr "En gratis SIP video-telefon" -#: ../gtk/main.c:2221 +#: ../gtk/main.c:2242 #, c-format msgid "Hello\n" msgstr "" -#: ../gtk/friendlist.c:505 +#: ../gtk/friendlist.c:461 msgid "Add to addressbook" msgstr "" -#: ../gtk/friendlist.c:691 -msgid "Presence status" -msgstr "Tilstedestatus" - -#: ../gtk/friendlist.c:709 ../gtk/propertybox.c:569 ../gtk/contact.ui.h:1 -msgid "Name" -msgstr "Navn" - -#: ../gtk/friendlist.c:721 -msgid "Call" -msgstr "" - -#: ../gtk/friendlist.c:726 -msgid "Chat" -msgstr "" - -#: ../gtk/friendlist.c:756 +#: ../gtk/friendlist.c:627 #, c-format msgid "Search in %s directory" msgstr "Søk i %s katalogen" -#: ../gtk/friendlist.c:924 +#: ../gtk/friendlist.c:772 msgid "Invalid sip contact !" msgstr "Ugyldig SIP kontakt !" -#: ../gtk/friendlist.c:976 +#: ../gtk/friendlist.c:820 +#, c-format +msgid "Add a new contact" +msgstr "" + +#: ../gtk/friendlist.c:823 #, c-format msgid "Edit contact '%s'" msgstr "Rediger kontakt '%s'" -#: ../gtk/friendlist.c:977 +#: ../gtk/friendlist.c:824 #, c-format msgid "Delete contact '%s'" msgstr "Slett kontakt '%s'" -#: ../gtk/friendlist.c:978 +#: ../gtk/friendlist.c:825 #, c-format msgid "Delete chat history of '%s'" msgstr "" -#: ../gtk/friendlist.c:1029 +#: ../gtk/friendlist.c:862 #, c-format msgid "Add new contact from %s directory" msgstr "Legg til kontakt fra %s katalogen" -#: ../gtk/propertybox.c:575 +#: ../gtk/propertybox.c:592 ../gtk/contact.ui.h:1 +msgid "Name" +msgstr "Navn" + +#: ../gtk/propertybox.c:598 msgid "Rate (Hz)" msgstr "Frekvens (Hz)" -#: ../gtk/propertybox.c:581 +#: ../gtk/propertybox.c:604 msgid "Status" msgstr "Status" -#: ../gtk/propertybox.c:587 +#: ../gtk/propertybox.c:617 msgid "IP Bitrate (kbit/s)" msgstr "" -#: ../gtk/propertybox.c:596 +#: ../gtk/propertybox.c:628 msgid "Parameters" msgstr "Parametere" -#: ../gtk/propertybox.c:639 ../gtk/propertybox.c:782 +#: ../gtk/propertybox.c:670 ../gtk/propertybox.c:824 msgid "Enabled" msgstr "På" -#: ../gtk/propertybox.c:641 ../gtk/propertybox.c:782 ../gtk/parameters.ui.h:20 +#: ../gtk/propertybox.c:672 ../gtk/propertybox.c:824 ../gtk/parameters.ui.h:60 msgid "Disabled" msgstr "Av" -#: ../gtk/propertybox.c:828 +#: ../gtk/propertybox.c:902 msgid "Account" msgstr "Konto" -#: ../gtk/propertybox.c:1091 +#: ../gtk/propertybox.c:1170 msgid "English" msgstr "Engelsk" -#: ../gtk/propertybox.c:1092 +#: ../gtk/propertybox.c:1171 msgid "French" msgstr "Fransk" -#: ../gtk/propertybox.c:1093 +#: ../gtk/propertybox.c:1172 msgid "Swedish" msgstr "Svensk" -#: ../gtk/propertybox.c:1094 +#: ../gtk/propertybox.c:1173 msgid "Italian" msgstr "Italisensk" -#: ../gtk/propertybox.c:1095 +#: ../gtk/propertybox.c:1174 msgid "Spanish" msgstr "Spansk" -#: ../gtk/propertybox.c:1096 +#: ../gtk/propertybox.c:1175 msgid "Brazilian Portugese" msgstr "Portugisisk" -#: ../gtk/propertybox.c:1097 +#: ../gtk/propertybox.c:1176 msgid "Polish" msgstr "Polsk" -#: ../gtk/propertybox.c:1098 +#: ../gtk/propertybox.c:1177 msgid "German" msgstr "Tysk" -#: ../gtk/propertybox.c:1099 +#: ../gtk/propertybox.c:1178 msgid "Russian" msgstr "Russisk" -#: ../gtk/propertybox.c:1100 +#: ../gtk/propertybox.c:1179 msgid "Japanese" msgstr "Japansk" -#: ../gtk/propertybox.c:1101 +#: ../gtk/propertybox.c:1180 msgid "Dutch" msgstr "Nederlandsk" -#: ../gtk/propertybox.c:1102 +#: ../gtk/propertybox.c:1181 msgid "Hungarian" msgstr "Ungarsk" -#: ../gtk/propertybox.c:1103 +#: ../gtk/propertybox.c:1182 msgid "Czech" msgstr "Tjekkisk" -#: ../gtk/propertybox.c:1104 +#: ../gtk/propertybox.c:1183 msgid "Chinese" msgstr "Kinesisk" -#: ../gtk/propertybox.c:1105 +#: ../gtk/propertybox.c:1184 msgid "Traditional Chinese" msgstr "" -#: ../gtk/propertybox.c:1106 +#: ../gtk/propertybox.c:1185 msgid "Norwegian" msgstr "" -#: ../gtk/propertybox.c:1107 +#: ../gtk/propertybox.c:1186 msgid "Hebrew" msgstr "" -#: ../gtk/propertybox.c:1108 +#: ../gtk/propertybox.c:1187 msgid "Serbian" msgstr "" -#: ../gtk/propertybox.c:1175 +#: ../gtk/propertybox.c:1188 +msgid "Arabic" +msgstr "" + +#: ../gtk/propertybox.c:1189 +msgid "Turkish" +msgstr "" + +#: ../gtk/propertybox.c:1246 msgid "" "You need to restart linphone for the new language selection to take effect." msgstr "Du må restarte linphone for at det nye språkvalget skal iverksettes." -#: ../gtk/propertybox.c:1255 +#: ../gtk/propertybox.c:1326 msgid "None" msgstr "" -#: ../gtk/propertybox.c:1259 +#: ../gtk/propertybox.c:1330 msgid "SRTP" msgstr "" -#: ../gtk/propertybox.c:1265 +#: ../gtk/propertybox.c:1336 msgid "DTLS" msgstr "" -#: ../gtk/propertybox.c:1272 +#: ../gtk/propertybox.c:1343 msgid "ZRTP" msgstr "" @@ -420,324 +446,195 @@ msgid_plural "Found %i contacts" msgstr[0] "Fant kontakt %i" msgstr[1] "Hittat kontakt %i" -#: ../gtk/setupwizard.c:32 -msgid "" -"Welcome!\n" -"This assistant will help you to use a SIP account for your calls." -msgstr "" - -#: ../gtk/setupwizard.c:41 -msgid "Create an account on linphone.org" -msgstr "" - -#: ../gtk/setupwizard.c:42 -msgid "I have already a linphone.org account and I just want to use it" -msgstr "" - -#: ../gtk/setupwizard.c:43 -msgid "I have already a sip account and I just want to use it" -msgstr "" - -#: ../gtk/setupwizard.c:44 -msgid "I want to specify a remote configuration URI" -msgstr "" - -#: ../gtk/setupwizard.c:87 -msgid "Enter your linphone.org username" -msgstr "" - -#: ../gtk/setupwizard.c:100 ../gtk/parameters.ui.h:85 ../gtk/ldap.ui.h:4 -msgid "Username:" -msgstr "Brukernavn:" - -#: ../gtk/setupwizard.c:102 ../gtk/password.ui.h:4 ../gtk/ldap.ui.h:5 -msgid "Password:" -msgstr "Passord:" - -#: ../gtk/setupwizard.c:122 -msgid "Enter your account informations" -msgstr "" - -#: ../gtk/setupwizard.c:138 -msgid "Username*" -msgstr "" - -#: ../gtk/setupwizard.c:139 -msgid "Password*" -msgstr "" - -#: ../gtk/setupwizard.c:142 -msgid "Domain*" -msgstr "" - -#: ../gtk/setupwizard.c:143 -msgid "Proxy" -msgstr "" - -#: ../gtk/setupwizard.c:322 -msgid "(*) Required fields" -msgstr "" - -#: ../gtk/setupwizard.c:323 -msgid "Username: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:325 -msgid "Password: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:327 -msgid "Email: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:329 -msgid "Confirm your password: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:343 -msgid "Keep me informed with linphone updates" -msgstr "" - -#: ../gtk/setupwizard.c:399 -msgid "" -"Error, account not validated, username already used or server unreachable.\n" -"Please go back and try again." -msgstr "" - -#: ../gtk/setupwizard.c:410 -msgid "Thank you. Your account is now configured and ready for use." -msgstr "Takk. Ditt konto er nå satt opp og klart til bruk." - -#: ../gtk/setupwizard.c:418 -msgid "" -"Please validate your account by clicking on the link we just sent you by email.\n" -"Then come back here and press Next button." -msgstr "" - -#: ../gtk/setupwizard.c:609 -msgid "SIP account configuration assistant" -msgstr "" - -#: ../gtk/setupwizard.c:629 -msgid "Welcome to the account setup assistant" -msgstr "Velkommen til brukerkontoveiviseren" - -#: ../gtk/setupwizard.c:634 -msgid "Account setup assistant" -msgstr "Brukerkontoveiviser" - -#: ../gtk/setupwizard.c:640 -msgid "Configure your account (step 1/1)" -msgstr "" - -#: ../gtk/setupwizard.c:645 -msgid "Enter your sip username (step 1/1)" -msgstr "" - -#: ../gtk/setupwizard.c:649 -msgid "Enter account information (step 1/2)" -msgstr "" - -#: ../gtk/setupwizard.c:658 -msgid "Validation (step 2/2)" -msgstr "" - -#: ../gtk/setupwizard.c:663 -msgid "Error" -msgstr "" - -#: ../gtk/setupwizard.c:667 ../gtk/audio_assistant.c:534 -msgid "Terminating" -msgstr "" - -#: ../gtk/incall_view.c:70 ../gtk/incall_view.c:94 +#: ../gtk/incall_view.c:67 ../gtk/incall_view.c:87 #, c-format msgid "Call #%i" msgstr "" -#: ../gtk/incall_view.c:155 +#: ../gtk/incall_view.c:145 #, c-format msgid "Transfer to call #%i with %s" msgstr "" -#: ../gtk/incall_view.c:211 ../gtk/incall_view.c:214 +#: ../gtk/incall_view.c:202 ../gtk/incall_view.c:205 msgid "Not used" msgstr "" -#: ../gtk/incall_view.c:221 +#: ../gtk/incall_view.c:212 msgid "ICE not activated" msgstr "" -#: ../gtk/incall_view.c:223 +#: ../gtk/incall_view.c:214 msgid "ICE failed" msgstr "" -#: ../gtk/incall_view.c:225 +#: ../gtk/incall_view.c:216 msgid "ICE in progress" msgstr "" -#: ../gtk/incall_view.c:227 +#: ../gtk/incall_view.c:218 msgid "Going through one or more NATs" msgstr "" -#: ../gtk/incall_view.c:229 +#: ../gtk/incall_view.c:220 msgid "Direct" msgstr "" -#: ../gtk/incall_view.c:231 +#: ../gtk/incall_view.c:222 msgid "Through a relay server" msgstr "" -#: ../gtk/incall_view.c:239 +#: ../gtk/incall_view.c:230 msgid "uPnP not activated" msgstr "" -#: ../gtk/incall_view.c:241 +#: ../gtk/incall_view.c:232 msgid "uPnP in progress" msgstr "" -#: ../gtk/incall_view.c:243 +#: ../gtk/incall_view.c:234 msgid "uPnp not available" msgstr "" -#: ../gtk/incall_view.c:245 +#: ../gtk/incall_view.c:236 msgid "uPnP is running" msgstr "" -#: ../gtk/incall_view.c:247 +#: ../gtk/incall_view.c:238 msgid "uPnP failed" msgstr "" -#: ../gtk/incall_view.c:257 ../gtk/incall_view.c:258 +#: ../gtk/incall_view.c:248 ../gtk/incall_view.c:249 msgid "Direct or through server" msgstr "" -#: ../gtk/incall_view.c:267 ../gtk/incall_view.c:279 +#: ../gtk/incall_view.c:258 ../gtk/incall_view.c:270 #, c-format msgid "" "download: %f\n" "upload: %f (kbit/s)" msgstr "" -#: ../gtk/incall_view.c:272 ../gtk/incall_view.c:274 +#: ../gtk/incall_view.c:263 ../gtk/incall_view.c:265 #, c-format msgid "%ix%i @ %f fps" msgstr "" -#: ../gtk/incall_view.c:304 +#: ../gtk/incall_view.c:295 #, c-format msgid "%.3f seconds" msgstr "" -#: ../gtk/incall_view.c:407 ../gtk/main.ui.h:12 ../gtk/videowindow.c:235 +#: ../gtk/incall_view.c:453 ../gtk/in_call_frame.ui.h:10 +#: ../gtk/videowindow.c:236 msgid "Hang up" msgstr "" -#: ../gtk/incall_view.c:511 +#: ../gtk/incall_view.c:559 msgid "Calling..." msgstr "Ringer..." -#: ../gtk/incall_view.c:514 ../gtk/incall_view.c:733 -msgid "00::00::00" -msgstr "00:00:00" +#: ../gtk/incall_view.c:562 ../gtk/incall_view.c:792 +msgid "00:00:00" +msgstr "" -#: ../gtk/incall_view.c:525 +#: ../gtk/incall_view.c:573 msgid "Incoming call" msgstr "Innkommende samtale" -#: ../gtk/incall_view.c:562 +#: ../gtk/incall_view.c:610 msgid "good" msgstr "" -#: ../gtk/incall_view.c:564 +#: ../gtk/incall_view.c:612 msgid "average" msgstr "" -#: ../gtk/incall_view.c:566 +#: ../gtk/incall_view.c:614 msgid "poor" msgstr "" -#: ../gtk/incall_view.c:568 +#: ../gtk/incall_view.c:616 msgid "very poor" msgstr "" -#: ../gtk/incall_view.c:570 +#: ../gtk/incall_view.c:618 msgid "too bad" msgstr "" -#: ../gtk/incall_view.c:571 ../gtk/incall_view.c:587 +#: ../gtk/incall_view.c:619 ../gtk/incall_view.c:635 msgid "unavailable" msgstr "" -#: ../gtk/incall_view.c:679 +#: ../gtk/incall_view.c:731 msgid "Secured by SRTP" msgstr "" -#: ../gtk/incall_view.c:685 +#: ../gtk/incall_view.c:737 msgid "Secured by DTLS" msgstr "" -#: ../gtk/incall_view.c:691 +#: ../gtk/incall_view.c:743 #, c-format msgid "Secured by ZRTP - [auth token: %s]" msgstr "" -#: ../gtk/incall_view.c:697 +#: ../gtk/incall_view.c:747 msgid "Set unverified" msgstr "" -#: ../gtk/incall_view.c:697 ../gtk/main.ui.h:4 +#: ../gtk/incall_view.c:747 msgid "Set verified" msgstr "" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In conference" msgstr "" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In call" msgstr "I samtale med" -#: ../gtk/incall_view.c:764 +#: ../gtk/incall_view.c:824 msgid "Paused call" msgstr "Pauset samtale" -#: ../gtk/incall_view.c:800 +#: ../gtk/incall_view.c:861 msgid "Call ended." msgstr "Samtale avsluttet." -#: ../gtk/incall_view.c:831 +#: ../gtk/incall_view.c:892 msgid "Transfer in progress" msgstr "" -#: ../gtk/incall_view.c:834 +#: ../gtk/incall_view.c:895 msgid "Transfer done." msgstr "" -#: ../gtk/incall_view.c:837 +#: ../gtk/incall_view.c:898 msgid "Transfer failed." msgstr "" -#: ../gtk/incall_view.c:881 +#: ../gtk/incall_view.c:929 msgid "Resume" msgstr "Fortsett" -#: ../gtk/incall_view.c:888 ../gtk/main.ui.h:9 +#: ../gtk/incall_view.c:929 ../gtk/in_call_frame.ui.h:7 msgid "Pause" msgstr "Pause" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 #, c-format msgid "" "Recording into\n" "%s %s" msgstr "" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 msgid "(Paused)" msgstr "" -#: ../gtk/loginframe.c:87 +#: ../gtk/loginframe.c:75 #, c-format msgid "Please enter login information for %s" msgstr "Skriv inn påloggingsinformasjon for %s:" @@ -752,262 +649,107 @@ msgstr "" msgid "Downloading of remote configuration from %s failed." msgstr "" -#: ../gtk/audio_assistant.c:98 +#: ../gtk/audio_assistant.c:103 msgid "No voice detected" msgstr "" -#: ../gtk/audio_assistant.c:99 +#: ../gtk/audio_assistant.c:104 msgid "Too low" msgstr "" -#: ../gtk/audio_assistant.c:100 +#: ../gtk/audio_assistant.c:105 msgid "Good" msgstr "" -#: ../gtk/audio_assistant.c:101 +#: ../gtk/audio_assistant.c:106 msgid "Too loud" msgstr "" -#: ../gtk/audio_assistant.c:183 +#: ../gtk/audio_assistant.c:188 msgid "Did you hear three beeps ?" msgstr "" -#: ../gtk/audio_assistant.c:292 ../gtk/audio_assistant.c:297 +#: ../gtk/audio_assistant.c:299 ../gtk/audio_assistant.c:304 msgid "Sound preferences not found " msgstr "" -#: ../gtk/audio_assistant.c:306 +#: ../gtk/audio_assistant.c:313 msgid "Cannot launch system sound control " msgstr "" -#: ../gtk/audio_assistant.c:318 +#: ../gtk/audio_assistant.c:325 msgid "" "Welcome!\n" "This assistant will help you to configure audio settings for Linphone" msgstr "" -#: ../gtk/audio_assistant.c:328 +#: ../gtk/audio_assistant.c:335 msgid "Capture device" msgstr "" -#: ../gtk/audio_assistant.c:329 +#: ../gtk/audio_assistant.c:336 msgid "Recorded volume" msgstr "" -#: ../gtk/audio_assistant.c:333 +#: ../gtk/audio_assistant.c:340 msgid "No voice" msgstr "" -#: ../gtk/audio_assistant.c:334 ../gtk/audio_assistant.c:373 +#: ../gtk/audio_assistant.c:341 ../gtk/audio_assistant.c:380 msgid "System sound preferences" msgstr "" -#: ../gtk/audio_assistant.c:369 +#: ../gtk/audio_assistant.c:376 msgid "Playback device" msgstr "" -#: ../gtk/audio_assistant.c:370 +#: ../gtk/audio_assistant.c:377 msgid "Play three beeps" msgstr "" -#: ../gtk/audio_assistant.c:403 +#: ../gtk/audio_assistant.c:410 msgid "Press the record button and say some words" msgstr "" -#: ../gtk/audio_assistant.c:404 +#: ../gtk/audio_assistant.c:411 msgid "Listen to your record voice" msgstr "" -#: ../gtk/audio_assistant.c:405 +#: ../gtk/audio_assistant.c:412 ../gtk/conf_frame.ui.h:2 +#: ../gtk/in_call_frame.ui.h:4 msgid "Record" msgstr "" -#: ../gtk/audio_assistant.c:406 +#: ../gtk/audio_assistant.c:413 msgid "Play" msgstr "" -#: ../gtk/audio_assistant.c:433 +#: ../gtk/audio_assistant.c:440 msgid "Let's start Linphone now" msgstr "" -#: ../gtk/audio_assistant.c:503 +#: ../gtk/audio_assistant.c:510 msgid "Audio Assistant" msgstr "" -#: ../gtk/audio_assistant.c:513 ../gtk/main.ui.h:32 +#: ../gtk/audio_assistant.c:520 ../gtk/main.ui.h:13 msgid "Audio assistant" msgstr "" -#: ../gtk/audio_assistant.c:518 +#: ../gtk/audio_assistant.c:525 msgid "Mic Gain calibration" msgstr "" -#: ../gtk/audio_assistant.c:524 +#: ../gtk/audio_assistant.c:531 msgid "Speaker volume calibration" msgstr "" -#: ../gtk/audio_assistant.c:529 +#: ../gtk/audio_assistant.c:536 msgid "Record and Play" msgstr "" -#: ../gtk/main.ui.h:1 -msgid "Callee name" -msgstr "" - -#: ../gtk/main.ui.h:2 -msgid "Send" -msgstr "Send" - -#: ../gtk/main.ui.h:3 -msgid "End conference" -msgstr "" - -#: ../gtk/main.ui.h:7 -msgid "Record this call to an audio file" -msgstr "" - -#: ../gtk/main.ui.h:8 -msgid "Video" -msgstr "" - -#: ../gtk/main.ui.h:10 -msgid "Mute" -msgstr "" - -#: ../gtk/main.ui.h:11 -msgid "Transfer" -msgstr "Overfører" - -#: ../gtk/main.ui.h:14 -msgid "In call" -msgstr "I samtale" - -#: ../gtk/main.ui.h:15 -msgid "Duration" -msgstr "Varighet" - -#: ../gtk/main.ui.h:16 -msgid "Call quality rating" -msgstr "" - -#: ../gtk/main.ui.h:17 -msgid "All users" -msgstr "Alle brukere" - -#: ../gtk/main.ui.h:18 -msgid "Online users" -msgstr "Tilkoblede brukere" - -#: ../gtk/main.ui.h:19 -msgid "ADSL" -msgstr "ADSL" - -#: ../gtk/main.ui.h:20 -msgid "Fiber Channel" -msgstr "Fiber Kanal" - -#: ../gtk/main.ui.h:21 -msgid "Default" -msgstr "Standard" - -#: ../gtk/main.ui.h:22 -msgid "Delete" -msgstr "" - -#: ../gtk/main.ui.h:23 -msgid "_Options" -msgstr "_Alternativer" - -#: ../gtk/main.ui.h:24 -msgid "Set configuration URI" -msgstr "" - -#: ../gtk/main.ui.h:25 -msgid "Always start video" -msgstr "" - -#: ../gtk/main.ui.h:26 -msgid "Enable self-view" -msgstr "Vis video av deg selv" - -#: ../gtk/main.ui.h:27 -msgid "_Help" -msgstr "_Hjelp" - -#: ../gtk/main.ui.h:28 -msgid "Show debug window" -msgstr "Vis avlusningsvindu" - -#: ../gtk/main.ui.h:29 -msgid "_Homepage" -msgstr "H_jemmeside" - -#: ../gtk/main.ui.h:30 -msgid "Check _Updates" -msgstr "Sjekk _Oppdateringer" - -#: ../gtk/main.ui.h:31 -msgid "Account assistant" -msgstr "" - -#: ../gtk/main.ui.h:33 -msgid "SIP address or phone number:" -msgstr "Sip adresse eller telefonnummer:" - -#: ../gtk/main.ui.h:34 -msgid "Initiate a new call" -msgstr "Start en ny samtale" - -#: ../gtk/main.ui.h:35 -msgid "Contacts" -msgstr "Kontakter" - -#: ../gtk/main.ui.h:36 -msgid "Search" -msgstr "Søk" - -#: ../gtk/main.ui.h:37 -msgid "Add contacts from directory" -msgstr "Legg til kontakter fra katalogen" - -#: ../gtk/main.ui.h:38 -msgid "Add contact" -msgstr "Legg til kontakt" - -#: ../gtk/main.ui.h:39 -msgid "Recent calls" -msgstr "" - -#: ../gtk/main.ui.h:40 -msgid "My current identity:" -msgstr "Min nåværende identitet:" - -#: ../gtk/main.ui.h:41 ../gtk/tunnel_config.ui.h:7 -msgid "Username" -msgstr "Brukernavn" - -#: ../gtk/main.ui.h:42 ../gtk/tunnel_config.ui.h:8 -msgid "Password" -msgstr "Passord" - -#: ../gtk/main.ui.h:43 -msgid "Internet connection:" -msgstr "Internet forbindelse:" - -#: ../gtk/main.ui.h:44 -msgid "Automatically log me in" -msgstr "Logg meg på automatisk" - -#: ../gtk/main.ui.h:45 ../gtk/password.ui.h:3 -msgid "UserID" -msgstr "BrukerID" - -#: ../gtk/main.ui.h:46 -msgid "Login information" -msgstr "Innlogginsinformasjon" - -#: ../gtk/main.ui.h:47 -msgid "Welcome!" +#: ../gtk/audio_assistant.c:541 ../gtk/setup_wizard.ui.h:38 +msgid "Terminating" msgstr "" #: ../gtk/about.ui.h:1 @@ -1038,456 +780,6 @@ msgid "" "he: Eli Zaretskii \n" msgstr "" -#: ../gtk/contact.ui.h:2 -msgid "SIP Address" -msgstr "SIP Addresse" - -#: ../gtk/contact.ui.h:3 -msgid "Show this contact presence status" -msgstr "Vis kontaktens tilstedestatus" - -#: ../gtk/contact.ui.h:4 -msgid "Allow this contact to see my presence status" -msgstr "La denne kontakten se min tilstedestatus" - -#: ../gtk/contact.ui.h:5 -msgid "Contact information" -msgstr "Kontaktinformasjon" - -#: ../gtk/log.ui.h:1 -msgid "Linphone debug window" -msgstr "Linphone avlusningsvindu" - -#: ../gtk/log.ui.h:2 -msgid "Scroll to end" -msgstr "" - -#: ../gtk/password.ui.h:1 -msgid "Linphone - Authentication required" -msgstr "Linphone - Autorisering kreves" - -#: ../gtk/password.ui.h:2 -msgid "Please enter the domain password" -msgstr "Skriv inn passordet for domenet" - -#: ../gtk/call_logs.ui.h:1 -msgid "Call history" -msgstr "Samtalehistorikk" - -#: ../gtk/call_logs.ui.h:2 -msgid "Clear all" -msgstr "Fjern alle" - -#: ../gtk/call_logs.ui.h:3 -msgid "Call back" -msgstr "Ring tilbake" - -#: ../gtk/sip_account.ui.h:1 -msgid "Linphone - Configure a SIP account" -msgstr "Linphone - Konfigurer en SIP konto" - -#: ../gtk/sip_account.ui.h:2 -msgid "Your SIP identity:" -msgstr "Din SIP identitet:" - -#: ../gtk/sip_account.ui.h:3 -msgid "Looks like sip:@" -msgstr "Ser ut som sip:@" - -#: ../gtk/sip_account.ui.h:4 -msgid "sip:" -msgstr "sip:" - -#: ../gtk/sip_account.ui.h:5 -msgid "SIP Proxy address:" -msgstr "SIP Proxy addresse:" - -#: ../gtk/sip_account.ui.h:6 -msgid "Looks like sip:" -msgstr "Ser ut som sip:" - -#: ../gtk/sip_account.ui.h:7 -msgid "Registration duration (sec):" -msgstr "Registreringsfrekvens (sek.):" - -#: ../gtk/sip_account.ui.h:8 -msgid "Contact params (optional):" -msgstr "" - -#: ../gtk/sip_account.ui.h:9 -msgid "AVPF regular RTCP interval (sec):" -msgstr "" - -#: ../gtk/sip_account.ui.h:10 -msgid "Route (optional):" -msgstr "Route (valgfritt):" - -#: ../gtk/sip_account.ui.h:11 -msgid "Transport" -msgstr "" - -#: ../gtk/sip_account.ui.h:12 -msgid "Register" -msgstr "" - -#: ../gtk/sip_account.ui.h:13 -msgid "Publish presence information" -msgstr "Publiser tilstedestatus" - -#: ../gtk/sip_account.ui.h:14 -msgid "Enable AVPF" -msgstr "" - -#: ../gtk/sip_account.ui.h:15 -msgid "Configure a SIP account" -msgstr "Konfigurer en SIP konto" - -#: ../gtk/parameters.ui.h:1 -msgid "anonymous" -msgstr "" - -#: ../gtk/parameters.ui.h:2 -msgid "GSSAPI" -msgstr "" - -#: ../gtk/parameters.ui.h:3 -msgid "SASL" -msgstr "" - -#: ../gtk/parameters.ui.h:4 -msgid "default soundcard" -msgstr "standard lydkort" - -#: ../gtk/parameters.ui.h:5 -msgid "a sound card" -msgstr "ett lydkort" - -#: ../gtk/parameters.ui.h:6 -msgid "default camera" -msgstr "standard kamera" - -#: ../gtk/parameters.ui.h:7 -msgid "CIF" -msgstr "CIF" - -#: ../gtk/parameters.ui.h:8 -msgid "Audio codecs" -msgstr "Lyd kodek" - -#: ../gtk/parameters.ui.h:9 -msgid "Video codecs" -msgstr "Video kodek" - -#: ../gtk/parameters.ui.h:10 -msgid "C" -msgstr "C" - -#: ../gtk/parameters.ui.h:11 -msgid "SIP (UDP)" -msgstr "" - -#: ../gtk/parameters.ui.h:12 -msgid "SIP (TCP)" -msgstr "" - -#: ../gtk/parameters.ui.h:13 -msgid "SIP (TLS)" -msgstr "" - -#: ../gtk/parameters.ui.h:14 -msgid "Settings" -msgstr "Innstillinger" - -#: ../gtk/parameters.ui.h:15 -msgid "Set Maximum Transmission Unit:" -msgstr "Velg MTU (Maximum Transmission Unit):" - -#: ../gtk/parameters.ui.h:16 -msgid "Send DTMFs as SIP info" -msgstr "Send DTMF som SIP-info" - -#: ../gtk/parameters.ui.h:17 -msgid "Allow IPv6" -msgstr "" - -#: ../gtk/parameters.ui.h:18 -msgid "Transport" -msgstr "Transport" - -#: ../gtk/parameters.ui.h:19 -msgid "SIP/UDP port" -msgstr "" - -#: ../gtk/parameters.ui.h:21 -msgid "Random" -msgstr "" - -#: ../gtk/parameters.ui.h:22 -msgid "SIP/TCP port" -msgstr "" - -#: ../gtk/parameters.ui.h:23 -msgid "Audio RTP/UDP:" -msgstr "Lyd RTP/UDP:" - -#: ../gtk/parameters.ui.h:24 -msgid "Fixed" -msgstr "" - -#: ../gtk/parameters.ui.h:25 -msgid "Video RTP/UDP:" -msgstr "Video RTP/UDP:" - -#: ../gtk/parameters.ui.h:26 -msgid "Media encryption type" -msgstr "" - -#: ../gtk/parameters.ui.h:27 -msgid "Media encryption is mandatory" -msgstr "" - -#: ../gtk/parameters.ui.h:28 -msgid "Tunnel" -msgstr "" - -#: ../gtk/parameters.ui.h:29 -msgid "DSCP fields" -msgstr "" - -#: ../gtk/parameters.ui.h:30 -msgid "Network protocol and ports" -msgstr "" - -#: ../gtk/parameters.ui.h:31 -msgid "Direct connection to the Internet" -msgstr "Tilkoblet Internett direkte" - -#: ../gtk/parameters.ui.h:32 -msgid "Behind NAT / Firewall (specify gateway IP )" -msgstr "" - -#: ../gtk/parameters.ui.h:33 -msgid "Behind NAT / Firewall (use STUN to resolve)" -msgstr "Bak NAT / Brannmur (bruk STUN for å avgjøre)" - -#: ../gtk/parameters.ui.h:34 -msgid "Behind NAT / Firewall (use ICE)" -msgstr "" - -#: ../gtk/parameters.ui.h:35 -msgid "Behind NAT / Firewall (use uPnP)" -msgstr "" - -#: ../gtk/parameters.ui.h:36 -msgid "Public IP address:" -msgstr "Offentlig IP-addresse:" - -#: ../gtk/parameters.ui.h:37 -msgid "Stun server:" -msgstr "STUN tjener:" - -#: ../gtk/parameters.ui.h:38 -msgid "NAT and Firewall" -msgstr "NAT og Brannvegg" - -#: ../gtk/parameters.ui.h:39 -msgid "Network settings" -msgstr "Nettverksinnstillinger" - -#: ../gtk/parameters.ui.h:40 -msgid "Ring sound:" -msgstr "Ringelyd:" - -#: ../gtk/parameters.ui.h:41 -msgid "ALSA special device (optional):" -msgstr "Spesiell ALSA enhet (valgfritt):" - -#: ../gtk/parameters.ui.h:42 -msgid "Capture device:" -msgstr "Mikrofonenhet:" - -#: ../gtk/parameters.ui.h:43 -msgid "Ring device:" -msgstr "Ringe-enhet:" - -#: ../gtk/parameters.ui.h:44 -msgid "Playback device:" -msgstr "Avspillingsenhet:" - -#: ../gtk/parameters.ui.h:45 -msgid "Enable echo cancellation" -msgstr "Bruk ekko-kansellering" - -#: ../gtk/parameters.ui.h:46 -msgid "Audio" -msgstr "Lyd" - -#: ../gtk/parameters.ui.h:47 -msgid "Video input device:" -msgstr "Videoenhet:" - -#: ../gtk/parameters.ui.h:48 -msgid "Prefered video resolution:" -msgstr "Foretrukke video-oppløsning:" - -#: ../gtk/parameters.ui.h:49 -msgid "Video output method:" -msgstr "" - -#: ../gtk/parameters.ui.h:50 -msgid "Show camera preview" -msgstr "" - -#: ../gtk/parameters.ui.h:51 -msgid "Video" -msgstr "Video" - -#: ../gtk/parameters.ui.h:52 -msgid "Multimedia settings" -msgstr "Multimediainnstillinger" - -#: ../gtk/parameters.ui.h:53 -msgid "This section defines your SIP address when not using a SIP account" -msgstr "Denne seksjonen velger SIP-addresse når du ikke bruker en SIP-konto" - -#: ../gtk/parameters.ui.h:54 -msgid "Your display name (eg: John Doe):" -msgstr "Vist navn (eks: Ola Nordmann):" - -#: ../gtk/parameters.ui.h:55 -msgid "Your username:" -msgstr "Ditt brukernavn:" - -#: ../gtk/parameters.ui.h:56 -msgid "Your resulting SIP address:" -msgstr "Din resulterende SIP addresse:" - -#: ../gtk/parameters.ui.h:57 -msgid "Default identity" -msgstr "Standard identitet" - -#: ../gtk/parameters.ui.h:58 -msgid "Wizard" -msgstr "" - -#: ../gtk/parameters.ui.h:59 -msgid "Add" -msgstr "Legg til" - -#: ../gtk/parameters.ui.h:60 -msgid "Edit" -msgstr "Rediger" - -#: ../gtk/parameters.ui.h:61 -msgid "Remove" -msgstr "Fjern" - -#: ../gtk/parameters.ui.h:62 -msgid "Proxy accounts" -msgstr "Proxy kontoer" - -#: ../gtk/parameters.ui.h:63 -msgid "Erase all passwords" -msgstr "Slett alle passord" - -#: ../gtk/parameters.ui.h:64 -msgid "Privacy" -msgstr "Personvern" - -#: ../gtk/parameters.ui.h:65 -msgid "Automatically answer when a call is received" -msgstr "" - -#: ../gtk/parameters.ui.h:66 -msgid "Delay before answering (ms)" -msgstr "" - -#: ../gtk/parameters.ui.h:67 -msgid "Auto-answer" -msgstr "" - -#: ../gtk/parameters.ui.h:68 -msgid "Manage SIP Accounts" -msgstr "Behandle SIP-kontoer" - -#: ../gtk/parameters.ui.h:69 ../gtk/tunnel_config.ui.h:4 -msgid "Enable" -msgstr "Aktiver" - -#: ../gtk/parameters.ui.h:70 ../gtk/tunnel_config.ui.h:5 -msgid "Disable" -msgstr "Deaktiver" - -#: ../gtk/parameters.ui.h:71 -msgid "Codecs" -msgstr "Kodeker" - -#: ../gtk/parameters.ui.h:72 -msgid "0 stands for \"unlimited\"" -msgstr "0 betyr \"ubegrenset\"" - -#: ../gtk/parameters.ui.h:73 -msgid "Upload speed limit in Kbit/sec:" -msgstr "Maks opplastningshastighet i Kbit/sek:" - -#: ../gtk/parameters.ui.h:74 -msgid "Download speed limit in Kbit/sec:" -msgstr "Nedlastningsbegrensning i Kbit/sek:" - -#: ../gtk/parameters.ui.h:75 -msgid "Enable adaptive rate control" -msgstr "" - -#: ../gtk/parameters.ui.h:76 -msgid "" -"Adaptive rate control is a technique to dynamically guess the available " -"bandwidth during a call." -msgstr "" - -#: ../gtk/parameters.ui.h:77 -msgid "Bandwidth control" -msgstr "Båndbreddekontrol" - -#: ../gtk/parameters.ui.h:78 -msgid "Codecs" -msgstr "Kodek" - -#: ../gtk/parameters.ui.h:79 -msgid "Language" -msgstr "Språk" - -#: ../gtk/parameters.ui.h:80 -msgid "Show advanced settings" -msgstr "Vis avanserte innstillinger" - -#: ../gtk/parameters.ui.h:81 -msgid "Level" -msgstr "Nivå" - -#: ../gtk/parameters.ui.h:82 -msgid "User interface" -msgstr "Brukergrensesnitt" - -#: ../gtk/parameters.ui.h:83 ../gtk/ldap.ui.h:2 -msgid "Server address:" -msgstr "" - -#: ../gtk/parameters.ui.h:84 ../gtk/ldap.ui.h:3 -msgid "Authentication method:" -msgstr "" - -#: ../gtk/parameters.ui.h:86 -msgid "LDAP Account setup" -msgstr "" - -#: ../gtk/parameters.ui.h:87 -msgid "LDAP" -msgstr "" - -#: ../gtk/parameters.ui.h:88 -msgid "Done" -msgstr "Ferdig" - #: ../gtk/buddylookup.ui.h:1 msgid "Search contacts in directory" msgstr "Søk kontakter i katalogen" @@ -1500,29 +792,21 @@ msgstr "Legg til listen min" msgid "Search somebody" msgstr "Søk noen" -#: ../gtk/waiting.ui.h:2 -msgid "Please wait" -msgstr "Vennligst vent" - -#: ../gtk/dscp_settings.ui.h:1 -msgid "DSCP settings" +#: ../gtk/callee_frame.ui.h:1 +msgid "Callee name" msgstr "" -#: ../gtk/dscp_settings.ui.h:2 -msgid "SIP" -msgstr "" +#: ../gtk/call_logs.ui.h:1 +msgid "Call history" +msgstr "Samtalehistorikk" -#: ../gtk/dscp_settings.ui.h:3 -msgid "Audio RTP stream" -msgstr "" +#: ../gtk/call_logs.ui.h:2 +msgid "Clear all" +msgstr "Fjern alle" -#: ../gtk/dscp_settings.ui.h:4 -msgid "Video RTP stream" -msgstr "" - -#: ../gtk/dscp_settings.ui.h:5 -msgid "Set DSCP values (in hexadecimal)" -msgstr "" +#: ../gtk/call_logs.ui.h:3 +msgid "Call back" +msgstr "Ring tilbake" #: ../gtk/call_statistics.ui.h:1 msgid "Call statistics" @@ -1572,30 +856,112 @@ msgstr "" msgid "Call statistics and information" msgstr "" -#: ../gtk/tunnel_config.ui.h:1 -msgid "Configure VoIP tunnel" +#: ../gtk/chatroom_frame.ui.h:1 +msgid "Send" +msgstr "Send" + +#: ../gtk/conf_frame.ui.h:1 +msgid "End conference" msgstr "" -#: ../gtk/tunnel_config.ui.h:2 -msgid "Host" +#: ../gtk/config-uri.ui.h:1 +msgid "Specifying a remote configuration URI" msgstr "" -#: ../gtk/tunnel_config.ui.h:3 -msgid "Port" +#: ../gtk/config-uri.ui.h:2 +msgid "" +"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" +"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " msgstr "" -#: ../gtk/tunnel_config.ui.h:6 -msgid "Configure tunnel" +#: ../gtk/contact.ui.h:2 +msgid "SIP Address" +msgstr "SIP Addresse" + +#: ../gtk/contact.ui.h:3 +msgid "Show this contact presence status" +msgstr "Vis kontaktens tilstedestatus" + +#: ../gtk/contact.ui.h:4 +msgid "Allow this contact to see my presence status" +msgstr "La denne kontakten se min tilstedestatus" + +#: ../gtk/contact.ui.h:5 +msgid "Contact information" +msgstr "Kontaktinformasjon" + +#: ../gtk/dscp_settings.ui.h:1 +msgid "DSCP settings" msgstr "" -#: ../gtk/tunnel_config.ui.h:9 -msgid "Configure http proxy (optional)" +#: ../gtk/dscp_settings.ui.h:2 +msgid "SIP" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:3 +msgid "Audio RTP stream" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:4 +msgid "Video RTP stream" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:5 +msgid "Set DSCP values (in hexadecimal)" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:1 +msgid "Click here to set the speakers volume" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:5 +msgid "Record this call to an audio file" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:6 +msgid "Video" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:8 +msgid "Mute" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:9 +msgid "Transfer" +msgstr "Overfører" + +#: ../gtk/in_call_frame.ui.h:12 +msgid "In call" +msgstr "I samtale" + +#: ../gtk/in_call_frame.ui.h:13 +msgid "Duration" +msgstr "Varighet" + +#: ../gtk/in_call_frame.ui.h:14 +msgid "Call quality rating" msgstr "" #: ../gtk/ldap.ui.h:1 msgid "LDAP Settings" msgstr "" +#: ../gtk/ldap.ui.h:2 ../gtk/parameters.ui.h:89 +msgid "Server address:" +msgstr "" + +#: ../gtk/ldap.ui.h:3 ../gtk/parameters.ui.h:90 +msgid "Authentication method:" +msgstr "" + +#: ../gtk/ldap.ui.h:4 ../gtk/parameters.ui.h:91 ../gtk/setup_wizard.ui.h:17 +msgid "Username:" +msgstr "Brukernavn:" + +#: ../gtk/ldap.ui.h:5 ../gtk/password.ui.h:4 ../gtk/setup_wizard.ui.h:18 +msgid "Password:" +msgstr "Passord:" + #: ../gtk/ldap.ui.h:6 msgid "Use TLS Connection" msgstr "" @@ -1681,16 +1047,504 @@ msgstr "" msgid "NTLM" msgstr "" -#: ../gtk/config-uri.ui.h:1 -msgid "Specifying a remote configuration URI" +#: ../gtk/login_frame.ui.h:1 ../gtk/tunnel_config.ui.h:7 +msgid "Username" +msgstr "Brukernavn" + +#: ../gtk/login_frame.ui.h:2 ../gtk/tunnel_config.ui.h:8 +msgid "Password" +msgstr "Passord" + +#: ../gtk/login_frame.ui.h:3 +msgid "Internet connection:" +msgstr "Internet forbindelse:" + +#: ../gtk/login_frame.ui.h:4 +msgid "Automatically log me in" +msgstr "Logg meg på automatisk" + +#: ../gtk/login_frame.ui.h:5 ../gtk/password.ui.h:3 +msgid "UserID" +msgstr "BrukerID" + +#: ../gtk/login_frame.ui.h:6 +msgid "Login information" +msgstr "Innlogginsinformasjon" + +#: ../gtk/login_frame.ui.h:7 +msgid "Welcome!" msgstr "" -#: ../gtk/config-uri.ui.h:2 -msgid "" -"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" -"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " +#: ../gtk/login_frame.ui.h:8 +msgid "ADSL" +msgstr "ADSL" + +#: ../gtk/login_frame.ui.h:9 +msgid "Fiber Channel" +msgstr "Fiber Kanal" + +#: ../gtk/log.ui.h:1 +msgid "Linphone debug window" +msgstr "Linphone avlusningsvindu" + +#: ../gtk/log.ui.h:2 +msgid "Scroll to end" msgstr "" +#: ../gtk/main.ui.h:1 +msgid "Default" +msgstr "Standard" + +#: ../gtk/main.ui.h:2 +msgid "Delete" +msgstr "" + +#: ../gtk/main.ui.h:3 +msgid "_Options" +msgstr "_Alternativer" + +#: ../gtk/main.ui.h:4 +msgid "Set configuration URI" +msgstr "" + +#: ../gtk/main.ui.h:5 +msgid "Always start video" +msgstr "" + +#: ../gtk/main.ui.h:6 +msgid "Enable self-view" +msgstr "Vis video av deg selv" + +#: ../gtk/main.ui.h:7 +msgid "Show keypad" +msgstr "" + +#: ../gtk/main.ui.h:8 +msgid "_Help" +msgstr "_Hjelp" + +#: ../gtk/main.ui.h:9 +msgid "Show debug window" +msgstr "Vis avlusningsvindu" + +#: ../gtk/main.ui.h:10 +msgid "_Homepage" +msgstr "H_jemmeside" + +#: ../gtk/main.ui.h:11 +msgid "Check _Updates" +msgstr "Sjekk _Oppdateringer" + +#: ../gtk/main.ui.h:12 +msgid "Account assistant" +msgstr "" + +#: ../gtk/main.ui.h:14 +msgid "SIP address or phone number:" +msgstr "Sip adresse eller telefonnummer:" + +#: ../gtk/main.ui.h:15 +msgid "Initiate a new call" +msgstr "Start en ny samtale" + +#: ../gtk/main.ui.h:16 +msgid "Contacts" +msgstr "Kontakter" + +#: ../gtk/main.ui.h:17 +msgid "Search" +msgstr "Søk" + +#: ../gtk/main.ui.h:18 +msgid "Add contacts from directory" +msgstr "Legg til kontakter fra katalogen" + +#: ../gtk/main.ui.h:19 +msgid "Add contact" +msgstr "Legg til kontakt" + +#: ../gtk/main.ui.h:20 +msgid "Clear call history" +msgstr "" + +#: ../gtk/main.ui.h:22 +msgid "My current identity:" +msgstr "Min nåværende identitet:" + +#: ../gtk/main.ui.h:23 +msgid "Autoanswer is enabled" +msgstr "" + +#: ../gtk/parameters.ui.h:1 +msgid "anonymous" +msgstr "" + +#: ../gtk/parameters.ui.h:2 +msgid "GSSAPI" +msgstr "" + +#: ../gtk/parameters.ui.h:3 +msgid "SASL" +msgstr "" + +#: ../gtk/parameters.ui.h:4 +msgid "default soundcard" +msgstr "standard lydkort" + +#: ../gtk/parameters.ui.h:5 +msgid "a sound card" +msgstr "ett lydkort" + +#: ../gtk/parameters.ui.h:6 +msgid "default camera" +msgstr "standard kamera" + +#: ../gtk/parameters.ui.h:7 +msgid "CIF" +msgstr "CIF" + +#: ../gtk/parameters.ui.h:8 +msgid "Audio codecs" +msgstr "Lyd kodek" + +#: ../gtk/parameters.ui.h:9 +msgid "Video codecs" +msgstr "Video kodek" + +#: ../gtk/parameters.ui.h:10 +msgid "C" +msgstr "C" + +#: ../gtk/parameters.ui.h:11 +msgid "SIP (UDP)" +msgstr "" + +#: ../gtk/parameters.ui.h:12 +msgid "SIP (TCP)" +msgstr "" + +#: ../gtk/parameters.ui.h:13 +msgid "SIP (TLS)" +msgstr "" + +#: ../gtk/parameters.ui.h:14 +msgid "default" +msgstr "" + +#: ../gtk/parameters.ui.h:15 +msgid "high-fps" +msgstr "" + +#: ../gtk/parameters.ui.h:16 +msgid "custom" +msgstr "" + +#: ../gtk/parameters.ui.h:17 +msgid "Settings" +msgstr "Innstillinger" + +#: ../gtk/parameters.ui.h:18 +msgid "This section defines your SIP address when not using a SIP account" +msgstr "Denne seksjonen velger SIP-addresse når du ikke bruker en SIP-konto" + +#: ../gtk/parameters.ui.h:19 +msgid "Your display name (eg: John Doe):" +msgstr "Vist navn (eks: Ola Nordmann):" + +#: ../gtk/parameters.ui.h:20 +msgid "Your username:" +msgstr "Ditt brukernavn:" + +#: ../gtk/parameters.ui.h:21 +msgid "Your resulting SIP address:" +msgstr "Din resulterende SIP addresse:" + +#: ../gtk/parameters.ui.h:22 +msgid "Default identity" +msgstr "Standard identitet" + +#: ../gtk/parameters.ui.h:23 +msgid "Wizard" +msgstr "" + +#: ../gtk/parameters.ui.h:24 +msgid "Add" +msgstr "Legg til" + +#: ../gtk/parameters.ui.h:25 +msgid "Edit" +msgstr "Rediger" + +#: ../gtk/parameters.ui.h:26 +msgid "Remove" +msgstr "Fjern" + +#: ../gtk/parameters.ui.h:27 +msgid "Proxy accounts" +msgstr "Proxy kontoer" + +#: ../gtk/parameters.ui.h:28 +msgid "Erase all passwords" +msgstr "Slett alle passord" + +#: ../gtk/parameters.ui.h:29 +msgid "Privacy" +msgstr "Personvern" + +#: ../gtk/parameters.ui.h:30 +msgid "Automatically answer when a call is received" +msgstr "" + +#: ../gtk/parameters.ui.h:31 +msgid "Delay before answering (ms)" +msgstr "" + +#: ../gtk/parameters.ui.h:32 +msgid "Auto-answer" +msgstr "" + +#: ../gtk/parameters.ui.h:33 +msgid "Manage SIP Accounts" +msgstr "Behandle SIP-kontoer" + +#: ../gtk/parameters.ui.h:34 +msgid "Ring sound:" +msgstr "Ringelyd:" + +#: ../gtk/parameters.ui.h:35 +msgid "ALSA special device (optional):" +msgstr "Spesiell ALSA enhet (valgfritt):" + +#: ../gtk/parameters.ui.h:36 +msgid "Capture device:" +msgstr "Mikrofonenhet:" + +#: ../gtk/parameters.ui.h:37 +msgid "Ring device:" +msgstr "Ringe-enhet:" + +#: ../gtk/parameters.ui.h:38 +msgid "Playback device:" +msgstr "Avspillingsenhet:" + +#: ../gtk/parameters.ui.h:39 +msgid "Enable echo cancellation" +msgstr "Bruk ekko-kansellering" + +#: ../gtk/parameters.ui.h:40 +msgid "Audio" +msgstr "Lyd" + +#: ../gtk/parameters.ui.h:41 +msgid "Video input device:" +msgstr "Videoenhet:" + +#: ../gtk/parameters.ui.h:42 +msgid "Preferred video resolution:" +msgstr "" + +#: ../gtk/parameters.ui.h:43 +msgid "Video output method:" +msgstr "" + +#: ../gtk/parameters.ui.h:44 +msgid "Show camera preview" +msgstr "" + +#: ../gtk/parameters.ui.h:45 +msgid "Video preset:" +msgstr "" + +#: ../gtk/parameters.ui.h:46 +msgid "Preferred video framerate:" +msgstr "" + +#: ../gtk/parameters.ui.h:47 +msgid "0 stands for \"unlimited\"" +msgstr "0 betyr \"ubegrenset\"" + +#: ../gtk/parameters.ui.h:48 +msgid "Video" +msgstr "Video" + +#: ../gtk/parameters.ui.h:49 +msgid "Upload speed limit in Kbit/sec:" +msgstr "Maks opplastningshastighet i Kbit/sek:" + +#: ../gtk/parameters.ui.h:50 +msgid "Download speed limit in Kbit/sec:" +msgstr "Nedlastningsbegrensning i Kbit/sek:" + +#: ../gtk/parameters.ui.h:51 +msgid "Enable adaptive rate control" +msgstr "" + +#: ../gtk/parameters.ui.h:52 +msgid "" +"Adaptive rate control is a technique to dynamically guess the available " +"bandwidth during a call." +msgstr "" + +#: ../gtk/parameters.ui.h:53 +msgid "Bandwidth control" +msgstr "Båndbreddekontrol" + +#: ../gtk/parameters.ui.h:54 +msgid "Multimedia settings" +msgstr "Multimediainnstillinger" + +#: ../gtk/parameters.ui.h:55 +msgid "Set Maximum Transmission Unit:" +msgstr "Velg MTU (Maximum Transmission Unit):" + +#: ../gtk/parameters.ui.h:56 +msgid "Send DTMFs as SIP info" +msgstr "Send DTMF som SIP-info" + +#: ../gtk/parameters.ui.h:57 +msgid "Allow IPv6" +msgstr "" + +#: ../gtk/parameters.ui.h:58 +msgid "Transport" +msgstr "Transport" + +#: ../gtk/parameters.ui.h:59 +msgid "SIP/UDP port" +msgstr "" + +#: ../gtk/parameters.ui.h:61 +msgid "Random" +msgstr "" + +#: ../gtk/parameters.ui.h:62 +msgid "SIP/TCP port" +msgstr "" + +#: ../gtk/parameters.ui.h:63 +msgid "Audio RTP/UDP:" +msgstr "Lyd RTP/UDP:" + +#: ../gtk/parameters.ui.h:64 +msgid "Fixed" +msgstr "" + +#: ../gtk/parameters.ui.h:65 +msgid "Video RTP/UDP:" +msgstr "Video RTP/UDP:" + +#: ../gtk/parameters.ui.h:66 +msgid "Media encryption type" +msgstr "" + +#: ../gtk/parameters.ui.h:67 +msgid "Media encryption is mandatory" +msgstr "" + +#: ../gtk/parameters.ui.h:68 +msgid "Tunnel" +msgstr "" + +#: ../gtk/parameters.ui.h:69 +msgid "DSCP fields" +msgstr "" + +#: ../gtk/parameters.ui.h:70 +msgid "Network protocol and ports" +msgstr "" + +#: ../gtk/parameters.ui.h:71 +msgid "Direct connection to the Internet" +msgstr "Tilkoblet Internett direkte" + +#: ../gtk/parameters.ui.h:72 +msgid "Behind NAT / Firewall (specify gateway IP )" +msgstr "" + +#: ../gtk/parameters.ui.h:73 +msgid "Behind NAT / Firewall (use STUN to resolve)" +msgstr "Bak NAT / Brannmur (bruk STUN for å avgjøre)" + +#: ../gtk/parameters.ui.h:74 +msgid "Behind NAT / Firewall (use ICE)" +msgstr "" + +#: ../gtk/parameters.ui.h:75 +msgid "Behind NAT / Firewall (use uPnP)" +msgstr "" + +#: ../gtk/parameters.ui.h:76 +msgid "Public IP address:" +msgstr "Offentlig IP-addresse:" + +#: ../gtk/parameters.ui.h:77 +msgid "Stun server:" +msgstr "STUN tjener:" + +#: ../gtk/parameters.ui.h:78 +msgid "NAT and Firewall" +msgstr "NAT og Brannvegg" + +#: ../gtk/parameters.ui.h:79 +msgid "Network settings" +msgstr "Nettverksinnstillinger" + +#: ../gtk/parameters.ui.h:80 ../gtk/tunnel_config.ui.h:4 +msgid "Enable" +msgstr "Aktiver" + +#: ../gtk/parameters.ui.h:81 ../gtk/tunnel_config.ui.h:5 +msgid "Disable" +msgstr "Deaktiver" + +#: ../gtk/parameters.ui.h:82 +msgid "Audio codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:83 +msgid "Video codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:84 +msgid "Codecs" +msgstr "Kodek" + +#: ../gtk/parameters.ui.h:85 +msgid "Language" +msgstr "Språk" + +#: ../gtk/parameters.ui.h:86 +msgid "Show advanced settings" +msgstr "Vis avanserte innstillinger" + +#: ../gtk/parameters.ui.h:87 +msgid "Level" +msgstr "Nivå" + +#: ../gtk/parameters.ui.h:88 +msgid "User interface" +msgstr "Brukergrensesnitt" + +#: ../gtk/parameters.ui.h:92 +msgid "LDAP Account setup" +msgstr "" + +#: ../gtk/parameters.ui.h:93 +msgid "LDAP" +msgstr "" + +#: ../gtk/parameters.ui.h:94 +msgid "Done" +msgstr "Ferdig" + +#: ../gtk/password.ui.h:1 +msgid "Linphone - Authentication required" +msgstr "Linphone - Autorisering kreves" + +#: ../gtk/password.ui.h:2 +msgid "Please enter the domain password" +msgstr "Skriv inn passordet for domenet" + #: ../gtk/provisioning-fetch.ui.h:1 msgid "Configuring..." msgstr "" @@ -1699,68 +1553,278 @@ msgstr "" msgid "Please wait while fetching configuration from server..." msgstr "" -#: ../coreapi/linphonecore.c:1539 +#: ../gtk/setup_wizard.ui.h:1 +msgid "SIP account configuration assistant" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:2 +msgid "" +"Welcome!\n" +"This assistant will help you to use a SIP account for your calls." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:4 +msgid "Welcome to the account setup assistant" +msgstr "Velkommen til brukerkontoveiviseren" + +#: ../gtk/setup_wizard.ui.h:5 +msgid "Create an account on linphone.org" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:6 +msgid "I have already a linphone.org account and I just want to use it" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:7 +msgid "I have already a sip account and I just want to use it" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:8 +msgid "I want to specify a remote configuration URI" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:9 +msgid "Account setup assistant" +msgstr "Brukerkontoveiviser" + +#: ../gtk/setup_wizard.ui.h:10 +msgid "Enter your account information" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:11 +msgid "Username*" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:12 +msgid "Password*" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:13 +msgid "Domain*" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:14 +msgid "Proxy" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:15 +msgid "Configure your account (step 1/1)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:16 +msgid "Enter your linphone.org username" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:19 +msgid "Enter your sip username (step 1/1)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:20 +msgid "(*) Required fields" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:21 +msgid "Email: (*)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:22 +msgid "Username: (*)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:23 +msgid "Password: (*)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:24 +msgid "Confirm your password: (*)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:25 +msgid "Keep me informed with linphone updates" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:26 +msgid "Enter account information (step 1/2)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:27 +msgid "Your account is being created, please wait." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:28 +msgid "Account creation in progress" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:29 +msgid "" +"Please validate your account by clicking on the link we just sent you by email.\n" +"Then come back here and press Next button." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:31 +msgid "Validation (step 2/2)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:32 +msgid "Checking if your account is been validated, please wait." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:33 +msgid "Account validation check in progress" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:34 +msgid "" +"Error, account not validated, username already used or server unreachable.\n" +"Please go back and try again." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:36 +msgid "Error" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:37 +msgid "Thank you. Your account is now configured and ready for use." +msgstr "Takk. Ditt konto er nå satt opp og klart til bruk." + +#: ../gtk/sip_account.ui.h:1 +msgid "Linphone - Configure a SIP account" +msgstr "Linphone - Konfigurer en SIP konto" + +#: ../gtk/sip_account.ui.h:2 +msgid "Your SIP identity:" +msgstr "Din SIP identitet:" + +#: ../gtk/sip_account.ui.h:3 +msgid "Looks like sip:@" +msgstr "Ser ut som sip:@" + +#: ../gtk/sip_account.ui.h:4 +msgid "sip:" +msgstr "sip:" + +#: ../gtk/sip_account.ui.h:5 +msgid "SIP Proxy address:" +msgstr "SIP Proxy addresse:" + +#: ../gtk/sip_account.ui.h:6 +msgid "Looks like sip:" +msgstr "Ser ut som sip:" + +#: ../gtk/sip_account.ui.h:7 +msgid "Registration duration (sec):" +msgstr "Registreringsfrekvens (sek.):" + +#: ../gtk/sip_account.ui.h:8 +msgid "Contact params (optional):" +msgstr "" + +#: ../gtk/sip_account.ui.h:9 +msgid "AVPF regular RTCP interval (sec):" +msgstr "" + +#: ../gtk/sip_account.ui.h:10 +msgid "Route (optional):" +msgstr "Route (valgfritt):" + +#: ../gtk/sip_account.ui.h:11 +msgid "Transport" +msgstr "" + +#: ../gtk/sip_account.ui.h:12 +msgid "Register" +msgstr "" + +#: ../gtk/sip_account.ui.h:13 +msgid "Publish presence information" +msgstr "Publiser tilstedestatus" + +#: ../gtk/sip_account.ui.h:14 +msgid "Enable AVPF" +msgstr "" + +#: ../gtk/sip_account.ui.h:15 +msgid "Configure a SIP account" +msgstr "Konfigurer en SIP konto" + +#: ../gtk/tunnel_config.ui.h:1 +msgid "Configure VoIP tunnel" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:2 +msgid "Host" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:3 +msgid "Port" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:6 +msgid "Configure tunnel" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:9 +msgid "Configure http proxy (optional)" +msgstr "" + +#: ../gtk/waiting.ui.h:2 +msgid "Please wait" +msgstr "Vennligst vent" + +#: ../coreapi/linphonecore.c:1560 msgid "Ready" msgstr "Klar" -#: ../coreapi/linphonecore.c:2551 +#: ../coreapi/linphonecore.c:2556 msgid "Configuring" msgstr "" -#: ../coreapi/linphonecore.c:2725 -msgid "Looking for telephone number destination..." -msgstr "Ser etter telefonnummer for destinasjonen..." - -#: ../coreapi/linphonecore.c:2727 -msgid "Could not resolve this number." -msgstr "Kan ikke tilkoble dette nummeret." - #. must be known at that time -#: ../coreapi/linphonecore.c:3013 +#: ../coreapi/linphonecore.c:2951 msgid "Contacting" msgstr "Tilknytter" -#: ../coreapi/linphonecore.c:3018 +#: ../coreapi/linphonecore.c:2956 msgid "Could not call" msgstr "Kunne ikke ringe" -#: ../coreapi/linphonecore.c:3169 +#: ../coreapi/linphonecore.c:3092 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "Beklager, du har nådd maksimalt antall samtidige samtaler" -#: ../coreapi/linphonecore.c:3327 +#: ../coreapi/linphonecore.c:3250 msgid "is contacting you" msgstr "Kontakter deg." -#: ../coreapi/linphonecore.c:3328 +#: ../coreapi/linphonecore.c:3251 msgid " and asked autoanswer." msgstr " og ba om autosvar." -#: ../coreapi/linphonecore.c:3452 +#: ../coreapi/linphonecore.c:3377 msgid "Modifying call parameters..." msgstr "Endrer ringeparametre..." -#: ../coreapi/linphonecore.c:3802 +#: ../coreapi/linphonecore.c:3769 msgid "Connected." msgstr "Tilkoblet" -#: ../coreapi/linphonecore.c:3827 +#: ../coreapi/linphonecore.c:3794 msgid "Call aborted" msgstr "Samtale avbrutt" -#: ../coreapi/linphonecore.c:4024 +#: ../coreapi/linphonecore.c:3983 msgid "Could not pause the call" msgstr "Kunne ikke pause samtalen" -#: ../coreapi/linphonecore.c:4027 +#: ../coreapi/linphonecore.c:3986 msgid "Pausing the current call..." msgstr "Pauser nåværende samtale" -#: ../coreapi/misc.c:434 +#: ../coreapi/misc.c:440 msgid "Stun lookup in progress..." msgstr "STUN oppslag pågår..." -#: ../coreapi/misc.c:615 +#: ../coreapi/misc.c:650 msgid "ICE local candidates gathering in progress..." msgstr "" @@ -1816,166 +1880,173 @@ msgstr "" msgid "Unknown status" msgstr "" -#: ../coreapi/proxy.c:328 +#: ../coreapi/proxy.c:292 msgid "" "The sip proxy address you entered is invalid, it must start with \"sip:\" " "followed by a hostname." msgstr "SIP proxy adressen du har angitt er ugyldig, den må begynne med \"sip:\" etterfult av vertsnavn." -#: ../coreapi/proxy.c:334 +#: ../coreapi/proxy.c:298 msgid "" "The sip identity you entered is invalid.\n" "It should look like sip:username@proxydomain, such as sip:alice@example.net" msgstr "SIP adressen du har angitt er feil. Adressen bør se ut som sip: brukernavn@domenenavn, f.eks sip:ola@eksempel.no" -#: ../coreapi/proxy.c:1416 +#: ../coreapi/proxy.c:927 +msgid "Looking for telephone number destination..." +msgstr "Ser etter telefonnummer for destinasjonen..." + +#: ../coreapi/proxy.c:931 +msgid "Could not resolve this number." +msgstr "Kan ikke tilkoble dette nummeret." + +#: ../coreapi/proxy.c:1324 #, c-format msgid "Could not login as %s" msgstr "Ikke ikke logge inn som %s" -#: ../coreapi/callbacks.c:428 +#: ../coreapi/proxy.c:1411 +#, c-format +msgid "Refreshing on %s..." +msgstr "" + +#: ../coreapi/callbacks.c:423 msgid "Remote ringing." msgstr "Ringer hos motparten." -#: ../coreapi/callbacks.c:440 +#: ../coreapi/callbacks.c:435 msgid "Remote ringing..." msgstr "" -#: ../coreapi/callbacks.c:461 +#: ../coreapi/callbacks.c:458 msgid "Early media." msgstr "Tidlig media" -#: ../coreapi/callbacks.c:534 +#: ../coreapi/callbacks.c:488 #, c-format -msgid "Call with %s is paused." -msgstr "Samtalen med %s er pauset." +msgid "Call answered by %s" +msgstr "" -#: ../coreapi/callbacks.c:547 -#, c-format -msgid "Call answered by %s - on hold." -msgstr "Samtale besvart av %s - på vent." - -#: ../coreapi/callbacks.c:557 +#: ../coreapi/callbacks.c:527 msgid "Call resumed." msgstr "Samtale gjenopptatt." -#: ../coreapi/callbacks.c:561 -#, c-format -msgid "Call answered by %s." -msgstr "Samtale besvart av %s." - -#: ../coreapi/callbacks.c:584 +#: ../coreapi/callbacks.c:582 msgid "Incompatible, check codecs or security settings..." msgstr "" -#: ../coreapi/callbacks.c:589 ../coreapi/callbacks.c:906 +#: ../coreapi/callbacks.c:587 ../coreapi/callbacks.c:923 msgid "Incompatible media parameters." msgstr "" -#: ../coreapi/callbacks.c:619 +#: ../coreapi/callbacks.c:612 msgid "We have been resumed." msgstr "" #. we are being paused -#: ../coreapi/callbacks.c:628 +#: ../coreapi/callbacks.c:620 msgid "We are paused by other party." msgstr "" -#. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:666 +#: ../coreapi/callbacks.c:630 msgid "Call is updated by remote." msgstr "" -#: ../coreapi/callbacks.c:782 +#: ../coreapi/callbacks.c:799 msgid "Call terminated." msgstr "Samtale avsluttet." -#: ../coreapi/callbacks.c:810 +#: ../coreapi/callbacks.c:827 msgid "User is busy." msgstr "Brukeren er opptatt." -#: ../coreapi/callbacks.c:811 +#: ../coreapi/callbacks.c:828 msgid "User is temporarily unavailable." msgstr "Brukeren er midlertidig ikke tilgjengelig." #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:813 +#: ../coreapi/callbacks.c:830 msgid "User does not want to be disturbed." msgstr "Brukeren vil ikke bli forstyrret." -#: ../coreapi/callbacks.c:814 +#: ../coreapi/callbacks.c:831 msgid "Call declined." msgstr "Samtale avvist." -#: ../coreapi/callbacks.c:829 +#: ../coreapi/callbacks.c:846 msgid "Request timeout." msgstr "" -#: ../coreapi/callbacks.c:860 +#: ../coreapi/callbacks.c:877 msgid "Redirected" msgstr "Omdirigert" -#: ../coreapi/callbacks.c:915 +#: ../coreapi/callbacks.c:927 msgid "Call failed." msgstr "Samtale feilet." -#: ../coreapi/callbacks.c:993 +#: ../coreapi/callbacks.c:1005 #, c-format msgid "Registration on %s successful." msgstr "Registrering hos %s lykkes." -#: ../coreapi/callbacks.c:994 +#: ../coreapi/callbacks.c:1006 #, c-format msgid "Unregistration on %s done." msgstr "Avregistrering hos %s lykkes." -#: ../coreapi/callbacks.c:1012 +#: ../coreapi/callbacks.c:1024 msgid "no response timeout" msgstr "ingen svar innen angitt tid" -#: ../coreapi/callbacks.c:1015 +#: ../coreapi/callbacks.c:1027 #, c-format msgid "Registration on %s failed: %s" msgstr "Registrering hos %s mislykkes: %s" -#: ../coreapi/callbacks.c:1022 +#: ../coreapi/callbacks.c:1034 msgid "Service unavailable, retrying" msgstr "" #. if encryption is DTLS, no status to be displayed -#: ../coreapi/linphonecall.c:180 +#: ../coreapi/linphonecall.c:197 #, c-format msgid "Authentication token is %s" msgstr "" -#: ../coreapi/linphonecall.c:1310 +#: ../coreapi/linphonecall.c:1561 +#, c-format +msgid "Call parameters could not be modified: %s." +msgstr "" + +#: ../coreapi/linphonecall.c:1563 msgid "Call parameters were successfully modified." msgstr "" -#: ../coreapi/linphonecall.c:3686 +#: ../coreapi/linphonecall.c:4396 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." msgstr[0] "Du har %i ubesvarte anrop." msgstr[1] "Du har %i missade samtal" -#: ../coreapi/call_log.c:209 +#: ../coreapi/call_log.c:223 msgid "aborted" msgstr "" -#: ../coreapi/call_log.c:212 +#: ../coreapi/call_log.c:226 msgid "completed" msgstr "" -#: ../coreapi/call_log.c:215 +#: ../coreapi/call_log.c:229 msgid "missed" msgstr "" -#: ../coreapi/call_log.c:218 +#: ../coreapi/call_log.c:232 msgid "unknown" msgstr "" -#: ../coreapi/call_log.c:220 +#: ../coreapi/call_log.c:234 #, c-format msgid "" "%s at %s\n" @@ -1985,7 +2056,7 @@ msgid "" "Duration: %i mn %i sec\n" msgstr "" -#: ../coreapi/call_log.c:221 +#: ../coreapi/call_log.c:235 msgid "Outgoing call" msgstr "" diff --git a/po/nl.po b/po/nl.po index 98034aaaf..166734df1 100644 --- a/po/nl.po +++ b/po/nl.po @@ -8,74 +8,83 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-04-30 10:13+0200\n" -"PO-Revision-Date: 2015-04-30 08:13+0000\n" +"POT-Creation-Date: 2015-11-10 15:16+0100\n" +"PO-Revision-Date: 2015-11-10 14:16+0000\n" "Last-Translator: Belledonne Communications \n" -"Language-Team: Dutch (http://www.transifex.com/projects/p/linphone-gtk/language/nl/)\n" +"Language-Team: Dutch (http://www.transifex.com/belledonne-communications/linphone-gtk/language/nl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: nl\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ../gtk/calllogs.c:148 ../gtk/friendlist.c:974 +#: ../gtk/calllogs.c:178 #, c-format msgid "Call %s" msgstr "%s bellen" -#: ../gtk/calllogs.c:149 ../gtk/friendlist.c:975 +#: ../gtk/calllogs.c:179 #, c-format msgid "Send text to %s" msgstr "SMS versturen aan %s" -#: ../gtk/calllogs.c:232 +#: ../gtk/calllogs.c:181 +#, c-format +msgid "Add %s to your contact list" +msgstr "" + +#: ../gtk/calllogs.c:245 ../gtk/main.ui.h:21 +msgid "Recent calls" +msgstr "Recente gesprekken" + +#: ../gtk/calllogs.c:260 #, c-format msgid "Recent calls (%i)" msgstr "Recent oproepen (%i)" -#: ../gtk/calllogs.c:314 +#: ../gtk/calllogs.c:331 msgid "n/a" msgstr "n.v.t." -#: ../gtk/calllogs.c:317 +#: ../gtk/calllogs.c:334 msgid "Aborted" msgstr "Afgebroken" -#: ../gtk/calllogs.c:320 +#: ../gtk/calllogs.c:337 msgid "Missed" msgstr "Gemist" -#: ../gtk/calllogs.c:323 +#: ../gtk/calllogs.c:340 msgid "Declined" msgstr "Geweigerd" -#: ../gtk/calllogs.c:329 +#: ../gtk/calllogs.c:346 #, c-format msgid "%i minute" msgid_plural "%i minutes" msgstr[0] "%i minuut" msgstr[1] "%i minuten" -#: ../gtk/calllogs.c:332 +#: ../gtk/calllogs.c:349 #, c-format msgid "%i second" msgid_plural "%i seconds" msgstr[0] "%i seconde" msgstr[1] "%i seconden" -#: ../gtk/calllogs.c:337 +#: ../gtk/calllogs.c:354 #, c-format msgid "" "%s\tQuality: %s\n" "%s\t%s\t" msgstr "%s\tKwaliteit: %s\n%s\t%s\t" -#: ../gtk/calllogs.c:341 +#: ../gtk/calllogs.c:358 #, c-format msgid "%s\t%s" msgstr "%s\t%s" -#: ../gtk/conference.c:38 ../gtk/main.ui.h:13 +#: ../gtk/conference.c:38 ../gtk/in_call_frame.ui.h:11 msgid "Conference" msgstr "Vergadering" @@ -88,297 +97,314 @@ msgstr "Ik" msgid "Couldn't find pixmap file: %s" msgstr "Het pixmap-bestand %s kon niet worden gevonden" -#: ../gtk/main.c:137 +#: ../gtk/chat.c:196 ../gtk/chat.c:254 +msgid "Sending..." +msgstr "" + +#: ../gtk/chat.c:213 ../gtk/chat.c:263 +msgid "Message not sent" +msgstr "" + +#: ../gtk/chat.c:472 +msgid "Copy" +msgstr "" + +#: ../gtk/main.c:138 msgid "log to stdout some debug information while running." msgstr "loggen naar stdout om wat foutopsporingsinformatie te verkrijgen tijdens uitvoeren." -#: ../gtk/main.c:138 +#: ../gtk/main.c:139 +msgid "display version and exit." +msgstr "" + +#: ../gtk/main.c:140 msgid "path to a file to write logs into." msgstr "Pad naar een bestand om logbestanden heen te schrijven." -#: ../gtk/main.c:139 +#: ../gtk/main.c:141 msgid "Start linphone with video disabled." msgstr "Linphone opstarten met uitgeschakelde video." -#: ../gtk/main.c:140 +#: ../gtk/main.c:142 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 +#: ../gtk/main.c:143 msgid "address to call right now" msgstr "adres om nu naar toe te bellen" -#: ../gtk/main.c:142 +#: ../gtk/main.c:144 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:143 +#: ../gtk/main.c:145 msgid "Configuration file" msgstr "Configuratiebestand" -#: ../gtk/main.c:144 +#: ../gtk/main.c:146 msgid "Run the audio assistant" msgstr "Doorloop de audio-instelwizard" -#: ../gtk/main.c:145 +#: ../gtk/main.c:147 msgid "Run self test and exit 0 if succeed" msgstr "Draai een zelftest en exit 0 wanneer succesvol" -#: ../gtk/main.c:1070 +#: ../gtk/main.c:1046 #, c-format msgid "" -"%s would like to add you to his contact list.\n" -"Would you allow him to see your presence status or add him to your contact list ?\n" +"%s would like to add you to his/her contact list.\n" +"Would you add him/her to your contact list and allow him/her to see your presence status?\n" "If you answer no, this person will be temporarily blacklisted." -msgstr "%s wil u toevoegen aan zijn/haar contactpersonenlijst.\nWilt u toestaan dat hij/zij uw aanwezigheidsstatus ziet of hem/haar toevoegen aan uw contactpersonenljst?\nIndien u nee antwoordt, zal deze persoon tijdelijk op de zwarte lijst worden gezet." +msgstr "" -#: ../gtk/main.c:1147 +#: ../gtk/main.c:1123 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" msgstr "Vul uw wachtwoord in voor gebruikersnaam %s\nop realm %s" -#: ../gtk/main.c:1268 +#: ../gtk/main.c:1253 msgid "Call error" msgstr "Oproepfout" -#: ../gtk/main.c:1271 ../coreapi/linphonecore.c:3846 +#: ../gtk/main.c:1256 ../coreapi/linphonecore.c:3813 msgid "Call ended" msgstr "Oproep beëindigd" -#: ../gtk/main.c:1274 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1259 ../coreapi/call_log.c:235 msgid "Incoming call" msgstr "Inkomende oproep" -#: ../gtk/main.c:1276 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1261 ../gtk/incall_view.c:580 ../gtk/in_call_frame.ui.h:2 msgid "Answer" msgstr "Opnemen" -#: ../gtk/main.c:1278 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1263 ../gtk/in_call_frame.ui.h:3 msgid "Decline" msgstr "Weigeren" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 msgid "Call paused" msgstr "Oproep gepauzeerd" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 #, c-format msgid "by %s" msgstr "door %s" -#: ../gtk/main.c:1354 +#: ../gtk/main.c:1339 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "%s stelt u voor om video in te schakelen. Wilt u dit accepteren?" -#: ../gtk/main.c:1509 +#: ../gtk/main.c:1505 msgid "Website link" msgstr "Websitelink" -#: ../gtk/main.c:1568 ../gtk/waiting.ui.h:1 +#: ../gtk/main.c:1564 ../gtk/waiting.ui.h:1 msgid "Linphone" msgstr "Linphone" -#: ../gtk/main.c:1569 +#: ../gtk/main.c:1565 msgid "A video internet phone" msgstr "" -#: ../gtk/main.c:1629 +#: ../gtk/main.c:1624 #, c-format msgid "%s (Default)" msgstr "%s (Standaard)" -#: ../gtk/main.c:1962 ../coreapi/callbacks.c:1063 +#: ../gtk/main.c:1960 ../coreapi/callbacks.c:1075 #, c-format msgid "We are transferred to %s" msgstr "We zijn overgeschakeld naar %s" -#: ../gtk/main.c:1972 +#: ../gtk/main.c:1970 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.\nU zult niet in staat zijn om audio-oproepen te ontvangen of versturen." -#: ../gtk/main.c:2117 +#: ../gtk/main.c:2129 msgid "A free SIP video-phone" msgstr "Een gratis SIP-videotelefoon" -#: ../gtk/main.c:2221 +#: ../gtk/main.c:2242 #, c-format msgid "Hello\n" msgstr "" -#: ../gtk/friendlist.c:505 +#: ../gtk/friendlist.c:461 msgid "Add to addressbook" msgstr "Toevoegen aan adresboek" -#: ../gtk/friendlist.c:691 -msgid "Presence status" -msgstr "Aanwezigheidsstatus" - -#: ../gtk/friendlist.c:709 ../gtk/propertybox.c:569 ../gtk/contact.ui.h:1 -msgid "Name" -msgstr "Naam" - -#: ../gtk/friendlist.c:721 -msgid "Call" -msgstr "Bellen" - -#: ../gtk/friendlist.c:726 -msgid "Chat" -msgstr "Chatten" - -#: ../gtk/friendlist.c:756 +#: ../gtk/friendlist.c:627 #, c-format msgid "Search in %s directory" msgstr "Zoeken in de map %s" -#: ../gtk/friendlist.c:924 +#: ../gtk/friendlist.c:772 msgid "Invalid sip contact !" msgstr "Ongeldig SIP-contactpersoon" -#: ../gtk/friendlist.c:976 +#: ../gtk/friendlist.c:820 +#, c-format +msgid "Add a new contact" +msgstr "" + +#: ../gtk/friendlist.c:823 #, c-format msgid "Edit contact '%s'" msgstr "Contactpersoon '%s' bewerken" -#: ../gtk/friendlist.c:977 +#: ../gtk/friendlist.c:824 #, c-format msgid "Delete contact '%s'" msgstr "Contactpersoon '%s' verwijderen" -#: ../gtk/friendlist.c:978 +#: ../gtk/friendlist.c:825 #, c-format msgid "Delete chat history of '%s'" msgstr "Chatgeschiedenis van '%s' verwijderen" -#: ../gtk/friendlist.c:1029 +#: ../gtk/friendlist.c:862 #, c-format msgid "Add new contact from %s directory" msgstr "Nieuw contactpersoon toevoegen vanuit de map %s" -#: ../gtk/propertybox.c:575 +#: ../gtk/propertybox.c:592 ../gtk/contact.ui.h:1 +msgid "Name" +msgstr "Naam" + +#: ../gtk/propertybox.c:598 msgid "Rate (Hz)" msgstr "Frequentie (Hz)" -#: ../gtk/propertybox.c:581 +#: ../gtk/propertybox.c:604 msgid "Status" msgstr "Status" -#: ../gtk/propertybox.c:587 +#: ../gtk/propertybox.c:617 msgid "IP Bitrate (kbit/s)" msgstr "IP-bitrate (kbit/s)" -#: ../gtk/propertybox.c:596 +#: ../gtk/propertybox.c:628 msgid "Parameters" msgstr "Argumenten" -#: ../gtk/propertybox.c:639 ../gtk/propertybox.c:782 +#: ../gtk/propertybox.c:670 ../gtk/propertybox.c:824 msgid "Enabled" msgstr "Ingeschakeld" -#: ../gtk/propertybox.c:641 ../gtk/propertybox.c:782 ../gtk/parameters.ui.h:20 +#: ../gtk/propertybox.c:672 ../gtk/propertybox.c:824 ../gtk/parameters.ui.h:60 msgid "Disabled" msgstr "Uitgeschakeld" -#: ../gtk/propertybox.c:828 +#: ../gtk/propertybox.c:902 msgid "Account" msgstr "Account" -#: ../gtk/propertybox.c:1091 +#: ../gtk/propertybox.c:1170 msgid "English" msgstr "Engels" -#: ../gtk/propertybox.c:1092 +#: ../gtk/propertybox.c:1171 msgid "French" msgstr "Frans" -#: ../gtk/propertybox.c:1093 +#: ../gtk/propertybox.c:1172 msgid "Swedish" msgstr "Zweeds" -#: ../gtk/propertybox.c:1094 +#: ../gtk/propertybox.c:1173 msgid "Italian" msgstr "Italiaans" -#: ../gtk/propertybox.c:1095 +#: ../gtk/propertybox.c:1174 msgid "Spanish" msgstr "Spaans" -#: ../gtk/propertybox.c:1096 +#: ../gtk/propertybox.c:1175 msgid "Brazilian Portugese" msgstr "Braziliaans Portugees" -#: ../gtk/propertybox.c:1097 +#: ../gtk/propertybox.c:1176 msgid "Polish" msgstr "Pools" -#: ../gtk/propertybox.c:1098 +#: ../gtk/propertybox.c:1177 msgid "German" msgstr "Duits" -#: ../gtk/propertybox.c:1099 +#: ../gtk/propertybox.c:1178 msgid "Russian" msgstr "Russisch" -#: ../gtk/propertybox.c:1100 +#: ../gtk/propertybox.c:1179 msgid "Japanese" msgstr "Japans" -#: ../gtk/propertybox.c:1101 +#: ../gtk/propertybox.c:1180 msgid "Dutch" msgstr "Nederlands" -#: ../gtk/propertybox.c:1102 +#: ../gtk/propertybox.c:1181 msgid "Hungarian" msgstr "Hongaars" -#: ../gtk/propertybox.c:1103 +#: ../gtk/propertybox.c:1182 msgid "Czech" msgstr "Tjechisch" -#: ../gtk/propertybox.c:1104 +#: ../gtk/propertybox.c:1183 msgid "Chinese" msgstr "Chinees" -#: ../gtk/propertybox.c:1105 +#: ../gtk/propertybox.c:1184 msgid "Traditional Chinese" msgstr "Traditioneel Chinees" -#: ../gtk/propertybox.c:1106 +#: ../gtk/propertybox.c:1185 msgid "Norwegian" msgstr "Noors" -#: ../gtk/propertybox.c:1107 +#: ../gtk/propertybox.c:1186 msgid "Hebrew" msgstr "Hebreeuws" -#: ../gtk/propertybox.c:1108 +#: ../gtk/propertybox.c:1187 msgid "Serbian" msgstr "Servisch" -#: ../gtk/propertybox.c:1175 +#: ../gtk/propertybox.c:1188 +msgid "Arabic" +msgstr "" + +#: ../gtk/propertybox.c:1189 +msgid "Turkish" +msgstr "" + +#: ../gtk/propertybox.c:1246 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:1255 +#: ../gtk/propertybox.c:1326 msgid "None" msgstr "Geen" -#: ../gtk/propertybox.c:1259 +#: ../gtk/propertybox.c:1330 msgid "SRTP" msgstr "SRTP" -#: ../gtk/propertybox.c:1265 +#: ../gtk/propertybox.c:1336 msgid "DTLS" msgstr "DTLS" -#: ../gtk/propertybox.c:1272 +#: ../gtk/propertybox.c:1343 msgid "ZRTP" msgstr "ZRTP" @@ -420,324 +446,195 @@ msgid_plural "Found %i contacts" msgstr[0] "%i contactpersoon gevonden" msgstr[1] "%i contactpersonen gevonden" -#: ../gtk/setupwizard.c:32 -msgid "" -"Welcome!\n" -"This assistant will help you to use a SIP account for your calls." -msgstr "Welkom!\nDeze instelwizard zal u begeleiden bij het gebruiken van een SIP-account voor oproepen." - -#: ../gtk/setupwizard.c:41 -msgid "Create an account on linphone.org" -msgstr "Creëer een account op linphone.org" - -#: ../gtk/setupwizard.c:42 -msgid "I have already a linphone.org account and I just want to use it" -msgstr "Ik heb al een linphone.org-account en wil deze graag gebruiken" - -#: ../gtk/setupwizard.c:43 -msgid "I have already a sip account and I just want to use it" -msgstr "Ik heb al een SIP-account en wil deze graag gebruiken" - -#: ../gtk/setupwizard.c:44 -msgid "I want to specify a remote configuration URI" -msgstr "Ik wil een externe URI-configuratie opgeven" - -#: ../gtk/setupwizard.c:87 -msgid "Enter your linphone.org username" -msgstr "Vul uw linphone.org-gebruikersnaam in" - -#: ../gtk/setupwizard.c:100 ../gtk/parameters.ui.h:85 ../gtk/ldap.ui.h:4 -msgid "Username:" -msgstr "Gebruikersnaam:" - -#: ../gtk/setupwizard.c:102 ../gtk/password.ui.h:4 ../gtk/ldap.ui.h:5 -msgid "Password:" -msgstr "Wachtwoord:" - -#: ../gtk/setupwizard.c:122 -msgid "Enter your account informations" -msgstr "Vul uw accountinformatie in" - -#: ../gtk/setupwizard.c:138 -msgid "Username*" -msgstr "Gebruikersnaam*" - -#: ../gtk/setupwizard.c:139 -msgid "Password*" -msgstr "Wachtwoord*" - -#: ../gtk/setupwizard.c:142 -msgid "Domain*" -msgstr "Domeinnaam*" - -#: ../gtk/setupwizard.c:143 -msgid "Proxy" -msgstr "Proxy" - -#: ../gtk/setupwizard.c:322 -msgid "(*) Required fields" -msgstr "(*) Verplichte velden" - -#: ../gtk/setupwizard.c:323 -msgid "Username: (*)" -msgstr "Gebruikersnaam: (*)" - -#: ../gtk/setupwizard.c:325 -msgid "Password: (*)" -msgstr "Wachtwoord: (*)" - -#: ../gtk/setupwizard.c:327 -msgid "Email: (*)" -msgstr "E-mailadres: (*)" - -#: ../gtk/setupwizard.c:329 -msgid "Confirm your password: (*)" -msgstr "Bevestig uw wachtwoord: (*)" - -#: ../gtk/setupwizard.c:343 -msgid "Keep me informed with linphone updates" -msgstr "Houdt me op de hoogte van linphone-updates" - -#: ../gtk/setupwizard.c:399 -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.\nGa terug en probeer het opnieuw." - -#: ../gtk/setupwizard.c:410 -msgid "Thank you. Your account is now configured and ready for use." -msgstr "Bedankt. Uw account is nu ingesteld en klaar voor gebruik." - -#: ../gtk/setupwizard.c:418 -msgid "" -"Please validate your account by clicking on the link we just sent you by 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.\nKom dan terug naar dit venster en klik op de knop Volgende." - -#: ../gtk/setupwizard.c:609 -msgid "SIP account configuration assistant" -msgstr "SIP-account-instelwizard" - -#: ../gtk/setupwizard.c:629 -msgid "Welcome to the account setup assistant" -msgstr "Welkom bij de account-instelwizard" - -#: ../gtk/setupwizard.c:634 -msgid "Account setup assistant" -msgstr "Account-instelwizard" - -#: ../gtk/setupwizard.c:640 -msgid "Configure your account (step 1/1)" -msgstr "Uw account instellen (stap 1/1)" - -#: ../gtk/setupwizard.c:645 -msgid "Enter your sip username (step 1/1)" -msgstr "Vul uw SIP-gebruikersnaam in (stap 1/1)" - -#: ../gtk/setupwizard.c:649 -msgid "Enter account information (step 1/2)" -msgstr "Vul uw accountinformatie in (stap 1/2)" - -#: ../gtk/setupwizard.c:658 -msgid "Validation (step 2/2)" -msgstr "Geldigheid (stap 2/2)" - -#: ../gtk/setupwizard.c:663 -msgid "Error" -msgstr "Fout" - -#: ../gtk/setupwizard.c:667 ../gtk/audio_assistant.c:534 -msgid "Terminating" -msgstr "Bezig met vernietigen" - -#: ../gtk/incall_view.c:70 ../gtk/incall_view.c:94 +#: ../gtk/incall_view.c:67 ../gtk/incall_view.c:87 #, c-format msgid "Call #%i" msgstr "#%i bellen" -#: ../gtk/incall_view.c:155 +#: ../gtk/incall_view.c:145 #, c-format msgid "Transfer to call #%i with %s" msgstr "Overschakelen naar gesprek #%i met %s" -#: ../gtk/incall_view.c:211 ../gtk/incall_view.c:214 +#: ../gtk/incall_view.c:202 ../gtk/incall_view.c:205 msgid "Not used" msgstr "Niet in gebruik" -#: ../gtk/incall_view.c:221 +#: ../gtk/incall_view.c:212 msgid "ICE not activated" msgstr "ICE is niet geactiveerd" -#: ../gtk/incall_view.c:223 +#: ../gtk/incall_view.c:214 msgid "ICE failed" msgstr "ICE is mislukt" -#: ../gtk/incall_view.c:225 +#: ../gtk/incall_view.c:216 msgid "ICE in progress" msgstr "ICE is bezig" -#: ../gtk/incall_view.c:227 +#: ../gtk/incall_view.c:218 msgid "Going through one or more NATs" msgstr "Die door één of meer NATs gaan" -#: ../gtk/incall_view.c:229 +#: ../gtk/incall_view.c:220 msgid "Direct" msgstr "Direct" -#: ../gtk/incall_view.c:231 +#: ../gtk/incall_view.c:222 msgid "Through a relay server" msgstr "Via een relay-server" -#: ../gtk/incall_view.c:239 +#: ../gtk/incall_view.c:230 msgid "uPnP not activated" msgstr "uPnP is niet geactiveerd" -#: ../gtk/incall_view.c:241 +#: ../gtk/incall_view.c:232 msgid "uPnP in progress" msgstr "uPnP is bezig" -#: ../gtk/incall_view.c:243 +#: ../gtk/incall_view.c:234 msgid "uPnp not available" msgstr "uPnP is niet beschikbaar" -#: ../gtk/incall_view.c:245 +#: ../gtk/incall_view.c:236 msgid "uPnP is running" msgstr "uPnP wordt uitgevoerd" -#: ../gtk/incall_view.c:247 +#: ../gtk/incall_view.c:238 msgid "uPnP failed" msgstr "uPnP is mislukt" -#: ../gtk/incall_view.c:257 ../gtk/incall_view.c:258 +#: ../gtk/incall_view.c:248 ../gtk/incall_view.c:249 msgid "Direct or through server" msgstr "Direct of via een server" -#: ../gtk/incall_view.c:267 ../gtk/incall_view.c:279 +#: ../gtk/incall_view.c:258 ../gtk/incall_view.c:270 #, c-format msgid "" "download: %f\n" "upload: %f (kbit/s)" msgstr "download: %f\nupload: %f (kbit/s)" -#: ../gtk/incall_view.c:272 ../gtk/incall_view.c:274 +#: ../gtk/incall_view.c:263 ../gtk/incall_view.c:265 #, c-format msgid "%ix%i @ %f fps" msgstr "%ix%i @ %f fps" -#: ../gtk/incall_view.c:304 +#: ../gtk/incall_view.c:295 #, c-format msgid "%.3f seconds" msgstr "%.3f seconden" -#: ../gtk/incall_view.c:407 ../gtk/main.ui.h:12 ../gtk/videowindow.c:235 +#: ../gtk/incall_view.c:453 ../gtk/in_call_frame.ui.h:10 +#: ../gtk/videowindow.c:236 msgid "Hang up" msgstr "Ophangen" -#: ../gtk/incall_view.c:511 +#: ../gtk/incall_view.c:559 msgid "Calling..." msgstr "Bezig met bellen..." -#: ../gtk/incall_view.c:514 ../gtk/incall_view.c:733 -msgid "00::00::00" -msgstr "00::00::00" +#: ../gtk/incall_view.c:562 ../gtk/incall_view.c:792 +msgid "00:00:00" +msgstr "" -#: ../gtk/incall_view.c:525 +#: ../gtk/incall_view.c:573 msgid "Incoming call" msgstr "Inkomende oproep" -#: ../gtk/incall_view.c:562 +#: ../gtk/incall_view.c:610 msgid "good" msgstr "goed" -#: ../gtk/incall_view.c:564 +#: ../gtk/incall_view.c:612 msgid "average" msgstr "gemiddeld" -#: ../gtk/incall_view.c:566 +#: ../gtk/incall_view.c:614 msgid "poor" msgstr "slecht" -#: ../gtk/incall_view.c:568 +#: ../gtk/incall_view.c:616 msgid "very poor" msgstr "erg slecht" -#: ../gtk/incall_view.c:570 +#: ../gtk/incall_view.c:618 msgid "too bad" msgstr "verschrikkelijk" -#: ../gtk/incall_view.c:571 ../gtk/incall_view.c:587 +#: ../gtk/incall_view.c:619 ../gtk/incall_view.c:635 msgid "unavailable" msgstr "niet beschikbaar" -#: ../gtk/incall_view.c:679 +#: ../gtk/incall_view.c:731 msgid "Secured by SRTP" msgstr "Beveiligd door SRTP" -#: ../gtk/incall_view.c:685 +#: ../gtk/incall_view.c:737 msgid "Secured by DTLS" msgstr "Beveiligd door DTLS" -#: ../gtk/incall_view.c:691 +#: ../gtk/incall_view.c:743 #, c-format msgid "Secured by ZRTP - [auth token: %s]" msgstr "Beveiligd door ZRTP - [authenticatiesleutel: %s]" -#: ../gtk/incall_view.c:697 +#: ../gtk/incall_view.c:747 msgid "Set unverified" msgstr "Instellen als niet-geverifieerd" -#: ../gtk/incall_view.c:697 ../gtk/main.ui.h:4 +#: ../gtk/incall_view.c:747 msgid "Set verified" msgstr "Instellen als geverifieerd" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In conference" msgstr "In een vergadering" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In call" msgstr "In gesprek" -#: ../gtk/incall_view.c:764 +#: ../gtk/incall_view.c:824 msgid "Paused call" msgstr "Gepauzeerde oproep" -#: ../gtk/incall_view.c:800 +#: ../gtk/incall_view.c:861 msgid "Call ended." msgstr "Oproep is beëindigd." -#: ../gtk/incall_view.c:831 +#: ../gtk/incall_view.c:892 msgid "Transfer in progress" msgstr "De overdracht is bezig" -#: ../gtk/incall_view.c:834 +#: ../gtk/incall_view.c:895 msgid "Transfer done." msgstr "De overdracht is voltooid." -#: ../gtk/incall_view.c:837 +#: ../gtk/incall_view.c:898 msgid "Transfer failed." msgstr "De overdracht is mislukt." -#: ../gtk/incall_view.c:881 +#: ../gtk/incall_view.c:929 msgid "Resume" msgstr "Hervatten" -#: ../gtk/incall_view.c:888 ../gtk/main.ui.h:9 +#: ../gtk/incall_view.c:929 ../gtk/in_call_frame.ui.h:7 msgid "Pause" msgstr "Pauzeren" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 #, c-format msgid "" "Recording into\n" "%s %s" msgstr "Bezig met opnemen naar%s %s" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 msgid "(Paused)" msgstr "(Gepauzeerd)" -#: ../gtk/loginframe.c:87 +#: ../gtk/loginframe.c:75 #, c-format msgid "Please enter login information for %s" msgstr "Vul uw inloggegevens in voor %s" @@ -752,263 +649,108 @@ msgstr "bezig met ophalen van %s" msgid "Downloading of remote configuration from %s failed." msgstr "Het downloaden van de externe configuratie van %s is mislukt." -#: ../gtk/audio_assistant.c:98 +#: ../gtk/audio_assistant.c:103 msgid "No voice detected" msgstr "Er is geen stem gedetecteerd" -#: ../gtk/audio_assistant.c:99 +#: ../gtk/audio_assistant.c:104 msgid "Too low" msgstr "Te zacht" -#: ../gtk/audio_assistant.c:100 +#: ../gtk/audio_assistant.c:105 msgid "Good" msgstr "Goed" -#: ../gtk/audio_assistant.c:101 +#: ../gtk/audio_assistant.c:106 msgid "Too loud" msgstr "Te hard" -#: ../gtk/audio_assistant.c:183 +#: ../gtk/audio_assistant.c:188 msgid "Did you hear three beeps ?" msgstr "Heeft u drie pieptonen gehoord?" -#: ../gtk/audio_assistant.c:292 ../gtk/audio_assistant.c:297 +#: ../gtk/audio_assistant.c:299 ../gtk/audio_assistant.c:304 msgid "Sound preferences not found " msgstr "De geluidsvoorkeuren zijn niet gevonden" -#: ../gtk/audio_assistant.c:306 +#: ../gtk/audio_assistant.c:313 msgid "Cannot launch system sound control " msgstr "Het systeemgeluidspaneel kon niet worden gestart" -#: ../gtk/audio_assistant.c:318 +#: ../gtk/audio_assistant.c:325 msgid "" "Welcome!\n" "This assistant will help you to configure audio settings for Linphone" msgstr "Welkom!\nDeze instelwizard zal u begeleiden bij het instellen van de audio-instellingen van Linphone" -#: ../gtk/audio_assistant.c:328 +#: ../gtk/audio_assistant.c:335 msgid "Capture device" msgstr "Opname-apparaat" -#: ../gtk/audio_assistant.c:329 +#: ../gtk/audio_assistant.c:336 msgid "Recorded volume" msgstr "Opgenomen volume" -#: ../gtk/audio_assistant.c:333 +#: ../gtk/audio_assistant.c:340 msgid "No voice" msgstr "Geen stem" -#: ../gtk/audio_assistant.c:334 ../gtk/audio_assistant.c:373 +#: ../gtk/audio_assistant.c:341 ../gtk/audio_assistant.c:380 msgid "System sound preferences" msgstr "Systeemgeluidsinstellingen" -#: ../gtk/audio_assistant.c:369 +#: ../gtk/audio_assistant.c:376 msgid "Playback device" msgstr "Afspeelapparaat" -#: ../gtk/audio_assistant.c:370 +#: ../gtk/audio_assistant.c:377 msgid "Play three beeps" msgstr "Drie pieptonen afspelen" -#: ../gtk/audio_assistant.c:403 +#: ../gtk/audio_assistant.c:410 msgid "Press the record button and say some words" msgstr "Klik op de opnameknop en zeg enkele woorden" -#: ../gtk/audio_assistant.c:404 +#: ../gtk/audio_assistant.c:411 msgid "Listen to your record voice" msgstr "Luister naar uw opgenomen stem" -#: ../gtk/audio_assistant.c:405 +#: ../gtk/audio_assistant.c:412 ../gtk/conf_frame.ui.h:2 +#: ../gtk/in_call_frame.ui.h:4 msgid "Record" msgstr "Opnemen" -#: ../gtk/audio_assistant.c:406 +#: ../gtk/audio_assistant.c:413 msgid "Play" msgstr "Afspelen" -#: ../gtk/audio_assistant.c:433 +#: ../gtk/audio_assistant.c:440 msgid "Let's start Linphone now" msgstr "Laten we nu Linphone opstarten" -#: ../gtk/audio_assistant.c:503 +#: ../gtk/audio_assistant.c:510 msgid "Audio Assistant" msgstr "Audio-instelwizard" -#: ../gtk/audio_assistant.c:513 ../gtk/main.ui.h:32 +#: ../gtk/audio_assistant.c:520 ../gtk/main.ui.h:13 msgid "Audio assistant" msgstr "Audio-instelwizard" -#: ../gtk/audio_assistant.c:518 +#: ../gtk/audio_assistant.c:525 msgid "Mic Gain calibration" msgstr "Kalibratie van het microfoonbereik" -#: ../gtk/audio_assistant.c:524 +#: ../gtk/audio_assistant.c:531 msgid "Speaker volume calibration" msgstr "Kalibratie van het luidsprekervolume" -#: ../gtk/audio_assistant.c:529 +#: ../gtk/audio_assistant.c:536 msgid "Record and Play" msgstr "Opnemen en afspelen" -#: ../gtk/main.ui.h:1 -msgid "Callee name" -msgstr "Bellernaam" - -#: ../gtk/main.ui.h:2 -msgid "Send" -msgstr "Verzenden" - -#: ../gtk/main.ui.h:3 -msgid "End conference" -msgstr "Vergadering beëindigen" - -#: ../gtk/main.ui.h:7 -msgid "Record this call to an audio file" -msgstr "Deze oproep opnemen naar een audiobestand" - -#: ../gtk/main.ui.h:8 -msgid "Video" -msgstr "Video" - -#: ../gtk/main.ui.h:10 -msgid "Mute" -msgstr "Dempen" - -#: ../gtk/main.ui.h:11 -msgid "Transfer" -msgstr "Overdracht" - -#: ../gtk/main.ui.h:14 -msgid "In call" -msgstr "In gesprek" - -#: ../gtk/main.ui.h:15 -msgid "Duration" -msgstr "Duur" - -#: ../gtk/main.ui.h:16 -msgid "Call quality rating" -msgstr "Waardering van de gesprekskwaliteit" - -#: ../gtk/main.ui.h:17 -msgid "All users" -msgstr "Alle gebruikers" - -#: ../gtk/main.ui.h:18 -msgid "Online users" -msgstr "Online gebruikers" - -#: ../gtk/main.ui.h:19 -msgid "ADSL" -msgstr "ADSL" - -#: ../gtk/main.ui.h:20 -msgid "Fiber Channel" -msgstr "Fiber-kanaal" - -#: ../gtk/main.ui.h:21 -msgid "Default" -msgstr "Standaard" - -#: ../gtk/main.ui.h:22 -msgid "Delete" -msgstr "Verwijderen" - -#: ../gtk/main.ui.h:23 -msgid "_Options" -msgstr "_Opties" - -#: ../gtk/main.ui.h:24 -msgid "Set configuration URI" -msgstr "Configuratie-URI instellen" - -#: ../gtk/main.ui.h:25 -msgid "Always start video" -msgstr "Video altijd starten" - -#: ../gtk/main.ui.h:26 -msgid "Enable self-view" -msgstr "Eigen weergave inschakelen" - -#: ../gtk/main.ui.h:27 -msgid "_Help" -msgstr "_Hulp" - -#: ../gtk/main.ui.h:28 -msgid "Show debug window" -msgstr "Foutopsporingsvenster weergeven" - -#: ../gtk/main.ui.h:29 -msgid "_Homepage" -msgstr "_Website" - -#: ../gtk/main.ui.h:30 -msgid "Check _Updates" -msgstr "Controleren op _updates" - -#: ../gtk/main.ui.h:31 -msgid "Account assistant" -msgstr "Account-instelwizard" - -#: ../gtk/main.ui.h:33 -msgid "SIP address or phone number:" -msgstr "SIP-adres of telefoonnummer:" - -#: ../gtk/main.ui.h:34 -msgid "Initiate a new call" -msgstr "Een nieuw gesprek beginnen" - -#: ../gtk/main.ui.h:35 -msgid "Contacts" -msgstr "Contactpersonen" - -#: ../gtk/main.ui.h:36 -msgid "Search" -msgstr "Zoeken" - -#: ../gtk/main.ui.h:37 -msgid "Add contacts from directory" -msgstr "Voeg contactpersonen toe uit map" - -#: ../gtk/main.ui.h:38 -msgid "Add contact" -msgstr "Contactpersoon toevoegen" - -#: ../gtk/main.ui.h:39 -msgid "Recent calls" -msgstr "Recente gesprekken" - -#: ../gtk/main.ui.h:40 -msgid "My current identity:" -msgstr "Mijn huidige identiteit:" - -#: ../gtk/main.ui.h:41 ../gtk/tunnel_config.ui.h:7 -msgid "Username" -msgstr "Gebruikersnaam" - -#: ../gtk/main.ui.h:42 ../gtk/tunnel_config.ui.h:8 -msgid "Password" -msgstr "Wachtwoord" - -#: ../gtk/main.ui.h:43 -msgid "Internet connection:" -msgstr "Internetverbinding:" - -#: ../gtk/main.ui.h:44 -msgid "Automatically log me in" -msgstr "Automatisch inloggen" - -#: ../gtk/main.ui.h:45 ../gtk/password.ui.h:3 -msgid "UserID" -msgstr "Gebruikersidentificatie" - -#: ../gtk/main.ui.h:46 -msgid "Login information" -msgstr "Inloginformatie" - -#: ../gtk/main.ui.h:47 -msgid "Welcome!" -msgstr "Welkom!" +#: ../gtk/audio_assistant.c:541 ../gtk/setup_wizard.ui.h:38 +msgid "Terminating" +msgstr "Bezig met vernietigen" #: ../gtk/about.ui.h:1 msgid "About Linphone" @@ -1038,456 +780,6 @@ msgid "" "he: Eli Zaretskii \n" msgstr "fr: Simon Morlat\nen: Simon Morlat and Delphine Perreau\nit: Alberto Zanoni \nde: Jean-Jacques Sarton \nsv: Daniel Nylander \nes: Jesus Benitez \nja: YAMAGUCHI YOSHIYA \npt_BR: Rafael Caesar Lenzi \npl: Robert Nasiadek \ncs: Petr Pisar \nhu: anonymous\nhe: Eli Zaretskii \n" -#: ../gtk/contact.ui.h:2 -msgid "SIP Address" -msgstr "SIP-adres" - -#: ../gtk/contact.ui.h:3 -msgid "Show this contact presence status" -msgstr "De aanwezigheidsstatus van dit contactpersoon weergeven" - -#: ../gtk/contact.ui.h:4 -msgid "Allow this contact to see my presence status" -msgstr "Toestaan dat deze contactpersoon mijn aanwezigheidsstatus kan weergeven" - -#: ../gtk/contact.ui.h:5 -msgid "Contact information" -msgstr "Contactinformatie" - -#: ../gtk/log.ui.h:1 -msgid "Linphone debug window" -msgstr "Linphone-foutopsporingsvenster" - -#: ../gtk/log.ui.h:2 -msgid "Scroll to end" -msgstr "Scroll naar het einde" - -#: ../gtk/password.ui.h:1 -msgid "Linphone - Authentication required" -msgstr "Linphone - Authenticatie is vereist" - -#: ../gtk/password.ui.h:2 -msgid "Please enter the domain password" -msgstr "Vul het domeinnaamwachtwoord in" - -#: ../gtk/call_logs.ui.h:1 -msgid "Call history" -msgstr "Gespreksgeschiedenis" - -#: ../gtk/call_logs.ui.h:2 -msgid "Clear all" -msgstr "Alles wissen" - -#: ../gtk/call_logs.ui.h:3 -msgid "Call back" -msgstr "Terugbellen" - -#: ../gtk/sip_account.ui.h:1 -msgid "Linphone - Configure a SIP account" -msgstr "Linphone - Een SIP-account instellen" - -#: ../gtk/sip_account.ui.h:2 -msgid "Your SIP identity:" -msgstr "Uw SIP-identiteit:" - -#: ../gtk/sip_account.ui.h:3 -msgid "Looks like sip:@" -msgstr "Lijkt op:@" - -#: ../gtk/sip_account.ui.h:4 -msgid "sip:" -msgstr "sip:" - -#: ../gtk/sip_account.ui.h:5 -msgid "SIP Proxy address:" -msgstr "SIP-proxyadres:" - -#: ../gtk/sip_account.ui.h:6 -msgid "Looks like sip:" -msgstr "Lijkt op sip:" - -#: ../gtk/sip_account.ui.h:7 -msgid "Registration duration (sec):" -msgstr "Registratieduur (sec):" - -#: ../gtk/sip_account.ui.h:8 -msgid "Contact params (optional):" -msgstr "Contactparameters (optioneel):" - -#: ../gtk/sip_account.ui.h:9 -msgid "AVPF regular RTCP interval (sec):" -msgstr "AVPF regulier RTCP-tussenpose (sec):" - -#: ../gtk/sip_account.ui.h:10 -msgid "Route (optional):" -msgstr "Route (optioneel):" - -#: ../gtk/sip_account.ui.h:11 -msgid "Transport" -msgstr "Overdracht" - -#: ../gtk/sip_account.ui.h:12 -msgid "Register" -msgstr "Registreren" - -#: ../gtk/sip_account.ui.h:13 -msgid "Publish presence information" -msgstr "Aanwezigheidsinformatie publiceren" - -#: ../gtk/sip_account.ui.h:14 -msgid "Enable AVPF" -msgstr "AVPF inschakelen" - -#: ../gtk/sip_account.ui.h:15 -msgid "Configure a SIP account" -msgstr "Een SIP-account instellen" - -#: ../gtk/parameters.ui.h:1 -msgid "anonymous" -msgstr "anoniem" - -#: ../gtk/parameters.ui.h:2 -msgid "GSSAPI" -msgstr "GSSAPI" - -#: ../gtk/parameters.ui.h:3 -msgid "SASL" -msgstr "SASL" - -#: ../gtk/parameters.ui.h:4 -msgid "default soundcard" -msgstr "standaard geluidskaart" - -#: ../gtk/parameters.ui.h:5 -msgid "a sound card" -msgstr "een geluidskaart" - -#: ../gtk/parameters.ui.h:6 -msgid "default camera" -msgstr "standaard camera" - -#: ../gtk/parameters.ui.h:7 -msgid "CIF" -msgstr "CIF" - -#: ../gtk/parameters.ui.h:8 -msgid "Audio codecs" -msgstr "Audio-codecs" - -#: ../gtk/parameters.ui.h:9 -msgid "Video codecs" -msgstr "Video-codecs" - -#: ../gtk/parameters.ui.h:10 -msgid "C" -msgstr "C" - -#: ../gtk/parameters.ui.h:11 -msgid "SIP (UDP)" -msgstr "" - -#: ../gtk/parameters.ui.h:12 -msgid "SIP (TCP)" -msgstr "" - -#: ../gtk/parameters.ui.h:13 -msgid "SIP (TLS)" -msgstr "" - -#: ../gtk/parameters.ui.h:14 -msgid "Settings" -msgstr "Instellingen" - -#: ../gtk/parameters.ui.h:15 -msgid "Set Maximum Transmission Unit:" -msgstr "Maximale Transmissie-unit instellen:" - -#: ../gtk/parameters.ui.h:16 -msgid "Send DTMFs as SIP info" -msgstr "DTMF's als SIP-informatie versturen" - -#: ../gtk/parameters.ui.h:17 -msgid "Allow IPv6" -msgstr "" - -#: ../gtk/parameters.ui.h:18 -msgid "Transport" -msgstr "Overdracht" - -#: ../gtk/parameters.ui.h:19 -msgid "SIP/UDP port" -msgstr "SIP/UDP-poort" - -#: ../gtk/parameters.ui.h:21 -msgid "Random" -msgstr "Willekeurig" - -#: ../gtk/parameters.ui.h:22 -msgid "SIP/TCP port" -msgstr "SIP/TCP-poort" - -#: ../gtk/parameters.ui.h:23 -msgid "Audio RTP/UDP:" -msgstr "AUDIO RTP/UDP:" - -#: ../gtk/parameters.ui.h:24 -msgid "Fixed" -msgstr "Vastgezet" - -#: ../gtk/parameters.ui.h:25 -msgid "Video RTP/UDP:" -msgstr "Video RTP/UDP:" - -#: ../gtk/parameters.ui.h:26 -msgid "Media encryption type" -msgstr "Mediaversleutelingstype" - -#: ../gtk/parameters.ui.h:27 -msgid "Media encryption is mandatory" -msgstr "Mediaversleuteling is vereist" - -#: ../gtk/parameters.ui.h:28 -msgid "Tunnel" -msgstr "Tunnel" - -#: ../gtk/parameters.ui.h:29 -msgid "DSCP fields" -msgstr "DSCP-velden" - -#: ../gtk/parameters.ui.h:30 -msgid "Network protocol and ports" -msgstr "Netwerkprotocol en -poorten" - -#: ../gtk/parameters.ui.h:31 -msgid "Direct connection to the Internet" -msgstr "Directe verbinding met het internet" - -#: ../gtk/parameters.ui.h:32 -msgid "Behind NAT / Firewall (specify gateway IP )" -msgstr "Achter een NAT / Firewall (specificeer de gateway IP)" - -#: ../gtk/parameters.ui.h:33 -msgid "Behind NAT / Firewall (use STUN to resolve)" -msgstr "" - -#: ../gtk/parameters.ui.h:34 -msgid "Behind NAT / Firewall (use ICE)" -msgstr "" - -#: ../gtk/parameters.ui.h:35 -msgid "Behind NAT / Firewall (use uPnP)" -msgstr "" - -#: ../gtk/parameters.ui.h:36 -msgid "Public IP address:" -msgstr "Openbaar IP-adres:" - -#: ../gtk/parameters.ui.h:37 -msgid "Stun server:" -msgstr "Stun-server" - -#: ../gtk/parameters.ui.h:38 -msgid "NAT and Firewall" -msgstr "NAT en Firewall" - -#: ../gtk/parameters.ui.h:39 -msgid "Network settings" -msgstr "Netwerkinstellingen" - -#: ../gtk/parameters.ui.h:40 -msgid "Ring sound:" -msgstr "Belgeluid:" - -#: ../gtk/parameters.ui.h:41 -msgid "ALSA special device (optional):" -msgstr "ALSA speciaal apparaat (optioneel)" - -#: ../gtk/parameters.ui.h:42 -msgid "Capture device:" -msgstr "Opnameapparaat:" - -#: ../gtk/parameters.ui.h:43 -msgid "Ring device:" -msgstr "Belapparaat:" - -#: ../gtk/parameters.ui.h:44 -msgid "Playback device:" -msgstr "Afspeelapparaat:" - -#: ../gtk/parameters.ui.h:45 -msgid "Enable echo cancellation" -msgstr "Echo-onderdrukking inschakelen" - -#: ../gtk/parameters.ui.h:46 -msgid "Audio" -msgstr "Audio" - -#: ../gtk/parameters.ui.h:47 -msgid "Video input device:" -msgstr "Videoingang-apparaat:" - -#: ../gtk/parameters.ui.h:48 -msgid "Prefered video resolution:" -msgstr "Voorkeursvideoresolutie:" - -#: ../gtk/parameters.ui.h:49 -msgid "Video output method:" -msgstr "Videouitgangsmethode:" - -#: ../gtk/parameters.ui.h:50 -msgid "Show camera preview" -msgstr "Cameravoorbeeld weergeven" - -#: ../gtk/parameters.ui.h:51 -msgid "Video" -msgstr "Video" - -#: ../gtk/parameters.ui.h:52 -msgid "Multimedia settings" -msgstr "Multimedia-instellingen" - -#: ../gtk/parameters.ui.h:53 -msgid "This section defines your SIP address when not using a SIP account" -msgstr "" - -#: ../gtk/parameters.ui.h:54 -msgid "Your display name (eg: John Doe):" -msgstr "Uw weergavenaam (bijv.: Jan Noniem):" - -#: ../gtk/parameters.ui.h:55 -msgid "Your username:" -msgstr "Uw gebruikersnaam:" - -#: ../gtk/parameters.ui.h:56 -msgid "Your resulting SIP address:" -msgstr "" - -#: ../gtk/parameters.ui.h:57 -msgid "Default identity" -msgstr "Standaardidentiteit" - -#: ../gtk/parameters.ui.h:58 -msgid "Wizard" -msgstr "Instelhulp" - -#: ../gtk/parameters.ui.h:59 -msgid "Add" -msgstr "Toevoegen" - -#: ../gtk/parameters.ui.h:60 -msgid "Edit" -msgstr "Bewerken" - -#: ../gtk/parameters.ui.h:61 -msgid "Remove" -msgstr "Verwijderen" - -#: ../gtk/parameters.ui.h:62 -msgid "Proxy accounts" -msgstr "" - -#: ../gtk/parameters.ui.h:63 -msgid "Erase all passwords" -msgstr "" - -#: ../gtk/parameters.ui.h:64 -msgid "Privacy" -msgstr "" - -#: ../gtk/parameters.ui.h:65 -msgid "Automatically answer when a call is received" -msgstr "" - -#: ../gtk/parameters.ui.h:66 -msgid "Delay before answering (ms)" -msgstr "" - -#: ../gtk/parameters.ui.h:67 -msgid "Auto-answer" -msgstr "" - -#: ../gtk/parameters.ui.h:68 -msgid "Manage SIP Accounts" -msgstr "" - -#: ../gtk/parameters.ui.h:69 ../gtk/tunnel_config.ui.h:4 -msgid "Enable" -msgstr "Aan" - -#: ../gtk/parameters.ui.h:70 ../gtk/tunnel_config.ui.h:5 -msgid "Disable" -msgstr "Uit" - -#: ../gtk/parameters.ui.h:71 -msgid "Codecs" -msgstr "" - -#: ../gtk/parameters.ui.h:72 -msgid "0 stands for \"unlimited\"" -msgstr "" - -#: ../gtk/parameters.ui.h:73 -msgid "Upload speed limit in Kbit/sec:" -msgstr "" - -#: ../gtk/parameters.ui.h:74 -msgid "Download speed limit in Kbit/sec:" -msgstr "" - -#: ../gtk/parameters.ui.h:75 -msgid "Enable adaptive rate control" -msgstr "" - -#: ../gtk/parameters.ui.h:76 -msgid "" -"Adaptive rate control is a technique to dynamically guess the available " -"bandwidth during a call." -msgstr "" - -#: ../gtk/parameters.ui.h:77 -msgid "Bandwidth control" -msgstr "" - -#: ../gtk/parameters.ui.h:78 -msgid "Codecs" -msgstr "" - -#: ../gtk/parameters.ui.h:79 -msgid "Language" -msgstr "" - -#: ../gtk/parameters.ui.h:80 -msgid "Show advanced settings" -msgstr "" - -#: ../gtk/parameters.ui.h:81 -msgid "Level" -msgstr "" - -#: ../gtk/parameters.ui.h:82 -msgid "User interface" -msgstr "" - -#: ../gtk/parameters.ui.h:83 ../gtk/ldap.ui.h:2 -msgid "Server address:" -msgstr "" - -#: ../gtk/parameters.ui.h:84 ../gtk/ldap.ui.h:3 -msgid "Authentication method:" -msgstr "" - -#: ../gtk/parameters.ui.h:86 -msgid "LDAP Account setup" -msgstr "" - -#: ../gtk/parameters.ui.h:87 -msgid "LDAP" -msgstr "" - -#: ../gtk/parameters.ui.h:88 -msgid "Done" -msgstr "" - #: ../gtk/buddylookup.ui.h:1 msgid "Search contacts in directory" msgstr "" @@ -1500,29 +792,21 @@ msgstr "" msgid "Search somebody" msgstr "" -#: ../gtk/waiting.ui.h:2 -msgid "Please wait" -msgstr "" +#: ../gtk/callee_frame.ui.h:1 +msgid "Callee name" +msgstr "Bellernaam" -#: ../gtk/dscp_settings.ui.h:1 -msgid "DSCP settings" -msgstr "" +#: ../gtk/call_logs.ui.h:1 +msgid "Call history" +msgstr "Gespreksgeschiedenis" -#: ../gtk/dscp_settings.ui.h:2 -msgid "SIP" -msgstr "SIP" +#: ../gtk/call_logs.ui.h:2 +msgid "Clear all" +msgstr "Alles wissen" -#: ../gtk/dscp_settings.ui.h:3 -msgid "Audio RTP stream" -msgstr "" - -#: ../gtk/dscp_settings.ui.h:4 -msgid "Video RTP stream" -msgstr "" - -#: ../gtk/dscp_settings.ui.h:5 -msgid "Set DSCP values (in hexadecimal)" -msgstr "" +#: ../gtk/call_logs.ui.h:3 +msgid "Call back" +msgstr "Terugbellen" #: ../gtk/call_statistics.ui.h:1 msgid "Call statistics" @@ -1572,30 +856,112 @@ msgstr "" msgid "Call statistics and information" msgstr "" -#: ../gtk/tunnel_config.ui.h:1 -msgid "Configure VoIP tunnel" +#: ../gtk/chatroom_frame.ui.h:1 +msgid "Send" +msgstr "Verzenden" + +#: ../gtk/conf_frame.ui.h:1 +msgid "End conference" +msgstr "Vergadering beëindigen" + +#: ../gtk/config-uri.ui.h:1 +msgid "Specifying a remote configuration URI" msgstr "" -#: ../gtk/tunnel_config.ui.h:2 -msgid "Host" +#: ../gtk/config-uri.ui.h:2 +msgid "" +"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" +"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " msgstr "" -#: ../gtk/tunnel_config.ui.h:3 -msgid "Port" +#: ../gtk/contact.ui.h:2 +msgid "SIP Address" +msgstr "SIP-adres" + +#: ../gtk/contact.ui.h:3 +msgid "Show this contact presence status" +msgstr "De aanwezigheidsstatus van dit contactpersoon weergeven" + +#: ../gtk/contact.ui.h:4 +msgid "Allow this contact to see my presence status" +msgstr "Toestaan dat deze contactpersoon mijn aanwezigheidsstatus kan weergeven" + +#: ../gtk/contact.ui.h:5 +msgid "Contact information" +msgstr "Contactinformatie" + +#: ../gtk/dscp_settings.ui.h:1 +msgid "DSCP settings" msgstr "" -#: ../gtk/tunnel_config.ui.h:6 -msgid "Configure tunnel" +#: ../gtk/dscp_settings.ui.h:2 +msgid "SIP" +msgstr "SIP" + +#: ../gtk/dscp_settings.ui.h:3 +msgid "Audio RTP stream" msgstr "" -#: ../gtk/tunnel_config.ui.h:9 -msgid "Configure http proxy (optional)" +#: ../gtk/dscp_settings.ui.h:4 +msgid "Video RTP stream" msgstr "" +#: ../gtk/dscp_settings.ui.h:5 +msgid "Set DSCP values (in hexadecimal)" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:1 +msgid "Click here to set the speakers volume" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:5 +msgid "Record this call to an audio file" +msgstr "Deze oproep opnemen naar een audiobestand" + +#: ../gtk/in_call_frame.ui.h:6 +msgid "Video" +msgstr "Video" + +#: ../gtk/in_call_frame.ui.h:8 +msgid "Mute" +msgstr "Dempen" + +#: ../gtk/in_call_frame.ui.h:9 +msgid "Transfer" +msgstr "Overdracht" + +#: ../gtk/in_call_frame.ui.h:12 +msgid "In call" +msgstr "In gesprek" + +#: ../gtk/in_call_frame.ui.h:13 +msgid "Duration" +msgstr "Duur" + +#: ../gtk/in_call_frame.ui.h:14 +msgid "Call quality rating" +msgstr "Waardering van de gesprekskwaliteit" + #: ../gtk/ldap.ui.h:1 msgid "LDAP Settings" msgstr "" +#: ../gtk/ldap.ui.h:2 ../gtk/parameters.ui.h:89 +msgid "Server address:" +msgstr "" + +#: ../gtk/ldap.ui.h:3 ../gtk/parameters.ui.h:90 +msgid "Authentication method:" +msgstr "" + +#: ../gtk/ldap.ui.h:4 ../gtk/parameters.ui.h:91 ../gtk/setup_wizard.ui.h:17 +msgid "Username:" +msgstr "Gebruikersnaam:" + +#: ../gtk/ldap.ui.h:5 ../gtk/password.ui.h:4 ../gtk/setup_wizard.ui.h:18 +msgid "Password:" +msgstr "Wachtwoord:" + #: ../gtk/ldap.ui.h:6 msgid "Use TLS Connection" msgstr "" @@ -1681,16 +1047,504 @@ msgstr "" msgid "NTLM" msgstr "" -#: ../gtk/config-uri.ui.h:1 -msgid "Specifying a remote configuration URI" +#: ../gtk/login_frame.ui.h:1 ../gtk/tunnel_config.ui.h:7 +msgid "Username" +msgstr "Gebruikersnaam" + +#: ../gtk/login_frame.ui.h:2 ../gtk/tunnel_config.ui.h:8 +msgid "Password" +msgstr "Wachtwoord" + +#: ../gtk/login_frame.ui.h:3 +msgid "Internet connection:" +msgstr "Internetverbinding:" + +#: ../gtk/login_frame.ui.h:4 +msgid "Automatically log me in" +msgstr "Automatisch inloggen" + +#: ../gtk/login_frame.ui.h:5 ../gtk/password.ui.h:3 +msgid "UserID" +msgstr "Gebruikersidentificatie" + +#: ../gtk/login_frame.ui.h:6 +msgid "Login information" +msgstr "Inloginformatie" + +#: ../gtk/login_frame.ui.h:7 +msgid "Welcome!" +msgstr "Welkom!" + +#: ../gtk/login_frame.ui.h:8 +msgid "ADSL" +msgstr "ADSL" + +#: ../gtk/login_frame.ui.h:9 +msgid "Fiber Channel" +msgstr "Fiber-kanaal" + +#: ../gtk/log.ui.h:1 +msgid "Linphone debug window" +msgstr "Linphone-foutopsporingsvenster" + +#: ../gtk/log.ui.h:2 +msgid "Scroll to end" +msgstr "Scroll naar het einde" + +#: ../gtk/main.ui.h:1 +msgid "Default" +msgstr "Standaard" + +#: ../gtk/main.ui.h:2 +msgid "Delete" +msgstr "Verwijderen" + +#: ../gtk/main.ui.h:3 +msgid "_Options" +msgstr "_Opties" + +#: ../gtk/main.ui.h:4 +msgid "Set configuration URI" +msgstr "Configuratie-URI instellen" + +#: ../gtk/main.ui.h:5 +msgid "Always start video" +msgstr "Video altijd starten" + +#: ../gtk/main.ui.h:6 +msgid "Enable self-view" +msgstr "Eigen weergave inschakelen" + +#: ../gtk/main.ui.h:7 +msgid "Show keypad" msgstr "" -#: ../gtk/config-uri.ui.h:2 -msgid "" -"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" -"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " +#: ../gtk/main.ui.h:8 +msgid "_Help" +msgstr "_Hulp" + +#: ../gtk/main.ui.h:9 +msgid "Show debug window" +msgstr "Foutopsporingsvenster weergeven" + +#: ../gtk/main.ui.h:10 +msgid "_Homepage" +msgstr "_Website" + +#: ../gtk/main.ui.h:11 +msgid "Check _Updates" +msgstr "Controleren op _updates" + +#: ../gtk/main.ui.h:12 +msgid "Account assistant" +msgstr "Account-instelwizard" + +#: ../gtk/main.ui.h:14 +msgid "SIP address or phone number:" +msgstr "SIP-adres of telefoonnummer:" + +#: ../gtk/main.ui.h:15 +msgid "Initiate a new call" +msgstr "Een nieuw gesprek beginnen" + +#: ../gtk/main.ui.h:16 +msgid "Contacts" +msgstr "Contactpersonen" + +#: ../gtk/main.ui.h:17 +msgid "Search" +msgstr "Zoeken" + +#: ../gtk/main.ui.h:18 +msgid "Add contacts from directory" +msgstr "Voeg contactpersonen toe uit map" + +#: ../gtk/main.ui.h:19 +msgid "Add contact" +msgstr "Contactpersoon toevoegen" + +#: ../gtk/main.ui.h:20 +msgid "Clear call history" msgstr "" +#: ../gtk/main.ui.h:22 +msgid "My current identity:" +msgstr "Mijn huidige identiteit:" + +#: ../gtk/main.ui.h:23 +msgid "Autoanswer is enabled" +msgstr "" + +#: ../gtk/parameters.ui.h:1 +msgid "anonymous" +msgstr "anoniem" + +#: ../gtk/parameters.ui.h:2 +msgid "GSSAPI" +msgstr "GSSAPI" + +#: ../gtk/parameters.ui.h:3 +msgid "SASL" +msgstr "SASL" + +#: ../gtk/parameters.ui.h:4 +msgid "default soundcard" +msgstr "standaard geluidskaart" + +#: ../gtk/parameters.ui.h:5 +msgid "a sound card" +msgstr "een geluidskaart" + +#: ../gtk/parameters.ui.h:6 +msgid "default camera" +msgstr "standaard camera" + +#: ../gtk/parameters.ui.h:7 +msgid "CIF" +msgstr "CIF" + +#: ../gtk/parameters.ui.h:8 +msgid "Audio codecs" +msgstr "Audio-codecs" + +#: ../gtk/parameters.ui.h:9 +msgid "Video codecs" +msgstr "Video-codecs" + +#: ../gtk/parameters.ui.h:10 +msgid "C" +msgstr "C" + +#: ../gtk/parameters.ui.h:11 +msgid "SIP (UDP)" +msgstr "" + +#: ../gtk/parameters.ui.h:12 +msgid "SIP (TCP)" +msgstr "" + +#: ../gtk/parameters.ui.h:13 +msgid "SIP (TLS)" +msgstr "" + +#: ../gtk/parameters.ui.h:14 +msgid "default" +msgstr "" + +#: ../gtk/parameters.ui.h:15 +msgid "high-fps" +msgstr "" + +#: ../gtk/parameters.ui.h:16 +msgid "custom" +msgstr "" + +#: ../gtk/parameters.ui.h:17 +msgid "Settings" +msgstr "Instellingen" + +#: ../gtk/parameters.ui.h:18 +msgid "This section defines your SIP address when not using a SIP account" +msgstr "" + +#: ../gtk/parameters.ui.h:19 +msgid "Your display name (eg: John Doe):" +msgstr "Uw weergavenaam (bijv.: Jan Noniem):" + +#: ../gtk/parameters.ui.h:20 +msgid "Your username:" +msgstr "Uw gebruikersnaam:" + +#: ../gtk/parameters.ui.h:21 +msgid "Your resulting SIP address:" +msgstr "" + +#: ../gtk/parameters.ui.h:22 +msgid "Default identity" +msgstr "Standaardidentiteit" + +#: ../gtk/parameters.ui.h:23 +msgid "Wizard" +msgstr "Instelhulp" + +#: ../gtk/parameters.ui.h:24 +msgid "Add" +msgstr "Toevoegen" + +#: ../gtk/parameters.ui.h:25 +msgid "Edit" +msgstr "Bewerken" + +#: ../gtk/parameters.ui.h:26 +msgid "Remove" +msgstr "Verwijderen" + +#: ../gtk/parameters.ui.h:27 +msgid "Proxy accounts" +msgstr "" + +#: ../gtk/parameters.ui.h:28 +msgid "Erase all passwords" +msgstr "" + +#: ../gtk/parameters.ui.h:29 +msgid "Privacy" +msgstr "" + +#: ../gtk/parameters.ui.h:30 +msgid "Automatically answer when a call is received" +msgstr "" + +#: ../gtk/parameters.ui.h:31 +msgid "Delay before answering (ms)" +msgstr "" + +#: ../gtk/parameters.ui.h:32 +msgid "Auto-answer" +msgstr "" + +#: ../gtk/parameters.ui.h:33 +msgid "Manage SIP Accounts" +msgstr "" + +#: ../gtk/parameters.ui.h:34 +msgid "Ring sound:" +msgstr "Belgeluid:" + +#: ../gtk/parameters.ui.h:35 +msgid "ALSA special device (optional):" +msgstr "ALSA speciaal apparaat (optioneel)" + +#: ../gtk/parameters.ui.h:36 +msgid "Capture device:" +msgstr "Opnameapparaat:" + +#: ../gtk/parameters.ui.h:37 +msgid "Ring device:" +msgstr "Belapparaat:" + +#: ../gtk/parameters.ui.h:38 +msgid "Playback device:" +msgstr "Afspeelapparaat:" + +#: ../gtk/parameters.ui.h:39 +msgid "Enable echo cancellation" +msgstr "Echo-onderdrukking inschakelen" + +#: ../gtk/parameters.ui.h:40 +msgid "Audio" +msgstr "Audio" + +#: ../gtk/parameters.ui.h:41 +msgid "Video input device:" +msgstr "Videoingang-apparaat:" + +#: ../gtk/parameters.ui.h:42 +msgid "Preferred video resolution:" +msgstr "" + +#: ../gtk/parameters.ui.h:43 +msgid "Video output method:" +msgstr "Videouitgangsmethode:" + +#: ../gtk/parameters.ui.h:44 +msgid "Show camera preview" +msgstr "Cameravoorbeeld weergeven" + +#: ../gtk/parameters.ui.h:45 +msgid "Video preset:" +msgstr "" + +#: ../gtk/parameters.ui.h:46 +msgid "Preferred video framerate:" +msgstr "" + +#: ../gtk/parameters.ui.h:47 +msgid "0 stands for \"unlimited\"" +msgstr "" + +#: ../gtk/parameters.ui.h:48 +msgid "Video" +msgstr "Video" + +#: ../gtk/parameters.ui.h:49 +msgid "Upload speed limit in Kbit/sec:" +msgstr "" + +#: ../gtk/parameters.ui.h:50 +msgid "Download speed limit in Kbit/sec:" +msgstr "" + +#: ../gtk/parameters.ui.h:51 +msgid "Enable adaptive rate control" +msgstr "" + +#: ../gtk/parameters.ui.h:52 +msgid "" +"Adaptive rate control is a technique to dynamically guess the available " +"bandwidth during a call." +msgstr "" + +#: ../gtk/parameters.ui.h:53 +msgid "Bandwidth control" +msgstr "" + +#: ../gtk/parameters.ui.h:54 +msgid "Multimedia settings" +msgstr "Multimedia-instellingen" + +#: ../gtk/parameters.ui.h:55 +msgid "Set Maximum Transmission Unit:" +msgstr "Maximale Transmissie-unit instellen:" + +#: ../gtk/parameters.ui.h:56 +msgid "Send DTMFs as SIP info" +msgstr "DTMF's als SIP-informatie versturen" + +#: ../gtk/parameters.ui.h:57 +msgid "Allow IPv6" +msgstr "" + +#: ../gtk/parameters.ui.h:58 +msgid "Transport" +msgstr "Overdracht" + +#: ../gtk/parameters.ui.h:59 +msgid "SIP/UDP port" +msgstr "SIP/UDP-poort" + +#: ../gtk/parameters.ui.h:61 +msgid "Random" +msgstr "Willekeurig" + +#: ../gtk/parameters.ui.h:62 +msgid "SIP/TCP port" +msgstr "SIP/TCP-poort" + +#: ../gtk/parameters.ui.h:63 +msgid "Audio RTP/UDP:" +msgstr "AUDIO RTP/UDP:" + +#: ../gtk/parameters.ui.h:64 +msgid "Fixed" +msgstr "Vastgezet" + +#: ../gtk/parameters.ui.h:65 +msgid "Video RTP/UDP:" +msgstr "Video RTP/UDP:" + +#: ../gtk/parameters.ui.h:66 +msgid "Media encryption type" +msgstr "Mediaversleutelingstype" + +#: ../gtk/parameters.ui.h:67 +msgid "Media encryption is mandatory" +msgstr "Mediaversleuteling is vereist" + +#: ../gtk/parameters.ui.h:68 +msgid "Tunnel" +msgstr "Tunnel" + +#: ../gtk/parameters.ui.h:69 +msgid "DSCP fields" +msgstr "DSCP-velden" + +#: ../gtk/parameters.ui.h:70 +msgid "Network protocol and ports" +msgstr "Netwerkprotocol en -poorten" + +#: ../gtk/parameters.ui.h:71 +msgid "Direct connection to the Internet" +msgstr "Directe verbinding met het internet" + +#: ../gtk/parameters.ui.h:72 +msgid "Behind NAT / Firewall (specify gateway IP )" +msgstr "Achter een NAT / Firewall (specificeer de gateway IP)" + +#: ../gtk/parameters.ui.h:73 +msgid "Behind NAT / Firewall (use STUN to resolve)" +msgstr "" + +#: ../gtk/parameters.ui.h:74 +msgid "Behind NAT / Firewall (use ICE)" +msgstr "" + +#: ../gtk/parameters.ui.h:75 +msgid "Behind NAT / Firewall (use uPnP)" +msgstr "" + +#: ../gtk/parameters.ui.h:76 +msgid "Public IP address:" +msgstr "Openbaar IP-adres:" + +#: ../gtk/parameters.ui.h:77 +msgid "Stun server:" +msgstr "Stun-server" + +#: ../gtk/parameters.ui.h:78 +msgid "NAT and Firewall" +msgstr "NAT en Firewall" + +#: ../gtk/parameters.ui.h:79 +msgid "Network settings" +msgstr "Netwerkinstellingen" + +#: ../gtk/parameters.ui.h:80 ../gtk/tunnel_config.ui.h:4 +msgid "Enable" +msgstr "Aan" + +#: ../gtk/parameters.ui.h:81 ../gtk/tunnel_config.ui.h:5 +msgid "Disable" +msgstr "Uit" + +#: ../gtk/parameters.ui.h:82 +msgid "Audio codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:83 +msgid "Video codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:84 +msgid "Codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:85 +msgid "Language" +msgstr "" + +#: ../gtk/parameters.ui.h:86 +msgid "Show advanced settings" +msgstr "" + +#: ../gtk/parameters.ui.h:87 +msgid "Level" +msgstr "" + +#: ../gtk/parameters.ui.h:88 +msgid "User interface" +msgstr "" + +#: ../gtk/parameters.ui.h:92 +msgid "LDAP Account setup" +msgstr "" + +#: ../gtk/parameters.ui.h:93 +msgid "LDAP" +msgstr "" + +#: ../gtk/parameters.ui.h:94 +msgid "Done" +msgstr "" + +#: ../gtk/password.ui.h:1 +msgid "Linphone - Authentication required" +msgstr "Linphone - Authenticatie is vereist" + +#: ../gtk/password.ui.h:2 +msgid "Please enter the domain password" +msgstr "Vul het domeinnaamwachtwoord in" + #: ../gtk/provisioning-fetch.ui.h:1 msgid "Configuring..." msgstr "" @@ -1699,68 +1553,278 @@ msgstr "" msgid "Please wait while fetching configuration from server..." msgstr "" -#: ../coreapi/linphonecore.c:1539 +#: ../gtk/setup_wizard.ui.h:1 +msgid "SIP account configuration assistant" +msgstr "SIP-account-instelwizard" + +#: ../gtk/setup_wizard.ui.h:2 +msgid "" +"Welcome!\n" +"This assistant will help you to use a SIP account for your calls." +msgstr "Welkom!\nDeze instelwizard zal u begeleiden bij het gebruiken van een SIP-account voor oproepen." + +#: ../gtk/setup_wizard.ui.h:4 +msgid "Welcome to the account setup assistant" +msgstr "Welkom bij de account-instelwizard" + +#: ../gtk/setup_wizard.ui.h:5 +msgid "Create an account on linphone.org" +msgstr "Creëer een account op linphone.org" + +#: ../gtk/setup_wizard.ui.h:6 +msgid "I have already a linphone.org account and I just want to use it" +msgstr "Ik heb al een linphone.org-account en wil deze graag gebruiken" + +#: ../gtk/setup_wizard.ui.h:7 +msgid "I have already a sip account and I just want to use it" +msgstr "Ik heb al een SIP-account en wil deze graag gebruiken" + +#: ../gtk/setup_wizard.ui.h:8 +msgid "I want to specify a remote configuration URI" +msgstr "Ik wil een externe URI-configuratie opgeven" + +#: ../gtk/setup_wizard.ui.h:9 +msgid "Account setup assistant" +msgstr "Account-instelwizard" + +#: ../gtk/setup_wizard.ui.h:10 +msgid "Enter your account information" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:11 +msgid "Username*" +msgstr "Gebruikersnaam*" + +#: ../gtk/setup_wizard.ui.h:12 +msgid "Password*" +msgstr "Wachtwoord*" + +#: ../gtk/setup_wizard.ui.h:13 +msgid "Domain*" +msgstr "Domeinnaam*" + +#: ../gtk/setup_wizard.ui.h:14 +msgid "Proxy" +msgstr "Proxy" + +#: ../gtk/setup_wizard.ui.h:15 +msgid "Configure your account (step 1/1)" +msgstr "Uw account instellen (stap 1/1)" + +#: ../gtk/setup_wizard.ui.h:16 +msgid "Enter your linphone.org username" +msgstr "Vul uw linphone.org-gebruikersnaam in" + +#: ../gtk/setup_wizard.ui.h:19 +msgid "Enter your sip username (step 1/1)" +msgstr "Vul uw SIP-gebruikersnaam in (stap 1/1)" + +#: ../gtk/setup_wizard.ui.h:20 +msgid "(*) Required fields" +msgstr "(*) Verplichte velden" + +#: ../gtk/setup_wizard.ui.h:21 +msgid "Email: (*)" +msgstr "E-mailadres: (*)" + +#: ../gtk/setup_wizard.ui.h:22 +msgid "Username: (*)" +msgstr "Gebruikersnaam: (*)" + +#: ../gtk/setup_wizard.ui.h:23 +msgid "Password: (*)" +msgstr "Wachtwoord: (*)" + +#: ../gtk/setup_wizard.ui.h:24 +msgid "Confirm your password: (*)" +msgstr "Bevestig uw wachtwoord: (*)" + +#: ../gtk/setup_wizard.ui.h:25 +msgid "Keep me informed with linphone updates" +msgstr "Houdt me op de hoogte van linphone-updates" + +#: ../gtk/setup_wizard.ui.h:26 +msgid "Enter account information (step 1/2)" +msgstr "Vul uw accountinformatie in (stap 1/2)" + +#: ../gtk/setup_wizard.ui.h:27 +msgid "Your account is being created, please wait." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:28 +msgid "Account creation in progress" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:29 +msgid "" +"Please validate your account by clicking on the link we just sent you by 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.\nKom dan terug naar dit venster en klik op de knop Volgende." + +#: ../gtk/setup_wizard.ui.h:31 +msgid "Validation (step 2/2)" +msgstr "Geldigheid (stap 2/2)" + +#: ../gtk/setup_wizard.ui.h:32 +msgid "Checking if your account is been validated, please wait." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:33 +msgid "Account validation check in progress" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:34 +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.\nGa terug en probeer het opnieuw." + +#: ../gtk/setup_wizard.ui.h:36 +msgid "Error" +msgstr "Fout" + +#: ../gtk/setup_wizard.ui.h:37 +msgid "Thank you. Your account is now configured and ready for use." +msgstr "Bedankt. Uw account is nu ingesteld en klaar voor gebruik." + +#: ../gtk/sip_account.ui.h:1 +msgid "Linphone - Configure a SIP account" +msgstr "Linphone - Een SIP-account instellen" + +#: ../gtk/sip_account.ui.h:2 +msgid "Your SIP identity:" +msgstr "Uw SIP-identiteit:" + +#: ../gtk/sip_account.ui.h:3 +msgid "Looks like sip:@" +msgstr "Lijkt op:@" + +#: ../gtk/sip_account.ui.h:4 +msgid "sip:" +msgstr "sip:" + +#: ../gtk/sip_account.ui.h:5 +msgid "SIP Proxy address:" +msgstr "SIP-proxyadres:" + +#: ../gtk/sip_account.ui.h:6 +msgid "Looks like sip:" +msgstr "Lijkt op sip:" + +#: ../gtk/sip_account.ui.h:7 +msgid "Registration duration (sec):" +msgstr "Registratieduur (sec):" + +#: ../gtk/sip_account.ui.h:8 +msgid "Contact params (optional):" +msgstr "Contactparameters (optioneel):" + +#: ../gtk/sip_account.ui.h:9 +msgid "AVPF regular RTCP interval (sec):" +msgstr "AVPF regulier RTCP-tussenpose (sec):" + +#: ../gtk/sip_account.ui.h:10 +msgid "Route (optional):" +msgstr "Route (optioneel):" + +#: ../gtk/sip_account.ui.h:11 +msgid "Transport" +msgstr "Overdracht" + +#: ../gtk/sip_account.ui.h:12 +msgid "Register" +msgstr "Registreren" + +#: ../gtk/sip_account.ui.h:13 +msgid "Publish presence information" +msgstr "Aanwezigheidsinformatie publiceren" + +#: ../gtk/sip_account.ui.h:14 +msgid "Enable AVPF" +msgstr "AVPF inschakelen" + +#: ../gtk/sip_account.ui.h:15 +msgid "Configure a SIP account" +msgstr "Een SIP-account instellen" + +#: ../gtk/tunnel_config.ui.h:1 +msgid "Configure VoIP tunnel" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:2 +msgid "Host" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:3 +msgid "Port" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:6 +msgid "Configure tunnel" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:9 +msgid "Configure http proxy (optional)" +msgstr "" + +#: ../gtk/waiting.ui.h:2 +msgid "Please wait" +msgstr "" + +#: ../coreapi/linphonecore.c:1560 msgid "Ready" msgstr "Gereed." -#: ../coreapi/linphonecore.c:2551 +#: ../coreapi/linphonecore.c:2556 msgid "Configuring" msgstr "" -#: ../coreapi/linphonecore.c:2725 -msgid "Looking for telephone number destination..." -msgstr "Zoekt de lokatie van het telefoonnummer..." - -#: ../coreapi/linphonecore.c:2727 -msgid "Could not resolve this number." -msgstr "Kon dit nummer niet vinden." - #. must be known at that time -#: ../coreapi/linphonecore.c:3013 +#: ../coreapi/linphonecore.c:2951 msgid "Contacting" msgstr "Verbinden" -#: ../coreapi/linphonecore.c:3018 +#: ../coreapi/linphonecore.c:2956 msgid "Could not call" msgstr "" -#: ../coreapi/linphonecore.c:3169 +#: ../coreapi/linphonecore.c:3092 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "" -#: ../coreapi/linphonecore.c:3327 +#: ../coreapi/linphonecore.c:3250 msgid "is contacting you" msgstr "" -#: ../coreapi/linphonecore.c:3328 +#: ../coreapi/linphonecore.c:3251 msgid " and asked autoanswer." msgstr "" -#: ../coreapi/linphonecore.c:3452 +#: ../coreapi/linphonecore.c:3377 msgid "Modifying call parameters..." msgstr "" -#: ../coreapi/linphonecore.c:3802 +#: ../coreapi/linphonecore.c:3769 msgid "Connected." msgstr "Verbonden." -#: ../coreapi/linphonecore.c:3827 +#: ../coreapi/linphonecore.c:3794 msgid "Call aborted" msgstr "" -#: ../coreapi/linphonecore.c:4024 +#: ../coreapi/linphonecore.c:3983 msgid "Could not pause the call" msgstr "" -#: ../coreapi/linphonecore.c:4027 +#: ../coreapi/linphonecore.c:3986 msgid "Pausing the current call..." msgstr "" -#: ../coreapi/misc.c:434 +#: ../coreapi/misc.c:440 msgid "Stun lookup in progress..." msgstr "STUN adres wordt opgezocht..." -#: ../coreapi/misc.c:615 +#: ../coreapi/misc.c:650 msgid "ICE local candidates gathering in progress..." msgstr "" @@ -1816,166 +1880,173 @@ msgstr "" msgid "Unknown status" msgstr "" -#: ../coreapi/proxy.c:328 +#: ../coreapi/proxy.c:292 msgid "" "The sip proxy address you entered is invalid, it must start with \"sip:\" " "followed by a hostname." msgstr "" -#: ../coreapi/proxy.c:334 +#: ../coreapi/proxy.c:298 msgid "" "The sip identity you entered is invalid.\n" "It should look like sip:username@proxydomain, such as sip:alice@example.net" msgstr "" -#: ../coreapi/proxy.c:1416 +#: ../coreapi/proxy.c:927 +msgid "Looking for telephone number destination..." +msgstr "Zoekt de lokatie van het telefoonnummer..." + +#: ../coreapi/proxy.c:931 +msgid "Could not resolve this number." +msgstr "Kon dit nummer niet vinden." + +#: ../coreapi/proxy.c:1324 #, c-format msgid "Could not login as %s" msgstr "" -#: ../coreapi/callbacks.c:428 +#: ../coreapi/proxy.c:1411 +#, c-format +msgid "Refreshing on %s..." +msgstr "" + +#: ../coreapi/callbacks.c:423 msgid "Remote ringing." msgstr "" -#: ../coreapi/callbacks.c:440 +#: ../coreapi/callbacks.c:435 msgid "Remote ringing..." msgstr "" -#: ../coreapi/callbacks.c:461 +#: ../coreapi/callbacks.c:458 msgid "Early media." msgstr "" -#: ../coreapi/callbacks.c:534 +#: ../coreapi/callbacks.c:488 #, c-format -msgid "Call with %s is paused." +msgid "Call answered by %s" msgstr "" -#: ../coreapi/callbacks.c:547 -#, c-format -msgid "Call answered by %s - on hold." -msgstr "" - -#: ../coreapi/callbacks.c:557 +#: ../coreapi/callbacks.c:527 msgid "Call resumed." msgstr "" -#: ../coreapi/callbacks.c:561 -#, c-format -msgid "Call answered by %s." -msgstr "" - -#: ../coreapi/callbacks.c:584 +#: ../coreapi/callbacks.c:582 msgid "Incompatible, check codecs or security settings..." msgstr "" -#: ../coreapi/callbacks.c:589 ../coreapi/callbacks.c:906 +#: ../coreapi/callbacks.c:587 ../coreapi/callbacks.c:923 msgid "Incompatible media parameters." msgstr "" -#: ../coreapi/callbacks.c:619 +#: ../coreapi/callbacks.c:612 msgid "We have been resumed." msgstr "" #. we are being paused -#: ../coreapi/callbacks.c:628 +#: ../coreapi/callbacks.c:620 msgid "We are paused by other party." msgstr "" -#. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:666 +#: ../coreapi/callbacks.c:630 msgid "Call is updated by remote." msgstr "" -#: ../coreapi/callbacks.c:782 +#: ../coreapi/callbacks.c:799 msgid "Call terminated." msgstr "Oproep beeindigd." -#: ../coreapi/callbacks.c:810 +#: ../coreapi/callbacks.c:827 msgid "User is busy." msgstr "Gebruiker is bezet." -#: ../coreapi/callbacks.c:811 +#: ../coreapi/callbacks.c:828 msgid "User is temporarily unavailable." msgstr "Gebruiker is tijdelijk niet beschikbaar." #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:813 +#: ../coreapi/callbacks.c:830 msgid "User does not want to be disturbed." msgstr "De gebruiker wenst niet gestoord te worden." -#: ../coreapi/callbacks.c:814 +#: ../coreapi/callbacks.c:831 msgid "Call declined." msgstr "Oproep geweigerd." -#: ../coreapi/callbacks.c:829 +#: ../coreapi/callbacks.c:846 msgid "Request timeout." msgstr "" -#: ../coreapi/callbacks.c:860 +#: ../coreapi/callbacks.c:877 msgid "Redirected" msgstr "" -#: ../coreapi/callbacks.c:915 +#: ../coreapi/callbacks.c:927 msgid "Call failed." msgstr "" -#: ../coreapi/callbacks.c:993 +#: ../coreapi/callbacks.c:1005 #, c-format msgid "Registration on %s successful." msgstr "Registratie op %s gelukt." -#: ../coreapi/callbacks.c:994 +#: ../coreapi/callbacks.c:1006 #, c-format msgid "Unregistration on %s done." msgstr "" -#: ../coreapi/callbacks.c:1012 +#: ../coreapi/callbacks.c:1024 msgid "no response timeout" msgstr "" -#: ../coreapi/callbacks.c:1015 +#: ../coreapi/callbacks.c:1027 #, c-format msgid "Registration on %s failed: %s" msgstr "" -#: ../coreapi/callbacks.c:1022 +#: ../coreapi/callbacks.c:1034 msgid "Service unavailable, retrying" msgstr "" #. if encryption is DTLS, no status to be displayed -#: ../coreapi/linphonecall.c:180 +#: ../coreapi/linphonecall.c:197 #, c-format msgid "Authentication token is %s" msgstr "" -#: ../coreapi/linphonecall.c:1310 +#: ../coreapi/linphonecall.c:1561 +#, c-format +msgid "Call parameters could not be modified: %s." +msgstr "" + +#: ../coreapi/linphonecall.c:1563 msgid "Call parameters were successfully modified." msgstr "" -#: ../coreapi/linphonecall.c:3686 +#: ../coreapi/linphonecall.c:4396 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." msgstr[0] "" msgstr[1] "" -#: ../coreapi/call_log.c:209 +#: ../coreapi/call_log.c:223 msgid "aborted" msgstr "" -#: ../coreapi/call_log.c:212 +#: ../coreapi/call_log.c:226 msgid "completed" msgstr "" -#: ../coreapi/call_log.c:215 +#: ../coreapi/call_log.c:229 msgid "missed" msgstr "" -#: ../coreapi/call_log.c:218 +#: ../coreapi/call_log.c:232 msgid "unknown" msgstr "" -#: ../coreapi/call_log.c:220 +#: ../coreapi/call_log.c:234 #, c-format msgid "" "%s at %s\n" @@ -1985,7 +2056,7 @@ msgid "" "Duration: %i mn %i sec\n" msgstr "" -#: ../coreapi/call_log.c:221 +#: ../coreapi/call_log.c:235 msgid "Outgoing call" msgstr "" diff --git a/po/pl.po b/po/pl.po index 6dbfbfdb0..b9425fcf3 100644 --- a/po/pl.po +++ b/po/pl.po @@ -7,48 +7,57 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-04-30 10:13+0200\n" -"PO-Revision-Date: 2015-04-30 08:13+0000\n" +"POT-Creation-Date: 2015-11-10 15:16+0100\n" +"PO-Revision-Date: 2015-11-10 14:16+0000\n" "Last-Translator: Belledonne Communications \n" -"Language-Team: Polish (http://www.transifex.com/projects/p/linphone-gtk/language/pl/)\n" +"Language-Team: Polish (http://www.transifex.com/belledonne-communications/linphone-gtk/language/pl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: pl\n" "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: ../gtk/calllogs.c:148 ../gtk/friendlist.c:974 +#: ../gtk/calllogs.c:178 #, c-format msgid "Call %s" msgstr "" -#: ../gtk/calllogs.c:149 ../gtk/friendlist.c:975 +#: ../gtk/calllogs.c:179 #, c-format msgid "Send text to %s" msgstr "" -#: ../gtk/calllogs.c:232 +#: ../gtk/calllogs.c:181 +#, c-format +msgid "Add %s to your contact list" +msgstr "" + +#: ../gtk/calllogs.c:245 ../gtk/main.ui.h:21 +msgid "Recent calls" +msgstr "" + +#: ../gtk/calllogs.c:260 #, c-format msgid "Recent calls (%i)" msgstr "" -#: ../gtk/calllogs.c:314 +#: ../gtk/calllogs.c:331 msgid "n/a" msgstr "" -#: ../gtk/calllogs.c:317 +#: ../gtk/calllogs.c:334 msgid "Aborted" msgstr "" -#: ../gtk/calllogs.c:320 +#: ../gtk/calllogs.c:337 msgid "Missed" msgstr "" -#: ../gtk/calllogs.c:323 +#: ../gtk/calllogs.c:340 msgid "Declined" msgstr "" -#: ../gtk/calllogs.c:329 +#: ../gtk/calllogs.c:346 #, c-format msgid "%i minute" msgid_plural "%i minutes" @@ -56,7 +65,7 @@ msgstr[0] "" msgstr[1] "" msgstr[2] "" -#: ../gtk/calllogs.c:332 +#: ../gtk/calllogs.c:349 #, c-format msgid "%i second" msgid_plural "%i seconds" @@ -64,19 +73,19 @@ msgstr[0] "" msgstr[1] "" msgstr[2] "" -#: ../gtk/calllogs.c:337 +#: ../gtk/calllogs.c:354 #, c-format msgid "" "%s\tQuality: %s\n" "%s\t%s\t" msgstr "" -#: ../gtk/calllogs.c:341 +#: ../gtk/calllogs.c:358 #, c-format msgid "%s\t%s" msgstr "" -#: ../gtk/conference.c:38 ../gtk/main.ui.h:13 +#: ../gtk/conference.c:38 ../gtk/in_call_frame.ui.h:11 msgid "Conference" msgstr "" @@ -89,297 +98,314 @@ msgstr "" msgid "Couldn't find pixmap file: %s" msgstr "Nie można znaleźć pixmapy: %s" -#: ../gtk/main.c:137 -msgid "log to stdout some debug information while running." +#: ../gtk/chat.c:196 ../gtk/chat.c:254 +msgid "Sending..." +msgstr "" + +#: ../gtk/chat.c:213 ../gtk/chat.c:263 +msgid "Message not sent" +msgstr "" + +#: ../gtk/chat.c:472 +msgid "Copy" msgstr "" #: ../gtk/main.c:138 -msgid "path to a file to write logs into." +msgid "log to stdout some debug information while running." msgstr "" #: ../gtk/main.c:139 -msgid "Start linphone with video disabled." +msgid "display version and exit." msgstr "" #: ../gtk/main.c:140 -msgid "Start only in the system tray, do not show the main interface." +msgid "path to a file to write logs into." msgstr "" #: ../gtk/main.c:141 -msgid "address to call right now" +msgid "Start linphone with video disabled." msgstr "" #: ../gtk/main.c:142 +msgid "Start only in the system tray, do not show the main interface." +msgstr "" + +#: ../gtk/main.c:143 +msgid "address to call right now" +msgstr "" + +#: ../gtk/main.c:144 msgid "" "Specifiy a working directory (should be the base of the installation, eg: " "c:\\Program Files\\Linphone)" msgstr "" -#: ../gtk/main.c:143 +#: ../gtk/main.c:145 msgid "Configuration file" msgstr "" -#: ../gtk/main.c:144 +#: ../gtk/main.c:146 msgid "Run the audio assistant" msgstr "" -#: ../gtk/main.c:145 +#: ../gtk/main.c:147 msgid "Run self test and exit 0 if succeed" msgstr "" -#: ../gtk/main.c:1070 +#: ../gtk/main.c:1046 #, c-format msgid "" -"%s would like to add you to his contact list.\n" -"Would you allow him to see your presence status or add him to your contact list ?\n" +"%s would like to add you to his/her contact list.\n" +"Would you add him/her to your contact list and allow him/her to see your presence status?\n" "If you answer no, this person will be temporarily blacklisted." msgstr "" -#: ../gtk/main.c:1147 +#: ../gtk/main.c:1123 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" msgstr "" -#: ../gtk/main.c:1268 +#: ../gtk/main.c:1253 msgid "Call error" msgstr "" -#: ../gtk/main.c:1271 ../coreapi/linphonecore.c:3846 +#: ../gtk/main.c:1256 ../coreapi/linphonecore.c:3813 msgid "Call ended" msgstr "" -#: ../gtk/main.c:1274 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1259 ../coreapi/call_log.c:235 msgid "Incoming call" msgstr "" -#: ../gtk/main.c:1276 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1261 ../gtk/incall_view.c:580 ../gtk/in_call_frame.ui.h:2 msgid "Answer" msgstr "" -#: ../gtk/main.c:1278 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1263 ../gtk/in_call_frame.ui.h:3 msgid "Decline" msgstr "" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 msgid "Call paused" msgstr "" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 #, c-format msgid "by %s" msgstr "" -#: ../gtk/main.c:1354 +#: ../gtk/main.c:1339 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "" -#: ../gtk/main.c:1509 +#: ../gtk/main.c:1505 msgid "Website link" msgstr "" -#: ../gtk/main.c:1568 ../gtk/waiting.ui.h:1 +#: ../gtk/main.c:1564 ../gtk/waiting.ui.h:1 msgid "Linphone" msgstr "" -#: ../gtk/main.c:1569 +#: ../gtk/main.c:1565 msgid "A video internet phone" msgstr "" -#: ../gtk/main.c:1629 +#: ../gtk/main.c:1624 #, c-format msgid "%s (Default)" msgstr "" -#: ../gtk/main.c:1962 ../coreapi/callbacks.c:1063 +#: ../gtk/main.c:1960 ../coreapi/callbacks.c:1075 #, c-format msgid "We are transferred to %s" msgstr "" -#: ../gtk/main.c:1972 +#: ../gtk/main.c:1970 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:2117 +#: ../gtk/main.c:2129 msgid "A free SIP video-phone" msgstr "" -#: ../gtk/main.c:2221 +#: ../gtk/main.c:2242 #, c-format msgid "Hello\n" msgstr "" -#: ../gtk/friendlist.c:505 +#: ../gtk/friendlist.c:461 msgid "Add to addressbook" msgstr "" -#: ../gtk/friendlist.c:691 -msgid "Presence status" -msgstr "" - -#: ../gtk/friendlist.c:709 ../gtk/propertybox.c:569 ../gtk/contact.ui.h:1 -msgid "Name" -msgstr "Nazwa" - -#: ../gtk/friendlist.c:721 -msgid "Call" -msgstr "" - -#: ../gtk/friendlist.c:726 -msgid "Chat" -msgstr "" - -#: ../gtk/friendlist.c:756 +#: ../gtk/friendlist.c:627 #, c-format msgid "Search in %s directory" msgstr "" -#: ../gtk/friendlist.c:924 +#: ../gtk/friendlist.c:772 msgid "Invalid sip contact !" msgstr "" -#: ../gtk/friendlist.c:976 +#: ../gtk/friendlist.c:820 +#, c-format +msgid "Add a new contact" +msgstr "" + +#: ../gtk/friendlist.c:823 #, c-format msgid "Edit contact '%s'" msgstr "" -#: ../gtk/friendlist.c:977 +#: ../gtk/friendlist.c:824 #, c-format msgid "Delete contact '%s'" msgstr "" -#: ../gtk/friendlist.c:978 +#: ../gtk/friendlist.c:825 #, c-format msgid "Delete chat history of '%s'" msgstr "" -#: ../gtk/friendlist.c:1029 +#: ../gtk/friendlist.c:862 #, c-format msgid "Add new contact from %s directory" msgstr "" -#: ../gtk/propertybox.c:575 +#: ../gtk/propertybox.c:592 ../gtk/contact.ui.h:1 +msgid "Name" +msgstr "Nazwa" + +#: ../gtk/propertybox.c:598 msgid "Rate (Hz)" msgstr "Jakość (Hz)" -#: ../gtk/propertybox.c:581 +#: ../gtk/propertybox.c:604 msgid "Status" msgstr "Status" -#: ../gtk/propertybox.c:587 +#: ../gtk/propertybox.c:617 msgid "IP Bitrate (kbit/s)" msgstr "" -#: ../gtk/propertybox.c:596 +#: ../gtk/propertybox.c:628 msgid "Parameters" msgstr "Parametr" -#: ../gtk/propertybox.c:639 ../gtk/propertybox.c:782 +#: ../gtk/propertybox.c:670 ../gtk/propertybox.c:824 msgid "Enabled" msgstr "Włączone" -#: ../gtk/propertybox.c:641 ../gtk/propertybox.c:782 ../gtk/parameters.ui.h:20 +#: ../gtk/propertybox.c:672 ../gtk/propertybox.c:824 ../gtk/parameters.ui.h:60 msgid "Disabled" msgstr "Wyłączone" -#: ../gtk/propertybox.c:828 +#: ../gtk/propertybox.c:902 msgid "Account" msgstr "" -#: ../gtk/propertybox.c:1091 +#: ../gtk/propertybox.c:1170 msgid "English" msgstr "" -#: ../gtk/propertybox.c:1092 +#: ../gtk/propertybox.c:1171 msgid "French" msgstr "" -#: ../gtk/propertybox.c:1093 +#: ../gtk/propertybox.c:1172 msgid "Swedish" msgstr "" -#: ../gtk/propertybox.c:1094 +#: ../gtk/propertybox.c:1173 msgid "Italian" msgstr "" -#: ../gtk/propertybox.c:1095 +#: ../gtk/propertybox.c:1174 msgid "Spanish" msgstr "" -#: ../gtk/propertybox.c:1096 +#: ../gtk/propertybox.c:1175 msgid "Brazilian Portugese" msgstr "" -#: ../gtk/propertybox.c:1097 +#: ../gtk/propertybox.c:1176 msgid "Polish" msgstr "" -#: ../gtk/propertybox.c:1098 +#: ../gtk/propertybox.c:1177 msgid "German" msgstr "" -#: ../gtk/propertybox.c:1099 +#: ../gtk/propertybox.c:1178 msgid "Russian" msgstr "" -#: ../gtk/propertybox.c:1100 +#: ../gtk/propertybox.c:1179 msgid "Japanese" msgstr "" -#: ../gtk/propertybox.c:1101 +#: ../gtk/propertybox.c:1180 msgid "Dutch" msgstr "" -#: ../gtk/propertybox.c:1102 +#: ../gtk/propertybox.c:1181 msgid "Hungarian" msgstr "" -#: ../gtk/propertybox.c:1103 +#: ../gtk/propertybox.c:1182 msgid "Czech" msgstr "" -#: ../gtk/propertybox.c:1104 +#: ../gtk/propertybox.c:1183 msgid "Chinese" msgstr "" -#: ../gtk/propertybox.c:1105 +#: ../gtk/propertybox.c:1184 msgid "Traditional Chinese" msgstr "" -#: ../gtk/propertybox.c:1106 +#: ../gtk/propertybox.c:1185 msgid "Norwegian" msgstr "" -#: ../gtk/propertybox.c:1107 +#: ../gtk/propertybox.c:1186 msgid "Hebrew" msgstr "" -#: ../gtk/propertybox.c:1108 +#: ../gtk/propertybox.c:1187 msgid "Serbian" msgstr "" -#: ../gtk/propertybox.c:1175 +#: ../gtk/propertybox.c:1188 +msgid "Arabic" +msgstr "" + +#: ../gtk/propertybox.c:1189 +msgid "Turkish" +msgstr "" + +#: ../gtk/propertybox.c:1246 msgid "" "You need to restart linphone for the new language selection to take effect." msgstr "" -#: ../gtk/propertybox.c:1255 +#: ../gtk/propertybox.c:1326 msgid "None" msgstr "" -#: ../gtk/propertybox.c:1259 +#: ../gtk/propertybox.c:1330 msgid "SRTP" msgstr "" -#: ../gtk/propertybox.c:1265 +#: ../gtk/propertybox.c:1336 msgid "DTLS" msgstr "" -#: ../gtk/propertybox.c:1272 +#: ../gtk/propertybox.c:1343 msgid "ZRTP" msgstr "" @@ -422,324 +448,195 @@ msgstr[0] "" msgstr[1] "" msgstr[2] "" -#: ../gtk/setupwizard.c:32 -msgid "" -"Welcome!\n" -"This assistant will help you to use a SIP account for your calls." -msgstr "" - -#: ../gtk/setupwizard.c:41 -msgid "Create an account on linphone.org" -msgstr "" - -#: ../gtk/setupwizard.c:42 -msgid "I have already a linphone.org account and I just want to use it" -msgstr "" - -#: ../gtk/setupwizard.c:43 -msgid "I have already a sip account and I just want to use it" -msgstr "" - -#: ../gtk/setupwizard.c:44 -msgid "I want to specify a remote configuration URI" -msgstr "" - -#: ../gtk/setupwizard.c:87 -msgid "Enter your linphone.org username" -msgstr "" - -#: ../gtk/setupwizard.c:100 ../gtk/parameters.ui.h:85 ../gtk/ldap.ui.h:4 -msgid "Username:" -msgstr "" - -#: ../gtk/setupwizard.c:102 ../gtk/password.ui.h:4 ../gtk/ldap.ui.h:5 -msgid "Password:" -msgstr "" - -#: ../gtk/setupwizard.c:122 -msgid "Enter your account informations" -msgstr "" - -#: ../gtk/setupwizard.c:138 -msgid "Username*" -msgstr "" - -#: ../gtk/setupwizard.c:139 -msgid "Password*" -msgstr "" - -#: ../gtk/setupwizard.c:142 -msgid "Domain*" -msgstr "" - -#: ../gtk/setupwizard.c:143 -msgid "Proxy" -msgstr "" - -#: ../gtk/setupwizard.c:322 -msgid "(*) Required fields" -msgstr "" - -#: ../gtk/setupwizard.c:323 -msgid "Username: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:325 -msgid "Password: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:327 -msgid "Email: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:329 -msgid "Confirm your password: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:343 -msgid "Keep me informed with linphone updates" -msgstr "" - -#: ../gtk/setupwizard.c:399 -msgid "" -"Error, account not validated, username already used or server unreachable.\n" -"Please go back and try again." -msgstr "" - -#: ../gtk/setupwizard.c:410 -msgid "Thank you. Your account is now configured and ready for use." -msgstr "" - -#: ../gtk/setupwizard.c:418 -msgid "" -"Please validate your account by clicking on the link we just sent you by email.\n" -"Then come back here and press Next button." -msgstr "" - -#: ../gtk/setupwizard.c:609 -msgid "SIP account configuration assistant" -msgstr "" - -#: ../gtk/setupwizard.c:629 -msgid "Welcome to the account setup assistant" -msgstr "" - -#: ../gtk/setupwizard.c:634 -msgid "Account setup assistant" -msgstr "" - -#: ../gtk/setupwizard.c:640 -msgid "Configure your account (step 1/1)" -msgstr "" - -#: ../gtk/setupwizard.c:645 -msgid "Enter your sip username (step 1/1)" -msgstr "" - -#: ../gtk/setupwizard.c:649 -msgid "Enter account information (step 1/2)" -msgstr "" - -#: ../gtk/setupwizard.c:658 -msgid "Validation (step 2/2)" -msgstr "" - -#: ../gtk/setupwizard.c:663 -msgid "Error" -msgstr "" - -#: ../gtk/setupwizard.c:667 ../gtk/audio_assistant.c:534 -msgid "Terminating" -msgstr "" - -#: ../gtk/incall_view.c:70 ../gtk/incall_view.c:94 +#: ../gtk/incall_view.c:67 ../gtk/incall_view.c:87 #, c-format msgid "Call #%i" msgstr "" -#: ../gtk/incall_view.c:155 +#: ../gtk/incall_view.c:145 #, c-format msgid "Transfer to call #%i with %s" msgstr "" -#: ../gtk/incall_view.c:211 ../gtk/incall_view.c:214 +#: ../gtk/incall_view.c:202 ../gtk/incall_view.c:205 msgid "Not used" msgstr "" -#: ../gtk/incall_view.c:221 +#: ../gtk/incall_view.c:212 msgid "ICE not activated" msgstr "" -#: ../gtk/incall_view.c:223 +#: ../gtk/incall_view.c:214 msgid "ICE failed" msgstr "" -#: ../gtk/incall_view.c:225 +#: ../gtk/incall_view.c:216 msgid "ICE in progress" msgstr "" -#: ../gtk/incall_view.c:227 +#: ../gtk/incall_view.c:218 msgid "Going through one or more NATs" msgstr "" -#: ../gtk/incall_view.c:229 +#: ../gtk/incall_view.c:220 msgid "Direct" msgstr "" -#: ../gtk/incall_view.c:231 +#: ../gtk/incall_view.c:222 msgid "Through a relay server" msgstr "" -#: ../gtk/incall_view.c:239 +#: ../gtk/incall_view.c:230 msgid "uPnP not activated" msgstr "" -#: ../gtk/incall_view.c:241 +#: ../gtk/incall_view.c:232 msgid "uPnP in progress" msgstr "" -#: ../gtk/incall_view.c:243 +#: ../gtk/incall_view.c:234 msgid "uPnp not available" msgstr "" -#: ../gtk/incall_view.c:245 +#: ../gtk/incall_view.c:236 msgid "uPnP is running" msgstr "" -#: ../gtk/incall_view.c:247 +#: ../gtk/incall_view.c:238 msgid "uPnP failed" msgstr "" -#: ../gtk/incall_view.c:257 ../gtk/incall_view.c:258 +#: ../gtk/incall_view.c:248 ../gtk/incall_view.c:249 msgid "Direct or through server" msgstr "" -#: ../gtk/incall_view.c:267 ../gtk/incall_view.c:279 +#: ../gtk/incall_view.c:258 ../gtk/incall_view.c:270 #, c-format msgid "" "download: %f\n" "upload: %f (kbit/s)" msgstr "" -#: ../gtk/incall_view.c:272 ../gtk/incall_view.c:274 +#: ../gtk/incall_view.c:263 ../gtk/incall_view.c:265 #, c-format msgid "%ix%i @ %f fps" msgstr "" -#: ../gtk/incall_view.c:304 +#: ../gtk/incall_view.c:295 #, c-format msgid "%.3f seconds" msgstr "" -#: ../gtk/incall_view.c:407 ../gtk/main.ui.h:12 ../gtk/videowindow.c:235 +#: ../gtk/incall_view.c:453 ../gtk/in_call_frame.ui.h:10 +#: ../gtk/videowindow.c:236 msgid "Hang up" msgstr "" -#: ../gtk/incall_view.c:511 +#: ../gtk/incall_view.c:559 msgid "Calling..." msgstr "" -#: ../gtk/incall_view.c:514 ../gtk/incall_view.c:733 -msgid "00::00::00" +#: ../gtk/incall_view.c:562 ../gtk/incall_view.c:792 +msgid "00:00:00" msgstr "" -#: ../gtk/incall_view.c:525 +#: ../gtk/incall_view.c:573 msgid "Incoming call" msgstr "" -#: ../gtk/incall_view.c:562 +#: ../gtk/incall_view.c:610 msgid "good" msgstr "" -#: ../gtk/incall_view.c:564 +#: ../gtk/incall_view.c:612 msgid "average" msgstr "" -#: ../gtk/incall_view.c:566 +#: ../gtk/incall_view.c:614 msgid "poor" msgstr "" -#: ../gtk/incall_view.c:568 +#: ../gtk/incall_view.c:616 msgid "very poor" msgstr "" -#: ../gtk/incall_view.c:570 +#: ../gtk/incall_view.c:618 msgid "too bad" msgstr "" -#: ../gtk/incall_view.c:571 ../gtk/incall_view.c:587 +#: ../gtk/incall_view.c:619 ../gtk/incall_view.c:635 msgid "unavailable" msgstr "" -#: ../gtk/incall_view.c:679 +#: ../gtk/incall_view.c:731 msgid "Secured by SRTP" msgstr "" -#: ../gtk/incall_view.c:685 +#: ../gtk/incall_view.c:737 msgid "Secured by DTLS" msgstr "" -#: ../gtk/incall_view.c:691 +#: ../gtk/incall_view.c:743 #, c-format msgid "Secured by ZRTP - [auth token: %s]" msgstr "" -#: ../gtk/incall_view.c:697 +#: ../gtk/incall_view.c:747 msgid "Set unverified" msgstr "" -#: ../gtk/incall_view.c:697 ../gtk/main.ui.h:4 +#: ../gtk/incall_view.c:747 msgid "Set verified" msgstr "" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In conference" msgstr "" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In call" msgstr "" -#: ../gtk/incall_view.c:764 +#: ../gtk/incall_view.c:824 msgid "Paused call" msgstr "" -#: ../gtk/incall_view.c:800 +#: ../gtk/incall_view.c:861 msgid "Call ended." msgstr "" -#: ../gtk/incall_view.c:831 +#: ../gtk/incall_view.c:892 msgid "Transfer in progress" msgstr "" -#: ../gtk/incall_view.c:834 +#: ../gtk/incall_view.c:895 msgid "Transfer done." msgstr "" -#: ../gtk/incall_view.c:837 +#: ../gtk/incall_view.c:898 msgid "Transfer failed." msgstr "" -#: ../gtk/incall_view.c:881 +#: ../gtk/incall_view.c:929 msgid "Resume" msgstr "" -#: ../gtk/incall_view.c:888 ../gtk/main.ui.h:9 +#: ../gtk/incall_view.c:929 ../gtk/in_call_frame.ui.h:7 msgid "Pause" msgstr "" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 #, c-format msgid "" "Recording into\n" "%s %s" msgstr "" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 msgid "(Paused)" msgstr "" -#: ../gtk/loginframe.c:87 +#: ../gtk/loginframe.c:75 #, c-format msgid "Please enter login information for %s" msgstr "" @@ -754,262 +651,107 @@ msgstr "" msgid "Downloading of remote configuration from %s failed." msgstr "" -#: ../gtk/audio_assistant.c:98 +#: ../gtk/audio_assistant.c:103 msgid "No voice detected" msgstr "" -#: ../gtk/audio_assistant.c:99 +#: ../gtk/audio_assistant.c:104 msgid "Too low" msgstr "" -#: ../gtk/audio_assistant.c:100 +#: ../gtk/audio_assistant.c:105 msgid "Good" msgstr "" -#: ../gtk/audio_assistant.c:101 +#: ../gtk/audio_assistant.c:106 msgid "Too loud" msgstr "" -#: ../gtk/audio_assistant.c:183 +#: ../gtk/audio_assistant.c:188 msgid "Did you hear three beeps ?" msgstr "" -#: ../gtk/audio_assistant.c:292 ../gtk/audio_assistant.c:297 +#: ../gtk/audio_assistant.c:299 ../gtk/audio_assistant.c:304 msgid "Sound preferences not found " msgstr "" -#: ../gtk/audio_assistant.c:306 +#: ../gtk/audio_assistant.c:313 msgid "Cannot launch system sound control " msgstr "" -#: ../gtk/audio_assistant.c:318 +#: ../gtk/audio_assistant.c:325 msgid "" "Welcome!\n" "This assistant will help you to configure audio settings for Linphone" msgstr "" -#: ../gtk/audio_assistant.c:328 +#: ../gtk/audio_assistant.c:335 msgid "Capture device" msgstr "" -#: ../gtk/audio_assistant.c:329 +#: ../gtk/audio_assistant.c:336 msgid "Recorded volume" msgstr "" -#: ../gtk/audio_assistant.c:333 +#: ../gtk/audio_assistant.c:340 msgid "No voice" msgstr "" -#: ../gtk/audio_assistant.c:334 ../gtk/audio_assistant.c:373 +#: ../gtk/audio_assistant.c:341 ../gtk/audio_assistant.c:380 msgid "System sound preferences" msgstr "" -#: ../gtk/audio_assistant.c:369 +#: ../gtk/audio_assistant.c:376 msgid "Playback device" msgstr "" -#: ../gtk/audio_assistant.c:370 +#: ../gtk/audio_assistant.c:377 msgid "Play three beeps" msgstr "" -#: ../gtk/audio_assistant.c:403 +#: ../gtk/audio_assistant.c:410 msgid "Press the record button and say some words" msgstr "" -#: ../gtk/audio_assistant.c:404 +#: ../gtk/audio_assistant.c:411 msgid "Listen to your record voice" msgstr "" -#: ../gtk/audio_assistant.c:405 +#: ../gtk/audio_assistant.c:412 ../gtk/conf_frame.ui.h:2 +#: ../gtk/in_call_frame.ui.h:4 msgid "Record" msgstr "" -#: ../gtk/audio_assistant.c:406 +#: ../gtk/audio_assistant.c:413 msgid "Play" msgstr "" -#: ../gtk/audio_assistant.c:433 +#: ../gtk/audio_assistant.c:440 msgid "Let's start Linphone now" msgstr "" -#: ../gtk/audio_assistant.c:503 +#: ../gtk/audio_assistant.c:510 msgid "Audio Assistant" msgstr "" -#: ../gtk/audio_assistant.c:513 ../gtk/main.ui.h:32 +#: ../gtk/audio_assistant.c:520 ../gtk/main.ui.h:13 msgid "Audio assistant" msgstr "" -#: ../gtk/audio_assistant.c:518 +#: ../gtk/audio_assistant.c:525 msgid "Mic Gain calibration" msgstr "" -#: ../gtk/audio_assistant.c:524 +#: ../gtk/audio_assistant.c:531 msgid "Speaker volume calibration" msgstr "" -#: ../gtk/audio_assistant.c:529 +#: ../gtk/audio_assistant.c:536 msgid "Record and Play" msgstr "" -#: ../gtk/main.ui.h:1 -msgid "Callee name" -msgstr "" - -#: ../gtk/main.ui.h:2 -msgid "Send" -msgstr "" - -#: ../gtk/main.ui.h:3 -msgid "End conference" -msgstr "" - -#: ../gtk/main.ui.h:7 -msgid "Record this call to an audio file" -msgstr "" - -#: ../gtk/main.ui.h:8 -msgid "Video" -msgstr "" - -#: ../gtk/main.ui.h:10 -msgid "Mute" -msgstr "" - -#: ../gtk/main.ui.h:11 -msgid "Transfer" -msgstr "" - -#: ../gtk/main.ui.h:14 -msgid "In call" -msgstr "" - -#: ../gtk/main.ui.h:15 -msgid "Duration" -msgstr "" - -#: ../gtk/main.ui.h:16 -msgid "Call quality rating" -msgstr "" - -#: ../gtk/main.ui.h:17 -msgid "All users" -msgstr "" - -#: ../gtk/main.ui.h:18 -msgid "Online users" -msgstr "" - -#: ../gtk/main.ui.h:19 -msgid "ADSL" -msgstr "" - -#: ../gtk/main.ui.h:20 -msgid "Fiber Channel" -msgstr "" - -#: ../gtk/main.ui.h:21 -msgid "Default" -msgstr "" - -#: ../gtk/main.ui.h:22 -msgid "Delete" -msgstr "" - -#: ../gtk/main.ui.h:23 -msgid "_Options" -msgstr "" - -#: ../gtk/main.ui.h:24 -msgid "Set configuration URI" -msgstr "" - -#: ../gtk/main.ui.h:25 -msgid "Always start video" -msgstr "" - -#: ../gtk/main.ui.h:26 -msgid "Enable self-view" -msgstr "" - -#: ../gtk/main.ui.h:27 -msgid "_Help" -msgstr "" - -#: ../gtk/main.ui.h:28 -msgid "Show debug window" -msgstr "" - -#: ../gtk/main.ui.h:29 -msgid "_Homepage" -msgstr "" - -#: ../gtk/main.ui.h:30 -msgid "Check _Updates" -msgstr "" - -#: ../gtk/main.ui.h:31 -msgid "Account assistant" -msgstr "" - -#: ../gtk/main.ui.h:33 -msgid "SIP address or phone number:" -msgstr "" - -#: ../gtk/main.ui.h:34 -msgid "Initiate a new call" -msgstr "" - -#: ../gtk/main.ui.h:35 -msgid "Contacts" -msgstr "" - -#: ../gtk/main.ui.h:36 -msgid "Search" -msgstr "" - -#: ../gtk/main.ui.h:37 -msgid "Add contacts from directory" -msgstr "" - -#: ../gtk/main.ui.h:38 -msgid "Add contact" -msgstr "" - -#: ../gtk/main.ui.h:39 -msgid "Recent calls" -msgstr "" - -#: ../gtk/main.ui.h:40 -msgid "My current identity:" -msgstr "" - -#: ../gtk/main.ui.h:41 ../gtk/tunnel_config.ui.h:7 -msgid "Username" -msgstr "" - -#: ../gtk/main.ui.h:42 ../gtk/tunnel_config.ui.h:8 -msgid "Password" -msgstr "" - -#: ../gtk/main.ui.h:43 -msgid "Internet connection:" -msgstr "" - -#: ../gtk/main.ui.h:44 -msgid "Automatically log me in" -msgstr "" - -#: ../gtk/main.ui.h:45 ../gtk/password.ui.h:3 -msgid "UserID" -msgstr "" - -#: ../gtk/main.ui.h:46 -msgid "Login information" -msgstr "" - -#: ../gtk/main.ui.h:47 -msgid "Welcome!" +#: ../gtk/audio_assistant.c:541 ../gtk/setup_wizard.ui.h:38 +msgid "Terminating" msgstr "" #: ../gtk/about.ui.h:1 @@ -1040,456 +782,6 @@ msgid "" "he: Eli Zaretskii \n" msgstr "" -#: ../gtk/contact.ui.h:2 -msgid "SIP Address" -msgstr "" - -#: ../gtk/contact.ui.h:3 -msgid "Show this contact presence status" -msgstr "" - -#: ../gtk/contact.ui.h:4 -msgid "Allow this contact to see my presence status" -msgstr "" - -#: ../gtk/contact.ui.h:5 -msgid "Contact information" -msgstr "" - -#: ../gtk/log.ui.h:1 -msgid "Linphone debug window" -msgstr "" - -#: ../gtk/log.ui.h:2 -msgid "Scroll to end" -msgstr "" - -#: ../gtk/password.ui.h:1 -msgid "Linphone - Authentication required" -msgstr "" - -#: ../gtk/password.ui.h:2 -msgid "Please enter the domain password" -msgstr "" - -#: ../gtk/call_logs.ui.h:1 -msgid "Call history" -msgstr "" - -#: ../gtk/call_logs.ui.h:2 -msgid "Clear all" -msgstr "" - -#: ../gtk/call_logs.ui.h:3 -msgid "Call back" -msgstr "" - -#: ../gtk/sip_account.ui.h:1 -msgid "Linphone - Configure a SIP account" -msgstr "" - -#: ../gtk/sip_account.ui.h:2 -msgid "Your SIP identity:" -msgstr "" - -#: ../gtk/sip_account.ui.h:3 -msgid "Looks like sip:@" -msgstr "" - -#: ../gtk/sip_account.ui.h:4 -msgid "sip:" -msgstr "sip:" - -#: ../gtk/sip_account.ui.h:5 -msgid "SIP Proxy address:" -msgstr "" - -#: ../gtk/sip_account.ui.h:6 -msgid "Looks like sip:" -msgstr "" - -#: ../gtk/sip_account.ui.h:7 -msgid "Registration duration (sec):" -msgstr "" - -#: ../gtk/sip_account.ui.h:8 -msgid "Contact params (optional):" -msgstr "" - -#: ../gtk/sip_account.ui.h:9 -msgid "AVPF regular RTCP interval (sec):" -msgstr "" - -#: ../gtk/sip_account.ui.h:10 -msgid "Route (optional):" -msgstr "" - -#: ../gtk/sip_account.ui.h:11 -msgid "Transport" -msgstr "" - -#: ../gtk/sip_account.ui.h:12 -msgid "Register" -msgstr "" - -#: ../gtk/sip_account.ui.h:13 -msgid "Publish presence information" -msgstr "" - -#: ../gtk/sip_account.ui.h:14 -msgid "Enable AVPF" -msgstr "" - -#: ../gtk/sip_account.ui.h:15 -msgid "Configure a SIP account" -msgstr "" - -#: ../gtk/parameters.ui.h:1 -msgid "anonymous" -msgstr "" - -#: ../gtk/parameters.ui.h:2 -msgid "GSSAPI" -msgstr "" - -#: ../gtk/parameters.ui.h:3 -msgid "SASL" -msgstr "" - -#: ../gtk/parameters.ui.h:4 -msgid "default soundcard" -msgstr "" - -#: ../gtk/parameters.ui.h:5 -msgid "a sound card" -msgstr "" - -#: ../gtk/parameters.ui.h:6 -msgid "default camera" -msgstr "" - -#: ../gtk/parameters.ui.h:7 -msgid "CIF" -msgstr "" - -#: ../gtk/parameters.ui.h:8 -msgid "Audio codecs" -msgstr "" - -#: ../gtk/parameters.ui.h:9 -msgid "Video codecs" -msgstr "" - -#: ../gtk/parameters.ui.h:10 -msgid "C" -msgstr "" - -#: ../gtk/parameters.ui.h:11 -msgid "SIP (UDP)" -msgstr "" - -#: ../gtk/parameters.ui.h:12 -msgid "SIP (TCP)" -msgstr "" - -#: ../gtk/parameters.ui.h:13 -msgid "SIP (TLS)" -msgstr "" - -#: ../gtk/parameters.ui.h:14 -msgid "Settings" -msgstr "" - -#: ../gtk/parameters.ui.h:15 -msgid "Set Maximum Transmission Unit:" -msgstr "" - -#: ../gtk/parameters.ui.h:16 -msgid "Send DTMFs as SIP info" -msgstr "" - -#: ../gtk/parameters.ui.h:17 -msgid "Allow IPv6" -msgstr "" - -#: ../gtk/parameters.ui.h:18 -msgid "Transport" -msgstr "" - -#: ../gtk/parameters.ui.h:19 -msgid "SIP/UDP port" -msgstr "" - -#: ../gtk/parameters.ui.h:21 -msgid "Random" -msgstr "" - -#: ../gtk/parameters.ui.h:22 -msgid "SIP/TCP port" -msgstr "" - -#: ../gtk/parameters.ui.h:23 -msgid "Audio RTP/UDP:" -msgstr "" - -#: ../gtk/parameters.ui.h:24 -msgid "Fixed" -msgstr "" - -#: ../gtk/parameters.ui.h:25 -msgid "Video RTP/UDP:" -msgstr "" - -#: ../gtk/parameters.ui.h:26 -msgid "Media encryption type" -msgstr "" - -#: ../gtk/parameters.ui.h:27 -msgid "Media encryption is mandatory" -msgstr "" - -#: ../gtk/parameters.ui.h:28 -msgid "Tunnel" -msgstr "" - -#: ../gtk/parameters.ui.h:29 -msgid "DSCP fields" -msgstr "" - -#: ../gtk/parameters.ui.h:30 -msgid "Network protocol and ports" -msgstr "" - -#: ../gtk/parameters.ui.h:31 -msgid "Direct connection to the Internet" -msgstr "" - -#: ../gtk/parameters.ui.h:32 -msgid "Behind NAT / Firewall (specify gateway IP )" -msgstr "" - -#: ../gtk/parameters.ui.h:33 -msgid "Behind NAT / Firewall (use STUN to resolve)" -msgstr "" - -#: ../gtk/parameters.ui.h:34 -msgid "Behind NAT / Firewall (use ICE)" -msgstr "" - -#: ../gtk/parameters.ui.h:35 -msgid "Behind NAT / Firewall (use uPnP)" -msgstr "" - -#: ../gtk/parameters.ui.h:36 -msgid "Public IP address:" -msgstr "" - -#: ../gtk/parameters.ui.h:37 -msgid "Stun server:" -msgstr "" - -#: ../gtk/parameters.ui.h:38 -msgid "NAT and Firewall" -msgstr "" - -#: ../gtk/parameters.ui.h:39 -msgid "Network settings" -msgstr "" - -#: ../gtk/parameters.ui.h:40 -msgid "Ring sound:" -msgstr "" - -#: ../gtk/parameters.ui.h:41 -msgid "ALSA special device (optional):" -msgstr "" - -#: ../gtk/parameters.ui.h:42 -msgid "Capture device:" -msgstr "" - -#: ../gtk/parameters.ui.h:43 -msgid "Ring device:" -msgstr "" - -#: ../gtk/parameters.ui.h:44 -msgid "Playback device:" -msgstr "" - -#: ../gtk/parameters.ui.h:45 -msgid "Enable echo cancellation" -msgstr "" - -#: ../gtk/parameters.ui.h:46 -msgid "Audio" -msgstr "" - -#: ../gtk/parameters.ui.h:47 -msgid "Video input device:" -msgstr "" - -#: ../gtk/parameters.ui.h:48 -msgid "Prefered video resolution:" -msgstr "" - -#: ../gtk/parameters.ui.h:49 -msgid "Video output method:" -msgstr "" - -#: ../gtk/parameters.ui.h:50 -msgid "Show camera preview" -msgstr "" - -#: ../gtk/parameters.ui.h:51 -msgid "Video" -msgstr "" - -#: ../gtk/parameters.ui.h:52 -msgid "Multimedia settings" -msgstr "" - -#: ../gtk/parameters.ui.h:53 -msgid "This section defines your SIP address when not using a SIP account" -msgstr "" - -#: ../gtk/parameters.ui.h:54 -msgid "Your display name (eg: John Doe):" -msgstr "" - -#: ../gtk/parameters.ui.h:55 -msgid "Your username:" -msgstr "" - -#: ../gtk/parameters.ui.h:56 -msgid "Your resulting SIP address:" -msgstr "" - -#: ../gtk/parameters.ui.h:57 -msgid "Default identity" -msgstr "" - -#: ../gtk/parameters.ui.h:58 -msgid "Wizard" -msgstr "" - -#: ../gtk/parameters.ui.h:59 -msgid "Add" -msgstr "" - -#: ../gtk/parameters.ui.h:60 -msgid "Edit" -msgstr "" - -#: ../gtk/parameters.ui.h:61 -msgid "Remove" -msgstr "" - -#: ../gtk/parameters.ui.h:62 -msgid "Proxy accounts" -msgstr "" - -#: ../gtk/parameters.ui.h:63 -msgid "Erase all passwords" -msgstr "" - -#: ../gtk/parameters.ui.h:64 -msgid "Privacy" -msgstr "" - -#: ../gtk/parameters.ui.h:65 -msgid "Automatically answer when a call is received" -msgstr "" - -#: ../gtk/parameters.ui.h:66 -msgid "Delay before answering (ms)" -msgstr "" - -#: ../gtk/parameters.ui.h:67 -msgid "Auto-answer" -msgstr "" - -#: ../gtk/parameters.ui.h:68 -msgid "Manage SIP Accounts" -msgstr "" - -#: ../gtk/parameters.ui.h:69 ../gtk/tunnel_config.ui.h:4 -msgid "Enable" -msgstr "Włączony" - -#: ../gtk/parameters.ui.h:70 ../gtk/tunnel_config.ui.h:5 -msgid "Disable" -msgstr "Wyłącz" - -#: ../gtk/parameters.ui.h:71 -msgid "Codecs" -msgstr "" - -#: ../gtk/parameters.ui.h:72 -msgid "0 stands for \"unlimited\"" -msgstr "" - -#: ../gtk/parameters.ui.h:73 -msgid "Upload speed limit in Kbit/sec:" -msgstr "" - -#: ../gtk/parameters.ui.h:74 -msgid "Download speed limit in Kbit/sec:" -msgstr "" - -#: ../gtk/parameters.ui.h:75 -msgid "Enable adaptive rate control" -msgstr "" - -#: ../gtk/parameters.ui.h:76 -msgid "" -"Adaptive rate control is a technique to dynamically guess the available " -"bandwidth during a call." -msgstr "" - -#: ../gtk/parameters.ui.h:77 -msgid "Bandwidth control" -msgstr "" - -#: ../gtk/parameters.ui.h:78 -msgid "Codecs" -msgstr "" - -#: ../gtk/parameters.ui.h:79 -msgid "Language" -msgstr "" - -#: ../gtk/parameters.ui.h:80 -msgid "Show advanced settings" -msgstr "" - -#: ../gtk/parameters.ui.h:81 -msgid "Level" -msgstr "" - -#: ../gtk/parameters.ui.h:82 -msgid "User interface" -msgstr "" - -#: ../gtk/parameters.ui.h:83 ../gtk/ldap.ui.h:2 -msgid "Server address:" -msgstr "" - -#: ../gtk/parameters.ui.h:84 ../gtk/ldap.ui.h:3 -msgid "Authentication method:" -msgstr "" - -#: ../gtk/parameters.ui.h:86 -msgid "LDAP Account setup" -msgstr "" - -#: ../gtk/parameters.ui.h:87 -msgid "LDAP" -msgstr "" - -#: ../gtk/parameters.ui.h:88 -msgid "Done" -msgstr "" - #: ../gtk/buddylookup.ui.h:1 msgid "Search contacts in directory" msgstr "" @@ -1502,28 +794,20 @@ msgstr "" msgid "Search somebody" msgstr "" -#: ../gtk/waiting.ui.h:2 -msgid "Please wait" +#: ../gtk/callee_frame.ui.h:1 +msgid "Callee name" msgstr "" -#: ../gtk/dscp_settings.ui.h:1 -msgid "DSCP settings" +#: ../gtk/call_logs.ui.h:1 +msgid "Call history" msgstr "" -#: ../gtk/dscp_settings.ui.h:2 -msgid "SIP" -msgstr "SIP" - -#: ../gtk/dscp_settings.ui.h:3 -msgid "Audio RTP stream" +#: ../gtk/call_logs.ui.h:2 +msgid "Clear all" msgstr "" -#: ../gtk/dscp_settings.ui.h:4 -msgid "Video RTP stream" -msgstr "" - -#: ../gtk/dscp_settings.ui.h:5 -msgid "Set DSCP values (in hexadecimal)" +#: ../gtk/call_logs.ui.h:3 +msgid "Call back" msgstr "" #: ../gtk/call_statistics.ui.h:1 @@ -1574,30 +858,112 @@ msgstr "" msgid "Call statistics and information" msgstr "" -#: ../gtk/tunnel_config.ui.h:1 -msgid "Configure VoIP tunnel" +#: ../gtk/chatroom_frame.ui.h:1 +msgid "Send" msgstr "" -#: ../gtk/tunnel_config.ui.h:2 -msgid "Host" +#: ../gtk/conf_frame.ui.h:1 +msgid "End conference" msgstr "" -#: ../gtk/tunnel_config.ui.h:3 -msgid "Port" +#: ../gtk/config-uri.ui.h:1 +msgid "Specifying a remote configuration URI" msgstr "" -#: ../gtk/tunnel_config.ui.h:6 -msgid "Configure tunnel" +#: ../gtk/config-uri.ui.h:2 +msgid "" +"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" +"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " msgstr "" -#: ../gtk/tunnel_config.ui.h:9 -msgid "Configure http proxy (optional)" +#: ../gtk/contact.ui.h:2 +msgid "SIP Address" +msgstr "" + +#: ../gtk/contact.ui.h:3 +msgid "Show this contact presence status" +msgstr "" + +#: ../gtk/contact.ui.h:4 +msgid "Allow this contact to see my presence status" +msgstr "" + +#: ../gtk/contact.ui.h:5 +msgid "Contact information" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:1 +msgid "DSCP settings" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:2 +msgid "SIP" +msgstr "SIP" + +#: ../gtk/dscp_settings.ui.h:3 +msgid "Audio RTP stream" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:4 +msgid "Video RTP stream" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:5 +msgid "Set DSCP values (in hexadecimal)" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:1 +msgid "Click here to set the speakers volume" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:5 +msgid "Record this call to an audio file" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:6 +msgid "Video" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:8 +msgid "Mute" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:9 +msgid "Transfer" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:12 +msgid "In call" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:13 +msgid "Duration" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:14 +msgid "Call quality rating" msgstr "" #: ../gtk/ldap.ui.h:1 msgid "LDAP Settings" msgstr "" +#: ../gtk/ldap.ui.h:2 ../gtk/parameters.ui.h:89 +msgid "Server address:" +msgstr "" + +#: ../gtk/ldap.ui.h:3 ../gtk/parameters.ui.h:90 +msgid "Authentication method:" +msgstr "" + +#: ../gtk/ldap.ui.h:4 ../gtk/parameters.ui.h:91 ../gtk/setup_wizard.ui.h:17 +msgid "Username:" +msgstr "" + +#: ../gtk/ldap.ui.h:5 ../gtk/password.ui.h:4 ../gtk/setup_wizard.ui.h:18 +msgid "Password:" +msgstr "" + #: ../gtk/ldap.ui.h:6 msgid "Use TLS Connection" msgstr "" @@ -1683,14 +1049,502 @@ msgstr "" msgid "NTLM" msgstr "" -#: ../gtk/config-uri.ui.h:1 -msgid "Specifying a remote configuration URI" +#: ../gtk/login_frame.ui.h:1 ../gtk/tunnel_config.ui.h:7 +msgid "Username" msgstr "" -#: ../gtk/config-uri.ui.h:2 +#: ../gtk/login_frame.ui.h:2 ../gtk/tunnel_config.ui.h:8 +msgid "Password" +msgstr "" + +#: ../gtk/login_frame.ui.h:3 +msgid "Internet connection:" +msgstr "" + +#: ../gtk/login_frame.ui.h:4 +msgid "Automatically log me in" +msgstr "" + +#: ../gtk/login_frame.ui.h:5 ../gtk/password.ui.h:3 +msgid "UserID" +msgstr "" + +#: ../gtk/login_frame.ui.h:6 +msgid "Login information" +msgstr "" + +#: ../gtk/login_frame.ui.h:7 +msgid "Welcome!" +msgstr "" + +#: ../gtk/login_frame.ui.h:8 +msgid "ADSL" +msgstr "" + +#: ../gtk/login_frame.ui.h:9 +msgid "Fiber Channel" +msgstr "" + +#: ../gtk/log.ui.h:1 +msgid "Linphone debug window" +msgstr "" + +#: ../gtk/log.ui.h:2 +msgid "Scroll to end" +msgstr "" + +#: ../gtk/main.ui.h:1 +msgid "Default" +msgstr "" + +#: ../gtk/main.ui.h:2 +msgid "Delete" +msgstr "" + +#: ../gtk/main.ui.h:3 +msgid "_Options" +msgstr "" + +#: ../gtk/main.ui.h:4 +msgid "Set configuration URI" +msgstr "" + +#: ../gtk/main.ui.h:5 +msgid "Always start video" +msgstr "" + +#: ../gtk/main.ui.h:6 +msgid "Enable self-view" +msgstr "" + +#: ../gtk/main.ui.h:7 +msgid "Show keypad" +msgstr "" + +#: ../gtk/main.ui.h:8 +msgid "_Help" +msgstr "" + +#: ../gtk/main.ui.h:9 +msgid "Show debug window" +msgstr "" + +#: ../gtk/main.ui.h:10 +msgid "_Homepage" +msgstr "" + +#: ../gtk/main.ui.h:11 +msgid "Check _Updates" +msgstr "" + +#: ../gtk/main.ui.h:12 +msgid "Account assistant" +msgstr "" + +#: ../gtk/main.ui.h:14 +msgid "SIP address or phone number:" +msgstr "" + +#: ../gtk/main.ui.h:15 +msgid "Initiate a new call" +msgstr "" + +#: ../gtk/main.ui.h:16 +msgid "Contacts" +msgstr "" + +#: ../gtk/main.ui.h:17 +msgid "Search" +msgstr "" + +#: ../gtk/main.ui.h:18 +msgid "Add contacts from directory" +msgstr "" + +#: ../gtk/main.ui.h:19 +msgid "Add contact" +msgstr "" + +#: ../gtk/main.ui.h:20 +msgid "Clear call history" +msgstr "" + +#: ../gtk/main.ui.h:22 +msgid "My current identity:" +msgstr "" + +#: ../gtk/main.ui.h:23 +msgid "Autoanswer is enabled" +msgstr "" + +#: ../gtk/parameters.ui.h:1 +msgid "anonymous" +msgstr "" + +#: ../gtk/parameters.ui.h:2 +msgid "GSSAPI" +msgstr "" + +#: ../gtk/parameters.ui.h:3 +msgid "SASL" +msgstr "" + +#: ../gtk/parameters.ui.h:4 +msgid "default soundcard" +msgstr "" + +#: ../gtk/parameters.ui.h:5 +msgid "a sound card" +msgstr "" + +#: ../gtk/parameters.ui.h:6 +msgid "default camera" +msgstr "" + +#: ../gtk/parameters.ui.h:7 +msgid "CIF" +msgstr "" + +#: ../gtk/parameters.ui.h:8 +msgid "Audio codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:9 +msgid "Video codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:10 +msgid "C" +msgstr "" + +#: ../gtk/parameters.ui.h:11 +msgid "SIP (UDP)" +msgstr "" + +#: ../gtk/parameters.ui.h:12 +msgid "SIP (TCP)" +msgstr "" + +#: ../gtk/parameters.ui.h:13 +msgid "SIP (TLS)" +msgstr "" + +#: ../gtk/parameters.ui.h:14 +msgid "default" +msgstr "" + +#: ../gtk/parameters.ui.h:15 +msgid "high-fps" +msgstr "" + +#: ../gtk/parameters.ui.h:16 +msgid "custom" +msgstr "" + +#: ../gtk/parameters.ui.h:17 +msgid "Settings" +msgstr "" + +#: ../gtk/parameters.ui.h:18 +msgid "This section defines your SIP address when not using a SIP account" +msgstr "" + +#: ../gtk/parameters.ui.h:19 +msgid "Your display name (eg: John Doe):" +msgstr "" + +#: ../gtk/parameters.ui.h:20 +msgid "Your username:" +msgstr "" + +#: ../gtk/parameters.ui.h:21 +msgid "Your resulting SIP address:" +msgstr "" + +#: ../gtk/parameters.ui.h:22 +msgid "Default identity" +msgstr "" + +#: ../gtk/parameters.ui.h:23 +msgid "Wizard" +msgstr "" + +#: ../gtk/parameters.ui.h:24 +msgid "Add" +msgstr "" + +#: ../gtk/parameters.ui.h:25 +msgid "Edit" +msgstr "" + +#: ../gtk/parameters.ui.h:26 +msgid "Remove" +msgstr "" + +#: ../gtk/parameters.ui.h:27 +msgid "Proxy accounts" +msgstr "" + +#: ../gtk/parameters.ui.h:28 +msgid "Erase all passwords" +msgstr "" + +#: ../gtk/parameters.ui.h:29 +msgid "Privacy" +msgstr "" + +#: ../gtk/parameters.ui.h:30 +msgid "Automatically answer when a call is received" +msgstr "" + +#: ../gtk/parameters.ui.h:31 +msgid "Delay before answering (ms)" +msgstr "" + +#: ../gtk/parameters.ui.h:32 +msgid "Auto-answer" +msgstr "" + +#: ../gtk/parameters.ui.h:33 +msgid "Manage SIP Accounts" +msgstr "" + +#: ../gtk/parameters.ui.h:34 +msgid "Ring sound:" +msgstr "" + +#: ../gtk/parameters.ui.h:35 +msgid "ALSA special device (optional):" +msgstr "" + +#: ../gtk/parameters.ui.h:36 +msgid "Capture device:" +msgstr "" + +#: ../gtk/parameters.ui.h:37 +msgid "Ring device:" +msgstr "" + +#: ../gtk/parameters.ui.h:38 +msgid "Playback device:" +msgstr "" + +#: ../gtk/parameters.ui.h:39 +msgid "Enable echo cancellation" +msgstr "" + +#: ../gtk/parameters.ui.h:40 +msgid "Audio" +msgstr "" + +#: ../gtk/parameters.ui.h:41 +msgid "Video input device:" +msgstr "" + +#: ../gtk/parameters.ui.h:42 +msgid "Preferred video resolution:" +msgstr "" + +#: ../gtk/parameters.ui.h:43 +msgid "Video output method:" +msgstr "" + +#: ../gtk/parameters.ui.h:44 +msgid "Show camera preview" +msgstr "" + +#: ../gtk/parameters.ui.h:45 +msgid "Video preset:" +msgstr "" + +#: ../gtk/parameters.ui.h:46 +msgid "Preferred video framerate:" +msgstr "" + +#: ../gtk/parameters.ui.h:47 +msgid "0 stands for \"unlimited\"" +msgstr "" + +#: ../gtk/parameters.ui.h:48 +msgid "Video" +msgstr "" + +#: ../gtk/parameters.ui.h:49 +msgid "Upload speed limit in Kbit/sec:" +msgstr "" + +#: ../gtk/parameters.ui.h:50 +msgid "Download speed limit in Kbit/sec:" +msgstr "" + +#: ../gtk/parameters.ui.h:51 +msgid "Enable adaptive rate control" +msgstr "" + +#: ../gtk/parameters.ui.h:52 msgid "" -"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" -"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " +"Adaptive rate control is a technique to dynamically guess the available " +"bandwidth during a call." +msgstr "" + +#: ../gtk/parameters.ui.h:53 +msgid "Bandwidth control" +msgstr "" + +#: ../gtk/parameters.ui.h:54 +msgid "Multimedia settings" +msgstr "" + +#: ../gtk/parameters.ui.h:55 +msgid "Set Maximum Transmission Unit:" +msgstr "" + +#: ../gtk/parameters.ui.h:56 +msgid "Send DTMFs as SIP info" +msgstr "" + +#: ../gtk/parameters.ui.h:57 +msgid "Allow IPv6" +msgstr "" + +#: ../gtk/parameters.ui.h:58 +msgid "Transport" +msgstr "" + +#: ../gtk/parameters.ui.h:59 +msgid "SIP/UDP port" +msgstr "" + +#: ../gtk/parameters.ui.h:61 +msgid "Random" +msgstr "" + +#: ../gtk/parameters.ui.h:62 +msgid "SIP/TCP port" +msgstr "" + +#: ../gtk/parameters.ui.h:63 +msgid "Audio RTP/UDP:" +msgstr "" + +#: ../gtk/parameters.ui.h:64 +msgid "Fixed" +msgstr "" + +#: ../gtk/parameters.ui.h:65 +msgid "Video RTP/UDP:" +msgstr "" + +#: ../gtk/parameters.ui.h:66 +msgid "Media encryption type" +msgstr "" + +#: ../gtk/parameters.ui.h:67 +msgid "Media encryption is mandatory" +msgstr "" + +#: ../gtk/parameters.ui.h:68 +msgid "Tunnel" +msgstr "" + +#: ../gtk/parameters.ui.h:69 +msgid "DSCP fields" +msgstr "" + +#: ../gtk/parameters.ui.h:70 +msgid "Network protocol and ports" +msgstr "" + +#: ../gtk/parameters.ui.h:71 +msgid "Direct connection to the Internet" +msgstr "" + +#: ../gtk/parameters.ui.h:72 +msgid "Behind NAT / Firewall (specify gateway IP )" +msgstr "" + +#: ../gtk/parameters.ui.h:73 +msgid "Behind NAT / Firewall (use STUN to resolve)" +msgstr "" + +#: ../gtk/parameters.ui.h:74 +msgid "Behind NAT / Firewall (use ICE)" +msgstr "" + +#: ../gtk/parameters.ui.h:75 +msgid "Behind NAT / Firewall (use uPnP)" +msgstr "" + +#: ../gtk/parameters.ui.h:76 +msgid "Public IP address:" +msgstr "" + +#: ../gtk/parameters.ui.h:77 +msgid "Stun server:" +msgstr "" + +#: ../gtk/parameters.ui.h:78 +msgid "NAT and Firewall" +msgstr "" + +#: ../gtk/parameters.ui.h:79 +msgid "Network settings" +msgstr "" + +#: ../gtk/parameters.ui.h:80 ../gtk/tunnel_config.ui.h:4 +msgid "Enable" +msgstr "Włączony" + +#: ../gtk/parameters.ui.h:81 ../gtk/tunnel_config.ui.h:5 +msgid "Disable" +msgstr "Wyłącz" + +#: ../gtk/parameters.ui.h:82 +msgid "Audio codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:83 +msgid "Video codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:84 +msgid "Codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:85 +msgid "Language" +msgstr "" + +#: ../gtk/parameters.ui.h:86 +msgid "Show advanced settings" +msgstr "" + +#: ../gtk/parameters.ui.h:87 +msgid "Level" +msgstr "" + +#: ../gtk/parameters.ui.h:88 +msgid "User interface" +msgstr "" + +#: ../gtk/parameters.ui.h:92 +msgid "LDAP Account setup" +msgstr "" + +#: ../gtk/parameters.ui.h:93 +msgid "LDAP" +msgstr "" + +#: ../gtk/parameters.ui.h:94 +msgid "Done" +msgstr "" + +#: ../gtk/password.ui.h:1 +msgid "Linphone - Authentication required" +msgstr "" + +#: ../gtk/password.ui.h:2 +msgid "Please enter the domain password" msgstr "" #: ../gtk/provisioning-fetch.ui.h:1 @@ -1701,68 +1555,278 @@ msgstr "" msgid "Please wait while fetching configuration from server..." msgstr "" -#: ../coreapi/linphonecore.c:1539 +#: ../gtk/setup_wizard.ui.h:1 +msgid "SIP account configuration assistant" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:2 +msgid "" +"Welcome!\n" +"This assistant will help you to use a SIP account for your calls." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:4 +msgid "Welcome to the account setup assistant" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:5 +msgid "Create an account on linphone.org" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:6 +msgid "I have already a linphone.org account and I just want to use it" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:7 +msgid "I have already a sip account and I just want to use it" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:8 +msgid "I want to specify a remote configuration URI" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:9 +msgid "Account setup assistant" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:10 +msgid "Enter your account information" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:11 +msgid "Username*" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:12 +msgid "Password*" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:13 +msgid "Domain*" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:14 +msgid "Proxy" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:15 +msgid "Configure your account (step 1/1)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:16 +msgid "Enter your linphone.org username" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:19 +msgid "Enter your sip username (step 1/1)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:20 +msgid "(*) Required fields" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:21 +msgid "Email: (*)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:22 +msgid "Username: (*)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:23 +msgid "Password: (*)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:24 +msgid "Confirm your password: (*)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:25 +msgid "Keep me informed with linphone updates" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:26 +msgid "Enter account information (step 1/2)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:27 +msgid "Your account is being created, please wait." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:28 +msgid "Account creation in progress" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:29 +msgid "" +"Please validate your account by clicking on the link we just sent you by email.\n" +"Then come back here and press Next button." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:31 +msgid "Validation (step 2/2)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:32 +msgid "Checking if your account is been validated, please wait." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:33 +msgid "Account validation check in progress" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:34 +msgid "" +"Error, account not validated, username already used or server unreachable.\n" +"Please go back and try again." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:36 +msgid "Error" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:37 +msgid "Thank you. Your account is now configured and ready for use." +msgstr "" + +#: ../gtk/sip_account.ui.h:1 +msgid "Linphone - Configure a SIP account" +msgstr "" + +#: ../gtk/sip_account.ui.h:2 +msgid "Your SIP identity:" +msgstr "" + +#: ../gtk/sip_account.ui.h:3 +msgid "Looks like sip:@" +msgstr "" + +#: ../gtk/sip_account.ui.h:4 +msgid "sip:" +msgstr "sip:" + +#: ../gtk/sip_account.ui.h:5 +msgid "SIP Proxy address:" +msgstr "" + +#: ../gtk/sip_account.ui.h:6 +msgid "Looks like sip:" +msgstr "" + +#: ../gtk/sip_account.ui.h:7 +msgid "Registration duration (sec):" +msgstr "" + +#: ../gtk/sip_account.ui.h:8 +msgid "Contact params (optional):" +msgstr "" + +#: ../gtk/sip_account.ui.h:9 +msgid "AVPF regular RTCP interval (sec):" +msgstr "" + +#: ../gtk/sip_account.ui.h:10 +msgid "Route (optional):" +msgstr "" + +#: ../gtk/sip_account.ui.h:11 +msgid "Transport" +msgstr "" + +#: ../gtk/sip_account.ui.h:12 +msgid "Register" +msgstr "" + +#: ../gtk/sip_account.ui.h:13 +msgid "Publish presence information" +msgstr "" + +#: ../gtk/sip_account.ui.h:14 +msgid "Enable AVPF" +msgstr "" + +#: ../gtk/sip_account.ui.h:15 +msgid "Configure a SIP account" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:1 +msgid "Configure VoIP tunnel" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:2 +msgid "Host" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:3 +msgid "Port" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:6 +msgid "Configure tunnel" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:9 +msgid "Configure http proxy (optional)" +msgstr "" + +#: ../gtk/waiting.ui.h:2 +msgid "Please wait" +msgstr "" + +#: ../coreapi/linphonecore.c:1560 msgid "Ready" msgstr "" -#: ../coreapi/linphonecore.c:2551 +#: ../coreapi/linphonecore.c:2556 msgid "Configuring" msgstr "" -#: ../coreapi/linphonecore.c:2725 -msgid "Looking for telephone number destination..." -msgstr "" - -#: ../coreapi/linphonecore.c:2727 -msgid "Could not resolve this number." -msgstr "" - #. must be known at that time -#: ../coreapi/linphonecore.c:3013 +#: ../coreapi/linphonecore.c:2951 msgid "Contacting" msgstr "" -#: ../coreapi/linphonecore.c:3018 +#: ../coreapi/linphonecore.c:2956 msgid "Could not call" msgstr "" -#: ../coreapi/linphonecore.c:3169 +#: ../coreapi/linphonecore.c:3092 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "" -#: ../coreapi/linphonecore.c:3327 +#: ../coreapi/linphonecore.c:3250 msgid "is contacting you" msgstr "" -#: ../coreapi/linphonecore.c:3328 +#: ../coreapi/linphonecore.c:3251 msgid " and asked autoanswer." msgstr "" -#: ../coreapi/linphonecore.c:3452 +#: ../coreapi/linphonecore.c:3377 msgid "Modifying call parameters..." msgstr "" -#: ../coreapi/linphonecore.c:3802 +#: ../coreapi/linphonecore.c:3769 msgid "Connected." msgstr "Połączony" -#: ../coreapi/linphonecore.c:3827 +#: ../coreapi/linphonecore.c:3794 msgid "Call aborted" msgstr "" -#: ../coreapi/linphonecore.c:4024 +#: ../coreapi/linphonecore.c:3983 msgid "Could not pause the call" msgstr "" -#: ../coreapi/linphonecore.c:4027 +#: ../coreapi/linphonecore.c:3986 msgid "Pausing the current call..." msgstr "" -#: ../coreapi/misc.c:434 +#: ../coreapi/misc.c:440 msgid "Stun lookup in progress..." msgstr "" -#: ../coreapi/misc.c:615 +#: ../coreapi/misc.c:650 msgid "ICE local candidates gathering in progress..." msgstr "" @@ -1818,143 +1882,150 @@ msgstr "" msgid "Unknown status" msgstr "" -#: ../coreapi/proxy.c:328 +#: ../coreapi/proxy.c:292 msgid "" "The sip proxy address you entered is invalid, it must start with \"sip:\" " "followed by a hostname." msgstr "" -#: ../coreapi/proxy.c:334 +#: ../coreapi/proxy.c:298 msgid "" "The sip identity you entered is invalid.\n" "It should look like sip:username@proxydomain, such as sip:alice@example.net" msgstr "" -#: ../coreapi/proxy.c:1416 +#: ../coreapi/proxy.c:927 +msgid "Looking for telephone number destination..." +msgstr "" + +#: ../coreapi/proxy.c:931 +msgid "Could not resolve this number." +msgstr "" + +#: ../coreapi/proxy.c:1324 #, c-format msgid "Could not login as %s" msgstr "" -#: ../coreapi/callbacks.c:428 +#: ../coreapi/proxy.c:1411 +#, c-format +msgid "Refreshing on %s..." +msgstr "" + +#: ../coreapi/callbacks.c:423 msgid "Remote ringing." msgstr "" -#: ../coreapi/callbacks.c:440 +#: ../coreapi/callbacks.c:435 msgid "Remote ringing..." msgstr "" -#: ../coreapi/callbacks.c:461 +#: ../coreapi/callbacks.c:458 msgid "Early media." msgstr "" -#: ../coreapi/callbacks.c:534 +#: ../coreapi/callbacks.c:488 #, c-format -msgid "Call with %s is paused." +msgid "Call answered by %s" msgstr "" -#: ../coreapi/callbacks.c:547 -#, c-format -msgid "Call answered by %s - on hold." -msgstr "" - -#: ../coreapi/callbacks.c:557 +#: ../coreapi/callbacks.c:527 msgid "Call resumed." msgstr "" -#: ../coreapi/callbacks.c:561 -#, c-format -msgid "Call answered by %s." -msgstr "" - -#: ../coreapi/callbacks.c:584 +#: ../coreapi/callbacks.c:582 msgid "Incompatible, check codecs or security settings..." msgstr "" -#: ../coreapi/callbacks.c:589 ../coreapi/callbacks.c:906 +#: ../coreapi/callbacks.c:587 ../coreapi/callbacks.c:923 msgid "Incompatible media parameters." msgstr "" -#: ../coreapi/callbacks.c:619 +#: ../coreapi/callbacks.c:612 msgid "We have been resumed." msgstr "" #. we are being paused -#: ../coreapi/callbacks.c:628 +#: ../coreapi/callbacks.c:620 msgid "We are paused by other party." msgstr "" -#. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:666 +#: ../coreapi/callbacks.c:630 msgid "Call is updated by remote." msgstr "" -#: ../coreapi/callbacks.c:782 +#: ../coreapi/callbacks.c:799 msgid "Call terminated." msgstr "" -#: ../coreapi/callbacks.c:810 +#: ../coreapi/callbacks.c:827 msgid "User is busy." msgstr "Osoba jest zajęta." -#: ../coreapi/callbacks.c:811 +#: ../coreapi/callbacks.c:828 msgid "User is temporarily unavailable." msgstr "Osoba jest tymczasowo niedostępna." #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:813 +#: ../coreapi/callbacks.c:830 msgid "User does not want to be disturbed." msgstr "Osoba nie chce, aby jej przeszkadzać." -#: ../coreapi/callbacks.c:814 +#: ../coreapi/callbacks.c:831 msgid "Call declined." msgstr "Rozmowa odrzucona." -#: ../coreapi/callbacks.c:829 +#: ../coreapi/callbacks.c:846 msgid "Request timeout." msgstr "" -#: ../coreapi/callbacks.c:860 +#: ../coreapi/callbacks.c:877 msgid "Redirected" msgstr "" -#: ../coreapi/callbacks.c:915 +#: ../coreapi/callbacks.c:927 msgid "Call failed." msgstr "" -#: ../coreapi/callbacks.c:993 +#: ../coreapi/callbacks.c:1005 #, c-format msgid "Registration on %s successful." msgstr "" -#: ../coreapi/callbacks.c:994 +#: ../coreapi/callbacks.c:1006 #, c-format msgid "Unregistration on %s done." msgstr "" -#: ../coreapi/callbacks.c:1012 +#: ../coreapi/callbacks.c:1024 msgid "no response timeout" msgstr "" -#: ../coreapi/callbacks.c:1015 +#: ../coreapi/callbacks.c:1027 #, c-format msgid "Registration on %s failed: %s" msgstr "" -#: ../coreapi/callbacks.c:1022 +#: ../coreapi/callbacks.c:1034 msgid "Service unavailable, retrying" msgstr "" #. if encryption is DTLS, no status to be displayed -#: ../coreapi/linphonecall.c:180 +#: ../coreapi/linphonecall.c:197 #, c-format msgid "Authentication token is %s" msgstr "" -#: ../coreapi/linphonecall.c:1310 +#: ../coreapi/linphonecall.c:1561 +#, c-format +msgid "Call parameters could not be modified: %s." +msgstr "" + +#: ../coreapi/linphonecall.c:1563 msgid "Call parameters were successfully modified." msgstr "" -#: ../coreapi/linphonecall.c:3686 +#: ../coreapi/linphonecall.c:4396 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." @@ -1962,23 +2033,23 @@ msgstr[0] "" msgstr[1] "" msgstr[2] "" -#: ../coreapi/call_log.c:209 +#: ../coreapi/call_log.c:223 msgid "aborted" msgstr "" -#: ../coreapi/call_log.c:212 +#: ../coreapi/call_log.c:226 msgid "completed" msgstr "" -#: ../coreapi/call_log.c:215 +#: ../coreapi/call_log.c:229 msgid "missed" msgstr "" -#: ../coreapi/call_log.c:218 +#: ../coreapi/call_log.c:232 msgid "unknown" msgstr "" -#: ../coreapi/call_log.c:220 +#: ../coreapi/call_log.c:234 #, c-format msgid "" "%s at %s\n" @@ -1988,7 +2059,7 @@ msgid "" "Duration: %i mn %i sec\n" msgstr "" -#: ../coreapi/call_log.c:221 +#: ../coreapi/call_log.c:235 msgid "Outgoing call" msgstr "" diff --git a/po/pt_BR.po b/po/pt_BR.po index 00d0b57e3..0aec9db79 100644 --- a/po/pt_BR.po +++ b/po/pt_BR.po @@ -7,74 +7,83 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-04-30 10:13+0200\n" -"PO-Revision-Date: 2015-04-30 08:13+0000\n" +"POT-Creation-Date: 2015-11-10 15:16+0100\n" +"PO-Revision-Date: 2015-11-10 14:16+0000\n" "Last-Translator: Belledonne Communications \n" -"Language-Team: Portuguese (Brazil) (http://www.transifex.com/projects/p/linphone-gtk/language/pt_BR/)\n" +"Language-Team: Portuguese (Brazil) (http://www.transifex.com/belledonne-communications/linphone-gtk/language/pt_BR/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: pt_BR\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: ../gtk/calllogs.c:148 ../gtk/friendlist.c:974 +#: ../gtk/calllogs.c:178 #, c-format msgid "Call %s" msgstr "" -#: ../gtk/calllogs.c:149 ../gtk/friendlist.c:975 +#: ../gtk/calllogs.c:179 #, c-format msgid "Send text to %s" msgstr "" -#: ../gtk/calllogs.c:232 +#: ../gtk/calllogs.c:181 +#, c-format +msgid "Add %s to your contact list" +msgstr "" + +#: ../gtk/calllogs.c:245 ../gtk/main.ui.h:21 +msgid "Recent calls" +msgstr "" + +#: ../gtk/calllogs.c:260 #, c-format msgid "Recent calls (%i)" msgstr "" -#: ../gtk/calllogs.c:314 +#: ../gtk/calllogs.c:331 msgid "n/a" msgstr "" -#: ../gtk/calllogs.c:317 +#: ../gtk/calllogs.c:334 msgid "Aborted" msgstr "" -#: ../gtk/calllogs.c:320 +#: ../gtk/calllogs.c:337 msgid "Missed" msgstr "" -#: ../gtk/calllogs.c:323 +#: ../gtk/calllogs.c:340 msgid "Declined" msgstr "" -#: ../gtk/calllogs.c:329 +#: ../gtk/calllogs.c:346 #, c-format msgid "%i minute" msgid_plural "%i minutes" msgstr[0] "" msgstr[1] "" -#: ../gtk/calllogs.c:332 +#: ../gtk/calllogs.c:349 #, c-format msgid "%i second" msgid_plural "%i seconds" msgstr[0] "" msgstr[1] "" -#: ../gtk/calllogs.c:337 +#: ../gtk/calllogs.c:354 #, c-format msgid "" "%s\tQuality: %s\n" "%s\t%s\t" msgstr "" -#: ../gtk/calllogs.c:341 +#: ../gtk/calllogs.c:358 #, c-format msgid "%s\t%s" msgstr "" -#: ../gtk/conference.c:38 ../gtk/main.ui.h:13 +#: ../gtk/conference.c:38 ../gtk/in_call_frame.ui.h:11 msgid "Conference" msgstr "" @@ -87,297 +96,314 @@ msgstr "" msgid "Couldn't find pixmap file: %s" msgstr "Não é possível achar arquivo pixmap: %s" -#: ../gtk/main.c:137 -msgid "log to stdout some debug information while running." +#: ../gtk/chat.c:196 ../gtk/chat.c:254 +msgid "Sending..." +msgstr "" + +#: ../gtk/chat.c:213 ../gtk/chat.c:263 +msgid "Message not sent" +msgstr "" + +#: ../gtk/chat.c:472 +msgid "Copy" msgstr "" #: ../gtk/main.c:138 -msgid "path to a file to write logs into." +msgid "log to stdout some debug information while running." msgstr "" #: ../gtk/main.c:139 -msgid "Start linphone with video disabled." +msgid "display version and exit." msgstr "" #: ../gtk/main.c:140 -msgid "Start only in the system tray, do not show the main interface." +msgid "path to a file to write logs into." msgstr "" #: ../gtk/main.c:141 -msgid "address to call right now" +msgid "Start linphone with video disabled." msgstr "" #: ../gtk/main.c:142 +msgid "Start only in the system tray, do not show the main interface." +msgstr "" + +#: ../gtk/main.c:143 +msgid "address to call right now" +msgstr "" + +#: ../gtk/main.c:144 msgid "" "Specifiy a working directory (should be the base of the installation, eg: " "c:\\Program Files\\Linphone)" msgstr "" -#: ../gtk/main.c:143 +#: ../gtk/main.c:145 msgid "Configuration file" msgstr "" -#: ../gtk/main.c:144 +#: ../gtk/main.c:146 msgid "Run the audio assistant" msgstr "" -#: ../gtk/main.c:145 +#: ../gtk/main.c:147 msgid "Run self test and exit 0 if succeed" msgstr "" -#: ../gtk/main.c:1070 +#: ../gtk/main.c:1046 #, c-format msgid "" -"%s would like to add you to his contact list.\n" -"Would you allow him to see your presence status or add him to your contact list ?\n" +"%s would like to add you to his/her contact list.\n" +"Would you add him/her to your contact list and allow him/her to see your presence status?\n" "If you answer no, this person will be temporarily blacklisted." msgstr "" -#: ../gtk/main.c:1147 +#: ../gtk/main.c:1123 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" msgstr "" -#: ../gtk/main.c:1268 +#: ../gtk/main.c:1253 msgid "Call error" msgstr "" -#: ../gtk/main.c:1271 ../coreapi/linphonecore.c:3846 +#: ../gtk/main.c:1256 ../coreapi/linphonecore.c:3813 msgid "Call ended" msgstr "" -#: ../gtk/main.c:1274 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1259 ../coreapi/call_log.c:235 msgid "Incoming call" msgstr "Camadas recebidas" -#: ../gtk/main.c:1276 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1261 ../gtk/incall_view.c:580 ../gtk/in_call_frame.ui.h:2 msgid "Answer" msgstr "" -#: ../gtk/main.c:1278 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1263 ../gtk/in_call_frame.ui.h:3 msgid "Decline" msgstr "" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 msgid "Call paused" msgstr "" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 #, c-format msgid "by %s" msgstr "" -#: ../gtk/main.c:1354 +#: ../gtk/main.c:1339 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "" -#: ../gtk/main.c:1509 +#: ../gtk/main.c:1505 msgid "Website link" msgstr "" -#: ../gtk/main.c:1568 ../gtk/waiting.ui.h:1 +#: ../gtk/main.c:1564 ../gtk/waiting.ui.h:1 msgid "Linphone" msgstr "" -#: ../gtk/main.c:1569 +#: ../gtk/main.c:1565 msgid "A video internet phone" msgstr "" -#: ../gtk/main.c:1629 +#: ../gtk/main.c:1624 #, c-format msgid "%s (Default)" msgstr "" -#: ../gtk/main.c:1962 ../coreapi/callbacks.c:1063 +#: ../gtk/main.c:1960 ../coreapi/callbacks.c:1075 #, c-format msgid "We are transferred to %s" msgstr "" -#: ../gtk/main.c:1972 +#: ../gtk/main.c:1970 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:2117 +#: ../gtk/main.c:2129 msgid "A free SIP video-phone" msgstr "" -#: ../gtk/main.c:2221 +#: ../gtk/main.c:2242 #, c-format msgid "Hello\n" msgstr "" -#: ../gtk/friendlist.c:505 +#: ../gtk/friendlist.c:461 msgid "Add to addressbook" msgstr "" -#: ../gtk/friendlist.c:691 -msgid "Presence status" -msgstr "Status de presença" - -#: ../gtk/friendlist.c:709 ../gtk/propertybox.c:569 ../gtk/contact.ui.h:1 -msgid "Name" -msgstr "Nome" - -#: ../gtk/friendlist.c:721 -msgid "Call" -msgstr "" - -#: ../gtk/friendlist.c:726 -msgid "Chat" -msgstr "" - -#: ../gtk/friendlist.c:756 +#: ../gtk/friendlist.c:627 #, c-format msgid "Search in %s directory" msgstr "" -#: ../gtk/friendlist.c:924 +#: ../gtk/friendlist.c:772 msgid "Invalid sip contact !" msgstr "" -#: ../gtk/friendlist.c:976 +#: ../gtk/friendlist.c:820 +#, c-format +msgid "Add a new contact" +msgstr "" + +#: ../gtk/friendlist.c:823 #, c-format msgid "Edit contact '%s'" msgstr "" -#: ../gtk/friendlist.c:977 +#: ../gtk/friendlist.c:824 #, c-format msgid "Delete contact '%s'" msgstr "" -#: ../gtk/friendlist.c:978 +#: ../gtk/friendlist.c:825 #, c-format msgid "Delete chat history of '%s'" msgstr "" -#: ../gtk/friendlist.c:1029 +#: ../gtk/friendlist.c:862 #, c-format msgid "Add new contact from %s directory" msgstr "" -#: ../gtk/propertybox.c:575 +#: ../gtk/propertybox.c:592 ../gtk/contact.ui.h:1 +msgid "Name" +msgstr "Nome" + +#: ../gtk/propertybox.c:598 msgid "Rate (Hz)" msgstr "Taxa (Hz)" -#: ../gtk/propertybox.c:581 +#: ../gtk/propertybox.c:604 msgid "Status" msgstr "" -#: ../gtk/propertybox.c:587 +#: ../gtk/propertybox.c:617 msgid "IP Bitrate (kbit/s)" msgstr "" -#: ../gtk/propertybox.c:596 +#: ../gtk/propertybox.c:628 msgid "Parameters" msgstr "Parâmetros" -#: ../gtk/propertybox.c:639 ../gtk/propertybox.c:782 +#: ../gtk/propertybox.c:670 ../gtk/propertybox.c:824 msgid "Enabled" msgstr "Ativado" -#: ../gtk/propertybox.c:641 ../gtk/propertybox.c:782 ../gtk/parameters.ui.h:20 +#: ../gtk/propertybox.c:672 ../gtk/propertybox.c:824 ../gtk/parameters.ui.h:60 msgid "Disabled" msgstr "Desativado" -#: ../gtk/propertybox.c:828 +#: ../gtk/propertybox.c:902 msgid "Account" msgstr "" -#: ../gtk/propertybox.c:1091 +#: ../gtk/propertybox.c:1170 msgid "English" msgstr "" -#: ../gtk/propertybox.c:1092 +#: ../gtk/propertybox.c:1171 msgid "French" msgstr "" -#: ../gtk/propertybox.c:1093 +#: ../gtk/propertybox.c:1172 msgid "Swedish" msgstr "" -#: ../gtk/propertybox.c:1094 +#: ../gtk/propertybox.c:1173 msgid "Italian" msgstr "" -#: ../gtk/propertybox.c:1095 +#: ../gtk/propertybox.c:1174 msgid "Spanish" msgstr "" -#: ../gtk/propertybox.c:1096 +#: ../gtk/propertybox.c:1175 msgid "Brazilian Portugese" msgstr "" -#: ../gtk/propertybox.c:1097 +#: ../gtk/propertybox.c:1176 msgid "Polish" msgstr "" -#: ../gtk/propertybox.c:1098 +#: ../gtk/propertybox.c:1177 msgid "German" msgstr "" -#: ../gtk/propertybox.c:1099 +#: ../gtk/propertybox.c:1178 msgid "Russian" msgstr "" -#: ../gtk/propertybox.c:1100 +#: ../gtk/propertybox.c:1179 msgid "Japanese" msgstr "" -#: ../gtk/propertybox.c:1101 +#: ../gtk/propertybox.c:1180 msgid "Dutch" msgstr "" -#: ../gtk/propertybox.c:1102 +#: ../gtk/propertybox.c:1181 msgid "Hungarian" msgstr "" -#: ../gtk/propertybox.c:1103 +#: ../gtk/propertybox.c:1182 msgid "Czech" msgstr "" -#: ../gtk/propertybox.c:1104 +#: ../gtk/propertybox.c:1183 msgid "Chinese" msgstr "" -#: ../gtk/propertybox.c:1105 +#: ../gtk/propertybox.c:1184 msgid "Traditional Chinese" msgstr "" -#: ../gtk/propertybox.c:1106 +#: ../gtk/propertybox.c:1185 msgid "Norwegian" msgstr "" -#: ../gtk/propertybox.c:1107 +#: ../gtk/propertybox.c:1186 msgid "Hebrew" msgstr "" -#: ../gtk/propertybox.c:1108 +#: ../gtk/propertybox.c:1187 msgid "Serbian" msgstr "" -#: ../gtk/propertybox.c:1175 +#: ../gtk/propertybox.c:1188 +msgid "Arabic" +msgstr "" + +#: ../gtk/propertybox.c:1189 +msgid "Turkish" +msgstr "" + +#: ../gtk/propertybox.c:1246 msgid "" "You need to restart linphone for the new language selection to take effect." msgstr "" -#: ../gtk/propertybox.c:1255 +#: ../gtk/propertybox.c:1326 msgid "None" msgstr "Nenhum" -#: ../gtk/propertybox.c:1259 +#: ../gtk/propertybox.c:1330 msgid "SRTP" msgstr "" -#: ../gtk/propertybox.c:1265 +#: ../gtk/propertybox.c:1336 msgid "DTLS" msgstr "" -#: ../gtk/propertybox.c:1272 +#: ../gtk/propertybox.c:1343 msgid "ZRTP" msgstr "" @@ -419,324 +445,195 @@ msgid_plural "Found %i contacts" msgstr[0] "" msgstr[1] "" -#: ../gtk/setupwizard.c:32 -msgid "" -"Welcome!\n" -"This assistant will help you to use a SIP account for your calls." -msgstr "" - -#: ../gtk/setupwizard.c:41 -msgid "Create an account on linphone.org" -msgstr "" - -#: ../gtk/setupwizard.c:42 -msgid "I have already a linphone.org account and I just want to use it" -msgstr "" - -#: ../gtk/setupwizard.c:43 -msgid "I have already a sip account and I just want to use it" -msgstr "" - -#: ../gtk/setupwizard.c:44 -msgid "I want to specify a remote configuration URI" -msgstr "" - -#: ../gtk/setupwizard.c:87 -msgid "Enter your linphone.org username" -msgstr "" - -#: ../gtk/setupwizard.c:100 ../gtk/parameters.ui.h:85 ../gtk/ldap.ui.h:4 -msgid "Username:" -msgstr "" - -#: ../gtk/setupwizard.c:102 ../gtk/password.ui.h:4 ../gtk/ldap.ui.h:5 -msgid "Password:" -msgstr "" - -#: ../gtk/setupwizard.c:122 -msgid "Enter your account informations" -msgstr "" - -#: ../gtk/setupwizard.c:138 -msgid "Username*" -msgstr "" - -#: ../gtk/setupwizard.c:139 -msgid "Password*" -msgstr "" - -#: ../gtk/setupwizard.c:142 -msgid "Domain*" -msgstr "" - -#: ../gtk/setupwizard.c:143 -msgid "Proxy" -msgstr "" - -#: ../gtk/setupwizard.c:322 -msgid "(*) Required fields" -msgstr "" - -#: ../gtk/setupwizard.c:323 -msgid "Username: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:325 -msgid "Password: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:327 -msgid "Email: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:329 -msgid "Confirm your password: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:343 -msgid "Keep me informed with linphone updates" -msgstr "" - -#: ../gtk/setupwizard.c:399 -msgid "" -"Error, account not validated, username already used or server unreachable.\n" -"Please go back and try again." -msgstr "" - -#: ../gtk/setupwizard.c:410 -msgid "Thank you. Your account is now configured and ready for use." -msgstr "" - -#: ../gtk/setupwizard.c:418 -msgid "" -"Please validate your account by clicking on the link we just sent you by email.\n" -"Then come back here and press Next button." -msgstr "" - -#: ../gtk/setupwizard.c:609 -msgid "SIP account configuration assistant" -msgstr "" - -#: ../gtk/setupwizard.c:629 -msgid "Welcome to the account setup assistant" -msgstr "" - -#: ../gtk/setupwizard.c:634 -msgid "Account setup assistant" -msgstr "" - -#: ../gtk/setupwizard.c:640 -msgid "Configure your account (step 1/1)" -msgstr "" - -#: ../gtk/setupwizard.c:645 -msgid "Enter your sip username (step 1/1)" -msgstr "" - -#: ../gtk/setupwizard.c:649 -msgid "Enter account information (step 1/2)" -msgstr "" - -#: ../gtk/setupwizard.c:658 -msgid "Validation (step 2/2)" -msgstr "" - -#: ../gtk/setupwizard.c:663 -msgid "Error" -msgstr "" - -#: ../gtk/setupwizard.c:667 ../gtk/audio_assistant.c:534 -msgid "Terminating" -msgstr "" - -#: ../gtk/incall_view.c:70 ../gtk/incall_view.c:94 +#: ../gtk/incall_view.c:67 ../gtk/incall_view.c:87 #, c-format msgid "Call #%i" msgstr "" -#: ../gtk/incall_view.c:155 +#: ../gtk/incall_view.c:145 #, c-format msgid "Transfer to call #%i with %s" msgstr "" -#: ../gtk/incall_view.c:211 ../gtk/incall_view.c:214 +#: ../gtk/incall_view.c:202 ../gtk/incall_view.c:205 msgid "Not used" msgstr "" -#: ../gtk/incall_view.c:221 +#: ../gtk/incall_view.c:212 msgid "ICE not activated" msgstr "" -#: ../gtk/incall_view.c:223 +#: ../gtk/incall_view.c:214 msgid "ICE failed" msgstr "" -#: ../gtk/incall_view.c:225 +#: ../gtk/incall_view.c:216 msgid "ICE in progress" msgstr "" -#: ../gtk/incall_view.c:227 +#: ../gtk/incall_view.c:218 msgid "Going through one or more NATs" msgstr "" -#: ../gtk/incall_view.c:229 +#: ../gtk/incall_view.c:220 msgid "Direct" msgstr "" -#: ../gtk/incall_view.c:231 +#: ../gtk/incall_view.c:222 msgid "Through a relay server" msgstr "" -#: ../gtk/incall_view.c:239 +#: ../gtk/incall_view.c:230 msgid "uPnP not activated" msgstr "" -#: ../gtk/incall_view.c:241 +#: ../gtk/incall_view.c:232 msgid "uPnP in progress" msgstr "" -#: ../gtk/incall_view.c:243 +#: ../gtk/incall_view.c:234 msgid "uPnp not available" msgstr "" -#: ../gtk/incall_view.c:245 +#: ../gtk/incall_view.c:236 msgid "uPnP is running" msgstr "" -#: ../gtk/incall_view.c:247 +#: ../gtk/incall_view.c:238 msgid "uPnP failed" msgstr "" -#: ../gtk/incall_view.c:257 ../gtk/incall_view.c:258 +#: ../gtk/incall_view.c:248 ../gtk/incall_view.c:249 msgid "Direct or through server" msgstr "" -#: ../gtk/incall_view.c:267 ../gtk/incall_view.c:279 +#: ../gtk/incall_view.c:258 ../gtk/incall_view.c:270 #, c-format msgid "" "download: %f\n" "upload: %f (kbit/s)" msgstr "" -#: ../gtk/incall_view.c:272 ../gtk/incall_view.c:274 +#: ../gtk/incall_view.c:263 ../gtk/incall_view.c:265 #, c-format msgid "%ix%i @ %f fps" msgstr "" -#: ../gtk/incall_view.c:304 +#: ../gtk/incall_view.c:295 #, c-format msgid "%.3f seconds" msgstr "" -#: ../gtk/incall_view.c:407 ../gtk/main.ui.h:12 ../gtk/videowindow.c:235 +#: ../gtk/incall_view.c:453 ../gtk/in_call_frame.ui.h:10 +#: ../gtk/videowindow.c:236 msgid "Hang up" msgstr "" -#: ../gtk/incall_view.c:511 +#: ../gtk/incall_view.c:559 msgid "Calling..." msgstr "" -#: ../gtk/incall_view.c:514 ../gtk/incall_view.c:733 -msgid "00::00::00" +#: ../gtk/incall_view.c:562 ../gtk/incall_view.c:792 +msgid "00:00:00" msgstr "" -#: ../gtk/incall_view.c:525 +#: ../gtk/incall_view.c:573 msgid "Incoming call" msgstr "" -#: ../gtk/incall_view.c:562 +#: ../gtk/incall_view.c:610 msgid "good" msgstr "" -#: ../gtk/incall_view.c:564 +#: ../gtk/incall_view.c:612 msgid "average" msgstr "" -#: ../gtk/incall_view.c:566 +#: ../gtk/incall_view.c:614 msgid "poor" msgstr "" -#: ../gtk/incall_view.c:568 +#: ../gtk/incall_view.c:616 msgid "very poor" msgstr "" -#: ../gtk/incall_view.c:570 +#: ../gtk/incall_view.c:618 msgid "too bad" msgstr "" -#: ../gtk/incall_view.c:571 ../gtk/incall_view.c:587 +#: ../gtk/incall_view.c:619 ../gtk/incall_view.c:635 msgid "unavailable" msgstr "" -#: ../gtk/incall_view.c:679 +#: ../gtk/incall_view.c:731 msgid "Secured by SRTP" msgstr "" -#: ../gtk/incall_view.c:685 +#: ../gtk/incall_view.c:737 msgid "Secured by DTLS" msgstr "" -#: ../gtk/incall_view.c:691 +#: ../gtk/incall_view.c:743 #, c-format msgid "Secured by ZRTP - [auth token: %s]" msgstr "" -#: ../gtk/incall_view.c:697 +#: ../gtk/incall_view.c:747 msgid "Set unverified" msgstr "" -#: ../gtk/incall_view.c:697 ../gtk/main.ui.h:4 +#: ../gtk/incall_view.c:747 msgid "Set verified" msgstr "" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In conference" msgstr "" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In call" msgstr "" -#: ../gtk/incall_view.c:764 +#: ../gtk/incall_view.c:824 msgid "Paused call" msgstr "" -#: ../gtk/incall_view.c:800 +#: ../gtk/incall_view.c:861 msgid "Call ended." msgstr "" -#: ../gtk/incall_view.c:831 +#: ../gtk/incall_view.c:892 msgid "Transfer in progress" msgstr "" -#: ../gtk/incall_view.c:834 +#: ../gtk/incall_view.c:895 msgid "Transfer done." msgstr "" -#: ../gtk/incall_view.c:837 +#: ../gtk/incall_view.c:898 msgid "Transfer failed." msgstr "" -#: ../gtk/incall_view.c:881 +#: ../gtk/incall_view.c:929 msgid "Resume" msgstr "" -#: ../gtk/incall_view.c:888 ../gtk/main.ui.h:9 +#: ../gtk/incall_view.c:929 ../gtk/in_call_frame.ui.h:7 msgid "Pause" msgstr "" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 #, c-format msgid "" "Recording into\n" "%s %s" msgstr "" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 msgid "(Paused)" msgstr "" -#: ../gtk/loginframe.c:87 +#: ../gtk/loginframe.c:75 #, c-format msgid "Please enter login information for %s" msgstr "" @@ -751,262 +648,107 @@ msgstr "" msgid "Downloading of remote configuration from %s failed." msgstr "" -#: ../gtk/audio_assistant.c:98 +#: ../gtk/audio_assistant.c:103 msgid "No voice detected" msgstr "" -#: ../gtk/audio_assistant.c:99 +#: ../gtk/audio_assistant.c:104 msgid "Too low" msgstr "" -#: ../gtk/audio_assistant.c:100 +#: ../gtk/audio_assistant.c:105 msgid "Good" msgstr "" -#: ../gtk/audio_assistant.c:101 +#: ../gtk/audio_assistant.c:106 msgid "Too loud" msgstr "" -#: ../gtk/audio_assistant.c:183 +#: ../gtk/audio_assistant.c:188 msgid "Did you hear three beeps ?" msgstr "" -#: ../gtk/audio_assistant.c:292 ../gtk/audio_assistant.c:297 +#: ../gtk/audio_assistant.c:299 ../gtk/audio_assistant.c:304 msgid "Sound preferences not found " msgstr "" -#: ../gtk/audio_assistant.c:306 +#: ../gtk/audio_assistant.c:313 msgid "Cannot launch system sound control " msgstr "" -#: ../gtk/audio_assistant.c:318 +#: ../gtk/audio_assistant.c:325 msgid "" "Welcome!\n" "This assistant will help you to configure audio settings for Linphone" msgstr "" -#: ../gtk/audio_assistant.c:328 +#: ../gtk/audio_assistant.c:335 msgid "Capture device" msgstr "" -#: ../gtk/audio_assistant.c:329 +#: ../gtk/audio_assistant.c:336 msgid "Recorded volume" msgstr "" -#: ../gtk/audio_assistant.c:333 +#: ../gtk/audio_assistant.c:340 msgid "No voice" msgstr "" -#: ../gtk/audio_assistant.c:334 ../gtk/audio_assistant.c:373 +#: ../gtk/audio_assistant.c:341 ../gtk/audio_assistant.c:380 msgid "System sound preferences" msgstr "" -#: ../gtk/audio_assistant.c:369 +#: ../gtk/audio_assistant.c:376 msgid "Playback device" msgstr "" -#: ../gtk/audio_assistant.c:370 +#: ../gtk/audio_assistant.c:377 msgid "Play three beeps" msgstr "" -#: ../gtk/audio_assistant.c:403 +#: ../gtk/audio_assistant.c:410 msgid "Press the record button and say some words" msgstr "" -#: ../gtk/audio_assistant.c:404 +#: ../gtk/audio_assistant.c:411 msgid "Listen to your record voice" msgstr "" -#: ../gtk/audio_assistant.c:405 +#: ../gtk/audio_assistant.c:412 ../gtk/conf_frame.ui.h:2 +#: ../gtk/in_call_frame.ui.h:4 msgid "Record" msgstr "" -#: ../gtk/audio_assistant.c:406 +#: ../gtk/audio_assistant.c:413 msgid "Play" msgstr "" -#: ../gtk/audio_assistant.c:433 +#: ../gtk/audio_assistant.c:440 msgid "Let's start Linphone now" msgstr "" -#: ../gtk/audio_assistant.c:503 +#: ../gtk/audio_assistant.c:510 msgid "Audio Assistant" msgstr "" -#: ../gtk/audio_assistant.c:513 ../gtk/main.ui.h:32 +#: ../gtk/audio_assistant.c:520 ../gtk/main.ui.h:13 msgid "Audio assistant" msgstr "" -#: ../gtk/audio_assistant.c:518 +#: ../gtk/audio_assistant.c:525 msgid "Mic Gain calibration" msgstr "" -#: ../gtk/audio_assistant.c:524 +#: ../gtk/audio_assistant.c:531 msgid "Speaker volume calibration" msgstr "" -#: ../gtk/audio_assistant.c:529 +#: ../gtk/audio_assistant.c:536 msgid "Record and Play" msgstr "" -#: ../gtk/main.ui.h:1 -msgid "Callee name" -msgstr "" - -#: ../gtk/main.ui.h:2 -msgid "Send" -msgstr "" - -#: ../gtk/main.ui.h:3 -msgid "End conference" -msgstr "" - -#: ../gtk/main.ui.h:7 -msgid "Record this call to an audio file" -msgstr "" - -#: ../gtk/main.ui.h:8 -msgid "Video" -msgstr "" - -#: ../gtk/main.ui.h:10 -msgid "Mute" -msgstr "" - -#: ../gtk/main.ui.h:11 -msgid "Transfer" -msgstr "" - -#: ../gtk/main.ui.h:14 -msgid "In call" -msgstr "" - -#: ../gtk/main.ui.h:15 -msgid "Duration" -msgstr "" - -#: ../gtk/main.ui.h:16 -msgid "Call quality rating" -msgstr "" - -#: ../gtk/main.ui.h:17 -msgid "All users" -msgstr "" - -#: ../gtk/main.ui.h:18 -msgid "Online users" -msgstr "" - -#: ../gtk/main.ui.h:19 -msgid "ADSL" -msgstr "" - -#: ../gtk/main.ui.h:20 -msgid "Fiber Channel" -msgstr "" - -#: ../gtk/main.ui.h:21 -msgid "Default" -msgstr "" - -#: ../gtk/main.ui.h:22 -msgid "Delete" -msgstr "" - -#: ../gtk/main.ui.h:23 -msgid "_Options" -msgstr "" - -#: ../gtk/main.ui.h:24 -msgid "Set configuration URI" -msgstr "" - -#: ../gtk/main.ui.h:25 -msgid "Always start video" -msgstr "" - -#: ../gtk/main.ui.h:26 -msgid "Enable self-view" -msgstr "" - -#: ../gtk/main.ui.h:27 -msgid "_Help" -msgstr "" - -#: ../gtk/main.ui.h:28 -msgid "Show debug window" -msgstr "" - -#: ../gtk/main.ui.h:29 -msgid "_Homepage" -msgstr "" - -#: ../gtk/main.ui.h:30 -msgid "Check _Updates" -msgstr "" - -#: ../gtk/main.ui.h:31 -msgid "Account assistant" -msgstr "" - -#: ../gtk/main.ui.h:33 -msgid "SIP address or phone number:" -msgstr "" - -#: ../gtk/main.ui.h:34 -msgid "Initiate a new call" -msgstr "" - -#: ../gtk/main.ui.h:35 -msgid "Contacts" -msgstr "" - -#: ../gtk/main.ui.h:36 -msgid "Search" -msgstr "" - -#: ../gtk/main.ui.h:37 -msgid "Add contacts from directory" -msgstr "" - -#: ../gtk/main.ui.h:38 -msgid "Add contact" -msgstr "" - -#: ../gtk/main.ui.h:39 -msgid "Recent calls" -msgstr "" - -#: ../gtk/main.ui.h:40 -msgid "My current identity:" -msgstr "" - -#: ../gtk/main.ui.h:41 ../gtk/tunnel_config.ui.h:7 -msgid "Username" -msgstr "" - -#: ../gtk/main.ui.h:42 ../gtk/tunnel_config.ui.h:8 -msgid "Password" -msgstr "" - -#: ../gtk/main.ui.h:43 -msgid "Internet connection:" -msgstr "" - -#: ../gtk/main.ui.h:44 -msgid "Automatically log me in" -msgstr "" - -#: ../gtk/main.ui.h:45 ../gtk/password.ui.h:3 -msgid "UserID" -msgstr "" - -#: ../gtk/main.ui.h:46 -msgid "Login information" -msgstr "" - -#: ../gtk/main.ui.h:47 -msgid "Welcome!" +#: ../gtk/audio_assistant.c:541 ../gtk/setup_wizard.ui.h:38 +msgid "Terminating" msgstr "" #: ../gtk/about.ui.h:1 @@ -1037,456 +779,6 @@ msgid "" "he: Eli Zaretskii \n" msgstr "" -#: ../gtk/contact.ui.h:2 -msgid "SIP Address" -msgstr "" - -#: ../gtk/contact.ui.h:3 -msgid "Show this contact presence status" -msgstr "" - -#: ../gtk/contact.ui.h:4 -msgid "Allow this contact to see my presence status" -msgstr "" - -#: ../gtk/contact.ui.h:5 -msgid "Contact information" -msgstr "" - -#: ../gtk/log.ui.h:1 -msgid "Linphone debug window" -msgstr "" - -#: ../gtk/log.ui.h:2 -msgid "Scroll to end" -msgstr "" - -#: ../gtk/password.ui.h:1 -msgid "Linphone - Authentication required" -msgstr "" - -#: ../gtk/password.ui.h:2 -msgid "Please enter the domain password" -msgstr "" - -#: ../gtk/call_logs.ui.h:1 -msgid "Call history" -msgstr "" - -#: ../gtk/call_logs.ui.h:2 -msgid "Clear all" -msgstr "" - -#: ../gtk/call_logs.ui.h:3 -msgid "Call back" -msgstr "" - -#: ../gtk/sip_account.ui.h:1 -msgid "Linphone - Configure a SIP account" -msgstr "" - -#: ../gtk/sip_account.ui.h:2 -msgid "Your SIP identity:" -msgstr "" - -#: ../gtk/sip_account.ui.h:3 -msgid "Looks like sip:@" -msgstr "" - -#: ../gtk/sip_account.ui.h:4 -msgid "sip:" -msgstr "" - -#: ../gtk/sip_account.ui.h:5 -msgid "SIP Proxy address:" -msgstr "" - -#: ../gtk/sip_account.ui.h:6 -msgid "Looks like sip:" -msgstr "" - -#: ../gtk/sip_account.ui.h:7 -msgid "Registration duration (sec):" -msgstr "" - -#: ../gtk/sip_account.ui.h:8 -msgid "Contact params (optional):" -msgstr "" - -#: ../gtk/sip_account.ui.h:9 -msgid "AVPF regular RTCP interval (sec):" -msgstr "" - -#: ../gtk/sip_account.ui.h:10 -msgid "Route (optional):" -msgstr "Rota (opcional):" - -#: ../gtk/sip_account.ui.h:11 -msgid "Transport" -msgstr "" - -#: ../gtk/sip_account.ui.h:12 -msgid "Register" -msgstr "" - -#: ../gtk/sip_account.ui.h:13 -msgid "Publish presence information" -msgstr "" - -#: ../gtk/sip_account.ui.h:14 -msgid "Enable AVPF" -msgstr "" - -#: ../gtk/sip_account.ui.h:15 -msgid "Configure a SIP account" -msgstr "" - -#: ../gtk/parameters.ui.h:1 -msgid "anonymous" -msgstr "" - -#: ../gtk/parameters.ui.h:2 -msgid "GSSAPI" -msgstr "" - -#: ../gtk/parameters.ui.h:3 -msgid "SASL" -msgstr "" - -#: ../gtk/parameters.ui.h:4 -msgid "default soundcard" -msgstr "" - -#: ../gtk/parameters.ui.h:5 -msgid "a sound card" -msgstr "" - -#: ../gtk/parameters.ui.h:6 -msgid "default camera" -msgstr "" - -#: ../gtk/parameters.ui.h:7 -msgid "CIF" -msgstr "" - -#: ../gtk/parameters.ui.h:8 -msgid "Audio codecs" -msgstr "" - -#: ../gtk/parameters.ui.h:9 -msgid "Video codecs" -msgstr "" - -#: ../gtk/parameters.ui.h:10 -msgid "C" -msgstr "" - -#: ../gtk/parameters.ui.h:11 -msgid "SIP (UDP)" -msgstr "" - -#: ../gtk/parameters.ui.h:12 -msgid "SIP (TCP)" -msgstr "" - -#: ../gtk/parameters.ui.h:13 -msgid "SIP (TLS)" -msgstr "" - -#: ../gtk/parameters.ui.h:14 -msgid "Settings" -msgstr "" - -#: ../gtk/parameters.ui.h:15 -msgid "Set Maximum Transmission Unit:" -msgstr "" - -#: ../gtk/parameters.ui.h:16 -msgid "Send DTMFs as SIP info" -msgstr "" - -#: ../gtk/parameters.ui.h:17 -msgid "Allow IPv6" -msgstr "" - -#: ../gtk/parameters.ui.h:18 -msgid "Transport" -msgstr "" - -#: ../gtk/parameters.ui.h:19 -msgid "SIP/UDP port" -msgstr "" - -#: ../gtk/parameters.ui.h:21 -msgid "Random" -msgstr "" - -#: ../gtk/parameters.ui.h:22 -msgid "SIP/TCP port" -msgstr "" - -#: ../gtk/parameters.ui.h:23 -msgid "Audio RTP/UDP:" -msgstr "" - -#: ../gtk/parameters.ui.h:24 -msgid "Fixed" -msgstr "" - -#: ../gtk/parameters.ui.h:25 -msgid "Video RTP/UDP:" -msgstr "" - -#: ../gtk/parameters.ui.h:26 -msgid "Media encryption type" -msgstr "" - -#: ../gtk/parameters.ui.h:27 -msgid "Media encryption is mandatory" -msgstr "" - -#: ../gtk/parameters.ui.h:28 -msgid "Tunnel" -msgstr "" - -#: ../gtk/parameters.ui.h:29 -msgid "DSCP fields" -msgstr "" - -#: ../gtk/parameters.ui.h:30 -msgid "Network protocol and ports" -msgstr "" - -#: ../gtk/parameters.ui.h:31 -msgid "Direct connection to the Internet" -msgstr "" - -#: ../gtk/parameters.ui.h:32 -msgid "Behind NAT / Firewall (specify gateway IP )" -msgstr "" - -#: ../gtk/parameters.ui.h:33 -msgid "Behind NAT / Firewall (use STUN to resolve)" -msgstr "" - -#: ../gtk/parameters.ui.h:34 -msgid "Behind NAT / Firewall (use ICE)" -msgstr "" - -#: ../gtk/parameters.ui.h:35 -msgid "Behind NAT / Firewall (use uPnP)" -msgstr "" - -#: ../gtk/parameters.ui.h:36 -msgid "Public IP address:" -msgstr "" - -#: ../gtk/parameters.ui.h:37 -msgid "Stun server:" -msgstr "" - -#: ../gtk/parameters.ui.h:38 -msgid "NAT and Firewall" -msgstr "" - -#: ../gtk/parameters.ui.h:39 -msgid "Network settings" -msgstr "" - -#: ../gtk/parameters.ui.h:40 -msgid "Ring sound:" -msgstr "" - -#: ../gtk/parameters.ui.h:41 -msgid "ALSA special device (optional):" -msgstr "" - -#: ../gtk/parameters.ui.h:42 -msgid "Capture device:" -msgstr "" - -#: ../gtk/parameters.ui.h:43 -msgid "Ring device:" -msgstr "" - -#: ../gtk/parameters.ui.h:44 -msgid "Playback device:" -msgstr "" - -#: ../gtk/parameters.ui.h:45 -msgid "Enable echo cancellation" -msgstr "" - -#: ../gtk/parameters.ui.h:46 -msgid "Audio" -msgstr "" - -#: ../gtk/parameters.ui.h:47 -msgid "Video input device:" -msgstr "" - -#: ../gtk/parameters.ui.h:48 -msgid "Prefered video resolution:" -msgstr "" - -#: ../gtk/parameters.ui.h:49 -msgid "Video output method:" -msgstr "" - -#: ../gtk/parameters.ui.h:50 -msgid "Show camera preview" -msgstr "" - -#: ../gtk/parameters.ui.h:51 -msgid "Video" -msgstr "" - -#: ../gtk/parameters.ui.h:52 -msgid "Multimedia settings" -msgstr "" - -#: ../gtk/parameters.ui.h:53 -msgid "This section defines your SIP address when not using a SIP account" -msgstr "" - -#: ../gtk/parameters.ui.h:54 -msgid "Your display name (eg: John Doe):" -msgstr "" - -#: ../gtk/parameters.ui.h:55 -msgid "Your username:" -msgstr "" - -#: ../gtk/parameters.ui.h:56 -msgid "Your resulting SIP address:" -msgstr "" - -#: ../gtk/parameters.ui.h:57 -msgid "Default identity" -msgstr "" - -#: ../gtk/parameters.ui.h:58 -msgid "Wizard" -msgstr "" - -#: ../gtk/parameters.ui.h:59 -msgid "Add" -msgstr "" - -#: ../gtk/parameters.ui.h:60 -msgid "Edit" -msgstr "Editar" - -#: ../gtk/parameters.ui.h:61 -msgid "Remove" -msgstr "Remover" - -#: ../gtk/parameters.ui.h:62 -msgid "Proxy accounts" -msgstr "" - -#: ../gtk/parameters.ui.h:63 -msgid "Erase all passwords" -msgstr "" - -#: ../gtk/parameters.ui.h:64 -msgid "Privacy" -msgstr "" - -#: ../gtk/parameters.ui.h:65 -msgid "Automatically answer when a call is received" -msgstr "" - -#: ../gtk/parameters.ui.h:66 -msgid "Delay before answering (ms)" -msgstr "" - -#: ../gtk/parameters.ui.h:67 -msgid "Auto-answer" -msgstr "" - -#: ../gtk/parameters.ui.h:68 -msgid "Manage SIP Accounts" -msgstr "" - -#: ../gtk/parameters.ui.h:69 ../gtk/tunnel_config.ui.h:4 -msgid "Enable" -msgstr "Ativado" - -#: ../gtk/parameters.ui.h:70 ../gtk/tunnel_config.ui.h:5 -msgid "Disable" -msgstr "Desativar" - -#: ../gtk/parameters.ui.h:71 -msgid "Codecs" -msgstr "" - -#: ../gtk/parameters.ui.h:72 -msgid "0 stands for \"unlimited\"" -msgstr "" - -#: ../gtk/parameters.ui.h:73 -msgid "Upload speed limit in Kbit/sec:" -msgstr "" - -#: ../gtk/parameters.ui.h:74 -msgid "Download speed limit in Kbit/sec:" -msgstr "" - -#: ../gtk/parameters.ui.h:75 -msgid "Enable adaptive rate control" -msgstr "" - -#: ../gtk/parameters.ui.h:76 -msgid "" -"Adaptive rate control is a technique to dynamically guess the available " -"bandwidth during a call." -msgstr "" - -#: ../gtk/parameters.ui.h:77 -msgid "Bandwidth control" -msgstr "" - -#: ../gtk/parameters.ui.h:78 -msgid "Codecs" -msgstr "" - -#: ../gtk/parameters.ui.h:79 -msgid "Language" -msgstr "" - -#: ../gtk/parameters.ui.h:80 -msgid "Show advanced settings" -msgstr "" - -#: ../gtk/parameters.ui.h:81 -msgid "Level" -msgstr "" - -#: ../gtk/parameters.ui.h:82 -msgid "User interface" -msgstr "" - -#: ../gtk/parameters.ui.h:83 ../gtk/ldap.ui.h:2 -msgid "Server address:" -msgstr "" - -#: ../gtk/parameters.ui.h:84 ../gtk/ldap.ui.h:3 -msgid "Authentication method:" -msgstr "" - -#: ../gtk/parameters.ui.h:86 -msgid "LDAP Account setup" -msgstr "" - -#: ../gtk/parameters.ui.h:87 -msgid "LDAP" -msgstr "" - -#: ../gtk/parameters.ui.h:88 -msgid "Done" -msgstr "" - #: ../gtk/buddylookup.ui.h:1 msgid "Search contacts in directory" msgstr "" @@ -1499,28 +791,20 @@ msgstr "" msgid "Search somebody" msgstr "" -#: ../gtk/waiting.ui.h:2 -msgid "Please wait" +#: ../gtk/callee_frame.ui.h:1 +msgid "Callee name" msgstr "" -#: ../gtk/dscp_settings.ui.h:1 -msgid "DSCP settings" +#: ../gtk/call_logs.ui.h:1 +msgid "Call history" msgstr "" -#: ../gtk/dscp_settings.ui.h:2 -msgid "SIP" +#: ../gtk/call_logs.ui.h:2 +msgid "Clear all" msgstr "" -#: ../gtk/dscp_settings.ui.h:3 -msgid "Audio RTP stream" -msgstr "" - -#: ../gtk/dscp_settings.ui.h:4 -msgid "Video RTP stream" -msgstr "" - -#: ../gtk/dscp_settings.ui.h:5 -msgid "Set DSCP values (in hexadecimal)" +#: ../gtk/call_logs.ui.h:3 +msgid "Call back" msgstr "" #: ../gtk/call_statistics.ui.h:1 @@ -1571,30 +855,112 @@ msgstr "" msgid "Call statistics and information" msgstr "" -#: ../gtk/tunnel_config.ui.h:1 -msgid "Configure VoIP tunnel" +#: ../gtk/chatroom_frame.ui.h:1 +msgid "Send" msgstr "" -#: ../gtk/tunnel_config.ui.h:2 -msgid "Host" +#: ../gtk/conf_frame.ui.h:1 +msgid "End conference" msgstr "" -#: ../gtk/tunnel_config.ui.h:3 -msgid "Port" +#: ../gtk/config-uri.ui.h:1 +msgid "Specifying a remote configuration URI" msgstr "" -#: ../gtk/tunnel_config.ui.h:6 -msgid "Configure tunnel" +#: ../gtk/config-uri.ui.h:2 +msgid "" +"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" +"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " msgstr "" -#: ../gtk/tunnel_config.ui.h:9 -msgid "Configure http proxy (optional)" +#: ../gtk/contact.ui.h:2 +msgid "SIP Address" +msgstr "" + +#: ../gtk/contact.ui.h:3 +msgid "Show this contact presence status" +msgstr "" + +#: ../gtk/contact.ui.h:4 +msgid "Allow this contact to see my presence status" +msgstr "" + +#: ../gtk/contact.ui.h:5 +msgid "Contact information" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:1 +msgid "DSCP settings" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:2 +msgid "SIP" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:3 +msgid "Audio RTP stream" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:4 +msgid "Video RTP stream" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:5 +msgid "Set DSCP values (in hexadecimal)" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:1 +msgid "Click here to set the speakers volume" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:5 +msgid "Record this call to an audio file" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:6 +msgid "Video" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:8 +msgid "Mute" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:9 +msgid "Transfer" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:12 +msgid "In call" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:13 +msgid "Duration" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:14 +msgid "Call quality rating" msgstr "" #: ../gtk/ldap.ui.h:1 msgid "LDAP Settings" msgstr "" +#: ../gtk/ldap.ui.h:2 ../gtk/parameters.ui.h:89 +msgid "Server address:" +msgstr "" + +#: ../gtk/ldap.ui.h:3 ../gtk/parameters.ui.h:90 +msgid "Authentication method:" +msgstr "" + +#: ../gtk/ldap.ui.h:4 ../gtk/parameters.ui.h:91 ../gtk/setup_wizard.ui.h:17 +msgid "Username:" +msgstr "" + +#: ../gtk/ldap.ui.h:5 ../gtk/password.ui.h:4 ../gtk/setup_wizard.ui.h:18 +msgid "Password:" +msgstr "" + #: ../gtk/ldap.ui.h:6 msgid "Use TLS Connection" msgstr "" @@ -1680,14 +1046,502 @@ msgstr "" msgid "NTLM" msgstr "" -#: ../gtk/config-uri.ui.h:1 -msgid "Specifying a remote configuration URI" +#: ../gtk/login_frame.ui.h:1 ../gtk/tunnel_config.ui.h:7 +msgid "Username" msgstr "" -#: ../gtk/config-uri.ui.h:2 +#: ../gtk/login_frame.ui.h:2 ../gtk/tunnel_config.ui.h:8 +msgid "Password" +msgstr "" + +#: ../gtk/login_frame.ui.h:3 +msgid "Internet connection:" +msgstr "" + +#: ../gtk/login_frame.ui.h:4 +msgid "Automatically log me in" +msgstr "" + +#: ../gtk/login_frame.ui.h:5 ../gtk/password.ui.h:3 +msgid "UserID" +msgstr "" + +#: ../gtk/login_frame.ui.h:6 +msgid "Login information" +msgstr "" + +#: ../gtk/login_frame.ui.h:7 +msgid "Welcome!" +msgstr "" + +#: ../gtk/login_frame.ui.h:8 +msgid "ADSL" +msgstr "" + +#: ../gtk/login_frame.ui.h:9 +msgid "Fiber Channel" +msgstr "" + +#: ../gtk/log.ui.h:1 +msgid "Linphone debug window" +msgstr "" + +#: ../gtk/log.ui.h:2 +msgid "Scroll to end" +msgstr "" + +#: ../gtk/main.ui.h:1 +msgid "Default" +msgstr "" + +#: ../gtk/main.ui.h:2 +msgid "Delete" +msgstr "" + +#: ../gtk/main.ui.h:3 +msgid "_Options" +msgstr "" + +#: ../gtk/main.ui.h:4 +msgid "Set configuration URI" +msgstr "" + +#: ../gtk/main.ui.h:5 +msgid "Always start video" +msgstr "" + +#: ../gtk/main.ui.h:6 +msgid "Enable self-view" +msgstr "" + +#: ../gtk/main.ui.h:7 +msgid "Show keypad" +msgstr "" + +#: ../gtk/main.ui.h:8 +msgid "_Help" +msgstr "" + +#: ../gtk/main.ui.h:9 +msgid "Show debug window" +msgstr "" + +#: ../gtk/main.ui.h:10 +msgid "_Homepage" +msgstr "" + +#: ../gtk/main.ui.h:11 +msgid "Check _Updates" +msgstr "" + +#: ../gtk/main.ui.h:12 +msgid "Account assistant" +msgstr "" + +#: ../gtk/main.ui.h:14 +msgid "SIP address or phone number:" +msgstr "" + +#: ../gtk/main.ui.h:15 +msgid "Initiate a new call" +msgstr "" + +#: ../gtk/main.ui.h:16 +msgid "Contacts" +msgstr "" + +#: ../gtk/main.ui.h:17 +msgid "Search" +msgstr "" + +#: ../gtk/main.ui.h:18 +msgid "Add contacts from directory" +msgstr "" + +#: ../gtk/main.ui.h:19 +msgid "Add contact" +msgstr "" + +#: ../gtk/main.ui.h:20 +msgid "Clear call history" +msgstr "" + +#: ../gtk/main.ui.h:22 +msgid "My current identity:" +msgstr "" + +#: ../gtk/main.ui.h:23 +msgid "Autoanswer is enabled" +msgstr "" + +#: ../gtk/parameters.ui.h:1 +msgid "anonymous" +msgstr "" + +#: ../gtk/parameters.ui.h:2 +msgid "GSSAPI" +msgstr "" + +#: ../gtk/parameters.ui.h:3 +msgid "SASL" +msgstr "" + +#: ../gtk/parameters.ui.h:4 +msgid "default soundcard" +msgstr "" + +#: ../gtk/parameters.ui.h:5 +msgid "a sound card" +msgstr "" + +#: ../gtk/parameters.ui.h:6 +msgid "default camera" +msgstr "" + +#: ../gtk/parameters.ui.h:7 +msgid "CIF" +msgstr "" + +#: ../gtk/parameters.ui.h:8 +msgid "Audio codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:9 +msgid "Video codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:10 +msgid "C" +msgstr "" + +#: ../gtk/parameters.ui.h:11 +msgid "SIP (UDP)" +msgstr "" + +#: ../gtk/parameters.ui.h:12 +msgid "SIP (TCP)" +msgstr "" + +#: ../gtk/parameters.ui.h:13 +msgid "SIP (TLS)" +msgstr "" + +#: ../gtk/parameters.ui.h:14 +msgid "default" +msgstr "" + +#: ../gtk/parameters.ui.h:15 +msgid "high-fps" +msgstr "" + +#: ../gtk/parameters.ui.h:16 +msgid "custom" +msgstr "" + +#: ../gtk/parameters.ui.h:17 +msgid "Settings" +msgstr "" + +#: ../gtk/parameters.ui.h:18 +msgid "This section defines your SIP address when not using a SIP account" +msgstr "" + +#: ../gtk/parameters.ui.h:19 +msgid "Your display name (eg: John Doe):" +msgstr "" + +#: ../gtk/parameters.ui.h:20 +msgid "Your username:" +msgstr "" + +#: ../gtk/parameters.ui.h:21 +msgid "Your resulting SIP address:" +msgstr "" + +#: ../gtk/parameters.ui.h:22 +msgid "Default identity" +msgstr "" + +#: ../gtk/parameters.ui.h:23 +msgid "Wizard" +msgstr "" + +#: ../gtk/parameters.ui.h:24 +msgid "Add" +msgstr "" + +#: ../gtk/parameters.ui.h:25 +msgid "Edit" +msgstr "Editar" + +#: ../gtk/parameters.ui.h:26 +msgid "Remove" +msgstr "Remover" + +#: ../gtk/parameters.ui.h:27 +msgid "Proxy accounts" +msgstr "" + +#: ../gtk/parameters.ui.h:28 +msgid "Erase all passwords" +msgstr "" + +#: ../gtk/parameters.ui.h:29 +msgid "Privacy" +msgstr "" + +#: ../gtk/parameters.ui.h:30 +msgid "Automatically answer when a call is received" +msgstr "" + +#: ../gtk/parameters.ui.h:31 +msgid "Delay before answering (ms)" +msgstr "" + +#: ../gtk/parameters.ui.h:32 +msgid "Auto-answer" +msgstr "" + +#: ../gtk/parameters.ui.h:33 +msgid "Manage SIP Accounts" +msgstr "" + +#: ../gtk/parameters.ui.h:34 +msgid "Ring sound:" +msgstr "" + +#: ../gtk/parameters.ui.h:35 +msgid "ALSA special device (optional):" +msgstr "" + +#: ../gtk/parameters.ui.h:36 +msgid "Capture device:" +msgstr "" + +#: ../gtk/parameters.ui.h:37 +msgid "Ring device:" +msgstr "" + +#: ../gtk/parameters.ui.h:38 +msgid "Playback device:" +msgstr "" + +#: ../gtk/parameters.ui.h:39 +msgid "Enable echo cancellation" +msgstr "" + +#: ../gtk/parameters.ui.h:40 +msgid "Audio" +msgstr "" + +#: ../gtk/parameters.ui.h:41 +msgid "Video input device:" +msgstr "" + +#: ../gtk/parameters.ui.h:42 +msgid "Preferred video resolution:" +msgstr "" + +#: ../gtk/parameters.ui.h:43 +msgid "Video output method:" +msgstr "" + +#: ../gtk/parameters.ui.h:44 +msgid "Show camera preview" +msgstr "" + +#: ../gtk/parameters.ui.h:45 +msgid "Video preset:" +msgstr "" + +#: ../gtk/parameters.ui.h:46 +msgid "Preferred video framerate:" +msgstr "" + +#: ../gtk/parameters.ui.h:47 +msgid "0 stands for \"unlimited\"" +msgstr "" + +#: ../gtk/parameters.ui.h:48 +msgid "Video" +msgstr "" + +#: ../gtk/parameters.ui.h:49 +msgid "Upload speed limit in Kbit/sec:" +msgstr "" + +#: ../gtk/parameters.ui.h:50 +msgid "Download speed limit in Kbit/sec:" +msgstr "" + +#: ../gtk/parameters.ui.h:51 +msgid "Enable adaptive rate control" +msgstr "" + +#: ../gtk/parameters.ui.h:52 msgid "" -"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" -"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " +"Adaptive rate control is a technique to dynamically guess the available " +"bandwidth during a call." +msgstr "" + +#: ../gtk/parameters.ui.h:53 +msgid "Bandwidth control" +msgstr "" + +#: ../gtk/parameters.ui.h:54 +msgid "Multimedia settings" +msgstr "" + +#: ../gtk/parameters.ui.h:55 +msgid "Set Maximum Transmission Unit:" +msgstr "" + +#: ../gtk/parameters.ui.h:56 +msgid "Send DTMFs as SIP info" +msgstr "" + +#: ../gtk/parameters.ui.h:57 +msgid "Allow IPv6" +msgstr "" + +#: ../gtk/parameters.ui.h:58 +msgid "Transport" +msgstr "" + +#: ../gtk/parameters.ui.h:59 +msgid "SIP/UDP port" +msgstr "" + +#: ../gtk/parameters.ui.h:61 +msgid "Random" +msgstr "" + +#: ../gtk/parameters.ui.h:62 +msgid "SIP/TCP port" +msgstr "" + +#: ../gtk/parameters.ui.h:63 +msgid "Audio RTP/UDP:" +msgstr "" + +#: ../gtk/parameters.ui.h:64 +msgid "Fixed" +msgstr "" + +#: ../gtk/parameters.ui.h:65 +msgid "Video RTP/UDP:" +msgstr "" + +#: ../gtk/parameters.ui.h:66 +msgid "Media encryption type" +msgstr "" + +#: ../gtk/parameters.ui.h:67 +msgid "Media encryption is mandatory" +msgstr "" + +#: ../gtk/parameters.ui.h:68 +msgid "Tunnel" +msgstr "" + +#: ../gtk/parameters.ui.h:69 +msgid "DSCP fields" +msgstr "" + +#: ../gtk/parameters.ui.h:70 +msgid "Network protocol and ports" +msgstr "" + +#: ../gtk/parameters.ui.h:71 +msgid "Direct connection to the Internet" +msgstr "" + +#: ../gtk/parameters.ui.h:72 +msgid "Behind NAT / Firewall (specify gateway IP )" +msgstr "" + +#: ../gtk/parameters.ui.h:73 +msgid "Behind NAT / Firewall (use STUN to resolve)" +msgstr "" + +#: ../gtk/parameters.ui.h:74 +msgid "Behind NAT / Firewall (use ICE)" +msgstr "" + +#: ../gtk/parameters.ui.h:75 +msgid "Behind NAT / Firewall (use uPnP)" +msgstr "" + +#: ../gtk/parameters.ui.h:76 +msgid "Public IP address:" +msgstr "" + +#: ../gtk/parameters.ui.h:77 +msgid "Stun server:" +msgstr "" + +#: ../gtk/parameters.ui.h:78 +msgid "NAT and Firewall" +msgstr "" + +#: ../gtk/parameters.ui.h:79 +msgid "Network settings" +msgstr "" + +#: ../gtk/parameters.ui.h:80 ../gtk/tunnel_config.ui.h:4 +msgid "Enable" +msgstr "Ativado" + +#: ../gtk/parameters.ui.h:81 ../gtk/tunnel_config.ui.h:5 +msgid "Disable" +msgstr "Desativar" + +#: ../gtk/parameters.ui.h:82 +msgid "Audio codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:83 +msgid "Video codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:84 +msgid "Codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:85 +msgid "Language" +msgstr "" + +#: ../gtk/parameters.ui.h:86 +msgid "Show advanced settings" +msgstr "" + +#: ../gtk/parameters.ui.h:87 +msgid "Level" +msgstr "" + +#: ../gtk/parameters.ui.h:88 +msgid "User interface" +msgstr "" + +#: ../gtk/parameters.ui.h:92 +msgid "LDAP Account setup" +msgstr "" + +#: ../gtk/parameters.ui.h:93 +msgid "LDAP" +msgstr "" + +#: ../gtk/parameters.ui.h:94 +msgid "Done" +msgstr "" + +#: ../gtk/password.ui.h:1 +msgid "Linphone - Authentication required" +msgstr "" + +#: ../gtk/password.ui.h:2 +msgid "Please enter the domain password" msgstr "" #: ../gtk/provisioning-fetch.ui.h:1 @@ -1698,68 +1552,278 @@ msgstr "" msgid "Please wait while fetching configuration from server..." msgstr "" -#: ../coreapi/linphonecore.c:1539 +#: ../gtk/setup_wizard.ui.h:1 +msgid "SIP account configuration assistant" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:2 +msgid "" +"Welcome!\n" +"This assistant will help you to use a SIP account for your calls." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:4 +msgid "Welcome to the account setup assistant" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:5 +msgid "Create an account on linphone.org" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:6 +msgid "I have already a linphone.org account and I just want to use it" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:7 +msgid "I have already a sip account and I just want to use it" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:8 +msgid "I want to specify a remote configuration URI" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:9 +msgid "Account setup assistant" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:10 +msgid "Enter your account information" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:11 +msgid "Username*" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:12 +msgid "Password*" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:13 +msgid "Domain*" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:14 +msgid "Proxy" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:15 +msgid "Configure your account (step 1/1)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:16 +msgid "Enter your linphone.org username" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:19 +msgid "Enter your sip username (step 1/1)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:20 +msgid "(*) Required fields" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:21 +msgid "Email: (*)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:22 +msgid "Username: (*)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:23 +msgid "Password: (*)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:24 +msgid "Confirm your password: (*)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:25 +msgid "Keep me informed with linphone updates" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:26 +msgid "Enter account information (step 1/2)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:27 +msgid "Your account is being created, please wait." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:28 +msgid "Account creation in progress" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:29 +msgid "" +"Please validate your account by clicking on the link we just sent you by email.\n" +"Then come back here and press Next button." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:31 +msgid "Validation (step 2/2)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:32 +msgid "Checking if your account is been validated, please wait." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:33 +msgid "Account validation check in progress" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:34 +msgid "" +"Error, account not validated, username already used or server unreachable.\n" +"Please go back and try again." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:36 +msgid "Error" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:37 +msgid "Thank you. Your account is now configured and ready for use." +msgstr "" + +#: ../gtk/sip_account.ui.h:1 +msgid "Linphone - Configure a SIP account" +msgstr "" + +#: ../gtk/sip_account.ui.h:2 +msgid "Your SIP identity:" +msgstr "" + +#: ../gtk/sip_account.ui.h:3 +msgid "Looks like sip:@" +msgstr "" + +#: ../gtk/sip_account.ui.h:4 +msgid "sip:" +msgstr "" + +#: ../gtk/sip_account.ui.h:5 +msgid "SIP Proxy address:" +msgstr "" + +#: ../gtk/sip_account.ui.h:6 +msgid "Looks like sip:" +msgstr "" + +#: ../gtk/sip_account.ui.h:7 +msgid "Registration duration (sec):" +msgstr "" + +#: ../gtk/sip_account.ui.h:8 +msgid "Contact params (optional):" +msgstr "" + +#: ../gtk/sip_account.ui.h:9 +msgid "AVPF regular RTCP interval (sec):" +msgstr "" + +#: ../gtk/sip_account.ui.h:10 +msgid "Route (optional):" +msgstr "Rota (opcional):" + +#: ../gtk/sip_account.ui.h:11 +msgid "Transport" +msgstr "" + +#: ../gtk/sip_account.ui.h:12 +msgid "Register" +msgstr "" + +#: ../gtk/sip_account.ui.h:13 +msgid "Publish presence information" +msgstr "" + +#: ../gtk/sip_account.ui.h:14 +msgid "Enable AVPF" +msgstr "" + +#: ../gtk/sip_account.ui.h:15 +msgid "Configure a SIP account" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:1 +msgid "Configure VoIP tunnel" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:2 +msgid "Host" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:3 +msgid "Port" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:6 +msgid "Configure tunnel" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:9 +msgid "Configure http proxy (optional)" +msgstr "" + +#: ../gtk/waiting.ui.h:2 +msgid "Please wait" +msgstr "" + +#: ../coreapi/linphonecore.c:1560 msgid "Ready" msgstr "" -#: ../coreapi/linphonecore.c:2551 +#: ../coreapi/linphonecore.c:2556 msgid "Configuring" msgstr "" -#: ../coreapi/linphonecore.c:2725 -msgid "Looking for telephone number destination..." -msgstr "Procurando por telefone de destino..." - -#: ../coreapi/linphonecore.c:2727 -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:3013 +#: ../coreapi/linphonecore.c:2951 msgid "Contacting" msgstr "" -#: ../coreapi/linphonecore.c:3018 +#: ../coreapi/linphonecore.c:2956 msgid "Could not call" msgstr "" -#: ../coreapi/linphonecore.c:3169 +#: ../coreapi/linphonecore.c:3092 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "" -#: ../coreapi/linphonecore.c:3327 +#: ../coreapi/linphonecore.c:3250 msgid "is contacting you" msgstr "" -#: ../coreapi/linphonecore.c:3328 +#: ../coreapi/linphonecore.c:3251 msgid " and asked autoanswer." msgstr "" -#: ../coreapi/linphonecore.c:3452 +#: ../coreapi/linphonecore.c:3377 msgid "Modifying call parameters..." msgstr "" -#: ../coreapi/linphonecore.c:3802 +#: ../coreapi/linphonecore.c:3769 msgid "Connected." msgstr "Conectado." -#: ../coreapi/linphonecore.c:3827 +#: ../coreapi/linphonecore.c:3794 msgid "Call aborted" msgstr "" -#: ../coreapi/linphonecore.c:4024 +#: ../coreapi/linphonecore.c:3983 msgid "Could not pause the call" msgstr "" -#: ../coreapi/linphonecore.c:4027 +#: ../coreapi/linphonecore.c:3986 msgid "Pausing the current call..." msgstr "" -#: ../coreapi/misc.c:434 +#: ../coreapi/misc.c:440 msgid "Stun lookup in progress..." msgstr "" -#: ../coreapi/misc.c:615 +#: ../coreapi/misc.c:650 msgid "ICE local candidates gathering in progress..." msgstr "" @@ -1815,166 +1879,173 @@ msgstr "" msgid "Unknown status" msgstr "" -#: ../coreapi/proxy.c:328 +#: ../coreapi/proxy.c:292 msgid "" "The sip proxy address you entered is invalid, it must start with \"sip:\" " "followed by a hostname." msgstr "" -#: ../coreapi/proxy.c:334 +#: ../coreapi/proxy.c:298 msgid "" "The sip identity you entered is invalid.\n" "It should look like sip:username@proxydomain, such as sip:alice@example.net" msgstr "" -#: ../coreapi/proxy.c:1416 +#: ../coreapi/proxy.c:927 +msgid "Looking for telephone number destination..." +msgstr "Procurando por telefone de destino..." + +#: ../coreapi/proxy.c:931 +msgid "Could not resolve this number." +msgstr "Não foi possível encontrar este número." + +#: ../coreapi/proxy.c:1324 #, c-format msgid "Could not login as %s" msgstr "" -#: ../coreapi/callbacks.c:428 +#: ../coreapi/proxy.c:1411 +#, c-format +msgid "Refreshing on %s..." +msgstr "" + +#: ../coreapi/callbacks.c:423 msgid "Remote ringing." msgstr "" -#: ../coreapi/callbacks.c:440 +#: ../coreapi/callbacks.c:435 msgid "Remote ringing..." msgstr "" -#: ../coreapi/callbacks.c:461 +#: ../coreapi/callbacks.c:458 msgid "Early media." msgstr "" -#: ../coreapi/callbacks.c:534 +#: ../coreapi/callbacks.c:488 #, c-format -msgid "Call with %s is paused." +msgid "Call answered by %s" msgstr "" -#: ../coreapi/callbacks.c:547 -#, c-format -msgid "Call answered by %s - on hold." -msgstr "" - -#: ../coreapi/callbacks.c:557 +#: ../coreapi/callbacks.c:527 msgid "Call resumed." msgstr "" -#: ../coreapi/callbacks.c:561 -#, c-format -msgid "Call answered by %s." -msgstr "" - -#: ../coreapi/callbacks.c:584 +#: ../coreapi/callbacks.c:582 msgid "Incompatible, check codecs or security settings..." msgstr "" -#: ../coreapi/callbacks.c:589 ../coreapi/callbacks.c:906 +#: ../coreapi/callbacks.c:587 ../coreapi/callbacks.c:923 msgid "Incompatible media parameters." msgstr "" -#: ../coreapi/callbacks.c:619 +#: ../coreapi/callbacks.c:612 msgid "We have been resumed." msgstr "" #. we are being paused -#: ../coreapi/callbacks.c:628 +#: ../coreapi/callbacks.c:620 msgid "We are paused by other party." msgstr "" -#. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:666 +#: ../coreapi/callbacks.c:630 msgid "Call is updated by remote." msgstr "" -#: ../coreapi/callbacks.c:782 +#: ../coreapi/callbacks.c:799 msgid "Call terminated." msgstr "" -#: ../coreapi/callbacks.c:810 +#: ../coreapi/callbacks.c:827 msgid "User is busy." msgstr "Usuário está ocupado." -#: ../coreapi/callbacks.c:811 +#: ../coreapi/callbacks.c:828 msgid "User is temporarily unavailable." msgstr "Usuário está temporáriamente indisponível." #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:813 +#: ../coreapi/callbacks.c:830 msgid "User does not want to be disturbed." msgstr "" -#: ../coreapi/callbacks.c:814 +#: ../coreapi/callbacks.c:831 msgid "Call declined." msgstr "" -#: ../coreapi/callbacks.c:829 +#: ../coreapi/callbacks.c:846 msgid "Request timeout." msgstr "" -#: ../coreapi/callbacks.c:860 +#: ../coreapi/callbacks.c:877 msgid "Redirected" msgstr "" -#: ../coreapi/callbacks.c:915 +#: ../coreapi/callbacks.c:927 msgid "Call failed." msgstr "" -#: ../coreapi/callbacks.c:993 +#: ../coreapi/callbacks.c:1005 #, c-format msgid "Registration on %s successful." msgstr "" -#: ../coreapi/callbacks.c:994 +#: ../coreapi/callbacks.c:1006 #, c-format msgid "Unregistration on %s done." msgstr "" -#: ../coreapi/callbacks.c:1012 +#: ../coreapi/callbacks.c:1024 msgid "no response timeout" msgstr "" -#: ../coreapi/callbacks.c:1015 +#: ../coreapi/callbacks.c:1027 #, c-format msgid "Registration on %s failed: %s" msgstr "" -#: ../coreapi/callbacks.c:1022 +#: ../coreapi/callbacks.c:1034 msgid "Service unavailable, retrying" msgstr "" #. if encryption is DTLS, no status to be displayed -#: ../coreapi/linphonecall.c:180 +#: ../coreapi/linphonecall.c:197 #, c-format msgid "Authentication token is %s" msgstr "" -#: ../coreapi/linphonecall.c:1310 +#: ../coreapi/linphonecall.c:1561 +#, c-format +msgid "Call parameters could not be modified: %s." +msgstr "" + +#: ../coreapi/linphonecall.c:1563 msgid "Call parameters were successfully modified." msgstr "" -#: ../coreapi/linphonecall.c:3686 +#: ../coreapi/linphonecall.c:4396 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." msgstr[0] "" msgstr[1] "" -#: ../coreapi/call_log.c:209 +#: ../coreapi/call_log.c:223 msgid "aborted" msgstr "" -#: ../coreapi/call_log.c:212 +#: ../coreapi/call_log.c:226 msgid "completed" msgstr "" -#: ../coreapi/call_log.c:215 +#: ../coreapi/call_log.c:229 msgid "missed" msgstr "" -#: ../coreapi/call_log.c:218 +#: ../coreapi/call_log.c:232 msgid "unknown" msgstr "" -#: ../coreapi/call_log.c:220 +#: ../coreapi/call_log.c:234 #, c-format msgid "" "%s at %s\n" @@ -1984,7 +2055,7 @@ msgid "" "Duration: %i mn %i sec\n" msgstr "" -#: ../coreapi/call_log.c:221 +#: ../coreapi/call_log.c:235 msgid "Outgoing call" msgstr "" diff --git a/po/ru.po b/po/ru.po index a82543013..c9948b51b 100644 --- a/po/ru.po +++ b/po/ru.po @@ -12,76 +12,87 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-04-30 10:13+0200\n" -"PO-Revision-Date: 2015-04-30 08:13+0000\n" +"POT-Creation-Date: 2015-11-10 15:16+0100\n" +"PO-Revision-Date: 2015-11-10 14:16+0000\n" "Last-Translator: Belledonne Communications \n" -"Language-Team: Russian (http://www.transifex.com/projects/p/linphone-gtk/language/ru/)\n" +"Language-Team: Russian (http://www.transifex.com/belledonne-communications/linphone-gtk/language/ru/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: ru\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n" -#: ../gtk/calllogs.c:148 ../gtk/friendlist.c:974 +#: ../gtk/calllogs.c:178 #, c-format msgid "Call %s" msgstr "Звонок %s" -#: ../gtk/calllogs.c:149 ../gtk/friendlist.c:975 +#: ../gtk/calllogs.c:179 #, c-format msgid "Send text to %s" msgstr "Послать текст для %s" -#: ../gtk/calllogs.c:232 +#: ../gtk/calllogs.c:181 +#, c-format +msgid "Add %s to your contact list" +msgstr "Добавить %s в мой список контактов" + +#: ../gtk/calllogs.c:245 ../gtk/main.ui.h:21 +msgid "Recent calls" +msgstr "Последние звонки" + +#: ../gtk/calllogs.c:260 #, c-format msgid "Recent calls (%i)" msgstr "Последние вызовы (%i)" -#: ../gtk/calllogs.c:314 +#: ../gtk/calllogs.c:331 msgid "n/a" msgstr "—" -#: ../gtk/calllogs.c:317 +#: ../gtk/calllogs.c:334 msgid "Aborted" msgstr "Прервано" -#: ../gtk/calllogs.c:320 +#: ../gtk/calllogs.c:337 msgid "Missed" msgstr "Пропущено" -#: ../gtk/calllogs.c:323 +#: ../gtk/calllogs.c:340 msgid "Declined" msgstr "Отклонено" -#: ../gtk/calllogs.c:329 +#: ../gtk/calllogs.c:346 #, c-format msgid "%i minute" msgid_plural "%i minutes" msgstr[0] "%i минута" msgstr[1] "%i минуты" msgstr[2] "%i минут" +msgstr[3] "%i минут" -#: ../gtk/calllogs.c:332 +#: ../gtk/calllogs.c:349 #, c-format msgid "%i second" msgid_plural "%i seconds" msgstr[0] "%i секунда" msgstr[1] "%i секунды" msgstr[2] "%i секунд" +msgstr[3] "%i секунд" -#: ../gtk/calllogs.c:337 +#: ../gtk/calllogs.c:354 #, c-format msgid "" "%s\tQuality: %s\n" "%s\t%s\t" msgstr "%s\tКачество: %s\n%s\t%s\t" -#: ../gtk/calllogs.c:341 +#: ../gtk/calllogs.c:358 #, c-format msgid "%s\t%s" msgstr "%s\t%s" -#: ../gtk/conference.c:38 ../gtk/main.ui.h:13 +#: ../gtk/conference.c:38 ../gtk/in_call_frame.ui.h:11 msgid "Conference" msgstr "Конференция" @@ -94,297 +105,314 @@ msgstr "Мне" msgid "Couldn't find pixmap file: %s" msgstr "Невозможно найти графический файл: %s" -#: ../gtk/main.c:137 +#: ../gtk/chat.c:196 ../gtk/chat.c:254 +msgid "Sending..." +msgstr "Отправка..." + +#: ../gtk/chat.c:213 ../gtk/chat.c:263 +msgid "Message not sent" +msgstr "Сообщение не отправилось" + +#: ../gtk/chat.c:472 +msgid "Copy" +msgstr "Копировать" + +#: ../gtk/main.c:138 msgid "log to stdout some debug information while running." msgstr "Вывод некоторой отладочной информации на устройство стандартного вывода во время работы." -#: ../gtk/main.c:138 +#: ../gtk/main.c:139 +msgid "display version and exit." +msgstr "показать версию и выйти." + +#: ../gtk/main.c:140 msgid "path to a file to write logs into." msgstr "Путь к файлу для записи логов." -#: ../gtk/main.c:139 +#: ../gtk/main.c:141 msgid "Start linphone with video disabled." msgstr "Запуск linphone с видео отключен." -#: ../gtk/main.c:140 +#: ../gtk/main.c:142 msgid "Start only in the system tray, do not show the main interface." msgstr "Показывать только в системном лотке, не запуская главное окно." -#: ../gtk/main.c:141 +#: ../gtk/main.c:143 msgid "address to call right now" msgstr "Адрес для звонка прямо сейчас." -#: ../gtk/main.c:142 +#: ../gtk/main.c:144 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:143 +#: ../gtk/main.c:145 msgid "Configuration file" msgstr "Файл конфигурации" -#: ../gtk/main.c:144 +#: ../gtk/main.c:146 msgid "Run the audio assistant" msgstr "Запустить помощника аудио" -#: ../gtk/main.c:145 +#: ../gtk/main.c:147 msgid "Run self test and exit 0 if succeed" msgstr "Запустить самотест и выйти при успехе со статусом 0" -#: ../gtk/main.c:1070 +#: ../gtk/main.c:1046 #, c-format msgid "" -"%s would like to add you to his contact list.\n" -"Would you allow him to see your presence status or add him to your contact list ?\n" +"%s would like to add you to his/her contact list.\n" +"Would you add him/her to your contact list and allow him/her to see your presence status?\n" "If you answer no, this person will be temporarily blacklisted." -msgstr "%s вы бы хотели быть добавленным в этот контактный лист.\nВы разрешаете ему(ей) видеть ваш статус присутствия или добавить в контактный лист?\nЕсли вы ответите Нет, эта персона будет временно в чёрном списке." +msgstr "%s хочет добавить Вас в его/её список контактов.\nВы бы добавили его/её в свой список контактов и позволили ему/ей видеть ваш статус присутствия?\nЕсли вы ответите нет, то этот человек будет временно занесён в чёрный список." -#: ../gtk/main.c:1147 +#: ../gtk/main.c:1123 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" msgstr "Пожалуйста, введите пароль для пользователя %s\n для реалм (рилм) %s:" -#: ../gtk/main.c:1268 +#: ../gtk/main.c:1253 msgid "Call error" msgstr "Ошибка звонка" -#: ../gtk/main.c:1271 ../coreapi/linphonecore.c:3846 +#: ../gtk/main.c:1256 ../coreapi/linphonecore.c:3813 msgid "Call ended" msgstr "Звонок окончен" -#: ../gtk/main.c:1274 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1259 ../coreapi/call_log.c:235 msgid "Incoming call" msgstr "Входящий звонок" -#: ../gtk/main.c:1276 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1261 ../gtk/incall_view.c:580 ../gtk/in_call_frame.ui.h:2 msgid "Answer" msgstr "Ответ" -#: ../gtk/main.c:1278 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1263 ../gtk/in_call_frame.ui.h:3 msgid "Decline" msgstr "Отклонить" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 msgid "Call paused" msgstr "Звонок приостановлен" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 #, c-format msgid "by %s" msgstr "%s" -#: ../gtk/main.c:1354 +#: ../gtk/main.c:1339 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "%s предложил запустить видео. Вы принимаете?" -#: ../gtk/main.c:1509 +#: ../gtk/main.c:1505 msgid "Website link" msgstr "Домашняя страница" -#: ../gtk/main.c:1568 ../gtk/waiting.ui.h:1 +#: ../gtk/main.c:1564 ../gtk/waiting.ui.h:1 msgid "Linphone" msgstr "Linphone" -#: ../gtk/main.c:1569 +#: ../gtk/main.c:1565 msgid "A video internet phone" -msgstr "" +msgstr "Видео интернет телефон" -#: ../gtk/main.c:1629 +#: ../gtk/main.c:1624 #, c-format msgid "%s (Default)" msgstr "%s (по умолчанию)" -#: ../gtk/main.c:1962 ../coreapi/callbacks.c:1063 +#: ../gtk/main.c:1960 ../coreapi/callbacks.c:1075 #, c-format msgid "We are transferred to %s" msgstr "Мы передали в %s" -#: ../gtk/main.c:1972 +#: ../gtk/main.c:1970 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." msgstr "Звуковые карты не были обнаружены на этом компьютере.\nВы не сможете отправлять или получать аудио звонки." -#: ../gtk/main.c:2117 +#: ../gtk/main.c:2129 msgid "A free SIP video-phone" msgstr "Свободный SIP видео-телефон" -#: ../gtk/main.c:2221 +#: ../gtk/main.c:2242 #, c-format msgid "Hello\n" msgstr "Привет\n" -#: ../gtk/friendlist.c:505 +#: ../gtk/friendlist.c:461 msgid "Add to addressbook" msgstr "Добавить в адресную книгу" -#: ../gtk/friendlist.c:691 -msgid "Presence status" -msgstr "Статус присутствия" - -#: ../gtk/friendlist.c:709 ../gtk/propertybox.c:569 ../gtk/contact.ui.h:1 -msgid "Name" -msgstr "Имя" - -#: ../gtk/friendlist.c:721 -msgid "Call" -msgstr "Звонок" - -#: ../gtk/friendlist.c:726 -msgid "Chat" -msgstr "Чат" - -#: ../gtk/friendlist.c:756 +#: ../gtk/friendlist.c:627 #, c-format msgid "Search in %s directory" msgstr "Поиск в директории %s" -#: ../gtk/friendlist.c:924 +#: ../gtk/friendlist.c:772 msgid "Invalid sip contact !" msgstr "Неверный sip контакт!" -#: ../gtk/friendlist.c:976 +#: ../gtk/friendlist.c:820 +#, c-format +msgid "Add a new contact" +msgstr "Добавить новый контакт" + +#: ../gtk/friendlist.c:823 #, c-format msgid "Edit contact '%s'" msgstr "Редактировать контакт '%s'" -#: ../gtk/friendlist.c:977 +#: ../gtk/friendlist.c:824 #, c-format msgid "Delete contact '%s'" msgstr "Удалить контакт '%s'" -#: ../gtk/friendlist.c:978 +#: ../gtk/friendlist.c:825 #, c-format msgid "Delete chat history of '%s'" msgstr "Удалить историю чата для '%s'" -#: ../gtk/friendlist.c:1029 +#: ../gtk/friendlist.c:862 #, c-format msgid "Add new contact from %s directory" msgstr "Добавить новый контакт из директории '%s'" -#: ../gtk/propertybox.c:575 +#: ../gtk/propertybox.c:592 ../gtk/contact.ui.h:1 +msgid "Name" +msgstr "Имя" + +#: ../gtk/propertybox.c:598 msgid "Rate (Hz)" msgstr "Частота (Гц)" -#: ../gtk/propertybox.c:581 +#: ../gtk/propertybox.c:604 msgid "Status" msgstr "Статус" -#: ../gtk/propertybox.c:587 +#: ../gtk/propertybox.c:617 msgid "IP Bitrate (kbit/s)" msgstr "IP битрейт (КБит/сек)" -#: ../gtk/propertybox.c:596 +#: ../gtk/propertybox.c:628 msgid "Parameters" msgstr "Параметры" -#: ../gtk/propertybox.c:639 ../gtk/propertybox.c:782 +#: ../gtk/propertybox.c:670 ../gtk/propertybox.c:824 msgid "Enabled" msgstr "Разрешён" -#: ../gtk/propertybox.c:641 ../gtk/propertybox.c:782 ../gtk/parameters.ui.h:20 +#: ../gtk/propertybox.c:672 ../gtk/propertybox.c:824 ../gtk/parameters.ui.h:60 msgid "Disabled" msgstr "Не разрешён" -#: ../gtk/propertybox.c:828 +#: ../gtk/propertybox.c:902 msgid "Account" msgstr "Учётная запись" -#: ../gtk/propertybox.c:1091 +#: ../gtk/propertybox.c:1170 msgid "English" msgstr "Английский" -#: ../gtk/propertybox.c:1092 +#: ../gtk/propertybox.c:1171 msgid "French" msgstr "Французский" -#: ../gtk/propertybox.c:1093 +#: ../gtk/propertybox.c:1172 msgid "Swedish" msgstr "Шведский" -#: ../gtk/propertybox.c:1094 +#: ../gtk/propertybox.c:1173 msgid "Italian" msgstr "Итальянский" -#: ../gtk/propertybox.c:1095 +#: ../gtk/propertybox.c:1174 msgid "Spanish" msgstr "Испанский" -#: ../gtk/propertybox.c:1096 +#: ../gtk/propertybox.c:1175 msgid "Brazilian Portugese" msgstr "Бразильский португальский" -#: ../gtk/propertybox.c:1097 +#: ../gtk/propertybox.c:1176 msgid "Polish" msgstr "Польский" -#: ../gtk/propertybox.c:1098 +#: ../gtk/propertybox.c:1177 msgid "German" msgstr "Немецкий" -#: ../gtk/propertybox.c:1099 +#: ../gtk/propertybox.c:1178 msgid "Russian" msgstr "Русский" -#: ../gtk/propertybox.c:1100 +#: ../gtk/propertybox.c:1179 msgid "Japanese" msgstr "Японский" -#: ../gtk/propertybox.c:1101 +#: ../gtk/propertybox.c:1180 msgid "Dutch" msgstr "Датский" -#: ../gtk/propertybox.c:1102 +#: ../gtk/propertybox.c:1181 msgid "Hungarian" msgstr "Венгерский" -#: ../gtk/propertybox.c:1103 +#: ../gtk/propertybox.c:1182 msgid "Czech" msgstr "Чешский" -#: ../gtk/propertybox.c:1104 +#: ../gtk/propertybox.c:1183 msgid "Chinese" msgstr "Китайский" -#: ../gtk/propertybox.c:1105 +#: ../gtk/propertybox.c:1184 msgid "Traditional Chinese" msgstr "Традиционный китайский" -#: ../gtk/propertybox.c:1106 +#: ../gtk/propertybox.c:1185 msgid "Norwegian" msgstr "Норвежский" -#: ../gtk/propertybox.c:1107 +#: ../gtk/propertybox.c:1186 msgid "Hebrew" msgstr "Иврит" -#: ../gtk/propertybox.c:1108 +#: ../gtk/propertybox.c:1187 msgid "Serbian" msgstr "Сербский" -#: ../gtk/propertybox.c:1175 +#: ../gtk/propertybox.c:1188 +msgid "Arabic" +msgstr "Арабский" + +#: ../gtk/propertybox.c:1189 +msgid "Turkish" +msgstr "Турецкий" + +#: ../gtk/propertybox.c:1246 msgid "" "You need to restart linphone for the new language selection to take effect." msgstr "Вы должны перезагрузить linphone для того, чтобы языковые настройки вступили в силу." -#: ../gtk/propertybox.c:1255 +#: ../gtk/propertybox.c:1326 msgid "None" msgstr "Нет" -#: ../gtk/propertybox.c:1259 +#: ../gtk/propertybox.c:1330 msgid "SRTP" msgstr "SRTP" -#: ../gtk/propertybox.c:1265 +#: ../gtk/propertybox.c:1336 msgid "DTLS" msgstr "DTLS" -#: ../gtk/propertybox.c:1272 +#: ../gtk/propertybox.c:1343 msgid "ZRTP" msgstr "ZRTP" @@ -426,325 +454,197 @@ msgid_plural "Found %i contacts" msgstr[0] "Найден %i контакт" msgstr[1] "Найдено %i контакта" msgstr[2] "Найдено %i контактов" +msgstr[3] "Найдено %i контактов" -#: ../gtk/setupwizard.c:32 -msgid "" -"Welcome!\n" -"This assistant will help you to use a SIP account for your calls." -msgstr "Добро пожаловать!\nЭтот ассистент поможет вам использовать SIP аккаунт для ваших звонков." - -#: ../gtk/setupwizard.c:41 -msgid "Create an account on linphone.org" -msgstr "Создать учётную запись на linphone.org" - -#: ../gtk/setupwizard.c:42 -msgid "I have already a linphone.org account and I just want to use it" -msgstr "Я уже имею учётную запись на linphone.org и только хочу использовать её" - -#: ../gtk/setupwizard.c:43 -msgid "I have already a sip account and I just want to use it" -msgstr "Я уже имею учётную запись sip и только хочу использовать её" - -#: ../gtk/setupwizard.c:44 -msgid "I want to specify a remote configuration URI" -msgstr "Я хочу указать удалённую конфигурацию URI" - -#: ../gtk/setupwizard.c:87 -msgid "Enter your linphone.org username" -msgstr "Введите ваше имя пользователя для linphone.org" - -#: ../gtk/setupwizard.c:100 ../gtk/parameters.ui.h:85 ../gtk/ldap.ui.h:4 -msgid "Username:" -msgstr "Имя пользователя:" - -#: ../gtk/setupwizard.c:102 ../gtk/password.ui.h:4 ../gtk/ldap.ui.h:5 -msgid "Password:" -msgstr "Пароль:" - -#: ../gtk/setupwizard.c:122 -msgid "Enter your account informations" -msgstr "Введите вашу информацию об учётной записи" - -#: ../gtk/setupwizard.c:138 -msgid "Username*" -msgstr "Имя пользователя*" - -#: ../gtk/setupwizard.c:139 -msgid "Password*" -msgstr "Пароль*" - -#: ../gtk/setupwizard.c:142 -msgid "Domain*" -msgstr "Домен*" - -#: ../gtk/setupwizard.c:143 -msgid "Proxy" -msgstr "Прокси" - -#: ../gtk/setupwizard.c:322 -msgid "(*) Required fields" -msgstr "(*) Обязательные поля" - -#: ../gtk/setupwizard.c:323 -msgid "Username: (*)" -msgstr "Имя пользователя: (*)" - -#: ../gtk/setupwizard.c:325 -msgid "Password: (*)" -msgstr "Пароль: (*)" - -#: ../gtk/setupwizard.c:327 -msgid "Email: (*)" -msgstr "Электронная почта: (*)" - -#: ../gtk/setupwizard.c:329 -msgid "Confirm your password: (*)" -msgstr "Подтвердите ваш пароль: (*)" - -#: ../gtk/setupwizard.c:343 -msgid "Keep me informed with linphone updates" -msgstr "Информировать об обновлениях linphone" - -#: ../gtk/setupwizard.c:399 -msgid "" -"Error, account not validated, username already used or server unreachable.\n" -"Please go back and try again." -msgstr "Ошибка, учётная запись не подтверждена, имя пользователя уже используется или\nсервер недоступен. Пожалуйста, зайдите снова и попробуйте ещё раз." - -#: ../gtk/setupwizard.c:410 -msgid "Thank you. Your account is now configured and ready for use." -msgstr "Спасибо! Учётная запись успешно настроена и готова к использованию." - -#: ../gtk/setupwizard.c:418 -msgid "" -"Please validate your account by clicking on the link we just sent you by email.\n" -"Then come back here and press Next button." -msgstr "Пожалуйста, подтвердите вашу учётную запись, щёлкнув на ссылку, которую вы только\nчто получили по электронной почте. Затем вернитесь сюда и нажмите кнопку Далее." - -#: ../gtk/setupwizard.c:609 -msgid "SIP account configuration assistant" -msgstr "Помощник настройки учётной записи SIP" - -#: ../gtk/setupwizard.c:629 -msgid "Welcome to the account setup assistant" -msgstr "Добро пожаловать в помощник настройки учётной записи" - -#: ../gtk/setupwizard.c:634 -msgid "Account setup assistant" -msgstr "Помощник настройки учётной записи" - -#: ../gtk/setupwizard.c:640 -msgid "Configure your account (step 1/1)" -msgstr "Настроить вашу учётную запись (шаг 1/1)" - -#: ../gtk/setupwizard.c:645 -msgid "Enter your sip username (step 1/1)" -msgstr "Введите ваше sip имя пользователя (шаг 1/1)" - -#: ../gtk/setupwizard.c:649 -msgid "Enter account information (step 1/2)" -msgstr "Введите информацию об учётной записи (шаг 1/2)" - -#: ../gtk/setupwizard.c:658 -msgid "Validation (step 2/2)" -msgstr "Подтверждение (шаг 2/2)" - -#: ../gtk/setupwizard.c:663 -msgid "Error" -msgstr "Ошибка" - -#: ../gtk/setupwizard.c:667 ../gtk/audio_assistant.c:534 -msgid "Terminating" -msgstr "Прерывание" - -#: ../gtk/incall_view.c:70 ../gtk/incall_view.c:94 +#: ../gtk/incall_view.c:67 ../gtk/incall_view.c:87 #, c-format msgid "Call #%i" msgstr "Звонок #%i" -#: ../gtk/incall_view.c:155 +#: ../gtk/incall_view.c:145 #, c-format msgid "Transfer to call #%i with %s" msgstr "Передача позвонить #%i с %s" -#: ../gtk/incall_view.c:211 ../gtk/incall_view.c:214 +#: ../gtk/incall_view.c:202 ../gtk/incall_view.c:205 msgid "Not used" msgstr "Не используется" -#: ../gtk/incall_view.c:221 +#: ../gtk/incall_view.c:212 msgid "ICE not activated" msgstr "ICE не активировано" -#: ../gtk/incall_view.c:223 +#: ../gtk/incall_view.c:214 msgid "ICE failed" msgstr "Неудача ICE" -#: ../gtk/incall_view.c:225 +#: ../gtk/incall_view.c:216 msgid "ICE in progress" msgstr "ICE в прогрессе" -#: ../gtk/incall_view.c:227 +#: ../gtk/incall_view.c:218 msgid "Going through one or more NATs" msgstr "Пройти через один или несколько NAT" -#: ../gtk/incall_view.c:229 +#: ../gtk/incall_view.c:220 msgid "Direct" msgstr "Напрямую" -#: ../gtk/incall_view.c:231 +#: ../gtk/incall_view.c:222 msgid "Through a relay server" msgstr "Через сервер ретрансляции" -#: ../gtk/incall_view.c:239 +#: ../gtk/incall_view.c:230 msgid "uPnP not activated" msgstr "uPnP не активировано" -#: ../gtk/incall_view.c:241 +#: ../gtk/incall_view.c:232 msgid "uPnP in progress" msgstr "uPnP в прогрессе" -#: ../gtk/incall_view.c:243 +#: ../gtk/incall_view.c:234 msgid "uPnp not available" msgstr "uPnp недоступен" -#: ../gtk/incall_view.c:245 +#: ../gtk/incall_view.c:236 msgid "uPnP is running" msgstr "uPnP выполняется" -#: ../gtk/incall_view.c:247 +#: ../gtk/incall_view.c:238 msgid "uPnP failed" msgstr "Неудача uPnP" -#: ../gtk/incall_view.c:257 ../gtk/incall_view.c:258 +#: ../gtk/incall_view.c:248 ../gtk/incall_view.c:249 msgid "Direct or through server" msgstr "Напрямую или через сервер" -#: ../gtk/incall_view.c:267 ../gtk/incall_view.c:279 +#: ../gtk/incall_view.c:258 ../gtk/incall_view.c:270 #, c-format msgid "" "download: %f\n" "upload: %f (kbit/s)" msgstr "загрузка: %f\nотдача: %f (КБит/сек)" -#: ../gtk/incall_view.c:272 ../gtk/incall_view.c:274 +#: ../gtk/incall_view.c:263 ../gtk/incall_view.c:265 #, c-format msgid "%ix%i @ %f fps" msgstr "%ix%i @ %f кадр/сек" -#: ../gtk/incall_view.c:304 +#: ../gtk/incall_view.c:295 #, c-format msgid "%.3f seconds" msgstr "%.3f секунд" -#: ../gtk/incall_view.c:407 ../gtk/main.ui.h:12 ../gtk/videowindow.c:235 +#: ../gtk/incall_view.c:453 ../gtk/in_call_frame.ui.h:10 +#: ../gtk/videowindow.c:236 msgid "Hang up" msgstr "Повесить трубку" -#: ../gtk/incall_view.c:511 +#: ../gtk/incall_view.c:559 msgid "Calling..." msgstr "Звоним..." -#: ../gtk/incall_view.c:514 ../gtk/incall_view.c:733 -msgid "00::00::00" -msgstr "00::00::00" +#: ../gtk/incall_view.c:562 ../gtk/incall_view.c:792 +msgid "00:00:00" +msgstr "00:00:00" -#: ../gtk/incall_view.c:525 +#: ../gtk/incall_view.c:573 msgid "Incoming call" msgstr "Входящий звонок" -#: ../gtk/incall_view.c:562 +#: ../gtk/incall_view.c:610 msgid "good" msgstr "хороший" -#: ../gtk/incall_view.c:564 +#: ../gtk/incall_view.c:612 msgid "average" msgstr "средний" -#: ../gtk/incall_view.c:566 +#: ../gtk/incall_view.c:614 msgid "poor" msgstr "плохой" -#: ../gtk/incall_view.c:568 +#: ../gtk/incall_view.c:616 msgid "very poor" msgstr "очень плохой" -#: ../gtk/incall_view.c:570 +#: ../gtk/incall_view.c:618 msgid "too bad" msgstr "совсем плохой" -#: ../gtk/incall_view.c:571 ../gtk/incall_view.c:587 +#: ../gtk/incall_view.c:619 ../gtk/incall_view.c:635 msgid "unavailable" msgstr "недоступен" -#: ../gtk/incall_view.c:679 +#: ../gtk/incall_view.c:731 msgid "Secured by SRTP" msgstr "Защищённые с помощью SRTP" -#: ../gtk/incall_view.c:685 +#: ../gtk/incall_view.c:737 msgid "Secured by DTLS" msgstr "Защищённые с помощью DTLS" -#: ../gtk/incall_view.c:691 +#: ../gtk/incall_view.c:743 #, c-format msgid "Secured by ZRTP - [auth token: %s]" msgstr "Защищённые с помощью ZRTP - [знак аутентификации: %s]" -#: ../gtk/incall_view.c:697 +#: ../gtk/incall_view.c:747 msgid "Set unverified" msgstr "Установить непроверенный" -#: ../gtk/incall_view.c:697 ../gtk/main.ui.h:4 +#: ../gtk/incall_view.c:747 msgid "Set verified" msgstr "Установить проверенный" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In conference" msgstr "В конференции" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In call" msgstr "Звоним" -#: ../gtk/incall_view.c:764 +#: ../gtk/incall_view.c:824 msgid "Paused call" msgstr "Звонок приостановлен" -#: ../gtk/incall_view.c:800 +#: ../gtk/incall_view.c:861 msgid "Call ended." msgstr "Звонок закончен." -#: ../gtk/incall_view.c:831 +#: ../gtk/incall_view.c:892 msgid "Transfer in progress" msgstr "Передача в прогрессе" -#: ../gtk/incall_view.c:834 +#: ../gtk/incall_view.c:895 msgid "Transfer done." msgstr "Передача завершена." -#: ../gtk/incall_view.c:837 +#: ../gtk/incall_view.c:898 msgid "Transfer failed." msgstr "Передача неудачна." -#: ../gtk/incall_view.c:881 +#: ../gtk/incall_view.c:929 msgid "Resume" msgstr "Продолжить" -#: ../gtk/incall_view.c:888 ../gtk/main.ui.h:9 +#: ../gtk/incall_view.c:929 ../gtk/in_call_frame.ui.h:7 msgid "Pause" msgstr "Пауза" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 #, c-format msgid "" "Recording into\n" "%s %s" msgstr "Записывается в\n%s %s" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 msgid "(Paused)" msgstr "(Пауза)" -#: ../gtk/loginframe.c:87 +#: ../gtk/loginframe.c:75 #, c-format msgid "Please enter login information for %s" msgstr "Пожалуйста, введите информацию для входа %s:" @@ -759,263 +659,108 @@ msgstr "получение от %s" msgid "Downloading of remote configuration from %s failed." msgstr "Загрузка удалённой конфигурации из %s неудачна." -#: ../gtk/audio_assistant.c:98 +#: ../gtk/audio_assistant.c:103 msgid "No voice detected" msgstr "Голос не обнаружен" -#: ../gtk/audio_assistant.c:99 +#: ../gtk/audio_assistant.c:104 msgid "Too low" msgstr "Слишком тихо" -#: ../gtk/audio_assistant.c:100 +#: ../gtk/audio_assistant.c:105 msgid "Good" msgstr "Хорошо" -#: ../gtk/audio_assistant.c:101 +#: ../gtk/audio_assistant.c:106 msgid "Too loud" msgstr "Слишком громко" -#: ../gtk/audio_assistant.c:183 +#: ../gtk/audio_assistant.c:188 msgid "Did you hear three beeps ?" msgstr "Вы слышали 3 сигнала?" -#: ../gtk/audio_assistant.c:292 ../gtk/audio_assistant.c:297 +#: ../gtk/audio_assistant.c:299 ../gtk/audio_assistant.c:304 msgid "Sound preferences not found " msgstr "Настройки звука не найдены" -#: ../gtk/audio_assistant.c:306 +#: ../gtk/audio_assistant.c:313 msgid "Cannot launch system sound control " msgstr "Не удаётся запустить системное управление звуком" -#: ../gtk/audio_assistant.c:318 +#: ../gtk/audio_assistant.c:325 msgid "" "Welcome!\n" "This assistant will help you to configure audio settings for Linphone" msgstr "Добро пожаловать!\nЭтот ассистент поможет вам настроить настройки аудио для Linphone." -#: ../gtk/audio_assistant.c:328 +#: ../gtk/audio_assistant.c:335 msgid "Capture device" msgstr "Устройство захвата" -#: ../gtk/audio_assistant.c:329 +#: ../gtk/audio_assistant.c:336 msgid "Recorded volume" msgstr "Уровень записи" -#: ../gtk/audio_assistant.c:333 +#: ../gtk/audio_assistant.c:340 msgid "No voice" msgstr "Нет голоса" -#: ../gtk/audio_assistant.c:334 ../gtk/audio_assistant.c:373 +#: ../gtk/audio_assistant.c:341 ../gtk/audio_assistant.c:380 msgid "System sound preferences" msgstr "Системные настройки звука" -#: ../gtk/audio_assistant.c:369 +#: ../gtk/audio_assistant.c:376 msgid "Playback device" msgstr "Устройство воспроизведения" -#: ../gtk/audio_assistant.c:370 +#: ../gtk/audio_assistant.c:377 msgid "Play three beeps" msgstr "Проиграть три сигнала" -#: ../gtk/audio_assistant.c:403 +#: ../gtk/audio_assistant.c:410 msgid "Press the record button and say some words" msgstr "Нажмите кнопку записи и скажите несколько слов" -#: ../gtk/audio_assistant.c:404 +#: ../gtk/audio_assistant.c:411 msgid "Listen to your record voice" msgstr "Прослушайте ваш записанный голос" -#: ../gtk/audio_assistant.c:405 +#: ../gtk/audio_assistant.c:412 ../gtk/conf_frame.ui.h:2 +#: ../gtk/in_call_frame.ui.h:4 msgid "Record" msgstr "Запись" -#: ../gtk/audio_assistant.c:406 +#: ../gtk/audio_assistant.c:413 msgid "Play" msgstr "Воспроизведение" -#: ../gtk/audio_assistant.c:433 +#: ../gtk/audio_assistant.c:440 msgid "Let's start Linphone now" msgstr "Давайте сейчас запустим linphone" -#: ../gtk/audio_assistant.c:503 +#: ../gtk/audio_assistant.c:510 msgid "Audio Assistant" msgstr "Помощник аудио" -#: ../gtk/audio_assistant.c:513 ../gtk/main.ui.h:32 +#: ../gtk/audio_assistant.c:520 ../gtk/main.ui.h:13 msgid "Audio assistant" msgstr "Помощник аудио" -#: ../gtk/audio_assistant.c:518 +#: ../gtk/audio_assistant.c:525 msgid "Mic Gain calibration" msgstr "Калибровка усиления микрофона" -#: ../gtk/audio_assistant.c:524 +#: ../gtk/audio_assistant.c:531 msgid "Speaker volume calibration" msgstr "Калибровка громкости динамика" -#: ../gtk/audio_assistant.c:529 +#: ../gtk/audio_assistant.c:536 msgid "Record and Play" msgstr "Записать и проиграть" -#: ../gtk/main.ui.h:1 -msgid "Callee name" -msgstr "Имя вызываемого" - -#: ../gtk/main.ui.h:2 -msgid "Send" -msgstr "Отправить" - -#: ../gtk/main.ui.h:3 -msgid "End conference" -msgstr "Конец конференции" - -#: ../gtk/main.ui.h:7 -msgid "Record this call to an audio file" -msgstr "Записать этот вызов в аудио файл" - -#: ../gtk/main.ui.h:8 -msgid "Video" -msgstr "Видео" - -#: ../gtk/main.ui.h:10 -msgid "Mute" -msgstr "Без звука" - -#: ../gtk/main.ui.h:11 -msgid "Transfer" -msgstr "Передача" - -#: ../gtk/main.ui.h:14 -msgid "In call" -msgstr "Входящий звонок" - -#: ../gtk/main.ui.h:15 -msgid "Duration" -msgstr "Продолжительность" - -#: ../gtk/main.ui.h:16 -msgid "Call quality rating" -msgstr "Вызвать рейтинг качества" - -#: ../gtk/main.ui.h:17 -msgid "All users" -msgstr "Все пользователи" - -#: ../gtk/main.ui.h:18 -msgid "Online users" -msgstr "Пользователи в сети" - -#: ../gtk/main.ui.h:19 -msgid "ADSL" -msgstr "ADSL" - -#: ../gtk/main.ui.h:20 -msgid "Fiber Channel" -msgstr "Оптоволоконный канал" - -#: ../gtk/main.ui.h:21 -msgid "Default" -msgstr "По умолчанию" - -#: ../gtk/main.ui.h:22 -msgid "Delete" -msgstr "Удалить" - -#: ../gtk/main.ui.h:23 -msgid "_Options" -msgstr "_Опции" - -#: ../gtk/main.ui.h:24 -msgid "Set configuration URI" -msgstr "Установить конфигурацию URI" - -#: ../gtk/main.ui.h:25 -msgid "Always start video" -msgstr "Всегда запускать видео" - -#: ../gtk/main.ui.h:26 -msgid "Enable self-view" -msgstr "Показать окно видео" - -#: ../gtk/main.ui.h:27 -msgid "_Help" -msgstr "_Помощь" - -#: ../gtk/main.ui.h:28 -msgid "Show debug window" -msgstr "Показать окно отладки" - -#: ../gtk/main.ui.h:29 -msgid "_Homepage" -msgstr "_Домашняя страница" - -#: ../gtk/main.ui.h:30 -msgid "Check _Updates" -msgstr "Проверить _обновления" - -#: ../gtk/main.ui.h:31 -msgid "Account assistant" -msgstr "Помощник учётной записи" - -#: ../gtk/main.ui.h:33 -msgid "SIP address or phone number:" -msgstr "SIP-адрес или номер телефона:" - -#: ../gtk/main.ui.h:34 -msgid "Initiate a new call" -msgstr "Начать новый звонок" - -#: ../gtk/main.ui.h:35 -msgid "Contacts" -msgstr "Контакты" - -#: ../gtk/main.ui.h:36 -msgid "Search" -msgstr "Поиск" - -#: ../gtk/main.ui.h:37 -msgid "Add contacts from directory" -msgstr "Добавить контакты из директории" - -#: ../gtk/main.ui.h:38 -msgid "Add contact" -msgstr "Добавить контакт" - -#: ../gtk/main.ui.h:39 -msgid "Recent calls" -msgstr "Последние звонки" - -#: ../gtk/main.ui.h:40 -msgid "My current identity:" -msgstr "Мой текущий идентификатор:" - -#: ../gtk/main.ui.h:41 ../gtk/tunnel_config.ui.h:7 -msgid "Username" -msgstr "Имя пользователя" - -#: ../gtk/main.ui.h:42 ../gtk/tunnel_config.ui.h:8 -msgid "Password" -msgstr "Пароль" - -#: ../gtk/main.ui.h:43 -msgid "Internet connection:" -msgstr "Интернет-соединение:" - -#: ../gtk/main.ui.h:44 -msgid "Automatically log me in" -msgstr "Входить автоматически" - -#: ../gtk/main.ui.h:45 ../gtk/password.ui.h:3 -msgid "UserID" -msgstr "Идентификатор пользователя" - -#: ../gtk/main.ui.h:46 -msgid "Login information" -msgstr "Информация для входа" - -#: ../gtk/main.ui.h:47 -msgid "Welcome!" -msgstr "Добро пожаловать!" +#: ../gtk/audio_assistant.c:541 ../gtk/setup_wizard.ui.h:38 +msgid "Terminating" +msgstr "Прерывание" #: ../gtk/about.ui.h:1 msgid "About Linphone" @@ -1045,456 +790,6 @@ msgid "" "he: Eli Zaretskii \n" msgstr "fr: Simon Morlat\nen: Simon Morlat and Delphine Perreau\nit: Alberto Zanoni \nde: Jean-Jacques Sarton \nsv: Daniel Nylander \nes: Jesus Benitez \nja: YAMAGUCHI YOSHIYA \npt_BR: Rafael Caesar Lenzi \npl: Robert Nasiadek \ncs: Petr Pisar \nhu: anonymous\nhe: Eli Zaretskii \n" -#: ../gtk/contact.ui.h:2 -msgid "SIP Address" -msgstr "SIP адрес" - -#: ../gtk/contact.ui.h:3 -msgid "Show this contact presence status" -msgstr "Показывать этому контакту статус присутствия" - -#: ../gtk/contact.ui.h:4 -msgid "Allow this contact to see my presence status" -msgstr "Разрешить этому контакту видеть мой статус присутствия" - -#: ../gtk/contact.ui.h:5 -msgid "Contact information" -msgstr "Контактная информация" - -#: ../gtk/log.ui.h:1 -msgid "Linphone debug window" -msgstr "Окно отладки linphone" - -#: ../gtk/log.ui.h:2 -msgid "Scroll to end" -msgstr "Прокрутка в конец" - -#: ../gtk/password.ui.h:1 -msgid "Linphone - Authentication required" -msgstr "Linphone - необходима регистрация" - -#: ../gtk/password.ui.h:2 -msgid "Please enter the domain password" -msgstr "Введите пароль для домена" - -#: ../gtk/call_logs.ui.h:1 -msgid "Call history" -msgstr "История звонков" - -#: ../gtk/call_logs.ui.h:2 -msgid "Clear all" -msgstr "Очистить всё" - -#: ../gtk/call_logs.ui.h:3 -msgid "Call back" -msgstr "Позвонить повторно" - -#: ../gtk/sip_account.ui.h:1 -msgid "Linphone - Configure a SIP account" -msgstr "Linphone - настроить учётную запись SIP" - -#: ../gtk/sip_account.ui.h:2 -msgid "Your SIP identity:" -msgstr "Ваш идентификатор SIP:" - -#: ../gtk/sip_account.ui.h:3 -msgid "Looks like sip:@" -msgstr "Выглядит как sip:<имя_пользователя>@<домен>" - -#: ../gtk/sip_account.ui.h:4 -msgid "sip:" -msgstr "sip:" - -#: ../gtk/sip_account.ui.h:5 -msgid "SIP Proxy address:" -msgstr "Адрес SIP прокси:" - -#: ../gtk/sip_account.ui.h:6 -msgid "Looks like sip:" -msgstr "Выглядит как sip:<прокси имя_хоста>" - -#: ../gtk/sip_account.ui.h:7 -msgid "Registration duration (sec):" -msgstr "Продолжительность регистрации (сек):" - -#: ../gtk/sip_account.ui.h:8 -msgid "Contact params (optional):" -msgstr "Параметры контакта (опционально):" - -#: ../gtk/sip_account.ui.h:9 -msgid "AVPF regular RTCP interval (sec):" -msgstr "AVPF постоянный интервал RTCP (сек):" - -#: ../gtk/sip_account.ui.h:10 -msgid "Route (optional):" -msgstr "Маршрут (опционально):" - -#: ../gtk/sip_account.ui.h:11 -msgid "Transport" -msgstr "Транспорт" - -#: ../gtk/sip_account.ui.h:12 -msgid "Register" -msgstr "Регистрация" - -#: ../gtk/sip_account.ui.h:13 -msgid "Publish presence information" -msgstr "Опубликовать статус присутствия" - -#: ../gtk/sip_account.ui.h:14 -msgid "Enable AVPF" -msgstr "Разрешить AVPF" - -#: ../gtk/sip_account.ui.h:15 -msgid "Configure a SIP account" -msgstr "Настроить учётную запись SIP" - -#: ../gtk/parameters.ui.h:1 -msgid "anonymous" -msgstr "аноним" - -#: ../gtk/parameters.ui.h:2 -msgid "GSSAPI" -msgstr "GSSAPI" - -#: ../gtk/parameters.ui.h:3 -msgid "SASL" -msgstr "SASL" - -#: ../gtk/parameters.ui.h:4 -msgid "default soundcard" -msgstr "звуковая карта по умолчанию" - -#: ../gtk/parameters.ui.h:5 -msgid "a sound card" -msgstr "звуковая карта" - -#: ../gtk/parameters.ui.h:6 -msgid "default camera" -msgstr "камера по умолчанию" - -#: ../gtk/parameters.ui.h:7 -msgid "CIF" -msgstr "CIF" - -#: ../gtk/parameters.ui.h:8 -msgid "Audio codecs" -msgstr "Аудио кодеки" - -#: ../gtk/parameters.ui.h:9 -msgid "Video codecs" -msgstr "Видео кодеки" - -#: ../gtk/parameters.ui.h:10 -msgid "C" -msgstr "C" - -#: ../gtk/parameters.ui.h:11 -msgid "SIP (UDP)" -msgstr "SIP (UDP)" - -#: ../gtk/parameters.ui.h:12 -msgid "SIP (TCP)" -msgstr "SIP (TCP)" - -#: ../gtk/parameters.ui.h:13 -msgid "SIP (TLS)" -msgstr "SIP (TLS)" - -#: ../gtk/parameters.ui.h:14 -msgid "Settings" -msgstr "Настройки" - -#: ../gtk/parameters.ui.h:15 -msgid "Set Maximum Transmission Unit:" -msgstr "Установить MTU (максимально передаваемый блок):" - -#: ../gtk/parameters.ui.h:16 -msgid "Send DTMFs as SIP info" -msgstr "Отправлять DTFM как SIP-информацию" - -#: ../gtk/parameters.ui.h:17 -msgid "Allow IPv6" -msgstr "Разрешить IPv6" - -#: ../gtk/parameters.ui.h:18 -msgid "Transport" -msgstr "Транспорт" - -#: ../gtk/parameters.ui.h:19 -msgid "SIP/UDP port" -msgstr "Порт SIP/UDP" - -#: ../gtk/parameters.ui.h:21 -msgid "Random" -msgstr "Случайно" - -#: ../gtk/parameters.ui.h:22 -msgid "SIP/TCP port" -msgstr "Порт SIP/TCP" - -#: ../gtk/parameters.ui.h:23 -msgid "Audio RTP/UDP:" -msgstr "Аудио RTP/UDP:" - -#: ../gtk/parameters.ui.h:24 -msgid "Fixed" -msgstr "Фиксированный" - -#: ../gtk/parameters.ui.h:25 -msgid "Video RTP/UDP:" -msgstr "Видео RTP/UDP:" - -#: ../gtk/parameters.ui.h:26 -msgid "Media encryption type" -msgstr "Тип медиа-шифрования" - -#: ../gtk/parameters.ui.h:27 -msgid "Media encryption is mandatory" -msgstr "Медиа-шифрование обязательно" - -#: ../gtk/parameters.ui.h:28 -msgid "Tunnel" -msgstr "Тунель" - -#: ../gtk/parameters.ui.h:29 -msgid "DSCP fields" -msgstr "Поля DSCP" - -#: ../gtk/parameters.ui.h:30 -msgid "Network protocol and ports" -msgstr "Сетевые протоколы и порты" - -#: ../gtk/parameters.ui.h:31 -msgid "Direct connection to the Internet" -msgstr "Прямое подключение к интернет" - -#: ../gtk/parameters.ui.h:32 -msgid "Behind NAT / Firewall (specify gateway IP )" -msgstr "За NAT / брандмауэром (указать IP шлюза)" - -#: ../gtk/parameters.ui.h:33 -msgid "Behind NAT / Firewall (use STUN to resolve)" -msgstr "За NAT / брандмауэром (использовать STUN)" - -#: ../gtk/parameters.ui.h:34 -msgid "Behind NAT / Firewall (use ICE)" -msgstr "За NAT / брандмауэром (использовать ICE)" - -#: ../gtk/parameters.ui.h:35 -msgid "Behind NAT / Firewall (use uPnP)" -msgstr "За NAT / брандмауэром (использовать uPnP)" - -#: ../gtk/parameters.ui.h:36 -msgid "Public IP address:" -msgstr "Выделенный (публичный) IP-адрес:" - -#: ../gtk/parameters.ui.h:37 -msgid "Stun server:" -msgstr "STUN сервер:" - -#: ../gtk/parameters.ui.h:38 -msgid "NAT and Firewall" -msgstr "NAT и брандмауэр" - -#: ../gtk/parameters.ui.h:39 -msgid "Network settings" -msgstr "Настройки сети" - -#: ../gtk/parameters.ui.h:40 -msgid "Ring sound:" -msgstr "Мелодия звонка:" - -#: ../gtk/parameters.ui.h:41 -msgid "ALSA special device (optional):" -msgstr "Специальное устройство ALSA (опционально)" - -#: ../gtk/parameters.ui.h:42 -msgid "Capture device:" -msgstr "Устройство захвата:" - -#: ../gtk/parameters.ui.h:43 -msgid "Ring device:" -msgstr "Устройство звонка:" - -#: ../gtk/parameters.ui.h:44 -msgid "Playback device:" -msgstr "Устройство воспроизведения:" - -#: ../gtk/parameters.ui.h:45 -msgid "Enable echo cancellation" -msgstr "Разрешить подавление эха" - -#: ../gtk/parameters.ui.h:46 -msgid "Audio" -msgstr "Аудио" - -#: ../gtk/parameters.ui.h:47 -msgid "Video input device:" -msgstr "Устройство для вывода видео:" - -#: ../gtk/parameters.ui.h:48 -msgid "Prefered video resolution:" -msgstr "Предпочтительное разрешение видео:" - -#: ../gtk/parameters.ui.h:49 -msgid "Video output method:" -msgstr "Метод вывода видео:" - -#: ../gtk/parameters.ui.h:50 -msgid "Show camera preview" -msgstr "Показать предпросмотр с камеры" - -#: ../gtk/parameters.ui.h:51 -msgid "Video" -msgstr "Видео" - -#: ../gtk/parameters.ui.h:52 -msgid "Multimedia settings" -msgstr "Настройки мультимедиа" - -#: ../gtk/parameters.ui.h:53 -msgid "This section defines your SIP address when not using a SIP account" -msgstr "Эта секция определяет ваш SIP адрес, когда вы не используете учётную запись SIP" - -#: ../gtk/parameters.ui.h:54 -msgid "Your display name (eg: John Doe):" -msgstr "Отображаемое имя (например: Иван Сидоров):" - -#: ../gtk/parameters.ui.h:55 -msgid "Your username:" -msgstr "Ваше имя пользователя:" - -#: ../gtk/parameters.ui.h:56 -msgid "Your resulting SIP address:" -msgstr "Ваш результирующий SIP адрес:" - -#: ../gtk/parameters.ui.h:57 -msgid "Default identity" -msgstr "Идентификатор по умолчанию" - -#: ../gtk/parameters.ui.h:58 -msgid "Wizard" -msgstr "Мастер" - -#: ../gtk/parameters.ui.h:59 -msgid "Add" -msgstr "Добавить" - -#: ../gtk/parameters.ui.h:60 -msgid "Edit" -msgstr "Редактировать" - -#: ../gtk/parameters.ui.h:61 -msgid "Remove" -msgstr "Удалить" - -#: ../gtk/parameters.ui.h:62 -msgid "Proxy accounts" -msgstr "Учётные записи" - -#: ../gtk/parameters.ui.h:63 -msgid "Erase all passwords" -msgstr "Стереть все пароли" - -#: ../gtk/parameters.ui.h:64 -msgid "Privacy" -msgstr "Секретность" - -#: ../gtk/parameters.ui.h:65 -msgid "Automatically answer when a call is received" -msgstr "Автоматический ответ при получении звонка" - -#: ../gtk/parameters.ui.h:66 -msgid "Delay before answering (ms)" -msgstr "Задержка перед ответом (мс)" - -#: ../gtk/parameters.ui.h:67 -msgid "Auto-answer" -msgstr "Автоответ" - -#: ../gtk/parameters.ui.h:68 -msgid "Manage SIP Accounts" -msgstr "Управление учётными записями SIP" - -#: ../gtk/parameters.ui.h:69 ../gtk/tunnel_config.ui.h:4 -msgid "Enable" -msgstr "Разрешить" - -#: ../gtk/parameters.ui.h:70 ../gtk/tunnel_config.ui.h:5 -msgid "Disable" -msgstr "Выключить" - -#: ../gtk/parameters.ui.h:71 -msgid "Codecs" -msgstr "Кодеки" - -#: ../gtk/parameters.ui.h:72 -msgid "0 stands for \"unlimited\"" -msgstr "0 означает \"безлимитный\"" - -#: ../gtk/parameters.ui.h:73 -msgid "Upload speed limit in Kbit/sec:" -msgstr "Ограничение исходящего потока КБит/сек:" - -#: ../gtk/parameters.ui.h:74 -msgid "Download speed limit in Kbit/sec:" -msgstr "Ограничение скорости входящего потока КБит/сек:" - -#: ../gtk/parameters.ui.h:75 -msgid "Enable adaptive rate control" -msgstr "Разрешить адаптивное управление скоростью" - -#: ../gtk/parameters.ui.h:76 -msgid "" -"Adaptive rate control is a technique to dynamically guess the available " -"bandwidth during a call." -msgstr "Адаптивное управление скоростью - это технология динамического угадывания доступной пропускной способности во время звонка." - -#: ../gtk/parameters.ui.h:77 -msgid "Bandwidth control" -msgstr "Пропускная способность" - -#: ../gtk/parameters.ui.h:78 -msgid "Codecs" -msgstr "Кодеки" - -#: ../gtk/parameters.ui.h:79 -msgid "Language" -msgstr "Язык" - -#: ../gtk/parameters.ui.h:80 -msgid "Show advanced settings" -msgstr "Показать дополнительные настройки" - -#: ../gtk/parameters.ui.h:81 -msgid "Level" -msgstr "Уровень" - -#: ../gtk/parameters.ui.h:82 -msgid "User interface" -msgstr "Пользовательский интерфейс" - -#: ../gtk/parameters.ui.h:83 ../gtk/ldap.ui.h:2 -msgid "Server address:" -msgstr "Адрес сервера:" - -#: ../gtk/parameters.ui.h:84 ../gtk/ldap.ui.h:3 -msgid "Authentication method:" -msgstr "Метод аутентификации:" - -#: ../gtk/parameters.ui.h:86 -msgid "LDAP Account setup" -msgstr "Установка учётной записи LDAP" - -#: ../gtk/parameters.ui.h:87 -msgid "LDAP" -msgstr "LDAP" - -#: ../gtk/parameters.ui.h:88 -msgid "Done" -msgstr "Готово" - #: ../gtk/buddylookup.ui.h:1 msgid "Search contacts in directory" msgstr "Поиск контактов в директории" @@ -1507,29 +802,21 @@ msgstr "Добавить в мой список" msgid "Search somebody" msgstr "Поиск кого-нибудь" -#: ../gtk/waiting.ui.h:2 -msgid "Please wait" -msgstr "Пожалуйста, подождите" +#: ../gtk/callee_frame.ui.h:1 +msgid "Callee name" +msgstr "Имя вызываемого" -#: ../gtk/dscp_settings.ui.h:1 -msgid "DSCP settings" -msgstr "Настройки DSCP" +#: ../gtk/call_logs.ui.h:1 +msgid "Call history" +msgstr "История звонков" -#: ../gtk/dscp_settings.ui.h:2 -msgid "SIP" -msgstr "SIP" +#: ../gtk/call_logs.ui.h:2 +msgid "Clear all" +msgstr "Очистить всё" -#: ../gtk/dscp_settings.ui.h:3 -msgid "Audio RTP stream" -msgstr "Аудио поток RTP" - -#: ../gtk/dscp_settings.ui.h:4 -msgid "Video RTP stream" -msgstr "Видео поток RTP" - -#: ../gtk/dscp_settings.ui.h:5 -msgid "Set DSCP values (in hexadecimal)" -msgstr "Установить значения DSCP (в шестнадцатеричном формате)" +#: ../gtk/call_logs.ui.h:3 +msgid "Call back" +msgstr "Позвонить повторно" #: ../gtk/call_statistics.ui.h:1 msgid "Call statistics" @@ -1579,30 +866,112 @@ msgstr "Профиль RTP" msgid "Call statistics and information" msgstr "Вызов статистики и информации" -#: ../gtk/tunnel_config.ui.h:1 -msgid "Configure VoIP tunnel" -msgstr "Настроить тунель VoIP" +#: ../gtk/chatroom_frame.ui.h:1 +msgid "Send" +msgstr "Отправить" -#: ../gtk/tunnel_config.ui.h:2 -msgid "Host" -msgstr "Хост" +#: ../gtk/conf_frame.ui.h:1 +msgid "End conference" +msgstr "Конец конференции" -#: ../gtk/tunnel_config.ui.h:3 -msgid "Port" -msgstr "Порт" +#: ../gtk/config-uri.ui.h:1 +msgid "Specifying a remote configuration URI" +msgstr "Указание удалённой конфигурации URI" -#: ../gtk/tunnel_config.ui.h:6 -msgid "Configure tunnel" -msgstr "Конфигурировать тунель" +#: ../gtk/config-uri.ui.h:2 +msgid "" +"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" +"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " +msgstr "Этот диалог позволяет установить HTTP или HTTPS адрес, когда конфигурация будет получена при запуске.\nПожалуйста, введите или измените настройки URI ниже. После нажатия OK linphone автоматически перезагрузится чтобы получить и учесть новую конфигурацию в учётной записи." -#: ../gtk/tunnel_config.ui.h:9 -msgid "Configure http proxy (optional)" -msgstr "Конфигурировать http прокси (опционально)" +#: ../gtk/contact.ui.h:2 +msgid "SIP Address" +msgstr "SIP адрес" + +#: ../gtk/contact.ui.h:3 +msgid "Show this contact presence status" +msgstr "Показывать этому контакту статус присутствия" + +#: ../gtk/contact.ui.h:4 +msgid "Allow this contact to see my presence status" +msgstr "Разрешить этому контакту видеть мой статус присутствия" + +#: ../gtk/contact.ui.h:5 +msgid "Contact information" +msgstr "Контактная информация" + +#: ../gtk/dscp_settings.ui.h:1 +msgid "DSCP settings" +msgstr "Настройки DSCP" + +#: ../gtk/dscp_settings.ui.h:2 +msgid "SIP" +msgstr "SIP" + +#: ../gtk/dscp_settings.ui.h:3 +msgid "Audio RTP stream" +msgstr "Аудио поток RTP" + +#: ../gtk/dscp_settings.ui.h:4 +msgid "Video RTP stream" +msgstr "Видео поток RTP" + +#: ../gtk/dscp_settings.ui.h:5 +msgid "Set DSCP values (in hexadecimal)" +msgstr "Установить значения DSCP (в шестнадцатеричном формате)" + +#: ../gtk/in_call_frame.ui.h:1 +msgid "Click here to set the speakers volume" +msgstr "Щёлкните здесь чтобы установить громкость динамиков" + +#: ../gtk/in_call_frame.ui.h:5 +msgid "Record this call to an audio file" +msgstr "Записать этот вызов в аудио файл" + +#: ../gtk/in_call_frame.ui.h:6 +msgid "Video" +msgstr "Видео" + +#: ../gtk/in_call_frame.ui.h:8 +msgid "Mute" +msgstr "Без звука" + +#: ../gtk/in_call_frame.ui.h:9 +msgid "Transfer" +msgstr "Передача" + +#: ../gtk/in_call_frame.ui.h:12 +msgid "In call" +msgstr "Входящий звонок" + +#: ../gtk/in_call_frame.ui.h:13 +msgid "Duration" +msgstr "Продолжительность" + +#: ../gtk/in_call_frame.ui.h:14 +msgid "Call quality rating" +msgstr "Вызвать рейтинг качества" #: ../gtk/ldap.ui.h:1 msgid "LDAP Settings" msgstr "Настройки LDAP" +#: ../gtk/ldap.ui.h:2 ../gtk/parameters.ui.h:89 +msgid "Server address:" +msgstr "Адрес сервера:" + +#: ../gtk/ldap.ui.h:3 ../gtk/parameters.ui.h:90 +msgid "Authentication method:" +msgstr "Метод аутентификации:" + +#: ../gtk/ldap.ui.h:4 ../gtk/parameters.ui.h:91 ../gtk/setup_wizard.ui.h:17 +msgid "Username:" +msgstr "Имя пользователя:" + +#: ../gtk/ldap.ui.h:5 ../gtk/password.ui.h:4 ../gtk/setup_wizard.ui.h:18 +msgid "Password:" +msgstr "Пароль:" + #: ../gtk/ldap.ui.h:6 msgid "Use TLS Connection" msgstr "Использовать соединение TLS" @@ -1688,15 +1057,503 @@ msgstr "ДАЙДЖЕСТ-MD5" msgid "NTLM" msgstr "NTLM" -#: ../gtk/config-uri.ui.h:1 -msgid "Specifying a remote configuration URI" -msgstr "Указание удалённой конфигурации URI" +#: ../gtk/login_frame.ui.h:1 ../gtk/tunnel_config.ui.h:7 +msgid "Username" +msgstr "Имя пользователя" -#: ../gtk/config-uri.ui.h:2 +#: ../gtk/login_frame.ui.h:2 ../gtk/tunnel_config.ui.h:8 +msgid "Password" +msgstr "Пароль" + +#: ../gtk/login_frame.ui.h:3 +msgid "Internet connection:" +msgstr "Интернет-соединение:" + +#: ../gtk/login_frame.ui.h:4 +msgid "Automatically log me in" +msgstr "Входить автоматически" + +#: ../gtk/login_frame.ui.h:5 ../gtk/password.ui.h:3 +msgid "UserID" +msgstr "Идентификатор пользователя" + +#: ../gtk/login_frame.ui.h:6 +msgid "Login information" +msgstr "Информация для входа" + +#: ../gtk/login_frame.ui.h:7 +msgid "Welcome!" +msgstr "Добро пожаловать!" + +#: ../gtk/login_frame.ui.h:8 +msgid "ADSL" +msgstr "ADSL" + +#: ../gtk/login_frame.ui.h:9 +msgid "Fiber Channel" +msgstr "Оптоволоконный канал" + +#: ../gtk/log.ui.h:1 +msgid "Linphone debug window" +msgstr "Окно отладки linphone" + +#: ../gtk/log.ui.h:2 +msgid "Scroll to end" +msgstr "Прокрутка в конец" + +#: ../gtk/main.ui.h:1 +msgid "Default" +msgstr "По умолчанию" + +#: ../gtk/main.ui.h:2 +msgid "Delete" +msgstr "Удалить" + +#: ../gtk/main.ui.h:3 +msgid "_Options" +msgstr "_Опции" + +#: ../gtk/main.ui.h:4 +msgid "Set configuration URI" +msgstr "Установить конфигурацию URI" + +#: ../gtk/main.ui.h:5 +msgid "Always start video" +msgstr "Всегда запускать видео" + +#: ../gtk/main.ui.h:6 +msgid "Enable self-view" +msgstr "Показать окно видео" + +#: ../gtk/main.ui.h:7 +msgid "Show keypad" +msgstr "Показать клавиатуру" + +#: ../gtk/main.ui.h:8 +msgid "_Help" +msgstr "_Помощь" + +#: ../gtk/main.ui.h:9 +msgid "Show debug window" +msgstr "Показать окно отладки" + +#: ../gtk/main.ui.h:10 +msgid "_Homepage" +msgstr "_Домашняя страница" + +#: ../gtk/main.ui.h:11 +msgid "Check _Updates" +msgstr "Проверить _обновления" + +#: ../gtk/main.ui.h:12 +msgid "Account assistant" +msgstr "Помощник учётной записи" + +#: ../gtk/main.ui.h:14 +msgid "SIP address or phone number:" +msgstr "SIP-адрес или номер телефона:" + +#: ../gtk/main.ui.h:15 +msgid "Initiate a new call" +msgstr "Начать новый звонок" + +#: ../gtk/main.ui.h:16 +msgid "Contacts" +msgstr "Контакты" + +#: ../gtk/main.ui.h:17 +msgid "Search" +msgstr "Поиск" + +#: ../gtk/main.ui.h:18 +msgid "Add contacts from directory" +msgstr "Добавить контакты из директории" + +#: ../gtk/main.ui.h:19 +msgid "Add contact" +msgstr "Добавить контакт" + +#: ../gtk/main.ui.h:20 +msgid "Clear call history" +msgstr "Очистить историю звонков" + +#: ../gtk/main.ui.h:22 +msgid "My current identity:" +msgstr "Мой текущий идентификатор:" + +#: ../gtk/main.ui.h:23 +msgid "Autoanswer is enabled" +msgstr "Автоответ включен" + +#: ../gtk/parameters.ui.h:1 +msgid "anonymous" +msgstr "аноним" + +#: ../gtk/parameters.ui.h:2 +msgid "GSSAPI" +msgstr "GSSAPI" + +#: ../gtk/parameters.ui.h:3 +msgid "SASL" +msgstr "SASL" + +#: ../gtk/parameters.ui.h:4 +msgid "default soundcard" +msgstr "звуковая карта по умолчанию" + +#: ../gtk/parameters.ui.h:5 +msgid "a sound card" +msgstr "звуковая карта" + +#: ../gtk/parameters.ui.h:6 +msgid "default camera" +msgstr "камера по умолчанию" + +#: ../gtk/parameters.ui.h:7 +msgid "CIF" +msgstr "CIF" + +#: ../gtk/parameters.ui.h:8 +msgid "Audio codecs" +msgstr "Аудио кодеки" + +#: ../gtk/parameters.ui.h:9 +msgid "Video codecs" +msgstr "Видео кодеки" + +#: ../gtk/parameters.ui.h:10 +msgid "C" +msgstr "C" + +#: ../gtk/parameters.ui.h:11 +msgid "SIP (UDP)" +msgstr "SIP (UDP)" + +#: ../gtk/parameters.ui.h:12 +msgid "SIP (TCP)" +msgstr "SIP (TCP)" + +#: ../gtk/parameters.ui.h:13 +msgid "SIP (TLS)" +msgstr "SIP (TLS)" + +#: ../gtk/parameters.ui.h:14 +msgid "default" +msgstr "По умолчанию" + +#: ../gtk/parameters.ui.h:15 +msgid "high-fps" +msgstr "много кадров в секунду" + +#: ../gtk/parameters.ui.h:16 +msgid "custom" +msgstr "Пользовательский" + +#: ../gtk/parameters.ui.h:17 +msgid "Settings" +msgstr "Настройки" + +#: ../gtk/parameters.ui.h:18 +msgid "This section defines your SIP address when not using a SIP account" +msgstr "Эта секция определяет ваш SIP адрес, когда вы не используете учётную запись SIP" + +#: ../gtk/parameters.ui.h:19 +msgid "Your display name (eg: John Doe):" +msgstr "Отображаемое имя (например: Иван Сидоров):" + +#: ../gtk/parameters.ui.h:20 +msgid "Your username:" +msgstr "Ваше имя пользователя:" + +#: ../gtk/parameters.ui.h:21 +msgid "Your resulting SIP address:" +msgstr "Ваш результирующий SIP адрес:" + +#: ../gtk/parameters.ui.h:22 +msgid "Default identity" +msgstr "Идентификатор по умолчанию" + +#: ../gtk/parameters.ui.h:23 +msgid "Wizard" +msgstr "Мастер" + +#: ../gtk/parameters.ui.h:24 +msgid "Add" +msgstr "Добавить" + +#: ../gtk/parameters.ui.h:25 +msgid "Edit" +msgstr "Редактировать" + +#: ../gtk/parameters.ui.h:26 +msgid "Remove" +msgstr "Удалить" + +#: ../gtk/parameters.ui.h:27 +msgid "Proxy accounts" +msgstr "Учётные записи" + +#: ../gtk/parameters.ui.h:28 +msgid "Erase all passwords" +msgstr "Стереть все пароли" + +#: ../gtk/parameters.ui.h:29 +msgid "Privacy" +msgstr "Секретность" + +#: ../gtk/parameters.ui.h:30 +msgid "Automatically answer when a call is received" +msgstr "Автоматический ответ при получении звонка" + +#: ../gtk/parameters.ui.h:31 +msgid "Delay before answering (ms)" +msgstr "Задержка перед ответом (мс)" + +#: ../gtk/parameters.ui.h:32 +msgid "Auto-answer" +msgstr "Автоответ" + +#: ../gtk/parameters.ui.h:33 +msgid "Manage SIP Accounts" +msgstr "Управление учётными записями SIP" + +#: ../gtk/parameters.ui.h:34 +msgid "Ring sound:" +msgstr "Мелодия звонка:" + +#: ../gtk/parameters.ui.h:35 +msgid "ALSA special device (optional):" +msgstr "Специальное устройство ALSA (опционально)" + +#: ../gtk/parameters.ui.h:36 +msgid "Capture device:" +msgstr "Устройство захвата:" + +#: ../gtk/parameters.ui.h:37 +msgid "Ring device:" +msgstr "Устройство звонка:" + +#: ../gtk/parameters.ui.h:38 +msgid "Playback device:" +msgstr "Устройство воспроизведения:" + +#: ../gtk/parameters.ui.h:39 +msgid "Enable echo cancellation" +msgstr "Разрешить подавление эха" + +#: ../gtk/parameters.ui.h:40 +msgid "Audio" +msgstr "Аудио" + +#: ../gtk/parameters.ui.h:41 +msgid "Video input device:" +msgstr "Устройство для вывода видео:" + +#: ../gtk/parameters.ui.h:42 +msgid "Preferred video resolution:" +msgstr "Предпочтительное разрешение видео:" + +#: ../gtk/parameters.ui.h:43 +msgid "Video output method:" +msgstr "Метод вывода видео:" + +#: ../gtk/parameters.ui.h:44 +msgid "Show camera preview" +msgstr "Показать предпросмотр с камеры" + +#: ../gtk/parameters.ui.h:45 +msgid "Video preset:" +msgstr "Предустановки видео:" + +#: ../gtk/parameters.ui.h:46 +msgid "Preferred video framerate:" +msgstr "Предпочтительная частота кадров:" + +#: ../gtk/parameters.ui.h:47 +msgid "0 stands for \"unlimited\"" +msgstr "0 означает \"безлимитный\"" + +#: ../gtk/parameters.ui.h:48 +msgid "Video" +msgstr "Видео" + +#: ../gtk/parameters.ui.h:49 +msgid "Upload speed limit in Kbit/sec:" +msgstr "Ограничение исходящего потока КБит/сек:" + +#: ../gtk/parameters.ui.h:50 +msgid "Download speed limit in Kbit/sec:" +msgstr "Ограничение скорости входящего потока КБит/сек:" + +#: ../gtk/parameters.ui.h:51 +msgid "Enable adaptive rate control" +msgstr "Разрешить адаптивное управление скоростью" + +#: ../gtk/parameters.ui.h:52 msgid "" -"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" -"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " -msgstr "Этот диалог позволяет установить HTTP или HTTPS адрес, когда конфигурация будет получена при запуске.\nПожалуйста, введите или измените настройки URI ниже. После нажатия OK linphone автоматически перезагрузится чтобы получить и учесть новую конфигурацию в учётной записи." +"Adaptive rate control is a technique to dynamically guess the available " +"bandwidth during a call." +msgstr "Адаптивное управление скоростью - это технология динамического угадывания доступной пропускной способности во время звонка." + +#: ../gtk/parameters.ui.h:53 +msgid "Bandwidth control" +msgstr "Пропускная способность" + +#: ../gtk/parameters.ui.h:54 +msgid "Multimedia settings" +msgstr "Настройки мультимедиа" + +#: ../gtk/parameters.ui.h:55 +msgid "Set Maximum Transmission Unit:" +msgstr "Установить MTU (максимально передаваемый блок):" + +#: ../gtk/parameters.ui.h:56 +msgid "Send DTMFs as SIP info" +msgstr "Отправлять DTFM как SIP-информацию" + +#: ../gtk/parameters.ui.h:57 +msgid "Allow IPv6" +msgstr "Разрешить IPv6" + +#: ../gtk/parameters.ui.h:58 +msgid "Transport" +msgstr "Транспорт" + +#: ../gtk/parameters.ui.h:59 +msgid "SIP/UDP port" +msgstr "Порт SIP/UDP" + +#: ../gtk/parameters.ui.h:61 +msgid "Random" +msgstr "Случайно" + +#: ../gtk/parameters.ui.h:62 +msgid "SIP/TCP port" +msgstr "Порт SIP/TCP" + +#: ../gtk/parameters.ui.h:63 +msgid "Audio RTP/UDP:" +msgstr "Аудио RTP/UDP:" + +#: ../gtk/parameters.ui.h:64 +msgid "Fixed" +msgstr "Фиксированный" + +#: ../gtk/parameters.ui.h:65 +msgid "Video RTP/UDP:" +msgstr "Видео RTP/UDP:" + +#: ../gtk/parameters.ui.h:66 +msgid "Media encryption type" +msgstr "Тип медиа-шифрования" + +#: ../gtk/parameters.ui.h:67 +msgid "Media encryption is mandatory" +msgstr "Медиа-шифрование обязательно" + +#: ../gtk/parameters.ui.h:68 +msgid "Tunnel" +msgstr "Тунель" + +#: ../gtk/parameters.ui.h:69 +msgid "DSCP fields" +msgstr "Поля DSCP" + +#: ../gtk/parameters.ui.h:70 +msgid "Network protocol and ports" +msgstr "Сетевые протоколы и порты" + +#: ../gtk/parameters.ui.h:71 +msgid "Direct connection to the Internet" +msgstr "Прямое подключение к интернет" + +#: ../gtk/parameters.ui.h:72 +msgid "Behind NAT / Firewall (specify gateway IP )" +msgstr "За NAT / брандмауэром (указать IP шлюза)" + +#: ../gtk/parameters.ui.h:73 +msgid "Behind NAT / Firewall (use STUN to resolve)" +msgstr "За NAT / брандмауэром (использовать STUN)" + +#: ../gtk/parameters.ui.h:74 +msgid "Behind NAT / Firewall (use ICE)" +msgstr "За NAT / брандмауэром (использовать ICE)" + +#: ../gtk/parameters.ui.h:75 +msgid "Behind NAT / Firewall (use uPnP)" +msgstr "За NAT / брандмауэром (использовать uPnP)" + +#: ../gtk/parameters.ui.h:76 +msgid "Public IP address:" +msgstr "Выделенный (публичный) IP-адрес:" + +#: ../gtk/parameters.ui.h:77 +msgid "Stun server:" +msgstr "STUN сервер:" + +#: ../gtk/parameters.ui.h:78 +msgid "NAT and Firewall" +msgstr "NAT и брандмауэр" + +#: ../gtk/parameters.ui.h:79 +msgid "Network settings" +msgstr "Настройки сети" + +#: ../gtk/parameters.ui.h:80 ../gtk/tunnel_config.ui.h:4 +msgid "Enable" +msgstr "Разрешить" + +#: ../gtk/parameters.ui.h:81 ../gtk/tunnel_config.ui.h:5 +msgid "Disable" +msgstr "Выключить" + +#: ../gtk/parameters.ui.h:82 +msgid "Audio codecs" +msgstr "Аудио кодеки" + +#: ../gtk/parameters.ui.h:83 +msgid "Video codecs" +msgstr "Видео кодеки" + +#: ../gtk/parameters.ui.h:84 +msgid "Codecs" +msgstr "Кодеки" + +#: ../gtk/parameters.ui.h:85 +msgid "Language" +msgstr "Язык" + +#: ../gtk/parameters.ui.h:86 +msgid "Show advanced settings" +msgstr "Показать дополнительные настройки" + +#: ../gtk/parameters.ui.h:87 +msgid "Level" +msgstr "Уровень" + +#: ../gtk/parameters.ui.h:88 +msgid "User interface" +msgstr "Пользовательский интерфейс" + +#: ../gtk/parameters.ui.h:92 +msgid "LDAP Account setup" +msgstr "Установка учётной записи LDAP" + +#: ../gtk/parameters.ui.h:93 +msgid "LDAP" +msgstr "LDAP" + +#: ../gtk/parameters.ui.h:94 +msgid "Done" +msgstr "Готово" + +#: ../gtk/password.ui.h:1 +msgid "Linphone - Authentication required" +msgstr "Linphone - необходима регистрация" + +#: ../gtk/password.ui.h:2 +msgid "Please enter the domain password" +msgstr "Введите пароль для домена" #: ../gtk/provisioning-fetch.ui.h:1 msgid "Configuring..." @@ -1706,68 +1563,278 @@ msgstr "Конфигурирование..." msgid "Please wait while fetching configuration from server..." msgstr "Пожалуйста, подождите пока получается конфигурация с сервера..." -#: ../coreapi/linphonecore.c:1539 +#: ../gtk/setup_wizard.ui.h:1 +msgid "SIP account configuration assistant" +msgstr "Помощник настройки учётной записи SIP" + +#: ../gtk/setup_wizard.ui.h:2 +msgid "" +"Welcome!\n" +"This assistant will help you to use a SIP account for your calls." +msgstr "Добро пожаловать!\nЭтот ассистент поможет вам использовать SIP аккаунт для ваших звонков." + +#: ../gtk/setup_wizard.ui.h:4 +msgid "Welcome to the account setup assistant" +msgstr "Добро пожаловать в помощник настройки учётной записи" + +#: ../gtk/setup_wizard.ui.h:5 +msgid "Create an account on linphone.org" +msgstr "Создать учётную запись на linphone.org" + +#: ../gtk/setup_wizard.ui.h:6 +msgid "I have already a linphone.org account and I just want to use it" +msgstr "Я уже имею учётную запись на linphone.org и только хочу использовать её" + +#: ../gtk/setup_wizard.ui.h:7 +msgid "I have already a sip account and I just want to use it" +msgstr "Я уже имею учётную запись sip и только хочу использовать её" + +#: ../gtk/setup_wizard.ui.h:8 +msgid "I want to specify a remote configuration URI" +msgstr "Я хочу указать удалённую конфигурацию URI" + +#: ../gtk/setup_wizard.ui.h:9 +msgid "Account setup assistant" +msgstr "Помощник настройки учётной записи" + +#: ../gtk/setup_wizard.ui.h:10 +msgid "Enter your account information" +msgstr "Введите вашу информацию об учётной записи" + +#: ../gtk/setup_wizard.ui.h:11 +msgid "Username*" +msgstr "Имя пользователя*" + +#: ../gtk/setup_wizard.ui.h:12 +msgid "Password*" +msgstr "Пароль*" + +#: ../gtk/setup_wizard.ui.h:13 +msgid "Domain*" +msgstr "Домен*" + +#: ../gtk/setup_wizard.ui.h:14 +msgid "Proxy" +msgstr "Прокси" + +#: ../gtk/setup_wizard.ui.h:15 +msgid "Configure your account (step 1/1)" +msgstr "Настроить вашу учётную запись (шаг 1/1)" + +#: ../gtk/setup_wizard.ui.h:16 +msgid "Enter your linphone.org username" +msgstr "Введите ваше имя пользователя для linphone.org" + +#: ../gtk/setup_wizard.ui.h:19 +msgid "Enter your sip username (step 1/1)" +msgstr "Введите ваше sip имя пользователя (шаг 1/1)" + +#: ../gtk/setup_wizard.ui.h:20 +msgid "(*) Required fields" +msgstr "(*) Обязательные поля" + +#: ../gtk/setup_wizard.ui.h:21 +msgid "Email: (*)" +msgstr "Электронная почта: (*)" + +#: ../gtk/setup_wizard.ui.h:22 +msgid "Username: (*)" +msgstr "Имя пользователя: (*)" + +#: ../gtk/setup_wizard.ui.h:23 +msgid "Password: (*)" +msgstr "Пароль: (*)" + +#: ../gtk/setup_wizard.ui.h:24 +msgid "Confirm your password: (*)" +msgstr "Подтвердите ваш пароль: (*)" + +#: ../gtk/setup_wizard.ui.h:25 +msgid "Keep me informed with linphone updates" +msgstr "Информировать об обновлениях linphone" + +#: ../gtk/setup_wizard.ui.h:26 +msgid "Enter account information (step 1/2)" +msgstr "Введите информацию об учётной записи (шаг 1/2)" + +#: ../gtk/setup_wizard.ui.h:27 +msgid "Your account is being created, please wait." +msgstr "Ваша учётная запись создаётся, пожалуйста, подождите." + +#: ../gtk/setup_wizard.ui.h:28 +msgid "Account creation in progress" +msgstr "Создание учётной записи в прогрессе" + +#: ../gtk/setup_wizard.ui.h:29 +msgid "" +"Please validate your account by clicking on the link we just sent you by email.\n" +"Then come back here and press Next button." +msgstr "Пожалуйста, подтвердите вашу учётную запись, щёлкнув на ссылку, которую вы только\nчто получили по электронной почте. Затем вернитесь сюда и нажмите кнопку Далее." + +#: ../gtk/setup_wizard.ui.h:31 +msgid "Validation (step 2/2)" +msgstr "Подтверждение (шаг 2/2)" + +#: ../gtk/setup_wizard.ui.h:32 +msgid "Checking if your account is been validated, please wait." +msgstr "Проверяется действительность вашей учётной записи, пожалуйста, подождите." + +#: ../gtk/setup_wizard.ui.h:33 +msgid "Account validation check in progress" +msgstr "Проверка действительности учётной записи в прогрессе" + +#: ../gtk/setup_wizard.ui.h:34 +msgid "" +"Error, account not validated, username already used or server unreachable.\n" +"Please go back and try again." +msgstr "Ошибка, учётная запись не подтверждена, имя пользователя уже используется или\nсервер недоступен. Пожалуйста, зайдите снова и попробуйте ещё раз." + +#: ../gtk/setup_wizard.ui.h:36 +msgid "Error" +msgstr "Ошибка" + +#: ../gtk/setup_wizard.ui.h:37 +msgid "Thank you. Your account is now configured and ready for use." +msgstr "Спасибо! Учётная запись успешно настроена и готова к использованию." + +#: ../gtk/sip_account.ui.h:1 +msgid "Linphone - Configure a SIP account" +msgstr "Linphone - настроить учётную запись SIP" + +#: ../gtk/sip_account.ui.h:2 +msgid "Your SIP identity:" +msgstr "Ваш идентификатор SIP:" + +#: ../gtk/sip_account.ui.h:3 +msgid "Looks like sip:@" +msgstr "Выглядит как sip:<имя_пользователя>@<домен>" + +#: ../gtk/sip_account.ui.h:4 +msgid "sip:" +msgstr "sip:" + +#: ../gtk/sip_account.ui.h:5 +msgid "SIP Proxy address:" +msgstr "Адрес SIP прокси:" + +#: ../gtk/sip_account.ui.h:6 +msgid "Looks like sip:" +msgstr "Выглядит как sip:<прокси имя_хоста>" + +#: ../gtk/sip_account.ui.h:7 +msgid "Registration duration (sec):" +msgstr "Продолжительность регистрации (сек):" + +#: ../gtk/sip_account.ui.h:8 +msgid "Contact params (optional):" +msgstr "Параметры контакта (опционально):" + +#: ../gtk/sip_account.ui.h:9 +msgid "AVPF regular RTCP interval (sec):" +msgstr "AVPF постоянный интервал RTCP (сек):" + +#: ../gtk/sip_account.ui.h:10 +msgid "Route (optional):" +msgstr "Маршрут (опционально):" + +#: ../gtk/sip_account.ui.h:11 +msgid "Transport" +msgstr "Транспорт" + +#: ../gtk/sip_account.ui.h:12 +msgid "Register" +msgstr "Регистрация" + +#: ../gtk/sip_account.ui.h:13 +msgid "Publish presence information" +msgstr "Опубликовать статус присутствия" + +#: ../gtk/sip_account.ui.h:14 +msgid "Enable AVPF" +msgstr "Разрешить AVPF" + +#: ../gtk/sip_account.ui.h:15 +msgid "Configure a SIP account" +msgstr "Настроить учётную запись SIP" + +#: ../gtk/tunnel_config.ui.h:1 +msgid "Configure VoIP tunnel" +msgstr "Настроить тунель VoIP" + +#: ../gtk/tunnel_config.ui.h:2 +msgid "Host" +msgstr "Хост" + +#: ../gtk/tunnel_config.ui.h:3 +msgid "Port" +msgstr "Порт" + +#: ../gtk/tunnel_config.ui.h:6 +msgid "Configure tunnel" +msgstr "Конфигурировать тунель" + +#: ../gtk/tunnel_config.ui.h:9 +msgid "Configure http proxy (optional)" +msgstr "Конфигурировать http прокси (опционально)" + +#: ../gtk/waiting.ui.h:2 +msgid "Please wait" +msgstr "Пожалуйста, подождите" + +#: ../coreapi/linphonecore.c:1560 msgid "Ready" msgstr "Готов" -#: ../coreapi/linphonecore.c:2551 +#: ../coreapi/linphonecore.c:2556 msgid "Configuring" msgstr "Конфигурирование" -#: ../coreapi/linphonecore.c:2725 -msgid "Looking for telephone number destination..." -msgstr "Поиск назначения для телефонного номера.." - -#: ../coreapi/linphonecore.c:2727 -msgid "Could not resolve this number." -msgstr "Не получилось принять решение по этому номеру." - #. must be known at that time -#: ../coreapi/linphonecore.c:3013 +#: ../coreapi/linphonecore.c:2951 msgid "Contacting" msgstr "Соединение" -#: ../coreapi/linphonecore.c:3018 +#: ../coreapi/linphonecore.c:2956 msgid "Could not call" msgstr "Невозможно позвонить" -#: ../coreapi/linphonecore.c:3169 +#: ../coreapi/linphonecore.c:3092 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "К сожалению, мы достигли максимального количества одновременных звонков" -#: ../coreapi/linphonecore.c:3327 +#: ../coreapi/linphonecore.c:3250 msgid "is contacting you" msgstr "контактирует с вами" -#: ../coreapi/linphonecore.c:3328 +#: ../coreapi/linphonecore.c:3251 msgid " and asked autoanswer." msgstr "и спросил автоматический ответ." -#: ../coreapi/linphonecore.c:3452 +#: ../coreapi/linphonecore.c:3377 msgid "Modifying call parameters..." msgstr "Изменение параметров звонка..." -#: ../coreapi/linphonecore.c:3802 +#: ../coreapi/linphonecore.c:3769 msgid "Connected." msgstr "Соединён." -#: ../coreapi/linphonecore.c:3827 +#: ../coreapi/linphonecore.c:3794 msgid "Call aborted" msgstr "Звонок отменён" -#: ../coreapi/linphonecore.c:4024 +#: ../coreapi/linphonecore.c:3983 msgid "Could not pause the call" msgstr "Невозможно приостановить звонок" -#: ../coreapi/linphonecore.c:4027 +#: ../coreapi/linphonecore.c:3986 msgid "Pausing the current call..." msgstr "Приостановка текущего звонка..." -#: ../coreapi/misc.c:434 +#: ../coreapi/misc.c:440 msgid "Stun lookup in progress..." msgstr "Идет поиск STUN..." -#: ../coreapi/misc.c:615 +#: ../coreapi/misc.c:650 msgid "ICE local candidates gathering in progress..." msgstr "Сбор локальных кандидатов ICE в прогрессе..." @@ -1823,167 +1890,175 @@ msgstr "Отдых" msgid "Unknown status" msgstr "Неизвестный статус" -#: ../coreapi/proxy.c:328 +#: ../coreapi/proxy.c:292 msgid "" "The sip proxy address you entered is invalid, it must start with \"sip:\" " "followed by a hostname." msgstr "Введённый SIP-адрес прокси является недействительным, он должен начинаться с \"sip:имя_хоста\"" -#: ../coreapi/proxy.c:334 +#: ../coreapi/proxy.c:298 msgid "" "The sip identity you entered is invalid.\n" "It should look like sip:username@proxydomain, such as sip:alice@example.net" msgstr "Неверные параметры для sip идентификации\nДолжно выглядеть как sip:имя_пользователя@домен_прокси, как например, sip:alice@example.net" -#: ../coreapi/proxy.c:1416 +#: ../coreapi/proxy.c:927 +msgid "Looking for telephone number destination..." +msgstr "Поиск назначения для телефонного номера.." + +#: ../coreapi/proxy.c:931 +msgid "Could not resolve this number." +msgstr "Не получилось принять решение по этому номеру." + +#: ../coreapi/proxy.c:1324 #, c-format msgid "Could not login as %s" msgstr "Невозможно зайти как: %s" -#: ../coreapi/callbacks.c:428 +#: ../coreapi/proxy.c:1411 +#, c-format +msgid "Refreshing on %s..." +msgstr "Обновление %s..." + +#: ../coreapi/callbacks.c:423 msgid "Remote ringing." msgstr "Дистанционный звонок." -#: ../coreapi/callbacks.c:440 +#: ../coreapi/callbacks.c:435 msgid "Remote ringing..." msgstr "Дистанционный звонок..." -#: ../coreapi/callbacks.c:461 +#: ../coreapi/callbacks.c:458 msgid "Early media." msgstr "Предответное проключение." -#: ../coreapi/callbacks.c:534 +#: ../coreapi/callbacks.c:488 #, c-format -msgid "Call with %s is paused." -msgstr "Звонок с %s приостановлен." +msgid "Call answered by %s" +msgstr "На звонок ответил %s" -#: ../coreapi/callbacks.c:547 -#, c-format -msgid "Call answered by %s - on hold." -msgstr "На звонок ответил %s - на удержании." - -#: ../coreapi/callbacks.c:557 +#: ../coreapi/callbacks.c:527 msgid "Call resumed." msgstr "Звонок возобновлён." -#: ../coreapi/callbacks.c:561 -#, c-format -msgid "Call answered by %s." -msgstr "На звонок ответил %s." - -#: ../coreapi/callbacks.c:584 +#: ../coreapi/callbacks.c:582 msgid "Incompatible, check codecs or security settings..." msgstr "Несовместимость, проверьте кодеки или параметры безопасности..." -#: ../coreapi/callbacks.c:589 ../coreapi/callbacks.c:906 +#: ../coreapi/callbacks.c:587 ../coreapi/callbacks.c:923 msgid "Incompatible media parameters." msgstr "Несовместимость медиа-параметров." -#: ../coreapi/callbacks.c:619 +#: ../coreapi/callbacks.c:612 msgid "We have been resumed." msgstr "Мы возобновили." #. we are being paused -#: ../coreapi/callbacks.c:628 +#: ../coreapi/callbacks.c:620 msgid "We are paused by other party." msgstr "Мы приостановлены другой стороной." -#. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:666 +#: ../coreapi/callbacks.c:630 msgid "Call is updated by remote." msgstr "Звонок был дистанционно обновлён." -#: ../coreapi/callbacks.c:782 +#: ../coreapi/callbacks.c:799 msgid "Call terminated." msgstr "Звонок прерван." -#: ../coreapi/callbacks.c:810 +#: ../coreapi/callbacks.c:827 msgid "User is busy." msgstr "Пользователь занят." -#: ../coreapi/callbacks.c:811 +#: ../coreapi/callbacks.c:828 msgid "User is temporarily unavailable." msgstr "Пользователь временно недоступен." #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:813 +#: ../coreapi/callbacks.c:830 msgid "User does not want to be disturbed." msgstr "Пользователь не хочет чтобы его беспокоили." -#: ../coreapi/callbacks.c:814 +#: ../coreapi/callbacks.c:831 msgid "Call declined." msgstr "Звонок отклонён." -#: ../coreapi/callbacks.c:829 +#: ../coreapi/callbacks.c:846 msgid "Request timeout." msgstr "Таймаут запроса." -#: ../coreapi/callbacks.c:860 +#: ../coreapi/callbacks.c:877 msgid "Redirected" msgstr "Переадресован" -#: ../coreapi/callbacks.c:915 +#: ../coreapi/callbacks.c:927 msgid "Call failed." msgstr "Звонок не удался." -#: ../coreapi/callbacks.c:993 +#: ../coreapi/callbacks.c:1005 #, c-format msgid "Registration on %s successful." msgstr "Регистрация на %s прошла успешно." -#: ../coreapi/callbacks.c:994 +#: ../coreapi/callbacks.c:1006 #, c-format msgid "Unregistration on %s done." msgstr "Отмена регистрации на %s завершена." -#: ../coreapi/callbacks.c:1012 +#: ../coreapi/callbacks.c:1024 msgid "no response timeout" msgstr "время ожидания истекло" -#: ../coreapi/callbacks.c:1015 +#: ../coreapi/callbacks.c:1027 #, c-format msgid "Registration on %s failed: %s" msgstr "Регистрация на %s не удалась: %s" -#: ../coreapi/callbacks.c:1022 +#: ../coreapi/callbacks.c:1034 msgid "Service unavailable, retrying" msgstr "Сервис недоступен, повтор" #. if encryption is DTLS, no status to be displayed -#: ../coreapi/linphonecall.c:180 +#: ../coreapi/linphonecall.c:197 #, c-format msgid "Authentication token is %s" msgstr "Маркер проверки подлинности: %s" -#: ../coreapi/linphonecall.c:1310 +#: ../coreapi/linphonecall.c:1561 +#, c-format +msgid "Call parameters could not be modified: %s." +msgstr "Параметры звонка не были изменены: %s." + +#: ../coreapi/linphonecall.c:1563 msgid "Call parameters were successfully modified." msgstr "Параметры звонка были успешно изменены." -#: ../coreapi/linphonecall.c:3686 +#: ../coreapi/linphonecall.c:4396 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." msgstr[0] "У вас %i пропущенный вызов." msgstr[1] "У вас %i пропущенных вызова." msgstr[2] "У вас %i пропущенных вызов." +msgstr[3] "У вас %i пропущенных вызов." -#: ../coreapi/call_log.c:209 +#: ../coreapi/call_log.c:223 msgid "aborted" msgstr "прервано" -#: ../coreapi/call_log.c:212 +#: ../coreapi/call_log.c:226 msgid "completed" msgstr "завершено" -#: ../coreapi/call_log.c:215 +#: ../coreapi/call_log.c:229 msgid "missed" msgstr "пропущено" -#: ../coreapi/call_log.c:218 +#: ../coreapi/call_log.c:232 msgid "unknown" msgstr "неизвестно" -#: ../coreapi/call_log.c:220 +#: ../coreapi/call_log.c:234 #, c-format msgid "" "%s at %s\n" @@ -1993,7 +2068,7 @@ msgid "" "Duration: %i mn %i sec\n" msgstr "%s в %s\nОт: %s\nДо: %s\nСтатус: %s\nПродолжительность: %i мин %i сек\n" -#: ../coreapi/call_log.c:221 +#: ../coreapi/call_log.c:235 msgid "Outgoing call" msgstr "Исходящий вызов" diff --git a/po/sr.po b/po/sr.po index 6adc05f37..b66280c91 100644 --- a/po/sr.po +++ b/po/sr.po @@ -8,48 +8,57 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-04-30 10:13+0200\n" -"PO-Revision-Date: 2015-04-30 08:13+0000\n" +"POT-Creation-Date: 2015-11-10 15:16+0100\n" +"PO-Revision-Date: 2015-11-10 14:16+0000\n" "Last-Translator: Belledonne Communications \n" -"Language-Team: Serbian (http://www.transifex.com/projects/p/linphone-gtk/language/sr/)\n" +"Language-Team: Serbian (http://www.transifex.com/belledonne-communications/linphone-gtk/language/sr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: sr\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: ../gtk/calllogs.c:148 ../gtk/friendlist.c:974 +#: ../gtk/calllogs.c:178 #, c-format msgid "Call %s" msgstr "Позови „%s“" -#: ../gtk/calllogs.c:149 ../gtk/friendlist.c:975 +#: ../gtk/calllogs.c:179 #, c-format msgid "Send text to %s" msgstr "Пошаљи текст за %s" -#: ../gtk/calllogs.c:232 +#: ../gtk/calllogs.c:181 +#, c-format +msgid "Add %s to your contact list" +msgstr "" + +#: ../gtk/calllogs.c:245 ../gtk/main.ui.h:21 +msgid "Recent calls" +msgstr "Скорашњи позиви" + +#: ../gtk/calllogs.c:260 #, c-format msgid "Recent calls (%i)" msgstr "Недавни позиви (%i)" -#: ../gtk/calllogs.c:314 +#: ../gtk/calllogs.c:331 msgid "n/a" msgstr "н/д" -#: ../gtk/calllogs.c:317 +#: ../gtk/calllogs.c:334 msgid "Aborted" msgstr "Прекинут" -#: ../gtk/calllogs.c:320 +#: ../gtk/calllogs.c:337 msgid "Missed" msgstr "Пропуштен" -#: ../gtk/calllogs.c:323 +#: ../gtk/calllogs.c:340 msgid "Declined" msgstr "Одбијен" -#: ../gtk/calllogs.c:329 +#: ../gtk/calllogs.c:346 #, c-format msgid "%i minute" msgid_plural "%i minutes" @@ -57,7 +66,7 @@ msgstr[0] "%i минут" msgstr[1] "%i минута" msgstr[2] "%i минута" -#: ../gtk/calllogs.c:332 +#: ../gtk/calllogs.c:349 #, c-format msgid "%i second" msgid_plural "%i seconds" @@ -65,19 +74,19 @@ msgstr[0] "%i секунда" msgstr[1] "%i секунде" msgstr[2] "%i секунди" -#: ../gtk/calllogs.c:337 +#: ../gtk/calllogs.c:354 #, c-format msgid "" "%s\tQuality: %s\n" "%s\t%s\t" msgstr "%s\tКвалитет: %s\n%s\t%s\t" -#: ../gtk/calllogs.c:341 +#: ../gtk/calllogs.c:358 #, c-format msgid "%s\t%s" msgstr "%s\t%s" -#: ../gtk/conference.c:38 ../gtk/main.ui.h:13 +#: ../gtk/conference.c:38 ../gtk/in_call_frame.ui.h:11 msgid "Conference" msgstr "Конференција" @@ -90,297 +99,314 @@ msgstr "Ја" msgid "Couldn't find pixmap file: %s" msgstr "Не могу да пронађем датотеку сличице: %s" -#: ../gtk/main.c:137 +#: ../gtk/chat.c:196 ../gtk/chat.c:254 +msgid "Sending..." +msgstr "" + +#: ../gtk/chat.c:213 ../gtk/chat.c:263 +msgid "Message not sent" +msgstr "" + +#: ../gtk/chat.c:472 +msgid "Copy" +msgstr "Умножи" + +#: ../gtk/main.c:138 msgid "log to stdout some debug information while running." msgstr "бележи на стандардни излаз неке податке прочишћавања док ради." -#: ../gtk/main.c:138 +#: ../gtk/main.c:139 +msgid "display version and exit." +msgstr "приказује издање и излази." + +#: ../gtk/main.c:140 msgid "path to a file to write logs into." msgstr "путања до датотеке за уписивање дневника." -#: ../gtk/main.c:139 +#: ../gtk/main.c:141 msgid "Start linphone with video disabled." msgstr "Покреће линфон са искљученим видеом." -#: ../gtk/main.c:140 +#: ../gtk/main.c:142 msgid "Start only in the system tray, do not show the main interface." msgstr "Покреће се само у системској фиоци, не приказује главно сучеље." -#: ../gtk/main.c:141 +#: ../gtk/main.c:143 msgid "address to call right now" msgstr "адреса за позивање управо сада" -#: ../gtk/main.c:142 +#: ../gtk/main.c:144 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:143 +#: ../gtk/main.c:145 msgid "Configuration file" msgstr "Датотека подешавања" -#: ../gtk/main.c:144 +#: ../gtk/main.c:146 msgid "Run the audio assistant" msgstr "Покреће помоћника звука" -#: ../gtk/main.c:145 +#: ../gtk/main.c:147 msgid "Run self test and exit 0 if succeed" msgstr "Покреће самоиспробавање и излази 0 ако је успешно" -#: ../gtk/main.c:1070 +#: ../gtk/main.c:1046 #, c-format msgid "" -"%s would like to add you to his contact list.\n" -"Would you allow him to see your presence status or add him to your contact list ?\n" +"%s would like to add you to his/her contact list.\n" +"Would you add him/her to your contact list and allow him/her to see your presence status?\n" "If you answer no, this person will be temporarily blacklisted." -msgstr "%s жели да вас дода на списак пријатеља.\nДа ли желите да му допустите да види ваше стање присуства или да га додате на ваш списак пријатеља ?\nАко одговорите са не, ова особа ће привремено бити стављена на списак забрана." +msgstr "%s жели да вас дода на свој списак контакта.\nДа ли желите да га/је додате на ваш списак контакта и да му/јој омогућите да види ваше стање присуства?\nАко одговорите негативно, ова особа ће тренутно бити стављена на списак забрањених." -#: ../gtk/main.c:1147 +#: ../gtk/main.c:1123 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" msgstr "Унесите вашу лозинку за корисничко име %s\n на подручју %s:" -#: ../gtk/main.c:1268 +#: ../gtk/main.c:1253 msgid "Call error" msgstr "Грешка позива" -#: ../gtk/main.c:1271 ../coreapi/linphonecore.c:3846 +#: ../gtk/main.c:1256 ../coreapi/linphonecore.c:3813 msgid "Call ended" msgstr "Позив је завршен" -#: ../gtk/main.c:1274 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1259 ../coreapi/call_log.c:235 msgid "Incoming call" msgstr "Долазни позив" -#: ../gtk/main.c:1276 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1261 ../gtk/incall_view.c:580 ../gtk/in_call_frame.ui.h:2 msgid "Answer" msgstr "Јави се" -#: ../gtk/main.c:1278 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1263 ../gtk/in_call_frame.ui.h:3 msgid "Decline" msgstr "Одбиј" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 msgid "Call paused" msgstr "Позив је заустављен" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 #, c-format msgid "by %s" msgstr "од %s" -#: ../gtk/main.c:1354 +#: ../gtk/main.c:1339 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "%s предлаже да започнете видео. Да ли прихватате ?" -#: ../gtk/main.c:1509 +#: ../gtk/main.c:1505 msgid "Website link" msgstr "Веза веб сајта" -#: ../gtk/main.c:1568 ../gtk/waiting.ui.h:1 +#: ../gtk/main.c:1564 ../gtk/waiting.ui.h:1 msgid "Linphone" msgstr "Линфон" -#: ../gtk/main.c:1569 +#: ../gtk/main.c:1565 msgid "A video internet phone" -msgstr "" +msgstr "Интернетски видео телефон" -#: ../gtk/main.c:1629 +#: ../gtk/main.c:1624 #, c-format msgid "%s (Default)" msgstr "%s (основно)" -#: ../gtk/main.c:1962 ../coreapi/callbacks.c:1063 +#: ../gtk/main.c:1960 ../coreapi/callbacks.c:1075 #, c-format msgid "We are transferred to %s" msgstr "Преселили смо се на %s" -#: ../gtk/main.c:1972 +#: ../gtk/main.c:1970 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." msgstr "Ниједна звучна картица није откривена на овом рачунару.\nНећете бити у могућности да шаљете или да примате звучне позиве." -#: ../gtk/main.c:2117 +#: ../gtk/main.c:2129 msgid "A free SIP video-phone" msgstr "Слободан СИП телефон са снимком" -#: ../gtk/main.c:2221 +#: ../gtk/main.c:2242 #, c-format msgid "Hello\n" -msgstr "" +msgstr "Здраво\n" -#: ../gtk/friendlist.c:505 +#: ../gtk/friendlist.c:461 msgid "Add to addressbook" msgstr "Додајте у адресар" -#: ../gtk/friendlist.c:691 -msgid "Presence status" -msgstr "Стање присуства" - -#: ../gtk/friendlist.c:709 ../gtk/propertybox.c:569 ../gtk/contact.ui.h:1 -msgid "Name" -msgstr "Име" - -#: ../gtk/friendlist.c:721 -msgid "Call" -msgstr "Позови" - -#: ../gtk/friendlist.c:726 -msgid "Chat" -msgstr "Ћаскај" - -#: ../gtk/friendlist.c:756 +#: ../gtk/friendlist.c:627 #, c-format msgid "Search in %s directory" msgstr "Тражи у директоријуму „%s“" -#: ../gtk/friendlist.c:924 +#: ../gtk/friendlist.c:772 msgid "Invalid sip contact !" msgstr "Неисправан сип контакт !" -#: ../gtk/friendlist.c:976 +#: ../gtk/friendlist.c:820 +#, c-format +msgid "Add a new contact" +msgstr "" + +#: ../gtk/friendlist.c:823 #, c-format msgid "Edit contact '%s'" msgstr "Уредите контакт „%s“" -#: ../gtk/friendlist.c:977 +#: ../gtk/friendlist.c:824 #, c-format msgid "Delete contact '%s'" msgstr "Обришите контакт „%s“" -#: ../gtk/friendlist.c:978 +#: ../gtk/friendlist.c:825 #, c-format msgid "Delete chat history of '%s'" msgstr "Обришите историјат ћаскања за „%s“" -#: ../gtk/friendlist.c:1029 +#: ../gtk/friendlist.c:862 #, c-format msgid "Add new contact from %s directory" msgstr "Додајте нови контакт из директоријума „%s“" -#: ../gtk/propertybox.c:575 +#: ../gtk/propertybox.c:592 ../gtk/contact.ui.h:1 +msgid "Name" +msgstr "Име" + +#: ../gtk/propertybox.c:598 msgid "Rate (Hz)" msgstr "Проток (Hz)" -#: ../gtk/propertybox.c:581 +#: ../gtk/propertybox.c:604 msgid "Status" msgstr "Стање" -#: ../gtk/propertybox.c:587 +#: ../gtk/propertybox.c:617 msgid "IP Bitrate (kbit/s)" msgstr "Проток бита ИП-а (kbit/s)" -#: ../gtk/propertybox.c:596 +#: ../gtk/propertybox.c:628 msgid "Parameters" msgstr "Параметри" -#: ../gtk/propertybox.c:639 ../gtk/propertybox.c:782 +#: ../gtk/propertybox.c:670 ../gtk/propertybox.c:824 msgid "Enabled" msgstr "Укључено" -#: ../gtk/propertybox.c:641 ../gtk/propertybox.c:782 ../gtk/parameters.ui.h:20 +#: ../gtk/propertybox.c:672 ../gtk/propertybox.c:824 ../gtk/parameters.ui.h:60 msgid "Disabled" msgstr "Искључено" -#: ../gtk/propertybox.c:828 +#: ../gtk/propertybox.c:902 msgid "Account" msgstr "Налог" -#: ../gtk/propertybox.c:1091 +#: ../gtk/propertybox.c:1170 msgid "English" msgstr "Енглески" -#: ../gtk/propertybox.c:1092 +#: ../gtk/propertybox.c:1171 msgid "French" msgstr "Француски" -#: ../gtk/propertybox.c:1093 +#: ../gtk/propertybox.c:1172 msgid "Swedish" msgstr "Шведски" -#: ../gtk/propertybox.c:1094 +#: ../gtk/propertybox.c:1173 msgid "Italian" msgstr "Италијански" -#: ../gtk/propertybox.c:1095 +#: ../gtk/propertybox.c:1174 msgid "Spanish" msgstr "Шпански" -#: ../gtk/propertybox.c:1096 +#: ../gtk/propertybox.c:1175 msgid "Brazilian Portugese" msgstr "Бразилски португалски" -#: ../gtk/propertybox.c:1097 +#: ../gtk/propertybox.c:1176 msgid "Polish" msgstr "Пољски" -#: ../gtk/propertybox.c:1098 +#: ../gtk/propertybox.c:1177 msgid "German" msgstr "Немачки" -#: ../gtk/propertybox.c:1099 +#: ../gtk/propertybox.c:1178 msgid "Russian" msgstr "Руски" -#: ../gtk/propertybox.c:1100 +#: ../gtk/propertybox.c:1179 msgid "Japanese" msgstr "Јапански" -#: ../gtk/propertybox.c:1101 +#: ../gtk/propertybox.c:1180 msgid "Dutch" msgstr "Холандски" -#: ../gtk/propertybox.c:1102 +#: ../gtk/propertybox.c:1181 msgid "Hungarian" msgstr "Мађарски" -#: ../gtk/propertybox.c:1103 +#: ../gtk/propertybox.c:1182 msgid "Czech" msgstr "Чешки" -#: ../gtk/propertybox.c:1104 +#: ../gtk/propertybox.c:1183 msgid "Chinese" msgstr "Кинески" -#: ../gtk/propertybox.c:1105 +#: ../gtk/propertybox.c:1184 msgid "Traditional Chinese" msgstr "Традиционални кинески" -#: ../gtk/propertybox.c:1106 +#: ../gtk/propertybox.c:1185 msgid "Norwegian" msgstr "Норвешки" -#: ../gtk/propertybox.c:1107 +#: ../gtk/propertybox.c:1186 msgid "Hebrew" msgstr "Јеврејски" -#: ../gtk/propertybox.c:1108 +#: ../gtk/propertybox.c:1187 msgid "Serbian" msgstr "Српски" -#: ../gtk/propertybox.c:1175 +#: ../gtk/propertybox.c:1188 +msgid "Arabic" +msgstr "Арапски" + +#: ../gtk/propertybox.c:1189 +msgid "Turkish" +msgstr "Турски" + +#: ../gtk/propertybox.c:1246 msgid "" "You need to restart linphone for the new language selection to take effect." msgstr "Треба поново да покренете линфон да би нови изабрани језик ступио у дејство." -#: ../gtk/propertybox.c:1255 +#: ../gtk/propertybox.c:1326 msgid "None" msgstr "Ништа" -#: ../gtk/propertybox.c:1259 +#: ../gtk/propertybox.c:1330 msgid "SRTP" msgstr "СРТП" -#: ../gtk/propertybox.c:1265 +#: ../gtk/propertybox.c:1336 msgid "DTLS" -msgstr "" +msgstr "ДТЛС" -#: ../gtk/propertybox.c:1272 +#: ../gtk/propertybox.c:1343 msgid "ZRTP" msgstr "ЗРТП" @@ -423,324 +449,195 @@ msgstr[0] "Нашао сам %i контакт" msgstr[1] "Нашао сам %i контакта" msgstr[2] "Нашао сам %i контаката" -#: ../gtk/setupwizard.c:32 -msgid "" -"Welcome!\n" -"This assistant will help you to use a SIP account for your calls." -msgstr "Добро дошли!\nОвај помоћник ће вам помоћи да користите СИП налог за ваше позиве." - -#: ../gtk/setupwizard.c:41 -msgid "Create an account on linphone.org" -msgstr "Направи налог на линфон.орг-у" - -#: ../gtk/setupwizard.c:42 -msgid "I have already a linphone.org account and I just want to use it" -msgstr "Већ имам налог линфон.орг-а и желим да га користим" - -#: ../gtk/setupwizard.c:43 -msgid "I have already a sip account and I just want to use it" -msgstr "Већ имам сип налог и желим да га користим" - -#: ../gtk/setupwizard.c:44 -msgid "I want to specify a remote configuration URI" -msgstr "Желим да наведем удаљену путању подешавања" - -#: ../gtk/setupwizard.c:87 -msgid "Enter your linphone.org username" -msgstr "Унесите ваше корисничко име линфон.орг-а" - -#: ../gtk/setupwizard.c:100 ../gtk/parameters.ui.h:85 ../gtk/ldap.ui.h:4 -msgid "Username:" -msgstr "Корисничко име:" - -#: ../gtk/setupwizard.c:102 ../gtk/password.ui.h:4 ../gtk/ldap.ui.h:5 -msgid "Password:" -msgstr "Лозинка:" - -#: ../gtk/setupwizard.c:122 -msgid "Enter your account informations" -msgstr "Унесите податке вашег налога" - -#: ../gtk/setupwizard.c:138 -msgid "Username*" -msgstr "Корисник*" - -#: ../gtk/setupwizard.c:139 -msgid "Password*" -msgstr "Лозинка*" - -#: ../gtk/setupwizard.c:142 -msgid "Domain*" -msgstr "Домен*" - -#: ../gtk/setupwizard.c:143 -msgid "Proxy" -msgstr "Посредник" - -#: ../gtk/setupwizard.c:322 -msgid "(*) Required fields" -msgstr "(*) Обавезна поља" - -#: ../gtk/setupwizard.c:323 -msgid "Username: (*)" -msgstr "Корисник: (*)" - -#: ../gtk/setupwizard.c:325 -msgid "Password: (*)" -msgstr "Лозинка: (*)" - -#: ../gtk/setupwizard.c:327 -msgid "Email: (*)" -msgstr "Ел. пошта: (*)" - -#: ../gtk/setupwizard.c:329 -msgid "Confirm your password: (*)" -msgstr "Потврдите вашу лозинку: (*)" - -#: ../gtk/setupwizard.c:343 -msgid "Keep me informed with linphone updates" -msgstr "Обавештавај ме о ажурирањима линфона" - -#: ../gtk/setupwizard.c:399 -msgid "" -"Error, account not validated, username already used or server unreachable.\n" -"Please go back and try again." -msgstr "Грешка, налог није потврђен, корисничко име је већ у употреби или је сервер недоступан.\nВратите се назад и покушајте опет." - -#: ../gtk/setupwizard.c:410 -msgid "Thank you. Your account is now configured and ready for use." -msgstr "Хвала вам. Ваш налог је сада подешен и спреман за употребу." - -#: ../gtk/setupwizard.c:418 -msgid "" -"Please validate your account by clicking on the link we just sent you by email.\n" -"Then come back here and press Next button." -msgstr "Потврдите ваш налог притиском на везу коју смо вам управо послали ел. поштом.\nЗатим се вратите овде и притисните дугме „Напред“." - -#: ../gtk/setupwizard.c:609 -msgid "SIP account configuration assistant" -msgstr "Помоћник подешавања СИП налога" - -#: ../gtk/setupwizard.c:629 -msgid "Welcome to the account setup assistant" -msgstr "Добро дошли у помоћника подешавања налога" - -#: ../gtk/setupwizard.c:634 -msgid "Account setup assistant" -msgstr "Помоћник подешавања налога" - -#: ../gtk/setupwizard.c:640 -msgid "Configure your account (step 1/1)" -msgstr "Подесите ваш налог (корак 1/1)" - -#: ../gtk/setupwizard.c:645 -msgid "Enter your sip username (step 1/1)" -msgstr "Унесите ваше корисничко име сип-а (корак 1/1)" - -#: ../gtk/setupwizard.c:649 -msgid "Enter account information (step 1/2)" -msgstr "Унесите податке налога (корак 1/2)" - -#: ../gtk/setupwizard.c:658 -msgid "Validation (step 2/2)" -msgstr "Потврђивање (корак 2/2)" - -#: ../gtk/setupwizard.c:663 -msgid "Error" -msgstr "Грешка" - -#: ../gtk/setupwizard.c:667 ../gtk/audio_assistant.c:534 -msgid "Terminating" -msgstr "Завршавам" - -#: ../gtk/incall_view.c:70 ../gtk/incall_view.c:94 +#: ../gtk/incall_view.c:67 ../gtk/incall_view.c:87 #, c-format msgid "Call #%i" msgstr "Позив бр. %i" -#: ../gtk/incall_view.c:155 +#: ../gtk/incall_view.c:145 #, c-format msgid "Transfer to call #%i with %s" msgstr "Пребаци позив #%i са %s" -#: ../gtk/incall_view.c:211 ../gtk/incall_view.c:214 +#: ../gtk/incall_view.c:202 ../gtk/incall_view.c:205 msgid "Not used" msgstr "Не користи се" -#: ../gtk/incall_view.c:221 +#: ../gtk/incall_view.c:212 msgid "ICE not activated" msgstr "ИЦЕ није покренут" -#: ../gtk/incall_view.c:223 +#: ../gtk/incall_view.c:214 msgid "ICE failed" msgstr "ИЦЕ није успео" -#: ../gtk/incall_view.c:225 +#: ../gtk/incall_view.c:216 msgid "ICE in progress" msgstr "ИЦЕ је у току" -#: ../gtk/incall_view.c:227 +#: ../gtk/incall_view.c:218 msgid "Going through one or more NATs" msgstr "Пролазим кроз један или више НАТ-са" -#: ../gtk/incall_view.c:229 +#: ../gtk/incall_view.c:220 msgid "Direct" msgstr "Непосредно" -#: ../gtk/incall_view.c:231 +#: ../gtk/incall_view.c:222 msgid "Through a relay server" msgstr "Преко преносног сервера" -#: ../gtk/incall_view.c:239 +#: ../gtk/incall_view.c:230 msgid "uPnP not activated" msgstr "уПнП није покренут" -#: ../gtk/incall_view.c:241 +#: ../gtk/incall_view.c:232 msgid "uPnP in progress" msgstr "уПнП је у току" -#: ../gtk/incall_view.c:243 +#: ../gtk/incall_view.c:234 msgid "uPnp not available" msgstr "уПнП није доступан" -#: ../gtk/incall_view.c:245 +#: ../gtk/incall_view.c:236 msgid "uPnP is running" msgstr "уПнП ради" -#: ../gtk/incall_view.c:247 +#: ../gtk/incall_view.c:238 msgid "uPnP failed" msgstr "уПнП није успео" -#: ../gtk/incall_view.c:257 ../gtk/incall_view.c:258 +#: ../gtk/incall_view.c:248 ../gtk/incall_view.c:249 msgid "Direct or through server" msgstr "Непосредно или кроз сервер" -#: ../gtk/incall_view.c:267 ../gtk/incall_view.c:279 +#: ../gtk/incall_view.c:258 ../gtk/incall_view.c:270 #, c-format msgid "" "download: %f\n" "upload: %f (kbit/s)" msgstr "преузимање: %f\nотпремање: %f (kbit/s)" -#: ../gtk/incall_view.c:272 ../gtk/incall_view.c:274 +#: ../gtk/incall_view.c:263 ../gtk/incall_view.c:265 #, c-format msgid "%ix%i @ %f fps" msgstr "%ix%i @ %f к/с" -#: ../gtk/incall_view.c:304 +#: ../gtk/incall_view.c:295 #, c-format msgid "%.3f seconds" msgstr "%.3f секунде" -#: ../gtk/incall_view.c:407 ../gtk/main.ui.h:12 ../gtk/videowindow.c:235 +#: ../gtk/incall_view.c:453 ../gtk/in_call_frame.ui.h:10 +#: ../gtk/videowindow.c:236 msgid "Hang up" msgstr "Прекини" -#: ../gtk/incall_view.c:511 +#: ../gtk/incall_view.c:559 msgid "Calling..." msgstr "Позивам..." -#: ../gtk/incall_view.c:514 ../gtk/incall_view.c:733 -msgid "00::00::00" -msgstr "00::00::00" +#: ../gtk/incall_view.c:562 ../gtk/incall_view.c:792 +msgid "00:00:00" +msgstr "00:00:00" -#: ../gtk/incall_view.c:525 +#: ../gtk/incall_view.c:573 msgid "Incoming call" msgstr "Долазни позив" -#: ../gtk/incall_view.c:562 +#: ../gtk/incall_view.c:610 msgid "good" msgstr "добро" -#: ../gtk/incall_view.c:564 +#: ../gtk/incall_view.c:612 msgid "average" msgstr "просечно" -#: ../gtk/incall_view.c:566 +#: ../gtk/incall_view.c:614 msgid "poor" msgstr "оскудно" -#: ../gtk/incall_view.c:568 +#: ../gtk/incall_view.c:616 msgid "very poor" msgstr "јадно" -#: ../gtk/incall_view.c:570 +#: ../gtk/incall_view.c:618 msgid "too bad" msgstr "много лоше" -#: ../gtk/incall_view.c:571 ../gtk/incall_view.c:587 +#: ../gtk/incall_view.c:619 ../gtk/incall_view.c:635 msgid "unavailable" msgstr "недоступно" -#: ../gtk/incall_view.c:679 +#: ../gtk/incall_view.c:731 msgid "Secured by SRTP" msgstr "Осигурано СРТП-ом" -#: ../gtk/incall_view.c:685 +#: ../gtk/incall_view.c:737 msgid "Secured by DTLS" -msgstr "" +msgstr "Осигурано ДТЛС-ом" -#: ../gtk/incall_view.c:691 +#: ../gtk/incall_view.c:743 #, c-format msgid "Secured by ZRTP - [auth token: %s]" msgstr "Осигурано ЗРТП-ом [потврђивање идентитета: %s]" -#: ../gtk/incall_view.c:697 +#: ../gtk/incall_view.c:747 msgid "Set unverified" msgstr "Непроверено подешавање" -#: ../gtk/incall_view.c:697 ../gtk/main.ui.h:4 +#: ../gtk/incall_view.c:747 msgid "Set verified" msgstr "Проверено подешавање" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In conference" msgstr "На конференцији" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In call" msgstr "У позиву" -#: ../gtk/incall_view.c:764 +#: ../gtk/incall_view.c:824 msgid "Paused call" msgstr "Заустављен позив" -#: ../gtk/incall_view.c:800 +#: ../gtk/incall_view.c:861 msgid "Call ended." msgstr "Позив је завршен." -#: ../gtk/incall_view.c:831 +#: ../gtk/incall_view.c:892 msgid "Transfer in progress" msgstr "Пренос је у току" -#: ../gtk/incall_view.c:834 +#: ../gtk/incall_view.c:895 msgid "Transfer done." msgstr "Пренос је обављен." -#: ../gtk/incall_view.c:837 +#: ../gtk/incall_view.c:898 msgid "Transfer failed." msgstr "Пренос није успео." -#: ../gtk/incall_view.c:881 +#: ../gtk/incall_view.c:929 msgid "Resume" msgstr "Настави" -#: ../gtk/incall_view.c:888 ../gtk/main.ui.h:9 +#: ../gtk/incall_view.c:929 ../gtk/in_call_frame.ui.h:7 msgid "Pause" msgstr "Застани" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 #, c-format msgid "" "Recording into\n" "%s %s" msgstr "Снимам у\n%s %s" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 msgid "(Paused)" msgstr "(Паузирано)" -#: ../gtk/loginframe.c:87 +#: ../gtk/loginframe.c:75 #, c-format msgid "Please enter login information for %s" msgstr "Унесите податке пријављивања за %s" @@ -755,263 +652,108 @@ msgstr "довлачим са „%s“" msgid "Downloading of remote configuration from %s failed." msgstr "Преузимање удаљеног подешавања са „%s“ није успело." -#: ../gtk/audio_assistant.c:98 +#: ../gtk/audio_assistant.c:103 msgid "No voice detected" msgstr "Глас није откривен" -#: ../gtk/audio_assistant.c:99 +#: ../gtk/audio_assistant.c:104 msgid "Too low" msgstr "Сувише низак" -#: ../gtk/audio_assistant.c:100 +#: ../gtk/audio_assistant.c:105 msgid "Good" msgstr "Добар" -#: ../gtk/audio_assistant.c:101 +#: ../gtk/audio_assistant.c:106 msgid "Too loud" msgstr "Сувише гласан" -#: ../gtk/audio_assistant.c:183 +#: ../gtk/audio_assistant.c:188 msgid "Did you hear three beeps ?" msgstr "Да ли сте чули три писка ?" -#: ../gtk/audio_assistant.c:292 ../gtk/audio_assistant.c:297 +#: ../gtk/audio_assistant.c:299 ../gtk/audio_assistant.c:304 msgid "Sound preferences not found " msgstr "Нисам пронашао поставке звука " -#: ../gtk/audio_assistant.c:306 +#: ../gtk/audio_assistant.c:313 msgid "Cannot launch system sound control " msgstr "Не могу да покренем управљање звуком система " -#: ../gtk/audio_assistant.c:318 +#: ../gtk/audio_assistant.c:325 msgid "" "Welcome!\n" "This assistant will help you to configure audio settings for Linphone" msgstr "Добро дошли!\nОвај помоћник ће вам помоћи да подесите поставке звука за Линфон" -#: ../gtk/audio_assistant.c:328 +#: ../gtk/audio_assistant.c:335 msgid "Capture device" msgstr "Уређај за снимање" -#: ../gtk/audio_assistant.c:329 +#: ../gtk/audio_assistant.c:336 msgid "Recorded volume" msgstr "Снимљени волумен" -#: ../gtk/audio_assistant.c:333 +#: ../gtk/audio_assistant.c:340 msgid "No voice" msgstr "Нема гласа" -#: ../gtk/audio_assistant.c:334 ../gtk/audio_assistant.c:373 +#: ../gtk/audio_assistant.c:341 ../gtk/audio_assistant.c:380 msgid "System sound preferences" msgstr "Поставке звука система" -#: ../gtk/audio_assistant.c:369 +#: ../gtk/audio_assistant.c:376 msgid "Playback device" msgstr "Уређај за пуштање" -#: ../gtk/audio_assistant.c:370 +#: ../gtk/audio_assistant.c:377 msgid "Play three beeps" msgstr "Пусти три писка" -#: ../gtk/audio_assistant.c:403 +#: ../gtk/audio_assistant.c:410 msgid "Press the record button and say some words" msgstr "Притисните дугме за снимање и реците нешто" -#: ../gtk/audio_assistant.c:404 +#: ../gtk/audio_assistant.c:411 msgid "Listen to your record voice" msgstr "Слушајте ваш снимљени глас" -#: ../gtk/audio_assistant.c:405 +#: ../gtk/audio_assistant.c:412 ../gtk/conf_frame.ui.h:2 +#: ../gtk/in_call_frame.ui.h:4 msgid "Record" msgstr "Сними" -#: ../gtk/audio_assistant.c:406 +#: ../gtk/audio_assistant.c:413 msgid "Play" msgstr "Пусти" -#: ../gtk/audio_assistant.c:433 +#: ../gtk/audio_assistant.c:440 msgid "Let's start Linphone now" msgstr "Хајде сада да покренемо Линфон" -#: ../gtk/audio_assistant.c:503 +#: ../gtk/audio_assistant.c:510 msgid "Audio Assistant" msgstr "Помоћник звука" -#: ../gtk/audio_assistant.c:513 ../gtk/main.ui.h:32 +#: ../gtk/audio_assistant.c:520 ../gtk/main.ui.h:13 msgid "Audio assistant" msgstr "Помоћник звука" -#: ../gtk/audio_assistant.c:518 +#: ../gtk/audio_assistant.c:525 msgid "Mic Gain calibration" msgstr "Дотеривање појачања микрофона" -#: ../gtk/audio_assistant.c:524 +#: ../gtk/audio_assistant.c:531 msgid "Speaker volume calibration" msgstr "Дотеривање јачине звука звучника" -#: ../gtk/audio_assistant.c:529 +#: ../gtk/audio_assistant.c:536 msgid "Record and Play" msgstr "Снимите и пустите" -#: ../gtk/main.ui.h:1 -msgid "Callee name" -msgstr "Име позивника" - -#: ../gtk/main.ui.h:2 -msgid "Send" -msgstr "Пошаљи" - -#: ../gtk/main.ui.h:3 -msgid "End conference" -msgstr "Заврши конференцију" - -#: ../gtk/main.ui.h:7 -msgid "Record this call to an audio file" -msgstr "Сними овај позив у звучну датотеку" - -#: ../gtk/main.ui.h:8 -msgid "Video" -msgstr "Видео" - -#: ../gtk/main.ui.h:10 -msgid "Mute" -msgstr "Утишај" - -#: ../gtk/main.ui.h:11 -msgid "Transfer" -msgstr "Пренос" - -#: ../gtk/main.ui.h:14 -msgid "In call" -msgstr "Долазни позив" - -#: ../gtk/main.ui.h:15 -msgid "Duration" -msgstr "Трајање" - -#: ../gtk/main.ui.h:16 -msgid "Call quality rating" -msgstr "Оцена квалитета позива" - -#: ../gtk/main.ui.h:17 -msgid "All users" -msgstr "Сви корисници" - -#: ../gtk/main.ui.h:18 -msgid "Online users" -msgstr "Корисници на мрежи" - -#: ../gtk/main.ui.h:19 -msgid "ADSL" -msgstr "АДСЛ" - -#: ../gtk/main.ui.h:20 -msgid "Fiber Channel" -msgstr "Оптички канал" - -#: ../gtk/main.ui.h:21 -msgid "Default" -msgstr "Основно" - -#: ../gtk/main.ui.h:22 -msgid "Delete" -msgstr "Обриши" - -#: ../gtk/main.ui.h:23 -msgid "_Options" -msgstr "_Могућности" - -#: ../gtk/main.ui.h:24 -msgid "Set configuration URI" -msgstr "Постави путању подешавања" - -#: ../gtk/main.ui.h:25 -msgid "Always start video" -msgstr "Увек покрени видео" - -#: ../gtk/main.ui.h:26 -msgid "Enable self-view" -msgstr "Укључи самовиђење" - -#: ../gtk/main.ui.h:27 -msgid "_Help" -msgstr "По_моћ" - -#: ../gtk/main.ui.h:28 -msgid "Show debug window" -msgstr "Прикажи прозорче прочишћавања" - -#: ../gtk/main.ui.h:29 -msgid "_Homepage" -msgstr "_Матична страница" - -#: ../gtk/main.ui.h:30 -msgid "Check _Updates" -msgstr "Провери _ажурирања" - -#: ../gtk/main.ui.h:31 -msgid "Account assistant" -msgstr "Помоћник налога" - -#: ../gtk/main.ui.h:33 -msgid "SIP address or phone number:" -msgstr "СИП адреса или број телефона:" - -#: ../gtk/main.ui.h:34 -msgid "Initiate a new call" -msgstr "Започните нови позив" - -#: ../gtk/main.ui.h:35 -msgid "Contacts" -msgstr "Пријатељи" - -#: ../gtk/main.ui.h:36 -msgid "Search" -msgstr "Тражи" - -#: ../gtk/main.ui.h:37 -msgid "Add contacts from directory" -msgstr "Додај пријатеље из директоријума" - -#: ../gtk/main.ui.h:38 -msgid "Add contact" -msgstr "Додај пријатеља" - -#: ../gtk/main.ui.h:39 -msgid "Recent calls" -msgstr "Скорашњи позиви" - -#: ../gtk/main.ui.h:40 -msgid "My current identity:" -msgstr "Мој тренутни идентитет:" - -#: ../gtk/main.ui.h:41 ../gtk/tunnel_config.ui.h:7 -msgid "Username" -msgstr "Корисник" - -#: ../gtk/main.ui.h:42 ../gtk/tunnel_config.ui.h:8 -msgid "Password" -msgstr "Лозинка" - -#: ../gtk/main.ui.h:43 -msgid "Internet connection:" -msgstr "Интернет веза:" - -#: ../gtk/main.ui.h:44 -msgid "Automatically log me in" -msgstr "Сам ме пријави" - -#: ../gtk/main.ui.h:45 ../gtk/password.ui.h:3 -msgid "UserID" -msgstr "ИБ корисника" - -#: ../gtk/main.ui.h:46 -msgid "Login information" -msgstr "Подаци пријављивања" - -#: ../gtk/main.ui.h:47 -msgid "Welcome!" -msgstr "Добро дошли!" +#: ../gtk/audio_assistant.c:541 ../gtk/setup_wizard.ui.h:38 +msgid "Terminating" +msgstr "Завршавам" #: ../gtk/about.ui.h:1 msgid "About Linphone" @@ -1041,456 +783,6 @@ msgid "" "he: Eli Zaretskii \n" msgstr "fr: Simon Morlat\nen: Simon Morlat and Delphine Perreau\nit: Alberto Zanoni \nde: Jean-Jacques Sarton \nsv: Daniel Nylander \nes: Jesus Benitez \nja: YAMAGUCHI YOSHIYA \npt_BR: Rafael Caesar Lenzi \npl: Robert Nasiadek \ncs: Petr Pisar \nhu: anonymous\nhe: Eli Zaretskii \nsr: Мирослав Николић \n" -#: ../gtk/contact.ui.h:2 -msgid "SIP Address" -msgstr "СИП адреса" - -#: ../gtk/contact.ui.h:3 -msgid "Show this contact presence status" -msgstr "Прикажи стање присуства овог пријатеља" - -#: ../gtk/contact.ui.h:4 -msgid "Allow this contact to see my presence status" -msgstr "Дозволи овом пријатељу да види стање мог присуства" - -#: ../gtk/contact.ui.h:5 -msgid "Contact information" -msgstr "Подаци о пријатељу" - -#: ../gtk/log.ui.h:1 -msgid "Linphone debug window" -msgstr "Линфоново прозорче прочишћавања" - -#: ../gtk/log.ui.h:2 -msgid "Scroll to end" -msgstr "Премакни на крај" - -#: ../gtk/password.ui.h:1 -msgid "Linphone - Authentication required" -msgstr "Линфон — Потребно је потврђивање идентитета" - -#: ../gtk/password.ui.h:2 -msgid "Please enter the domain password" -msgstr "Унесите лозинку домена" - -#: ../gtk/call_logs.ui.h:1 -msgid "Call history" -msgstr "Историјат позива" - -#: ../gtk/call_logs.ui.h:2 -msgid "Clear all" -msgstr "Очистите све" - -#: ../gtk/call_logs.ui.h:3 -msgid "Call back" -msgstr "Повратни позив" - -#: ../gtk/sip_account.ui.h:1 -msgid "Linphone - Configure a SIP account" -msgstr "Линфон — Подесите СИП налог" - -#: ../gtk/sip_account.ui.h:2 -msgid "Your SIP identity:" -msgstr "Ваш СИП идентитет:" - -#: ../gtk/sip_account.ui.h:3 -msgid "Looks like sip:@" -msgstr "Изгледа као „sip:<корисничко-име>@<домен>“" - -#: ../gtk/sip_account.ui.h:4 -msgid "sip:" -msgstr "сип:" - -#: ../gtk/sip_account.ui.h:5 -msgid "SIP Proxy address:" -msgstr "Адреса СИП посредника:" - -#: ../gtk/sip_account.ui.h:6 -msgid "Looks like sip:" -msgstr "Изгледа као „sip:<назив посредника>“" - -#: ../gtk/sip_account.ui.h:7 -msgid "Registration duration (sec):" -msgstr "Трајање уписа (сек):" - -#: ../gtk/sip_account.ui.h:8 -msgid "Contact params (optional):" -msgstr "Параметри пријатеља (изборно):" - -#: ../gtk/sip_account.ui.h:9 -msgid "AVPF regular RTCP interval (sec):" -msgstr "АВПФ редован РТЦП интервал (сек):" - -#: ../gtk/sip_account.ui.h:10 -msgid "Route (optional):" -msgstr "Рута (изборно):" - -#: ../gtk/sip_account.ui.h:11 -msgid "Transport" -msgstr "Пренос" - -#: ../gtk/sip_account.ui.h:12 -msgid "Register" -msgstr "Упиши се" - -#: ../gtk/sip_account.ui.h:13 -msgid "Publish presence information" -msgstr "Објави податке о присуству" - -#: ../gtk/sip_account.ui.h:14 -msgid "Enable AVPF" -msgstr "Укључи АВПФ" - -#: ../gtk/sip_account.ui.h:15 -msgid "Configure a SIP account" -msgstr "Подесите СИП налог" - -#: ../gtk/parameters.ui.h:1 -msgid "anonymous" -msgstr "безимено" - -#: ../gtk/parameters.ui.h:2 -msgid "GSSAPI" -msgstr "ГССАПИ" - -#: ../gtk/parameters.ui.h:3 -msgid "SASL" -msgstr "САСЛ" - -#: ../gtk/parameters.ui.h:4 -msgid "default soundcard" -msgstr "основна звучна картица" - -#: ../gtk/parameters.ui.h:5 -msgid "a sound card" -msgstr "звучна картица" - -#: ../gtk/parameters.ui.h:6 -msgid "default camera" -msgstr "основна камерица" - -#: ../gtk/parameters.ui.h:7 -msgid "CIF" -msgstr "ЦИФ" - -#: ../gtk/parameters.ui.h:8 -msgid "Audio codecs" -msgstr "Кодеци звука" - -#: ../gtk/parameters.ui.h:9 -msgid "Video codecs" -msgstr "Кодеци снимка" - -#: ../gtk/parameters.ui.h:10 -msgid "C" -msgstr "В" - -#: ../gtk/parameters.ui.h:11 -msgid "SIP (UDP)" -msgstr "СИП (УДП)" - -#: ../gtk/parameters.ui.h:12 -msgid "SIP (TCP)" -msgstr "СИП (ТЦП)" - -#: ../gtk/parameters.ui.h:13 -msgid "SIP (TLS)" -msgstr "СИП (ТЛС)" - -#: ../gtk/parameters.ui.h:14 -msgid "Settings" -msgstr "Подешавања" - -#: ../gtk/parameters.ui.h:15 -msgid "Set Maximum Transmission Unit:" -msgstr "Подеси јединицу највећег преноса:" - -#: ../gtk/parameters.ui.h:16 -msgid "Send DTMFs as SIP info" -msgstr "Пошаљи ДТМФ као СИП податке" - -#: ../gtk/parameters.ui.h:17 -msgid "Allow IPv6" -msgstr "" - -#: ../gtk/parameters.ui.h:18 -msgid "Transport" -msgstr "Пренос" - -#: ../gtk/parameters.ui.h:19 -msgid "SIP/UDP port" -msgstr "СИП/УДП прикључник" - -#: ../gtk/parameters.ui.h:21 -msgid "Random" -msgstr "Насумично" - -#: ../gtk/parameters.ui.h:22 -msgid "SIP/TCP port" -msgstr "СИП/ТЦП прикључник" - -#: ../gtk/parameters.ui.h:23 -msgid "Audio RTP/UDP:" -msgstr "РТП/УДП звука:" - -#: ../gtk/parameters.ui.h:24 -msgid "Fixed" -msgstr "Неизмењиво" - -#: ../gtk/parameters.ui.h:25 -msgid "Video RTP/UDP:" -msgstr "РТП/УДП снимка:" - -#: ../gtk/parameters.ui.h:26 -msgid "Media encryption type" -msgstr "Врста шифровања медија" - -#: ../gtk/parameters.ui.h:27 -msgid "Media encryption is mandatory" -msgstr "Шифровање медија је обавезно" - -#: ../gtk/parameters.ui.h:28 -msgid "Tunnel" -msgstr "Тунел" - -#: ../gtk/parameters.ui.h:29 -msgid "DSCP fields" -msgstr "ДСЦП поља" - -#: ../gtk/parameters.ui.h:30 -msgid "Network protocol and ports" -msgstr "Мрежни протокол и прикључници" - -#: ../gtk/parameters.ui.h:31 -msgid "Direct connection to the Internet" -msgstr "Непосредна веза на Интернет" - -#: ../gtk/parameters.ui.h:32 -msgid "Behind NAT / Firewall (specify gateway IP )" -msgstr "Иза НАТ-а / мрежне баријере (наведите ИП мрежног пролаза)" - -#: ../gtk/parameters.ui.h:33 -msgid "Behind NAT / Firewall (use STUN to resolve)" -msgstr "Иза НАТ-а / мрежне баријере (користите СТУН за решавање)" - -#: ../gtk/parameters.ui.h:34 -msgid "Behind NAT / Firewall (use ICE)" -msgstr "Иза НАТ-а / мрежне баријере (користите ИЦЕ)" - -#: ../gtk/parameters.ui.h:35 -msgid "Behind NAT / Firewall (use uPnP)" -msgstr "Иза НАТ-а / мрежне баријере (користите уПнП)" - -#: ../gtk/parameters.ui.h:36 -msgid "Public IP address:" -msgstr "Јавна ИП адреса:" - -#: ../gtk/parameters.ui.h:37 -msgid "Stun server:" -msgstr "Стун сервер:" - -#: ../gtk/parameters.ui.h:38 -msgid "NAT and Firewall" -msgstr "НАТ и мрежна баријера" - -#: ../gtk/parameters.ui.h:39 -msgid "Network settings" -msgstr "Мрежа" - -#: ../gtk/parameters.ui.h:40 -msgid "Ring sound:" -msgstr "Звук звона:" - -#: ../gtk/parameters.ui.h:41 -msgid "ALSA special device (optional):" -msgstr "АЛСА-ин посебни уређај (изборно):" - -#: ../gtk/parameters.ui.h:42 -msgid "Capture device:" -msgstr "Уређај за снимање:" - -#: ../gtk/parameters.ui.h:43 -msgid "Ring device:" -msgstr "Уређај за звоно:" - -#: ../gtk/parameters.ui.h:44 -msgid "Playback device:" -msgstr "Уређај за пуштање:" - -#: ../gtk/parameters.ui.h:45 -msgid "Enable echo cancellation" -msgstr "Укључи поништавање одјека" - -#: ../gtk/parameters.ui.h:46 -msgid "Audio" -msgstr "Звук" - -#: ../gtk/parameters.ui.h:47 -msgid "Video input device:" -msgstr "Улазни уређај снимка:" - -#: ../gtk/parameters.ui.h:48 -msgid "Prefered video resolution:" -msgstr "Жељена резолуција снимка:" - -#: ../gtk/parameters.ui.h:49 -msgid "Video output method:" -msgstr "Начин излаза снимка:" - -#: ../gtk/parameters.ui.h:50 -msgid "Show camera preview" -msgstr "Прикажи претпреглед камерице" - -#: ../gtk/parameters.ui.h:51 -msgid "Video" -msgstr "Снимак" - -#: ../gtk/parameters.ui.h:52 -msgid "Multimedia settings" -msgstr "Мултимедија" - -#: ../gtk/parameters.ui.h:53 -msgid "This section defines your SIP address when not using a SIP account" -msgstr "Овај одељак одређује вашу СИП адресу када не користите СИП налог" - -#: ../gtk/parameters.ui.h:54 -msgid "Your display name (eg: John Doe):" -msgstr "Ваше приказано име (нпр: Пера Перић):" - -#: ../gtk/parameters.ui.h:55 -msgid "Your username:" -msgstr "Ваше корисничко име:" - -#: ../gtk/parameters.ui.h:56 -msgid "Your resulting SIP address:" -msgstr "Ваша резултирајућа СИП адреса:" - -#: ../gtk/parameters.ui.h:57 -msgid "Default identity" -msgstr "Основни идентитет" - -#: ../gtk/parameters.ui.h:58 -msgid "Wizard" -msgstr "Чаробњак" - -#: ../gtk/parameters.ui.h:59 -msgid "Add" -msgstr "Додај" - -#: ../gtk/parameters.ui.h:60 -msgid "Edit" -msgstr "Уреди" - -#: ../gtk/parameters.ui.h:61 -msgid "Remove" -msgstr "Уклони" - -#: ../gtk/parameters.ui.h:62 -msgid "Proxy accounts" -msgstr "Посреднички налози" - -#: ../gtk/parameters.ui.h:63 -msgid "Erase all passwords" -msgstr "Обриши све лозинке" - -#: ../gtk/parameters.ui.h:64 -msgid "Privacy" -msgstr "Приватност" - -#: ../gtk/parameters.ui.h:65 -msgid "Automatically answer when a call is received" -msgstr "" - -#: ../gtk/parameters.ui.h:66 -msgid "Delay before answering (ms)" -msgstr "" - -#: ../gtk/parameters.ui.h:67 -msgid "Auto-answer" -msgstr "" - -#: ../gtk/parameters.ui.h:68 -msgid "Manage SIP Accounts" -msgstr "СИП налози" - -#: ../gtk/parameters.ui.h:69 ../gtk/tunnel_config.ui.h:4 -msgid "Enable" -msgstr "Укључи" - -#: ../gtk/parameters.ui.h:70 ../gtk/tunnel_config.ui.h:5 -msgid "Disable" -msgstr "Искључи" - -#: ../gtk/parameters.ui.h:71 -msgid "Codecs" -msgstr "Кодеци" - -#: ../gtk/parameters.ui.h:72 -msgid "0 stands for \"unlimited\"" -msgstr "0 значи „неограничено“" - -#: ../gtk/parameters.ui.h:73 -msgid "Upload speed limit in Kbit/sec:" -msgstr "Ограничи брзину слања на (Kb/s):" - -#: ../gtk/parameters.ui.h:74 -msgid "Download speed limit in Kbit/sec:" -msgstr "Ограничи брзину преузимања на (Kb/s):" - -#: ../gtk/parameters.ui.h:75 -msgid "Enable adaptive rate control" -msgstr "Укључи прилагодљиво управљање протоком" - -#: ../gtk/parameters.ui.h:76 -msgid "" -"Adaptive rate control is a technique to dynamically guess the available " -"bandwidth during a call." -msgstr "Прилагодљиво управљање протоком је техника за променљиво погађање доступног пропусног опсега за време позива." - -#: ../gtk/parameters.ui.h:77 -msgid "Bandwidth control" -msgstr "Управљање пропусним опсегом" - -#: ../gtk/parameters.ui.h:78 -msgid "Codecs" -msgstr "Kодеци" - -#: ../gtk/parameters.ui.h:79 -msgid "Language" -msgstr "Језик" - -#: ../gtk/parameters.ui.h:80 -msgid "Show advanced settings" -msgstr "Прикажи напредна подешавања" - -#: ../gtk/parameters.ui.h:81 -msgid "Level" -msgstr "Ниво" - -#: ../gtk/parameters.ui.h:82 -msgid "User interface" -msgstr "Корисничко сучеље" - -#: ../gtk/parameters.ui.h:83 ../gtk/ldap.ui.h:2 -msgid "Server address:" -msgstr "Адреса сервера:" - -#: ../gtk/parameters.ui.h:84 ../gtk/ldap.ui.h:3 -msgid "Authentication method:" -msgstr "Начин потврђивања идентитета:" - -#: ../gtk/parameters.ui.h:86 -msgid "LDAP Account setup" -msgstr "Подешавања ЛДАП налога" - -#: ../gtk/parameters.ui.h:87 -msgid "LDAP" -msgstr "ЛДАП" - -#: ../gtk/parameters.ui.h:88 -msgid "Done" -msgstr "Готово" - #: ../gtk/buddylookup.ui.h:1 msgid "Search contacts in directory" msgstr "Потражите пријатеље у директоријуму" @@ -1503,29 +795,21 @@ msgstr "Додај на мој списак" msgid "Search somebody" msgstr "Потражите неког" -#: ../gtk/waiting.ui.h:2 -msgid "Please wait" -msgstr "Сачекајте мало" +#: ../gtk/callee_frame.ui.h:1 +msgid "Callee name" +msgstr "Име позивника" -#: ../gtk/dscp_settings.ui.h:1 -msgid "DSCP settings" -msgstr "ДСЦП подешавања" +#: ../gtk/call_logs.ui.h:1 +msgid "Call history" +msgstr "Историјат позива" -#: ../gtk/dscp_settings.ui.h:2 -msgid "SIP" -msgstr "СИП" +#: ../gtk/call_logs.ui.h:2 +msgid "Clear all" +msgstr "Очистите све" -#: ../gtk/dscp_settings.ui.h:3 -msgid "Audio RTP stream" -msgstr "РТП ток звука" - -#: ../gtk/dscp_settings.ui.h:4 -msgid "Video RTP stream" -msgstr "РТП ток снимка" - -#: ../gtk/dscp_settings.ui.h:5 -msgid "Set DSCP values (in hexadecimal)" -msgstr "Подесите ДСЦП вредности (хексадецимално)" +#: ../gtk/call_logs.ui.h:3 +msgid "Call back" +msgstr "Повратни позив" #: ../gtk/call_statistics.ui.h:1 msgid "Call statistics" @@ -1575,30 +859,112 @@ msgstr "РТП профил" msgid "Call statistics and information" msgstr "Статистика позива и подаци" -#: ../gtk/tunnel_config.ui.h:1 -msgid "Configure VoIP tunnel" -msgstr "Подесите ВоИП тунел" +#: ../gtk/chatroom_frame.ui.h:1 +msgid "Send" +msgstr "Пошаљи" -#: ../gtk/tunnel_config.ui.h:2 -msgid "Host" -msgstr "Домаћин" +#: ../gtk/conf_frame.ui.h:1 +msgid "End conference" +msgstr "Заврши конференцију" -#: ../gtk/tunnel_config.ui.h:3 -msgid "Port" -msgstr "Прикључник" +#: ../gtk/config-uri.ui.h:1 +msgid "Specifying a remote configuration URI" +msgstr "Наводим удаљену путању подешавања" -#: ../gtk/tunnel_config.ui.h:6 -msgid "Configure tunnel" -msgstr "Подесите тунел" +#: ../gtk/config-uri.ui.h:2 +msgid "" +"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" +"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " +msgstr "Ово прозорче омогућава подешавање хттп или хттпс адресе када се подешавање добавља на покретању.\nУнесите или измените путању подешавања. Након што притиснете „У реду“, Линфон ће се сам поново покренути како би довукао и унео у налог нова подешавања. " -#: ../gtk/tunnel_config.ui.h:9 -msgid "Configure http proxy (optional)" -msgstr "Подесите хттп посредника (изборно)" +#: ../gtk/contact.ui.h:2 +msgid "SIP Address" +msgstr "СИП адреса" + +#: ../gtk/contact.ui.h:3 +msgid "Show this contact presence status" +msgstr "Прикажи стање присуства овог пријатеља" + +#: ../gtk/contact.ui.h:4 +msgid "Allow this contact to see my presence status" +msgstr "Дозволи овом пријатељу да види стање мог присуства" + +#: ../gtk/contact.ui.h:5 +msgid "Contact information" +msgstr "Подаци о пријатељу" + +#: ../gtk/dscp_settings.ui.h:1 +msgid "DSCP settings" +msgstr "ДСЦП подешавања" + +#: ../gtk/dscp_settings.ui.h:2 +msgid "SIP" +msgstr "СИП" + +#: ../gtk/dscp_settings.ui.h:3 +msgid "Audio RTP stream" +msgstr "РТП ток звука" + +#: ../gtk/dscp_settings.ui.h:4 +msgid "Video RTP stream" +msgstr "РТП ток снимка" + +#: ../gtk/dscp_settings.ui.h:5 +msgid "Set DSCP values (in hexadecimal)" +msgstr "Подесите ДСЦП вредности (хексадецимално)" + +#: ../gtk/in_call_frame.ui.h:1 +msgid "Click here to set the speakers volume" +msgstr "Притисните овде да подесите јачину звучника" + +#: ../gtk/in_call_frame.ui.h:5 +msgid "Record this call to an audio file" +msgstr "Сними овај позив у звучну датотеку" + +#: ../gtk/in_call_frame.ui.h:6 +msgid "Video" +msgstr "Видео" + +#: ../gtk/in_call_frame.ui.h:8 +msgid "Mute" +msgstr "Утишај" + +#: ../gtk/in_call_frame.ui.h:9 +msgid "Transfer" +msgstr "Пренос" + +#: ../gtk/in_call_frame.ui.h:12 +msgid "In call" +msgstr "Долазни позив" + +#: ../gtk/in_call_frame.ui.h:13 +msgid "Duration" +msgstr "Трајање" + +#: ../gtk/in_call_frame.ui.h:14 +msgid "Call quality rating" +msgstr "Оцена квалитета позива" #: ../gtk/ldap.ui.h:1 msgid "LDAP Settings" msgstr "ЛДАП подешавања" +#: ../gtk/ldap.ui.h:2 ../gtk/parameters.ui.h:89 +msgid "Server address:" +msgstr "Адреса сервера:" + +#: ../gtk/ldap.ui.h:3 ../gtk/parameters.ui.h:90 +msgid "Authentication method:" +msgstr "Начин потврђивања идентитета:" + +#: ../gtk/ldap.ui.h:4 ../gtk/parameters.ui.h:91 ../gtk/setup_wizard.ui.h:17 +msgid "Username:" +msgstr "Корисничко име:" + +#: ../gtk/ldap.ui.h:5 ../gtk/password.ui.h:4 ../gtk/setup_wizard.ui.h:18 +msgid "Password:" +msgstr "Лозинка:" + #: ../gtk/ldap.ui.h:6 msgid "Use TLS Connection" msgstr "Користи ТЛС везу" @@ -1684,15 +1050,503 @@ msgstr "ДИГЕСТ-МД5" msgid "NTLM" msgstr "НТЛМ" -#: ../gtk/config-uri.ui.h:1 -msgid "Specifying a remote configuration URI" -msgstr "Наводим удаљену путању подешавања" +#: ../gtk/login_frame.ui.h:1 ../gtk/tunnel_config.ui.h:7 +msgid "Username" +msgstr "Корисник" -#: ../gtk/config-uri.ui.h:2 +#: ../gtk/login_frame.ui.h:2 ../gtk/tunnel_config.ui.h:8 +msgid "Password" +msgstr "Лозинка" + +#: ../gtk/login_frame.ui.h:3 +msgid "Internet connection:" +msgstr "Интернет веза:" + +#: ../gtk/login_frame.ui.h:4 +msgid "Automatically log me in" +msgstr "Сам ме пријави" + +#: ../gtk/login_frame.ui.h:5 ../gtk/password.ui.h:3 +msgid "UserID" +msgstr "ИБ корисника" + +#: ../gtk/login_frame.ui.h:6 +msgid "Login information" +msgstr "Подаци пријављивања" + +#: ../gtk/login_frame.ui.h:7 +msgid "Welcome!" +msgstr "Добро дошли!" + +#: ../gtk/login_frame.ui.h:8 +msgid "ADSL" +msgstr "АДСЛ" + +#: ../gtk/login_frame.ui.h:9 +msgid "Fiber Channel" +msgstr "Оптички канал" + +#: ../gtk/log.ui.h:1 +msgid "Linphone debug window" +msgstr "Линфоново прозорче прочишћавања" + +#: ../gtk/log.ui.h:2 +msgid "Scroll to end" +msgstr "Премакни на крај" + +#: ../gtk/main.ui.h:1 +msgid "Default" +msgstr "Основно" + +#: ../gtk/main.ui.h:2 +msgid "Delete" +msgstr "Обриши" + +#: ../gtk/main.ui.h:3 +msgid "_Options" +msgstr "_Могућности" + +#: ../gtk/main.ui.h:4 +msgid "Set configuration URI" +msgstr "Постави путању подешавања" + +#: ../gtk/main.ui.h:5 +msgid "Always start video" +msgstr "Увек покрени видео" + +#: ../gtk/main.ui.h:6 +msgid "Enable self-view" +msgstr "Укључи самовиђење" + +#: ../gtk/main.ui.h:7 +msgid "Show keypad" +msgstr "" + +#: ../gtk/main.ui.h:8 +msgid "_Help" +msgstr "По_моћ" + +#: ../gtk/main.ui.h:9 +msgid "Show debug window" +msgstr "Прикажи прозорче прочишћавања" + +#: ../gtk/main.ui.h:10 +msgid "_Homepage" +msgstr "_Матична страница" + +#: ../gtk/main.ui.h:11 +msgid "Check _Updates" +msgstr "Провери _ажурирања" + +#: ../gtk/main.ui.h:12 +msgid "Account assistant" +msgstr "Помоћник налога" + +#: ../gtk/main.ui.h:14 +msgid "SIP address or phone number:" +msgstr "СИП адреса или број телефона:" + +#: ../gtk/main.ui.h:15 +msgid "Initiate a new call" +msgstr "Започните нови позив" + +#: ../gtk/main.ui.h:16 +msgid "Contacts" +msgstr "Пријатељи" + +#: ../gtk/main.ui.h:17 +msgid "Search" +msgstr "Тражи" + +#: ../gtk/main.ui.h:18 +msgid "Add contacts from directory" +msgstr "Додај пријатеље из директоријума" + +#: ../gtk/main.ui.h:19 +msgid "Add contact" +msgstr "Додај пријатеља" + +#: ../gtk/main.ui.h:20 +msgid "Clear call history" +msgstr "" + +#: ../gtk/main.ui.h:22 +msgid "My current identity:" +msgstr "Мој тренутни идентитет:" + +#: ../gtk/main.ui.h:23 +msgid "Autoanswer is enabled" +msgstr "" + +#: ../gtk/parameters.ui.h:1 +msgid "anonymous" +msgstr "безимено" + +#: ../gtk/parameters.ui.h:2 +msgid "GSSAPI" +msgstr "ГССАПИ" + +#: ../gtk/parameters.ui.h:3 +msgid "SASL" +msgstr "САСЛ" + +#: ../gtk/parameters.ui.h:4 +msgid "default soundcard" +msgstr "основна звучна картица" + +#: ../gtk/parameters.ui.h:5 +msgid "a sound card" +msgstr "звучна картица" + +#: ../gtk/parameters.ui.h:6 +msgid "default camera" +msgstr "основна камерица" + +#: ../gtk/parameters.ui.h:7 +msgid "CIF" +msgstr "ЦИФ" + +#: ../gtk/parameters.ui.h:8 +msgid "Audio codecs" +msgstr "Кодеци звука" + +#: ../gtk/parameters.ui.h:9 +msgid "Video codecs" +msgstr "Кодеци снимка" + +#: ../gtk/parameters.ui.h:10 +msgid "C" +msgstr "В" + +#: ../gtk/parameters.ui.h:11 +msgid "SIP (UDP)" +msgstr "СИП (УДП)" + +#: ../gtk/parameters.ui.h:12 +msgid "SIP (TCP)" +msgstr "СИП (ТЦП)" + +#: ../gtk/parameters.ui.h:13 +msgid "SIP (TLS)" +msgstr "СИП (ТЛС)" + +#: ../gtk/parameters.ui.h:14 +msgid "default" +msgstr "основно" + +#: ../gtk/parameters.ui.h:15 +msgid "high-fps" +msgstr "високи-проток" + +#: ../gtk/parameters.ui.h:16 +msgid "custom" +msgstr "произвољно" + +#: ../gtk/parameters.ui.h:17 +msgid "Settings" +msgstr "Подешавања" + +#: ../gtk/parameters.ui.h:18 +msgid "This section defines your SIP address when not using a SIP account" +msgstr "Овај одељак одређује вашу СИП адресу када не користите СИП налог" + +#: ../gtk/parameters.ui.h:19 +msgid "Your display name (eg: John Doe):" +msgstr "Ваше приказано име (нпр: Пера Перић):" + +#: ../gtk/parameters.ui.h:20 +msgid "Your username:" +msgstr "Ваше корисничко име:" + +#: ../gtk/parameters.ui.h:21 +msgid "Your resulting SIP address:" +msgstr "Ваша резултирајућа СИП адреса:" + +#: ../gtk/parameters.ui.h:22 +msgid "Default identity" +msgstr "Основни идентитет" + +#: ../gtk/parameters.ui.h:23 +msgid "Wizard" +msgstr "Чаробњак" + +#: ../gtk/parameters.ui.h:24 +msgid "Add" +msgstr "Додај" + +#: ../gtk/parameters.ui.h:25 +msgid "Edit" +msgstr "Уреди" + +#: ../gtk/parameters.ui.h:26 +msgid "Remove" +msgstr "Уклони" + +#: ../gtk/parameters.ui.h:27 +msgid "Proxy accounts" +msgstr "Посреднички налози" + +#: ../gtk/parameters.ui.h:28 +msgid "Erase all passwords" +msgstr "Обриши све лозинке" + +#: ../gtk/parameters.ui.h:29 +msgid "Privacy" +msgstr "Приватност" + +#: ../gtk/parameters.ui.h:30 +msgid "Automatically answer when a call is received" +msgstr "Сам одговори када се прими позив" + +#: ../gtk/parameters.ui.h:31 +msgid "Delay before answering (ms)" +msgstr "Сачекај пре него што одговориш (ms)" + +#: ../gtk/parameters.ui.h:32 +msgid "Auto-answer" +msgstr "Самостални-одговор" + +#: ../gtk/parameters.ui.h:33 +msgid "Manage SIP Accounts" +msgstr "СИП налози" + +#: ../gtk/parameters.ui.h:34 +msgid "Ring sound:" +msgstr "Звук звона:" + +#: ../gtk/parameters.ui.h:35 +msgid "ALSA special device (optional):" +msgstr "АЛСА-ин посебни уређај (изборно):" + +#: ../gtk/parameters.ui.h:36 +msgid "Capture device:" +msgstr "Уређај за снимање:" + +#: ../gtk/parameters.ui.h:37 +msgid "Ring device:" +msgstr "Уређај за звоно:" + +#: ../gtk/parameters.ui.h:38 +msgid "Playback device:" +msgstr "Уређај за пуштање:" + +#: ../gtk/parameters.ui.h:39 +msgid "Enable echo cancellation" +msgstr "Укључи поништавање одјека" + +#: ../gtk/parameters.ui.h:40 +msgid "Audio" +msgstr "Звук" + +#: ../gtk/parameters.ui.h:41 +msgid "Video input device:" +msgstr "Улазни уређај снимка:" + +#: ../gtk/parameters.ui.h:42 +msgid "Preferred video resolution:" +msgstr "Жељена резолуција снимка:" + +#: ../gtk/parameters.ui.h:43 +msgid "Video output method:" +msgstr "Начин излаза снимка:" + +#: ../gtk/parameters.ui.h:44 +msgid "Show camera preview" +msgstr "Прикажи претпреглед камерице" + +#: ../gtk/parameters.ui.h:45 +msgid "Video preset:" +msgstr "Претподешавање снимка:" + +#: ../gtk/parameters.ui.h:46 +msgid "Preferred video framerate:" +msgstr "Жељени проток кадрова снимка:" + +#: ../gtk/parameters.ui.h:47 +msgid "0 stands for \"unlimited\"" +msgstr "0 значи „неограничено“" + +#: ../gtk/parameters.ui.h:48 +msgid "Video" +msgstr "Снимак" + +#: ../gtk/parameters.ui.h:49 +msgid "Upload speed limit in Kbit/sec:" +msgstr "Ограничи брзину слања на (Kb/s):" + +#: ../gtk/parameters.ui.h:50 +msgid "Download speed limit in Kbit/sec:" +msgstr "Ограничи брзину преузимања на (Kb/s):" + +#: ../gtk/parameters.ui.h:51 +msgid "Enable adaptive rate control" +msgstr "Укључи прилагодљиво управљање протоком" + +#: ../gtk/parameters.ui.h:52 msgid "" -"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" -"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " -msgstr "Ово прозорче омогућава подешавање хттп или хттпс адресе када се подешавање добавља на покретању.\nУнесите или измените путању подешавања. Након што притиснете „У реду“, Линфон ће се сам поново покренути како би довукао и унео у налог нова подешавања. " +"Adaptive rate control is a technique to dynamically guess the available " +"bandwidth during a call." +msgstr "Прилагодљиво управљање протоком је техника за променљиво погађање доступног пропусног опсега за време позива." + +#: ../gtk/parameters.ui.h:53 +msgid "Bandwidth control" +msgstr "Управљање пропусним опсегом" + +#: ../gtk/parameters.ui.h:54 +msgid "Multimedia settings" +msgstr "Мултимедија" + +#: ../gtk/parameters.ui.h:55 +msgid "Set Maximum Transmission Unit:" +msgstr "Подеси јединицу највећег преноса:" + +#: ../gtk/parameters.ui.h:56 +msgid "Send DTMFs as SIP info" +msgstr "Пошаљи ДТМФ као СИП податке" + +#: ../gtk/parameters.ui.h:57 +msgid "Allow IPv6" +msgstr "Омогући ИПв6" + +#: ../gtk/parameters.ui.h:58 +msgid "Transport" +msgstr "Пренос" + +#: ../gtk/parameters.ui.h:59 +msgid "SIP/UDP port" +msgstr "СИП/УДП прикључник" + +#: ../gtk/parameters.ui.h:61 +msgid "Random" +msgstr "Насумично" + +#: ../gtk/parameters.ui.h:62 +msgid "SIP/TCP port" +msgstr "СИП/ТЦП прикључник" + +#: ../gtk/parameters.ui.h:63 +msgid "Audio RTP/UDP:" +msgstr "РТП/УДП звука:" + +#: ../gtk/parameters.ui.h:64 +msgid "Fixed" +msgstr "Неизмењиво" + +#: ../gtk/parameters.ui.h:65 +msgid "Video RTP/UDP:" +msgstr "РТП/УДП снимка:" + +#: ../gtk/parameters.ui.h:66 +msgid "Media encryption type" +msgstr "Врста шифровања медија" + +#: ../gtk/parameters.ui.h:67 +msgid "Media encryption is mandatory" +msgstr "Шифровање медија је обавезно" + +#: ../gtk/parameters.ui.h:68 +msgid "Tunnel" +msgstr "Тунел" + +#: ../gtk/parameters.ui.h:69 +msgid "DSCP fields" +msgstr "ДСЦП поља" + +#: ../gtk/parameters.ui.h:70 +msgid "Network protocol and ports" +msgstr "Мрежни протокол и прикључници" + +#: ../gtk/parameters.ui.h:71 +msgid "Direct connection to the Internet" +msgstr "Непосредна веза на Интернет" + +#: ../gtk/parameters.ui.h:72 +msgid "Behind NAT / Firewall (specify gateway IP )" +msgstr "Иза НАТ-а / мрежне баријере (наведите ИП мрежног пролаза)" + +#: ../gtk/parameters.ui.h:73 +msgid "Behind NAT / Firewall (use STUN to resolve)" +msgstr "Иза НАТ-а / мрежне баријере (користите СТУН за решавање)" + +#: ../gtk/parameters.ui.h:74 +msgid "Behind NAT / Firewall (use ICE)" +msgstr "Иза НАТ-а / мрежне баријере (користите ИЦЕ)" + +#: ../gtk/parameters.ui.h:75 +msgid "Behind NAT / Firewall (use uPnP)" +msgstr "Иза НАТ-а / мрежне баријере (користите уПнП)" + +#: ../gtk/parameters.ui.h:76 +msgid "Public IP address:" +msgstr "Јавна ИП адреса:" + +#: ../gtk/parameters.ui.h:77 +msgid "Stun server:" +msgstr "Стун сервер:" + +#: ../gtk/parameters.ui.h:78 +msgid "NAT and Firewall" +msgstr "НАТ и мрежна баријера" + +#: ../gtk/parameters.ui.h:79 +msgid "Network settings" +msgstr "Мрежа" + +#: ../gtk/parameters.ui.h:80 ../gtk/tunnel_config.ui.h:4 +msgid "Enable" +msgstr "Укључи" + +#: ../gtk/parameters.ui.h:81 ../gtk/tunnel_config.ui.h:5 +msgid "Disable" +msgstr "Искључи" + +#: ../gtk/parameters.ui.h:82 +msgid "Audio codecs" +msgstr "Кодеци звука" + +#: ../gtk/parameters.ui.h:83 +msgid "Video codecs" +msgstr "Кодеци снимка" + +#: ../gtk/parameters.ui.h:84 +msgid "Codecs" +msgstr "Kодеци" + +#: ../gtk/parameters.ui.h:85 +msgid "Language" +msgstr "Језик" + +#: ../gtk/parameters.ui.h:86 +msgid "Show advanced settings" +msgstr "Прикажи напредна подешавања" + +#: ../gtk/parameters.ui.h:87 +msgid "Level" +msgstr "Ниво" + +#: ../gtk/parameters.ui.h:88 +msgid "User interface" +msgstr "Корисничко сучеље" + +#: ../gtk/parameters.ui.h:92 +msgid "LDAP Account setup" +msgstr "Подешавања ЛДАП налога" + +#: ../gtk/parameters.ui.h:93 +msgid "LDAP" +msgstr "ЛДАП" + +#: ../gtk/parameters.ui.h:94 +msgid "Done" +msgstr "Готово" + +#: ../gtk/password.ui.h:1 +msgid "Linphone - Authentication required" +msgstr "Линфон — Потребно је потврђивање идентитета" + +#: ../gtk/password.ui.h:2 +msgid "Please enter the domain password" +msgstr "Унесите лозинку домена" #: ../gtk/provisioning-fetch.ui.h:1 msgid "Configuring..." @@ -1702,68 +1556,278 @@ msgstr "Подешавам..." msgid "Please wait while fetching configuration from server..." msgstr "Сачекајте док довучем подешавања са сервера..." -#: ../coreapi/linphonecore.c:1539 +#: ../gtk/setup_wizard.ui.h:1 +msgid "SIP account configuration assistant" +msgstr "Помоћник подешавања СИП налога" + +#: ../gtk/setup_wizard.ui.h:2 +msgid "" +"Welcome!\n" +"This assistant will help you to use a SIP account for your calls." +msgstr "Добро дошли!\nОвај помоћник ће вам помоћи да користите СИП налог за ваше позиве." + +#: ../gtk/setup_wizard.ui.h:4 +msgid "Welcome to the account setup assistant" +msgstr "Добро дошли у помоћника подешавања налога" + +#: ../gtk/setup_wizard.ui.h:5 +msgid "Create an account on linphone.org" +msgstr "Направи налог на линфон.орг-у" + +#: ../gtk/setup_wizard.ui.h:6 +msgid "I have already a linphone.org account and I just want to use it" +msgstr "Већ имам налог линфон.орг-а и желим да га користим" + +#: ../gtk/setup_wizard.ui.h:7 +msgid "I have already a sip account and I just want to use it" +msgstr "Већ имам сип налог и желим да га користим" + +#: ../gtk/setup_wizard.ui.h:8 +msgid "I want to specify a remote configuration URI" +msgstr "Желим да наведем удаљену путању подешавања" + +#: ../gtk/setup_wizard.ui.h:9 +msgid "Account setup assistant" +msgstr "Помоћник подешавања налога" + +#: ../gtk/setup_wizard.ui.h:10 +msgid "Enter your account information" +msgstr "Унесите податке вашег налога" + +#: ../gtk/setup_wizard.ui.h:11 +msgid "Username*" +msgstr "Корисник*" + +#: ../gtk/setup_wizard.ui.h:12 +msgid "Password*" +msgstr "Лозинка*" + +#: ../gtk/setup_wizard.ui.h:13 +msgid "Domain*" +msgstr "Домен*" + +#: ../gtk/setup_wizard.ui.h:14 +msgid "Proxy" +msgstr "Посредник" + +#: ../gtk/setup_wizard.ui.h:15 +msgid "Configure your account (step 1/1)" +msgstr "Подесите ваш налог (корак 1/1)" + +#: ../gtk/setup_wizard.ui.h:16 +msgid "Enter your linphone.org username" +msgstr "Унесите ваше корисничко име линфон.орг-а" + +#: ../gtk/setup_wizard.ui.h:19 +msgid "Enter your sip username (step 1/1)" +msgstr "Унесите ваше корисничко име сип-а (корак 1/1)" + +#: ../gtk/setup_wizard.ui.h:20 +msgid "(*) Required fields" +msgstr "(*) Обавезна поља" + +#: ../gtk/setup_wizard.ui.h:21 +msgid "Email: (*)" +msgstr "Ел. пошта: (*)" + +#: ../gtk/setup_wizard.ui.h:22 +msgid "Username: (*)" +msgstr "Корисник: (*)" + +#: ../gtk/setup_wizard.ui.h:23 +msgid "Password: (*)" +msgstr "Лозинка: (*)" + +#: ../gtk/setup_wizard.ui.h:24 +msgid "Confirm your password: (*)" +msgstr "Потврдите вашу лозинку: (*)" + +#: ../gtk/setup_wizard.ui.h:25 +msgid "Keep me informed with linphone updates" +msgstr "Обавештавај ме о ажурирањима линфона" + +#: ../gtk/setup_wizard.ui.h:26 +msgid "Enter account information (step 1/2)" +msgstr "Унесите податке налога (корак 1/2)" + +#: ../gtk/setup_wizard.ui.h:27 +msgid "Your account is being created, please wait." +msgstr "Ваш налог је направљен, сачекајте тренутак." + +#: ../gtk/setup_wizard.ui.h:28 +msgid "Account creation in progress" +msgstr "Прављење налога је у току" + +#: ../gtk/setup_wizard.ui.h:29 +msgid "" +"Please validate your account by clicking on the link we just sent you by email.\n" +"Then come back here and press Next button." +msgstr "Потврдите ваш налог притиском на везу коју смо вам управо послали ел. поштом.\nЗатим се вратите овде и притисните дугме „Напред“." + +#: ../gtk/setup_wizard.ui.h:31 +msgid "Validation (step 2/2)" +msgstr "Потврђивање (корак 2/2)" + +#: ../gtk/setup_wizard.ui.h:32 +msgid "Checking if your account is been validated, please wait." +msgstr "Проверавам да ли је ваш налог потврђен, сачекајте тренутак." + +#: ../gtk/setup_wizard.ui.h:33 +msgid "Account validation check in progress" +msgstr "Провера налога је у току" + +#: ../gtk/setup_wizard.ui.h:34 +msgid "" +"Error, account not validated, username already used or server unreachable.\n" +"Please go back and try again." +msgstr "Грешка, налог није потврђен, корисничко име је већ у употреби или је сервер недоступан.\nВратите се назад и покушајте опет." + +#: ../gtk/setup_wizard.ui.h:36 +msgid "Error" +msgstr "Грешка" + +#: ../gtk/setup_wizard.ui.h:37 +msgid "Thank you. Your account is now configured and ready for use." +msgstr "Хвала вам. Ваш налог је сада подешен и спреман за употребу." + +#: ../gtk/sip_account.ui.h:1 +msgid "Linphone - Configure a SIP account" +msgstr "Линфон — Подесите СИП налог" + +#: ../gtk/sip_account.ui.h:2 +msgid "Your SIP identity:" +msgstr "Ваш СИП идентитет:" + +#: ../gtk/sip_account.ui.h:3 +msgid "Looks like sip:@" +msgstr "Изгледа као „sip:<корисничко-име>@<домен>“" + +#: ../gtk/sip_account.ui.h:4 +msgid "sip:" +msgstr "сип:" + +#: ../gtk/sip_account.ui.h:5 +msgid "SIP Proxy address:" +msgstr "Адреса СИП посредника:" + +#: ../gtk/sip_account.ui.h:6 +msgid "Looks like sip:" +msgstr "Изгледа као „sip:<назив посредника>“" + +#: ../gtk/sip_account.ui.h:7 +msgid "Registration duration (sec):" +msgstr "Трајање уписа (сек):" + +#: ../gtk/sip_account.ui.h:8 +msgid "Contact params (optional):" +msgstr "Параметри пријатеља (изборно):" + +#: ../gtk/sip_account.ui.h:9 +msgid "AVPF regular RTCP interval (sec):" +msgstr "АВПФ редован РТЦП интервал (сек):" + +#: ../gtk/sip_account.ui.h:10 +msgid "Route (optional):" +msgstr "Рута (изборно):" + +#: ../gtk/sip_account.ui.h:11 +msgid "Transport" +msgstr "Пренос" + +#: ../gtk/sip_account.ui.h:12 +msgid "Register" +msgstr "Упиши се" + +#: ../gtk/sip_account.ui.h:13 +msgid "Publish presence information" +msgstr "Објави податке о присуству" + +#: ../gtk/sip_account.ui.h:14 +msgid "Enable AVPF" +msgstr "Укључи АВПФ" + +#: ../gtk/sip_account.ui.h:15 +msgid "Configure a SIP account" +msgstr "Подесите СИП налог" + +#: ../gtk/tunnel_config.ui.h:1 +msgid "Configure VoIP tunnel" +msgstr "Подесите ВоИП тунел" + +#: ../gtk/tunnel_config.ui.h:2 +msgid "Host" +msgstr "Домаћин" + +#: ../gtk/tunnel_config.ui.h:3 +msgid "Port" +msgstr "Прикључник" + +#: ../gtk/tunnel_config.ui.h:6 +msgid "Configure tunnel" +msgstr "Подесите тунел" + +#: ../gtk/tunnel_config.ui.h:9 +msgid "Configure http proxy (optional)" +msgstr "Подесите хттп посредника (изборно)" + +#: ../gtk/waiting.ui.h:2 +msgid "Please wait" +msgstr "Сачекајте мало" + +#: ../coreapi/linphonecore.c:1560 msgid "Ready" msgstr "Спреман" -#: ../coreapi/linphonecore.c:2551 +#: ../coreapi/linphonecore.c:2556 msgid "Configuring" msgstr "Подешавам" -#: ../coreapi/linphonecore.c:2725 -msgid "Looking for telephone number destination..." -msgstr "Тражим одредиште телефонског броја..." - -#: ../coreapi/linphonecore.c:2727 -msgid "Could not resolve this number." -msgstr "Не могу да решим овај број." - #. must be known at that time -#: ../coreapi/linphonecore.c:3013 +#: ../coreapi/linphonecore.c:2951 msgid "Contacting" msgstr "Ступам у везу" -#: ../coreapi/linphonecore.c:3018 +#: ../coreapi/linphonecore.c:2956 msgid "Could not call" msgstr "Не могу да позовем" -#: ../coreapi/linphonecore.c:3169 +#: ../coreapi/linphonecore.c:3092 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "Извините, достигли смо највећи број истовремених позива" -#: ../coreapi/linphonecore.c:3327 +#: ../coreapi/linphonecore.c:3250 msgid "is contacting you" msgstr "вам се обраћа" -#: ../coreapi/linphonecore.c:3328 +#: ../coreapi/linphonecore.c:3251 msgid " and asked autoanswer." msgstr " и затражени само-одговор." -#: ../coreapi/linphonecore.c:3452 +#: ../coreapi/linphonecore.c:3377 msgid "Modifying call parameters..." msgstr "Мењам параметре позива..." -#: ../coreapi/linphonecore.c:3802 +#: ../coreapi/linphonecore.c:3769 msgid "Connected." msgstr "Повезан сам." -#: ../coreapi/linphonecore.c:3827 +#: ../coreapi/linphonecore.c:3794 msgid "Call aborted" msgstr "Позив је прекинут" -#: ../coreapi/linphonecore.c:4024 +#: ../coreapi/linphonecore.c:3983 msgid "Could not pause the call" msgstr "Не могу да зауставим позив" -#: ../coreapi/linphonecore.c:4027 +#: ../coreapi/linphonecore.c:3986 msgid "Pausing the current call..." msgstr "Заустављам тренутни позив..." -#: ../coreapi/misc.c:434 +#: ../coreapi/misc.c:440 msgid "Stun lookup in progress..." msgstr "У току је тражење стуна..." -#: ../coreapi/misc.c:615 +#: ../coreapi/misc.c:650 msgid "ICE local candidates gathering in progress..." msgstr "Прикупљање месних ИЦЕ кандидата је у току..." @@ -1819,143 +1883,150 @@ msgstr "На одмору" msgid "Unknown status" msgstr "Непознато стање" -#: ../coreapi/proxy.c:328 +#: ../coreapi/proxy.c:292 msgid "" "The sip proxy address you entered is invalid, it must start with \"sip:\" " "followed by a hostname." msgstr "Адреса сип посредника коју сте унели је неисправна, мора почети на „sip:“ за којим следи назив домаћина." -#: ../coreapi/proxy.c:334 +#: ../coreapi/proxy.c:298 msgid "" "The sip identity you entered is invalid.\n" "It should look like sip:username@proxydomain, such as sip:alice@example.net" -msgstr "Сип идентитет који сте унели није исправан.\nТреба да изгледа као „sip:корисник@домен-посредника, као што је „sip:alice@example.net“" +msgstr "Сип идентитет који сте унели није исправан.\nТреба да буде у облику „sip:корисник@домен-посредника“, као што је „sip:alice@example.net“" -#: ../coreapi/proxy.c:1416 +#: ../coreapi/proxy.c:927 +msgid "Looking for telephone number destination..." +msgstr "Тражим одредиште телефонског броја..." + +#: ../coreapi/proxy.c:931 +msgid "Could not resolve this number." +msgstr "Не могу да решим овај број." + +#: ../coreapi/proxy.c:1324 #, c-format msgid "Could not login as %s" msgstr "Не могу да се пријавим као %s" -#: ../coreapi/callbacks.c:428 +#: ../coreapi/proxy.c:1411 +#, c-format +msgid "Refreshing on %s..." +msgstr "Освежавам на %s..." + +#: ../coreapi/callbacks.c:423 msgid "Remote ringing." msgstr "Удаљено звоњење." -#: ../coreapi/callbacks.c:440 +#: ../coreapi/callbacks.c:435 msgid "Remote ringing..." msgstr "Удаљено звоњење..." -#: ../coreapi/callbacks.c:461 +#: ../coreapi/callbacks.c:458 msgid "Early media." msgstr "Ранији медиј." -#: ../coreapi/callbacks.c:534 +#: ../coreapi/callbacks.c:488 #, c-format -msgid "Call with %s is paused." -msgstr "Позив са „%s“ је заустављен." +msgid "Call answered by %s" +msgstr "На позив је одговорио/ла %s" -#: ../coreapi/callbacks.c:547 -#, c-format -msgid "Call answered by %s - on hold." -msgstr "Позив на који је одговорио „%s“ — на чекању." - -#: ../coreapi/callbacks.c:557 +#: ../coreapi/callbacks.c:527 msgid "Call resumed." msgstr "Позив је настављен." -#: ../coreapi/callbacks.c:561 -#, c-format -msgid "Call answered by %s." -msgstr "На позив је одговорио „%s“." - -#: ../coreapi/callbacks.c:584 +#: ../coreapi/callbacks.c:582 msgid "Incompatible, check codecs or security settings..." msgstr "Несагласно, проверите кодеке или безбедносна подешавања..." -#: ../coreapi/callbacks.c:589 ../coreapi/callbacks.c:906 +#: ../coreapi/callbacks.c:587 ../coreapi/callbacks.c:923 msgid "Incompatible media parameters." msgstr "Медијски параметри су несагласни." -#: ../coreapi/callbacks.c:619 +#: ../coreapi/callbacks.c:612 msgid "We have been resumed." msgstr "Наставили смо." #. we are being paused -#: ../coreapi/callbacks.c:628 +#: ../coreapi/callbacks.c:620 msgid "We are paused by other party." msgstr "Друга страна нас је паузирала." -#. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:666 +#: ../coreapi/callbacks.c:630 msgid "Call is updated by remote." msgstr "Позив је освежен удаљеним." -#: ../coreapi/callbacks.c:782 +#: ../coreapi/callbacks.c:799 msgid "Call terminated." msgstr "Позив је завршен." -#: ../coreapi/callbacks.c:810 +#: ../coreapi/callbacks.c:827 msgid "User is busy." msgstr "Корисник је заузет." -#: ../coreapi/callbacks.c:811 +#: ../coreapi/callbacks.c:828 msgid "User is temporarily unavailable." msgstr "Корисник је привремено недоступан." #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:813 +#: ../coreapi/callbacks.c:830 msgid "User does not want to be disturbed." msgstr "Корисник не жели да буде узнемираван." -#: ../coreapi/callbacks.c:814 +#: ../coreapi/callbacks.c:831 msgid "Call declined." msgstr "Позив је одбијен." -#: ../coreapi/callbacks.c:829 +#: ../coreapi/callbacks.c:846 msgid "Request timeout." msgstr "Истекло је време захтева." -#: ../coreapi/callbacks.c:860 +#: ../coreapi/callbacks.c:877 msgid "Redirected" msgstr "Преусмерен" -#: ../coreapi/callbacks.c:915 +#: ../coreapi/callbacks.c:927 msgid "Call failed." msgstr "Позив није успео." -#: ../coreapi/callbacks.c:993 +#: ../coreapi/callbacks.c:1005 #, c-format msgid "Registration on %s successful." msgstr "Уписивање на „%s“ је успело." -#: ../coreapi/callbacks.c:994 +#: ../coreapi/callbacks.c:1006 #, c-format msgid "Unregistration on %s done." msgstr "Исписивање са „%s“ је обављено." -#: ../coreapi/callbacks.c:1012 +#: ../coreapi/callbacks.c:1024 msgid "no response timeout" msgstr "нема ограничења одговора" -#: ../coreapi/callbacks.c:1015 +#: ../coreapi/callbacks.c:1027 #, c-format msgid "Registration on %s failed: %s" msgstr "Уписивање на „%s“ није успело: %s" -#: ../coreapi/callbacks.c:1022 +#: ../coreapi/callbacks.c:1034 msgid "Service unavailable, retrying" msgstr "Услуга није доступна, поново покушавам" #. if encryption is DTLS, no status to be displayed -#: ../coreapi/linphonecall.c:180 +#: ../coreapi/linphonecall.c:197 #, c-format msgid "Authentication token is %s" msgstr "Симбол потврђивања идентитета је „%s“" -#: ../coreapi/linphonecall.c:1310 -msgid "Call parameters were successfully modified." -msgstr "" +#: ../coreapi/linphonecall.c:1561 +#, c-format +msgid "Call parameters could not be modified: %s." +msgstr "Параметри позива не могу бити измењени: %s." -#: ../coreapi/linphonecall.c:3686 +#: ../coreapi/linphonecall.c:1563 +msgid "Call parameters were successfully modified." +msgstr "Параметри позива су успешно измењени." + +#: ../coreapi/linphonecall.c:4396 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." @@ -1963,23 +2034,23 @@ msgstr[0] "Пропустили сте %i позив." msgstr[1] "Пропустили сте %i позива." msgstr[2] "Пропустили сте %i позива." -#: ../coreapi/call_log.c:209 +#: ../coreapi/call_log.c:223 msgid "aborted" msgstr "прекинут" -#: ../coreapi/call_log.c:212 +#: ../coreapi/call_log.c:226 msgid "completed" msgstr "завршен" -#: ../coreapi/call_log.c:215 +#: ../coreapi/call_log.c:229 msgid "missed" msgstr "пропуштен" -#: ../coreapi/call_log.c:218 +#: ../coreapi/call_log.c:232 msgid "unknown" msgstr "непознато" -#: ../coreapi/call_log.c:220 +#: ../coreapi/call_log.c:234 #, c-format msgid "" "%s at %s\n" @@ -1989,7 +2060,7 @@ msgid "" "Duration: %i mn %i sec\n" msgstr "%s на %s\nПозивач: %s\nПозивник: %s\nСтање: %s\nТрајање: %i мин. %i сек.\n" -#: ../coreapi/call_log.c:221 +#: ../coreapi/call_log.c:235 msgid "Outgoing call" msgstr "Одлазни позив" diff --git a/po/sv.po b/po/sv.po index bbc77c665..70a09d3a9 100644 --- a/po/sv.po +++ b/po/sv.po @@ -7,74 +7,83 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-04-30 10:13+0200\n" -"PO-Revision-Date: 2015-04-30 08:13+0000\n" +"POT-Creation-Date: 2015-11-10 15:16+0100\n" +"PO-Revision-Date: 2015-11-10 14:16+0000\n" "Last-Translator: Belledonne Communications \n" -"Language-Team: Swedish (http://www.transifex.com/projects/p/linphone-gtk/language/sv/)\n" +"Language-Team: Swedish (http://www.transifex.com/belledonne-communications/linphone-gtk/language/sv/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: sv\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ../gtk/calllogs.c:148 ../gtk/friendlist.c:974 +#: ../gtk/calllogs.c:178 #, c-format msgid "Call %s" msgstr "Ringer %s" -#: ../gtk/calllogs.c:149 ../gtk/friendlist.c:975 +#: ../gtk/calllogs.c:179 #, c-format msgid "Send text to %s" msgstr "Skicka text till %s" -#: ../gtk/calllogs.c:232 +#: ../gtk/calllogs.c:181 +#, c-format +msgid "Add %s to your contact list" +msgstr "" + +#: ../gtk/calllogs.c:245 ../gtk/main.ui.h:21 +msgid "Recent calls" +msgstr "" + +#: ../gtk/calllogs.c:260 #, c-format msgid "Recent calls (%i)" msgstr "" -#: ../gtk/calllogs.c:314 +#: ../gtk/calllogs.c:331 msgid "n/a" msgstr "" -#: ../gtk/calllogs.c:317 +#: ../gtk/calllogs.c:334 msgid "Aborted" msgstr "" -#: ../gtk/calllogs.c:320 +#: ../gtk/calllogs.c:337 msgid "Missed" msgstr "" -#: ../gtk/calllogs.c:323 +#: ../gtk/calllogs.c:340 msgid "Declined" msgstr "" -#: ../gtk/calllogs.c:329 +#: ../gtk/calllogs.c:346 #, c-format msgid "%i minute" msgid_plural "%i minutes" msgstr[0] "" msgstr[1] "" -#: ../gtk/calllogs.c:332 +#: ../gtk/calllogs.c:349 #, c-format msgid "%i second" msgid_plural "%i seconds" msgstr[0] "" msgstr[1] "" -#: ../gtk/calllogs.c:337 +#: ../gtk/calllogs.c:354 #, c-format msgid "" "%s\tQuality: %s\n" "%s\t%s\t" msgstr "" -#: ../gtk/calllogs.c:341 +#: ../gtk/calllogs.c:358 #, c-format msgid "%s\t%s" msgstr "" -#: ../gtk/conference.c:38 ../gtk/main.ui.h:13 +#: ../gtk/conference.c:38 ../gtk/in_call_frame.ui.h:11 msgid "Conference" msgstr "" @@ -87,297 +96,314 @@ msgstr "" msgid "Couldn't find pixmap file: %s" msgstr "Kunde inte hitta pixmap filen: %s" -#: ../gtk/main.c:137 +#: ../gtk/chat.c:196 ../gtk/chat.c:254 +msgid "Sending..." +msgstr "" + +#: ../gtk/chat.c:213 ../gtk/chat.c:263 +msgid "Message not sent" +msgstr "" + +#: ../gtk/chat.c:472 +msgid "Copy" +msgstr "" + +#: ../gtk/main.c:138 msgid "log to stdout some debug information while running." msgstr "skriv loggning information under körning" -#: ../gtk/main.c:138 -msgid "path to a file to write logs into." -msgstr "" - #: ../gtk/main.c:139 -msgid "Start linphone with video disabled." +msgid "display version and exit." msgstr "" #: ../gtk/main.c:140 +msgid "path to a file to write logs into." +msgstr "" + +#: ../gtk/main.c:141 +msgid "Start linphone with video disabled." +msgstr "" + +#: ../gtk/main.c:142 msgid "Start only in the system tray, do not show the main interface." msgstr "Starta ikonifierat, visa inte huvudfönstret" -#: ../gtk/main.c:141 +#: ../gtk/main.c:143 msgid "address to call right now" msgstr "Samtalsmottagare" -#: ../gtk/main.c:142 +#: ../gtk/main.c:144 msgid "" "Specifiy a working directory (should be the base of the installation, eg: " "c:\\Program Files\\Linphone)" msgstr "Välj en arbetskatalog som ska vara basen för installationen, såsom C:\\Program\\Linphone" -#: ../gtk/main.c:143 +#: ../gtk/main.c:145 msgid "Configuration file" msgstr "" -#: ../gtk/main.c:144 +#: ../gtk/main.c:146 msgid "Run the audio assistant" msgstr "" -#: ../gtk/main.c:145 +#: ../gtk/main.c:147 msgid "Run self test and exit 0 if succeed" msgstr "" -#: ../gtk/main.c:1070 +#: ../gtk/main.c:1046 #, c-format msgid "" -"%s would like to add you to his contact list.\n" -"Would you allow him to see your presence status or add him to your contact list ?\n" +"%s would like to add you to his/her contact list.\n" +"Would you add him/her to your contact list and allow him/her to see your presence status?\n" "If you answer no, this person will be temporarily blacklisted." -msgstr "%s skulle vilja lägga till dig till hans/hennes kontaktlista.\nVill du tillåta honom/henne att se din närvarostatus eller lägga till honom/henne till din kontaktlista?\nOm du svarar nej, personen kommer att vara bannlyst." +msgstr "" -#: ../gtk/main.c:1147 +#: ../gtk/main.c:1123 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" msgstr "" -#: ../gtk/main.c:1268 +#: ../gtk/main.c:1253 msgid "Call error" msgstr "" -#: ../gtk/main.c:1271 ../coreapi/linphonecore.c:3846 +#: ../gtk/main.c:1256 ../coreapi/linphonecore.c:3813 msgid "Call ended" msgstr "Samtalet slut" -#: ../gtk/main.c:1274 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1259 ../coreapi/call_log.c:235 msgid "Incoming call" msgstr "Inkommande samtal" -#: ../gtk/main.c:1276 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1261 ../gtk/incall_view.c:580 ../gtk/in_call_frame.ui.h:2 msgid "Answer" msgstr "" -#: ../gtk/main.c:1278 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1263 ../gtk/in_call_frame.ui.h:3 msgid "Decline" msgstr "Avböj" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 msgid "Call paused" msgstr "" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 #, c-format msgid "by %s" msgstr "" -#: ../gtk/main.c:1354 +#: ../gtk/main.c:1339 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "" -#: ../gtk/main.c:1509 +#: ../gtk/main.c:1505 msgid "Website link" msgstr "Webbsajt" -#: ../gtk/main.c:1568 ../gtk/waiting.ui.h:1 +#: ../gtk/main.c:1564 ../gtk/waiting.ui.h:1 msgid "Linphone" msgstr "Linphone" -#: ../gtk/main.c:1569 +#: ../gtk/main.c:1565 msgid "A video internet phone" msgstr "" -#: ../gtk/main.c:1629 +#: ../gtk/main.c:1624 #, c-format msgid "%s (Default)" msgstr "%s (Default)" -#: ../gtk/main.c:1962 ../coreapi/callbacks.c:1063 +#: ../gtk/main.c:1960 ../coreapi/callbacks.c:1075 #, c-format msgid "We are transferred to %s" msgstr "" -#: ../gtk/main.c:1972 +#: ../gtk/main.c:1970 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:2117 +#: ../gtk/main.c:2129 msgid "A free SIP video-phone" msgstr "En gratis SIP video-telefon" -#: ../gtk/main.c:2221 +#: ../gtk/main.c:2242 #, c-format msgid "Hello\n" msgstr "" -#: ../gtk/friendlist.c:505 +#: ../gtk/friendlist.c:461 msgid "Add to addressbook" msgstr "" -#: ../gtk/friendlist.c:691 -msgid "Presence status" -msgstr "Närvarostatus" - -#: ../gtk/friendlist.c:709 ../gtk/propertybox.c:569 ../gtk/contact.ui.h:1 -msgid "Name" -msgstr "Namn" - -#: ../gtk/friendlist.c:721 -msgid "Call" -msgstr "" - -#: ../gtk/friendlist.c:726 -msgid "Chat" -msgstr "" - -#: ../gtk/friendlist.c:756 +#: ../gtk/friendlist.c:627 #, c-format msgid "Search in %s directory" msgstr "Sök i %s katalogen" -#: ../gtk/friendlist.c:924 +#: ../gtk/friendlist.c:772 msgid "Invalid sip contact !" msgstr "ogiltig SIP kontakt!" -#: ../gtk/friendlist.c:976 +#: ../gtk/friendlist.c:820 +#, c-format +msgid "Add a new contact" +msgstr "" + +#: ../gtk/friendlist.c:823 #, c-format msgid "Edit contact '%s'" msgstr "Ändra kontakt '%s'" -#: ../gtk/friendlist.c:977 +#: ../gtk/friendlist.c:824 #, c-format msgid "Delete contact '%s'" msgstr "Ta bort kontakt '%s'" -#: ../gtk/friendlist.c:978 +#: ../gtk/friendlist.c:825 #, c-format msgid "Delete chat history of '%s'" msgstr "" -#: ../gtk/friendlist.c:1029 +#: ../gtk/friendlist.c:862 #, c-format msgid "Add new contact from %s directory" msgstr "Lägg till kontakt ifrån %s katalogen" -#: ../gtk/propertybox.c:575 +#: ../gtk/propertybox.c:592 ../gtk/contact.ui.h:1 +msgid "Name" +msgstr "Namn" + +#: ../gtk/propertybox.c:598 msgid "Rate (Hz)" msgstr "Frekvens (Hz)" -#: ../gtk/propertybox.c:581 +#: ../gtk/propertybox.c:604 msgid "Status" msgstr "Status" -#: ../gtk/propertybox.c:587 +#: ../gtk/propertybox.c:617 msgid "IP Bitrate (kbit/s)" msgstr "" -#: ../gtk/propertybox.c:596 +#: ../gtk/propertybox.c:628 msgid "Parameters" msgstr "Parametrar" -#: ../gtk/propertybox.c:639 ../gtk/propertybox.c:782 +#: ../gtk/propertybox.c:670 ../gtk/propertybox.c:824 msgid "Enabled" msgstr "På" -#: ../gtk/propertybox.c:641 ../gtk/propertybox.c:782 ../gtk/parameters.ui.h:20 +#: ../gtk/propertybox.c:672 ../gtk/propertybox.c:824 ../gtk/parameters.ui.h:60 msgid "Disabled" msgstr "Av" -#: ../gtk/propertybox.c:828 +#: ../gtk/propertybox.c:902 msgid "Account" msgstr "Konto" -#: ../gtk/propertybox.c:1091 +#: ../gtk/propertybox.c:1170 msgid "English" msgstr "Engelska" -#: ../gtk/propertybox.c:1092 +#: ../gtk/propertybox.c:1171 msgid "French" msgstr "Fransk" -#: ../gtk/propertybox.c:1093 +#: ../gtk/propertybox.c:1172 msgid "Swedish" msgstr "Svenska" -#: ../gtk/propertybox.c:1094 +#: ../gtk/propertybox.c:1173 msgid "Italian" msgstr "Italiensk" -#: ../gtk/propertybox.c:1095 +#: ../gtk/propertybox.c:1174 msgid "Spanish" msgstr "Spanska" -#: ../gtk/propertybox.c:1096 +#: ../gtk/propertybox.c:1175 msgid "Brazilian Portugese" msgstr "Portugisiska" -#: ../gtk/propertybox.c:1097 +#: ../gtk/propertybox.c:1176 msgid "Polish" msgstr "Polska" -#: ../gtk/propertybox.c:1098 +#: ../gtk/propertybox.c:1177 msgid "German" msgstr "Tyska" -#: ../gtk/propertybox.c:1099 +#: ../gtk/propertybox.c:1178 msgid "Russian" msgstr "Ryska" -#: ../gtk/propertybox.c:1100 +#: ../gtk/propertybox.c:1179 msgid "Japanese" msgstr "Japanska" -#: ../gtk/propertybox.c:1101 +#: ../gtk/propertybox.c:1180 msgid "Dutch" msgstr "Nederländksa" -#: ../gtk/propertybox.c:1102 +#: ../gtk/propertybox.c:1181 msgid "Hungarian" msgstr "Hungerska" -#: ../gtk/propertybox.c:1103 +#: ../gtk/propertybox.c:1182 msgid "Czech" msgstr "Tjekiska" -#: ../gtk/propertybox.c:1104 +#: ../gtk/propertybox.c:1183 msgid "Chinese" msgstr "Kinesiska" -#: ../gtk/propertybox.c:1105 +#: ../gtk/propertybox.c:1184 msgid "Traditional Chinese" msgstr "" -#: ../gtk/propertybox.c:1106 +#: ../gtk/propertybox.c:1185 msgid "Norwegian" msgstr "" -#: ../gtk/propertybox.c:1107 +#: ../gtk/propertybox.c:1186 msgid "Hebrew" msgstr "" -#: ../gtk/propertybox.c:1108 +#: ../gtk/propertybox.c:1187 msgid "Serbian" msgstr "" -#: ../gtk/propertybox.c:1175 +#: ../gtk/propertybox.c:1188 +msgid "Arabic" +msgstr "" + +#: ../gtk/propertybox.c:1189 +msgid "Turkish" +msgstr "" + +#: ../gtk/propertybox.c:1246 msgid "" "You need to restart linphone for the new language selection to take effect." msgstr "Du behöver starta om programmet för att det nya språket ska synas." -#: ../gtk/propertybox.c:1255 +#: ../gtk/propertybox.c:1326 msgid "None" msgstr "" -#: ../gtk/propertybox.c:1259 +#: ../gtk/propertybox.c:1330 msgid "SRTP" msgstr "" -#: ../gtk/propertybox.c:1265 +#: ../gtk/propertybox.c:1336 msgid "DTLS" msgstr "" -#: ../gtk/propertybox.c:1272 +#: ../gtk/propertybox.c:1343 msgid "ZRTP" msgstr "" @@ -419,324 +445,195 @@ msgid_plural "Found %i contacts" msgstr[0] "Hittat kontakt %i" msgstr[1] "Hittat kontakt %i" -#: ../gtk/setupwizard.c:32 -msgid "" -"Welcome!\n" -"This assistant will help you to use a SIP account for your calls." -msgstr "" - -#: ../gtk/setupwizard.c:41 -msgid "Create an account on linphone.org" -msgstr "" - -#: ../gtk/setupwizard.c:42 -msgid "I have already a linphone.org account and I just want to use it" -msgstr "" - -#: ../gtk/setupwizard.c:43 -msgid "I have already a sip account and I just want to use it" -msgstr "" - -#: ../gtk/setupwizard.c:44 -msgid "I want to specify a remote configuration URI" -msgstr "" - -#: ../gtk/setupwizard.c:87 -msgid "Enter your linphone.org username" -msgstr "" - -#: ../gtk/setupwizard.c:100 ../gtk/parameters.ui.h:85 ../gtk/ldap.ui.h:4 -msgid "Username:" -msgstr "Användarnamn:" - -#: ../gtk/setupwizard.c:102 ../gtk/password.ui.h:4 ../gtk/ldap.ui.h:5 -msgid "Password:" -msgstr "Lösenord:" - -#: ../gtk/setupwizard.c:122 -msgid "Enter your account informations" -msgstr "" - -#: ../gtk/setupwizard.c:138 -msgid "Username*" -msgstr "" - -#: ../gtk/setupwizard.c:139 -msgid "Password*" -msgstr "" - -#: ../gtk/setupwizard.c:142 -msgid "Domain*" -msgstr "" - -#: ../gtk/setupwizard.c:143 -msgid "Proxy" -msgstr "" - -#: ../gtk/setupwizard.c:322 -msgid "(*) Required fields" -msgstr "" - -#: ../gtk/setupwizard.c:323 -msgid "Username: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:325 -msgid "Password: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:327 -msgid "Email: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:329 -msgid "Confirm your password: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:343 -msgid "Keep me informed with linphone updates" -msgstr "" - -#: ../gtk/setupwizard.c:399 -msgid "" -"Error, account not validated, username already used or server unreachable.\n" -"Please go back and try again." -msgstr "" - -#: ../gtk/setupwizard.c:410 -msgid "Thank you. Your account is now configured and ready for use." -msgstr "Tack. Ditt konto är nu konfigurerad och färdig att användas." - -#: ../gtk/setupwizard.c:418 -msgid "" -"Please validate your account by clicking on the link we just sent you by email.\n" -"Then come back here and press Next button." -msgstr "" - -#: ../gtk/setupwizard.c:609 -msgid "SIP account configuration assistant" -msgstr "" - -#: ../gtk/setupwizard.c:629 -msgid "Welcome to the account setup assistant" -msgstr "Välkommen till kontoinstallationsassistenten" - -#: ../gtk/setupwizard.c:634 -msgid "Account setup assistant" -msgstr "Kontoinstallationsassistenten" - -#: ../gtk/setupwizard.c:640 -msgid "Configure your account (step 1/1)" -msgstr "" - -#: ../gtk/setupwizard.c:645 -msgid "Enter your sip username (step 1/1)" -msgstr "" - -#: ../gtk/setupwizard.c:649 -msgid "Enter account information (step 1/2)" -msgstr "" - -#: ../gtk/setupwizard.c:658 -msgid "Validation (step 2/2)" -msgstr "" - -#: ../gtk/setupwizard.c:663 -msgid "Error" -msgstr "" - -#: ../gtk/setupwizard.c:667 ../gtk/audio_assistant.c:534 -msgid "Terminating" -msgstr "" - -#: ../gtk/incall_view.c:70 ../gtk/incall_view.c:94 +#: ../gtk/incall_view.c:67 ../gtk/incall_view.c:87 #, c-format msgid "Call #%i" msgstr "" -#: ../gtk/incall_view.c:155 +#: ../gtk/incall_view.c:145 #, c-format msgid "Transfer to call #%i with %s" msgstr "" -#: ../gtk/incall_view.c:211 ../gtk/incall_view.c:214 +#: ../gtk/incall_view.c:202 ../gtk/incall_view.c:205 msgid "Not used" msgstr "" -#: ../gtk/incall_view.c:221 +#: ../gtk/incall_view.c:212 msgid "ICE not activated" msgstr "" -#: ../gtk/incall_view.c:223 +#: ../gtk/incall_view.c:214 msgid "ICE failed" msgstr "" -#: ../gtk/incall_view.c:225 +#: ../gtk/incall_view.c:216 msgid "ICE in progress" msgstr "" -#: ../gtk/incall_view.c:227 +#: ../gtk/incall_view.c:218 msgid "Going through one or more NATs" msgstr "" -#: ../gtk/incall_view.c:229 +#: ../gtk/incall_view.c:220 msgid "Direct" msgstr "" -#: ../gtk/incall_view.c:231 +#: ../gtk/incall_view.c:222 msgid "Through a relay server" msgstr "" -#: ../gtk/incall_view.c:239 +#: ../gtk/incall_view.c:230 msgid "uPnP not activated" msgstr "" -#: ../gtk/incall_view.c:241 +#: ../gtk/incall_view.c:232 msgid "uPnP in progress" msgstr "" -#: ../gtk/incall_view.c:243 +#: ../gtk/incall_view.c:234 msgid "uPnp not available" msgstr "" -#: ../gtk/incall_view.c:245 +#: ../gtk/incall_view.c:236 msgid "uPnP is running" msgstr "" -#: ../gtk/incall_view.c:247 +#: ../gtk/incall_view.c:238 msgid "uPnP failed" msgstr "" -#: ../gtk/incall_view.c:257 ../gtk/incall_view.c:258 +#: ../gtk/incall_view.c:248 ../gtk/incall_view.c:249 msgid "Direct or through server" msgstr "" -#: ../gtk/incall_view.c:267 ../gtk/incall_view.c:279 +#: ../gtk/incall_view.c:258 ../gtk/incall_view.c:270 #, c-format msgid "" "download: %f\n" "upload: %f (kbit/s)" msgstr "" -#: ../gtk/incall_view.c:272 ../gtk/incall_view.c:274 +#: ../gtk/incall_view.c:263 ../gtk/incall_view.c:265 #, c-format msgid "%ix%i @ %f fps" msgstr "" -#: ../gtk/incall_view.c:304 +#: ../gtk/incall_view.c:295 #, c-format msgid "%.3f seconds" msgstr "" -#: ../gtk/incall_view.c:407 ../gtk/main.ui.h:12 ../gtk/videowindow.c:235 +#: ../gtk/incall_view.c:453 ../gtk/in_call_frame.ui.h:10 +#: ../gtk/videowindow.c:236 msgid "Hang up" msgstr "" -#: ../gtk/incall_view.c:511 +#: ../gtk/incall_view.c:559 msgid "Calling..." msgstr "Ringer..." -#: ../gtk/incall_view.c:514 ../gtk/incall_view.c:733 -msgid "00::00::00" -msgstr "00:00:00" +#: ../gtk/incall_view.c:562 ../gtk/incall_view.c:792 +msgid "00:00:00" +msgstr "" -#: ../gtk/incall_view.c:525 +#: ../gtk/incall_view.c:573 msgid "Incoming call" msgstr "" -#: ../gtk/incall_view.c:562 +#: ../gtk/incall_view.c:610 msgid "good" msgstr "" -#: ../gtk/incall_view.c:564 +#: ../gtk/incall_view.c:612 msgid "average" msgstr "" -#: ../gtk/incall_view.c:566 +#: ../gtk/incall_view.c:614 msgid "poor" msgstr "" -#: ../gtk/incall_view.c:568 +#: ../gtk/incall_view.c:616 msgid "very poor" msgstr "" -#: ../gtk/incall_view.c:570 +#: ../gtk/incall_view.c:618 msgid "too bad" msgstr "" -#: ../gtk/incall_view.c:571 ../gtk/incall_view.c:587 +#: ../gtk/incall_view.c:619 ../gtk/incall_view.c:635 msgid "unavailable" msgstr "" -#: ../gtk/incall_view.c:679 +#: ../gtk/incall_view.c:731 msgid "Secured by SRTP" msgstr "" -#: ../gtk/incall_view.c:685 +#: ../gtk/incall_view.c:737 msgid "Secured by DTLS" msgstr "" -#: ../gtk/incall_view.c:691 +#: ../gtk/incall_view.c:743 #, c-format msgid "Secured by ZRTP - [auth token: %s]" msgstr "" -#: ../gtk/incall_view.c:697 +#: ../gtk/incall_view.c:747 msgid "Set unverified" msgstr "" -#: ../gtk/incall_view.c:697 ../gtk/main.ui.h:4 +#: ../gtk/incall_view.c:747 msgid "Set verified" msgstr "" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In conference" msgstr "" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In call" msgstr "" -#: ../gtk/incall_view.c:764 +#: ../gtk/incall_view.c:824 msgid "Paused call" msgstr "" -#: ../gtk/incall_view.c:800 +#: ../gtk/incall_view.c:861 msgid "Call ended." msgstr "Samtalet slut." -#: ../gtk/incall_view.c:831 +#: ../gtk/incall_view.c:892 msgid "Transfer in progress" msgstr "" -#: ../gtk/incall_view.c:834 +#: ../gtk/incall_view.c:895 msgid "Transfer done." msgstr "" -#: ../gtk/incall_view.c:837 +#: ../gtk/incall_view.c:898 msgid "Transfer failed." msgstr "" -#: ../gtk/incall_view.c:881 +#: ../gtk/incall_view.c:929 msgid "Resume" msgstr "" -#: ../gtk/incall_view.c:888 ../gtk/main.ui.h:9 +#: ../gtk/incall_view.c:929 ../gtk/in_call_frame.ui.h:7 msgid "Pause" msgstr "" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 #, c-format msgid "" "Recording into\n" "%s %s" msgstr "" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 msgid "(Paused)" msgstr "" -#: ../gtk/loginframe.c:87 +#: ../gtk/loginframe.c:75 #, c-format msgid "Please enter login information for %s" msgstr "Mata in ditt lösenord för domänen %s:" @@ -751,262 +648,107 @@ msgstr "" msgid "Downloading of remote configuration from %s failed." msgstr "" -#: ../gtk/audio_assistant.c:98 +#: ../gtk/audio_assistant.c:103 msgid "No voice detected" msgstr "" -#: ../gtk/audio_assistant.c:99 +#: ../gtk/audio_assistant.c:104 msgid "Too low" msgstr "" -#: ../gtk/audio_assistant.c:100 +#: ../gtk/audio_assistant.c:105 msgid "Good" msgstr "" -#: ../gtk/audio_assistant.c:101 +#: ../gtk/audio_assistant.c:106 msgid "Too loud" msgstr "" -#: ../gtk/audio_assistant.c:183 +#: ../gtk/audio_assistant.c:188 msgid "Did you hear three beeps ?" msgstr "" -#: ../gtk/audio_assistant.c:292 ../gtk/audio_assistant.c:297 +#: ../gtk/audio_assistant.c:299 ../gtk/audio_assistant.c:304 msgid "Sound preferences not found " msgstr "" -#: ../gtk/audio_assistant.c:306 +#: ../gtk/audio_assistant.c:313 msgid "Cannot launch system sound control " msgstr "" -#: ../gtk/audio_assistant.c:318 +#: ../gtk/audio_assistant.c:325 msgid "" "Welcome!\n" "This assistant will help you to configure audio settings for Linphone" msgstr "" -#: ../gtk/audio_assistant.c:328 +#: ../gtk/audio_assistant.c:335 msgid "Capture device" msgstr "" -#: ../gtk/audio_assistant.c:329 +#: ../gtk/audio_assistant.c:336 msgid "Recorded volume" msgstr "" -#: ../gtk/audio_assistant.c:333 +#: ../gtk/audio_assistant.c:340 msgid "No voice" msgstr "" -#: ../gtk/audio_assistant.c:334 ../gtk/audio_assistant.c:373 +#: ../gtk/audio_assistant.c:341 ../gtk/audio_assistant.c:380 msgid "System sound preferences" msgstr "" -#: ../gtk/audio_assistant.c:369 +#: ../gtk/audio_assistant.c:376 msgid "Playback device" msgstr "" -#: ../gtk/audio_assistant.c:370 +#: ../gtk/audio_assistant.c:377 msgid "Play three beeps" msgstr "" -#: ../gtk/audio_assistant.c:403 +#: ../gtk/audio_assistant.c:410 msgid "Press the record button and say some words" msgstr "" -#: ../gtk/audio_assistant.c:404 +#: ../gtk/audio_assistant.c:411 msgid "Listen to your record voice" msgstr "" -#: ../gtk/audio_assistant.c:405 +#: ../gtk/audio_assistant.c:412 ../gtk/conf_frame.ui.h:2 +#: ../gtk/in_call_frame.ui.h:4 msgid "Record" msgstr "" -#: ../gtk/audio_assistant.c:406 +#: ../gtk/audio_assistant.c:413 msgid "Play" msgstr "" -#: ../gtk/audio_assistant.c:433 +#: ../gtk/audio_assistant.c:440 msgid "Let's start Linphone now" msgstr "" -#: ../gtk/audio_assistant.c:503 +#: ../gtk/audio_assistant.c:510 msgid "Audio Assistant" msgstr "" -#: ../gtk/audio_assistant.c:513 ../gtk/main.ui.h:32 +#: ../gtk/audio_assistant.c:520 ../gtk/main.ui.h:13 msgid "Audio assistant" msgstr "" -#: ../gtk/audio_assistant.c:518 +#: ../gtk/audio_assistant.c:525 msgid "Mic Gain calibration" msgstr "" -#: ../gtk/audio_assistant.c:524 +#: ../gtk/audio_assistant.c:531 msgid "Speaker volume calibration" msgstr "" -#: ../gtk/audio_assistant.c:529 +#: ../gtk/audio_assistant.c:536 msgid "Record and Play" msgstr "" -#: ../gtk/main.ui.h:1 -msgid "Callee name" -msgstr "" - -#: ../gtk/main.ui.h:2 -msgid "Send" -msgstr "Skicka" - -#: ../gtk/main.ui.h:3 -msgid "End conference" -msgstr "" - -#: ../gtk/main.ui.h:7 -msgid "Record this call to an audio file" -msgstr "" - -#: ../gtk/main.ui.h:8 -msgid "Video" -msgstr "" - -#: ../gtk/main.ui.h:10 -msgid "Mute" -msgstr "" - -#: ../gtk/main.ui.h:11 -msgid "Transfer" -msgstr "" - -#: ../gtk/main.ui.h:14 -msgid "In call" -msgstr "I samtal" - -#: ../gtk/main.ui.h:15 -msgid "Duration" -msgstr "Förlopp" - -#: ../gtk/main.ui.h:16 -msgid "Call quality rating" -msgstr "" - -#: ../gtk/main.ui.h:17 -msgid "All users" -msgstr "" - -#: ../gtk/main.ui.h:18 -msgid "Online users" -msgstr "" - -#: ../gtk/main.ui.h:19 -msgid "ADSL" -msgstr "" - -#: ../gtk/main.ui.h:20 -msgid "Fiber Channel" -msgstr "" - -#: ../gtk/main.ui.h:21 -msgid "Default" -msgstr "" - -#: ../gtk/main.ui.h:22 -msgid "Delete" -msgstr "" - -#: ../gtk/main.ui.h:23 -msgid "_Options" -msgstr "" - -#: ../gtk/main.ui.h:24 -msgid "Set configuration URI" -msgstr "" - -#: ../gtk/main.ui.h:25 -msgid "Always start video" -msgstr "" - -#: ../gtk/main.ui.h:26 -msgid "Enable self-view" -msgstr "Själv bild" - -#: ../gtk/main.ui.h:27 -msgid "_Help" -msgstr "" - -#: ../gtk/main.ui.h:28 -msgid "Show debug window" -msgstr "" - -#: ../gtk/main.ui.h:29 -msgid "_Homepage" -msgstr "" - -#: ../gtk/main.ui.h:30 -msgid "Check _Updates" -msgstr "" - -#: ../gtk/main.ui.h:31 -msgid "Account assistant" -msgstr "" - -#: ../gtk/main.ui.h:33 -msgid "SIP address or phone number:" -msgstr "Användarnamn" - -#: ../gtk/main.ui.h:34 -msgid "Initiate a new call" -msgstr "" - -#: ../gtk/main.ui.h:35 -msgid "Contacts" -msgstr "" - -#: ../gtk/main.ui.h:36 -msgid "Search" -msgstr "Sök" - -#: ../gtk/main.ui.h:37 -msgid "Add contacts from directory" -msgstr "Lägg till kontakt ifrån katalogen" - -#: ../gtk/main.ui.h:38 -msgid "Add contact" -msgstr "" - -#: ../gtk/main.ui.h:39 -msgid "Recent calls" -msgstr "" - -#: ../gtk/main.ui.h:40 -msgid "My current identity:" -msgstr "Min nuvarande identitet" - -#: ../gtk/main.ui.h:41 ../gtk/tunnel_config.ui.h:7 -msgid "Username" -msgstr "Användarnamn" - -#: ../gtk/main.ui.h:42 ../gtk/tunnel_config.ui.h:8 -msgid "Password" -msgstr "Lösenord" - -#: ../gtk/main.ui.h:43 -msgid "Internet connection:" -msgstr "Internet förbindelse:" - -#: ../gtk/main.ui.h:44 -msgid "Automatically log me in" -msgstr "Logga mig automatiskt" - -#: ../gtk/main.ui.h:45 ../gtk/password.ui.h:3 -msgid "UserID" -msgstr "AnvändarID" - -#: ../gtk/main.ui.h:46 -msgid "Login information" -msgstr "Login information" - -#: ../gtk/main.ui.h:47 -msgid "Welcome!" +#: ../gtk/audio_assistant.c:541 ../gtk/setup_wizard.ui.h:38 +msgid "Terminating" msgstr "" #: ../gtk/about.ui.h:1 @@ -1037,456 +779,6 @@ msgid "" "he: Eli Zaretskii \n" msgstr "" -#: ../gtk/contact.ui.h:2 -msgid "SIP Address" -msgstr "SIP Adress" - -#: ../gtk/contact.ui.h:3 -msgid "Show this contact presence status" -msgstr "Visa kontaktens närvarostatus" - -#: ../gtk/contact.ui.h:4 -msgid "Allow this contact to see my presence status" -msgstr "Tillåt den här kontakten att se min närvarostatus" - -#: ../gtk/contact.ui.h:5 -msgid "Contact information" -msgstr "Kontakt information" - -#: ../gtk/log.ui.h:1 -msgid "Linphone debug window" -msgstr "Linphone debug fönster" - -#: ../gtk/log.ui.h:2 -msgid "Scroll to end" -msgstr "" - -#: ../gtk/password.ui.h:1 -msgid "Linphone - Authentication required" -msgstr "" - -#: ../gtk/password.ui.h:2 -msgid "Please enter the domain password" -msgstr "Mata in lösenordet för domänen" - -#: ../gtk/call_logs.ui.h:1 -msgid "Call history" -msgstr "Samtalshistorik" - -#: ../gtk/call_logs.ui.h:2 -msgid "Clear all" -msgstr "" - -#: ../gtk/call_logs.ui.h:3 -msgid "Call back" -msgstr "" - -#: ../gtk/sip_account.ui.h:1 -msgid "Linphone - Configure a SIP account" -msgstr "Linphone - Konfigurera ett SIP konto" - -#: ../gtk/sip_account.ui.h:2 -msgid "Your SIP identity:" -msgstr "Din SIP identitet:" - -#: ../gtk/sip_account.ui.h:3 -msgid "Looks like sip:@" -msgstr "" - -#: ../gtk/sip_account.ui.h:4 -msgid "sip:" -msgstr "sip:" - -#: ../gtk/sip_account.ui.h:5 -msgid "SIP Proxy address:" -msgstr "SIP Proxy adress:" - -#: ../gtk/sip_account.ui.h:6 -msgid "Looks like sip:" -msgstr "" - -#: ../gtk/sip_account.ui.h:7 -msgid "Registration duration (sec):" -msgstr "Registreringsfrekvens (sek.):" - -#: ../gtk/sip_account.ui.h:8 -msgid "Contact params (optional):" -msgstr "" - -#: ../gtk/sip_account.ui.h:9 -msgid "AVPF regular RTCP interval (sec):" -msgstr "" - -#: ../gtk/sip_account.ui.h:10 -msgid "Route (optional):" -msgstr "Route (tillval):" - -#: ../gtk/sip_account.ui.h:11 -msgid "Transport" -msgstr "" - -#: ../gtk/sip_account.ui.h:12 -msgid "Register" -msgstr "" - -#: ../gtk/sip_account.ui.h:13 -msgid "Publish presence information" -msgstr "Publicera närvaro information" - -#: ../gtk/sip_account.ui.h:14 -msgid "Enable AVPF" -msgstr "" - -#: ../gtk/sip_account.ui.h:15 -msgid "Configure a SIP account" -msgstr "Konfigurera ett SIP konto" - -#: ../gtk/parameters.ui.h:1 -msgid "anonymous" -msgstr "" - -#: ../gtk/parameters.ui.h:2 -msgid "GSSAPI" -msgstr "" - -#: ../gtk/parameters.ui.h:3 -msgid "SASL" -msgstr "" - -#: ../gtk/parameters.ui.h:4 -msgid "default soundcard" -msgstr "default ljudkort" - -#: ../gtk/parameters.ui.h:5 -msgid "a sound card" -msgstr "" - -#: ../gtk/parameters.ui.h:6 -msgid "default camera" -msgstr "default kamera" - -#: ../gtk/parameters.ui.h:7 -msgid "CIF" -msgstr "" - -#: ../gtk/parameters.ui.h:8 -msgid "Audio codecs" -msgstr "" - -#: ../gtk/parameters.ui.h:9 -msgid "Video codecs" -msgstr "" - -#: ../gtk/parameters.ui.h:10 -msgid "C" -msgstr "" - -#: ../gtk/parameters.ui.h:11 -msgid "SIP (UDP)" -msgstr "" - -#: ../gtk/parameters.ui.h:12 -msgid "SIP (TCP)" -msgstr "" - -#: ../gtk/parameters.ui.h:13 -msgid "SIP (TLS)" -msgstr "" - -#: ../gtk/parameters.ui.h:14 -msgid "Settings" -msgstr "Inställningar" - -#: ../gtk/parameters.ui.h:15 -msgid "Set Maximum Transmission Unit:" -msgstr "Välj MTU (Maximum Transmission Unit):" - -#: ../gtk/parameters.ui.h:16 -msgid "Send DTMFs as SIP info" -msgstr "Kicka DTMF koder som SIP info" - -#: ../gtk/parameters.ui.h:17 -msgid "Allow IPv6" -msgstr "" - -#: ../gtk/parameters.ui.h:18 -msgid "Transport" -msgstr "Transport" - -#: ../gtk/parameters.ui.h:19 -msgid "SIP/UDP port" -msgstr "" - -#: ../gtk/parameters.ui.h:21 -msgid "Random" -msgstr "" - -#: ../gtk/parameters.ui.h:22 -msgid "SIP/TCP port" -msgstr "" - -#: ../gtk/parameters.ui.h:23 -msgid "Audio RTP/UDP:" -msgstr "" - -#: ../gtk/parameters.ui.h:24 -msgid "Fixed" -msgstr "" - -#: ../gtk/parameters.ui.h:25 -msgid "Video RTP/UDP:" -msgstr "" - -#: ../gtk/parameters.ui.h:26 -msgid "Media encryption type" -msgstr "" - -#: ../gtk/parameters.ui.h:27 -msgid "Media encryption is mandatory" -msgstr "" - -#: ../gtk/parameters.ui.h:28 -msgid "Tunnel" -msgstr "" - -#: ../gtk/parameters.ui.h:29 -msgid "DSCP fields" -msgstr "" - -#: ../gtk/parameters.ui.h:30 -msgid "Network protocol and ports" -msgstr "" - -#: ../gtk/parameters.ui.h:31 -msgid "Direct connection to the Internet" -msgstr "Direkt förbindelse till Internet" - -#: ../gtk/parameters.ui.h:32 -msgid "Behind NAT / Firewall (specify gateway IP )" -msgstr "" - -#: ../gtk/parameters.ui.h:33 -msgid "Behind NAT / Firewall (use STUN to resolve)" -msgstr "Bakom en NAT / brandvägg (använd STUN för att avgöra adressen)" - -#: ../gtk/parameters.ui.h:34 -msgid "Behind NAT / Firewall (use ICE)" -msgstr "" - -#: ../gtk/parameters.ui.h:35 -msgid "Behind NAT / Firewall (use uPnP)" -msgstr "" - -#: ../gtk/parameters.ui.h:36 -msgid "Public IP address:" -msgstr "Publik IP adress:" - -#: ../gtk/parameters.ui.h:37 -msgid "Stun server:" -msgstr "STUN server:" - -#: ../gtk/parameters.ui.h:38 -msgid "NAT and Firewall" -msgstr "NAT och Brandvägg" - -#: ../gtk/parameters.ui.h:39 -msgid "Network settings" -msgstr "Nätverksinställningar" - -#: ../gtk/parameters.ui.h:40 -msgid "Ring sound:" -msgstr "Ring signal:" - -#: ../gtk/parameters.ui.h:41 -msgid "ALSA special device (optional):" -msgstr "ALSA speciell enhet (tillval):" - -#: ../gtk/parameters.ui.h:42 -msgid "Capture device:" -msgstr "Mikrofon enhet:" - -#: ../gtk/parameters.ui.h:43 -msgid "Ring device:" -msgstr "Ringning enhet:" - -#: ../gtk/parameters.ui.h:44 -msgid "Playback device:" -msgstr "Uppspelningsenhet:" - -#: ../gtk/parameters.ui.h:45 -msgid "Enable echo cancellation" -msgstr "Tillåta ekokancellering" - -#: ../gtk/parameters.ui.h:46 -msgid "Audio" -msgstr "Audio" - -#: ../gtk/parameters.ui.h:47 -msgid "Video input device:" -msgstr "Video ingångsenhet:" - -#: ../gtk/parameters.ui.h:48 -msgid "Prefered video resolution:" -msgstr "Video upplösning:" - -#: ../gtk/parameters.ui.h:49 -msgid "Video output method:" -msgstr "" - -#: ../gtk/parameters.ui.h:50 -msgid "Show camera preview" -msgstr "" - -#: ../gtk/parameters.ui.h:51 -msgid "Video" -msgstr "Video" - -#: ../gtk/parameters.ui.h:52 -msgid "Multimedia settings" -msgstr "Multimedia inställningar" - -#: ../gtk/parameters.ui.h:53 -msgid "This section defines your SIP address when not using a SIP account" -msgstr "Denna sektion specificerar din SIP adress när du inte använder ett SIP konto" - -#: ../gtk/parameters.ui.h:54 -msgid "Your display name (eg: John Doe):" -msgstr "Ditt synliga namn, e.g. Kalle Karlsson:" - -#: ../gtk/parameters.ui.h:55 -msgid "Your username:" -msgstr "Ditt användarnamn:" - -#: ../gtk/parameters.ui.h:56 -msgid "Your resulting SIP address:" -msgstr "Din SIP adress:" - -#: ../gtk/parameters.ui.h:57 -msgid "Default identity" -msgstr "Default identitet" - -#: ../gtk/parameters.ui.h:58 -msgid "Wizard" -msgstr "" - -#: ../gtk/parameters.ui.h:59 -msgid "Add" -msgstr "Lägg till" - -#: ../gtk/parameters.ui.h:60 -msgid "Edit" -msgstr "Editera" - -#: ../gtk/parameters.ui.h:61 -msgid "Remove" -msgstr "Ta bort" - -#: ../gtk/parameters.ui.h:62 -msgid "Proxy accounts" -msgstr "Proxy konton" - -#: ../gtk/parameters.ui.h:63 -msgid "Erase all passwords" -msgstr "Glöm alla lösenord" - -#: ../gtk/parameters.ui.h:64 -msgid "Privacy" -msgstr "Integritet" - -#: ../gtk/parameters.ui.h:65 -msgid "Automatically answer when a call is received" -msgstr "" - -#: ../gtk/parameters.ui.h:66 -msgid "Delay before answering (ms)" -msgstr "" - -#: ../gtk/parameters.ui.h:67 -msgid "Auto-answer" -msgstr "" - -#: ../gtk/parameters.ui.h:68 -msgid "Manage SIP Accounts" -msgstr "Hantera SIP konton" - -#: ../gtk/parameters.ui.h:69 ../gtk/tunnel_config.ui.h:4 -msgid "Enable" -msgstr "Möjliggör" - -#: ../gtk/parameters.ui.h:70 ../gtk/tunnel_config.ui.h:5 -msgid "Disable" -msgstr "Inaktivera" - -#: ../gtk/parameters.ui.h:71 -msgid "Codecs" -msgstr "Codecs" - -#: ../gtk/parameters.ui.h:72 -msgid "0 stands for \"unlimited\"" -msgstr "0 står för \"utan begränsning\"" - -#: ../gtk/parameters.ui.h:73 -msgid "Upload speed limit in Kbit/sec:" -msgstr "Max upstream bandbreddshastighet i kbit/sek:" - -#: ../gtk/parameters.ui.h:74 -msgid "Download speed limit in Kbit/sec:" -msgstr "Max downstream bandbreddshastighet i kbit/sek:" - -#: ../gtk/parameters.ui.h:75 -msgid "Enable adaptive rate control" -msgstr "" - -#: ../gtk/parameters.ui.h:76 -msgid "" -"Adaptive rate control is a technique to dynamically guess the available " -"bandwidth during a call." -msgstr "" - -#: ../gtk/parameters.ui.h:77 -msgid "Bandwidth control" -msgstr "Bandbreddskontroll" - -#: ../gtk/parameters.ui.h:78 -msgid "Codecs" -msgstr "Codecs" - -#: ../gtk/parameters.ui.h:79 -msgid "Language" -msgstr "Språk" - -#: ../gtk/parameters.ui.h:80 -msgid "Show advanced settings" -msgstr "Visa avancerade inställningar" - -#: ../gtk/parameters.ui.h:81 -msgid "Level" -msgstr "Nivå" - -#: ../gtk/parameters.ui.h:82 -msgid "User interface" -msgstr "Användarinterface" - -#: ../gtk/parameters.ui.h:83 ../gtk/ldap.ui.h:2 -msgid "Server address:" -msgstr "" - -#: ../gtk/parameters.ui.h:84 ../gtk/ldap.ui.h:3 -msgid "Authentication method:" -msgstr "" - -#: ../gtk/parameters.ui.h:86 -msgid "LDAP Account setup" -msgstr "" - -#: ../gtk/parameters.ui.h:87 -msgid "LDAP" -msgstr "" - -#: ../gtk/parameters.ui.h:88 -msgid "Done" -msgstr "Klar" - #: ../gtk/buddylookup.ui.h:1 msgid "Search contacts in directory" msgstr "Sök för kontakter i katalogen" @@ -1499,28 +791,20 @@ msgstr "Lägg till min lista" msgid "Search somebody" msgstr "Sök efter kontakter" -#: ../gtk/waiting.ui.h:2 -msgid "Please wait" -msgstr "Vänta" - -#: ../gtk/dscp_settings.ui.h:1 -msgid "DSCP settings" +#: ../gtk/callee_frame.ui.h:1 +msgid "Callee name" msgstr "" -#: ../gtk/dscp_settings.ui.h:2 -msgid "SIP" +#: ../gtk/call_logs.ui.h:1 +msgid "Call history" +msgstr "Samtalshistorik" + +#: ../gtk/call_logs.ui.h:2 +msgid "Clear all" msgstr "" -#: ../gtk/dscp_settings.ui.h:3 -msgid "Audio RTP stream" -msgstr "" - -#: ../gtk/dscp_settings.ui.h:4 -msgid "Video RTP stream" -msgstr "" - -#: ../gtk/dscp_settings.ui.h:5 -msgid "Set DSCP values (in hexadecimal)" +#: ../gtk/call_logs.ui.h:3 +msgid "Call back" msgstr "" #: ../gtk/call_statistics.ui.h:1 @@ -1571,30 +855,112 @@ msgstr "" msgid "Call statistics and information" msgstr "" -#: ../gtk/tunnel_config.ui.h:1 -msgid "Configure VoIP tunnel" +#: ../gtk/chatroom_frame.ui.h:1 +msgid "Send" +msgstr "Skicka" + +#: ../gtk/conf_frame.ui.h:1 +msgid "End conference" msgstr "" -#: ../gtk/tunnel_config.ui.h:2 -msgid "Host" +#: ../gtk/config-uri.ui.h:1 +msgid "Specifying a remote configuration URI" msgstr "" -#: ../gtk/tunnel_config.ui.h:3 -msgid "Port" +#: ../gtk/config-uri.ui.h:2 +msgid "" +"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" +"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " msgstr "" -#: ../gtk/tunnel_config.ui.h:6 -msgid "Configure tunnel" +#: ../gtk/contact.ui.h:2 +msgid "SIP Address" +msgstr "SIP Adress" + +#: ../gtk/contact.ui.h:3 +msgid "Show this contact presence status" +msgstr "Visa kontaktens närvarostatus" + +#: ../gtk/contact.ui.h:4 +msgid "Allow this contact to see my presence status" +msgstr "Tillåt den här kontakten att se min närvarostatus" + +#: ../gtk/contact.ui.h:5 +msgid "Contact information" +msgstr "Kontakt information" + +#: ../gtk/dscp_settings.ui.h:1 +msgid "DSCP settings" msgstr "" -#: ../gtk/tunnel_config.ui.h:9 -msgid "Configure http proxy (optional)" +#: ../gtk/dscp_settings.ui.h:2 +msgid "SIP" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:3 +msgid "Audio RTP stream" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:4 +msgid "Video RTP stream" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:5 +msgid "Set DSCP values (in hexadecimal)" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:1 +msgid "Click here to set the speakers volume" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:5 +msgid "Record this call to an audio file" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:6 +msgid "Video" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:8 +msgid "Mute" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:9 +msgid "Transfer" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:12 +msgid "In call" +msgstr "I samtal" + +#: ../gtk/in_call_frame.ui.h:13 +msgid "Duration" +msgstr "Förlopp" + +#: ../gtk/in_call_frame.ui.h:14 +msgid "Call quality rating" msgstr "" #: ../gtk/ldap.ui.h:1 msgid "LDAP Settings" msgstr "" +#: ../gtk/ldap.ui.h:2 ../gtk/parameters.ui.h:89 +msgid "Server address:" +msgstr "" + +#: ../gtk/ldap.ui.h:3 ../gtk/parameters.ui.h:90 +msgid "Authentication method:" +msgstr "" + +#: ../gtk/ldap.ui.h:4 ../gtk/parameters.ui.h:91 ../gtk/setup_wizard.ui.h:17 +msgid "Username:" +msgstr "Användarnamn:" + +#: ../gtk/ldap.ui.h:5 ../gtk/password.ui.h:4 ../gtk/setup_wizard.ui.h:18 +msgid "Password:" +msgstr "Lösenord:" + #: ../gtk/ldap.ui.h:6 msgid "Use TLS Connection" msgstr "" @@ -1680,16 +1046,504 @@ msgstr "" msgid "NTLM" msgstr "" -#: ../gtk/config-uri.ui.h:1 -msgid "Specifying a remote configuration URI" +#: ../gtk/login_frame.ui.h:1 ../gtk/tunnel_config.ui.h:7 +msgid "Username" +msgstr "Användarnamn" + +#: ../gtk/login_frame.ui.h:2 ../gtk/tunnel_config.ui.h:8 +msgid "Password" +msgstr "Lösenord" + +#: ../gtk/login_frame.ui.h:3 +msgid "Internet connection:" +msgstr "Internet förbindelse:" + +#: ../gtk/login_frame.ui.h:4 +msgid "Automatically log me in" +msgstr "Logga mig automatiskt" + +#: ../gtk/login_frame.ui.h:5 ../gtk/password.ui.h:3 +msgid "UserID" +msgstr "AnvändarID" + +#: ../gtk/login_frame.ui.h:6 +msgid "Login information" +msgstr "Login information" + +#: ../gtk/login_frame.ui.h:7 +msgid "Welcome!" msgstr "" -#: ../gtk/config-uri.ui.h:2 -msgid "" -"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" -"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " +#: ../gtk/login_frame.ui.h:8 +msgid "ADSL" msgstr "" +#: ../gtk/login_frame.ui.h:9 +msgid "Fiber Channel" +msgstr "" + +#: ../gtk/log.ui.h:1 +msgid "Linphone debug window" +msgstr "Linphone debug fönster" + +#: ../gtk/log.ui.h:2 +msgid "Scroll to end" +msgstr "" + +#: ../gtk/main.ui.h:1 +msgid "Default" +msgstr "" + +#: ../gtk/main.ui.h:2 +msgid "Delete" +msgstr "" + +#: ../gtk/main.ui.h:3 +msgid "_Options" +msgstr "" + +#: ../gtk/main.ui.h:4 +msgid "Set configuration URI" +msgstr "" + +#: ../gtk/main.ui.h:5 +msgid "Always start video" +msgstr "" + +#: ../gtk/main.ui.h:6 +msgid "Enable self-view" +msgstr "Själv bild" + +#: ../gtk/main.ui.h:7 +msgid "Show keypad" +msgstr "" + +#: ../gtk/main.ui.h:8 +msgid "_Help" +msgstr "" + +#: ../gtk/main.ui.h:9 +msgid "Show debug window" +msgstr "" + +#: ../gtk/main.ui.h:10 +msgid "_Homepage" +msgstr "" + +#: ../gtk/main.ui.h:11 +msgid "Check _Updates" +msgstr "" + +#: ../gtk/main.ui.h:12 +msgid "Account assistant" +msgstr "" + +#: ../gtk/main.ui.h:14 +msgid "SIP address or phone number:" +msgstr "Användarnamn" + +#: ../gtk/main.ui.h:15 +msgid "Initiate a new call" +msgstr "" + +#: ../gtk/main.ui.h:16 +msgid "Contacts" +msgstr "" + +#: ../gtk/main.ui.h:17 +msgid "Search" +msgstr "Sök" + +#: ../gtk/main.ui.h:18 +msgid "Add contacts from directory" +msgstr "Lägg till kontakt ifrån katalogen" + +#: ../gtk/main.ui.h:19 +msgid "Add contact" +msgstr "" + +#: ../gtk/main.ui.h:20 +msgid "Clear call history" +msgstr "" + +#: ../gtk/main.ui.h:22 +msgid "My current identity:" +msgstr "Min nuvarande identitet" + +#: ../gtk/main.ui.h:23 +msgid "Autoanswer is enabled" +msgstr "" + +#: ../gtk/parameters.ui.h:1 +msgid "anonymous" +msgstr "" + +#: ../gtk/parameters.ui.h:2 +msgid "GSSAPI" +msgstr "" + +#: ../gtk/parameters.ui.h:3 +msgid "SASL" +msgstr "" + +#: ../gtk/parameters.ui.h:4 +msgid "default soundcard" +msgstr "default ljudkort" + +#: ../gtk/parameters.ui.h:5 +msgid "a sound card" +msgstr "" + +#: ../gtk/parameters.ui.h:6 +msgid "default camera" +msgstr "default kamera" + +#: ../gtk/parameters.ui.h:7 +msgid "CIF" +msgstr "" + +#: ../gtk/parameters.ui.h:8 +msgid "Audio codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:9 +msgid "Video codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:10 +msgid "C" +msgstr "" + +#: ../gtk/parameters.ui.h:11 +msgid "SIP (UDP)" +msgstr "" + +#: ../gtk/parameters.ui.h:12 +msgid "SIP (TCP)" +msgstr "" + +#: ../gtk/parameters.ui.h:13 +msgid "SIP (TLS)" +msgstr "" + +#: ../gtk/parameters.ui.h:14 +msgid "default" +msgstr "" + +#: ../gtk/parameters.ui.h:15 +msgid "high-fps" +msgstr "" + +#: ../gtk/parameters.ui.h:16 +msgid "custom" +msgstr "" + +#: ../gtk/parameters.ui.h:17 +msgid "Settings" +msgstr "Inställningar" + +#: ../gtk/parameters.ui.h:18 +msgid "This section defines your SIP address when not using a SIP account" +msgstr "Denna sektion specificerar din SIP adress när du inte använder ett SIP konto" + +#: ../gtk/parameters.ui.h:19 +msgid "Your display name (eg: John Doe):" +msgstr "Ditt synliga namn, e.g. Kalle Karlsson:" + +#: ../gtk/parameters.ui.h:20 +msgid "Your username:" +msgstr "Ditt användarnamn:" + +#: ../gtk/parameters.ui.h:21 +msgid "Your resulting SIP address:" +msgstr "Din SIP adress:" + +#: ../gtk/parameters.ui.h:22 +msgid "Default identity" +msgstr "Default identitet" + +#: ../gtk/parameters.ui.h:23 +msgid "Wizard" +msgstr "" + +#: ../gtk/parameters.ui.h:24 +msgid "Add" +msgstr "Lägg till" + +#: ../gtk/parameters.ui.h:25 +msgid "Edit" +msgstr "Editera" + +#: ../gtk/parameters.ui.h:26 +msgid "Remove" +msgstr "Ta bort" + +#: ../gtk/parameters.ui.h:27 +msgid "Proxy accounts" +msgstr "Proxy konton" + +#: ../gtk/parameters.ui.h:28 +msgid "Erase all passwords" +msgstr "Glöm alla lösenord" + +#: ../gtk/parameters.ui.h:29 +msgid "Privacy" +msgstr "Integritet" + +#: ../gtk/parameters.ui.h:30 +msgid "Automatically answer when a call is received" +msgstr "" + +#: ../gtk/parameters.ui.h:31 +msgid "Delay before answering (ms)" +msgstr "" + +#: ../gtk/parameters.ui.h:32 +msgid "Auto-answer" +msgstr "" + +#: ../gtk/parameters.ui.h:33 +msgid "Manage SIP Accounts" +msgstr "Hantera SIP konton" + +#: ../gtk/parameters.ui.h:34 +msgid "Ring sound:" +msgstr "Ring signal:" + +#: ../gtk/parameters.ui.h:35 +msgid "ALSA special device (optional):" +msgstr "ALSA speciell enhet (tillval):" + +#: ../gtk/parameters.ui.h:36 +msgid "Capture device:" +msgstr "Mikrofon enhet:" + +#: ../gtk/parameters.ui.h:37 +msgid "Ring device:" +msgstr "Ringning enhet:" + +#: ../gtk/parameters.ui.h:38 +msgid "Playback device:" +msgstr "Uppspelningsenhet:" + +#: ../gtk/parameters.ui.h:39 +msgid "Enable echo cancellation" +msgstr "Tillåta ekokancellering" + +#: ../gtk/parameters.ui.h:40 +msgid "Audio" +msgstr "Audio" + +#: ../gtk/parameters.ui.h:41 +msgid "Video input device:" +msgstr "Video ingångsenhet:" + +#: ../gtk/parameters.ui.h:42 +msgid "Preferred video resolution:" +msgstr "" + +#: ../gtk/parameters.ui.h:43 +msgid "Video output method:" +msgstr "" + +#: ../gtk/parameters.ui.h:44 +msgid "Show camera preview" +msgstr "" + +#: ../gtk/parameters.ui.h:45 +msgid "Video preset:" +msgstr "" + +#: ../gtk/parameters.ui.h:46 +msgid "Preferred video framerate:" +msgstr "" + +#: ../gtk/parameters.ui.h:47 +msgid "0 stands for \"unlimited\"" +msgstr "0 står för \"utan begränsning\"" + +#: ../gtk/parameters.ui.h:48 +msgid "Video" +msgstr "Video" + +#: ../gtk/parameters.ui.h:49 +msgid "Upload speed limit in Kbit/sec:" +msgstr "Max upstream bandbreddshastighet i kbit/sek:" + +#: ../gtk/parameters.ui.h:50 +msgid "Download speed limit in Kbit/sec:" +msgstr "Max downstream bandbreddshastighet i kbit/sek:" + +#: ../gtk/parameters.ui.h:51 +msgid "Enable adaptive rate control" +msgstr "" + +#: ../gtk/parameters.ui.h:52 +msgid "" +"Adaptive rate control is a technique to dynamically guess the available " +"bandwidth during a call." +msgstr "" + +#: ../gtk/parameters.ui.h:53 +msgid "Bandwidth control" +msgstr "Bandbreddskontroll" + +#: ../gtk/parameters.ui.h:54 +msgid "Multimedia settings" +msgstr "Multimedia inställningar" + +#: ../gtk/parameters.ui.h:55 +msgid "Set Maximum Transmission Unit:" +msgstr "Välj MTU (Maximum Transmission Unit):" + +#: ../gtk/parameters.ui.h:56 +msgid "Send DTMFs as SIP info" +msgstr "Kicka DTMF koder som SIP info" + +#: ../gtk/parameters.ui.h:57 +msgid "Allow IPv6" +msgstr "" + +#: ../gtk/parameters.ui.h:58 +msgid "Transport" +msgstr "Transport" + +#: ../gtk/parameters.ui.h:59 +msgid "SIP/UDP port" +msgstr "" + +#: ../gtk/parameters.ui.h:61 +msgid "Random" +msgstr "" + +#: ../gtk/parameters.ui.h:62 +msgid "SIP/TCP port" +msgstr "" + +#: ../gtk/parameters.ui.h:63 +msgid "Audio RTP/UDP:" +msgstr "" + +#: ../gtk/parameters.ui.h:64 +msgid "Fixed" +msgstr "" + +#: ../gtk/parameters.ui.h:65 +msgid "Video RTP/UDP:" +msgstr "" + +#: ../gtk/parameters.ui.h:66 +msgid "Media encryption type" +msgstr "" + +#: ../gtk/parameters.ui.h:67 +msgid "Media encryption is mandatory" +msgstr "" + +#: ../gtk/parameters.ui.h:68 +msgid "Tunnel" +msgstr "" + +#: ../gtk/parameters.ui.h:69 +msgid "DSCP fields" +msgstr "" + +#: ../gtk/parameters.ui.h:70 +msgid "Network protocol and ports" +msgstr "" + +#: ../gtk/parameters.ui.h:71 +msgid "Direct connection to the Internet" +msgstr "Direkt förbindelse till Internet" + +#: ../gtk/parameters.ui.h:72 +msgid "Behind NAT / Firewall (specify gateway IP )" +msgstr "" + +#: ../gtk/parameters.ui.h:73 +msgid "Behind NAT / Firewall (use STUN to resolve)" +msgstr "Bakom en NAT / brandvägg (använd STUN för att avgöra adressen)" + +#: ../gtk/parameters.ui.h:74 +msgid "Behind NAT / Firewall (use ICE)" +msgstr "" + +#: ../gtk/parameters.ui.h:75 +msgid "Behind NAT / Firewall (use uPnP)" +msgstr "" + +#: ../gtk/parameters.ui.h:76 +msgid "Public IP address:" +msgstr "Publik IP adress:" + +#: ../gtk/parameters.ui.h:77 +msgid "Stun server:" +msgstr "STUN server:" + +#: ../gtk/parameters.ui.h:78 +msgid "NAT and Firewall" +msgstr "NAT och Brandvägg" + +#: ../gtk/parameters.ui.h:79 +msgid "Network settings" +msgstr "Nätverksinställningar" + +#: ../gtk/parameters.ui.h:80 ../gtk/tunnel_config.ui.h:4 +msgid "Enable" +msgstr "Möjliggör" + +#: ../gtk/parameters.ui.h:81 ../gtk/tunnel_config.ui.h:5 +msgid "Disable" +msgstr "Inaktivera" + +#: ../gtk/parameters.ui.h:82 +msgid "Audio codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:83 +msgid "Video codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:84 +msgid "Codecs" +msgstr "Codecs" + +#: ../gtk/parameters.ui.h:85 +msgid "Language" +msgstr "Språk" + +#: ../gtk/parameters.ui.h:86 +msgid "Show advanced settings" +msgstr "Visa avancerade inställningar" + +#: ../gtk/parameters.ui.h:87 +msgid "Level" +msgstr "Nivå" + +#: ../gtk/parameters.ui.h:88 +msgid "User interface" +msgstr "Användarinterface" + +#: ../gtk/parameters.ui.h:92 +msgid "LDAP Account setup" +msgstr "" + +#: ../gtk/parameters.ui.h:93 +msgid "LDAP" +msgstr "" + +#: ../gtk/parameters.ui.h:94 +msgid "Done" +msgstr "Klar" + +#: ../gtk/password.ui.h:1 +msgid "Linphone - Authentication required" +msgstr "" + +#: ../gtk/password.ui.h:2 +msgid "Please enter the domain password" +msgstr "Mata in lösenordet för domänen" + #: ../gtk/provisioning-fetch.ui.h:1 msgid "Configuring..." msgstr "" @@ -1698,68 +1552,278 @@ msgstr "" msgid "Please wait while fetching configuration from server..." msgstr "" -#: ../coreapi/linphonecore.c:1539 +#: ../gtk/setup_wizard.ui.h:1 +msgid "SIP account configuration assistant" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:2 +msgid "" +"Welcome!\n" +"This assistant will help you to use a SIP account for your calls." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:4 +msgid "Welcome to the account setup assistant" +msgstr "Välkommen till kontoinstallationsassistenten" + +#: ../gtk/setup_wizard.ui.h:5 +msgid "Create an account on linphone.org" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:6 +msgid "I have already a linphone.org account and I just want to use it" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:7 +msgid "I have already a sip account and I just want to use it" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:8 +msgid "I want to specify a remote configuration URI" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:9 +msgid "Account setup assistant" +msgstr "Kontoinstallationsassistenten" + +#: ../gtk/setup_wizard.ui.h:10 +msgid "Enter your account information" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:11 +msgid "Username*" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:12 +msgid "Password*" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:13 +msgid "Domain*" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:14 +msgid "Proxy" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:15 +msgid "Configure your account (step 1/1)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:16 +msgid "Enter your linphone.org username" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:19 +msgid "Enter your sip username (step 1/1)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:20 +msgid "(*) Required fields" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:21 +msgid "Email: (*)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:22 +msgid "Username: (*)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:23 +msgid "Password: (*)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:24 +msgid "Confirm your password: (*)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:25 +msgid "Keep me informed with linphone updates" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:26 +msgid "Enter account information (step 1/2)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:27 +msgid "Your account is being created, please wait." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:28 +msgid "Account creation in progress" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:29 +msgid "" +"Please validate your account by clicking on the link we just sent you by email.\n" +"Then come back here and press Next button." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:31 +msgid "Validation (step 2/2)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:32 +msgid "Checking if your account is been validated, please wait." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:33 +msgid "Account validation check in progress" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:34 +msgid "" +"Error, account not validated, username already used or server unreachable.\n" +"Please go back and try again." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:36 +msgid "Error" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:37 +msgid "Thank you. Your account is now configured and ready for use." +msgstr "Tack. Ditt konto är nu konfigurerad och färdig att användas." + +#: ../gtk/sip_account.ui.h:1 +msgid "Linphone - Configure a SIP account" +msgstr "Linphone - Konfigurera ett SIP konto" + +#: ../gtk/sip_account.ui.h:2 +msgid "Your SIP identity:" +msgstr "Din SIP identitet:" + +#: ../gtk/sip_account.ui.h:3 +msgid "Looks like sip:@" +msgstr "" + +#: ../gtk/sip_account.ui.h:4 +msgid "sip:" +msgstr "sip:" + +#: ../gtk/sip_account.ui.h:5 +msgid "SIP Proxy address:" +msgstr "SIP Proxy adress:" + +#: ../gtk/sip_account.ui.h:6 +msgid "Looks like sip:" +msgstr "" + +#: ../gtk/sip_account.ui.h:7 +msgid "Registration duration (sec):" +msgstr "Registreringsfrekvens (sek.):" + +#: ../gtk/sip_account.ui.h:8 +msgid "Contact params (optional):" +msgstr "" + +#: ../gtk/sip_account.ui.h:9 +msgid "AVPF regular RTCP interval (sec):" +msgstr "" + +#: ../gtk/sip_account.ui.h:10 +msgid "Route (optional):" +msgstr "Route (tillval):" + +#: ../gtk/sip_account.ui.h:11 +msgid "Transport" +msgstr "" + +#: ../gtk/sip_account.ui.h:12 +msgid "Register" +msgstr "" + +#: ../gtk/sip_account.ui.h:13 +msgid "Publish presence information" +msgstr "Publicera närvaro information" + +#: ../gtk/sip_account.ui.h:14 +msgid "Enable AVPF" +msgstr "" + +#: ../gtk/sip_account.ui.h:15 +msgid "Configure a SIP account" +msgstr "Konfigurera ett SIP konto" + +#: ../gtk/tunnel_config.ui.h:1 +msgid "Configure VoIP tunnel" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:2 +msgid "Host" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:3 +msgid "Port" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:6 +msgid "Configure tunnel" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:9 +msgid "Configure http proxy (optional)" +msgstr "" + +#: ../gtk/waiting.ui.h:2 +msgid "Please wait" +msgstr "Vänta" + +#: ../coreapi/linphonecore.c:1560 msgid "Ready" msgstr "Redo" -#: ../coreapi/linphonecore.c:2551 +#: ../coreapi/linphonecore.c:2556 msgid "Configuring" msgstr "" -#: ../coreapi/linphonecore.c:2725 -msgid "Looking for telephone number destination..." -msgstr "Leta efter telefonnummer för destinationen..." - -#: ../coreapi/linphonecore.c:2727 -msgid "Could not resolve this number." -msgstr "Kan inte nå dett nummer." - #. must be known at that time -#: ../coreapi/linphonecore.c:3013 +#: ../coreapi/linphonecore.c:2951 msgid "Contacting" msgstr "Kontaktar" -#: ../coreapi/linphonecore.c:3018 +#: ../coreapi/linphonecore.c:2956 msgid "Could not call" msgstr "" -#: ../coreapi/linphonecore.c:3169 +#: ../coreapi/linphonecore.c:3092 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "" -#: ../coreapi/linphonecore.c:3327 +#: ../coreapi/linphonecore.c:3250 msgid "is contacting you" msgstr "" -#: ../coreapi/linphonecore.c:3328 +#: ../coreapi/linphonecore.c:3251 msgid " and asked autoanswer." msgstr "" -#: ../coreapi/linphonecore.c:3452 +#: ../coreapi/linphonecore.c:3377 msgid "Modifying call parameters..." msgstr "" -#: ../coreapi/linphonecore.c:3802 +#: ../coreapi/linphonecore.c:3769 msgid "Connected." msgstr "Kopplad" -#: ../coreapi/linphonecore.c:3827 +#: ../coreapi/linphonecore.c:3794 msgid "Call aborted" msgstr "" -#: ../coreapi/linphonecore.c:4024 +#: ../coreapi/linphonecore.c:3983 msgid "Could not pause the call" msgstr "" -#: ../coreapi/linphonecore.c:4027 +#: ../coreapi/linphonecore.c:3986 msgid "Pausing the current call..." msgstr "" -#: ../coreapi/misc.c:434 +#: ../coreapi/misc.c:440 msgid "Stun lookup in progress..." msgstr "STUN uppslagning pågår..." -#: ../coreapi/misc.c:615 +#: ../coreapi/misc.c:650 msgid "ICE local candidates gathering in progress..." msgstr "" @@ -1815,166 +1879,173 @@ msgstr "" msgid "Unknown status" msgstr "" -#: ../coreapi/proxy.c:328 +#: ../coreapi/proxy.c:292 msgid "" "The sip proxy address you entered is invalid, it must start with \"sip:\" " "followed by a hostname." msgstr "SIP proxy adressen som du matade in är inte rätt, adressen måste starta med \"sip:\", följd av ett hostnamn" -#: ../coreapi/proxy.c:334 +#: ../coreapi/proxy.c:298 msgid "" "The sip identity you entered is invalid.\n" "It should look like sip:username@proxydomain, such as sip:alice@example.net" msgstr "SIP adressen som du matade in är inte rätt. Adressen borde se ut som sip:namn@domän, såsom sip:peter@exempel.se" -#: ../coreapi/proxy.c:1416 +#: ../coreapi/proxy.c:927 +msgid "Looking for telephone number destination..." +msgstr "Leta efter telefonnummer för destinationen..." + +#: ../coreapi/proxy.c:931 +msgid "Could not resolve this number." +msgstr "Kan inte nå dett nummer." + +#: ../coreapi/proxy.c:1324 #, c-format msgid "Could not login as %s" msgstr "Kunde inte logga in som %s" -#: ../coreapi/callbacks.c:428 +#: ../coreapi/proxy.c:1411 +#, c-format +msgid "Refreshing on %s..." +msgstr "" + +#: ../coreapi/callbacks.c:423 msgid "Remote ringing." msgstr "Ringer hos motparten." -#: ../coreapi/callbacks.c:440 +#: ../coreapi/callbacks.c:435 msgid "Remote ringing..." msgstr "" -#: ../coreapi/callbacks.c:461 +#: ../coreapi/callbacks.c:458 msgid "Early media." msgstr "Tidig media" -#: ../coreapi/callbacks.c:534 +#: ../coreapi/callbacks.c:488 #, c-format -msgid "Call with %s is paused." +msgid "Call answered by %s" msgstr "" -#: ../coreapi/callbacks.c:547 -#, c-format -msgid "Call answered by %s - on hold." -msgstr "" - -#: ../coreapi/callbacks.c:557 +#: ../coreapi/callbacks.c:527 msgid "Call resumed." msgstr "" -#: ../coreapi/callbacks.c:561 -#, c-format -msgid "Call answered by %s." -msgstr "" - -#: ../coreapi/callbacks.c:584 +#: ../coreapi/callbacks.c:582 msgid "Incompatible, check codecs or security settings..." msgstr "" -#: ../coreapi/callbacks.c:589 ../coreapi/callbacks.c:906 +#: ../coreapi/callbacks.c:587 ../coreapi/callbacks.c:923 msgid "Incompatible media parameters." msgstr "" -#: ../coreapi/callbacks.c:619 +#: ../coreapi/callbacks.c:612 msgid "We have been resumed." msgstr "" #. we are being paused -#: ../coreapi/callbacks.c:628 +#: ../coreapi/callbacks.c:620 msgid "We are paused by other party." msgstr "" -#. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:666 +#: ../coreapi/callbacks.c:630 msgid "Call is updated by remote." msgstr "" -#: ../coreapi/callbacks.c:782 +#: ../coreapi/callbacks.c:799 msgid "Call terminated." msgstr "Samtalet slut." -#: ../coreapi/callbacks.c:810 +#: ../coreapi/callbacks.c:827 msgid "User is busy." msgstr "Användare upptagen." -#: ../coreapi/callbacks.c:811 +#: ../coreapi/callbacks.c:828 msgid "User is temporarily unavailable." msgstr "Användaren temporärt inte tillgänglig." #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:813 +#: ../coreapi/callbacks.c:830 msgid "User does not want to be disturbed." msgstr "Användaren vill inte bli störd." -#: ../coreapi/callbacks.c:814 +#: ../coreapi/callbacks.c:831 msgid "Call declined." msgstr "Samtalet avböjdes." -#: ../coreapi/callbacks.c:829 +#: ../coreapi/callbacks.c:846 msgid "Request timeout." msgstr "" -#: ../coreapi/callbacks.c:860 +#: ../coreapi/callbacks.c:877 msgid "Redirected" msgstr "" -#: ../coreapi/callbacks.c:915 +#: ../coreapi/callbacks.c:927 msgid "Call failed." msgstr "" -#: ../coreapi/callbacks.c:993 +#: ../coreapi/callbacks.c:1005 #, c-format msgid "Registration on %s successful." msgstr "Registrering hos %s lyckades." -#: ../coreapi/callbacks.c:994 +#: ../coreapi/callbacks.c:1006 #, c-format msgid "Unregistration on %s done." msgstr "Avregistrering hos %s lyckades." -#: ../coreapi/callbacks.c:1012 +#: ../coreapi/callbacks.c:1024 msgid "no response timeout" msgstr "Inget svar inom angiven tid" -#: ../coreapi/callbacks.c:1015 +#: ../coreapi/callbacks.c:1027 #, c-format msgid "Registration on %s failed: %s" msgstr "Registrering hos %s mislyckades: %s" -#: ../coreapi/callbacks.c:1022 +#: ../coreapi/callbacks.c:1034 msgid "Service unavailable, retrying" msgstr "" #. if encryption is DTLS, no status to be displayed -#: ../coreapi/linphonecall.c:180 +#: ../coreapi/linphonecall.c:197 #, c-format msgid "Authentication token is %s" msgstr "" -#: ../coreapi/linphonecall.c:1310 +#: ../coreapi/linphonecall.c:1561 +#, c-format +msgid "Call parameters could not be modified: %s." +msgstr "" + +#: ../coreapi/linphonecall.c:1563 msgid "Call parameters were successfully modified." msgstr "" -#: ../coreapi/linphonecall.c:3686 +#: ../coreapi/linphonecall.c:4396 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." msgstr[0] "Du har %i missat samtal" msgstr[1] "Du har %i missade samtal" -#: ../coreapi/call_log.c:209 +#: ../coreapi/call_log.c:223 msgid "aborted" msgstr "" -#: ../coreapi/call_log.c:212 +#: ../coreapi/call_log.c:226 msgid "completed" msgstr "" -#: ../coreapi/call_log.c:215 +#: ../coreapi/call_log.c:229 msgid "missed" msgstr "" -#: ../coreapi/call_log.c:218 +#: ../coreapi/call_log.c:232 msgid "unknown" msgstr "" -#: ../coreapi/call_log.c:220 +#: ../coreapi/call_log.c:234 #, c-format msgid "" "%s at %s\n" @@ -1984,7 +2055,7 @@ msgid "" "Duration: %i mn %i sec\n" msgstr "" -#: ../coreapi/call_log.c:221 +#: ../coreapi/call_log.c:235 msgid "Outgoing call" msgstr "" diff --git a/po/tr.po b/po/tr.po index e2d9c815e..1a37a9d0f 100644 --- a/po/tr.po +++ b/po/tr.po @@ -8,74 +8,83 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-04-30 10:13+0200\n" -"PO-Revision-Date: 2015-04-30 08:13+0000\n" +"POT-Creation-Date: 2015-11-10 15:16+0100\n" +"PO-Revision-Date: 2015-11-10 14:16+0000\n" "Last-Translator: Belledonne Communications \n" -"Language-Team: Turkish (http://www.transifex.com/projects/p/linphone-gtk/language/tr/)\n" +"Language-Team: Turkish (http://www.transifex.com/belledonne-communications/linphone-gtk/language/tr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: tr\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: ../gtk/calllogs.c:148 ../gtk/friendlist.c:974 +#: ../gtk/calllogs.c:178 #, c-format msgid "Call %s" msgstr "" -#: ../gtk/calllogs.c:149 ../gtk/friendlist.c:975 +#: ../gtk/calllogs.c:179 #, c-format msgid "Send text to %s" msgstr "" -#: ../gtk/calllogs.c:232 +#: ../gtk/calllogs.c:181 #, c-format -msgid "Recent calls (%i)" +msgid "Add %s to your contact list" msgstr "" -#: ../gtk/calllogs.c:314 +#: ../gtk/calllogs.c:245 ../gtk/main.ui.h:21 +msgid "Recent calls" +msgstr "Son çağrılar" + +#: ../gtk/calllogs.c:260 +#, c-format +msgid "Recent calls (%i)" +msgstr "Son çağrılar (%i)" + +#: ../gtk/calllogs.c:331 msgid "n/a" msgstr "" -#: ../gtk/calllogs.c:317 +#: ../gtk/calllogs.c:334 msgid "Aborted" msgstr "İptal edildi" -#: ../gtk/calllogs.c:320 +#: ../gtk/calllogs.c:337 msgid "Missed" msgstr "Yanıtsız" -#: ../gtk/calllogs.c:323 +#: ../gtk/calllogs.c:340 msgid "Declined" msgstr "Reddedildi" -#: ../gtk/calllogs.c:329 +#: ../gtk/calllogs.c:346 #, c-format msgid "%i minute" msgid_plural "%i minutes" msgstr[0] "" msgstr[1] "" -#: ../gtk/calllogs.c:332 +#: ../gtk/calllogs.c:349 #, c-format msgid "%i second" msgid_plural "%i seconds" msgstr[0] "" msgstr[1] "" -#: ../gtk/calllogs.c:337 +#: ../gtk/calllogs.c:354 #, c-format msgid "" "%s\tQuality: %s\n" "%s\t%s\t" -msgstr "" +msgstr "%s\tKalite: %s\n%s\t%s\t" -#: ../gtk/calllogs.c:341 +#: ../gtk/calllogs.c:358 #, c-format msgid "%s\t%s" -msgstr "" +msgstr "%s\t%s" -#: ../gtk/conference.c:38 ../gtk/main.ui.h:13 +#: ../gtk/conference.c:38 ../gtk/in_call_frame.ui.h:11 msgid "Conference" msgstr "Grup görüşme" @@ -88,297 +97,314 @@ msgstr "" msgid "Couldn't find pixmap file: %s" msgstr "" -#: ../gtk/main.c:137 +#: ../gtk/chat.c:196 ../gtk/chat.c:254 +msgid "Sending..." +msgstr "" + +#: ../gtk/chat.c:213 ../gtk/chat.c:263 +msgid "Message not sent" +msgstr "İleti gitmedi" + +#: ../gtk/chat.c:472 +msgid "Copy" +msgstr "Kopya" + +#: ../gtk/main.c:138 msgid "log to stdout some debug information while running." msgstr "" -#: ../gtk/main.c:138 +#: ../gtk/main.c:139 +msgid "display version and exit." +msgstr "sürümü görüntüle ve çık." + +#: ../gtk/main.c:140 msgid "path to a file to write logs into." msgstr "Günlükleri içine yazmak için bir dosya yolu" -#: ../gtk/main.c:139 +#: ../gtk/main.c:141 msgid "Start linphone with video disabled." msgstr "Linphonu görüntü olmadan başlat" -#: ../gtk/main.c:140 +#: ../gtk/main.c:142 msgid "Start only in the system tray, do not show the main interface." msgstr "Sadece sistem tepsisinde başlat, ana arayüzü gösterme." -#: ../gtk/main.c:141 +#: ../gtk/main.c:143 msgid "address to call right now" msgstr "adres ara" -#: ../gtk/main.c:142 +#: ../gtk/main.c:144 msgid "" "Specifiy a working directory (should be the base of the installation, eg: " "c:\\Program Files\\Linphone)" msgstr "Bir çalışma dizini belirtin (kurulum temelinde olmalı,örneğin: c:\\Program Files\\Linphone)" -#: ../gtk/main.c:143 +#: ../gtk/main.c:145 msgid "Configuration file" msgstr "Yapılandırma dosyası" -#: ../gtk/main.c:144 +#: ../gtk/main.c:146 msgid "Run the audio assistant" msgstr "Ses yardımcısını çalıştır" -#: ../gtk/main.c:145 +#: ../gtk/main.c:147 msgid "Run self test and exit 0 if succeed" msgstr "" -#: ../gtk/main.c:1070 +#: ../gtk/main.c:1046 #, c-format msgid "" -"%s would like to add you to his contact list.\n" -"Would you allow him to see your presence status or add him to your contact list ?\n" +"%s would like to add you to his/her contact list.\n" +"Would you add him/her to your contact list and allow him/her to see your presence status?\n" "If you answer no, this person will be temporarily blacklisted." msgstr "" -#: ../gtk/main.c:1147 +#: ../gtk/main.c:1123 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" msgstr "" -#: ../gtk/main.c:1268 +#: ../gtk/main.c:1253 msgid "Call error" msgstr "Çağrı yanlış" -#: ../gtk/main.c:1271 ../coreapi/linphonecore.c:3846 +#: ../gtk/main.c:1256 ../coreapi/linphonecore.c:3813 msgid "Call ended" msgstr "Çağrı sonlandırıldı" -#: ../gtk/main.c:1274 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1259 ../coreapi/call_log.c:235 msgid "Incoming call" msgstr "Gelen çağrı" -#: ../gtk/main.c:1276 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1261 ../gtk/incall_view.c:580 ../gtk/in_call_frame.ui.h:2 msgid "Answer" msgstr "Yanıt" -#: ../gtk/main.c:1278 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1263 ../gtk/in_call_frame.ui.h:3 msgid "Decline" msgstr "Reddet" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 msgid "Call paused" msgstr "Çağrı duraklatıldı" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 #, c-format msgid "by %s" msgstr "" -#: ../gtk/main.c:1354 +#: ../gtk/main.c:1339 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "" -#: ../gtk/main.c:1509 +#: ../gtk/main.c:1505 msgid "Website link" msgstr "İnternet " -#: ../gtk/main.c:1568 ../gtk/waiting.ui.h:1 +#: ../gtk/main.c:1564 ../gtk/waiting.ui.h:1 msgid "Linphone" msgstr "Linphone" -#: ../gtk/main.c:1569 +#: ../gtk/main.c:1565 msgid "A video internet phone" -msgstr "" +msgstr "Görüntülü internet telefonu" -#: ../gtk/main.c:1629 +#: ../gtk/main.c:1624 #, c-format msgid "%s (Default)" msgstr "" -#: ../gtk/main.c:1962 ../coreapi/callbacks.c:1063 +#: ../gtk/main.c:1960 ../coreapi/callbacks.c:1075 #, c-format msgid "We are transferred to %s" msgstr "" -#: ../gtk/main.c:1972 +#: ../gtk/main.c:1970 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:2117 +#: ../gtk/main.c:2129 msgid "A free SIP video-phone" msgstr "Özgür bir SİP görüntülü-telefon" -#: ../gtk/main.c:2221 +#: ../gtk/main.c:2242 #, c-format msgid "Hello\n" msgstr "Merhaba\n" -#: ../gtk/friendlist.c:505 +#: ../gtk/friendlist.c:461 msgid "Add to addressbook" msgstr "Adres defterine ekle" -#: ../gtk/friendlist.c:691 -msgid "Presence status" -msgstr "durum bilgisi" - -#: ../gtk/friendlist.c:709 ../gtk/propertybox.c:569 ../gtk/contact.ui.h:1 -msgid "Name" -msgstr "Ad" - -#: ../gtk/friendlist.c:721 -msgid "Call" -msgstr "Çağrı" - -#: ../gtk/friendlist.c:726 -msgid "Chat" -msgstr "Söyleşi" - -#: ../gtk/friendlist.c:756 +#: ../gtk/friendlist.c:627 #, c-format msgid "Search in %s directory" msgstr "" -#: ../gtk/friendlist.c:924 +#: ../gtk/friendlist.c:772 msgid "Invalid sip contact !" msgstr "Geçersiz sip bağlantısı !" -#: ../gtk/friendlist.c:976 +#: ../gtk/friendlist.c:820 +#, c-format +msgid "Add a new contact" +msgstr "Yeni bir bağlantı ekle" + +#: ../gtk/friendlist.c:823 #, c-format msgid "Edit contact '%s'" msgstr "" -#: ../gtk/friendlist.c:977 +#: ../gtk/friendlist.c:824 #, c-format msgid "Delete contact '%s'" msgstr "" -#: ../gtk/friendlist.c:978 +#: ../gtk/friendlist.c:825 #, c-format msgid "Delete chat history of '%s'" msgstr "" -#: ../gtk/friendlist.c:1029 +#: ../gtk/friendlist.c:862 #, c-format msgid "Add new contact from %s directory" -msgstr "" +msgstr "%s dizininden yeni bağlantı ekle" -#: ../gtk/propertybox.c:575 +#: ../gtk/propertybox.c:592 ../gtk/contact.ui.h:1 +msgid "Name" +msgstr "Ad" + +#: ../gtk/propertybox.c:598 msgid "Rate (Hz)" msgstr "Hız (Hz)" -#: ../gtk/propertybox.c:581 +#: ../gtk/propertybox.c:604 msgid "Status" msgstr "Durum" -#: ../gtk/propertybox.c:587 +#: ../gtk/propertybox.c:617 msgid "IP Bitrate (kbit/s)" msgstr "İP Bit hızı (kbit/s)" -#: ../gtk/propertybox.c:596 +#: ../gtk/propertybox.c:628 msgid "Parameters" msgstr "Değişkenler" -#: ../gtk/propertybox.c:639 ../gtk/propertybox.c:782 +#: ../gtk/propertybox.c:670 ../gtk/propertybox.c:824 msgid "Enabled" msgstr "Etkin" -#: ../gtk/propertybox.c:641 ../gtk/propertybox.c:782 ../gtk/parameters.ui.h:20 +#: ../gtk/propertybox.c:672 ../gtk/propertybox.c:824 ../gtk/parameters.ui.h:60 msgid "Disabled" msgstr "Devre dışı" -#: ../gtk/propertybox.c:828 +#: ../gtk/propertybox.c:902 msgid "Account" msgstr "Hesap" -#: ../gtk/propertybox.c:1091 +#: ../gtk/propertybox.c:1170 msgid "English" msgstr "İngilizce" -#: ../gtk/propertybox.c:1092 +#: ../gtk/propertybox.c:1171 msgid "French" msgstr "Fransızca" -#: ../gtk/propertybox.c:1093 +#: ../gtk/propertybox.c:1172 msgid "Swedish" msgstr "İsveççe" -#: ../gtk/propertybox.c:1094 +#: ../gtk/propertybox.c:1173 msgid "Italian" msgstr "İtalyanca" -#: ../gtk/propertybox.c:1095 +#: ../gtk/propertybox.c:1174 msgid "Spanish" msgstr "İspanyolca" -#: ../gtk/propertybox.c:1096 +#: ../gtk/propertybox.c:1175 msgid "Brazilian Portugese" msgstr "Brezilya Portekizcesi" -#: ../gtk/propertybox.c:1097 +#: ../gtk/propertybox.c:1176 msgid "Polish" msgstr "Lehçe" -#: ../gtk/propertybox.c:1098 +#: ../gtk/propertybox.c:1177 msgid "German" msgstr "Almanca" -#: ../gtk/propertybox.c:1099 +#: ../gtk/propertybox.c:1178 msgid "Russian" msgstr "Rusca" -#: ../gtk/propertybox.c:1100 +#: ../gtk/propertybox.c:1179 msgid "Japanese" msgstr "Japonca" -#: ../gtk/propertybox.c:1101 +#: ../gtk/propertybox.c:1180 msgid "Dutch" msgstr "Flemenkçe" -#: ../gtk/propertybox.c:1102 +#: ../gtk/propertybox.c:1181 msgid "Hungarian" msgstr "Macarca" -#: ../gtk/propertybox.c:1103 +#: ../gtk/propertybox.c:1182 msgid "Czech" msgstr "Çekce" -#: ../gtk/propertybox.c:1104 +#: ../gtk/propertybox.c:1183 msgid "Chinese" msgstr "Çince" -#: ../gtk/propertybox.c:1105 +#: ../gtk/propertybox.c:1184 msgid "Traditional Chinese" msgstr "Geleneksel Çince" -#: ../gtk/propertybox.c:1106 +#: ../gtk/propertybox.c:1185 msgid "Norwegian" msgstr "Norveççe" -#: ../gtk/propertybox.c:1107 +#: ../gtk/propertybox.c:1186 msgid "Hebrew" msgstr "İbranice" -#: ../gtk/propertybox.c:1108 +#: ../gtk/propertybox.c:1187 msgid "Serbian" msgstr "Sırpça" -#: ../gtk/propertybox.c:1175 +#: ../gtk/propertybox.c:1188 +msgid "Arabic" +msgstr "Arapça" + +#: ../gtk/propertybox.c:1189 +msgid "Turkish" +msgstr "Türkçe" + +#: ../gtk/propertybox.c:1246 msgid "" "You need to restart linphone for the new language selection to take effect." msgstr "Yeni dil seçiminizin etkili olabilmesi için linfonu yeniden başlatmalısınız." -#: ../gtk/propertybox.c:1255 +#: ../gtk/propertybox.c:1326 msgid "None" msgstr "Hiçbiri" -#: ../gtk/propertybox.c:1259 +#: ../gtk/propertybox.c:1330 msgid "SRTP" msgstr "SRTP (Güvenli Gerçek Zamanlı Aktarım Protokolü)" -#: ../gtk/propertybox.c:1265 +#: ../gtk/propertybox.c:1336 msgid "DTLS" msgstr "DTLS" -#: ../gtk/propertybox.c:1272 +#: ../gtk/propertybox.c:1343 msgid "ZRTP" msgstr "ZRTP" @@ -395,7 +421,7 @@ msgstr "En son sürümü çalıştırıyorsunuz" #: ../gtk/buddylookup.c:85 msgid "Firstname, Lastname" -msgstr "" +msgstr "İlk ad, Son ad" #: ../gtk/buddylookup.c:160 msgid "Error communicating with server." @@ -420,324 +446,195 @@ msgid_plural "Found %i contacts" msgstr[0] "" msgstr[1] "" -#: ../gtk/setupwizard.c:32 -msgid "" -"Welcome!\n" -"This assistant will help you to use a SIP account for your calls." -msgstr "Hoşgeldiniz!\nBu yardımcı,çağrılarınız için bir SIP hesabı kullanmanıza yardım edecek." - -#: ../gtk/setupwizard.c:41 -msgid "Create an account on linphone.org" -msgstr "linphone.org'da bir hesap oluştur" - -#: ../gtk/setupwizard.c:42 -msgid "I have already a linphone.org account and I just want to use it" -msgstr "" - -#: ../gtk/setupwizard.c:43 -msgid "I have already a sip account and I just want to use it" -msgstr "" - -#: ../gtk/setupwizard.c:44 -msgid "I want to specify a remote configuration URI" -msgstr "" - -#: ../gtk/setupwizard.c:87 -msgid "Enter your linphone.org username" -msgstr "linphone.org kullanıcı adınızı girin" - -#: ../gtk/setupwizard.c:100 ../gtk/parameters.ui.h:85 ../gtk/ldap.ui.h:4 -msgid "Username:" -msgstr "Kullanıcı adı:" - -#: ../gtk/setupwizard.c:102 ../gtk/password.ui.h:4 ../gtk/ldap.ui.h:5 -msgid "Password:" -msgstr "Parola:" - -#: ../gtk/setupwizard.c:122 -msgid "Enter your account informations" -msgstr "Hesap bilgilerinizi girin" - -#: ../gtk/setupwizard.c:138 -msgid "Username*" -msgstr "Kallanıcı adı*" - -#: ../gtk/setupwizard.c:139 -msgid "Password*" -msgstr "Parola*" - -#: ../gtk/setupwizard.c:142 -msgid "Domain*" -msgstr "Alan adı*" - -#: ../gtk/setupwizard.c:143 -msgid "Proxy" -msgstr "Vekil sunucu" - -#: ../gtk/setupwizard.c:322 -msgid "(*) Required fields" -msgstr "(*) Zorunlu alanlar" - -#: ../gtk/setupwizard.c:323 -msgid "Username: (*)" -msgstr "Kullanıcı adı: (*)" - -#: ../gtk/setupwizard.c:325 -msgid "Password: (*)" -msgstr "Parola: (*)" - -#: ../gtk/setupwizard.c:327 -msgid "Email: (*)" -msgstr "E-posta: (*)" - -#: ../gtk/setupwizard.c:329 -msgid "Confirm your password: (*)" -msgstr "Parolanızı onaylayın: (*)" - -#: ../gtk/setupwizard.c:343 -msgid "Keep me informed with linphone updates" -msgstr "linphone güncellemeleri hakkında beni bilgilendir" - -#: ../gtk/setupwizard.c:399 -msgid "" -"Error, account not validated, username already used or server unreachable.\n" -"Please go back and try again." -msgstr "Hata,hesap geçersiz,kullanıcı adı kullanılıyor veya sunucuya erişilemiyor.\nLütfen geri dönün ve tekrar deneyin." - -#: ../gtk/setupwizard.c:410 -msgid "Thank you. Your account is now configured and ready for use." -msgstr "Teşekkürler. Hesabınız yapılandırıldı ve kullanıma hazır." - -#: ../gtk/setupwizard.c:418 -msgid "" -"Please validate your account by clicking on the link we just sent you by email.\n" -"Then come back here and press Next button." -msgstr "Lütfen size e-posta yoluyla gönderdiğimiz bağlantıyı tıklayarak hesabınızı doğrulayın.\nSonra buraya geri dönün ve İleri düğmesine basın." - -#: ../gtk/setupwizard.c:609 -msgid "SIP account configuration assistant" -msgstr "SİP hesabı yapılandırma yardımcısı" - -#: ../gtk/setupwizard.c:629 -msgid "Welcome to the account setup assistant" -msgstr "Hesap açma yardımcısına hoşgeldiniz" - -#: ../gtk/setupwizard.c:634 -msgid "Account setup assistant" -msgstr "Hesap açma yardımcısı" - -#: ../gtk/setupwizard.c:640 -msgid "Configure your account (step 1/1)" -msgstr "Hesabınızı yapılandırın (adım 1/1)" - -#: ../gtk/setupwizard.c:645 -msgid "Enter your sip username (step 1/1)" -msgstr "sip kullanıcı adınızı girin (adım 1/1)" - -#: ../gtk/setupwizard.c:649 -msgid "Enter account information (step 1/2)" -msgstr "Hesap bilgilerini girin (adım 1/2)" - -#: ../gtk/setupwizard.c:658 -msgid "Validation (step 2/2)" -msgstr "Doğrulama (adım 2/2)" - -#: ../gtk/setupwizard.c:663 -msgid "Error" -msgstr "Hata" - -#: ../gtk/setupwizard.c:667 ../gtk/audio_assistant.c:534 -msgid "Terminating" -msgstr "Sonlandırma" - -#: ../gtk/incall_view.c:70 ../gtk/incall_view.c:94 +#: ../gtk/incall_view.c:67 ../gtk/incall_view.c:87 #, c-format msgid "Call #%i" msgstr "" -#: ../gtk/incall_view.c:155 +#: ../gtk/incall_view.c:145 #, c-format msgid "Transfer to call #%i with %s" msgstr "" -#: ../gtk/incall_view.c:211 ../gtk/incall_view.c:214 +#: ../gtk/incall_view.c:202 ../gtk/incall_view.c:205 msgid "Not used" msgstr "Kullanılmıyor" -#: ../gtk/incall_view.c:221 +#: ../gtk/incall_view.c:212 msgid "ICE not activated" msgstr "ICE etkin değil" -#: ../gtk/incall_view.c:223 +#: ../gtk/incall_view.c:214 msgid "ICE failed" msgstr "ICE başarısız" -#: ../gtk/incall_view.c:225 +#: ../gtk/incall_view.c:216 msgid "ICE in progress" msgstr "ICE sürüyor" -#: ../gtk/incall_view.c:227 +#: ../gtk/incall_view.c:218 msgid "Going through one or more NATs" msgstr "" -#: ../gtk/incall_view.c:229 +#: ../gtk/incall_view.c:220 msgid "Direct" -msgstr "" +msgstr "Doğrudan" -#: ../gtk/incall_view.c:231 +#: ../gtk/incall_view.c:222 msgid "Through a relay server" msgstr "" -#: ../gtk/incall_view.c:239 +#: ../gtk/incall_view.c:230 msgid "uPnP not activated" msgstr "Evrensel Tak-Çalıştır etkin değil" -#: ../gtk/incall_view.c:241 +#: ../gtk/incall_view.c:232 msgid "uPnP in progress" msgstr "Evrensel Tak-Çalıştır ilerliyor" -#: ../gtk/incall_view.c:243 +#: ../gtk/incall_view.c:234 msgid "uPnp not available" msgstr "Evrensel Tak-Çalıştır kullanılamaz" -#: ../gtk/incall_view.c:245 +#: ../gtk/incall_view.c:236 msgid "uPnP is running" msgstr "Evrensel Tak-Çalıştır çalışıyor" -#: ../gtk/incall_view.c:247 +#: ../gtk/incall_view.c:238 msgid "uPnP failed" msgstr "Evrensel Tak-Çalıştır başarısız" -#: ../gtk/incall_view.c:257 ../gtk/incall_view.c:258 +#: ../gtk/incall_view.c:248 ../gtk/incall_view.c:249 msgid "Direct or through server" msgstr "" -#: ../gtk/incall_view.c:267 ../gtk/incall_view.c:279 +#: ../gtk/incall_view.c:258 ../gtk/incall_view.c:270 #, c-format msgid "" "download: %f\n" "upload: %f (kbit/s)" msgstr "" -#: ../gtk/incall_view.c:272 ../gtk/incall_view.c:274 +#: ../gtk/incall_view.c:263 ../gtk/incall_view.c:265 #, c-format msgid "%ix%i @ %f fps" msgstr "" -#: ../gtk/incall_view.c:304 +#: ../gtk/incall_view.c:295 #, c-format msgid "%.3f seconds" msgstr "" -#: ../gtk/incall_view.c:407 ../gtk/main.ui.h:12 ../gtk/videowindow.c:235 +#: ../gtk/incall_view.c:453 ../gtk/in_call_frame.ui.h:10 +#: ../gtk/videowindow.c:236 msgid "Hang up" msgstr "Telefonu kapatma" -#: ../gtk/incall_view.c:511 +#: ../gtk/incall_view.c:559 msgid "Calling..." msgstr "" -#: ../gtk/incall_view.c:514 ../gtk/incall_view.c:733 -msgid "00::00::00" -msgstr "00::00::00" +#: ../gtk/incall_view.c:562 ../gtk/incall_view.c:792 +msgid "00:00:00" +msgstr "00:00:00" -#: ../gtk/incall_view.c:525 +#: ../gtk/incall_view.c:573 msgid "Incoming call" msgstr "" -#: ../gtk/incall_view.c:562 +#: ../gtk/incall_view.c:610 msgid "good" msgstr "iyi" -#: ../gtk/incall_view.c:564 +#: ../gtk/incall_view.c:612 msgid "average" msgstr "orta" -#: ../gtk/incall_view.c:566 +#: ../gtk/incall_view.c:614 msgid "poor" msgstr "kötü" -#: ../gtk/incall_view.c:568 +#: ../gtk/incall_view.c:616 msgid "very poor" msgstr "çok kötü" -#: ../gtk/incall_view.c:570 +#: ../gtk/incall_view.c:618 msgid "too bad" msgstr "" -#: ../gtk/incall_view.c:571 ../gtk/incall_view.c:587 +#: ../gtk/incall_view.c:619 ../gtk/incall_view.c:635 msgid "unavailable" msgstr "kullanılamaz" -#: ../gtk/incall_view.c:679 +#: ../gtk/incall_view.c:731 msgid "Secured by SRTP" msgstr "SRTP güvencesi altında" -#: ../gtk/incall_view.c:685 +#: ../gtk/incall_view.c:737 msgid "Secured by DTLS" msgstr "DLTS güvencesi altında" -#: ../gtk/incall_view.c:691 +#: ../gtk/incall_view.c:743 #, c-format msgid "Secured by ZRTP - [auth token: %s]" msgstr "" -#: ../gtk/incall_view.c:697 +#: ../gtk/incall_view.c:747 msgid "Set unverified" -msgstr "" +msgstr "Doğrulanmamış ayar" -#: ../gtk/incall_view.c:697 ../gtk/main.ui.h:4 +#: ../gtk/incall_view.c:747 msgid "Set verified" -msgstr "" +msgstr "Doğrulanmış ayar" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In conference" msgstr "" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In call" msgstr "" -#: ../gtk/incall_view.c:764 +#: ../gtk/incall_view.c:824 msgid "Paused call" msgstr "" -#: ../gtk/incall_view.c:800 +#: ../gtk/incall_view.c:861 msgid "Call ended." msgstr "" -#: ../gtk/incall_view.c:831 +#: ../gtk/incall_view.c:892 msgid "Transfer in progress" msgstr "Aktarım sürüyor" -#: ../gtk/incall_view.c:834 +#: ../gtk/incall_view.c:895 msgid "Transfer done." msgstr "Aktarım tamam" -#: ../gtk/incall_view.c:837 +#: ../gtk/incall_view.c:898 msgid "Transfer failed." msgstr "Aktarım başarısız" -#: ../gtk/incall_view.c:881 +#: ../gtk/incall_view.c:929 msgid "Resume" msgstr "Devam et" -#: ../gtk/incall_view.c:888 ../gtk/main.ui.h:9 +#: ../gtk/incall_view.c:929 ../gtk/in_call_frame.ui.h:7 msgid "Pause" msgstr "Duraklat" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 #, c-format msgid "" "Recording into\n" "%s %s" msgstr "" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 msgid "(Paused)" msgstr "(Duraklatıldı)" -#: ../gtk/loginframe.c:87 +#: ../gtk/loginframe.c:75 #, c-format msgid "Please enter login information for %s" msgstr "" @@ -752,263 +649,108 @@ msgstr "" msgid "Downloading of remote configuration from %s failed." msgstr "" -#: ../gtk/audio_assistant.c:98 +#: ../gtk/audio_assistant.c:103 msgid "No voice detected" msgstr "Ses olmadığı algılandı" -#: ../gtk/audio_assistant.c:99 +#: ../gtk/audio_assistant.c:104 msgid "Too low" msgstr "Çok düşük" -#: ../gtk/audio_assistant.c:100 +#: ../gtk/audio_assistant.c:105 msgid "Good" msgstr "İyi" -#: ../gtk/audio_assistant.c:101 +#: ../gtk/audio_assistant.c:106 msgid "Too loud" msgstr "Çok yüksek" -#: ../gtk/audio_assistant.c:183 +#: ../gtk/audio_assistant.c:188 msgid "Did you hear three beeps ?" msgstr "Üç bip sesi duydun mu?" -#: ../gtk/audio_assistant.c:292 ../gtk/audio_assistant.c:297 +#: ../gtk/audio_assistant.c:299 ../gtk/audio_assistant.c:304 msgid "Sound preferences not found " msgstr "Ses tercihleri bulunamadı" -#: ../gtk/audio_assistant.c:306 +#: ../gtk/audio_assistant.c:313 msgid "Cannot launch system sound control " msgstr "Ses kontrol sistemi başlatılamıyor" -#: ../gtk/audio_assistant.c:318 +#: ../gtk/audio_assistant.c:325 msgid "" "Welcome!\n" "This assistant will help you to configure audio settings for Linphone" msgstr "Hoşgeldiniz!\nBu yardımcı,Linphone'un ses ayarlarını yapılandırmanıza yardım edecek" -#: ../gtk/audio_assistant.c:328 +#: ../gtk/audio_assistant.c:335 msgid "Capture device" msgstr "Görüntü yakalama aygıtı" -#: ../gtk/audio_assistant.c:329 +#: ../gtk/audio_assistant.c:336 msgid "Recorded volume" msgstr "" -#: ../gtk/audio_assistant.c:333 +#: ../gtk/audio_assistant.c:340 msgid "No voice" msgstr "Ses yok" -#: ../gtk/audio_assistant.c:334 ../gtk/audio_assistant.c:373 +#: ../gtk/audio_assistant.c:341 ../gtk/audio_assistant.c:380 msgid "System sound preferences" msgstr "Sistem ses tercihleri" -#: ../gtk/audio_assistant.c:369 +#: ../gtk/audio_assistant.c:376 msgid "Playback device" msgstr "Oynatma aygıtı" -#: ../gtk/audio_assistant.c:370 +#: ../gtk/audio_assistant.c:377 msgid "Play three beeps" msgstr "Üç bip sesi çal" -#: ../gtk/audio_assistant.c:403 +#: ../gtk/audio_assistant.c:410 msgid "Press the record button and say some words" msgstr "Kayıt tuşuna bas ve bazı kelimeler söyle" -#: ../gtk/audio_assistant.c:404 +#: ../gtk/audio_assistant.c:411 msgid "Listen to your record voice" msgstr "Kaydettiğin sesi dinle" -#: ../gtk/audio_assistant.c:405 +#: ../gtk/audio_assistant.c:412 ../gtk/conf_frame.ui.h:2 +#: ../gtk/in_call_frame.ui.h:4 msgid "Record" msgstr "Kayıt" -#: ../gtk/audio_assistant.c:406 +#: ../gtk/audio_assistant.c:413 msgid "Play" msgstr "Çalma" -#: ../gtk/audio_assistant.c:433 +#: ../gtk/audio_assistant.c:440 msgid "Let's start Linphone now" -msgstr "" +msgstr "Haydi şimdi Linphona başlayalım" -#: ../gtk/audio_assistant.c:503 +#: ../gtk/audio_assistant.c:510 msgid "Audio Assistant" msgstr "Ses Yardımcısı" -#: ../gtk/audio_assistant.c:513 ../gtk/main.ui.h:32 +#: ../gtk/audio_assistant.c:520 ../gtk/main.ui.h:13 msgid "Audio assistant" msgstr "Ses yardımcısı" -#: ../gtk/audio_assistant.c:518 +#: ../gtk/audio_assistant.c:525 msgid "Mic Gain calibration" msgstr "" -#: ../gtk/audio_assistant.c:524 +#: ../gtk/audio_assistant.c:531 msgid "Speaker volume calibration" msgstr "" -#: ../gtk/audio_assistant.c:529 +#: ../gtk/audio_assistant.c:536 msgid "Record and Play" -msgstr "" +msgstr "Kaydet ve Oynat" -#: ../gtk/main.ui.h:1 -msgid "Callee name" -msgstr "" - -#: ../gtk/main.ui.h:2 -msgid "Send" -msgstr "Gönder" - -#: ../gtk/main.ui.h:3 -msgid "End conference" -msgstr "" - -#: ../gtk/main.ui.h:7 -msgid "Record this call to an audio file" -msgstr "" - -#: ../gtk/main.ui.h:8 -msgid "Video" -msgstr "Görüntü" - -#: ../gtk/main.ui.h:10 -msgid "Mute" -msgstr "Sessiz" - -#: ../gtk/main.ui.h:11 -msgid "Transfer" -msgstr "Aktarım" - -#: ../gtk/main.ui.h:14 -msgid "In call" -msgstr "" - -#: ../gtk/main.ui.h:15 -msgid "Duration" -msgstr "Süre" - -#: ../gtk/main.ui.h:16 -msgid "Call quality rating" -msgstr "" - -#: ../gtk/main.ui.h:17 -msgid "All users" -msgstr "Tüm kullanıcılar" - -#: ../gtk/main.ui.h:18 -msgid "Online users" -msgstr "Çevrimiçi kullanıcılar" - -#: ../gtk/main.ui.h:19 -msgid "ADSL" -msgstr "ADSL" - -#: ../gtk/main.ui.h:20 -msgid "Fiber Channel" -msgstr "" - -#: ../gtk/main.ui.h:21 -msgid "Default" -msgstr "Öntanımlı" - -#: ../gtk/main.ui.h:22 -msgid "Delete" -msgstr "Sil" - -#: ../gtk/main.ui.h:23 -msgid "_Options" -msgstr "_Seçenekler" - -#: ../gtk/main.ui.h:24 -msgid "Set configuration URI" -msgstr "" - -#: ../gtk/main.ui.h:25 -msgid "Always start video" -msgstr "" - -#: ../gtk/main.ui.h:26 -msgid "Enable self-view" -msgstr "" - -#: ../gtk/main.ui.h:27 -msgid "_Help" -msgstr "_Yardım" - -#: ../gtk/main.ui.h:28 -msgid "Show debug window" -msgstr "Hata düzeltme penceresini göster" - -#: ../gtk/main.ui.h:29 -msgid "_Homepage" -msgstr "_Anasayfa" - -#: ../gtk/main.ui.h:30 -msgid "Check _Updates" -msgstr "Güncellemeleri _Denetle" - -#: ../gtk/main.ui.h:31 -msgid "Account assistant" -msgstr "Hesap yardımcısı" - -#: ../gtk/main.ui.h:33 -msgid "SIP address or phone number:" -msgstr "SİP adresi veya telefon numarası:" - -#: ../gtk/main.ui.h:34 -msgid "Initiate a new call" -msgstr "Yeni bir arama başlat" - -#: ../gtk/main.ui.h:35 -msgid "Contacts" -msgstr "Bağlantılar" - -#: ../gtk/main.ui.h:36 -msgid "Search" -msgstr "Arama" - -#: ../gtk/main.ui.h:37 -msgid "Add contacts from directory" -msgstr "" - -#: ../gtk/main.ui.h:38 -msgid "Add contact" -msgstr "Bağlantı ekle" - -#: ../gtk/main.ui.h:39 -msgid "Recent calls" -msgstr "Son çağrılar" - -#: ../gtk/main.ui.h:40 -msgid "My current identity:" -msgstr "" - -#: ../gtk/main.ui.h:41 ../gtk/tunnel_config.ui.h:7 -msgid "Username" -msgstr "Kallanıcı adı" - -#: ../gtk/main.ui.h:42 ../gtk/tunnel_config.ui.h:8 -msgid "Password" -msgstr "Parola" - -#: ../gtk/main.ui.h:43 -msgid "Internet connection:" -msgstr "İnternet bağlantısı:" - -#: ../gtk/main.ui.h:44 -msgid "Automatically log me in" -msgstr "" - -#: ../gtk/main.ui.h:45 ../gtk/password.ui.h:3 -msgid "UserID" -msgstr "Kullanıcı kimliği" - -#: ../gtk/main.ui.h:46 -msgid "Login information" -msgstr "" - -#: ../gtk/main.ui.h:47 -msgid "Welcome!" -msgstr "Hoşgeldiniz!" +#: ../gtk/audio_assistant.c:541 ../gtk/setup_wizard.ui.h:38 +msgid "Terminating" +msgstr "Sonlandırma" #: ../gtk/about.ui.h:1 msgid "About Linphone" @@ -1038,6 +780,100 @@ msgid "" "he: Eli Zaretskii \n" msgstr "fr: Simon Morlat\nen: Simon Morlat and Delphine Perreau\nit: Alberto Zanoni \nde: Jean-Jacques Sarton \nsv: Daniel Nylander \nes: Jesus Benitez \nja: YAMAGUCHI YOSHIYA \npt_BR: Rafael Caesar Lenzi \npl: Robert Nasiadek \ncs: Petr Pisar \nhu: anonymous\nhe: Eli Zaretskii \n" +#: ../gtk/buddylookup.ui.h:1 +msgid "Search contacts in directory" +msgstr "Dizinde bağlantılar ara" + +#: ../gtk/buddylookup.ui.h:2 +msgid "Add to my list" +msgstr "Listeme ekle" + +#: ../gtk/buddylookup.ui.h:3 +msgid "Search somebody" +msgstr "" + +#: ../gtk/callee_frame.ui.h:1 +msgid "Callee name" +msgstr "" + +#: ../gtk/call_logs.ui.h:1 +msgid "Call history" +msgstr "Çağrı geçmişi" + +#: ../gtk/call_logs.ui.h:2 +msgid "Clear all" +msgstr "Hepsini temizle" + +#: ../gtk/call_logs.ui.h:3 +msgid "Call back" +msgstr "Geri arama" + +#: ../gtk/call_statistics.ui.h:1 +msgid "Call statistics" +msgstr "Çağrı istatistikleri" + +#: ../gtk/call_statistics.ui.h:2 +msgid "Audio codec" +msgstr "Ses çözücü" + +#: ../gtk/call_statistics.ui.h:3 +msgid "Video codec" +msgstr "Görüntü çözücü" + +#: ../gtk/call_statistics.ui.h:4 +msgid "Audio IP bandwidth usage" +msgstr "" + +#: ../gtk/call_statistics.ui.h:5 +msgid "Audio Media connectivity" +msgstr "Ses Ortamı bağlanırlığı" + +#: ../gtk/call_statistics.ui.h:6 +msgid "Video IP bandwidth usage" +msgstr "" + +#: ../gtk/call_statistics.ui.h:7 +msgid "Video Media connectivity" +msgstr "Görüntü Ortamı bağlanırlığı" + +#: ../gtk/call_statistics.ui.h:8 +msgid "Round trip time" +msgstr "Sinyal gidiş-dönüş süresi" + +#: ../gtk/call_statistics.ui.h:9 +msgid "Video resolution received" +msgstr "Alınan görüntü çözünürlüğü" + +#: ../gtk/call_statistics.ui.h:10 +msgid "Video resolution sent" +msgstr "Giden görüntü çözünürlüğü" + +#: ../gtk/call_statistics.ui.h:11 +msgid "RTP profile" +msgstr "" + +#: ../gtk/call_statistics.ui.h:12 +msgid "Call statistics and information" +msgstr "" + +#: ../gtk/chatroom_frame.ui.h:1 +msgid "Send" +msgstr "Gönder" + +#: ../gtk/conf_frame.ui.h:1 +msgid "End conference" +msgstr "Grup görüşme son" + +#: ../gtk/config-uri.ui.h:1 +msgid "Specifying a remote configuration URI" +msgstr "" + +#: ../gtk/config-uri.ui.h:2 +msgid "" +"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" +"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " +msgstr "" + #: ../gtk/contact.ui.h:2 msgid "SIP Address" msgstr "SİP Adresi" @@ -1054,6 +890,199 @@ msgstr "" msgid "Contact information" msgstr "Bağlantı bilgisi" +#: ../gtk/dscp_settings.ui.h:1 +msgid "DSCP settings" +msgstr "DSCP ayarları" + +#: ../gtk/dscp_settings.ui.h:2 +msgid "SIP" +msgstr "SİP" + +#: ../gtk/dscp_settings.ui.h:3 +msgid "Audio RTP stream" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:4 +msgid "Video RTP stream" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:5 +msgid "Set DSCP values (in hexadecimal)" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:1 +msgid "Click here to set the speakers volume" +msgstr "Hoparlör ses miktarı ayarı için buraya tıkla" + +#: ../gtk/in_call_frame.ui.h:5 +msgid "Record this call to an audio file" +msgstr "Bu aramayı bir ses dosyasına kaydet" + +#: ../gtk/in_call_frame.ui.h:6 +msgid "Video" +msgstr "Görüntü" + +#: ../gtk/in_call_frame.ui.h:8 +msgid "Mute" +msgstr "Sessiz" + +#: ../gtk/in_call_frame.ui.h:9 +msgid "Transfer" +msgstr "Aktarım" + +#: ../gtk/in_call_frame.ui.h:12 +msgid "In call" +msgstr "arıyor" + +#: ../gtk/in_call_frame.ui.h:13 +msgid "Duration" +msgstr "Süre" + +#: ../gtk/in_call_frame.ui.h:14 +msgid "Call quality rating" +msgstr "" + +#: ../gtk/ldap.ui.h:1 +msgid "LDAP Settings" +msgstr "LDAP Ayarları" + +#: ../gtk/ldap.ui.h:2 ../gtk/parameters.ui.h:89 +msgid "Server address:" +msgstr "Sunucu adresi:" + +#: ../gtk/ldap.ui.h:3 ../gtk/parameters.ui.h:90 +msgid "Authentication method:" +msgstr "Kimlik doğrulama yöntemi:" + +#: ../gtk/ldap.ui.h:4 ../gtk/parameters.ui.h:91 ../gtk/setup_wizard.ui.h:17 +msgid "Username:" +msgstr "Kullanıcı adı:" + +#: ../gtk/ldap.ui.h:5 ../gtk/password.ui.h:4 ../gtk/setup_wizard.ui.h:18 +msgid "Password:" +msgstr "Parola:" + +#: ../gtk/ldap.ui.h:6 +msgid "Use TLS Connection" +msgstr "TLS Bağlantısı Kullan" + +#: ../gtk/ldap.ui.h:7 +msgid "Not yet available" +msgstr "Henüz kullanılabilir değil" + +#: ../gtk/ldap.ui.h:8 +msgid "Connection" +msgstr "" + +#: ../gtk/ldap.ui.h:9 +msgid "Bind DN" +msgstr "" + +#: ../gtk/ldap.ui.h:10 +msgid "Authname" +msgstr "" + +#: ../gtk/ldap.ui.h:11 +msgid "Realm" +msgstr "Ülke" + +#: ../gtk/ldap.ui.h:12 +msgid "SASL" +msgstr "" + +#: ../gtk/ldap.ui.h:13 +msgid "Base object:" +msgstr "Temel nesne:" + +#: ../gtk/ldap.ui.h:15 +#, no-c-format +msgid "Filter (%s for name):" +msgstr "" + +#: ../gtk/ldap.ui.h:16 +msgid "Name Attribute:" +msgstr "Öznitelik Adı:" + +#: ../gtk/ldap.ui.h:17 +msgid "SIP address attribute:" +msgstr "" + +#: ../gtk/ldap.ui.h:18 +msgid "Attributes to query:" +msgstr "" + +#: ../gtk/ldap.ui.h:19 +msgid "Search" +msgstr "Ara" + +#: ../gtk/ldap.ui.h:20 +msgid "Timeout for search:" +msgstr "" + +#: ../gtk/ldap.ui.h:21 +msgid "Max results:" +msgstr "En çok sonuç:" + +#: ../gtk/ldap.ui.h:22 +msgid "Follow Aliases" +msgstr "" + +#: ../gtk/ldap.ui.h:23 +msgid "Miscellaneous" +msgstr "Çeşitli" + +#: ../gtk/ldap.ui.h:24 +msgid "ANONYMOUS" +msgstr "" + +#: ../gtk/ldap.ui.h:25 +msgid "SIMPLE" +msgstr "" + +#: ../gtk/ldap.ui.h:26 +msgid "DIGEST-MD5" +msgstr "" + +#: ../gtk/ldap.ui.h:27 +msgid "NTLM" +msgstr "" + +#: ../gtk/login_frame.ui.h:1 ../gtk/tunnel_config.ui.h:7 +msgid "Username" +msgstr "Kallanıcı adı" + +#: ../gtk/login_frame.ui.h:2 ../gtk/tunnel_config.ui.h:8 +msgid "Password" +msgstr "Parola" + +#: ../gtk/login_frame.ui.h:3 +msgid "Internet connection:" +msgstr "İnternet bağlantısı:" + +#: ../gtk/login_frame.ui.h:4 +msgid "Automatically log me in" +msgstr "" + +#: ../gtk/login_frame.ui.h:5 ../gtk/password.ui.h:3 +msgid "UserID" +msgstr "Kullanıcı kimliği" + +#: ../gtk/login_frame.ui.h:6 +msgid "Login information" +msgstr "Giriş bilgisi" + +#: ../gtk/login_frame.ui.h:7 +msgid "Welcome!" +msgstr "Hoşgeldiniz!" + +#: ../gtk/login_frame.ui.h:8 +msgid "ADSL" +msgstr "ADSL" + +#: ../gtk/login_frame.ui.h:9 +msgid "Fiber Channel" +msgstr "" + #: ../gtk/log.ui.h:1 msgid "Linphone debug window" msgstr "Linphone hata giderme penceresi" @@ -1062,6 +1091,452 @@ msgstr "Linphone hata giderme penceresi" msgid "Scroll to end" msgstr "Sonuna kadar ilerleyin" +#: ../gtk/main.ui.h:1 +msgid "Default" +msgstr "Öntanımlı" + +#: ../gtk/main.ui.h:2 +msgid "Delete" +msgstr "Sil" + +#: ../gtk/main.ui.h:3 +msgid "_Options" +msgstr "_Seçenekler" + +#: ../gtk/main.ui.h:4 +msgid "Set configuration URI" +msgstr "" + +#: ../gtk/main.ui.h:5 +msgid "Always start video" +msgstr "Her zaman görüntüyü başlat" + +#: ../gtk/main.ui.h:6 +msgid "Enable self-view" +msgstr "" + +#: ../gtk/main.ui.h:7 +msgid "Show keypad" +msgstr "" + +#: ../gtk/main.ui.h:8 +msgid "_Help" +msgstr "_Yardım" + +#: ../gtk/main.ui.h:9 +msgid "Show debug window" +msgstr "Hata düzeltme penceresini göster" + +#: ../gtk/main.ui.h:10 +msgid "_Homepage" +msgstr "_Anasayfa" + +#: ../gtk/main.ui.h:11 +msgid "Check _Updates" +msgstr "Güncellemeleri _Denetle" + +#: ../gtk/main.ui.h:12 +msgid "Account assistant" +msgstr "Hesap yardımcısı" + +#: ../gtk/main.ui.h:14 +msgid "SIP address or phone number:" +msgstr "SİP adresi veya telefon numarası:" + +#: ../gtk/main.ui.h:15 +msgid "Initiate a new call" +msgstr "Yeni bir arama başlat" + +#: ../gtk/main.ui.h:16 +msgid "Contacts" +msgstr "Bağlantılar" + +#: ../gtk/main.ui.h:17 +msgid "Search" +msgstr "Arama" + +#: ../gtk/main.ui.h:18 +msgid "Add contacts from directory" +msgstr "Rehberden bağlantılar ekle" + +#: ../gtk/main.ui.h:19 +msgid "Add contact" +msgstr "Bağlantı ekle" + +#: ../gtk/main.ui.h:20 +msgid "Clear call history" +msgstr "" + +#: ../gtk/main.ui.h:22 +msgid "My current identity:" +msgstr "" + +#: ../gtk/main.ui.h:23 +msgid "Autoanswer is enabled" +msgstr "" + +#: ../gtk/parameters.ui.h:1 +msgid "anonymous" +msgstr "kimliği belirsiz" + +#: ../gtk/parameters.ui.h:2 +msgid "GSSAPI" +msgstr "GSSAPI" + +#: ../gtk/parameters.ui.h:3 +msgid "SASL" +msgstr "SASL" + +#: ../gtk/parameters.ui.h:4 +msgid "default soundcard" +msgstr "öntanımlı ses kartı" + +#: ../gtk/parameters.ui.h:5 +msgid "a sound card" +msgstr "Ses kartı" + +#: ../gtk/parameters.ui.h:6 +msgid "default camera" +msgstr "öntanımlı kamera" + +#: ../gtk/parameters.ui.h:7 +msgid "CIF" +msgstr "CIF" + +#: ../gtk/parameters.ui.h:8 +msgid "Audio codecs" +msgstr "Ses çözücüleri" + +#: ../gtk/parameters.ui.h:9 +msgid "Video codecs" +msgstr "Görüntü çözücüleri" + +#: ../gtk/parameters.ui.h:10 +msgid "C" +msgstr "C" + +#: ../gtk/parameters.ui.h:11 +msgid "SIP (UDP)" +msgstr "SIP (UDP)" + +#: ../gtk/parameters.ui.h:12 +msgid "SIP (TCP)" +msgstr "SIP (TCP)" + +#: ../gtk/parameters.ui.h:13 +msgid "SIP (TLS)" +msgstr "SIP (TLS)" + +#: ../gtk/parameters.ui.h:14 +msgid "default" +msgstr "Öntanımlı" + +#: ../gtk/parameters.ui.h:15 +msgid "high-fps" +msgstr "yüksek-fps" + +#: ../gtk/parameters.ui.h:16 +msgid "custom" +msgstr "özel" + +#: ../gtk/parameters.ui.h:17 +msgid "Settings" +msgstr "Ayarlar" + +#: ../gtk/parameters.ui.h:18 +msgid "This section defines your SIP address when not using a SIP account" +msgstr "" + +#: ../gtk/parameters.ui.h:19 +msgid "Your display name (eg: John Doe):" +msgstr "Görünecek adınız (örneğin: Faradunda Marti)" + +#: ../gtk/parameters.ui.h:20 +msgid "Your username:" +msgstr "Kullanıcı adınız:" + +#: ../gtk/parameters.ui.h:21 +msgid "Your resulting SIP address:" +msgstr "" + +#: ../gtk/parameters.ui.h:22 +msgid "Default identity" +msgstr "Öntanımlı kimlik" + +#: ../gtk/parameters.ui.h:23 +msgid "Wizard" +msgstr "Yardımcı" + +#: ../gtk/parameters.ui.h:24 +msgid "Add" +msgstr "Ekle" + +#: ../gtk/parameters.ui.h:25 +msgid "Edit" +msgstr "Düzenle" + +#: ../gtk/parameters.ui.h:26 +msgid "Remove" +msgstr "Kaldır" + +#: ../gtk/parameters.ui.h:27 +msgid "Proxy accounts" +msgstr "Vekil sunucu hesapları" + +#: ../gtk/parameters.ui.h:28 +msgid "Erase all passwords" +msgstr "Bütün parolaları sil" + +#: ../gtk/parameters.ui.h:29 +msgid "Privacy" +msgstr "Gizlilik" + +#: ../gtk/parameters.ui.h:30 +msgid "Automatically answer when a call is received" +msgstr "Bir çağrı alındığında otomatik olarak yanıtla" + +#: ../gtk/parameters.ui.h:31 +msgid "Delay before answering (ms)" +msgstr "" + +#: ../gtk/parameters.ui.h:32 +msgid "Auto-answer" +msgstr "Otomatik yanıt" + +#: ../gtk/parameters.ui.h:33 +msgid "Manage SIP Accounts" +msgstr "SİP Hesaplarını Yönet" + +#: ../gtk/parameters.ui.h:34 +msgid "Ring sound:" +msgstr "Zil sesi:" + +#: ../gtk/parameters.ui.h:35 +msgid "ALSA special device (optional):" +msgstr "ALSA özel aygıt (seçmeli)" + +#: ../gtk/parameters.ui.h:36 +msgid "Capture device:" +msgstr "Görüntü yakalama aygıtı" + +#: ../gtk/parameters.ui.h:37 +msgid "Ring device:" +msgstr "Ses çalma aygıtı:" + +#: ../gtk/parameters.ui.h:38 +msgid "Playback device:" +msgstr "Oynatma aygıtı:" + +#: ../gtk/parameters.ui.h:39 +msgid "Enable echo cancellation" +msgstr "yankı giderme etkin" + +#: ../gtk/parameters.ui.h:40 +msgid "Audio" +msgstr "Ses" + +#: ../gtk/parameters.ui.h:41 +msgid "Video input device:" +msgstr "Görüntü aygıtı:" + +#: ../gtk/parameters.ui.h:42 +msgid "Preferred video resolution:" +msgstr "Tercih edilen görüntü çözünürlüğü:" + +#: ../gtk/parameters.ui.h:43 +msgid "Video output method:" +msgstr "Görüntü çıkış yöntemi:" + +#: ../gtk/parameters.ui.h:44 +msgid "Show camera preview" +msgstr "Kamera önizlemesi göster" + +#: ../gtk/parameters.ui.h:45 +msgid "Video preset:" +msgstr "Görüntü ön ayarları:" + +#: ../gtk/parameters.ui.h:46 +msgid "Preferred video framerate:" +msgstr "Tercih edilen görüntü kare sayısı:" + +#: ../gtk/parameters.ui.h:47 +msgid "0 stands for \"unlimited\"" +msgstr "" + +#: ../gtk/parameters.ui.h:48 +msgid "Video" +msgstr "Görüntü" + +#: ../gtk/parameters.ui.h:49 +msgid "Upload speed limit in Kbit/sec:" +msgstr "Gönderim hız sınırı Kbit/saniye:" + +#: ../gtk/parameters.ui.h:50 +msgid "Download speed limit in Kbit/sec:" +msgstr "İndirme hız sınırı Kbit/saniye:" + +#: ../gtk/parameters.ui.h:51 +msgid "Enable adaptive rate control" +msgstr "" + +#: ../gtk/parameters.ui.h:52 +msgid "" +"Adaptive rate control is a technique to dynamically guess the available " +"bandwidth during a call." +msgstr "" + +#: ../gtk/parameters.ui.h:53 +msgid "Bandwidth control" +msgstr "Bantgenişliği denetimi" + +#: ../gtk/parameters.ui.h:54 +msgid "Multimedia settings" +msgstr "Çokluortam ayarları" + +#: ../gtk/parameters.ui.h:55 +msgid "Set Maximum Transmission Unit:" +msgstr "" + +#: ../gtk/parameters.ui.h:56 +msgid "Send DTMFs as SIP info" +msgstr "" + +#: ../gtk/parameters.ui.h:57 +msgid "Allow IPv6" +msgstr "IPv6'ya izin ver" + +#: ../gtk/parameters.ui.h:58 +msgid "Transport" +msgstr "Taşıma" + +#: ../gtk/parameters.ui.h:59 +msgid "SIP/UDP port" +msgstr "SIP/UDP bağlantı noktası" + +#: ../gtk/parameters.ui.h:61 +msgid "Random" +msgstr "Rastgele" + +#: ../gtk/parameters.ui.h:62 +msgid "SIP/TCP port" +msgstr "SIP/TCP bağlantı noktası" + +#: ../gtk/parameters.ui.h:63 +msgid "Audio RTP/UDP:" +msgstr "" + +#: ../gtk/parameters.ui.h:64 +msgid "Fixed" +msgstr "Sabitlenmiş" + +#: ../gtk/parameters.ui.h:65 +msgid "Video RTP/UDP:" +msgstr "" + +#: ../gtk/parameters.ui.h:66 +msgid "Media encryption type" +msgstr "Ortam şifreleme türü" + +#: ../gtk/parameters.ui.h:67 +msgid "Media encryption is mandatory" +msgstr "Ortam şifrelemesi zorunludur" + +#: ../gtk/parameters.ui.h:68 +msgid "Tunnel" +msgstr "Tünel" + +#: ../gtk/parameters.ui.h:69 +msgid "DSCP fields" +msgstr "" + +#: ../gtk/parameters.ui.h:70 +msgid "Network protocol and ports" +msgstr "" + +#: ../gtk/parameters.ui.h:71 +msgid "Direct connection to the Internet" +msgstr "İnternete doğrudan bağlantı" + +#: ../gtk/parameters.ui.h:72 +msgid "Behind NAT / Firewall (specify gateway IP )" +msgstr "" + +#: ../gtk/parameters.ui.h:73 +msgid "Behind NAT / Firewall (use STUN to resolve)" +msgstr "" + +#: ../gtk/parameters.ui.h:74 +msgid "Behind NAT / Firewall (use ICE)" +msgstr "" + +#: ../gtk/parameters.ui.h:75 +msgid "Behind NAT / Firewall (use uPnP)" +msgstr "" + +#: ../gtk/parameters.ui.h:76 +msgid "Public IP address:" +msgstr "Ortak İP adresi:" + +#: ../gtk/parameters.ui.h:77 +msgid "Stun server:" +msgstr "Stun sunucusu:" + +#: ../gtk/parameters.ui.h:78 +msgid "NAT and Firewall" +msgstr "" + +#: ../gtk/parameters.ui.h:79 +msgid "Network settings" +msgstr "Ağ ayarları" + +#: ../gtk/parameters.ui.h:80 ../gtk/tunnel_config.ui.h:4 +msgid "Enable" +msgstr "Etkinleştirme" + +#: ../gtk/parameters.ui.h:81 ../gtk/tunnel_config.ui.h:5 +msgid "Disable" +msgstr "Devre dışı" + +#: ../gtk/parameters.ui.h:82 +msgid "Audio codecs" +msgstr "Ses çözücüleri" + +#: ../gtk/parameters.ui.h:83 +msgid "Video codecs" +msgstr "Görüntü çözücüleri" + +#: ../gtk/parameters.ui.h:84 +msgid "Codecs" +msgstr "Çözücüler" + +#: ../gtk/parameters.ui.h:85 +msgid "Language" +msgstr "Dil" + +#: ../gtk/parameters.ui.h:86 +msgid "Show advanced settings" +msgstr "Gelişmiş ayarları göster" + +#: ../gtk/parameters.ui.h:87 +msgid "Level" +msgstr "Aşama" + +#: ../gtk/parameters.ui.h:88 +msgid "User interface" +msgstr "Kullanıcı arayüzü" + +#: ../gtk/parameters.ui.h:92 +msgid "LDAP Account setup" +msgstr "LDAP Hesap ayarı" + +#: ../gtk/parameters.ui.h:93 +msgid "LDAP" +msgstr "LDAP" + +#: ../gtk/parameters.ui.h:94 +msgid "Done" +msgstr "Tamam" + #: ../gtk/password.ui.h:1 msgid "Linphone - Authentication required" msgstr "Linphone - Kimlik doğrulaması gerekli" @@ -1070,17 +1545,147 @@ msgstr "Linphone - Kimlik doğrulaması gerekli" msgid "Please enter the domain password" msgstr "Lütfen alan adı parolası girin" -#: ../gtk/call_logs.ui.h:1 -msgid "Call history" -msgstr "Çağrı geçmişi" +#: ../gtk/provisioning-fetch.ui.h:1 +msgid "Configuring..." +msgstr "Yapılandırılıyor..." -#: ../gtk/call_logs.ui.h:2 -msgid "Clear all" -msgstr "Hepsini temizle" +#: ../gtk/provisioning-fetch.ui.h:2 +msgid "Please wait while fetching configuration from server..." +msgstr "" -#: ../gtk/call_logs.ui.h:3 -msgid "Call back" -msgstr "Geri arama" +#: ../gtk/setup_wizard.ui.h:1 +msgid "SIP account configuration assistant" +msgstr "SİP hesabı yapılandırma yardımcısı" + +#: ../gtk/setup_wizard.ui.h:2 +msgid "" +"Welcome!\n" +"This assistant will help you to use a SIP account for your calls." +msgstr "Hoşgeldiniz!\nBu yardımcı,çağrılarınız için bir SIP hesabı kullanmanıza yardım edecek." + +#: ../gtk/setup_wizard.ui.h:4 +msgid "Welcome to the account setup assistant" +msgstr "Hesap açma yardımcısına hoşgeldiniz" + +#: ../gtk/setup_wizard.ui.h:5 +msgid "Create an account on linphone.org" +msgstr "linphone.org'da bir hesap oluştur" + +#: ../gtk/setup_wizard.ui.h:6 +msgid "I have already a linphone.org account and I just want to use it" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:7 +msgid "I have already a sip account and I just want to use it" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:8 +msgid "I want to specify a remote configuration URI" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:9 +msgid "Account setup assistant" +msgstr "Hesap açma yardımcısı" + +#: ../gtk/setup_wizard.ui.h:10 +msgid "Enter your account information" +msgstr "Hesap bilgilerinizi girin" + +#: ../gtk/setup_wizard.ui.h:11 +msgid "Username*" +msgstr "Kallanıcı adı*" + +#: ../gtk/setup_wizard.ui.h:12 +msgid "Password*" +msgstr "Parola*" + +#: ../gtk/setup_wizard.ui.h:13 +msgid "Domain*" +msgstr "Alan adı*" + +#: ../gtk/setup_wizard.ui.h:14 +msgid "Proxy" +msgstr "Vekil sunucu" + +#: ../gtk/setup_wizard.ui.h:15 +msgid "Configure your account (step 1/1)" +msgstr "Hesabınızı yapılandırın (adım 1/1)" + +#: ../gtk/setup_wizard.ui.h:16 +msgid "Enter your linphone.org username" +msgstr "linphone.org kullanıcı adınızı girin" + +#: ../gtk/setup_wizard.ui.h:19 +msgid "Enter your sip username (step 1/1)" +msgstr "sip kullanıcı adınızı girin (adım 1/1)" + +#: ../gtk/setup_wizard.ui.h:20 +msgid "(*) Required fields" +msgstr "(*) Zorunlu alanlar" + +#: ../gtk/setup_wizard.ui.h:21 +msgid "Email: (*)" +msgstr "E-posta: (*)" + +#: ../gtk/setup_wizard.ui.h:22 +msgid "Username: (*)" +msgstr "Kullanıcı adı: (*)" + +#: ../gtk/setup_wizard.ui.h:23 +msgid "Password: (*)" +msgstr "Parola: (*)" + +#: ../gtk/setup_wizard.ui.h:24 +msgid "Confirm your password: (*)" +msgstr "Parolanızı onaylayın: (*)" + +#: ../gtk/setup_wizard.ui.h:25 +msgid "Keep me informed with linphone updates" +msgstr "linphone güncellemeleri hakkında beni bilgilendir" + +#: ../gtk/setup_wizard.ui.h:26 +msgid "Enter account information (step 1/2)" +msgstr "Hesap bilgilerini girin (adım 1/2)" + +#: ../gtk/setup_wizard.ui.h:27 +msgid "Your account is being created, please wait." +msgstr "Hebabınız oluşturulmaya başlandı,lütfen bekleyin." + +#: ../gtk/setup_wizard.ui.h:28 +msgid "Account creation in progress" +msgstr "Hesap oluşturma sürüyor" + +#: ../gtk/setup_wizard.ui.h:29 +msgid "" +"Please validate your account by clicking on the link we just sent you by email.\n" +"Then come back here and press Next button." +msgstr "Lütfen size e-posta yoluyla gönderdiğimiz bağlantıyı tıklayarak hesabınızı doğrulayın.\nSonra buraya geri dönün ve İleri düğmesine basın." + +#: ../gtk/setup_wizard.ui.h:31 +msgid "Validation (step 2/2)" +msgstr "Doğrulama (adım 2/2)" + +#: ../gtk/setup_wizard.ui.h:32 +msgid "Checking if your account is been validated, please wait." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:33 +msgid "Account validation check in progress" +msgstr "Hesap geçerlilik sınaması sürüyor" + +#: ../gtk/setup_wizard.ui.h:34 +msgid "" +"Error, account not validated, username already used or server unreachable.\n" +"Please go back and try again." +msgstr "Hata,hesap geçersiz,kullanıcı adı kullanılıyor veya sunucuya erişilemiyor.\nLütfen geri dönün ve tekrar deneyin." + +#: ../gtk/setup_wizard.ui.h:36 +msgid "Error" +msgstr "Hata" + +#: ../gtk/setup_wizard.ui.h:37 +msgid "Thank you. Your account is now configured and ready for use." +msgstr "Teşekkürler. Hesabınız yapılandırıldı ve kullanıma hazır." #: ../gtk/sip_account.ui.h:1 msgid "Linphone - Configure a SIP account" @@ -1142,439 +1747,9 @@ msgstr "AVPF'yi etkinleştir" msgid "Configure a SIP account" msgstr "Bir SİP hesabı yapılandır" -#: ../gtk/parameters.ui.h:1 -msgid "anonymous" -msgstr "kimliği belirsiz" - -#: ../gtk/parameters.ui.h:2 -msgid "GSSAPI" -msgstr "" - -#: ../gtk/parameters.ui.h:3 -msgid "SASL" -msgstr "" - -#: ../gtk/parameters.ui.h:4 -msgid "default soundcard" -msgstr "öntanımlı ses kartı" - -#: ../gtk/parameters.ui.h:5 -msgid "a sound card" -msgstr "Ses kartı" - -#: ../gtk/parameters.ui.h:6 -msgid "default camera" -msgstr "öntanımlı kamera" - -#: ../gtk/parameters.ui.h:7 -msgid "CIF" -msgstr "CIF" - -#: ../gtk/parameters.ui.h:8 -msgid "Audio codecs" -msgstr "Ses kodekleri" - -#: ../gtk/parameters.ui.h:9 -msgid "Video codecs" -msgstr "Görüntü kodekleri" - -#: ../gtk/parameters.ui.h:10 -msgid "C" -msgstr "C" - -#: ../gtk/parameters.ui.h:11 -msgid "SIP (UDP)" -msgstr "SIP (UDP)" - -#: ../gtk/parameters.ui.h:12 -msgid "SIP (TCP)" -msgstr "SIP (TCP)" - -#: ../gtk/parameters.ui.h:13 -msgid "SIP (TLS)" -msgstr "SIP (TLS)" - -#: ../gtk/parameters.ui.h:14 -msgid "Settings" -msgstr "Ayarlar" - -#: ../gtk/parameters.ui.h:15 -msgid "Set Maximum Transmission Unit:" -msgstr "" - -#: ../gtk/parameters.ui.h:16 -msgid "Send DTMFs as SIP info" -msgstr "" - -#: ../gtk/parameters.ui.h:17 -msgid "Allow IPv6" -msgstr "" - -#: ../gtk/parameters.ui.h:18 -msgid "Transport" -msgstr "" - -#: ../gtk/parameters.ui.h:19 -msgid "SIP/UDP port" -msgstr "SIP/UDP bağlantı noktası" - -#: ../gtk/parameters.ui.h:21 -msgid "Random" -msgstr "Rastgele" - -#: ../gtk/parameters.ui.h:22 -msgid "SIP/TCP port" -msgstr "SIP/TCP bağlantı noktası" - -#: ../gtk/parameters.ui.h:23 -msgid "Audio RTP/UDP:" -msgstr "" - -#: ../gtk/parameters.ui.h:24 -msgid "Fixed" -msgstr "Sabitlenmiş" - -#: ../gtk/parameters.ui.h:25 -msgid "Video RTP/UDP:" -msgstr "" - -#: ../gtk/parameters.ui.h:26 -msgid "Media encryption type" -msgstr "Ortam şifreleme türü" - -#: ../gtk/parameters.ui.h:27 -msgid "Media encryption is mandatory" -msgstr "Ortam şifrelemesi zorunludur" - -#: ../gtk/parameters.ui.h:28 -msgid "Tunnel" -msgstr "Tünel" - -#: ../gtk/parameters.ui.h:29 -msgid "DSCP fields" -msgstr "" - -#: ../gtk/parameters.ui.h:30 -msgid "Network protocol and ports" -msgstr "" - -#: ../gtk/parameters.ui.h:31 -msgid "Direct connection to the Internet" -msgstr "İnternete doğrudan bağlantı" - -#: ../gtk/parameters.ui.h:32 -msgid "Behind NAT / Firewall (specify gateway IP )" -msgstr "" - -#: ../gtk/parameters.ui.h:33 -msgid "Behind NAT / Firewall (use STUN to resolve)" -msgstr "" - -#: ../gtk/parameters.ui.h:34 -msgid "Behind NAT / Firewall (use ICE)" -msgstr "" - -#: ../gtk/parameters.ui.h:35 -msgid "Behind NAT / Firewall (use uPnP)" -msgstr "" - -#: ../gtk/parameters.ui.h:36 -msgid "Public IP address:" -msgstr "Ortak İP adresi:" - -#: ../gtk/parameters.ui.h:37 -msgid "Stun server:" -msgstr "Stun sunucusu:" - -#: ../gtk/parameters.ui.h:38 -msgid "NAT and Firewall" -msgstr "" - -#: ../gtk/parameters.ui.h:39 -msgid "Network settings" -msgstr "Ağ ayarları" - -#: ../gtk/parameters.ui.h:40 -msgid "Ring sound:" -msgstr "Zil sesi:" - -#: ../gtk/parameters.ui.h:41 -msgid "ALSA special device (optional):" -msgstr "ALSA özel aygıt (seçmeli)" - -#: ../gtk/parameters.ui.h:42 -msgid "Capture device:" -msgstr "Görüntü yakalama aygıtı" - -#: ../gtk/parameters.ui.h:43 -msgid "Ring device:" -msgstr "Ses çalma aygıtı:" - -#: ../gtk/parameters.ui.h:44 -msgid "Playback device:" -msgstr "Oynatma aygıtı:" - -#: ../gtk/parameters.ui.h:45 -msgid "Enable echo cancellation" -msgstr "" - -#: ../gtk/parameters.ui.h:46 -msgid "Audio" -msgstr "Ses" - -#: ../gtk/parameters.ui.h:47 -msgid "Video input device:" -msgstr "Görüntü aygıtı:" - -#: ../gtk/parameters.ui.h:48 -msgid "Prefered video resolution:" -msgstr "Tercih edilen görüntü çözünürlüğü:" - -#: ../gtk/parameters.ui.h:49 -msgid "Video output method:" -msgstr "Görüntü çıkış yöntemi:" - -#: ../gtk/parameters.ui.h:50 -msgid "Show camera preview" -msgstr "Kamera önizlemesi göster" - -#: ../gtk/parameters.ui.h:51 -msgid "Video" -msgstr "Görüntü" - -#: ../gtk/parameters.ui.h:52 -msgid "Multimedia settings" -msgstr "Çokluortam ayarları" - -#: ../gtk/parameters.ui.h:53 -msgid "This section defines your SIP address when not using a SIP account" -msgstr "" - -#: ../gtk/parameters.ui.h:54 -msgid "Your display name (eg: John Doe):" -msgstr "Görünecek adınız (örneğin: Faradunda Marti)" - -#: ../gtk/parameters.ui.h:55 -msgid "Your username:" -msgstr "Kullanıcı adınız:" - -#: ../gtk/parameters.ui.h:56 -msgid "Your resulting SIP address:" -msgstr "" - -#: ../gtk/parameters.ui.h:57 -msgid "Default identity" -msgstr "Öntanımlı kimlik" - -#: ../gtk/parameters.ui.h:58 -msgid "Wizard" -msgstr "Yardımcı" - -#: ../gtk/parameters.ui.h:59 -msgid "Add" -msgstr "Ekle" - -#: ../gtk/parameters.ui.h:60 -msgid "Edit" -msgstr "Düzenle" - -#: ../gtk/parameters.ui.h:61 -msgid "Remove" -msgstr "Kaldır" - -#: ../gtk/parameters.ui.h:62 -msgid "Proxy accounts" -msgstr "" - -#: ../gtk/parameters.ui.h:63 -msgid "Erase all passwords" -msgstr "Bütün parolaları sil" - -#: ../gtk/parameters.ui.h:64 -msgid "Privacy" -msgstr "Gizlilik" - -#: ../gtk/parameters.ui.h:65 -msgid "Automatically answer when a call is received" -msgstr "" - -#: ../gtk/parameters.ui.h:66 -msgid "Delay before answering (ms)" -msgstr "" - -#: ../gtk/parameters.ui.h:67 -msgid "Auto-answer" -msgstr "Otomatik yanıt" - -#: ../gtk/parameters.ui.h:68 -msgid "Manage SIP Accounts" -msgstr "SİP Hesaplarını Yönet" - -#: ../gtk/parameters.ui.h:69 ../gtk/tunnel_config.ui.h:4 -msgid "Enable" -msgstr "Etkinleştirme" - -#: ../gtk/parameters.ui.h:70 ../gtk/tunnel_config.ui.h:5 -msgid "Disable" -msgstr "Devre dışı" - -#: ../gtk/parameters.ui.h:71 -msgid "Codecs" -msgstr "Çözücüler" - -#: ../gtk/parameters.ui.h:72 -msgid "0 stands for \"unlimited\"" -msgstr "" - -#: ../gtk/parameters.ui.h:73 -msgid "Upload speed limit in Kbit/sec:" -msgstr "Gönderim hız sınırı Kbit/saniye:" - -#: ../gtk/parameters.ui.h:74 -msgid "Download speed limit in Kbit/sec:" -msgstr "İndirme hız sınırı Kbit/saniye:" - -#: ../gtk/parameters.ui.h:75 -msgid "Enable adaptive rate control" -msgstr "" - -#: ../gtk/parameters.ui.h:76 -msgid "" -"Adaptive rate control is a technique to dynamically guess the available " -"bandwidth during a call." -msgstr "" - -#: ../gtk/parameters.ui.h:77 -msgid "Bandwidth control" -msgstr "Bantgenişliği denetimi" - -#: ../gtk/parameters.ui.h:78 -msgid "Codecs" -msgstr "Çözücüler" - -#: ../gtk/parameters.ui.h:79 -msgid "Language" -msgstr "Dil" - -#: ../gtk/parameters.ui.h:80 -msgid "Show advanced settings" -msgstr "Gelişmiş ayarları göster" - -#: ../gtk/parameters.ui.h:81 -msgid "Level" -msgstr "Aşama" - -#: ../gtk/parameters.ui.h:82 -msgid "User interface" -msgstr "Kullanıcı arayüzü" - -#: ../gtk/parameters.ui.h:83 ../gtk/ldap.ui.h:2 -msgid "Server address:" -msgstr "Sunucu adresi:" - -#: ../gtk/parameters.ui.h:84 ../gtk/ldap.ui.h:3 -msgid "Authentication method:" -msgstr "Kimlik doğrulama yöntemi:" - -#: ../gtk/parameters.ui.h:86 -msgid "LDAP Account setup" -msgstr "LDAP Hesap ayarı" - -#: ../gtk/parameters.ui.h:87 -msgid "LDAP" -msgstr "LDAP" - -#: ../gtk/parameters.ui.h:88 -msgid "Done" -msgstr "Tamam" - -#: ../gtk/buddylookup.ui.h:1 -msgid "Search contacts in directory" -msgstr "" - -#: ../gtk/buddylookup.ui.h:2 -msgid "Add to my list" -msgstr "Listeme ekle" - -#: ../gtk/buddylookup.ui.h:3 -msgid "Search somebody" -msgstr "" - -#: ../gtk/waiting.ui.h:2 -msgid "Please wait" -msgstr "Lütfen bekleyin" - -#: ../gtk/dscp_settings.ui.h:1 -msgid "DSCP settings" -msgstr "DSCP ayarları" - -#: ../gtk/dscp_settings.ui.h:2 -msgid "SIP" -msgstr "SİP" - -#: ../gtk/dscp_settings.ui.h:3 -msgid "Audio RTP stream" -msgstr "" - -#: ../gtk/dscp_settings.ui.h:4 -msgid "Video RTP stream" -msgstr "" - -#: ../gtk/dscp_settings.ui.h:5 -msgid "Set DSCP values (in hexadecimal)" -msgstr "" - -#: ../gtk/call_statistics.ui.h:1 -msgid "Call statistics" -msgstr "Çağrı istatistikleri" - -#: ../gtk/call_statistics.ui.h:2 -msgid "Audio codec" -msgstr "Ses çözücü" - -#: ../gtk/call_statistics.ui.h:3 -msgid "Video codec" -msgstr "Görüntü çözücü" - -#: ../gtk/call_statistics.ui.h:4 -msgid "Audio IP bandwidth usage" -msgstr "" - -#: ../gtk/call_statistics.ui.h:5 -msgid "Audio Media connectivity" -msgstr "Ses Ortamı bağlanırlığı" - -#: ../gtk/call_statistics.ui.h:6 -msgid "Video IP bandwidth usage" -msgstr "" - -#: ../gtk/call_statistics.ui.h:7 -msgid "Video Media connectivity" -msgstr "Görüntü Ortamı bağlanırlığı" - -#: ../gtk/call_statistics.ui.h:8 -msgid "Round trip time" -msgstr "Sinyal gidiş-dönüş süresi" - -#: ../gtk/call_statistics.ui.h:9 -msgid "Video resolution received" -msgstr "Alınan görüntü çözünürlüğü" - -#: ../gtk/call_statistics.ui.h:10 -msgid "Video resolution sent" -msgstr "Giden görüntü çözünürlüğü" - -#: ../gtk/call_statistics.ui.h:11 -msgid "RTP profile" -msgstr "" - -#: ../gtk/call_statistics.ui.h:12 -msgid "Call statistics and information" -msgstr "" - #: ../gtk/tunnel_config.ui.h:1 msgid "Configure VoIP tunnel" -msgstr "" +msgstr "VoIP tüneli yapılandır" #: ../gtk/tunnel_config.ui.h:2 msgid "Host" @@ -1592,175 +1767,64 @@ msgstr "" msgid "Configure http proxy (optional)" msgstr "" -#: ../gtk/ldap.ui.h:1 -msgid "LDAP Settings" -msgstr "LDAP Ayarları" +#: ../gtk/waiting.ui.h:2 +msgid "Please wait" +msgstr "Lütfen bekleyin" -#: ../gtk/ldap.ui.h:6 -msgid "Use TLS Connection" -msgstr "TLS Bağlantısı Kullan" - -#: ../gtk/ldap.ui.h:7 -msgid "Not yet available" -msgstr "Henüz kullanılabilir değil" - -#: ../gtk/ldap.ui.h:8 -msgid "Connection" -msgstr "" - -#: ../gtk/ldap.ui.h:9 -msgid "Bind DN" -msgstr "" - -#: ../gtk/ldap.ui.h:10 -msgid "Authname" -msgstr "" - -#: ../gtk/ldap.ui.h:11 -msgid "Realm" -msgstr "Ülke" - -#: ../gtk/ldap.ui.h:12 -msgid "SASL" -msgstr "" - -#: ../gtk/ldap.ui.h:13 -msgid "Base object:" -msgstr "" - -#: ../gtk/ldap.ui.h:15 -#, no-c-format -msgid "Filter (%s for name):" -msgstr "" - -#: ../gtk/ldap.ui.h:16 -msgid "Name Attribute:" -msgstr "" - -#: ../gtk/ldap.ui.h:17 -msgid "SIP address attribute:" -msgstr "" - -#: ../gtk/ldap.ui.h:18 -msgid "Attributes to query:" -msgstr "" - -#: ../gtk/ldap.ui.h:19 -msgid "Search" -msgstr "" - -#: ../gtk/ldap.ui.h:20 -msgid "Timeout for search:" -msgstr "" - -#: ../gtk/ldap.ui.h:21 -msgid "Max results:" -msgstr "" - -#: ../gtk/ldap.ui.h:22 -msgid "Follow Aliases" -msgstr "" - -#: ../gtk/ldap.ui.h:23 -msgid "Miscellaneous" -msgstr "" - -#: ../gtk/ldap.ui.h:24 -msgid "ANONYMOUS" -msgstr "" - -#: ../gtk/ldap.ui.h:25 -msgid "SIMPLE" -msgstr "" - -#: ../gtk/ldap.ui.h:26 -msgid "DIGEST-MD5" -msgstr "" - -#: ../gtk/ldap.ui.h:27 -msgid "NTLM" -msgstr "" - -#: ../gtk/config-uri.ui.h:1 -msgid "Specifying a remote configuration URI" -msgstr "" - -#: ../gtk/config-uri.ui.h:2 -msgid "" -"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" -"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " -msgstr "" - -#: ../gtk/provisioning-fetch.ui.h:1 -msgid "Configuring..." -msgstr "Yapılandırılıyor..." - -#: ../gtk/provisioning-fetch.ui.h:2 -msgid "Please wait while fetching configuration from server..." -msgstr "" - -#: ../coreapi/linphonecore.c:1539 +#: ../coreapi/linphonecore.c:1560 msgid "Ready" msgstr "Hazır" -#: ../coreapi/linphonecore.c:2551 +#: ../coreapi/linphonecore.c:2556 msgid "Configuring" msgstr "Yapılandırılıyor" -#: ../coreapi/linphonecore.c:2725 -msgid "Looking for telephone number destination..." -msgstr "" - -#: ../coreapi/linphonecore.c:2727 -msgid "Could not resolve this number." -msgstr "" - #. must be known at that time -#: ../coreapi/linphonecore.c:3013 +#: ../coreapi/linphonecore.c:2951 msgid "Contacting" msgstr "Bağlanıyor" -#: ../coreapi/linphonecore.c:3018 +#: ../coreapi/linphonecore.c:2956 msgid "Could not call" msgstr "" -#: ../coreapi/linphonecore.c:3169 +#: ../coreapi/linphonecore.c:3092 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "" -#: ../coreapi/linphonecore.c:3327 +#: ../coreapi/linphonecore.c:3250 msgid "is contacting you" msgstr "" -#: ../coreapi/linphonecore.c:3328 +#: ../coreapi/linphonecore.c:3251 msgid " and asked autoanswer." msgstr "" -#: ../coreapi/linphonecore.c:3452 +#: ../coreapi/linphonecore.c:3377 msgid "Modifying call parameters..." msgstr "" -#: ../coreapi/linphonecore.c:3802 +#: ../coreapi/linphonecore.c:3769 msgid "Connected." msgstr "Bağlandı." -#: ../coreapi/linphonecore.c:3827 +#: ../coreapi/linphonecore.c:3794 msgid "Call aborted" msgstr "Çağrı iptal edildi" -#: ../coreapi/linphonecore.c:4024 +#: ../coreapi/linphonecore.c:3983 msgid "Could not pause the call" msgstr "" -#: ../coreapi/linphonecore.c:4027 +#: ../coreapi/linphonecore.c:3986 msgid "Pausing the current call..." msgstr "" -#: ../coreapi/misc.c:434 +#: ../coreapi/misc.c:440 msgid "Stun lookup in progress..." msgstr "" -#: ../coreapi/misc.c:615 +#: ../coreapi/misc.c:650 msgid "ICE local candidates gathering in progress..." msgstr "" @@ -1816,166 +1880,173 @@ msgstr "Tatil" msgid "Unknown status" msgstr "Bilinmeyen durum" -#: ../coreapi/proxy.c:328 +#: ../coreapi/proxy.c:292 msgid "" "The sip proxy address you entered is invalid, it must start with \"sip:\" " "followed by a hostname." msgstr "" -#: ../coreapi/proxy.c:334 +#: ../coreapi/proxy.c:298 msgid "" "The sip identity you entered is invalid.\n" "It should look like sip:username@proxydomain, such as sip:alice@example.net" msgstr "" -#: ../coreapi/proxy.c:1416 +#: ../coreapi/proxy.c:927 +msgid "Looking for telephone number destination..." +msgstr "" + +#: ../coreapi/proxy.c:931 +msgid "Could not resolve this number." +msgstr "" + +#: ../coreapi/proxy.c:1324 #, c-format msgid "Could not login as %s" msgstr "" -#: ../coreapi/callbacks.c:428 +#: ../coreapi/proxy.c:1411 +#, c-format +msgid "Refreshing on %s..." +msgstr "" + +#: ../coreapi/callbacks.c:423 msgid "Remote ringing." msgstr "" -#: ../coreapi/callbacks.c:440 +#: ../coreapi/callbacks.c:435 msgid "Remote ringing..." msgstr "" -#: ../coreapi/callbacks.c:461 +#: ../coreapi/callbacks.c:458 msgid "Early media." msgstr "" -#: ../coreapi/callbacks.c:534 +#: ../coreapi/callbacks.c:488 #, c-format -msgid "Call with %s is paused." +msgid "Call answered by %s" msgstr "" -#: ../coreapi/callbacks.c:547 -#, c-format -msgid "Call answered by %s - on hold." -msgstr "" - -#: ../coreapi/callbacks.c:557 +#: ../coreapi/callbacks.c:527 msgid "Call resumed." -msgstr "" +msgstr "Arama yeniden başlatıldı." -#: ../coreapi/callbacks.c:561 -#, c-format -msgid "Call answered by %s." -msgstr "" - -#: ../coreapi/callbacks.c:584 +#: ../coreapi/callbacks.c:582 msgid "Incompatible, check codecs or security settings..." msgstr "" -#: ../coreapi/callbacks.c:589 ../coreapi/callbacks.c:906 +#: ../coreapi/callbacks.c:587 ../coreapi/callbacks.c:923 msgid "Incompatible media parameters." msgstr "" -#: ../coreapi/callbacks.c:619 +#: ../coreapi/callbacks.c:612 msgid "We have been resumed." msgstr "" #. we are being paused -#: ../coreapi/callbacks.c:628 +#: ../coreapi/callbacks.c:620 msgid "We are paused by other party." msgstr "" -#. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:666 +#: ../coreapi/callbacks.c:630 msgid "Call is updated by remote." msgstr "" -#: ../coreapi/callbacks.c:782 +#: ../coreapi/callbacks.c:799 msgid "Call terminated." msgstr "Çağrı sonlandırıldı" -#: ../coreapi/callbacks.c:810 +#: ../coreapi/callbacks.c:827 msgid "User is busy." msgstr "Kullanıcı meşgul" -#: ../coreapi/callbacks.c:811 +#: ../coreapi/callbacks.c:828 msgid "User is temporarily unavailable." -msgstr "" +msgstr "K" #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:813 +#: ../coreapi/callbacks.c:830 msgid "User does not want to be disturbed." msgstr "Kullanıcı rahatsız edilmek istemiyor." -#: ../coreapi/callbacks.c:814 +#: ../coreapi/callbacks.c:831 msgid "Call declined." msgstr "Çağrı reddedildi." -#: ../coreapi/callbacks.c:829 +#: ../coreapi/callbacks.c:846 msgid "Request timeout." msgstr "İstek zamanaşımına uğradı." -#: ../coreapi/callbacks.c:860 +#: ../coreapi/callbacks.c:877 msgid "Redirected" msgstr "Yeniden yönlendirildi" -#: ../coreapi/callbacks.c:915 +#: ../coreapi/callbacks.c:927 msgid "Call failed." msgstr "Arama başarısız" -#: ../coreapi/callbacks.c:993 +#: ../coreapi/callbacks.c:1005 #, c-format msgid "Registration on %s successful." msgstr "" -#: ../coreapi/callbacks.c:994 +#: ../coreapi/callbacks.c:1006 #, c-format msgid "Unregistration on %s done." msgstr "" -#: ../coreapi/callbacks.c:1012 +#: ../coreapi/callbacks.c:1024 msgid "no response timeout" msgstr "" -#: ../coreapi/callbacks.c:1015 +#: ../coreapi/callbacks.c:1027 #, c-format msgid "Registration on %s failed: %s" msgstr "" -#: ../coreapi/callbacks.c:1022 +#: ../coreapi/callbacks.c:1034 msgid "Service unavailable, retrying" msgstr "Servis kullanımdışı, tekrar deneyin" #. if encryption is DTLS, no status to be displayed -#: ../coreapi/linphonecall.c:180 +#: ../coreapi/linphonecall.c:197 #, c-format msgid "Authentication token is %s" msgstr "" -#: ../coreapi/linphonecall.c:1310 +#: ../coreapi/linphonecall.c:1561 +#, c-format +msgid "Call parameters could not be modified: %s." +msgstr "" + +#: ../coreapi/linphonecall.c:1563 msgid "Call parameters were successfully modified." msgstr "" -#: ../coreapi/linphonecall.c:3686 +#: ../coreapi/linphonecall.c:4396 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." msgstr[0] "" msgstr[1] "" -#: ../coreapi/call_log.c:209 +#: ../coreapi/call_log.c:223 msgid "aborted" msgstr "iptal edildi" -#: ../coreapi/call_log.c:212 +#: ../coreapi/call_log.c:226 msgid "completed" msgstr "tamamlandı" -#: ../coreapi/call_log.c:215 +#: ../coreapi/call_log.c:229 msgid "missed" msgstr "Yanıtsız" -#: ../coreapi/call_log.c:218 +#: ../coreapi/call_log.c:232 msgid "unknown" msgstr "bilinmeyen" -#: ../coreapi/call_log.c:220 +#: ../coreapi/call_log.c:234 #, c-format msgid "" "%s at %s\n" @@ -1985,9 +2056,9 @@ msgid "" "Duration: %i mn %i sec\n" msgstr "" -#: ../coreapi/call_log.c:221 +#: ../coreapi/call_log.c:235 msgid "Outgoing call" -msgstr "" +msgstr "Giden arama" #: ../gtk/videowindow.c:66 #, c-format diff --git a/po/zh_CN.po b/po/zh_CN.po index 00322bce9..7e69f59c2 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -7,72 +7,81 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-04-30 10:13+0200\n" -"PO-Revision-Date: 2015-04-30 08:13+0000\n" +"POT-Creation-Date: 2015-11-10 15:16+0100\n" +"PO-Revision-Date: 2015-11-10 14:16+0000\n" "Last-Translator: Belledonne Communications \n" -"Language-Team: Chinese (China) (http://www.transifex.com/projects/p/linphone-gtk/language/zh_CN/)\n" +"Language-Team: Chinese (China) (http://www.transifex.com/belledonne-communications/linphone-gtk/language/zh_CN/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: zh_CN\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: ../gtk/calllogs.c:148 ../gtk/friendlist.c:974 +#: ../gtk/calllogs.c:178 #, c-format msgid "Call %s" msgstr "呼叫 %s" -#: ../gtk/calllogs.c:149 ../gtk/friendlist.c:975 +#: ../gtk/calllogs.c:179 #, c-format msgid "Send text to %s" msgstr "发送消息给 %s" -#: ../gtk/calllogs.c:232 +#: ../gtk/calllogs.c:181 +#, c-format +msgid "Add %s to your contact list" +msgstr "" + +#: ../gtk/calllogs.c:245 ../gtk/main.ui.h:21 +msgid "Recent calls" +msgstr "" + +#: ../gtk/calllogs.c:260 #, c-format msgid "Recent calls (%i)" msgstr "" -#: ../gtk/calllogs.c:314 +#: ../gtk/calllogs.c:331 msgid "n/a" msgstr "" -#: ../gtk/calllogs.c:317 +#: ../gtk/calllogs.c:334 msgid "Aborted" msgstr "" -#: ../gtk/calllogs.c:320 +#: ../gtk/calllogs.c:337 msgid "Missed" msgstr "" -#: ../gtk/calllogs.c:323 +#: ../gtk/calllogs.c:340 msgid "Declined" msgstr "" -#: ../gtk/calllogs.c:329 +#: ../gtk/calllogs.c:346 #, c-format msgid "%i minute" msgid_plural "%i minutes" msgstr[0] "" -#: ../gtk/calllogs.c:332 +#: ../gtk/calllogs.c:349 #, c-format msgid "%i second" msgid_plural "%i seconds" msgstr[0] "" -#: ../gtk/calllogs.c:337 +#: ../gtk/calllogs.c:354 #, c-format msgid "" "%s\tQuality: %s\n" "%s\t%s\t" msgstr "" -#: ../gtk/calllogs.c:341 +#: ../gtk/calllogs.c:358 #, c-format msgid "%s\t%s" msgstr "" -#: ../gtk/conference.c:38 ../gtk/main.ui.h:13 +#: ../gtk/conference.c:38 ../gtk/in_call_frame.ui.h:11 msgid "Conference" msgstr "" @@ -85,297 +94,314 @@ msgstr "" msgid "Couldn't find pixmap file: %s" msgstr "无法打开位图文件:%s" -#: ../gtk/main.c:137 +#: ../gtk/chat.c:196 ../gtk/chat.c:254 +msgid "Sending..." +msgstr "" + +#: ../gtk/chat.c:213 ../gtk/chat.c:263 +msgid "Message not sent" +msgstr "" + +#: ../gtk/chat.c:472 +msgid "Copy" +msgstr "" + +#: ../gtk/main.c:138 msgid "log to stdout some debug information while running." msgstr "运行时向标准输出记录调试信息。" -#: ../gtk/main.c:138 -msgid "path to a file to write logs into." -msgstr "" - #: ../gtk/main.c:139 -msgid "Start linphone with video disabled." +msgid "display version and exit." msgstr "" #: ../gtk/main.c:140 +msgid "path to a file to write logs into." +msgstr "" + +#: ../gtk/main.c:141 +msgid "Start linphone with video disabled." +msgstr "" + +#: ../gtk/main.c:142 msgid "Start only in the system tray, do not show the main interface." msgstr "启动到系统托盘,不显示主界面。" -#: ../gtk/main.c:141 +#: ../gtk/main.c:143 msgid "address to call right now" msgstr "现在呼叫的地址" -#: ../gtk/main.c:142 +#: ../gtk/main.c:144 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:143 +#: ../gtk/main.c:145 msgid "Configuration file" msgstr "" -#: ../gtk/main.c:144 +#: ../gtk/main.c:146 msgid "Run the audio assistant" msgstr "" -#: ../gtk/main.c:145 +#: ../gtk/main.c:147 msgid "Run self test and exit 0 if succeed" msgstr "" -#: ../gtk/main.c:1070 +#: ../gtk/main.c:1046 #, c-format msgid "" -"%s would like to add you to his contact list.\n" -"Would you allow him to see your presence status or add him to your contact list ?\n" +"%s would like to add you to his/her contact list.\n" +"Would you add him/her to your contact list and allow him/her to see your presence status?\n" "If you answer no, this person will be temporarily blacklisted." -msgstr "%s 想加您为联系人。\n您是否允许他看到您的在线状态或者将它加为您的联系人允许?\n如果您回答否,则会将该人临时性的放入黑名单" +msgstr "" -#: ../gtk/main.c:1147 +#: ../gtk/main.c:1123 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" msgstr "" -#: ../gtk/main.c:1268 +#: ../gtk/main.c:1253 msgid "Call error" msgstr "" -#: ../gtk/main.c:1271 ../coreapi/linphonecore.c:3846 +#: ../gtk/main.c:1256 ../coreapi/linphonecore.c:3813 msgid "Call ended" msgstr "呼叫结束" -#: ../gtk/main.c:1274 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1259 ../coreapi/call_log.c:235 msgid "Incoming call" msgstr "呼入" -#: ../gtk/main.c:1276 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1261 ../gtk/incall_view.c:580 ../gtk/in_call_frame.ui.h:2 msgid "Answer" msgstr "" -#: ../gtk/main.c:1278 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1263 ../gtk/in_call_frame.ui.h:3 msgid "Decline" msgstr "拒绝" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 msgid "Call paused" msgstr "" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 #, c-format msgid "by %s" msgstr "" -#: ../gtk/main.c:1354 +#: ../gtk/main.c:1339 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "" -#: ../gtk/main.c:1509 +#: ../gtk/main.c:1505 msgid "Website link" msgstr "网站" -#: ../gtk/main.c:1568 ../gtk/waiting.ui.h:1 +#: ../gtk/main.c:1564 ../gtk/waiting.ui.h:1 msgid "Linphone" msgstr "Linphone" -#: ../gtk/main.c:1569 +#: ../gtk/main.c:1565 msgid "A video internet phone" msgstr "" -#: ../gtk/main.c:1629 +#: ../gtk/main.c:1624 #, c-format msgid "%s (Default)" msgstr "%s (默认)" -#: ../gtk/main.c:1962 ../coreapi/callbacks.c:1063 +#: ../gtk/main.c:1960 ../coreapi/callbacks.c:1075 #, c-format msgid "We are transferred to %s" msgstr "" -#: ../gtk/main.c:1972 +#: ../gtk/main.c:1970 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." msgstr "未在此计算机上检测到声卡。\n您无法发送或接收音频呼叫。" -#: ../gtk/main.c:2117 +#: ../gtk/main.c:2129 msgid "A free SIP video-phone" msgstr "免费的 SIP 视频电话" -#: ../gtk/main.c:2221 +#: ../gtk/main.c:2242 #, c-format msgid "Hello\n" msgstr "" -#: ../gtk/friendlist.c:505 +#: ../gtk/friendlist.c:461 msgid "Add to addressbook" msgstr "" -#: ../gtk/friendlist.c:691 -msgid "Presence status" -msgstr "在线状态" - -#: ../gtk/friendlist.c:709 ../gtk/propertybox.c:569 ../gtk/contact.ui.h:1 -msgid "Name" -msgstr "名称" - -#: ../gtk/friendlist.c:721 -msgid "Call" -msgstr "" - -#: ../gtk/friendlist.c:726 -msgid "Chat" -msgstr "" - -#: ../gtk/friendlist.c:756 +#: ../gtk/friendlist.c:627 #, c-format msgid "Search in %s directory" msgstr "在 %s 目录中查找 " -#: ../gtk/friendlist.c:924 +#: ../gtk/friendlist.c:772 msgid "Invalid sip contact !" msgstr "无效的 SIP 联系人!" -#: ../gtk/friendlist.c:976 +#: ../gtk/friendlist.c:820 +#, c-format +msgid "Add a new contact" +msgstr "" + +#: ../gtk/friendlist.c:823 #, c-format msgid "Edit contact '%s'" msgstr "编辑联系人 %s" -#: ../gtk/friendlist.c:977 +#: ../gtk/friendlist.c:824 #, c-format msgid "Delete contact '%s'" msgstr "删除联系人 %s" -#: ../gtk/friendlist.c:978 +#: ../gtk/friendlist.c:825 #, c-format msgid "Delete chat history of '%s'" msgstr "" -#: ../gtk/friendlist.c:1029 +#: ../gtk/friendlist.c:862 #, c-format msgid "Add new contact from %s directory" msgstr "从 %s 目录增加联系人 " -#: ../gtk/propertybox.c:575 +#: ../gtk/propertybox.c:592 ../gtk/contact.ui.h:1 +msgid "Name" +msgstr "名称" + +#: ../gtk/propertybox.c:598 msgid "Rate (Hz)" msgstr "采样率(Hz)" -#: ../gtk/propertybox.c:581 +#: ../gtk/propertybox.c:604 msgid "Status" msgstr "状态" -#: ../gtk/propertybox.c:587 +#: ../gtk/propertybox.c:617 msgid "IP Bitrate (kbit/s)" msgstr "" -#: ../gtk/propertybox.c:596 +#: ../gtk/propertybox.c:628 msgid "Parameters" msgstr "参数" -#: ../gtk/propertybox.c:639 ../gtk/propertybox.c:782 +#: ../gtk/propertybox.c:670 ../gtk/propertybox.c:824 msgid "Enabled" msgstr "启用" -#: ../gtk/propertybox.c:641 ../gtk/propertybox.c:782 ../gtk/parameters.ui.h:20 +#: ../gtk/propertybox.c:672 ../gtk/propertybox.c:824 ../gtk/parameters.ui.h:60 msgid "Disabled" msgstr "禁用" -#: ../gtk/propertybox.c:828 +#: ../gtk/propertybox.c:902 msgid "Account" msgstr "帐户" -#: ../gtk/propertybox.c:1091 +#: ../gtk/propertybox.c:1170 msgid "English" msgstr "英语" -#: ../gtk/propertybox.c:1092 +#: ../gtk/propertybox.c:1171 msgid "French" msgstr "法语" -#: ../gtk/propertybox.c:1093 +#: ../gtk/propertybox.c:1172 msgid "Swedish" msgstr "瑞典语" -#: ../gtk/propertybox.c:1094 +#: ../gtk/propertybox.c:1173 msgid "Italian" msgstr "意大利语" -#: ../gtk/propertybox.c:1095 +#: ../gtk/propertybox.c:1174 msgid "Spanish" msgstr "西班牙语" -#: ../gtk/propertybox.c:1096 +#: ../gtk/propertybox.c:1175 msgid "Brazilian Portugese" msgstr "巴西葡萄牙语" -#: ../gtk/propertybox.c:1097 +#: ../gtk/propertybox.c:1176 msgid "Polish" msgstr "波兰语" -#: ../gtk/propertybox.c:1098 +#: ../gtk/propertybox.c:1177 msgid "German" msgstr "德语" -#: ../gtk/propertybox.c:1099 +#: ../gtk/propertybox.c:1178 msgid "Russian" msgstr "俄语" -#: ../gtk/propertybox.c:1100 +#: ../gtk/propertybox.c:1179 msgid "Japanese" msgstr "日语" -#: ../gtk/propertybox.c:1101 +#: ../gtk/propertybox.c:1180 msgid "Dutch" msgstr "荷兰语" -#: ../gtk/propertybox.c:1102 +#: ../gtk/propertybox.c:1181 msgid "Hungarian" msgstr "匈牙利语" -#: ../gtk/propertybox.c:1103 +#: ../gtk/propertybox.c:1182 msgid "Czech" msgstr "捷克语" -#: ../gtk/propertybox.c:1104 +#: ../gtk/propertybox.c:1183 msgid "Chinese" msgstr "中文" -#: ../gtk/propertybox.c:1105 +#: ../gtk/propertybox.c:1184 msgid "Traditional Chinese" msgstr "" -#: ../gtk/propertybox.c:1106 +#: ../gtk/propertybox.c:1185 msgid "Norwegian" msgstr "" -#: ../gtk/propertybox.c:1107 +#: ../gtk/propertybox.c:1186 msgid "Hebrew" msgstr "" -#: ../gtk/propertybox.c:1108 +#: ../gtk/propertybox.c:1187 msgid "Serbian" msgstr "" -#: ../gtk/propertybox.c:1175 +#: ../gtk/propertybox.c:1188 +msgid "Arabic" +msgstr "" + +#: ../gtk/propertybox.c:1189 +msgid "Turkish" +msgstr "" + +#: ../gtk/propertybox.c:1246 msgid "" "You need to restart linphone for the new language selection to take effect." msgstr "您需要重启 linphone 以使语言选择生效。" -#: ../gtk/propertybox.c:1255 +#: ../gtk/propertybox.c:1326 msgid "None" msgstr "" -#: ../gtk/propertybox.c:1259 +#: ../gtk/propertybox.c:1330 msgid "SRTP" msgstr "" -#: ../gtk/propertybox.c:1265 +#: ../gtk/propertybox.c:1336 msgid "DTLS" msgstr "" -#: ../gtk/propertybox.c:1272 +#: ../gtk/propertybox.c:1343 msgid "ZRTP" msgstr "" @@ -416,324 +442,195 @@ msgid "Found %i contact" msgid_plural "Found %i contacts" msgstr[0] "找到 %i 联系方式" -#: ../gtk/setupwizard.c:32 -msgid "" -"Welcome!\n" -"This assistant will help you to use a SIP account for your calls." -msgstr "" - -#: ../gtk/setupwizard.c:41 -msgid "Create an account on linphone.org" -msgstr "" - -#: ../gtk/setupwizard.c:42 -msgid "I have already a linphone.org account and I just want to use it" -msgstr "" - -#: ../gtk/setupwizard.c:43 -msgid "I have already a sip account and I just want to use it" -msgstr "" - -#: ../gtk/setupwizard.c:44 -msgid "I want to specify a remote configuration URI" -msgstr "" - -#: ../gtk/setupwizard.c:87 -msgid "Enter your linphone.org username" -msgstr "" - -#: ../gtk/setupwizard.c:100 ../gtk/parameters.ui.h:85 ../gtk/ldap.ui.h:4 -msgid "Username:" -msgstr "用户名:" - -#: ../gtk/setupwizard.c:102 ../gtk/password.ui.h:4 ../gtk/ldap.ui.h:5 -msgid "Password:" -msgstr "密码:" - -#: ../gtk/setupwizard.c:122 -msgid "Enter your account informations" -msgstr "" - -#: ../gtk/setupwizard.c:138 -msgid "Username*" -msgstr "" - -#: ../gtk/setupwizard.c:139 -msgid "Password*" -msgstr "" - -#: ../gtk/setupwizard.c:142 -msgid "Domain*" -msgstr "" - -#: ../gtk/setupwizard.c:143 -msgid "Proxy" -msgstr "" - -#: ../gtk/setupwizard.c:322 -msgid "(*) Required fields" -msgstr "" - -#: ../gtk/setupwizard.c:323 -msgid "Username: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:325 -msgid "Password: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:327 -msgid "Email: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:329 -msgid "Confirm your password: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:343 -msgid "Keep me informed with linphone updates" -msgstr "" - -#: ../gtk/setupwizard.c:399 -msgid "" -"Error, account not validated, username already used or server unreachable.\n" -"Please go back and try again." -msgstr "" - -#: ../gtk/setupwizard.c:410 -msgid "Thank you. Your account is now configured and ready for use." -msgstr "谢谢,您的帐户已经配置完毕,可以使用。" - -#: ../gtk/setupwizard.c:418 -msgid "" -"Please validate your account by clicking on the link we just sent you by email.\n" -"Then come back here and press Next button." -msgstr "" - -#: ../gtk/setupwizard.c:609 -msgid "SIP account configuration assistant" -msgstr "" - -#: ../gtk/setupwizard.c:629 -msgid "Welcome to the account setup assistant" -msgstr "欢迎使用帐户设置向导" - -#: ../gtk/setupwizard.c:634 -msgid "Account setup assistant" -msgstr "帐户设置向导" - -#: ../gtk/setupwizard.c:640 -msgid "Configure your account (step 1/1)" -msgstr "" - -#: ../gtk/setupwizard.c:645 -msgid "Enter your sip username (step 1/1)" -msgstr "" - -#: ../gtk/setupwizard.c:649 -msgid "Enter account information (step 1/2)" -msgstr "" - -#: ../gtk/setupwizard.c:658 -msgid "Validation (step 2/2)" -msgstr "" - -#: ../gtk/setupwizard.c:663 -msgid "Error" -msgstr "" - -#: ../gtk/setupwizard.c:667 ../gtk/audio_assistant.c:534 -msgid "Terminating" -msgstr "" - -#: ../gtk/incall_view.c:70 ../gtk/incall_view.c:94 +#: ../gtk/incall_view.c:67 ../gtk/incall_view.c:87 #, c-format msgid "Call #%i" msgstr "" -#: ../gtk/incall_view.c:155 +#: ../gtk/incall_view.c:145 #, c-format msgid "Transfer to call #%i with %s" msgstr "" -#: ../gtk/incall_view.c:211 ../gtk/incall_view.c:214 +#: ../gtk/incall_view.c:202 ../gtk/incall_view.c:205 msgid "Not used" msgstr "" -#: ../gtk/incall_view.c:221 +#: ../gtk/incall_view.c:212 msgid "ICE not activated" msgstr "" -#: ../gtk/incall_view.c:223 +#: ../gtk/incall_view.c:214 msgid "ICE failed" msgstr "" -#: ../gtk/incall_view.c:225 +#: ../gtk/incall_view.c:216 msgid "ICE in progress" msgstr "" -#: ../gtk/incall_view.c:227 +#: ../gtk/incall_view.c:218 msgid "Going through one or more NATs" msgstr "" -#: ../gtk/incall_view.c:229 +#: ../gtk/incall_view.c:220 msgid "Direct" msgstr "" -#: ../gtk/incall_view.c:231 +#: ../gtk/incall_view.c:222 msgid "Through a relay server" msgstr "" -#: ../gtk/incall_view.c:239 +#: ../gtk/incall_view.c:230 msgid "uPnP not activated" msgstr "" -#: ../gtk/incall_view.c:241 +#: ../gtk/incall_view.c:232 msgid "uPnP in progress" msgstr "" -#: ../gtk/incall_view.c:243 +#: ../gtk/incall_view.c:234 msgid "uPnp not available" msgstr "" -#: ../gtk/incall_view.c:245 +#: ../gtk/incall_view.c:236 msgid "uPnP is running" msgstr "" -#: ../gtk/incall_view.c:247 +#: ../gtk/incall_view.c:238 msgid "uPnP failed" msgstr "" -#: ../gtk/incall_view.c:257 ../gtk/incall_view.c:258 +#: ../gtk/incall_view.c:248 ../gtk/incall_view.c:249 msgid "Direct or through server" msgstr "" -#: ../gtk/incall_view.c:267 ../gtk/incall_view.c:279 +#: ../gtk/incall_view.c:258 ../gtk/incall_view.c:270 #, c-format msgid "" "download: %f\n" "upload: %f (kbit/s)" msgstr "" -#: ../gtk/incall_view.c:272 ../gtk/incall_view.c:274 +#: ../gtk/incall_view.c:263 ../gtk/incall_view.c:265 #, c-format msgid "%ix%i @ %f fps" msgstr "" -#: ../gtk/incall_view.c:304 +#: ../gtk/incall_view.c:295 #, c-format msgid "%.3f seconds" msgstr "" -#: ../gtk/incall_view.c:407 ../gtk/main.ui.h:12 ../gtk/videowindow.c:235 +#: ../gtk/incall_view.c:453 ../gtk/in_call_frame.ui.h:10 +#: ../gtk/videowindow.c:236 msgid "Hang up" msgstr "" -#: ../gtk/incall_view.c:511 +#: ../gtk/incall_view.c:559 msgid "Calling..." msgstr "正在呼叫..." -#: ../gtk/incall_view.c:514 ../gtk/incall_view.c:733 -msgid "00::00::00" -msgstr "00::00::00" +#: ../gtk/incall_view.c:562 ../gtk/incall_view.c:792 +msgid "00:00:00" +msgstr "" -#: ../gtk/incall_view.c:525 +#: ../gtk/incall_view.c:573 msgid "Incoming call" msgstr "" -#: ../gtk/incall_view.c:562 +#: ../gtk/incall_view.c:610 msgid "good" msgstr "" -#: ../gtk/incall_view.c:564 +#: ../gtk/incall_view.c:612 msgid "average" msgstr "" -#: ../gtk/incall_view.c:566 +#: ../gtk/incall_view.c:614 msgid "poor" msgstr "" -#: ../gtk/incall_view.c:568 +#: ../gtk/incall_view.c:616 msgid "very poor" msgstr "" -#: ../gtk/incall_view.c:570 +#: ../gtk/incall_view.c:618 msgid "too bad" msgstr "" -#: ../gtk/incall_view.c:571 ../gtk/incall_view.c:587 +#: ../gtk/incall_view.c:619 ../gtk/incall_view.c:635 msgid "unavailable" msgstr "" -#: ../gtk/incall_view.c:679 +#: ../gtk/incall_view.c:731 msgid "Secured by SRTP" msgstr "" -#: ../gtk/incall_view.c:685 +#: ../gtk/incall_view.c:737 msgid "Secured by DTLS" msgstr "" -#: ../gtk/incall_view.c:691 +#: ../gtk/incall_view.c:743 #, c-format msgid "Secured by ZRTP - [auth token: %s]" msgstr "" -#: ../gtk/incall_view.c:697 +#: ../gtk/incall_view.c:747 msgid "Set unverified" msgstr "" -#: ../gtk/incall_view.c:697 ../gtk/main.ui.h:4 +#: ../gtk/incall_view.c:747 msgid "Set verified" msgstr "" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In conference" msgstr "" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In call" msgstr "" -#: ../gtk/incall_view.c:764 +#: ../gtk/incall_view.c:824 msgid "Paused call" msgstr "" -#: ../gtk/incall_view.c:800 +#: ../gtk/incall_view.c:861 msgid "Call ended." msgstr "通话结束。" -#: ../gtk/incall_view.c:831 +#: ../gtk/incall_view.c:892 msgid "Transfer in progress" msgstr "" -#: ../gtk/incall_view.c:834 +#: ../gtk/incall_view.c:895 msgid "Transfer done." msgstr "" -#: ../gtk/incall_view.c:837 +#: ../gtk/incall_view.c:898 msgid "Transfer failed." msgstr "" -#: ../gtk/incall_view.c:881 +#: ../gtk/incall_view.c:929 msgid "Resume" msgstr "" -#: ../gtk/incall_view.c:888 ../gtk/main.ui.h:9 +#: ../gtk/incall_view.c:929 ../gtk/in_call_frame.ui.h:7 msgid "Pause" msgstr "" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 #, c-format msgid "" "Recording into\n" "%s %s" msgstr "" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 msgid "(Paused)" msgstr "" -#: ../gtk/loginframe.c:87 +#: ../gtk/loginframe.c:75 #, c-format msgid "Please enter login information for %s" msgstr "请输入 %s 的登录信息" @@ -748,262 +645,107 @@ msgstr "" msgid "Downloading of remote configuration from %s failed." msgstr "" -#: ../gtk/audio_assistant.c:98 +#: ../gtk/audio_assistant.c:103 msgid "No voice detected" msgstr "" -#: ../gtk/audio_assistant.c:99 +#: ../gtk/audio_assistant.c:104 msgid "Too low" msgstr "" -#: ../gtk/audio_assistant.c:100 +#: ../gtk/audio_assistant.c:105 msgid "Good" msgstr "" -#: ../gtk/audio_assistant.c:101 +#: ../gtk/audio_assistant.c:106 msgid "Too loud" msgstr "" -#: ../gtk/audio_assistant.c:183 +#: ../gtk/audio_assistant.c:188 msgid "Did you hear three beeps ?" msgstr "" -#: ../gtk/audio_assistant.c:292 ../gtk/audio_assistant.c:297 +#: ../gtk/audio_assistant.c:299 ../gtk/audio_assistant.c:304 msgid "Sound preferences not found " msgstr "" -#: ../gtk/audio_assistant.c:306 +#: ../gtk/audio_assistant.c:313 msgid "Cannot launch system sound control " msgstr "" -#: ../gtk/audio_assistant.c:318 +#: ../gtk/audio_assistant.c:325 msgid "" "Welcome!\n" "This assistant will help you to configure audio settings for Linphone" msgstr "" -#: ../gtk/audio_assistant.c:328 +#: ../gtk/audio_assistant.c:335 msgid "Capture device" msgstr "" -#: ../gtk/audio_assistant.c:329 +#: ../gtk/audio_assistant.c:336 msgid "Recorded volume" msgstr "" -#: ../gtk/audio_assistant.c:333 +#: ../gtk/audio_assistant.c:340 msgid "No voice" msgstr "" -#: ../gtk/audio_assistant.c:334 ../gtk/audio_assistant.c:373 +#: ../gtk/audio_assistant.c:341 ../gtk/audio_assistant.c:380 msgid "System sound preferences" msgstr "" -#: ../gtk/audio_assistant.c:369 +#: ../gtk/audio_assistant.c:376 msgid "Playback device" msgstr "" -#: ../gtk/audio_assistant.c:370 +#: ../gtk/audio_assistant.c:377 msgid "Play three beeps" msgstr "" -#: ../gtk/audio_assistant.c:403 +#: ../gtk/audio_assistant.c:410 msgid "Press the record button and say some words" msgstr "" -#: ../gtk/audio_assistant.c:404 +#: ../gtk/audio_assistant.c:411 msgid "Listen to your record voice" msgstr "" -#: ../gtk/audio_assistant.c:405 +#: ../gtk/audio_assistant.c:412 ../gtk/conf_frame.ui.h:2 +#: ../gtk/in_call_frame.ui.h:4 msgid "Record" msgstr "" -#: ../gtk/audio_assistant.c:406 +#: ../gtk/audio_assistant.c:413 msgid "Play" msgstr "" -#: ../gtk/audio_assistant.c:433 +#: ../gtk/audio_assistant.c:440 msgid "Let's start Linphone now" msgstr "" -#: ../gtk/audio_assistant.c:503 +#: ../gtk/audio_assistant.c:510 msgid "Audio Assistant" msgstr "" -#: ../gtk/audio_assistant.c:513 ../gtk/main.ui.h:32 +#: ../gtk/audio_assistant.c:520 ../gtk/main.ui.h:13 msgid "Audio assistant" msgstr "" -#: ../gtk/audio_assistant.c:518 +#: ../gtk/audio_assistant.c:525 msgid "Mic Gain calibration" msgstr "" -#: ../gtk/audio_assistant.c:524 +#: ../gtk/audio_assistant.c:531 msgid "Speaker volume calibration" msgstr "" -#: ../gtk/audio_assistant.c:529 +#: ../gtk/audio_assistant.c:536 msgid "Record and Play" msgstr "" -#: ../gtk/main.ui.h:1 -msgid "Callee name" -msgstr "" - -#: ../gtk/main.ui.h:2 -msgid "Send" -msgstr "发送" - -#: ../gtk/main.ui.h:3 -msgid "End conference" -msgstr "" - -#: ../gtk/main.ui.h:7 -msgid "Record this call to an audio file" -msgstr "" - -#: ../gtk/main.ui.h:8 -msgid "Video" -msgstr "" - -#: ../gtk/main.ui.h:10 -msgid "Mute" -msgstr "" - -#: ../gtk/main.ui.h:11 -msgid "Transfer" -msgstr "" - -#: ../gtk/main.ui.h:14 -msgid "In call" -msgstr "呼入" - -#: ../gtk/main.ui.h:15 -msgid "Duration" -msgstr "通话时间" - -#: ../gtk/main.ui.h:16 -msgid "Call quality rating" -msgstr "" - -#: ../gtk/main.ui.h:17 -msgid "All users" -msgstr "" - -#: ../gtk/main.ui.h:18 -msgid "Online users" -msgstr "" - -#: ../gtk/main.ui.h:19 -msgid "ADSL" -msgstr "" - -#: ../gtk/main.ui.h:20 -msgid "Fiber Channel" -msgstr "" - -#: ../gtk/main.ui.h:21 -msgid "Default" -msgstr "默认" - -#: ../gtk/main.ui.h:22 -msgid "Delete" -msgstr "" - -#: ../gtk/main.ui.h:23 -msgid "_Options" -msgstr "" - -#: ../gtk/main.ui.h:24 -msgid "Set configuration URI" -msgstr "" - -#: ../gtk/main.ui.h:25 -msgid "Always start video" -msgstr "" - -#: ../gtk/main.ui.h:26 -msgid "Enable self-view" -msgstr "启用自视" - -#: ../gtk/main.ui.h:27 -msgid "_Help" -msgstr "" - -#: ../gtk/main.ui.h:28 -msgid "Show debug window" -msgstr "" - -#: ../gtk/main.ui.h:29 -msgid "_Homepage" -msgstr "" - -#: ../gtk/main.ui.h:30 -msgid "Check _Updates" -msgstr "" - -#: ../gtk/main.ui.h:31 -msgid "Account assistant" -msgstr "" - -#: ../gtk/main.ui.h:33 -msgid "SIP address or phone number:" -msgstr "SIP 地址或电话号码:" - -#: ../gtk/main.ui.h:34 -msgid "Initiate a new call" -msgstr "" - -#: ../gtk/main.ui.h:35 -msgid "Contacts" -msgstr "联系人" - -#: ../gtk/main.ui.h:36 -msgid "Search" -msgstr "搜索" - -#: ../gtk/main.ui.h:37 -msgid "Add contacts from directory" -msgstr "从目录增加联系人" - -#: ../gtk/main.ui.h:38 -msgid "Add contact" -msgstr "" - -#: ../gtk/main.ui.h:39 -msgid "Recent calls" -msgstr "" - -#: ../gtk/main.ui.h:40 -msgid "My current identity:" -msgstr "当前地址:" - -#: ../gtk/main.ui.h:41 ../gtk/tunnel_config.ui.h:7 -msgid "Username" -msgstr "用户名" - -#: ../gtk/main.ui.h:42 ../gtk/tunnel_config.ui.h:8 -msgid "Password" -msgstr "密码" - -#: ../gtk/main.ui.h:43 -msgid "Internet connection:" -msgstr "网络连接:" - -#: ../gtk/main.ui.h:44 -msgid "Automatically log me in" -msgstr "自动登录" - -#: ../gtk/main.ui.h:45 ../gtk/password.ui.h:3 -msgid "UserID" -msgstr "用户 ID" - -#: ../gtk/main.ui.h:46 -msgid "Login information" -msgstr "登录信息" - -#: ../gtk/main.ui.h:47 -msgid "Welcome!" +#: ../gtk/audio_assistant.c:541 ../gtk/setup_wizard.ui.h:38 +msgid "Terminating" msgstr "" #: ../gtk/about.ui.h:1 @@ -1034,456 +776,6 @@ msgid "" "he: Eli Zaretskii \n" msgstr "" -#: ../gtk/contact.ui.h:2 -msgid "SIP Address" -msgstr "SIP 地址" - -#: ../gtk/contact.ui.h:3 -msgid "Show this contact presence status" -msgstr "显示该联系人的在线状态" - -#: ../gtk/contact.ui.h:4 -msgid "Allow this contact to see my presence status" -msgstr "允许此人看到我的在线状态" - -#: ../gtk/contact.ui.h:5 -msgid "Contact information" -msgstr "联系人信息" - -#: ../gtk/log.ui.h:1 -msgid "Linphone debug window" -msgstr "Linphone 调试窗口" - -#: ../gtk/log.ui.h:2 -msgid "Scroll to end" -msgstr "" - -#: ../gtk/password.ui.h:1 -msgid "Linphone - Authentication required" -msgstr "" - -#: ../gtk/password.ui.h:2 -msgid "Please enter the domain password" -msgstr "请输入密码" - -#: ../gtk/call_logs.ui.h:1 -msgid "Call history" -msgstr "呼叫历史" - -#: ../gtk/call_logs.ui.h:2 -msgid "Clear all" -msgstr "" - -#: ../gtk/call_logs.ui.h:3 -msgid "Call back" -msgstr "" - -#: ../gtk/sip_account.ui.h:1 -msgid "Linphone - Configure a SIP account" -msgstr "Linphone - 配置 SIP 帐户" - -#: ../gtk/sip_account.ui.h:2 -msgid "Your SIP identity:" -msgstr "您的 SIP 地址:" - -#: ../gtk/sip_account.ui.h:3 -msgid "Looks like sip:@" -msgstr "类似于 sip:<用户名>@<域>" - -#: ../gtk/sip_account.ui.h:4 -msgid "sip:" -msgstr "sip:" - -#: ../gtk/sip_account.ui.h:5 -msgid "SIP Proxy address:" -msgstr "SIP 代理地址:" - -#: ../gtk/sip_account.ui.h:6 -msgid "Looks like sip:" -msgstr "类似于 sip:<代理主机名>" - -#: ../gtk/sip_account.ui.h:7 -msgid "Registration duration (sec):" -msgstr "注册间隔(秒):" - -#: ../gtk/sip_account.ui.h:8 -msgid "Contact params (optional):" -msgstr "" - -#: ../gtk/sip_account.ui.h:9 -msgid "AVPF regular RTCP interval (sec):" -msgstr "" - -#: ../gtk/sip_account.ui.h:10 -msgid "Route (optional):" -msgstr "路由(可选):" - -#: ../gtk/sip_account.ui.h:11 -msgid "Transport" -msgstr "" - -#: ../gtk/sip_account.ui.h:12 -msgid "Register" -msgstr "" - -#: ../gtk/sip_account.ui.h:13 -msgid "Publish presence information" -msgstr "发布在线状态" - -#: ../gtk/sip_account.ui.h:14 -msgid "Enable AVPF" -msgstr "" - -#: ../gtk/sip_account.ui.h:15 -msgid "Configure a SIP account" -msgstr "配置 SIP 帐户" - -#: ../gtk/parameters.ui.h:1 -msgid "anonymous" -msgstr "" - -#: ../gtk/parameters.ui.h:2 -msgid "GSSAPI" -msgstr "" - -#: ../gtk/parameters.ui.h:3 -msgid "SASL" -msgstr "" - -#: ../gtk/parameters.ui.h:4 -msgid "default soundcard" -msgstr "默认声卡" - -#: ../gtk/parameters.ui.h:5 -msgid "a sound card" -msgstr "" - -#: ../gtk/parameters.ui.h:6 -msgid "default camera" -msgstr "默认摄像头" - -#: ../gtk/parameters.ui.h:7 -msgid "CIF" -msgstr "CIF" - -#: ../gtk/parameters.ui.h:8 -msgid "Audio codecs" -msgstr "" - -#: ../gtk/parameters.ui.h:9 -msgid "Video codecs" -msgstr "" - -#: ../gtk/parameters.ui.h:10 -msgid "C" -msgstr "C" - -#: ../gtk/parameters.ui.h:11 -msgid "SIP (UDP)" -msgstr "" - -#: ../gtk/parameters.ui.h:12 -msgid "SIP (TCP)" -msgstr "" - -#: ../gtk/parameters.ui.h:13 -msgid "SIP (TLS)" -msgstr "" - -#: ../gtk/parameters.ui.h:14 -msgid "Settings" -msgstr "设置" - -#: ../gtk/parameters.ui.h:15 -msgid "Set Maximum Transmission Unit:" -msgstr "设置最大传输单元(MTU):" - -#: ../gtk/parameters.ui.h:16 -msgid "Send DTMFs as SIP info" -msgstr "以 SIP 消息发送 DTMF" - -#: ../gtk/parameters.ui.h:17 -msgid "Allow IPv6" -msgstr "" - -#: ../gtk/parameters.ui.h:18 -msgid "Transport" -msgstr "传输协议" - -#: ../gtk/parameters.ui.h:19 -msgid "SIP/UDP port" -msgstr "" - -#: ../gtk/parameters.ui.h:21 -msgid "Random" -msgstr "" - -#: ../gtk/parameters.ui.h:22 -msgid "SIP/TCP port" -msgstr "" - -#: ../gtk/parameters.ui.h:23 -msgid "Audio RTP/UDP:" -msgstr "音频 RTP/UDP:" - -#: ../gtk/parameters.ui.h:24 -msgid "Fixed" -msgstr "" - -#: ../gtk/parameters.ui.h:25 -msgid "Video RTP/UDP:" -msgstr "视频 RTP/UDP:" - -#: ../gtk/parameters.ui.h:26 -msgid "Media encryption type" -msgstr "" - -#: ../gtk/parameters.ui.h:27 -msgid "Media encryption is mandatory" -msgstr "" - -#: ../gtk/parameters.ui.h:28 -msgid "Tunnel" -msgstr "" - -#: ../gtk/parameters.ui.h:29 -msgid "DSCP fields" -msgstr "" - -#: ../gtk/parameters.ui.h:30 -msgid "Network protocol and ports" -msgstr "" - -#: ../gtk/parameters.ui.h:31 -msgid "Direct connection to the Internet" -msgstr "直接连接到互联网" - -#: ../gtk/parameters.ui.h:32 -msgid "Behind NAT / Firewall (specify gateway IP )" -msgstr "" - -#: ../gtk/parameters.ui.h:33 -msgid "Behind NAT / Firewall (use STUN to resolve)" -msgstr "在 NAT 或防火墙后(使用 STUN 解决)" - -#: ../gtk/parameters.ui.h:34 -msgid "Behind NAT / Firewall (use ICE)" -msgstr "" - -#: ../gtk/parameters.ui.h:35 -msgid "Behind NAT / Firewall (use uPnP)" -msgstr "" - -#: ../gtk/parameters.ui.h:36 -msgid "Public IP address:" -msgstr "公网 IP 地址:" - -#: ../gtk/parameters.ui.h:37 -msgid "Stun server:" -msgstr "Stun 服务器:" - -#: ../gtk/parameters.ui.h:38 -msgid "NAT and Firewall" -msgstr "NAT 及防火墙" - -#: ../gtk/parameters.ui.h:39 -msgid "Network settings" -msgstr "网络设置" - -#: ../gtk/parameters.ui.h:40 -msgid "Ring sound:" -msgstr "铃声文件:" - -#: ../gtk/parameters.ui.h:41 -msgid "ALSA special device (optional):" -msgstr "ALSA 特殊设备(可选):" - -#: ../gtk/parameters.ui.h:42 -msgid "Capture device:" -msgstr "录音设备:" - -#: ../gtk/parameters.ui.h:43 -msgid "Ring device:" -msgstr "响铃设备:" - -#: ../gtk/parameters.ui.h:44 -msgid "Playback device:" -msgstr "回放设备:" - -#: ../gtk/parameters.ui.h:45 -msgid "Enable echo cancellation" -msgstr "启用回声抑制" - -#: ../gtk/parameters.ui.h:46 -msgid "Audio" -msgstr "音频" - -#: ../gtk/parameters.ui.h:47 -msgid "Video input device:" -msgstr "视频输入设备:" - -#: ../gtk/parameters.ui.h:48 -msgid "Prefered video resolution:" -msgstr "视频分辨率:" - -#: ../gtk/parameters.ui.h:49 -msgid "Video output method:" -msgstr "" - -#: ../gtk/parameters.ui.h:50 -msgid "Show camera preview" -msgstr "" - -#: ../gtk/parameters.ui.h:51 -msgid "Video" -msgstr "视频" - -#: ../gtk/parameters.ui.h:52 -msgid "Multimedia settings" -msgstr "音视频设置" - -#: ../gtk/parameters.ui.h:53 -msgid "This section defines your SIP address when not using a SIP account" -msgstr "该段在您不使用SIP帐户时的SIP地址" - -#: ../gtk/parameters.ui.h:54 -msgid "Your display name (eg: John Doe):" -msgstr "您的显示名:" - -#: ../gtk/parameters.ui.h:55 -msgid "Your username:" -msgstr "您的用户名:" - -#: ../gtk/parameters.ui.h:56 -msgid "Your resulting SIP address:" -msgstr "您的 SIP 地址结果:" - -#: ../gtk/parameters.ui.h:57 -msgid "Default identity" -msgstr "默认帐户" - -#: ../gtk/parameters.ui.h:58 -msgid "Wizard" -msgstr "" - -#: ../gtk/parameters.ui.h:59 -msgid "Add" -msgstr "添加" - -#: ../gtk/parameters.ui.h:60 -msgid "Edit" -msgstr "编辑" - -#: ../gtk/parameters.ui.h:61 -msgid "Remove" -msgstr "移除" - -#: ../gtk/parameters.ui.h:62 -msgid "Proxy accounts" -msgstr "代理帐户" - -#: ../gtk/parameters.ui.h:63 -msgid "Erase all passwords" -msgstr "清除所有密码" - -#: ../gtk/parameters.ui.h:64 -msgid "Privacy" -msgstr "隐私" - -#: ../gtk/parameters.ui.h:65 -msgid "Automatically answer when a call is received" -msgstr "" - -#: ../gtk/parameters.ui.h:66 -msgid "Delay before answering (ms)" -msgstr "" - -#: ../gtk/parameters.ui.h:67 -msgid "Auto-answer" -msgstr "" - -#: ../gtk/parameters.ui.h:68 -msgid "Manage SIP Accounts" -msgstr "SIP 帐户管理" - -#: ../gtk/parameters.ui.h:69 ../gtk/tunnel_config.ui.h:4 -msgid "Enable" -msgstr "启用" - -#: ../gtk/parameters.ui.h:70 ../gtk/tunnel_config.ui.h:5 -msgid "Disable" -msgstr "禁用" - -#: ../gtk/parameters.ui.h:71 -msgid "Codecs" -msgstr "编解码器" - -#: ../gtk/parameters.ui.h:72 -msgid "0 stands for \"unlimited\"" -msgstr "0 表示 “没有限制”" - -#: ../gtk/parameters.ui.h:73 -msgid "Upload speed limit in Kbit/sec:" -msgstr "上传速率限制 kbit/s:" - -#: ../gtk/parameters.ui.h:74 -msgid "Download speed limit in Kbit/sec:" -msgstr "下载速率限制 kbit/s:" - -#: ../gtk/parameters.ui.h:75 -msgid "Enable adaptive rate control" -msgstr "" - -#: ../gtk/parameters.ui.h:76 -msgid "" -"Adaptive rate control is a technique to dynamically guess the available " -"bandwidth during a call." -msgstr "" - -#: ../gtk/parameters.ui.h:77 -msgid "Bandwidth control" -msgstr "带宽控制" - -#: ../gtk/parameters.ui.h:78 -msgid "Codecs" -msgstr "编解码器" - -#: ../gtk/parameters.ui.h:79 -msgid "Language" -msgstr "语言" - -#: ../gtk/parameters.ui.h:80 -msgid "Show advanced settings" -msgstr "显示高级设置" - -#: ../gtk/parameters.ui.h:81 -msgid "Level" -msgstr "级别" - -#: ../gtk/parameters.ui.h:82 -msgid "User interface" -msgstr "用户界面" - -#: ../gtk/parameters.ui.h:83 ../gtk/ldap.ui.h:2 -msgid "Server address:" -msgstr "" - -#: ../gtk/parameters.ui.h:84 ../gtk/ldap.ui.h:3 -msgid "Authentication method:" -msgstr "" - -#: ../gtk/parameters.ui.h:86 -msgid "LDAP Account setup" -msgstr "" - -#: ../gtk/parameters.ui.h:87 -msgid "LDAP" -msgstr "" - -#: ../gtk/parameters.ui.h:88 -msgid "Done" -msgstr "完成" - #: ../gtk/buddylookup.ui.h:1 msgid "Search contacts in directory" msgstr "查找联系人" @@ -1496,28 +788,20 @@ msgstr "添加为联系人" msgid "Search somebody" msgstr "找人" -#: ../gtk/waiting.ui.h:2 -msgid "Please wait" -msgstr "请稍候" - -#: ../gtk/dscp_settings.ui.h:1 -msgid "DSCP settings" +#: ../gtk/callee_frame.ui.h:1 +msgid "Callee name" msgstr "" -#: ../gtk/dscp_settings.ui.h:2 -msgid "SIP" +#: ../gtk/call_logs.ui.h:1 +msgid "Call history" +msgstr "呼叫历史" + +#: ../gtk/call_logs.ui.h:2 +msgid "Clear all" msgstr "" -#: ../gtk/dscp_settings.ui.h:3 -msgid "Audio RTP stream" -msgstr "" - -#: ../gtk/dscp_settings.ui.h:4 -msgid "Video RTP stream" -msgstr "" - -#: ../gtk/dscp_settings.ui.h:5 -msgid "Set DSCP values (in hexadecimal)" +#: ../gtk/call_logs.ui.h:3 +msgid "Call back" msgstr "" #: ../gtk/call_statistics.ui.h:1 @@ -1568,30 +852,112 @@ msgstr "" msgid "Call statistics and information" msgstr "" -#: ../gtk/tunnel_config.ui.h:1 -msgid "Configure VoIP tunnel" +#: ../gtk/chatroom_frame.ui.h:1 +msgid "Send" +msgstr "发送" + +#: ../gtk/conf_frame.ui.h:1 +msgid "End conference" msgstr "" -#: ../gtk/tunnel_config.ui.h:2 -msgid "Host" +#: ../gtk/config-uri.ui.h:1 +msgid "Specifying a remote configuration URI" msgstr "" -#: ../gtk/tunnel_config.ui.h:3 -msgid "Port" +#: ../gtk/config-uri.ui.h:2 +msgid "" +"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" +"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " msgstr "" -#: ../gtk/tunnel_config.ui.h:6 -msgid "Configure tunnel" +#: ../gtk/contact.ui.h:2 +msgid "SIP Address" +msgstr "SIP 地址" + +#: ../gtk/contact.ui.h:3 +msgid "Show this contact presence status" +msgstr "显示该联系人的在线状态" + +#: ../gtk/contact.ui.h:4 +msgid "Allow this contact to see my presence status" +msgstr "允许此人看到我的在线状态" + +#: ../gtk/contact.ui.h:5 +msgid "Contact information" +msgstr "联系人信息" + +#: ../gtk/dscp_settings.ui.h:1 +msgid "DSCP settings" msgstr "" -#: ../gtk/tunnel_config.ui.h:9 -msgid "Configure http proxy (optional)" +#: ../gtk/dscp_settings.ui.h:2 +msgid "SIP" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:3 +msgid "Audio RTP stream" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:4 +msgid "Video RTP stream" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:5 +msgid "Set DSCP values (in hexadecimal)" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:1 +msgid "Click here to set the speakers volume" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:5 +msgid "Record this call to an audio file" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:6 +msgid "Video" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:8 +msgid "Mute" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:9 +msgid "Transfer" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:12 +msgid "In call" +msgstr "呼入" + +#: ../gtk/in_call_frame.ui.h:13 +msgid "Duration" +msgstr "通话时间" + +#: ../gtk/in_call_frame.ui.h:14 +msgid "Call quality rating" msgstr "" #: ../gtk/ldap.ui.h:1 msgid "LDAP Settings" msgstr "" +#: ../gtk/ldap.ui.h:2 ../gtk/parameters.ui.h:89 +msgid "Server address:" +msgstr "" + +#: ../gtk/ldap.ui.h:3 ../gtk/parameters.ui.h:90 +msgid "Authentication method:" +msgstr "" + +#: ../gtk/ldap.ui.h:4 ../gtk/parameters.ui.h:91 ../gtk/setup_wizard.ui.h:17 +msgid "Username:" +msgstr "用户名:" + +#: ../gtk/ldap.ui.h:5 ../gtk/password.ui.h:4 ../gtk/setup_wizard.ui.h:18 +msgid "Password:" +msgstr "密码:" + #: ../gtk/ldap.ui.h:6 msgid "Use TLS Connection" msgstr "" @@ -1677,16 +1043,504 @@ msgstr "" msgid "NTLM" msgstr "" -#: ../gtk/config-uri.ui.h:1 -msgid "Specifying a remote configuration URI" +#: ../gtk/login_frame.ui.h:1 ../gtk/tunnel_config.ui.h:7 +msgid "Username" +msgstr "用户名" + +#: ../gtk/login_frame.ui.h:2 ../gtk/tunnel_config.ui.h:8 +msgid "Password" +msgstr "密码" + +#: ../gtk/login_frame.ui.h:3 +msgid "Internet connection:" +msgstr "网络连接:" + +#: ../gtk/login_frame.ui.h:4 +msgid "Automatically log me in" +msgstr "自动登录" + +#: ../gtk/login_frame.ui.h:5 ../gtk/password.ui.h:3 +msgid "UserID" +msgstr "用户 ID" + +#: ../gtk/login_frame.ui.h:6 +msgid "Login information" +msgstr "登录信息" + +#: ../gtk/login_frame.ui.h:7 +msgid "Welcome!" msgstr "" -#: ../gtk/config-uri.ui.h:2 -msgid "" -"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" -"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " +#: ../gtk/login_frame.ui.h:8 +msgid "ADSL" msgstr "" +#: ../gtk/login_frame.ui.h:9 +msgid "Fiber Channel" +msgstr "" + +#: ../gtk/log.ui.h:1 +msgid "Linphone debug window" +msgstr "Linphone 调试窗口" + +#: ../gtk/log.ui.h:2 +msgid "Scroll to end" +msgstr "" + +#: ../gtk/main.ui.h:1 +msgid "Default" +msgstr "默认" + +#: ../gtk/main.ui.h:2 +msgid "Delete" +msgstr "" + +#: ../gtk/main.ui.h:3 +msgid "_Options" +msgstr "" + +#: ../gtk/main.ui.h:4 +msgid "Set configuration URI" +msgstr "" + +#: ../gtk/main.ui.h:5 +msgid "Always start video" +msgstr "" + +#: ../gtk/main.ui.h:6 +msgid "Enable self-view" +msgstr "启用自视" + +#: ../gtk/main.ui.h:7 +msgid "Show keypad" +msgstr "" + +#: ../gtk/main.ui.h:8 +msgid "_Help" +msgstr "" + +#: ../gtk/main.ui.h:9 +msgid "Show debug window" +msgstr "" + +#: ../gtk/main.ui.h:10 +msgid "_Homepage" +msgstr "" + +#: ../gtk/main.ui.h:11 +msgid "Check _Updates" +msgstr "" + +#: ../gtk/main.ui.h:12 +msgid "Account assistant" +msgstr "" + +#: ../gtk/main.ui.h:14 +msgid "SIP address or phone number:" +msgstr "SIP 地址或电话号码:" + +#: ../gtk/main.ui.h:15 +msgid "Initiate a new call" +msgstr "" + +#: ../gtk/main.ui.h:16 +msgid "Contacts" +msgstr "联系人" + +#: ../gtk/main.ui.h:17 +msgid "Search" +msgstr "搜索" + +#: ../gtk/main.ui.h:18 +msgid "Add contacts from directory" +msgstr "从目录增加联系人" + +#: ../gtk/main.ui.h:19 +msgid "Add contact" +msgstr "" + +#: ../gtk/main.ui.h:20 +msgid "Clear call history" +msgstr "" + +#: ../gtk/main.ui.h:22 +msgid "My current identity:" +msgstr "当前地址:" + +#: ../gtk/main.ui.h:23 +msgid "Autoanswer is enabled" +msgstr "" + +#: ../gtk/parameters.ui.h:1 +msgid "anonymous" +msgstr "" + +#: ../gtk/parameters.ui.h:2 +msgid "GSSAPI" +msgstr "" + +#: ../gtk/parameters.ui.h:3 +msgid "SASL" +msgstr "" + +#: ../gtk/parameters.ui.h:4 +msgid "default soundcard" +msgstr "默认声卡" + +#: ../gtk/parameters.ui.h:5 +msgid "a sound card" +msgstr "" + +#: ../gtk/parameters.ui.h:6 +msgid "default camera" +msgstr "默认摄像头" + +#: ../gtk/parameters.ui.h:7 +msgid "CIF" +msgstr "CIF" + +#: ../gtk/parameters.ui.h:8 +msgid "Audio codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:9 +msgid "Video codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:10 +msgid "C" +msgstr "C" + +#: ../gtk/parameters.ui.h:11 +msgid "SIP (UDP)" +msgstr "" + +#: ../gtk/parameters.ui.h:12 +msgid "SIP (TCP)" +msgstr "" + +#: ../gtk/parameters.ui.h:13 +msgid "SIP (TLS)" +msgstr "" + +#: ../gtk/parameters.ui.h:14 +msgid "default" +msgstr "" + +#: ../gtk/parameters.ui.h:15 +msgid "high-fps" +msgstr "" + +#: ../gtk/parameters.ui.h:16 +msgid "custom" +msgstr "" + +#: ../gtk/parameters.ui.h:17 +msgid "Settings" +msgstr "设置" + +#: ../gtk/parameters.ui.h:18 +msgid "This section defines your SIP address when not using a SIP account" +msgstr "该段在您不使用SIP帐户时的SIP地址" + +#: ../gtk/parameters.ui.h:19 +msgid "Your display name (eg: John Doe):" +msgstr "您的显示名:" + +#: ../gtk/parameters.ui.h:20 +msgid "Your username:" +msgstr "您的用户名:" + +#: ../gtk/parameters.ui.h:21 +msgid "Your resulting SIP address:" +msgstr "您的 SIP 地址结果:" + +#: ../gtk/parameters.ui.h:22 +msgid "Default identity" +msgstr "默认帐户" + +#: ../gtk/parameters.ui.h:23 +msgid "Wizard" +msgstr "" + +#: ../gtk/parameters.ui.h:24 +msgid "Add" +msgstr "添加" + +#: ../gtk/parameters.ui.h:25 +msgid "Edit" +msgstr "编辑" + +#: ../gtk/parameters.ui.h:26 +msgid "Remove" +msgstr "移除" + +#: ../gtk/parameters.ui.h:27 +msgid "Proxy accounts" +msgstr "代理帐户" + +#: ../gtk/parameters.ui.h:28 +msgid "Erase all passwords" +msgstr "清除所有密码" + +#: ../gtk/parameters.ui.h:29 +msgid "Privacy" +msgstr "隐私" + +#: ../gtk/parameters.ui.h:30 +msgid "Automatically answer when a call is received" +msgstr "" + +#: ../gtk/parameters.ui.h:31 +msgid "Delay before answering (ms)" +msgstr "" + +#: ../gtk/parameters.ui.h:32 +msgid "Auto-answer" +msgstr "" + +#: ../gtk/parameters.ui.h:33 +msgid "Manage SIP Accounts" +msgstr "SIP 帐户管理" + +#: ../gtk/parameters.ui.h:34 +msgid "Ring sound:" +msgstr "铃声文件:" + +#: ../gtk/parameters.ui.h:35 +msgid "ALSA special device (optional):" +msgstr "ALSA 特殊设备(可选):" + +#: ../gtk/parameters.ui.h:36 +msgid "Capture device:" +msgstr "录音设备:" + +#: ../gtk/parameters.ui.h:37 +msgid "Ring device:" +msgstr "响铃设备:" + +#: ../gtk/parameters.ui.h:38 +msgid "Playback device:" +msgstr "回放设备:" + +#: ../gtk/parameters.ui.h:39 +msgid "Enable echo cancellation" +msgstr "启用回声抑制" + +#: ../gtk/parameters.ui.h:40 +msgid "Audio" +msgstr "音频" + +#: ../gtk/parameters.ui.h:41 +msgid "Video input device:" +msgstr "视频输入设备:" + +#: ../gtk/parameters.ui.h:42 +msgid "Preferred video resolution:" +msgstr "" + +#: ../gtk/parameters.ui.h:43 +msgid "Video output method:" +msgstr "" + +#: ../gtk/parameters.ui.h:44 +msgid "Show camera preview" +msgstr "" + +#: ../gtk/parameters.ui.h:45 +msgid "Video preset:" +msgstr "" + +#: ../gtk/parameters.ui.h:46 +msgid "Preferred video framerate:" +msgstr "" + +#: ../gtk/parameters.ui.h:47 +msgid "0 stands for \"unlimited\"" +msgstr "0 表示 “没有限制”" + +#: ../gtk/parameters.ui.h:48 +msgid "Video" +msgstr "视频" + +#: ../gtk/parameters.ui.h:49 +msgid "Upload speed limit in Kbit/sec:" +msgstr "上传速率限制 kbit/s:" + +#: ../gtk/parameters.ui.h:50 +msgid "Download speed limit in Kbit/sec:" +msgstr "下载速率限制 kbit/s:" + +#: ../gtk/parameters.ui.h:51 +msgid "Enable adaptive rate control" +msgstr "" + +#: ../gtk/parameters.ui.h:52 +msgid "" +"Adaptive rate control is a technique to dynamically guess the available " +"bandwidth during a call." +msgstr "" + +#: ../gtk/parameters.ui.h:53 +msgid "Bandwidth control" +msgstr "带宽控制" + +#: ../gtk/parameters.ui.h:54 +msgid "Multimedia settings" +msgstr "音视频设置" + +#: ../gtk/parameters.ui.h:55 +msgid "Set Maximum Transmission Unit:" +msgstr "设置最大传输单元(MTU):" + +#: ../gtk/parameters.ui.h:56 +msgid "Send DTMFs as SIP info" +msgstr "以 SIP 消息发送 DTMF" + +#: ../gtk/parameters.ui.h:57 +msgid "Allow IPv6" +msgstr "" + +#: ../gtk/parameters.ui.h:58 +msgid "Transport" +msgstr "传输协议" + +#: ../gtk/parameters.ui.h:59 +msgid "SIP/UDP port" +msgstr "" + +#: ../gtk/parameters.ui.h:61 +msgid "Random" +msgstr "" + +#: ../gtk/parameters.ui.h:62 +msgid "SIP/TCP port" +msgstr "" + +#: ../gtk/parameters.ui.h:63 +msgid "Audio RTP/UDP:" +msgstr "音频 RTP/UDP:" + +#: ../gtk/parameters.ui.h:64 +msgid "Fixed" +msgstr "" + +#: ../gtk/parameters.ui.h:65 +msgid "Video RTP/UDP:" +msgstr "视频 RTP/UDP:" + +#: ../gtk/parameters.ui.h:66 +msgid "Media encryption type" +msgstr "" + +#: ../gtk/parameters.ui.h:67 +msgid "Media encryption is mandatory" +msgstr "" + +#: ../gtk/parameters.ui.h:68 +msgid "Tunnel" +msgstr "" + +#: ../gtk/parameters.ui.h:69 +msgid "DSCP fields" +msgstr "" + +#: ../gtk/parameters.ui.h:70 +msgid "Network protocol and ports" +msgstr "" + +#: ../gtk/parameters.ui.h:71 +msgid "Direct connection to the Internet" +msgstr "直接连接到互联网" + +#: ../gtk/parameters.ui.h:72 +msgid "Behind NAT / Firewall (specify gateway IP )" +msgstr "" + +#: ../gtk/parameters.ui.h:73 +msgid "Behind NAT / Firewall (use STUN to resolve)" +msgstr "在 NAT 或防火墙后(使用 STUN 解决)" + +#: ../gtk/parameters.ui.h:74 +msgid "Behind NAT / Firewall (use ICE)" +msgstr "" + +#: ../gtk/parameters.ui.h:75 +msgid "Behind NAT / Firewall (use uPnP)" +msgstr "" + +#: ../gtk/parameters.ui.h:76 +msgid "Public IP address:" +msgstr "公网 IP 地址:" + +#: ../gtk/parameters.ui.h:77 +msgid "Stun server:" +msgstr "Stun 服务器:" + +#: ../gtk/parameters.ui.h:78 +msgid "NAT and Firewall" +msgstr "NAT 及防火墙" + +#: ../gtk/parameters.ui.h:79 +msgid "Network settings" +msgstr "网络设置" + +#: ../gtk/parameters.ui.h:80 ../gtk/tunnel_config.ui.h:4 +msgid "Enable" +msgstr "启用" + +#: ../gtk/parameters.ui.h:81 ../gtk/tunnel_config.ui.h:5 +msgid "Disable" +msgstr "禁用" + +#: ../gtk/parameters.ui.h:82 +msgid "Audio codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:83 +msgid "Video codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:84 +msgid "Codecs" +msgstr "编解码器" + +#: ../gtk/parameters.ui.h:85 +msgid "Language" +msgstr "语言" + +#: ../gtk/parameters.ui.h:86 +msgid "Show advanced settings" +msgstr "显示高级设置" + +#: ../gtk/parameters.ui.h:87 +msgid "Level" +msgstr "级别" + +#: ../gtk/parameters.ui.h:88 +msgid "User interface" +msgstr "用户界面" + +#: ../gtk/parameters.ui.h:92 +msgid "LDAP Account setup" +msgstr "" + +#: ../gtk/parameters.ui.h:93 +msgid "LDAP" +msgstr "" + +#: ../gtk/parameters.ui.h:94 +msgid "Done" +msgstr "完成" + +#: ../gtk/password.ui.h:1 +msgid "Linphone - Authentication required" +msgstr "" + +#: ../gtk/password.ui.h:2 +msgid "Please enter the domain password" +msgstr "请输入密码" + #: ../gtk/provisioning-fetch.ui.h:1 msgid "Configuring..." msgstr "" @@ -1695,68 +1549,278 @@ msgstr "" msgid "Please wait while fetching configuration from server..." msgstr "" -#: ../coreapi/linphonecore.c:1539 +#: ../gtk/setup_wizard.ui.h:1 +msgid "SIP account configuration assistant" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:2 +msgid "" +"Welcome!\n" +"This assistant will help you to use a SIP account for your calls." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:4 +msgid "Welcome to the account setup assistant" +msgstr "欢迎使用帐户设置向导" + +#: ../gtk/setup_wizard.ui.h:5 +msgid "Create an account on linphone.org" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:6 +msgid "I have already a linphone.org account and I just want to use it" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:7 +msgid "I have already a sip account and I just want to use it" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:8 +msgid "I want to specify a remote configuration URI" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:9 +msgid "Account setup assistant" +msgstr "帐户设置向导" + +#: ../gtk/setup_wizard.ui.h:10 +msgid "Enter your account information" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:11 +msgid "Username*" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:12 +msgid "Password*" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:13 +msgid "Domain*" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:14 +msgid "Proxy" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:15 +msgid "Configure your account (step 1/1)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:16 +msgid "Enter your linphone.org username" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:19 +msgid "Enter your sip username (step 1/1)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:20 +msgid "(*) Required fields" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:21 +msgid "Email: (*)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:22 +msgid "Username: (*)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:23 +msgid "Password: (*)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:24 +msgid "Confirm your password: (*)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:25 +msgid "Keep me informed with linphone updates" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:26 +msgid "Enter account information (step 1/2)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:27 +msgid "Your account is being created, please wait." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:28 +msgid "Account creation in progress" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:29 +msgid "" +"Please validate your account by clicking on the link we just sent you by email.\n" +"Then come back here and press Next button." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:31 +msgid "Validation (step 2/2)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:32 +msgid "Checking if your account is been validated, please wait." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:33 +msgid "Account validation check in progress" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:34 +msgid "" +"Error, account not validated, username already used or server unreachable.\n" +"Please go back and try again." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:36 +msgid "Error" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:37 +msgid "Thank you. Your account is now configured and ready for use." +msgstr "谢谢,您的帐户已经配置完毕,可以使用。" + +#: ../gtk/sip_account.ui.h:1 +msgid "Linphone - Configure a SIP account" +msgstr "Linphone - 配置 SIP 帐户" + +#: ../gtk/sip_account.ui.h:2 +msgid "Your SIP identity:" +msgstr "您的 SIP 地址:" + +#: ../gtk/sip_account.ui.h:3 +msgid "Looks like sip:@" +msgstr "类似于 sip:<用户名>@<域>" + +#: ../gtk/sip_account.ui.h:4 +msgid "sip:" +msgstr "sip:" + +#: ../gtk/sip_account.ui.h:5 +msgid "SIP Proxy address:" +msgstr "SIP 代理地址:" + +#: ../gtk/sip_account.ui.h:6 +msgid "Looks like sip:" +msgstr "类似于 sip:<代理主机名>" + +#: ../gtk/sip_account.ui.h:7 +msgid "Registration duration (sec):" +msgstr "注册间隔(秒):" + +#: ../gtk/sip_account.ui.h:8 +msgid "Contact params (optional):" +msgstr "" + +#: ../gtk/sip_account.ui.h:9 +msgid "AVPF regular RTCP interval (sec):" +msgstr "" + +#: ../gtk/sip_account.ui.h:10 +msgid "Route (optional):" +msgstr "路由(可选):" + +#: ../gtk/sip_account.ui.h:11 +msgid "Transport" +msgstr "" + +#: ../gtk/sip_account.ui.h:12 +msgid "Register" +msgstr "" + +#: ../gtk/sip_account.ui.h:13 +msgid "Publish presence information" +msgstr "发布在线状态" + +#: ../gtk/sip_account.ui.h:14 +msgid "Enable AVPF" +msgstr "" + +#: ../gtk/sip_account.ui.h:15 +msgid "Configure a SIP account" +msgstr "配置 SIP 帐户" + +#: ../gtk/tunnel_config.ui.h:1 +msgid "Configure VoIP tunnel" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:2 +msgid "Host" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:3 +msgid "Port" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:6 +msgid "Configure tunnel" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:9 +msgid "Configure http proxy (optional)" +msgstr "" + +#: ../gtk/waiting.ui.h:2 +msgid "Please wait" +msgstr "请稍候" + +#: ../coreapi/linphonecore.c:1560 msgid "Ready" msgstr "就绪" -#: ../coreapi/linphonecore.c:2551 +#: ../coreapi/linphonecore.c:2556 msgid "Configuring" msgstr "" -#: ../coreapi/linphonecore.c:2725 -msgid "Looking for telephone number destination..." -msgstr "查询电话号码目的地..." - -#: ../coreapi/linphonecore.c:2727 -msgid "Could not resolve this number." -msgstr "该号码无法解析。" - #. must be known at that time -#: ../coreapi/linphonecore.c:3013 +#: ../coreapi/linphonecore.c:2951 msgid "Contacting" msgstr "联系中" -#: ../coreapi/linphonecore.c:3018 +#: ../coreapi/linphonecore.c:2956 msgid "Could not call" msgstr "" -#: ../coreapi/linphonecore.c:3169 +#: ../coreapi/linphonecore.c:3092 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "" -#: ../coreapi/linphonecore.c:3327 +#: ../coreapi/linphonecore.c:3250 msgid "is contacting you" msgstr "正在联系您" -#: ../coreapi/linphonecore.c:3328 +#: ../coreapi/linphonecore.c:3251 msgid " and asked autoanswer." msgstr " 并询问了自动回答。" -#: ../coreapi/linphonecore.c:3452 +#: ../coreapi/linphonecore.c:3377 msgid "Modifying call parameters..." msgstr "" -#: ../coreapi/linphonecore.c:3802 +#: ../coreapi/linphonecore.c:3769 msgid "Connected." msgstr "已连接。" -#: ../coreapi/linphonecore.c:3827 +#: ../coreapi/linphonecore.c:3794 msgid "Call aborted" msgstr "" -#: ../coreapi/linphonecore.c:4024 +#: ../coreapi/linphonecore.c:3983 msgid "Could not pause the call" msgstr "" -#: ../coreapi/linphonecore.c:4027 +#: ../coreapi/linphonecore.c:3986 msgid "Pausing the current call..." msgstr "" -#: ../coreapi/misc.c:434 +#: ../coreapi/misc.c:440 msgid "Stun lookup in progress..." msgstr "正在进行 Stun 查找..." -#: ../coreapi/misc.c:615 +#: ../coreapi/misc.c:650 msgid "ICE local candidates gathering in progress..." msgstr "" @@ -1812,165 +1876,172 @@ msgstr "" msgid "Unknown status" msgstr "" -#: ../coreapi/proxy.c:328 +#: ../coreapi/proxy.c:292 msgid "" "The sip proxy address you entered is invalid, it must start with \"sip:\" " "followed by a hostname." msgstr "您输入的 SIP 代理地址无效,它必须是以“sip:”开头,并紧随一个主机名。" -#: ../coreapi/proxy.c:334 +#: ../coreapi/proxy.c:298 msgid "" "The sip identity you entered is invalid.\n" "It should look like sip:username@proxydomain, such as sip:alice@example.net" msgstr "您输入的地址无效。\n它应具有“sip:用户名@代理域”的形式,例如 sip:alice@example.net" -#: ../coreapi/proxy.c:1416 +#: ../coreapi/proxy.c:927 +msgid "Looking for telephone number destination..." +msgstr "查询电话号码目的地..." + +#: ../coreapi/proxy.c:931 +msgid "Could not resolve this number." +msgstr "该号码无法解析。" + +#: ../coreapi/proxy.c:1324 #, c-format msgid "Could not login as %s" msgstr "无法登录为 %s" -#: ../coreapi/callbacks.c:428 +#: ../coreapi/proxy.c:1411 +#, c-format +msgid "Refreshing on %s..." +msgstr "" + +#: ../coreapi/callbacks.c:423 msgid "Remote ringing." msgstr "响铃。" -#: ../coreapi/callbacks.c:440 +#: ../coreapi/callbacks.c:435 msgid "Remote ringing..." msgstr "" -#: ../coreapi/callbacks.c:461 +#: ../coreapi/callbacks.c:458 msgid "Early media." msgstr "" -#: ../coreapi/callbacks.c:534 +#: ../coreapi/callbacks.c:488 #, c-format -msgid "Call with %s is paused." +msgid "Call answered by %s" msgstr "" -#: ../coreapi/callbacks.c:547 -#, c-format -msgid "Call answered by %s - on hold." -msgstr "" - -#: ../coreapi/callbacks.c:557 +#: ../coreapi/callbacks.c:527 msgid "Call resumed." msgstr "" -#: ../coreapi/callbacks.c:561 -#, c-format -msgid "Call answered by %s." -msgstr "" - -#: ../coreapi/callbacks.c:584 +#: ../coreapi/callbacks.c:582 msgid "Incompatible, check codecs or security settings..." msgstr "" -#: ../coreapi/callbacks.c:589 ../coreapi/callbacks.c:906 +#: ../coreapi/callbacks.c:587 ../coreapi/callbacks.c:923 msgid "Incompatible media parameters." msgstr "" -#: ../coreapi/callbacks.c:619 +#: ../coreapi/callbacks.c:612 msgid "We have been resumed." msgstr "" #. we are being paused -#: ../coreapi/callbacks.c:628 +#: ../coreapi/callbacks.c:620 msgid "We are paused by other party." msgstr "" -#. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:666 +#: ../coreapi/callbacks.c:630 msgid "Call is updated by remote." msgstr "" -#: ../coreapi/callbacks.c:782 +#: ../coreapi/callbacks.c:799 msgid "Call terminated." msgstr "通话结束。" -#: ../coreapi/callbacks.c:810 +#: ../coreapi/callbacks.c:827 msgid "User is busy." msgstr "被叫正忙。" -#: ../coreapi/callbacks.c:811 +#: ../coreapi/callbacks.c:828 msgid "User is temporarily unavailable." msgstr "您呼叫的用户暂时无法接通。" #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:813 +#: ../coreapi/callbacks.c:830 msgid "User does not want to be disturbed." msgstr "用户已开启免打扰功能。" -#: ../coreapi/callbacks.c:814 +#: ../coreapi/callbacks.c:831 msgid "Call declined." msgstr "呼叫被拒绝。" -#: ../coreapi/callbacks.c:829 +#: ../coreapi/callbacks.c:846 msgid "Request timeout." msgstr "" -#: ../coreapi/callbacks.c:860 +#: ../coreapi/callbacks.c:877 msgid "Redirected" msgstr "已重定向" -#: ../coreapi/callbacks.c:915 +#: ../coreapi/callbacks.c:927 msgid "Call failed." msgstr "呼叫失败。" -#: ../coreapi/callbacks.c:993 +#: ../coreapi/callbacks.c:1005 #, c-format msgid "Registration on %s successful." msgstr "成功注册到 %s" -#: ../coreapi/callbacks.c:994 +#: ../coreapi/callbacks.c:1006 #, c-format msgid "Unregistration on %s done." msgstr "已在 %s 解除注册。" -#: ../coreapi/callbacks.c:1012 +#: ../coreapi/callbacks.c:1024 msgid "no response timeout" msgstr "没有响应,超时" -#: ../coreapi/callbacks.c:1015 +#: ../coreapi/callbacks.c:1027 #, c-format msgid "Registration on %s failed: %s" msgstr "注册到 %s 失败: %s" -#: ../coreapi/callbacks.c:1022 +#: ../coreapi/callbacks.c:1034 msgid "Service unavailable, retrying" msgstr "" #. if encryption is DTLS, no status to be displayed -#: ../coreapi/linphonecall.c:180 +#: ../coreapi/linphonecall.c:197 #, c-format msgid "Authentication token is %s" msgstr "" -#: ../coreapi/linphonecall.c:1310 +#: ../coreapi/linphonecall.c:1561 +#, c-format +msgid "Call parameters could not be modified: %s." +msgstr "" + +#: ../coreapi/linphonecall.c:1563 msgid "Call parameters were successfully modified." msgstr "" -#: ../coreapi/linphonecall.c:3686 +#: ../coreapi/linphonecall.c:4396 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." msgstr[0] "您错过了 %i 个呼叫。" -#: ../coreapi/call_log.c:209 +#: ../coreapi/call_log.c:223 msgid "aborted" msgstr "" -#: ../coreapi/call_log.c:212 +#: ../coreapi/call_log.c:226 msgid "completed" msgstr "" -#: ../coreapi/call_log.c:215 +#: ../coreapi/call_log.c:229 msgid "missed" msgstr "" -#: ../coreapi/call_log.c:218 +#: ../coreapi/call_log.c:232 msgid "unknown" msgstr "" -#: ../coreapi/call_log.c:220 +#: ../coreapi/call_log.c:234 #, c-format msgid "" "%s at %s\n" @@ -1980,7 +2051,7 @@ msgid "" "Duration: %i mn %i sec\n" msgstr "" -#: ../coreapi/call_log.c:221 +#: ../coreapi/call_log.c:235 msgid "Outgoing call" msgstr "" diff --git a/po/zh_TW.po b/po/zh_TW.po index 0e5d4080f..95ddf0898 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -7,72 +7,81 @@ msgid "" msgstr "" "Project-Id-Version: linphone-gtk\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-04-30 10:13+0200\n" -"PO-Revision-Date: 2015-04-30 08:13+0000\n" +"POT-Creation-Date: 2015-11-10 15:16+0100\n" +"PO-Revision-Date: 2015-11-10 14:16+0000\n" "Last-Translator: Belledonne Communications \n" -"Language-Team: Chinese (Taiwan) (http://www.transifex.com/projects/p/linphone-gtk/language/zh_TW/)\n" +"Language-Team: Chinese (Taiwan) (http://www.transifex.com/belledonne-communications/linphone-gtk/language/zh_TW/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: zh_TW\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: ../gtk/calllogs.c:148 ../gtk/friendlist.c:974 +#: ../gtk/calllogs.c:178 #, c-format msgid "Call %s" msgstr "播打給 %s" -#: ../gtk/calllogs.c:149 ../gtk/friendlist.c:975 +#: ../gtk/calllogs.c:179 #, c-format msgid "Send text to %s" msgstr "傳送文字給 %s" -#: ../gtk/calllogs.c:232 +#: ../gtk/calllogs.c:181 +#, c-format +msgid "Add %s to your contact list" +msgstr "" + +#: ../gtk/calllogs.c:245 ../gtk/main.ui.h:21 +msgid "Recent calls" +msgstr "" + +#: ../gtk/calllogs.c:260 #, c-format msgid "Recent calls (%i)" msgstr "" -#: ../gtk/calllogs.c:314 +#: ../gtk/calllogs.c:331 msgid "n/a" msgstr "" -#: ../gtk/calllogs.c:317 +#: ../gtk/calllogs.c:334 msgid "Aborted" msgstr "" -#: ../gtk/calllogs.c:320 +#: ../gtk/calllogs.c:337 msgid "Missed" msgstr "" -#: ../gtk/calllogs.c:323 +#: ../gtk/calllogs.c:340 msgid "Declined" msgstr "" -#: ../gtk/calllogs.c:329 +#: ../gtk/calllogs.c:346 #, c-format msgid "%i minute" msgid_plural "%i minutes" msgstr[0] "" -#: ../gtk/calllogs.c:332 +#: ../gtk/calllogs.c:349 #, c-format msgid "%i second" msgid_plural "%i seconds" msgstr[0] "" -#: ../gtk/calllogs.c:337 +#: ../gtk/calllogs.c:354 #, c-format msgid "" "%s\tQuality: %s\n" "%s\t%s\t" msgstr "" -#: ../gtk/calllogs.c:341 +#: ../gtk/calllogs.c:358 #, c-format msgid "%s\t%s" msgstr "" -#: ../gtk/conference.c:38 ../gtk/main.ui.h:13 +#: ../gtk/conference.c:38 ../gtk/in_call_frame.ui.h:11 msgid "Conference" msgstr "" @@ -85,297 +94,314 @@ msgstr "" msgid "Couldn't find pixmap file: %s" msgstr "找不到 pixmap 檔:%s" -#: ../gtk/main.c:137 +#: ../gtk/chat.c:196 ../gtk/chat.c:254 +msgid "Sending..." +msgstr "" + +#: ../gtk/chat.c:213 ../gtk/chat.c:263 +msgid "Message not sent" +msgstr "" + +#: ../gtk/chat.c:472 +msgid "Copy" +msgstr "" + +#: ../gtk/main.c:138 msgid "log to stdout some debug information while running." msgstr "執行時將一些除錯資訊記錄到標準輸出。" -#: ../gtk/main.c:138 -msgid "path to a file to write logs into." -msgstr "" - #: ../gtk/main.c:139 -msgid "Start linphone with video disabled." +msgid "display version and exit." msgstr "" #: ../gtk/main.c:140 +msgid "path to a file to write logs into." +msgstr "" + +#: ../gtk/main.c:141 +msgid "Start linphone with video disabled." +msgstr "" + +#: ../gtk/main.c:142 msgid "Start only in the system tray, do not show the main interface." msgstr "只在系統匣啟動,不要顯示主要介面。" -#: ../gtk/main.c:141 +#: ../gtk/main.c:143 msgid "address to call right now" msgstr "現在要打電話的位址" -#: ../gtk/main.c:142 +#: ../gtk/main.c:144 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:143 +#: ../gtk/main.c:145 msgid "Configuration file" msgstr "" -#: ../gtk/main.c:144 +#: ../gtk/main.c:146 msgid "Run the audio assistant" msgstr "" -#: ../gtk/main.c:145 +#: ../gtk/main.c:147 msgid "Run self test and exit 0 if succeed" msgstr "" -#: ../gtk/main.c:1070 +#: ../gtk/main.c:1046 #, c-format msgid "" -"%s would like to add you to his contact list.\n" -"Would you allow him to see your presence status or add him to your contact list ?\n" +"%s would like to add you to his/her contact list.\n" +"Would you add him/her to your contact list and allow him/her to see your presence status?\n" "If you answer no, this person will be temporarily blacklisted." -msgstr "%s 想要加您加入他的連絡人清單。\n您是否要允許他看見您的上線狀態或將他加入您的連絡人清單?\n如果您回答否,這個人會被暫時列入黑名單。" +msgstr "" -#: ../gtk/main.c:1147 +#: ../gtk/main.c:1123 #, c-format msgid "" "Please enter your password for username %s\n" " at realm %s:" msgstr "" -#: ../gtk/main.c:1268 +#: ../gtk/main.c:1253 msgid "Call error" msgstr "" -#: ../gtk/main.c:1271 ../coreapi/linphonecore.c:3846 +#: ../gtk/main.c:1256 ../coreapi/linphonecore.c:3813 msgid "Call ended" msgstr "通話已結束" -#: ../gtk/main.c:1274 ../coreapi/call_log.c:221 +#: ../gtk/main.c:1259 ../coreapi/call_log.c:235 msgid "Incoming call" msgstr "來電" -#: ../gtk/main.c:1276 ../gtk/incall_view.c:532 ../gtk/main.ui.h:5 +#: ../gtk/main.c:1261 ../gtk/incall_view.c:580 ../gtk/in_call_frame.ui.h:2 msgid "Answer" msgstr "接聽" -#: ../gtk/main.c:1278 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1263 ../gtk/in_call_frame.ui.h:3 msgid "Decline" msgstr "拒接" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 msgid "Call paused" msgstr "" -#: ../gtk/main.c:1284 +#: ../gtk/main.c:1269 #, c-format msgid "by %s" msgstr "" -#: ../gtk/main.c:1354 +#: ../gtk/main.c:1339 #, c-format msgid "%s proposed to start video. Do you accept ?" msgstr "" -#: ../gtk/main.c:1509 +#: ../gtk/main.c:1505 msgid "Website link" msgstr "網站連結" -#: ../gtk/main.c:1568 ../gtk/waiting.ui.h:1 +#: ../gtk/main.c:1564 ../gtk/waiting.ui.h:1 msgid "Linphone" msgstr "Linphone" -#: ../gtk/main.c:1569 +#: ../gtk/main.c:1565 msgid "A video internet phone" msgstr "" -#: ../gtk/main.c:1629 +#: ../gtk/main.c:1624 #, c-format msgid "%s (Default)" msgstr "%s (預設值)" -#: ../gtk/main.c:1962 ../coreapi/callbacks.c:1063 +#: ../gtk/main.c:1960 ../coreapi/callbacks.c:1075 #, c-format msgid "We are transferred to %s" msgstr "我們被轉接到 %s" -#: ../gtk/main.c:1972 +#: ../gtk/main.c:1970 msgid "" "No sound cards have been detected on this computer.\n" "You won't be able to send or receive audio calls." msgstr "在這臺電腦中偵測不到音效卡。\n您將無法傳送或接收語音電話。" -#: ../gtk/main.c:2117 +#: ../gtk/main.c:2129 msgid "A free SIP video-phone" msgstr "自由的 SIP 視訊電話" -#: ../gtk/main.c:2221 +#: ../gtk/main.c:2242 #, c-format msgid "Hello\n" msgstr "" -#: ../gtk/friendlist.c:505 +#: ../gtk/friendlist.c:461 msgid "Add to addressbook" msgstr "" -#: ../gtk/friendlist.c:691 -msgid "Presence status" -msgstr "上線狀態" - -#: ../gtk/friendlist.c:709 ../gtk/propertybox.c:569 ../gtk/contact.ui.h:1 -msgid "Name" -msgstr "名稱" - -#: ../gtk/friendlist.c:721 -msgid "Call" -msgstr "" - -#: ../gtk/friendlist.c:726 -msgid "Chat" -msgstr "" - -#: ../gtk/friendlist.c:756 +#: ../gtk/friendlist.c:627 #, c-format msgid "Search in %s directory" msgstr "在 %s 目錄中搜尋" -#: ../gtk/friendlist.c:924 +#: ../gtk/friendlist.c:772 msgid "Invalid sip contact !" msgstr "無效的 sip 連絡人!" -#: ../gtk/friendlist.c:976 +#: ../gtk/friendlist.c:820 +#, c-format +msgid "Add a new contact" +msgstr "" + +#: ../gtk/friendlist.c:823 #, c-format msgid "Edit contact '%s'" msgstr "編輯連絡人「%s」" -#: ../gtk/friendlist.c:977 +#: ../gtk/friendlist.c:824 #, c-format msgid "Delete contact '%s'" msgstr "刪除連絡人「%s」" -#: ../gtk/friendlist.c:978 +#: ../gtk/friendlist.c:825 #, c-format msgid "Delete chat history of '%s'" msgstr "" -#: ../gtk/friendlist.c:1029 +#: ../gtk/friendlist.c:862 #, c-format msgid "Add new contact from %s directory" msgstr "從 %s 目錄加入新的連絡人" -#: ../gtk/propertybox.c:575 +#: ../gtk/propertybox.c:592 ../gtk/contact.ui.h:1 +msgid "Name" +msgstr "名稱" + +#: ../gtk/propertybox.c:598 msgid "Rate (Hz)" msgstr "頻率 (Hz)" -#: ../gtk/propertybox.c:581 +#: ../gtk/propertybox.c:604 msgid "Status" msgstr "狀態" -#: ../gtk/propertybox.c:587 +#: ../gtk/propertybox.c:617 msgid "IP Bitrate (kbit/s)" msgstr "" -#: ../gtk/propertybox.c:596 +#: ../gtk/propertybox.c:628 msgid "Parameters" msgstr "參數" -#: ../gtk/propertybox.c:639 ../gtk/propertybox.c:782 +#: ../gtk/propertybox.c:670 ../gtk/propertybox.c:824 msgid "Enabled" msgstr "已啟用" -#: ../gtk/propertybox.c:641 ../gtk/propertybox.c:782 ../gtk/parameters.ui.h:20 +#: ../gtk/propertybox.c:672 ../gtk/propertybox.c:824 ../gtk/parameters.ui.h:60 msgid "Disabled" msgstr "已停用" -#: ../gtk/propertybox.c:828 +#: ../gtk/propertybox.c:902 msgid "Account" msgstr "帳號" -#: ../gtk/propertybox.c:1091 +#: ../gtk/propertybox.c:1170 msgid "English" msgstr "英語" -#: ../gtk/propertybox.c:1092 +#: ../gtk/propertybox.c:1171 msgid "French" msgstr "法語" -#: ../gtk/propertybox.c:1093 +#: ../gtk/propertybox.c:1172 msgid "Swedish" msgstr "瑞典語" -#: ../gtk/propertybox.c:1094 +#: ../gtk/propertybox.c:1173 msgid "Italian" msgstr "義大利語" -#: ../gtk/propertybox.c:1095 +#: ../gtk/propertybox.c:1174 msgid "Spanish" msgstr "西班牙語" -#: ../gtk/propertybox.c:1096 +#: ../gtk/propertybox.c:1175 msgid "Brazilian Portugese" msgstr "巴西葡萄牙語" -#: ../gtk/propertybox.c:1097 +#: ../gtk/propertybox.c:1176 msgid "Polish" msgstr "波蘭語" -#: ../gtk/propertybox.c:1098 +#: ../gtk/propertybox.c:1177 msgid "German" msgstr "德語" -#: ../gtk/propertybox.c:1099 +#: ../gtk/propertybox.c:1178 msgid "Russian" msgstr "俄語" -#: ../gtk/propertybox.c:1100 +#: ../gtk/propertybox.c:1179 msgid "Japanese" msgstr "日語" -#: ../gtk/propertybox.c:1101 +#: ../gtk/propertybox.c:1180 msgid "Dutch" msgstr "荷蘭語" -#: ../gtk/propertybox.c:1102 +#: ../gtk/propertybox.c:1181 msgid "Hungarian" msgstr "匈牙利語" -#: ../gtk/propertybox.c:1103 +#: ../gtk/propertybox.c:1182 msgid "Czech" msgstr "捷克語" -#: ../gtk/propertybox.c:1104 +#: ../gtk/propertybox.c:1183 msgid "Chinese" msgstr "中文" -#: ../gtk/propertybox.c:1105 +#: ../gtk/propertybox.c:1184 msgid "Traditional Chinese" msgstr "" -#: ../gtk/propertybox.c:1106 +#: ../gtk/propertybox.c:1185 msgid "Norwegian" msgstr "" -#: ../gtk/propertybox.c:1107 +#: ../gtk/propertybox.c:1186 msgid "Hebrew" msgstr "" -#: ../gtk/propertybox.c:1108 +#: ../gtk/propertybox.c:1187 msgid "Serbian" msgstr "" -#: ../gtk/propertybox.c:1175 +#: ../gtk/propertybox.c:1188 +msgid "Arabic" +msgstr "" + +#: ../gtk/propertybox.c:1189 +msgid "Turkish" +msgstr "" + +#: ../gtk/propertybox.c:1246 msgid "" "You need to restart linphone for the new language selection to take effect." msgstr "您需要重新啟動 linphone 才能讓新選擇的語言生效。" -#: ../gtk/propertybox.c:1255 +#: ../gtk/propertybox.c:1326 msgid "None" msgstr "" -#: ../gtk/propertybox.c:1259 +#: ../gtk/propertybox.c:1330 msgid "SRTP" msgstr "" -#: ../gtk/propertybox.c:1265 +#: ../gtk/propertybox.c:1336 msgid "DTLS" msgstr "" -#: ../gtk/propertybox.c:1272 +#: ../gtk/propertybox.c:1343 msgid "ZRTP" msgstr "" @@ -416,324 +442,195 @@ msgid "Found %i contact" msgid_plural "Found %i contacts" msgstr[0] "找不到 %i 個連絡人" -#: ../gtk/setupwizard.c:32 -msgid "" -"Welcome!\n" -"This assistant will help you to use a SIP account for your calls." -msgstr "" - -#: ../gtk/setupwizard.c:41 -msgid "Create an account on linphone.org" -msgstr "" - -#: ../gtk/setupwizard.c:42 -msgid "I have already a linphone.org account and I just want to use it" -msgstr "" - -#: ../gtk/setupwizard.c:43 -msgid "I have already a sip account and I just want to use it" -msgstr "" - -#: ../gtk/setupwizard.c:44 -msgid "I want to specify a remote configuration URI" -msgstr "" - -#: ../gtk/setupwizard.c:87 -msgid "Enter your linphone.org username" -msgstr "" - -#: ../gtk/setupwizard.c:100 ../gtk/parameters.ui.h:85 ../gtk/ldap.ui.h:4 -msgid "Username:" -msgstr "使用者名稱:" - -#: ../gtk/setupwizard.c:102 ../gtk/password.ui.h:4 ../gtk/ldap.ui.h:5 -msgid "Password:" -msgstr "密碼: " - -#: ../gtk/setupwizard.c:122 -msgid "Enter your account informations" -msgstr "" - -#: ../gtk/setupwizard.c:138 -msgid "Username*" -msgstr "" - -#: ../gtk/setupwizard.c:139 -msgid "Password*" -msgstr "" - -#: ../gtk/setupwizard.c:142 -msgid "Domain*" -msgstr "" - -#: ../gtk/setupwizard.c:143 -msgid "Proxy" -msgstr "" - -#: ../gtk/setupwizard.c:322 -msgid "(*) Required fields" -msgstr "" - -#: ../gtk/setupwizard.c:323 -msgid "Username: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:325 -msgid "Password: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:327 -msgid "Email: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:329 -msgid "Confirm your password: (*)" -msgstr "" - -#: ../gtk/setupwizard.c:343 -msgid "Keep me informed with linphone updates" -msgstr "" - -#: ../gtk/setupwizard.c:399 -msgid "" -"Error, account not validated, username already used or server unreachable.\n" -"Please go back and try again." -msgstr "" - -#: ../gtk/setupwizard.c:410 -msgid "Thank you. Your account is now configured and ready for use." -msgstr "謝謝您。您的帳號已設定完成並且可以使用。" - -#: ../gtk/setupwizard.c:418 -msgid "" -"Please validate your account by clicking on the link we just sent you by email.\n" -"Then come back here and press Next button." -msgstr "" - -#: ../gtk/setupwizard.c:609 -msgid "SIP account configuration assistant" -msgstr "" - -#: ../gtk/setupwizard.c:629 -msgid "Welcome to the account setup assistant" -msgstr "歡迎使用帳號設定助理" - -#: ../gtk/setupwizard.c:634 -msgid "Account setup assistant" -msgstr "帳號設定助理" - -#: ../gtk/setupwizard.c:640 -msgid "Configure your account (step 1/1)" -msgstr "" - -#: ../gtk/setupwizard.c:645 -msgid "Enter your sip username (step 1/1)" -msgstr "" - -#: ../gtk/setupwizard.c:649 -msgid "Enter account information (step 1/2)" -msgstr "" - -#: ../gtk/setupwizard.c:658 -msgid "Validation (step 2/2)" -msgstr "" - -#: ../gtk/setupwizard.c:663 -msgid "Error" -msgstr "" - -#: ../gtk/setupwizard.c:667 ../gtk/audio_assistant.c:534 -msgid "Terminating" -msgstr "" - -#: ../gtk/incall_view.c:70 ../gtk/incall_view.c:94 +#: ../gtk/incall_view.c:67 ../gtk/incall_view.c:87 #, c-format msgid "Call #%i" msgstr "" -#: ../gtk/incall_view.c:155 +#: ../gtk/incall_view.c:145 #, c-format msgid "Transfer to call #%i with %s" msgstr "" -#: ../gtk/incall_view.c:211 ../gtk/incall_view.c:214 +#: ../gtk/incall_view.c:202 ../gtk/incall_view.c:205 msgid "Not used" msgstr "" -#: ../gtk/incall_view.c:221 +#: ../gtk/incall_view.c:212 msgid "ICE not activated" msgstr "" -#: ../gtk/incall_view.c:223 +#: ../gtk/incall_view.c:214 msgid "ICE failed" msgstr "" -#: ../gtk/incall_view.c:225 +#: ../gtk/incall_view.c:216 msgid "ICE in progress" msgstr "" -#: ../gtk/incall_view.c:227 +#: ../gtk/incall_view.c:218 msgid "Going through one or more NATs" msgstr "" -#: ../gtk/incall_view.c:229 +#: ../gtk/incall_view.c:220 msgid "Direct" msgstr "" -#: ../gtk/incall_view.c:231 +#: ../gtk/incall_view.c:222 msgid "Through a relay server" msgstr "" -#: ../gtk/incall_view.c:239 +#: ../gtk/incall_view.c:230 msgid "uPnP not activated" msgstr "" -#: ../gtk/incall_view.c:241 +#: ../gtk/incall_view.c:232 msgid "uPnP in progress" msgstr "" -#: ../gtk/incall_view.c:243 +#: ../gtk/incall_view.c:234 msgid "uPnp not available" msgstr "" -#: ../gtk/incall_view.c:245 +#: ../gtk/incall_view.c:236 msgid "uPnP is running" msgstr "" -#: ../gtk/incall_view.c:247 +#: ../gtk/incall_view.c:238 msgid "uPnP failed" msgstr "" -#: ../gtk/incall_view.c:257 ../gtk/incall_view.c:258 +#: ../gtk/incall_view.c:248 ../gtk/incall_view.c:249 msgid "Direct or through server" msgstr "" -#: ../gtk/incall_view.c:267 ../gtk/incall_view.c:279 +#: ../gtk/incall_view.c:258 ../gtk/incall_view.c:270 #, c-format msgid "" "download: %f\n" "upload: %f (kbit/s)" msgstr "" -#: ../gtk/incall_view.c:272 ../gtk/incall_view.c:274 +#: ../gtk/incall_view.c:263 ../gtk/incall_view.c:265 #, c-format msgid "%ix%i @ %f fps" msgstr "" -#: ../gtk/incall_view.c:304 +#: ../gtk/incall_view.c:295 #, c-format msgid "%.3f seconds" msgstr "" -#: ../gtk/incall_view.c:407 ../gtk/main.ui.h:12 ../gtk/videowindow.c:235 +#: ../gtk/incall_view.c:453 ../gtk/in_call_frame.ui.h:10 +#: ../gtk/videowindow.c:236 msgid "Hang up" msgstr "" -#: ../gtk/incall_view.c:511 +#: ../gtk/incall_view.c:559 msgid "Calling..." msgstr "播打..." -#: ../gtk/incall_view.c:514 ../gtk/incall_view.c:733 -msgid "00::00::00" -msgstr "00::00::00" +#: ../gtk/incall_view.c:562 ../gtk/incall_view.c:792 +msgid "00:00:00" +msgstr "" -#: ../gtk/incall_view.c:525 +#: ../gtk/incall_view.c:573 msgid "Incoming call" msgstr "來電" -#: ../gtk/incall_view.c:562 +#: ../gtk/incall_view.c:610 msgid "good" msgstr "" -#: ../gtk/incall_view.c:564 +#: ../gtk/incall_view.c:612 msgid "average" msgstr "" -#: ../gtk/incall_view.c:566 +#: ../gtk/incall_view.c:614 msgid "poor" msgstr "" -#: ../gtk/incall_view.c:568 +#: ../gtk/incall_view.c:616 msgid "very poor" msgstr "" -#: ../gtk/incall_view.c:570 +#: ../gtk/incall_view.c:618 msgid "too bad" msgstr "" -#: ../gtk/incall_view.c:571 ../gtk/incall_view.c:587 +#: ../gtk/incall_view.c:619 ../gtk/incall_view.c:635 msgid "unavailable" msgstr "" -#: ../gtk/incall_view.c:679 +#: ../gtk/incall_view.c:731 msgid "Secured by SRTP" msgstr "" -#: ../gtk/incall_view.c:685 +#: ../gtk/incall_view.c:737 msgid "Secured by DTLS" msgstr "" -#: ../gtk/incall_view.c:691 +#: ../gtk/incall_view.c:743 #, c-format msgid "Secured by ZRTP - [auth token: %s]" msgstr "" -#: ../gtk/incall_view.c:697 +#: ../gtk/incall_view.c:747 msgid "Set unverified" msgstr "" -#: ../gtk/incall_view.c:697 ../gtk/main.ui.h:4 +#: ../gtk/incall_view.c:747 msgid "Set verified" msgstr "" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In conference" msgstr "" -#: ../gtk/incall_view.c:728 +#: ../gtk/incall_view.c:787 msgid "In call" msgstr "通話中" -#: ../gtk/incall_view.c:764 +#: ../gtk/incall_view.c:824 msgid "Paused call" msgstr "暫停通話" -#: ../gtk/incall_view.c:800 +#: ../gtk/incall_view.c:861 msgid "Call ended." msgstr "通話結束。" -#: ../gtk/incall_view.c:831 +#: ../gtk/incall_view.c:892 msgid "Transfer in progress" msgstr "" -#: ../gtk/incall_view.c:834 +#: ../gtk/incall_view.c:895 msgid "Transfer done." msgstr "" -#: ../gtk/incall_view.c:837 +#: ../gtk/incall_view.c:898 msgid "Transfer failed." msgstr "" -#: ../gtk/incall_view.c:881 +#: ../gtk/incall_view.c:929 msgid "Resume" msgstr "繼續" -#: ../gtk/incall_view.c:888 ../gtk/main.ui.h:9 +#: ../gtk/incall_view.c:929 ../gtk/in_call_frame.ui.h:7 msgid "Pause" msgstr "暫停" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 #, c-format msgid "" "Recording into\n" "%s %s" msgstr "" -#: ../gtk/incall_view.c:954 +#: ../gtk/incall_view.c:995 msgid "(Paused)" msgstr "" -#: ../gtk/loginframe.c:87 +#: ../gtk/loginframe.c:75 #, c-format msgid "Please enter login information for %s" msgstr "請輸入 %s 的 登入資訊" @@ -748,262 +645,107 @@ msgstr "" msgid "Downloading of remote configuration from %s failed." msgstr "" -#: ../gtk/audio_assistant.c:98 +#: ../gtk/audio_assistant.c:103 msgid "No voice detected" msgstr "" -#: ../gtk/audio_assistant.c:99 +#: ../gtk/audio_assistant.c:104 msgid "Too low" msgstr "" -#: ../gtk/audio_assistant.c:100 +#: ../gtk/audio_assistant.c:105 msgid "Good" msgstr "" -#: ../gtk/audio_assistant.c:101 +#: ../gtk/audio_assistant.c:106 msgid "Too loud" msgstr "" -#: ../gtk/audio_assistant.c:183 +#: ../gtk/audio_assistant.c:188 msgid "Did you hear three beeps ?" msgstr "" -#: ../gtk/audio_assistant.c:292 ../gtk/audio_assistant.c:297 +#: ../gtk/audio_assistant.c:299 ../gtk/audio_assistant.c:304 msgid "Sound preferences not found " msgstr "" -#: ../gtk/audio_assistant.c:306 +#: ../gtk/audio_assistant.c:313 msgid "Cannot launch system sound control " msgstr "" -#: ../gtk/audio_assistant.c:318 +#: ../gtk/audio_assistant.c:325 msgid "" "Welcome!\n" "This assistant will help you to configure audio settings for Linphone" msgstr "" -#: ../gtk/audio_assistant.c:328 +#: ../gtk/audio_assistant.c:335 msgid "Capture device" msgstr "" -#: ../gtk/audio_assistant.c:329 +#: ../gtk/audio_assistant.c:336 msgid "Recorded volume" msgstr "" -#: ../gtk/audio_assistant.c:333 +#: ../gtk/audio_assistant.c:340 msgid "No voice" msgstr "" -#: ../gtk/audio_assistant.c:334 ../gtk/audio_assistant.c:373 +#: ../gtk/audio_assistant.c:341 ../gtk/audio_assistant.c:380 msgid "System sound preferences" msgstr "" -#: ../gtk/audio_assistant.c:369 +#: ../gtk/audio_assistant.c:376 msgid "Playback device" msgstr "" -#: ../gtk/audio_assistant.c:370 +#: ../gtk/audio_assistant.c:377 msgid "Play three beeps" msgstr "" -#: ../gtk/audio_assistant.c:403 +#: ../gtk/audio_assistant.c:410 msgid "Press the record button and say some words" msgstr "" -#: ../gtk/audio_assistant.c:404 +#: ../gtk/audio_assistant.c:411 msgid "Listen to your record voice" msgstr "" -#: ../gtk/audio_assistant.c:405 +#: ../gtk/audio_assistant.c:412 ../gtk/conf_frame.ui.h:2 +#: ../gtk/in_call_frame.ui.h:4 msgid "Record" msgstr "" -#: ../gtk/audio_assistant.c:406 +#: ../gtk/audio_assistant.c:413 msgid "Play" msgstr "" -#: ../gtk/audio_assistant.c:433 +#: ../gtk/audio_assistant.c:440 msgid "Let's start Linphone now" msgstr "" -#: ../gtk/audio_assistant.c:503 +#: ../gtk/audio_assistant.c:510 msgid "Audio Assistant" msgstr "" -#: ../gtk/audio_assistant.c:513 ../gtk/main.ui.h:32 +#: ../gtk/audio_assistant.c:520 ../gtk/main.ui.h:13 msgid "Audio assistant" msgstr "" -#: ../gtk/audio_assistant.c:518 +#: ../gtk/audio_assistant.c:525 msgid "Mic Gain calibration" msgstr "" -#: ../gtk/audio_assistant.c:524 +#: ../gtk/audio_assistant.c:531 msgid "Speaker volume calibration" msgstr "" -#: ../gtk/audio_assistant.c:529 +#: ../gtk/audio_assistant.c:536 msgid "Record and Play" msgstr "" -#: ../gtk/main.ui.h:1 -msgid "Callee name" -msgstr "" - -#: ../gtk/main.ui.h:2 -msgid "Send" -msgstr "傳送" - -#: ../gtk/main.ui.h:3 -msgid "End conference" -msgstr "" - -#: ../gtk/main.ui.h:7 -msgid "Record this call to an audio file" -msgstr "" - -#: ../gtk/main.ui.h:8 -msgid "Video" -msgstr "" - -#: ../gtk/main.ui.h:10 -msgid "Mute" -msgstr "" - -#: ../gtk/main.ui.h:11 -msgid "Transfer" -msgstr "轉接" - -#: ../gtk/main.ui.h:14 -msgid "In call" -msgstr "通話中" - -#: ../gtk/main.ui.h:15 -msgid "Duration" -msgstr "時間長度" - -#: ../gtk/main.ui.h:16 -msgid "Call quality rating" -msgstr "" - -#: ../gtk/main.ui.h:17 -msgid "All users" -msgstr "所有使用者" - -#: ../gtk/main.ui.h:18 -msgid "Online users" -msgstr "線上使用者" - -#: ../gtk/main.ui.h:19 -msgid "ADSL" -msgstr "ADSL" - -#: ../gtk/main.ui.h:20 -msgid "Fiber Channel" -msgstr "光纖通道" - -#: ../gtk/main.ui.h:21 -msgid "Default" -msgstr "預設值" - -#: ../gtk/main.ui.h:22 -msgid "Delete" -msgstr "" - -#: ../gtk/main.ui.h:23 -msgid "_Options" -msgstr "選項(_O)" - -#: ../gtk/main.ui.h:24 -msgid "Set configuration URI" -msgstr "" - -#: ../gtk/main.ui.h:25 -msgid "Always start video" -msgstr "" - -#: ../gtk/main.ui.h:26 -msgid "Enable self-view" -msgstr "啟用自拍檢視" - -#: ../gtk/main.ui.h:27 -msgid "_Help" -msgstr "求助(_H)" - -#: ../gtk/main.ui.h:28 -msgid "Show debug window" -msgstr "顯示除錯視窗" - -#: ../gtk/main.ui.h:29 -msgid "_Homepage" -msgstr "官方網頁(_H)" - -#: ../gtk/main.ui.h:30 -msgid "Check _Updates" -msgstr "檢查更新(_U)" - -#: ../gtk/main.ui.h:31 -msgid "Account assistant" -msgstr "" - -#: ../gtk/main.ui.h:33 -msgid "SIP address or phone number:" -msgstr "SIP 位址或電話號碼:" - -#: ../gtk/main.ui.h:34 -msgid "Initiate a new call" -msgstr "打出新電話" - -#: ../gtk/main.ui.h:35 -msgid "Contacts" -msgstr "連絡人" - -#: ../gtk/main.ui.h:36 -msgid "Search" -msgstr "搜尋" - -#: ../gtk/main.ui.h:37 -msgid "Add contacts from directory" -msgstr "從目錄加入連絡人" - -#: ../gtk/main.ui.h:38 -msgid "Add contact" -msgstr "加入聯絡人" - -#: ../gtk/main.ui.h:39 -msgid "Recent calls" -msgstr "" - -#: ../gtk/main.ui.h:40 -msgid "My current identity:" -msgstr "我目前的使用者識別:" - -#: ../gtk/main.ui.h:41 ../gtk/tunnel_config.ui.h:7 -msgid "Username" -msgstr "使用者名稱" - -#: ../gtk/main.ui.h:42 ../gtk/tunnel_config.ui.h:8 -msgid "Password" -msgstr "密碼" - -#: ../gtk/main.ui.h:43 -msgid "Internet connection:" -msgstr "網路連線:" - -#: ../gtk/main.ui.h:44 -msgid "Automatically log me in" -msgstr "將我自動登入" - -#: ../gtk/main.ui.h:45 ../gtk/password.ui.h:3 -msgid "UserID" -msgstr "使用者ID" - -#: ../gtk/main.ui.h:46 -msgid "Login information" -msgstr "登入資訊" - -#: ../gtk/main.ui.h:47 -msgid "Welcome!" +#: ../gtk/audio_assistant.c:541 ../gtk/setup_wizard.ui.h:38 +msgid "Terminating" msgstr "" #: ../gtk/about.ui.h:1 @@ -1034,456 +776,6 @@ msgid "" "he: Eli Zaretskii \n" msgstr "" -#: ../gtk/contact.ui.h:2 -msgid "SIP Address" -msgstr "SIP 位址" - -#: ../gtk/contact.ui.h:3 -msgid "Show this contact presence status" -msgstr "顯示這個連絡人的上線狀態" - -#: ../gtk/contact.ui.h:4 -msgid "Allow this contact to see my presence status" -msgstr "允許這個連絡人看到我的上線狀態" - -#: ../gtk/contact.ui.h:5 -msgid "Contact information" -msgstr "連絡人資訊" - -#: ../gtk/log.ui.h:1 -msgid "Linphone debug window" -msgstr "Linphone 除錯視窗" - -#: ../gtk/log.ui.h:2 -msgid "Scroll to end" -msgstr "" - -#: ../gtk/password.ui.h:1 -msgid "Linphone - Authentication required" -msgstr "Linphone - 需要驗證" - -#: ../gtk/password.ui.h:2 -msgid "Please enter the domain password" -msgstr "請輸入這個網域的密碼" - -#: ../gtk/call_logs.ui.h:1 -msgid "Call history" -msgstr "通話紀錄" - -#: ../gtk/call_logs.ui.h:2 -msgid "Clear all" -msgstr "全部清除" - -#: ../gtk/call_logs.ui.h:3 -msgid "Call back" -msgstr "回電" - -#: ../gtk/sip_account.ui.h:1 -msgid "Linphone - Configure a SIP account" -msgstr "Linphone - 設定 SIP 帳號" - -#: ../gtk/sip_account.ui.h:2 -msgid "Your SIP identity:" -msgstr "您的 SIP 使用者識別:" - -#: ../gtk/sip_account.ui.h:3 -msgid "Looks like sip:@" -msgstr "看起來像 sip:@" - -#: ../gtk/sip_account.ui.h:4 -msgid "sip:" -msgstr "sip:" - -#: ../gtk/sip_account.ui.h:5 -msgid "SIP Proxy address:" -msgstr "SIP 代理位址:" - -#: ../gtk/sip_account.ui.h:6 -msgid "Looks like sip:" -msgstr "看起來像 sip:" - -#: ../gtk/sip_account.ui.h:7 -msgid "Registration duration (sec):" -msgstr "註冊時間 (秒):" - -#: ../gtk/sip_account.ui.h:8 -msgid "Contact params (optional):" -msgstr "" - -#: ../gtk/sip_account.ui.h:9 -msgid "AVPF regular RTCP interval (sec):" -msgstr "" - -#: ../gtk/sip_account.ui.h:10 -msgid "Route (optional):" -msgstr "路由 (選擇性):" - -#: ../gtk/sip_account.ui.h:11 -msgid "Transport" -msgstr "" - -#: ../gtk/sip_account.ui.h:12 -msgid "Register" -msgstr "" - -#: ../gtk/sip_account.ui.h:13 -msgid "Publish presence information" -msgstr "發布上線資訊" - -#: ../gtk/sip_account.ui.h:14 -msgid "Enable AVPF" -msgstr "" - -#: ../gtk/sip_account.ui.h:15 -msgid "Configure a SIP account" -msgstr "設定 SIP 帳號" - -#: ../gtk/parameters.ui.h:1 -msgid "anonymous" -msgstr "" - -#: ../gtk/parameters.ui.h:2 -msgid "GSSAPI" -msgstr "" - -#: ../gtk/parameters.ui.h:3 -msgid "SASL" -msgstr "" - -#: ../gtk/parameters.ui.h:4 -msgid "default soundcard" -msgstr "預設的音效卡" - -#: ../gtk/parameters.ui.h:5 -msgid "a sound card" -msgstr "音效卡" - -#: ../gtk/parameters.ui.h:6 -msgid "default camera" -msgstr "預設的攝影機" - -#: ../gtk/parameters.ui.h:7 -msgid "CIF" -msgstr "CIF" - -#: ../gtk/parameters.ui.h:8 -msgid "Audio codecs" -msgstr "音訊編碼解碼器" - -#: ../gtk/parameters.ui.h:9 -msgid "Video codecs" -msgstr "視訊編碼解碼器" - -#: ../gtk/parameters.ui.h:10 -msgid "C" -msgstr "C" - -#: ../gtk/parameters.ui.h:11 -msgid "SIP (UDP)" -msgstr "" - -#: ../gtk/parameters.ui.h:12 -msgid "SIP (TCP)" -msgstr "" - -#: ../gtk/parameters.ui.h:13 -msgid "SIP (TLS)" -msgstr "" - -#: ../gtk/parameters.ui.h:14 -msgid "Settings" -msgstr "設定值" - -#: ../gtk/parameters.ui.h:15 -msgid "Set Maximum Transmission Unit:" -msgstr "設定最大傳輸單位:" - -#: ../gtk/parameters.ui.h:16 -msgid "Send DTMFs as SIP info" -msgstr "傳送 DTMFs 為 SIP 資訊" - -#: ../gtk/parameters.ui.h:17 -msgid "Allow IPv6" -msgstr "" - -#: ../gtk/parameters.ui.h:18 -msgid "Transport" -msgstr "傳輸" - -#: ../gtk/parameters.ui.h:19 -msgid "SIP/UDP port" -msgstr "" - -#: ../gtk/parameters.ui.h:21 -msgid "Random" -msgstr "" - -#: ../gtk/parameters.ui.h:22 -msgid "SIP/TCP port" -msgstr "" - -#: ../gtk/parameters.ui.h:23 -msgid "Audio RTP/UDP:" -msgstr "音效 RTP/UDP:" - -#: ../gtk/parameters.ui.h:24 -msgid "Fixed" -msgstr "" - -#: ../gtk/parameters.ui.h:25 -msgid "Video RTP/UDP:" -msgstr "視訊 RTP/UDP:" - -#: ../gtk/parameters.ui.h:26 -msgid "Media encryption type" -msgstr "" - -#: ../gtk/parameters.ui.h:27 -msgid "Media encryption is mandatory" -msgstr "" - -#: ../gtk/parameters.ui.h:28 -msgid "Tunnel" -msgstr "" - -#: ../gtk/parameters.ui.h:29 -msgid "DSCP fields" -msgstr "" - -#: ../gtk/parameters.ui.h:30 -msgid "Network protocol and ports" -msgstr "" - -#: ../gtk/parameters.ui.h:31 -msgid "Direct connection to the Internet" -msgstr "直接連線到網際網路" - -#: ../gtk/parameters.ui.h:32 -msgid "Behind NAT / Firewall (specify gateway IP )" -msgstr "" - -#: ../gtk/parameters.ui.h:33 -msgid "Behind NAT / Firewall (use STUN to resolve)" -msgstr "在 NAT / 防火牆之後 (使用 STUN 解析)" - -#: ../gtk/parameters.ui.h:34 -msgid "Behind NAT / Firewall (use ICE)" -msgstr "" - -#: ../gtk/parameters.ui.h:35 -msgid "Behind NAT / Firewall (use uPnP)" -msgstr "" - -#: ../gtk/parameters.ui.h:36 -msgid "Public IP address:" -msgstr "公共 IP 地址:" - -#: ../gtk/parameters.ui.h:37 -msgid "Stun server:" -msgstr "Stun 伺服器:" - -#: ../gtk/parameters.ui.h:38 -msgid "NAT and Firewall" -msgstr "NAT 與防火牆" - -#: ../gtk/parameters.ui.h:39 -msgid "Network settings" -msgstr "網路設定值" - -#: ../gtk/parameters.ui.h:40 -msgid "Ring sound:" -msgstr "鈴聲音效:" - -#: ../gtk/parameters.ui.h:41 -msgid "ALSA special device (optional):" -msgstr "ALSA 特殊裝置 (選擇性):" - -#: ../gtk/parameters.ui.h:42 -msgid "Capture device:" -msgstr "捕捉裝置:" - -#: ../gtk/parameters.ui.h:43 -msgid "Ring device:" -msgstr "響鈴裝置:" - -#: ../gtk/parameters.ui.h:44 -msgid "Playback device:" -msgstr "播放裝置" - -#: ../gtk/parameters.ui.h:45 -msgid "Enable echo cancellation" -msgstr "啟用回音消除" - -#: ../gtk/parameters.ui.h:46 -msgid "Audio" -msgstr "音效" - -#: ../gtk/parameters.ui.h:47 -msgid "Video input device:" -msgstr "視訊輸入裝置:" - -#: ../gtk/parameters.ui.h:48 -msgid "Prefered video resolution:" -msgstr "偏好的視訊解析度:" - -#: ../gtk/parameters.ui.h:49 -msgid "Video output method:" -msgstr "" - -#: ../gtk/parameters.ui.h:50 -msgid "Show camera preview" -msgstr "" - -#: ../gtk/parameters.ui.h:51 -msgid "Video" -msgstr "視訊" - -#: ../gtk/parameters.ui.h:52 -msgid "Multimedia settings" -msgstr "多媒體設定值" - -#: ../gtk/parameters.ui.h:53 -msgid "This section defines your SIP address when not using a SIP account" -msgstr "這一區在不使用 SIP 帳號時定義您的 SIP 位址" - -#: ../gtk/parameters.ui.h:54 -msgid "Your display name (eg: John Doe):" -msgstr "您的顯示名稱 (例如: John Doe):" - -#: ../gtk/parameters.ui.h:55 -msgid "Your username:" -msgstr "您的使用者名稱:" - -#: ../gtk/parameters.ui.h:56 -msgid "Your resulting SIP address:" -msgstr "您組成的 SIP 位址:" - -#: ../gtk/parameters.ui.h:57 -msgid "Default identity" -msgstr "預設身分識別" - -#: ../gtk/parameters.ui.h:58 -msgid "Wizard" -msgstr "" - -#: ../gtk/parameters.ui.h:59 -msgid "Add" -msgstr "加入" - -#: ../gtk/parameters.ui.h:60 -msgid "Edit" -msgstr "編輯" - -#: ../gtk/parameters.ui.h:61 -msgid "Remove" -msgstr "移除" - -#: ../gtk/parameters.ui.h:62 -msgid "Proxy accounts" -msgstr "代理伺服器帳號" - -#: ../gtk/parameters.ui.h:63 -msgid "Erase all passwords" -msgstr "消除所有的密碼" - -#: ../gtk/parameters.ui.h:64 -msgid "Privacy" -msgstr "隱私" - -#: ../gtk/parameters.ui.h:65 -msgid "Automatically answer when a call is received" -msgstr "" - -#: ../gtk/parameters.ui.h:66 -msgid "Delay before answering (ms)" -msgstr "" - -#: ../gtk/parameters.ui.h:67 -msgid "Auto-answer" -msgstr "" - -#: ../gtk/parameters.ui.h:68 -msgid "Manage SIP Accounts" -msgstr "管理 SIP 帳號" - -#: ../gtk/parameters.ui.h:69 ../gtk/tunnel_config.ui.h:4 -msgid "Enable" -msgstr "啟用" - -#: ../gtk/parameters.ui.h:70 ../gtk/tunnel_config.ui.h:5 -msgid "Disable" -msgstr "停用" - -#: ../gtk/parameters.ui.h:71 -msgid "Codecs" -msgstr "編碼解碼器" - -#: ../gtk/parameters.ui.h:72 -msgid "0 stands for \"unlimited\"" -msgstr "0 表示「不限制」" - -#: ../gtk/parameters.ui.h:73 -msgid "Upload speed limit in Kbit/sec:" -msgstr "上傳速度限制於 Kbit/sec:" - -#: ../gtk/parameters.ui.h:74 -msgid "Download speed limit in Kbit/sec:" -msgstr "下載速度限制於 Kbit/sec:" - -#: ../gtk/parameters.ui.h:75 -msgid "Enable adaptive rate control" -msgstr "" - -#: ../gtk/parameters.ui.h:76 -msgid "" -"Adaptive rate control is a technique to dynamically guess the available " -"bandwidth during a call." -msgstr "" - -#: ../gtk/parameters.ui.h:77 -msgid "Bandwidth control" -msgstr "頻寬控制" - -#: ../gtk/parameters.ui.h:78 -msgid "Codecs" -msgstr "編碼解碼器" - -#: ../gtk/parameters.ui.h:79 -msgid "Language" -msgstr "語言" - -#: ../gtk/parameters.ui.h:80 -msgid "Show advanced settings" -msgstr "顯示進階設定值" - -#: ../gtk/parameters.ui.h:81 -msgid "Level" -msgstr "級數" - -#: ../gtk/parameters.ui.h:82 -msgid "User interface" -msgstr "使用者介面" - -#: ../gtk/parameters.ui.h:83 ../gtk/ldap.ui.h:2 -msgid "Server address:" -msgstr "" - -#: ../gtk/parameters.ui.h:84 ../gtk/ldap.ui.h:3 -msgid "Authentication method:" -msgstr "" - -#: ../gtk/parameters.ui.h:86 -msgid "LDAP Account setup" -msgstr "" - -#: ../gtk/parameters.ui.h:87 -msgid "LDAP" -msgstr "" - -#: ../gtk/parameters.ui.h:88 -msgid "Done" -msgstr "完成" - #: ../gtk/buddylookup.ui.h:1 msgid "Search contacts in directory" msgstr "在目錄中搜尋" @@ -1496,29 +788,21 @@ msgstr "加入我的清單" msgid "Search somebody" msgstr "搜尋某人" -#: ../gtk/waiting.ui.h:2 -msgid "Please wait" -msgstr "請稍候" - -#: ../gtk/dscp_settings.ui.h:1 -msgid "DSCP settings" +#: ../gtk/callee_frame.ui.h:1 +msgid "Callee name" msgstr "" -#: ../gtk/dscp_settings.ui.h:2 -msgid "SIP" -msgstr "" +#: ../gtk/call_logs.ui.h:1 +msgid "Call history" +msgstr "通話紀錄" -#: ../gtk/dscp_settings.ui.h:3 -msgid "Audio RTP stream" -msgstr "" +#: ../gtk/call_logs.ui.h:2 +msgid "Clear all" +msgstr "全部清除" -#: ../gtk/dscp_settings.ui.h:4 -msgid "Video RTP stream" -msgstr "" - -#: ../gtk/dscp_settings.ui.h:5 -msgid "Set DSCP values (in hexadecimal)" -msgstr "" +#: ../gtk/call_logs.ui.h:3 +msgid "Call back" +msgstr "回電" #: ../gtk/call_statistics.ui.h:1 msgid "Call statistics" @@ -1568,30 +852,112 @@ msgstr "" msgid "Call statistics and information" msgstr "" -#: ../gtk/tunnel_config.ui.h:1 -msgid "Configure VoIP tunnel" +#: ../gtk/chatroom_frame.ui.h:1 +msgid "Send" +msgstr "傳送" + +#: ../gtk/conf_frame.ui.h:1 +msgid "End conference" msgstr "" -#: ../gtk/tunnel_config.ui.h:2 -msgid "Host" +#: ../gtk/config-uri.ui.h:1 +msgid "Specifying a remote configuration URI" msgstr "" -#: ../gtk/tunnel_config.ui.h:3 -msgid "Port" +#: ../gtk/config-uri.ui.h:2 +msgid "" +"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" +"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " msgstr "" -#: ../gtk/tunnel_config.ui.h:6 -msgid "Configure tunnel" +#: ../gtk/contact.ui.h:2 +msgid "SIP Address" +msgstr "SIP 位址" + +#: ../gtk/contact.ui.h:3 +msgid "Show this contact presence status" +msgstr "顯示這個連絡人的上線狀態" + +#: ../gtk/contact.ui.h:4 +msgid "Allow this contact to see my presence status" +msgstr "允許這個連絡人看到我的上線狀態" + +#: ../gtk/contact.ui.h:5 +msgid "Contact information" +msgstr "連絡人資訊" + +#: ../gtk/dscp_settings.ui.h:1 +msgid "DSCP settings" msgstr "" -#: ../gtk/tunnel_config.ui.h:9 -msgid "Configure http proxy (optional)" +#: ../gtk/dscp_settings.ui.h:2 +msgid "SIP" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:3 +msgid "Audio RTP stream" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:4 +msgid "Video RTP stream" +msgstr "" + +#: ../gtk/dscp_settings.ui.h:5 +msgid "Set DSCP values (in hexadecimal)" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:1 +msgid "Click here to set the speakers volume" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:5 +msgid "Record this call to an audio file" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:6 +msgid "Video" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:8 +msgid "Mute" +msgstr "" + +#: ../gtk/in_call_frame.ui.h:9 +msgid "Transfer" +msgstr "轉接" + +#: ../gtk/in_call_frame.ui.h:12 +msgid "In call" +msgstr "通話中" + +#: ../gtk/in_call_frame.ui.h:13 +msgid "Duration" +msgstr "時間長度" + +#: ../gtk/in_call_frame.ui.h:14 +msgid "Call quality rating" msgstr "" #: ../gtk/ldap.ui.h:1 msgid "LDAP Settings" msgstr "" +#: ../gtk/ldap.ui.h:2 ../gtk/parameters.ui.h:89 +msgid "Server address:" +msgstr "" + +#: ../gtk/ldap.ui.h:3 ../gtk/parameters.ui.h:90 +msgid "Authentication method:" +msgstr "" + +#: ../gtk/ldap.ui.h:4 ../gtk/parameters.ui.h:91 ../gtk/setup_wizard.ui.h:17 +msgid "Username:" +msgstr "使用者名稱:" + +#: ../gtk/ldap.ui.h:5 ../gtk/password.ui.h:4 ../gtk/setup_wizard.ui.h:18 +msgid "Password:" +msgstr "密碼: " + #: ../gtk/ldap.ui.h:6 msgid "Use TLS Connection" msgstr "" @@ -1677,16 +1043,504 @@ msgstr "" msgid "NTLM" msgstr "" -#: ../gtk/config-uri.ui.h:1 -msgid "Specifying a remote configuration URI" +#: ../gtk/login_frame.ui.h:1 ../gtk/tunnel_config.ui.h:7 +msgid "Username" +msgstr "使用者名稱" + +#: ../gtk/login_frame.ui.h:2 ../gtk/tunnel_config.ui.h:8 +msgid "Password" +msgstr "密碼" + +#: ../gtk/login_frame.ui.h:3 +msgid "Internet connection:" +msgstr "網路連線:" + +#: ../gtk/login_frame.ui.h:4 +msgid "Automatically log me in" +msgstr "將我自動登入" + +#: ../gtk/login_frame.ui.h:5 ../gtk/password.ui.h:3 +msgid "UserID" +msgstr "使用者ID" + +#: ../gtk/login_frame.ui.h:6 +msgid "Login information" +msgstr "登入資訊" + +#: ../gtk/login_frame.ui.h:7 +msgid "Welcome!" msgstr "" -#: ../gtk/config-uri.ui.h:2 -msgid "" -"This dialog allows to set an http or https address when configuration is to be fetched at startup.\n" -"Please enter or modify the configuration URI below. After clicking OK, Linphone will restart automatically in order to fetch and take into account the new configuration. " +#: ../gtk/login_frame.ui.h:8 +msgid "ADSL" +msgstr "ADSL" + +#: ../gtk/login_frame.ui.h:9 +msgid "Fiber Channel" +msgstr "光纖通道" + +#: ../gtk/log.ui.h:1 +msgid "Linphone debug window" +msgstr "Linphone 除錯視窗" + +#: ../gtk/log.ui.h:2 +msgid "Scroll to end" msgstr "" +#: ../gtk/main.ui.h:1 +msgid "Default" +msgstr "預設值" + +#: ../gtk/main.ui.h:2 +msgid "Delete" +msgstr "" + +#: ../gtk/main.ui.h:3 +msgid "_Options" +msgstr "選項(_O)" + +#: ../gtk/main.ui.h:4 +msgid "Set configuration URI" +msgstr "" + +#: ../gtk/main.ui.h:5 +msgid "Always start video" +msgstr "" + +#: ../gtk/main.ui.h:6 +msgid "Enable self-view" +msgstr "啟用自拍檢視" + +#: ../gtk/main.ui.h:7 +msgid "Show keypad" +msgstr "" + +#: ../gtk/main.ui.h:8 +msgid "_Help" +msgstr "求助(_H)" + +#: ../gtk/main.ui.h:9 +msgid "Show debug window" +msgstr "顯示除錯視窗" + +#: ../gtk/main.ui.h:10 +msgid "_Homepage" +msgstr "官方網頁(_H)" + +#: ../gtk/main.ui.h:11 +msgid "Check _Updates" +msgstr "檢查更新(_U)" + +#: ../gtk/main.ui.h:12 +msgid "Account assistant" +msgstr "" + +#: ../gtk/main.ui.h:14 +msgid "SIP address or phone number:" +msgstr "SIP 位址或電話號碼:" + +#: ../gtk/main.ui.h:15 +msgid "Initiate a new call" +msgstr "打出新電話" + +#: ../gtk/main.ui.h:16 +msgid "Contacts" +msgstr "連絡人" + +#: ../gtk/main.ui.h:17 +msgid "Search" +msgstr "搜尋" + +#: ../gtk/main.ui.h:18 +msgid "Add contacts from directory" +msgstr "從目錄加入連絡人" + +#: ../gtk/main.ui.h:19 +msgid "Add contact" +msgstr "加入聯絡人" + +#: ../gtk/main.ui.h:20 +msgid "Clear call history" +msgstr "" + +#: ../gtk/main.ui.h:22 +msgid "My current identity:" +msgstr "我目前的使用者識別:" + +#: ../gtk/main.ui.h:23 +msgid "Autoanswer is enabled" +msgstr "" + +#: ../gtk/parameters.ui.h:1 +msgid "anonymous" +msgstr "" + +#: ../gtk/parameters.ui.h:2 +msgid "GSSAPI" +msgstr "" + +#: ../gtk/parameters.ui.h:3 +msgid "SASL" +msgstr "" + +#: ../gtk/parameters.ui.h:4 +msgid "default soundcard" +msgstr "預設的音效卡" + +#: ../gtk/parameters.ui.h:5 +msgid "a sound card" +msgstr "音效卡" + +#: ../gtk/parameters.ui.h:6 +msgid "default camera" +msgstr "預設的攝影機" + +#: ../gtk/parameters.ui.h:7 +msgid "CIF" +msgstr "CIF" + +#: ../gtk/parameters.ui.h:8 +msgid "Audio codecs" +msgstr "音訊編碼解碼器" + +#: ../gtk/parameters.ui.h:9 +msgid "Video codecs" +msgstr "視訊編碼解碼器" + +#: ../gtk/parameters.ui.h:10 +msgid "C" +msgstr "C" + +#: ../gtk/parameters.ui.h:11 +msgid "SIP (UDP)" +msgstr "" + +#: ../gtk/parameters.ui.h:12 +msgid "SIP (TCP)" +msgstr "" + +#: ../gtk/parameters.ui.h:13 +msgid "SIP (TLS)" +msgstr "" + +#: ../gtk/parameters.ui.h:14 +msgid "default" +msgstr "" + +#: ../gtk/parameters.ui.h:15 +msgid "high-fps" +msgstr "" + +#: ../gtk/parameters.ui.h:16 +msgid "custom" +msgstr "" + +#: ../gtk/parameters.ui.h:17 +msgid "Settings" +msgstr "設定值" + +#: ../gtk/parameters.ui.h:18 +msgid "This section defines your SIP address when not using a SIP account" +msgstr "這一區在不使用 SIP 帳號時定義您的 SIP 位址" + +#: ../gtk/parameters.ui.h:19 +msgid "Your display name (eg: John Doe):" +msgstr "您的顯示名稱 (例如: John Doe):" + +#: ../gtk/parameters.ui.h:20 +msgid "Your username:" +msgstr "您的使用者名稱:" + +#: ../gtk/parameters.ui.h:21 +msgid "Your resulting SIP address:" +msgstr "您組成的 SIP 位址:" + +#: ../gtk/parameters.ui.h:22 +msgid "Default identity" +msgstr "預設身分識別" + +#: ../gtk/parameters.ui.h:23 +msgid "Wizard" +msgstr "" + +#: ../gtk/parameters.ui.h:24 +msgid "Add" +msgstr "加入" + +#: ../gtk/parameters.ui.h:25 +msgid "Edit" +msgstr "編輯" + +#: ../gtk/parameters.ui.h:26 +msgid "Remove" +msgstr "移除" + +#: ../gtk/parameters.ui.h:27 +msgid "Proxy accounts" +msgstr "代理伺服器帳號" + +#: ../gtk/parameters.ui.h:28 +msgid "Erase all passwords" +msgstr "消除所有的密碼" + +#: ../gtk/parameters.ui.h:29 +msgid "Privacy" +msgstr "隱私" + +#: ../gtk/parameters.ui.h:30 +msgid "Automatically answer when a call is received" +msgstr "" + +#: ../gtk/parameters.ui.h:31 +msgid "Delay before answering (ms)" +msgstr "" + +#: ../gtk/parameters.ui.h:32 +msgid "Auto-answer" +msgstr "" + +#: ../gtk/parameters.ui.h:33 +msgid "Manage SIP Accounts" +msgstr "管理 SIP 帳號" + +#: ../gtk/parameters.ui.h:34 +msgid "Ring sound:" +msgstr "鈴聲音效:" + +#: ../gtk/parameters.ui.h:35 +msgid "ALSA special device (optional):" +msgstr "ALSA 特殊裝置 (選擇性):" + +#: ../gtk/parameters.ui.h:36 +msgid "Capture device:" +msgstr "捕捉裝置:" + +#: ../gtk/parameters.ui.h:37 +msgid "Ring device:" +msgstr "響鈴裝置:" + +#: ../gtk/parameters.ui.h:38 +msgid "Playback device:" +msgstr "播放裝置" + +#: ../gtk/parameters.ui.h:39 +msgid "Enable echo cancellation" +msgstr "啟用回音消除" + +#: ../gtk/parameters.ui.h:40 +msgid "Audio" +msgstr "音效" + +#: ../gtk/parameters.ui.h:41 +msgid "Video input device:" +msgstr "視訊輸入裝置:" + +#: ../gtk/parameters.ui.h:42 +msgid "Preferred video resolution:" +msgstr "" + +#: ../gtk/parameters.ui.h:43 +msgid "Video output method:" +msgstr "" + +#: ../gtk/parameters.ui.h:44 +msgid "Show camera preview" +msgstr "" + +#: ../gtk/parameters.ui.h:45 +msgid "Video preset:" +msgstr "" + +#: ../gtk/parameters.ui.h:46 +msgid "Preferred video framerate:" +msgstr "" + +#: ../gtk/parameters.ui.h:47 +msgid "0 stands for \"unlimited\"" +msgstr "0 表示「不限制」" + +#: ../gtk/parameters.ui.h:48 +msgid "Video" +msgstr "視訊" + +#: ../gtk/parameters.ui.h:49 +msgid "Upload speed limit in Kbit/sec:" +msgstr "上傳速度限制於 Kbit/sec:" + +#: ../gtk/parameters.ui.h:50 +msgid "Download speed limit in Kbit/sec:" +msgstr "下載速度限制於 Kbit/sec:" + +#: ../gtk/parameters.ui.h:51 +msgid "Enable adaptive rate control" +msgstr "" + +#: ../gtk/parameters.ui.h:52 +msgid "" +"Adaptive rate control is a technique to dynamically guess the available " +"bandwidth during a call." +msgstr "" + +#: ../gtk/parameters.ui.h:53 +msgid "Bandwidth control" +msgstr "頻寬控制" + +#: ../gtk/parameters.ui.h:54 +msgid "Multimedia settings" +msgstr "多媒體設定值" + +#: ../gtk/parameters.ui.h:55 +msgid "Set Maximum Transmission Unit:" +msgstr "設定最大傳輸單位:" + +#: ../gtk/parameters.ui.h:56 +msgid "Send DTMFs as SIP info" +msgstr "傳送 DTMFs 為 SIP 資訊" + +#: ../gtk/parameters.ui.h:57 +msgid "Allow IPv6" +msgstr "" + +#: ../gtk/parameters.ui.h:58 +msgid "Transport" +msgstr "傳輸" + +#: ../gtk/parameters.ui.h:59 +msgid "SIP/UDP port" +msgstr "" + +#: ../gtk/parameters.ui.h:61 +msgid "Random" +msgstr "" + +#: ../gtk/parameters.ui.h:62 +msgid "SIP/TCP port" +msgstr "" + +#: ../gtk/parameters.ui.h:63 +msgid "Audio RTP/UDP:" +msgstr "音效 RTP/UDP:" + +#: ../gtk/parameters.ui.h:64 +msgid "Fixed" +msgstr "" + +#: ../gtk/parameters.ui.h:65 +msgid "Video RTP/UDP:" +msgstr "視訊 RTP/UDP:" + +#: ../gtk/parameters.ui.h:66 +msgid "Media encryption type" +msgstr "" + +#: ../gtk/parameters.ui.h:67 +msgid "Media encryption is mandatory" +msgstr "" + +#: ../gtk/parameters.ui.h:68 +msgid "Tunnel" +msgstr "" + +#: ../gtk/parameters.ui.h:69 +msgid "DSCP fields" +msgstr "" + +#: ../gtk/parameters.ui.h:70 +msgid "Network protocol and ports" +msgstr "" + +#: ../gtk/parameters.ui.h:71 +msgid "Direct connection to the Internet" +msgstr "直接連線到網際網路" + +#: ../gtk/parameters.ui.h:72 +msgid "Behind NAT / Firewall (specify gateway IP )" +msgstr "" + +#: ../gtk/parameters.ui.h:73 +msgid "Behind NAT / Firewall (use STUN to resolve)" +msgstr "在 NAT / 防火牆之後 (使用 STUN 解析)" + +#: ../gtk/parameters.ui.h:74 +msgid "Behind NAT / Firewall (use ICE)" +msgstr "" + +#: ../gtk/parameters.ui.h:75 +msgid "Behind NAT / Firewall (use uPnP)" +msgstr "" + +#: ../gtk/parameters.ui.h:76 +msgid "Public IP address:" +msgstr "公共 IP 地址:" + +#: ../gtk/parameters.ui.h:77 +msgid "Stun server:" +msgstr "Stun 伺服器:" + +#: ../gtk/parameters.ui.h:78 +msgid "NAT and Firewall" +msgstr "NAT 與防火牆" + +#: ../gtk/parameters.ui.h:79 +msgid "Network settings" +msgstr "網路設定值" + +#: ../gtk/parameters.ui.h:80 ../gtk/tunnel_config.ui.h:4 +msgid "Enable" +msgstr "啟用" + +#: ../gtk/parameters.ui.h:81 ../gtk/tunnel_config.ui.h:5 +msgid "Disable" +msgstr "停用" + +#: ../gtk/parameters.ui.h:82 +msgid "Audio codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:83 +msgid "Video codecs" +msgstr "" + +#: ../gtk/parameters.ui.h:84 +msgid "Codecs" +msgstr "編碼解碼器" + +#: ../gtk/parameters.ui.h:85 +msgid "Language" +msgstr "語言" + +#: ../gtk/parameters.ui.h:86 +msgid "Show advanced settings" +msgstr "顯示進階設定值" + +#: ../gtk/parameters.ui.h:87 +msgid "Level" +msgstr "級數" + +#: ../gtk/parameters.ui.h:88 +msgid "User interface" +msgstr "使用者介面" + +#: ../gtk/parameters.ui.h:92 +msgid "LDAP Account setup" +msgstr "" + +#: ../gtk/parameters.ui.h:93 +msgid "LDAP" +msgstr "" + +#: ../gtk/parameters.ui.h:94 +msgid "Done" +msgstr "完成" + +#: ../gtk/password.ui.h:1 +msgid "Linphone - Authentication required" +msgstr "Linphone - 需要驗證" + +#: ../gtk/password.ui.h:2 +msgid "Please enter the domain password" +msgstr "請輸入這個網域的密碼" + #: ../gtk/provisioning-fetch.ui.h:1 msgid "Configuring..." msgstr "" @@ -1695,68 +1549,278 @@ msgstr "" msgid "Please wait while fetching configuration from server..." msgstr "" -#: ../coreapi/linphonecore.c:1539 +#: ../gtk/setup_wizard.ui.h:1 +msgid "SIP account configuration assistant" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:2 +msgid "" +"Welcome!\n" +"This assistant will help you to use a SIP account for your calls." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:4 +msgid "Welcome to the account setup assistant" +msgstr "歡迎使用帳號設定助理" + +#: ../gtk/setup_wizard.ui.h:5 +msgid "Create an account on linphone.org" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:6 +msgid "I have already a linphone.org account and I just want to use it" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:7 +msgid "I have already a sip account and I just want to use it" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:8 +msgid "I want to specify a remote configuration URI" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:9 +msgid "Account setup assistant" +msgstr "帳號設定助理" + +#: ../gtk/setup_wizard.ui.h:10 +msgid "Enter your account information" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:11 +msgid "Username*" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:12 +msgid "Password*" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:13 +msgid "Domain*" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:14 +msgid "Proxy" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:15 +msgid "Configure your account (step 1/1)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:16 +msgid "Enter your linphone.org username" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:19 +msgid "Enter your sip username (step 1/1)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:20 +msgid "(*) Required fields" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:21 +msgid "Email: (*)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:22 +msgid "Username: (*)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:23 +msgid "Password: (*)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:24 +msgid "Confirm your password: (*)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:25 +msgid "Keep me informed with linphone updates" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:26 +msgid "Enter account information (step 1/2)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:27 +msgid "Your account is being created, please wait." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:28 +msgid "Account creation in progress" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:29 +msgid "" +"Please validate your account by clicking on the link we just sent you by email.\n" +"Then come back here and press Next button." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:31 +msgid "Validation (step 2/2)" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:32 +msgid "Checking if your account is been validated, please wait." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:33 +msgid "Account validation check in progress" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:34 +msgid "" +"Error, account not validated, username already used or server unreachable.\n" +"Please go back and try again." +msgstr "" + +#: ../gtk/setup_wizard.ui.h:36 +msgid "Error" +msgstr "" + +#: ../gtk/setup_wizard.ui.h:37 +msgid "Thank you. Your account is now configured and ready for use." +msgstr "謝謝您。您的帳號已設定完成並且可以使用。" + +#: ../gtk/sip_account.ui.h:1 +msgid "Linphone - Configure a SIP account" +msgstr "Linphone - 設定 SIP 帳號" + +#: ../gtk/sip_account.ui.h:2 +msgid "Your SIP identity:" +msgstr "您的 SIP 使用者識別:" + +#: ../gtk/sip_account.ui.h:3 +msgid "Looks like sip:@" +msgstr "看起來像 sip:@" + +#: ../gtk/sip_account.ui.h:4 +msgid "sip:" +msgstr "sip:" + +#: ../gtk/sip_account.ui.h:5 +msgid "SIP Proxy address:" +msgstr "SIP 代理位址:" + +#: ../gtk/sip_account.ui.h:6 +msgid "Looks like sip:" +msgstr "看起來像 sip:" + +#: ../gtk/sip_account.ui.h:7 +msgid "Registration duration (sec):" +msgstr "註冊時間 (秒):" + +#: ../gtk/sip_account.ui.h:8 +msgid "Contact params (optional):" +msgstr "" + +#: ../gtk/sip_account.ui.h:9 +msgid "AVPF regular RTCP interval (sec):" +msgstr "" + +#: ../gtk/sip_account.ui.h:10 +msgid "Route (optional):" +msgstr "路由 (選擇性):" + +#: ../gtk/sip_account.ui.h:11 +msgid "Transport" +msgstr "" + +#: ../gtk/sip_account.ui.h:12 +msgid "Register" +msgstr "" + +#: ../gtk/sip_account.ui.h:13 +msgid "Publish presence information" +msgstr "發布上線資訊" + +#: ../gtk/sip_account.ui.h:14 +msgid "Enable AVPF" +msgstr "" + +#: ../gtk/sip_account.ui.h:15 +msgid "Configure a SIP account" +msgstr "設定 SIP 帳號" + +#: ../gtk/tunnel_config.ui.h:1 +msgid "Configure VoIP tunnel" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:2 +msgid "Host" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:3 +msgid "Port" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:6 +msgid "Configure tunnel" +msgstr "" + +#: ../gtk/tunnel_config.ui.h:9 +msgid "Configure http proxy (optional)" +msgstr "" + +#: ../gtk/waiting.ui.h:2 +msgid "Please wait" +msgstr "請稍候" + +#: ../coreapi/linphonecore.c:1560 msgid "Ready" msgstr "準備就緒" -#: ../coreapi/linphonecore.c:2551 +#: ../coreapi/linphonecore.c:2556 msgid "Configuring" msgstr "" -#: ../coreapi/linphonecore.c:2725 -msgid "Looking for telephone number destination..." -msgstr "尋找電話號碼目的端..." - -#: ../coreapi/linphonecore.c:2727 -msgid "Could not resolve this number." -msgstr "無法解析這個號碼。" - #. must be known at that time -#: ../coreapi/linphonecore.c:3013 +#: ../coreapi/linphonecore.c:2951 msgid "Contacting" msgstr "正在連絡" -#: ../coreapi/linphonecore.c:3018 +#: ../coreapi/linphonecore.c:2956 msgid "Could not call" msgstr "無法通話" -#: ../coreapi/linphonecore.c:3169 +#: ../coreapi/linphonecore.c:3092 msgid "Sorry, we have reached the maximum number of simultaneous calls" msgstr "抱歉,我們已達瀏同步通話的最大數目" -#: ../coreapi/linphonecore.c:3327 +#: ../coreapi/linphonecore.c:3250 msgid "is contacting you" msgstr "正在連絡您" -#: ../coreapi/linphonecore.c:3328 +#: ../coreapi/linphonecore.c:3251 msgid " and asked autoanswer." msgstr "並要求自動接聽。" -#: ../coreapi/linphonecore.c:3452 +#: ../coreapi/linphonecore.c:3377 msgid "Modifying call parameters..." msgstr "修改通話參數..." -#: ../coreapi/linphonecore.c:3802 +#: ../coreapi/linphonecore.c:3769 msgid "Connected." msgstr "已連線。" -#: ../coreapi/linphonecore.c:3827 +#: ../coreapi/linphonecore.c:3794 msgid "Call aborted" msgstr "通話已放棄" -#: ../coreapi/linphonecore.c:4024 +#: ../coreapi/linphonecore.c:3983 msgid "Could not pause the call" msgstr "無法暫停通話" -#: ../coreapi/linphonecore.c:4027 +#: ../coreapi/linphonecore.c:3986 msgid "Pausing the current call..." msgstr "暫停目前的通話..." -#: ../coreapi/misc.c:434 +#: ../coreapi/misc.c:440 msgid "Stun lookup in progress..." msgstr "正在進行 Stun 搜尋..." -#: ../coreapi/misc.c:615 +#: ../coreapi/misc.c:650 msgid "ICE local candidates gathering in progress..." msgstr "" @@ -1812,165 +1876,172 @@ msgstr "" msgid "Unknown status" msgstr "" -#: ../coreapi/proxy.c:328 +#: ../coreapi/proxy.c:292 msgid "" "The sip proxy address you entered is invalid, it must start with \"sip:\" " "followed by a hostname." msgstr "您輸入的 sip 代理位址是無效的,它必須要以「sip:」開頭,後面接主機名稱。" -#: ../coreapi/proxy.c:334 +#: ../coreapi/proxy.c:298 msgid "" "The sip identity you entered is invalid.\n" "It should look like sip:username@proxydomain, such as sip:alice@example.net" msgstr "您輸入的 sip 身分是無效的。\n它應該看起來像 sip:使用者名稱@代理網域,像是 sip:alice@example.net" -#: ../coreapi/proxy.c:1416 +#: ../coreapi/proxy.c:927 +msgid "Looking for telephone number destination..." +msgstr "尋找電話號碼目的端..." + +#: ../coreapi/proxy.c:931 +msgid "Could not resolve this number." +msgstr "無法解析這個號碼。" + +#: ../coreapi/proxy.c:1324 #, c-format msgid "Could not login as %s" msgstr "無法以 %s 登入" -#: ../coreapi/callbacks.c:428 +#: ../coreapi/proxy.c:1411 +#, c-format +msgid "Refreshing on %s..." +msgstr "" + +#: ../coreapi/callbacks.c:423 msgid "Remote ringing." msgstr "遠端響鈴。" -#: ../coreapi/callbacks.c:440 +#: ../coreapi/callbacks.c:435 msgid "Remote ringing..." msgstr "遠端響鈴..." -#: ../coreapi/callbacks.c:461 +#: ../coreapi/callbacks.c:458 msgid "Early media." msgstr "早期媒體。" -#: ../coreapi/callbacks.c:534 +#: ../coreapi/callbacks.c:488 #, c-format -msgid "Call with %s is paused." -msgstr "和 %s 的通話已暫停。" +msgid "Call answered by %s" +msgstr "" -#: ../coreapi/callbacks.c:547 -#, c-format -msgid "Call answered by %s - on hold." -msgstr "通話由 %s 接聽 - 保留中。" - -#: ../coreapi/callbacks.c:557 +#: ../coreapi/callbacks.c:527 msgid "Call resumed." msgstr "通話已繼續。" -#: ../coreapi/callbacks.c:561 -#, c-format -msgid "Call answered by %s." -msgstr "通話由 %s 接聽。" - -#: ../coreapi/callbacks.c:584 +#: ../coreapi/callbacks.c:582 msgid "Incompatible, check codecs or security settings..." msgstr "" -#: ../coreapi/callbacks.c:589 ../coreapi/callbacks.c:906 +#: ../coreapi/callbacks.c:587 ../coreapi/callbacks.c:923 msgid "Incompatible media parameters." msgstr "" -#: ../coreapi/callbacks.c:619 +#: ../coreapi/callbacks.c:612 msgid "We have been resumed." msgstr "" #. we are being paused -#: ../coreapi/callbacks.c:628 +#: ../coreapi/callbacks.c:620 msgid "We are paused by other party." msgstr "" -#. reINVITE and in-dialogs UPDATE go here -#: ../coreapi/callbacks.c:666 +#: ../coreapi/callbacks.c:630 msgid "Call is updated by remote." msgstr "" -#: ../coreapi/callbacks.c:782 +#: ../coreapi/callbacks.c:799 msgid "Call terminated." msgstr "通話已終止。" -#: ../coreapi/callbacks.c:810 +#: ../coreapi/callbacks.c:827 msgid "User is busy." msgstr "使用者現正忙碌。" -#: ../coreapi/callbacks.c:811 +#: ../coreapi/callbacks.c:828 msgid "User is temporarily unavailable." msgstr "使用者暫時無法聯繫。" #. char *retrymsg=_("%s. Retry after %i minute(s)."); -#: ../coreapi/callbacks.c:813 +#: ../coreapi/callbacks.c:830 msgid "User does not want to be disturbed." msgstr "使用者不想要被打擾。" -#: ../coreapi/callbacks.c:814 +#: ../coreapi/callbacks.c:831 msgid "Call declined." msgstr "通話被拒接。" -#: ../coreapi/callbacks.c:829 +#: ../coreapi/callbacks.c:846 msgid "Request timeout." msgstr "" -#: ../coreapi/callbacks.c:860 +#: ../coreapi/callbacks.c:877 msgid "Redirected" msgstr "已重新導向" -#: ../coreapi/callbacks.c:915 +#: ../coreapi/callbacks.c:927 msgid "Call failed." msgstr "通話失敗。" -#: ../coreapi/callbacks.c:993 +#: ../coreapi/callbacks.c:1005 #, c-format msgid "Registration on %s successful." msgstr "在 %s 註冊成功。" -#: ../coreapi/callbacks.c:994 +#: ../coreapi/callbacks.c:1006 #, c-format msgid "Unregistration on %s done." msgstr "在 %s 取消註冊完成。" -#: ../coreapi/callbacks.c:1012 +#: ../coreapi/callbacks.c:1024 msgid "no response timeout" msgstr "沒有回應逾時" -#: ../coreapi/callbacks.c:1015 +#: ../coreapi/callbacks.c:1027 #, c-format msgid "Registration on %s failed: %s" msgstr "在 %s 註冊失敗:%s" -#: ../coreapi/callbacks.c:1022 +#: ../coreapi/callbacks.c:1034 msgid "Service unavailable, retrying" msgstr "" #. if encryption is DTLS, no status to be displayed -#: ../coreapi/linphonecall.c:180 +#: ../coreapi/linphonecall.c:197 #, c-format msgid "Authentication token is %s" msgstr "" -#: ../coreapi/linphonecall.c:1310 +#: ../coreapi/linphonecall.c:1561 +#, c-format +msgid "Call parameters could not be modified: %s." +msgstr "" + +#: ../coreapi/linphonecall.c:1563 msgid "Call parameters were successfully modified." msgstr "" -#: ../coreapi/linphonecall.c:3686 +#: ../coreapi/linphonecall.c:4396 #, c-format msgid "You have missed %i call." msgid_plural "You have missed %i calls." msgstr[0] "您有 %i 通未接來電。" -#: ../coreapi/call_log.c:209 +#: ../coreapi/call_log.c:223 msgid "aborted" msgstr "" -#: ../coreapi/call_log.c:212 +#: ../coreapi/call_log.c:226 msgid "completed" msgstr "" -#: ../coreapi/call_log.c:215 +#: ../coreapi/call_log.c:229 msgid "missed" msgstr "" -#: ../coreapi/call_log.c:218 +#: ../coreapi/call_log.c:232 msgid "unknown" msgstr "" -#: ../coreapi/call_log.c:220 +#: ../coreapi/call_log.c:234 #, c-format msgid "" "%s at %s\n" @@ -1980,7 +2051,7 @@ msgid "" "Duration: %i mn %i sec\n" msgstr "" -#: ../coreapi/call_log.c:221 +#: ../coreapi/call_log.c:235 msgid "Outgoing call" msgstr "" diff --git a/tester/CMakeLists.txt b/tester/CMakeLists.txt index 555f17ce9..7ed25ecaa 100644 --- a/tester/CMakeLists.txt +++ b/tester/CMakeLists.txt @@ -20,46 +20,71 @@ # ############################################################################ -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 + complex_sip_call_tester.c dtmf_tester.c eventapi_tester.c flexisip_tester.c liblinphone_tester.c log_collection_tester.c message_tester.c - multi_call.c + multi_call_tester.c multicast_call_tester.c offeranswer_tester.c player_tester.c presence_tester.c + proxy_config_tester.c quality_reporting_tester.c register_tester.c remote_provisioning_tester.c setup_tester.c stun_tester.c tester.c - transport_tester.c + tunnel_tester.c upnp_tester.c video_tester.c ) +apply_compile_flags(SOURCE_FILES "CPP" "C") + +#executable must be available on root path, not host one +find_program(SIPP_PROGRAM NAMES sipp sipp.exe ONLY_CMAKE_FIND_ROOT_PATH) +if(SIPP_PROGRAM) + add_definitions(-DHAVE_SIPP=1) + add_definitions(-DSIPP_COMMAND="${SIPP_PROGRAM}") +endif() + 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} PRIVATE common) -target_link_libraries(liblinphone_tester linphone ${CUNIT_LIBRARIES}) -if (GTK2_FOUND) - target_compile_definitions(liblinphone_tester PRIVATE HAVE_GTK) - target_include_directories(liblinphone_tester PUBLIC ${GTK2_INCLUDE_DIRS}) - target_link_libraries(liblinphone_tester linphone ${GTK2_LIBRARIES}) +if(IOS) + add_library(linphonetester STATIC ${SOURCE_FILES}) + target_include_directories(linphonetester PUBLIC ${CUNIT_INCLUDE_DIRS} PRIVATE common) + target_link_libraries(linphonetester linphone ${CUNIT_LIBRARIES}) + install(TARGETS linphonetester + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE + ) + install(FILES "liblinphone_tester.h" "common/bc_tester_utils.h" + DESTINATION include/linphone + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ + ) +else() + add_executable(liblinphone_tester ${SOURCE_FILES}) + set_target_properties(liblinphone_tester PROPERTIES LINKER_LANGUAGE CXX) + target_include_directories(liblinphone_tester PUBLIC ${CUNIT_INCLUDE_DIRS} PRIVATE common) + target_link_libraries(liblinphone_tester linphone ${CUNIT_LIBRARIES}) + if (GTK2_FOUND) + target_compile_definitions(liblinphone_tester PRIVATE HAVE_GTK) + target_include_directories(liblinphone_tester PUBLIC ${GTK2_INCLUDE_DIRS}) + target_link_libraries(liblinphone_tester linphone ${GTK2_LIBRARIES}) + if(GTKMACINTEGRATION_FOUND) + target_include_directories(liblinphone_tester PUBLIC ${GTKMACINTEGRATION_INCLUDE_DIRS}) + target_link_libraries(liblinphone_tester ${GTKMACINTEGRATION_LIBRARIES}) + endif() + endif() endif() diff --git a/tester/Makefile.am b/tester/Makefile.am index 86510d794..40dabb7e2 100644 --- a/tester/Makefile.am +++ b/tester/Makefile.am @@ -1,34 +1,137 @@ -EXTRA_DIST= tester_hosts sounds images certificates rcfiles + +TESTER_SOUNDS = sounds/ahbahouaismaisbon.wav \ + sounds/hello8000.wav \ + sounds/oldphone.wav \ + sounds/sintel_trailer_opus_h264.mkv \ + sounds/sintel_trailer_pcmu_h264.mkv \ + sounds/hello8000.mkv \ + sounds/hello8000_mkv_ref.wav\ + sounds/ringback.wav \ + sounds/sintel_trailer_opus_vp8.mkv \ + sounds/vrroom.wav + + +SIPP_FILES = sipp/call_invite_200ok_without_contact_header.xml \ + sipp/call_with_multiple_audio_mline_in_sdp.xml \ + sipp/call_with_video_mline_before_audio_in_sdp.xml\ + sipp/call_with_audio_mline_before_video_in_sdp.xml \ + sipp/call_with_multiple_video_mline_in_sdp.xml \ + sipp/sip_update_within_icoming_reinvite_with_no_sdp.xml + + +CERTIFICATE_ALT_FILES = certificates/altname/agent.pem \ + certificates/altname/cafile.pem \ + certificates/altname/openssl-altname.cnf + +CERTIFICATE_CN_FILES = certificates/cn/agent.pem \ + certificates/cn/cafile.pem \ + certificates/cn/openssl-cn.cnf + +CERTIFICATE_FILES = $(CERTIFICATE_ALT_FILES) $(CERTIFICATE_CN_FILES) + +RCFILES = \ + rcfiles/empty_rc\ + rcfiles/laure_call_logs_rc\ + rcfiles/laure_rc\ + rcfiles/marie_early_rc\ + rcfiles/marie_h264_rc\ + rcfiles/marie_quality_reporting_rc\ + rcfiles/marie_rc\ + rcfiles/marie_rc_rtcp_xr\ + rcfiles/marie_remote_404_rc\ + rcfiles/marie_remote_default_values_rc\ + rcfiles/marie_remote_https_rc\ + rcfiles/marie_remote_invalid_rc\ + rcfiles/marie_remote_invalid_uri_rc\ + rcfiles/marie_remote_localfile2_rc\ + rcfiles/marie_remote_localfile_android_rc\ + rcfiles/marie_remote_localfile_rc\ + rcfiles/marie_remote_localfile_win10_rc\ + rcfiles/marie_remote_rc\ + rcfiles/marie_sips_rc\ + rcfiles/marie_transient_remote_rc\ + rcfiles/marie_zrtp_aes256_rc\ + rcfiles/marie_zrtp_b256_rc\ + rcfiles/marie_zrtp_srtpsuite_aes256_rc\ + rcfiles/michelle_rc\ + rcfiles/multi_account_rc\ + rcfiles/pauline_alt_rc\ + rcfiles/pauline_h264_rc\ + rcfiles/pauline_rc\ + rcfiles/pauline_rc_rtcp_xr\ + rcfiles/pauline_sips_rc\ + rcfiles/pauline_tcp_rc\ + rcfiles/pauline_wild_rc\ + rcfiles/pauline_zrtp_aes256_rc\ + rcfiles/pauline_zrtp_b256_rc\ + rcfiles/pauline_zrtp_srtpsuite_aes256_rc\ + rcfiles/remote_zero_length_params_rc\ + rcfiles/stun_rc\ + rcfiles/upnp_rc\ + rcfiles/zero_length_params_rc + +IMAGE_FILES = images/nowebcamCIF.jpg + +COMMON_FILE = common/bc_completion + +EXTRA_DIST = tester_hosts\ + messages.db\ + $(TESTER_SOUNDS)\ + $(SIPP_FILES)\ + $(CERTIFICATE_FILES)\ + $(RCFILES)\ + $(IMAGE_FILES)\ + $(COMMON_FILE) + + if BUILD_CUNIT_TESTS +sounddir = $(datadir)/liblinphone_tester/sounds +sound_DATA = $(TESTER_SOUNDS) +sippdir = $(datadir)/liblinphone_tester/sipp +sipp_DATA = $(SIPP_FILES) +certificatesaltdir=$(datadir)/liblinphone_tester/certificates/altname +certificatesalt_DATA = $(CERTIFICATE_ALT_FILES) +certificatescndir=$(datadir)/liblinphone_tester/certificates/cn +certificatescn_DATA = $(CERTIFICATE_CN_FILES) +rcfilesdir = $(datadir)/liblinphone_tester/rcfiles +rcfiles_DATA = $(RCFILES) +imagesdir = $(datadir)/liblinphone_tester/images +images_DATA = $(IMAGE_FILES) +commondir = $(datadir)/liblinphone_tester/common +common_DATA = $(COMMON_FILE) + # there are 2 targets: liblinphonetester.la and the executable liblinphone_tester liblinphonedir = $(includedir)/linphone liblinphone_HEADERS = liblinphone_tester.h + lib_LTLIBRARIES = liblinphonetester.la liblinphonetester_la_SOURCES = \ accountmanager.c \ call_tester.c \ + complex_sip_call_tester.c \ dtmf_tester.c \ eventapi_tester.c \ flexisip_tester.c \ log_collection_tester.c \ message_tester.c \ - multi_call.c \ + multi_call_tester.c \ multicast_call_tester.c \ offeranswer_tester.c \ player_tester.c \ presence_tester.c \ + proxy_config_tester.c \ quality_reporting_tester.c \ register_tester.c \ remote_provisioning_tester.c \ setup_tester.c \ stun_tester.c \ - transport_tester.c \ + tunnel_tester.c \ tester.c \ upnp_tester.c \ video_tester.c \ @@ -40,8 +143,16 @@ liblinphonetester_la_HEADERS = common/bc_tester_utils.h liblinphonetester_la_LDFLAGS= -no-undefined liblinphonetester_la_LIBADD= ../coreapi/liblinphone.la $(CUNIT_LIBS) +liblinphone_tester_bindir = $(bindir)/liblinphone_tester +liblinphone_testerdir = $(datadir)/liblinphone_tester + +dist_liblinphone_tester_DATA = tester_hosts messages.db + + AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/coreapi -I$(top_srcdir)/tester/common -AM_CFLAGS = -DBC_CONFIG_FILE=\"config.h\" $(STRICT_OPTIONS) $(STRICT_OPTIONS_CC) -DIN_LINPHONE $(ORTP_CFLAGS) $(MEDIASTREAMER_CFLAGS) $(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 @@ -50,9 +161,11 @@ AM_CFLAGS += $(LIBGTK_CFLAGS) $(LIBGTKMAC_CFLAGS) -DHAVE_GTK endif -if !BUILD_IOS +bin_PROGRAMS= -noinst_PROGRAMS = liblinphone_tester +if !BUILD_IOS +#noinst_PROGRAMS = liblinphone_tester +bin_PROGRAMS += liblinphone_tester liblinphone_tester_SOURCES = liblinphone_tester.c liblinphone_tester_LDADD = $(top_builddir)/coreapi/liblinphone.la liblinphonetester.la -lm diff --git a/tester/accountmanager.c b/tester/accountmanager.c index d46c2064d..543384bc7 100644 --- a/tester/accountmanager.c +++ b/tester/accountmanager.c @@ -123,7 +123,7 @@ void account_create_on_server(Account *account, const LinphoneProxyConfig *refcf vtable.registration_state_changed=account_created_on_server_cb; vtable.auth_info_requested=account_created_auth_requested_cb; - lc=configure_lc_from(&vtable,bc_tester_read_dir_prefix,NULL,account); + lc=configure_lc_from(&vtable,bc_tester_get_resource_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; @@ -146,7 +146,7 @@ void account_create_on_server(Account *account, const LinphoneProxyConfig *refcf linphone_proxy_config_set_server_addr(cfg,tmp); ms_free(tmp); linphone_address_unref(server_addr); - linphone_proxy_config_set_expires(cfg,3600); + linphone_proxy_config_set_expires(cfg,3*3600); //accounts are valid 3 hours linphone_core_add_proxy_config(lc,cfg); @@ -187,6 +187,10 @@ LinphoneAddress *account_manager_check_account(AccountManager *m, LinphoneProxyC LinphoneAuthInfo *ai; char *tmp; bool_t create_account=FALSE; + const LinphoneAuthInfo *original_ai = linphone_core_find_auth_info(lc + ,NULL + , linphone_address_get_username(id_addr) + , linphone_address_get_domain(id_addr)); if (!account){ account=account_new(id_addr,m->unique_id); @@ -203,6 +207,11 @@ LinphoneAddress *account_manager_check_account(AccountManager *m, LinphoneProxyC if (create_account){ account_create_on_server(account,cfg); } + + /*remove previous auth info to avoid mismatching*/ + if (original_ai) + linphone_core_remove_auth_info(lc,original_ai); + ai=linphone_auth_info_new(linphone_address_get_username(account->modified_identity), NULL, account->password,NULL,NULL,linphone_address_get_domain(account->modified_identity)); diff --git a/tester/call_tester.c b/tester/call_tester.c index e3ddacfc0..723dbdff3 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -17,7 +17,7 @@ */ - #include +#include #include #include "linphonecore.h" #include "lpconfig.h" @@ -26,7 +26,7 @@ #include "mediastreamer2/msutils.h" #include "belle-sip/sipstack.h" -#ifdef WIN32 +#ifdef _WIN32 #define unlink _unlink #ifndef F_OK #define F_OK 00 /*visual studio does not define F_OK*/ @@ -83,15 +83,27 @@ void call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState void call_stats_updated(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallStats *lstats) { stats* counters = get_stats(lc); counters->number_of_LinphoneCallStatsUpdated++; - if (lstats->updated == LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE) { + if (lstats->updated & LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE) { counters->number_of_rtcp_received++; - } else if (lstats->updated == LINPHONE_CALL_STATS_SENT_RTCP_UPDATE) { + if (lstats->rtcp_received_via_mux){ + counters->number_of_rtcp_received_via_mux++; + } + } + if (lstats->updated & LINPHONE_CALL_STATS_SENT_RTCP_UPDATE ) { counters->number_of_rtcp_sent++; } - counters->audio_download_bandwidth = linphone_call_get_audio_stats(call)->download_bandwidth; - counters->audio_upload_bandwidth = linphone_call_get_audio_stats(call)->upload_bandwidth; - counters->video_download_bandwidth = linphone_call_get_video_stats(call)->download_bandwidth; - counters->video_upload_bandwidth = linphone_call_get_video_stats(call)->upload_bandwidth; + if (lstats->updated & LINPHONE_CALL_STATS_PERIODICAL_UPDATE ) { + int tab_size = sizeof (counters->audio_download_bandwidth)/sizeof(int); + int index = (counters->current_bandwidth_index++) % tab_size; + + counters->current_audio_download_bandwidth = counters->audio_download_bandwidth + index; + counters->current_audio_upload_bandwidth = counters->audio_upload_bandwidth +index; + + counters->audio_download_bandwidth[index] = (int)linphone_call_get_audio_stats(call)->download_bandwidth; + counters->audio_upload_bandwidth[index] = (int)linphone_call_get_audio_stats(call)->upload_bandwidth; + counters->video_download_bandwidth[index] = (int)linphone_call_get_video_stats(call)->download_bandwidth; + counters->video_upload_bandwidth[index] = (int)linphone_call_get_video_stats(call)->upload_bandwidth; + } } @@ -135,7 +147,7 @@ void linphone_transfer_state_changed(LinphoneCore *lc, LinphoneCall *transfered, } -void linphone_call_cb(LinphoneCall *call,void * user_data) { +void linphone_call_iframe_decoded_cb(LinphoneCall *call,void * user_data) { 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); stats* counters; @@ -149,7 +161,6 @@ void linphone_call_cb(LinphoneCall *call,void * user_data) { void liblinphone_tester_check_rtcp(LinphoneCoreManager* caller, LinphoneCoreManager* callee) { LinphoneCall *c1,*c2; - int dummy=0; MSTimeSpec ts; c1=linphone_core_get_current_call(caller->lc); @@ -164,22 +175,22 @@ void liblinphone_tester_check_rtcp(LinphoneCoreManager* caller, LinphoneCoreMana liblinphone_tester_clock_start(&ts); do { - if (linphone_call_get_audio_stats(c1)->round_trip_delay >0.0 - && linphone_call_get_audio_stats(c2)->round_trip_delay >0.0 + if (linphone_call_get_audio_stats(c1)->round_trip_delay > 0.0 + && linphone_call_get_audio_stats(c2)->round_trip_delay > 0.0 && (!linphone_call_log_video_enabled(linphone_call_get_call_log(c1)) || linphone_call_get_video_stats(c1)->round_trip_delay>0.0) && (!linphone_call_log_video_enabled(linphone_call_get_call_log(c2)) || linphone_call_get_video_stats(c2)->round_trip_delay>0.0)) { break; } - wait_for_until(caller->lc,callee->lc,&dummy,1,500); /*just to sleep while iterating*/ - }while (!liblinphone_tester_clock_elapsed(&ts,12000)); - BC_ASSERT_TRUE(linphone_call_get_audio_stats(c1)->round_trip_delay>0.0); - BC_ASSERT_TRUE(linphone_call_get_audio_stats(c2)->round_trip_delay>0.0); + wait_for_until(caller->lc,callee->lc,NULL,0,20); /*just to sleep while iterating*/ + }while (!liblinphone_tester_clock_elapsed(&ts,15000)); + BC_ASSERT_GREATER(linphone_call_get_audio_stats(c1)->round_trip_delay,0.0,float,"%f"); + BC_ASSERT_GREATER(linphone_call_get_audio_stats(c2)->round_trip_delay,0.0,float,"%f"); if (linphone_call_log_video_enabled(linphone_call_get_call_log(c1))) { - BC_ASSERT_TRUE(linphone_call_get_video_stats(c1)->round_trip_delay>0.0); + BC_ASSERT_GREATER(linphone_call_get_video_stats(c1)->round_trip_delay,0.0,float,"%f"); } if (linphone_call_log_video_enabled(linphone_call_get_call_log(c2))) { - BC_ASSERT_TRUE(linphone_call_get_video_stats(c2)->round_trip_delay>0.0); + BC_ASSERT_GREATER(linphone_call_get_video_stats(c2)->round_trip_delay,0.0,float,"%f"); } linphone_call_unref(c1); linphone_call_unref(c2); @@ -206,15 +217,18 @@ bool_t call_with_params2(LinphoneCoreManager* caller_mgr LinphoneCallParams *callee_params = callee_test_params->base; bool_t did_receive_call; LinphoneCall *callee_call=NULL; + LinphoneCall *caller_call=NULL; setup_sdp_handling(caller_test_params, caller_mgr); setup_sdp_handling(callee_test_params, callee_mgr); if (!caller_params){ - BC_ASSERT_PTR_NOT_NULL(linphone_core_invite_address(caller_mgr->lc,callee_mgr->identity)); + BC_ASSERT_PTR_NOT_NULL((caller_call=linphone_core_invite_address(caller_mgr->lc,callee_mgr->identity))); }else{ - BC_ASSERT_PTR_NOT_NULL(linphone_core_invite_address_with_params(caller_mgr->lc,callee_mgr->identity,caller_params)); + BC_ASSERT_PTR_NOT_NULL((caller_call=linphone_core_invite_address_with_params(caller_mgr->lc,callee_mgr->identity,caller_params))); } + + BC_ASSERT_PTR_NULL(linphone_call_get_remote_params(caller_call)); /*assert that remote params are NULL when no response is received yet*/ did_receive_call = wait_for(callee_mgr->lc ,caller_mgr->lc @@ -235,10 +249,10 @@ bool_t call_with_params2(LinphoneCoreManager* caller_mgr while (caller_mgr->stat.number_of_LinphoneCallOutgoingRinging!=(initial_caller.number_of_LinphoneCallOutgoingRinging + 1) && caller_mgr->stat.number_of_LinphoneCallOutgoingEarlyMedia!=(initial_caller.number_of_LinphoneCallOutgoingEarlyMedia +1) - && retry++ <20) { + && retry++ < 100) { linphone_core_iterate(caller_mgr->lc); linphone_core_iterate(callee_mgr->lc); - ms_usleep(100000); + ms_usleep(20000); } @@ -279,10 +293,10 @@ bool_t call_with_params2(LinphoneCoreManager* caller_mgr BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallConnected,initial_callee.number_of_LinphoneCallConnected+1)); BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallConnected,initial_callee.number_of_LinphoneCallConnected+1)); - /*just to sleep*/ - result = wait_for(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_caller.number_of_LinphoneCallStreamsRunning+1) + + result = wait_for_until(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_caller.number_of_LinphoneCallStreamsRunning+1, 2000) && - wait_for(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_callee.number_of_LinphoneCallStreamsRunning+1); + wait_for_until(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_callee.number_of_LinphoneCallStreamsRunning+1, 2000); if (linphone_core_get_media_encryption(caller_mgr->lc) != LinphoneMediaEncryptionNone || linphone_core_get_media_encryption(callee_mgr->lc) != LinphoneMediaEncryptionNone) { @@ -302,6 +316,16 @@ bool_t call_with_params2(LinphoneCoreManager* caller_mgr } } + /*wait ice re-invite*/ + if (linphone_core_get_firewall_policy(caller_mgr->lc) == LinphonePolicyUseIce + && linphone_core_get_firewall_policy(callee_mgr->lc) == LinphonePolicyUseIce + && !linphone_core_sdp_200_ack_enabled(caller_mgr->lc) /*ice does not work with sdp less invite*/ + && lp_config_get_int(callee_mgr->lc->config, "sip", "update_call_when_ice_completed", TRUE) + && lp_config_get_int(caller_mgr->lc->config, "sip", "update_call_when_ice_completed", TRUE)) { + BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_caller.number_of_LinphoneCallStreamsRunning+2)); + BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_callee.number_of_LinphoneCallStreamsRunning+2)); + + } return result; } @@ -311,7 +335,7 @@ bool_t call_with_params(LinphoneCoreManager* caller_mgr ,const LinphoneCallParams *callee_params){ LinphoneCallTestParams caller_test_params = {0}, callee_test_params = {0}; caller_test_params.base = (LinphoneCallParams*)caller_params; - callee_test_params.base = (LinphoneCallParams*)caller_params; + callee_test_params.base = (LinphoneCallParams*)callee_params; return call_with_params2(caller_mgr,callee_mgr,&caller_test_params,&callee_test_params,FALSE); } @@ -331,34 +355,29 @@ bool_t call(LinphoneCoreManager* caller_mgr,LinphoneCoreManager* callee_mgr){ } void end_call(LinphoneCoreManager *m1, LinphoneCoreManager *m2){ + int previous_count_1 = m1->stat.number_of_LinphoneCallEnd; + int previous_count_2 = m2->stat.number_of_LinphoneCallEnd; linphone_core_terminate_all_calls(m1->lc); - BC_ASSERT_TRUE(wait_for(m1->lc,m2->lc,&m1->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(m1->lc,m2->lc,&m2->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(m1->lc,m2->lc,&m1->stat.number_of_LinphoneCallReleased,1)); - BC_ASSERT_TRUE(wait_for(m1->lc,m2->lc,&m2->stat.number_of_LinphoneCallReleased,1)); + BC_ASSERT_TRUE(wait_for(m1->lc,m2->lc,&m1->stat.number_of_LinphoneCallEnd,previous_count_1+1)); + BC_ASSERT_TRUE(wait_for(m1->lc,m2->lc,&m2->stat.number_of_LinphoneCallEnd,previous_count_2+1)); + BC_ASSERT_TRUE(wait_for(m1->lc,m2->lc,&m1->stat.number_of_LinphoneCallReleased,previous_count_1+1)); + BC_ASSERT_TRUE(wait_for(m1->lc,m2->lc,&m2->stat.number_of_LinphoneCallReleased,previous_count_2+1)); } void simple_call_base(bool_t enable_multicast_recv_side) { - int begin; - int leaked_objects; LinphoneCoreManager* marie; LinphoneCoreManager* pauline; const LinphoneAddress *from; LinphoneCall *pauline_call; LinphoneProxyConfig* marie_cfg; - const char* marie_id = NULL; - - 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"); + pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); /* with the account manager, we might lose the identity */ marie_cfg = linphone_core_get_default_proxy_config(marie->lc); - marie_id = linphone_proxy_config_get_identity(marie_cfg); { - LinphoneAddress* marie_addr = linphone_address_new(marie_id); + LinphoneAddress* marie_addr = linphone_address_clone(linphone_proxy_config_get_identity_address(marie_cfg)); char* marie_tmp_id = NULL; linphone_address_set_display_name(marie_addr, "Super Marie"); marie_tmp_id = linphone_address_as_string(marie_addr); @@ -368,7 +387,7 @@ void simple_call_base(bool_t enable_multicast_recv_side) { linphone_proxy_config_done(marie_cfg); ms_free(marie_tmp_id); - linphone_address_unref(marie_addr); + linphone_address_destroy(marie_addr); } linphone_core_enable_audio_multicast(pauline->lc,enable_multicast_recv_side); @@ -392,31 +411,43 @@ void simple_call_base(bool_t enable_multicast_recv_side) { liblinphone_tester_check_rtcp(marie,pauline); end_call(marie,pauline); - linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); - - leaked_objects=belle_sip_object_get_object_count()-begin; - BC_ASSERT_TRUE(leaked_objects==0); - if (leaked_objects>0){ - belle_sip_object_dump_active_objects(); - } + linphone_core_manager_destroy(marie); } -static void simple_call() { +static void simple_call(void) { simple_call_base(FALSE); } +static void automatic_call_termination(void) { + LinphoneCoreManager* marie; + LinphoneCoreManager* pauline; + + marie = linphone_core_manager_new( "marie_rc"); + pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + + + if (!BC_ASSERT_TRUE(call(marie,pauline))) goto end; + + liblinphone_tester_check_rtcp(marie,pauline); + + linphone_core_destroy(pauline->lc); + pauline->lc = NULL; + /*marie shall receive the BYE*/ + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1)); + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallReleased, 1)); +end: + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(marie); +} + static void call_with_timeouted_bye(void) { - int begin; - int leaked_objects; LinphoneCoreManager* marie; LinphoneCoreManager* pauline; belle_sip_timer_config_t timer_config; - 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"); + pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); BC_ASSERT_TRUE(call(marie,pauline)); @@ -440,48 +471,9 @@ static void call_with_timeouted_bye(void) { linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); - - leaked_objects=belle_sip_object_get_object_count()-begin; - BC_ASSERT_TRUE(leaked_objects==0); - if (leaked_objects>0){ - belle_sip_object_dump_active_objects(); - } } -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)); - BC_ASSERT_STRING_EQUAL(result, "+33952636505"); - linphone_proxy_config_normalize_number(cfg, "09 52 63 65 05", result, sizeof(result)); - BC_ASSERT_STRING_EQUAL(result, "+33952636505"); - linphone_proxy_config_normalize_number(cfg, "09-52-63-65-05", result, sizeof(result)); - BC_ASSERT_STRING_EQUAL(result, "+33952636505"); - linphone_proxy_config_normalize_number(cfg, "+31952636505", result, sizeof(result)); - BC_ASSERT_STRING_EQUAL(result, "+31952636505"); - linphone_proxy_config_normalize_number(cfg, "0033952636505", result, sizeof(result)); - BC_ASSERT_STRING_EQUAL(result, "+33952636505"); - linphone_proxy_config_normalize_number(cfg, "0033952636505", result, sizeof(result)); - BC_ASSERT_STRING_EQUAL(result, "+33952636505"); - linphone_proxy_config_normalize_number(cfg, "toto", result, sizeof(result)); - BC_ASSERT_STRING_EQUAL(result, "toto"); - - linphone_proxy_config_set_dial_escape_plus(cfg, TRUE); - linphone_proxy_config_normalize_number(cfg, "0033952636505", result, sizeof(result)); - BC_ASSERT_STRING_EQUAL(result, "0033952636505"); - linphone_proxy_config_normalize_number(cfg, "0952636505", result, sizeof(result)); - BC_ASSERT_STRING_EQUAL(result, "0033952636505"); - linphone_proxy_config_normalize_number(cfg, "+34952636505", result, sizeof(result)); - BC_ASSERT_STRING_EQUAL(result, "0034952636505"); - - linphone_proxy_config_unref(cfg); - linphone_core_manager_destroy(marie); -} - -static void direct_call_over_ipv6(){ +static void direct_call_over_ipv6(void){ LinphoneCoreManager* marie; LinphoneCoreManager* pauline; @@ -489,7 +481,7 @@ static void direct_call_over_ipv6(){ LCSipTransports pauline_transports; LinphoneAddress* pauline_dest = linphone_address_new("sip:[::1];transport=tcp"); marie = linphone_core_manager_new( "marie_rc"); - pauline = linphone_core_manager_new( "pauline_tcp_rc"); + pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); linphone_core_enable_ipv6(marie->lc,TRUE); linphone_core_enable_ipv6(pauline->lc,TRUE); @@ -518,12 +510,12 @@ static void direct_call_over_ipv6(){ }else ms_warning("Test skipped, no ipv6 available"); } -static void call_outbound_with_multiple_proxy() { - LinphoneCoreManager* pauline = linphone_core_manager_new2( "pauline_rc", FALSE); +static void call_outbound_with_multiple_proxy(void) { LinphoneCoreManager* marie = linphone_core_manager_new2( "marie_rc", FALSE); + LinphoneCoreManager* pauline = linphone_core_manager_new2( "pauline_tcp_rc", FALSE); LinphoneProxyConfig* lpc = NULL; - LinphoneProxyConfig* registered_lpc = linphone_proxy_config_new(); + LinphoneProxyConfig* registered_lpc = linphone_core_create_proxy_config(marie->lc); linphone_core_get_default_proxy(marie->lc, &lpc); linphone_core_set_default_proxy(marie->lc,NULL); @@ -538,6 +530,7 @@ static void call_outbound_with_multiple_proxy() { linphone_proxy_config_enable_register(registered_lpc, TRUE); linphone_core_add_proxy_config(marie->lc, registered_lpc); + linphone_proxy_config_unref(registered_lpc); // set first LPC to unreacheable proxy addr linphone_proxy_config_edit(lpc); @@ -553,12 +546,13 @@ static void call_outbound_with_multiple_proxy() { // calling marie should go through the second proxy config BC_ASSERT_TRUE(call(marie, pauline)); + end_call(marie, pauline); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } #if 0 /* TODO: activate test when the implementation is ready */ -static void multiple_answers_call() { +static void multiple_answers_call(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 call running, the other should be terminated */ @@ -607,7 +601,7 @@ 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 * call running, the other should be terminated */ - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc" ); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc" ); LinphoneCoreManager* marie1 = linphone_core_manager_new( "marie_rc" ); LinphoneCoreManager* marie2 = linphone_core_manager_new( "marie_rc" ); @@ -643,6 +637,7 @@ static void multiple_answers_call_with_media_relay(void) { BC_ASSERT_TRUE( wait_for_list(lcs, &marie1->stat.number_of_LinphoneCallStreamsRunning, 1, 2000) ); BC_ASSERT_TRUE( wait_for_list(lcs, &marie2->stat.number_of_LinphoneCallEnd, 1, 2000) ); + end_call(marie1, pauline); linphone_core_manager_destroy(pauline); linphone_core_manager_destroy(marie1); @@ -650,14 +645,13 @@ static void multiple_answers_call_with_media_relay(void) { } static void call_with_specified_codec_bitrate(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - const LinphoneCallStats *pauline_stats,*marie_stats; + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); bool_t call_ok; - char * codec = "opus"; + const char * codec = "opus"; int rate = 48000; int min_bw=24; - int max_bw=40; + int max_bw=50; #ifdef __arm__ if (ms_get_cpu_count() <2) { /*2 opus codec channel + resampler is too much for a single core*/ @@ -667,14 +661,17 @@ static void call_with_specified_codec_bitrate(void) { min_bw=20; max_bw=35; #else - CU_PASS("Test requires at least a dual core"); + BC_PASS("Test requires at least a dual core"); goto end; #endif } #endif + /*Force marie to play from file: if soundcard is used and it is silient, then vbr mode will drop down the bitrate + Note that a play file is already set by linphone_core_manager_new() (but not used)*/ + linphone_core_set_use_files(marie->lc, TRUE); if (linphone_core_find_payload_type(marie->lc,codec,rate,-1)==NULL){ - ms_warning("opus codec not supported, test skipped."); + BC_PASS("opus codec not supported, test skipped."); goto end; } @@ -691,11 +688,14 @@ static void call_with_specified_codec_bitrate(void) { BC_ASSERT_TRUE((call_ok=call(pauline,marie))); if (!call_ok) goto end; liblinphone_tester_check_rtcp(marie,pauline); - marie_stats=linphone_call_get_audio_stats(linphone_core_get_current_call(marie->lc)); - pauline_stats=linphone_call_get_audio_stats(linphone_core_get_current_call(pauline->lc)); - BC_ASSERT_TRUE(marie_stats->download_bandwidth<(min_bw+5+min_bw*.1)); - BC_ASSERT_TRUE(pauline_stats->download_bandwidth>(max_bw-5-max_bw*.1)); + /*wait a bit that bitstreams are stabilized*/ + wait_for_until(marie->lc, pauline->lc, NULL, 0, 2000); + BC_ASSERT_LOWER(linphone_core_manager_get_mean_audio_down_bw(marie), (int)(min_bw+5+min_bw*.1), int, "%i"); + BC_ASSERT_GREATER(linphone_core_manager_get_mean_audio_down_bw(marie), 10, int, "%i"); /*check that at least something is received */ + BC_ASSERT_GREATER(linphone_core_manager_get_mean_audio_down_bw(pauline), (int)(max_bw-5-max_bw*.1), int, "%i"); + + end_call(pauline, marie); end: linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); @@ -703,22 +703,22 @@ end: static void simple_call_compatibility_mode(void) { char route[256]; - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCore* lc_marie=marie->lc; LinphoneCore* lc_pauline=pauline->lc; stats* stat_marie=&marie->stat; stats* stat_pauline=&pauline->stat; LinphoneProxyConfig* proxy; - LinphoneAddress* identity; + const LinphoneAddress* identity; LinphoneAddress* proxy_address; char*tmp; LCSipTransports transport; linphone_core_get_default_proxy(lc_marie,&proxy); BC_ASSERT_PTR_NOT_NULL (proxy); - identity = linphone_address_new(linphone_proxy_config_get_identity(proxy)); + identity = linphone_proxy_config_get_identity_address(proxy); proxy_address=linphone_address_new(linphone_proxy_config_get_addr(proxy)); @@ -749,7 +749,6 @@ static void simple_call_compatibility_mode(void) { BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call_remote_address(lc_pauline)); if (linphone_core_get_current_call_remote_address(lc_pauline)) { BC_ASSERT_TRUE(linphone_address_weak_equal(identity,linphone_core_get_current_call_remote_address(lc_pauline))); - linphone_address_destroy(identity); linphone_core_accept_call(lc_pauline,linphone_core_get_current_call(lc_pauline)); @@ -757,11 +756,9 @@ static void simple_call_compatibility_mode(void) { BC_ASSERT_TRUE(wait_for(lc_pauline,lc_marie,&stat_marie->number_of_LinphoneCallConnected,1)); BC_ASSERT_TRUE(wait_for(lc_pauline,lc_marie,&stat_pauline->number_of_LinphoneCallStreamsRunning,1)); BC_ASSERT_TRUE(wait_for(lc_pauline,lc_marie,&stat_marie->number_of_LinphoneCallStreamsRunning,1)); - /*just to sleep*/ + wait_for(lc_pauline,lc_marie,&stat_marie->number_of_LinphoneCallStreamsRunning,3); - linphone_core_terminate_all_calls(lc_pauline); - BC_ASSERT_TRUE(wait_for(lc_pauline,lc_marie,&stat_pauline->number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(lc_pauline,lc_marie,&stat_marie->number_of_LinphoneCallEnd,1)); + end_call(pauline, marie); } linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); @@ -769,8 +766,8 @@ static void simple_call_compatibility_mode(void) { static void cancelled_call(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCall* out_call = linphone_core_invite_address(pauline->lc,marie->identity); linphone_call_ref(out_call); @@ -863,8 +860,8 @@ static void early_cancelled_call(void) { } static void cancelled_ringing_call(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCall* out_call = linphone_core_invite_address(pauline->lc,marie->identity); linphone_call_ref(out_call); @@ -882,8 +879,8 @@ static void cancelled_ringing_call(void) { } static void early_declined_call(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCallLog* out_call_log; LinphoneCall* out_call; @@ -923,8 +920,8 @@ static void call_busy_when_calling_self(void) { static void call_declined(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCall* in_call; LinphoneCall* out_call = linphone_core_invite_address(pauline->lc,marie->identity); @@ -939,7 +936,9 @@ static void call_declined(void) { BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallEnd,1, int, "%d"); BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallEnd,1, int, "%d"); BC_ASSERT_EQUAL(linphone_call_get_reason(in_call),LinphoneReasonDeclined, int, "%d"); + BC_ASSERT_EQUAL(linphone_call_log_get_status(linphone_call_get_call_log(in_call)),LinphoneCallDeclined, int, "%d"); BC_ASSERT_EQUAL(linphone_call_get_reason(out_call),LinphoneReasonDeclined, int, "%d"); + BC_ASSERT_EQUAL(linphone_call_log_get_status(linphone_call_get_call_log(out_call)),LinphoneCallDeclined, int, "%d"); linphone_call_unref(in_call); } linphone_call_unref(out_call); @@ -948,38 +947,33 @@ static void call_declined(void) { } static void call_terminated_by_caller(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); BC_ASSERT_TRUE(call(pauline,marie)); - /*just to sleep*/ - linphone_core_terminate_all_calls(pauline->lc); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + + end_call(pauline, marie); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } static void call_with_no_sdp(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); linphone_core_enable_sdp_200_ack(marie->lc,TRUE); BC_ASSERT_TRUE(call(marie,pauline)); - /*just to sleep*/ - linphone_core_terminate_all_calls(pauline->lc); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + end_call(pauline, marie); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } static void call_with_no_sdp_ack_without_sdp(void){ - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCall *call; linphone_core_enable_sdp_200_ack(marie->lc,TRUE); @@ -997,72 +991,20 @@ static void call_with_no_sdp_ack_without_sdp(void){ linphone_core_manager_destroy(pauline); } - -static bool_t check_ice(LinphoneCoreManager* caller, LinphoneCoreManager* callee, LinphoneIceState state) { - LinphoneCall *c1,*c2; - bool_t audio_success=FALSE; - bool_t video_success=FALSE; - bool_t video_enabled; - MSTimeSpec ts; - - c1=linphone_core_get_current_call(caller->lc); - c2=linphone_core_get_current_call(callee->lc); - +static void check_nb_media_starts(LinphoneCoreManager *caller, LinphoneCoreManager *callee, unsigned int caller_nb_media_starts, unsigned int callee_nb_media_starts) { + LinphoneCall *c1 = linphone_core_get_current_call(caller->lc); + LinphoneCall *c2 = linphone_core_get_current_call(callee->lc); BC_ASSERT_PTR_NOT_NULL(c1); BC_ASSERT_PTR_NOT_NULL(c2); - if (!c1 || !c2) return FALSE; - linphone_call_ref(c1); - linphone_call_ref(c2); - - BC_ASSERT_EQUAL(linphone_call_params_video_enabled(linphone_call_get_current_params(c1)),linphone_call_params_video_enabled(linphone_call_get_current_params(c2)), int, "%d"); - video_enabled=linphone_call_params_video_enabled(linphone_call_get_current_params(c1)); - liblinphone_tester_clock_start(&ts); - do{ - if ((c1 != NULL) && (c2 != NULL)) { - if (linphone_call_get_audio_stats(c1)->ice_state==state && - linphone_call_get_audio_stats(c2)->ice_state==state ){ - audio_success=TRUE; - break; - } - linphone_core_iterate(caller->lc); - linphone_core_iterate(callee->lc); - } - ms_usleep(20000); - }while(!liblinphone_tester_clock_elapsed(&ts,10000)); - - if (video_enabled){ - liblinphone_tester_clock_start(&ts); - do{ - if ((c1 != NULL) && (c2 != NULL)) { - if (linphone_call_get_video_stats(c1)->ice_state==state && - linphone_call_get_video_stats(c2)->ice_state==state ){ - video_success=TRUE; - break; - } - linphone_core_iterate(caller->lc); - linphone_core_iterate(callee->lc); - } - ms_usleep(20000); - }while(!liblinphone_tester_clock_elapsed(&ts,10000)); - } - - /*make sure encryption mode are preserved*/ if (c1) { - const LinphoneCallParams* call_param = linphone_call_get_current_params(c1); - BC_ASSERT_EQUAL(linphone_call_params_get_media_encryption(call_param),linphone_core_get_media_encryption(caller->lc), int, "%d"); + BC_ASSERT_EQUAL(c1->nb_media_starts, caller_nb_media_starts, unsigned int, "%u"); } if (c2) { - const LinphoneCallParams* call_param = linphone_call_get_current_params(c2); - BC_ASSERT_EQUAL(linphone_call_params_get_media_encryption(call_param),linphone_core_get_media_encryption(callee->lc), int, "%d"); + BC_ASSERT_EQUAL(c2->nb_media_starts, callee_nb_media_starts, unsigned int, "%u"); } - linphone_call_unref(c1); - linphone_call_unref(c2); - return video_enabled ? audio_success && video_success : audio_success; } static void _call_with_ice_base(LinphoneCoreManager* pauline,LinphoneCoreManager* marie, bool_t caller_with_ice, bool_t callee_with_ice, bool_t random_ports) { - bool_t call_ok; - if (callee_with_ice){ linphone_core_set_firewall_policy(marie->lc,LinphonePolicyUseIce); } @@ -1073,32 +1015,33 @@ static void _call_with_ice_base(LinphoneCoreManager* pauline,LinphoneCoreManager if (random_ports){ linphone_core_set_audio_port(marie->lc,-1); linphone_core_set_video_port(marie->lc,-1); + linphone_core_set_text_port(marie->lc, -1); linphone_core_set_audio_port(pauline->lc,-1); linphone_core_set_video_port(pauline->lc,-1); + linphone_core_set_text_port(pauline->lc, -1); } - BC_ASSERT_TRUE((call_ok=call(pauline,marie))); - if (!call_ok) goto end; + if (!BC_ASSERT_TRUE(call(pauline,marie))) + return; + if (callee_with_ice && caller_with_ice) { /*wait for the ICE reINVITE to complete*/ BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2)); BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,2)); BC_ASSERT_TRUE(check_ice(pauline,marie,LinphoneIceStateHostConnection)); + check_nb_media_starts(pauline, marie, 1, 1); } liblinphone_tester_check_rtcp(marie,pauline); /*then close the call*/ - linphone_core_terminate_all_calls(pauline->lc); -end: - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + end_call(pauline, marie); } static void _call_with_ice(bool_t caller_with_ice, bool_t callee_with_ice, bool_t random_ports) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); _call_with_ice_base(pauline,marie,caller_with_ice,callee_with_ice,random_ports); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); @@ -1109,8 +1052,8 @@ static void call_with_ice(void){ /*ICE is not expected to work in this case, however this should not crash*/ static void call_with_ice_no_sdp(void){ - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); linphone_core_enable_sdp_200_ack(pauline->lc,TRUE); @@ -1122,6 +1065,7 @@ static void call_with_ice_no_sdp(void){ liblinphone_tester_check_rtcp(marie,pauline); + end_call(pauline, marie); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } @@ -1139,8 +1083,8 @@ static void not_ice_to_ice(void){ } static void call_with_custom_headers(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCall *call_marie,*call_pauline; LinphoneCallParams *params; const LinphoneCallParams *marie_remote_params; @@ -1158,7 +1102,7 @@ static void call_with_custom_headers(void) { linphone_address_destroy(marie->identity); marie->identity=marie_identity; - params=linphone_core_create_default_call_parameters(marie->lc); + params=linphone_core_create_call_params(marie->lc, NULL); linphone_call_params_add_custom_header(params,"Weather","bad"); linphone_call_params_add_custom_header(params,"Working","yes"); @@ -1199,19 +1143,84 @@ static void call_with_custom_headers(void) { ms_free(marie_remote_contact); ms_free(marie_remote_contact_header); + end_call(pauline, marie); - /*just to sleep*/ - linphone_core_terminate_all_calls(pauline->lc); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - BC_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 void call_with_custom_sdp_attributes_cb(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *message) { + if (cstate == LinphoneCallUpdatedByRemote) { + LinphoneCallParams *params; + const LinphoneCallParams *remote_params = linphone_call_get_remote_params(call); + const char *value = linphone_call_params_get_custom_sdp_attribute(remote_params, "weather"); + BC_ASSERT_PTR_NOT_NULL(value); + if (value) BC_ASSERT_STRING_EQUAL(value, "sunny"); + params = linphone_core_create_call_params(lc, call); + linphone_call_params_clear_custom_sdp_attributes(params); + linphone_call_params_clear_custom_sdp_media_attributes(params, LinphoneStreamTypeAudio); + linphone_call_params_add_custom_sdp_attribute(params, "working", "no"); + BC_ASSERT_EQUAL(linphone_core_accept_call_update(lc, call, params), 0, int, "%i"); + linphone_call_params_destroy(params); + } +} + +static void call_with_custom_sdp_attributes(void) { + LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager *pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + LinphoneCall *call_marie, *call_pauline; + LinphoneCallParams *pauline_params; + const LinphoneCallParams *marie_remote_params; + const LinphoneCallParams *pauline_remote_params; + const char *value; + LinphoneCoreVTable *vtable; + + pauline_params = linphone_core_create_call_params(pauline->lc, NULL); + linphone_call_params_add_custom_sdp_attribute(pauline_params, "weather", "bad"); + linphone_call_params_add_custom_sdp_attribute(pauline_params, "working", "yes"); + linphone_call_params_add_custom_sdp_media_attribute(pauline_params, LinphoneStreamTypeAudio, "sleeping", "almost"); + BC_ASSERT_TRUE(call_with_caller_params(pauline, marie, pauline_params)); + linphone_call_params_destroy(pauline_params); + + call_marie = linphone_core_get_current_call(marie->lc); + call_pauline = linphone_core_get_current_call(pauline->lc); + BC_ASSERT_PTR_NOT_NULL(call_marie); + BC_ASSERT_PTR_NOT_NULL(call_pauline); + + marie_remote_params = linphone_call_get_remote_params(call_marie); + value = linphone_call_params_get_custom_sdp_attribute(marie_remote_params, "weather"); + BC_ASSERT_PTR_NOT_NULL(value); + if (value) BC_ASSERT_STRING_EQUAL(value, "bad"); + value = linphone_call_params_get_custom_sdp_media_attribute(marie_remote_params, LinphoneStreamTypeAudio, "sleeping"); + BC_ASSERT_PTR_NOT_NULL(value); + if (value) BC_ASSERT_STRING_EQUAL(value, "almost"); + + vtable = linphone_core_v_table_new(); + vtable->call_state_changed = call_with_custom_sdp_attributes_cb; + linphone_core_add_listener(marie->lc, vtable); + pauline_params = linphone_core_create_call_params(pauline->lc, call_pauline); + linphone_call_params_clear_custom_sdp_attributes(pauline_params); + linphone_call_params_clear_custom_sdp_media_attributes(pauline_params, LinphoneStreamTypeAudio); + linphone_call_params_add_custom_sdp_attribute(pauline_params, "weather", "sunny"); + linphone_core_update_call(pauline->lc, call_pauline, pauline_params); + BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneCallUpdatedByRemote, 1)); + BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneCallUpdating, 1)); + linphone_call_params_destroy(pauline_params); + BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 2)); + pauline_remote_params = linphone_call_get_remote_params(call_pauline); + value = linphone_call_params_get_custom_sdp_attribute(pauline_remote_params, "working"); + BC_ASSERT_PTR_NOT_NULL(value); + if (value) BC_ASSERT_STRING_EQUAL(value, "no"); + + end_call(pauline, marie); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } void call_paused_resumed_base(bool_t multicast) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCall* call_pauline; const rtp_stats_t * stats; bool_t call_ok; @@ -1243,13 +1252,9 @@ void call_paused_resumed_base(bool_t multicast) { /*since RTCP streams are reset when call is paused/resumed, there should be no loss at all*/ stats = rtp_session_get_stats(call_pauline->sessions->rtp_session); - BC_ASSERT_EQUAL(stats->cum_packet_loss, 0, int, "%d"); - - /*just to sleep*/ - linphone_core_terminate_all_calls(pauline->lc); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + BC_ASSERT_EQUAL((int)stats->cum_packet_loss, 0, int, "%d"); + end_call(pauline, marie); end: linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); @@ -1257,18 +1262,208 @@ end: static void call_paused_resumed(void) { call_paused_resumed_base(FALSE); } + +static void call_paused_by_both(void) { + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + LinphoneCall* call_pauline, *call_marie; + const rtp_stats_t * stats; + MSList *lcs = NULL; + bool_t call_ok; + + lcs = ms_list_append(lcs, pauline->lc); + lcs = ms_list_append(lcs, marie->lc); + BC_ASSERT_TRUE((call_ok=call(pauline,marie))); + + if (!call_ok) goto end; + + call_pauline = linphone_core_get_current_call(pauline->lc); + call_marie = linphone_core_get_current_call(marie->lc); + + wait_for_until(pauline->lc, marie->lc, NULL, 5, 2000); + + linphone_core_pause_call(pauline->lc,call_pauline); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallPausing,1)); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallPausedByRemote,1)); + BC_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, 2000); + + /*marie pauses the call also*/ + linphone_core_pause_call(marie->lc, call_marie); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallPausing,1)); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallPaused,1)); + + wait_for_until(pauline->lc, marie->lc, NULL, 5, 2000); + /*pauline must stay in paused state*/ + BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallPaused, 1, int, "%i"); + check_media_direction(pauline, call_pauline, lcs, LinphoneMediaDirectionInactive, LinphoneMediaDirectionInvalid); + check_media_direction(marie, call_marie, lcs, LinphoneMediaDirectionInactive, LinphoneMediaDirectionInvalid); + + /*now pauline wants to resume*/ + linphone_core_resume_call(pauline->lc, call_pauline); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallResuming,1)); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallPausedByRemote,1)); + /*Marie must stay in paused state*/ + wait_for_until(pauline->lc, marie->lc, NULL, 5, 2000); + BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallPaused, 1, int, "%i"); + + /*now marie wants to resume also*/ + linphone_core_resume_call(marie->lc, call_marie); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallResuming,1)); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,2)); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2)); + /*same here: wait a while for a bit of a traffic, we need to receive a RTCP packet*/ + wait_for_until(pauline->lc, marie->lc, NULL, 5, 5000); + + /*since RTCP streams are reset when call is paused/resumed, there should be no loss at all*/ + stats = rtp_session_get_stats(call_pauline->sessions->rtp_session); + BC_ASSERT_EQUAL((int)stats->cum_packet_loss, 0, int, "%d"); + + end_call(marie, pauline); + +end: + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + ms_list_free(lcs); +} + +static void call_paused_resumed_with_video_base_call_cb(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *message) { + if (cstate == LinphoneCallUpdatedByRemote) { + LinphoneCallParams *params = linphone_core_create_call_params(lc, call); + linphone_call_params_enable_video(params, TRUE); + ms_message (" New state LinphoneCallUpdatedByRemote on call [%p], accepting with video on",call); + BC_ASSERT_NOT_EQUAL(linphone_core_accept_call_update(lc, call, params), 0, int, "%i"); + linphone_call_params_destroy(params); + } +} +/*this test makes sure that pause/resume will not bring up video by accident*/ +static void call_paused_resumed_with_video_base(bool_t sdp_200_ack + ,bool_t use_video_policy_for_re_invite_sdp_200 + ,bool_t resume_in_audio_send_only_video_inactive_first + ,bool_t with_call_accept){ + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + LinphoneCall* call_pauline, *call_marie; + MSList *lcs = NULL; + LinphoneVideoPolicy vpol; + bool_t call_ok; + LinphoneCoreVTable *vtable = linphone_core_v_table_new(); + vtable->call_state_changed = call_paused_resumed_with_video_base_call_cb; + lcs = ms_list_append(lcs, pauline->lc); + lcs = ms_list_append(lcs, marie->lc); + + vpol.automatically_accept = FALSE; + vpol.automatically_initiate = TRUE; /* needed to present a video mline*/ + + linphone_core_set_video_policy(marie->lc, &vpol); + linphone_core_enable_video(marie->lc, TRUE, TRUE); + + vpol.automatically_accept = FALSE; + vpol.automatically_initiate = TRUE; + + linphone_core_set_video_policy(pauline->lc, &vpol); + linphone_core_enable_video(pauline->lc, TRUE, TRUE); + + BC_ASSERT_TRUE((call_ok=call(marie, pauline))); + + if (!call_ok) goto end; + + call_pauline = linphone_core_get_current_call(pauline->lc); + call_marie = linphone_core_get_current_call(marie->lc); + + wait_for_until(pauline->lc, marie->lc, NULL, 5, 2000); + + linphone_core_pause_call(pauline->lc,call_pauline); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallPausing,1)); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallPausedByRemote,1)); + BC_ASSERT_FALSE(linphone_call_params_video_enabled(linphone_call_get_remote_params(call_marie))); + BC_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, 2000); + + /*check if video stream is still offered even if disabled*/ + + BC_ASSERT_EQUAL(call_pauline->localdesc->nb_streams, 2, int, "%i"); + BC_ASSERT_EQUAL(call_marie->localdesc->nb_streams, 2, int, "%i"); + + linphone_core_enable_sdp_200_ack(pauline->lc,sdp_200_ack); + + if (use_video_policy_for_re_invite_sdp_200) { + LpConfig *marie_lp; + marie_lp = linphone_core_get_config(marie->lc); + lp_config_set_int(marie_lp,"sip","sdp_200_ack_follow_video_policy",1); + } + /*now pauline wants to resume*/ + if (resume_in_audio_send_only_video_inactive_first) { + LinphoneCallParams *params = linphone_core_create_call_params(pauline->lc, call_pauline); + linphone_call_params_set_video_direction(params,LinphoneMediaDirectionInactive); + linphone_call_params_set_audio_direction(params,LinphoneMediaDirectionSendOnly); + linphone_core_update_call(pauline->lc,call_pauline,params); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallPausedByRemote,2)); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallUpdating,1)); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2)); + linphone_call_params_set_video_direction(params,LinphoneMediaDirectionSendRecv); + linphone_call_params_set_audio_direction(params,LinphoneMediaDirectionSendRecv); + if (with_call_accept) { + linphone_core_add_listener(marie->lc, vtable); + } + linphone_core_update_call(pauline->lc,call_pauline,params); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,3)); + linphone_call_params_destroy(params); + } else { + linphone_core_resume_call(pauline->lc, call_pauline); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallResuming,1)); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2)); + } + + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,2)); + + if (use_video_policy_for_re_invite_sdp_200) { + /*make sure video was offered*/ + BC_ASSERT_TRUE(linphone_call_params_video_enabled(linphone_call_get_remote_params(call_pauline))); + } else { + BC_ASSERT_FALSE(linphone_call_params_video_enabled(linphone_call_get_current_params(call_pauline))); + BC_ASSERT_FALSE(linphone_call_params_video_enabled(linphone_call_get_current_params(call_marie))); + } + end_call(marie, pauline); + +end: + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + ms_list_free(lcs); +} +static void call_paused_resumed_with_video(void){ + call_paused_resumed_with_video_base(FALSE, FALSE,FALSE,FALSE); +} + +static void call_paused_resumed_with_no_sdp_ack(void){ + call_paused_resumed_with_video_base(TRUE, FALSE,FALSE,FALSE); +} +static void call_paused_resumed_with_no_sdp_ack_using_video_policy(void){ + call_paused_resumed_with_video_base(TRUE, TRUE,FALSE,FALSE); +} +static void call_paused_updated_resumed_with_no_sdp_ack_using_video_policy(void){ + call_paused_resumed_with_video_base(TRUE, TRUE,TRUE,FALSE); +} +static void call_paused_updated_resumed_with_no_sdp_ack_using_video_policy_and_accept_call_update(void){ + call_paused_resumed_with_video_base(TRUE, TRUE,TRUE,TRUE); +} + #define CHECK_CURRENT_LOSS_RATE() \ rtcp_count_current = pauline->stat.number_of_rtcp_sent; \ /*wait for an RTCP packet to have an accurate cumulative lost value*/ \ BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &pauline->stat.number_of_rtcp_sent, rtcp_count_current+1, 10000)); \ stats = rtp_session_get_stats(call_pauline->audiostream->ms.sessions.rtp_session); \ loss_percentage = stats->cum_packet_loss * 100.f / (stats->packet_recv + stats->cum_packet_loss); \ - BC_ASSERT_TRUE(.75 * params.loss_rate < loss_percentage); \ - BC_ASSERT_TRUE(loss_percentage < 1.25 * params.loss_rate) + BC_ASSERT_GREATER(loss_percentage, .75f * params.loss_rate, float, "%f"); \ + BC_ASSERT_LOWER(loss_percentage , 1.25f * params.loss_rate, float, "%f") static void call_paused_resumed_with_loss(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCall* call_pauline; const rtp_stats_t * stats; float loss_percentage; @@ -1305,9 +1500,7 @@ static void call_paused_resumed_with_loss(void) { /*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); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + end_call(marie, pauline); } linphone_core_manager_destroy(marie); @@ -1326,9 +1519,9 @@ bool_t pause_call_1(LinphoneCoreManager* mgr_1,LinphoneCall* call_1,LinphoneCore return linphone_call_get_state(call_1) == LinphoneCallPaused && linphone_call_get_state(call_2)==LinphoneCallPausedByRemote; } #if 0 -void concurrent_paused_resumed_base() { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); +void concurrent_paused_resumed_base(void) { + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCall* call_pauline,call_marie; const rtp_stats_t * stats; @@ -1360,7 +1553,7 @@ void concurrent_paused_resumed_base() { stats = rtp_session_get_stats(call_pauline->sessions->rtp_session); BC_ASSERT_EQUAL(stats->cum_packet_loss, 0, int, "%d"); - /*just to sleep*/ + linphone_core_terminate_all_calls(pauline->lc); BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); @@ -1371,8 +1564,8 @@ void concurrent_paused_resumed_base() { } #endif static void call_paused_resumed_from_callee(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCall* call_marie; const rtp_stats_t * stats; bool_t call_ok; @@ -1397,12 +1590,9 @@ static void call_paused_resumed_from_callee(void) { /*since RTCP streams are reset when call is paused/resumed, there should be no loss at all*/ stats = rtp_session_get_stats(call_marie->sessions->rtp_session); - BC_ASSERT_EQUAL(stats->cum_packet_loss, 0, int, "%d"); + BC_ASSERT_EQUAL((int)stats->cum_packet_loss, 0, int, "%d"); - /*just to sleep*/ - linphone_core_terminate_all_calls(pauline->lc); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + end_call(pauline, marie); end: linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); @@ -1410,7 +1600,7 @@ end: static void audio_call_with_ice_no_matching_audio_codecs(void) { LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); - LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCall *out_call; linphone_core_enable_payload_type(marie->lc, linphone_core_find_payload_type(marie->lc, "PCMU", 8000, 1), FALSE); /* Disable PCMU */ @@ -1455,10 +1645,11 @@ static LinphoneCall* setup_video(LinphoneCoreManager* caller,LinphoneCoreManager linphone_core_enable_video_display(caller->lc, FALSE); if ((call_obj = linphone_core_get_current_call(callee->lc))) { - callee_params = linphone_call_params_copy(linphone_call_get_current_params(call_obj)); + callee_params = linphone_core_create_call_params(callee->lc, call_obj); /*add video*/ linphone_call_params_enable_video(callee_params,TRUE); linphone_core_update_call(callee->lc,call_obj,callee_params); + linphone_call_params_destroy(callee_params); } return call_obj; } @@ -1514,7 +1705,7 @@ bool_t add_video(LinphoneCoreManager* caller,LinphoneCoreManager* callee, bool_t } if (video_policy->automatically_accept) { - linphone_call_set_next_video_frame_decoded_callback(call_obj,linphone_call_cb,callee->lc); + linphone_call_set_next_video_frame_decoded_callback(call_obj,linphone_call_iframe_decoded_cb,callee->lc); /*send vfu*/ linphone_call_send_vfu_request(call_obj); return wait_for(caller->lc,callee->lc,&callee->stat.number_of_IframeDecoded,initial_callee_stat.number_of_IframeDecoded+1); @@ -1540,11 +1731,11 @@ static bool_t remove_video(LinphoneCoreManager *caller, LinphoneCoreManager *cal } if ((call_obj = linphone_core_get_current_call(callee->lc))) { - callee_params = linphone_call_params_copy(linphone_call_get_current_params(call_obj)); - + callee_params = linphone_core_create_call_params(callee->lc, call_obj); /* Remove video. */ linphone_call_params_enable_video(callee_params, FALSE); linphone_core_update_call(callee->lc, call_obj, callee_params); + linphone_call_params_destroy(callee_params); BC_ASSERT_TRUE(wait_for(caller->lc, callee->lc, &caller->stat.number_of_LinphoneCallUpdatedByRemote, initial_caller_stat.number_of_LinphoneCallUpdatedByRemote + 1)); BC_ASSERT_TRUE(wait_for(caller->lc, callee->lc, &callee->stat.number_of_LinphoneCallUpdating, initial_callee_stat.number_of_LinphoneCallUpdating + 1)); @@ -1560,18 +1751,16 @@ static bool_t remove_video(LinphoneCoreManager *caller, LinphoneCoreManager *cal } static void call_with_video_added(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); bool_t call_ok; BC_ASSERT_TRUE((call_ok=call(pauline,marie))); if (!call_ok) goto end; BC_ASSERT_TRUE(add_video(pauline,marie, TRUE)); - /*just to sleep*/ - linphone_core_terminate_all_calls(pauline->lc); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + + end_call(pauline, marie); end: linphone_core_manager_destroy(marie); @@ -1579,8 +1768,8 @@ end: } static void call_with_video_added_2(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); bool_t call_ok; /*in this variant marie is already in automatically accept*/ LinphoneVideoPolicy marie_policy; @@ -1595,18 +1784,16 @@ static void call_with_video_added_2(void) { if (!call_ok) goto end; BC_ASSERT_TRUE(add_video(marie,pauline, TRUE)); - /*just to sleep*/ - linphone_core_terminate_all_calls(pauline->lc); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + + end_call(pauline, marie); end: linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } static void call_with_video_added_random_ports(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); bool_t call_ok; linphone_core_set_audio_port(marie->lc,-1); @@ -1618,10 +1805,7 @@ static void call_with_video_added_random_ports(void) { if (!call_ok) goto end; BC_ASSERT_TRUE(add_video(pauline,marie, TRUE)); - /*just to sleep*/ - linphone_core_terminate_all_calls(pauline->lc); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + end_call(pauline, marie); end: linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); @@ -1629,8 +1813,8 @@ end: static void call_with_several_video_switches(void) { int dummy = 0; - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); bool_t call_ok; BC_ASSERT_TRUE(call_ok=call(pauline,marie)); @@ -1642,10 +1826,8 @@ static void call_with_several_video_switches(void) { BC_ASSERT_TRUE(add_video(pauline,marie, TRUE)); wait_for_until(pauline->lc,marie->lc,&dummy,1,1000); /* Wait for VFU request exchanges to be finished. */ BC_ASSERT_TRUE(remove_video(pauline,marie)); - /*just to sleep*/ - linphone_core_terminate_all_calls(pauline->lc); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + /**/ + end_call(pauline, marie); end: linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); @@ -1653,8 +1835,8 @@ end: static void srtp_call_with_several_video_switches(void) { int dummy = 0; - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); bool_t call_ok; if (linphone_core_media_encryption_supported(marie->lc, LinphoneMediaEncryptionSRTP)) { @@ -1670,10 +1852,8 @@ static void srtp_call_with_several_video_switches(void) { BC_ASSERT_TRUE(add_video(pauline,marie, TRUE)); wait_for_until(pauline->lc,marie->lc,&dummy,1,1000); /* Wait for VFU request exchanges to be finished. */ BC_ASSERT_TRUE(remove_video(pauline,marie)); - /*just to sleep*/ - linphone_core_terminate_all_calls(pauline->lc); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + /**/ + end_call(pauline, marie); } else { ms_warning("Not tested because SRTP is not available."); } @@ -1683,8 +1863,8 @@ end: } static void call_with_declined_video_base(bool_t using_policy) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCall* marie_call; LinphoneCall* pauline_call; LinphoneVideoPolicy marie_policy, pauline_policy; @@ -1706,12 +1886,12 @@ static void call_with_declined_video_base(bool_t using_policy) { linphone_core_set_video_policy(pauline->lc,&pauline_policy); } - caller_test_params.base=linphone_core_create_default_call_parameters(pauline->lc); + caller_test_params.base=linphone_core_create_call_params(pauline->lc, NULL); if (!using_policy) linphone_call_params_enable_video(caller_test_params.base,TRUE); if (!using_policy){ - callee_test_params.base=linphone_core_create_default_call_parameters(marie->lc); + callee_test_params.base=linphone_core_create_call_params(marie->lc, NULL); linphone_call_params_enable_video(callee_test_params.base,FALSE); } @@ -1726,10 +1906,7 @@ static void call_with_declined_video_base(bool_t using_policy) { BC_ASSERT_FALSE(linphone_call_log_video_enabled(linphone_call_get_call_log(marie_call))); BC_ASSERT_FALSE(linphone_call_log_video_enabled(linphone_call_get_call_log(pauline_call))); - - linphone_core_terminate_all_calls(pauline->lc); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + end_call(pauline, marie); end: linphone_core_manager_destroy(marie); @@ -1738,21 +1915,63 @@ end: static void call_with_declined_video(void) { call_with_declined_video_base(FALSE); } -static void call_with_declined_video_using_policy(void) { - call_with_declined_video_base(TRUE); -} -static void video_call_base_2(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}; +static void call_with_declined_video_despite_policy(void) { + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCall* marie_call; LinphoneCall* pauline_call; LinphoneVideoPolicy marie_policy, pauline_policy; + LinphoneCallTestParams caller_test_params = {0}, callee_test_params = {0}; + bool_t call_ok; linphone_core_enable_video_capture(marie->lc, TRUE); linphone_core_enable_video_display(marie->lc, TRUE); linphone_core_enable_video_capture(pauline->lc, TRUE); linphone_core_enable_video_display(pauline->lc, FALSE); + pauline_policy.automatically_initiate=TRUE; + pauline_policy.automatically_accept=TRUE; + marie_policy.automatically_initiate=TRUE; + marie_policy.automatically_accept=TRUE; + + linphone_core_set_video_policy(marie->lc,&marie_policy); + linphone_core_set_video_policy(pauline->lc,&pauline_policy); + + caller_test_params.base=linphone_core_create_call_params(pauline->lc, NULL); + + callee_test_params.base=linphone_core_create_call_params(marie->lc, NULL); + linphone_call_params_enable_video(callee_test_params.base,FALSE); + + BC_ASSERT_TRUE((call_ok=call_with_params2(pauline,marie,&caller_test_params,&callee_test_params,FALSE))); + if (!call_ok) goto end; + + linphone_call_params_destroy(caller_test_params.base); + if (callee_test_params.base) linphone_call_params_destroy(callee_test_params.base); + marie_call=linphone_core_get_current_call(marie->lc); + pauline_call=linphone_core_get_current_call(pauline->lc); + + BC_ASSERT_FALSE(linphone_call_log_video_enabled(linphone_call_get_call_log(marie_call))); + BC_ASSERT_FALSE(linphone_call_log_video_enabled(linphone_call_get_call_log(pauline_call))); + + end_call(pauline, marie); + +end: + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +static void call_with_declined_video_using_policy(void) { + call_with_declined_video_base(TRUE); +} + + +void video_call_base_2(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; + LinphoneVideoPolicy marie_policy, pauline_policy; + if (using_policy) { marie_policy.automatically_initiate=FALSE; marie_policy.automatically_accept=TRUE; @@ -1762,35 +1981,29 @@ static void video_call_base_2(LinphoneCoreManager* pauline,LinphoneCoreManager* 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); - } + + linphone_core_enable_video_display(marie->lc, callee_video_enabled); + linphone_core_enable_video_capture(marie->lc, callee_video_enabled); + + linphone_core_enable_video_display(pauline->lc, caller_video_enabled); + linphone_core_enable_video_capture(pauline->lc, caller_video_enabled); 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", bc_tester_read_dir_prefix); - pauline->lc->user_certificates_path = ms_strdup_printf("%s/certificates/pauline", bc_tester_read_dir_prefix); + marie->lc->user_certificates_path = bc_tester_file("certificates-marie"); + pauline->lc->user_certificates_path = bc_tester_file("certificates-pauline"); + belle_sip_mkdir(marie->lc->user_certificates_path); + belle_sip_mkdir(pauline->lc->user_certificates_path); } linphone_core_set_media_encryption(marie->lc,mode); linphone_core_set_media_encryption(pauline->lc,mode); - caller_test_params.base=linphone_core_create_default_call_parameters(pauline->lc); + caller_test_params.base=linphone_core_create_call_params(pauline->lc, NULL); if (!using_policy) linphone_call_params_enable_video(caller_test_params.base,TRUE); if (!using_policy){ - callee_test_params.base=linphone_core_create_default_call_parameters(marie->lc); + callee_test_params.base=linphone_core_create_call_params(marie->lc, NULL); linphone_call_params_enable_video(callee_test_params.base,TRUE); } @@ -1807,36 +2020,145 @@ static void video_call_base_2(LinphoneCoreManager* pauline,LinphoneCoreManager* BC_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_set_next_video_frame_decoded_callback(marie_call,linphone_call_iframe_decoded_cb,marie->lc); linphone_call_send_vfu_request(marie_call); BC_ASSERT_TRUE( wait_for(marie->lc,pauline->lc,&marie->stat.number_of_IframeDecoded,1)); } else { BC_ASSERT_FALSE(linphone_call_log_video_enabled(linphone_call_get_call_log(marie_call))); BC_ASSERT_FALSE(linphone_call_log_video_enabled(linphone_call_get_call_log(pauline_call))); } - liblinphone_tester_check_rtcp(marie,pauline); - } - } + + + +void video_call_base_3(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; + LinphoneVideoPolicy marie_policy, pauline_policy; + + + if (using_policy) { + marie_policy.automatically_initiate=FALSE; + marie_policy.automatically_accept=TRUE; + pauline_policy.automatically_initiate=TRUE; + pauline_policy.automatically_accept=FALSE; + + linphone_core_set_video_policy(marie->lc,&marie_policy); + linphone_core_set_video_policy(pauline->lc,&pauline_policy); + } + + linphone_core_enable_video_display(marie->lc, callee_video_enabled); + linphone_core_enable_video_capture(marie->lc, callee_video_enabled); + + linphone_core_enable_video_display(pauline->lc, caller_video_enabled); + linphone_core_enable_video_capture(pauline->lc, caller_video_enabled); + + if (mode==LinphoneMediaEncryptionDTLS) { /* for DTLS we must access certificates or at least have a directory to store them */ + marie->lc->user_certificates_path = bc_tester_file("certificates-marie"); + pauline->lc->user_certificates_path = bc_tester_file("certificates-pauline"); + belle_sip_mkdir(marie->lc->user_certificates_path); + belle_sip_mkdir(pauline->lc->user_certificates_path); + } + + linphone_core_set_media_encryption(marie->lc,mode); + linphone_core_set_media_encryption(pauline->lc,mode); + /* Create call params */ + caller_test_params.base=linphone_core_create_call_params(pauline->lc, NULL); + + + if (!using_policy) + linphone_call_params_enable_video(caller_test_params.base,TRUE); + + if (!using_policy){ + callee_test_params.base=linphone_core_create_call_params(marie->lc, NULL); + linphone_call_params_enable_video(callee_test_params.base,TRUE); + + } + + + BC_ASSERT_TRUE(call_with_params2(pauline,marie,&caller_test_params,&callee_test_params,using_policy)); + marie_call=linphone_core_get_current_call(marie->lc); + pauline_call=linphone_core_get_current_call(pauline->lc); + + linphone_call_params_destroy(caller_test_params.base); + if (callee_test_params.base) linphone_call_params_destroy(callee_test_params.base); + + if (marie_call && pauline_call ) { + if (callee_video_enabled && caller_video_enabled) { + BC_ASSERT_TRUE(linphone_call_log_video_enabled(linphone_call_get_call_log(marie_call))); + BC_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_iframe_decoded_cb,marie->lc); + + linphone_call_send_vfu_request(marie_call); + BC_ASSERT_TRUE( wait_for(marie->lc,pauline->lc,&marie->stat.number_of_IframeDecoded,1)); + if (rtp_session_avpf_enabled(marie_call->sessions->rtp_session)){ + + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline_call->videostream->ms_video_stat.counter_rcvd_fir, 1)); + } + else{ + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline_call->videostream->ms_video_stat.counter_rcvd_fir, 0)); + } + ms_message ("video_call_base_3 : [%p] received %d FIR ",&pauline_call ,pauline_call->videostream->ms_video_stat.counter_rcvd_fir); + ms_message ("video_call_base_3 : [%p] stat number of iframe decoded %d ",&marie_call, marie->stat.number_of_IframeDecoded); + linphone_call_set_next_video_frame_decoded_callback(pauline_call,linphone_call_iframe_decoded_cb,pauline->lc); + linphone_call_send_vfu_request(pauline_call); + BC_ASSERT_TRUE( wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_IframeDecoded,1)); + if (rtp_session_avpf_enabled(pauline_call->sessions->rtp_session)){ + + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie_call->videostream->ms_video_stat.counter_rcvd_fir, 1)); + } + else{ + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie_call->videostream->ms_video_stat.counter_rcvd_fir, 0)); + } + ms_message ("video_call_base_3 : [%p] received %d FIR ",&marie_call ,marie_call->videostream->ms_video_stat.counter_rcvd_fir); + ms_message ("video_call_base_3 : [%p] stat number of iframe decoded %d ",&pauline_call, pauline->stat.number_of_IframeDecoded); + } else { + BC_ASSERT_FALSE(linphone_call_log_video_enabled(linphone_call_get_call_log(marie_call))); + BC_ASSERT_FALSE(linphone_call_log_video_enabled(linphone_call_get_call_log(pauline_call))); + } + liblinphone_tester_check_rtcp(marie,pauline); + } +} + 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) { video_call_base_2(pauline,marie,using_policy,mode,callee_video_enabled,caller_video_enabled); - linphone_core_terminate_all_calls(pauline->lc); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + end_call(pauline, marie); } + static void video_call(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); video_call_base(marie,pauline,FALSE,LinphoneMediaEncryptionNone,TRUE,TRUE); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } +static void video_call_base_avpf(LinphoneCoreManager* pauline,LinphoneCoreManager* marie, bool_t using_policy,LinphoneMediaEncryption mode, bool_t callee_video_enabled, bool_t caller_video_enabled) { + linphone_core_set_avpf_mode(pauline->lc,LinphoneAVPFEnabled); + linphone_core_set_avpf_mode(marie->lc,LinphoneAVPFEnabled); + video_call_base_3(pauline,marie,using_policy,mode,callee_video_enabled,caller_video_enabled); + end_call(pauline, marie); +} +static void video_call_avpf(void) { + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + + video_call_base_avpf(marie,pauline,FALSE,LinphoneMediaEncryptionNone,TRUE,TRUE); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + static void video_call_zrtp(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); if (linphone_core_media_encryption_supported(marie->lc,LinphoneMediaEncryptionZRTP)) { video_call_base(marie,pauline,FALSE,LinphoneMediaEncryptionZRTP,TRUE,TRUE); } else @@ -1846,8 +2168,8 @@ static void video_call_zrtp(void) { } static void video_call_dtls(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); if (linphone_core_media_encryption_supported(pauline->lc,LinphoneMediaEncryptionDTLS)) { video_call_base(marie,pauline,FALSE,LinphoneMediaEncryptionDTLS,TRUE,TRUE); } else @@ -1858,32 +2180,32 @@ 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"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); 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"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_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"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); video_call_base(marie,pauline,TRUE,LinphoneMediaEncryptionNone,TRUE,FALSE); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } static void video_call_no_sdp(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); linphone_core_enable_sdp_200_ack(pauline->lc,TRUE); video_call_base(pauline,marie,FALSE,LinphoneMediaEncryptionNone,TRUE,TRUE); linphone_core_manager_destroy(marie); @@ -1891,8 +2213,8 @@ static void video_call_no_sdp(void) { } static void call_with_ice_video_to_novideo(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneVideoPolicy vpol={0}; vpol.automatically_initiate=TRUE; linphone_core_set_video_policy(pauline->lc,&vpol); @@ -1906,8 +2228,9 @@ static void call_with_ice_video_to_novideo(void) { static void _call_with_ice_video(LinphoneVideoPolicy caller_policy, LinphoneVideoPolicy callee_policy, bool_t video_added_by_caller, bool_t video_added_by_callee, bool_t video_removed_by_caller, bool_t video_removed_by_callee) { LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); - LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); bool_t call_ok; + unsigned int nb_media_starts = 1; linphone_core_set_video_policy(pauline->lc, &caller_policy); linphone_core_set_video_policy(marie->lc, &callee_policy); @@ -1926,6 +2249,8 @@ static void _call_with_ice_video(LinphoneVideoPolicy caller_policy, LinphoneVide /* Wait for ICE reINVITEs to complete. */ BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 2) && wait_for(pauline->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 2)); + check_nb_media_starts(pauline, marie, nb_media_starts, nb_media_starts); + nb_media_starts++; if (video_added_by_caller) { BC_ASSERT_TRUE(add_video(marie, pauline, FALSE)); @@ -1934,6 +2259,13 @@ static void _call_with_ice_video(LinphoneVideoPolicy caller_policy, LinphoneVide } if (video_added_by_caller || video_added_by_callee) { BC_ASSERT_TRUE(check_ice(pauline, marie, LinphoneIceStateHostConnection)); + if (linphone_call_params_video_enabled(linphone_call_get_current_params(linphone_core_get_current_call(marie->lc)))){ + /* Wait for ICE reINVITEs to complete if video was really added */ + BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 4) + && wait_for(pauline->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 4)); + check_nb_media_starts(pauline, marie, nb_media_starts, nb_media_starts); + nb_media_starts++; + } } if (video_removed_by_caller) { @@ -1943,8 +2275,12 @@ static void _call_with_ice_video(LinphoneVideoPolicy caller_policy, LinphoneVide } if (video_removed_by_caller || video_removed_by_callee) { BC_ASSERT_TRUE(check_ice(pauline, marie, LinphoneIceStateHostConnection)); + check_nb_media_starts(pauline, marie, nb_media_starts, nb_media_starts); + nb_media_starts++; } + end_call(pauline, marie); + end: linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); @@ -1971,10 +2307,60 @@ static void call_with_ice_video_added_and_refused(void) { _call_with_ice_video(caller_policy, callee_policy, TRUE, FALSE, FALSE, FALSE); } +static void call_with_ice_video_added_with_video_policies_to_false(void) { + LinphoneVideoPolicy vpol = { FALSE, FALSE }; + _call_with_ice_video(vpol, vpol, FALSE, TRUE, FALSE, FALSE); +} + +#if ICE_WAS_WORKING_WITH_REAL_TIME_TEXT /*which is not the case at the moment*/ + +static void call_with_ice_video_and_rtt(void) { + LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + bool_t call_ok; + LinphoneVideoPolicy policy = { TRUE, TRUE }; + LinphoneCallParams *params = NULL; + LinphoneCall *marie_call = NULL; + + linphone_core_set_video_policy(pauline->lc, &policy); + linphone_core_set_video_policy(marie->lc, &policy); + linphone_core_enable_video_capture(marie->lc, TRUE); + linphone_core_enable_video_display(marie->lc, FALSE); + linphone_core_enable_video_capture(pauline->lc, FALSE); + linphone_core_enable_video_display(pauline->lc, TRUE); + linphone_core_set_firewall_policy(marie->lc, LinphonePolicyUseIce); + linphone_core_set_firewall_policy(pauline->lc, LinphonePolicyUseIce); + + linphone_core_set_audio_port(marie->lc, -1); + linphone_core_set_video_port(marie->lc, -1); + linphone_core_set_text_port(marie->lc, -1); + linphone_core_set_audio_port(pauline->lc, -1); + linphone_core_set_video_port(pauline->lc, -1); + linphone_core_set_text_port(pauline->lc, -1); + + params = linphone_core_create_default_call_parameters(pauline->lc); + linphone_call_params_enable_realtime_text(params, TRUE); + BC_ASSERT_TRUE(call_ok = call_with_caller_params(pauline, marie, params)); + if (!call_ok) goto end; + BC_ASSERT_TRUE(check_ice(pauline, marie, LinphoneIceStateHostConnection)); + + marie_call = linphone_core_get_current_call(marie->lc); + BC_ASSERT_TRUE(linphone_call_params_audio_enabled(linphone_call_get_current_params(marie_call))); + BC_ASSERT_TRUE(linphone_call_params_video_enabled(linphone_call_get_current_params(marie_call))); + BC_ASSERT_TRUE(linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(marie_call))); + + end_call(pauline, marie); +end: + linphone_call_params_destroy(params); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +#endif static void video_call_with_early_media_no_matching_audio_codecs(void) { LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); - LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCall *out_call, *pauline_call; LinphoneVideoPolicy vpol={0}; @@ -2007,18 +2393,15 @@ static void video_call_with_early_media_no_matching_audio_codecs(void) { /*audio stream shall not have been requested to start*/ BC_ASSERT_PTR_NULL(pauline_call->audiostream->soundread); - BC_ASSERT_TRUE(linphone_call_params_video_enabled(linphone_call_get_current_params(out_call))==TRUE); - BC_ASSERT_TRUE(linphone_call_params_video_enabled(linphone_call_get_current_params(pauline_call))==TRUE); + BC_ASSERT_TRUE(linphone_call_params_video_enabled(linphone_call_get_current_params(out_call))); + BC_ASSERT_TRUE(linphone_call_params_video_enabled(linphone_call_get_current_params(pauline_call))); linphone_core_accept_call(pauline->lc, pauline_call); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1)); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 1)); - linphone_core_terminate_call(marie->lc, out_call); - - BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallEnd, 1)); - BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1)); + end_call(marie, pauline); end: linphone_call_unref(out_call); @@ -2027,17 +2410,12 @@ end: } static void video_call_limited_bandwidth(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_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); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); - linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } @@ -2045,8 +2423,8 @@ static void video_call_limited_bandwidth(void) { #endif /*VIDEO_ENABLED*/ static void _call_with_media_relay(bool_t random_ports) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); bool_t call_ok; linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL); @@ -2067,10 +2445,7 @@ static void _call_with_media_relay(bool_t random_ports) { BC_ASSERT_TRUE(add_video(pauline,marie, TRUE)); liblinphone_tester_check_rtcp(pauline,marie); #endif - /*just to sleep*/ - linphone_core_terminate_all_calls(pauline->lc); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + end_call(pauline, marie); end: linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); @@ -2085,12 +2460,12 @@ static void call_with_media_relay_random_ports(void) { } static void call_with_privacy(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCall *c1,*c2; LinphoneCallParams *params; LinphoneProxyConfig* pauline_proxy; - params=linphone_core_create_default_call_parameters(pauline->lc); + params=linphone_core_create_call_params(pauline->lc, NULL); linphone_call_params_set_privacy(params,LinphonePrivacyId); BC_ASSERT_TRUE(call_with_caller_params(pauline,marie,params)); @@ -2111,10 +2486,7 @@ static void call_with_privacy(void) { BC_ASSERT_EQUAL(linphone_call_params_get_privacy(linphone_call_get_current_params(c2)),LinphonePrivacyId, int, "%d"); } - /*just to sleep*/ - linphone_core_terminate_all_calls(pauline->lc); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + end_call(pauline, marie); /*test proxy config privacy*/ linphone_core_get_default_proxy(pauline->lc,&pauline_proxy); @@ -2134,10 +2506,8 @@ static void call_with_privacy(void) { BC_ASSERT_EQUAL(linphone_call_params_get_privacy(linphone_call_get_current_params(c2)),LinphonePrivacyId, int, "%d"); } - /*just to sleep*/ - linphone_core_terminate_all_calls(pauline->lc); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,2)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,2)); + + end_call(pauline, marie); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); @@ -2146,11 +2516,11 @@ static void call_with_privacy(void) { /*this ones makes call with privacy without previous registration*/ static void call_with_privacy2(void) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new2( "pauline_rc",FALSE); + LinphoneCoreManager* pauline = linphone_core_manager_new2(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc", FALSE); LinphoneCall *c1,*c2; LinphoneCallParams *params; LinphoneProxyConfig* pauline_proxy; - params=linphone_core_create_default_call_parameters(pauline->lc); + params=linphone_core_create_call_params(pauline->lc, NULL); linphone_call_params_set_privacy(params,LinphonePrivacyId); linphone_core_get_default_proxy(pauline->lc,&pauline_proxy); @@ -2176,10 +2546,7 @@ static void call_with_privacy2(void) { BC_ASSERT_EQUAL(linphone_call_params_get_privacy(linphone_call_get_current_params(c2)),LinphonePrivacyId, int, "%d"); } - /*just to sleep*/ - linphone_core_terminate_all_calls(pauline->lc); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + end_call(pauline, marie); /*test proxy config privacy*/ linphone_proxy_config_set_privacy(pauline_proxy,LinphonePrivacyId); @@ -2196,71 +2563,67 @@ static void call_with_privacy2(void) { BC_ASSERT_FALSE(linphone_address_weak_equal(linphone_call_get_remote_address(c2),pauline->identity)); BC_ASSERT_EQUAL(linphone_call_params_get_privacy(linphone_call_get_current_params(c2)),LinphonePrivacyId, int, "%d"); } - linphone_core_terminate_all_calls(pauline->lc); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,2)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,2)); + end_call(marie, pauline); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } -static void srtp_call() { +static void srtp_call(void) { call_base(LinphoneMediaEncryptionSRTP,FALSE,FALSE,LinphonePolicyNoFirewall,FALSE); } -static void zrtp_call() { +static void zrtp_call(void) { call_base(LinphoneMediaEncryptionZRTP,FALSE,FALSE,LinphonePolicyNoFirewall,FALSE); } -static void zrtp_sas_call() { +static void zrtp_sas_call(void) { call_base_with_configfile(LinphoneMediaEncryptionZRTP,FALSE,FALSE,LinphonePolicyNoFirewall,FALSE, "marie_zrtp_b256_rc", "pauline_zrtp_b256_rc"); - call_base_with_configfile(LinphoneMediaEncryptionZRTP,FALSE,FALSE,LinphonePolicyNoFirewall,FALSE, "marie_zrtp_b256_rc", "pauline_rc"); + call_base_with_configfile(LinphoneMediaEncryptionZRTP,FALSE,FALSE,LinphonePolicyNoFirewall,FALSE, "marie_zrtp_b256_rc", "pauline_tcp_rc"); } -static void zrtp_cipher_call() { +static void zrtp_cipher_call(void) { call_base_with_configfile(LinphoneMediaEncryptionZRTP,FALSE,FALSE,LinphonePolicyNoFirewall,FALSE, "marie_zrtp_srtpsuite_aes256_rc", "pauline_zrtp_srtpsuite_aes256_rc"); call_base_with_configfile(LinphoneMediaEncryptionZRTP,FALSE,FALSE,LinphonePolicyNoFirewall,FALSE, "marie_zrtp_aes256_rc", "pauline_zrtp_aes256_rc"); - call_base_with_configfile(LinphoneMediaEncryptionZRTP,FALSE,FALSE,LinphonePolicyNoFirewall,FALSE, "marie_zrtp_aes256_rc", "pauline_rc"); + call_base_with_configfile(LinphoneMediaEncryptionZRTP,FALSE,FALSE,LinphonePolicyNoFirewall,FALSE, "marie_zrtp_aes256_rc", "pauline_tcp_rc"); } -static void zrtp_video_call() { +static void zrtp_video_call(void) { call_base(LinphoneMediaEncryptionZRTP,TRUE,FALSE,LinphonePolicyNoFirewall,FALSE); } -static void dtls_srtp_call() { +static void dtls_srtp_call(void) { call_base(LinphoneMediaEncryptionDTLS,FALSE,FALSE,LinphonePolicyNoFirewall,FALSE); } -static void dtls_srtp_call_with_media_realy() { +static void dtls_srtp_call_with_media_realy(void) { call_base(LinphoneMediaEncryptionDTLS,FALSE,TRUE,LinphonePolicyNoFirewall,FALSE); } -static void dtls_srtp_ice_call() { +static void dtls_srtp_ice_call(void) { call_base(LinphoneMediaEncryptionDTLS,FALSE,FALSE,LinphonePolicyUseIce,FALSE); } #ifdef VIDEO_ENABLED -static void dtls_srtp_video_call() { +static void dtls_srtp_video_call(void) { call_base(LinphoneMediaEncryptionDTLS,TRUE,FALSE,LinphonePolicyNoFirewall,FALSE); } -static void dtls_srtp_ice_video_call() { +static void dtls_srtp_ice_video_call(void) { call_base(LinphoneMediaEncryptionDTLS,TRUE,FALSE,LinphonePolicyUseIce,FALSE); } -static void dtls_srtp_ice_video_call_with_relay() { +static void dtls_srtp_ice_video_call_with_relay(void) { call_base(LinphoneMediaEncryptionDTLS,TRUE,TRUE,LinphonePolicyUseIce,FALSE); } #endif static void call_with_declined_srtp(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); if (linphone_core_media_encryption_supported(marie->lc,LinphoneMediaEncryptionSRTP)) { linphone_core_set_media_encryption(pauline->lc,LinphoneMediaEncryptionSRTP); BC_ASSERT_TRUE(call(pauline,marie)); - linphone_core_terminate_all_calls(marie->lc); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + end_call(marie, pauline); } else { ms_warning ("not tested because srtp not available"); } @@ -2273,8 +2636,8 @@ static void call_srtp_paused_and_resumed(void) { * This test was made to evidence a bug due to internal usage of current_params while not yet filled by linphone_call_get_current_params(). * As a result it must not use the call() function because it calls linphone_call_get_current_params(). */ - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); const LinphoneCallParams *params; LinphoneCall *pauline_call; @@ -2301,13 +2664,11 @@ static void call_srtp_paused_and_resumed(void) { /*assert that after pause and resume, SRTP is still being used*/ params = linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc)); - BC_ASSERT_TRUE(linphone_call_params_get_media_encryption(params) == LinphoneMediaEncryptionSRTP); + BC_ASSERT_EQUAL(linphone_call_params_get_media_encryption(params) , LinphoneMediaEncryptionSRTP, int, "%d"); params = linphone_call_get_current_params(linphone_core_get_current_call(marie->lc)); - BC_ASSERT_TRUE(linphone_call_params_get_media_encryption(params) == LinphoneMediaEncryptionSRTP); + BC_ASSERT_EQUAL(linphone_call_params_get_media_encryption(params) , LinphoneMediaEncryptionSRTP, int, "%d"); - linphone_core_terminate_all_calls(marie->lc); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + end_call(pauline, marie); end: linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); @@ -2319,63 +2680,63 @@ static void on_eof(LinphonePlayer *player, void *user_data){ } static void call_with_file_player(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphonePlayer *player; - char hellopath[256]; - char *recordpath = create_filepath(bc_tester_writable_dir_prefix, "record-call_with_file_player", "wav"); + char *hellopath = bc_tester_res("sounds/ahbahouaismaisbon.wav"); + char *recordpath = create_filepath(bc_tester_get_writable_dir_prefix(), "record-call_with_file_player", "wav"); bool_t call_ok; + int attempts; + double similar=1; + const double threshold = 0.9; - /*make sure the record file doesn't already exists, otherwise this test will append new samples to it*/ - unlink(recordpath); + /*this test is actually attempted three times in case of failure, because the audio comparison at the end is very sensitive to + * jitter buffer drifts, which sometimes happen if the machine is unable to run the test in good realtime conditions */ + for (attempts=0; attempts<3; attempts++){ + reset_counters(&marie->stat); + reset_counters(&pauline->stat); + /*make sure the record file doesn't already exists, otherwise this test will append new samples to it*/ + unlink(recordpath); + /*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); + linphone_core_set_play_file(marie->lc,NULL); - snprintf(hellopath,sizeof(hellopath), "%s/sounds/ahbahouaismaisbon.wav", bc_tester_read_dir_prefix); + /*callee is recording and plays file*/ + linphone_core_use_files(pauline->lc,TRUE); + linphone_core_set_play_file(pauline->lc,NULL); + linphone_core_set_record_file(pauline->lc,recordpath); - /*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); - linphone_core_set_play_file(marie->lc,NULL); - - /*callee is recording and plays file*/ - linphone_core_use_files(pauline->lc,TRUE); - linphone_core_set_play_file(pauline->lc,NULL); - linphone_core_set_record_file(pauline->lc,recordpath); - - BC_ASSERT_TRUE((call_ok=call(marie,pauline))); - if (!call_ok) goto end; - player=linphone_call_get_player(linphone_core_get_current_call(marie->lc)); - BC_ASSERT_PTR_NOT_NULL(player); - if (player){ - BC_ASSERT_TRUE(linphone_player_open(player,hellopath,on_eof,marie)==0); - BC_ASSERT_TRUE(linphone_player_start(player)==0); - } - - /* This assert should be modified to be at least as long as the WAV file */ - BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&marie->stat.number_of_player_eof,1,10000)); - - /*just to sleep*/ - linphone_core_terminate_all_calls(marie->lc); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); - /*cannot run on iphone simulator because locks main loop beyond permitted time (should run - on another thread) */ -#if !defined(__arm__) && !defined(__arm64__) && !TARGET_IPHONE_SIMULATOR && !defined(ANDROID) - { - double similar; - const int threshold = 90; - BC_ASSERT_EQUAL(ms_audio_diff(hellopath,recordpath,&similar,audio_cmp_max_shift,NULL,NULL), 0, int, "%d"); - BC_ASSERT_GREATER(100*similar, threshold, int, "%d"); - BC_ASSERT_LOWER(100*similar, 100, int, "%d"); - if (threshold < 100*similar && 100*similar < 100) { - remove(recordpath); + BC_ASSERT_TRUE((call_ok=call(marie,pauline))); + if (!call_ok) goto end; + player=linphone_call_get_player(linphone_core_get_current_call(marie->lc)); + BC_ASSERT_PTR_NOT_NULL(player); + if (player){ + BC_ASSERT_EQUAL(linphone_player_open(player,hellopath,on_eof,marie),0, int, "%d"); + BC_ASSERT_EQUAL(linphone_player_start(player),0, int, "%d"); } + /* This assert should be modified to be at least as long as the WAV file */ + BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&marie->stat.number_of_player_eof,1,10000)); + /*wait one second more for transmission to be fully ended (transmission time + jitter buffer)*/ + wait_for_until(pauline->lc,marie->lc,NULL,0,1000); + + end_call(marie, pauline); + /*cannot run on iphone simulator because locks main loop beyond permitted time (should run + on another thread) */ + BC_ASSERT_EQUAL(ms_audio_diff(hellopath,recordpath,&similar,&audio_cmp_params,NULL,NULL), 0, int, "%d"); + if (similar>=threshold) + break; } -#else - remove(recordpath); -#endif + BC_ASSERT_GREATER(similar, threshold, double, "%g"); + BC_ASSERT_LOWER(similar, 1.0, double, "%g"); + if (similar >= threshold && similar <= 1.0) { + remove(recordpath); + } + end: linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); ms_free(recordpath); + ms_free(hellopath); } static bool_t is_format_supported(LinphoneCore *lc, const char *fmt){ @@ -2387,29 +2748,29 @@ static bool_t is_format_supported(LinphoneCore *lc, const char *fmt){ } static void call_with_mkv_file_player(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphonePlayer *player; - char hellomkv[256]; - char hellowav[256]; + char *hellomkv; + char *hellowav; char *recordpath; bool_t call_ok; #if !defined(__arm__) && !defined(__arm64__) && !TARGET_IPHONE_SIMULATOR && !defined(ANDROID) - double similar; + double similar=0.0; const double threshold = 0.9; #define DO_AUDIO_CMP #endif + hellowav = bc_tester_res("sounds/hello8000_mkv_ref.wav"); + hellomkv = bc_tester_res("sounds/hello8000.mkv"); if (!is_format_supported(marie->lc,"mkv")){ ms_warning("Test skipped, no mkv support."); goto end; } - recordpath = create_filepath(bc_tester_writable_dir_prefix, "record-call_with_mkv_file_player", "wav"); + recordpath = create_filepath(bc_tester_get_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", 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); @@ -2427,22 +2788,21 @@ static void call_with_mkv_file_player(void) { int res = linphone_player_open(player,hellomkv,on_eof,marie); if(!ms_filter_codec_supported("opus")) { BC_ASSERT_EQUAL(res, -1, int, "%d"); + end_call(marie, pauline); goto end; } BC_ASSERT_EQUAL(res, 0, int, "%d"); - BC_ASSERT_TRUE(linphone_player_start(player)==0); + BC_ASSERT_EQUAL(linphone_player_start(player),0,int,"%d"); BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&marie->stat.number_of_player_eof,1,12000)); linphone_player_close(player); + /*wait for one second more so that last RTP packets can arrive*/ + wait_for_until(pauline->lc,marie->lc,NULL,0,1000); } - - /*just to sleep*/ - linphone_core_terminate_all_calls(marie->lc); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + end_call(marie, pauline); #ifdef DO_AUDIO_CMP - BC_ASSERT_TRUE(ms_audio_diff(hellowav,recordpath,&similar,audio_cmp_max_shift,NULL,NULL)==0); - BC_ASSERT_TRUE(similar>threshold); - BC_ASSERT_TRUE(similar<=1.0); + BC_ASSERT_EQUAL(ms_audio_diff(hellowav,recordpath,&similar,&audio_cmp_params,NULL,NULL),0,int,"%d"); + BC_ASSERT_GREATER(similar,threshold,double,"%f"); + BC_ASSERT_LOWER(similar,1.0,double,"%f"); if(similar>threshold && similar<=1.0) { remove(recordpath); } @@ -2455,7 +2815,8 @@ static void call_with_mkv_file_player(void) { end: linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); - + ms_free(hellomkv); + ms_free(hellowav); } void call_base_with_configfile(LinphoneMediaEncryption mode, bool_t enable_video,bool_t enable_relay,LinphoneFirewallPolicy policy,bool_t enable_tunnel, const char *marie_rc, const char *pauline_rc) { @@ -2463,6 +2824,9 @@ void call_base_with_configfile(LinphoneMediaEncryption mode, bool_t enable_video LinphoneCoreManager* pauline = linphone_core_manager_new(pauline_rc); bool_t call_ok; + linphone_core_set_video_device(pauline->lc,liblinphone_tester_mire_id); + linphone_core_set_video_device(marie->lc,liblinphone_tester_mire_id); + if (enable_relay) { linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL); linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL); @@ -2470,17 +2834,17 @@ void call_base_with_configfile(LinphoneMediaEncryption mode, bool_t enable_video if (enable_tunnel) { int i; LinphoneTunnelConfig * tunnel_config = linphone_tunnel_config_new(); - linphone_tunnel_config_set_host(tunnel_config,"tunnel.linphone.org"); - linphone_tunnel_config_set_port(tunnel_config,443); + linphone_tunnel_config_set_host(tunnel_config, "tunnel.linphone.org"); + linphone_tunnel_config_set_port(tunnel_config, 443); linphone_tunnel_add_server(linphone_core_get_tunnel(marie->lc),tunnel_config); linphone_tunnel_enable_sip(linphone_core_get_tunnel(marie->lc),FALSE); linphone_tunnel_set_mode(linphone_core_get_tunnel(marie->lc),LinphoneTunnelModeEnable); - for (i=0;i<10;i++) { + for (i=0;i<100;i++) { if (linphone_tunnel_connected(linphone_core_get_tunnel(marie->lc))) { break; } linphone_core_iterate(marie->lc); - ms_usleep(200000); + ms_usleep(20000); } BC_ASSERT_TRUE(linphone_tunnel_connected(linphone_core_get_tunnel(marie->lc))); @@ -2489,8 +2853,10 @@ void call_base_with_configfile(LinphoneMediaEncryption mode, bool_t enable_video 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", bc_tester_read_dir_prefix); - pauline->lc->user_certificates_path = ms_strdup_printf("%s/certificates/pauline", bc_tester_read_dir_prefix); + marie->lc->user_certificates_path = bc_tester_file("certificates-marie"); + pauline->lc->user_certificates_path = bc_tester_file("certificates-pauline"); + belle_sip_mkdir(marie->lc->user_certificates_path); + belle_sip_mkdir(pauline->lc->user_certificates_path); } linphone_core_set_firewall_policy(marie->lc,policy); @@ -2502,10 +2868,20 @@ void call_base_with_configfile(LinphoneMediaEncryption mode, bool_t enable_video && linphone_core_get_media_encryption(pauline->lc) == LinphoneMediaEncryptionZRTP) { /*wait for SAS*/ int i; - for (i=0;i<10;i++) { - if (linphone_call_get_authentication_token(linphone_core_get_current_call(pauline->lc)) + for (i=0;i<100;i++) { + LinphoneCall *pauline_call = linphone_core_get_current_call(pauline->lc); + LinphoneCall *marie_call = linphone_core_get_current_call(marie->lc); + + if (!pauline_call || !marie_call){ + /*if one of the two calls was disapeering, don't crash, but report it*/ + BC_ASSERT_PTR_NOT_NULL(pauline_call); + BC_ASSERT_PTR_NOT_NULL(marie_call); + break; + } + + if (linphone_call_get_authentication_token(pauline_call) && - linphone_call_get_authentication_token(linphone_core_get_current_call(marie->lc))) { + linphone_call_get_authentication_token(marie_call)) { /*check SAS*/ BC_ASSERT_STRING_EQUAL(linphone_call_get_authentication_token(linphone_core_get_current_call(pauline->lc)) ,linphone_call_get_authentication_token(linphone_core_get_current_call(marie->lc))); @@ -2514,41 +2890,30 @@ void call_base_with_configfile(LinphoneMediaEncryption mode, bool_t enable_video } linphone_core_iterate(marie->lc); linphone_core_iterate(pauline->lc); - ms_usleep(200000); + ms_usleep(20000); } - } if (policy == LinphonePolicyUseIce){ - int i=0; BC_ASSERT_TRUE(check_ice(pauline,marie,enable_tunnel?LinphoneIceStateReflexiveConnection:LinphoneIceStateHostConnection)); - for (i=0;i<100;i++) { /*fixme to workaround a crash*/ - ms_usleep(20000); - linphone_core_iterate(marie->lc); - linphone_core_iterate(pauline->lc); - } + wait_for_until(marie->lc, pauline->lc, NULL, 0, 2000);/*fixme to workaround a crash*/ } #ifdef VIDEO_ENABLED if (enable_video) { if (linphone_core_video_supported(marie->lc)) { - add_video(pauline,marie, TRUE); - if (policy == LinphonePolicyUseIce) - BC_ASSERT_TRUE(check_ice(pauline,marie,enable_tunnel?LinphoneIceStateReflexiveConnection:LinphoneIceStateHostConnection)); - + BC_ASSERT_TRUE(add_video(pauline,marie, TRUE)); + if (policy == LinphonePolicyUseIce){ + BC_ASSERT_TRUE(check_ice(pauline, marie, enable_tunnel ? LinphoneIceStateReflexiveConnection + : LinphoneIceStateHostConnection)); + } liblinphone_tester_check_rtcp(marie,pauline); - /*wait for ice to found the direct path*/ - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_IframeDecoded,1)); + } else { ms_warning ("not tested because video not available"); } } #endif - - - /*just to sleep*/ - linphone_core_terminate_all_calls(marie->lc); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + end_call(marie, pauline); } else { ms_warning ("not tested because %s not available", linphone_media_encryption_to_string(mode)); } @@ -2558,7 +2923,7 @@ end: } void call_base(LinphoneMediaEncryption mode, bool_t enable_video,bool_t enable_relay,LinphoneFirewallPolicy policy,bool_t enable_tunnel) { - call_base_with_configfile(mode, enable_video, enable_relay, policy, enable_tunnel, "marie_rc", "pauline_rc"); + call_base_with_configfile(mode, enable_video, enable_relay, policy, enable_tunnel, "marie_rc", "pauline_tcp_rc"); } #ifdef VIDEO_ENABLED @@ -2586,11 +2951,13 @@ static void dtls_ice_call_with_relay(void) { } static void early_media_call(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_early_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_early_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + bool_t call_ok; - BC_ASSERT_TRUE(call(pauline,marie)); + BC_ASSERT_TRUE(call_ok=call(pauline,marie)); + if (!call_ok) goto end; BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallIncomingEarlyMedia,1, int, "%d"); BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallOutgoingEarlyMedia,1, int, "%d"); @@ -2599,20 +2966,15 @@ static void early_media_call(void) { /*added because a bug related to early-media caused the Connected state to be reached two times*/ BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallConnected,1, int, "%d"); - /*just to sleep*/ - linphone_core_terminate_all_calls(marie->lc); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); - - - + end_call(pauline, marie); +end: linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } static void early_media_call_with_ringing(void){ LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new("pauline_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new("pauline_tcp_rc"); MSList* lcs = NULL; LinphoneCall* marie_call; LinphoneCallLog *marie_call_log; @@ -2655,12 +3017,9 @@ static void early_media_call_with_ringing(void){ /*just to have a call duration !=0*/ wait_for_list(lcs,&dummy,1,2000); - linphone_core_terminate_all_calls(pauline->lc); - - BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000)); - BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000)); + end_call(pauline, marie); ended_time=ms_get_cur_time_ms(); - BC_ASSERT_TRUE( labs((linphone_call_log_get_duration(marie_call_log)*1000) - (int64_t)(ended_time - connected_time)) <=1000 ); + BC_ASSERT_LOWER( labs((long)((linphone_call_log_get_duration(marie_call_log)*1000) - (int64_t)(ended_time - connected_time))), 1000, long, "%ld"); ms_list_free(lcs); } @@ -2670,7 +3029,7 @@ static void early_media_call_with_ringing(void){ static void early_media_call_with_update_base(bool_t media_change){ LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new("pauline_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); MSList* lcs = NULL; LinphoneCall *marie_call, *pauline_call; LinphoneCallParams *pauline_params; @@ -2708,6 +3067,7 @@ static void early_media_call_with_update_base(bool_t media_change){ linphone_call_params_set_session_name(pauline_params,UPDATED_SESSION_NAME); linphone_core_update_call(pauline->lc, pauline_call, pauline_params); + linphone_call_params_destroy(pauline_params); BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallEarlyUpdating,1,2000)); BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallEarlyUpdatedByRemote,1,2000)); BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallOutgoingEarlyMedia,1,2000)); @@ -2728,10 +3088,7 @@ static void early_media_call_with_update_base(bool_t media_change){ liblinphone_tester_check_rtcp(marie, pauline); - linphone_core_terminate_all_calls(pauline->lc); - - BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000)); - BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000)); + end_call(pauline, marie); end: @@ -2756,8 +3113,8 @@ static void check_call_state(LinphoneCoreManager* mgr,LinphoneCallState state) { } static void call_established_with_rejected_info(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); int dummy=0; bool_t call_ok=FALSE; @@ -2777,11 +3134,132 @@ static void call_established_with_rejected_info(void) { check_call_state(pauline,LinphoneCallStreamsRunning); check_call_state(marie,LinphoneCallStreamsRunning); + end_call(pauline, marie); + } - /*just to sleep*/ - linphone_core_terminate_all_calls(pauline->lc); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - BC_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 void call_established_with_complex_rejected_operation(void) { + + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + bool_t call_ok=FALSE; + LinphoneCallParams *params; + + BC_ASSERT_TRUE((call_ok=call(pauline,marie))); + if (call_ok){ + + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,1)); + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,1)); + + linphone_core_enable_payload_type(pauline->lc,linphone_core_find_payload_type(pauline->lc,"PCMU",8000,1),FALSE); /*disable PCMU*/ + linphone_core_enable_payload_type(pauline->lc,linphone_core_find_payload_type(pauline->lc,"PCMA",8000,1),TRUE); /*enable PCMA*/ + linphone_core_enable_payload_type(marie->lc,linphone_core_find_payload_type(marie->lc,"PCMU",8000,1),FALSE); /*disable PCMU*/ + linphone_core_enable_payload_type(marie->lc,linphone_core_find_payload_type(marie->lc,"PCMA",8000,1),TRUE); /*enable PCMA*/ + + /*just to authenticate marie*/ + linphone_call_send_info_message(linphone_core_get_current_call(marie->lc),linphone_core_create_info_message(marie->lc)); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_inforeceived,1)); + BC_ASSERT_EQUAL(pauline->stat.number_of_inforeceived,1, int, "%d"); + /*to give time for 200ok to arrive*/ + wait_for_until(marie->lc,pauline->lc,NULL,0,1000); + + + + 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))); + + + linphone_core_update_call( marie->lc + ,linphone_core_get_current_call(marie->lc) + ,linphone_call_get_current_params(linphone_core_get_current_call(marie->lc))); + + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2)); + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,2)); + + BC_ASSERT_EQUAL(linphone_call_get_reason(linphone_core_get_current_call(pauline->lc)),LinphoneReasonTemporarilyUnavailable, int, "%d"); + BC_ASSERT_EQUAL(linphone_call_get_reason(linphone_core_get_current_call(pauline->lc)),LinphoneReasonTemporarilyUnavailable, int, "%d"); + + check_call_state(pauline,LinphoneCallStreamsRunning); + check_call_state(marie,LinphoneCallStreamsRunning); + + 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))); + + + linphone_call_send_info_message(linphone_core_get_current_call(marie->lc),linphone_core_create_info_message(marie->lc)); + + + params=linphone_core_create_call_params(marie->lc,linphone_core_get_current_call(marie->lc)); + sal_enable_pending_trans_checking(marie->lc->sal,FALSE); /*to allow // transactions*/ + linphone_core_enable_payload_type(marie->lc,linphone_core_find_payload_type(marie->lc,"PCMU",8000,1),TRUE); + linphone_core_enable_payload_type(marie->lc,linphone_core_find_payload_type(marie->lc,"PCMA",8000,1),FALSE); + + linphone_core_update_call( marie->lc + ,linphone_core_get_current_call(marie->lc) + ,params); + + linphone_call_params_destroy(params); + + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,3)); + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,3)); + + BC_ASSERT_EQUAL(linphone_call_get_reason(linphone_core_get_current_call(pauline->lc)),LinphoneReasonTemporarilyUnavailable, int, "%d"); + BC_ASSERT_EQUAL(linphone_call_get_reason(linphone_core_get_current_call(pauline->lc)),LinphoneReasonTemporarilyUnavailable, int, "%d"); + + end_call(pauline, marie); + } + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +static void call_established_with_rejected_info_during_reinvite(void) { + + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + bool_t call_ok=FALSE; + + BC_ASSERT_TRUE((call_ok=call(pauline,marie))); + if (call_ok){ + + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,1)); + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,1)); + + linphone_core_enable_payload_type(pauline->lc,linphone_core_find_payload_type(pauline->lc,"PCMU",8000,1),FALSE); /*disable PCMU*/ + linphone_core_enable_payload_type(pauline->lc,linphone_core_find_payload_type(pauline->lc,"PCMA",8000,1),TRUE); /*enable PCMA*/ + linphone_core_enable_payload_type(marie->lc,linphone_core_find_payload_type(marie->lc,"PCMU",8000,1),FALSE); /*disable PCMU*/ + linphone_core_enable_payload_type(marie->lc,linphone_core_find_payload_type(marie->lc,"PCMA",8000,1),TRUE); /*enable PCMA*/ + + /*just to authenticate marie*/ + linphone_call_send_info_message(linphone_core_get_current_call(marie->lc),linphone_core_create_info_message(marie->lc)); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_inforeceived,1)); + BC_ASSERT_EQUAL(pauline->stat.number_of_inforeceived,1, int, "%d"); + /*to give time for 200ok to arrive*/ + wait_for_until(marie->lc,pauline->lc,NULL,0,1000); + + + //sal_enable_pending_trans_checking(marie->lc->sal,FALSE); /*to allow // transactions*/ + + linphone_call_send_info_message(linphone_core_get_current_call(marie->lc),linphone_core_create_info_message(marie->lc)); + + //sal_set_send_error(marie->lc->sal, -1); /*to avoid 491 pending to be sent*/ + + 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))); + + + + wait_for_until(pauline->lc,pauline->lc,NULL,0,2000); /*to avoid 491 pending to be sent to early*/ + + + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2)); + end_call(pauline, marie); } linphone_core_manager_destroy(marie); @@ -2790,8 +3268,8 @@ static void call_established_with_rejected_info(void) { static void call_established_with_rejected_reinvite(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); bool_t call_ok=FALSE; BC_ASSERT_TRUE(call_ok=call(pauline,marie)); @@ -2812,11 +3290,7 @@ static void call_established_with_rejected_reinvite(void) { BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallStreamsRunning,1, int, "%d"); check_call_state(pauline,LinphoneCallStreamsRunning); check_call_state(marie,LinphoneCallStreamsRunning); - - /*just to sleep*/ - linphone_core_terminate_all_calls(pauline->lc); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + end_call(pauline, marie); } linphone_core_manager_destroy(marie); @@ -2824,8 +3298,8 @@ static void call_established_with_rejected_reinvite(void) { } static void call_established_with_rejected_incoming_reinvite(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); bool_t call_ok=FALSE; BC_ASSERT_TRUE((call_ok=call(pauline,marie))); @@ -2851,11 +3325,7 @@ static void call_established_with_rejected_incoming_reinvite(void) { BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallStreamsRunning,1, int, "%d"); check_call_state(pauline,LinphoneCallStreamsRunning); check_call_state(marie,LinphoneCallStreamsRunning); - - /*just to sleep*/ - linphone_core_terminate_all_calls(pauline->lc); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + end_call(pauline, marie); } linphone_core_manager_destroy(marie); @@ -2864,7 +3334,7 @@ static void call_established_with_rejected_incoming_reinvite(void) { static void call_redirect(void){ LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new("pauline_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCoreManager* laure = linphone_core_manager_new("laure_rc"); MSList* lcs = NULL; char *margaux_url = NULL; @@ -2902,10 +3372,7 @@ static void call_redirect(void){ liblinphone_tester_check_rtcp(marie, laure); - linphone_core_terminate_all_calls(laure->lc); - - BC_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallEnd,1,5000)); - BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,5000)); + end_call(laure, marie); } ms_list_free(lcs); @@ -2916,22 +3383,32 @@ 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"); +static void call_established_with_rejected_reinvite_with_error_base(bool_t trans_pending) { + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); bool_t call_ok=TRUE; + int result; BC_ASSERT_TRUE((call_ok=call(pauline,marie))); 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); + if (trans_pending) { + LinphoneInfoMessage * info = linphone_core_create_info_message(pauline->lc); + linphone_call_send_info_message(linphone_core_get_current_call(pauline->lc),info); - linphone_core_update_call( pauline->lc + } else + sal_enable_unconditional_answer(marie->lc->sal,TRUE); + + result = 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))); + if (trans_pending) + BC_ASSERT_NOT_EQUAL(result,0, int, "%d"); + else + BC_ASSERT_EQUAL(result,0,int, "%d"); BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2)); @@ -2941,22 +3418,31 @@ static void call_established_with_rejected_reinvite_with_error(void) { check_call_state(pauline,LinphoneCallStreamsRunning); check_call_state(marie,LinphoneCallStreamsRunning); - /*just to sleep*/ - linphone_core_terminate_all_calls(pauline->lc); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + if (!trans_pending) + sal_enable_unconditional_answer(marie->lc->sal,FALSE); + + end_call(pauline, marie); } linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } +static void call_established_with_rejected_reinvite_with_error(void) { + call_established_with_rejected_reinvite_with_error_base(FALSE); +} + +static void call_established_with_rejected_reinvite_with_trans_pending_error(void) { + call_established_with_rejected_reinvite_with_error_base(TRUE); +} + static void call_rejected_because_wrong_credentials_with_params(const char* user_agent,bool_t enable_auth_req_cb) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneAuthInfo* good_auth_info=linphone_auth_info_clone(linphone_core_find_auth_info(marie->lc,NULL,linphone_address_get_username(marie->identity),NULL)); LinphoneAuthInfo* wrong_auth_info=linphone_auth_info_clone(good_auth_info); bool_t result=FALSE; linphone_auth_info_set_passwd(wrong_auth_info,"passecretdutout"); + linphone_auth_info_set_ha1(wrong_auth_info, NULL); linphone_core_clear_all_auth_info(marie->lc); if (user_agent) { @@ -2988,15 +3474,15 @@ static void call_rejected_because_wrong_credentials_with_params(const char* user linphone_core_manager_destroy(marie); } -static void call_rejected_because_wrong_credentials() { +static void call_rejected_because_wrong_credentials(void) { call_rejected_because_wrong_credentials_with_params(NULL,TRUE); } -static void call_rejected_without_403_because_wrong_credentials() { +static void call_rejected_without_403_because_wrong_credentials(void) { call_rejected_because_wrong_credentials_with_params("tester-no-403",TRUE); } -static void call_rejected_without_403_because_wrong_credentials_no_auth_req_cb() { +static void call_rejected_without_403_because_wrong_credentials_no_auth_req_cb(void) { call_rejected_because_wrong_credentials_with_params("tester-no-403",FALSE); } @@ -3007,7 +3493,7 @@ static void multiple_early_media(void) { LinphoneCoreManager* marie1 = linphone_core_manager_new("marie_early_rc"); LinphoneCoreManager* marie2 = linphone_core_manager_new("marie_early_rc"); MSList *lcs=NULL; - LinphoneCallParams *params=linphone_core_create_default_call_parameters(pauline->lc); + LinphoneCallParams *params=linphone_core_create_call_params(pauline->lc, NULL); LinphoneVideoPolicy pol; LinphoneCall *marie1_call; LinphoneCall *marie2_call; @@ -3053,9 +3539,9 @@ static void multiple_early_media(void) { /*wait a bit that streams are established*/ wait_for_list(lcs,&dummy,1,6000); - BC_ASSERT_TRUE(linphone_call_get_audio_stats(pauline_call)->download_bandwidth>70); - BC_ASSERT_TRUE(linphone_call_get_audio_stats(marie1_call)->download_bandwidth>70); - BC_ASSERT_TRUE(linphone_call_get_audio_stats(marie2_call)->download_bandwidth>70); + BC_ASSERT_GREATER(linphone_core_manager_get_max_audio_down_bw(pauline),70,int,"%i"); + BC_ASSERT_GREATER(linphone_core_manager_get_mean_audio_down_bw(marie1), 70, int, "%i"); + BC_ASSERT_GREATER(linphone_core_manager_get_mean_audio_down_bw(marie2), 70, int, "%i"); linphone_core_accept_call(marie1->lc,linphone_core_get_current_call(marie1->lc)); BC_ASSERT_TRUE(wait_for_list(lcs,&marie1->stat.number_of_LinphoneCallStreamsRunning,1,3000)); @@ -3066,8 +3552,8 @@ static void multiple_early_media(void) { /*wait a bit that streams are established*/ wait_for_list(lcs,&dummy,1,3000); - BC_ASSERT_TRUE(linphone_call_get_audio_stats(pauline_call)->download_bandwidth>71); - BC_ASSERT_TRUE(linphone_call_get_audio_stats(marie1_call)->download_bandwidth>71); + BC_ASSERT_GREATER(linphone_core_manager_get_mean_audio_down_bw(pauline), 71, int, "%i"); + BC_ASSERT_GREATER(linphone_core_manager_get_mean_audio_down_bw(marie1), 71, int, "%i"); /*send an INFO in reverse side to check that dialogs are properly established*/ info=linphone_core_create_info_message(marie1->lc); @@ -3075,9 +3561,7 @@ static void multiple_early_media(void) { BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_inforeceived,1,3000)); } - linphone_core_terminate_all_calls(pauline->lc); - BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,3000)); - BC_ASSERT_TRUE(wait_for_list(lcs,&marie1->stat.number_of_LinphoneCallEnd,1,3000)); + end_call(pauline, marie1); ms_list_free(lcs); linphone_core_manager_destroy(marie1); @@ -3089,50 +3573,62 @@ static void multiple_early_media(void) { void check_media_direction(LinphoneCoreManager* mgr, LinphoneCall *call, MSList* lcs,LinphoneMediaDirection audio_dir, LinphoneMediaDirection video_dir) { BC_ASSERT_PTR_NOT_NULL(call); if (call) { - const LinphoneCallParams *params = linphone_call_get_current_params(call); + const LinphoneCallParams *params; + wait_for_list(lcs,NULL,0,5000); /*on some device, it may take 3 to 4s to get audio from mic*/ + params = linphone_call_get_current_params(call); #ifdef VIDEO_ENABLED - int current_recv_iframe = mgr->stat.number_of_IframeDecoded; - int expected_recv_iframe=0; - int dummy = 0; + if (video_dir != LinphoneMediaDirectionInvalid){ + int current_recv_iframe = mgr->stat.number_of_IframeDecoded; + int expected_recv_iframe=0; - BC_ASSERT_EQUAL(video_dir,linphone_call_params_get_video_direction(params), int, "%d"); - linphone_call_set_next_video_frame_decoded_callback(call,linphone_call_cb,mgr->lc); - linphone_call_send_vfu_request(call); + if (video_dir != LinphoneMediaDirectionInactive){ + BC_ASSERT_TRUE(linphone_call_params_video_enabled(params)); + } + BC_ASSERT_EQUAL(linphone_call_params_get_video_direction(params), video_dir, int, "%d"); + linphone_call_set_next_video_frame_decoded_callback(call,linphone_call_iframe_decoded_cb,mgr->lc); + linphone_call_send_vfu_request(call); - - wait_for_list(lcs,&dummy,1,2000); /*on some device, it may take 3 to 4s to get audio from mic*/ - - switch (video_dir) { - case LinphoneMediaDirectionInactive: - BC_ASSERT_TRUE(linphone_call_get_video_stats(call)->upload_bandwidth<5); - case LinphoneMediaDirectionSendOnly: - expected_recv_iframe = 0; - BC_ASSERT_TRUE(linphone_call_get_video_stats(call)->download_bandwidth<5); - break; - case LinphoneMediaDirectionRecvOnly: - BC_ASSERT_TRUE(linphone_call_get_video_stats(call)->upload_bandwidth<5); - case LinphoneMediaDirectionSendRecv: - expected_recv_iframe = 1; - break; - } - - BC_ASSERT_TRUE(wait_for_list(lcs, &mgr->stat.number_of_IframeDecoded,current_recv_iframe + expected_recv_iframe,3000)); -#endif - BC_ASSERT_EQUAL(audio_dir,linphone_call_params_get_audio_direction(params), int, "%d"); - switch (audio_dir) { + switch (video_dir) { case LinphoneMediaDirectionInactive: - BC_ASSERT_TRUE(linphone_call_get_audio_stats(call)->upload_bandwidth<5); + BC_ASSERT_LOWER((int)linphone_call_get_video_stats(call)->upload_bandwidth, 5, int, "%i"); + break; case LinphoneMediaDirectionSendOnly: - BC_ASSERT_TRUE(linphone_call_get_video_stats(call)->download_bandwidth<5); - if (audio_dir == LinphoneMediaDirectionSendOnly) BC_ASSERT_TRUE(wait_for_list(lcs,&mgr->stat.audio_upload_bandwidth,70,4000)); + expected_recv_iframe = 0; + BC_ASSERT_LOWER((int)linphone_call_get_video_stats(call)->download_bandwidth, 5, int, "%i"); break; case LinphoneMediaDirectionRecvOnly: - BC_ASSERT_TRUE(linphone_call_get_audio_stats(call)->upload_bandwidth<5); + BC_ASSERT_LOWER((int)linphone_call_get_video_stats(call)->upload_bandwidth, 5, int, "%i"); case LinphoneMediaDirectionSendRecv: - BC_ASSERT_TRUE(wait_for_list(lcs,&mgr->stat.audio_download_bandwidth,70,4000)); - if (audio_dir == LinphoneMediaDirectionSendRecv) BC_ASSERT_TRUE(wait_for_list(lcs,&mgr->stat.audio_upload_bandwidth,70,4000)); + expected_recv_iframe = 1; + break; + default: break; } + + BC_ASSERT_TRUE(wait_for_list(lcs, &mgr->stat.number_of_IframeDecoded,current_recv_iframe + expected_recv_iframe,3000)); + } +#endif + if (audio_dir != LinphoneMediaDirectionInvalid){ + BC_ASSERT_EQUAL(linphone_call_params_get_audio_direction(params), audio_dir, int, "%d"); + switch (audio_dir) { + case LinphoneMediaDirectionInactive: + BC_ASSERT_LOWER(linphone_core_manager_get_mean_audio_up_bw(mgr), 5, int, "%i"); + BC_ASSERT_LOWER(linphone_core_manager_get_mean_audio_down_bw(mgr), 5, int, "%i"); + break; + case LinphoneMediaDirectionSendOnly: + BC_ASSERT_GREATER(linphone_core_manager_get_mean_audio_up_bw(mgr), 70, int, "%i"); + break; + case LinphoneMediaDirectionRecvOnly: + BC_ASSERT_LOWER(linphone_core_manager_get_mean_audio_up_bw(mgr), 5, int, "%i"); + break; + case LinphoneMediaDirectionSendRecv: + BC_ASSERT_GREATER(linphone_core_manager_get_mean_audio_down_bw(mgr), 70, int, "%i"); + BC_ASSERT_GREATER(linphone_core_manager_get_mean_audio_up_bw(mgr), 70, int, "%i"); + break; + default: + break; + } + } } } @@ -3147,14 +3643,14 @@ static void accept_call_in_send_only_base(LinphoneCoreManager* pauline, Linphone linphone_core_enable_video(pauline->lc,TRUE,TRUE); linphone_core_set_video_policy(pauline->lc,&pol); - linphone_core_set_video_device(pauline->lc,"Mire: Mire (synthetic moving picture)"); + linphone_core_set_video_device(pauline->lc,liblinphone_tester_mire_id); linphone_core_enable_video(marie->lc,TRUE,TRUE); linphone_core_set_video_policy(marie->lc,&pol); - linphone_core_set_video_device(marie->lc,"Mire: Mire (synthetic moving picture)"); + linphone_core_set_video_device(marie->lc,liblinphone_tester_mire_id); linphone_call_set_next_video_frame_decoded_callback(linphone_core_invite_address(pauline->lc,marie->identity) - ,linphone_call_cb + ,linphone_call_iframe_decoded_cb ,pauline->lc); @@ -3167,7 +3663,7 @@ static void accept_call_in_send_only_base(LinphoneCoreManager* pauline, Linphone } if (call) { - params=linphone_core_create_default_call_parameters(marie->lc); + params=linphone_core_create_call_params(marie->lc, NULL); linphone_call_params_set_audio_direction(params,LinphoneMediaDirectionSendOnly); linphone_call_params_set_video_direction(params,LinphoneMediaDirectionSendOnly); linphone_core_accept_call_with_params(marie->lc,call,params); @@ -3187,19 +3683,14 @@ static void accept_call_in_send_only_base(LinphoneCoreManager* pauline, Linphone } static void accept_call_in_send_base(bool_t caller_has_ice) { - int begin; - int leaked_objects; LinphoneCoreManager *pauline, *marie; MSList *lcs=NULL;; - belle_sip_object_enable_leak_detector(TRUE); - begin=belle_sip_object_get_object_count(); - - pauline = linphone_core_manager_new("pauline_rc"); + marie = linphone_core_manager_new("marie_rc"); + pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); if (caller_has_ice) { linphone_core_set_firewall_policy(pauline->lc,LinphonePolicyUseIce); } - marie = linphone_core_manager_new("marie_rc"); lcs=ms_list_append(lcs,pauline->lc); lcs=ms_list_append(lcs,marie->lc); @@ -3208,16 +3699,9 @@ static void accept_call_in_send_base(bool_t caller_has_ice) { end_call(marie,pauline); - ms_free(lcs); + ms_list_free(lcs); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); - - leaked_objects=belle_sip_object_get_object_count()-begin; - - BC_ASSERT_TRUE(leaked_objects==0); - if (leaked_objects>0){ - belle_sip_object_dump_active_objects(); - } } static void accept_call_in_send_only(void) { @@ -3228,17 +3712,13 @@ static void accept_call_in_send_only_with_ice(void) { accept_call_in_send_base(TRUE); } -void two_accepted_call_in_send_only() { - int begin; - int leaked_objects; +void two_accepted_call_in_send_only(void) { LinphoneCoreManager *pauline, *marie, *laure; MSList *lcs=NULL; - belle_sip_object_enable_leak_detector(TRUE); - begin=belle_sip_object_get_object_count(); - - pauline = linphone_core_manager_new("pauline_rc"); marie = linphone_core_manager_new("marie_rc"); + linphone_core_use_files(marie->lc, TRUE); + pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); laure = linphone_core_manager_new("laure_rc"); lcs=ms_list_append(lcs,pauline->lc); @@ -3247,24 +3727,16 @@ void two_accepted_call_in_send_only() { accept_call_in_send_only_base(pauline,marie,lcs); - reset_counters(&marie->stat); accept_call_in_send_only_base(laure,marie,lcs); - end_call(marie,pauline); - end_call(laure,marie); + end_call(pauline, marie); + end_call(laure, marie); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); linphone_core_manager_destroy(laure); - - leaked_objects=belle_sip_object_get_object_count()-begin; - - BC_ASSERT_TRUE(leaked_objects==0); - if (leaked_objects>0){ - belle_sip_object_dump_active_objects(); - } - + ms_list_free(lcs); } #endif @@ -3272,7 +3744,7 @@ static char *create_filepath(const char *dir, const char *filename, const char * return ms_strdup_printf("%s/%s.%s",dir,filename,ext); } -static void record_call(const char *filename, bool_t enableVideo) { +static void record_call(const char *filename, bool_t enableVideo, const char *video_codec) { LinphoneCoreManager *marie = NULL; LinphoneCoreManager *pauline = NULL; LinphoneCallParams *marieParams = NULL; @@ -3291,17 +3763,18 @@ static void record_call(const char *filename, bool_t enableVideo) { marie = linphone_core_manager_new("marie_h264_rc"); pauline = linphone_core_manager_new("pauline_h264_rc"); - marieParams = linphone_core_create_default_call_parameters(marie->lc); - paulineParams = linphone_core_create_default_call_parameters(pauline->lc); + marieParams = linphone_core_create_call_params(marie->lc, NULL); + paulineParams = linphone_core_create_call_params(pauline->lc, NULL); #ifdef VIDEO_ENABLED + linphone_core_set_video_device(pauline->lc, liblinphone_tester_mire_id); if(enableVideo) { - if((linphone_core_find_payload_type(marie->lc, "H264", -1, -1) != NULL) - && (linphone_core_find_payload_type(pauline->lc, "H264", -1, -1) != NULL)) { + if(linphone_core_find_payload_type(marie->lc, video_codec, -1, -1) + && linphone_core_find_payload_type(pauline->lc, video_codec, -1, -1)) { linphone_call_params_enable_video(marieParams, TRUE); linphone_call_params_enable_video(paulineParams, TRUE); - disable_all_video_codecs_except_one(marie->lc, "H264"); - disable_all_video_codecs_except_one(pauline->lc, "H264"); + disable_all_video_codecs_except_one(marie->lc, video_codec); + disable_all_video_codecs_except_one(pauline->lc, video_codec); } else { ms_warning("call_recording(): the H264 payload has not been found. Only sound will be recorded"); } @@ -3311,7 +3784,7 @@ 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(bc_tester_writable_dir_prefix, filename, format); + filepath = create_filepath(bc_tester_get_writable_dir_prefix(), filename, format); remove(filepath); linphone_call_params_set_record_file(marieParams, filepath); BC_ASSERT_TRUE(call_succeeded = call_with_params(marie, pauline, marieParams, paulineParams)); @@ -3322,11 +3795,13 @@ static void record_call(const char *filename, bool_t enableVideo) { wait_for_until(marie->lc,pauline->lc,&dummy,1,5000); linphone_call_stop_recording(callInst); end_call(marie, pauline); - BC_ASSERT_EQUAL(access(filepath, F_OK), 0, int, "%d"); + BC_ASSERT_EQUAL(ortp_file_exist(filepath), 0, int, "%d"); } remove(filepath); ms_free(filepath); } + linphone_call_params_destroy(paulineParams); + linphone_call_params_destroy(marieParams); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); #if defined(HAVE_OPENH264) && defined(ANDROID) @@ -3335,21 +3810,25 @@ static void record_call(const char *filename, bool_t enableVideo) { } static void audio_call_recording_test(void) { - record_call("recording", FALSE); + record_call("recording", FALSE, NULL); } #ifdef VIDEO_ENABLED -static void video_call_recording_test(void) { - record_call("recording", TRUE); +static void video_call_recording_h264_test(void) { + record_call("recording", TRUE, "H264"); +} + +static void video_call_recording_vp8_test(void) { + record_call("recording", TRUE, "VP8"); } static void video_call_snapshot(void) { LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); - LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_rc"); - LinphoneCallParams *marieParams = linphone_core_create_default_call_parameters(marie->lc); - LinphoneCallParams *paulineParams = linphone_core_create_default_call_parameters(pauline->lc); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + LinphoneCallParams *marieParams = linphone_core_create_call_params(marie->lc, NULL); + LinphoneCallParams *paulineParams = linphone_core_create_call_params(pauline->lc, NULL); LinphoneCall *callInst = NULL; - char *filename = create_filepath(bc_tester_writable_dir_prefix, "snapshot", "jpeg"); + char *filename = create_filepath(bc_tester_get_writable_dir_prefix(), "snapshot", "jpeg"); int dummy = 0; bool_t call_succeeded = FALSE; @@ -3363,12 +3842,19 @@ static void video_call_snapshot(void) { BC_ASSERT_TRUE(call_succeeded = call_with_params(marie, pauline, marieParams, paulineParams)); BC_ASSERT_PTR_NOT_NULL(callInst = linphone_core_get_current_call(marie->lc)); if((call_succeeded == TRUE) && (callInst != NULL)) { - linphone_call_take_video_snapshot(callInst, filename); - wait_for_until(marie->lc, pauline->lc, &dummy, 1, 5000); - BC_ASSERT_EQUAL(access(filename, F_OK), 0, int, "%d"); - remove(filename); + int jpeg_support = linphone_call_take_video_snapshot(callInst, filename); + if (jpeg_support < 0) { + ms_warning("No jpegwriter support!"); + } else { + wait_for_until(marie->lc, pauline->lc, &dummy, 1, 5000); + BC_ASSERT_EQUAL(ortp_file_exist(filename), 0, int, "%d"); + remove(filename); + } + end_call(marie, pauline); } ms_free(filename); + linphone_call_params_unref(marieParams); + linphone_call_params_unref(paulineParams); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } @@ -3376,18 +3862,13 @@ static void video_call_snapshot(void) { #endif static void call_with_in_dialog_update(void) { - int begin; - int leaked_objects; LinphoneCoreManager* marie; LinphoneCoreManager* pauline; LinphoneCallParams *params; bool_t call_ok; - 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"); + pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); BC_ASSERT_TRUE(call_ok=call(pauline,marie)); if (!call_ok) goto end; @@ -3405,27 +3886,16 @@ static void call_with_in_dialog_update(void) { end: linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); - - leaked_objects=belle_sip_object_get_object_count()-begin; - BC_ASSERT_TRUE(leaked_objects==0); - if (leaked_objects>0){ - belle_sip_object_dump_active_objects(); - } } static void call_with_in_dialog_codec_change_base(bool_t no_sdp) { - int begin; - int leaked_objects; int dummy=0; LinphoneCoreManager* marie; LinphoneCoreManager* pauline; LinphoneCallParams *params; bool_t call_ok; - 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"); + pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); BC_ASSERT_TRUE(call_ok=call(pauline,marie)); if (!call_ok) goto end; @@ -3447,19 +3917,13 @@ static void call_with_in_dialog_codec_change_base(bool_t no_sdp) { BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2)); BC_ASSERT_STRING_EQUAL("PCMA",linphone_payload_type_get_mime_type(linphone_call_params_get_used_audio_codec(linphone_call_get_current_params(linphone_core_get_current_call(marie->lc))))); wait_for_until(marie->lc, pauline->lc, &dummy, 1, 5000); - BC_ASSERT_TRUE(linphone_call_get_audio_stats(linphone_core_get_current_call(marie->lc))->download_bandwidth>70); - BC_ASSERT_TRUE(linphone_call_get_audio_stats(linphone_core_get_current_call(pauline->lc))->download_bandwidth>70); + BC_ASSERT_GREATER(linphone_core_manager_get_max_audio_down_bw(marie),70,int,"%i"); + BC_ASSERT_GREATER(linphone_core_manager_get_max_audio_down_bw(pauline),70,int,"%i"); end_call(marie,pauline); end: linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); - - leaked_objects=belle_sip_object_get_object_count()-begin; - BC_ASSERT_TRUE(leaked_objects==0); - if (leaked_objects>0){ - belle_sip_object_dump_active_objects(); - } } static void call_with_in_dialog_codec_change(void) { call_with_in_dialog_codec_change_base(FALSE); @@ -3468,19 +3932,14 @@ static void call_with_in_dialog_codec_change_no_sdp(void) { call_with_in_dialog_codec_change_base(TRUE); } static void call_with_custom_supported_tags(void) { - int begin; - int leaked_objects; LinphoneCoreManager* marie; LinphoneCoreManager* pauline; const LinphoneCallParams *remote_params; const char *recv_supported; bool_t call_ok; - 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"); + pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); linphone_core_add_supported_tag(marie->lc,"pouet-tag"); BC_ASSERT_TRUE(call_ok=call(pauline,marie)); @@ -3490,33 +3949,27 @@ static void call_with_custom_supported_tags(void) { recv_supported=linphone_call_params_get_custom_header(remote_params,"supported"); BC_ASSERT_PTR_NOT_NULL(recv_supported); if (recv_supported){ - BC_ASSERT_TRUE(strstr(recv_supported,"pouet-tag")!=NULL); + BC_ASSERT_PTR_NOT_NULL(strstr(recv_supported,"pouet-tag")); } end_call(marie,pauline); end: linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); - - leaked_objects=belle_sip_object_get_object_count()-begin; - BC_ASSERT_TRUE(leaked_objects==0); - if (leaked_objects>0){ - belle_sip_object_dump_active_objects(); - } } static void call_log_from_taken_from_p_asserted_id(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCall *c1,*c2; LinphoneCallParams *params; - const char* paulie_asserted_id ="\"Paupauche\" "; - LinphoneAddress *paulie_asserted_id_addr = linphone_address_new(paulie_asserted_id); + const char* pauline_asserted_id ="\"Paupauche\" "; + LinphoneAddress *pauline_asserted_id_addr = linphone_address_new(pauline_asserted_id); LpConfig *marie_lp; bool_t call_ok; - params=linphone_core_create_default_call_parameters(pauline->lc); + params=linphone_core_create_call_params(pauline->lc, NULL); - linphone_call_params_add_custom_header(params,"P-Asserted-Identity",paulie_asserted_id); + linphone_call_params_add_custom_header(params,"P-Asserted-Identity",pauline_asserted_id); /*fixme, should be able to add several time the same header linphone_call_params_add_custom_header(params,"P-Asserted-Identity","\"Paupauche\" ");*/ marie_lp = linphone_core_get_config(marie->lc); @@ -3534,21 +3987,17 @@ static void call_log_from_taken_from_p_asserted_id(void) { BC_ASSERT_PTR_NOT_NULL(c2); /*make sure remote identity is hidden*/ - BC_ASSERT_TRUE(linphone_address_weak_equal(linphone_call_get_remote_address(c2),paulie_asserted_id_addr)); - - - /*just to sleep*/ - linphone_core_terminate_all_calls(pauline->lc); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + BC_ASSERT_TRUE(linphone_address_weak_equal(linphone_call_get_remote_address(c2),pauline_asserted_id_addr)); + linphone_address_destroy(pauline_asserted_id_addr); + end_call(pauline, marie); end: linphone_call_params_destroy(params); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } -static void incoming_invite_with_invalid_sdp() { - LinphoneCoreManager* caller = linphone_core_manager_new( "pauline_rc"); +static void incoming_invite_with_invalid_sdp(void) { + LinphoneCoreManager* caller = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneCoreManager* callee = linphone_core_manager_new( "marie_rc"); LinphoneCallTestParams caller_test_params = {0}, callee_test_params = {0}; @@ -3564,8 +4013,8 @@ static void incoming_invite_with_invalid_sdp() { linphone_core_manager_destroy(caller); } -static void outgoing_invite_with_invalid_sdp() { - LinphoneCoreManager* caller = linphone_core_manager_new( "pauline_rc"); +static void outgoing_invite_with_invalid_sdp(void) { + LinphoneCoreManager* caller = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneCoreManager* callee = linphone_core_manager_new( "marie_rc"); LinphoneCallTestParams caller_test_params = {0}, callee_test_params = {0}; @@ -3583,9 +4032,9 @@ static void outgoing_invite_with_invalid_sdp() { linphone_core_manager_destroy(caller); } -static void incoming_reinvite_with_invalid_ack_sdp(){ +static void incoming_reinvite_with_invalid_ack_sdp(void){ #ifdef VIDEO_ENABLED - LinphoneCoreManager* caller = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* caller = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneCoreManager* callee = linphone_core_manager_new( "marie_rc"); LinphoneCall * inc_call; BC_ASSERT_TRUE(call(caller,callee)); @@ -3614,9 +4063,7 @@ static void incoming_reinvite_with_invalid_ack_sdp(){ sal_call_set_sdp_handling(inc_call->op, SalOpSDPNormal); } - linphone_core_terminate_all_calls(caller->lc); - BC_ASSERT_TRUE(wait_for(caller->lc,callee->lc,&caller->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(caller->lc,callee->lc,&callee->stat.number_of_LinphoneCallEnd,1)); + end_call(caller, callee); linphone_core_manager_destroy(callee); linphone_core_manager_destroy(caller); @@ -3625,9 +4072,9 @@ static void incoming_reinvite_with_invalid_ack_sdp(){ #endif } -static void outgoing_reinvite_with_invalid_ack_sdp() { +static void outgoing_reinvite_with_invalid_ack_sdp(void) { #ifdef VIDEO_ENABLED - LinphoneCoreManager* caller = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* caller = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneCoreManager* callee = linphone_core_manager_new( "marie_rc"); LinphoneCall * out_call; BC_ASSERT_TRUE(call(caller,callee)); @@ -3653,9 +4100,7 @@ static void outgoing_reinvite_with_invalid_ack_sdp() { sal_call_set_sdp_handling(out_call->op, SalOpSDPNormal); } - linphone_core_terminate_all_calls(caller->lc); - BC_ASSERT_TRUE(wait_for(caller->lc,callee->lc,&caller->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(caller->lc,callee->lc,&callee->stat.number_of_LinphoneCallEnd,1)); + end_call(caller, callee); linphone_core_manager_destroy(callee); linphone_core_manager_destroy(caller); @@ -3665,25 +4110,22 @@ static void outgoing_reinvite_with_invalid_ack_sdp() { } -static void call_with_paused_no_sdp_on_resume() { - int begin; - int leaked_objects; +static void call_with_paused_no_sdp_on_resume(void) { int dummy=0; LinphoneCoreManager* marie; LinphoneCoreManager* pauline; LinphoneCall* call_marie = NULL; - - belle_sip_object_enable_leak_detector(TRUE); - begin=belle_sip_object_get_object_count(); + bool_t call_ok; marie = linphone_core_manager_new( "marie_rc"); - pauline = linphone_core_manager_new( "pauline_rc"); - BC_ASSERT_TRUE(call(pauline,marie)); + pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + BC_ASSERT_TRUE(call_ok=call(pauline,marie)); + if (!call_ok) goto end; + liblinphone_tester_check_rtcp(marie,pauline); call_marie = linphone_core_get_current_call(marie->lc); BC_ASSERT_PTR_NOT_NULL(call_marie); - if (!call_marie) goto end; ms_message("== Call is OK =="); @@ -3709,23 +4151,18 @@ static void call_with_paused_no_sdp_on_resume() { BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2)); wait_for_until(marie->lc, pauline->lc, &dummy, 1, 3000); - BC_ASSERT_TRUE(linphone_call_get_audio_stats(call_marie)->download_bandwidth>70); + BC_ASSERT_GREATER(linphone_core_manager_get_max_audio_down_bw(marie),70,int,"%i"); BC_ASSERT_TRUE(linphone_call_get_audio_stats(linphone_core_get_current_call(pauline->lc))->download_bandwidth>70); -end: end_call(marie,pauline); +end: + linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); - - leaked_objects=belle_sip_object_get_object_count()-begin; - BC_ASSERT_TRUE(leaked_objects==0); - if (leaked_objects>0){ - belle_sip_object_dump_active_objects(); - } } 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"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); MSList* lcs = NULL; LinphoneCall* marie_call; LinphoneCallParams* params = NULL; @@ -3742,7 +4179,7 @@ static void early_media_without_sdp_in_200_base( bool_t use_video, bool_t use_ic /* Marie calls Pauline, and after the call has rung, transitions to an early_media session */ - params = linphone_core_create_default_call_parameters(marie->lc); + params = linphone_core_create_call_params(marie->lc, NULL); if( use_video){ @@ -3755,6 +4192,7 @@ static void early_media_without_sdp_in_200_base( bool_t use_video, bool_t use_ic } marie_call = linphone_core_invite_address_with_params(marie->lc, pauline->identity, params); + linphone_call_params_destroy(params); marie_call_log = linphone_call_get_call_log(marie_call); BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallIncomingReceived,1,3000)); @@ -3785,45 +4223,36 @@ static void early_media_without_sdp_in_200_base( bool_t use_video, bool_t use_ic /*just to have a call duration !=0*/ wait_for_list(lcs,&dummy,1,2000); - linphone_core_terminate_all_calls(pauline->lc); - - BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000)); - BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000)); + end_call(pauline, marie); ended_time=ms_get_cur_time_ms(); - BC_ASSERT_TRUE( labs((linphone_call_log_get_duration(marie_call_log)*1000) - (int64_t)(ended_time - connected_time)) <=1000 ); - ms_list_free(lcs); + BC_ASSERT_LOWER(labs((long)((linphone_call_log_get_duration(marie_call_log)*1000) - (int64_t)(ended_time - connected_time))), 1000, long, "%ld"); } - + ms_list_free(lcs); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } -static void call_with_early_media_and_no_sdp_in_200_with_video(){ +static void call_with_early_media_and_no_sdp_in_200_with_video(void){ early_media_without_sdp_in_200_base(TRUE, FALSE); } -static void call_with_early_media_and_no_sdp_in_200(){ +static void call_with_early_media_and_no_sdp_in_200(void){ early_media_without_sdp_in_200_base(FALSE, FALSE); } -static void call_with_early_media_ice_and_no_sdp_in_200(){ +static void call_with_early_media_ice_and_no_sdp_in_200(void){ 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",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(); + char *audio_file_with_silence=bc_tester_res("sounds/ahbahouaismaisbon.wav"); + char *recorded_file=bc_tester_file("result.wav"); marie = linphone_core_manager_new( "marie_rc"); - pauline = linphone_core_manager_new( "pauline_rc"); + pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); remove(recorded_file); @@ -3853,18 +4282,13 @@ static void call_with_generic_cn(void) { err=stat(recorded_file,&stbuf); BC_ASSERT_EQUAL(err, 0, int, "%d"); if (err==0){ - BC_ASSERT_TRUE(stbuf.st_size>120000); + BC_ASSERT_GREATER(stbuf.st_size,120000,int, "%d"); } } linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); - leaked_objects=belle_sip_object_get_object_count()-begin; - BC_ASSERT_TRUE(leaked_objects==0); - if (leaked_objects>0){ - belle_sip_object_dump_active_objects(); - } ms_free(audio_file_with_silence); ms_free(recorded_file); } @@ -3893,18 +4317,14 @@ void static call_state_changed_3(LinphoneCore *lc, LinphoneCall *call, LinphoneC static void call_with_transport_change_base(bool_t succesfull_call) { - int begin; - int leaked_objects; LCSipTransports sip_tr; LinphoneCoreManager* marie; LinphoneCoreManager* pauline; LinphoneCoreVTable * v_table; - belle_sip_object_enable_leak_detector(TRUE); - begin=belle_sip_object_get_object_count(); v_table = linphone_core_v_table_new(); v_table->call_state_changed=call_state_changed_2; marie = linphone_core_manager_new("marie_rc"); - pauline = linphone_core_manager_new( "pauline_rc"); + pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_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; @@ -3916,7 +4336,7 @@ static void call_with_transport_change_base(bool_t succesfull_call) { linphone_core_set_sip_transports(marie->lc,&sip_tr); if (succesfull_call) { BC_ASSERT_TRUE(call(marie,pauline)); - linphone_core_terminate_all_calls(marie->lc); + end_call(marie, pauline); } else linphone_core_invite(marie->lc,"nexiste_pas"); @@ -3930,13 +4350,6 @@ static void call_with_transport_change_base(bool_t succesfull_call) { } linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); - - leaked_objects=belle_sip_object_get_object_count()-begin; - BC_ASSERT_TRUE(leaked_objects==0); - if (leaked_objects>0){ - belle_sip_object_dump_active_objects(); - } - } static void call_with_transport_change_after_released(void) { call_with_transport_change_base(TRUE); @@ -3947,22 +4360,17 @@ static void unsucessfull_call_with_transport_change_after_released(void) { #ifdef VIDEO_ENABLED static void video_call_with_re_invite_inactive_followed_by_re_invite_base(LinphoneMediaEncryption mode, bool_t no_sdp) { - int begin; - int leaked_objects; LinphoneCoreManager* marie; LinphoneCoreManager* pauline; LinphoneCallParams *params; const LinphoneCallParams *current_params; MSList *lcs=NULL; - 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"); + pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); linphone_core_set_avpf_mode(pauline->lc,TRUE); - linphone_core_set_video_device(pauline->lc,"Mire: Mire (synthetic moving picture)"); - linphone_core_set_video_device(marie->lc,"Mire: Mire (synthetic moving picture)"); + linphone_core_set_video_device(pauline->lc,liblinphone_tester_mire_id); + linphone_core_set_video_device(marie->lc,liblinphone_tester_mire_id); linphone_core_set_avpf_mode(marie->lc,TRUE); lcs=ms_list_append(lcs,pauline->lc); lcs=ms_list_append(lcs,marie->lc); @@ -3978,7 +4386,7 @@ static void video_call_with_re_invite_inactive_followed_by_re_invite_base(Linpho linphone_call_params_destroy(params); BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallUpdating,1)); - BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallPaused,1)); + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,2)); BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallPausedByRemote,1)); check_media_direction(marie,linphone_core_get_current_call(marie->lc),lcs,LinphoneMediaDirectionInactive,LinphoneMediaDirectionInactive); @@ -3988,19 +4396,13 @@ static void video_call_with_re_invite_inactive_followed_by_re_invite_base(Linpho linphone_core_enable_sdp_200_ack(marie->lc,TRUE); } - /* - currently update call cannot be used in paused state, might not be good. params=linphone_core_create_call_params(marie->lc,linphone_core_get_current_call(marie->lc)); linphone_call_params_set_audio_direction(params,LinphoneMediaDirectionSendRecv); linphone_call_params_set_video_direction(params,LinphoneMediaDirectionSendRecv); linphone_core_update_call(marie->lc,linphone_core_get_current_call(marie->lc),params); linphone_call_params_destroy(params); - */ - linphone_core_resume_call(marie->lc,linphone_core_get_current_call(marie->lc)); - - BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallResuming,1)); - BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,2)); + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,3)); BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2)); check_media_direction(marie,linphone_core_get_current_call(marie->lc),lcs,LinphoneMediaDirectionSendRecv,LinphoneMediaDirectionSendRecv); @@ -4008,44 +4410,41 @@ static void video_call_with_re_invite_inactive_followed_by_re_invite_base(Linpho /*assert that after pause and resume, SRTP is still being used*/ current_params = linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc)); - BC_ASSERT_TRUE(linphone_call_params_get_media_encryption(current_params) == mode); + BC_ASSERT_EQUAL(linphone_call_params_get_media_encryption(current_params) , mode, int, "%d"); current_params = linphone_call_get_current_params(linphone_core_get_current_call(marie->lc)); - BC_ASSERT_TRUE(linphone_call_params_get_media_encryption(current_params) == mode); + BC_ASSERT_EQUAL(linphone_call_params_get_media_encryption(current_params) , mode, int, "%d"); } end_call(marie,pauline); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); - - leaked_objects=belle_sip_object_get_object_count()-begin; - BC_ASSERT_TRUE(leaked_objects==0); - if (leaked_objects>0){ - belle_sip_object_dump_active_objects(); - } } -static void video_call_with_re_invite_inactive_followed_by_re_invite() { +static void video_call_with_re_invite_inactive_followed_by_re_invite(void) { video_call_with_re_invite_inactive_followed_by_re_invite_base(LinphoneMediaEncryptionNone,FALSE); } -static void video_call_with_re_invite_inactive_followed_by_re_invite_no_sdp() { +static void video_call_with_re_invite_inactive_followed_by_re_invite_no_sdp(void) { video_call_with_re_invite_inactive_followed_by_re_invite_base(LinphoneMediaEncryptionNone, TRUE); } -static void srtp_video_call_with_re_invite_inactive_followed_by_re_invite() { + +static void srtp_video_call_with_re_invite_inactive_followed_by_re_invite(void) { if (ms_srtp_supported()) video_call_with_re_invite_inactive_followed_by_re_invite_base(LinphoneMediaEncryptionSRTP,FALSE); else ms_message("srtp_video_call_with_re_invite_inactive_followed_by_re_invite skipped, missing srtp support"); } -static void srtp_video_call_with_re_invite_inactive_followed_by_re_invite_no_sdp() { + +static void srtp_video_call_with_re_invite_inactive_followed_by_re_invite_no_sdp(void) { if (ms_srtp_supported()) video_call_with_re_invite_inactive_followed_by_re_invite_base(LinphoneMediaEncryptionSRTP, TRUE); else ms_message("srtp_video_call_with_re_invite_inactive_followed_by_re_invite_no_sdp skipped, missing srtp support"); } -static void video_call_ice_params() { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + +static void video_call_ice_params(void) { + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); linphone_core_set_firewall_policy(marie->lc,LinphonePolicyUseIce); linphone_core_set_firewall_policy(pauline->lc,LinphonePolicyUseIce); @@ -4053,23 +4452,150 @@ static void video_call_ice_params() { linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } + +static void audio_call_with_video_policy_enabled(void){ + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + LinphoneVideoPolicy vpol; + + + linphone_core_enable_video(marie->lc, TRUE, TRUE); + linphone_core_enable_video(pauline->lc, TRUE, TRUE); + vpol.automatically_accept = vpol.automatically_initiate = TRUE; + linphone_core_set_video_policy(marie->lc, &vpol); + vpol.automatically_accept = vpol.automatically_initiate = FALSE; + linphone_core_set_video_policy(pauline->lc, &vpol); + + linphone_core_set_firewall_policy(marie->lc, LinphonePolicyUseIce); + linphone_core_set_firewall_policy(pauline->lc, LinphonePolicyUseIce); + + linphone_core_invite_address(pauline->lc, marie->identity); + if (!BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallIncomingReceived, 1))) goto end; + linphone_core_accept_call(marie->lc, linphone_core_get_current_call(marie->lc)); + /* + LinphoneCallParams *params; + params = linphone_core_create_call_params(marie->lc, linphone_core_get_current_call(marie->lc)); + linphone_call_params_enable_video(params, TRUE); + linphone_core_accept_call_with_params(marie->lc, linphone_core_get_current_call(marie->lc), params); + linphone_call_params_destroy(params);*/ + + /*wait for call to be established and ICE reINVITEs to be done */ + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 2)); + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 2)); + + linphone_core_pause_call(marie->lc, linphone_core_get_current_call(marie->lc)); + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallPausedByRemote, 1)); + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallPaused, 1)); + + end_call(marie, pauline); +end: + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + + +static void classic_video_entry_phone_setup(void) { + LinphoneCoreManager *callee_mgr = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager *caller_mgr = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + LinphoneCallParams *early_media_params = NULL; + LinphoneCallParams *in_call_params = NULL; + LinphoneCall *callee_call = NULL; + LinphoneVideoPolicy vpol = { TRUE, TRUE }; + MSList *lcs = NULL; + int retry = 0; + bool_t ok; + + lcs = ms_list_append(lcs, caller_mgr->lc); + lcs = ms_list_append(lcs, callee_mgr->lc); + + linphone_core_enable_video(caller_mgr->lc, TRUE, TRUE); + linphone_core_enable_video(callee_mgr->lc, TRUE, TRUE); + linphone_core_set_avpf_mode(caller_mgr->lc, LinphoneAVPFEnabled); + linphone_core_set_avpf_mode(callee_mgr->lc, LinphoneAVPFEnabled); + linphone_core_set_video_policy(caller_mgr->lc, &vpol); + linphone_core_set_video_policy(callee_mgr->lc, &vpol); + linphone_core_set_video_device(caller_mgr->lc, liblinphone_tester_mire_id); + linphone_core_set_video_device(callee_mgr->lc, liblinphone_tester_mire_id); + + BC_ASSERT_PTR_NOT_NULL(linphone_core_invite_address(caller_mgr->lc, callee_mgr->identity)); + + ok = wait_for(callee_mgr->lc, caller_mgr->lc, &callee_mgr->stat.number_of_LinphoneCallIncomingReceived, 1); + BC_ASSERT_TRUE(ok); + if (!ok) goto end; + BC_ASSERT_TRUE(caller_mgr->stat.number_of_LinphoneCallOutgoingProgress == 1); + + callee_call = linphone_core_get_call_by_remote_address2(callee_mgr->lc, caller_mgr->identity); + early_media_params = linphone_core_create_call_params(callee_mgr->lc, callee_call); + linphone_call_params_set_audio_direction(early_media_params, LinphoneMediaDirectionInactive); + linphone_call_params_set_video_direction(early_media_params, LinphoneMediaDirectionRecvOnly); + linphone_core_accept_early_media_with_params(callee_mgr->lc, callee_call, early_media_params); + linphone_call_params_destroy(early_media_params); + + while ((caller_mgr->stat.number_of_LinphoneCallOutgoingEarlyMedia != 1) && (retry++ < 100)) { + linphone_core_iterate(caller_mgr->lc); + linphone_core_iterate(callee_mgr->lc); + ms_usleep(20000); + } + BC_ASSERT_TRUE(caller_mgr->stat.number_of_LinphoneCallOutgoingEarlyMedia == 1); + BC_ASSERT_TRUE(callee_mgr->stat.number_of_LinphoneCallIncomingEarlyMedia == 1); + + check_media_direction(callee_mgr, callee_call, lcs, LinphoneMediaDirectionInactive, LinphoneMediaDirectionRecvOnly); + callee_call = linphone_core_get_call_by_remote_address2(callee_mgr->lc, caller_mgr->identity); + in_call_params = linphone_core_create_call_params(callee_mgr->lc, callee_call); + linphone_call_params_set_audio_direction(in_call_params, LinphoneMediaDirectionSendRecv); + linphone_call_params_set_video_direction(in_call_params, LinphoneMediaDirectionSendRecv); + linphone_core_accept_call_with_params(callee_mgr->lc, callee_call, in_call_params); + linphone_call_params_destroy(in_call_params); + + BC_ASSERT_TRUE(wait_for(callee_mgr->lc, caller_mgr->lc, &callee_mgr->stat.number_of_LinphoneCallConnected, 1)); + BC_ASSERT_TRUE(wait_for(callee_mgr->lc, caller_mgr->lc, &caller_mgr->stat.number_of_LinphoneCallConnected, 1)); + + ok = wait_for_until(callee_mgr->lc, caller_mgr->lc, &caller_mgr->stat.number_of_LinphoneCallStreamsRunning, 1, 2000) + && wait_for_until(callee_mgr->lc, caller_mgr->lc, &callee_mgr->stat.number_of_LinphoneCallStreamsRunning, 1, 2000); + BC_ASSERT_TRUE(ok); + if (!ok) goto end; + check_media_direction(callee_mgr, callee_call, lcs, LinphoneMediaDirectionSendRecv, LinphoneMediaDirectionSendRecv); + + callee_call = linphone_core_get_current_call(callee_mgr->lc); + in_call_params = linphone_core_create_call_params(callee_mgr->lc, callee_call); + linphone_call_params_set_audio_direction(in_call_params, LinphoneMediaDirectionRecvOnly); + linphone_call_params_set_video_direction(in_call_params, LinphoneMediaDirectionSendOnly); + linphone_core_update_call(callee_mgr->lc, callee_call, in_call_params); + linphone_call_params_destroy(in_call_params); + + ok = wait_for_until(callee_mgr->lc, caller_mgr->lc, &caller_mgr->stat.number_of_LinphoneCallStreamsRunning, 2, 2000) + && wait_for_until(callee_mgr->lc, caller_mgr->lc, &callee_mgr->stat.number_of_LinphoneCallStreamsRunning, 2, 2000); + BC_ASSERT_TRUE(ok); + if (!ok) goto end; + callee_call = linphone_core_get_current_call(callee_mgr->lc); + check_media_direction(callee_mgr, callee_call, lcs, LinphoneMediaDirectionRecvOnly, LinphoneMediaDirectionSendOnly); + + end_call(caller_mgr, callee_mgr); + +end: + linphone_core_manager_destroy(callee_mgr); + linphone_core_manager_destroy(caller_mgr); + ms_list_free(lcs); +} #endif -static void simple_stereo_call(const char *codec_name, int clock_rate, int bitrate_override) { - int begin; - int leaked_objects; +#if !defined(__arm__) && !defined(__arm64__) && !TARGET_IPHONE_SIMULATOR && !defined(ANDROID) +static void completion_cb(void *user_data, int percentage){ + fprintf(stdout,"%i %% completed\r",percentage); + fflush(stdout); +} +#endif + +static void simple_stereo_call(const char *codec_name, int clock_rate, int bitrate_override, bool_t stereo) { LinphoneCoreManager* marie; LinphoneCoreManager* pauline; PayloadType *pt; - char *stereo_file = ms_strdup_printf("%s/%s",bc_tester_read_dir_prefix,"sounds/vrroom.wav"); - char *recordpath = create_filepath(bc_tester_writable_dir_prefix, "stereo-record", "wav"); - int dummy=0; - - belle_sip_object_enable_leak_detector(TRUE); - begin=belle_sip_object_get_object_count(); + char *stereo_file = bc_tester_res("sounds/vrroom.wav"); + char *recordpath = bc_tester_file("stereo-record.wav"); + bool_t audio_cmp_failed = FALSE; marie = linphone_core_manager_new( "marie_rc"); - pauline = linphone_core_manager_new( "pauline_rc"); + pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); /*make sure we have opus*/ pt = linphone_core_find_payload_type(marie->lc, codec_name, clock_rate, 2); @@ -4077,10 +4603,10 @@ static void simple_stereo_call(const char *codec_name, int clock_rate, int bitra ms_warning("%s not available, stereo with %s not tested.",codec_name, codec_name); goto end; } - payload_type_set_recv_fmtp(pt, NULL); /*remove fmtp that by default contain stereo=0*/ + if (stereo) payload_type_set_recv_fmtp(pt, "stereo=1;sprop-stereo=1"); if (bitrate_override) linphone_core_set_payload_type_bitrate(marie->lc, pt, bitrate_override); pt = linphone_core_find_payload_type(pauline->lc, codec_name, clock_rate, 2); - payload_type_set_recv_fmtp(pt, NULL); + if (stereo) payload_type_set_recv_fmtp(pt, "stereo=1;sprop-stereo=1"); if (bitrate_override) linphone_core_set_payload_type_bitrate(pauline->lc, pt, bitrate_override); disable_all_audio_codecs_except_one(marie->lc, codec_name, clock_rate); @@ -4091,51 +4617,1037 @@ static void simple_stereo_call(const char *codec_name, int clock_rate, int bitra linphone_core_set_use_files(pauline->lc, TRUE); linphone_core_set_record_file(pauline->lc, recordpath); - remove(recordpath); - /*stereo is supported only without volume control, echo canceller...*/ lp_config_set_string(marie->lc->config,"sound","features","NONE"); lp_config_set_string(pauline->lc->config,"sound","features","NONE"); - if (!BC_ASSERT_TRUE(call(marie,pauline))) goto end; - wait_for_until(marie->lc, pauline->lc, &dummy, 1,6000); - end_call(marie,pauline); + if (!BC_ASSERT_TRUE(call(pauline,marie))) goto end; + wait_for_until(marie->lc, pauline->lc, NULL, 0, 6000); + end_call(pauline, marie); - if (clock_rate!=48000) ms_warning("Similarity checking not implemented for files not having the same sampling rate"); - else{ + + if (clock_rate!=48000) { + ms_warning("Similarity checking not implemented for files not having the same sampling rate"); + }else{ #if !defined(__arm__) && !defined(__arm64__) && !TARGET_IPHONE_SIMULATOR && !defined(ANDROID) double similar; - const double threshold = .7f; - BC_ASSERT_EQUAL(ms_audio_diff(stereo_file,recordpath,&similar,audio_cmp_max_shift,NULL,NULL), 0, int, "%d"); - BC_ASSERT_GREATER(similar, threshold, float, "%f"); - BC_ASSERT_LOWER(similar, 1.f, float, "%f"); + double min_threshold = .75f; /*should be above 0.8 in best conditions*/ + double max_threshold = 1.f; + if (!stereo){ + /*when opus doesn't transmit stereo, the cross correlation is around 0.6 : as expected, it is not as good as in full stereo mode*/ + min_threshold = .4f; + max_threshold = .68f; + } + BC_ASSERT_EQUAL(ms_audio_diff(stereo_file, recordpath,&similar,&audio_cmp_params,completion_cb,NULL), 0, int, "%d"); + BC_ASSERT_GREATER(similar, min_threshold, double, "%g"); + BC_ASSERT_LOWER(similar, max_threshold, double, "%g"); + if (similarmax_threshold){ + audio_cmp_failed = TRUE; + } #endif } - - + if (!audio_cmp_failed) unlink(recordpath); end: linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); ms_free(stereo_file); ms_free(recordpath); - - leaked_objects=belle_sip_object_get_object_count()-begin; - BC_ASSERT_TRUE(leaked_objects==0); - if (leaked_objects>0){ - belle_sip_object_dump_active_objects(); - } } static void simple_stereo_call_l16(void){ - simple_stereo_call("L16", 44100, 0); + simple_stereo_call("L16", 44100, 0, TRUE); } static void simple_stereo_call_opus(void){ - simple_stereo_call("opus", 48000, 150); + simple_stereo_call("opus", 48000, 150, TRUE); } +static void call_with_complex_late_offering(void){ + LinphoneCallParams *params; + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + LinphoneCall* call_pauline; + LinphoneCall* call_marie; + LinphoneVideoPolicy vpol = {TRUE, TRUE}; + bool_t call_ok; + + linphone_core_enable_video(pauline->lc, TRUE, TRUE); + linphone_core_enable_video(marie->lc, TRUE, TRUE); + linphone_core_set_video_policy(pauline->lc, &vpol); + linphone_core_set_video_policy(marie->lc, &vpol); + linphone_core_set_video_device(pauline->lc,liblinphone_tester_mire_id); + linphone_core_set_video_device(marie->lc,liblinphone_tester_mire_id); + + BC_ASSERT_TRUE((call_ok=call(pauline,marie))); + if (!call_ok) goto end; + + call_pauline = linphone_core_get_current_call(pauline->lc); + call_marie = linphone_core_get_current_call(marie->lc); + + //Invite inactive Audio/video (Marie pause Pauline) + ms_message("CONTEXT: Marie sends INVITE with SDP with all streams inactive"); + params=linphone_core_create_call_params(marie->lc,call_marie); + linphone_call_params_set_audio_direction(params,LinphoneMediaDirectionInactive); + linphone_call_params_set_video_direction(params,LinphoneMediaDirectionInactive); + + linphone_core_update_call(marie->lc, call_marie ,params); + linphone_call_params_destroy(params); + + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallUpdating,1)); + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallPausedByRemote,1)); + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,2)); + + //Marie sends INVITE without SDP + ms_message("CONTEXT: Marie sends INVITE without SDP for setting streams in send-only mode"); + linphone_core_enable_sdp_200_ack(marie->lc,TRUE); + params=linphone_core_create_call_params(marie->lc,call_marie); + linphone_call_params_set_audio_direction(params,LinphoneMediaDirectionSendOnly); + linphone_call_params_set_video_direction(params,LinphoneMediaDirectionSendOnly); + linphone_core_update_call(marie->lc, call_marie , params); + linphone_call_params_destroy(params); + + //Pauline OK with sendonly + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallUpdating,2)); + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,3)); + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallPausedByRemote,2)); + + linphone_core_enable_sdp_200_ack(marie->lc,FALSE); + + //Pauline pause Marie + ms_message("CONTEXT: Pauline pauses the call"); + linphone_core_pause_call(pauline->lc,call_pauline); + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallPausing,1)); + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallPaused,1)); + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallPausedByRemote,1)); + + //Pauline resume Marie + ms_message("CONTEXT: Pauline resumes the call"); + wait_for_until(pauline->lc, marie->lc, NULL, 5, 2000); + linphone_core_resume_call(pauline->lc,call_pauline); + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,4)); + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallResuming,1)); + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallPausedByRemote,3)); + + wait_for_until(pauline->lc, marie->lc, NULL, 0, 2000); + + //Marie invite inactive Audio/Video + ms_message("CONTEXT: Marie sends INVITE with SDP with all streams inactive"); + params=linphone_core_create_call_params(marie->lc,call_marie); + linphone_call_params_set_audio_direction(params,LinphoneMediaDirectionInactive); + linphone_call_params_set_video_direction(params,LinphoneMediaDirectionInactive); + + linphone_core_update_call(marie->lc, call_marie,params); + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallUpdating,3)); + linphone_call_params_destroy(params); + + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallPausedByRemote,4)); + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,5)); + + //Marie sends INVITE without SDP + ms_message("CONTEXT: Marie sends INVITE without SDP in the purpose of re-enabling streams in sendrecv mode"); + linphone_core_enable_sdp_200_ack(marie->lc,TRUE); + params=linphone_core_create_call_params(marie->lc,call_marie); + linphone_call_params_set_audio_direction(params,LinphoneMediaDirectionSendRecv); + linphone_call_params_set_video_direction(params,LinphoneMediaDirectionSendRecv); + linphone_core_update_call(marie->lc, call_marie,params); + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallUpdating,3)); + linphone_call_params_destroy(params); + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallUpdatedByRemote,1)); + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2)); + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,5)); + + linphone_core_enable_sdp_200_ack(marie->lc,FALSE); + + end_call(marie,pauline); + +end: + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +static void simple_mono_call_opus(void){ + /*actually a call where input/output is made with stereo but opus transmits everything as mono*/ + simple_stereo_call("opus", 48000, 150, FALSE); +} + +/* because SIP ALG (like in android phones) crash when seing a domain name in SDP, we prefer using SIP/TLS for both participants*/ +static void call_with_fqdn_in_sdp(void) { + bool_t tls_supported = transport_supported(LinphoneTransportTls); + LinphoneCoreManager* marie = linphone_core_manager_new(tls_supported ? "marie_sips_rc" : "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(tls_supported ? "pauline_rc" : "pauline_tcp_rc"); + LpConfig *lp; + bool_t call_ok; + + lp = linphone_core_get_config(marie->lc); + lp_config_set_string(lp,"rtp","bind_address","localhost"); + lp = linphone_core_get_config(pauline->lc); + lp_config_set_string(lp,"rtp","bind_address","localhost"); + + + BC_ASSERT_TRUE(call_ok=call(marie,pauline)); + if (!call_ok) goto end; + liblinphone_tester_check_rtcp(pauline,marie); + +#ifdef VIDEO_ENABLED + BC_ASSERT_TRUE(add_video(pauline,marie, TRUE)); + liblinphone_tester_check_rtcp(pauline,marie); +#endif + end_call(pauline, marie); +end: + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +static void call_with_rtp_io_mode(void) { + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + LinphonePlayer *player; + char *hellopath = bc_tester_res("sounds/ahbahouaismaisbon.wav"); + char *recordpath = create_filepath(bc_tester_get_writable_dir_prefix(), "record-call_with_rtp_io_mode", "wav"); + bool_t call_ok; + int attempts; + double similar=1; + const double threshold = 0.85; + + /*this test is actually attempted three times in case of failure, because the audio comparison at the end is very sensitive to + * jitter buffer drifts, which sometimes happen if the machine is unable to run the test in good realtime conditions */ + for (attempts=0; attempts<3; attempts++){ + /* Make sure that the record file doesn't already exists, otherwise this test will append new samples to it. */ + unlink(recordpath); + reset_counters(&marie->stat); + reset_counters(&pauline->stat); + + /* The 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); + linphone_core_set_play_file(marie->lc, NULL); + linphone_core_set_record_file(marie->lc, recordpath); + linphone_core_use_files(pauline->lc, FALSE); + + /* The callee uses the RTP IO mode with the PCMU codec to send back audio to the caller. */ + disable_all_audio_codecs_except_one(pauline->lc, "pcmu", -1); + lp_config_set_int(pauline->lc->config, "sound", "rtp_io", 1); + lp_config_set_string(pauline->lc->config, "sound", "rtp_local_addr", "127.0.0.1"); + lp_config_set_string(pauline->lc->config, "sound", "rtp_remote_addr", "127.0.0.1"); + lp_config_set_int(pauline->lc->config, "sound", "rtp_local_port", 17076); + lp_config_set_int(pauline->lc->config, "sound", "rtp_remote_port", 17076); + lp_config_set_string(pauline->lc->config, "sound", "rtp_map", "pcmu/8000/1"); + + BC_ASSERT_TRUE((call_ok = call(marie, pauline))); + if (!call_ok) goto end; + player = linphone_call_get_player(linphone_core_get_current_call(marie->lc)); + BC_ASSERT_PTR_NOT_NULL(player); + if (player) { + BC_ASSERT_EQUAL(linphone_player_open(player, hellopath, on_eof, marie) , 0, int, "%d"); + BC_ASSERT_EQUAL(linphone_player_start(player) , 0, int, "%d"); + } + + /* This assert should be modified to be at least as long as the WAV file */ + BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &marie->stat.number_of_player_eof, 1, 10000)); + /*wait for one second more so that last RTP packets can arrive*/ + wait_for_until(pauline->lc,marie->lc,NULL,0,1000); + end_call(pauline,marie); + + BC_ASSERT_EQUAL(ms_audio_diff(hellopath, recordpath, &similar, &audio_cmp_params, NULL, NULL), 0, int, "%d"); + if (similar>=threshold) break; + } + BC_ASSERT_GREATER(similar, threshold, double, "%g"); + BC_ASSERT_LOWER(similar, 1.0, double, "%g"); + if (similar >= threshold && similar <= 1.0) { + remove(recordpath); + } + +end: + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + ms_free(recordpath); + ms_free(hellopath); +} + +static void generic_nack_received(const OrtpEventData *evd, stats *st) { + if (rtcp_is_RTPFB(evd->packet)) { + switch (rtcp_RTPFB_get_type(evd->packet)) { + case RTCP_RTPFB_NACK: + st->number_of_rtcp_generic_nack++; + break; + default: + break; + } + } +} + +static void call_with_generic_nack_rtcp_feedback(void) { + LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager *pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + LpConfig *lp; + LinphoneCall *call_marie; + bool_t call_ok; + OrtpNetworkSimulatorParams params = { 0 }; + + params.enabled = TRUE; + params.loss_rate = 10; + params.consecutive_loss_probability = 0.75; + params.mode = OrtpNetworkSimulatorOutbound; + linphone_core_set_avpf_mode(marie->lc, LinphoneAVPFEnabled); + linphone_core_set_avpf_mode(pauline->lc, LinphoneAVPFEnabled); + lp = linphone_core_get_config(pauline->lc); + lp_config_set_int(lp, "rtp", "rtcp_fb_generic_nack_enabled", 1); + + + BC_ASSERT_TRUE(call_ok = call(pauline, marie)); + if (!call_ok) goto end; + BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1)); + BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 1)); + call_marie = linphone_core_get_current_call(marie->lc); + if (call_marie) { + rtp_session_enable_network_simulation(call_marie->audiostream->ms.sessions.rtp_session, ¶ms); + ortp_ev_dispatcher_connect(media_stream_get_event_dispatcher(&call_marie->audiostream->ms), + ORTP_EVENT_RTCP_PACKET_RECEIVED, RTCP_RTPFB, (OrtpEvDispatcherCb)generic_nack_received, &marie->stat); + } + + BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &marie->stat.number_of_rtcp_generic_nack, 5, 8000)); + end_call(pauline, marie); + +end: + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +// This is a custom structure used for the tests using custom RTP transport modifier. +// It is only used to count the number of sent and received packets +typedef struct _RtpTransportModifierData { + uint64_t packetSentCount; + uint64_t packetReceivedCount; + MSQueue to_send; + MSQueue to_recv; +} RtpTransportModifierData; + +const char *XOR_KEY = "BELLEDONNECOMMUNICATIONS"; + +// Callback called when a packet is on it's way to be sent +// This is where we can do some changes on it, like encrypt it +static int rtptm_on_send(RtpTransportModifier *rtptm, mblk_t *msg) { + RtpTransportModifierData *data = rtptm->data; + rtp_header_t *rtp = (rtp_header_t*)msg->b_rptr; + + if (rtp->version == 0) { + // This is probably a STUN packet, so don't count it (oRTP won't) and don't encrypt it either + return (int)msgdsize(msg); + } + + data->packetSentCount += 1; + ms_queue_put(&data->to_send, dupmsg(msg)); + return 0; // Return 0 to drop the packet, it will be injected later +} + +// Callback called when a packet is on it's way to be received +// This is where we can do some changes on it, like decrypt it +static int rtptm_on_receive(RtpTransportModifier *rtptm, mblk_t *msg) { + RtpTransportModifierData *data = rtptm->data; + rtp_header_t *rtp = (rtp_header_t*)msg->b_rptr; + + if (rtp->version == 0) { + // This is probably a STUN packet, so don't count it (oRTP won't) and don't decrypt it either + return (int)msgdsize(msg); + } + + data->packetReceivedCount += 1; + ms_queue_put(&data->to_recv, dupmsg(msg)); + return 0; // Return 0 to drop the packet, it will be injected later +} + +static void rtptm_on_schedule(RtpTransportModifier *rtptm) { + RtpTransportModifierData *data = rtptm->data; + mblk_t *msg = NULL; + + while ((msg = ms_queue_get(&data->to_send)) != NULL) { + int size = 0; + unsigned char *src; + int i = 0; + + // Mediastream can create a mblk_t with only the RTP header and setting the b_cont pointer to the actual RTP content buffer + // In this scenario, the result of rtp_get_payload will be 0, and we won't be able to do our XOR encryption on the payload + // The call to msgpullup will trigger a memcpy of the header and the payload in the same buffer in the msg mblk_t + msgpullup(msg, -1); + // Now that the mblk_t buffer directly contains the header and the payload, we can get the size of the payload and a pointer to it's start (we don't encrypt the RTP header) + size = rtp_get_payload(msg, &src); + + // Just for fun, let's do a XOR encryption + for (i = 0; i < size; i++) { + src[i] ^= (unsigned char) XOR_KEY[i % strlen(XOR_KEY)]; + } + + meta_rtp_transport_modifier_inject_packet_to_send(rtptm->transport, rtptm, msg, 0); + } + + msg = NULL; + while ((msg = ms_queue_get(&data->to_recv)) != NULL) { + int size = 0; + unsigned char *src; + int i = 0; + + // On the receiving side, there is no need for a msgpullup, the mblk_t contains the header and the payload in the same buffer + // We just ask for the size and a pointer to the payload buffer + size = rtp_get_payload(msg, &src); + + // Since we did a XOR encryption on the send side, we have to do it again to decrypt the payload + for (i = 0; i < size; i++) { + src[i] ^= (unsigned char) XOR_KEY[i % strlen(XOR_KEY)]; + } + + meta_rtp_transport_modifier_inject_packet_to_recv(rtptm->transport, rtptm, msg, 0); + } +} + +// This callback is called when the transport modifier is being destroyed +// It is a good place to free the resources allocated for the transport modifier +static void rtptm_destroy(RtpTransportModifier *rtptm) { + // Do nothing, we'll free it later because we need to access the RtpTransportModifierData structure after the call is ended +} + +// This is the callback called when the state of the call change +void static call_state_changed_4(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *msg) { + int i = 0; + + // To add a custom RTP transport modifier, we have to do it before the call is running, but after the RTP session is created. + if (cstate == LinphoneCallIncomingReceived || cstate == LinphoneCallOutgoingProgress) { + RtpTransport *rtpt = NULL; + RtpTransportModifierData *data = ms_new0(RtpTransportModifierData, 1); + RtpTransportModifier *rtptm = ms_new0(RtpTransportModifier, 1); + ms_queue_init(&data->to_send); + ms_queue_init(&data->to_recv); + rtptm->data = data; + rtptm->t_process_on_send = rtptm_on_send; + rtptm->t_process_on_receive = rtptm_on_receive; + rtptm->t_process_on_schedule = rtptm_on_schedule; + rtptm->t_destroy = rtptm_destroy; + + // Here we iterate on each meta rtp transport available + for (i = 0; i < linphone_call_get_stream_count(call); i++) { + MSFormatType type; + + rtpt = linphone_call_get_meta_rtp_transport(call, i); + + // If we wanted, we also could get the RTCP meta transports like this: + // rtcpt = linphone_call_get_meta_rtcp_transport(call, i); + + // If you want to know which stream meta RTP transport is the current one, you can use + type = linphone_call_get_stream_type(call, i); + // Currently there is only MSAudio and MSVideo types, but this could change later + if (type == MSAudio) { + // And now we append our RTP transport modifier to the current list of modifiers + meta_rtp_transport_append_modifier(rtpt, rtptm); + } else if (type == MSVideo) { + // Because the call of this test is audio only, we don't have to append our modifier to the meta RTP transport from the video stream + } + } + // We save the pointer to our RtpTransportModifier in the call user_data to be able to get to it later + call->user_data = rtptm; + } +} + +static void custom_rtp_modifier(bool_t pauseResumeTest, bool_t recordTest) { + // This will initialize two linphone core using information contained in the marie_rc and pauline_rc files and wait for them to be correctly registered + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + LinphoneCall* call_pauline = NULL; + LinphoneCall* call_marie = NULL; + const rtp_stats_t * stats; + bool_t call_ok; + LinphoneCoreVTable * v_table; + RtpTransportModifier *rtptm_marie = NULL; + RtpTransportModifier *rtptm_pauline = NULL; + RtpTransportModifierData *data_marie = NULL; + RtpTransportModifierData *data_pauline = NULL; + // The following are only used for the record test + LinphonePlayer *player; + char *hellopath = bc_tester_res("sounds/ahbahouaismaisbon.wav"); // File to be played + char *recordpath = create_filepath(bc_tester_get_writable_dir_prefix(), "record-call_with_file_player", "wav"); // File to record the received sound + double similar = 1; // The factor of similarity between the played file and the one recorded + const double threshold = 0.85; // Minimum similarity value to consider the record file equal to the one sent + + // We create a new vtable to listen only to the call state changes, in order to plug our RTP Transport Modifier when the call will be established + v_table = linphone_core_v_table_new(); + v_table->call_state_changed = call_state_changed_4; + linphone_core_add_listener(pauline->lc,v_table); + v_table = linphone_core_v_table_new(); + v_table->call_state_changed = call_state_changed_4; + linphone_core_add_listener(marie->lc,v_table); + + if (recordTest) { // When we do the record test, we need a file player to play the content of a sound file + /*make sure the record file doesn't already exists, otherwise this test will append new samples to it*/ + unlink(recordpath); + + linphone_core_use_files(pauline->lc,TRUE); + linphone_core_set_play_file(pauline->lc,NULL); + linphone_core_set_record_file(pauline->lc,NULL); + + /*callee is recording and plays file*/ + linphone_core_use_files(marie->lc,TRUE); + linphone_core_set_play_file(marie->lc,NULL); + linphone_core_set_record_file(marie->lc,recordpath); + } + + // Now the the call should be running (call state StreamsRunning) + BC_ASSERT_TRUE((call_ok=call(pauline,marie))); + + if (!call_ok) goto end; + + // Ref the call to keep the pointer valid even after the call is release + call_pauline = linphone_call_ref(linphone_core_get_current_call(pauline->lc)); + call_marie = linphone_call_ref(linphone_core_get_current_call(marie->lc)); + + // This is for the pause/resume test, we don't do it in the call record test to be able to check the recorded call matches the file played + if (pauseResumeTest) { + // This only wait for 3 seconds in order to generate traffic for the test + wait_for_until(pauline->lc, marie->lc, NULL, 5, 3000); + + linphone_core_pause_call(pauline->lc,call_pauline); + BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneCallPausing, 1)); + BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneCallPausedByRemote, 1)); + BC_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, 2000); + + linphone_core_resume_call(pauline->lc,call_pauline); + + BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 2)); + BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 2)); + + /*same here: wait a while for a bit of a traffic, we need to receive a RTCP packet*/ + wait_for_until(pauline->lc, marie->lc, NULL, 5, 5000); + + /*since RTCP streams are reset when call is paused/resumed, there should be no loss at all*/ + stats = rtp_session_get_stats(call_pauline->sessions->rtp_session); + BC_ASSERT_EQUAL((int)stats->cum_packet_loss, 0, int, "%d"); + + end_call(pauline, marie); + } else if (recordTest) { + player = linphone_call_get_player(call_pauline); + BC_ASSERT_PTR_NOT_NULL(player); + if (player) { + // This will ask pauline to play the file + BC_ASSERT_EQUAL(linphone_player_open(player, hellopath, on_eof, pauline),0, int, "%d"); + BC_ASSERT_EQUAL(linphone_player_start(player), 0, int, "%d"); + } + /* This assert should be modified to be at least as long as the WAV file */ + BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &pauline->stat.number_of_player_eof, 1, 10000)); + /*wait one second more for transmission to be fully ended (transmission time + jitter buffer)*/ + wait_for_until(pauline->lc, marie->lc, NULL, 0, 1000); + + end_call(pauline, marie); + + // Now we compute a similarity factor between the original file and the one we recorded on the callee side + BC_ASSERT_EQUAL(ms_audio_diff(hellopath, recordpath, &similar, &audio_cmp_params, NULL, NULL), 0, int, "%d"); + + BC_ASSERT_GREATER(similar, threshold, double, "%g"); + BC_ASSERT_LOWER(similar, 1.0, double, "%g"); + if (similar >= threshold && similar <= 1.0) { + // If the similarity value is between perfect (1) and our threshold (0.9), then we delete the file used for the record + remove(recordpath); + } + } else { + // This only wait for 3 seconds in order to generate traffic for the test + wait_for_until(pauline->lc, marie->lc, NULL, 5, 3000); + + // We termine the call and check the stats to see if the call is correctly ended on both sides + end_call(pauline, marie); + } + + // Now we can go fetch our custom structure and check the number of packets sent/received is the same on both sides + rtptm_marie = (RtpTransportModifier *)call_marie->user_data; + rtptm_pauline = (RtpTransportModifier *)call_pauline->user_data; + data_marie = (RtpTransportModifierData *)rtptm_marie->data; + data_pauline = (RtpTransportModifierData *)rtptm_pauline->data; + + BC_ASSERT_PTR_NOT_NULL(data_marie); + BC_ASSERT_PTR_NOT_NULL(data_pauline); + ms_message("Marie sent %i RTP packets and received %i (through our modifier)", (int)data_marie->packetSentCount, (int)data_marie->packetReceivedCount); + ms_message("Pauline sent %i RTP packets and received %i (through our modifier)", (int)data_pauline->packetSentCount, (int)data_pauline->packetReceivedCount); + // There will be a few RTP packets sent on marie's side before the call is ended at pauline's request, so we need the threshold + BC_ASSERT_TRUE(data_marie->packetSentCount - data_pauline->packetReceivedCount < 50); + BC_ASSERT_TRUE(data_marie->packetReceivedCount == data_pauline->packetSentCount); + // At this point, we know each packet that has been processed in the send callback of our RTP modifier also go through the recv callback of the remote. + + // Now we want to ensure that all sent RTP packets actually go through our RTP transport modifier and thus no packet leave without being processed (by any operation we might want to do on it) + { + const LinphoneCallStats *marie_stats = linphone_call_get_audio_stats(call_marie); + const LinphoneCallStats *pauline_stats = linphone_call_get_audio_stats(call_pauline); + rtp_stats_t marie_rtp_stats = linphone_call_stats_get_rtp_stats(marie_stats); + rtp_stats_t pauline_rtp_stats = linphone_call_stats_get_rtp_stats(pauline_stats); + ms_message("Marie sent %i RTP packets and received %i (for real)", (int)marie_rtp_stats.packet_sent, (int)marie_rtp_stats.packet_recv); + ms_message("Pauline sent %i RTP packets and received %i (for real)", (int)pauline_rtp_stats.packet_sent, (int)pauline_rtp_stats.packet_recv); + BC_ASSERT_TRUE(data_marie->packetReceivedCount == marie_rtp_stats.packet_recv); + BC_ASSERT_TRUE(data_marie->packetSentCount == marie_rtp_stats.packet_sent); + // There can be a small difference between the number of packets received in the modifier and the number processed in reception because the processing is asynchronous + BC_ASSERT_TRUE(data_pauline->packetReceivedCount - pauline_rtp_stats.packet_recv < 20); + BC_ASSERT_TRUE(data_pauline->packetSentCount == pauline_rtp_stats.packet_sent); + } + +end: + // Since we didn't free the resources of our RTP transport modifier in the rtptm_destroy callback, we'll do it here + if (data_pauline) { + ms_free(data_pauline); + } + ms_free(rtptm_pauline); + if (data_marie) { + ms_free(data_marie); + } + ms_free(rtptm_marie); + + // Unref the previously ref calls + if (call_marie) { + linphone_call_unref(call_marie); + } + if (call_pauline) { + linphone_call_unref(call_pauline); + } + + // The test is finished, the linphone core are no longer needed, we can safely free them + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + + ms_free(recordpath); + ms_free(hellopath); +} + +static void call_with_custom_rtp_modifier(void) { + custom_rtp_modifier(FALSE, FALSE); +} + +static void call_paused_resumed_with_custom_rtp_modifier(void) { + custom_rtp_modifier(TRUE, FALSE); +} + +static void call_record_with_custom_rtp_modifier(void) { + custom_rtp_modifier(FALSE, TRUE); +} + +static void _call_with_network_switch_in_early_state(bool_t network_loosed_by_caller){ + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + + linphone_core_invite_address(marie->lc, pauline->identity); + if (!BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallIncomingReceived, 1))) goto end; + if (!BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallOutgoingRinging, 1))) goto end; + if (network_loosed_by_caller){ + linphone_core_set_network_reachable(marie->lc, FALSE); + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallError, 1)); + linphone_core_set_network_reachable(marie->lc, TRUE); + linphone_core_terminate_call(pauline->lc, linphone_core_get_current_call(pauline->lc)); + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallEnd, 1)); + }else{ + linphone_core_set_network_reachable(pauline->lc, FALSE); + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallError, 1)); + linphone_core_set_network_reachable(pauline->lc, TRUE); + linphone_core_terminate_call(marie->lc, linphone_core_get_current_call(marie->lc)); + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1)); + } + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallReleased, 1)); + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallReleased, 1)); +end: + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +static void call_with_network_switch_in_early_state_1(void){ + _call_with_network_switch_in_early_state(TRUE); +} + +static void call_with_network_switch_in_early_state_2(void){ + _call_with_network_switch_in_early_state(FALSE); +} + +static void _call_with_network_switch(bool_t use_ice, bool_t with_socket_refresh){ + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + MSList *lcs = NULL; + bool_t call_ok; + + 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_firewall_policy(pauline->lc,LinphonePolicyUseIce); + } + if (with_socket_refresh){ + lp_config_set_int(linphone_core_get_config(marie->lc), "net", "recreate_sockets_when_network_is_up", 1); + lp_config_set_int(linphone_core_get_config(pauline->lc), "net", "recreate_sockets_when_network_is_up", 1); + } + + BC_ASSERT_TRUE((call_ok=call(pauline,marie))); + if (!call_ok) goto end; + + wait_for_until(marie->lc, pauline->lc, NULL, 0, 2000); + if (use_ice) BC_ASSERT_TRUE(check_ice(pauline,marie,LinphoneIceStateHostConnection)); + + /*marie looses the network and reconnects*/ + linphone_core_set_network_reachable(marie->lc, FALSE); + wait_for_until(marie->lc, pauline->lc, NULL, 0, 1000); + + /*marie will reconnect and register*/ + linphone_core_set_network_reachable(marie->lc, TRUE); + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneRegistrationOk, 2)); + + /*pauline shall receive a reINVITE to update the session*/ + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallUpdatedByRemote, 1)); + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 2)); + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 2)); + + /*check that media is back*/ + check_media_direction(marie, linphone_core_get_current_call(marie->lc), lcs, LinphoneMediaDirectionSendRecv, LinphoneMediaDirectionInvalid); + liblinphone_tester_check_rtcp(pauline, marie); + if (use_ice) BC_ASSERT_TRUE(check_ice(pauline,marie,LinphoneIceStateHostConnection)); + + /*pauline shall be able to end the call without problem now*/ + end_call(pauline, marie); +end: + ms_list_free(lcs); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +static void call_with_network_switch(void){ + _call_with_network_switch(FALSE, FALSE); +} + +static void call_with_network_switch_and_ice(void){ + _call_with_network_switch(TRUE, FALSE); +} + +static void call_with_network_switch_and_socket_refresh(void){ + _call_with_network_switch(TRUE, TRUE); +} + +#ifdef CALL_LOGS_STORAGE_ENABLED + +static void call_logs_if_no_db_set(void) { + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* laure = linphone_core_manager_new("laure_call_logs_rc"); + BC_ASSERT_TRUE(ms_list_size(laure->lc->call_logs) == 10); + + BC_ASSERT_TRUE(call(marie, laure)); + wait_for_until(marie->lc, laure->lc, NULL, 5, 1000); + end_call(marie, laure); + + BC_ASSERT_TRUE(ms_list_size(laure->lc->call_logs) == 11); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(laure); +} + +static void call_logs_migrate(void) { + LinphoneCoreManager* laure = linphone_core_manager_new("laure_call_logs_rc"); + char *logs_db = create_filepath(bc_tester_get_writable_dir_prefix(), "call_logs", "db"); + int i = 0; + int incoming_count = 0, outgoing_count = 0, missed_count = 0, aborted_count = 0, decline_count = 0, video_enabled_count = 0; + + unlink(logs_db); + BC_ASSERT_TRUE(ms_list_size(laure->lc->call_logs) == 10); + + linphone_core_set_call_logs_database_path(laure->lc, logs_db); + BC_ASSERT_TRUE(linphone_core_get_call_history_size(laure->lc) == 10); + + for (; i < ms_list_size(laure->lc->call_logs); i++) { + LinphoneCallLog *log = ms_list_nth_data(laure->lc->call_logs, i); + LinphoneCallStatus state = linphone_call_log_get_status(log); + LinphoneCallDir direction = linphone_call_log_get_dir(log); + + if (state == LinphoneCallAborted) { + aborted_count += 1; + } else if (state == LinphoneCallMissed) { + missed_count += 1; + } else if (state == LinphoneCallDeclined) { + decline_count += 1; + } + + if (direction == LinphoneCallOutgoing) { + outgoing_count += 1; + } else { + incoming_count += 1; + } + + if (linphone_call_log_video_enabled(log)) { + video_enabled_count += 1; + } + } + BC_ASSERT_TRUE(incoming_count == 5); + BC_ASSERT_TRUE(outgoing_count == 5); + BC_ASSERT_TRUE(missed_count == 1); + BC_ASSERT_TRUE(aborted_count == 3); + BC_ASSERT_TRUE(decline_count == 2); + BC_ASSERT_TRUE(video_enabled_count == 3); + + { + LinphoneCallLog *log = linphone_core_get_last_outgoing_call_log(laure->lc); + BC_ASSERT_PTR_NOT_NULL(log); + if (log) { + BC_ASSERT_EQUAL((int)log->start_date_time, 1441738272, int, "%d"); + linphone_call_log_unref(log); + log = NULL; + } + } + + laure->lc->call_logs = ms_list_free_with_data(laure->lc->call_logs, (void (*)(void*))linphone_call_log_unref); + call_logs_read_from_config_file(laure->lc); + BC_ASSERT_TRUE(ms_list_size(laure->lc->call_logs) == 0); + + unlink(logs_db); + ms_free(logs_db); + linphone_core_manager_destroy(laure); +} + +static void call_logs_sqlite_storage(void) { + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + char *logs_db = create_filepath(bc_tester_get_writable_dir_prefix(), "call_logs", "db"); + MSList *logs = NULL; + LinphoneCallLog *call_log = NULL; + LinphoneAddress *laure = NULL; + time_t start_time = time(NULL); + unlink(logs_db); + + linphone_core_set_call_logs_database_path(marie->lc, logs_db); + BC_ASSERT_TRUE(linphone_core_get_call_history_size(marie->lc) == 0); + + BC_ASSERT_TRUE(call(marie, pauline)); + wait_for_until(marie->lc, pauline->lc, NULL, 5, 500); + call_log = linphone_call_get_call_log(linphone_core_get_current_call(marie->lc)); + linphone_call_log_set_user_data(call_log, &start_time); + linphone_call_log_set_ref_key(call_log, "ref_key"); + end_call(marie, pauline); + BC_ASSERT_TRUE(linphone_core_get_call_history_size(marie->lc) == 1); + + logs = linphone_core_get_call_history_for_address(marie->lc, linphone_proxy_config_get_identity_address(linphone_core_get_default_proxy_config(pauline->lc))); + BC_ASSERT_TRUE(ms_list_size(logs) == 1); + ms_list_free_with_data(logs, (void (*)(void*))linphone_call_log_unref); + + laure = linphone_address_new("\"Laure\" "); + logs = linphone_core_get_call_history_for_address(marie->lc, laure); + BC_ASSERT_TRUE(ms_list_size(logs) == 0); + linphone_address_destroy(laure); + + logs = linphone_core_get_call_history_for_address(marie->lc, linphone_proxy_config_get_identity_address(linphone_core_get_default_proxy_config(pauline->lc))); + if (BC_ASSERT_TRUE(ms_list_size(logs) == 1)) { + const char *call_id; + const char *ref_key = linphone_call_log_get_ref_key(call_log); + call_log = logs->data; + BC_ASSERT_EQUAL(linphone_call_log_get_dir(call_log), LinphoneCallOutgoing, int, "%d"); + BC_ASSERT_LOWER(linphone_call_log_get_duration(call_log), 2, float, "%.1f"); + BC_ASSERT_TRUE(linphone_address_equal( + linphone_call_log_get_from_address(call_log), + linphone_proxy_config_get_identity_address(linphone_core_get_default_proxy_config(marie->lc)))); + BC_ASSERT_TRUE(linphone_address_equal( + linphone_call_log_get_to_address(call_log), + linphone_proxy_config_get_identity_address(linphone_core_get_default_proxy_config(pauline->lc)))); + BC_ASSERT_PTR_NOT_NULL(linphone_call_log_get_local_stats(call_log)); + BC_ASSERT_GREATER(linphone_call_log_get_quality(call_log), -1, int, "%d"); + BC_ASSERT_PTR_NOT_NULL(ref_key); + if (ref_key) { + BC_ASSERT_STRING_EQUAL(ref_key, "ref_key"); + } + BC_ASSERT_PTR_EQUAL(linphone_call_log_get_user_data(call_log), &start_time); + + call_id = linphone_call_log_get_call_id(call_log); + BC_ASSERT_PTR_NOT_NULL(call_id); + BC_ASSERT_PTR_NOT_NULL(linphone_core_find_call_log_from_call_id(marie->lc, call_id)); + + BC_ASSERT_TRUE(linphone_address_equal( + linphone_call_log_get_remote_address(call_log), + linphone_proxy_config_get_identity_address(linphone_core_get_default_proxy_config(pauline->lc)))); + BC_ASSERT_PTR_NOT_NULL(linphone_call_log_get_remote_stats(call_log)); + BC_ASSERT_GREATER(linphone_call_log_get_start_date(call_log), start_time, int, "%d"); + BC_ASSERT_EQUAL(linphone_call_log_get_status(call_log), LinphoneCallSuccess, int, "%d"); + } + + linphone_core_delete_call_log(marie->lc, (LinphoneCallLog *)ms_list_nth_data(logs, 0)); + ms_list_free_with_data(logs, (void (*)(void*))linphone_call_log_unref); + BC_ASSERT_TRUE(linphone_core_get_call_history_size(marie->lc) == 0); + + reset_counters(&marie->stat); + reset_counters(&pauline->stat); + BC_ASSERT_TRUE(call(marie, pauline)); + end_call(marie, pauline); + + reset_counters(&marie->stat); + reset_counters(&pauline->stat); + BC_ASSERT_TRUE(call(marie, pauline)); + end_call(marie, pauline); + BC_ASSERT_TRUE(linphone_core_get_call_history_size(marie->lc) == 2); + + linphone_core_delete_call_history(marie->lc); + BC_ASSERT_TRUE(linphone_core_get_call_history_size(marie->lc) == 0); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + unlink(logs_db); + ms_free(logs_db); +} + +#endif + + +static void call_with_http_proxy(void) { + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new("pauline_rc"); + bool_t call_ok; + LinphoneCall *marie_call; + LinphoneAddress *contact_addr; + struct addrinfo *res=NULL; + struct addrinfo hints = {0}; + char ip[NI_MAXHOST]; + int err; + + if (!transport_supported(LinphoneTransportTls)) { + ms_message("Test skipped because no tls support"); + goto end; + } + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + + err = getaddrinfo("sip.linphone.org","8888", &hints, &res); + if (err !=0){ + ms_error("call_with_http_proxy(): getaddrinfo() error: %s", gai_strerror(err)); + } + BC_ASSERT_PTR_NOT_NULL(res); + if (!res) goto end; + + BC_ASSERT_EQUAL(err=getnameinfo(res->ai_addr, (socklen_t)res->ai_addrlen, ip, sizeof(ip)-1, NULL, 0, NI_NUMERICHOST), 0, int, "%i"); + if (err != 0){ + ms_error("call_with_http_proxy(): getnameinfo() error: %s", gai_strerror(err)); + goto end; + } + + freeaddrinfo(res); + + linphone_core_set_http_proxy_host(pauline->lc,"sip.linphone.org"); + linphone_core_set_network_reachable(pauline->lc, FALSE); /*to make sure channel is restarted*/ + linphone_core_set_network_reachable(pauline->lc, TRUE); + + BC_ASSERT_TRUE((call_ok=call(pauline,marie))); + if (!call_ok) goto end; + + marie_call = linphone_core_get_current_call(marie->lc); + contact_addr = linphone_address_new(linphone_call_get_remote_contact(marie_call)); + BC_ASSERT_STRING_EQUAL(linphone_address_get_domain(contact_addr),ip); + linphone_address_destroy(contact_addr); + end_call(marie, pauline); +end: + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +static void _call_with_rtcp_mux(bool_t caller_rtcp_mux, bool_t callee_rtcp_mux, bool_t with_ice,bool_t with_ice_reinvite){ + LinphoneCoreManager * marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager *pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + const LinphoneCallParams *params; + MSList *lcs = NULL; + + lcs = ms_list_append(lcs, marie->lc); + lcs = ms_list_append(lcs, pauline->lc); + + if (caller_rtcp_mux){ + lp_config_set_int(linphone_core_get_config(marie->lc), "rtp", "rtcp_mux", 1); + } + if (callee_rtcp_mux){ + lp_config_set_int(linphone_core_get_config(pauline->lc), "rtp", "rtcp_mux", 1); + } + if (with_ice){ + linphone_core_set_user_agent(pauline->lc, "Natted Linphone", NULL); + linphone_core_set_user_agent(marie->lc, "Natted Linphone", NULL); + linphone_core_set_firewall_policy(marie->lc, LinphonePolicyUseIce); + linphone_core_set_firewall_policy(pauline->lc, LinphonePolicyUseIce); + } + if (!with_ice_reinvite) { + lp_config_set_int(linphone_core_get_config(pauline->lc), "sip", "update_call_when_ice_completed", 0); + lp_config_set_int(linphone_core_get_config(marie->lc), "sip", "update_call_when_ice_completed", 0); + } + + if (!BC_ASSERT_TRUE(call(marie,pauline))) goto end; + + params = linphone_call_get_remote_params(linphone_core_get_current_call(pauline->lc)); + BC_ASSERT_TRUE(caller_rtcp_mux == (linphone_call_params_get_custom_sdp_media_attribute(params, LinphoneStreamTypeAudio, "rtcp-mux") != NULL)); + if (caller_rtcp_mux){ + params = linphone_call_get_remote_params(linphone_core_get_current_call(marie->lc)); + BC_ASSERT_TRUE(callee_rtcp_mux == (linphone_call_params_get_custom_sdp_media_attribute(params, LinphoneStreamTypeAudio, "rtcp-mux") != NULL)); + } + + if (with_ice){ + check_ice(marie, pauline, LinphoneIceStateHostConnection); + } + liblinphone_tester_check_rtcp(marie,pauline); + + if (caller_rtcp_mux && callee_rtcp_mux){ + BC_ASSERT_EQUAL(marie->stat.number_of_rtcp_received_via_mux, marie->stat.number_of_rtcp_received, int, "%i"); + BC_ASSERT_GREATER(marie->stat.number_of_rtcp_received, 0, int, "%i"); + BC_ASSERT_EQUAL(pauline->stat.number_of_rtcp_received_via_mux, pauline->stat.number_of_rtcp_received, int, "%i"); + BC_ASSERT_GREATER(pauline->stat.number_of_rtcp_received, 0, int, "%i"); + }else{ + BC_ASSERT_TRUE(marie->stat.number_of_rtcp_received_via_mux == 0); + BC_ASSERT_TRUE(pauline->stat.number_of_rtcp_received_via_mux == 0); + } + + check_media_direction(pauline, linphone_core_get_current_call(pauline->lc), lcs, LinphoneMediaDirectionSendRecv, LinphoneMediaDirectionInvalid); + end_call(marie,pauline); + +end: + ms_list_free(lcs); + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(marie); +} + +static void call_with_rtcp_mux(void){ + _call_with_rtcp_mux(TRUE, TRUE, FALSE,TRUE); +} + +static void call_with_rtcp_mux_not_accepted(void){ + _call_with_rtcp_mux(TRUE, FALSE, FALSE,TRUE); +} + +static void call_with_ice_and_rtcp_mux(void){ + _call_with_rtcp_mux(TRUE, TRUE, TRUE,TRUE); +} + +static void call_with_ice_and_rtcp_mux_without_reinvite(void){ + _call_with_rtcp_mux(TRUE, TRUE, TRUE,FALSE); +} + +static void call_with_zrtp_configured_calling_base(LinphoneCoreManager *marie, LinphoneCoreManager *pauline) { + bool_t call_ok; + + linphone_core_set_media_encryption(marie->lc, LinphoneMediaEncryptionZRTP); + BC_ASSERT_TRUE((call_ok=call(pauline,marie))); + + liblinphone_tester_check_rtcp(marie,pauline); + + BC_ASSERT_EQUAL(linphone_call_params_get_media_encryption(linphone_call_get_current_params(linphone_core_get_current_call(marie->lc))) + , LinphoneMediaEncryptionNone, int, "%i"); + BC_ASSERT_EQUAL(linphone_call_params_get_media_encryption(linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc))) + , LinphoneMediaEncryptionNone, int, "%i"); + end_call(pauline, marie); + +} +static void call_with_zrtp_configured_calling_side(void) { + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + + call_with_zrtp_configured_calling_base(marie,pauline); + + linphone_core_set_user_agent(pauline->lc, "Natted Linphone", NULL); + linphone_core_set_user_agent(marie->lc, "Natted Linphone", NULL); + call_with_zrtp_configured_calling_base(marie,pauline); + + linphone_core_set_firewall_policy(marie->lc,LinphonePolicyUseIce); + linphone_core_set_firewall_policy(pauline->lc,LinphonePolicyUseIce); + call_with_zrtp_configured_calling_base(marie,pauline); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + + +} test_t call_tests[] = { - { "Phone number normalization", phone_number_normalization }, { "Early declined call", early_declined_call }, { "Call declined", call_declined }, { "Cancelled call", cancelled_call }, @@ -4144,6 +5656,8 @@ test_t call_tests[] = { { "Cancelled ringing call", cancelled_ringing_call }, { "Call busy when calling self", call_busy_when_calling_self}, { "Simple call", simple_call }, + { "Call terminated automatically by linphone_core_destroy", automatic_call_termination }, + { "Call with http proxy", call_with_http_proxy }, { "Call with timeouted bye", call_with_timeouted_bye }, { "Direct call over IPv6", direct_call_over_ipv6}, { "Outbound call with multiple proxy possible", call_outbound_with_multiple_proxy }, @@ -4163,6 +5677,12 @@ test_t call_tests[] = { { "Call without SDP", call_with_no_sdp}, { "Call without SDP and ACK without SDP", call_with_no_sdp_ack_without_sdp}, { "Call paused resumed", call_paused_resumed }, + { "Call paused resumed with video", call_paused_resumed_with_video }, + { "Call paused resumed with video no sdp ack", call_paused_resumed_with_no_sdp_ack}, + { "Call paused resumed with video no sdk ack using video policy for resume offers",call_paused_resumed_with_no_sdp_ack_using_video_policy}, + { "Call paused, updated and resumed with video no sdk ack using video policy for resume offers", call_paused_updated_resumed_with_no_sdp_ack_using_video_policy}, + { "Call paused, updated and resumed with video no sdk ack using video policy for resume offers with accept call update", call_paused_updated_resumed_with_no_sdp_ack_using_video_policy_and_accept_call_update}, + { "Call paused by both parties", call_paused_by_both }, { "Call paused resumed with loss", call_paused_resumed_with_loss }, { "Call paused resumed from callee", call_paused_resumed_from_callee }, { "SRTP call", srtp_call }, @@ -4178,7 +5698,8 @@ test_t call_tests[] = { { "Call with mkv file player", call_with_mkv_file_player}, { "Audio call with ICE no matching audio codecs", audio_call_with_ice_no_matching_audio_codecs }, #ifdef VIDEO_ENABLED - { "Simple video call",video_call}, + { "Simple video call AVPF",video_call_avpf}, + { "Simple video call",video_call}, { "Simple ZRTP video call",video_call_zrtp}, { "Simple DTLS video call",video_call_dtls}, { "Simple video call using policy",video_call_using_policy}, @@ -4193,6 +5714,7 @@ test_t call_tests[] = { { "Call with several video switches", call_with_several_video_switches }, { "SRTP call with several video switches", srtp_call_with_several_video_switches }, { "Call with video declined", call_with_declined_video}, + { "Call with video declined despite policy", call_with_declined_video_despite_policy}, { "Call with video declined using policy", call_with_declined_video_using_policy}, { "Call with multiple early media", multiple_early_media }, { "Call with ICE from video to non-video", call_with_ice_video_to_novideo}, @@ -4200,8 +5722,14 @@ test_t call_tests[] = { { "Call with ICE and video added 2", call_with_ice_video_added_2 }, { "Call with ICE and video added 3", call_with_ice_video_added_3 }, { "Call with ICE and video added and refused", call_with_ice_video_added_and_refused }, + { "Call with ICE and video added with video policies to false", call_with_ice_video_added_with_video_policies_to_false }, +#if ICE_WAS_WORKING_WITH_REAL_TIME_TEXT + { "Call with ICE, video and realtime text", call_with_ice_video_and_rtt }, +#endif { "Video call with ICE accepted using call params",video_call_ice_params}, - { "Video call recording", video_call_recording_test }, + { "Audio call paused with caller video policy enabled",audio_call_with_video_policy_enabled}, + { "Video call recording (H264)", video_call_recording_h264_test }, + { "Video call recording (VP8)", video_call_recording_vp8_test }, { "Snapshot", video_call_snapshot }, { "Video call with early media and no matching audio codecs", video_call_with_early_media_no_matching_audio_codecs }, { "DTLS SRTP video call",dtls_srtp_video_call}, @@ -4215,7 +5743,8 @@ test_t call_tests[] = { { "Video call with re-invite(inactive) followed by re-invite(no sdp)", video_call_with_re_invite_inactive_followed_by_re_invite_no_sdp}, { "SRTP Video call with re-invite(inactive) followed by re-invite", srtp_video_call_with_re_invite_inactive_followed_by_re_invite}, { "SRTP Video call with re-invite(inactive) followed by re-invite(no sdp)", srtp_video_call_with_re_invite_inactive_followed_by_re_invite_no_sdp}, - #endif + { "Classic video entry phone setup", classic_video_entry_phone_setup }, +#endif { "SRTP ice call", srtp_ice_call }, { "ZRTP ice call", zrtp_ice_call }, { "ZRTP ice call with relay", zrtp_ice_call_with_relay}, @@ -4232,10 +5761,14 @@ test_t call_tests[] = { { "Call from ICE to not ICE",ice_to_not_ice}, { "Call from not ICE to ICE",not_ice_to_ice}, { "Call with custom headers",call_with_custom_headers}, + { "Call with custom SDP attributes", call_with_custom_sdp_attributes }, { "Call established with rejected INFO",call_established_with_rejected_info}, { "Call established with rejected RE-INVITE",call_established_with_rejected_reinvite}, { "Call established with rejected incoming RE-INVITE", call_established_with_rejected_incoming_reinvite }, { "Call established with rejected RE-INVITE in error", call_established_with_rejected_reinvite_with_error}, + { "Call established with rejected RE-INVITE with trans pending error", call_established_with_rejected_reinvite_with_trans_pending_error}, + { "Call established with complex rejected operation",call_established_with_complex_rejected_operation}, + { "Call established with rejected info during re-invite",call_established_with_rejected_info_during_reinvite}, { "Call redirected by callee", call_redirect}, { "Call with specified codec bitrate", call_with_specified_codec_bitrate}, { "Call with in-dialog UPDATE request", call_with_in_dialog_update }, @@ -4255,13 +5788,31 @@ test_t call_tests[] = { { "Call with transport change after released", call_with_transport_change_after_released }, { "Unsuccessful call with transport change after released",unsucessfull_call_with_transport_change_after_released}, { "Simple stereo call with L16", simple_stereo_call_l16 }, - { "Simple stereo call with opus", simple_stereo_call_opus } + { "Simple stereo call with opus", simple_stereo_call_opus }, + { "Simple mono call with opus", simple_mono_call_opus }, + { "Call with FQDN in SDP", call_with_fqdn_in_sdp}, + { "Call with RTP IO mode", call_with_rtp_io_mode }, + { "Call with generic NACK RTCP feedback", call_with_generic_nack_rtcp_feedback }, + { "Call with complex late offering", call_with_complex_late_offering }, +#ifdef CALL_LOGS_STORAGE_ENABLED + { "Call log working if no db set", call_logs_if_no_db_set }, + { "Call log storage migration from rc to db", call_logs_migrate }, + { "Call log storage in sqlite database", call_logs_sqlite_storage }, +#endif + { "Call with custom RTP Modifier", call_with_custom_rtp_modifier }, + { "Call paused resumed with custom RTP Modifier", call_paused_resumed_with_custom_rtp_modifier }, + { "Call record with custom RTP Modifier", call_record_with_custom_rtp_modifier }, + { "Call with network switch", call_with_network_switch }, + { "Call with network switch in early state 1", call_with_network_switch_in_early_state_1 }, + { "Call with network switch in early state 2", call_with_network_switch_in_early_state_2 }, + { "Call with network switch and ICE", call_with_network_switch_and_ice }, + { "Call with network switch with socket refresh", call_with_network_switch_and_socket_refresh }, + { "Call with rtcp-mux", call_with_rtcp_mux}, + { "Call with rtcp-mux not accepted", call_with_rtcp_mux_not_accepted}, + { "Call with ICE and rtcp-mux", call_with_ice_and_rtcp_mux}, + { "Call with ICE and rtcp-mux without ICE re-invite", call_with_ice_and_rtcp_mux_without_reinvite}, + { "call with ZRTP configured calling side only", call_with_zrtp_configured_calling_side} }; -test_suite_t call_test_suite = { - "Single Call", - NULL, - NULL, - sizeof(call_tests) / sizeof(call_tests[0]), - call_tests -}; +test_suite_t call_test_suite = {"Single Call", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each, + sizeof(call_tests) / sizeof(call_tests[0]), call_tests}; diff --git a/tester/certificates/cn/cafile.pem b/tester/certificates/cn/cafile.pem index 43437333b..60b6983e8 100644 --- a/tester/certificates/cn/cafile.pem +++ b/tester/certificates/cn/cafile.pem @@ -19,28 +19,26 @@ FUWGJhPnkrnklmBdVB0l7qXYjR5uf766HDkoDxuLhNifow3IYvsS+L2Y6puRQb9w HLMDE29mBDl0WyoX3h0yR0EiAO15V9A7I10= -----END CERTIFICATE----- -UTN USERFirst Hardware Root CA, used for *.linphone.org -============================== +AddTrust External Root used for *.linphone.org +====================== -----BEGIN CERTIFICATE----- -MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCBlzELMAkGA1UE -BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl -IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAd -BgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgx -OTIyWjCBlzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0 -eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVz -ZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlI -wrthdBKWHTxqctU8EGc6Oe0rE81m65UJM6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFd -tqdt++BxF2uiiPsA3/4aMXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8 -i4fDidNdoI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqIDsjf -Pe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9KsyoUhbAgMBAAGjgbkw -gbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFKFyXyYbKJhDlV0HN9WF -lp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNF -UkZpcnN0LUhhcmR3YXJlLmNybDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUF -BwMGBggrBgEFBQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM -//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28GpgoiskliCE7/yMgUsogW -XecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gECJChicsZUN/KHAG8HQQZexB2 -lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kn -iCrVWFCVH/A7HFe7fRQ5YiuayZSSKqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67 -nfhmqA== +MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYD +VQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEw +NDgzOFowbzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRU +cnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0Eg +Um9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvtH7xsD821 ++iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6RQa1wVsfw +Tz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSccbNQYArHE504B4YCqOmo +aSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy +2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv7 +7+ldU9U0WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYDVR0P +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0Jvf6xCZU7wO94CTL +VBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRk +VHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB +IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZl +j7DYd7usQWxHYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 +6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvCNr4TDea9Y355 +e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4u +G+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= -----END CERTIFICATE----- diff --git a/tester/common/bc_completion b/tester/common/bc_completion index b155f0c85..c5bd543d2 100644 --- a/tester/common/bc_completion +++ b/tester/common/bc_completion @@ -70,16 +70,16 @@ _liblinphone_complete() { # if latest arg does not start with '--', it is a custom value if [ $latest_is_empty = 0 ] && ! grep -q -- '^--' <<< "$latest_arg"; then - # echo "yes!$prev_arg $has_not_set_suite" if [ "$prev_arg" = "--test" ] && [ $has_not_set_suite = 0 ]; then - suite_name=$(echo $@ | sed -nE 's/.*--suite (.*) (--.*)$/\1/p' |sed "s@\\\\@@g") + suite_name=$(echo $@ | sed -nE 's/.*--suite ([^(--)]*) (--.*)$/\1/p' |sed "s@\\\\@@g") completions="$($program --list-tests $suite_name)" elif [ "$prev_arg" = "--suite" ] || [ "$prev_arg" = "--list-tests" ]; then completions="$($program --list-suites)" fi elif [ "$latest_arg" = "--test" ]; then + # list available tests if --suite was provided if [ $has_not_set_suite = 0 ]; then - suite_name=$(echo $@ | sed -nE 's/.*--suite (.*) (--.*)$/\1/p' |sed "s@\\\\@@g") + suite_name=$(echo $@ | sed -nE 's/.*--suite ([^(--)]*) (--.*)/\1/p' |sed "s@\\\\@@g") completions="$($program --list-tests $suite_name)" fi elif [ "$latest_arg" = "--suite" ] || [ "$latest_arg" = "--list-tests" ]; then diff --git a/tester/common/bc_tester_utils.c b/tester/common/bc_tester_utils.c index 7c47dc25f..44b31f736 100644 --- a/tester/common/bc_tester_utils.c +++ b/tester/common/bc_tester_utils.c @@ -23,24 +23,49 @@ along with this program. If not, see . #include "bc_tester_utils.h" #include +#include +#include + +#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4) +#pragma GCC diagnostic push +#endif +#pragma GCC diagnostic ignored "-Wstrict-prototypes" #include "CUnit/Basic.h" #include "CUnit/Automated.h" +#include "CUnit/MyMem.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="."; +#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4) +#pragma GCC diagnostic pop #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 = "."; +#ifdef _WIN32 +#if defined(__MINGW32__) || !defined(WINAPI_FAMILY_PARTITION) || !defined(WINAPI_PARTITION_DESKTOP) +#define BC_TESTER_WINDOWS_DESKTOP 1 +#elif defined(WINAPI_FAMILY_PARTITION) +#if defined(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#define BC_TESTER_WINDOWS_DESKTOP 1 #endif +#if defined(WINAPI_PARTITION_PHONE_APP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) +#define BC_TESTER_WINDOWS_PHONE 1 +#endif +#if defined(WINAPI_PARTITION_APP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) +#define BC_TESTER_WINDOWS_UNIVERSAL 1 +#endif +#endif +#endif + +#ifdef __linux +/*for monitoring total space allocated via malloc*/ +#include +#endif + +static char *bc_tester_resource_dir_prefix = NULL; +// by default writable will always write near the executable +static char *bc_tester_writable_dir_prefix = NULL; + +static char *bc_current_suite_name = NULL; +static char *bc_current_test_name = NULL; int bc_printf_verbosity_info; int bc_printf_verbosity_error; @@ -57,19 +82,21 @@ 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); +static long max_vm_kb = 0; -void bc_tester_printf(int level, const char *fmt, ...) { +void (*tester_printf_va)(int level, const char *format, va_list args); + +void bc_tester_printf(int level, const char *format, ...) { va_list args; - va_start (args, fmt); - tester_printf_va(level, fmt, args); + va_start (args, format); + tester_printf_va(level, format, 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); + CU_pSuite pSuite = CU_add_suite(suite->name, suite->before_all, suite->after_all); for (i = 0; i < suite->nb_tests; i++) { if (NULL == CU_add_test(pSuite, suite->tests[i].name, suite->tests[i].func)) { @@ -89,7 +116,7 @@ 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))) { + if (strcmp(suite_name, test_suite[i]->name) == 0) { return i; } } @@ -97,7 +124,7 @@ int bc_tester_suite_index(const char *suite_name) { return -1; } -int bc_tester_nb_suites() { +int bc_tester_nb_suites(void) { return nb_test_suites; } @@ -114,7 +141,7 @@ int bc_tester_nb_tests(const char *suite_name) { return test_suite[i]->nb_tests; } -void bc_tester_list_suites() { +void bc_tester_list_suites(void) { int j; for(j=0;jpName); + suite_start_time = time(NULL); + bc_current_suite_name = pSuite->pName; } static void suite_complete_message_handler(const CU_pSuite pSuite, const CU_pFailureRecord pFailure) { - bc_tester_printf(bc_printf_verbosity_info,"Suite [%s] ended\n", pSuite->pName); + bc_tester_printf(bc_printf_verbosity_info, "Suite [%s] ended in %lu sec\n", pSuite->pName, + time(NULL) - suite_start_time); } +static time_t test_start_time = 0; static void test_start_message_handler(const CU_pTest pTest, const CU_pSuite pSuite) { + int suite_index = bc_tester_suite_index(pSuite->pName); + if (test_suite[suite_index]->before_each) { + test_suite[suite_index]->before_each(); + } bc_tester_printf(bc_printf_verbosity_info,"Suite [%s] Test [%s] started", pSuite->pName,pTest->pName); + test_start_time = time(NULL); + bc_current_test_name = pTest->pName; } /*derivated from cunit*/ -static void test_complete_message_handler(const CU_pTest pTest, - const CU_pSuite pSuite, - const CU_pFailureRecord pFailureList) { +static void test_complete_message_handler(const CU_pTest pTest, const CU_pSuite pSuite, + const CU_pFailureRecord pFailureList) { int i; - char result[2048]; - char buffer[2048]; + int suite_index = bc_tester_suite_index(pSuite->pName); CU_pFailureRecord pFailure = pFailureList; - snprintf(result, sizeof(result), "Suite [%s] Test [%s]", pSuite->pName, pTest->pName); + char *buffer = NULL; + char* result = bc_sprintf("Suite [%s] Test [%s] %s in %lu secs", pSuite->pName, pTest->pName, + pFailure ? "failed" : "passed", (unsigned long)(time(NULL) - test_start_time)); + if (pFailure) { - strncat(result, " failed:", strlen(" failed:")); - for (i = 1 ; (NULL != pFailure) ; pFailure = pFailure->pNext, i++) { - snprintf(buffer, sizeof(buffer), "\n %d. %s:%u - %s", i, - (NULL != pFailure->strFileName) ? pFailure->strFileName : "", - pFailure->uiLineNumber, - (NULL != pFailure->strCondition) ? pFailure->strCondition : ""); - strncat(result, buffer, strlen(buffer)); + for (i = 1; (NULL != pFailure); pFailure = pFailure->pNext, i++) { + buffer = bc_sprintf("%s\n %d. %s:%u - %s", + result, + i, + (NULL != pFailure->strFileName) ? pFailure->strFileName : "", + pFailure->uiLineNumber, + (NULL != pFailure->strCondition) ? pFailure->strCondition : ""); + free(result); + result = buffer; } - } else { - strncat(result, " passed", strlen(" passed")); } - bc_tester_printf(bc_printf_verbosity_info,"%s\n", result); + + bc_tester_printf(bc_printf_verbosity_info,"%s", result); + free(result); + + if (test_suite[suite_index]->after_each) { + test_suite[suite_index]->after_each(); + } + //insert empty line + bc_tester_printf(bc_printf_verbosity_info,""); + +#ifdef __linux + /* use mallinfo() to monitor allocated space. It is linux specific but other methods don't work: + * setrlimit() RLIMIT_DATA doesn't count memory allocated via mmap() (which is used internally by malloc) + * setrlimit() RLIMIT_AS works but also counts virtual memory allocated by thread stacks, which is very big and + * hardly controllable. + * setrlimit() RLIMIT_RSS does nothing interesting on linux. + * getrusage() of RSS is unreliable: memory blocks can be leaked without being read or written, which would not + * appear in RSS. + * mallinfo() itself is the less worse solution. Allocated bytes are returned as 'int' so limited to 2GB + */ + if (max_vm_kb) { + struct mallinfo minfo = mallinfo(); + if (minfo.uordblks > max_vm_kb * 1024) { + bc_tester_printf( + bc_printf_verbosity_error, + "The program exceeded the maximum amount of memory allocatable (%i bytes), aborting now.\n", + minfo.uordblks); + abort(); + } + } +#endif } #endif @@ -249,37 +318,147 @@ int bc_tester_run_tests(const char *suite_name, const char *test_name) { } } } +#ifdef __linux + bc_tester_printf(bc_printf_verbosity_info, "Still %i kilobytes allocated when all tests are finished.", + mallinfo().uordblks / 1024); +#endif + return CU_get_number_of_tests_failed()!=0; } void bc_tester_helper(const char *name, const char* additionnal_helper) { - bc_tester_printf(bc_printf_verbosity_info,"%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" + bc_tester_printf(bc_printf_verbosity_info, + "%s --help\n" #ifdef HAVE_CU_CURSES - "\t\t\t--curses\n" + "\t\t\t--curses\n" #endif - "\t\t\t--xml\n" - "\t\t\t--xml-file \n" - "And additionally:\n" - "%s" - , name - , additionnal_helper); + "\t\t\t--list-suites\n" + "\t\t\t--list-tests \n" + "\t\t\t--suite \n" + "\t\t\t--test \n" + "\t\t\t--resource-dir (directory where tester resource are located)\n" + "\t\t\t--writable-dir (directory where temporary files should be created)\n" + "\t\t\t--xml\n" + "\t\t\t--xml-file \n" + "\t\t\t--max-alloc (maximum ammount of memory obtained via malloc allocator)\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) { +#if !defined(BC_TESTER_WINDOWS_PHONE) && !defined(BC_TESTER_WINDOWS_UNIVERSAL) && !defined(__QNX__) && !defined(ANDROID) && !defined(IOS) +static int file_exists(const char* root_path) { + char * res_path = bc_sprintf("%s/common/bc_completion", root_path); + FILE* file = fopen(res_path, "r"); + int found = (file != NULL); + free(res_path); + if (file) { + fclose(file); + } + return found; +} +#endif + +static void detect_res_prefix(const char* prog) { + char* progpath = NULL; + FILE* writable_file = NULL; + + if (prog != NULL) { + progpath = strdup(prog); + if (strchr(prog, '/') != NULL) { + progpath[strrchr(prog, '/') - prog + 1] = '\0'; + } else if (strchr(prog, '\\') != NULL) { + progpath[strrchr(prog, '\\') - prog + 1] = '\0'; + } + } +#if !defined(BC_TESTER_WINDOWS_PHONE) && !defined(BC_TESTER_WINDOWS_UNIVERSAL) && !defined(__QNX__) && !defined(ANDROID) && !defined(IOS) + { + char* prefix = NULL; + + if (file_exists(".")) { + prefix = strdup("."); + } else if (file_exists("..")) { + prefix = strdup(".."); + } else if (progpath) { + //for autotools, binary is in .libs/ subdirectory + char * progpath2 = bc_sprintf("%s/../", progpath); + if (file_exists(progpath)) { + prefix = strdup(progpath); + } else if (file_exists(progpath2)) { + prefix = strdup(progpath2); + } + free(progpath2); + } + + if (bc_tester_resource_dir_prefix != NULL && !file_exists(bc_tester_resource_dir_prefix)) { + bc_tester_printf(bc_printf_verbosity_error, "Invalid provided resource directory: could not find expected resources in %s.\n", bc_tester_resource_dir_prefix); + free(bc_tester_resource_dir_prefix); + bc_tester_resource_dir_prefix = NULL; + } + + if (prefix != NULL) { + if (bc_tester_resource_dir_prefix == NULL) { + bc_tester_printf(bc_printf_verbosity_error, "Resource directory set to %s\n", prefix); + bc_tester_set_resource_dir_prefix(prefix); + } + + if (bc_tester_writable_dir_prefix == NULL) { + bc_tester_printf(bc_printf_verbosity_error, "Writable directory set to %s\n", prefix); + bc_tester_set_writable_dir_prefix(prefix); + } + free(prefix); + } + } +#endif + + // check that we can write in writable directory + if (bc_tester_writable_dir_prefix != NULL) { + char * writable_file_path = bc_sprintf("%s/%s", bc_tester_writable_dir_prefix, ".bc_tester_utils.tmp"); + writable_file = fopen(writable_file_path, "w"); + if (writable_file) { + fclose(writable_file); + } + free(writable_file_path); + } + if (bc_tester_resource_dir_prefix == NULL || writable_file == NULL) { + if (bc_tester_resource_dir_prefix == NULL) { + bc_tester_printf(bc_printf_verbosity_error, "Failed to detect resources for %s.\n", prog); + bc_tester_printf(bc_printf_verbosity_error, "Could not find resource directory in %s! Please try again using option --resource-dir.\n", progpath); + } + if (writable_file == NULL) { + bc_tester_printf(bc_printf_verbosity_error, "Failed to write file in %s. Please try again using option --writable-dir.\n", bc_tester_writable_dir_prefix); + } + abort(); + } + + if (progpath != NULL) { + free(progpath); + } +} + +void bc_tester_init(void (*ftester_printf)(int level, const char *format, va_list args), int iverbosity_info, int iverbosity_error) { tester_printf_va = ftester_printf; bc_printf_verbosity_error = iverbosity_error; bc_printf_verbosity_info = iverbosity_info; + bc_tester_writable_dir_prefix = strdup("."); +} + +void bc_tester_set_max_vm(long max_vm_kb) { +#ifdef __linux + max_vm_kb = max_vm_kb; + bc_tester_printf(bc_printf_verbosity_info, "Maximum virtual memory space set to %li kilo bytes", max_vm_kb); +#else + bc_tester_printf(bc_printf_verbosity_error, "Maximum virtual memory space setting is only implemented on Linux."); +#endif } 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){ @@ -302,7 +481,16 @@ int bc_tester_parse_args(int argc, char **argv, int argid) xml_enabled = 1; } else if (strcmp(argv[i], "--xml") == 0){ xml_enabled = 1; - }else { + } else if (strcmp(argv[i], "--max-alloc") == 0) { + CHECK_ARG("--max-alloc", ++i, argc); + max_vm_kb = atol(argv[i]); + } else if (strcmp(argv[i], "--resource-dir") == 0) { + CHECK_ARG("--resource-dir", ++i, argc); + bc_tester_resource_dir_prefix = strdup(argv[i]); + } else if (strcmp(argv[i], "--writable-dir") == 0) { + CHECK_ARG("--writable-dir", ++i, argc); + bc_tester_writable_dir_prefix = strdup(argv[i]); + } else { bc_tester_printf(bc_printf_verbosity_error, "Unknown option \"%s\"\n", argv[i]); return -1; } @@ -316,12 +504,16 @@ int bc_tester_parse_args(int argc, char **argv, int argid) return i - argid + 1; } -int bc_tester_start() { +int bc_tester_start(const char* prog_name) { int ret; + + detect_res_prefix(prog_name); + + if (max_vm_kb) + bc_tester_set_max_vm(max_vm_kb); + if( xml_enabled ){ - size_t size = strlen(xml_file) + strlen(".tmp") + 1; - char * xml_tmp_file = malloc(sizeof(char) * size); - snprintf(xml_tmp_file, size, "%s.tmp", xml_file); + char * xml_tmp_file = bc_sprintf("%s.tmp", xml_file); CU_set_output_filename(xml_tmp_file); free(xml_tmp_file); } @@ -341,20 +533,22 @@ void bc_tester_add_suite(test_suite_t *suite) { } } -void bc_tester_uninit() { +void bc_tester_uninit(void) { + /* Redisplay list of failed tests on end */ + /*BUG: do not display list of failures on mingw, it crashes mysteriously*/ +#if !defined(WIN32) && !defined(_MSC_VER) /* Redisplay list of failed tests on end */ if (CU_get_number_of_failure_records()){ CU_basic_show_failures(CU_get_failure_list()); } +#endif CU_cleanup_registry(); /*add missing final newline*/ bc_tester_printf(bc_printf_verbosity_info,""); if( xml_enabled ){ /*create real xml file only if tester did not crash*/ - size_t size = strlen(xml_file) + strlen(".tmp-Results.xml") + 1; - char * xml_tmp_file = malloc(sizeof(char) * size); - snprintf(xml_tmp_file, size, "%s.tmp-Results.xml", xml_file); + char * xml_tmp_file = bc_sprintf("%s.tmp-Results.xml", xml_file); rename(xml_tmp_file, xml_file); free(xml_tmp_file); } @@ -364,14 +558,108 @@ void bc_tester_uninit() { test_suite = NULL; nb_test_suites = 0; } + + if (bc_tester_resource_dir_prefix != NULL) { + free(bc_tester_resource_dir_prefix); + bc_tester_resource_dir_prefix = NULL; + } + if (bc_tester_writable_dir_prefix != NULL) { + free(bc_tester_writable_dir_prefix); + bc_tester_writable_dir_prefix = NULL; + } +} + +static void bc_tester_set_dir_prefix(char **prefix, const char *name) { + if (*prefix != NULL) free(*prefix); + *prefix = strdup(name); +} + +const char * bc_tester_get_resource_dir_prefix(void) { + return bc_tester_resource_dir_prefix; +} + +void bc_tester_set_resource_dir_prefix(const char *name) { + bc_tester_set_dir_prefix(&bc_tester_resource_dir_prefix, name); +} + +const char * bc_tester_get_writable_dir_prefix(void) { + return bc_tester_writable_dir_prefix; +} + +void bc_tester_set_writable_dir_prefix(const char *name) { + bc_tester_set_dir_prefix(&bc_tester_writable_dir_prefix, name); +} + +static char * bc_tester_path(const char *prefix, const char *name) { + if (name) { + return bc_sprintf("%s/%s", prefix, name); + } else { + return NULL; + } } char * bc_tester_res(const char *name) { - char* file = NULL; - if (name) { - size_t len = strlen(bc_tester_read_dir_prefix) + 1 + strlen(name) + 1; - file = malloc(len); - snprintf(file, len, "%s/%s", bc_tester_read_dir_prefix, name); - } - return file; + return bc_tester_path(bc_tester_resource_dir_prefix, name); +} + +char * bc_tester_file(const char *name) { + return bc_tester_path(bc_tester_writable_dir_prefix, name); +} + +char* bc_sprintfva(const char* format, va_list args) { + /* Guess we need no more than 100 bytes. */ + int n, size = 200; + char *p,*np; +#ifndef WIN32 + va_list cap;/*copy of our argument list: a va_list cannot be re-used (SIGSEGV on linux 64 bits)*/ +#endif + if ((p = malloc(size)) == NULL) + return NULL; + while (1) + { + /* Try to print in the allocated space. */ +#ifndef WIN32 + va_copy(cap,args); + n = vsnprintf (p, size, format, cap); + va_end(cap); +#else + /*this works on 32 bits, luckily*/ + n = vsnprintf (p, size, format, args); +#endif + /* If that worked, return the string. */ + if (n > -1 && n < size) + return p; + //bc_tester_printf(bc_printf_verbosity_error, "Reallocing space.\n"); + /* Else try again with more space. */ + if (n > -1) /* glibc 2.1 */ + size = n + 1; /* precisely what is needed */ + else /* glibc 2.0 */ + size *= 2; /* twice the old size */ + if ((np = realloc (p, size)) == NULL) + { + free(p); + return NULL; + } + else + { + p = np; + } + } +} + +char* bc_sprintf(const char* format, ...) { + va_list args; + char* res; + va_start(args, format); + res = bc_sprintfva(format, args); + va_end (args); + return res; +} + +const char * bc_tester_current_suite_name(void) { + return bc_current_suite_name; +} + +const char * bc_tester_current_test_name(void) { + return bc_current_test_name; } diff --git a/tester/common/bc_tester_utils.h b/tester/common/bc_tester_utils.h index a0e95884a..25acd0623 100644 --- a/tester/common/bc_tester_utils.h +++ b/tester/common/bc_tester_utils.h @@ -16,7 +16,6 @@ along with this program. If not, see . */ - #ifndef TESTER_UTILS_H #define TESTER_UTILS_H @@ -25,16 +24,24 @@ #include #include -extern const char *bc_tester_read_dir_prefix; -extern const char *bc_tester_writable_dir_prefix; +#ifdef _WIN32 +#ifndef snprintf +#define snprintf _snprintf +#endif +#ifndef strdup +#define strdup _strdup +#endif +#endif extern int bc_printf_verbosity_info; extern int bc_printf_verbosity_error; typedef void (*test_function_t)(void); -typedef int (*init_function_t)(void); -typedef int (*cleanup_function_t)(void); -typedef int (*test_suite_function_t)(const char *name); +/** Function used in all suites - it is invoked before all and each tests and also after each and all tests + * @return 0 means success, otherwise it's an error +**/ +typedef int (*pre_post_function_t)(void); +// typedef int (*test_suite_function_t)(const char *name); typedef struct { const char *name; @@ -42,11 +49,14 @@ typedef struct { } test_t; typedef struct { - const char *name; - init_function_t init_func; - cleanup_function_t cleanup_func; - int nb_tests; - test_t *tests; + const char *name; /*suite name*/ + pre_post_function_t + before_all; /*function invoked before running the suite. If not returning 0, suite is not launched. */ + pre_post_function_t after_all; /*function invoked at the end of the suite, even if some tests failed. */ + test_function_t before_each; /*function invoked before each test within this suite. */ + test_function_t after_each; /*function invoked after each test within this suite, even if it failed. */ + int nb_tests; /* number of tests */ + test_t *tests; /* tests within this suite */ } test_suite_t; #ifdef __cplusplus @@ -64,32 +74,48 @@ void bc_tester_init(void (*ftester_printf)(int level, const char *fmt, va_list a , 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(); +int bc_tester_start(const char* prog_name); void bc_tester_add_suite(test_suite_t *suite); -void bc_tester_uninit(); +void bc_tester_uninit(void); void bc_tester_printf(int level, const char *fmt, ...); +const char * bc_tester_get_resource_dir_prefix(void); +void bc_tester_set_resource_dir_prefix(const char *name); +const char * bc_tester_get_writable_dir_prefix(void); +void bc_tester_set_writable_dir_prefix(const char *name); -int bc_tester_nb_suites(); +int bc_tester_nb_suites(void); int bc_tester_nb_tests(const char* name); -void bc_tester_list_suites(); +void bc_tester_list_suites(void); 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); +const char * bc_tester_current_suite_name(void); +const char * bc_tester_current_test_name(void); +char* bc_sprintfva(const char* format, va_list args); +char* bc_sprintf(const char* format, ...); /** * Get full path to the given resource * - * @param name relative resource path (relative to bc_tester_writable_dir_prefix) + * @param name relative resource path * @return path to the resource. Must be freed by caller. */ char * bc_tester_res(const char *name); +/** +* Get full path to the given writable_file +* +* @param name relative writable file path +* @return path to the writable file. Must be freed by caller. +*/ +char * bc_tester_file(const char *name); -/*Redefine the CU_... macros WITHOUT final ';' semicolon, to allow IF conditions and with smarter error message */ + +/*Redefine the CU_... macros WITHOUT final ';' semicolon, to allow IF conditions and smarter error message */ extern int CU_assertImplementation(int bValue, unsigned int uiLine, const char *strCondition, @@ -97,25 +123,36 @@ extern int CU_assertImplementation(int bValue, const char *strFunction, int bFatal); -#define _BC_ASSERT(pred, format, fatal) CU_assertImplementation(pred, __LINE__, format, __FILE__, "", fatal) +#ifdef _WIN32 +#define BC_INLINE __inline +#else +#define BC_INLINE inline +#endif + +static BC_INLINE int _BC_ASSERT(const char* file, int line, int predicate, const char* format, int fatal) { + if (!predicate) bc_tester_printf(bc_printf_verbosity_info, format, NULL); + return CU_assertImplementation(predicate, line, format, file, "", fatal); +} + #define _BC_ASSERT_PRED(name, pred, actual, expected, type, fatal, ...) \ do { \ char format[4096] = {0}; \ type cactual = (actual); \ type cexpected = (expected); \ snprintf(format, 4096, name "(" #actual ", " #expected ") - " __VA_ARGS__); \ - _BC_ASSERT(pred, format, fatal); \ + _BC_ASSERT(__FILE__, __LINE__, pred, format, fatal); \ } while (0) -#define BC_PASS(msg) _BC_ASSERT(TRUE, "BC_PASS(" #msg ").", FALSE) -#define BC_FAIL(msg) _BC_ASSERT(FALSE, "BC_FAIL(" #msg ").", FALSE) -#define BC_ASSERT(value) _BC_ASSERT((value), #value, FALSE) -#define BC_ASSERT_FATAL(value) _BC_ASSERT((value), #value, TRUE) -#define BC_TEST(value) _BC_ASSERT((value), #value, FALSE) -#define BC_TEST_FATAL(value) _BC_ASSERT((value), #value, TRUE) -#define BC_ASSERT_TRUE(value) _BC_ASSERT((value), ("BC_ASSERT_TRUE(" #value ")"), FALSE) -#define BC_ASSERT_TRUE_FATAL(value) _BC_ASSERT((value), ("BC_ASSERT_TRUE_FATAL(" #value ")"), TRUE) -#define BC_ASSERT_FALSE(value) _BC_ASSERT(!(value), ("BC_ASSERT_FALSE(" #value ")"), FALSE) -#define BC_ASSERT_FALSE_FATAL(value) _BC_ASSERT(!(value), ("BC_ASSERT_FALSE_FATAL(" #value ")"), TRUE) + +#define BC_PASS(msg) _BC_ASSERT(__FILE__, __LINE__, TRUE, "BC_PASS(" #msg ").", FALSE) +#define BC_FAIL(msg) _BC_ASSERT(__FILE__, __LINE__, FALSE, "BC_FAIL(" #msg ").", FALSE) +#define BC_ASSERT(value) _BC_ASSERT(__FILE__, __LINE__, (value), #value, FALSE) +#define BC_ASSERT_FATAL(value) _BC_ASSERT(__FILE__, __LINE__, (value), #value, TRUE) +#define BC_TEST(value) _BC_ASSERT(__FILE__, __LINE__, (value), #value, FALSE) +#define BC_TEST_FATAL(value) _BC_ASSERT(__FILE__, __LINE__, (value), #value, TRUE) +#define BC_ASSERT_TRUE(value) _BC_ASSERT(__FILE__, __LINE__, (value), ("BC_ASSERT_TRUE(" #value ")"), FALSE) +#define BC_ASSERT_TRUE_FATAL(value) _BC_ASSERT(__FILE__, __LINE__, (value), ("BC_ASSERT_TRUE_FATAL(" #value ")"), TRUE) +#define BC_ASSERT_FALSE(value) _BC_ASSERT(__FILE__, __LINE__, !(value), ("BC_ASSERT_FALSE(" #value ")"), FALSE) +#define BC_ASSERT_FALSE_FATAL(value) _BC_ASSERT(__FILE__, __LINE__, !(value), ("BC_ASSERT_FALSE_FATAL(" #value ")"), TRUE) #define BC_ASSERT_EQUAL(actual, expected, type, type_format) _BC_ASSERT_PRED("BC_ASSERT_EQUAL", ((cactual) == (cexpected)), actual, expected, type, FALSE, "Expected " type_format " but was " type_format ".", cexpected, cactual) #define BC_ASSERT_EQUAL_FATAL(actual, expected, type, type_format) _BC_ASSERT_PRED("BC_ASSERT_EQUAL_FATAL", ((cactual) == (cexpected)), actual, expected, type, TRUE, "Expected " type_format " but was " type_format ".", cexpected, cactual) #define BC_ASSERT_NOT_EQUAL(actual, expected, type, type_format) _BC_ASSERT_PRED("BC_ASSERT_NOT_EQUAL", ((cactual) != (cexpected)), actual, expected, type, FALSE, "Expected NOT " type_format " but it was.", cexpected) @@ -124,10 +161,10 @@ extern int CU_assertImplementation(int bValue, #define BC_ASSERT_PTR_EQUAL_FATAL(actual, expected) _BC_ASSERT_PRED("BC_ASSERT_PTR_EQUAL_FATAL", ((cactual) == (cexpected)), (const void*)(actual), (const void*)(expected), const void*, TRUE, "Expected %p but was %p.", cexpected, cactual) #define BC_ASSERT_PTR_NOT_EQUAL(actual, expected) _BC_ASSERT_PRED("BC_ASSERT_PTR_NOT_EQUAL", ((cactual) != (cexpected)), (const void*)(actual), (const void*)(expected), const void*, FALSE, "Expected NOT %p but it was.", cexpected) #define BC_ASSERT_PTR_NOT_EQUAL_FATAL(actual, expected) _BC_ASSERT_PRED("BC_ASSERT_PTR_NOT_EQUAL_FATAL", ((cactual) != (cexpected)), (const void*)(actual), (const void*)(expected), const void*, TRUE, "Expected NOT %p but it was.", cexpected) -#define BC_ASSERT_PTR_NULL(value) _BC_ASSERT_PRED("BC_ASSERT_PTR_NULL", ((cactual) == (cexpected)), (const void*)(value), (const void*)NULL, const void*, FALSE, "Expected NULL but was %p.", cactual) -#define BC_ASSERT_PTR_NULL_FATAL(value) _BC_ASSERT_PRED("BC_ASSERT_PTR_NULL_FATAL", ((cactual) == (cexpected)), (const void*)(value), (const void*)NULL, const void*, TRUE, "Expected NULL but was %p.", cactual) -#define BC_ASSERT_PTR_NOT_NULL(value) _BC_ASSERT_PRED("BC_ASSERT_PTR_NOT_NULL", ((cactual) != (cexpected)), (const void*)(value), (const void*)NULL, const void*, FALSE, "Expected NOT NULL but it was.") -#define BC_ASSERT_PTR_NOT_NULL_FATAL(value) _BC_ASSERT_PRED("BC_ASSERT_PTR_NOT_NULL_FATAL", ((cactual) != (cexpected)), (const void*)(value), (const void*)NULL, const void*, TRUE, "Expected NOT NULL but it was.") +#define BC_ASSERT_PTR_NULL(value) _BC_ASSERT_PRED("BC_ASSERT_PTR_NULL", ((cactual) == (cexpected)), (const void*)(value), NULL, const void*, FALSE, "Expected NULL but was %p.", cactual) +#define BC_ASSERT_PTR_NULL_FATAL(value) _BC_ASSERT_PRED("BC_ASSERT_PTR_NULL_FATAL", ((cactual) == (cexpected)), (const void*)(value), NULL, const void*, TRUE, "Expected NULL but was %p.", cactual) +#define BC_ASSERT_PTR_NOT_NULL(value) _BC_ASSERT_PRED("BC_ASSERT_PTR_NOT_NULL", ((cactual) != (cexpected)), (const void*)(value), NULL, const void*, FALSE, "Expected NOT NULL but it was.") +#define BC_ASSERT_PTR_NOT_NULL_FATAL(value) _BC_ASSERT_PRED("BC_ASSERT_PTR_NOT_NULL_FATAL", ((cactual) != (cexpected)), (const void*)(value), NULL, const void*, TRUE, "Expected NOT NULL but it was.") #define BC_ASSERT_STRING_EQUAL(actual, expected) _BC_ASSERT_PRED("BC_ASSERT_STRING_EQUAL", !(strcmp((const char*)(cactual), (const char*)(cexpected))), actual, expected, const char*, FALSE, "Expected %s but was %s.", cexpected, cactual) #define BC_ASSERT_STRING_EQUAL_FATAL(actual, expected) _BC_ASSERT_PRED("BC_ASSERT_STRING_EQUAL_FATAL", !(strcmp((const char*)(cactual), (const char*)(cexpected))), actual, expected, const char*, TRUE, "Expected %s but was %s.", cexpected, cactual) #define BC_ASSERT_STRING_NOT_EQUAL(actual, expected) _BC_ASSERT_PRED("BC_ASSERT_STRING_NOT_EQUAL", (strcmp((const char*)(cactual), (const char*)(cexpected))), actual, expected, const char*, FALSE, "Expected NOT %s but it was.", cexpected) diff --git a/tester/complex_sip_call_tester.c b/tester/complex_sip_call_tester.c new file mode 100644 index 000000000..605b10cba --- /dev/null +++ b/tester/complex_sip_call_tester.c @@ -0,0 +1,366 @@ +/* + liblinphone_tester - liblinphone test suite + Copyright (C) 2015 Belledonne Communications SARL + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + + +#include "linphonecore.h" +#include "liblinphone_tester.h" +#include "lpconfig.h" +#include "private.h" + +#ifdef _MSC_VER +#define popen _popen +#define pclose _pclose +#endif + +void check_rtcp(LinphoneCall *call) { + MSTimeSpec ts; + + linphone_call_ref(call); + liblinphone_tester_clock_start(&ts); + + do { + if (linphone_call_get_audio_stats(call)->round_trip_delay > 0.0 && (!linphone_call_log_video_enabled(linphone_call_get_call_log(call)) || linphone_call_get_video_stats(call)->round_trip_delay > 0.0)) { + break; + } + wait_for_until(call->core, NULL, NULL, 0, 20); /*just to sleep while iterating*/ + } while (!liblinphone_tester_clock_elapsed(&ts, 15000)); + + BC_ASSERT_GREATER(linphone_call_get_audio_stats(call)->round_trip_delay, 0.0, float, "%f"); + if (linphone_call_log_video_enabled(linphone_call_get_call_log(call))) { + BC_ASSERT_GREATER(linphone_call_get_video_stats(call)->round_trip_delay, 0.0, float, "%f"); + } + + linphone_call_unref(call); +} + +static FILE *sip_start(const char *senario, const char* dest_username, LinphoneAddress* dest_addres) { +#if HAVE_SIPP + char *dest; + char *command; + FILE *file; + + if (linphone_address_get_port(dest_addres)>0) + dest = ms_strdup_printf("%s:%i",linphone_address_get_domain(dest_addres),linphone_address_get_port(dest_addres)); + else + dest = ms_strdup_printf("%s",linphone_address_get_domain(dest_addres)); + //until errors logs are handled correctly and stop breaks output, they will be DISABLED + command = ms_strdup_printf(SIPP_COMMAND" -sf %s -s %s %s -trace_err -trace_msg -rtp_echo -m 1 -d 1000",senario,dest_username,dest); + + ms_message("Starting sipp commad [%s]",command); + file = popen(command, "r"); + ms_free(command); + ms_free(dest); + return file; +#else + return NULL; +#endif +} + + +static FILE *sip_start_recv(const char *senario) { +#if HAVE_SIPP + char *command; + FILE *file; + + //until errors logs are handled correctly and stop breaks output, they will be DISABLED + command = ms_strdup_printf(SIPP_COMMAND" -sf %s -trace_err -trace_msg -rtp_echo -m 1 -d 1000",senario); + + ms_message("Starting sipp commad [%s]",command); + file = popen(command, "r"); + ms_free(command); + return file; +#else + return NULL; +#endif +} + + +/*static void dest_server_server_resolved(void *data, const char *name, struct addrinfo *ai_list) { + *(struct addrinfo **)data =ai_list; +}*/ +static void sip_update_within_icoming_reinvite_with_no_sdp(void) { + LinphoneCoreManager *mgr; +/* LinphoneProxyConfig *proxy = linphone_core_get_default_proxy_config(mgr->lc); + LinphoneAddress *dest = linphone_address_new(linphone_proxy_config_get_route(proxy) ?linphone_proxy_config_get_route(proxy):linphone_proxy_config_get_server_addr(proxy)); + struct addrinfo *addrinfo = NULL; + char ipstring [INET6_ADDRSTRLEN]; + int err; + int port = linphone_address_get_port(dest);*/ + char *identity_char; + char *scen; + FILE * sipp_out; + + /*currently we use direct connection because sipp do not properly set ACK request uri*/ + mgr= linphone_core_manager_new2( "empty_rc", FALSE); + mgr->identity= linphone_core_get_primary_contact_parsed(mgr->lc); + linphone_address_set_username(mgr->identity,"marie"); + identity_char=linphone_address_as_string(mgr->identity); + linphone_core_set_primary_contact(mgr->lc,identity_char); + linphone_core_iterate(mgr->lc); + /* + sal_resolve_a( mgr->lc->sal + ,linphone_address_get_domain(dest) + ,linphone_address_get_port(dest) + ,AF_INET + ,(SalResolverCallback)dest_server_server_resolved + ,&addrinfo); + linphone_address_destroy(dest); + dest=linphone_address_new(NULL); + + wait_for(mgr->lc, mgr->lc, (int*)&addrinfo, 1); + err=getnameinfo((struct sockaddr + *)addrinfo->ai_addr,addrinfo->ai_addrlen,ipstring,INET6_ADDRSTRLEN,NULL,0,NI_NUMERICHOST); + linphone_address_set_domain(dest, ipstring); + if (port > 0) + linphone_address_set_port(dest, port); + */ + scen = bc_tester_res("sipp/sip_update_within_icoming_reinvite_with_no_sdp.xml"); + sipp_out = sip_start(scen, linphone_address_get_username(mgr->identity), mgr->identity); + + if (sipp_out) { + BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallIncomingReceived, 1)); + linphone_core_accept_call(mgr->lc, linphone_core_get_current_call(mgr->lc)); + BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallStreamsRunning, 2)); + BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallEnd, 1)); + pclose(sipp_out); + } + linphone_core_manager_destroy(mgr); +} + +static void call_with_audio_mline_before_video_in_sdp(void) { + LinphoneCoreManager *mgr; + char *identity_char; + char *scen; + FILE * sipp_out; + LinphoneCall *call = NULL; + + /*currently we use direct connection because sipp do not properly set ACK request uri*/ + mgr= linphone_core_manager_new2( "empty_rc", FALSE); + mgr->identity = linphone_core_get_primary_contact_parsed(mgr->lc); + linphone_address_set_username(mgr->identity,"marie"); + identity_char = linphone_address_as_string(mgr->identity); + linphone_core_set_primary_contact(mgr->lc,identity_char); + + linphone_core_iterate(mgr->lc); + + scen = bc_tester_res("sipp/call_with_audio_mline_before_video_in_sdp.xml"); + + sipp_out = sip_start(scen, linphone_address_get_username(mgr->identity), mgr->identity); + + if (sipp_out) { + BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallIncomingReceived, 1)); + call = linphone_core_get_current_call(mgr->lc); + BC_ASSERT_PTR_NOT_NULL(call); + if (call) { + linphone_core_accept_call(mgr->lc, call); + BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallStreamsRunning, 1)); + BC_ASSERT_EQUAL(call->main_audio_stream_index, 0, int, "%d"); + BC_ASSERT_EQUAL(call->main_video_stream_index, 1, int, "%d"); + BC_ASSERT_TRUE(call->main_text_stream_index > 1); + BC_ASSERT_TRUE(linphone_call_log_video_enabled(linphone_call_get_call_log(call))); + + check_rtcp(call); + } + + BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallEnd, 1)); + pclose(sipp_out); + } + linphone_core_manager_destroy(mgr); +} + +static void call_with_video_mline_before_audio_in_sdp(void) { + LinphoneCoreManager *mgr; + char *identity_char; + char *scen; + FILE * sipp_out; + LinphoneCall *call = NULL; + + /*currently we use direct connection because sipp do not properly set ACK request uri*/ + mgr= linphone_core_manager_new2( "empty_rc", FALSE); + mgr->identity = linphone_core_get_primary_contact_parsed(mgr->lc); + linphone_address_set_username(mgr->identity,"marie"); + identity_char = linphone_address_as_string(mgr->identity); + linphone_core_set_primary_contact(mgr->lc,identity_char); + + linphone_core_iterate(mgr->lc); + + scen = bc_tester_res("sipp/call_with_video_mline_before_audio_in_sdp.xml"); + + sipp_out = sip_start(scen, linphone_address_get_username(mgr->identity), mgr->identity); + + if (sipp_out) { + BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallIncomingReceived, 1)); + call = linphone_core_get_current_call(mgr->lc); + BC_ASSERT_PTR_NOT_NULL(call); + if (call) { + linphone_core_accept_call(mgr->lc, call); + BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallStreamsRunning, 1)); + BC_ASSERT_EQUAL(call->main_audio_stream_index, 1, int, "%d"); + BC_ASSERT_EQUAL(call->main_video_stream_index, 0, int, "%d"); + BC_ASSERT_TRUE(call->main_text_stream_index > 1); + BC_ASSERT_TRUE(linphone_call_log_video_enabled(linphone_call_get_call_log(call))); + + check_rtcp(call); + } + + BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallEnd, 1)); + pclose(sipp_out); + } + linphone_core_manager_destroy(mgr); +} + +static void call_with_multiple_audio_mline_in_sdp(void) { + LinphoneCoreManager *mgr; + char *identity_char; + char *scen; + FILE * sipp_out; + LinphoneCall *call = NULL; + + /*currently we use direct connection because sipp do not properly set ACK request uri*/ + mgr= linphone_core_manager_new2( "empty_rc", FALSE); + mgr->identity = linphone_core_get_primary_contact_parsed(mgr->lc); + linphone_address_set_username(mgr->identity,"marie"); + identity_char = linphone_address_as_string(mgr->identity); + linphone_core_set_primary_contact(mgr->lc,identity_char); + + linphone_core_iterate(mgr->lc); + + scen = bc_tester_res("sipp/call_with_multiple_audio_mline_in_sdp.xml"); + + sipp_out = sip_start(scen, linphone_address_get_username(mgr->identity), mgr->identity); + + if (sipp_out) { + BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallIncomingReceived, 1)); + call = linphone_core_get_current_call(mgr->lc); + BC_ASSERT_PTR_NOT_NULL(call); + if (call) { + linphone_core_accept_call(mgr->lc, call); + BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallStreamsRunning, 1)); + BC_ASSERT_EQUAL(call->main_audio_stream_index, 0, int, "%d"); + BC_ASSERT_EQUAL(call->main_video_stream_index, 2, int, "%d"); + BC_ASSERT_TRUE(call->main_text_stream_index > 2); + BC_ASSERT_TRUE(linphone_call_log_video_enabled(linphone_call_get_call_log(call))); + + check_rtcp(call); + } + + BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallEnd, 1)); + pclose(sipp_out); + } + linphone_core_manager_destroy(mgr); +} + +static void call_with_multiple_video_mline_in_sdp(void) { + LinphoneCoreManager *mgr; + char *identity_char; + char *scen; + FILE * sipp_out; + LinphoneCall *call = NULL; + + /*currently we use direct connection because sipp do not properly set ACK request uri*/ + mgr= linphone_core_manager_new2( "empty_rc", FALSE); + mgr->identity = linphone_core_get_primary_contact_parsed(mgr->lc); + linphone_address_set_username(mgr->identity,"marie"); + identity_char = linphone_address_as_string(mgr->identity); + linphone_core_set_primary_contact(mgr->lc,identity_char); + + linphone_core_iterate(mgr->lc); + + scen = bc_tester_res("sipp/call_with_multiple_video_mline_in_sdp.xml"); + + sipp_out = sip_start(scen, linphone_address_get_username(mgr->identity), mgr->identity); + + if (sipp_out) { + BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallIncomingReceived, 1)); + call = linphone_core_get_current_call(mgr->lc); + BC_ASSERT_PTR_NOT_NULL(call); + if (call) { + linphone_core_accept_call(mgr->lc, call); + BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallStreamsRunning, 1)); + BC_ASSERT_EQUAL(call->main_audio_stream_index, 0, int, "%d"); + BC_ASSERT_EQUAL(call->main_video_stream_index, 1, int, "%d"); + BC_ASSERT_TRUE(call->main_text_stream_index > 3); + BC_ASSERT_TRUE(linphone_call_log_video_enabled(linphone_call_get_call_log(call))); + + check_rtcp(call); + } + + BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallEnd, 1)); + pclose(sipp_out); + } + linphone_core_manager_destroy(mgr); +} + + +static void call_invite_200ok_without_contact_header(void) { + LinphoneCoreManager *mgr; + char *identity_char; + char *scen; + FILE * sipp_out; + LinphoneCall *call = NULL; + + /*currently we use direct connection because sipp do not properly set ACK request uri*/ + mgr= linphone_core_manager_new2("empty_rc", FALSE); + mgr->identity = linphone_core_get_primary_contact_parsed(mgr->lc); + linphone_address_set_username(mgr->identity,"marie"); + identity_char = linphone_address_as_string(mgr->identity); + linphone_core_set_primary_contact(mgr->lc,identity_char); + + linphone_core_iterate(mgr->lc); + + scen = bc_tester_res("sipp/call_invite_200ok_without_contact_header.xml"); + + sipp_out = sip_start_recv(scen); + + if (sipp_out) { + call = linphone_core_invite(mgr->lc, "sipp@127.0.0.1"); + BC_ASSERT_PTR_NOT_NULL(call); + BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallOutgoingInit, 1)); + BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallOutgoingProgress, 1)); + BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallOutgoingRinging, 1)); + /*assert that the call never gets connected nor terminated*/ + BC_ASSERT_FALSE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallConnected, 1)); + BC_ASSERT_EQUAL(mgr->stat.number_of_LinphoneCallEnd, 0, int, "%d"); + BC_ASSERT_EQUAL(mgr->stat.number_of_LinphoneCallError, 0, int, "%d"); + linphone_core_terminate_call(mgr->lc, call); + BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallEnd, 1)); + BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallReleased, 1)); + pclose(sipp_out); + } + linphone_core_manager_destroy(mgr); +} + + +static test_t tests[] = { + { "SIP UPDATE within incoming reinvite without sdp", sip_update_within_icoming_reinvite_with_no_sdp }, + { "Call with audio mline before video in sdp", call_with_audio_mline_before_video_in_sdp }, + { "Call with video mline before audio in sdp", call_with_video_mline_before_audio_in_sdp }, + { "Call with multiple audio mline in sdp", call_with_multiple_audio_mline_in_sdp }, + { "Call with multiple video mline in sdp", call_with_multiple_video_mline_in_sdp }, + { "Call invite 200ok without contact header", call_invite_200ok_without_contact_header } +}; + +test_suite_t complex_sip_call_test_suite = { + "Complex SIP Call", + NULL, + NULL, + liblinphone_tester_before_each, + liblinphone_tester_after_each, + sizeof(tests) / sizeof(tests[0]), + tests +}; diff --git a/tester/dtmf_tester.c b/tester/dtmf_tester.c index 22d03837c..e31102304 100644 --- a/tester/dtmf_tester.c +++ b/tester/dtmf_tester.c @@ -19,10 +19,6 @@ #include "liblinphone_tester.h" #include "private.h" -LinphoneCoreManager* marie; -LinphoneCoreManager* pauline; -LinphoneCall *marie_call; - void dtmf_received(LinphoneCore *lc, LinphoneCall *call, int dtmf) { stats* counters = get_stats(lc); char** dst = &counters->dtmf_list_received; @@ -32,11 +28,21 @@ void dtmf_received(LinphoneCore *lc, LinphoneCall *call, int dtmf) { counters->dtmf_count++; } -void send_dtmf_base(bool_t use_rfc2833, bool_t use_sipinfo, char dtmf, char* dtmf_seq) { +void send_dtmf_base(LinphoneCoreManager **pmarie, LinphoneCoreManager **ppauline, bool_t use_rfc2833, bool_t use_sipinfo, char dtmf, char* dtmf_seq, bool_t use_opus) { char* expected = NULL; int dtmf_count_prev; - marie = linphone_core_manager_new( "marie_rc"); - pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager *marie = *pmarie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager *pauline = *ppauline = linphone_core_manager_new( "pauline_tcp_rc"); + LinphoneCall *marie_call = NULL; + + if (use_opus) { + if (!ms_filter_codec_supported("opus")) { + ms_warning("Opus not supported, skipping test."); + return; + } + disable_all_audio_codecs_except_one(marie->lc, "opus", 48000); + disable_all_audio_codecs_except_one(pauline->lc, "opus", 48000); + } linphone_core_set_use_rfc2833_for_dtmf(marie->lc, use_rfc2833); linphone_core_set_use_info_for_dtmf(marie->lc, use_sipinfo); @@ -66,7 +72,7 @@ void send_dtmf_base(bool_t use_rfc2833, bool_t use_sipinfo, char dtmf, char* dtm linphone_call_send_dtmfs(marie_call, dtmf_seq); /*wait for the DTMF sequence to be received from pauline*/ - BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, &pauline->stat.dtmf_count, dtmf_count_prev + strlen(dtmf_seq), 10000 + dtmf_delay_ms * strlen(dtmf_seq))); + BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, &pauline->stat.dtmf_count, (int)(dtmf_count_prev + strlen(dtmf_seq)), (int)(10000 + dtmf_delay_ms * strlen(dtmf_seq)))); expected = (dtmf!='\0')?ms_strdup_printf("%c%s",dtmf,dtmf_seq):ms_strdup(dtmf_seq); } @@ -81,61 +87,79 @@ void send_dtmf_base(bool_t use_rfc2833, bool_t use_sipinfo, char dtmf, char* dtm } } -void send_dtmf_cleanup() { - BC_ASSERT_PTR_NULL(marie_call->dtmfs_timer); - BC_ASSERT_PTR_NULL(marie_call->dtmf_sequence); - - /*just to sleep*/ - linphone_core_terminate_all_calls(pauline->lc); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); +void send_dtmf_cleanup(LinphoneCoreManager *marie, LinphoneCoreManager *pauline) { + LinphoneCall *marie_call = linphone_core_get_current_call(marie->lc); + if (marie_call) { + BC_ASSERT_PTR_NULL(marie_call->dtmfs_timer); + BC_ASSERT_PTR_NULL(marie_call->dtmf_sequence); + /*just to sleep*/ + linphone_core_terminate_all_calls(pauline->lc); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); + BC_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 void send_dtmf_rfc2833() { - send_dtmf_base(TRUE,FALSE,'1',NULL); - send_dtmf_cleanup(); +static void send_dtmf_rfc2833(void) { + LinphoneCoreManager *marie, *pauline; + send_dtmf_base(&marie, &pauline, TRUE,FALSE,'1',NULL,FALSE); + send_dtmf_cleanup(marie, pauline); } -static void send_dtmf_sip_info() { - send_dtmf_base(FALSE,TRUE,'#',NULL); - send_dtmf_cleanup(); +static void send_dtmf_sip_info(void) { + LinphoneCoreManager *marie, *pauline; + send_dtmf_base(&marie, &pauline, FALSE,TRUE,'#',NULL,FALSE); + send_dtmf_cleanup(marie, pauline); } -static void send_dtmfs_sequence_rfc2833() { - send_dtmf_base(TRUE,FALSE,'\0',"1230#"); - send_dtmf_cleanup(); +static void send_dtmfs_sequence_rfc2833(void) { + LinphoneCoreManager *marie, *pauline; + send_dtmf_base(&marie, &pauline, TRUE,FALSE,'\0',"1230#",FALSE); + send_dtmf_cleanup(marie, pauline); } -static void send_dtmfs_sequence_sip_info() { - send_dtmf_base(FALSE,TRUE,'\0',"1230#"); - send_dtmf_cleanup(); +static void send_dtmfs_sequence_sip_info(void) { + LinphoneCoreManager *marie, *pauline; + send_dtmf_base(&marie, &pauline, FALSE,TRUE,'\0',"1230#",FALSE); + send_dtmf_cleanup(marie, pauline); } -static void send_dtmfs_sequence_not_ready() { +static void send_dtmfs_sequence_not_ready(void) { + LinphoneCoreManager *marie; marie = linphone_core_manager_new( "marie_rc"); BC_ASSERT_EQUAL(linphone_call_send_dtmfs(linphone_core_get_current_call(marie->lc), "123"), -1, int, "%d"); linphone_core_manager_destroy(marie); } -static void send_dtmfs_sequence_call_state_changed() { - send_dtmf_base(FALSE,TRUE,'\0',NULL); +static void send_dtmfs_sequence_call_state_changed(void) { + LinphoneCoreManager *marie, *pauline; + LinphoneCall *marie_call = NULL; + send_dtmf_base(&marie, &pauline, FALSE,TRUE,'\0',NULL,FALSE); - /*very long DTMF(around 4 sec to be sent)*/ - linphone_call_send_dtmfs(marie_call, "123456789123456789"); - /*just after, change call state, and expect DTMF to be canceled*/ - linphone_core_pause_call(marie_call->core,marie_call); - BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallPausing,1)); - BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallPaused,1)); + marie_call = linphone_core_get_current_call(marie->lc); + if (marie_call) { + /*very long DTMF(around 4 sec to be sent)*/ + linphone_call_send_dtmfs(marie_call, "123456789123456789"); + /*just after, change call state, and expect DTMF to be canceled*/ + linphone_core_pause_call(marie_call->core,marie_call); + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallPausing,1)); + BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallPaused,1)); - /*wait a few time to ensure that no DTMF are received*/ - wait_for_until(marie->lc, pauline->lc, NULL, 0, 1000); + /*wait a few time to ensure that no DTMF are received*/ + wait_for_until(marie->lc, pauline->lc, NULL, 0, 1000); - BC_ASSERT_PTR_NULL(pauline->stat.dtmf_list_received); + BC_ASSERT_PTR_NULL(pauline->stat.dtmf_list_received); + } + end_call(marie, pauline); + send_dtmf_cleanup(marie, pauline); +} - send_dtmf_cleanup(); +static void send_dtmf_rfc2833_opus(void) { + LinphoneCoreManager *marie, *pauline; + send_dtmf_base(&marie, &pauline, TRUE,FALSE,'1',NULL,TRUE); + send_dtmf_cleanup(marie, pauline); } test_t dtmf_tests[] = { @@ -145,12 +169,8 @@ test_t dtmf_tests[] = { { "Send DTMF sequence using SIP INFO",send_dtmfs_sequence_sip_info}, { "DTMF sequence not sent if invalid call",send_dtmfs_sequence_not_ready}, { "DTMF sequence canceled if call state changed",send_dtmfs_sequence_call_state_changed}, + { "Send DTMF using RFC2833 using Opus",send_dtmf_rfc2833_opus}, }; -test_suite_t dtmf_test_suite = { - "DTMF", - NULL, - NULL, - sizeof(dtmf_tests) / sizeof(dtmf_tests[0]), - dtmf_tests -}; +test_suite_t dtmf_test_suite = {"DTMF", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each, + sizeof(dtmf_tests) / sizeof(dtmf_tests[0]), dtmf_tests}; diff --git a/tester/eventapi_tester.c b/tester/eventapi_tester.c index 8ac8e2c18..09925fa45 100644 --- a/tester/eventapi_tester.c +++ b/tester/eventapi_tester.c @@ -39,7 +39,7 @@ const char *liblinphone_tester_get_notify_content(void){ void linphone_notify_received(LinphoneCore *lc, LinphoneEvent *lev, const char *eventname, const LinphoneContent *content){ LinphoneCoreManager *mgr; BC_ASSERT_PTR_NOT_NULL_FATAL(content); - BC_ASSERT_TRUE(strcmp(notify_content,(const char*)linphone_content_get_buffer(content))==0); + BC_ASSERT_STRING_EQUAL(notify_content,(const char*)linphone_content_get_buffer(content)); mgr=get_manager(lc); mgr->stat.number_of_NotifyReceived++; } @@ -122,7 +122,7 @@ void linphone_publish_state_changed(LinphoneCore *lc, LinphoneEvent *ev, Linphon static void subscribe_test_declined(void) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneContent* content; LinphoneEvent *lev; const LinphoneErrorInfo *ei; @@ -164,7 +164,7 @@ typedef enum RefreshTestType{ static void subscribe_test_with_args(bool_t terminated_by_subscriber, RefreshTestType refresh_type) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneContent* content; LinphoneEvent *lev; int expires= refresh_type!=NoRefresh ? 4 : 600; @@ -193,7 +193,7 @@ static void subscribe_test_with_args(bool_t terminated_by_subscriber, RefreshTes if (refresh_type==AutoRefresh){ wait_for_list(lcs,NULL,0,6000); - BC_ASSERT_TRUE(linphone_event_get_subscription_state(pauline->lev)==LinphoneSubscriptionActive); + BC_ASSERT_EQUAL(linphone_event_get_subscription_state(pauline->lev), LinphoneSubscriptionActive, int, "%d"); }else if (refresh_type==ManualRefresh){ BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionExpiring,1,4000)); linphone_event_update_subscribe(lev,NULL); @@ -217,7 +217,7 @@ static void subscribe_test_with_args(bool_t terminated_by_subscriber, RefreshTes static void subscribe_test_with_args2(bool_t terminated_by_subscriber, RefreshTestType refresh_type) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneContent* content; LinphoneEvent *lev; int expires= refresh_type!=NoRefresh ? 4 : 600; @@ -242,10 +242,11 @@ static void subscribe_test_with_args2(bool_t terminated_by_subscriber, RefreshTe BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingInit,1,1000)); BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,3000)); - /*check good receipt of custom headers*/ - BC_ASSERT_STRING_EQUAL(linphone_event_get_custom_header(pauline->lev,"My-Header"),"pouet"); - BC_ASSERT_STRING_EQUAL(linphone_event_get_custom_header(pauline->lev,"My-Header2"),"pimpon"); - + if (pauline->stat.number_of_LinphoneSubscriptionIncomingReceived == 1) { + /*check good receipt of custom headers*/ + BC_ASSERT_STRING_EQUAL(linphone_event_get_custom_header(pauline->lev,"My-Header"),"pouet"); + BC_ASSERT_STRING_EQUAL(linphone_event_get_custom_header(pauline->lev,"My-Header2"),"pimpon"); + } BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,1,5000)); BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionActive,1,5000)); @@ -254,7 +255,7 @@ static void subscribe_test_with_args2(bool_t terminated_by_subscriber, RefreshTe if (refresh_type==AutoRefresh){ wait_for_list(lcs,NULL,0,6000); - BC_ASSERT_TRUE(linphone_event_get_subscription_state(pauline->lev)==LinphoneSubscriptionActive); + BC_ASSERT_EQUAL(linphone_event_get_subscription_state(pauline->lev), LinphoneSubscriptionActive, int, "%d"); }else if (refresh_type==ManualRefresh){ BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionExpiring,1,4000)); linphone_event_update_subscribe(lev,NULL); @@ -301,7 +302,7 @@ static void subscribe_test_manually_refreshed(void){ static void publish_test_with_args(bool_t refresh, int expires){ LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneContent* content; LinphoneEvent *lev; MSList* lcs=ms_list_append(NULL,marie->lc); @@ -342,15 +343,15 @@ static void publish_test_with_args(bool_t refresh, int expires){ linphone_core_manager_destroy(pauline); } -static void publish_test(){ +static void publish_test(void){ publish_test_with_args(TRUE,5); } -static void publish_no_auto_test(){ +static void publish_no_auto_test(void){ publish_test_with_args(FALSE,5); } -static void publish_without_expires(){ +static void publish_without_expires(void){ publish_test_with_args(TRUE,-1); } @@ -366,11 +367,5 @@ test_t event_tests[] = { { "Publish without automatic refresh",publish_no_auto_test } }; -test_suite_t event_test_suite = { - "Event", - NULL, - NULL, - sizeof(event_tests) / sizeof(event_tests[0]), - event_tests -}; - +test_suite_t event_test_suite = {"Event", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each, + sizeof(event_tests) / sizeof(event_tests[0]), event_tests}; diff --git a/tester/flexisip/flexisip.conf b/tester/flexisip/flexisip.conf old mode 100755 new mode 100644 index be06bbf89..f1cce0bef --- a/tester/flexisip/flexisip.conf +++ b/tester/flexisip/flexisip.conf @@ -18,7 +18,7 @@ auto-respawn=true # List of white space separated host names pointing to this machine. # This is to prevent loops while routing SIP messages. # Default value: localhost -aliases=localhost sipopen.example.org sip.example.org auth.example.org auth1.example.org auth2.example.org client.example.org sip2.linphone.org +aliases=localhost sip2.linphone.org sipopen.example.org sip.example.org auth.example.org auth1.example.org auth2.example.org client.example.org # List of white space separated SIP uris where the proxy must listen.Wildcard # (*) can be used to mean 'all local ip addresses'. If 'transport' @@ -37,7 +37,12 @@ aliases=localhost sipopen.example.org sip.example.org auth.example.org auth1.exa # transports=sips:sip.linphone.org:6060;maddr=192.168.0.29 # Default value: sip:* #transports=sip:192.168.56.101:5060 sips:192.168.56.101:5061 -transports=sip:*:5060 sips:*:5061;tls-certificates-dir=/etc/flexisip/tls/certificates/cn sips:*:5062;tls-certificates-dir=/etc/flexisip/tls/certificates/altname sips:*:5063;require-peer-certificate=1 sip:*:5064 + +#note: the ip addresses are explicitely specified here because the machine has several interfaces. In a simple case, using '*' instead of the explicit ip address is sufficient, +#and there is no need to specify the ipv6 transport addresses. +transports=sip:MacBook-Pro-de-jehan.local:5060 sips:MacBook-Pro-de-jehan.local:5061;tls-certificates-dir=/etc/flexisip/tls/certificates/cn sips:MacBook-Pro-de-jehan.local:5062;tls-certificates-dir=/etc/flexisip/tls/certificates/altname sips:MacBook-Pro-de-jehan.local:5063;require-peer-certificate=1 sip:MacBook-Pro-de-jehan.local:5064 sip:[2001:41d0:2:14b0::1]:5060 sips:[2001:41d0:2:14b0::1]:5061;tls-certificates-dir=/etc/flexisip/tls/certificates/cn sips:[2001:41d0:2:14b0::1]:5062;tls-certificates-dir=/etc/flexisip/tls/certificates/altname sips:[2001:41d0:2:14b0::1]:5063;require-peer-certificate=1 sip:[2001:41d0:2:14b0::1]:5064 + + # An absolute path of a directory where TLS server certificate and # private key can be found, concatenated inside an 'agent.pem' file. # Default value: /etc/flexisip/tls @@ -61,35 +66,6 @@ bind-address=0.0.0.0 port=3478 -## -## This module bans user when they are sending too much packets on -## a given timelapse -## -[module::DoS] -# Indicate whether the module is activated. -# Default value: true -enabled=true - -# A request/response enters module if the boolean filter evaluates -# to true. Ex: from.uri.domain contains 'sip.linphone.org', from.uri.domain -# in 'a.org b.org c.org', (to.uri.domain in 'a.org b.org c.org') -# && (user-agent == 'Linphone v2') -# Default value: -filter= - -# Number of milliseconds to calculate the packet rate -# Default value: 1000 -time-period=1000 - -# Maximum packet rate received in [time-period] millisecond(s) to -# consider to consider it a DoS attack. -# Default value: 5 -packet-rate-limit=5 - -# Number of minutes to ban the ip/port using iptables -# Default value: 1 -ban-time=1 - ## ## The NatHelper module executes small tasks to make SIP work smoothly @@ -107,7 +83,7 @@ enabled=true # to true. Ex: from.uri.domain contains 'sip.linphone.org', from.uri.domain # in 'a.org b.org c.org', (to.uri.domain in 'a.org b.org c.org') # && (user-agent == 'Linphone v2') -# Default value: +# Default value: filter= # Internal URI parameter added to response contact by first proxy @@ -131,19 +107,19 @@ no-403=user-agent contains 'tester-no-403' # to true. Ex: from.uri.domain contains 'sip.linphone.org', from.uri.domain # in 'a.org b.org c.org', (to.uri.domain in 'a.org b.org c.org') # && (user-agent == 'Linphone v2') -# Default value: -filter= from.uri.domain contains 'sip.example.org' || from.uri.domain contains 'auth.example.org' || from.uri.domain contains 'auth1.example.org' || from.uri.domain contains 'auth2.example.org' || from.uri.domain contains 'anonymous.invalid' +# Default value: +filter= from.uri.domain contains 'sip.example.org' || from.uri.domain contains 'auth.example.org' || from.uri.domain contains 'auth1.example.org' || from.uri.domain contains 'auth2.example.org' || from.uri.domain contains 'anonymous.invalid' # List of whitespace separated domain names to challenge. Others # are denied. -# Default value: +# Default value: auth-domains= sip.example.org auth.example.org auth1.example.org auth2.example.org client-certificates-domains=client.example.org # List of whitespace separated IP which will not be challenged. -# Default value: +# Default value: trusted-hosts= # Database backend implementation [odbc, file]. @@ -154,50 +130,27 @@ db-implementation=file # DSN=myodbc3; where 'myodbc3' is the datasource name. ex2: DRIVER={MySQL};SERVER=host;DATABASE=db;USER=user;PASSWORD=pass;OPTION=3; # for a DSN-less connection. ex3: /etc/flexisip/passwd; for a file # containing one 'user@domain password' by line. -# Default value: -datasource=./flexisip/userdb.conf +# Default value: +datasource=/etc/flexisip/userdb.conf -# Odbc SQL request to execute to obtain the password +# Odbc SQL request to execute to obtain the password # . Named parameters are :id (the user found in the from header), # :domain (the authorization realm) and :authid (the authorization # username). The use of the :id parameter is mandatory. # Default value: select password from accounts where id = :id and domain = :domain and authid=:authid request=select password from accounts where id = :id and domain = :domain and authid=:authid -# Maximum length of the login column in database. -# Default value: 100 -max-id-length=100 - -# Maximum length of the password column in database -# Default value: 100 -max-password-length=100 # Use pooling in odbc # Default value: true odbc-pooling=true -# Display timing statistics after this count of seconds -# Default value: 0 -odbc-display-timings-interval=0 - -# Display timing statistics once the number of samples reach this -# number. -# Default value: 0 -odbc-display-timings-after-count=0 - -# Retrieve passwords asynchronously. -# Default value: false -odbc-asynchronous=false # Duration of the validity of the credentials added to the cache # in seconds. # Default value: 1800 cache-expire=1800 -# Retrieve password immediately so that it is cached when an authenticated -# request arrives. -# Default value: true -immediate-retrieve-password=true # True if retrieved passwords from the database are hashed. HA1=MD5(A1) # = MD5(username:realm:pass). @@ -209,15 +162,8 @@ hashed-passwords=false # Default value: false new-auth-on-407=false -# Enable a feature useful for automatic tests, allowing a client -# to create a temporary account in the password database in memory. -# This MUST not be used for production as it is a real security -# hole. -# Default value: false - enable-test-accounts-creation=true - ## ## ... ## @@ -230,15 +176,15 @@ enabled=false # to true. Ex: from.uri.domain contains 'sip.linphone.org', from.uri.domain # in 'a.org b.org c.org', (to.uri.domain in 'a.org b.org c.org') # && (user-agent == 'Linphone v2') -# Default value: +# Default value: filter= # A gateway uri where to send all requests, as a SIP url (eg 'sip:gateway.example.net') -# Default value: +# Default value: gateway= # Modify the from and to domains of incoming register -# Default value: +# Default value: gateway-domain= # The gateway will be added to the incoming register contacts. @@ -277,6 +223,7 @@ fork-late=true call-fork-timeout=20 + # All the forked have to decline in order to decline the caller # invite # Default value: false @@ -299,7 +246,7 @@ enabled=true # to true. Ex: from.uri.domain contains 'sip.linphone.org', from.uri.domain # in 'a.org b.org c.org', (to.uri.domain in 'a.org b.org c.org') # && (user-agent == 'Linphone v2') -# Default value: +# Default value: filter= # List of whitelist separated domain names to be managed by the @@ -312,7 +259,7 @@ reg-domains=localhost sip.example.org sipopen.example.org auth1.example.org sip2 max-contacts-by-aor=15 # List of contact uri parameters that can be used to identify a -# user's device. +# user's device. # Default value: +sip.instance #unique-id-parameters= @@ -327,7 +274,7 @@ min-expires=1 # File containing the static records to add to database at startup. # Format: one 'sip_uri contact_header' by line. Example: # , -# Default value: +# Default value: static-records-file= # Timeout in seconds after which the static records file is re-read @@ -349,12 +296,12 @@ db-implementation=internal # Generate a contact from the TO header and route it to the above # destination. [sip:host:port] -# Default value: +# Default value: generated-contact-route= # Require presence of authorization header for specified realm. # [Realm] -# Default value: +# Default value: generated-contact-expected-realm= @@ -367,7 +314,7 @@ enabled=false # to true. Ex: from.uri.domain contains 'sip.linphone.org', from.uri.domain # in 'a.org b.org c.org', (to.uri.domain in 'a.org b.org c.org') # && (user-agent == 'Linphone v2') -# Default value: +# Default value: filter= # Hack for workarounding Nortel CS2k gateways bug. @@ -387,12 +334,12 @@ enabled=false # to true. Ex: from.uri.domain contains 'sip.linphone.org', from.uri.domain # in 'a.org b.org c.org', (to.uri.domain in 'a.org b.org c.org') # && (user-agent == 'Linphone v2') -# Default value: +# Default value: filter= # Whitespace separated list of sip routes to balance the requests. # Example: -# Default value: +# Default value: routes= ## @@ -411,7 +358,7 @@ enabled=true # to true. Ex: from.uri.domain contains 'sip.linphone.org', from.uri.domain # in 'a.org b.org c.org', (to.uri.domain in 'a.org b.org c.org') # && (:q -# Default value: +# Default value: filter= (user-agent contains 'Natted Linphone') # SDP attribute set by the first proxy to forbid subsequent proxies @@ -470,7 +417,7 @@ enabled=false # to true. Ex: from.uri.domain contains 'sip.linphone.org', from.uri.domain # in 'a.org b.org c.org', (to.uri.domain in 'a.org b.org c.org') # && (user-agent == 'Linphone v2') -# Default value: +# Default value: filter= # Nominal size of RTP jitter buffer, in milliseconds. A value of @@ -480,7 +427,7 @@ jb-nom-size=0 # Whitespace separated list of user-agent strings for which audio # rate control is performed. -# Default value: +# Default value: rc-user-agents= # Whitespace seprated list of audio codecs, in order of preference. @@ -506,11 +453,11 @@ enabled=true # to true. Ex: from.uri.domain contains 'sip.linphone.org', from.uri.domain # in 'a.org b.org c.org', (to.uri.domain in 'a.org b.org c.org') # && (user-agent == 'Linphone v2') -# Default value: +# Default value: filter= # A sip uri where to send all requests -# Default value: +# Default value: route= # Rewrite request-uri's host and port according to above route @@ -542,7 +489,129 @@ filter= # to this address will be deleted by this module and thus not be # delivered. # Default value: -collector-address=sip:collector@sip.example.org +collector-address=sip:sip.example.org + +## +## This module performs push notifications to mobile phone notification +## systems: apple, android, windows, as well as a generic http get/post +## to a custom server to which actual sending of the notification +## is delegated. The push notification is sent when an INVITE or +## MESSAGE request is not answered by the destination of the request +## within a certain period of time, configurable hereunder as 'timeout' +## parameter. +## +[module::PushNotification] +# Indicate whether the module is activated. +# Default value: false +enabled=true + +# A request/response enters module if the boolean filter evaluates +# to true. Ex: from.uri.domain contains 'sip.linphone.org', from.uri.domain +# in 'a.org b.org c.org', (to.uri.domain in 'a.org b.org c.org') +# && (user-agent == 'Linphone v2') +# Default value: +filter= + +# Number of second to wait before sending a push notification to +# device(if <=0 then disabled) +# Default value: 5 +timeout=5 + +# Maximum number of notifications queued for each client +# Default value: 10 +max-queue-size=10 + +# Enable push notification for apple devices +# Default value: true +apple=false + +# Path to directory where to find Apple Push Notification service +# certificates. They should bear the appid of the application, suffixed +# by the release mode and .pem extension. For example: org.linphone.dev.pem +# org.linphone.prod.pem com.somephone.dev.pem etc... The files should +# be .pem format, and made of certificate followed by private key. +# Default value: /etc/flexisip/apn +apple-certificate-dir=/etc/flexisip/apn + +# Enable push notification for android devices +# Default value: true +google=false + +# List of couples projectId:ApiKey for each android project that +# supports push notifications +# Default value: +google-projects-api-keys= + +# Enable push notification for windows phone 8 devices +# Default value: true +windowsphone=false + +# Set the badge value to 0 for apple push +# Default value: false +no-badge=false + +# Instead of having Flexisip sending the push notification directly +# to the Google/Apple/Microsoft push servers, send an http request +# to an http server with all required information encoded in URL, +# to which the actual sending of the push notification is delegated. +# The following arguments can be substitued in the http request +# uri, with the following values: +# - $type : apple, google, wp +# - $event : call, message +# - $from-name : the display name in the from header +# - $from-uri : the sip uri of the from header +# - $from-tag : the tag of the from header +# - $call-id : the call-id of the INVITE or MESSAGE request +# - $to-uri : the sip uri of the to header +# - $api-key : the api key to use (google only) +# - $msgid : the message id to put in the notification +# - $sound : the sound file to play with the notification +# + The content of the text message is put in the body of the http +# request as text/plain, if any. +# Example: http://192.168.0.2/$type/$event?from-uri=$from-uri&tag=$from-tag&callid=$callid&to=$to-uri +# Default value: +external-push-uri=http://127.0.0.1:80/$type/$event?from-uri=$from-uri&tag=$from-tag&callid=$callid&to=$to-uri + +# Method for reaching external-push-uri, typically GET or POST +# Default value: GET +external-push-method=GET + +## +## This module bans user when they are sending too much packets on +## a given timelapseTo see the list of currently banned ips/ports, +## use iptables -LYou can also check the queue of unban commands +## using atq +## +[module::DoSProtection] + +# Indicate whether the module is activated. +# Default value: true +enabled=true + +# A request/response enters module if the boolean filter evaluates +# to true. Ex: from.uri.domain contains 'sip.linphone.org', from.uri.domain +# in 'a.org b.org c.org', (to.uri.domain in 'a.org b.org c.org') +# && (user-agent == 'Linphone v2') +# Default value: +filter= + +# Number of milliseconds to consider to compute the packet rate +# Default value: 3000 +time-period=15000 + +# Maximum packet rate received in [time-period] millisecond(s) to +# consider it as a DoS attack. +# Default value: 20 +packet-rate-limit=5 + +# Number of minutes to ban the ip/port using iptables (might be +# less because it justs uses the minutes of the clock, not the seconds. +# So if the unban command is queued at 13:11:56 and scheduled and +# the ban time is 1 minute, it will be executed at 13:12:00) +# Default value: 2 +ban-time=1 + diff --git a/tester/flexisip_tester.c b/tester/flexisip_tester.c index 926221836..2b60a0f80 100644 --- a/tester/flexisip_tester.c +++ b/tester/flexisip_tester.c @@ -24,8 +24,8 @@ static void subscribe_forking(void) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); - LinphoneCoreManager* pauline2 = linphone_core_manager_new( "pauline_tcp_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + LinphoneCoreManager* pauline2 = linphone_core_manager_new( transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneContent* content; LinphoneEvent *lev; int expires= 600; @@ -59,12 +59,11 @@ static void subscribe_forking(void) { } static void message_forking(void) { - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCoreManager* marie2 = linphone_core_manager_new( "marie_rc"); MSList* lcs=ms_list_append(NULL,marie->lc); - char* to = linphone_address_as_string(marie->identity); - LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc,to); + LinphoneChatRoom* chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity); LinphoneChatMessage* message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu"); lcs=ms_list_append(lcs,pauline->lc); @@ -78,18 +77,16 @@ static void message_forking(void) { linphone_core_manager_destroy(marie); linphone_core_manager_destroy(marie2); linphone_core_manager_destroy(pauline); - ms_free(to); ms_list_free(lcs); } static void message_forking_with_unreachable_recipients(void) { - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCoreManager* marie2 = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* marie3 = linphone_core_manager_new( "marie_rc"); MSList* lcs=ms_list_append(NULL,marie->lc); - char* to = linphone_address_as_string(marie->identity); - LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc,to); + LinphoneChatRoom* chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity); LinphoneChatMessage* message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu"); lcs=ms_list_append(lcs,pauline->lc); @@ -119,19 +116,18 @@ static void message_forking_with_unreachable_recipients(void) { linphone_core_manager_destroy(marie); linphone_core_manager_destroy(marie2); + linphone_core_manager_destroy(marie3); linphone_core_manager_destroy(pauline); - ms_free(to); ms_list_free(lcs); } static void message_forking_with_all_recipients_unreachable(void) { - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCoreManager* marie2 = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* marie3 = linphone_core_manager_new( "marie_rc"); MSList* lcs=ms_list_append(NULL,marie->lc); - char* to = linphone_address_as_string(marie->identity); - LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc,to); + LinphoneChatRoom* chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity); LinphoneChatMessage* message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu"); lcs=ms_list_append(lcs,pauline->lc); @@ -169,14 +165,14 @@ static void message_forking_with_all_recipients_unreachable(void) { linphone_core_manager_destroy(marie); linphone_core_manager_destroy(marie2); + linphone_core_manager_destroy(marie3); linphone_core_manager_destroy(pauline); - ms_free(to); ms_list_free(lcs); } static void call_forking(void){ - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCoreManager* marie2 = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* marie3 = linphone_core_manager_new( "marie_rc"); MSList* lcs=ms_list_append(NULL,pauline->lc); @@ -221,43 +217,43 @@ static void call_forking(void){ } static void call_forking_with_urgent_reply(void){ - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCoreManager* marie2 = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* 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); + if (linphone_core_media_encryption_supported(pauline->lc,LinphoneMediaEncryptionSRTP)) { + 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); - BC_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*/ - BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,9000)); - /*Marie should be ringing*/ - BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,1000)); + linphone_core_set_media_encryption(pauline->lc,LinphoneMediaEncryptionSRTP); + linphone_core_set_network_reachable(marie2->lc,FALSE); + linphone_core_set_network_reachable(marie3->lc,FALSE); - /*marie accepts the call on its first device*/ - linphone_core_accept_call(marie->lc,linphone_core_get_current_call(marie->lc)); - BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,1000)); - BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,1000)); - BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallConnected,1,1000)); - BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,1000)); + linphone_core_invite_address(pauline->lc,marie->identity); + /*pauline should hear ringback, after 5 seconds, when it will retry without SRTP*/ + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,9000)); + /*Marie should be ringing*/ + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,1000)); - linphone_core_terminate_call(pauline->lc,linphone_core_get_current_call(pauline->lc)); - BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000)); - BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000)); + /*marie accepts the call on its first device*/ + linphone_core_accept_call(marie->lc,linphone_core_get_current_call(marie->lc)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallConnected,1,1000)); + BC_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)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000)); + } linphone_core_manager_destroy(pauline); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(marie2); @@ -266,8 +262,8 @@ static void call_forking_with_urgent_reply(void){ } static void call_forking_cancelled(void){ - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCoreManager* marie2 = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* marie3 = linphone_core_manager_new( "marie_rc"); MSList* lcs=ms_list_append(NULL,pauline->lc); @@ -306,8 +302,8 @@ static void call_forking_cancelled(void){ } static void call_forking_declined(bool_t declined_globaly){ - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCoreManager* marie2 = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* marie3 = linphone_core_manager_new( "marie_rc"); MSList* lcs=ms_list_append(NULL,pauline->lc); @@ -329,7 +325,7 @@ static void call_forking_declined(bool_t declined_globaly){ BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallIncomingReceived,1,1000)); BC_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallIncomingReceived,1,1000)); - /*marie1 finally declines the call*/ + /*marie finally declines the call*/ linphone_core_decline_call(marie->lc,linphone_core_get_current_call(marie->lc), declined_globaly ? LinphoneReasonDeclined : LinphoneReasonBusy ); @@ -370,22 +366,29 @@ static void call_forking_declined_localy(void){ 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"); + LinphoneCoreManager* marie = linphone_core_manager_new2( "marie_rc", FALSE); + LinphoneCoreManager* pauline = linphone_core_manager_new2( transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc",FALSE); + int dummy=0; linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL); linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL); + linphone_proxy_config_set_contact_uri_parameters( + linphone_core_get_default_proxy_config(marie->lc), + "app-id=org.linphonetester;pn-tok=aaabbb;pn-type=apple;pn-msg-str=33;pn-call-str=34;"); lcs=ms_list_append(NULL,pauline->lc); - lcs=ms_list_append(lcs,marie->lc); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneRegistrationOk,1,5000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneRegistrationOk,1,5000)); + /*unfortunately marie gets unreachable due to crappy 3G operator or iOS bug...*/ linphone_core_set_network_reachable(marie->lc,FALSE); linphone_core_invite_address(pauline->lc,marie->identity); - /*the server is expected to send a push notification to marie, this will wake up linphone, that will reconnect:*/ + /*After 5 seconds the server is expected to send a push notification to marie, this will wake up linphone, that will reconnect:*/ + wait_for_list(lcs,&dummy,1,6000); linphone_core_set_network_reachable(marie->lc,TRUE); /*Marie shall receive the call immediately*/ @@ -412,8 +415,8 @@ static void call_forking_with_push_notification_single(void){ } 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* pauline = linphone_core_manager_new( transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCoreManager* marie2 = linphone_core_manager_new( "marie_rc"); MSList* lcs=ms_list_append(NULL,pauline->lc); @@ -430,7 +433,7 @@ static void call_forking_with_push_notification_multiple(void){ linphone_core_invite_address(pauline->lc,marie->identity); - /*marie1 will ring*/ + /*marie will ring*/ BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,5000)); /*pauline should hear ringback as well*/ BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,1000)); @@ -448,7 +451,7 @@ static void call_forking_with_push_notification_multiple(void){ BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallConnected,1,1000)); BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallStreamsRunning,1,1000)); - /*call to marie1 should be cancelled*/ + /*call to marie should be cancelled*/ BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000)); liblinphone_tester_check_rtcp(pauline,marie2); @@ -464,8 +467,8 @@ static void call_forking_with_push_notification_multiple(void){ } static void call_forking_not_responded(void){ - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCoreManager* marie2 = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* marie3 = linphone_core_manager_new( "marie_rc"); MSList* lcs=ms_list_append(NULL,pauline->lc); @@ -502,64 +505,57 @@ static void call_forking_not_responded(void){ } static void early_media_call_forking(void) { - LinphoneCoreManager* pauline = linphone_core_manager_new("pauline_tcp_rc"); - LinphoneCoreManager* marie1 = linphone_core_manager_new("marie_early_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_early_rc"); LinphoneCoreManager* marie2 = linphone_core_manager_new("marie_early_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); MSList *lcs=NULL; - LinphoneCallParams *params=linphone_core_create_default_call_parameters(pauline->lc); + LinphoneCallParams *params=linphone_core_create_call_params(pauline->lc, NULL); LinphoneVideoPolicy pol; - LinphoneCall *marie1_call; - LinphoneCall *marie2_call; - LinphoneCall *pauline_call; int dummy=0; pol.automatically_accept=1; pol.automatically_initiate=1; - linphone_core_set_user_agent(marie1->lc,"Natted Linphone",NULL); + linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL); linphone_core_set_user_agent(marie2->lc,"Natted Linphone",NULL); linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL); linphone_core_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(marie->lc,TRUE,TRUE); + linphone_core_set_video_policy(marie->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,marie->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_core_invite_address_with_params(pauline->lc,marie->identity,params); linphone_call_params_destroy(params); - BC_ASSERT_TRUE(wait_for_list(lcs, &marie1->stat.number_of_LinphoneCallIncomingEarlyMedia,1,3000)); + BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallIncomingEarlyMedia,1,3000)); BC_ASSERT_TRUE(wait_for_list(lcs, &marie2->stat.number_of_LinphoneCallIncomingEarlyMedia,1,3000)); BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallOutgoingEarlyMedia,1,3000)); BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallOutgoingEarlyMedia,1, int, "%d"); - 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); - BC_ASSERT_GREATER(linphone_call_get_audio_stats(pauline_call)->download_bandwidth, 60, int, "%d"); - BC_ASSERT_LOWER(linphone_call_get_audio_stats(pauline_call)->download_bandwidth, 99, int, "%d"); - BC_ASSERT_GREATER(linphone_call_get_audio_stats(marie1_call)->download_bandwidth, 60, int, "%d"); - BC_ASSERT_LOWER(linphone_call_get_audio_stats(marie1_call)->download_bandwidth, 99, int, "%d"); - BC_ASSERT_GREATER(linphone_call_get_audio_stats(marie2_call)->download_bandwidth, 60, int, "%d"); - BC_ASSERT_LOWER(linphone_call_get_audio_stats(marie2_call)->download_bandwidth, 99, int, "%d"); + wait_for_list(lcs,&dummy,1,5000); + BC_ASSERT_GREATER(linphone_core_manager_get_mean_audio_down_bw(pauline), 60, int, "%d"); + BC_ASSERT_LOWER(linphone_core_manager_get_mean_audio_down_bw(pauline), 99, int, "%d"); + BC_ASSERT_GREATER(linphone_core_manager_get_mean_audio_down_bw(marie), 60, int, "%d"); + BC_ASSERT_LOWER(linphone_core_manager_get_mean_audio_down_bw(marie), 99, int, "%d"); + BC_ASSERT_GREATER(linphone_core_manager_get_mean_audio_down_bw(marie2), 60, int, "%d"); + BC_ASSERT_LOWER(linphone_core_manager_get_mean_audio_down_bw(marie2), 99, int, "%d"); - linphone_core_accept_call(marie1->lc,linphone_core_get_current_call(marie1->lc)); - BC_ASSERT_TRUE(wait_for_list(lcs,&marie1->stat.number_of_LinphoneCallStreamsRunning,1,3000)); + linphone_core_accept_call(marie->lc,linphone_core_get_current_call(marie->lc)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,3000)); BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,3000)); /*marie2 should get her call terminated*/ @@ -567,97 +563,97 @@ static void early_media_call_forking(void) { /*wait a bit that streams are established*/ wait_for_list(lcs,&dummy,1,3000); - BC_ASSERT_GREATER(linphone_call_get_audio_stats(pauline_call)->download_bandwidth, 60, int, "%d"); - BC_ASSERT_LOWER(linphone_call_get_audio_stats(pauline_call)->download_bandwidth, 99, int, "%d"); - BC_ASSERT_GREATER(linphone_call_get_audio_stats(marie1_call)->download_bandwidth, 60, int, "%d"); - BC_ASSERT_LOWER(linphone_call_get_audio_stats(marie1_call)->download_bandwidth, 99, int, "%d"); + BC_ASSERT_GREATER(linphone_core_manager_get_mean_audio_down_bw(pauline), 60, int, "%d"); + BC_ASSERT_LOWER(linphone_core_manager_get_mean_audio_down_bw(pauline), 99, int, "%d"); + BC_ASSERT_GREATER(linphone_core_manager_get_mean_audio_down_bw(marie), 60, int, "%d"); + BC_ASSERT_LOWER(linphone_core_manager_get_mean_audio_down_bw(marie), 99, int, "%d"); - linphone_core_terminate_all_calls(pauline->lc); - BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,5000)); - BC_ASSERT_TRUE(wait_for_list(lcs,&marie1->stat.number_of_LinphoneCallEnd,1,5000)); + end_call(pauline, marie); ms_list_free(lcs); - linphone_core_manager_destroy(marie1); - linphone_core_manager_destroy(marie2); linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(marie2); + linphone_core_manager_destroy(marie); } static void call_with_sips(void){ - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_sips_rc"); - 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); + if (transport_supported(LinphoneTransportTls)) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_sips_rc"); + 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); + 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_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); + linphone_core_invite_address(marie->lc,pauline1->identity); - /*marie should hear ringback*/ - BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallOutgoingRinging,1,3000)); - /*Only the sips registered device from pauline should ring*/ - BC_ASSERT_TRUE(wait_for_list(lcs,&pauline1->stat.number_of_LinphoneCallIncomingReceived,1,1000)); + /*marie should hear ringback*/ + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallOutgoingRinging,1,3000)); + /*Only the sips registered device from pauline should ring*/ + BC_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)); - BC_ASSERT_TRUE(wait_for_list(lcs,&pauline1->stat.number_of_LinphoneCallConnected,1,1000)); - BC_ASSERT_TRUE(wait_for_list(lcs,&pauline1->stat.number_of_LinphoneCallStreamsRunning,1,1000)); - BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallConnected,1,1000)); - BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,1000)); + /*pauline accepts the call */ + linphone_core_accept_call(pauline1->lc,linphone_core_get_current_call(pauline1->lc)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline1->stat.number_of_LinphoneCallConnected,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline1->stat.number_of_LinphoneCallStreamsRunning,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallConnected,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,1000)); - /*pauline2 should not have ring*/ - BC_ASSERT_EQUAL(pauline2->stat.number_of_LinphoneCallIncomingReceived, 0, int, "%d"); + /*pauline2 should not have ring*/ + BC_ASSERT_EQUAL(pauline2->stat.number_of_LinphoneCallIncomingReceived, 0, int, "%d"); - linphone_core_terminate_call(pauline1->lc,linphone_core_get_current_call(pauline1->lc)); - BC_ASSERT_TRUE(wait_for_list(lcs,&pauline1->stat.number_of_LinphoneCallEnd,1,3000)); - BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,3000)); + linphone_core_terminate_call(pauline1->lc,linphone_core_get_current_call(pauline1->lc)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline1->stat.number_of_LinphoneCallEnd,1,3000)); + BC_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); - ms_list_free(lcs); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline1); + linphone_core_manager_destroy(pauline2); + ms_list_free(lcs); + } } static void call_with_sips_not_achievable(void){ - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_sips_rc"); - LinphoneCoreManager* pauline1 = linphone_core_manager_new( "pauline_rc"); - LinphoneCoreManager* pauline2 = linphone_core_manager_new( "pauline_tcp_rc"); - MSList* lcs=ms_list_append(NULL,marie->lc); - LinphoneAddress *dest; - LinphoneCall *call; - const LinphoneErrorInfo *ei; + if (transport_supported(LinphoneTransportTls)) { + LinphoneCoreManager* pauline2 = linphone_core_manager_new( "pauline_tcp_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_sips_rc"); + LinphoneCoreManager* pauline1 = linphone_core_manager_new( "pauline_rc"); + MSList* lcs=ms_list_append(NULL,marie->lc); + LinphoneAddress *dest; + LinphoneCall *call; + const LinphoneErrorInfo *ei; - lcs=ms_list_append(lcs,pauline1->lc); - lcs=ms_list_append(lcs,pauline2->lc); + 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); - linphone_call_ref(call); - linphone_address_unref(dest); + dest=linphone_address_clone(pauline1->identity); + linphone_address_set_secure(dest,TRUE); + call=linphone_core_invite_address(marie->lc,dest); + linphone_call_ref(call); + linphone_address_unref(dest); - /*Call should be rejected by server with 480*/ - BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallError,1,6000)); - ei=linphone_call_get_error_info(call); - BC_ASSERT_PTR_NOT_NULL(ei); - if (ei){ - BC_ASSERT_EQUAL(linphone_error_info_get_reason(ei), LinphoneReasonTemporarilyUnavailable, int, "%d"); + /*Call should be rejected by server with 480*/ + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallError,1,6000)); + ei=linphone_call_get_error_info(call); + BC_ASSERT_PTR_NOT_NULL(ei); + if (ei){ + BC_ASSERT_EQUAL(linphone_error_info_get_reason(ei), LinphoneReasonTemporarilyUnavailable, int, "%d"); + } + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline1); + linphone_core_manager_destroy(pauline2); + ms_list_free(lcs); } - - linphone_core_manager_destroy(marie); - linphone_core_manager_destroy(pauline1); - linphone_core_manager_destroy(pauline2); - ms_list_free(lcs); } static void call_with_ipv6(void) { - int begin; - int leaked_objects; LinphoneCoreManager* marie; LinphoneCoreManager* pauline; LinphoneCall *pauline_call; @@ -670,12 +666,9 @@ static void call_with_ipv6(void) { return; } - belle_sip_object_enable_leak_detector(TRUE); - begin=belle_sip_object_get_object_count(); - liblinphone_tester_enable_ipv6(TRUE); marie = linphone_core_manager_new( "marie_rc"); - pauline = linphone_core_manager_new( "pauline_rc"); + pauline = linphone_core_manager_new( transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL); linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL); @@ -705,98 +698,90 @@ static void call_with_ipv6(void) { linphone_core_manager_destroy(pauline); liblinphone_tester_enable_ipv6(FALSE); - leaked_objects=belle_sip_object_get_object_count()-begin; - BC_ASSERT_EQUAL(leaked_objects, 0, int, "%d"); - if (leaked_objects>0){ - belle_sip_object_dump_active_objects(); - } 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); + if (transport_supported(LinphoneTransportTls)) { + LinphoneCoreManager* marie = linphone_core_manager_init( "marie_rc"); + LinphoneChatRoom* chat_room; + LinphoneChatMessage* message; + LinphoneChatMessageCbs *cbs; + LinphoneContent* content; + FILE *file_to_send = NULL; + size_t file_size; + char *send_filepath = bc_tester_res("images/nowebcamCIF.jpg"); + char *receive_filepath = bc_tester_file("receive_file.dump"); + LinphoneCoreManager* pauline = linphone_core_manager_init( "pauline_rc"); - 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(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); - 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); - BC_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); - } - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageFileTransferDone,1)); - BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1, int, "%d"); - BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageDelivered,1, int, "%d"); - BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageExtBodyReceived,1, int, "%d"); - BC_ASSERT_TRUE(compare_files(send_filepath, receive_filepath)); + 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); - linphone_content_unref(content); - linphone_core_manager_destroy(marie); - linphone_core_manager_destroy(pauline); - ms_free(send_filepath); - ms_free(receive_filepath); + /* 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 */ + + chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity); + /* 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, tester_file_transfer_send); + linphone_chat_room_send_chat_message(chat_room,message); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageExtBodyReceived,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); + } + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageFileTransferDone,1)); + + BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,2, int, "%d"); + BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageDelivered,1, int, "%d"); + BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageExtBodyReceived,1, int, "%d"); + 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; +void send_file_transfer_message_using_external_body_url(LinphoneCoreManager *marie, LinphoneCoreManager *pauline) { 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); + chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity); message = linphone_chat_room_create_message(chat_room, NULL); @@ -817,81 +802,86 @@ static void send_file_transfer_message_using_external_body_url(LinphoneCoreManag } 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"); + if (transport_supported(LinphoneTransportTls)) { + 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(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); + 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); + reset_counters(&marie->stat); + reset_counters(&pauline->stat); - linphone_core_refresh_registers(marie->lc); - linphone_core_refresh_registers(pauline->lc); + linphone_core_refresh_registers(marie->lc); + linphone_core_refresh_registers(pauline->lc); - send_file_transfer_message_using_external_body_url(marie, pauline); + send_file_transfer_message_using_external_body_url(marie, pauline); - linphone_core_manager_destroy(marie); - linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(marie); + } } 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"); + if (transport_supported(LinphoneTransportTls)) { + 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(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); + 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); + reset_counters(&marie->stat); + reset_counters(&pauline->stat); - send_file_transfer_message_using_external_body_url(marie, pauline); + send_file_transfer_message_using_external_body_url(marie, pauline); - linphone_core_manager_destroy(marie); - linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(marie); + } } static void dos_module_trigger(void) { - char *to; LinphoneChatRoom *chat_room; int i = 0; + const char* passmsg = "This one should pass through"; int number_of_messge_to_send = 100; LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new("pauline_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); reset_counters(&marie->stat); reset_counters(&pauline->stat); - to = linphone_address_as_string(marie->identity); - chat_room = linphone_core_create_chat_room(pauline->lc,to); + chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity); do { char msg[128]; sprintf(msg, "Flood message number %i", i); linphone_chat_room_send_message(chat_room, msg); - ms_usleep(100000); + ms_usleep(10000); i++; } while (i < number_of_messge_to_send); // At this point we should be banned for a minute - ms_usleep(90000000); // Wait 90 seconds to ensure we are not banned anymore + ms_usleep(65000000); // Wait several seconds to ensure we are not banned anymore BC_ASSERT_LOWER(marie->stat.number_of_LinphoneMessageReceived, number_of_messge_to_send, int, "%d"); reset_counters(&marie->stat); reset_counters(&pauline->stat); - linphone_chat_room_send_message(chat_room, "This one should pass through"); + linphone_chat_room_send_message(chat_room, passmsg); BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived, 1)); - + BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageReceived, 1, int, "%d"); + if (marie->stat.last_received_chat_message) { + BC_ASSERT_NSTRING_EQUAL(linphone_chat_message_get_text(marie->stat.last_received_chat_message), passmsg, strlen(passmsg)); + } linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); - ms_free(to); } test_t flexisip_tests[] = { @@ -917,13 +907,5 @@ test_t flexisip_tests[] = { { "DoS module trigger by sending a lot of chat messages", dos_module_trigger } }; - -test_suite_t flexisip_test_suite = { - "Flexisip", - NULL, - NULL, - sizeof(flexisip_tests) / sizeof(flexisip_tests[0]), - flexisip_tests -}; - - +test_suite_t flexisip_test_suite = {"Flexisip", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each, + sizeof(flexisip_tests) / sizeof(flexisip_tests[0]), flexisip_tests}; diff --git a/tester/liblinphone_tester.c b/tester/liblinphone_tester.c index d4f42190d..2363fb886 100644 --- a/tester/liblinphone_tester.c +++ b/tester/liblinphone_tester.c @@ -23,10 +23,21 @@ #if HAVE_CU_CURSES #include "CUnit/CUCurses.h" #endif + +#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4) +#pragma GCC diagnostic push +#endif +#pragma GCC diagnostic ignored "-Wstrict-prototypes" + #ifdef HAVE_GTK #include #endif +#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4) +#pragma GCC diagnostic pop +#endif + + static FILE * log_file = NULL; #ifdef ANDROID @@ -122,14 +133,8 @@ JNIEXPORT void JNICALL Java_org_linphone_tester_Tester_clearAccounts(JNIEnv *env } #endif /* ANDROID */ -#ifdef __QNX__ -static void liblinphone_tester_qnx_log_handler(OrtpLogLevel lev, const char *fmt, va_list args) { - ortp_qnx_log_handler("liblinphone_tester", lev, fmt, args); -} -#endif /* __QNX__ */ - static void log_handler(int lev, const char *fmt, va_list args) { -#ifdef WIN32 +#ifdef _WIN32 vfprintf(lev == ORTP_ERROR ? stderr : stdout, fmt, args); fprintf(lev == ORTP_ERROR ? stderr : stdout, "\n"); #else @@ -150,34 +155,45 @@ static void log_handler(int lev, const char *fmt, va_list args) { } } -void liblinphone_tester_init(void) { +void liblinphone_tester_init(void(*ftester_printf)(int level, const char *fmt, va_list args)) { if (! log_file) { #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); #endif } - bc_tester_init(log_handler, ORTP_MESSAGE, ORTP_ERROR); + if (ftester_printf == NULL) ftester_printf = log_handler; + bc_tester_init(ftester_printf, ORTP_MESSAGE, ORTP_ERROR); liblinphone_tester_add_suites(); } -void liblinphone_tester_uninit(void) { - bc_tester_uninit(); +int liblinphone_tester_set_log_file(const char *filename) { + if (log_file) { + fclose(log_file); + } + log_file = fopen(filename, "w"); + if (!log_file) { + ms_error("Cannot open file [%s] for writing logs because [%s]", filename, strerror(errno)); + return -1; + } + ms_message("Redirecting traces to file [%s]", filename); + ortp_set_log_file(log_file); + return 0; } +#if !TARGET_OS_IPHONE && !(defined(LINPHONE_WINDOWS_PHONE) || defined(LINPHONE_WINDOWS_UNIVERSAL)) + 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"; + "\t\t\t--dns-hosts \n" + "\t\t\t--keep-recorded-files\n" + "\t\t\t--disable-leak-detector\n"; -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) int main (int argc, char *argv[]) { int i; @@ -191,49 +207,45 @@ int main (int argc, char *argv[]) gdk_threads_init(); #endif - liblinphone_tester_init(); + liblinphone_tester_init(NULL); for(i = 1; i < argc; ++i) { if (strcmp(argv[i], "--verbose") == 0) { - linphone_core_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL); + linphone_core_set_log_level(ORTP_MESSAGE); } else if (strcmp(argv[i], "--silent") == 0) { - linphone_core_set_log_level_mask(ORTP_FATAL); + linphone_core_set_log_level(ORTP_FATAL); } else if (strcmp(argv[i],"--log-file")==0){ CHECK_ARG("--log-file", ++i, argc); - log_file=fopen(argv[i],"w"); - if (!log_file) { - ms_error("Cannot open file [%s] for writing logs because [%s]",argv[i],strerror(errno)); - return -2; - } else { - ms_message("Redirecting traces to file [%s]",argv[i]); - ortp_set_log_file(log_file); - } + if (liblinphone_tester_set_log_file(argv[i]) < 0) return -2; } else if (strcmp(argv[i],"--domain")==0){ CHECK_ARG("--domain", ++i, argc); test_domain=argv[i]; } else if (strcmp(argv[i],"--auth-domain")==0){ CHECK_ARG("--auth-domain", ++i, argc); auth_domain=argv[i]; - } else if (strcmp(argv[i],"--config")==0){ - CHECK_ARG("--config", ++i, argc); - bc_tester_read_dir_prefix=argv[i]; }else if (strcmp(argv[i],"--dns-hosts")==0){ CHECK_ARG("--dns-hosts", ++i, argc); userhostsfile=argv[i]; + } else if (strcmp(argv[i],"--keep-recorded-files")==0){ + liblinphone_tester_keep_recorded_files(TRUE); + } else if (strcmp(argv[i],"--disable-leak-detector")==0){ + liblinphone_tester_disable_leak_detector(TRUE); } else { - int ret = bc_tester_parse_args(argc, argv, i); - if (ret>0) { - i += ret - 1; + int bret = bc_tester_parse_args(argc, argv, i); + if (bret>0) { + i += bret - 1; continue; - } else if (ret<0) { + } else if (bret<0) { bc_tester_helper(argv[0], liblinphone_helper); } - return ret; + return bret; } } - ret = bc_tester_start(); + ret = bc_tester_start(argv[0]); liblinphone_tester_uninit(); return ret; } + + #endif diff --git a/tester/liblinphone_tester.h b/tester/liblinphone_tester.h index 4fb0e2fa0..4cbe28046 100644 --- a/tester/liblinphone_tester.h +++ b/tester/liblinphone_tester.h @@ -24,6 +24,7 @@ #include "bc_tester_utils.h" #include "linphonecore.h" +#include #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -44,14 +45,18 @@ extern test_suite_t stun_test_suite; extern test_suite_t remote_provisioning_test_suite; extern test_suite_t quality_reporting_test_suite; extern test_suite_t log_collection_test_suite; -extern test_suite_t transport_test_suite; +extern test_suite_t tunnel_test_suite; extern test_suite_t player_test_suite; 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 test_suite_t proxy_config_test_suite; +#if HAVE_SIPP +extern test_suite_t complex_sip_call_test_suite; +#endif +extern int manager_count; extern int liblinphone_tester_ipv6_available(void); @@ -68,15 +73,23 @@ extern int liblinphone_tester_ipv6_available(void); */ extern void liblinphone_tester_keep_accounts( int keep ); +/** + * @brief Tells the test whether to not remove recorded audio/video files after the tests. + * @details By default recorded files are erased after the test, unless the test is failed. +**/ +void liblinphone_tester_keep_recorded_files(int keep); + +/** + * @brief Disable the automatic object leak detection. This is useful because the object leak detector prevents valgrind from seeing the leaks. + * @details By default object leak detector is enabled. +**/ +void liblinphone_tester_disable_leak_detector(int disabled); + /** * @brief Clears the created accounts during the testing session. */ extern void liblinphone_tester_clear_accounts(void); -#ifdef __cplusplus -}; -#endif - extern const char* test_domain; extern const char* auth_domain; @@ -204,7 +217,8 @@ typedef struct _stats { int number_of_LinphoneCallStatsUpdated; int number_of_rtcp_sent; - int number_of_rtcp_received; + int number_of_rtcp_received; /*total number of rtcp packet received */ + int number_of_rtcp_received_via_mux;/*number of rtcp packet received in rtcp-mux mode*/ int number_of_video_windows_created; @@ -212,13 +226,19 @@ typedef struct _stats { int number_of_LinphoneCoreLogCollectionUploadStateDelivered; int number_of_LinphoneCoreLogCollectionUploadStateNotDelivered; int number_of_LinphoneCoreLogCollectionUploadStateInProgress; - int audio_download_bandwidth; - int audio_upload_bandwidth; - int video_download_bandwidth; - int video_upload_bandwidth; + int audio_download_bandwidth[3]; + int *current_audio_download_bandwidth; + int audio_upload_bandwidth[3]; + int *current_audio_upload_bandwidth; + int video_download_bandwidth[3]; + int video_upload_bandwidth[3]; + int current_bandwidth_index; + + int number_of_rtcp_generic_nack; }stats; + typedef struct _LinphoneCoreManager { LinphoneCoreVTable v_table; LinphoneCore* lc; @@ -236,7 +256,7 @@ typedef struct _LinphoneCallTestParams { } LinphoneCallTestParams; -void liblinphone_tester_add_suites(); +void liblinphone_tester_add_suites(void); LinphoneCoreManager* linphone_core_manager_init(const char* rc_file); void linphone_core_manager_start(LinphoneCoreManager *mgr, const char* rc_file, int check_for_proxies); @@ -254,8 +274,8 @@ void notify_presence_received(LinphoneCore *lc, LinphoneFriend * lf); void text_message_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from_address, const char *message); void message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage* message); void file_transfer_received(LinphoneChatMessage *message, const LinphoneContent* content, const LinphoneBuffer *buffer); -LinphoneBuffer * file_transfer_send(LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t size); -LinphoneBuffer * memory_file_transfer_send(LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t size); +LinphoneBuffer * tester_file_transfer_send(LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t size); +LinphoneBuffer * tester_memory_file_transfer_send(LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t size); void file_transfer_progress_indication(LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t total); void is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room); void info_message_received(LinphoneCore *lc, LinphoneCall *call, const LinphoneInfoMessage *msg); @@ -288,6 +308,7 @@ void end_call(LinphoneCoreManager *m1, LinphoneCoreManager *m2); void disable_all_audio_codecs_except_one(LinphoneCore *lc, const char *mime, int rate); void disable_all_video_codecs_except_one(LinphoneCore *lc, const char *mime); stats * get_stats(LinphoneCore *lc); +bool_t transport_supported(LinphoneTransportType transport); LinphoneCoreManager *get_manager(LinphoneCore *lc); const char *liblinphone_tester_get_subscribe_content(void); const char *liblinphone_tester_get_notify_content(void); @@ -300,17 +321,39 @@ 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); -void linphone_call_cb(LinphoneCall *call,void * user_data); +void linphone_call_iframe_decoded_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_with_configfile(LinphoneMediaEncryption mode, bool_t enable_video,bool_t enable_relay,LinphoneFirewallPolicy policy,bool_t enable_tunnel, const char *marie_rc, const char *pauline_rc); 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); +void compare_files(const char *path1, const char *path2); void check_media_direction(LinphoneCoreManager* mgr, LinphoneCall *call, MSList* lcs,LinphoneMediaDirection audio_dir, LinphoneMediaDirection video_dir); -static const int audio_cmp_max_shift=20; +extern const MSAudioDiffParams audio_cmp_params; + +/* + * this function return max value in the last 3 seconds*/ +int linphone_core_manager_get_max_audio_down_bw(const LinphoneCoreManager *mgr); +int linphone_core_manager_get_max_audio_up_bw(const LinphoneCoreManager *mgr); +int linphone_core_manager_get_mean_audio_down_bw(const LinphoneCoreManager *mgr); +int linphone_core_manager_get_mean_audio_up_bw(const LinphoneCoreManager *mgr); + +void video_call_base_2(LinphoneCoreManager* pauline,LinphoneCoreManager* marie, bool_t using_policy,LinphoneMediaEncryption mode, bool_t callee_video_enabled, bool_t caller_video_enabled); + +void liblinphone_tester_before_each(void); +void liblinphone_tester_after_each(void); +void liblinphone_tester_init(void(*ftester_printf)(int level, const char *fmt, va_list args)); +void liblinphone_tester_uninit(void); +int liblinphone_tester_set_log_file(const char *filename); +bool_t check_ice(LinphoneCoreManager* caller, LinphoneCoreManager* callee, LinphoneIceState state); + +extern const char *liblinphone_tester_mire_id; + + +#ifdef __cplusplus +}; +#endif #endif /* LIBLINPHONE_TESTER_H_ */ - diff --git a/tester/liblinphone_tester_windows.cpp b/tester/liblinphone_tester_windows.cpp new file mode 100644 index 000000000..838ea52be --- /dev/null +++ b/tester/liblinphone_tester_windows.cpp @@ -0,0 +1,153 @@ +#include + +#include "liblinphone_tester_windows.h" + +using namespace liblinphone_tester_runtime_component; +using namespace Platform; +using namespace Windows::Foundation; +using namespace Windows::Storage; +using namespace Windows::System::Threading; + +#define MAX_TRACE_SIZE 2048 +#define MAX_SUITE_NAME_SIZE 128 +#define MAX_WRITABLE_DIR_SIZE 1024 + +static OutputTraceListener^ sTraceListener; + +LibLinphoneTester^ LibLinphoneTester::_instance = ref new LibLinphoneTester(); + +static void nativeOutputTraceHandler(int lev, const char *fmt, va_list args) +{ + if (sTraceListener) { + wchar_t wstr[MAX_TRACE_SIZE] = { 0 }; + std::string str; + str.resize(MAX_TRACE_SIZE); + vsnprintf((char *)str.c_str(), MAX_TRACE_SIZE, fmt, args); + mbstowcs(wstr, str.c_str(), MAX_TRACE_SIZE - 1); + String^ msg = ref new String(wstr); + String^ l; + switch (lev) { + case ORTP_FATAL: + case ORTP_ERROR: + l = ref new String(L"Error"); + break; + case ORTP_WARNING: + l = ref new String(L"Warning"); + break; + case ORTP_MESSAGE: + l = ref new String(L"Message"); + break; + default: + l = ref new String(L"Debug"); + break; + } + sTraceListener->outputTrace(l, msg); + } +} + +static void libLinphoneNativeOutputTraceHandler(OrtpLogLevel lev, const char *fmt, va_list args) +{ + nativeOutputTraceHandler((int)lev, fmt, args); +} + + +LibLinphoneTester::LibLinphoneTester() +{ +} + +LibLinphoneTester::~LibLinphoneTester() +{ + liblinphone_tester_uninit(); +} + +void LibLinphoneTester::setOutputTraceListener(OutputTraceListener^ traceListener) +{ + sTraceListener = traceListener; +} + +void LibLinphoneTester::initialize(StorageFolder^ writableDirectory, Platform::Boolean ui) +{ + if (ui) { + liblinphone_tester_init(nativeOutputTraceHandler); + } else { + liblinphone_tester_init(NULL); + linphone_core_set_log_level_mask((OrtpLogLevel)(ORTP_MESSAGE | ORTP_WARNING | ORTP_ERROR | ORTP_FATAL)); + } + + char writable_dir[MAX_WRITABLE_DIR_SIZE] = { 0 }; + const wchar_t *wwritable_dir = writableDirectory->Path->Data(); + wcstombs(writable_dir, wwritable_dir, sizeof(writable_dir)); + bc_tester_set_writable_dir_prefix(writable_dir); + bc_tester_set_resource_dir_prefix("Assets"); + + if (!ui) { + char *xmlFile = bc_tester_file("LibLinphoneWindows10.xml"); + char *args[] = { "--xml-file", xmlFile }; + bc_tester_parse_args(2, args, 0); + + char *logFile = bc_tester_file("LibLinphoneWindows10.log"); + liblinphone_tester_set_log_file(logFile); + free(logFile); + } +} + +bool LibLinphoneTester::run(Platform::String^ suiteName, Platform::String^ caseName, Platform::Boolean verbose) +{ + std::wstring all(L"ALL"); + std::wstring wssuitename = suiteName->Data(); + std::wstring wscasename = caseName->Data(); + char csuitename[MAX_SUITE_NAME_SIZE] = { 0 }; + char ccasename[MAX_SUITE_NAME_SIZE] = { 0 }; + wcstombs(csuitename, wssuitename.c_str(), sizeof(csuitename)); + wcstombs(ccasename, wscasename.c_str(), sizeof(ccasename)); + + if (verbose) { + linphone_core_set_log_level_mask((OrtpLogLevel)(ORTP_MESSAGE | ORTP_WARNING | ORTP_ERROR | ORTP_FATAL)); + } + else { + linphone_core_set_log_level_mask(ORTP_FATAL); + } + linphone_core_set_log_handler(libLinphoneNativeOutputTraceHandler); + return bc_tester_run_tests(wssuitename == all ? 0 : csuitename, wscasename == all ? 0 : ccasename) != 0; +} + +void LibLinphoneTester::runAllToXml() +{ + auto workItem = ref new WorkItemHandler([this](IAsyncAction ^workItem) { + bc_tester_start(NULL); + bc_tester_uninit(); + }); + _asyncAction = ThreadPool::RunAsync(workItem); +} + +unsigned int LibLinphoneTester::nbTestSuites() +{ + return bc_tester_nb_suites(); +} + +unsigned int LibLinphoneTester::nbTests(Platform::String^ suiteName) +{ + std::wstring suitename = suiteName->Data(); + char cname[MAX_SUITE_NAME_SIZE] = { 0 }; + wcstombs(cname, suitename.c_str(), sizeof(cname)); + return bc_tester_nb_tests(cname); +} + +Platform::String^ LibLinphoneTester::testSuiteName(int index) +{ + const char *cname = bc_tester_suite_name(index); + wchar_t wcname[MAX_SUITE_NAME_SIZE]; + mbstowcs(wcname, cname, sizeof(wcname)); + return ref new String(wcname); +} + +Platform::String^ LibLinphoneTester::testName(Platform::String^ suiteName, int testIndex) +{ + std::wstring suitename = suiteName->Data(); + char csuitename[MAX_SUITE_NAME_SIZE] = { 0 }; + wcstombs(csuitename, suitename.c_str(), sizeof(csuitename)); + const char *cname = bc_tester_test_name(csuitename, testIndex); + wchar_t wcname[MAX_SUITE_NAME_SIZE]; + mbstowcs(wcname, cname, sizeof(wcname)); + return ref new String(wcname); +} diff --git a/tester/liblinphone_tester_windows.h b/tester/liblinphone_tester_windows.h new file mode 100644 index 000000000..d45a90fce --- /dev/null +++ b/tester/liblinphone_tester_windows.h @@ -0,0 +1,41 @@ +#pragma once + +#include "linphonecore.h" +#include "liblinphone_tester.h" + +namespace liblinphone_tester_runtime_component +{ + public interface class OutputTraceListener + { + public: + void outputTrace(Platform::String^ lev, Platform::String^ msg); + }; + + public ref class LibLinphoneTester sealed + { + public: + void setOutputTraceListener(OutputTraceListener^ traceListener); + unsigned int nbTestSuites(); + unsigned int nbTests(Platform::String^ suiteName); + Platform::String^ testSuiteName(int index); + Platform::String^ testName(Platform::String^ suiteName, int testIndex); + void initialize(Windows::Storage::StorageFolder^ writableDirectory, Platform::Boolean ui); + bool run(Platform::String^ suiteName, Platform::String^ caseName, Platform::Boolean verbose); + void runAllToXml(); + + static property LibLinphoneTester^ Instance + { + LibLinphoneTester^ get() { return _instance; } + } + property Windows::Foundation::IAsyncAction^ AsyncAction + { + Windows::Foundation::IAsyncAction^ get() { return _asyncAction; } + } + private: + LibLinphoneTester(); + ~LibLinphoneTester(); + + static LibLinphoneTester^ _instance; + Windows::Foundation::IAsyncAction^ _asyncAction; + }; +} \ No newline at end of file diff --git a/tester/log_collection_tester.c b/tester/log_collection_tester.c index 3d55075c7..1a074b61f 100644 --- a/tester/log_collection_tester.c +++ b/tester/log_collection_tester.c @@ -30,7 +30,7 @@ /*getline is POSIX 2008, not available on many systems.*/ -#if defined(ANDROID) || defined(WIN32) +#if defined(ANDROID) || defined(_WIN32) || defined(__QNX__) /* This code is public domain -- Will Hartung 4/9/09 */ static size_t getline(char **lineptr, size_t *n, FILE *stream) { char *bufptr = NULL; @@ -89,9 +89,9 @@ static size_t getline(char **lineptr, size_t *n, FILE *stream) { #endif static LinphoneLogCollectionState old_collection_state; -static void collect_init() { +static void collect_init(void) { old_collection_state = linphone_core_log_collection_enabled(); - linphone_core_set_log_collection_path(bc_tester_writable_dir_prefix); + linphone_core_set_log_collection_path(bc_tester_get_writable_dir_prefix()); } static void collect_cleanup(LinphoneCoreManager *marie) { @@ -108,7 +108,7 @@ static LinphoneCoreManager* setup(bool_t enable_logs) { collect_init(); linphone_core_enable_log_collection(enable_logs); - marie = linphone_core_manager_new( "marie_rc"); + marie = linphone_core_manager_new2( "marie_rc", 0); // wait a few seconds to generate some traffic while (--timeout){ // Generate some logs - error logs because we must ensure that @@ -140,17 +140,17 @@ static FILE* gzuncompress(const char* filepath) { } #endif -static time_t get_current_time() { +static time_t get_current_time(void) { struct timeval tp; struct tm *lt; -#ifndef WIN32 +#ifndef _WIN32 struct tm tmbuf; #endif time_t tt; ortp_gettimeofday(&tp,NULL); tt = (time_t)tp.tv_sec; -#ifdef WIN32 +#ifdef _WIN32 lt = localtime(&tt); #else lt = localtime_r(&tt,&tmbuf); @@ -161,7 +161,7 @@ static time_t get_current_time() { static time_t check_file(LinphoneCoreManager* mgr) { time_t cur_time = get_current_time(); - char* filepath = linphone_core_compress_log_collection(mgr->lc); + char* filepath = linphone_core_compress_log_collection(); time_t log_time = -1; uint32_t timediff = 0; FILE *file = NULL; @@ -172,7 +172,7 @@ static time_t check_file(LinphoneCoreManager* mgr) { int line_count = 0; char *line = NULL; size_t line_size = 256; -#ifndef WIN32 +#ifndef _WIN32 struct tm tm_curr = {0}; time_t time_prev = 0; #endif @@ -186,13 +186,13 @@ static time_t check_file(LinphoneCoreManager* mgr) { BC_ASSERT_PTR_NOT_NULL(file); if (!file) return 0; // 1) expect to find folder name in filename path - BC_ASSERT_PTR_NOT_NULL(strstr(filepath, bc_tester_writable_dir_prefix)); + BC_ASSERT_PTR_NOT_NULL(strstr(filepath, bc_tester_get_writable_dir_prefix())); // 2) check file contents while (getline(&line, &line_size, file) != -1) { // a) there should be at least 25 lines ++line_count; -#ifndef WIN32 +#ifndef _WIN32 // b) logs should be ordered by date (format: 2014-11-04 15:22:12:606) if (strlen(line) > 24) { char date[24] = {'\0'}; @@ -202,13 +202,13 @@ static time_t check_file(LinphoneCoreManager* mgr) { if (strptime(date, "%Y-%m-%d %H:%M:%S", &tm_curr) != NULL) { tm_curr.tm_isdst = -1; // LOL log_time = mktime(&tm_curr); - BC_ASSERT_TRUE(log_time >= time_prev); + BC_ASSERT_GREATER(log_time , time_prev, long int, "%ld"); time_prev = log_time; } } #endif } - BC_ASSERT_TRUE(line_count > 25); + BC_ASSERT_GREATER(line_count , 25, int, "%d"); free(line); fclose(file); ms_free(filepath); @@ -216,8 +216,8 @@ static time_t check_file(LinphoneCoreManager* mgr) { timediff = labs((long int)log_time - (long int)cur_time); (void)timediff; -#ifndef WIN32 - BC_ASSERT_TRUE( timediff <= 1 ); +#ifndef _WIN32 + BC_ASSERT_LOWER(timediff, 1, unsigned, "%u"); if( !(timediff <= 1) ){ char buffers[2][128] = {{0}}; strftime(buffers[0], sizeof(buffers[0]), "%Y-%m-%d %H:%M:%S", localtime(&log_time)); @@ -237,26 +237,26 @@ static time_t check_file(LinphoneCoreManager* mgr) { return log_time; } -static void collect_files_disabled() { +static void collect_files_disabled(void) { LinphoneCoreManager* marie = setup(FALSE); - BC_ASSERT_PTR_NULL(linphone_core_compress_log_collection(marie->lc)); + BC_ASSERT_PTR_NULL(linphone_core_compress_log_collection()); collect_cleanup(marie); } -static void collect_files_filled() { +static void collect_files_filled(void) { LinphoneCoreManager* marie = setup(TRUE); check_file(marie); collect_cleanup(marie); } -static void collect_files_small_size() { +static void collect_files_small_size(void) { LinphoneCoreManager* marie = setup(TRUE); linphone_core_set_log_collection_max_file_size(5000); check_file(marie); collect_cleanup(marie); } -static void collect_files_changing_size() { +static void collect_files_changing_size(void) { LinphoneCoreManager* marie = setup(TRUE); int waiting = 100; @@ -273,43 +273,47 @@ static void collect_files_changing_size() { static void logCollectionUploadStateChangedCb(LinphoneCore *lc, LinphoneCoreLogCollectionUploadState state, const char *info) { stats* counters = get_stats(lc); + ms_message("lc [%p], logCollectionUploadStateChanged to [%s], info [%s]",lc + ,linphone_core_log_collection_upload_state_to_string(state) + ,info); switch(state) { case LinphoneCoreLogCollectionUploadStateInProgress: counters->number_of_LinphoneCoreLogCollectionUploadStateInProgress++; break; case LinphoneCoreLogCollectionUploadStateDelivered: counters->number_of_LinphoneCoreLogCollectionUploadStateDelivered++; - BC_ASSERT_GREATER(strlen(info), 0, int, "%d"); + BC_ASSERT_GREATER((int)strlen(info), 0, int, "%d"); 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); +static void upload_collected_traces(void) { + if (transport_supported(LinphoneTransportTls)) { + 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); - BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphoneCoreLogCollectionUploadStateDelivered,1)); + 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(); + linphone_core_upload_log_collection(marie->lc); + BC_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); - BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphoneCoreLogCollectionUploadStateDelivered,2)); - - collect_cleanup(marie); + /*try 2 times*/ + waiting=100; + linphone_core_reset_log_collection(); + while (--waiting) ms_error("(test error)Waiting %d...", waiting); + linphone_core_compress_log_collection(); + linphone_core_upload_log_collection(marie->lc); + BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphoneCoreLogCollectionUploadStateDelivered,2)); + collect_cleanup(marie); + } } test_t log_collection_tests[] = { @@ -320,11 +324,6 @@ test_t log_collection_tests[] = { { "Upload collected traces", upload_collected_traces} }; -test_suite_t log_collection_test_suite = { - "LogCollection", - NULL, - NULL, - sizeof(log_collection_tests) / sizeof(log_collection_tests[0]), - log_collection_tests -}; - +test_suite_t log_collection_test_suite = {"LogCollection", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each, + sizeof(log_collection_tests) / sizeof(log_collection_tests[0]), + log_collection_tests}; diff --git a/tester/message_tester.c b/tester/message_tester.c index 7e27f0ff4..2b6e69aba 100644 --- a/tester/message_tester.c +++ b/tester/message_tester.c @@ -30,16 +30,16 @@ static char* message_external_body_url=NULL; -void text_message_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from_address, const char *message) { +void text_message_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from_address, const char *msg) { stats* counters = get_stats(lc); counters->number_of_LinphoneMessageReceivedLegacy++; } -void message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage* message) { - char* from=linphone_address_as_string(linphone_chat_message_get_from(message)); +void message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage* msg) { + char* from=linphone_address_as_string(linphone_chat_message_get_from(msg)); stats* counters; - const char *text=linphone_chat_message_get_text(message); - const char *external_body_url=linphone_chat_message_get_external_body_url(message); + const char *text=linphone_chat_message_get_text(msg); + const char *external_body_url=linphone_chat_message_get_external_body_url(msg); ms_message("Message from [%s] is [%s] , external URL [%s]",from?from:"" ,text?text:"" ,external_body_url?external_body_url:""); @@ -47,13 +47,13 @@ void message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMess counters = get_stats(lc); counters->number_of_LinphoneMessageReceived++; if (counters->last_received_chat_message) linphone_chat_message_unref(counters->last_received_chat_message); - counters->last_received_chat_message=linphone_chat_message_ref(message); - if (linphone_chat_message_get_file_transfer_information(message)) { + counters->last_received_chat_message=linphone_chat_message_ref(msg); + if (linphone_chat_message_get_file_transfer_information(msg)) { counters->number_of_LinphoneMessageReceivedWithFile++; - } else if (linphone_chat_message_get_external_body_url(message)) { + } else if (linphone_chat_message_get_external_body_url(msg)) { counters->number_of_LinphoneMessageExtBodyReceived++; if (message_external_body_url) { - BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_external_body_url(message),message_external_body_url); + BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_external_body_url(msg),message_external_body_url); message_external_body_url=NULL; } } @@ -62,23 +62,23 @@ void message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMess /** * function invoked when a file transfer is received. * */ -void file_transfer_received(LinphoneChatMessage *message, const LinphoneContent* content, const LinphoneBuffer *buffer){ +void file_transfer_received(LinphoneChatMessage *msg, const LinphoneContent* content, const LinphoneBuffer *buffer){ FILE* file=NULL; - char receive_file[256]; - LinphoneChatRoom *cr = linphone_chat_message_get_chat_room(message); + char *receive_file = bc_tester_file("receive_file.dump"); + LinphoneChatRoom *cr = linphone_chat_message_get_chat_room(msg); LinphoneCore *lc = linphone_chat_room_get_core(cr); - snprintf(receive_file,sizeof(receive_file), "%s/receive_file.dump", bc_tester_writable_dir_prefix); - if (!linphone_chat_message_get_user_data(message)) { + if (!linphone_chat_message_get_user_data(msg)) { /*first chunk, creating file*/ file = fopen(receive_file,"wb"); - linphone_chat_message_set_user_data(message,(void*)file); /*store fd for next chunks*/ + linphone_chat_message_set_user_data(msg,(void*)file); /*store fd for next chunks*/ } - - file = (FILE*)linphone_chat_message_get_user_data(message); - + ms_free(receive_file); + file = (FILE*)linphone_chat_message_get_user_data(msg); + BC_ASSERT_PTR_NOT_NULL(file); if (linphone_buffer_is_empty(buffer)) { /* tranfer complete */ stats* counters = get_stats(lc); counters->number_of_LinphoneFileTransferDownloadSuccessful++; + linphone_chat_message_set_user_data(msg, NULL); fclose(file); } else { /* store content on a file*/ if (fwrite(linphone_buffer_get_content(buffer),linphone_buffer_get_size(buffer),1,file)==-1){ @@ -87,54 +87,51 @@ void file_transfer_received(LinphoneChatMessage *message, const LinphoneContent* } } -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 * */ -LinphoneBuffer * file_transfer_send(LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t size){ +LinphoneBuffer * tester_file_transfer_send(LinphoneChatMessage *msg, const LinphoneContent* content, size_t offset, size_t size){ LinphoneBuffer *lb; size_t file_size; size_t size_to_send; - FILE *file_to_send; uint8_t *buf; - if (size == 0) return linphone_buffer_new(); /*end of file*/ - file_to_send = linphone_chat_message_get_user_data(message); + FILE *file_to_send = linphone_chat_message_get_user_data(msg); + + BC_ASSERT_PTR_NOT_NULL(file_to_send); + if (file_to_send == NULL){ + return NULL; + } fseek(file_to_send, 0, SEEK_END); file_size = ftell(file_to_send); - fseek(file_to_send, offset, SEEK_SET); + fseek(file_to_send, (long)offset, SEEK_SET); size_to_send = MIN(size, file_size - offset); buf = ms_malloc(size_to_send); if (fread(buf, size_to_send, 1, file_to_send)!=size_to_send){ - ms_error("fread error"); + // reaching end of file, close it + fclose(file_to_send); + linphone_chat_message_set_user_data(msg, NULL); } lb = linphone_buffer_new_from_data(buf, size_to_send); ms_free(buf); return lb; } -LinphoneBuffer * memory_file_transfer_send(LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t size){ - size_t size_to_send = MIN(size, sizeof(big_file) - offset); - if (size == 0) return linphone_buffer_new(); /*end of file*/ - return linphone_buffer_new_from_data((uint8_t *)big_file + offset, size_to_send); -} - /** * function invoked to report file transfer progress. * */ -void file_transfer_progress_indication(LinphoneChatMessage *message, const LinphoneContent* content, size_t offset, size_t total) { - LinphoneChatRoom *cr = linphone_chat_message_get_chat_room(message); +void file_transfer_progress_indication(LinphoneChatMessage *msg, const LinphoneContent* content, size_t offset, size_t total) { + LinphoneChatRoom *cr = linphone_chat_message_get_chat_room(msg); LinphoneCore *lc = linphone_chat_room_get_core(cr); - const LinphoneAddress* from_address = linphone_chat_message_get_from(message); - const LinphoneAddress* to_address = linphone_chat_message_get_to(message); - char *address = linphone_chat_message_is_outgoing(message)?linphone_address_as_string(to_address):linphone_address_as_string(from_address); + const LinphoneAddress* from_address = linphone_chat_message_get_from(msg); + const LinphoneAddress* to_address = linphone_chat_message_get_to(msg); + char *address = linphone_chat_message_is_outgoing(msg)?linphone_address_as_string(to_address):linphone_address_as_string(from_address); stats* counters = get_stats(lc); int progress = (int)((offset * 100)/total); ms_message(" File transfer [%d%%] %s of type [%s/%s] %s [%s] \n", progress - ,(linphone_chat_message_is_outgoing(message)?"sent":"received") + ,(linphone_chat_message_is_outgoing(msg)?"sent":"received") , linphone_content_get_type(content) , linphone_content_get_subtype(content) - ,(linphone_chat_message_is_outgoing(message)?"to":"from") + ,(linphone_chat_message_is_outgoing(msg)?"to":"from") , address); counters->progress_of_LinphoneFileTransfer = progress; free(address); @@ -157,9 +154,6 @@ 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); - 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 LinphoneChatMessageStateIdle: return; @@ -179,128 +173,129 @@ void liblinphone_tester_chat_message_msg_state_changed(LinphoneChatMessage *msg, counters->number_of_LinphoneMessageFileTransferDone++; return; } - ms_error("Unexpected state [%s] for message [%p]",linphone_chat_message_state_to_string(state), msg); + ms_error("Unexpected state [%s] for msg [%p]",linphone_chat_message_state_to_string(state), msg); } +void compare_files(const char *path1, const char *path2) { + size_t size1; + size_t size2; + uint8_t *buf1; + uint8_t *buf2; + + buf1 = (uint8_t*)ms_load_path_content(path1, &size1); + buf2 = (uint8_t*)ms_load_path_content(path2, &size2); + BC_ASSERT_PTR_NOT_NULL(buf1); + BC_ASSERT_PTR_NOT_NULL(buf2); + BC_ASSERT_EQUAL((uint8_t)size1, (uint8_t)size2, uint8_t, "%u"); + BC_ASSERT_EQUAL(memcmp(buf1, buf2, size1), 0, int, "%d"); + ms_free(buf1); + ms_free(buf2); +} + +LinphoneChatMessage* create_message_from_nowebcam(LinphoneChatRoom *chat_room) { + FILE *file_to_send = NULL; + LinphoneChatMessageCbs *cbs; + LinphoneContent* content; + LinphoneChatMessage* msg; + size_t file_size; + char *send_filepath = bc_tester_res("images/nowebcamCIF.jpg"); + 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); + + content = linphone_core_create_content(chat_room->lc); + belle_sip_object_set_name(&content->base, "nowebcam content"); + 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"); + + + msg = linphone_chat_room_create_file_transfer_message(chat_room, content); + cbs = linphone_chat_message_get_callbacks(msg); + linphone_chat_message_cbs_set_file_transfer_send(cbs, tester_file_transfer_send); + linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed); + linphone_chat_message_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication); + linphone_chat_message_set_user_data(msg, file_to_send); + + linphone_content_unref(content); + ms_free(send_filepath); + return msg; +} + +void text_message_base(LinphoneCoreManager* marie, LinphoneCoreManager* pauline) { + LinphoneChatMessage* msg = linphone_chat_room_create_message(linphone_core_get_chat_room(pauline->lc,marie->identity),"Bli bli bli \n blu"); + LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg); + linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed); + linphone_chat_room_send_chat_message(msg->chat_room,msg); + + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageDelivered,1)); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1)); + + BC_ASSERT_PTR_NOT_NULL(linphone_core_get_chat_room(marie->lc,pauline->identity)); +} + +/****************************** Tests starting below ******************************/ + 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; + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); - to = linphone_address_as_string(marie->identity); - chat_room = linphone_core_create_chat_room(pauline->lc,to); - ms_free(to); - { - 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_room_send_message(chat_room,"Bla bla bla bla"); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1)); - BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageReceivedLegacy,1, int, "%d"); - - BC_ASSERT_PTR_NOT_NULL(linphone_core_get_chat_room(marie->lc,pauline->identity)); + linphone_chat_room_send_message(linphone_core_get_chat_room(pauline->lc,marie->identity), "hello"); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedLegacy,1)); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } -static void text_message_within_dialog(void) { - char* to; - LinphoneChatRoom* chat_room; +static void text_message_within_call_dialog(void) { LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); lp_config_set_int(pauline->lc->config,"sip","chat_use_call_dialogs",1); - to = linphone_address_as_string(marie->identity); - chat_room = linphone_core_create_chat_room(pauline->lc,to); - ms_free(to); - { - 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); - } BC_ASSERT_TRUE(call(marie,pauline)); + linphone_chat_room_send_message(linphone_core_get_chat_room(pauline->lc, marie->identity),"Bla bla bla bla"); - linphone_chat_room_send_message(chat_room,"Bla bla bla bla"); BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1)); + // when using call dialogs, we will never receive delivered status + BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageDelivered,0,int,"%d"); - BC_ASSERT_PTR_NOT_NULL(linphone_core_get_chat_room(marie->lc,pauline->identity)); - + end_call(marie, pauline); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } static LinphoneAuthInfo* text_message_with_credential_from_auth_cb_auth_info; static void text_message_with_credential_from_auth_cb_auth_info_requested(LinphoneCore *lc, const char *realm, const char *username, const char *domain) { - ms_message("text_message_with_credential_from_auth_cb:Auth info requested for user id [%s] at realm [%s]\n" + ms_message("text_message_with_credential_from_auth_callback:Auth info requested for user id [%s] at realm [%s]\n" ,username ,realm); linphone_core_add_auth_info(lc,text_message_with_credential_from_auth_cb_auth_info); /*add stored authentication info to LinphoneCore*/ } - - -static void text_message_with_credential_from_auth_cb(void) { - char* to; - LinphoneChatRoom* chat_room; - LinphoneCoreVTable* vtable = linphone_core_v_table_new(); +static void text_message_with_credential_from_auth_callback(void) { LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - text_message_with_credential_from_auth_cb_auth_info=linphone_auth_info_clone((LinphoneAuthInfo*)(linphone_core_get_auth_info_list(marie->lc)->data)); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); + LinphoneCoreVTable* vtable = linphone_core_v_table_new(); /*to force cb to be called*/ - linphone_core_clear_all_auth_info(marie->lc); + text_message_with_credential_from_auth_cb_auth_info=linphone_auth_info_clone((LinphoneAuthInfo*)(linphone_core_get_auth_info_list(pauline->lc)->data)); + linphone_core_clear_all_auth_info(pauline->lc); vtable->auth_info_requested=text_message_with_credential_from_auth_cb_auth_info_requested; - linphone_core_add_listener(marie->lc, vtable); + linphone_core_add_listener(pauline->lc, vtable); - to = linphone_address_as_string(marie->identity); - chat_room = linphone_core_create_chat_room(pauline->lc,to); - ms_free(to); - { - 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_room_send_message(chat_room,"Bla bla bla bla"); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1)); - BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageReceivedLegacy,1, int, "%d"); - - BC_ASSERT_PTR_NOT_NULL(linphone_core_get_chat_room(marie->lc,pauline->identity)); + text_message_base(marie, pauline); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } 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"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); + linphone_proxy_config_set_privacy(linphone_core_get_default_proxy_config(pauline->lc),LinphonePrivacyId); - to = linphone_address_as_string(marie->identity); - chat_room = linphone_core_create_chat_room(pauline->lc,to); - ms_free(to); - - /*test proxy config privacy*/ - linphone_core_get_default_proxy(pauline->lc,&pauline_proxy); - linphone_proxy_config_set_privacy(pauline_proxy,LinphonePrivacyId); - - BC_ASSERT_PTR_NOT_NULL(linphone_core_get_chat_room(marie->lc,pauline->identity)); - { - 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_room_send_message(chat_room,"Bla bla bla bla"); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1)); + text_message_base(marie, pauline); BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageReceivedLegacy,1, int, "%d"); linphone_core_manager_destroy(marie); @@ -308,19 +303,14 @@ static void text_message_with_privacy(void) { } static void text_message_compatibility_mode(void) { - char route[256]; LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - LinphoneProxyConfig* proxy; - LinphoneAddress* proxy_address; + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); + LinphoneProxyConfig* proxy = linphone_core_get_default_proxy_config(marie->lc); + LinphoneAddress* proxy_address=linphone_address_new(linphone_proxy_config_get_server_addr(proxy)); + char route[256]; char*tmp; - LCSipTransports transport; - char* to = linphone_address_as_string(pauline->identity); - LinphoneChatRoom* chat_room; - - linphone_core_get_default_proxy(marie->lc,&proxy); - BC_ASSERT_PTR_NOT_NULL (proxy); - proxy_address=linphone_address_new(linphone_proxy_config_get_addr(proxy)); + /*only keep tcp*/ + LCSipTransports transport = {0,-1,0,0}; linphone_address_clean(proxy_address); tmp=linphone_address_as_string_uri_only(proxy_address); linphone_proxy_config_set_server_addr(proxy,tmp); @@ -328,89 +318,76 @@ static void text_message_compatibility_mode(void) { linphone_proxy_config_set_route(proxy,route); ms_free(tmp); linphone_address_destroy(proxy_address); - linphone_core_get_sip_transports(marie->lc,&transport); - transport.udp_port=0; - transport.tls_port=0; - transport.dtls_port=0; - /*only keep tcp*/ linphone_core_set_sip_transports(marie->lc,&transport); marie->stat.number_of_LinphoneRegistrationOk=0; - BC_ASSERT_TRUE (wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphoneRegistrationOk,1)); - chat_room = linphone_core_create_chat_room(marie->lc,to); - { - 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_room_send_message(chat_room,"Bla bla bla bla"); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageReceived,1)); - BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageReceivedLegacy,1, int, "%d"); + text_message_base(marie, pauline); + linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } static void text_message_with_ack(void) { - int leaked_objects; - int begin; - LinphoneCoreManager* marie; - LinphoneCoreManager* pauline; + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); - belle_sip_object_enable_leak_detector(TRUE); - begin=belle_sip_object_get_object_count(); + text_message_base(marie, pauline); - marie = linphone_core_manager_new( "marie_rc"); - pauline = linphone_core_manager_new( "pauline_rc"); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} - { - 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); - 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_room_send_chat_message(chat_room,message); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1)); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageDelivered,1)); - BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1, int, "%d"); - ms_free(to); - linphone_core_manager_destroy(marie); - linphone_core_manager_destroy(pauline); - } - leaked_objects=belle_sip_object_get_object_count()-begin; - BC_ASSERT_TRUE(leaked_objects==0); - if (leaked_objects>0){ - belle_sip_object_dump_active_objects(); - } +static void text_message_with_send_error(void) { + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); + + LinphoneChatRoom* chat_room = linphone_core_get_chat_room(marie->lc, pauline->identity); + LinphoneChatMessage* msg = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu"); + LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg); + + /*simulate a network error*/ + sal_set_send_error(marie->lc->sal, -1); + linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed); + linphone_chat_room_send_chat_message(chat_room,msg); + + /* check transient msg list: the msg should be in it, and should be the only one */ + BC_ASSERT_EQUAL(ms_list_size(chat_room->transient_messages), 1, int, "%d"); + BC_ASSERT_PTR_EQUAL(ms_list_nth_data(chat_room->transient_messages,0), msg); + + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageNotDelivered,1)); + /*BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageInProgress,1, int, "%d");*/ + BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageReceived,0, int, "%d"); + + /* the msg should have been discarded from transient list after an error */ + BC_ASSERT_EQUAL(ms_list_size(chat_room->transient_messages), 0, int, "%d"); + + sal_set_send_error(marie->lc->sal, 0); + + /*give a chance to register again to allow linphone_core_manager_destroy to properly unregister*/ + linphone_core_refresh_registers(marie->lc); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneRegistrationOk,marie->stat.number_of_LinphoneRegistrationOk + 1)); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); } 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); - 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); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); + LinphoneChatRoom* chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity); + LinphoneChatMessage* msg = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu"); + LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg); - linphone_chat_message_set_external_body_url(message,message_external_body_url="http://www.linphone.org"); + message_external_body_url="http://www.linphone.org"; + linphone_chat_message_set_external_body_url(msg,message_external_body_url); - { - 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_room_send_chat_message(chat_room,message); + linphone_chat_room_send_chat_message(chat_room,msg); - /* check transient message list: the message should be in it, and should be the only one */ + /* check transient msg list: the msg should be in it, and should be the only one */ BC_ASSERT_EQUAL(ms_list_size(chat_room->transient_messages), 1, int, "%d"); - BC_ASSERT_PTR_EQUAL(ms_list_nth_data(chat_room->transient_messages,0), message); + BC_ASSERT_PTR_EQUAL(ms_list_nth_data(chat_room->transient_messages,0), msg); BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1)); BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageDelivered,1)); @@ -422,187 +399,462 @@ static void text_message_with_external_body(void) { linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); - ms_free(to); } -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; - - 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; -} - -static void file_transfer_message(void) { - char* to; +void transfer_message_base2(LinphoneCoreManager* marie, LinphoneCoreManager* pauline, bool_t upload_error, bool_t download_error) { + char *send_filepath = bc_tester_res("images/nowebcamCIF.jpg"); + char *receive_filepath = bc_tester_file("receive_file.dump"); LinphoneChatRoom* chat_room; - LinphoneChatMessage* message; + LinphoneChatMessage* msg; 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_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - - 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); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,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); - } - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,1)); + chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity); + /* create a file transfer msg */ + msg = create_message_from_nowebcam(chat_room); + linphone_chat_room_send_chat_message(chat_room,msg); - BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1, int, "%d"); - BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageDelivered,1, int, "%d"); - BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,1, int, "%d"); - BC_ASSERT_TRUE(compare_files(send_filepath, receive_filepath)); + if (upload_error) { + /*wait for file to be 25% uploaded and simulate a network error*/ + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.progress_of_LinphoneFileTransfer,25)); + sal_set_send_error(pauline->lc->sal, -1); - linphone_content_unref(content); - linphone_core_manager_destroy(marie); - linphone_core_manager_destroy(pauline); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageNotDelivered,1)); + + BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageNotDelivered,1, int, "%d"); + BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,0, int, "%d"); + + sal_set_send_error(pauline->lc->sal, 0); + + linphone_core_refresh_registers(pauline->lc); /*to make sure registration is back in registered and so it can be later unregistered*/ + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneRegistrationOk,pauline->stat.number_of_LinphoneRegistrationOk+1)); + } else { + BC_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_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication); + linphone_chat_message_download_file(marie->stat.last_received_chat_message); + + if (download_error) { + /* wait for file to be 50% downloaded */ + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.progress_of_LinphoneFileTransfer, 50)); + /* and simulate network error */ + belle_http_provider_set_recv_error(marie->lc->http_provider, -1); + BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneMessageNotDelivered,1, 10000)); + belle_http_provider_set_recv_error(marie->lc->http_provider, 0); + } else { + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,1)); + compare_files(send_filepath, receive_filepath); + } + } + BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,2, int, "%d"); //sent twice because of file transfer + BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageDelivered,1, int, "%d"); + } ms_free(send_filepath); ms_free(receive_filepath); } -/* same than previous but with a 160 characters file */ -#define SMALL_FILE_SIZE 160 -static void small_file_transfer_message(void) { - int i; - char* to; +void transfer_message_base(bool_t upload_error, bool_t download_error) { + if (transport_supported(LinphoneTransportTls)) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); + transfer_message_base2(marie,pauline,upload_error,download_error); + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(marie); + } +} +static void transfer_message(void) { + transfer_message_base(FALSE, FALSE); +} + +static void transfer_message_with_upload_io_error(void) { + transfer_message_base(TRUE, FALSE); +} + +static void transfer_message_with_download_io_error(void) { + transfer_message_base(FALSE, TRUE); +} + +static void transfer_message_upload_cancelled(void) { + if (transport_supported(LinphoneTransportTls)) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneChatRoom* chat_room; + LinphoneChatMessage* msg; + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); + + /* 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 */ + chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity); + + msg = create_message_from_nowebcam(chat_room); + linphone_chat_room_send_chat_message(chat_room,msg); + + /*wait for file to be 50% uploaded and cancel the transfer */ + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.progress_of_LinphoneFileTransfer, 50)); + linphone_chat_message_cancel_file_transfer(msg); + + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageNotDelivered,1)); + + BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageNotDelivered,1, int, "%d"); + BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,0, int, "%d"); + + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(marie); + } +} + +static void transfer_message_download_cancelled(void) { LinphoneChatRoom* chat_room; - LinphoneChatMessage* message; - LinphoneChatMessageCbs *cbs; - LinphoneContent* content; - const char* big_file_content="big file"; /* setting dummy file content to something */ + LinphoneChatMessage* msg; LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - reset_counters(&marie->stat); - reset_counters(&pauline->stat); - - for (i=0;ilc,"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,SMALL_FILE_SIZE); /*total size to be transfered*/ - linphone_content_set_name(content,"bigfile.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); + chat_room = linphone_core_get_chat_room(pauline->lc,marie->identity); + msg = create_message_from_nowebcam(chat_room); + linphone_chat_room_send_message2(chat_room,msg,NULL,pauline->lc); + + /* wait for marie to receive pauline's msg */ BC_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); + + + if (marie->stat.last_received_chat_message ) { /* get last msg and use it to download file */ + LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(marie->stat.last_received_chat_message); + linphone_chat_message_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication); + linphone_chat_message_start_file_download(marie->stat.last_received_chat_message, liblinphone_tester_chat_message_state_change, marie->lc); + /* wait for file to be 50% downloaded */ + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.progress_of_LinphoneFileTransfer, 50)); + /* and cancel the transfer */ + linphone_chat_message_cancel_file_transfer(marie->stat.last_received_chat_message); } - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,1)); - BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1, int, "%d"); + BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,2, int, "%d"); BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageDelivered,1, int, "%d"); - BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,1, int, "%d"); + BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,0, int, "%d"); + BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageNotDelivered,1, int, "%d"); - linphone_content_unref(content); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } +static void file_transfer_using_external_body_url(void) { + if (transport_supported(LinphoneTransportTls)) { + LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); + LinphoneChatMessageCbs *cbs; + LinphoneChatRoom *chat_room; + LinphoneChatMessage *msg; + LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_rc"); + + /* 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 */ + chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity); + + msg = linphone_chat_room_create_message(chat_room, NULL); + + cbs = linphone_chat_message_get_callbacks(msg); + linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed); + + linphone_chat_message_set_external_body_url(msg, "https://www.linphone.org:444//tmp/54ec58280ace9_c30709218df8eaba61d1.jpg"); + linphone_chat_room_send_chat_message(chat_room, msg); + + BC_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); + } + BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageExtBodyReceived, 1)); + BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneMessageInProgress, 1)); + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(marie); + } +} + +static void file_transfer_2_messages_simultaneously(void) { + if (transport_supported(LinphoneTransportTls)) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneChatRoom* pauline_room; + LinphoneChatMessage* msg; + LinphoneChatMessage* msg2; + LinphoneChatMessageCbs *cbs; + char *send_filepath = bc_tester_res("images/nowebcamCIF.jpg"); + char *receive_filepath = bc_tester_file("receive_file.dump"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); + + /* 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 */ + pauline_room = linphone_core_get_chat_room(pauline->lc, marie->identity); + msg = create_message_from_nowebcam(pauline_room); + msg2 = create_message_from_nowebcam(pauline_room); + + cbs = linphone_chat_message_get_callbacks(msg2); + linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed); + + BC_ASSERT_EQUAL(ms_list_size(linphone_core_get_chat_rooms(marie->lc)), 0, int, "%d"); + linphone_chat_room_send_chat_message(pauline_room,msg); + linphone_chat_room_send_chat_message(pauline_room,msg2); + if (BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,1))) { + msg = linphone_chat_message_clone(marie->stat.last_received_chat_message); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,2)); + msg2 = marie->stat.last_received_chat_message; + BC_ASSERT_EQUAL(ms_list_size(linphone_core_get_chat_rooms(marie->lc)), 1, int, "%d"); + if (ms_list_size(linphone_core_get_chat_rooms(marie->lc)) != 1) { + char * buf = ms_strdup_printf("Found %d rooms instead of 1: ", ms_list_size(linphone_core_get_chat_rooms(marie->lc))); + const MSList *it = linphone_core_get_chat_rooms(marie->lc); + while (it) { + const LinphoneAddress * peer = linphone_chat_room_get_peer_address(it->data); + buf = ms_strcat_printf("%s, ", linphone_address_get_username(peer)); + it = it->next; + } + ms_error("%s", buf); + } + + cbs = linphone_chat_message_get_callbacks(msg); + linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed); + linphone_chat_message_cbs_set_file_transfer_recv(cbs, file_transfer_received); + linphone_chat_message_download_file(msg); + + cbs = linphone_chat_message_get_callbacks(msg2); + linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed); + linphone_chat_message_cbs_set_file_transfer_recv(cbs, file_transfer_received); + linphone_chat_message_download_file(msg2); + + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,2)); + + BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,4, int, "%d"); + BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageDelivered,2, int, "%d"); + compare_files(send_filepath, receive_filepath); + + linphone_chat_message_unref(msg); + } + linphone_core_manager_destroy(pauline); + ms_free(send_filepath); + ms_free(receive_filepath); + linphone_core_manager_destroy(marie); + } +} + +static void text_message_denied(void) { + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); + LinphoneChatRoom* chat_room = linphone_core_get_chat_room(marie->lc, pauline->identity); + LinphoneChatMessage* msg = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu"); + LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg); + + /*pauline doesn't want to be disturbed*/ + linphone_core_disable_chat(pauline->lc,LinphoneReasonDoNotDisturb); + linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed); + linphone_chat_room_send_chat_message(chat_room,msg); + + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageNotDelivered,1)); + BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageReceived,0, int, "%d"); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +static const char *info_content="blabla"; + +void info_message_received(LinphoneCore *lc, LinphoneCall* call, const LinphoneInfoMessage *msg){ + stats* counters = get_stats(lc); + + if (counters->last_received_info_message) { + linphone_info_message_destroy(counters->last_received_info_message); + } + counters->last_received_info_message=linphone_info_message_copy(msg); + counters->number_of_inforeceived++; +} + +void info_message_base(bool_t with_content) { + LinphoneInfoMessage *info; + const LinphoneContent *content; + const char *hvalue; + + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); + + BC_ASSERT_TRUE(call(pauline,marie)); + + info=linphone_core_create_info_message(marie->lc); + linphone_info_message_add_header(info,"Weather","still bad"); + if (with_content) { + LinphoneContent* ct=linphone_core_create_content(marie->lc); + linphone_content_set_type(ct,"application"); + linphone_content_set_subtype(ct,"somexml"); + linphone_content_set_buffer(ct,info_content,strlen(info_content)); + linphone_info_message_set_content(info,ct); + linphone_content_unref(ct); + } + linphone_call_send_info_message(linphone_core_get_current_call(marie->lc),info); + linphone_info_message_destroy(info); + + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_inforeceived,1)); + + BC_ASSERT_PTR_NOT_NULL(pauline->stat.last_received_info_message); + hvalue=linphone_info_message_get_header(pauline->stat.last_received_info_message, "Weather"); + content=linphone_info_message_get_content(pauline->stat.last_received_info_message); + + BC_ASSERT_PTR_NOT_NULL(hvalue); + if (hvalue) + BC_ASSERT_STRING_EQUAL(hvalue, "still bad"); + + if (with_content){ + BC_ASSERT_PTR_NOT_NULL(content); + if (content) { + BC_ASSERT_PTR_NOT_NULL(linphone_content_get_buffer(content)); + BC_ASSERT_PTR_NOT_NULL(linphone_content_get_type(content)); + BC_ASSERT_PTR_NOT_NULL(linphone_content_get_subtype(content)); + if (linphone_content_get_type(content)) BC_ASSERT_STRING_EQUAL(linphone_content_get_type(content),"application"); + if (linphone_content_get_subtype(content)) BC_ASSERT_STRING_EQUAL(linphone_content_get_subtype(content),"somexml"); + if (linphone_content_get_buffer(content))BC_ASSERT_STRING_EQUAL((const char*)linphone_content_get_buffer(content),info_content); + BC_ASSERT_EQUAL((int)linphone_content_get_size(content),(int)strlen(info_content), int, "%d"); + } + } + end_call(marie, pauline); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +static void info_message(void){ + info_message_base(FALSE); +} + +static void info_message_with_body(void){ + info_message_base(TRUE); +} + +static void is_composing_notification(void) { + LinphoneChatRoom* chat_room; + int dummy = 0; + + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); + chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity); + linphone_core_get_chat_room(marie->lc, pauline->identity); /*make marie create the chatroom with pauline, which is necessary for receiving the is-composing*/ + linphone_chat_room_compose(chat_room); + wait_for_until(pauline->lc, marie->lc, &dummy, 1, 1500); /*just to sleep while iterating*/ + linphone_chat_room_send_message(chat_room, "Composing a msg"); + BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneIsComposingActiveReceived, 1)); + BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneIsComposingIdleReceived, 2)); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + + #ifdef HAVE_LIME -static void lime_file_transfer_message(void) { - int i; - char *to; + +static FILE* fopen_from_write_dir(const char * name, const char * mode) { + char *filepath = bc_tester_file(name); + FILE * file = fopen(filepath,mode); + ms_free(filepath); + return file; +} + +static void lime_text_message(void) { 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); + LinphoneChatRoom* chat_room; + char* filepath; + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_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", "wb"); - ZIDCachePaulineFD = fopen("tmpZIDCachePauline.xml", "wb"); + ZIDCacheMarieFD = fopen_from_write_dir("tmpZIDCacheMarie.xml", "w"); + ZIDCachePaulineFD = fopen_from_write_dir("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); + + filepath = bc_tester_file("tmpZIDCacheMarie.xml"); + linphone_core_set_zrtp_secrets_file(marie->lc, filepath); + ms_free(filepath); + + filepath = bc_tester_file("tmpZIDCachePauline.xml"); + linphone_core_set_zrtp_secrets_file(pauline->lc, filepath); + ms_free(filepath); + + chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity); + + linphone_chat_room_send_message(chat_room,"Bla bla bla bla"); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1)); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedLegacy,1)); + + BC_ASSERT_PTR_NOT_NULL(linphone_core_get_chat_room(marie->lc,pauline->identity)); + /* TODO : check the msg arrived correctly deciphered */ + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +static void lime_text_message_to_non_lime(void) { + FILE *ZIDCachePaulineFD; + LinphoneChatRoom* chat_room; + char* filepath; + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); + + /* make sure lime is enabled */ + linphone_core_enable_lime(marie->lc, 0); + 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 */ + ZIDCachePaulineFD = fopen_from_write_dir("tmpZIDCachePauline.xml", "w"); + fprintf(ZIDCachePaulineFD, "\n005dbe0399643d953a2202ddef7692d0792a67491ae2d44e9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899%s08df5907d30959b8cb70f6fff2d8febd88fb41b0c8afc39e4b972f86dd5cfe2d60f020a3fe11dc2cc0e1e8ed9341b4cd14944db806ca4fc95456bbe45d95c43a5f9aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b77193bcffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b7719300000078000001cf011234567889643d953a2202ee9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899%s81e6e6362c34dc974263d1f77cbb9a8d6d6a718330994379099a8fa19fb12faa25d9ac653a83c4559cb0ae7394e7cd3b2d3c57bb28e62068d2df23e8f9b77193f69aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b7719322ffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b771930000002e0000000001", linphone_address_as_string_uri_only(marie->identity), linphone_address_as_string_uri_only(marie->identity)); + fclose(ZIDCachePaulineFD); + + filepath = bc_tester_file("tmpZIDCachePauline.xml"); + linphone_core_set_zrtp_secrets_file(pauline->lc, filepath); + ms_free(filepath); + + chat_room = linphone_core_get_chat_room(pauline->lc, marie->identity); + + linphone_chat_room_send_message(chat_room,"Bla bla bla bla"); + //since we cannot decrypt message, we should not receive any message + BC_ASSERT_FALSE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1)); + BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageReceivedLegacy,0, int, "%d"); + + BC_ASSERT_PTR_NOT_NULL(linphone_core_get_chat_room(marie->lc,pauline->identity)); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} +void lime_transfer_message_base(bool_t encrypt_file) { + FILE *ZIDCacheMarieFD, *ZIDCachePaulineFD; + LinphoneCoreManager *marie, *pauline; + LinphoneChatMessage *msg; + LinphoneChatMessageCbs *cbs; + char *pauline_id, *marie_id; + char *filepath; + + marie = linphone_core_manager_new( "marie_rc"); + pauline = linphone_core_manager_new( "pauline_tcp_rc"); + + /* make sure lime is enabled */ + linphone_core_enable_lime(marie->lc, 1); + linphone_core_enable_lime(pauline->lc, 1); + if (!encrypt_file) { + LpConfig *pauline_lp = linphone_core_get_config(pauline->lc); + lp_config_set_int(pauline_lp,"sip","lime_for_file_sharing",0); + } + + /* 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_from_write_dir("tmpZIDCacheMarie.xml", "wb"); + ZIDCachePaulineFD = fopen_from_write_dir("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); @@ -611,35 +863,22 @@ static void lime_file_transfer_message(void) { 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"); + + filepath = bc_tester_file("tmpZIDCacheMarie.xml"); + linphone_core_set_zrtp_secrets_file(marie->lc, filepath); + ms_free(filepath); + + filepath = bc_tester_file("tmpZIDCachePauline.xml"); + linphone_core_set_zrtp_secrets_file(pauline->lc, filepath); + ms_free(filepath); /* 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"); + /* create a file transfer msg */ + msg = create_message_from_nowebcam(linphone_core_get_chat_room(pauline->lc, marie->identity)); - 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); + linphone_chat_room_send_chat_message(msg->chat_room, msg); BC_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); @@ -649,14 +888,19 @@ static void lime_file_transfer_message(void) { } BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,1)); - BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1, int, "%d"); + BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,2, int, "%d"); // file transfer BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageDelivered,1, int, "%d"); BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,1, int, "%d"); - - linphone_content_unref(content); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); +} +static void lime_transfer_message(void) { + lime_transfer_message_base(TRUE); +} + +static void lime_transfer_message_without_encryption(void) { + lime_transfer_message_base(FALSE); } static void printHex(char *title, uint8_t *data, uint32_t length) { @@ -669,12 +913,12 @@ static void printHex(char *title, uint8_t *data, uint32_t length) { sprintf (debug_string, "0x%02x, ", data[i]); debug_string+=6; } - debug_string = '\0'; + *debug_string = '\0'; ms_message("%s", debug_string_buffer); } -#define PLAIN_TEXT_TEST_MESSAGE "Ceci est un fabuleux message de test à encrypter" static void lime_unit(void) { + const char* PLAIN_TEXT_TEST_MESSAGE = "Ceci est un fabuleux msg de test à encrypter"; int retval; size_t size; uint8_t *cacheBufferString; @@ -699,10 +943,10 @@ static void lime_unit(void) { /**** use functions that are not directly used by external entities ****/ /* create and load cache file */ - CACHE = fopen("ZIDCache.xml", "wb"); + CACHE = fopen_from_write_dir("ZIDCache.xml", "wb"); fprintf (CACHE, "\nef7692d0792a67491ae2d44e005dbe0399643d953a2202dd9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899pipo1@pipo.com963c57bb28e62068d2df23e8f9b771932d3c57bb28e62068d2df23e8f9b7719305d9ac653a83c4559cb0ae7394e7cd3b2d3c57bb28e62068d2df23e8f9b771935f9aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b7719302ffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b7719300000069000001e8011234567889643d953a2202ee9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899pipo1@pipo.com123456789012345678901234567890123456765431262068d2df23e8f9b7719325d9ac653a83c4559cb0ae7394e7cd3b2d3c57bb28e62068d2df23e8f9b77193f69aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b7719322ffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b77193000000010000000001"); fclose(CACHE); - CACHE = fopen("ZIDCache.xml", "rb+"); + CACHE = fopen_from_write_dir("ZIDCache.xml", "rb+"); cacheBufferString = (uint8_t*) ms_load_file_content(CACHE, &size); *(cacheBufferString+size) = '\0'; fclose(CACHE); @@ -735,7 +979,7 @@ static void lime_unit(void) { printHex("sessionID", associatedKey.sessionId, 32); ms_message("session index %d\n", associatedKey.sessionIndex); - /* encrypt/decrypt a message */ + /* encrypt/decrypt a msg */ lime_encryptMessage(associatedKeys.peerKeys[0], (uint8_t *)PLAIN_TEXT_TEST_MESSAGE, strlen(PLAIN_TEXT_TEST_MESSAGE), senderZID, encryptedMessage); printHex("Ciphered", encryptedMessage, strlen((char *)encryptedMessage)); /* invert sender and receiverZID to decrypt/authenticate */ @@ -767,18 +1011,18 @@ static void lime_unit(void) { /* dump the xml document into a string */ xmlDocDumpFormatMemoryEnc(cacheBuffer, &xmlStringOutput, &xmlStringLength, "UTF-8", 0); /* write it to the file */ - CACHE = fopen("ZIDCache.xml", "w+"); + CACHE = fopen_from_write_dir("ZIDCache.xml", "w+"); fwrite(xmlStringOutput, 1, xmlStringLength, CACHE); xmlFree(xmlStringOutput); fclose(CACHE); xmlFreeDoc(cacheBuffer); - /**** Higher level tests using 2 caches to encrypt/decrypt a message ****/ + /**** Higher level tests using 2 caches to encrypt/decrypt a msg ****/ /* Create Alice cache file and then load it */ - CACHE = fopen("ZIDCacheAlice.xml", "wb"); + CACHE = fopen_from_write_dir("ZIDCacheAlice.xml", "wb"); fprintf(CACHE, "\nef7692d0792a67491ae2d44e005dbe0399643d953a2202dd9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899sip:pauline@sip.example.org9111ebeb52e50edcc6fcb3eea1a2d3ae3c2c75d3668923e83c59d0f47245515060f020a3fe11dc2cc0e1e8ed9341b4cd14944db806ca4fc95456bbe45d95c43a5f9aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b77193bcffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b7719300000080000001cf011234567889643d953a2202ee9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899sip:pauline@sip.example.org72d80ab1cad243cf45634980c1d02cfb2df81ce0dd5dfcf1ebeacfc5345a917625d9ac653a83c4559cb0ae7394e7cd3b2d3c57bb28e62068d2df23e8f9b77193f69aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b7719322ffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b771930000000f00000000"); fclose(CACHE); - CACHE = fopen("ZIDCacheAlice.xml", "rb+"); + CACHE = fopen_from_write_dir("ZIDCacheAlice.xml", "rb+"); cacheBufferString = (uint8_t *)ms_load_file_content(CACHE, &size); *(cacheBufferString+size) = '\0'; fclose(CACHE); @@ -787,10 +1031,10 @@ static void lime_unit(void) { ms_free(cacheBufferString); /* Create Bob cache file and then load it */ - CACHE = fopen("ZIDCacheBob.xml", "wb"); + CACHE = fopen_from_write_dir("ZIDCacheBob.xml", "wb"); fprintf(CACHE, "\n005dbe0399643d953a2202ddef7692d0792a67491ae2d44e9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899sip:marie@sip.example.org9111ebeb52e50edcc6fcb3eea1a2d3ae3c2c75d3668923e83c59d0f47245515060f020a3fe11dc2cc0e1e8ed9341b4cd14944db806ca4fc95456bbe45d95c43a5f9aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b77193bcffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b7719300000080000001cf011234567889643d953a2202ee9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899sip:marie@sip.example.org81e6e6362c34dc974263d1f77cbb9a8d6d6a718330994379099a8fa19fb12faa25d9ac653a83c4559cb0ae7394e7cd3b2d3c57bb28e62068d2df23e8f9b77193f69aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b7719322ffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b771930000002e0000000001"); fclose(CACHE); - CACHE = fopen("ZIDCacheBob.xml", "rb+"); + CACHE = fopen_from_write_dir("ZIDCacheBob.xml", "rb+"); cacheBufferString = (uint8_t *)ms_load_file_content(CACHE, &size); *(cacheBufferString+size) = '\0'; fclose(CACHE); @@ -800,21 +1044,21 @@ static void lime_unit(void) { - /* encrypt a message */ + /* encrypt a msg */ retval = lime_createMultipartMessage(cacheBufferAlice, (uint8_t *)PLAIN_TEXT_TEST_MESSAGE, (uint8_t *)"sip:pauline@sip.example.org", &multipartMessage); BC_ASSERT_EQUAL_FATAL(retval, 0, int, "%d"); if (retval == 0) { - ms_message("Encrypted message created is %s", multipartMessage); + ms_message("Encrypted msg created is %s", multipartMessage); } - /* decrypt the multipart message */ + /* decrypt the multipart msg */ retval = lime_decryptMultipartMessage(cacheBufferBob, multipartMessage, &decryptedMessage); BC_ASSERT_EQUAL_FATAL(retval, 0, int, "%d"); if (retval == 0) { BC_ASSERT_STRING_EQUAL((char *)decryptedMessage, (char *)PLAIN_TEXT_TEST_MESSAGE); - ms_message("Succesfully decrypted message is %s", decryptedMessage); + ms_message("Succesfully decrypted msg is %s", decryptedMessage); } free(multipartMessage); free(decryptedMessage); @@ -823,14 +1067,14 @@ static void lime_unit(void) { /* dump the xml document into a string */ xmlDocDumpFormatMemoryEnc(cacheBufferAlice, &xmlStringOutput, &xmlStringLength, "UTF-8", 0); /* write it to the file */ - CACHE = fopen("ZIDCacheAlice.xml", "wb+"); + CACHE = fopen_from_write_dir("ZIDCacheAlice.xml", "wb+"); fwrite(xmlStringOutput, 1, xmlStringLength, CACHE); xmlFree(xmlStringOutput); fclose(CACHE); xmlDocDumpFormatMemoryEnc(cacheBufferBob, &xmlStringOutput, &xmlStringLength, "UTF-8", 0); /* write it to the file */ - CACHE = fopen("ZIDCacheBob.xml", "wb+"); + CACHE = fopen_from_write_dir("ZIDCacheBob.xml", "wb+"); fwrite(xmlStringOutput, 1, xmlStringLength, CACHE); xmlFree(xmlStringOutput); fclose(CACHE); @@ -840,512 +1084,9 @@ static void lime_unit(void) { xmlFreeDoc(cacheBufferBob); } -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"); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1)); - BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageReceivedLegacy,1, int, "%d"); - - BC_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); -} #endif /* HAVE_LIME */ -static void file_transfer_message_io_error_upload(void) { - int i; - char* to; - LinphoneChatRoom* chat_room; - LinphoneChatMessage* message; - LinphoneChatMessageCbs *cbs; - LinphoneContent* content; - 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); - - /* setting dummy file content to something */ - for (i=0;ilc,"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); - - /* 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,"bigfile.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_message_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication); - linphone_chat_room_send_chat_message(chat_room,message); - - /*wait for file to be 25% uploaded and simultate a network error*/ - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.progress_of_LinphoneFileTransfer,25)); - sal_set_send_error(pauline->lc->sal, -1); - - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageNotDelivered,1)); - - BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageNotDelivered,1, int, "%d"); - BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,0, int, "%d"); - - sal_set_send_error(pauline->lc->sal, 0); - - linphone_core_refresh_registers(pauline->lc); /*to make sure registration is back in registered and so it can be later unregistered*/ - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneRegistrationOk,pauline->stat.number_of_LinphoneRegistrationOk+1)); - - linphone_content_unref(content); - linphone_core_manager_destroy(marie); - linphone_core_manager_destroy(pauline); -} - - -#ifdef TEST_IS_BUGGED_NO_CALL_TO_IO_ERROR_CALLBACK -static void file_transfer_message_io_error_download(void) { - int i; - char* to; - LinphoneChatRoom* chat_room; - LinphoneChatMessage* message; - LinphoneContent content; - 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); - - /* setting dummy file content to something */ - for (i=0;ilc,"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 */ - memset(&content,0,sizeof(content)); - content.type="text"; - content.subtype="plain"; - content.size=sizeof(big_file); /*total size to be transfered*/ - content.name = "bigfile.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); - } - linphone_chat_room_send_message2(chat_room,message,liblinphone_tester_chat_message_state_change,pauline->lc); - - /* wait for marie to receive pauline's message */ - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,1)); - - - if (marie->stat.last_received_chat_message ) { /* get last message and use it to download file */ - linphone_chat_message_start_file_download(marie->stat.last_received_chat_message, liblinphone_tester_chat_message_state_change, marie->lc); - /* wait for file to be 50% downloaded */ - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.progress_of_LinphoneFileTransfer, 50)); - /* and simulate network error */ - sal_set_recv_error(marie->lc->sal, -1); - } - - BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1, int, "%d"); - BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageDelivered,1, int, "%d"); - BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageNotDelivered,1, int, "%d"); - BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,0, int, "%d"); - - sal_set_recv_error(marie->lc->sal, 0); - linphone_core_manager_destroy(marie); - linphone_core_manager_destroy(pauline); -} -#endif - -static void file_transfer_message_upload_cancelled(void) { - int i; - char* to; - LinphoneChatRoom* chat_room; - LinphoneChatMessage* message; - LinphoneChatMessageCbs *cbs; - LinphoneContent* content; - 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); - - /* setting dummy file content to something */ - for (i=0;ilc,"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); - - /* 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,"bigfile.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_message_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication); - linphone_chat_room_send_chat_message(chat_room,message); - - /*wait for file to be 50% uploaded and cancel the transfer */ - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.progress_of_LinphoneFileTransfer, 50)); - linphone_chat_message_cancel_file_transfer(message); - - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageNotDelivered,1)); - - BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageNotDelivered,1, int, "%d"); - BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,0, int, "%d"); - - linphone_content_unref(content); - linphone_core_manager_destroy(marie); - linphone_core_manager_destroy(pauline); -} - -static void file_transfer_message_download_cancelled(void) { -#if 0 - int i; - char* to; - LinphoneChatRoom* chat_room; - LinphoneChatMessage* message; - LinphoneContent content; - 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); - - /* setting dummy file content to something */ - for (i=0;ilc,"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); - - /* create a file transfer message */ - memset(&content,0,sizeof(content)); - content.type="text"; - content.subtype="plain"; - content.size=sizeof(big_file); /*total size to be transfered*/ - content.name = "bigfile.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); - } - linphone_chat_room_send_message2(chat_room,message,liblinphone_tester_chat_message_state_change,pauline->lc); - - /* wait for marie to receive pauline's message */ - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,1)); - - - if (marie->stat.last_received_chat_message ) { /* get last message and use it to download file */ - linphone_chat_message_start_file_download(marie->stat.last_received_chat_message, liblinphone_tester_chat_message_state_change, marie->lc); - /* wait for file to be 50% downloaded */ - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.progress_of_LinphoneFileTransfer, 50)); - /* and cancel the transfer */ - linphone_chat_message_cancel_file_transfer(marie->stat.last_received_chat_message); - } - - BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1, int, "%d"); - BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageDelivered,1, int, "%d"); - BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,0, int, "%d"); - BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageNotDelivered,1, int, "%d"); - - linphone_core_manager_destroy(marie); - linphone_core_manager_destroy(pauline); -#endif - ms_error("Test skipped"); -} - -static void file_transfer_using_external_body_url(void) { - char *to; - LinphoneChatMessageCbs *cbs; - LinphoneChatRoom *chat_room; - LinphoneChatMessage *message; - LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); - LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_rc"); - 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); - - BC_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); - } - BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageExtBodyReceived, 1)); - BC_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); -} - -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); - 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); - reset_counters(&marie->stat); - reset_counters(&pauline->stat); - - /*simultate a network error*/ - sal_set_send_error(marie->lc->sal, -1); - { - 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_room_send_chat_message(chat_room,message); - - /* check transient message list: the message should be in it, and should be the only one */ - BC_ASSERT_EQUAL(ms_list_size(chat_room->transient_messages), 1, int, "%d"); - BC_ASSERT_PTR_EQUAL(ms_list_nth_data(chat_room->transient_messages,0), message); - - - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageNotDelivered,1)); - /*BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageInProgress,1, int, "%d");*/ - BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageReceived,0, int, "%d"); - - /* the message should have been discarded from transient list after an error */ - BC_ASSERT_EQUAL(ms_list_size(chat_room->transient_messages), 0, int, "%d"); - - sal_set_send_error(marie->lc->sal, 0); - ms_free(to); - linphone_core_manager_destroy(marie); - linphone_core_manager_destroy(pauline); -} - -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); - 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); - - /*pauline doesn't want to be disturbed*/ - linphone_core_disable_chat(pauline->lc,LinphoneReasonDoNotDisturb); - { - 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_room_send_chat_message(chat_room,message); - - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageNotDelivered,1)); - BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageReceived,0, int, "%d"); - ms_free(to); - linphone_core_manager_destroy(marie); - linphone_core_manager_destroy(pauline); -} - -static const char *info_content="blabla"; - -void info_message_received(LinphoneCore *lc, LinphoneCall* call, const LinphoneInfoMessage *msg){ - stats* counters = get_stats(lc); - - if (counters->last_received_info_message) { - linphone_info_message_destroy(counters->last_received_info_message); - } - counters->last_received_info_message=linphone_info_message_copy(msg); - counters->number_of_inforeceived++; -} - - - -static void info_message_with_args(bool_t with_content) { - LinphoneInfoMessage *info; - const LinphoneContent *content; - const char *hvalue; - - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - - BC_ASSERT_TRUE(call(pauline,marie)); - - info=linphone_core_create_info_message(marie->lc); - linphone_info_message_add_header(info,"Weather","still bad"); - if (with_content) { - LinphoneContent* ct=linphone_core_create_content(marie->lc); - linphone_content_set_type(ct,"application"); - linphone_content_set_subtype(ct,"somexml"); - linphone_content_set_buffer(ct,info_content,strlen(info_content)); - linphone_info_message_set_content(info,ct); - linphone_content_unref(ct); - } - { - 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_call_send_info_message(linphone_core_get_current_call(marie->lc),info); - linphone_info_message_destroy(info); - - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_inforeceived,1)); - - BC_ASSERT_PTR_NOT_NULL(pauline->stat.last_received_info_message); - hvalue=linphone_info_message_get_header(pauline->stat.last_received_info_message, "Weather"); - content=linphone_info_message_get_content(pauline->stat.last_received_info_message); - - BC_ASSERT_PTR_NOT_NULL(hvalue); - if (hvalue) - BC_ASSERT_TRUE(strcmp(hvalue,"still bad")==0); - - if (with_content){ - BC_ASSERT_PTR_NOT_NULL(content); - if (content) { - BC_ASSERT_PTR_NOT_NULL(linphone_content_get_buffer(content)); - BC_ASSERT_PTR_NOT_NULL(linphone_content_get_type(content)); - BC_ASSERT_PTR_NOT_NULL(linphone_content_get_subtype(content)); - if (linphone_content_get_type(content)) BC_ASSERT_TRUE(strcmp(linphone_content_get_type(content),"application")==0); - if (linphone_content_get_subtype(content)) BC_ASSERT_TRUE(strcmp(linphone_content_get_subtype(content),"somexml")==0); - if (linphone_content_get_buffer(content))BC_ASSERT_TRUE(strcmp((const char*)linphone_content_get_buffer(content),info_content)==0); - BC_ASSERT_EQUAL(linphone_content_get_size(content),strlen(info_content), int, "%d"); - } - } - linphone_core_manager_destroy(marie); - linphone_core_manager_destroy(pauline); -} - -static void info_message(){ - info_message_with_args(FALSE); -} - -static void info_message_with_body(){ - info_message_with_args(TRUE); -} - -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"); - - to = linphone_address_as_string(marie->identity); - chat_room = linphone_core_create_chat_room(pauline->lc, to); - - ms_free(to); - { - 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_room_compose(chat_room); - wait_for_until(pauline->lc, marie->lc, &dummy, 1, 1500); /*just to sleep while iterating*/ - linphone_chat_room_send_message(chat_room, "Composing a message"); - BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneIsComposingActiveReceived, 1)); - BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneIsComposingIdleReceived, 2)); - linphone_core_manager_destroy(marie); - linphone_core_manager_destroy(pauline); -} - #ifdef MSG_STORAGE_ENABLED /* @@ -1353,8 +1094,7 @@ static void is_composing_notification(void) { * Destination file is truncated if existing. * Return 0 on success, positive value on error. */ -static int -message_tester_copy_file(const char *from, const char *to) +int message_tester_copy_file(const char *from, const char *to) { FILE *in, *out; char buf[256]; @@ -1395,20 +1135,24 @@ message_tester_copy_file(const char *from, const char *to) return 0; } -static int check_no_strange_time(void* data,int argc, char** argv,char** cNames) { +int check_no_strange_time(void* data,int argc, char** argv,char** cNames) { BC_ASSERT_EQUAL(argc, 1, int, "%d"); BC_ASSERT_STRING_EQUAL(cNames[0], "COUNT(*)"); // count of non updated messages should be 0 BC_ASSERT_STRING_EQUAL(argv[0], "0"); // count of non updated messages should be 0 return 0; } -static void message_storage_migration() { +void history_message_count_helper(LinphoneChatRoom* chatroom, int x, int y, int expected ){ + MSList* messages = linphone_chat_room_get_history_range(chatroom, x, y); + BC_ASSERT_EQUAL(ms_list_size(messages), expected, int, "%d"); + ms_list_free_with_data(messages, (void (*)(void *))linphone_chat_message_unref); +} + +static void database_migration(void) { LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); - char src_db[256]; - char tmp_db[256]; - MSList* chatrooms; - 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); + char *src_db = bc_tester_res("messages.db"); + char *tmp_db = bc_tester_file("tmp.db"); + const MSList* chatrooms; BC_ASSERT_EQUAL_FATAL(message_tester_copy_file(src_db, tmp_db), 0, int, "%d"); @@ -1427,28 +1171,16 @@ static void message_storage_migration() { linphone_core_manager_destroy(marie); remove(tmp_db); + ms_free(src_db); + ms_free(tmp_db); } -static void history_message_count_helper(LinphoneChatRoom* chatroom, int x, int y, int expected ){ - MSList* messages = linphone_chat_room_get_history_range(chatroom, x, y); - int size = ms_list_size(messages); - if( expected != size ){ - ms_warning("History retrieved from %d to %d returned %d records, but expected %d", x, y, size, expected); - } - BC_ASSERT_EQUAL(size, expected, int, "%d"); - - ms_list_free_with_data(messages, (void (*)(void *))linphone_chat_message_unref); - -} - -static void history_range_full_test(){ +static void history_range(void){ LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); LinphoneAddress *jehan_addr = linphone_address_new(""); LinphoneChatRoom *chatroom; - char src_db[256]; - char tmp_db[256]; - 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); + char *src_db = bc_tester_res("messages.db"); + char *tmp_db = bc_tester_file("tmp.db"); BC_ASSERT_EQUAL_FATAL(message_tester_copy_file(src_db, tmp_db), 0, int, "%d"); @@ -1479,18 +1211,17 @@ static void history_range_full_test(){ linphone_core_manager_destroy(marie); linphone_address_destroy(jehan_addr); remove(tmp_db); + ms_free(src_db); + ms_free(tmp_db); } - -static void history_messages_count() { +static void history_count(void) { LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); LinphoneAddress *jehan_addr = linphone_address_new(""); LinphoneChatRoom *chatroom; MSList *messages; - char src_db[256]; - char tmp_db[256]; - 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); + char *src_db = bc_tester_res("messages.db"); + char *tmp_db = bc_tester_file("tmp.db"); BC_ASSERT_EQUAL_FATAL(message_tester_copy_file(src_db, tmp_db), 0, int, "%d"); @@ -1510,11 +1241,11 @@ static void history_messages_count() { messages=linphone_chat_room_get_history(chatroom,0); BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(chatroom), 1270, int, "%d"); BC_ASSERT_EQUAL(ms_list_size(messages), 1270, int, "%d"); - /*check the second most recent message*/ + /*check the second most recent msg*/ BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text((LinphoneChatMessage *)messages->next->data), "Fore and aft follow each other."); ms_list_free_with_data(messages, (void (*)(void*))linphone_chat_message_unref); - /*test offset+limit: retrieve the 42th latest message only and check its content*/ + /*test offset+limit: retrieve the 42th latest msg only and check its content*/ messages=linphone_chat_room_get_history_range(chatroom, 42, 42); BC_ASSERT_EQUAL(ms_list_size(messages), 1, int, "%d"); BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text((LinphoneChatMessage *)messages->data), "If you open yourself to the Tao is intangible and evasive, yet prefers to keep us at the mercy of the kingdom, then all of the streams of hundreds of valleys because of its limitless possibilities."); @@ -1538,48 +1269,489 @@ static void history_messages_count() { linphone_core_manager_destroy(marie); linphone_address_destroy(jehan_addr); remove(tmp_db); + ms_free(src_db); + ms_free(tmp_db); +} +#endif + +static void text_status_after_destroying_chat_room(void) { + LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); + LinphoneChatRoom *chatroom = linphone_core_get_chat_room_from_uri(marie->lc, ""); + LinphoneChatMessage *msg = linphone_chat_room_create_message(chatroom, "hello"); + linphone_chat_room_send_chat_message(chatroom, msg); + linphone_core_delete_chat_room(marie->lc, chatroom); + //since message is orphan, we do not expect to be notified of state change + BC_ASSERT_FALSE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneMessageNotDelivered, 1, 1000)); + linphone_core_manager_destroy(marie); } +void file_transfer_io_error_base(char *server_url, bool_t destroy_room) { + LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); + LinphoneChatRoom *chatroom = linphone_core_get_chat_room_from_uri(marie->lc, ""); + LinphoneChatMessage *msg = create_message_from_nowebcam(chatroom); + LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg); + linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed); + linphone_core_set_file_transfer_server(marie->lc, server_url); + linphone_chat_room_send_chat_message(chatroom, msg); + BC_ASSERT_TRUE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneMessageInProgress, 1, 1000)); + if (destroy_room) { + //since message is orphan, we do not expect to be notified of state change + linphone_core_delete_chat_room(marie->lc, chatroom); + BC_ASSERT_FALSE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneMessageNotDelivered, 1, 1000)); + } else { + BC_ASSERT_TRUE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneMessageNotDelivered, 1, 1000)); + } + linphone_core_manager_destroy(marie); +} -#endif +static void file_transfer_not_sent_if_invalid_url(void) { + file_transfer_io_error_base("INVALID URL", FALSE); +} + +static void file_transfer_not_sent_if_host_not_found(void) { + file_transfer_io_error_base("https://not_existing_url.com", FALSE); +} + +static void file_transfer_not_sent_if_url_moved_permanently(void) { + file_transfer_io_error_base("http://linphone.org/toto.php", FALSE); +} + +static void file_transfer_io_error_after_destroying_chatroom(void) { + file_transfer_io_error_base("https://www.linphone.org:444/lft.php", TRUE); +} + +static void real_time_text(bool_t audio_stream_enabled, bool_t srtp_enabled, bool_t mess_with_marie_payload_number, bool_t mess_with_pauline_payload_number, bool_t ice_enabled) { + LinphoneChatRoom *pauline_chat_room; + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); + LinphoneCallParams *marie_params = NULL; + LinphoneCall *pauline_call, *marie_call; + + if (mess_with_marie_payload_number) { + MSList *elem; + for (elem = marie->lc->codecs_conf.text_codecs; elem != NULL; elem = elem->next) { + PayloadType *pt = (PayloadType*)elem->data; + if (strcasecmp(pt->mime_type, payload_type_t140.mime_type) == 0) { + payload_type_set_number(pt, 99); + break; + } + } + } else if (mess_with_pauline_payload_number) { + MSList *elem; + for (elem = pauline->lc->codecs_conf.text_codecs; elem != NULL; elem = elem->next) { + PayloadType *pt = (PayloadType*)elem->data; + if (strcasecmp(pt->mime_type, payload_type_t140.mime_type) == 0) { + payload_type_set_number(pt, 99); + break; + } + } + } + + if (ice_enabled) { + linphone_core_set_firewall_policy(marie->lc, LinphonePolicyUseIce); + linphone_core_set_firewall_policy(pauline->lc, LinphonePolicyUseIce); + } + + if (srtp_enabled) { + BC_ASSERT_TRUE(linphone_core_media_encryption_supported(marie->lc, LinphoneMediaEncryptionSRTP)); + linphone_core_set_media_encryption(marie->lc, LinphoneMediaEncryptionSRTP); + linphone_core_set_media_encryption(pauline->lc, LinphoneMediaEncryptionSRTP); + linphone_core_set_media_encryption_mandatory(marie->lc, TRUE); + linphone_core_set_media_encryption_mandatory(pauline->lc, TRUE); + } + + marie_params = linphone_core_create_call_params(marie->lc, NULL); + linphone_call_params_enable_realtime_text(marie_params,TRUE); + if (!audio_stream_enabled) { + linphone_call_params_enable_audio(marie_params,FALSE); + linphone_core_set_nortp_timeout(marie->lc, 10); + linphone_core_set_nortp_timeout(pauline->lc, 10); + } + + BC_ASSERT_TRUE(call_with_caller_params(marie, pauline, marie_params)); + pauline_call = linphone_core_get_current_call(pauline->lc); + marie_call = linphone_core_get_current_call(marie->lc); + if (pauline_call) { + BC_ASSERT_TRUE(linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(pauline_call))); + if (!audio_stream_enabled) { + BC_ASSERT_TRUE(linphone_call_params_audio_enabled(linphone_call_get_current_params(pauline_call))); + } + + pauline_chat_room = linphone_call_get_chat_room(pauline_call); + BC_ASSERT_PTR_NOT_NULL(pauline_chat_room); + if (pauline_chat_room) { + const char* message = "Lorem Ipsum Belledonnum Communicatum"; + int i; + LinphoneChatMessage* rtt_message = linphone_chat_room_create_message(pauline_chat_room,NULL); + LinphoneChatRoom *marie_chat_room = linphone_call_get_chat_room(marie_call); + + for (i = 0; i < strlen(message); i++) { + linphone_chat_message_put_char(rtt_message, message[i]); + BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneIsComposingActiveReceived, i+1, 1000)); + BC_ASSERT_EQUAL(linphone_chat_room_get_char(marie_chat_room), message[i], char, "%c"); + } + linphone_chat_room_send_chat_message(pauline_chat_room, rtt_message); + BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageReceived, 1)); + } + + if (!audio_stream_enabled) { + int dummy = 0; + wait_for_until(pauline->lc, marie->lc, &dummy, 1, 13000); /* Wait to see if call is dropped after the nortp_timeout */ + BC_ASSERT_FALSE(marie->stat.number_of_LinphoneCallEnd > 0); + BC_ASSERT_FALSE(pauline->stat.number_of_LinphoneCallEnd > 0); + } + + if (ice_enabled) { + BC_ASSERT_TRUE(check_ice(pauline,marie,LinphoneIceStateHostConnection)); + } + + end_call(marie, pauline); + } + linphone_call_params_destroy(marie_params); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +static void real_time_text_message(void) { + real_time_text(TRUE, FALSE, FALSE, FALSE, FALSE); +} + +static void real_time_text_conversation(void) { + LinphoneChatRoom *pauline_chat_room, *marie_chat_room; + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); + LinphoneCallParams *marie_params = linphone_core_create_call_params(marie->lc, NULL); + LinphoneCall *pauline_call, *marie_call; + linphone_call_params_enable_realtime_text(marie_params,TRUE); + + BC_ASSERT_TRUE(call_with_caller_params(marie, pauline, marie_params)); + pauline_call=linphone_core_get_current_call(pauline->lc); + marie_call=linphone_core_get_current_call(marie->lc); + BC_ASSERT_TRUE(linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(pauline_call))); + + pauline_chat_room = linphone_call_get_chat_room(pauline_call); + BC_ASSERT_PTR_NOT_NULL(pauline_chat_room); + marie_chat_room = linphone_call_get_chat_room(marie_call); + BC_ASSERT_PTR_NOT_NULL(pauline_chat_room); + if (pauline_chat_room && marie_chat_room) { + const char* message1_1 = "Lorem Ipsum"; + const char* message1_2 = "Muspi Merol"; + const char* message2_1 = "Belledonnum Communicatum"; + const char* message2_2 = "Mutacinummoc Munnodelleb"; + int i; + LinphoneChatMessage* pauline_rtt_message = linphone_chat_room_create_message(pauline_chat_room,NULL); + LinphoneChatMessage* marie_rtt_message = linphone_chat_room_create_message(marie_chat_room,NULL); + + for (i = 0; i < strlen(message1_1); i++) { + linphone_chat_message_put_char(pauline_rtt_message, message1_1[i]); + BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneIsComposingActiveReceived, i+1, 1000)); + BC_ASSERT_EQUAL(linphone_chat_room_get_char(marie_chat_room), message1_1[i], char, "%c"); + + linphone_chat_message_put_char(marie_rtt_message, message1_2[i]); + BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneIsComposingActiveReceived, i+1, 1000)); + BC_ASSERT_EQUAL(linphone_chat_room_get_char(pauline_chat_room), message1_2[i], char, "%c"); + } + + /*Commit the message, triggers a NEW LINE in T.140 */ + linphone_chat_room_send_chat_message(pauline_chat_room, pauline_rtt_message); + linphone_chat_room_send_chat_message(marie_chat_room, marie_rtt_message); + + BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageReceived, 1)); + { + LinphoneChatMessage * msg = marie->stat.last_received_chat_message; + BC_ASSERT_PTR_NOT_NULL(msg); + if (msg) { + BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(msg), message1_1); + } + } + BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneMessageReceived, 1)); + { + LinphoneChatMessage * msg = pauline->stat.last_received_chat_message; + BC_ASSERT_PTR_NOT_NULL(msg); + if (msg) { + BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(msg), message1_2); + } + } + + reset_counters(&pauline->stat); + reset_counters(&marie->stat); + pauline_rtt_message = linphone_chat_room_create_message(pauline_chat_room,NULL); + marie_rtt_message = linphone_chat_room_create_message(marie_chat_room,NULL); + + for (i = 0; i < strlen(message2_1); i++) { + linphone_chat_message_put_char(pauline_rtt_message, message2_1[i]); + BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneIsComposingActiveReceived, i+1, 1000)); + BC_ASSERT_EQUAL(linphone_chat_room_get_char(marie_chat_room), message2_1[i], char, "%c"); + + linphone_chat_message_put_char(marie_rtt_message, message2_2[i]); + BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneIsComposingActiveReceived, i+1, 1000)); + BC_ASSERT_EQUAL(linphone_chat_room_get_char(pauline_chat_room), message2_2[i], char, "%c"); + } + + /*Commit the message, triggers a NEW LINE in T.140 */ + linphone_chat_room_send_chat_message(pauline_chat_room, pauline_rtt_message); + linphone_chat_room_send_chat_message(marie_chat_room, marie_rtt_message); + + BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageReceived, 1)); + { + LinphoneChatMessage * msg = marie->stat.last_received_chat_message; + BC_ASSERT_PTR_NOT_NULL(msg); + if (msg) { + BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(msg), message2_1); + } + } + BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneMessageReceived, 1)); + { + LinphoneChatMessage * msg = pauline->stat.last_received_chat_message; + BC_ASSERT_PTR_NOT_NULL(msg); + if (msg) { + BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(msg), message2_2); + } + } + } + end_call(marie, pauline); + linphone_call_params_destroy(marie_params); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +static void real_time_text_without_audio(void) { + real_time_text(FALSE, FALSE, FALSE, FALSE, FALSE); +} + +static void real_time_text_srtp(void) { + real_time_text(TRUE, TRUE, FALSE, FALSE, FALSE); +} + +static void real_time_text_ice(void) { + real_time_text(TRUE, FALSE, FALSE, FALSE, TRUE); +} + +static void real_time_text_message_compat(bool_t end_with_crlf, bool_t end_with_lf) { + LinphoneChatRoom *pauline_chat_room; + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); + LinphoneCallParams *marie_params = NULL; + LinphoneCall *pauline_call, *marie_call; + + marie_params = linphone_core_create_call_params(marie->lc, NULL); + linphone_call_params_enable_realtime_text(marie_params,TRUE); + + BC_ASSERT_TRUE(call_with_caller_params(marie, pauline, marie_params)); + pauline_call=linphone_core_get_current_call(pauline->lc); + marie_call=linphone_core_get_current_call(marie->lc); + if (pauline_call) { + BC_ASSERT_TRUE(linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(pauline_call))); + + pauline_chat_room = linphone_call_get_chat_room(pauline_call); + BC_ASSERT_PTR_NOT_NULL(pauline_chat_room); + if (pauline_chat_room) { + const char* message = "Lorem Ipsum Belledonnum Communicatum"; + int i; + LinphoneChatMessage* rtt_message = linphone_chat_room_create_message(pauline_chat_room,NULL); + LinphoneChatRoom *marie_chat_room = linphone_call_get_chat_room(marie_call); + uint32_t crlf = 0x0D0A; + uint32_t lf = 0x0A; + + for (i = 0; i < strlen(message); i++) { + linphone_chat_message_put_char(rtt_message, message[i]); + BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneIsComposingActiveReceived, i+1, 1000)); + BC_ASSERT_EQUAL(linphone_chat_room_get_char(marie_chat_room), message[i], char, "%c"); + } + + if (end_with_crlf) { + linphone_chat_message_put_char(rtt_message, crlf); + } else if (end_with_lf) { + linphone_chat_message_put_char(rtt_message, lf); + } + BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneIsComposingActiveReceived, strlen(message), 1000)); + BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageReceived, 1)); + } + end_call(marie, pauline); + } + linphone_call_params_destroy(marie_params); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +static void real_time_text_message_compat_crlf(void) { + real_time_text_message_compat(TRUE, FALSE); +} + +static void real_time_text_message_compat_lf(void) { + real_time_text_message_compat(FALSE, TRUE); +} + +static void real_time_text_message_accented_chars(void) { + LinphoneChatRoom *pauline_chat_room; + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); + LinphoneCallParams *marie_params = NULL; + LinphoneCall *pauline_call, *marie_call; + + marie_params = linphone_core_create_call_params(marie->lc, NULL); + linphone_call_params_enable_realtime_text(marie_params,TRUE); + + BC_ASSERT_TRUE(call_with_caller_params(marie, pauline, marie_params)); + pauline_call=linphone_core_get_current_call(pauline->lc); + marie_call=linphone_core_get_current_call(marie->lc); + if (pauline_call) { + BC_ASSERT_TRUE(linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(pauline_call))); + + pauline_chat_room = linphone_call_get_chat_room(pauline_call); + BC_ASSERT_PTR_NOT_NULL(pauline_chat_room); + if (pauline_chat_room) { + LinphoneChatMessage* rtt_message = linphone_chat_room_create_message(pauline_chat_room,NULL); + LinphoneChatRoom *marie_chat_room = linphone_call_get_chat_room(marie_call); + int i; + uint32_t message[8]; + int message_len = 8; + + message[0] = 0xE3; // ã + message[1] = 0xE6; // æ + message[2] = 0xE7; // ç + message[3] = 0xE9; // é + message[4] = 0xEE; // î + message[5] = 0xF8; // ø + message[6] = 0xF9; // ù + message[7] = 0xFF; // ÿ + for (i = 0; i < message_len; i++) { + linphone_chat_message_put_char(rtt_message, message[i]); + BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneIsComposingActiveReceived, i+1, 1000)); + BC_ASSERT_EQUAL(linphone_chat_room_get_char(marie_chat_room), message[i], unsigned long, "%lu"); + } + + linphone_chat_room_send_chat_message(pauline_chat_room, rtt_message); + BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageReceived, 1)); + BC_ASSERT_EQUAL(strcmp(marie->stat.last_received_chat_message->message, "ãæçéîøùÿ"), 0, int, "%i"); + } + end_call(marie, pauline); + } + linphone_call_params_destroy(marie_params); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +static void real_time_text_message_different_text_codecs_payload_numbers_sender_side(void) { + real_time_text(FALSE, FALSE, TRUE, FALSE, FALSE); +} + +static void real_time_text_message_different_text_codecs_payload_numbers_receiver_side(void) { + real_time_text(FALSE, FALSE, FALSE, TRUE, FALSE); +} + +static void real_time_text_copy_paste(void) { + LinphoneChatRoom *pauline_chat_room; + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); + LinphoneCallParams *marie_params = NULL; + LinphoneCall *pauline_call, *marie_call; + + marie_params = linphone_core_create_call_params(marie->lc, NULL); + linphone_call_params_enable_realtime_text(marie_params,TRUE); + + BC_ASSERT_TRUE(call_with_caller_params(marie, pauline, marie_params)); + pauline_call = linphone_core_get_current_call(pauline->lc); + marie_call = linphone_core_get_current_call(marie->lc); + if (pauline_call) { + BC_ASSERT_TRUE(linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(pauline_call))); + + pauline_chat_room = linphone_call_get_chat_room(pauline_call); + BC_ASSERT_PTR_NOT_NULL(pauline_chat_room); + if (pauline_chat_room) { + const char* message = "Lorem Ipsum Belledonnum Communicatum"; + int i; + LinphoneChatMessage* rtt_message = linphone_chat_room_create_message(pauline_chat_room,NULL); + LinphoneChatRoom *marie_chat_room = linphone_call_get_chat_room(marie_call); + + for (i = 1; i <= strlen(message); i++) { + linphone_chat_message_put_char(rtt_message, message[i-1]); + if (i % 4 == 0) { + int j; + BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneIsComposingActiveReceived, i, 1000)); + for (j = 4; j > 0; j--) { + BC_ASSERT_EQUAL(linphone_chat_room_get_char(marie_chat_room), message[i-j], char, "%c"); + } + } + } + linphone_chat_room_send_chat_message(pauline_chat_room, rtt_message); + BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageReceived, 1)); + } + + end_call(marie, pauline); + } + linphone_call_params_destroy(marie_params); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +void file_transfer_with_http_proxy(void) { + if (transport_supported(LinphoneTransportTls)) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); + linphone_core_set_http_proxy_host(marie->lc, "sip.linphone.org"); + transfer_message_base2(marie,pauline,FALSE,FALSE); + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(marie); + } +} test_t message_tests[] = { - { "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}, - { "Text message with privacy", text_message_with_privacy }, - { "Text message compatibility mode", text_message_compatibility_mode }, - { "Text message with ack", text_message_with_ack }, - { "Text message with send error", text_message_with_send_error }, - { "Text message with external body", text_message_with_external_body }, - { "File transfer message", file_transfer_message }, - { "Small File transfer message", small_file_transfer_message}, - { "File transfer message with io error at upload", file_transfer_message_io_error_upload }, -/* { "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 }, - { "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 } + {"Text message", text_message}, + {"Text message within call dialog", text_message_within_call_dialog}, + {"Text message with credentials from auth callback", text_message_with_credential_from_auth_callback}, + {"Text message with privacy", text_message_with_privacy}, + {"Text message compatibility mode", text_message_compatibility_mode}, + {"Text message with ack", text_message_with_ack}, + {"Text message with send error", text_message_with_send_error}, + {"Text message with external body", text_message_with_external_body}, + {"Transfer message", transfer_message}, + {"Transfer message with http proxy", file_transfer_with_http_proxy}, + {"Transfer message with upload io error", transfer_message_with_upload_io_error}, + {"Transfer message with download io error", transfer_message_with_download_io_error}, + {"Transfer message upload cancelled", transfer_message_upload_cancelled}, + {"Transfer message download cancelled", transfer_message_download_cancelled}, + {"Transfer message using external body url", file_transfer_using_external_body_url}, + {"Transfer 2 messages simultaneously", file_transfer_2_messages_simultaneously}, + {"Text message denied", text_message_denied}, + {"Info message", info_message}, + {"Info message with body", info_message_with_body}, + {"IsComposing notification", is_composing_notification}, #ifdef HAVE_LIME - ,{ "Lime Text Message", lime_text_message } - ,{ "Lime File transfer message", lime_file_transfer_message } - ,{ "Lime Unitary", lime_unit } + {"Lime text message", lime_text_message}, + {"Lime text message to non lime", lime_text_message_to_non_lime}, + {"Lime transfer message", lime_transfer_message}, + {"Lime transfer message without encryption", lime_transfer_message_without_encryption}, + {"Lime unitary", lime_unit}, #endif /* HAVE_LIME */ #ifdef MSG_STORAGE_ENABLED - ,{ "Database migration", message_storage_migration } - ,{ "History count", history_messages_count } - ,{ "History range", history_range_full_test } + {"Database migration", database_migration}, + {"History range", history_range}, + {"History count", history_count}, #endif + {"Text status after destroying chat room", text_status_after_destroying_chat_room}, + {"Transfer not sent if invalid url", file_transfer_not_sent_if_invalid_url}, + {"Transfer not sent if host not found", file_transfer_not_sent_if_host_not_found}, + {"Transfer not sent if url moved permanently", file_transfer_not_sent_if_url_moved_permanently}, + {"Transfer io error after destroying chatroom", file_transfer_io_error_after_destroying_chatroom}, + {"Real Time Text message", real_time_text_message}, + {"Real Time Text conversation", real_time_text_conversation}, + {"Real Time Text without audio", real_time_text_without_audio}, + {"Real Time Text with srtp", real_time_text_srtp}, + {"Real Time Text with ice", real_time_text_ice}, + {"Real Time Text message compatibility crlf", real_time_text_message_compat_crlf}, + {"Real Time Text message compatibility lf", real_time_text_message_compat_lf}, + {"Real Time Text message with accented characters", real_time_text_message_accented_chars}, + {"Real Time Text offer answer with different payload numbers (sender side)", real_time_text_message_different_text_codecs_payload_numbers_sender_side}, + {"Real Time Text offer answer with different payload numbers (receiver side)", real_time_text_message_different_text_codecs_payload_numbers_receiver_side}, + {"Real Time Text copy paste", real_time_text_copy_paste}, }; test_suite_t message_test_suite = { "Message", NULL, NULL, - sizeof(message_tests) / sizeof(message_tests[0]), - message_tests + liblinphone_tester_before_each, + liblinphone_tester_after_each, + sizeof(message_tests) / sizeof(message_tests[0]), message_tests }; - diff --git a/tester/multi_call.c b/tester/multi_call_tester.c similarity index 65% rename from tester/multi_call.c rename to tester/multi_call_tester.c index b0fed70cc..c8021afc3 100644 --- a/tester/multi_call.c +++ b/tester/multi_call_tester.c @@ -26,21 +26,21 @@ #include "mediastreamer2/msutils.h" #include "belle-sip/sipstack.h" -#ifdef WIN32 +#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* pauline = linphone_core_manager_new( "pauline_tcp_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); + LinphoneCallParams *laure_params=linphone_core_create_call_params(laure->lc, NULL); + LinphoneCallParams *marie_params=linphone_core_create_call_params(marie->lc, NULL); if (enable_caller_privacy) linphone_call_params_set_privacy(marie_params,LinphonePrivacyId); @@ -115,11 +115,11 @@ static void call_waiting_indication_with_privacy(void) { static void incoming_call_accepted_when_outgoing_call_in_state(LinphoneCallState state) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc"); MSList* lcs; - LinphoneCallParams *laure_params=linphone_core_create_default_call_parameters(laure->lc); - LinphoneCallParams *marie_params=linphone_core_create_default_call_parameters(marie->lc); + LinphoneCallParams *laure_params=linphone_core_create_call_params(laure->lc, NULL); + LinphoneCallParams *marie_params=linphone_core_create_call_params(marie->lc, NULL); lcs=ms_list_append(NULL,marie->lc); lcs=ms_list_append(lcs,pauline->lc); @@ -186,7 +186,7 @@ static void simple_conference_base(LinphoneCoreManager* marie, LinphoneCoreManag LinphoneCall* marie_call_pauline; LinphoneCall* pauline_called_by_marie; LinphoneCall* marie_call_laure; - + 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); @@ -218,6 +218,11 @@ static void simple_conference_base(LinphoneCoreManager* marie, LinphoneCoreManag BC_ASSERT_TRUE(linphone_core_is_in_conference(marie->lc)); BC_ASSERT_EQUAL(linphone_core_get_conference_size(marie->lc),3, int, "%d"); + BC_ASSERT_PTR_NULL(linphone_core_get_current_call(marie->lc)); + BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(pauline->lc)); + BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(laure->lc)); + + /* * 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) { @@ -229,6 +234,10 @@ static void simple_conference_base(LinphoneCoreManager* marie, LinphoneCoreManag } } */ + for (calls=linphone_core_get_calls(marie->lc);calls!=NULL;calls=calls->next) { + LinphoneCall *call=(LinphoneCall *)calls->data; + BC_ASSERT_EQUAL(linphone_core_get_media_encryption(marie->lc),linphone_call_params_get_media_encryption(linphone_call_get_current_params(call)),int,"%d"); + } linphone_core_terminate_conference(marie->lc); @@ -236,13 +245,12 @@ static void simple_conference_base(LinphoneCoreManager* marie, LinphoneCoreManag BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,10000)); BC_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* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc"); simple_conference_base(marie,pauline,laure); linphone_core_manager_destroy(marie); @@ -250,28 +258,69 @@ static void simple_conference(void) { linphone_core_manager_destroy(laure); } +static void simple_encrypted_conference_with_ice(LinphoneMediaEncryption mode) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); + LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc"); + + if (linphone_core_media_encryption_supported(marie->lc,mode)) { + 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"); + + /*work around a to avoid stun resolution to be initiate in call_received callback leading a mainloop reentrency*/ + /* + belle_sip_main_loop_iterate() at belle_sip_loop.c:369 + belle_sip_main_loop_run [inlined]() at belle_sip_loop.c:478 + belle_sip_main_loop_sleep() at belle_sip_loop.c:490 + sal_iterate() at sal_impl.c:745 + linphone_core_get_stun_server_addrinfo() at misc.c:585 + linphone_core_gather_ice_candidates() at misc.c:610 + linphone_call_prepare_ice() at linphonecall.c:1 906 + linphone_call_new_incoming() at linphonecall.c:1 101 + call_received() at callbacks.c:347 + ... + linphone_core_iterate() at linphonecore.c:2 620 + ... + + linphone_core_set_stun_server() initiates an asynchronous resolution, but it needs a few iteration before it is completed. + By calling private function linphone_core_get_stun_server_addrinfo() we make sure to wait that the resolution is done before the + test calls actually start. + */ + linphone_core_get_stun_server_addrinfo(marie->lc); + linphone_core_get_stun_server_addrinfo(pauline->lc); + linphone_core_get_stun_server_addrinfo(laure->lc); + /**/ + + linphone_core_set_media_encryption(marie->lc,mode); + linphone_core_set_media_encryption(pauline->lc,mode); + linphone_core_set_media_encryption(laure->lc,mode); + + simple_conference_base(marie,pauline,laure); + } else { + ms_warning("No [%s] support available",linphone_media_encryption_to_string(mode)); + BC_PASS("Passed"); + } + + 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); + simple_encrypted_conference_with_ice(LinphoneMediaEncryptionNone); +} +static void simple_zrtp_conference_with_ice(void) { + simple_encrypted_conference_with_ice(LinphoneMediaEncryptionZRTP); } static void simple_call_transfer(void) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc"); LinphoneCall* pauline_called_by_marie; LinphoneCall *marie_calling_pauline; @@ -315,13 +364,16 @@ static void simple_call_transfer(void) { marie_calling_laure=linphone_core_get_current_call(marie->lc); BC_ASSERT_PTR_NOT_NULL_FATAL(marie_calling_laure); - BC_ASSERT_TRUE(linphone_call_get_transferer_call(marie_calling_laure)==marie_calling_pauline); + BC_ASSERT_PTR_EQUAL(linphone_call_get_transferer_call(marie_calling_laure),marie_calling_pauline); BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneTransferCallConnected,1,2000)); /*terminate marie to pauline call*/ - BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,2000)); - BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,2000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallReleased,1,2000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallReleased,1,2000)); + + end_call(marie, laure); + BC_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallReleased,1,2000)); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); @@ -331,7 +383,7 @@ static void simple_call_transfer(void) { static void unattended_call_transfer(void) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc"); LinphoneCall* pauline_called_by_marie; @@ -369,6 +421,7 @@ static void unattended_call_transfer(void) { BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,2000)); + end_call(laure, pauline); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); linphone_core_manager_destroy(laure); @@ -377,7 +430,7 @@ static void unattended_call_transfer(void) { static void unattended_call_transfer_with_error(void) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneCall* pauline_called_by_marie; bool_t call_ok=TRUE; MSList* lcs=ms_list_append(NULL,marie->lc); @@ -407,6 +460,8 @@ static void unattended_call_transfer_with_error(void) { /*and call should be resumed*/ BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,2000)); + + end_call(marie, pauline); } linphone_core_manager_destroy(marie); @@ -417,7 +472,7 @@ static void unattended_call_transfer_with_error(void) { 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* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc"); LinphoneCall* marie_call_pauline; LinphoneCall* pauline_called_by_marie; @@ -427,7 +482,6 @@ static void call_transfer_existing_call_outgoing_call(void) { 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); @@ -483,32 +537,181 @@ static void call_transfer_existing_call_outgoing_call(void) { BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,2000)); BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,2,2000)); BC_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallEnd,1,2000)); + + end_call(pauline, laure); } + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(laure); + linphone_core_manager_destroy(pauline); + ms_list_free(lcs); +} + +static void eject_from_3_participants_conference(void) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); + LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc"); + + 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); + + BC_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); + BC_ASSERT_TRUE(pause_call_1(marie,marie_call_pauline,pauline,pauline_called_by_marie)); + + BC_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); + + BC_ASSERT_PTR_NOT_NULL_FATAL(marie_call_laure); + + linphone_core_add_to_conference(marie->lc,marie_call_laure); + BC_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); + + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallResuming,initial_marie_stat.number_of_LinphoneCallResuming+1,2000)); + + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,initial_pauline_stat.number_of_LinphoneCallStreamsRunning+1,5000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallStreamsRunning,initial_laure_stat.number_of_LinphoneCallStreamsRunning+1,2000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,initial_marie_stat.number_of_LinphoneCallStreamsRunning+2,3000)); + + BC_ASSERT_TRUE(linphone_core_is_in_conference(marie->lc)); + BC_ASSERT_EQUAL(linphone_core_get_conference_size(marie->lc),3, int, "%d"); + + BC_ASSERT_PTR_NULL(linphone_core_get_current_call(marie->lc)); + + linphone_core_remove_from_conference(marie->lc, marie_call_pauline); + + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallPausedByRemote,1,10000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallStreamsRunning,3,10000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,5,10000)); + BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(marie->lc)); + BC_ASSERT_EQUAL(ms_list_size(linphone_core_get_calls(marie->lc)), 2, int, "%d"); + BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(pauline->lc)); + BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(laure->lc)); + end_call(laure, marie); + end_call(pauline, marie); + + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,10000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,10000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallEnd,1,10000)); + + ms_list_free(lcs); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); linphone_core_manager_destroy(laure); +} + +static void eject_from_4_participants_conference(void) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); + LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc"); + LinphoneCoreManager* michelle = linphone_core_manager_new( "michelle_rc"); + int timeout_ms = 5000; + stats initial_laure_stat; + stats initial_michelle_stat; + + LinphoneCall* marie_call_pauline; + LinphoneCall* pauline_called_by_marie; + LinphoneCall* marie_call_laure; + LinphoneCall* marie_call_michelle; + LinphoneCall* michelle_called_by_marie; + MSList* lcs=ms_list_append(NULL,marie->lc); + lcs=ms_list_append(lcs,pauline->lc); + lcs=ms_list_append(lcs,laure->lc); + lcs=ms_list_append(lcs,michelle->lc); + + BC_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); + BC_ASSERT_TRUE(pause_call_1(marie,marie_call_pauline,pauline,pauline_called_by_marie)); + + BC_ASSERT_TRUE(call(marie,michelle)); + marie_call_michelle=linphone_core_get_current_call(marie->lc); + michelle_called_by_marie=linphone_core_get_current_call(michelle->lc); + BC_ASSERT_TRUE(pause_call_1(marie,marie_call_michelle,michelle,michelle_called_by_marie)); + + BC_ASSERT_TRUE(call(marie,laure)); + initial_laure_stat=laure->stat; + initial_michelle_stat=michelle->stat; + + marie_call_laure=linphone_core_get_current_call(marie->lc); + + BC_ASSERT_PTR_NOT_NULL_FATAL(marie_call_laure); + + linphone_core_add_to_conference(marie->lc,marie_call_laure); + linphone_core_add_to_conference(marie->lc,marie_call_michelle); + linphone_core_add_to_conference(marie->lc,marie_call_pauline); + + while (linphone_core_get_conference_size(marie->lc)!=4&&timeout_ms) { + wait_for_list(lcs, NULL, 0, 100); + timeout_ms -= 100; + } + BC_ASSERT_TRUE(linphone_core_is_in_conference(marie->lc)); + BC_ASSERT_EQUAL(linphone_core_get_conference_size(marie->lc),4, int, "%d"); + + BC_ASSERT_PTR_NULL(linphone_core_get_current_call(marie->lc)); + + linphone_core_remove_from_conference(marie->lc, marie_call_pauline); + + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallPausedByRemote,1,10000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallStreamsRunning,initial_laure_stat.number_of_LinphoneCallStreamsRunning+1,10000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&michelle->stat.number_of_LinphoneCallStreamsRunning,initial_michelle_stat.number_of_LinphoneCallStreamsRunning+1,10000)); + + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,5,10000)); + BC_ASSERT_PTR_NULL(linphone_core_get_current_call(marie->lc)); + BC_ASSERT_TRUE(linphone_core_is_in_conference(marie->lc)); + BC_ASSERT_EQUAL(linphone_core_get_conference_size(marie->lc),3, int, "%d"); + BC_ASSERT_EQUAL(ms_list_size(linphone_core_get_calls(marie->lc)), 3, int, "%d"); + BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(pauline->lc)); + BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(laure->lc)); + BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(michelle->lc)); + end_call(laure, marie); + end_call(pauline, marie); + end_call(michelle, marie); + + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,10000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,10000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallEnd,1,10000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&michelle->stat.number_of_LinphoneCallEnd,1,10000)); + ms_list_free(lcs); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(laure); + linphone_core_manager_destroy(michelle); } test_t multi_call_tests[] = { { "Call waiting indication", call_waiting_indication }, { "Call waiting indication with privacy", call_waiting_indication_with_privacy }, + { "Incoming call accepted when outgoing call in progress",incoming_call_accepted_when_outgoing_call_in_progress}, + { "Incoming call accepted when outgoing call in outgoing ringing",incoming_call_accepted_when_outgoing_call_in_outgoing_ringing}, + { "Incoming call accepted when outgoing call in outgoing ringing early media",incoming_call_accepted_when_outgoing_call_in_outgoing_ringing_early_media}, { "Simple conference", simple_conference }, { "Simple conference with ICE",simple_conference_with_ice}, + { "Simple ZRTP conference with ICE",simple_zrtp_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 }, - { "Incoming call accepted when outgoing call in progress",incoming_call_accepted_when_outgoing_call_in_progress}, - { "Incoming call accepted when outgoing call in outgoing ringing",incoming_call_accepted_when_outgoing_call_in_outgoing_ringing}, - { "Incoming call accepted when outgoing call in outgoing ringing early media",incoming_call_accepted_when_outgoing_call_in_outgoing_ringing_early_media}, + { "Eject from 3 participants conference", eject_from_3_participants_conference }, + { "Eject from 4 participants conference", eject_from_4_participants_conference }, }; -test_suite_t multi_call_test_suite = { - "Multi call", - NULL, - NULL, - sizeof(multi_call_tests) / sizeof(multi_call_tests[0]), - multi_call_tests -}; +test_suite_t multi_call_test_suite = {"Multi call", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each, + sizeof(multi_call_tests) / sizeof(multi_call_tests[0]), multi_call_tests}; diff --git a/tester/multicast_call_tester.c b/tester/multicast_call_tester.c index 3453463a0..8d9123ad3 100644 --- a/tester/multicast_call_tester.c +++ b/tester/multicast_call_tester.c @@ -24,14 +24,10 @@ static void call_multicast_base(bool_t video) { LinphoneCoreManager *marie, *pauline; - int begin; - int leaked_objects; LinphoneVideoPolicy marie_policy, pauline_policy; - 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"); + pauline = linphone_core_manager_new( "pauline_tcp_rc"); if (video) { linphone_core_enable_video_capture(marie->lc, TRUE); @@ -53,12 +49,12 @@ static void call_multicast_base(bool_t video) { linphone_core_enable_audio_multicast(pauline->lc,TRUE); BC_ASSERT_TRUE(call(pauline,marie)); - wait_for_until(marie->lc, pauline->lc, NULL, 1, 3000); + wait_for_until(marie->lc, pauline->lc, NULL, 1, 6000); if (linphone_core_get_current_call(marie->lc)) { - BC_ASSERT_GREATER(linphone_call_get_audio_stats(linphone_core_get_current_call(marie->lc))->download_bandwidth,70,int,"%d"); + BC_ASSERT_GREATER(linphone_core_manager_get_max_audio_down_bw(marie),70,int,"%d"); if (video) { /*check video path*/ - linphone_call_set_next_video_frame_decoded_callback(linphone_core_get_current_call(marie->lc),linphone_call_cb,marie->lc); + linphone_call_set_next_video_frame_decoded_callback(linphone_core_get_current_call(marie->lc),linphone_call_iframe_decoded_cb,marie->lc); linphone_call_send_vfu_request(linphone_core_get_current_call(marie->lc)); BC_ASSERT_TRUE( wait_for(marie->lc,pauline->lc,&marie->stat.number_of_IframeDecoded,1)); } @@ -67,20 +63,12 @@ static void call_multicast_base(bool_t video) { } linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); - - leaked_objects=belle_sip_object_get_object_count()-begin; - BC_ASSERT_TRUE(leaked_objects==0); - if (leaked_objects>0){ - belle_sip_object_dump_active_objects(); - } - belle_sip_object_enable_leak_detector(FALSE); - } static void call_multicast(void) { call_multicast_base(FALSE); } -static void multicast_audio_with_pause_resume() { +static void multicast_audio_with_pause_resume(void) { call_paused_resumed_base(TRUE); } #ifdef VIDEO_ENABLED @@ -92,17 +80,13 @@ static void early_media_with_multicast_base(bool_t video) { LinphoneCoreManager *marie, *pauline, *pauline2; MSList* lcs = NULL; int dummy=0; - int leaked_objects; - int begin; LinphoneVideoPolicy marie_policy, pauline_policy; LpConfig *marie_lp; LinphoneCallParams *params; - 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"); - pauline2 = linphone_core_manager_new("pauline_rc"); + pauline = linphone_core_manager_new("pauline_tcp_rc"); + pauline2 = linphone_core_manager_new("pauline_tcp_rc"); marie_lp=linphone_core_get_config(marie->lc); lp_config_set_int(marie_lp,"misc","real_early_media",1); @@ -114,6 +98,14 @@ static void early_media_with_multicast_base(bool_t video) { linphone_core_enable_video_display(pauline2->lc, TRUE); linphone_core_enable_video_capture(marie->lc, TRUE); linphone_core_enable_video_display(marie->lc, FALSE); + + linphone_core_set_video_device(pauline->lc, liblinphone_tester_mire_id); + linphone_core_set_video_device(pauline2->lc, liblinphone_tester_mire_id); + linphone_core_set_video_device(marie->lc, liblinphone_tester_mire_id); + + linphone_core_set_avpf_mode(pauline->lc, LinphoneAVPFEnabled); + linphone_core_set_avpf_mode(pauline2->lc, LinphoneAVPFEnabled); + linphone_core_set_avpf_mode(marie->lc, LinphoneAVPFEnabled); marie_policy.automatically_initiate=TRUE; marie_policy.automatically_accept=TRUE; @@ -147,7 +139,7 @@ static void early_media_with_multicast_base(bool_t video) { /* send a 183 to initiate the early media */ if (video) { /*check video path*/ - linphone_call_set_next_video_frame_decoded_callback(linphone_core_get_current_call(pauline->lc),linphone_call_cb,pauline->lc); + linphone_call_set_next_video_frame_decoded_callback(linphone_core_get_current_call(pauline->lc),linphone_call_iframe_decoded_cb,pauline->lc); } linphone_core_accept_early_media(pauline->lc, linphone_core_get_current_call(pauline->lc)); @@ -158,7 +150,7 @@ static void early_media_with_multicast_base(bool_t video) { /* send a 183 to initiate the early media */ if (video) { /*check video path*/ - linphone_call_set_next_video_frame_decoded_callback(linphone_core_get_current_call(pauline2->lc),linphone_call_cb,pauline2->lc); + linphone_call_set_next_video_frame_decoded_callback(linphone_core_get_current_call(pauline2->lc),linphone_call_iframe_decoded_cb,pauline2->lc); } linphone_core_accept_early_media(pauline2->lc, linphone_core_get_current_call(pauline2->lc)); @@ -167,10 +159,10 @@ static void early_media_with_multicast_base(bool_t video) { wait_for_list(lcs, &dummy, 1, 3000); - BC_ASSERT_TRUE(linphone_call_get_audio_stats(linphone_core_get_current_call(pauline->lc))->download_bandwidth>70); + BC_ASSERT_GREATER(linphone_core_manager_get_max_audio_down_bw(pauline),70,int,"%i"); BC_ASSERT_TRUE(linphone_call_get_audio_stats(linphone_core_get_current_call(pauline->lc))->download_bandwidth<90); - BC_ASSERT_TRUE(linphone_call_get_audio_stats(linphone_core_get_current_call(pauline2->lc))->download_bandwidth>70); + BC_ASSERT_GREATER(linphone_core_manager_get_max_audio_down_bw(pauline2),70,int,"%i"); BC_ASSERT_TRUE(linphone_call_get_audio_stats(linphone_core_get_current_call(pauline2->lc))->download_bandwidth<90); BC_ASSERT_TRUE(linphone_call_params_audio_multicast_enabled(linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc)))); @@ -197,7 +189,7 @@ static void early_media_with_multicast_base(bool_t video) { BC_ASSERT_TRUE(linphone_call_params_video_multicast_enabled(linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc)))); BC_ASSERT_TRUE(linphone_call_params_video_multicast_enabled(linphone_call_get_current_params(linphone_core_get_current_call(marie->lc)))); } - params=linphone_call_params_copy(linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc))); + params = linphone_core_create_call_params(pauline->lc, linphone_core_get_current_call(pauline->lc)); linphone_call_params_enable_audio_multicast(params,FALSE); linphone_call_params_enable_video_multicast(params,FALSE); @@ -237,23 +229,16 @@ static void early_media_with_multicast_base(bool_t video) { linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); linphone_core_manager_destroy(pauline2); - - leaked_objects=belle_sip_object_get_object_count()-begin; - BC_ASSERT_EQUAL(leaked_objects,0, int, "%d"); - if (leaked_objects>0){ - belle_sip_object_dump_active_objects(); - } - belle_sip_object_enable_leak_detector(FALSE); } -static void early_media_with_multicast_audio() { +static void early_media_with_multicast_audio(void) { early_media_with_multicast_base(FALSE); } -static void unicast_incoming_with_multicast_audio_on() { +static void unicast_incoming_with_multicast_audio_on(void) { simple_call_base(TRUE); } #ifdef VIDEO_ENABLED -static void early_media_with_multicast_video() { +static void early_media_with_multicast_video(void) { early_media_with_multicast_base(TRUE); } #endif @@ -269,10 +254,6 @@ test_t multicast_call_tests[] = { #endif }; -test_suite_t multicast_call_test_suite = { - "Multicast Call", - NULL, - NULL, - sizeof(multicast_call_tests) / sizeof(multicast_call_tests[0]), - multicast_call_tests -}; +test_suite_t multicast_call_test_suite = {"Multicast Call", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each, + sizeof(multicast_call_tests) / sizeof(multicast_call_tests[0]), + multicast_call_tests}; diff --git a/tester/offeranswer_tester.c b/tester/offeranswer_tester.c index 67d9c9d62..bca89abdd 100644 --- a/tester/offeranswer_tester.c +++ b/tester/offeranswer_tester.c @@ -43,13 +43,13 @@ static void start_with_no_config(void){ int speex16_codec_pos=get_codec_position(codecs, "speex", 16000); PayloadType *pt; opus_codec_pos=get_codec_position(codecs, "opus", 48000); - if (opus_codec_pos!=-1) BC_ASSERT_TRUE(opus_codec_pos==0); - BC_ASSERT_TRUE(speex16_codec_poslc,"pcmu",-1); disable_all_audio_codecs_except_one(pauline->lc,"pcmu",-1); @@ -111,52 +106,34 @@ static void simple_call_with_different_codec_mappings(void) { end_call(marie,pauline); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); - - leaked_objects=belle_sip_object_get_object_count()-begin; - BC_ASSERT_TRUE(leaked_objects==0); - if (leaked_objects>0){ - belle_sip_object_dump_active_objects(); - } } static void call_failed_because_of_codecs(void) { - int begin,leaked_objects; + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); + LinphoneCall* out_call; - belle_sip_object_enable_leak_detector(TRUE); - begin=belle_sip_object_get_object_count(); + disable_all_audio_codecs_except_one(marie->lc,"pcmu",-1); + disable_all_audio_codecs_except_one(pauline->lc,"pcma",-1); + out_call = linphone_core_invite_address(pauline->lc,marie->identity); + linphone_call_ref(out_call); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallOutgoingInit,1)); - { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - LinphoneCall* out_call; + /*flexisip will retain the 488 until the "urgent reply" timeout (I.E 5s) arrives.*/ + BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallError,1,7000)); + BC_ASSERT_EQUAL(linphone_call_get_reason(out_call),LinphoneReasonNotAcceptable, int, "%d"); + BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallIncomingReceived,0, int, "%d"); + BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallReleased,0, int, "%d"); - disable_all_audio_codecs_except_one(marie->lc,"pcmu",-1); - disable_all_audio_codecs_except_one(pauline->lc,"pcma",-1); - out_call = linphone_core_invite_address(pauline->lc,marie->identity); - linphone_call_ref(out_call); - BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallOutgoingInit,1)); - - /*flexisip will retain the 488 until the "urgent reply" timeout (I.E 5s) arrives.*/ - BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallError,1,7000)); - BC_ASSERT_EQUAL(linphone_call_get_reason(out_call),LinphoneReasonNotAcceptable, int, "%d"); - BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallIncomingReceived,0, int, "%d"); - BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallReleased,0, int, "%d"); - - linphone_call_unref(out_call); - linphone_core_manager_destroy(marie); - linphone_core_manager_destroy(pauline); - } - leaked_objects=belle_sip_object_get_object_count()-begin; - BC_ASSERT_TRUE(leaked_objects==0); - if (leaked_objects>0){ - belle_sip_object_dump_active_objects(); - } + linphone_call_unref(out_call); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); } 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"); + LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc"); LinphoneProxyConfig *lpc; const LinphoneCallParams *params; @@ -214,7 +191,7 @@ end: } 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); + profile_call_base(avpf1, srtp1, avpf2,srtp2,FALSE,expected_profile); } static void avp_to_avp_call(void) { profile_call(FALSE, LinphoneMediaEncryptionNone, FALSE, LinphoneMediaEncryptionNone, "RTP/AVP"); @@ -298,6 +275,94 @@ static void savpf_dtls_to_avpf_call(void) { profile_call(TRUE, LinphoneMediaEncryptionDTLS, TRUE, LinphoneMediaEncryptionNone, "UDP/TLS/RTP/SAVPF"); } +#ifdef VIDEO_ENABLED +static LinphonePayloadType * configure_core_for_avpf_and_video(LinphoneCore *lc) { + LinphoneProxyConfig *lpc; + LinphonePayloadType *lpt; + LinphoneVideoPolicy policy = { 0 }; + + policy.automatically_initiate = TRUE; + policy.automatically_accept = TRUE; + linphone_core_get_default_proxy(lc, &lpc); + linphone_proxy_config_enable_avpf(lpc, TRUE); + linphone_proxy_config_set_avpf_rr_interval(lpc, 3); + linphone_core_set_video_device(lc, "StaticImage: Static picture"); + linphone_core_enable_video_capture(lc, TRUE); + linphone_core_enable_video_display(lc, TRUE); + linphone_core_set_video_policy(lc, &policy); + lpt = linphone_core_find_payload_type(lc, "VP8", 90000, -1); + if (lpt == NULL) { + ms_warning("VP8 codec not available."); + } else { + disable_all_video_codecs_except_one(lc, "VP8"); + } + return lpt; +} + +static void check_avpf_features(LinphoneCore *lc, unsigned char expected_features) { + LinphoneCall *lcall = linphone_core_get_current_call(lc); + BC_ASSERT_PTR_NOT_NULL(lcall); + if (lcall != NULL) { + SalStreamDescription *desc = sal_media_description_find_stream(lcall->resultdesc, SalProtoRtpAvpf, SalVideo); + BC_ASSERT_PTR_NOT_NULL(desc); + if (desc != NULL) { + BC_ASSERT_PTR_NOT_NULL(desc->payloads); + if (desc->payloads) { + PayloadType *pt = (PayloadType *)desc->payloads->data; + BC_ASSERT_STRING_EQUAL(pt->mime_type, "VP8"); + BC_ASSERT_EQUAL(pt->avpf.features, expected_features, int, "%d"); + } + } + } +} + +static void compatible_avpf_features(void) { + LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc"); + LinphonePayloadType *lpt; + bool_t call_ok; + + if (configure_core_for_avpf_and_video(marie->lc) == NULL) goto end; + lpt = configure_core_for_avpf_and_video(pauline->lc); + + BC_ASSERT_TRUE((call_ok=call(marie, pauline))); + if (!call_ok) goto end; + + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 1)); + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1)); + check_avpf_features(marie->lc, lpt->avpf.features); + check_avpf_features(pauline->lc, lpt->avpf.features); + + end_call(marie,pauline); +end: + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(marie); +} + +static void incompatible_avpf_features(void) { + LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc"); + LinphonePayloadType *lpt; + bool_t call_ok; + + if (configure_core_for_avpf_and_video(marie->lc) == NULL) goto end; + lpt = configure_core_for_avpf_and_video(pauline->lc); + lpt->avpf.features = PAYLOAD_TYPE_AVPF_NONE; + + BC_ASSERT_TRUE(call_ok=call(marie, pauline)); + if (!call_ok) goto end; + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 1)); + BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1)); + check_avpf_features(marie->lc, PAYLOAD_TYPE_AVPF_NONE); + check_avpf_features(pauline->lc, PAYLOAD_TYPE_AVPF_NONE); + + end_call(marie,pauline); +end: + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(marie); +} +#endif + static test_t offeranswer_tests[] = { { "Start with no config", start_with_no_config }, { "Call failed because of codecs", call_failed_because_of_codecs }, @@ -323,13 +388,11 @@ static test_t offeranswer_tests[] = { { "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}, - +#ifdef VIDEO_ENABLED + { "Compatible AVPF features", compatible_avpf_features }, + { "Incompatible AVPF features", incompatible_avpf_features }, +#endif }; -test_suite_t offeranswer_test_suite = { - "Offer-answer", - NULL, - NULL, - sizeof(offeranswer_tests) / sizeof(offeranswer_tests[0]), - offeranswer_tests -}; +test_suite_t offeranswer_test_suite = {"Offer-answer", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each, + sizeof(offeranswer_tests) / sizeof(offeranswer_tests[0]), offeranswer_tests}; diff --git a/tester/player_tester.c b/tester/player_tester.c index 909fdffe9..f5c0c3cb9 100644 --- a/tester/player_tester.c +++ b/tester/player_tester.c @@ -32,36 +32,39 @@ static void eof_callback(LinphonePlayer *player, void *user_data) { *eof = TRUE; } -static void play_file(const char *filename, bool_t unsupported_format, const char *audio_mime, const char *video_mime) { +static void play_file(const char *filename, bool_t supported_format, const char *audio_mime, const char *video_mime) { LinphoneCoreManager *lc_manager; LinphonePlayer *player; int res, time = 0; bool_t eof = FALSE; + bool_t audio_codec_supported; + bool_t video_codec_supported; lc_manager = linphone_core_manager_new("marie_rc"); BC_ASSERT_PTR_NOT_NULL(lc_manager); if(lc_manager == NULL) return; + + audio_codec_supported = (audio_mime && ms_factory_get_decoder(ms_factory_get_fallback(), audio_mime)); + video_codec_supported = (video_mime && ms_factory_get_decoder(ms_factory_get_fallback(), video_mime)); player = linphone_core_create_local_player(lc_manager->lc, ms_snd_card_manager_get_default_card(ms_snd_card_manager_get()), video_stream_get_default_video_renderer(), 0); BC_ASSERT_PTR_NOT_NULL(player); if(player == NULL) goto fail; res = linphone_player_open(player, filename, eof_callback, &eof); - if(unsupported_format - || (audio_mime == NULL && video_mime == NULL) - || (video_mime == NULL && audio_mime && !ms_filter_codec_supported(audio_mime)) - || (audio_mime == NULL && video_mime && !ms_filter_codec_supported(video_mime))) { - BC_ASSERT_EQUAL(res, -1, int, "%d"); - } else { + if(supported_format && (audio_codec_supported || video_codec_supported)) { BC_ASSERT_EQUAL(res, 0, int, "%d"); + } else { + BC_ASSERT_EQUAL(res, -1, int, "%d"); } + if(res == -1) goto fail; res = linphone_player_start(player); BC_ASSERT_EQUAL(res, 0, int, "%d"); if(res == -1) goto fail; - BC_ASSERT_TRUE(wait_for_eof(&eof, &time, 100, 13000)); + BC_ASSERT_TRUE(wait_for_eof(&eof, &time, 100, (int)(linphone_player_get_duration(player) * 1.05))); linphone_player_close(player); @@ -70,22 +73,35 @@ static void play_file(const char *filename, bool_t unsupported_format, const cha if(lc_manager) linphone_core_manager_destroy(lc_manager); } -static void playing_test(void) { - char *filename = ms_strdup_printf("%s/sounds/hello_opus_h264.mkv", bc_tester_read_dir_prefix); +static void sintel_trailer_opus_h264_test(void) { + char *filename = bc_tester_res("sounds/sintel_trailer_opus_h264.mkv"); const char *audio_mime = "opus"; - const char *video_mime = "h264"; - play_file(filename, !linphone_local_player_matroska_supported(), audio_mime, video_mime); + const char *video_mime = "H264"; + play_file(filename, linphone_local_player_matroska_supported(), audio_mime, video_mime); + ms_free(filename); +} + +static void sintel_trailer_pcmu_h264_test(void) { + char *filename = bc_tester_res("sounds/sintel_trailer_pcmu_h264.mkv"); + const char *audio_mime = "pcmu"; + const char *video_mime = "H264"; + play_file(filename, linphone_local_player_matroska_supported(), audio_mime, video_mime); + ms_free(filename); +} + +static void sintel_trailer_opus_vp8_test(void) { + char *filename = bc_tester_res("sounds/sintel_trailer_opus_vp8.mkv"); + const char *audio_mime = "opus"; + const char *video_mime = "VP8"; + play_file(filename, linphone_local_player_matroska_supported(), audio_mime, video_mime); ms_free(filename); } test_t player_tests[] = { - { "Local MKV file" , playing_test } + { "Sintel trailer opus/h264" , sintel_trailer_opus_h264_test }, + { "Sintel trailer pcmu/h264" , sintel_trailer_pcmu_h264_test }, + { "Sintel trailer opus/VP8" , sintel_trailer_opus_vp8_test } }; -test_suite_t player_test_suite = { - "Player", - NULL, - NULL, - sizeof(player_tests) / sizeof(test_t), - player_tests -}; +test_suite_t player_test_suite = {"Player", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each, + sizeof(player_tests) / sizeof(test_t), player_tests}; diff --git a/tester/presence_tester.c b/tester/presence_tester.c index ef16102a0..6a9d758cd 100644 --- a/tester/presence_tester.c +++ b/tester/presence_tester.c @@ -28,12 +28,14 @@ static LinphoneCoreManager* presence_linphone_core_manager_new(char* username) { linphone_address_set_username(mgr->identity,username); identity_char=linphone_address_as_string(mgr->identity); linphone_core_set_primary_contact(mgr->lc,identity_char); + ms_free(identity_char); return mgr; } + void new_subscription_requested(LinphoneCore *lc, LinphoneFriend *lf, const char *url){ char* from=linphone_address_as_string(linphone_friend_get_address(lf)); stats* counters; - ms_message("New subscription request from [%s] url [%s]",from,url); + ms_message("New subscription request from [%s] url [%s]",from,url); ms_free(from); counters = get_stats(lc); counters->number_of_NewSubscriptionRequest++; @@ -141,11 +143,11 @@ static void simple_publish_with_expire(int expires) { linphone_core_manager_destroy(marie); } -static void simple_publish() { +static void simple_publish(void) { simple_publish_with_expire(-1); } -static void publish_with_expires() { +static void publish_with_expires(void) { simple_publish_with_expire(1); } @@ -162,6 +164,7 @@ static bool_t subscribe_to_callee_presence(LinphoneCoreManager* caller_mgr,Linph linphone_friend_done(friend); linphone_core_add_friend(caller_mgr->lc,friend); + linphone_friend_unref(friend); result=wait_for(caller_mgr->lc,callee_mgr->lc,&caller_mgr->stat.number_of_LinphonePresenceActivityOnline,initial_caller.number_of_LinphonePresenceActivityOnline+1); /*without proxy, callee cannot subscribe to caller @@ -180,11 +183,12 @@ static bool_t subscribe_to_callee_presence(LinphoneCoreManager* caller_mgr,Linph } static void subscribe_failure_handle_by_app(void) { LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new("pauline_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new("pauline_tcp_rc"); LinphoneProxyConfig* config; LinphoneFriend* lf; char* lf_identity=linphone_address_as_string_uri_only(pauline->identity); - linphone_core_get_default_proxy(marie->lc,&config); + + linphone_core_get_default_proxy(marie->lc,&config); BC_ASSERT_TRUE(subscribe_to_callee_presence(marie,pauline)); wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_NewSubscriptionRequest,1); /*just to wait for unsubscription even if not notified*/ @@ -232,6 +236,7 @@ static void unsubscribe_while_subscribing(void) { linphone_friend_enable_subscribes(friend,TRUE); linphone_friend_done(friend); linphone_core_add_friend(marie->lc,friend); + linphone_friend_unref(friend); linphone_core_iterate(marie->lc); linphone_core_manager_destroy(marie); } @@ -299,7 +304,7 @@ static void presence_information(void) { BC_ASSERT_EQUAL(linphone_presence_activity_get_type(activity), LinphonePresenceActivitySteering, int, "%d"); description = linphone_presence_activity_get_description(activity); BC_ASSERT_PTR_NOT_NULL(description); - if (description != NULL) BC_ASSERT_EQUAL(strcmp(description, bike_description), 0, int, "%d"); + if (description != NULL) BC_ASSERT_STRING_EQUAL(description, bike_description); /* Presence activity with description and note. */ presence = linphone_presence_model_new_with_activity_and_note(LinphonePresenceActivityVacation, NULL, vacation_note, vacation_lang); @@ -317,7 +322,7 @@ static void presence_information(void) { note_content = linphone_presence_note_get_content(note); BC_ASSERT_PTR_NOT_NULL(note_content); if (note_content != NULL) { - BC_ASSERT_EQUAL(strcmp(note_content, vacation_note), 0, int, "%d"); + BC_ASSERT_STRING_EQUAL(note_content, vacation_note); } } @@ -330,7 +335,7 @@ static void presence_information(void) { contact2 = linphone_presence_model_get_contact(presence); BC_ASSERT_PTR_NOT_NULL(contact2); if (contact2 != NULL) { - BC_ASSERT_EQUAL(strcmp(contact, contact2), 0, int, "%d"); + BC_ASSERT_STRING_EQUAL(contact, contact2); ms_free(contact2); } @@ -341,11 +346,89 @@ static void presence_information(void) { wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityShopping,1); BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePresenceActivityShopping, 1, int, "%d"); presence_timestamp = linphone_presence_model_get_timestamp(presence); - BC_ASSERT_TRUE(presence_timestamp >= current_timestamp); + BC_ASSERT_GREATER((unsigned)presence_timestamp , (unsigned)current_timestamp, unsigned, "%u"); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } + + +static void subscribe_presence_forked(void){ + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline1 = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + LinphoneCoreManager* pauline2 = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + LinphoneFriend *lf; + MSList *lcs = NULL; + + lcs = ms_list_append(lcs, marie->lc); + lcs = ms_list_append(lcs, pauline1->lc); + lcs = ms_list_append(lcs, pauline2->lc); + + lf = linphone_core_create_friend(marie->lc); + linphone_friend_set_address(lf, pauline1->identity); + linphone_friend_enable_subscribes(lf, TRUE); + + linphone_core_add_friend(marie->lc, lf); + linphone_friend_unref(lf); + + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline1->stat.number_of_NewSubscriptionRequest,1, 10000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline2->stat.number_of_NewSubscriptionRequest,1, 2000)); + /*we should get two notifies*/ + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePresenceActivityOnline,2, 10000)); + + /*marie also shall receive two SUBSCRIBEs from the two paulines, but won't be notified to the app since + Marie set Pauline as a friend.*/ + BC_ASSERT_EQUAL(marie->stat.number_of_NewSubscriptionRequest, 0, int, "%d"); + /*and the two paulines shall be notified of marie's presence*/ + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline1->stat.number_of_LinphonePresenceActivityOnline,1, 3000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline2->stat.number_of_LinphonePresenceActivityOnline,1, 2000)); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline1); + linphone_core_manager_destroy(pauline2); + + ms_list_free(lcs); +} + +static void subscribe_presence_expired(void){ + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline1 = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + LinphoneFriend *lf; + MSList *lcs = NULL; + + lcs = ms_list_append(lcs, marie->lc); + lcs = ms_list_append(lcs, pauline1->lc); + + lp_config_set_int(marie->lc->config, "sip", "subscribe_expires", 10); + + lf = linphone_core_create_friend(marie->lc); + linphone_friend_set_address(lf, pauline1->identity); + linphone_friend_enable_subscribes(lf, TRUE); + + linphone_core_add_friend(marie->lc, lf); + linphone_friend_unref(lf); + + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline1->stat.number_of_NewSubscriptionRequest,1, 5000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePresenceActivityOnline,1, 2000)); + + lf = linphone_core_find_friend(pauline1->lc, marie->identity); + BC_ASSERT_PTR_NOT_NULL(lf->insubs); + /*marie comes offline suddenly*/ + linphone_core_set_network_reachable(marie->lc, FALSE); + /*after a certain time, pauline shall see the incoming SUBSCRIBE expired*/ + wait_for_list(lcs,NULL, 0, 11000); + + BC_ASSERT_PTR_NULL(lf->insubs); + /*just make network reachable so that marie can unregister properly*/ + linphone_core_set_network_reachable(marie->lc, TRUE); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneRegistrationOk,2, 10000)); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline1); + + ms_list_free(lcs); +} + + #define USE_PRESENCE_SERVER 0 #if USE_PRESENCE_SERVER @@ -476,17 +559,13 @@ test_t presence_tests[] = { { "Unsubscribe while subscribing", unsubscribe_while_subscribing }, { "Presence information", presence_information }, { "App managed presence failure", subscribe_failure_handle_by_app }, + { "Presence SUBSCRIBE forked", subscribe_presence_forked }, + { "Presence SUBSCRIBE expired", subscribe_presence_expired }, #if USE_PRESENCE_SERVER { "Subscribe with late publish", test_subscribe_notify_publish }, { "Forked subscribe with late publish", test_forked_subscribe_notify_publish }, #endif }; -test_suite_t presence_test_suite = { - "Presence", - NULL, - NULL, - sizeof(presence_tests) / sizeof(presence_tests[0]), - presence_tests -}; - +test_suite_t presence_test_suite = {"Presence", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each, + sizeof(presence_tests) / sizeof(presence_tests[0]), presence_tests}; diff --git a/tester/proxy_config_tester.c b/tester/proxy_config_tester.c new file mode 100644 index 000000000..771403e84 --- /dev/null +++ b/tester/proxy_config_tester.c @@ -0,0 +1,183 @@ +/* + 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 "liblinphone_tester.h" + +#include + +const char* phone_normalization(LinphoneProxyConfig *proxy, const char* in) { + static char result[255]; + char * output = linphone_proxy_config_normalize_phone_number(proxy, in); + if (output) { + memcpy(result, output, strlen(output)+1); + ms_free(output); + return result; + } else { + return NULL; + } +} + +static void phone_normalization_without_proxy(void) { + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "012 345 6789"), "0123456789"); + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "+33123456789"), "+33123456789"); + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "+33012345678"), "+33012345678"); + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "+33 0012345678"), "+330012345678"); + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "+33012345678"), "+33012345678"); + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "+3301234567891"), "+3301234567891"); + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "+33 01234567891"), "+3301234567891"); + BC_ASSERT_PTR_NULL(phone_normalization(NULL, "I_AM_NOT_A_NUMBER")); // invalid phone number + + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "0"), "0"); + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "01"), "01"); + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "012"), "012"); + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "0123"), "0123"); + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "01234"), "01234"); + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "012345"), "012345"); + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "0123456"), "0123456"); + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "01234567"), "01234567"); + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "012345678"), "012345678"); + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "0123456789"), "0123456789"); + BC_ASSERT_STRING_EQUAL(phone_normalization(NULL, "01234567890"), "01234567890"); +} + +static void phone_normalization_with_proxy(void) { + LinphoneProxyConfig *proxy = linphone_proxy_config_new(); + linphone_proxy_config_set_dial_prefix(proxy, "33"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "012 3456 789"), "+33123456789"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+33123456789"), "+33123456789"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+33 0123456789"), "+330123456789"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+330012345678"), "+330012345678"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+3301 2345678"), "+33012345678"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+3301234567891"), "+3301234567891"); + + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "123456789"), "+33123456789"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, " 0123456789"), "+33123456789"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0012345678"), "+12345678"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "01 2345678"), "+33012345678"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "01234567891"), "+33234567891"); // invalid phone number (too long) + BC_ASSERT_PTR_NULL(phone_normalization(proxy, "I_AM_NOT_A_NUMBER")); // invalid phone number + + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+990012345678"), "+990012345678"); + + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0952636505"), "+33952636505"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "09 52 63 65 05"), "+33952636505"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "09-52-63-65-05"), "+33952636505"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+31952636505"), "+31952636505"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0033952636505"), "+33952636505"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0033952636505"), "+33952636505"); + BC_ASSERT_PTR_NULL(phone_normalization(proxy, "toto")); + + + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0"), "+330"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "01"), "+3301"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "012"), "+33012"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0123"), "+330123"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "01234"), "+3301234"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "012345"), "+33012345"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0123456"), "+330123456"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "01234567"), "+3301234567"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "012345678"), "+33012345678"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0123456789"), "+33123456789"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "01234567890"), "+33234567890"); + + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+330"), "+330"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+3301"), "+3301"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+33012"), "+33012"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+330123"), "+330123"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+3301234"), "+3301234"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+33012345"), "+33012345"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+330123456"), "+330123456"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+3301234567"), "+3301234567"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+33012345678"), "+33012345678"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+330123456789"), "+330123456789"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+3301234567890"), "+3301234567890"); + + // invalid prefix - use a generic dialplan with 10 max length + linphone_proxy_config_set_dial_prefix(proxy, "99"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0012345678"), "+12345678"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0"), "+990"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "01"), "+9901"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "012"), "+99012"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0123"), "+990123"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "01234"), "+9901234"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "012345"), "+99012345"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0123456"), "+990123456"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "01234567"), "+9901234567"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "012345678"), "+99012345678"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0123456789"), "+990123456789"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "01234567890"), "+991234567890"); + + linphone_proxy_config_destroy(proxy); +} + +static void phone_normalization_with_dial_escape_plus(void){ + LinphoneProxyConfig *proxy = linphone_proxy_config_new(); + linphone_proxy_config_set_dial_prefix(proxy, "33"); + linphone_proxy_config_set_dial_escape_plus(proxy, TRUE); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0033952636505"), "0033952636505"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0952636505"), "0033952636505"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+34952636505"), "0034952636505"); + + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0"), "00330"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "01"), "003301"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "012"), "0033012"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0123"), "00330123"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "01234"), "003301234"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "012345"), "0033012345"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0123456"), "00330123456"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "01234567"), "003301234567"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "012345678"), "0033012345678"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0123456789"), "0033123456789"); + BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "01234567890"), "0033234567890"); + + + linphone_proxy_config_destroy(proxy); +} + +#define SIP_URI_CHECK(actual, expected) { \ + LinphoneProxyConfig *proxy = linphone_proxy_config_new(); \ + LinphoneAddress* res;\ + char* actual_str;\ + linphone_proxy_config_set_identity(proxy, "sip:username@linphone.org"); \ + res = linphone_proxy_config_normalize_sip_uri(proxy, actual); \ + actual_str = linphone_address_as_string_uri_only(res); \ + BC_ASSERT_STRING_EQUAL(actual_str, expected); \ + ms_free(actual_str); \ + linphone_address_destroy(res); \ + linphone_proxy_config_destroy(proxy); \ + } + + +static void sip_uri_normalization(void) { + char* expected ="sip:%d9%a1@linphone.org"; + BC_ASSERT_PTR_NULL(linphone_proxy_config_normalize_sip_uri(NULL, "test")); + SIP_URI_CHECK("test@linphone.org", "sip:test@linphone.org"); + SIP_URI_CHECK("test@linphone.org;transport=tls", "sip:test@linphone.org;transport=tls"); + + SIP_URI_CHECK("١", expected); //test that no more invalid memory writes are made (valgrind only) +} + +test_t proxy_config_tests[] = { + { "Phone normalization without proxy", phone_normalization_without_proxy }, + { "Phone normalization with proxy", phone_normalization_with_proxy }, + { "Phone normalization with dial escape plus", phone_normalization_with_dial_escape_plus }, + { "SIP URI normalization", sip_uri_normalization }, +}; + +test_suite_t proxy_config_test_suite = {"Proxy config", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each, + sizeof(proxy_config_tests) / sizeof(proxy_config_tests[0]), proxy_config_tests}; diff --git a/tester/quality_reporting_tester.c b/tester/quality_reporting_tester.c index e5c97b8ee..1810b058d 100644 --- a/tester/quality_reporting_tester.c +++ b/tester/quality_reporting_tester.c @@ -24,22 +24,14 @@ /*avoid crash if x is NULL on libc versions <4.5.26 */ #define __strstr(x, y) ((x==NULL)?NULL:strstr(x,y)) -void on_report_send_mandatory(const LinphoneCall *call, int stream_type, const LinphoneContent *content){ +void on_report_send_mandatory(const LinphoneCall *call, SalStreamType stream_type, const LinphoneContent *content){ char * body = (char *)linphone_content_get_buffer(content); char * remote_metrics_start = __strstr(body, "RemoteMetrics:"); - reporting_session_report_t * report = call->log->reporting.reports[stream_type]; - MediaStream * ms; - if (stream_type == LINPHONE_CALL_STATS_AUDIO){ - ms = (MediaStream*)call->audiostream; - }else{ - ms = (MediaStream*)call->videostream; - } BC_ASSERT_TRUE( __strstr(body, "VQIntervalReport\r\n") == body || __strstr(body, "VQSessionReport\r\n") == body || __strstr(body, "VQSessionReport: CallTerm\r\n") == body ); - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "CallID:")); BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "LocalID:")); BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "RemoteID:")); @@ -68,12 +60,6 @@ void on_report_send_mandatory(const LinphoneCall *call, int stream_type, const L BC_ASSERT_TRUE(!remote_metrics_start || body < remote_metrics_start); BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "DialogID:")); - - if (report->remote_metrics.rtcp_sr_count&&ms!=NULL&&ms->rc!=NULL){ - /* Hack: reset rtcp_sr_count to 0 because in case of interval reports, we need one RTCP SR by interval */ - report->remote_metrics.rtcp_sr_count=0; - BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "AdaptiveAlg:")); - } } char * on_report_send_verify_metrics(const reporting_content_metrics_t *metrics, char * body){ @@ -92,7 +78,7 @@ char * on_report_send_verify_metrics(const reporting_content_metrics_t *metrics, return body; } -void on_report_send_with_rtcp_xr_local(const LinphoneCall *call, int stream_type, const LinphoneContent *content){ +void on_report_send_with_rtcp_xr_local(const LinphoneCall *call, SalStreamType stream_type, const LinphoneContent *content){ char * body = (char*)linphone_content_get_buffer(content); char * remote_metrics_start = __strstr(body, "RemoteMetrics:"); reporting_session_report_t * report = call->log->reporting.reports[stream_type]; @@ -100,7 +86,7 @@ void on_report_send_with_rtcp_xr_local(const LinphoneCall *call, int stream_type BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "LocalMetrics:")); BC_ASSERT_TRUE(!remote_metrics_start || on_report_send_verify_metrics(&report->local_metrics,body) < remote_metrics_start); } -void on_report_send_with_rtcp_xr_remote(const LinphoneCall *call, int stream_type, const LinphoneContent *content){ +void on_report_send_with_rtcp_xr_remote(const LinphoneCall *call, SalStreamType stream_type, const LinphoneContent *content){ char * body = (char*)linphone_content_get_buffer(content); reporting_session_report_t * report = call->log->reporting.reports[stream_type]; @@ -111,7 +97,7 @@ void on_report_send_with_rtcp_xr_remote(const LinphoneCall *call, int stream_typ on_report_send_verify_metrics(&report->remote_metrics,body); } } -void on_report_send_with_rtcp_xr_both(const LinphoneCall *call, int stream_type, const LinphoneContent *content){ +void on_report_send_with_rtcp_xr_both(const LinphoneCall *call, SalStreamType stream_type, const LinphoneContent *content){ on_report_send_with_rtcp_xr_local(call,stream_type,content); on_report_send_with_rtcp_xr_remote(call,stream_type,content); } @@ -141,38 +127,39 @@ bool_t create_call_for_quality_reporting_tests( return call_succeeded; } -static void quality_reporting_not_used_without_config() { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); +static void quality_reporting_not_used_without_config(void) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_quality_reporting_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneCall* call_marie = NULL; LinphoneCall* call_pauline = NULL; if (create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline, NULL, NULL)) { - // marie has stats collection enabled but pauline has not + // marie has stats collection enabled but pauline has not BC_ASSERT_TRUE(linphone_proxy_config_quality_reporting_enabled(call_marie->dest_proxy)); BC_ASSERT_FALSE(linphone_proxy_config_quality_reporting_enabled(call_pauline->dest_proxy)); - BC_ASSERT_STRING_EQUAL(linphone_proxy_config_get_quality_reporting_collector(call_marie->dest_proxy), - "sip:collector@sip.example.org"); - // this field should be already filled BC_ASSERT_PTR_NOT_NULL(call_marie->log->reporting.reports[0]->info.local_addr.ip); // but not this one since it is updated at the end of call BC_ASSERT_PTR_NULL(call_marie->log->reporting.reports[0]->dialog_id); + end_call(marie, pauline); } + linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } -static void quality_reporting_not_sent_if_call_not_started() { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); +static void quality_reporting_not_sent_if_call_not_started(void) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_quality_reporting_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneCallLog* out_call_log; LinphoneCall* out_call; linphone_core_set_max_calls(pauline->lc,0); out_call = linphone_core_invite(marie->lc,"pauline"); + BC_ASSERT_PTR_NOT_NULL(out_call); + if(out_call == NULL) goto end; linphone_call_ref(out_call); BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallError,1, 10000)); @@ -191,21 +178,21 @@ static void quality_reporting_not_sent_if_call_not_started() { // since the callee was busy, there should be no publish to do BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress,0, int, "%d"); BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,0, int, "%d"); - +end: linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } -static void quality_reporting_not_sent_if_low_bandwidth() { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); +static void quality_reporting_not_sent_if_low_bandwidth(void) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_quality_reporting_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneCallParams* marie_params; - marie_params=linphone_core_create_default_call_parameters(marie->lc); + marie_params=linphone_core_create_call_params(marie->lc, NULL); linphone_call_params_enable_low_bandwidth(marie_params,TRUE); if (create_call_for_quality_reporting_tests(marie, pauline, NULL, NULL, marie_params, NULL)) { - linphone_core_terminate_all_calls(marie->lc); + end_call(marie, pauline); BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress,0, int, "%d"); BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,0, int, "%d"); @@ -215,33 +202,34 @@ static void quality_reporting_not_sent_if_low_bandwidth() { linphone_core_manager_destroy(pauline); } -void on_report_send_remove_fields(const LinphoneCall *call, int stream_type, const LinphoneContent *content){ +void on_report_send_remove_fields(const LinphoneCall *call, SalStreamType stream_type, const LinphoneContent *content){ char *body = (char*)linphone_content_get_buffer(content); /*corrupt start of the report*/ strncpy(body, "corrupted report is corrupted", strlen("corrupted report is corrupted")); } -static void quality_reporting_invalid_report() { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); +static void quality_reporting_invalid_report(void) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_quality_reporting_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneCall* call_marie = NULL; LinphoneCall* call_pauline = NULL; if (create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline, NULL, NULL)) { linphone_reporting_set_on_report_send(call_marie, on_report_send_remove_fields); - linphone_core_terminate_all_calls(marie->lc); + end_call(marie, pauline); BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishProgress,1)); BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishError,1,3000)); + BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishError,1, int, "%d"); BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,0, int, "%d"); } linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } -static void quality_reporting_at_call_termination() { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); +static void quality_reporting_at_call_termination(void) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_quality_reporting_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc_rtcp_xr"); LinphoneCall* call_marie = NULL; LinphoneCall* call_pauline = NULL; @@ -262,13 +250,14 @@ static void quality_reporting_at_call_termination() { // PUBLISH submission to the collector should be ok BC_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphonePublishProgress,1)); + BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress,1, int, "%d"); BC_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphonePublishOk,1)); } linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } -static void quality_reporting_interval_report() { +static void quality_reporting_interval_report(void) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc_rtcp_xr"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc_rtcp_xr"); LinphoneCall* call_marie = NULL; @@ -276,22 +265,24 @@ static void quality_reporting_interval_report() { if (create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline, NULL, NULL)) { linphone_reporting_set_on_report_send(call_marie, on_report_send_mandatory); - linphone_proxy_config_set_quality_reporting_interval(call_marie->dest_proxy, 10); + linphone_proxy_config_set_quality_reporting_interval(call_marie->dest_proxy, 1); BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(marie->lc)); BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(pauline->lc)); // PUBLISH submission to the collector should be ok - BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishProgress,3,60000)); - BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,3,60000)); + BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishProgress,1,60000)); + BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,1,60000)); + end_call(marie, pauline); } linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } -static void quality_reporting_session_report_if_video_stopped() { +#ifdef VIDEO_ENABLED +static void quality_reporting_session_report_if_video_stopped(void) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc_rtcp_xr"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneCall* call_pauline = NULL; LinphoneCall* call_marie = NULL; LinphoneCallParams* pauline_params; @@ -301,9 +292,9 @@ static void quality_reporting_session_report_if_video_stopped() { linphone_core_enable_video_display(marie->lc, FALSE); linphone_core_enable_video_capture(pauline->lc, TRUE); linphone_core_enable_video_display(pauline->lc, FALSE); - marie_params=linphone_core_create_default_call_parameters(marie->lc); + marie_params=linphone_core_create_call_params(marie->lc, NULL); linphone_call_params_enable_video(marie_params,TRUE); - pauline_params=linphone_core_create_default_call_parameters(pauline->lc); + pauline_params=linphone_core_create_call_params(pauline->lc, NULL); linphone_call_params_enable_video(pauline_params,TRUE); if (create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline, marie_params, pauline_params)) { @@ -319,12 +310,12 @@ static void quality_reporting_session_report_if_video_stopped() { linphone_call_params_enable_video(pauline_params,FALSE); linphone_core_update_call(pauline->lc,call_pauline,pauline_params); - BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishProgress,1,5000)); - BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,1,5000)); + BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishProgress,1,10000)); + BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,1,10000)); BC_ASSERT_FALSE(linphone_call_params_video_enabled(linphone_call_get_current_params(call_pauline))); - linphone_core_terminate_all_calls(marie->lc); + end_call(marie, pauline); BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishProgress,2,5000)); BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,2,5000)); @@ -335,6 +326,102 @@ static void quality_reporting_session_report_if_video_stopped() { linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } +#endif + +void publish_report_with_route_state_changed(LinphoneCore *lc, LinphoneEvent *ev, LinphonePublishState state){ + if (state == LinphonePublishProgress) { + BC_ASSERT_STRING_EQUAL(linphone_address_as_string(linphone_event_get_resource(ev)), linphone_proxy_config_get_quality_reporting_collector(linphone_core_get_default_proxy_config(lc))); + } +} + +static void quality_reporting_sent_using_custom_route(void) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_quality_reporting_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); + LinphoneCall* call_marie = NULL; + LinphoneCall* call_pauline = NULL; + + LinphoneCoreVTable publish_vtable = {0}; + publish_vtable.publish_state_changed = publish_report_with_route_state_changed; + linphone_core_add_listener(marie->lc, &publish_vtable); + + //INVALID collector: sip.linphone.org do not collect reports, so it will throw a 404 Not Found error + linphone_proxy_config_set_quality_reporting_collector(linphone_core_get_default_proxy_config(marie->lc), "sip:sip.linphone.org"); + + if (create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline, NULL, NULL)) { + end_call(marie, pauline); + + // PUBLISH submission to the collector should be ERROR since route is not valid + BC_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphonePublishProgress,1)); + BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress,1, int, "%d"); + BC_ASSERT_TRUE(wait_for_until(marie->lc,NULL,&marie->stat.number_of_LinphonePublishError,1,10000)); + BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,0,int, "%d"); + } + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +#ifdef VIDEO_ENABLED +static void quality_reporting_interval_report_video_and_rtt(void) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc_rtcp_xr"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc_rtcp_xr"); + LinphoneCall* call_marie = NULL; + LinphoneCall* call_pauline = NULL; + LinphoneCallParams* pauline_params; + LinphoneCallParams* marie_params; + LinphoneChatRoom *pauline_chat_room; + + linphone_core_enable_video_capture(marie->lc, TRUE); + linphone_core_enable_video_display(marie->lc, FALSE); + linphone_core_enable_video_capture(pauline->lc, TRUE); + linphone_core_enable_video_display(pauline->lc, FALSE); + marie_params=linphone_core_create_call_params(marie->lc, NULL); + linphone_call_params_enable_video(marie_params,TRUE); + linphone_call_params_enable_realtime_text(marie_params,TRUE); + pauline_params=linphone_core_create_call_params(pauline->lc, NULL); + linphone_call_params_enable_video(pauline_params,TRUE); + linphone_call_params_enable_realtime_text(pauline_params,TRUE); + + if (create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline, marie_params, pauline_params)) { + linphone_reporting_set_on_report_send(call_marie, on_report_send_mandatory); + linphone_proxy_config_set_quality_reporting_interval(call_marie->dest_proxy, 1); + + BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,NULL,0,3000)); + BC_ASSERT_TRUE(linphone_call_params_video_enabled(linphone_call_get_current_params(call_pauline))); + BC_ASSERT_TRUE(linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(call_pauline))); + + BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(marie->lc)); + BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(pauline->lc)); + + // PUBLISH submission to the collector should be ok + BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishProgress,1,60000)); + BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,1,60000)); + + pauline_chat_room = linphone_call_get_chat_room(call_pauline); + BC_ASSERT_PTR_NOT_NULL(pauline_chat_room); + if (pauline_chat_room) { + const char* message = "Lorem Ipsum Belledonnum Communicatum"; + int i; + LinphoneChatMessage* rtt_message = linphone_chat_room_create_message(pauline_chat_room,NULL); + LinphoneChatRoom *marie_chat_room = linphone_call_get_chat_room(call_marie); + + for (i = 0; i < strlen(message); i++) { + linphone_chat_message_put_char(rtt_message, message[i]); + BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneIsComposingActiveReceived, i+1, 1000)); + BC_ASSERT_EQUAL(linphone_chat_room_get_char(marie_chat_room), message[i], char, "%c"); + } + linphone_chat_room_send_chat_message(pauline_chat_room, rtt_message); + } + + end_call(marie, pauline); + } + + linphone_call_params_destroy(marie_params); + linphone_call_params_destroy(pauline_params); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} +#endif test_t quality_reporting_tests[] = { { "Not used if no config", quality_reporting_not_used_without_config}, @@ -343,13 +430,13 @@ test_t quality_reporting_tests[] = { { "Call term session report invalid if missing mandatory fields", quality_reporting_invalid_report}, { "Call term session report sent if call ended normally", quality_reporting_at_call_termination}, { "Interval report if interval is configured", quality_reporting_interval_report}, + #ifdef VIDEO_ENABLED + { "Interval report if interval is configured with video and realtime text", quality_reporting_interval_report_video_and_rtt}, { "Session report sent if video stopped during call", quality_reporting_session_report_if_video_stopped}, + #endif + { "Sent using custom route", quality_reporting_sent_using_custom_route}, }; -test_suite_t quality_reporting_test_suite = { - "QualityReporting", - NULL, - NULL, - sizeof(quality_reporting_tests) / sizeof(quality_reporting_tests[0]), - quality_reporting_tests -}; +test_suite_t quality_reporting_test_suite = {"QualityReporting", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each, + sizeof(quality_reporting_tests) / sizeof(quality_reporting_tests[0]), + quality_reporting_tests}; diff --git a/tester/rcfiles/laure_call_logs_rc b/tester/rcfiles/laure_call_logs_rc new file mode 100644 index 000000000..268707287 --- /dev/null +++ b/tester/rcfiles/laure_call_logs_rc @@ -0,0 +1,155 @@ +[sip] +sip_port=5092 +sip_tcp_port=5092 +sip_tls_port=5093 +default_proxy=0 +ping_with_options=0 +register_only_when_network_is_up=0 + +[auth_info_0] +username=laure +userid=laure +passwd=secret +realm="sip.example.org" + + +[proxy_0] +reg_proxy=sip.example.org +reg_identity=sip:laure@sip.example.org +reg_expires=3600 +reg_sendregister=1 +publish=0 +dial_escape_plus=0 + + +[rtp] +audio_rtp_port=9010-9390 +video_rtp_port=9410-9910 + +[video] +display=0 +capture=0 +show_local=0 +size=qcif +enabled=0 +self_view=0 +automatically_initiate=0 +automatically_accept=0 +device=StaticImage: Static picture + +[sound] +echocancellation=0 #to not overload cpu in case of VG + +[net] +dns_srv_enabled=0 #no srv needed in general +stun_server=stun.linphone.org + +[call_log_0] +dir=0 +status=0 +from=sip:pauline@sip.linphone.org +to=sip:laure@sip.linphone.org +start_date_time=1441738272 +duration=3 +quality=5.000000 +video_enabled=0 +call_id=o6mx-QSdKJ + +[call_log_1] +dir=0 +status=1 +from=sip:pauline@sip.linphone.org +to=sip:laure@sip.linphone.org +start_date_time=1441738266 +duration=0 +quality=-1.000000 +video_enabled=0 +call_id=wnXDtOhURa + +[call_log_2] +dir=1 +status=2 +from=sip:laure@sip.linphone.org +to=sip:pauline@sip.linphone.org +start_date_time=1441738258 +duration=0 +quality=-1.000000 +video_enabled=0 +call_id=81ZldO6dlk + +[call_log_3] +dir=1 +status=1 +from=sip:laure@sip.linphone.org +to=sip:pauline@sip.linphone.org +start_date_time=1441738250 +duration=0 +quality=-1.000000 +video_enabled=0 +call_id=3yq7TlwS8Q + +[call_log_4] +dir=1 +status=0 +from=sip:laure@sip.linphone.org +to=sip:pauline@sip.linphone.org +start_date_time=1441738243 +duration=0 +quality=-1.000000 +video_enabled=1 +call_id=EmoqEyeLbZ + +[call_log_5] +dir=0 +status=1 +from=sip:pauline@sip.linphone.org +to=sip:laure@sip.linphone.org +start_date_time=1441738234 +duration=0 +quality=-1.000000 +video_enabled=0 +call_id=xl29jqHZ2N + +[call_log_6] +dir=1 +status=0 +from=sip:laure@sip.linphone.org +to=sip:pauline@sip.linphone.org +start_date_time=1441738215 +duration=6 +quality=4.898808 +video_enabled=1 +call_id=2JNrT43eji + +[call_log_7] +dir=0 +status=0 +from=sip:pauline@sip.linphone.org +to=sip:laure@sip.linphone.org +start_date_time=1441738200 +duration=5 +quality=4.715808 +video_enabled=1 +call_id=joyRwGhk-2 + +[call_log_8] +dir=1 +status=3 +from=sip:laure@sip.linphone.org +to=sip:pauline@sip.linphone.org +start_date_time=1441738122 +duration=0 +quality=-1.000000 +video_enabled=0 +call_id=az01erTY2U + +[call_log_9] +dir=0 +status=3 +from=sip:pauline@sip.linphone.org +to=sip:laure@sip.linphone.org +start_date_time=1441738031 +duration=0 +quality=-1.000000 +video_enabled=0 +call_id=jk39dfZP0L diff --git a/tester/rcfiles/marie_h264_rc b/tester/rcfiles/marie_h264_rc index dc89fceb4..8cd970d24 100644 --- a/tester/rcfiles/marie_h264_rc +++ b/tester/rcfiles/marie_h264_rc @@ -22,8 +22,6 @@ reg_expires=3600 reg_sendregister=1 publish=0 dial_escape_plus=0 -quality_reporting_collector=sip:collector@sip.example.org -quality_reporting_enabled=1 [friend_0] url="Paupoche" diff --git a/tester/rcfiles/marie_quality_reporting_rc b/tester/rcfiles/marie_quality_reporting_rc new file mode 100644 index 000000000..10cacfc7d --- /dev/null +++ b/tester/rcfiles/marie_quality_reporting_rc @@ -0,0 +1,49 @@ +[sip] +sip_port=-1 +sip_tcp_port=-1 +sip_tls_port=-1 +default_proxy=0 +ping_with_options=0 +register_only_when_network_is_up=0 +composing_idle_timeout=1 + +[auth_info_0] +username=marie +userid=marie +passwd=secret +realm=sip.example.org + + +[proxy_0] +reg_proxy=sip.example.org;transport=tcp +reg_route=sip.example.org;transport=tcp;lr +reg_identity=sip:marie@sip.example.org +reg_expires=3600 +reg_sendregister=1 +publish=0 +dial_escape_plus=0 +quality_reporting_enabled=1 + +[friend_0] +url="Paupoche" +pol=accept +subscribe=0 + + +[rtp] +audio_rtp_port=20070-22070 +video_rtp_port=24000-25000 + +[video] +display=0 +capture=0 +show_local=0 +size=vga +enabled=0 +self_view=0 +automatically_initiate=0 +automatically_accept=0 +device=StaticImage: Static picture + +[sound] +echocancellation=0 #to not overload cpu in case of VG diff --git a/tester/rcfiles/marie_rc b/tester/rcfiles/marie_rc index fe9687c36..5492e8dc9 100644 --- a/tester/rcfiles/marie_rc +++ b/tester/rcfiles/marie_rc @@ -22,8 +22,6 @@ reg_expires=3600 reg_sendregister=1 publish=0 dial_escape_plus=0 -quality_reporting_collector=sip:collector@sip.example.org -quality_reporting_enabled=1 [friend_0] url="Paupoche" @@ -34,6 +32,7 @@ subscribe=0 [rtp] audio_rtp_port=18070-28000 video_rtp_port=28070-38000 +text_rtp_port=39000-49000 [video] display=0 diff --git a/tester/rcfiles/marie_rc_rtcp_xr b/tester/rcfiles/marie_rc_rtcp_xr index 06f0b5b63..4f2ead6df 100644 --- a/tester/rcfiles/marie_rc_rtcp_xr +++ b/tester/rcfiles/marie_rc_rtcp_xr @@ -22,7 +22,6 @@ reg_expires=3600 reg_sendregister=1 publish=0 dial_escape_plus=0 -quality_reporting_collector=sip:collector@sip.example.org quality_reporting_enabled=1 [friend_0] @@ -34,6 +33,7 @@ subscribe=0 [rtp] audio_rtp_port=20070-22070 video_rtp_port=24000-25000 +text_rtp_port=26000-30000 rtcp_xr_enabled=1 rtcp_xr_rcvr_rtt_mode=all rtcp_xr_rcvr_rtt_max_size=10000 diff --git a/tester/rcfiles/marie_remote_localfile_win10_rc b/tester/rcfiles/marie_remote_localfile_win10_rc new file mode 100644 index 000000000..9c9eec7a6 --- /dev/null +++ b/tester/rcfiles/marie_remote_localfile_win10_rc @@ -0,0 +1,3 @@ +[misc] +config-uri=file://./Assets/rcfiles/marie_remote_localfile2_rc + diff --git a/tester/rcfiles/marie_sips_rc b/tester/rcfiles/marie_sips_rc index f67cca50d..3556248b0 100644 --- a/tester/rcfiles/marie_sips_rc +++ b/tester/rcfiles/marie_sips_rc @@ -22,8 +22,6 @@ reg_expires=3600 reg_sendregister=1 publish=0 dial_escape_plus=0 -quality_reporting_collector=sip:collector@sip2.linphone.org -quality_reporting_enabled=1 [friend_0] url="Paupoche" diff --git a/tester/rcfiles/marie_zrtp_aes256_rc b/tester/rcfiles/marie_zrtp_aes256_rc index 6bf6d2612..2230535b6 100644 --- a/tester/rcfiles/marie_zrtp_aes256_rc +++ b/tester/rcfiles/marie_zrtp_aes256_rc @@ -23,8 +23,6 @@ reg_expires=3600 reg_sendregister=1 publish=0 dial_escape_plus=0 -quality_reporting_collector=sip:collector@sip.example.org -quality_reporting_enabled=1 [friend_0] url="Paupoche" diff --git a/tester/rcfiles/marie_zrtp_b256_rc b/tester/rcfiles/marie_zrtp_b256_rc index b7cfca0a4..a9668f2f9 100644 --- a/tester/rcfiles/marie_zrtp_b256_rc +++ b/tester/rcfiles/marie_zrtp_b256_rc @@ -23,8 +23,6 @@ reg_expires=3600 reg_sendregister=1 publish=0 dial_escape_plus=0 -quality_reporting_collector=sip:collector@sip.example.org -quality_reporting_enabled=1 [friend_0] url="Paupoche" diff --git a/tester/rcfiles/marie_zrtp_srtpsuite_aes256_rc b/tester/rcfiles/marie_zrtp_srtpsuite_aes256_rc index e966e59c2..3dc5b4d6a 100644 --- a/tester/rcfiles/marie_zrtp_srtpsuite_aes256_rc +++ b/tester/rcfiles/marie_zrtp_srtpsuite_aes256_rc @@ -23,8 +23,6 @@ reg_expires=3600 reg_sendregister=1 publish=0 dial_escape_plus=0 -quality_reporting_collector=sip:collector@sip.example.org -quality_reporting_enabled=1 [friend_0] url="Paupoche" diff --git a/tester/rcfiles/michelle_rc b/tester/rcfiles/michelle_rc new file mode 100644 index 000000000..68ca11a7c --- /dev/null +++ b/tester/rcfiles/michelle_rc @@ -0,0 +1,44 @@ +[sip] +sip_port=-1 +sip_tcp_port=-1 +sip_tls_port=-1 +default_proxy=0 + +[auth_info_0] +username=michelle +userid=michelle +passwd=secret +realm="sip.example.org" + + +[proxy_0] +reg_proxy=sip.example.org +reg_identity=sip:michelle@sip.example.org +reg_expires=3600 +reg_sendregister=1 +publish=0 +dial_escape_plus=0 + + +[rtp] +audio_rtp_port=9010-9390 +video_rtp_port=9410-9910 + +[video] +display=0 +capture=0 +show_local=0 +size=qcif +enabled=0 +self_view=0 +automatically_initiate=0 +automatically_accept=0 +device=StaticImage: Static picture + +[sound] +echocancellation=0 #to not overload cpu in case of VG + +[net] +dns_srv_enabled=0 #no srv needed in general +stun_server=stun.linphone.org + diff --git a/tester/rcfiles/pauline_h264_rc b/tester/rcfiles/pauline_h264_rc index 8f30cf020..158f45fe5 100644 --- a/tester/rcfiles/pauline_h264_rc +++ b/tester/rcfiles/pauline_h264_rc @@ -15,8 +15,8 @@ realm=sip.example.org [proxy_0] -reg_proxy=sip2.linphone.org;transport=tls -reg_route=sip2.linphone.org;transport=tls +reg_proxy=sip2.linphone.org;transport=tcp +reg_route=sip2.linphone.org;transport=tcp reg_identity=sip:pauline@sip.example.org reg_expires=3600 reg_sendregister=1 diff --git a/tester/rcfiles/pauline_rc_rtcp_xr b/tester/rcfiles/pauline_rc_rtcp_xr index 94c0314ea..442804d73 100644 --- a/tester/rcfiles/pauline_rc_rtcp_xr +++ b/tester/rcfiles/pauline_rc_rtcp_xr @@ -15,8 +15,8 @@ realm=sip.example.org [proxy_0] -reg_proxy=sip2.linphone.org;transport=tls -reg_route=sip2.linphone.org;transport=tls +reg_proxy=sip2.linphone.org;transport=tcp +reg_route=sip2.linphone.org;transport=tcp reg_identity=sip:pauline@sip.example.org reg_expires=3600 reg_sendregister=1 @@ -31,6 +31,7 @@ dial_escape_plus=0 [rtp] audio_rtp_port=18070-28000 video_rtp_port=39072-49000 +text_rtp_port=29000-38000 rtcp_xr_enabled=1 rtcp_xr_rcvr_rtt_mode=all rtcp_xr_rcvr_rtt_max_size=10000 diff --git a/tester/rcfiles/pauline_tcp_rc b/tester/rcfiles/pauline_tcp_rc index 1b2a85e80..284f0e776 100644 --- a/tester/rcfiles/pauline_tcp_rc +++ b/tester/rcfiles/pauline_tcp_rc @@ -31,12 +31,13 @@ dial_escape_plus=0 [rtp] audio_rtp_port=18070-28000 video_rtp_port=39072-49000 +text_rtp_port=49001-55000 [video] display=0 capture=0 show_local=0 -size=vga +size=qcif enabled=0 self_view=0 automatically_initiate=0 diff --git a/tester/rcfiles/pauline_zrtp_aes256_rc b/tester/rcfiles/pauline_zrtp_aes256_rc index 470432c99..5f1af185d 100644 --- a/tester/rcfiles/pauline_zrtp_aes256_rc +++ b/tester/rcfiles/pauline_zrtp_aes256_rc @@ -16,8 +16,8 @@ realm=sip.example.org [proxy_0] -reg_proxy=sip2.linphone.org;transport=tls -reg_route=sip2.linphone.org;transport=tls +reg_proxy=sip2.linphone.org;transport=tcp +reg_route=sip2.linphone.org;transport=tcp reg_identity=sip:pauline@sip.example.org reg_expires=3600 reg_sendregister=1 diff --git a/tester/rcfiles/pauline_zrtp_b256_rc b/tester/rcfiles/pauline_zrtp_b256_rc index e2d6ce14b..cf74f3fa7 100644 --- a/tester/rcfiles/pauline_zrtp_b256_rc +++ b/tester/rcfiles/pauline_zrtp_b256_rc @@ -16,8 +16,8 @@ realm=sip.example.org [proxy_0] -reg_proxy=sip2.linphone.org;transport=tls -reg_route=sip2.linphone.org;transport=tls +reg_proxy=sip2.linphone.org;transport=tcp +reg_route=sip2.linphone.org;transport=tcp reg_identity=sip:pauline@sip.example.org reg_expires=3600 reg_sendregister=1 diff --git a/tester/rcfiles/pauline_zrtp_srtpsuite_aes256_rc b/tester/rcfiles/pauline_zrtp_srtpsuite_aes256_rc index 08ba14da8..b79b11874 100644 --- a/tester/rcfiles/pauline_zrtp_srtpsuite_aes256_rc +++ b/tester/rcfiles/pauline_zrtp_srtpsuite_aes256_rc @@ -16,8 +16,8 @@ realm=sip.example.org [proxy_0] -reg_proxy=sip2.linphone.org;transport=tls -reg_route=sip2.linphone.org;transport=tls +reg_proxy=sip2.linphone.org;transport=tcp +reg_route=sip2.linphone.org;transport=tcp reg_identity=sip:pauline@sip.example.org reg_expires=3600 reg_sendregister=1 diff --git a/tester/register_tester.c b/tester/register_tester.c index 5f13243cc..4a9282ebf 100644 --- a/tester/register_tester.c +++ b/tester/register_tester.c @@ -32,20 +32,20 @@ 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); + LinphoneCoreManager* lcm=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); + linphone_core_add_listener(lcm->lc,vtable); } /*to allow testing with 127.0.0.1*/ - linphone_core_set_network_reachable(mgr->lc,TRUE); - return mgr; + linphone_core_set_network_reachable(lcm->lc,TRUE); + return lcm; } -static LinphoneCoreManager* create_lcm() { +static LinphoneCoreManager* create_lcm(void) { return create_lcm_with_auth(0); } @@ -85,6 +85,7 @@ static void register_with_refresh_base_3(LinphoneCore* lc BC_ASSERT_PTR_NOT_NULL(lc); if (!lc) return; + counters = get_stats(lc); reset_counters(counters); linphone_core_set_sip_transports(lc,&transport); @@ -111,7 +112,7 @@ static void register_with_refresh_base_3(LinphoneCore* lc linphone_core_set_default_proxy(lc,proxy_cfg); while (counters->number_of_LinphoneRegistrationOk<1+(refresh!=0) - && retry++ <(110 /*only wait 11 s if final state is progress*/+(expected_final_state==LinphoneRegistrationProgress?0:200))) { + && retry++ <(1100 /*only wait 11 s if final state is progress*/+(expected_final_state==LinphoneRegistrationProgress?0:2000))) { linphone_core_iterate(lc); if (counters->number_of_auth_info_requested>0 && linphone_proxy_config_get_state(proxy_cfg) == LinphoneRegistrationFailed && late_auth_info) { if (!linphone_core_get_auth_info_list(lc)) { @@ -123,9 +124,10 @@ static void register_with_refresh_base_3(LinphoneCore* lc if (linphone_proxy_config_get_error(proxy_cfg) == LinphoneReasonBadCredentials || (counters->number_of_auth_info_requested>2 &&linphone_proxy_config_get_error(proxy_cfg) == LinphoneReasonUnauthorized)) /*no need to continue if auth cannot be found*/ break; /*no need to continue*/ - ms_usleep(100000); + ms_usleep(10000); } - BC_ASSERT_EQUAL(linphone_proxy_config_is_registered(proxy_cfg),(expected_final_state == LinphoneRegistrationOk), int, "%d"); + + BC_ASSERT_EQUAL(linphone_proxy_config_is_registered(proxy_cfg), expected_final_state == LinphoneRegistrationOk, int, "%d"); BC_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationNone,0, int, "%d"); BC_ASSERT_TRUE(counters->number_of_LinphoneRegistrationProgress>=1); if (expected_final_state == LinphoneRegistrationOk) { @@ -134,7 +136,7 @@ static void register_with_refresh_base_3(LinphoneCore* lc } else /*checking to be done outside this functions*/ BC_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationCleared,0, int, "%d"); - + linphone_proxy_config_destroy(proxy_cfg); } static void register_with_refresh_base_2(LinphoneCore* lc @@ -157,7 +159,7 @@ static void register_with_refresh(LinphoneCoreManager* lcm, bool_t refresh,const BC_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationCleared,1, int, "%d"); } -static void register_with_refresh_with_send_error() { +static void register_with_refresh_with_send_error(void) { int retry=0; LinphoneCoreManager* lcm = create_lcm_with_auth(1); stats* counters = &lcm->stat; @@ -169,9 +171,9 @@ static void register_with_refresh_with_send_error() { register_with_refresh_base(lcm->lc,TRUE,auth_domain,route); /*simultate a network error*/ sal_set_send_error(lcm->lc->sal, -1); - while (counters->number_of_LinphoneRegistrationProgress<2 && retry++ <20) { + while (counters->number_of_LinphoneRegistrationProgress<2 && retry++ <200) { linphone_core_iterate(lcm->lc); - ms_usleep(100000); + ms_usleep(10000); } BC_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationFailed,0, int, "%d"); BC_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationProgress,2, int, "%d"); @@ -181,7 +183,7 @@ static void register_with_refresh_with_send_error() { linphone_core_manager_destroy(lcm); } -static void simple_register(){ +static void simple_register(void){ LinphoneCoreManager* lcm = create_lcm(); stats* counters = &lcm->stat; register_with_refresh(lcm,FALSE,NULL,NULL); @@ -204,11 +206,11 @@ static void register_with_custom_headers(void){ wait_for(marie->lc, NULL, &marie->stat.number_of_LinphoneRegistrationOk,initial_register_ok+1); value=linphone_proxy_config_get_custom_header(cfg, "Server"); BC_ASSERT_PTR_NOT_NULL(value); - if (value) BC_ASSERT_TRUE(strstr(value, "Flexisip")!=NULL); + if (value) BC_ASSERT_PTR_NOT_NULL(strstr(value, "Flexisip")); linphone_core_manager_destroy(marie); } -static void simple_unregister(){ +static void simple_unregister(void){ LinphoneCoreManager* lcm = create_lcm(); stats* counters = &lcm->stat; LinphoneProxyConfig* proxy_config; @@ -227,7 +229,7 @@ static void simple_unregister(){ linphone_core_manager_destroy(lcm); } -static void change_expires(){ +static void change_expires(void){ LinphoneCoreManager* lcm = create_lcm(); stats* counters = &lcm->stat; LinphoneProxyConfig* proxy_config; @@ -255,7 +257,7 @@ static void change_expires(){ } /*take care of min expires configuration from server*/ -static void simple_register_with_refresh() { +static void simple_register_with_refresh(void) { LinphoneCoreManager* lcm = create_lcm(); stats* counters = &lcm->stat; register_with_refresh(lcm,TRUE,NULL,NULL); @@ -263,7 +265,7 @@ static void simple_register_with_refresh() { linphone_core_manager_destroy(lcm); } -static void simple_auth_register_with_refresh() { +static void simple_auth_register_with_refresh(void) { LinphoneCoreManager* lcm = create_lcm_with_auth(1); stats* counters = &lcm->stat; char route[256]; @@ -273,7 +275,7 @@ static void simple_auth_register_with_refresh() { linphone_core_manager_destroy(lcm); } -static void simple_tcp_register(){ +static void simple_tcp_register(void){ char route[256]; LinphoneCoreManager* lcm; sprintf(route,"sip:%s;transport=tcp",test_route); @@ -282,7 +284,7 @@ static void simple_tcp_register(){ linphone_core_manager_destroy(lcm); } -static void simple_tcp_register_compatibility_mode(){ +static void simple_tcp_register_compatibility_mode(void){ char route[256]; LinphoneCoreManager* lcm; LCSipTransports transport = {0,5070,0,0}; @@ -292,18 +294,18 @@ static void simple_tcp_register_compatibility_mode(){ linphone_core_manager_destroy(lcm); } - -static void simple_tls_register(){ - char route[256]; - LinphoneCoreManager* lcm; - sprintf(route,"sip:%s;transport=tls",test_route); - lcm = create_lcm(); - register_with_refresh(lcm,FALSE,test_domain,route); - linphone_core_manager_destroy(lcm); +static void simple_tls_register(void){ + if (transport_supported(LinphoneTransportTls)) { + char route[256]; + LinphoneCoreManager* lcm = create_lcm(); + sprintf(route,"sip:%s;transport=tls",test_route); + register_with_refresh(lcm,FALSE,test_domain,route); + linphone_core_manager_destroy(lcm); + } } -static void simple_authenticated_register(){ +static void simple_authenticated_register(void){ stats* counters; LinphoneCoreManager* lcm = create_lcm(); LinphoneAuthInfo *info=linphone_auth_info_new(test_username,NULL,test_password,NULL,auth_domain,NULL); /*create authentication structure from identity*/ @@ -313,9 +315,10 @@ static void simple_authenticated_register(){ counters = &lcm->stat; register_with_refresh(lcm,FALSE,auth_domain,route); BC_ASSERT_EQUAL(counters->number_of_auth_info_requested,0, int, "%d"); + linphone_core_manager_destroy(lcm); } -static void ha1_authenticated_register(){ +static void ha1_authenticated_register(void){ stats* counters; LinphoneCoreManager* lcm = create_lcm(); char ha1[33]; @@ -328,47 +331,89 @@ static void ha1_authenticated_register(){ counters = &lcm->stat; register_with_refresh(lcm,FALSE,auth_domain,route); BC_ASSERT_EQUAL(counters->number_of_auth_info_requested,0, int, "%d"); + linphone_core_manager_destroy(lcm); } -static void authenticated_register_with_no_initial_credentials(){ - LinphoneCoreManager *mgr; +static void authenticated_register_with_no_initial_credentials(void){ + LinphoneCoreManager *lcm; LinphoneCoreVTable* vtable = linphone_core_v_table_new(); stats* counters; char route[256]; sprintf(route,"sip:%s",test_route); - mgr = linphone_core_manager_new(NULL); + lcm = linphone_core_manager_new(NULL); vtable->auth_info_requested=auth_info_requested; - linphone_core_add_listener(mgr->lc,vtable); + linphone_core_add_listener(lcm->lc,vtable); - counters= get_stats(mgr->lc); + counters= get_stats(lcm->lc); counters->number_of_auth_info_requested=0; - register_with_refresh(mgr,FALSE,auth_domain,route); + register_with_refresh(lcm,FALSE,auth_domain,route); BC_ASSERT_EQUAL(counters->number_of_auth_info_requested,1, int, "%d"); - linphone_core_manager_destroy(mgr); + linphone_core_manager_destroy(lcm); } -static void authenticated_register_with_late_credentials(){ - LinphoneCoreManager *mgr; +static void authenticated_register_with_late_credentials(void){ + LinphoneCoreManager *lcm; stats* counters; - LCSipTransports transport = {5070,5070,0,5071}; char route[256]; + LCSipTransports transport = {5070,5070,0,5071}; sprintf(route,"sip:%s",test_route); - mgr = linphone_core_manager_new(NULL); + lcm = linphone_core_manager_new(NULL); - counters = get_stats(mgr->lc); - register_with_refresh_base_2(mgr->lc,FALSE,auth_domain,route,TRUE,transport); + counters = get_stats(lcm->lc); + register_with_refresh_base_2(lcm->lc,FALSE,auth_domain,route,TRUE,transport); BC_ASSERT_EQUAL(counters->number_of_auth_info_requested,1, int, "%d"); - linphone_core_manager_destroy(mgr); + linphone_core_manager_destroy(lcm); } -static void authenticated_register_with_wrong_late_credentials(){ - LinphoneCoreManager *mgr; +static void authenticated_register_with_provided_credentials(void){ + LinphoneCoreManager *lcm; + stats* counters; + LinphoneProxyConfig *cfg; + char route[256]; + LinphoneAddress *from; + char *addr; + LinphoneAuthInfo *ai; + + sprintf(route,"sip:%s",test_route); + + lcm = linphone_core_manager_new(NULL); + + counters = get_stats(lcm->lc); + cfg = linphone_core_create_proxy_config(lcm->lc); + from = create_linphone_address(auth_domain); + + linphone_proxy_config_set_identity(cfg, addr=linphone_address_as_string(from)); + ms_free(addr); + + linphone_proxy_config_enable_register(cfg,TRUE); + linphone_proxy_config_set_expires(cfg,1); + linphone_proxy_config_set_route(cfg, test_route); + linphone_proxy_config_set_server_addr(cfg,test_route); + linphone_address_destroy(from); + + ai = linphone_auth_info_new(test_username, NULL, test_password, NULL, NULL, NULL); + linphone_core_add_auth_info(lcm->lc, ai); + + linphone_core_add_proxy_config(lcm->lc, cfg); + + BC_ASSERT_TRUE(wait_for(lcm->lc,lcm->lc,&counters->number_of_LinphoneRegistrationOk,1)); + BC_ASSERT_EQUAL(counters->number_of_auth_info_requested,0, int, "%d"); + + BC_ASSERT_PTR_NULL(lp_config_get_string(lcm->lc->config, "auth_info_0", "passwd", NULL)); + BC_ASSERT_PTR_NOT_NULL(lp_config_get_string(lcm->lc->config, "auth_info_0", "ha1", NULL)); + + linphone_proxy_config_destroy(cfg); + linphone_core_manager_destroy(lcm); +} + +static void authenticated_register_with_wrong_late_credentials(void){ + LinphoneCoreManager *lcm; stats* counters; LCSipTransports transport = {5070,5070,0,5071}; char route[256]; @@ -379,19 +424,19 @@ static void authenticated_register_with_wrong_late_credentials(){ sprintf(route,"sip:%s",test_route); - mgr = linphone_core_manager_new(NULL); + lcm = linphone_core_manager_new(NULL); - counters = get_stats(mgr->lc); - register_with_refresh_base_3(mgr->lc,FALSE,auth_domain,route,TRUE,transport,LinphoneRegistrationFailed); + counters = get_stats(lcm->lc); + register_with_refresh_base_3(lcm->lc,FALSE,auth_domain,route,TRUE,transport,LinphoneRegistrationFailed); BC_ASSERT_EQUAL(counters->number_of_auth_info_requested,2, int, "%d"); BC_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationFailed,2, int, "%d"); BC_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationProgress,2, int, "%d"); test_password=saved_test_passwd; - linphone_core_manager_destroy(mgr); + linphone_core_manager_destroy(lcm); } -static void authenticated_register_with_wrong_credentials_with_params_base(const char* user_agent,LinphoneCoreManager *mgr) { +static void authenticated_register_with_wrong_credentials_with_params_base(const char* user_agent,LinphoneCoreManager *lcm) { stats* counters; 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*/ @@ -399,28 +444,28 @@ static void authenticated_register_with_wrong_credentials_with_params_base(const sprintf(route,"sip:%s",test_route); - sal_set_refresher_retry_after(mgr->lc->sal,500); + sal_set_refresher_retry_after(lcm->lc->sal,500); if (user_agent) { - linphone_core_set_user_agent(mgr->lc,user_agent,NULL); + linphone_core_set_user_agent(lcm->lc,user_agent,NULL); } - linphone_core_add_auth_info(mgr->lc,info); /*add wrong authentication info to LinphoneCore*/ - counters = get_stats(mgr->lc); - register_with_refresh_base_3(mgr->lc,TRUE,auth_domain,route,FALSE,transport,LinphoneRegistrationFailed); + linphone_core_add_auth_info(lcm->lc,info); /*add wrong authentication info to LinphoneCore*/ + counters = get_stats(lcm->lc); + register_with_refresh_base_3(lcm->lc,TRUE,auth_domain,route,FALSE,transport,LinphoneRegistrationFailed); //BC_ASSERT_EQUAL(counters->number_of_auth_info_requested,3, int, "%d"); register_with_refresh_base_3 does not alow to precisely check number of number_of_auth_info_requested /*wait for retry*/ - BC_ASSERT_TRUE(wait_for(mgr->lc,mgr->lc,&counters->number_of_auth_info_requested,4)); + BC_ASSERT_TRUE(wait_for(lcm->lc,lcm->lc,&counters->number_of_auth_info_requested,4)); BC_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationFailed,1, int, "%d"); /*check the detailed error info */ if (!user_agent || strcmp(user_agent,"tester-no-403")!=0){ LinphoneProxyConfig *cfg=NULL; - linphone_core_get_default_proxy(mgr->lc,&cfg); + linphone_core_get_default_proxy(lcm->lc,&cfg); BC_ASSERT_PTR_NOT_NULL(cfg); if (cfg){ const LinphoneErrorInfo *ei=linphone_proxy_config_get_error_info(cfg); const char *phrase=linphone_error_info_get_phrase(ei); BC_ASSERT_PTR_NOT_NULL(phrase); - if (phrase) BC_ASSERT_TRUE(strcmp(phrase,"Forbidden")==0); + if (phrase) BC_ASSERT_STRING_EQUAL(phrase,"Forbidden"); BC_ASSERT_EQUAL(linphone_error_info_get_protocol_code(ei),403, int, "%d"); BC_ASSERT_PTR_NULL(linphone_error_info_get_details(ei)); } @@ -428,77 +473,84 @@ static void authenticated_register_with_wrong_credentials_with_params_base(const } } static void authenticated_register_with_wrong_credentials_with_params(const char* user_agent) { - LinphoneCoreManager *mgr = linphone_core_manager_new(NULL); - authenticated_register_with_wrong_credentials_with_params_base(user_agent,mgr); - linphone_core_manager_destroy(mgr); + LinphoneCoreManager *lcm = linphone_core_manager_new(NULL); + authenticated_register_with_wrong_credentials_with_params_base(user_agent,lcm); + linphone_core_manager_destroy(lcm); } -static void authenticated_register_with_wrong_credentials() { +static void authenticated_register_with_wrong_credentials(void) { authenticated_register_with_wrong_credentials_with_params(NULL); } -static void authenticated_register_with_wrong_credentials_2() { - LinphoneCoreManager *mgr = linphone_core_manager_new(NULL); - stats* counters = get_stats(mgr->lc); +static void authenticated_register_with_wrong_credentials_2(void) { + LinphoneCoreManager *lcm = linphone_core_manager_new(NULL); + stats* counters = get_stats(lcm->lc); int current_in_progress; LinphoneProxyConfig* proxy; - authenticated_register_with_wrong_credentials_with_params_base(NULL,mgr); + authenticated_register_with_wrong_credentials_with_params_base(NULL,lcm); - linphone_core_get_default_proxy(mgr->lc,&proxy); + linphone_core_get_default_proxy(lcm->lc,&proxy); /*Make sure registration attempts are stopped*/ linphone_proxy_config_edit(proxy); linphone_proxy_config_enable_register(proxy,FALSE); linphone_proxy_config_done(proxy); current_in_progress=counters->number_of_LinphoneRegistrationProgress; - BC_ASSERT_FALSE(wait_for(mgr->lc,mgr->lc,&counters->number_of_LinphoneRegistrationProgress,current_in_progress+1)); + BC_ASSERT_FALSE(wait_for(lcm->lc,lcm->lc,&counters->number_of_LinphoneRegistrationProgress,current_in_progress+1)); - linphone_core_manager_destroy(mgr); + linphone_core_manager_destroy(lcm); } -static void authenticated_register_with_wrong_credentials_without_403() { +static void authenticated_register_with_wrong_credentials_without_403(void) { authenticated_register_with_wrong_credentials_with_params("tester-no-403"); } static LinphoneCoreManager* configure_lcm(void) { - LinphoneCoreManager *mgr=linphone_core_manager_new( "multi_account_rc"); - stats *counters=&mgr->stat; - BC_ASSERT_TRUE(wait_for(mgr->lc,mgr->lc,&counters->number_of_LinphoneRegistrationOk,ms_list_size(linphone_core_get_proxy_config_list(mgr->lc)))); - BC_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationFailed,0, int, "%d"); - return mgr; + if (transport_supported(LinphoneTransportTls)) { + LinphoneCoreManager *lcm=linphone_core_manager_new2( "multi_account_rc", FALSE); + stats *counters=&lcm->stat; + BC_ASSERT_TRUE(wait_for(lcm->lc,lcm->lc,&counters->number_of_LinphoneRegistrationOk,ms_list_size(linphone_core_get_proxy_config_list(lcm->lc)))); + BC_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationFailed,0, int, "%d"); + return lcm; + } + return NULL; } -static void multiple_proxy(){ - LinphoneCoreManager *mgr=configure_lcm(); - linphone_core_manager_destroy(mgr); +static void multiple_proxy(void){ + LinphoneCoreManager *lcm=configure_lcm(); + if (lcm) { + linphone_core_manager_destroy(lcm); + } } -static void network_state_change(){ +static void network_state_change(void){ int register_ok; stats *counters; - LinphoneCoreManager *mgr=configure_lcm(); - LinphoneCore *lc=mgr->lc; + LinphoneCoreManager *lcm=configure_lcm(); + if (lcm) { + LinphoneCore *lc=lcm->lc; - counters = get_stats(lc); - register_ok=counters->number_of_LinphoneRegistrationOk; - linphone_core_set_network_reachable(lc,FALSE); - BC_ASSERT_TRUE(wait_for(lc,lc,&counters->number_of_NetworkReachableFalse,1)); - BC_ASSERT_TRUE(wait_for(lc,lc,&counters->number_of_LinphoneRegistrationNone,register_ok)); - linphone_core_set_network_reachable(lc,TRUE); - BC_ASSERT_TRUE(wait_for(lc,lc,&counters->number_of_NetworkReachableTrue,1)); - wait_for(lc,lc,&counters->number_of_LinphoneRegistrationOk,2*register_ok); + counters = get_stats(lc); + register_ok=counters->number_of_LinphoneRegistrationOk; + linphone_core_set_network_reachable(lc,FALSE); + BC_ASSERT_TRUE(wait_for(lc,lc,&counters->number_of_NetworkReachableFalse,1)); + BC_ASSERT_TRUE(wait_for(lc,lc,&counters->number_of_LinphoneRegistrationNone,register_ok)); + linphone_core_set_network_reachable(lc,TRUE); + BC_ASSERT_TRUE(wait_for(lc,lc,&counters->number_of_NetworkReachableTrue,1)); + wait_for(lc,lc,&counters->number_of_LinphoneRegistrationOk,2*register_ok); - linphone_core_manager_destroy(mgr); + linphone_core_manager_destroy(lcm); + } } static int get_number_of_udp_proxy(const LinphoneCore* lc) { int number_of_udp_proxy=0; LinphoneProxyConfig* proxy_cfg; - MSList* proxys; - for (proxys=(MSList*)linphone_core_get_proxy_config_list(lc);proxys!=NULL;proxys=proxys->next) { + const MSList* proxys; + for (proxys=linphone_core_get_proxy_config_list(lc);proxys!=NULL;proxys=proxys->next) { proxy_cfg=(LinphoneProxyConfig*)proxys->data; if (strcmp("udp",linphone_proxy_config_get_transport(proxy_cfg))==0) number_of_udp_proxy++; } return number_of_udp_proxy; } -static void transport_change(){ - LinphoneCoreManager *mgr; +static void transport_change(void){ + LinphoneCoreManager *lcm; LinphoneCore* lc; int register_ok; stats* counters ; @@ -506,29 +558,31 @@ static void transport_change(){ LCSipTransports sip_tr_orig; 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); - register_ok=counters->number_of_LinphoneRegistrationOk; + lcm=configure_lcm(); + if (lcm) { + memset(&sip_tr,0,sizeof(sip_tr)); + lc=lcm->lc; + counters = get_stats(lc); + register_ok=counters->number_of_LinphoneRegistrationOk; - number_of_udp_proxy=get_number_of_udp_proxy(lc); - total_number_of_proxies=ms_list_size(linphone_core_get_proxy_config_list(lc)); - linphone_core_get_sip_transports(lc,&sip_tr_orig); + number_of_udp_proxy=get_number_of_udp_proxy(lc); + total_number_of_proxies=ms_list_size(linphone_core_get_proxy_config_list(lc)); + linphone_core_get_sip_transports(lc,&sip_tr_orig); - sip_tr.udp_port=sip_tr_orig.udp_port; + sip_tr.udp_port=sip_tr_orig.udp_port; - /*keep only udp*/ - linphone_core_set_sip_transports(lc,&sip_tr); - BC_ASSERT_TRUE(wait_for(lc,lc,&counters->number_of_LinphoneRegistrationOk,register_ok+number_of_udp_proxy)); + /*keep only udp*/ + linphone_core_set_sip_transports(lc,&sip_tr); + BC_ASSERT_TRUE(wait_for(lc,lc,&counters->number_of_LinphoneRegistrationOk,register_ok+number_of_udp_proxy)); - BC_ASSERT_TRUE(wait_for(lc,lc,&counters->number_of_LinphoneRegistrationFailed,total_number_of_proxies-number_of_udp_proxy)); + BC_ASSERT_TRUE(wait_for(lc,lc,&counters->number_of_LinphoneRegistrationFailed,total_number_of_proxies-number_of_udp_proxy)); - linphone_core_manager_destroy(mgr); + linphone_core_manager_destroy(lcm); + } } -static void proxy_transport_change(){ +static void proxy_transport_change(void){ LinphoneCoreManager* lcm = create_lcm(); stats* counters = &lcm->stat; LinphoneProxyConfig* proxy_config; @@ -563,7 +617,7 @@ static void proxy_transport_change(){ linphone_core_manager_destroy(lcm); } -static void proxy_transport_change_with_wrong_port() { +static void proxy_transport_change_with_wrong_port(void) { LinphoneCoreManager* lcm = create_lcm(); stats* counters = &lcm->stat; LinphoneProxyConfig* proxy_config; @@ -594,7 +648,7 @@ static void proxy_transport_change_with_wrong_port() { } -static void proxy_transport_change_with_wrong_port_givin_up() { +static void proxy_transport_change_with_wrong_port_givin_up(void) { LinphoneCoreManager* lcm = create_lcm(); stats* counters = &lcm->stat; LinphoneProxyConfig* proxy_config; @@ -623,210 +677,226 @@ static void proxy_transport_change_with_wrong_port_givin_up() { } -static void io_recv_error(){ - LinphoneCoreManager *mgr; +static void io_recv_error(void){ + LinphoneCoreManager *lcm; LinphoneCore* lc; int register_ok; stats* counters ; int number_of_udp_proxy=0; - 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); - sal_set_recv_error(lc->sal, 0); + lcm=configure_lcm(); + if (lcm) { + lc=lcm->lc; + counters = get_stats(lc); + register_ok=counters->number_of_LinphoneRegistrationOk; + number_of_udp_proxy=get_number_of_udp_proxy(lc); + sal_set_recv_error(lc->sal, 0); - BC_ASSERT_TRUE(wait_for(lc,lc,&counters->number_of_LinphoneRegistrationProgress,2*(register_ok-number_of_udp_proxy) /*because 1 udp*/)); - BC_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationFailed,0,int,"%d"); + BC_ASSERT_TRUE(wait_for(lc,lc,&counters->number_of_LinphoneRegistrationProgress,2*(register_ok-number_of_udp_proxy) /*because 1 udp*/)); + BC_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationFailed,0,int,"%d"); - sal_set_recv_error(lc->sal, 1); /*reset*/ + sal_set_recv_error(lc->sal, 1); /*reset*/ - linphone_core_manager_destroy(mgr); + linphone_core_manager_destroy(lcm); + } } -static void io_recv_error_retry_immediatly(){ - LinphoneCoreManager *mgr; +static void io_recv_error_retry_immediatly(void){ + LinphoneCoreManager *lcm; LinphoneCore* lc; int register_ok; stats* counters ; int number_of_udp_proxy=0; + lcm=configure_lcm(); + if (lcm) { + lc=lcm->lc; + counters = get_stats(lc); + register_ok=counters->number_of_LinphoneRegistrationOk; + number_of_udp_proxy=get_number_of_udp_proxy(lc); + sal_set_recv_error(lc->sal, 0); - 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); - sal_set_recv_error(lc->sal, 0); + BC_ASSERT_TRUE(wait_for(lc,NULL,&counters->number_of_LinphoneRegistrationProgress,(register_ok-number_of_udp_proxy)+register_ok /*because 1 udp*/)); + BC_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationFailed,0,int,"%d"); + sal_set_recv_error(lc->sal, 1); /*reset*/ - BC_ASSERT_TRUE(wait_for(lc,NULL,&counters->number_of_LinphoneRegistrationProgress,(register_ok-number_of_udp_proxy)+register_ok /*because 1 udp*/)); - BC_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationFailed,0,int,"%d"); - sal_set_recv_error(lc->sal, 1); /*reset*/ + BC_ASSERT_TRUE(wait_for_until(lc,lc,&counters->number_of_LinphoneRegistrationOk,register_ok-number_of_udp_proxy+register_ok,30000)); - BC_ASSERT_TRUE(wait_for(lc,lc,&counters->number_of_LinphoneRegistrationOk,register_ok-number_of_udp_proxy+register_ok)); - - linphone_core_manager_destroy(mgr); + linphone_core_manager_destroy(lcm); + } } -static void io_recv_error_late_recovery(){ - LinphoneCoreManager *mgr; - LinphoneCore* lc; - int register_ok; - stats* counters ; - int number_of_udp_proxy=0; - MSList* lcs; - - mgr=linphone_core_manager_new2( "multi_account_rc",FALSE); /*to make sure iterates are not call yet*/ - lc=mgr->lc; - sal_set_refresher_retry_after(lc->sal,1000); - counters=&mgr->stat; - BC_ASSERT_TRUE(wait_for(mgr->lc,mgr->lc,&counters->number_of_LinphoneRegistrationOk,ms_list_size(linphone_core_get_proxy_config_list(mgr->lc)))); +static void io_recv_error_late_recovery(void){ + if (transport_supported(LinphoneTransportTls)) { + LinphoneCoreManager *lcm; + LinphoneCore* lc; + int register_ok; + stats* counters ; + int number_of_udp_proxy=0; + MSList* lcs; + lcm=linphone_core_manager_new2( "multi_account_rc",FALSE); /*to make sure iterates are not call yet*/ + lc=lcm->lc; + sal_set_refresher_retry_after(lc->sal,1000); + counters=&lcm->stat; + BC_ASSERT_TRUE(wait_for(lcm->lc,lcm->lc,&counters->number_of_LinphoneRegistrationOk,ms_list_size(linphone_core_get_proxy_config_list(lcm->lc)))); - counters = get_stats(lc); - register_ok=counters->number_of_LinphoneRegistrationOk; - number_of_udp_proxy=get_number_of_udp_proxy(lc); - /*simulate a general socket error*/ - sal_set_recv_error(lc->sal, 0); - sal_set_send_error(lc->sal, -1); + counters = get_stats(lc); + register_ok=counters->number_of_LinphoneRegistrationOk; + number_of_udp_proxy=get_number_of_udp_proxy(lc); + /*simulate a general socket error*/ + sal_set_recv_error(lc->sal, 0); + sal_set_send_error(lc->sal, -1); - BC_ASSERT_TRUE(wait_for(lc,NULL,&counters->number_of_LinphoneRegistrationProgress,(register_ok-number_of_udp_proxy)+register_ok /*because 1 udp*/)); - BC_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationFailed,0,int,"%d"); + BC_ASSERT_TRUE(wait_for(lc,NULL,&counters->number_of_LinphoneRegistrationProgress,(register_ok-number_of_udp_proxy)+register_ok /*because 1 udp*/)); + BC_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationFailed,0,int,"%d"); - BC_ASSERT_TRUE(wait_for_list(lcs=ms_list_append(NULL,lc),&counters->number_of_LinphoneRegistrationFailed,(register_ok-number_of_udp_proxy),sal_get_refresher_retry_after(lc->sal)+3000)); + BC_ASSERT_TRUE(wait_for_list(lcs=ms_list_append(NULL,lc),&counters->number_of_LinphoneRegistrationFailed,(register_ok-number_of_udp_proxy),sal_get_refresher_retry_after(lc->sal)+3000)); - sal_set_recv_error(lc->sal, 1); /*reset*/ - sal_set_send_error(lc->sal, 0); + sal_set_recv_error(lc->sal, 1); /*reset*/ + sal_set_send_error(lc->sal, 0); - BC_ASSERT_TRUE(wait_for_list(lcs=ms_list_append(NULL,lc),&counters->number_of_LinphoneRegistrationOk,register_ok-number_of_udp_proxy +register_ok,sal_get_refresher_retry_after(lc->sal)+3000)); - - linphone_core_manager_destroy(mgr); + BC_ASSERT_TRUE(wait_for_list(lcs=ms_list_append(NULL,lc),&counters->number_of_LinphoneRegistrationOk,register_ok-number_of_udp_proxy +register_ok,sal_get_refresher_retry_after(lc->sal)+3000)); + linphone_core_manager_destroy(lcm); + } } -static void io_recv_error_without_active_register(){ - LinphoneCoreManager *mgr; +static void io_recv_error_without_active_register(void){ + LinphoneCoreManager *lcm; LinphoneCore* lc; int register_ok; stats* counters ; MSList* proxys; int dummy=0; - mgr=configure_lcm(); - lc=mgr->lc; - counters = get_stats(lc); + lcm=configure_lcm(); + if (lcm) { + lc=lcm->lc; + counters = get_stats(lc); - register_ok=counters->number_of_LinphoneRegistrationOk; + register_ok=counters->number_of_LinphoneRegistrationOk; - for (proxys=ms_list_copy(linphone_core_get_proxy_config_list(lc));proxys!=NULL;proxys=proxys->next) { - LinphoneProxyConfig* proxy_cfg=(LinphoneProxyConfig*)proxys->data; - linphone_proxy_config_edit(proxy_cfg); - linphone_proxy_config_enableregister(proxy_cfg,FALSE); - linphone_proxy_config_done(proxy_cfg); + for (proxys=ms_list_copy(linphone_core_get_proxy_config_list(lc));proxys!=NULL;proxys=proxys->next) { + LinphoneProxyConfig* proxy_cfg=(LinphoneProxyConfig*)proxys->data; + linphone_proxy_config_edit(proxy_cfg); + linphone_proxy_config_enableregister(proxy_cfg,FALSE); + linphone_proxy_config_done(proxy_cfg); + } + ms_list_free(proxys); + /*wait for unregistrations*/ + BC_ASSERT_TRUE(wait_for(lc,lc,&counters->number_of_LinphoneRegistrationCleared,register_ok /*because 1 udp*/)); + + sal_set_recv_error(lc->sal, 0); + + /*nothing should happen because no active registration*/ + wait_for_until(lc,lc, &dummy, 1, 3000); + BC_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationProgress, ms_list_size(linphone_core_get_proxy_config_list(lc)), int, "%d"); + + BC_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationFailed,0,int,"%d"); + + sal_set_recv_error(lc->sal, 1); /*reset*/ + + linphone_core_manager_destroy(lcm); } - ms_list_free(proxys); - /*wait for unregistrations*/ - BC_ASSERT_TRUE(wait_for(lc,lc,&counters->number_of_LinphoneRegistrationCleared,register_ok /*because 1 udp*/)); - - sal_set_recv_error(lc->sal, 0); - - /*nothing should happen because no active registration*/ - wait_for_until(lc,lc, &dummy, 1, 3000); - BC_ASSERT_TRUE(counters->number_of_LinphoneRegistrationProgress == ms_list_size(linphone_core_get_proxy_config_list(lc))); - - BC_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationFailed,0,int,"%d"); - - sal_set_recv_error(lc->sal, 1); /*reset*/ - - linphone_core_manager_destroy(mgr); } -static void tls_certificate_failure(){ - LinphoneCoreManager* mgr; - LinphoneCore *lc; - char rootcapath[256]; +static void tls_certificate_failure(void){ + if (transport_supported(LinphoneTransportTls)) { + LinphoneCoreManager* lcm; + LinphoneCore *lc; + char *rootcapath = bc_tester_res("certificates/cn/agent.pem"); /*bad root ca*/ - mgr=linphone_core_manager_new2("pauline_rc",FALSE); - lc=mgr->lc; - 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); - BC_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); - BC_ASSERT_TRUE(wait_for(lc,lc,&mgr->stat.number_of_LinphoneRegistrationFailed,2)); - 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); - BC_ASSERT_TRUE(wait_for(lc,lc,&mgr->stat.number_of_LinphoneRegistrationOk,1)); - BC_ASSERT_EQUAL(mgr->stat.number_of_LinphoneRegistrationFailed,2, int, "%d"); - linphone_core_destroy(mgr->lc); + lcm=linphone_core_manager_new2("pauline_rc",FALSE); + lc=lcm->lc; + linphone_core_set_root_ca(lcm->lc,rootcapath); + linphone_core_set_network_reachable(lc,TRUE); + BC_ASSERT_TRUE(wait_for(lcm->lc,lcm->lc,&lcm->stat.number_of_LinphoneRegistrationFailed,1)); + linphone_core_set_root_ca(lcm->lc,NULL); /*no root ca*/ + linphone_core_refresh_registers(lcm->lc); + BC_ASSERT_TRUE(wait_for(lc,lc,&lcm->stat.number_of_LinphoneRegistrationFailed,2)); + ms_free(rootcapath); + rootcapath = bc_tester_res("certificates/cn/cafile.pem"); /*good root ca*/ + linphone_core_set_root_ca(lcm->lc,rootcapath); + linphone_core_refresh_registers(lcm->lc); + BC_ASSERT_TRUE(wait_for(lc,lc,&lcm->stat.number_of_LinphoneRegistrationOk,1)); + BC_ASSERT_EQUAL(lcm->stat.number_of_LinphoneRegistrationFailed,2, int, "%d"); + linphone_core_manager_destroy(lcm); + ms_free(rootcapath); + } } /*the purpose of this test is to check that will not block the proxy config during SSL handshake for entire life in case of mistaken configuration*/ -static void tls_with_non_tls_server(){ - LinphoneCoreManager *mgr; - LinphoneProxyConfig* proxy_cfg; - LinphoneAddress* addr; - char tmp[256]; - LinphoneCore *lc; +static void tls_with_non_tls_server(void){ + if (transport_supported(LinphoneTransportTls)) { + LinphoneCoreManager *lcm; + LinphoneProxyConfig* proxy_cfg; + 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); - linphone_core_get_default_proxy(lc,&proxy_cfg); - linphone_proxy_config_edit(proxy_cfg); - addr=linphone_address_new(linphone_proxy_config_get_addr(proxy_cfg)); - snprintf(tmp,sizeof(tmp),"sip:%s:%i;transport=tls" ,linphone_address_get_domain(addr) - ,(linphone_address_get_port(addr)>0?linphone_address_get_port(addr):5060)); - linphone_proxy_config_set_server_addr(proxy_cfg,tmp); - linphone_proxy_config_done(proxy_cfg); - linphone_address_destroy(addr); - BC_ASSERT_TRUE(wait_for_until(lc,lc,&mgr->stat.number_of_LinphoneRegistrationFailed,1,5000)); - linphone_core_manager_destroy(mgr); + lcm=linphone_core_manager_new2( "marie_rc", 0); + lc=lcm->lc; + sal_set_transport_timeout(lc->sal,3000); + linphone_core_get_default_proxy(lc,&proxy_cfg); + linphone_proxy_config_edit(proxy_cfg); + addr=linphone_address_new(linphone_proxy_config_get_addr(proxy_cfg)); + snprintf(tmp,sizeof(tmp),"sip:%s:%i;transport=tls" ,linphone_address_get_domain(addr) + ,(linphone_address_get_port(addr)>0?linphone_address_get_port(addr):5060)); + linphone_proxy_config_set_server_addr(proxy_cfg,tmp); + linphone_proxy_config_done(proxy_cfg); + linphone_address_destroy(addr); + BC_ASSERT_TRUE(wait_for_until(lc,lc,&lcm->stat.number_of_LinphoneRegistrationFailed,1,5000)); + linphone_core_manager_destroy(lcm); + } } -static void tls_alt_name_register(){ - LinphoneCoreManager* mgr; - LinphoneCore *lc; - char rootcapath[256]; +static void tls_alt_name_register(void){ + if (transport_supported(LinphoneTransportTls)) { + LinphoneCoreManager* lcm; + LinphoneCore *lc; + char *rootcapath = bc_tester_res("certificates/cn/cafile.pem"); - mgr=linphone_core_manager_new2("pauline_alt_rc",FALSE); - lc=mgr->lc; - 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); - BC_ASSERT_TRUE(wait_for(lc,lc,&mgr->stat.number_of_LinphoneRegistrationOk,1)); - BC_ASSERT_EQUAL(mgr->stat.number_of_LinphoneRegistrationFailed,0, int, "%d"); - linphone_core_manager_destroy(mgr); + lcm=linphone_core_manager_new2("pauline_alt_rc",FALSE); + lc=lcm->lc; + linphone_core_set_root_ca(lc,rootcapath); + linphone_core_refresh_registers(lc); + BC_ASSERT_TRUE(wait_for(lc,lc,&lcm->stat.number_of_LinphoneRegistrationOk,1)); + BC_ASSERT_EQUAL(lcm->stat.number_of_LinphoneRegistrationFailed,0, int, "%d"); + linphone_core_manager_destroy(lcm); + ms_free(rootcapath); + } } -static void tls_wildcard_register(){ - LinphoneCoreManager* mgr; - LinphoneCore *lc; - char rootcapath[256]; +static void tls_wildcard_register(void){ + if (transport_supported(LinphoneTransportTls)) { + LinphoneCoreManager* lcm; + LinphoneCore *lc; + char *rootcapath = bc_tester_res("certificates/cn/cafile.pem"); - mgr=linphone_core_manager_new2("pauline_wild_rc",FALSE); - lc=mgr->lc; - 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); - BC_ASSERT_TRUE(wait_for(lc,lc,&mgr->stat.number_of_LinphoneRegistrationOk,2)); - BC_ASSERT_EQUAL(mgr->stat.number_of_LinphoneRegistrationFailed,0, int, "%d"); - linphone_core_destroy(mgr->lc); + lcm=linphone_core_manager_new2("pauline_wild_rc",FALSE); + lc=lcm->lc; + linphone_core_set_root_ca(lc,rootcapath); + linphone_core_refresh_registers(lc); + BC_ASSERT_TRUE(wait_for(lc,lc,&lcm->stat.number_of_LinphoneRegistrationOk,2)); + BC_ASSERT_EQUAL(lcm->stat.number_of_LinphoneRegistrationFailed,0, int, "%d"); + linphone_core_manager_destroy(lcm); + ms_free(rootcapath); + } } -static void redirect(){ +static void redirect(void){ char route[256]; LinphoneCoreManager* lcm; LCSipTransports transport = {-1,0,0,0}; sprintf(route,"sip:%s:5064",test_route); lcm = create_lcm(); - linphone_core_set_user_agent(lcm->lc,"redirect",NULL); - register_with_refresh_base_2(lcm->lc,FALSE,test_domain,route,FALSE,transport); - linphone_core_manager_destroy(lcm); + if (lcm) { + linphone_core_set_user_agent(lcm->lc,"redirect",NULL); + register_with_refresh_base_2(lcm->lc,FALSE,test_domain,route,FALSE,transport); + linphone_core_manager_destroy(lcm); + } } test_t register_tests[] = { @@ -848,6 +918,7 @@ test_t register_tests[] = { { "Digest auth with wrong credentials without 403", authenticated_register_with_wrong_credentials_without_403}, { "Authenticated register with wrong late credentials", authenticated_register_with_wrong_late_credentials}, { "Authenticated register with late credentials", authenticated_register_with_late_credentials }, + { "Authenticated register with provided credentials", authenticated_register_with_provided_credentials }, { "Register with refresh", simple_register_with_refresh }, { "Authenticated register with refresh", simple_auth_register_with_refresh }, { "Register with refresh and send error", register_with_refresh_with_send_error }, @@ -865,11 +936,5 @@ test_t register_tests[] = { { "Simple redirect", redirect} }; -test_suite_t register_test_suite = { - "Register", - NULL, - NULL, - sizeof(register_tests) / sizeof(register_tests[0]), - register_tests -}; - +test_suite_t register_test_suite = {"Register", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each, + sizeof(register_tests) / sizeof(register_tests[0]), register_tests}; diff --git a/tester/remote_provisioning_tester.c b/tester/remote_provisioning_tester.c index ad3c5ebb1..9bb1e41bf 100644 --- a/tester/remote_provisioning_tester.c +++ b/tester/remote_provisioning_tester.c @@ -52,16 +52,18 @@ static void remote_provisioning_transient(void) { LinphoneCoreManager* marie = linphone_core_manager_new2("marie_transient_remote_rc", FALSE); BC_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphoneConfiguringSuccessful,1)); BC_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphoneRegistrationOk,1)); - BC_ASSERT_TRUE(linphone_core_is_provisioning_transient(marie->lc) == TRUE); - BC_ASSERT_TRUE(linphone_core_get_provisioning_uri(marie->lc) == NULL); + BC_ASSERT_TRUE(linphone_core_is_provisioning_transient(marie->lc)); + BC_ASSERT_PTR_NULL(linphone_core_get_provisioning_uri(marie->lc)); linphone_core_manager_destroy(marie); } static void remote_provisioning_https(void) { - LinphoneCoreManager* marie = linphone_core_manager_new2("marie_remote_https_rc", FALSE); - BC_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphoneConfiguringSuccessful,1)); - BC_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphoneRegistrationOk,1)); - linphone_core_manager_destroy(marie); + if (transport_supported(LinphoneTransportTls)) { + LinphoneCoreManager* marie = linphone_core_manager_new2("marie_remote_https_rc", FALSE); + BC_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphoneConfiguringSuccessful,1)); + BC_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphoneRegistrationOk,1)); + linphone_core_manager_destroy(marie); + } } static void remote_provisioning_not_found(void) { @@ -87,8 +89,8 @@ static void remote_provisioning_default_values(void) { LinphoneCoreManager* marie = linphone_core_manager_new2("marie_remote_default_values_rc", FALSE); BC_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphoneConfiguringSuccessful,1)); lpc = linphone_core_create_proxy_config(marie->lc); - BC_ASSERT_TRUE(lpc->reg_sendregister == TRUE); - BC_ASSERT_TRUE(lpc->expires == 604800); + BC_ASSERT_TRUE(lpc->reg_sendregister); + BC_ASSERT_EQUAL(lpc->expires, 604800, int, "%d"); BC_ASSERT_STRING_EQUAL(lpc->reg_proxy, ""); BC_ASSERT_STRING_EQUAL(lpc->reg_route, ""); BC_ASSERT_STRING_EQUAL(lpc->reg_identity, "sip:?@sip.linphone.org"); @@ -96,7 +98,7 @@ static void remote_provisioning_default_values(void) { LpConfig* lp = linphone_core_get_config(marie->lc); BC_ASSERT_STRING_EQUAL(lp_config_get_string(lp,"app","toto","empty"),"titi"); } - + linphone_proxy_config_destroy(lpc); linphone_core_manager_destroy(marie); } @@ -108,6 +110,8 @@ static void remote_provisioning_file(void) { return; #elif defined(ANDROID) marie = linphone_core_manager_new2("marie_remote_localfile_android_rc", FALSE); +#elif defined(LINPHONE_WINDOWS_UNIVERSAL) + marie = linphone_core_manager_new2("marie_remote_localfile_win10_rc", FALSE); #else marie = linphone_core_manager_new2("marie_remote_localfile_rc", FALSE); #endif @@ -132,10 +136,6 @@ test_t remote_provisioning_tests[] = { { "Remote provisioning invalid URI", remote_provisioning_invalid_uri } }; -test_suite_t remote_provisioning_test_suite = { - "RemoteProvisioning", - NULL, - NULL, - sizeof(remote_provisioning_tests) / sizeof(remote_provisioning_tests[0]), - remote_provisioning_tests -}; +test_suite_t remote_provisioning_test_suite = {"RemoteProvisioning", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each, + sizeof(remote_provisioning_tests) / sizeof(remote_provisioning_tests[0]), + remote_provisioning_tests}; diff --git a/tester/setup_tester.c b/tester/setup_tester.c index cb1bcb883..a4af256c1 100644 --- a/tester/setup_tester.c +++ b/tester/setup_tester.c @@ -25,7 +25,7 @@ static void linphone_version_test(void){ const char *version=linphone_core_get_version(); /*make sure the git version is always included in the version number*/ - BC_ASSERT_TRUE(strstr(version,"unknown")==NULL); + BC_ASSERT_PTR_NULL(strstr(version,"unknown")); } static void core_init_test(void) { @@ -71,7 +71,7 @@ static void core_sip_transport_test(void) { linphone_core_destroy(lc); } -static void linphone_interpret_url_test() +static void linphone_interpret_url_test(void) { LinphoneCoreVTable v_table; LinphoneCore* lc; @@ -94,7 +94,7 @@ static void linphone_interpret_url_test() linphone_core_destroy ( lc ); } -static void linphone_lpconfig_from_buffer(){ +static void linphone_lpconfig_from_buffer(void){ const char* buffer = "[buffer]\ntest=ok"; const char* buffer_linebreaks = "[buffer_linebreaks]\n\n\n\r\n\n\r\ntest=ok"; LpConfig* conf; @@ -108,7 +108,7 @@ static void linphone_lpconfig_from_buffer(){ lp_config_destroy(conf); } -static void linphone_lpconfig_from_buffer_zerolen_value(){ +static void linphone_lpconfig_from_buffer_zerolen_value(void){ /* parameters that have no value should return NULL, not "". */ const char* zerolen = "[test]\nzero_len=\nnon_zero_len=test"; LpConfig* conf; @@ -124,10 +124,10 @@ static void linphone_lpconfig_from_buffer_zerolen_value(){ lp_config_destroy(conf); } -static void linphone_lpconfig_from_file_zerolen_value(){ +static void linphone_lpconfig_from_file_zerolen_value(void){ /* 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", bc_tester_read_dir_prefix, zero_rc_file); + char* rc_path = ms_strdup_printf("%s/rcfiles/%s", bc_tester_get_resource_dir_prefix(), zero_rc_file); LpConfig* conf; /* not using lp_config_new() because it expects a readable file, and iOS (for instance) @@ -146,9 +146,9 @@ static void linphone_lpconfig_from_file_zerolen_value(){ lp_config_destroy(conf); } -static void linphone_lpconfig_from_xml_zerolen_value(){ +static void linphone_lpconfig_from_xml_zerolen_value(void){ const char* zero_xml_file = "remote_zero_length_params_rc"; - char* xml_path = ms_strdup_printf("%s/rcfiles/%s", bc_tester_read_dir_prefix, zero_xml_file); + char* xml_path = ms_strdup_printf("%s/rcfiles/%s", bc_tester_get_resource_dir_prefix(), zero_xml_file); LpConfig* conf; LinphoneCoreManager* mgr = linphone_core_manager_new2("empty_rc",FALSE); @@ -167,7 +167,7 @@ static void linphone_lpconfig_from_xml_zerolen_value(){ ms_free(xml_path); } -void linphone_proxy_config_address_equal_test() { +void linphone_proxy_config_address_equal_test(void) { LinphoneAddress *a = linphone_address_new("sip:toto@titi"); LinphoneAddress *b = linphone_address_new("sips:toto@titi"); LinphoneAddress *c = linphone_address_new("sip:toto@titi;transport=tcp"); @@ -189,9 +189,11 @@ void linphone_proxy_config_address_equal_test() { linphone_address_destroy(b); linphone_address_destroy(c); linphone_address_destroy(d); + linphone_address_destroy(e); + linphone_address_destroy(f); } -void linphone_proxy_config_is_server_config_changed_test() { +void linphone_proxy_config_is_server_config_changed_test(void) { LinphoneProxyConfig* proxy_config = linphone_proxy_config_new(); linphone_proxy_config_done(proxy_config); /*test done without edit*/ @@ -233,13 +235,13 @@ void linphone_proxy_config_is_server_config_changed_test() { linphone_proxy_config_destroy(proxy_config); } -static void chat_root_test(void) { +static void chat_room_test(void) { LinphoneCoreVTable v_table; LinphoneCore* lc; memset (&v_table,0,sizeof(v_table)); lc = linphone_core_new(&v_table,NULL,NULL,NULL); BC_ASSERT_PTR_NOT_NULL_FATAL(lc); - linphone_core_create_chat_room(lc,"sip:toto@titi.com"); + BC_ASSERT_PTR_NOT_NULL(linphone_core_get_chat_room_from_uri(lc,"sip:toto@titi.com")); linphone_core_destroy(lc); } @@ -265,6 +267,30 @@ static void devices_reload_test(void) { linphone_core_manager_destroy(mgr); } +static void codec_usability_test(void) { + LinphoneCoreManager *mgr = linphone_core_manager_new2("empty_rc", FALSE); + PayloadType *pt = linphone_core_find_payload_type(mgr->lc, "PCMU", 8000, -1); + + BC_ASSERT_PTR_NOT_NULL(pt); + if (!pt) goto end; + /*no limit*/ + linphone_core_set_upload_bandwidth(mgr->lc, 0); + linphone_core_set_download_bandwidth(mgr->lc, 0); + BC_ASSERT_TRUE(linphone_core_check_payload_type_usability(mgr->lc, pt)); + /*low limit*/ + linphone_core_set_upload_bandwidth(mgr->lc, 50); + linphone_core_set_download_bandwidth(mgr->lc, 50); + BC_ASSERT_FALSE(linphone_core_check_payload_type_usability(mgr->lc, pt)); + + /*reasonable limit*/ + linphone_core_set_upload_bandwidth(mgr->lc, 200); + linphone_core_set_download_bandwidth(mgr->lc, 200); + BC_ASSERT_TRUE(linphone_core_check_payload_type_usability(mgr->lc, pt)); + +end: + linphone_core_manager_destroy(mgr); +} + test_t setup_tests[] = { { "Version check", linphone_version_test }, { "Linphone Address", linphone_address_test }, @@ -277,15 +303,10 @@ test_t setup_tests[] = { { "LPConfig zero_len value from buffer", linphone_lpconfig_from_buffer_zerolen_value }, { "LPConfig zero_len value from file", linphone_lpconfig_from_file_zerolen_value }, { "LPConfig zero_len value from XML", linphone_lpconfig_from_xml_zerolen_value }, - { "Chat room", chat_root_test }, - { "Devices reload", devices_reload_test } -}; - -test_suite_t setup_test_suite = { - "Setup", - NULL, - NULL, - sizeof(setup_tests) / sizeof(setup_tests[0]), - setup_tests + { "Chat room", chat_room_test }, + { "Devices reload", devices_reload_test }, + { "Codec usability", codec_usability_test } }; +test_suite_t setup_test_suite = {"Setup", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each, + sizeof(setup_tests) / sizeof(setup_tests[0]), setup_tests}; diff --git a/tester/sipp/call_invite_200ok_without_contact_header.xml b/tester/sipp/call_invite_200ok_without_contact_header.xml new file mode 100644 index 000000000..d53913047 --- /dev/null +++ b/tester/sipp/call_invite_200ok_without_contact_header.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Content-Length: 0 + + ]]> + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tester/sipp/call_with_audio_mline_before_video_in_sdp.xml b/tester/sipp/call_with_audio_mline_before_video_in_sdp.xml new file mode 100644 index 000000000..dabe990e4 --- /dev/null +++ b/tester/sipp/call_with_audio_mline_before_video_in_sdp.xml @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + ;tag=[pid]SIPpTag00[call_number] + To: sut + Call-ID: [call_id] + CSeq: 1 INVITE + Contact: sip:sipp@[local_ip]:[local_port] + Max-Forwards: 70 + Subject: Performance Test + Content-Type: application/sdp + Content-Length: [len] + + v=0 + o=user1 53655765 2353687637 IN IP[media_ip_type] [media_ip] + s=- + c=IN IP[media_ip_type] [media_ip] + t=0 0 + m=audio [media_port] RTP/AVP 96 97 0 8 101 98 + a=rtpmap:96 speex/16000 + a=fmtp:96 vbr=on + a=rtpmap:97 speex/8000 + a=fmtp:97 vbr=on + a=rtpmap:101 telephone-event/16000 + a=rtpmap:98 telephone-event/8000 + m=video [media_port+2] RTP/AVP 96 + a=rtpmap:96 VP8/90000 + + ]]> + + + + + + + + + + + + + + + + + + + + + ;tag=[pid]SIPpTag00[call_number] + To: sut [peer_tag_param] + Call-ID: [call_id] + CSeq: 1 ACK + Contact: sip:sipp@[local_ip]:[local_port] + Max-Forwards: 70 + Subject: Performance Test + Content-Length: 0 + + ]]> + + + + + + + + + ;tag=[pid]SIPpTag00[call_number] + To: sut [peer_tag_param] + Call-ID: [call_id] + CSeq: 2 BYE + Contact: sip:sipp@[local_ip]:[local_port] + Max-Forwards: 70 + Subject: Performance Test + Content-Length: 0 + + ]]> + + + + + + + + + + + + + diff --git a/tester/sipp/call_with_multiple_audio_mline_in_sdp.xml b/tester/sipp/call_with_multiple_audio_mline_in_sdp.xml new file mode 100644 index 000000000..ec4f70a4d --- /dev/null +++ b/tester/sipp/call_with_multiple_audio_mline_in_sdp.xml @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + ;tag=[pid]SIPpTag00[call_number] + To: sut + Call-ID: [call_id] + CSeq: 1 INVITE + Contact: sip:sipp@[local_ip]:[local_port] + Max-Forwards: 70 + Subject: Performance Test + Content-Type: application/sdp + Content-Length: [len] + + v=0 + o=user1 53655765 2353687637 IN IP[media_ip_type] [media_ip] + s=- + c=IN IP[media_ip_type] [media_ip] + t=0 0 + m=audio [media_port] RTP/AVP 96 97 0 8 101 98 + a=rtpmap:96 speex/16000 + a=fmtp:96 vbr=on + a=rtpmap:97 speex/8000 + a=fmtp:97 vbr=on + a=rtpmap:101 telephone-event/16000 + a=rtpmap:98 telephone-event/8000 + m=audio [media_port+1] RTP/AVP 96 97 0 8 101 98 + a=rtpmap:96 speex/16000 + a=fmtp:96 vbr=on + a=rtpmap:97 speex/8000 + a=fmtp:97 vbr=on + a=rtpmap:101 telephone-event/16000 + a=rtpmap:98 telephone-event/8000 + m=video [media_port+2] RTP/AVP 96 + a=rtpmap:96 VP8/90000 + + ]]> + + + + + + + + + + + + + + + + + + + + + ;tag=[pid]SIPpTag00[call_number] + To: sut [peer_tag_param] + Call-ID: [call_id] + CSeq: 1 ACK + Contact: sip:sipp@[local_ip]:[local_port] + Max-Forwards: 70 + Subject: Performance Test + Content-Length: 0 + + ]]> + + + + + + + + + ;tag=[pid]SIPpTag00[call_number] + To: sut [peer_tag_param] + Call-ID: [call_id] + CSeq: 2 BYE + Contact: sip:sipp@[local_ip]:[local_port] + Max-Forwards: 70 + Subject: Performance Test + Content-Length: 0 + + ]]> + + + + + + + + + + + + + diff --git a/tester/sipp/call_with_multiple_video_mline_in_sdp.xml b/tester/sipp/call_with_multiple_video_mline_in_sdp.xml new file mode 100644 index 000000000..dfd317e55 --- /dev/null +++ b/tester/sipp/call_with_multiple_video_mline_in_sdp.xml @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + ;tag=[pid]SIPpTag00[call_number] + To: sut + Call-ID: [call_id] + CSeq: 1 INVITE + Contact: sip:sipp@[local_ip]:[local_port] + Max-Forwards: 70 + Subject: Performance Test + Content-Type: application/sdp + Content-Length: [len] + + v=0 + o=user1 53655765 2353687637 IN IP[media_ip_type] [media_ip] + s=- + c=IN IP[media_ip_type] [media_ip] + t=0 0 + m=audio [media_port] RTP/AVP 96 97 0 8 101 98 + a=rtpmap:96 speex/16000 + a=fmtp:96 vbr=on + a=rtpmap:97 speex/8000 + a=fmtp:97 vbr=on + a=rtpmap:101 telephone-event/16000 + a=rtpmap:98 telephone-event/8000 + m=video [media_port+2] RTP/AVP 96 + a=rtpmap:96 VP8/90000 + m=video [media_port+3] RTP/AVP 96 + a=rtpmap:96 VP8/90000 + m=video [media_port+4] RTP/AVP 96 + a=rtpmap:96 VP8/90000 + + ]]> + + + + + + + + + + + + + + + + + + + + + ;tag=[pid]SIPpTag00[call_number] + To: sut [peer_tag_param] + Call-ID: [call_id] + CSeq: 1 ACK + Contact: sip:sipp@[local_ip]:[local_port] + Max-Forwards: 70 + Subject: Performance Test + Content-Length: 0 + + ]]> + + + + + + + + + ;tag=[pid]SIPpTag00[call_number] + To: sut [peer_tag_param] + Call-ID: [call_id] + CSeq: 2 BYE + Contact: sip:sipp@[local_ip]:[local_port] + Max-Forwards: 70 + Subject: Performance Test + Content-Length: 0 + + ]]> + + + + + + + + + + + + + diff --git a/tester/sipp/call_with_video_mline_before_audio_in_sdp.xml b/tester/sipp/call_with_video_mline_before_audio_in_sdp.xml new file mode 100644 index 000000000..d4d419597 --- /dev/null +++ b/tester/sipp/call_with_video_mline_before_audio_in_sdp.xml @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + ;tag=[pid]SIPpTag00[call_number] + To: sut + Call-ID: [call_id] + CSeq: 1 INVITE + Contact: sip:sipp@[local_ip]:[local_port] + Max-Forwards: 70 + Subject: Performance Test + Content-Type: application/sdp + Content-Length: [len] + + v=0 + o=user1 53655765 2353687637 IN IP[media_ip_type] [media_ip] + s=- + c=IN IP[media_ip_type] [media_ip] + t=0 0 + m=video [media_port+2] RTP/AVP 96 + a=rtpmap:96 VP8/90000 + m=audio [media_port] RTP/AVP 96 97 0 8 101 98 + a=rtpmap:96 speex/16000 + a=fmtp:96 vbr=on + a=rtpmap:97 speex/8000 + a=fmtp:97 vbr=on + a=rtpmap:101 telephone-event/16000 + a=rtpmap:98 telephone-event/8000 + + ]]> + + + + + + + + + + + + + + + + + + + + + ;tag=[pid]SIPpTag00[call_number] + To: sut [peer_tag_param] + Call-ID: [call_id] + CSeq: 1 ACK + Contact: sip:sipp@[local_ip]:[local_port] + Max-Forwards: 70 + Subject: Performance Test + Content-Length: 0 + + ]]> + + + + + + + + + ;tag=[pid]SIPpTag00[call_number] + To: sut [peer_tag_param] + Call-ID: [call_id] + CSeq: 2 BYE + Contact: sip:sipp@[local_ip]:[local_port] + Max-Forwards: 70 + Subject: Performance Test + Content-Length: 0 + + ]]> + + + + + + + + + + + + + diff --git a/tester/sipp/sip_update_within_icoming_reinvite_with_no_sdp.xml b/tester/sipp/sip_update_within_icoming_reinvite_with_no_sdp.xml new file mode 100644 index 000000000..9fffd4ff9 --- /dev/null +++ b/tester/sipp/sip_update_within_icoming_reinvite_with_no_sdp.xml @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + ;tag=[pid]SIPpTag00[call_number] + To: sut + Call-ID: [call_id] + CSeq: 1 INVITE + Contact: sip:sipp@[local_ip]:[local_port] + Max-Forwards: 70 + Subject: Performance Test + Content-Type: application/sdp + Content-Length: [len] + + v=0 + o=user1 53655765 2353687637 IN IP[media_ip_type] [media_ip] + s=- + c=IN IP[media_ip_type] [media_ip] + t=0 0 + m=audio [media_port] RTP/AVP 0 + a=rtpmap:0 PCMU/8000 + + ]]> + + + + + + + + + + + + + ;tag=[pid]SIPpTag00[call_number] + To: sut [peer_tag_param] + Call-ID: [call_id] + CSeq: 1 ACK + Contact: sip:sipp@[local_ip]:[local_port] + Max-Forwards: 70 + Subject: Performance Test + Content-Length: 0 + + ]]> + + + ;tag=[pid]SIPpTag00[call_number] + To: sut [peer_tag_param] + Call-ID: [call_id] + CSeq: 2 INVITE + Contact: sip:sipp@[local_ip]:[local_port] + Max-Forwards: 70 + Subject: Performance Test + Content-Length: 0 + + ]]> + + + + + + + + + + + ;tag=[pid]SIPpTag00[call_number] + To: sut [peer_tag_param] + Call-ID: [call_id] + CSeq: 3 UPDATE + Contact: sip:sipp@[local_ip]:[local_port] + Max-Forwards: 70 + Subject: Performance Test + Content-Length: 0 + + ]]> + + + + + ;tag=[pid]SIPpTag00[call_number] + To: sut [peer_tag_param] + Call-ID: [call_id] + CSeq: 2 ACK + Contact: sip:sipp@[local_ip]:[local_port] + Max-Forwards: 70 + Subject: Performance Test + Content-Type: application/sdp + Content-Length: [len] + + v=0 + o=user1 53655765 2353687637 IN IP[media_ip_type] [media_ip] + s=- + c=IN IP[media_ip_type] [media_ip] + t=0 0 + m=audio [media_port] RTP/AVP 0 + a=rtpmap:0 PCMU/8000 + + ]]> + + + + + + ;tag=[pid]SIPpTag00[call_number] + To: sut [peer_tag_param] + Call-ID: [call_id] + CSeq: 4 BYE + Contact: sip:sipp@[local_ip]:[local_port] + Max-Forwards: 70 + Subject: Performance Test + Content-Length: 0 + + ]]> + + + + + + + + + + + + + + diff --git a/tester/sounds/hello_opus_h264.mkv b/tester/sounds/hello_opus_h264.mkv deleted file mode 100644 index 4aa5d338b..000000000 Binary files a/tester/sounds/hello_opus_h264.mkv and /dev/null differ diff --git a/tester/sounds/sintel_trailer_opus_h264.mkv b/tester/sounds/sintel_trailer_opus_h264.mkv new file mode 100644 index 000000000..420f5c291 Binary files /dev/null and b/tester/sounds/sintel_trailer_opus_h264.mkv differ diff --git a/tester/sounds/sintel_trailer_opus_vp8.mkv b/tester/sounds/sintel_trailer_opus_vp8.mkv new file mode 100644 index 000000000..de7b37a3c Binary files /dev/null and b/tester/sounds/sintel_trailer_opus_vp8.mkv differ diff --git a/tester/sounds/sintel_trailer_pcmu_h264.mkv b/tester/sounds/sintel_trailer_pcmu_h264.mkv new file mode 100644 index 000000000..84b9bfa24 Binary files /dev/null and b/tester/sounds/sintel_trailer_pcmu_h264.mkv differ diff --git a/tester/sounds/vrroom.wav b/tester/sounds/vrroom.wav index 673a3addc..a78e25820 100644 Binary files a/tester/sounds/vrroom.wav and b/tester/sounds/vrroom.wav differ diff --git a/tester/stun_tester.c b/tester/stun_tester.c index 03aa1ac13..38da6fe16 100644 --- a/tester/stun_tester.c +++ b/tester/stun_tester.c @@ -36,7 +36,7 @@ static int test_stun_encode( char*buffer, size_t len, bool_t expect_fail ) memset(&username,0,sizeof(username)); memset(&password,0,sizeof(password)); stunBuildReqSimple( &req, &username, TRUE , TRUE , 11); - len = stunEncodeMessage( &req, buffer, len, &password); + len = stunEncodeMessage( &req, buffer, (unsigned int)len, &password); if (len<=0){ if( expect_fail ) ms_message("Fail to encode stun message (EXPECTED).\n"); @@ -44,11 +44,11 @@ static int test_stun_encode( char*buffer, size_t len, bool_t expect_fail ) ms_error("Fail to encode stun message.\n"); return -1; } - return len; + return (int)len; } -static void linphone_stun_test_encode() +static void linphone_stun_test_encode(void) { char smallBuff[12]; size_t smallLen = 12; @@ -64,7 +64,7 @@ static void linphone_stun_test_encode() } -static void linphone_stun_test_grab_ip() +static void linphone_stun_test_grab_ip(void) { LinphoneCoreManager* lc_stun = linphone_core_manager_new2( "stun_rc", FALSE); LinphoneCall dummy_call; @@ -72,8 +72,12 @@ static void linphone_stun_test_grab_ip() int tmp=0; memset(&dummy_call, 0, sizeof(LinphoneCall)); - dummy_call.media_ports[0].rtp_port = 7078; - dummy_call.media_ports[1].rtp_port = 9078; + dummy_call.main_audio_stream_index = 0; + dummy_call.main_video_stream_index = 1; + dummy_call.main_text_stream_index = 2; + dummy_call.media_ports[dummy_call.main_audio_stream_index].rtp_port = 7078; + dummy_call.media_ports[dummy_call.main_video_stream_index].rtp_port = 9078; + dummy_call.media_ports[dummy_call.main_text_stream_index].rtp_port = 11078; linphone_core_set_stun_server(lc_stun->lc, stun_address); BC_ASSERT_STRING_EQUAL(stun_address, linphone_core_get_stun_server(lc_stun->lc)); @@ -91,6 +95,8 @@ static void linphone_stun_test_grab_ip() BC_ASSERT( dummy_call.vc.addr[0] != '\0'); BC_ASSERT( dummy_call.vc.port != 0); #endif + BC_ASSERT( dummy_call.tc.addr[0] != '\0'); + BC_ASSERT( dummy_call.tc.port != 0); ms_message("STUN test result: local audio port maps to %s:%i", dummy_call.ac.addr, @@ -100,6 +106,9 @@ static void linphone_stun_test_grab_ip() dummy_call.vc.addr, dummy_call.vc.port); #endif + ms_message("STUN test result: local text port maps to %s:%i", + dummy_call.tc.addr, + dummy_call.tc.port); linphone_core_manager_destroy(lc_stun); } @@ -110,10 +119,5 @@ test_t stun_tests[] = { { "STUN encode buffer protection", linphone_stun_test_encode }, }; -test_suite_t stun_test_suite = { - "Stun", - NULL, - NULL, - sizeof(stun_tests) / sizeof(stun_tests[0]), - stun_tests -}; +test_suite_t stun_test_suite = {"Stun", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each, + sizeof(stun_tests) / sizeof(stun_tests[0]), stun_tests}; diff --git a/tester/tester.c b/tester/tester.c index e63629bc3..ad3380993 100644 --- a/tester/tester.c +++ b/tester/tester.c @@ -17,11 +17,17 @@ */ #include -#include "CUnit/TestRun.h" -#include "CUnit/Automated.h" #include "linphonecore.h" #include "private.h" #include "liblinphone_tester.h" + +#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4) +#pragma GCC diagnostic push +#endif +#pragma GCC diagnostic ignored "-Wstrict-prototypes" + +#include "CUnit/TestRun.h" +#include "CUnit/Automated.h" #if HAVE_CU_CURSES #include "CUnit/CUCurses.h" #endif @@ -29,9 +35,21 @@ #include #endif +#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4) +#pragma GCC diagnostic pop +#endif + +#if _WIN32 +#define unlink _unlink +#endif + static bool_t liblinphone_tester_ipv6_enabled=FALSE; static int liblinphone_tester_keep_accounts_flag = 0; -static int manager_count = 0; +static int liblinphone_tester_keep_record_files = FALSE; +static int liblinphone_tester_leak_detector_disabled = FALSE; +int manager_count = 0; +int leaked_objects_count = 0; +const MSAudioDiffParams audio_cmp_params = {10,2000}; const char* test_domain="sipopen.example.org"; const char* auth_domain="sip.example.org"; @@ -40,7 +58,9 @@ const char* test_password="secret"; const char* test_route="sip2.linphone.org"; const char *userhostsfile = "tester_hosts"; - static void network_reachable(LinphoneCore *lc, bool_t reachable) { +const char *liblinphone_tester_mire_id="Mire: Mire (synthetic moving picture)"; + +static void network_reachable(LinphoneCore *lc, bool_t reachable) { stats* counters; ms_message("Network reachable [%s]",reachable?"TRUE":"FALSE"); counters = get_stats(lc); @@ -90,6 +110,7 @@ static void auth_info_requested(LinphoneCore *lc, const char *realm, const char void reset_counters( stats* counters) { if (counters->last_received_chat_message) linphone_chat_message_unref(counters->last_received_chat_message); + if (counters->last_received_info_message) linphone_info_message_destroy(counters->last_received_info_message); memset(counters,0,sizeof(stats)); } @@ -107,7 +128,9 @@ LinphoneCore* configure_lc_from(LinphoneCoreVTable* v_table, const char* path, c if (file){ filepath = ms_strdup_printf("%s/%s", path, file); - BC_ASSERT_TRUE_FATAL(ortp_file_exist(filepath)==0); + if (ortp_file_exist(filepath) != 0) { + ms_fatal("Could not find file %s in path %s, did you configured resources directory correctly?", file, path); + } config = lp_config_new_with_factory(NULL,filepath); } @@ -183,7 +206,7 @@ bool_t wait_for_list(MSList* lcs,int* counter,int value,int timeout_ms) { #endif linphone_core_iterate((LinphoneCore*)(iterator->data)); } -#ifdef WIN32 +#ifdef LINPHONE_WINDOWS_DESKTOP { MSG msg; while (PeekMessage(&msg, NULL, 0, 0,1)){ @@ -224,9 +247,23 @@ LinphoneCoreManager *get_manager(LinphoneCore *lc){ return manager; } +bool_t transport_supported(LinphoneTransportType transport) { + Sal *sal = sal_init(); + bool_t supported = sal_transport_available(sal,(SalTransport)transport); + if (!supported) ms_message("TLS transport not supported, falling back to TCP if possible otherwise skipping test."); + sal_uninit(sal); + return supported; +} + + +static void display_status(LinphoneCore *lc, const char *status){ + ms_message("display_status(): %s",status); +} + LinphoneCoreManager* linphone_core_manager_init(const char* rc_file) { LinphoneCoreManager* mgr= ms_new0(LinphoneCoreManager,1); char *rc_path = NULL; + char *hellopath = bc_tester_res("sounds/hello8000.wav"); 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; @@ -246,10 +283,11 @@ LinphoneCoreManager* linphone_core_manager_init(const char* rc_file) { mgr->v_table.network_reachable=network_reachable; mgr->v_table.dtmf_received=dtmf_received; mgr->v_table.call_stats_updated=call_stats_updated; + mgr->v_table.display_status=display_status; reset_counters(&mgr->stat); if (rc_file) rc_path = ms_strdup_printf("rcfiles/%s", rc_file); - mgr->lc=configure_lc_from(&mgr->v_table, bc_tester_read_dir_prefix, rc_path, mgr); + mgr->lc=configure_lc_from(&mgr->v_table, bc_tester_get_resource_dir_prefix(), rc_path, mgr); linphone_core_manager_check_accounts(mgr); manager_count++; @@ -257,6 +295,8 @@ LinphoneCoreManager* linphone_core_manager_init(const char* rc_file) { #if TARGET_OS_IPHONE linphone_core_set_ringer_device( mgr->lc, "AQ: Audio Queue Device"); linphone_core_set_ringback(mgr->lc, NULL); +#elif __QNX__ + linphone_core_set_playback_device(mgr->lc, "QSA: voice"); #endif #ifdef VIDEO_ENABLED @@ -276,17 +316,18 @@ LinphoneCoreManager* linphone_core_manager_init(const char* rc_file) { #endif + linphone_core_set_play_file(mgr->lc,hellopath); /*is also used when in pause*/ + ms_free(hellopath); + if( manager_count >= 2){ - char hellopath[512]; - char *recordpath = ms_strdup_printf("%s/record_for_lc_%p.wav",bc_tester_writable_dir_prefix,mgr->lc); + char *recordpath = ms_strdup_printf("%s/record_for_lc_%p.wav",bc_tester_get_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", bc_tester_read_dir_prefix); - linphone_core_set_play_file(mgr->lc,hellopath); + linphone_core_set_use_files(mgr->lc, TRUE); linphone_core_set_record_file(mgr->lc,recordpath); ms_free(recordpath); } - linphone_core_set_user_certificates_path(mgr->lc,bc_tester_writable_dir_prefix); + + linphone_core_set_user_certificates_path(mgr->lc,bc_tester_get_writable_dir_prefix()); if (rc_path) ms_free(rc_path); @@ -316,7 +357,7 @@ void linphone_core_manager_start(LinphoneCoreManager *mgr, const char* rc_file, linphone_core_get_default_proxy(mgr->lc,&proxy); if (proxy) { - mgr->identity = linphone_address_new(linphone_proxy_config_get_identity(proxy)); + mgr->identity = linphone_address_clone(linphone_proxy_config_get_identity_address(proxy)); linphone_address_clean(mgr->identity); } } @@ -341,19 +382,30 @@ void linphone_core_manager_stop(LinphoneCoreManager *mgr){ } void linphone_core_manager_destroy(LinphoneCoreManager* mgr) { + if (mgr->stat.last_received_chat_message) { + linphone_chat_message_unref(mgr->stat.last_received_chat_message); + } + if (mgr->stat.last_received_info_message) linphone_info_message_destroy(mgr->stat.last_received_info_message); if (mgr->lc){ const char *record_file=linphone_core_get_record_file(mgr->lc); - if (record_file){ + int unterminated_calls; + + if (!liblinphone_tester_keep_record_files && record_file){ if ((CU_get_number_of_failures()-mgr->number_of_cunit_error_at_creation)>0) { ms_message ("Test has failed, keeping recorded file [%s]",record_file); } else { unlink(record_file); } } + BC_ASSERT_EQUAL((unterminated_calls=ms_list_size(mgr->lc->calls)), 0, int, "%i"); + if (unterminated_calls != 0) { + ms_error("There are still %d calls pending, please terminates them before invoking linphone_core_manager_destroy().", unterminated_calls); + } linphone_core_destroy(mgr->lc); } - if (mgr->identity) linphone_address_destroy(mgr->identity); - if (mgr->stat.last_received_chat_message) linphone_chat_message_unref(mgr->stat.last_received_chat_message); + if (mgr->identity) { + linphone_address_destroy(mgr->identity); + } manager_count--; ms_free(mgr); @@ -367,7 +419,7 @@ int liblinphone_tester_ipv6_available(void){ socklen_t slen=sizeof(ss); char localip[128]; int port=0; - belle_sip_get_src_addr_for(ai->ai_addr,ai->ai_addrlen,(struct sockaddr*) &ss,&slen,4444); + belle_sip_get_src_addr_for(ai->ai_addr,(socklen_t)ai->ai_addrlen,(struct sockaddr*) &ss,&slen,4444); src.ai_addr=(struct sockaddr*) &ss; src.ai_addrlen=slen; belle_sip_addrinfo_to_ip(&src,localip, sizeof(localip),&port); @@ -381,6 +433,14 @@ void liblinphone_tester_keep_accounts( int keep ){ liblinphone_tester_keep_accounts_flag = keep; } +void liblinphone_tester_keep_recorded_files(int keep){ + liblinphone_tester_keep_record_files = keep; +} + +void liblinphone_tester_disable_leak_detector(int disabled){ + liblinphone_tester_leak_detector_disabled = disabled; +} + void liblinphone_tester_clear_accounts(void){ account_manager_destroy(); } @@ -402,11 +462,210 @@ void liblinphone_tester_add_suites() { 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(&tunnel_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); + bc_tester_add_suite(&proxy_config_test_suite); +#if HAVE_SIPP + bc_tester_add_suite(&complex_sip_call_test_suite); +#endif } + +static int linphone_core_manager_get_max_audio_bw_base(const int array[],int array_size) { + int i,result=0; + for (i=0; istat.audio_download_bandwidth + , sizeof(mgr->stat.audio_download_bandwidth)/sizeof(int)); +} +int linphone_core_manager_get_max_audio_up_bw(const LinphoneCoreManager *mgr) { + return linphone_core_manager_get_max_audio_bw_base(mgr->stat.audio_upload_bandwidth + , sizeof(mgr->stat.audio_upload_bandwidth)/sizeof(int)); +} + +int linphone_core_manager_get_mean_audio_down_bw(const LinphoneCoreManager *mgr) { + return linphone_core_manager_get_mean_audio_bw_base(mgr->stat.audio_download_bandwidth + , sizeof(mgr->stat.audio_download_bandwidth)/sizeof(int)); +} +int linphone_core_manager_get_mean_audio_up_bw(const LinphoneCoreManager *mgr) { + return linphone_core_manager_get_mean_audio_bw_base(mgr->stat.audio_upload_bandwidth + , sizeof(mgr->stat.audio_upload_bandwidth)/sizeof(int)); +} + +void liblinphone_tester_before_each(void) { + if (!liblinphone_tester_leak_detector_disabled){ + belle_sip_object_enable_leak_detector(TRUE); + leaked_objects_count = belle_sip_object_get_object_count(); + } +} + +static char* all_leaks_buffer = NULL; + +void liblinphone_tester_after_each(void) { + if (!liblinphone_tester_leak_detector_disabled){ + int leaked_objects = belle_sip_object_get_object_count() - leaked_objects_count; + if (leaked_objects > 0) { + char* format = ms_strdup_printf("%d object%s leaked in suite [%s] test [%s], please fix that!", + leaked_objects, leaked_objects>1?"s were":"was", + bc_tester_current_suite_name(), bc_tester_current_test_name()); + belle_sip_object_dump_active_objects(); + belle_sip_object_flush_active_objects(); + bc_tester_printf(bc_printf_verbosity_info, format); + ms_error("%s", format); + + all_leaks_buffer = ms_strcat_printf(all_leaks_buffer, "\n%s", format); + } + } + + if (manager_count != 0) { + ms_fatal("%d Linphone core managers are still alive!", manager_count); + } +} + +void liblinphone_tester_uninit(void) { + // show all leaks that happened during the test + if (all_leaks_buffer) { + bc_tester_printf(bc_printf_verbosity_info, all_leaks_buffer); + ms_free(all_leaks_buffer); + all_leaks_buffer = NULL; + } + bc_tester_uninit(); +} + +static void check_ice_from_rtp(LinphoneCall *c1, LinphoneCall *c2, LinphoneStreamType stream_type) { + MediaStream *ms; + switch (stream_type) { + case LinphoneStreamTypeAudio: + ms=&c1->audiostream->ms; + break; + case LinphoneStreamTypeVideo: + ms=&c1->videostream->ms; + break; + case LinphoneStreamTypeText: + ms=&c1->textstream->ms; + break; + default: + ms_error("Unknown stream type [%s]", linphone_stream_type_to_string(stream_type)); + BC_ASSERT_FALSE(stream_type >= LinphoneStreamTypeUnknown); + return; + } + + + if (linphone_call_get_audio_stats(c1)->ice_state == LinphoneIceStateHostConnection && media_stream_started(ms)) { + char ip[16]; + char port[8]; + getnameinfo((const struct sockaddr *)&c1->audiostream->ms.sessions.rtp_session->rtp.gs.rem_addr + , c1->audiostream->ms.sessions.rtp_session->rtp.gs.rem_addrlen + , ip + , sizeof(ip) + , port + , sizeof(port) + , NI_NUMERICHOST|NI_NUMERICSERV); + BC_ASSERT_STRING_EQUAL(ip, c2->media_localip); + } +} +bool_t check_ice(LinphoneCoreManager* caller, LinphoneCoreManager* callee, LinphoneIceState state) { + LinphoneCall *c1,*c2; + bool_t audio_success=FALSE; + bool_t video_success=FALSE; + bool_t text_success=FALSE; + bool_t video_enabled, realtime_text_enabled; + MSTimeSpec ts; + + c1=linphone_core_get_current_call(caller->lc); + c2=linphone_core_get_current_call(callee->lc); + + BC_ASSERT_PTR_NOT_NULL(c1); + BC_ASSERT_PTR_NOT_NULL(c2); + if (!c1 || !c2) return FALSE; + linphone_call_ref(c1); + linphone_call_ref(c2); + + BC_ASSERT_EQUAL(linphone_call_params_video_enabled(linphone_call_get_current_params(c1)),linphone_call_params_video_enabled(linphone_call_get_current_params(c2)), int, "%d"); + BC_ASSERT_EQUAL(linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(c1)),linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(c2)), int, "%d"); + video_enabled=linphone_call_params_video_enabled(linphone_call_get_current_params(c1)); + realtime_text_enabled=linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(c1)); + liblinphone_tester_clock_start(&ts); + do{ + if ((c1 != NULL) && (c2 != NULL)) { + if (linphone_call_get_audio_stats(c1)->ice_state==state && + linphone_call_get_audio_stats(c2)->ice_state==state ){ + audio_success=TRUE; + check_ice_from_rtp(c1,c2,LinphoneStreamTypeAudio); + check_ice_from_rtp(c2,c1,LinphoneStreamTypeAudio); + break; + } + linphone_core_iterate(caller->lc); + linphone_core_iterate(callee->lc); + } + ms_usleep(20000); + }while(!liblinphone_tester_clock_elapsed(&ts,10000)); + + if (video_enabled){ + liblinphone_tester_clock_start(&ts); + do{ + if ((c1 != NULL) && (c2 != NULL)) { + if (linphone_call_get_video_stats(c1)->ice_state==state && + linphone_call_get_video_stats(c2)->ice_state==state ){ + video_success=TRUE; + check_ice_from_rtp(c1,c2,LinphoneStreamTypeVideo); + check_ice_from_rtp(c2,c1,LinphoneStreamTypeVideo); + break; + } + linphone_core_iterate(caller->lc); + linphone_core_iterate(callee->lc); + } + ms_usleep(20000); + }while(!liblinphone_tester_clock_elapsed(&ts,10000)); + } + + if (realtime_text_enabled){ + liblinphone_tester_clock_start(&ts); + do{ + if ((c1 != NULL) && (c2 != NULL)) { + if (linphone_call_get_text_stats(c1)->ice_state==state && + linphone_call_get_text_stats(c2)->ice_state==state ){ + text_success=TRUE; + check_ice_from_rtp(c1,c2,LinphoneStreamTypeText); + check_ice_from_rtp(c2,c1,LinphoneStreamTypeText); + break; + } + linphone_core_iterate(caller->lc); + linphone_core_iterate(callee->lc); + } + ms_usleep(20000); + }while(!liblinphone_tester_clock_elapsed(&ts,10000)); + } + + /*make sure encryption mode are preserved*/ + if (c1) { + const LinphoneCallParams* call_param = linphone_call_get_current_params(c1); + BC_ASSERT_EQUAL(linphone_call_params_get_media_encryption(call_param),linphone_core_get_media_encryption(caller->lc), int, "%d"); + } + if (c2) { + const LinphoneCallParams* call_param = linphone_call_get_current_params(c2); + BC_ASSERT_EQUAL(linphone_call_params_get_media_encryption(call_param),linphone_core_get_media_encryption(callee->lc), int, "%d"); + } + linphone_call_unref(c1); + linphone_call_unref(c2); + return video_enabled ? (realtime_text_enabled ? text_success && audio_success && video_success : audio_success && video_success) : realtime_text_enabled ? text_success && audio_success : audio_success; +} + + diff --git a/tester/transport_tester.c b/tester/tunnel_tester.c similarity index 80% rename from tester/transport_tester.c rename to tester/tunnel_tester.c index aae69c3a0..f3d383cf2 100644 --- a/tester/transport_tester.c +++ b/tester/tunnel_tester.c @@ -46,19 +46,13 @@ static const char* get_ip_from_hostname(const char * tunnel_hostname){ return output; } static char* get_public_contact_ip(LinphoneCore* lc) { - long contact_host_ip_len; - char contact_host_ip[255]; - char * contact = linphone_proxy_config_get_contact(linphone_core_get_default_proxy_config(lc)); + const LinphoneAddress * contact = linphone_proxy_config_get_contact(linphone_core_get_default_proxy_config(lc)); BC_ASSERT_PTR_NOT_NULL(contact); - contact_host_ip_len = strchr(contact, ':')-contact; - strncpy(contact_host_ip, contact, contact_host_ip_len); - contact_host_ip[contact_host_ip_len]='\0'; - ms_free(contact); - return ms_strdup(contact_host_ip); + return ms_strdup(linphone_address_get_domain(contact)); } -static void call_with_transport_base(LinphoneTunnelMode tunnel_mode, bool_t with_sip, LinphoneMediaEncryption encryption, bool_t with_video_and_ice) { +static void call_with_tunnel_base(LinphoneTunnelMode tunnel_mode, bool_t with_sip, LinphoneMediaEncryption encryption, bool_t with_video_and_ice) { if (linphone_core_tunnel_available()){ LinphoneCoreManager *pauline = linphone_core_manager_new( "pauline_rc"); LinphoneCoreManager *marie = linphone_core_manager_new( "marie_rc"); @@ -134,8 +128,8 @@ static void call_with_transport_base(LinphoneTunnelMode tunnel_mode, bool_t with pauline_call=linphone_core_get_current_call(pauline->lc); BC_ASSERT_PTR_NOT_NULL(pauline_call); if (pauline_call!=NULL){ - BC_ASSERT_PTR_EQUAL(linphone_call_params_get_media_encryption(linphone_call_get_current_params(pauline_call)), - encryption); + BC_ASSERT_EQUAL(linphone_call_params_get_media_encryption(linphone_call_get_current_params(pauline_call)), + encryption, int, "%d"); } if (tunnel_mode == LinphoneTunnelModeEnable && with_sip){ /* make sure the call from pauline arrived from the tunnel by checking the contact address*/ @@ -174,30 +168,30 @@ static void call_with_transport_base(LinphoneTunnelMode tunnel_mode, bool_t with static void call_with_tunnel(void) { - call_with_transport_base(LinphoneTunnelModeEnable, TRUE, LinphoneMediaEncryptionNone, FALSE); + call_with_tunnel_base(LinphoneTunnelModeEnable, TRUE, LinphoneMediaEncryptionNone, FALSE); } static void call_with_tunnel_srtp(void) { - call_with_transport_base(LinphoneTunnelModeEnable, TRUE, LinphoneMediaEncryptionSRTP, FALSE); + call_with_tunnel_base(LinphoneTunnelModeEnable, TRUE, LinphoneMediaEncryptionSRTP, FALSE); } static void call_with_tunnel_without_sip(void) { - call_with_transport_base(LinphoneTunnelModeEnable, FALSE, LinphoneMediaEncryptionNone, FALSE); + call_with_tunnel_base(LinphoneTunnelModeEnable, FALSE, LinphoneMediaEncryptionNone, FALSE); } static void call_with_tunnel_auto(void) { - call_with_transport_base(LinphoneTunnelModeAuto, TRUE, LinphoneMediaEncryptionNone, FALSE); + call_with_tunnel_base(LinphoneTunnelModeAuto, TRUE, LinphoneMediaEncryptionNone, FALSE); } static void call_with_tunnel_auto_without_sip_with_srtp(void) { - call_with_transport_base(LinphoneTunnelModeAuto, FALSE, LinphoneMediaEncryptionSRTP, FALSE); + call_with_tunnel_base(LinphoneTunnelModeAuto, FALSE, LinphoneMediaEncryptionSRTP, FALSE); } #ifdef VIDEO_ENABLED static void full_tunnel_video_ice_call(void){ if (linphone_core_tunnel_available()){ - call_with_transport_base(LinphoneTunnelModeEnable, TRUE, LinphoneMediaEncryptionNone, TRUE); + call_with_tunnel_base(LinphoneTunnelModeEnable, TRUE, LinphoneMediaEncryptionNone, TRUE); }else ms_warning("Could not test %s because tunnel functionality is not available",__FUNCTION__); } @@ -250,28 +244,23 @@ static void tunnel_ice_call(void) { else ms_warning("Could not test %s because tunnel functionality is not available",__FUNCTION__); } -test_t transport_tests[] = { - { "Tunnel only", call_with_tunnel }, - { "Tunnel with SRTP", call_with_tunnel_srtp }, - { "Tunnel without SIP", call_with_tunnel_without_sip }, - { "Tunnel in automatic mode", call_with_tunnel_auto }, - { "Tunnel in automatic mode with SRTP without SIP", call_with_tunnel_auto_without_sip_with_srtp }, - { "Tunnel ice call", tunnel_ice_call }, - { "Tunnel SRTP ice call", tunnel_srtp_ice_call }, - { "Tunnel ZRTP ice call", tunnel_zrtp_ice_call }, +test_t tunnel_tests[] = { + { "Simple", call_with_tunnel }, + { "With SRTP", call_with_tunnel_srtp }, + { "Without SIP", call_with_tunnel_without_sip }, + { "In automatic mode", call_with_tunnel_auto }, + { "In automatic mode with SRTP without SIP", call_with_tunnel_auto_without_sip_with_srtp }, + { "Ice call", tunnel_ice_call }, + { "SRTP ice call", tunnel_srtp_ice_call }, + { "ZRTP ice call", tunnel_zrtp_ice_call }, #ifdef VIDEO_ENABLED - { "Tunnel ice video call", tunnel_video_ice_call }, - { "Tunnel with SIP - ice video call", full_tunnel_video_ice_call }, - { "Tunnel SRTP ice video call", tunnel_srtp_video_ice_call }, - { "Tunnel DTLS ice video call", tunnel_dtls_video_ice_call }, - { "Tunnel ZRTP ice video call", tunnel_zrtp_video_ice_call }, + { "Ice video call", tunnel_video_ice_call }, + { "With SIP - ice video call", full_tunnel_video_ice_call }, + { "SRTP ice video call", tunnel_srtp_video_ice_call }, + { "DTLS ice video call", tunnel_dtls_video_ice_call }, + { "ZRTP ice video call", tunnel_zrtp_video_ice_call }, #endif }; -test_suite_t transport_test_suite = { - "Transport", - NULL, - NULL, - sizeof(transport_tests) / sizeof(transport_tests[0]), - transport_tests -}; +test_suite_t tunnel_test_suite = {"Tunnel", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each, + sizeof(tunnel_tests) / sizeof(tunnel_tests[0]), tunnel_tests}; diff --git a/tester/upnp_tester.c b/tester/upnp_tester.c index 3f39b0c9c..bef3a626f 100644 --- a/tester/upnp_tester.c +++ b/tester/upnp_tester.c @@ -27,7 +27,7 @@ static void upnp_start_n_stop(void) { LinphoneCoreManager* lc_upnp = linphone_core_manager_new2( "upnp_rc", FALSE); wait_for(lc_upnp->lc,lc_upnp->lc,&tmp,1); #ifdef BUILD_UPNP - BC_ASSERT_TRUE(lc_upnp->lc->upnp != NULL); + BC_ASSERT_PTR_NOT_NULL(lc_upnp->lc->upnp); #endif linphone_core_manager_destroy(lc_upnp); } @@ -36,7 +36,7 @@ static void upnp_check_state(void) { int tmp = 0; LinphoneCoreManager* lc_upnp = linphone_core_manager_new2( "upnp_rc", FALSE); wait_for(lc_upnp->lc,lc_upnp->lc,&tmp,1); - BC_ASSERT_TRUE(linphone_core_get_upnp_state(lc_upnp->lc) == LinphoneUpnpStateOk); + BC_ASSERT_EQUAL(linphone_core_get_upnp_state(lc_upnp->lc), LinphoneUpnpStateOk, int, "%d"); linphone_core_manager_destroy(lc_upnp); } @@ -46,7 +46,10 @@ static void upnp_check_ipaddress(void) { LinphoneCoreManager* lc_upnp = linphone_core_manager_new2( "upnp_rc", FALSE); wait_for(lc_upnp->lc,lc_upnp->lc,&tmp,1); addr = linphone_core_get_upnp_external_ipaddress(lc_upnp->lc); - BC_ASSERT_TRUE(addr != NULL && strlen(addr)>=7); + BC_ASSERT_PTR_NOT_NULL(addr); + if (addr!=NULL) { + BC_ASSERT_GREATER((int)strlen(addr),7,int,"%d"); + } linphone_core_manager_destroy(lc_upnp); } @@ -56,10 +59,5 @@ test_t upnp_tests[] = { { "Check ip address", upnp_check_ipaddress }, }; -test_suite_t upnp_test_suite = { - "Upnp", - NULL, - NULL, - sizeof(upnp_tests) / sizeof(upnp_tests[0]), - upnp_tests -}; +test_suite_t upnp_test_suite = {"Upnp", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each, + sizeof(upnp_tests) / sizeof(upnp_tests[0]), upnp_tests}; diff --git a/tester/video_tester.c b/tester/video_tester.c index 163d2f3f0..6dc165bf6 100644 --- a/tester/video_tester.c +++ b/tester/video_tester.c @@ -17,18 +17,23 @@ */ #include "private.h" -#if defined(VIDEO_ENABLED) && defined(HAVE_GTK) +#if defined(VIDEO_ENABLED) #include "linphonecore.h" #include "liblinphone_tester.h" #include "lpconfig.h" +#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4) +#pragma GCC diagnostic push +#endif +#pragma GCC diagnostic ignored "-Wstrict-prototypes" +#if HAVE_GTK #include #ifdef GDK_WINDOWING_X11 #include -#elif defined(WIN32) +#elif defined(_WIN32) #include #elif defined(__APPLE__) extern void *gdk_quartz_window_get_nswindow(GdkWindow *window); @@ -37,14 +42,18 @@ extern void *gdk_quartz_window_get_nsview(GdkWindow *window); #include +#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4) +#pragma GCC diagnostic pop +#endif -static unsigned long get_native_handle(GdkWindow *gdkw) { + +static void *get_native_handle(GdkWindow *gdkw) { #ifdef GDK_WINDOWING_X11 - return (unsigned long)GDK_WINDOW_XID(gdkw); -#elif defined(WIN32) - return (unsigned long)GDK_WINDOW_HWND(gdkw); + return (void *)GDK_WINDOW_XID(gdkw); +#elif defined(_WIN32) + return (void *)GDK_WINDOW_HWND(gdkw); #elif defined(__APPLE__) - return (unsigned long)gdk_quartz_window_get_nsview(gdkw); + return (void *)gdk_quartz_window_get_nsview(gdkw); #endif g_warning("No way to get the native handle from gdk window"); return 0; @@ -118,7 +127,7 @@ static void early_media_video_call_state_changed(LinphoneCore *lc, LinphoneCall video_call_state_changed(lc, call, cstate, msg); switch (cstate) { case LinphoneCallIncomingReceived: - params = linphone_core_create_default_call_parameters(lc); + params = linphone_core_create_call_params(lc, call); linphone_call_params_enable_video(params, TRUE); linphone_call_params_set_audio_direction(params, LinphoneMediaDirectionSendOnly); linphone_call_params_set_video_direction(params, LinphoneMediaDirectionRecvOnly); @@ -136,7 +145,7 @@ static void early_media_video_call_state_changed_with_inactive_audio(LinphoneCor video_call_state_changed(lc, call, cstate, msg); switch (cstate) { case LinphoneCallIncomingReceived: - params = linphone_core_create_default_call_parameters(lc); + params = linphone_core_create_call_params(lc, call); linphone_call_params_enable_video(params, TRUE); linphone_call_params_set_audio_direction(params, LinphoneMediaDirectionInactive); linphone_call_params_set_video_direction(params, LinphoneMediaDirectionRecvOnly); @@ -175,10 +184,10 @@ static bool_t video_call_with_params(LinphoneCoreManager* caller_mgr, LinphoneCo while (caller_mgr->stat.number_of_LinphoneCallOutgoingRinging != (initial_caller.number_of_LinphoneCallOutgoingRinging + 1) && caller_mgr->stat.number_of_LinphoneCallOutgoingEarlyMedia != (initial_caller.number_of_LinphoneCallOutgoingEarlyMedia + 1) - && retry++ < 20) { + && retry++ < 200) { linphone_core_iterate(caller_mgr->lc); linphone_core_iterate(callee_mgr->lc); - ms_usleep(100000); + ms_usleep(10000); } BC_ASSERT_TRUE((caller_mgr->stat.number_of_LinphoneCallOutgoingRinging == initial_caller.number_of_LinphoneCallOutgoingRinging + 1) @@ -208,7 +217,7 @@ static LinphoneCallParams * _configure_for_video(LinphoneCoreManager *manager, L linphone_core_set_video_device(manager->lc, "StaticImage: Static picture"); linphone_core_enable_video_capture(manager->lc, TRUE); linphone_core_enable_video_display(manager->lc, TRUE); - params = linphone_core_create_default_call_parameters(manager->lc); + params = linphone_core_create_call_params(manager->lc, NULL); linphone_call_params_enable_video(params, TRUE); if (linphone_core_find_payload_type(manager->lc,"VP8", 90000, -1)!=NULL){ disable_all_video_codecs_except_one(manager->lc, "VP8"); @@ -247,7 +256,7 @@ static void early_media_video_during_video_call_test(void) { LinphoneCallParams *laure_params; marie = linphone_core_manager_new("marie_rc"); - pauline = linphone_core_manager_new("pauline_rc"); + pauline = linphone_core_manager_new("pauline_tcp_rc"); laure = linphone_core_manager_new("laure_rc"); marie_params = configure_for_early_media_video_receiving(marie); pauline_params = configure_for_video(pauline); @@ -297,7 +306,7 @@ static void two_incoming_early_media_video_calls_test(void) { const MSList *calls_list; marie = linphone_core_manager_new("marie_rc"); - pauline = linphone_core_manager_new("pauline_rc"); + pauline = linphone_core_manager_new("pauline_tcp_rc"); laure = linphone_core_manager_new("laure_rc"); marie_params = configure_for_early_media_video_receiving(marie); pauline_params = configure_for_early_media_video_sending(pauline); @@ -305,7 +314,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", bc_tester_read_dir_prefix); + ringback_path = bc_tester_res("sounds/ringback.wav"); linphone_core_set_remote_ringback_tone(marie->lc, ringback_path); ms_free(ringback_path); @@ -364,7 +373,7 @@ static void early_media_video_with_inactive_audio(void) { LinphoneCallParams *pauline_params; marie = linphone_core_manager_new("marie_rc"); - pauline = linphone_core_manager_new("pauline_rc"); + pauline = linphone_core_manager_new("pauline_tcp_rc"); marie_params = configure_for_early_media_video_receiving_with_inactive_audio(marie); pauline_params = configure_for_early_media_video_sending(pauline); @@ -422,7 +431,7 @@ static void forked_outgoing_early_media_video_call_with_inactive_audio_test(void lcs = ms_list_append(lcs,marie2->lc); lcs = ms_list_append(lcs,pauline->lc); - pauline_params = linphone_core_create_default_call_parameters(pauline->lc); + pauline_params = linphone_core_create_call_params(pauline->lc, NULL); linphone_call_params_enable_early_media_sending(pauline_params, TRUE); linphone_call_params_enable_video(pauline_params, TRUE); marie1_params = configure_for_early_media_video_receiving_with_inactive_audio(marie1); @@ -431,27 +440,42 @@ static void forked_outgoing_early_media_video_call_with_inactive_audio_test(void linphone_core_invite_address_with_params(pauline->lc, marie1->identity, pauline_params); linphone_call_params_destroy(pauline_params); + BC_ASSERT_TRUE(wait_for_list(lcs, &marie1->stat.number_of_LinphoneCallIncomingReceived, 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(lcs, &marie2->stat.number_of_LinphoneCallIncomingReceived, 1, 3000)); + + marie1_call = linphone_core_get_current_call(marie1->lc); + marie2_call = linphone_core_get_current_call(marie2->lc); + + if (marie1_call){ + linphone_call_set_next_video_frame_decoded_callback(marie1_call, linphone_call_iframe_decoded_cb, marie1->lc); + } + if (marie2_call){ + linphone_call_set_next_video_frame_decoded_callback(marie2_call, linphone_call_iframe_decoded_cb, marie2->lc); + } + BC_ASSERT_TRUE(wait_for_list(lcs, &marie1->stat.number_of_LinphoneCallIncomingEarlyMedia, 1, 3000)); BC_ASSERT_TRUE(wait_for_list(lcs, &marie2->stat.number_of_LinphoneCallIncomingEarlyMedia, 1, 3000)); BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallOutgoingEarlyMedia, 1, 3000)); 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); BC_ASSERT_PTR_NOT_NULL(pauline_call); BC_ASSERT_PTR_NOT_NULL(marie1_call); BC_ASSERT_PTR_NOT_NULL(marie2_call); if (pauline_call && marie1_call && marie2_call) { + linphone_call_set_next_video_frame_decoded_callback(pauline_call, linphone_call_iframe_decoded_cb, pauline->lc); + /* wait a bit that streams are established */ - wait_for_list(lcs, &dummy, 1, 6000); - BC_ASSERT_TRUE(linphone_call_get_audio_stats(pauline_call)->download_bandwidth == 0); - BC_ASSERT_TRUE(linphone_call_get_audio_stats(marie1_call)->download_bandwidth == 0); - BC_ASSERT_TRUE(linphone_call_get_audio_stats(marie2_call)->download_bandwidth == 0); - BC_ASSERT_TRUE(linphone_call_get_video_stats(pauline_call)->download_bandwidth == 0); - BC_ASSERT_TRUE(linphone_call_get_video_stats(marie1_call)->download_bandwidth > 0); - BC_ASSERT_TRUE(linphone_call_get_video_stats(marie2_call)->download_bandwidth > 0); + wait_for_list(lcs, &dummy, 1, 3000); + BC_ASSERT_EQUAL(linphone_call_get_audio_stats(pauline_call)->download_bandwidth, 0, float, "%f"); + BC_ASSERT_EQUAL(linphone_call_get_audio_stats(marie1_call)->download_bandwidth, 0, float, "%f"); + BC_ASSERT_EQUAL(linphone_call_get_audio_stats(marie2_call)->download_bandwidth, 0, float, "%f"); + BC_ASSERT_LOWER(linphone_call_get_video_stats(pauline_call)->download_bandwidth, 11, float, "%f"); /* because of stun packets*/ + BC_ASSERT_GREATER(linphone_call_get_video_stats(marie1_call)->download_bandwidth, 0, float, "%f"); + BC_ASSERT_GREATER(linphone_call_get_video_stats(marie2_call)->download_bandwidth, 0, float, "%f"); + BC_ASSERT_GREATER(marie1->stat.number_of_IframeDecoded, 1, int, "%i"); + BC_ASSERT_GREATER(marie2->stat.number_of_IframeDecoded, 1, int, "%i"); linphone_call_params_set_audio_direction(marie1_params, LinphoneMediaDirectionSendRecv); linphone_core_accept_call_with_params(marie1->lc, linphone_core_get_current_call(marie1->lc), marie1_params); @@ -463,10 +487,11 @@ static void forked_outgoing_early_media_video_call_with_inactive_audio_test(void /*wait a bit that streams are established*/ wait_for_list(lcs, &dummy, 1, 3000); - BC_ASSERT_TRUE(linphone_call_get_audio_stats(pauline_call)->download_bandwidth > 71); - BC_ASSERT_TRUE(linphone_call_get_audio_stats(marie1_call)->download_bandwidth > 71); - BC_ASSERT_TRUE(linphone_call_get_video_stats(pauline_call)->download_bandwidth > 0); - BC_ASSERT_TRUE(linphone_call_get_video_stats(marie1_call)->download_bandwidth > 0); + BC_ASSERT_GREATER(linphone_call_get_audio_stats(pauline_call)->download_bandwidth, 71, float, "%f"); + BC_ASSERT_GREATER(linphone_call_get_audio_stats(marie1_call)->download_bandwidth, 71, float, "%f"); + BC_ASSERT_GREATER(linphone_call_get_video_stats(pauline_call)->download_bandwidth, 0, float, "%f"); + BC_ASSERT_GREATER(linphone_call_get_video_stats(marie1_call)->download_bandwidth, 0, float, "%f"); + BC_ASSERT_GREATER(pauline->stat.number_of_IframeDecoded, 1, int, "%i"); /* send an INFO in reverse side to check that dialogs are properly established */ info = linphone_core_create_info_message(marie1->lc); @@ -485,20 +510,58 @@ static void forked_outgoing_early_media_video_call_with_inactive_audio_test(void linphone_core_manager_destroy(marie2); linphone_core_manager_destroy(pauline); } +#endif /*HAVE_GTK*/ +static void enable_disable_camera_after_camera_switches(void) { + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + const char *currentCamId = (char*)linphone_core_get_video_device(marie->lc); + const char **cameras=linphone_core_get_video_devices(marie->lc); + const char *newCamId=NULL; + int i; + + + video_call_base_2(marie,pauline,FALSE,LinphoneMediaEncryptionNone,TRUE,TRUE); + + for (i=0;cameras[i]!=NULL;++i){ + if (strcmp(cameras[i],currentCamId)!=0){ + newCamId=cameras[i]; + break; + } + } + if (newCamId){ + LinphoneCall *call = linphone_core_get_current_call(marie->lc); + ms_message("Switching from [%s] to [%s]", currentCamId, newCamId); + linphone_core_set_video_device(marie->lc, newCamId); + if(call != NULL) { + linphone_core_update_call(marie->lc, call, NULL); + } + BC_ASSERT_STRING_EQUAL(newCamId,ms_web_cam_get_string_id(linphone_call_get_video_device(call))); + linphone_call_enable_camera(call,FALSE); + linphone_core_iterate(marie->lc); + linphone_call_enable_camera(call,TRUE); + BC_ASSERT_STRING_EQUAL(newCamId,ms_web_cam_get_string_id(linphone_call_get_video_device(call))); + } + + + linphone_core_terminate_all_calls(pauline->lc); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1)); + BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1)); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} test_t video_tests[] = { +#if HAVE_GTK { "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 }, { "Early-media video with inactive audio", early_media_video_with_inactive_audio }, - { "Forked outgoing early-media video call with inactive audio", forked_outgoing_early_media_video_call_with_inactive_audio_test } + { "Forked outgoing early-media video call with inactive audio", forked_outgoing_early_media_video_call_with_inactive_audio_test }, +#endif /*HAVE_GTK*/ + { "Enable/disable camera after camera switches", enable_disable_camera_after_camera_switches} + }; -test_suite_t video_test_suite = { - "Video", - NULL, - NULL, - sizeof(video_tests) / sizeof(video_tests[0]), - video_tests -}; +test_suite_t video_test_suite = {"Video", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each, + sizeof(video_tests) / sizeof(video_tests[0]), video_tests}; #endif /* VIDEO_ENABLED */ diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 6d383a4a7..104f2346c 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -43,6 +43,7 @@ set(LP_GEN_WRAPPERS_LIBS ${XML2_LIBRARIES} ) +apply_compile_flags(LP_GEN_WRAPPERS_SOURCE_FILES "CPP" "CXX") add_executable(lp-gen-wrappers ${LP_GEN_WRAPPERS_SOURCE_FILES}) target_link_libraries(lp-gen-wrappers ${LP_GEN_WRAPPERS_LIBS}) diff --git a/tools/Makefile.am b/tools/Makefile.am index ecd6cab5a..8a2c21436 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -19,7 +19,7 @@ EXTRA_DIST=xml2lpc_jni.cc lpc2xml_jni.cc if BUILD_TOOLS -bin_PROGRAMS=xml2lpc_test lpc2xml_test lp-gen-wrappers lp-autoanswer +bin_PROGRAMS=xml2lpc_test lpc2xml_test lp-gen-wrappers lp-autoanswer lp-test-ecc xml2lpc_test_SOURCES=\ xml2lpc_test.c @@ -48,6 +48,26 @@ lp_autoanswer_LDADD=\ $(top_builddir)/coreapi/liblinphone.la \ $(MEDIASTREAMER_LIBS) +lp_test_ecc_SOURCES=test_ecc.c +lp_test_ecc_CFLAGS=$(COMMON_CFLAGS) +lp_test_ecc_LDADD=$(top_builddir)/coreapi/liblinphone.la + endif + +if ENABLE_TESTS + +noinst_PROGRAMS=test_lsd test_numbers + +test_lsd_SOURCES=test_lsd.c +test_lsd_CFLAGS=$(COMMON_CFLAGS) +test_lsd_LDADD=$(top_builddir)/coreapi/liblinphone.la + + + +test_numbers_SOURCES=test_numbers.c +test_numbers_CFLAGS=$(COMMON_CFLAGS) +test_numbers_LDADD=$(top_builddir)/coreapi/liblinphone.la + +endif diff --git a/tools/auto_answer.c b/tools/auto_answer.c index 3e7f64b80..8cedc9bc0 100644 --- a/tools/auto_answer.c +++ b/tools/auto_answer.c @@ -30,11 +30,21 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include static bool_t running=TRUE; +static bool_t print_stats=FALSE; +static bool_t dump_stats=FALSE; static void stop(int signum){ running=FALSE; } +#ifndef WIN32 +static void stats(int signum){ + print_stats=TRUE; +} +static void dump_call_logs(int signum){ + dump_stats=TRUE; +} +#endif #ifndef PACKAGE_DATA_DIR #define PACKAGE_DATA_DIR '.' #endif @@ -45,25 +55,26 @@ static void call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCal LinphoneCallParams * call_params; switch(cstate){ case LinphoneCallIncomingReceived: - ms_message("Incoming call arrive !\n"); + ms_message("Incoming call arriving !\n"); /* accept the incoming call*/ - call_params = linphone_core_create_default_call_parameters(lc); + call_params = linphone_core_create_call_params(lc, call); linphone_call_params_enable_video(call_params,TRUE); linphone_call_params_set_audio_direction(call_params,LinphoneMediaDirectionSendOnly); linphone_call_params_set_video_direction(call_params,LinphoneMediaDirectionSendOnly); linphone_core_accept_call_with_params(lc,call,call_params); linphone_call_params_destroy(call_params); - break; default: break; } } extern MSWebCamDesc mire_desc; -static void helper() { - printf("auto_answer --help\n" +static void helper(const char *progname) { + printf("%s --help\n" "\t\t\t--listening-uri uri to listen on, default [sip:localhost:5060]\n" - "\t\t\t--verbose\n"); + "\t\t\t--max-call-duration max duration of a call in seconds, default [3600]\n" + "\t\t\t--media-file \n" + "\t\t\t--verbose\n", progname); exit(0); } @@ -76,16 +87,25 @@ int main(int argc, char *argv[]){ LCSipTransports tp; char * tmp = NULL; LpConfig * lp_config = lp_config_new(NULL); + int max_call_duration=3600; + static const char *media_file = NULL; + policy.automatically_accept=TRUE; signal(SIGINT,stop); +#ifndef WIN32 + signal(SIGUSR1,stats); + signal(SIGUSR2,dump_call_logs); +#endif for(i = 1; i < argc; ++i) { if (strcmp(argv[i], "--verbose") == 0) { linphone_core_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL); + } else if (strcmp(argv[i], "--max-call-duration") == 0){ + max_call_duration = atoi(argv[++i]); } else if (strcmp(argv[i], "--listening-uri") == 0){ addr = linphone_address_new(argv[++i]); if (!addr) { printf("Error, bad sip uri"); - helper(); + helper(argv[0]); } /* switch(linphone_address_get_transport(addr)) { case LinphoneTransportUdp: @@ -96,8 +116,13 @@ int main(int argc, char *argv[]){ helper(); break; }*/ + } else if (strcmp(argv[i], "--media-file") == 0){ + i++; + if (inext) { + LinphoneCallLog *call_log=(LinphoneCallLog *)iterator->data; + char * tmp_str = linphone_call_log_to_str(call_log); + ms_message("\n%s",tmp_str); + ms_free(tmp_str); + } + dump_stats=FALSE; + ms_message("*********************************"); + } + for (iterator=linphone_core_get_calls(lc);iterator!=NULL;iterator=iterator->next) { + LinphoneCall *call=(LinphoneCall *)iterator->data; + if (linphone_call_get_duration(call) > max_call_duration) { + ms_message("Terminating call [%p] after [%i] s",call,linphone_call_get_duration(call)); + linphone_core_terminate_call(lc,call); + break; + } + } + } ms_message("Shutting down...\n"); diff --git a/tools/lpc2xml_test.c b/tools/lpc2xml_test.c index 03ac571cf..b52ecbb51 100644 --- a/tools/lpc2xml_test.c +++ b/tools/lpc2xml_test.c @@ -42,28 +42,30 @@ void cb_function(void *ctx, lpc2xml_log_level level, const char *msg, va_list li } void show_usage(int argc, char *argv[]) { - fprintf(stderr, "usage %s convert \n", - argv[0]); + fprintf(stderr, "usage:\n%s convert \n%s dump \n", argv[0], argv[0]); } int main(int argc, char *argv[]) { lpc2xml_context *ctx; LpConfig *lpc; - if(argc != 4) { + if(argc > 4 || argc < 3) { show_usage(argc, argv); return -1; } - ctx = lpc2xml_context_new(cb_function, NULL); lpc = lp_config_new(argv[2]); - lpc2xml_set_lpc(ctx, lpc); - if(strcmp("convert", argv[1]) == 0) { + if(strcmp("convert", argv[1]) == 0 && argc == 4) { + ctx = lpc2xml_context_new(cb_function, NULL); lpc2xml_convert_file(ctx, argv[3]); + lpc2xml_set_lpc(ctx, lpc); + lpc2xml_context_destroy(ctx); + } else if (strcmp("dump", argv[1]) == 0 && argc == 3) { + char *dump = lp_config_dump_as_xml(lpc); + fprintf(stdout, "%s", dump); } else { show_usage(argc, argv); } lp_config_destroy(lpc); - lpc2xml_context_destroy(ctx); return 0; } diff --git a/tools/python/apixml2python.py b/tools/python/apixml2python.py index a073e8141..94e4c0a48 100755 --- a/tools/python/apixml2python.py +++ b/tools/python/apixml2python.py @@ -65,6 +65,7 @@ blacklisted_functions = [ 'linphone_proxy_config_set_file_transfer_server', # defined but not implemented in linphone core 'linphone_proxy_config_set_privacy', # missing LinphonePrivacyMask 'linphone_tunnel_get_http_proxy', # to be handwritten because of double pointer indirection + 'linphone_xml_rpc_request_new_with_args', # to be handwritten because of va_list 'lp_config_for_each_entry', # to be handwritten because of callback 'lp_config_for_each_section', # to be handwritten because of callback 'lp_config_get_range', # to be handwritten because of result via arguments @@ -75,10 +76,14 @@ hand_written_functions = [ HandWrittenClassMethod('Buffer', 'new_from_data', 'linphone_buffer_new_from_data', "Create a new LinphoneBuffer object from existing data.\n\n:param data: The initial data to store in the LinphoneBuffer.\n:type data: ByteArray\n:returns: A new LinphoneBuffer object.\n:rtype: linphone.Buffer"), HandWrittenProperty('Buffer', 'content', 'linphone_buffer_get_content', 'linphone_buffer_set_content', "[ByteArray] Set the content of the data buffer."), HandWrittenProperty('Content', 'buffer', 'linphone_content_get_buffer', 'linphone_content_set_buffer', "[ByteArray] Set the content data buffer."), + HandWrittenProperty('Call', 'native_video_window_id', 'linphone_call_get_native_video_window_id', 'linphone_call_set_native_video_window_id', "[int] Set the native video window id where the video is to be displayed."), + HandWrittenProperty('Core', 'native_preview_window_id', 'linphone_core_get_native_preview_window_id', 'linphone_core_set_native_preview_window_id', "[int] Set the native window id where the preview video (local camera) is to be displayed. This has to be used in conjonction with :py:meth:`linphone.Core.use_preview_window` . MacOS, Linux, Windows: if not set or zero the core will create its own window, unless the special id -1 is given."), + HandWrittenProperty('Core', 'native_video_window_id', 'linphone_core_get_native_video_window_id', 'linphone_core_set_native_video_window_id', "[int] Set the native video window id where the video is to be displayed. For MacOS, Linux, Windows: if not set or LINPHONE_VIDEO_DISPLAY_AUTO the core will create its own window, unless the special id LINPHONE_VIDEO_DISPLAY_NONE is given."), HandWrittenProperty('Core', 'sip_transports', 'linphone_core_get_sip_transports', 'linphone_core_set_sip_transports', "[:py:class:`linphone.SipTransports`] Sets the ports to be used for each transport. A zero value port for a given transport means the transport is not used. A value of LC_SIP_TRANSPORT_RANDOM (-1) means the port is to be chosen randomly by the system."), HandWrittenProperty('Core', 'sip_transports_used', 'linphone_core_get_sip_transports_used', None, "[:py:class:`linphone.SipTransports`] Retrieves the real port number assigned for each sip transport (udp, tcp, tls). A zero value means that the transport is not activated. If LC_SIP_TRANSPORT_RANDOM was passed to :py:attr:`linphone.Core.sip_transports`, the random port choosed by the system is returned."), HandWrittenProperty('Core', 'sound_devices', 'linphone_core_get_sound_devices', None, "[list of string] Get the available sound devices."), HandWrittenProperty('Core', 'video_devices', 'linphone_core_get_video_devices', None, "[list of string] Get the available video capture devices."), + HandWrittenProperty('LpConfig', 'sections_names', 'lp_config_get_sections_names', None, "[list of string] Get the sections' names in the lp config."), HandWrittenClassMethod('Core', 'new', 'linphone_core_new', "Instantiate a LinphoneCore object.\n\n:param vtable: The callbacks.\n:type vtable: dictionary\n:param configPath: A path to a config file. If it does not exists it will be created. The config file is used to store all settings, call logs, friends, proxies... so that all these settings become persistent over the life of the LinphoneCore object. It is allowed to set to None. In that case LinphoneCore will not store any settings.\n:type configPath: string\n:param factoryConfigPath: A path to a read-only config file that can be used to store hard-coded preference such as proxy settings or internal preferences. The settings in this factory file always override the one in the normal config file. It is OPTIONAL, use None if unneeded.\n:type factoryConfigPath: string\n:rtype: linphone.Core"), HandWrittenClassMethod('Core', 'new_with_config', 'linphone_core_new_with_config', "Instantiate a LinphoneCore object from a LpConfig.\n\n:param vtable: The callbacks.\n:type vtable: dictionary\n:param config: A LpConfig object holding the configuration of the LinphoneCore to be instantiated.\n:rtype: linphone.Core"), HandWrittenDeallocMethod('Core', 'linphone_core_destroy') diff --git a/tools/python/apixml2python/handwritten_declarations.mustache b/tools/python/apixml2python/handwritten_declarations.mustache index 4a4b2c1ef..534efc981 100644 --- a/tools/python/apixml2python/handwritten_declarations.mustache +++ b/tools/python/apixml2python/handwritten_declarations.mustache @@ -1,3 +1,9 @@ +static PyObject * pylinphone_Call_get_native_video_window_id(PyObject *self, void *closure); +static int pylinphone_Call_set_native_video_window_id(PyObject *self, PyObject *value, void *closure); +static PyObject * pylinphone_Core_get_native_preview_window_id(PyObject *self, void *closure); +static int pylinphone_Core_set_native_preview_window_id(PyObject *self, PyObject *value, void *closure); +static PyObject * pylinphone_Core_get_native_video_window_id(PyObject *self, void *closure); +static int pylinphone_Core_set_native_video_window_id(PyObject *self, PyObject *value, void *closure); static PyObject * pylinphone_Core_get_sip_transports(PyObject *self, void *closure); static int pylinphone_Core_set_sip_transports(PyObject *self, PyObject *value, void *closure); static void pylinphone_Core_dealloc(PyObject *self); @@ -34,3 +40,5 @@ static int pylinphone_Buffer_set_content(PyObject *self, PyObject *value, void * static PyObject * pylinphone_Content_get_buffer(PyObject *self, void *closure); static int pylinphone_Content_set_buffer(PyObject *self, PyObject *value, void *closure); + +static PyObject * pylinphone_LpConfig_get_sections_names(PyObject *self, void *closure); \ No newline at end of file diff --git a/tools/python/apixml2python/handwritten_definitions.mustache b/tools/python/apixml2python/handwritten_definitions.mustache index e9edec0fb..5c8db7305 100644 --- a/tools/python/apixml2python/handwritten_definitions.mustache +++ b/tools/python/apixml2python/handwritten_definitions.mustache @@ -128,6 +128,152 @@ static PyObject * pylinphone_module_method_set_log_handler(PyObject *self, PyObj } +static PyObject * pylinphone_Call_get_native_video_window_id(PyObject *self, void *closure) { + void * cresult; + PyObject * pyresult; + PyObject * pyret; + const LinphoneCall *native_ptr; + native_ptr = pylinphone_Call_get_native_ptr(self); + if (native_ptr == NULL) { + PyErr_SetString(PyExc_TypeError, "Invalid linphone.Call instance"); + return NULL; + } + + pylinphone_trace(1, "[PYLINPHONE] >>> %s(%p [%p])", __FUNCTION__, self, native_ptr); + cresult = linphone_call_get_native_video_window_id(native_ptr); + pylinphone_dispatch_messages(); + + pyret = Py_BuildValue("k", (unsigned long)cresult); + + pylinphone_trace(-1, "[PYLINPHONE] <<< %s -> %p", __FUNCTION__, pyret); + return pyret; +} + +static int pylinphone_Call_set_native_video_window_id(PyObject *self, PyObject *value, void *closure) { + LinphoneCall *native_ptr; + unsigned long _id; + native_ptr = pylinphone_Call_get_native_ptr(self); + if (native_ptr == NULL) { + PyErr_SetString(PyExc_TypeError, "Invalid linphone.Call instance"); + return -1; + } + + if (value == NULL) { + PyErr_SetString(PyExc_TypeError, "Cannot delete the 'native_video_window_id' attribute."); + return -1; + } + if (!PyInt_Check(value)) { + PyErr_SetString(PyExc_TypeError, "The 'native_video_window_id' attribute value must be a unsigned int."); + return -1; + } + + _id = (unsigned long)PyInt_AsUnsignedLongMask(value); + + pylinphone_trace(1, "[PYLINPHONE] >>> %s(%p [%p], %u)", __FUNCTION__, self, native_ptr, _id); + linphone_call_set_native_video_window_id(native_ptr, (void *)_id); + pylinphone_dispatch_messages(); + pylinphone_trace(-1, "[PYLINPHONE] <<< %s -> 0", __FUNCTION__); + return 0; +} + + +static PyObject * pylinphone_Core_get_native_preview_window_id(PyObject *self, void *closure) { + void * cresult; + PyObject * pyresult; + PyObject * pyret; + const LinphoneCore *native_ptr; + native_ptr = pylinphone_Core_get_native_ptr(self); + if (native_ptr == NULL) { + PyErr_SetString(PyExc_TypeError, "Invalid linphone.Core instance"); + return NULL; + } + + pylinphone_trace(1, "[PYLINPHONE] >>> %s(%p [%p])", __FUNCTION__, self, native_ptr); + cresult = linphone_core_get_native_preview_window_id(native_ptr); + pylinphone_dispatch_messages(); + + pyret = Py_BuildValue("k", (unsigned long)cresult); + + pylinphone_trace(-1, "[PYLINPHONE] <<< %s -> %p", __FUNCTION__, pyret); + return pyret; +} + +static int pylinphone_Core_set_native_preview_window_id(PyObject *self, PyObject *value, void *closure) { + LinphoneCore *native_ptr; + unsigned long _id; + native_ptr = pylinphone_Core_get_native_ptr(self); + if (native_ptr == NULL) { + PyErr_SetString(PyExc_TypeError, "Invalid linphone.Core instance"); + return -1; + } + + if (value == NULL) { + PyErr_SetString(PyExc_TypeError, "Cannot delete the 'native_preview_window_id' attribute."); + return -1; + } + if (!PyInt_Check(value)) { + PyErr_SetString(PyExc_TypeError, "The 'native_preview_window_id' attribute value must be a unsigned int."); + return -1; + } + + _id = (unsigned long)PyInt_AsUnsignedLongMask(value); + + pylinphone_trace(1, "[PYLINPHONE] >>> %s(%p [%p], %u)", __FUNCTION__, self, native_ptr, _id); + linphone_core_set_native_preview_window_id(native_ptr, (void *)_id); + pylinphone_dispatch_messages(); + pylinphone_trace(-1, "[PYLINPHONE] <<< %s -> 0", __FUNCTION__); + return 0; +} + + +static PyObject * pylinphone_Core_get_native_video_window_id(PyObject *self, void *closure) { + void * cresult; + PyObject * pyresult; + PyObject * pyret; + const LinphoneCore *native_ptr; + native_ptr = pylinphone_Core_get_native_ptr(self); + if (native_ptr == NULL) { + PyErr_SetString(PyExc_TypeError, "Invalid linphone.Core instance"); + return NULL; + } + + pylinphone_trace(1, "[PYLINPHONE] >>> %s(%p [%p])", __FUNCTION__, self, native_ptr); + cresult = linphone_core_get_native_video_window_id(native_ptr); + pylinphone_dispatch_messages(); + + pyret = Py_BuildValue("k", (unsigned long)cresult); + + pylinphone_trace(-1, "[PYLINPHONE] <<< %s -> %p", __FUNCTION__, pyret); + return pyret; +} + +static int pylinphone_Core_set_native_video_window_id(PyObject *self, PyObject *value, void *closure) { + LinphoneCore *native_ptr; + unsigned long _id; + native_ptr = pylinphone_Core_get_native_ptr(self); + if (native_ptr == NULL) { + PyErr_SetString(PyExc_TypeError, "Invalid linphone.Core instance"); + return -1; + } + + if (value == NULL) { + PyErr_SetString(PyExc_TypeError, "Cannot delete the 'native_video_window_id' attribute."); + return -1; + } + if (!PyInt_Check(value)) { + PyErr_SetString(PyExc_TypeError, "The 'native_video_window_id' attribute value must be a unsigned int."); + return -1; + } + + _id = (unsigned long)PyInt_AsUnsignedLongMask(value); + + pylinphone_trace(1, "[PYLINPHONE] >>> %s(%p [%p], %u)", __FUNCTION__, self, native_ptr, _id); + linphone_core_set_native_video_window_id(native_ptr, (void *)_id); + pylinphone_dispatch_messages(); + pylinphone_trace(-1, "[PYLINPHONE] <<< %s -> 0", __FUNCTION__); + return 0; +} + static PyObject * pylinphone_Core_get_sip_transports(PyObject *self, void *closure) { PyObject *pytr; LCSipTransports tr = { 0 }; @@ -824,3 +970,28 @@ static int pylinphone_Content_set_buffer(PyObject *self, PyObject *value, void * pylinphone_trace(-1, "[PYLINPHONE] <<< %s -> 0", __FUNCTION__); return 0; } + +static PyObject * pylinphone_LpConfig_get_sections_names(PyObject *self, void *closure) { + PyObject *_list; + const char **_names; + LpConfig *native_ptr = pylinphone_LpConfig_get_native_ptr(self); + + if (native_ptr == NULL) { + PyErr_SetString(PyExc_TypeError, "Invalid linphone.LpConfig instance"); + return NULL; + } + + pylinphone_trace(1, "[PYLINPHONE] >>> %s(%p [%p])", __FUNCTION__, self, native_ptr); + _names = lp_config_get_sections_names(native_ptr); + pylinphone_dispatch_messages(); + + _list = PyList_New(0); + while (*_names != NULL) { + PyObject *_item = PyString_FromString(*_names); + PyList_Append(_list, _item); + _names++; + } + + pylinphone_trace(-1, "[PYLINPHONE] <<< %s -> %p", __FUNCTION__, _list); + return _list; +} diff --git a/tools/python/doc/source/conf.py b/tools/python/doc/source/conf.py index c01ba688d..f3ecde103 100644 --- a/tools/python/doc/source/conf.py +++ b/tools/python/doc/source/conf.py @@ -53,9 +53,9 @@ copyright = u'2014, Belledonne Communications' # built documents. # # The short X.Y version. -version = '3.8' +version = '3.9' # The full version, including alpha/beta/rc tags. -release = '3.8.2' +release = '3.9.1' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/tools/python/unittests/linphonetester.py b/tools/python/unittests/linphonetester.py index 366f22a82..dfeeea9d4 100644 --- a/tools/python/unittests/linphonetester.py +++ b/tools/python/unittests/linphonetester.py @@ -105,15 +105,14 @@ class AccountManager: def check_account(self, cfg): create_account = False lc = cfg.core - identity = cfg.identity - id_addr = linphone.Address.new(identity) + id_addr = cfg.identity_address account = self._get_account(id_addr) if account is None: - linphonetester_logger.info("[TESTER] No account for {identity} exists, going to create one.".format(identity=identity)) + linphonetester_logger.info("[TESTER] No account for {identity} exists, going to create one.".format(identity=id_addr.as_string())) account = Account(id_addr, self.unique_id) self.accounts.append(account) create_account = True - cfg.identity = account.modified_identity.as_string() + cfg.identity_address = account.modified_identity if create_account: self._create_account_on_server(account, cfg) ai = linphone.AuthInfo.new(account.modified_identity.username, None, account.password, None, None, account.modified_identity.domain) @@ -136,7 +135,7 @@ class AccountManager: cfg = lc.create_proxy_config() tmp_identity.password = account.password tmp_identity.set_header("X-Create-Account", "yes") - cfg.identity = tmp_identity.as_string() + cfg.identity_address = tmp_identity server_addr = linphone.Address.new(refcfg.server_addr) server_addr.transport = linphone.TransportType.Tcp; server_addr.port = 0 @@ -144,15 +143,15 @@ class AccountManager: cfg.expires = 3600 lc.add_proxy_config(cfg) if AccountManager.wait_for_until(lc, None, lambda lc: lc.user_data().auth_requested == True, 10000) != True: - linphonetester_logger.critical("[TESTER] Account for {identity} could not be created on server.".format(identity=refcfg.identity)) + linphonetester_logger.critical("[TESTER] Account for {identity} could not be created on server.".format(identity=refcfg.identity_address.as_string())) sys.exit(-1) cfg.edit() - cfg.identity = account.modified_identity.as_string() + cfg.identity_address = account.modified_identity cfg.done() ai = linphone.AuthInfo.new(account.modified_identity.username, None, account.password, None, None, account.modified_identity.domain) lc.add_auth_info(ai) if AccountManager.wait_for_until(lc, None, lambda lc: lc.user_data().created == True, 3000) != True: - linphonetester_logger.critical("[TESTER] Account for {identity} is not working on server.".format(identity=refcfg.identity)) + linphonetester_logger.critical("[TESTER] Account for {identity} is not working on server.".format(identity=refcfg.identity_address.as_string())) sys.exit(-1) lc.remove_proxy_config(cfg) if AccountManager.wait_for_until(lc, None, lambda lc: lc.user_data().done == True, 3000) != True: @@ -211,6 +210,7 @@ class CoreManagerStats: self.number_of_LinphoneMessageNotDelivered = 0 self.number_of_LinphoneIsComposingActiveReceived = 0 self.number_of_LinphoneIsComposingIdleReceived = 0 + self.number_of_LinphoneFileTransferDownloadSuccessful = 0 self.progress_of_LinphoneFileTransfer = 0 self.number_of_IframeDecoded = 0 @@ -392,7 +392,7 @@ class CoreManager: def registration_state_changed(cls, lc, cfg, state, message): manager = lc.user_data() linphonetester_logger.info("[TESTER] New registration state {state} for user id [{identity}] at proxy [{addr}]".format( - state=linphone.RegistrationState.string(state), identity=cfg.identity, addr=cfg.server_addr)) + state=linphone.RegistrationState.string(state), identity=cfg.identity_address.as_string(), addr=cfg.server_addr)) if state == linphone.RegistrationState.None: manager.stats.number_of_LinphoneRegistrationNone += 1 elif state == linphone.RegistrationState.Progress: @@ -598,8 +598,7 @@ class CoreManager: self.enable_audio_codec("PCMU", 8000) if self.lc.default_proxy_config is not None: - self.identity = linphone.Address.new(self.lc.default_proxy_config.identity) - self.identity.clean() + self.lc.default_proxy_config.identity_address.clean() def enable_audio_codec(self, mime, rate): codecs = self.lc.audio_codecs diff --git a/tools/python/unittests/test_message.py b/tools/python/unittests/test_message.py index 12495cc84..653b3e747 100644 --- a/tools/python/unittests/test_message.py +++ b/tools/python/unittests/test_message.py @@ -59,29 +59,25 @@ class TestMessage: receive_filepath = msg.user_data stats = msg.chat_room.core.user_data().stats if buf.empty: # Transfer complete - stats.number_of_LinphoneMessageExtBodyReceived += 1 + stats.number_of_LinphoneFileTransferDownloadSuccessful += 1 else: # Store content f = open(receive_filepath, 'ab') f.write(buf.content) f.close() - @classmethod - def memory_file_transfer_send(cls, msg, content, offset, size): - send_buf = msg.user_data - send_size = len(send_buf) - if offset >= send_size: - return linphone.Buffer.new() - if (send_size - offset) < size: - size = send_size - offset - return linphone.Buffer.new_from_string(send_buf[offset:offset+size]) - - @classmethod - def memory_file_transfer_recv(cls, msg, content, buf): - stats = msg.chat_room.core.user_data().stats - if buf.empty: # Transfer complete - stats.number_of_LinphoneMessageExtBodyReceived += 1 - else: # Store content - msg.user_data += buf.string_content + def create_message_from_no_webcam(self, chat_room): + send_filepath = os.path.join(tester_resources_path, 'images', 'nowebcamCIF.jpg') + content = chat_room.core.create_content() + content.type = 'image' + content.subtype = 'jpeg' + content.size = os.path.getsize(send_filepath) # total size to be transfered + content.name = 'nowebcamCIF.jpg' + message = chat_room.create_file_transfer_message(content) + message.callbacks.msg_state_changed = TestMessage.msg_state_changed + message.callbacks.file_transfer_send = TestMessage.file_transfer_send + message.callbacks.file_transfer_progress_indication = TestMessage.file_transfer_progress_indication + message.user_data = send_filepath + return message def wait_for_server_to_purge_messages(self, manager1, manager2): # Wait a little bit just to have time to purge message stored in the server @@ -91,122 +87,68 @@ class TestMessage: def test_text_message(self): marie = CoreManager('marie_rc') - pauline = CoreManager('pauline_rc') + pauline = CoreManager('pauline_tcp_rc') chat_room = pauline.lc.get_chat_room(marie.identity) self.wait_for_server_to_purge_messages(marie, pauline) - msg = chat_room.create_message("Bla bla bla bla") + msg = chat_room.create_message("hello") + msg.callbacks.msg_state_changed = TestMessage.msg_state_changed chat_room.send_chat_message(msg) assert_equals(CoreManager.wait_for(pauline, marie, lambda pauline, marie: marie.stats.number_of_LinphoneMessageReceived == 1), True) + assert_equals(CoreManager.wait_for(pauline, marie, lambda pauline, marie: pauline.stats.number_of_LinphoneMessageDelivered == 1), True) assert marie.lc.get_chat_room(pauline.identity) is not None - def test_text_message_within_dialog(self): + def test_text_message_within_call_dialog(self): marie = CoreManager('marie_rc') - pauline = CoreManager('pauline_rc') + pauline = CoreManager('pauline_tcp_rc') pauline.lc.config.set_int('sip', 'chat_use_call_dialogs', 1) - chat_room = pauline.lc.get_chat_room(marie.identity) self.wait_for_server_to_purge_messages(marie, pauline) assert_equals(CoreManager.call(marie, pauline), True) + chat_room = pauline.lc.get_chat_room(marie.identity) msg = chat_room.create_message("Bla bla bla bla") + msg.callbacks.msg_state_changed = TestMessage.msg_state_changed chat_room.send_chat_message(msg) assert_equals(CoreManager.wait_for(pauline, marie, lambda pauline, marie: marie.stats.number_of_LinphoneMessageReceived == 1), True) + # When using call dialogs, we will never receive delivered status + assert_equals(pauline.stats.number_of_LinphoneMessageDelivered, 0) assert marie.lc.get_chat_room(pauline.identity) is not None + CoreManager.end_call(marie, pauline) - def test_file_transfer_message(self): + def test_transfer_message(self): marie = CoreManager('marie_rc') - pauline = CoreManager('pauline_rc') + pauline = CoreManager('pauline_tcp_rc') send_filepath = os.path.join(tester_resources_path, 'images', 'nowebcamCIF.jpg') receive_filepath = 'receive_file.dump' pauline.lc.file_transfer_server = "https://www.linphone.org:444/lft.php" - chat_room = pauline.lc.get_chat_room(marie.identity) - content = pauline.lc.create_content() - content.type = 'image' - content.subtype = 'jpeg' - content.size = os.path.getsize(send_filepath) # total size to be transfered - content.name = 'nowebcamCIF.jpg' - message = chat_room.create_file_transfer_message(content) - message.user_data = send_filepath self.wait_for_server_to_purge_messages(marie, pauline) - message.callbacks.msg_state_changed = TestMessage.msg_state_changed - message.callbacks.file_transfer_send = TestMessage.file_transfer_send + chat_room = pauline.lc.get_chat_room(marie.identity) + message = self.create_message_from_no_webcam(chat_room) chat_room.send_chat_message(message) assert_equals(CoreManager.wait_for(pauline, marie, lambda pauline, marie: marie.stats.number_of_LinphoneMessageReceivedWithFile == 1), True) if marie.stats.last_received_chat_message is not None: cbs = marie.stats.last_received_chat_message.callbacks cbs.msg_state_changed = TestMessage.msg_state_changed cbs.file_transfer_recv = TestMessage.file_transfer_recv + cbs.file_transfer_progress_indication = TestMessage.file_transfer_progress_indication marie.stats.last_received_chat_message.user_data = receive_filepath marie.stats.last_received_chat_message.download_file() - assert_equals(CoreManager.wait_for(pauline, marie, lambda pauline, marie: marie.stats.number_of_LinphoneMessageExtBodyReceived == 1), True) - assert_equals(pauline.stats.number_of_LinphoneMessageInProgress, 1) - assert_equals(pauline.stats.number_of_LinphoneMessageDelivered, 1) - assert_equals(marie.stats.number_of_LinphoneMessageExtBodyReceived, 1) + assert_equals(CoreManager.wait_for(pauline, marie, lambda pauline, marie: marie.stats.number_of_LinphoneFileTransferDownloadSuccessful == 1), True) + assert_equals(pauline.stats.number_of_LinphoneMessageInProgress, 2) + assert_equals(CoreManager.wait_for(pauline, marie, lambda pauline, marie: pauline.stats.number_of_LinphoneMessageDelivered == 1), True) assert_equals(filecmp.cmp(send_filepath, receive_filepath, shallow=False), True) if os.path.exists(receive_filepath): os.remove(receive_filepath) - def test_small_file_transfer_message(self): - send_buf = "small file" + def test_transfer_message_upload_cancelled(self): marie = CoreManager('marie_rc') - pauline = CoreManager('pauline_rc') - while len(send_buf) < 160: - send_buf += send_buf - l = list(send_buf[0:160]) - l[0] = 'S' - l[-1] = 'E' - send_buf = ''.join(l) + pauline = CoreManager('pauline_tcp_rc') pauline.lc.file_transfer_server = "https://www.linphone.org:444/lft.php" - chat_room = pauline.lc.get_chat_room(marie.identity) - content = pauline.lc.create_content() - content.type = 'text' - content.subtype = 'plain' - content.size = len(send_buf) # total size to be transfered - content.name = 'small_file.txt' - message = chat_room.create_file_transfer_message(content) - message.user_data = send_buf self.wait_for_server_to_purge_messages(marie, pauline) - message.callbacks.msg_state_changed = TestMessage.msg_state_changed - message.callbacks.file_transfer_send = TestMessage.memory_file_transfer_send - chat_room.send_chat_message(message) - assert_equals(CoreManager.wait_for(pauline, marie, lambda pauline, marie: marie.stats.number_of_LinphoneMessageReceivedWithFile == 1), True) - if marie.stats.last_received_chat_message is not None: - cbs = marie.stats.last_received_chat_message.callbacks - cbs.msg_state_changed = TestMessage.msg_state_changed - cbs.file_transfer_recv = TestMessage.memory_file_transfer_recv - marie.stats.last_received_chat_message.user_data = '' - marie.stats.last_received_chat_message.download_file() - assert_equals(CoreManager.wait_for(pauline, marie, lambda pauline, marie: marie.stats.number_of_LinphoneMessageExtBodyReceived == 1), True) - assert_equals(pauline.stats.number_of_LinphoneMessageInProgress, 1) - assert_equals(pauline.stats.number_of_LinphoneMessageDelivered, 1) - assert_equals(marie.stats.number_of_LinphoneMessageExtBodyReceived, 1) - assert_equals(send_buf, marie.stats.last_received_chat_message.user_data) - - def test_file_transfer_message_upload_cancelled(self): - send_buf = "big file" - marie = CoreManager('marie_rc') - pauline = CoreManager('pauline_rc') - while len(send_buf) < 128000: - send_buf += send_buf - l = list(send_buf[0:128000]) - l[0] = 'S' - l[-1] = 'E' - send_buf = ''.join(l) - pauline.lc.file_transfer_server = "https://www.linphone.org:444/lft.php" chat_room = pauline.lc.get_chat_room(marie.identity) - content = pauline.lc.create_content() - content.type = 'text' - content.subtype = 'plain' - content.size = len(send_buf) # total size to be transfered - content.name = 'big_file.txt' - message = chat_room.create_file_transfer_message(content) - message.user_data = send_buf - self.wait_for_server_to_purge_messages(marie, pauline) - message.callbacks.msg_state_changed = TestMessage.msg_state_changed - message.callbacks.file_transfer_send = TestMessage.memory_file_transfer_send - message.callbacks.file_transfer_progress_indication = TestMessage.file_transfer_progress_indication + message = self.create_message_from_no_webcam(chat_room) chat_room.send_chat_message(message) # Wait for file to be at least 50% uploaded and cancel the transfer assert_equals(CoreManager.wait_for(pauline, marie, lambda pauline, marie: pauline.stats.progress_of_LinphoneFileTransfer >= 50), True) message.cancel_file_transfer() assert_equals(CoreManager.wait_for(pauline, marie, lambda pauline, marie: pauline.stats.number_of_LinphoneMessageNotDelivered == 1), True) assert_equals(pauline.stats.number_of_LinphoneMessageNotDelivered, 1) - assert_equals(marie.stats.number_of_LinphoneMessageExtBodyReceived, 0) + assert_equals(marie.stats.number_of_LinphoneFileTransferDownloadSuccessful, 0) diff --git a/tools/python/unittests/test_register.py b/tools/python/unittests/test_register.py index 0ce9bdf2f..a136c8a79 100644 --- a/tools/python/unittests/test_register.py +++ b/tools/python/unittests/test_register.py @@ -24,7 +24,7 @@ class RegisterCoreManager(CoreManager): self.lc.sip_transports = transport proxy_cfg = self.lc.create_proxy_config() from_address = create_address(domain) - proxy_cfg.identity = from_address.as_string() + proxy_cfg.identity_address = from_address server_addr = from_address.domain proxy_cfg.register_enabled = True proxy_cfg.expires = 1 diff --git a/tools/python/unittests/test_setup.py b/tools/python/unittests/test_setup.py index 9fcafa8b8..43fbf0042 100644 --- a/tools/python/unittests/test_setup.py +++ b/tools/python/unittests/test_setup.py @@ -5,9 +5,6 @@ import os class TestSetup: - def test_address(self): - create_address(None) - def test_version(self): lc = linphone.Core.new({}, None, None) assert_equals(lc.version.find("unknown"), -1) @@ -38,16 +35,6 @@ class TestSetup: assert_equals(lc.config.get_int('sip', 'sip_tcp_port', -2), -1) assert_equals(lc.config.get_int('sip', 'sip_tls_port', -2), -1) - def test_interpret_url(self): - lc = linphone.Core.new({}, None, None) - assert lc is not None - sips_address = "sips:margaux@sip.linphone.org" - address = lc.interpret_url(sips_address) - assert address is not None - assert_equals(address.scheme, "sips") - assert_equals(address.username, "margaux") - assert_equals(address.domain, "sip.linphone.org") - def test_lpconfig_from_buffer(self): buffer = "[buffer]\ntest=ok" buffer_linebreaks = "[buffer_linebreaks]\n\n\n\r\n\n\r\ntest=ok" diff --git a/coreapi/test_ecc.c b/tools/test_ecc.c similarity index 61% rename from coreapi/test_ecc.c rename to tools/test_ecc.c index 8d383b625..83d4d4bb6 100644 --- a/coreapi/test_ecc.c +++ b/tools/test_ecc.c @@ -18,47 +18,47 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - #include "linphonecore.h" #include "linphonecore_utils.h" #if _MSC_VER #include #endif +static int done = 0; -static void calibration_finished(LinphoneCore *lc, LinphoneEcCalibratorStatus status, int delay, void *data){ - ms_message("echo calibration finished %s.",status==LinphoneEcCalibratorDone ? "successfully" : "with faillure"); - if (status==LinphoneEcCalibratorDone) ms_message("Measured delay is %i",delay); +static void calibration_finished(LinphoneCore *lc, LinphoneEcCalibratorStatus status, int delay, void *data) { + ms_message("echo calibration finished %s.", status == LinphoneEcCalibratorDone ? "successfully" : "with faillure"); + if (status == LinphoneEcCalibratorDone) + ms_message("Measured delay is %i", delay); + done = 1; } - -static char config_file[1024]; -void parse_args(int argc, char *argv[]){ +static char config_file[1024] = {0}; +void parse_args(int argc, char *argv[]) { #ifndef F_OK #define F_OK 4 #endif - if (argc != 3 || strncmp("-c",argv[1], 2) || access(argv[2],F_OK)!=0) { + if (argc != 3 || strncmp("-c", argv[1], 2) || access(argv[2], F_OK) != 0) { printf("Usage: test_ecc [-c config_file] where config_file will be written with the detected value\n"); exit(-1); } - strncpy(config_file,argv[2],1024); + strncpy(config_file, argv[2], 1024); } -int main(int argc, char *argv[]){ - int count=0; - LinphoneCoreVTable vtable={0}; +int main(int argc, char *argv[]) { + LinphoneCoreVTable vtable = {0}; LinphoneCore *lc; - if (argc>1) parse_args(argc,argv); - lc=linphone_core_new(&vtable,config_file,NULL,NULL); - + if (argc > 1) + parse_args(argc, argv); + lc = linphone_core_new(&vtable, config_file[0] ? config_file : NULL, NULL, NULL); + linphone_core_enable_logs(NULL); - linphone_core_start_echo_calibration(lc,calibration_finished,NULL,NULL,NULL); - - while(count++<1000){ + linphone_core_start_echo_calibration(lc, calibration_finished, NULL, NULL, NULL); + + while (!done) { linphone_core_iterate(lc); - ms_usleep(10000); + ms_usleep(20000); } linphone_core_destroy(lc); return 0; } - diff --git a/tools/test_lsd.c b/tools/test_lsd.c new file mode 100644 index 000000000..ed38fedde --- /dev/null +++ b/tools/test_lsd.c @@ -0,0 +1,103 @@ +/* +linphone +Copyright (C) 2010 Simon MORLAT (simon.morlat@linphone.org) + +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. +*/ + +/* Linphone Sound Daemon: is a lightweight utility to play sounds to speaker during a conversation. + This is useful for embedded platforms, where sound apis are not performant enough to allow + simultaneous sound access. + + This file is a test program that plays several sound files and places a call simultatenously. +*/ + +#include "linphonecore_utils.h" + +static void play_finished(LsdPlayer *p) { + const char *filename = (const char *)lsd_player_get_user_pointer(p); + ms_message("Playing of %s is finished.", filename); + if (!lsd_player_loop_enabled(p)) { + linphone_sound_daemon_release_player(lsd_player_get_daemon(p), p); + } +} + +static void wait_a_bit(LinphoneCore *lc, int seconds) { + time_t orig = ms_time(NULL); + while (ms_time(NULL) - orig < seconds) { + /* we need to call iterate to receive notifications */ + linphone_core_iterate(lc); + ms_usleep(50000); + } +} + +int main(int argc, char *argv[]) { + LinphoneCore *lc; + LinphoneCoreVTable vtable = {0}; + LinphoneSoundDaemon *lsd; + LsdPlayer *p; + + linphone_core_enable_logs(stdout); + lc = linphone_core_new(&vtable, NULL, NULL, NULL); + lsd = linphone_sound_daemon_new(NULL, 44100, 1); + + linphone_core_use_sound_daemon(lc, lsd); + + /* start a play */ + p = linphone_sound_daemon_get_player(lsd); + lsd_player_set_callback(p, play_finished); + lsd_player_set_user_pointer(p, "share/hello8000.wav"); + lsd_player_play(p, "share/hello8000.wav"); + wait_a_bit(lc, 2); + + /*start another one */ + p = linphone_sound_daemon_get_player(lsd); + lsd_player_set_callback(p, play_finished); + lsd_player_set_user_pointer(p, "share/hello16000.wav"); + lsd_player_enable_loop(p, TRUE); + lsd_player_play(p, "share/hello16000.wav"); + + /* after a few seconds decrease the volume */ + wait_a_bit(lc, 3); + lsd_player_set_gain(p, 0.3); + wait_a_bit(lc, 5); + + /*now play some stereo music*/ + p = linphone_sound_daemon_get_player(lsd); + lsd_player_set_callback(p, play_finished); + lsd_player_set_user_pointer(p, "share/rings/rock.wav"); + lsd_player_play(p, "share/rings/rock.wav"); + wait_a_bit(lc, 2); + + /*now play some stereo music at 22khz in order to test + stereo resampling */ + p = linphone_sound_daemon_get_player(lsd); + lsd_player_set_callback(p, play_finished); + lsd_player_set_user_pointer(p, "share/rings/bigben.wav"); + lsd_player_play(p, "share/rings/bigben.wav"); + wait_a_bit(lc, 6); + + /* now place an outgoing call if sip address argument is given */ + if (argc > 1) { + linphone_core_invite(lc, argv[1]); + wait_a_bit(lc, 10); + linphone_core_terminate_call(lc, NULL); + } + linphone_core_use_sound_daemon(lc, NULL); + linphone_sound_daemon_destroy(lsd); + linphone_core_destroy(lc); + + return 0; +} diff --git a/tools/test_numbers.c b/tools/test_numbers.c new file mode 100644 index 000000000..f6d3baaf3 --- /dev/null +++ b/tools/test_numbers.c @@ -0,0 +1,57 @@ +/* +linphone +Copyright (C) 2012 Belledonne Communications SARL +Author: Simon MORLAT (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "linphonecore.h" +#include "linphonecore_utils.h" + +int main(int argc, char *argv[]) { + LinphoneProxyConfig *cfg; + char *normalized_number; + if (argc < 2) { + fprintf(stderr, "Usage:\n%s [] [--escape-plus]\nReturns normalized number.", + argv[0]); + return -1; + } + linphone_core_enable_logs(stderr); + linphone_core_set_log_level(ORTP_DEBUG); + cfg = linphone_proxy_config_new(); + if (argc > 2) + linphone_proxy_config_set_dial_prefix(cfg, argv[2]); + if (argc > 3 && strcmp(argv[3], "--escape-plus") == 0) + linphone_proxy_config_set_dial_escape_plus(cfg, TRUE); + normalized_number = linphone_proxy_config_normalize_phone_number(cfg, argv[1]); + + if (!normalized_number) { + printf("Invalid phone number: %s\n", argv[1]); + } else { + printf("Normalized number is %s\n", normalized_number); + /*check extracted ccc*/ + if (linphone_proxy_config_get_dial_prefix(cfg) != NULL) { + if (linphone_dial_plan_lookup_ccc_from_e164(normalized_number) != + atoi(linphone_proxy_config_get_dial_prefix(cfg))) { + printf("Error ccc [%i] not correctly parsed\n", + linphone_dial_plan_lookup_ccc_from_e164(normalized_number)); + } else { + printf("Extracted ccc is [%i] \n", linphone_dial_plan_lookup_ccc_from_e164(normalized_number)); + } + } + } + return 0; +}