diff --git a/.cproject b/.cproject
index 8f37d4ae1..f4c0aff9b 100644
--- a/.cproject
+++ b/.cproject
@@ -39,6 +39,7 @@
+
diff --git a/.gitignore b/.gitignore
index 93f145c5a..b262a4641 100644
--- a/.gitignore
+++ b/.gitignore
@@ -55,12 +55,18 @@ coreapi/help/realtimetext_sender
coreapi/test_ecc
coreapi/test_lsd
gtk/version_date.h
+daemon/linphone-daemon
+daemon/linphone-daemon-pipetest
+*.la
+*.lo
+*.deps
+*.libs
+share/certdata.txt
+coreapi/test_numbers
specs.c
*.orig
*.rej
*.kdev4
-*.lo
-*.la
*.swp
.deps
.libs
@@ -69,7 +75,6 @@ tools/test_lsd
tools/test_numbers
coreapi/help/notify
share/fresh-rootca.pem
-share/certdata.txt
tester/liblinphone_tester
tools/lp-gen-wrappers
tools/lpc2xml_test
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 69759f76b..f8f184fba 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -105,7 +105,7 @@ if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS)
else()
find_package(BelleSIP REQUIRED)
find_package(Mediastreamer2 REQUIRED)
- find_package(BcToolbox REQUIRED OPTIONAL_COMPONENTS tester)
+ find_package(BcToolbox 0.0.3 REQUIRED OPTIONAL_COMPONENTS tester)
endif()
find_package(XML2 REQUIRED)
find_package(Zlib)
diff --git a/Makefile.am b/Makefile.am
index 18d95f563..7960711f0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,8 +4,7 @@
ACLOCAL_AMFLAGS = -I m4 $(ACLOCAL_MACOS_FLAGS)
SUBDIRS = build m4 pixmaps po @ORTP_DIR@ @MS2_DIR@ \
- coreapi console gtk share scripts tools tester include
-
+ coreapi console gtk share scripts tools daemon tester include
GITVERSION=`cd $(top_srcdir) && git describe --always || echo $(VERSION)`
@@ -62,6 +61,30 @@ EXTRA_DIST = BUGS \
$(LINPHONEDEPS_FILELIST) \
$(ISS_SCRIPT).in
+EXTRA_DIST += CMakeLists.txt \
+cmake/FindGtkMacIntegration.cmake \
+cmake/FindIconv.cmake \
+cmake/FindIntl.cmake \
+cmake/FindNotify.cmake \
+cmake/FindSqlite3.cmake \
+cmake/FindXML2.cmake \
+cmake/FindZlib.cmake \
+cmake/LinphoneConfig.cmake.in \
+config.h.cmake \
+console/CMakeLists.txt \
+coreapi/CMakeLists.txt \
+coreapi/gitversion.cmake \
+coreapi/help/CMakeLists.txt \
+gtk/CMakeLists.txt \
+java/CMakeLists.txt \
+pixmaps/CMakeLists.txt \
+po/CMakeLists.txt \
+share/CMakeLists.txt \
+share/rings/CMakeLists.txt \
+share/rootca.cmake \
+tester/CMakeLists.txt \
+tools/CMakeLists.txt
+
DISTCLEANFILES= $(ISS_SCRIPT) $(PACKAGE_WIN32_FILELIST)
CLEANFILES=Portfile Portfile-devel
diff --git a/build/Makefile.am b/build/Makefile.am
index 84ac3e909..8145474f1 100644
--- a/build/Makefile.am
+++ b/build/Makefile.am
@@ -1,2 +1,4 @@
SUBDIRS=macos
+EXTRA_DIST = openembedded
+
diff --git a/build/openembedded/README b/build/openembedded/README
new file mode 100644
index 000000000..ec505a9c3
--- /dev/null
+++ b/build/openembedded/README
@@ -0,0 +1,57 @@
+Recipes for open embedded: http://www.openembedded.org
+
+Documentations:
+http://docs.openembedded.org/usermanual/
+http://bitbake.berlios.de/manual/
+
+
+
+Instructions for compilation from sources: (requires 10 Go of free space)
+- Choose a distribution and build it.
+ For example, to build Angstrom follow the guide at http://www.angstrom-distribution.org/building-angstrom
+ For IGEPv2 use environment variable MACHINE=igep0020
+ It is possible to use MACHINE=qemuarm to build an image that can be run on a computer with qemu.
+
+- Add linphone recipes to the pool with an higher priority:
+ Edit conf/bblayers.conf to set EXTRALAYERS to point to the source repository of linphone. Search the EXTRALAYERS definition in conf/bblayers.conf
+ and modify it like this:
+
+ # Add your overlay location to EXTRALAYERS
+ # Make sure to have a conf/layers.conf in there
+ EXTRALAYERS ?= "/home/smorlat/sources/git/linphone-daemon/build/openembedded"
+
+ This additional layer gives access to the various linphone recipes but also to a recipe to build an entire image containing linphone.
+ To build this image based on the generic console image you will need to use:
+ bitbake console-linphone-image
+
+
+- Prepare compilation
+ Source appropriate environment with "~/.oe/enviro*"
+ Change directory to where you launched Angstrom install script.
+
+- Compile linphone
+ bitbake -c clean linphone
+ bitbake linphone
+
+- If you want additional codecs (e.g. iLBC or AMR) compile linphone-plugins
+ bitbake -c clean linphone-plugins
+ bitbake linphone-plugins
+
+- Find the generated packages "*.ipk"
+ Example: /Data/work/angstrom/angstrom-setup-scripts/build/tmp-angstrom_2008_1/deploy/glibc/ipk/armv7a/
+
+
+
+
+Installation
+- check network connectivity
+ * ping linphone.org
+ * see "route -n"
+ * see "/etc/resolv.conf"
+- update package list
+ * opkg update
+- copy ipk files to install to /tmp
+- eventually remove previously installed packages
+- install with "opkg install libortp*.ipk libmediastreamer*.ipk liblinphone*.ipk linphonec*.ipk"
+
+
diff --git a/build/openembedded/antlr3/antlr3c.inc b/build/openembedded/antlr3/antlr3c.inc
new file mode 100644
index 000000000..e13b73088
--- /dev/null
+++ b/build/openembedded/antlr3/antlr3c.inc
@@ -0,0 +1,15 @@
+DESCRIPTION = "Linphone version of antlr3"
+LICENSE = "GPL"
+
+PROVIDES = "antlr3c antlr3c-dev"
+ALLOW_EMPTY_${PN} = "1"
+
+S = "${WORKDIR}/git/runtime/C"
+
+inherit autotools pkgconfig lib_package
+
+do_fetch_append() {
+ import os
+ os.system("autogen.sh")
+}
+
diff --git a/build/openembedded/antlr3/antlr3c_linphone.bb b/build/openembedded/antlr3/antlr3c_linphone.bb
new file mode 100644
index 000000000..1c090ffab
--- /dev/null
+++ b/build/openembedded/antlr3/antlr3c_linphone.bb
@@ -0,0 +1,7 @@
+require antlr3c.inc
+
+SRCREV="f0dbcbbcd22a7fd9a479ff68d4daa9225fb2f3b1"
+PR="R3"
+SRC_URI = "git://git.linphone.org/antlr3.git"
+
+LIC_FILES_CHKSUM= "file://COPYING;md5=13c502aaa9b2ca91d01a3aae44d899b4"
diff --git a/build/openembedded/belle-sip/belle-sip.inc b/build/openembedded/belle-sip/belle-sip.inc
new file mode 100644
index 000000000..a57e4e41a
--- /dev/null
+++ b/build/openembedded/belle-sip/belle-sip.inc
@@ -0,0 +1,15 @@
+DESCRIPTION = "SIP stack from Belledonne Communications"
+LICENSE = "GPL"
+
+DEPENDS_${PN} = "polarssl-dev antlr3c-dev"
+DEPENDS = "polarssl-dev antlr3c-dev"
+RDEPENDS_${PN} = "polarssl-dev antlr3c-dev"
+
+EXTRA_OECONF += "--disable-strict --with-antlr=${STAGING_DIR_HOST}${layout_exec_prefix}/usr --with-polarssl=${STAGING_DIR_HOST}${layout_exec_prefix}/usr"
+INSANE_SKIP_belle-sip += "dev-deps"
+
+inherit autotools pkgconfig
+
+do_autoreconf () {
+ ./autogen.sh
+}
diff --git a/build/openembedded/belle-sip/belle-sip_master.bb b/build/openembedded/belle-sip/belle-sip_master.bb
new file mode 100644
index 000000000..f0f843543
--- /dev/null
+++ b/build/openembedded/belle-sip/belle-sip_master.bb
@@ -0,0 +1,10 @@
+require belle-sip.inc
+
+SRCREV="af93922ac91cf3cbf5ceed0328bf43d08d37714e"
+S = "${WORKDIR}/git"
+
+PR="R1"
+
+
+SRC_URI = "git://git.linphone.org/belle-sip.git;commit=${SRCREV}"
+LIC_FILES_CHKSUM = "file://COPYING;md5=9f9938e31db89d55a796e86808c96848"
diff --git a/build/openembedded/conf/layer.conf b/build/openembedded/conf/layer.conf
new file mode 100644
index 000000000..1b29844a8
--- /dev/null
+++ b/build/openembedded/conf/layer.conf
@@ -0,0 +1,9 @@
+# We have a conf and classes directory, append to BBPATH
+BBPATH .= ":${LAYERDIR}"
+
+# We have a recipes directory, add to BBFILES
+BBFILES += "${LAYERDIR}/*.bb ${LAYERDIR}/*/*.bb"
+
+BBFILE_COLLECTIONS += "linphone-layer"
+BBFILE_PATTERN_linphone-layer := "^${LAYERDIR}/"
+BBFILE_PRIORITY_linphone-layer = "50"
diff --git a/build/openembedded/files/igep0020/alsa_8khz.patch b/build/openembedded/files/igep0020/alsa_8khz.patch
new file mode 100644
index 000000000..17774d4e6
--- /dev/null
+++ b/build/openembedded/files/igep0020/alsa_8khz.patch
@@ -0,0 +1,13 @@
+--- linphone/mediastreamer2/src/alsa.c_orig 2011-05-24 12:39:33.824600109 +0200
++++ linphone/mediastreamer2/src/alsa.c 2011-05-24 12:40:04.760407404 +0200
+@@ -32,8 +32,8 @@
+ /*in case of troubles with a particular driver, try incrementing ALSA_PERIOD_SIZE
+ to 512, 1024, 2048, 4096...
+ then try incrementing the number of periods*/
+-#define ALSA_PERIODS 8
+-#define ALSA_PERIOD_SIZE 256
++#define ALSA_PERIODS 4
++#define ALSA_PERIOD_SIZE 512
+
+ /*uncomment the following line if you have problems with an alsa driver
+ having sound quality trouble:*/
diff --git a/build/openembedded/libgsm/libgsm-1.0.13/01_makefile.patch b/build/openembedded/libgsm/libgsm-1.0.13/01_makefile.patch
new file mode 100644
index 000000000..947db37bf
--- /dev/null
+++ b/build/openembedded/libgsm/libgsm-1.0.13/01_makefile.patch
@@ -0,0 +1,71 @@
+diff -urNad libgsm-1.0.12~/Makefile libgsm-1.0.12/Makefile
+--- libgsm-1.0.12~/Makefile 2007-11-01 15:37:52.000000000 +0100
++++ libgsm-1.0.12/Makefile 2007-11-01 15:43:06.000000000 +0100
+@@ -96,7 +96,7 @@
+ # Other tools
+
+ SHELL = /bin/sh
+-LN = ln
++LN = ln -s
+ BASENAME = basename
+ AR = ar
+ ARFLAGS = cr
+@@ -140,6 +140,7 @@
+ # Targets
+
+ LIBGSM = $(LIB)/libgsm.a
++LIBGSMSO= $(LIB)/libgsm.so
+
+ TOAST = $(BIN)/toast
+ UNTOAST = $(BIN)/untoast
+@@ -279,7 +280,7 @@
+
+ # Target rules
+
+-all: $(LIBGSM) $(TOAST) $(TCAT) $(UNTOAST)
++all: $(LIBGSM) $(LIBGSMSO) $(TOAST) $(TCAT) $(UNTOAST)
+ @-echo $(ROOT): Done.
+
+ tst: $(TST)/lin2cod $(TST)/cod2lin $(TOAST) $(TST)/test-result
+@@ -299,6 +300,11 @@
+
+ # The basic API: libgsm
+
++$(LIBGSMSO): $(LIB) $(GSM_OBJECTS)
++ $(LD) -o $@.1.0.12 -shared -Xlinker -soname -Xlinker libgsm.so.1 $(GSM_OBJECTS) -lc $(LDFLAGS)
++ ln -fs libgsm.so.1.0.12 lib/libgsm.so.1
++ ln -fs libgsm.so.1.0.12 lib/libgsm.so
++
+ $(LIBGSM): $(LIB) $(GSM_OBJECTS)
+ -rm $(RMFLAGS) $(LIBGSM)
+ $(AR) $(ARFLAGS) $(LIBGSM) $(GSM_OBJECTS)
+@@ -308,15 +314,15 @@
+ # Toast, Untoast and Tcat -- the compress-like frontends to gsm.
+
+ $(TOAST): $(BIN) $(TOAST_OBJECTS) $(LIBGSM)
+- $(LD) $(LFLAGS) -o $(TOAST) $(TOAST_OBJECTS) $(LIBGSM) $(LDLIB)
++ $(LD) $(LFLAGS) -o $(TOAST) $(TOAST_OBJECTS) $(LIBGSMSO) $(LDLIB)
+
+ $(UNTOAST): $(BIN) $(TOAST)
+ -rm $(RMFLAGS) $(UNTOAST)
+- $(LN) $(TOAST) $(UNTOAST)
++ $(LN) toast $(UNTOAST)
+
+ $(TCAT): $(BIN) $(TOAST)
+ -rm $(RMFLAGS) $(TCAT)
+- $(LN) $(TOAST) $(TCAT)
++ $(LN) toast $(TCAT)
+
+
+ # The local bin and lib directories
+@@ -426,7 +432,9 @@
+
+ clean: semi-clean
+ -rm $(RMFLAGS) $(LIBGSM) $(ADDTST)/add \
+- $(TOAST) $(TCAT) $(UNTOAST) \
++ $(LIBGSMSO) $(LIB)/libgsm.so.1.0.12 \
++ $(LIB)libgsm.so.1 \
++ $(TOAST) $(TCAT) $(UNTOAST) \
+ $(ROOT)/gsm-1.0.tar.Z
+
+
diff --git a/build/openembedded/libgsm/libgsm-1.0.13/02_cplusplus.patch b/build/openembedded/libgsm/libgsm-1.0.13/02_cplusplus.patch
new file mode 100644
index 000000000..a4bbb4067
--- /dev/null
+++ b/build/openembedded/libgsm/libgsm-1.0.13/02_cplusplus.patch
@@ -0,0 +1,25 @@
+diff -urNad libgsm-1.0.10~/inc/gsm.h libgsm-1.0.10/inc/gsm.h
+--- libgsm-1.0.10~/inc/gsm.h 2007-11-01 15:37:52.000000000 +0100
++++ libgsm-1.0.10/inc/gsm.h 2007-11-01 15:44:52.000000000 +0100
+@@ -54,6 +54,10 @@
+ #define GSM_OPT_FRAME_INDEX 5
+ #define GSM_OPT_FRAME_CHAIN 6
+
++#ifdef __cplusplus
++extern "C" {
++#endif
++
+ extern gsm gsm_create GSM_P((void));
+ extern void gsm_destroy GSM_P((gsm));
+
+@@ -66,6 +70,10 @@
+ extern int gsm_explode GSM_P((gsm, gsm_byte *, gsm_signal *));
+ extern void gsm_implode GSM_P((gsm, gsm_signal *, gsm_byte *));
+
++#ifdef __cplusplus
++}
++#endif
++
+ #undef GSM_P
+
+ #endif /* GSM_H */
diff --git a/build/openembedded/libgsm/libgsm-1.0.13/03_config.patch b/build/openembedded/libgsm/libgsm-1.0.13/03_config.patch
new file mode 100644
index 000000000..dad241e2b
--- /dev/null
+++ b/build/openembedded/libgsm/libgsm-1.0.13/03_config.patch
@@ -0,0 +1,154 @@
+diff -urNad libgsm-1.0.10~/Makefile libgsm-1.0.10/Makefile
+--- libgsm-1.0.10~/Makefile 2007-11-01 15:37:52.000000000 +0100
++++ libgsm-1.0.10/Makefile 2007-11-01 15:48:02.000000000 +0100
+@@ -151,7 +151,7 @@
+
+ HEADERS = $(INC)/proto.h \
+ $(INC)/unproto.h \
+- $(INC)/config.h \
++ $(INC)/gsm_config.h \
+ $(INC)/private.h \
+ $(INC)/gsm.h \
+ $(INC)/toast.h \
+diff -urNad libgsm-1.0.10~/inc/config.h libgsm-1.0.10/inc/config.h
+--- libgsm-1.0.10~/inc/config.h 2007-11-01 15:37:52.000000000 +0100
++++ libgsm-1.0.10/inc/config.h 1970-01-01 01:00:00.000000000 +0100
+@@ -1,37 +0,0 @@
+-/*
+- * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+- * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
+- * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+- */
+-
+-/*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/config.h,v 1.5 1996/07/02 11:26:20 jutta Exp $*/
+-
+-#ifndef CONFIG_H
+-#define CONFIG_H
+-
+-/*efine SIGHANDLER_T int /* signal handlers are void */
+-/*efine HAS_SYSV_SIGNAL 1 /* sigs not blocked/reset? */
+-
+-#define HAS_STDLIB_H 1 /* /usr/include/stdlib.h */
+-#define HAS_LIMITS_H 1 /* /usr/include/limits.h */
+-#define HAS_FCNTL_H 1 /* /usr/include/fcntl.h */
+-#define HAS_ERRNO_DECL 1 /* errno.h declares errno */
+-
+-#define HAS_FSTAT 1 /* fstat syscall */
+-#define HAS_FCHMOD 1 /* fchmod syscall */
+-#define HAS_CHMOD 1 /* chmod syscall */
+-#define HAS_FCHOWN 1 /* fchown syscall */
+-#define HAS_CHOWN 1 /* chown syscall */
+-/*efine HAS__FSETMODE 1 /* _fsetmode -- set file mode */
+-
+-#define HAS_STRING_H 1 /* /usr/include/string.h */
+-/*efine HAS_STRINGS_H 1 /* /usr/include/strings.h */
+-
+-#define HAS_UNISTD_H 1 /* /usr/include/unistd.h */
+-#define HAS_UTIME 1 /* POSIX utime(path, times) */
+-/*efine HAS_UTIMES 1 /* use utimes() syscall instead */
+-#define HAS_UTIME_H 1 /* UTIME header file */
+-#define HAS_UTIMBUF 1 /* struct utimbuf */
+-/*efine HAS_UTIMEUSEC 1 /* microseconds in utimbuf? */
+-
+-#endif /* CONFIG_H */
+diff -urNad libgsm-1.0.10~/inc/gsm_config.h libgsm-1.0.10/inc/gsm_config.h
+--- libgsm-1.0.10~/inc/gsm_config.h 1970-01-01 01:00:00.000000000 +0100
++++ libgsm-1.0.10/inc/gsm_config.h 2007-11-01 15:46:19.000000000 +0100
+@@ -0,0 +1,37 @@
++/*
++ * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
++ * Universitaet Berlin. See the accompanying file "COPYRIGHT" for
++ * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
++ */
++
++/*$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/config.h,v 1.5 1996/07/02 11:26:20 jutta Exp $*/
++
++#ifndef CONFIG_H
++#define CONFIG_H
++
++/*efine SIGHANDLER_T int -* signal handlers are void */
++/*efine HAS_SYSV_SIGNAL 1 -* sigs not blocked/reset? */
++
++#define HAS_STDLIB_H 1 /* /usr/include/stdlib.h */
++#define HAS_STDIO_H 1 /* /usr/include/stdio.h */
++/*efine HAS_LIMITS_H 1 -* /usr/include/limits.h */
++#define HAS_FCNTL_H 1 /* /usr/include/fcntl.h */
++
++#define HAS_FSTAT 1 /* fstat syscall */
++#define HAS_FCHMOD 1 /* fchmod syscall */
++#define HAS_CHMOD 1 /* chmod syscall */
++#define HAS_FCHOWN 1 /* fchown syscall */
++#define HAS_CHOWN 1 /* chown syscall */
++/*efine HAS__FSETMODE 1 -* _fsetmode -- set file mode */
++
++#define HAS_STRING_H 1 /* /usr/include/string.h */
++/*efine HAS_STRINGS_H 1 -* /usr/include/strings.h */
++
++#define HAS_UNISTD_H 1 /* /usr/include/unistd.h */
++#define HAS_UTIME 1 /* POSIX utime(path, times) */
++/*efine HAS_UTIMES 1 -* use utimes() syscall instead */
++#define HAS_UTIME_H 1 /* UTIME header file */
++/*efine HAS_UTIMBUF 1 -* struct utimbuf */
++/*efine HAS_UTIMEUSEC 1 -* microseconds in utimbuf? */
++
++#endif /* CONFIG_H */
+diff -urNad libgsm-1.0.10~/inc/toast.h libgsm-1.0.10/inc/toast.h
+--- libgsm-1.0.10~/inc/toast.h 2007-11-01 15:37:52.000000000 +0100
++++ libgsm-1.0.10/inc/toast.h 2007-11-01 15:48:17.000000000 +0100
+@@ -9,7 +9,7 @@
+ #ifndef TOAST_H
+ #define TOAST_H /* Guard against multiple includes */
+
+-#include "config.h"
++#include "gsm_config.h"
+
+ #include
+ #include
+diff -urNad libgsm-1.0.10~/src/code.c libgsm-1.0.10/src/code.c
+--- libgsm-1.0.10~/src/code.c 2007-11-01 15:37:52.000000000 +0100
++++ libgsm-1.0.10/src/code.c 2007-11-01 15:48:34.000000000 +0100
+@@ -6,7 +6,7 @@
+
+ /* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/code.c,v 1.3 1996/07/02 09:59:05 jutta Exp $ */
+
+-#include "config.h"
++#include "gsm_config.h"
+
+
+ #ifdef HAS_STDLIB_H
+diff -urNad libgsm-1.0.10~/src/gsm_create.c libgsm-1.0.10/src/gsm_create.c
+--- libgsm-1.0.10~/src/gsm_create.c 1996-07-02 16:32:44.000000000 +0200
++++ libgsm-1.0.10/src/gsm_create.c 2007-11-01 15:48:48.000000000 +0100
+@@ -6,7 +6,7 @@
+
+ static char const ident[] = "$Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_create.c,v 1.4 1996/07/02 09:59:05 jutta Exp $";
+
+-#include "config.h"
++#include "gsm_config.h"
+
+ #ifdef HAS_STRING_H
+ #include
+diff -urNad libgsm-1.0.10~/src/gsm_destroy.c libgsm-1.0.10/src/gsm_destroy.c
+--- libgsm-1.0.10~/src/gsm_destroy.c 1996-07-02 16:32:39.000000000 +0200
++++ libgsm-1.0.10/src/gsm_destroy.c 2007-11-01 15:48:57.000000000 +0100
+@@ -7,7 +7,7 @@
+ /* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/gsm_destroy.c,v 1.3 1994/11/28 19:52:25 jutta Exp $ */
+
+ #include "gsm.h"
+-#include "config.h"
++#include "gsm_config.h"
+ #include "proto.h"
+
+ #ifdef HAS_STDLIB_H
+diff -urNad libgsm-1.0.10~/tls/taste.c libgsm-1.0.10/tls/taste.c
+--- libgsm-1.0.10~/tls/taste.c 1996-07-02 16:33:05.000000000 +0200
++++ libgsm-1.0.10/tls/taste.c 2007-11-01 15:49:54.000000000 +0100
+@@ -10,7 +10,7 @@
+ #include
+ #include
+
+-#include "config.h"
++#include "gsm_config.h"
+
+ #ifdef HAS_STDLIB_H
+ # include
diff --git a/build/openembedded/libgsm/libgsm-1.0.13/04_includes.patch b/build/openembedded/libgsm/libgsm-1.0.13/04_includes.patch
new file mode 100644
index 000000000..2769b40b0
--- /dev/null
+++ b/build/openembedded/libgsm/libgsm-1.0.13/04_includes.patch
@@ -0,0 +1,43 @@
+diff -urNad libgsm-1.0.10~/inc/toast.h libgsm-1.0.10/inc/toast.h
+--- libgsm-1.0.10~/inc/toast.h 2007-11-01 15:37:52.000000000 +0100
++++ libgsm-1.0.10/inc/toast.h 2007-11-01 15:52:33.000000000 +0100
+@@ -16,11 +16,12 @@
+
+ #include
+ #include
++#include
+ #include
+
+ #include
+-#ifndef HAS_ERRNO_DECL
+- extern int errno;
++#ifndef errno
++ extern int errno;
+ #endif
+
+ #ifdef HAS_LIMITS_H
+@@ -37,6 +38,10 @@
+ # endif
+ #endif
+
++#ifdef HAS_STDIO_H
++# include
++#endif
++
+ #include "gsm.h"
+
+ #ifndef S_ISREG
+diff -urNad libgsm-1.0.10~/src/code.c libgsm-1.0.10/src/code.c
+--- libgsm-1.0.10~/src/code.c 2007-11-01 15:37:52.000000000 +0100
++++ libgsm-1.0.10/src/code.c 2007-11-01 15:52:33.000000000 +0100
+@@ -9,8 +9,8 @@
+ #include "config.h"
+
+
+-#ifdef HAS_STDLIB_H
+-#include
++#ifdef HAS_STRING_H
++#include
+ #else
+ # include "proto.h"
+ extern char * memcpy P((char *, char *, int));
diff --git a/build/openembedded/libgsm/libgsm-1.0.13/05_compiler_warnings.patch b/build/openembedded/libgsm/libgsm-1.0.13/05_compiler_warnings.patch
new file mode 100644
index 000000000..c40100c92
--- /dev/null
+++ b/build/openembedded/libgsm/libgsm-1.0.13/05_compiler_warnings.patch
@@ -0,0 +1,98 @@
+diff -urNad libgsm-1.0.10~/src/debug.c libgsm-1.0.10/src/debug.c
+--- libgsm-1.0.10~/src/debug.c 2007-11-01 15:37:52.000000000 +0100
++++ libgsm-1.0.10/src/debug.c 2007-11-01 15:53:42.000000000 +0100
+@@ -49,7 +49,7 @@
+ fprintf( stderr, "%s [%d .. %d]: ", name, from, to );
+ while (from <= to) {
+
+- fprintf(stderr, "%d ", ptr[ from ] );
++ fprintf(stderr, "%ld ", ptr[ from ] );
+ from++;
+ if (nprinted++ >= 7) {
+ nprinted = 0;
+@@ -63,14 +63,14 @@
+ char * name,
+ longword value )
+ {
+- fprintf(stderr, "%s: %d\n", name, (long)value );
++ fprintf(stderr, "%s: %ld\n", name, (long)value );
+ }
+
+ void gsm_debug_word P2( (name, value),
+ char * name,
+ word value )
+ {
+- fprintf(stderr, "%s: %d\n", name, (long)value);
++ fprintf(stderr, "%s: %ld\n", name, (long)value);
+ }
+
+ #endif
+diff -urNad libgsm-1.0.10~/src/toast.c libgsm-1.0.10/src/toast.c
+--- libgsm-1.0.10~/src/toast.c 2007-11-01 15:37:52.000000000 +0100
++++ libgsm-1.0.10/src/toast.c 2007-11-01 15:53:42.000000000 +0100
+@@ -251,8 +251,8 @@
+ {
+ char * s;
+ if (!(s = malloc(len))) {
+- fprintf(stderr, "%s: failed to malloc %d bytes -- abort\n",
+- progname, len);
++ fprintf(stderr, "%s: failed to malloc %ld bytes -- abort\n",
++ progname, (long) len);
+ onintr();
+ exit(1);
+ }
+@@ -270,7 +270,7 @@
+ maxlen = strlen(name) + 1 + strlen(want) + strlen(cut);
+ p = strcpy(emalloc(maxlen), name);
+
+- if (s = suffix(p, cut)) strcpy(s, want);
++ if ((s = suffix(p, cut))) strcpy(s, want);
+ else if (*want && !suffix(p, want)) strcat(p, want);
+
+ return p;
+@@ -386,7 +386,7 @@
+ ut[0] = instat.st_atime;
+ ut[1] = instat.st_mtime;
+
+- (void) utime(outname, ut);
++ (void) utime(outname, (struct utimbuf *)ut);
+
+ #endif /* UTIMBUF */
+ }
+@@ -416,7 +416,7 @@
+ }
+ if (st->st_nlink > 1 && !f_cat && !f_precious) {
+ fprintf(stderr,
+- "%s: \"%s\" has %s other link%s -- unchanged.\n",
++ "%s: \"%s\" has %d other link%s -- unchanged.\n",
+ progname,name,st->st_nlink - 1,"s" + (st->st_nlink<=2));
+ return 0;
+ }
+@@ -585,8 +585,8 @@
+
+ if (cc != sizeof(s)) {
+ if (cc >= 0) fprintf(stderr,
+- "%s: incomplete frame (%d byte%s missing) from %s\n",
+- progname, sizeof(s) - cc,
++ "%s: incomplete frame (%ld byte%s missing) from %s\n",
++ progname, (long) sizeof(s) - cc,
+ "s" + (sizeof(s) - cc == 1),
+ inname ? inname : "stdin" );
+ gsm_destroy(r);
+@@ -624,8 +624,6 @@
+
+ static int process P1((name), char * name)
+ {
+- int step = 0;
+-
+ out = (FILE *)0;
+ in = (FILE *)0;
+
+@@ -779,7 +777,6 @@
+ case 'h': help(); exit(0);
+
+ default:
+- usage:
+ fprintf(stderr,
+ "Usage: %s [-fcpdhvuaslFC] [files...] (-h for help)\n",
+ progname);
diff --git a/build/openembedded/libgsm/libgsm.inc b/build/openembedded/libgsm/libgsm.inc
new file mode 100644
index 000000000..a731e81b8
--- /dev/null
+++ b/build/openembedded/libgsm/libgsm.inc
@@ -0,0 +1,34 @@
+DESCRIPTION = "GSM Audio Library"
+SECTION = "libs"
+PRIORITY = "optional"
+LICENSE = "libgsm"
+
+INC_PR = "r2"
+
+SRC_URI = "http://www.quut.com/gsm/gsm-${PV}.tar.gz \
+ file://01_makefile.patch \
+ file://02_cplusplus.patch \
+ file://03_config.patch \
+ file://04_includes.patch \
+ file://05_compiler_warnings.patch \
+ "
+
+CFLAGS += "-c -g -fPIC -Wall -D_GNU_SOURCE -D_REENTRANT -DNeedFunctionPrototypes=1 -DWAV49 -I./inc"
+
+PARALLEL_MAKE = ""
+
+do_compile() {
+ unset LD
+ oe_runmake CCFLAGS="${CFLAGS}"
+}
+
+do_install() {
+ oe_libinstall -a -C lib libgsm ${D}${libdir}
+ oe_libinstall -so -C lib libgsm ${D}${libdir}
+ install -d ${D}${includedir}/gsm
+ install -m 0644 ${S}/inc/gsm.h ${D}${includedir}/gsm/
+ cd ${D}${includedir}
+ ln -s gsm/gsm.h gsm.h
+}
+
+LIC_FILES_CHKSUM = "file://COPYRIGHT;md5=fc1372895b173aaf543a122db37e04f5"
\ No newline at end of file
diff --git a/build/openembedded/libgsm/libgsm_1.0.13.bb b/build/openembedded/libgsm/libgsm_1.0.13.bb
new file mode 100644
index 000000000..e6bf9baf6
--- /dev/null
+++ b/build/openembedded/libgsm/libgsm_1.0.13.bb
@@ -0,0 +1,8 @@
+require libgsm.inc
+
+PR = "${INC_PR}.0"
+
+S = "${WORKDIR}/gsm-1.0-pl13/"
+
+SRC_URI[md5sum] = "c1ba392ce61dc4aff1c29ea4e92f6df4"
+SRC_URI[sha256sum] = "52c518244d428c2e56c543b98c9135f4a76ff780c32455580b793f60a0a092ad"
diff --git a/build/openembedded/libilbc-rfc3951_git.bb b/build/openembedded/libilbc-rfc3951_git.bb
new file mode 100644
index 000000000..250976172
--- /dev/null
+++ b/build/openembedded/libilbc-rfc3951_git.bb
@@ -0,0 +1,13 @@
+DESCRIPTION = "iLBC codec as published in IETF RFC 3951"
+SECTION = "libs"
+PRIORITY = "optional"
+LICENSE = "LGPLv3"
+PR = "r1"
+
+SRC_URI = "git://git.linphone.org/libilbc-rfc3951.git;protocol=git"
+SRCREV = "b9490e0cbdda6a4ec29f7c47d81d3997004fedba"
+S = "${WORKDIR}/git"
+
+LIC_FILES_CHKSUM = "file://COPYING;md5=586c8a6efdeabd095cc4206ce4d0699b"
+
+inherit autotools pkgconfig
diff --git a/build/openembedded/linphone-plugins.bb b/build/openembedded/linphone-plugins.bb
new file mode 100644
index 000000000..4d31895cd
--- /dev/null
+++ b/build/openembedded/linphone-plugins.bb
@@ -0,0 +1,9 @@
+DESCRIPTION = "Plugins for linphone to have additional codecs."
+LICENSE = ""
+ALLOW_EMPTY_${PN} = "1"
+PACKAGES = "${PN}"
+DEPENDS_${PN} = "linphone msamr msilbc msx264"
+RDEPENDS_${PN} = "linphonec msamr msilbc msx264"
+
+LIC_FILES_CHKSUM = "file://${COREBASE}/LICENSE;md5=3f40d7994397109285ec7b81fdeb3b58 \
+ file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420"
diff --git a/build/openembedded/linphone/linphone-common.inc b/build/openembedded/linphone/linphone-common.inc
new file mode 100644
index 000000000..64309228a
--- /dev/null
+++ b/build/openembedded/linphone/linphone-common.inc
@@ -0,0 +1,66 @@
+SECTION = "x11/network"
+SECTION_liblinphone = "libs/network"
+SECTION_libmediastreamer = "libs/network"
+SECTION_libortp = "libs/network"
+SECTION_linphonec = "console/network"
+
+SRC_URI_append_igep0020 = " file://alsa_8khz.patch"
+
+DEPENDS_${PN} = "intltool-native speex alsa-lib spandsp belle-sip liblinphone libxv ffmpeg libv4l libgsm"
+DEPENDS_liblinphone = "libmediastreamer libortp"
+DEPENDS_libmediastreamer = "speex alsa-lib libortp"
+
+PROVIDES = "linphone linphonec liblinphone libmediastreamer libortp"
+
+inherit autotools pkgconfig gettext
+
+INSANE_SKIP_linphone += "dev-deps"
+INSANE_SKIP_liblinphone += "dev-deps"
+
+do_install_append(){
+ install -d ${D}${bindir}
+}
+
+EXTRA_OECONF = " \
+ --disable-tests \
+ --with-ffmpeg=${STAGING_DIR_HOST}${layout_exec_prefix} --enable-video --disable-vp8 \
+ --disable-glx \
+ --enable-alsa --disable-pulseaudio \
+ --without-readline \
+ --with-speex=${STAGING_DIR_HOST}${layout_exec_prefix} \
+ --disable-manual --enable-tests=yes \
+ --enable-console_ui=no \
+ --enable-gtk_ui=no \
+ --with-realprefix=/usr \
+ "
+
+EXTRA_OEMAKE = " V=1"
+
+PACKAGES = "${PN}-dbg ${PN}-dev ${PN}-doc ${PN}c ${PN}-common linphone-rings liblinphone libmediastreamer-bin libmediastreamer libortp ${PN}-utils ${PN}-tests"
+
+FILES_${PN}-common = "\
+ ${bindir}/lp-gen-wrappers \
+ ${datadir}/pixmaps \
+ ${datadir}/applications \
+ ${datadir}/gnome \
+ ${datadir}/tutorials \
+ ${datadir}/linphone \
+ ${datadir}/sounds/linphone/hello8000.wav \
+ ${datadir}/sounds/linphone/hello16000.wav \
+ ${datadir}/sounds/linphone/incoming_chat.wav \
+ ${datadir}/sounds/linphone/ringback.wav \
+ ${datadir}/images/nowebcamCIF.jpg \
+ ${datadir}/appdata/linphone.appdata.xml \
+ ${datadir}/icons \
+ "
+FILES_${PN}-tests = "${bindir}/xml2lpc_test ${bindir}/lpc2xml_test"
+FILES_${PN} = "${bindir}/linphone"
+FILES_${PN}c = "${bindir}/linphonec ${bindir}/linphone-daemon ${bindir}/linphone-daemon-pipetest ${bindir}/linphonecsh ${bindir}/sipomatic ${bindir}/auto_answer"
+FILES_${PN}-rings = "${datadir}/sounds/linphone/rings"
+FILES_liblinphone = "${libdir}/liblinphone.so.*"
+FILES_libmediastreamer-bin = "${bindir}/mediastream ${bindir}/msaudiocmp"
+FILES_libmediastreamer = "${libdir}/libmediastreamer_base.so.* ${libdir}/libmediastreamer_voip.so.* ${libdir}/mediastreamer/ ${libdir}/mediastreamer/plugins"
+FILES_libortp = "${libdir}/libortp.so.*"
+FILES_${PN}-dev += "${libdir}/*.a ${libdir}/*.la ${libdir}/pkgconfig ${includedir}"
+FILES_${PN}-utils = "${bindir}/test_ecc ${bindir}/test_lsd"
+FILES_${PN}-doc = "${docdir}/ortp-0.24.1 ${docdir}/mediastreamer-2.11.1 ${docdir}/linphone-3.8.1-linphone-daemon ${mandir}"
diff --git a/build/openembedded/linphone/linphone-common_git.inc b/build/openembedded/linphone/linphone-common_git.inc
new file mode 100644
index 000000000..3d92b7f46
--- /dev/null
+++ b/build/openembedded/linphone/linphone-common_git.inc
@@ -0,0 +1,37 @@
+
+SRCREV = "cfa356c8680d26eec970c7b54beea0717b91f2b0"
+L_GIT_SRC_URI = "gitosis@git.linphone.org:linphone-daemon"
+PR_append = "+gitr${SRCREV}"
+
+LINPHONE_TMP_DIR="/tmp/LINPHONE_TMP_${SRCREV}"
+SRC_URI = "file://${LINPHONE_TMP_DIR}/linphone.tar.gz"
+
+S = "${WORKDIR}/linphone"
+
+# bitbake git fetcher currently doesn't handle git submodules
+# There is also a problem with autogen and AC_SUBST
+# note: don't use a ssh key with password, it does not work.
+do_fetch_prepend () {
+ import os,bb
+ bb.note("Hack preparing clone in %s" %"${LINPHONE_TMP_DIR}")
+ os.system("rm -rf ${LINPHONE_TMP_DIR}")
+ os.system("mkdir -p ${LINPHONE_TMP_DIR}")
+
+ bb.note("Hack cloning linphone !recursively")
+ os.system("cd ${LINPHONE_TMP_DIR}; git clone --recursive ${L_GIT_SRC_URI} linphone")
+
+ bb.note("Hack launching autogen.sh manually")
+ os.system("cd ${LINPHONE_TMP_DIR}/linphone; ./autogen.sh")
+
+ bb.note("Hack preparing linphone.tar.gz")
+ # we need to keep the .git since the versioning in linphone is done through `git describe`
+ os.system("cd ${LINPHONE_TMP_DIR}; tar czf linphone.tar.gz linphone")
+}
+
+require linphone-common.inc
+
+
+#Required to avoid compile errors on May 2011.
+EXTRA_OECONF +=" --disable-strict"
+
+LIC_FILES_CHKSUM = "file://COPYING;md5=9f9938e31db89d55a796e86808c96848"
diff --git a/build/openembedded/linphone/linphone-common_local.inc b/build/openembedded/linphone/linphone-common_local.inc
new file mode 100644
index 000000000..a77b212e3
--- /dev/null
+++ b/build/openembedded/linphone/linphone-common_local.inc
@@ -0,0 +1,15 @@
+SRC_URI = "file://${HOME}/linphone-3.6.1.tar.gz"
+
+S = "${WORKDIR}/linphone-3.6.1"
+
+require linphone-common.inc
+
+do_configure_prepend () {
+ ./autogen.sh
+ libtoolize --copy --force
+}
+
+#Required to avoid compile errors on May 2011.
+EXTRA_OECONF +=" --disable-strict --disable-glx"
+
+LIC_FILES_CHKSUM = "file://COPYING;md5=94d55d512a9ba36caa9b7df079bae19f"
diff --git a/build/openembedded/linphone/linphone_+git-nogtk-gsm-video-x11.bb b/build/openembedded/linphone/linphone_+git-nogtk-gsm-video-x11.bb
new file mode 100644
index 000000000..0d55b7665
--- /dev/null
+++ b/build/openembedded/linphone/linphone_+git-nogtk-gsm-video-x11.bb
@@ -0,0 +1,16 @@
+## THIS unusable work in progress ##
+
+DESCRIPTION = "Audio/video SIP-based IP phone (console edition)"
+HOMEPAGE = "http://www.linphone.org/?lang=us"
+LICENSE = "GPLv2"
+PR="r0"
+
+DEFAULT_PREFERENCE = "3"
+OVERRIDES_append = ":console"
+OVERRIDES_append = ":gsm"
+OVERRIDES_append = ":video"
+OVERRIDES_append = ":x11"
+
+#PARALLEL_MAKE="V=1"
+
+require linphone-common_git.inc
diff --git a/build/openembedded/linphone/linphone_+git-nogtk-gsm-video.bb b/build/openembedded/linphone/linphone_+git-nogtk-gsm-video.bb
new file mode 100644
index 000000000..ae1120632
--- /dev/null
+++ b/build/openembedded/linphone/linphone_+git-nogtk-gsm-video.bb
@@ -0,0 +1,15 @@
+## THIS unusable work in progress ##
+
+DESCRIPTION = "Audio/video SIP-based IP phone (console edition)"
+HOMEPAGE = "http://www.linphone.org/?lang=us"
+LICENSE = "GPLv2"
+PR="r14"
+
+DEFAULT_PREFERENCE = "3"
+OVERRIDES_append = ":console"
+OVERRIDES_append = ":gsm"
+OVERRIDES_append = ":video"
+
+#PARALLEL_MAKE="V=1"
+
+require linphone-common_git.inc
diff --git a/build/openembedded/linphone/linphone_+git-nogtk-gsm.bb b/build/openembedded/linphone/linphone_+git-nogtk-gsm.bb
new file mode 100644
index 000000000..a9496c1ef
--- /dev/null
+++ b/build/openembedded/linphone/linphone_+git-nogtk-gsm.bb
@@ -0,0 +1,14 @@
+
+
+DESCRIPTION = "Audio/video SIP-based IP phone (console edition)"
+HOMEPAGE = "http://www.linphone.org/?lang=us"
+LICENSE = "GPLv2"
+PR="r15"
+
+DEFAULT_PREFERENCE = "3"
+OVERRIDES_append = ":console"
+OVERRIDES_append = ":gsm"
+
+#PARALLEL_MAKE="V=1"
+
+require linphone-common_git.inc
diff --git a/build/openembedded/linphone/linphone_+git-nogtk.bb b/build/openembedded/linphone/linphone_+git-nogtk.bb
new file mode 100644
index 000000000..a9228042a
--- /dev/null
+++ b/build/openembedded/linphone/linphone_+git-nogtk.bb
@@ -0,0 +1,13 @@
+## THIS unusable work in progress ##
+
+DESCRIPTION = "Audio/video SIP-based IP phone (console edition)"
+HOMEPAGE = "http://www.linphone.org/?lang=us"
+LICENSE = "GPLv2"
+PR="r14"
+
+DEFAULT_PREFERENCE = "3"
+OVERRIDES_append = ":console"
+
+#PARALLEL_MAKE="V=1"
+
+require linphone-common_git.inc
diff --git a/build/openembedded/linphone/linphone_+local-nogtk-gsm-video-x11.bb b/build/openembedded/linphone/linphone_+local-nogtk-gsm-video-x11.bb
new file mode 100644
index 000000000..427eb94bc
--- /dev/null
+++ b/build/openembedded/linphone/linphone_+local-nogtk-gsm-video-x11.bb
@@ -0,0 +1,16 @@
+## THIS unusable work in progress ##
+
+DESCRIPTION = "Audio/video SIP-based IP phone (console edition)"
+HOMEPAGE = "http://www.linphone.org/?lang=us"
+LICENSE = "GPLv2"
+PR="r9"
+
+DEFAULT_PREFERENCE = "-1"
+OVERRIDES_append = ":console"
+OVERRIDES_append = ":gsm"
+OVERRIDES_append = ":video"
+OVERRIDES_append = ":x11"
+
+#PARALLEL_MAKE="V=1"
+
+require linphone-common_local.inc
diff --git a/build/openembedded/linphone/linphone_+local-nogtk-gsm-video.bb b/build/openembedded/linphone/linphone_+local-nogtk-gsm-video.bb
new file mode 100644
index 000000000..9a599dc4f
--- /dev/null
+++ b/build/openembedded/linphone/linphone_+local-nogtk-gsm-video.bb
@@ -0,0 +1,15 @@
+## THIS unusable work in progress ##
+
+DESCRIPTION = "Audio/video SIP-based IP phone (console edition)"
+HOMEPAGE = "http://www.linphone.org/?lang=us"
+LICENSE = "GPLv2"
+PR="r9"
+
+DEFAULT_PREFERENCE = "-1"
+OVERRIDES_append = ":console"
+OVERRIDES_append = ":gsm"
+OVERRIDES_append = ":video"
+
+#PARALLEL_MAKE="V=1"
+
+require linphone-common_local.inc
diff --git a/build/openembedded/linphone/linphone_+local-nogtk-gsm.bb b/build/openembedded/linphone/linphone_+local-nogtk-gsm.bb
new file mode 100644
index 000000000..d48a1a17e
--- /dev/null
+++ b/build/openembedded/linphone/linphone_+local-nogtk-gsm.bb
@@ -0,0 +1,14 @@
+## THIS unusable work in progress ##
+
+DESCRIPTION = "Audio/video SIP-based IP phone (console edition)"
+HOMEPAGE = "http://www.linphone.org/?lang=us"
+LICENSE = "GPLv2"
+PR="r9"
+
+DEFAULT_PREFERENCE = "-1"
+OVERRIDES_append = ":console"
+OVERRIDES_append = ":gsm"
+
+#PARALLEL_MAKE="V=1"
+
+require linphone-common_local.inc
diff --git a/build/openembedded/linphone/linphone_+local-nogtk.bb b/build/openembedded/linphone/linphone_+local-nogtk.bb
new file mode 100644
index 000000000..9a54c256a
--- /dev/null
+++ b/build/openembedded/linphone/linphone_+local-nogtk.bb
@@ -0,0 +1,13 @@
+## THIS unusable work in progress ##
+
+DESCRIPTION = "Audio/video SIP-based IP phone (console edition)"
+HOMEPAGE = "http://www.linphone.org/?lang=us"
+LICENSE = "GPLv2"
+PR="r9"
+
+DEFAULT_PREFERENCE = "-1"
+OVERRIDES_append = ":console"
+
+#PARALLEL_MAKE="V=1"
+
+require linphone-common_local.inc
diff --git a/build/openembedded/linphone/linphone_git.bb b/build/openembedded/linphone/linphone_git.bb
new file mode 100644
index 000000000..f1c65a799
--- /dev/null
+++ b/build/openembedded/linphone/linphone_git.bb
@@ -0,0 +1,39 @@
+DESCRIPTION = "Audio/video SIP-based IP phone (console edition)"
+HOMEPAGE = "http://www.linphone.org/?lang=us"
+LICENSE = "GPLv2"
+
+SRCREV = "855f3aa1b83fd979bb8ff4c6373522bc72fe77ec"
+L_GIT_SRC_URI = "gitosis@git.linphone.org:linphone-daemon"
+
+LINPHONE_TMP_DIR="/tmp/LINPHONE_TMP_${SRCREV}"
+SRC_URI = "file://${LINPHONE_TMP_DIR}/linphone.tar.gz"
+
+S = "${WORKDIR}/linphone"
+
+# bitbake git fetcher currently doesn't handle git submodules
+# There is also a problem with autogen and AC_SUBST
+# note: don't use a ssh key with password, it does not work.
+do_fetch_prepend () {
+ import os,bb
+ bb.note("Hack preparing clone in %s" %"${LINPHONE_TMP_DIR}")
+ os.system("rm -rf ${LINPHONE_TMP_DIR}")
+ os.system("mkdir -p ${LINPHONE_TMP_DIR}")
+
+ bb.note("Hack cloning linphone !recursively")
+ os.system("cd ${LINPHONE_TMP_DIR}; git clone ${L_GIT_SRC_URI} linphone; cd linphone; git checkout ${SRCREV}; git submodule update --recursive --init")
+
+ bb.note("Hack launching autogen.sh manually")
+ os.system("cd ${LINPHONE_TMP_DIR}/linphone; ./autogen.sh")
+
+ bb.note("Hack preparing linphone.tar.gz")
+ # we need to keep the .git since the versioning in linphone is done through `git describe`
+ os.system("cd ${LINPHONE_TMP_DIR}; tar czf linphone.tar.gz linphone")
+}
+
+require linphone-common.inc
+
+
+#Required to avoid compile errors on May 2011.
+EXTRA_OECONF +=" --disable-strict"
+
+LIC_FILES_CHKSUM = "file://COPYING;md5=9f9938e31db89d55a796e86808c96848"
diff --git a/build/openembedded/msamr/msamr-common.inc b/build/openembedded/msamr/msamr-common.inc
new file mode 100644
index 000000000..4f35dafc3
--- /dev/null
+++ b/build/openembedded/msamr/msamr-common.inc
@@ -0,0 +1,20 @@
+DESCRIPTION = "Mediastreamer2 plugin adding support for AMR codec"
+SECTION = "libs"
+PRIORITY = "optional"
+LICENSE = "GPLv3"
+
+LIC_FILES_CHKSUM = "file://COPYING;md5=d32239bcb673463ab874e80d47fae504"
+
+DEPENDS = "linphone opencore-amr"
+DEPENDS_append_wideband = " vo-amrwbenc"
+
+MSAMR_WIDEBAND = ""
+MSAMR_WIDEBAND_wideband = "--enable-wideband"
+
+EXTRA_OECONF = "\
+ ${MSAMR_WIDEBAND} \
+ "
+
+FILES_${PN} = "${libdir}/mediastreamer/plugins/*.so.*"
+FILES_${PN}-dev = "${libdir}/mediastreamer/plugins/*.la ${libdir}/mediastreamer/plugins/*.so"
+inherit autotools pkgconfig
diff --git a/build/openembedded/msamr/msamr_git+wb.bb b/build/openembedded/msamr/msamr_git+wb.bb
new file mode 100644
index 000000000..63f1caa8b
--- /dev/null
+++ b/build/openembedded/msamr/msamr_git+wb.bb
@@ -0,0 +1,8 @@
+PR = "r2"
+SRC_URI = "git://git.linphone.org/msamr.git;protocol=git"
+SRCREV = "6ed342ed00526c21e85f8a06538fe3da2c7a24f4"
+S = "${WORKDIR}/git"
+
+OVERRIDES_append = ":wideband"
+
+require msamr-common.inc
diff --git a/build/openembedded/msamr/msamr_git.bb b/build/openembedded/msamr/msamr_git.bb
new file mode 100644
index 000000000..07b394dc2
--- /dev/null
+++ b/build/openembedded/msamr/msamr_git.bb
@@ -0,0 +1,6 @@
+PR = "r2"
+SRC_URI = "git://git.linphone.org/msamr.git;protocol=git"
+SRCREV = "6ed342ed00526c21e85f8a06538fe3da2c7a24f4"
+S = "${WORKDIR}/git"
+
+require msamr-common.inc
diff --git a/build/openembedded/msamr/msamr_local+wb.bb b/build/openembedded/msamr/msamr_local+wb.bb
new file mode 100644
index 000000000..cb89a1bde
--- /dev/null
+++ b/build/openembedded/msamr/msamr_local+wb.bb
@@ -0,0 +1,13 @@
+PR = "r1"
+SRC_URI = "file://${HOME}/msamr-0.0.2.tar.gz"
+S = "${WORKDIR}/msamr-0.0.2"
+
+do_configure_prepend () {
+ ./autogen.sh
+}
+
+OVERRIDES_append = ":wideband"
+
+DEFAULT_PREFERENCE="-1"
+
+require msamr-common.inc
diff --git a/build/openembedded/msamr/msamr_local.bb b/build/openembedded/msamr/msamr_local.bb
new file mode 100644
index 000000000..f6349af74
--- /dev/null
+++ b/build/openembedded/msamr/msamr_local.bb
@@ -0,0 +1,11 @@
+PR = "r1"
+SRC_URI = "file://${HOME}/msamr-0.0.2.tar.gz"
+S = "${WORKDIR}/msamr-0.0.2"
+
+do_configure_prepend () {
+ ./autogen.sh
+}
+
+DEFAULT_PREFERENCE="-1"
+
+require msamr-common.inc
diff --git a/build/openembedded/msilbc/msilbc-common.inc b/build/openembedded/msilbc/msilbc-common.inc
new file mode 100644
index 000000000..6651f9a70
--- /dev/null
+++ b/build/openembedded/msilbc/msilbc-common.inc
@@ -0,0 +1,12 @@
+DESCRIPTION = "Mediastreamer2 plugin adding support for ILBC codec"
+SECTION = "libs"
+PRIORITY = "optional"
+LICENSE = "GPLv2"
+DEPENDS = "linphone libilbc-rfc3951"
+
+FILES_${PN} = "${libdir}/mediastreamer/plugins/*.so.*"
+FILES_${PN}-dev = "${libdir}/mediastreamer/plugins/*.la ${libdir}/mediastreamer/plugins/*.so"
+
+LIC_FILES_CHKSUM = "file://COPYING;md5=59530bdf33659b29e73d4adb9f9f6552"
+
+inherit autotools pkgconfig
diff --git a/build/openembedded/msilbc/msilbc_git.bb b/build/openembedded/msilbc/msilbc_git.bb
new file mode 100644
index 000000000..3ed186094
--- /dev/null
+++ b/build/openembedded/msilbc/msilbc_git.bb
@@ -0,0 +1,6 @@
+PR = "r1"
+SRC_URI = "git://git.linphone.org/msilbc.git;protocol=git"
+SRCREV = "2bf845d7f537eb671dd32ca5b0cc932e8bb48952"
+S = "${WORKDIR}/git"
+
+require msilbc-common.inc
diff --git a/build/openembedded/msilbc/msilbc_local.bb b/build/openembedded/msilbc/msilbc_local.bb
new file mode 100644
index 000000000..72b08b239
--- /dev/null
+++ b/build/openembedded/msilbc/msilbc_local.bb
@@ -0,0 +1,11 @@
+PR = "r0"
+SRC_URI = "file://${HOME}/msilbc-2.0.3.tar.gz"
+S = "${WORKDIR}/msilbc-2.0.3"
+
+do_configure_prepend () {
+ ./autogen.sh
+}
+
+DEFAULT_PREFERENCE="-1"
+
+require msilbc-common.inc
diff --git a/build/openembedded/msimx6vpu-h264/msimx6vpu-h264.inc b/build/openembedded/msimx6vpu-h264/msimx6vpu-h264.inc
new file mode 100644
index 000000000..74c31cdb1
--- /dev/null
+++ b/build/openembedded/msimx6vpu-h264/msimx6vpu-h264.inc
@@ -0,0 +1,12 @@
+SECTION = "libs"
+
+DEPENDS_${PN} = "libmediastreamer imx-lib imx-vpu"
+DEPENDS = "libmediastreamer imx-lib imx-vpu"
+
+PROVIDES = "msimx6vpu-h264 msimx6vpu-h264-dbg"
+
+inherit autotools gettext
+
+FILES_${PN} = "${libdir}/mediastreamer/plugins/*.so.*"
+FILES_${PN}-dev = "${libdir}/mediastreamer/plugins/*.la ${libdir}/mediastreamer/plugins/*.so"
+FILES_${PN}-dbg = "${libdir}/mediastreamer/plugins/.debug/*.so.* /usr/src/debug"
diff --git a/build/openembedded/msimx6vpu-h264/msimx6vpu-h264_git.bb b/build/openembedded/msimx6vpu-h264/msimx6vpu-h264_git.bb
new file mode 100644
index 000000000..13137448a
--- /dev/null
+++ b/build/openembedded/msimx6vpu-h264/msimx6vpu-h264_git.bb
@@ -0,0 +1,23 @@
+DESCRIPTION = "A H264 encoder/decoder plugin for mediastreamer using Freescale's IMX6's VPU"
+HOMEPAGE = "http://www.linphone.org/?lang=us"
+LICENSE = "GPLv3+"
+
+GIT_SRC_URI = "gitosis@git.linphone.org:msimx6vpu-h264.git"
+SRCREV = "master"
+LIC_FILES_CHKSUM = "file://COPYING;md5=c46082167a314d785d012a244748d803"
+
+TMP_DIR="/tmp/TMP_MSIMX6VPUH264_${SRCREV}"
+SRC_URI = "file://${TMP_DIR}/msimx6vpu-h264.tar.gz"
+
+S = "${WORKDIR}/msimx6vpu-h264"
+
+# note: don't use a ssh key with password, it does not work.
+do_fetch_prepend () {
+ import os,bb
+ os.system("rm -rf ${TMP_DIR}")
+ os.system("mkdir -p ${TMP_DIR}")
+ os.system("cd ${TMP_DIR}; git clone ${GIT_SRC_URI} msimx6vpu-h264")
+ os.system("cd ${TMP_DIR}; tar czf msimx6vpu-h264.tar.gz msimx6vpu-h264")
+}
+
+require msimx6vpu-h264.inc
diff --git a/build/openembedded/msv4l2-display/msv4l2-display-common.inc b/build/openembedded/msv4l2-display/msv4l2-display-common.inc
new file mode 100644
index 000000000..c58e41998
--- /dev/null
+++ b/build/openembedded/msv4l2-display/msv4l2-display-common.inc
@@ -0,0 +1,14 @@
+SECTION = "libs"
+
+DEPENDS_${PN} = "libmediastreamer"
+DEPENDS = "libmediastreamer"
+
+PROVIDES = "msv4l2-display"
+
+EXTRA_OECONF += ' CFLAGS="-DOUTPUT_VIDEO_DEVICE=17"'
+
+inherit autotools gettext
+
+FILES_${PN} = "${libdir}/mediastreamer/plugins/*.so.*"
+FILES_${PN}-dev = "${libdir}/mediastreamer/plugins/*.la ${libdir}/mediastreamer/plugins/*.so"
+FILES_${PN}-dbg = "${libdir}/mediastreamer/plugins/.debug/*.so.* /usr/src/debug"
diff --git a/build/openembedded/msv4l2-display/msv4l2-display_git.bb b/build/openembedded/msv4l2-display/msv4l2-display_git.bb
new file mode 100644
index 000000000..14c7b7c7e
--- /dev/null
+++ b/build/openembedded/msv4l2-display/msv4l2-display_git.bb
@@ -0,0 +1,23 @@
+DESCRIPTION = "V4L2 display filter plugin for mediastreamer/linphone"
+HOMEPAGE = "http://www.linphone.org/?lang=us"
+LICENSE = "GPLv3+"
+
+GIT_SRC_URI = "gitosis@git.linphone.org:msv4l2-display.git"
+SRCREV = "master"
+LIC_FILES_CHKSUM = "file://COPYING;md5=c46082167a314d785d012a244748d803"
+
+TMP_DIR="/tmp/TMP_MSV4L2Display_${SRCREV}"
+SRC_URI = "file://${TMP_DIR}/msv4l2-display.tar.gz"
+
+S = "${WORKDIR}/msv4l2-display"
+
+# note: don't use a ssh key with password, it does not work.
+do_fetch_prepend () {
+ import os,bb
+ os.system("rm -rf ${TMP_DIR}")
+ os.system("mkdir -p ${TMP_DIR}")
+ os.system("cd ${TMP_DIR}; git clone ${GIT_SRC_URI} msv4l2-display")
+ os.system("cd ${TMP_DIR}; tar czf msv4l2-display.tar.gz msv4l2-display")
+}
+
+require msv4l2-display-common.inc
diff --git a/build/openembedded/mswebrtc/mswebrtc-common.inc b/build/openembedded/mswebrtc/mswebrtc-common.inc
new file mode 100644
index 000000000..bdccee2f4
--- /dev/null
+++ b/build/openembedded/mswebrtc/mswebrtc-common.inc
@@ -0,0 +1,15 @@
+DESCRIPTION = "Mediastreamer2 plugin adding support for WebRTC features (iSAC codec, AEC...)"
+SECTION = "libs"
+PRIORITY = "optional"
+LICENSE = "GPLv2"
+DEPENDS = "linphone"
+
+EXTRA_OECONF = "--disable-isac"
+
+FILES_${PN} = "${libdir}/mediastreamer/plugins/*.so.*"
+FILES_${PN}-dev = "${libdir}/mediastreamer/plugins/*.la ${libdir}/mediastreamer/plugins/*.so"
+FILES_${PN}-dbg = "${libdir}/mediastreamer/plugins/.debug/*.so.* /usr/src/debug"
+
+LIC_FILES_CHKSUM = "file://COPYING;md5=59530bdf33659b29e73d4adb9f9f6552"
+
+inherit autotools pkgconfig
diff --git a/build/openembedded/mswebrtc/mswebrtc_git.bb b/build/openembedded/mswebrtc/mswebrtc_git.bb
new file mode 100644
index 000000000..526f70554
--- /dev/null
+++ b/build/openembedded/mswebrtc/mswebrtc_git.bb
@@ -0,0 +1,6 @@
+PR = "r3"
+SRC_URI = "git://git.linphone.org/mswebrtc.git;protocol=git"
+SRCREV = "a9b5929928dd58299ceaed0aeb507c82bae80b55"
+S = "${WORKDIR}/git"
+
+require mswebrtc-common.inc
diff --git a/build/openembedded/mswebrtc/mswebrtc_local.bb b/build/openembedded/mswebrtc/mswebrtc_local.bb
new file mode 100644
index 000000000..8921a3c8e
--- /dev/null
+++ b/build/openembedded/mswebrtc/mswebrtc_local.bb
@@ -0,0 +1,11 @@
+PR = "r0"
+SRC_URI = "file://${HOME}/mswebrtc-1.0.tar.gz"
+S = "${WORKDIR}/mswebrtc-1.0"
+
+do_configure_prepend () {
+ ./autogen.sh
+}
+
+DEFAULT_PREFERENCE="-1"
+
+require mswebrtc-common.inc
diff --git a/build/openembedded/msx264/msx264-common.inc b/build/openembedded/msx264/msx264-common.inc
new file mode 100644
index 000000000..b340dc99f
--- /dev/null
+++ b/build/openembedded/msx264/msx264-common.inc
@@ -0,0 +1,12 @@
+DESCRIPTION = "Mediastreamer2 plugin adding support for H264 codec"
+SECTION = "libs"
+PRIORITY = "optional"
+LICENSE = "GPLv3"
+
+LIC_FILES_CHKSUM = "file://COPYING;md5=59530bdf33659b29e73d4adb9f9f6552"
+
+DEPENDS = "linphone x264"
+
+FILES_${PN} = "${libdir}/mediastreamer/plugins/*.so.*"
+FILES_${PN}-dev = "${libdir}/mediastreamer/plugins/*.la ${libdir}/mediastreamer/plugins/*.so"
+inherit autotools pkgconfig
diff --git a/build/openembedded/msx264/msx264_git.bb b/build/openembedded/msx264/msx264_git.bb
new file mode 100644
index 000000000..40a26e5fe
--- /dev/null
+++ b/build/openembedded/msx264/msx264_git.bb
@@ -0,0 +1,6 @@
+PR = "r1"
+SRC_URI = "git://git.linphone.org/msx264.git;protocol=git"
+SRCREV = "f1fd3d6be817dd5c1b8a46f68de04421f75cf056"
+S = "${WORKDIR}/git"
+
+require msx264-common.inc
diff --git a/build/openembedded/msx264/msx264_local.bb b/build/openembedded/msx264/msx264_local.bb
new file mode 100644
index 000000000..ef7ab1a82
--- /dev/null
+++ b/build/openembedded/msx264/msx264_local.bb
@@ -0,0 +1,11 @@
+PR = "r1"
+SRC_URI = "file://${HOME}/msx264-1.4.2.tar.gz"
+S = "${WORKDIR}/msx264-1.4.2"
+
+do_configure_prepend () {
+ ./autogen.sh
+}
+
+DEFAULT_PREFERENCE="-1"
+
+require msx264-common.inc
diff --git a/build/openembedded/opencore-amr_0.1.3.bb b/build/openembedded/opencore-amr_0.1.3.bb
new file mode 100644
index 000000000..7c338543d
--- /dev/null
+++ b/build/openembedded/opencore-amr_0.1.3.bb
@@ -0,0 +1,12 @@
+DESCRIPTION = "OpenCORE Adaptive Multi Rate (AMR) speech codec library implementation"
+SECTION = "libs"
+PRIORITY = "optional"
+LICENSE = "Apache"
+
+PR = "r1"
+SRC_URI = "${SOURCEFORGE_MIRROR}/opencore-amr/${PN}-${PV}.tar.gz"
+
+inherit autotools pkgconfig
+SRC_URI[md5sum] = "09d2c5dfb43a9f6e9fec8b1ae678e725"
+SRC_URI[sha256sum] = "106bf811c1f36444d7671d8fd2589f8b2e0cca58a2c764da62ffc4a070595385"
+LIC_FILES_CHKSUM = "file://COPYING;md5=dd2c2486aca02190153cf399e508c7e7"
\ No newline at end of file
diff --git a/build/openembedded/polarssl/polarssl-linphone/darwin.patch b/build/openembedded/polarssl/polarssl-linphone/darwin.patch
new file mode 100644
index 000000000..9faf5c1b7
--- /dev/null
+++ b/build/openembedded/polarssl/polarssl-linphone/darwin.patch
@@ -0,0 +1,14 @@
+diff -urN a/library/Makefile b/library/Makefile
+--- a/library/Makefile 2013-07-29 17:26:14.000000000 +0200
++++ b/library/Makefile 2013-07-29 17:26:58.000000000 +0200
+@@ -26,7 +26,9 @@
+
+ DLEXT=so
+ # OSX shared library extension:
+-# DLEXT=dylib
++ifdef DARWIN
++DLEXT=dylib
++endif
+
+ # Windows shared library extension:
+ ifdef WINDOWS
diff --git a/build/openembedded/polarssl/polarssl-linphone/soname.patch b/build/openembedded/polarssl/polarssl-linphone/soname.patch
new file mode 100644
index 000000000..29a1ca955
--- /dev/null
+++ b/build/openembedded/polarssl/polarssl-linphone/soname.patch
@@ -0,0 +1,51 @@
+diff -urN polarssl.orig/library/Makefile polarssl.new/library/Makefile
+--- polarssl.orig/library/Makefile 2013-08-22 10:24:46.353700982 +0200
++++ polarssl.new/library/Makefile 2013-08-22 10:21:43.933733318 +0200
+@@ -28,12 +28,14 @@
+ # OSX shared library extension:
+ ifdef DARWIN
+ DLEXT=dylib
++SONAME=libpolarssl.0.dylib
+ endif
+
+ # Windows shared library extension:
+ ifdef WINDOWS
+ DLEXT=dll
+ LDFLAGS += -lws2_32
++SONAME=libpolarssl-0.dll
+ endif
+
+ OBJS= aes.o arc4.o asn1parse.o \
+@@ -73,15 +75,17 @@
+
+ libpolarssl.so: libpolarssl.a
+ echo " LD $@"
+- $(CC) ${LDFLAGS} -shared -Wl,-soname,$(SONAME) -o $@ $(OBJS)
++ $(CC) ${LDFLAGS} -shared -Wl,-soname,$(SONAME) -o $(SONAME) $(OBJS)
++ ln -s $(SONAME) $@
+
+ libpolarssl.dylib: libpolarssl.a
+ echo " LD $@"
+- $(CC) ${LDFLAGS} -dynamiclib -o $@ $(OBJS)
++ $(CC) ${LDFLAGS} -dynamiclib -Wl,-install_name,$(SONAME) -o $(SONAME) $(OBJS)
++ ln -s $(SONAME) $@
+
+ libpolarssl.dll: libpolarssl.a
+ echo " LD $@"
+- $(CC) -shared -Wl,-soname,$@,--out-implib,$@.a -o $@ $(OBJS) -lws2_32 -lwinmm -lgdi32
++ $(CC) -shared -Wl,-soname,$(SONAME),--out-implib,$@.a -o $(SONAME) $(OBJS) -lws2_32 -lwinmm -lgdi32
+
+ .c.o:
+ echo " CC $<"
+diff -urN polarssl.orig/Makefile polarssl.new/Makefile
+--- polarssl.orig/Makefile 2013-08-22 10:24:34.585703377 +0200
++++ polarssl.new/Makefile 2013-08-22 10:19:26.801749343 +0200
+@@ -21,7 +21,7 @@
+ cp -r include/polarssl $(DESTDIR)/include
+
+ mkdir -p $(DESTDIR)/lib
+- cp library/libpolarssl.* $(DESTDIR)/lib
++ cp -d library/libpolarssl* $(DESTDIR)/lib
+
+ mkdir -p $(DESTDIR)/bin
+ cp library/libpolarssl*.dll $(DESTDIR)/bin
diff --git a/build/openembedded/polarssl/polarssl.inc b/build/openembedded/polarssl/polarssl.inc
new file mode 100644
index 000000000..c9957212e
--- /dev/null
+++ b/build/openembedded/polarssl/polarssl.inc
@@ -0,0 +1,17 @@
+DESCRIPTION = "SSL/TLS library"
+LICENSE = "GPL"
+
+inherit pkgconfig
+
+EXTRA_OEMAKE += " SHARED=1"
+
+PROVIDES = "polarssl polarssl-dev"
+ALLOW_EMPTY_${PN} = "1"
+
+PACKAGES += "${PN}-utils"
+
+MAKE_DESTDIR = "DESTDIR=${D}/${prefix}"
+
+FILES_${PN} += "${sharedlibdir}/*${SOLIBSDEV}"
+FILES_${PN}-dev += "!${sharedlibdir}/*${SOLIBSDEV}"
+FILES_${PN}-utils += "${bindir}/polarssl_*"
diff --git a/build/openembedded/polarssl/polarssl_linphone.bb b/build/openembedded/polarssl/polarssl_linphone.bb
new file mode 100644
index 000000000..41ed5060e
--- /dev/null
+++ b/build/openembedded/polarssl/polarssl_linphone.bb
@@ -0,0 +1,14 @@
+require polarssl.inc
+
+SRCREV="cecb44e4f13f42f793dde34b42793e1ebcce91a5"
+
+S = "${WORKDIR}/git"
+
+do_fetch_prepend () {
+ import bb
+ bb.note("Will checkout in %s" % "${S}" )
+}
+
+SRC_URI = "git://git.linphone.org/polarssl.git"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=751419260aa954499f7abaabaa882bbe"
+
diff --git a/build/openembedded/spandsp_0.0.6-pre18.bb b/build/openembedded/spandsp_0.0.6-pre18.bb
new file mode 100644
index 000000000..c87ff3c9e
--- /dev/null
+++ b/build/openembedded/spandsp_0.0.6-pre18.bb
@@ -0,0 +1,24 @@
+PR = "r0"
+
+SRC_URI = "http://www.soft-switch.org/downloads/spandsp/${PN}-0.0.6pre18.tgz"
+
+S = "${WORKDIR}/spandsp-0.0.6"
+
+# *cough*
+do_configure_append() {
+ rm config.log
+}
+
+DESCRIPTION = "A library of many DSP functions for telephony."
+HOMEPAGE = "http://www.soft-switch.org"
+SECTION = "libs"
+LICENSE = "LGPL"
+DEPENDS_${PN} = "tiff libxml2"
+
+inherit autotools
+
+#PARALLEL_MAKE = ""
+
+SRC_URI[md5sum] = "98330bc00a581ed8d71ebe34afabbcf9"
+SRC_URI[sha256sum] = "835cd886105e4e39791f0e8cfe004c39b069f2e6dcb0795a68a6c79b5d14af2c"
+LIC_FILES_CHKSUM = "file://COPYING;md5=8791c23ddf418deb5be264cffb5fa6bc"
diff --git a/build/openembedded/vo-amrwbenc_0.1.2.bb b/build/openembedded/vo-amrwbenc_0.1.2.bb
new file mode 100644
index 000000000..a34b7de3b
--- /dev/null
+++ b/build/openembedded/vo-amrwbenc_0.1.2.bb
@@ -0,0 +1,13 @@
+DESCRIPTION = "VisualOn AMR-WB encoder library"
+SECTION = "libs"
+PRIORITY = "optional"
+LICENSE = "Apache"
+DEPENDS = "opencore-amr"
+
+PR = "r1"
+SRC_URI = "${SOURCEFORGE_MIRROR}/opencore-amr/${PN}-${PV}.tar.gz"
+
+inherit autotools pkgconfig
+SRC_URI[md5sum] = "588205f686adc23532e31fe3646ddcb6"
+SRC_URI[sha256sum] = "dd8c33e57bc415754f31fbb1b1536563bf731fc14e55f8182564e4c0fbb26435"
+LIC_FILES_CHKSUM = "file://COPYING;md5=dd2c2486aca02190153cf399e508c7e7"
\ No newline at end of file
diff --git a/build/openembedded/x264_git.bb b/build/openembedded/x264_git.bb
new file mode 100644
index 000000000..481da9986
--- /dev/null
+++ b/build/openembedded/x264_git.bb
@@ -0,0 +1,18 @@
+DESCRIPTION = "x264 is a free software library and application for encoding video streams into the H.264/MPEG-4 AVC format."
+SECTION = "libs/multimedia"
+PRIORITY = "optional"
+LICENSE = "GPLv2"
+HOMEPAGE = "http://www.videolan.org/developers/x264.html"
+PR = "r1"
+
+SRC_URI = "git://git.videolan.org/x264.git;protocol=git"
+SRCREV = "e89c4cfc9f37d0b7684507974b333545b5bcc37a"
+S = "${WORKDIR}/git"
+
+EXTRA_OECONF += "--disable-lavf --enable-pic"
+EXTRA_OEMAKE = ""
+AS = "${TARGET_PREFIX}gcc"
+
+LIC_FILES_CHKSUM = "file://COPYING;md5=94d55d512a9ba36caa9b7df079bae19f"
+
+inherit autotools pkgconfig
diff --git a/cmake/FindIconv.cmake b/cmake/FindIconv.cmake
index c65317a56..b0ae9013a 100644
--- a/cmake/FindIconv.cmake
+++ b/cmake/FindIconv.cmake
@@ -26,13 +26,16 @@
# ICONV_INCLUDE_DIRS - the libiconv include directory
# ICONV_LIBRARIES - The libraries needed to use libiconv
-set(_ICONV_ROOT_PATHS
- ${CMAKE_INSTALL_PREFIX}
-)
+if(APPLE AND NOT IOS)
+ set(ICONV_HINTS "/usr")
+endif()
+if(ICONV_HINTS)
+ set(ICONV_LIBRARIES_HINTS "${ICONV_HINTS}/lib")
+endif()
find_path(ICONV_INCLUDE_DIRS
NAMES iconv.h
- HINTS _ICONV_ROOT_PATHS
+ HINTS "${ICONV_HINTS}"
PATH_SUFFIXES include
)
@@ -42,8 +45,7 @@ endif()
find_library(ICONV_LIBRARIES
NAMES iconv
- HINTS ${_ICONV_ROOT_PATHS}
- PATH_SUFFIXES bin lib
+ HINTS "${ICONV_LIBRARIES_HINTS}"
)
include(FindPackageHandleStandardArgs)
diff --git a/cmake/FindSqlite3.cmake b/cmake/FindSqlite3.cmake
index 7cab06bd1..ea8d0292d 100644
--- a/cmake/FindSqlite3.cmake
+++ b/cmake/FindSqlite3.cmake
@@ -26,13 +26,16 @@
# SQLITE3_INCLUDE_DIRS - the sqlite3 include directory
# SQLITE3_LIBRARIES - The libraries needed to use sqlite3
-set(_SQLITE3_ROOT_PATHS
- ${CMAKE_INSTALL_PREFIX}
-)
+if(APPLE AND NOT IOS)
+ set(SQLITE3_HINTS "/usr")
+endif()
+if(SQLITE3_HINTS)
+ set(SQLITE3_LIBRARIES_HINTS "${SQLITE3_HINTS}/lib")
+endif()
find_path(SQLITE3_INCLUDE_DIRS
NAMES sqlite3.h
- HINTS _SQLITE3_ROOT_PATHS
+ HINTS "${SQLITE3_HINTS}"
PATH_SUFFIXES include
)
@@ -42,8 +45,7 @@ endif()
find_library(SQLITE3_LIBRARIES
NAMES sqlite3
- HINTS ${_SQLITE3_ROOT_PATHS}
- PATH_SUFFIXES bin lib
+ HINTS "${SQLITE3_LIBRARIES_HINTS}"
)
include(FindPackageHandleStandardArgs)
diff --git a/cmake/FindXML2.cmake b/cmake/FindXML2.cmake
index 9d0eebe14..cf0333f4b 100644
--- a/cmake/FindXML2.cmake
+++ b/cmake/FindXML2.cmake
@@ -26,13 +26,16 @@
# XML2_INCLUDE_DIRS - the libxml2 include directory
# XML2_LIBRARIES - The libraries needed to use libxml2
-set(_XML2_ROOT_PATHS
- ${CMAKE_INSTALL_PREFIX}
-)
+if(APPLE AND NOT IOS)
+ set(XML2_HINTS "/usr")
+endif()
+if(XML2_HINTS)
+ set(XML2_LIBRARIES_HINTS "${XML2_HINTS}/lib")
+endif()
find_path(XML2_INCLUDE_DIRS
NAMES libxml/xmlreader.h
- HINTS _XML2_ROOT_PATHS
+ HINTS "${XML2_HINTS}"
PATH_SUFFIXES include/libxml2
)
@@ -42,8 +45,7 @@ endif()
find_library(XML2_LIBRARIES
NAMES xml2
- HINTS ${_XML2_ROOT_PATHS}
- PATH_SUFFIXES bin lib
+ HINTS "${XML2_LIBRARIES_HINTS}"
)
include(FindPackageHandleStandardArgs)
diff --git a/cmake/FindZlib.cmake b/cmake/FindZlib.cmake
index f29d2a8db..ca718d860 100644
--- a/cmake/FindZlib.cmake
+++ b/cmake/FindZlib.cmake
@@ -26,9 +26,16 @@
# ZLIB_INCLUDE_DIRS - the zlib include directory
# ZLIB_LIBRARIES - The libraries needed to use zlib
+if(APPLE AND NOT IOS)
+ set(ZLIB_HINTS "/usr")
+endif()
+if(ZLIB_HINTS)
+ set(ZLIB_LIBRARIES_HINTS "${ZLIB_HINTS}/lib")
+endif()
+
find_path(ZLIB_INCLUDE_DIRS
NAMES zlib.h
- HINTS _ZLIB_ROOT_PATHS
+ HINTS "${ZLIB_HINTS}"
PATH_SUFFIXES include
)
@@ -39,12 +46,12 @@ endif()
if(ENABLE_STATIC)
find_library(ZLIB_LIBRARIES
NAMES zstatic zlibstatic zlibstaticd z
- PATH_SUFFIXES bin lib
+ HINTS "${ZLIB_LIBRARIES_HINTS}"
)
else()
find_library(ZLIB_LIBRARIES
NAMES z zlib zlibd
- PATH_SUFFIXES bin lib
+ HINTS "${ZLIB_LIBRARIES_HINTS}"
)
endif()
diff --git a/configure.ac b/configure.ac
index 633738e7e..d36e66dbf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1120,6 +1120,7 @@ AC_CONFIG_FILES([
tester/Makefile
gtk/Makefile
console/Makefile
+ daemon/Makefile
share/Makefile
share/C/Makefile
share/fr/Makefile
diff --git a/coreapi/TunnelManager.cc b/coreapi/TunnelManager.cc
index b74baedb2..15e7c29b5 100644
--- a/coreapi/TunnelManager.cc
+++ b/coreapi/TunnelManager.cc
@@ -100,6 +100,15 @@ void TunnelManager::startClient() {
ms_message("TunnelManager: Starting tunnel client");
mTunnelClient = new TunnelClient(TRUE);
mTunnelClient->setCallback((TunnelClientController::StateCallback)tunnelCallback,this);
+ if (mVerifyServerCertificate) {
+ const char *rootCertificatePath = linphone_core_get_root_ca(mCore);
+ if (rootCertificatePath != NULL) {
+ ms_message("TunnelManager: Load root certificate from %s", rootCertificatePath);
+ mTunnelClient->setRootCertificate(rootCertificatePath); /* give the path to root certificate to the tunnel client in order to be able to verify the server certificate */
+ } else {
+ ms_warning("TunnelManager is set to verify server certificate but no root certificate is available in linphoneCore");
+ }
+ }
list::iterator it;
for(it=mServerAddrs.begin();it!=mServerAddrs.end();++it){
const ServerAddr &addr=*it;
@@ -334,7 +343,7 @@ LinphoneTunnelMode TunnelManager::getMode() const {
void TunnelManager::processUdpMirrorEvent(const Event &ev){
if(mState != autodetecting) return;
if (ev.mData.mHaveUdp) {
- ms_message("TunnelManager: UDP mirror test succeed");
+ ms_message("TunnelManager: UDP mirror test succeed on %s:%d", mCurrentUdpMirrorClient->getServerAddress().mAddr.c_str(), mCurrentUdpMirrorClient->getServerAddress().mPort);
if(mTunnelClient) {
if(mTunnelizeSipPackets) doUnregistration();
sal_set_tunnel(mCore->sal,NULL);
@@ -344,10 +353,10 @@ void TunnelManager::processUdpMirrorEvent(const Event &ev){
}
mState = disabled;
} else {
- ms_message("TunnelManager: UDP mirror test failed");
+ ms_message("TunnelManager: UDP mirror test failed on %s:%d", mCurrentUdpMirrorClient->getServerAddress().mAddr.c_str(), mCurrentUdpMirrorClient->getServerAddress().mPort);
mCurrentUdpMirrorClient++;
if (mCurrentUdpMirrorClient !=mUdpMirrorClients.end()) {
- ms_message("TunnelManager: trying another UDP mirror");
+ ms_message("TunnelManager: trying another UDP mirror on %s:%d", mCurrentUdpMirrorClient->getServerAddress().mAddr.c_str(), mCurrentUdpMirrorClient->getServerAddress().mPort);
if (mLongRunningTaskId == 0)
mLongRunningTaskId = sal_begin_background_task("Tunnel auto detect", NULL, NULL);
UdpMirrorClient &lUdpMirrorClient=*mCurrentUdpMirrorClient;
@@ -427,6 +436,14 @@ bool TunnelManager::tunnelizeSipPacketsEnabled() const {
return mTunnelizeSipPackets;
}
+void TunnelManager::verifyServerCertificate(bool enable){
+ mVerifyServerCertificate = enable;
+}
+
+bool TunnelManager::verifyServerCertificateEnabled() const {
+ return mVerifyServerCertificate;
+}
+
void TunnelManager::setHttpProxy(const char *host,int port, const char *username, const char *passwd){
mHttpUserName=username?username:"";
mHttpPasswd=passwd?passwd:"";
diff --git a/coreapi/TunnelManager.hh b/coreapi/TunnelManager.hh
index 764c8efda..dccaf8756 100644
--- a/coreapi/TunnelManager.hh
+++ b/coreapi/TunnelManager.hh
@@ -110,6 +110,18 @@ namespace belledonnecomm {
* @return True, SIP packets pass through the tunnel
*/
bool tunnelizeSipPacketsEnabled() const;
+ /**
+ * Indicate to the tunnel manager wether server certificate
+ * must be verified during TLS handshake. Default: disabled
+ * @param enable If set to TRUE, SIP packets will pass through the tunnel.
+ * If set to FALSE, SIP packets will pass by the configured proxies.
+ */
+ void verifyServerCertificate(bool enable);
+ /**
+ * Check wether the tunnel manager is set to verify server certificate during TLS handshake
+ * @return True, server certificate is verified(using the linphonecore root certificate)
+ */
+ bool verifyServerCertificateEnabled() const;
/**
* @brief Constructor
* @param lc The LinphoneCore instance of which the TunnelManager will be associated to.
@@ -188,6 +200,7 @@ namespace belledonnecomm {
LinphoneTunnelMode mMode;
State mState;
bool mTunnelizeSipPackets;
+ bool mVerifyServerCertificate;
TunnelClient* mTunnelClient;
std::string mHttpUserName;
std::string mHttpPasswd;
diff --git a/coreapi/account_creator.c b/coreapi/account_creator.c
index d1eb954a5..1ea4aabb5 100644
--- a/coreapi/account_creator.c
+++ b/coreapi/account_creator.c
@@ -170,9 +170,13 @@ static char* _get_identity(const LinphoneAccountCreator *creator) {
//we must escape username
LinphoneProxyConfig* proxy = linphone_proxy_config_new();
LinphoneAddress* addr;
- linphone_proxy_config_set_identity(proxy, "sip:userame@domain.com");
+ // creator->domain may contain some port or some transport (eg. toto.org:443;transport=tcp),
+ // we will accept that
+ char * tmpidentity = ms_strdup_printf("sip:username@%s", creator->domain);
+ linphone_proxy_config_set_identity(proxy, tmpidentity);
+ ms_free(tmpidentity);
addr = linphone_proxy_config_normalize_sip_uri(proxy, creator->username);
- linphone_address_set_domain(addr, creator->domain);
+
identity = linphone_address_as_string(addr);
linphone_address_destroy(addr);
linphone_proxy_config_destroy(proxy);
diff --git a/coreapi/bellesip_sal/sal_impl.c b/coreapi/bellesip_sal/sal_impl.c
index 131d7656c..010921544 100644
--- a/coreapi/bellesip_sal/sal_impl.c
+++ b/coreapi/bellesip_sal/sal_impl.c
@@ -501,6 +501,7 @@ Sal * sal_init(MSFactory *factory){
sal->refresher_retry_after=60000; /*default value in ms*/
sal->enable_sip_update=TRUE;
sal->pending_trans_checking=TRUE;
+ sal->ssl_config = NULL;
return sal;
}
@@ -746,6 +747,7 @@ static void set_tls_properties(Sal *ctx){
else if (!ctx->tls_verify_cn) verify_exceptions = BELLE_TLS_VERIFY_CN_MISMATCH;
belle_tls_crypto_config_set_verify_exceptions(crypto_config, verify_exceptions);
if (ctx->root_ca != NULL) belle_tls_crypto_config_set_root_ca(crypto_config, ctx->root_ca);
+ if (ctx->ssl_config != NULL) belle_tls_crypto_config_set_ssl_config(crypto_config, ctx->ssl_config);
belle_sip_tls_listening_point_set_crypto_config(tlp, crypto_config);
belle_sip_object_unref(crypto_config);
}
@@ -774,6 +776,12 @@ void sal_verify_server_cn(Sal *ctx, bool_t verify){
return ;
}
+void sal_set_ssl_config(Sal *ctx, void *ssl_config) {
+ ctx->ssl_config = ssl_config;
+ set_tls_properties(ctx);
+ return ;
+}
+
void sal_use_tcp_tls_keepalive(Sal *ctx, bool_t enabled) {
ctx->use_tcp_tls_keep_alive=enabled;
}
diff --git a/coreapi/bellesip_sal/sal_impl.h b/coreapi/bellesip_sal/sal_impl.h
index b9175a7d0..a77ed6855 100644
--- a/coreapi/bellesip_sal/sal_impl.h
+++ b/coreapi/bellesip_sal/sal_impl.h
@@ -53,6 +53,7 @@ struct Sal{
bool_t enable_sip_update; /*true by default*/
SalOpSDPHandling default_sdp_handling;
bool_t pending_trans_checking; /*testing purpose*/
+ void *ssl_config;
};
typedef enum SalOpState {
diff --git a/coreapi/bellesip_sal/sal_op_presence.c b/coreapi/bellesip_sal/sal_op_presence.c
index 6e9f0e6d2..dd157b3f6 100644
--- a/coreapi/bellesip_sal/sal_op_presence.c
+++ b/coreapi/bellesip_sal/sal_op_presence.c
@@ -47,7 +47,29 @@ void sal_add_presence_info(SalOp *op, belle_sip_message_t *notify, SalPresenceMo
}
static void presence_process_io_error(void *user_ctx, const belle_sip_io_error_event_t *event){
- /*ms_error("presence_process_io_error not implemented yet");*/
+ SalOp* op = (SalOp*)user_ctx;
+ belle_sip_request_t* request;
+ belle_sip_client_transaction_t* client_transaction = NULL;
+
+ if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(belle_sip_io_error_event_get_source(event),
+ belle_sip_client_transaction_t)){
+ client_transaction = (belle_sip_client_transaction_t*)belle_sip_io_error_event_get_source(event);
+ }
+
+ if (!client_transaction) return;
+
+ request = belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(client_transaction));
+
+ if (strcmp("SUBSCRIBE",belle_sip_request_get_method(request))==0){
+ if (op->refresher){
+ ms_warning("presence_process_io_error() refresher is present, should not happen");
+ return;
+ }
+ ms_message("subscription to [%s] io error",sal_op_get_to(op));
+ if (!op->op_released){
+ op->base.root->callbacks.notify_presence(op,SalSubscribeTerminated, NULL,NULL); /*NULL = offline*/
+ }
+ }
}
static void presence_process_dialog_terminated(void *ctx, const belle_sip_dialog_terminated_event_t *event) {
@@ -81,6 +103,12 @@ static void presence_refresher_listener(belle_sip_refresher_t* refresher, void*
/*send a new SUBSCRIBE, that will attempt to establish a new dialog*/
sal_subscribe_presence(op,NULL,NULL,-1);
}
+ if (status_code == 0 || status_code == 503){
+ /*timeout or io error: the remote doesn't seem reachable.*/
+ if (!op->op_released){
+ op->base.root->callbacks.notify_presence(op,SalSubscribeActive, NULL,NULL); /*NULL = offline*/
+ }
+ }
}
diff --git a/coreapi/bellesip_sal/sal_op_registration.c b/coreapi/bellesip_sal/sal_op_registration.c
index 961ba4a34..5ae75722f 100644
--- a/coreapi/bellesip_sal/sal_op_registration.c
+++ b/coreapi/bellesip_sal/sal_op_registration.c
@@ -25,8 +25,8 @@ static void register_refresher_listener (belle_sip_refresher_t* refresher
,const char* reason_phrase) {
SalOp* op = (SalOp*)user_pointer;
belle_sip_response_t* response=belle_sip_transaction_get_response(BELLE_SIP_TRANSACTION(belle_sip_refresher_get_transaction(refresher)));
- ms_message("Register refresher [%i] reason [%s] for proxy [%s]",status_code,reason_phrase,sal_op_get_proxy(op));
-
+ ms_message("Register refresher [%i] reason [%s] for proxy [%s]",status_code,reason_phrase,sal_op_get_proxy(op));
+
if (belle_sip_refresher_get_auth_events(refresher)) {
if (op->auth_info) sal_auth_info_delete(op->auth_info);
/*only take first one for now*/
@@ -46,7 +46,7 @@ static void register_refresher_listener (belle_sip_refresher_t* refresher
}
sal_op_set_service_route(op,(const SalAddress*)service_route_address);
if (service_route_address) belle_sip_object_unref(service_route_address);
-
+
sal_remove_pending_auth(op->base.root,op); /*just in case*/
if (contact) {
sal_op_set_contact_address(op,(SalAddress*)(BELLE_SIP_HEADER_ADDRESS(contact))); /*update contact with real value*/
@@ -79,13 +79,13 @@ int sal_register(SalOp *op, const char *proxy, const char *from, int expires,Sal
belle_sip_request_t *req;
belle_sip_uri_t* req_uri;
belle_sip_header_t* accept_header;
-
+
if (op->refresher){
belle_sip_refresher_stop(op->refresher);
belle_sip_object_unref(op->refresher);
op->refresher=NULL;
}
-
+
op->type=SalOpRegister;
sal_op_set_from(op,from);
sal_op_set_to(op,from);
diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c
index 1e14854a9..41b399e08 100644
--- a/coreapi/callbacks.c
+++ b/coreapi/callbacks.c
@@ -158,12 +158,12 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia
if (call->all_muted){
ms_message("Early media finished, unmuting inputs...");
/*we were in early media, now we want to enable real media */
- linphone_call_enable_camera (call,linphone_call_camera_enabled (call));
+ call->all_muted = FALSE;
if (call->audiostream)
linphone_core_enable_mic(lc, linphone_core_mic_enabled(lc));
#ifdef VIDEO_ENABLED
if (call->videostream && call->camera_enabled)
- video_stream_change_camera(call->videostream,linphone_call_get_video_device(call));
+ linphone_call_enable_camera(call, linphone_call_camera_enabled(call));
#endif
}
/*FIXME ZRTP, might be restarted in any cases ? */
diff --git a/coreapi/carddav.c b/coreapi/carddav.c
index 6bfcb1d8e..233da34a8 100644
--- a/coreapi/carddav.c
+++ b/coreapi/carddav.c
@@ -31,7 +31,7 @@ LinphoneCardDavContext* linphone_carddav_context_new(LinphoneFriendList *lfl) {
carddav_context = (LinphoneCardDavContext *)ms_new0(LinphoneCardDavContext, 1);
carddav_context->friend_list = linphone_friend_list_ref(lfl);
#else
- ms_error("vCard isn't available (maybe it wasn't compiled), can't do CardDAV sync");
+ ms_error("[carddav] vCard isn't available (maybe it wasn't compiled), can't do CardDAV sync");
#endif
return carddav_context;
}
@@ -64,7 +64,7 @@ static void linphone_carddav_sync_done(LinphoneCardDavContext *cdc, bool_t succe
ms_debug("CardDAV sync successful, saving new cTag: %i", cdc->ctag);
linphone_friend_list_update_revision(cdc->friend_list, cdc->ctag);
} else {
- ms_error("CardDAV sync failure: %s", msg);
+ ms_error("[carddav] CardDAV sync failure: %s", msg);
}
if (cdc->sync_done_cb) {
@@ -105,31 +105,38 @@ static void linphone_carddav_vcards_pulled(LinphoneCardDavContext *cdc, MSList *
linphone_vcard_set_url(lvc, full_url);
linphone_vcard_set_etag(lvc, vCard->etag);
ms_debug("Downloaded vCard etag/url are %s and %s", vCard->etag, full_url);
- }
- lf = linphone_friend_new_from_vcard(lvc);
- local_friend = ms_list_find_custom(friends, (int (*)(const void*, const void*))find_matching_friend, lf);
-
- if (local_friend) {
- LinphoneFriend *lf2 = (LinphoneFriend *)local_friend->data;
- lf->storage_id = lf2->storage_id;
- lf->pol = lf2->pol;
- lf->subscribe = lf2->subscribe;
- lf->refkey = ms_strdup(lf2->refkey);
- lf->presence_received = lf2->presence_received;
- lf->lc = lf2->lc;
- lf->friend_list = lf2->friend_list;
-
- if (cdc->contact_updated_cb) {
- ms_debug("Contact updated: %s", linphone_friend_get_name(lf));
- cdc->contact_updated_cb(cdc, lf, lf2);
+
+ lf = linphone_friend_new_from_vcard(lvc);
+ if (lf) {
+ local_friend = ms_list_find_custom(friends, (int (*)(const void*, const void*))find_matching_friend, lf);
+
+ if (local_friend) {
+ LinphoneFriend *lf2 = (LinphoneFriend *)local_friend->data;
+ lf->storage_id = lf2->storage_id;
+ lf->pol = lf2->pol;
+ lf->subscribe = lf2->subscribe;
+ lf->refkey = ms_strdup(lf2->refkey);
+ lf->presence_received = lf2->presence_received;
+ lf->lc = lf2->lc;
+ lf->friend_list = lf2->friend_list;
+
+ if (cdc->contact_updated_cb) {
+ ms_debug("Contact updated: %s", linphone_friend_get_name(lf));
+ cdc->contact_updated_cb(cdc, lf, lf2);
+ }
+ } else {
+ if (cdc->contact_created_cb) {
+ ms_debug("Contact created: %s", linphone_friend_get_name(lf));
+ cdc->contact_created_cb(cdc, lf);
+ }
+ }
+ linphone_friend_unref(lf);
+ } else {
+ ms_error("[carddav] Couldn't create a friend from vCard");
}
} else {
- if (cdc->contact_created_cb) {
- ms_debug("Contact created: %s", linphone_friend_get_name(lf));
- cdc->contact_created_cb(cdc, lf);
- }
+ ms_error("[carddav] Couldn't parse vCard %s", vCard->vcard);
}
- linphone_friend_unref(lf);
}
vCards = ms_list_next(vCards);
}
@@ -367,7 +374,7 @@ static void process_response_from_carddav_request(void *data, const belle_http_r
linphone_carddav_sync_done(query->context, TRUE, NULL);
break;
default:
- ms_error("Unknown request: %i", query->type);
+ ms_error("[carddav] Unknown request: %i", query->type);
break;
}
} else {
@@ -383,7 +390,7 @@ static void process_response_from_carddav_request(void *data, const belle_http_r
static void process_io_error_from_carddav_request(void *data, const belle_sip_io_error_event_t *event) {
LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)data;
- ms_error("I/O error during CardDAV request sending");
+ ms_error("[carddav] I/O error during CardDAV request sending");
linphone_carddav_query_free(query);
linphone_carddav_sync_done(query->context, FALSE, "I/O error during CardDAV request sending");
}
@@ -412,7 +419,7 @@ static void process_auth_requested_from_carddav_request(void *data, belle_sip_au
}
if (!auth_infos) {
- ms_error("Authentication requested during CardDAV request sending, and username/password weren't provided");
+ ms_error("[carddav] Authentication requested during CardDAV request sending, and username/password weren't provided");
linphone_carddav_sync_done(query->context, FALSE, "Authentication requested during CardDAV request sending, and username/password weren't provided");
linphone_carddav_query_free(query);
}
@@ -528,7 +535,7 @@ void linphone_carddav_put_vcard(LinphoneCardDavContext *cdc, LinphoneFriend *lf)
}
if (msg) {
- ms_error("%s", msg);
+ ms_error("[carddav] %s", msg);
}
if (cdc && cdc->sync_done_cb) {
@@ -582,7 +589,7 @@ void linphone_carddav_delete_vcard(LinphoneCardDavContext *cdc, LinphoneFriend *
}
if (msg) {
- ms_error("%s", msg);
+ ms_error("[carddav] %s", msg);
}
if (cdc && cdc->sync_done_cb) {
diff --git a/coreapi/friend.c b/coreapi/friend.c
index 41d191535..7d0c43196 100644
--- a/coreapi/friend.c
+++ b/coreapi/friend.c
@@ -195,6 +195,10 @@ void linphone_core_interpret_friend_uri(LinphoneCore *lc, const char *uri, char
}
}
+const LinphoneAddress *linphone_friend_get_address(const LinphoneFriend *lf){
+ return lf->uri;
+}
+
int linphone_friend_set_address(LinphoneFriend *lf, const LinphoneAddress *addr){
LinphoneAddress *fr = linphone_address_clone(addr);
LinphoneVcard *vcard = NULL;
@@ -211,6 +215,106 @@ int linphone_friend_set_address(LinphoneFriend *lf, const LinphoneAddress *addr)
return 0;
}
+void linphone_friend_add_address(LinphoneFriend *lf, const LinphoneAddress *addr) {
+ LinphoneVcard *vcard = NULL;
+ if (!lf || !addr) {
+ return;
+ }
+
+ vcard = linphone_friend_get_vcard(lf);
+ if (!vcard) {
+ return;
+ }
+
+ linphone_vcard_add_sip_address(vcard, linphone_address_as_string_uri_only(addr));
+}
+
+MSList* linphone_friend_get_addresses(LinphoneFriend *lf) {
+ LinphoneVcard *vcard = NULL;
+ MSList *sipAddresses = NULL;
+ MSList *addresses = NULL;
+ MSList *iterator = NULL;
+
+ if (!lf) {
+ return NULL;
+ }
+
+ vcard = linphone_friend_get_vcard(lf);
+ if (!vcard) {
+ return NULL;
+ }
+
+ sipAddresses = linphone_vcard_get_sip_addresses(vcard);
+ iterator = sipAddresses;
+ while (iterator) {
+ const char *sipAddress = (const char *)iterator->data;
+ LinphoneAddress *addr = linphone_address_new(sipAddress);
+ if (addr) {
+ addresses = ms_list_append(addresses, addr);
+ }
+ iterator = ms_list_next(iterator);
+ }
+ if (sipAddresses) ms_list_free(sipAddresses);
+ return addresses;
+}
+
+void linphone_friend_remove_address(LinphoneFriend *lf, const LinphoneAddress *addr) {
+ LinphoneVcard *vcard = NULL;
+ if (!lf || !addr) {
+ return;
+ }
+
+ vcard = linphone_friend_get_vcard(lf);
+ if (!vcard) {
+ return;
+ }
+
+ linphone_vcard_remove_sip_address(vcard, linphone_address_as_string_uri_only(addr));
+}
+
+void linphone_friend_add_phone_number(LinphoneFriend *lf, const char *phone) {
+ LinphoneVcard *vcard = NULL;
+ if (!lf || !phone) {
+ return;
+ }
+
+ vcard = linphone_friend_get_vcard(lf);
+ if (!vcard) {
+ return;
+ }
+
+ linphone_vcard_add_phone_number(vcard, phone);
+}
+
+MSList* linphone_friend_get_phone_numbers(LinphoneFriend *lf) {
+ LinphoneVcard *vcard = NULL;
+
+ if (!lf) {
+ return NULL;
+ }
+
+ vcard = linphone_friend_get_vcard(lf);
+ if (!vcard) {
+ return NULL;
+ }
+
+ return linphone_vcard_get_phone_numbers(vcard);
+}
+
+void linphone_friend_remove_phone_number(LinphoneFriend *lf, const char *phone) {
+ LinphoneVcard *vcard = NULL;
+ if (!lf || !phone) {
+ return;
+ }
+
+ vcard = linphone_friend_get_vcard(lf);
+ if (!vcard) {
+ return;
+ }
+
+ linphone_vcard_remove_phone_number(vcard, phone);
+}
+
int linphone_friend_set_name(LinphoneFriend *lf, const char *name){
LinphoneAddress *fr = lf->uri;
LinphoneVcard *vcard = NULL;
@@ -334,10 +438,6 @@ static belle_sip_error_code _linphone_friend_marshall(belle_sip_object_t *obj, c
return err;
}
-const LinphoneAddress *linphone_friend_get_address(const LinphoneFriend *lf){
- return lf->uri;
-}
-
const char * linphone_friend_get_name(const LinphoneFriend *lf) {
if (lf && lf->vcard) {
return linphone_vcard_get_full_name(lf->vcard);
@@ -360,6 +460,7 @@ LinphoneOnlineStatus linphone_friend_get_status(const LinphoneFriend *lf){
LinphoneOnlineStatus online_status = LinphoneStatusOffline;
LinphonePresenceBasicStatus basic_status = LinphonePresenceBasicStatusClosed;
LinphonePresenceActivity *activity = NULL;
+ const char *description = NULL;
unsigned int nb_activities = 0;
if (lf->presence != NULL) {
@@ -376,6 +477,7 @@ LinphoneOnlineStatus linphone_friend_get_status(const LinphoneFriend *lf){
}
if (nb_activities == 1) {
activity = linphone_presence_model_get_activity(lf->presence);
+ description = linphone_presence_activity_get_description(activity);
switch (linphone_presence_activity_get_type(activity)) {
case LinphonePresenceActivityBreakfast:
case LinphonePresenceActivityDinner:
@@ -402,6 +504,12 @@ LinphoneOnlineStatus linphone_friend_get_status(const LinphoneFriend *lf){
online_status = LinphoneStatusVacation;
break;
case LinphonePresenceActivityBusy:
+ if (description && strcmp(description, "Do not disturb") == 0) { // See linphonecore.c linphone_core_set_presence_info() method
+ online_status = LinphoneStatusDoNotDisturb;
+ } else {
+ online_status = LinphoneStatusBusy;
+ }
+ break;
case LinphonePresenceActivityLookingForWork:
case LinphonePresenceActivityPlaying:
case LinphonePresenceActivityShopping:
@@ -915,6 +1023,7 @@ LinphoneFriend *linphone_friend_new_from_vcard(LinphoneVcard *vcard) {
linphone_friend_set_address(fr, linphone_address);
linphone_address_unref(linphone_address);
}
+ ms_free(sipAddresses);
}
if (name) {
linphone_friend_set_name(fr, name);
@@ -1366,7 +1475,7 @@ void linphone_core_migrate_friends_from_rc_to_db(LinphoneCore *lc) {
return;
}
- if (ms_list_size(linphone_friend_list_get_friends(lfl)) > 0) {
+ if (ms_list_size(linphone_friend_list_get_friends(lfl)) > 0 && lfl->storage_id == 0) {
linphone_core_remove_friend_list(lc, lfl);
lfl = linphone_core_create_friend_list(lc);
linphone_core_add_friend_list(lc, lfl);
diff --git a/coreapi/friendlist.c b/coreapi/friendlist.c
index 1ab02b5a5..40f083802 100644
--- a/coreapi/friendlist.c
+++ b/coreapi/friendlist.c
@@ -296,6 +296,7 @@ static void linphone_friend_list_destroy(LinphoneFriendList *list) {
if (list->event != NULL) {
linphone_event_terminate(list->event);
linphone_event_unref(list->event);
+ list->event = NULL;
}
if (list->uri != NULL) ms_free(list->uri);
if (list->cbs) linphone_friend_list_cbs_unref(list->cbs);
@@ -436,7 +437,7 @@ LinphoneFriendListStatus linphone_friend_list_import_friend(LinphoneFriendList *
return LinphoneFriendListOK;
}
-static void carddav_done(LinphoneCardDavContext *cdc, bool_t success, const char *msg) {
+static void carddav_done(LinphoneCardDavContext *cdc, bool_t success, const char *msg) {
if (cdc && cdc->friend_list->cbs->sync_state_changed_cb) {
cdc->friend_list->cbs->sync_state_changed_cb(cdc->friend_list, success ? LinphoneFriendListSyncSuccessful : LinphoneFriendListSyncFailure, msg);
}
@@ -465,7 +466,7 @@ static LinphoneFriendListStatus _linphone_friend_list_remove_friend(LinphoneFrie
}
}
}
-
+
lf->friend_list = NULL;
linphone_friend_unref(lf);
list->friends = ms_list_remove_link(list->friends, elem);
@@ -483,7 +484,7 @@ const MSList * linphone_friend_list_get_friends(const LinphoneFriendList *list)
void linphone_friend_list_update_dirty_friends(LinphoneFriendList *list) {
LinphoneCardDavContext *cdc = linphone_carddav_context_new(list);
MSList *dirty_friends = list->dirty_friends_to_update;
-
+
if (cdc) {
cdc->sync_done_cb = carddav_done;
while (dirty_friends) {
@@ -528,7 +529,7 @@ static void carddav_updated(LinphoneCardDavContext *cdc, LinphoneFriend *lf_new,
elem->data = linphone_friend_ref(lf_new);
}
linphone_core_store_friend_in_db(lf_new->lc, lf_new);
-
+
if (cdc->friend_list->cbs->contact_updated_cb) {
cdc->friend_list->cbs->contact_updated_cb(lfl, lf_new, lf_old);
}
@@ -538,7 +539,7 @@ static void carddav_updated(LinphoneCardDavContext *cdc, LinphoneFriend *lf_new,
void linphone_friend_list_synchronize_friends_from_server(LinphoneFriendList *list) {
LinphoneCardDavContext *cdc = linphone_carddav_context_new(list);
-
+
if (cdc) {
cdc->contact_created_cb = carddav_created;
cdc->contact_removed_cb = carddav_removed;
@@ -601,6 +602,8 @@ void linphone_friend_list_close_subscriptions(LinphoneFriendList *list) {
/* FIXME we should wait until subscription to complete. */
if (list->event) {
linphone_event_terminate(list->event);
+ linphone_event_unref(list->event);
+ list->event = NULL;
} else if (list->friends)
ms_list_for_each(list->friends, (void (*)(void *))linphone_friend_close_subscriptions);
}
@@ -734,7 +737,7 @@ void linphone_friend_list_subscription_state_changed(LinphoneCore *lc, LinphoneE
, linphone_subscription_state_to_string(state)
, lev
, list);
-
+
if (state == LinphoneSubscriptionOutgoingProgress && linphone_event_get_reason(lev) == LinphoneReasonNoMatch) {
ms_message("Resseting version count for friend list [%p]",list);
list->expected_notification_version = 0;
@@ -749,7 +752,7 @@ LinphoneCore* linphone_friend_list_get_core(LinphoneFriendList *list) {
int linphone_friend_list_import_friends_from_vcard4_file(LinphoneFriendList *list, const char *vcard_file) {
MSList *vcards = linphone_vcard_list_from_vcard4_file(vcard_file);
int count = 0;
-
+
#ifndef VCARD_ENABLED
ms_error("vCard support wasn't enabled at compilation time");
return -1;
@@ -762,7 +765,7 @@ int linphone_friend_list_import_friends_from_vcard4_file(LinphoneFriendList *lis
ms_error("Can't import into a NULL list");
return -1;
}
-
+
while (vcards != NULL && vcards->data != NULL) {
LinphoneVcard *vcard = (LinphoneVcard *)vcards->data;
LinphoneFriend *lf = linphone_friend_new_from_vcard(vcard);
@@ -785,7 +788,7 @@ int linphone_friend_list_import_friends_from_vcard4_file(LinphoneFriendList *lis
int linphone_friend_list_import_friends_from_vcard4_buffer(LinphoneFriendList *list, const char *vcard_buffer) {
MSList *vcards = linphone_vcard_list_from_vcard4_buffer(vcard_buffer);
int count = 0;
-
+
#ifndef VCARD_ENABLED
ms_error("vCard support wasn't enabled at compilation time");
return -1;
@@ -798,7 +801,7 @@ int linphone_friend_list_import_friends_from_vcard4_buffer(LinphoneFriendList *l
ms_error("Can't import into a NULL list");
return -1;
}
-
+
while (vcards != NULL && vcards->data != NULL) {
LinphoneVcard *vcard = (LinphoneVcard *)vcards->data;
LinphoneFriend *lf = linphone_friend_new_from_vcard(vcard);
@@ -821,13 +824,13 @@ int linphone_friend_list_import_friends_from_vcard4_buffer(LinphoneFriendList *l
void linphone_friend_list_export_friends_as_vcard4_file(LinphoneFriendList *list, const char *vcard_file) {
FILE *file = NULL;
const MSList *friends = linphone_friend_list_get_friends(list);
-
+
file = fopen(vcard_file, "wb");
if (file == NULL) {
ms_warning("Could not write %s ! Maybe it is read-only. Contacts will not be saved.", vcard_file);
return;
}
-
+
#ifndef VCARD_ENABLED
ms_error("vCard support wasn't enabled at compilation time");
#endif
@@ -842,6 +845,6 @@ void linphone_friend_list_export_friends_as_vcard4_file(LinphoneFriendList *list
}
friends = ms_list_next(friends);
}
-
+
fclose(file);
}
diff --git a/coreapi/help/Doxyfile.in b/coreapi/help/Doxyfile.in
index 6692ba25e..b0230913f 100644
--- a/coreapi/help/Doxyfile.in
+++ b/coreapi/help/Doxyfile.in
@@ -496,7 +496,7 @@ HIDE_IN_BODY_DOCS = NO
# will be excluded. Set it to YES to include the internal documentation.
# The default value is: NO.
-INTERNAL_DOCS = NO
+INTERNAL_DOCS = YES
# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
# names in lower-case letters. If set to YES, upper-case letters are also
diff --git a/coreapi/linphone_proxy_config.h b/coreapi/linphone_proxy_config.h
index 3bd1cda3d..2fb5bda9f 100644
--- a/coreapi/linphone_proxy_config.h
+++ b/coreapi/linphone_proxy_config.h
@@ -524,6 +524,29 @@ LINPHONE_PUBLIC void linphone_proxy_config_set_custom_header(LinphoneProxyConfig
**/
LINPHONE_PUBLIC const LinphoneAuthInfo* linphone_proxy_config_find_auth_info(const LinphoneProxyConfig *cfg);
+
+/**
+ * Get the persistent reference key associated to the proxy config.
+ *
+ * The reference key can be for example an id to an external database.
+ * It is stored in the config file, thus can survive to process exits/restarts.
+ *
+ * @param[in] cfg #LinphoneProxyConfig object.
+ * @return The reference key string that has been associated to the proxy config, or NULL if none has been associated.
+**/
+LINPHONE_PUBLIC const char * linphone_proxy_config_get_ref_key(const LinphoneProxyConfig *cfg);
+
+/**
+ * Associate a persistent reference key to the proxy config.
+ *
+ * The reference key can be for example an id to an external database.
+ * It is stored in the config file, thus can survive to process exits/restarts.
+ *
+ * @param[in] cfg #LinphoneProxyConfig object.
+ * @param[in] refkey The reference key string to associate to the proxy config.
+**/
+LINPHONE_PUBLIC void linphone_proxy_config_set_ref_key(LinphoneProxyConfig *cfg, const char *refkey);
+
/**
* @}
*/
diff --git a/coreapi/linphone_tunnel.cc b/coreapi/linphone_tunnel.cc
index a751bc948..b6529499f 100644
--- a/coreapi/linphone_tunnel.cc
+++ b/coreapi/linphone_tunnel.cc
@@ -330,6 +330,15 @@ bool_t linphone_tunnel_sip_enabled(const LinphoneTunnel *tunnel) {
return bcTunnel(tunnel)->tunnelizeSipPacketsEnabled() ? TRUE : FALSE;
}
+void linphone_tunnel_verify_server_certificate(LinphoneTunnel *tunnel, bool_t enable) {
+ bcTunnel(tunnel)->verifyServerCertificate(enable);
+ lp_config_set_int(config(tunnel), "tunnel", "verifyCert", (enable ? TRUE : FALSE));
+}
+
+bool_t linphone_tunnel_verify_server_certificate_enabled(const LinphoneTunnel *tunnel) {
+ return bcTunnel(tunnel)->verifyServerCertificateEnabled() ? TRUE : FALSE;
+}
+
static void my_ortp_logv(const char *domain, OrtpLogLevel level, const char *fmt, va_list args){
ortp_logv(domain, level,fmt,args);
}
@@ -342,14 +351,17 @@ static void my_ortp_logv(const char *domain, OrtpLogLevel level, const char *fmt
void linphone_tunnel_configure(LinphoneTunnel *tunnel){
LinphoneTunnelMode mode = linphone_tunnel_mode_from_string(lp_config_get_string(config(tunnel), "tunnel", "mode", NULL));
bool_t tunnelizeSIPPackets = (bool_t)lp_config_get_int(config(tunnel), "tunnel", "sip", TRUE);
+ bool_t tunnelVerifyServerCertificate = (bool_t)lp_config_get_int(config(tunnel), "tunnel", "verifyCert", FALSE);
linphone_tunnel_enable_logs_with_handler(tunnel,TRUE,my_ortp_logv);
linphone_tunnel_load_config(tunnel);
linphone_tunnel_enable_sip(tunnel, tunnelizeSIPPackets);
linphone_tunnel_set_mode(tunnel, mode);
+ linphone_tunnel_verify_server_certificate(tunnel, tunnelVerifyServerCertificate);
}
/* Deprecated functions */
void linphone_tunnel_enable(LinphoneTunnel *tunnel, bool_t enabled) {
+ ms_warning("linphone_tunnel_enable is deprecated - please use linphone_tunnel_set_mode instead.");
if(enabled) linphone_tunnel_set_mode(tunnel, LinphoneTunnelModeEnable);
else linphone_tunnel_set_mode(tunnel, LinphoneTunnelModeDisable);
}
diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c
index 1abb1c452..1e95540ca 100644
--- a/coreapi/linphonecall.c
+++ b/coreapi/linphonecall.c
@@ -765,6 +765,7 @@ void linphone_call_make_local_media_description(LinphoneCall *call) {
} else {
ms_message("Don't put audio stream on local offer for call [%p]",call);
md->streams[call->main_audio_stream_index].dir = SalStreamInactive;
+ if(l) l=ms_list_free_with_data(l, (void (*)(void *))payload_type_destroy);
}
if (params->custom_sdp_media_attributes[LinphoneStreamTypeAudio])
md->streams[call->main_audio_stream_index].custom_sdp_attributes = sal_custom_sdp_attribute_clone(params->custom_sdp_media_attributes[LinphoneStreamTypeAudio]);
@@ -799,6 +800,7 @@ void linphone_call_make_local_media_description(LinphoneCall *call) {
} else {
ms_message("Don't put video stream on local offer for call [%p]",call);
md->streams[call->main_video_stream_index].dir = SalStreamInactive;
+ if(l) l=ms_list_free_with_data(l, (void (*)(void *))payload_type_destroy);
}
if (params->custom_sdp_media_attributes[LinphoneStreamTypeVideo])
md->streams[call->main_video_stream_index].custom_sdp_attributes = sal_custom_sdp_attribute_clone(params->custom_sdp_media_attributes[LinphoneStreamTypeVideo]);
@@ -1728,6 +1730,7 @@ static void linphone_call_destroy(LinphoneCall *obj){
linphone_address_unref(obj->me);
obj->me = NULL;
}
+ if (obj->onhold_file) ms_free(obj->onhold_file);
sal_error_info_reset(&obj->non_op_error);
}
@@ -2069,15 +2072,23 @@ LinphoneCall *linphone_call_get_replaced_call(LinphoneCall *call){
void linphone_call_enable_camera (LinphoneCall *call, bool_t enable){
#ifdef VIDEO_ENABLED
call->camera_enabled=enable;
- if ((call->state==LinphoneCallStreamsRunning || call->state==LinphoneCallOutgoingEarlyMedia || call->state==LinphoneCallIncomingEarlyMedia)
- && call->videostream!=NULL && video_stream_started(call->videostream) ){
- if (video_stream_get_camera(call->videostream) != linphone_call_get_video_device(call)) {
- const char *cur_cam, *new_cam;
- cur_cam = video_stream_get_camera(call->videostream) ? ms_web_cam_get_name(video_stream_get_camera(call->videostream)) : "NULL";
- new_cam = linphone_call_get_video_device(call) ? ms_web_cam_get_name(linphone_call_get_video_device(call)) : "NULL";
- ms_message("Switching video cam from [%s] to [%s] on call [%p]" , cur_cam, new_cam, call);
- video_stream_change_camera(call->videostream, linphone_call_get_video_device(call));
- }
+ switch(call->state) {
+ case LinphoneCallStreamsRunning:
+ case LinphoneCallOutgoingEarlyMedia:
+ case LinphoneCallIncomingEarlyMedia:
+ case LinphoneCallConnected:
+ if(call->videostream!=NULL
+ && video_stream_started(call->videostream)
+ && video_stream_get_camera(call->videostream) != linphone_call_get_video_device(call)) {
+ const char *cur_cam, *new_cam;
+ cur_cam = video_stream_get_camera(call->videostream) ? ms_web_cam_get_name(video_stream_get_camera(call->videostream)) : "NULL";
+ new_cam = linphone_call_get_video_device(call) ? ms_web_cam_get_name(linphone_call_get_video_device(call)) : "NULL";
+ ms_message("Switching video cam from [%s] to [%s] on call [%p]" , cur_cam, new_cam, call);
+ video_stream_change_camera(call->videostream, linphone_call_get_video_device(call));
+ }
+ break;
+
+ default: break;
}
#endif
}
@@ -2272,7 +2283,7 @@ int linphone_call_prepare_ice(LinphoneCall *call, bool_t incoming_offer){
video_stream_prepare_video(call->videostream);
}
#endif
- if (call->params->realtimetext_enabled) {
+ if (call->params->realtimetext_enabled && call->textstream->ms.state==MSStreamInitialized) {
text_stream_prepare_text(call->textstream);
}
@@ -3747,10 +3758,10 @@ static void linphone_call_stop_text_stream(LinphoneCall *call) {
linphone_reporting_update_media_info(call, LINPHONE_CALL_STATS_TEXT);
media_stream_reclaim_sessions(&call->textstream->ms, &call->sessions[call->main_text_stream_index]);
linphone_call_log_fill_stats(call->log, (MediaStream*)call->textstream);
+ update_rtp_stats(call, call->main_text_stream_index);
text_stream_stop(call->textstream);
call->textstream = NULL;
- update_rtp_stats(call, call->main_text_stream_index);
- linphone_call_handle_stream_events(call, call->main_video_stream_index);
+ linphone_call_handle_stream_events(call, call->main_text_stream_index);
rtp_session_unregister_event_queue(call->sessions[call->main_text_stream_index].rtp_session, call->textstream_app_evq);
ortp_ev_queue_flush(call->textstream_app_evq);
ortp_ev_queue_destroy(call->textstream_app_evq);
diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c
index 92668030f..c99b4b78c 100644
--- a/coreapi/linphonecore.c
+++ b/coreapi/linphonecore.c
@@ -1681,6 +1681,7 @@ static void linphone_core_register_default_codecs(LinphoneCore *lc){
linphone_core_register_payload_type(lc,&payload_type_aal2_g726_32,NULL,FALSE);
linphone_core_register_payload_type(lc,&payload_type_aal2_g726_40,NULL,FALSE);
linphone_core_register_payload_type(lc,&payload_type_codec2,NULL,FALSE);
+ linphone_core_register_payload_type(lc,&payload_type_bv16,NULL,FALSE);
#ifdef VIDEO_ENABLED
@@ -4172,6 +4173,7 @@ int linphone_core_preempt_sound_resources(LinphoneCore *lc){
int linphone_core_resume_call(LinphoneCore *lc, LinphoneCall *call){
char temp[255]={0};
const char *subject="Call resuming";
+ char *tmp;
if(call->state!=LinphoneCallPaused ){
ms_warning("we cannot resume a call that has not been established and paused before");
@@ -4212,7 +4214,8 @@ int linphone_core_resume_call(LinphoneCore *lc, LinphoneCall *call){
linphone_call_set_state(call,LinphoneCallResuming,"Resuming");
if (call->params->in_conference==FALSE)
lc->current_call=call;
- snprintf(temp,sizeof(temp)-1,"Resuming the call with %s",linphone_call_get_remote_address_as_string(call));
+ snprintf(temp,sizeof(temp)-1,"Resuming the call with %s",(tmp = linphone_call_get_remote_address_as_string(call)));
+ ms_free(tmp);
linphone_core_notify_display_status(lc,temp);
if (lc->sip_conf.sdp_200_ack){
@@ -4458,6 +4461,7 @@ LinphonePresenceModel * linphone_core_get_presence_model(const LinphoneCore *lc)
* Get playback sound level in 0-100 scale.
*
* @ingroup media_parameters
+ * @deprecated
**/
int linphone_core_get_play_level(LinphoneCore *lc)
{
@@ -4468,6 +4472,7 @@ int linphone_core_get_play_level(LinphoneCore *lc)
* Get ring sound level in 0-100 scale
*
* @ingroup media_parameters
+ * @deprecated
**/
int linphone_core_get_ring_level(LinphoneCore *lc)
{
@@ -4478,6 +4483,7 @@ int linphone_core_get_ring_level(LinphoneCore *lc)
* Get sound capture level in 0-100 scale
*
* @ingroup media_parameters
+ * @deprecated
**/
int linphone_core_get_rec_level(LinphoneCore *lc){
return lc->sound_conf.rec_lev;
@@ -4487,6 +4493,7 @@ int linphone_core_get_rec_level(LinphoneCore *lc){
* Set sound ring level in 0-100 scale
*
* @ingroup media_parameters
+ * @deprecated
**/
void linphone_core_set_ring_level(LinphoneCore *lc, int level){
MSSndCard *sndcard;
@@ -4560,7 +4567,7 @@ float linphone_core_get_playback_gain_db(LinphoneCore *lc) {
/**
* Set sound playback level in 0-100 scale
- *
+ * @deprecated
* @ingroup media_parameters
**/
void linphone_core_set_play_level(LinphoneCore *lc, int level){
@@ -4572,7 +4579,7 @@ void linphone_core_set_play_level(LinphoneCore *lc, int level){
/**
* Set sound capture level in 0-100 scale
- *
+ * @deprecated
* @ingroup media_parameters
**/
void linphone_core_set_rec_level(LinphoneCore *lc, int level)
@@ -4889,6 +4896,13 @@ void linphone_core_verify_server_cn(LinphoneCore *lc, bool_t yesno){
lp_config_set_int(lc->config,"sip","verify_server_cn",yesno);
}
+void linphone_core_set_ssl_config(LinphoneCore *lc, void *ssl_config) {
+ sal_set_ssl_config(lc->sal, ssl_config);
+ if (lc->http_crypto_config) {
+ belle_tls_crypto_config_set_ssl_config(lc->http_crypto_config, ssl_config);
+ }
+}
+
static void notify_end_of_ringtone( LinphoneRingtonePlayer* rp, void* user_data, int status) {
LinphoneCore *lc=(LinphoneCore*)user_data;
lc->preview_finished=1;
diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h
index d30c5b4ab..1cc8e084d 100644
--- a/coreapi/linphonecore.h
+++ b/coreapi/linphonecore.h
@@ -3213,32 +3213,43 @@ LINPHONE_PUBLIC void linphone_core_reload_sound_devices(LinphoneCore *lc);
LINPHONE_PUBLIC bool_t linphone_core_sound_device_can_capture(LinphoneCore *lc, const char *device);
LINPHONE_PUBLIC bool_t linphone_core_sound_device_can_playback(LinphoneCore *lc, const char *device);
-LINPHONE_PUBLIC int linphone_core_get_ring_level(LinphoneCore *lc);
-LINPHONE_PUBLIC int linphone_core_get_play_level(LinphoneCore *lc);
-LINPHONE_PUBLIC int linphone_core_get_rec_level(LinphoneCore *lc);
-LINPHONE_PUBLIC void linphone_core_set_ring_level(LinphoneCore *lc, int level);
-LINPHONE_PUBLIC void linphone_core_set_play_level(LinphoneCore *lc, int level);
+LINPHONE_PUBLIC LINPHONE_DEPRECATED int linphone_core_get_ring_level(LinphoneCore *lc);
+LINPHONE_PUBLIC LINPHONE_DEPRECATED int linphone_core_get_play_level(LinphoneCore *lc);
+LINPHONE_PUBLIC LINPHONE_DEPRECATED int linphone_core_get_rec_level(LinphoneCore *lc);
+LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_core_set_ring_level(LinphoneCore *lc, int level);
+LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_core_set_play_level(LinphoneCore *lc, int level);
+LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_core_set_rec_level(LinphoneCore *lc, int level);
+LINPHONE_DEPRECATED char linphone_core_get_sound_source(LinphoneCore *lc);
+LINPHONE_DEPRECATED void linphone_core_set_sound_source(LinphoneCore *lc, char source);
LINPHONE_PUBLIC void linphone_core_set_mic_gain_db(LinphoneCore *lc, float level);
LINPHONE_PUBLIC float linphone_core_get_mic_gain_db(LinphoneCore *lc);
LINPHONE_PUBLIC void linphone_core_set_playback_gain_db(LinphoneCore *lc, float level);
LINPHONE_PUBLIC float linphone_core_get_playback_gain_db(LinphoneCore *lc);
-LINPHONE_PUBLIC void linphone_core_set_rec_level(LinphoneCore *lc, int level);
LINPHONE_PUBLIC const char * linphone_core_get_ringer_device(LinphoneCore *lc);
LINPHONE_PUBLIC const char * linphone_core_get_playback_device(LinphoneCore *lc);
LINPHONE_PUBLIC const char * linphone_core_get_capture_device(LinphoneCore *lc);
LINPHONE_PUBLIC int linphone_core_set_ringer_device(LinphoneCore *lc, const char * devid);
LINPHONE_PUBLIC int linphone_core_set_playback_device(LinphoneCore *lc, const char * devid);
LINPHONE_PUBLIC int linphone_core_set_capture_device(LinphoneCore *lc, const char * devid);
-char linphone_core_get_sound_source(LinphoneCore *lc);
-void linphone_core_set_sound_source(LinphoneCore *lc, char source);
+
LINPHONE_PUBLIC void linphone_core_stop_ringing(LinphoneCore *lc);
LINPHONE_PUBLIC void linphone_core_set_ring(LinphoneCore *lc, const char *path);
LINPHONE_PUBLIC const char *linphone_core_get_ring(const LinphoneCore *lc);
LINPHONE_PUBLIC void linphone_core_verify_server_certificates(LinphoneCore *lc, bool_t yesno);
LINPHONE_PUBLIC void linphone_core_verify_server_cn(LinphoneCore *lc, bool_t yesno);
LINPHONE_PUBLIC void linphone_core_set_root_ca(LinphoneCore *lc, const char *path);
+/**
+ * @internal
+ * Set the pointer to an externally provided ssl configuration for the crypto library
+ * @param lc #LinphoneCore object
+ * @param[in] ssl_config A pointer to an opaque structure which will be provided directly to the crypto library used in bctoolbox. Use with extra care.
+ * This ssl_config structure is responsability of the caller and will not be freed at the connection's end.
+ * @ingroup initializing
+ * @endinternal
+ */
+LINPHONE_PUBLIC void linphone_core_set_ssl_config(LinphoneCore *lc, void *ssl_config);
LINPHONE_PUBLIC const char *linphone_core_get_root_ca(LinphoneCore *lc);
LINPHONE_PUBLIC void linphone_core_set_ringback(LinphoneCore *lc, const char *path);
LINPHONE_PUBLIC const char * linphone_core_get_ringback(const LinphoneCore *lc);
diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc
index 434d5f75b..84ccf5342 100644
--- a/coreapi/linphonecore_jni.cc
+++ b/coreapi/linphonecore_jni.cc
@@ -81,7 +81,10 @@ void linphone_android_log_handler(int prio, char *str) {
} else {
current = str;
while ((next = strchr(current, '\n')) != NULL) {
+
*next = '\0';
+ if (next != str && next[-1] == '\r')
+ next[-1] = '\0';
__android_log_write(prio, LogDomain, current);
current = next + 1;
}
@@ -449,7 +452,7 @@ jobject getProxy(JNIEnv *env, LinphoneProxyConfig *proxy, jobject core){
linphone_proxy_config_set_user_data(proxy,(void*)env->NewWeakGlobalRef(jobj));
linphone_proxy_config_ref(proxy);
}else{
- //promote the weak ref to local ref
+ //promote the weak ref to local ref
jobj=env->NewLocalRef((jobject)up);
if (jobj == NULL){
//the weak ref was dead
@@ -493,11 +496,42 @@ jobject getChatMessage(JNIEnv *env, LinphoneChatMessage *msg){
void *up = linphone_chat_message_get_user_data(msg);
if (up == NULL) {
- jobj = env->NewObject(ljb->chatMessageClass, ljb->chatMessageCtrId, (jlong)linphone_chat_message_ref(msg));
- jobj = env->NewGlobalRef(jobj);
- linphone_chat_message_set_user_data(msg,(void*)jobj);
+ jobj = env->NewObject(ljb->chatMessageClass, ljb->chatMessageCtrId, (jlong)msg);
+ void *userdata = (void*)env->NewWeakGlobalRef(jobj);
+ linphone_chat_message_set_user_data(msg, userdata);
+ linphone_chat_message_ref(msg);
} else {
- jobj = (jobject)up;
+ jobj = env->NewLocalRef((jobject)up);
+ if (jobj == NULL) {
+ // takes implicit local ref
+ jobj = env->NewObject(ljb->chatMessageClass, ljb->chatMessageCtrId, (jlong)msg);
+ linphone_chat_message_set_user_data(msg, (void*)env->NewWeakGlobalRef(jobj));
+ }
+ }
+ }
+ return jobj;
+}
+
+jobject getChatRoom(JNIEnv *env, LinphoneChatRoom *room) {
+ jobject jobj = 0;
+
+ if (room != NULL){
+ LinphoneCore *lc = linphone_chat_room_get_core(room);
+ LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc);
+
+ void *up = linphone_chat_room_get_user_data(room);
+ if (up == NULL) {
+ // take implicit local ref
+ jobj = env->NewObject(ljb->chatRoomClass, ljb->chatRoomCtrId, (jlong)room);
+ linphone_chat_room_set_user_data(room, (void*)env->NewWeakGlobalRef(jobj));
+ linphone_chat_room_ref(room);
+ } else {
+ jobj = env->NewLocalRef((jobject)up);
+ if (jobj == NULL) {
+ // takes implicit local ref
+ jobj = env->NewObject(ljb->chatRoomClass, ljb->chatRoomCtrId, (jlong)room);
+ linphone_chat_room_set_user_data(room, (void*)env->NewWeakGlobalRef(jobj));
+ }
}
}
return jobj;
@@ -908,7 +942,6 @@ public:
}
static void message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *msg) {
JNIEnv *env = 0;
- jobject jmsg;
jint result = jvm->AttachCurrentThread(&env,NULL);
if (result != 0) {
ms_error("cannot attach VM");
@@ -922,8 +955,8 @@ public:
env->CallVoidMethod(lcData->listener
,ljb->messageReceivedId
,lcData->core
- ,env->NewObject(ljb->chatRoomClass,ljb->chatRoomCtrId,(jlong)room)
- ,(jmsg = getChatMessage(env, msg)));
+ ,getChatRoom(env, room)
+ ,getChatMessage(env, msg));
handle_possible_java_exception(env, lcData->listener);
}
static void is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room) {
@@ -940,7 +973,7 @@ public:
env->CallVoidMethod(lcData->listener
,ljb->isComposingReceivedId
,lcData->core
- ,env->NewObject(ljb->chatRoomClass,ljb->chatRoomCtrId,(jlong)room));
+ ,getChatRoom(env, room));
handle_possible_java_exception(env, lcData->listener);
}
static void ecCalibrationStatus(LinphoneCore *lc, LinphoneEcCalibratorStatus status, int delay_ms, void *data) {
@@ -1749,7 +1782,7 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_muteMic( JNIEnv* env
,jobject thiz
,jlong lc
,jboolean isMuted) {
- linphone_core_mute_mic((LinphoneCore*)lc,isMuted);
+ linphone_core_enable_mic((LinphoneCore*)lc,isMuted);
}
extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_interpretUrl( JNIEnv* env
@@ -2130,7 +2163,7 @@ JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneCoreImpl_getPresenceMod
RETURN_USER_DATA_OBJECT("PresenceModelImpl", linphone_presence_model, model)
}
-extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_getOrCreateChatRoom(JNIEnv* env
+extern "C" jobject Java_org_linphone_core_LinphoneCoreImpl_getOrCreateChatRoom(JNIEnv* env
,jobject thiz
,jlong lc
,jstring jto) {
@@ -2138,15 +2171,15 @@ extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_getOrCreateChatRoom(JNI
const char* to = env->GetStringUTFChars(jto, NULL);
LinphoneChatRoom* lResult = linphone_core_get_chat_room_from_uri((LinphoneCore*)lc,to);
env->ReleaseStringUTFChars(jto, to);
- return (jlong)lResult;
+ return getChatRoom(env, lResult);
}
-extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_getChatRoom(JNIEnv* env
+extern "C" jobject Java_org_linphone_core_LinphoneCoreImpl_getChatRoom(JNIEnv* env
,jobject thiz
,jlong lc
,jlong to) {
LinphoneChatRoom* lResult = linphone_core_get_chat_room((LinphoneCore*)lc,(LinphoneAddress *)to);
- return (jlong)lResult;
+ return getChatRoom(env, lResult);
}
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_enableVideo(JNIEnv* env
@@ -2288,7 +2321,8 @@ extern "C" jboolean Java_org_linphone_core_LinphoneCoreImpl_needsEchoCalibration
return TRUE;
}
- SoundDeviceDescription *sound_description = sound_device_description_get();
+ MSDevicesInfo *devices = ms_factory_get_devices_info(factory);
+ SoundDeviceDescription *sound_description = ms_devices_info_get_sound_device_description(devices);
if(sound_description != NULL && sound_description == &genericSoundDeviceDescriptor){
return TRUE;
}
@@ -2298,6 +2332,19 @@ extern "C" jboolean Java_org_linphone_core_LinphoneCoreImpl_needsEchoCalibration
return TRUE;
}
+extern "C" jboolean Java_org_linphone_core_LinphoneCoreImpl_hasCrappyOpenGL(JNIEnv *env, jobject thiz, jlong lcptr) {
+ LinphoneCore *lc = (LinphoneCore*) lcptr;
+ MSFactory * factory = linphone_core_get_ms_factory(lc);
+ MSDevicesInfo *devices = ms_factory_get_devices_info(factory);
+ SoundDeviceDescription *sound_description = ms_devices_info_get_sound_device_description(devices);
+ if (sound_description != NULL && sound_description == &genericSoundDeviceDescriptor){
+ return FALSE;
+ }
+
+ if (sound_description->flags & DEVICE_HAS_CRAPPY_OPENGL) return TRUE;
+ return FALSE;
+}
+
extern "C" jboolean Java_org_linphone_core_LinphoneCoreImpl_hasBuiltInEchoCanceler(JNIEnv *env, jobject thiz, jlong lcptr) {
MSSndCard *sndcard;
LinphoneCore *lc = (LinphoneCore*) lcptr;
@@ -3415,8 +3462,74 @@ extern "C" void Java_org_linphone_core_LinphoneFriendListImpl_updateSubscription
linphone_friend_list_update_subscriptions((LinphoneFriendList*)friendListptr, (LinphoneProxyConfig*)proxyConfigPtr, jonlyWhenRegistered);
}
+extern "C" jlongArray Java_org_linphone_core_LinphoneFriendImpl_getAddresses(JNIEnv* env
+ ,jobject thiz
+ ,jlong ptr) {
+ MSList *addresses = linphone_friend_get_addresses((LinphoneFriend*)ptr);
+ MSList *list = addresses;
+ int size = ms_list_size(addresses);
+ jlongArray jaddresses = env->NewLongArray(size);
+ jlong *jInternalArray = env->GetLongArrayElements(jaddresses, NULL);
+ for (int i = 0; i < size; i++) {
+ jInternalArray[i] = (unsigned long) (addresses->data);
+ addresses = ms_list_next(addresses);
+ }
+ ms_list_free(list);
+ env->ReleaseLongArrayElements(jaddresses, jInternalArray, 0);
+ return jaddresses;
+}
+extern "C" void Java_org_linphone_core_LinphoneFriendImpl_addAddress(JNIEnv* env
+ ,jobject thiz
+ ,jlong ptr
+ ,jlong jaddress) {
+ linphone_friend_add_address((LinphoneFriend*)ptr, (LinphoneAddress*)jaddress);
+}
+extern "C" void Java_org_linphone_core_LinphoneFriendImpl_removeAddress(JNIEnv* env
+ ,jobject thiz
+ ,jlong ptr
+ ,jlong jaddress) {
+ linphone_friend_remove_address((LinphoneFriend*)ptr, (LinphoneAddress*)jaddress);
+}
+
+extern "C" jobjectArray Java_org_linphone_core_LinphoneFriendImpl_getPhoneNumbers(JNIEnv* env
+ ,jobject thiz
+ ,jlong ptr) {
+ MSList *phone_numbers = linphone_friend_get_phone_numbers((LinphoneFriend*)ptr);
+ MSList *list = phone_numbers;
+ int size = ms_list_size(phone_numbers);
+ jobjectArray jphonenumbers = env->NewObjectArray(size, env->FindClass("java/lang/String"), env->NewStringUTF(""));
+ for (int i = 0; i < size; i++) {
+ const char *phone = (const char *)phone_numbers->data;
+ env->SetObjectArrayElement(jphonenumbers, i, env->NewStringUTF(phone));
+ phone_numbers = ms_list_next(phone_numbers);
+ }
+ ms_list_free(list);
+ return jphonenumbers;
+}
+
+extern "C" void Java_org_linphone_core_LinphoneFriendImpl_addPhoneNumber(JNIEnv* env
+ ,jobject thiz
+ ,jlong ptr
+ ,jstring jphone) {
+ if (jphone) {
+ const char* phone = env->GetStringUTFChars(jphone, NULL);
+ linphone_friend_add_phone_number((LinphoneFriend*)ptr, phone);
+ env->ReleaseStringUTFChars(jphone, phone);
+ }
+}
+
+extern "C" void Java_org_linphone_core_LinphoneFriendImpl_removePhoneNumber(JNIEnv* env
+ ,jobject thiz
+ ,jlong ptr
+ ,jstring jphone) {
+ if (jphone) {
+ const char* phone = env->GetStringUTFChars(jphone, NULL);
+ linphone_friend_remove_phone_number((LinphoneFriend*)ptr, phone);
+ env->ReleaseStringUTFChars(jphone, phone);
+ }
+}
extern "C" jlong Java_org_linphone_core_LinphoneFriendImpl_getAddress(JNIEnv* env
,jobject thiz
@@ -3431,6 +3544,31 @@ extern "C" jstring Java_org_linphone_core_LinphoneFriendImpl_getName(JNIEnv* en
return name ? env->NewStringUTF(name) : NULL;
}
+extern "C" jstring Java_org_linphone_core_LinphoneFriendImpl_getOrganization(JNIEnv* env,
+ jobject thiz,
+ jlong ptr) {
+ LinphoneFriend *lf = (LinphoneFriend *)ptr;
+ LinphoneVcard *lvc = linphone_friend_get_vcard(lf);
+ if (lvc) {
+ const char *org = linphone_vcard_get_organization(lvc);
+ return org ? env->NewStringUTF(org) : NULL;
+ }
+ return NULL;
+}
+
+extern "C" void Java_org_linphone_core_LinphoneFriendImpl_setOrganization(JNIEnv* env,
+ jobject thiz,
+ jlong ptr,
+ jstring jorg) {
+ LinphoneFriend *lf = (LinphoneFriend *)ptr;
+ LinphoneVcard *lvc = linphone_friend_get_vcard(lf);
+ if (lvc) {
+ const char* org = env->GetStringUTFChars(jorg, NULL);
+ linphone_vcard_set_organization(lvc, org);
+ env->ReleaseStringUTFChars(jorg, org);
+ }
+}
+
extern "C" void Java_org_linphone_core_LinphoneFriendImpl_setIncSubscribePolicy(JNIEnv* env
,jobject thiz
,jlong ptr
@@ -3556,26 +3694,28 @@ extern "C" jobject Java_org_linphone_core_LinphoneCoreImpl_getFriendByAddress(JN
}
}
-extern "C" jlongArray _LinphoneChatRoomImpl_getHistory(JNIEnv* env
- ,jobject thiz
- ,jlong ptr
- ,MSList* history) {
+extern "C" jobjectArray _LinphoneChatRoomImpl_getHistory(JNIEnv* env, jobject thiz, jlong ptr, MSList* history) {
+ LinphoneChatRoom *room = (LinphoneChatRoom *)ptr;
+ LinphoneCore *lc = linphone_chat_room_get_core(room);
+ LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc);
+ MSList *list = history;
int historySize = ms_list_size(history);
- jlongArray jHistory = env->NewLongArray(historySize);
- jlong *jInternalArray = env->GetLongArrayElements(jHistory, NULL);
-
+ jobjectArray jHistory = env->NewObjectArray(historySize, ljb->chatMessageClass, NULL);
+
for (int i = 0; i < historySize; i++) {
- jInternalArray[i] = (unsigned long) (history->data);
+ LinphoneChatMessage *msg = (LinphoneChatMessage *)history->data;
+ jobject jmsg = getChatMessage(env, msg);
+ if (jmsg != NULL) {
+ env->SetObjectArrayElement(jHistory, i, jmsg);
+ env->DeleteLocalRef(jmsg);
+ }
history = history->next;
}
- ms_list_free(history);
-
- env->ReleaseLongArrayElements(jHistory, jInternalArray, 0);
-
+ ms_list_free(list);
return jHistory;
}
-extern "C" jlongArray Java_org_linphone_core_LinphoneChatRoomImpl_getHistoryRange(JNIEnv* env
+extern "C" jobjectArray Java_org_linphone_core_LinphoneChatRoomImpl_getHistoryRange(JNIEnv* env
,jobject thiz
,jlong ptr
,jint start
@@ -3583,7 +3723,7 @@ extern "C" jlongArray Java_org_linphone_core_LinphoneChatRoomImpl_getHistoryRang
MSList* history = linphone_chat_room_get_history_range((LinphoneChatRoom*)ptr, start, end);
return _LinphoneChatRoomImpl_getHistory(env, thiz, ptr, history);
}
-extern "C" jlongArray Java_org_linphone_core_LinphoneChatRoomImpl_getHistory(JNIEnv* env
+extern "C" jobjectArray Java_org_linphone_core_LinphoneChatRoomImpl_getHistory(JNIEnv* env
,jobject thiz
,jlong ptr
,jint limit) {
@@ -3970,21 +4110,25 @@ extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_unref(JNIEnv* en
linphone_chat_message_unref((LinphoneChatMessage*)ptr);
}
-extern "C" jlongArray Java_org_linphone_core_LinphoneCoreImpl_getChatRooms(JNIEnv* env
+extern "C" jobjectArray Java_org_linphone_core_LinphoneCoreImpl_getChatRooms(JNIEnv* env
,jobject thiz
,jlong ptr) {
- const MSList* chats = linphone_core_get_chat_rooms((LinphoneCore*)ptr);
+ LinphoneCore *lc = (LinphoneCore*)ptr;
+ const MSList* chats = linphone_core_get_chat_rooms(lc);
+ LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc);
int chatsSize = ms_list_size(chats);
- jlongArray jChats = env->NewLongArray(chatsSize);
- jlong *jInternalArray = env->GetLongArrayElements(jChats, NULL);
+ jobjectArray jChats = env->NewObjectArray(chatsSize, ljb->chatRoomClass, NULL);
for (int i = 0; i < chatsSize; i++) {
- jInternalArray[i] = (unsigned long) (chats->data);
+ LinphoneChatRoom *room = (LinphoneChatRoom *)chats->data;
+ jobject jroom = getChatRoom(env, room);
+ if (jroom != NULL) {
+ env->SetObjectArrayElement(jChats, i, jroom);
+ env->DeleteLocalRef(jroom);
+ }
chats = chats->next;
}
- env->ReleaseLongArrayElements(jChats, jInternalArray, 0);
-
return jChats;
}
@@ -6824,8 +6968,8 @@ JNIEXPORT jstring JNICALL Java_org_linphone_core_LinphoneCoreImpl_getVideoPreset
return tmp ? env->NewStringUTF(tmp) : NULL;
}
-extern "C" jlong Java_org_linphone_core_LinphoneCallImpl_getChatRoom(JNIEnv* env ,jobject thiz, jlong ptr) {
- return (jlong) linphone_call_get_chat_room((LinphoneCall *) ptr);
+extern "C" jobject Java_org_linphone_core_LinphoneCallImpl_getChatRoom(JNIEnv* env ,jobject thiz, jlong ptr) {
+ return getChatRoom(env, linphone_call_get_chat_room((LinphoneCall *) ptr));
}
extern "C" void Java_org_linphone_core_LinphoneCallParamsImpl_enableRealTimeText(JNIEnv* env ,jobject thiz, jlong ptr, jboolean yesno) {
@@ -6840,6 +6984,12 @@ extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_putChar(JNIEnv* e
linphone_chat_message_put_char((LinphoneChatMessage *)ptr, character);
}
+extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_finalize(JNIEnv* env, jobject thiz, jlong ptr) {
+ LinphoneChatRoom *room = (LinphoneChatRoom *)ptr;
+ linphone_chat_room_set_user_data(room, NULL);
+ linphone_chat_room_unref(room);
+}
+
extern "C" jobject Java_org_linphone_core_LinphoneChatRoomImpl_getCall(JNIEnv* env ,jobject thiz, jlong ptr) {
return getCall(env, linphone_chat_room_get_call((LinphoneChatRoom *)ptr));
}
diff --git a/coreapi/linphonefriend.h b/coreapi/linphonefriend.h
index 5488a1358..693ee90f1 100644
--- a/coreapi/linphonefriend.h
+++ b/coreapi/linphonefriend.h
@@ -162,7 +162,49 @@ LINPHONE_PUBLIC int linphone_friend_set_address(LinphoneFriend *fr, const Linpho
* @param lf #LinphoneFriend object
* @return #LinphoneAddress
*/
-LINPHONE_PUBLIC const LinphoneAddress *linphone_friend_get_address(const LinphoneFriend *lf);
+LINPHONE_PUBLIC const LinphoneAddress *linphone_friend_get_address(const LinphoneFriend *lf);
+
+/**
+ * Adds an address in this friend
+ * @param lf #LinphoneFriend object
+ * @param addr #LinphoneAddress object
+ */
+LINPHONE_PUBLIC void linphone_friend_add_address(LinphoneFriend *lf, const LinphoneAddress *addr);
+
+/**
+ * Returns a list of #LinphoneAddress for this friend
+ * @param lf #LinphoneFriend object
+ * @return \mslist{LinphoneAddress}
+ */
+LINPHONE_PUBLIC MSList* linphone_friend_get_addresses(LinphoneFriend *lf);
+
+/**
+ * Removes an address in this friend
+ * @param lf #LinphoneFriend object
+ * @param addr #LinphoneAddress object
+ */
+LINPHONE_PUBLIC void linphone_friend_remove_address(LinphoneFriend *lf, const LinphoneAddress *addr);
+
+/**
+ * Adds a phone number in this friend
+ * @param lf #LinphoneFriend object
+ * @param phone number to add
+ */
+LINPHONE_PUBLIC void linphone_friend_add_phone_number(LinphoneFriend *lf, const char *phone);
+
+/**
+ * Returns a list of phone numbers for this friend
+ * @param lf #LinphoneFriend object
+ * @return \mslist{const char *}
+ */
+LINPHONE_PUBLIC MSList* linphone_friend_get_phone_numbers(LinphoneFriend *lf);
+
+/**
+ * Removes a phone number in this friend
+ * @param lf #LinphoneFriend object
+ * @param phone number to remove
+ */
+LINPHONE_PUBLIC void linphone_friend_remove_phone_number(LinphoneFriend *lf, const char *phone);
/**
* Set the display name for this friend
diff --git a/coreapi/lpconfig.c b/coreapi/lpconfig.c
index 83bd411b7..cd036947e 100644
--- a/coreapi/lpconfig.c
+++ b/coreapi/lpconfig.c
@@ -923,26 +923,53 @@ const char** lp_config_get_sections_names(LpConfig *lpconfig) {
const MSList *sections = lpconfig->sections;
int ndev;
int i;
-
+
ndev = ms_list_size(sections);
sections_names = ms_malloc((ndev + 1) * sizeof(const char *));
-
+
for (i = 0; sections != NULL; sections = sections->next, i++) {
LpSection *section = (LpSection *)sections->data;
sections_names[i] = ms_strdup(section->name);
}
-
+
sections_names[ndev] = NULL;
return sections_names;
}
char* lp_config_dump_as_xml(const LpConfig *lpconfig) {
char *buffer;
-
+
lpc2xml_context *ctx = lpc2xml_context_new(NULL, NULL);
lpc2xml_set_lpc(ctx, lpconfig);
lpc2xml_convert_string(ctx, &buffer);
lpc2xml_context_destroy(ctx);
-
+
return buffer;
-}
\ No newline at end of file
+}
+
+struct _entry_data {
+ const LpConfig *conf;
+ const char *section;
+ char** buffer;
+};
+
+static void dump_entry(const char *entry, void *data) {
+ struct _entry_data *d = (struct _entry_data *) data;
+ const char *value = lp_config_get_string(d->conf, d->section, entry, "");
+ *d->buffer = ms_strcat_printf(*d->buffer, "\t%s=%s\n", entry, value);
+}
+
+static void dump_section(const char *section, void *data) {
+ struct _entry_data *d = (struct _entry_data *) data;
+ d->section = section;
+ *d->buffer = ms_strcat_printf(*d->buffer, "[%s]\n", section);
+ lp_config_for_each_entry(d->conf, section, dump_entry, d);
+}
+
+char* lp_config_dump(const LpConfig *lpconfig) {
+ char* buffer = NULL;
+ struct _entry_data d = { lpconfig, NULL, &buffer };
+ lp_config_for_each_section(lpconfig, dump_section, &d);
+
+ return buffer;
+}
diff --git a/coreapi/lpconfig.h b/coreapi/lpconfig.h
index 49e2bb50d..c18af988a 100644
--- a/coreapi/lpconfig.h
+++ b/coreapi/lpconfig.h
@@ -306,11 +306,20 @@ LINPHONE_PUBLIC bool_t lp_config_relative_file_exists(const LpConfig *lpconfig,
* Dumps the LpConfig as XML into a buffer
* @param[in] lpconfig The LpConfig object
* @return The buffer that contains the XML dump
- *
+ *
* @ingroup misc
**/
LINPHONE_PUBLIC char* lp_config_dump_as_xml(const LpConfig *lpconfig);
+/**
+ * Dumps the LpConfig as INI into a buffer
+ * @param[in] lpconfig The LpConfig object
+ * @return The buffer that contains the config dump
+ *
+ * @ingroup misc
+**/
+LINPHONE_PUBLIC char* lp_config_dump(const LpConfig *lpconfig);
+
/**
* Retrieves the overwrite flag for a config item
*
diff --git a/coreapi/private.h b/coreapi/private.h
index 98fdb93cf..f79b646c0 100644
--- a/coreapi/private.h
+++ b/coreapi/private.h
@@ -631,6 +631,7 @@ struct _LinphoneProxyConfig
LinphoneEvent *long_term_event;
unsigned long long previous_publish_config_hash[2];
+ char *refkey;
};
BELLE_SIP_DECLARE_VPTR(LinphoneProxyConfig);
diff --git a/coreapi/proxy.c b/coreapi/proxy.c
index 6743f93c1..343289fa9 100644
--- a/coreapi/proxy.c
+++ b/coreapi/proxy.c
@@ -105,7 +105,7 @@ static void linphone_proxy_config_init(LinphoneCore* lc, LinphoneProxyConfig *cf
const char *quality_reporting_collector = lc ? lp_config_get_default_string(lc->config, "proxy", "quality_reporting_collector", NULL) : NULL;
const char *contact_params = lc ? lp_config_get_default_string(lc->config, "proxy", "contact_parameters", NULL) : NULL;
const char *contact_uri_params = lc ? lp_config_get_default_string(lc->config, "proxy", "contact_uri_parameters", NULL) : NULL;
-
+ const char *refkey = lc ? lp_config_get_default_string(lc->config, "proxy", "refkey", NULL) : NULL;
cfg->expires = lc ? lp_config_get_default_int(lc->config, "proxy", "reg_expires", 3600) : 3600;
cfg->reg_sendregister = lc ? lp_config_get_default_int(lc->config, "proxy", "reg_sendregister", 1) : 1;
cfg->dial_prefix = dial_prefix ? ms_strdup(dial_prefix) : NULL;
@@ -124,6 +124,7 @@ static void linphone_proxy_config_init(LinphoneCore* lc, LinphoneProxyConfig *cf
cfg->avpf_mode = lc ? lp_config_get_default_int(lc->config, "proxy", "avpf", LinphoneAVPFDefault) : LinphoneAVPFDefault;
cfg->avpf_rr_interval = lc ? lp_config_get_default_int(lc->config, "proxy", "avpf_rr_interval", 5) : 5;
cfg->publish_expires=-1;
+ cfg->refkey = refkey ? ms_strdup(refkey) : NULL;
}
LinphoneProxyConfig *linphone_proxy_config_new() {
@@ -218,6 +219,7 @@ void _linphone_proxy_config_destroy(LinphoneProxyConfig *cfg){
if (cfg->saved_identity!=NULL) linphone_address_destroy(cfg->saved_identity);
if (cfg->sent_headers!=NULL) sal_custom_header_free(cfg->sent_headers);
if (cfg->pending_contact) linphone_address_unref(cfg->pending_contact);
+ if (cfg->refkey) ms_free(cfg->refkey);
_linphone_proxy_config_release_ops(cfg);
}
@@ -856,6 +858,7 @@ static bool_t lookup_dial_plan_by_ccc(const char *ccc, dial_plan_t *plan){
bool_t linphone_proxy_config_is_phone_number(LinphoneProxyConfig *proxy, const char *username){
const char *p;
+ if (!username) return FALSE;
for(p=username;*p!='\0';++p){
if (isdigit(*p) ||
*p==' ' ||
@@ -939,6 +942,9 @@ char* linphone_proxy_config_normalize_phone_number(LinphoneProxyConfig *proxy, c
, flatten_start);
ms_debug("Prepended prefix resulted in %s", result);
}
+ }else if (tmpproxy->dial_escape_plus){
+ /* user did not provide dial prefix, so we'll take the most generic one */
+ result = replace_plus_with_icp(flatten,most_common_dialplan.icp);
}
if (result==NULL) {
result = flatten;
@@ -1331,6 +1337,7 @@ void linphone_proxy_config_write_to_config_file(LpConfig *config, LinphoneProxyC
lp_config_set_int(config,key,"dial_escape_plus",cfg->dial_escape_plus);
lp_config_set_string(config,key,"dial_prefix",cfg->dial_prefix);
lp_config_set_int(config,key,"privacy",cfg->privacy);
+ if (cfg->refkey) lp_config_set_string(config,key,"refkey",cfg->refkey);
}
@@ -1387,6 +1394,9 @@ LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(LinphoneCore* lc
if (tmp!=NULL && strlen(tmp)>0)
linphone_proxy_config_set_sip_setup(cfg,tmp);
CONFIGURE_INT_VALUE(cfg,config,key,privacy,"privacy")
+
+ CONFIGURE_STRING_VALUE(cfg,config,key,ref_key,"refkey")
+
return cfg;
}
@@ -1637,3 +1647,15 @@ const struct _LinphoneAuthInfo* linphone_proxy_config_find_auth_info(const Linph
const char* domain = cfg->identity_address ? linphone_address_get_domain(cfg->identity_address) : NULL;
return _linphone_core_find_auth_info(cfg->lc, cfg->realm, username, domain, TRUE);
}
+
+const char * linphone_proxy_config_get_ref_key(const LinphoneProxyConfig *cfg) {
+ return cfg->refkey;
+}
+
+void linphone_proxy_config_set_ref_key(LinphoneProxyConfig *cfg, const char *refkey) {
+ if (cfg->refkey!=NULL){
+ ms_free(cfg->refkey);
+ cfg->refkey=NULL;
+ }
+ if (refkey) cfg->refkey=ms_strdup(refkey);
+}
diff --git a/coreapi/vcard.cc b/coreapi/vcard.cc
index fe6bc8a2b..2623c241f 100644
--- a/coreapi/vcard.cc
+++ b/coreapi/vcard.cc
@@ -163,6 +163,59 @@ MSList* linphone_vcard_get_sip_addresses(const LinphoneVcard *vCard) {
return result;
}
+void linphone_vcard_add_phone_number(LinphoneVcard *vCard, const char *phone) {
+ if (!vCard || !phone) return;
+
+ shared_ptr phone_number = belcard::BelCardGeneric::create();
+ phone_number->setValue(phone);
+ vCard->belCard->addPhoneNumber(phone_number);
+}
+
+void linphone_vcard_remove_phone_number(LinphoneVcard *vCard, const char *phone) {
+ if (!vCard) return;
+
+ for (auto it = vCard->belCard->getPhoneNumbers().begin(); it != vCard->belCard->getPhoneNumbers().end(); ++it) {
+ const char *value = (*it)->getValue().c_str();
+ if (strcmp(value, phone) == 0) {
+ vCard->belCard->removePhoneNumber(*it);
+ break;
+ }
+ }
+}
+
+MSList* linphone_vcard_get_phone_numbers(const LinphoneVcard *vCard) {
+ MSList *result = NULL;
+ if (!vCard) return NULL;
+
+ for (auto it = vCard->belCard->getPhoneNumbers().begin(); it != vCard->belCard->getPhoneNumbers().end(); ++it) {
+ const char *value = (*it)->getValue().c_str();
+ result = ms_list_append(result, (char *)value);
+ }
+ return result;
+}
+
+void linphone_vcard_set_organization(LinphoneVcard *vCard, const char *organization) {
+ if (!vCard) return;
+
+ if (vCard->belCard->getOrganizations().size() > 0) {
+ const shared_ptr org = vCard->belCard->getOrganizations().front();
+ org->setValue(organization);
+ } else {
+ shared_ptr org = belcard::BelCardGeneric::create();
+ org->setValue(organization);
+ vCard->belCard->addOrganization(org);
+ }
+}
+
+const char* linphone_vcard_get_organization(const LinphoneVcard *vCard) {
+ if (vCard && vCard->belCard->getOrganizations().size() > 0) {
+ const shared_ptr org = vCard->belCard->getOrganizations().front();
+ return org->getValue().c_str();
+ }
+
+ return NULL;
+}
+
bool_t linphone_vcard_generate_unique_id(LinphoneVcard *vCard) {
char uuid[64];
diff --git a/coreapi/vcard.h b/coreapi/vcard.h
index 15a3a891d..7948fbd11 100644
--- a/coreapi/vcard.h
+++ b/coreapi/vcard.h
@@ -122,6 +122,48 @@ void linphone_vcard_edit_main_sip_address(LinphoneVcard *vCard, const char *sip_
*/
LINPHONE_PUBLIC MSList* linphone_vcard_get_sip_addresses(const LinphoneVcard *vCard);
+/**
+ * Adds a phone number in the vCard, using the TEL property
+ * @param[in] vCard the LinphoneVcard
+ * @param[in] sip_address the phone number to add
+ */
+void linphone_vcard_add_phone_number(LinphoneVcard *vCard, const char *phone);
+
+/**
+ * Removes a phone number in the vCard (if it exists), using the TEL property
+ * @param[in] vCard the LinphoneVcard
+ * @param[in] sip_address the phone number to remove
+ */
+void linphone_vcard_remove_phone_number(LinphoneVcard *vCard, const char *phone);
+
+/**
+ * Returns the list of phone numbers (as string) in the vCard (all the TEL attributes) or NULL
+ * @param[in] vCard the LinphoneVcard
+ * @return \mslist{const char *}
+ */
+LINPHONE_PUBLIC MSList* linphone_vcard_get_phone_numbers(const LinphoneVcard *vCard);
+
+/**
+ * Returns the list of SIP addresses (as string) in the vCard (all the IMPP attributes that has an URI value starting by "sip:") or NULL
+ * @param[in] vCard the LinphoneVcard
+ * @return \mslist{const char *}
+ */
+LINPHONE_PUBLIC MSList* linphone_vcard_get_sip_addresses(const LinphoneVcard *vCard);
+
+/**
+ * Fills the Organization field of the vCard
+ * @param[in] vCard the LinphoneVcard
+ * @param[in] url the Organization
+ */
+LINPHONE_PUBLIC void linphone_vcard_set_organization(LinphoneVcard *vCard, const char *organization);
+
+/**
+ * Gets the Organization of the vCard
+ * @param[in] vCard the LinphoneVcard
+ * @return the Organization of the vCard or NULL
+ */
+LINPHONE_PUBLIC const char* linphone_vcard_get_organization(const LinphoneVcard *vCard);
+
/**
* Generates a random unique id for the vCard.
* If is required to be able to synchronize the vCard with a CardDAV server
@@ -163,7 +205,7 @@ LINPHONE_PUBLIC const char* linphone_vcard_get_etag(const LinphoneVcard *vCard);
* @param[in] vCard the LinphoneVcard
* @param[in] url the URL
*/
-LINPHONE_PUBLIC void linphone_vcard_set_url(LinphoneVcard *vCard, const char * url);
+LINPHONE_PUBLIC void linphone_vcard_set_url(LinphoneVcard *vCard, const char *url);
/**
* Gets the URL of the vCard
diff --git a/coreapi/vcard_stubs.c b/coreapi/vcard_stubs.c
index 7c473f129..0a0fa20ae 100644
--- a/coreapi/vcard_stubs.c
+++ b/coreapi/vcard_stubs.c
@@ -71,6 +71,26 @@ MSList* linphone_vcard_get_sip_addresses(const LinphoneVcard *vCard) {
return NULL;
}
+void linphone_vcard_add_phone_number(LinphoneVcard *vCard, const char *phone) {
+
+}
+
+void linphone_vcard_remove_phone_number(LinphoneVcard *vCard, const char *phone) {
+
+}
+
+MSList* linphone_vcard_get_phone_numbers(const LinphoneVcard *vCard) {
+ return NULL;
+}
+
+void linphone_vcard_set_organization(LinphoneVcard *vCard, const char *organization) {
+
+}
+
+const char* linphone_vcard_get_organization(const LinphoneVcard *vCard) {
+ return NULL;
+}
+
bool_t linphone_vcard_generate_unique_id(LinphoneVcard *vCard) {
return FALSE;
}
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
new file mode 100644
index 000000000..3837ee119
--- /dev/null
+++ b/daemon/Makefile.am
@@ -0,0 +1,106 @@
+
+
+bin_PROGRAMS=linphone-daemon linphone-daemon-pipetest
+
+linphone_daemon_SOURCES=daemon.cc \
+ commands/adaptive-jitter-compensation.cc \
+ commands/answer.cc \
+ commands/audio-codec-get.cc \
+ commands/audio-codec-move.cc \
+ commands/audio-codec-set.cc \
+ commands/audio-codec-toggle.cc \
+ commands/audio-stream-start.cc \
+ commands/audio-stream-stop.cc \
+ commands/audio-stream-stats.cc \
+ commands/auth-infos-clear.cc \
+ commands/call.cc \
+ commands/call-stats.cc \
+ commands/call-status.cc \
+ commands/call-pause.cc \
+ commands/call-resume.cc \
+ commands/call-mute.cc \
+ commands/video.cc \
+ commands/call-transfer.cc \
+ commands/conference.cc \
+ commands/dtmf.cc \
+ commands/firewall-policy.cc \
+ commands/help.cc \
+ commands/ipv6.cc \
+ commands/jitterbuffer.cc \
+ commands/media-encryption.cc \
+ commands/msfilter-add-fmtp.cc \
+ commands/play-wav.cc \
+ commands/pop-event.cc \
+ commands/port.cc \
+ commands/ptime.cc \
+ commands/register.cc \
+ commands/register-status.cc \
+ commands/terminate.cc \
+ commands/unregister.cc \
+ commands/quit.cc \
+ commands/version.cc \
+ commands/contact.cc \
+ commands/config.cc commands/configcommand.h \
+ daemon.h \
+ commands/adaptive-jitter-compensation.h \
+ commands/answer.h \
+ commands/audio-codec-get.h \
+ commands/audio-codec-move.h \
+ commands/audio-codec-set.h \
+ commands/audio-codec-toggle.h \
+ commands/audio-stream-start.h \
+ commands/audio-stream-stop.h \
+ commands/audio-stream-stats.h \
+ commands/auth-infos-clear.h \
+ commands/call.h \
+ commands/call-stats.h \
+ commands/call-status.h \
+ commands/call-pause.h \
+ commands/call-resume.h \
+ commands/call-mute.h \
+ commands/video.h \
+ commands/call-transfer.h \
+ commands/conference.h \
+ commands/dtmf.h \
+ commands/firewall-policy.h \
+ commands/help.h \
+ commands/ipv6.h \
+ commands/jitterbuffer.h \
+ commands/media-encryption.h \
+ commands/msfilter-add-fmtp.h \
+ commands/play-wav.h \
+ commands/pop-event.h \
+ commands/port.h \
+ commands/ptime.h \
+ commands/register.h \
+ commands/register-status.h \
+ commands/terminate.h \
+ commands/unregister.h \
+ commands/quit.h \
+ commands/contact.h \
+ commands/netsim.cc commands/netsim.h\
+ commands/cn.cc commands/cn.h \
+ commands/version.h
+
+linphone_daemon_pipetest_SOURCES=daemon-pipetest.c
+
+linphone_daemon_pipetest_LDADD=$(ORTP_LIBS)
+
+linphone_daemon_LDADD=$(top_builddir)/coreapi/liblinphone.la $(READLINE_LIBS) \
+ $(MEDIASTREAMER_LIBS) \
+ $(ORTP_LIBS) \
+ $(SPEEX_LIBS) \
+ $(LIBXML2_LIBS)
+
+AM_CFLAGS=$(READLINE_CFLAGS) -DIN_LINPHONE $(STRICT_OPTIONS)
+AM_CXXFLAGS=$(READLINE_CXXFLAGS) -DIN_LINPHONE $(STRICT_OPTIONS)
+
+INCLUDES = \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/coreapi \
+ -I$(top_srcdir)/include \
+ $(ORTP_CFLAGS) \
+ $(MEDIASTREAMER_CFLAGS) \
+ $(BELLESIP_CFLAGS)\
+ $(LIBXML2_CFLAGS)
+
diff --git a/daemon/commands/adaptive-jitter-compensation.cc b/daemon/commands/adaptive-jitter-compensation.cc
new file mode 100644
index 000000000..949aa792d
--- /dev/null
+++ b/daemon/commands/adaptive-jitter-compensation.cc
@@ -0,0 +1,114 @@
+#include "adaptive-jitter-compensation.h"
+
+using namespace std;
+
+class AdaptiveBufferCompensationResponse : public Response {
+public:
+ enum StreamType {
+ AudioStream,
+ VideoStream,
+ AllStreams
+ };
+
+ AdaptiveBufferCompensationResponse(LinphoneCore *core, StreamType type);
+
+private:
+ void outputAdaptiveBufferCompensation(LinphoneCore *core, ostringstream &ost, const char *header, bool_t value);
+};
+
+AdaptiveBufferCompensationResponse::AdaptiveBufferCompensationResponse(LinphoneCore *core, StreamType type) : Response() {
+ bool enabled = false;
+ ostringstream ost;
+ switch (type) {
+ case AudioStream:
+ enabled = linphone_core_audio_adaptive_jittcomp_enabled(core);
+ outputAdaptiveBufferCompensation(core, ost, "Audio", enabled);
+ break;
+ case VideoStream:
+ enabled = linphone_core_video_adaptive_jittcomp_enabled(core);
+ outputAdaptiveBufferCompensation(core, ost, "Video", enabled);
+ break;
+ case AllStreams:
+ enabled = linphone_core_audio_adaptive_jittcomp_enabled(core);
+ outputAdaptiveBufferCompensation(core, ost, "Audio", enabled);
+ enabled = linphone_core_video_adaptive_jittcomp_enabled(core);
+ outputAdaptiveBufferCompensation(core, ost, "Video", enabled);
+ break;
+ }
+ setBody(ost.str().c_str());
+}
+
+void AdaptiveBufferCompensationResponse::outputAdaptiveBufferCompensation(LinphoneCore *core, ostringstream &ost, const char *header, bool_t value) {
+ ost << header << ": ";
+ if (value) {
+ ost << "enabled\n";
+ } else {
+ ost << "disabled\n";
+ }
+}
+
+AdaptiveBufferCompensationCommand::AdaptiveBufferCompensationCommand() :
+ DaemonCommand("adaptive-jitter-compensation", "adaptive-jitter-compensation [] [enable|disable]",
+ "Enable or disable adaptive buffer compensation respectively with the 'enable' and 'disable' parameters for the specified stream, "
+ "return the status of the use of adaptive buffer compensation without parameter.\n"
+ " must be one of these values: audio, video.") {
+ addExample(new DaemonCommandExample("adaptive-jitter-compensation audio",
+ "Status: Ok\n\n"
+ "Audio: enabled"));
+ addExample(new DaemonCommandExample("adaptive-jitter-compensation video",
+ "Status: Ok\n\n"
+ "Video: disabled"));
+ addExample(new DaemonCommandExample("adaptive-jitter-compensation",
+ "Status: Ok\n\n"
+ "Audio: enabled\n"
+ "Video: disabled"));
+ addExample(new DaemonCommandExample("adaptive-jitter-compensation video enable",
+ "Status: Ok\n\n"
+ "Video: enabled"));
+}
+
+void AdaptiveBufferCompensationCommand::exec(Daemon *app, const char *args) {
+ string stream;
+ string state;
+ istringstream ist(args);
+ ist >> stream;
+ if (ist.fail()) {
+ app->sendResponse(AdaptiveBufferCompensationResponse(app->getCore(), AdaptiveBufferCompensationResponse::AllStreams));
+ } else {
+ ist >> state;
+ if (ist.fail()) {
+ if (stream.compare("audio") == 0) {
+ app->sendResponse(AdaptiveBufferCompensationResponse(app->getCore(), AdaptiveBufferCompensationResponse::AudioStream));
+ } else if (stream.compare("video") == 0) {
+ app->sendResponse(AdaptiveBufferCompensationResponse(app->getCore(), AdaptiveBufferCompensationResponse::VideoStream));
+ } else {
+ app->sendResponse(Response("Incorrect stream parameter.", Response::Error));
+ }
+ } else {
+ AdaptiveBufferCompensationResponse::StreamType type;
+ bool enabled;
+ if (stream.compare("audio") == 0) {
+ type = AdaptiveBufferCompensationResponse::AudioStream;
+ } else if (stream.compare("video") == 0) {
+ type = AdaptiveBufferCompensationResponse::VideoStream;
+ } else {
+ app->sendResponse(Response("Incorrect stream parameter.", Response::Error));
+ return;
+ }
+ if (state.compare("enable") == 0) {
+ enabled = TRUE;
+ } else if (state.compare("disable") == 0) {
+ enabled = FALSE;
+ } else {
+ app->sendResponse(Response("Incorrect parameter.", Response::Error));
+ return;
+ }
+ if (type == AdaptiveBufferCompensationResponse::AudioStream) {
+ linphone_core_enable_audio_adaptive_jittcomp(app->getCore(), enabled);
+ } else if (type == AdaptiveBufferCompensationResponse::VideoStream) {
+ linphone_core_enable_video_adaptive_jittcomp(app->getCore(), enabled);
+ }
+ app->sendResponse(AdaptiveBufferCompensationResponse(app->getCore(), AdaptiveBufferCompensationResponse::AllStreams));
+ }
+ }
+}
diff --git a/daemon/commands/adaptive-jitter-compensation.h b/daemon/commands/adaptive-jitter-compensation.h
new file mode 100644
index 000000000..dc319b7c5
--- /dev/null
+++ b/daemon/commands/adaptive-jitter-compensation.h
@@ -0,0 +1,12 @@
+#ifndef COMMAND_ADAPTIVE_BUFFER_COMPENSATION_H_
+#define COMMAND_ADAPTIVE_BUFFER_COMPENSATION_H_
+
+#include "../daemon.h"
+
+class AdaptiveBufferCompensationCommand: public DaemonCommand {
+public:
+ AdaptiveBufferCompensationCommand();
+ virtual void exec(Daemon *app, const char *args);
+};
+
+#endif //COMMAND_ADAPTIVE_BUFFER_COMPENSATION_H_
diff --git a/daemon/commands/answer.cc b/daemon/commands/answer.cc
new file mode 100644
index 000000000..943aa26fc
--- /dev/null
+++ b/daemon/commands/answer.cc
@@ -0,0 +1,55 @@
+#include "answer.h"
+
+using namespace std;
+
+AnswerCommand::AnswerCommand() :
+ DaemonCommand("answer", "answer ", "Answer an incoming call.") {
+ addExample(new DaemonCommandExample("answer 3",
+ "Status: Error\n"
+ "Reason: No call with such id."));
+ addExample(new DaemonCommandExample("answer 2",
+ "Status: Error\n"
+ "Reason: Can't accept this call."));
+ addExample(new DaemonCommandExample("answer 1",
+ "Status: Ok"));
+ addExample(new DaemonCommandExample("answer",
+ "Status: Ok"));
+ addExample(new DaemonCommandExample("answer",
+ "Status: Error\n"
+ "Reason: No call to accept."));
+}
+
+void AnswerCommand::exec(Daemon *app, const char *args) {
+ LinphoneCore *lc = app->getCore();
+ int cid;
+ LinphoneCall *call;
+ if (sscanf(args, "%i", &cid) == 1) {
+ call = app->findCall(cid);
+ if (call == NULL) {
+ app->sendResponse(Response("No call with such id."));
+ return;
+ } else {
+ LinphoneCallState cstate = linphone_call_get_state(call);
+ if (cstate == LinphoneCallIncomingReceived || cstate == LinphoneCallIncomingEarlyMedia) {
+ if (linphone_core_accept_call(lc, call) == 0) {
+ app->sendResponse(Response());
+ return;
+ }
+ }
+ app->sendResponse(Response("Can't accept this call."));
+ return;
+ }
+ } else {
+ for (const MSList* elem = linphone_core_get_calls(lc); elem != NULL; elem = elem->next) {
+ call = (LinphoneCall*) elem->data;
+ LinphoneCallState cstate = linphone_call_get_state(call);
+ if (cstate == LinphoneCallIncomingReceived || cstate == LinphoneCallIncomingEarlyMedia) {
+ if (linphone_core_accept_call(lc, call) == 0) {
+ app->sendResponse(Response());
+ return;
+ }
+ }
+ }
+ }
+ app->sendResponse(Response("No call to accept."));
+}
diff --git a/daemon/commands/answer.h b/daemon/commands/answer.h
new file mode 100644
index 000000000..38e7e5e7a
--- /dev/null
+++ b/daemon/commands/answer.h
@@ -0,0 +1,12 @@
+#ifndef COMMAND_ANSWER_H_
+#define COMMAND_ANSWER_H_
+
+#include "../daemon.h"
+
+class AnswerCommand: public DaemonCommand {
+public:
+ AnswerCommand();
+ virtual void exec(Daemon *app, const char *args);
+};
+
+#endif //COMMAND_ANSWER_H_
diff --git a/daemon/commands/audio-codec-get.cc b/daemon/commands/audio-codec-get.cc
new file mode 100644
index 000000000..48bd25f05
--- /dev/null
+++ b/daemon/commands/audio-codec-get.cc
@@ -0,0 +1,74 @@
+#include "audio-codec-get.h"
+
+using namespace std;
+
+AudioCodecGetCommand::AudioCodecGetCommand() :
+ DaemonCommand("audio-codec-get", "audio-codec-get ",
+ "Get an audio codec if a parameter is given, otherwise return the audio codec list.\n"
+ " is of the form mime/rate/channels, eg. speex/16000/1") {
+ addExample(new DaemonCommandExample("audio-codec-get 9",
+ "Status: Ok\n\n"
+ "Index: 9\n"
+ "Payload-type-number: 9\n"
+ "Clock-rate: 8000\n"
+ "Bitrate: 64000\n"
+ "Mime: G722\n"
+ "Channels: 1\n"
+ "Recv-fmtp: \n"
+ "Send-fmtp: \n"
+ "Enabled: false"));
+ addExample(new DaemonCommandExample("audio-codec-get G722/8000/1",
+ "Status: Ok\n\n"
+ "Index: 9\n"
+ "Payload-type-number: 9\n"
+ "Clock-rate: 8000\n"
+ "Bitrate: 64000\n"
+ "Mime: G722\n"
+ "Channels: 1\n"
+ "Recv-fmtp: \n"
+ "Send-fmtp: \n"
+ "Enabled: false"));
+ addExample(new DaemonCommandExample("audio-codec-get 2",
+ "Status: Error\n"
+ "Reason: Audio codec not found."));
+}
+
+void AudioCodecGetCommand::exec(Daemon *app, const char *args) {
+ bool list = false;
+ bool found = false;
+ istringstream ist(args);
+ ostringstream ost;
+ PayloadType *pt=NULL;
+
+ if (ist.peek() == EOF) {
+ found = list = true;
+ } else {
+ string mime_type;
+ ist >> mime_type;
+ PayloadTypeParser parser(app->getCore(), mime_type);
+ if (!parser.successful()) {
+ app->sendResponse(Response("Incorrect mime type format.", Response::Error));
+ return;
+ }
+ pt = parser.getPayloadType();
+ }
+
+ int index = 0;
+ for (const MSList *node = linphone_core_get_audio_codecs(app->getCore()); node != NULL; node = ms_list_next(node)) {
+ PayloadType *payload = reinterpret_cast(node->data);
+ if (list) {
+ ost << PayloadTypeResponse(app->getCore(), payload, index).getBody() << "\n";
+ } else if (pt == payload) {
+ ost << PayloadTypeResponse(app->getCore(), payload, index).getBody();
+ found = true;
+ break;
+ }
+ ++index;
+ }
+
+ if (!found) {
+ app->sendResponse(Response("Audio codec not found.", Response::Error));
+ } else {
+ app->sendResponse(Response(ost.str().c_str(), Response::Ok));
+ }
+}
diff --git a/daemon/commands/audio-codec-get.h b/daemon/commands/audio-codec-get.h
new file mode 100644
index 000000000..14ff63d66
--- /dev/null
+++ b/daemon/commands/audio-codec-get.h
@@ -0,0 +1,12 @@
+#ifndef COMMAND_AUDIO_CODEC_GET_H_
+#define COMMAND_AUDIO_CODEC_GET_H_
+
+#include "../daemon.h"
+
+class AudioCodecGetCommand: public DaemonCommand {
+public:
+ AudioCodecGetCommand();
+ virtual void exec(Daemon *app, const char *args);
+};
+
+#endif //COMMAND_AUDIO_CODEC_GET_H_
diff --git a/daemon/commands/audio-codec-move.cc b/daemon/commands/audio-codec-move.cc
new file mode 100644
index 000000000..3d65f9113
--- /dev/null
+++ b/daemon/commands/audio-codec-move.cc
@@ -0,0 +1,87 @@
+#include "audio-codec-move.h"
+
+using namespace std;
+
+AudioCodecMoveCommand::AudioCodecMoveCommand() :
+ DaemonCommand("audio-codec-move", "audio-codec-move ",
+ "Move a codec to the specified index.\n"
+ " is of the form mime/rate/channels, eg. speex/16000/1") {
+ addExample(new DaemonCommandExample("audio-codec-move 9 1",
+ "Status: Ok\n\n"
+ "Index: 1\n"
+ "Payload-type-number: 9\n"
+ "Clock-rate: 8000\n"
+ "Bitrate: 64000\n"
+ "Mime: G722\n"
+ "Channels: 1\n"
+ "Recv-fmtp: \n"
+ "Send-fmtp: \n"
+ "Enabled: false"));
+ addExample(new DaemonCommandExample("audio-codec-move G722/8000/1 9",
+ "Status: Ok\n\n"
+ "Index: 9\n"
+ "Payload-type-number: 9\n"
+ "Clock-rate: 8000\n"
+ "Bitrate: 64000\n"
+ "Mime: G722\n"
+ "Channels: 1\n"
+ "Recv-fmtp: \n"
+ "Send-fmtp: \n"
+ "Enabled: false"));
+}
+
+void AudioCodecMoveCommand::exec(Daemon *app, const char *args) {
+ istringstream ist(args);
+
+ if (ist.peek() == EOF) {
+ app->sendResponse(Response("Missing parameters.", Response::Error));
+ return;
+ }
+
+ string mime_type;
+ ist >> mime_type;
+ if (ist.peek() == EOF) {
+ app->sendResponse(Response("Missing index parameter.", Response::Error));
+ return;
+ }
+ PayloadTypeParser parser(app->getCore(), mime_type);
+ if (!parser.successful()) {
+ app->sendResponse(Response("Incorrect mime type format.", Response::Error));
+ return;
+ }
+ PayloadType *selected_payload = NULL;
+ selected_payload = parser.getPayloadType();
+
+ if (selected_payload == NULL) {
+ app->sendResponse(Response("Audio codec not found.", Response::Error));
+ return;
+ }
+
+ int index;
+ ist >> index;
+ if (ist.fail() || (index < 0)) {
+ app->sendResponse(Response("Incorrect index parameter.", Response::Error));
+ return;
+ }
+
+ int i = 0;
+ MSList *mslist = NULL;
+ for (const MSList *node = linphone_core_get_audio_codecs(app->getCore()); node != NULL; node = ms_list_next(node)) {
+ PayloadType *payload = reinterpret_cast(node->data);
+ if (i == index) {
+ mslist = ms_list_append(mslist, selected_payload);
+ ++i;
+ }
+ if (selected_payload != payload) {
+ mslist = ms_list_append(mslist, payload);
+ ++i;
+ }
+ }
+ if (i <= index) {
+ index = i;
+ mslist = ms_list_append(mslist, selected_payload);
+ }
+ linphone_core_set_audio_codecs(app->getCore(), mslist);
+
+ app->sendResponse(PayloadTypeResponse(app->getCore(), selected_payload, index));
+}
diff --git a/daemon/commands/audio-codec-move.h b/daemon/commands/audio-codec-move.h
new file mode 100644
index 000000000..ce299dd9b
--- /dev/null
+++ b/daemon/commands/audio-codec-move.h
@@ -0,0 +1,12 @@
+#ifndef COMMAND_AUDIO_CODEC_MOVE_H_
+#define COMMAND_AUDIO_CODEC_MOVE_H_
+
+#include "../daemon.h"
+
+class AudioCodecMoveCommand: public DaemonCommand {
+public:
+ AudioCodecMoveCommand();
+ virtual void exec(Daemon *app, const char *args);
+};
+
+#endif //COMMAND_AUDIO_CODEC_MOVE_H_
diff --git a/daemon/commands/audio-codec-set.cc b/daemon/commands/audio-codec-set.cc
new file mode 100644
index 000000000..5e9d2935a
--- /dev/null
+++ b/daemon/commands/audio-codec-set.cc
@@ -0,0 +1,128 @@
+#include "audio-codec-set.h"
+
+#include "private.h"
+
+/*hack, until this function comes to linphonecore*/
+#define _payload_type_get_number(pt) ((long)(pt)->user_data)
+#define _payload_type_set_number(pt,n) (pt)->user_data=(void*)(long)(n)
+
+using namespace std;
+
+AudioCodecSetCommand::AudioCodecSetCommand() :
+ DaemonCommand("audio-codec-set", "audio-codec-set ",
+ "Set a property (number, clock_rate, recv_fmtp, send_fmtp, bitrate (in kbps/s)) of a codec. Numbering of payload type is automatically performed at startup, any change will be lost after restart.\n"
+ " is of the form mime/rate/channels, eg. speex/16000/1") {
+ addExample(new DaemonCommandExample("audio-codec-set 9 number 18",
+ "Status: Ok\n\n"
+ "Index: 10\n"
+ "Payload-type-number: 18\n"
+ "Clock-rate: 8000\n"
+ "Bitrate: 64000\n"
+ "Mime: G722\n"
+ "Channels: 1\n"
+ "Recv-fmtp: \n"
+ "Send-fmtp: \n"
+ "Enabled: false"));
+ addExample(new DaemonCommandExample("audio-codec-set G722/8000/1 number 9",
+ "Status: Ok\n\n"
+ "Index: 10\n"
+ "Payload-type-number: 9\n"
+ "Clock-rate: 8000\n"
+ "Bitrate: 64000\n"
+ "Mime: G722\n"
+ "Channels: 1\n"
+ "Recv-fmtp: \n"
+ "Send-fmtp: \n"
+ "Enabled: false"));
+ addExample(new DaemonCommandExample("audio-codec-set 9 clock_rate 16000",
+ "Status: Ok\n\n"
+ "Index: 10\n"
+ "Payload-type-number: 9\n"
+ "Clock-rate: 16000\n"
+ "Bitrate: 64000\n"
+ "Mime: G722\n"
+ "Channels: 1\n"
+ "Recv-fmtp: \n"
+ "Send-fmtp: \n"
+ "Enabled: false"));
+}
+
+static PayloadType *findPayload(LinphoneCore *lc, int payload_type, int *index){
+ if (index) *index=0;
+ for (const MSList *node = linphone_core_get_audio_codecs(lc); node != NULL; node = ms_list_next(node)) {
+ PayloadType *payload = reinterpret_cast(node->data);
+ if (index) (*index)++;
+ if (payload_type == linphone_core_get_payload_type_number(lc, payload)) {
+ return payload;
+ }
+ }
+ return NULL;
+}
+
+void AudioCodecSetCommand::exec(Daemon *app, const char *args) {
+ istringstream ist(args);
+
+ if (ist.peek() == EOF) {
+ app->sendResponse(Response("Missing parameters.", Response::Error));
+ return;
+ }
+
+ string mime_type;
+ ist >> mime_type;
+ PayloadTypeParser parser(app->getCore(), mime_type);
+ if (!parser.successful()) {
+ app->sendResponse(Response("Incorrect mime type format.", Response::Error));
+ return;
+ }
+ string param;
+ string value;
+ ist >> param;
+ if (ist.fail()) {
+ app->sendResponse(Response("Missing/Incorrect parameter(s).", Response::Error));
+ return;
+ }
+ ist >> value;
+ if (value.length() > 255) value.resize(255);
+
+ PayloadType *payload=parser.getPayloadType();
+ if (payload) {
+ bool handled = false;
+ if (param.compare("clock_rate") == 0) {
+ if (value.length() > 0) {
+ payload->clock_rate = atoi(value.c_str());
+ handled = true;
+ }
+ } else if (param.compare("recv_fmtp") == 0) {
+ payload_type_set_recv_fmtp(payload, value.c_str());
+ handled = true;
+ } else if (param.compare("send_fmtp") == 0) {
+ payload_type_set_send_fmtp(payload, value.c_str());
+ handled = true;
+ } else if (param.compare("number") == 0) {
+ if (value.length() > 0) {
+ int idx=atoi(value.c_str());
+ PayloadType *conflict=NULL;
+ if (idx!=-1){
+ conflict=findPayload(app->getCore(), atoi(value.c_str()), NULL);
+ }
+ if (conflict) {
+ app->sendResponse(Response("New payload type number is already used.", Response::Error));
+ } else {
+ linphone_core_set_payload_type_number(app->getCore(),payload, idx);
+ app->sendResponse(PayloadTypeResponse(app->getCore(), payload, parser.getPosition()));
+ }
+ return;
+ }
+ } else if (param.compare("bitrate") == 0) {
+ linphone_core_set_payload_type_bitrate(app->getCore(), payload, atoi(value.c_str()));
+ handled=true;
+ }
+ if (handled) {
+ app->sendResponse(PayloadTypeResponse(app->getCore(), payload, parser.getPosition()));
+ } else {
+ app->sendResponse(Response("Invalid codec parameter.", Response::Error));
+ }
+ return;
+ }
+ app->sendResponse(Response("Audio codec not found.", Response::Error));
+}
diff --git a/daemon/commands/audio-codec-set.h b/daemon/commands/audio-codec-set.h
new file mode 100644
index 000000000..1f5a07369
--- /dev/null
+++ b/daemon/commands/audio-codec-set.h
@@ -0,0 +1,12 @@
+#ifndef COMMAND_AUDIO_CODEC_SET_H_
+#define COMMAND_AUDIO_CODEC_SET_H_
+
+#include "../daemon.h"
+
+class AudioCodecSetCommand: public DaemonCommand {
+public:
+ AudioCodecSetCommand();
+ virtual void exec(Daemon *app, const char *args);
+};
+
+#endif //COMMAND_AUDIO_CODEC_SET_H_
diff --git a/daemon/commands/audio-codec-toggle.cc b/daemon/commands/audio-codec-toggle.cc
new file mode 100644
index 000000000..4f782abe7
--- /dev/null
+++ b/daemon/commands/audio-codec-toggle.cc
@@ -0,0 +1,103 @@
+#include "audio-codec-toggle.h"
+#include "audio-codec-get.h"
+
+using namespace std;
+
+AudioCodecToggleCommand::AudioCodecToggleCommand(const char *name, const char *proto, const char *help, bool enable) :
+ DaemonCommand(name, proto, help), mEnable(enable) {
+}
+
+void AudioCodecToggleCommand::exec(Daemon *app, const char *args) {
+ istringstream ist(args);
+
+ if (ist.peek() == EOF) {
+ app->sendResponse(Response("Missing parameter.", Response::Error));
+ } else {
+ string mime_type;
+ PayloadType *pt = NULL;
+ ist >> mime_type;
+ PayloadTypeParser parser(app->getCore(), mime_type, true);
+ if (!parser.successful()) {
+ app->sendResponse(Response("Incorrect mime type format.", Response::Error));
+ return;
+ }
+ if (!parser.all()) pt = parser.getPayloadType();
+
+ int index = 0;
+ for (const MSList *node = linphone_core_get_audio_codecs(app->getCore()); node != NULL; node = ms_list_next(node)) {
+ PayloadType *payload = reinterpret_cast(node->data);
+ if (parser.all()) {
+ linphone_core_enable_payload_type(app->getCore(), payload, mEnable);
+ } else {
+ if (pt == payload) {
+ linphone_core_enable_payload_type(app->getCore(), payload, mEnable);
+ app->sendResponse(PayloadTypeResponse(app->getCore(), payload, index));
+ return;
+ }
+ }
+ ++index;
+ }
+ if (parser.all()) {
+ AudioCodecGetCommand getCommand;
+ getCommand.exec(app, "");
+ } else {
+ app->sendResponse(Response("Audio codec not found.", Response::Error));
+ }
+ }
+}
+
+AudioCodecEnableCommand::AudioCodecEnableCommand() :
+ AudioCodecToggleCommand("audio-codec-enable", "audio-codec-enable ",
+ "Enable an audio codec.\n"
+ " is of the form mime/rate/channels, eg. speex/16000/1", true) {
+ addExample(new DaemonCommandExample("audio-codec-enable G722/8000/1",
+ "Status: Ok\n\n"
+ "Index: 9\n"
+ "Payload-type-number: 9\n"
+ "Clock-rate: 8000\n"
+ "Bitrate: 64000\n"
+ "Mime: G722\n"
+ "Channels: 1\n"
+ "Recv-fmtp: \n"
+ "Send-fmtp: \n"
+ "Enabled: true"));
+ addExample(new DaemonCommandExample("audio-codec-enable 9",
+ "Status: Ok\n\n"
+ "Index: 9\n"
+ "Payload-type-number: 9\n"
+ "Clock-rate: 8000\n"
+ "Bitrate: 64000\n"
+ "Mime: G722\n"
+ "Channels: 1\n"
+ "Recv-fmtp: \n"
+ "Send-fmtp: \n"
+ "Enabled: true"));
+}
+
+AudioCodecDisableCommand::AudioCodecDisableCommand() :
+ AudioCodecToggleCommand("audio-codec-disable", "audio-codec-disable ",
+ "Disable an audio codec.\n"
+ " is of the form mime/rate/channels, eg. speex/16000/1", false) {
+ addExample(new DaemonCommandExample("audio-codec-disable G722/8000/1",
+ "Status: Ok\n\n"
+ "Index: 9\n"
+ "Payload-type-number: 9\n"
+ "Clock-rate: 8000\n"
+ "Bitrate: 64000\n"
+ "Mime: G722\n"
+ "Channels: 1\n"
+ "Recv-fmtp: \n"
+ "Send-fmtp: \n"
+ "Enabled: false"));
+ addExample(new DaemonCommandExample("audio-codec-disable 9",
+ "Status: Ok\n\n"
+ "Index: 9\n"
+ "Payload-type-number: 9\n"
+ "Clock-rate: 8000\n"
+ "Bitrate: 64000\n"
+ "Mime: G722\n"
+ "Channels: 1\n"
+ "Recv-fmtp: \n"
+ "Send-fmtp: \n"
+ "Enabled: false"));
+}
\ No newline at end of file
diff --git a/daemon/commands/audio-codec-toggle.h b/daemon/commands/audio-codec-toggle.h
new file mode 100644
index 000000000..bce36dfa2
--- /dev/null
+++ b/daemon/commands/audio-codec-toggle.h
@@ -0,0 +1,24 @@
+#ifndef COMMAND_AUDIO_CODEC_TOGGLE_H_
+#define COMMAND_AUDIO_CODEC_TOGGLE_H_
+
+#include "../daemon.h"
+
+class AudioCodecToggleCommand: public DaemonCommand {
+public:
+ AudioCodecToggleCommand(const char *name, const char *proto, const char *help, bool enable);
+ virtual void exec(Daemon *app, const char *args);
+protected:
+ bool mEnable;
+};
+
+class AudioCodecEnableCommand: public AudioCodecToggleCommand {
+public:
+ AudioCodecEnableCommand();
+};
+
+class AudioCodecDisableCommand: public AudioCodecToggleCommand {
+public:
+ AudioCodecDisableCommand();
+};
+
+#endif //COMMAND_AUDIO_CODEC_TOGGLE_H_
diff --git a/daemon/commands/audio-stream-start.cc b/daemon/commands/audio-stream-start.cc
new file mode 100644
index 000000000..e6b8bf8ba
--- /dev/null
+++ b/daemon/commands/audio-stream-start.cc
@@ -0,0 +1,76 @@
+#include "audio-stream-start.h"
+#include "private.h"
+
+using namespace std;
+
+AudioStreamStartCommand::AudioStreamStartCommand() :
+ DaemonCommand("audio-stream-start", "audio-stream-start ", "Start an audio stream.") {
+ addExample(new DaemonCommandExample("audio-stream-start 192.168.1.28 7078 9",
+ "Status: Ok\n\n"
+ "Id: 1"));
+}
+
+static PayloadType *getPayloadType(LinphoneCore *lc, const MSList *codecs, int number){
+ const MSList *elem;
+ for (elem=codecs;elem!=NULL;elem=elem->next){
+ PayloadType *pt=(PayloadType*)elem->data;
+ if (linphone_core_get_payload_type_number(lc, pt)==number)
+ return pt;
+ }
+ return NULL;
+}
+
+void AudioStreamStartCommand::exec(Daemon *app, const char *args) {
+ char addr[256];
+ int port;
+ int payload_type;
+ MSFactory* factory ;
+
+ factory = (app->getCore())->factory;
+
+ if (sscanf(args, "%255s %d %d", addr, &port, &payload_type) == 3) {
+ int local_port = linphone_core_get_audio_port(app->getCore());
+ int jitt = linphone_core_get_audio_jittcomp(app->getCore());
+ bool_t echo_canceller = linphone_core_echo_cancellation_enabled(app->getCore());
+ int ptime=linphone_core_get_upload_ptime(app->getCore());
+ MSSndCardManager *manager = ms_factory_get_snd_card_manager(factory);
+ MSSndCard *capture_card = ms_snd_card_manager_get_card(manager, linphone_core_get_capture_device(app->getCore()));
+ MSSndCard *play_card = ms_snd_card_manager_get_card(manager, linphone_core_get_playback_device(app->getCore()));
+ RtpProfile *prof=rtp_profile_new("stream");
+ PayloadType *pt=getPayloadType(app->getCore(), linphone_core_get_audio_codecs(app->getCore()), payload_type);
+
+ if (!pt){
+ app->sendResponse(Response("No payload type were assigned to this number."));
+ return;
+ }
+ AudioStream *stream = audio_stream_new(factory, local_port, local_port + 1, linphone_core_ipv6_enabled(app->getCore()));
+ audio_stream_set_features(stream,linphone_core_get_audio_features(app->getCore()));
+
+ pt=payload_type_clone(pt);
+ if (ptime!=0){
+ char fmtp[32];
+ snprintf(fmtp,sizeof(fmtp)-1,"ptime=%i",ptime);
+ payload_type_append_send_fmtp(pt,fmtp);
+ }
+ rtp_profile_set_payload(prof,payload_type,pt);
+ if (linphone_core_generic_confort_noise_enabled(app->getCore())){
+ rtp_profile_set_payload(prof,13,payload_type_clone(&payload_type_cn));
+ }
+
+
+ audio_stream_enable_adaptive_jittcomp(stream, linphone_core_audio_adaptive_jittcomp_enabled(app->getCore()));
+ rtp_session_set_symmetric_rtp(stream->ms.sessions.rtp_session, linphone_core_symmetric_rtp_enabled(app->getCore()));
+
+ int err=audio_stream_start_now(stream, prof, addr, port, port + 1, payload_type, jitt, play_card, capture_card, echo_canceller);
+
+ if (err != 0) {
+ app->sendResponse(Response("Error during audio stream creation."));
+ return;
+ }
+ ostringstream ostr;
+ ostr << "Id: " << app->updateAudioStreamId(stream) << "\n";
+ app->sendResponse(Response(ostr.str().c_str(), Response::Ok));
+ } else {
+ app->sendResponse(Response("Missing/Incorrect parameter(s)."));
+ }
+}
diff --git a/daemon/commands/audio-stream-start.h b/daemon/commands/audio-stream-start.h
new file mode 100644
index 000000000..e32f9192f
--- /dev/null
+++ b/daemon/commands/audio-stream-start.h
@@ -0,0 +1,12 @@
+#ifndef COMMAND_AUDIO_STREAM_START_H_
+#define COMMAND_AUDIO_STREAM_START_H_
+
+#include "../daemon.h"
+
+class AudioStreamStartCommand: public DaemonCommand {
+public:
+ AudioStreamStartCommand();
+ virtual void exec(Daemon *app, const char *args);
+};
+
+#endif //COMMAND_AUDIO_STREAM_START_H_
diff --git a/daemon/commands/audio-stream-stats.cc b/daemon/commands/audio-stream-stats.cc
new file mode 100644
index 000000000..8ec208301
--- /dev/null
+++ b/daemon/commands/audio-stream-stats.cc
@@ -0,0 +1,46 @@
+#include "audio-stream-stats.h"
+
+using namespace std;
+
+AudioStreamStatsCommand::AudioStreamStatsCommand() :
+ DaemonCommand("audio-stream-stats", "audio-stream-stats ", "Return stats of a given audio stream.") {
+ addExample(new DaemonCommandExample("audio-stream-stats 1",
+ "Status: Ok\n\n"
+ "Audio-ICE state: Not activated\n"
+ "Audio-RoundTripDelay: 0.0859833\n"
+ "Audio-Jitter: 296\n"
+ "Audio-JitterBufferSizeMs: 47.7778\n"
+ "Audio-Received-InterarrivalJitter: 154\n"
+ "Audio-Received-FractionLost: 0\n"
+ "Audio-Sent-InterarrivalJitter: 296\n"
+ "Audio-Sent-FractionLost: 0\n"
+ "Audio-Payload-type-number: 111\n"
+ "Audio-Clock-rate: 16000\n"
+ "Audio-Bitrate: 44000\n"
+ "Audio-Mime: speex\n"
+ "Audio-Channels: 1\n"
+ "Audio-Recv-fmtp: vbr=on\n"
+ "Audio-Send-fmtp: vbr=on"));
+ addExample(new DaemonCommandExample("audio-stream-stats 2",
+ "Status: Error\n"
+ "Reason: No audio stream with such id."));
+}
+
+void AudioStreamStatsCommand::exec(Daemon *app, const char *args) {
+ int sid;
+ AudioStreamAndOther *stream = NULL;
+ if (sscanf(args, "%i", &sid) == 1) {
+ stream = app->findAudioStreamAndOther(sid);
+ if (!stream) {
+ app->sendResponse(Response("No audio stream with such id."));
+ return;
+ }
+ } else {
+ app->sendResponse(Response("No stream specified."));
+ return;
+ }
+
+ ostringstream ostr;
+ ostr << AudioStreamStatsResponse(app, stream->stream, &stream->stats, false).getBody();
+ app->sendResponse(Response(ostr.str().c_str(), Response::Ok));
+}
diff --git a/daemon/commands/audio-stream-stats.h b/daemon/commands/audio-stream-stats.h
new file mode 100644
index 000000000..c25746cd0
--- /dev/null
+++ b/daemon/commands/audio-stream-stats.h
@@ -0,0 +1,12 @@
+#ifndef COMMAND_AUDIO_STREAM_STATS_H_
+#define COMMAND_AUDIO_STREAM_STATS_H_
+
+#include "../daemon.h"
+
+class AudioStreamStatsCommand: public DaemonCommand {
+public:
+ AudioStreamStatsCommand();
+ virtual void exec(Daemon *app, const char *args);
+};
+
+#endif //COMMAND_AUDIO_STREAM_STATS_H_
diff --git a/daemon/commands/audio-stream-stop.cc b/daemon/commands/audio-stream-stop.cc
new file mode 100644
index 000000000..69a1ec862
--- /dev/null
+++ b/daemon/commands/audio-stream-stop.cc
@@ -0,0 +1,30 @@
+#include "audio-stream-stop.h"
+
+using namespace std;
+
+AudioStreamStopCommand::AudioStreamStopCommand() :
+ DaemonCommand("audio-stream-stop", "audio-stream-stop
"<"<<"Examples"<<""< &examples=(*it)->getExamples();
+ cout<<"";
+ for(list::const_iterator ex_it=examples.begin();ex_it!=examples.end();++ex_it){
+ cout<<""<")<getCommand())<<"
"<getOutput())<<"
"<
";
+ }
+ cout<<"
"<"<]\n"
+#if defined(LICENCE_GPL) || defined(LICENCE_COMMERCIAL)
+ "Licence: "
+#ifdef LICENCE_GPL
+ "GPL"
+#endif
+#ifdef LICENCE_COMMERCIAL
+ "Commercial"
+#endif
+ "\n"
+#endif
+
+ "where options are :\n"
+ "\t--help\t\t\tPrint this notice.\n"
+ "\t--dump-commands-help\tDump the help of every available commands.\n"
+ "\t--dump-commands-html-help\tDump the help of every available commands.\n"
+ "\t--pipe \tCreate an unix server socket to receive commands.\n"
+ "\t--log \t\tSupply a file where the log will be saved.\n"
+ "\t--factory-config \tSupply a readonly linphonerc style config file to start with.\n"
+ "\t--config \t\tSupply a linphonerc style config file to start with.\n"
+ "\t--disable-stats-events\t\tDo not automatically raise RTP statistics events.\n"
+ "\t--enable-lsd\t\tUse the linphone sound daemon.\n"
+ "\t-C\t\t\tenable video capture.\n"
+ "\t-D\t\t\tenable video display.\n");
+}
+
+void Daemon::startThread() {
+ ms_thread_create(&this->mThread, NULL, Daemon::iterateThread, this);
+}
+
+char *Daemon::readLine(const char *prompt, bool *eof) {
+ *eof=false;
+#ifdef HAVE_READLINE
+ return readline(prompt);
+#else
+ if (cin.eof()) {
+ *eof=true;
+ return NULL;
+ }
+ cout << prompt;
+ char *buff = (char *) malloc(sLineSize);
+ cin.getline(buff, sLineSize);
+ return buff;
+#endif
+}
+
+int Daemon::run() {
+ char line[sLineSize] = "daemon-linphone>";
+ char *ret;
+ mRunning = true;
+ startThread();
+ while (mRunning) {
+ bool eof=false;
+ if (mServerFd == -1) {
+ ret = readLine(line,&eof);
+ if (ret && ret[0] != '\0') {
+#ifdef HAVE_READLINE
+ add_history(ret);
+#endif
+ }
+ } else {
+ ret = readPipe(line, sLineSize);
+ }
+ if (ret && ret[0] != '\0') {
+ execCommand(ret);
+ }
+ if (mServerFd == -1 && ret != NULL) {
+ free(ret);
+ }
+ if (eof && mRunning) {
+ mRunning = false; // ctrl+d
+ cout << "Quitting..." << endl;
+ }
+ }
+ stopThread();
+ return 0;
+}
+
+void Daemon::stopThread() {
+ void *ret;
+ ms_thread_join(mThread, &ret);
+}
+
+void Daemon::quit() {
+ mRunning = false;
+}
+
+void Daemon::enableStatsEvents(bool enabled){
+ mUseStatsEvents=enabled;
+}
+
+void Daemon::enableLSD(bool enabled) {
+ if (mLSD) linphone_sound_daemon_destroy(mLSD);
+ linphone_core_use_sound_daemon(mLc, NULL);
+ if (enabled) {
+ mLSD = linphone_sound_daemon_new(mLc->factory,NULL, 44100, 1);
+ linphone_core_use_sound_daemon(mLc, mLSD);
+ }
+}
+
+Daemon::~Daemon() {
+ uninitCommands();
+
+ for (std::map::iterator it = mAudioStreams.begin(); it != mAudioStreams.end(); ++it) {
+ audio_stream_stop(it->second->stream);
+ }
+
+ enableLSD(false);
+ linphone_core_destroy(mLc);
+ if (mChildFd != -1) {
+ close(mChildFd);
+ }
+ if (mServerFd != -1) {
+ ortp_server_pipe_close(mServerFd);
+ }
+ if (mLogFile != NULL) {
+ linphone_core_enable_logs(NULL);
+ fclose(mLogFile);
+ }
+
+ ms_mutex_destroy(&mMutex);
+
+#ifdef HAVE_READLINE
+ stifle_history(30);
+ write_history(mHistfile.c_str());
+#endif
+}
+
+int main(int argc, char *argv[]) {
+ const char *config_path = NULL;
+ const char *factory_config_path = NULL;
+ const char *pipe_name = NULL;
+ const char *log_file = NULL;
+ bool capture_video = false;
+ bool display_video = false;
+ bool stats_enabled = true;
+ bool lsd_enabled = false;
+ int i;
+
+ for (i = 1; i < argc; ++i) {
+ if (strcmp(argv[i], "--help") == 0) {
+ printHelp();
+ return 0;
+ } else if (strcmp(argv[i], "--dump-commands-help") == 0) {
+ Daemon app(NULL, NULL, NULL, NULL, false, false);
+ app.dumpCommandsHelp();
+ return 0;
+ }else if (strcmp(argv[i], "--dump-commands-html-help") == 0) {
+ Daemon app(NULL, NULL, NULL, NULL, false, false);
+ app.dumpCommandsHelpHtml();
+ return 0;
+ } else if (strcmp(argv[i], "--pipe") == 0) {
+ if (i + 1 >= argc) {
+ fprintf(stderr, "no pipe name specify after --pipe\n");
+ return -1;
+ }
+ pipe_name = argv[++i];
+ } else if (strcmp(argv[i], "--factory-config") == 0) {
+ if (i + 1 >= argc) {
+ fprintf(stderr, "no file specify after --factory-config\n");
+ return -1;
+ }
+ factory_config_path = argv[i + 1];
+ i++;
+ } else if (strcmp(argv[i], "--config") == 0) {
+ if (i + 1 >= argc) {
+ fprintf(stderr, "no file specify after --config\n");
+ return -1;
+ }
+ config_path = argv[i + 1];
+ i++;
+ } else if (strcmp(argv[i], "--log") == 0) {
+ if (i + 1 >= argc) {
+ fprintf(stderr, "no file specify after --log\n");
+ return -1;
+ }
+ log_file = argv[i + 1];
+ i++;
+ } else if (strcmp(argv[i], "-C") == 0) {
+ capture_video = true;
+ } else if (strcmp(argv[i], "-D") == 0) {
+ display_video = true;
+ }else if (strcmp(argv[i],"--disable-stats-events")==0){
+ stats_enabled = false;
+ } else if (strcmp(argv[i], "--enable-lsd") == 0) {
+ lsd_enabled = true;
+ }
+ }
+ Daemon app(config_path, factory_config_path, log_file, pipe_name, display_video, capture_video);
+ app.enableStatsEvents(stats_enabled);
+ app.enableLSD(lsd_enabled);
+ return app.run();
+}
diff --git a/daemon/daemon.h b/daemon/daemon.h
new file mode 100644
index 000000000..564cb7994
--- /dev/null
+++ b/daemon/daemon.h
@@ -0,0 +1,263 @@
+#ifndef DAEMON_H_
+#define DAEMON_H_
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include