Merge remote-tracking branch 'linphone/master' into daemon

Conflicts:
	configure.ac
This commit is contained in:
Simon Morlat 2015-05-19 09:36:24 +02:00
commit acf1c35d1d
121 changed files with 9394 additions and 6423 deletions

6
.gitignore vendored
View file

@ -87,3 +87,9 @@ po/linphone.pot
.tx/linphone-gtk.audio-assistantdesktopin/
tester/linphone_log.gz.txt
tools/auto_answer
tools/lp-autoanswer
build/macos/pkg-distribution.xml
tester/record_for_lc_*.wav
tester/record-call_with_file_player.wav
tester/ZIDCache*.xml

View file

@ -26,18 +26,20 @@ project(LINPHONE C CXX)
set(LINPHONE_MAJOR_VERSION "3")
set(LINPHONE_MINOR_VERSION "8")
set(LINPHONE_MICRO_VERSION "1")
set(LINPHONE_MICRO_VERSION "2")
set(LINPHONE_VERSION "${LINPHONE_MAJOR_VERSION}.${LINPHONE_MINOR_VERSION}.${LINPHONE_MICRO_VERSION}")
set(LINPHONE_SO_VERSION "6")
set(LINPHONE_ALL_LANGS "cs de es fr he hu it ja nb_NO nl pl pt_BR ru sr sv zh_CN zh_TW")
set(LINPHONE_SO_VERSION "7")
file(GLOB LINPHONE_PO_FILES RELATIVE "${CMAKE_SOURCE_DIR}/po" "${CMAKE_SOURCE_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}")
include(CMakeDependentOption)
option(ENABLE_STATIC "Build static library (default is shared library)." NO)
option(ENABLE_CONSOLE_UI "Turn on or off compilation of console interface." YES)
option(ENABLE_DATE "Use build date in internal version number." NO)
option(ENABLE_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_MSG_STORAGE "Turn on compilation of message storage." YES)
@ -216,6 +218,9 @@ endif()
add_subdirectory(coreapi)
add_subdirectory(share)
if(ENABLE_CONSOLE_UI)
add_subdirectory(console)
endif()
if(ENABLE_GTK_UI)
add_subdirectory(gtk)
add_subdirectory(pixmaps)

104
COPYING
View file

@ -338,3 +338,107 @@ proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
-------------------------------------------------------------------------------
-------------------------------------------------------
About The Cisco-Provided Binary of OpenH264 Video Codec
-------------------------------------------------------
Cisco provides this program under the terms of the BSD license.
Additionally, this binary is licensed under Ciscos AVC/H.264 Patent Portfolio
License from MPEG LA, at no cost to you, provided that the requirements and
conditions shown below in the AVC/H.264 Patent Portfolio sections are met.
As with all AVC/H.264 codecs, you may also obtain your own patent license from
MPEG LA or from the individual patent owners, or proceed at your own risk.
Your rights from Cisco under the BSD license are not affected by this choice.
For more information on the OpenH264 binary licensing, please see the OpenH264
FAQ found at http://www.openh264.org/faq.html#binary
A corresponding source code to this binary program is available under the same
BSD terms, which can be found at http://www.openh264.org
-----------
BSD License
-----------
Copyright © 2014 Cisco Systems, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-----------------------------------------
AVC/H.264 Patent Portfolio License Notice
-----------------------------------------
The binary form of this Software is distributed by Cisco under the AVC/H.264
Patent Portfolio License from MPEG LA, and is subject to the following
requirements, which may or may not be applicable to your use of this software:
THIS PRODUCT IS LICENSED UNDER THE AVC PATENT PORTFOLIO LICENSE FOR THE
PERSONAL USE OF A CONSUMER OR OTHER USES IN WHICH IT DOES NOT RECEIVE
REMUNERATION TO (i) ENCODE VIDEO IN COMPLIANCE WITH THE AVC STANDARD
(“AVC VIDEO”) AND/OR (ii) DECODE AVC VIDEO THAT WAS ENCODED BY A CONSUMER
ENGAGED IN A PERSONAL ACTIVITY AND/OR WAS OBTAINED FROM A VIDEO PROVIDER
LICENSED TO PROVIDE AVC VIDEO. NO LICENSE IS GRANTED OR SHALL BE IMPLIED FOR
ANY OTHER USE. ADDITIONAL INFORMATION MAY BE OBTAINED FROM MPEG LA, L.L.C. SEE
HTTP://WWW.MPEGLA.COM
Accordingly, please be advised that content providers and broadcasters using
AVC/H.264 in their service may be required to obtain a separate use license
from MPEG LA, referred to as "(b) sublicenses" in the SUMMARY OF AVC/H.264
LICENSE TERMS from MPEG LA found at http://www.openh264.org/mpegla
---------------------------------------------
AVC/H.264 Patent Portfolio License Conditions
---------------------------------------------
In addition, the Cisco-provided binary of this Software is licensed under
Cisco's license from MPEG LA only if the following conditions are met:
1. The Cisco-provided binary is separately downloaded to an end users device,
and not integrated into or combined with third party software prior to being
downloaded to the end users device;
2. The end user must have the ability to control (e.g., to enable, disable, or
re-enable) the use of the Cisco-provided binary;
3. Third party software, in the location where end users can control the use of
the Cisco-provided binary, must display the following text:
"OpenH264 Video Codec provided by Cisco Systems, Inc."
4. Any third-party software that makes use of the Cisco-provided binary must
reproduce all of the above text, as well as this last condition, in the EULA
and/or in another location where licensing information is to be presented to
the end user.
v1.0

View file

@ -209,6 +209,7 @@ Portfile-devel: $(top_srcdir)/scripts/Portfile-devel.tmpl dist
MACAPPNAME=Linphone.app
MACAPPZIP=$(PACKAGE)-$(GITVERSION).app.zip
MACAPPDMG=$(PACKAGE)-$(GITVERSION).dmg
MACAPPPKG=$(PACKAGE)-$(GITVERSION).pkg
BUNDLEPREFIX=./
BUNDLEDIR=$(BUNDLEPREFIX)$(MACAPPNAME)
#a path prefix where additional libs can be cherry-picked by the bundler.
@ -229,15 +230,29 @@ Linphone.app:
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
rm -f ${BUNDLEDIR}/Contents/Resources/lib/libopenh264*
bundle: Linphone.app
bundle: $(MACAPPNAME)
cd $(BUNDLEDIR)/.. && rm -f $(MACAPPZIP) && zip -r $(MACAPPZIP) $(MACAPPNAME) && cd -
cd $(BUNDLEDIR)/.. && rm -f $(MAXAPPDMG) && hdiutil create $(MACAPPDMG) -srcfolder $(MACAPPNAME) -ov && cd -
signed-bundle: Linphone.app
codesign --deep -s $(BUNDLE_SIGNING_ID) $(BUNDLEDIR)
signed-bundle: $(MACAPPNAME)
codesign --deep -s "$(BUNDLE_SIGNING_ID)" $(BUNDLEDIR)
cd $(BUNDLEDIR)/.. && rm -f $(MAXAPPDMG) && hdiutil create $(MACAPPDMG) -srcfolder $(MACAPPNAME) -ov && cd -
pkg: $(MACAPPNAME)
rm -rf ./packaging
mkdir -p ./packaging
cp ${srcdir}/COPYING ./packaging
cp ${srcdir}/pixmaps/linphone.png ./packaging
pkgbuild --install-location /Applications --scripts ${srcdir}/build/macos/pkg-scripts --component $(MACAPPNAME) ./packaging/linphone.pkg
productbuild --resources . --distribution ${srcdir}/build/macos/pkg-distribution.xml --package-path ./packaging $(MACAPPPKG)
signed-pkg: pkg
mv $(MACAPPPKG) $(MACAPPPKG).tmp
productsign --sign "$(BUNDLE_SIGNING_ID)" $(MACAPPPKG).tmp $(MACAPPPKG)
rm -f $(MACAPPPKG).tmp
###
### CLEAN
@ -247,4 +262,8 @@ clean-local:
discovery:
touch specs.c
$(CC) --include $(top_builddir)/config.h \
$(TUNNEL_CFLAGS) $(CFLAGS) $(MEDIASTREAMER2_CFLAGS) $(ORTP_CFLAGS) $(SIPSTACK_CFLAGS) $(CUNIT_CFLAGS) -E -P -v -dD specs.c
$(TUNNEL_CFLAGS) $(CFLAGS) $(MEDIASTREAMER2_CFLAGS) $(ORTP_CFLAGS) $(SIPSTACK_CFLAGS) $(CUNIT_CFLAGS) -E -P -v -dD specs.c
.PHONY: $(MACAPPNAME) pkg

12
NEWS
View file

@ -1,3 +1,15 @@
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
* update SO version to 7 (it should have been done in 3.8.0)
* bug fixes
linphone-3.8.1 -- March 31th, 2015
Application level improvements:
* Auto-answer ability

6
README
View file

@ -59,14 +59,14 @@ For windows compilation see README.mingw.
For macOS X, see README.macos
******************************** notes for developers: *****************************
******************************** Notes for developers *****************************
Here is a short description of the content of the source tree.
- oRTP/ is a poweful implementation of the RTP protocol. See the oRTP/README for more details.
It is used by the mediastreamer to send and receive streams to the network.
It is used by mediastreamer2 to send and receive streams to the network.
- mediastreamer2/ is one of the important part of linphone. It is a framework library for audio
- mediastreamer2/ is one of the important part of linphone. It is a framework for audio
and video processing. It contains several objects for grabing audio and video and outputing
it (through rtp, to file).
It contains also codec objects to compress audio and video streams.

View file

@ -44,14 +44,14 @@ Install `GTK`. It is recommended to use the `quartz` backend for better integrat
antlr3.2 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
brew link readline --force
##### Linphone UI (GTK version)
brew install cairo --without-x11
brew install cairo --without-x11
brew install gtk+ --without-x11
brew install gettext gtk-mac-integration libsoup hicolor-icon-theme
#readline is required from linphonec.c otherwise compilation will fail
brew link readline --force
brew install gtk-mac-integration libsoup hicolor-icon-theme
### Building Linphone
@ -72,7 +72,7 @@ The next pieces need to be compiled manually.
* Install polarssl (encryption library used by belle-sip)
git clone git://git.linphone.org/polarssl.git -b linphone
git clone git://git.linphone.org/polarssl.git
cd polarssl
./autogen.sh && ./configure --prefix=/opt/local && make
sudo make install
@ -92,7 +92,7 @@ The next pieces need to be compiled manually.
* (Optional) Install zrtp, for unbreakable call encryption
git clone git://git.linphone.org:bzrtp
git clone git://git.linphone.org/bzrtp.git
cd bzrtp && ./autogen.sh && ./configure --prefix=/opt/local && make
sudo make install
@ -103,9 +103,6 @@ The next pieces need to be compiled manually.
make CCFLAGS="$CFLAGS -c -O2 -DNeedFunctionPrototypes=1"
sudo make install INSTALL_ROOT=/opt/local GSM_INSTALL_INC=/opt/local/include
* (Optional) libvpx-1.2 has a bug on MacOS resulting in ugly video. It is recommended to upgrade it manually to 1.3 from source.
The libvpx build isn't able to produce dual architecture files. To workaround this, configure libvpx twice and use lipo to create a dual architecture `libvpx.a`.
* (Optional, proprietary extension only) Compile and install the tunnel library
If you got the source code from git, run `./autogen.sh` first.
Then or otherwise, do:
@ -116,7 +113,7 @@ The libvpx build isn't able to produce dual architecture files. To workaround th
If you got the source code from git, run `./autogen.sh` first.
Then or otherwise, :
PKG_CONFIG_PATH=/usr/local/lib/pkgconfig ./configure --prefix=/opt/local --with-srtp=/opt/local --with-gsm=/opt/local --enable-zrtp --disable-strict && make
PKG_CONFIG_PATH=/opt/local/lib/pkgconfig ./configure --prefix=/opt/local --with-srtp=/opt/local --with-gsm=/opt/local --enable-zrtp --disable-strict && make
* Install on the system

View file

@ -1,7 +1,7 @@
LOCAL_PATH := $(call my-dir)/../../tester
common_SRC_FILES := \
../../belle-sip/tester/common/bc_tester_utils.c \
common/bc_tester_utils.c \
call_tester.c \
liblinphone_tester.c \
message_tester.c \
@ -30,7 +30,7 @@ common_C_INCLUDES += \
$(LOCAL_PATH)/../coreapi \
$(LOCAL_PATH)/../oRTP/include \
$(LOCAL_PATH)/../mediastreamer2/include \
$(LOCAL_PATH)/../../belle-sip/tester/common \
$(LOCAL_PATH)/common
include $(CLEAR_VARS)

View file

@ -25,7 +25,7 @@
<key>NSHumanReadableCopyright</key>
<string>Copyright 2011 Belledonne Communications</string>
<key>LSMinimumSystemVersion</key>
<string>10.4</string>
<string>10.7</string>
<key>NSAppSleepDisabled</key>
<string>YES</string>
</dict>

View file

@ -1,3 +1,7 @@
EXTRA_DIST=linphone.bundle environment.sh Info-linphone.plist.in
EXTRA_DIST= \
linphone.bundle \
environment.sh \
Info-linphone.plist.in \
pkg-scripts/postinstall \
pkg-distribution.xml.in

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<installer-gui-script minSpecVersion="1">
<title>Linphone</title>
<license file="COPYING" mime-type="text/plain"/>
<background file="linphone.png" mime-type="image/png" />
<pkg-ref id="org.linphone.linphone"/>
<options customize="never" require-scripts="false"/>
<choices-outline>
<line choice="default">
<line choice="org.linphone.linphone"/>
</line>
</choices-outline>
<choice id="default"/>
<choice id="org.linphone.linphone" visible="false">
<pkg-ref id="org.linphone.linphone"/>
</choice>
<pkg-ref id="org.linphone.linphone" version="@PACKAGE_VERSION@" onConclusion="none">linphone.pkg</pkg-ref>
</installer-gui-script>

View file

@ -0,0 +1,16 @@
#!/bin/bash
CURL=/usr/bin/curl
BUNZIP2=/usr/bin/bunzip2
VERSION=1.4.0
BASENAME=libopenh264-${VERSION}-osx64
FILENAME=${BASENAME}.dylib.bz2
TMPDIR=/tmp/linphone_installer
mkdir ${TMPDIR}
cd ${TMPDIR}
${CURL} http://ciscobinary.openh264.org/${FILENAME} > ${FILENAME}
${BUNZIP2} ${FILENAME}
cp ${BASENAME}.dylib /Applications/Linphone.app/Contents/Resources/lib/libopenh264.0.dylib
rm -r ${TMPDIR}

View file

@ -40,11 +40,19 @@ if(ZLIB_INCLUDE_DIRS)
set(HAVE_ZLIB_H 1)
endif()
find_library(ZLIB_LIBRARIES
NAMES z zlib zlibd
HINTS ${_ZLIB_ROOT_PATHS}
PATH_SUFFIXES bin lib
)
if(ENABLE_STATIC)
find_library(ZLIB_LIBRARIES
NAMES zstatic zlibstatic zlibstaticd
HINTS ${_ZLIB_ROOT_PATHS}
PATH_SUFFIXES bin lib
)
else()
find_library(ZLIB_LIBRARIES
NAMES z zlib zlibd
HINTS ${_ZLIB_ROOT_PATHS}
PATH_SUFFIXES bin lib
)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Zlib

View file

