Skip to content
Snippets Groups Projects
Commit 83f960cc authored by Emmanuel Milou's avatar Emmanuel Milou
Browse files
Conflicts:
	tools/build-system/launchpad/dput.conf
parents 4528e2d9 ad979d4f
No related branches found
No related tags found
No related merge requests found
Showing
with 629 additions and 325 deletions
[submodule "kde"]
path = kde
url = https://github.com/Elv13/sflphone-kde.git
...@@ -10,7 +10,7 @@ AM_INIT_AUTOMAKE ...@@ -10,7 +10,7 @@ AM_INIT_AUTOMAKE
AC_CONFIG_HEADERS([config.h]) AC_CONFIG_HEADERS([config.h])
# Silent build by default. Use make V=1 to increase verbosity # Silent build by default. Use make V=1 to increase verbosity
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) #m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
dnl Improve make variable MAKE dnl Improve make variable MAKE
AC_PROG_MAKE_SET AC_PROG_MAKE_SET
...@@ -63,29 +63,29 @@ AC_CHECK_TYPES([ptrdiff_t]) ...@@ -63,29 +63,29 @@ AC_CHECK_TYPES([ptrdiff_t])
dnl ******************************** dnl ********************************
dnl Check for needed functions dnl Check for needed functions
dnl ******************************** dnl ********************************
AC_FUNC_CHOWN #AC_FUNC_CHOWN
AC_FUNC_ERROR_AT_LINE #AC_FUNC_ERROR_AT_LINE
AC_FUNC_FORK #AC_FUNC_FORK
AC_PROG_GCC_TRADITIONAL #AC_PROG_GCC_TRADITIONAL
AC_FUNC_MALLOC #AC_FUNC_MALLOC
AC_FUNC_MEMCMP #AC_FUNC_MEMCMP
AC_FUNC_REALLOC #AC_FUNC_REALLOC
AC_FUNC_SELECT_ARGTYPES #AC_FUNC_SELECT_ARGTYPES
AC_DIAGNOSE([obsolete],[your code may safely assume C89 semantics that RETSIGTYPE is void. #AC_DIAGNOSE([obsolete],[your code may safely assume C89 semantics that RETSIGTYPE is void.
Remove this warning and the `AC_CACHE_CHECK' when you adjust the code.])dnl #Remove this warning and the `AC_CACHE_CHECK' when you adjust the code.])dnl
AC_CACHE_CHECK([return type of signal handlers],[ac_cv_type_signal],[AC_COMPILE_IFELSE( #AC_CACHE_CHECK([return type of signal handlers],[ac_cv_type_signal],[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([#include <sys/types.h> #[AC_LANG_PROGRAM([#include <sys/types.h>
#include <signal.h> ##include <signal.h>
], #],
[return *(signal (0, 0)) (0) == 1;])], # [return *(signal (0, 0)) (0) == 1;])],
[ac_cv_type_signal=int], # [ac_cv_type_signal=int],
[ac_cv_type_signal=void])]) # [ac_cv_type_signal=void])])
AC_DEFINE_UNQUOTED([RETSIGTYPE],[$ac_cv_type_signal],[Define as the return type of signal handlers #AC_DEFINE_UNQUOTED([RETSIGTYPE],[$ac_cv_type_signal],[Define as the return type of signal handlers
(`int' or `void').]) # (`int' or `void').])
AC_FUNC_STAT #AC_FUNC_STAT
AC_FUNC_UTIME_NULL #AC_FUNC_UTIME_NULL
AC_FUNC_VPRINTF #AC_FUNC_VPRINTF
dnl Check for GNU ccRTP dnl Check for GNU ccRTP
PKG_PROG_PKG_CONFIG PKG_PROG_PKG_CONFIG
...@@ -110,7 +110,6 @@ AC_ARG_WITH([pulse], ...@@ -110,7 +110,6 @@ AC_ARG_WITH([pulse],
[ AS_HELP_STRING([--without-pulse], [disable support for pulseaudio]) ], [ AS_HELP_STRING([--without-pulse], [disable support for pulseaudio]) ],
[], [],
[with_pulse=yes]) [with_pulse=yes])
AS_IF([test "x$with_pulse" = "xyes"], [ AS_IF([test "x$with_pulse" = "xyes"], [
PKG_CHECK_MODULES(PULSEAUDIO, libpulse >= ${LIBPULSE_MIN_VERSION},, AC_MSG_ERROR([Missing pulseaudio development package: libpulse-dev])) PKG_CHECK_MODULES(PULSEAUDIO, libpulse >= ${LIBPULSE_MIN_VERSION},, AC_MSG_ERROR([Missing pulseaudio development package: libpulse-dev]))
]); ]);
...@@ -161,13 +160,43 @@ PKG_CHECK_MODULES([CCRTP], [libccrtp] >= ${LIBCCRTP_MIN_VERSION},, [ ...@@ -161,13 +160,43 @@ PKG_CHECK_MODULES([CCRTP], [libccrtp] >= ${LIBCCRTP_MIN_VERSION},, [
PKG_CHECK_MODULES([CCRTP], [libccrtp1] >= ${LIBCCRTP_MIN_VERSION},, AC_MSG_ERROR([Missing ccrtp development package: libccrtp-dev])) PKG_CHECK_MODULES([CCRTP], [libccrtp1] >= ${LIBCCRTP_MIN_VERSION},, AC_MSG_ERROR([Missing ccrtp development package: libccrtp-dev]))
]) ])
# TLS
# required dependency(ies): libssl
dnl Check for OpenSSL to link against pjsip and provide SIPS TLS support dnl Check for OpenSSL to link against pjsip and provide SIPS TLS support
AC_ARG_WITH([tls],
[ AS_HELP_STRING([--without-tls], [disable support for tls]) ],
[],
[with_tls=yes])
AS_IF([test "x$with_tls" = "xyes"], [
PKG_CHECK_MODULES([libssl], libssl,, AC_MSG_ERROR([Missing ssl development package: libssl-dev])) PKG_CHECK_MODULES([libssl], libssl,, AC_MSG_ERROR([Missing ssl development package: libssl-dev]))
]);
AC_DEFINE_UNQUOTED([HAVE_TLS], `if test "x$with_tls" = "xyes"; then echo 1; else echo 0; fi`, [Define if you have tls support])
AM_CONDITIONAL(BUILD_TLS, test "x$with_tls" = "xyes" )
# ZRTP
# required dependency(ies): libzrtp
dnl Check for libzrtpcpp, a ccRTP extension providing zrtp key exchange dnl Check for libzrtpcpp, a ccRTP extension providing zrtp key exchange
LIBZRTPCPP_MIN_VERSION=1.3.0 LIBZRTPCPP_MIN_VERSION=1.3.0
PKG_CHECK_MODULES(ZRTPCPP, libzrtpcpp >= ${LIBZRTPCPP_MIN_VERSION},, AC_MSG_ERROR([Missing zrtp development package: libzrtpcpp-dev])) AC_ARG_WITH([zrtp],
[ AS_HELP_STRING([--without-zrtp], [disable support for zrtp]) ],
[],
[with_zrtp=yes])
AS_IF([test "x$with_zrtp" = "xyes"], [
PKG_CHECK_MODULES([ZRTPCPP], libzrtpcpp >= ${LIBZRTPCPP_MIN_VERSION},, AC_MSG_ERROR([Missing zrtp development package: libzrtpcpp-dev]))
]);
AC_DEFINE_UNQUOTED([HAVE_ZRTP], `if test "x$with_zrtp" = "xyes"; then echo 1; else echo 0; fi`, [Define if you have zrtp support])
AM_CONDITIONAL(BUILD_ZRTP, test "x$with_zrtp" = "xyes" )
# DBUS
# required dependency(ies): libdbus-c++
dnl DBus-C++ detection dnl DBus-C++ detection
dnl pkg-config doesn't like 0.6.0-pre1 version number, it assumes that it is dnl pkg-config doesn't like 0.6.0-pre1 version number, it assumes that it is
dnl more recent than (unreleased) 0.6.0 dnl more recent than (unreleased) 0.6.0
...@@ -175,17 +204,51 @@ DBUS_CPP_REQUIRED_VERSION=0.6.0-pre1 ...@@ -175,17 +204,51 @@ DBUS_CPP_REQUIRED_VERSION=0.6.0-pre1
PKG_CHECK_MODULES(DBUSCPP, dbus-c++-1,, PKG_CHECK_MODULES(DBUSCPP, dbus-c++-1,,
AC_MSG_ERROR([You need the DBus-c++ libraries (version $DBUS_CPP_REQUIRED_VERSION or better)])) AC_MSG_ERROR([You need the DBus-c++ libraries (version $DBUS_CPP_REQUIRED_VERSION or better)]))
AX_LIB_EXPAT([1.95.8])
# Instant Messaging
# required dependency(ies): libxpat
AC_ARG_WITH([instant_messaging],
[ AS_HELP_STRING([--without-instant_messaging], [disable support for instant-messaging]) ],
[],
[with_instant_messaging=yes])
AS_IF([test "x$with_instant_messaging" = "xyes"], [
AX_LIB_EXPAT([1.95.0])
AS_IF([test "$HAVE_EXPAT" != "yes"], [AC_MSG_ERROR([libexpat could not be found, which is required to build this package.])], []) AS_IF([test "$HAVE_EXPAT" != "yes"], [AC_MSG_ERROR([libexpat could not be found, which is required to build this package.])], [])
]);
AC_DEFINE_UNQUOTED([HAVE_INSTANT_MESSAGING], `if test "x$with_instant_messaging" = "xyes"; then echo 1; else echo 0; fi`, [Define if you have instant messaging support])
AM_CONDITIONAL(BUILD_INSTANT_MESSAGING, test "x$with_instant_messaging" = "xyes" )
# PTHREAD
# required dependency(ies): libxpat
AX_PTHREAD AX_PTHREAD
# SDES Key Exchange
# required dependency(ies): libpcre
AC_ARG_WITH([sdes],
[ AS_HELP_STRING([--without-sdes], [disable support for sdes key exchange]) ],
[],
[with_sdes=yes])
AS_IF([test "x$with_sdes" = "xyes"], [
AX_PATH_LIB_PCRE AX_PATH_LIB_PCRE
]);
AC_DEFINE_UNQUOTED([HAVE_SDES], `if test "x$with_sdes" = "xyes"; then echo 1; else echo 0; fi`, [Define if you have sdes support])
AM_CONDITIONAL(BUILD_SDES, test "x$with_sdes" = "xyes" )
dnl Check for libcppunit-dev dnl Check for libcppunit-dev
CPPUNIT_MIN_VERSION=1.12 CPPUNIT_MIN_VERSION=1.12
PKG_CHECK_MODULES(CPPUNIT, cppunit >= ${CPPUNIT_MIN_VERSION}, AM_CONDITIONAL(BUILD_TEST, test 1 = 1 ), AM_CONDITIONAL(BUILD_TEST, test 0 = 1 )) PKG_CHECK_MODULES(CPPUNIT, cppunit >= ${CPPUNIT_MIN_VERSION}, AM_CONDITIONAL(BUILD_TEST, test 1 = 1 ), AM_CONDITIONAL(BUILD_TEST, test 0 = 1 ))
# GSM CODEC
# required dependency(ies): libgsm
dnl check for libgsm1 (doesn't use pkg-config) dnl check for libgsm1 (doesn't use pkg-config)
dnl Check for libgsm dnl Check for libgsm
AC_ARG_WITH([gsm], [AS_HELP_STRING([--without-gsm], AC_ARG_WITH([gsm], [AS_HELP_STRING([--without-gsm],
...@@ -202,10 +265,13 @@ AS_IF([test "x$with_gsm" != xno], ...@@ -202,10 +265,13 @@ AS_IF([test "x$with_gsm" != xno],
AC_DEFINE_UNQUOTED([HAVE_GSM], `if test "x$with_gsm" = "xyes"; then echo 1; else echo 0; fi`, [Define if you have libgsm]) AC_DEFINE_UNQUOTED([HAVE_GSM], `if test "x$with_gsm" = "xyes"; then echo 1; else echo 0; fi`, [Define if you have libgsm])
AM_CONDITIONAL(BUILD_GSM, test "x$with_gsm" = "xyes" ) AM_CONDITIONAL(BUILD_GSM, test "x$with_gsm" = "xyes" )
# SPEEX CODEC
# required dependency(ies): libspeex
dnl Check for libspeex dnl Check for libspeex
AC_ARG_WITH([speex], AC_ARG_WITH([speex],
[AS_HELP_STRING([--without-speex], [AS_HELP_STRING([--without-speex], [disable support for speex codec])],
[disable support for speex codec])],
[], [],
[with_speex=yes]) [with_speex=yes])
...@@ -219,12 +285,29 @@ AS_IF([test "x$with_speex" != xno], ...@@ -219,12 +285,29 @@ AS_IF([test "x$with_speex" != xno],
AC_DEFINE_UNQUOTED([HAVE_SPEEX], `if test "x$with_speex" = "xyes"; then echo 1; else echo 0; fi`, [Define if you have libspeex]) AC_DEFINE_UNQUOTED([HAVE_SPEEX], `if test "x$with_speex" = "xyes"; then echo 1; else echo 0; fi`, [Define if you have libspeex])
AM_CONDITIONAL(BUILD_SPEEX, test "x$with_speex" = "xyes" ) AM_CONDITIONAL(BUILD_SPEEX, test "x$with_speex" = "xyes" )
# SPEEX DSP
# required dependency(ies): libspeexdsp
dnl check in case the libspeexdsp is not installed dnl check in case the libspeexdsp is not installed
AC_ARG_WITH([speexdsp],
[AS_HELP_STRING([--without-speexdsp],
[disable support for speexdp Noise Suppression and Automatic Gain Control])],
[],
[with_speexdsp=yes])
AS_IF([test "x$with_speexdsp" != xno],
AC_CHECK_HEADER([speex/speex_preprocess.h], , AC_MSG_FAILURE([Unable to find the libspeexdsp headers (you may need to install the libspeexdsp-dev package) used for Noise Suppression and Automatic Gain Control.])) AC_CHECK_HEADER([speex/speex_preprocess.h], , AC_MSG_FAILURE([Unable to find the libspeexdsp headers (you may need to install the libspeexdsp-dev package) used for Noise Suppression and Automatic Gain Control.]))
AC_SEARCH_LIBS([speex_preprocess_run], [speexdsp], [], [ AC_SEARCH_LIBS([speex_preprocess_run], [speexdsp], [], [AC_MSG_ERROR([Unable to find speexdsp development files])])
AC_MSG_ERROR([Unable to find speexdsp development files]) )
])
AC_DEFINE_UNQUOTED([HAVE_SPEEXDSP], `if test "x$with_speexdsp" = "xyes"; then echo 1; else echo 0; fi`, [Define if you have libspeexdsp])
AM_CONDITIONAL(BUILD_SPEEXDSP, test "x$with_speexdsp" = "xyes" )
# IAX
# required dependency(ies): libiax2 (static)
dnl Check for IAX dnl Check for IAX
AC_ARG_WITH([iax2], [AS_HELP_STRING([--without-iax2], AC_ARG_WITH([iax2], [AS_HELP_STRING([--without-iax2],
[disable support for the iax2 protocol])], [], [with_iax2=yes]) [disable support for the iax2 protocol])], [], [with_iax2=yes])
...@@ -232,6 +315,10 @@ AC_ARG_WITH([iax2], [AS_HELP_STRING([--without-iax2], ...@@ -232,6 +315,10 @@ AC_ARG_WITH([iax2], [AS_HELP_STRING([--without-iax2],
AC_DEFINE_UNQUOTED([HAVE_IAX], `if test "x$with_iax2" = "xyes"; then echo 1; else echo 0;fi`, [Define if you have libiax2]) AC_DEFINE_UNQUOTED([HAVE_IAX], `if test "x$with_iax2" = "xyes"; then echo 1; else echo 0;fi`, [Define if you have libiax2])
AM_CONDITIONAL(USE_IAX, test "x$with_iax2" = "xyes" ) AM_CONDITIONAL(USE_IAX, test "x$with_iax2" = "xyes" )
# NETWORK MANAGER
# required dependency(ies): libiax2 (static)
dnl Check for network-manager dnl Check for network-manager
AC_ARG_WITH([networkmanager], [AS_HELP_STRING([--without-networkmanager], AC_ARG_WITH([networkmanager], [AS_HELP_STRING([--without-networkmanager],
[disable support for network-manager events])], [], [disable support for network-manager events])], [],
...@@ -239,6 +326,10 @@ AC_ARG_WITH([networkmanager], [AS_HELP_STRING([--without-networkmanager], ...@@ -239,6 +326,10 @@ AC_ARG_WITH([networkmanager], [AS_HELP_STRING([--without-networkmanager],
AM_CONDITIONAL(USE_NETWORKMANAGER, test "x$with_networkmanager" = "xyes" ) AM_CONDITIONAL(USE_NETWORKMANAGER, test "x$with_networkmanager" = "xyes" )
# DOXYGEN
# required dependency(ies): doxygen
# check for doxygen, mostly stolen from http://log4cpp.sourceforge.net/ # check for doxygen, mostly stolen from http://log4cpp.sourceforge.net/
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
AC_DEFUN([BB_ENABLE_DOXYGEN], AC_DEFUN([BB_ENABLE_DOXYGEN],
...@@ -256,7 +347,9 @@ AC_DEFUN([BB_ENABLE_DOXYGEN], ...@@ -256,7 +347,9 @@ AC_DEFUN([BB_ENABLE_DOXYGEN],
# Acutally perform the doxygen check # Acutally perform the doxygen check
BB_ENABLE_DOXYGEN BB_ENABLE_DOXYGEN
CXXFLAGS="${CXXFLAGS} -g -Wno-return-type -Wall -Wextra -Wnon-virtual-dtor -Weffc++ -Wfatal-errors"
CXXFLAGS="${CXXFLAGS} -g -Wno-return-type -Wall -Wextra -Wnon-virtual-dtor -Weffc++"
dnl What to generate dnl What to generate
AC_CONFIG_FILES([Makefile]) AC_CONFIG_FILES([Makefile])
......
if USE_IAX
SUBDIRS = iax2 SUBDIRS = iax2
endif
EXTRA_DIST=pjproject EXTRA_DIST=pjproject
SECTION="1" SECTION="1"
TEMPLATES=\ TEMPLATES=sflphoned.pod
sflphoned.pod
man_MANS=sflphoned.1 man_MANS=sflphoned.1
POD2MAN=pod2man POD2MAN=pod2man
EXTRA_DIST= $(man_MANS) EXTRA_DIST=$(man_MANS) $(TEMPLATES)
all: $(MANPAGES) all: $(MANPAGES)
......
...@@ -5,27 +5,29 @@ libexec_PROGRAMS = sflphoned ...@@ -5,27 +5,29 @@ libexec_PROGRAMS = sflphoned
if SFL_VIDEO if SFL_VIDEO
SFL_VIDEO_SUBDIR = video SFL_VIDEO_SUBDIR = video
SFL_VIDEO_LIB=./video/libvideo.la
endif endif
SUBDIRS = dbus audio config hooks history sip iax im $(SFL_VIDEO_SUBDIR) if BUILD_INSTANT_MESSAGING
INSTANT_MESSAGING_SUBDIR = im
sflphoned_SOURCES = main.cpp IM_LIB=./im/libim.la
endif
# Redefine the USE_IAX variable here, so that it could be used in managerimpl # Redefine the USE_IAX variable here, so that it could be used in managerimpl
if USE_IAX if USE_IAX
IAX_SUBDIR=iax
IAX_CXXFLAG=-DUSE_IAX IAX_CXXFLAG=-DUSE_IAX
IAX_LIB=./iax/libiaxlink.la IAX_LIB=./iax/libiaxlink.la $(top_builddir)/libs/iax2/libiax2.la
else
IAX_CXXFLAG=
IAX_LIB=
endif endif
if USE_NETWORKMANAGER if USE_NETWORKMANAGER
NETWORKMANAGER=-DUSE_NETWORKMANAGER NETWORKMANAGER=-DUSE_NETWORKMANAGER
else
NETWORKMANAGER=
endif endif
SUBDIRS = dbus audio config hooks history sip $(IAX_SUBDIR) $(INSTANT_MESSAGING_SUBDIR) $(SFL_VIDEO_SUBDIR)
sflphoned_SOURCES = main.cpp
sflphoned_CXXFLAGS = \ sflphoned_CXXFLAGS = \
-DPREFIX=\"$(prefix)\" -DPROGSHAREDIR=\"${datadir}/sflphone\" $(IAX_CXXFLAG) $(NETWORKMANAGER) \ -DPREFIX=\"$(prefix)\" -DPROGSHAREDIR=\"${datadir}/sflphone\" $(IAX_CXXFLAG) $(NETWORKMANAGER) \
-DVERSION=\"$(VERSION)\" -DVERSION=\"$(VERSION)\"
...@@ -54,22 +56,18 @@ noinst_HEADERS = \ ...@@ -54,22 +56,18 @@ noinst_HEADERS = \
cc_thread.h \ cc_thread.h \
cc_config.h \ cc_config.h \
sfl_types.h \ sfl_types.h \
array_size.h array_size.h \
account_schema.h \
if SFL_VIDEO registration_states.h
SFL_VIDEO_LIB=./video/libvideo.la
endif
libsflphone_la_LIBADD = \ libsflphone_la_LIBADD = \
$(top_builddir)/libs/iax2/libiax2.la \
$(IAX_LIB) \ $(IAX_LIB) \
./im/libim.la \
./sip/libsiplink.la \ ./sip/libsiplink.la \
./audio/libaudio.la \ ./audio/libaudio.la \
./dbus/libdbus.la \ ./dbus/libdbus.la \
./config/libconfig.la \ ./config/libconfig.la \
./hooks/libhooks.la \ ./hooks/libhooks.la \
./history/libhistory.la $(SFL_VIDEO_LIB) ./history/libhistory.la $(SFL_VIDEO_LIB) $(IM_LIB)
libsflphone_la_LDFLAGS = \ libsflphone_la_LDFLAGS = \
@CCGNU2_LIBS@ \ @CCGNU2_LIBS@ \
......
...@@ -29,26 +29,54 @@ ...@@ -29,26 +29,54 @@
* shall include the source code for the parts of OpenSSL used as well * shall include the source code for the parts of OpenSSL used as well
* as that of the covered work. * as that of the covered work.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "account.h" #include "account.h"
#include "manager.h" #include <algorithm>
#include "dbus/configurationmanager.h"
#ifdef SFL_VIDEO #ifdef SFL_VIDEO
#include "video/video_endpoint.h" #include "video/libav_utils.h"
#endif #endif
Account::Account(const std::string &accountID, const std::string &type) : #include "logger.h"
#include "manager.h"
#include "dbus/configurationmanager.h"
const char * const Account::AUDIO_CODECS_KEY = "audioCodecs"; // 0/9/110/111/112/
const char * const Account::VIDEO_CODECS_KEY = "videoCodecs";
const char * const Account::VIDEO_CODEC_ENABLED = "enabled";
const char * const Account::VIDEO_CODEC_NAME = "name";
const char * const Account::VIDEO_CODEC_PARAMETERS ="parameters";
const char * const Account::VIDEO_CODEC_BITRATE = "bitrate";
const char * const Account::RINGTONE_PATH_KEY = "ringtonePath";
const char * const Account::RINGTONE_ENABLED_KEY = "ringtoneEnabled";
const char * const Account::DISPLAY_NAME_KEY = "displayName";
const char * const Account::ALIAS_KEY = "alias";
const char * const Account::TYPE_KEY = "type";
const char * const Account::ID_KEY = "id";
const char * const Account::USERNAME_KEY = "username";
const char * const Account::AUTHENTICATION_USERNAME_KEY = "authenticationUsername";
const char * const Account::PASSWORD_KEY = "password";
const char * const Account::HOSTNAME_KEY = "hostname";
const char * const Account::ACCOUNT_ENABLE_KEY = "enable";
const char * const Account::MAILBOX_KEY = "mailbox";
using std::map;
using std::string;
using std::vector;
Account::Account(const string &accountID, const string &type) :
accountID_(accountID) accountID_(accountID)
, username_() , username_()
, hostname_() , hostname_()
, alias_() , alias_()
, enabled_(true) , enabled_(true)
, type_(type) , type_(type)
, registrationState_(Unregistered) , registrationState_(UNREGISTERED)
, audioCodecList_() , audioCodecList_()
, videoCodecList_() , videoCodecList_()
, audioCodecStr_() , audioCodecStr_()
, videoCodecStr_()
, ringtonePath_("/usr/share/sflphone/ringtones/konga.ul") , ringtonePath_("/usr/share/sflphone/ringtones/konga.ul")
, ringtoneEnabled_(true) , ringtoneEnabled_(true)
, displayName_("") , displayName_("")
...@@ -79,7 +107,7 @@ void Account::loadDefaultCodecs() ...@@ -79,7 +107,7 @@ void Account::loadDefaultCodecs()
// CodecMap codecMap = Manager::instance ().getCodecDescriptorMap ().getCodecsMap(); // CodecMap codecMap = Manager::instance ().getCodecDescriptorMap ().getCodecsMap();
// Initialize codec // Initialize codec
std::vector<std::string> result; vector<string> result;
result.push_back("0"); result.push_back("0");
result.push_back("3"); result.push_back("3");
result.push_back("8"); result.push_back("8");
...@@ -90,31 +118,90 @@ void Account::loadDefaultCodecs() ...@@ -90,31 +118,90 @@ void Account::loadDefaultCodecs()
setActiveAudioCodecs(result); setActiveAudioCodecs(result);
#ifdef SFL_VIDEO #ifdef SFL_VIDEO
setActiveVideoCodecs(sfl_video::getCodecList()); // we don't need to validate via setVideoCodecs, since these are defaults
videoCodecList_ = libav_utils::getDefaultCodecs();
#endif #endif
} }
void Account::setActiveVideoCodecs(const std::vector<std::string> &list) #ifdef SFL_VIDEO
namespace {
bool isPositiveInteger(const string &s)
{
string::const_iterator it = s.begin();
while (it != s.end() and std::isdigit(*it))
++it;
return not s.empty() and it == s.end();
}
bool isBoolean(const string &s)
{
return s == "true" or s == "false";
}
template <typename Predicate>
bool isFieldValid(const map<string, string> &codec, const char *field, Predicate p)
{
map<string, string>::const_iterator key(codec.find(field));
return key != codec.end() and p(key->second);
}
bool isCodecValid(const map<string, string> &codec, const vector<map<string, string> > &defaults)
{
const map<string, string>::const_iterator name(codec.find(Account::VIDEO_CODEC_NAME));
if (name == codec.end()) {
ERROR("Field \"name\" missing in codec specification");
return false;
}
// check that it's in the list of valid codecs and that it has all the required fields
for (vector<map<string, string> >::const_iterator i = defaults.begin(); i != defaults.end(); ++i) {
const map<string, string>::const_iterator defaultName = i->find(Account::VIDEO_CODEC_NAME);
if (defaultName->second == name->second) {
return isFieldValid(codec, Account::VIDEO_CODEC_BITRATE, isPositiveInteger)
and isFieldValid(codec, Account::VIDEO_CODEC_ENABLED, isBoolean);
}
}
ERROR("Codec %s not supported", name->second.c_str());
return false;
}
bool isCodecListValid(const vector<map<string, string> > &list)
{
const vector<map<string, string> > defaults(libav_utils::getDefaultCodecs());
if (list.size() != defaults.size()) {
ERROR("New codec list has a different length than the list of supported codecs");
return false;
}
// make sure that all codecs are present
for (vector<map<string, string> >::const_iterator i = list.begin();
i != list.end(); ++i) {
if (not isCodecValid(*i, defaults))
return false;
}
return true;
}
}
#endif
void Account::setVideoCodecs(const vector<map<string, string> > &list)
{ {
#ifdef SFL_VIDEO #ifdef SFL_VIDEO
// first clear the previously stored codecs if (isCodecListValid(list))
videoCodecList_.clear(); videoCodecList_ = list;
videoCodecList_ = !list.empty() ? list : sfl_video::getCodecList();
// update the codec string according to new codec selection
videoCodecStr_ = ManagerImpl::join_string(list);
#else #else
(void) list; (void) list;
#endif #endif
} }
void Account::setActiveAudioCodecs(const std::vector<std::string> &list) void Account::setActiveAudioCodecs(const vector<string> &list)
{ {
// first clear the previously stored codecs // first clear the previously stored codecs
audioCodecList_.clear(); audioCodecList_.clear();
// list contains the ordered payload of active codecs picked by the user for this account // list contains the ordered payload of active codecs picked by the user for this account
// we used the CodecOrder vector to save the order. // we used the CodecOrder vector to save the order.
for (std::vector<std::string>::const_iterator iter = list.begin(); iter != list.end(); for (vector<string>::const_iterator iter = list.begin(); iter != list.end();
++iter) { ++iter) {
int payload = std::atoi(iter->c_str()); int payload = std::atoi(iter->c_str());
audioCodecList_.push_back(payload); audioCodecList_.push_back(payload);
...@@ -124,7 +211,7 @@ void Account::setActiveAudioCodecs(const std::vector<std::string> &list) ...@@ -124,7 +211,7 @@ void Account::setActiveAudioCodecs(const std::vector<std::string> &list)
audioCodecStr_ = ManagerImpl::join_string(list); audioCodecStr_ = ManagerImpl::join_string(list);
} }
std::string Account::mapStateNumberToString(RegistrationState state) string Account::mapStateNumberToString(RegistrationState state)
{ {
static const char * mapStateToChar[] = { static const char * mapStateToChar[] = {
"UNREGISTERED", "UNREGISTERED",
...@@ -138,8 +225,31 @@ std::string Account::mapStateNumberToString(RegistrationState state) ...@@ -138,8 +225,31 @@ std::string Account::mapStateNumberToString(RegistrationState state)
"ERRORCONFSTUN" "ERRORCONFSTUN"
}; };
if (state > NumberOfStates) if (state > NUMBER_OF_STATES)
return "ERROR"; return "ERROR";
return mapStateToChar[state]; return mapStateToChar[state];
} }
vector<map<string, string> >
Account::getAllVideoCodecs() const
{
return videoCodecList_;
}
namespace {
bool is_inactive(const map<string, string> &codec)
{
map<string, string>::const_iterator iter = codec.find(Account::VIDEO_CODEC_ENABLED);
return iter == codec.end() or iter->second != "true";
}
}
vector<map<string, string> >
Account::getActiveVideoCodecs() const
{
// FIXME: validate video codec details first
vector<map<string, string> > result(videoCodecList_);
result.erase(std::remove_if(result.begin(), result.end(), is_inactive), result.end());
return result;
}
...@@ -35,10 +35,10 @@ ...@@ -35,10 +35,10 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "global.h"
#include "noncopyable.h" #include "noncopyable.h"
#include "config/sfl_config.h" #include "config/sfl_config.h"
#include "config/serializable.h" #include "config/serializable.h"
#include "registration_states.h"
class VoIPLink; class VoIPLink;
...@@ -49,102 +49,6 @@ class VoIPLink; ...@@ -49,102 +49,6 @@ class VoIPLink;
* It contains account, configuration, VoIP Link and Calls (inside the VoIPLink) * It contains account, configuration, VoIP Link and Calls (inside the VoIPLink)
*/ */
/** Contains all the state an Voip can be in */
enum RegistrationState {
Unregistered,
Trying,
Registered,
Error,
ErrorAuth ,
ErrorNetwork ,
ErrorHost,
ErrorExistStun,
ErrorNotAcceptable,
NumberOfStates
};
// Account identifier
static const char *const CONFIG_ACCOUNT_ID = "Account.id";
// Common account parameters
static const char *const CONFIG_ACCOUNT_TYPE = "Account.type";
static const char *const CONFIG_ACCOUNT_ALIAS = "Account.alias";
static const char *const CONFIG_ACCOUNT_MAILBOX = "Account.mailbox";
static const char *const CONFIG_ACCOUNT_ENABLE = "Account.enable";
static const char *const CONFIG_ACCOUNT_REGISTRATION_EXPIRE = "Account.registrationExpire";
static const char *const CONFIG_ACCOUNT_REGISTRATION_STATUS = "Account.registrationStatus";
static const char *const CONFIG_ACCOUNT_REGISTRATION_STATE_CODE = "Account.registrationCode";
static const char *const CONFIG_ACCOUNT_REGISTRATION_STATE_DESC = "Account.registrationDescription";
static const char *const CONFIG_CREDENTIAL_NUMBER = "Credential.count";
static const char *const CONFIG_ACCOUNT_DTMF_TYPE = "Account.dtmfType";
static const char *const CONFIG_RINGTONE_PATH = "Account.ringtonePath";
static const char *const CONFIG_RINGTONE_ENABLED = "Account.ringtoneEnabled";
static const char *const CONFIG_KEEP_ALIVE_ENABLED = "Account.keepAliveEnabled";
static const char *const CONFIG_ACCOUNT_HOSTNAME = "Account.hostname";
static const char *const CONFIG_ACCOUNT_USERNAME = "Account.username";
static const char *const CONFIG_ACCOUNT_ROUTESET = "Account.routeset";
static const char *const CONFIG_ACCOUNT_PASSWORD = "Account.password";
static const char *const CONFIG_ACCOUNT_REALM = "Account.realm";
static const char *const CONFIG_ACCOUNT_DEFAULT_REALM = "*";
static const char *const CONFIG_ACCOUNT_USERAGENT = "Account.useragent";
static const char *const CONFIG_LOCAL_INTERFACE = "Account.localInterface";
static const char *const CONFIG_PUBLISHED_SAMEAS_LOCAL = "Account.publishedSameAsLocal";
static const char *const CONFIG_LOCAL_PORT = "Account.localPort";
static const char *const CONFIG_PUBLISHED_PORT = "Account.publishedPort";
static const char *const CONFIG_PUBLISHED_ADDRESS = "Account.publishedAddress";
static const char *const CONFIG_DISPLAY_NAME = "Account.displayName";
static const char *const CONFIG_DEFAULT_ADDRESS = "0.0.0.0";
// SIP specific parameters
static const char *const CONFIG_SIP_PROXY = "SIP.proxy";
static const char *const CONFIG_STUN_SERVER = "STUN.server";
static const char *const CONFIG_STUN_ENABLE = "STUN.enable";
// SRTP specific parameters
static const char *const CONFIG_SRTP_ENABLE = "SRTP.enable";
static const char *const CONFIG_SRTP_KEY_EXCHANGE = "SRTP.keyExchange";
static const char *const CONFIG_SRTP_ENCRYPTION_ALGO = "SRTP.encryptionAlgorithm"; // Provided by ccRTP,0=NULL,1=AESCM,2=AESF8
static const char *const CONFIG_SRTP_RTP_FALLBACK = "SRTP.rtpFallback";
static const char *const CONFIG_ZRTP_HELLO_HASH = "ZRTP.helloHashEnable";
static const char *const CONFIG_ZRTP_DISPLAY_SAS = "ZRTP.displaySAS";
static const char *const CONFIG_ZRTP_NOT_SUPP_WARNING = "ZRTP.notSuppWarning";
static const char *const CONFIG_ZRTP_DISPLAY_SAS_ONCE = "ZRTP.displaySasOnce";
static const char *const CONFIG_TLS_LISTENER_PORT = "TLS.listenerPort";
static const char *const CONFIG_TLS_ENABLE = "TLS.enable";
static const char *const CONFIG_TLS_CA_LIST_FILE = "TLS.certificateListFile";
static const char *const CONFIG_TLS_CERTIFICATE_FILE = "TLS.certificateFile";
static const char *const CONFIG_TLS_PRIVATE_KEY_FILE = "TLS.privateKeyFile";
static const char *const CONFIG_TLS_PASSWORD = "TLS.password";
static const char *const CONFIG_TLS_METHOD = "TLS.method";
static const char *const CONFIG_TLS_CIPHERS = "TLS.ciphers";
static const char *const CONFIG_TLS_SERVER_NAME = "TLS.serverName";
static const char *const CONFIG_TLS_VERIFY_SERVER = "TLS.verifyServer";
static const char *const CONFIG_TLS_VERIFY_CLIENT = "TLS.verifyClient";
static const char *const CONFIG_TLS_REQUIRE_CLIENT_CERTIFICATE = "TLS.requireClientCertificate";
static const char *const CONFIG_TLS_NEGOTIATION_TIMEOUT_SEC = "TLS.negotiationTimeoutSec";
static const char *const CONFIG_TLS_NEGOTIATION_TIMEOUT_MSEC = "TLS.negotiationTimemoutMsec";
// General configuration keys for accounts
static const char * const ALIAS_KEY = "alias";
static const char * const TYPE_KEY = "type";
static const char * const ID_KEY = "id";
static const char * const USERNAME_KEY = "username";
static const char * const AUTHENTICATION_USERNAME_KEY = "authenticationUsername";
static const char * const PASSWORD_KEY = "password";
static const char * const HOSTNAME_KEY = "hostname";
static const char * const ACCOUNT_ENABLE_KEY = "enable";
static const char * const MAILBOX_KEY = "mailbox";
static const char * const AUDIO_CODECS_KEY = "audioCodecs"; // 0/9/110/111/112/
static const char * const VIDEO_CODECS_KEY = "videoCodecs";
static const char * const RINGTONE_PATH_KEY = "ringtonePath";
static const char * const RINGTONE_ENABLED_KEY = "ringtoneEnabled";
static const char * const DISPLAY_NAME_KEY = "displayName";
class Account : public Serializable { class Account : public Serializable {
public: public:
...@@ -225,17 +129,16 @@ class Account : public Serializable { ...@@ -225,17 +129,16 @@ class Account : public Serializable {
std::string getAlias() const { std::string getAlias() const {
return alias_; return alias_;
} }
void setAlias(const std::string &alias) { void setAlias(const std::string &alias) {
alias_ = alias; alias_ = alias;
} }
/** std::vector<std::map<std::string, std::string> >
* Accessor to data structures getAllVideoCodecs() const;
* @return std::vector<std::string>& The list that reflects the user's choice
*/ std::vector<std::map<std::string, std::string> >
std::vector<std::string> getActiveVideoCodecs() const { getActiveVideoCodecs() const;
return videoCodecList_;
}
/* Accessor to data structures /* Accessor to data structures
* @return CodecOrder& The list that reflects the user's choice * @return CodecOrder& The list that reflects the user's choice
...@@ -249,7 +152,7 @@ class Account : public Serializable { ...@@ -249,7 +152,7 @@ class Account : public Serializable {
* SDP offer and configuration respectively * SDP offer and configuration respectively
*/ */
void setActiveAudioCodecs(const std::vector<std::string>& list); void setActiveAudioCodecs(const std::vector<std::string>& list);
void setActiveVideoCodecs(const std::vector<std::string>& list); void setVideoCodecs(const std::vector<std::map<std::string, std::string> > &codecs);
std::string getRingtonePath() const { std::string getRingtonePath() const {
return ringtonePath_; return ringtonePath_;
...@@ -280,6 +183,10 @@ class Account : public Serializable { ...@@ -280,6 +183,10 @@ class Account : public Serializable {
mailBox_ = mb; mailBox_ = mb;
} }
static const char * const VIDEO_CODEC_ENABLED;
static const char * const VIDEO_CODEC_NAME;
static const char * const VIDEO_CODEC_PARAMETERS;
static const char * const VIDEO_CODEC_BITRATE;
private: private:
NON_COPYABLE(Account); NON_COPYABLE(Account);
...@@ -289,6 +196,23 @@ class Account : public Serializable { ...@@ -289,6 +196,23 @@ class Account : public Serializable {
void loadDefaultCodecs(); void loadDefaultCodecs();
protected: protected:
friend class ConfigurationTest;
// General configuration keys for accounts
static const char * const AUDIO_CODECS_KEY;
static const char * const VIDEO_CODECS_KEY;
static const char * const RINGTONE_PATH_KEY;
static const char * const RINGTONE_ENABLED_KEY;
static const char * const DISPLAY_NAME_KEY;
static const char * const ALIAS_KEY;
static const char * const TYPE_KEY;
static const char * const ID_KEY;
static const char * const USERNAME_KEY;
static const char * const AUTHENTICATION_USERNAME_KEY;
static const char * const PASSWORD_KEY;
static const char * const HOSTNAME_KEY;
static const char * const ACCOUNT_ENABLE_KEY;
static const char * const MAILBOX_KEY;
static std::string mapStateNumberToString(RegistrationState state); static std::string mapStateNumberToString(RegistrationState state);
/** /**
...@@ -336,9 +260,9 @@ class Account : public Serializable { ...@@ -336,9 +260,9 @@ class Account : public Serializable {
std::vector<int> audioCodecList_; std::vector<int> audioCodecList_;
/** /**
* Vector containing the order of the video codecs * Vector containing the video codecs in order
*/ */
std::vector<std::string> videoCodecList_; std::vector<std::map<std::string, std::string> > videoCodecList_;
/** /**
* List of audio codecs obtained when parsing configuration and used * List of audio codecs obtained when parsing configuration and used
...@@ -346,12 +270,6 @@ class Account : public Serializable { ...@@ -346,12 +270,6 @@ class Account : public Serializable {
*/ */
std::string audioCodecStr_; std::string audioCodecStr_;
/**
* List of video codecs obtained when parsing configuration and used
* to generate codec order list
*/
std::string videoCodecStr_;
/** /**
* Ringtone .au file used for this account * Ringtone .au file used for this account
*/ */
......
/*
* Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010, 2011 Savoir-Faire Linux Inc.
* Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
* Author: Yan Morin <yan.morin@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Additional permission under GNU GPL version 3 section 7:
*
* If you modify this program, or any covered work, by linking or
* combining it with the OpenSSL project's OpenSSL library (or a
* modified version of that library), containing parts covered by the
* terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
* grants you additional permission to convey the resulting work.
* Corresponding Source for a non-source form of such a combination
* shall include the source code for the parts of OpenSSL used as well
* as that of the covered work.
*/
#ifndef ACCOUNT_SCHEMA_H
#define ACCOUNT_SCHEMA_H_
/**
* @file account_schema.h
* @brief Account specfic keys/constants that must be shared in daemon and clients.
*/
// Account identifier
static const char *const CONFIG_ACCOUNT_ID = "Account.id";
// Common account parameters
static const char *const CONFIG_ACCOUNT_TYPE = "Account.type";
static const char *const CONFIG_ACCOUNT_ALIAS = "Account.alias";
static const char *const CONFIG_ACCOUNT_MAILBOX = "Account.mailbox";
static const char *const CONFIG_ACCOUNT_ENABLE = "Account.enable";
static const char *const CONFIG_ACCOUNT_REGISTRATION_EXPIRE = "Account.registrationExpire";
static const char *const CONFIG_ACCOUNT_REGISTRATION_STATUS = "Account.registrationStatus";
static const char *const CONFIG_ACCOUNT_REGISTRATION_STATE_CODE = "Account.registrationCode";
static const char *const CONFIG_ACCOUNT_REGISTRATION_STATE_DESC = "Account.registrationDescription";
static const char *const CONFIG_CREDENTIAL_NUMBER = "Credential.count";
static const char *const CONFIG_ACCOUNT_DTMF_TYPE = "Account.dtmfType";
static const char *const CONFIG_RINGTONE_PATH = "Account.ringtonePath";
static const char *const CONFIG_RINGTONE_ENABLED = "Account.ringtoneEnabled";
static const char *const CONFIG_KEEP_ALIVE_ENABLED = "Account.keepAliveEnabled";
static const char *const CONFIG_ACCOUNT_HOSTNAME = "Account.hostname";
static const char *const CONFIG_ACCOUNT_USERNAME = "Account.username";
static const char *const CONFIG_ACCOUNT_ROUTESET = "Account.routeset";
static const char *const CONFIG_ACCOUNT_PASSWORD = "Account.password";
static const char *const CONFIG_ACCOUNT_REALM = "Account.realm";
static const char *const CONFIG_ACCOUNT_DEFAULT_REALM = "*";
static const char *const CONFIG_ACCOUNT_USERAGENT = "Account.useragent";
static const char *const CONFIG_LOCAL_INTERFACE = "Account.localInterface";
static const char *const CONFIG_PUBLISHED_SAMEAS_LOCAL = "Account.publishedSameAsLocal";
static const char *const CONFIG_LOCAL_PORT = "Account.localPort";
static const char *const CONFIG_PUBLISHED_PORT = "Account.publishedPort";
static const char *const CONFIG_PUBLISHED_ADDRESS = "Account.publishedAddress";
static const char *const CONFIG_DISPLAY_NAME = "Account.displayName";
static const char *const CONFIG_DEFAULT_ADDRESS = "0.0.0.0";
// SIP specific parameters
static const char *const CONFIG_SIP_PROXY = "SIP.proxy";
static const char *const CONFIG_STUN_SERVER = "STUN.server";
static const char *const CONFIG_STUN_ENABLE = "STUN.enable";
// SRTP specific parameters
static const char *const CONFIG_SRTP_ENABLE = "SRTP.enable";
static const char *const CONFIG_SRTP_KEY_EXCHANGE = "SRTP.keyExchange";
static const char *const CONFIG_SRTP_ENCRYPTION_ALGO = "SRTP.encryptionAlgorithm"; // Provided by ccRTP,0=NULL,1=AESCM,2=AESF8
static const char *const CONFIG_SRTP_RTP_FALLBACK = "SRTP.rtpFallback";
static const char *const CONFIG_ZRTP_HELLO_HASH = "ZRTP.helloHashEnable";
static const char *const CONFIG_ZRTP_DISPLAY_SAS = "ZRTP.displaySAS";
static const char *const CONFIG_ZRTP_NOT_SUPP_WARNING = "ZRTP.notSuppWarning";
static const char *const CONFIG_ZRTP_DISPLAY_SAS_ONCE = "ZRTP.displaySasOnce";
static const char *const CONFIG_TLS_LISTENER_PORT = "TLS.listenerPort";
static const char *const CONFIG_TLS_ENABLE = "TLS.enable";
static const char *const CONFIG_TLS_CA_LIST_FILE = "TLS.certificateListFile";
static const char *const CONFIG_TLS_CERTIFICATE_FILE = "TLS.certificateFile";
static const char *const CONFIG_TLS_PRIVATE_KEY_FILE = "TLS.privateKeyFile";
static const char *const CONFIG_TLS_PASSWORD = "TLS.password";
static const char *const CONFIG_TLS_METHOD = "TLS.method";
static const char *const CONFIG_TLS_CIPHERS = "TLS.ciphers";
static const char *const CONFIG_TLS_SERVER_NAME = "TLS.serverName";
static const char *const CONFIG_TLS_VERIFY_SERVER = "TLS.verifyServer";
static const char *const CONFIG_TLS_VERIFY_CLIENT = "TLS.verifyClient";
static const char *const CONFIG_TLS_REQUIRE_CLIENT_CERTIFICATE = "TLS.requireClientCertificate";
static const char *const CONFIG_TLS_NEGOTIATION_TIMEOUT_SEC = "TLS.negotiationTimeoutSec";
static const char *const CONFIG_TLS_NEGOTIATION_TIMEOUT_MSEC = "TLS.negotiationTimemoutMsec";
#endif
...@@ -8,6 +8,11 @@ if BUILD_PULSE ...@@ -8,6 +8,11 @@ if BUILD_PULSE
SUBDIRS += pulseaudio SUBDIRS += pulseaudio
endif endif
if BUILD_SPEEXDSP
SFL_SPEEXDSP_SRC=echosuppress.cpp speexechocancel.cpp noisesuppress.cpp
SFL_SPEEXDSP_HEAD=echosuppress.h speexechocancel.h noisesuppress.h
endif
libaudio_la_SOURCES = \ libaudio_la_SOURCES = \
audioloop.cpp \ audioloop.cpp \
ringbuffer.cpp \ ringbuffer.cpp \
...@@ -18,9 +23,7 @@ libaudio_la_SOURCES = \ ...@@ -18,9 +23,7 @@ libaudio_la_SOURCES = \
audiolayer.cpp \ audiolayer.cpp \
samplerateconverter.cpp \ samplerateconverter.cpp \
delaydetection.cpp \ delaydetection.cpp \
echosuppress.cpp \ $(SFL_SPEEXDSP_SRC) \
speexechocancel.cpp \
noisesuppress.cpp \
gaincontrol.cpp \ gaincontrol.cpp \
dcblocker.cpp dcblocker.cpp
...@@ -33,9 +36,7 @@ noinst_HEADERS = \ ...@@ -33,9 +36,7 @@ noinst_HEADERS = \
audiolayer.h \ audiolayer.h \
recordable.h \ recordable.h \
delaydetection.h \ delaydetection.h \
echosuppress.h \ $(SFL_SPEEXDSP_HEAD) \
speexechocancel.h \
noisesuppress.h \
gaincontrol.h \ gaincontrol.h \
dcblocker.h \ dcblocker.h \
samplerateconverter.h samplerateconverter.h
......
...@@ -40,12 +40,18 @@ ...@@ -40,12 +40,18 @@
#include "dbus/configurationmanager.h" #include "dbus/configurationmanager.h"
#include <ctime> #include <ctime>
#define SFL_ALSA_PERIOD_SIZE 160
#define SFL_ALSA_NB_PERIOD 8
#define SFL_ALSA_BUFFER_SIZE SFL_ALSA_PERIOD_SIZE*SFL_ALSA_NB_PERIOD
class AlsaThread : public ost::Thread { class AlsaThread : public ost::Thread {
public: public:
AlsaThread(AlsaLayer *alsa); AlsaThread(AlsaLayer *alsa);
~AlsaThread() { ost::Thread::terminate(); } ~AlsaThread() { ost::Thread::terminate(); }
void initAudioLayer();
virtual void run(); virtual void run();
private: private:
...@@ -57,11 +63,57 @@ AlsaThread::AlsaThread(AlsaLayer *alsa) ...@@ -57,11 +63,57 @@ AlsaThread::AlsaThread(AlsaLayer *alsa)
: ost::Thread(), alsa_(alsa) : ost::Thread(), alsa_(alsa)
{} {}
void AlsaThread::initAudioLayer(void)
{
std::string pcmp;
std::string pcmr;
std::string pcmc;
if (alsa_->audioPlugin_ == PCM_DMIX_DSNOOP) {
pcmp = alsa_->buildDeviceTopo(PCM_DMIX, alsa_->indexOut_);
pcmr = alsa_->buildDeviceTopo(PCM_DMIX, alsa_->indexRing_);
pcmc = alsa_->buildDeviceTopo(PCM_DSNOOP, alsa_->indexIn_);
} else {
pcmp = alsa_->buildDeviceTopo(alsa_->audioPlugin_, alsa_->indexOut_);
pcmr = alsa_->buildDeviceTopo(alsa_->audioPlugin_, alsa_->indexRing_);
pcmc = alsa_->buildDeviceTopo(alsa_->audioPlugin_, alsa_->indexIn_);
}
if (not alsa_->is_capture_open_) {
alsa_->is_capture_open_ = alsa_->openDevice(&alsa_->captureHandle_, pcmc, SND_PCM_STREAM_CAPTURE);
if (not alsa_->is_capture_open_)
Manager::instance().getDbusManager()->getConfigurationManager()->errorAlert(ALSA_CAPTURE_DEVICE);
}
if (not alsa_->is_playback_open_) {
alsa_->is_playback_open_ = alsa_->openDevice(&alsa_->playbackHandle_, pcmp, SND_PCM_STREAM_PLAYBACK);
if (not alsa_->is_playback_open_)
Manager::instance().getDbusManager()->getConfigurationManager()->errorAlert(ALSA_PLAYBACK_DEVICE);
if (alsa_->getIndexPlayback() != alsa_->getIndexRingtone())
if (!alsa_->openDevice(&alsa_->ringtoneHandle_, pcmr, SND_PCM_STREAM_PLAYBACK))
Manager::instance().getDbusManager()->getConfigurationManager()->errorAlert(ALSA_PLAYBACK_DEVICE);
}
alsa_->prepareCaptureStream();
alsa_->preparePlaybackStream();
alsa_->startCaptureStream();
alsa_->startPlaybackStream();
alsa_->flushMain();
alsa_->flushUrgent();
}
/** /**
* Reimplementation of run() * Reimplementation of run()
*/ */
void AlsaThread::run() void AlsaThread::run()
{ {
initAudioLayer();
while (alsa_->isStarted_) { while (alsa_->isStarted_) {
alsa_->audioCallback(); alsa_->audioCallback();
ost::Thread::sleep(20 /* ms */); ost::Thread::sleep(20 /* ms */);
...@@ -135,47 +187,6 @@ AlsaLayer::startStream() ...@@ -135,47 +187,6 @@ AlsaLayer::startStream()
if (is_playback_running_ and is_capture_running_) if (is_playback_running_ and is_capture_running_)
return; return;
std::string pcmp;
std::string pcmr;
std::string pcmc;
if (audioPlugin_ == PCM_DMIX_DSNOOP) {
pcmp = buildDeviceTopo(PCM_DMIX, indexOut_);
pcmr = buildDeviceTopo(PCM_DMIX, indexRing_);
pcmc = buildDeviceTopo(PCM_DSNOOP, indexIn_);
} else {
pcmp = buildDeviceTopo(audioPlugin_, indexOut_);
pcmr = buildDeviceTopo(audioPlugin_, indexRing_);
pcmc = buildDeviceTopo(audioPlugin_, indexIn_);
}
if (not is_capture_open_) {
is_capture_open_ = openDevice(&captureHandle_, pcmc, SND_PCM_STREAM_CAPTURE);
if (not is_capture_open_)
Manager::instance().getDbusManager()->getConfigurationManager()->errorAlert(ALSA_CAPTURE_DEVICE);
}
if (not is_playback_open_) {
is_playback_open_ = openDevice(&playbackHandle_, pcmp, SND_PCM_STREAM_PLAYBACK);
if (not is_playback_open_)
Manager::instance().getDbusManager()->getConfigurationManager()->errorAlert(ALSA_PLAYBACK_DEVICE);
if (getIndexPlayback() != getIndexRingtone())
if (!openDevice(&ringtoneHandle_, pcmr, SND_PCM_STREAM_PLAYBACK))
Manager::instance().getDbusManager()->getConfigurationManager()->errorAlert(ALSA_PLAYBACK_DEVICE);
}
prepareCaptureStream();
preparePlaybackStream();
startCaptureStream();
startPlaybackStream();
flushMain();
flushUrgent();
if (audioThread_ == NULL) { if (audioThread_ == NULL) {
audioThread_ = new AlsaThread(this); audioThread_ = new AlsaThread(this);
audioThread_->start(); audioThread_->start();
...@@ -278,8 +289,6 @@ void AlsaLayer::closePlaybackStream() ...@@ -278,8 +289,6 @@ void AlsaLayer::closePlaybackStream()
void AlsaLayer::startPlaybackStream() void AlsaLayer::startPlaybackStream()
{ {
if (playbackHandle_ and not is_playback_running_)
if (ALSA_CALL(snd_pcm_start(playbackHandle_), "Couldn't start playback") >= 0)
is_playback_running_ = true; is_playback_running_ = true;
} }
...@@ -292,8 +301,6 @@ void AlsaLayer::prepareCaptureStream() ...@@ -292,8 +301,6 @@ void AlsaLayer::prepareCaptureStream()
void AlsaLayer::preparePlaybackStream() void AlsaLayer::preparePlaybackStream()
{ {
if (is_playback_open_ and not is_playback_prepared_)
if (ALSA_CALL(snd_pcm_prepare(playbackHandle_), "Couldn't prepare playback") >= 0)
is_playback_prepared_ = true; is_playback_prepared_ = true;
} }
...@@ -307,8 +314,14 @@ bool AlsaLayer::alsa_set_params(snd_pcm_t *pcm_handle) ...@@ -307,8 +314,14 @@ bool AlsaLayer::alsa_set_params(snd_pcm_t *pcm_handle)
snd_pcm_hw_params_t *hwparams; snd_pcm_hw_params_t *hwparams;
snd_pcm_hw_params_alloca(&hwparams); snd_pcm_hw_params_alloca(&hwparams);
snd_pcm_uframes_t periodSize = 160; snd_pcm_uframes_t period_size = SFL_ALSA_PERIOD_SIZE;
unsigned int periods = 4; snd_pcm_uframes_t buffer_size = SFL_ALSA_BUFFER_SIZE;
unsigned int periods = SFL_ALSA_NB_PERIOD;
snd_pcm_uframes_t period_size_min = 0;
snd_pcm_uframes_t period_size_max = 0;
snd_pcm_uframes_t buffer_size_min = 0;
snd_pcm_uframes_t buffer_size_max = 0;
#define HW pcm_handle, hwparams /* hardware parameters */ #define HW pcm_handle, hwparams /* hardware parameters */
TRY(snd_pcm_hw_params_any(HW), "hwparams init"); TRY(snd_pcm_hw_params_any(HW), "hwparams init");
...@@ -316,9 +329,32 @@ bool AlsaLayer::alsa_set_params(snd_pcm_t *pcm_handle) ...@@ -316,9 +329,32 @@ bool AlsaLayer::alsa_set_params(snd_pcm_t *pcm_handle)
TRY(snd_pcm_hw_params_set_format(HW, SND_PCM_FORMAT_S16_LE), "sample format"); TRY(snd_pcm_hw_params_set_format(HW, SND_PCM_FORMAT_S16_LE), "sample format");
TRY(snd_pcm_hw_params_set_rate_near(HW, &sampleRate_, NULL), "sample rate"); TRY(snd_pcm_hw_params_set_rate_near(HW, &sampleRate_, NULL), "sample rate");
TRY(snd_pcm_hw_params_set_channels(HW, 1), "channel count"); TRY(snd_pcm_hw_params_set_channels(HW, 1), "channel count");
TRY(snd_pcm_hw_params_set_period_size_near(HW, &periodSize, NULL), "period time");
TRY(snd_pcm_hw_params_set_periods_near(HW, &periods, NULL), "periods number"); snd_pcm_hw_params_get_buffer_size_min(hwparams, &buffer_size_min);
snd_pcm_hw_params_get_buffer_size_max(hwparams, &buffer_size_max);
snd_pcm_hw_params_get_period_size_min(hwparams, &period_size_min, NULL);
snd_pcm_hw_params_get_period_size_max(hwparams, &period_size_max, NULL);
DEBUG("Buffer size range from %lu to %lu", buffer_size_min, buffer_size_max);
DEBUG("Period size range from %lu to %lu", period_size_min, period_size_max);
buffer_size = buffer_size > buffer_size_max ? buffer_size_max : buffer_size;
buffer_size = buffer_size < buffer_size_min ? buffer_size_min : buffer_size;
period_size = period_size > period_size_max ? period_size_max : period_size;
period_size = period_size < period_size_min ? period_size_min : period_size;
TRY(snd_pcm_hw_params_set_buffer_size_near(HW, &buffer_size), "Unable to set buffer size for playback");
TRY(snd_pcm_hw_params_set_period_size_near(HW, &period_size, NULL), "Unable to set period size for playback");
TRY(snd_pcm_hw_params_set_periods_near(HW, &periods, NULL), "Unable to set number of periods for playback");
TRY(snd_pcm_hw_params(HW), "hwparams"); TRY(snd_pcm_hw_params(HW), "hwparams");
snd_pcm_hw_params_get_buffer_size(hwparams, &buffer_size);
snd_pcm_hw_params_get_period_size(hwparams, &period_size, NULL);
DEBUG("Was set period_size = %lu", period_size);
DEBUG("Was set buffer_size = %lu", buffer_size);
if (2*period_size > buffer_size) {
ERROR("buffer to small, could not use");
return false;
}
#undef HW #undef HW
DEBUG("%s using sampling rate %dHz", DEBUG("%s using sampling rate %dHz",
...@@ -330,7 +366,7 @@ bool AlsaLayer::alsa_set_params(snd_pcm_t *pcm_handle) ...@@ -330,7 +366,7 @@ bool AlsaLayer::alsa_set_params(snd_pcm_t *pcm_handle)
#define SW pcm_handle, swparams /* software parameters */ #define SW pcm_handle, swparams /* software parameters */
snd_pcm_sw_params_current(SW); snd_pcm_sw_params_current(SW);
TRY(snd_pcm_sw_params_set_start_threshold(SW, periodSize * 2), "start threshold"); TRY(snd_pcm_sw_params_set_start_threshold(SW, period_size * 2), "start threshold");
TRY(snd_pcm_sw_params(SW), "sw parameters"); TRY(snd_pcm_sw_params(SW), "sw parameters");
#undef SW #undef SW
......
...@@ -2,19 +2,19 @@ include $(top_srcdir)/globals.mak ...@@ -2,19 +2,19 @@ include $(top_srcdir)/globals.mak
noinst_LTLIBRARIES = libaudiortp.la noinst_LTLIBRARIES = libaudiortp.la
if BUILD_ZRTP
SFL_ZRTP_SRC=audio_zrtp_session.h audio_zrtp_session.cpp zrtp_session_callback.cpp zrtp_session_callback.h
endif
libaudiortp_la_SOURCES = \ libaudiortp_la_SOURCES = \
$(SFL_ZRTP_SRC) \
audio_rtp_session.cpp \ audio_rtp_session.cpp \
audio_symmetric_rtp_session.cpp \ audio_symmetric_rtp_session.cpp \
audio_rtp_record_handler.cpp \ audio_rtp_record_handler.cpp \
audio_rtp_factory.cpp \ audio_rtp_factory.cpp \
audio_zrtp_session.cpp \
zrtp_session_callback.cpp \
audio_srtp_session.cpp \ audio_srtp_session.cpp \
audio_rtp_session.h \ audio_rtp_session.h \
audio_rtp_record_handler.h \ audio_rtp_record_handler.h \
audio_rtp_factory.h \ audio_rtp_factory.h \
audio_symmetric_rtp_session.h \ audio_symmetric_rtp_session.h \
audio_zrtp_session.h \
zrtp_session_callback.h \
audio_srtp_session.h audio_srtp_session.h
...@@ -29,7 +29,9 @@ ...@@ -29,7 +29,9 @@
*/ */
#include "audio_rtp_factory.h" #include "audio_rtp_factory.h"
#if HAVE_ZRTP
#include "audio_zrtp_session.h" #include "audio_zrtp_session.h"
#endif
#include "audio_symmetric_rtp_session.h" #include "audio_symmetric_rtp_session.h"
#include "manager.h" #include "manager.h"
#include "sip/sdp.h" #include "sip/sdp.h"
...@@ -37,6 +39,7 @@ ...@@ -37,6 +39,7 @@
#include "sip/sipaccount.h" #include "sip/sipaccount.h"
#include "sip/sdes_negotiator.h" #include "sip/sdes_negotiator.h"
#include "logger.h" #include "logger.h"
#include "config.h"
namespace sfl { namespace sfl {
...@@ -69,10 +72,14 @@ void AudioRtpFactory::initConfig() ...@@ -69,10 +72,14 @@ void AudioRtpFactory::initConfig()
srtpEnabled_ = account->getSrtpEnabled(); srtpEnabled_ = account->getSrtpEnabled();
std::string key(account->getSrtpKeyExchange()); std::string key(account->getSrtpKeyExchange());
if (srtpEnabled_) { if (srtpEnabled_) {
#if HAVE_ZRTP
if (key == "sdes") if (key == "sdes")
keyExchangeProtocol_ = SDES; keyExchangeProtocol_ = SDES;
else if (key == "zrtp") else if (key == "zrtp")
keyExchangeProtocol_ = ZRTP; keyExchangeProtocol_ = ZRTP;
#else
keyExchangeProtocol_ = SDES;
#endif
} else { } else {
keyExchangeProtocol_ = NONE; keyExchangeProtocol_ = NONE;
} }
...@@ -86,14 +93,14 @@ void AudioRtpFactory::initConfig() ...@@ -86,14 +93,14 @@ void AudioRtpFactory::initConfig()
void AudioRtpFactory::initSession() void AudioRtpFactory::initSession()
{ {
DEBUG("AudioRtpFactory: init session"); DEBUG("AudioRtpFactory: init session2");
ost::MutexLock m(audioRtpThreadMutex_); ost::MutexLock m(audioRtpThreadMutex_);
if (srtpEnabled_) { if (srtpEnabled_) {
const std::string zidFilename(Manager::instance().voipPreferences.getZidFile()); const std::string zidFilename(Manager::instance().voipPreferences.getZidFile());
switch (keyExchangeProtocol_) { switch (keyExchangeProtocol_) {
#if HAVE_ZRTP
case ZRTP: case ZRTP:
rtpSession_ = new AudioZrtpSession(*ca_, zidFilename); rtpSession_ = new AudioZrtpSession(*ca_, zidFilename);
// TODO: be careful with that. The hello hash is computed asynchronously. Maybe it's // TODO: be careful with that. The hello hash is computed asynchronously. Maybe it's
...@@ -101,7 +108,7 @@ void AudioRtpFactory::initSession() ...@@ -101,7 +108,7 @@ void AudioRtpFactory::initSession()
if (helloHashEnabled_) if (helloHashEnabled_)
ca_->getLocalSDP()->setZrtpHash(static_cast<AudioZrtpSession *>(rtpSession_)->getHelloHash()); ca_->getLocalSDP()->setZrtpHash(static_cast<AudioZrtpSession *>(rtpSession_)->getHelloHash());
break; break;
#endif
case SDES: case SDES:
rtpSession_ = new AudioSrtpSession(*ca_); rtpSession_ = new AudioSrtpSession(*ca_);
break; break;
...@@ -152,6 +159,7 @@ void AudioRtpFactory::updateDestinationIpAddress() ...@@ -152,6 +159,7 @@ void AudioRtpFactory::updateDestinationIpAddress()
rtpSession_->updateDestinationIpAddress(); rtpSession_->updateDestinationIpAddress();
} }
#if HAVE_ZRTP
sfl::AudioZrtpSession * AudioRtpFactory::getAudioZrtpSession() sfl::AudioZrtpSession * AudioRtpFactory::getAudioZrtpSession()
{ {
if (keyExchangeProtocol_ == ZRTP) if (keyExchangeProtocol_ == ZRTP)
...@@ -159,6 +167,7 @@ sfl::AudioZrtpSession * AudioRtpFactory::getAudioZrtpSession() ...@@ -159,6 +167,7 @@ sfl::AudioZrtpSession * AudioRtpFactory::getAudioZrtpSession()
else else
throw AudioRtpFactoryException("rtpSession_ is NULL in getAudioZrtpSession"); throw AudioRtpFactoryException("rtpSession_ is NULL in getAudioZrtpSession");
} }
#endif
void sfl::AudioRtpFactory::initLocalCryptoInfo() void sfl::AudioRtpFactory::initLocalCryptoInfo()
{ {
......
...@@ -46,7 +46,9 @@ class SIPCall; ...@@ -46,7 +46,9 @@ class SIPCall;
namespace sfl { namespace sfl {
#if HAVE_ZRTP
class AudioZrtpSession; class AudioZrtpSession;
#endif
class AudioCodec; class AudioCodec;
class UnsupportedRtpSessionType : public std::logic_error { class UnsupportedRtpSessionType : public std::logic_error {
...@@ -115,12 +117,14 @@ class AudioRtpFactory { ...@@ -115,12 +117,14 @@ class AudioRtpFactory {
srtpEnabled_ = enable; srtpEnabled_ = enable;
} }
#if HAVE_ZRTP
/** /**
* Get the current AudioZrtpSession. Throws an AudioRtpFactoryException * Get the current AudioZrtpSession. Throws an AudioRtpFactoryException
* if the current rtp thread is null, or if it's not of the correct type. * if the current rtp thread is null, or if it's not of the correct type.
* @return The current AudioZrtpSession thread. * @return The current AudioZrtpSession thread.
*/ */
sfl::AudioZrtpSession* getAudioZrtpSession(); sfl::AudioZrtpSession* getAudioZrtpSession();
#endif
void initLocalCryptoInfo(); void initLocalCryptoInfo();
void initLocalCryptoInfoOnOffHold(); void initLocalCryptoInfoOnOffHold();
......
...@@ -40,8 +40,6 @@ ...@@ -40,8 +40,6 @@
namespace sfl { namespace sfl {
static const SFLDataFormat INIT_FADE_IN_FACTOR = 32000;
#ifdef RECTODISK #ifdef RECTODISK
std::ofstream rtpResampled ("testRtpOutputResampled.raw", std::ifstream::binary); std::ofstream rtpResampled ("testRtpOutputResampled.raw", std::ifstream::binary);
std::ofstream rtpNotResampled("testRtpOutput.raw", std::ifstream::binary); std::ofstream rtpNotResampled("testRtpOutput.raw", std::ifstream::binary);
...@@ -69,10 +67,12 @@ AudioRtpRecord::AudioRtpRecord() : ...@@ -69,10 +67,12 @@ AudioRtpRecord::AudioRtpRecord() :
, codecFrameSize_(0) , codecFrameSize_(0)
, converterSamplingRate_(0) , converterSamplingRate_(0)
, dtmfQueue_() , dtmfQueue_()
, fadeFactor_(INIT_FADE_IN_FACTOR) , fadeFactor_(1.0 / 32000.0)
#if HAVE_SPEEXDSP
, noiseSuppressEncode_(0) , noiseSuppressEncode_(0)
, noiseSuppressDecode_(0) , noiseSuppressDecode_(0)
, audioProcessMutex_() , audioProcessMutex_()
#endif
, callId_("") , callId_("")
, dtmfPayloadType_(101) // same as Asterisk , dtmfPayloadType_(101) // same as Asterisk
{} {}
...@@ -87,15 +87,16 @@ AudioRtpRecord::~AudioRtpRecord() ...@@ -87,15 +87,16 @@ AudioRtpRecord::~AudioRtpRecord()
delete converterEncode_; delete converterEncode_;
delete converterDecode_; delete converterDecode_;
delete audioCodec_; delete audioCodec_;
#if HAVE_SPEEXDSP
delete noiseSuppressEncode_; delete noiseSuppressEncode_;
delete noiseSuppressDecode_; delete noiseSuppressDecode_;
#endif
} }
AudioRtpRecordHandler::AudioRtpRecordHandler(SIPCall &call) : AudioRtpRecordHandler::AudioRtpRecordHandler(SIPCall &call) :
audioRtpRecord_(), audioRtpRecord_(),
id_(call.getCallId()), id_(call.getCallId()),
echoCanceller(call.getMemoryPool()),
gainController(8000, -10.0) gainController(8000, -10.0)
{} {}
...@@ -128,6 +129,7 @@ void AudioRtpRecordHandler::initBuffers() ...@@ -128,6 +129,7 @@ void AudioRtpRecordHandler::initBuffers()
audioRtpRecord_.converterDecode_ = new SamplerateConverter(getCodecSampleRate()); audioRtpRecord_.converterDecode_ = new SamplerateConverter(getCodecSampleRate());
} }
#if HAVE_SPEEXDSP
void AudioRtpRecordHandler::initNoiseSuppress() void AudioRtpRecordHandler::initNoiseSuppress()
{ {
ost::MutexLock lock(audioRtpRecord_.audioProcessMutex_); ost::MutexLock lock(audioRtpRecord_.audioProcessMutex_);
...@@ -136,6 +138,7 @@ void AudioRtpRecordHandler::initNoiseSuppress() ...@@ -136,6 +138,7 @@ void AudioRtpRecordHandler::initNoiseSuppress()
delete audioRtpRecord_.noiseSuppressDecode_; delete audioRtpRecord_.noiseSuppressDecode_;
audioRtpRecord_.noiseSuppressDecode_ = new NoiseSuppress(getCodecFrameSize(), getCodecSampleRate()); audioRtpRecord_.noiseSuppressDecode_ = new NoiseSuppress(getCodecFrameSize(), getCodecSampleRate());
} }
#endif
void AudioRtpRecordHandler::putDtmfEvent(int digit) void AudioRtpRecordHandler::putDtmfEvent(int digit)
{ {
...@@ -173,9 +176,6 @@ int AudioRtpRecordHandler::processDataEncode() ...@@ -173,9 +176,6 @@ int AudioRtpRecordHandler::processDataEncode()
audioRtpRecord_.fadeInDecodedData(samples); audioRtpRecord_.fadeInDecodedData(samples);
if (Manager::instance().getEchoCancelState())
echoCanceller.getData(micData);
SFLDataFormat *out = micData; SFLDataFormat *out = micData;
if (codecSampleRate != mainBufferSampleRate) { if (codecSampleRate != mainBufferSampleRate) {
...@@ -194,11 +194,13 @@ int AudioRtpRecordHandler::processDataEncode() ...@@ -194,11 +194,13 @@ int AudioRtpRecordHandler::processDataEncode()
out = audioRtpRecord_.resampledData_.data(); out = audioRtpRecord_.resampledData_.data();
} }
#if HAVE_SPEEXDSP
if (Manager::instance().audioPreference.getNoiseReduce()) { if (Manager::instance().audioPreference.getNoiseReduce()) {
ost::MutexLock lock(audioRtpRecord_.audioProcessMutex_); ost::MutexLock lock(audioRtpRecord_.audioProcessMutex_);
assert(audioRtpRecord_.noiseSuppressEncode_); assert(audioRtpRecord_.noiseSuppressEncode_);
audioRtpRecord_.noiseSuppressEncode_->process(micData, getCodecFrameSize()); audioRtpRecord_.noiseSuppressEncode_->process(micData, getCodecFrameSize());
} }
#endif
{ {
ost::MutexLock lock(audioRtpRecord_.audioCodecMutex_); ost::MutexLock lock(audioRtpRecord_.audioCodecMutex_);
...@@ -221,12 +223,13 @@ void AudioRtpRecordHandler::processDataDecode(unsigned char *spkrData, size_t si ...@@ -221,12 +223,13 @@ void AudioRtpRecordHandler::processDataDecode(unsigned char *spkrData, size_t si
inSamples = audioRtpRecord_.audioCodec_->decode(spkrDataDecoded, spkrData, size); inSamples = audioRtpRecord_.audioCodec_->decode(spkrDataDecoded, spkrData, size);
} }
#if HAVE_SPEEXDSP
if (Manager::instance().audioPreference.getNoiseReduce()) { if (Manager::instance().audioPreference.getNoiseReduce()) {
ost::MutexLock lock(audioRtpRecord_.audioProcessMutex_); ost::MutexLock lock(audioRtpRecord_.audioProcessMutex_);
assert(audioRtpRecord_.noiseSuppressDecode_); assert(audioRtpRecord_.noiseSuppressDecode_);
audioRtpRecord_.noiseSuppressDecode_->process(spkrDataDecoded, getCodecFrameSize()); audioRtpRecord_.noiseSuppressDecode_->process(spkrDataDecoded, getCodecFrameSize());
} }
#endif
audioRtpRecord_.fadeInDecodedData(inSamples); audioRtpRecord_.fadeInDecodedData(inSamples);
...@@ -249,23 +252,20 @@ void AudioRtpRecordHandler::processDataDecode(unsigned char *spkrData, size_t si ...@@ -249,23 +252,20 @@ void AudioRtpRecordHandler::processDataDecode(unsigned char *spkrData, size_t si
mainBufferSampleRate, inSamples); mainBufferSampleRate, inSamples);
} }
if (Manager::instance().getEchoCancelState())
echoCanceller.putData(out, outSamples);
Manager::instance().getMainBuffer()->putData(out, outSamples * sizeof(SFLDataFormat), id_); Manager::instance().getMainBuffer()->putData(out, outSamples * sizeof(SFLDataFormat), id_);
} }
void AudioRtpRecord::fadeInDecodedData(size_t size) void AudioRtpRecord::fadeInDecodedData(size_t size)
{ {
// if factor reaches 0, this function should have no effect // if factor reaches 1, this function should have no effect
if (fadeFactor_ <= 0 or size > decData_.size()) if (fadeFactor_ >= 1.0 or size > decData_.size())
return; return;
std::transform(decData_.begin(), decData_.begin() + size, decData_.begin(), std::transform(decData_.begin(), decData_.begin() + size, decData_.begin(),
std::bind1st(std::divides<double>(), fadeFactor_)); std::bind1st(std::multiplies<double>(), fadeFactor_));
// Factor used to increase volume in fade in // Factor used to increase volume in fade in
const SFLDataFormat FADEIN_STEP_SIZE = 4; const double FADEIN_STEP_SIZE = 4.0;
fadeFactor_ /= FADEIN_STEP_SIZE; fadeFactor_ *= FADEIN_STEP_SIZE;
} }
} }
...@@ -89,10 +89,14 @@ class AudioRtpRecord { ...@@ -89,10 +89,14 @@ class AudioRtpRecord {
int codecFrameSize_; int codecFrameSize_;
int converterSamplingRate_; int converterSamplingRate_;
std::list<DTMFEvent> dtmfQueue_; std::list<DTMFEvent> dtmfQueue_;
SFLDataFormat fadeFactor_; double fadeFactor_;
#if HAVE_SPEEXDSP
NoiseSuppress *noiseSuppressEncode_; NoiseSuppress *noiseSuppressEncode_;
NoiseSuppress *noiseSuppressDecode_; NoiseSuppress *noiseSuppressDecode_;
ost::Mutex audioProcessMutex_; ost::Mutex audioProcessMutex_;
#endif
std::string callId_; std::string callId_;
unsigned int dtmfPayloadType_; unsigned int dtmfPayloadType_;
...@@ -146,7 +150,9 @@ class AudioRtpRecordHandler { ...@@ -146,7 +150,9 @@ class AudioRtpRecordHandler {
void initBuffers(); void initBuffers();
#if HAVE_SPEEXDSP
void initNoiseSuppress(); void initNoiseSuppress();
#endif
/** /**
* Encode audio data from mainbuffer * Encode audio data from mainbuffer
...@@ -174,7 +180,6 @@ class AudioRtpRecordHandler { ...@@ -174,7 +180,6 @@ class AudioRtpRecordHandler {
private: private:
const std::string id_; const std::string id_;
EchoSuppress echoCanceller;
GainControl gainController; GainControl gainController;
}; };
} }
......
...@@ -68,11 +68,13 @@ void AudioRtpSession::updateSessionMedia(AudioCodec &audioCodec) ...@@ -68,11 +68,13 @@ void AudioRtpSession::updateSessionMedia(AudioCodec &audioCodec)
Manager::instance().audioSamplingRateChanged(audioRtpRecord_.codecSampleRate_); Manager::instance().audioSamplingRateChanged(audioRtpRecord_.codecSampleRate_);
#if HAVE_SPEEXDSP
if (lastSamplingRate != audioRtpRecord_.codecSampleRate_) { if (lastSamplingRate != audioRtpRecord_.codecSampleRate_) {
DEBUG("Update noise suppressor with sampling rate %d and frame size %d", DEBUG("Update noise suppressor with sampling rate %d and frame size %d",
getCodecSampleRate(), getCodecFrameSize()); getCodecSampleRate(), getCodecFrameSize());
initNoiseSuppress(); initNoiseSuppress();
} }
#endif
} }
void AudioRtpSession::setSessionMedia(AudioCodec &audioCodec) void AudioRtpSession::setSessionMedia(AudioCodec &audioCodec)
...@@ -233,7 +235,9 @@ int AudioRtpSession::startRtpThread(AudioCodec &audiocodec) ...@@ -233,7 +235,9 @@ int AudioRtpSession::startRtpThread(AudioCodec &audiocodec)
setSessionTimeouts(); setSessionTimeouts();
setSessionMedia(audiocodec); setSessionMedia(audiocodec);
initBuffers(); initBuffers();
#if HAVE_SPEEXDSP
initNoiseSuppress(); initNoiseSuppress();
#endif
queue_.enableStack(); queue_.enableStack();
thread_.start(); thread_.start();
......
...@@ -47,24 +47,26 @@ ...@@ -47,24 +47,26 @@
namespace sfl { namespace sfl {
AudioZrtpSession::AudioZrtpSession(SIPCall &call, const std::string &zidFilename) : AudioZrtpSession::AudioZrtpSession(SIPCall &call, const std::string &zidFilename) :
AudioRtpSession(call, *this, *this), ost::TimerPort()
ost::TRTPSessionBase<ost::SymmetricRTPChannel, ost::SymmetricRTPChannel, ost::ZrtpQueue>(ost::InetHostAddress(call_.getLocalIp().c_str()), , ost::SymmetricZRTPSession(ost::InetHostAddress(call.getLocalIp().c_str()), call.getLocalAudioPort())
call_.getLocalAudioPort(), , AudioRtpSession(call, *this, *this)
0, , zidFilename_(zidFilename)
ost::MembershipBookkeeping::defaultMembersHashSize, , rtpThread_(*this)
ost::defaultApplication()),
zidFilename_(zidFilename)
{ {
initializeZid(); initializeZid();
DEBUG("Setting new RTP session with destination %s:%d", DEBUG("Setting new RTP session with destination %s:%d",
call_.getLocalIp().c_str(), call_.getLocalAudioPort()); call_.getLocalIp().c_str(), call_.getLocalAudioPort());
audioRtpRecord_.callId_ = call_.getCallId();
} }
AudioZrtpSession::~AudioZrtpSession() AudioZrtpSession::~AudioZrtpSession()
{ {
ost::Thread::terminate(); if (rtpThread_.running_) {
Manager::instance().getMainBuffer()->unBindAll(call_.getCallId()); rtpThread_.running_ = false;
rtpThread_.join();
} }
}
void AudioZrtpSession::initializeZid() void AudioZrtpSession::initializeZid()
{ {
...@@ -120,46 +122,31 @@ void AudioZrtpSession::sendMicData() ...@@ -120,46 +122,31 @@ void AudioZrtpSession::sendMicData()
queue_.sendImmediate(timestamp_, getMicDataEncoded(), compSize); queue_.sendImmediate(timestamp_, getMicDataEncoded(), compSize);
} }
void AudioZrtpSession::run() AudioZrtpSession::AudioZrtpThread::AudioZrtpThread(AudioZrtpSession &session) : running_(true), zrtpSession_(session)
{}
void AudioZrtpSession::AudioZrtpThread::run()
{ {
// Set recording sampling rate // Set recording sampling rate
call_.setRecordingSmplRate(getCodecSampleRate()); int threadSleep = 20;
DEBUG("Entering mainloop for call %s", call_.getCallId().c_str());
uint32 timeout = 0; DEBUG("Entering Audio zrtp thread main loop %s", running_ ? "running" : "not running");
while (isActive()) { TimerPort::setTimer(threadSleep);
if (timeout < 1000)
timeout = getSchedulingTimeout();
while (running_) {
// Send session // Send session
if (hasDTMFPending()) if (zrtpSession_.hasDTMFPending())
sendDtmfEvent(); zrtpSession_.sendDtmfEvent();
else else
sendMicData(); zrtpSession_.sendMicData();
controlReceptionService(); Thread::sleep(TimerPort::getTimer());
controlTransmissionService();
uint32 maxWait = timeval2microtimeout(getRTCPCheckInterval()); TimerPort::incTimer(threadSleep);
// make sure the scheduling timeout is
// <= the check interval for RTCP
// packets
timeout = (timeout > maxWait) ? maxWait : timeout;
if (timeout < 1000) { // !(timeout/1000)
// dispatchDataPacket();
timerTick();
} else {
if (isPendingData(timeout / 1000)) {
if (isActive())
takeInDataPacket();
}
timeout = 0;
}
} }
DEBUG("Left main loop for call %s", call_.getCallId().c_str()); DEBUG("Leaving audio rtp thread loop");
} }
int AudioZrtpSession::getIncrementForDTMF() const int AudioZrtpSession::getIncrementForDTMF() const
...@@ -172,4 +159,13 @@ void AudioZrtpSession::setSessionMedia(AudioCodec &audioCodec) ...@@ -172,4 +159,13 @@ void AudioZrtpSession::setSessionMedia(AudioCodec &audioCodec)
AudioRtpSession::setSessionMedia(audioCodec); AudioRtpSession::setSessionMedia(audioCodec);
} }
int AudioZrtpSession::startRtpThread(AudioCodec &audiocodec)
{
if(isStarted_)
return 0;
AudioRtpSession::startRtpThread(audiocodec);
return startZrtpThread();
}
} }
...@@ -54,25 +54,46 @@ class ZrtpZidException : public std::runtime_error { ...@@ -54,25 +54,46 @@ class ZrtpZidException : public std::runtime_error {
}; };
class AudioZrtpSession : class AudioZrtpSession :
public AudioRtpSession, protected ost::Thread, public ost::TimerPort,
public ost::TRTPSessionBase<ost::SymmetricRTPChannel, ost::SymmetricRTPChannel, ost::ZrtpQueue> { // public ost::TRTPSessionBase<ost::SymmetricRTPChannel, ost::SymmetricRTPChannel, ost::ZrtpQueue> {
public ost::SymmetricZRTPSession,
public AudioRtpSession {
public: public:
AudioZrtpSession(SIPCall &call, const std::string& zidFilename); AudioZrtpSession(SIPCall &call, const std::string& zidFilename);
~AudioZrtpSession(); ~AudioZrtpSession();
// Thread associated method int startZrtpThread() {
virtual void run(); rtpThread_.start();
return 0;
}
virtual bool onRTPPacketRecv(ost::IncomingRTPPkt &pkt) { virtual bool onRTPPacketRecv(ost::IncomingRTPPkt &pkt) {
return AudioRtpSession::onRTPPacketRecv(pkt); return AudioRtpSession::onRTPPacketRecv(pkt);
} }
private: private:
NON_COPYABLE(AudioZrtpSession);
class AudioZrtpThread : public ost::Thread, public ost::TimerPort {
public:
AudioZrtpThread(AudioZrtpSession &session);
virtual void run();
bool running_;
private:
NON_COPYABLE(AudioZrtpThread);
AudioZrtpSession &zrtpSession_;
};
void sendMicData(); void sendMicData();
void initializeZid(); void initializeZid();
std::string zidFilename_; std::string zidFilename_;
void setSessionMedia(AudioCodec &codec); void setSessionMedia(AudioCodec &codec);
int startRtpThread(AudioCodec &audiocodec);
virtual int getIncrementForDTMF() const; virtual int getIncrementForDTMF() const;
AudioZrtpThread rtpThread_;
}; };
} }
......
...@@ -383,10 +383,10 @@ void MainBuffer::flushAllBuffers() ...@@ -383,10 +383,10 @@ void MainBuffer::flushAllBuffers()
iter->second->flushAll(); iter->second->flushAll();
} }
void MainBuffer::stateInfo() void MainBuffer::dumpInfo() const
{ {
// print each call and bound call ids // print each call and bound call ids
for (CallIDMap::iterator iter_call = callIDMap_.begin(); iter_call != callIDMap_.end(); ++iter_call) { for (CallIDMap::const_iterator iter_call = callIDMap_.begin(); iter_call != callIDMap_.end(); ++iter_call) {
std::string dbg_str(" Call: \t"); std::string dbg_str(" Call: \t");
dbg_str.append(iter_call->first); dbg_str.append(iter_call->first);
dbg_str.append(" is bound to: \t"); dbg_str.append(" is bound to: \t");
...@@ -402,7 +402,7 @@ void MainBuffer::stateInfo() ...@@ -402,7 +402,7 @@ void MainBuffer::stateInfo()
} }
// Print ringbuffers ids and readpointers // Print ringbuffers ids and readpointers
for (RingBufferMap::iterator iter_buffer = ringBufferMap_.begin(); iter_buffer != ringBufferMap_.end(); ++iter_buffer) { for (RingBufferMap::const_iterator iter_buffer = ringBufferMap_.begin(); iter_buffer != ringBufferMap_.end(); ++iter_buffer) {
std::string dbg_str(" Buffer: \t"); std::string dbg_str(" Buffer: \t");
dbg_str.append(iter_buffer->first); dbg_str.append(iter_buffer->first);
......
...@@ -94,7 +94,7 @@ class MainBuffer { ...@@ -94,7 +94,7 @@ class MainBuffer {
void flushAllBuffers(); void flushAllBuffers();
void stateInfo(); void dumpInfo() const;
private: private:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment