Merge remote-tracking branch 'GitHub-FS/master'

This commit is contained in:
rance 2021-03-18 21:52:07 +00:00
commit b796f8639a
56 changed files with 1500 additions and 612 deletions

View File

@ -0,0 +1,22 @@
<configuration name="amrwb.conf">
<settings>
<!-- AMRWB modes (supported bitrates):
mode 8 AMR-WB_23.85 23.85 Kbit/s
mode 7 AMR-WB_23.05 23.05 Kbit/s
mode 7 AMR-WB_19.85 19.85 Kbit/s
mode 6 AMR-WB_18.25 18.25 Kbit/s
mode 5 AMR-WB_15.85 15.85 Kbit/s
mode 4 AMR-WB_14.25 14.25 Kbit/s
mode 3 AMR-WB_12.65 12.65 Kbit/s
mode 2 AMR-WB_8.85 8.85 Kbit/s
mode 1 AMR-WB_6.60 6.60 Kbit/s
-->
<param name="default-bitrate" value="8"/>
<!-- Enable VoLTE specific FMTP -->
<param name="volte" value="1"/>
<!-- Enable automatic bitrate variation during the call based on RTCP feedback -->
<param name="adjust-bitrate" value="0"/>
<!-- force OA when originating -->
<param name="force-oa" value="0"/>
</settings>
</configuration>

View File

@ -15,5 +15,7 @@
<param name="volte" value="0"/>
<!-- Enable automatic bitrate variation during the call based on RTCP feedback -->
<param name="adjust-bitrate" value="0"/>
<!-- force OA when originating -->
<param name="force-oa" value="0"/>
</settings>
</configuration>

View File

@ -1,7 +1,22 @@
<configuration name="amrwb.conf">
<settings>
<param name="default-bitrate" value="8"/>
<param name="volte" value="1"/>
<param name="adjust-bitrate" value="0"/>
<settings>
<!-- AMRWB modes (supported bitrates):
mode 8 AMR-WB_23.85 23.85 Kbit/s
mode 7 AMR-WB_23.05 23.05 Kbit/s
mode 7 AMR-WB_19.85 19.85 Kbit/s
mode 6 AMR-WB_18.25 18.25 Kbit/s
mode 5 AMR-WB_15.85 15.85 Kbit/s
mode 4 AMR-WB_14.25 14.25 Kbit/s
mode 3 AMR-WB_12.65 12.65 Kbit/s
mode 2 AMR-WB_8.85 8.85 Kbit/s
mode 1 AMR-WB_6.60 6.60 Kbit/s
-->
<param name="default-bitrate" value="8"/>
<!-- Enable VoLTE specific FMTP -->
<param name="volte" value="1"/>
<!-- Enable automatic bitrate variation during the call based on RTCP feedback -->
<param name="adjust-bitrate" value="0"/>
<!-- force OA when originating -->
<param name="force-oa" value="0"/>
</settings>
</configuration>

View File

@ -1,297 +0,0 @@
%define ver %{VERSION_NUMBER}
%define rel %{RELEASE_NUMBER}
Name: erlang
Version: %{ver}
Release: %{rel}.1%{?dist}
Summary: General-purpose programming language and runtime environment
Group: Development/Languages
License: ERPL
URL: http://www.erlang.org
Source: http://www.erlang.org/download/otp_src_R14B03.tar.gz
Source1: http://www.erlang.org/download/otp_doc_html_R14B03.tar.gz
Source2: http://www.erlang.org/download/otp_doc_man_R14B03.tar.gz
Patch1: otp-R14B-00-0001-Do-not-format-man-pages.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: ncurses-devel
BuildRequires: openssl-devel
BuildRequires: unixODBC-devel
BuildRequires: tcl-devel
BuildRequires: tk-devel
BuildRequires: gd-devel
# BuildRequires: jdk
BuildRequires: flex
BuildRequires: m4
Requires: tk
# Added virtual Provides for each erlang module
Provides: erlang-appmon = %{version}-%{release}
Provides: erlang-asn1 = %{version}-%{release}
Provides: erlang-common_test = %{version}-%{release}
Provides: erlang-compiler = %{version}-%{release}
Provides: erlang-cosEvent = %{version}-%{release}
Provides: erlang-cosEventDomain = %{version}-%{release}
Provides: erlang-cosFileTransfer = %{version}-%{release}
Provides: erlang-cosNotification = %{version}-%{release}
Provides: erlang-cosProperty = %{version}-%{release}
Provides: erlang-cosTime = %{version}-%{release}
Provides: erlang-cosTransactions = %{version}-%{release}
Provides: erlang-crypto = %{version}-%{release}
Provides: erlang-debugger = %{version}-%{release}
Provides: erlang-dialyzer = %{version}-%{release}
Provides: erlang-docbuilder = %{version}-%{release}
Provides: erlang-edoc = %{version}-%{release}
Provides: erlang-erts = %{version}-%{release}
Provides: erlang-et = %{version}-%{release}
Provides: erlang-eunit = %{version}-%{release}
Provides: erlang-gs = %{version}-%{release}
Provides: erlang-hipe = %{version}-%{release}
Provides: erlang-ic = %{version}-%{release}
Provides: erlang-inets = %{version}-%{release}
Provides: erlang-inviso = %{version}-%{release}
Provides: erlang-kernel = %{version}-%{release}
Provides: erlang-megaco = %{version}-%{release}
Provides: erlang-mnesia = %{version}-%{release}
Provides: erlang-observer = %{version}-%{release}
Provides: erlang-odbc = %{version}-%{release}
Provides: erlang-orber = %{version}-%{release}
Provides: erlang-os_mon = %{version}-%{release}
Provides: erlang-otp_mibs = %{version}-%{release}
Provides: erlang-parsetools = %{version}-%{release}
Provides: erlang-percept = %{version}-%{release}
Provides: erlang-pman = %{version}-%{release}
Provides: erlang-public_key = %{version}-%{release}
Provides: erlang-runtime_tools = %{version}-%{release}
Provides: erlang-sasl = %{version}-%{release}
Provides: erlang-snmp = %{version}-%{release}
Provides: erlang-ssh = %{version}-%{release}
Provides: erlang-ssl = %{version}-%{release}
Provides: erlang-stdlib = %{version}-%{release}
Provides: erlang-syntax_tools = %{version}-%{release}
Provides: erlang-test_server = %{version}-%{release}
Provides: erlang-toolbar = %{version}-%{release}
Provides: erlang-tools = %{version}-%{release}
Provides: erlang-tv = %{version}-%{release}
Provides: erlang-typer = %{version}-%{release}
Provides: erlang-webtool = %{version}-%{release}
Provides: erlang-xmerl = %{version}-%{release}
%description
Erlang is a general-purpose programming language and runtime
environment. Erlang has built-in support for concurrency, distribution
and fault tolerance. Erlang is used in several large telecommunication
systems from Ericsson.
%package doc
Summary: Erlang documentation
Group: Development/Languages
%description doc
Documentation for Erlang.
%prep
%setup -q -n otp_src_%{ver}%{rel}
#%setup -q -n otp_src_%{ver}
%build
# WARN: --enable-dynamic-ssl-lib needed for preventing strange messages about missing dependencies on EPEL
# see https://bugzilla.redhat.com/458646 and https://bugzilla.redhat.com/499525
%ifarch sparcv9 sparc64
CFLAGS="$RPM_OPT_FLAGS -mcpu=ultrasparc -fno-strict-aliasing" %configure --enable-dynamic-ssl-lib
%else
CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing" %configure --enable-dynamic-ssl-lib
%endif
chmod -R u+w .
make
%install
rm -rf $RPM_BUILD_ROOT
make INSTALL_PREFIX=$RPM_BUILD_ROOT install
# clean up
find $RPM_BUILD_ROOT%{_libdir}/erlang -perm 0775 | xargs chmod 755
find $RPM_BUILD_ROOT%{_libdir}/erlang -name Makefile | xargs chmod 644
find $RPM_BUILD_ROOT%{_libdir}/erlang -name \*.o | xargs chmod 644
find $RPM_BUILD_ROOT%{_libdir}/erlang -name \*.bat | xargs rm -f
find $RPM_BUILD_ROOT%{_libdir}/erlang -name index.txt.old | xargs rm -f
# doc
mkdir -p erlang_doc
tar -C erlang_doc -zxf %{SOURCE1}
tar -C $RPM_BUILD_ROOT/%{_libdir}/erlang -zxf %{SOURCE2}
# make links to binaries
#mkdir -p $RPM_BUILD_ROOT/%{_bindir}
#cd $RPM_BUILD_ROOT/%{_bindir}
#for file in erl erlc escript dialyzer
#do
# ln -sf ../%{_lib}/erlang/bin/$file .
#done
# remove buildroot from installed files
cd $RPM_BUILD_ROOT/%{_libdir}/erlang
sed -i "s|$RPM_BUILD_ROOT||" erts*/bin/{erl,start} releases/RELEASES bin/{erl,start}
%clean
rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
%doc AUTHORS EPLICENCE README.md
%{_bindir}/*
%{_libdir}/erlang
%files doc
%defattr(-,root,root)
%doc erlang_doc/*
%post
%{_libdir}/erlang/Install -minimal %{_libdir}/erlang >/dev/null 2>/dev/null
%changelog
* Wed Sep 29 2010 Anthony Molinaro <anthony.molinaro@openx.org> - R14B-00.1
- modified R13B04 spec to work with R14B
* Wed Jul 7 2010 Anthony Molinaro <anthony.molinaro@openx.org> - R13B-04.1
- modified the R12B spec to work with R13B04
* Mon Jun 7 2010 Peter Lemenkov <lemenkov@gmail.com> - R12B-5.10
- Added missing virtual provides erlang-erts
* Tue May 25 2010 Peter Lemenkov <lemenkov@gmail.com> - R12B-5.9
- Use java-1.4.2 only for EL-[45]
- Added virtual provides for each erlang module
- Small typo fix
* Mon Apr 19 2010 Peter Lemenkov <lemenkov@gmail.com> - R12B-5.8
- Patches rebased
- Added patches 6,7 from trunk
- Use %%configure
* Tue Apr 21 2009 Debarshi Ray <rishi@fedoraproject.org> R12B-5.7
- Updated rpath patch.
- Fixed configure to respect $RPM_OPT_FLAGS.
* Sun Mar 1 2009 Gerard Milmeister <gemi@bluewin.ch> - R12B-5.6
- new release R12B-5
- link escript and dialyzer to %{_bindir}
* Tue Feb 24 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - R12B-5.5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
* Sat Feb 14 2009 Dennis Gilmore <dennis@ausil.us> - R12B-4.5
- fix sparc arches to compile
* Fri Jan 16 2009 Tomas Mraz <tmraz@redhat.com> - R12B-4.4
- rebuild with new openssl
* Sat Oct 25 2008 Gerard Milmeister <gemi@bluewin.ch> - R12B-4.1
- new release R12B-4
* Fri Sep 5 2008 Gerard Milmeister <gemi@bluewin.ch> - R12B-3.3
- fixed sslrpath patch
* Thu Jul 17 2008 Tom "spot" Callaway <tcallawa@redhat.com> - R12B-3.2
- fix license tag
* Sun Jul 6 2008 Gerard Milmeister <gemi@bluewin.ch> - R12B-3.1
- new release R12B-3
* Thu Mar 27 2008 Gerard Milmeister <gemi@bluewin.ch> - R12B-1.1
- new release R12B-1
* Sat Feb 23 2008 Gerard Milmeister <gemi@bluewin.ch> - R12B-0.3
- disable strict aliasing optimization
* Mon Feb 18 2008 Fedora Release Engineering <rel-eng@fedoraproject.org> - R12B-0.2
- Autorebuild for GCC 4.3
* Sat Dec 8 2007 Gerard Milmeister <gemi@bluewin.ch> - R12B-0.1
- new release R12B-0
* Wed Dec 05 2007 Release Engineering <rel-eng at fedoraproject dot org> - R11B-6
- Rebuild for deps
* Sun Aug 19 2007 Gerard Milmeister <gemi@bluewin.ch> - R11B-5.3
- fix some permissions
* Sat Aug 18 2007 Gerard Milmeister <gemi@bluewin.ch> - R11B-5.2
- enable dynamic linking for ssl
* Sat Aug 18 2007 Gerard Milmeister <gemi@bluewin.ch> - R11B-5.1
- new release R11B-5
* Sat Mar 24 2007 Thomas Fitzsimmons <fitzsim@redhat.com> - R11B-2.4
- Require java-1.5.0-gcj-devel for build.
* Sun Dec 31 2006 Gerard Milmeister <gemi@bluewin.ch> - R11B-2.3
- remove buildroot from installed files
* Sat Dec 30 2006 Gerard Milmeister <gemi@bluewin.ch> - R11B-2.2
- added patch for compiling with glibc 2.5
* Sat Dec 30 2006 Gerard Milmeister <gemi@bluewin.ch> - R11B-2.1
- new version R11B-2
* Mon Aug 28 2006 Gerard Milmeister <gemi@bluewin.ch> - R11B-0.3
- Rebuild for FE6
* Wed Jul 5 2006 Gerard Milmeister <gemi@bluewin.ch> - R11B-0.2
- add BR m4
* Thu May 18 2006 Gerard Milmeister <gemi@bluewin.ch> - R11B-0.1
- new version R11B-0
* Wed May 3 2006 Gerard Milmeister <gemi@bluewin.ch> - R10B-10.3
- added patch for run_erl by Knut-Håvard Aksnes
* Mon Mar 13 2006 Gerard Milmeister <gemi@bluewin.ch> - R10B-10.1
- new version R10B-10
* Thu Dec 29 2005 Gerard Milmeister <gemi@bluewin.ch> - R10B-9.1
- New Version R10B-9
* Sat Oct 29 2005 Gerard Milmeister <gemi@bluewin.ch> - R10B-8.2
- updated rpath patch
* Sat Oct 29 2005 Gerard Milmeister <gemi@bluewin.ch> - R10B-8.1
- New Version R10B-8
* Sat Oct 1 2005 Gerard Milmeister <gemi@bluewin.ch> - R10B-6.4
- Added tk-devel and tcl-devel to buildreq
- Added tk to req
* Tue Sep 6 2005 Gerard Milmeister <gemi@bluewin.ch> - R10B-6.3
- Remove perl BuildRequires
* Tue Aug 30 2005 Gerard Milmeister <gemi@bluewin.ch> - R10B-6.2
- change /usr/lib to %%{_libdir}
- redirect output in %%post to /dev/null
- add unixODBC-devel to BuildRequires
- split doc off to erlang-doc package
* Sat Jun 25 2005 Gerard Milmeister <gemi@bluewin.ch> - R10B-6.1
- New Version R10B-6
* Sun Feb 13 2005 Gerard Milmeister <gemi@bluewin.ch> - R10B-3.1
- New Version R10B-3
* Mon Dec 27 2004 Gerard Milmeister <gemi@bluewin.ch> - 0:R10B-2-0.fdr.1
- New Version R10B-2
* Wed Oct 6 2004 Gerard Milmeister <gemi@bluewin.ch> - 0:R10B-0.fdr.1
- New Version R10B
* Thu Oct 16 2003 Gerard Milmeister <gemi@bluewin.ch> - 0:R9B-1.fdr.1
- First Fedora release

View File

@ -37,7 +37,6 @@
%define build_mod_esl 0
%define build_mod_rayo 1
%define build_mod_ssml 1
%define build_mod_shout 1
%define build_mod_opusfile 0
%define build_mod_v8 0
@ -47,7 +46,6 @@
%{?with_py26_esl:%define build_py26_esl 1 }
%{?with_timerfd:%define build_timerfd 1 }
%{?with_mod_esl:%define build_mod_esl 1 }
%{?with_mod_shout:%define build_mod_shout 1 }
%{?with_mod_opusfile:%define build_mod_opusfile 1 }
%{?with_mod_v8:%define build_mod_v8 1 }
@ -176,6 +174,9 @@ Requires: libsndfile
PreReq: %insserv_prereq %fillup_prereq
%endif
%if 0%{?fedora}
BuildRequires: gumbo-parser-devel
%endif
######################################################################################################################
#
@ -1078,7 +1079,6 @@ Mod shell stream is a FreeSWITCH module to allow you to stream audio from an
arbitrary shell command. You could use it to read audio from a database, from
a soundcard, etc.
%if %{build_mod_shout}
%package format-mod-shout
Summary: Implements Media Steaming from arbitrary shell commands for the FreeSWITCH open source telephony platform
Group: System/Libraries
@ -1093,7 +1093,6 @@ BuildRequires: lame-devel
%description format-mod-shout
Mod Shout is a FreeSWITCH module to allow you to stream audio from MP3s or a i
shoutcast stream.
%endif
%if %{build_mod_opusfile}
%package format-mod-opusfile
@ -1503,10 +1502,7 @@ EVENT_HANDLERS_MODULES+=" event_handlers/mod_rayo"
#
######################################################################################################################
FORMATS_MODULES="formats/mod_local_stream formats/mod_native_file formats/mod_portaudio_stream \
formats/mod_shell_stream formats/mod_sndfile formats/mod_tone_stream"
%if %{build_mod_shout}
FORMATS_MODULES+=" formats/mod_shout "
%endif
formats/mod_shell_stream formats/mod_shout formats/mod_sndfile formats/mod_tone_stream"
%if %{build_mod_ssml}
FORMATS_MODULES+=" formats/mod_ssml"
%endif
@ -1622,6 +1618,7 @@ autoreconf --force --install
--with-odbc \
--with-erlang \
--with-openssl \
--enable-zrtp \
%{?configure_options}
unset MODULES
@ -1645,6 +1642,7 @@ cd libs/esl
%{__mkdir} -p %{buildroot}%{prefix}/log
%{__mkdir} -p %{buildroot}%{logfiledir}
%{__mkdir} -p %{buildroot}%{runtimedir}
%{__mkdir} -p %{buildroot}%{_localstatedir}/cache/freeswitch
#install the esl stuff
cd libs/esl
@ -2073,6 +2071,7 @@ fi
%{MODINSTDIR}/mod_httapi.so*
%files application-http-cache
%dir %attr(0750, freeswitch, daemon) %{_localstatedir}/cache/freeswitch
%{MODINSTDIR}/mod_http_cache.so*
%files application-lcr
@ -2324,10 +2323,8 @@ fi
%files format-shell-stream
%{MODINSTDIR}/mod_shell_stream.so*
%if %{build_mod_shout}
%files format-mod-shout
%{MODINSTDIR}/mod_shout.so*
%endif
%if %{build_mod_ssml}
%files format-ssml
@ -2344,18 +2341,15 @@ fi
######################################################################################################################
%files lua
%{MODINSTDIR}/mod_lua*.so*
%dir %attr(0750, freeswitch, daemon) %{sysconfdir}/autoload_configs
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/lua.conf.xml
%files perl
%{MODINSTDIR}/mod_perl*.so*
%{prefix}/perl/*
%dir %attr(0750, freeswitch, daemon) %{sysconfdir}/autoload_configs
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/perl.conf.xml
%files python
%{MODINSTDIR}/mod_python*.so*
%dir %attr(0750, freeswitch, daemon) %{sysconfdir}/autoload_configs
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/python.conf.xml
%if %{build_mod_v8}
@ -2365,7 +2359,6 @@ fi
%{LIBDIR}/libicui18n.so
%{LIBDIR}/libicuuc.so
%endif
%dir %attr(0750, freeswitch, daemon) %{sysconfdir}/autoload_configs
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/v8.conf.xml
######################################################################################################################

View File

@ -132,6 +132,7 @@ struct switch_core_session {
switch_mutex_t *mutex;
switch_mutex_t *stack_count_mutex;
switch_mutex_t *resample_mutex;
switch_mutex_t *codec_init_mutex;
switch_mutex_t *codec_read_mutex;
switch_mutex_t *codec_write_mutex;
switch_mutex_t *video_codec_read_mutex;

View File

@ -854,8 +854,8 @@ struct switch_json_api_interface {
struct switch_json_api_interface *next;
};
#define PROTECT_INTERFACE(_it) if (_it) {switch_mutex_lock(_it->reflock); switch_thread_rwlock_rdlock(_it->parent->rwlock); switch_thread_rwlock_rdlock(_it->rwlock); _it->refs++; _it->parent->refs++; switch_mutex_unlock(_it->reflock);} //if (!strcmp(_it->interface_name, "user")) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "+++++++++++LOCK %s %d/%d\n", _it->interface_name, _it->refs, _it->parent->refs);
#define UNPROTECT_INTERFACE(_it) if (_it) {switch_mutex_lock(_it->reflock); switch_thread_rwlock_unlock(_it->rwlock); switch_thread_rwlock_unlock(_it->parent->rwlock); _it->refs--; _it->parent->refs--; switch_mutex_unlock(_it->reflock);} //if (!strcmp(_it->interface_name, "user")) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "---------UNLOCK %s %d/%d\n", _it->interface_name, _it->refs, _it->parent->refs);
#define PROTECT_INTERFACE(_it) if (_it) {switch_thread_rwlock_rdlock(_it->parent->rwlock); switch_thread_rwlock_rdlock(_it->rwlock); switch_mutex_lock(_it->reflock); _it->refs++; _it->parent->refs++; switch_mutex_unlock(_it->reflock);} //if (!strcmp(_it->interface_name, "user")) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "+++++++++++LOCK %s %d/%d\n", _it->interface_name, _it->refs, _it->parent->refs);
#define UNPROTECT_INTERFACE(_it) if (_it) {switch_mutex_lock(_it->reflock); _it->refs--; _it->parent->refs--; switch_mutex_unlock(_it->reflock); switch_thread_rwlock_unlock(_it->rwlock); switch_thread_rwlock_unlock(_it->parent->rwlock);} //if (!strcmp(_it->interface_name, "user")) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "---------UNLOCK %s %d/%d\n", _it->interface_name, _it->refs, _it->parent->refs);
#include "switch_frame.h"

View File

@ -66,6 +66,23 @@ SWITCH_DECLARE(uint32_t) switch_scheduler_add_task(time_t task_runtime,
switch_scheduler_func_t func,
const char *desc, const char *group, uint32_t cmd_id, void *cmd_arg, switch_scheduler_flag_t flags);
/*!
\brief Schedule a task in the future
\param task_runtime the time in epoch seconds to execute the task.
\param func the callback function to execute when the task is executed.
\param desc an arbitrary description of the task.
\param group a group id tag to link multiple tasks to a single entity.
\param cmd_id an arbitrary index number be used in the callback.
\param cmd_arg user data to be passed to the callback.
\param flags flags to alter behaviour
\param task_id pointer to put the id of the task to
\return the id of the task
*/
SWITCH_DECLARE(uint32_t) switch_scheduler_add_task_ex(time_t task_runtime,
switch_scheduler_func_t func,
const char *desc, const char *group, uint32_t cmd_id, void *cmd_arg, switch_scheduler_flag_t flags, uint32_t *task_id);
/*!
\brief Delete a scheduled task
\param task_id the id of the task

View File

@ -353,7 +353,8 @@ typedef enum {
ED_BRIDGE_READ = (1 << 4),
ED_BRIDGE_WRITE = (1 << 5),
ED_TAP_READ = (1 << 6),
ED_TAP_WRITE = (1 << 7)
ED_TAP_WRITE = (1 << 7),
ED_STEREO = (1 << 8)
} switch_eavesdrop_flag_enum_t;
typedef uint32_t switch_eavesdrop_flag_t;
@ -1415,6 +1416,7 @@ CF_HOLD_BLEG - B leg is on hold
CF_SERVICE - Channel has a service thread
CF_TAGGED - Channel is tagged
CF_WINNER - Channel is the winner
CF_REUSE_CALLER_PROFILE - Channel reuse caller profile
CF_CONTROLLED - Channel is under control
CF_PROXY_MODE - Channel has no media
CF_SUSPEND - Suspend i/o
@ -1467,6 +1469,7 @@ typedef enum {
CF_SERVICE,
CF_TAGGED,
CF_WINNER,
CF_REUSE_CALLER_PROFILE,
CF_CONTROLLED,
CF_PROXY_MODE,
CF_PROXY_OFF,

View File

@ -1716,6 +1716,12 @@ fct_clp__parse(fct_clp_t *clp, int argc, char const *argv[])
arg =NULL;
}
}
if (arg != NULL)
{
free(arg);
arg = NULL;
}
}

View File

@ -141,7 +141,7 @@ static switch_status_t fst_init_core_and_modload(const char *confdir, const char
*/
#define fst_session_park(session) \
switch_ivr_park_session(session); \
switch_channel_wait_for_state(switch_core_session_get_channel(session), NULL, CS_PARK);
switch_channel_wait_for_flag(switch_core_session_get_channel(session), CF_PARK, SWITCH_TRUE, 10000, NULL);
/**
* check for test requirement - execute teardown on failure

View File

@ -110,7 +110,7 @@ static void dump_encoder_ctx(AVCodecContext *ctx)
#ifdef DUMP_ENCODER_CTX
#define STRINGIFY(x) #x
#define my_dump_int(x) switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, STRINGIFY(x) " = %d\n", ctx->x);
#define my_dump_int64(x) switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, STRINGIFY(x) " = % " SWITCH_INT64_T_FMT "\n", ctx->x);
#define my_dump_int64(x) switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, STRINGIFY(x) " = %" SWITCH_INT64_T_FMT "\n", ctx->x);
#define my_dump_float(x) switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, STRINGIFY(x) " = %f\n", ctx->x);
#define my_dump_enum(x) switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, STRINGIFY(x) " = %d\n", ctx->x);
#define my_dump_uint(x) switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, STRINGIFY(x) " = 0x%x\n", ctx->x);

View File

@ -702,7 +702,7 @@ GCC_DIAG_ON(deprecated-declarations)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "sample_rate: %d nb_samples: %d\n", mst->frame->sample_rate, mst->frame->nb_samples);
if (c->sample_fmt != AV_SAMPLE_FMT_S16) {
if (c->sample_fmt != AV_SAMPLE_FMT_S16 || c->sample_rate != mst->sample_rate) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "sample_fmt %d != AV_SAMPLE_FMT_S16, start resampler\n", c->sample_fmt);
mst->resample_ctx = swr_alloc();
@ -1231,7 +1231,7 @@ GCC_DIAG_ON(deprecated-declarations)
context->audio_st[1].sample_rate = handle->samplerate;
GCC_DIAG_OFF(deprecated-declarations)
if (context->audio_st[0].st->codec->sample_fmt != AV_SAMPLE_FMT_S16) {
if (context->audio_st[0].st->codec->sample_fmt != AV_SAMPLE_FMT_S16 || context->audio_st[0].st->codec->sample_rate != handle->samplerate) {
GCC_DIAG_ON(deprecated-declarations)
int x;
for (x = 0; x < context->has_audio && x < 2 && c[x]; x++) {

View File

@ -998,7 +998,7 @@ cc_status_t cc_agent_update(const char *key, const char *value, const char *agen
{
cc_status_t result = CC_STATUS_SUCCESS;
char *sql;
char res[256];
char res[256] = "";
switch_event_t *event;
/* Check to see if agent already exist */