@ -1,6 +1,6 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT([linphone],[3.8.1-linphone-daemon],[linphone-developers@nongnu.org])
AC_INIT([linphone],[3.8.2-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=6 dnl increment this number when you add/change/remove an interface
LIBLINPHONE_SO_CURRENT=7 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
@ -347,10 +347,14 @@ if test "$gtk_ui" = "true" ; then
fi
AC_DEFINE([HAVE_GTK_OSX],[1],[Defined when gtk osx is used])
fi
PKG_CHECK_MODULES(LIBGLIB, [glib-2.0 >= 2.26.0], [build_status_notifier=yes], [build_status_notifier=no])
else
echo "GTK interface compilation is disabled."
fi
AM_CONDITIONAL([BUILD_STATUS_NOTIFIER], [test "$build_status_notifier" = "yes"])
AC_ARG_ENABLE(notify,
[AS_HELP_STRING([--enable-notify=[yes/no]], [Enable libnotify support (default=yes)])],
[case "${enableval}" in
@ -1037,6 +1041,7 @@ AC_CONFIG_FILES([
build/Makefile
build/macos/Makefile
build/macos/Info-linphone.plist
build/macos/pkg-distribution.xml
m4/Makefile
po/Makefile.in
pixmaps/Makefile

53
console/CMakeLists.txt Normal file
View file

@ -0,0 +1,53 @@
############################################################################
# CMakeLists.txt
# 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.
#
############################################################################
set(LINPHONEC_SOURCE_FILES
linphonec.c
linphonec.h
commands.c
)
set(LINPHONECSH_SOURCE_FILES
shell.c
)
add_executable(linphonec ${LINPHONEC_SOURCE_FILES})
target_link_libraries(linphonec linphone)
if(WIN32)
add_executable(linphoned WIN32 ${LINPHONEC_SOURCE_FILES})
target_link_libraries(linphoned linphone)
endif()
add_executable(linphonecsh ${LINPHONECSH_SOURCE_FILES})
target_link_libraries(linphonecsh linphone)
set(INSTALL_TARGETS linphonec linphonecsh)
if(WIN32)
list(APPEND INSTALL_TARGETS linphoned)
endif()
install(TARGETS ${INSTALL_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
)

View file

@ -28,7 +28,6 @@
#include <stdlib.h>
#ifndef _WIN32_WCE
#include <errno.h>
#include <unistd.h>
#endif /*_WIN32_WCE*/
#include <limits.h>
#include <ctype.h>
@ -38,6 +37,7 @@
#ifndef WIN32
#include <sys/wait.h>
#include <unistd.h>
#endif
#define AUDIO 0
@ -1915,24 +1915,24 @@ static int lpc_cmd_register(LinphoneCore *lc, char *args){
const MSList *elem;
if (!args)
{
/* it means that you want to register the default proxy */
LinphoneProxyConfig *cfg=NULL;
linphone_core_get_default_proxy(lc,&cfg);
if (cfg)
{
if(!linphone_proxy_config_is_registered(cfg)) {
{
/* it means that you want to register the default proxy */
LinphoneProxyConfig *cfg=NULL;
linphone_core_get_default_proxy(lc,&cfg);
if (cfg)
{
if(!linphone_proxy_config_is_registered(cfg)) {
linphone_proxy_config_enable_register(cfg,TRUE);
linphone_proxy_config_done(cfg);
}else{
linphonec_out("default proxy already registered\n");
}
}else{
linphonec_out("we do not have a default proxy\n");
return 0;
}
return 1;
}
}else{
linphonec_out("we do not have a default proxy\n");
return 0;
}
return 1;
}
passwd[0]=proxy[0]=identity[0]='\0';
sscanf(args,"%511s %511s %511s",identity,proxy,passwd);
if (proxy[0]=='\0' || identity[0]=='\0'){
@ -1943,7 +1943,7 @@ static int lpc_cmd_register(LinphoneCore *lc, char *args){
LinphoneAddress *from;
LinphoneAuthInfo *info;
if ((from=linphone_address_new(identity))!=NULL){
info=linphone_auth_info_new(NULL,NULL,passwd,NULL,NULL,linphone_address_get_username(from));
info=linphone_auth_info_new(linphone_address_get_username(from),NULL,passwd,NULL,NULL,linphone_address_get_username(from));
linphone_core_add_auth_info(lc,info);
linphone_address_destroy(from);
linphone_auth_info_destroy(info);

View file

@ -25,9 +25,7 @@
****************************************************************************/
#include <string.h>
#ifndef _WIN32_WCE
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include "private.h" /*coreapi/private.h, needed for LINPHONE_VERSION */
@ -48,17 +46,19 @@
#endif /*_WIN32_WCE*/
#else
#include <sys/socket.h>
#include <sys/time.h>
#include <netdb.h>
#include <sys/un.h>
#include <sys/stat.h>
#include <unistd.h>
#endif
#if defined(_WIN32_WCE)
#if !defined(PATH_MAX)
#define PATH_MAX 256
#endif /*PATH_MAX*/
#if defined(_WIN32_WCE)
#if !defined(strdup)
#define strdup _strdup
#endif /*strdup*/
@ -661,6 +661,12 @@ main (int argc, char *argv[]) {
exit(EXIT_SUCCESS); /* should never reach here */
}
#ifdef _MSC_VER
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
return main(__argc, __argv);
}
#endif
/*
* Initialize linphonec
*/
@ -1214,15 +1220,21 @@ linphonec_parse_cmdline(int argc, char **argv)
else if (strncmp ("-c", argv[arg_num], 2) == 0)
{
if ( ++arg_num >= argc ) print_usage(EXIT_FAILURE);
#ifdef _MSC_VER
if (strcmp(argv[arg_num], "NUL") != 0) {
#endif
#if !defined(_WIN32_WCE)
if (access(argv[arg_num],F_OK)!=0 )
{
fprintf (stderr,
"Cannot open config file %s.\n",
argv[arg_num]);
exit(EXIT_FAILURE);
}
if (access(argv[arg_num], F_OK) != 0)
{
fprintf(stderr,
"Cannot open config file %s.\n",
argv[arg_num]);
exit(EXIT_FAILURE);
}
#endif /*_WIN32_WCE*/
#ifdef _MSC_VER
}
#endif
snprintf(configfile_name, PATH_MAX, "%s", argv[arg_num]);
}
else if (strncmp ("-b", argv[arg_num], 2) == 0)

View file

@ -48,6 +48,7 @@
#define STATUS_AUTOANSWER (1<<3)
#define STATUS_IN_CONNECTED (1<<4) /* incoming call accepted */
#define STATUS_OUT_CONNECTED (1<<5) /*outgoing call accepted */
#define STATUS_IN_COMING (1<<6) /*incoming call pending */
static int make_status_value(const char *status_string){
@ -70,6 +71,9 @@ static int make_status_value(const char *status_string){
if (strstr(status_string,"hook=answered")){
ret|=STATUS_IN_CONNECTED;
}
if (strstr(status_string,"Incoming call from ")){
ret|=STATUS_IN_COMING;
}
return ret;
}
@ -181,7 +185,7 @@ static void spawn_linphonec(int argc, char *argv[]){
int fd;
/*we are the new process*/
setsid();
fd = open("/dev/null", O_RDWR);
if (fd==-1){
fprintf(stderr,"Could not open /dev/null\n");
@ -191,7 +195,7 @@ static void spawn_linphonec(int argc, char *argv[]){
dup2(fd, 1);
dup2(fd, 2);
close(fd);
if (execvp("linphonec",args)==-1){
fprintf(stderr,"Fail to spawn linphonec: %s\n",strerror(errno));
exit(-1);
@ -207,7 +211,7 @@ static void spawn_linphonec(int argc, char *argv[]){
const char *cmd = "linphoned.exe --pipe -c NUL";
char *args_in_line = argv_to_line(argc, argv);
char *cmd_with_args;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pinfo, sizeof(pinfo) );
@ -217,7 +221,7 @@ static void spawn_linphonec(int argc, char *argv[]){
} else {
cmd_with_args = ortp_strdup(cmd);
}
ret=CreateProcess(NULL, cmd_with_args,
NULL,
NULL,
@ -308,7 +312,7 @@ static int status_execute(int argc, char *argv[]){
char cmd[512];
char reply[DEFAULT_REPLY_SIZE];
int err;
if (argc==1){
snprintf(cmd,sizeof(cmd),"status %s",argv[0]);
err=send_command(cmd,reply,sizeof(reply),TRUE);

View file

@ -20,7 +20,7 @@
#
############################################################################
if(MSVC)
if(MSVC AND NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "WindowsPhone")
find_library(LIBGCC NAMES gcc)
find_library(LIBMINGWEX NAMES mingwex)
endif()
@ -121,8 +121,6 @@ add_definitions(
)
set(LIBS
${LIBGCC}
${LIBMINGWEX}
${BELLESIP_LIBRARIES}
${MEDIASTREAMER2_LIBRARIES}
${XML2_LIBRARIES}
@ -142,6 +140,9 @@ endif()
if(ENABLE_ASSISTANT)
list(APPEND LIBS ${SOUP_LIBRARIES})
endif()
if(MSVC AND NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "WindowsPhone")
list(APPEND LIBS ${LIBGCC} ${LIBMINGWEX})
endif()
if(WIN32 AND NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "WindowsPhone")
list(APPEND LIBS shlwapi)
endif()
@ -166,7 +167,12 @@ if(WIN32 AND "${CMAKE_SYSTEM_NAME}" STREQUAL "WindowsPhone")
set_target_properties(linphone PROPERTIES PREFIX "lib")
endif()
if(ICONV_FOUND)
target_include_directories(linphone PUBLIC ${ICONV_INCLUDE_DIRS})
if(APPLE)
# Prevent conflict between the system iconv.h header and the one from macports.
target_compile_options(linphone PRIVATE "-include" "${ICONV_INCLUDE_DIRS}/iconv.h")
else()
target_include_directories(linphone PRIVATE ${ICONV_INCLUDE_DIRS})
endif()
endif()
install(TARGETS linphone EXPORT LinphoneTargets
@ -199,4 +205,6 @@ install(FILES ${HEADER_FILES}
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
)
add_subdirectory(help)
if(ENABLE_DOC)
add_subdirectory(help)
endif()

View file

@ -199,7 +199,7 @@ AM_CXXFLAGS=$(COMMON_CFLAGS) $(STRICT_OPTIONS_CXX)
make_gitversion_h:
if test -n "$(GITLOG)" ; then \
if test "$(GITDESCRIBE)" != "" ; then \
if test "$(GIT_TAG)" != "$(PACKAGE_VERSION)" ; then \
if [ "$(GIT_TAG)" != "$(PACKAGE_VERSION)" ]; then \
$(ECHO) "*** PACKAGE_VERSION and git tag differ. Please put them identical."; \
exit 1; \
fi ; \

View file

@ -128,6 +128,11 @@ static void add_rtcp_fb_attributes(belle_sdp_media_description_t *media_desc, co
payload_type_set_flag(pt, PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED);
avpf_params = payload_type_get_avpf_params(pt);
/* Add trr-int if not set generally. */
if (general_trr_int != TRUE) {
add_rtcp_fb_trr_int_attribute(media_desc, payload_type_get_number(pt), avpf_params.trr_interval);
}
/* Add rtcp-fb attributes according to the AVPF features of the payload types. */
if (avpf_params.features & PAYLOAD_TYPE_AVPF_PLI) {
add_rtcp_fb_nack_attribute(media_desc, payload_type_get_number(pt), BELLE_SDP_RTCP_FB_PLI);
@ -538,9 +543,6 @@ static void apply_rtcp_fb_attribute_to_payload(belle_sdp_rtcp_fb_attribute_t *fb
switch (belle_sdp_rtcp_fb_attribute_get_type(fb_attribute)) {
case BELLE_SDP_RTCP_FB_NACK:
switch (belle_sdp_rtcp_fb_attribute_get_param(fb_attribute)) {
case BELLE_SDP_RTCP_FB_NONE:
avpf_params.features |= PAYLOAD_TYPE_AVPF_PLI | PAYLOAD_TYPE_AVPF_SLI | PAYLOAD_TYPE_AVPF_RPSI;
break;
case BELLE_SDP_RTCP_FB_PLI:
avpf_params.features |= PAYLOAD_TYPE_AVPF_PLI;
break;
@ -550,6 +552,7 @@ static void apply_rtcp_fb_attribute_to_payload(belle_sdp_rtcp_fb_attribute_t *fb
case BELLE_SDP_RTCP_FB_RPSI:
avpf_params.features |= PAYLOAD_TYPE_AVPF_RPSI;
break;
case BELLE_SDP_RTCP_FB_NONE:
default:
break;
}
@ -581,6 +584,15 @@ 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);

View file

@ -235,6 +235,21 @@ void linphone_call_params_unref(LinphoneCallParams *cp) {
belle_sip_object_unref(cp);
}
void linphone_call_params_enable_audio_multicast(LinphoneCallParams *params, bool_t yesno) {
params->audio_multicast_enabled=yesno;
}
bool_t linphone_call_params_audio_multicast_enabled(const LinphoneCallParams *params) {
return params->audio_multicast_enabled;
}
void linphone_call_params_enable_video_multicast(LinphoneCallParams *params, bool_t yesno) {
params->video_multicast_enabled=yesno;
}
bool_t linphone_call_params_video_multicast_enabled(const LinphoneCallParams *params) {
return params->video_multicast_enabled;
}
/*******************************************************************************
* Constructor and destructor functions *
******************************************************************************/

View file

@ -322,6 +322,42 @@ LINPHONE_PUBLIC LinphoneCallParams * linphone_call_params_ref(LinphoneCallParams
LINPHONE_PUBLIC void linphone_call_params_unref(LinphoneCallParams *cp);
/**
* Use to enable multicast rtp for audio stream.
* * If enabled, outgoing calls put a multicast address from #linphone_core_get_video_multicast_addr into audio cline. In case of outgoing call audio stream is sent to this multicast address.
* <br> For incoming calls behavior is unchanged.
* @param core #LinphoneCallParams
* @param yesno if yes, subsequent calls will propose multicast ip set by #linphone_core_set_audio_multicast_addr
* @ingroup media_parameters
**/
LINPHONE_PUBLIC void linphone_call_params_enable_audio_multicast(LinphoneCallParams *param, bool_t yesno);
/**
* Use to get multicast state of audio stream.
* @param core #LinphoneCallParams
* @return true if subsequent calls will propose multicast ip set by #linphone_core_set_audio_multicast_addr
* @ingroup media_parameters
**/
LINPHONE_PUBLIC bool_t linphone_call_params_audio_multicast_enabled(const LinphoneCallParams *param);
/**
* Use to enable multicast rtp for video stream.
* If enabled, outgoing calls put a multicast address from #linphone_core_get_video_multicast_addr into video cline. In case of outgoing call video stream is sent to this multicast address.
* <br> For incoming calls behavior is unchanged.
* @param core #LinphoneCallParams
* @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);
/**
* Use to get multicast state of video stream.
* @param core #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);
/*******************************************************************************
* DEPRECATED *
******************************************************************************/

View file

@ -119,6 +119,8 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia
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);
@ -144,10 +146,13 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia
call->resultdesc=new_md;
if ((call->audiostream && call->audiostream->ms.state==MSStreamStarted) || (call->videostream && call->videostream->ms.state==MSStreamStarted)){
clear_early_media_destinations(call);
/* we already started media: check if we really need to restart it*/
if (oldmd){
int md_changed = media_parameters_changed(call, oldmd, new_md);
if ((md_changed & SAL_MEDIA_DESCRIPTION_CODEC_CHANGED)){
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))){
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.");
@ -181,6 +186,11 @@ 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]);
}
linphone_call_init_media_streams (call);
}
@ -245,18 +255,6 @@ static bool_t already_a_call_with_remote_address(const LinphoneCore *lc, const L
return FALSE;
}
static bool_t already_an_outgoing_call_pending(LinphoneCore *lc){
MSList *elem;
for(elem=lc->calls;elem!=NULL;elem=elem->next){
LinphoneCall *call=(LinphoneCall*)elem->data;
if (call->state==LinphoneCallOutgoingInit
|| call->state==LinphoneCallOutgoingProgress
|| call->state==LinphoneCallOutgoingRinging){
return TRUE;
}
}
return FALSE;
}
static void call_received(SalOp *h){
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(h));
@ -264,9 +262,9 @@ static void call_received(SalOp *h){
char *alt_contact;
LinphoneAddress *from_addr=NULL;
LinphoneAddress *to_addr=NULL;
/*this mode is deprcated because probably useless*/
bool_t prevent_colliding_calls=lp_config_get_int(lc->config,"sip","prevent_colliding_calls",FALSE);
LinphoneAddress *from_address_to_search_if_me=NULL; /*address used to know if I'm the caller*/
SalMediaDescription *md;
const char * p_asserted_id;
/* first check if we can answer successfully to this invite */
if (linphone_presence_model_get_basic_status(lc->presence_model) == LinphonePresenceBasicStatusClosed) {
@ -300,9 +298,9 @@ static void call_received(SalOp *h){
sal_op_release(h);
return;
}
p_asserted_id = sal_custom_header_find(sal_op_get_recv_custom_header(h),"P-Asserted-Identity");
/*in some situation, better to trust the network rather than the UAC*/
if (lp_config_get_int(lc->config,"sip","call_logs_use_asserted_id_instead_of_from",0)) {
const char * p_asserted_id = sal_custom_header_find(sal_op_get_recv_custom_header(h),"P-Asserted-Identity");
LinphoneAddress *p_asserted_id_addr;
if (!p_asserted_id) {
ms_warning("No P-Asserted-Identity header found so cannot use it for op [%p] instead of from",h);
@ -321,13 +319,26 @@ static void call_received(SalOp *h){
from_addr=linphone_address_new(sal_op_get_from(h));
to_addr=linphone_address_new(sal_op_get_to(h));
if ((already_a_call_with_remote_address(lc,from_addr) && prevent_colliding_calls) || already_an_outgoing_call_pending(lc)){
ms_warning("Receiving a call while one is initiated, refusing this one with busy message.");
if (sal_op_get_privacy(h) == SalPrivacyNone) {
from_address_to_search_if_me=linphone_address_clone(from_addr);
} else if (p_asserted_id) {
from_address_to_search_if_me = linphone_address_new(p_asserted_id);
} else {
ms_warning ("Hidden from identity, don't know if it's me");
}
if (from_address_to_search_if_me && already_a_call_with_remote_address(lc,from_address_to_search_if_me)){
char *addr = linphone_address_as_string(from_addr);
ms_warning("Receiving a call while one with same address [%s] is initiated, refusing this one with busy message.",addr);
sal_call_decline(h,SalReasonBusy,NULL);
sal_op_release(h);
linphone_address_destroy(from_addr);
linphone_address_destroy(to_addr);
linphone_address_destroy(from_address_to_search_if_me);
ms_free(addr);
return;
} else if (from_address_to_search_if_me) {
linphone_address_destroy(from_address_to_search_if_me);
}
call=linphone_call_new_incoming(lc,from_addr,to_addr,h);
@ -526,6 +537,7 @@ static void call_accepted(SalOp *op){
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)){
{
@ -620,12 +632,17 @@ static void call_resumed(LinphoneCore *lc, LinphoneCall *call){
}
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."));
_linphone_core_accept_call_update(lc,call,NULL,LinphoneCallPausedByRemote,"Call paused by remote");
params = linphone_call_params_copy(call->params);
if (lp_config_get_int(lc->config, "sip", "inactive_video_on_pause", 0)) {
linphone_call_params_set_video_direction(params, LinphoneMediaDirectionInactive);
}
_linphone_core_accept_call_update(lc,call,params,LinphoneCallPausedByRemote,"Call paused by remote");
linphone_call_params_unref(params);
}
static void call_updated_by_remote(LinphoneCore *lc, LinphoneCall *call, bool_t is_update){
@ -658,7 +675,7 @@ static void call_updated_by_remote(LinphoneCore *lc, LinphoneCall *call, bool_t
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=FALSE;
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);
@ -671,7 +688,7 @@ static void call_updated_by_remote(LinphoneCore *lc, LinphoneCall *call, bool_t
/* 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=FALSE;
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));
}

View file

@ -128,7 +128,7 @@ void __linphone_friend_do_subscribe(LinphoneFriend *fr){
}
LinphoneFriend * linphone_friend_new(){
LinphoneFriend *obj=ms_new0(LinphoneFriend,1);
LinphoneFriend *obj=belle_sip_object_new(LinphoneFriend);
obj->pol=LinphoneSPAccept;
obj->presence=NULL;
obj->subscribe=TRUE;
@ -150,11 +150,11 @@ LinphoneFriend *linphone_friend_new_with_address(const char *addr){
}
void linphone_friend_set_user_data(LinphoneFriend *lf, void *data){
lf->up=data;
lf->user_data=data;
}
void* linphone_friend_get_user_data(const LinphoneFriend *lf){
return lf->up;
return lf->user_data;
}
bool_t linphone_friend_in_list(const LinphoneFriend *lf){
@ -266,7 +266,7 @@ void linphone_friend_close_subscriptions(LinphoneFriend *lf){
}
}
void linphone_friend_destroy(LinphoneFriend *lf){
static void _linphone_friend_destroy(LinphoneFriend *lf){
if (lf->insub) {
sal_op_release(lf->insub);
lf->insub=NULL;
@ -278,7 +278,6 @@ void linphone_friend_destroy(LinphoneFriend *lf){
if (lf->presence != NULL) linphone_presence_model_unref(lf->presence);
if (lf->uri!=NULL) linphone_address_destroy(lf->uri);
if (lf->info!=NULL) buddy_info_free(lf->info);
ms_free(lf);
}
const LinphoneAddress *linphone_friend_get_address(const LinphoneFriend *lf){
@ -481,7 +480,7 @@ void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *lf)
if (tmp) ms_free(tmp);
return ;
}
lc->friends=ms_list_append(lc->friends,lf);
lc->friends=ms_list_append(lc->friends,linphone_friend_ref(lf));
lf->lc=lc;
if ( linphone_core_ready(lc)) linphone_friend_apply(lf,lc);
else lf->commit=TRUE;
@ -685,3 +684,25 @@ LinphoneCore *linphone_friend_get_core(const LinphoneFriend *fr){
return fr->lc;
}
LinphoneFriend *linphone_friend_ref(LinphoneFriend *lf) {
belle_sip_object_ref(lf);
return lf;
}
void linphone_friend_unref(LinphoneFriend *lf) {
belle_sip_object_unref(lf);
}
/* DEPRECATED */
void linphone_friend_destroy(LinphoneFriend *lf) {
linphone_friend_unref(lf);
}
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
FALSE
);

View file

@ -37,10 +37,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2/mseventqueue.h"
#include "mediastreamer2/mssndcard.h"
static const char EC_STATE_STORE[] = ".linphone.ecstate";
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);
#ifdef VIDEO_ENABLED
MSWebCam *get_nowebcam_device(){
@ -555,26 +556,30 @@ static void transfer_already_assigned_payload_types(SalMediaDescription *old, Sa
}
static const char *linphone_call_get_bind_ip_for_stream(LinphoneCall *call, int stream_index){
const char *bind_ip = lp_config_get_string(call->core->config,"rtp","bind_address",call->af==AF_INET6 ? "::0" : "0.0.0.0"); ;
const char *bind_ip = lp_config_get_string(call->core->config,"rtp","bind_address",call->af==AF_INET6 ? "::0" : "0.0.0.0");
if (stream_index<2 && call->media_ports[stream_index].multicast_ip[0]!='\0'){
if (call->dir==LinphoneCallOutgoing){
/*as multicast sender, we must decide a local interface to use to send multicast, and bind to it*/
bind_ip=call->localip;
bind_ip=call->media_localip;
}
}
return bind_ip;
}
static const char *linphone_call_get_public_ip_for_stream(LinphoneCall *call, int stream_index){
const char *public_ip=call->localip;
const char *public_ip=call->media_localip;
if (stream_index<2 && call->media_ports[stream_index].multicast_ip[0]!='\0')
public_ip=call->media_ports[stream_index].multicast_ip;
return public_ip;
}
void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *call){
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_make_local_media_description_with_params(LinphoneCore *lc, LinphoneCall *call, LinphoneCallParams *params) {
MSList *l;
SalMediaDescription *old_md=call->localdesc;
int i;
@ -586,19 +591,19 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *
CodecConstraints codec_hints={0};
/*multicast is only set in case of outgoing call*/
if (call->dir == LinphoneCallOutgoing && linphone_core_audio_multicast_enabled(lc)) {
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;
}
if (call->dir == LinphoneCallOutgoing && linphone_core_video_multicast_enabled(lc)) {
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;
}
subject=linphone_call_params_get_session_name(call->params);
subject=linphone_call_params_get_session_name(params);
linphone_core_adapt_to_network(lc,call->ping_time,call->params);
linphone_core_adapt_to_network(lc,call->ping_time,params);
if (call->dest_proxy)
me=linphone_proxy_config_get_identity(call->dest_proxy);
@ -610,13 +615,15 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *
md->session_ver=(old_md ? (old_md->session_ver+1) : (rand() & 0xfff));
md->nb_streams=(call->biggestdesc ? call->biggestdesc->nb_streams : 1);
strncpy(md->addr,call->localip,sizeof(md->addr));
/*re-check local ip address each time we make a new offer, because it may change in case of network reconnection*/
linphone_call_get_local_ip(call, call->dir == LinphoneCallOutgoing ? call->log->to : call->log->from);
strncpy(md->addr,call->media_localip,sizeof(md->addr));
if (linphone_address_get_username(addr)) /*might be null in case of identity without userinfo*/
strncpy(md->username,linphone_address_get_username(addr),sizeof(md->username));
if (subject) strncpy(md->name,subject,sizeof(md->name));
if (call->params->down_bw)
md->bandwidth=call->params->down_bw;
if (params->down_bw)
md->bandwidth=params->down_bw;
else md->bandwidth=linphone_core_get_download_bandwidth(lc);
/*set audio capabilities */
@ -625,14 +632,14 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *
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(call->params);
md->streams[0].dir=get_audio_dir_from_call_params(call->params);
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 (call->params->down_ptime)
md->streams[0].ptime=call->params->down_ptime;
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=call->params->audio_bw;
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);
@ -648,14 +655,14 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *
ms_warning("Cannot get audio local ssrc for call [%p]",call);
nb_active_streams++;
if (call->params->has_video && (!call->params->internal_call_update || !call->current_params->video_declined)){
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(call->params);
md->streams[1].dir=get_video_dir_from_call_params(params);
md->streams[1].type=SalVideo;
codec_hints.bandwidth_limit=0;
codec_hints.max_codecs=-1;
@ -664,8 +671,8 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *
md->streams[1].payloads=l;
if (call->videostream && call->videostream->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->videostream->ms.sessions.rtp_session);
strncpy(md->streams[0].rtcp_cname,me,sizeof(md->streams[0].rtcp_cname));
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));
ms_free(me);
}
else
@ -807,17 +814,6 @@ static void linphone_call_init_common(LinphoneCall *call, LinphoneAddress *from,
linphone_core_get_video_port_range(call->core, &min_port, &max_port);
port_config_set(call,1,min_port,max_port);
if (call->dir==LinphoneCallOutgoing){
if ( linphone_core_audio_multicast_enabled(call->core)){
strncpy(call->media_ports[0].multicast_ip,
linphone_core_get_audio_multicast_addr(call->core), sizeof(call->media_ports[0].multicast_ip));
}
if ( linphone_core_video_multicast_enabled(call->core)){
strncpy(call->media_ports[1].multicast_ip,
linphone_core_get_video_multicast_addr(call->core), sizeof(call->media_ports[1].multicast_ip));
}
}
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
@ -906,18 +902,25 @@ static void linphone_call_get_local_ip(LinphoneCall *call, const LinphoneAddress
}
if (linphone_core_get_firewall_policy(call->core)==LinphonePolicyUseNatAddress
&& (ip=linphone_core_get_nat_address_resolved(call->core))!=NULL){
strncpy(call->localip,ip,LINPHONE_IPADDR_SIZE);
strncpy(call->media_localip,ip,LINPHONE_IPADDR_SIZE);
return;
}
#ifdef BUILD_UPNP
else if (call->core->upnp != NULL && linphone_core_get_firewall_policy(call->core)==LinphonePolicyUseUpnp &&
linphone_upnp_context_get_state(call->core->upnp) == LinphoneUpnpStateOk) {
ip = linphone_upnp_context_get_external_ipaddress(call->core->upnp);
strncpy(call->localip,ip,LINPHONE_IPADDR_SIZE);
strncpy(call->media_localip,ip,LINPHONE_IPADDR_SIZE);
return;
}
#endif //BUILD_UPNP
linphone_core_get_local_ip(call->core, af, dest, call->localip);
/*first nominal use case*/
linphone_core_get_local_ip(call->core, af, dest, call->media_localip);
/*next, sometime, override from config*/
if ((ip=lp_config_get_string(call->core->config,"rtp","bind_address",NULL)))
strncpy(call->media_localip,ip,LINPHONE_IPADDR_SIZE);
return;
}
static void linphone_call_destroy(LinphoneCall *obj);
@ -930,7 +933,19 @@ BELLE_SIP_INSTANCIATE_VPTR(LinphoneCall, belle_sip_object_t,
NULL, // marshal
FALSE
);
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));
} else
call->media_ports[0].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));
} else
call->media_ports[1].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);
@ -941,6 +956,8 @@ LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddr
linphone_call_init_common(call,from,to);
call->params = linphone_call_params_copy(params);
linphone_call_fill_media_multicast_addr(call);
if (linphone_core_get_firewall_policy(call->core) == LinphonePolicyUseIce) {
call->ice_session = ice_session_new();
/*for backward compatibility purposes, shall be enabled by default in futur*/
@ -977,8 +994,6 @@ 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) {
int i;
/* Handle AVPF, SRTP and DTLS. */
call->params->avpf_enabled = sal_media_description_has_avpf(md);
if (call->params->avpf_enabled == TRUE) {
@ -990,31 +1005,25 @@ void linphone_call_set_compatible_incoming_call_parameters(LinphoneCall *call, c
}
if ((sal_media_description_has_dtls(md) == TRUE) && (media_stream_dtls_supported() == TRUE)) {
call->params->media_encryption = LinphoneMediaEncryptionDTLS;
}
if ((sal_media_description_has_srtp(md) == TRUE) && (ms_srtp_supported() == TRUE)) {
}else if ((sal_media_description_has_srtp(md) == TRUE) && (ms_srtp_supported() == TRUE)) {
call->params->media_encryption = LinphoneMediaEncryptionSRTP;
}else if (call->params->media_encryption != LinphoneMediaEncryptionZRTP){
call->params->media_encryption = LinphoneMediaEncryptionNone;
}
/* set both local audio & video multicast ip address if any*/
for (i=0;i<2;++i){
if (md->streams[i].rtp_addr[i]!='\0' && ms_is_multicast(md->streams[i].rtp_addr)) {
strncpy(call->media_ports[i].multicast_ip,md->streams[i].rtp_addr,sizeof(call->media_ports[i].multicast_ip));
ms_message("Disabling rtcp on call [%p], stream [%i] because of multicast",call,i);
call->media_ports[i].mcast_rtp_port=md->streams[i].rtp_port;
call->media_ports[i].mcast_rtcp_port=0;
}
}
}
LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, SalOp *op){
LinphoneCall *call = belle_sip_object_new(LinphoneCall);
const SalMediaDescription *md;
SalMediaDescription *md;
LinphoneFirewallPolicy fpol;
int i;
call->dir=LinphoneCallIncoming;
sal_op_set_user_pointer(op,call);
call->op=op;
call->core=lc;
linphone_call_incoming_select_ip_version(call);
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));
@ -1060,7 +1069,15 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro
// 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;i<md->nb_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));
}
}
}
fpol=linphone_core_get_firewall_policy(call->core);
/*create the ice session now if ICE is required*/
if (fpol==LinphonePolicyUseIce){
@ -1179,21 +1196,8 @@ static void linphone_call_set_terminated(LinphoneCall *call){
void linphone_call_fix_call_parameters(LinphoneCall *call){
if (sal_call_is_offerer(call->op)) {
/*get remote params*/
const LinphoneCallParams* lcp = linphone_call_get_remote_params(call);
call->current_params->video_declined = call->params->has_video && !lcp->has_video;
}
switch(call->params->media_encryption) {
case LinphoneMediaEncryptionZRTP:
case LinphoneMediaEncryptionDTLS:
case LinphoneMediaEncryptionNone:
/* do nothing */
break;
case LinphoneMediaEncryptionSRTP:
call->params->media_encryption=call->current_params->media_encryption;
break;
default:
ms_fatal("Unknown media encryption type on call [%p]", call);
break;
const LinphoneCallParams* rcp = linphone_call_get_remote_params(call);
call->current_params->video_declined = call->params->has_video && !rcp->has_video;
}
}
@ -1410,6 +1414,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);
}
/**
* Returns current parameters associated to the call.
@ -1431,20 +1443,36 @@ const LinphoneCallParams * linphone_call_get_current_params(LinphoneCall *call){
}
#endif
if (linphone_call_all_streams_encrypted(call)) {
if (linphone_call_get_authentication_token(call)) {
/* REVISITED
* Previous code was buggy.
* Relying on the mediastream's state (added by jehan: only) to know the current encryption is unreliable.
* For (added by jehan: both DTLS and) ZRTP it is though necessary.
* But for all others the current_params->media_encryption state should reflect (added by jehan: both) what is agreed by the offer/answer
* mechanism (added by jehan: and encryption status from media which is much stronger than only result of offer/answer )
* Typically there can be inactive streams for which the media layer has no idea of whether they are encrypted or not.
*/
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 {
/* TODO : check this or presence of dtls_fingerprint in the call? */
if (call->params->media_encryption == LinphoneMediaEncryptionDTLS) {
call->current_params->media_encryption=LinphoneMediaEncryptionDTLS;
} else {
call->current_params->media_encryption=LinphoneMediaEncryptionSRTP;
}
call->current_params->media_encryption=LinphoneMediaEncryptionNone;
}
} else {
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;
}
break;
case LinphoneMediaEncryptionNone:
call->current_params->media_encryption=LinphoneMediaEncryptionNone;
break;
}
call->current_params->avpf_enabled = linphone_call_all_streams_avpf_enabled(call);
if (call->current_params->avpf_enabled == TRUE) {
call->current_params->avpf_rr_interval = linphone_call_get_avpf_rr_interval(call);
@ -1452,10 +1480,23 @@ const LinphoneCallParams * linphone_call_get_current_params(LinphoneCall *call){
call->current_params->avpf_rr_interval = 0;
}
if (md){
const char *rtp_addr;
SalStreamDescription *sd=sal_media_description_find_best_stream(md,SalAudio);
call->current_params->audio_dir=sd ? media_direction_from_sal_stream_dir(sd->dir) : LinphoneMediaDirectionInactive;
if (call->current_params->audio_dir != LinphoneMediaDirectionInactive) {
rtp_addr = sd->rtp_addr[0]!='\0' ? sd->rtp_addr : call->resultdesc->addr;
call->current_params->audio_multicast_enabled = ms_is_multicast(rtp_addr);
} else
call->current_params->audio_multicast_enabled = FALSE;
sd=sal_media_description_find_best_stream(md,SalVideo);
call->current_params->video_dir=sd ? media_direction_from_sal_stream_dir(sd->dir) : LinphoneMediaDirectionInactive;
if (call->current_params->video_dir != LinphoneMediaDirectionInactive) {
rtp_addr = sd->rtp_addr[0]!='\0' ? sd->rtp_addr : call->resultdesc->addr;
call->current_params->video_multicast_enabled = ms_is_multicast(rtp_addr);
} else
call->current_params->video_multicast_enabled = FALSE;
}
return call->current_params;
@ -1844,7 +1885,7 @@ int linphone_call_prepare_ice(LinphoneCall *call, bool_t incoming_offer){
if ((linphone_core_get_firewall_policy(call->core) == LinphonePolicyUseIce) && (call->ice_session != NULL)){
if (incoming_offer){
remote=sal_call_get_remote_media_description(call->op);
has_video=call->params->has_video && linphone_core_media_description_contains_video_stream(remote);
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);
@ -1874,9 +1915,38 @@ int linphone_call_prepare_ice(LinphoneCall *call, bool_t incoming_offer){
/*eventually join to a multicast group if told to do so*/
static void linphone_call_join_multicast_group(LinphoneCall *call, int stream_index, MediaStream *ms){
if (call->media_ports[stream_index].multicast_ip[stream_index]!='\0' && call->media_ports[stream_index].mcast_rtp_port!=0){
if (call->media_ports[stream_index].multicast_ip[stream_index]!='\0'){
media_stream_join_multicast_group(ms, call->media_ports[stream_index].multicast_ip);
}
} else
ms_error("Cannot join multicast group if multicast ip is not set for call [%p]",call);
}
static SalMulticastRole linphone_call_get_multicast_role(const LinphoneCall *call,SalStreamType type) {
SalMulticastRole multicast_role=SalMulticastInactive;
SalMediaDescription *remotedesc, *localdesc;
SalStreamDescription *stream_desc = NULL;
if (!call->op) goto end;
remotedesc = sal_call_get_remote_media_description(call->op);
localdesc = call->localdesc;
if (!localdesc && !remotedesc && call->dir == LinphoneCallOutgoing) {
/*well using call dir*/
if ((type == SalAudio && linphone_call_params_audio_multicast_enabled(call->params))
|| (type == SalVideo && linphone_call_params_video_multicast_enabled(call->params)))
multicast_role=SalMulticastSender;
} else if (localdesc && (!remotedesc || sal_call_is_offerer(call->op))) {
stream_desc = sal_media_description_find_best_stream(localdesc, type);
} else if (!sal_call_is_offerer(call->op) && remotedesc)
stream_desc = sal_media_description_find_best_stream(remotedesc, type);
if (stream_desc)
multicast_role=stream_desc->multicast_role;
else
ms_message("Cannot determine multicast role for stream type [%s] on call [%p]",sal_stream_type_to_string(type),call);
end:
return multicast_role;
}
void linphone_call_init_audio_stream(LinphoneCall *call){
@ -1887,14 +1957,23 @@ 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){
SalMulticastRole multicast_role = linphone_call_get_multicast_role(call,SalAudio);
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, SalAudio);
call->audiostream=audiostream=audio_stream_new2(linphone_call_get_bind_ip_for_stream(call,0),
call->media_ports[0].mcast_rtp_port ? call->media_ports[0].mcast_rtp_port : call->media_ports[0].rtp_port,
call->media_ports[0].mcast_rtcp_port ? call->media_ports[0].mcast_rtcp_port : call->media_ports[0].rtcp_port);
linphone_call_join_multicast_group(call, 0, &audiostream->ms);
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);
if (multicast_role == SalMulticastReceiver)
linphone_call_join_multicast_group(call, 0, &audiostream->ms);
rtp_session_enable_network_simulation(call->audiostream->ms.sessions.rtp_session, &lc->net_conf.netsim_params);
cname = linphone_address_as_string_uri_only(call->me);
audio_stream_set_rtcp_information(call->audiostream, cname, rtcp_tool);
@ -1954,7 +2033,8 @@ void linphone_call_init_audio_stream(LinphoneCall *call){
audio_stream_set_echo_canceller_params(audiostream,len,delay,framesize);
if (audiostream->ec) {
char *statestr=ms_malloc0(EC_STATE_MAX_LEN);
if (lp_config_read_relative_file(lc->config, EC_STATE_STORE, statestr, EC_STATE_MAX_LEN) == 0) {
if (lp_config_relative_file_exists(lc->config, EC_STATE_STORE)
&& lp_config_read_relative_file(lc->config, EC_STATE_STORE, statestr, EC_STATE_MAX_LEN) == 0) {
ms_filter_call_method(audiostream->ec, MS_ECHO_CANCELLER_SET_STATE_STRING, statestr);
}
ms_free(statestr);
@ -1987,11 +2067,14 @@ void linphone_call_init_audio_stream(LinphoneCall *call){
_linphone_call_prepare_ice_for_stream(call,0,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){
@ -2000,10 +2083,18 @@ void linphone_call_init_video_stream(LinphoneCall *call){
const char *display_filter=linphone_core_get_video_display_filter(lc);
if (call->sessions[1].rtp_session==NULL){
SalMulticastRole multicast_role = linphone_call_get_multicast_role(call,SalVideo);
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, SalVideo);
call->videostream=video_stream_new2(linphone_call_get_bind_ip_for_stream(call,1),
call->media_ports[1].mcast_rtp_port>0 ? call->media_ports[1].mcast_rtp_port : call->media_ports[1].rtp_port,
call->media_ports[1].mcast_rtcp_port>0 ? call->media_ports[1].mcast_rtcp_port : call->media_ports[1].rtcp_port);
linphone_call_join_multicast_group(call, 1, &call->videostream->ms);
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);
if (multicast_role == SalMulticastReceiver)
linphone_call_join_multicast_group(call, 1, &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);
@ -2790,9 +2881,6 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut
video_stream_enable_zrtp(call->videostream,call->audiostream,&params);
}
#endif
}else if (call->params->media_encryption==LinphoneMediaEncryptionSRTP){
call->current_params->media_encryption=linphone_call_all_streams_encrypted(call) ?
LinphoneMediaEncryptionSRTP : LinphoneMediaEncryptionNone;
}
set_dtls_fingerprint_on_all_streams(call);
@ -3245,23 +3333,27 @@ 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 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
}
return rtp_stats;
}
/**
* Gets the cumulative number of late packets
* @return The cumulative number of late packets
**/
uint64_t linphone_call_stats_get_late_packets_cumulative_number(const LinphoneCallStats *stats, LinphoneCall *call) {
rtp_stats_t rtp_stats;
if (!stats || !call)
return 0;
memset(&rtp_stats, 0, sizeof(rtp_stats));
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
return rtp_stats.outoftime;
return linphone_call_stats_get_rtp_stats(stats, call).outoftime;
}
/**
@ -3739,7 +3831,7 @@ void linphone_call_zoom_video(LinphoneCall* call, float zoom_factor, float* cx,
static LinphoneAddress *get_fixed_contact(LinphoneCore *lc, LinphoneCall *call , LinphoneProxyConfig *dest_proxy){
LinphoneAddress *ctt=NULL;
LinphoneAddress *ret=NULL;
const char *localip=call->localip;
//const char *localip=call->localip;
/* first use user's supplied ip address if asked*/
if (linphone_core_get_firewall_policy(lc)==LinphonePolicyUseNatAddress){
@ -3762,9 +3854,9 @@ static LinphoneAddress *get_fixed_contact(LinphoneCore *lc, LinphoneCall *call ,
ctt=linphone_core_get_primary_contact_parsed(lc);
if (ctt!=NULL){
/*otherwise use supplied localip*/
linphone_address_set_domain(ctt,localip);
linphone_address_set_port(ctt,linphone_core_get_sip_port(lc));
ms_message("Contact has been fixed using local ip"/* to %s",ret*/);
linphone_address_set_domain(ctt,NULL/*localip*/);
linphone_address_set_port(ctt,-1/*linphone_core_get_sip_port(lc)*/);
ms_message("Contact has not been fixed stack will do"/* to %s",ret*/);
ret=ctt;
}
}

View file

@ -1253,6 +1253,7 @@ static void ui_config_read(LinphoneCore *lc)
int i;
for (i=0;(lf=linphone_friend_new_from_config_file(lc,i))!=NULL;i++){
linphone_core_add_friend(lc,lf);
linphone_friend_unref(lf);
}
call_logs_read_from_config_file(lc);
}
@ -3435,6 +3436,8 @@ int linphone_core_start_update_call(LinphoneCore *lc, LinphoneCall *call){
int err;
bool_t no_user_consent=call->params->no_user_consent;
linphone_call_fill_media_multicast_addr(call);
if (!no_user_consent) linphone_call_make_local_media_description(lc,call);
#ifdef BUILD_UPNP
if(call->upnp_session != NULL) {
@ -3562,10 +3565,11 @@ int linphone_core_update_call(LinphoneCore *lc, LinphoneCall *call, const Linpho
* When receiving a #LinphoneCallUpdatedByRemote state notification, prevent LinphoneCore from performing an automatic answer.
*
* When receiving a #LinphoneCallUpdatedByRemote state notification (ie an incoming reINVITE), the default behaviour of
* LinphoneCore is to automatically answer the reINIVTE with call parameters unchanged.
* LinphoneCore is defined by the "defer_update_default" option of the "sip" section of the config. If this option is 0 (the default)
* then the LinphoneCore automatically answers the reINIVTE with call parameters unchanged.
* However when for example when the remote party updated the call to propose a video stream, it can be useful
* to prompt the user before answering. This can be achieved by calling linphone_core_defer_call_update() during
* the call state notifiacation, to deactivate the automatic answer that would just confirm the audio but reject the video.
* the call state notification, to deactivate the automatic answer that would just confirm the audio but reject the video.
* Then, when the user responds to dialog prompt, it becomes possible to call linphone_core_accept_call_update() to answer
* the reINVITE, with eventually video enabled in the LinphoneCallParams argument.
*
@ -3591,6 +3595,7 @@ int linphone_core_start_accept_call_update(LinphoneCore *lc, LinphoneCall *call,
linphone_call_make_local_media_description(lc,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);
@ -3648,6 +3653,11 @@ int _linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, cons
}
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);
linphone_call_params_enable_video_multicast(call->params,FALSE);
}
}else
linphone_call_set_new_params(call,params);
@ -3659,6 +3669,9 @@ int _linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, cons
ms_warning("Video isn't supported in conference");
call->params->has_video = FALSE;
}
/*update multicast params according to call params*/
linphone_call_fill_media_multicast_addr(call);
linphone_call_init_media_streams(call); /*so that video stream is initialized if necessary*/
if (call->ice_session != NULL) {
if (linphone_call_prepare_ice(call,TRUE)==1)
@ -3718,6 +3731,7 @@ int linphone_core_accept_call_with_params(LinphoneCore *lc, LinphoneCall *call,
SalOp *replaced;
SalMediaDescription *new_md;
bool_t was_ringing=FALSE;
MSList * iterator;
if (call==NULL){
//if just one call is present answer the only one ...
@ -3738,6 +3752,28 @@ int linphone_core_accept_call_with_params(LinphoneCore *lc, LinphoneCall *call,
break;
}
for (iterator=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);
linphone_core_terminate_call(lc,a_call);
break;
default:
break; /*nothing to do*/
}
}
if (iterator) ms_list_free(iterator);
/* check if this call is supposed to replace an already running one*/
replaced=sal_call_get_replaces(call->op);
if (replaced){
@ -3794,6 +3830,7 @@ int linphone_core_accept_call_with_params(LinphoneCore *lc, LinphoneCall *call,
}
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;
@ -3987,27 +4024,34 @@ 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.");
return -1;
}
linphone_call_make_local_media_description(lc,call);
if (sal_media_description_has_dir(call->resultdesc, SalStreamSendRecv)) {
subject = "Call on hold";
} else if (sal_media_description_has_dir(call->resultdesc, SalStreamRecvOnly)) {
subject = "Call on hold for me too";
} else {
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);
#ifdef BUILD_UPNP
if(call->upnp_session != NULL) {
linphone_core_update_local_media_description_from_upnp(call->localdesc, call->upnp_session);
}
#endif //BUILD_UPNP
if (sal_media_description_has_dir(call->resultdesc,SalStreamSendRecv)){
sal_media_description_set_dir(call->localdesc,SalStreamSendOnly);
subject="Call on hold";
}else if (sal_media_description_has_dir(call->resultdesc,SalStreamRecvOnly)){
sal_media_description_set_dir(call->localdesc,SalStreamSendOnly);
subject="Call on hold for me too";
}else{
ms_error("No reason to pause this call, it is already paused or inactive.");
return -1;
}
sal_call_set_local_media_description(call->op,call->localdesc);
if (sal_call_update(call->op,subject,FALSE) != 0){
linphone_core_notify_display_warning(lc,_("Could not pause the call"));
@ -4127,9 +4171,17 @@ static int remote_address_compare(LinphoneCall *call, const LinphoneAddress *rad
* @ingroup call_control
*/
LinphoneCall *linphone_core_get_call_by_remote_address(LinphoneCore *lc, const char *remote_address){
LinphoneCall *call=NULL;
LinphoneAddress *raddr=linphone_address_new(remote_address);
if (raddr) {
call=linphone_core_get_call_by_remote_address2(lc, raddr);
linphone_address_unref(raddr);
}
return call;
}
LinphoneCall *linphone_core_get_call_by_remote_address2(LinphoneCore *lc, LinphoneAddress *raddr){
MSList *elem=ms_list_find_custom(lc->calls,(int (*)(const void*,const void *))remote_address_compare,raddr);
linphone_address_unref(raddr);
if (elem) return (LinphoneCall*) elem->data;
return NULL;
}
@ -4625,23 +4677,53 @@ const char** linphone_core_get_video_devices(const LinphoneCore *lc){
}
void linphone_core_reload_sound_devices(LinphoneCore *lc){
const char *ringer,*playback,*capture;
ringer=linphone_core_get_ringer_device(lc);
playback=linphone_core_get_playback_device(lc);
capture=linphone_core_get_capture_device(lc);
const char *ringer;
const char *playback;
const char *capture;
char *ringer_copy = NULL;
char *playback_copy = NULL;
char *capture_copy = NULL;
ringer = linphone_core_get_ringer_device(lc);
if (ringer != NULL) {
ringer_copy = ms_strdup(ringer);
}
playback = linphone_core_get_playback_device(lc);
if (playback != NULL) {
playback_copy = ms_strdup(playback);
}
capture = linphone_core_get_capture_device(lc);
if (capture != NULL) {
capture_copy = ms_strdup(capture);
}
ms_snd_card_manager_reload(ms_snd_card_manager_get());
build_sound_devices_table(lc);
linphone_core_set_ringer_device(lc,ringer);
linphone_core_set_playback_device(lc,playback);
linphone_core_set_capture_device(lc,capture);
if (ringer_copy != NULL) {
linphone_core_set_ringer_device(lc, ringer_copy);
ms_free(ringer_copy);
}
if (playback_copy != NULL) {
linphone_core_set_playback_device(lc, playback_copy);
ms_free(playback_copy);
}
if (capture_copy != NULL) {
linphone_core_set_capture_device(lc, capture_copy);
ms_free(capture_copy);
}
}
void linphone_core_reload_video_devices(LinphoneCore *lc){
const char *devid;
devid=linphone_core_get_video_device(lc);
char *devid_copy = NULL;
const char *devid = linphone_core_get_video_device(lc);
if (devid != NULL) {
devid_copy = ms_strdup(devid);
}
ms_web_cam_manager_reload(ms_web_cam_manager_get());
build_video_devices_table(lc);
linphone_core_set_video_device(lc,devid);
if (devid_copy != NULL) {
linphone_core_set_video_device(lc, devid_copy);
ms_free(devid_copy);
}
}
char linphone_core_get_sound_source(LinphoneCore *lc)
@ -6295,7 +6377,7 @@ void ui_config_uninit(LinphoneCore* lc)
{
ms_message("Destroying friends.");
if (lc->friends){
ms_list_for_each(lc->friends,(void (*)(void *))linphone_friend_destroy);
ms_list_for_each(lc->friends,(void (*)(void *))linphone_friend_unref);
ms_list_free(lc->friends);
lc->friends=NULL;
}
@ -6981,6 +7063,8 @@ void linphone_core_init_default_params(LinphoneCore*lc, LinphoneCallParams *para
params->audio_dir=LinphoneMediaDirectionSendRecv;
params->video_dir=LinphoneMediaDirectionSendRecv;
params->real_early_media=lp_config_get_int(lc->config,"misc","real_early_media",FALSE);
params->audio_multicast_enabled=linphone_core_audio_multicast_enabled(lc);
params->video_multicast_enabled=linphone_core_video_multicast_enabled(lc);
}
void linphone_core_set_device_identifier(LinphoneCore *lc,const char* device_id) {

View file

@ -183,7 +183,7 @@ typedef enum _LinphoneReason LinphoneReason;
* Converts a LinphoneReason enum to a string.
* @ingroup misc
**/
const char *linphone_reason_to_string(LinphoneReason err);
LINPHONE_PUBLIC const char *linphone_reason_to_string(LinphoneReason err);
/**
* Object representing full details about a signaling error or status.
@ -561,6 +561,7 @@ LINPHONE_PUBLIC float linphone_call_stats_get_sender_loss_rate(const LinphoneCal
LINPHONE_PUBLIC float linphone_call_stats_get_receiver_loss_rate(const LinphoneCallStats *stats);
LINPHONE_PUBLIC float linphone_call_stats_get_sender_interarrival_jitter(const LinphoneCallStats *stats, LinphoneCall *call);
LINPHONE_PUBLIC float linphone_call_stats_get_receiver_interarrival_jitter(const LinphoneCallStats *stats, LinphoneCall *call);
LINPHONE_PUBLIC rtp_stats_t linphone_call_stats_get_rtp_stats(const LinphoneCallStats *statss, LinphoneCall *call);
LINPHONE_PUBLIC uint64_t linphone_call_stats_get_late_packets_cumulative_number(const LinphoneCallStats *stats, LinphoneCall *call);
LINPHONE_PUBLIC float linphone_call_stats_get_download_bandwidth(const LinphoneCallStats *stats);
LINPHONE_PUBLIC float linphone_call_stats_get_upload_bandwidth(const LinphoneCallStats *stats);
@ -1076,9 +1077,10 @@ LINPHONE_PUBLIC bool_t linphone_proxy_config_is_phone_number(LinphoneProxyConfig
/**
* Normalize a human readable phone number into a basic string. 888-444-222 becomes 888444222
* or +33888444222 depending on the #LinphoneProxyConfig argument. 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.
* 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
@ -1623,7 +1625,7 @@ typedef enum _LinphoneGlobalState{
LinphoneGlobalConfiguring
}LinphoneGlobalState;
const char *linphone_global_state_to_string(LinphoneGlobalState gs);
LINPHONE_PUBLIC const char *linphone_global_state_to_string(LinphoneGlobalState gs);
/**
* LinphoneCoreLogCollectionUploadState is used to notify if log collection upload have been succesfully delivered or not.
@ -2235,6 +2237,17 @@ LINPHONE_PUBLIC LinphoneCallParams *linphone_core_create_call_params(LinphoneCor
LINPHONE_PUBLIC LinphoneCall *linphone_core_get_call_by_remote_address(LinphoneCore *lc, const char *remote_address);
/**
* Get the call with the remote_address specified
* @param lc
* @param remote_address
* @return the LinphoneCall of the call if found
*
* @ingroup call_control
*/
LINPHONE_PUBLIC LinphoneCall *linphone_core_get_call_by_remote_address2(LinphoneCore *lc, LinphoneAddress *remote_address);
/**
* Send the specified dtmf.
*
@ -2770,10 +2783,10 @@ LINPHONE_PUBLIC void linphone_core_enable_mic(LinphoneCore *lc, bool_t enable);
**/
LINPHONE_PUBLIC bool_t linphone_core_mic_enabled(LinphoneCore *lc);
bool_t linphone_core_is_rtp_muted(LinphoneCore *lc);
LINPHONE_PUBLIC bool_t linphone_core_is_rtp_muted(LinphoneCore *lc);
bool_t linphone_core_get_rtp_no_xmit_on_audio_mute(const LinphoneCore *lc);
void linphone_core_set_rtp_no_xmit_on_audio_mute(LinphoneCore *lc, bool_t val);
LINPHONE_PUBLIC bool_t linphone_core_get_rtp_no_xmit_on_audio_mute(const LinphoneCore *lc);
LINPHONE_PUBLIC void linphone_core_set_rtp_no_xmit_on_audio_mute(LinphoneCore *lc, bool_t val);
/*******************************************************************************
@ -3129,7 +3142,7 @@ LINPHONE_PUBLIC int linphone_core_get_calls_nb(const LinphoneCore *lc);
LINPHONE_PUBLIC const MSList *linphone_core_get_calls(LinphoneCore *lc);
LinphoneGlobalState linphone_core_get_global_state(const LinphoneCore *lc);
LINPHONE_PUBLIC LinphoneGlobalState linphone_core_get_global_state(const LinphoneCore *lc);
/**
* force registration refresh to be initiated upon next iterate
* @ingroup proxies

View file

@ -250,6 +250,32 @@ jobject getChatMessage(JNIEnv *env, LinphoneChatMessage *msg){
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,"<init>", "(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);
@ -729,7 +755,7 @@ public:
env->CallVoidMethod(lcData->listener
,lcData->notifyPresenceReceivedId
,lcData->core
,env->NewObject(lcData->friendClass,lcData->friendCtrId,(jlong)my_friend));
,getFriend(env,my_friend));
if (env->ExceptionCheck()) {
ms_error("Listener %p raised an exception",lcData->listener);
env->ExceptionClear();
@ -747,7 +773,7 @@ public:
env->CallVoidMethod(lcData->listener
,lcData->newSubscriptionRequestId
,lcData->core
,env->NewObject(lcData->friendClass,lcData->friendCtrId,(jlong)my_friend)
,getFriend(env,my_friend)
,url ? env->NewStringUTF(url) : NULL);
if (env->ExceptionCheck()) {
ms_error("Listener %p raised an exception",lcData->listener);
@ -1023,12 +1049,16 @@ public:
}
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,
lcData->core,
(jmsg = getChatMessage(env, message)),
content ? create_java_linphone_content(env, content) : NULL,
jcontent,
progress);
if (jcontent) {
env->DeleteLocalRef(jcontent);
}
}
static void fileTransferSend(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, char* buff, size_t* size) {
@ -1042,13 +1072,21 @@ public:
}
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,
lcData->core,
(jmsg = getChatMessage(env, message)),
content ? create_java_linphone_content(env, content) : NULL,
buff ? env->NewDirectByteBuffer(buff, asking) : NULL,
jcontent,
jbuffer,
asking);
if (jcontent) {
env->DeleteLocalRef(jcontent);
}
if (jbuffer) {
env->DeleteLocalRef(jbuffer);
}
}
static void fileTransferRecv(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, const char* buff, size_t size) {
@ -1064,14 +1102,18 @@ public:
jbyteArray jbytes = env->NewByteArray(size);
env->SetByteArrayRegion(jbytes, 0, size, (jbyte*)buff);
jobject jcontent = content ? create_java_linphone_content(env, content) : NULL;
env->CallVoidMethod(lcData->listener,
lcData->fileTransferRecvId,
lcData->core,
(jmsg = getChatMessage(env, message)),
content ? create_java_linphone_content(env, content) : NULL,
jcontent,
jbytes,
size);
if (jcontent) {
env->DeleteLocalRef(jcontent);
}
}
static void logCollectionUploadProgressIndication(LinphoneCore *lc, size_t offset, size_t total) {
JNIEnv *env = 0;
@ -1810,6 +1852,26 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_addFriend(JNIEnv* env
) {
linphone_core_add_friend((LinphoneCore*)lc,(LinphoneFriend*)aFriend);
}
extern "C" jobjectArray Java_org_linphone_core_LinphoneCoreImpl_getFriendList(JNIEnv* env
,jobject thiz
,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);
for (int i = 0; i < friendsSize; i++) {
LinphoneFriend* lfriend = (LinphoneFriend*)friends->data;
jobject jfriend = getFriend(env,lfriend);
if(jfriend != NULL){
env->SetObjectArrayElement(jFriends, i, jfriend);
}
friends = friends->next;
}
env->DeleteGlobalRef(cls);
return jFriends;
}
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setPresenceInfo(JNIEnv* env
,jobject thiz
,jlong lc
@ -2837,10 +2899,12 @@ extern "C" jlong Java_org_linphone_core_LinphoneFriendImpl_newLinphoneFriend(JNI
if (jFriendUri) {
const char* friendUri = env->GetStringUTFChars(jFriendUri, NULL);
lResult= linphone_friend_new_with_address(friendUri);
lResult = linphone_friend_new_with_address(friendUri);
linphone_friend_set_user_data(lResult,env->NewWeakGlobalRef(thiz));
env->ReleaseStringUTFChars(jFriendUri, friendUri);
} else {
lResult = linphone_friend_new();
linphone_friend_set_user_data(lResult,env->NewWeakGlobalRef(thiz));
}
return (jlong)lResult;
}
@ -2908,6 +2972,14 @@ extern "C" jstring Java_org_linphone_core_LinphoneFriendImpl_getRefKey(JNIEnv*
}
extern "C" void Java_org_linphone_core_LinphoneFriendImpl_finalize(JNIEnv* env
,jobject thiz
,jlong ptr) {
LinphoneFriend *lfriend=(LinphoneFriend*)ptr;
linphone_friend_set_user_data(lfriend,NULL);
linphone_friend_unref(lfriend);
}
/*
* Class: org_linphone_core_LinphoneFriendImpl
* Method: getPresenceModel
@ -2936,14 +3008,19 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_removeFriend(JNIEnv* en
,jlong lf) {
linphone_core_remove_friend((LinphoneCore*)ptr, (LinphoneFriend*)lf);
}
extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_getFriendByAddress(JNIEnv* env
extern "C" jobject Java_org_linphone_core_LinphoneCoreImpl_getFriendByAddress(JNIEnv* env
,jobject thiz
,jlong ptr
,jstring jaddress) {
const char* address = env->GetStringUTFChars(jaddress, NULL);
LinphoneFriend *lf = linphone_core_get_friend_by_address((LinphoneCore*)ptr, address);
env->ReleaseStringUTFChars(jaddress, address);
return (jlong) lf;
if(lf != NULL) {
jobject jfriend = getFriend(env,lf);
return jfriend;
} else {
return NULL;
}
}
extern "C" jlongArray _LinphoneChatRoomImpl_getHistory(JNIEnv* env
@ -3255,14 +3332,16 @@ static void message_state_changed(LinphoneChatMessage* msg, LinphoneChatMessageS
jclass clazz = (jclass) env->GetObjectClass(listener);
jmethodID method = env->GetMethodID(clazz, "onLinphoneChatMessageStateChanged","(Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneChatMessage$State;)V");
jobject jmessage = getChatMessage(env, msg);
jclass chatMessageStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneChatMessage$State"));
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));
if (state == LinphoneChatMessageStateDelivered || state == LinphoneChatMessageStateNotDelivered) {
env->DeleteGlobalRef(listener);
}
env->DeleteLocalRef(chatMessageStateClass);
}
static void file_transfer_progress_indication(LinphoneChatMessage *msg, const LinphoneContent* content, size_t offset, size_t total) {
@ -3276,8 +3355,13 @@ static void file_transfer_progress_indication(LinphoneChatMessage *msg, const Li
jobject listener = (jobject) msg->cb_ud;
jclass clazz = (jclass) env->GetObjectClass(listener);
jmethodID method = env->GetMethodID(clazz, "onLinphoneChatMessageFileTransferProgressChanged", "(Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneContent;II)V");
env->DeleteLocalRef(clazz);
jobject jmessage = getChatMessage(env, msg);
env->CallVoidMethod(listener, method, jmessage, content ? create_java_linphone_content(env, content) : NULL, offset, total);
jobject jcontent = content ? create_java_linphone_content(env, content) : NULL;
env->CallVoidMethod(listener, method, jmessage, jcontent, offset, total);
if (jcontent) {
env->DeleteLocalRef(jcontent);
}
}
static void file_transfer_recv(LinphoneChatMessage *msg, const LinphoneContent* content, const LinphoneBuffer *buffer) {
@ -3291,8 +3375,18 @@ static void file_transfer_recv(LinphoneChatMessage *msg, const LinphoneContent*
jobject listener = (jobject) msg->cb_ud;
jclass clazz = (jclass) env->GetObjectClass(listener);
jmethodID method = env->GetMethodID(clazz, "onLinphoneChatMessageFileTransferReceived", "(Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneContent;Lorg/linphone/core/LinphoneBuffer;)V");
env->DeleteLocalRef(clazz);
jobject jmessage = getChatMessage(env, msg);
env->CallVoidMethod(listener, method, jmessage, content ? create_java_linphone_content(env, content) : NULL, buffer ? create_java_linphone_buffer(env, buffer) : NULL);
jobject jbuffer = buffer ? create_java_linphone_buffer(env, buffer) : NULL;
jobject jcontent = content ? create_java_linphone_content(env, content) : NULL;
env->CallVoidMethod(listener, method, jmessage, jcontent, jbuffer);
if (jbuffer) {
env->DeleteLocalRef(jbuffer);
}
if (jcontent) {
env->DeleteLocalRef(jcontent);
}
}
static LinphoneBuffer* file_transfer_send(LinphoneChatMessage *msg, const LinphoneContent* content, size_t offset, size_t size) {
@ -3307,11 +3401,18 @@ static LinphoneBuffer* file_transfer_send(LinphoneChatMessage *msg, const Linph
jobject listener = (jobject) msg->cb_ud;
jclass clazz = (jclass) env->GetObjectClass(listener);
jmethodID method = env->GetMethodID(clazz, "onLinphoneChatMessageFileTransferSent","(Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneContent;IILorg/linphone/core/LinphoneBuffer;)V");
env->DeleteLocalRef(clazz);
jobject jmessage = getChatMessage(env, msg);
jobject jbuffer = create_java_linphone_buffer(env, NULL);
env->CallVoidMethod(listener, method, jmessage, content ? create_java_linphone_content(env, content) : NULL, offset, size, jbuffer);
jobject jcontent = content ? create_java_linphone_content(env, content) : NULL;
env->CallVoidMethod(listener, method, jmessage, jcontent, offset, size, jbuffer);
if (jcontent) {
env->DeleteLocalRef(jcontent);
}
buffer = create_c_linphone_buffer_from_java_linphone_buffer(env, jbuffer);
env->DeleteLocalRef(jbuffer);
return buffer;
}
@ -3385,6 +3486,7 @@ static void chat_room_impl_callback(LinphoneChatMessage* msg, LinphoneChatMessag
if (state == LinphoneChatMessageStateDelivered || state == LinphoneChatMessageStateNotDelivered) {
env->DeleteGlobalRef(listener);
env->DeleteGlobalRef(jmessage);
env->DeleteGlobalRef(chatMessageStateClass);
linphone_chat_message_set_user_data(msg,NULL);
}
}
@ -3570,6 +3672,19 @@ extern "C" jboolean Java_org_linphone_core_LinphoneCallParamsImpl_getVideoEnable
return (jboolean)linphone_call_params_video_enabled((LinphoneCallParams*)lcp);
}
extern "C" void Java_org_linphone_core_LinphoneCallParamsImpl_enableVideoMulticast(JNIEnv *env, jobject thiz, jlong lcp, jboolean b){
linphone_call_params_enable_video_multicast((LinphoneCallParams*)lcp, b);
}
extern "C" jboolean Java_org_linphone_core_LinphoneCallParamsImpl_videoMulticastEnabled(JNIEnv *env, jobject thiz, jlong lcp){
return (jboolean)linphone_call_params_video_multicast_enabled((LinphoneCallParams*)lcp);
}
extern "C" void Java_org_linphone_core_LinphoneCallParamsImpl_enableAudioMulticast(JNIEnv *env, jobject thiz, jlong lcp, jboolean b){
linphone_call_params_enable_audio_multicast((LinphoneCallParams*)lcp, b);
}
extern "C" jboolean Java_org_linphone_core_LinphoneCallParamsImpl_audioMulticastEnabled(JNIEnv *env, jobject thiz, jlong lcp){
return (jboolean)linphone_call_params_audio_multicast_enabled((LinphoneCallParams*)lcp);
}
extern "C" jboolean Java_org_linphone_core_LinphoneCallParamsImpl_localConferenceMode(JNIEnv *env, jobject thiz, jlong lcp){
return (jboolean)linphone_call_params_get_local_conference_mode((LinphoneCallParams*)lcp);
}
@ -3802,6 +3917,17 @@ JNIEXPORT jstring JNICALL Java_org_linphone_core_LinphoneProxyConfigImpl_getReal
return jvalue;
}
JNIEXPORT jboolean JNICALL Java_org_linphone_core_LinphoneProxyConfigImpl_isPhoneNumber(JNIEnv *env, jobject thiz, jlong ptr, jstring jusername) {
if(jusername){
const char *username=env->GetStringUTFChars(jusername, NULL);
bool_t res = linphone_proxy_config_is_phone_number((LinphoneProxyConfig *)ptr, username);
env->ReleaseStringUTFChars(jusername,username);
return (jboolean) res;
} else {
return JNI_FALSE;
}
}
extern "C" jint Java_org_linphone_core_LinphoneCallImpl_getDuration(JNIEnv* env,jobject thiz,jlong ptr) {
return (jint)linphone_call_get_duration((LinphoneCall *) ptr);
}
@ -4088,6 +4214,7 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_tunnelAddServer(JNIEnv *
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");
}
@ -4117,6 +4244,7 @@ extern "C" jobjectArray Java_org_linphone_core_LinphoneCoreImpl_tunnelGetServers
env->CallVoidMethod(elt, setRemoteUdpMirrorPortMethod, linphone_tunnel_config_get_remote_udp_mirror_port(conf));
env->CallVoidMethod(elt, setDelayMethod, linphone_tunnel_config_get_delay(conf));
env->SetObjectArrayElement(tunnelConfigArray, i, elt);
env->DeleteLocalRef(TunnelConfigClass);
}
}
return tunnelConfigArray;
@ -4548,7 +4676,7 @@ static jobject create_java_linphone_content(JNIEnv *env, const LinphoneContent *
jint jsize = 0;
const LinphoneContentPrivate *content = LINPHONE_CONTENT_PRIVATE(icontent);
contentClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneContentImpl"));
contentClass = (jclass)env->FindClass("org/linphone/core/LinphoneContentImpl");
ctor = env->GetMethodID(contentClass,"<init>", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[BLjava/lang/String;I)V");
jtype = env->NewStringUTF(content->type);
@ -4563,7 +4691,17 @@ static jobject create_java_linphone_content(JNIEnv *env, const LinphoneContent *
}
jobject jobj = env->NewObject(contentClass, ctor, jname, jtype, jsubtype, jdata, jencoding, jsize);
env->DeleteGlobalRef(contentClass);
env->DeleteLocalRef(contentClass);
env->DeleteLocalRef(jtype);
env->DeleteLocalRef(jsubtype);
if (jencoding) {
env->DeleteLocalRef(jencoding);
}
if (jname) {
env->DeleteLocalRef(jname);
}
return jobj;
}
@ -4573,7 +4711,7 @@ static jobject create_java_linphone_buffer(JNIEnv *env, const LinphoneBuffer *bu
jbyteArray jdata = NULL;
jint jsize = 0;
bufferClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneBufferImpl"));
bufferClass = (jclass)env->FindClass("org/linphone/core/LinphoneBufferImpl");
ctor = env->GetMethodID(bufferClass,"<init>", "([BI)V");
jsize = buffer ? (jint) buffer->size : 0;
@ -4583,32 +4721,32 @@ static jobject create_java_linphone_buffer(JNIEnv *env, const LinphoneBuffer *bu
}
jobject jobj = env->NewObject(bufferClass, ctor, jdata, jsize);
env->DeleteGlobalRef(bufferClass);
env->DeleteLocalRef(bufferClass);
return jobj;
}
static LinphoneBuffer* create_c_linphone_buffer_from_java_linphone_buffer(JNIEnv *env, jobject jbuffer) {
jclass bufferClass;
jmethodID getSizeMethod, getDataMethod;
LinphoneBuffer *buffer;
LinphoneBuffer *buffer = NULL;
jint jsize;
jobject jdata;
jbyteArray jcontent;
uint8_t *content;
bufferClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneBufferImpl"));
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<jbyteArray>(jdata);
content = (uint8_t*)env->GetByteArrayElements(jcontent, NULL);
buffer = linphone_buffer_new_from_data(content, (size_t)jsize);
env->ReleaseByteArrayElements(jcontent, (jbyte*)content, JNI_ABORT);
env->DeleteGlobalRef(bufferClass);
if (jcontent != NULL) {
content = (uint8_t*)env->GetByteArrayElements(jcontent, NULL);
buffer = linphone_buffer_new_from_data(content, (size_t)jsize);
env->ReleaseByteArrayElements(jcontent, (jbyte*)content, JNI_ABORT);
}
env->DeleteLocalRef(bufferClass);
return buffer;
}

View file

@ -135,8 +135,9 @@ LINPHONE_PUBLIC LinphoneFriend *linphone_friend_new_with_address(const char *add
#define linphone_friend_new_with_addr linphone_friend_new_with_address
/**
* Destructor
* @param lf #LinphoneFriend object
* Destroy a LinphoneFriend.
* @param lf LinphoneFriend object
* @deprecated Use linphone_friend_unref() instead.
*/
LINPHONE_PUBLIC void linphone_friend_destroy(LinphoneFriend *lf);
@ -393,6 +394,18 @@ LINPHONE_PUBLIC LinphoneFriend *linphone_core_find_friend(const LinphoneCore *lc
*/
LINPHONE_PUBLIC LinphoneFriend *linphone_core_get_friend_by_ref_key(const LinphoneCore *lc, const char *key);
/**
* Acquire a reference to the linphone friend.
* @param[in] lf LinphoneFriend object
* @return The same LinphoneFriend object
**/
LINPHONE_PUBLIC LinphoneFriend * linphone_friend_ref(LinphoneFriend *lf);
/**
* Release a reference to the linphone friend.
* @param[in] lf LinohoneFriend object
**/
LINPHONE_PUBLIC void linphone_friend_unref(LinphoneFriend *lf);
/**
* Returns the LinphoneCore object managing this friend, if any.

View file

@ -100,7 +100,7 @@ LpItem * lp_comment_new(const char *comment){
pos=strchr(item->value,'\r');
if (pos==NULL)
pos=strchr(item->value,'\n');
if(pos) {
*pos='\0'; /*replace the '\n' */
}
@ -362,7 +362,7 @@ LpConfig *lp_config_new_with_factory(const char *config_filename, const char *fa
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 !defined(WIN32)
{
struct stat fileStat;
@ -719,7 +719,24 @@ static char *_lp_config_dirname(char *path) {
#endif
}
bool_t lp_config_relative_file_exists(const LpConfig *lpconfig, const char *filename) {
if (lpconfig->filename == NULL) {
return FALSE;
} else {
char *dir = _lp_config_dirname(lpconfig->filename);
char *filepath = ms_strdup_printf("%s/%s", dir, filename);
FILE *file = fopen(filepath, "r");
ms_free(dir);
ms_free(filepath);
if (file) {
fclose(file);
}
return file != NULL;
}
}
void lp_config_write_relative_file(const LpConfig *lpconfig, const char *filename, const char *data) {
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);
@ -759,7 +776,7 @@ int lp_config_read_relative_file(const LpConfig *lpconfig, const char *filename,
ms_free(dir);
ms_free(filepath);
return 0;
err:
ms_free(dir);
ms_free(filepath);

View file

@ -290,6 +290,11 @@ LINPHONE_PUBLIC void lp_config_write_relative_file(const LpConfig *lpconfig, con
*/
LINPHONE_PUBLIC int lp_config_read_relative_file(const LpConfig *lpconfig, const char *filename, char *data, size_t max_length);
/**
* @return TRUE if file exists relative to the to the current location
**/
LINPHONE_PUBLIC bool_t lp_config_relative_file_exists(const LpConfig *lpconfig, const char *filename);
#ifdef __cplusplus
}
#endif

View file

@ -59,6 +59,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define RTP_HDR_SZ 12
#define IP4_HDR_SZ 20 /*20 is the minimum, but there may be some options*/
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)){
@ -716,8 +717,26 @@ void linphone_core_update_ice_state_in_call_stats(LinphoneCall *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));
}
void _update_local_media_description_from_ice(SalMediaDescription *desc, IceSession *session)
{
void linphone_call_stop_ice_for_inactive_streams(LinphoneCall *call) {
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++) {
IceCheckList *cl = ice_session_check_list(session, i);
if (!sal_stream_description_active(&desc->streams[i]) && cl) {
ice_session_remove_check_list(session, cl);
clear_ice_check_list(call, cl);
}
}
linphone_core_update_ice_state_in_call_stats(call);
}
void _update_local_media_description_from_ice(SalMediaDescription *desc, IceSession *session) {
const char *rtp_addr, *rtcp_addr;
IceSessionState session_state = ice_session_state(session);
int nb_candidates;

View file

@ -112,7 +112,8 @@ struct _LinphoneCallParams{
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 video_multicast_enabled;
bool_t audio_multicast_enabled;
};
BELLE_SIP_DECLARE_VPTR(LinphoneCallParams);
@ -205,8 +206,6 @@ typedef struct StunCandidate{
typedef struct _PortConfig{
char multicast_ip[LINPHONE_IPADDR_SIZE];
int mcast_rtp_port;
int mcast_rtcp_port;
int rtp_port;
int rtcp_port;
}PortConfig;
@ -227,7 +226,7 @@ struct _LinphoneCall{
LinphoneAddress *me; /*Either from or to based on call dir*/
SalOp *op;
SalOp *ping_op;
char localip[LINPHONE_IPADDR_SIZE]; /* our best guess for local ipaddress for this call */
char media_localip[LINPHONE_IPADDR_SIZE]; /* our best guess for local media ipaddress for this call */
LinphoneCallState state;
LinphoneCallState prevstate;
LinphoneCallState transfer_state; /*idle if no transfer*/
@ -395,6 +394,7 @@ void linphone_core_adapt_to_network(LinphoneCore *lc, int ping_time_ms, Linphone
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 _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);
@ -414,8 +414,6 @@ void linphone_core_get_local_ip(LinphoneCore *lc, int af, const char *dest, char
LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(LinphoneCore *lc, int index);
void linphone_proxy_config_write_to_config_file(struct _LpConfig* config,LinphoneProxyConfig *obj, int index);
bool_t linphone_proxy_config_normalize_number(LinphoneProxyConfig *cfg, const char *username, char *result, size_t result_len);
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);
@ -552,6 +550,8 @@ BELLE_SIP_DECLARE_VPTR(LinphoneChatRoom);
struct _LinphoneFriend{
belle_sip_object_t base;
void *user_data;
LinphoneAddress *uri;
SalOp *insub;
SalOp *outsub;
@ -560,7 +560,6 @@ struct _LinphoneFriend{
struct _LinphoneCore *lc;
BuddyInfo *info;
char *refkey;
void *up;
bool_t subscribe;
bool_t subscribe_active;
bool_t inc_subscribe_pending;
@ -568,6 +567,8 @@ struct _LinphoneFriend{
bool_t initial_subscribes_sent; /*used to know if initial subscribe message was sent or not*/
};
BELLE_SIP_DECLARE_VPTR(LinphoneFriend);
typedef struct sip_config
{
@ -776,7 +777,7 @@ struct _LinphoneCore
char* user_certificates_path;
LinphoneVideoPolicy video_policy;
time_t network_last_check;
bool_t use_files;
bool_t apply_nat_settings;
bool_t initial_subscribes_sent;
@ -786,7 +787,7 @@ struct _LinphoneCore
bool_t auto_net_state_mon;
bool_t network_reachable;
bool_t network_reachable_to_be_notified; /*set to true when state must be notified in next iterate*/
bool_t use_preview_window;
bool_t network_last_status;
bool_t ringstream_autorelease;
@ -855,7 +856,9 @@ 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_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);
bool_t linphone_core_is_payload_type_usable_for_bandwidth(LinphoneCore *lc, const PayloadType *pt, int bandwidth_limit);
@ -1079,7 +1082,8 @@ BELLE_SIP_TYPE_ID(LinphoneChatRoom),
BELLE_SIP_TYPE_ID(LinphoneContent),
BELLE_SIP_TYPE_ID(LinphoneLDAPContactProvider),
BELLE_SIP_TYPE_ID(LinphoneLDAPContactSearch),
BELLE_SIP_TYPE_ID(LinphoneProxyConfig)
BELLE_SIP_TYPE_ID(LinphoneProxyConfig),
BELLE_SIP_TYPE_ID(LinphoneFriend)
BELLE_SIP_DECLARE_TYPES_END

View file

@ -937,11 +937,12 @@ static void replace_icp(const char *src, char *dest, size_t destlen, const char
}
bool_t linphone_proxy_config_normalize_number(LinphoneProxyConfig *proxy, const char *username, char *result, size_t result_len){
bool_t linphone_proxy_config_normalize_number(LinphoneProxyConfig *inproxy, const char *username, char *result, size_t result_len){
bool_t ret;
LinphoneProxyConfig *proxy = inproxy ? inproxy : linphone_proxy_config_new();
memset(result, 0, result_len);
if (linphone_proxy_config_is_phone_number(proxy, username)){
char *flatten;
flatten=flatten_number(username);
char *flatten=flatten_number(username);
ms_debug("Flattened number is '%s'",flatten);
if (proxy->dial_prefix==NULL || proxy->dial_prefix[0]=='\0'){
@ -987,11 +988,13 @@ bool_t linphone_proxy_config_normalize_number(LinphoneProxyConfig *proxy, const
}
}
ms_free(flatten);
return TRUE;
ret = TRUE;
} else {
strncpy(result,username,result_len-1);
return FALSE;
ret = FALSE;
}
if (inproxy==NULL) ms_free(proxy);
return ret;
}
/**

View file

@ -307,6 +307,8 @@ int sal_stream_description_equals(const SalStreamDescription *sd1, const SalStre
if (sd1->type != sd2->type) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
if (strcmp(sd1->rtp_addr, sd2->rtp_addr) != 0) result |= SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED;
if (sd1->rtp_addr[0]!='\0' && sd2->rtp_addr[0]!='\0' && ms_is_multicast(sd1->rtp_addr) != ms_is_multicast(sd2->rtp_addr))
result |= SAL_MEDIA_DESCRIPTION_NETWORK_XXXCAST_CHANGED;
if (sd1->rtp_port != sd2->rtp_port) {
if ((sd1->rtp_port == 0) || (sd2->rtp_port == 0)) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
else result |= SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED;
@ -330,6 +332,8 @@ int sal_media_description_equals(const SalMediaDescription *md1, const SalMediaD
int i;
if (strcmp(md1->addr, md2->addr) != 0) result |= SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED;
if (md1->addr[0]!='\0' && md2->addr[0]!='\0' && ms_is_multicast(md1->addr) != ms_is_multicast(md2->addr))
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){

View file

@ -45,6 +45,11 @@ etc/gtk-2.0/gtk.immodules
etc/gtk-2.0/im-multipress.conf
etc/pango
etc/pango/pango.modules
share/locale/ar/LC_MESSAGES/atk10.mo
share/locale/ar/LC_MESSAGES/gdk-pixbuf.mo
share/locale/ar/LC_MESSAGES/glib20.mo
share/locale/ar/LC_MESSAGES/gtk20-properties.mo
share/locale/ar/LC_MESSAGES/gtk20.mo
share/locale/cs
share/locale/cs/LC_MESSAGES
share/locale/cs/LC_MESSAGES/atk10.mo
@ -171,6 +176,12 @@ share/locale/sv/LC_MESSAGES/gettext-runtime.mo
share/locale/sv/LC_MESSAGES/glib20.mo
share/locale/sv/LC_MESSAGES/gtk20-properties.mo
share/locale/sv/LC_MESSAGES/gtk20.mo
share/locale/tr/LC_MESSAGES/atk10.mo
share/locale/tr/LC_MESSAGES/gdk-pixbuf.mo
share/locale/tr/LC_MESSAGES/gettext-runtime.mo
share/locale/tr/LC_MESSAGES/glib20.mo
share/locale/tr/LC_MESSAGES/gtk20-properties.mo
share/locale/tr/LC_MESSAGES/gtk20.mo
share/locale/zh_CN
share/locale/zh_CN/LC_MESSAGES
share/locale/zh_CN/LC_MESSAGES/atk10.mo

View file

@ -64,6 +64,8 @@ set(SOURCE_FILES
main.c
propertybox.c
singleinstance.c
status_icon.c
status_notifier.c
support.c
update.c
utils.c

View file

@ -55,7 +55,15 @@ linphone_SOURCES= \
config-fetching.c \
audio_assistant.c \
videowindow.c \
status_icon.c status_icon.h \
linphone.h
if BUILD_STATUS_NOTIFIER
linphone_SOURCES+= \
status_notifier.c \
status_notifier.h
endif
if BUILD_WIZARD
linphone_SOURCES+= \
setupwizard.c

View file

@ -147,7 +147,7 @@ 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);
g_free(name);
ms_free(name);
}
}
if (call_label){

View file

@ -294,6 +294,8 @@ void linphone_gtk_compose_text(void) {
LinphoneChatRoom *cr=g_object_get_data(G_OBJECT(w),"cr");
if (cr) {
linphone_chat_room_compose(cr);
linphone_chat_room_mark_as_read(cr);
linphone_gtk_friend_list_update_chat_picture();
}
}
@ -422,7 +424,7 @@ GtkWidget* linphone_gtk_init_chatroom(LinphoneChatRoom *cr, const LinphoneAddres
display_history_message(chat_view,messages,with);
button = linphone_gtk_get_widget(chat_view,"send");
g_signal_connect_swapped(G_OBJECT(button),"clicked",(GCallback)linphone_gtk_send_text,NULL);
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);

View file

@ -55,6 +55,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <locale.h>
#endif
#include "status_icon.h"
const char *this_program_ident_string="linphone_ident_string=" LINPHONE_VERSION;
@ -220,7 +221,7 @@ static const char *linphone_gtk_get_factory_config_file(){
basename ++;
*basename = '\0';
snprintf(_factory_config_file, sizeof(_factory_config_file),
"%s/../share/Linphone/%s", progdir, FACTORY_CONFIG_FILE);
"%s/../share/linphone/%s", progdir, FACTORY_CONFIG_FILE);
} else {
free(progdir);
return NULL;
@ -342,7 +343,7 @@ static void linphone_gtk_configure_window(GtkWidget *w, const char *window_name)
linphone_gtk_visibility_set(shown,window_name,w,TRUE);
if (icon_path) {
GdkPixbuf *pbuf=create_pixbuf(icon_path);
if(pbuf != NULL) {
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);
@ -351,9 +352,7 @@ static void linphone_gtk_configure_window(GtkWidget *w, const char *window_name)
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_object_unref(G_OBJECT(pbuf_16));
g_object_unref(G_OBJECT(pbuf_32));
g_object_unref(G_OBJECT(pbuf));
g_list_foreach(pbuf_list, (GFunc)g_object_unref,NULL);
g_list_free(pbuf_list);
}
}
@ -545,7 +544,10 @@ void linphone_gtk_show_about(void){
gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(about),LIBLINPHONE_GIT_VERSION);
gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(about),linphone_gtk_get_ui_config("title","Linphone"));
gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(about),linphone_gtk_get_ui_config("home","http://www.linphone.org"));
if (logo) gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(about),logo);
if (logo) {
gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(about), logo);
g_object_unref(logo);
}
tmp=linphone_gtk_get_ui_config("artists",defcfg);
if (tmp!=defcfg){
const char *tmp2[2];
@ -1312,7 +1314,8 @@ static void linphone_gtk_global_state_changed(LinphoneCore *lc, LinphoneGlobalSt
}
}
static void on_call_updated_response(GtkWidget *dialog, gint responseid, LinphoneCall *call){
static void on_call_updated_response(GtkWidget *dialog, gint responseid, gpointer user_data){
LinphoneCall *call = (LinphoneCall *)g_object_get_data(G_OBJECT(dialog), "call");
if (linphone_call_get_state(call)==LinphoneCallUpdatedByRemote){
LinphoneCore *lc=linphone_call_get_core(call);
LinphoneCallParams *params=linphone_call_params_copy(linphone_call_get_current_params(call));
@ -1320,13 +1323,12 @@ static void on_call_updated_response(GtkWidget *dialog, gint responseid, Linphon
linphone_core_accept_call_update(lc,call,params);
linphone_call_params_destroy(params);
}
linphone_call_unref(call);
g_source_remove_by_user_data(dialog);
gtk_widget_destroy(dialog);
}
static void on_call_updated_timeout(GtkWidget *dialog){
gtk_widget_destroy(dialog);
on_call_updated_response(dialog, GTK_RESPONSE_NO, NULL);
}
static void linphone_gtk_call_updated_by_remote(LinphoneCall *call){
@ -1338,7 +1340,7 @@ static void linphone_gtk_call_updated_by_remote(LinphoneCall *call){
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);
if (video_used==FALSE && video_requested && !pol->automatically_accept){
if (!video_used && video_requested && !pol->automatically_accept){
linphone_core_defer_call_update(lc,call);
{
const LinphoneAddress *addr=linphone_call_get_remote_address(call);
@ -1351,8 +1353,9 @@ static void linphone_gtk_call_updated_by_remote(LinphoneCall *call){
GTK_MESSAGE_WARNING,
GTK_BUTTONS_YES_NO,
_("%s proposed to start video. Do you accept ?"),dname);
g_signal_connect(G_OBJECT(dialog),"response",(GCallback)on_call_updated_response,linphone_call_ref(call));
g_timeout_add(20000,(GSourceFunc)on_call_updated_timeout,dialog);
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);
gtk_widget_show(dialog);
}
}
@ -1496,15 +1499,6 @@ void linphone_gtk_link_to_website(GtkWidget *item){
linphone_gtk_open_browser(home);
}
#ifndef HAVE_GTK_OSX
static GtkStatusIcon *icon=NULL;
static void icon_popup_menu(GtkStatusIcon *status_icon, guint button, guint activate_time, gpointer user_data){
GtkWidget *menu=(GtkWidget*)g_object_get_data(G_OBJECT(status_icon),"menu");
gtk_menu_popup(GTK_MENU(menu),NULL,NULL,gtk_status_icon_position_menu,status_icon,button,activate_time);
}
static GtkWidget *create_icon_menu(){
GtkWidget *menu=gtk_menu_new();
GtkWidget *menu_item;
@ -1538,11 +1532,14 @@ static GtkWidget *create_icon_menu(){
return 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);
}
#endif
static void handle_icon_click() {
static void handle_icon_click(LinphoneStatusIcon *si, void *user_data) {
#ifndef HAVE_GTK_OSX
GtkWidget *mw=linphone_gtk_get_main_window();
if (!gtk_window_is_active((GtkWindow*)mw)) {
if(!gtk_widget_is_drawable(mw)){
@ -1554,67 +1551,42 @@ static void handle_icon_click() {
linphone_gtk_save_main_window_position((GtkWindow*)mw, NULL, NULL);
gtk_widget_hide(mw);
}
}
static void linphone_gtk_init_status_icon(){
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);
GtkWidget *menu=create_icon_menu();
const char *title;
title=linphone_gtk_get_ui_config("title",_("Linphone - a video internet phone"));
icon=gtk_status_icon_new_from_pixbuf(pbuf);
#if GTK_CHECK_VERSION(2,20,2)
gtk_status_icon_set_name(icon,title);
#endif
g_signal_connect_swapped(G_OBJECT(icon),"activate",(GCallback)handle_icon_click,NULL);
g_signal_connect(G_OBJECT(icon),"popup-menu",(GCallback)icon_popup_menu,NULL);
gtk_status_icon_set_tooltip(icon,title);
gtk_status_icon_set_visible(icon,TRUE);
g_object_set_data(G_OBJECT(icon),"menu",menu);
g_object_weak_ref(G_OBJECT(icon),(GWeakNotify)gtk_widget_destroy,menu);
g_object_set_data(G_OBJECT(icon),"icon",pbuf);
g_object_weak_ref(G_OBJECT(icon),(GWeakNotify)g_object_unref,pbuf);
pbuf=create_pixbuf(call_icon_path);
g_object_set_data(G_OBJECT(icon),"call_icon",pbuf);
}
static gboolean do_icon_blink(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);
}else{
gtk_status_icon_set_from_pixbuf(gi,call_icon);
static void linphone_gtk_status_icon_initialised_cb(LinphoneStatusIconParams *params) {
LinphoneStatusIcon *icon = linphone_status_icon_get();
if(icon) {
linphone_status_icon_start(icon, params);
}
return TRUE;
linphone_status_icon_params_unref(params);
}
#endif
void linphone_gtk_status_icon_set_blinking(gboolean val){
#ifdef HAVE_GTK_OSX
static gint attention_id;
GtkosxApplication *theMacApp=gtkosx_application_get();
if (val)
attention_id=gtkosx_application_attention_request(theMacApp,CRITICAL_REQUEST);
else gtkosx_application_cancel_attention_request(theMacApp,attention_id);
#else
if (icon!=NULL){
guint tout;
tout=(unsigned)GPOINTER_TO_INT(g_object_get_data(G_OBJECT(icon),"timeout"));
if (val && tout==0){
tout=g_timeout_add(500,(GSourceFunc)do_icon_blink,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");
g_source_remove(tout);
g_object_set_data(G_OBJECT(icon),"timeout",NULL);
gtk_status_icon_set_from_pixbuf(icon,normal_icon);
static void linphone_gtk_init_status_icon(void) {
GtkWidget *menu = create_icon_menu();
LinphoneStatusIconParams *params = linphone_status_icon_params_new();
linphone_status_icon_params_set_menu(params, menu);
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);
}
linphone_status_icon_params_unref(params);
}
}
void linphone_gtk_status_icon_set_blinking(gboolean val) {
LinphoneStatusIcon *icon = linphone_status_icon_get();
if(icon) {
linphone_status_icon_enable_blinking(icon, val);
}
#endif
}
void linphone_gtk_options_activate(GtkWidget *item){
@ -1763,7 +1735,7 @@ static void linphone_gtk_configure_main_window(){
}
if (search_icon){
GdkPixbuf *pbuf=create_pixbuf(search_icon);
if(pbuf != NULL) {
if(pbuf) {
gtk_image_set_from_pixbuf(GTK_IMAGE(linphone_gtk_get_widget(w,"directory_search_button_icon")),pbuf);
g_object_unref(G_OBJECT(pbuf));
}
@ -1788,6 +1760,7 @@ static void linphone_gtk_configure_main_window(){
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);
}
}
if (linphone_gtk_can_manage_accounts()) {
@ -2018,13 +1991,10 @@ static void linphone_gtk_quit(void){
quit_done=TRUE;
linphone_gtk_quit_core();
linphone_gtk_uninit_instance();
#ifndef HAVE_GTK_OSX
g_object_unref(icon);
icon=NULL;
#endif
#ifdef HAVE_NOTIFY
notify_uninit();
#endif
linphone_status_icon_uninit();
gtk_widget_destroy(the_ui);
the_ui=NULL;
gdk_threads_leave();
@ -2061,9 +2031,9 @@ static void linphone_gtk_init_ui(void){
start_option=START_AUDIO_ASSISTANT;
iconified = TRUE;
}
#ifndef HAVE_GTK_OSX
linphone_gtk_init_status_icon();
#endif
if (!iconified){
linphone_gtk_show_main_window();
linphone_gtk_check_soundcards();
@ -2097,43 +2067,30 @@ int main(int argc, char *argv[]){
workingdir= (tmp=g_getenv("LINPHONE_WORKDIR")) ? g_strdup(tmp) : NULL;
#ifdef WIN32
/*workaround for windows: sometimes LANG is defined to an integer value, not understood by gtk */
if ((lang=getenv("LANG"))!=NULL){
if (atoi(lang)!=0){
char tmp[128];
snprintf(tmp,sizeof(tmp),"LANG=",lang);
_putenv(tmp);
}
}
#else
#ifdef __linux
/*for pulseaudio:*/
g_setenv("PULSE_PROP_media.role", "phone", TRUE);
#endif
lang=linphone_gtk_get_lang(config_file);
if (lang == NULL || lang[0]=='\0'){
lang = getenv("LANG");
lang = g_getenv("LANGUAGE");
if (!lang) lang = g_getenv("LANG");
}
if (lang && lang[0]!='\0'){
#ifdef WIN32
char tmp[128];
snprintf(tmp,sizeof(tmp),"LANG=%s",lang);
_putenv(tmp);
if (strncmp(lang,"zh",2)==0){
workaround_gtk_entry_chinese_bug=TRUE;
}
#elif __APPLE__
setenv("LANG",lang,1);
setenv("LANGUAGE",lang,1);
#else
setenv("LANGUAGE",lang,1);
#endif
g_setenv("LANGUAGE",lang,1);
}
#ifdef ENABLE_NLS
setlocale(LC_ALL, "");
bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
setlocale(LC_ALL,"");
/*do not use textdomain(): this sets a global default domain. On Mac OS bundle, it breaks gtk translations (obscure bug somewhere)*/
/*textdomain (GETTEXT_PACKAGE);*/
#else
@ -2200,7 +2157,10 @@ int main(int argc, char *argv[]){
}
g_set_application_name(app_name);
pbuf=create_pixbuf(icon_path);
if (pbuf!=NULL) gtk_window_set_default_icon(pbuf);
if (pbuf) {
gtk_window_set_default_icon(pbuf);
g_object_unref(pbuf);
}
#ifdef HAVE_GTK_OSX
GtkosxApplication *theMacApp = gtkosx_application_get();
@ -2242,10 +2202,6 @@ core_start:
goto core_start;
}
if (config_file) g_free(config_file);
#ifndef HAVE_GTK_OSX
/*workaround a bug on win32 that makes status icon still present in the systray even after program exit.*/
if (icon) gtk_status_icon_set_visible(icon,FALSE);
#endif
free(progpath);
/*output a translated "hello" string to the terminal, which allows the builder to check that translations are working.*/
if (selftest){

View file

@ -532,6 +532,23 @@ static void fmtp_edited(GtkCellRendererText *renderer, gchar *path, gchar *new_t
}
}
static void bitrate_edited(GtkCellRendererText *renderer, gchar *path, gchar *new_text, gpointer userdata){
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)){
PayloadType *pt;
gtk_list_store_set(store,&iter,CODEC_BITRATE,newbitrate,-1);
gtk_tree_model_get(GTK_TREE_MODEL(store),&iter,CODEC_PRIVDATA,&pt,-1);
linphone_core_set_payload_type_bitrate(linphone_gtk_get_core(), pt, (int)newbitrate);
}
}
static void linphone_gtk_init_codec_list(GtkTreeView *listview){
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
@ -571,7 +588,9 @@ static void linphone_gtk_init_codec_list(GtkTreeView *listview){
renderer,
"text", CODEC_BITRATE,
"foreground",CODEC_COLOR,
"editable",TRUE,
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"),

View file

@ -26,8 +26,6 @@ static const int PASSWORD_MIN_SIZE = 6;
static const int LOGIN_MIN_SIZE = 4;
static GtkWidget *the_assistant=NULL;
static GdkPixbuf *ok;
static GdkPixbuf *notok;
static GtkWidget *create_intro(){
GtkWidget *vbox=gtk_vbox_new(FALSE,2);
@ -205,10 +203,12 @@ static void account_email_changed(GtkEntry *entry, GtkWidget *w) {
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);
}
@ -227,11 +227,13 @@ static void account_password_changed(GtkEntry *entry, GtkWidget *w) {
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 !");
}
@ -252,11 +254,13 @@ gboolean update_interface_with_username_availability(gpointer *w) {
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);
@ -297,6 +301,7 @@ static void account_username_changed(GtkEntry *entry, GtkWidget *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");
}
@ -313,7 +318,7 @@ static void account_username_changed(GtkEntry *entry, GtkWidget *w) {
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);
@ -595,6 +600,8 @@ void linphone_gtk_show_assistant(void){
GtkWidget *validate;
GtkWidget *error;
GtkWidget *end;
GdkPixbuf *ok;
GdkPixbuf *notok;
if(the_assistant!=NULL)
return;
w=the_assistant=gtk_assistant_new();
@ -602,7 +609,9 @@ void linphone_gtk_show_assistant(void){
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();

516
gtk/status_icon.c Normal file
View file

@ -0,0 +1,516 @@
/*
linphone, gtk-glade interface.
Copyright (C) 2015 Belledonne Communications <info@belledonne-communications.com>
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 "status_icon.h"
#include "linphone.h"
#ifdef HAVE_GTK_OSX
#include <gtkosxapplication.h>
#endif
#if !defined(WIN32) && !defined(__APPLE__) && GLIB_CHECK_VERSION(2, 26, 0)
#define STATUS_NOTIFIER_IS_USABLE 1
#endif
#include "status_notifier.h"
typedef struct __LinphoneStatusIconDesc _LinphoneStatusIconDesc;
static LinphoneStatusIcon *_linphone_status_icon_instance = NULL;
static const _LinphoneStatusIconDesc *_linphone_status_icon_selected_desc = NULL;
static GSList *_linphone_status_icon_impls = NULL;
struct _LinphoneStatusIconParams {
char *title;
char *desc;
GtkWidget *menu;
LinphoneStatusIconOnClickCallback on_click_cb;
void *user_data;
int ref;
};
LinphoneStatusIconParams *linphone_status_icon_params_new(void) {
return g_new0(LinphoneStatusIconParams, 1);
}
LinphoneStatusIconParams *linphone_status_icon_params_ref(LinphoneStatusIconParams *obj) {
obj->ref++;
return obj;
}
void linphone_status_icon_params_unref(LinphoneStatusIconParams *obj) {
obj->ref--;
if(obj->ref < 0) {
if(obj->title) g_free(obj->title);
if(obj->menu) g_object_unref(obj->menu);
if(obj->desc) g_free(obj->desc);
g_free(obj);
}
}
void linphone_status_icon_params_set_title(LinphoneStatusIconParams *obj, const char *title) {
if(obj->title) g_free(obj->title);
if(title) obj->title = g_strdup(title);
else obj->title = NULL;
}
void linphone_status_icon_params_set_description(LinphoneStatusIconParams *obj, const char *desc) {
if(obj->desc) g_free(obj->desc);
if(desc) obj->desc = g_strdup(desc);
else obj->desc = NULL;
}
void linphone_status_icon_params_set_menu(LinphoneStatusIconParams *obj, GtkWidget *menu) {
if(obj->menu) g_object_unref(obj->menu);
if(menu) obj->menu = g_object_ref_sink(menu);
else obj->menu = NULL;
}
void linphone_status_icon_params_set_on_click_cb(LinphoneStatusIconParams *obj, LinphoneStatusIconOnClickCallback cb, void *user_data) {
obj->on_click_cb = cb;
obj->user_data = user_data;
}
typedef void (*LinphoneStatusIconDescInitFunc)(LinphoneStatusIcon *obj);
typedef void (*LinphoneStatusIconDescUninitFunc)(LinphoneStatusIcon *obj);
typedef void (*LinphoneStatusIconDescStartFunc)(LinphoneStatusIcon *obj);
typedef void (*LinphoneStatusIconDescEnableBlinkingFunc)(LinphoneStatusIcon *obj, gboolean enable);
typedef void (*LinphoneStatusIconDescIsSupportedResultCb)(const _LinphoneStatusIconDesc *obj, gboolean result, void *user_data);
typedef gboolean (*LinphoneStatusIconDescIsSupportedFunc)(
const _LinphoneStatusIconDesc *desc,
gboolean *result,
LinphoneStatusIconDescIsSupportedResultCb cb,
void *user_data
);
typedef void (*LinphoneStatusIconDescFindResultCb)(const _LinphoneStatusIconDesc *desc, void *user_data);
struct __LinphoneStatusIconDesc {
const char *impl_name;
LinphoneStatusIconDescInitFunc init;
LinphoneStatusIconDescUninitFunc uninit;
LinphoneStatusIconDescStartFunc start;
LinphoneStatusIconDescEnableBlinkingFunc enable_blinking;
LinphoneStatusIconDescIsSupportedFunc is_supported;
};
static gboolean _linphone_status_icon_desc_is_supported(
const _LinphoneStatusIconDesc *desc,
gboolean *result,
LinphoneStatusIconDescIsSupportedResultCb cb,
void *user_data) {
return desc->is_supported(desc, result, cb, user_data);
}
typedef struct {
GSList *i;
LinphoneStatusIconDescFindResultCb cb;
void *user_data;
} _LinphoneStatusIconDescSearchCtx;
static void _linphone_status_icon_desc_is_supported_result_cb(
const _LinphoneStatusIconDesc *desc,
gboolean result,
_LinphoneStatusIconDescSearchCtx *ctx) {
if(!result) {
;
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);
g_free(ctx);
}
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;
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);
goto sync_return;
}
} else {
return 0;
}
}
*desc = NULL;
sync_return:
g_free(ctx);
return 1;
}
struct _LinphoneStatusIcon {
const _LinphoneStatusIconDesc *desc;
LinphoneStatusIconParams *params;
void *data;
};
static LinphoneStatusIcon *_linphone_status_icon_new(const _LinphoneStatusIconDesc *desc) {
LinphoneStatusIcon *si = (LinphoneStatusIcon *)g_new0(LinphoneStatusIcon, 1);
si->desc = desc;
if(desc->init) desc->init(si);
return si;
}
static void _linphone_status_icon_free(LinphoneStatusIcon *obj) {
if(obj->desc->uninit) obj->desc->uninit(obj->data);
if(obj->params) linphone_status_icon_params_unref(obj->params);
g_free(obj);
}
const char *linphone_status_icon_get_implementation_name(const LinphoneStatusIcon *obj) {
return obj->desc->impl_name;
}
void linphone_status_icon_start(LinphoneStatusIcon *obj, LinphoneStatusIconParams *params) {
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) {
if(obj->desc->enable_blinking) obj->desc->enable_blinking(obj, enable);
}
static void _linphone_status_icon_notify_click(LinphoneStatusIcon *obj) {
if(obj->params->on_click_cb) {
obj->params->on_click_cb(obj, obj->params->user_data);
}
}
void _linphone_status_icon_init_cb(const _LinphoneStatusIconDesc *desc, void *user_data) {
void **ctx = (void **)user_data;
LinphoneStatusIconReadyCb cb = (LinphoneStatusIconReadyCb)ctx[0];
_linphone_status_icon_selected_desc = desc;
if(cb) cb(ctx[1]);
g_free(ctx);
}
#ifdef STATUS_NOTIFIER_IS_USABLE
static const _LinphoneStatusIconDesc _linphone_status_icon_impl_status_notifier;
#endif
#ifdef HAVE_GTK_OSX
static const _LinphoneStatusIconDesc _linphone_status_icon_impl_gtkosx_app_desc;
#else
static const _LinphoneStatusIconDesc _linphone_status_icon_impl_gtk_desc;
#endif
void _linphone_status_icon_create_implementations_list(void) {
#ifdef STATUS_NOTIFIER_IS_USABLE
_linphone_status_icon_impls = g_slist_append(_linphone_status_icon_impls, (void *)&_linphone_status_icon_impl_status_notifier);
#endif
#if HAVE_GTK_OSX
_linphone_status_icon_impls = g_slist_append(_linphone_status_icon_impls, (void *)&_linphone_status_icon_impl_gtkosx_app_desc);
#else
_linphone_status_icon_impls = g_slist_append(_linphone_status_icon_impls, (void *)&_linphone_status_icon_impl_gtk_desc);
#endif
}
gboolean linphone_status_icon_init(LinphoneStatusIconReadyCb ready_cb, void *user_data) {
const _LinphoneStatusIconDesc *desc;
void **ctx;
_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);
return 1;
} else return 0;
}
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);
}
LinphoneStatusIcon *linphone_status_icon_get(void) {
if(_linphone_status_icon_instance == NULL) {
if(_linphone_status_icon_selected_desc)
_linphone_status_icon_instance = _linphone_status_icon_new(_linphone_status_icon_selected_desc);
}
return _linphone_status_icon_instance;
}
/* GtkStatusIcon implementation */
#ifndef HAVE_GTK_OSX
static void _linphone_status_icon_impl_gtk_on_click_cb(LinphoneStatusIcon *si) {
_linphone_status_icon_notify_click(si);
}
static void _linphone_status_icon_impl_gtk_popup_menu(GtkStatusIcon *status_icon, guint button, guint activate_time, LinphoneStatusIcon *si){
GtkWidget *menu = si->params->menu;
gtk_menu_popup(GTK_MENU(menu),NULL,NULL,gtk_status_icon_position_menu,status_icon,button,activate_time);
}
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);
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);
si->data = icon;
}
static void _linphone_status_icon_impl_gtk_uninit(LinphoneStatusIcon *si) {
GtkStatusIcon *icon = GTK_STATUS_ICON(si->data);
gtk_status_icon_set_visible(icon, FALSE);
}
static void _linphone_status_icon_impl_gtk_start(LinphoneStatusIcon *si) {
GtkStatusIcon *icon = GTK_STATUS_ICON(si->data);
#if GTK_CHECK_VERSION(2,20,2)
char *name = g_strdup_printf("%s - %s", si->params->title, si->params->desc);
gtk_status_icon_set_name(icon, name);
g_free(name);
#endif
gtk_status_icon_set_visible(icon,TRUE);
}
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);
}else{
gtk_status_icon_set_from_pixbuf(gi,call_icon);
}
return TRUE;
}
static void _linphone_status_icon_impl_enable_blinking(LinphoneStatusIcon *si, gboolean val) {
GtkStatusIcon *icon = GTK_STATUS_ICON(si->data);
guint tout;
tout=(unsigned)GPOINTER_TO_INT(g_object_get_data(G_OBJECT(icon),"timeout"));
if (val && tout==0){
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");
g_source_remove(tout);
g_object_set_data(G_OBJECT(icon),"timeout",NULL);
gtk_status_icon_set_from_pixbuf(icon,normal_icon);
}
}
static gboolean _linphone_status_icon_impl_is_supported(
const _LinphoneStatusIconDesc *desc,
gboolean *result,
LinphoneStatusIconDescIsSupportedResultCb cb,
void *user_data) {
*result = 1;
return 1;
}
static const _LinphoneStatusIconDesc _linphone_status_icon_impl_gtk_desc = {
"gtk_status_icon",
_linphone_status_icon_impl_gtk_init,
_linphone_status_icon_impl_gtk_uninit,
_linphone_status_icon_impl_gtk_start,
_linphone_status_icon_impl_enable_blinking,
_linphone_status_icon_impl_is_supported
};
#endif
/* GtkosxApplication implementation */
#ifdef HAVE_GTK_OSX
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) {
gtkosx_application_cancel_attention_request(theMacApp, *attention_id);
*attention_id = 0;
}
}
static gboolean _linphone_status_icon_impl_gtkosx_app_is_supported(
const _LinphoneStatusIconDesc *desc,
gboolean *result,
LinphoneStatusIconDescIsSupportedResultCb cb,
void *user_data) {
*result = 1;
return 1;
}
static const _LinphoneStatusIconDesc _linphone_status_icon_impl_gtkosx_app_desc = {
.impl_name = "gtkosx_application",
.init = NULL,
.uninit = NULL,
.start = NULL,
.enable_blinking = _linphone_status_icon_impl_gtkosx_app_enable_blinking,
.is_supported = _linphone_status_icon_impl_gtkosx_app_is_supported
};
#endif
/* Implementation based on the StatusNotifier Freedesktop standard */
#ifdef STATUS_NOTIFIER_IS_USABLE
typedef struct {
int x;
int y;
} _LinphoneStatusIconPosition;
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_activated_cb(BcStatusNotifier *sn, int x, int y, void *user_data) {
LinphoneStatusIcon *si = (LinphoneStatusIcon *)user_data;
_linphone_status_icon_notify_click(si);
}
static void _linphone_status_icon_impr_sn_get_position(GtkMenu *menu, int *x, int *y, gboolean *push_in, gpointer data) {
_LinphoneStatusIconPosition *pos = (_LinphoneStatusIconPosition *)data;
*x = pos->x;
*y = pos->y;
*push_in = TRUE;
}
static void _linphone_status_icon_impl_sn_menu_called_cb(BcStatusNotifier *sn, int x, int y, void *user_data) {
LinphoneStatusIcon *si = (LinphoneStatusIcon *)user_data;
GtkWidget *menu = si->params->menu;
_LinphoneStatusIconPosition pos = {x, y};
gtk_menu_popup(
GTK_MENU(menu),
NULL,
NULL,
_linphone_status_icon_impr_sn_get_position,
&pos,
0,
gtk_get_current_event_time()
);
}
static void _linphone_status_icon_impl_sn_start(LinphoneStatusIcon *si) {
BcStatusNotifier *sn = (BcStatusNotifier *)si->data;
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);
bc_status_notifier_params_set_id(params, "linphone");
bc_status_notifier_params_set_title(params, si->params->title);
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;
if(val) {
bc_status_notifier_update_status(sn, BcStatusNotifierStatusNeedsAttention);
} else {
bc_status_notifier_update_status(sn, BcStatusNotifierStatusPassive);
}
}
static void _linphone_status_icon_impl_is_supported_cb(const char *prefix, gboolean result, void **data) {
_LinphoneStatusIconDesc *desc = (_LinphoneStatusIconDesc *)data[0];
LinphoneStatusIconDescIsSupportedResultCb cb = (LinphoneStatusIconDescIsSupportedResultCb)data[1];
if(cb) cb(desc, result, data[2]);
g_free(data);
g_free(desc);
}
static gboolean _linphone_status_icon_impl_sn_is_supported(
const _LinphoneStatusIconDesc *desc,
gboolean *result,
LinphoneStatusIconDescIsSupportedResultCb cb,
void *user_data) {
_LinphoneStatusIconDesc *desc2 = g_new(_LinphoneStatusIconDesc, 1);
void **data = g_new(void *, 3);
*desc2 = *desc;
data[0] = desc2;
data[1] = cb;
data[2] = user_data;
bc_status_notifier_is_supported(
"org.kde",
(BcStatusNotifierSupportDetectionCb)_linphone_status_icon_impl_is_supported_cb,
data
);
return 0;
}
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,
.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
};
#endif

53
gtk/status_icon.h Normal file
View file

@ -0,0 +1,53 @@
/*
linphone, gtk-glade interface.
Copyright (C) 2015 Belledonne Communications <info@belledonne-communications.com>
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.
*/
/*
* LinphoneStatusIcon is an singleton interface which abstracts the
* technology used to manage the status icon.
*/
#include <glib.h>
#include <gtk/gtk.h>
struct _LinphoneStatusIcon;
typedef void (*LinphoneStatusIconOnClickCallback)(struct _LinphoneStatusIcon *si, void *user_data);
typedef struct _LinphoneStatusIconParams LinphoneStatusIconParams;
LinphoneStatusIconParams *linphone_status_icon_params_new(void);
LinphoneStatusIconParams *linphone_status_icon_params_ref(LinphoneStatusIconParams *obj);
void linphone_status_icon_params_unref(LinphoneStatusIconParams *obj);
void linphone_status_icon_params_set_title(LinphoneStatusIconParams *obj, const char *title);
void linphone_status_icon_params_set_description(LinphoneStatusIconParams *obj, const char *desc);
void linphone_status_icon_params_set_menu(LinphoneStatusIconParams *obj, GtkWidget *menu);
void linphone_status_icon_params_set_on_click_cb(LinphoneStatusIconParams* obj, LinphoneStatusIconOnClickCallback cb, void *user_data);
typedef void (*LinphoneStatusIconReadyCb)(void *user_data);
typedef struct _LinphoneStatusIcon LinphoneStatusIcon;
gboolean linphone_status_icon_init(LinphoneStatusIconReadyCb ready_cb, void* user_data);
void linphone_status_icon_uninit(void);
LinphoneStatusIcon *linphone_status_icon_get(void);
const char *linphone_status_icon_get_implementation_name(const LinphoneStatusIcon *obj);
void linphone_status_icon_start(LinphoneStatusIcon *obj, LinphoneStatusIconParams *params);
void linphone_status_icon_enable_blinking(LinphoneStatusIcon *obj, gboolean enable);

644
gtk/status_notifier.c Normal file
View file

@ -0,0 +1,644 @@
/*
linphone, gtk-glade interface.
Copyright (C) 2015 Belledonne Communications <info@belledonne-communications.com>
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 "status_notifier.h"
#include <gio/gio.h>
#include <string.h>
#ifdef _MSC_VER
#include <process.h>
#define getpid() _getpid()
typedef int lppid_t;
#else
#include <unistd.h>
typedef pid_t lppid_t;
#endif
const gchar *bc_status_notifier_category_to_string(BcStatusNotifierCategory c) {
switch(c){
case BcStatusNotifierCategoryApplicationStatus:
return "ApplicationStatus";
case BcStatusNotifierCategoryCommunications:
return "Communications";
case BcStatusNotifierCategorySystemService:
return "SystemServices";
case BcStatusNotifierCategoryHardware:
return "Hardware";
}
return "bad category";
}
const gchar *bc_status_notifier_status_to_string(BcStatusNotifierStatus s) {
switch(s){
case BcStatusNotifierStatusPassive:
return "Passive";
case BcStatusNotifierStatusActive:
return "Active";
case BcStatusNotifierStatusNeedsAttention:
return "NeedsAttention";
}
return "badstatus";
};
struct _BcStatusNotifierToolTip {
char *icon_name;
char *title;
char *text;
int ref;
};
BcStatusNotifierToolTip *bc_status_notifier_tool_tip_new(const char *icon_name, const char *title, const char *text) {
BcStatusNotifierToolTip *obj = (BcStatusNotifierToolTip *)g_new0(BcStatusNotifierToolTip, 1);
if(icon_name) obj->icon_name = g_strdup(icon_name);
if(title) obj->title = g_strdup(title);
if(text) obj->text = g_strdup(text);
return obj;
}
BcStatusNotifierToolTip *bc_status_notifier_tool_tip_ref(BcStatusNotifierToolTip *obj) {
obj->ref++;
return obj;
}
void bc_status_notifier_tool_tip_unref(BcStatusNotifierToolTip *obj) {
obj->ref--;
if(obj->ref < 0) {
if(obj->icon_name) g_free(obj->icon_name);
if(obj->title) g_free(obj->title);
if(obj->text) g_free(obj->text);
g_free(obj);
}
}
static GVariant *_bc_status_notifier_tool_tip_to_variant(const BcStatusNotifierToolTip *obj) {
GVariant *attr[] = {
g_variant_new_string(obj->icon_name ? obj->icon_name : ""),
g_variant_new_array(G_VARIANT_TYPE_VARIANT, NULL, 0),
g_variant_new_string(obj->title ? obj->title : ""),
g_variant_new_string(obj->text ? obj->text : ""),
};
return g_variant_new_tuple(attr, 4);
}
static const char *_bc_status_notifier_to_string[] = {
"vertical",
"horizontal",
NULL
};
static BcStatusNotifierOrientation _bc_status_notifier_orientation_from_string(const char *s) {
int i;
for(i=0; _bc_status_notifier_to_string[i] && g_strcmp0(s, _bc_status_notifier_to_string[i]) == 0; i++);
if(_bc_status_notifier_to_string[i]) return i;
else return BcStatusNotifierOrientationVertical;
}
struct _BcStatusNotifierParams{
char *prefix;
int item_id;
BcStatusNotifierCategory category;
char *id;
char *title;
BcStatusNotifierStatus status;
guint32 window_id;
char *icon_name;
char *overlay_icon_name;
char *attention_icon_name;
char *attention_movie_name;
BcStatusNotifierToolTip *tool_tip;
BcStatusNotifierSignalsVTable vtable;
void *user_data;
int ref;
};
#define DEFAULT_PREFIX "org.freedesktop"
BcStatusNotifierParams *bc_status_notifier_params_new(void) {
BcStatusNotifierParams *obj = (BcStatusNotifierParams *)g_new0(BcStatusNotifierParams, 1);
obj->prefix = g_strdup(DEFAULT_PREFIX);
return obj;
}
BcStatusNotifierParams *bc_status_notifier_params_ref(BcStatusNotifierParams *obj) {
obj->ref++;
return obj;
}
void bc_status_notifier_params_unref(BcStatusNotifierParams *obj) {
obj->ref--;
if(obj->ref < 0) {
if(obj->prefix) g_free(obj->prefix);
if(obj->id) g_free(obj->id);
if(obj->title) g_free(obj->title);
if(obj->icon_name) g_free(obj->icon_name);
if(obj->overlay_icon_name) g_free(obj->overlay_icon_name);
if(obj->attention_icon_name) g_free(obj->attention_icon_name);
if(obj->attention_movie_name) g_free(obj->attention_movie_name);
if(obj->tool_tip) bc_status_notifier_tool_tip_unref(obj->tool_tip);
g_free(obj);
}
}
void bc_status_notifier_params_set_dbus_prefix(BcStatusNotifierParams *obj, const char *prefix) {
if(obj->prefix) g_free(obj->prefix);
if(prefix) obj->prefix = g_strdup(prefix);
else obj->prefix = NULL;
}
const char *bc_satus_notifier_params_get_dbus_prefix(const BcStatusNotifierParams *obj) {
return obj->prefix;
}
void bc_status_notifier_params_set_item_id(BcStatusNotifierParams *obj, int item_id) {
obj->item_id = item_id;
}
int bc_status_notifier_params_get_item_id(const BcStatusNotifierParams *obj) {
return obj->item_id;
}
void bc_status_notifier_params_set_category(BcStatusNotifierParams *obj, BcStatusNotifierCategory category) {
obj->category = category;
}
BcStatusNotifierCategory bc_status_notifier_params_get_category(const BcStatusNotifierParams *obj) {
return obj->category;
}
void bc_status_notifier_params_set_id(BcStatusNotifierParams *obj, const char *id) {
if(obj->id) g_free(obj->id);
if(id) obj->id = g_strdup(id);
else obj->id = NULL;
}
const char *bc_status_notifier_params_get_id(const BcStatusNotifierParams *obj) {
return obj->id;
}
void bc_status_notifier_params_set_title(BcStatusNotifierParams *obj, const char *title) {
if(obj->title) g_free(obj->title);
if(title) obj->title = g_strdup(title);
else obj->title = NULL;
}
const char *bc_status_notifier_params_get_title(const BcStatusNotifierParams *obj) {
return obj->title;
}
void bc_status_notifier_params_set_status(BcStatusNotifierParams *obj, BcStatusNotifierStatus status) {
obj->status = status;
}
BcStatusNotifierStatus bc_status_notifier_params_get_status(const BcStatusNotifierParams *obj) {
return obj->status;
}
void bc_status_notifier_params_set_window_id(BcStatusNotifierParams *obj, guint32 window_id) {
obj->window_id = window_id;
}
guint32 bc_status_notifier_params_get_window_id(const BcStatusNotifierParams *obj) {
return obj->window_id;
}
void bc_status_notifier_params_set_icon_name(BcStatusNotifierParams *obj, const char *name) {
if(obj->icon_name) g_free(obj->icon_name);
if(name) obj->icon_name = g_strdup(name);
else obj->icon_name = NULL;
}
const char *bc_status_notifier_params_get_icon_name(const BcStatusNotifierParams *obj) {
return obj->icon_name;
}
void bc_status_notifier_params_set_overlay_icon_name(BcStatusNotifierParams *obj, const char *name) {
if(obj->overlay_icon_name) g_free(obj->overlay_icon_name);
if(name) obj->overlay_icon_name = g_strdup(name);
else obj->overlay_icon_name = NULL;
}
const char *bc_status_notifier_params_get_overlay_icon_name(const BcStatusNotifierParams *obj) {
return obj->overlay_icon_name;
}
void bc_status_notifier_params_set_attention_icon_name(BcStatusNotifierParams *obj, const char *name) {
if(obj->attention_icon_name) g_free(obj->attention_icon_name);
if(name) obj->attention_icon_name = g_strdup(name);
else obj->attention_icon_name = NULL;
}
const char *bc_status_notifier_params_get_attention_icon_name(const BcStatusNotifierParams *obj) {
return obj->attention_icon_name;
}
void bc_status_notifier_params_set_attention_movie_name(BcStatusNotifierParams *obj, const char *name) {
if(obj->attention_movie_name) g_free(obj->attention_movie_name);
if(name) obj->attention_movie_name = g_strdup(name);
else obj->attention_movie_name = NULL;
}
const char *bc_status_notifier_params_get_attention_movie_name(const BcStatusNotifierParams *obj) {
return obj->attention_movie_name;
}
void bc_status_notifier_params_set_tool_tip(BcStatusNotifierParams *obj, BcStatusNotifierToolTip *tool_tip) {
if(obj->tool_tip) bc_status_notifier_tool_tip_unref(obj->tool_tip);
if(tool_tip) obj->tool_tip = bc_status_notifier_tool_tip_ref(tool_tip);
else obj->tool_tip = NULL;
}
const BcStatusNotifierToolTip *bc_status_notifier_params_get_tool_tip(const BcStatusNotifierParams *obj) {
return obj->tool_tip;
}
void bc_status_notifier_params_set_vtable(BcStatusNotifierParams *obj, const BcStatusNotifierSignalsVTable *vtable, void *user_data) {
obj->vtable = *vtable;
obj->user_data = user_data;
}
struct _BcStatusNotifier {
BcStatusNotifierParams *params;
guint bus_owner_id;
GDBusConnection *conn;
BcStatusNotifierState state;
BcStatusNotifierStateVTable vtable;
void *user_data;
int ref;
};
#define ITEM_NAME "StatusNotifierItem"
#define WATCHER_NAME "StatusNotifierWatcher"
#define CALL_TIMEOUT 1000
#define STATUS_NOTIFIER_INTROSPECTION_DATA \
"<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\" \
\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\"> \
<node name=\"/StatusNotifierItem\"> \
<interface name=\"org.kde.StatusNotifierItem\"> \
<property name=\"Category\" type=\"s\" access=\"read\"/> \
<property name=\"Id\" type=\"s\" access=\"read\"/> \
<property name=\"Title\" type=\"s\" access=\"read\"/> \
<property name=\"Status\" type=\"s\" access=\"read\"/> \
<property name=\"WindowId\" type=\"u\" access=\"read\"/> \
<property name=\"IconName\" type=\"s\" access=\"read\"/> \
<property name=\"IconPixmap\" type=\"a(iiay)\" access=\"read\"/> \
<property name=\"OverlayIconName\" type=\"s\" access=\"read\"/> \
<property name=\"OverlayIconPixmap\" type=\"a(iiay)\" access=\"read\"/> \
<property name=\"AttentionIconName\" type=\"s\" access=\"read\"/> \
<property name=\"AttentionIconPixmap\" type=\"a(iiay)\" access=\"read\"/> \
<property name=\"AttentionMovieName\" type=\"s\" access=\"read\"/> \
<property name=\"ToolTip\" type=\"(sa(iiay)ss)\" access=\"read\"/> \
<method name=\"ContextMenu\"> \
<arg name=\"x\" type=\"i\" direction=\"in\" /> \
<arg name=\"y\" type=\"i\" direction=\"in\" /> \
</method> \
<method name=\"Activate\"> \
<arg name=\"x\" type=\"i\" direction=\"in\" /> \
<arg name=\"y\" type=\"i\" direction=\"in\" /> \
</method> \
<method name=\"SecondaryActivate\"> \
<arg name=\"x\" type=\"i\" direction=\"in\" /> \
<arg name=\"y\" type=\"i\" direction=\"in\" /> \
</method> \
<method name=\"Scroll\"> \
<arg name=\"delta\" type=\"i\" direction=\"in\" /> \
<arg name=\"orientation\" type=\"s\" direction=\"in\" /> \
</method> \
<signal name=\"NewTitle\" /> \
<signal name=\"NewIcon\" /> \
<signal name=\"NewAttentionIcon\" /> \
<signal name=\"NewOverlayIcon\" /> \
<signal name=\"NewToolTip\" /> \
<signal name=\"NewStatus\"> \
<arg name=\"status\" type=\"s\" /> \
</signal> \
</interface> \
</node>"
BcStatusNotifier *bc_status_notifier_new(void) {
return (BcStatusNotifier *)g_new0(BcStatusNotifier, 1);
}
BcStatusNotifier *bc_status_notifier_ref(BcStatusNotifier *obj) {
obj->ref++;
return obj;
}
void bc_status_notifier_unref(BcStatusNotifier *obj) {
obj->ref--;
if(obj->ref < 0) {
bc_status_notifier_stop(obj);
if(obj->params) bc_status_notifier_params_unref(obj->params);
g_free(obj);
}
}
static GVariant *_bc_status_notifier_get_property_cb(
GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
const gchar *interface_name,
const gchar *property_name,
GError **error,
BcStatusNotifier *sn) {
GVariant *value = NULL;
if(g_strcmp0(property_name, "Category") == 0) {
value = g_variant_new_string(bc_status_notifier_category_to_string(sn->params->category));
} else if(g_strcmp0(property_name, "Id") == 0) {
value = g_variant_new_string(sn->params->id ? sn->params->id : "");
} else if(g_strcmp0(property_name, "Title") == 0) {
value = g_variant_new_string(sn->params->title ? sn->params->title : "");
} else if(g_strcmp0(property_name, "Status") == 0) {
value = g_variant_new_string(bc_status_notifier_status_to_string(sn->params->status));
} else if(g_strcmp0(property_name, "WindowId") == 0) {
value = g_variant_new_uint32(sn->params->window_id);
} else if(g_strcmp0(property_name, "IconName") == 0) {
value = g_variant_new_string(sn->params->icon_name ? sn->params->icon_name : "");
} else if(g_strcmp0(property_name, "IconPixmap") == 0) {
value = g_variant_new_array(G_VARIANT_TYPE_VARIANT, NULL, 0);
} else if(g_strcmp0(property_name, "OverlayIconName") == 0) {
value = g_variant_new_string(sn->params->overlay_icon_name ? sn->params->overlay_icon_name : "");
} else if(g_strcmp0(property_name, "OverlayIconPixmap") == 0) {
value = g_variant_new_array(G_VARIANT_TYPE_VARIANT, NULL, 0);
} else if(g_strcmp0(property_name, "AttentionIconName") == 0) {
value = g_variant_new_string(sn->params->attention_icon_name ? sn->params->attention_icon_name : "");
} else if(g_strcmp0(property_name, "AttentionIconPixmap") == 0) {
value = g_variant_new_array(G_VARIANT_TYPE_VARIANT, NULL, 0);
} else if(g_strcmp0(property_name, "AttentionMovieName") == 0) {
value = g_variant_new_string(sn->params->attention_movie_name ? sn->params->attention_movie_name : "");
} else if(g_strcmp0(property_name, "ToolTip") == 0) {
if(sn->params->tool_tip) {
value = _bc_status_notifier_tool_tip_to_variant(sn->params->tool_tip);
} else {
BcStatusNotifierToolTip *tool_tip = bc_status_notifier_tool_tip_new("", "", "");
value = _bc_status_notifier_tool_tip_to_variant(tool_tip);
bc_status_notifier_tool_tip_unref(tool_tip);
}
}
return value;
}
static void _bc_status_notifier_method_call_cb(
GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
const gchar *interface_name,
const gchar *method_name,
GVariant *parameters,
GDBusMethodInvocation *invocation,
BcStatusNotifier *sn) {
if(g_strcmp0(method_name, "ContextMenu") == 0) {
if(sn->params->vtable.context_menu_called_cb) {
int x, y;
g_variant_get_child(parameters, 0, "i", &x);
g_variant_get_child(parameters, 1, "i", &y);
sn->params->vtable.context_menu_called_cb(sn, x, y, sn->params->user_data);
}
} else if(g_strcmp0(method_name, "Activate") == 0) {
if(sn->params->vtable.activate_called_cb) {
int x, y;
g_variant_get_child(parameters, 0, "i", &x);
g_variant_get_child(parameters, 1, "i", &y);
sn->params->vtable.activate_called_cb(sn, x, y, sn->params->user_data);
}
} else if(g_strcmp0(method_name, "SecondaryActivate") == 0) {
if(sn->params->vtable.secondary_activate_called_cb) {
int x, y;
g_variant_get_child(parameters, 0, "i", &x);
g_variant_get_child(parameters, 1, "i", &y);
sn->params->vtable.secondary_activate_called_cb(sn, x, y, sn->params->user_data);
}
} else if(g_strcmp0(method_name, "Scroll") == 0) {
if(sn->params->vtable.scroll_called_cb) {
int delta;
BcStatusNotifierOrientation orient;
char *orient_str;
g_variant_get_child(parameters, 0, "i", &delta);
g_variant_get_child(parameters, 1, "&s", &orient_str);
orient = _bc_status_notifier_orientation_from_string(orient_str);
sn->params->vtable.scroll_called_cb(sn, delta, orient, sn->params->user_data);
}
}
g_dbus_method_invocation_return_value(invocation, NULL);
}
static void _bc_status_notifier_bus_acquired_cb(GDBusConnection *conn, const gchar *name, BcStatusNotifier *sn) {
char *interface_name = g_strdup_printf("%s.%s", sn->params->prefix, ITEM_NAME);
char *item_path = g_strdup_printf("/%s", ITEM_NAME);
GDBusInterfaceVTable vtable = {
(GDBusInterfaceMethodCallFunc)_bc_status_notifier_method_call_cb,
(GDBusInterfaceGetPropertyFunc)_bc_status_notifier_get_property_cb,
NULL
};
GDBusNodeInfo *node_info = g_dbus_node_info_new_for_xml(STATUS_NOTIFIER_INTROSPECTION_DATA, NULL);
GDBusInterfaceInfo *interface = g_dbus_node_info_lookup_interface(
node_info,
interface_name
);
g_free(interface_name);
sn->conn = conn;
g_dbus_connection_register_object(
conn,
item_path,
interface,
&vtable,
bc_status_notifier_ref(sn),
(GDestroyNotify)bc_status_notifier_unref,
NULL
);
g_free(item_path);
g_dbus_node_info_unref(node_info);
}
static void _bc_status_notifier_name_acquired_cb(GDBusConnection *conn, const gchar *name, BcStatusNotifier *sn) {
GVariant *item_name = g_variant_new_string(name);
GVariant *parameters = g_variant_new_tuple(&item_name, 1);
char *watcher_bus_name = g_strdup_printf("%s.%s", sn->params->prefix, WATCHER_NAME);
char *watcher_interface_name = watcher_bus_name;
char *watcher_path = g_strdup_printf("/%s", WATCHER_NAME);
g_dbus_connection_call(
conn,
watcher_bus_name,
watcher_path,
watcher_interface_name,
"RegisterStatusNotifierItem",
parameters,
NULL,
G_DBUS_CALL_FLAGS_NONE,
CALL_TIMEOUT,
NULL,
NULL,
NULL
);
g_free(watcher_bus_name);
g_free(watcher_path);
sn->state = BcStatusNotifierStateRunning;
if(sn->vtable.success) sn->vtable.success(sn, sn->user_data);
}
static void _bc_status_notifier_name_lost(GDBusConnection *conn, const gchar *name, BcStatusNotifier *sn) {
if(conn == NULL) {
sn->state = BcStatusNotifierStateStopped;
if(sn->vtable.fail) sn->vtable.fail(sn, sn->user_data);
}
}
void bc_status_notifier_start(BcStatusNotifier* obj, BcStatusNotifierParams* params, const BcStatusNotifierStateVTable *vtable, void *user_data) {
if(obj->state == BcStatusNotifierStateStopped) {
lppid_t pid = getpid();
char *dbus_name = g_strdup_printf("%s.%s-%d-%d", params->prefix, ITEM_NAME, pid, params->item_id);
if(obj->params) bc_status_notifier_params_unref(obj->params);
obj->params = bc_status_notifier_params_ref(params);
if(vtable) obj->vtable = *vtable;
else {
obj->vtable.success = NULL;
obj->vtable.fail = NULL;
}
obj->user_data = user_data;
obj->state = BcStatusNotifierStateStarting;
obj->bus_owner_id = g_bus_own_name(
G_BUS_TYPE_SESSION,
dbus_name,
G_BUS_NAME_OWNER_FLAGS_NONE,
(GBusAcquiredCallback)_bc_status_notifier_bus_acquired_cb,
(GBusNameAcquiredCallback)_bc_status_notifier_name_acquired_cb,
(GBusNameLostCallback)_bc_status_notifier_name_lost,
bc_status_notifier_ref(obj),
(GDestroyNotify)bc_status_notifier_unref
);
g_free(dbus_name);
}
}
void bc_status_notifier_stop(BcStatusNotifier *obj) {
if(obj->state == BcStatusNotifierStateRunning) {
g_bus_unown_name(obj->bus_owner_id);
obj->bus_owner_id = 0;
obj->conn = NULL;
obj->state = BcStatusNotifierStateStopped;
}
}
const BcStatusNotifierParams *bc_status_notifier_get_params(const BcStatusNotifier *obj) {
return obj->params;
}
static void _bc_status_notifier_emit_signal(const BcStatusNotifier *obj, const char *sig_name, GVariant *parameters) {
char *item_interface_name = g_strdup_printf("%s.%s", obj->params->prefix, ITEM_NAME);
char *item_path = g_strdup_printf("/%s", ITEM_NAME);
g_dbus_connection_emit_signal(
obj->conn,
NULL,
item_path,
item_interface_name,
sig_name,
parameters,
NULL
);
g_free(item_interface_name);
g_free(item_path);
}
void bc_status_notifier_update_title(BcStatusNotifier *obj, const char *title) {
bc_status_notifier_params_set_title(obj->params, title);
_bc_status_notifier_emit_signal(obj, "NewTitle", NULL);
}
void bc_status_notifier_update_icon(BcStatusNotifier *obj, const char *icon_name) {
bc_status_notifier_params_set_icon_name(obj->params, icon_name);
_bc_status_notifier_emit_signal(obj, "NewIcon", NULL);
}
void bc_status_notifier_update_attention_icon(BcStatusNotifier *obj, const char *icon_name) {
bc_status_notifier_params_set_attention_icon_name(obj->params, icon_name);
_bc_status_notifier_emit_signal(obj, "NewAttentionIcon", NULL);
}
void bc_status_notifier_update_overlay_icon(BcStatusNotifier *obj, const char *icon_name) {
bc_status_notifier_params_set_overlay_icon_name(obj->params, icon_name);
_bc_status_notifier_emit_signal(obj, "NewOverlayIcon", NULL);
}
void bc_status_notifier_update_tool_tip(BcStatusNotifier *obj, BcStatusNotifierToolTip *tool_tip) {
bc_status_notifier_params_set_tool_tip(obj->params, tool_tip);
_bc_status_notifier_emit_signal(obj, "NewToolTip", NULL);
}
void bc_status_notifier_update_status(BcStatusNotifier *obj, BcStatusNotifierStatus status) {
GVariant *status_var = g_variant_new_string(bc_status_notifier_status_to_string(status));
GVariant *parameter = g_variant_new_tuple(&status_var, 1);
bc_status_notifier_params_set_status(obj->params, status);
_bc_status_notifier_emit_signal(obj, "NewStatus", parameter);
}
typedef struct _BcWatcherDetectionCtx {
char *prefix;
guint watcher_id;
BcStatusNotifierSupportDetectionCb cb;
void *user_data;
} BcWatcherDetectionCtx;
static void _bc_watcher_detection_ctx_free(BcWatcherDetectionCtx *obj) {
g_free(obj->prefix);
g_free(obj);
}
static void _bc_watcher_name_appeared_cb(GDBusConnection *conn, const char *name, const char *name_owner, BcWatcherDetectionCtx *ctx) {
g_bus_unwatch_name(ctx->watcher_id);
if(ctx->cb) ctx->cb(ctx->prefix, 1, ctx->user_data);
}
static void _bc_watcher_name_vannished_cb(GDBusConnection *conn, const char *name, BcWatcherDetectionCtx *ctx) {
g_bus_unwatch_name(ctx->watcher_id);
if(ctx->cb) ctx->cb(ctx->prefix, 0, ctx->user_data);
}
void bc_status_notifier_is_supported(const char* prefix, BcStatusNotifierSupportDetectionCb cb, void *user_data) {
char *bus_name = g_strdup_printf("%s.%s", prefix, WATCHER_NAME);
BcWatcherDetectionCtx *ctx = (BcWatcherDetectionCtx *)g_new0(BcWatcherDetectionCtx, 1);
ctx->prefix = g_strdup(prefix);
ctx->cb = cb;
ctx->user_data = user_data;
ctx->watcher_id = g_bus_watch_name(
G_BUS_TYPE_SESSION,
bus_name,
G_BUS_NAME_WATCHER_FLAGS_NONE,
(GBusNameAppearedCallback)_bc_watcher_name_appeared_cb,
(GBusNameVanishedCallback)_bc_watcher_name_vannished_cb,
ctx,
(GDestroyNotify)_bc_watcher_detection_ctx_free
);
g_free(bus_name);
}

163
gtk/status_notifier.h Normal file
View file

@ -0,0 +1,163 @@
/*
linphone, gtk-glade interface.
Copyright (C) 2015 Belledonne Communications <info@belledonne-communications.com>
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.
*/
/**
* BcStatusNotifier is an implementation of the StatusNotiferItem standard defined by freedesktop.org.
* It is a new way to manage status icons on GNU/Linux systems by using D-Bus. It is implemented by
* Unity desktop environmemt and it is the only way to create status icons on KDE 5.
* Visit http://freedesktop.org/wiki/Specifications/StatusNotifierItem/ for more information.
*/
#ifndef STATUS_NOTIFIER_H
#define STATUS_NOTIFIER_H
#include <glib.h>
struct _BcStatusNotifier;
typedef enum {
BcStatusNotifierCategoryApplicationStatus,
BcStatusNotifierCategoryCommunications,
BcStatusNotifierCategorySystemService,
BcStatusNotifierCategoryHardware
} BcStatusNotifierCategory;
const gchar *bc_status_notifier_category_to_string(BcStatusNotifierCategory c);
typedef enum {
BcStatusNotifierStatusPassive,
BcStatusNotifierStatusActive,
BcStatusNotifierStatusNeedsAttention
} BcStatusNotifierStatus;
const gchar *bc_status_notifier_status_to_string(BcStatusNotifierStatus s);
typedef struct _BcStatusNotifierToolTip BcStatusNotifierToolTip;
BcStatusNotifierToolTip *bc_status_notifier_tool_tip_new(const char *icon_name, const char *title, const char *text);
BcStatusNotifierToolTip *bc_status_notifier_tool_tip_ref(BcStatusNotifierToolTip *obj);
void bc_status_notifier_tool_tip_unref(BcStatusNotifierToolTip *obj);
typedef enum _BcStatusNotifierOrientation {
BcStatusNotifierOrientationVertical,
BcStatusNotifierOrientationHorizontal
} BcStatusNotifierOrientation;
typedef void (*BcStatusNotifierContextMenuCalledCb)(struct _BcStatusNotifier *sn, int x, int y, void *user_data);
typedef void (*BcStatusNotifierActivateCalledCb)(struct _BcStatusNotifier *sn, int x, int y, void *user_data);
typedef void (*BcStatusNotifierSecondaryActivateCb)(struct _BcStatusNotifier *sn, int x, int y, void *user_data);
typedef void (*BcStatusNotifierScrollCalledCb)(struct _BcStatusNotifier *sn, int delta, BcStatusNotifierOrientation o, void *user_data);
typedef struct _BcStatusNotifierSignalsVTable {
BcStatusNotifierContextMenuCalledCb context_menu_called_cb;
BcStatusNotifierActivateCalledCb activate_called_cb;
BcStatusNotifierSecondaryActivateCb secondary_activate_called_cb;
BcStatusNotifierScrollCalledCb scroll_called_cb;
} BcStatusNotifierSignalsVTable;
typedef struct _BcStatusNotifierParams BcStatusNotifierParams;
BcStatusNotifierParams *bc_status_notifier_params_new(void);
BcStatusNotifierParams *bc_status_notifier_params_ref(BcStatusNotifierParams *obj);
void bc_status_notifier_params_unref(BcStatusNotifierParams *obj);
void bc_status_notifier_params_set_dbus_prefix(BcStatusNotifierParams *obj, const char *prefix);
const char *bc_satus_notifier_params_get_dbus_prefix(const BcStatusNotifierParams *obj);
void bc_status_notifier_params_set_item_id(BcStatusNotifierParams *obj, int item_id);
int bc_status_notifier_params_get_item_id(const BcStatusNotifierParams *obj);
void bc_status_notifier_params_set_category(BcStatusNotifierParams *obj, BcStatusNotifierCategory category);
BcStatusNotifierCategory bc_status_notifier_params_get_category(const BcStatusNotifierParams *obj);
void bc_status_notifier_params_set_id(BcStatusNotifierParams *obj, const char *id);
const char *bc_status_notifier_params_get_id(const BcStatusNotifierParams *obj);
void bc_status_notifier_params_set_title(BcStatusNotifierParams *obj, const char *title);
const char *bc_status_notifier_params_get_title(const BcStatusNotifierParams *obj);
void bc_status_notifier_params_set_status(BcStatusNotifierParams *obj, BcStatusNotifierStatus status);
BcStatusNotifierStatus bc_status_notifier_params_get_status(const BcStatusNotifierParams *obj);
void bc_status_notifier_params_set_window_id(BcStatusNotifierParams *obj, guint32 window_id);
guint32 bc_status_notifier_params_get_window_id(const BcStatusNotifierParams *obj);
void bc_status_notifier_params_set_icon_name(BcStatusNotifierParams *obj, const char *name);
const char *bc_status_notifier_params_get_icon_name(const BcStatusNotifierParams *obj);
void bc_status_notifier_params_set_overlay_icon_name(BcStatusNotifierParams *obj, const char *name);
const char *bc_status_notifier_params_get_overlay_icon_name(const BcStatusNotifierParams *obj);
void bc_status_notifier_params_set_attention_icon_name(BcStatusNotifierParams *obj, const char *icon_name);
const char *bc_status_notifier_params_get_attention_icon_name(const BcStatusNotifierParams *obj);
void bc_status_notifier_params_set_attention_movie_name(BcStatusNotifierParams *obj, const char *name);
const char *bc_status_notifier_params_get_attention_movie_name(const BcStatusNotifierParams *obj);
void bc_status_notifier_params_set_tool_tip(BcStatusNotifierParams *obj, BcStatusNotifierToolTip *tool_tip);
const BcStatusNotifierToolTip *bc_status_notifier_params_get_tool_tip(const BcStatusNotifierParams *obj);
void bc_status_notifier_params_set_vtable(BcStatusNotifierParams *obj, const BcStatusNotifierSignalsVTable *vtable, void *user_data);
typedef enum _BcStatusNotifierState {
BcStatusNotifierStateStopped,
BcStatusNotifierStateStarting,
BcStatusNotifierStateRunning
} BcStatusNotifierState;
typedef void (*BcStatusNotifierStartedCb)(struct _BcStatusNotifier *sn, void *user_data);
typedef void (*BcStatusNotifierStartingFailedCb)(struct _BcStatusNotifier *sn, void *user_data);
typedef struct _BcStatusNotifierStateVTable {
BcStatusNotifierStartedCb success;
BcStatusNotifierStartingFailedCb fail;
} BcStatusNotifierStateVTable;
typedef struct _BcStatusNotifier BcStatusNotifier;
BcStatusNotifier *bc_status_notifier_new(void);
BcStatusNotifier *bc_status_notifier_ref(BcStatusNotifier *obj);
void bc_status_notifier_unref(BcStatusNotifier *obj);
void bc_status_notifier_start(BcStatusNotifier* obj, BcStatusNotifierParams* params, const BcStatusNotifierStateVTable* vtable, void* user_data);
void bc_status_notifier_stop(BcStatusNotifier* obj);
const BcStatusNotifierParams *bc_status_notifier_get_params(const BcStatusNotifier *obj);
void bc_status_notifier_update_title(BcStatusNotifier* obj, const char* title);
void bc_status_notifier_update_icon(BcStatusNotifier* obj, const char* icon_name);
void bc_status_notifier_update_attention_icon(BcStatusNotifier* obj, const char* icon_name);
void bc_status_notifier_update_overlay_icon(BcStatusNotifier* obj, const char* icon_name);
void bc_status_notifier_update_tool_tip(BcStatusNotifier* obj, BcStatusNotifierToolTip* tool_tip);
void bc_status_notifier_update_status(BcStatusNotifier* obj, BcStatusNotifierStatus status);
typedef void (*BcStatusNotifierSupportDetectionCb)(const char *prefix, gboolean is_supported, void *user_data);
void bc_status_notifier_is_supported(const char* prefix, BcStatusNotifierSupportDetectionCb cb, void *user_data);
#endif

View file

@ -102,14 +102,14 @@ void linphone_gtk_reload_sound_devices(void){
GtkWidget *mw=linphone_gtk_get_main_window();
GtkWidget *pb=(GtkWidget*)g_object_get_data(G_OBJECT(mw),"parameters");
linphone_core_reload_sound_devices(linphone_gtk_get_core());
linphone_gtk_fill_soundcards(pb);
if (pb) linphone_gtk_fill_soundcards(pb);
}
void linphone_gtk_reload_video_devices(void){
GtkWidget *mw=linphone_gtk_get_main_window();
GtkWidget *pb=(GtkWidget*)g_object_get_data(G_OBJECT(mw),"parameters");
linphone_core_reload_video_devices(linphone_gtk_get_core());
linphone_gtk_fill_webcams(pb);
if (pb) linphone_gtk_fill_webcams(pb);
}
#ifdef HAVE_LIBUDEV_H

View file

@ -68,15 +68,20 @@ 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_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_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)
#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*);

View file

@ -131,4 +131,31 @@ public interface LinphoneCallParams {
* @return The received video size.
*/
VideoSize getReceivedVideoSize();
/**
* Use to enable multicast rtp for audio stream.
* * If enabled, outgoing calls put a multicast address from #linphone_core_get_video_multicast_addr into audio cline. In case of outgoing call audio stream is sent to this multicast address.
* <br> For incoming calls behavior is unchanged.
* @param yesno if yes, subsequent calls will propose multicast ip set by LinphoneCore.setAudioMulticastAddr
**/
void enableAudioMulticast(boolean yesno);
/**
* Use to get multicast state of audio stream.
* @return true if subsequent calls will propose multicast ip set by LinphoneCore.setAudioMulticastAddr
**/
boolean audioMulticastEnabled();
/**
* Use to enable multicast rtp for video stream.
* If enabled, outgoing calls put a multicast address from #linphone_core_get_video_multicast_addr into video cline. In case of outgoing call video stream is sent to this multicast address.
* <br> For incoming calls behavior is unchanged.
* @param yesno if yes, subsequent outgoing calls will propose multicast ip set by LinphoneCore.setVideoMulticastAddr
**/
void enableVideoMulticast(boolean yesno);
/**
* Use to get multicast state of video stream.
* @return true if subsequent calls will propose multicast ip set by LinphoneCore.setVideoMulticastAddr
**/
boolean videoMulticastEnabled();
}

View file

@ -889,6 +889,12 @@ public interface LinphoneCore {
*/
void addFriend(LinphoneFriend lf) throws LinphoneCoreException;
/**
* Get list of LinphoneFriend
* @return LinphoneFriend list
*/
LinphoneFriend[] getFriendList();
/**
* @brief Set my presence status
* @param minutes_away how long in away

View file

@ -306,6 +306,13 @@ public interface LinphoneProxyConfig {
**/
void setUserData(Object obj);
/**
* Detect if the given input is a phone number or not.
* @param username string to parse.
* @return TRUE if input is a phone number, FALSE otherwise.
**/
boolean isPhoneNumber(String username);
/**
* Returns user data from a proxy config. return null if any
* @return an Object.

View file

@ -150,4 +150,25 @@ public class LinphoneCallParamsImpl implements LinphoneCallParams {
vSize.height = nativeSize[1];
return vSize;
}
private native void enableAudioMulticast(long ptr,boolean yesno);
@Override
public void enableAudioMulticast(boolean yesno) {
enableAudioMulticast(nativePtr,yesno);
}
private native boolean audioMulticastEnabled(long ptr);
@Override
public boolean audioMulticastEnabled() {
return audioMulticastEnabled(nativePtr);
}
private native void enableVideoMulticast(long ptr,boolean yesno);
@Override
public void enableVideoMulticast(boolean yesno) {
enableVideoMulticast(nativePtr,yesno);
}
private native boolean videoMulticastEnabled(long ptr);
@Override
public boolean videoMulticastEnabled() {
return videoMulticastEnabled(nativePtr);
}
}

View file

@ -20,6 +20,7 @@ package org.linphone.core;
import java.io.File;
import java.io.IOException;
import java.util.List;
import org.linphone.mediastream.MediastreamerAndroidContext;
import org.linphone.mediastream.Version;
@ -33,30 +34,41 @@ public class LinphoneCoreFactoryImpl extends LinphoneCoreFactory {
System.loadLibrary(s);
return true;
} catch (Throwable e) {
Log.w("Unable to load optional library lib", s);
Log.w("LinphoneCoreFactoryImpl", "Unable to load optional library lib" + s);
}
return false;
}
static {
String eabi = "armeabi";
if (Version.isX86()) {
eabi = "x86";
} else if (Version.isArmv7()) {
eabi = "armeabi-v7a";
List<String> cpuabis=Version.getCpuAbis();
String ffmpegAbi;
boolean libLoaded=false;
Throwable firstException=null;
for (String abi : cpuabis){
Log.i("LinphoneCoreFactoryImpl","Trying to load liblinphone for " + abi);
ffmpegAbi=abi;
// FFMPEG (audio/video)
if (abi.startsWith("armeabi")) {
ffmpegAbi="arm";
}
loadOptionalLibrary("ffmpeg-linphone-"+ffmpegAbi);
//Main library
try {
System.loadLibrary("linphone-" + abi);
Log.i("LinphoneCoreFactoryImpl","Loading done with " + abi);
libLoaded=true;
break;
}catch(Throwable e) {
if (firstException == null) firstException=e;
}
}
// FFMPEG (audio/video)
if (Version.isX86()) {
loadOptionalLibrary("ffmpeg-linphone-x86");
} else if (Version.isArmv7()) {
loadOptionalLibrary("ffmpeg-linphone-arm");
if (!libLoaded){
throw new RuntimeException(firstException);
}else{
Version.dumpCapabilities();
}
//Main library
System.loadLibrary("linphone-" + eabi);
Version.dumpCapabilities();
}
@Override
public LinphoneAuthInfo createAuthInfo(String username, String password,

View file

@ -92,6 +92,7 @@ class LinphoneCoreImpl implements LinphoneCore {
private native void setPreviewWindowId(long nativePtr, Object wid);
private native void setDeviceRotation(long nativePtr, int rotation);
private native void addFriend(long nativePtr,long friend);
private native LinphoneFriend[] getFriendList(long nativePtr);
private native void setPresenceInfo(long nativePtr, int minutes_away, String alternative_contact, int status);
private native int getPresenceInfo(long nativePtr);
private native void setPresenceModel(long nativePtr, long presencePtr);
@ -433,8 +434,12 @@ class LinphoneCoreImpl implements LinphoneCore {
public synchronized void addFriend(LinphoneFriend lf) throws LinphoneCoreException {
addFriend(nativePtr,((LinphoneFriendImpl)lf).nativePtr);
}
public synchronized LinphoneFriend[] getFriendList() {
return getFriendList(nativePtr);
}
@SuppressWarnings("deprecation")
public synchronized void setPresenceInfo(int minutes_away, String alternative_contact, OnlineStatus status) {
setPresenceInfo(nativePtr,minutes_away,alternative_contact,status.mValue);
@ -955,14 +960,10 @@ class LinphoneCoreImpl implements LinphoneCore {
removeFriend(nativePtr, lf.getNativePtr());
}
private native long getFriendByAddress(long ptr, String sipUri);
private native LinphoneFriend getFriendByAddress(long ptr, String sipUri);
@Override
public synchronized LinphoneFriend findFriendByAddress(String sipUri) {
long ptr = getFriendByAddress(nativePtr, sipUri);
if (ptr == 0) {
return null;
}
return new LinphoneFriendImpl(ptr);
return getFriendByAddress(nativePtr, sipUri);
}
public synchronized void setAudioPort(int port) {

View file

@ -22,6 +22,7 @@ import java.io.Serializable;
class LinphoneFriendImpl implements LinphoneFriend, Serializable {
protected final long nativePtr;
private native void finalize(long nativePtr);
private native long newLinphoneFriend(String friendUri);
private native void setAddress(long nativePtr,long friend);
private native long getAddress(long nativePtr);
@ -34,24 +35,26 @@ class LinphoneFriendImpl implements LinphoneFriend, Serializable {
private native void setPresenceModel(long nativePtr, long presencePtr);
private native void edit(long nativePtr);
private native void done(long nativePtr);
private native void delete(long ptr);
private native Object getCore(long ptr);
private native void setRefKey(long nativePtr, String key);
private native String getRefKey(long nativePtr);
boolean ownPtr = false;
protected LinphoneFriendImpl() {
nativePtr = newLinphoneFriend(null);
}
}
protected LinphoneFriendImpl(String friendUri) {
nativePtr = newLinphoneFriend(friendUri);
}
/*reserved for JNI */
protected LinphoneFriendImpl(long aNativePtr) {
nativePtr = aNativePtr;
ownPtr=false;
}
protected void finalize() throws Throwable {
if (ownPtr) delete(nativePtr);
if (nativePtr != 0) {
finalize(nativePtr);
}
super.finalize();
}
public void setAddress(LinphoneAddress anAddress) {
this.setAddress(nativePtr, ((LinphoneAddressImpl)anAddress).nativePtr);

View file

@ -362,6 +362,12 @@ class LinphoneProxyConfigImpl implements LinphoneProxyConfig {
return getPublishExpires(nativePtr);
}
private native boolean isPhoneNumber(long nativePtr,String username);
@Override
public boolean isPhoneNumber(String username){
return isPhoneNumber(nativePtr,username);
}
@Override
public void setUserData(Object obj) {
userData = obj;

View file

@ -16,13 +16,21 @@ ShowLanguageDialog=yes
UninstallDisplayIcon={app}\bin\linphone.exe
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
Name: "italian"; MessagesFile: "compiler:Languages\Italian.isl";
Name: "french"; MessagesFile: "compiler:Languages\French.isl"
Name: "czech"; MessagesFile: "compiler:Languages\Czech.isl"
Name: "german"; MessagesFile: "compiler:Languages\German.isl"
Name: "spanish"; MessagesFile: "compiler:Languages\Spanish.isl"
Name: "czech"; MessagesFile: "compiler:Languages\Czech.isl"
Name: "english"; MessagesFile: "compiler:Default.isl"
Name: "french"; MessagesFile: "compiler:Languages\French.isl"
Name: "german"; MessagesFile: "compiler:Languages\German.isl"
Name: "hebrew"; MessagesFile: "compiler:Languages\Hebrew.isl"
Name: "hungarian"; MessagesFile: "compiler:Languages\Hungarian.isl"
Name: "italian"; MessagesFile: "compiler:Languages\Italian.isl";
Name: "japanese"; MessagesFile: "compiler:Languages\Japanese.isl"
Name: "norwegian"; MessagesFile: "compiler:Languages\Norwegian.isl"
Name: "polish"; MessagesFile: "compiler:Languages\Polish.isl"
Name: "portuguese"; MessagesFile: "compiler:Languages\Portuguese.isl"
Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl"
Name: "slovenian"; MessagesFile: "compiler:Languages\Slovenian.isl"
Name: "spanish"; MessagesFile: "compiler:Languages\Spanish.isl"
Name: "turkish"; MessagesFile: "compiler:Languages\Turkish.isl"
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked

@ -1 +1 @@
Subproject commit 524b87f7f6b4e87f0676dba1ca9e3e71dae77482
Subproject commit ebf5adcbb3a9e48ef5d71635cdfc62ecddba10d4

2
oRTP

@ -1 +1 @@
Subproject commit f21b5418b62c8acbe7a8a3be4ddf569af537d35e
Subproject commit 15476b915d35e91f3bad92b5e7d1bc4073c50603

View file

@ -42,6 +42,7 @@ set(PIXMAPS
hold_on.png
linphone-banner.png
linphone.icns
linphone.png
mic_active.png
mic_muted.png
notok.png

View file

@ -21,8 +21,7 @@
############################################################################
if(GETTEXT_FOUND)
string(REPLACE " " ";" LANGUAGES ${LINPHONE_ALL_LANGS})
foreach(language ${LANGUAGES})
foreach(language ${LINPHONE_ALL_LANGS_LIST})
GETTEXT_PROCESS_PO_FILES(${language} ALL PO_FILES ${language}.po)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${language}.gmo
DESTINATION ${PACKAGE_LOCALE_DIR}/${language}/LC_MESSAGES

490
po/ar.po

File diff suppressed because it is too large Load diff

442
po/cs.po

File diff suppressed because it is too large Load diff

442
po/de.po

File diff suppressed because it is too large Load diff

442
po/es.po

File diff suppressed because it is too large Load diff

448
po/fr.po

File diff suppressed because it is too large Load diff

442
po/he.po

File diff suppressed because it is too large Load diff

442
po/hu.po

File diff suppressed because it is too large Load diff

440
po/it.po

File diff suppressed because it is too large Load diff

442
po/ja.po

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

442
po/nl.po

File diff suppressed because it is too large Load diff

462
po/pl.po

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

444
po/ru.po

File diff suppressed because it is too large Load diff

442
po/sr.po

File diff suppressed because it is too large Load diff

442
po/sv.po

File diff suppressed because it is too large Load diff

556
po/tr.po

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -33,6 +33,7 @@ liblinphonetester_la_SOURCES = \
upnp_tester.c \
video_tester.c \
common/bc_tester_utils.c
liblinphonetester_ladir = $(includedir)/linphone
liblinphonetester_la_HEADERS = common/bc_tester_utils.h

View file

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<cache><selfZID>ef7692d0792a67491ae2d44e</selfZID><peer><ZID>005dbe0399643d953a2202dd</ZID><rs1>9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045</rs1><aux>f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e</aux><rs2>2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899</rs2><uri>pipo1@pipo.com</uri><sndKey>963c57bb28e62068d2df23e8f9b771932d3c57bb28e62068d2df23e8f9b77193</sndKey><rcvKey>05d9ac653a83c4559cb0ae7394e7cd3b2d3c57bb28e62068d2df23e8f9b77193</rcvKey><sndSId>5f9aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b77193</sndSId><rcvSId>02ffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b77193</rcvSId><sndIndex>00000069</sndIndex><rcvIndex>000001e8</rcvIndex><pvs>01</pvs></peer><peer><ZID>1234567889643d953a2202ee</ZID><rs1>9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045</rs1><aux>f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e</aux><rs2>2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899</rs2><uri>pipo1@pipo.com</uri><sndKey>123456789012345678901234567890123456765431262068d2df23e8f9b77193</sndKey><rcvKey>25d9ac653a83c4559cb0ae7394e7cd3b2d3c57bb28e62068d2df23e8f9b77193</rcvKey><sndSId>f69aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b77193</sndSId><rcvSId>22ffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b77193</rcvSId><sndIndex>00000001</sndIndex><rcvIndex>00000000</rcvIndex><pvs>01</pvs></peer></cache>

View file

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<cache><selfZID>ef7692d0792a67491ae2d44e</selfZID><peer><ZID>005dbe0399643d953a2202dd</ZID><rs1>9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045</rs1><aux>f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e</aux><rs2>2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899</rs2><uri>sip:pauline@sip.example.org</uri><sndKey>9111ebeb52e50edcc6fcb3eea1a2d3ae3c2c75d3668923e83c59d0f472455150</sndKey><rcvKey>60f020a3fe11dc2cc0e1e8ed9341b4cd14944db806ca4fc95456bbe45d95c43a</rcvKey><sndSId>5f9aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b77193</sndSId><rcvSId>bcffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b77193</rcvSId><sndIndex>00000080</sndIndex><rcvIndex>000001cf</rcvIndex><pvs>01</pvs></peer><peer><ZID>1234567889643d953a2202ee</ZID><rs1>9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045</rs1><aux>f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e</aux><rs2>2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899</rs2><uri>sip:pauline@sip.example.org</uri><sndKey>72d80ab1cad243cf45634980c1d02cfb2df81ce0dd5dfcf1ebeacfc5345a9176</sndKey><rcvKey>25d9ac653a83c4559cb0ae7394e7cd3b2d3c57bb28e62068d2df23e8f9b77193</rcvKey><sndSId>f69aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b77193</sndSId><rcvSId>22ffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b77193</rcvSId><sndIndex>0000000f</sndIndex><rcvIndex>00000000</rcvIndex></peer></cache>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<cache><selfZID>005dbe0399643d953a2202dd</selfZID>
<peer><ZID>ef7692d0792a67491ae2d44e</ZID><rs1>9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045</rs1><aux>f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e</aux><rs2>2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899</rs2><uri>sip:marie@sip.example.org</uri><rcvKey>9111ebeb52e50edcc6fcb3eea1a2d3ae3c2c75d3668923e83c59d0f472455150</rcvKey><sndKey>60f020a3fe11dc2cc0e1e8ed9341b4cd14944db806ca4fc95456bbe45d95c43a</sndKey><rcvSId>5f9aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b77193</rcvSId><sndSId>bcffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b77193</sndSId><rcvIndex>00000080</rcvIndex><sndIndex>000001cf</sndIndex><pvs>01</pvs></peer>
<peer><ZID>1234567889643d953a2202ee</ZID><rs1>9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045</rs1><aux>f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e</aux><rs2>2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899</rs2><uri>sip:marie@sip.example.org</uri><sndKey>81e6e6362c34dc974263d1f77cbb9a8d6d6a718330994379099a8fa19fb12faa</sndKey><rcvKey>25d9ac653a83c4559cb0ae7394e7cd3b2d3c57bb28e62068d2df23e8f9b77193</rcvKey><sndSId>f69aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b77193</sndSId><rcvSId>22ffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b77193</rcvSId><sndIndex>0000002e</sndIndex><rcvIndex>00000000</rcvIndex><pvs>01</pvs></peer></cache>

File diff suppressed because it is too large Load diff

View file

@ -22,8 +22,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "bc_tester_utils.h"
#include <stdarg.h>
#include <stdlib.h>
#include "CUnit/Basic.h"
#include "CUnit/Automated.h"
#if WINAPI_FAMILY_PHONE_APP
@ -41,6 +42,9 @@ const char *bc_tester_writable_dir_prefix = "/data/data/org.linphone.tester/cach
const char *bc_tester_writable_dir_prefix = ".";
#endif
int bc_printf_verbosity_info;
int bc_printf_verbosity_error;
static test_suite_t **test_suite = NULL;
static int nb_test_suites = 0;
@ -54,10 +58,8 @@ int xml_enabled = 0;
char * suite_name;
char * test_name;
void (*tester_printf_va)(int level, const char *fmt, va_list args);
int verbosity_info;
int verbosity_error;
static void tester_printf(int level, const char *fmt, ...) {
void bc_tester_printf(int level, const char *fmt, ...) {
va_list args;
va_start (args, fmt);
tester_printf_va(level, fmt, args);
@ -115,7 +117,7 @@ int bc_tester_nb_tests(const char *suite_name) {
void bc_tester_list_suites() {
int j;
for(j=0;j<nb_test_suites;j++) {
tester_printf(verbosity_info, "%s", bc_tester_suite_name(j));
bc_tester_printf(bc_printf_verbosity_info, "%s", bc_tester_suite_name(j));
}
}
@ -123,36 +125,36 @@ void bc_tester_list_tests(const char *suite_name) {
int j;
for( j = 0; j < bc_tester_nb_tests(suite_name); j++) {
const char *test_name = bc_tester_test_name(suite_name, j);
tester_printf(verbosity_info, "%s", test_name);
bc_tester_printf(bc_printf_verbosity_info, "%s", test_name);
}
}
static void all_complete_message_handler(const CU_pFailureRecord pFailure) {
#ifdef HAVE_CU_GET_SUITE
char * results = CU_get_run_results_string();
tester_printf(verbosity_info,"\n%s",results);
bc_tester_printf(bc_printf_verbosity_info,"\n%s",results);
free(results);
#endif
}
static void suite_init_failure_message_handler(const CU_pSuite pSuite) {
tester_printf(verbosity_error,"Suite initialization failed for [%s]", pSuite->pName);
bc_tester_printf(bc_printf_verbosity_error,"Suite initialization failed for [%s]", pSuite->pName);
}
static void suite_cleanup_failure_message_handler(const CU_pSuite pSuite) {
tester_printf(verbosity_error,"Suite cleanup failed for [%s]", pSuite->pName);
bc_tester_printf(bc_printf_verbosity_error,"Suite cleanup failed for [%s]", pSuite->pName);
}
#ifdef HAVE_CU_GET_SUITE
static void suite_start_message_handler(const CU_pSuite pSuite) {
tester_printf(verbosity_info,"Suite [%s] started", pSuite->pName);
bc_tester_printf(bc_printf_verbosity_info,"Suite [%s] started\n", pSuite->pName);
}
static void suite_complete_message_handler(const CU_pSuite pSuite, const CU_pFailureRecord pFailure) {
tester_printf(verbosity_info,"Suite [%s] ended", pSuite->pName);
bc_tester_printf(bc_printf_verbosity_info,"Suite [%s] ended\n", pSuite->pName);
}
static void test_start_message_handler(const CU_pTest pTest, const CU_pSuite pSuite) {
tester_printf(verbosity_info,"Suite [%s] Test [%s] started", pSuite->pName,pTest->pName);
bc_tester_printf(bc_printf_verbosity_info,"Suite [%s] Test [%s] started", pSuite->pName,pTest->pName);
}
/*derivated from cunit*/
@ -176,7 +178,7 @@ static void test_complete_message_handler(const CU_pTest pTest,
} else {
strncat(result, " passed", strlen(" passed"));
}
tester_printf(verbosity_info,"%s\n", result);
bc_tester_printf(bc_printf_verbosity_info,"%s\n", result);
}
#endif
@ -206,26 +208,26 @@ int bc_tester_run_tests(const char *suite_name, const char *test_name) {
#ifndef HAVE_CU_GET_SUITE
if( suite_name ){
tester_printf(verbosity_info, "Tester compiled without CU_get_suite() function, running all tests instead of suite '%s'", suite_name);
bc_tester_printf(bc_printf_verbosity_info, "Tester compiled without CU_get_suite() function, running all tests instead of suite '%s'", suite_name);
}
#else
if (suite_name){
CU_pSuite suite;
suite=CU_get_suite(suite_name);
if (!suite) {
tester_printf(verbosity_error, "Could not find suite '%s'. Available suites are:", suite_name);
bc_tester_printf(bc_printf_verbosity_error, "Could not find suite '%s'. Available suites are:", suite_name);
bc_tester_list_suites();
return -1;
} else if (test_name) {
CU_pTest test=CU_get_test_by_name(test_name, suite);
if (!test) {
tester_printf(verbosity_error, "Could not find test '%s' in suite '%s'. Available tests are:", test_name, suite_name);
bc_tester_printf(bc_printf_verbosity_error, "Could not find test '%s' in suite '%s'. Available tests are:", test_name, suite_name);
// do not use suite_name here, since this method is case sensitive
bc_tester_list_tests(suite->pName);
return -2;
} else {
CU_ErrorCode err= CU_run_test(suite, test);
if (err != CUE_SUCCESS) tester_printf(verbosity_error, "CU_basic_run_test error %d", err);
if (err != CUE_SUCCESS) bc_tester_printf(bc_printf_verbosity_error, "CU_basic_run_test error %d", err);
}
} else {
CU_run_suite(suite);
@ -253,7 +255,7 @@ int bc_tester_run_tests(const char *suite_name, const char *test_name) {
void bc_tester_helper(const char *name, const char* additionnal_helper) {
tester_printf(verbosity_info,"%s --help\n"
bc_tester_printf(bc_printf_verbosity_info,"%s --help\n"
"\t\t\t--list-suites\n"
"\t\t\t--list-tests <suite>\n"
"\t\t\t--suite <suite name>\n"
@ -271,8 +273,8 @@ void bc_tester_helper(const char *name, const char* additionnal_helper) {
void bc_tester_init(void (*ftester_printf)(int level, const char *fmt, va_list args), int iverbosity_info, int iverbosity_error) {
tester_printf_va = ftester_printf;
verbosity_error = iverbosity_error;
verbosity_info = iverbosity_info;
bc_printf_verbosity_error = iverbosity_error;
bc_printf_verbosity_info = iverbosity_info;
}
int bc_tester_parse_args(int argc, char **argv, int argid)
@ -301,12 +303,12 @@ int bc_tester_parse_args(int argc, char **argv, int argid)
} else if (strcmp(argv[i], "--xml") == 0){
xml_enabled = 1;
}else {
tester_printf(verbosity_error, "Unknown option \"%s\"\n", argv[i]);
bc_tester_printf(bc_printf_verbosity_error, "Unknown option \"%s\"\n", argv[i]);
return -1;
}
if( xml_enabled && (suite_name || test_name) ){
tester_printf(verbosity_error, "Cannot use both XML and specific test suite\n");
bc_tester_printf(bc_printf_verbosity_error, "Cannot use both XML and specific test suite\n");
return -1;
}
@ -346,7 +348,7 @@ void bc_tester_uninit() {
}
CU_cleanup_registry();
/*add missing final newline*/
tester_printf(verbosity_info,"");
bc_tester_printf(bc_printf_verbosity_info,"");
if( xml_enabled ){
/*create real xml file only if tester did not crash*/
@ -363,3 +365,13 @@ void bc_tester_uninit() {
nb_test_suites = 0;
}
}
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;
}

View file

@ -20,13 +20,20 @@
#ifndef TESTER_UTILS_H
#define TESTER_UTILS_H
#include "CUnit/Basic.h"
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <math.h>
extern const char *bc_tester_read_dir_prefix;
extern const char *bc_tester_writable_dir_prefix;
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);
typedef struct {
@ -36,8 +43,8 @@ typedef struct {
typedef struct {
const char *name;
CU_InitializeFunc init_func;
CU_CleanupFunc cleanup_func;
init_function_t init_func;
cleanup_function_t cleanup_func;
int nb_tests;
test_t *tests;
} test_suite_t;
@ -60,6 +67,7 @@ int bc_tester_parse_args(int argc, char** argv, int argid);
int bc_tester_start();
void bc_tester_add_suite(test_suite_t *suite);
void bc_tester_uninit();
void bc_tester_printf(int level, const char *fmt, ...);
int bc_tester_nb_suites();
int bc_tester_nb_tests(const char* name);
@ -71,6 +79,72 @@ 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);
/**
* Get full path to the given resource
*
* @param name relative resource path (relative to bc_tester_writable_dir_prefix)
* @return path to the resource. Must be freed by caller.
*/
char * bc_tester_res(const char *name);
/*Redefine the CU_... macros WITHOUT final ';' semicolon, to allow IF conditions and with smarter error message */
extern int CU_assertImplementation(int bValue,
unsigned int uiLine,
const char *strCondition,
const char *strFile,
const char *strFunction,
int bFatal);
#define _BC_ASSERT(pred, format, fatal) CU_assertImplementation(pred, __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); \
} 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_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)
#define BC_ASSERT_NOT_EQUAL_FATAL(actual, expected, type, type_format) _BC_ASSERT_PRED("BC_ASSERT_NOT_EQUAL_FATAL", ((cactual) != (cexpected)), actual, expected, type, TRUE, "Expected NOT " type_format " but it was.", cexpected)
#define BC_ASSERT_PTR_EQUAL(actual, expected) _BC_ASSERT_PRED("BC_ASSERT_PTR_EQUAL", ((cactual) == (cexpected)), (const void*)(actual), (const void*)(expected), const void*, FALSE, "Expected %p but was %p.", cexpected, cactual)
#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_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)
#define BC_ASSERT_STRING_NOT_EQUAL_FATAL(actual, expected) _BC_ASSERT_PRED("BC_ASSERT_STRING_NOT_EQUAL_FATAL", (strcmp((const char*)(cactual), (const char*)(cexpected))), actual, expected, const char*, TRUE, "Expected NOT %s but it was.", cexpected)
#define BC_ASSERT_NSTRING_EQUAL(actual, expected, count) _BC_ASSERT_PRED("BC_ASSERT_NSTRING_EQUAL", !(strncmp((const char*)(cactual), (const char*)(cexpected), (size_t)(count))), actual, expected, const char*, FALSE, "Expected %*s but was %*s.", (int)(count), cexpected, (int)(count), cactual)
#define BC_ASSERT_NSTRING_EQUAL_FATAL(actual, expected, count) _BC_ASSERT_PRED("BC_ASSERT_NSTRING_EQUAL_FATAL", !(strncmp((const char*)(cactual), (const char*)(cexpected), (size_t)(count))), actual, expected, const char*, TRUE, "Expected %*s but was %*s.", (int)count, cexpected, (int)count, cactual)
#define BC_ASSERT_NSTRING_NOT_EQUAL(actual, expected, count) _BC_ASSERT_PRED("BC_ASSERT_NSTRING_NOT_EQUAL", (strncmp((const char*)(cactual), (const char*)(cexpected), (size_t)(count))), actual, expected, const char*, FALSE, "Expected %*s but it was.", (int)count, cexpected)
#define BC_ASSERT_NSTRING_NOT_EQUAL_FATAL(actual, expected, count) _BC_ASSERT_PRED("BC_ASSERT_NSTRING_NOT_EQUAL_FATAL", (strncmp((const char*)(cactual), (const char*)(cexpected), (size_t)(count))), actual, expected, const char*, TRUE, "Expected %*s but it was.", (int)count, cexpected)
#define BC_ASSERT_DOUBLE_EQUAL(actual, expected, granularity) _BC_ASSERT_PRED("BC_ASSERT_DOUBLE_EQUAL", ((fabs((double)(cactual) - (cexpected)) <= fabs((double)(granularity)))), actual, expected, double, FALSE, "Expected %f but was %f.", cexpected, cactual)
#define BC_ASSERT_DOUBLE_EQUAL_FATAL(actual, expected, granularity) _BC_ASSERT_PRED("BC_ASSERT_DOUBLE_EQUAL_FATAL", ((fabs((double)(cactual) - (cexpected)) <= fabs((double)(granularity)))), actual, expected, double, TRUE, "Expected %f but was %f.", cexpected, cactual)
#define BC_ASSERT_DOUBLE_NOT_EQUAL(actual, expected, granularity) _BC_ASSERT_PRED("BC_ASSERT_DOUBLE_NOT_EQUAL", ((fabs((double)(cactual) - (cexpected)) > fabs((double)(granularity)))), actual, expected, double, FALSE, "Expected %f but was %f.", cexpected, cactual)
#define BC_ASSERT_DOUBLE_NOT_EQUAL_FATAL(actual, expected, granularity) _BC_ASSERT_PRED("BC_ASSERT_DOUBLE_NOT_EQUAL_FATAL", ((fabs((double)(cactual) - (cexpected)) > fabs((double)(granularity)))), actual, expected, double, TRUE, "Expected %f but was %f.", cexpected, cactual)
/*Custom defines*/
#define BC_ASSERT_GREATER(actual, lower, type, type_format) _BC_ASSERT_PRED("BC_ASSERT_GREATER", ((cactual) >= (cexpected)), actual, lower, type, FALSE, "Expected at least " type_format " but was " type_format ".", cexpected, cactual)
#define BC_ASSERT_LOWER(actual, lower, type, type_format) _BC_ASSERT_PRED("BC_ASSERT_LOWER", ((cactual) <= (cexpected)), actual, lower, type, FALSE, "Expected at most " type_format " but was " type_format ".", cexpected, cactual)
#ifdef __cplusplus
}
#endif

View file

@ -43,12 +43,12 @@ void send_dtmf_base(bool_t use_rfc2833, bool_t use_sipinfo, char dtmf, char* dtm
linphone_core_set_use_rfc2833_for_dtmf(pauline->lc, use_rfc2833);
linphone_core_set_use_info_for_dtmf(pauline->lc, use_sipinfo);
CU_ASSERT_TRUE(call(pauline,marie));
BC_ASSERT_TRUE(call(pauline,marie));
marie_call = linphone_core_get_current_call(marie->lc);
CU_ASSERT_PTR_NOT_NULL(marie_call);
BC_ASSERT_PTR_NOT_NULL(marie_call);
if (!marie_call) return;
if (dtmf != '\0') {
@ -56,7 +56,7 @@ void send_dtmf_base(bool_t use_rfc2833, bool_t use_sipinfo, char dtmf, char* dtm
linphone_call_send_dtmf(marie_call, dtmf);
/*wait for the DTMF to be received from pauline*/
CU_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, &pauline->stat.dtmf_count, dtmf_count_prev+1, 10000));
BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, &pauline->stat.dtmf_count, dtmf_count_prev+1, 10000));
expected = ms_strdup_printf("%c", dtmf);
}
@ -66,29 +66,29 @@ 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*/
CU_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, dtmf_count_prev + strlen(dtmf_seq), 10000 + dtmf_delay_ms * strlen(dtmf_seq)));
expected = (dtmf!='\0')?ms_strdup_printf("%c%s",dtmf,dtmf_seq):ms_strdup(dtmf_seq);
}
if (expected != NULL) {
CU_ASSERT_PTR_NOT_NULL(pauline->stat.dtmf_list_received);
BC_ASSERT_PTR_NOT_NULL(pauline->stat.dtmf_list_received);
if (pauline->stat.dtmf_list_received) {
CU_ASSERT_STRING_EQUAL(pauline->stat.dtmf_list_received, expected);
BC_ASSERT_STRING_EQUAL(pauline->stat.dtmf_list_received, expected);
}
ms_free(expected);
} else {
CU_ASSERT_PTR_NULL(pauline->stat.dtmf_list_received);
BC_ASSERT_PTR_NULL(pauline->stat.dtmf_list_received);
}
}
void send_dtmf_cleanup() {
CU_ASSERT_PTR_NULL(marie_call->dtmfs_timer);
CU_ASSERT_PTR_NULL(marie_call->dtmf_sequence);
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);
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1));
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1));
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);
@ -116,7 +116,7 @@ static void send_dtmfs_sequence_sip_info() {
static void send_dtmfs_sequence_not_ready() {
marie = linphone_core_manager_new( "marie_rc");
CU_ASSERT_EQUAL(linphone_call_send_dtmfs(linphone_core_get_current_call(marie->lc), "123"), -1);
BC_ASSERT_EQUAL(linphone_call_send_dtmfs(linphone_core_get_current_call(marie->lc), "123"), -1, int, "%d");
linphone_core_manager_destroy(marie);
}
@ -127,13 +127,13 @@ static void send_dtmfs_sequence_call_state_changed() {
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);
CU_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallPausing,1));
CU_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_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);
CU_ASSERT_PTR_NULL(pauline->stat.dtmf_list_received);
BC_ASSERT_PTR_NULL(pauline->stat.dtmf_list_received);
send_dtmf_cleanup();
}

View file

@ -17,8 +17,7 @@
*/
#include <stdio.h>
#include "CUnit/Basic.h"
#include "linphonecore.h"
#include "private.h"
#include "lpconfig.h"
@ -39,8 +38,8 @@ const char *liblinphone_tester_get_notify_content(void){
void linphone_notify_received(LinphoneCore *lc, LinphoneEvent *lev, const char *eventname, const LinphoneContent *content){
LinphoneCoreManager *mgr;
CU_ASSERT_PTR_NOT_NULL_FATAL(content);
CU_ASSERT_TRUE(strcmp(notify_content,(const char*)linphone_content_get_buffer(content))==0);
BC_ASSERT_PTR_NOT_NULL_FATAL(content);
BC_ASSERT_TRUE(strcmp(notify_content,(const char*)linphone_content_get_buffer(content))==0);
mgr=get_manager(lc);
mgr->stat.number_of_NotifyReceived++;
}
@ -55,7 +54,7 @@ void linphone_subscription_state_change(LinphoneCore *lc, LinphoneEvent *lev, Li
linphone_content_set_type(content,"application");
linphone_content_set_subtype(content,"somexml2");
linphone_content_set_buffer(content,notify_content,strlen(notify_content));
ms_message("Subscription state [%s] from [%s]",linphone_subscription_state_to_string(state),from);
ms_free(from);
@ -107,10 +106,10 @@ void linphone_publish_state_changed(LinphoneCore *lc, LinphoneEvent *ev, Linphon
ms_free(from);
switch(state){
case LinphonePublishProgress: counters->number_of_LinphonePublishProgress++; break;
case LinphonePublishOk:
case LinphonePublishOk:
/*make sure custom header access API is working*/
CU_ASSERT_PTR_NOT_NULL(linphone_event_get_custom_header(ev,"From"));
counters->number_of_LinphonePublishOk++;
BC_ASSERT_PTR_NOT_NULL(linphone_event_get_custom_header(ev,"From"));
counters->number_of_LinphonePublishOk++;
break;
case LinphonePublishError: counters->number_of_LinphonePublishError++; break;
case LinphonePublishExpiring: counters->number_of_LinphonePublishExpiring++; break;
@ -118,7 +117,7 @@ void linphone_publish_state_changed(LinphoneCore *lc, LinphoneEvent *ev, Linphon
default:
break;
}
}
static void subscribe_test_declined(void) {
@ -140,16 +139,16 @@ static void subscribe_test_declined(void) {
lev=linphone_core_subscribe(marie->lc,pauline->identity,"dodo",600,content);
linphone_event_ref(lev);
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingInit,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,3000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionError,1,21000));/*yes flexisip may wait 20 secs in case of forking*/
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));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionError,1,21000));/*yes flexisip may wait 20 secs in case of forking*/
ei=linphone_event_get_error_info(lev);
CU_ASSERT_PTR_NOT_NULL(ei);
BC_ASSERT_PTR_NOT_NULL(ei);
if (ei){
CU_ASSERT_EQUAL(linphone_error_info_get_protocol_code(ei),603);
CU_ASSERT_PTR_NOT_NULL(linphone_error_info_get_phrase(ei));
BC_ASSERT_EQUAL(linphone_error_info_get_protocol_code(ei),603, int, "%d");
BC_ASSERT_PTR_NOT_NULL(linphone_error_info_get_phrase(ei));
}
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionTerminated,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionTerminated,1,1000));
linphone_content_unref(content);
linphone_event_unref(lev);
@ -183,33 +182,33 @@ static void subscribe_test_with_args(bool_t terminated_by_subscriber, RefreshTes
linphone_content_set_buffer(content,subscribe_content,strlen(subscribe_content));
lev=linphone_core_subscribe(marie->lc,pauline->identity,"dodo",expires,content);
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingInit,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,3000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,1,3000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionActive,1,1000));
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));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,1,3000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionActive,1,1000));
/*make sure marie receives first notification before terminating*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_NotifyReceived,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_NotifyReceived,1,1000));
if (refresh_type==AutoRefresh){
wait_for_list(lcs,NULL,0,6000);
CU_ASSERT_TRUE(linphone_event_get_subscription_state(pauline->lev)==LinphoneSubscriptionActive);
BC_ASSERT_TRUE(linphone_event_get_subscription_state(pauline->lev)==LinphoneSubscriptionActive);
}else if (refresh_type==ManualRefresh){
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionExpiring,1,4000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionExpiring,1,4000));
linphone_event_update_subscribe(lev,NULL);
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,2,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,2,2000));
}
if (terminated_by_subscriber){
linphone_event_terminate(lev);
}else{
CU_ASSERT_PTR_NOT_NULL_FATAL(pauline->lev);
BC_ASSERT_PTR_NOT_NULL_FATAL(pauline->lev);
linphone_event_terminate(pauline->lev);
}
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionTerminated,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionTerminated,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionTerminated,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionTerminated,1,1000));
linphone_content_unref(content);
linphone_core_manager_destroy(marie);
@ -223,7 +222,7 @@ static void subscribe_test_with_args2(bool_t terminated_by_subscriber, RefreshTe
LinphoneEvent *lev;
int expires= refresh_type!=NoRefresh ? 4 : 600;
MSList* lcs=ms_list_append(NULL,marie->lc);
lcs=ms_list_append(lcs,pauline->lc);
if (refresh_type==ManualRefresh){
@ -240,37 +239,37 @@ static void subscribe_test_with_args2(bool_t terminated_by_subscriber, RefreshTe
linphone_event_add_custom_header(lev,"My-Header2","pimpon");
linphone_event_send_subscribe(lev,content);
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingInit,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,3000));
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*/
CU_ASSERT_STRING_EQUAL(linphone_event_get_custom_header(pauline->lev,"My-Header"),"pouet");
CU_ASSERT_STRING_EQUAL(linphone_event_get_custom_header(pauline->lev,"My-Header2"),"pimpon");
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,1,5000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionActive,1,5000));
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));
/*make sure marie receives first notification before terminating*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_NotifyReceived,1,5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_NotifyReceived,1,5000));
if (refresh_type==AutoRefresh){
wait_for_list(lcs,NULL,0,6000);
CU_ASSERT_TRUE(linphone_event_get_subscription_state(pauline->lev)==LinphoneSubscriptionActive);
BC_ASSERT_TRUE(linphone_event_get_subscription_state(pauline->lev)==LinphoneSubscriptionActive);
}else if (refresh_type==ManualRefresh){
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionExpiring,1,4000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionExpiring,1,4000));
linphone_event_update_subscribe(lev,NULL);
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,2,5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,2,5000));
}
if (terminated_by_subscriber){
linphone_event_terminate(lev);
}else{
CU_ASSERT_PTR_NOT_NULL_FATAL(pauline->lev);
BC_ASSERT_PTR_NOT_NULL_FATAL(pauline->lev);
linphone_event_terminate(pauline->lev);
}
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionTerminated,1,5000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionTerminated,1,5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionTerminated,1,5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionTerminated,1,5000));
linphone_content_unref(content);
linphone_core_manager_destroy(marie);
@ -285,7 +284,7 @@ static void subscribe_test_terminated_by_notifier(void){
subscribe_test_with_args(FALSE,NoRefresh);
}
/* Caution: this test does not really check that the subscribe are refreshed, because the core is not managing the expiration of
/* Caution: this test does not really check that the subscribe are refreshed, because the core is not managing the expiration of
* unrefreshed subscribe dialogs. So it is just checking that it is not crashing.
*/
static void subscribe_test_refreshed(void){
@ -320,21 +319,21 @@ static void publish_test_with_args(bool_t refresh, int expires){
linphone_event_send_publish(lev,content);
linphone_event_ref(lev);
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishProgress,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishOk,1,3000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishProgress,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishOk,1,3000));
if (!refresh){
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishExpiring,1,5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishExpiring,1,5000));
linphone_event_update_publish(lev,content);
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishProgress,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishOk,1,3000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishProgress,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishOk,1,3000));
}else{
}
linphone_event_terminate(lev);
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishCleared,1,3000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePublishCleared,1,3000));
linphone_event_unref(lev);

