mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-02-02 19:29:27 +00:00
Merge branch 'master' of git.linphone.org:linphone-private
This commit is contained in:
commit
aadd9b0b02
81 changed files with 10544 additions and 11861 deletions
60
AUTHORS
60
AUTHORS
|
|
@ -1,57 +1,13 @@
|
|||
Simon MORLAT (simon dot morlat at linphone dot org) wrotes:
|
||||
- main graphical program (gnome)
|
||||
- RTP library (oRTP)
|
||||
- SIP user-agent library (osipua)
|
||||
- audio library (mediastreamer), for codec and i/o handling.
|
||||
- sipomatic, the automatic sip replier, which is often used for testing.
|
||||
Main authors:
|
||||
|
||||
Florian Wintertein < f-win at gmx dot net > wrotes the console version of linphone (linphonec)
|
||||
Belledonne Communications SARL team:
|
||||
Simon Morlat, Jehan Monnier, Guillaume Beraudo
|
||||
|
||||
Contributors:
|
||||
|
||||
Florian Wintertein < f-win at gmx dot net > originaly wrotes the console version of linphone (linphonec)
|
||||
in console/ directory.
|
||||
|
||||
Aymeric Moizard (jack at atosc dot org) wrotes:
|
||||
- the oSIP SIP transactionnal stack (not part of linphone)
|
||||
- some piece of code of the osip distribution have been reused in osipua
|
||||
- presence information support in osipua
|
||||
- and contributes to some parts of osipua (digest authentification)
|
||||
For more information about oSIP, see http://osip.atosc.org
|
||||
|
||||
Sharath Udupa is developing the media_api, a usefull library to manage audio and video streams
|
||||
for basic calls as well as conference.
|
||||
|
||||
Sandro Santilli < strk at keybit dot net > wrote enhancements in the
|
||||
console interface (readline, new commands) and some bug fixes for
|
||||
the core api.
|
||||
console interface (readline, new commands).
|
||||
|
||||
Bryan Ogawa ( bko at cisco dot com ) sent a patch that made the linphone-0.7.1 release.
|
||||
This patch fixed several issues in the SIP part while working with proxies.
|
||||
|
||||
Koichi KUNITAKE < kunitake at linux-ipv6 dot org > has contributed a patch bringing
|
||||
full IPv6 support.
|
||||
|
||||
The Speex codec is a project from Jean Marc Valin. See http://speex.sourceforge.net for more
|
||||
information.
|
||||
|
||||
The GSM library was written by :
|
||||
Jutta Degener and Carsten Bormann,Technische Universitaet Berlin.
|
||||
|
||||
The LPC10-1.5 library was written by:
|
||||
Andy Fingerhut
|
||||
Applied Research Laboratory <-- this line is optional if
|
||||
Washington University, Campus Box 1045/Bryan 509 you have limited space
|
||||
One Brookings Drive
|
||||
Saint Louis, MO 63130-4899
|
||||
jaf@arl.wustl.edu
|
||||
http://www.arl.wustl.edu/~jaf/
|
||||
|
||||
See text files in gsmlib and lpc10-1.5 directories for further information.
|
||||
|
||||
G711 library has some code from the alsa-lib on http://www.alsa-project.org
|
||||
|
||||
Icons by Pablo Marcelo Moia.
|
||||
|
||||
Translations:
|
||||
fr: Simon Morlat
|
||||
en: Simon Morlat and Delphine Perreau
|
||||
it: Alberto Zanoni <alberto.zanoni@-NO-SPAM-PLEASE!-tiscalinet.it>
|
||||
de: Jean-Jacques Sarton <jj.sarton@-NO-SPAM-PLEASE-t-online.de>
|
||||
es: Jesús Benítez <gnelson at inMail dot sk>
|
||||
|
|
|
|||
12
Makefile.am
12
Makefile.am
|
|
@ -48,16 +48,16 @@ SDK_EXCLUDED= \
|
|||
$(OPTIONAL_SOUNDS)
|
||||
|
||||
|
||||
GTK_PREFIX=/usr
|
||||
GTK_PREFIX=/
|
||||
GTK_THEME=Outcrop
|
||||
GTK_FILELIST=gtk+-2.18.5.filelist
|
||||
GTK_FILELIST=gtk+-2.22.1.filelist
|
||||
GTK_FILELIST_PATH=$(shell cd $(top_srcdir) && pwd)/$(GTK_FILELIST)
|
||||
LINPHONEDEPS_FILELIST=linphone-deps.filelist
|
||||
WINBINDIST_FILES=$(shell cat $(top_srcdir)/$(LINPHONEDEPS_FILELIST))
|
||||
ISS_SCRIPT=linphone.iss
|
||||
ISS_SCRIPT_PATH=$(shell cd $(top_srcdir) && pwd)/$(ISS_SCRIPT)
|
||||
#path to Inno Setup 5 compiler
|
||||
ISCC=/c/Program\ Files/Inno\ Setup\ 5/ISCC.exe
|
||||
ISCC=ISCC.exe
|
||||
PACKAGE_WIN32_FILELIST=$(PACKAGE)-win32.filelist
|
||||
|
||||
EXTRA_DIST = config.rpath BUGS linphone.kdevelop \
|
||||
|
|
@ -109,7 +109,11 @@ other-cherrypick:
|
|||
cp $$file $(INSTALLDIR_WITH_PREFIX)/$$file ;\
|
||||
fi \
|
||||
done
|
||||
cp /mingw/bin/libgcc_s*.dll $(INSTALLDIR_WITH_PREFIX)/bin/.
|
||||
cp /mingw/bin/libgcc_s*.dll \
|
||||
/mingw/bin/libstdc++-6.dll \
|
||||
/mingw/bin/libintl-8.dll \
|
||||
/mingw/bin/libiconv-2.dll \
|
||||
$(INSTALLDIR_WITH_PREFIX)/bin/.
|
||||
|
||||
|
||||
gtk-cherrypick:
|
||||
|
|
|
|||
19
NEWS
19
NEWS
|
|
@ -1,3 +1,22 @@
|
|||
linphone-3.4.0 -- February 7th, 2011
|
||||
* implement multiple calls feature:
|
||||
- call hold (with possibility to play a music file)
|
||||
- call resume
|
||||
- acceptance of 2nd call while putting the others on hold
|
||||
- creation of another outgoing call while already in call
|
||||
- blind call transfer
|
||||
- attended call transfer
|
||||
**CAUTION**: LinphoneCoreVTable has changed: pay attention to this when upgrading an old application to a newer liblinphone.
|
||||
* improve bandwidth management (one b=AS line is used for audio+video)
|
||||
* improvements in the echo limiter performance
|
||||
* implement a echo calibration feature (see linphone_core_start_echo_calibration()).
|
||||
* stun support bugfixes
|
||||
* possibility to use two video windows, one for local preview, one for remote video (linphonec only)
|
||||
* optimize by not re-creating streams when SDP is unchanged during a reinvite
|
||||
* support for sending early media
|
||||
* doxygen doc and javadoc improvements
|
||||
* based on mediastreamer-2.7.0, please refer to mediastreamer NEWS for changes.
|
||||
|
||||
linphone-3.3.2 -- July 1st, 2010
|
||||
* fix crash when setting firewall address in gtk interface
|
||||
* fix crash while closing video window on windows
|
||||
|
|
|
|||
10
README
10
README
|
|
@ -5,16 +5,16 @@ This is Linphone, a free (GPL) video softphone based on the SIP protocol.
|
|||
- you need at least:
|
||||
- libosip2>=3.0.3
|
||||
- libeXosip2>=3.0.3
|
||||
- speex>=1.1.6
|
||||
- libreadline
|
||||
- speex>=1.2.0 (including libspeexdsp part)
|
||||
- libreadline (optional: for convenient command line in linphonec)
|
||||
+ gsm codec (gsm source package or libgsm-dev or gsm-devel) (optional)
|
||||
+ if you want to gtk/glade interface:
|
||||
- gtk>=2.16.0
|
||||
- libglade>=2.2
|
||||
+ if you want video support:
|
||||
- SDL>=1.2.10
|
||||
- libavcodec (ffmpeg) from a year 2007 or later cvs/svn
|
||||
- libavcodec (ffmpeg)
|
||||
- libswscale (part of ffmpeg too) for better scaling performance
|
||||
- theora (optional)
|
||||
|
||||
with their corresponding -dev or -devel package if you don't use source packages.
|
||||
|
||||
|
|
@ -38,7 +38,7 @@ Here is a short description of the content of the source tree.
|
|||
- coreapi/ is the central point of linphone, which handles relationship between sip signalisation and media
|
||||
streaming. It contains an easy to use api to create a sip phone.
|
||||
|
||||
- gtk-glade/ is the directory that contains the gui frontend of linphone. It uses all libraries descibed above.
|
||||
- gtk/ is the directory that contains the gui frontend of linphone. It uses all libraries descibed above.
|
||||
|
||||
- console/
|
||||
* linphonec.c is the main file for the console version of linphone.
|
||||
|
|
|
|||
104
README.mingw
104
README.mingw
|
|
@ -1,61 +1,57 @@
|
|||
Software to install
|
||||
*******************
|
||||
|
||||
* mingw32, using Automated windows installer (when launched, choose candidate to have lastest binaries)
|
||||
* msys, using windows installer too.
|
||||
Download lastest mingw-get-inst.exe from http://www.mingw.org
|
||||
Run mingw-get-inst.exe. Choose "download lastest catalogues".
|
||||
In the feature list, select:
|
||||
* C compiler
|
||||
* C++ compiler
|
||||
* Mingw developer toolkit
|
||||
Let the installer fetch and install everything.
|
||||
|
||||
run msys as Administrator (right click on the icon, and click 'run as administrator')
|
||||
In mingw shell, run
|
||||
|
||||
Download zip and unzip (download setup.exe and run) from http://gnuwin32.sourceforge.net
|
||||
- add them to your path in msys terminal:
|
||||
export PATH=$PATH:/c/Program\ Files/GnuWin32/bin
|
||||
mingw-get install msys-zip
|
||||
mingw-get install msys-unzip
|
||||
mingw-get install msys-wget
|
||||
|
||||
Download from mingw download page (http://www.mingw.org, click download):
|
||||
- MSYS automake-1.11
|
||||
- MSYS autoconf-2.63
|
||||
- MSYS libtool>=2.2.7
|
||||
- MSYS libcrypt*-bin
|
||||
- MSYS perl
|
||||
- MSYS gettext-*bin* and gettext-*dev*
|
||||
===> Uncompress all these packages in /
|
||||
- from gcc-4.4 directory
|
||||
Download:
|
||||
- gcc-core*-bin
|
||||
- gcc-core-*-dll
|
||||
- gcc-c++*-bin
|
||||
- gcc-c++*-dll
|
||||
- gmp*-dll
|
||||
- mpfr*-dll
|
||||
- w32api*-dev
|
||||
- mingwrt-dev and mingwrt-dll (mingw run time)
|
||||
- gnu binutils 2.19
|
||||
===> Uncompress all these packages in /mingw
|
||||
mkdir -p /opt/perl/bin
|
||||
cp /bin/perl /opt/perl/bin/.
|
||||
|
||||
note: lzma files can be uncompressed using tar --lzma -xvf <file>
|
||||
cd ~
|
||||
#Download intltool
|
||||
wget http://ftp.acc.umu.se/pub/GNOME/binaries/win32/intltool/0.40/intltool_0.40.4-1_win32.zip
|
||||
|
||||
* Download intltool (quicklink:
|
||||
http://ftp.acc.umu.se/pub/GNOME/binaries/win32/intltool/0.40/intltool_0.40.4-1_win32.zip
|
||||
note: -dev package is not needed.)
|
||||
uncompress in / with 'unzip' command.
|
||||
Download lastest linphone-deps-win32 zip from
|
||||
http://download.savannah.gnu.org/releases-noredirect/linphone/misc
|
||||
using your browser.
|
||||
|
||||
* Download lastest gtk+bundle from http://www.gtk.org , uncompress in /
|
||||
* Download libglade and libglade-dev >=2.6.3 from gnome ftp:
|
||||
http://ftp.gnome.org/pub/GNOME/binaries/win32/libglade/2.6/libglade-dev_2.6.4-1_win32.zip
|
||||
http://ftp.gnome.org/pub/GNOME/binaries/win32/libglade/2.6/libglade_2.6.4-1_win32.zip
|
||||
uncompress in /
|
||||
* Download ActiveState perl and run the installer with default options (http://www.activestate.com , developer tools)
|
||||
Yes it is required despite MSYS perl is already installed.
|
||||
Download lastest gtk+ win32 bundle from http://www.gtk.org
|
||||
|
||||
* Download lastest linphone-deps from linphone downloads, misc directory:
|
||||
http://download.savannah.gnu.org/releases-noredirect/linphone/misc/)
|
||||
uncompress in /
|
||||
* Download and install Inno Setup Compiler in its default path (required only if you run 'make setup.exe').
|
||||
Install all these three package in /:
|
||||
|
||||
* HACKS:
|
||||
Move out /lib/libintl.la : it confuses libtool
|
||||
mv /lib/libintl.la /lib/libintl.la.bak
|
||||
Move out libstdc++.la in order to workaround a gcc-4.4.0 bug (or packaging bug):
|
||||
mv /mingw/lib/gcc/mingw32/4.4.0/libstdc++.la /mingw/lib/gcc/mingw32/4.4.0/libstdc++.la.bak
|
||||
cd /
|
||||
unzip ~/intltool_0.40.4-1_win32.zip
|
||||
unzip <path to gtk bundle zip>
|
||||
unzip <path to linphone-deps>
|
||||
|
||||
#Install GTK+ Outcrop theme, the one used by linphone for distribution.
|
||||
cd /share/themes
|
||||
wget http://art.gnome.org/download/themes/gtk2/1122/GTK2-Outcrop.tar.gz
|
||||
tar -xvzf GTK2-Outcrop.tar.gz
|
||||
|
||||
#Remove the special stdint.h and inttypes.h included in linphone-deps: it is for MSVC only.
|
||||
#Mingw will use the one in /mingw/include
|
||||
rm /include/stdint.h /include/inttypes.h
|
||||
|
||||
#Remove libgcc specific libraries, only needed for MSVC:
|
||||
rm /lib/libgcc.a /lib/libmingw32.a /lib/libmingwex.a
|
||||
|
||||
#Remove libintl from gtk, we don't need it and it conflicts with the one supplied by mingw.
|
||||
rm /lib/libintl.dll.a
|
||||
rm /include/intl.h
|
||||
|
||||
* Download and install Inno Setup Compiler (required only if you run 'make setup.exe'). Add it to your windows Path environment variable.
|
||||
|
||||
Get Linphone source code
|
||||
************************
|
||||
|
|
@ -66,7 +62,7 @@ It is recommended that you create a directory somewhere with a path without any
|
|||
c:\sources\
|
||||
Within msys-git bash, do
|
||||
cd /c/sources
|
||||
git clone git://git.savannah.nongnu.org/linphone.git
|
||||
git clone git://git.savannah.nongnu.org/linphone.git --recursive
|
||||
|
||||
|
||||
Building
|
||||
|
|
@ -76,17 +72,6 @@ WARNING: During the build, windows might slow down suddenly. Using ctl+alt+del t
|
|||
you might see a process 'LVpSRV.exe' or something like this that eats 90% of cpu.
|
||||
Kill it. Don't know what it is, but once killed, windows runs normally.
|
||||
|
||||
The following variables must be exported:
|
||||
|
||||
#use ActiveState perl instead of mingw perl
|
||||
export PERL="/c/Perl/bin/perl"
|
||||
export INTLTOOL_PERL="/c/Perl/bin/perl"
|
||||
#add gnuwin32 tools to your path:
|
||||
export PATH=$PATH:/c/Program\ Files/Gnuwin32/bin
|
||||
|
||||
for convenience the 'mingw-envsetup.sh' script in linphone sources does this, so you can just source it:
|
||||
. ./mingw-envsetup.sh
|
||||
|
||||
#run autogen.sh after a git checkout or update
|
||||
./autogen.sh
|
||||
./configure --prefix=/opt/linphone --enable-shared --disable-static
|
||||
|
|
@ -97,6 +82,7 @@ make install
|
|||
make zip
|
||||
#additionally you can make binary installer if you have Inno Setup 5 installed in its default path
|
||||
make setup.exe
|
||||
#now you're done, you have a fresh linphone windows installer in the current directory.
|
||||
|
||||
#build plugins
|
||||
cd mediastreamer2/plugins/msx264
|
||||
|
|
|
|||
|
|
@ -20,6 +20,10 @@ if test -d /opt/local/share/aclocal ; then
|
|||
ACLOCAL_ARGS="-I /opt/local/share/aclocal"
|
||||
fi
|
||||
|
||||
if test -d /share/aclocal ; then
|
||||
ACLOCAL_ARGS="$ACLOCAL_ARGS -I /share/aclocal"
|
||||
fi
|
||||
|
||||
if test -f /opt/local/bin/intltoolize ; then
|
||||
#darwin
|
||||
INTLTOOLIZE=/opt/local/bin/intltoolize
|
||||
|
|
|
|||
|
|
@ -46,13 +46,14 @@ LOCAL_SRC_FILES = \
|
|||
sal_eXosip2_sdp.c \
|
||||
offeranswer.c \
|
||||
callbacks.c \
|
||||
linphonecall.c
|
||||
linphonecall.c \
|
||||
ec-calibrator.c
|
||||
|
||||
LOCAL_CFLAGS += \
|
||||
-D_BYTE_ORDER=_LITTLE_ENDIAN \
|
||||
-DORTP_INET6 \
|
||||
-DENABLE_TRACE \
|
||||
-DLINPHONE_VERSION=\"Linphone-3.3.x\" \
|
||||
-DLINPHONE_VERSION=\"3.4.0\" \
|
||||
-DLINPHONE_PLUGINS_DIR=\"\\tmp\" \
|
||||
-DLOG_DOMAIN=\"Linphone\"
|
||||
|
||||
|
|
@ -72,10 +73,11 @@ LOCAL_C_INCLUDES += \
|
|||
|
||||
LOCAL_LDLIBS += -llog -ldl
|
||||
|
||||
|
||||
|
||||
LOCAL_STATIC_LIBRARIES := \
|
||||
libmediastreamer2 \
|
||||
libortp \
|
||||
libspeex \
|
||||
libeXosip2 \
|
||||
libosip2 \
|
||||
libgsm
|
||||
|
|
@ -85,9 +87,14 @@ LOCAL_STATIC_LIBRARIES += \
|
|||
libavcodec \
|
||||
libswscale \
|
||||
libavcore \
|
||||
libavutil
|
||||
libavutil \
|
||||
libmsx264 \
|
||||
libx264
|
||||
endif
|
||||
|
||||
LOCAL_STATIC_LIBRARIES += libspeex
|
||||
|
||||
|
||||
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
|
||||
LOCAL_CFLAGS += -DHAVE_ILBC=1
|
||||
LOCAL_STATIC_LIBRARIES += libmsilbc
|
||||
|
|
|
|||
22
configure.ac
22
configure.ac
|
|
@ -1,6 +1,6 @@
|
|||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_INIT([linphone],[3.3.99.10],[linphone-developers@nongnu.org])
|
||||
AC_INIT([linphone],[3.4.1],[linphone-developers@nongnu.org])
|
||||
AC_CANONICAL_SYSTEM
|
||||
AC_CONFIG_SRCDIR([coreapi/linphonecore.c])
|
||||
|
||||
|
|
@ -95,25 +95,19 @@ AC_SUBST(ALL_LINGUAS)
|
|||
AC_DEFINE_UNQUOTED(LINPHONE_ALL_LANGS, "$ALL_LINGUAS", [All supported languages])
|
||||
|
||||
if test "$mingw_found" != "yes" ; then
|
||||
dnl gettext macro does not work properly under mingw.
|
||||
dnl gettext macro does not work properly under mingw. And we want to use the one provided by GTK.
|
||||
AM_GNU_GETTEXT([external])
|
||||
LIBS="$LIBS $LIBINTL"
|
||||
else
|
||||
if test "$mingwce_found" != "yes" ; then
|
||||
AC_DEFINE(ENABLE_NLS,1,[Tells whether localisation is possible])
|
||||
AC_DEFINE(HAVE_GETTEXT,1,[Tells wheter localisation is possible])
|
||||
LIBS="$LIBS -L/usr/lib -lintl"
|
||||
else
|
||||
dnl gettext macro does not work properly under mingw.
|
||||
AM_GNU_GETTEXT([external])
|
||||
LIBS="$LIBS $LIBINTL"
|
||||
fi
|
||||
AC_DEFINE(ENABLE_NLS,1,[Tells whether localisation is possible])
|
||||
AC_DEFINE(HAVE_GETTEXT,1,[Tells wheter localisation is possible])
|
||||
LIBS="$LIBS -lintl"
|
||||
fi
|
||||
|
||||
GETTEXT_PACKAGE=linphone
|
||||
AC_SUBST(GETTEXT_PACKAGE)
|
||||
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE",[The name of the gettext package name])
|
||||
AC_CHECK_LIB(intl,libintl_gettext)
|
||||
dnl AC_CHECK_LIB(intl,libintl_gettext)
|
||||
|
||||
AC_CHECK_FUNCS([get_current_dir_name strndup stpcpy] )
|
||||
|
||||
|
|
@ -304,7 +298,9 @@ AC_ARG_ENABLE(x11,
|
|||
if test "$video" = "true"; then
|
||||
|
||||
if test "$enable_x11" = "true"; then
|
||||
AC_CHECK_HEADERS(X11/Xlib.h)
|
||||
AC_CHECK_HEADERS(X11/Xlib.h)
|
||||
AC_CHECK_LIB(X11,XUnmapWindow, X11_LIBS="-lX11")
|
||||
AC_SUBST(X11_LIBS)
|
||||
fi
|
||||
AC_DEFINE(VIDEO_ENABLED,1,[defined if video support is available])
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ linphonec_LDADD = $(top_builddir)/coreapi/liblinphone.la $(READLINE_LIBS) \
|
|||
$(MEDIASTREAMER_LIBS) \
|
||||
$(ORTP_LIBS) \
|
||||
$(SPEEX_LIBS) \
|
||||
$(OSIP_LIBS)
|
||||
$(OSIP_LIBS) \
|
||||
$(X11_LIBS)
|
||||
|
||||
if BUILD_WIN32
|
||||
#special build of linphonec to detach from the windows console
|
||||
|
|
@ -33,17 +34,6 @@ linphoned_LDADD=$(linphonec_LDADD)
|
|||
endif
|
||||
|
||||
|
||||
sipomatic_SOURCES=\
|
||||
sipomatic.c sipomatic.h
|
||||
sipomatic_CFLAGS= $(COMMON_CFLAGS) $(CONSOLE_FLAGS)
|
||||
|
||||
sipomatic_LDADD= $(INTLLIBS) \
|
||||
$(top_builddir)/coreapi/liblinphone.la \
|
||||
$(MEDIASTREAMER_LIBS) \
|
||||
$(ORTP_LIBS) \
|
||||
$(SPEEX_LIBS) \
|
||||
$(OSIP_LIBS)
|
||||
|
||||
linphonecsh_SOURCES = shell.c
|
||||
linphonecsh_CFLAGS = $(CONSOLE_FLAGS)
|
||||
linphonecsh_LDADD = $(ORTP_LIBS)
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ static int lpc_cmd_acodec(LinphoneCore *lc, char *args);
|
|||
static int lpc_cmd_vcodec(LinphoneCore *lc, char *args);
|
||||
static int lpc_cmd_codec(int type, LinphoneCore *lc, char *args);
|
||||
static int lpc_cmd_echocancellation(LinphoneCore *lc, char *args);
|
||||
static int lpc_cmd_echolimiter(LinphoneCore *lc, char *args);
|
||||
static int lpc_cmd_pause(LinphoneCore *lc, char *args);
|
||||
static int lpc_cmd_resume(LinphoneCore *lc, char *args);
|
||||
static int lpc_cmd_mute_mic(LinphoneCore *lc, char *args);
|
||||
|
|
@ -93,6 +94,7 @@ static int lpc_cmd_camera(LinphoneCore *lc, char *args);
|
|||
static int lpc_cmd_video_window(LinphoneCore *lc, char *args);
|
||||
static int lpc_cmd_preview_window(LinphoneCore *lc, char *args);
|
||||
static int lpc_cmd_snapshot(LinphoneCore *lc, char *args);
|
||||
static int lpc_cmd_vfureq(LinphoneCore *lc, char *arg);
|
||||
#endif
|
||||
static int lpc_cmd_states(LinphoneCore *lc, char *args);
|
||||
static int lpc_cmd_identify(LinphoneCore *lc, char *args);
|
||||
|
|
@ -269,6 +271,10 @@ static LPC_COMMAND advanced_commands[] = {
|
|||
"'ec on [<delay>] [<tail>] [<framesize>]' : turn EC on with given delay, tail length and framesize\n"
|
||||
"'ec off' : turn echo cancellation (EC) off\n"
|
||||
"'ec show' : show EC status" },
|
||||
{ "el", lpc_cmd_echolimiter, "Echo limiter",
|
||||
"'el on turns on echo limiter (automatic half duplex, for cases where echo canceller cannot work)\n"
|
||||
"'el off' : turn echo limiter off\n"
|
||||
"'el show' : show echo limiter status" },
|
||||
{ "nortp-on-audio-mute", lpc_cmd_rtp_no_xmit_on_audio_mute,
|
||||
"Set the rtp_no_xmit_on_audio_mute configuration parameter",
|
||||
" If set to 1 then rtp transmission will be muted when\n"
|
||||
|
|
@ -293,6 +299,7 @@ static LPC_COMMAND advanced_commands[] = {
|
|||
{ "snapshot", lpc_cmd_snapshot, "Take a snapshot of currently received video stream",
|
||||
"'snapshot <file path>': take a snapshot and records it in jpeg format into the supplied path\n"
|
||||
},
|
||||
{ "vfureq", lpc_cmd_vfureq, "Request the other side to send VFU for the current call"},
|
||||
#endif
|
||||
{ "states", lpc_cmd_states, "Show internal states of liblinphone, registrations and calls, according to linphonecore.h definitions",
|
||||
"'states global': shows global state of liblinphone \n"
|
||||
|
|
@ -1948,10 +1955,18 @@ static int lpc_cmd_status(LinphoneCore *lc, char *args)
|
|||
LinphoneCallState call_state=LinphoneCallIdle;
|
||||
if (call) call_state=linphone_call_get_state(call);
|
||||
|
||||
switch(call_state){
|
||||
switch(call_state){
|
||||
case LinphoneCallOutgoingInit:
|
||||
linphonec_out("hook=outgoing_init sip:%s\n",linphonec_get_callee());
|
||||
break;
|
||||
case LinphoneCallOutgoingProgress:
|
||||
linphonec_out("hook=dialing\n");
|
||||
linphonec_out("hook=dialing sip:%s\n",linphonec_get_callee());
|
||||
break;
|
||||
case LinphoneCallOutgoingRinging:
|
||||
linphonec_out("hook=ringing sip:%s\n",linphonec_get_callee());
|
||||
break;
|
||||
case LinphoneCallPaused:
|
||||
linphonec_out("hook=paused sip:%s\n",linphonec_get_callee());
|
||||
break;
|
||||
case LinphoneCallIdle:
|
||||
linphonec_out("hook=offhook\n");
|
||||
|
|
@ -1964,8 +1979,8 @@ static int lpc_cmd_status(LinphoneCore *lc, char *args)
|
|||
linphone_core_is_mic_muted (lc) ? "yes" : "no",
|
||||
linphone_core_is_rtp_muted(lc) ? "yes" : "no");
|
||||
}else{
|
||||
linphonec_out("hook=answered duration=%i\n" ,
|
||||
linphone_core_get_current_call_duration(lc));
|
||||
linphonec_out("hook=answered duration=%i %s\n" ,
|
||||
linphone_core_get_current_call_duration(lc), linphonec_get_caller());
|
||||
}
|
||||
break;
|
||||
case LinphoneCallIncomingReceived:
|
||||
|
|
@ -2202,6 +2217,18 @@ static int lpc_cmd_echocancellation(LinphoneCore *lc, char *args){
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int lpc_cmd_echolimiter(LinphoneCore *lc, char *args){
|
||||
if (args){
|
||||
if (strcmp(args,"on")==0){
|
||||
linphone_core_enable_echo_limiter (lc,TRUE);
|
||||
}else if (strcmp(args,"off")==0){
|
||||
linphone_core_enable_echo_limiter (lc,FALSE);
|
||||
}
|
||||
}
|
||||
linphonec_out("Echo limiter is now %s.\n",linphone_core_echo_limiter_enabled (lc) ? "on":"off");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lpc_cmd_mute_mic(LinphoneCore *lc, char *args)
|
||||
{
|
||||
linphone_core_mute_mic(lc, 1);
|
||||
|
|
@ -2408,12 +2435,21 @@ static int lpc_cmd_snapshot(LinphoneCore *lc, char *args){
|
|||
if (!args) return 0;
|
||||
call=linphone_core_get_current_call(lc);
|
||||
if (call!=NULL){
|
||||
linphone_call_take_video_snapshot (call,args);
|
||||
linphonec_out("Taking video snaphot in file %s\n", args);
|
||||
linphone_call_take_video_snapshot(call,args);
|
||||
linphonec_out("Taking video snapshot in file %s\n", args);
|
||||
}else linphonec_out("There is no active call.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lpc_cmd_vfureq(LinphoneCore *lc, char *arg){
|
||||
LinphoneCall *call;
|
||||
call=linphone_core_get_current_call(lc);
|
||||
if (call!=NULL){
|
||||
linphone_call_send_vfu_request(call);
|
||||
linphonec_out("VFU request sent\n");
|
||||
}else linphonec_out("There is no active call.\n");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int lpc_cmd_identify(LinphoneCore *lc, char *args){
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#endif /*_WIN32_WCE*/
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <linphonecore.h>
|
||||
|
||||
|
|
@ -79,7 +80,6 @@
|
|||
|
||||
#ifdef HAVE_X11_XLIB_H
|
||||
#include <X11/Xlib.h>
|
||||
#include <SDL/SDL_syswm.h>
|
||||
#endif
|
||||
|
||||
/***************************************************************************
|
||||
|
|
@ -162,6 +162,7 @@ static char *logfile_name = NULL;
|
|||
static char configfile_name[PATH_MAX];
|
||||
static const char *factory_configfile_name=NULL;
|
||||
static char *sipAddr = NULL; /* for autocall */
|
||||
static int window_id = 0; /* 0=standalone window, or window id for embedding video */
|
||||
#if !defined(_WIN32_WCE)
|
||||
static ortp_pipe_t client_sock=ORTP_PIPE_INVALID;
|
||||
#endif /*_WIN32_WCE*/
|
||||
|
|
@ -391,7 +392,7 @@ static void
|
|||
linphonec_text_received(LinphoneCore *lc, LinphoneChatRoom *cr,
|
||||
const LinphoneAddress *from, const char *msg)
|
||||
{
|
||||
printf("%s: %s\n", linphone_address_as_string(from), msg);
|
||||
linphonec_out("Message received from %s: %s\n", linphone_address_as_string(from), msg);
|
||||
// TODO: provide mechanism for answering.. ('say' command?)
|
||||
}
|
||||
|
||||
|
|
@ -716,6 +717,12 @@ linphonec_init(int argc, char **argv)
|
|||
*/
|
||||
linphonec=linphone_core_new (&linphonec_vtable, configfile_name, factory_configfile_name, NULL);
|
||||
linphone_core_enable_video(linphonec,vcap_enabled,display_enabled);
|
||||
if (display_enabled && window_id != 0)
|
||||
{
|
||||
printf ("Setting window_id: 0x%x\n", window_id);
|
||||
linphone_core_set_native_video_window_id(linphonec,window_id);
|
||||
}
|
||||
|
||||
linphone_core_enable_video_preview(linphonec,preview_enabled);
|
||||
if (!(vcap_enabled || display_enabled)) printf("Warning: video is disabled in linphonec, use -V or -C or -D to enable.\n");
|
||||
#ifdef HAVE_READLINE
|
||||
|
|
@ -878,6 +885,7 @@ usage: linphonec [-c file] [-s sipaddr] [-a] [-V] [-d level ] [-l logfile]\n\
|
|||
-C enable video capture only (disabled by default)\n\
|
||||
-D enable video display only (disabled by default)\n\
|
||||
-S show general state messages (disabled by default)\n\
|
||||
--wid windowid force embedding of video window into provided windowid (disabled by default)\n\
|
||||
-v or --version display version and exits.\n");
|
||||
|
||||
exit(exit_status);
|
||||
|
|
@ -1226,6 +1234,14 @@ linphonec_parse_cmdline(int argc, char **argv)
|
|||
{
|
||||
unix_socket=1;
|
||||
}
|
||||
else if (strncmp ("--wid", argv[arg_num], 5) == 0)
|
||||
{
|
||||
arg_num++;
|
||||
if (arg_num < argc) {
|
||||
char *tmp;
|
||||
window_id = strtol( argv[arg_num], &tmp, 0 );
|
||||
}
|
||||
}
|
||||
else if (old_arg_num == arg_num)
|
||||
{
|
||||
fprintf (stderr, "ERROR: bad arguments\n");
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ void sipomatic_process_event(Sipomatic *obj,eXosip_event_t *ev)
|
|||
}
|
||||
|
||||
|
||||
void endoffile_cb(void *ud, unsigned int ev,void * arg){
|
||||
void endoffile_cb(void *ud, MSFilter *f, unsigned int ev,void * arg){
|
||||
Call*call=(Call*)ud;
|
||||
call->eof=1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,8 @@ liblinphone_la_SOURCES=\
|
|||
linphonecall.c \
|
||||
sipsetup.c sipsetup.h \
|
||||
siplogin.c \
|
||||
lsd.c linphonecore_utils.h
|
||||
lsd.c linphonecore_utils.h \
|
||||
ec-calibrator.c
|
||||
|
||||
|
||||
liblinphone_la_LDFLAGS= -version-info $(LIBLINPHONE_SO_VERSION) -no-undefined
|
||||
|
|
@ -49,7 +50,7 @@ if BUILD_WIN32
|
|||
liblinphone_la_LIBADD+=$(top_builddir)/oRTP/src/libortp.la
|
||||
endif
|
||||
|
||||
noinst_PROGRAMS=test_lsd
|
||||
noinst_PROGRAMS=test_lsd test_ecc
|
||||
|
||||
test_lsd_SOURCES=test_lsd.c
|
||||
|
||||
|
|
@ -57,6 +58,14 @@ test_lsd_LDADD=liblinphone.la \
|
|||
$(MEDIASTREAMER_LIBS) \
|
||||
$(ORTP_LIBS)
|
||||
|
||||
test_ecc_SOURCES=test_ecc.c
|
||||
|
||||
test_ecc_LDADD=liblinphone.la \
|
||||
$(MEDIASTREAMER_LIBS) \
|
||||
$(ORTP_LIBS)
|
||||
|
||||
|
||||
|
||||
AM_CFLAGS=$(STRICT_OPTIONS) -DIN_LINPHONE \
|
||||
$(ORTP_CFLAGS) \
|
||||
$(OSIP_CFLAGS) \
|
||||
|
|
|
|||
|
|
@ -193,21 +193,26 @@ static void call_received(SalOp *h){
|
|||
}else{
|
||||
/*TODO : play a tone within the context of the current call */
|
||||
}
|
||||
|
||||
|
||||
linphone_call_ref(call); /*prevent the call from being destroyed while we are notifying, if the user declines within the state callback */
|
||||
linphone_call_set_state(call,LinphoneCallIncomingReceived,"Incoming call");
|
||||
|
||||
sal_call_notify_ringing(h,propose_early_media || ringback_tone!=NULL);
|
||||
if (call->state==LinphoneCallIncomingReceived){
|
||||
sal_call_notify_ringing(h,propose_early_media || ringback_tone!=NULL);
|
||||
|
||||
if (propose_early_media || ringback_tone!=NULL){
|
||||
linphone_call_set_state(call,LinphoneCallIncomingEarlyMedia,"Incoming call early media");
|
||||
linphone_core_update_streams(lc,call,md);
|
||||
if (propose_early_media || ringback_tone!=NULL){
|
||||
linphone_call_set_state(call,LinphoneCallIncomingEarlyMedia,"Incoming call early media");
|
||||
linphone_core_update_streams(lc,call,md);
|
||||
}
|
||||
if (sal_call_get_replaces(call->op)!=NULL && lp_config_get_int(lc->config,"sip","auto_answer_replacing_calls",1)){
|
||||
linphone_core_accept_call(lc,call);
|
||||
}
|
||||
}
|
||||
linphone_call_unref(call);
|
||||
|
||||
ms_free(barmesg);
|
||||
ms_free(tmp);
|
||||
|
||||
|
||||
if (sal_call_get_replaces(call->op)!=NULL && lp_config_get_int(lc->config,"sip","auto_answer_replacing_calls",1)){
|
||||
linphone_core_accept_call(lc,call);
|
||||
}
|
||||
}
|
||||
|
||||
static void call_ringing(SalOp *h){
|
||||
|
|
@ -286,6 +291,7 @@ static void call_accepted(SalOp *op){
|
|||
ms_free(tmp);
|
||||
ms_free(msg);
|
||||
}
|
||||
linphone_core_update_streams (lc,call,md);
|
||||
linphone_call_set_state(call,LinphoneCallPaused,"Call paused");
|
||||
}else if (sal_media_description_has_dir(md,SalStreamRecvOnly)){
|
||||
/*we are put on hold when the call is initially accepted */
|
||||
|
|
@ -296,19 +302,32 @@ static void call_accepted(SalOp *op){
|
|||
ms_free(tmp);
|
||||
ms_free(msg);
|
||||
}
|
||||
linphone_call_set_state(call,LinphoneCallPaused,"Call paused");
|
||||
linphone_core_update_streams (lc,call,md);
|
||||
linphone_call_set_state(call,LinphoneCallPausedByRemote,"Call paused by remote");
|
||||
}else{
|
||||
if (lc->vtable.display_status){
|
||||
lc->vtable.display_status(lc,_("Call answered - connected."));
|
||||
}
|
||||
if (call->state==LinphoneCallStreamsRunning){
|
||||
/*media was running before, the remote as acceted a call modification (that is
|
||||
a reinvite made by us. We must notify the application this reinvite was accepted*/
|
||||
linphone_call_set_state(call, LinphoneCallUpdated, "Call updated");
|
||||
}else{
|
||||
if (call->state==LinphoneCallResuming){
|
||||
if (lc->vtable.display_status){
|
||||
lc->vtable.display_status(lc,_("Call resumed."));
|
||||
}
|
||||
}else{
|
||||
if (lc->vtable.display_status){
|
||||
char *tmp=linphone_call_get_remote_address_as_string (call);
|
||||
char *msg=ms_strdup_printf(_("Call answered by %s."),tmp);
|
||||
lc->vtable.display_status(lc,msg);
|
||||
ms_free(tmp);
|
||||
ms_free(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
linphone_call_set_state(call,LinphoneCallStreamsRunning,"Connected (streams running)");
|
||||
linphone_core_update_streams (lc,call,md);
|
||||
linphone_call_set_state(call, LinphoneCallStreamsRunning, "Streams running");
|
||||
lc->current_call=call;
|
||||
}
|
||||
linphone_core_update_streams (lc,call,md);
|
||||
}else{
|
||||
/*send a bye*/
|
||||
ms_error("Incompatible SDP offer received in 200Ok, need to abort the call");
|
||||
|
|
@ -342,6 +361,7 @@ static void call_ack(SalOp *op){
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* this callback is called when an incoming re-INVITE modifies the session*/
|
||||
static void call_updating(SalOp *op){
|
||||
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
|
||||
|
|
@ -353,32 +373,22 @@ static void call_updating(SalOp *op){
|
|||
|
||||
if (md && !sal_media_description_empty(md))
|
||||
{
|
||||
if ((call->state==LinphoneCallPausedByRemote || call->state==LinphoneCallPaused) &&
|
||||
sal_media_description_has_dir(md,SalStreamSendRecv) && strcmp(md->addr,"0.0.0.0")!=0){
|
||||
/*make sure we can be resumed */
|
||||
if (lc->current_call!=NULL && lc->current_call!=call){
|
||||
ms_warning("Attempt to be resumed but already in call with somebody else!");
|
||||
/*we are actively running another call, reject with a busy*/
|
||||
sal_call_decline (op,SalReasonBusy,NULL);
|
||||
return;
|
||||
if (sal_media_description_has_dir(call->localdesc,SalStreamSendRecv)){
|
||||
ms_message("Our local status is SalStreamSendRecv");
|
||||
if (sal_media_description_has_dir (md,SalStreamRecvOnly) || sal_media_description_has_dir(md,SalStreamInactive)){
|
||||
/* we are being paused */
|
||||
if(lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,_("We are being paused..."));
|
||||
linphone_call_set_state (call,LinphoneCallPausedByRemote,"Call paused by remote");
|
||||
}else if (!sal_media_description_has_dir(call->resultdesc,SalStreamSendRecv) && sal_media_description_has_dir(md,SalStreamSendRecv)){
|
||||
if(lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,_("We have been resumed..."));
|
||||
linphone_call_set_state (call,LinphoneCallStreamsRunning,"Connected (streams running)");
|
||||
lc->current_call=call;
|
||||
}else{
|
||||
prevstate=call->state;
|
||||
linphone_call_set_state(call, LinphoneCallUpdatedByRemote,"Call updated by remote");
|
||||
}
|
||||
if(lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,_("We have been resumed..."));
|
||||
linphone_call_set_state (call,LinphoneCallStreamsRunning,"Connected (streams running)");
|
||||
}
|
||||
else if(call->state==LinphoneCallStreamsRunning &&
|
||||
( sal_media_description_has_dir(md,SalStreamRecvOnly)
|
||||
|| sal_media_description_has_dir(md,SalStreamInactive)
|
||||
|| strcmp(md->addr,"0.0.0.0")==0)){
|
||||
if(lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,_("We are being paused..."));
|
||||
linphone_call_set_state (call,LinphoneCallPausedByRemote,"Call paused by remote");
|
||||
if (lc->current_call!=call){
|
||||
ms_error("Inconsitency detected: current call is %p but call %p is being paused !",lc->current_call,call);
|
||||
}
|
||||
}else{
|
||||
prevstate=call->state;
|
||||
linphone_call_set_state(call, LinphoneCallUpdatedByRemote,"Call updated by remote");
|
||||
}
|
||||
/*accept the modification (sends a 200Ok)*/
|
||||
sal_call_accept(op);
|
||||
|
|
@ -494,6 +504,13 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de
|
|||
}
|
||||
}
|
||||
|
||||
static void call_released(SalOp *op){
|
||||
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
|
||||
if (call!=NULL){
|
||||
linphone_call_set_state(call,LinphoneCallReleased,"Call released");
|
||||
}else ms_error("call_released() for already destroyed call ?");
|
||||
}
|
||||
|
||||
static void auth_requested(SalOp *h, const char *realm, const char *username){
|
||||
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(h));
|
||||
LinphoneAuthInfo *ai=(LinphoneAuthInfo*)linphone_core_find_auth_info(lc,realm,username);
|
||||
|
|
@ -509,7 +526,7 @@ static void auth_requested(SalOp *h, const char *realm, const char *username){
|
|||
ai->usecount++;
|
||||
}else{
|
||||
if (ai && ai->works==FALSE) {
|
||||
register_failure(h, SalErrorFailure, SalReasonForbidden, _("Authentication failure"));
|
||||
sal_op_cancel_authentication(h);
|
||||
}
|
||||
if (lc->vtable.auth_info_requested)
|
||||
lc->vtable.auth_info_requested(lc,realm,username);
|
||||
|
|
@ -669,6 +686,7 @@ SalCallbacks linphone_sal_callbacks={
|
|||
call_updating,
|
||||
call_terminated,
|
||||
call_failure,
|
||||
call_released,
|
||||
auth_requested,
|
||||
auth_success,
|
||||
register_success,
|
||||
|
|
|
|||
179
coreapi/ec-calibrator.c
Normal file
179
coreapi/ec-calibrator.c
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
linphone
|
||||
Copyright (C) 2011 Belledonne Communications SARL
|
||||
Author: Simon MORLAT (simon.morlat@linphone.org)
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "private.h"
|
||||
|
||||
#include "mediastreamer2/mstonedetector.h"
|
||||
#include "mediastreamer2/dtmfgen.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void ecc_init_filters(EcCalibrator *ecc){
|
||||
ecc->ticker=ms_ticker_new();
|
||||
|
||||
ecc->sndread=ms_snd_card_create_reader(ecc->play_card);
|
||||
ecc->det=ms_filter_new(MS_TONE_DETECTOR_ID);
|
||||
ecc->rec=ms_filter_new(MS_FILE_REC_ID);
|
||||
|
||||
ms_filter_link(ecc->sndread,0,ecc->det,0);
|
||||
ms_filter_link(ecc->det,0,ecc->rec,0);
|
||||
|
||||
ecc->play=ms_filter_new(MS_FILE_PLAYER_ID);
|
||||
ecc->gen=ms_filter_new(MS_DTMF_GEN_ID);
|
||||
ecc->resampler=ms_filter_new(MS_RESAMPLE_ID);
|
||||
ecc->sndwrite=ms_snd_card_create_writer(ecc->capt_card);
|
||||
|
||||
ms_filter_link(ecc->play,0,ecc->gen,0);
|
||||
ms_filter_link(ecc->gen,0,ecc->resampler,0);
|
||||
ms_filter_link(ecc->resampler,0,ecc->sndwrite,0);
|
||||
unsigned int rate;
|
||||
ms_filter_call_method(ecc->sndwrite,MS_FILTER_GET_SAMPLE_RATE,&rate);
|
||||
ms_filter_call_method(ecc->resampler,MS_FILTER_SET_OUTPUT_SAMPLE_RATE,&rate);
|
||||
|
||||
ms_ticker_attach(ecc->ticker,ecc->play);
|
||||
ms_ticker_attach(ecc->ticker,ecc->sndread);
|
||||
}
|
||||
|
||||
static void ecc_deinit_filters(EcCalibrator *ecc){
|
||||
ms_ticker_detach(ecc->ticker,ecc->play);
|
||||
ms_ticker_detach(ecc->ticker,ecc->sndread);
|
||||
|
||||
ms_filter_unlink(ecc->play,0,ecc->gen,0);
|
||||
ms_filter_unlink(ecc->gen,0,ecc->resampler,0);
|
||||
ms_filter_unlink(ecc->resampler,0,ecc->sndwrite,0);
|
||||
|
||||
ms_filter_unlink(ecc->sndread,0,ecc->det,0);
|
||||
ms_filter_unlink(ecc->det,0,ecc->rec,0);
|
||||
|
||||
ms_filter_destroy(ecc->sndread);
|
||||
ms_filter_destroy(ecc->det);
|
||||
ms_filter_destroy(ecc->rec);
|
||||
ms_filter_destroy(ecc->play);
|
||||
ms_filter_destroy(ecc->gen);
|
||||
ms_filter_destroy(ecc->resampler);
|
||||
ms_filter_destroy(ecc->sndwrite);
|
||||
|
||||
ms_ticker_destroy(ecc->ticker);
|
||||
}
|
||||
|
||||
static void on_tone_sent(void *data, MSFilter *f, unsigned int event_id, void *arg){
|
||||
MSDtmfGenEvent *ev=(MSDtmfGenEvent*)arg;
|
||||
EcCalibrator *ecc=(EcCalibrator*)data;
|
||||
ecc->sent_count++;
|
||||
ecc->acc-=ev->tone_start_time;
|
||||
ms_message("Sent tone at %u",(unsigned int)ev->tone_start_time);
|
||||
}
|
||||
|
||||
static void on_tone_received(void *data, MSFilter *f, unsigned int event_id, void *arg){
|
||||
MSToneDetectorEvent *ev=(MSToneDetectorEvent*)arg;
|
||||
EcCalibrator *ecc=(EcCalibrator*)data;
|
||||
ecc->recv_count++;
|
||||
ecc->acc+=ev->tone_start_time;
|
||||
ms_message("Received tone at %u",(unsigned int)ev->tone_start_time);
|
||||
}
|
||||
|
||||
static void ecc_play_tones(EcCalibrator *ecc){
|
||||
MSDtmfGenCustomTone tone;
|
||||
MSToneDetectorDef expected_tone;
|
||||
|
||||
|
||||
ms_filter_set_notify_callback(ecc->det,on_tone_received,ecc);
|
||||
|
||||
expected_tone.frequency=2000;
|
||||
expected_tone.min_duration=40;
|
||||
expected_tone.min_amplitude=0.02;
|
||||
|
||||
ms_filter_call_method (ecc->det,MS_TONE_DETECTOR_ADD_SCAN,&expected_tone);
|
||||
|
||||
tone.frequency=1000;
|
||||
tone.duration=1000;
|
||||
tone.amplitude=1.0;
|
||||
|
||||
/*play an initial tone to startup the audio playback/capture*/
|
||||
ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone);
|
||||
ms_sleep(2);
|
||||
|
||||
ms_filter_set_notify_callback(ecc->gen,on_tone_sent,ecc);
|
||||
tone.frequency=2000;
|
||||
tone.duration=100;
|
||||
|
||||
ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone);
|
||||
ms_sleep(1);
|
||||
ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone);
|
||||
ms_sleep(1);
|
||||
ms_filter_call_method(ecc->gen,MS_DTMF_GEN_PLAY_CUSTOM,&tone);
|
||||
ms_sleep(1);
|
||||
|
||||
if (ecc->sent_count==3 && ecc->recv_count==3){
|
||||
int delay=ecc->acc/3;
|
||||
if (delay<0){
|
||||
ms_error("Quite surprising calibration result, delay=%i",delay);
|
||||
ecc->status=LinphoneEcCalibratorFailed;
|
||||
}else{ms_message("Echo calibration estimated delay to be %i ms",delay);
|
||||
ecc->delay=delay;
|
||||
ecc->status=LinphoneEcCalibratorDone;
|
||||
}
|
||||
}else{
|
||||
ms_error("Echo calibration failed, tones received = %i",ecc->recv_count);
|
||||
ecc->status=LinphoneEcCalibratorFailed;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void * ecc_thread(void *p){
|
||||
EcCalibrator *ecc=(EcCalibrator*)p;
|
||||
|
||||
ecc_init_filters(ecc);
|
||||
ecc_play_tones(ecc);
|
||||
ecc_deinit_filters(ecc);
|
||||
ms_thread_exit(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EcCalibrator * ec_calibrator_new(MSSndCard *play_card, MSSndCard *capt_card, LinphoneEcCalibrationCallback cb, void *cb_data ){
|
||||
EcCalibrator *ecc=ms_new0(EcCalibrator,1);
|
||||
|
||||
ecc->cb=cb;
|
||||
ecc->cb_data=cb_data;
|
||||
ecc->capt_card=capt_card;
|
||||
ecc->play_card=play_card;
|
||||
ms_thread_create(&ecc->thread,NULL,ecc_thread,ecc);
|
||||
return ecc;
|
||||
}
|
||||
|
||||
LinphoneEcCalibratorStatus ec_calibrator_get_status(EcCalibrator *ecc){
|
||||
return ecc->status;
|
||||
}
|
||||
|
||||
void ec_calibrator_destroy(EcCalibrator *ecc){
|
||||
ms_thread_join(ecc->thread,NULL);
|
||||
ms_free(ecc);
|
||||
}
|
||||
|
||||
int linphone_core_start_echo_calibration(LinphoneCore *lc, LinphoneEcCalibrationCallback cb, void *cb_data){
|
||||
if (lc->ecc!=NULL){
|
||||
ms_error("Echo calibration is still on going !");
|
||||
return -1;
|
||||
}
|
||||
lc->ecc=ec_calibrator_new(lc->sound_conf.play_sndcard,lc->sound_conf.capt_sndcard,cb,cb_data);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -277,7 +277,9 @@ SalPresenceStatus linphone_online_status_to_sal(LinphoneOnlineStatus os){
|
|||
}
|
||||
|
||||
void linphone_friend_notify(LinphoneFriend *lf, LinphoneOnlineStatus os){
|
||||
//printf("Wish to notify %p, lf->nid=%i\n",lf,lf->nid);
|
||||
char *addr=linphone_address_as_string(linphone_friend_get_address(lf));
|
||||
ms_message("Want to notify %s, insub=%p",addr,lf->insub);
|
||||
ms_free(addr);
|
||||
if (lf->insub!=NULL){
|
||||
sal_notify_presence(lf->insub,linphone_online_status_to_sal(os),NULL);
|
||||
}
|
||||
|
|
@ -286,8 +288,6 @@ void linphone_friend_notify(LinphoneFriend *lf, LinphoneOnlineStatus os){
|
|||
static void linphone_friend_unsubscribe(LinphoneFriend *lf){
|
||||
if (lf->outsub!=NULL) {
|
||||
sal_unsubscribe(lf->outsub);
|
||||
sal_op_release(lf->outsub);
|
||||
lf->outsub=NULL;
|
||||
lf->subscribe_active=FALSE;
|
||||
}
|
||||
}
|
||||
|
|
@ -296,13 +296,19 @@ void linphone_friend_close_subscriptions(LinphoneFriend *lf){
|
|||
linphone_friend_unsubscribe(lf);
|
||||
if (lf->insub){
|
||||
sal_notify_close(lf->insub);
|
||||
sal_op_release(lf->insub);
|
||||
lf->insub=NULL;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_friend_destroy(LinphoneFriend *lf){
|
||||
|
||||
if (lf->insub) {
|
||||
sal_op_release(lf->insub);
|
||||
lf->insub=NULL;
|
||||
}
|
||||
if (lf->outsub){
|
||||
sal_op_release(lf->outsub);
|
||||
lf->outsub=NULL;
|
||||
}
|
||||
if (lf->uri!=NULL) linphone_address_destroy(lf->uri);
|
||||
if (lf->info!=NULL) buddy_info_free(lf->info);
|
||||
ms_free(lf);
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ WARN_LOGFILE =
|
|||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
INPUT = . ../
|
||||
INPUT = @top_srcdir@/coreapi @top_srcdir@/coreapi/help
|
||||
|
||||
FILE_PATTERNS = *.h \
|
||||
*.c \
|
||||
|
|
@ -89,7 +89,7 @@ RECURSIVE = NO
|
|||
EXCLUDE =
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS =
|
||||
EXAMPLE_PATH = ../../ .
|
||||
EXAMPLE_PATH = @top_srcdir@ @top_srcdir@/coreapi/help
|
||||
EXAMPLE_PATTERNS =
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
IMAGE_PATH =
|
||||
|
|
|
|||
|
|
@ -32,23 +32,29 @@ endif
|
|||
clean-local:
|
||||
rm -rf doc
|
||||
|
||||
#tutorials
|
||||
|
||||
noinst_PROGRAMS=helloworld registration buddy_status chatroom
|
||||
|
||||
helloworld_SOURCES=helloworld.c
|
||||
LINPHONE_TUTOS=$(helloworld_SOURCES)
|
||||
|
||||
helloworld_LDADD=$(top_builddir)/coreapi/liblinphone.la \
|
||||
$(MEDIASTREAMER_LIBS) \
|
||||
$(ORTP_LIBS)
|
||||
|
||||
registration_SOURCES=registration.c
|
||||
LINPHONE_TUTOS+=$(registration_SOURCES)
|
||||
|
||||
registration_LDADD=$(helloworld_LDADD)
|
||||
|
||||
buddy_status_SOURCES=buddy_status.c
|
||||
LINPHONE_TUTOS+=$(buddy_status_SOURCES)
|
||||
|
||||
buddy_status_LDADD=$(helloworld_LDADD)
|
||||
|
||||
chatroom_SOURCES=chatroom.c
|
||||
LINPHONE_TUTOS+=$(chatroom_SOURCES)
|
||||
|
||||
chatroom_LDADD=$(helloworld_LDADD)
|
||||
|
||||
|
|
@ -68,3 +74,7 @@ AM_CFLAGS=$(STRICT_OPTIONS) -DIN_LINPHONE \
|
|||
-DORTP_INET6 \
|
||||
$(VIDEO_CFLAGS)
|
||||
|
||||
|
||||
tutodir=$(datadir)/tutorials/linphone
|
||||
|
||||
tuto_DATA=$(LINPHONE_TUTOS)
|
||||
|
|
|
|||
|
|
@ -66,19 +66,36 @@ static void new_subscription_request (LinphoneCore *lc, LinphoneFriend *friend,
|
|||
linphone_core_add_friend(lc,friend); /* add this new friend to the buddy list*/
|
||||
|
||||
}
|
||||
/**
|
||||
* Registration state notification callback
|
||||
*/
|
||||
static void registration_state_changed(struct _LinphoneCore *lc, LinphoneProxyConfig *cfg, LinphoneRegistrationState cstate, const char *message){
|
||||
printf("New registration state %s for user id [%s] at proxy [%s]\n"
|
||||
,linphone_registration_state_to_string(cstate)
|
||||
,linphone_proxy_config_get_identity(cfg)
|
||||
,linphone_proxy_config_get_addr(cfg));
|
||||
}
|
||||
|
||||
LinphoneCore *lc;
|
||||
int main(int argc, char *argv[]){
|
||||
LinphoneCoreVTable vtable={0};
|
||||
|
||||
char* dest_friend=NULL;
|
||||
|
||||
char* identity=NULL;
|
||||
char* password=NULL;
|
||||
|
||||
/* takes sip uri identity from the command line arguments */
|
||||
if (argc>1){
|
||||
dest_friend=argv[1];
|
||||
}
|
||||
|
||||
/* takes sip uri identity from the command line arguments */
|
||||
if (argc>2){
|
||||
identity=argv[2];
|
||||
}
|
||||
/* takes password from the command line arguments */
|
||||
if (argc>3){
|
||||
password=argv[3];
|
||||
}
|
||||
signal(SIGINT,stop);
|
||||
//#define DEBUG
|
||||
#ifdef DEBUG
|
||||
|
|
@ -91,11 +108,47 @@ int main(int argc, char *argv[]){
|
|||
*/
|
||||
vtable.notify_presence_recv=notify_presence_recv_updated;
|
||||
vtable.new_subscription_request=new_subscription_request;
|
||||
vtable.registration_state_changed=registration_state_changed; /*just in case sip proxy is used*/
|
||||
|
||||
/*
|
||||
Instantiate a LinphoneCore object given the LinphoneCoreVTable
|
||||
*/
|
||||
lc=linphone_core_new(&vtable,NULL,NULL,NULL);
|
||||
/*sip proxy might be requested*/
|
||||
if (identity != NULL) {
|
||||
/*create proxy config*/
|
||||
LinphoneProxyConfig* proxy_cfg = linphone_proxy_config_new();
|
||||
/*parse identity*/
|
||||
LinphoneAddress *from = linphone_address_new(identity);
|
||||
if (from==NULL){
|
||||
printf("%s not a valid sip uri, must be like sip:toto@sip.linphone.org \n",identity);
|
||||
goto end;
|
||||
}
|
||||
LinphoneAuthInfo *info;
|
||||
if (password!=NULL){
|
||||
info=linphone_auth_info_new(linphone_address_get_username(from),NULL,password,NULL,NULL); /*create authentication structure from identity*/
|
||||
linphone_core_add_auth_info(lc,info); /*add authentication info to LinphoneCore*/
|
||||
}
|
||||
|
||||
// configure proxy entries
|
||||
linphone_proxy_config_set_identity(proxy_cfg,identity); /*set identity with user name and domain*/
|
||||
linphone_proxy_config_set_server_addr(proxy_cfg,linphone_address_get_domain(from)); /* we assume domain = proxy server address*/
|
||||
linphone_proxy_config_enable_register(proxy_cfg,TRUE); /*activate registration for this proxy config*/
|
||||
linphone_proxy_config_enable_publish(proxy_cfg,TRUE); /* enable presence satus publication for this proxy*/
|
||||
linphone_address_destroy(from); /*release resource*/
|
||||
|
||||
linphone_core_add_proxy_config(lc,proxy_cfg); /*add proxy config to linphone core*/
|
||||
linphone_core_set_default_proxy(lc,proxy_cfg); /*set to default proxy*/
|
||||
|
||||
|
||||
/* Loop until registration status is available */
|
||||
do {
|
||||
linphone_core_iterate(lc); /* first iterate initiates registration */
|
||||
ms_usleep(100000);
|
||||
}
|
||||
while( running && linphone_proxy_config_get_state(proxy_cfg) == LinphoneRegistrationProgress);
|
||||
|
||||
}
|
||||
LinphoneFriend* my_friend=NULL;
|
||||
|
||||
if (dest_friend) {
|
||||
|
|
|
|||
|
|
@ -34,6 +34,13 @@
|
|||
|
||||
/**
|
||||
* @defgroup call_control Placing and receiving calls
|
||||
*
|
||||
* The #LinphoneCall object represents an incoming or outgoing call managed by the #LinphoneCore.
|
||||
* Outgoing calls can be created using linphone_core_invite() or linphone_core_invite_address(), while incoming calls are notified to the application
|
||||
* through the LinphoneCoreVTable::call_state_changed callback.
|
||||
*
|
||||
* See the basic call \ref basic_call_tutorials "tutorial".
|
||||
*
|
||||
**/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import org.linphone.core.LinphoneAddress;
|
|||
import org.linphone.core.LinphoneCall;
|
||||
import org.linphone.core.LinphoneChatRoom;
|
||||
import org.linphone.core.LinphoneCore;
|
||||
import org.linphone.core.LinphoneCore.EcCalibratorStatus;
|
||||
import org.linphone.core.LinphoneCoreException;
|
||||
import org.linphone.core.LinphoneCoreFactory;
|
||||
import org.linphone.core.LinphoneCoreListener;
|
||||
|
|
@ -40,7 +41,9 @@ import org.linphone.core.LinphoneFriend.SubscribePolicy;
|
|||
* from a sip uri identity passed from the command line.
|
||||
* <br>Argument must be like sip:jehan@sip.linphone.org .
|
||||
* ex budy_list sip:jehan@sip.linphone.org
|
||||
* <br>Subscription is cleared on SIGINT
|
||||
* <br>
|
||||
* Optionnally argument 2 can be registration sip identy.Argument 3 can be passord.
|
||||
* ex: budy_list sip:jehan@sip.linphone.org sip:myidentity@sip.linphone.org mypassword
|
||||
*
|
||||
* Ported from buddy_status.c
|
||||
*
|
||||
|
|
@ -81,7 +84,9 @@ public class TutorialBuddyStatus implements LinphoneCoreListener {
|
|||
}
|
||||
|
||||
|
||||
public void registrationState(LinphoneCore lc, LinphoneProxyConfig cfg,RegistrationState cstate, String smessage) {}
|
||||
public void registrationState(LinphoneCore lc, LinphoneProxyConfig cfg,RegistrationState cstate, String smessage) {
|
||||
write(cfg.getIdentity() + " : "+smessage+"\n");
|
||||
}
|
||||
public void show(LinphoneCore lc) {}
|
||||
public void byeReceived(LinphoneCore lc, String from) {}
|
||||
public void authInfoRequested(LinphoneCore lc, String realm, String username) {}
|
||||
|
|
@ -91,14 +96,14 @@ public class TutorialBuddyStatus implements LinphoneCoreListener {
|
|||
public void globalState(LinphoneCore lc, GlobalState state, String message) {}
|
||||
public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from, String message) {}
|
||||
public void callState(LinphoneCore lc, LinphoneCall call, State cstate, String msg) {}
|
||||
|
||||
public void ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status,int delay_ms, Object data) {}
|
||||
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Check tutorial was called with the right number of arguments
|
||||
if (args.length != 1) {
|
||||
throw new IllegalArgumentException("Bad number of arguments");
|
||||
if (args.length < 1 || args.length > 3 ) {
|
||||
throw new IllegalArgumentException("Bad number of arguments ["+args.length+"] should be 1, 2 or 3");
|
||||
}
|
||||
|
||||
// Create tutorial object
|
||||
|
|
@ -106,7 +111,13 @@ public class TutorialBuddyStatus implements LinphoneCoreListener {
|
|||
try {
|
||||
// takes sip uri identity from the command line arguments
|
||||
String userSipAddress = args[1];
|
||||
tutorial.launchTutorial(userSipAddress);
|
||||
|
||||
// takes sip uri identity from the command line arguments
|
||||
String mySipAddress = args.length>1?args[1]:null;
|
||||
// takes password from the command line arguments
|
||||
String mySipPassword =args.length>2?args[2]:null;
|
||||
|
||||
tutorial.launchTutorial(userSipAddress,mySipAddress,mySipPassword);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
|
@ -114,7 +125,7 @@ public class TutorialBuddyStatus implements LinphoneCoreListener {
|
|||
|
||||
|
||||
|
||||
public void launchTutorial(String sipAddress) throws LinphoneCoreException {
|
||||
public void launchTutorial(String sipAddress,String mySipAddress, String mySipPassword) throws LinphoneCoreException {
|
||||
final LinphoneCoreFactory lcFactory = LinphoneCoreFactory.instance();
|
||||
|
||||
// First instantiate the core Linphone object given only a listener.
|
||||
|
|
@ -131,6 +142,34 @@ public class TutorialBuddyStatus implements LinphoneCoreListener {
|
|||
return;
|
||||
}
|
||||
|
||||
if (mySipAddress != null) {
|
||||
// Parse identity
|
||||
LinphoneAddress address = lcFactory.createLinphoneAddress(mySipAddress);
|
||||
String username = address.getUserName();
|
||||
String domain = address.getDomain();
|
||||
|
||||
|
||||
if (mySipPassword != null) {
|
||||
// create authentication structure from identity and add to linphone
|
||||
lc.addAuthInfo(lcFactory.createAuthInfo(username, mySipPassword, null));
|
||||
}
|
||||
|
||||
// create proxy config
|
||||
LinphoneProxyConfig proxyCfg = lcFactory.createProxyConfig(mySipAddress, domain, null, true);
|
||||
proxyCfg.enablePublish(true);
|
||||
lc.addProxyConfig(proxyCfg); // add it to linphone
|
||||
lc.setDefaultProxyConfig(proxyCfg);
|
||||
while (!proxyCfg.isRegistered()) {
|
||||
lc.iterate(); //iterate until registration
|
||||
try{
|
||||
Thread.sleep(1000);
|
||||
} catch(InterruptedException ie) {
|
||||
write("Interrupted!\nAborting");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// configure this friend to emit SUBSCRIBE message after being added to LinphoneCore
|
||||
lf.enableSubscribes(true);
|
||||
|
||||
|
|
@ -191,4 +230,6 @@ public class TutorialBuddyStatus implements LinphoneCoreListener {
|
|||
TutorialNotifier.notify(s);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import org.linphone.core.LinphoneAddress;
|
|||
import org.linphone.core.LinphoneCall;
|
||||
import org.linphone.core.LinphoneChatRoom;
|
||||
import org.linphone.core.LinphoneCore;
|
||||
import org.linphone.core.LinphoneCore.EcCalibratorStatus;
|
||||
import org.linphone.core.LinphoneCoreException;
|
||||
import org.linphone.core.LinphoneCoreFactory;
|
||||
import org.linphone.core.LinphoneCoreListener;
|
||||
|
|
@ -73,7 +74,7 @@ public class TutorialChatRoom implements LinphoneCoreListener {
|
|||
public void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf,String url) {}
|
||||
public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf) {}
|
||||
public void callState(LinphoneCore lc, LinphoneCall call, State cstate, String msg){}
|
||||
|
||||
public void ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status,int delay_ms, Object data) {}
|
||||
|
||||
|
||||
public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from, String message) {
|
||||
|
|
@ -144,4 +145,5 @@ public class TutorialChatRoom implements LinphoneCoreListener {
|
|||
TutorialNotifier.notify(s);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import org.linphone.core.LinphoneAddress;
|
|||
import org.linphone.core.LinphoneCall;
|
||||
import org.linphone.core.LinphoneChatRoom;
|
||||
import org.linphone.core.LinphoneCore;
|
||||
import org.linphone.core.LinphoneCore.EcCalibratorStatus;
|
||||
import org.linphone.core.LinphoneCoreException;
|
||||
import org.linphone.core.LinphoneCoreFactory;
|
||||
import org.linphone.core.LinphoneCoreListener;
|
||||
|
|
@ -67,7 +68,7 @@ public class TutorialHelloWorld implements LinphoneCoreListener {
|
|||
public void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf,String url) {}
|
||||
public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf) {}
|
||||
public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from, String message) {}
|
||||
|
||||
public void ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status,int delay_ms, Object data) {}
|
||||
/*
|
||||
* Call state notification listener
|
||||
*/
|
||||
|
|
@ -153,4 +154,5 @@ public class TutorialHelloWorld implements LinphoneCoreListener {
|
|||
TutorialNotifier.notify(s);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import org.linphone.core.LinphoneAddress;
|
|||
import org.linphone.core.LinphoneCall;
|
||||
import org.linphone.core.LinphoneChatRoom;
|
||||
import org.linphone.core.LinphoneCore;
|
||||
import org.linphone.core.LinphoneCore.EcCalibratorStatus;
|
||||
import org.linphone.core.LinphoneCoreException;
|
||||
import org.linphone.core.LinphoneCoreFactory;
|
||||
import org.linphone.core.LinphoneCoreListener;
|
||||
|
|
@ -64,10 +65,7 @@ public class TutorialRegistration implements LinphoneCoreListener {
|
|||
* Registration state notification listener
|
||||
*/
|
||||
public void registrationState(LinphoneCore lc, LinphoneProxyConfig cfg,RegistrationState cstate, String smessage) {
|
||||
write(cfg.getIdentity() + " : "+smessage+"\n");
|
||||
|
||||
if (RegistrationState.RegistrationOk.equals(cstate))
|
||||
running = false;
|
||||
write(cfg.getIdentity() + " : "+smessage);
|
||||
}
|
||||
|
||||
public void show(LinphoneCore lc) {}
|
||||
|
|
@ -81,7 +79,7 @@ public class TutorialRegistration implements LinphoneCoreListener {
|
|||
public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf) {}
|
||||
public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from, String message) {}
|
||||
public void callState(LinphoneCore lc, LinphoneCall call, State cstate, String msg) {}
|
||||
|
||||
public void ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status,int delay_ms, Object data) {}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Check tutorial was called with the right number of arguments
|
||||
|
|
@ -127,36 +125,56 @@ public class TutorialRegistration implements LinphoneCoreListener {
|
|||
|
||||
// create proxy config
|
||||
LinphoneProxyConfig proxyCfg = lcFactory.createProxyConfig(sipAddress, domain, null, true);
|
||||
proxyCfg.setExpires(2000);
|
||||
lc.addProxyConfig(proxyCfg); // add it to linphone
|
||||
lc.setDefaultProxyConfig(proxyCfg);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// main loop for receiving notifications and doing background linphonecore work
|
||||
running = true;
|
||||
while (running) {
|
||||
lc.iterate(); // first iterate initiates registration
|
||||
try{
|
||||
Thread.sleep(50);
|
||||
} catch(InterruptedException ie) {
|
||||
write("Interrupted!\nAborting");
|
||||
return;
|
||||
}
|
||||
sleep(50);
|
||||
}
|
||||
|
||||
|
||||
// Unregister
|
||||
lc.getDefaultProxyConfig().edit();
|
||||
lc.getDefaultProxyConfig().enableRegister(false);
|
||||
lc.getDefaultProxyConfig().done();
|
||||
while(lc.getDefaultProxyConfig().getState() != RegistrationState.RegistrationCleared) {
|
||||
lc.iterate();
|
||||
sleep(50);
|
||||
}
|
||||
|
||||
// Then register again
|
||||
lc.getDefaultProxyConfig().edit();
|
||||
lc.getDefaultProxyConfig().enableRegister(true);
|
||||
lc.getDefaultProxyConfig().done();
|
||||
|
||||
while(lc.getDefaultProxyConfig().getState() != RegistrationState.RegistrationOk
|
||||
&& lc.getDefaultProxyConfig().getState() != RegistrationState.RegistrationFailed) {
|
||||
lc.iterate();
|
||||
sleep(50);
|
||||
}
|
||||
|
||||
// Automatic unregistration on exit
|
||||
|
||||
|
||||
} finally {
|
||||
write("Shutting down...");
|
||||
write("Shutting down linphone...");
|
||||
// You need to destroy the LinphoneCore object when no longer used
|
||||
lc.destroy();
|
||||
write("Exited");
|
||||
}
|
||||
}
|
||||
|
||||
private void sleep(int ms) {
|
||||
try {
|
||||
Thread.sleep(ms);
|
||||
} catch(InterruptedException ie) {
|
||||
write("Interrupted!\nAborting");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void stopMainLoop() {
|
||||
running=false;
|
||||
|
|
@ -167,4 +185,6 @@ public class TutorialRegistration implements LinphoneCoreListener {
|
|||
TutorialNotifier.notify(s);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "mediastreamer2/msequalizer.h"
|
||||
#include "mediastreamer2/msfileplayer.h"
|
||||
#include "mediastreamer2/msjpegwriter.h"
|
||||
#include "mediastreamer2/mseventqueue.h"
|
||||
|
||||
#ifdef VIDEO_ENABLED
|
||||
static MSWebCam *get_nowebcam_device(){
|
||||
|
|
@ -58,18 +59,21 @@ static MSList *make_codec_list(LinphoneCore *lc, const MSList *codecs, int bandw
|
|||
return l;
|
||||
}
|
||||
|
||||
SalMediaDescription *create_local_media_description(LinphoneCore *lc, LinphoneCall *call){
|
||||
static SalMediaDescription *_create_local_media_description(LinphoneCore *lc, LinphoneCall *call, unsigned int session_id, unsigned int session_ver){
|
||||
MSList *l;
|
||||
PayloadType *pt;
|
||||
const char *me=linphone_core_get_identity(lc);
|
||||
LinphoneAddress *addr=linphone_address_new(me);
|
||||
const char *username=linphone_address_get_username (addr);
|
||||
SalMediaDescription *md=sal_media_description_new();
|
||||
|
||||
|
||||
md->session_id=session_id;
|
||||
md->session_ver=session_ver;
|
||||
md->nstreams=1;
|
||||
strncpy(md->addr,call->localip,sizeof(md->addr));
|
||||
strncpy(md->username,username,sizeof(md->username));
|
||||
md->bandwidth=linphone_core_get_download_bandwidth(lc);
|
||||
|
||||
/*set audio capabilities */
|
||||
strncpy(md->streams[0].addr,call->localip,sizeof(md->streams[0].addr));
|
||||
md->streams[0].port=call->audio_port;
|
||||
|
|
@ -81,8 +85,6 @@ SalMediaDescription *create_local_media_description(LinphoneCore *lc, LinphoneCa
|
|||
l=ms_list_append(l,pt);
|
||||
md->streams[0].payloads=l;
|
||||
|
||||
if (lc->dw_audio_bw>0)
|
||||
md->streams[0].bandwidth=lc->dw_audio_bw;
|
||||
|
||||
if (call->params.has_video){
|
||||
md->nstreams++;
|
||||
|
|
@ -91,13 +93,27 @@ SalMediaDescription *create_local_media_description(LinphoneCore *lc, LinphoneCa
|
|||
md->streams[1].type=SalVideo;
|
||||
l=make_codec_list(lc,lc->codecs_conf.video_codecs,0);
|
||||
md->streams[1].payloads=l;
|
||||
if (lc->dw_video_bw)
|
||||
md->streams[1].bandwidth=lc->dw_video_bw;
|
||||
}
|
||||
linphone_address_destroy(addr);
|
||||
return md;
|
||||
}
|
||||
|
||||
void update_local_media_description(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription **md){
|
||||
if (*md == NULL) {
|
||||
*md = _create_local_media_description(lc,call,0,0);
|
||||
} else {
|
||||
unsigned int id = (*md)->session_id;
|
||||
unsigned int ver = (*md)->session_ver+1;
|
||||
sal_media_description_unref(*md);
|
||||
*md = _create_local_media_description(lc,call,id,ver);
|
||||
}
|
||||
}
|
||||
|
||||
SalMediaDescription *create_local_media_description(LinphoneCore *lc, LinphoneCall *call){
|
||||
unsigned int id=rand();
|
||||
return _create_local_media_description(lc,call,id,id);
|
||||
}
|
||||
|
||||
static int find_port_offset(LinphoneCore *lc){
|
||||
int offset;
|
||||
MSList *elem;
|
||||
|
|
@ -129,6 +145,7 @@ static void linphone_call_init_common(LinphoneCall *call, LinphoneAddress *from,
|
|||
call->start_time=time(NULL);
|
||||
call->media_start_time=0;
|
||||
call->log=linphone_call_log_new(call, from, to);
|
||||
call->owns_call_log=TRUE;
|
||||
linphone_core_notify_all_friends(call->core,LinphoneStatusOnThePhone);
|
||||
port_offset=find_port_offset (call->core);
|
||||
if (port_offset==-1) return;
|
||||
|
|
@ -225,8 +242,10 @@ static void linphone_call_set_terminated(LinphoneCall *call){
|
|||
else status=LinphoneCallSuccess;
|
||||
|
||||
}
|
||||
call->owns_call_log=FALSE;
|
||||
linphone_call_log_completed(call->log,call, status);
|
||||
|
||||
|
||||
if (call == lc->current_call){
|
||||
ms_message("Resetting the current call");
|
||||
lc->current_call=NULL;
|
||||
|
|
@ -239,13 +258,6 @@ static void linphone_call_set_terminated(LinphoneCall *call){
|
|||
if (ms_list_size(lc->calls)==0)
|
||||
linphone_core_notify_all_friends(lc,lc->presence_mode);
|
||||
|
||||
if (call->op!=NULL) {
|
||||
/* so that we cannot have anymore upcalls for SAL
|
||||
concerning this call*/
|
||||
sal_op_release(call->op);
|
||||
call->op=NULL;
|
||||
}
|
||||
linphone_call_unref(call);
|
||||
}
|
||||
|
||||
const char *linphone_call_state_to_string(LinphoneCallState cs){
|
||||
|
|
@ -286,14 +298,23 @@ const char *linphone_call_state_to_string(LinphoneCallState cs){
|
|||
return "LinphoneCallIncomingEarlyMedia";
|
||||
case LinphoneCallUpdated:
|
||||
return "LinphoneCallUpdated";
|
||||
case LinphoneCallReleased:
|
||||
return "LinphoneCallReleased";
|
||||
}
|
||||
return "undefined state";
|
||||
}
|
||||
|
||||
void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const char *message){
|
||||
LinphoneCore *lc=call->core;
|
||||
bool_t finalize_call=FALSE;
|
||||
|
||||
if (call->state!=cstate){
|
||||
if (call->state==LinphoneCallEnd || call->state==LinphoneCallError){
|
||||
if (cstate!=LinphoneCallReleased){
|
||||
ms_warning("Spurious call state change from %s to %s, ignored.",linphone_call_state_to_string(call->state),
|
||||
linphone_call_state_to_string(cstate));
|
||||
return;
|
||||
}
|
||||
}
|
||||
ms_message("Call %p: moving from state %s to %s",call,linphone_call_state_to_string(call->state),
|
||||
linphone_call_state_to_string(cstate));
|
||||
if (cstate!=LinphoneCallRefered){
|
||||
|
|
@ -302,14 +323,20 @@ void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const
|
|||
call->state=cstate;
|
||||
}
|
||||
if (cstate==LinphoneCallEnd || cstate==LinphoneCallError){
|
||||
finalize_call=TRUE;
|
||||
linphone_call_ref(call);
|
||||
linphone_call_set_terminated (call);
|
||||
}
|
||||
|
||||
if (lc->vtable.call_state_changed)
|
||||
lc->vtable.call_state_changed(lc,call,cstate,message);
|
||||
if (finalize_call)
|
||||
if (cstate==LinphoneCallReleased){
|
||||
if (call->op!=NULL) {
|
||||
/* so that we cannot have anymore upcalls for SAL
|
||||
concerning this call*/
|
||||
sal_op_release(call->op);
|
||||
call->op=NULL;
|
||||
}
|
||||
linphone_call_unref(call);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -333,6 +360,8 @@ static void linphone_call_destroy(LinphoneCall *obj)
|
|||
if (obj->refer_to){
|
||||
ms_free(obj->refer_to);
|
||||
}
|
||||
if (obj->owns_call_log)
|
||||
linphone_call_log_destroy(obj->log);
|
||||
ms_free(obj);
|
||||
}
|
||||
|
||||
|
|
@ -367,7 +396,7 @@ void linphone_call_unref(LinphoneCall *obj){
|
|||
* Returns current parameters associated to the call.
|
||||
**/
|
||||
const LinphoneCallParams * linphone_call_get_current_params(const LinphoneCall *call){
|
||||
return &call->params;
|
||||
return &call->current_params;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -476,6 +505,20 @@ int linphone_call_get_duration(const LinphoneCall *call){
|
|||
return time(NULL)-call->media_start_time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the call object this call is replacing, if any.
|
||||
* Call replacement can occur during call transfers.
|
||||
* By default, the core automatically terminates the replaced call and accept the new one.
|
||||
* This function allows the application to know whether a new incoming call is a one that replaces another one.
|
||||
**/
|
||||
LinphoneCall *linphone_call_get_replaced_call(LinphoneCall *call){
|
||||
SalOp *op=sal_call_get_replaces(call->op);
|
||||
if (op){
|
||||
return (LinphoneCall*)sal_op_get_user_pointer(op);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate whether camera input should be sent to remote end.
|
||||
**/
|
||||
|
|
@ -508,21 +551,21 @@ int linphone_call_take_video_snapshot(LinphoneCall *call, const char *file){
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns TRUE if camera pictures are sent to the remote party.
|
||||
**/
|
||||
bool_t linphone_call_camera_enabled (const LinphoneCall *call){
|
||||
return call->camera_active;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Enable video stream.
|
||||
**/
|
||||
void linphone_call_params_enable_video(LinphoneCallParams *cp, bool_t enabled){
|
||||
cp->has_video=enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns whether video is enabled.
|
||||
**/
|
||||
bool_t linphone_call_params_video_enabled(const LinphoneCallParams *cp){
|
||||
return cp->has_video;
|
||||
|
|
@ -575,6 +618,21 @@ static void rendercb(void *data, const MSPicture *local, const MSPicture *remote
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef VIDEO_ENABLED
|
||||
static void video_stream_event_cb(void *user_pointer, const MSFilter *f, const unsigned int event_id, const void *args){
|
||||
ms_warning("In linphonecall.c: video_stream_event_cb");
|
||||
switch (event_id) {
|
||||
case MS_VIDEO_DECODER_DECODING_ERRORS:
|
||||
ms_warning("CAse is MS_VIDEO_DECODER_DECODING_ERRORS");
|
||||
linphone_call_send_vfu_request((LinphoneCall*) user_pointer);
|
||||
break;
|
||||
default:
|
||||
ms_warning("Unhandled event %i", event_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void linphone_call_init_media_streams(LinphoneCall *call){
|
||||
LinphoneCore *lc=call->core;
|
||||
SalMediaDescription *md=call->localdesc;
|
||||
|
|
@ -609,6 +667,7 @@ void linphone_call_init_media_streams(LinphoneCall *call){
|
|||
call->videostream=video_stream_new(md->streams[1].port,linphone_core_ipv6_enabled(lc));
|
||||
if( lc->video_conf.displaytype != NULL)
|
||||
video_stream_set_display_filter_name(call->videostream,lc->video_conf.displaytype);
|
||||
video_stream_set_event_callback(call->videostream,video_stream_event_cb, call);
|
||||
#ifdef TEST_EXT_RENDERER
|
||||
video_stream_set_render_callback(call->videostream,rendercb,NULL);
|
||||
#endif
|
||||
|
|
@ -675,27 +734,24 @@ static void post_configure_audio_streams(LinphoneCall*call){
|
|||
}
|
||||
if (st->volsend){
|
||||
ms_filter_call_method(st->volsend,MS_VOLUME_REMOVE_DC,&dc_removal);
|
||||
}
|
||||
if (linphone_core_echo_limiter_enabled(lc)){
|
||||
float speed=lp_config_get_float(lc->config,"sound","el_speed",-1);
|
||||
thres=lp_config_get_float(lc->config,"sound","el_thres",-1);
|
||||
float force=lp_config_get_float(lc->config,"sound","el_force",-1);
|
||||
int sustain=lp_config_get_int(lc->config,"sound","el_sustain",-1);
|
||||
float transmit_thres=lp_config_get_float(lc->config,"sound","el_transmit_thres",-1);
|
||||
MSFilter *f=NULL;
|
||||
if (st->el_type!=ELInactive){
|
||||
f=st->volsend;
|
||||
if (speed==-1) speed=0.03;
|
||||
if (force==-1) force=25;
|
||||
ms_filter_call_method(f,MS_VOLUME_SET_EA_SPEED,&speed);
|
||||
ms_filter_call_method(f,MS_VOLUME_SET_EA_FORCE,&force);
|
||||
if (thres!=-1)
|
||||
ms_filter_call_method(f,MS_VOLUME_SET_EA_THRESHOLD,&thres);
|
||||
if (sustain!=-1)
|
||||
ms_filter_call_method(f,MS_VOLUME_SET_EA_SUSTAIN,&sustain);
|
||||
}
|
||||
}
|
||||
|
||||
if (st->volsend){
|
||||
f=st->volsend;
|
||||
if (speed==-1) speed=0.03;
|
||||
if (force==-1) force=25;
|
||||
ms_filter_call_method(f,MS_VOLUME_SET_EA_SPEED,&speed);
|
||||
ms_filter_call_method(f,MS_VOLUME_SET_EA_FORCE,&force);
|
||||
if (thres!=-1)
|
||||
ms_filter_call_method(f,MS_VOLUME_SET_EA_THRESHOLD,&thres);
|
||||
if (sustain!=-1)
|
||||
ms_filter_call_method(f,MS_VOLUME_SET_EA_SUSTAIN,&sustain);
|
||||
if (transmit_thres!=-1)
|
||||
ms_filter_call_method(f,MS_VOLUME_SET_EA_TRANSMIT_THRESHOLD,&transmit_thres);
|
||||
|
||||
ms_filter_call_method(st->volsend,MS_VOLUME_SET_NOISE_GATE_THRESHOLD,&ng_thres);
|
||||
ms_filter_call_method(st->volsend,MS_VOLUME_SET_NOISE_GATE_FLOORGAIN,&ng_floorgain);
|
||||
}
|
||||
|
|
@ -716,12 +772,13 @@ static void post_configure_audio_streams(LinphoneCall*call){
|
|||
|
||||
|
||||
|
||||
static RtpProfile *make_profile(LinphoneCore *lc, const SalMediaDescription *md, const SalStreamDescription *desc, int *used_pt){
|
||||
static RtpProfile *make_profile(LinphoneCall *call, const SalMediaDescription *md, const SalStreamDescription *desc, int *used_pt){
|
||||
int bw;
|
||||
const MSList *elem;
|
||||
RtpProfile *prof=rtp_profile_new("Call profile");
|
||||
bool_t first=TRUE;
|
||||
int remote_bw=0;
|
||||
LinphoneCore *lc=call->core;
|
||||
*used_pt=-1;
|
||||
|
||||
for(elem=desc->payloads;elem!=NULL;elem=elem->next){
|
||||
|
|
@ -730,7 +787,7 @@ static RtpProfile *make_profile(LinphoneCore *lc, const SalMediaDescription *md,
|
|||
|
||||
if (first) {
|
||||
if (desc->type==SalAudio){
|
||||
linphone_core_update_allocated_audio_bandwidth_in_call(lc,pt);
|
||||
linphone_core_update_allocated_audio_bandwidth_in_call(call,pt);
|
||||
}
|
||||
*used_pt=payload_type_get_number(pt);
|
||||
first=FALSE;
|
||||
|
|
@ -740,13 +797,13 @@ static RtpProfile *make_profile(LinphoneCore *lc, const SalMediaDescription *md,
|
|||
/*case where b=AS is given globally, not per stream*/
|
||||
remote_bw=md->bandwidth;
|
||||
if (desc->type==SalVideo){
|
||||
remote_bw-=lc->audio_bw;
|
||||
remote_bw=get_video_bandwidth(remote_bw,call->audio_bw);
|
||||
}
|
||||
}
|
||||
|
||||
if (desc->type==SalAudio){
|
||||
bw=get_min_bandwidth(lc->up_audio_bw,remote_bw);
|
||||
}else bw=get_min_bandwidth(lc->up_video_bw,remote_bw);
|
||||
bw=get_min_bandwidth(call->audio_bw,remote_bw);
|
||||
}else bw=get_min_bandwidth(get_video_bandwidth(linphone_core_get_upload_bandwidth (lc),call->audio_bw),remote_bw);
|
||||
if (bw>0) pt->normal_bitrate=bw*1000;
|
||||
else if (desc->type==SalAudio){
|
||||
pt->normal_bitrate=-1;
|
||||
|
|
@ -779,12 +836,17 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut
|
|||
const char *tool="linphone-" LINPHONE_VERSION;
|
||||
char *cname;
|
||||
int used_pt=-1;
|
||||
#ifdef VIDEO_ENABLED
|
||||
const SalStreamDescription *vstream=sal_media_description_find_stream(call->resultdesc,
|
||||
SalProtoRtpAvp,SalVideo);
|
||||
#endif
|
||||
|
||||
if(call->audiostream == NULL)
|
||||
{
|
||||
ms_fatal("start_media_stream() called without prior init !");
|
||||
return;
|
||||
}
|
||||
call->current_params = call->params;
|
||||
/* adjust rtp jitter compensation. It must be at least the latency of the sound card */
|
||||
int jitt_comp=MAX(lc->sound_conf.latency,lc->rtp_conf.audio_jitt_comp);
|
||||
|
||||
|
|
@ -800,7 +862,9 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut
|
|||
MSSndCard *captcard=lc->sound_conf.capt_sndcard;
|
||||
const char *playfile=lc->play_file;
|
||||
const char *recfile=lc->rec_file;
|
||||
call->audio_profile=make_profile(lc,call->resultdesc,stream,&used_pt);
|
||||
call->audio_profile=make_profile(call,call->resultdesc,stream,&used_pt);
|
||||
bool_t use_ec;
|
||||
|
||||
if (used_pt!=-1){
|
||||
if (playcard==NULL) {
|
||||
ms_warning("No card defined for playback !");
|
||||
|
|
@ -817,7 +881,8 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut
|
|||
playcard=NULL;
|
||||
captcard=NULL;
|
||||
recfile=NULL;
|
||||
playfile=NULL;
|
||||
/*And we will eventually play "playfile" if set by the user*/
|
||||
/*playfile=NULL;*/
|
||||
}
|
||||
if (send_ringbacktone){
|
||||
captcard=NULL;
|
||||
|
|
@ -828,6 +893,12 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut
|
|||
captcard=NULL;
|
||||
playcard=NULL;
|
||||
}
|
||||
use_ec=captcard==NULL ? FALSE : linphone_core_echo_cancellation_enabled(lc);
|
||||
#if defined(VIDEO_ENABLED) && defined(ANDROID)
|
||||
/*On android we have to disable the echo canceller to preserve CPU for video codecs */
|
||||
if (vstream && vstream->dir!=SalStreamInactive && vstream->payloads!=NULL)
|
||||
use_ec=FALSE;
|
||||
#endif
|
||||
audio_stream_start_full(
|
||||
call->audiostream,
|
||||
call->audio_profile,
|
||||
|
|
@ -840,11 +911,16 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut
|
|||
recfile,
|
||||
playcard,
|
||||
captcard,
|
||||
captcard==NULL ? FALSE : linphone_core_echo_cancellation_enabled(lc));
|
||||
use_ec
|
||||
);
|
||||
post_configure_audio_streams(call);
|
||||
if (all_inputs_muted && !send_ringbacktone){
|
||||
audio_stream_set_mic_gain(call->audiostream,0);
|
||||
}
|
||||
if (stream->dir==SalStreamSendOnly && playfile!=NULL){
|
||||
int pause_time=500;
|
||||
ms_filter_call_method(call->audiostream->soundread,MS_FILE_PLAYER_LOOP,&pause_time);
|
||||
}
|
||||
if (send_ringbacktone){
|
||||
setup_ring_player(lc,call);
|
||||
}
|
||||
|
|
@ -854,23 +930,23 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut
|
|||
}
|
||||
#ifdef VIDEO_ENABLED
|
||||
{
|
||||
const SalStreamDescription *stream=sal_media_description_find_stream(call->resultdesc,
|
||||
SalProtoRtpAvp,SalVideo);
|
||||
|
||||
used_pt=-1;
|
||||
/* shutdown preview */
|
||||
if (lc->previewstream!=NULL) {
|
||||
video_preview_stop(lc->previewstream);
|
||||
lc->previewstream=NULL;
|
||||
}
|
||||
if (stream && stream->dir!=SalStreamInactive) {
|
||||
const char *addr=stream->addr[0]!='\0' ? stream->addr : call->resultdesc->addr;
|
||||
call->video_profile=make_profile(lc,call->resultdesc,stream,&used_pt);
|
||||
call->current_params.has_video=FALSE;
|
||||
if (vstream && vstream->dir!=SalStreamInactive) {
|
||||
const char *addr=vstream->addr[0]!='\0' ? vstream->addr : call->resultdesc->addr;
|
||||
call->video_profile=make_profile(call,call->resultdesc,vstream,&used_pt);
|
||||
if (used_pt!=-1){
|
||||
VideoStreamDir dir=VideoStreamSendRecv;
|
||||
MSWebCam *cam=lc->video_conf.device;
|
||||
bool_t is_inactive=FALSE;
|
||||
|
||||
call->params.has_video=TRUE;
|
||||
call->current_params.has_video=TRUE;
|
||||
|
||||
video_stream_set_sent_video_size(call->videostream,linphone_core_get_preferred_video_size(lc));
|
||||
video_stream_enable_self_view(call->videostream,lc->video_conf.selfview);
|
||||
|
|
@ -880,12 +956,12 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut
|
|||
video_stream_set_native_preview_window_id (call->videostream,lc->preview_window_id);
|
||||
video_stream_use_preview_video_window (call->videostream,lc->use_preview_window);
|
||||
|
||||
if (stream->dir==SalStreamSendOnly && lc->video_conf.capture ){
|
||||
if (vstream->dir==SalStreamSendOnly && lc->video_conf.capture ){
|
||||
cam=get_nowebcam_device();
|
||||
dir=VideoStreamSendOnly;
|
||||
}else if (stream->dir==SalStreamRecvOnly && lc->video_conf.display ){
|
||||
}else if (vstream->dir==SalStreamRecvOnly && lc->video_conf.display ){
|
||||
dir=VideoStreamRecvOnly;
|
||||
}else if (stream->dir==SalStreamSendRecv){
|
||||
}else if (vstream->dir==SalStreamSendRecv){
|
||||
if (lc->video_conf.display && lc->video_conf.capture)
|
||||
dir=VideoStreamSendRecv;
|
||||
else if (lc->video_conf.display)
|
||||
|
|
@ -903,8 +979,8 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut
|
|||
if (!is_inactive){
|
||||
video_stream_set_direction (call->videostream, dir);
|
||||
video_stream_start(call->videostream,
|
||||
call->video_profile, addr, stream->port,
|
||||
stream->port+1,
|
||||
call->video_profile, addr, vstream->port,
|
||||
vstream->port+1,
|
||||
used_pt, jitt_comp, cam);
|
||||
video_stream_set_rtcp_information(call->videostream, cname,tool);
|
||||
}
|
||||
|
|
@ -939,6 +1015,7 @@ void linphone_call_stop_media_streams(LinphoneCall *call){
|
|||
video_stream_stop(call->videostream);
|
||||
call->videostream=NULL;
|
||||
}
|
||||
ms_event_queue_skip(call->core->msevq);
|
||||
|
||||
#endif
|
||||
if (call->audio_profile){
|
||||
|
|
@ -953,3 +1030,52 @@ void linphone_call_stop_media_streams(LinphoneCall *call){
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef VIDEO_ENABLED
|
||||
/**
|
||||
* Request remote side to send us VFU.
|
||||
**/
|
||||
void linphone_call_send_vfu_request(LinphoneCall *call)
|
||||
{
|
||||
if (LinphoneCallStreamsRunning == linphone_call_get_state(call))
|
||||
sal_call_send_vfu_request(call->op);
|
||||
}
|
||||
#endif
|
||||
|
||||
void linphone_call_enable_echo_cancellation(LinphoneCall *call, bool_t enable) {
|
||||
if (call!=NULL && call->audiostream!=NULL && call->audiostream->ec){
|
||||
bool_t bypass_mode = !enable;
|
||||
ms_filter_call_method(call->audiostream->ec,MS_ECHO_CANCELLER_SET_BYPASS_MODE,&bypass_mode);
|
||||
}
|
||||
}
|
||||
bool_t linphone_call_echo_cancellation_enabled(LinphoneCall *call) {
|
||||
if (call!=NULL && call->audiostream!=NULL && call->audiostream->ec){
|
||||
bool_t val;
|
||||
ms_filter_call_method(call->audiostream->ec,MS_ECHO_CANCELLER_GET_BYPASS_MODE,&val);
|
||||
return !val;
|
||||
} else {
|
||||
return linphone_core_echo_cancellation_enabled(call->core);
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_call_enable_echo_limiter(LinphoneCall *call, bool_t val){
|
||||
if (call!=NULL && call->audiostream!=NULL ) {
|
||||
if (val) {
|
||||
const char *type=lp_config_get_string(call->core->config,"sound","el_type","mic");
|
||||
if (strcasecmp(type,"mic")==0)
|
||||
audio_stream_enable_echo_limiter(call->audiostream,ELControlMic);
|
||||
else if (strcasecmp(type,"full")==0)
|
||||
audio_stream_enable_echo_limiter(call->audiostream,ELControlFull);
|
||||
} else {
|
||||
audio_stream_enable_echo_limiter(call->audiostream,ELInactive);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool_t linphone_call_echo_limiter_enabled(const LinphoneCall *call){
|
||||
if (call!=NULL && call->audiostream!=NULL ){
|
||||
return call->audiostream->el_type !=ELInactive ;
|
||||
} else {
|
||||
return linphone_core_echo_limiter_enabled(call->core);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ static void toggle_video_preview(LinphoneCore *lc, bool_t val);
|
|||
#define LOCAL_RING "rings/oldphone.wav"
|
||||
/* same for remote ring (ringback)*/
|
||||
#define REMOTE_RING "ringback.wav"
|
||||
#define HOLD_MUSIC "rings/toy-mono.wav"
|
||||
|
||||
|
||||
extern SalCallbacks linphone_sal_callbacks;
|
||||
|
||||
|
|
@ -452,6 +454,8 @@ static void sound_config_read(LinphoneCore *lc)
|
|||
tmpbuf=PACKAGE_SOUND_DIR "/" REMOTE_RING;
|
||||
}
|
||||
linphone_core_set_ringback(lc,tmpbuf);
|
||||
|
||||
linphone_core_set_play_file(lc,lp_config_get_string(lc->config,"sound","hold_music",PACKAGE_SOUND_DIR "/" HOLD_MUSIC));
|
||||
check_sound_device(lc);
|
||||
lc->sound_conf.latency=0;
|
||||
|
||||
|
|
@ -571,6 +575,7 @@ static void sip_config_read(LinphoneCore *lc)
|
|||
lc->sip_conf.keepalive_period=lp_config_get_int(lc->config,"sip","keepalive_period",10000);
|
||||
sal_set_keepalive_period(lc->sal,lc->sip_conf.keepalive_period);
|
||||
sal_use_one_matching_codec_policy(lc->sal,lp_config_get_int(lc->config,"sip","only_one_codec",0));
|
||||
sal_use_double_registrations(lc->sal,lp_config_get_int(lc->config,"sip","use_double_registrations",1));
|
||||
}
|
||||
|
||||
static void rtp_config_read(LinphoneCore *lc)
|
||||
|
|
@ -590,6 +595,8 @@ static void rtp_config_read(LinphoneCore *lc)
|
|||
jitt_comp=lp_config_get_int(lc->config,"rtp","audio_jitt_comp",60);
|
||||
linphone_core_set_audio_jittcomp(lc,jitt_comp);
|
||||
jitt_comp=lp_config_get_int(lc->config,"rtp","video_jitt_comp",60);
|
||||
if (jitt_comp==0) jitt_comp=60;
|
||||
lc->rtp_conf.video_jitt_comp=jitt_comp;
|
||||
nortp_timeout=lp_config_get_int(lc->config,"rtp","nortp_timeout",30);
|
||||
linphone_core_set_nortp_timeout(lc,nortp_timeout);
|
||||
rtp_no_xmit_on_audio_mute=lp_config_get_int(lc->config,"rtp","rtp_no_xmit_on_audio_mute",FALSE);
|
||||
|
|
@ -816,13 +823,6 @@ static void autoreplier_config_init(LinphoneCore *lc)
|
|||
*/
|
||||
void linphone_core_set_download_bandwidth(LinphoneCore *lc, int bw){
|
||||
lc->net_conf.download_bw=bw;
|
||||
if (bw==0){ /*infinite*/
|
||||
lc->dw_audio_bw=-1;
|
||||
lc->dw_video_bw=-1;
|
||||
}else {
|
||||
lc->dw_audio_bw=MIN(lc->audio_bw,bw);
|
||||
lc->dw_video_bw=MAX(bw-lc->dw_audio_bw-10,0);/*-10: security margin*/
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -840,13 +840,6 @@ void linphone_core_set_download_bandwidth(LinphoneCore *lc, int bw){
|
|||
*/
|
||||
void linphone_core_set_upload_bandwidth(LinphoneCore *lc, int bw){
|
||||
lc->net_conf.upload_bw=bw;
|
||||
if (bw==0){ /*infinite*/
|
||||
lc->up_audio_bw=-1;
|
||||
lc->up_video_bw=-1;
|
||||
}else{
|
||||
lc->up_audio_bw=MIN(lc->audio_bw,bw);
|
||||
lc->up_video_bw=MAX(bw-lc->up_audio_bw-10,0);/*-10: security margin*/
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -924,7 +917,8 @@ static void linphone_core_init (LinphoneCore * lc, const LinphoneCoreVTable *vta
|
|||
{
|
||||
memset (lc, 0, sizeof (LinphoneCore));
|
||||
lc->data=userdata;
|
||||
|
||||
lc->ringstream_autorelease=TRUE;
|
||||
|
||||
memcpy(&lc->vtable,vtable,sizeof(LinphoneCoreVTable));
|
||||
|
||||
linphone_core_set_state(lc,LinphoneGlobalStartup,"Starting up");
|
||||
|
|
@ -933,8 +927,8 @@ static void linphone_core_init (LinphoneCore * lc, const LinphoneCoreVTable *vta
|
|||
linphone_core_assign_payload_type(&payload_type_gsm,3,NULL);
|
||||
linphone_core_assign_payload_type(&payload_type_pcma8000,8,NULL);
|
||||
linphone_core_assign_payload_type(&payload_type_lpc1015,115,NULL);
|
||||
linphone_core_assign_payload_type(&payload_type_speex_nb,110,"vbr=vad");
|
||||
linphone_core_assign_payload_type(&payload_type_speex_wb,111,"vbr=vad");
|
||||
linphone_core_assign_payload_type(&payload_type_speex_nb,110,"vbr=on");
|
||||
linphone_core_assign_payload_type(&payload_type_speex_wb,111,"vbr=on");
|
||||
linphone_core_assign_payload_type(&payload_type_speex_uwb,112,"vbr=on");
|
||||
linphone_core_assign_payload_type(&payload_type_telephone_event,101,"0-11");
|
||||
linphone_core_assign_payload_type(&payload_type_ilbc,113,"mode=30");
|
||||
|
|
@ -968,8 +962,8 @@ static void linphone_core_init (LinphoneCore * lc, const LinphoneCoreVTable *vta
|
|||
linphone_core_assign_payload_type(&payload_type_h263_1998,98,"CIF=1;QCIF=1");
|
||||
linphone_core_assign_payload_type(&payload_type_mp4v,99,"profile-level-id=3");
|
||||
linphone_core_assign_payload_type(&payload_type_x_snow,100,NULL);
|
||||
linphone_core_assign_payload_type(&payload_type_h264,102,NULL);
|
||||
linphone_core_assign_payload_type(&payload_type_h264,103,"packetization-mode=1");
|
||||
linphone_core_assign_payload_type(&payload_type_h264,102,"profile-level-id=428014");
|
||||
linphone_core_assign_payload_type(&payload_type_h264,103,"packetization-mode=1;profile-level-id=428014");
|
||||
#endif
|
||||
|
||||
ms_init();
|
||||
|
|
@ -1630,9 +1624,9 @@ static void linphone_core_do_plugin_tasks(LinphoneCore *lc){
|
|||
* - handles timers and timeout
|
||||
* - performs registration to proxies
|
||||
* - authentication retries
|
||||
* The application MUST call this function from periodically, in its main loop.
|
||||
* Be careful that this function must be call from the same thread as
|
||||
* other liblinphone methods. In not the case make sure all liblinphone calls are
|
||||
* The application MUST call this function periodically, in its main loop.
|
||||
* Be careful that this function must be called from the same thread as
|
||||
* other liblinphone methods. If it is not the case make sure all liblinphone calls are
|
||||
* serialized with a mutex.
|
||||
**/
|
||||
void linphone_core_iterate(LinphoneCore *lc){
|
||||
|
|
@ -1649,6 +1643,19 @@ void linphone_core_iterate(LinphoneCore *lc){
|
|||
one_second_elapsed=TRUE;
|
||||
}
|
||||
|
||||
if (lc->ecc!=NULL){
|
||||
LinphoneEcCalibratorStatus ecs=ec_calibrator_get_status(lc->ecc);
|
||||
if (ecs!=LinphoneEcCalibratorInProgress){
|
||||
if (lc->ecc->cb)
|
||||
lc->ecc->cb(lc,ecs,lc->ecc->delay,lc->ecc->cb_data);
|
||||
if (ecs==LinphoneEcCalibratorDone){
|
||||
lp_config_set_int(lc->config, "sound", "ec_delay",MAX(lc->ecc->delay-10,0));
|
||||
}
|
||||
ec_calibrator_destroy(lc->ecc);
|
||||
lc->ecc=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (lc->preview_finished){
|
||||
lc->preview_finished=0;
|
||||
ring_stop(lc->ringstream);
|
||||
|
|
@ -1656,7 +1663,7 @@ void linphone_core_iterate(LinphoneCore *lc){
|
|||
lc_callback_obj_invoke(&lc->preview_finished_cb,lc);
|
||||
}
|
||||
|
||||
if (lc->ringstream && lc->dmfs_playing_start_time!=0
|
||||
if (lc->ringstream && lc->ringstream_autorelease && lc->dmfs_playing_start_time!=0
|
||||
&& (curtime-lc->dmfs_playing_start_time)>5){
|
||||
ring_stop(lc->ringstream);
|
||||
lc->ringstream=NULL;
|
||||
|
|
@ -1664,7 +1671,7 @@ void linphone_core_iterate(LinphoneCore *lc){
|
|||
}
|
||||
|
||||
sal_iterate(lc->sal);
|
||||
ms_event_queue_pump(lc->msevq);
|
||||
if (lc->msevq) ms_event_queue_pump(lc->msevq);
|
||||
if (lc->auto_net_state_mon) monitor_network_state(lc,curtime);
|
||||
|
||||
proxy_update(lc);
|
||||
|
|
@ -2169,31 +2176,43 @@ bool_t linphone_core_inc_invite_pending(LinphoneCore*lc){
|
|||
LinphoneCall *call = linphone_core_get_current_call(lc);
|
||||
if(call != NULL)
|
||||
{
|
||||
if(call->dir==LinphoneCallIncoming)
|
||||
if(call->dir==LinphoneCallIncoming
|
||||
&& (call->state == LinphoneCallIncomingReceived || call->state == LinphoneCallIncomingEarlyMedia))
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a running call according to supplied call parameters.
|
||||
* Updates a running call according to supplied call parameters or parameters changed in the LinphoneCore.
|
||||
*
|
||||
* For the moment, this is limited to enabling or disabling the video stream.
|
||||
* In this version this is limited to the following use cases:
|
||||
* - setting up/down the video stream according to the video parameter of the LinphoneCallParams (see linphone_call_params_enable_video() ).
|
||||
* - changing the size of the transmitted video after calling linphone_core_set_preferred_video_size()
|
||||
*
|
||||
* In case no changes are requested through the LinphoneCallParams argument, then this argument can be ommitted and set to NULL.
|
||||
*
|
||||
* @return 0 if successful, -1 otherwise.
|
||||
**/
|
||||
int linphone_core_update_call(LinphoneCore *lc, LinphoneCall *call, LinphoneCallParams *params){
|
||||
int err;
|
||||
|
||||
if (call->localdesc)
|
||||
sal_media_description_unref(call->localdesc);
|
||||
call->params=*params;
|
||||
call->localdesc=create_local_media_description (lc,call);
|
||||
call->camera_active=params->has_video;
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,_("Modifying call parameters..."));
|
||||
sal_call_set_local_media_description (call->op,call->localdesc);
|
||||
err=sal_call_update(call->op);
|
||||
int linphone_core_update_call(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params){
|
||||
int err=0;
|
||||
if (params!=NULL){
|
||||
call->params=*params;
|
||||
update_local_media_description(lc,call,&call->localdesc);
|
||||
call->camera_active=params->has_video;
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,_("Modifying call parameters..."));
|
||||
sal_call_set_local_media_description (call->op,call->localdesc);
|
||||
err=sal_call_update(call->op,"Media parameters update");
|
||||
}else{
|
||||
#ifdef VIDEO_ENABLED
|
||||
if (call->videostream!=NULL){
|
||||
video_stream_set_sent_video_size(call->videostream,linphone_core_get_preferred_video_size(lc));
|
||||
video_stream_update_video_params (call->videostream);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
@ -2213,7 +2232,7 @@ int linphone_core_update_call(LinphoneCore *lc, LinphoneCall *call, LinphoneCall
|
|||
**/
|
||||
int linphone_core_accept_call(LinphoneCore *lc, LinphoneCall *call)
|
||||
{
|
||||
LinphoneProxyConfig *cfg=NULL;
|
||||
LinphoneProxyConfig *cfg=NULL,*dest_proxy=NULL;
|
||||
const char *contact=NULL;
|
||||
SalOp *replaced;
|
||||
SalMediaDescription *new_md;
|
||||
|
|
@ -2268,8 +2287,15 @@ int linphone_core_accept_call(LinphoneCore *lc, LinphoneCall *call)
|
|||
}
|
||||
|
||||
linphone_core_get_default_proxy(lc,&cfg);
|
||||
dest_proxy=cfg;
|
||||
dest_proxy=linphone_core_lookup_known_proxy(lc,call->log->to);
|
||||
|
||||
if (cfg!=dest_proxy && dest_proxy!=NULL) {
|
||||
ms_message("Overriding default proxy setting for this call:");
|
||||
ms_message("The used identity will be %s",linphone_proxy_config_get_identity(dest_proxy));
|
||||
}
|
||||
/*try to be best-effort in giving real local or routable contact address*/
|
||||
contact=get_fixed_contact(lc,call,cfg);
|
||||
contact=get_fixed_contact(lc,call,dest_proxy);
|
||||
if (contact)
|
||||
sal_op_set_contact(call->op,contact);
|
||||
|
||||
|
|
@ -2404,13 +2430,23 @@ LinphoneCall *linphone_core_get_current_call(const LinphoneCore *lc)
|
|||
int linphone_core_pause_call(LinphoneCore *lc, LinphoneCall *the_call)
|
||||
{
|
||||
LinphoneCall *call = the_call;
|
||||
const char *subject=NULL;
|
||||
|
||||
if (call->state!=LinphoneCallStreamsRunning && call->state!=LinphoneCallPausedByRemote){
|
||||
ms_warning("Cannot pause this call, it is not active.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sal_call_hold(call->op,TRUE) != 0)
|
||||
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;
|
||||
}
|
||||
if (sal_call_update(call->op,subject) != 0)
|
||||
{
|
||||
if (lc->vtable.display_warning)
|
||||
lc->vtable.display_warning(lc,_("Could not pause the call"));
|
||||
|
|
@ -2460,14 +2496,14 @@ int linphone_core_resume_call(LinphoneCore *lc, LinphoneCall *the_call)
|
|||
return -1;
|
||||
}
|
||||
ms_message("Resuming call %p",call);
|
||||
if(sal_call_hold(call->op,FALSE) != 0){
|
||||
sal_media_description_set_dir(call->localdesc,SalStreamSendRecv);
|
||||
if(sal_call_update(call->op,"Call resuming") != 0){
|
||||
return -1;
|
||||
}
|
||||
linphone_call_set_state (call,LinphoneCallResuming,"Resuming");
|
||||
snprintf(temp,sizeof(temp)-1,"Resuming the call with %s",linphone_call_get_remote_address_as_string(call));
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,temp);
|
||||
lc->current_call=call;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -2828,8 +2864,10 @@ void linphone_core_set_sound_source(LinphoneCore *lc, char source)
|
|||
void linphone_core_set_ring(LinphoneCore *lc,const char *path){
|
||||
if (lc->sound_conf.local_ring!=0){
|
||||
ms_free(lc->sound_conf.local_ring);
|
||||
lc->sound_conf.local_ring=NULL;
|
||||
}
|
||||
lc->sound_conf.local_ring=ms_strdup(path);
|
||||
if (path)
|
||||
lc->sound_conf.local_ring=ms_strdup(path);
|
||||
if ( linphone_core_ready(lc) && lc->sound_conf.local_ring)
|
||||
lp_config_set_string(lc->config,"sound","local_ring",lc->sound_conf.local_ring);
|
||||
}
|
||||
|
|
@ -2843,7 +2881,7 @@ const char *linphone_core_get_ring(const LinphoneCore *lc){
|
|||
return lc->sound_conf.local_ring;
|
||||
}
|
||||
|
||||
static void notify_end_of_ring(void *ud ,unsigned int event, void * arg){
|
||||
static void notify_end_of_ring(void *ud, MSFilter *f, unsigned int event, void *arg){
|
||||
LinphoneCore *lc=(LinphoneCore*)ud;
|
||||
lc->preview_finished=1;
|
||||
}
|
||||
|
|
@ -2888,7 +2926,7 @@ const char * linphone_core_get_ringback(const LinphoneCore *lc){
|
|||
}
|
||||
|
||||
/**
|
||||
* Enables or disable echo cancellation.
|
||||
* Enables or disable echo cancellation. Value is saved an used for subsequent calls
|
||||
*
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
|
|
@ -2898,6 +2936,7 @@ void linphone_core_enable_echo_cancellation(LinphoneCore *lc, bool_t val){
|
|||
lp_config_set_int(lc->config,"sound","echocancellation",val);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns TRUE if echo cancellation is enabled.
|
||||
*
|
||||
|
|
@ -3363,12 +3402,18 @@ void linphone_core_use_preview_window(LinphoneCore *lc, bool_t yesno){
|
|||
}
|
||||
|
||||
static MSVideoSizeDef supported_resolutions[]={
|
||||
#ifdef ENABLE_HD
|
||||
{ {MS_VIDEO_SIZE_1080P_W,MS_VIDEO_SIZE_1080P_H} , "1080p" },
|
||||
{ {MS_VIDEO_SIZE_720P_W,MS_VIDEO_SIZE_720P_H} , "1080p" },
|
||||
#endif
|
||||
{ {MS_VIDEO_SIZE_SVGA_W,MS_VIDEO_SIZE_SVGA_H} , "svga" },
|
||||
{ {MS_VIDEO_SIZE_4CIF_W,MS_VIDEO_SIZE_4CIF_H} , "4cif" },
|
||||
{ {MS_VIDEO_SIZE_VGA_W,MS_VIDEO_SIZE_VGA_H} , "vga" },
|
||||
{ {MS_VIDEO_SIZE_CIF_W,MS_VIDEO_SIZE_CIF_H} , "cif" },
|
||||
{ {MS_VIDEO_SIZE_QVGA_W,MS_VIDEO_SIZE_QVGA_H} , "qvga" },
|
||||
{ {MS_VIDEO_SIZE_QVGA_H,MS_VIDEO_SIZE_QVGA_W} , "qvga-portrait" },
|
||||
{ {MS_VIDEO_SIZE_QCIF_W,MS_VIDEO_SIZE_QCIF_H} , "qcif" },
|
||||
{ {MS_VIDEO_SIZE_QCIF_H,MS_VIDEO_SIZE_QCIF_W} , "qcif-portrait" },
|
||||
{ {0,0} , NULL }
|
||||
};
|
||||
|
||||
|
|
@ -3509,8 +3554,10 @@ static MSFilter *get_dtmf_gen(LinphoneCore *lc){
|
|||
}
|
||||
}
|
||||
if (lc->ringstream==NULL){
|
||||
float amp=0.1;
|
||||
MSSndCard *ringcard=lc->sound_conf.lsd_card ?lc->sound_conf.lsd_card : lc->sound_conf.ring_sndcard;
|
||||
lc->ringstream=ring_start(NULL,0,ringcard);
|
||||
ms_filter_call_method(lc->ringstream->gendtmf,MS_DTMF_GEN_SET_DEFAULT_AMPLITUDE,&);
|
||||
lc->dmfs_playing_start_time=time(NULL);
|
||||
}else{
|
||||
if (lc->dmfs_playing_start_time!=0)
|
||||
|
|
@ -3667,17 +3714,16 @@ void sip_config_uninit(LinphoneCore *lc)
|
|||
linphone_proxy_config_write_to_config_file(lc->config,cfg,i);
|
||||
linphone_proxy_config_edit(cfg); /* to unregister */
|
||||
}
|
||||
/*to ensure remove configs are erased:*/
|
||||
linphone_proxy_config_write_to_config_file(lc->config,NULL,i);
|
||||
|
||||
if (lc->sal){
|
||||
int i;
|
||||
for (i=0;i<20;i++){
|
||||
sal_iterate(lc->sal);
|
||||
for (i=0;i<20;i++){
|
||||
sal_iterate(lc->sal);
|
||||
#ifndef WIN32
|
||||
usleep(100000);
|
||||
usleep(100000);
|
||||
#else
|
||||
Sleep(100);
|
||||
Sleep(100);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
ms_list_for_each(config->proxies,(void (*)(void*)) linphone_proxy_config_destroy);
|
||||
|
|
@ -3809,7 +3855,6 @@ static void linphone_core_uninit(LinphoneCore *lc)
|
|||
usleep(50000);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (lc->friends)
|
||||
ms_list_for_each(lc->friends,(void (*)(void *))linphone_friend_close_subscriptions);
|
||||
linphone_core_set_state(lc,LinphoneGlobalShutdown,"Shutting down");
|
||||
|
|
@ -3820,14 +3865,16 @@ static void linphone_core_uninit(LinphoneCore *lc)
|
|||
}
|
||||
#endif
|
||||
ms_event_queue_destroy(lc->msevq);
|
||||
lc->msevq=NULL;
|
||||
/* save all config */
|
||||
net_config_uninit(lc);
|
||||
sip_config_uninit(lc);
|
||||
rtp_config_uninit(lc);
|
||||
if (lc->ringstream) ring_stop(lc->ringstream);
|
||||
sound_config_uninit(lc);
|
||||
video_config_uninit(lc);
|
||||
codecs_config_uninit(lc);
|
||||
ui_config_uninit(lc);
|
||||
sip_config_uninit(lc);
|
||||
if (lp_config_needs_commit(lc->config)) lp_config_sync(lc->config);
|
||||
lp_config_destroy(lc->config);
|
||||
lc->config = NULL; /* Mark the config as NULL to block further calls */
|
||||
|
|
@ -3837,7 +3884,6 @@ static void linphone_core_uninit(LinphoneCore *lc)
|
|||
lc->call_logs=ms_list_free(lc->call_logs);
|
||||
|
||||
linphone_core_free_payload_types();
|
||||
|
||||
ortp_exit();
|
||||
linphone_core_set_state(lc,LinphoneGlobalOff,"Off");
|
||||
}
|
||||
|
|
@ -3959,7 +4005,7 @@ static PayloadType* find_payload_type_from_list(const char* type, int rate,const
|
|||
const MSList *elem;
|
||||
for(elem=from;elem!=NULL;elem=elem->next){
|
||||
PayloadType *pt=(PayloadType*)elem->data;
|
||||
if ((strcmp((char*)type, payload_type_get_mime(pt)) == 0) && rate==pt->clock_rate) {
|
||||
if ((strcmp((char*)type, payload_type_get_mime(pt)) == 0) && (rate == -1 || rate==pt->clock_rate)) {
|
||||
return pt;
|
||||
}
|
||||
}
|
||||
|
|
@ -4027,4 +4073,31 @@ const char *linphone_error_to_string(LinphoneReason err){
|
|||
}
|
||||
return "unknown error";
|
||||
}
|
||||
/**
|
||||
* enable signaling keep alive
|
||||
*/
|
||||
void linphone_core_enable_keep_alive(LinphoneCore* lc,bool_t enable) {
|
||||
if (enable > 0) {
|
||||
sal_set_keepalive_period(lc->sal,lc->sip_conf.keepalive_period);
|
||||
} else {
|
||||
sal_set_keepalive_period(lc->sal,0);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Is signaling keep alive
|
||||
*/
|
||||
bool_t linphone_core_keep_alive_enabled(LinphoneCore* lc) {
|
||||
return sal_get_keepalive_period(lc->sal) > 0;
|
||||
}
|
||||
|
||||
void linphone_core_start_dtmf_stream(LinphoneCore* lc) {
|
||||
get_dtmf_gen(lc); /*make sure ring stream is started*/
|
||||
lc->ringstream_autorelease=FALSE; /*disable autorelease mode*/
|
||||
}
|
||||
|
||||
void linphone_core_stop_dtmf_stream(LinphoneCore* lc) {
|
||||
if (lc->ringstream) ring_stop(lc->ringstream);
|
||||
lc->ringstream=NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -185,6 +185,7 @@ void linphone_call_params_destroy(LinphoneCallParams *cp);
|
|||
|
||||
/**
|
||||
* Enum describing failure reasons.
|
||||
* @ingroup initializing
|
||||
**/
|
||||
enum _LinphoneReason{
|
||||
LinphoneReasonNone,
|
||||
|
|
@ -203,8 +204,13 @@ const char *linphone_reason_to_string(LinphoneReason err);
|
|||
struct _LinphoneCall;
|
||||
typedef struct _LinphoneCall LinphoneCall;
|
||||
|
||||
/**
|
||||
* LinphoneCallState enum represents the different state a call can reach into.
|
||||
* The application is notified of state changes through the LinphoneCoreVTable::call_state_changed callback.
|
||||
* @ingroup call_control
|
||||
**/
|
||||
typedef enum _LinphoneCallState{
|
||||
LinphoneCallIdle,
|
||||
LinphoneCallIdle, /**<Initial call state */
|
||||
LinphoneCallIncomingReceived, /**<This is a new incoming call */
|
||||
LinphoneCallOutgoingInit, /**<An outgoing call is started */
|
||||
LinphoneCallOutgoingProgress, /**<An outgoing call is in progress */
|
||||
|
|
@ -221,7 +227,8 @@ typedef enum _LinphoneCallState{
|
|||
LinphoneCallPausedByRemote, /**<The call is paused by remote end*/
|
||||
LinphoneCallUpdatedByRemote, /**<The call's parameters are updated, used for example when video is asked by remote */
|
||||
LinphoneCallIncomingEarlyMedia, /**<We are proposing early media to an incoming call */
|
||||
LinphoneCallUpdated /**<The remote accepted the call update initiated by us */
|
||||
LinphoneCallUpdated, /**<The remote accepted the call update initiated by us */
|
||||
LinphoneCallReleased /**< The call object is no more retained by the core */
|
||||
} LinphoneCallState;
|
||||
|
||||
const char *linphone_call_state_to_string(LinphoneCallState cs);
|
||||
|
|
@ -238,6 +245,7 @@ void linphone_call_unref(LinphoneCall *call);
|
|||
LinphoneCallLog *linphone_call_get_call_log(const LinphoneCall *call);
|
||||
const char *linphone_call_get_refer_to(const LinphoneCall *call);
|
||||
bool_t linphone_call_has_transfer_pending(const LinphoneCall *call);
|
||||
LinphoneCall *linphone_call_get_replaced_call(LinphoneCall *call);
|
||||
int linphone_call_get_duration(const LinphoneCall *call);
|
||||
const LinphoneCallParams * linphone_call_get_current_params(const LinphoneCall *call);
|
||||
void linphone_call_enable_camera(LinphoneCall *lc, bool_t enabled);
|
||||
|
|
@ -247,8 +255,34 @@ LinphoneReason linphone_call_get_reason(const LinphoneCall *call);
|
|||
const char *linphone_call_get_remote_user_agent(LinphoneCall *call);
|
||||
void *linphone_call_get_user_pointer(LinphoneCall *call);
|
||||
void linphone_call_set_user_pointer(LinphoneCall *call, void *user_pointer);
|
||||
|
||||
|
||||
/**
|
||||
* Enables or disable echo cancellation for this call
|
||||
* @param call
|
||||
* @param val
|
||||
*
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
void linphone_call_enable_echo_cancellation(LinphoneCall *call, bool_t val) ;
|
||||
/**
|
||||
* Returns TRUE if echo cancellation is enabled.
|
||||
*
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
bool_t linphone_call_echo_cancellation_enabled(LinphoneCall *lc);
|
||||
/**
|
||||
* Enables or disable echo limiter for this call
|
||||
* @param call
|
||||
* @param val
|
||||
*
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
void linphone_call_enable_echo_limiter(LinphoneCall *call, bool_t val);
|
||||
/**
|
||||
* Returns TRUE if echo limiter is enabled.
|
||||
*
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
bool_t linphone_call_echo_limiter_enabled(const LinphoneCall *call);
|
||||
/**
|
||||
* @addtogroup proxies
|
||||
* @{
|
||||
|
|
@ -275,11 +309,11 @@ typedef struct _LinphoneProxyConfig LinphoneProxyConfig;
|
|||
* LinphoneRegistrationState describes proxy registration states.
|
||||
**/
|
||||
typedef enum _LinphoneRegistrationState{
|
||||
LinphoneRegistrationNone,
|
||||
LinphoneRegistrationProgress,
|
||||
LinphoneRegistrationOk,
|
||||
LinphoneRegistrationCleared,
|
||||
LinphoneRegistrationFailed
|
||||
LinphoneRegistrationNone, /**<Initial state for registrations */
|
||||
LinphoneRegistrationProgress, /**<Registration is in progress */
|
||||
LinphoneRegistrationOk, /**< Registration is successful */
|
||||
LinphoneRegistrationCleared, /**< Unregistration succeeded */
|
||||
LinphoneRegistrationFailed /**<Registration failed */
|
||||
}LinphoneRegistrationState;
|
||||
|
||||
/**
|
||||
|
|
@ -303,6 +337,13 @@ void linphone_proxy_config_enable_register(LinphoneProxyConfig *obj, bool_t val)
|
|||
#define linphone_proxy_config_enableregister linphone_proxy_config_enable_register
|
||||
void linphone_proxy_config_edit(LinphoneProxyConfig *obj);
|
||||
int linphone_proxy_config_done(LinphoneProxyConfig *obj);
|
||||
/**
|
||||
* Indicates either or not, PUBLISH must be issued for this #LinphoneProxyConfig .
|
||||
* <br> In case this #LinphoneProxyConfig has been added to #LinphoneCore, follows the linphone_proxy_config_edit() rule.
|
||||
* @param obj object pointer
|
||||
* @param val if true, publish will be engaged
|
||||
*
|
||||
*/
|
||||
void linphone_proxy_config_enable_publish(LinphoneProxyConfig *obj, bool_t val);
|
||||
void linphone_proxy_config_set_dial_escape_plus(LinphoneProxyConfig *cfg, bool_t val);
|
||||
void linphone_proxy_config_set_dial_prefix(LinphoneProxyConfig *cfg, const char *prefix);
|
||||
|
|
@ -451,6 +492,17 @@ void * linphone_chat_room_get_user_data(LinphoneChatRoom *cr);
|
|||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @addtogroup initializing
|
||||
* @{
|
||||
**/
|
||||
|
||||
/**
|
||||
* LinphoneGlobalState describes the global state of the LinphoneCore object.
|
||||
* It is notified via the LinphoneCoreVTable::global_state_changed
|
||||
**/
|
||||
typedef enum _LinphoneGlobalState{
|
||||
LinphoneGlobalOff,
|
||||
LinphoneGlobalStartup,
|
||||
|
|
@ -460,11 +512,6 @@ typedef enum _LinphoneGlobalState{
|
|||
|
||||
const char *linphone_global_state_to_string(LinphoneGlobalState gs);
|
||||
|
||||
/**
|
||||
* @addtogroup initializing
|
||||
* @{
|
||||
**/
|
||||
|
||||
|
||||
/**Call state notification callback prototype*/
|
||||
typedef void (*LinphoneGlobalStateCb)(struct _LinphoneCore *lc, LinphoneGlobalState gstate, const char *message);
|
||||
|
|
@ -618,7 +665,7 @@ int linphone_core_pause_all_calls(LinphoneCore *lc);
|
|||
|
||||
int linphone_core_resume_call(LinphoneCore *lc, LinphoneCall *call);
|
||||
|
||||
int linphone_core_update_call(LinphoneCore *lc, LinphoneCall *call, LinphoneCallParams *params);
|
||||
int linphone_core_update_call(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params);
|
||||
|
||||
LinphoneCallParams *linphone_core_create_default_call_parameters(LinphoneCore *lc);
|
||||
|
||||
|
|
@ -886,6 +933,14 @@ void linphone_core_set_network_reachable(LinphoneCore* lc,bool_t value);
|
|||
*/
|
||||
bool_t linphone_core_is_network_reachabled(LinphoneCore* lc);
|
||||
|
||||
/**
|
||||
* enable signaling keep alive. small udp packet sent periodically to keep udp NAT association
|
||||
*/
|
||||
void linphone_core_enable_keep_alive(LinphoneCore* lc,bool_t enable);
|
||||
/**
|
||||
* Is signaling keep alive
|
||||
*/
|
||||
bool_t linphone_core_keep_alive_enabled(LinphoneCore* lc);
|
||||
|
||||
void *linphone_core_get_user_data(LinphoneCore *lc);
|
||||
|
||||
|
|
@ -922,6 +977,6 @@ LinphoneGlobalState linphone_core_get_global_state(const LinphoneCore *lc);
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
void linphone_call_send_vfu_request(LinphoneCall *call);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -17,15 +17,16 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include <jni.h>
|
||||
#include "linphonecore.h"
|
||||
#include "linphonecore_utils.h"
|
||||
|
||||
#include "mediastreamer2/msjava.h"
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <android/log.h>
|
||||
extern "C" void libmsilbc_init();
|
||||
extern "C" void libmsx264_init();
|
||||
#endif /*ANDROID*/
|
||||
|
||||
extern "C" void ms_andsnd_set_jvm(JavaVM *jvm) ;
|
||||
extern "C" void ms_andvid_set_jvm(JavaVM *jvm) ;
|
||||
|
||||
static JavaVM *jvm=0;
|
||||
|
||||
#ifdef ANDROID
|
||||
|
|
@ -46,10 +47,7 @@ static void linphone_android_log_handler(OrtpLogLevel lev, const char *fmt, va_l
|
|||
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *ajvm, void *reserved)
|
||||
{
|
||||
#ifdef ANDROID
|
||||
ms_andsnd_set_jvm(ajvm);
|
||||
#ifdef VIDEO_ENABLED
|
||||
ms_andvid_set_jvm(ajvm);
|
||||
#endif /*VIDEO_ENABLED*/
|
||||
ms_set_jvm(ajvm);
|
||||
#endif /*ANDROID*/
|
||||
jvm=ajvm;
|
||||
return JNI_VERSION_1_2;
|
||||
|
|
@ -103,7 +101,10 @@ public:
|
|||
callStateId = env->GetMethodID(listernerClass,"callState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;Lorg/linphone/core/LinphoneCall$State;Ljava/lang/String;)V");
|
||||
callStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCall$State"));
|
||||
callStateFromIntId = env->GetStaticMethodID(callStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCall$State;");
|
||||
|
||||
/*void ecCalibrationStatus(LinphoneCore.EcCalibratorStatus status, int delay_ms, Object data);*/
|
||||
ecCalibrationStatusId = env->GetMethodID(listernerClass,"ecCalibrationStatus","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCore$EcCalibratorStatus;ILjava/lang/Object;)V");
|
||||
ecCalibratorStatusClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$EcCalibratorStatus"));
|
||||
ecCalibratorStatusFromIntId = env->GetStaticMethodID(ecCalibratorStatusClass,"fromInt","(I)Lorg/linphone/core/LinphoneCore$EcCalibratorStatus;");
|
||||
/*void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf, String url)*/
|
||||
newSubscriptionRequestId = env->GetMethodID(listernerClass,"newSubscriptionRequest","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneFriend;Ljava/lang/String;)V");
|
||||
|
||||
|
|
@ -168,6 +169,10 @@ public:
|
|||
jmethodID callStateId;
|
||||
jmethodID callStateFromIntId;
|
||||
|
||||
jclass ecCalibratorStatusClass;
|
||||
jmethodID ecCalibrationStatusId;
|
||||
jmethodID ecCalibratorStatusFromIntId;
|
||||
|
||||
jclass proxyClass;
|
||||
jmethodID proxyCtrId;
|
||||
|
||||
|
|
@ -293,6 +298,26 @@ public:
|
|||
,env->NewObject(lcData->addressClass,lcData->addressCtrId,(jlong)from)
|
||||
,message ? env->NewStringUTF(message) : NULL);
|
||||
}
|
||||
static void ecCalibrationStatus(LinphoneCore *lc, LinphoneEcCalibratorStatus status, int delay_ms, void *data) {
|
||||
JNIEnv *env = 0;
|
||||
jint result = jvm->AttachCurrentThread(&env,NULL);
|
||||
if (result != 0) {
|
||||
ms_error("cannot attach VM\n");
|
||||
return;
|
||||
}
|
||||
LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_get_user_data(lc);
|
||||
env->CallVoidMethod(lcData->listener
|
||||
,lcData->ecCalibrationStatusId
|
||||
,lcData->core
|
||||
,env->CallStaticObjectMethod(lcData->ecCalibratorStatusClass,lcData->ecCalibratorStatusFromIntId,(jint)status)
|
||||
,delay_ms
|
||||
,data ? data : NULL);
|
||||
if (data != NULL &&status !=LinphoneEcCalibratorInProgress ) {
|
||||
//final state, releasing global ref
|
||||
env->DeleteGlobalRef((jobject)data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
|
@ -306,12 +331,12 @@ extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_newLinphoneCore(JNIEnv*
|
|||
const char* userConfig = juserConfig?env->GetStringUTFChars(juserConfig, NULL):NULL;
|
||||
const char* factoryConfig = jfactoryConfig?env->GetStringUTFChars(jfactoryConfig, NULL):NULL;
|
||||
LinphoneCoreData* ldata = new LinphoneCoreData(env,thiz,jlistener,juserdata);
|
||||
#ifdef ANDROID
|
||||
ms_andsnd_set_jvm(jvm);
|
||||
#endif /*ANDROID*/
|
||||
|
||||
#ifdef HAVE_ILBC
|
||||
libmsilbc_init(); // requires an fpu
|
||||
#endif
|
||||
#ifdef VIDEO_ENABLED
|
||||
libmsx264_init();
|
||||
#endif
|
||||
jlong nativePtr = (jlong)linphone_core_new( &ldata->vTable
|
||||
,userConfig
|
||||
|
|
@ -512,6 +537,24 @@ extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_findPayloadType(JNIEnv*
|
|||
env->ReleaseStringUTFChars(jmime, mime);
|
||||
return result;
|
||||
}
|
||||
extern "C" jlongArray Java_org_linphone_core_LinphoneCoreImpl_listVideoPayloadTypes(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc) {
|
||||
const MSList* codecs = linphone_core_get_video_codecs((LinphoneCore*)lc);
|
||||
int codecsCount = ms_list_size(codecs);
|
||||
jlongArray jCodecs = env->NewLongArray(codecsCount);
|
||||
jlong *jInternalArray = env->GetLongArrayElements(jCodecs, NULL);
|
||||
|
||||
for (int i = 0; i < codecsCount; i++ ) {
|
||||
jInternalArray[i] = (unsigned long) (codecs->data);
|
||||
codecs = codecs->next;
|
||||
}
|
||||
|
||||
env->ReleaseLongArrayElements(jCodecs, jInternalArray, 0);
|
||||
|
||||
return jCodecs;
|
||||
}
|
||||
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_enablePayloadType(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc
|
||||
|
|
@ -599,6 +642,29 @@ extern "C" jstring Java_org_linphone_core_LinphoneCoreImpl_getRing(JNIEnv* env
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_enableKeepAlive(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc
|
||||
,jboolean enable) {
|
||||
linphone_core_enable_keep_alive((LinphoneCore*)lc,enable);
|
||||
|
||||
}
|
||||
extern "C" jboolean Java_org_linphone_core_LinphoneCoreImpl_isKeepAliveEnabled(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc) {
|
||||
return linphone_core_keep_alive_enabled((LinphoneCore*)lc);
|
||||
|
||||
}
|
||||
extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_startEchoCalibration(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong lc
|
||||
,jobject data) {
|
||||
return linphone_core_start_echo_calibration((LinphoneCore*)lc
|
||||
, LinphoneCoreData::ecCalibrationStatus
|
||||
, data?env->NewGlobalRef(data):NULL);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//ProxyConfig
|
||||
|
|
@ -710,7 +776,15 @@ extern "C" void Java_org_linphone_core_LinphoneProxyConfigImpl_setDialPrefix(JNI
|
|||
linphone_proxy_config_set_dial_prefix((LinphoneProxyConfig*)proxyCfg,prefix);
|
||||
env->ReleaseStringUTFChars(jprefix, prefix);
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneProxyConfigImpl_enablePublish(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong proxyCfg
|
||||
,jboolean val) {
|
||||
linphone_proxy_config_enable_publish((LinphoneProxyConfig*)proxyCfg,val);
|
||||
}
|
||||
extern "C" jboolean Java_org_linphone_core_LinphoneProxyConfigImpl_publishEnabled(JNIEnv* env,jobject thiz,jlong proxyCfg) {
|
||||
return linphone_proxy_config_publish_enabled((LinphoneProxyConfig*)proxyCfg);
|
||||
}
|
||||
|
||||
//Auth Info
|
||||
|
||||
|
|
@ -834,12 +908,10 @@ extern "C" jboolean Java_org_linphone_core_LinphoneCallLogImpl_isIncoming(JNIEnv
|
|||
return ((LinphoneCallLog*)ptr)->dir==LinphoneCallIncoming?JNI_TRUE:JNI_FALSE;
|
||||
}
|
||||
|
||||
extern "C" jstring Java_org_linphone_core_PayloadTypeImpl_toString(JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr) {
|
||||
|
||||
/*payloadType*/
|
||||
extern "C" jstring Java_org_linphone_core_PayloadTypeImpl_toString(JNIEnv* env,jobject thiz,jlong ptr) {
|
||||
PayloadType* pt = (PayloadType*)ptr;
|
||||
char* value = ms_strdup_printf("[%s] clock [%s], bitrate [%s]"
|
||||
char* value = ms_strdup_printf("[%s] clock [%i], bitrate [%i]"
|
||||
,payload_type_get_mime(pt)
|
||||
,payload_type_get_rate(pt)
|
||||
,payload_type_get_bitrate(pt));
|
||||
|
|
@ -847,6 +919,16 @@ extern "C" jstring Java_org_linphone_core_PayloadTypeImpl_toString(JNIEnv* env
|
|||
ms_free(value);
|
||||
return jvalue;
|
||||
}
|
||||
extern "C" jstring Java_org_linphone_core_PayloadTypeImpl_getMime(JNIEnv* env,jobject thiz,jlong ptr) {
|
||||
PayloadType* pt = (PayloadType*)ptr;
|
||||
jstring jvalue =env->NewStringUTF(payload_type_get_mime(pt));
|
||||
return jvalue;
|
||||
}
|
||||
extern "C" jint Java_org_linphone_core_PayloadTypeImpl_getRate(JNIEnv* env,jobject thiz, jlong ptr) {
|
||||
PayloadType* pt = (PayloadType*)ptr;
|
||||
return payload_type_get_rate(pt);
|
||||
}
|
||||
|
||||
//LinphoneCall
|
||||
extern "C" void Java_org_linphone_core_LinphoneCallImpl_ref(JNIEnv* env
|
||||
,jobject thiz
|
||||
|
|
@ -883,6 +965,36 @@ extern "C" jint Java_org_linphone_core_LinphoneCallImpl_getState( JNIEnv* env
|
|||
,jlong ptr) {
|
||||
return (jint)linphone_call_get_state((LinphoneCall*)ptr);
|
||||
}
|
||||
extern "C" void Java_org_linphone_core_LinphoneCallImpl_enableEchoCancellation( JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr
|
||||
,jboolean value) {
|
||||
linphone_call_enable_echo_cancellation((LinphoneCall*)ptr,value);
|
||||
}
|
||||
extern "C" jboolean Java_org_linphone_core_LinphoneCallImpl_isEchoCancellationEnabled( JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr) {
|
||||
return linphone_call_echo_cancellation_enabled((LinphoneCall*)ptr);
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneCallImpl_enableEchoLimiter( JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr
|
||||
,jboolean value) {
|
||||
linphone_call_enable_echo_limiter((LinphoneCall*)ptr,value);
|
||||
}
|
||||
extern "C" jboolean Java_org_linphone_core_LinphoneCallImpl_isEchoLimiterEnabled( JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr) {
|
||||
return linphone_call_echo_limiter_enabled((LinphoneCall*)ptr);
|
||||
}
|
||||
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneCallImpl_getReplacedCall( JNIEnv* env
|
||||
,jobject thiz
|
||||
,jlong ptr) {
|
||||
return (jlong)linphone_call_get_replaced_call((LinphoneCall*)ptr);
|
||||
}
|
||||
|
||||
|
||||
//LinphoneFriend
|
||||
extern "C" long Java_org_linphone_core_LinphoneFriendImpl_newLinphoneFriend(JNIEnv* env
|
||||
|
|
@ -993,6 +1105,10 @@ extern "C" jstring Java_org_linphone_core_LinphoneCoreImpl_getStunServer(JNIEnv
|
|||
return jvalue;
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneCallParamsImpl_audioBandwidth(JNIEnv *env, jobject thiz, jlong lcp, jint bw){
|
||||
linphone_call_params_set_audio_bandwidth_limit((LinphoneCallParams*)lcp, bw);
|
||||
}
|
||||
|
||||
extern "C" void Java_org_linphone_core_LinphoneCallParamsImpl_enableVideo(JNIEnv *env, jobject thiz, jlong lcp, jboolean b){
|
||||
linphone_call_params_enable_video((LinphoneCallParams*)lcp, b);
|
||||
}
|
||||
|
|
@ -1000,15 +1116,19 @@ extern "C" void Java_org_linphone_core_LinphoneCallParamsImpl_enableVideo(JNIEnv
|
|||
extern "C" jboolean Java_org_linphone_core_LinphoneCallParamsImpl_getVideoEnabled(JNIEnv *env, jobject thiz, jlong lcp){
|
||||
return linphone_call_params_video_enabled((LinphoneCallParams*)lcp);
|
||||
}
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneCallParamsImpl_copy(JNIEnv *env, jobject thiz, jlong lcp){
|
||||
return (jlong) linphone_call_params_copy((LinphoneCallParams*)lcp);
|
||||
extern "C" void Java_org_linphone_core_LinphoneCallParamsImpl_destroy(JNIEnv *env, jobject thiz, jlong lc){
|
||||
return linphone_call_params_destroy((LinphoneCallParams*)lc);
|
||||
}
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_createDefaultCallParams(JNIEnv *env, jobject thiz, jlong lc){
|
||||
return (jlong) linphone_core_create_default_call_parameters((LinphoneCore*)lc);
|
||||
}
|
||||
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneCallImpl_getCurrentParams(JNIEnv *env, jobject thiz, jlong lc){
|
||||
return (jlong) linphone_call_get_current_params((LinphoneCall*)lc);
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneCallImpl_getCurrentParamsCopy(JNIEnv *env, jobject thiz, jlong lc){
|
||||
return (jlong) linphone_call_params_copy(linphone_call_get_current_params((LinphoneCall*)lc));
|
||||
}
|
||||
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneCallImpl_enableCamera(JNIEnv *env, jobject thiz, jlong lc, jboolean b){
|
||||
linphone_call_enable_camera((LinphoneCall *)lc, (bool_t) b);
|
||||
}
|
||||
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_inviteAddressWithParams(JNIEnv *env, jobject thiz, jlong lc, jlong addr, jlong params){
|
||||
|
|
@ -1020,7 +1140,7 @@ extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_updateAddressWithParams(
|
|||
}
|
||||
|
||||
extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_updateCall(JNIEnv *env, jobject thiz, jlong lc, jlong call, jlong params){
|
||||
return (jint) linphone_core_update_call((LinphoneCore *)lc, (LinphoneCall *)call, (LinphoneCallParams *)params);
|
||||
return (jint) linphone_core_update_call((LinphoneCore *)lc, (LinphoneCall *)call, (const LinphoneCallParams *)params);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1046,4 +1166,10 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setDownloadBandwidth(JNI
|
|||
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setUploadBandwidth(JNIEnv *env, jobject thiz, jlong lc, jint bw){
|
||||
linphone_core_set_upload_bandwidth((LinphoneCore *)lc, (int) bw);
|
||||
}
|
||||
extern "C" int Java_org_linphone_core_LinphoneProxyConfigImpl_getState(JNIEnv* env,jobject thiz,jlong ptr) {
|
||||
return (int) linphone_proxy_config_get_state((const LinphoneProxyConfig *) ptr);
|
||||
}
|
||||
extern "C" void Java_org_linphone_core_LinphoneProxyConfigImpl_setExpires(JNIEnv* env,jobject thiz,jlong ptr,jint delay) {
|
||||
linphone_proxy_config_expires((LinphoneProxyConfig *) ptr, (int) delay);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#else
|
||||
#include "linphone/linphonecore.h"
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct _LsdPlayer LsdPlayer;
|
||||
typedef struct _LinphoneSoundDaemon LinphoneSoundDaemon;
|
||||
|
|
@ -49,4 +52,35 @@ void linphone_sound_daemon_release_all_players(LinphoneSoundDaemon *obj);
|
|||
void linphone_core_use_sound_daemon(LinphoneCore *lc, LinphoneSoundDaemon *lsd);
|
||||
void linphone_sound_daemon_destroy(LinphoneSoundDaemon *obj);
|
||||
|
||||
/**
|
||||
* Enum describing the result of the echo canceller calibration process.
|
||||
**/
|
||||
typedef enum {
|
||||
LinphoneEcCalibratorInProgress,
|
||||
LinphoneEcCalibratorDone,
|
||||
LinphoneEcCalibratorFailed
|
||||
}LinphoneEcCalibratorStatus;
|
||||
|
||||
|
||||
typedef void (*LinphoneEcCalibrationCallback)(LinphoneCore *lc, LinphoneEcCalibratorStatus status, int delay_ms, void *data);
|
||||
|
||||
/**
|
||||
* Start an echo calibration of the sound devices, in order to find adequate settings for the echo canceller automatically.
|
||||
**/
|
||||
int linphone_core_start_echo_calibration(LinphoneCore *lc, LinphoneEcCalibrationCallback cb, void *cb_data);
|
||||
#if TARGET_OS_IPHONE
|
||||
/**
|
||||
* IOS special function to warm up dtmf feeback stream. #linphone_core_stop_dtmf_stream must be called before entering BG mode
|
||||
*/
|
||||
void linphone_core_start_dtmf_stream(const LinphoneCore* lc);
|
||||
/**
|
||||
* IOS special function to stop dtmf feed back function. Must be called before entering BG mode
|
||||
*/
|
||||
void linphone_core_stop_dtmf_stream(const LinphoneCore* lc);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ void *lsd_player_get_user_pointer(const LsdPlayer *p){
|
|||
return p->user_data;
|
||||
}
|
||||
|
||||
static void lsd_player_on_eop(void * userdata, unsigned int id, void *arg){
|
||||
static void lsd_player_on_eop(void * userdata, MSFilter *f, unsigned int id, void *arg){
|
||||
LsdPlayer *p=(LsdPlayer *)userdata;
|
||||
if (p->eop_cb!=NULL)
|
||||
p->eop_cb(p);
|
||||
|
|
|
|||
|
|
@ -233,11 +233,9 @@ static double get_audio_payload_bandwidth(LinphoneCore *lc, const PayloadType *p
|
|||
return packet_size*8.0*npacket;
|
||||
}
|
||||
|
||||
void linphone_core_update_allocated_audio_bandwidth_in_call(LinphoneCore *lc, const PayloadType *pt){
|
||||
lc->audio_bw=(int)(get_audio_payload_bandwidth(lc,pt)/1000.0);
|
||||
/*update*/
|
||||
linphone_core_set_download_bandwidth(lc,lc->net_conf.download_bw);
|
||||
linphone_core_set_upload_bandwidth(lc,lc->net_conf.upload_bw);
|
||||
void linphone_core_update_allocated_audio_bandwidth_in_call(LinphoneCall *call, const PayloadType *pt){
|
||||
call->audio_bw=(int)(get_audio_payload_bandwidth(call->core,pt)/1000.0);
|
||||
ms_message("Audio bandwidth for this call is %i",call->audio_bw);
|
||||
}
|
||||
|
||||
void linphone_core_update_allocated_audio_bandwidth(LinphoneCore *lc){
|
||||
|
|
@ -254,7 +252,7 @@ void linphone_core_update_allocated_audio_bandwidth(LinphoneCore *lc){
|
|||
}
|
||||
}
|
||||
if (max) {
|
||||
linphone_core_update_allocated_audio_bandwidth_in_call(lc,max);
|
||||
lc->audio_bw=(int)(get_audio_payload_bandwidth(lc,max)/1000.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -278,11 +276,6 @@ bool_t linphone_core_is_payload_type_usable_for_bandwidth(LinphoneCore *lc, Payl
|
|||
break;
|
||||
case PAYLOAD_VIDEO:
|
||||
if (bandwidth_limit!=0) {/* infinite (-1) or strictly positive*/
|
||||
/*let the video use all the bandwidth minus the maximum bandwidth used by audio */
|
||||
if (bandwidth_limit>0)
|
||||
pt->normal_bitrate=bandwidth_limit*1000;
|
||||
else
|
||||
pt->normal_bitrate=1500000; /*around 1.5 Mbit/s*/
|
||||
ret=TRUE;
|
||||
}
|
||||
else ret=FALSE;
|
||||
|
|
@ -295,27 +288,25 @@ bool_t linphone_core_is_payload_type_usable_for_bandwidth(LinphoneCore *lc, Payl
|
|||
bool_t linphone_core_check_payload_type_usability(LinphoneCore *lc, PayloadType *pt)
|
||||
{
|
||||
double codec_band;
|
||||
int min_audio_bw;
|
||||
int min_video_bw;
|
||||
int allowed_bw,video_bw;
|
||||
bool_t ret=FALSE;
|
||||
/*
|
||||
update allocated audio bandwidth to allocate the remaining to video.
|
||||
This must be done outside calls, because after sdp negociation
|
||||
the audio bandwidth is refined to the selected codec
|
||||
*/
|
||||
if (!linphone_core_in_call(lc)) linphone_core_update_allocated_audio_bandwidth(lc);
|
||||
min_audio_bw=get_min_bandwidth(linphone_core_get_download_bandwidth(lc),
|
||||
|
||||
linphone_core_update_allocated_audio_bandwidth(lc);
|
||||
allowed_bw=get_min_bandwidth(linphone_core_get_download_bandwidth(lc),
|
||||
linphone_core_get_upload_bandwidth(lc));
|
||||
if (min_audio_bw==0) min_audio_bw=-1;
|
||||
min_video_bw=get_min_bandwidth(lc->dw_video_bw,lc->up_video_bw);
|
||||
if (allowed_bw==0) {
|
||||
allowed_bw=-1;
|
||||
video_bw=1500; /*around 1.5 Mbit/s*/
|
||||
}else
|
||||
video_bw=get_video_bandwidth(allowed_bw,lc->audio_bw);
|
||||
|
||||
switch (pt->type){
|
||||
case PAYLOAD_AUDIO_CONTINUOUS:
|
||||
case PAYLOAD_AUDIO_PACKETIZED:
|
||||
codec_band=get_audio_payload_bandwidth(lc,pt);
|
||||
ret=bandwidth_is_greater(min_audio_bw*1000,codec_band);
|
||||
ret=bandwidth_is_greater(allowed_bw*1000,codec_band);
|
||||
/*hack to avoid using uwb codecs when having low bitrate and video*/
|
||||
if (bandwidth_is_greater(199,min_audio_bw)){
|
||||
if (bandwidth_is_greater(199,allowed_bw)){
|
||||
if (linphone_core_video_enabled(lc) && pt->clock_rate>16000){
|
||||
ret=FALSE;
|
||||
}
|
||||
|
|
@ -323,19 +314,13 @@ bool_t linphone_core_check_payload_type_usability(LinphoneCore *lc, PayloadType
|
|||
//ms_message("Payload %s: %g",pt->mime_type,codec_band);
|
||||
break;
|
||||
case PAYLOAD_VIDEO:
|
||||
if (min_video_bw!=0) {/* infinite (-1) or strictly positive*/
|
||||
/*let the video use all the bandwidth minus the maximum bandwidth used by audio */
|
||||
if (min_video_bw>0)
|
||||
pt->normal_bitrate=min_video_bw*1000;
|
||||
else
|
||||
pt->normal_bitrate=1500000; /*around 1.5 Mbit/s*/
|
||||
if (video_bw>0){
|
||||
pt->normal_bitrate=video_bw*1000;
|
||||
ret=TRUE;
|
||||
}
|
||||
else ret=FALSE;
|
||||
break;
|
||||
}
|
||||
/*if (!ret) ms_warning("Payload %s is not usable with your internet connection.",pt->mime_type);*/
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t
|
|||
|
||||
|
||||
|
||||
static SalStreamDir compute_dir(SalStreamDir local, SalStreamDir answered){
|
||||
static SalStreamDir compute_dir_outgoing(SalStreamDir local, SalStreamDir answered){
|
||||
SalStreamDir res=local;
|
||||
if (local==SalStreamSendRecv){
|
||||
if (answered==SalStreamRecvOnly){
|
||||
|
|
@ -124,6 +124,30 @@ static SalStreamDir compute_dir(SalStreamDir local, SalStreamDir answered){
|
|||
return res;
|
||||
}
|
||||
|
||||
static SalStreamDir compute_dir_incoming(SalStreamDir local, SalStreamDir offered){
|
||||
SalStreamDir res=SalStreamSendRecv;
|
||||
if (local==SalStreamSendRecv){
|
||||
if (offered==SalStreamSendOnly)
|
||||
res=SalStreamRecvOnly;
|
||||
else if (offered==SalStreamRecvOnly)
|
||||
res=SalStreamSendOnly;
|
||||
else if (offered==SalStreamInactive)
|
||||
res=SalStreamInactive;
|
||||
else
|
||||
res=SalStreamSendRecv;
|
||||
}else if (local==SalStreamSendOnly){
|
||||
if (offered==SalStreamRecvOnly || offered==SalStreamSendRecv)
|
||||
res=SalStreamSendOnly;
|
||||
else res=SalStreamInactive;
|
||||
}else if (local==SalStreamRecvOnly){
|
||||
if (offered==SalStreamSendOnly || offered==SalStreamSendRecv)
|
||||
res=SalStreamRecvOnly;
|
||||
else
|
||||
res=SalStreamInactive;
|
||||
}else res=SalStreamInactive;
|
||||
return res;
|
||||
}
|
||||
|
||||
static void initiate_outgoing(const SalStreamDescription *local_offer,
|
||||
const SalStreamDescription *remote_answer,
|
||||
SalStreamDescription *result){
|
||||
|
|
@ -131,7 +155,7 @@ static void initiate_outgoing(const SalStreamDescription *local_offer,
|
|||
result->payloads=match_payloads(local_offer->payloads,remote_answer->payloads,TRUE,FALSE);
|
||||
result->proto=local_offer->proto;
|
||||
result->type=local_offer->type;
|
||||
result->dir=compute_dir(local_offer->dir,remote_answer->dir);
|
||||
result->dir=compute_dir_outgoing(local_offer->dir,remote_answer->dir);
|
||||
|
||||
if (result->payloads && !only_telephone_event(result->payloads)){
|
||||
strcpy(result->addr,remote_answer->addr);
|
||||
|
|
@ -150,18 +174,12 @@ static void initiate_incoming(const SalStreamDescription *local_cap,
|
|||
result->payloads=match_payloads(local_cap->payloads,remote_offer->payloads, FALSE, one_matching_codec);
|
||||
result->proto=local_cap->proto;
|
||||
result->type=local_cap->type;
|
||||
if (remote_offer->dir==SalStreamSendOnly)
|
||||
result->dir=SalStreamRecvOnly;
|
||||
else if (remote_offer->dir==SalStreamRecvOnly){
|
||||
result->dir=SalStreamSendOnly;
|
||||
}else if (remote_offer->dir==SalStreamInactive){
|
||||
result->dir=SalStreamInactive;
|
||||
}else result->dir=SalStreamSendRecv;
|
||||
result->dir=compute_dir_incoming(local_cap->dir,remote_offer->dir);
|
||||
if (result->payloads && !only_telephone_event(result->payloads)){
|
||||
strcpy(result->addr,local_cap->addr);
|
||||
result->port=local_cap->port;
|
||||
result->bandwidth=local_cap->bandwidth;
|
||||
result->ptime=local_cap->ptime;
|
||||
result->ptime=local_cap->ptime;
|
||||
}else{
|
||||
result->port=0;
|
||||
}
|
||||
|
|
@ -187,6 +205,7 @@ int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer,
|
|||
else ms_warning("No matching stream for %i",i);
|
||||
}
|
||||
result->nstreams=j;
|
||||
result->bandwidth=remote_answer->bandwidth;
|
||||
strcpy(result->addr,remote_answer->addr);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -199,21 +218,30 @@ int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer,
|
|||
int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities,
|
||||
const SalMediaDescription *remote_offer,
|
||||
SalMediaDescription *result, bool_t one_matching_codec){
|
||||
int i,j;
|
||||
int i;
|
||||
const SalStreamDescription *ls,*rs;
|
||||
|
||||
for(i=0,j=0;i<remote_offer->nstreams;++i){
|
||||
for(i=0;i<remote_offer->nstreams;++i){
|
||||
rs=&remote_offer->streams[i];
|
||||
ms_message("Processing for stream %i",i);
|
||||
ls=sal_media_description_find_stream((SalMediaDescription*)local_capabilities,rs->proto,rs->type);
|
||||
if (ls){
|
||||
initiate_incoming(ls,rs,&result->streams[j],one_matching_codec);
|
||||
++j;
|
||||
initiate_incoming(ls,rs,&result->streams[i],one_matching_codec);
|
||||
} else {
|
||||
/* create an inactive stream for the answer, as there where no matching stream a local capability */
|
||||
result->streams[i].dir=SalStreamInactive;
|
||||
result->streams[i].port=0;
|
||||
result->streams[i].type=rs->type;
|
||||
if (rs->type==SalOther){
|
||||
strncpy(result->streams[i].typeother,rs->typeother,sizeof(rs->typeother)-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
result->nstreams=j;
|
||||
result->nstreams=i;
|
||||
strcpy(result->username, local_capabilities->username);
|
||||
strcpy(result->addr,local_capabilities->addr);
|
||||
result->bandwidth=local_capabilities->bandwidth;
|
||||
result->session_ver=local_capabilities->session_ver;
|
||||
result->session_id=local_capabilities->session_id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#define _PRIVATE_H
|
||||
|
||||
#include "linphonecore.h"
|
||||
#include "linphonecore_utils.h"
|
||||
#include "sal.h"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
|
@ -88,13 +89,16 @@ struct _LinphoneCall
|
|||
struct _VideoStream *videostream;
|
||||
char *refer_to;
|
||||
LinphoneCallParams params;
|
||||
LinphoneCallParams current_params;
|
||||
int up_bw; /*upload bandwidth setting at the time the call is started. Used to detect if it changes during a call */
|
||||
int audio_bw; /*upload bandwidth used by audio */
|
||||
bool_t refer_pending;
|
||||
bool_t media_pending;
|
||||
bool_t audio_muted;
|
||||
bool_t camera_active;
|
||||
bool_t all_muted; /*this flag is set during early medias*/
|
||||
bool_t playing_ringbacktone;
|
||||
bool_t owns_call_log;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -146,6 +150,11 @@ static inline bool_t bandwidth_is_greater(int bw1, int bw2){
|
|||
else return bw1>=bw2;
|
||||
}
|
||||
|
||||
static inline int get_video_bandwidth(int total, int audio){
|
||||
if (total<=0) return 0;
|
||||
return total-audio-10;
|
||||
}
|
||||
|
||||
static inline void set_string(char **dest, const char *src){
|
||||
if (*dest){
|
||||
ms_free(*dest);
|
||||
|
|
@ -170,7 +179,7 @@ void linphone_subscription_closed(LinphoneCore *lc, SalOp *op);
|
|||
MSList *linphone_find_friend(MSList *fl, const LinphoneAddress *fri, LinphoneFriend **lf);
|
||||
|
||||
void linphone_core_update_allocated_audio_bandwidth(LinphoneCore *lc);
|
||||
void linphone_core_update_allocated_audio_bandwidth_in_call(LinphoneCore *lc, const PayloadType *pt);
|
||||
void linphone_core_update_allocated_audio_bandwidth_in_call(LinphoneCall *call, const PayloadType *pt);
|
||||
void linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call);
|
||||
|
||||
void linphone_core_send_initial_subscribes(LinphoneCore *lc);
|
||||
|
|
@ -411,16 +420,13 @@ struct _LinphoneCore
|
|||
char *play_file;
|
||||
char *rec_file;
|
||||
time_t prevtime;
|
||||
int dw_audio_bw;
|
||||
int up_audio_bw;
|
||||
int dw_video_bw;
|
||||
int up_video_bw;
|
||||
int audio_bw;
|
||||
LinphoneWaitingCallback wait_cb;
|
||||
void *wait_ctx;
|
||||
unsigned long video_window_id;
|
||||
unsigned long preview_window_id;
|
||||
time_t netup_time; /*time when network went reachable */
|
||||
struct _EcCalibrator *ecc;
|
||||
bool_t use_files;
|
||||
bool_t apply_nat_settings;
|
||||
bool_t initial_subscribes_sent;
|
||||
|
|
@ -429,6 +435,7 @@ struct _LinphoneCore
|
|||
bool_t auto_net_state_mon;
|
||||
bool_t network_reachable;
|
||||
bool_t use_preview_window;
|
||||
bool_t ringstream_autorelease;
|
||||
};
|
||||
|
||||
bool_t linphone_core_can_we_add_call(LinphoneCore *lc);
|
||||
|
|
@ -440,6 +447,7 @@ int linphone_core_get_calls_nb(const LinphoneCore *lc);
|
|||
void linphone_core_set_state(LinphoneCore *lc, LinphoneGlobalState gstate, const char *message);
|
||||
|
||||
SalMediaDescription *create_local_media_description(LinphoneCore *lc, LinphoneCall *call);
|
||||
void update_local_media_description(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription **md);
|
||||
|
||||
void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription *new_md);
|
||||
|
||||
|
|
@ -448,6 +456,27 @@ bool_t linphone_core_is_payload_type_usable_for_bandwidth(LinphoneCore *lc, Payl
|
|||
#define linphone_core_ready(lc) ((lc)->state!=LinphoneGlobalStartup)
|
||||
void _linphone_core_configure_resolver();
|
||||
|
||||
struct _EcCalibrator{
|
||||
ms_thread_t thread;
|
||||
MSSndCard *play_card,*capt_card;
|
||||
MSFilter *sndread,*det,*rec;
|
||||
MSFilter *play, *gen, *sndwrite,*resampler;
|
||||
MSTicker *ticker;
|
||||
LinphoneEcCalibrationCallback cb;
|
||||
void *cb_data;
|
||||
int recv_count;
|
||||
int sent_count;
|
||||
int64_t acc;
|
||||
int delay;
|
||||
LinphoneEcCalibratorStatus status;
|
||||
};
|
||||
|
||||
typedef struct _EcCalibrator EcCalibrator;
|
||||
|
||||
LinphoneEcCalibratorStatus ec_calibrator_get_status(EcCalibrator *ecc);
|
||||
|
||||
void ec_calibrator_destroy(EcCalibrator *ecc);
|
||||
|
||||
#define HOLD_OFF (0)
|
||||
#define HOLD_ON (1)
|
||||
|
||||
|
|
|
|||
|
|
@ -215,7 +215,6 @@ void linphone_proxy_config_expires(LinphoneProxyConfig *obj, int val){
|
|||
void linphone_proxy_config_enable_publish(LinphoneProxyConfig *obj, bool_t val){
|
||||
obj->publish=val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts editing a proxy configuration.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -79,19 +79,41 @@ void sal_media_description_set_dir(SalMediaDescription *md, SalStreamDir stream_
|
|||
}
|
||||
}
|
||||
|
||||
bool_t sal_media_description_has_dir(const SalMediaDescription *md, SalStreamDir stream_dir){
|
||||
|
||||
static bool_t is_null_address(const char *addr){
|
||||
return strcmp(addr,"0.0.0.0")==0 || strcmp(addr,"::0")==0;
|
||||
}
|
||||
|
||||
/*check for the presence of at least one stream with requested direction */
|
||||
static bool_t has_dir(const SalMediaDescription *md, SalStreamDir stream_dir){
|
||||
int i;
|
||||
bool_t found=FALSE;
|
||||
|
||||
/* we are looking for at least one stream with requested direction, inactive streams are ignored*/
|
||||
for(i=0;i<md->nstreams;++i){
|
||||
const SalStreamDescription *ss=&md->streams[i];
|
||||
if (ss->dir==stream_dir) found=TRUE;
|
||||
else{
|
||||
if (ss->dir!=SalStreamInactive) return FALSE;
|
||||
}
|
||||
if (ss->dir==stream_dir) return TRUE;
|
||||
if (stream_dir==SalStreamSendOnly && (is_null_address(md->addr) || is_null_address(ss->addr)))
|
||||
return TRUE;
|
||||
}
|
||||
return found;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool_t sal_media_description_has_dir(const SalMediaDescription *md, SalStreamDir stream_dir){
|
||||
if (stream_dir==SalStreamRecvOnly){
|
||||
if (has_dir(md,SalStreamSendOnly) || has_dir(md,SalStreamSendRecv)) return FALSE;
|
||||
else return TRUE;
|
||||
}else if (stream_dir==SalStreamSendOnly){
|
||||
if (has_dir(md,SalStreamRecvOnly) || has_dir(md,SalStreamSendRecv)) return FALSE;
|
||||
else return TRUE;
|
||||
}else if (stream_dir==SalStreamSendRecv){
|
||||
return has_dir(md,SalStreamSendRecv);
|
||||
}else{
|
||||
/*SalStreamInactive*/
|
||||
if (has_dir(md,SalStreamSendOnly) || has_dir(md,SalStreamSendRecv) || has_dir(md,SalStreamRecvOnly))
|
||||
return FALSE;
|
||||
else return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -128,7 +150,6 @@ static bool_t payload_list_equals(const MSList *l1, const MSList *l2){
|
|||
}
|
||||
if (e1!=NULL || e2!=NULL){
|
||||
/*means one list is longer than the other*/
|
||||
abort();
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
|
|
@ -267,3 +288,24 @@ void __sal_op_free(SalOp *op){
|
|||
sal_media_description_unref(b->remote_media);
|
||||
ms_free(op);
|
||||
}
|
||||
|
||||
SalAuthInfo* sal_auth_info_new() {
|
||||
return ms_new0(SalAuthInfo,1);
|
||||
}
|
||||
|
||||
SalAuthInfo* sal_auth_info_clone(const SalAuthInfo* auth_info) {
|
||||
SalAuthInfo* new_auth_info=sal_auth_info_new();
|
||||
new_auth_info->username=auth_info->username?ms_strdup(auth_info->username):NULL;
|
||||
new_auth_info->userid=auth_info->userid?ms_strdup(auth_info->userid):NULL;
|
||||
new_auth_info->realm=auth_info->realm?ms_strdup(auth_info->realm):NULL;
|
||||
new_auth_info->password=auth_info->password?ms_strdup(auth_info->password):NULL;
|
||||
return new_auth_info;
|
||||
}
|
||||
|
||||
void sal_auth_info_delete(const SalAuthInfo* auth_info) {
|
||||
if (auth_info->username) ms_free(auth_info->username);
|
||||
if (auth_info->userid) ms_free(auth_info->userid);
|
||||
if (auth_info->realm) ms_free(auth_info->realm);
|
||||
if (auth_info->password) ms_free(auth_info->password);
|
||||
ms_free((void*)auth_info);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ typedef struct SalEndpointCandidate{
|
|||
typedef struct SalStreamDescription{
|
||||
SalMediaProto proto;
|
||||
SalStreamType type;
|
||||
char typeother[32];
|
||||
char addr[64];
|
||||
int port;
|
||||
MSList *payloads; //<list of PayloadType
|
||||
|
|
@ -120,6 +121,8 @@ typedef struct SalMediaDescription{
|
|||
char username[64];
|
||||
int nstreams;
|
||||
int bandwidth;
|
||||
unsigned int session_ver;
|
||||
unsigned int session_id;
|
||||
SalStreamDescription streams[SAL_MEDIA_DESCRIPTION_MAX_STREAMS];
|
||||
} SalMediaDescription;
|
||||
|
||||
|
|
@ -192,6 +195,7 @@ typedef void (*SalOnCallAck)(SalOp *op);
|
|||
typedef void (*SalOnCallUpdating)(SalOp *op);/*< Called when a reINVITE is received*/
|
||||
typedef void (*SalOnCallTerminated)(SalOp *op, const char *from);
|
||||
typedef void (*SalOnCallFailure)(SalOp *op, SalError error, SalReason reason, const char *details, int code);
|
||||
typedef void (*SalOnCallReleased)(SalOp *salop);
|
||||
typedef void (*SalOnAuthRequested)(SalOp *op, const char *realm, const char *username);
|
||||
typedef void (*SalOnAuthSuccess)(SalOp *op, const char *realm, const char *username);
|
||||
typedef void (*SalOnRegisterSuccess)(SalOp *op, bool_t registered);
|
||||
|
|
@ -215,6 +219,7 @@ typedef struct SalCallbacks{
|
|||
SalOnCallUpdating call_updating;
|
||||
SalOnCallTerminated call_terminated;
|
||||
SalOnCallFailure call_failure;
|
||||
SalOnCallReleased call_released;
|
||||
SalOnAuthRequested auth_requested;
|
||||
SalOnAuthSuccess auth_success;
|
||||
SalOnRegisterSuccess register_success;
|
||||
|
|
@ -238,6 +243,10 @@ typedef struct SalAuthInfo{
|
|||
char *realm;
|
||||
}SalAuthInfo;
|
||||
|
||||
SalAuthInfo* sal_auth_info_new();
|
||||
SalAuthInfo* sal_auth_info_clone(const SalAuthInfo* auth_info);
|
||||
void sal_auth_info_delete(const SalAuthInfo* auth_info);
|
||||
|
||||
void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs);
|
||||
int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure);
|
||||
int sal_unlisten_ports(Sal *ctx);
|
||||
|
|
@ -245,7 +254,13 @@ ortp_socket_t sal_get_socket(Sal *ctx);
|
|||
void sal_set_user_agent(Sal *ctx, const char *user_agent);
|
||||
/*keepalive period in ms*/
|
||||
void sal_set_keepalive_period(Sal *ctx,unsigned int value);
|
||||
/**
|
||||
* returns keepalive period in ms
|
||||
* 0 desactiaved
|
||||
* */
|
||||
unsigned int sal_get_keepalive_period(Sal *ctx);
|
||||
void sal_use_session_timers(Sal *ctx, int expires);
|
||||
void sal_use_double_registrations(Sal *ctx, bool_t enabled);
|
||||
void sal_use_one_matching_codec_policy(Sal *ctx, bool_t one_matching_codec);
|
||||
int sal_iterate(Sal *sal);
|
||||
MSList * sal_get_pending_auths(Sal *sal);
|
||||
|
|
@ -261,6 +276,7 @@ void sal_op_set_from(SalOp *op, const char *from);
|
|||
void sal_op_set_to(SalOp *op, const char *to);
|
||||
void sal_op_release(SalOp *h);
|
||||
void sal_op_authenticate(SalOp *h, const SalAuthInfo *info);
|
||||
void sal_op_cancel_authentication(SalOp *h);
|
||||
void sal_op_set_user_pointer(SalOp *h, void *up);
|
||||
int sal_op_get_auth_requested(SalOp *h, const char **realm, const char **username);
|
||||
const char *sal_op_get_from(const SalOp *op);
|
||||
|
|
@ -281,8 +297,7 @@ int sal_call_notify_ringing(SalOp *h, bool_t early_media);
|
|||
/*accept an incoming call or, during a call accept a reINVITE*/
|
||||
int sal_call_accept(SalOp*h);
|
||||
int sal_call_decline(SalOp *h, SalReason reason, const char *redirection /*optional*/);
|
||||
int sal_call_hold(SalOp *h, bool_t holdon);
|
||||
int sal_call_update(SalOp *h);
|
||||
int sal_call_update(SalOp *h, const char *subject);
|
||||
SalMediaDescription * sal_call_get_final_media_description(SalOp *h);
|
||||
int sal_call_refer(SalOp *h, const char *refer_to);
|
||||
int sal_call_refer_with_replaces(SalOp *h, SalOp *other_call_h);
|
||||
|
|
@ -294,6 +309,7 @@ SalOp *sal_call_get_replaces(SalOp *h);
|
|||
int sal_call_send_dtmf(SalOp *h, char dtmf);
|
||||
int sal_call_terminate(SalOp *h);
|
||||
bool_t sal_call_autoanswer_asked(SalOp *op);
|
||||
void sal_call_send_vfu_request(SalOp *h);
|
||||
|
||||
/*Registration*/
|
||||
int sal_register(SalOp *op, const char *proxy, const char *from, int expires);
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#endif
|
||||
|
||||
#include "sal_eXosip2.h"
|
||||
|
||||
#include "private.h"
|
||||
#include "offeranswer.h"
|
||||
|
||||
static void text_received(Sal *sal, eXosip_event_t *ev);
|
||||
|
|
@ -165,6 +165,7 @@ SalOp * sal_op_new(Sal *sal){
|
|||
op->referred_by=NULL;
|
||||
op->masquerade_via=FALSE;
|
||||
op->auto_answer_asked=FALSE;
|
||||
op->auth_info=NULL;
|
||||
return op;
|
||||
}
|
||||
|
||||
|
|
@ -209,6 +210,9 @@ void sal_op_release(SalOp *op){
|
|||
if (op->referred_by){
|
||||
ms_free(op->referred_by);
|
||||
}
|
||||
if (op->auth_info) {
|
||||
sal_auth_info_delete(op->auth_info);
|
||||
}
|
||||
__sal_op_free(op);
|
||||
}
|
||||
|
||||
|
|
@ -260,6 +264,7 @@ Sal * sal_init(){
|
|||
eXosip_init();
|
||||
sal=ms_new0(Sal,1);
|
||||
sal->keepalive_period=30;
|
||||
sal->double_reg=TRUE;
|
||||
return sal;
|
||||
}
|
||||
|
||||
|
|
@ -292,6 +297,8 @@ void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){
|
|||
ctx->callbacks.call_failure=(SalOnCallFailure)unimplemented_stub;
|
||||
if (ctx->callbacks.call_terminated==NULL)
|
||||
ctx->callbacks.call_terminated=(SalOnCallTerminated)unimplemented_stub;
|
||||
if (ctx->callbacks.call_released==NULL)
|
||||
ctx->callbacks.call_released=(SalOnCallReleased)unimplemented_stub;
|
||||
if (ctx->callbacks.call_updating==NULL)
|
||||
ctx->callbacks.call_updating=(SalOnCallUpdating)unimplemented_stub;
|
||||
if (ctx->callbacks.auth_requested==NULL)
|
||||
|
|
@ -330,13 +337,17 @@ int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int i
|
|||
int err;
|
||||
bool_t ipv6;
|
||||
int proto=IPPROTO_UDP;
|
||||
int keepalive = ctx->keepalive_period;
|
||||
|
||||
switch (tr) {
|
||||
case SalTransportDatagram:
|
||||
proto=IPPROTO_UDP;
|
||||
eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &keepalive);
|
||||
break;
|
||||
case SalTransportStream:
|
||||
proto= IPPROTO_TCP;
|
||||
keepalive=-1;
|
||||
eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE,&keepalive);
|
||||
break;
|
||||
default:
|
||||
ms_warning("unexpected proto, using datagram");
|
||||
|
|
@ -357,7 +368,7 @@ int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int i
|
|||
#ifdef HAVE_EXOSIP_GET_SOCKET
|
||||
ms_message("Exosip has socket number %i",eXosip_get_socket(proto));
|
||||
#endif
|
||||
eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &ctx->keepalive_period);
|
||||
|
||||
ctx->running=TRUE;
|
||||
return err;
|
||||
}
|
||||
|
|
@ -387,6 +398,10 @@ MSList *sal_get_pending_auths(Sal *sal){
|
|||
return ms_list_copy(sal->pending_auths);
|
||||
}
|
||||
|
||||
void sal_use_double_registrations(Sal *ctx, bool_t enabled){
|
||||
ctx->double_reg=enabled;
|
||||
}
|
||||
|
||||
static int extract_received_rport(osip_message_t *msg, const char **received, int *rportval){
|
||||
osip_via_t *via=NULL;
|
||||
osip_generic_param_t *param=NULL;
|
||||
|
|
@ -455,6 +470,8 @@ static void sdp_process(SalOp *h){
|
|||
int i;
|
||||
offer_answer_initiate_incoming(h->base.local_media,h->base.remote_media,h->result,h->base.root->one_matching_codec);
|
||||
h->sdp_answer=media_description_to_sdp(h->result);
|
||||
/*once we have generated the SDP answer, we modify the result description for processing by the upper layer.
|
||||
It should contains media parameters constraint from the remote offer, not our response*/
|
||||
strcpy(h->result->addr,h->base.remote_media->addr);
|
||||
h->result->bandwidth=h->base.remote_media->bandwidth;
|
||||
for(i=0;i<h->result->nstreams;++i){
|
||||
|
|
@ -637,6 +654,7 @@ int sal_ping(SalOp *op, const char *from, const char *to){
|
|||
|
||||
sal_op_set_from(op,from);
|
||||
sal_op_set_to(op,to);
|
||||
/*bug here: eXosip2 does not honor the route argument*/
|
||||
eXosip_options_build_request (&options, sal_op_get_to(op),
|
||||
sal_op_get_from(op),sal_op_get_route(op));
|
||||
if (options){
|
||||
|
|
@ -732,38 +750,59 @@ int sal_call_send_dtmf(SalOp *h, char dtmf){
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void push_auth_to_exosip(const SalAuthInfo *info){
|
||||
const char *userid;
|
||||
if (info->userid==NULL || info->userid[0]=='\0') userid=info->username;
|
||||
else userid=info->userid;
|
||||
ms_message("Authentication info for username [%s], id[%s], realm [%s] added to eXosip", info->username,userid, info->realm);
|
||||
eXosip_add_authentication_info (info->username,userid,
|
||||
info->password, NULL,info->realm);
|
||||
}
|
||||
/*
|
||||
* Just for symmetry ;-)
|
||||
*/
|
||||
static void pop_auth_from_exosip() {
|
||||
eXosip_clear_authentication_info();
|
||||
}
|
||||
|
||||
int sal_call_terminate(SalOp *h){
|
||||
int err;
|
||||
if (h->auth_info) push_auth_to_exosip(h->auth_info);
|
||||
eXosip_lock();
|
||||
err=eXosip_call_terminate(h->cid,h->did);
|
||||
eXosip_unlock();
|
||||
pop_auth_from_exosip();
|
||||
if (err!=0){
|
||||
ms_warning("Exosip could not terminate the call: cid=%i did=%i", h->cid,h->did);
|
||||
}
|
||||
sal_remove_call(h->base.root,h);
|
||||
h->cid=-1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sal_op_authenticate(SalOp *h, const SalAuthInfo *info){
|
||||
if (h->pending_auth){
|
||||
const char *userid;
|
||||
if (info->userid==NULL || info->userid[0]=='\0') userid=info->username;
|
||||
else userid=info->userid;
|
||||
ms_message("Authentication info for %s %s added to eXosip", info->username,info->realm);
|
||||
eXosip_add_authentication_info (info->username,userid,
|
||||
info->password, NULL,info->realm);
|
||||
push_auth_to_exosip(info);
|
||||
eXosip_lock();
|
||||
eXosip_default_action(h->pending_auth);
|
||||
eXosip_unlock();
|
||||
ms_message("eXosip_default_action() done");
|
||||
eXosip_clear_authentication_info();
|
||||
pop_auth_from_exosip();
|
||||
eXosip_event_free(h->pending_auth);
|
||||
sal_remove_pending_auth(sal_op_get_sal(h),h);
|
||||
h->pending_auth=NULL;
|
||||
if (h->auth_info) sal_auth_info_delete(h->auth_info); /*if already exist*/
|
||||
h->auth_info=sal_auth_info_clone(info); /*store auth info for subsequent request*/
|
||||
}
|
||||
}
|
||||
void sal_op_cancel_authentication(SalOp *h) {
|
||||
if (h->rid >0) {
|
||||
sal_op_get_sal(h)->callbacks.register_failure(h,SalErrorFailure, SalReasonForbidden,_("Authentication failure"));
|
||||
} else if (h->cid >0) {
|
||||
sal_op_get_sal(h)->callbacks.call_failure(h,SalErrorFailure, SalReasonForbidden,_("Authentication failure"),0);
|
||||
} else {
|
||||
ms_warning("Auth failure not handled");
|
||||
}
|
||||
|
||||
}
|
||||
static void set_network_origin(SalOp *op, osip_message_t *req){
|
||||
const char *received=NULL;
|
||||
int rport=5060;
|
||||
|
|
@ -815,6 +854,9 @@ static SalOp *find_op(Sal *sal, eXosip_event_t *ev){
|
|||
if (ev->sid>0){
|
||||
return sal_find_out_subscribe(sal,ev->sid);
|
||||
}
|
||||
if (ev->nid>0){
|
||||
return sal_find_in_subscribe(sal,ev->nid);
|
||||
}
|
||||
if (ev->response) return sal_find_other(sal,ev->response);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -1033,8 +1075,6 @@ static void call_terminated(Sal *sal, eXosip_event_t *ev){
|
|||
if (ev->request){
|
||||
osip_from_to_str(ev->request->from,&from);
|
||||
}
|
||||
sal_remove_call(sal,op);
|
||||
op->cid=-1;
|
||||
sal->callbacks.call_terminated(op,from!=NULL ? from : sal_op_get_from(op));
|
||||
if (from) osip_free(from);
|
||||
}
|
||||
|
|
@ -1045,9 +1085,10 @@ static void call_released(Sal *sal, eXosip_event_t *ev){
|
|||
ms_warning("No op associated to this call_released()");
|
||||
return;
|
||||
}
|
||||
op->cid=-1;
|
||||
if (op->did==-1)
|
||||
if (op->did==-1) {
|
||||
sal->callbacks.call_failure(op,SalErrorNoResponse,SalReasonUnknown,NULL, 487);
|
||||
}
|
||||
sal->callbacks.call_released(op);
|
||||
}
|
||||
|
||||
static int get_auth_data_from_response(osip_message_t *resp, const char **realm, const char **username){
|
||||
|
|
@ -1216,6 +1257,33 @@ static bool_t call_failure(Sal *sal, eXosip_event_t *ev){
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* Request remote side to send us VFU */
|
||||
void sal_call_send_vfu_request(SalOp *h){
|
||||
osip_message_t *msg=NULL;
|
||||
char info_body[] =
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
|
||||
"<media_control>"
|
||||
" <vc_primitive>"
|
||||
" <to_encoder>"
|
||||
" <picture_fast_update></picture_fast_update>"
|
||||
" </to_encoder>"
|
||||
" </vc_primitive>"
|
||||
"</media_control>";
|
||||
|
||||
char clen[10];
|
||||
|
||||
eXosip_lock();
|
||||
eXosip_call_build_info(h->did,&msg);
|
||||
if (msg){
|
||||
osip_message_set_body(msg,info_body,strlen(info_body));
|
||||
osip_message_set_content_type(msg,"application/media_control+xml");
|
||||
snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(info_body));
|
||||
osip_message_set_content_length(msg,clen);
|
||||
eXosip_call_send_request(h->did,msg);
|
||||
ms_message("Sending VFU request !");
|
||||
}
|
||||
eXosip_unlock();
|
||||
}
|
||||
|
||||
static void process_media_control_xml(Sal *sal, eXosip_event_t *ev){
|
||||
SalOp *op=find_op(sal,ev);
|
||||
|
|
@ -1505,6 +1573,9 @@ static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *ori
|
|||
char *tmp;
|
||||
char port[20];
|
||||
SalAddress *addr;
|
||||
Sal *sal=op->base.root;
|
||||
|
||||
if (sal->double_reg==FALSE) return FALSE;
|
||||
|
||||
if (extract_received_rport(last_answer,&received,&rport)==-1) return FALSE;
|
||||
osip_message_get_contact(orig_request,0,&ctt);
|
||||
|
|
@ -1681,7 +1752,7 @@ static bool_t process_event(Sal *sal, eXosip_event_t *ev){
|
|||
call_message_new(sal,ev);
|
||||
break;
|
||||
case EXOSIP_CALL_MESSAGE_REQUESTFAILURE:
|
||||
if (ev->did<0 && ev->response &&
|
||||
if (ev->response &&
|
||||
(ev->response->status_code==407 || ev->response->status_code==401)){
|
||||
return process_authentication(sal,ev);
|
||||
}
|
||||
|
|
@ -1736,6 +1807,7 @@ static bool_t process_event(Sal *sal, eXosip_event_t *ev){
|
|||
other_request_reply(sal,ev);
|
||||
break;
|
||||
case EXOSIP_MESSAGE_REQUESTFAILURE:
|
||||
case EXOSIP_NOTIFICATION_REQUESTFAILURE:
|
||||
if (ev->response) {
|
||||
switch (ev->response->status_code) {
|
||||
case 407:
|
||||
|
|
@ -1934,6 +2006,9 @@ void sal_set_keepalive_period(Sal *ctx,unsigned int value) {
|
|||
ctx->keepalive_period=value;
|
||||
eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &value);
|
||||
}
|
||||
unsigned int sal_get_keepalive_period(Sal *ctx) {
|
||||
return ctx->keepalive_period;
|
||||
}
|
||||
|
||||
const char * sal_address_get_port(const SalAddress *addr) {
|
||||
const osip_from_t *u=(const osip_from_t*)addr;
|
||||
|
|
@ -1949,47 +2024,18 @@ int sal_address_get_port_int(const SalAddress *uri) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a re-Invite used to hold the current call
|
||||
*/
|
||||
int sal_call_hold(SalOp *h, bool_t holdon)
|
||||
{
|
||||
int err=0;
|
||||
|
||||
osip_message_t *reinvite=NULL;
|
||||
if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != OSIP_SUCCESS || reinvite==NULL)
|
||||
return -1;
|
||||
osip_message_set_subject(reinvite,holdon ? "Phone call hold" : "Phone call resume" );
|
||||
osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
|
||||
if (h->base.root->session_expires!=0){
|
||||
osip_message_set_header(reinvite, "Session-expires", "200");
|
||||
osip_message_set_supported(reinvite, "timer");
|
||||
}
|
||||
//add something to say that the distant sip phone will be in sendonly/sendrecv mode
|
||||
if (h->base.local_media){
|
||||
h->sdp_offering=TRUE;
|
||||
sal_media_description_set_dir(h->base.local_media, holdon ? SalStreamSendOnly : SalStreamSendRecv);
|
||||
set_sdp_from_desc(reinvite,h->base.local_media);
|
||||
}else h->sdp_offering=FALSE;
|
||||
eXosip_lock();
|
||||
err = eXosip_call_send_request(h->did, reinvite);
|
||||
eXosip_unlock();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* sends a reinvite. Local media description may have changed by application since call establishment*/
|
||||
int sal_call_update(SalOp *h){
|
||||
int sal_call_update(SalOp *h, const char *subject){
|
||||
int err=0;
|
||||
osip_message_t *reinvite=NULL;
|
||||
|
||||
eXosip_lock();
|
||||
if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != OSIP_SUCCESS || reinvite==NULL){
|
||||
if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != 0 || reinvite==NULL){
|
||||
eXosip_unlock();
|
||||
return -1;
|
||||
}
|
||||
eXosip_unlock();
|
||||
osip_message_set_subject(reinvite,osip_strdup("Phone call parameters updated"));
|
||||
osip_message_set_subject(reinvite,subject);
|
||||
osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
|
||||
if (h->base.root->session_expires!=0){
|
||||
osip_message_set_header(reinvite, "Session-expires", "200");
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ struct Sal{
|
|||
int keepalive_period;
|
||||
void *up;
|
||||
bool_t one_matching_codec;
|
||||
bool_t double_reg;
|
||||
};
|
||||
|
||||
struct SalOp{
|
||||
|
|
@ -64,6 +65,7 @@ struct SalOp{
|
|||
bool_t reinvite;
|
||||
bool_t masquerade_via;
|
||||
bool_t auto_answer_asked;
|
||||
const SalAuthInfo *auth_info;
|
||||
};
|
||||
|
||||
void sal_remove_out_subscribe(Sal *sal, SalOp *op);
|
||||
|
|
@ -77,6 +79,7 @@ void sal_exosip_subscription_closed(Sal *sal,eXosip_event_t *ev);
|
|||
|
||||
void sal_exosip_in_subscription_closed(Sal *sal, eXosip_event_t *ev);
|
||||
SalOp * sal_find_out_subscribe(Sal *sal, int sid);
|
||||
SalOp * sal_find_in_subscribe(Sal *sal, int nid);
|
||||
void sal_exosip_fix_route(SalOp *op);
|
||||
|
||||
void _osip_list_set_empty(osip_list_t *l, void (*freefunc)(void*));
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ SalOp * sal_find_out_subscribe(Sal *sal, int sid){
|
|||
op=(SalOp*)elem->data;
|
||||
if (op->sid==sid) return op;
|
||||
}
|
||||
ms_message("No op for sid %i",sid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -50,7 +51,7 @@ void sal_remove_out_subscribe(Sal *sal, SalOp *op){
|
|||
sal->out_subscribes=ms_list_remove(sal->out_subscribes,op);
|
||||
}
|
||||
|
||||
static SalOp * sal_find_in_subscribe(Sal *sal, int nid){
|
||||
SalOp * sal_find_in_subscribe(Sal *sal, int nid){
|
||||
const MSList *elem;
|
||||
SalOp *op;
|
||||
for(elem=sal->in_subscribes;elem!=NULL;elem=elem->next){
|
||||
|
|
@ -569,6 +570,7 @@ int sal_notify_presence(SalOp *op, SalPresenceStatus status, const char *status_
|
|||
if (msg!=NULL){
|
||||
const char *identity=sal_op_get_contact(op);
|
||||
if (identity==NULL) identity=sal_op_get_to(op);
|
||||
_osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
|
||||
osip_message_set_contact(msg,identity);
|
||||
add_presence_body(msg,status);
|
||||
eXosip_insubscription_send_request(op->did,msg);
|
||||
|
|
|
|||
|
|
@ -127,14 +127,18 @@ static sdp_message_t *create_generic_sdp(const SalMediaDescription *desc)
|
|||
{
|
||||
sdp_message_t *local;
|
||||
int inet6;
|
||||
|
||||
char sessid[16];
|
||||
char sessver[16];
|
||||
|
||||
snprintf(sessid,16,"%i",desc->session_id);
|
||||
snprintf(sessver,16,"%i",desc->session_ver);
|
||||
sdp_message_init (&local);
|
||||
if (strchr(desc->addr,':')!=NULL){
|
||||
inet6=1;
|
||||
}else inet6=0;
|
||||
sdp_message_v_version_set (local, osip_strdup ("0"));
|
||||
sdp_message_o_origin_set (local, osip_strdup (desc->username),
|
||||
osip_strdup ("123456"), osip_strdup ("654321"),
|
||||
osip_strdup (sessid), osip_strdup (sessver),
|
||||
osip_strdup ("IN"), inet6 ? osip_strdup("IP6") : osip_strdup ("IP4"),
|
||||
osip_strdup (desc->addr));
|
||||
sdp_message_s_name_set (local, osip_strdup ("A conversation"));
|
||||
|
|
@ -181,11 +185,23 @@ static void add_payload(sdp_message_t *msg, int line, const PayloadType *pt)
|
|||
|
||||
|
||||
static void add_line(sdp_message_t *msg, int lineno, const SalStreamDescription *desc){
|
||||
const char *mt=desc->type==SalAudio ? "audio" : "video";
|
||||
const char *mt=NULL;
|
||||
const MSList *elem;
|
||||
const char *addr;
|
||||
const char *dir="sendrecv";
|
||||
int port;
|
||||
|
||||
switch (desc->type) {
|
||||
case SalAudio:
|
||||
mt="audio";
|
||||
break;
|
||||
case SalVideo:
|
||||
mt="video";
|
||||
break;
|
||||
case SalOther:
|
||||
mt=desc->typeother;
|
||||
break;
|
||||
}
|
||||
if (desc->candidates[0].addr[0]!='\0'){
|
||||
addr=desc->candidates[0].addr;
|
||||
port=desc->candidates[0].port;
|
||||
|
|
@ -310,7 +326,10 @@ int sdp_to_media_description(sdp_message_t *msg, SalMediaDescription *desc){
|
|||
stream->type=SalAudio;
|
||||
}else if (strcasecmp("video", mtype) == 0){
|
||||
stream->type=SalVideo;
|
||||
}else stream->type=SalOther;
|
||||
}else {
|
||||
stream->type=SalOther;
|
||||
strncpy(stream->typeother,mtype,sizeof(stream->typeother)-1);
|
||||
}
|
||||
for(j=0;(sbw=sdp_message_bandwidth_get(msg,i,j))!=NULL;++j){
|
||||
if (strcasecmp(sbw->b_bwtype,"AS")==0) stream->bandwidth=atoi(sbw->b_bandwidth);
|
||||
}
|
||||
|
|
|
|||
46
coreapi/test_ecc.c
Normal file
46
coreapi/test_ecc.c
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
linphone
|
||||
Copyright (C) 2011 Belledonne Communications SARL
|
||||
Author: Simon MORLAT (simon.morlat@linphone.org)
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "linphonecore.h"
|
||||
#include "linphonecore_utils.h"
|
||||
|
||||
static void calibration_finished(LinphoneCore *lc, LinphoneEcCalibratorStatus status, int delay, void *data){
|
||||
ms_message("echo calibration finished %s.",status==LinphoneEcCalibratorDone ? "successfully" : "with faillure");
|
||||
if (status==LinphoneEcCalibratorDone) ms_message("Measured delay is %i",delay);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]){
|
||||
int count=0;
|
||||
LinphoneCoreVTable vtable={0};
|
||||
LinphoneCore *lc=linphone_core_new(&vtable,NULL,NULL,NULL);
|
||||
|
||||
linphone_core_enable_logs(NULL);
|
||||
|
||||
linphone_core_start_echo_calibration(lc,calibration_finished,NULL);
|
||||
|
||||
while(count++<1000){
|
||||
linphone_core_iterate(lc);
|
||||
ms_usleep(10000);
|
||||
}
|
||||
linphone_core_destroy(lc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -4,7 +4,6 @@
|
|||
# It must be run within a gtk+ binary bundle tree, such as in the zip bundle
|
||||
# downloadable from www.gtk.org
|
||||
echo bin
|
||||
echo bin/libglade-2.0-0.dll
|
||||
find bin -name *.dll
|
||||
find lib/gtk-2.0
|
||||
find etc
|
||||
|
|
|
|||
152
gtk+-2.22.1.filelist
Normal file
152
gtk+-2.22.1.filelist
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
bin
|
||||
bin/freetype6.dll
|
||||
bin/intl.dll
|
||||
bin/libasprintf-0.dll
|
||||
bin/libatk-1.0-0.dll
|
||||
bin/libcairo-2.dll
|
||||
bin/libcairo-gobject-2.dll
|
||||
bin/libcairo-script-interpreter-2.dll
|
||||
bin/libexpat-1.dll
|
||||
bin/libfontconfig-1.dll
|
||||
bin/libgailutil-18.dll
|
||||
bin/libgcc_s_dw2-1.dll
|
||||
bin/libgdk-win32-2.0-0.dll
|
||||
bin/libgdk_pixbuf-2.0-0.dll
|
||||
bin/libgio-2.0-0.dll
|
||||
bin/libglib-2.0-0.dll
|
||||
bin/libgmodule-2.0-0.dll
|
||||
bin/libgobject-2.0-0.dll
|
||||
bin/libgthread-2.0-0.dll
|
||||
bin/libgtk-win32-2.0-0.dll
|
||||
bin/libpango-1.0-0.dll
|
||||
bin/libpangocairo-1.0-0.dll
|
||||
bin/libpangoft2-1.0-0.dll
|
||||
bin/libpangowin32-1.0-0.dll
|
||||
bin/libpng14-14.dll
|
||||
bin/zlib1.dll
|
||||
lib/gtk-2.0
|
||||
lib/gtk-2.0/2.10.0
|
||||
lib/gtk-2.0/2.10.0/engines
|
||||
lib/gtk-2.0/2.10.0/engines/libpixmap.dll
|
||||
lib/gtk-2.0/2.10.0/engines/libwimp.dll
|
||||
lib/gtk-2.0/include
|
||||
lib/gtk-2.0/include/gdkconfig.h
|
||||
lib/gtk-2.0/modules
|
||||
lib/gtk-2.0/modules/libgail.dll
|
||||
etc
|
||||
etc/fonts
|
||||
etc/fonts/fonts.conf
|
||||
etc/fonts/fonts.dtd
|
||||
etc/gtk-2.0
|
||||
etc/gtk-2.0/gtk.immodules
|
||||
etc/gtk-2.0/im-multipress.conf
|
||||
etc/pango
|
||||
etc/pango/pango.modules
|
||||
share/locale/fr
|
||||
share/locale/fr/LC_MESSAGES
|
||||
share/locale/fr/LC_MESSAGES/atk10.mo
|
||||
share/locale/fr/LC_MESSAGES/gdk-pixbuf.mo
|
||||
share/locale/fr/LC_MESSAGES/gettext-runtime.mo
|
||||
share/locale/fr/LC_MESSAGES/glib20.mo
|
||||
share/locale/fr/LC_MESSAGES/gtk20-properties.mo
|
||||
share/locale/fr/LC_MESSAGES/gtk20.mo
|
||||
share/locale/de
|
||||
share/locale/de/LC_MESSAGES
|
||||
share/locale/de/LC_MESSAGES/atk10.mo
|
||||
share/locale/de/LC_MESSAGES/gdk-pixbuf.mo
|
||||
share/locale/de/LC_MESSAGES/gettext-runtime.mo
|
||||
share/locale/de/LC_MESSAGES/glib20.mo
|
||||
share/locale/de/LC_MESSAGES/gtk20-properties.mo
|
||||
share/locale/de/LC_MESSAGES/gtk20.mo
|
||||
share/locale/sv
|
||||
share/locale/sv/LC_MESSAGES
|
||||
share/locale/sv/LC_MESSAGES/atk10.mo
|
||||
share/locale/sv/LC_MESSAGES/gdk-pixbuf.mo
|
||||
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/cs
|
||||
share/locale/cs/LC_MESSAGES
|
||||
share/locale/cs/LC_MESSAGES/atk10.mo
|
||||
share/locale/cs/LC_MESSAGES/gdk-pixbuf.mo
|
||||
share/locale/cs/LC_MESSAGES/gettext-runtime.mo
|
||||
share/locale/cs/LC_MESSAGES/glib20.mo
|
||||
share/locale/cs/LC_MESSAGES/gtk20-properties.mo
|
||||
share/locale/cs/LC_MESSAGES/gtk20.mo
|
||||
share/locale/es
|
||||
share/locale/es/LC_MESSAGES
|
||||
share/locale/es/LC_MESSAGES/atk10.mo
|
||||
share/locale/es/LC_MESSAGES/gdk-pixbuf.mo
|
||||
share/locale/es/LC_MESSAGES/gettext-runtime.mo
|
||||
share/locale/es/LC_MESSAGES/glib20.mo
|
||||
share/locale/es/LC_MESSAGES/gtk20-properties.mo
|
||||
share/locale/es/LC_MESSAGES/gtk20.mo
|
||||
share/locale/hu
|
||||
share/locale/hu/LC_MESSAGES
|
||||
share/locale/hu/LC_MESSAGES/atk10.mo
|
||||
share/locale/hu/LC_MESSAGES/gdk-pixbuf.mo
|
||||
share/locale/hu/LC_MESSAGES/glib20.mo
|
||||
share/locale/hu/LC_MESSAGES/gtk20-properties.mo
|
||||
share/locale/hu/LC_MESSAGES/gtk20.mo
|
||||
share/locale/it
|
||||
share/locale/it/LC_MESSAGES
|
||||
share/locale/it/LC_MESSAGES/atk10.mo
|
||||
share/locale/it/LC_MESSAGES/gdk-pixbuf.mo
|
||||
share/locale/it/LC_MESSAGES/gettext-runtime.mo
|
||||
share/locale/it/LC_MESSAGES/glib20.mo
|
||||
share/locale/it/LC_MESSAGES/gtk20-properties.mo
|
||||
share/locale/it/LC_MESSAGES/gtk20.mo
|
||||
share/locale/ja
|
||||
share/locale/ja/LC_MESSAGES
|
||||
share/locale/ja/LC_MESSAGES/atk10.mo
|
||||
share/locale/ja/LC_MESSAGES/gdk-pixbuf.mo
|
||||
share/locale/ja/LC_MESSAGES/gettext-runtime.mo
|
||||
share/locale/ja/LC_MESSAGES/glib20.mo
|
||||
share/locale/ja/LC_MESSAGES/gtk20-properties.mo
|
||||
share/locale/ja/LC_MESSAGES/gtk20.mo
|
||||
share/locale/nl
|
||||
share/locale/nl/LC_MESSAGES
|
||||
share/locale/nl/LC_MESSAGES/atk10.mo
|
||||
share/locale/nl/LC_MESSAGES/gdk-pixbuf.mo
|
||||
share/locale/nl/LC_MESSAGES/gettext-runtime.mo
|
||||
share/locale/nl/LC_MESSAGES/glib20.mo
|
||||
share/locale/nl/LC_MESSAGES/gtk20-properties.mo
|
||||
share/locale/nl/LC_MESSAGES/gtk20.mo
|
||||
share/locale/pl
|
||||
share/locale/pl/LC_MESSAGES
|
||||
share/locale/pl/LC_MESSAGES/atk10.mo
|
||||
share/locale/pl/LC_MESSAGES/gdk-pixbuf.mo
|
||||
share/locale/pl/LC_MESSAGES/gettext-runtime.mo
|
||||
share/locale/pl/LC_MESSAGES/glib20.mo
|
||||
share/locale/pl/LC_MESSAGES/gtk20-properties.mo
|
||||
share/locale/pl/LC_MESSAGES/gtk20.mo
|
||||
share/locale/ru
|
||||
share/locale/ru/LC_MESSAGES
|
||||
share/locale/ru/LC_MESSAGES/atk10.mo
|
||||
share/locale/ru/LC_MESSAGES/gdk-pixbuf.mo
|
||||
share/locale/ru/LC_MESSAGES/gettext-runtime.mo
|
||||
share/locale/ru/LC_MESSAGES/glib20.mo
|
||||
share/locale/ru/LC_MESSAGES/gtk20-properties.mo
|
||||
share/locale/ru/LC_MESSAGES/gtk20.mo
|
||||
share/locale/pt_BR
|
||||
share/locale/pt_BR/LC_MESSAGES
|
||||
share/locale/pt_BR/LC_MESSAGES/atk10.mo
|
||||
share/locale/pt_BR/LC_MESSAGES/gdk-pixbuf.mo
|
||||
share/locale/pt_BR/LC_MESSAGES/gettext-runtime.mo
|
||||
share/locale/pt_BR/LC_MESSAGES/glib20.mo
|
||||
share/locale/pt_BR/LC_MESSAGES/gtk20-properties.mo
|
||||
share/locale/pt_BR/LC_MESSAGES/gtk20.mo
|
||||
share/themes
|
||||
share/themes/Default
|
||||
share/themes/Default/gtk-2.0-key
|
||||
share/themes/Default/gtk-2.0-key/gtkrc
|
||||
share/themes/Emacs
|
||||
share/themes/Emacs/gtk-2.0-key
|
||||
share/themes/Emacs/gtk-2.0-key/gtkrc
|
||||
share/themes/MS-Windows
|
||||
share/themes/MS-Windows/gtk-2.0
|
||||
share/themes/MS-Windows/gtk-2.0/gtkrc
|
||||
share/themes/Raleigh
|
||||
share/themes/Raleigh/gtk-2.0
|
||||
share/themes/Raleigh/gtk-2.0/gtkrc
|
||||
|
|
@ -58,7 +58,7 @@ static GtkWidget *make_tab_header(int number){
|
|||
GtkWidget *w=gtk_hbox_new (FALSE,0);
|
||||
GtkWidget *i=create_pixmap ("status-green.png");
|
||||
GtkWidget *l;
|
||||
gchar *text=g_strdup_printf("Call %i",number);
|
||||
gchar *text=g_strdup_printf("Call #%i",number);
|
||||
l=gtk_label_new (text);
|
||||
gtk_box_pack_start (GTK_BOX(w),i,FALSE,FALSE,0);
|
||||
gtk_box_pack_end(GTK_BOX(w),l,TRUE,TRUE,0);
|
||||
|
|
@ -66,6 +66,60 @@ static GtkWidget *make_tab_header(int number){
|
|||
return w;
|
||||
}
|
||||
|
||||
static void linphone_gtk_transfer_call(LinphoneCall *dest_call){
|
||||
LinphoneCall *call=linphone_gtk_get_currently_displayed_call();
|
||||
linphone_core_transfer_call_to_another (linphone_gtk_get_core(),call,dest_call);
|
||||
}
|
||||
|
||||
static void transfer_button_clicked(GtkWidget *button, gpointer call_ref){
|
||||
GtkWidget *menu_item;
|
||||
GtkWidget *menu=gtk_menu_new();
|
||||
LinphoneCall *call=(LinphoneCall*)call_ref;
|
||||
LinphoneCore *lc=linphone_gtk_get_core();
|
||||
const MSList *elem=linphone_core_get_calls(lc);
|
||||
|
||||
for(;elem!=NULL;elem=elem->next){
|
||||
LinphoneCall *other_call=(LinphoneCall*)elem->data;
|
||||
GtkWidget *call_view=(GtkWidget*)linphone_call_get_user_pointer(other_call);
|
||||
if (other_call!=call){
|
||||
int call_index=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(call_view),"call_index"));
|
||||
char *remote_uri=linphone_call_get_remote_address_as_string (other_call);
|
||||
char *text=g_strdup_printf("Transfer to call #%i with %s",call_index,remote_uri);
|
||||
menu_item=gtk_image_menu_item_new_with_label(text);
|
||||
ms_free(remote_uri);
|
||||
g_free(text);
|
||||
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item),create_pixmap("status-green.png"));
|
||||
gtk_widget_show(menu_item);
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(menu),menu_item);
|
||||
g_signal_connect_swapped(G_OBJECT(menu_item),"activate",(GCallback)linphone_gtk_transfer_call,other_call);
|
||||
}
|
||||
}
|
||||
gtk_menu_popup(GTK_MENU(menu),NULL,NULL,NULL,NULL,0,
|
||||
gtk_get_current_event_time());
|
||||
gtk_widget_show(menu);
|
||||
}
|
||||
|
||||
void linphone_gtk_enable_transfer_button(LinphoneCore *lc, gboolean value){
|
||||
const MSList *elem=linphone_core_get_calls(lc);
|
||||
for(;elem!=NULL;elem=elem->next){
|
||||
LinphoneCall *call=(LinphoneCall*)elem->data;
|
||||
GtkWidget *call_view=(GtkWidget*)linphone_call_get_user_pointer(call);
|
||||
GtkWidget *box=linphone_gtk_get_widget (call_view,"mute_pause_buttons");
|
||||
GtkWidget *button=(GtkWidget*)g_object_get_data(G_OBJECT(box),"transfer");
|
||||
if (button && value==FALSE){
|
||||
gtk_widget_destroy(button);
|
||||
button=NULL;
|
||||
}else if (!button && value==TRUE){
|
||||
button=gtk_button_new_with_label (_("Transfer"));
|
||||
gtk_button_set_image(GTK_BUTTON(button),gtk_image_new_from_stock (GTK_STOCK_GO_FORWARD,GTK_ICON_SIZE_BUTTON));
|
||||
g_signal_connect(G_OBJECT(button),"clicked",(GCallback)transfer_button_clicked,call);
|
||||
gtk_widget_show_all(button);
|
||||
gtk_container_add(GTK_CONTAINER(box),button);
|
||||
}
|
||||
g_object_set_data(G_OBJECT(box),"transfer",button);
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_gtk_create_in_call_view(LinphoneCall *call){
|
||||
GtkWidget *call_view=linphone_gtk_create_widget("main","in_call_frame");
|
||||
GtkWidget *main_window=linphone_gtk_get_main_window ();
|
||||
|
|
@ -78,6 +132,8 @@ void linphone_gtk_create_in_call_view(LinphoneCall *call){
|
|||
call_index=1;
|
||||
}
|
||||
g_object_set_data(G_OBJECT(call_view),"call",call);
|
||||
g_object_set_data(G_OBJECT(call_view),"call_index",GINT_TO_POINTER(call_index));
|
||||
|
||||
linphone_call_set_user_pointer (call,call_view);
|
||||
linphone_call_ref(call);
|
||||
gtk_notebook_append_page (notebook,call_view,make_tab_header(call_index));
|
||||
|
|
@ -145,6 +201,7 @@ void linphone_gtk_in_call_view_set_incoming(LinphoneCall *call, bool_t with_paus
|
|||
GtkWidget *animation=linphone_gtk_get_widget(callview,"in_call_animation");
|
||||
GdkPixbufAnimation *pbuf=create_pixbuf_animation("calling_anim.gif");
|
||||
GtkWidget *answer_button;
|
||||
GtkWidget *image;
|
||||
|
||||
gtk_label_set_markup(GTK_LABEL(status),_("<b>Incoming call</b>"));
|
||||
gtk_widget_show_all(linphone_gtk_get_widget(callview,"answer_decline_panel"));
|
||||
|
|
@ -153,14 +210,17 @@ void linphone_gtk_in_call_view_set_incoming(LinphoneCall *call, bool_t with_paus
|
|||
display_peer_name_in_label(callee,linphone_call_get_remote_address (call));
|
||||
|
||||
answer_button=linphone_gtk_get_widget(callview,"accept_call");
|
||||
gtk_button_set_image(GTK_BUTTON(answer_button),
|
||||
create_pixmap (linphone_gtk_get_ui_config("start_call_icon","startcall-green.png")));
|
||||
image=create_pixmap (linphone_gtk_get_ui_config("start_call_icon","startcall-green.png"));
|
||||
if (with_pause){
|
||||
gtk_button_set_label(GTK_BUTTON(answer_button),
|
||||
_("Pause all calls\nand answer"));
|
||||
}else gtk_button_set_label(GTK_BUTTON(answer_button),_("Answer"));
|
||||
gtk_button_set_image(GTK_BUTTON(linphone_gtk_get_widget(callview,"decline_call")),
|
||||
create_pixmap (linphone_gtk_get_ui_config("stop_call_icon","stopcall-red.png")));
|
||||
gtk_button_set_image(GTK_BUTTON(answer_button),image);
|
||||
gtk_widget_show(image);
|
||||
|
||||
image=create_pixmap (linphone_gtk_get_ui_config("stop_call_icon","stopcall-red.png"));
|
||||
gtk_button_set_image(GTK_BUTTON(linphone_gtk_get_widget(callview,"decline_call")),image);
|
||||
gtk_widget_show(image);
|
||||
|
||||
if (pbuf!=NULL){
|
||||
gtk_image_set_from_animation(GTK_IMAGE(animation),pbuf);
|
||||
|
|
|
|||
|
|
@ -1,147 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 2.16 -->
|
||||
<!-- interface-naming-policy toplevel-contextual -->
|
||||
<object class="GtkDialog" id="incoming_call">
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="border_width">5</property>
|
||||
<property name="type">popup</property>
|
||||
<property name="title" translatable="yes">Linphone - Incoming call</property>
|
||||
<property name="window_position">center-on-parent</property>
|
||||
<property name="icon">linphone2.png</property>
|
||||
<property name="type_hint">notification</property>
|
||||
<property name="urgency_hint">True</property>
|
||||
<property name="deletable">False</property>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkVBox" id="dialog-vbox8">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkFrame" id="frame16">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<child>
|
||||
<object class="GtkAlignment" id="alignment16">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="left_padding">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="message">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">Incoming call from</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="label43">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">Incoming call</property>
|
||||
<property name="use_markup">True</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkHButtonBox" id="dialog-action_area7">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="layout_style">spread</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="accept_call">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<signal handler="linphone_gtk_accept_call" name="clicked"/>
|
||||
<child>
|
||||
<object class="GtkHBox" id="hbox17">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image12">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-yes</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label44">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">Accept</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="decline_cal">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<signal handler="linphone_gtk_decline_call" name="clicked"/>
|
||||
<child>
|
||||
<object class="GtkHBox" id="hbox20">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="image13">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="stock">gtk-no</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="decline_call">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label" translatable="yes">Decline</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
|
|
@ -97,6 +97,7 @@ void linphone_gtk_in_call_view_set_incoming(LinphoneCall *call, bool_t with_paus
|
|||
void linphone_gtk_in_call_view_set_paused(LinphoneCall *call);
|
||||
void linphone_gtk_enable_mute_button(GtkButton *button, gboolean sensitive);
|
||||
void linphone_gtk_enable_hold_button(LinphoneCall *call, gboolean sensitive, gboolean holdon);
|
||||
void linphone_gtk_enable_transfer_button(LinphoneCore *lc, gboolean value);
|
||||
|
||||
void linphone_gtk_show_login_frame(LinphoneProxyConfig *cfg);
|
||||
void linphone_gtk_exit_login_frame(void);
|
||||
|
|
|
|||
|
|
@ -689,6 +689,7 @@ static void linphone_gtk_update_call_buttons(LinphoneCall *call){
|
|||
bool_t start_active=TRUE;
|
||||
bool_t stop_active=FALSE;
|
||||
bool_t add_call=FALSE;
|
||||
int call_list_size=ms_list_size(calls);
|
||||
|
||||
if (calls==NULL){
|
||||
start_active=TRUE;
|
||||
|
|
@ -699,7 +700,7 @@ static void linphone_gtk_update_call_buttons(LinphoneCall *call){
|
|||
start_active=TRUE;
|
||||
add_call=TRUE;
|
||||
}else if (call!=NULL && linphone_call_get_state(call)==LinphoneCallIncomingReceived && all_other_calls_paused(call,calls)){
|
||||
if (ms_list_size(calls)>1){
|
||||
if (call_list_size>1){
|
||||
start_active=TRUE;
|
||||
add_call=TRUE;
|
||||
}else{
|
||||
|
|
@ -724,6 +725,7 @@ static void linphone_gtk_update_call_buttons(LinphoneCall *call){
|
|||
GTK_BUTTON(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"main_mute")),
|
||||
FALSE);
|
||||
}
|
||||
linphone_gtk_enable_transfer_button(lc,call_list_size>1);
|
||||
update_video_title();
|
||||
}
|
||||
|
||||
|
|
@ -1444,6 +1446,7 @@ int main(int argc, char *argv[]){
|
|||
|
||||
settings=gtk_settings_get_default();
|
||||
g_type_class_unref (g_type_class_ref (GTK_TYPE_IMAGE_MENU_ITEM));
|
||||
g_type_class_unref (g_type_class_ref (GTK_TYPE_BUTTON));
|
||||
g_object_set(settings, "gtk-menu-images", TRUE, NULL);
|
||||
g_object_set(settings, "gtk-button-images", TRUE, NULL);
|
||||
#ifdef WIN32
|
||||
|
|
|
|||
|
|
@ -1401,6 +1401,8 @@
|
|||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
|
|
|||
|
|
@ -21,9 +21,10 @@ package org.linphone.core;
|
|||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* Object representing a Call. calls are created using {@link LinphoneCore#invite(LinphoneAddress)} or paased to the application by listener {@link LinphoneCoreListener#callState(LinphoneCore, LinphoneCall, State, String)}
|
||||
* Object representing a Call. calls are created using {@link LinphoneCore#invite(LinphoneAddress)} or passed to the application by listener {@link LinphoneCoreListener#callState(LinphoneCore, LinphoneCall, State, String)}
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public interface LinphoneCall {
|
||||
/**
|
||||
* Linphone call states
|
||||
|
|
@ -109,7 +110,11 @@ public interface LinphoneCall {
|
|||
* The remote accepted the call update initiated by us
|
||||
*/
|
||||
public static final State CallUpdated = new State(17, "CallUpdated");
|
||||
|
||||
|
||||
/**
|
||||
* The call object is now released.
|
||||
*/
|
||||
public static final State CallReleased = new State(18,"CallReleased");
|
||||
|
||||
private State(int value,String stringValue) {
|
||||
mValue = value;
|
||||
|
|
@ -150,9 +155,32 @@ public interface LinphoneCall {
|
|||
**/
|
||||
public LinphoneCallLog getCallLog();
|
||||
|
||||
/**
|
||||
* @return parameters for this call; read only, call copy() to get a read/write version.
|
||||
*/
|
||||
public LinphoneCallParams getCurrentParamsReadOnly();
|
||||
public LinphoneCallParams getCurrentParamsCopy();
|
||||
|
||||
public void enableCamera(boolean enabled);
|
||||
/**
|
||||
* Enables or disable echo cancellation.
|
||||
* @param enable
|
||||
*/
|
||||
public void enableEchoCancellation(boolean enable);
|
||||
/**
|
||||
* get EC status
|
||||
* @return true if echo cancellation is enabled.
|
||||
*/
|
||||
public boolean isEchoCancellationEnabled();
|
||||
/**
|
||||
* Enables or disable echo limiter cancellation.
|
||||
* @param enable
|
||||
*/
|
||||
public void enableEchoLimiter(boolean enable);
|
||||
/**
|
||||
* get EL status
|
||||
* @return true if echo limiter is enabled.
|
||||
*/
|
||||
public boolean isEchoLimiterEnabled();
|
||||
/**
|
||||
* Returns the object associated to a call this one is replacing.
|
||||
* Call replacement can occur during transfer scenarios.
|
||||
*/
|
||||
public LinphoneCall getReplacedCall();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ package org.linphone.core;
|
|||
import java.util.Vector;
|
||||
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public interface LinphoneCallLog {
|
||||
/**
|
||||
* Represents call status
|
||||
|
|
|
|||
|
|
@ -28,5 +28,10 @@ package org.linphone.core;
|
|||
public interface LinphoneCallParams {
|
||||
void setVideoEnabled(boolean b);
|
||||
boolean getVideoEnabled();
|
||||
LinphoneCallParams copy();
|
||||
|
||||
/**
|
||||
* @param value 0 to disable limitation
|
||||
*/
|
||||
void setAudioBandwidth(int value);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,11 +25,12 @@ import java.util.Vector;
|
|||
* Linphone core main object created by method {@link LinphoneCoreFactory#createLinphoneCore(LinphoneCoreListener, String, String, Object)}.
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public interface LinphoneCore {
|
||||
/**
|
||||
* linphone core states
|
||||
*/
|
||||
static public class GlobalState {
|
||||
static public class GlobalState {
|
||||
static private Vector values = new Vector();
|
||||
/**
|
||||
* Off
|
||||
|
|
@ -72,28 +73,28 @@ public interface LinphoneCore {
|
|||
* Describes proxy registration states.
|
||||
*
|
||||
*/
|
||||
static public class RegistrationState {
|
||||
static private Vector values = new Vector();
|
||||
static public class RegistrationState {
|
||||
private static Vector values = new Vector();
|
||||
/**
|
||||
* None
|
||||
*/
|
||||
static public RegistrationState RegistrationNone = new RegistrationState(0,"RegistrationNone");
|
||||
public static RegistrationState RegistrationNone = new RegistrationState(0,"RegistrationNone");
|
||||
/**
|
||||
* In Progress
|
||||
*/
|
||||
static public RegistrationState RegistrationProgress = new RegistrationState(1,"RegistrationProgress");
|
||||
public static RegistrationState RegistrationProgress = new RegistrationState(1,"RegistrationProgress");
|
||||
/**
|
||||
* Ok
|
||||
*/
|
||||
static public RegistrationState RegistrationOk = new RegistrationState(2,"RegistrationOk");
|
||||
public static RegistrationState RegistrationOk = new RegistrationState(2,"RegistrationOk");
|
||||
/**
|
||||
* Cleared
|
||||
*/
|
||||
static public RegistrationState RegistrationCleared = new RegistrationState(3,"RegistrationCleared");
|
||||
public static RegistrationState RegistrationCleared = new RegistrationState(3,"RegistrationCleared");
|
||||
/**
|
||||
* Failed
|
||||
*/
|
||||
static public RegistrationState RegistrationFailed = new RegistrationState(4,"RegistrationFailed");
|
||||
public static RegistrationState RegistrationFailed = new RegistrationState(4,"RegistrationFailed");
|
||||
private final int mValue;
|
||||
private final String mStringValue;
|
||||
|
||||
|
|
@ -118,7 +119,7 @@ public interface LinphoneCore {
|
|||
* Describes firewall policy.
|
||||
*
|
||||
*/
|
||||
static public class FirewallPolicy {
|
||||
static public class FirewallPolicy {
|
||||
static private Vector values = new Vector();
|
||||
/**
|
||||
* No firewall is assumed.
|
||||
|
|
@ -178,6 +179,50 @@ public interface LinphoneCore {
|
|||
return mStringValue;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* EC Calibrator Status
|
||||
.
|
||||
*
|
||||
*/
|
||||
static public class EcCalibratorStatus {
|
||||
|
||||
static private Vector values = new Vector();
|
||||
/**
|
||||
* Calibration in progress
|
||||
*/
|
||||
static public EcCalibratorStatus InProgress = new EcCalibratorStatus(0,"InProgress");
|
||||
/**
|
||||
* Calibration done
|
||||
*/
|
||||
static public EcCalibratorStatus Done = new EcCalibratorStatus(1,"Done");
|
||||
/**
|
||||
* Calibration in progress
|
||||
*/
|
||||
static public EcCalibratorStatus Failed = new EcCalibratorStatus(2,"Failed");
|
||||
|
||||
private final int mValue;
|
||||
private final String mStringValue;
|
||||
|
||||
private EcCalibratorStatus(int value,String stringValue) {
|
||||
mValue = value;
|
||||
values.addElement(this);
|
||||
mStringValue=stringValue;
|
||||
}
|
||||
public static EcCalibratorStatus fromInt(int value) {
|
||||
|
||||
for (int i=0; i<values.size();i++) {
|
||||
EcCalibratorStatus status = (EcCalibratorStatus) values.elementAt(i);
|
||||
if (status.mValue == value) return status;
|
||||
}
|
||||
throw new RuntimeException("status not found ["+value+"]");
|
||||
}
|
||||
public String toString() {
|
||||
return mStringValue;
|
||||
}
|
||||
public int value(){
|
||||
return mValue;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* clear all added proxy configs
|
||||
*/
|
||||
|
|
@ -298,12 +343,12 @@ public interface LinphoneCore {
|
|||
* @param network state
|
||||
*
|
||||
*/
|
||||
public void setNetworkStateReachable(boolean isReachable);
|
||||
public void setNetworkReachable(boolean isReachable);
|
||||
/**
|
||||
*
|
||||
* @return if false, there is no network connection.
|
||||
*/
|
||||
public boolean getNetworkStateReachable();
|
||||
public boolean isNetworkReachable();
|
||||
/**
|
||||
* destroy linphone core and free all underlying resources
|
||||
*/
|
||||
|
|
@ -492,4 +537,22 @@ public interface LinphoneCore {
|
|||
public void setPreferredVideoSize(VideoSize vSize);
|
||||
|
||||
public VideoSize getPreferredVideoSize();
|
||||
|
||||
public PayloadType[] listVideoCodecs();
|
||||
/**
|
||||
* enable signaling keep alive. small udp packet sent periodically to keep udp NAT association
|
||||
*/
|
||||
void enableKeepAlive(boolean enable);
|
||||
/**
|
||||
* get keep elive mode
|
||||
* @return true if enable
|
||||
*/
|
||||
boolean isKeepAliveEnabled();
|
||||
/**
|
||||
* Start an echo calibration of the sound devices, in order to find adequate settings for the echo canceler automatically.
|
||||
* status is notified to {@link LinphoneCoreListener#ecCalibrationStatus(EcCalibratorStatus, int, Object)}
|
||||
* @param User object
|
||||
* @throws LinphoneCoreException if operation is still in progress;
|
||||
**/
|
||||
void startEchoCalibration(Object data) throws LinphoneCoreException;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ package org.linphone.core;
|
|||
|
||||
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
abstract public class LinphoneCoreFactory {
|
||||
|
||||
private static String factoryName = "org.linphone.core.LinphoneCoreFactoryImpl";
|
||||
|
|
|
|||
|
|
@ -78,5 +78,14 @@ public interface LinphoneCoreListener {
|
|||
* @param message incoming message
|
||||
*/
|
||||
public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from,String message);
|
||||
/**
|
||||
* Invoked when echo cancalation calibration is completed
|
||||
* @param lc LinphoneCore
|
||||
* @param status
|
||||
* @param delay_ms echo delay
|
||||
* @param data
|
||||
*/
|
||||
void ecCalibrationStatus(LinphoneCore lc,LinphoneCore.EcCalibratorStatus status, int delay_ms, Object data);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import java.util.Vector;
|
|||
*
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public interface LinphoneFriend {
|
||||
/**
|
||||
* Enum controlling behavior for incoming subscription request.
|
||||
|
|
|
|||
|
|
@ -112,5 +112,25 @@ public interface LinphoneProxyConfig {
|
|||
* @return the route set for this proxy configuration.
|
||||
*/
|
||||
public String getRoute();
|
||||
/**
|
||||
* Indicates either or not, PUBLISH must be issued for this #LinphoneProxyConfig .
|
||||
* <br> In case this #LinphoneProxyConfig has been added to #LinphoneCore, follows the linphone_proxy_config_edit() rule.
|
||||
* @param obj object pointer
|
||||
* @param val if true, publish will be engaged
|
||||
*
|
||||
*/
|
||||
public void enablePublish(boolean enable);
|
||||
/**
|
||||
* returns publish state for this proxy config (see {@link #enablePublish(boolean)} )
|
||||
*/
|
||||
public boolean publishEnabled();
|
||||
|
||||
|
||||
LinphoneCore.RegistrationState getState();
|
||||
|
||||
/**
|
||||
* Sets the registration expiration time.
|
||||
* @param delay expiration time in seconds
|
||||
*/
|
||||
void setExpires(int delay);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import java.util.Vector;
|
|||
* Enum describing remote friend status
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class OnlineStatus {
|
||||
|
||||
static private Vector values = new Vector();
|
||||
|
|
|
|||
|
|
@ -20,4 +20,5 @@ package org.linphone.core;
|
|||
|
||||
public interface PayloadType {
|
||||
|
||||
String getMime();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,29 +25,27 @@ public final class VideoSize {
|
|||
public static final int QCIF = 0;
|
||||
public static final int CIF = 1;
|
||||
public static final int HVGA = 2;
|
||||
public static final int QVGA = 3;
|
||||
|
||||
private int width;
|
||||
public int getWidth() {return width;}
|
||||
public void setWidth(int width) {this.width = width;}
|
||||
|
||||
private int height;
|
||||
public int getHeight() {return height;}
|
||||
public void setHeight(int height) {this.height = height;}
|
||||
public int width;
|
||||
public int height;
|
||||
|
||||
public VideoSize() {}
|
||||
private VideoSize(int width, int height) {
|
||||
public VideoSize(int width, int height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public static final VideoSize createStandard(int code) {
|
||||
public static final VideoSize createStandard(int code, boolean inverted) {
|
||||
switch (code) {
|
||||
case QCIF:
|
||||
return new VideoSize(176, 144);
|
||||
return inverted? new VideoSize(144, 176) : new VideoSize(176, 144);
|
||||
case CIF:
|
||||
return new VideoSize(352, 288);
|
||||
return inverted? new VideoSize(288, 352) : new VideoSize(352, 288);
|
||||
case HVGA:
|
||||
return new VideoSize(320, 480);
|
||||
return inverted? new VideoSize(320,480) : new VideoSize(480, 320);
|
||||
case QVGA:
|
||||
return inverted? new VideoSize(240, 320) : new VideoSize(320, 240);
|
||||
default:
|
||||
return new VideoSize(); // Invalid one
|
||||
}
|
||||
|
|
@ -80,5 +78,15 @@ public final class VideoSize {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "width = "+width + " height = " + height;
|
||||
}
|
||||
public boolean isPortrait() {
|
||||
return height >= width;
|
||||
}
|
||||
public VideoSize createInverted() {
|
||||
return new VideoSize(height, width);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
package org.linphone.core;
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class LinphoneCoreException extends Exception {
|
||||
|
||||
public LinphoneCoreException() {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
./bin/avcodec-52.dll
|
||||
./bin/avformat-52.dll
|
||||
./bin/avutil-50.dll
|
||||
./bin/libeXosip2-4.dll
|
||||
./bin/libeXosip2-6.dll
|
||||
./bin/libogg.dll
|
||||
./bin/libtheora.dll
|
||||
./bin/libxml2-2.dll
|
||||
./bin/libosip2-4.dll
|
||||
./bin/libosipparser2-4.dll
|
||||
./bin/libosip2-6.dll
|
||||
./bin/libosipparser2-6.dll
|
||||
./bin/swscale-0.dll
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 28a6e7f22fbdd93a01676fc9cc47a2605c846d75
|
||||
Subproject commit b9a6dad7339175e894d1a0f291ccb5d1143e3199
|
||||
2
oRTP
2
oRTP
|
|
@ -1 +1 @@
|
|||
Subproject commit 7faf69b5eb260ae82ef1efbc49713ccedac7d737
|
||||
Subproject commit 4e61d05db02318f44768458a69f29faec75c94c8
|
||||
|
|
@ -73,3 +73,6 @@ mediastreamer2/src/itc.c
|
|||
mediastreamer2/src/extdisplay.c
|
||||
mediastreamer2/src/msiounit.c
|
||||
mediastreamer2/src/x11video.c
|
||||
mediastreamer2/src/msandroid.cpp
|
||||
mediastreamer2/src/msandroidvideo.cpp
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
|
||||
gtk/p2pwizard.ui
|
||||
|
|
|
|||
1401
po/pt_BR.po
1401
po/pt_BR.po
File diff suppressed because it is too large
Load diff
2018
po/zh_CN.po
2018
po/zh_CN.po
File diff suppressed because it is too large
Load diff
|
|
@ -8,7 +8,7 @@ LINPHONE_RINGS=rings/orig.wav \
|
|||
rings/oldphone-mono-30s.caf \
|
||||
rings/rock.wav \
|
||||
rings/bigben.wav \
|
||||
rings/toy.wav \
|
||||
rings/toy-mono.wav \
|
||||
rings/sweet.wav \
|
||||
rings/synth.wav \
|
||||
rings/tapping.wav
|
||||
|
|
|
|||
BIN
share/rings/toy-mono.wav
Normal file
BIN
share/rings/toy-mono.wav
Normal file
Binary file not shown.
Binary file not shown.
Loading…
Add table
Reference in a new issue