diff --git a/Makefile.am b/Makefile.am index b25b08956f..1a1befe7e0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -31,6 +31,7 @@ AM_CPPFLAGS = $(SWITCH_AM_CXXFLAGS) -I$(switch_srcdir)/libs/sofia-sip/libsofia-s AM_LDFLAGS = $(SWITCH_AM_LDFLAGS) $(AM_LIBAPR_LDFLAGS) $(AM_LIBAPU_LDFLAGS) DEFAULT_SOUNDS=en-us-callie-8000 +MY_DEFAULT_ARGS= --build=$(build) --host=$(host) --target=$(target) --prefix="$(prefix)" --exec_prefix="$(exec_prefix)" --libdir="$(libdir)" .INTERMEDIATE: -ldl -liconv -lpthread @@ -329,6 +330,9 @@ fs_cli_SOURCES = libs/esl/src/esl.c libs/esl/src/esl_config.c libs/esl/src/esl_e fs_cli_CFLAGS = $(AM_CFLAGS) -I$(switch_srcdir)/libs/esl/src/include $(LIBEDIT_CFLAGS) fs_cli_LDFLAGS = $(AM_LDFLAGS) -lpthread $(ESL_LDFLAGS) -lm $(LIBEDIT_LIBS) +if DISABLE_CC +fs_cli_CFLAGS += -DDISABLE_CC +endif ## ## fs_encode () @@ -456,7 +460,7 @@ libs/libzrtp/libzrtp.a: cd libs/libzrtp && $(MAKE) libs/sofia-sip/Makefile: - cd libs/sofia-sip && sh ./configure.gnu --prefix=$(prefix) + cd libs/sofia-sip && sh ./configure.gnu $(MY_DEFAULT_ARGS) libs/sofia-sip/libsofia-sip-ua/sdp/.libs/libsdp.a libs/sofia-sip/libsofia-sip-ua/su/.libs/libsu.a: libs/sofia-sip/.update libs/sofia-sip/Makefile @cd libs/sofia-sip && $(MAKE) noop @@ -629,7 +633,7 @@ sndfile-reconf: tiff-reconf: cd libs/tiff-4.0.2 && autoreconf -fi - cd libs/tiff-4.0.2 && sh ./configure.gnu + cd libs/tiff-4.0.2 && sh ./configure.gnu $(MY_DEFAULT_ARGS) cd libs/tiff-4.0.2 && make python-reconf: @@ -645,19 +649,19 @@ srtp-reconf: iks-reconf: cd libs/iksemel && $(MAKE) clean cd libs/iksemel && autoreconf -fi - cd libs/iksemel && sh ./configure.gnu --prefix=$(prefix) + cd libs/iksemel && sh ./configure.gnu $(MY_DEFAULT_ARGS) $(MAKE) mod_dingaling-clean spandsp-reconf: tiff-reconf cd libs/spandsp && $(MAKE) clean || echo cd libs/spandsp && autoreconf -fi - cd libs/spandsp && sh ./configure.gnu --prefix=$(prefix) + cd libs/spandsp && sh ./configure.gnu $(MY_DEFAULT_ARGS) cd libs/spandsp && $(MAKE) sofia-reconf: cd libs/sofia-sip && sh ./autogen.sh cd libs/sofia-sip && $(MAKE) clean - cd libs/sofia-sip && ./configure --prefix=$(prefix) --with-pic --with-glib=no --disable-shared + cd libs/sofia-sip && ./configure $(MY_DEFAULT_ARGS) --with-pic --with-glib=no --disable-shared lua-reconf: cd src/mod/languages/mod_lua/lua && make clean diff --git a/build/Makefile.openbsd b/build/Makefile.openbsd index 8d72e3e0a0..a2213a76f7 100644 --- a/build/Makefile.openbsd +++ b/build/Makefile.openbsd @@ -36,7 +36,7 @@ clean: has-git: @git --version || PKG_PATH=http://openbsd.mirrors.pair.com/`uname -r`/packages/`machine -a`/ pkg_add -r git -deps: libedit libressl curl +deps: libedit openssl curl @PKG_PATH=http://openbsd.mirrors.pair.com/`uname -r`/packages/`machine -a`/ pkg_add -r $(PKG) openssl: openssl-$(OPENSSL)/.done diff --git a/conf/vanilla/autoload_configs/timezones.conf.xml b/conf/vanilla/autoload_configs/timezones.conf.xml index 397e9a979f..757d16c19d 100644 --- a/conf/vanilla/autoload_configs/timezones.conf.xml +++ b/conf/vanilla/autoload_configs/timezones.conf.xml @@ -13,19 +13,20 @@ - - + + - + + @@ -51,7 +52,7 @@ - + @@ -59,23 +60,25 @@ - - - - - - - - - + + + + + + + + + + - - + + - + + @@ -83,20 +86,21 @@ - + - + - + - + - + + @@ -107,12 +111,12 @@ - - + + - + @@ -120,38 +124,42 @@ - + - + - + + + + - + + @@ -164,31 +172,36 @@ + + - - + + - + - + + + - + + - + @@ -197,7 +210,7 @@ - + @@ -210,20 +223,22 @@ - + + + - - + + @@ -236,58 +251,59 @@ - + - + - + + - + - - + + - + + + - + - - + + - - + + + - + - - - - + @@ -300,15 +316,16 @@ - + + - - - - + + + + @@ -320,8 +337,8 @@ - + @@ -336,8 +353,8 @@ - + @@ -349,15 +366,19 @@ - + + + + + - + - + @@ -365,40 +386,52 @@ + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -411,6 +444,7 @@ + @@ -420,7 +454,7 @@ - + @@ -429,9 +463,9 @@ - + - + @@ -439,10 +473,10 @@ - + - + @@ -454,12 +488,34 @@ - + + + + + + + + + + + + + + + + + + + + + + + @@ -472,22 +528,47 @@ - + + + + + + + + + + + + + + + + + + + - - - + - + + + + + + + + + + - - + + @@ -508,6 +589,7 @@ + @@ -516,10 +598,20 @@ - + - + + + + + + + + + + + @@ -535,17 +627,1224 @@ + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/configure.ac b/configure.ac index 7cd2efd248..7ae8101072 100644 --- a/configure.ac +++ b/configure.ac @@ -3,10 +3,10 @@ # Must change all of the below together # For a release, set revision for that tagged release as well and uncomment -AC_INIT([freeswitch], [1.4.9], bugs@freeswitch.org) +AC_INIT([freeswitch], [1.4.10], bugs@freeswitch.org) AC_SUBST(SWITCH_VERSION_MAJOR, [1]) AC_SUBST(SWITCH_VERSION_MINOR, [4]) -AC_SUBST(SWITCH_VERSION_MICRO, [9]) +AC_SUBST(SWITCH_VERSION_MICRO, [10]) AC_SUBST(SWITCH_VERSION_REVISION, []) AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, []) @@ -498,6 +498,8 @@ AC_ARG_ENABLE(cpp, AM_CONDITIONAL([ENABLE_CPP],[test "${enable_cpp}" = "yes"]) +AM_CONDITIONAL([DISABLE_CC],[test "${disable_cc}" = "yes"]) + AC_ARG_ENABLE([system-xmlrpc-c], [AS_HELP_STRING([--enable-system-xmlrpc-c], [use system lib for xmlrpc-c])],, diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index bc7da61c3f..225f37e6c9 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -1214,6 +1214,17 @@ set_modules_non_dfsg () { done } +unavoid_modules () { + local len=${#avoid_mods} + for ((i=0; i&2 echo "Please wait, this takes a few seconds..." >&2 test -z "$modulelist_opt" || set_modules_${modulelist_opt/-/_} +test -z "$modules_add" || unavoid_modules "$modules_add" echo "Adding any new modules to control-modules..." >&2 parse_dir=control-modules.parse diff --git a/debian/control-modules b/debian/control-modules index 9246317117..a494304f6e 100644 --- a/debian/control-modules +++ b/debian/control-modules @@ -333,6 +333,7 @@ Description: mod_opus Adds mod_opus. Module: codecs/mod_sangoma_codec +Build-Depends: libsngtc-dev Description: mod_sangoma_codec Adds mod_sangoma_codec. diff --git a/debian/util.sh b/debian/util.sh index b15bf5395a..a7cb4dc400 100755 --- a/debian/util.sh +++ b/debian/util.sh @@ -209,10 +209,12 @@ create_dsc () { { set -e local OPTIND OPTARG modules_conf="" modules_list="" speed="normal" suite_postfix="" suite_postfix_p=false zl=9 - while getopts 'f:m:s:u:z:' o "$@"; do + local modules_add="" + while getopts 'f:m:p:s:u:z:' o "$@"; do case "$o" in f) modules_conf="$OPTARG";; m) modules_list="$OPTARG";; + p) modules_add="$modules_add $OPTARG";; s) speed="$OPTARG";; u) suite_postfix="$OPTARG"; suite_postfix_p=true; ;; z) zl="$OPTARG";; @@ -235,6 +237,11 @@ create_dsc () { bootstrap_args="-mnon-dfsg" else set_modules_${modules_list}; fi fi + if test -n "$modules_add"; then + for x in $modules_add; do + bootstrap_args="$bootstrap_args -p${x}" + done + fi (cd debian && ./bootstrap.sh -c $distro $bootstrap_args) case "$speed" in paranoid) sed -i ./debian/rules \ @@ -263,15 +270,31 @@ cd /tmp/buildd/*/debian/.. EOF } +get_sources () { + local tgt_distro="$1" + while read type path distro components; do + test "$type" = deb || continue + printf "$type $path $tgt_distro $components\n" + done < /etc/apt/sources.list +} + +get_mirrors () { + get_sources "$1" | tr '\n' '|' | head -c-1; echo +} + build_debs () { { set -e local OPTIND OPTARG debug_hook=false hookdir="" cow_build_opts="" - while getopts 'Bbd' o "$@"; do + local keep_pbuilder_config=false + local use_system_sources=false + while getopts 'Bbdkt' o "$@"; do case "$o" in B) cow_build_opts="--debbuildopts '-B'";; b) cow_build_opts="--debbuildopts '-b'";; d) debug_hook=true;; + k) keep_pbuilder_config=true;; + t) use_system_sources=true;; esac done shift $(($OPTIND-1)) @@ -288,10 +311,22 @@ build_debs () { || err "package cowbuilder isn't installed" local cow_img=/var/cache/pbuilder/base-$distro-$arch.cow cow () { - cowbuilder "$@" \ - --distribution $distro \ - --architecture $arch \ - --basepath $cow_img + if ! $use_system_sources; then + cowbuilder "$@" \ + --distribution $distro \ + --architecture $arch \ + --basepath $cow_img + else + local keyring="$(mktemp /tmp/keyringXXXXXXXX.asc)" + apt-key exportall > "$keyring" + cowbuilder "$@" \ + --distribution $distro \ + --architecture $arch \ + --basepath $cow_img \ + --keyring "$keyring" \ + --othermirror "$(get_mirrors $distro)" + rm -f $keyring + fi } if ! [ -d $cow_img ]; then announce "Creating base $distro-$arch image..." @@ -302,7 +337,9 @@ build_debs () { fi announce "Updating base $distro-$arch image..." local x=30 - while ! cow --update --override-config; do + local opts="--override-config" + $keep_pbuilder_config && opts="" + while ! cow --update $opts; do [ $x -lt 1 ] && break; sleep 120; x=$((x-1)) done announce "Building $distro-$arch DEBs from $dsc..." @@ -324,7 +361,7 @@ build_all () { local OPTIND OPTARG local orig_opts="" dsc_opts="" deb_opts="" modlist="" local archs="" distros="" orig="" depinst=false par=false - while getopts 'a:bc:df:ijl:m:no:s:u:v:z:' o "$@"; do + while getopts 'a:bc:df:ijkl:m:no:p:s:tu:v:z:' o "$@"; do case "$o" in a) archs="$archs $OPTARG";; b) orig_opts="$orig_opts -b";; @@ -333,11 +370,14 @@ build_all () { f) dsc_opts="$dsc_opts -f$OPTARG";; i) depinst=true;; j) par=true;; + k) deb_opts="$deb_opts -k";; l) modlist="$OPTARG";; m) orig_opts="$orig_opts -m$OPTARG"; dsc_opts="$dsc_opts -m$OPTARG";; n) orig_opts="$orig_opts -n";; o) orig="$OPTARG";; + p) dsc_opts="$dsc_opts -p$OPTARG";; s) dsc_opts="$dsc_opts -s$OPTARG";; + t) deb_opts="$deb_opts -t";; u) dsc_opts="$dsc_opts -u$OPTARG";; v) orig_opts="$orig_opts -v$OPTARG";; z) orig_opts="$orig_opts -z$OPTARG"; dsc_opts="$dsc_opts -z$OPTARG";; @@ -416,14 +456,18 @@ commands: Build only modules listed in this file -i Auto install build deps on host system -j Build debs in parallel + -k Don't override pbuilder image configurations -l -m [ quicktest | non-dfsg ] Choose custom list of modules to build -n Nightly build -o Specify existing .orig.tar.xz file + -p + Include otherwise avoided module -s [ paranoid | reckless ] Set FS bootstrap/build -j flags + -t Use system /etc/apt/sources.list in build environment -u Specify a custom suite postfix -v Set version @@ -436,6 +480,8 @@ commands: -B Binary architecture-dependent build -b Binary-only build -d Enable cowbuilder debug hook + -k Don't override pbuilder image configurations + -t Use system /etc/apt/sources.list in build environment create-dbg-pkgs @@ -445,6 +491,8 @@ commands: Build only modules listed in this file -m [ quicktest | non-dfsg ] Choose custom list of modules to build + -p + Include otherwise avoided module -s [ paranoid | reckless ] Set FS bootstrap/build -j flags -u diff --git a/libs/esl/Makefile.am b/libs/esl/Makefile.am index cc84ae3aae..3b1563eaed 100644 --- a/libs/esl/Makefile.am +++ b/libs/esl/Makefile.am @@ -25,6 +25,10 @@ fs_cli_CFLAGS = $(AM_CFLAGS) -I$(switch_srcdir)/libs/esl/src/include $(LIBEDIT_ fs_cli_LDFLAGS = $(AM_LDFLAGS) $(LDFLAGS) $(LIBS) $(LIBEDIT_LIBS) fs_cli_LDADD = libesl.la +if DISABLE_CC +fs_cli_CFLAGS += -DDISABLE_CC +endif + testclient_SOURCES = testclient.c testclient_CFLAGS = $(AM_CFLAGS) -I$(switch_srcdir)/libs/esl/src/include testclient_LDFLAGS = $(AM_LDFLAGS) $(LDFLAGS) $(LIBS) diff --git a/libs/esl/fs_cli.c b/libs/esl/fs_cli.c index 3610ae5219..bab2d5b3b2 100644 --- a/libs/esl/fs_cli.c +++ b/libs/esl/fs_cli.c @@ -1040,8 +1040,11 @@ static void print_banner(FILE *stream, int color) fprintf(stream, "%s%s%s", ESL_SEQ_DEFAULT_COLOR, ESL_SEQ_FYELLOW, ESL_SEQ_BBLUE); } +#ifndef DISABLE_CC fprintf(stream, "%s%s", banner, use); - +#else + fprintf(stream, "%s", banner); +#endif if (color) { fprintf(stream, "%s", ESL_SEQ_DEFAULT_COLOR); diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c index be301f3da8..aa071870a0 100644 --- a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c +++ b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c @@ -1251,6 +1251,8 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan) } else if (caller_data->hangup_cause == PRI_CAUSE_DESTINATION_OUT_OF_ORDER) { /* Can happen when we have a DL link expire or some timer expired */ ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); + } else if (caller_data->hangup_cause == PRI_CAUSE_INVALID_NUMBER_FORMAT) { + ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); } } } diff --git a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c index 9c5ea6696f..369a05d1d0 100644 --- a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c +++ b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c @@ -1402,7 +1402,7 @@ static FIO_READ_FUNCTION(zt_read) } else { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Skipping one IO read cycle due to DTMF event processing\n"); } - continue; + break; } /* Read error, keep going unless to many errors force us to abort ...*/ diff --git a/libs/libdingaling/src/libdingaling.c b/libs/libdingaling/src/libdingaling.c index 7394d1d5c5..0b7c037866 100644 --- a/libs/libdingaling/src/libdingaling.c +++ b/libs/libdingaling/src/libdingaling.c @@ -127,6 +127,7 @@ struct ldl_handle { char *password; char *server; char *status_msg; + char *priority; uint16_t port; int features; int counter; @@ -1470,7 +1471,7 @@ static int on_commands(void *user_data, ikspak *pak) static int on_result(void *user_data, ikspak *pak) { ldl_handle_t *handle = user_data; - iks *msg, *ctag; + iks *msg, *ctag, *tag; if ((msg = iks_make_pres (IKS_SHOW_AVAILABLE, handle->status_msg))) { ctag = iks_insert(msg, "c"); @@ -1480,6 +1481,11 @@ static int on_result(void *user_data, ikspak *pak) iks_insert_attrib(ctag, "client", "libdingaling"); iks_insert_attrib(ctag, "xmlns", "http://jabber.org/protocol/caps"); + if (handle->priority && strlen(handle->priority)) { + tag = iks_insert (msg, "priority"); + iks_insert_cdata(tag, handle->priority, 0); + } + apr_queue_push(handle->queue, msg); msg = NULL; } @@ -3117,6 +3123,7 @@ ldl_status ldl_handle_init(ldl_handle_t **handle, char *server, ldl_user_flag_t flags, char *status_msg, + char *priority, ldl_loop_callback_t loop_callback, ldl_session_callback_t session_callback, ldl_response_callback_t response_callback, @@ -3162,6 +3169,10 @@ ldl_status ldl_handle_init(ldl_handle_t **handle, new_handle->status_msg = apr_pstrdup(pool, status_msg); } + if (priority) { + new_handle->priority = apr_pstrdup(pool, priority); + } + if (loop_callback) { new_handle->loop_callback = loop_callback; } diff --git a/libs/libdingaling/src/libdingaling.h b/libs/libdingaling/src/libdingaling.h index 7c425e6f45..05fafc6da9 100644 --- a/libs/libdingaling/src/libdingaling.h +++ b/libs/libdingaling/src/libdingaling.h @@ -666,6 +666,7 @@ ldl_status ldl_handle_init(ldl_handle_t **handle, char *server, ldl_user_flag_t flags, char *status_msg, + char *priority, ldl_loop_callback_t loop_callback, ldl_session_callback_t session_callback, ldl_response_callback_t response_callback, diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update index 63605e55a1..c3f2b72bea 100644 --- a/libs/sofia-sip/.update +++ b/libs/sofia-sip/.update @@ -1 +1 @@ -Thu Sep 25 21:43:53 CDT 2014 +Wed Oct 1 18:09:52 CDT 2014 diff --git a/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su.h b/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su.h index a1b2813d2d..4c471e4df2 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su.h +++ b/libs/sofia-sip/libsofia-sip-ua/su/sofia-sip/su.h @@ -316,7 +316,7 @@ SOFIAPUBFUN int su_getlocalip(su_sockaddr_t *sin); * and which was missing from WINSOCK */ #define su_is_blocking(e) \ - ((e) == EINPROGRESS || (e) == EAGAIN || (e) == EWOULDBLOCK) +((e) == EINPROGRESS || (e) == EAGAIN || (e) == EWOULDBLOCK || (e) == EINTR) #endif #if SU_HAVE_WINSOCK diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su.c b/libs/sofia-sip/libsofia-sip-ua/su/su.c index b2de1b3e8f..7bc2c00b3e 100644 --- a/libs/sofia-sip/libsofia-sip-ua/su/su.c +++ b/libs/sofia-sip/libsofia-sip-ua/su/su.c @@ -511,25 +511,26 @@ issize_t su_vrecv(su_socket_t s, su_iovec_t iov[], isize_t iovlen, int flags, #else - +#include issize_t su_vsend(su_socket_t s, su_iovec_t const iov[], isize_t iovlen, int flags, su_sockaddr_t const *su, socklen_t sulen) { struct msghdr hdr[1] = {{0}}; - int rv; + issize_t rv; + int sanity = 100; hdr->msg_name = (void *)su; hdr->msg_namelen = sulen; hdr->msg_iov = (struct iovec *)iov; hdr->msg_iovlen = iovlen; - + do { if ((rv = sendmsg(s, hdr, flags)) == -1) { - if (errno == EAGAIN) usleep(1000); + if (errno == EAGAIN) sched_yield(); } - } while (rv == -1 && (errno == EAGAIN || errno == EINTR)); - + } while (--sanity > 0 && rv == -1 && (errno == EAGAIN || errno == EINTR)); + return rv; } @@ -545,9 +546,7 @@ issize_t su_vrecv(su_socket_t s, su_iovec_t iov[], isize_t iovlen, int flags, hdr->msg_iov = (struct iovec *)iov; hdr->msg_iovlen = iovlen; - do { - retval = recvmsg(s, hdr, flags); - } while (retval == -1 && errno == EINTR); + retval = recvmsg(s, hdr, flags); if (su && sulen) *sulen = hdr->msg_namelen; diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/ws.c b/libs/sofia-sip/libsofia-sip-ua/tport/ws.c index 6fa69d2161..51ae0f13f7 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/ws.c +++ b/libs/sofia-sip/libsofia-sip-ua/tport/ws.c @@ -352,7 +352,10 @@ ssize_t ws_raw_read(wsh_t *wsh, void *data, size_t bytes, int block) goto end; } - if (block) ms_sleep(10); + if (block) { + wsh->x++; + ms_sleep(10); + } } } while (r == -1 && err == SSL_ERROR_WANT_READ && wsh->x < 100); @@ -361,14 +364,19 @@ ssize_t ws_raw_read(wsh_t *wsh, void *data, size_t bytes, int block) } do { + r = recv(wsh->sock, data, bytes, 0); + if (r == -1) { if (!block && xp_is_blocking(xp_errno())) { r = -2; goto end; } - if (block) ms_sleep(10); + if (block) { + wsh->x++; + ms_sleep(10); + } } } while (r == -1 && xp_is_blocking(xp_errno()) && wsh->x < 100); diff --git a/libs/srtp/libsrtp.2010.vcxproj b/libs/srtp/libsrtp.2010.vcxproj index 06d304b9bf..3440c53820 100644 --- a/libs/srtp/libsrtp.2010.vcxproj +++ b/libs/srtp/libsrtp.2010.vcxproj @@ -421,6 +421,11 @@ + + + {25bd39b1-c8bf-4676-a738-9cabd9c6bc79} + + diff --git a/libs/srtp/libsrtp.2012.vcxproj b/libs/srtp/libsrtp.2012.vcxproj index 0d321c9e46..a7ceca487a 100644 --- a/libs/srtp/libsrtp.2012.vcxproj +++ b/libs/srtp/libsrtp.2012.vcxproj @@ -429,6 +429,11 @@ + + + {25bd39b1-c8bf-4676-a738-9cabd9c6bc79} + + diff --git a/libs/win32/openssl/libeay32.2010.vcxproj b/libs/win32/openssl/libeay32.2010.vcxproj index ebbc82735a..d4b579a3af 100644 --- a/libs/win32/openssl/libeay32.2010.vcxproj +++ b/libs/win32/openssl/libeay32.2010.vcxproj @@ -76,8 +76,8 @@ <_ProjectFileVersion>10.0.30319.1 true true - true - true + false + false $(PlatformName)\libeay32\$(Configuration)\ $(PlatformName)\libeay32\$(Configuration)\ $(PlatformName)\libeay32\$(Configuration)\ @@ -85,18 +85,18 @@ - copy /Y "$(ProjectDir)opensslconf.h" "$(ProjectDir)..\..\openssl-1.0.1g\include\openssl\opensslconf.h" -copy /Y "$(ProjectDir)applink.c" "$(ProjectDir)..\..\openssl-1.0.1g\include\openssl\applink.c" -copy /Y "$(ProjectDir)buildinf.h" "$(ProjectDir)..\..\openssl-1.0.1g\crypto\buildinf.h" -copy /Y "$(ProjectDir)libeay32.def" "$(ProjectDir)..\..\openssl-1.0.1g\libeay32.def" -if not exist "$(ProjectDir)..\..\openssl-1.0.1g\include\openssl\e_os.h" xcopy "$(ProjectDir)\include\*.*" "$(ProjectDir)..\..\openssl-1.0.1g\include\openssl\" /C /Y /S + copy /Y "$(ProjectDir)opensslconf.h" "$(ProjectDir)..\..\openssl-$(OpenSSLVersion)\include\openssl\opensslconf.h" +copy /Y "$(ProjectDir)applink.c" "$(ProjectDir)..\..\openssl-$(OpenSSLVersion)\include\openssl\applink.c" +copy /Y "$(ProjectDir)buildinf.h" "$(ProjectDir)..\..\openssl-$(OpenSSLVersion)\crypto\buildinf.h" +copy /Y "$(ProjectDir)libeay32.def" "$(ProjectDir)..\..\openssl-$(OpenSSLVersion)\libeay32.def" +if not exist "$(ProjectDir)..\..\openssl-$(OpenSSLVersion)\include\openssl\e_os.h" xcopy "$(ProjectDir)\include\*.*" "$(ProjectDir)..\..\openssl-$(OpenSSLVersion)\include\openssl\" /C /Y /S /Gs0 %(AdditionalOptions) Disabled AnySuitable - ..\..\openssl-1.0.1g\include;..\..\openssl-1.0.1g\crypto;..\..\openssl-1.0.1g\crypto\aes;..\..\openssl-1.0.1g\crypto\asn1;..\..\openssl-1.0.1g\crypto\bf;..\..\openssl-1.0.1g\crypto\bio;..\..\openssl-1.0.1g\crypto\bn;..\..\openssl-1.0.1g\crypto\buffer;..\..\openssl-1.0.1g\crypto\camellia;..\..\openssl-1.0.1g\crypto\cast;..\..\openssl-1.0.1g\crypto\cms;..\..\openssl-1.0.1g\crypto\comp;..\..\openssl-1.0.1g\crypto\conf;..\..\openssl-1.0.1g\crypto\des;..\..\openssl-1.0.1g\crypto\dh;..\..\openssl-1.0.1g\crypto\dsa;..\..\openssl-1.0.1g\crypto\dso;..\..\openssl-1.0.1g\crypto\ec;..\..\openssl-1.0.1g\crypto\ecdh;..\..\openssl-1.0.1g\crypto\ecdsa;..\..\openssl-1.0.1g\crypto\engine;..\..\openssl-1.0.1g\crypto\err;..\..\openssl-1.0.1g\crypto\evp;..\..\openssl-1.0.1g\crypto\modes;..\..\openssl-1.0.1g\ms;..\..\openssl-1.0.1g;%(AdditionalIncludeDirectories) + ..\..\openssl-$(OpenSSLVersion)\include;..\..\openssl-$(OpenSSLVersion)\crypto;..\..\openssl-$(OpenSSLVersion)\crypto\aes;..\..\openssl-$(OpenSSLVersion)\crypto\asn1;..\..\openssl-$(OpenSSLVersion)\crypto\bf;..\..\openssl-$(OpenSSLVersion)\crypto\bio;..\..\openssl-$(OpenSSLVersion)\crypto\bn;..\..\openssl-$(OpenSSLVersion)\crypto\buffer;..\..\openssl-$(OpenSSLVersion)\crypto\camellia;..\..\openssl-$(OpenSSLVersion)\crypto\cast;..\..\openssl-$(OpenSSLVersion)\crypto\cms;..\..\openssl-$(OpenSSLVersion)\crypto\comp;..\..\openssl-$(OpenSSLVersion)\crypto\conf;..\..\openssl-$(OpenSSLVersion)\crypto\des;..\..\openssl-$(OpenSSLVersion)\crypto\dh;..\..\openssl-$(OpenSSLVersion)\crypto\dsa;..\..\openssl-$(OpenSSLVersion)\crypto\dso;..\..\openssl-$(OpenSSLVersion)\crypto\ec;..\..\openssl-$(OpenSSLVersion)\crypto\ecdh;..\..\openssl-$(OpenSSLVersion)\crypto\ecdsa;..\..\openssl-$(OpenSSLVersion)\crypto\engine;..\..\openssl-$(OpenSSLVersion)\crypto\err;..\..\openssl-$(OpenSSLVersion)\crypto\evp;..\..\openssl-$(OpenSSLVersion)\crypto\modes;..\..\openssl-$(OpenSSLVersion)\ms;..\..\openssl-$(OpenSSLVersion);%(AdditionalIncludeDirectories) WINDOWS;WIN32;_DEBUG;_CRT_NON_CONFORMING_SWPRINTFS;OPENSSL_THREADS;DSO_WIN32;OPENSSL_SYSNAME_WIN32;WIN32_LEAN_AND_MEAN;L_ENDIAN;_CRT_SECURE_NO_DEPRECATE;OPENSSL_NO_ASM;OPENSSL_NO_GMP;OPENSSL_NO_JPAKE;OPENSSL_NO_KRB5;OPENSSL_NO_MD2;OPENSSL_NO_RFC3779;OPENSSL_NO_STORE;OPENSSL_NO_STATIC_ENGINE;OPENSSL_BUILD_SHLIBCRYPTO;MK1MF_BUILD;OPENSSL_NO_SCTP;OPENSSL_NO_EC_NISTP_64_GCC_128;%(PreprocessorDefinitions) true MultiThreadedDebugDLL @@ -111,7 +111,7 @@ if not exist "$(ProjectDir)..\..\openssl-1.0.1g\include\openssl\e_os.h" xcopy "$ ws2_32.lib;%(AdditionalDependencies) - $(ProjectDir)..\..\openssl-1.0.1g\libeay32.def + $(ProjectDir)..\..\openssl-$(OpenSSLVersion)\libeay32.def true true MachineX86 @@ -119,11 +119,11 @@ if not exist "$(ProjectDir)..\..\openssl-1.0.1g\include\openssl\e_os.h" xcopy "$ - copy /Y "$(ProjectDir)opensslconf.h" "$(ProjectDir)..\..\openssl-1.0.1g\include\openssl\opensslconf.h" -copy /Y "$(ProjectDir)applink.c" "$(ProjectDir)..\..\openssl-1.0.1g\include\openssl\applink.c" -copy /Y "$(ProjectDir)buildinf.h" "$(ProjectDir)..\..\openssl-1.0.1g\crypto\buildinf.h" -copy /Y "$(ProjectDir)libeay32.def" "$(ProjectDir)..\..\openssl-1.0.1g\libeay32.def" -if not exist "$(ProjectDir)..\..\openssl-1.0.1g\include\openssl\e_os.h" xcopy "$(ProjectDir)\include\*.*" "$(ProjectDir)..\..\openssl-1.0.1g\include\openssl\" /C /Y /S + copy /Y "$(ProjectDir)opensslconf.h" "$(ProjectDir)..\..\openssl-$(OpenSSLVersion)\include\openssl\opensslconf.h" +copy /Y "$(ProjectDir)applink.c" "$(ProjectDir)..\..\openssl-$(OpenSSLVersion)\include\openssl\applink.c" +copy /Y "$(ProjectDir)buildinf.h" "$(ProjectDir)..\..\openssl-$(OpenSSLVersion)\crypto\buildinf.h" +copy /Y "$(ProjectDir)libeay32.def" "$(ProjectDir)..\..\openssl-$(OpenSSLVersion)\libeay32.def" +if not exist "$(ProjectDir)..\..\openssl-$(OpenSSLVersion)\include\openssl\e_os.h" xcopy "$(ProjectDir)\include\*.*" "$(ProjectDir)..\..\openssl-$(OpenSSLVersion)\include\openssl\" /C /Y /S diff --git a/libs/win32/openssl/ssleay32.2010.vcxproj b/libs/win32/openssl/ssleay32.2010.vcxproj index 9e4f641c28..c4d86f5db8 100644 --- a/libs/win32/openssl/ssleay32.2010.vcxproj +++ b/libs/win32/openssl/ssleay32.2010.vcxproj @@ -74,9 +74,9 @@ <_ProjectFileVersion>10.0.30319.1 true - true + false true - true + false $(PlatformName)\ssleay32\$(Configuration)\ $(PlatformName)\ssleay32\$(Configuration)\ $(PlatformName)\ssleay32\$(Configuration)\ diff --git a/scripts/perl/timezone-gen.pl b/scripts/perl/timezone-gen.pl index 281f88556c..6127005062 100755 --- a/scripts/perl/timezone-gen.pl +++ b/scripts/perl/timezone-gen.pl @@ -55,16 +55,13 @@ foreach my $name ( sort( keys(%name_to_file) ) ) { my $data = join( "", <$in> ); close($in); - if ( $data !~ /^TZif/o ) { + my @strings = $data =~ (m/[ -~]{4,}/g); + if ( shift(@strings) !~ /^TZif/o ) { $debug && print "Skipped $file\n"; next; } - my $tmp = $data; - $tmp =~ s/\n$//s; - $tmp =~ s/.*\n//sgmo; - - $zones{$name} = $tmp; + $zones{$name} = pop(@strings); } open( my $out, ">$output" ); diff --git a/src/include/switch_channel.h b/src/include/switch_channel.h index a305c96a45..3c08d6a22d 100644 --- a/src/include/switch_channel.h +++ b/src/include/switch_channel.h @@ -678,7 +678,8 @@ SWITCH_DECLARE(void) switch_channel_release_device_record(switch_device_record_t SWITCH_DECLARE(switch_status_t) switch_channel_bind_device_state_handler(switch_device_state_function_t function, void *user_data); SWITCH_DECLARE(switch_status_t) switch_channel_unbind_device_state_handler(switch_device_state_function_t function); SWITCH_DECLARE(const char *) switch_channel_device_state2str(switch_device_state_t device_state); - +SWITCH_DECLARE(switch_status_t) switch_channel_pass_sdp(switch_channel_t *from_channel, switch_channel_t *to_channel, const char *sdp); + SWITCH_END_EXTERN_C #endif /* For Emacs: diff --git a/src/include/switch_core_media.h b/src/include/switch_core_media.h index 59e1b02b34..2256814d01 100644 --- a/src/include/switch_core_media.h +++ b/src/include/switch_core_media.h @@ -275,8 +275,8 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se SWITCH_DECLARE(switch_rtp_crypto_key_type_t) switch_core_media_crypto_str2type(const char *str); SWITCH_DECLARE(const char *) switch_core_media_crypto_type2str(switch_rtp_crypto_key_type_t type); SWITCH_DECLARE(int) switch_core_media_crypto_keylen(switch_rtp_crypto_key_type_t type); - - +SWITCH_DECLARE(char *) switch_core_media_filter_sdp(const char *sdp, const char *cmd, const char *arg); +SWITCH_DECLARE(char *) switch_core_media_process_sdp_filter(const char *sdp, const char *cmd_buf, switch_core_session_t *session); SWITCH_END_EXTERN_C #endif /* For Emacs: diff --git a/src/include/switch_stfu.h b/src/include/switch_stfu.h index 7bc2c766dc..9a1c592db3 100644 --- a/src/include/switch_stfu.h +++ b/src/include/switch_stfu.h @@ -181,7 +181,8 @@ typedef void (*stfu_n_call_me_t)(stfu_instance_t *i, void *); void stfu_n_report(stfu_instance_t *i, stfu_report_t *r); void stfu_n_destroy(stfu_instance_t **i); stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_qlen, uint32_t samples_per_packet, uint32_t samples_per_second, uint32_t max_drift_ms); -stfu_status_t stfu_n_resize(stfu_instance_t *i, uint32_t qlen); +stfu_status_t _stfu_n_resize(stfu_instance_t *i, int32_t qlen, int line); +#define stfu_n_resize(_i, _ql) _stfu_n_resize(_i, _ql, __LINE__) stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint16_t seq, uint32_t pt, void *data, size_t datalen, uint32_t timer_ts, int last); stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i); SWITCH_DECLARE(int32_t) stfu_n_copy_next_frame(stfu_instance_t *jb, uint32_t timestamp, uint16_t seq, uint16_t distance, stfu_frame_t *next_frame); diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 145d743274..910b44b338 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -839,7 +839,7 @@ typedef enum { /* FLUSH JITTERBUFFER When getting RFC2833 to reduce bleed through */ - RTP_BUG_ACCEPT_ANY_PAYLOAD = (1 << 11) + RTP_BUG_ACCEPT_ANY_PAYLOAD = (1 << 11), /* Make FS accept any payload type instead of dropping and returning CNG frame. Workaround while FS only supports a single payload per rtp session. @@ -847,6 +847,15 @@ typedef enum { This should probably be a flag, but flag enum is already full! */ + + RTP_BUG_ALWAYS_AUTO_ADJUST = (1 << 12) + + /* + Leave the auto-adjust behavior enableed permenantly rather than only at appropriate times. (IMPLICITLY sets RTP_BUG_ACCEPT_ANY_PACKETS) + + */ + + } switch_rtp_bug_flag_t; #ifdef _MSC_VER diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h index d7c07e7171..e8b6843d14 100644 --- a/src/include/switch_utils.h +++ b/src/include/switch_utils.h @@ -418,6 +418,7 @@ SWITCH_DECLARE(switch_status_t) switch_frame_alloc(switch_frame_t **frame, switc SWITCH_DECLARE(switch_status_t) switch_frame_dup(switch_frame_t *orig, switch_frame_t **clone); SWITCH_DECLARE(switch_status_t) switch_frame_free(switch_frame_t **frame); SWITCH_DECLARE(switch_bool_t) switch_is_number(const char *str); +SWITCH_DECLARE(switch_bool_t) switch_is_leading_number(const char *str); SWITCH_DECLARE(char *) switch_find_parameter(const char *str, const char *param, switch_memory_pool_t *pool); /*! diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index e84b9248a1..6fc06ea07e 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -3786,25 +3786,31 @@ SWITCH_STANDARD_API(uuid_send_message_function) return SWITCH_STATUS_SUCCESS; } -#define INFO_SYNTAX "" +#define INFO_SYNTAX " [ ] " SWITCH_STANDARD_API(uuid_send_info_function) { switch_status_t status = SWITCH_STATUS_FALSE; - char *mycmd = NULL, *argv[2] = { 0 }; + char *mycmd = NULL, *argv[4] = { 0 }; int argc = 0; if (!zstr(cmd) && (mycmd = strdup(cmd))) { argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); } - if (argc < 1) { + if (argc < 1 || argc == 3) { stream->write_function(stream, "-USAGE: %s\n", INFO_SYNTAX); } else { switch_core_session_message_t msg = { 0 }; switch_core_session_t *lsession = NULL; msg.message_id = SWITCH_MESSAGE_INDICATE_INFO; - msg.string_array_arg[2] = argv[1]; + if (argc > 3) { + msg.string_array_arg[0] = argv[1]; + msg.string_array_arg[1] = argv[2]; + msg.string_array_arg[2] = argv[3]; + } else { + msg.string_array_arg[2] = argv[1]; + } msg.from = __FILE__; if ((lsession = switch_core_session_locate(argv[0]))) { @@ -6591,18 +6597,26 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) { switch_api_interface_t *commands_api_interface; switch_json_api_interface_t *json_api_interface; + int use_system_commands = 1; + + if (switch_true(switch_core_get_variable("disable_system_api_commands"))) { + use_system_commands = 0; + } *module_interface = switch_loadable_module_create_module_interface(pool, modname); switch_thread_rwlock_create(&bgapi_rwlock, pool); switch_mutex_init(&reload_mutex, SWITCH_MUTEX_NESTED, pool); + if (use_system_commands) { + SWITCH_ADD_API(commands_api_interface, "bg_system", "Execute a system command in the background", bg_system_function, SYSTEM_SYNTAX); + SWITCH_ADD_API(commands_api_interface, "system", "Execute a system command", system_function, SYSTEM_SYNTAX); + } SWITCH_ADD_API(commands_api_interface, "acl", "Compare an ip to an acl list", acl_function, " "); SWITCH_ADD_API(commands_api_interface, "alias", "Alias", alias_function, ALIAS_SYNTAX); SWITCH_ADD_API(commands_api_interface, "coalesce", "Return first nonempty parameter", coalesce_function, COALESCE_SYNTAX); SWITCH_ADD_API(commands_api_interface, "banner", "Return the system banner", banner_function, ""); SWITCH_ADD_API(commands_api_interface, "bgapi", "Execute an api command in a thread", bgapi_function, "[ ]"); - SWITCH_ADD_API(commands_api_interface, "bg_system", "Execute a system command in the background", bg_system_function, SYSTEM_SYNTAX); SWITCH_ADD_API(commands_api_interface, "break", "uuid_break", break_function, BREAK_SYNTAX); SWITCH_ADD_API(commands_api_interface, "complete", "Complete", complete_function, COMPLETE_SYNTAX); SWITCH_ADD_API(commands_api_interface, "cond", "Evaluate a conditional", cond_function, " ? : "); @@ -6663,7 +6677,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) SWITCH_ADD_API(commands_api_interface, "status", "Show current status", status_function, ""); SWITCH_ADD_API(commands_api_interface, "strftime_tz", "Display formatted time of timezone", strftime_tz_api_function, " [|][format string]"); SWITCH_ADD_API(commands_api_interface, "stun", "Execute STUN lookup", stun_function, "[:port] [[: [count]"); SWITCH_ADD_API(commands_api_interface, "timer_test", "Exercise FS timer", timer_test_function, TIMER_TEST_SYNTAX); SWITCH_ADD_API(commands_api_interface, "tone_detect", "Start tone detection on a channel", tone_detect_session_function, TONE_DETECT_SYNTAX); diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index c431f11286..d0e68a5211 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -413,7 +413,7 @@ typedef struct conference_obj { int comfort_noise_level; int auto_recording; int record_count; - int min_recording_participants; + uint32_t min_recording_participants; int video_running; int ivr_dtmf_timeout; int ivr_input_timeout; @@ -3183,6 +3183,7 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v } /* Set the conference recording variable for each member */ for (omember = conference->members; omember; omember = omember->next) { + if (!omember->session) continue; channel = switch_core_session_get_channel(omember->session); switch_channel_set_variable(channel, "conference_recording", conference->record_filename); } @@ -4659,7 +4660,8 @@ static void member_add_file_data(conference_member_t *member, int16_t *data, swi if (file_sample_len <= 0) { member->fnode->done++; } else { /* there is file node data to mix into the frame */ - int32_t i, sample; + uint32_t i; + int32_t sample; /* Check for output volume adjustments */ if (member->volume_out_level) { @@ -5518,7 +5520,7 @@ static switch_status_t conference_play_file(conference_obj_t *conference, char * switch_core_file_close(&fnode->fh); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Position Data.\n"); fnode->al = NULL; - channels = conference->channels; + channels = (uint8_t)conference->channels; bad_params = 1; goto retry; } diff --git a/src/mod/applications/mod_valet_parking/mod_valet_parking.c b/src/mod/applications/mod_valet_parking/mod_valet_parking.c index 05b8074a02..6dc34fe7f1 100644 --- a/src/mod/applications/mod_valet_parking/mod_valet_parking.c +++ b/src/mod/applications/mod_valet_parking/mod_valet_parking.c @@ -880,7 +880,7 @@ static void pres_event_handler(switch_event_t *event) switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_count", "%d", EC++); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "unique-id", lot_name); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "channel-state", "CS_ROUTING"); - switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "answer-state", token->bridged == 0 ? "early" : "confirmed"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "answer-state", "confirmed"); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-direction", token->bridged == 0 ? "outbound" : "inbound"); switch_event_fire(&event); } diff --git a/src/mod/codecs/mod_g729/Makefile.am b/src/mod/codecs/mod_g729/Makefile.am index 4c5ef90f28..beb5451634 100644 --- a/src/mod/codecs/mod_g729/Makefile.am +++ b/src/mod/codecs/mod_g729/Makefile.am @@ -3,7 +3,7 @@ MODNAME=mod_g729 G729_DIR=$(switch_srcdir)/libs/libg729 G729_BUILDDIR=$(switch_builddir)/libs/libg729 -G729_A=$(BUILDDIR)/.libs/libg729.a +G729_A=$(G729_BUILDDIR)/.libs/libg729.a mod_LTLIBRARIES = mod_g729.la mod_g729_la_SOURCES = mod_g729.c @@ -13,7 +13,7 @@ mod_g729_la_LDFLAGS = -avoid-version -module -no-undefined -shared if HAVE_G729 mod_g729_la_CFLAGS += -I$(G729_DIR)/src/include -mod_g729_la_LIBADD +- $(G729_A) +mod_g729_la_LIBADD += $(G729_A) else mod_g729_la_CFLAGS += -DG729_PASSTHROUGH endif diff --git a/src/mod/codecs/mod_opus/Makefile.am b/src/mod/codecs/mod_opus/Makefile.am index 647358601f..0dadfc05ab 100644 --- a/src/mod/codecs/mod_opus/Makefile.am +++ b/src/mod/codecs/mod_opus/Makefile.am @@ -11,13 +11,15 @@ mod_opus_la_CFLAGS = $(AM_CFLAGS) -I$(OPUS_DIR)/include mod_opus_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(OPUS_LA) mod_opus_la_LDFLAGS = -avoid-version -module -no-undefined -shared -lm -lz +MY_DEFAULT_ARGS = --build=$(build) --host=$(host) --target=$(target) --prefix="$(prefix)" --exec_prefix="$(exec_prefix)" --libdir="$(libdir)" --disable-shared --with-pic --srcdir=$(OPUS_DIR) + BUILT_SOURCES=$(OPUS_LA) $(OPUS_DIR)/configure: $(GETLIB) $(OPUS).tar.gz $(OPUS_BUILDDIR)/Makefile: $(OPUS_DIR)/configure mkdir -p $(OPUS_BUILDDIR) - cd $(OPUS_BUILDDIR) && $(DEFAULT_VARS) $(OPUS_DIR)/configure --disable-shared --with-pic --srcdir=$(OPUS_DIR) + cd $(OPUS_BUILDDIR) && $(DEFAULT_VARS) $(OPUS_DIR)/configure $(MY_DEFAULT_ARGS) $(TOUCH_TARGET) $(OPUS_LA): $(OPUS_BUILDDIR)/Makefile diff --git a/src/mod/directories/mod_ldap/Makefile.am b/src/mod/directories/mod_ldap/Makefile.am index 5526eb9074..b5a4586239 100644 --- a/src/mod/directories/mod_ldap/Makefile.am +++ b/src/mod/directories/mod_ldap/Makefile.am @@ -13,7 +13,7 @@ mod_ldap_la_CFLAGS = $(AM_CFLAGS) -DWITH_OPENLDAP -DLDAP_DEPRECATED -I$(LDAP_D mod_ldap_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(LDAPLA) $(LIBLBERLA) mod_ldap_la_LDFLAGS = -avoid-version -module -no-undefined -shared -MY_DEFAULT_ARGS= --disable-slapd --disable-bdb --disable-hdb +MY_DEFAULT_ARGS= --build=$(build) --host=$(host) --target=$(target) --prefix="$(prefix)" --exec_prefix="$(exec_prefix)" --libdir="$(libdir)" --disable-slapd --disable-bdb --disable-hdb $(MODNAME).lo: $(LDAPLA) $(LIBLBERLA) diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index 6be269e565..1592def644 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -124,6 +124,7 @@ struct mdl_profile { char *login; char *password; char *message; + char *priority; #ifdef AUTO_REPLY char *auto_reply; #endif @@ -2844,7 +2845,7 @@ static switch_status_t init_profile(mdl_profile_t *profile, uint8_t login) profile->login, profile->password, profile->server, - profile->user_flags, profile->message, handle_loop, handle_signalling, handle_response, profile) == LDL_STATUS_SUCCESS) { + profile->user_flags, profile->message, profile->priority, handle_loop, handle_signalling, handle_response, profile) == LDL_STATUS_SUCCESS) { profile->purge = SWITCH_FALSE; switch_thread_rwlock_create(&profile->rwlock, module_pool); @@ -2923,6 +2924,8 @@ static void set_profile_val(mdl_profile_t *profile, char *var, char *val) profile->name = switch_core_strdup(module_pool, val); } else if (!strcasecmp(var, "message") && !zstr(val)) { profile->message = switch_core_strdup(module_pool, val); + } else if (!strcasecmp(var, "priority") && !zstr(val)) { + profile->priority = switch_core_strdup(module_pool, val); } else if (!strcasecmp(var, "local-network-acl") && !zstr(val)) { profile->local_network = switch_core_strdup(module_pool, val); } else if (!strcasecmp(var, "rtp-ip")) { @@ -3189,6 +3192,8 @@ static switch_bool_t match_profile(mdl_profile_t *profile, mdl_profile_t *new_pr (new_profile->password && profile->password && !strcasecmp(new_profile->password, profile->password))) && ((!new_profile->message && !profile->message) || (new_profile->message && profile->message && !strcasecmp(new_profile->message, profile->message))) && + ((!new_profile->priority && !profile->priority) || + (new_profile->priority && profile->priority && !strcasecmp(new_profile->priority, profile->priority))) && ((!new_profile->avatar && !profile->avatar) || (new_profile->avatar && profile->avatar && !strcasecmp(new_profile->avatar, profile->avatar))) && #ifdef AUTO_REPLY ((!new_profile->auto_reply && !profile->auto_reply) || @@ -3310,6 +3315,7 @@ static switch_status_t soft_reload(void) switch_set_flag(profile, TFLAG_AUTO); profile->message = ""; + profile->priority = ""; profile->user_flags |= LDL_FLAG_COMPONENT; switch_mutex_init(&profile->mutex, SWITCH_MUTEX_NESTED, module_pool); switch_snprintf(dbname, sizeof(dbname), "dingaling_%s", profile->name); @@ -3440,6 +3446,7 @@ static switch_status_t load_config(void) switch_set_flag(profile, TFLAG_AUTO); profile->message = ""; + profile->priority = ""; profile->user_flags |= LDL_FLAG_COMPONENT; switch_mutex_init(&profile->mutex, SWITCH_MUTEX_NESTED, module_pool); switch_snprintf(dbname, sizeof(dbname), "dingaling_%s", profile->name); diff --git a/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp b/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp index 82b2eb39c6..7ad50e65e9 100644 --- a/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp +++ b/src/mod/endpoints/mod_gsmopen/mod_gsmopen.cpp @@ -243,6 +243,26 @@ switch_status_t gsmopen_tech_init(private_t *tech_pvt, switch_core_session_t *se return SWITCH_STATUS_SUCCESS; } +static switch_status_t list_interfaces(const char *line, const char *cursor, switch_console_callback_match_t **matches) +{ + int interface_id; + switch_console_callback_match_t *my_matches = NULL; + switch_status_t status = SWITCH_STATUS_FALSE; + + for (interface_id = 0; interface_id < GSMOPEN_MAX_INTERFACES; interface_id++) { + if (globals.GSMOPEN_INTERFACES[interface_id].running) { + switch_console_push_match(&my_matches, (const char *) globals.GSMOPEN_INTERFACES[interface_id].name); + } + } + + if (my_matches) { + *matches = my_matches; + status = SWITCH_STATUS_SUCCESS; + } + + return status; +} + static switch_status_t interface_exists(char *the_interface) { int i; @@ -1883,6 +1903,20 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_gsmopen_load) SENDSMS_SYNTAX); SWITCH_ADD_CHAT(chat_interface, GSMOPEN_CHAT_PROTO, chat_send); + switch_console_set_complete("add gsm list"); + switch_console_set_complete("add gsm list full"); + switch_console_set_complete("add gsm console ::gsm::list_interfaces"); + switch_console_set_complete("add gsm remove ::gsm::list_interfaces"); + switch_console_set_complete("add gsm reload"); + switch_console_set_complete("add gsmopen ::gsm::list_interfaces"); + switch_console_set_complete("add gsmopen_dump list"); + switch_console_set_complete("add gsmopen_dump ::gsm::list_interfaces"); + switch_console_set_complete("add gsmopen_ussd ::gsm::list_interfaces"); + switch_console_set_complete("add gsmopen_sendsms ::gsm::list_interfaces"); + switch_console_set_complete("add gsmopen_boost_audio ::gsm::list_interfaces"); + + switch_console_add_complete_func("::gsm::list_interfaces", list_interfaces); + /* indicate that the module should continue to be loaded */ return SWITCH_STATUS_SUCCESS; } else diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index aff86a6331..dde3c88e1a 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -465,6 +465,7 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Sending BYE to %s\n", switch_channel_get_name(channel)); if (!sofia_test_flag(tech_pvt, TFLAG_BYE)) { nua_bye(tech_pvt->nh, + SIPTAG_CONTACT(SIP_NONE), TAG_IF(!zstr(reason), SIPTAG_REASON_STR(reason)), TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)), TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), @@ -478,6 +479,7 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session) } if (!sofia_test_flag(tech_pvt, TFLAG_BYE)) { nua_cancel(tech_pvt->nh, + SIPTAG_CONTACT(SIP_NONE), TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)), TAG_IF(!zstr(reason), SIPTAG_REASON_STR(reason)), TAG_IF(!zstr(bye_headers), SIPTAG_HEADER_STR(bye_headers)), TAG_END()); } @@ -1419,14 +1421,13 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi case SWITCH_MESSAGE_INDICATE_MEDIA: { uint32_t send_invite = 1; + const char *r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE); switch_channel_clear_flag(channel, CF_PROXY_MODE); switch_core_media_set_local_sdp(session, NULL, SWITCH_FALSE); if (!(switch_channel_test_flag(channel, CF_ANSWERED) || switch_channel_test_flag(channel, CF_EARLY_MEDIA))) { if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) { - const char *r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE); - switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE); if (sofia_media_tech_media(tech_pvt, r_sdp) != SWITCH_STATUS_SUCCESS) { @@ -1438,13 +1439,16 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi } } - if (!switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO)) { - switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_FALSE); - if ((status = switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0)) != SWITCH_STATUS_SUCCESS) { - switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); - goto end_lock; - } + + switch_core_media_set_sdp_codec_string(tech_pvt->session, r_sdp, SDP_TYPE_RESPONSE); + switch_channel_set_variable(tech_pvt->channel, "absolute_codec_string", switch_channel_get_variable(tech_pvt->channel, "ep_codec_string")); + switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE); + + if ((status = switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0)) != SWITCH_STATUS_SUCCESS) { + switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); + goto end_lock; } + switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 1); if (send_invite) { @@ -2418,6 +2422,7 @@ static int show_reg_callback(void *pArg, int argc, char **argv, char **columnNam "Contact: \t%s\n" "Agent: \t%s\n" "Status: \t%s(%s) EXP(%s) EXPSECS(%d)\n" + "Ping-Status:\t%s\n" "Host: \t%s\n" "IP: \t%s\n" "Port: \t%s\n" @@ -2425,9 +2430,9 @@ static int show_reg_callback(void *pArg, int argc, char **argv, char **columnNam "Auth-Realm: \t%s\n" "MWI-Account:\t%s@%s\n\n", switch_str_nil(argv[0]), switch_str_nil(argv[1]), switch_str_nil(argv[2]), switch_str_nil(argv[3]), - switch_str_nil(argv[7]), switch_str_nil(argv[4]), switch_str_nil(argv[5]), exp_buf, exp_secs, switch_str_nil(argv[11]), - switch_str_nil(argv[12]), switch_str_nil(argv[13]), switch_str_nil(argv[14]), switch_str_nil(argv[15]), - switch_str_nil(argv[16]), switch_str_nil(argv[17])); + switch_str_nil(argv[7]), switch_str_nil(argv[4]), switch_str_nil(argv[5]), exp_buf, exp_secs, switch_str_nil(argv[18]), + switch_str_nil(argv[11]), switch_str_nil(argv[12]), switch_str_nil(argv[13]), switch_str_nil(argv[14]), + switch_str_nil(argv[15]), switch_str_nil(argv[16]), switch_str_nil(argv[17])); return 0; } @@ -2459,6 +2464,7 @@ static int show_reg_callback_xml(void *pArg, int argc, char **argv, char **colum cb->stream->write_function(cb->stream, " %s\n", switch_amp_encode(switch_str_nil(argv[7]), xmlbuf, buflen)); cb->stream->write_function(cb->stream, " %s(%s) exp(%s) expsecs(%d)\n", switch_str_nil(argv[4]), switch_str_nil(argv[5]), exp_buf, exp_secs); + cb->stream->write_function(cb->stream, " %s\n", switch_str_nil(argv[18])); cb->stream->write_function(cb->stream, " %s\n", switch_str_nil(argv[11])); cb->stream->write_function(cb->stream, " %s\n", switch_str_nil(argv[12])); cb->stream->write_function(cb->stream, " %s\n", switch_str_nil(argv[13])); @@ -2682,19 +2688,19 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t if (!sql && argv[2] && !strcasecmp(argv[2], "pres") && argv[3]) { sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status," "rpid,expires,user_agent,server_user,server_host,profile_name,hostname," - "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host" + "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status" " from sip_registrations where profile_name='%q' and presence_hosts like '%%%q%%'", profile->name, argv[3]); } if (!sql && argv[2] && !strcasecmp(argv[2], "reg") && argv[3]) { sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status," "rpid,expires,user_agent,server_user,server_host,profile_name,hostname," - "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host" + "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host, ping_status" " from sip_registrations where profile_name='%q' and contact like '%%%q%%'", profile->name, argv[3]); } if (!sql && argv[2] && !strcasecmp(argv[2], "reg")) { sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status," "rpid,expires,user_agent,server_user,server_host,profile_name,hostname," - "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host" + "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status" " from sip_registrations where profile_name='%q'", profile->name); } if (!sql && argv[2] && !strcasecmp(argv[2], "user") && argv[3]) { @@ -2721,7 +2727,7 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status," "rpid,expires,user_agent,server_user,server_host,profile_name,hostname," - "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host" + "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status" " from sip_registrations where profile_name='%q' and %s", profile->name, sqlextra); switch_safe_free(dup); switch_safe_free(sqlextra); @@ -2965,21 +2971,21 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status," "rpid,expires,user_agent,server_user,server_host,profile_name,hostname," - "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host" + "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status" " from sip_registrations where profile_name='%q' and presence_hosts like '%%%q%%'", profile->name, argv[3]); } if (!sql && argv[2] && !strcasecmp(argv[2], "reg") && argv[3]) { sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status," "rpid,expires,user_agent,server_user,server_host,profile_name,hostname," - "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host" + "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status" " from sip_registrations where profile_name='%q' and contact like '%%%q%%'", profile->name, argv[3]); } if (!sql && argv[2] && !strcasecmp(argv[2], "reg")) { sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status," "rpid,expires,user_agent,server_user,server_host,profile_name,hostname," - "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host" + "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status" " from sip_registrations where profile_name='%q'", profile->name); } if (!sql && argv[2] && !strcasecmp(argv[2], "user") && argv[3]) { @@ -3006,7 +3012,7 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status," "rpid,expires,user_agent,server_user,server_host,profile_name,hostname," - "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host" + "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status" " from sip_registrations where profile_name='%q' and %s", profile->name, sqlextra); switch_safe_free(dup); switch_safe_free(sqlextra); diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index ee03f235ce..2aab666248 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -84,6 +84,7 @@ typedef struct private_object private_object_t; #define MY_EVENT_UNREGISTER "sofia::unregister" #define MY_EVENT_EXPIRE "sofia::expire" #define MY_EVENT_GATEWAY_STATE "sofia::gateway_state" +#define MY_EVENT_SIP_USER_STATE "sofia::sip_user_state" #define MY_EVENT_NOTIFY_REFER "sofia::notify_refer" #define MY_EVENT_REINVITE "sofia::reinvite" #define MY_EVENT_GATEWAY_ADD "sofia::gateway_add" @@ -426,6 +427,13 @@ typedef enum { SOFIA_GATEWAY_INVALID } sofia_gateway_status_t; +typedef enum { + SOFIA_REG_REACHABLE, + SOFIA_REG_UNREACHABLE, + + SOFIA_REG_INVALID +} sofia_sip_user_status_t; + typedef enum { SUB_STATE_UNSUBED, SUB_STATE_TRYING, @@ -603,6 +611,8 @@ struct sofia_profile { char *challenge_realm; char *pnp_prov_url; char *pnp_notify_profile; + int sip_user_ping_max; + int sip_user_ping_min; sofia_cid_type_t cid_type; switch_core_media_dtmf_t dtmf_type; int auto_restart; @@ -792,6 +802,7 @@ struct private_object { char *respond_dest; time_t last_vid_info; uint32_t keepalive; + uint32_t sent_invites; }; @@ -1124,6 +1135,9 @@ void sofia_profile_destroy(sofia_profile_t *profile); switch_status_t sip_dig_function(_In_opt_z_ const char *cmd, _In_opt_ switch_core_session_t *session, _In_ switch_stream_handle_t *stream); const char *sofia_gateway_status_name(sofia_gateway_status_t status); void sofia_reg_fire_custom_gateway_state_event(sofia_gateway_t *gateway, int status, const char *phrase); +const char *sofia_sip_user_status_name(sofia_sip_user_status_t status); +void sofia_reg_fire_custom_sip_user_state_event(sofia_profile_t *profile, const char *sip_user, const char *contact, + const char* from_user, const char* from_host, const char *call_id, sofia_sip_user_status_t status, int options_res, const char *phrase); uint32_t sofia_reg_reg_count(sofia_profile_t *profile, const char *user, const char *host); char *sofia_media_get_multipart(switch_core_session_t *session, const char *prefix, const char *sdp, char **mp_type); int sofia_glue_tech_simplify(private_object_t *tech_pvt); diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 6cf16e5912..af7d4b9857 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -2096,8 +2096,8 @@ void sofia_event_callback(nua_event_t event, if (event == nua_i_invite) { - if (sip->sip_min_se && profile->minimum_session_expires) { - if (sip->sip_min_se->min_delta < profile->minimum_session_expires) { + if (sip->sip_session_expires && profile->minimum_session_expires) { + if (sip->sip_session_expires->x_delta < profile->minimum_session_expires) { char buf[64] = ""; switch_snprintf(buf, sizeof(buf), "Min-SE: %d", profile->minimum_session_expires); nua_respond(nh, SIP_422_SESSION_TIMER_TOO_SMALL, SIPTAG_HEADER_STR(buf),TAG_END()); @@ -2477,11 +2477,11 @@ void event_handler(switch_event_t *event) sql = switch_mprintf("insert into sip_registrations " "(call_id, sip_user, sip_host, presence_hosts, contact, status, rpid, expires," "user_agent, server_user, server_host, profile_name, hostname, network_ip, network_port, sip_username, sip_realm," - "mwi_user, mwi_host, orig_server_host, orig_hostname) " - "values ('%q','%q','%q','%q','%q','Registered','%q',%ld, '%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q')", + "mwi_user, mwi_host, orig_server_host, orig_hostname, ping_status, ping_count) " + "values ('%q','%q','%q','%q','%q','Registered','%q',%ld, '%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q', '%q', %d)", call_id, from_user, from_host, presence_hosts, contact_str, rpid, expires, user_agent, to_user, guess_ip4, profile_name, mod_sofia_globals.hostname, network_ip, network_port, username, realm, mwi_user, mwi_host, - orig_server_host, orig_hostname); + orig_server_host, orig_hostname, "Reachable", 0); if (sql) { sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE); @@ -2495,6 +2495,33 @@ void event_handler(switch_event_t *event) end: switch_safe_free(fixed_contact_str); switch_safe_free(dup_mwi_account); + } else if ((subclass = switch_event_get_header_nil(event, "orig-event-subclass")) && !strcasecmp(subclass, MY_EVENT_SIP_USER_STATE)) { + char *profile_name = switch_event_get_header_nil(event, "orig-profile-name"); + char *from_user = switch_event_get_header_nil(event, "orig-from-user"); + char *from_host = switch_event_get_header_nil(event, "orig-from-host"); + const char *call_id = switch_event_get_header_nil(event, "orig-call-id"); + char *ping_status = switch_event_get_header_nil(event, "orig-Ping-Status"); + sofia_profile_t *profile = NULL; + + if (!profile_name || !(profile = sofia_glue_find_profile(profile_name))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Profile\n"); + } else { + if (!strcmp(ping_status, "REACHABLE")) { + sql = switch_mprintf("update sip_registrations set ping_status='%s' where sip_user='%s' and sip_host='%s' and call_id='%q'", + "Reachable", from_user, from_host, call_id); + } else { + sql = switch_mprintf("update sip_registrations set ping_status='%s' where sip_user='%s' and sip_host='%s' and call_id='%q'", + "Unreachable", from_user, from_host, call_id); + } + if (sql) { + sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Propagating sip_user_state for %s@%s. Ping-Status: %s\n", from_user, from_host, ping_status); + } + + if (profile) { + sofia_glue_release_profile(profile); + } + } } } @@ -4014,6 +4041,9 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) profile->user_agent = switch_core_sprintf(profile->pool, "FreeSWITCH-mod_sofia/%s", switch_version_full()); + profile->sip_user_ping_max = 3; + profile->sip_user_ping_min = 1; + profile->name = switch_core_strdup(profile->pool, xprofilename); switch_snprintf(url, sizeof(url), "sofia_reg_%s", xprofilename); @@ -4772,6 +4802,10 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } else { sofia_clear_pflag(profile, PFLAG_UNREG_OPTIONS_FAIL); } + } else if (!strcasecmp(var, "sip-user-ping-max")) { + profile->sip_user_ping_max = atoi(val); + } else if (!strcasecmp(var, "sip-user-ping-min")) { + profile->sip_user_ping_min = atoi(val); } else if (!strcasecmp(var, "require-secure-rtp")) { if (switch_true(val)) { sofia_set_pflag(profile, PFLAG_SECURE); @@ -5178,13 +5212,13 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) } else if (!strcasecmp(var, "tls-ciphers") && !zstr(val)) { profile->tls_ciphers = switch_core_strdup(profile->pool, val); } else if (!strcasecmp(var, "tls-version") && !zstr(val)) { - char *ps = val, *pe; + char *ps = val, *pe = val; profile->tls_version = 0; - while (1) { + while (ps && *pe) { int n; pe = strchr(ps,','); if (!pe && !(pe = memchr(ps,0,1024))) break; - n = pe-ps; + n = (int)(pe-ps); if (n==5 && !strncasecmp(ps, "sslv2", n)) profile->tls_version |= SOFIA_TLS_VERSION_SSLv2; if (n==5 && !strncasecmp(ps, "sslv3", n)) @@ -5198,7 +5232,6 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name) if (n==7 && !strncasecmp(ps, "tlsv1.2", n)) profile->tls_version |= SOFIA_TLS_VERSION_TLSv1_2; ps=pe+1; - if (!*pe) break; } } else if (!strcasecmp(var, "tls-timeout")) { int v = atoi(val); @@ -5545,6 +5578,44 @@ const char *sofia_gateway_status_name(sofia_gateway_status_t status) } } +const char *sofia_sip_user_status_name(sofia_sip_user_status_t status) +{ + static const char *status_names[] = { "UNREACHABLE", "REACHABLE", NULL }; + + if (status < SOFIA_REG_INVALID) { + return status_names[status]; + } else { + return "INVALID"; + } +} + +struct cb_helper_sip_user_status { + char *status; + size_t status_len; + + char *contact; + size_t contact_len; + + int count; +}; + +int sofia_sip_user_status_callback(void *pArg, int argc, char **argv, char **columnNames) +{ + struct cb_helper_sip_user_status *cbt = (struct cb_helper_sip_user_status *) pArg; + + if (argc != 3) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "expected 3 arguments from query, instead got %d\n", argc); + return 0; + } + + switch_copy_string(cbt->status, argv[0], cbt->status_len); + cbt->count = (argv[1] && switch_is_number(argv[1])) ? atoi(argv[1]) : 0; + + switch_copy_string(cbt->contact, argv[2], cbt->contact_len); + + return 1; +} + static void sofia_handle_sip_r_options(switch_core_session_t *session, int status, char const *phrase, nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip, @@ -5608,18 +5679,85 @@ static void sofia_handle_sip_r_options(switch_core_session_t *session, int statu gateway->ping = switch_epoch_time_now(NULL) + gateway->ping_freq; sofia_reg_release_gateway(gateway); gateway->pinging = 0; - } else if (sofia_test_pflag(profile, PFLAG_UNREG_OPTIONS_FAIL) && (status != 200 && status != 486) && - sip && sip->sip_to && sip->sip_call_id && sip->sip_call_id->i_id && strchr(sip->sip_call_id->i_id, '_')) { - char *sql; - time_t now = switch_epoch_time_now(NULL); + } else if (sip && sip->sip_to && sip->sip_call_id && sip->sip_call_id->i_id && strchr(sip->sip_call_id->i_id, '_')) { const char *call_id = strchr(sip->sip_call_id->i_id, '_') + 1; + char *sql; + struct cb_helper_sip_user_status sip_user_status; + char ping_status[255] = ""; + char sip_contact[1024] = ""; + int sip_user_ping_min = profile->sip_user_ping_min; + int sip_user_ping_max = profile->sip_user_ping_max; - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Expire registration '%s@%s' due to options failure\n", - sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host); + char *sip_user = switch_mprintf("%s@%s", sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host); + + sip_user_status.status = ping_status; + sip_user_status.status_len = sizeof(ping_status); + sip_user_status.contact = sip_contact; + sip_user_status.contact_len = sizeof(sip_contact); + sql = switch_mprintf("select ping_status, ping_count, contact from sip_registrations where sip_user='%s' and sip_host='%s' and call_id='%q'", + sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id); + sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_sip_user_status_callback, &sip_user_status); + switch_safe_free(sql); + + if (status != 200 && status != 486) { + sip_user_status.count--; + if (sip_user_status.count >= 0) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Ping to sip user '%s@%s' failed with code %d - count %d, state %s\n", + sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, status, sip_user_status.count, sip_user_status.status); + sql = switch_mprintf("update sip_registrations set ping_count=%d where sip_user='%s' and sip_host='%s' and call_id='%q'", sip_user_status.count, + sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id); + sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE); + switch_safe_free(sql); + } + if (sip_user_status.count < sip_user_ping_min) { + if (strcmp(sip_user_status.status, "Unreachable")) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Sip user '%s@%s' is now Unreachable\n", + sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host); + sql = switch_mprintf("update sip_registrations set ping_status='Unreachable' where sip_user='%s' and sip_host='%s' and call_id='%q'", + sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id); + sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE); + switch_safe_free(sql); + sofia_reg_fire_custom_sip_user_state_event(profile, sip_user, sip_user_status.contact, sip->sip_to->a_url->url_user, + sip->sip_to->a_url->url_host, call_id, SOFIA_REG_REACHABLE, status, phrase); + + if (sofia_test_pflag(profile, PFLAG_UNREG_OPTIONS_FAIL)) { + time_t now = switch_epoch_time_now(NULL); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Expire sip user '%s@%s' due to options failure\n", + sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host); + + sql = switch_mprintf("update sip_registrations set expires=%ld where sip_user='%s' and sip_host='%s' and call_id='%q'", + (long) now, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id); + sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE); + switch_safe_free(sql); + } + } + } + } else { + sip_user_status.count++; + if (sip_user_status.count <= sip_user_ping_max) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Ping to sip user '%s@%s' succeeded with code %d - count %d, state %s\n", + sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, status, sip_user_status.count, sip_user_status.status); + sql = switch_mprintf("update sip_registrations set ping_count=%d where sip_user='%s' and sip_host='%s' and call_id='%q'", sip_user_status.count, + sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id); + sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE); + switch_safe_free(sql); + } + if (sip_user_status.count >= sip_user_ping_min) { + if (strcmp(sip_user_status.status, "Reachable")) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Sip user '%s@%s' is now Reachable\n", + sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host); + sql = switch_mprintf("update sip_registrations set ping_status='Reachable' where sip_user='%s' and sip_host='%s' and call_id='%q'", + sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id); + sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE); + switch_safe_free(sql); + sofia_reg_fire_custom_sip_user_state_event(profile, sip_user, sip_user_status.contact, sip->sip_to->a_url->url_user, + sip->sip_to->a_url->url_host, call_id, SOFIA_REG_UNREACHABLE, status, phrase); + } + } + } + + switch_safe_free(sip_user); - sql = switch_mprintf("update sip_registrations set expires=%ld where sip_user='%s' and sip_host='%s' and call_id='%q'", - (long) now, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id); - sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE); } } @@ -6348,6 +6486,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, int is_dup_sdp = 0; switch_event_t *s_event = NULL; char *p; + char *patched_sdp = NULL; tl_gets(tags, NUTAG_CALLSTATE_REF(ss_state), @@ -6364,27 +6503,36 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (!tech_pvt || !tech_pvt->nh) { goto done; } - } - - if (tech_pvt) { + if ((status > 100 || switch_channel_test_flag(channel, CF_ANSWERED)) && status < 300 && !r_sdp && tech_pvt->mparams.last_sdp_str) { r_sdp = tech_pvt->mparams.last_sdp_str; } tech_pvt->mparams.last_sdp_str = NULL; - } + + + if (r_sdp && (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA))) { + const char *var; + + if ((var = switch_channel_get_variable(channel, "bypass_media_sdp_filter"))) { + if ((patched_sdp = switch_core_media_process_sdp_filter(r_sdp, var, session))) { + r_sdp = patched_sdp; + } + } + } - if ((channel && (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA))) || - (sofia_test_flag(profile, TFLAG_INB_NOMEDIA) || sofia_test_flag(profile, TFLAG_PROXY_MEDIA))) { - - /* This marr in our code brought to you by people who can't read........ */ - if (profile->ndlb & SM_NDLB_ALLOW_BAD_IANANAME && r_sdp && (p = (char *) switch_stristr("g729a/8000", r_sdp))) { - p += 4; - *p++ = '/'; - *p++ = '8'; - *p++ = '0'; - *p++ = '0'; - *p++ = '0'; - *p++ = ' '; + if ((switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) || + (sofia_test_flag(profile, TFLAG_INB_NOMEDIA) || sofia_test_flag(profile, TFLAG_PROXY_MEDIA))) { + + /* This marr in our code brought to you by people who can't read........ */ + if (profile->ndlb & SM_NDLB_ALLOW_BAD_IANANAME && r_sdp && (p = (char *) switch_stristr("g729a/8000", r_sdp))) { + p += 4; + *p++ = '/'; + *p++ = '8'; + *p++ = '0'; + *p++ = '0'; + *p++ = '0'; + *p++ = ' '; + } } } @@ -6567,9 +6715,8 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { other_channel = switch_core_session_get_channel(other_session); - if (!switch_channel_get_variable(other_channel, SWITCH_B_SDP_VARIABLE)) { - switch_channel_set_variable(other_channel, SWITCH_B_SDP_VARIABLE, r_sdp); - } + switch_channel_pass_sdp(channel, other_channel, r_sdp); + //switch_channel_pre_answer(other_channel); switch_core_session_queue_indication(other_session, SWITCH_MESSAGE_INDICATE_PROGRESS); switch_core_session_rwunlock(other_session); @@ -6626,9 +6773,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, other_channel = switch_core_session_get_channel(other_session); //other_tech_pvt = switch_core_session_get_private(other_session); - if (!switch_channel_get_variable(other_channel, SWITCH_B_SDP_VARIABLE)) { - switch_channel_set_variable(other_channel, SWITCH_B_SDP_VARIABLE, r_sdp); - } + switch_channel_pass_sdp(channel, other_channel, r_sdp); switch_core_session_queue_indication(other_session, SWITCH_MESSAGE_INDICATE_ANSWER); switch_core_session_rwunlock(other_session); } @@ -6885,11 +7030,27 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) { + if ((sofia_test_media_flag(profile, SCMF_DISABLE_HOLD) + || ((var = switch_channel_get_variable(channel, "rtp_disable_hold")) && switch_true(var))) + && ((switch_stristr("sendonly", r_sdp) || switch_stristr("0.0.0.0", r_sdp)) || tech_pvt->mparams.hold_laps)) { + nua_respond(tech_pvt->nh, SIP_200_OK, TAG_END()); + + if (tech_pvt->mparams.hold_laps) { + tech_pvt->mparams.hold_laps = 0; + } else { + tech_pvt->mparams.hold_laps = 1; + } + + goto done; + } + if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { switch_core_session_message_t *msg; private_object_t *other_tech_pvt; - - if (switch_channel_test_flag(channel, CF_PROXY_MODE) && !is_t38 && (profile->media_options & MEDIA_OPT_MEDIA_ON_HOLD)) { + int media_on_hold = switch_true(switch_channel_get_variable_dup(channel, "bypass_media_resume_on_hold", SWITCH_FALSE, -1)); + + if (switch_channel_test_flag(channel, CF_PROXY_MODE) && !is_t38 && + ((profile->media_options & MEDIA_OPT_MEDIA_ON_HOLD) || media_on_hold)) { if (switch_stristr("sendonly", r_sdp) || switch_stristr("0.0.0.0", r_sdp)) { tech_pvt->mparams.hold_laps = 1; switch_channel_set_variable(channel, SWITCH_R_SDP_VARIABLE, r_sdp); @@ -6900,7 +7061,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) { //const char *r_sdp = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE); - + switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_TRUE); if (sofia_media_tech_media(tech_pvt, r_sdp) != SWITCH_STATUS_SUCCESS) { switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "CODEC NEGOTIATION ERROR"); @@ -7003,8 +7164,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); } goto done; - } else { - + } else { if (switch_channel_test_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_NEGOTIATED)) { nua_respond(tech_pvt->nh, SIP_200_OK, TAG_END()); goto done; @@ -7016,6 +7176,12 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST); } + + if (switch_channel_test_flag(channel, CF_PROXY_MODE)) { + nua_respond(tech_pvt->nh, SIP_200_OK, TAG_END()); + goto done; + } + if (match && sofia_test_flag(tech_pvt, TFLAG_NOREPLY)) { sofia_clear_flag(tech_pvt, TFLAG_NOREPLY); goto done; @@ -7035,6 +7201,11 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Processing updated SDP\n"); } else { + if (switch_channel_test_flag(channel, CF_PROXY_MODE) || switch_channel_test_flag(channel, CF_PROXY_MEDIA)) { + nua_respond(tech_pvt->nh, SIP_200_OK, TAG_END()); + goto done; + } + switch_channel_set_flag(tech_pvt->channel, CF_REINVITE); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Reinvite Codec Error!\n"); is_ok = 0; @@ -7114,10 +7285,8 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { other_channel = switch_core_session_get_channel(other_session); - if (!switch_channel_get_variable(other_channel, SWITCH_B_SDP_VARIABLE)) { - switch_channel_set_variable(other_channel, SWITCH_B_SDP_VARIABLE, r_sdp); - } - + switch_channel_pass_sdp(channel, other_channel, r_sdp); + if (sofia_test_flag(tech_pvt, TFLAG_3PCC) && sofia_test_pflag(profile, PFLAG_3PCC_PROXY)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "3PCC-PROXY, Got my ACK\n"); sofia_set_flag(tech_pvt, TFLAG_3PCC_HAS_ACK); @@ -7218,10 +7387,8 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { other_channel = switch_core_session_get_channel(other_session); - if (!switch_channel_get_variable(other_channel, SWITCH_B_SDP_VARIABLE)) { - switch_channel_set_variable(other_channel, SWITCH_B_SDP_VARIABLE, r_sdp); - } - + switch_channel_pass_sdp(channel, other_channel, r_sdp); + //switch_channel_answer(other_channel); switch_core_session_queue_indication(other_session, SWITCH_MESSAGE_INDICATE_ANSWER); @@ -7326,6 +7493,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, done: + switch_safe_free(patched_sdp); if ((enum nua_callstate) ss_state == nua_callstate_ready && channel && session && tech_pvt) { sofia_set_flag(tech_pvt, TFLAG_SIMPLIFY); @@ -7738,6 +7906,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t q850 = switch_core_session_sprintf(a_session, "Q.850;cause=16;text=\"normal_clearing\""); } nua_bye(b_tech_pvt->nh, + SIPTAG_CONTACT(SIP_NONE), TAG_IF(!zstr(q850), SIPTAG_REASON_STR(q850)), TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END()); diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 99caba5c2e..a52ba0473d 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -735,8 +735,12 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) cid_name = caller_profile->caller_id_name; cid_num = caller_profile->caller_id_number; - switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_FALSE); - switch_core_media_check_video_codecs(tech_pvt->session); + + if (!tech_pvt->sent_invites && !switch_channel_test_flag(channel, CF_ANSWERED)) { + switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_FALSE); + switch_core_media_check_video_codecs(tech_pvt->session); + } + check_decode(cid_name, session); check_decode(cid_num, session); @@ -1229,6 +1233,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session) switch_channel_get_name(tech_pvt->channel), switch_version_full_human(), tech_pvt->mparams.local_sdp_str ? tech_pvt->mparams.local_sdp_str : "NO SDP PRESENT\n"); + tech_pvt->sent_invites++; if (sofia_use_soa(tech_pvt)) { nua_invite(tech_pvt->nh, @@ -1984,6 +1989,8 @@ int sofia_glue_init_sql(sofia_profile_t *profile) " presence_hosts VARCHAR(255),\n" " contact VARCHAR(1024),\n" " status VARCHAR(255),\n" + " ping_status VARCHAR(255),\n" + " ping_count INTEGER,\n" " rpid VARCHAR(255),\n" " expires BIGINT,\n" " user_agent VARCHAR(255),\n" @@ -2116,6 +2123,7 @@ int sofia_glue_init_sql(sofia_profile_t *profile) "create index sr_expires on sip_registrations (expires)", "create index sr_hostname on sip_registrations (hostname)", "create index sr_status on sip_registrations (status)", + "create index sr_ping_status on sip_registrations (ping_status)", "create index sr_network_ip on sip_registrations (network_ip)", "create index sr_network_port on sip_registrations (network_port)", "create index sr_sip_username on sip_registrations (sip_username)", @@ -2194,6 +2202,9 @@ int sofia_glue_init_sql(sofia_profile_t *profile) switch_cache_db_test_reactive(dbh, test_sql, "drop table sip_registrations", reg_sql); + + switch_cache_db_test_reactive(dbh, "select ping_count from sip_registrations", NULL, "alter table sip_registrations add column ping_count INTEGER default 0"); + switch_cache_db_test_reactive(dbh, "select ping_status from sip_registrations", NULL, "alter table sip_registrations add column ping_status VARCHAR(255) default \"Reachable\""); test2 = switch_mprintf("%s;%s", test_sql, test_sql); diff --git a/src/mod/endpoints/mod_sofia/sofia_media.c b/src/mod/endpoints/mod_sofia/sofia_media.c index 8bd9a589f0..7cb9572c7c 100644 --- a/src/mod/endpoints/mod_sofia/sofia_media.c +++ b/src/mod/endpoints/mod_sofia/sofia_media.c @@ -104,9 +104,9 @@ static void process_mp(switch_core_session_t *session, switch_stream_handle_t *s if ((dval = strchr(dname, ':'))) { *dval++ = '\0'; if (*dval == '~') { - stream->write_function(stream, "--%s\nContent-Type: %s\nContent-Length: %d\n%s\n", boundary, dname, strlen(dval), dval + 1); + stream->write_function(stream, "--%s\r\nContent-Type: %s\r\nContent-Length: %d\r\n%s\r\n", boundary, dname, strlen(dval), dval + 1); } else { - stream->write_function(stream, "--%s\nContent-Type: %s\nContent-Length: %d\n\n%s\n", boundary, dname, strlen(dval) + 1, dval); + stream->write_function(stream, "--%s\r\nContent-Type: %s\r\nContent-Length: %d\r\n\r\n%s\r\n", boundary, dname, strlen(dval) + 1, dval); } } } @@ -146,9 +146,9 @@ char *sofia_media_get_multipart(switch_core_session_t *session, const char *pref if (x) { *mp_type = switch_core_session_sprintf(session, "multipart/mixed; boundary=%s", boundary); if (sdp) { - stream.write_function(&stream, "--%s\nContent-Type: application/sdp\nContent-Length: %d\n\n%s\n", boundary, strlen(sdp) + 1, sdp); + stream.write_function(&stream, "--%s\r\nContent-Type: application/sdp\r\nContent-Length: %d\r\n\r\n%s\r\n", boundary, strlen(sdp) + 1, sdp); } - stream.write_function(&stream, "--%s--\n", boundary); + stream.write_function(&stream, "--%s--\r\n", boundary); } if (!zstr((char *) stream.data)) { diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 053ddd9a9e..8b3373ce9a 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -161,6 +161,26 @@ void sofia_reg_fire_custom_gateway_state_event(sofia_gateway_t *gateway, int sta } } +void sofia_reg_fire_custom_sip_user_state_event(sofia_profile_t *profile, const char *sip_user, const char *contact, + const char* from_user, const char* from_host, const char *call_id, sofia_sip_user_status_t status, int options_res, const char *phrase) +{ + switch_event_t *s_event; + if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_SIP_USER_STATE) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "sip_contact", contact); + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile-name", profile->name); + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "sip_user", sip_user); + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-user", from_user); + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-host", from_host); + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "call-id", call_id); + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "Ping-Status", sofia_sip_user_status_name(status)); + switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "Status", "%d", options_res); + if (!zstr(phrase)) { + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "Phrase", phrase); + } + switch_event_fire(&s_event); + } +} + void sofia_reg_unregister(sofia_profile_t *profile) { sofia_gateway_t *gateway_ptr; @@ -830,7 +850,7 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot) sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,rpid," "expires,user_agent,server_user,server_host,profile_name" " from sip_registrations where hostname='%s' and " - "profile_name='%s'", mod_sofia_globals.hostname, profile->name); + "profile_name='%s' and orig_hostname='%s'", mod_sofia_globals.hostname, profile->name, mod_sofia_globals.hostname); sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_reg_nat_callback, profile); switch_safe_free(sql); @@ -847,7 +867,7 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot) "expires,user_agent,server_user,server_host,profile_name" " from sip_registrations where (status like '%%NAT%%' " "or contact like '%%fs_nat=yes%%') and hostname='%s' " - "and profile_name='%s'", mod_sofia_globals.hostname, profile->name); + "and profile_name='%s' and orig_hostname='%s'", mod_sofia_globals.hostname, profile->name, mod_sofia_globals.hostname); sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_reg_nat_callback, profile); switch_safe_free(sql); @@ -1805,12 +1825,12 @@ uint8_t sofia_reg_handle_register_token(nua_t *nua, sofia_profile_t *profile, nu sql = switch_mprintf("insert into sip_registrations " "(call_id,sip_user,sip_host,presence_hosts,contact,status,rpid,expires," "user_agent,server_user,server_host,profile_name,hostname,network_ip,network_port,sip_username,sip_realm," - "mwi_user,mwi_host, orig_server_host, orig_hostname, sub_host) " - "values ('%q','%q', '%q','%q','%q','%q', '%q', %ld, '%q', '%q', '%q', '%q', '%q', '%q', '%q','%q','%q','%q','%q','%q','%q','%q')", + "mwi_user,mwi_host, orig_server_host, orig_hostname, sub_host, ping_status, ping_count) " + "values ('%q','%q', '%q','%q','%q','%q', '%q', %ld, '%q', '%q', '%q', '%q', '%q', '%q', '%q','%q','%q','%q','%q','%q','%q','%q', '%q', %d)", call_id, to_user, reg_host, profile->presence_hosts ? profile->presence_hosts : "", contact_str, reg_desc, rpid, (long) reg_time + (long) exptime + profile->sip_expires_late_margin, agent, from_user, guess_ip4, profile->name, mod_sofia_globals.hostname, network_ip, network_port_c, username, realm, - mwi_user, mwi_host, guess_ip4, mod_sofia_globals.hostname, sub_host); + mwi_user, mwi_host, guess_ip4, mod_sofia_globals.hostname, sub_host, "Reachable", 0); } else { sql = switch_mprintf("update sip_registrations set call_id='%q'," "sub_host='%q', network_ip='%q',network_port='%q'," @@ -2483,7 +2503,7 @@ void sofia_reg_handle_sip_r_challenge(int status, if (session) { switch_channel_hangup(switch_core_session_get_channel(session), SWITCH_CAUSE_MANDATORY_IE_MISSING); } else { - nua_cancel(nh, TAG_END()); + nua_cancel(nh, SIPTAG_CONTACT(SIP_NONE), TAG_END()); } end: diff --git a/src/mod/endpoints/mod_verto/mod_verto.c b/src/mod/endpoints/mod_verto/mod_verto.c index ce5dcd0d4b..3fa68853ec 100644 --- a/src/mod/endpoints/mod_verto/mod_verto.c +++ b/src/mod/endpoints/mod_verto/mod_verto.c @@ -2189,7 +2189,7 @@ static void verto_set_media_options(verto_pvt_t *tech_pvt, verto_profile_t *prof tech_pvt->mparams->inbound_codec_string = switch_core_session_strdup(tech_pvt->session, profile->inbound_codec_string); tech_pvt->mparams->outbound_codec_string = switch_core_session_strdup(tech_pvt->session, profile->outbound_codec_string); - tech_pvt->mparams->jb_msec = "-3"; + tech_pvt->mparams->jb_msec = "-1"; switch_media_handle_set_media_flag(tech_pvt->smh, SCMF_SUPPRESS_CNG); switch_media_handle_set_media_flag(tech_pvt->smh, SCMF_RENEG_ON_REINVITE); @@ -2401,7 +2401,8 @@ static void pass_sdp(verto_pvt_t *tech_pvt) if (switch_core_session_get_partner(tech_pvt->session, &other_session) == SWITCH_STATUS_SUCCESS) { other_channel = switch_core_session_get_channel(other_session); - switch_channel_set_variable(other_channel, SWITCH_B_SDP_VARIABLE, tech_pvt->r_sdp); + switch_channel_pass_sdp(tech_pvt->channel, other_channel, tech_pvt->r_sdp); + switch_channel_set_flag(other_channel, CF_PROXY_MODE); switch_core_session_queue_indication(other_session, SWITCH_MESSAGE_INDICATE_ANSWER); switch_core_session_rwunlock(other_session); diff --git a/src/mod/endpoints/mod_verto/ws.c b/src/mod/endpoints/mod_verto/ws.c index 6fa69d2161..51ae0f13f7 100644 --- a/src/mod/endpoints/mod_verto/ws.c +++ b/src/mod/endpoints/mod_verto/ws.c @@ -352,7 +352,10 @@ ssize_t ws_raw_read(wsh_t *wsh, void *data, size_t bytes, int block) goto end; } - if (block) ms_sleep(10); + if (block) { + wsh->x++; + ms_sleep(10); + } } } while (r == -1 && err == SSL_ERROR_WANT_READ && wsh->x < 100); @@ -361,14 +364,19 @@ ssize_t ws_raw_read(wsh_t *wsh, void *data, size_t bytes, int block) } do { + r = recv(wsh->sock, data, bytes, 0); + if (r == -1) { if (!block && xp_is_blocking(xp_errno())) { r = -2; goto end; } - if (block) ms_sleep(10); + if (block) { + wsh->x++; + ms_sleep(10); + } } } while (r == -1 && xp_is_blocking(xp_errno()) && wsh->x < 100); diff --git a/src/mod/xml_int/mod_xml_ldap/Makefile.am b/src/mod/xml_int/mod_xml_ldap/Makefile.am index 7b1348046e..650587a192 100644 --- a/src/mod/xml_int/mod_xml_ldap/Makefile.am +++ b/src/mod/xml_int/mod_xml_ldap/Makefile.am @@ -17,7 +17,7 @@ mod_xml_ldap_la_LDFLAGS = -avoid-version -module -no-undefined -shared BUILT_SOURCES=$(LDAPLA) $(LIBLBERLA) $(LIBLUTILA) -MY_DEFAULT_ARGS= --disable-slapd --disable-slurpd --disable-relay --disable-bdb --disable-hdb +MY_DEFAULT_ARGS= --build=$(build) --host=$(host) --target=$(target) --prefix="$(prefix)" --exec_prefix="$(exec_prefix)" --libdir="$(libdir)" --disable-slapd --disable-slurpd --disable-relay --disable-bdb --disable-hdb $(LDAP_DIR): $(GETLIB) $(LDAP).tar.gz diff --git a/src/switch_channel.c b/src/switch_channel.c index bfd20abc91..49aa4e1923 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -5220,6 +5220,28 @@ SWITCH_DECLARE(switch_status_t) switch_channel_unbind_device_state_handler(switc return status; } +SWITCH_DECLARE(switch_status_t) switch_channel_pass_sdp(switch_channel_t *from_channel, switch_channel_t *to_channel, const char *sdp) +{ + switch_status_t status = SWITCH_STATUS_FALSE; + char *use_sdp = (char *) sdp; + char *patched_sdp = NULL; + + if (!switch_channel_get_variable(to_channel, SWITCH_B_SDP_VARIABLE)) { + const char *var; + + if ((var = switch_channel_get_variable(from_channel, "bypass_media_sdp_filter"))) { + if ((patched_sdp = switch_core_media_process_sdp_filter(use_sdp, var, from_channel->session))) { + use_sdp = patched_sdp; + } + } + + switch_channel_set_variable(to_channel, SWITCH_B_SDP_VARIABLE, use_sdp); + } + + switch_safe_free(patched_sdp); + + return status; +} /* For Emacs: * Local Variables: diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 844497cc80..73d404cfa9 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -859,6 +859,14 @@ SWITCH_DECLARE(void) switch_core_media_parse_rtp_bugs(switch_rtp_bug_flag_t *fla if (switch_stristr("~FLUSH_JB_ON_DTMF", str)) { *flag_pole &= ~RTP_BUG_FLUSH_JB_ON_DTMF; } + + if (switch_stristr("ALWAYS_AUTO_ADJUST", str)) { + *flag_pole |= (RTP_BUG_ALWAYS_AUTO_ADJUST | RTP_BUG_ACCEPT_ANY_PACKETS); + } + + if (switch_stristr("~ALWAYS_AUTO_ADJUST", str)) { + *flag_pole &= ~(RTP_BUG_ALWAYS_AUTO_ADJUST | RTP_BUG_ACCEPT_ANY_PACKETS); + } } @@ -3419,6 +3427,11 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s codec_ms = ptime; + if (switch_channel_get_variable(session->channel, "rtp_h_X-Broken-PTIME") && a_engine->read_impl.microseconds_per_packet) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Overwriting ptime from a known broken endpoint with the currently used value of %d ms\n", a_engine->read_impl.microseconds_per_packet / 1000); + codec_ms = a_engine->read_impl.microseconds_per_packet / 1000; + } + if (maxptime && (!codec_ms || codec_ms > maxptime)) { codec_ms = maxptime; } @@ -4060,11 +4073,23 @@ SWITCH_DECLARE(int) switch_core_media_toggle_hold(switch_core_session_t *session if (switch_channel_test_flag(session->channel, CF_PROTO_HOLD)) { const char *val; + int media_on_hold_a = switch_true(switch_channel_get_variable_dup(session->channel, "bypass_media_resume_on_hold", SWITCH_FALSE, -1)); + int media_on_hold_b = switch_true(switch_channel_get_variable_dup(b_channel, "bypass_media_resume_on_hold", SWITCH_FALSE, -1)); + int bypass_after_hold_a = 0; + int bypass_after_hold_b = 0; + + if (media_on_hold_a) { + bypass_after_hold_a = switch_true(switch_channel_get_variable_dup(session->channel, "bypass_media_after_hold", SWITCH_FALSE, -1)); + } + + if (media_on_hold_b) { + bypass_after_hold_b = switch_true(switch_channel_get_variable_dup(b_channel, "bypass_media_after_hold", SWITCH_FALSE, -1)); + } switch_yield(250000); if (b_channel && (switch_channel_test_flag(session->channel, CF_BYPASS_MEDIA_AFTER_HOLD) || - switch_channel_test_flag(b_channel, CF_BYPASS_MEDIA_AFTER_HOLD))) { + switch_channel_test_flag(b_channel, CF_BYPASS_MEDIA_AFTER_HOLD) || bypass_after_hold_a || bypass_after_hold_b)) { /* try to stay out from media stream */ switch_ivr_nomedia(switch_core_session_get_uuid(session), SMF_REBRIDGE); } @@ -7847,6 +7872,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se case SWITCH_MESSAGE_INDICATE_MEDIA: { + + a_engine->codec_negotiated = 0; + v_engine->codec_negotiated = 0; + if (session->track_duration) { switch_core_session_enable_heartbeat(session, session->track_duration); } @@ -7861,9 +7890,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se switch_channel_set_flag(session->channel, CF_PROXY_MODE); - a_engine->codec_negotiated = 0; - v_engine->codec_negotiated = 0; - switch_core_media_set_local_sdp(session, NULL, SWITCH_FALSE); if (switch_true(switch_channel_get_variable(session->channel, "bypass_keep_codec"))) { @@ -8736,7 +8762,7 @@ SWITCH_DECLARE (void) switch_core_media_recover_session(switch_core_session_t *s } if ((tmp = switch_channel_get_variable(session->channel, "rtp_use_pt"))) { - a_engine->cur_payload_map->pt = a_engine->cur_payload_map->agreed_pt = (switch_payload_t)atoi(tmp); + a_engine->cur_payload_map->pt = a_engine->cur_payload_map->agreed_pt = (switch_payload_t)(smh->payload_space = atoi(tmp)); } if ((tmp = switch_channel_get_variable(session->channel, "rtp_audio_recv_pt"))) { @@ -8744,9 +8770,10 @@ SWITCH_DECLARE (void) switch_core_media_recover_session(switch_core_session_t *s } switch_core_media_set_codec(session, 0, smh->mparams->codec_flags); - + a_engine->adv_sdp_ip = smh->mparams->extrtpip = (char *) ip; a_engine->adv_sdp_port = a_engine->local_sdp_port = (switch_port_t)atoi(port); + a_engine->codec_negotiated = 1; if (!zstr(ip)) { a_engine->local_sdp_ip = switch_core_session_strdup(session, ip); @@ -8849,6 +8876,268 @@ SWITCH_DECLARE(void) switch_core_media_deinit(void) } +static int payload_number(const char *name) +{ + if (!strcasecmp(name, "pcmu")) { + return 0; + } + + if (!strcasecmp(name, "pcma")) { + return 8; + } + + if (!strcasecmp(name, "gsm")) { + return 3; + } + + if (!strcasecmp(name, "g722")) { + return 9; + } + + if (!strcasecmp(name, "g729")) { + return 18; + } + + if (!strcasecmp(name, "dvi4")) { + return 5; + } + + if (!strcasecmp(name, "h261")) { + return 31; + } + + if (!strcasecmp(name, "h263")) { + return 34; + } + + return -1; +} + +static int find_pt(const char *sdp, const char *name) +{ + const char *p; + + if ((p = switch_stristr(name, sdp))) { + if (p < end_of_p(sdp) && *(p+strlen(name)) == '/' && *(p-1) == ' ') { + p -= 2; + + while(*p > 47 && *p < 58) { + p--; + } + p++; + + if (p) { + return atoi(p); + } + } + } + + return -1; +} + + +SWITCH_DECLARE(char *) switch_core_media_filter_sdp(const char *sdp_str, const char *cmd, const char *arg) +{ + char *new_sdp = NULL; + int pt = -1, te = -1; + switch_size_t len; + const char *i; + char *o; + int in_m = 0, m_tally = 0, slash = 0; + int number = 0, skip = 0; + int remove = !strcasecmp(cmd, "remove"); + int only = !strcasecmp(cmd, "only"); + char *end = end_of_p((char *)sdp_str); + int tst; + end++; + + + if (remove || only) { + pt = payload_number(arg); + + if (pt < 0) { + pt = find_pt(sdp_str, arg); + } + } else { + return NULL; + } + + if (only) { + te = find_pt(sdp_str, "telephone-event"); + } + + + len = strlen(sdp_str) + 2; + new_sdp = malloc(len); + o = new_sdp; + i = sdp_str; + + + while(i && *i && i < end) { + + if (*i == 'm' && *(i+1) == '=') { + in_m = 1; + m_tally++; + } + + if (in_m) { + if (*i == '\r' || *i == '\n') { + in_m = 0; + slash = 0; + } else { + if (*i == '/') { + slash++; + while(*i != ' ' && i < end) { + *o++ = *i++; + } + + *o++ = *i++; + } + + if (slash && switch_is_leading_number(i)) { + + + number = atoi(i); + + while(i < end && ((*i > 47 && *i < 58) || *i == ' ')) { + + if (remove) { + tst = (number != pt); + } else { + tst = (number == pt || number == te); + } + + if (tst) { + *o++ = *i; + } + i++; + + if (*i == ' ') { + break; + } + + } + + if (remove) { + tst = (number == pt); + } else { + tst = (number != pt && number != te); + } + + if (tst) { + skip++; + } + } + } + } + + while (i < end && !strncasecmp(i, "a=rtpmap:", 9)) { + const char *t = i + 9; + + number = atoi(t); + + if (remove) { + tst = (number == pt); + } else { + tst = (number != pt && number != te); + } + + while(i < end && (*i != '\r' && *i != '\n')) { + if (!tst) *o++ = *i; + i++; + } + + while(i < end && (*i == '\r' || *i == '\n')) { + if (!tst) *o++ = *i; + i++; + } + } + + while (i < end && !strncasecmp(i, "a=fmtp:", 7)) { + const char *t = i + 7; + + number = atoi(t); + + if (remove) { + tst = (number == pt); + } else { + tst = (number != pt && number != te); + } + + while(i < end && (*i != '\r' && *i != '\n')) { + if (!tst) *o++ = *i; + i++; + } + + while(i < end && (*i == '\r' || *i == '\n')) { + if (!tst) *o++ = *i; + i++; + } + } + + if (!skip) { + *o++ = *i; + } + + skip = 0; + + i++; + } + + *o = '\0'; + + return new_sdp; +} + +SWITCH_DECLARE(char *) switch_core_media_process_sdp_filter(const char *sdp, const char *cmd_buf, switch_core_session_t *session) +{ + switch_channel_t *channel = switch_core_session_get_channel(session); + char *cmd = switch_core_session_strdup(session, cmd_buf); + int argc = 0; + char *argv[50]; + int x = 0; + char *patched_sdp = NULL; + + argc = switch_split(cmd, '|', argv); + + for (x = 0; x < argc; x++) { + char *command = argv[x]; + char *arg = strchr(command, '('); + + if (arg) { + char *e = switch_find_end_paren(arg, '(', ')'); + *arg++ = '\0'; + if (e) *e = '\0'; + } + + if (zstr(command) || zstr(arg)) { + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_WARNING, "%s SDP FILTER PARSE ERROR\n", switch_channel_get_name(channel)); + } else { + char *tmp_sdp = NULL; + + if (patched_sdp) { + tmp_sdp = switch_core_media_filter_sdp(patched_sdp, command, arg); + } else { + tmp_sdp = switch_core_media_filter_sdp(sdp, command, arg); + } + + + switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, + "%s Filter command %s(%s)\nFROM:\n==========\n%s\nTO:\n==========\n%s\n\n", + switch_channel_get_name(channel), + command, arg, patched_sdp ? patched_sdp : sdp, tmp_sdp); + + + if (tmp_sdp) { + switch_safe_free(patched_sdp); + patched_sdp = tmp_sdp; + } + } + } + + return patched_sdp; + +} /* For Emacs: * Local Variables: diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 853d106e68..c5f1eaa718 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -654,7 +654,7 @@ SWITCH_DECLARE(switch_call_cause_t) switch_core_session_outgoing_channel(switch_ } if ((val = switch_channel_get_variable(channel, SWITCH_R_SDP_VARIABLE))) { - switch_channel_set_variable(peer_channel, SWITCH_B_SDP_VARIABLE, val); + switch_channel_pass_sdp(channel, peer_channel, val); } if (switch_channel_test_flag(channel, CF_PROXY_MODE)) { diff --git a/src/switch_pgsql.c b/src/switch_pgsql.c index ccf64d1503..74eea5cb8e 100644 --- a/src/switch_pgsql.c +++ b/src/switch_pgsql.c @@ -305,7 +305,7 @@ SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_next_result_timed(switch_pgsq if (PQisBusy(handle->con)) { /* Wait for a result to become available, up to msec milliseconds */ - start = switch_time_now(); + start = switch_micro_time_now(); while((ctime = switch_micro_time_now()) - start <= usec) { int wait_time = (usec - (ctime - start)) / 1000; fds[0].fd = handle->sock; diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 086d7b0e1c..306a3217d3 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -1002,7 +1002,11 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d return; } - switch_rtp_clear_flag(rtp_session, SWITCH_RTP_FLAG_AUTOADJ); + if ((rtp_session->rtp_bugs & RTP_BUG_ALWAYS_AUTO_ADJUST)) { + switch_rtp_set_flag(rtp_session, SWITCH_RTP_FLAG_AUTOADJ); + } else { + switch_rtp_clear_flag(rtp_session, SWITCH_RTP_FLAG_AUTOADJ); + } } } @@ -5804,19 +5808,27 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ } rtp_session->auto_adj_used = 1; switch_rtp_set_remote_address(rtp_session, tx_host, switch_sockaddr_get_port(rtp_session->from_addr), 0, SWITCH_FALSE, &err); - switch_rtp_clear_flag(rtp_session, SWITCH_RTP_FLAG_AUTOADJ); + if ((rtp_session->rtp_bugs & RTP_BUG_ALWAYS_AUTO_ADJUST)) { + switch_rtp_set_flag(rtp_session, SWITCH_RTP_FLAG_AUTOADJ); + } else { + switch_rtp_clear_flag(rtp_session, SWITCH_RTP_FLAG_AUTOADJ); + } if (rtp_session->ice.ice_user) { rtp_session->ice.addr = rtp_session->remote_addr; } } } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG, "Correct ip/port confirmed.\n"); - switch_rtp_clear_flag(rtp_session, SWITCH_RTP_FLAG_AUTOADJ); + if ((rtp_session->rtp_bugs & RTP_BUG_ALWAYS_AUTO_ADJUST)) { + switch_rtp_set_flag(rtp_session, SWITCH_RTP_FLAG_AUTOADJ); + } else { + switch_rtp_clear_flag(rtp_session, SWITCH_RTP_FLAG_AUTOADJ); + } rtp_session->auto_adj_used = 0; } } - if (bytes && rtp_session->autoadj_window) { + if (bytes && !(rtp_session->rtp_bugs & RTP_BUG_ALWAYS_AUTO_ADJUST) && rtp_session->autoadj_window) { if (--rtp_session->autoadj_window == 0) { switch_rtp_clear_flag(rtp_session, SWITCH_RTP_FLAG_AUTOADJ); } diff --git a/src/switch_stfu.c b/src/switch_stfu.c index 169deda326..0197d01b22 100644 --- a/src/switch_stfu.c +++ b/src/switch_stfu.c @@ -31,6 +31,9 @@ //#define DB_JB 1 +#define DBG_IN 1 +#define DBG_OUT 2 + #ifndef UINT_MAX # define UINT_MAX 4294967295U #endif @@ -100,6 +103,10 @@ struct stfu_instance { uint32_t period_jitter_count; double period_jitter_percent; double period_missing_percent; + uint32_t period_jitter_size_time; + uint32_t period_jitter_size_ts; + uint32_t period_jitter_size; + uint32_t session_clean_count; uint32_t session_missing_count; @@ -114,11 +121,15 @@ struct stfu_instance { int32_t max_drift; uint32_t drift_dropped_packets; uint32_t drift_max_dropped; + uint32_t consecutive_drift; int32_t ts_diff; int32_t last_ts_diff; int32_t same_ts; + uint32_t last_ts_skew; + uint32_t last_time_skew; + uint32_t period_time; uint32_t plc_len; @@ -230,8 +241,20 @@ void stfu_n_debug(stfu_instance_t *i, const char *name) if (i->name) free(i->name); if (name) { + int debug = 0; + + if (strstr(name, ":out")) { + debug |= DBG_OUT; + } + + if (strstr(name, ":in")) { + debug |= DBG_IN; + } + + if (debug) i->debug = (uint8_t)debug; + else i->debug = 3; + i->name = strdup(name); - i->debug = 1; } else { i->name = strdup("none"); i->debug = 0; @@ -250,15 +273,39 @@ void stfu_n_report(stfu_instance_t *i, stfu_report_t *r) r->period_missing_percent = i->period_missing_percent; } -stfu_status_t stfu_n_resize(stfu_instance_t *i, uint32_t qlen) +stfu_status_t stfu_n_auto_size(stfu_instance_t *i, int check_down) +{ + stfu_status_t r = STFU_IT_FAILED; + int len; + + if (!i->ms_per_packet) { + return r; + } + + len = i->period_jitter_size / i->ms_per_packet; + + if (len > i->qlen || (check_down && len < i->qlen)) { + if (check_down) { + len = i->qlen - 1; + } + r = stfu_n_resize(i, len); + } + + return r; +} + +stfu_status_t _stfu_n_resize(stfu_instance_t *i, int32_t qlen, int line) { stfu_status_t s; + int diff; - if (i->qlen == i->max_qlen) { + if (qlen == i->qlen) { return STFU_IT_FAILED; } - if (i->max_qlen && qlen > i->max_qlen) { + if (qlen < i->orig_qlen) { + qlen = i->orig_qlen; + } else if (i->max_qlen && qlen >= (int32_t)i->max_qlen) { if (i->qlen < i->max_qlen) { qlen = i->max_qlen; } else { @@ -266,11 +313,17 @@ stfu_status_t stfu_n_resize(stfu_instance_t *i, uint32_t qlen) } } + diff = qlen - i->qlen; + + if (stfu_log != null_logger && i->debug) { + stfu_log(STFU_LOG_EMERG, "%d %s resize %s %u %u\n", line, i->name, diff > 0 ? "up" : "down", i->qlen, i->qlen + diff); + } + if ((s = stfu_n_resize_aqueue(&i->a_queue, qlen)) == STFU_IT_WORKED) { stfu_n_resize_aqueue(&i->b_queue, qlen); s = stfu_n_resize_aqueue(&i->c_queue, qlen); - if (qlen > i->most_qlen) { + if (qlen > (int32_t)i->most_qlen) { i->most_qlen = qlen; } @@ -340,6 +393,10 @@ static void stfu_n_reset_counters(stfu_instance_t *i) i->period_missing_count = 0; i->period_jitter_count = 0; + i->period_jitter_size_time = 0; + i->period_jitter_size_ts = 0; + i->period_jitter_size = 0; + i->period_need_range = 0; i->period_need_range_avg = 0; @@ -377,7 +434,8 @@ void _stfu_n_reset(stfu_instance_t *i, const char *file, const char *func, int l i->miss_count = 0; i->packet_count = 0; i->ts_offset = 0; - + i->ts_drift = 0; + i->consecutive_drift = 0; } stfu_status_t stfu_n_sync(stfu_instance_t *i, uint32_t packets) @@ -423,9 +481,9 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint16_t seq, uin switch_time_t now; - if (!i->samples_per_packet && ts && i->last_rd_ts) { - i->ts_diff = ts - i->last_rd_ts; + i->ts_diff = ts - i->last_rd_ts; + if (!i->samples_per_packet && ts && i->last_rd_ts) { if (i->last_ts_diff == i->ts_diff) { if (++i->same_ts == 5) { i->samples_per_packet = i->ts_diff; @@ -437,13 +495,13 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint16_t seq, uin i->same_ts = 0; } - i->last_ts_diff = i->ts_diff; - if (!i->samples_per_packet) { i->last_rd_ts = ts; return STFU_IT_FAILED; } } + + i->last_ts_diff = i->ts_diff; if (!i->ms_per_packet) { i->ms_per_packet = 1000 / (i->samples_per_second / i->samples_per_packet); @@ -459,28 +517,65 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint16_t seq, uin i->last_clock_ts = now; - if (abs(diff - i->ms_per_packet) > 1) { - i->period_jitter_count++; + if (diff && i->ms_per_packet) { + i->last_time_skew = abs((int)(diff - (int)i->ms_per_packet)); } - if (timer_ts) { + if (i->last_ts_diff && i->samples_per_packet) { + i->last_ts_skew = abs((int)(i->last_ts_diff - (int)i->samples_per_packet)); + } + + if (i->ready && i->out_queue->array_len && (i->last_time_skew > 1 || i->last_ts_skew)) { + int time_ms = i->last_time_skew, ts_ms = (i->last_ts_skew / i->samples_per_packet) * i->ms_per_packet; + + if (time_ms > i->period_jitter_size_time) { + i->period_jitter_size_time = time_ms; + } + + if (ts_ms > i->period_jitter_size_ts) { + i->period_jitter_size_ts = ts_ms; + } + + if (i->period_jitter_size_time > i->period_jitter_size_ts) { + i->period_jitter_size = i->period_jitter_size_time; + } else { + i->period_jitter_size = i->period_jitter_size_ts; + } + + if (++i->period_jitter_count > 5) { + stfu_n_auto_size(i, 0); + } + } + + if (timer_ts && i->ready && i->out_queue->array_len) { if (ts && !i->ts_offset) { i->ts_offset = timer_ts - ts; } - i->ts_drift = ts + (i->ts_offset - timer_ts); - - if (i->ts_offset && i->ts_drift > 0) { - i->ts_offset = timer_ts - ts; + if (i->ts_offset) { i->ts_drift = ts + (i->ts_offset - timer_ts); + + if (i->ts_drift > 0) { + i->ts_offset = timer_ts - ts; + i->ts_drift = ts + (i->ts_offset - timer_ts); + } + + if (i->ts_drift) { + i->consecutive_drift++; + } else { + i->consecutive_drift = 0; + } } + - - if (i->max_drift) { + if (i->max_drift && i->consecutive_drift >= 10) { if (i->ts_drift < i->max_drift) { if (++i->drift_dropped_packets < i->drift_max_dropped) { - stfu_log(STFU_LOG_EMERG, "%s TOO LATE !!! %u \n\n\n", i->name, ts); + if (stfu_log != null_logger && i->debug) { + stfu_log(STFU_LOG_EMERG, "%s TOO LATE !!! %u \n\n\n", i->name, ts); + } stfu_n_reset(i); + //stfu_n_resize(i, 1); //stfu_n_sync(i, 1); //return STFU_ITS_TOO_LATE; } @@ -504,7 +599,7 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint16_t seq, uin if (stfu_log != null_logger && i->debug) { stfu_log(STFU_LOG_EMERG, "%s TOO LATE !!! %u \n\n\n", i->name, ts); } - stfu_n_sync(i, 1); + //stfu_n_resize(i, i->qlen + 1); return STFU_ITS_TOO_LATE; } } @@ -520,14 +615,9 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint16_t seq, uin i->period_need_range_avg = i->period_need_range / least1(i->period_missing_count); - if (i->period_missing_count > i->qlen * 2) { - if (stfu_log != null_logger && i->debug) { - stfu_log(STFU_LOG_EMERG, "%s resize up %u %u\n", i->name, i->qlen, i->qlen + 1); - } - stfu_n_resize(i, i->qlen + 1); - stfu_n_reset_counters(i); - } - + //if (i->period_missing_count > i->qlen * 2) { + //stfu_n_resize(i, 1); + //} i->diff = 0; @@ -541,32 +631,28 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint16_t seq, uin i->diff_total += i->diff; + i->period_jitter_percent = (double)(((double)i->period_jitter_count / (double)i->period_time) * 100.0f); + i->period_missing_percent= (double)(((double)i->period_missing_count / (double)i->period_time) * 100.0f); + if ((i->period_packet_in_count >= i->period_time)) { - i->period_jitter_percent = (double)(((double)i->period_jitter_count / (double)i->period_time) * 100.0f); - i->period_missing_percent = (double)(((double)i->period_missing_count / (double)i->period_time) * 100.0f); - i->period_packet_in_count = 0; if (stfu_log != null_logger && i->debug) { stfu_log(STFU_LOG_EMERG, "PERIOD %f jitter missing:%f q:%d/%d\n", i->period_jitter_percent, i->period_missing_percent, i->qlen, i->orig_qlen); } + stfu_n_auto_size(i, 1); - if (i->qlen > i->orig_qlen && i->period_jitter_percent < PERIOD_JITTER_TOLERANCE && i->period_missing_percent < PERIOD_JITTER_TOLERANCE) { - if (stfu_log != null_logger && i->debug) { - stfu_log(STFU_LOG_EMERG, "%s resize down %u %u\n", i->name, i->qlen, i->qlen - 1); - } - stfu_n_resize(i, i->qlen - 1); - stfu_n_sync(i, i->qlen); - } + //if (i->qlen > i->orig_qlen) { + //if (i->period_jitter_percent < PERIOD_JITTER_TOLERANCE && i->period_missing_percent < PERIOD_JITTER_TOLERANCE) { + // stfu_n_resize(i, -1); + //} + //} stfu_n_reset_counters(i); } - if (stfu_log != null_logger && i->debug) { - double jitter_percent = (double)(((double)i->period_jitter_count / (double)i->period_packet_in_count) * 100.0f); - double missing_percent = (double)(((double)i->period_missing_count / (double)i->period_packet_in_count) * 100.0f); - - stfu_log(STFU_LOG_EMERG, "I: %s len:%u/%u i=%u/%u - g:%u c:%u b:%u - ts:%u/%u/%u - m:%u(%f%%) j:%f%% dr:%d/%d\n", + if (stfu_log != null_logger && (i->debug & DBG_IN)) { + stfu_log(STFU_LOG_EMERG, "I: %s len:%u/%u i=%u/%u - g:%u c:%u b:%u - ts:%u/%u/%u - m:%u(%f%%) j:%0.2f%% js:%u/%u dr:%d/%d\n", i->name, i->qlen, i->max_qlen, i->period_packet_in_count, i->period_time, @@ -576,8 +662,10 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint16_t seq, uin ts, ts / i->samples_per_packet, i->last_wr_ts, i->period_missing_count, - missing_percent, - jitter_percent, + i->period_missing_percent, + i->period_jitter_percent, + i->period_jitter_size_time, + i->period_jitter_size_ts, i->ts_drift, i->max_drift); } @@ -621,12 +709,16 @@ static int stfu_n_find_any_frame(stfu_instance_t *in, stfu_queue_t *queue, stfu_ int best_diff = 1000000, cur_diff = 0; stfu_frame_t *frame = NULL, *best_frame = NULL; int newer = 0; + int was_read = 0; + stfu_assert(r_frame); *r_frame = NULL; top: + was_read = 0; + if (force) { in->cur_ts = 0; } @@ -634,6 +726,8 @@ static int stfu_n_find_any_frame(stfu_instance_t *in, stfu_queue_t *queue, stfu_ for(i = 0; i < queue->real_array_size; i++) { frame = &queue->array[i]; + if (frame->was_read) was_read++; + if (!frame->was_read && in->cur_ts && frame->ts > in->cur_ts) { newer++; } @@ -647,6 +741,15 @@ static int stfu_n_find_any_frame(stfu_instance_t *in, stfu_queue_t *queue, stfu_ } } + if (was_read == queue->real_array_size) { + if (stfu_log != null_logger && in->debug) { + stfu_log(STFU_LOG_EMERG, "%s OUT QUEUE EMPTY, SWAPPING\n", in->name); + stfu_n_swap(in); + in->ready = 0; + } + return 0; + } + if (!force && !best_frame && newer) { force = 1; goto top; @@ -693,6 +796,28 @@ static int stfu_n_find_frame(stfu_instance_t *in, stfu_queue_t *queue, uint32_t return 0; } +void stfu_n_dump(stfu_instance_t *i) +{ + uint32_t y; + stfu_frame_t *frame = NULL; + + if (stfu_log != null_logger && i->debug) { + stfu_log(STFU_LOG_EMERG, "%s OUT QUEUE: ------------\n", i->name); + for(y = 0; y < i->out_queue->array_len; y++) { + frame = &i->out_queue->array[y]; + stfu_log(STFU_LOG_EMERG, "%s\t%u:%u r:%d\n", i->name, frame->ts, frame->ts / i->samples_per_packet, frame->was_read); + } + stfu_log(STFU_LOG_EMERG, "%s\n\n", i->name); + stfu_log(STFU_LOG_EMERG, "%s IN QUEUE: ------------\n", i->name); + for(y = 0; y < i->in_queue->array_len; y++) { + frame = &i->in_queue->array[y]; + stfu_log(STFU_LOG_EMERG, "%s\t%u:%u r:%d\n", i->name, frame->ts, frame->ts / i->samples_per_packet, frame->was_read); + } + stfu_log(STFU_LOG_EMERG, "%s\n\n\n", i->name); + } +} + + stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i) { stfu_frame_t *rframe = NULL; @@ -769,9 +894,6 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i) if (!found && i->samples_per_packet) { - uint32_t y; - stfu_frame_t *frame = NULL; - int32_t delay = i->cur_ts - i->last_rd_ts; uint32_t need = abs(delay) / i->samples_per_packet; @@ -789,28 +911,12 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i) i->packet_count = 0; } - if (stfu_log != null_logger && i->debug) { - stfu_log(STFU_LOG_EMERG, "%s ------------\n", i->name); - for(y = 0; y < i->out_queue->array_len; y++) { - frame = &i->out_queue->array[y]; - stfu_log(STFU_LOG_EMERG, "%s\t%u:%u\n", i->name, frame->ts, frame->ts / i->samples_per_packet); - } - stfu_log(STFU_LOG_EMERG, "%s ------------\n\n\n", i->name); - - - stfu_log(STFU_LOG_EMERG, "%s ------------\n", i->name); - for(y = 0; y < i->in_queue->array_len; y++) { - frame = &i->in_queue->array[y]; - stfu_log(STFU_LOG_EMERG, "%s\t%u:%u\n", i->name, frame->ts, frame->ts / i->samples_per_packet); - } - stfu_log(STFU_LOG_EMERG, "%s\n\n\n", i->name); - - } + stfu_n_dump(i); } - if (stfu_log != null_logger && i->debug) { + if (stfu_log != null_logger && (i->debug & DBG_OUT)) { if (found) { - stfu_log(STFU_LOG_EMERG, "%s OUT: %u:%u %u\n", i->name, rframe->ts, rframe->ts / i->samples_per_packet, rframe->plc); + stfu_log(STFU_LOG_EMERG, "O: %s %u:%u %u\n", i->name, rframe->ts, rframe->ts / i->samples_per_packet, rframe->plc); } } @@ -856,7 +962,9 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i) } else { if (force) { - stfu_log(STFU_LOG_EMERG, "%s NO PACKETS HARD RESETTING\n", i->name); + if (stfu_log != null_logger && i->debug) { + stfu_log(STFU_LOG_EMERG, "%s NO PACKETS HARD RESETTING\n", i->name); + } stfu_n_reset(i); } else { i->last_wr_ts = i->cur_ts; diff --git a/src/switch_utils.c b/src/switch_utils.c index f57ea00c4e..3cde97a127 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -1231,6 +1231,25 @@ SWITCH_DECLARE(switch_bool_t) switch_is_number(const char *str) return r; } +SWITCH_DECLARE(switch_bool_t) switch_is_leading_number(const char *str) +{ + const char *p; + switch_bool_t r = SWITCH_FALSE; + + if (*str == '-' || *str == '+') { + str++; + } + + for (p = str; p && *p; p++) { + if ((*p == '.' || (*p > 47 && *p < 58))) { + r = SWITCH_TRUE; + break; + } + } + + return r; +} + SWITCH_DECLARE(const char *) switch_stristr(const char *instr, const char *str) { /*