View file

@ -60,31 +60,35 @@ bind-address=0.0.0.0
# Default value: 3478
port=3478
##
## DOS protection parameters.
## This module bans user when they are sending too much packets on
## a given timelapse
##
[dos-protection]
# Enable or disable DOS protection using IPTables firewall.
# Default value: false
enabled=false
[module::DoS]
# Indicate whether the module is activated.
# Default value: true
enabled=true
# List of whitelist IPs which won't be affected by DOS protection.
# Default value: 127.0.0.1
authorized-ip=127.0.0.1
# 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=
# Local ports to protect.
# Default value: 5060
port=5060
# Number of milliseconds to calculate the packet rate
# Default value: 1000
time-period=1000
# Time (in seconds) while an IP have to not send any packet in order
# to leave the blacklist.
# Default value: 60
ban-duration=60
# 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 packets authorized in 1sec before considering them as
# DOS attack.
# Default value: 20
packets-limit=20
# Number of minutes to ban the ip/port using iptables
# Default value: 1
ban-time=1
##
@ -273,10 +277,6 @@ fork-late=true
call-fork-timeout=20
# Only forward one response of forked invite to the caller
# Default value: true
fork-one-response=true
# All the forked have to decline in order to decline the caller
# invite
# Default value: false
@ -544,3 +544,5 @@ filter=
# Default value:
collector-address=sip:collector@sip.example.org