View File

@ -799,7 +799,7 @@ SWITCH_STANDARD_APP(curl_app_function)
switch_channel_t *channel = switch_core_session_get_channel(session);
char *url = NULL;
char *method = NULL;
char *postdata = NULL;
char *postdata = "";
char *content_type = NULL;
switch_bool_t do_headers = SWITCH_FALSE;
switch_bool_t do_json = SWITCH_FALSE;
@ -920,7 +920,7 @@ SWITCH_STANDARD_API(curl_function)
char *mydata = NULL;
char *url = NULL;
char *method = NULL;
char *postdata = NULL;
char *postdata = "";
char *content_type = NULL;
switch_bool_t do_headers = SWITCH_FALSE;
switch_bool_t do_json = SWITCH_FALSE;

View File

@ -1150,6 +1150,13 @@ SWITCH_STANDARD_APP(break_function)
}
}
SWITCH_STANDARD_APP(reuse_caller_profile_function)
{
switch_channel_t *channel;
channel = switch_core_session_get_channel(session);
switch_channel_set_flag(channel, CF_REUSE_CALLER_PROFILE);
}
SWITCH_STANDARD_APP(queue_dtmf_function)
{
switch_channel_queue_dtmf_string(switch_core_session_get_channel(session), (const char *) data);
@ -6551,6 +6558,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "deflect", "Send call deflect", "Send a call deflect.", deflect_function, "<deflect_data>", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "recovery_refresh", "Send call recovery_refresh", "Send a call recovery_refresh.", recovery_refresh_function, "", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "reuse_caller_profile", "Reuse the caller profile", "Reuse the caller profile", reuse_caller_profile_function, "", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "queue_dtmf", "Queue dtmf to be sent", "Queue dtmf to be sent from a session", queue_dtmf_function, "<dtmf_data>",
SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "send_dtmf", "Send dtmf to be sent", "Send dtmf to be sent from a session", send_dtmf_function, "<dtmf_data>",

View File

@ -496,6 +496,9 @@ switch_status_t ldns_lookup(const char *number, const char *root, char *server_n
if (!added_server) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No Nameservers specified, using host default\n");
/* create a new resolver from /etc/resolv.conf */
if (res) {
ldns_resolver_free(res);
}
s = ldns_resolver_new_frm_file(&res, NULL);
}

View File

@ -1534,6 +1534,7 @@ static switch_status_t httapi_sync(client_t *client)
char *q, *p = strstr(dynamic_url, "://");
use_url++;
switch_safe_free(dup_creds);
dup_creds = strdup(p+3);
*p = '\0';

View File

@ -144,10 +144,12 @@ static char* aws_s3_signature_key(char* key_signing, switch_aws_s3_profile* aws_
char key_service[SHA256_DIGEST_LENGTH];
char* aws4_secret_access_key = switch_mprintf("AWS4%s", aws_s3_profile->access_key_secret);
hmac256(key_date, SHA256_DIGEST_LENGTH, aws4_secret_access_key, strlen(aws4_secret_access_key), aws_s3_profile->date_stamp);
hmac256(key_region, SHA256_DIGEST_LENGTH, key_date, SHA256_DIGEST_LENGTH, aws_s3_profile->region);
hmac256(key_service, SHA256_DIGEST_LENGTH, key_region, SHA256_DIGEST_LENGTH, "s3");
hmac256(key_signing, SHA256_DIGEST_LENGTH, key_service, SHA256_DIGEST_LENGTH, "aws4_request");
if (!hmac256(key_date, SHA256_DIGEST_LENGTH, aws4_secret_access_key, (unsigned int)strlen(aws4_secret_access_key), aws_s3_profile->date_stamp)
|| !hmac256(key_region, SHA256_DIGEST_LENGTH, key_date, SHA256_DIGEST_LENGTH, aws_s3_profile->region)
|| !hmac256(key_service, SHA256_DIGEST_LENGTH, key_region, SHA256_DIGEST_LENGTH, "s3")
|| !hmac256(key_signing, SHA256_DIGEST_LENGTH, key_service, SHA256_DIGEST_LENGTH, "aws4_request")) {
key_signing = NULL;
}
switch_safe_free(aws4_secret_access_key);
@ -166,7 +168,7 @@ static char* aws_s3_standardized_query_string(switch_aws_s3_profile* aws_s3_prof
char* standardized_query_string;
credential = switch_mprintf("%s%%2F%s%%2F%s%%2Fs3%%2Faws4_request", aws_s3_profile->access_key_id, aws_s3_profile->date_stamp, aws_s3_profile->region);
switch_snprintf(expires, 9, "%ld", aws_s3_profile->expires);
switch_snprintf(expires, 9, "%" SWITCH_TIME_T_FMT, aws_s3_profile->expires);
standardized_query_string = switch_mprintf(
"X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=%s&X-Amz-Date=%s&X-Amz-Expires=%s&X-Amz-SignedHeaders=host",
@ -243,13 +245,14 @@ static char *aws_s3_authentication_create(switch_aws_s3_profile* aws_s3_profile)
string_to_sign = aws_s3_string_to_sign(standardized_request, aws_s3_profile);
// Get signature_key
aws_s3_signature_key(signature_key, aws_s3_profile);
// Get signature
hmac256_hex(signature, signature_key, SHA256_DIGEST_LENGTH, string_to_sign);
// Build final query string
query_param = switch_mprintf("%s&X-Amz-Signature=%s", standardized_query_string, signature);
if (!aws_s3_signature_key(signature_key, aws_s3_profile)
// Get signature
|| !hmac256_hex(signature, signature_key, SHA256_DIGEST_LENGTH, string_to_sign)) {
query_param = NULL;
} else {
// Build final query string
query_param = switch_mprintf("%s&X-Amz-Signature=%s", standardized_query_string, signature);
}
switch_safe_free(string_to_sign);
switch_safe_free(standardized_query_string);

View File

@ -1186,6 +1186,8 @@ static switch_status_t lcr_load_config()
if (db_check("ALTER TABLE carrier_gateway add codec varchar(255);") == SWITCH_TRUE) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "adding codec field your lcr carrier_gateway database schema.\n");
} else {
switch_safe_free(order_by.data);
switch_safe_free(sql_stream.data);
switch_goto_status(SWITCH_STATUS_FALSE, done);
}
}
@ -1197,6 +1199,8 @@ static switch_status_t lcr_load_config()
if (db_check("ALTER TABLE lcr add cid varchar(32);") == SWITCH_TRUE) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "adding cid field to your lcr database schema.\n");
} else {
switch_safe_free(order_by.data);
switch_safe_free(sql_stream.data);
switch_goto_status(SWITCH_STATUS_FALSE, done);
}
}
@ -1205,6 +1209,8 @@ static switch_status_t lcr_load_config()
if (db_check("ALTER TABLE lcr ADD lrn BOOLEAN NOT NULL DEFAULT false")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "adding lrn field to your lcr database schema.\n");
} else {
switch_safe_free(order_by.data);
switch_safe_free(sql_stream.data);
switch_goto_status(SWITCH_STATUS_FALSE, done);
}
}

View File