View file

@ -16,8 +16,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include "CUnit/Basic.h"
#include "linphonecore.h"
#include "lpconfig.h"
#include "private.h"
@ -42,13 +41,13 @@ static void subscribe_forking(void) {
lev=linphone_core_subscribe(marie->lc,pauline->identity,"dodo",expires,content);
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingInit,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,3000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline2->stat.number_of_LinphoneSubscriptionIncomingReceived,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,1,1000));
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));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline2->stat.number_of_LinphoneSubscriptionIncomingReceived,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,1,1000));
/*make sure marie receives first notification before terminating*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_NotifyReceived,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_NotifyReceived,1,1000));
linphone_event_terminate(lev);
@ -72,10 +71,10 @@ static void message_forking(void) {
lcs=ms_list_append(lcs,marie2->lc);
linphone_chat_room_send_message2(chat_room,message,liblinphone_tester_chat_message_state_change,pauline->lc);
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneMessageReceived,1,3000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneMessageReceived,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneMessageDelivered,1,1000));
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1);
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneMessageReceived,1,3000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneMessageReceived,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneMessageDelivered,1,1000));
BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1, int, "%d");
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(marie2);
linphone_core_manager_destroy(pauline);
@ -102,21 +101,21 @@ static void message_forking_with_unreachable_recipients(void) {
linphone_core_set_network_reachable(marie3->lc,FALSE);
linphone_chat_room_send_message2(chat_room,message,liblinphone_tester_chat_message_state_change,pauline->lc);
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneMessageReceived,1,3000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneMessageDelivered,1,1000));
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1);
CU_ASSERT_TRUE( marie2->stat.number_of_LinphoneMessageReceived==0);
CU_ASSERT_TRUE( marie3->stat.number_of_LinphoneMessageReceived==0);
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneMessageReceived,1,3000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneMessageDelivered,1,1000));
BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1, int, "%d");
BC_ASSERT_EQUAL(marie2->stat.number_of_LinphoneMessageReceived, 0, int, "%d");
BC_ASSERT_EQUAL(marie3->stat.number_of_LinphoneMessageReceived, 0, int, "%d");
/*marie 2 goes online */
linphone_core_set_network_reachable(marie2->lc,TRUE);
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneMessageReceived,1,3000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneMessageReceived,1,3000));
/*wait a long time so that all transactions are expired*/
wait_for_list(lcs,NULL,0,32000);
/*marie 3 goes online now*/
linphone_core_set_network_reachable(marie3->lc,TRUE);
CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneMessageReceived,1,3000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneMessageReceived,1,3000));
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(marie2);
@ -146,27 +145,27 @@ static void message_forking_with_all_recipients_unreachable(void) {
linphone_chat_room_send_message2(chat_room,message,liblinphone_tester_chat_message_state_change,pauline->lc);
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneMessageInProgress,1,5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneMessageInProgress,1,5000));
/*flexisip will accept the message with 202 after 16 seconds*/
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneMessageDelivered,1,18000));
CU_ASSERT_TRUE( marie->stat.number_of_LinphoneMessageReceived==0);
CU_ASSERT_TRUE( marie2->stat.number_of_LinphoneMessageReceived==0);
CU_ASSERT_TRUE( marie3->stat.number_of_LinphoneMessageReceived==0);
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneMessageDelivered,1,18000));
BC_ASSERT_EQUAL( marie->stat.number_of_LinphoneMessageReceived, 0, int, "%d");
BC_ASSERT_EQUAL( marie2->stat.number_of_LinphoneMessageReceived, 0, int, "%d");
BC_ASSERT_EQUAL( marie3->stat.number_of_LinphoneMessageReceived, 0, int, "%d");
/*marie 1 goes online */
linphone_core_set_network_reachable(marie->lc,TRUE);
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneMessageReceived,1,3000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneMessageReceived,1,3000));
/*marie 2 goes online */
linphone_core_set_network_reachable(marie2->lc,TRUE);
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneMessageReceived,1,3000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneMessageReceived,1,3000));
/*wait a long time so that all transactions are expired*/
wait_for_list(lcs,NULL,0,32000);
/*marie 3 goes online now*/
linphone_core_set_network_reachable(marie3->lc,TRUE);
CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneMessageReceived,1,3000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneMessageReceived,1,3000));
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(marie2);
@ -193,26 +192,26 @@ static void call_forking(void){
linphone_core_invite_address(pauline->lc,marie->identity);
/*pauline should hear ringback*/
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,3000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,3000));
/*all devices from Marie should be ringing*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,3000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallIncomingReceived,1,3000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallIncomingReceived,1,3000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,3000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallIncomingReceived,1,3000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallIncomingReceived,1,3000));
/*marie accepts the call on its first device*/
linphone_core_accept_call(marie->lc,linphone_core_get_current_call(marie->lc));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallConnected,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,1000));
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));
/*other devices should stop ringing*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallEnd,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallEnd,1,1000));
linphone_core_terminate_call(pauline->lc,linphone_core_get_current_call(pauline->lc));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000));
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);
@ -237,27 +236,27 @@ static void call_forking_with_urgent_reply(void){
linphone_core_set_user_agent(marie3->lc,"Natted Linphone",NULL);
linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL);
CU_ASSERT_TRUE(linphone_core_media_encryption_supported(pauline->lc,LinphoneMediaEncryptionSRTP));
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*/
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,9000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,9000));
/*Marie should be ringing*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,1000));
/*marie accepts the call on its first device*/
linphone_core_accept_call(marie->lc,linphone_core_get_current_call(marie->lc));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallConnected,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,1000));
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));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000));
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);
@ -284,20 +283,20 @@ static void call_forking_cancelled(void){
linphone_core_invite_address(pauline->lc,marie->identity);
/*pauline should hear ringback*/
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,3000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,3000));
/*all devices from Marie should be ringing*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallIncomingReceived,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallIncomingReceived,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,1000));
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));
/*pauline finally cancels the call*/
linphone_core_terminate_call(pauline->lc,linphone_core_get_current_call(pauline->lc));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000));
/*all devices should stop ringing*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallEnd,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallEnd,1,1000));
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(marie);
@ -324,11 +323,11 @@ static void call_forking_declined(bool_t declined_globaly){
linphone_core_invite_address(pauline->lc,marie->identity);
/*pauline should hear ringback*/
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,3000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,3000));
/*all devices from Marie should be ringing*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallIncomingReceived,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallIncomingReceived,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,1000));
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*/
linphone_core_decline_call(marie->lc,linphone_core_get_current_call(marie->lc),
@ -336,22 +335,22 @@ static void call_forking_declined(bool_t declined_globaly){
);
if (declined_globaly){
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000));
/*all devices should stop ringing*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallEnd,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallEnd,1,1000));
}else{
/*pauline should continue ringing and be able to hear a call taken by marie2 */
linphone_core_accept_call(marie2->lc, linphone_core_get_current_call(marie2->lc));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallStreamsRunning,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallStreamsRunning,1,2000));
liblinphone_tester_check_rtcp(pauline,marie2);
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,3000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallEnd,1,3000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,3000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallEnd,1,3000));
linphone_core_terminate_call(marie2->lc,linphone_core_get_current_call(marie2->lc));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,3000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,3000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,3000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,3000));
}
linphone_core_manager_destroy(pauline);
@ -390,22 +389,22 @@ static void call_forking_with_push_notification_single(void){
linphone_core_set_network_reachable(marie->lc,TRUE);
/*Marie shall receive the call immediately*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,5000));
/*pauline should hear ringback as well*/
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,1000));
/*marie accepts the call*/
linphone_core_accept_call(marie->lc,linphone_core_get_current_call(marie->lc));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,5000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallConnected,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallConnected,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,1000));
liblinphone_tester_check_rtcp(pauline,marie);
linphone_core_terminate_call(pauline->lc,linphone_core_get_current_call(pauline->lc));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,5000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,5000));
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(marie);
@ -432,32 +431,32 @@ static void call_forking_with_push_notification_multiple(void){
linphone_core_invite_address(pauline->lc,marie->identity);
/*marie1 will ring*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,5000));
/*pauline should hear ringback as well*/
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,1000));
/*the server is expected to send a push notification to marie2, this will wake up linphone, that will reconnect:*/
linphone_core_set_network_reachable(marie2->lc,TRUE);
/*Marie shall receive the call immediately*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallIncomingReceived,1,5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallIncomingReceived,1,5000));
/*marie2 accepts the call*/
linphone_core_accept_call(marie2->lc,linphone_core_get_current_call(marie2->lc));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallConnected,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallStreamsRunning,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallConnected,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallStreamsRunning,1,1000));
/*call to marie1 should be cancelled*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000));
liblinphone_tester_check_rtcp(pauline,marie2);
linphone_core_terminate_call(pauline->lc,linphone_core_get_current_call(pauline->lc));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,1000));
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(marie);
@ -482,18 +481,18 @@ static void call_forking_not_responded(void){
linphone_core_invite_address(pauline->lc,marie->identity);
/*pauline should hear ringback*/
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,3000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,3000));
/*all devices from Marie should be ringing*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallIncomingReceived,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallIncomingReceived,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallIncomingReceived,1,1000));
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));
/*nobody answers, flexisip should close the call after XX seconds*/
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallError,1,22000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallError,1,22000));
/*all devices should stop ringing*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallEnd,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie3->stat.number_of_LinphoneCallEnd,1,1000));
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(marie);
@ -541,10 +540,10 @@ static void early_media_call_forking(void) {
linphone_core_invite_address_with_params(pauline->lc,marie1->identity,params);
linphone_call_params_destroy(params);
CU_ASSERT_TRUE(wait_for_list(lcs, &marie1->stat.number_of_LinphoneCallIncomingEarlyMedia,1,3000));
CU_ASSERT_TRUE(wait_for_list(lcs, &marie2->stat.number_of_LinphoneCallIncomingEarlyMedia,1,3000));
CU_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallOutgoingEarlyMedia,1,3000));
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallOutgoingEarlyMedia,1);
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));
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);
@ -552,30 +551,30 @@ static void early_media_call_forking(void) {
/*wait a bit that streams are established*/
wait_for_list(lcs,&dummy,1,6000);
CU_ASSERT_TRUE(linphone_call_get_audio_stats(pauline_call)->download_bandwidth>60
&& linphone_call_get_audio_stats(pauline_call)->download_bandwidth<99);
CU_ASSERT_TRUE(linphone_call_get_audio_stats(marie1_call)->download_bandwidth>60
&& linphone_call_get_audio_stats(marie1_call)->download_bandwidth<99);
CU_ASSERT_TRUE(linphone_call_get_audio_stats(marie2_call)->download_bandwidth>60
&& linphone_call_get_audio_stats(marie2_call)->download_bandwidth<99);
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");
linphone_core_accept_call(marie1->lc,linphone_core_get_current_call(marie1->lc));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie1->stat.number_of_LinphoneCallStreamsRunning,1,3000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,3000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie1->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*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallEnd,1,1000));
/*wait a bit that streams are established*/
wait_for_list(lcs,&dummy,1,3000);
CU_ASSERT_TRUE(linphone_call_get_audio_stats(pauline_call)->download_bandwidth>60
&& linphone_call_get_audio_stats(pauline_call)->download_bandwidth<99 );
CU_ASSERT_TRUE(linphone_call_get_audio_stats(marie1_call)->download_bandwidth>60
&& linphone_call_get_audio_stats(marie1_call)->download_bandwidth<99 );
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");
linphone_core_terminate_all_calls(pauline->lc);
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,5000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie1->stat.number_of_LinphoneCallEnd,1,5000));
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));
ms_list_free(lcs);
linphone_core_manager_destroy(marie1);
@ -599,23 +598,23 @@ static void call_with_sips(void){
linphone_core_invite_address(marie->lc,pauline1->identity);
/*marie should hear ringback*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallOutgoingRinging,1,3000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallOutgoingRinging,1,3000));
/*Only the sips registered device from pauline should ring*/
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline1->stat.number_of_LinphoneCallIncomingReceived,1,1000));
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));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline1->stat.number_of_LinphoneCallConnected,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline1->stat.number_of_LinphoneCallStreamsRunning,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallConnected,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,1000));
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*/
CU_ASSERT_TRUE(pauline2->stat.number_of_LinphoneCallIncomingReceived==0);
BC_ASSERT_EQUAL(pauline2->stat.number_of_LinphoneCallIncomingReceived, 0, int, "%d");
linphone_core_terminate_call(pauline1->lc,linphone_core_get_current_call(pauline1->lc));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline1->stat.number_of_LinphoneCallEnd,1,3000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,3000));
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);
@ -643,11 +642,11 @@ static void call_with_sips_not_achievable(void){
linphone_address_unref(dest);
/*Call should be rejected by server with 480*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallError,1,6000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallError,1,6000));
ei=linphone_call_get_error_info(call);
CU_ASSERT_PTR_NOT_NULL(ei);
BC_ASSERT_PTR_NOT_NULL(ei);
if (ei){
CU_ASSERT_EQUAL(linphone_error_info_get_reason(ei), LinphoneReasonTemporarilyUnavailable);
BC_ASSERT_EQUAL(linphone_error_info_get_reason(ei), LinphoneReasonTemporarilyUnavailable, int, "%d");
}
linphone_core_manager_destroy(marie);
@ -680,20 +679,20 @@ static void call_with_ipv6(void) {
linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL);
linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL);
CU_ASSERT_TRUE(call(marie,pauline));
BC_ASSERT_TRUE(call(marie,pauline));
pauline_call=linphone_core_get_current_call(pauline->lc);
CU_ASSERT_PTR_NOT_NULL(pauline_call);
BC_ASSERT_PTR_NOT_NULL(pauline_call);
if (pauline_call){
/*check that the remote contact is IPv6*/
const char *contact=linphone_call_get_remote_contact(pauline_call);
LinphoneAddress *ct_addr;
CU_ASSERT_PTR_NOT_NULL(contact);
BC_ASSERT_PTR_NOT_NULL(contact);
if (contact){
ct_addr=linphone_address_new(contact);
CU_ASSERT_PTR_NOT_NULL(ct_addr);
BC_ASSERT_PTR_NOT_NULL(ct_addr);
if (ct_addr){
CU_ASSERT_TRUE(strchr(linphone_address_get_domain(ct_addr),':')!=NULL);
BC_ASSERT_PTR_NOT_NULL(strchr(linphone_address_get_domain(ct_addr),':'));
}
linphone_address_destroy(ct_addr);
}
@ -707,7 +706,7 @@ static void call_with_ipv6(void) {
liblinphone_tester_enable_ipv6(FALSE);
leaked_objects=belle_sip_object_get_object_count()-begin;
CU_ASSERT_TRUE(leaked_objects==0);
BC_ASSERT_EQUAL(leaked_objects, 0, int, "%d");
if (leaked_objects>0){
belle_sip_object_dump_active_objects();
}
@ -727,13 +726,13 @@ static void file_transfer_message_rcs_to_external_body_client(void) {
LinphoneCoreManager* marie = linphone_core_manager_init( "marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_init( "pauline_rc");
linphone_proxy_config_set_custom_header(marie->lc->default_proxy, "Accept", "application/sdp");
linphone_core_manager_start(marie, "marie_rc", TRUE);
linphone_proxy_config_set_custom_header(pauline->lc->default_proxy, "Accept", "application/sdp, 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);
@ -767,7 +766,7 @@ static void file_transfer_message_rcs_to_external_body_client(void) {
linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_message_cbs_set_file_transfer_send(cbs, file_transfer_send);
linphone_chat_room_send_chat_message(chat_room,message);
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageExtBodyReceived,1));
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);
@ -775,12 +774,12 @@ static void file_transfer_message_rcs_to_external_body_client(void) {
linphone_chat_message_cbs_set_file_transfer_recv(cbs, file_transfer_received);
linphone_chat_message_download_file(marie->stat.last_received_chat_message);
}
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageFileTransferDone,1));
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageFileTransferDone,1));
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1);
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageDelivered,1);
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageExtBodyReceived,1);
CU_ASSERT_TRUE(compare_files(send_filepath, receive_filepath));
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));
linphone_content_unref(content);
linphone_core_manager_destroy(marie);
@ -807,29 +806,29 @@ static void send_file_transfer_message_using_external_body_url(LinphoneCoreManag
linphone_chat_message_set_external_body_url(message, "https://www.linphone.org:444//tmp/54ec58280ace9_c30709218df8eaba61d1.jpg");
linphone_chat_room_send_chat_message(chat_room, message);
CU_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageReceived, 1));
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);
}
CU_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageExtBodyReceived, 1));
BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageExtBodyReceived, 1));
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress, 1);
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageExtBodyReceived, 1);
BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress, 1, int, "%d");
BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageExtBodyReceived, 1, int, "%d");
}
static void file_transfer_message_external_body_to_external_body_client(void) {
LinphoneCoreManager* marie = linphone_core_manager_init( "marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_init( "pauline_rc");
linphone_proxy_config_set_custom_header(marie->lc->default_proxy, "Accept", "application/sdp");
linphone_core_manager_start(marie, "marie_rc", TRUE);
linphone_proxy_config_set_custom_header(pauline->lc->default_proxy, "Accept", "application/sdp");
linphone_core_manager_start(pauline, "pauline_rc", TRUE);
reset_counters(&marie->stat);
reset_counters(&pauline->stat);
linphone_core_refresh_registers(marie->lc);
linphone_core_refresh_registers(pauline->lc);
@ -842,13 +841,13 @@ static void file_transfer_message_external_body_to_external_body_client(void) {
static void file_transfer_message_external_body_to_rcs_client(void) {
LinphoneCoreManager* marie = linphone_core_manager_init( "marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_init( "pauline_rc");
linphone_proxy_config_set_custom_header(marie->lc->default_proxy, "Accept", "application/sdp");
linphone_core_manager_start(marie, "marie_rc", TRUE);
linphone_proxy_config_set_custom_header(pauline->lc->default_proxy, "Accept", "application/sdp, text/plain, application/vnd.gsma.rcs-ft-http+xml");
linphone_core_manager_start(pauline, "pauline_rc", TRUE);
reset_counters(&marie->stat);
reset_counters(&pauline->stat);
@ -858,6 +857,43 @@ static void file_transfer_message_external_body_to_rcs_client(void) {
linphone_core_manager_destroy(pauline);
}
static void dos_module_trigger(void) {
char *to;
LinphoneChatRoom *chat_room;
int i = 0;
int number_of_messge_to_send = 100;
LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new("pauline_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);
do {
char msg[128];
sprintf(msg, "Flood message number %i", i);
linphone_chat_room_send_message(chat_room, msg);
ms_usleep(100000);
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
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");
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived, 1));
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
ms_free(to);
}
test_t flexisip_tests[] = {
{ "Subscribe forking", subscribe_forking },
{ "Message forking", message_forking },
@ -877,7 +913,8 @@ test_t flexisip_tests[] = {
{ "Call with ipv6", call_with_ipv6 },
{ "File transfer message rcs to external body client", file_transfer_message_rcs_to_external_body_client },
{ "File transfer message external body to rcs client", file_transfer_message_external_body_to_rcs_client },
{ "File transfer message external body to external body client", file_transfer_message_external_body_to_external_body_client }
{ "File transfer message external body to external body client", file_transfer_message_external_body_to_external_body_client },
{ "DoS module trigger by sending a lot of chat messages", dos_module_trigger }
};

View file

@ -16,8 +16,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include "CUnit/Basic.h"
#include "linphonecore.h"
#include "private.h"
#include "liblinphone_tester.h"
@ -28,7 +27,6 @@
#include <gtk/gtk.h>
#endif
static FILE * log_file = NULL;
#ifdef ANDROID

View file

@ -283,6 +283,7 @@ bool_t call_with_test_params(LinphoneCoreManager* caller_mgr
,const LinphoneCallTestParams *callee_test_params);
bool_t call(LinphoneCoreManager* caller_mgr,LinphoneCoreManager* callee_mgr);
bool_t add_video(LinphoneCoreManager* caller,LinphoneCoreManager* callee, bool_t change_video_policy);
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);
@ -307,5 +308,9 @@ void call_base(LinphoneMediaEncryption mode, bool_t enable_video,bool_t enable_r
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 check_media_direction(LinphoneCoreManager* mgr, LinphoneCall *call, MSList* lcs,LinphoneMediaDirection audio_dir, LinphoneMediaDirection video_dir);
static const int audio_cmp_max_shift=20;
#endif /* LIBLINPHONE_TESTER_H_ */

View file

@ -16,13 +16,10 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#ifndef __USE_XOPEN
/*on Debian OS, time.h does declare strptime only if __USE_XOPEN is declared */
#define __USE_XOPEN
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 700 // To have definition of strptime, snprintf and getline
#endif
#include <time.h>
#include "CUnit/Basic.h"
#include "linphonecore.h"
#include "private.h"
#include "liblinphone_tester.h"
@ -136,7 +133,7 @@ static FILE* gzuncompress(const char* filepath) {
memset(buffer, 0, strlen(buffer));
}
fclose(output);
CU_ASSERT_EQUAL(gzclose(file), Z_OK);
BC_ASSERT_EQUAL(gzclose(file), Z_OK, int, "%d");
ret=fopen(newname, "rb");
ms_free(newname);
return ret;
@ -169,7 +166,7 @@ static time_t check_file(LinphoneCoreManager* mgr) {
uint32_t timediff = 0;
FILE *file = NULL;
CU_ASSERT_PTR_NOT_NULL(filepath);
BC_ASSERT_PTR_NOT_NULL(filepath);
if (filepath != NULL) {
int line_count = 0;
@ -186,10 +183,10 @@ static time_t check_file(LinphoneCoreManager* mgr) {
#else
file = fopen(filepath, "rb");
#endif
CU_ASSERT_PTR_NOT_NULL(file);
BC_ASSERT_PTR_NOT_NULL(file);
if (!file) return 0;
// 1) expect to find folder name in filename path
CU_ASSERT_PTR_NOT_NULL(strstr(filepath, bc_tester_writable_dir_prefix));
BC_ASSERT_PTR_NOT_NULL(strstr(filepath, bc_tester_writable_dir_prefix));
// 2) check file contents
while (getline(&line, &line_size, file) != -1) {
@ -205,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);
CU_ASSERT_TRUE(log_time >= time_prev);
BC_ASSERT_TRUE(log_time >= time_prev);
time_prev = log_time;
}
}
#endif
}
CU_ASSERT_TRUE(line_count > 25);
BC_ASSERT_TRUE(line_count > 25);
free(line);
fclose(file);
ms_free(filepath);
@ -220,7 +217,7 @@ static time_t check_file(LinphoneCoreManager* mgr) {
timediff = labs((long int)log_time - (long int)cur_time);
(void)timediff;
#ifndef WIN32
CU_ASSERT_TRUE( timediff <= 1 );
BC_ASSERT_TRUE( timediff <= 1 );
if( !(timediff <= 1) ){
char buffers[2][128] = {{0}};
strftime(buffers[0], sizeof(buffers[0]), "%Y-%m-%d %H:%M:%S", localtime(&log_time));
@ -242,7 +239,7 @@ static time_t check_file(LinphoneCoreManager* mgr) {
static void collect_files_disabled() {
LinphoneCoreManager* marie = setup(FALSE);
CU_ASSERT_PTR_NULL(linphone_core_compress_log_collection(marie->lc));
BC_ASSERT_PTR_NULL(linphone_core_compress_log_collection(marie->lc));
collect_cleanup(marie);
}
@ -282,7 +279,7 @@ static void logCollectionUploadStateChangedCb(LinphoneCore *lc, LinphoneCoreLogC
break;
case LinphoneCoreLogCollectionUploadStateDelivered:
counters->number_of_LinphoneCoreLogCollectionUploadStateDelivered++;
CU_ASSERT_TRUE(strlen(info)>0)
BC_ASSERT_GREATER(strlen(info), 0, int, "%d");
break;
case LinphoneCoreLogCollectionUploadStateNotDelivered:
counters->number_of_LinphoneCoreLogCollectionUploadStateNotDelivered++;
@ -302,7 +299,7 @@ static void upload_collected_traces() {
while (--waiting) ms_error("(test error)Waiting %d...", waiting);
linphone_core_compress_log_collection(marie->lc);
linphone_core_upload_log_collection(marie->lc);
CU_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphoneCoreLogCollectionUploadStateDelivered,1));
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphoneCoreLogCollectionUploadStateDelivered,1));
/*try 2 times*/
waiting=100;
@ -310,7 +307,7 @@ static void upload_collected_traces() {
while (--waiting) ms_error("(test error)Waiting %d...", waiting);
linphone_core_compress_log_collection(marie->lc);
linphone_core_upload_log_collection(marie->lc);
CU_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphoneCoreLogCollectionUploadStateDelivered,2));
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphoneCoreLogCollectionUploadStateDelivered,2));
collect_cleanup(marie);
}

View file

@ -17,8 +17,7 @@
*/
#include <stdio.h>
#include "CUnit/Basic.h"
#include "linphonecore.h"
#include "private.h"
#include "liblinphone_tester.h"
@ -54,7 +53,7 @@ void message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMess
} else if (linphone_chat_message_get_external_body_url(message)) {
counters->number_of_LinphoneMessageExtBodyReceived++;
if (message_external_body_url) {
CU_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(message),message_external_body_url);
message_external_body_url=NULL;
}
}
@ -199,10 +198,10 @@ static void text_message(void) {
reset_counters(&pauline->stat);
}
linphone_chat_room_send_message(chat_room,"Bla bla bla bla");
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1));
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageReceivedLegacy,1);
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");
CU_ASSERT_PTR_NOT_NULL(linphone_core_get_chat_room(marie->lc,pauline->identity));
BC_ASSERT_PTR_NOT_NULL(linphone_core_get_chat_room(marie->lc,pauline->identity));
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
@ -225,12 +224,12 @@ static void text_message_within_dialog(void) {
reset_counters(&marie->stat);
reset_counters(&pauline->stat);
}
CU_ASSERT_TRUE(call(marie,pauline));
BC_ASSERT_TRUE(call(marie,pauline));
linphone_chat_room_send_message(chat_room,"Bla bla bla bla");
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1));
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1));
CU_ASSERT_PTR_NOT_NULL(linphone_core_get_chat_room(marie->lc,pauline->identity));
BC_ASSERT_PTR_NOT_NULL(linphone_core_get_chat_room(marie->lc,pauline->identity));
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
@ -268,10 +267,10 @@ static void text_message_with_credential_from_auth_cb(void) {
reset_counters(&pauline->stat);
}
linphone_chat_room_send_message(chat_room,"Bla bla bla bla");
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1));
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageReceivedLegacy,1);
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");
CU_ASSERT_PTR_NOT_NULL(linphone_core_get_chat_room(marie->lc,pauline->identity));
BC_ASSERT_PTR_NOT_NULL(linphone_core_get_chat_room(marie->lc,pauline->identity));
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
@ -293,7 +292,7 @@ static void text_message_with_privacy(void) {
linphone_core_get_default_proxy(pauline->lc,&pauline_proxy);
linphone_proxy_config_set_privacy(pauline_proxy,LinphonePrivacyId);
CU_ASSERT_PTR_NOT_NULL(linphone_core_get_chat_room(marie->lc,pauline->identity));
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*/
@ -301,8 +300,8 @@ static void text_message_with_privacy(void) {
reset_counters(&pauline->stat);
}
linphone_chat_room_send_message(chat_room,"Bla bla bla bla");
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1));
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageReceivedLegacy,1);
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");
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
@ -320,7 +319,7 @@ static void text_message_compatibility_mode(void) {
LinphoneChatRoom* chat_room;
linphone_core_get_default_proxy(marie->lc,&proxy);
CU_ASSERT_PTR_NOT_NULL (proxy);
BC_ASSERT_PTR_NOT_NULL (proxy);
proxy_address=linphone_address_new(linphone_proxy_config_get_addr(proxy));
linphone_address_clean(proxy_address);
tmp=linphone_address_as_string_uri_only(proxy_address);
@ -337,7 +336,7 @@ static void text_message_compatibility_mode(void) {
linphone_core_set_sip_transports(marie->lc,&transport);
marie->stat.number_of_LinphoneRegistrationOk=0;
CU_ASSERT_TRUE (wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphoneRegistrationOk,1));
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);
{
@ -347,8 +346,8 @@ static void text_message_compatibility_mode(void) {
reset_counters(&pauline->stat);
}
linphone_chat_room_send_message(chat_room,"Bla bla bla bla");
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageReceived,1));
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageReceivedLegacy,1);
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");
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
@ -376,15 +375,15 @@ static void text_message_with_ack(void) {
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);
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1));
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageDelivered,1));
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1);
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;
CU_ASSERT_TRUE(leaked_objects==0);
BC_ASSERT_TRUE(leaked_objects==0);
if (leaked_objects>0){
belle_sip_object_dump_active_objects();
}
@ -410,16 +409,16 @@ static void text_message_with_external_body(void) {
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 */
CU_ASSERT_EQUAL(ms_list_size(chat_room->transient_messages), 1);
CU_ASSERT_EQUAL(ms_list_nth_data(chat_room->transient_messages,0), message);
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);
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1));
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageDelivered,1));
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));
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1);
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageExtBodyReceived,1);
BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1, int, "%d");
BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageExtBodyReceived,1, int, "%d");
CU_ASSERT_EQUAL(ms_list_size(chat_room->transient_messages), 0);
BC_ASSERT_EQUAL(ms_list_size(chat_room->transient_messages), 0, int, "%d");
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
@ -487,7 +486,7 @@ static void file_transfer_message(void) {
linphone_chat_message_cbs_set_msg_state_changed(cbs,liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_message_cbs_set_file_transfer_send(cbs, file_transfer_send);
linphone_chat_room_send_chat_message(chat_room,message);
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,1));
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);
@ -495,12 +494,12 @@ static void file_transfer_message(void) {
linphone_chat_message_cbs_set_file_transfer_recv(cbs, file_transfer_received);
linphone_chat_message_download_file(marie->stat.last_received_chat_message);
}
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,1));
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,1));
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1);
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageDelivered,1);
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,1);
CU_ASSERT_TRUE(compare_files(send_filepath, receive_filepath));
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));
linphone_content_unref(content);
linphone_core_manager_destroy(marie);
@ -554,18 +553,18 @@ static void small_file_transfer_message(void) {
linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_message_cbs_set_file_transfer_send(cbs, memory_file_transfer_send);
linphone_chat_room_send_chat_message(chat_room,message);
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,1));
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);
}
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,1));
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,1));
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1);
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageDelivered,1);
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,1);
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");
linphone_content_unref(content);
linphone_core_manager_destroy(marie);
@ -641,18 +640,18 @@ static void lime_file_transfer_message(void) {
linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_message_cbs_set_file_transfer_send(cbs, memory_file_transfer_send);
linphone_chat_room_send_chat_message(chat_room,message);
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,1));
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);
}
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,1));
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,1));
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1);
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageDelivered,1);
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,1);
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");
linphone_content_unref(content);
linphone_core_manager_destroy(marie);
@ -662,13 +661,19 @@ static void lime_file_transfer_message(void) {
static void printHex(char *title, uint8_t *data, uint32_t length) {
int i;
printf ("%s : ", title);
char debug_string_buffer[2048];
char *debug_string = debug_string_buffer;
sprintf (debug_string, "%s : ", title);
debug_string += strlen(title)+3;
for (i=0; i<length; i++) {
printf ("0x%02x, ", data[i]);
sprintf (debug_string, "0x%02x, ", data[i]);
debug_string+=6;
}
printf ("\n");
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) {
int retval;
size_t size;
@ -684,13 +689,96 @@ static void lime_unit(void) {
limeKey_t associatedKey;
uint8_t targetZID[12] = {0x00, 0x5d, 0xbe, 0x03, 0x99, 0x64, 0x3d, 0x95, 0x3a, 0x22, 0x02, 0xdd};
uint8_t senderZID[12] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x70, 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0};
uint8_t encryptedMessage[48];
uint8_t plainMessage[48];
uint8_t encryptedMessage[1024];
uint8_t plainMessage[1024];
uint8_t receiverZID[12];
xmlDocPtr cacheBuffer;
FILE *CACHE;
/* Load Alice cache file */
FILE *CACHE = fopen("ZIDCacheAlice.xml", "rb+");
/**** Low level tests using on cache file to extract keys, encrypt/decrypt ****/
/**** use functions that are not directly used by external entities ****/
/* create and load cache file */
CACHE = fopen("ZIDCache.xml", "wb");
fprintf (CACHE, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<cache><selfZID>ef7692d0792a67491ae2d44e</selfZID><peer><ZID>005dbe0399643d953a2202dd</ZID><rs1>9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045</rs1><aux>f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e</aux><rs2>2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899</rs2><uri>pipo1@pipo.com</uri><sndKey>963c57bb28e62068d2df23e8f9b771932d3c57bb28e62068d2df23e8f9b77193</sndKey><rcvKey>05d9ac653a83c4559cb0ae7394e7cd3b2d3c57bb28e62068d2df23e8f9b77193</rcvKey><sndSId>5f9aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b77193</sndSId><rcvSId>02ffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b77193</rcvSId><sndIndex>00000069</sndIndex><rcvIndex>000001e8</rcvIndex><pvs>01</pvs></peer><peer><ZID>1234567889643d953a2202ee</ZID><rs1>9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045</rs1><aux>f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e</aux><rs2>2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899</rs2><uri>pipo1@pipo.com</uri><sndKey>123456789012345678901234567890123456765431262068d2df23e8f9b77193</sndKey><rcvKey>25d9ac653a83c4559cb0ae7394e7cd3b2d3c57bb28e62068d2df23e8f9b77193</rcvKey><sndSId>f69aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b77193</sndSId><rcvSId>22ffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b77193</rcvSId><sndIndex>00000001</sndIndex><rcvIndex>00000000</rcvIndex><pvs>01</pvs></peer></cache>");
fclose(CACHE);
CACHE = fopen("ZIDCache.xml", "rb+");
cacheBufferString = (uint8_t*) ms_load_file_content(CACHE, &size);
*(cacheBufferString+size) = '\0';
fclose(CACHE);
/* parse it to an xmlDoc */
cacheBuffer = xmlParseDoc(cacheBufferString);
ms_free(cacheBufferString);
/* get data from cache : sender */
associatedKeys.peerURI = (uint8_t *)malloc(15);
memcpy(associatedKeys.peerURI, "pipo1@pipo.com", 15);
associatedKeys.associatedZIDNumber = 0;
retval = lime_getCachedSndKeysByURI(cacheBuffer, &associatedKeys);
BC_ASSERT_EQUAL_FATAL(retval, 0, int, "%d");
BC_ASSERT_EQUAL_FATAL(associatedKeys.associatedZIDNumber, 2, int, "%d"); /* there are 2 keys associated to pipo1@pipo.com address in the cache above*/
ms_message("Get cached key by URI, for sender, return %d keys", associatedKeys.associatedZIDNumber);
for (i=0; i<associatedKeys.associatedZIDNumber; i++) {
printHex("ZID", associatedKeys.peerKeys[i]->peerZID, 12);
printHex("key", associatedKeys.peerKeys[i]->key, 32);
printHex("sessionID", associatedKeys.peerKeys[i]->sessionId, 32);
ms_message("session index %d\n", associatedKeys.peerKeys[i]->sessionIndex);
}
/* get data from cache : receiver */
memcpy(associatedKey.peerZID, targetZID, 12);
retval = lime_getCachedRcvKeyByZid(cacheBuffer, &associatedKey);
BC_ASSERT_EQUAL_FATAL(retval, 0, int, "%d");
printHex("Got receiver key for ZID", targetZID, 12);
printHex("Key", associatedKey.key, 32);
printHex("sessionID", associatedKey.sessionId, 32);
ms_message("session index %d\n", associatedKey.sessionIndex);
/* encrypt/decrypt a message */
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 */
memcpy(receiverZID, associatedKeys.peerKeys[0]->peerZID, 12);
memcpy(associatedKeys.peerKeys[0]->peerZID, senderZID, 12);
retval = lime_decryptMessage(associatedKeys.peerKeys[0], encryptedMessage, strlen(PLAIN_TEXT_TEST_MESSAGE)+16, receiverZID, plainMessage);
BC_ASSERT_EQUAL_FATAL(retval, 0, int, "%d");
BC_ASSERT_STRING_EQUAL((char *)plainMessage, (char *)PLAIN_TEXT_TEST_MESSAGE);
ms_message("Decrypt and auth returned %d\nPlain text is %s\n", retval, plainMessage);
/* update receiver data */
associatedKey.sessionIndex++;
associatedKey.key[0]++;
associatedKey.sessionId[0]++;
retval = lime_setCachedKey(cacheBuffer, &associatedKey, LIME_RECEIVER);
BC_ASSERT_EQUAL_FATAL(retval, 0, int, "%d");
/* update sender data */
associatedKeys.peerKeys[0]->sessionIndex++;
associatedKeys.peerKeys[0]->key[0]++;
associatedKeys.peerKeys[0]->sessionId[0]++;
retval = lime_setCachedKey(cacheBuffer, associatedKeys.peerKeys[0], LIME_SENDER);
BC_ASSERT_EQUAL_FATAL(retval, 0, int, "%d");
/* free memory */
lime_freeKeys(associatedKeys);
/* write the file */
/* dump the xml document into a string */
xmlDocDumpFormatMemoryEnc(cacheBuffer, &xmlStringOutput, &xmlStringLength, "UTF-8", 0);
/* write it to the file */
CACHE = fopen("ZIDCache.xml", "w+");
fwrite(xmlStringOutput, 1, xmlStringLength, CACHE);
xmlFree(xmlStringOutput);
fclose(CACHE);
xmlFreeDoc(cacheBuffer);
/**** Higher level tests using 2 caches to encrypt/decrypt a message ****/
/* Create Alice cache file and then load it */
CACHE = fopen("ZIDCacheAlice.xml", "wb");
fprintf(CACHE, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<cache><selfZID>ef7692d0792a67491ae2d44e</selfZID><peer><ZID>005dbe0399643d953a2202dd</ZID><rs1>9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045</rs1><aux>f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e</aux><rs2>2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899</rs2><uri>sip:pauline@sip.example.org</uri><sndKey>9111ebeb52e50edcc6fcb3eea1a2d3ae3c2c75d3668923e83c59d0f472455150</sndKey><rcvKey>60f020a3fe11dc2cc0e1e8ed9341b4cd14944db806ca4fc95456bbe45d95c43a</rcvKey><sndSId>5f9aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b77193</sndSId><rcvSId>bcffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b77193</rcvSId><sndIndex>00000080</sndIndex><rcvIndex>000001cf</rcvIndex><pvs>01</pvs></peer><peer><ZID>1234567889643d953a2202ee</ZID><rs1>9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045</rs1><aux>f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e</aux><rs2>2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899</rs2><uri>sip:pauline@sip.example.org</uri><sndKey>72d80ab1cad243cf45634980c1d02cfb2df81ce0dd5dfcf1ebeacfc5345a9176</sndKey><rcvKey>25d9ac653a83c4559cb0ae7394e7cd3b2d3c57bb28e62068d2df23e8f9b77193</rcvKey><sndSId>f69aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b77193</sndSId><rcvSId>22ffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b77193</rcvSId><sndIndex>0000000f</sndIndex><rcvIndex>00000000</rcvIndex></peer></cache>");
fclose(CACHE);
CACHE = fopen("ZIDCacheAlice.xml", "rb+");
cacheBufferString = (uint8_t *)ms_load_file_content(CACHE, &size);
*(cacheBufferString+size) = '\0';
fclose(CACHE);
@ -698,7 +786,10 @@ static void lime_unit(void) {
cacheBufferAlice = xmlParseDoc(cacheBufferString);
ms_free(cacheBufferString);
/* Load Bob cache file */
/* Create Bob cache file and then load it */
CACHE = fopen("ZIDCacheBob.xml", "wb");
fprintf(CACHE, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<cache><selfZID>005dbe0399643d953a2202dd</selfZID><peer><ZID>ef7692d0792a67491ae2d44e</ZID><rs1>9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045</rs1><aux>f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e</aux><rs2>2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899</rs2><uri>sip:marie@sip.example.org</uri><rcvKey>9111ebeb52e50edcc6fcb3eea1a2d3ae3c2c75d3668923e83c59d0f472455150</rcvKey><sndKey>60f020a3fe11dc2cc0e1e8ed9341b4cd14944db806ca4fc95456bbe45d95c43a</sndKey><rcvSId>5f9aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b77193</rcvSId><sndSId>bcffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b77193</sndSId><rcvIndex>00000080</rcvIndex><sndIndex>000001cf</sndIndex><pvs>01</pvs></peer><peer><ZID>1234567889643d953a2202ee</ZID><rs1>9b5c8f06f3b6c2c695f2dfc3c26f31f5fef8661f8c5fe7c95aeb5c5b0435b045</rs1><aux>f8324dd18ea905171ec2be89f879d01d5994132048d92ea020778cbdf31c605e</aux><rs2>2fdcef69380937c2cf221f7d11526f286c39f49641452ba9012521c705094899</rs2><uri>sip:marie@sip.example.org</uri><sndKey>81e6e6362c34dc974263d1f77cbb9a8d6d6a718330994379099a8fa19fb12faa</sndKey><rcvKey>25d9ac653a83c4559cb0ae7394e7cd3b2d3c57bb28e62068d2df23e8f9b77193</rcvKey><sndSId>f69aa1e5e4c7ec88fa389a9f6b8879b42d3c57bb28e62068d2df23e8f9b77193</sndSId><rcvSId>22ffd51e7316a6c6f53a50fcf01b01bf2d3c57bb28e62068d2df23e8f9b77193</rcvSId><sndIndex>0000002e</sndIndex><rcvIndex>00000000</rcvIndex><pvs>01</pvs></peer></cache>");
fclose(CACHE);
CACHE = fopen("ZIDCacheBob.xml", "rb+");
cacheBufferString = (uint8_t *)ms_load_file_content(CACHE, &size);
*(cacheBufferString+size) = '\0';
@ -710,19 +801,20 @@ static void lime_unit(void) {
/* encrypt a message */
retval = lime_createMultipartMessage(cacheBufferAlice, (uint8_t *)"Bonjour les petits lapins,ca va? éh oui oui", (uint8_t *)"sip:pauline@sip.example.org", &multipartMessage);
retval = lime_createMultipartMessage(cacheBufferAlice, (uint8_t *)PLAIN_TEXT_TEST_MESSAGE, (uint8_t *)"sip:pauline@sip.example.org", &multipartMessage);
printf("create message return %d\n", retval);
BC_ASSERT_EQUAL_FATAL(retval, 0, int, "%d");
if (retval == 0) {
printf("message is %s\n", multipartMessage);
ms_message("Encrypted message created is %s", multipartMessage);
}
/* decrypt the multipart message */
retval = lime_decryptMultipartMessage(cacheBufferBob, multipartMessage, &decryptedMessage);
printf("decrypt message return %d\n", retval);
BC_ASSERT_EQUAL_FATAL(retval, 0, int, "%d");
if (retval == 0) {
printf("message is %s##END\n", decryptedMessage);
BC_ASSERT_STRING_EQUAL((char *)decryptedMessage, (char *)PLAIN_TEXT_TEST_MESSAGE);
ms_message("Succesfully decrypted message is %s", decryptedMessage);
}
free(multipartMessage);
free(decryptedMessage);
@ -746,74 +838,6 @@ static void lime_unit(void) {
xmlFreeDoc(cacheBufferAlice);
xmlFreeDoc(cacheBufferBob);
/* Load cache file */
CACHE = fopen("ZIDCache.xml", "rb+");
cacheBufferString = (uint8_t*) ms_load_file_content(CACHE, &size);
*(cacheBufferString+size) = '\0';
fclose(CACHE);
/* parse it to an xmlDoc */
cacheBuffer = xmlParseDoc(cacheBufferString);
ms_free(cacheBufferString);
/* get data from cache : sender */
associatedKeys.peerURI = (uint8_t *)malloc(15);
memcpy(associatedKeys.peerURI, "pipo1@pipo.com", 15);
associatedKeys.associatedZIDNumber = 0;
retval = lime_getCachedSndKeysByURI(cacheBuffer, &associatedKeys);
printf("getCachedKeys returns %d, number of key found %d\n", retval, associatedKeys.associatedZIDNumber);
for (i=0; i<associatedKeys.associatedZIDNumber; i++) {
printHex("ZID", associatedKeys.peerKeys[i]->peerZID, 12);
printHex("key", associatedKeys.peerKeys[i]->key, 32);
printHex("sessionID", associatedKeys.peerKeys[i]->sessionId, 32);
printf("session index %d\n", associatedKeys.peerKeys[i]->sessionIndex);
}
/* get data from cache : receiver */
memcpy(associatedKey.peerZID, targetZID, 12);
retval = lime_getCachedRcvKeyByZid(cacheBuffer, &associatedKey);
printf("getCachedKey by ZID return %d\n", retval);
printHex("Key", associatedKey.key, 32);
printHex("sessionID", associatedKey.sessionId, 32);
printf("session index %d\n", associatedKey.sessionIndex);
/* encrypt/decrypt a message */
lime_encryptMessage(associatedKeys.peerKeys[0], (uint8_t *)"bla Bla bla b! Pipo", 20, senderZID, encryptedMessage);
printHex("Ciphered", encryptedMessage, 32);
/* invert sender and receiverZID to decrypt/authenticate */
memcpy(receiverZID, associatedKeys.peerKeys[0]->peerZID, 12);
memcpy(associatedKeys.peerKeys[0]->peerZID, senderZID, 12);
retval = lime_decryptMessage(associatedKeys.peerKeys[0], encryptedMessage, 36, receiverZID, plainMessage);
printf("Decrypt and auth returned %d\nPlain: %s\n", retval, plainMessage);
/* update receiver data */
associatedKey.sessionIndex++;
associatedKey.key[0]++;
associatedKey.sessionId[0]++;
retval = lime_setCachedKey(cacheBuffer, &associatedKey, LIME_RECEIVER);
printf("setCachedKey return %d\n", retval);
/* update sender data */
associatedKeys.peerKeys[0]->sessionIndex++;
associatedKeys.peerKeys[0]->key[0]++;
associatedKeys.peerKeys[0]->sessionId[0]++;
retval = lime_setCachedKey(cacheBuffer, associatedKeys.peerKeys[0], LIME_SENDER);
printf("setCachedKey return %d\n", retval);
/* free memory */
lime_freeKeys(associatedKeys);
/* write the file */
/* dump the xml document into a string */
xmlDocDumpFormatMemoryEnc(cacheBuffer, &xmlStringOutput, &xmlStringLength, "UTF-8", 0);
/* write it to the file */
CACHE = fopen("ZIDCache.xml", "w+");
fwrite(xmlStringOutput, 1, xmlStringLength, CACHE);
xmlFree(xmlStringOutput);
fclose(CACHE);
xmlFreeDoc(cacheBuffer);
}
static void lime_text_message(void) {
@ -842,10 +866,10 @@ static void lime_text_message(void) {
ms_free(to);
linphone_chat_room_send_message(chat_room,"Bla bla bla bla");
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1));
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageReceivedLegacy,1);
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");
CU_ASSERT_PTR_NOT_NULL(linphone_core_get_chat_room(marie->lc,pauline->identity));
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);
@ -901,18 +925,18 @@ static void file_transfer_message_io_error_upload(void) {
linphone_chat_room_send_chat_message(chat_room,message);
/*wait for file to be 25% uploaded and simultate a network error*/
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.progress_of_LinphoneFileTransfer,25));
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.progress_of_LinphoneFileTransfer,25));
sal_set_send_error(pauline->lc->sal, -1);
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageNotDelivered,1));
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageNotDelivered,1));
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageNotDelivered,1);
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,0);
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*/
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneRegistrationOk,pauline->stat.number_of_LinphoneRegistrationOk+1));
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);
@ -965,21 +989,21 @@ static void file_transfer_message_io_error_download(void) {
linphone_chat_room_send_message2(chat_room,message,liblinphone_tester_chat_message_state_change,pauline->lc);
/* wait for marie to receive pauline's message */
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,1));
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 */
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.progress_of_LinphoneFileTransfer, 50));
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);
}
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1);
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageDelivered,1);
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageNotDelivered,1);
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,0);
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);
@ -1035,13 +1059,13 @@ static void file_transfer_message_upload_cancelled(void) {
linphone_chat_room_send_chat_message(chat_room,message);
/*wait for file to be 50% uploaded and cancel the transfer */
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.progress_of_LinphoneFileTransfer, 50));
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.progress_of_LinphoneFileTransfer, 50));
linphone_chat_message_cancel_file_transfer(message);
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageNotDelivered,1));
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageNotDelivered,1));
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageNotDelivered,1);
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,0);
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);
@ -1092,21 +1116,21 @@ static void file_transfer_message_download_cancelled(void) {
linphone_chat_room_send_message2(chat_room,message,liblinphone_tester_chat_message_state_change,pauline->lc);
/* wait for marie to receive pauline's message */
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceivedWithFile,1));
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 */
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.progress_of_LinphoneFileTransfer, 50));
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);
}
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1);
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageDelivered,1);
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneFileTransferDownloadSuccessful,0);
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageNotDelivered,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_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);
@ -1140,12 +1164,12 @@ static void file_transfer_using_external_body_url(void) {
linphone_chat_message_set_external_body_url(message, "https://www.linphone.org:444//tmp/54ec58280ace9_c30709218df8eaba61d1.jpg");
linphone_chat_room_send_chat_message(chat_room, message);
CU_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageReceived, 1));
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);
}
CU_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageExtBodyReceived, 1));
CU_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneMessageInProgress, 1));
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);
@ -1174,16 +1198,16 @@ static void text_message_with_send_error(void) {
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 */
CU_ASSERT_EQUAL(ms_list_size(chat_room->transient_messages), 1);
CU_ASSERT_EQUAL(ms_list_nth_data(chat_room->transient_messages,0), message);
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);
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageNotDelivered,1));
/*CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageInProgress,1);*/
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageReceived,0);
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 */
CU_ASSERT_EQUAL(ms_list_size(chat_room->transient_messages), 0);
BC_ASSERT_EQUAL(ms_list_size(chat_room->transient_messages), 0, int, "%d");
sal_set_send_error(marie->lc->sal, 0);
ms_free(to);
@ -1211,8 +1235,8 @@ static void text_message_denied(void) {
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);
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageNotDelivered,1));
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageReceived,0);
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);
@ -1240,7 +1264,7 @@ static void info_message_with_args(bool_t with_content) {
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
CU_ASSERT_TRUE(call(pauline,marie));
BC_ASSERT_TRUE(call(pauline,marie));
info=linphone_core_create_info_message(marie->lc);
linphone_info_message_add_header(info,"Weather","still bad");
@ -1261,26 +1285,26 @@ static void info_message_with_args(bool_t with_content) {
linphone_call_send_info_message(linphone_core_get_current_call(marie->lc),info);
linphone_info_message_destroy(info);
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_inforeceived,1));
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_inforeceived,1));
CU_ASSERT_PTR_NOT_NULL(pauline->stat.last_received_info_message);
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);
CU_ASSERT_PTR_NOT_NULL(hvalue);
BC_ASSERT_PTR_NOT_NULL(hvalue);
if (hvalue)
CU_ASSERT_TRUE(strcmp(hvalue,"still bad")==0);
BC_ASSERT_TRUE(strcmp(hvalue,"still bad")==0);
if (with_content){
CU_ASSERT_PTR_NOT_NULL(content);
BC_ASSERT_PTR_NOT_NULL(content);
if (content) {
CU_ASSERT_PTR_NOT_NULL(linphone_content_get_buffer(content));
CU_ASSERT_PTR_NOT_NULL(linphone_content_get_type(content));
CU_ASSERT_PTR_NOT_NULL(linphone_content_get_subtype(content));
if (linphone_content_get_type(content)) CU_ASSERT_TRUE(strcmp(linphone_content_get_type(content),"application")==0);
if (linphone_content_get_subtype(content)) CU_ASSERT_TRUE(strcmp(linphone_content_get_subtype(content),"somexml")==0);
if (linphone_content_get_buffer(content))CU_ASSERT_TRUE(strcmp((const char*)linphone_content_get_buffer(content),info_content)==0);
CU_ASSERT_EQUAL(linphone_content_get_size(content),strlen(info_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);
@ -1316,8 +1340,8 @@ static void is_composing_notification(void) {
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");
CU_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneIsComposingActiveReceived, 1));
CU_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneIsComposingIdleReceived, 2));
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);
}
@ -1372,9 +1396,9 @@ message_tester_copy_file(const char *from, const char *to)
}
static int check_no_strange_time(void* data,int argc, char** argv,char** cNames) {
CU_ASSERT_EQUAL(argc, 1);
CU_ASSERT_STRING_EQUAL(cNames[0], "COUNT(*)"); // count of non updated messages should be 0
CU_ASSERT_STRING_EQUAL(argv[0], "0"); // count of non updated messages should be 0
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;
}
@ -1386,7 +1410,7 @@ static void message_storage_migration() {
snprintf(src_db,sizeof(src_db), "%s/messages.db", bc_tester_read_dir_prefix);
snprintf(tmp_db,sizeof(tmp_db), "%s/tmp.db", bc_tester_writable_dir_prefix);
CU_ASSERT_EQUAL_FATAL(message_tester_copy_file(src_db, tmp_db), 0);
BC_ASSERT_EQUAL_FATAL(message_tester_copy_file(src_db, tmp_db), 0, int, "%d");
// enable to test the performances of the migration step
//linphone_core_message_storage_set_debug(marie->lc, TRUE);
@ -1396,10 +1420,10 @@ static void message_storage_migration() {
linphone_core_set_chat_database_path(marie->lc, tmp_db);
chatrooms = linphone_core_get_chat_rooms(marie->lc);
CU_ASSERT(ms_list_size(chatrooms) > 0);
BC_ASSERT(ms_list_size(chatrooms) > 0);
// check that all messages have been migrated to the UTC time storage
CU_ASSERT(sqlite3_exec(marie->lc->db, "SELECT COUNT(*) FROM history WHERE time != '-1';", check_no_strange_time, NULL, NULL) == SQLITE_OK );
BC_ASSERT(sqlite3_exec(marie->lc->db, "SELECT COUNT(*) FROM history WHERE time != '-1';", check_no_strange_time, NULL, NULL) == SQLITE_OK );
linphone_core_manager_destroy(marie);
remove(tmp_db);
@ -1411,7 +1435,7 @@ static void history_message_count_helper(LinphoneChatRoom* chatroom, int x, int
if( expected != size ){
ms_warning("History retrieved from %d to %d returned %d records, but expected %d", x, y, size, expected);
}
CU_ASSERT_EQUAL(size, expected);
BC_ASSERT_EQUAL(size, expected, int, "%d");
ms_list_free_with_data(messages, (void (*)(void *))linphone_chat_message_unref);
@ -1426,12 +1450,12 @@ static void history_range_full_test(){
snprintf(src_db,sizeof(src_db), "%s/messages.db", bc_tester_read_dir_prefix);
snprintf(tmp_db,sizeof(tmp_db), "%s/tmp.db", bc_tester_writable_dir_prefix);
CU_ASSERT_EQUAL_FATAL(message_tester_copy_file(src_db, tmp_db), 0);
BC_ASSERT_EQUAL_FATAL(message_tester_copy_file(src_db, tmp_db), 0, int, "%d");
linphone_core_set_chat_database_path(marie->lc, tmp_db);
chatroom = linphone_core_get_chat_room(marie->lc, jehan_addr);
CU_ASSERT_PTR_NOT_NULL(chatroom);
BC_ASSERT_PTR_NOT_NULL(chatroom);
if (chatroom){
// We have 20 tests to perform to fully qualify the function, here they are:
history_message_count_helper(chatroom, 0, 0, 1);
@ -1468,47 +1492,47 @@ static void history_messages_count() {
snprintf(src_db,sizeof(src_db), "%s/messages.db", bc_tester_read_dir_prefix);
snprintf(tmp_db,sizeof(tmp_db), "%s/tmp.db", bc_tester_writable_dir_prefix);
CU_ASSERT_EQUAL_FATAL(message_tester_copy_file(src_db, tmp_db), 0);
BC_ASSERT_EQUAL_FATAL(message_tester_copy_file(src_db, tmp_db), 0, int, "%d");
linphone_core_set_chat_database_path(marie->lc, tmp_db);
chatroom = linphone_core_get_chat_room(marie->lc, jehan_addr);
CU_ASSERT_PTR_NOT_NULL(chatroom);
BC_ASSERT_PTR_NOT_NULL(chatroom);
if (chatroom){
messages=linphone_chat_room_get_history(chatroom,10);
CU_ASSERT_EQUAL(ms_list_size(messages), 10);
BC_ASSERT_EQUAL(ms_list_size(messages), 10, int, "%d");
ms_list_free_with_data(messages, (void (*)(void*))linphone_chat_message_unref);
messages=linphone_chat_room_get_history(chatroom,1);
CU_ASSERT_EQUAL(ms_list_size(messages), 1);
BC_ASSERT_EQUAL(ms_list_size(messages), 1, int, "%d");
ms_list_free_with_data(messages, (void (*)(void*))linphone_chat_message_unref);
messages=linphone_chat_room_get_history(chatroom,0);
CU_ASSERT_EQUAL(linphone_chat_room_get_history_size(chatroom), 1270);
CU_ASSERT_EQUAL(ms_list_size(messages), 1270);
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*/
CU_ASSERT_STRING_EQUAL(linphone_chat_message_get_text((LinphoneChatMessage *)messages->next->data), "Fore and aft follow each other.");
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*/
messages=linphone_chat_room_get_history_range(chatroom, 42, 42);
CU_ASSERT_EQUAL(ms_list_size(messages), 1);
CU_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.");
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.");
ms_list_free_with_data(messages, (void (*)(void*))linphone_chat_message_unref);
/*test offset without limit*/
messages = linphone_chat_room_get_history_range(chatroom, 1265, -1);
CU_ASSERT_EQUAL(ms_list_size(messages), 1270-1265);
BC_ASSERT_EQUAL(ms_list_size(messages), 1270-1265, int, "%d");
ms_list_free_with_data(messages, (void (*)(void*))linphone_chat_message_unref);
/*test limit without offset*/
messages = linphone_chat_room_get_history_range(chatroom, 0, 5);
CU_ASSERT_EQUAL(ms_list_size(messages), 6);
BC_ASSERT_EQUAL(ms_list_size(messages), 6, int, "%d");
ms_list_free_with_data(messages, (void (*)(void*))linphone_chat_message_unref);
/*test invalid start*/
messages = linphone_chat_room_get_history_range(chatroom, 1265, 1260);
CU_ASSERT_EQUAL(ms_list_size(messages), 1270-1265);
BC_ASSERT_EQUAL(ms_list_size(messages), 1270-1265, int, "%d");
ms_list_free_with_data(messages, (void (*)(void*))linphone_chat_message_unref);
}
linphone_core_manager_destroy(marie);

View file

@ -17,10 +17,8 @@
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "CUnit/Basic.h"
#include "linphonecore.h"
#include "lpconfig.h"
#include "private.h"
@ -51,23 +49,23 @@ static void call_waiting_indication_with_param(bool_t enable_caller_privacy) {
lcs=ms_list_append(lcs,pauline->lc);
lcs=ms_list_append(lcs,laure->lc);
CU_ASSERT_TRUE(call_with_caller_params(marie,pauline,marie_params));
BC_ASSERT_TRUE(call_with_caller_params(marie,pauline,marie_params));
pauline_called_by_marie=linphone_core_get_current_call(pauline->lc);
if (enable_caller_privacy)
linphone_call_params_set_privacy(laure_params,LinphonePrivacyId);
CU_ASSERT_PTR_NOT_NULL(linphone_core_invite_address_with_params(laure->lc,pauline->identity,laure_params));
BC_ASSERT_PTR_NOT_NULL(linphone_core_invite_address_with_params(laure->lc,pauline->identity,laure_params));
CU_ASSERT_TRUE(wait_for(laure->lc
BC_ASSERT_TRUE(wait_for(laure->lc
,pauline->lc
,&pauline->stat.number_of_LinphoneCallIncomingReceived
,2));
CU_ASSERT_EQUAL(laure->stat.number_of_LinphoneCallOutgoingProgress,1);
BC_ASSERT_EQUAL(laure->stat.number_of_LinphoneCallOutgoingProgress,1, int, "%d");
CU_ASSERT_TRUE(wait_for(laure->lc
BC_ASSERT_TRUE(wait_for(laure->lc
,pauline->lc
,&laure->stat.number_of_LinphoneCallOutgoingRinging
,1));
@ -81,25 +79,25 @@ static void call_waiting_indication_with_param(bool_t enable_caller_privacy) {
}
}
CU_ASSERT_TRUE(wait_for(laure->lc
BC_ASSERT_TRUE(wait_for(laure->lc
,pauline->lc
,&laure->stat.number_of_LinphoneCallConnected
,1));
CU_ASSERT_TRUE(wait_for(pauline->lc
BC_ASSERT_TRUE(wait_for(pauline->lc
,marie->lc
,&marie->stat.number_of_LinphoneCallPausedByRemote
,1));
if (pauline_called_by_laure && enable_caller_privacy )
CU_ASSERT_EQUAL(linphone_call_params_get_privacy(linphone_call_get_current_params(pauline_called_by_laure)),LinphonePrivacyId);
BC_ASSERT_EQUAL(linphone_call_params_get_privacy(linphone_call_get_current_params(pauline_called_by_laure)),LinphonePrivacyId, int, "%d");
/*wait a bit for ACK to be sent*/
wait_for_list(lcs,NULL,0,1000);
linphone_core_terminate_all_calls(pauline->lc);
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,10000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,10000));
CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallEnd,1,10000));
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));
linphone_core_manager_destroy(marie);
@ -115,6 +113,70 @@ static void call_waiting_indication_with_privacy(void) {
call_waiting_indication_with_param(TRUE);
}
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* 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);
lcs=ms_list_append(NULL,marie->lc);
lcs=ms_list_append(lcs,pauline->lc);
lcs=ms_list_append(lcs,laure->lc);
if (state==LinphoneCallOutgoingRinging || state==LinphoneCallOutgoingEarlyMedia) {
BC_ASSERT_PTR_NOT_NULL(linphone_core_invite_address_with_params(marie->lc,pauline->identity,marie_params));
BC_ASSERT_TRUE(wait_for(marie->lc
,pauline->lc
,&pauline->stat.number_of_LinphoneCallIncomingReceived
,1));
if (state==LinphoneCallOutgoingEarlyMedia)
linphone_core_accept_early_media(pauline->lc,linphone_core_get_current_call(pauline->lc));
BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallOutgoingProgress,1, int, "%d");
BC_ASSERT_TRUE(wait_for(marie->lc
,pauline->lc
,state==LinphoneCallOutgoingEarlyMedia?&marie->stat.number_of_LinphoneCallOutgoingEarlyMedia:&marie->stat.number_of_LinphoneCallOutgoingRinging
,1));
} else if (state==LinphoneCallOutgoingProgress) {
BC_ASSERT_PTR_NOT_NULL(linphone_core_invite_address(marie->lc,pauline->identity));
} else {
ms_error("Unsupported state");
return;
}
BC_ASSERT_TRUE(call_with_caller_params(laure,marie,laure_params));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,10000));
linphone_core_terminate_all_calls(marie->lc);
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));
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
ms_list_free(lcs);
}
static void incoming_call_accepted_when_outgoing_call_in_progress(void) {
incoming_call_accepted_when_outgoing_call_in_state(LinphoneCallOutgoingProgress);
}
static void incoming_call_accepted_when_outgoing_call_in_outgoing_ringing(void) {
incoming_call_accepted_when_outgoing_call_in_state(LinphoneCallOutgoingRinging);
}
static void incoming_call_accepted_when_outgoing_call_in_outgoing_ringing_early_media(void) {
incoming_call_accepted_when_outgoing_call_in_state(LinphoneCallOutgoingEarlyMedia);
}
static void simple_conference_base(LinphoneCoreManager* marie, LinphoneCoreManager* pauline, LinphoneCoreManager* laure) {
stats initial_marie_stat;
@ -129,32 +191,32 @@ static void simple_conference_base(LinphoneCoreManager* marie, LinphoneCoreManag
lcs=ms_list_append(lcs,pauline->lc);
lcs=ms_list_append(lcs,laure->lc);
CU_ASSERT_TRUE(call(marie,pauline));
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);
CU_ASSERT_TRUE(pause_call_1(marie,marie_call_pauline,pauline,pauline_called_by_marie));
BC_ASSERT_TRUE(pause_call_1(marie,marie_call_pauline,pauline,pauline_called_by_marie));
CU_ASSERT_TRUE(call(marie,laure));
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);
CU_ASSERT_PTR_NOT_NULL_FATAL(marie_call_laure);
BC_ASSERT_PTR_NOT_NULL_FATAL(marie_call_laure);
linphone_core_add_to_conference(marie->lc,marie_call_laure);
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallUpdating,initial_marie_stat.number_of_LinphoneCallUpdating+1,5000));
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);
CU_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,&marie->stat.number_of_LinphoneCallResuming,initial_marie_stat.number_of_LinphoneCallResuming+1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,initial_pauline_stat.number_of_LinphoneCallStreamsRunning+1,5000));
CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallStreamsRunning,initial_laure_stat.number_of_LinphoneCallStreamsRunning+1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,initial_marie_stat.number_of_LinphoneCallStreamsRunning+2,3000));
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));
CU_ASSERT_TRUE(linphone_core_is_in_conference(marie->lc));
CU_ASSERT_EQUAL(linphone_core_get_conference_size(marie->lc),3);
BC_ASSERT_TRUE(linphone_core_is_in_conference(marie->lc));
BC_ASSERT_EQUAL(linphone_core_get_conference_size(marie->lc),3, int, "%d");
/*
* FIXME: check_ice cannot work as it is today because there is no current call for the party that hosts the conference
@ -170,9 +232,9 @@ static void simple_conference_base(LinphoneCoreManager* marie, LinphoneCoreManag
linphone_core_terminate_conference(marie->lc);
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,10000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,10000));
CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallEnd,1,10000));
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));
@ -221,7 +283,7 @@ static void simple_call_transfer(void) {
lcs=ms_list_append(lcs,laure->lc);
CU_ASSERT_TRUE(call(marie,pauline));
BC_ASSERT_TRUE(call(marie,pauline));
marie_calling_pauline=linphone_core_get_current_call(marie->lc);
pauline_called_by_marie=linphone_core_get_current_call(pauline->lc);
@ -231,35 +293,35 @@ static void simple_call_transfer(void) {
linphone_core_transfer_call(pauline->lc,pauline_called_by_marie,laure_identity);
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallRefered,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallRefered,1,2000));
/*marie pausing pauline*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallPausing,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallPausedByRemote,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallPaused,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallPausing,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallPausedByRemote,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallPaused,1,2000));
/*marie calling laure*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallOutgoingProgress,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallOutgoingProgress,1,2000));
CU_ASSERT_PTR_NOT_NULL(linphone_call_get_transfer_target_call(marie_calling_pauline));
BC_ASSERT_PTR_NOT_NULL(linphone_call_get_transfer_target_call(marie_calling_pauline));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneTransferCallOutgoingInit,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallIncomingReceived,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallOutgoingRinging,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneTransferCallOutgoingProgress,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneTransferCallOutgoingInit,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallIncomingReceived,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallOutgoingRinging,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneTransferCallOutgoingProgress,1,2000));
linphone_core_accept_call(laure->lc,linphone_core_get_current_call(laure->lc));
CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallConnected,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallStreamsRunning,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallConnected,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallConnected,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallStreamsRunning,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallConnected,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,2000));
marie_calling_laure=linphone_core_get_current_call(marie->lc);
CU_ASSERT_PTR_NOT_NULL_FATAL(marie_calling_laure);
CU_ASSERT_TRUE(linphone_call_get_transferer_call(marie_calling_laure)==marie_calling_pauline);
BC_ASSERT_PTR_NOT_NULL_FATAL(marie_calling_laure);
BC_ASSERT_TRUE(linphone_call_get_transferer_call(marie_calling_laure)==marie_calling_pauline);
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneTransferCallConnected,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneTransferCallConnected,1,2000));
/*terminate marie to pauline call*/
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,2000));
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));
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
@ -279,7 +341,7 @@ static void unattended_call_transfer(void) {
lcs=ms_list_append(lcs,laure->lc);
CU_ASSERT_TRUE(call(marie,pauline));
BC_ASSERT_TRUE(call(marie,pauline));
pauline_called_by_marie=linphone_core_get_current_call(marie->lc);
reset_counters(&marie->stat);
@ -287,25 +349,25 @@ static void unattended_call_transfer(void) {
reset_counters(&laure->stat);
linphone_core_transfer_call(marie->lc,pauline_called_by_marie,laure_identity);
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallRefered,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallRefered,1,2000));
/*marie ends the call */
linphone_core_terminate_call(marie->lc,pauline_called_by_marie);
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,2000));
/*Pauline starts the transfer*/
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingInit,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingProgress,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallIncomingReceived,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingInit,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingProgress,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallIncomingReceived,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,2000));
linphone_core_accept_call(laure->lc,linphone_core_get_current_call(laure->lc));
CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallConnected,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallStreamsRunning,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallConnected,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallStreamsRunning,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,2000));
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
@ -319,10 +381,10 @@ static void unattended_call_transfer_with_error(void) {
LinphoneCall* pauline_called_by_marie;
bool_t call_ok=TRUE;
MSList* lcs=ms_list_append(NULL,marie->lc);
lcs=ms_list_append(lcs,pauline->lc);
CU_ASSERT_TRUE((call_ok=call(marie,pauline)));
BC_ASSERT_TRUE((call_ok=call(marie,pauline)));
if (call_ok){
pauline_called_by_marie=linphone_core_get_current_call(marie->lc);
@ -330,21 +392,21 @@ static void unattended_call_transfer_with_error(void) {
reset_counters(&pauline->stat);
linphone_core_transfer_call(marie->lc,pauline_called_by_marie,"unknown_user");
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallRefered,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallRefered,1,2000));
/*Pauline starts the transfer*/
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingInit,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingInit,1,2000));
/* and immediately get an error*/
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallError,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallError,1,2000));
/*the error must be reported back to marie*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneTransferCallError,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneTransferCallError,1,2000));
/*and pauline should resume the call automatically*/
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallResuming,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallResuming,1,2000));
/*and call should be resumed*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,2000));
}
linphone_core_manager_destroy(marie);
@ -365,24 +427,24 @@ 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);
/*marie call pauline*/
CU_ASSERT_TRUE((call_ok=call(marie,pauline)));
BC_ASSERT_TRUE((call_ok=call(marie,pauline)));
if (call_ok){
marie_call_pauline=linphone_core_get_current_call(marie->lc);
pauline_called_by_marie=linphone_core_get_current_call(pauline->lc);
/*marie pause pauline*/
CU_ASSERT_TRUE(pause_call_1(marie,marie_call_pauline,pauline,pauline_called_by_marie));
BC_ASSERT_TRUE(pause_call_1(marie,marie_call_pauline,pauline,pauline_called_by_marie));
/*marie call laure*/
CU_ASSERT_TRUE(call(marie,laure));
BC_ASSERT_TRUE(call(marie,laure));
marie_call_laure=linphone_core_get_current_call(marie->lc);
laure_called_by_marie=linphone_core_get_current_call(laure->lc);
/*marie pause laure*/
CU_ASSERT_TRUE(pause_call_1(marie,marie_call_laure,laure,laure_called_by_marie));
BC_ASSERT_TRUE(pause_call_1(marie,marie_call_laure,laure,laure_called_by_marie));
reset_counters(&marie->stat);
reset_counters(&pauline->stat);
@ -390,37 +452,37 @@ static void call_transfer_existing_call_outgoing_call(void) {
linphone_core_transfer_call_to_another(marie->lc,marie_call_pauline,marie_call_laure);
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallRefered,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallRefered,1,2000));
/*pauline pausing marie*/
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallPausing,1,4000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallPaused,1,4000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallPausing,1,4000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallPaused,1,4000));
/*pauline calling laure*/
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingProgress,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneTransferCallOutgoingInit,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallIncomingReceived,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneTransferCallOutgoingProgress,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingProgress,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneTransferCallOutgoingInit,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallIncomingReceived,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneTransferCallOutgoingProgress,1,2000));
/*laure accept call*/
for(calls=linphone_core_get_calls(laure->lc);calls!=NULL;calls=calls->next) {
lcall = (LinphoneCall*)calls->data;
if (linphone_call_get_state(lcall) == LinphoneCallIncomingReceived) {
CU_ASSERT_EQUAL(linphone_call_get_replaced_call(lcall),laure_called_by_marie);
BC_ASSERT_PTR_EQUAL(linphone_call_get_replaced_call(lcall),laure_called_by_marie);
linphone_core_accept_call(laure->lc,lcall);
break;
}
}
CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallConnected,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallStreamsRunning,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneTransferCallConnected,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallConnected,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallStreamsRunning,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,2000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneTransferCallConnected,1,2000));
/*terminate marie to pauline/laure call*/
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,2,2000));
CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallEnd,1,2000));
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));
}
linphone_core_manager_destroy(marie);
@ -437,7 +499,10 @@ test_t multi_call_tests[] = {
{ "Simple call transfer", simple_call_transfer },
{ "Unattended call transfer", unattended_call_transfer },
{ "Unattended call transfer with error", unattended_call_transfer_with_error },
{ "Call transfer existing call outgoing call", call_transfer_existing_call_outgoing_call }
{ "Call 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},
};
test_suite_t multi_call_test_suite = {

View file

@ -52,15 +52,15 @@ static void call_multicast_base(bool_t video) {
linphone_core_set_audio_multicast_addr(pauline->lc,"224.1.2.3");
linphone_core_enable_audio_multicast(pauline->lc,TRUE);
CU_ASSERT_TRUE(call(pauline,marie));
BC_ASSERT_TRUE(call(pauline,marie));
wait_for_until(marie->lc, pauline->lc, NULL, 1, 3000);
if (linphone_core_get_current_call(marie->lc)) {
CU_ASSERT_TRUE(linphone_call_get_audio_stats(linphone_core_get_current_call(marie->lc))->download_bandwidth>70);
BC_ASSERT_GREATER(linphone_call_get_audio_stats(linphone_core_get_current_call(marie->lc))->download_bandwidth,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_send_vfu_request(linphone_core_get_current_call(marie->lc));
CU_ASSERT_TRUE( wait_for(marie->lc,pauline->lc,&marie->stat.number_of_IframeDecoded,1));
BC_ASSERT_TRUE( wait_for(marie->lc,pauline->lc,&marie->stat.number_of_IframeDecoded,1));
}
end_call(marie,pauline);
@ -69,7 +69,7 @@ static void call_multicast_base(bool_t video) {
linphone_core_manager_destroy(pauline);
leaked_objects=belle_sip_object_get_object_count()-begin;
CU_ASSERT_TRUE(leaked_objects==0);
BC_ASSERT_TRUE(leaked_objects==0);
if (leaked_objects>0){
belle_sip_object_dump_active_objects();
}
@ -96,6 +96,7 @@ static void early_media_with_multicast_base(bool_t video) {
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();
@ -138,8 +139,8 @@ static void early_media_with_multicast_base(bool_t video) {
linphone_core_invite_address(marie->lc, pauline->identity);
CU_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallIncomingReceived,1,3000));
CU_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallOutgoingRinging,1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallIncomingReceived,1,3000));
BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallOutgoingRinging,1,1000));
if (linphone_core_inc_invite_pending(pauline->lc)) {
@ -150,8 +151,8 @@ static void early_media_with_multicast_base(bool_t video) {
}
linphone_core_accept_early_media(pauline->lc, linphone_core_get_current_call(pauline->lc));
CU_ASSERT_TRUE( wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallIncomingEarlyMedia,1,2000) );
CU_ASSERT_TRUE( wait_for_list(lcs, &marie->stat.number_of_LinphoneCallOutgoingEarlyMedia,1,2000) );
BC_ASSERT_TRUE( wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallIncomingEarlyMedia,1,2000) );
BC_ASSERT_TRUE( wait_for_list(lcs, &marie->stat.number_of_LinphoneCallOutgoingEarlyMedia,1,2000) );
if (linphone_core_inc_invite_pending(pauline2->lc)) {
/* send a 183 to initiate the early media */
@ -161,28 +162,75 @@ static void early_media_with_multicast_base(bool_t video) {
}
linphone_core_accept_early_media(pauline2->lc, linphone_core_get_current_call(pauline2->lc));
CU_ASSERT_TRUE( wait_for_list(lcs, &pauline2->stat.number_of_LinphoneCallIncomingEarlyMedia,1,2000) );
BC_ASSERT_TRUE( wait_for_list(lcs, &pauline2->stat.number_of_LinphoneCallIncomingEarlyMedia,1,2000) );
}
wait_for_list(lcs, &dummy, 1, 3000);
CU_ASSERT_TRUE(linphone_call_get_audio_stats(linphone_core_get_current_call(pauline->lc))->download_bandwidth>70);
CU_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(pauline->lc))->download_bandwidth>70);
BC_ASSERT_TRUE(linphone_call_get_audio_stats(linphone_core_get_current_call(pauline->lc))->download_bandwidth<90);
CU_ASSERT_TRUE(linphone_call_get_audio_stats(linphone_core_get_current_call(pauline2->lc))->download_bandwidth>70);
CU_ASSERT_TRUE(linphone_call_get_audio_stats(linphone_core_get_current_call(pauline2->lc))->download_bandwidth<90);
BC_ASSERT_TRUE(linphone_call_get_audio_stats(linphone_core_get_current_call(pauline2->lc))->download_bandwidth>70);
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))));
BC_ASSERT_TRUE(linphone_call_params_audio_multicast_enabled(linphone_call_get_current_params(linphone_core_get_current_call(marie->lc))));
if (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))));
}
if (video) {
CU_ASSERT_TRUE( wait_for_list(lcs,&pauline->stat.number_of_IframeDecoded,1,2000));
CU_ASSERT_TRUE( wait_for_list(lcs,&pauline2->stat.number_of_IframeDecoded,1,2000));
BC_ASSERT_TRUE( wait_for_list(lcs,&pauline->stat.number_of_IframeDecoded,1,2000));
BC_ASSERT_TRUE( wait_for_list(lcs,&pauline2->stat.number_of_IframeDecoded,1,2000));
}
linphone_core_accept_call(pauline->lc, linphone_core_get_current_call(pauline->lc));
CU_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallConnected, 1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallStreamsRunning, 1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallConnected, 1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallStreamsRunning, 1,1000));
BC_ASSERT_TRUE(wait_for_list(lcs, &pauline2->stat.number_of_LinphoneCallEnd, 1,1000));
BC_ASSERT_TRUE(linphone_call_params_audio_multicast_enabled(linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc))));
BC_ASSERT_TRUE(linphone_call_params_audio_multicast_enabled(linphone_call_get_current_params(linphone_core_get_current_call(marie->lc))));
if (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)));
linphone_call_params_enable_audio_multicast(params,FALSE);
linphone_call_params_enable_video_multicast(params,FALSE);
linphone_core_enable_video_capture(pauline->lc, TRUE);
linphone_core_enable_video_display(pauline->lc, TRUE);
linphone_core_enable_video_capture(marie->lc, TRUE);
linphone_core_enable_video_display(marie->lc, TRUE);
linphone_core_update_call( pauline->lc
, linphone_core_get_current_call(pauline->lc)
, params);
linphone_call_params_destroy(params);
BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallStreamsRunning, 2,1000));
BC_ASSERT_FALSE(linphone_call_params_audio_multicast_enabled(linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc))));
BC_ASSERT_FALSE(linphone_call_params_audio_multicast_enabled(linphone_call_get_current_params(linphone_core_get_current_call(marie->lc))));
check_media_direction( pauline
, linphone_core_get_current_call(pauline->lc)
, lcs
,LinphoneMediaDirectionSendRecv
, video?LinphoneMediaDirectionSendRecv:LinphoneMediaDirectionInactive);
check_media_direction( marie
, linphone_core_get_current_call(marie->lc)
, lcs
,LinphoneMediaDirectionSendRecv
, video?LinphoneMediaDirectionSendRecv:LinphoneMediaDirectionInactive);
if (video) {
BC_ASSERT_FALSE(linphone_call_params_video_multicast_enabled(linphone_call_get_current_params(linphone_core_get_current_call(marie->lc))));
BC_ASSERT_FALSE(linphone_call_params_video_multicast_enabled(linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc))));
}
end_call(marie,pauline);
}
ms_free(lcs);
@ -191,7 +239,7 @@ static void early_media_with_multicast_base(bool_t video) {
linphone_core_manager_destroy(pauline2);
leaked_objects=belle_sip_object_get_object_count()-begin;
CU_ASSERT_EQUAL(leaked_objects,0);
BC_ASSERT_EQUAL(leaked_objects,0, int, "%d");
if (leaked_objects>0){
belle_sip_object_dump_active_objects();
}

View file

@ -16,11 +16,8 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "CUnit/Basic.h"
#include "linphonecore.h"
#include "lpconfig.h"
#include "private.h"
@ -46,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) CU_ASSERT_TRUE(opus_codec_pos==0);
CU_ASSERT_TRUE(speex16_codec_pos<speex_codec_pos);
if (opus_codec_pos!=-1) BC_ASSERT_TRUE(opus_codec_pos==0);
BC_ASSERT_TRUE(speex16_codec_pos<speex_codec_pos);
pt=linphone_core_find_payload_type(lc, "speex", 16000, 1);
CU_ASSERT_PTR_NOT_NULL(pt);
BC_ASSERT_PTR_NOT_NULL(pt);
if (pt) {
CU_ASSERT_TRUE(linphone_core_payload_type_enabled(lc, pt)==TRUE);
BC_ASSERT_TRUE(linphone_core_payload_type_enabled(lc, pt)==TRUE);
}
linphone_core_destroy(lc);
}
@ -60,15 +57,15 @@ static void start_with_no_config(void){
static void check_payload_type_numbers(LinphoneCall *call1, LinphoneCall *call2, int expected_number){
const LinphoneCallParams *params=linphone_call_get_current_params(call1);
const PayloadType *pt=linphone_call_params_get_used_audio_codec(params);
CU_ASSERT_PTR_NOT_NULL(pt);
BC_ASSERT_PTR_NOT_NULL(pt);
if (pt){
CU_ASSERT_TRUE(linphone_core_get_payload_type_number(linphone_call_get_core(call1),pt)==expected_number);
BC_ASSERT_TRUE(linphone_core_get_payload_type_number(linphone_call_get_core(call1),pt)==expected_number);
}
params=linphone_call_get_current_params(call2);
pt=linphone_call_params_get_used_audio_codec(params);
CU_ASSERT_PTR_NOT_NULL(pt);
BC_ASSERT_PTR_NOT_NULL(pt);
if (pt){
CU_ASSERT_TRUE(linphone_core_get_payload_type_number(linphone_call_get_core(call1),pt)==expected_number);
BC_ASSERT_TRUE(linphone_core_get_payload_type_number(linphone_call_get_core(call1),pt)==expected_number);
}
}
@ -84,29 +81,29 @@ static void simple_call_with_different_codec_mappings(void) {
marie = linphone_core_manager_new( "marie_rc");
pauline = linphone_core_manager_new( "pauline_rc");
disable_all_audio_codecs_except_one(marie->lc,"pcmu",-1);
disable_all_audio_codecs_except_one(pauline->lc,"pcmu",-1);
/*marie set a fantasy number to PCMU*/
linphone_core_set_payload_type_number(marie->lc,
linphone_core_find_payload_type(marie->lc, "PCMU", 8000, -1),
104);
CU_ASSERT_TRUE(call(marie,pauline));
BC_ASSERT_TRUE(call(marie,pauline));
pauline_call=linphone_core_get_current_call(pauline->lc);
CU_ASSERT_PTR_NOT_NULL(pauline_call);
BC_ASSERT_PTR_NOT_NULL(pauline_call);
if (pauline_call){
LinphoneCallParams *params;
check_payload_type_numbers(linphone_core_get_current_call(marie->lc), pauline_call, 104);
/*make a reinvite in the other direction*/
linphone_core_update_call(pauline->lc, pauline_call,
linphone_core_update_call(pauline->lc, pauline_call,
params=linphone_core_create_call_params(pauline->lc, pauline_call));
linphone_call_params_unref(params);
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallUpdating,1));
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallUpdatedByRemote,1));
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2));
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,2));
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallUpdating,1));
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_LinphoneCallStreamsRunning,2));
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,2));
/*payload type numbers shall remain the same*/
check_payload_type_numbers(linphone_core_get_current_call(marie->lc), pauline_call, 104);
}
@ -116,7 +113,7 @@ static void simple_call_with_different_codec_mappings(void) {
linphone_core_manager_destroy(pauline);
leaked_objects=belle_sip_object_get_object_count()-begin;
CU_ASSERT_TRUE(leaked_objects==0);
BC_ASSERT_TRUE(leaked_objects==0);
if (leaked_objects>0){
belle_sip_object_dump_active_objects();
}
@ -137,20 +134,20 @@ static void call_failed_because_of_codecs(void) {
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);
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallOutgoingInit,1));
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.*/
CU_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallError,1,7000));
CU_ASSERT_EQUAL(linphone_call_get_reason(out_call),LinphoneReasonNotAcceptable);
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallIncomingReceived,0);
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallReleased,0);
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;
CU_ASSERT_TRUE(leaked_objects==0);
BC_ASSERT_TRUE(leaked_objects==0);
if (leaked_objects>0){
belle_sip_object_dump_active_objects();
}
@ -194,23 +191,23 @@ static void profile_call_base(bool_t avpf1, LinphoneMediaEncryption srtp1,bool_t
}
CU_ASSERT_TRUE(call(marie, pauline));
CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 1));
CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1));
BC_ASSERT_TRUE(call(marie, pauline));
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));
if (linphone_core_get_current_call(marie->lc)) {
params = linphone_call_get_current_params(linphone_core_get_current_call(marie->lc));
CU_ASSERT_STRING_EQUAL(linphone_call_params_get_rtp_profile(params), expected_profile);
BC_ASSERT_STRING_EQUAL(linphone_call_params_get_rtp_profile(params), expected_profile);
}
if (linphone_core_get_current_call(pauline->lc)) {
params = linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc));
CU_ASSERT_STRING_EQUAL(linphone_call_params_get_rtp_profile(params), expected_profile);
BC_ASSERT_STRING_EQUAL(linphone_call_params_get_rtp_profile(params), expected_profile);
}
linphone_core_terminate_all_calls(marie->lc);
CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1));
CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallEnd, 1));
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallConnected, 1);
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallConnected, 1);
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1));
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallEnd, 1));
BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallConnected, 1, int, "%d");
BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallConnected, 1, int, "%d");
end:
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(marie);

Some files were not shown because too many files have changed in this diff Show more