@ -698,6 +698,7 @@ SWITCH_LIMIT_RELEASE(mod_mongo_limit_release)
if (mod_mongo_increment(session, (const char *)p_key, -1, 0, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Couldn't decrement %s\n", (const char *)p_key);
status = SWITCH_STATUS_FALSE;
free(hi);
break;
} else {
switch_core_hash_delete(pvt->resources, (const char *) p_key);

View File

@ -197,11 +197,13 @@ SWITCH_LIMIT_RELEASE(limit_release_redis)
if (credis_decr(redis, (const char*)p_key, &val) != 0) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Couldn't decrement value corresponding to %s\n", (char *)p_key);
free(hi);
switch_goto_status(SWITCH_STATUS_FALSE, end);
}
p_uuid_key = switch_core_session_sprintf(session, "%s_%s", switch_core_get_switchname(), (char *)p_key);
if (credis_decr(redis,p_uuid_key,&uuid_val) != 0) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Couldn't decrement value corresponding to %s\n", p_uuid_key);
free(hi);
switch_goto_status(SWITCH_STATUS_FALSE, end);
}
switch_core_hash_delete(pvt->hash, (const char *) p_key);

View File

@ -143,7 +143,7 @@ SWITCH_STANDARD_API(snom_command_api_function)
}
if (switch_inet_pton(AF_INET, argv[0], &ip)) {
strncpy(host, argv[0], sizeof(host));
snprintf(host, sizeof(host), "%s", argv[0]);
} else {
char *sql = NULL;
char *ret = NULL;

View File

@ -970,7 +970,7 @@ SWITCH_STANDARD_APP(video_replace_start_function)
return;
}
switch_channel_wait_for_flag(channel, CF_VIDEO_READY, SWITCH_TRUE, 10000, NULL);
// switch_channel_wait_for_flag(channel, CF_VIDEO_READY, SWITCH_TRUE, 10000, NULL);
context = (video_replace_context_t *) switch_core_session_alloc(session, sizeof(*context));
switch_assert(context != NULL);

View File

@ -3855,6 +3855,7 @@ SWITCH_STANDARD_API(boxcount_api_function)
total_new_messages = total_saved_messages = 0;
message_count(profile, id, domain, "inbox", &total_new_messages, &total_saved_messages,
&total_new_urgent_messages, &total_saved_urgent_messages);
free(hi);
}
switch_mutex_unlock(globals.mutex);
}

View File

@ -137,6 +137,7 @@ static struct {
switch_byte_t volte; /* enable special fmtp for VoLTE compliance */
switch_byte_t adjust_bitrate;
int debug;
switch_byte_t force_oa; /*force OA when originating*/
} globals;
const int switch_amr_frame_sizes[] = {12,13,15,17,19,20,26,31,5,0,0,0,0,0,0,1};
@ -179,7 +180,7 @@ static switch_bool_t switch_amr_pack_oa(unsigned char *shift_buf, int n)
return SWITCH_TRUE;
}
static switch_bool_t switch_amr_info(unsigned char *encoded_buf, int encoded_data_len, int payload_format, char *print_text)
static switch_bool_t switch_amr_info(switch_codec_t *codec, unsigned char *encoded_buf, int encoded_data_len, int payload_format, char *print_text)
{
uint8_t *tocs;
int framesz, index, not_last_frame, q, ft;
@ -196,7 +197,7 @@ static switch_bool_t switch_amr_info(unsigned char *encoded_buf, int encoded_dat
tocs = encoded_buf;
index = (tocs[0] >> 3) & 0x0f;
if (index > SWITCH_AMR_MODES && index != 0xf) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "AMR decoder (OA): Invalid Table Of Contents (TOC): 0x%x\n", index);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_ERROR, "AMR decoder (OA): Invalid Table Of Contents (TOC): 0x%x\n", index);
return SWITCH_FALSE;
}
framesz = switch_amr_frame_sizes[index];
@ -216,15 +217,15 @@ static switch_bool_t switch_amr_info(unsigned char *encoded_buf, int encoded_dat
ft &= ~(1 << 5); /* Frame Type */
index = (shift_tocs[0] >> 3) & 0x0f;
if (index > SWITCH_AMR_MODES && index != 0xf) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "AMR decoder (BE): Invalid Table Of Contents (TOC): 0x%x\n", index);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_ERROR, "AMR decoder (BE): Invalid Table Of Contents (TOC): 0x%x\n", index);
return SWITCH_FALSE;
}
framesz = switch_amr_frame_sizes[index];
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s (%s): FT: [0x%x] Q: [0x%x] Frame flag: [%d]\n",
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "%s (%s): FT: [0x%x] Q: [0x%x] Frame flag: [%d]\n",
print_text, payload_format ? "OA":"BE", ft, q, not_last_frame);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s (%s): AMR encoded voice payload sz: [%d] : | encoded_data_len: [%d]\n",
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "%s (%s): AMR encoded voice payload sz: [%d] : | encoded_data_len: [%d]\n",
print_text, payload_format ? "OA":"BE", framesz, encoded_data_len);
return SWITCH_TRUE;
@ -276,8 +277,11 @@ static switch_status_t switch_amr_init(switch_codec_t *codec, switch_codec_flag_
* bandwidth-efficient operation is employed."
*
*/
switch_clear_flag(context, AMR_OPT_OCTET_ALIGN);
if (!globals.force_oa) {
switch_clear_flag(context, AMR_OPT_OCTET_ALIGN);
} else {
switch_set_flag(context, AMR_OPT_OCTET_ALIGN);
}
if (codec->fmtp_in) {
argc = switch_separate_string(codec->fmtp_in, ';', argv, (sizeof(argv) / sizeof(argv[0])));
for (x = 0; x < argc; x++) {
@ -452,7 +456,7 @@ static switch_status_t switch_amr_encode(switch_codec_t *codec,
}
if (globals.debug) {
switch_amr_info(shift_buf, *encoded_data_len, switch_test_flag(context, AMR_OPT_OCTET_ALIGN) ? 1 : 0, "AMR encoder");
switch_amr_info(codec, shift_buf, *encoded_data_len, switch_test_flag(context, AMR_OPT_OCTET_ALIGN) ? 1 : 0, "AMR encoder");
}
return SWITCH_STATUS_SUCCESS;
@ -479,7 +483,7 @@ static switch_status_t switch_amr_decode(switch_codec_t *codec,
}
if (globals.debug) {
switch_amr_info(buf, encoded_data_len, switch_test_flag(context, AMR_OPT_OCTET_ALIGN) ? 1 : 0, "AMR decoder");
switch_amr_info(codec, buf, encoded_data_len, switch_test_flag(context, AMR_OPT_OCTET_ALIGN) ? 1 : 0, "AMR decoder");
}
if (switch_test_flag(context, AMR_OPT_OCTET_ALIGN)) {
@ -643,6 +647,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_amr_load)
if (!strcasecmp(var, "adjust-bitrate")) {
globals.adjust_bitrate = (switch_byte_t) atoi(val);
}
if (!strcasecmp(var, "force-oa")) {
globals.force_oa = (switch_byte_t) atoi(val);
}
}
}
}

View File

@ -113,6 +113,7 @@ static int db_is_up(switch_pgsql_handle_t *handle)
int max_tries = DEFAULT_PGSQL_RETRIES;
int code = 0;
int recon = 0;
switch_byte_t sanity = 255;
if (handle) {
max_tries = handle->num_retries;
@ -132,10 +133,24 @@ top:
}
/* Try a non-blocking read on the connection to gobble up any EOF from a closed connection and mark the connection BAD if it is closed. */
PQconsumeInput(handle->con);
while (--sanity > 0)
{
if (PQisBusy(handle->con)) {
PQconsumeInput(handle->con);
switch_yield(1);
continue;
}
break;
}
if (!sanity) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Can not check DB Connection status: sanity = 0. Reconnecting...\n");
goto reset;
}
if (PQstatus(handle->con) == CONNECTION_BAD) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "PQstatus returned bad connection; reconnecting...\n");
reset:
handle->state = SWITCH_PGSQL_STATE_ERROR;
PQreset(handle->con);
if (PQstatus(handle->con) == CONNECTION_BAD) {
@ -358,6 +373,20 @@ switch_status_t pgsql_handle_connect(switch_pgsql_handle_t *handle)
return SWITCH_STATUS_FALSE;
}
if (PQsetnonblocking(handle->con, 1) == -1) {
char *err_str;
if ((err_str = pgsql_handle_get_error(handle))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s\n", err_str);
switch_safe_free(err_str);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to setup socket for the database [%s]\n", handle->dsn);
pgsql_handle_disconnect(handle);
}
return SWITCH_STATUS_FALSE;
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Connected to [%s]\n", handle->dsn);
handle->state = SWITCH_PGSQL_STATE_CONNECTED;
handle->sock = PQsocket(handle->con);
@ -486,15 +515,14 @@ error:
err_str = pgsql_handle_get_error(handle);
if (zstr(err_str)) {
if (zstr(er)) {
switch_safe_free(err_str);
if (!er) {
err_str = strdup((char *)"SQL ERROR!");
} else {
err_str = er;
}
} else {
if (!zstr(er)) {
free(er);
}
switch_safe_free(er);
}
if (err_str) {
@ -622,89 +650,91 @@ switch_status_t pgsql_next_result_timed(switch_pgsql_handle_t *handle, switch_pg
return SWITCH_STATUS_FALSE;
}
/* Try to consume input that might be waiting right away */
if (PQconsumeInput(handle->con)) {
/* And check to see if we have a full result ready for reading */
if (PQisBusy(handle->con)) {
if (PQisBusy(handle->con)) {
/* Try to consume input that might be waiting right away */
if (PQconsumeInput(handle->con)) {
/* And check to see if we have a full result ready for reading */
if (PQisBusy(handle->con)) {
/* Wait for a result to become available, up to msec milliseconds */
start = switch_micro_time_now();
while ((ctime = switch_micro_time_now()) - start <= usec) {
switch_time_t wait_time = (usec - (ctime - start)) / 1000;
/* Wait for the PostgreSQL socket to be ready for data reads. */
/* Wait for a result to become available, up to msec milliseconds */
start = switch_micro_time_now();
while ((ctime = switch_micro_time_now()) - start <= usec) {
switch_time_t wait_time = (usec - (ctime - start)) / 1000;
/* Wait for the PostgreSQL socket to be ready for data reads. */
#ifndef _WIN32
fds[0].fd = handle->sock;
fds[0].events |= POLLIN;
fds[0].events |= POLLERR;
fds[0].events |= POLLNVAL;
fds[0].events |= POLLHUP;
fds[0].events |= POLLPRI;
fds[0].events |= POLLRDNORM;
fds[0].events |= POLLRDBAND;
fds[0].fd = handle->sock;
fds[0].events |= POLLIN;
fds[0].events |= POLLERR;
fds[0].events |= POLLNVAL;
fds[0].events |= POLLHUP;
fds[0].events |= POLLPRI;
fds[0].events |= POLLRDNORM;
fds[0].events |= POLLRDBAND;
poll_res = poll(&fds[0], 1, wait_time);
poll_res = poll(&fds[0], 1, wait_time);
#else
struct timeval wait = { (long)wait_time * 1000, 0 };
FD_ZERO(&rs);
FD_SET(handle->sock, &rs);
FD_ZERO(&es);
FD_SET(handle->sock, &es);
poll_res = select(0, &rs, 0, &es, &wait);
struct timeval wait = { (long)wait_time * 1000, 0 };
FD_ZERO(&rs);
FD_SET(handle->sock, &rs);
FD_ZERO(&es);
FD_SET(handle->sock, &es);
poll_res = select(0, &rs, 0, &es, &wait);
#endif
if (poll_res > 0) {
if (poll_res > 0) {
#ifndef _WIN32
if (fds[0].revents & POLLHUP || fds[0].revents & POLLNVAL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "PGSQL socket closed or invalid while waiting for result for query (%s)\n", handle->sql);
goto error;
} else if (fds[0].revents & POLLERR) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Poll error trying to read PGSQL socket for query (%s)\n", handle->sql);
goto error;
} else if (fds[0].revents & POLLIN || fds[0].revents & POLLPRI || fds[0].revents & POLLRDNORM || fds[0].revents & POLLRDBAND) {
if (fds[0].revents & POLLHUP || fds[0].revents & POLLNVAL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "PGSQL socket closed or invalid while waiting for result for query (%s)\n", handle->sql);
goto error;
} else if (fds[0].revents & POLLERR) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Poll error trying to read PGSQL socket for query (%s)\n", handle->sql);
goto error;
} else if (fds[0].revents & POLLIN || fds[0].revents & POLLPRI || fds[0].revents & POLLRDNORM || fds[0].revents & POLLRDBAND) {
#else
if (FD_ISSET(handle->sock, &rs)) {
if (FD_ISSET(handle->sock, &rs)) {
#endif
/* Then try to consume any input waiting. */
if (PQconsumeInput(handle->con)) {
if (PQstatus(handle->con) == CONNECTION_BAD) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Connection terminated while waiting for result.\n");
handle->state = SWITCH_PGSQL_STATE_ERROR;
/* Then try to consume any input waiting. */
if (PQconsumeInput(handle->con)) {
if (PQstatus(handle->con) == CONNECTION_BAD) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Connection terminated while waiting for result.\n");
handle->state = SWITCH_PGSQL_STATE_ERROR;
goto error;
}
/* And check to see if we have a full result ready for reading */
if (!PQisBusy(handle->con)) {
/* If we can pull a full result without blocking, then break this loop */
break;
}
} else {
/* If we had an error trying to consume input, report it and cancel the query. */
err_str = pgsql_handle_get_error(handle);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "An error occurred trying to consume input for query (%s): %s\n", handle->sql, err_str);
switch_safe_free(err_str);
pgsql_cancel(handle);
goto error;
}
/* And check to see if we have a full result ready for reading */
if (!PQisBusy(handle->con)) {
/* If we can pull a full result without blocking, then break this loop */
break;
}
} else {
/* If we had an error trying to consume input, report it and cancel the query. */
err_str = pgsql_handle_get_error(handle);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "An error occurred trying to consume input for query (%s): %s\n", handle->sql, err_str);
switch_safe_free(err_str);
pgsql_cancel(handle);
goto error;
}
} else if (poll_res == -1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Poll failed trying to read PGSQL socket for query (%s)\n", handle->sql);
goto error;
}
} else if (poll_res == -1) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Poll failed trying to read PGSQL socket for query (%s)\n", handle->sql);
}
/* If we broke the loop above because of a timeout, report that and cancel the query. */
if (ctime - start > usec) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Query (%s) took too long to complete or database not responding.\n", handle->sql);
pgsql_cancel(handle);
goto error;
}
}
/* If we broke the loop above because of a timeout, report that and cancel the query. */
if (ctime - start > usec) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Query (%s) took too long to complete or database not responding.\n", handle->sql);
pgsql_cancel(handle);
goto error;
}
} else {
/* If we had an error trying to consume input, report it and cancel the query. */
err_str = pgsql_handle_get_error(handle);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "An error occurred trying to consume input for query (%s): %s\n", handle->sql, err_str);
switch_safe_free(err_str);
/* pgsql_cancel(handle); */
goto error;
}
} else {
/* If we had an error trying to consume input, report it and cancel the query. */
err_str = pgsql_handle_get_error(handle);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "An error occurred trying to consume input for query (%s): %s\n", handle->sql, err_str);
switch_safe_free(err_str);
/* pgsql_cancel(handle); */
goto error;
}
/* At this point, we know we can read a full result without blocking. */

View File

@ -1700,6 +1700,7 @@ static switch_call_cause_t null_channel_outgoing_channel(switch_core_session_t *
if (hangup_cause || !strncmp(caller_profile->destination_number, "cause-", 6)) {
if (!hangup_cause) hangup_cause = caller_profile->destination_number + 6;
switch_core_session_destroy(new_session);
return switch_channel_str2cause(hangup_cause);
}

View File

@ -2740,6 +2740,7 @@ const char *sofia_state_names[] = {
"FAIL_WAIT",
"EXPIRED",
"NOREG",
"DOWN",
"TIMEOUT",
NULL
};
@ -3653,15 +3654,21 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t
if (!strcasecmp(gname, "all")) {
for (gateway_ptr = profile->gateways; gateway_ptr; gateway_ptr = gateway_ptr->next) {
gateway_ptr->retry = 0;
gateway_ptr->state = REG_STATE_UNREGED;
if (gateway_ptr->state != REG_STATE_NOREG) {
gateway_ptr->retry = 0;
gateway_ptr->state = REG_STATE_UNREGED;
}
}
stream->write_function(stream, "+OK\n");
} else if ((gateway_ptr = sofia_reg_find_gateway(gname))) {
gateway_ptr->retry = 0;
gateway_ptr->state = REG_STATE_UNREGED;
stream->write_function(stream, "+OK\n");
sofia_reg_release_gateway(gateway_ptr);
if (gateway_ptr->state != REG_STATE_NOREG) {
gateway_ptr->retry = 0;
gateway_ptr->state = REG_STATE_UNREGED;
stream->write_function(stream, "+OK\n");
sofia_reg_release_gateway(gateway_ptr);
} else {
stream->write_function(stream, "-ERR NOREG gateway [%s] can't be registered!\n", gname);
}
} else {
stream->write_function(stream, "Invalid gateway!\n");
}
@ -3680,15 +3687,21 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t
if (!strcasecmp(gname, "all")) {
for (gateway_ptr = profile->gateways; gateway_ptr; gateway_ptr = gateway_ptr->next) {
gateway_ptr->retry = 0;
gateway_ptr->state = REG_STATE_UNREGISTER;
if (gateway_ptr->state != REG_STATE_NOREG) {
gateway_ptr->retry = 0;
gateway_ptr->state = REG_STATE_UNREGISTER;
}
}
stream->write_function(stream, "+OK\n");
} else if ((gateway_ptr = sofia_reg_find_gateway(gname))) {
gateway_ptr->retry = 0;
gateway_ptr->state = REG_STATE_UNREGISTER;
stream->write_function(stream, "+OK\n");
sofia_reg_release_gateway(gateway_ptr);
if (gateway_ptr->state != REG_STATE_NOREG) {
gateway_ptr->retry = 0;
gateway_ptr->state = REG_STATE_UNREGISTER;
stream->write_function(stream, "+OK\n");
sofia_reg_release_gateway(gateway_ptr);
} else {
stream->write_function(stream, "-ERR NOREG gateway [%s] can't be unregistered!\n", gname);
}
} else {
stream->write_function(stream, "Invalid gateway!\n");
}
@ -5070,7 +5083,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session
if (gateway_ptr && gateway_ptr->ob_vars) {
switch_event_header_t *hp;
for (hp = gateway_ptr->ob_vars->headers; hp; hp = hp->next) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s setting variable [%s]=[%s]\n",
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(nsession), SWITCH_LOG_DEBUG, "%s setting variable [%s]=[%s]\n",
switch_channel_get_name(nchannel), hp->name, hp->value);
if (!strncmp(hp->name, "p:", 2)) {
switch_channel_set_profile_var(nchannel, hp->name + 2, hp->value);

View File

@ -432,6 +432,7 @@ typedef enum {
REG_STATE_FAIL_WAIT,
REG_STATE_EXPIRED,
REG_STATE_NOREG,
REG_STATE_DOWN,
REG_STATE_TIMEOUT,
REG_STATE_LAST
} reg_state_t;

View File

@ -1733,6 +1733,10 @@ static void our_sofia_event_callback(nua_event_t event,
switch_channel_set_variable(channel, "sip_call_id", sip->sip_call_id->i_id);
}
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
switch_channel_set_variable(channel, "dlg_req_swap_direction", "true");
}
extract_header_vars(profile, sip, session, nh);
switch_core_recovery_track(session);
sofia_set_flag(tech_pvt, TFLAG_GOT_ACK);
@ -2278,7 +2282,7 @@ void sofia_process_dispatch_event(sofia_dispatch_event_t **dep)
profile->queued_events--;
switch_mutex_unlock(profile->flag_mutex);
nua_handle_unref(nh);
if (nh) nua_handle_unref(nh);
nua_unref(nua);
}
@ -2435,11 +2439,16 @@ void sofia_event_callback(nua_event_t event,
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "detaching session %s\n", sofia_private->uuid);
if (!zstr(tech_pvt->call_id)) {
char *uuid = strdup(switch_core_session_get_uuid(session));
tech_pvt->sofia_private = NULL;
tech_pvt->nh = NULL;
sofia_set_flag(tech_pvt, TFLAG_BYE);
switch_mutex_lock(profile->flag_mutex);
switch_core_hash_insert_auto_free(profile->chat_hash, tech_pvt->call_id, strdup(switch_core_session_get_uuid(session)));
if (switch_core_hash_insert_auto_free(profile->chat_hash, tech_pvt->call_id, uuid) != SWITCH_STATUS_SUCCESS) {
switch_safe_free(uuid);
}
switch_mutex_unlock(profile->flag_mutex);
nua_handle_destroy(nh);
} else {
@ -2507,7 +2516,7 @@ void sofia_event_callback(nua_event_t event,
de = su_alloc(nua_handle_get_home(nh), sizeof(*de));
memset(de, 0, sizeof(*de));
nua_save_event(nua, de->event);
de->nh = nua_handle_ref(nh);
de->nh = nh ? nua_handle_ref(nh) : NULL;
de->data = nua_event_data(de->event);
de->sip = sip_object(de->data->e_msg);
de->profile = profile;
@ -3171,7 +3180,6 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
if (!sofia_glue_init_sql(profile)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open SQL Database [%s]!\n", profile->name);
sofia_profile_start_failure(profile, profile->name);
sofia_glue_del_profile(profile);
goto end;
}
@ -3323,7 +3331,6 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
}
sofia_profile_start_failure(profile, profile->name);
sofia_glue_del_profile(profile);
goto end;
}
@ -3491,6 +3498,20 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
}
}
/* Do gateway cleanups */
sofia_glue_del_every_gateway(profile);
sofia_reg_check_gateway(profile, switch_epoch_time_now(NULL));
sofia_sub_check_gateway(profile, switch_epoch_time_now(NULL));
sofia_glue_fire_events(profile);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Waiting for worker thread\n");
if (worker_thread) {
switch_thread_join(&st, worker_thread);
}
else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: Sofia worker thead failed to start\n");
}
sofia_reg_unregister(profile);
nua_shutdown(profile->nua);
@ -3505,13 +3526,6 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
sofia_clear_pflag_locked(profile, PFLAG_RUNNING);
sofia_clear_pflag_locked(profile, PFLAG_SHUTDOWN);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Waiting for worker thread\n");
if ( worker_thread ) {
switch_thread_join(&st, worker_thread);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: Sofia worker thead failed to start\n");
}
sanity = 4;
while (profile->inuse) {
@ -3560,6 +3574,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
}
}
end:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock %s\n", profile->name);
switch_thread_rwlock_wrlock(profile->rwlock);
@ -3581,7 +3596,6 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
sofia_profile_destroy(profile);
end:
switch_mutex_lock(mod_sofia_globals.mutex);
mod_sofia_globals.threads--;
switch_mutex_unlock(mod_sofia_globals.mutex);
@ -6502,7 +6516,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
const char *uuid;
switch_core_session_t *other_session;
private_object_t *tech_pvt = switch_core_session_get_private(session);
char network_ip[80];
char network_ip[80] = "";
int network_port = 0;
switch_caller_profile_t *caller_profile = NULL;
int has_t38 = 0;
@ -7106,8 +7120,13 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
}
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND) {
switch_channel_set_variable(channel, "dlg_req_swap_direction", "true");
}
extract_header_vars(profile, sip, session, nh);
extract_vars(profile, sip, session);
switch_core_recovery_track(session);
switch_channel_clear_flag(tech_pvt->channel, CF_RECOVERING);
}
@ -7911,7 +7930,9 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
//switch_core_media_gen_local_sdp(session, NULL, 0, NULL, 0);
sofia_set_flag(tech_pvt, TFLAG_LATE_NEGOTIATION);
//Moves into CS_INIT so call moves forward into the dialplan
switch_channel_set_state(channel, CS_INIT);
if (switch_channel_get_state(channel) == CS_NEW) {
switch_channel_set_state(channel, CS_INIT);
}
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "No SDP in INVITE and 3pcc not enabled, hanging up.\n");
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "3PCC DISABLED");
@ -10891,9 +10912,10 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
if (switch_channel_get_variable(channel, "sip_to_uri")) {
const char *ipv6;
const char *tmp, *at, *url = NULL;
const char *tmp_user = switch_channel_get_variable(channel, "sip_to_user");
user = switch_core_session_url_encode(session, tmp_user);
host = switch_channel_get_variable(channel, "sip_to_host");
user = switch_channel_get_variable(channel, "sip_to_user");
switch_channel_set_variable(channel, "sip_to_comment", sip->sip_to->a_comment);

View File

@ -1211,7 +1211,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
}
sofia_glue_get_url_from_contact(rpid_domain, 0);
if ((rpid_domain = strrchr(rpid_domain, '@'))) {
if (rpid_domain && (rpid_domain = strrchr(rpid_domain, '@'))) {
rpid_domain++;
if ((p = strchr(rpid_domain, ';'))) {
*p = '\0';
@ -2235,7 +2235,7 @@ int sofia_recover_callback(switch_core_session_t *session)
const char *rr;
int r = 0;
const char *profile_name = switch_channel_get_variable_dup(channel, "recovery_profile_name", SWITCH_FALSE, -1);
int swap = switch_channel_var_true(channel, "dlg_req_swap_direction");
if (zstr(profile_name)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Missing profile\n");
@ -2275,10 +2275,9 @@ int sofia_recover_callback(switch_core_session_t *session)
rr = switch_channel_get_variable(channel, "sip_invite_record_route");
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
int break_rfc = switch_true(switch_channel_get_variable(channel, "sip_recovery_break_rfc"));
tech_pvt->dest = switch_core_session_sprintf(session, "sip:%s", switch_channel_get_variable(channel, "sip_req_uri"));
switch_channel_set_variable(channel, "sip_handle_full_from", switch_channel_get_variable(channel, break_rfc ? "sip_full_to" : "sip_full_from"));
switch_channel_set_variable(channel, "sip_handle_full_to", switch_channel_get_variable(channel, break_rfc ? "sip_full_from" : "sip_full_to"));
switch_channel_set_variable(channel, "sip_handle_full_from", switch_channel_get_variable(channel, swap ? "sip_full_to" : "sip_full_from"));
switch_channel_set_variable(channel, "sip_handle_full_to", switch_channel_get_variable(channel, swap ? "sip_full_from" : "sip_full_to"));
} else {
const char *contact_params = switch_channel_get_variable(channel, "sip_contact_params");
const char *contact_uri = switch_channel_get_variable(channel, "sip_contact_uri");
@ -2297,11 +2296,11 @@ int sofia_recover_callback(switch_core_session_t *session)
tech_pvt->dest = switch_core_session_sprintf(session, "sip:%s", switch_channel_get_variable(channel, "sip_from_uri"));
if (!switch_channel_get_variable_dup(channel, "sip_handle_full_from", SWITCH_FALSE, -1)) {
switch_channel_set_variable(channel, "sip_handle_full_from", switch_channel_get_variable(channel, "sip_full_to"));
switch_channel_set_variable(channel, "sip_handle_full_from", switch_channel_get_variable(channel, swap ? "sip_full_from" :"sip_full_to"));
}
if (!switch_channel_get_variable_dup(channel, "sip_handle_full_to", SWITCH_FALSE, -1)) {
switch_channel_set_variable(channel, "sip_handle_full_to", switch_channel_get_variable(channel, "sip_full_from"));
switch_channel_set_variable(channel, "sip_handle_full_to", switch_channel_get_variable(channel, swap ? "sip_full_to" : "sip_full_from"));
}
}

View File

@ -4284,7 +4284,11 @@ void sofia_presence_handle_sip_i_subscribe(int status,
}
}
}
switch_xml_free(xml);
}
switch_safe_free(pd_dup);
}
switch_event_fire(&event);
} else if (!strcasecmp(event, "message-summary")) {

View File

@ -323,7 +323,7 @@ void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now)
free(pkey);
}
if (gateway_ptr->state == REG_STATE_NOREG) {
if (gateway_ptr->state == REG_STATE_NOREG || gateway_ptr->state == REG_STATE_DOWN) {
if (last) {
last->next = gateway_ptr->next;
@ -356,7 +356,7 @@ void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now)
char *user_via = NULL;
char *register_host = NULL;
if (!now) {
if (!now && ostate != REG_STATE_NOREG) {
gateway_ptr->state = ostate = REG_STATE_UNREGED;
gateway_ptr->expires_str = "0";
}
@ -398,6 +398,7 @@ void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now)
}
switch (ostate) {
case REG_STATE_DOWN:
case REG_STATE_NOREG:
if (!gateway_ptr->ping && !gateway_ptr->pinging && gateway_ptr->status != SOFIA_GATEWAY_UP) {
gateway_ptr->status = SOFIA_GATEWAY_UP;
@ -432,7 +433,7 @@ void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now)
case REG_STATE_UNREGISTER:
sofia_reg_kill_reg(gateway_ptr);
gateway_ptr->state = REG_STATE_NOREG;
gateway_ptr->state = REG_STATE_DOWN;
gateway_ptr->status = SOFIA_GATEWAY_DOWN;
break;
case REG_STATE_UNREGED:
@ -1932,7 +1933,6 @@ uint8_t sofia_reg_handle_register_token(nua_t *nua, sofia_profile_t *profile, nu
switch_mutex_lock(profile->flag_mutex);
hnh = switch_core_hash_find(profile->reg_nh_hash, key);
switch_mutex_unlock(profile->flag_mutex);
if (!hnh) {
if (!(sofia_private = su_alloc(nua_handle_get_home(nh), sizeof(*sofia_private)))) {
@ -1953,6 +1953,8 @@ uint8_t sofia_reg_handle_register_token(nua_t *nua, sofia_profile_t *profile, nu
nua_handle_ref(nh);
switch_core_hash_insert(profile->reg_nh_hash, key, nh);
}
switch_mutex_unlock(profile->flag_mutex);
}

View File

@ -79,22 +79,22 @@ static int channelList_callback(void *pArg, int argc, char **argv, char **column
row->data = entry;
entry->idx = idx++;
strncpy(entry->uuid, switch_str_nil(argv[0]), sizeof(entry->uuid));
strncpy(entry->direction, switch_str_nil(argv[1]), sizeof(entry->direction));
snprintf(entry->uuid, sizeof(entry->uuid), "%s", switch_str_nil(argv[0]));
snprintf(entry->direction, sizeof(entry->direction), "%s", switch_str_nil(argv[1]));
entry->created_epoch = atoi(argv[3]);
strncpy(entry->name, switch_str_nil(argv[4]), sizeof(entry->name));
strncpy(entry->state, switch_str_nil(argv[5]), sizeof(entry->state));
strncpy(entry->cid_name, switch_str_nil(argv[6]), sizeof(entry->cid_name));
strncpy(entry->cid_num, switch_str_nil(argv[7]), sizeof(entry->cid_num));
strncpy(entry->dest, switch_str_nil(argv[9]), sizeof(entry->dest));
strncpy(entry->application, switch_str_nil(argv[10]), sizeof(entry->application));
strncpy(entry->application_data, switch_str_nil(argv[11]), sizeof(entry->application_data));
strncpy(entry->dialplan, switch_str_nil(argv[12]), sizeof(entry->dialplan));
strncpy(entry->context, switch_str_nil(argv[13]), sizeof(entry->context));
strncpy(entry->read_codec, switch_str_nil(argv[14]), sizeof(entry->read_codec));
snprintf(entry->name, sizeof(entry->name), "%s", switch_str_nil(argv[4]));
snprintf(entry->state, sizeof(entry->state), "%s", switch_str_nil(argv[5]));
snprintf(entry->cid_name, sizeof(entry->cid_name), "%s", switch_str_nil(argv[6]));
snprintf(entry->cid_num, sizeof(entry->cid_num), "%s", switch_str_nil(argv[7]));
snprintf(entry->dest, sizeof(entry->dest), "%s", switch_str_nil(argv[9]));
snprintf(entry->application, sizeof(entry->application), "%s", switch_str_nil(argv[10]));
snprintf(entry->application_data, sizeof(entry->application_data), "%s", switch_str_nil(argv[11]));
snprintf(entry->dialplan, sizeof(entry->dialplan), "%s", switch_str_nil(argv[12]));
snprintf(entry->context, sizeof(entry->context), "%s", switch_str_nil(argv[13]));
snprintf(entry->read_codec, sizeof(entry->read_codec), "%s", switch_str_nil(argv[14]));
entry->read_rate = atoi(switch_str_nil(argv[15]));
entry->read_bitrate = atoi(switch_str_nil(argv[16]));
strncpy(entry->write_codec, switch_str_nil(argv[17]), sizeof(entry->write_codec));
snprintf(entry->write_codec, sizeof(entry->write_codec), "%s", switch_str_nil(argv[17]));
entry->write_rate = atoi(switch_str_nil(argv[18]));
entry->write_bitrate = atoi(switch_str_nil(argv[19]));
@ -186,7 +186,7 @@ int handle_identity(netsnmp_mib_handler *handler, netsnmp_handler_registration *
snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) &version, strlen(version));
break;
case ID_UUID:
strncpy(uuid, switch_core_get_uuid(), sizeof(uuid));
snprintf(uuid, sizeof(uuid), "%s", switch_core_get_uuid());
snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) &uuid, strlen(uuid));
break;
default:

View File

@ -1333,8 +1333,6 @@ void do_telecast(switch_stream_handle_t *stream)
end:
switch_safe_free(uuid);
if (gfp) {
lame_close(gfp);
gfp = NULL;
@ -1350,6 +1348,8 @@ void do_telecast(switch_stream_handle_t *stream)
switch_core_session_rwunlock(tsession);
}
switch_safe_free(uuid);
}
void do_broadcast(switch_stream_handle_t *stream)

View File

@ -309,6 +309,12 @@ static switch_status_t sndfile_file_open(switch_file_handle_t *handle, const cha
sf_command(context->handle, SFC_FILE_TRUNCATE, &frames, sizeof(frames));
}
/*
http://www.mega-nerd.com/libsndfile/api.html#note2
*/
if (switch_test_flag(handle, SWITCH_FILE_DATA_SHORT)) {
sf_command(context->handle, SFC_SET_SCALE_FLOAT_INT_READ, NULL, SF_TRUE);
}
end:

View File

@ -4175,6 +4175,7 @@ SWITCH_DECLARE(char *) switch_channel_expand_variables_check(switch_channel_t *c
if (!switch_core_test_flag(SCF_API_EXPANSION) || (api_list && !switch_event_check_permission_list(api_list, vname))) {
func_val = NULL;
sub_val = "<API Execute Permission Denied>";
free(stream.data);
} else {
if (switch_api_execute(vname, vval, channel->session, &stream) == SWITCH_STATUS_SUCCESS) {
func_val = stream.data;

View File

@ -227,7 +227,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
switch_assert((*frame)->codec != NULL);
if (!(session->read_codec && (*frame)->codec && (*frame)->codec->implementation) && switch_core_codec_ready((*frame)->codec)) {
if (!switch_core_codec_ready(session->read_codec) || !switch_core_codec_ready((*frame)->codec)) {
status = SWITCH_STATUS_FALSE;
goto done;
}

View File

@ -3587,24 +3587,27 @@ static void switch_core_session_parse_codec_settings(switch_core_session_t *sess
//?
SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_codec(switch_core_session_t *session, int force)
{
switch_status_t status = SWITCH_STATUS_SUCCESS;
switch_media_handle_t *smh;
switch_rtp_engine_t *v_engine;
switch_assert(session);
switch_mutex_lock(session->codec_init_mutex);
if (!(smh = session->media_handle)) {
return SWITCH_STATUS_FALSE;
switch_goto_status(SWITCH_STATUS_FALSE, end);
}
v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
if (!v_engine->codec_negotiated) {
return SWITCH_STATUS_FALSE;
switch_goto_status(SWITCH_STATUS_FALSE, end);
}
if (v_engine->read_codec.implementation && switch_core_codec_ready(&v_engine->read_codec)) {
if (!force) {
return SWITCH_STATUS_SUCCESS;
switch_goto_status(SWITCH_STATUS_SUCCESS, end);
}
if (strcasecmp(v_engine->read_codec.implementation->iananame, v_engine->cur_payload_map->rm_encoding) ||
v_engine->read_codec.implementation->samples_per_second != v_engine->cur_payload_map->rm_rate) {
@ -3616,7 +3619,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_codec(switch_core_se
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Already using %s\n",
v_engine->read_codec.implementation->iananame);
return SWITCH_STATUS_SUCCESS;
switch_goto_status(SWITCH_STATUS_SUCCESS, end);
}
}
@ -3632,7 +3635,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_codec(switch_core_se
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
&v_engine->codec_settings, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't load codec?\n");
return SWITCH_STATUS_FALSE;
switch_goto_status(SWITCH_STATUS_FALSE, end);
} else {
if (switch_core_codec_init(&v_engine->write_codec,
v_engine->cur_payload_map->rm_encoding,
@ -3644,7 +3647,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_codec(switch_core_se
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
&v_engine->codec_settings, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't load codec?\n");
return SWITCH_STATUS_FALSE;
switch_goto_status(SWITCH_STATUS_FALSE, end);
} else {
v_engine->read_frame.rate = v_engine->cur_payload_map->rm_rate;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Set VIDEO Codec %s %s/%ld %d ms\n",
@ -3685,7 +3688,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_codec(switch_core_se
switch_channel_set_variable_printf(session->channel, "rtp_use_video_codec_ptime", "%d", 0);
}
}
return SWITCH_STATUS_SUCCESS;
end:
switch_mutex_unlock(session->codec_init_mutex);
return status;
}
@ -3699,8 +3706,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_codec(switch_core_session_
switch_assert(session);
switch_mutex_lock(session->codec_init_mutex);
if (!(smh = session->media_handle)) {
return SWITCH_STATUS_FALSE;
switch_goto_status(SWITCH_STATUS_FALSE, end);
}
a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
@ -3860,10 +3869,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_codec(switch_core_session_
end:
if (resetting) {
switch_core_session_unlock_codec_write(session);
switch_core_session_unlock_codec_read(session);
switch_channel_execute_on(session->channel, "execute_on_audio_change");
switch_core_session_unlock_codec_write(session);
switch_core_session_unlock_codec_read(session);
}
switch_mutex_unlock(session->codec_init_mutex);
return status;
}
static void clear_ice(switch_core_session_t *session, switch_media_type_t type)
@ -4814,11 +4826,7 @@ static void switch_core_media_set_rmode(switch_core_session_t *session, switch_m
if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
if (!switch_channel_media_up(session->channel) && sdp_type == SDP_TYPE_REQUEST) {
engine->rmode = switch_core_session_remote_media_flow(other_session, type);
media_flow_get_mode(engine->rmode, &rmode_str, &opp_rmode);
} else if (sdp_type == SDP_TYPE_RESPONSE && (switch_channel_test_flag(other_session->channel, CF_REINVITE) || switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND)) {
if (sdp_type == SDP_TYPE_RESPONSE && (switch_channel_test_flag(other_session->channel, CF_REINVITE) || switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND)) {
switch_core_media_set_smode(other_session, type, rmode, sdp_type);
}
@ -6790,6 +6798,7 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void
}
if (!(smh = session->media_handle)) {
switch_core_session_rwunlock(session);
return NULL;
}
@ -7300,12 +7309,14 @@ static void *SWITCH_THREAD_FUNC text_helper_thread(switch_thread_t *thread, void
return NULL;
}
mh->ready = 1;
if (!(smh = session->media_handle)) {
switch_core_session_rwunlock(session);
mh->ready = -1;
return NULL;
}
mh->ready = 1;
channel = switch_core_session_get_channel(session);
if (switch_channel_var_true(session->channel, "fire_text_events")) {
@ -7459,12 +7470,14 @@ static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, voi
return NULL;
}
mh->ready = 1;
if (!(smh = session->media_handle)) {
switch_core_session_rwunlock(session);
mh->ready = -1;
return NULL;
}
mh->ready = 1;
channel = switch_core_session_get_channel(session);
switch_core_autobind_cpu();
@ -9038,6 +9051,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
// goto video;
//}
if (!t_engine->cur_payload_map) {
goto text_up;
}
if (switch_channel_test_flag(session->channel, CF_TEXT_POSSIBLE) && t_engine->cur_payload_map->rm_encoding && t_engine->cur_payload_map->remote_sdp_port) {
/******************************************************************************************/
if (t_engine->rtp_session && is_reinvite) {
@ -15496,6 +15513,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_text_frame(switch_core
t_engine = &smh->engines[SWITCH_MEDIA_TYPE_TEXT];
if (!t_engine || !t_engine->tf) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "text engine not available for processing\n");
switch_goto_status(SWITCH_STATUS_BREAK, done);
}
if (!is_msrp && switch_channel_test_cap(session->channel, CC_RTP_RTT)) {
if (frame) {
@ -16012,7 +16034,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
session->write_codec->cur_frame = frame;
frame->codec->cur_frame = frame;
switch_assert(enc_frame->datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE);
switch_assert(session->enc_read_frame.datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE);
switch_assert(session->enc_write_frame.datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE);
status = switch_core_codec_encode(session->write_codec,
frame->codec,
enc_frame->data,
@ -16020,7 +16042,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
session->write_impl.actual_samples_per_second,
session->enc_write_frame.data, &session->enc_write_frame.datalen, &session->enc_write_frame.rate, &flag);
switch_assert(session->enc_read_frame.datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE);
switch_assert(session->enc_write_frame.datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE);
session->write_codec->cur_frame = NULL;
frame->codec->cur_frame = NULL;
@ -16122,7 +16144,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
session->write_codec->cur_frame = frame;
frame->codec->cur_frame = frame;
switch_assert(enc_frame->datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE);
switch_assert(session->enc_read_frame.datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE);
switch_assert(session->enc_write_frame.datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE);
status = switch_core_codec_encode(session->write_codec,
frame->codec,
enc_frame->data,
@ -16130,7 +16152,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
rate,
session->enc_write_frame.data, &session->enc_write_frame.datalen, &session->enc_write_frame.rate, &flag);
switch_assert(session->enc_read_frame.datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE);
switch_assert(session->enc_write_frame.datalen <= SWITCH_RECOMMENDED_BUFFER_SIZE);
session->write_codec->cur_frame = NULL;
frame->codec->cur_frame = NULL;

View File

@ -1026,8 +1026,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_queue_indication(switch_core
msg->message_id = indication;
msg->from = __FILE__;
switch_set_flag(msg, SCSMF_DYNAMIC);
switch_core_session_queue_message(session, msg);
return SWITCH_STATUS_SUCCESS;
if (switch_core_session_queue_message(session, msg) == SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_SUCCESS;
}
free(msg);
}
return SWITCH_STATUS_FALSE;
@ -2417,6 +2421,7 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_uuid(switch_
switch_mutex_init(&session->mutex, SWITCH_MUTEX_NESTED, session->pool);
switch_mutex_init(&session->stack_count_mutex, SWITCH_MUTEX_NESTED, session->pool);
switch_mutex_init(&session->resample_mutex, SWITCH_MUTEX_NESTED, session->pool);
switch_mutex_init(&session->codec_init_mutex, SWITCH_MUTEX_NESTED, session->pool);
switch_mutex_init(&session->codec_read_mutex, SWITCH_MUTEX_NESTED, session->pool);
switch_mutex_init(&session->codec_write_mutex, SWITCH_MUTEX_NESTED, session->pool);
switch_mutex_init(&session->video_codec_read_mutex, SWITCH_MUTEX_NESTED, session->pool);

View File

@ -129,6 +129,8 @@ static char *my_dup(const char *s)
#define FREE(ptr) switch_safe_free(ptr)
#endif
static void free_header(switch_event_header_t **header);
/* make sure this is synced with the switch_event_types_t enum in switch_types.h
also never put any new ones before EVENT_ALL
*/
@ -891,27 +893,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_del_header_val(switch_event_t *even
if (hp == event->last_header || !hp->next) {
event->last_header = lp;
}
FREE(hp->name);
if (hp->idx) {
int i = 0;
for (i = 0; i < hp->idx; i++) {
FREE(hp->array[i]);
}
FREE(hp->array);
}
FREE(hp->value);
memset(hp, 0, sizeof(*hp));
#ifdef SWITCH_EVENT_RECYCLE
if (switch_queue_trypush(EVENT_HEADER_RECYCLE_QUEUE, hp) != SWITCH_STATUS_SUCCESS) {
FREE(hp);
}
#else
FREE(hp);
#endif
free_header(&hp);
status = SWITCH_STATUS_SUCCESS;
} else {
lp = hp;
@ -944,6 +926,37 @@ static switch_event_header_t *new_header(const char *header_name)
}
static void free_header(switch_event_header_t **header)
{
assert(header);
if (*header) {
if ((*header)->idx) {
if (!(*header)->array) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "INDEX WITH NO ARRAY ?? [%s][%s]\n", (*header)->name, (*header)->value);
} else {
int i = 0;
for (i = 0; i < (*header)->idx; i++) {
FREE((*header)->array[i]);
}
FREE((*header)->array);
}
}
FREE((*header)->name);
FREE((*header)->value);
#ifdef SWITCH_EVENT_RECYCLE
if (switch_queue_trypush(EVENT_HEADER_RECYCLE_QUEUE, *header) != SWITCH_STATUS_SUCCESS) {
FREE(*header);
}
#else
FREE(*header);
#endif
}
}
SWITCH_DECLARE(int) switch_event_add_array(switch_event_t *event, const char *var, const char *val)
{
char *data;
@ -1012,10 +1025,11 @@ static switch_status_t switch_event_base_add_header(switch_event_t *event, switc
}
if (index_ptr || (stack & SWITCH_STACK_PUSH) || (stack & SWITCH_STACK_UNSHIFT)) {
switch_event_header_t *tmp_header = NULL;
if (!(header = switch_event_get_header_ptr(event, header_name)) && index_ptr) {
header = new_header(header_name);
tmp_header = header = new_header(header_name);
if (switch_test_flag(event, EF_UNIQ_HEADERS)) {
switch_event_del_header(event, header_name);
@ -1049,6 +1063,8 @@ static switch_status_t switch_event_base_add_header(switch_event_t *event, switc
goto redraw;
}
} else if (tmp_header) {
free_header(&tmp_header);
}
goto end;
} else {
@ -1266,33 +1282,7 @@ SWITCH_DECLARE(void) switch_event_destroy(switch_event_t **event)
for (hp = ep->headers; hp;) {
this = hp;
hp = hp->next;
if (this->idx) {
if (!this->array) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "INDEX WITH NO ARRAY WTF?? [%s][%s]\n", this->name, this->value);
} else {
int i = 0;
for (i = 0; i < this->idx; i++) {
FREE(this->array[i]);
}
FREE(this->array);
}
}
FREE(this->name);
FREE(this->value);
#ifdef SWITCH_EVENT_RECYCLE
if (switch_queue_trypush(EVENT_HEADER_RECYCLE_QUEUE, this) != SWITCH_STATUS_SUCCESS) {
FREE(this);
}
#else
FREE(this);
#endif
free_header(&this);
}
FREE(ep->body);
FREE(ep->subclass_name);
@ -2464,8 +2454,6 @@ SWITCH_DECLARE(char *) switch_event_expand_headers_check(switch_event_t *event,
char *expanded = NULL;
char *expanded_vname = NULL;
SWITCH_STANDARD_STREAM(stream);
if ((expanded_vname = switch_event_expand_headers_check(event, (char *) vname, var_list, api_list, recur+1)) == vname) {
expanded_vname = NULL;
} else {
@ -2482,6 +2470,7 @@ SWITCH_DECLARE(char *) switch_event_expand_headers_check(switch_event_t *event,
func_val = NULL;
sub_val = "<API execute Permission Denied>";
} else {
SWITCH_STANDARD_STREAM(stream);
if (switch_api_execute(vname, vval, NULL, &stream) == SWITCH_STATUS_SUCCESS) {
func_val = stream.data;
sub_val = func_val;

View File

@ -1011,7 +1011,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_park(switch_core_session_t *session,
rate = read_impl.actual_samples_per_second;
bpf = read_impl.decoded_bytes_per_packet;
if ((var = switch_channel_get_variable(channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE)) && (sval = atoi(var))) {
if (rate && (var = switch_channel_get_variable(channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE)) && (sval = atoi(var))) {
switch_core_session_get_read_impl(session, &imp);
if (switch_core_codec_init(&codec,
@ -2192,7 +2192,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_session_transfer(switch_core_session_
extension = "service";
}
new_profile = switch_caller_profile_clone(session, profile);
if (switch_channel_test_flag(channel, CF_REUSE_CALLER_PROFILE)){
new_profile = switch_channel_get_caller_profile(channel);
} else {
new_profile = switch_caller_profile_clone(session, profile);
}
new_profile->dialplan = switch_core_strdup(new_profile->pool, use_dialplan);
new_profile->context = switch_core_strdup(new_profile->pool, use_context);
@ -2238,7 +2243,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_session_transfer(switch_core_session_
switch_core_session_rwunlock(other_session);
}
switch_channel_set_caller_profile(channel, new_profile);
if (!switch_channel_test_flag(channel, CF_REUSE_CALLER_PROFILE)){
switch_channel_set_caller_profile(channel, new_profile);
}
switch_channel_set_state(channel, CS_ROUTING);
switch_channel_audio_sync(channel);
@ -3515,8 +3522,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_generate_json_cdr(switch_core_session
SWITCH_DECLARE(void) switch_ivr_park_session(switch_core_session_t *session)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_channel_set_state(channel, CS_PARK);
switch_channel_set_flag(channel, CF_TRANSFER);
switch_channel_set_state(channel, CS_PARK);
}

View File

@ -2084,7 +2084,7 @@ static switch_bool_t eavesdrop_callback(switch_media_bug_t *bug, void *user_data
memcpy(frame.data, nframe->data, nframe->datalen);
if (switch_core_session_write_frame(ep->eavesdropper, nframe, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
if (switch_core_session_write_frame(ep->eavesdropper, &frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
return SWITCH_FALSE;
}
}
@ -2184,6 +2184,25 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_update_display(switch_core_
return status;
}
/*Greatest Common Divisor*/
static uint32_t switch_gcd(uint32_t x, uint32_t y)
{
if (y == 0) {
return x;
}
return switch_gcd(y, x % y);
}
/*Least Common Multiple*/
static uint32_t switch_lcm(uint32_t x, uint32_t y)
{
uint32_t gcd = switch_gcd(x, y);
if (gcd) return (x * y) / gcd;
return 0;
}
SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session_t *session,
const char *uuid, const char *require_group, switch_eavesdrop_flag_t flags)
@ -2209,14 +2228,21 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session
char cid_buf[1024] = "";
switch_caller_profile_t *cp = NULL;
uint32_t sanity = 600;
switch_media_bug_flag_t read_flags = 0, write_flags = 0;
switch_media_bug_flag_t read_flags = 0, write_flags = 0, stereo_flag = 0;
const char *vval;
int buf_size = 0;
int channels;
int lcm, buff_min_len, buffered = 1;
if (!switch_channel_media_up(channel)) {
goto end;
}
if (tsession == session) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Eavesdrop target invalid.\n");
goto end;
}
while(switch_channel_state_change_pending(tchannel) || !switch_channel_media_up(tchannel)) {
switch_yield(10000);
if (!--sanity) break;
@ -2280,15 +2306,26 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session
ep = switch_core_session_alloc(session, sizeof(*ep));
tlen = tread_impl.decoded_bytes_per_packet;
if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
goto end;
}
if (switch_core_codec_init(&codec,
if (tread_impl.decoded_bytes_per_packet < read_impl.decoded_bytes_per_packet) {
if (switch_core_codec_init(&codec,
"L16",
NULL,
NULL,
read_impl.actual_samples_per_second,
read_impl.microseconds_per_packet / 1000,
read_impl.number_of_channels,
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot init codec\n");
goto end;
}
} else {
if (switch_core_codec_init(&codec,
"L16",
NULL,
NULL,
@ -2299,10 +2336,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session
NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot init codec\n");
goto end;
}
buffered = 0;
}
switch_core_session_get_read_impl(session, &read_impl);
ep->read_impl = read_impl;
ep->tread_impl = tread_impl;
@ -2356,6 +2393,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session
read_flags = 0;
}
if (flags & ED_STEREO) {
stereo_flag = SMBF_STEREO;
}
if (switch_channel_test_flag(session->channel, CF_VIDEO) && switch_channel_test_flag(tsession->channel, CF_VIDEO)) {
if ((vval = switch_channel_get_variable(session->channel, "eavesdrop_show_listener_video"))) {
@ -2384,7 +2424,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session
if (switch_core_media_bug_add(tsession, "eavesdrop", uuid,
eavesdrop_callback, ep, 0,
read_flags | write_flags | SMBF_READ_PING | SMBF_THREAD_LOCK | SMBF_NO_PAUSE,
read_flags | write_flags | SMBF_READ_PING | SMBF_THREAD_LOCK | SMBF_NO_PAUSE | stereo_flag,
&bug) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot attach bug\n");
goto end;
@ -2438,6 +2478,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session
switch_core_session_receive_message(tsession, &msg);
}
lcm = switch_lcm(tread_impl.decoded_bytes_per_packet, read_impl.decoded_bytes_per_packet);
while (switch_channel_up_nosig(tchannel) && switch_channel_ready(channel)) {
uint32_t len = sizeof(buf);
switch_event_t *event = NULL;
@ -2561,18 +2603,35 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session
switch_buffer_unlock(ep->w_buffer);
}
channels = switch_core_media_bug_test_flag(bug, SMBF_STEREO) ? 2 : tread_impl.number_of_channels;
if (channels == 0) {
channels = 1;
}
tlen = ep->read_impl.decoded_bytes_per_packet * channels;
if (len > tlen) {
len = tlen;
}
if (ep->buffer && switch_buffer_inuse(ep->buffer) >= len) {
if (buffered) {
buff_min_len = lcm * 2;
if (switch_buffer_inuse(ep->buffer) < buff_min_len) {
continue;
}
} else {
buff_min_len = len;
}
if (ep->buffer) {
switch_buffer_lock(ep->buffer);
while (switch_buffer_inuse(ep->buffer) >= len) {
while (switch_buffer_inuse(ep->buffer) >= buff_min_len) {
int tchanged = 0, changed = 0;
write_frame.datalen = (uint32_t) switch_buffer_read(ep->buffer, buf, len);
write_frame.samples = write_frame.datalen / 2;
write_frame.samples = write_frame.datalen / 2 / channels;
write_frame.channels = channels;
switch_core_session_get_read_impl(tsession, &tread_impl);
switch_core_session_get_read_impl(session, &read_impl);
@ -2582,7 +2641,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session
tchanged = 1;
}
if (read_impl.number_of_channels != ep->tread_impl.number_of_channels ||
if (read_impl.number_of_channels != ep->read_impl.number_of_channels ||
read_impl.actual_samples_per_second != ep->read_impl.actual_samples_per_second) {
changed = 1;
}
@ -2596,6 +2655,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session
ep->read_impl.number_of_channels,
read_impl.actual_samples_per_second,
read_impl.number_of_channels);
tlen = read_impl.decoded_bytes_per_packet * channels;
if (len > tlen) {
len = tlen;
}
}
if (tchanged) {
@ -2605,28 +2671,44 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session
ep->tread_impl.number_of_channels,
tread_impl.actual_samples_per_second,
tread_impl.number_of_channels);
}
tlen = tread_impl.decoded_bytes_per_packet;
if (len > tlen) {
len = tlen;
}
switch_core_codec_destroy(&codec);
switch_core_codec_destroy(&codec);
if (tread_impl.decoded_bytes_per_packet < read_impl.decoded_bytes_per_packet) {
if (switch_core_codec_init(&codec,
"L16",
NULL,
NULL,
tread_impl.actual_samples_per_second,
tread_impl.microseconds_per_packet / 1000,
tread_impl.number_of_channels,
read_impl.actual_samples_per_second,
read_impl.microseconds_per_packet / 1000,
read_impl.number_of_channels,
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot init codec\n");
switch_buffer_unlock(ep->buffer);
goto end;
}
buffered = 1;
lcm = switch_lcm(tread_impl.decoded_bytes_per_packet, read_impl.decoded_bytes_per_packet);
} else {
if (switch_core_codec_init(&codec,
"L16",
NULL,
NULL,
tread_impl.actual_samples_per_second,
tread_impl.microseconds_per_packet / 1000,
tread_impl.number_of_channels,
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot init codec\n");
switch_core_session_rwunlock(tsession);
switch_buffer_unlock(ep->buffer);
goto end;
}
if (buffered == 1) {
buffered = 0;
}
}
ep->read_impl = read_impl;
@ -2645,10 +2727,17 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_session(switch_core_session
if ((status = switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0)) != SWITCH_STATUS_SUCCESS) {
break;
}
switch_buffer_unlock(ep->buffer);
switch_buffer_lock(ep->buffer);
if (ep->tread_impl.decoded_bytes_per_packet == ep->read_impl.decoded_bytes_per_packet) {
/* push just the number of samples worth of a packet. */
break;
}
}
switch_buffer_unlock(ep->buffer);
}
}
end_loop:

View File

@ -830,6 +830,12 @@ static uint8_t check_channel_status(originate_global_t *oglobals, uint32_t len,
}
} else if (switch_channel_test_flag(oglobals->originate_status[i].peer_channel, CF_WINNER)) {
/* unset group_confirm variables */
switch_channel_set_variable(oglobals->originate_status[i].peer_channel, "group_confirm_key", NULL);
switch_channel_set_variable(oglobals->originate_status[i].peer_channel, "group_confirm_file", NULL);
switch_channel_set_variable(oglobals->originate_status[i].peer_channel, "group_confirm_error_file", NULL);
switch_channel_set_variable(oglobals->originate_status[i].peer_channel, "group_confirm_cancel_timeout", NULL);
switch_channel_set_variable(oglobals->originate_status[i].peer_channel, "group_confirm_read_timeout", NULL);
oglobals->idx = i;
rval = 0;
pindex = (uint32_t) i;
@ -2855,6 +2861,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
if (oglobals.session) {
if (!switch_channel_ready(caller_channel)) {
status = SWITCH_STATUS_FALSE;
if (local_var_event) switch_event_destroy(&local_var_event);
goto done;
}

View File

@ -1309,8 +1309,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
*arg++ = '\0';
}
if ((status = switch_ivr_phrase_macro(session, dup, arg, lang, args)) != SWITCH_STATUS_SUCCESS) {
arg_recursion_check_stop(args);
return status;
break;
}
continue;
} else {
@ -1327,8 +1326,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
if (engine && text) {
if ((status = switch_ivr_speak_text(session, engine, voice, (char *)text, args)) != SWITCH_STATUS_SUCCESS) {
arg_recursion_check_stop(args);
return status;
break;
}
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid Args\n");

View File

@ -605,17 +605,75 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_callback_exec_detailed(c
for (x = 1; x <= c; x++) {
SQLSMALLINT NameLength = 0, DataType = 0, DecimalDigits = 0, Nullable = 0;
SQLULEN ColumnSize = 0;
SQLLEN numRecs = 0;
SQLCHAR SqlState[6], Msg[SQL_MAX_MESSAGE_LENGTH];
SQLINTEGER NativeError;
SQLSMALLINT diagCount, MsgLen;
names[y] = malloc(name_len);
switch_assert(names[y]);
memset(names[y], 0, name_len);
SQLDescribeCol(stmt, x, (SQLCHAR *) names[y], (SQLSMALLINT) name_len, &NameLength, &DataType, &ColumnSize, &DecimalDigits, &Nullable);
if (!ColumnSize) {
if (ColumnSize <= 16383 || ColumnSize == 2147483647) {
SQLCHAR val[16384] = { 0 };
SQLLEN StrLen_or_IndPtr;
SQLRETURN rc;
ColumnSize = 16384;
SQLGetData(stmt, x, SQL_C_CHAR, val, ColumnSize, NULL);
vals[y] = strdup((char *)val);
/* check diag record and see if we can get real size
* https://docs.microsoft.com/en-us/sql/odbc/reference/develop-app/using-sqlgetdiagrec-and-sqlgetdiagfield?view=sql-server-ver15
* szSqlState = "01004" and StrLen_or_IndPtr=15794
*/
rc = SQLGetData(stmt, x, SQL_C_CHAR, val, ColumnSize, &StrLen_or_IndPtr);
if (rc == SQL_SUCCESS_WITH_INFO) {
int truncated = 0;
diagCount = 1;
SQLGetDiagField(SQL_HANDLE_STMT, stmt, 0, SQL_DIAG_NUMBER, &numRecs, 0, 0);
while (diagCount <= numRecs) {
SQLGetDiagRec(SQL_HANDLE_STMT, stmt, diagCount, SqlState, &NativeError,Msg, sizeof(Msg), &MsgLen);
if (!strcmp((char*)SqlState,"01004")){
truncated = 1;
break;
}
diagCount++;
}
if (truncated) {
if (StrLen_or_IndPtr && StrLen_or_IndPtr <= 268435456) {
int ValLen = strlen((char*)val);
ColumnSize = StrLen_or_IndPtr + 1;
vals[y] = malloc(ColumnSize);
switch_assert(vals[y]);
memset(vals[y], 0, ColumnSize);
strcpy(vals[y], (char*)val);
rc = SQLGetData(stmt, x, SQL_C_CHAR, (SQLCHAR *)vals[y] + ValLen, ColumnSize - ValLen, NULL);
if (rc != SQL_SUCCESS
#if (ODBCVER >= 0x0300)
&& rc != SQL_NO_DATA
#endif
) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQLGetData was truncated and failed to complete.\n");
switch_safe_free(vals[y]);
}
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sql data truncated - %s\n",SqlState);
vals[y] = NULL;
}
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQLGetData failed\n");
vals[y] = NULL;
}
} else if (rc == SQL_SUCCESS){
vals[y] = strdup((char *)val);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQLGetData failed\n");
vals[y] = NULL;
}
} else {
ColumnSize++;
@ -633,7 +691,7 @@ SWITCH_DECLARE(switch_odbc_status_t) switch_odbc_handle_callback_exec_detailed(c
for (x = 0; x < y; x++) {
free(names[x]);
free(vals[x]);
switch_safe_free(vals[x]);
}
free(names);
free(vals);

View File

@ -2991,7 +2991,7 @@ static void ping_socket(switch_rtp_t *rtp_session)
switch_size_t len = sizeof(o);
switch_socket_sendto(rtp_session->sock_input, rtp_session->local_addr, 0, (void *) &o, &len);
if (rtp_session->flags[SWITCH_RTP_FLAG_ENABLE_RTCP] && rtp_session->rtcp_sock_input) {
if (rtp_session->flags[SWITCH_RTP_FLAG_ENABLE_RTCP] && rtp_session->rtcp_sock_input && rtp_session->rtcp_sock_input != rtp_session->sock_input) {
switch_socket_sendto(rtp_session->rtcp_sock_input, rtp_session->rtcp_local_addr, 0, (void *) &o, &len);
}
}
@ -5077,11 +5077,11 @@ SWITCH_DECLARE(void) switch_rtp_kill_socket(switch_rtp_t *rtp_session)
}
if (rtp_session->flags[SWITCH_RTP_FLAG_ENABLE_RTCP]) {
if (rtp_session->rtcp_sock_input) {
if (rtp_session->rtcp_sock_input && rtp_session->rtcp_sock_input != rtp_session->sock_input) {
ping_socket(rtp_session);
switch_socket_shutdown(rtp_session->rtcp_sock_input, SWITCH_SHUTDOWN_READWRITE);
}
if (rtp_session->rtcp_sock_output && rtp_session->rtcp_sock_output != rtp_session->rtcp_sock_input) {
if (rtp_session->rtcp_sock_output && rtp_session->rtcp_sock_output != rtp_session->sock_output && rtp_session->rtcp_sock_output != rtp_session->rtcp_sock_input) {
switch_socket_shutdown(rtp_session->rtcp_sock_output, SWITCH_SHUTDOWN_READWRITE);
}
}
@ -5197,6 +5197,13 @@ SWITCH_DECLARE(void) switch_rtp_destroy(switch_rtp_t **rtp_session)
free_dtls(&(*rtp_session)->rtcp_dtls);
}
if ((*rtp_session)->rtcp_sock_input == (*rtp_session)->sock_input) {
(*rtp_session)->rtcp_sock_input = NULL;
}
if ((*rtp_session)->rtcp_sock_output == (*rtp_session)->sock_output) {
(*rtp_session)->rtcp_sock_output = NULL;
}
sock = (*rtp_session)->sock_input;
(*rtp_session)->sock_input = NULL;
@ -5211,13 +5218,12 @@ SWITCH_DECLARE(void) switch_rtp_destroy(switch_rtp_t **rtp_session)
if ((sock = (*rtp_session)->rtcp_sock_input)) {
(*rtp_session)->rtcp_sock_input = NULL;
switch_socket_close(sock);
}
if ((*rtp_session)->rtcp_sock_output && (*rtp_session)->rtcp_sock_output != sock) {
if ((sock = (*rtp_session)->rtcp_sock_output)) {
(*rtp_session)->rtcp_sock_output = NULL;
switch_socket_close(sock);
}
}
if ((*rtp_session)->rtcp_sock_output && (*rtp_session)->rtcp_sock_output != sock) {
sock = (*rtp_session)->rtcp_sock_output;
(*rtp_session)->rtcp_sock_output = NULL;
switch_socket_close(sock);
}
#ifdef ENABLE_SRTP

View File

@ -209,9 +209,21 @@ static void *SWITCH_THREAD_FUNC switch_scheduler_task_thread(switch_thread_t *th
}
SWITCH_DECLARE(uint32_t) switch_scheduler_add_task(time_t task_runtime,
switch_scheduler_func_t func,
const char *desc, const char *group, uint32_t cmd_id, void *cmd_arg, switch_scheduler_flag_t flags)
switch_scheduler_func_t func,
const char *desc, const char *group, uint32_t cmd_id, void *cmd_arg, switch_scheduler_flag_t flags)
{
uint32_t task_id;
switch_scheduler_add_task_ex(task_runtime, func, desc, group, cmd_id, cmd_arg, flags, &task_id);
return task_id;
}
SWITCH_DECLARE(uint32_t) switch_scheduler_add_task_ex(time_t task_runtime,
switch_scheduler_func_t func,
const char *desc, const char *group, uint32_t cmd_id, void *cmd_arg, switch_scheduler_flag_t flags, uint32_t *task_id)
{
uint32_t result;
switch_scheduler_task_container_t *container, *tp;
switch_event_t *event;
switch_time_t now = switch_epoch_time_now(NULL);
@ -220,6 +232,7 @@ SWITCH_DECLARE(uint32_t) switch_scheduler_add_task(time_t task_runtime,
switch_mutex_lock(globals.task_mutex);
switch_zmalloc(container, sizeof(*container));
switch_assert(func);
switch_assert(task_id);
if (task_runtime < now) {
container->task.repeat = (uint32_t)task_runtime;
@ -246,8 +259,6 @@ SWITCH_DECLARE(uint32_t) switch_scheduler_add_task(time_t task_runtime,
for (container->task.task_id = 0; !container->task.task_id; container->task.task_id = ++globals.task_id);
switch_mutex_unlock(globals.task_mutex);
tp = container;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Added task %u %s (%s) to run at %" SWITCH_INT64_T_FMT "\n",
tp->task.task_id, tp->desc, switch_str_nil(tp->task.group), tp->task.runtime);
@ -260,7 +271,12 @@ SWITCH_DECLARE(uint32_t) switch_scheduler_add_task(time_t task_runtime,
switch_queue_push(globals.event_queue, event);
event = NULL;
}
return container->task.task_id;
result = *task_id = container->task.task_id;
switch_mutex_unlock(globals.task_mutex);
return result;
}
SWITCH_DECLARE(uint32_t) switch_scheduler_del_task_id(uint32_t task_id)

View File

@ -4176,11 +4176,12 @@ SWITCH_DECLARE(void) switch_http_parse_qs(switch_http_request_t *request, char *
char *q;
char *next;
char *name, *val;
char *dup = NULL;
if (qs) {
q = qs;
} else { /*parse our own qs, dup to avoid modify the original string */
q = strdup(request->qs);
dup = q = strdup(request->qs);
}
switch_assert(q);
@ -4207,9 +4208,7 @@ SWITCH_DECLARE(void) switch_http_parse_qs(switch_http_request_t *request, char *
q = next;
} while (q);
if (!qs) {
switch_safe_free(q);
}
switch_safe_free(dup);
}
/* clean the uri to protect us from vulnerability attack */

View File

@ -2,13 +2,18 @@ include $(top_srcdir)/build/modmake.rulesam
noinst_PROGRAMS = switch_event switch_hash switch_ivr_originate switch_utils switch_core switch_console switch_vpx switch_core_file \
switch_ivr_play_say switch_core_codec switch_rtp switch_xml
noinst_PROGRAMS += switch_core_video switch_core_db switch_vad switch_core_asr
noinst_PROGRAMS += switch_core_video switch_core_db switch_vad switch_core_asr test_sofia
AM_LDFLAGS += -avoid-version -no-undefined $(SWITCH_AM_LDFLAGS) $(openssl_LIBS)
AM_LDFLAGS += $(FREESWITCH_LIBS) $(switch_builddir)/libfreeswitch.la $(CORE_LIBS) $(APR_LIBS)
# "make check" will not run these.
examples = switch_eavesdrop
if HAVE_FVAD
AM_CFLAGS += -DSWITCH_HAVE_FVAD
endif
TESTS = $(noinst_PROGRAMS)
bin_PROGRAMS = $(examples)

View File

@ -0,0 +1,238 @@
<?xml version="1.0"?>
<document type="freeswitch/xml">
<X-PRE-PROCESS cmd="exec-set" data="test=echo 1234"/>
<X-PRE-PROCESS cmd="set" data="default_password=$${test}"/>
<X-PRE-PROCESS cmd="set" data="core_video_blank_image=$${conf_dir}/freeswitch-logo.png"/>
<section name="configuration" description="Various Configuration">
<configuration name="modules.conf" description="Modules">
<modules>
<load module="mod_sofia"/>
<load module="mod_console"/>
<load module="mod_loopback"/>
<load module="mod_commands"/>
<load module="mod_dptools"/>
<load module="mod_dialplan_xml"/>
<load module="mod_tone_stream"/>
<load module="mod_commands"/>
<load module="mod_sndfile"/>
</modules>
</configuration>
<configuration name="console.conf" description="Console Logger">
<mappings>
<map name="all" value="console,debug,info,notice,warning,err,crit,alert"/>
</mappings>
<settings>
<param name="colorize" value="true"/>
<param name="loglevel" value="debug"/>
</settings>
</configuration>
<configuration name="timezones.conf" description="Timezones">
<timezones>
<zone name="GMT" value="GMT0" />
</timezones>
</configuration>
<configuration name="sofia.conf" description="SofiaSIP">
<profiles>
<profile name="external">
<gateways>
<gateway name="eavestest">
<param name="username" value="not-used"/>
<param name="password" value="not-used"/>
<param name="proxy" value="$${local_ip_v4}:61068"/>
<param name="register" value="false"/>
<param name="retry-seconds" value="30"/>
<param name="dtmf-type" value="rfc2833"/>
<variables>
<variable name="rtp_secure_media" value="false" direction="outbound"/>
</variables>
</gateway>
</gateways>
<domains>
<domain name="all" alias="false" parse="true"/>
</domains>
<settings>
<param name="debug" value="1"/>
<param name="shutdown-on-fail" value="true"/>
<param name="p-asserted-id-parse" value="verbatim"/>
<param name="username" value="SignalWire-STACK"/>
<param name="user-agent-string" value="SignalWire STACK Unit Test"/>
<param name="sip-trace" value="yes"/>
<param name="sip-capture" value="no"/>
<param name="rfc2833-pt" value="101"/>
<param name="sip-port" value="61068"/>
<param name="dialplan" value="XML"/>
<param name="context" value="default"/>
<param name="dtmf-duration" value="2000"/>
<param name="inbound-codec-prefs" value="PCMU"/>
<param name="outbound-codec-prefs" value="PCMU"/>
<param name="rtp-timer-name" value="soft"/>
<param name="local-network-acl" value="localnet.auto"/>
<param name="manage-presence" value="false"/>
<param name="inbound-codec-negotiation" value="generous"/>
<param name="nonce-ttl" value="60"/>
<param name="inbound-late-negotiation" value="true"/>
<param name="inbound-zrtp-passthru" value="false"/>
<param name="rtp-ip" value="$${local_ip_v4}"/>
<param name="sip-ip" value="$${local_ip_v4}"/>
<param name="ext-rtp-ip" value="$${local_ip_v4}"/>
<param name="ext-sip-ip" value="$${local_ip_v4}"/>
<param name="rtp-timeout-sec" value="300"/>
<param name="rtp-hold-timeout-sec" value="1800"/>
<param name="session-timeout" value="600"/>
<param name="minimum-session-expires" value="90"/>
<param name="tls" value="false"/>
</settings>
</profile>
<profile name="internal">
<gateways>
</gateways>
<domains>
<domain name="all" alias="false" parse="true"/>
</domains>
<settings>
<param name="debug" value="1"/>
<param name="shutdown-on-fail" value="true"/>
<param name="p-asserted-id-parse" value="verbatim"/>
<param name="username" value="SignalWire-STACK"/>
<param name="user-agent-string" value="SignalWire STACK Unit Test"/>
<param name="sip-trace" value="yes"/>
<param name="sip-capture" value="no"/>
<param name="rfc2833-pt" value="101"/>
<param name="sip-port" value="61069"/>
<param name="dialplan" value="XML"/>
<param name="context" value="default"/>
<param name="dtmf-duration" value="2000"/>
<param name="inbound-codec-prefs" value="PCMU"/>
<param name="outbound-codec-prefs" value="PCMU"/>
<param name="rtp-timer-name" value="soft"/>
<param name="local-network-acl" value="localnet.auto"/>
<param name="manage-presence" value="false"/>
<param name="inbound-codec-negotiation" value="generous"/>
<param name="nonce-ttl" value="60"/>
<param name="inbound-late-negotiation" value="true"/>
<param name="inbound-zrtp-passthru" value="false"/>
<param name="rtp-ip" value="$${local_ip_v4}"/>
<param name="sip-ip" value="$${local_ip_v4}"/>
<param name="ext-rtp-ip" value="$${local_ip_v4}"/>
<param name="ext-sip-ip" value="$${local_ip_v4}"/>
<param name="rtp-timeout-sec" value="300"/>
<param name="rtp-hold-timeout-sec" value="1800"/>
<param name="session-timeout" value="600"/>
<param name="minimum-session-expires" value="90"/>
<param name="tls" value="false"/>
</settings>
</profile>
</profiles>
</configuration>
<configuration name="switch.conf" description="Switch">
<param name="rtp-start-port" value="20000"/>
<param name="rtp-end-port" value="30000"/>
<param name="threaded-system-exec" value="true"/>
</configuration>
</section>
<section name="dialplan" description="Regex/XML Dialplan">
<context name="default">
<extension name="one">
<condition field="destination_number" expression="^\+15553332220$">
<action application="set" data="absolute_codec_string=PCMU@20i"/>
<action application="info"/>
<action application="answer"/>
<action application="park""/>
</condition>
</extension>
<extension name="two">
<condition field="destination_number" expression="^\+15553332221$">
<action application="set" data="absolute_codec_string=PCMU@10i"/>
<action application="info"/>
<action application="answer"/>
<action application="playback" data="{loops=-1}tone_stream://%(251,0,300)"/>
</condition>
</extension>
<extension name="three">
<condition field="destination_number" expression="^\+15553332222$">
<action application="set" data="absolute_codec_string=PCMU@30i"/>
<action application="info"/>
<action application="answer"/>
<action application="playback" data="{loops=-1}tone_stream://%(251,0,300)"/>
</condition>
</extension>
<extension name="four">
<condition field="destination_number" expression="^\+15553332223$">
<action application="set" data="absolute_codec_string=PCMU@40i"/>
<action application="info"/>
<action application="answer"/>
<action application="playback" data="{loops=-1}tone_stream://%(251,0,300)"/>
</condition>
</extension>
<extension name="five">
<condition field="destination_number" expression="^\+15553332224$">
<action application="set" data="absolute_codec_string=PCMU@80i"/>
<action application="info"/>
<action application="answer"/>
<action application="playback" data="{loops=-1}tone_stream://%(251,0,300)"/>
</condition>
</extension>
<extension name="six">
<condition field="destination_number" expression="^\+15553332225$">
<action application="set" data="absolute_codec_string=PCMU@10i"/>
<action application="info"/>
<action application="answer"/>
<action application="playback" data="{loops=-1}tone_stream://%(251,0,300)"/>
</condition>
</extension>
<extension name="seven">
<condition field="destination_number" expression="^\+15553332226$">
<action application="set" data="absolute_codec_string=PCMU@20i"/>
<action application="info"/>
<action application="answer"/>
<action application="record_session" data="/tmp/eaves-${uuid}.wav"/>
<action application="playback" data="{loops=-1}tone_stream://%(251,0,300)"/>
</condition>
</extension>
<extension name="eavesdropper_20ms">
<condition field="destination_number" expression="^\+15553332230$">
<action application="answer"/>
<action application="record_session" data="/tmp/eaves-${sip_h_X-UnitTestRecfile}.wav"/>
<action application="playback" data="silence_stream://-1,1400"/>
</condition>
</extension>
<extension name="eight">
<condition field="destination_number" expression="^\+15553332231$">
<action application="answer"/>
<action application="park"/>
</condition>
</extension>
<extension name="eavesdropper_30ms">
<condition field="destination_number" expression="^\+15553332240$">
<action application="set" data="absolute_codec_string=PCMU@30i"/>
<action application="answer"/>
<action application="record_session" data="/tmp/eaves-${sip_h_X-UnitTestRecfile}.wav"/>
<action application="playback" data="silence_stream://-1,1400"/>
</condition>
</extension>
<extension name="ten">
<condition field="destination_number" expression="^\+15553332241$">
<action application="set" data="absolute_codec_string=PCMU@30i"/>
<action application="info"/>
<action application="answer"/>
<action application="playback" data="{loops=-1}tone_stream://%(251,0,300)"/>
</condition>
</extension>
</context>
</section>
</document>

View File

@ -0,0 +1,14 @@
<include/>
<gateway name="eavestest">
<param name="username" value="not-used"/>
<param name="password" value="not-used"/>
<param name="proxy" value="127.0.0.1"/>
<param name="register" value="false"/>
<param name="retry-seconds" value="30"/>
<param name="dtmf-type" value="rfc2833"/>
<variables>
<variable name="rtp_secure_media" value="false" direction="outbound"/>
</variables>
</gateway>
</include>

View File

@ -0,0 +1,144 @@
<?xml version="1.0"?>
<document type="freeswitch/xml">
<section name="configuration" description="Various Configuration">
<configuration name="modules.conf" description="Modules">
<modules>
<load module="mod_sofia"/>
</modules>
</configuration>
<configuration name="console.conf" description="Console Logger">
<mappings>
<map name="all" value="console,debug,info,notice,warning,err,crit,alert"/>
</mappings>
<settings>
<param name="colorize" value="true"/>
<param name="uuid" value="true"/>
<param name="loglevel" value="debug"/>
</settings>
</configuration>
<configuration name="sofia.conf" description="SofiaSIP">
<profiles>
<profile name="external">
<gateways>
<gateway name="faxtest">
<param name="username" value="not-used"/>
<param name="password" value="not-used"/>
<param name="proxy" value="$${local_ip_v4}:61060"/>
<param name="register" value="false"/>
<param name="retry-seconds" value="30"/>
<param name="dtmf-type" value="rfc2833"/>
<variables>
<variable name="rtp_secure_media" value="false" direction="outbound"/>
</variables>
</gateway>
</gateways>
<domains>
<domain name="all" alias="false" parse="true"/>
</domains>
<settings>
<param name="debug" value="1"/>
<param name="shutdown-on-fail" value="true"/>
<param name="p-asserted-id-parse" value="verbatim"/>
<param name="username" value="SignalWire-STACK"/>
<param name="user-agent-string" value="SignalWire STACK Unit Test"/>
<param name="sip-trace" value="yes"/>
<param name="sip-capture" value="no"/>
<param name="rfc2833-pt" value="101"/>
<param name="sip-port" value="61060"/>
<param name="dialplan" value="XML"/>
<param name="context" value="default"/>
<param name="dtmf-duration" value="2000"/>
<param name="inbound-codec-prefs" value="PCMU"/>
<param name="outbound-codec-prefs" value="PCMU"/>
<param name="rtp-timer-name" value="soft"/>
<param name="local-network-acl" value="localnet.auto"/>
<param name="manage-presence" value="false"/>
<param name="inbound-codec-negotiation" value="generous"/>
<param name="nonce-ttl" value="60"/>
<param name="inbound-late-negotiation" value="true"/>
<param name="inbound-zrtp-passthru" value="false"/>
<param name="rtp-ip" value="$${local_ip_v4}"/>
<param name="sip-ip" value="$${local_ip_v4}"/>
<param name="ext-rtp-ip" value="$${local_ip_v4}"/>
<param name="ext-sip-ip" value="$${local_ip_v4}"/>
<param name="rtp-timeout-sec" value="300"/>
<param name="rtp-hold-timeout-sec" value="1800"/>
<param name="session-timeout" value="600"/>
<param name="minimum-session-expires" value="90"/>
<param name="tls" value="false"/>
</settings>
</profile>
<profile name="internal">
<gateways>
</gateways>
<domains>
<domain name="all" alias="false" parse="true"/>
</domains>
<settings>
<param name="debug" value="1"/>
<param name="shutdown-on-fail" value="true"/>
<param name="p-asserted-id-parse" value="verbatim"/>
<param name="username" value="SignalWire-STACK"/>
<param name="user-agent-string" value="SignalWire STACK Unit Test"/>
<param name="sip-trace" value="yes"/>
<param name="sip-capture" value="no"/>
<param name="rfc2833-pt" value="101"/>
<param name="sip-port" value="61061"/>
<param name="dialplan" value="XML"/>
<param name="context" value="default"/>
<param name="dtmf-duration" value="2000"/>
<param name="inbound-codec-prefs" value="PCMU"/>
<param name="outbound-codec-prefs" value="PCMU"/>
<param name="rtp-timer-name" value="soft"/>
<param name="local-network-acl" value="localnet.auto"/>
<param name="manage-presence" value="false"/>
<param name="inbound-codec-negotiation" value="generous"/>
<param name="nonce-ttl" value="60"/>
<param name="inbound-late-negotiation" value="true"/>
<param name="inbound-zrtp-passthru" value="false"/>
<param name="rtp-ip" value="$${local_ip_v4}"/>
<param name="sip-ip" value="$${local_ip_v4}"/>
<param name="ext-rtp-ip" value="$${local_ip_v4}"/>
<param name="ext-sip-ip" value="$${local_ip_v4}"/>
<param name="rtp-timeout-sec" value="300"/>
<param name="rtp-hold-timeout-sec" value="1800"/>
<param name="session-timeout" value="600"/>
<param name="minimum-session-expires" value="90"/>
<param name="tls" value="false"/>
</settings>
</profile>
</profiles>
</configuration>
<configuration name="switch.conf" description="Switch">
<param name="rtp-start-port" value="20000"/>
<param name="rtp-end-port" value="30000"/>
<param name="threaded-system-exec" value="true"/>
</configuration>
<configuration name="timezones.conf" description="Timezones">
<timezones>
<zone name="GMT" value="GMT0" />
</timezones>
</configuration>
</section>
<section name="dialplan" description="Regex/XML Dialplan">
<context name="default">
<extension name="sample">
<condition>
<action application="info"/>
</condition>
</extension>
</context>
</section>
</document>

View File

@ -0,0 +1,387 @@
#include <switch.h>
#include <test/switch_test.h>
static switch_status_t test_detect_long_tone_in_file(const char *filepath, int rate, int freq, int ptime) {
teletone_multi_tone_t mt;
teletone_tone_map_t map;
int16_t data[SWITCH_RECOMMENDED_BUFFER_SIZE] = { 0 };
switch_size_t len = (rate * ptime / 1000) /*packet len in samples */ * 8; /*length of chunk that must contain tone*/
switch_size_t fin = 0;
switch_status_t status;
switch_file_handle_t fh = { 0 };
uint8_t fail = 0, gaps = 0, audio = 0;
status = switch_core_file_open(&fh, filepath, 1, rate, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL);
if (status != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot open file [%s]\n", filepath);
return SWITCH_STATUS_FALSE;
}
mt.sample_rate = rate;
map.freqs[0] = (teletone_process_t)freq;
teletone_multi_tone_init(&mt, &map);
len = (rate * 2 / 100) /*packet len in samples */ * 8;
while (switch_core_file_read(&fh, &data, &len) == SWITCH_STATUS_SUCCESS) {
fin += len;
/*skip silence at the beginning of the file, 1 second max. */
if (!teletone_multi_tone_detect(&mt, data, len)) {
if ((fin > rate && !audio) || gaps > 30) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Too many gaps in audio or no tone detected 1st second. [%" SWITCH_SIZE_T_FMT "][%d]\n", fin, gaps);
fail = 1;
break;
}
gaps++;
continue;
} else {
audio++;
}
}
switch_core_file_close(&fh);
if (fail) {
return SWITCH_STATUS_FALSE;
}
return SWITCH_STATUS_SUCCESS;
}
FST_CORE_BEGIN("./conf_eavesdrop")
{
FST_SUITE_BEGIN(switch_eavesdrop)
{
FST_SETUP_BEGIN()
{
fst_requires_module("mod_loopback");
fst_requires_module("mod_sofia");
switch_core_set_variable("link_ip", switch_core_get_variable("local_ip_v4"));
}
FST_SETUP_END()
FST_TEARDOWN_BEGIN()
{
}
FST_TEARDOWN_END()
FST_TEST_BEGIN(test_eavesdrop_bridged_same_ptime_20ms)
{
switch_core_session_t *session1 = NULL;
switch_core_session_t *session2 = NULL;
switch_core_session_t *session3 = NULL;
switch_channel_t *channel1 = NULL;
switch_channel_t *channel2 = NULL;
switch_channel_t *channel3 = NULL;
switch_status_t status;
switch_call_cause_t cause;
switch_stream_handle_t stream = { 0 };
char eavesdrop_command[256] = { 0 };
char rec_path[1024];
char rec_uuid[SWITCH_UUID_FORMATTED_LENGTH + 1] = { 0 };
char eaves_dialstr[512] = { 0 };
switch_uuid_str(rec_uuid, sizeof(rec_uuid));
/*parked 20 ms ptime */
status = switch_ivr_originate(NULL, &session1, &cause, "{ignore_early_media=true}sofia/gateway/eavestest/+15553332220", 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
fst_requires(session1);
fst_check(status == SWITCH_STATUS_SUCCESS);
channel1 = switch_core_session_get_channel(session1);
fst_requires(channel1);
snprintf(eaves_dialstr, sizeof(eaves_dialstr), "{ignore_early_media=true}{sip_h_X-UnitTestRecfile=%s}sofia/gateway/eavestest/+15553332230", rec_uuid);
/*eavesdropper 20 ms ptime*/
status = switch_ivr_originate(NULL, &session2, &cause, eaves_dialstr, 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
fst_requires(session2);
fst_check(status == SWITCH_STATUS_SUCCESS);
channel2 = switch_core_session_get_channel(session2);
fst_requires(channel2);
/*milliwatt tone 20 ms ptime*/
status = switch_ivr_originate(NULL, &session3, &cause, "{ignore_early_media=true}sofia/gateway/eavestest/+15553332226", 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
fst_requires(session3);
fst_check(status == SWITCH_STATUS_SUCCESS);
channel3 = switch_core_session_get_channel(session3);
fst_requires(channel3);
SWITCH_STANDARD_STREAM(stream);
switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command), "uuid_bridge %s %s", switch_core_session_get_uuid(session1), switch_core_session_get_uuid(session2));
switch_api_execute("bgapi", eavesdrop_command, session1, &stream);
memset(eavesdrop_command, 0, sizeof(eavesdrop_command));
switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command),"uuid_setvar_multi %s eavesdrop_enable_dtmf=false;eavesdrop_whisper_bleg=true;eavesdrop_whisper_aleg=false", switch_core_session_get_uuid(session3));
switch_api_execute("bgapi", eavesdrop_command, session3, &stream);
memset(eavesdrop_command, 0, sizeof(eavesdrop_command));
switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command), "uuid_transfer %s 'eavesdrop:%s' inline", switch_core_session_get_uuid(session3), switch_core_session_get_uuid(session2));
switch_api_execute("bgapi", eavesdrop_command, session3, &stream);
switch_safe_free(stream.data);
sleep(5); // it will record ~ 5 secs
snprintf(rec_path, sizeof(rec_path), "/tmp/eaves-%s.wav", rec_uuid);
fst_requires(switch_file_exists(rec_path, fst_pool) == SWITCH_STATUS_SUCCESS);
fst_requires(test_detect_long_tone_in_file(rec_path, 8000, 300, 20) == SWITCH_STATUS_SUCCESS);
unlink(rec_path);
switch_channel_hangup(channel1, SWITCH_CAUSE_NORMAL_CLEARING);
switch_channel_hangup(channel2, SWITCH_CAUSE_NORMAL_CLEARING);
switch_channel_hangup(channel3, SWITCH_CAUSE_NORMAL_CLEARING);
switch_core_session_rwunlock(session1);
switch_core_session_rwunlock(session2);
switch_core_session_rwunlock(session3);
}
FST_TEST_END()
FST_TEST_BEGIN(test_eavesdrop_bridged_ptime_mismatch_20ms_30ms)
{
switch_core_session_t *session1 = NULL;
switch_core_session_t *session2 = NULL;
switch_core_session_t *session3 = NULL;
switch_channel_t *channel1 = NULL;
switch_channel_t *channel2 = NULL;
switch_channel_t *channel3 = NULL;
switch_status_t status;
switch_call_cause_t cause;
switch_stream_handle_t stream = { 0 };
char eavesdrop_command[256] = { 0 };
char rec_path[1024];
char rec_uuid[SWITCH_UUID_FORMATTED_LENGTH + 1] = { 0 };
char eaves_dialstr[512] = { 0 };
switch_uuid_str(rec_uuid, sizeof(rec_uuid));
/*parked 20 ms ptime */
status = switch_ivr_originate(NULL, &session1, &cause, "{ignore_early_media=true}sofia/gateway/eavestest/+15553332220", 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
fst_requires(session1);
fst_check(status == SWITCH_STATUS_SUCCESS);
channel1 = switch_core_session_get_channel(session1);
fst_requires(channel1);
snprintf(eaves_dialstr, sizeof(eaves_dialstr), "{ignore_early_media=true}{sip_h_X-UnitTestRecfile=%s}sofia/gateway/eavestest/+15553332230", rec_uuid);
/*eavesdropper 20 ms ptime*/
status = switch_ivr_originate(NULL, &session2, &cause, eaves_dialstr, 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
fst_requires(session2);
fst_check(status == SWITCH_STATUS_SUCCESS);
channel2 = switch_core_session_get_channel(session2);
fst_requires(channel2);
/*milliwatt tone 30 ms ptime*/
status = switch_ivr_originate(NULL, &session3, &cause, "{ignore_early_media=true}sofia/gateway/eavestest/+15553332222", 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
fst_requires(session3);
fst_check(status == SWITCH_STATUS_SUCCESS);
channel3 = switch_core_session_get_channel(session3);
fst_requires(channel3);
SWITCH_STANDARD_STREAM(stream);
switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command), "uuid_bridge %s %s", switch_core_session_get_uuid(session1), switch_core_session_get_uuid(session2));
switch_api_execute("bgapi", eavesdrop_command, session1, &stream);
memset(eavesdrop_command, 0, sizeof(eavesdrop_command));
switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command),"uuid_setvar_multi %s eavesdrop_enable_dtmf=false;eavesdrop_whisper_bleg=true;eavesdrop_whisper_aleg=false", switch_core_session_get_uuid(session3));
switch_api_execute("bgapi", eavesdrop_command, session3, &stream);
memset(eavesdrop_command, 0, sizeof(eavesdrop_command));
switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command), "uuid_transfer %s 'eavesdrop:%s' inline", switch_core_session_get_uuid(session3), switch_core_session_get_uuid(session2));
switch_api_execute("bgapi", eavesdrop_command, session3, &stream);
switch_safe_free(stream.data);
sleep(5); // it will record ~ 5 secs
snprintf(rec_path, sizeof(rec_path), "/tmp/eaves-%s.wav", rec_uuid);
fst_requires(switch_file_exists(rec_path, fst_pool) == SWITCH_STATUS_SUCCESS);
fst_requires(test_detect_long_tone_in_file(rec_path, 8000, 300, 20) == SWITCH_STATUS_SUCCESS);
unlink(rec_path);
switch_channel_hangup(channel1, SWITCH_CAUSE_NORMAL_CLEARING);
switch_channel_hangup(channel2, SWITCH_CAUSE_NORMAL_CLEARING);
switch_channel_hangup(channel3, SWITCH_CAUSE_NORMAL_CLEARING);
switch_core_session_rwunlock(session1);
switch_core_session_rwunlock(session2);
switch_core_session_rwunlock(session3);
}
FST_TEST_END()
FST_TEST_BEGIN(test_eavesdrop_bridged_ptime_mismatch_30ms_20ms)
{
switch_core_session_t *session1 = NULL;
switch_core_session_t *session2 = NULL;
switch_core_session_t *session3 = NULL;
switch_channel_t *channel1 = NULL;
switch_channel_t *channel2 = NULL;
switch_channel_t *channel3 = NULL;
switch_status_t status;
switch_call_cause_t cause;
switch_stream_handle_t stream = { 0 };
char eavesdrop_command[256] = { 0 };
char rec_path[1024];
char rec_uuid[SWITCH_UUID_FORMATTED_LENGTH + 1] = { 0 };
char eaves_dialstr[512] = { 0 };
switch_uuid_str(rec_uuid, sizeof(rec_uuid));
/*parked 30 ms ptime */
status = switch_ivr_originate(NULL, &session1, &cause, "{ignore_early_media=true}sofia/gateway/eavestest/+15553332231", 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
fst_requires(session1);
fst_check(status == SWITCH_STATUS_SUCCESS);
channel1 = switch_core_session_get_channel(session1);
fst_requires(channel1);
snprintf(eaves_dialstr, sizeof(eaves_dialstr), "{ignore_early_media=true}{sip_h_X-UnitTestRecfile=%s}sofia/gateway/eavestest/+15553332240", rec_uuid);
/*eavesdropper 30 ms ptime*/
status = switch_ivr_originate(NULL, &session2, &cause, eaves_dialstr, 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
fst_requires(session2);
fst_check(status == SWITCH_STATUS_SUCCESS);
channel2 = switch_core_session_get_channel(session2);
fst_requires(channel2);
/*milliwatt tone 20 ms ptime*/
status = switch_ivr_originate(NULL, &session3, &cause, "{ignore_early_media=true}sofia/gateway/eavestest/+15553332226", 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
fst_requires(session3);
fst_check(status == SWITCH_STATUS_SUCCESS);
channel3 = switch_core_session_get_channel(session3);
fst_requires(channel3);
SWITCH_STANDARD_STREAM(stream);
switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command), "uuid_bridge %s %s", switch_core_session_get_uuid(session1), switch_core_session_get_uuid(session2));
switch_api_execute("bgapi", eavesdrop_command, session1, &stream);
memset(eavesdrop_command, 0, sizeof(eavesdrop_command));
switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command),"uuid_setvar_multi %s eavesdrop_enable_dtmf=false;eavesdrop_whisper_bleg=true;eavesdrop_whisper_aleg=false", switch_core_session_get_uuid(session3));
switch_api_execute("bgapi", eavesdrop_command, session3, &stream);
memset(eavesdrop_command, 0, sizeof(eavesdrop_command));
switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command), "uuid_transfer %s 'eavesdrop:%s' inline", switch_core_session_get_uuid(session3), switch_core_session_get_uuid(session2));
switch_api_execute("bgapi", eavesdrop_command, session3, &stream);
switch_safe_free(stream.data);
sleep(5); // it will record ~ 5 secs
snprintf(rec_path, sizeof(rec_path), "/tmp/eaves-%s.wav", rec_uuid);
fst_requires(switch_file_exists(rec_path, fst_pool) == SWITCH_STATUS_SUCCESS);
fst_requires(test_detect_long_tone_in_file(rec_path, 8000, 300, 30) == SWITCH_STATUS_SUCCESS);
unlink(rec_path);
switch_channel_hangup(channel1, SWITCH_CAUSE_NORMAL_CLEARING);
switch_channel_hangup(channel2, SWITCH_CAUSE_NORMAL_CLEARING);
switch_channel_hangup(channel3, SWITCH_CAUSE_NORMAL_CLEARING);
switch_core_session_rwunlock(session1);
switch_core_session_rwunlock(session2);
switch_core_session_rwunlock(session3);
}
FST_TEST_END()
FST_TEST_BEGIN(test_eavesdrop_bridged_ptime_mismatch_reneg)
{
switch_core_session_t *session1 = NULL;
switch_core_session_t *session2 = NULL;
switch_core_session_t *session3 = NULL;
switch_channel_t *channel1 = NULL;
switch_channel_t *channel2 = NULL;
switch_channel_t *channel3 = NULL;
switch_status_t status;
switch_call_cause_t cause;
switch_stream_handle_t stream = { 0 };
char eavesdrop_command[256] = { 0 };
char rec_path[1024];
char rec_uuid[SWITCH_UUID_FORMATTED_LENGTH + 1] = { 0 };
char eaves_dialstr[512] = { 0 };
switch_uuid_str(rec_uuid, sizeof(rec_uuid));
/*parked 30 ms ptime */
status = switch_ivr_originate(NULL, &session1, &cause, "{ignore_early_media=true}sofia/gateway/eavestest/+15553332231", 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
fst_requires(session1);
fst_check(status == SWITCH_STATUS_SUCCESS);
channel1 = switch_core_session_get_channel(session1);
fst_requires(channel1);
snprintf(eaves_dialstr, sizeof(eaves_dialstr), "{ignore_early_media=true}{sip_h_X-UnitTestRecfile=%s}sofia/gateway/eavestest/+15553332240", rec_uuid);
/*eavesdropper 30 ms ptime*/
status = switch_ivr_originate(NULL, &session2, &cause, eaves_dialstr, 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
fst_requires(session2);
fst_check(status == SWITCH_STATUS_SUCCESS);
channel2 = switch_core_session_get_channel(session2);
fst_requires(channel2);
/*milliwatt tone 20 ms ptime*/
status = switch_ivr_originate(NULL, &session3, &cause, "{ignore_early_media=true}sofia/gateway/eavestest/+15553332226", 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
fst_requires(session3);
fst_check(status == SWITCH_STATUS_SUCCESS);
channel3 = switch_core_session_get_channel(session3);
fst_requires(channel3);
SWITCH_STANDARD_STREAM(stream);
switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command), "uuid_bridge %s %s", switch_core_session_get_uuid(session1), switch_core_session_get_uuid(session2));
switch_api_execute("bgapi", eavesdrop_command, session1, &stream);
memset(eavesdrop_command, 0, sizeof(eavesdrop_command));
switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command),"uuid_setvar_multi %s eavesdrop_enable_dtmf=false;eavesdrop_whisper_bleg=true;eavesdrop_whisper_aleg=false", switch_core_session_get_uuid(session3));
switch_api_execute("bgapi", eavesdrop_command, session3, &stream);
memset(eavesdrop_command, 0, sizeof(eavesdrop_command));
switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command), "uuid_transfer %s 'eavesdrop:%s' inline", switch_core_session_get_uuid(session3), switch_core_session_get_uuid(session2));
switch_api_execute("bgapi", eavesdrop_command, session3, &stream);
sleep(2);
// codec reneg for eavesdropper
memset(eavesdrop_command, 0, sizeof(eavesdrop_command));
switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command), "uuid_media_reneg %s = PCMU@20i", switch_core_session_get_uuid(session2));
switch_api_execute("bgapi", eavesdrop_command, session3, &stream);
sleep(1);
// codec reneg for eavesdroppee
memset(eavesdrop_command, 0, sizeof(eavesdrop_command));
switch_snprintf(eavesdrop_command, sizeof(eavesdrop_command), "uuid_media_reneg %s = PCMU@30i", switch_core_session_get_uuid(session3));
switch_api_execute("bgapi", eavesdrop_command, session3, &stream);
switch_safe_free(stream.data);
sleep(2);
snprintf(rec_path, sizeof(rec_path), "/tmp/eaves-%s.wav", rec_uuid);
fst_requires(switch_file_exists(rec_path, fst_pool) == SWITCH_STATUS_SUCCESS);
fst_requires(test_detect_long_tone_in_file(rec_path, 8000, 300, 30) == SWITCH_STATUS_SUCCESS);
unlink(rec_path);
switch_channel_hangup(channel1, SWITCH_CAUSE_NORMAL_CLEARING);
switch_channel_hangup(channel2, SWITCH_CAUSE_NORMAL_CLEARING);
switch_channel_hangup(channel3, SWITCH_CAUSE_NORMAL_CLEARING);
switch_core_session_rwunlock(session1);
switch_core_session_rwunlock(session2);
switch_core_session_rwunlock(session3);
}
FST_TEST_END()
}
FST_SUITE_END()
}
FST_CORE_END()

31
tests/unit/test_sofia.c Normal file
View File

@ -0,0 +1,31 @@
/*
* Copyright (C) 2018-2019, Signalwire, Inc. ALL RIGHTS RESERVED
* test_sofia.c -- Tests mod_sofia for memory leaks
*/
#include <switch.h>
#include <test/switch_test.h>
FST_CORE_DB_BEGIN("conf_sofia")
{
FST_SUITE_BEGIN(switch_sofia)
{
FST_SETUP_BEGIN()
{
fst_requires_module("mod_sofia");
}
FST_SETUP_END()
FST_TEARDOWN_BEGIN()
{
}
FST_TEARDOWN_END()
FST_TEST_BEGIN(sofia_leaks)
{
}
FST_TEST_END()
}
FST_SUITE_END()
}
FST_CORE_END()