mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-07-04 19:31:56 +00:00
Merge branch 'master' into v1.6
This commit is contained in:
+2
-2
@@ -159,7 +159,7 @@ check_lt_ver() {
|
||||
check_libtoolize() {
|
||||
# check libtoolize availability
|
||||
if [ -n "${LIBTOOL}" ]; then
|
||||
libtoolize=${LIBTOOLIZE:-`dirname "${libtool}"`/libtoolize}
|
||||
libtoolize=${LIBTOOLIZE:-`dirname "${LIBTOOL}"`/libtoolize}
|
||||
else
|
||||
libtoolize=${LIBTOOLIZE:-`${LIBDIR}/apr/build/PrintPath glibtoolize libtoolize libtoolize22 libtoolize15 libtoolize14`}
|
||||
fi
|
||||
@@ -190,7 +190,7 @@ check_make() {
|
||||
|
||||
make=`which make`
|
||||
if [ -x "$make" ]; then
|
||||
make_version=`$make --version | grep GNU`
|
||||
make_version=`$make --version || true | grep GNU`
|
||||
if [ $? -ne 0 ]; then
|
||||
make=`which gmake`
|
||||
if [ -x "$make" ]; then
|
||||
|
||||
@@ -40,6 +40,7 @@ applications/mod_httapi
|
||||
#applications/mod_redis
|
||||
#applications/mod_rss
|
||||
applications/mod_sms
|
||||
#applications/mod_sms_flowroute
|
||||
#applications/mod_snapshot
|
||||
#applications/mod_snom
|
||||
#applications/mod_sonar
|
||||
|
||||
@@ -238,7 +238,7 @@
|
||||
<param name="muted-sound" value="conference/conf-muted.wav"/>
|
||||
<param name="unmuted-sound" value="conference/conf-unmuted.wav"/>
|
||||
<param name="alone-sound" value="conference/conf-alone.wav"/>
|
||||
<param name="moh-sound" value="local_stream://stereo"/>
|
||||
<param name="moh-sound" value="$${hold_music}"/>
|
||||
<param name="enter-sound" value="tone_stream://%(200,0,500,600,700)"/>
|
||||
<param name="exit-sound" value="tone_stream://%(500,0,300,200,100,50,25)"/>
|
||||
<param name="kicked-sound" value="conference/conf-kicked.wav"/>
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
<!--<load module="mod_fsk"/>-->
|
||||
<!--<load module="mod_spy"/>-->
|
||||
<!--<load module="mod_sms"/>-->
|
||||
<!--<load module="mod_sms_flowroute"/>-->
|
||||
<!--<load module="mod_smpp"/>-->
|
||||
<!--<load module="mod_random"/>-->
|
||||
<load module="mod_httapi"/>
|
||||
@@ -100,6 +101,7 @@
|
||||
<load module="mod_opus"/>
|
||||
|
||||
<!-- File Format Interfaces -->
|
||||
<!--<load module="mod_av"/>-->
|
||||
<load module="mod_sndfile"/>
|
||||
<load module="mod_native_file"/>
|
||||
<load module="mod_png"/>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<configuration name="sms_flowroute.conf" description="SMS_FLOWROUTE send configs">
|
||||
<profiles>
|
||||
<profile name="default">
|
||||
<params>
|
||||
<param name="host" value="https://api.flowroute.com/v2/messages"/>
|
||||
<param name="debug" value="1"/>
|
||||
<param name="port" value="8090"/>
|
||||
<param name="access-key" value="ACCESS-KEY"/>
|
||||
<param name="secret-key" value="SECRET-KEY"/>
|
||||
</params>
|
||||
</profile>
|
||||
</profiles>
|
||||
</configuration>
|
||||
@@ -2,6 +2,12 @@
|
||||
|
||||
<settings>
|
||||
<param name="debug" value="0"/>
|
||||
<!-- seconds to wait before hanging up a disconnected channel -->
|
||||
<!-- <param name="detach-timeout-sec" value="120"/> -->
|
||||
<!-- enable broadcasting all FreeSWITCH events in Verto -->
|
||||
<!-- <param name="enable-fs-events" value="false"/> -->
|
||||
<!-- enable broadcasting FreeSWITCH presence events in Verto -->
|
||||
<!-- <param name="enable-presence" value="true"/> -->
|
||||
</settings>
|
||||
|
||||
<profiles>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<condition field="to" expression="^(.*)$">
|
||||
<!-- <action application="lua" data="test.lua"/> -->
|
||||
|
||||
<action application="reply" data="Hello, you said: ${_body}"/>
|
||||
<action application="reply" data="Hello, you said: ${body}"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
|
||||
@@ -382,6 +382,31 @@
|
||||
</extension>
|
||||
|
||||
<!-- STEREO 48kHz conferences / Video MCU -->
|
||||
<extension name="cdquality_stereo_conferences">
|
||||
<condition field="destination_number" expression="^(35\d{2}).*?-screen$">
|
||||
<action application="answer"/>
|
||||
<action application="send_display" data="FreeSWITCH Conference|$1"/>
|
||||
<action application="set" data="conference_member_flags=join-vid-floor"/>
|
||||
<action application="conference" data="$1-${domain_name}@video-mcu-stereo"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="conference-canvases" continue="true">
|
||||
<condition field="destination_number" expression="(35\d{2})-canvas-(\d+)">
|
||||
<action application="push" data="conference_member_flags=second-screen"/>
|
||||
<action application="set" data="video_initial_watching_canvas=$2"/>
|
||||
<action application="transfer" data="$1"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="conf mod">
|
||||
<condition field="destination_number" expression="^6070-moderator$">
|
||||
<action application="answer"/>
|
||||
<action application="set" data="conference_member_flags=moderator"/>
|
||||
<action application="conference" data="$1-${domain_name}@video-mcu-stereo"/>
|
||||
</condition>
|
||||
</extension>
|
||||
|
||||
<extension name="cdquality_conferences">
|
||||
<condition field="destination_number" expression="^(35\d{2})$">
|
||||
<action application="answer"/>
|
||||
|
||||
+31
-18
@@ -597,7 +597,7 @@ AC_SUBST(SYS_XMLRPC_CFLAGS)
|
||||
AC_SUBST(SYS_XMLRPC_LDFLAGS)
|
||||
AM_CONDITIONAL([SYSTEM_XMLRPCC],[test "${enable_xmlrpcc}" = "yes"])
|
||||
|
||||
for luaversion in lua5.2 lua-5.2 lua5.1 lua-5.1 lua; do
|
||||
for luaversion in lua5.2 lua-5.2 lua52 lua5.1 lua-5.1 lua; do
|
||||
PKG_CHECK_MODULES([LUA],[${luaversion}],[have_lua=yes],[have_lua=no])
|
||||
if test ${have_lua} = yes; then
|
||||
break
|
||||
@@ -793,7 +793,7 @@ case "$host" in
|
||||
;;
|
||||
*openbsd*)
|
||||
APR_ADDTO(CPPFLAGS, -I/usr/local/include)
|
||||
APR_ADDTO(LDFLAGS, -L/usr/local/lib)
|
||||
APR_ADDTO(LDFLAGS, -L/usr/local/lib -ltermcap)
|
||||
APR_ADDTO(SWITCH_AM_CFLAGS, -I/usr/local/include)
|
||||
;;
|
||||
*netbsd*)
|
||||
@@ -1413,6 +1413,18 @@ PKG_CHECK_MODULES([AMQP], [librabbitmq >= 0.5.2],[
|
||||
AM_CONDITIONAL([HAVE_AMQP],[true])],[
|
||||
AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_AMQP],[false])])
|
||||
|
||||
PKG_CHECK_MODULES([H2O], [libh2o-evloop >= 0.11.0],[
|
||||
AM_CONDITIONAL([HAVE_H2O],[true])],[
|
||||
AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_H2O],[false])])
|
||||
|
||||
PKG_CHECK_MODULES([BROTLIENC], [libbrotlienc >= 0.1.0],[
|
||||
AM_CONDITIONAL([HAVE_BROTLIENC],[true])],[
|
||||
AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_BROTLIENC],[false])])
|
||||
|
||||
PKG_CHECK_MODULES([BROTLIDEC], [libbrotlidec >= 0.1.0],[
|
||||
AM_CONDITIONAL([HAVE_BROTLIDEC],[true])],[
|
||||
AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_BROTLIDEC],[false])])
|
||||
|
||||
PKG_CHECK_MODULES([TAP], [tap >= 0.1.0],[
|
||||
AM_CONDITIONAL([HAVE_TAP],[true])],[
|
||||
AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_TAP],[false])])
|
||||
@@ -1693,6 +1705,22 @@ else
|
||||
AC_MSG_WARN([python support disabled, building mod_python will fail!])
|
||||
fi
|
||||
|
||||
#
|
||||
# SNMP checks for mod_snmp
|
||||
#
|
||||
AC_PATH_PROG([NET_SNMP_CONFIG], [net-snmp-config], [no])
|
||||
if test "$NET_SNMP_CONFIG" != "no"; then
|
||||
AC_MSG_CHECKING([for Net-SNMP libraries via net-snmp-config])
|
||||
SNMP_LIBS="`$NET_SNMP_CONFIG --base-agent-libs`"
|
||||
else
|
||||
# net-snmp-config not in path, fallback to sensible defaults
|
||||
SNMP_LIBS="-lnetsnmpmibs -lnetsnmpagent -lnetsnmp"
|
||||
fi
|
||||
|
||||
# fix linking error on Solaris patched Net-SNMP
|
||||
AS_CASE([$host], [*-solaris2*], [AC_CHECK_LIB([dladm], [dladm_open], [SNMP_LIBS="$SNMP_LIBS -ldladm"])])
|
||||
AC_SUBST(SNMP_LIBS)
|
||||
|
||||
CHECK_ERLANG
|
||||
|
||||
# we never use this, and hard setting it will make cross compile work better
|
||||
@@ -1746,6 +1774,7 @@ AC_CONFIG_FILES([Makefile
|
||||
src/mod/applications/mod_rss/Makefile
|
||||
src/mod/applications/mod_skel/Makefile
|
||||
src/mod/applications/mod_sms/Makefile
|
||||
src/mod/applications/mod_sms_flowroute/Makefile
|
||||
src/mod/applications/mod_snapshot/Makefile
|
||||
src/mod/applications/mod_snom/Makefile
|
||||
src/mod/applications/mod_sonar/Makefile
|
||||
@@ -1962,22 +1991,6 @@ esac
|
||||
|
||||
AC_OUTPUT
|
||||
|
||||
##
|
||||
## Registering for ClueCon
|
||||
##
|
||||
if ! test -f noreg -o -f /noreg; then
|
||||
echo ""
|
||||
echo ""
|
||||
echo $ECHO_N "Registering you for ClueCon http://www.cluecon.com $ECHO_C" 1>&6
|
||||
sleep 1
|
||||
echo $ECHO_N ".$ECHO_C" 1>&6
|
||||
sleep 1
|
||||
echo $ECHO_N ".$ECHO_C" 1>&6
|
||||
sleep 1
|
||||
AC_MSG_RESULT([ See you in August. ;-)])
|
||||
echo ""
|
||||
fi
|
||||
|
||||
##
|
||||
## Configuration summary
|
||||
##
|
||||
|
||||
Vendored
+162
-2
@@ -32,6 +32,7 @@ supported_debian_distros="wheezy jessie stretch sid"
|
||||
supported_ubuntu_distros="trusty utopic"
|
||||
supported_distros="$supported_debian_distros $supported_ubuntu_distros"
|
||||
avoid_mods=(
|
||||
applications/mod_sms_flowroute
|
||||
applications/mod_limit
|
||||
applications/mod_mongo
|
||||
applications/mod_mp4
|
||||
@@ -634,10 +635,12 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}),
|
||||
freeswitch-mod-dingaling (= \${binary:Version}),
|
||||
freeswitch-mod-loopback (= \${binary:Version}),
|
||||
freeswitch-mod-portaudio (= \${binary:Version}),
|
||||
freeswitch-mod-rtc (= \${binary:Version}),
|
||||
freeswitch-mod-rtmp (= \${binary:Version}),
|
||||
freeswitch-mod-skinny (= \${binary:Version}),
|
||||
freeswitch-mod-skypopen (= \${binary:Version}),
|
||||
freeswitch-mod-sofia (= \${binary:Version}),
|
||||
freeswitch-mod-verto (= \${binary:Version}),
|
||||
freeswitch-mod-cdr-csv (= \${binary:Version}),
|
||||
freeswitch-mod-cdr-mongodb (= \${binary:Version}),
|
||||
freeswitch-mod-cdr-sqlite (= \${binary:Version}),
|
||||
@@ -704,6 +707,33 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch
|
||||
This is a metapackage which depends on the packages needed to install
|
||||
most FreeSWITCH codecs.
|
||||
|
||||
Package: freeswitch-meta-codecs-dbg
|
||||
Architecture: any
|
||||
Depends: \${misc:Depends}, freeswitch (= \${binary:Version}),
|
||||
freeswitch-mod-amr-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-amrwb-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-b64-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-bv-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-codec2-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-dahdi-codec-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-g723-1-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-g729-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-h26x-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-isac-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-mp4v-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-opus-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-silk-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-spandsp-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-theora-dbg (= \${binary:Version}),
|
||||
Suggests:
|
||||
freeswitch-mod-ilbc-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-siren-dbg (= \${binary:Version})
|
||||
Description: Cross-Platform Scalable Multi-Protocol Soft Switch
|
||||
$(debian_wrap "${fs_description}")
|
||||
.
|
||||
This is a metapackage which depends on the packages needed to install
|
||||
most FreeSWITCH codecs.
|
||||
|
||||
Package: freeswitch-meta-conf
|
||||
Architecture: all
|
||||
Depends: \${misc:Depends},
|
||||
@@ -759,11 +789,141 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch
|
||||
This is a metapackage which depends on all mod_say languages for
|
||||
FreeSWITCH.
|
||||
|
||||
Package: freeswitch-meta-mod-say-dbg
|
||||
Architecture: any
|
||||
Depends: \${misc:Depends},
|
||||
freeswitch-mod-say-de-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-say-en-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-say-es-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-say-fa-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-say-fr-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-say-he-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-say-hr-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-say-hu-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-say-it-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-say-ja-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-say-nl-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-say-pl-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-say-pt-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-say-ru-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-say-th-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-say-zh-dbg (= \${binary:Version}),
|
||||
Description: Cross-Platform Scalable Multi-Protocol Soft Switch
|
||||
$(debian_wrap "${fs_description}")
|
||||
.
|
||||
This is a metapackage which depends on all mod_say languages for
|
||||
FreeSWITCH.
|
||||
|
||||
Package: freeswitch-meta-all-dbg
|
||||
Architecture: any
|
||||
Depends: \${misc:Depends}, freeswitch (= \${binary:Version}),
|
||||
freeswitch-meta-codecs-dbg (= \${binary:Version}),
|
||||
freeswitch-meta-lang-dbg (= \${binary:Version}),
|
||||
freeswitch-meta-mod-say (= \${binary:Version}),
|
||||
freeswitch-mod-abstraction-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-avmd-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-av-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-blacklist-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-callcenter-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-cidlookup-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-commands-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-conference-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-curl-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-db-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-directory-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-distributor-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-dptools-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-easyroute-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-enum-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-esf-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-esl-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-expr-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-fifo-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-fsk-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-fsv-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-hash-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-httapi-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-http-cache-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-lcr-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-memcache-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-nibblebill-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-oreka-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-png-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-redis-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-rss-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-sms-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-snapshot-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-snom-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-sonar-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-soundtouch-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-spandsp-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-spy-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-stress-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-translate-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-valet-parking-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-voicemail-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-voicemail-ivr-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-flite-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-pocketsphinx-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-tts-commandline-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-unimrcp-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-dialplan-asterisk-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-dialplan-directory-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-dialplan-xml-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-ldap-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-dingaling-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-loopback-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-portaudio-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-rtc-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-rtmp-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-skinny-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-skypopen-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-sofia-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-verto-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-cdr-csv-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-cdr-mongodb-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-cdr-sqlite-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-erlang-event-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-event-multicast-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-event-socket-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-json-cdr-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-kazoo-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-snmp-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-local-stream-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-native-file-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-portaudio-stream-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-shell-stream-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-sndfile-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-tone-stream-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-java-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-lua-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-perl-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-python-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-yaml-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-console-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-logfile-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-syslog-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-posix-timer-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-timerfd-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-xml-cdr-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-xml-curl-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-xml-rpc-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-xml-scgi-dbg (= \${binary:Version}),
|
||||
Recommends:
|
||||
Suggests:
|
||||
freeswitch-mod-vmd-dbg (= \${binary:Version}),
|
||||
freeswitch-mod-vlc-dbg (= \${binary:Version}),
|
||||
Description: Cross-Platform Scalable Multi-Protocol Soft Switch
|
||||
$(debian_wrap "${fs_description}")
|
||||
.
|
||||
This is a metapackage which recommends or suggests all packaged
|
||||
FreeSWITCH modules.
|
||||
|
||||
Package: freeswitch-all-dbg
|
||||
Section: debug
|
||||
Priority: extra
|
||||
Architecture: any
|
||||
Depends: \${misc:Depends}, freeswitch-meta-all (= \${binary:Version})
|
||||
Depends: \${misc:Depends}, freeswitch-meta-all (= \${binary:Version}), freeswitch-meta-all-dbg (= \${binary:Version})
|
||||
Description: debugging symbols for FreeSWITCH
|
||||
$(debian_wrap "${fs_description}")
|
||||
.
|
||||
@@ -840,7 +1000,7 @@ if [ ${use_sysvinit} = "true" ]; then
|
||||
cat <<EOF
|
||||
Package: freeswitch-sysvinit
|
||||
Architecture: all
|
||||
Depends: \${misc:Depends}, lsb-base (>= 3.0-6), sysvinit
|
||||
Depends: \${misc:Depends}, lsb-base (>= 3.0-6), sysvinit | sysvinit-utils
|
||||
Conflicts: freeswitch-init
|
||||
Provides: freeswitch-init
|
||||
Description: FreeSWITCH SysV init script
|
||||
|
||||
@@ -1935,6 +1935,7 @@ fi
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/shout.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/skinny.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/smpp.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/sms_flowroute.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/sofia.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/spandsp.conf.xml
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/switch.conf.xml
|
||||
|
||||
@@ -1089,7 +1089,7 @@
|
||||
return [w, h];
|
||||
}
|
||||
|
||||
var resList = [[320, 180], [320, 240], [640, 360], [640, 480], [1280, 720], [1920, 1080]];
|
||||
var resList = [[160, 120], [320, 180], [320, 240], [640, 360], [640, 480], [1280, 720], [1920, 1080]];
|
||||
var resI = 0;
|
||||
var ttl = 0;
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
<script src="bower_components/angular-directive.g-signin/google-plus-signin.js"></script>
|
||||
<script src="bower_components/angular-fullscreen/src/angular-fullscreen.js"></script>
|
||||
<script src="bower_components/ngstorage/ngStorage.js"></script>
|
||||
<script src="bower_components/momentjs/moment.js"></script>
|
||||
<script src="bower_components/moment/moment.js"></script>
|
||||
<script src="bower_components/humanize-duration/humanize-duration.js"></script>
|
||||
<script src="bower_components/angular-timer/dist/angular-timer.js"></script>
|
||||
<script src="bower_components/angular-tooltips/dist/angular-tooltips.min.js"></script>
|
||||
|
||||
@@ -292,7 +292,10 @@
|
||||
|
||||
$scope.closeSettings = function() {
|
||||
var settingsEl = angular.element(document.querySelector('#settings'));
|
||||
settingsEl.removeClass('toggled');
|
||||
if (settingsEl.hasClass('toggled')) {
|
||||
settingsEl.removeClass('toggled');
|
||||
$rootScope.$emit('toggledSettings', settingsEl.hasClass('toggled'));
|
||||
}
|
||||
};
|
||||
|
||||
$scope.goFullscreen = function() {
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
/* Controllers */
|
||||
var videoQuality = [];
|
||||
var videoQualitySource = [{
|
||||
id: 'qqvga',
|
||||
label: 'QQVGA 160x120',
|
||||
width: 160,
|
||||
height: 120
|
||||
}, {
|
||||
id: 'qvga',
|
||||
label: 'QVGA 320x240',
|
||||
width: 320,
|
||||
@@ -35,6 +40,10 @@ var videoQualitySource = [{
|
||||
}, ];
|
||||
|
||||
var videoResolution = {
|
||||
qqvga: {
|
||||
width: 160,
|
||||
height: 120
|
||||
},
|
||||
qvga: {
|
||||
width: 320,
|
||||
height: 240
|
||||
@@ -910,7 +919,10 @@ vertoService.service('verto', ['$rootScope', '$cookieStore', '$location', 'stora
|
||||
storage.data.useDedenc = false;
|
||||
storage.data.vidQual = 'hd';
|
||||
|
||||
if (upBand < 512) {
|
||||
if (upBand < 256) {
|
||||
storage.data.vidQual = 'qqvga';
|
||||
}
|
||||
else if (upBand < 512) {
|
||||
storage.data.vidQual = 'qvga';
|
||||
}
|
||||
else if (upBand < 1024) {
|
||||
|
||||
@@ -394,6 +394,10 @@ if ($('#devices').is(':visible')) {
|
||||
<div >
|
||||
<fieldset data-role="controlgroup" data-type="horizontal">
|
||||
<legend><b>Video Quality</b>:</legend>
|
||||
|
||||
<input type="radio" name="vqual" id="vqual_qqvga" value="qqvga">
|
||||
<label for="vqual_qqvga">QQVGA 160x120</label>
|
||||
|
||||
<input type="radio" name="vqual" id="vqual_qvga" value="qvga">
|
||||
<label for="vqual_qvga">QVGA 320x240</label>
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ var master = null;
|
||||
var canvas_id = null;
|
||||
var second_screen = null;
|
||||
var save_settings = true;
|
||||
|
||||
var vertoHandle = null;
|
||||
var video_screen = "webcam"
|
||||
|
||||
$( ".selector" ).pagecontainer({ "theme": "a" });
|
||||
@@ -140,7 +140,12 @@ function real_size() {
|
||||
|
||||
function check_vid_res()
|
||||
{
|
||||
if ($("#vqual_qvga").is(':checked')) {
|
||||
if ($("#vqual_qqvga").is(':checked')) {
|
||||
vid_width = 160;
|
||||
vid_height = 120;
|
||||
local_vid_width = 80;
|
||||
local_vid_height = 60;
|
||||
} else if ($("#vqual_qvga").is(':checked')) {
|
||||
vid_width = 320;
|
||||
vid_height = 240;
|
||||
local_vid_width = 160;
|
||||
@@ -218,6 +223,10 @@ function do_speed_test(fn)
|
||||
$("#vqual_qvga").prop("checked", true);
|
||||
vid = "320x240";
|
||||
}
|
||||
if (outgoingBandwidth < 256) {
|
||||
$("#vqual_qqvga").prop("checked", true);
|
||||
vid = "160x120";
|
||||
}
|
||||
//}
|
||||
|
||||
if (incomingBandwidth === "default") {
|
||||
@@ -1315,6 +1324,15 @@ function init() {
|
||||
|
||||
|
||||
|
||||
$("#vqual_qqvga").prop("checked", vqual === "qqvga").change(function(e) {
|
||||
if ($("#vqual_qqvga").is(':checked')) {
|
||||
vqual = "qqvga";
|
||||
$.cookie("verto_demo_vqual", vqual, {
|
||||
expires: 365
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$("#vqual_qvga").prop("checked", vqual === "qvga").change(function(e) {
|
||||
if ($("#vqual_qvga").is(':checked')) {
|
||||
vqual = "qvga";
|
||||
|
||||
@@ -1021,7 +1021,6 @@ static void ftdm_r2_on_chan_log(openr2_chan_t *r2chan, const char *file, const c
|
||||
static int ftdm_r2_on_dnis_digit_received(openr2_chan_t *r2chan, char digit)
|
||||
{
|
||||
ftdm_sigmsg_t sigev;
|
||||
ftdm_r2_data_t *r2data;
|
||||
ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
|
||||
ftdm_size_t collected_len = R2CALL(ftdmchan)->dnis_index;
|
||||
|
||||
@@ -1039,7 +1038,6 @@ static int ftdm_r2_on_dnis_digit_received(openr2_chan_t *r2chan, char digit)
|
||||
sigev.span_id = ftdmchan->span_id;
|
||||
sigev.channel = ftdmchan;
|
||||
sigev.event_id = FTDM_SIGEVENT_COLLECTED_DIGIT;
|
||||
r2data = ftdmchan->span->signal_data;
|
||||
if (ftdm_span_send_signal(ftdmchan->span, &sigev) == FTDM_BREAK) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Requested to stop getting DNIS. Current DNIS = %s\n", ftdmchan->caller_data.dnis.digits);
|
||||
return OR2_STOP_DNIS_REQUEST;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
Makefile
|
||||
config.mk
|
||||
libs-*.mk
|
||||
libs.doxy
|
||||
vp8_rtcd.h
|
||||
vp9_rtcd.h
|
||||
vpx_config.asm
|
||||
|
||||
@@ -1 +1 @@
|
||||
Wed Apr 27 16:01:46 EDT 2016
|
||||
Tue Aug 16 13:39:03 CDT 2016
|
||||
|
||||
@@ -1397,6 +1397,8 @@ void sdp_media_transport(sdp_media_t *m, char const *s)
|
||||
m->m_proto = sdp_proto_rtp, m->m_proto_name = "RTP/AVP";
|
||||
else if (su_casematch(s, "RTP/SAVP"))
|
||||
m->m_proto = sdp_proto_srtp, m->m_proto_name = "RTP/SAVP";
|
||||
else if (su_casematch(s, "UDP/TLS/RTP/SAVP"))
|
||||
m->m_proto = sdp_proto_srtp, m->m_proto_name = "RTP/SAVP";
|
||||
else if (su_casematch(s, "RTP/SAVPF"))
|
||||
m->m_proto = sdp_proto_extended_srtp, m->m_proto_name = "RTP/SAVPF";
|
||||
else if (su_casematch(s, "UDP/TLS/RTP/SAVPF"))
|
||||
|
||||
@@ -1061,9 +1061,11 @@ int soa_sdp_mode_set(sdp_session_t const *user,
|
||||
continue;
|
||||
}
|
||||
|
||||
send_mode = (sdp_mode_t)(um->m_mode & sdp_sendonly);
|
||||
if (rm)
|
||||
send_mode = (rm->m_mode & sdp_recvonly) ? sdp_sendonly : 0;
|
||||
if (um->m_mode) { /* when its inactive, keep it inactive */
|
||||
send_mode = (sdp_mode_t)(um->m_mode & sdp_sendonly);
|
||||
if (rm)
|
||||
send_mode = (rm->m_mode & sdp_recvonly) ? sdp_sendonly : 0;
|
||||
} else send_mode = um->m_mode;
|
||||
|
||||
recv_mode = (sdp_mode_t)(um->m_mode & sdp_recvonly);
|
||||
|
||||
|
||||
@@ -398,7 +398,7 @@ uint64_t su_nanocounter(void)
|
||||
static int init = 0;
|
||||
static clockid_t cpu = CLOCK_REALTIME;
|
||||
|
||||
# define CLOCK_GETTIMEOFDAY 0xdedbeefUL
|
||||
# define CLOCK_GETTIMEOFDAY ((clockid_t)-1)
|
||||
|
||||
if (init == 0) {
|
||||
init = 1;
|
||||
|
||||
@@ -467,7 +467,7 @@ int tport_capt_msg_hepv2 (tport_t const *self, msg_t *msg, size_t n,
|
||||
struct hep_ip6hdr hep_ip6header = {{{{0}}}};
|
||||
#endif
|
||||
int eth_frame_len = 16000;
|
||||
size_t i, dst = 0;
|
||||
size_t i, dst = 1;
|
||||
tport_master_t *mr;
|
||||
|
||||
assert(self); assert(msg);
|
||||
@@ -501,25 +501,25 @@ int tport_capt_msg_hepv2 (tport_t const *self, msg_t *msg, size_t n,
|
||||
else hep_header.hp_p = IPPROTO_UDP; /* DEFAULT UDP */
|
||||
|
||||
/* Check destination */
|
||||
if(strncmp("sent", what, 4) == 0) dst = 1;
|
||||
if(strncmp("sent", what, 4) == 0) dst = 0;
|
||||
|
||||
/* copy destination and source IPs*/
|
||||
if(su->su_family == AF_INET) {
|
||||
|
||||
memcpy(dst ? &hep_ipheader.hp_dst : &hep_ipheader.hp_src, &su->su_sin.sin_addr.s_addr, sizeof(su->su_sin.sin_addr.s_addr));
|
||||
memcpy(dst ? &hep_ipheader.hp_src : &hep_ipheader.hp_dst, &su_self->su_sin.sin_addr.s_addr, sizeof(su_self->su_sin.sin_addr.s_addr));
|
||||
memcpy(dst ? &hep_ipheader.hp_src : &hep_ipheader.hp_dst, &su->su_sin.sin_addr.s_addr, sizeof(su->su_sin.sin_addr.s_addr));
|
||||
memcpy(dst ? &hep_ipheader.hp_dst : &hep_ipheader.hp_src, &su_self->su_sin.sin_addr.s_addr, sizeof(su_self->su_sin.sin_addr.s_addr));
|
||||
hep_header.hp_l += sizeof(struct hep_iphdr);
|
||||
}
|
||||
#if SU_HAVE_IN6
|
||||
else {
|
||||
memcpy(dst ? &hep_ip6header.hp6_dst : &hep_ip6header.hp6_src, &su->su_sin.sin_addr.s_addr, sizeof(su->su_sin.sin_addr.s_addr));
|
||||
memcpy(dst ? &hep_ip6header.hp6_src : &hep_ip6header.hp6_dst, &su_self->su_sin.sin_addr.s_addr, sizeof(su_self->su_sin.sin_addr.s_addr));
|
||||
memcpy(dst ? &hep_ip6header.hp6_src : &hep_ip6header.hp6_dst, &su->su_sin.sin_addr.s_addr, sizeof(su->su_sin.sin_addr.s_addr));
|
||||
memcpy(dst ? &hep_ip6header.hp6_dst : &hep_ip6header.hp6_src, &su_self->su_sin.sin_addr.s_addr, sizeof(su_self->su_sin.sin_addr.s_addr));
|
||||
hep_header.hp_l += sizeof(struct hep_ip6hdr);
|
||||
}
|
||||
#endif
|
||||
|
||||
hep_header.hp_dport = dst ? su->su_port : su_self->su_port;
|
||||
hep_header.hp_sport = dst ? su_self->su_port : su->su_port;
|
||||
hep_header.hp_dport = dst ? su_self->su_port : su->su_port;
|
||||
hep_header.hp_sport = dst ? su->su_port : su_self->su_port;
|
||||
|
||||
if (hep_header.hp_v == 2){
|
||||
hep_header.hp_l += sizeof(struct hep_timehdr);
|
||||
@@ -605,7 +605,7 @@ int tport_capt_msg_hepv3 (tport_t const *self, msg_t *msg, size_t n,
|
||||
#endif
|
||||
|
||||
int eth_frame_len = 16000;
|
||||
size_t i, dst = 0;
|
||||
size_t i, dst = 1;
|
||||
tport_master_t *mr;
|
||||
|
||||
assert(self); assert(msg);
|
||||
@@ -649,7 +649,7 @@ int tport_capt_msg_hepv3 (tport_t const *self, msg_t *msg, size_t n,
|
||||
hg->ip_proto.chunk.length = htons(sizeof(hg->ip_proto));
|
||||
|
||||
/* Check destination */
|
||||
if(strncmp("sent", what, 4) == 0) dst = 1;
|
||||
if(strncmp("sent", what, 4) == 0) dst = 0;
|
||||
|
||||
/* copy destination and source IPs*/
|
||||
if(su->su_family == AF_INET) {
|
||||
@@ -657,13 +657,13 @@ int tport_capt_msg_hepv3 (tport_t const *self, msg_t *msg, size_t n,
|
||||
/* SRC IP */
|
||||
src_ip4.chunk.vendor_id = htons(0x0000);
|
||||
src_ip4.chunk.type_id = htons(0x0003);
|
||||
memcpy(dst ? &dst_ip4.data : &src_ip4.data, &su->su_sin.sin_addr.s_addr, sizeof(su->su_sin.sin_addr.s_addr));
|
||||
memcpy(dst ? &src_ip4.data : &dst_ip4.data, &su->su_sin.sin_addr.s_addr, sizeof(su->su_sin.sin_addr.s_addr));
|
||||
src_ip4.chunk.length = htons(sizeof(src_ip4));
|
||||
|
||||
/* DST IP */
|
||||
dst_ip4.chunk.vendor_id = htons(0x0000);
|
||||
dst_ip4.chunk.type_id = htons(0x0004);
|
||||
memcpy(dst ? &src_ip4.data : &dst_ip4.data, &su_self->su_sin.sin_addr.s_addr, sizeof(su_self->su_sin.sin_addr.s_addr));
|
||||
memcpy(dst ? &dst_ip4.data : &src_ip4.data, &su_self->su_sin.sin_addr.s_addr, sizeof(su_self->su_sin.sin_addr.s_addr));
|
||||
dst_ip4.chunk.length = htons(sizeof(dst_ip4));
|
||||
|
||||
iplen = sizeof(dst_ip4) + sizeof(src_ip4);
|
||||
@@ -674,13 +674,13 @@ int tport_capt_msg_hepv3 (tport_t const *self, msg_t *msg, size_t n,
|
||||
/* SRC IPv6 */
|
||||
src_ip6.chunk.vendor_id = htons(0x0000);
|
||||
src_ip6.chunk.type_id = htons(0x0005);
|
||||
memcpy(dst ? &dst_ip6.data : &src_ip6.data, &su->su_sin.sin_addr.s_addr, sizeof(su->su_sin.sin_addr.s_addr));
|
||||
memcpy(dst ? &src_ip6.data : &dst_ip6.data, &su->su_sin.sin_addr.s_addr, sizeof(su->su_sin.sin_addr.s_addr));
|
||||
src_ip6.chunk.length = htons(sizeof(src_ip6));
|
||||
|
||||
/* DST IPv6 */
|
||||
dst_ip6.chunk.vendor_id = htons(0x0000);
|
||||
dst_ip6.chunk.type_id = htons(0x0006);
|
||||
memcpy(dst ? &src_ip6.data : &dst_ip6.data, &su_self->su_sin.sin_addr.s_addr, sizeof(su_self->su_sin.sin_addr.s_addr));
|
||||
memcpy(dst ? &dst_ip6.data : &src_ip6.data, &su_self->su_sin.sin_addr.s_addr, sizeof(su_self->su_sin.sin_addr.s_addr));
|
||||
dst_ip6.chunk.length = htons(sizeof(dst_ip6));
|
||||
|
||||
iplen = sizeof(dst_ip6) + sizeof(src_ip6);
|
||||
|
||||
@@ -461,6 +461,7 @@ int tport_ws_init_secondary(tport_t *self, int socket, int accepted,
|
||||
tport_ws_t *wstp = (tport_ws_t *)self;
|
||||
|
||||
self->tp_has_connection = 1;
|
||||
self->tp_params->tpp_keepalive = 5000;
|
||||
|
||||
/* override the default 30 minute timeout on tport connections */
|
||||
self->tp_params->tpp_idle = UINT_MAX;
|
||||
@@ -493,10 +494,12 @@ int tport_ws_init_secondary(tport_t *self, int socket, int accepted,
|
||||
return *return_reason = "WS_INIT", -1;
|
||||
}
|
||||
|
||||
wstp->connected = time(NULL);
|
||||
|
||||
wstp->ws_initialized = 1;
|
||||
self->tp_pre_framed = 1;
|
||||
|
||||
|
||||
tport_set_secondary_timer(self);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -592,6 +595,32 @@ int tport_ws_next_timer(tport_t *self,
|
||||
su_time_t *return_target,
|
||||
char const **return_why)
|
||||
{
|
||||
tport_ws_t *wstp = (tport_ws_t *)self;
|
||||
int ll = establish_logical_layer(&wstp->ws);
|
||||
int punt = 0;
|
||||
|
||||
if (ll == -1) {
|
||||
punt = 1;
|
||||
} else if (ll < 0) {
|
||||
time_t now = time(NULL);
|
||||
if (now - wstp->connected > 5) {
|
||||
punt = 2;
|
||||
}
|
||||
} else {
|
||||
self->tp_params->tpp_keepalive = 0;
|
||||
}
|
||||
|
||||
if (punt) {
|
||||
tport_close(self);
|
||||
|
||||
SU_DEBUG_7(("%s(%p): %s to " TPN_FORMAT "%s\n",
|
||||
__func__, (void *)self,
|
||||
(punt == 2 ? "Timeout establishing SSL" : "Error establishing SSL"), TPN_ARGS(self->tp_name), ""));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
return
|
||||
tport_next_recv_timeout(self, return_target, return_why) |
|
||||
tport_next_keepalive(self, return_target, return_why);
|
||||
|
||||
@@ -59,6 +59,7 @@ typedef struct tport_ws_s {
|
||||
char wstp_buffer[65536];
|
||||
size_t wstp_buflen;
|
||||
SU_S8_T ws_initialized;
|
||||
time_t connected;
|
||||
unsigned ws_secure:1;
|
||||
unsigned:0;
|
||||
} tport_ws_t;
|
||||
|
||||
@@ -500,7 +500,7 @@ static int restore_socket(ws_socket_t sock)
|
||||
#endif
|
||||
|
||||
|
||||
static int establish_logical_layer(wsh_t *wsh)
|
||||
int establish_logical_layer(wsh_t *wsh)
|
||||
{
|
||||
|
||||
if (!wsh->sanity) {
|
||||
|
||||
@@ -119,7 +119,7 @@ typedef struct wsh_s {
|
||||
ssize_t ws_send_buf(wsh_t *wsh, ws_opcode_t oc);
|
||||
ssize_t ws_feed_buf(wsh_t *wsh, void *data, size_t bytes);
|
||||
|
||||
|
||||
int establish_logical_layer(wsh_t *wsh);
|
||||
ssize_t ws_raw_read(wsh_t *wsh, void *data, size_t bytes, int block);
|
||||
ssize_t ws_raw_write(wsh_t *wsh, void *data, size_t bytes);
|
||||
ssize_t ws_read_frame(wsh_t *wsh, ws_opcode_t *oc, uint8_t **data);
|
||||
|
||||
@@ -284,12 +284,15 @@ aes_icm_set_octet(aes_icm_ctx_t *c,
|
||||
|
||||
err_status_t
|
||||
aes_icm_set_iv(aes_icm_ctx_t *c, void *iv, int direction) {
|
||||
v128_t *nonce = (v128_t *) iv;
|
||||
v128_t nonce;
|
||||
|
||||
/* set nonce (for alignment) */
|
||||
v128_copy_octet_string(&nonce, iv);
|
||||
|
||||
debug_print(mod_aes_icm,
|
||||
"setting iv: %s", v128_hex_string(nonce));
|
||||
"setting iv: %s", v128_hex_string(&nonce));
|
||||
|
||||
v128_xor(&c->counter, &c->offset, nonce);
|
||||
v128_xor(&c->counter, &c->offset, &nonce);
|
||||
|
||||
debug_print(mod_aes_icm,
|
||||
"set_counter: %s", v128_hex_string(&c->counter));
|
||||
|
||||
@@ -263,11 +263,14 @@ err_status_t aes_icm_openssl_context_init (aes_icm_ctx_t *c, const uint8_t *key)
|
||||
err_status_t aes_icm_openssl_set_iv (aes_icm_ctx_t *c, void *iv, int dir)
|
||||
{
|
||||
const EVP_CIPHER *evp;
|
||||
v128_t *nonce = (v128_t*)iv;
|
||||
v128_t nonce;
|
||||
|
||||
debug_print(mod_aes_icm, "setting iv: %s", v128_hex_string(nonce));
|
||||
/* set nonce (for alignment) */
|
||||
v128_copy_octet_string(&nonce, iv);
|
||||
|
||||
v128_xor(&c->counter, &c->offset, nonce);
|
||||
debug_print(mod_aes_icm, "setting iv: %s", v128_hex_string(&nonce));
|
||||
|
||||
v128_xor(&c->counter, &c->offset, &nonce);
|
||||
|
||||
debug_print(mod_aes_icm, "set_counter: %s", v128_hex_string(&c->counter));
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -64,8 +64,6 @@ typedef enum {
|
||||
SCMF_CODEC_GREEDY,
|
||||
SCMF_CODEC_SCROOGE,
|
||||
SCMF_DISABLE_HOLD,
|
||||
SCMF_RENEG_ON_HOLD,
|
||||
SCMF_RENEG_ON_REINVITE,
|
||||
SCMF_LIBERAL_DTMF,
|
||||
SCMF_SUPPRESS_CNG,
|
||||
SCMF_DISABLE_RTP_AUTOADJ,
|
||||
@@ -75,6 +73,7 @@ typedef enum {
|
||||
SCMF_RTP_AUTOFLUSH_DURING_BRIDGE,
|
||||
SCMF_MULTI_ANSWER_AUDIO,
|
||||
SCMF_MULTI_ANSWER_VIDEO,
|
||||
SCMF_RECV_SDP,
|
||||
SCMF_MAX
|
||||
} switch_core_media_flag_t;
|
||||
|
||||
@@ -230,6 +229,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_choose_ports(switch_core_sessi
|
||||
SWITCH_DECLARE(void) switch_core_media_check_dtmf_type(switch_core_session_t *session);
|
||||
SWITCH_DECLARE(void) switch_core_media_absorb_sdp(switch_core_session_t *session);
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_media_proxy_remote_addr(switch_core_session_t *session, const char *sdp_str);
|
||||
SWITCH_DECLARE(void) switch_core_media_parse_media_flags(switch_core_session_t *session);
|
||||
SWITCH_DECLARE(void) switch_core_media_deactivate_rtp(switch_core_session_t *session);
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_session_t *session);
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_media_ext_address_lookup(switch_core_session_t *session, char **ip, switch_port_t *port, const char *sourceip);
|
||||
|
||||
@@ -352,10 +352,10 @@ SWITCH_DECLARE(void) switch_img_find_position(switch_img_position_t pos, int sw,
|
||||
*
|
||||
* \param[in] src The image descriptor
|
||||
* \param[in] dest The target memory address
|
||||
* \param[in] size The size of target memory address used for bounds check
|
||||
* \param[in] stride Bytes in a row for the destination. Pass 0 if the buffer has contiguous rows. Can be negative. A multiple of 16 is optimal.
|
||||
* \param[in] fmt The target format
|
||||
*/
|
||||
SWITCH_DECLARE(switch_status_t) switch_img_to_raw(switch_image_t *src, void *dest, switch_size_t size, switch_img_fmt_t fmt);
|
||||
SWITCH_DECLARE(switch_status_t) switch_img_to_raw(switch_image_t *src, void *dest, int stride, switch_img_fmt_t fmt);
|
||||
/*!\brief convert raw memory to switch_img_t
|
||||
*
|
||||
* if dest is NULL then a new img is created, user should destroy it later,
|
||||
|
||||
@@ -414,6 +414,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_tone_detect_session(switch_core_sessi
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *session, switch_file_handle_t *fh, const char *file,
|
||||
switch_input_args_t *args);
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_detect_audio(switch_core_session_t *session, uint32_t thresh, uint32_t audio_hits,
|
||||
uint32_t timeout_ms, const char *file);
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_detect_silence(switch_core_session_t *session, uint32_t thresh, uint32_t silence_hits,
|
||||
uint32_t timeout_ms, const char *file);
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_wait_for_silence(switch_core_session_t *session, uint32_t thresh, uint32_t silence_hits,
|
||||
uint32_t listen_hits, uint32_t timeout_ms, const char *file);
|
||||
|
||||
|
||||
@@ -139,6 +139,9 @@ typedef int gid_t;
|
||||
#ifndef __BYTE_ORDER
|
||||
#ifdef SWITCH_BYTE_ORDER
|
||||
#define __BYTE_ORDER SWITCH_BYTE_ORDER
|
||||
/* solaris */
|
||||
#elif defined(_BIG_ENDIAN)
|
||||
#define __BYTE_ORDER __BIG_ENDIAN
|
||||
#else
|
||||
#define __BYTE_ORDER __LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
@@ -766,6 +766,7 @@ typedef enum {
|
||||
SWITCH_RTP_FLAG_NACK,
|
||||
SWITCH_RTP_FLAG_TMMBR,
|
||||
SWITCH_RTP_FLAG_GEN_TS_DELTA,
|
||||
SWITCH_RTP_FLAG_DETECT_SSRC,
|
||||
SWITCH_RTP_FLAG_INVALID
|
||||
} switch_rtp_flag_t;
|
||||
|
||||
@@ -1509,6 +1510,7 @@ typedef enum {
|
||||
CF_3P_MEDIA_REQUESTED,
|
||||
CF_3P_NOMEDIA_REQUESTED,
|
||||
CF_3P_NOMEDIA_REQUESTED_BLEG,
|
||||
CF_IMAGE_SDP,
|
||||
CF_VIDEO_SDP_RECVD,
|
||||
/* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
|
||||
/* IF YOU ADD NEW ONES CHECK IF THEY SHOULD PERSIST OR ZERO THEM IN switch_core_session.c switch_core_session_request_xml() */
|
||||
@@ -1627,7 +1629,8 @@ typedef enum {
|
||||
SWITCH_CODEC_FLAG_AAL2 = (1 << 6),
|
||||
SWITCH_CODEC_FLAG_PASSTHROUGH = (1 << 7),
|
||||
SWITCH_CODEC_FLAG_READY = (1 << 8),
|
||||
SWITCH_CODEC_FLAG_HAS_PLC = (1 << 15)
|
||||
SWITCH_CODEC_FLAG_HAS_PLC = (1 << 15),
|
||||
SWITCH_CODEC_FLAG_VIDEO_PATCHING = (1 << 16)
|
||||
} switch_codec_flag_enum_t;
|
||||
typedef uint32_t switch_codec_flag_t;
|
||||
|
||||
@@ -1769,7 +1772,8 @@ typedef enum {
|
||||
SMBF_WRITE_VIDEO_STREAM = (1 << 20),
|
||||
SMBF_VIDEO_PATCH = (1 << 21),
|
||||
SMBF_SPY_VIDEO_STREAM = (1 << 22),
|
||||
SMBF_SPY_VIDEO_STREAM_BLEG = (1 << 23)
|
||||
SMBF_SPY_VIDEO_STREAM_BLEG = (1 << 23),
|
||||
SMBF_READ_VIDEO_PATCH = (1 << 24)
|
||||
} switch_media_bug_flag_enum_t;
|
||||
typedef uint32_t switch_media_bug_flag_t;
|
||||
|
||||
|
||||
@@ -693,7 +693,10 @@ static switch_status_t consume_h263_bitstream(h264_codec_context_t *context, swi
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!context->nalus[context->nalu_current_index].len) frame->m = 1;
|
||||
if (!context->nalus[context->nalu_current_index].len) {
|
||||
av_packet_unref(&context->encoder_avpacket);
|
||||
frame->m = 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
{
|
||||
|
||||
@@ -1239,6 +1239,7 @@ SWITCH_STANDARD_API(av_format_api_function)
|
||||
struct av_file_context {
|
||||
switch_memory_pool_t *pool;
|
||||
switch_mutex_t *mutex;
|
||||
switch_thread_cond_t *cond;
|
||||
switch_buffer_t *buf;
|
||||
switch_buffer_t *audio_buffer;
|
||||
switch_timer_t video_timer;
|
||||
@@ -1261,6 +1262,7 @@ struct av_file_context {
|
||||
record_helper_t eh;
|
||||
switch_thread_t *file_read_thread;
|
||||
int file_read_thread_running;
|
||||
int file_read_thread_started;
|
||||
switch_time_t video_start_time;
|
||||
switch_image_t *last_img;
|
||||
int read_fps;
|
||||
@@ -1417,7 +1419,11 @@ static void *SWITCH_THREAD_FUNC file_read_thread_run(switch_thread_t *thread, vo
|
||||
int sync = 0;
|
||||
int eof = 0;
|
||||
|
||||
switch_mutex_lock(context->mutex);
|
||||
context->file_read_thread_started = 1;
|
||||
context->file_read_thread_running = 1;
|
||||
switch_thread_cond_signal(context->cond);
|
||||
switch_mutex_unlock(context->mutex);
|
||||
|
||||
while (context->file_read_thread_running && !context->closed) {
|
||||
int vid_frames = 0;
|
||||
@@ -1684,6 +1690,7 @@ static switch_status_t av_file_open(switch_file_handle_t *handle, const char *pa
|
||||
}
|
||||
|
||||
switch_mutex_init(&context->mutex, SWITCH_MUTEX_NESTED, handle->memory_pool);
|
||||
switch_thread_cond_create(&context->cond, handle->memory_pool);
|
||||
switch_buffer_create_dynamic(&context->audio_buffer, 512, 512, 0);
|
||||
|
||||
if (!context->audio_buffer) {
|
||||
@@ -2064,6 +2071,12 @@ static switch_status_t av_file_read(switch_file_handle_t *handle, void *data, si
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_mutex_lock(context->mutex);
|
||||
while (!context->file_read_thread_started) {
|
||||
switch_thread_cond_wait(context->cond, context->mutex);
|
||||
}
|
||||
switch_mutex_unlock(context->mutex);
|
||||
|
||||
if (!context->file_read_thread_running && switch_buffer_inuse(context->audio_buffer) == 0) {
|
||||
*len = 0;
|
||||
return SWITCH_STATUS_FALSE;
|
||||
|
||||
@@ -5,15 +5,8 @@
|
||||
#include "avmd_amplitude.h"
|
||||
#include "avmd_psi.h"
|
||||
|
||||
/*! \brief
|
||||
* @author Eric des Courtis
|
||||
* @param b A circular audio sample buffer
|
||||
* @param i Position in the buffer
|
||||
* @param f Frequency estimate
|
||||
* @return The amplitude at position i
|
||||
*/
|
||||
extern double avmd_amplitude(circ_buffer_t *b, size_t i, double f)
|
||||
{
|
||||
|
||||
double avmd_amplitude(circ_buffer_t *b, size_t i, double f) {
|
||||
double result;
|
||||
result = sqrt(PSI(b, i) / sin(f * f));
|
||||
return result;
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
/*
|
||||
* @brief Estimation of amplitude using DESA-2 algorithm.
|
||||
* @author Eric des Courtis
|
||||
* @par Modifications: Piotr Gregor < piotrek.gregor gmail.com >
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Eric des Courtis <eric.des.courtis@benbria.com>
|
||||
* Piotr Gregor <piotrek.gregor gmail.com>:
|
||||
*/
|
||||
|
||||
|
||||
@@ -12,7 +15,12 @@
|
||||
#include "avmd_buffer.h"
|
||||
|
||||
|
||||
extern double avmd_amplitude(circ_buffer_t *, size_t i, double f);
|
||||
#ifdef WIN32
|
||||
#define __attribute__(x)
|
||||
#endif
|
||||
|
||||
|
||||
double avmd_amplitude(circ_buffer_t *, size_t i, double f) __attribute__ ((nonnull(1)));
|
||||
|
||||
|
||||
#endif /* __AVMD_AMPLITUDE_H__ */
|
||||
|
||||
@@ -19,8 +19,8 @@ int __isnan(double);
|
||||
#include "avmd_fast_acosf.h"
|
||||
#endif
|
||||
|
||||
extern double avmd_desa2(circ_buffer_t *b, size_t i)
|
||||
{
|
||||
|
||||
double avmd_desa2(circ_buffer_t *b, size_t i, double *amplitude) {
|
||||
double d;
|
||||
double n;
|
||||
double x0;
|
||||
@@ -30,6 +30,7 @@ extern double avmd_desa2(circ_buffer_t *b, size_t i)
|
||||
double x4;
|
||||
double x2sq;
|
||||
double result;
|
||||
double PSI_Xn, PSI_Yn, NEEDED;
|
||||
|
||||
x0 = GET_SAMPLE((b), (i));
|
||||
x1 = GET_SAMPLE((b), ((i) + 1));
|
||||
@@ -39,8 +40,14 @@ extern double avmd_desa2(circ_buffer_t *b, size_t i)
|
||||
|
||||
x2sq = x2 * x2;
|
||||
d = 2.0 * ((x2sq) - (x1 * x3));
|
||||
if (d == 0.0) return 0.0;
|
||||
n = ((x2sq) - (x0 * x4)) - ((x1 * x1) - (x0 * x2)) - ((x3 * x3) - (x2 * x4));
|
||||
if (d == 0.0) {
|
||||
*amplitude = 0.0;
|
||||
return 0.0;
|
||||
}
|
||||
PSI_Xn = ((x2sq) - (x0 * x4));
|
||||
NEEDED = ((x1 * x1) - (x0 * x2)) + ((x3 * x3) - (x2 * x4));
|
||||
n = ((x2sq) - (x0 * x4)) - NEEDED;
|
||||
PSI_Yn = NEEDED + PSI_Xn;
|
||||
|
||||
#ifdef AVMD_FAST_MATH
|
||||
result = 0.5 * (double)fast_acosf((float)n/d);
|
||||
@@ -48,7 +55,10 @@ extern double avmd_desa2(circ_buffer_t *b, size_t i)
|
||||
result = 0.5 * acos(n/d);
|
||||
#endif
|
||||
|
||||
if (ISNAN(result)) result = 0.0;
|
||||
if (ISNAN(result)) {
|
||||
result = 0.0;
|
||||
}
|
||||
*amplitude = 2.0 * PSI_Xn / sqrt(PSI_Yn);
|
||||
|
||||
return result;
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
/*
|
||||
* @brief DESA-2 algorithm implementation.
|
||||
* @author Eric des Courtis
|
||||
* @par Modifications: Piotr Gregor < piotrek.gregor gmail.com >
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Eric des Courtis <eric.des.courtis@benbria.com>
|
||||
* Piotr Gregor <piotrek.gregor gmail.com>:
|
||||
*/
|
||||
|
||||
|
||||
@@ -12,8 +15,14 @@
|
||||
#include <math.h>
|
||||
#include "avmd_buffer.h"
|
||||
|
||||
/* Returns digital frequency estimation. */
|
||||
extern double avmd_desa2(circ_buffer_t *b, size_t i);
|
||||
|
||||
#ifdef WIN32
|
||||
#define __attribute__(x)
|
||||
#endif
|
||||
|
||||
|
||||
/* Returns digital frequency estimation and amplitude estimation. */
|
||||
extern double avmd_desa2(circ_buffer_t *b, size_t i, double *amplitude) __attribute__ ((nonnull(1,3)));
|
||||
|
||||
|
||||
#endif /* __AVMD_DESA2_H__ */
|
||||
|
||||
@@ -19,11 +19,10 @@ int __isnan(double);
|
||||
#include "avmd_fast_acosf.h"
|
||||
#endif
|
||||
|
||||
|
||||
double
|
||||
avmd_desa2_tweaked(circ_buffer_t *b, size_t i)
|
||||
{
|
||||
double d;
|
||||
double n;
|
||||
avmd_desa2_tweaked(circ_buffer_t *b, size_t i, double *amplitude) {
|
||||
double n, d;
|
||||
double x0;
|
||||
double x1;
|
||||
double x2;
|
||||
@@ -31,6 +30,7 @@ avmd_desa2_tweaked(circ_buffer_t *b, size_t i)
|
||||
double x4;
|
||||
double x2sq;
|
||||
double result;
|
||||
double PSI_Xn, PSI_Yn, NEEDED;
|
||||
|
||||
x0 = GET_SAMPLE((b), (i));
|
||||
x1 = GET_SAMPLE((b), ((i) + 1));
|
||||
@@ -39,8 +39,10 @@ avmd_desa2_tweaked(circ_buffer_t *b, size_t i)
|
||||
x4 = GET_SAMPLE((b), ((i) + 4));
|
||||
x2sq = x2 * x2;
|
||||
d = 2.0 * ((x2sq) - (x1 * x3));
|
||||
n = ((x2sq) - (x0 * x4)) - ((x1 * x1)
|
||||
- (x0 * x2)) - ((x3 * x3) - (x2 * x4));
|
||||
PSI_Xn = ((x2sq) - (x0 * x4));
|
||||
NEEDED = ((x1 * x1) - (x0 * x2)) + ((x3 * x3) - (x2 * x4));
|
||||
n = ((x2sq) - (x0 * x4)) - NEEDED;
|
||||
PSI_Yn = NEEDED + PSI_Xn;
|
||||
|
||||
/* instead of
|
||||
#ifdef FASTMATH
|
||||
@@ -52,11 +54,14 @@ avmd_desa2_tweaked(circ_buffer_t *b, size_t i)
|
||||
|
||||
result = n/d;
|
||||
if (ISINF(result)) {
|
||||
if (n < 0.0)
|
||||
*amplitude = 0.0;
|
||||
if (n < 0.0) {
|
||||
return -10.0;
|
||||
else
|
||||
} else {
|
||||
return 10.0;
|
||||
}
|
||||
}
|
||||
*amplitude = 2.0 * PSI_Xn / sqrt(PSI_Yn);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,11 @@
|
||||
#include <switch.h>
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
#define __attribute__(x)
|
||||
#endif
|
||||
|
||||
|
||||
/* Instead of returning digital frequency estimation using
|
||||
* result = 0.5 * acos(n/d),
|
||||
* which involves expensive computation of arc cosine on
|
||||
@@ -33,9 +38,10 @@
|
||||
* to corresponding frequencies is nonlinear.
|
||||
* The actual frequency estimation can be retrieved later
|
||||
* from this partial result using
|
||||
* 0.5 * acos(n/d)
|
||||
* 0.5 * acos(returned_value)
|
||||
* Amplitude estimation is returned by address.
|
||||
*/
|
||||
double avmd_desa2_tweaked(circ_buffer_t *b, size_t i);
|
||||
double avmd_desa2_tweaked(circ_buffer_t *b, size_t i, double *amplitude) __attribute__ ((nonnull(1,3)));
|
||||
|
||||
|
||||
#endif /* __AVMD_DESA2_TWEAKED_H__ */
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#include "avmd_buffer.h"
|
||||
|
||||
#define PSI(b, i) (GET_SAMPLE((b), ((i) + 1))*GET_SAMPLE((b), ((i) + 1))-GET_SAMPLE((b), ((i) + 2))*GET_SAMPLE((b), ((i) + 0)))
|
||||
|
||||
#define PSI(b, i) (GET_SAMPLE((b), ((i) + 1)) * GET_SAMPLE((b), ((i) + 1)) - GET_SAMPLE((b), ((i) + 2)) * GET_SAMPLE((b), ((i) + 0)))
|
||||
|
||||
|
||||
#endif /* __AVMD_PSI_H__ */
|
||||
|
||||
@@ -8,12 +8,14 @@
|
||||
|
||||
<!-- Global settings -->
|
||||
|
||||
<!-- define/undefine this to enable/disable printing of avmd
|
||||
<!-- define/undefine this to enable/disable logging of avmd
|
||||
intermediate computations to log -->
|
||||
<param name="debug" value="0"/>
|
||||
|
||||
<!-- define/undef this to enable/disable reporting of beep
|
||||
detection status after session ended -->
|
||||
<!-- define/undef this to enable/disable verbose logging (and reporting to the console)
|
||||
of detection status and other diagnostics like parameters avmd session has been started with,
|
||||
change of configuration parameters, beep detection status after session ended
|
||||
(stop event is fired independently of this setting and beep status included there) -->
|
||||
<param name="report_status" value="1"/>
|
||||
|
||||
<!-- define/undefine this to enable/disable faster computation
|
||||
@@ -33,12 +35,15 @@
|
||||
<param name="require_continuous_streak" value="1"/>
|
||||
|
||||
<!-- required number of consecutive elements in the SMA buffer
|
||||
without reset -->
|
||||
without reset. This parameter helps to avoid false beeps, bigger this value is
|
||||
smaller the probability of getting false detection -->
|
||||
<param name="sample_n_continuous_streak" value="15"/>
|
||||
|
||||
<!-- define number of samples to skip starting from the beginning
|
||||
of the frame and after reset -->
|
||||
<param name="sample_n_to_skip" value="6"/>
|
||||
of the frame and/or after reset has happened. This serves the purpose of skipping first few
|
||||
estimations on each frame, as these estimations may be inaccurate. This parameter also helps
|
||||
to give more robust detections when it's value is increased (up to scertain limit of about 60). -->
|
||||
<param name="sample_n_to_skip" value="15"/>
|
||||
|
||||
<!-- define/undefine this to enable/disable simplified estimation
|
||||
of frequency based on approximation of sin(x) with (x)
|
||||
|
||||
@@ -35,8 +35,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <float.h>
|
||||
#include <inttypes.h>
|
||||
#define ISNAN(x) (!!(_isnan(x)))
|
||||
#define ISINF(x) (isinf(x))
|
||||
#else
|
||||
@@ -175,11 +177,13 @@ typedef struct {
|
||||
circ_buffer_t b;
|
||||
sma_buffer_t sma_b;
|
||||
sma_buffer_t sqa_b;
|
||||
sma_buffer_t sma_amp_b;
|
||||
sma_buffer_t sqa_amp_b;
|
||||
size_t pos;
|
||||
double f;
|
||||
/* freq_table_t ft; */
|
||||
avmd_state_t state;
|
||||
switch_time_t start_time;
|
||||
switch_time_t start_time, stop_time, detection_start_time, detection_stop_time;
|
||||
size_t samples_streak; /* number of DESA samples in single streak without reset needed to validate SMA estimator */
|
||||
size_t sample_count;
|
||||
} avmd_session_t;
|
||||
@@ -199,7 +203,8 @@ static switch_status_t avmd_register_all_events(void);
|
||||
static void avmd_unregister_all_events(void);
|
||||
|
||||
static void
|
||||
avmd_fire_event(enum avmd_event type, switch_core_session_t *fs_s, double freq, double v, avmd_beep_state_t beep_status, uint8_t info);
|
||||
avmd_fire_event(enum avmd_event type, switch_core_session_t *fs_s, double freq, double v_freq, double amp, double v_amp, avmd_beep_state_t beep_status, uint8_t info,
|
||||
switch_time_t detection_start_time, switch_time_t detection_stop_time, switch_time_t start_time, switch_time_t stop_time);
|
||||
|
||||
/* API [set default], reset to factory settings */
|
||||
static void avmd_set_xml_default_configuration(switch_mutex_t *mutex);
|
||||
@@ -256,6 +261,8 @@ init_avmd_session_data(avmd_session_t *avmd_session, switch_core_session_t *fs_s
|
||||
memcpy(&avmd_session->settings, &avmd_globals.settings, sizeof(struct avmd_settings));
|
||||
switch_mutex_init(&avmd_session->mutex, SWITCH_MUTEX_DEFAULT, switch_core_session_get_pool(fs_session));
|
||||
avmd_session->sample_count = 0;
|
||||
avmd_session->detection_start_time = 0;
|
||||
avmd_session->detection_stop_time = 0;
|
||||
|
||||
buf_sz = BEEP_LEN((uint32_t)avmd_session->rate) / (uint32_t)SINE_LEN(avmd_session->rate);
|
||||
if (buf_sz < 1) {
|
||||
@@ -276,6 +283,20 @@ init_avmd_session_data(avmd_session_t *avmd_session, switch_core_session_t *fs_s
|
||||
goto end;
|
||||
}
|
||||
memset(avmd_session->sqa_b.data, 0, sizeof(BUFF_TYPE) * buf_sz);
|
||||
|
||||
INIT_SMA_BUFFER(&avmd_session->sma_amp_b, buf_sz, fs_session);
|
||||
if (avmd_session->sma_amp_b.data == NULL) {
|
||||
status = SWITCH_STATUS_FALSE;
|
||||
goto end;
|
||||
}
|
||||
memset(avmd_session->sma_amp_b.data, 0, sizeof(BUFF_TYPE) * buf_sz);
|
||||
|
||||
INIT_SMA_BUFFER(&avmd_session->sqa_amp_b, buf_sz, fs_session);
|
||||
if (avmd_session->sqa_amp_b.data == NULL) {
|
||||
status = SWITCH_STATUS_FALSE;
|
||||
goto end;
|
||||
}
|
||||
memset(avmd_session->sqa_amp_b.data, 0, sizeof(BUFF_TYPE) * buf_sz);
|
||||
end:
|
||||
if (mutex != NULL)
|
||||
{
|
||||
@@ -407,10 +428,11 @@ avmd_unregister_all_events(void)
|
||||
}
|
||||
|
||||
static void
|
||||
avmd_fire_event(enum avmd_event type, switch_core_session_t *fs_s, double freq, double v, avmd_beep_state_t beep_status, uint8_t info)
|
||||
{
|
||||
avmd_fire_event(enum avmd_event type, switch_core_session_t *fs_s, double freq, double v_freq, double amp, double v_amp, avmd_beep_state_t beep_status, uint8_t info,
|
||||
switch_time_t detection_start_time, switch_time_t detection_stop_time, switch_time_t start_time, switch_time_t stop_time) {
|
||||
int res;
|
||||
switch_event_t *event;
|
||||
switch_time_t detection_time, total_time;
|
||||
switch_status_t status;
|
||||
switch_event_t *event_copy;
|
||||
char buf[AVMD_CHAR_BUF_LEN];
|
||||
@@ -421,26 +443,53 @@ avmd_fire_event(enum avmd_event type, switch_core_session_t *fs_s, double freq,
|
||||
}
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(fs_s));
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "avmd");
|
||||
switch (type)
|
||||
{
|
||||
switch (type) {
|
||||
case AVMD_EVENT_BEEP:
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Beep-Status", "DETECTED");
|
||||
res = snprintf(buf, AVMD_CHAR_BUF_LEN, "%f", freq);
|
||||
if (res < 0 || res > AVMD_CHAR_BUF_LEN - 1) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fs_s), SWITCH_LOG_ERROR, "Frequency truncated [%s], [%d] attempted!\n", buf, res);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "frequency", "ERROR (TRUNCATED)");
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Frequency", "ERROR (TRUNCATED)");
|
||||
}
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "frequency", buf);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Frequency", buf);
|
||||
|
||||
res = snprintf(buf, AVMD_CHAR_BUF_LEN, "%f", v);
|
||||
res = snprintf(buf, AVMD_CHAR_BUF_LEN, "%f", v_freq);
|
||||
if (res < 0 || res > AVMD_CHAR_BUF_LEN - 1) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fs_s), SWITCH_LOG_ERROR, "Error, truncated [%s], [%d] attempeted!\n", buf, res);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "variance", "ERROR (TRUNCATED)");
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Frequency-variance", "ERROR (TRUNCATED)");
|
||||
}
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "variance", buf);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Frequency-variance", buf);
|
||||
|
||||
res = snprintf(buf, AVMD_CHAR_BUF_LEN, "%f", amp);
|
||||
if (res < 0 || res > AVMD_CHAR_BUF_LEN - 1) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fs_s), SWITCH_LOG_ERROR, "Amplitude truncated [%s], [%d] attempted!\n", buf, res);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Amplitude", "ERROR (TRUNCATED)");
|
||||
}
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Amplitude", buf);
|
||||
|
||||
res = snprintf(buf, AVMD_CHAR_BUF_LEN, "%f", v_amp);
|
||||
if (res < 0 || res > AVMD_CHAR_BUF_LEN - 1) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fs_s), SWITCH_LOG_ERROR, "Error, truncated [%s], [%d] attempeted!\n", buf, res);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Amplitude-variance", "ERROR (TRUNCATED)");
|
||||
}
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Amplitude-variance", buf);
|
||||
|
||||
detection_time = detection_stop_time - detection_start_time;
|
||||
res = snprintf(buf, AVMD_CHAR_BUF_LEN, "%" PRId64 "", detection_time);
|
||||
if (res < 0 || res > AVMD_CHAR_BUF_LEN - 1) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fs_s), SWITCH_LOG_ERROR, "Detection time truncated [%s], [%d] attempted!\n", buf, res);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Detection-time", "ERROR (TRUNCATED)");
|
||||
}
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Detection-time", buf);
|
||||
break;
|
||||
|
||||
case AVMD_EVENT_SESSION_START:
|
||||
res = snprintf(buf, AVMD_CHAR_BUF_LEN, "%" PRId64 "", start_time);
|
||||
if (res < 0 || res > AVMD_CHAR_BUF_LEN - 1) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fs_s), SWITCH_LOG_ERROR, "Start time truncated [%s], [%d] attempted!\n", buf, res);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Start-time", "ERROR (TRUNCATED)");
|
||||
}
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Start-time", buf);
|
||||
break;
|
||||
|
||||
case AVMD_EVENT_SESSION_STOP:
|
||||
@@ -449,6 +498,13 @@ avmd_fire_event(enum avmd_event type, switch_core_session_t *fs_s, double freq,
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fs_s), SWITCH_LOG_ERROR, "Error, avmd session object not found in media bug!\n");
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "stop-status", "ERROR (AVMD SESSION OBJECT NOT FOUND IN MEDIA BUG)");
|
||||
}
|
||||
total_time = stop_time - start_time;
|
||||
res = snprintf(buf, AVMD_CHAR_BUF_LEN, "%" PRId64 "", total_time);
|
||||
if (res < 0 || res > AVMD_CHAR_BUF_LEN - 1) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fs_s), SWITCH_LOG_ERROR, "Total time truncated [%s], [%d] attempted!\n", buf, res);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Total-time", "ERROR (TRUNCATED)");
|
||||
}
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Total-time", buf);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -507,7 +563,7 @@ static void avmd_set_xml_default_configuration(switch_mutex_t *mutex)
|
||||
avmd_globals.settings.fast_math = 0;
|
||||
avmd_globals.settings.require_continuous_streak = 1;
|
||||
avmd_globals.settings.sample_n_continuous_streak = 15;
|
||||
avmd_globals.settings.sample_n_to_skip = 6;
|
||||
avmd_globals.settings.sample_n_to_skip = 15;
|
||||
avmd_globals.settings.simplified_estimation = 1;
|
||||
avmd_globals.settings.inbound_channnel = 0;
|
||||
avmd_globals.settings.outbound_channnel = 1;
|
||||
@@ -1055,7 +1111,7 @@ SWITCH_STANDARD_APP(avmd_start_app)
|
||||
goto end;
|
||||
}
|
||||
switch_channel_set_private(channel, "_avmd_", bug); /* Set the avmd tag to detect an existing avmd media bug */
|
||||
avmd_fire_event(AVMD_EVENT_SESSION_START, session, 0, 0, 0, 0);
|
||||
avmd_fire_event(AVMD_EVENT_SESSION_START, session, 0, 0, 0, 0, 0, 0, 0, 0, avmd_session->start_time, 0);
|
||||
if (avmd_session->settings.report_status == 1) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Avmd on channel [%s] started!\n", switch_channel_get_name(channel));
|
||||
}
|
||||
@@ -1070,7 +1126,8 @@ SWITCH_STANDARD_APP(avmd_stop_app)
|
||||
switch_media_bug_t *bug;
|
||||
switch_channel_t *channel;
|
||||
avmd_session_t *avmd_session;
|
||||
uint8_t report_status = 0, avmd_found = 1;
|
||||
switch_time_t start_time, stop_time, total_time;
|
||||
uint8_t report_status = 0;
|
||||
avmd_beep_state_t beep_status = BEEP_NOTDETECTED;
|
||||
|
||||
if (session == NULL) {
|
||||
@@ -1101,26 +1158,25 @@ SWITCH_STANDARD_APP(avmd_stop_app)
|
||||
|
||||
avmd_session = switch_core_media_bug_get_user_data(bug);
|
||||
if (avmd_session == NULL) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Stop failed - no avmd session object"
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Stop failed - no avmd session object, stop event not fired"
|
||||
" on this channel [%s]!\n", switch_channel_get_name(channel));
|
||||
avmd_found = 0;
|
||||
} else {
|
||||
switch_mutex_lock(avmd_session->mutex);
|
||||
report_status = avmd_session->settings.report_status;
|
||||
beep_status = avmd_session->state.beep_state;
|
||||
avmd_session->stop_time = switch_micro_time_now();
|
||||
start_time = avmd_session->start_time;
|
||||
stop_time = avmd_session->stop_time;
|
||||
total_time = stop_time - start_time;
|
||||
switch_mutex_unlock(avmd_session->mutex);
|
||||
avmd_fire_event(AVMD_EVENT_SESSION_STOP, session, 0, 0, 0, 0, beep_status, 1, 0, 0, start_time, stop_time);
|
||||
if (report_status == 1) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Avmd on channel [%s] stopped, beep status: [%s], total running time [%" PRId64 "] [us]\n",
|
||||
switch_channel_get_name(channel), beep_status == BEEP_DETECTED ? "DETECTED" : "NOTDETECTED", total_time);
|
||||
}
|
||||
}
|
||||
switch_channel_set_private(channel, "_avmd_", NULL);
|
||||
switch_core_media_bug_remove(session, &bug);
|
||||
if (avmd_found == 1) {
|
||||
avmd_fire_event(AVMD_EVENT_SESSION_STOP, session, 0, 0, beep_status, 1);
|
||||
} else {
|
||||
avmd_fire_event(AVMD_EVENT_SESSION_STOP, session, 0, 0, beep_status, 0);
|
||||
}
|
||||
if (report_status == 1) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Avmd on channel [%s] stopped, beep status: [%s]\n",
|
||||
switch_channel_get_name(channel), beep_status == BEEP_DETECTED ? "DETECTED" : "NOTDETECTED");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1376,15 +1432,19 @@ SWITCH_STANDARD_API(avmd_api_main)
|
||||
if (bug != NULL) {
|
||||
/* If we have a stop remove audio bug */
|
||||
if (strcasecmp(command, "stop") == 0) {
|
||||
avmd_session = (avmd_session_t*) switch_core_media_bug_get_user_data(bug);
|
||||
if (avmd_session == NULL) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fs_session), SWITCH_LOG_ERROR, "Stop failed - no avmd session object"
|
||||
" on this channel [%s]!\n", switch_channel_get_name(channel));
|
||||
goto end;
|
||||
}
|
||||
uuid_dup = switch_core_strdup(switch_core_session_get_pool(fs_session), uuid);
|
||||
switch_channel_set_private(channel, "_avmd_", NULL);
|
||||
switch_core_media_bug_remove(fs_session, &bug);
|
||||
avmd_fire_event(AVMD_EVENT_SESSION_STOP, fs_session, 0, 0, 0, 0);
|
||||
avmd_fire_event(AVMD_EVENT_SESSION_STOP, fs_session, 0, 0, 0, 0, 0, 0, 0, 0, avmd_session->start_time, avmd_session->stop_time);
|
||||
if (avmd_globals.settings.report_status == 1) {
|
||||
stream->write_function(stream, "+OK\n [%s] [%s] stopped\n\n",
|
||||
uuid_dup, switch_channel_get_name(channel));
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fs_session), SWITCH_LOG_INFO,
|
||||
"Avmd on channel [%s] stopped!\n", switch_channel_get_name(channel));
|
||||
stream->write_function(stream, "+OK\n [%s] [%s] stopped\n\n", uuid_dup, switch_channel_get_name(channel));
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fs_session), SWITCH_LOG_INFO, "Avmd on channel [%s] stopped!\n", switch_channel_get_name(channel));
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
@@ -1500,7 +1560,7 @@ SWITCH_STANDARD_API(avmd_api_main)
|
||||
|
||||
switch_channel_set_private(channel, "_avmd_", bug); /* Set the vmd tag to detect an existing vmd media bug */
|
||||
|
||||
avmd_fire_event(AVMD_EVENT_SESSION_START, fs_session, 0, 0, 0, 0);
|
||||
avmd_fire_event(AVMD_EVENT_SESSION_START, fs_session, 0, 0, 0, 0, 0, 0, 0, 0, avmd_session->start_time, 0);
|
||||
if (avmd_globals.settings.report_status == 1) {
|
||||
stream->write_function(stream, "+OK\n [%s] [%s] started!\n\n",
|
||||
uuid, switch_channel_get_name(channel));
|
||||
@@ -1527,11 +1587,12 @@ end:
|
||||
*/
|
||||
static void avmd_process(avmd_session_t *s, switch_frame_t *frame) {
|
||||
switch_channel_t *channel;
|
||||
switch_time_t detection_time;
|
||||
circ_buffer_t *b;
|
||||
size_t pos;
|
||||
double omega;
|
||||
double omega, amplitude;
|
||||
double f;
|
||||
double v;
|
||||
double v, v_amp = 0.0;
|
||||
double sma_digital_freq;
|
||||
uint32_t sine_len_i;
|
||||
int sample_to_skip_n = s->settings.sample_n_to_skip;
|
||||
@@ -1541,6 +1602,9 @@ static void avmd_process(avmd_session_t *s, switch_frame_t *frame) {
|
||||
|
||||
/* If beep has already been detected skip the CPU heavy stuff */
|
||||
if (s->state.beep_state == BEEP_DETECTED) return;
|
||||
if (s->detection_start_time == 0) {
|
||||
s->detection_start_time = switch_micro_time_now(); /* start detection timer */
|
||||
}
|
||||
|
||||
/* Precompute values used heavily in the inner loop */
|
||||
sine_len_i = (uint32_t) SINE_LEN(s->rate);
|
||||
@@ -1559,7 +1623,7 @@ static void avmd_process(avmd_session_t *s, switch_frame_t *frame) {
|
||||
/*for (pos = session->pos; pos < (GET_CURRENT_POS(b) - P); pos++) { */
|
||||
if ((sample_n % sine_len_i) == 0) {
|
||||
/* Get a desa2 frequency estimate every sine len */
|
||||
omega = avmd_desa2_tweaked(b, pos + sample_n);
|
||||
omega = avmd_desa2_tweaked(b, pos + sample_n, &litude);
|
||||
|
||||
if (omega < -0.999999 || omega > 0.999999) {
|
||||
if (s->settings.debug == 1) {
|
||||
@@ -1569,6 +1633,8 @@ static void avmd_process(avmd_session_t *s, switch_frame_t *frame) {
|
||||
if (s->settings.require_continuous_streak == 1) {
|
||||
RESET_SMA_BUFFER(&s->sma_b);
|
||||
RESET_SMA_BUFFER(&s->sqa_b);
|
||||
RESET_SMA_BUFFER(&s->sma_amp_b);
|
||||
RESET_SMA_BUFFER(&s->sqa_amp_b);
|
||||
s->samples_streak = s->settings.sample_n_continuous_streak;
|
||||
sample_to_skip_n = s->settings.sample_n_to_skip;
|
||||
}
|
||||
@@ -1603,12 +1669,15 @@ static void avmd_process(avmd_session_t *s, switch_frame_t *frame) {
|
||||
|
||||
APPEND_SMA_VAL(&s->sma_b, omega); /* append */
|
||||
APPEND_SMA_VAL(&s->sqa_b, omega * omega);
|
||||
APPEND_SMA_VAL(&s->sma_amp_b, amplitude); /* append */
|
||||
APPEND_SMA_VAL(&s->sqa_amp_b, amplitude * amplitude);
|
||||
if (s->settings.require_continuous_streak == 1) {
|
||||
if (s->samples_streak > 0) {
|
||||
--s->samples_streak;
|
||||
}
|
||||
}
|
||||
v = s->sqa_b.sma - (s->sma_b.sma * s->sma_b.sma); /* calculate variance (biased estimator) */
|
||||
v = s->sqa_b.sma - (s->sma_b.sma * s->sma_b.sma); /* calculate variance of omega(biased estimator) */
|
||||
v_amp = s->sqa_amp_b.sma - (s->sma_amp_b.sma * s->sma_amp_b.sma); /* calculate variance of amplitude (biased estimator) */
|
||||
if (s->settings.debug == 1) {
|
||||
#if !defined(WIN32) && defined(AVMD_FAST_MATH)
|
||||
f = 0.5 * (double) fast_acosf((float)omega);
|
||||
@@ -1619,11 +1688,16 @@ static void avmd_process(avmd_session_t *s, switch_frame_t *frame) {
|
||||
#endif /* !WIN32 && AVMD_FAST_MATH */
|
||||
if (s->settings.require_continuous_streak == 1) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session), SWITCH_LOG_DEBUG, "<<< AVMD v[%.10f]\tomega[%f]\tf[%f] [%f]Hz\t\tsma[%f][%f]Hz\t\tsqa[%f]\t"
|
||||
"streak[%zu] pos[%zu] sample_n[%zu] lpos[%zu] s[%zu]>>>\n", v, omega, f, TO_HZ(s->rate, f), s->sma_b.sma, TO_HZ(s->rate, sma_digital_freq), s->sqa_b.sma, s->samples_streak,
|
||||
s->sma_b.pos, sample_n, s->sma_b.lpos, pos);
|
||||
"amplitude[%f]\tv_amp[%f]\t"
|
||||
"streak[%zu] pos[%zu] sample_n[%zu] lpos[%zu] s[%zu]>>>\n", v, omega, f, TO_HZ(s->rate, f), s->sma_b.sma, TO_HZ(s->rate, sma_digital_freq), s->sqa_b.sma,
|
||||
amplitude, v_amp,
|
||||
s->samples_streak, s->sma_b.pos, sample_n, s->sma_b.lpos, pos);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session), SWITCH_LOG_DEBUG, "<<< AVMD v[%.10f]\tomega[%f]\tf[%f] [%f]Hz\t\tsma[%f][%f]Hz\t\tsqa[%f]\tpos[%zu]"
|
||||
" sample_n[%zu] lpos[%zu] s[%zu]>>>\n", v, omega, f, TO_HZ(s->rate, f), s->sma_b.sma, TO_HZ(s->rate, sma_digital_freq), s->sqa_b.sma, s->sma_b.pos, sample_n, s->sma_b.lpos, pos);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session), SWITCH_LOG_DEBUG, "<<< AVMD v[%.10f]\tomega[%f]\tf[%f] [%f]Hz\t\tsma[%f][%f]Hz\t\tsqa[%f]\t"
|
||||
"amplitude[%f]\tv_amp[%f]\t"
|
||||
"pos[%zu] sample_n[%zu] lpos[%zu] s[%zu]>>>\n", v, omega, f, TO_HZ(s->rate, f), s->sma_b.sma, TO_HZ(s->rate, sma_digital_freq), s->sqa_b.sma,
|
||||
amplitude, v_amp,
|
||||
s->sma_b.pos, sample_n, s->sma_b.lpos, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1639,15 +1713,19 @@ static void avmd_process(avmd_session_t *s, switch_frame_t *frame) {
|
||||
sma_digital_freq = 0.5 * acos(s->sma_b.sma);
|
||||
#endif /* !WIN32 && AVMD_FAST_MATH */
|
||||
|
||||
switch_channel_set_variable_printf(channel, "avmd_total_time", "[%d]", (int)(switch_micro_time_now() - s->start_time) / 1000);
|
||||
s->detection_stop_time = switch_micro_time_now(); /* stop detection timer */
|
||||
detection_time = s->detection_stop_time - s->detection_start_time; /* detection time length */
|
||||
switch_channel_set_variable_printf(channel, "avmd_total_time", "[%" PRId64 "]", detection_time / 1000);
|
||||
switch_channel_execute_on(channel, "execute_on_avmd_beep");
|
||||
avmd_fire_event(AVMD_EVENT_BEEP, s->session, TO_HZ(s->rate, sma_digital_freq), v, 0, 0);
|
||||
avmd_fire_event(AVMD_EVENT_BEEP, s->session, TO_HZ(s->rate, sma_digital_freq), v, s->sma_amp_b.sma, v_amp, 0, 0, s->detection_start_time, s->detection_stop_time, 0, 0);
|
||||
if (s->settings.report_status == 1) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session), SWITCH_LOG_INFO, "<<< AVMD - Beep Detected: f = [%f], variance = [%f] >>>\n", TO_HZ(s->rate, sma_digital_freq), v);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(s->session), SWITCH_LOG_INFO, "<<< AVMD - Beep Detected: f = [%f] variance = [%f], amplitude = [%f] variance = [%f], detection time [%" PRId64 "] [us] >>>\n", TO_HZ(s->rate, sma_digital_freq), v, s->sma_amp_b.sma, v_amp, detection_time);
|
||||
}
|
||||
switch_channel_set_variable(channel, "avmd_detect", "TRUE");
|
||||
RESET_SMA_BUFFER(&s->sma_b);
|
||||
RESET_SMA_BUFFER(&s->sqa_b);
|
||||
RESET_SMA_BUFFER(&s->sma_amp_b);
|
||||
RESET_SMA_BUFFER(&s->sqa_amp_b);
|
||||
s->state.beep_state = BEEP_DETECTED;
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -1556,6 +1556,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
|
||||
switch_time_t t_agent_answered = 0;
|
||||
switch_time_t t_member_called = atoi(h->member_joined_epoch);
|
||||
switch_event_t *event = NULL;
|
||||
int bridged = 1;
|
||||
|
||||
switch_mutex_lock(globals.mutex);
|
||||
globals.threads++;
|
||||
@@ -1786,21 +1787,6 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-DNIS", member_dnis);
|
||||
switch_event_fire(&event);
|
||||
}
|
||||
/* for xml_cdr needs */
|
||||
switch_channel_set_variable(member_channel, "cc_agent", h->agent_name);
|
||||
switch_channel_set_variable_printf(member_channel, "cc_queue_answered_epoch", "%" SWITCH_TIME_T_FMT, local_epoch_time_now(NULL));
|
||||
|
||||
/* Set UUID of the Agent channel */
|
||||
sql = switch_mprintf("UPDATE agents SET uuid = '%q', last_bridge_start = '%" SWITCH_TIME_T_FMT "', calls_answered = calls_answered + 1, no_answer_count = 0"
|
||||
" WHERE name = '%q' AND system = '%q'",
|
||||
agent_uuid, local_epoch_time_now(NULL),
|
||||
h->agent_name, h->agent_system);
|
||||
cc_execute_sql(NULL, sql, NULL);
|
||||
switch_safe_free(sql);
|
||||
|
||||
/* Change the agents Status in the tiers */
|
||||
cc_tier_update("state", cc_tier_state2str(CC_TIER_STATE_ACTIVE_INBOUND), h->queue_name, h->agent_name);
|
||||
cc_agent_update("state", cc_agent_state2str(CC_AGENT_STATE_IN_A_QUEUE_CALL), h->agent_name);
|
||||
|
||||
/* Record session if record-template is provided */
|
||||
if (h->record_template) {
|
||||
@@ -1825,11 +1811,56 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
|
||||
if (switch_true(switch_channel_get_variable(member_channel, SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE))) {
|
||||
switch_channel_set_flag(member_channel, CF_BYPASS_MEDIA_AFTER_BRIDGE);
|
||||
}
|
||||
switch_ivr_uuid_bridge(h->member_session_uuid, switch_core_session_get_uuid(agent_session));
|
||||
switch_channel_wait_for_flag(agent_channel, CF_BRIDGED, SWITCH_TRUE, 1000, NULL);
|
||||
|
||||
if (switch_ivr_uuid_bridge(h->member_session_uuid, switch_core_session_get_uuid(agent_session)) != SWITCH_STATUS_SUCCESS) {
|
||||
bridged = 0;
|
||||
}
|
||||
|
||||
if (bridged && (switch_channel_wait_for_flag(agent_channel, CF_BRIDGED, SWITCH_TRUE, 3000, NULL) != SWITCH_STATUS_SUCCESS)) {
|
||||
bridged = 0;
|
||||
}
|
||||
|
||||
if (!bridged && !switch_channel_up(member_channel)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Failed to bridge, member \"%s\" <%s> has gone just before we called agent %s\n",
|
||||
h->member_cid_name, h->member_cid_number, h->agent_name);
|
||||
switch_channel_set_variable(agent_channel, "cc_agent_bridged", "false");
|
||||
switch_channel_set_variable(member_channel, "cc_agent_bridged", "false");
|
||||
|
||||
if ((o_announce = switch_channel_get_variable(member_channel, "cc_bridge_failed_outbound_announce"))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Playing bridge failed audio to agent %s, audio: %s\n", h->agent_name, o_announce);
|
||||
playback_array(agent_session, o_announce);
|
||||
}
|
||||
|
||||
if (!strcasecmp(h->agent_type, CC_AGENT_TYPE_CALLBACK)) {
|
||||
switch_channel_hangup(agent_channel, SWITCH_CAUSE_ORIGINATOR_CANCEL);
|
||||
}
|
||||
} else {
|
||||
bridged = 1;
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Member \"%s\" %s is bridged to agent %s\n",
|
||||
h->member_cid_name, h->member_cid_number, h->agent_name);
|
||||
switch_channel_set_variable(member_channel, "cc_agent_bridged", "true");
|
||||
switch_channel_set_variable(agent_channel, "cc_agent_bridged", "true");
|
||||
switch_channel_set_variable(member_channel, "cc_agent_uuid", agent_uuid);
|
||||
}
|
||||
|
||||
if (bridged) {
|
||||
/* for xml_cdr needs */
|
||||
switch_channel_set_variable(member_channel, "cc_agent", h->agent_name);
|
||||
switch_channel_set_variable_printf(member_channel, "cc_queue_answered_epoch", "%" SWITCH_TIME_T_FMT, local_epoch_time_now(NULL));
|
||||
/* Set UUID of the Agent channel */
|
||||
sql = switch_mprintf("UPDATE agents SET uuid = '%q', last_bridge_start = '%" SWITCH_TIME_T_FMT "', calls_answered = calls_answered + 1, no_answer_count = 0"
|
||||
" WHERE name = '%q' AND system = '%q'",
|
||||
agent_uuid, local_epoch_time_now(NULL),
|
||||
h->agent_name, h->agent_system);
|
||||
cc_execute_sql(NULL, sql, NULL);
|
||||
switch_safe_free(sql);
|
||||
/* Change the agents Status in the tiers */
|
||||
cc_tier_update("state", cc_tier_state2str(CC_TIER_STATE_ACTIVE_INBOUND), h->queue_name, h->agent_name);
|
||||
cc_agent_update("state", cc_agent_state2str(CC_AGENT_STATE_IN_A_QUEUE_CALL), h->agent_name);
|
||||
|
||||
}
|
||||
/* Wait until the agent hangup. This will quit also if the agent transfer the call */
|
||||
while(switch_channel_up(agent_channel) && globals.running) {
|
||||
while(bridged && switch_channel_up(agent_channel) && globals.running) {
|
||||
if (!strcasecmp(h->agent_type, CC_AGENT_TYPE_UUID_STANDBY)) {
|
||||
if (!switch_channel_test_flag(agent_channel, CF_BRIDGED)) {
|
||||
break;
|
||||
@@ -1839,7 +1870,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
|
||||
}
|
||||
tiers_state = CC_TIER_STATE_READY;
|
||||
|
||||
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CALLCENTER_EVENT) == SWITCH_STATUS_SUCCESS) {
|
||||
if (bridged && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CALLCENTER_EVENT) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_channel_event_set_data(agent_channel, event);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Queue", h->queue_name);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Action", "bridge-agent-end");
|
||||
@@ -1847,6 +1878,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent", h->agent_name);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-System", h->agent_system);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-UUID", agent_uuid);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-Bridged", bridged ? "true" : "false");
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Called-Time", "%" SWITCH_TIME_T_FMT, t_agent_called);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Answered-Time", "%" SWITCH_TIME_T_FMT, t_agent_answered);
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Member-Joined-Time", "%" SWITCH_TIME_T_FMT, t_member_called);
|
||||
@@ -1857,15 +1889,17 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-CID-Number", h->member_cid_number);
|
||||
switch_event_fire(&event);
|
||||
}
|
||||
/* for xml_cdr needs */
|
||||
switch_channel_set_variable_printf(member_channel, "cc_queue_terminated_epoch", "%" SWITCH_TIME_T_FMT, local_epoch_time_now(NULL));
|
||||
if (bridged) {
|
||||
/* for xml_cdr needs */
|
||||
switch_channel_set_variable_printf(member_channel, "cc_queue_terminated_epoch", "%" SWITCH_TIME_T_FMT, local_epoch_time_now(NULL));
|
||||
|
||||
/* Update Agents Items */
|
||||
/* Do not remove uuid of the agent if we are a standby agent */
|
||||
sql = switch_mprintf("UPDATE agents SET %s last_bridge_end = %" SWITCH_TIME_T_FMT ", talk_time = talk_time + (%" SWITCH_TIME_T_FMT "-last_bridge_start) WHERE name = '%q' AND system = '%q';"
|
||||
, (strcasecmp(h->agent_type, CC_AGENT_TYPE_UUID_STANDBY)?"uuid = '',":""), local_epoch_time_now(NULL), local_epoch_time_now(NULL), h->agent_name, h->agent_system);
|
||||
cc_execute_sql(NULL, sql, NULL);
|
||||
switch_safe_free(sql);
|
||||
/* Update Agents Items */
|
||||
/* Do not remove uuid of the agent if we are a standby agent */
|
||||
sql = switch_mprintf("UPDATE agents SET %s last_bridge_end = %" SWITCH_TIME_T_FMT ", talk_time = talk_time + (%" SWITCH_TIME_T_FMT "-last_bridge_start) WHERE name = '%q' AND system = '%q';"
|
||||
, (strcasecmp(h->agent_type, CC_AGENT_TYPE_UUID_STANDBY)?"uuid = '',":""), local_epoch_time_now(NULL), local_epoch_time_now(NULL), h->agent_name, h->agent_system);
|
||||
cc_execute_sql(NULL, sql, NULL);
|
||||
switch_safe_free(sql);
|
||||
}
|
||||
|
||||
/* Remove the member entry from the db (Could become optional to support latter processing) */
|
||||
sql = switch_mprintf("DELETE FROM members WHERE system = 'single_box' AND uuid = '%q'", h->member_uuid);
|
||||
|
||||
@@ -6900,6 +6900,38 @@ SWITCH_STANDARD_JSON_API(json_execute_function)
|
||||
return status;
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_API(event_channel_broadcast_api_function)
|
||||
{
|
||||
cJSON *jdata = NULL;
|
||||
const char *channel;
|
||||
|
||||
if (!cmd) {
|
||||
stream->write_function(stream, "-ERR parsing channel\n", SWITCH_VA_NONE);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (!(jdata = cJSON_Parse(cmd))) {
|
||||
stream->write_function(stream, "-ERR parsing json\n");
|
||||
}
|
||||
|
||||
|
||||
if (jdata) {
|
||||
if (!(channel = cJSON_GetObjectCstr(jdata, "eventChannel"))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NO EVENT CHANNEL SPECIFIED\n");
|
||||
} else {
|
||||
switch_event_channel_broadcast(channel, &jdata, modname, NO_EVENT_CHANNEL_ID);
|
||||
stream->write_function(stream, "+OK message sent\n", SWITCH_VA_NONE);
|
||||
}
|
||||
|
||||
if (jdata) {
|
||||
cJSON_Delete(jdata);
|
||||
}
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_JSON_API(json_api_function)
|
||||
{
|
||||
cJSON *data, *cmd, *arg, *reply;
|
||||
@@ -7090,6 +7122,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
|
||||
SWITCH_ADD_API(commands_api_interface, "db_cache", "Manage db cache", db_cache_function, "status");
|
||||
SWITCH_ADD_API(commands_api_interface, "domain_exists", "Check if a domain exists", domain_exists_function, "<domain>");
|
||||
SWITCH_ADD_API(commands_api_interface, "echo", "Echo", echo_function, "<data>");
|
||||
SWITCH_ADD_API(commands_api_interface, "event_channel_broadcast", "Broadcast", event_channel_broadcast_api_function, "<channel> <json>");
|
||||
SWITCH_ADD_API(commands_api_interface, "escape", "Escape a string", escape_function, "<data>");
|
||||
SWITCH_ADD_API(commands_api_interface, "eval", "eval (noop)", eval_function, "[uuid:<uuid> ]<expression>");
|
||||
SWITCH_ADD_API(commands_api_interface, "expand", "Execute an api with variable expansion", expand_function, "[uuid:<uuid> ]<cmd> <args>");
|
||||
|
||||
@@ -1564,6 +1564,8 @@ switch_status_t conference_api_sub_clear_vid_floor(conference_obj_t *conference,
|
||||
//conference_video_set_floor_holder(conference, NULL);
|
||||
switch_mutex_unlock(conference->mutex);
|
||||
|
||||
stream->write_function(stream, "OK floor Cleared\n", SWITCH_VA_NONE);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1624,20 +1626,22 @@ switch_status_t conference_api_sub_vid_logo_img(conference_member_t *member, swi
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!strcasecmp(text, "allclear")) {
|
||||
switch_channel_set_variable(member->channel, "video_logo_path", NULL);
|
||||
member->video_logo = NULL;
|
||||
} else if (!strcasecmp(text, "clear")) {
|
||||
member->video_logo = NULL;
|
||||
} else {
|
||||
member->video_logo = switch_core_strdup(member->pool, text);
|
||||
}
|
||||
if (!zstr(text)) {
|
||||
if (!strcasecmp(text, "allclear")) {
|
||||
switch_channel_set_variable(member->channel, "video_logo_path", NULL);
|
||||
member->video_logo = NULL;
|
||||
} else if (!strcasecmp(text, "clear")) {
|
||||
member->video_logo = NULL;
|
||||
} else {
|
||||
member->video_logo = switch_core_strdup(member->pool, text);
|
||||
}
|
||||
|
||||
conference_video_layer_set_logo(member, layer, text);
|
||||
conference_video_layer_set_logo(member, layer, text);
|
||||
}
|
||||
|
||||
end:
|
||||
|
||||
stream->write_function(stream, "+OK\n");
|
||||
stream->write_function(stream, "%s\n", member->video_logo ? member->video_logo : "_undef_");
|
||||
|
||||
conference_video_release_layer(&layer);
|
||||
|
||||
@@ -2506,11 +2510,6 @@ switch_status_t conference_api_sub_record(conference_obj_t *conference, switch_s
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
if (conference->conference_video_mode == CONF_VIDEO_MODE_PASSTHROUGH) {
|
||||
stream->write_function(stream, "-ERR Video Passthru enabled, recording not permitted.\n");
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (argv[3]) {
|
||||
|
||||
if (argv[3]) {
|
||||
@@ -2529,6 +2528,10 @@ switch_status_t conference_api_sub_record(conference_obj_t *conference, switch_s
|
||||
|
||||
if (id == 0 && conference->canvases[0]) id = 1;
|
||||
|
||||
if (id > conference->canvas_count) {
|
||||
id = 1;
|
||||
}
|
||||
|
||||
if (id > 0) {
|
||||
stream->write_function(stream, "Record file %s canvas %d\n", argv[2], id);
|
||||
} else {
|
||||
|
||||
@@ -707,6 +707,7 @@ void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, void *ob
|
||||
|
||||
if (switch_channel_test_flag(channel, CF_VIDEO) && !conference_utils_member_test_flag(member, MFLAG_ACK_VIDEO)) {
|
||||
conference_utils_member_set_flag_locked(member, MFLAG_ACK_VIDEO);
|
||||
switch_img_free(&member->avatar_png_img);
|
||||
conference_video_check_avatar(member, SWITCH_FALSE);
|
||||
switch_core_session_video_reinit(member->session);
|
||||
conference_video_set_floor_holder(member->conference, member, SWITCH_FALSE);
|
||||
@@ -1121,6 +1122,7 @@ void conference_loop_output(conference_member_t *member)
|
||||
const char *prefix = switch_channel_get_variable(channel, "conference_auto_outcall_prefix");
|
||||
const char *maxwait = switch_channel_get_variable(channel, "conference_auto_outcall_maxwait");
|
||||
const char *delimiter_val = switch_channel_get_variable(channel, "conference_auto_outcall_delimiter");
|
||||
const char *skip_member_beep = switch_channel_get_variable(channel, "conference_auto_outcall_skip_member_beep");
|
||||
int to = 60;
|
||||
int wait_sec = 2;
|
||||
int loops = 0;
|
||||
@@ -1184,7 +1186,8 @@ void conference_loop_output(conference_member_t *member)
|
||||
goto end;
|
||||
}
|
||||
|
||||
conference_member_play_file(member, "tone_stream://%(500,0,640)", 0, SWITCH_TRUE);
|
||||
if (!skip_member_beep || !switch_true(skip_member_beep))
|
||||
conference_member_play_file(member, "tone_stream://%(500,0,640)", 0, SWITCH_TRUE);
|
||||
}
|
||||
|
||||
if (!conference_utils_test_flag(member->conference, CFLAG_ANSWERED)) {
|
||||
|
||||
@@ -60,11 +60,6 @@ void conference_record_launch_thread(conference_obj_t *conference, char *path, i
|
||||
return;
|
||||
}
|
||||
|
||||
if (conference->conference_video_mode == CONF_VIDEO_MODE_PASSTHROUGH) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Video Passthru enabled, recording not permitted.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
rec->conference = conference;
|
||||
rec->path = switch_core_strdup(pool, path);
|
||||
rec->pool = pool;
|
||||
|
||||
@@ -926,7 +926,7 @@ switch_status_t conference_video_attach_video_layer(conference_member_t *member,
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if (switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY && !member->avatar_png_img) {
|
||||
if ((switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY || switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) && !member->avatar_png_img) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
@@ -1317,7 +1317,7 @@ void conference_video_write_canvas_image_to_codec_group(conference_obj_t *confer
|
||||
switch_core_session_request_video_refresh(imember->session);
|
||||
}
|
||||
|
||||
if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY) {
|
||||
if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) {
|
||||
switch_core_session_rwunlock(imember->session);
|
||||
continue;
|
||||
}
|
||||
@@ -1354,6 +1354,10 @@ video_layout_t *conference_video_find_best_layout(conference_obj_t *conference,
|
||||
}
|
||||
}
|
||||
|
||||
if (!lg) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (vlnode = lg->layouts; vlnode; vlnode = vlnode->next) {
|
||||
if (vlnode->vlayout->layers >= (int)count) {
|
||||
break;
|
||||
@@ -1599,6 +1603,71 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_write_thread_run(switch_thread_
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void conference_video_member_video_mute_banner(mcu_canvas_t *canvas, mcu_layer_t *layer, conference_member_t *member)
|
||||
{
|
||||
const char *text = "VIDEO MUTED";
|
||||
char *dup = NULL;
|
||||
const char *var, *tmp = NULL;
|
||||
const char *fg = "";
|
||||
const char *bg = "";
|
||||
const char *font_face = "";
|
||||
const char *font_scale = "";
|
||||
const char *font_scale_percentage = "";
|
||||
char *parsed = NULL;
|
||||
switch_event_t *params = NULL;
|
||||
switch_image_t *text_img;
|
||||
char text_str[256] = "";
|
||||
|
||||
if ((var = switch_channel_get_variable_dup(member->channel, "video_mute_banner", SWITCH_FALSE, -1))) {
|
||||
text = var;
|
||||
} else if (member->conference->video_mute_banner) {
|
||||
text = member->conference->video_mute_banner;
|
||||
}
|
||||
|
||||
if (*text == '{') {
|
||||
dup = strdup(text);
|
||||
text = dup;
|
||||
|
||||
if (switch_event_create_brackets((char *)text, '{', '}', ',', ¶ms, &parsed, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS || !parsed) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error!\n");
|
||||
} else {
|
||||
text = parsed;
|
||||
}
|
||||
}
|
||||
|
||||
if ((tmp = strchr(text, '}'))) {
|
||||
text = tmp + 1;
|
||||
}
|
||||
|
||||
if (params) {
|
||||
if ((var = switch_event_get_header(params, "fg"))) {
|
||||
fg = var;
|
||||
}
|
||||
|
||||
if ((var = switch_event_get_header(params, "bg"))) {
|
||||
bg = var;
|
||||
}
|
||||
|
||||
if ((var = switch_event_get_header(params, "font_face"))) {
|
||||
font_face = var;
|
||||
}
|
||||
|
||||
if ((var = switch_event_get_header(params, "font_scale"))) {
|
||||
font_scale = var;
|
||||
font_scale_percentage = "%";
|
||||
}
|
||||
}
|
||||
|
||||
switch_snprintf(text_str, sizeof(text_str), "%s:%s:%s:%s%s:%s", fg, bg, font_face, font_scale, font_scale_percentage, text);
|
||||
text_img = switch_img_write_text_img(layer->screen_w, layer->screen_h, SWITCH_TRUE, text_str);
|
||||
switch_img_patch(canvas->img, text_img, layer->x_pos, layer->y_pos);
|
||||
switch_img_free(&text_img);
|
||||
|
||||
if (params) switch_event_destroy(¶ms);
|
||||
|
||||
switch_safe_free(dup);
|
||||
}
|
||||
|
||||
void conference_video_check_recording(conference_obj_t *conference, mcu_canvas_t *canvas, switch_frame_t *frame)
|
||||
{
|
||||
conference_member_t *imember;
|
||||
@@ -1643,7 +1712,10 @@ void conference_video_check_avatar(conference_member_t *member, switch_bool_t fo
|
||||
canvas = conference_video_get_canvas_locked(member);
|
||||
|
||||
if (conference_utils_test_flag(member->conference, CFLAG_VIDEO_REQUIRED_FOR_CANVAS) &&
|
||||
(!switch_channel_test_flag(member->channel, CF_VIDEO_READY) || switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY)) {
|
||||
(!switch_channel_test_flag(member->channel, CF_VIDEO_READY) ||
|
||||
(switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY ||
|
||||
switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE))) {
|
||||
|
||||
if (canvas) {
|
||||
conference_video_release_canvas(&canvas);
|
||||
}
|
||||
@@ -1656,7 +1728,8 @@ void conference_video_check_avatar(conference_member_t *member, switch_bool_t fo
|
||||
|
||||
member->avatar_patched = 0;
|
||||
|
||||
if (!force && switch_channel_test_flag(member->channel, CF_VIDEO_READY) && switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY) {
|
||||
if (!force && switch_channel_test_flag(member->channel, CF_VIDEO_READY) &&
|
||||
switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY && switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_INACTIVE) {
|
||||
conference_utils_member_set_flag_locked(member, MFLAG_ACK_VIDEO);
|
||||
} else {
|
||||
if (member->conference->no_video_avatar) {
|
||||
@@ -1795,7 +1868,8 @@ switch_status_t conference_video_find_layer(conference_obj_t *conference, mcu_ca
|
||||
if (!layer &&
|
||||
(canvas->layers_used < canvas->total_layers ||
|
||||
(avatar_layers && !member->avatar_png_img) || conference_utils_member_test_flag(member, MFLAG_MOD)) &&
|
||||
(member->avatar_png_img || switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY)) {
|
||||
(member->avatar_png_img || (switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY &&
|
||||
switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_INACTIVE))) {
|
||||
/* find an empty layer */
|
||||
for (i = 0; i < canvas->total_layers; i++) {
|
||||
mcu_layer_t *xlayer = &canvas->layers[i];
|
||||
@@ -1856,6 +1930,10 @@ void conference_video_pop_next_image(conference_member_t *member, switch_image_t
|
||||
int size = 0;
|
||||
void *pop;
|
||||
|
||||
if (member->avatar_png_img && switch_channel_test_flag(member->channel, CF_VIDEO_READY) && conference_utils_member_test_flag(member, MFLAG_ACK_VIDEO)) {
|
||||
switch_img_free(&member->avatar_png_img);
|
||||
}
|
||||
|
||||
if (!member->avatar_png_img && switch_channel_test_flag(member->channel, CF_VIDEO_READY)) {
|
||||
do {
|
||||
if (switch_queue_trypop(member->video_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) {
|
||||
@@ -1868,7 +1946,11 @@ void conference_video_pop_next_image(conference_member_t *member, switch_image_t
|
||||
size = switch_queue_size(member->video_queue);
|
||||
} while(size > 0);
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_CAN_BE_SEEN) && member->video_layer_id > -1 && switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY) {
|
||||
if (conference_utils_member_test_flag(member, MFLAG_CAN_BE_SEEN) &&
|
||||
member->video_layer_id > -1 &&
|
||||
switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY &&
|
||||
switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_INACTIVE
|
||||
) {
|
||||
if (img) {
|
||||
member->good_img++;
|
||||
if ((member->good_img % (int)(member->conference->video_fps.fps * 10)) == 0) {
|
||||
@@ -2227,7 +2309,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
|
||||
if (imember->channel && switch_channel_ready(imember->channel) && switch_channel_test_flag(imember->channel, CF_VIDEO_READY) &&
|
||||
!conference_utils_member_test_flag(imember, MFLAG_SECOND_SCREEN) &&
|
||||
conference_utils_member_test_flag(imember, MFLAG_RUNNING) && (!no_muted || seen) && (!no_av || (no_av && !imember->avatar_png_img))
|
||||
&& imember->canvas_id == canvas->canvas_id && imember->video_media_flow != SWITCH_MEDIA_FLOW_SENDONLY) {
|
||||
&& imember->canvas_id == canvas->canvas_id && imember->video_media_flow != SWITCH_MEDIA_FLOW_SENDONLY && imember->video_media_flow != SWITCH_MEDIA_FLOW_INACTIVE) {
|
||||
video_count++;
|
||||
}
|
||||
|
||||
@@ -2470,7 +2552,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
|
||||
switch_img_free(&img);
|
||||
}
|
||||
|
||||
if (!layer && (!conference_utils_test_flag(imember->conference, CFLAG_VIDEO_REQUIRED_FOR_CANVAS) || ((switch_channel_test_flag(imember->channel, CF_VIDEO_READY) && switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY)))) {
|
||||
if (!layer && (!conference_utils_test_flag(imember->conference, CFLAG_VIDEO_REQUIRED_FOR_CANVAS) || ((switch_channel_test_flag(imember->channel, CF_VIDEO_READY) && switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY && switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_INACTIVE)))) {
|
||||
if (conference_video_find_layer(conference, canvas, imember, &layer) == SWITCH_STATUS_SUCCESS) {
|
||||
imember->layer_timeout = 0;
|
||||
} else {
|
||||
@@ -2492,10 +2574,9 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
|
||||
// switch_img_free(&layer->cur_img);
|
||||
//}
|
||||
|
||||
if (conference_utils_member_test_flag(imember, MFLAG_CAN_BE_SEEN) || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY || conference_utils_test_flag(imember->conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS)) {
|
||||
if (conference_utils_member_test_flag(imember, MFLAG_CAN_BE_SEEN) || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE || conference_utils_test_flag(imember->conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS)) {
|
||||
layer->mute_patched = 0;
|
||||
} else {
|
||||
switch_image_t *tmp;
|
||||
|
||||
if (img && img != imember->avatar_png_img) {
|
||||
switch_img_free(&img);
|
||||
@@ -2523,10 +2604,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
|
||||
}
|
||||
|
||||
|
||||
tmp = switch_img_write_text_img(layer->screen_w, layer->screen_h, SWITCH_TRUE, "VIDEO MUTED");
|
||||
switch_img_patch(canvas->img, tmp, layer->x_pos, layer->y_pos);
|
||||
switch_img_free(&tmp);
|
||||
|
||||
conference_video_member_video_mute_banner(canvas, layer, imember);
|
||||
layer->mute_patched = 1;
|
||||
}
|
||||
}
|
||||
@@ -2613,7 +2691,9 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
|
||||
if (total > 0 &&
|
||||
(!conference_utils_test_flag(imember->conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS) ||
|
||||
conference_utils_member_test_flag(imember, MFLAG_CAN_BE_SEEN)) &&
|
||||
imember->session && switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY) {
|
||||
imember->session && switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY &&
|
||||
imember->session && switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_INACTIVE) {
|
||||
|
||||
total--;
|
||||
}
|
||||
|
||||
@@ -2637,7 +2717,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
|
||||
}
|
||||
}
|
||||
|
||||
if (imember->session && switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY) {
|
||||
if (imember->session && switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_SENDONLY && switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) != SWITCH_MEDIA_FLOW_INACTIVE) {
|
||||
conference_video_pop_next_image(imember, &imember->pcanvas_img);
|
||||
}
|
||||
|
||||
@@ -2683,7 +2763,8 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
|
||||
|
||||
if (!imember->rec &&
|
||||
(!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO) || !imember->canvas ||
|
||||
(switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY) ||
|
||||
(switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY ||
|
||||
switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) ||
|
||||
(switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS))) {
|
||||
continue;
|
||||
}
|
||||
@@ -2717,7 +2798,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
|
||||
switch_image_t *use_img = NULL;
|
||||
|
||||
if (!omember->session || !switch_channel_test_flag(omember->channel, CF_VIDEO_READY) ||
|
||||
switch_core_session_media_flow(omember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY) {
|
||||
switch_core_session_media_flow(omember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY || switch_core_session_media_flow(omember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2775,11 +2856,8 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
|
||||
layer->mute_patched = 0;
|
||||
} else if (!conference_utils_test_flag(imember->conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS)) {
|
||||
if (!layer->mute_patched) {
|
||||
switch_image_t *tmp;
|
||||
conference_video_scale_and_patch(layer, omember->video_mute_img ? omember->video_mute_img : omember->pcanvas_img, SWITCH_FALSE);
|
||||
tmp = switch_img_write_text_img(layer->screen_w, layer->screen_h, SWITCH_TRUE, "VIDEO MUTED");
|
||||
switch_img_patch(imember->canvas->img, tmp, layer->x_pos, layer->y_pos);
|
||||
switch_img_free(&tmp);
|
||||
conference_video_member_video_mute_banner(imember->canvas, layer, imember);
|
||||
layer->mute_patched = 1;
|
||||
}
|
||||
|
||||
@@ -3016,7 +3094,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr
|
||||
switch_core_session_request_video_refresh(imember->session);
|
||||
}
|
||||
|
||||
if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY) {
|
||||
if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) {
|
||||
switch_core_session_rwunlock(imember->session);
|
||||
continue;
|
||||
}
|
||||
@@ -3365,7 +3443,7 @@ void *SWITCH_THREAD_FUNC conference_video_super_muxing_thread_run(switch_thread_
|
||||
switch_core_session_request_video_refresh(imember->session);
|
||||
}
|
||||
|
||||
if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY) {
|
||||
if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) {
|
||||
switch_core_session_rwunlock(imember->session);
|
||||
continue;
|
||||
}
|
||||
@@ -3450,7 +3528,7 @@ void conference_video_find_floor(conference_member_t *member, switch_bool_t ente
|
||||
continue;
|
||||
}
|
||||
|
||||
if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY && !imember->avatar_png_img) {
|
||||
if ((switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) && !imember->avatar_png_img) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -3515,7 +3593,7 @@ void conference_video_set_floor_holder(conference_obj_t *conference, conference_
|
||||
return;
|
||||
}
|
||||
|
||||
if (member && switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY && !member->avatar_png_img) {
|
||||
if (member && (switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY || switch_core_session_media_flow(member->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) && !member->avatar_png_img) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3740,7 +3818,7 @@ switch_status_t conference_video_thread_callback(switch_core_session_t *session,
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY) {
|
||||
if (switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_SENDONLY || switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) {
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -3789,6 +3867,7 @@ switch_status_t conference_video_thread_callback(switch_core_session_t *session,
|
||||
if (switch_queue_trypush(member->video_queue, img_copy) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_img_free(&img_copy);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
switch_thread_rwlock_unlock(member->conference->rwlock);
|
||||
|
||||
@@ -691,35 +691,6 @@ void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *ob
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Close Unused Handles */
|
||||
if (conference->fnode) {
|
||||
conference_file_node_t *fnode, *cur;
|
||||
switch_memory_pool_t *pool;
|
||||
|
||||
fnode = conference->fnode;
|
||||
while (fnode) {
|
||||
cur = fnode;
|
||||
fnode = fnode->next;
|
||||
|
||||
if (cur->type != NODE_TYPE_SPEECH) {
|
||||
conference_file_close(conference, cur);
|
||||
}
|
||||
|
||||
pool = cur->pool;
|
||||
switch_core_destroy_memory_pool(&pool);
|
||||
}
|
||||
conference->fnode = NULL;
|
||||
}
|
||||
|
||||
if (conference->async_fnode) {
|
||||
switch_memory_pool_t *pool;
|
||||
conference_file_close(conference, conference->async_fnode);
|
||||
pool = conference->async_fnode->pool;
|
||||
conference->async_fnode = NULL;
|
||||
switch_core_destroy_memory_pool(&pool);
|
||||
}
|
||||
|
||||
switch_mutex_lock(conference->member_mutex);
|
||||
for (imember = conference->members; imember; imember = imember->next) {
|
||||
switch_channel_t *channel;
|
||||
@@ -768,7 +739,6 @@ void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *ob
|
||||
}
|
||||
switch_mutex_unlock(conference_globals.hash_mutex);
|
||||
|
||||
|
||||
conference_utils_clear_flag(conference, CFLAG_VIDEO_MUXING);
|
||||
|
||||
for (x = 0; x <= conference->canvas_count; x++) {
|
||||
@@ -779,6 +749,34 @@ void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *ob
|
||||
}
|
||||
}
|
||||
|
||||
/* Close Unused Handles */
|
||||
if (conference->fnode) {
|
||||
conference_file_node_t *fnode, *cur;
|
||||
switch_memory_pool_t *pool;
|
||||
|
||||
fnode = conference->fnode;
|
||||
while (fnode) {
|
||||
cur = fnode;
|
||||
fnode = fnode->next;
|
||||
|
||||
if (cur->type != NODE_TYPE_SPEECH) {
|
||||
conference_file_close(conference, cur);
|
||||
}
|
||||
|
||||
pool = cur->pool;
|
||||
switch_core_destroy_memory_pool(&pool);
|
||||
}
|
||||
conference->fnode = NULL;
|
||||
}
|
||||
|
||||
if (conference->async_fnode) {
|
||||
switch_memory_pool_t *pool;
|
||||
conference_file_close(conference, conference->async_fnode);
|
||||
pool = conference->async_fnode->pool;
|
||||
conference->async_fnode = NULL;
|
||||
switch_core_destroy_memory_pool(&pool);
|
||||
}
|
||||
|
||||
/* Wait till everybody is out */
|
||||
conference_utils_clear_flag_locked(conference, CFLAG_RUNNING);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write Lock ON\n");
|
||||
@@ -2252,7 +2250,7 @@ SWITCH_STANDARD_APP(conference_function)
|
||||
|
||||
if (conference) {
|
||||
switch_mutex_lock(conference->mutex);
|
||||
if (conference_utils_test_flag(conference, CFLAG_DYNAMIC) && conference->count == 0) {
|
||||
if (conference_utils_test_flag(conference, CFLAG_DYNAMIC) && conference->count == 0 && conference->count_ghosts == 0) {
|
||||
conference_utils_set_flag_locked(conference, CFLAG_DESTRUCT);
|
||||
}
|
||||
switch_mutex_unlock(conference->mutex);
|
||||
@@ -2401,6 +2399,7 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co
|
||||
char *video_letterbox_bgcolor = NULL;
|
||||
char *video_codec_bandwidth = NULL;
|
||||
char *no_video_avatar = NULL;
|
||||
char *video_mute_banner = NULL;
|
||||
conference_video_mode_t conference_video_mode = CONF_VIDEO_MODE_PASSTHROUGH;
|
||||
int conference_video_quality = 1;
|
||||
int auto_kps_debounce = 30000;
|
||||
@@ -2588,6 +2587,8 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co
|
||||
video_codec_bandwidth = val;
|
||||
} else if (!strcasecmp(var, "video-no-video-avatar") && !zstr(val)) {
|
||||
no_video_avatar = val;
|
||||
} else if (!strcasecmp(var, "video-mute-banner") && !zstr(val)) {
|
||||
video_mute_banner = val;
|
||||
} else if (!strcasecmp(var, "exit-sound") && !zstr(val)) {
|
||||
exit_sound = val;
|
||||
} else if (!strcasecmp(var, "alone-sound") && !zstr(val)) {
|
||||
@@ -2760,10 +2761,10 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co
|
||||
}
|
||||
}
|
||||
|
||||
if (scale_h264_canvas_width < 320 || scale_h264_canvas_width < 180) {
|
||||
if (scale_h264_canvas_width < 320 || scale_h264_canvas_height < 180) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid scale-h264-canvas-size, falling back to 320x180\n");
|
||||
scale_h264_canvas_width = 320;
|
||||
scale_h264_canvas_width = 180;
|
||||
scale_h264_canvas_height = 180;
|
||||
}
|
||||
} else if (!strcasecmp(var, "scale-h264-canvas-fps-divisor") && !zstr(val)) {
|
||||
scale_h264_canvas_fps_divisor = atoi(val);
|
||||
@@ -2889,6 +2890,10 @@ conference_obj_t *conference_new(char *name, conference_xml_cfg_t cfg, switch_co
|
||||
video_letterbox_bgcolor = "#000000";
|
||||
}
|
||||
|
||||
if (video_mute_banner) {
|
||||
conference->video_mute_banner = switch_core_strdup(conference->pool, video_mute_banner);
|
||||
}
|
||||
|
||||
if (no_video_avatar) {
|
||||
conference->no_video_avatar = switch_core_strdup(conference->pool, no_video_avatar);
|
||||
}
|
||||
|
||||
@@ -564,6 +564,7 @@ typedef struct conference_obj {
|
||||
char *video_border_color;
|
||||
char *video_super_canvas_bgcolor;
|
||||
char *video_letterbox_bgcolor;
|
||||
char *video_mute_banner;
|
||||
char *no_video_avatar;
|
||||
conference_video_mode_t conference_video_mode;
|
||||
int video_quality;
|
||||
|
||||
@@ -720,7 +720,7 @@ static switch_status_t video_thread_callback(switch_core_session_t *session, swi
|
||||
switch_assert(context->rawImage->width * 3 == context->rawImage->widthStep);
|
||||
}
|
||||
|
||||
switch_img_to_raw(frame->img, context->rawImage->imageData, context->rawImage->widthStep * context->h, SWITCH_IMG_FMT_RGB24);
|
||||
switch_img_to_raw(frame->img, context->rawImage->imageData, context->rawImage->widthStep, SWITCH_IMG_FMT_RGB24);
|
||||
detectAndDraw(context);
|
||||
|
||||
if (context->detected.simo_count > 20) {
|
||||
@@ -1167,7 +1167,7 @@ SWITCH_STANDARD_APP(cv_bug_start_function)
|
||||
int x, n;
|
||||
char *argv[25] = { 0 };
|
||||
int argc;
|
||||
switch_media_bug_flag_t flags = SMBF_READ_VIDEO_PING;
|
||||
switch_media_bug_flag_t flags = SMBF_READ_VIDEO_PING | SMBF_READ_VIDEO_PATCH;
|
||||
const char *function = "mod_cv";
|
||||
|
||||
if ((bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_cv_bug_"))) {
|
||||
@@ -1228,7 +1228,7 @@ SWITCH_STANDARD_API(cv_bug_api_function)
|
||||
char *nested_cascade_path = NULL;
|
||||
char *lbuf = NULL;
|
||||
int x, n, i;
|
||||
switch_media_bug_flag_t flags = SMBF_READ_VIDEO_PING;
|
||||
switch_media_bug_flag_t flags = SMBF_READ_VIDEO_PING | SMBF_READ_VIDEO_PATCH;
|
||||
const char *function = "mod_cv";
|
||||
|
||||
if (zstr(cmd)) {
|
||||
|
||||
@@ -4356,6 +4356,62 @@ SWITCH_STANDARD_APP(wait_for_silence_function)
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Usage: %s\n", WAIT_FOR_SILENCE_SYNTAX);
|
||||
}
|
||||
|
||||
#define DETECT_AUDIO_SYNTAX "<threshold> <audio_hits> <timeout_ms> [<file>]"
|
||||
SWITCH_STANDARD_APP(detect_audio_function)
|
||||
{
|
||||
char *argv[5] = { 0 };
|
||||
uint32_t thresh, audio_hits, timeout_ms = 0;
|
||||
int argc;
|
||||
char *lbuf = NULL;
|
||||
|
||||
if (!zstr(data) && (lbuf = switch_core_session_strdup(session, data))
|
||||
&& (argc = switch_separate_string(lbuf, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) >= 3) {
|
||||
thresh = atoi(argv[0]);
|
||||
audio_hits = atoi(argv[1]);
|
||||
timeout_ms = atoi(argv[2]);
|
||||
|
||||
if (argv[3]) {
|
||||
timeout_ms = switch_atoui(argv[3]);
|
||||
}
|
||||
|
||||
if (thresh > 0 && audio_hits > 0) {
|
||||
switch_ivr_detect_audio(session, thresh, audio_hits, timeout_ms, argv[4]);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Usage: %s\n", DETECT_AUDIO_SYNTAX);
|
||||
}
|
||||
|
||||
#define DETECT_SILENCE_SYNTAX "<threshold> <silence_hits> <timeout_ms> [<file>]"
|
||||
SWITCH_STANDARD_APP(detect_silence_function)
|
||||
{
|
||||
char *argv[5] = { 0 };
|
||||
uint32_t thresh, silence_hits, timeout_ms = 0;
|
||||
int argc;
|
||||
char *lbuf = NULL;
|
||||
|
||||
if (!zstr(data) && (lbuf = switch_core_session_strdup(session, data))
|
||||
&& (argc = switch_separate_string(lbuf, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) >= 3) {
|
||||
thresh = atoi(argv[0]);
|
||||
silence_hits = atoi(argv[1]);
|
||||
timeout_ms = atoi(argv[2]);
|
||||
|
||||
if (argv[3]) {
|
||||
timeout_ms = switch_atoui(argv[3]);
|
||||
}
|
||||
|
||||
if (thresh > 0 && silence_hits > 0) {
|
||||
switch_ivr_detect_silence(session, thresh, silence_hits, timeout_ms, argv[4]);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Usage: %s\n", DETECT_SILENCE_SYNTAX);
|
||||
}
|
||||
|
||||
static switch_status_t event_chat_send(switch_event_t *message_event)
|
||||
|
||||
{
|
||||
@@ -6270,6 +6326,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
|
||||
SAF_SUPPORT_NOMEDIA | SAF_ZOMBIE_EXEC);
|
||||
SWITCH_ADD_APP(app_interface, "say", "say", "say", say_function, SAY_SYNTAX, SAF_NONE);
|
||||
|
||||
SWITCH_ADD_APP(app_interface, "detect_audio", "detect_audio", "detect_audio", detect_audio_function, DETECT_AUDIO_SYNTAX,
|
||||
SAF_NONE);
|
||||
SWITCH_ADD_APP(app_interface, "detect_silence", "detect_silence", "detect_silence", detect_silence_function, DETECT_SILENCE_SYNTAX,
|
||||
SAF_NONE);
|
||||
SWITCH_ADD_APP(app_interface, "wait_for_silence", "wait_for_silence", "wait_for_silence", wait_for_silence_function, WAIT_FOR_SILENCE_SYNTAX,
|
||||
SAF_NONE);
|
||||
SWITCH_ADD_APP(app_interface, "session_loglevel", "session_loglevel", "session_loglevel", session_loglevel_function, SESSION_LOGLEVEL_SYNTAX,
|
||||
|
||||
@@ -141,8 +141,6 @@ static switch_status_t load_config(void)
|
||||
globals.nameserver[inameserver] = (char *) val;
|
||||
inameserver++;
|
||||
}
|
||||
} else if (!strcasecmp(var, "log-level-trace")) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2756,6 +2756,7 @@ SWITCH_STANDARD_APP(fifo_function)
|
||||
switch_strftime_nocheck(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm);
|
||||
switch_channel_set_variable(channel, "fifo_status", "WAITING");
|
||||
switch_channel_set_variable(channel, "fifo_timestamp", date);
|
||||
switch_channel_set_variable(channel, "fifo_push_timestamp", date);
|
||||
switch_channel_set_variable(channel, "fifo_serviced_uuid", NULL);
|
||||
|
||||
switch_channel_set_app_flag_key(FIFO_APP_KEY, channel, FIFO_APP_BRIDGE_TAG);
|
||||
|
||||
@@ -376,7 +376,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_hiredis_load)
|
||||
|
||||
SWITCH_ADD_LIMIT(limit_interface, "hiredis", hiredis_limit_incr, hiredis_limit_release, hiredis_limit_usage,
|
||||
hiredis_limit_reset, hiredis_limit_status, hiredis_limit_interval_reset);
|
||||
SWITCH_ADD_APP(app_interface, "hiredis_raw", "hiredis_raw", "hiredis_raw", raw_app, "", SAF_NONE);
|
||||
SWITCH_ADD_APP(app_interface, "hiredis_raw", "hiredis_raw", "hiredis_raw", raw_app, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
|
||||
SWITCH_ADD_API(api_interface, "hiredis_raw", "hiredis_raw", raw_api, "");
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
||||
@@ -1288,7 +1288,6 @@ static size_t file_callback(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
register unsigned int realsize = (unsigned int) (size * nmemb);
|
||||
client_t *client = data;
|
||||
char *zero = "\0";
|
||||
|
||||
client->bytes += realsize;
|
||||
|
||||
@@ -1299,7 +1298,6 @@ static size_t file_callback(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
}
|
||||
|
||||
switch_buffer_write(client->buffer, ptr, realsize);
|
||||
switch_buffer_write(client->buffer, zero, 1);
|
||||
|
||||
return realsize;
|
||||
}
|
||||
@@ -2313,6 +2311,9 @@ SWITCH_STANDARD_APP(httapi_function)
|
||||
const char *ct = switch_event_get_header(client->headers, "content-type");
|
||||
|
||||
if (switch_stristr("text/xml", ct)) {
|
||||
char *zero = "\0";
|
||||
switch_buffer_write(client->buffer, zero, 1);
|
||||
|
||||
status = parse_xml(client);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Received unsupported content-type %s\n", ct);
|
||||
@@ -2967,12 +2968,18 @@ static switch_status_t file_open(switch_file_handle_t *handle, const char *path,
|
||||
context->cache_file,
|
||||
handle->channels,
|
||||
handle->samplerate,
|
||||
SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL)) != SWITCH_STATUS_SUCCESS) {
|
||||
handle->flags, NULL)) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid cache file %s opening url %s Discarding file.\n", context->cache_file, path);
|
||||
unlink(context->cache_file);
|
||||
unlink(context->meta_file);
|
||||
return status;
|
||||
}
|
||||
|
||||
if (switch_test_flag(&context->fh, SWITCH_FILE_FLAG_VIDEO)) {
|
||||
switch_set_flag(handle, SWITCH_FILE_FLAG_VIDEO);
|
||||
} else {
|
||||
switch_set_flag(handle, SWITCH_FILE_FLAG_VIDEO);
|
||||
}
|
||||
}
|
||||
|
||||
handle->private_info = context;
|
||||
@@ -3057,6 +3064,20 @@ static switch_status_t http_file_file_close(switch_file_handle_t *handle)
|
||||
}
|
||||
|
||||
|
||||
static switch_status_t http_file_read_video(switch_file_handle_t *handle, switch_frame_t *frame, switch_video_read_flag_t flags)
|
||||
{
|
||||
http_file_context_t *context = handle->private_info;
|
||||
|
||||
return switch_core_file_read_video(&context->fh, frame, flags);
|
||||
}
|
||||
|
||||
static switch_status_t http_file_write_video(switch_file_handle_t *handle, switch_frame_t *frame)
|
||||
{
|
||||
http_file_context_t *context = handle->private_info;
|
||||
|
||||
return switch_core_file_write_video(&context->fh, frame);
|
||||
}
|
||||
|
||||
static switch_status_t http_file_write(switch_file_handle_t *handle, void *data, size_t *len)
|
||||
{
|
||||
http_file_context_t *context = handle->private_info;
|
||||
@@ -3121,6 +3142,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_httapi_load)
|
||||
http_file_interface->file_read = http_file_file_read;
|
||||
http_file_interface->file_write = http_file_write;
|
||||
http_file_interface->file_seek = http_file_file_seek;
|
||||
http_file_interface->file_read_video = http_file_read_video;
|
||||
http_file_interface->file_write_video = http_file_write_video;
|
||||
|
||||
https_file_supported_formats[0] = "https";
|
||||
|
||||
@@ -3132,6 +3155,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_httapi_load)
|
||||
https_file_interface->file_read = http_file_file_read;
|
||||
https_file_interface->file_write = http_file_write;
|
||||
https_file_interface->file_seek = http_file_file_seek;
|
||||
https_file_interface->file_read_video = http_file_read_video;
|
||||
https_file_interface->file_write_video = http_file_write_video;
|
||||
|
||||
switch_snprintf(globals.cache_path, sizeof(globals.cache_path), "%s%shttp_file_cache", SWITCH_GLOBAL_dirs.storage_dir, SWITCH_PATH_SEPARATOR);
|
||||
switch_dir_make_recursive(globals.cache_path, SWITCH_DEFAULT_DIR_PERMS, pool);
|
||||
|
||||
@@ -1740,6 +1740,12 @@ static switch_status_t http_cache_file_open(switch_file_handle_t *handle, const
|
||||
switch_clear_flag_locked(handle, SWITCH_FILE_NATIVE);
|
||||
}
|
||||
|
||||
if (switch_test_flag(&context->fh, SWITCH_FILE_FLAG_VIDEO)) {
|
||||
switch_set_flag_locked(handle, SWITCH_FILE_FLAG_VIDEO);
|
||||
} else {
|
||||
switch_clear_flag_locked(handle, SWITCH_FILE_FLAG_VIDEO);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -1791,6 +1797,30 @@ static switch_status_t http_file_write(switch_file_handle_t *handle, void *data,
|
||||
return switch_core_file_write(&context->fh, data, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read from HTTP video file
|
||||
* @param handle
|
||||
* @param frame
|
||||
* @return
|
||||
*/
|
||||
static switch_status_t http_file_read_video(switch_file_handle_t *handle, switch_frame_t *frame, switch_video_read_flag_t flags)
|
||||
{
|
||||
struct http_context *context = (struct http_context *)handle->private_info;
|
||||
return switch_core_file_read_video(&context->fh, frame, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write to HTTP video file
|
||||
* @param handle
|
||||
* @param frame
|
||||
* @return
|
||||
*/
|
||||
static switch_status_t http_file_write_video(switch_file_handle_t *handle, switch_frame_t *frame)
|
||||
{
|
||||
struct http_context *context = (struct http_context *)handle->private_info;
|
||||
return switch_core_file_write_video(&context->fh, frame);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close HTTP file
|
||||
* @param handle
|
||||
@@ -1851,6 +1881,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_http_cache_load)
|
||||
file_interface->file_close = http_file_close;
|
||||
file_interface->file_read = http_file_read;
|
||||
file_interface->file_write = http_file_write;
|
||||
file_interface->file_read_video = http_file_read_video;
|
||||
file_interface->file_write_video = http_file_write_video;
|
||||
|
||||
if (gcache.enable_file_formats) {
|
||||
file_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_FILE_INTERFACE);
|
||||
@@ -1860,6 +1892,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_http_cache_load)
|
||||
file_interface->file_close = http_file_close;
|
||||
file_interface->file_read = http_file_read;
|
||||
file_interface->file_write = http_file_write;
|
||||
file_interface->file_read_video = http_file_read_video;
|
||||
file_interface->file_write_video = http_file_write_video;
|
||||
|
||||
file_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_FILE_INTERFACE);
|
||||
file_interface->interface_name = modname;
|
||||
@@ -1868,6 +1902,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_http_cache_load)
|
||||
file_interface->file_close = http_file_close;
|
||||
file_interface->file_read = http_file_read;
|
||||
file_interface->file_write = http_file_write;
|
||||
file_interface->file_read_video = http_file_read_video;
|
||||
file_interface->file_write_video = http_file_write_video;
|
||||
}
|
||||
|
||||
/* create the queue from configuration */
|
||||
|
||||
@@ -251,23 +251,30 @@ SWITCH_STANDARD_API(mod_mongo_find_n_function)
|
||||
mongoc_cursor_t *cursor = mongoc_collection_find(col, query_options, 0, n, 0, query, fields, NULL);
|
||||
if (cursor && !mongoc_cursor_error(cursor, &error)) {
|
||||
/* get results from cursor */
|
||||
switch_stream_handle_t result_stream = { 0 };
|
||||
const bson_t *result;
|
||||
stream->write_function(stream, "-OK\n[");
|
||||
SWITCH_STANDARD_STREAM(result_stream);
|
||||
|
||||
if (mongoc_cursor_more(cursor) && mongoc_cursor_next(cursor, &result)) {
|
||||
char *json_result;
|
||||
json_result = bson_as_json(result, NULL);
|
||||
stream->write_function(stream, "%s", json_result);
|
||||
result_stream.write_function(&result_stream, "%s", json_result);
|
||||
bson_free(json_result);
|
||||
}
|
||||
while (mongoc_cursor_more(cursor) && mongoc_cursor_next(cursor, &result)) {
|
||||
char *json_result;
|
||||
json_result = bson_as_json(result, NULL);
|
||||
stream->write_function(stream, ",%s", json_result);
|
||||
result_stream.write_function(&result_stream, ",%s", json_result);
|
||||
bson_free(json_result);
|
||||
}
|
||||
stream->write_function(stream, "]\n");
|
||||
if (!mongoc_cursor_error(cursor, &error)) {
|
||||
stream->write_function(stream, "-OK\n[%s]", zstr((char *)result_stream.data) ? "" :(char *)result_stream.data);
|
||||
} else {
|
||||
stream->write_function(stream, "-ERR\nquery failed: %s", error.message);
|
||||
}
|
||||
switch_safe_free(result_stream.data);
|
||||
} else {
|
||||
stream->write_function(stream, "-ERR\nquery failed!\n");
|
||||
stream->write_function(stream, "-ERR\nquery failed: %s", error.message);
|
||||
}
|
||||
if (cursor) {
|
||||
mongoc_cursor_destroy(cursor);
|
||||
@@ -342,6 +349,8 @@ SWITCH_STANDARD_API(mod_mongo_find_one_function)
|
||||
json_result = bson_as_json(result, NULL);
|
||||
stream->write_function(stream, "-OK\n%s\n", json_result);
|
||||
bson_free(json_result);
|
||||
} else if (mongoc_cursor_error(cursor, &error)) {
|
||||
stream->write_function(stream, "-ERR\nquery failed: %s\n", error.message);
|
||||
} else {
|
||||
/* empty set */
|
||||
stream->write_function(stream, "-OK\n{}\n");
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
include $(top_srcdir)/build/modmake.rulesam
|
||||
MODNAME=mod_sms_flowroute
|
||||
|
||||
if HAVE_H2O
|
||||
|
||||
mod_LTLIBRARIES = mod_sms_flowroute.la
|
||||
mod_sms_flowroute_la_SOURCES = mod_sms_flowroute.c
|
||||
mod_sms_flowroute_la_CFLAGS = $(AM_CFLAGS) $(H2O_CFLAGS) $(BROTLIENC_CFLAGS) $(BROTLIDEC_CFLAGS)
|
||||
mod_sms_flowroute_la_LIBADD = $(switch_builddir)/libfreeswitch.la
|
||||
mod_sms_flowroute_la_LDFLAGS = -avoid-version -module -no-undefined -shared $(H2O_LIBS) $(BROTLIENC_LIBS) $(BROTLIDEC_LIBS) $(SWITCH_AM_LDFLAGS)
|
||||
|
||||
else
|
||||
install: error
|
||||
all: error
|
||||
error:
|
||||
$(error You must install libh2o and libh2o-dev to build this module)
|
||||
endif
|
||||
@@ -0,0 +1,30 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
For inbound, these are known leaks on per module load(not per message). These will likely require additions to libh2o to add a destroy function.
|
||||
|
||||
=================================================================
|
||||
==4164==ERROR: LeakSanitizer: detected memory leaks
|
||||
|
||||
Direct leak of 1104 byte(s) in 26 object(s) allocated from:
|
||||
#0 0x4c1e28 in __interceptor_malloc (/usr/local/freeswitch_sms_flowroute/bin/freeswitch+0x4c1e28)
|
||||
#1 0x7f868d71acbd in wcsdup /build/glibc-h_iKOs/glibc-2.19/wcsmbs/wcsdup.c:30
|
||||
|
||||
Direct leak of 184 byte(s) in 1 object(s) allocated from:
|
||||
#0 0x4c1e28 in __interceptor_malloc (/usr/local/freeswitch_sms_flowroute/bin/freeswitch+0x4c1e28)
|
||||
#1 0x7f867cdcbaee in h2o_mem_alloc /usr/src/h2o/include/h2o/memory.h:298
|
||||
#2 0x7f867cdcbaee in create_socket /usr/src/h2o/lib/common/socket/evloop.c.h:361
|
||||
|
||||
Indirect leak of 184 byte(s) in 1 object(s) allocated from:
|
||||
#0 0x4c1e28 in __interceptor_malloc (/usr/local/freeswitch_sms_flowroute/bin/freeswitch+0x4c1e28)
|
||||
#1 0x7f867cdcbaee in h2o_mem_alloc /usr/src/h2o/include/h2o/memory.h:298
|
||||
#2 0x7f867cdcbaee in create_socket /usr/src/h2o/lib/common/socket/evloop.c.h:361
|
||||
|
||||
Indirect leak of 88 byte(s) in 1 object(s) allocated from:
|
||||
#0 0x4c1e28 in __interceptor_malloc (/usr/local/freeswitch_sms_flowroute/bin/freeswitch+0x4c1e28)
|
||||
#1 0x7f867cdc9e12 in h2o_mem_alloc /usr/src/h2o/include/h2o/memory.h:298
|
||||
#2 0x7f867cdc9e12 in h2o_multithread_create_queue /usr/src/h2o/lib/common/multithread.c:106
|
||||
|
||||
SUMMARY: AddressSanitizer: 1560 byte(s) leaked in 29 allocation(s).
|
||||
@@ -0,0 +1,669 @@
|
||||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2005-2015, Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* William King <william.king@quentustech.com>
|
||||
*
|
||||
* mod_sms_flowroute.c SMS support for Flowroute SMS
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mod_sms_flowroute.h"
|
||||
|
||||
SWITCH_MODULE_LOAD_FUNCTION(mod_sms_flowroute_load);
|
||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sms_flowroute_shutdown);
|
||||
SWITCH_MODULE_DEFINITION(mod_sms_flowroute, mod_sms_flowroute_load, mod_sms_flowroute_shutdown, NULL);
|
||||
|
||||
mod_sms_flowroute_globals_t mod_sms_flowroute_globals;
|
||||
|
||||
static void on_accept(h2o_socket_t *listener, const char *error)
|
||||
{
|
||||
mod_sms_flowroute_profile_t *profile = listener->data;
|
||||
h2o_socket_t *sock = NULL;
|
||||
|
||||
if ( error != NULL ){
|
||||
return;
|
||||
}
|
||||
|
||||
if ((sock = h2o_evloop_socket_accept(listener)) == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
h2o_accept(profile->h2o_accept_context, sock);
|
||||
}
|
||||
|
||||
static void mod_sms_flowroute_profile_event_thread_on_timeout(h2o_timeout_entry_t *entry)
|
||||
{
|
||||
/* required to have this callback, to enable any per interval checks or cleanup. */
|
||||
}
|
||||
|
||||
static void *SWITCH_THREAD_FUNC mod_sms_flowroute_profile_event_thread(switch_thread_t *thread, void *obj)
|
||||
{
|
||||
mod_sms_flowroute_profile_t *profile = obj;
|
||||
struct sockaddr_in addr;
|
||||
int fd, reuseaddr_flag = 1, err = 0;
|
||||
h2o_socket_t *sock;
|
||||
h2o_timeout_t timeout = {0};
|
||||
h2o_timeout_entry_t timeout_entry = {0};
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
addr.sin_port = htons(profile->port);
|
||||
|
||||
err = (fd = socket(AF_INET, SOCK_STREAM, 0));
|
||||
if (err == -1 ) {
|
||||
fprintf(stderr, "unable to open socket [%d]\n", err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr_flag, sizeof(reuseaddr_flag));
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "Unable to set socket options [%d]\n", err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
|
||||
if (err != 0 ) {
|
||||
fprintf(stderr, "Unable to bind to socket [%d]\n", err);
|
||||
perror("bind");
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = listen(fd, SOMAXCONN);
|
||||
if ( err != 0) {
|
||||
fprintf(stderr, "Unable to listen on socket [%d]\n", err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sock = h2o_evloop_socket_create(profile->h2o_context.loop, fd, H2O_SOCKET_FLAG_DONT_READ);
|
||||
sock->data = (void *) profile;
|
||||
h2o_socket_read_start(sock, on_accept);
|
||||
|
||||
while ( profile->running ) {
|
||||
// switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Profile[%s] event thread loop\n", profile->name);
|
||||
h2o_timeout_init(profile->h2o_context.loop, &timeout, 1000); /* 1 second loop */
|
||||
timeout_entry.cb = mod_sms_flowroute_profile_event_thread_on_timeout;
|
||||
h2o_timeout_link(profile->h2o_context.loop, &timeout, &timeout_entry);
|
||||
|
||||
h2o_evloop_run(profile->h2o_context.loop);
|
||||
|
||||
h2o_timeout_unlink(&timeout_entry);
|
||||
h2o_timeout_dispose(profile->h2o_context.loop, &timeout);
|
||||
}
|
||||
h2o_socket_close(sock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch_status_t mod_sms_flowroute_profile_destroy(mod_sms_flowroute_profile_t **old_profile)
|
||||
{
|
||||
mod_sms_flowroute_profile_t *profile = NULL;
|
||||
switch_status_t status;
|
||||
|
||||
if ( !old_profile || !*old_profile ) {
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
profile = *old_profile;
|
||||
|
||||
switch_core_hash_delete(mod_sms_flowroute_globals.profile_hash, profile->name);
|
||||
|
||||
profile->running = 0;
|
||||
|
||||
if (profile->profile_thread) {
|
||||
switch_thread_join(&status, profile->profile_thread);
|
||||
}
|
||||
|
||||
switch_safe_free(profile->h2o_accept_context);
|
||||
switch_safe_free(profile->h2o_context.loop);
|
||||
h2o_context_dispose(&(profile->h2o_context));
|
||||
h2o_config_dispose(&(profile->h2o_globalconf));
|
||||
|
||||
switch_core_destroy_memory_pool(&(profile->pool));
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Profile[%s] destroyed\n", profile->name);
|
||||
|
||||
*old_profile = NULL;
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static int mod_sms_flowroute_profile_request_handler(h2o_handler_t *handler, h2o_req_t *request)
|
||||
{
|
||||
static h2o_generator_t generator = {NULL, NULL};
|
||||
h2o_iovec_t body = h2o_strdup(&request->pool, "ACCEPTED\n", SIZE_MAX);
|
||||
char *content = strndup(request->entity.base, request->entity.len);
|
||||
cJSON *parsed = NULL;
|
||||
switch_event_t *evt = NULL;
|
||||
|
||||
/* If there were a better way to cJSON_Parse, but with a str and len, this could remove a strndup */
|
||||
parsed = cJSON_Parse(content);
|
||||
|
||||
if ( !parsed ) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Invalid request received[%.*s]", (int) request->entity.len, request->entity.base);
|
||||
goto done;
|
||||
}
|
||||
|
||||
switch_event_create(&evt, SWITCH_EVENT_MESSAGE);
|
||||
switch_event_add_header_string(evt, SWITCH_STACK_BOTTOM, "to", cJSON_GetObjectCstr(parsed, "to"));
|
||||
switch_event_add_header_string(evt, SWITCH_STACK_BOTTOM, "body", cJSON_GetObjectCstr(parsed, "body"));
|
||||
switch_event_add_header_string(evt, SWITCH_STACK_BOTTOM, "from", cJSON_GetObjectCstr(parsed, "from"));
|
||||
switch_event_add_header_string(evt, SWITCH_STACK_BOTTOM, "record_id", cJSON_GetObjectCstr(parsed, "id"));
|
||||
switch_event_add_header_string(evt, SWITCH_STACK_BOTTOM, "context", "default");
|
||||
switch_event_add_header_string(evt, SWITCH_STACK_BOTTOM, "proto", "sms_flowroute");
|
||||
|
||||
switch_core_chat_send("GLOBAL_SMS", evt);
|
||||
switch_event_destroy(&evt);
|
||||
|
||||
request->res.status = 200;
|
||||
request->res.reason = "OK";
|
||||
h2o_add_header(&request->pool, &request->res.headers, H2O_TOKEN_CONTENT_TYPE, H2O_STRLIT("text/plain; charset=utf-8"));
|
||||
h2o_start_response(request, &generator);
|
||||
h2o_send(request, &body, 1, 1);
|
||||
|
||||
done:
|
||||
|
||||
cJSON_Delete(parsed);
|
||||
switch_safe_free(content);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch_status_t mod_sms_flowroute_profile_create(mod_sms_flowroute_profile_t **new_profile, char *name, int debug, int port,
|
||||
char *access_key, char *secret_key, char *host)
|
||||
{
|
||||
mod_sms_flowroute_profile_t *profile = NULL;
|
||||
switch_memory_pool_t *pool = NULL;
|
||||
switch_threadattr_t *thd_attr;
|
||||
char auth[256] = {0};
|
||||
unsigned int auth_size = 0;
|
||||
|
||||
switch_core_new_memory_pool(&pool);
|
||||
|
||||
profile = switch_core_alloc(pool, sizeof(mod_sms_flowroute_profile_t));
|
||||
|
||||
profile->pool = pool;
|
||||
profile->debug = debug;
|
||||
profile->running = 1;
|
||||
profile->name = name ? switch_core_strdup(profile->pool, name) : "default";
|
||||
profile->access_key = access_key ? switch_core_strdup(profile->pool, access_key) : "access_key";
|
||||
profile->secret_key = secret_key ? switch_core_strdup(profile->pool, secret_key) : "secret_key";
|
||||
profile->host = host ? switch_core_strdup(profile->pool, host) : "https://api.flowroute.com/v2/messages";
|
||||
profile->port = port ? port : 8000;
|
||||
|
||||
auth_size = snprintf(auth, 256, "%s:%s", profile->access_key, profile->secret_key);
|
||||
switch_b64_encode((unsigned char *)auth, auth_size, profile->auth_b64, 512);
|
||||
profile->auth_b64_size = strlen((const char *)profile->auth_b64);
|
||||
|
||||
if ( h2o_url_parse(profile->host, SIZE_MAX, &profile->url_parsed) != 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Profile[%s] error processing url[%s]\n", profile->name, profile->host);
|
||||
goto err;
|
||||
}
|
||||
|
||||
h2o_config_init(&(profile->h2o_globalconf));
|
||||
profile->h2o_hostconf = h2o_config_register_host(&(profile->h2o_globalconf), h2o_iovec_init(H2O_STRLIT("mod_sms_flowroute")), 2048);
|
||||
|
||||
/* Register h2o handlers here */
|
||||
profile->h2o_pathconf = h2o_config_register_path(profile->h2o_hostconf, "/", 0);
|
||||
profile->h2o_handler = h2o_create_handler(profile->h2o_pathconf, sizeof(h2o_handler_t));
|
||||
profile->h2o_handler->on_req = mod_sms_flowroute_profile_request_handler;
|
||||
|
||||
h2o_context_init(&(profile->h2o_context), h2o_evloop_create(), &(profile->h2o_globalconf));
|
||||
|
||||
profile->queue = h2o_multithread_create_queue(profile->h2o_context.loop);
|
||||
|
||||
profile->h2o_accept_context = calloc(1, sizeof(h2o_accept_ctx_t));
|
||||
profile->h2o_accept_context->ctx = &(profile->h2o_context);
|
||||
profile->h2o_accept_context->hosts = profile->h2o_globalconf.hosts;
|
||||
|
||||
switch_threadattr_create(&thd_attr, pool);
|
||||
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
|
||||
switch_thread_create(&(profile->profile_thread), thd_attr, mod_sms_flowroute_profile_event_thread, (void *) profile, pool);
|
||||
|
||||
switch_core_hash_insert(mod_sms_flowroute_globals.profile_hash, name, (void *) profile);
|
||||
*new_profile = profile;
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Profile[%s] created\n", profile->name);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
||||
err:
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
|
||||
static int on_body(h2o_http1client_t *client, const char *errstr)
|
||||
{
|
||||
h2o_http1client_ctx_t *ctx = client->ctx;
|
||||
mod_sms_flowroute_message_t *msg = H2O_STRUCT_FROM_MEMBER(mod_sms_flowroute_message_t, ctx, ctx);
|
||||
|
||||
if (errstr != NULL && errstr != h2o_http1client_error_is_eos) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SMS Send error on_body[%s]\n", errstr);
|
||||
goto err;
|
||||
}
|
||||
|
||||
fwrite(client->sock->input->bytes, 1, client->sock->input->size, stdout);
|
||||
h2o_buffer_consume(&client->sock->input, client->sock->input->size);
|
||||
|
||||
if (errstr == h2o_http1client_error_is_eos) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "SMS Send EOS\n");
|
||||
}
|
||||
|
||||
msg->status = 0;
|
||||
switch_mutex_unlock(msg->mutex);
|
||||
return 0;
|
||||
|
||||
err:
|
||||
msg->status = 3;
|
||||
switch_mutex_unlock(msg->mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static h2o_http1client_body_cb on_head(h2o_http1client_t *client, const char *errstr, int minor_version, int status, h2o_iovec_t msg_iovec,
|
||||
h2o_http1client_header_t *headers, size_t num_headers)
|
||||
{
|
||||
size_t i;
|
||||
switch_log_level_t loglevel = SWITCH_LOG_DEBUG;
|
||||
h2o_http1client_ctx_t *ctx = client->ctx;
|
||||
mod_sms_flowroute_message_t *msg = H2O_STRUCT_FROM_MEMBER(mod_sms_flowroute_message_t, ctx, ctx);
|
||||
|
||||
if (errstr != NULL && errstr != h2o_http1client_error_is_eos) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SMS Send error on_head[%s]\n", errstr);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ( status != 200 ) {
|
||||
loglevel = SWITCH_LOG_ERROR;
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, loglevel, "HTTP/1.%d %d %.*s\n", minor_version, status, (int)msg_iovec.len, msg_iovec.base);
|
||||
for (i = 0; i != num_headers; ++i) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, loglevel, "%.*s: %.*s\n",
|
||||
(int)headers[i].name_len, headers[i].name, (int)headers[i].value_len, headers[i].value);
|
||||
}
|
||||
|
||||
if (errstr == h2o_http1client_error_is_eos) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SMS Send error on_head no body received[%s]\n", errstr);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return on_body;
|
||||
|
||||
err:
|
||||
msg->status = 2;
|
||||
switch_mutex_unlock(msg->mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static h2o_http1client_head_cb on_connect(h2o_http1client_t *client, const char *errstr, h2o_iovec_t **reqbufs, size_t *reqbufcnt,
|
||||
int *method_is_head)
|
||||
{
|
||||
h2o_http1client_ctx_t *ctx = client->ctx;
|
||||
mod_sms_flowroute_message_t *msg = H2O_STRUCT_FROM_MEMBER(mod_sms_flowroute_message_t, ctx, ctx);
|
||||
|
||||
if (errstr != NULL) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SMS Send error on_connect[%s]\n", errstr);
|
||||
goto err;
|
||||
}
|
||||
|
||||
*reqbufs = (h2o_iovec_t *)client->data;
|
||||
*reqbufcnt = 1;
|
||||
*method_is_head = 0;
|
||||
|
||||
return on_head;
|
||||
|
||||
err:
|
||||
msg->status = 1;
|
||||
switch_mutex_unlock(msg->mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch_status_t mod_sms_flowroute_profile_send_message(mod_sms_flowroute_profile_t *profile, switch_event_t *event)
|
||||
{
|
||||
mod_sms_flowroute_message_t *msg = NULL;
|
||||
char *to = NULL, *from = NULL, *text = NULL;
|
||||
switch_status_t status = SWITCH_STATUS_GENERR;
|
||||
int wait_loops = 10; /* 10 seconds */
|
||||
cJSON *body = NULL;
|
||||
|
||||
msg = calloc(1, sizeof(mod_sms_flowroute_message_t));
|
||||
msg->req.base = calloc(1, 2048);
|
||||
msg->ctx.getaddr_receiver = &msg->getaddr_receiver;
|
||||
msg->ctx.io_timeout = &msg->io_timeout;
|
||||
msg->ctx.loop = profile->h2o_context.loop;
|
||||
msg->profile = profile;
|
||||
msg->status = -1;
|
||||
h2o_timeout_init(msg->ctx.loop, &msg->io_timeout, 5000); /* 5 seconds */
|
||||
h2o_multithread_register_receiver(profile->queue, msg->ctx.getaddr_receiver, h2o_hostinfo_getaddr_receiver);
|
||||
|
||||
msg->ctx.ssl_ctx = SSL_CTX_new(TLSv1_2_client_method());
|
||||
SSL_CTX_load_verify_locations(msg->ctx.ssl_ctx, NULL, "/etc/ssl/certs/");
|
||||
SSL_CTX_set_verify(msg->ctx.ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
|
||||
|
||||
switch_mutex_init(&msg->mutex, SWITCH_MUTEX_UNNESTED, profile->pool);
|
||||
switch_mutex_lock(msg->mutex);
|
||||
|
||||
body = cJSON_CreateObject();
|
||||
|
||||
to = switch_event_get_header(event, "to");
|
||||
if ( !to ) {
|
||||
to = switch_event_get_header(event, "destination_addr");
|
||||
}
|
||||
|
||||
from = switch_event_get_header(event, "from");
|
||||
if ( !from ) {
|
||||
from = switch_event_get_header(event, "source_addr");
|
||||
}
|
||||
|
||||
cJSON_AddItemToObject(body, "to", cJSON_CreateString(to));
|
||||
cJSON_AddItemToObject(body, "from", cJSON_CreateString(from));
|
||||
cJSON_AddItemToObject(body, "body", cJSON_CreateString((const char *) switch_event_get_body(event)));
|
||||
|
||||
text = cJSON_Print(body);
|
||||
cJSON_Delete(body);
|
||||
|
||||
msg->req.len = snprintf(msg->req.base, 2048, "POST %.*s HTTP/1.1\r\n"
|
||||
"Authorization: Basic %.*s\r\n"
|
||||
"Host: %.*s\r\n"
|
||||
"Accept: */*\r\n"
|
||||
"Content-Type: application/json\r\n"
|
||||
"Content-Length: %d\r\n"
|
||||
"\r\n%s",
|
||||
(int) profile->url_parsed.path.len, profile->url_parsed.path.base,
|
||||
profile->auth_b64_size, profile->auth_b64,
|
||||
(int) profile->url_parsed.authority.len, profile->url_parsed.authority.base,
|
||||
(int)strlen(text), text);
|
||||
|
||||
if ( profile->debug ) {
|
||||
char *msg_txt = NULL;
|
||||
switch_event_serialize(event, &msg_txt, SWITCH_FALSE);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Profile[%s] sending message from event\n%s\n", profile->name, msg_txt);
|
||||
switch_safe_free(msg_txt);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Profile[%s] sending message json:\n%s\n", profile->name, text);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "REQUEST\n\n%.*s\n\n", (int) msg->req.len, msg->req.base);
|
||||
}
|
||||
|
||||
h2o_http1client_connect(NULL, &msg->req, &(msg->ctx), profile->url_parsed.host, h2o_url_get_port(&profile->url_parsed), 1, on_connect);
|
||||
|
||||
do {
|
||||
switch_yield(1000000);
|
||||
wait_loops--;
|
||||
status = switch_mutex_trylock(msg->mutex);
|
||||
} while ( wait_loops > 0 && status != SWITCH_STATUS_SUCCESS);
|
||||
|
||||
if ( status != SWITCH_STATUS_SUCCESS ) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Profile[%s] send_message thread timed out on send\n", profile->name);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ( msg->status > 0 ) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Profile[%s] send_message resulted in failure status %d\n", profile->name, msg->status);
|
||||
goto err;
|
||||
}
|
||||
|
||||
h2o_timeout_dispose(msg->ctx.loop, msg->ctx.io_timeout);
|
||||
switch_mutex_destroy(msg->mutex);
|
||||
switch_safe_free(msg->req.base);
|
||||
switch_safe_free(msg);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
||||
err:
|
||||
if ( msg && msg->mutex ) {
|
||||
switch_mutex_destroy(msg->mutex);
|
||||
}
|
||||
h2o_timeout_dispose(msg->ctx.loop, msg->ctx.io_timeout);
|
||||
switch_safe_free(msg->req.base);
|
||||
switch_safe_free(msg);
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
switch_status_t mod_sms_flowroute_interface_chat_send(switch_event_t *event)
|
||||
{
|
||||
mod_sms_flowroute_profile_t *profile = NULL;
|
||||
char *profile_name = switch_event_get_header(event, "sms_flowroute_profile");
|
||||
|
||||
if (zstr(profile_name)) {
|
||||
profile_name = "default";
|
||||
}
|
||||
|
||||
profile = switch_core_hash_find(mod_sms_flowroute_globals.profile_hash, profile_name);
|
||||
|
||||
if (!profile) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "NO SUCH SMS_FLOWROUTE PROFILE[%s].", profile_name);
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
mod_sms_flowroute_profile_send_message(profile, event);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* static switch_status_t name (switch_event_t *message, const char *data) */
|
||||
SWITCH_STANDARD_CHAT_APP(mod_sms_flowroute_chat_send_function)
|
||||
{
|
||||
mod_sms_flowroute_profile_t *profile = NULL;
|
||||
|
||||
profile = switch_core_hash_find(mod_sms_flowroute_globals.profile_hash, data);
|
||||
|
||||
if ( !profile ) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "NO SUCH SMS_FLOWROUTE PROFILE[%s].", data);
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
mod_sms_flowroute_profile_send_message(profile, message);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* static void name (switch_core_session_t *session, const char *data) */
|
||||
SWITCH_STANDARD_APP(mod_sms_flowroute_app_send_function)
|
||||
{
|
||||
switch_event_header_t *chan_var = NULL;
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
switch_event_t *message = NULL;
|
||||
|
||||
if (switch_event_create(&message, SWITCH_EVENT_MESSAGE) != SWITCH_STATUS_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Copy over recognized channel vars. Then call the chat send function */
|
||||
/* Cycle through all of the channel headers, and ones with 'sms_flowroute_' prefix copy over without the prefix */
|
||||
for ( chan_var = switch_channel_variable_first(channel); chan_var; chan_var = chan_var->next) {
|
||||
if ( !strncmp(chan_var->name, "sms_flowroute_", 14) ) {
|
||||
switch_event_add_header_string(message, SWITCH_STACK_BOTTOM, chan_var->name + 14, chan_var->value);
|
||||
}
|
||||
}
|
||||
|
||||
/* Unlock the channel variables */
|
||||
switch_channel_variable_last(channel);
|
||||
mod_sms_flowroute_chat_send_function(message, data);
|
||||
return;
|
||||
}
|
||||
|
||||
/* static switch_status_t name (_In_opt_z_ const char *cmd, _In_opt_ switch_core_session_t *session, _In_ switch_stream_handle_t *stream) */
|
||||
SWITCH_STANDARD_API(mod_sms_flowroute_debug_api)
|
||||
{
|
||||
mod_sms_flowroute_globals.debug = switch_true(cmd);
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "debug is %s\n", (mod_sms_flowroute_globals.debug ? "on" : "off") );
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* static switch_status_t name (_In_opt_z_ const char *cmd, _In_opt_ switch_core_session_t *session, _In_ switch_stream_handle_t *stream) */
|
||||
SWITCH_STANDARD_API(mod_sms_flowroute_send_api)
|
||||
{
|
||||
mod_sms_flowroute_profile_t *profile = NULL;
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
switch_event_t *message = NULL;
|
||||
char *argv[1024] = { 0 };
|
||||
int argc = 0;
|
||||
char *cmd_dup = strdup(cmd);
|
||||
|
||||
if (!(argc = switch_separate_string(cmd_dup, '|', argv, (sizeof(argv) / sizeof(argv[0])))) || argc != 4 ) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid format. Must be | separated like: profile|destination|source|message\n");
|
||||
switch_goto_status(SWITCH_STATUS_GENERR, done);
|
||||
}
|
||||
|
||||
profile = switch_core_hash_find(mod_sms_flowroute_globals.profile_hash, argv[0]);
|
||||
|
||||
if ( !profile ) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "NO SUCH SMS_FLOWROUTE PROFILE[%s].", argv[0]);
|
||||
switch_goto_status(SWITCH_STATUS_GENERR, done);
|
||||
}
|
||||
|
||||
if (switch_event_create(&message, SWITCH_EVENT_MESSAGE) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_goto_status(SWITCH_STATUS_GENERR, done);
|
||||
}
|
||||
|
||||
switch_event_add_header_string(message, SWITCH_STACK_BOTTOM, "destination_addr", argv[1]);
|
||||
switch_event_add_header_string(message, SWITCH_STACK_BOTTOM, "source_addr", argv[2]);
|
||||
switch_event_set_body(message, argv[3]);
|
||||
|
||||
if (mod_sms_flowroute_profile_send_message(profile, message) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_goto_status(SWITCH_STATUS_GENERR, done);
|
||||
}
|
||||
|
||||
done:
|
||||
switch_safe_free(cmd_dup);
|
||||
return status;
|
||||
|
||||
}
|
||||
|
||||
switch_status_t mod_sms_flowroute_do_config()
|
||||
{
|
||||
char *conf = "sms_flowroute.conf";
|
||||
switch_xml_t xml, cfg, profiles, profile, params, param;
|
||||
|
||||
if (!(xml = switch_xml_open_cfg(conf, &cfg, NULL))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", conf);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ( (profiles = switch_xml_child(cfg, "profiles")) != NULL) {
|
||||
for (profile = switch_xml_child(profiles, "profile"); profile; profile = profile->next) {
|
||||
mod_sms_flowroute_profile_t *new_profile = NULL;
|
||||
int debug = 0, port = 0;
|
||||
char *access_key = NULL, *secret_key = NULL, *host = NULL;
|
||||
char *name = (char *)switch_xml_attr_soft(profile, "name");
|
||||
|
||||
// Load params
|
||||
if ( (params = switch_xml_child(profile, "params")) != NULL) {
|
||||
for (param = switch_xml_child(params, "param"); param; param = param->next) {
|
||||
char *var = (char *) switch_xml_attr_soft(param, "name");
|
||||
|
||||
if ( ! strncmp(var, "debug", 5) ) {
|
||||
debug = atoi(switch_xml_attr_soft(param, "value"));
|
||||
} else if ( ! strncmp(var, "port", 4) ) {
|
||||
port = atoi(switch_xml_attr_soft(param, "value"));
|
||||
} else if ( ! strncmp(var, "access-key", 10) ) {
|
||||
access_key = (char *) switch_xml_attr_soft(param, "value");
|
||||
} else if ( ! strncmp(var, "secret-key", 10) ) {
|
||||
secret_key = (char *) switch_xml_attr_soft(param, "value");
|
||||
} else if ( ! strncmp(var, "host", 4) ) {
|
||||
host = (char *) switch_xml_attr_soft(param, "value");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( mod_sms_flowroute_profile_create(&new_profile, name, debug, port, access_key, secret_key, host) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Created profile[%s]\n", name);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create profile[%s]\n", name);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Profiles config is missing\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
switch_xml_free(xml);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
||||
err:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Configuration failed\n");
|
||||
if(xml){
|
||||
switch_xml_free(xml);
|
||||
}
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
/* switch_status_t name (switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool) */
|
||||
SWITCH_MODULE_LOAD_FUNCTION(mod_sms_flowroute_load)
|
||||
{
|
||||
switch_api_interface_t *mod_sms_flowroute_api_interface;
|
||||
switch_chat_interface_t *mod_sms_flowroute_chat_interface;
|
||||
switch_chat_application_interface_t *mod_sms_flowroute_chat_app_interface;
|
||||
switch_application_interface_t *mod_sms_flowroute_app_interface;
|
||||
|
||||
/* connect my internal structure to the blank pointer passed to me */
|
||||
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
|
||||
|
||||
memset(&mod_sms_flowroute_globals, 0, sizeof(mod_sms_flowroute_globals_t));
|
||||
mod_sms_flowroute_globals.pool = pool;
|
||||
mod_sms_flowroute_globals.debug = 0;
|
||||
switch_core_hash_init(&(mod_sms_flowroute_globals.profile_hash));
|
||||
|
||||
if ( mod_sms_flowroute_do_config() != SWITCH_STATUS_SUCCESS ) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to load due to bad configs\n");
|
||||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
|
||||
/* SSL_load_error_strings();
|
||||
SSL_library_init();
|
||||
OpenSSL_add_all_algorithms();*/
|
||||
|
||||
|
||||
SWITCH_ADD_CHAT(mod_sms_flowroute_chat_interface, "sms_flowroute", mod_sms_flowroute_interface_chat_send);
|
||||
SWITCH_ADD_API(mod_sms_flowroute_api_interface, "sms_flowroute_send", "mod_sms_flowroute send", mod_sms_flowroute_send_api, NULL);
|
||||
SWITCH_ADD_API(mod_sms_flowroute_api_interface, "sms_flowroute_debug", "mod_sms_flowroute toggle debug", mod_sms_flowroute_debug_api, NULL);
|
||||
SWITCH_ADD_CHAT_APP(mod_sms_flowroute_chat_app_interface, "sms_flowroute_send", "send message to profile", "send message to profile",
|
||||
mod_sms_flowroute_chat_send_function, "", SCAF_NONE);
|
||||
SWITCH_ADD_APP(mod_sms_flowroute_app_interface, "sms_flowroute_send", NULL, NULL, mod_sms_flowroute_app_send_function,
|
||||
"sms_flowroute_send", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
|
||||
|
||||
/* indicate that the module should continue to be loaded */
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sms_flowroute_shutdown)
|
||||
{
|
||||
switch_hash_index_t *hi;
|
||||
mod_sms_flowroute_profile_t *profile = NULL;
|
||||
|
||||
while ((hi = switch_core_hash_first(mod_sms_flowroute_globals.profile_hash))) {
|
||||
switch_core_hash_this(hi, NULL, NULL, (void **)&profile);
|
||||
mod_sms_flowroute_profile_destroy(&profile);
|
||||
switch_safe_free(hi);
|
||||
}
|
||||
|
||||
switch_core_hash_destroy(&(mod_sms_flowroute_globals.profile_hash));
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
|
||||
*/
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Based on mod_skel by
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* William King <william.king@quentustech.com>
|
||||
*
|
||||
* mod_sms_flowroute.c SMS support for Flowroute SMS
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MOD_SMS_FLOWROUTE_H
|
||||
#define MOD_SMS_FLOWROUTE_H
|
||||
|
||||
#define H2O_USE_LIBUV 0
|
||||
#define H2O_USE_BROTLI 1
|
||||
|
||||
#include <switch.h>
|
||||
#include "h2o.h"
|
||||
#include "h2o/http1client.h"
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
int port;
|
||||
int debug;
|
||||
int running;
|
||||
char *host;
|
||||
|
||||
char *access_key;
|
||||
char *secret_key;
|
||||
|
||||
unsigned char auth_b64[512];
|
||||
int auth_b64_size;
|
||||
|
||||
h2o_url_t url_parsed;
|
||||
h2o_socketpool_t *sockpool;
|
||||
|
||||
h2o_globalconf_t h2o_globalconf;
|
||||
h2o_hostconf_t *h2o_hostconf;
|
||||
h2o_pathconf_t *h2o_pathconf;
|
||||
h2o_handler_t *h2o_handler;
|
||||
h2o_context_t h2o_context;
|
||||
h2o_accept_ctx_t *h2o_accept_context;
|
||||
h2o_multithread_queue_t *queue;
|
||||
|
||||
switch_thread_t *profile_thread;
|
||||
switch_memory_pool_t *pool;
|
||||
} mod_sms_flowroute_profile_t;
|
||||
|
||||
typedef struct {
|
||||
h2o_http1client_ctx_t ctx;
|
||||
mod_sms_flowroute_profile_t *profile;
|
||||
switch_mutex_t *mutex;
|
||||
h2o_iovec_t req;
|
||||
int status;
|
||||
h2o_multithread_receiver_t getaddr_receiver;
|
||||
h2o_timeout_t io_timeout;
|
||||
} mod_sms_flowroute_message_t;
|
||||
|
||||
typedef struct mod_sms_flowroute_globals_s {
|
||||
switch_memory_pool_t *pool;
|
||||
switch_hash_t *profile_hash;
|
||||
int debug;
|
||||
} mod_sms_flowroute_globals_t;
|
||||
|
||||
extern mod_sms_flowroute_globals_t mod_sms_flowroute_globals;
|
||||
|
||||
|
||||
#endif /* MOD_SMS_FLOWROUTE_H */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Copyright (C) 2005-2016, Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
@@ -849,17 +849,22 @@ static switch_bool_t callprogress_detector_process_buffer(switch_media_bug_t *bu
|
||||
tone_detector_process_buffer(detector, frame->data, frame->samples, &detected_tone);
|
||||
if (detected_tone) {
|
||||
switch_event_t *event = NULL;
|
||||
switch_channel_t *channel = NULL;
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
const char *execute_on_tone_var = switch_core_session_sprintf(session, "execute_on_spandsp_tone_detect_%s", detected_tone);
|
||||
const char *api_on_tone_var = switch_core_session_sprintf(session, "api_on_spandsp_tone_detect_%s", detected_tone);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "DETECTED TONE: %s\n", detected_tone);
|
||||
switch_channel_execute_on(channel, execute_on_tone_var);
|
||||
switch_channel_api_on(channel, api_on_tone_var);
|
||||
if (switch_event_create(&event, SWITCH_EVENT_DETECTED_TONE) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Detected-Tone", detected_tone);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(session));
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
if (channel) switch_channel_event_set_data(channel, event);
|
||||
|
||||
switch_channel_event_set_data(channel, event);
|
||||
switch_event_fire(&event);
|
||||
}
|
||||
if (switch_true(switch_channel_get_variable(channel, "spandsp_tone_detect_stop_on_tone"))) {
|
||||
/* all done */
|
||||
return SWITCH_FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -168,7 +168,7 @@ static switch_status_t process_event(switch_event_t *event)
|
||||
char *username[5] = { NULL };
|
||||
char *domain[5] = { NULL };
|
||||
char key[512];
|
||||
char *uuid = NULL, *my_uuid = NULL;
|
||||
char *my_uuid = NULL;
|
||||
int i;
|
||||
int found = 0;
|
||||
|
||||
@@ -203,7 +203,7 @@ static switch_status_t process_event(switch_event_t *event)
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (i = 0; i < 5; i++) {
|
||||
|
||||
if (username[i] && domain[i]) {
|
||||
spy_t *spy = NULL;
|
||||
@@ -215,7 +215,7 @@ static switch_status_t process_event(switch_event_t *event)
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
|
||||
my_uuid = switch_event_get_header(event, "Unique-ID");
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "UserSpy retrieved uuid %s for key %s, activating eavesdrop\n", uuid, key);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "UserSpy retrieved uuid %s for key %s, activating eavesdrop\n", my_uuid, key);
|
||||
|
||||
switch_channel_set_variable(channel, "spy_uuid", my_uuid);
|
||||
found++;
|
||||
|
||||
@@ -776,6 +776,7 @@ static switch_status_t find_non_loopback_bridge(switch_core_session_t *session,
|
||||
const char *a_uuid = NULL;
|
||||
switch_core_session_t *sp = NULL;
|
||||
|
||||
|
||||
*br_session = NULL;
|
||||
*br_uuid = NULL;
|
||||
|
||||
@@ -787,7 +788,9 @@ static switch_status_t find_non_loopback_bridge(switch_core_session_t *session,
|
||||
switch_channel_t *spchan = switch_core_session_get_channel(sp);
|
||||
|
||||
switch_channel_wait_for_state_or_greater(spchan, channel, CS_ROUTING);
|
||||
|
||||
|
||||
if (switch_false(switch_channel_get_variable(spchan, "loopback_bowout"))) break;
|
||||
|
||||
tech_pvt = switch_core_session_get_private(sp);
|
||||
|
||||
if (tech_pvt->other_channel) {
|
||||
|
||||
@@ -495,6 +495,30 @@
|
||||
really need to change this.
|
||||
-->
|
||||
<!-- <param name="renegotiate-codec-on-hold" value="true"/> -->
|
||||
<!-- Turn on proxy hold when proxy media and proxy mode are disabled
|
||||
By default it is not set
|
||||
-->
|
||||
<!-- <param name="proxy-hold" value="true"/> -->
|
||||
<!-- Choose the proxy notify events. Default is not set
|
||||
|
||||
all - every in-dialogs call sip notify will be proxy to the core pbx or b2bua
|
||||
<param name="proxy-notify-events" value="all"/>
|
||||
|
||||
<eventlist> - only event list sip notify will be proxy to the core pbx or b2bua
|
||||
this option provide users to specific events to be proxy through
|
||||
e.g talk,conference
|
||||
<param name="proxy-notify-events" value="talk,conference"/>
|
||||
-->
|
||||
<!-- Choose the proxy info content type. Default is not set.
|
||||
|
||||
all - every in-dialogs call sip infos will be proxy to the core pbx or b2bua
|
||||
<param name="proxy-info-content-types" value="all"/>
|
||||
|
||||
<info_content_type_list> - only content type list of sip info will be proxy to the core pbx
|
||||
or b2bua this option provide users to specific infos to be proxy through
|
||||
e.g application/pause-recording,application/resume-recording
|
||||
<param name="proxy-info-content-types" value="application/pause-recording,application/resume-recording"/>
|
||||
-->
|
||||
</settings>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
@@ -50,6 +50,7 @@ switch_endpoint_interface_t *sofia_endpoint_interface;
|
||||
|
||||
#define STRLEN 15
|
||||
|
||||
void mod_sofia_shutdown_cleanup();
|
||||
static switch_status_t sofia_on_init(switch_core_session_t *session);
|
||||
|
||||
static switch_status_t sofia_on_exchange_media(switch_core_session_t *session);
|
||||
@@ -1212,7 +1213,6 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
||||
case SWITCH_MESSAGE_INDICATE_MEDIA_RENEG:
|
||||
{
|
||||
if (msg->string_arg) {
|
||||
sofia_set_media_flag(tech_pvt->profile, SCMF_RENEG_ON_REINVITE);
|
||||
sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA);
|
||||
}
|
||||
|
||||
@@ -1378,25 +1378,21 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
||||
break;
|
||||
|
||||
case SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ:
|
||||
if (!switch_channel_test_flag(channel, CF_AVPF)) {
|
||||
//const char *ua = switch_channel_get_variable(tech_pvt->channel, "sip_user_agent");
|
||||
//if (ua && switch_stristr("polycom", ua)) {
|
||||
|
||||
//const char *pl = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<media_control>\n<vc_primitive>\n<to_encoder>\n<picture_fast_update>\n</picture_fast_update>\n</to_encoder>\n</vc_primitive>\n</media_control>";
|
||||
const char *pl = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<media_control><vc_primitive><to_encoder><picture_fast_update /></to_encoder></vc_primitive></media_control>\n";
|
||||
switch_time_t now = switch_micro_time_now();
|
||||
if (!switch_channel_test_flag(channel, CF_AVPF) && switch_true(switch_core_get_variable("sofia_send_info_vid_refresh"))) {
|
||||
const char *pl = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<media_control><vc_primitive><to_encoder><picture_fast_update /></to_encoder></vc_primitive></media_control>\n";
|
||||
switch_time_t now = switch_micro_time_now();
|
||||
|
||||
if (!tech_pvt->last_vid_info || (now - tech_pvt->last_vid_info) > 500000) {
|
||||
|
||||
if (!tech_pvt->last_vid_info || (now - tech_pvt->last_vid_info) > 500000) {
|
||||
|
||||
tech_pvt->last_vid_info = now;
|
||||
|
||||
if (!zstr(msg->string_arg)) {
|
||||
pl = msg->string_arg;
|
||||
}
|
||||
|
||||
nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("application/media_control+xml"), SIPTAG_PAYLOAD_STR(pl), TAG_END());
|
||||
tech_pvt->last_vid_info = now;
|
||||
|
||||
if (!zstr(msg->string_arg)) {
|
||||
pl = msg->string_arg;
|
||||
}
|
||||
//}
|
||||
|
||||
nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("application/media_control+xml"), SIPTAG_PAYLOAD_STR(pl), TAG_END());
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case SWITCH_MESSAGE_INDICATE_BROADCAST:
|
||||
@@ -5758,109 +5754,112 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
|
||||
switch_management_interface_t *management_interface;
|
||||
switch_application_interface_t *app_interface;
|
||||
struct in_addr in;
|
||||
switch_status_t status;
|
||||
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_NOTIFY_REFER) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_NOTIFY_REFER);
|
||||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_NOTIFY_WATCHED_HEADER) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_NOTIFY_WATCHED_HEADER);
|
||||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_UNREGISTER) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_UNREGISTER);
|
||||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_PROFILE_START) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_PROFILE_START);
|
||||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_REINVITE) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_REINVITE);
|
||||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_REPLACED) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_REPLACED);
|
||||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_TRANSFEROR) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_TRANSFEROR);
|
||||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_TRANSFEREE) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_TRANSFEREE);
|
||||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_ERROR) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_ERROR);
|
||||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_INTERCEPTED) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_INTERCEPTED);
|
||||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_GATEWAY_STATE) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_GATEWAY_STATE);
|
||||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_SIP_USER_STATE) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_SIP_USER_STATE);
|
||||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_GATEWAY_DEL) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_GATEWAY_DEL);
|
||||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_EXPIRE) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_EXPIRE);
|
||||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_REGISTER_ATTEMPT) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_REGISTER_ATTEMPT);
|
||||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_REGISTER_FAILURE) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_REGISTER_FAILURE);
|
||||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_PRE_REGISTER) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_PRE_REGISTER);
|
||||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_REGISTER) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_REGISTER);
|
||||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_GATEWAY_ADD) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_GATEWAY_ADD);
|
||||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
|
||||
memset(&mod_sofia_globals, 0, sizeof(mod_sofia_globals));
|
||||
mod_sofia_globals.destroy_private.destroy_nh = 1;
|
||||
mod_sofia_globals.destroy_private.is_static = 1;
|
||||
mod_sofia_globals.keep_private.is_static = 1;
|
||||
mod_sofia_globals.pool = pool;
|
||||
switch_mutex_init(&mod_sofia_globals.mutex, SWITCH_MUTEX_NESTED, mod_sofia_globals.pool);
|
||||
switch_core_hash_init(&mod_sofia_globals.profile_hash);
|
||||
switch_core_hash_init(&mod_sofia_globals.gateway_hash);
|
||||
switch_mutex_init(&mod_sofia_globals.hash_mutex, SWITCH_MUTEX_NESTED, mod_sofia_globals.pool);
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_NOTIFY_REFER) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_NOTIFY_REFER);
|
||||
switch_goto_status(SWITCH_STATUS_TERM, err);
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_NOTIFY_WATCHED_HEADER) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_NOTIFY_WATCHED_HEADER);
|
||||
switch_goto_status(SWITCH_STATUS_TERM, err);
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_UNREGISTER) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_UNREGISTER);
|
||||
switch_goto_status(SWITCH_STATUS_TERM, err);
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_PROFILE_START) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_PROFILE_START);
|
||||
switch_goto_status(SWITCH_STATUS_TERM, err);
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_REINVITE) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_REINVITE);
|
||||
switch_goto_status(SWITCH_STATUS_TERM, err);
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_REPLACED) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_REPLACED);
|
||||
switch_goto_status(SWITCH_STATUS_TERM, err);
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_TRANSFEROR) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_TRANSFEROR);
|
||||
switch_goto_status(SWITCH_STATUS_TERM, err);
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_TRANSFEREE) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_TRANSFEREE);
|
||||
switch_goto_status(SWITCH_STATUS_TERM, err);
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_ERROR) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_ERROR);
|
||||
switch_goto_status(SWITCH_STATUS_TERM, err);
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_INTERCEPTED) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_INTERCEPTED);
|
||||
switch_goto_status(SWITCH_STATUS_TERM, err);
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_GATEWAY_STATE) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_GATEWAY_STATE);
|
||||
switch_goto_status(SWITCH_STATUS_TERM, err);
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_SIP_USER_STATE) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_SIP_USER_STATE);
|
||||
switch_goto_status(SWITCH_STATUS_TERM, err);
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_GATEWAY_DEL) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_GATEWAY_DEL);
|
||||
switch_goto_status(SWITCH_STATUS_TERM, err);
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_EXPIRE) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_EXPIRE);
|
||||
switch_goto_status(SWITCH_STATUS_TERM, err);
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_REGISTER_ATTEMPT) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_REGISTER_ATTEMPT);
|
||||
switch_goto_status(SWITCH_STATUS_TERM, err);
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_REGISTER_FAILURE) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_REGISTER_FAILURE);
|
||||
switch_goto_status(SWITCH_STATUS_TERM, err);
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_PRE_REGISTER) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_PRE_REGISTER);
|
||||
switch_goto_status(SWITCH_STATUS_TERM, err);
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_REGISTER) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_REGISTER);
|
||||
switch_goto_status(SWITCH_STATUS_TERM, err);
|
||||
}
|
||||
|
||||
if (switch_event_reserve_subclass(MY_EVENT_GATEWAY_ADD) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", MY_EVENT_GATEWAY_ADD);
|
||||
switch_goto_status(SWITCH_STATUS_TERM, err);
|
||||
}
|
||||
|
||||
switch_find_local_ip(mod_sofia_globals.guess_ip, sizeof(mod_sofia_globals.guess_ip), &mod_sofia_globals.guess_mask, AF_INET);
|
||||
in.s_addr = mod_sofia_globals.guess_mask;
|
||||
@@ -5868,11 +5867,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
|
||||
|
||||
strcpy(mod_sofia_globals.hostname, switch_core_get_switchname());
|
||||
|
||||
|
||||
switch_core_hash_init(&mod_sofia_globals.profile_hash);
|
||||
switch_core_hash_init(&mod_sofia_globals.gateway_hash);
|
||||
switch_mutex_init(&mod_sofia_globals.hash_mutex, SWITCH_MUTEX_NESTED, mod_sofia_globals.pool);
|
||||
|
||||
switch_mutex_lock(mod_sofia_globals.mutex);
|
||||
mod_sofia_globals.running = 1;
|
||||
switch_mutex_unlock(mod_sofia_globals.mutex);
|
||||
@@ -5896,83 +5890,95 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
|
||||
|
||||
/* start one message thread */
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Starting initial message thread.\n");
|
||||
sofia_msg_thread_start(0);
|
||||
|
||||
|
||||
if (sofia_init() != SWITCH_STATUS_SUCCESS) {
|
||||
switch_goto_status(SWITCH_STATUS_GENERR, err);
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
if (config_sofia(SOFIA_CONFIG_LOAD, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||
mod_sofia_globals.running = 0;
|
||||
switch_goto_status(SWITCH_STATUS_GENERR, err);
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
sofia_msg_thread_start(0);
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Waiting for profiles to start\n");
|
||||
switch_yield(1500000);
|
||||
|
||||
if (switch_event_bind(modname, SWITCH_EVENT_CUSTOM, MULTICAST_EVENT, event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
|
||||
return SWITCH_STATUS_TERM;
|
||||
switch_goto_status(SWITCH_STATUS_TERM, err);
|
||||
}
|
||||
|
||||
if (switch_event_bind(modname, SWITCH_EVENT_CONFERENCE_DATA, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
|
||||
switch_goto_status(SWITCH_STATUS_GENERR, err);
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
if (switch_event_bind(modname, SWITCH_EVENT_PRESENCE_IN, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
|
||||
switch_goto_status(SWITCH_STATUS_GENERR, err);
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
if (switch_event_bind(modname, SWITCH_EVENT_PRESENCE_OUT, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
|
||||
switch_goto_status(SWITCH_STATUS_GENERR, err);
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
if (switch_event_bind(modname, SWITCH_EVENT_PRESENCE_PROBE, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
|
||||
switch_goto_status(SWITCH_STATUS_GENERR, err);
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
if (switch_event_bind(modname, SWITCH_EVENT_ROSTER, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
|
||||
switch_goto_status(SWITCH_STATUS_GENERR, err);
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
if (switch_event_bind(modname, SWITCH_EVENT_MESSAGE_WAITING, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
|
||||
switch_goto_status(SWITCH_STATUS_GENERR, err);
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
if (switch_event_bind(modname, SWITCH_EVENT_TRAP, SWITCH_EVENT_SUBCLASS_ANY, general_queue_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
|
||||
switch_goto_status(SWITCH_STATUS_GENERR, err);
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
if (switch_event_bind(modname, SWITCH_EVENT_NOTIFY, SWITCH_EVENT_SUBCLASS_ANY, general_queue_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
|
||||
switch_goto_status(SWITCH_STATUS_GENERR, err);
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
if (switch_event_bind(modname, SWITCH_EVENT_PHONE_FEATURE, SWITCH_EVENT_SUBCLASS_ANY, general_queue_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
|
||||
switch_goto_status(SWITCH_STATUS_GENERR, err);
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
if (switch_event_bind(modname, SWITCH_EVENT_SEND_MESSAGE, SWITCH_EVENT_SUBCLASS_ANY, general_queue_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
|
||||
switch_goto_status(SWITCH_STATUS_GENERR, err);
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
if (switch_event_bind(modname, SWITCH_EVENT_SEND_INFO, SWITCH_EVENT_SUBCLASS_ANY, general_queue_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
|
||||
switch_goto_status(SWITCH_STATUS_GENERR, err);
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
@@ -6035,10 +6041,14 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
|
||||
|
||||
/* indicate that the module should continue to be loaded */
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
||||
err:
|
||||
|
||||
mod_sofia_shutdown_cleanup();
|
||||
return status;
|
||||
}
|
||||
|
||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sofia_shutdown)
|
||||
{
|
||||
void mod_sofia_shutdown_cleanup() {
|
||||
int sanity = 0;
|
||||
int i;
|
||||
switch_status_t st;
|
||||
@@ -6077,8 +6087,10 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sofia_shutdown)
|
||||
switch_event_unbind_callback(general_queue_event_handler);
|
||||
switch_event_unbind_callback(event_handler);
|
||||
|
||||
switch_queue_push(mod_sofia_globals.presence_queue, NULL);
|
||||
switch_queue_interrupt_all(mod_sofia_globals.presence_queue);
|
||||
if (mod_sofia_globals.presence_queue) {
|
||||
switch_queue_push(mod_sofia_globals.presence_queue, NULL);
|
||||
switch_queue_interrupt_all(mod_sofia_globals.presence_queue);
|
||||
}
|
||||
|
||||
while (mod_sofia_globals.threads) {
|
||||
switch_cond_next();
|
||||
@@ -6087,13 +6099,11 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sofia_shutdown)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; mod_sofia_globals.msg_queue_thread[i]; i++) {
|
||||
switch_queue_push(mod_sofia_globals.msg_queue, NULL);
|
||||
switch_queue_interrupt_all(mod_sofia_globals.msg_queue);
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; mod_sofia_globals.msg_queue_thread[i]; i++) {
|
||||
switch_thread_join(&st, mod_sofia_globals.msg_queue_thread[i]);
|
||||
}
|
||||
@@ -6102,14 +6112,17 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sofia_shutdown)
|
||||
switch_thread_join(&st, mod_sofia_globals.presence_thread);
|
||||
}
|
||||
|
||||
//switch_yield(1000000);
|
||||
su_deinit();
|
||||
|
||||
switch_mutex_lock(mod_sofia_globals.hash_mutex);
|
||||
switch_core_hash_destroy(&mod_sofia_globals.profile_hash);
|
||||
switch_core_hash_destroy(&mod_sofia_globals.gateway_hash);
|
||||
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
|
||||
}
|
||||
|
||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sofia_shutdown)
|
||||
{
|
||||
mod_sofia_shutdown_cleanup();
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -293,6 +293,7 @@ typedef enum {
|
||||
PFLAG_CHANNEL_XML_FETCH_ON_NIGHTMARE_TRANSFER,
|
||||
PFLAG_FIRE_TRANFER_EVENTS,
|
||||
PFLAG_BLIND_AUTH_ENFORCE_RESULT,
|
||||
PFLAG_PROXY_HOLD,
|
||||
|
||||
/* No new flags below this line */
|
||||
PFLAG_MAX
|
||||
@@ -763,6 +764,8 @@ struct sofia_profile {
|
||||
ka_type_t keepalive;
|
||||
int bind_attempts;
|
||||
int bind_attempt_interval;
|
||||
char *proxy_notify_events;
|
||||
char *proxy_info_content_types;
|
||||
};
|
||||
|
||||
|
||||
@@ -1027,6 +1030,7 @@ void sofia_presence_set_chat_hash(private_object_t *tech_pvt, sip_t const *sip);
|
||||
switch_status_t sofia_on_hangup(switch_core_session_t *session);
|
||||
char *sofia_glue_get_url_from_contact(char *buf, uint8_t to_dup);
|
||||
char *sofia_glue_get_path_from_contact(char *buf);
|
||||
char *sofia_glue_get_profile_url(sofia_profile_t *profile, char *remote_ip, const sofia_transport_t transport);
|
||||
void sofia_presence_set_hash_key(char *hash_key, int32_t len, sip_t const *sip);
|
||||
void sofia_glue_sql_close(sofia_profile_t *profile, time_t prune);
|
||||
int sofia_glue_init_sql(sofia_profile_t *profile);
|
||||
@@ -1064,6 +1068,8 @@ void sofia_reg_release_gateway__(const char *file, const char *func, int line, s
|
||||
|
||||
#define sofia_use_soa(_t) sofia_test_flag(_t, TFLAG_ENABLE_SOA)
|
||||
|
||||
#define sofia_test_extra_headers(val) (((!strncasecmp(val, "X-", 2) && strncasecmp(val, "X-FS-", 5)) || !strncasecmp(val, "P-", 2) || !strncasecmp(val, "On", 2)) ? 1 : 0)
|
||||
|
||||
#define check_decode(_var, _session) do { \
|
||||
assert(_session); \
|
||||
if (!zstr(_var)) { \
|
||||
@@ -1160,6 +1166,7 @@ switch_status_t sofia_glue_send_notify(sofia_profile_t *profile, const char *use
|
||||
char *sofia_glue_get_extra_headers(switch_channel_t *channel, const char *prefix);
|
||||
void sofia_glue_set_extra_headers(switch_core_session_t *session, sip_t const *sip, const char *prefix);
|
||||
char *sofia_glue_get_extra_headers_from_event(switch_event_t *event, const char *prefix);
|
||||
char *sofia_glue_get_non_extra_unknown_headers(sip_t const *sip);
|
||||
void sofia_update_callee_id(switch_core_session_t *session, sofia_profile_t *profile, sip_t const *sip, switch_bool_t send);
|
||||
void sofia_send_callee_id(switch_core_session_t *session, const char *name, const char *number);
|
||||
int sofia_sla_supported(sip_t const *sip);
|
||||
|
||||
+237
-126
@@ -679,6 +679,29 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status,
|
||||
|
||||
/* if no session, assume it could be an incoming notify from a gateway subscription */
|
||||
if (session) {
|
||||
if (!zstr(profile->proxy_notify_events) && (!strcasecmp(profile->proxy_notify_events, "all") || strstr(profile->proxy_notify_events, sip->sip_event->o_type))) {
|
||||
switch_core_session_t *other_session;
|
||||
if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
|
||||
private_object_t *other_tech_pvt = switch_core_session_get_private(other_session);
|
||||
const char *full_to = NULL;
|
||||
char *pl = NULL;
|
||||
char *unknown = NULL;
|
||||
|
||||
full_to = switch_str_nil(switch_channel_get_variable(switch_core_session_get_channel(other_session), "sip_full_to"));
|
||||
if (sip->sip_payload && sip->sip_payload->pl_data) {
|
||||
pl = switch_core_session_strdup(other_session, (char*)sip->sip_payload->pl_data);
|
||||
}
|
||||
unknown = sofia_glue_get_non_extra_unknown_headers(sip);
|
||||
nua_notify(other_tech_pvt->nh, NUTAG_NEWSUB(1), NUTAG_SUBSTATE(nua_substate_active),
|
||||
TAG_IF((full_to), SIPTAG_TO_STR(full_to)), SIPTAG_SUBSCRIPTION_STATE_STR("active"),
|
||||
SIPTAG_EVENT_STR(sip->sip_event->o_type), TAG_IF(!zstr(unknown), SIPTAG_HEADER_STR(unknown)),
|
||||
TAG_IF(!zstr(pl), SIPTAG_PAYLOAD_STR(pl)), TAG_END());
|
||||
switch_safe_free(unknown);
|
||||
switch_core_session_rwunlock(other_session);
|
||||
}
|
||||
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS_MSG(de->data->e_msg), TAG_END());
|
||||
goto end;
|
||||
}
|
||||
/* make sure we have a proper "talk" event */
|
||||
if (strcasecmp(sip->sip_event->o_type, "talk")) {
|
||||
goto error;
|
||||
@@ -1567,20 +1590,25 @@ static void our_sofia_event_callback(nua_event_t event,
|
||||
if (channel && sip) {
|
||||
const char *r_sdp = NULL;
|
||||
|
||||
if (sofia_test_flag(tech_pvt, TFLAG_PASS_ACK) && sip->sip_payload && sip->sip_payload->pl_data) {
|
||||
r_sdp = sip->sip_payload->pl_data;
|
||||
if (sip->sip_payload && sip->sip_payload->pl_data) {
|
||||
if (sofia_test_flag(tech_pvt, TFLAG_PASS_ACK)) {
|
||||
r_sdp = sip->sip_payload->pl_data;
|
||||
|
||||
if (tech_pvt->mparams.last_sdp_str) {
|
||||
tech_pvt->mparams.prev_sdp_str = tech_pvt->mparams.last_sdp_str;
|
||||
}
|
||||
tech_pvt->mparams.last_sdp_str = NULL;
|
||||
if (tech_pvt->mparams.last_sdp_str) {
|
||||
tech_pvt->mparams.prev_sdp_str = tech_pvt->mparams.last_sdp_str;
|
||||
}
|
||||
tech_pvt->mparams.last_sdp_str = NULL;
|
||||
|
||||
|
||||
if (!zstr(tech_pvt->mparams.prev_sdp_str) && strcmp(tech_pvt->mparams.prev_sdp_str, sip->sip_payload->pl_data)) {
|
||||
if (!zstr(tech_pvt->mparams.prev_sdp_str) && strcmp(tech_pvt->mparams.prev_sdp_str, sip->sip_payload->pl_data)) {
|
||||
switch_channel_set_variable(channel, "sip_reinvite_sdp", sip->sip_payload->pl_data);
|
||||
tech_pvt->mparams.last_sdp_str = switch_core_session_strdup(session, sip->sip_payload->pl_data);
|
||||
} else {
|
||||
tech_pvt->mparams.last_sdp_str = tech_pvt->mparams.prev_sdp_str;
|
||||
}
|
||||
} else {
|
||||
switch_channel_set_variable(channel, "sip_reinvite_sdp", sip->sip_payload->pl_data);
|
||||
tech_pvt->mparams.last_sdp_str = switch_core_session_strdup(session, sip->sip_payload->pl_data);
|
||||
} else {
|
||||
tech_pvt->mparams.last_sdp_str = tech_pvt->mparams.prev_sdp_str;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4307,7 +4335,6 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
sofia_set_pflag(profile, PFLAG_ENABLE_CHAT);
|
||||
profile->auto_restart = 1;
|
||||
sofia_set_media_flag(profile, SCMF_AUTOFIX_TIMING);
|
||||
sofia_set_media_flag(profile, SCMF_RENEG_ON_REINVITE);
|
||||
sofia_set_media_flag(profile, SCMF_RTP_AUTOFLUSH_DURING_BRIDGE);
|
||||
profile->contact_user = SOFIA_DEFAULT_CONTACT_USER;
|
||||
sofia_set_pflag(profile, PFLAG_PASS_CALLEE_ID);
|
||||
@@ -4364,17 +4391,15 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s [%s]\n", var, val);
|
||||
|
||||
if (!strcasecmp(var, "debug")) {
|
||||
if (!strcasecmp(var, "debug") && val) {
|
||||
profile->debug = atoi(val);
|
||||
} else if (!strcasecmp(var, "parse-invite-tel-params")) {
|
||||
profile->parse_invite_tel_params = switch_true(val);
|
||||
} else if (!strcasecmp(var, "keepalive-method")) {
|
||||
if (!zstr(val)) {
|
||||
if (!strcasecmp(val, "info")) {
|
||||
profile->keepalive = KA_INFO;
|
||||
} else {
|
||||
profile->keepalive = KA_MESSAGE;
|
||||
}
|
||||
} else if (!strcasecmp(var, "keepalive-method") && !zstr(val)) {
|
||||
if (!strcasecmp(val, "info")) {
|
||||
profile->keepalive = KA_INFO;
|
||||
} else {
|
||||
profile->keepalive = KA_MESSAGE;
|
||||
}
|
||||
} else if (!strcasecmp(var, "bind-attempts") && val) {
|
||||
int ba = atoi(val) - 1;
|
||||
@@ -4455,17 +4480,17 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
} else {
|
||||
profile->mndlb &= ~SM_NDLB_NEVER_PATCH_REINVITE;
|
||||
}
|
||||
} else if (!strcasecmp(var, "registration-thread-frequency")) {
|
||||
} else if (!strcasecmp(var, "registration-thread-frequency") && !zstr(val)) {
|
||||
profile->ireg_seconds = atoi(val);
|
||||
if (profile->ireg_seconds < 0) {
|
||||
profile->ireg_seconds = IREG_SECONDS;
|
||||
}
|
||||
} else if (!strcasecmp(var, "ping-mean-interval")) {
|
||||
} else if (!strcasecmp(var, "ping-mean-interval") && !zstr(val)) {
|
||||
profile->iping_seconds = atoi(val);
|
||||
if (profile->iping_seconds < 0) {
|
||||
profile->iping_seconds = IPING_SECONDS;
|
||||
}
|
||||
} else if (!strcasecmp(var, "ping-thread-frequency")) {
|
||||
} else if (!strcasecmp(var, "ping-thread-frequency") && !zstr(val)) {
|
||||
profile->iping_freq = atoi(val);
|
||||
if (profile->iping_freq < 0) {
|
||||
profile->iping_freq = IPING_FREQUENCY;
|
||||
@@ -4540,7 +4565,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
} else {
|
||||
sofia_clear_pflag(profile, PFLAG_LIBERAL_DTMF);
|
||||
}
|
||||
} else if (!strcasecmp(var, "rtp-digit-delay")) {
|
||||
} else if (!strcasecmp(var, "rtp-digit-delay") && !zstr(val)) {
|
||||
int delay = atoi(val);
|
||||
if (delay < 0) {
|
||||
delay = 0;
|
||||
@@ -4548,11 +4573,10 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
profile->rtp_digit_delay = (uint32_t) delay;
|
||||
} else if (!strcasecmp(var, "watchdog-enabled")) {
|
||||
profile->watchdog_enabled = switch_true(val);
|
||||
} else if (!strcasecmp(var, "watchdog-step-timeout")) {
|
||||
} else if (!strcasecmp(var, "watchdog-step-timeout") && !zstr(val)) {
|
||||
profile->step_timeout = atoi(val);
|
||||
} else if (!strcasecmp(var, "watchdog-event-timeout")) {
|
||||
} else if (!strcasecmp(var, "watchdog-event-timeout") && !zstr(val)) {
|
||||
profile->event_timeout = atoi(val);
|
||||
|
||||
} else if (!strcasecmp(var, "in-dialog-chat")) {
|
||||
if (switch_true(val)) {
|
||||
sofia_set_pflag(profile, PFLAG_IN_DIALOG_CHAT);
|
||||
@@ -4589,18 +4613,6 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
} else {
|
||||
sofia_clear_pflag(profile, PFLAG_IGNORE_183NOSDP);
|
||||
}
|
||||
} else if (!strcasecmp(var, "renegotiate-codec-on-hold")) {
|
||||
if (switch_true(val)) {
|
||||
sofia_set_media_flag(profile, SCMF_RENEG_ON_HOLD);
|
||||
} else {
|
||||
sofia_clear_media_flag(profile, SCMF_RENEG_ON_HOLD);
|
||||
}
|
||||
} else if (!strcasecmp(var, "renegotiate-codec-on-reinvite")) {
|
||||
if (switch_true(val)) {
|
||||
sofia_set_media_flag(profile, SCMF_RENEG_ON_REINVITE);
|
||||
} else {
|
||||
sofia_clear_media_flag(profile, SCMF_RENEG_ON_REINVITE);
|
||||
}
|
||||
} else if (!strcasecmp(var, "presence-probe-on-register")) {
|
||||
if (switch_true(val)) {
|
||||
sofia_set_pflag(profile, PFLAG_PRESENCE_PROBE_ON_REGISTER);
|
||||
@@ -4608,9 +4620,9 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
sofia_clear_pflag(profile, PFLAG_PRESENCE_PROBE_ON_REGISTER);
|
||||
}
|
||||
} else if (!strcasecmp(var, "send-presence-on-register")) {
|
||||
if (switch_true(val) || !strcasecmp(val, "all")) {
|
||||
if (val && (switch_true(val) || !strcasecmp(val, "all"))) {
|
||||
sofia_set_pflag(profile, PFLAG_PRESENCE_ON_REGISTER);
|
||||
} else if (!strcasecmp(val, "first-only")) {
|
||||
} else if (val && !strcasecmp(val, "first-only")) {
|
||||
sofia_clear_pflag(profile, PFLAG_PRESENCE_ON_REGISTER);
|
||||
sofia_set_pflag(profile, PFLAG_PRESENCE_ON_FIRST_REGISTER);
|
||||
} else {
|
||||
@@ -4623,22 +4635,21 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
} else {
|
||||
sofia_clear_pflag(profile, PFLAG_CID_IN_1XX);
|
||||
}
|
||||
|
||||
} else if (!strcasecmp(var, "disable-hold")) {
|
||||
if (switch_true(val)) {
|
||||
sofia_set_media_flag(profile, SCMF_DISABLE_HOLD);
|
||||
} else {
|
||||
sofia_clear_media_flag(profile, SCMF_DISABLE_HOLD);
|
||||
}
|
||||
} else if (!strcasecmp(var, "auto-jitterbuffer-msec")) {
|
||||
} else if (!strcasecmp(var, "auto-jitterbuffer-msec") && !zstr(val)) {
|
||||
int msec = atoi(val);
|
||||
if (msec > 19) {
|
||||
profile->jb_msec = switch_core_strdup(profile->pool, val);
|
||||
}
|
||||
} else if (!strcasecmp(var, "dtmf-type")) {
|
||||
if (!strcasecmp(val, "rfc2833")) {
|
||||
if (val && !strcasecmp(val, "rfc2833")) {
|
||||
profile->dtmf_type = DTMF_2833;
|
||||
} else if (!strcasecmp(val, "info")) {
|
||||
} else if (val && !strcasecmp(val, "info")) {
|
||||
profile->dtmf_type = DTMF_INFO;
|
||||
} else {
|
||||
profile->dtmf_type = DTMF_NONE;
|
||||
@@ -4711,12 +4722,12 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
} else {
|
||||
sofia_clear_flag(profile, TFLAG_ZRTP_PASSTHRU);
|
||||
}
|
||||
} else if (!strcasecmp(var, "force-subscription-expires")) {
|
||||
} else if (!strcasecmp(var, "force-subscription-expires") && !zstr(val)) {
|
||||
int tmp = atoi(val);
|
||||
if (tmp > 0) {
|
||||
profile->force_subscription_expires = tmp;
|
||||
}
|
||||
} else if (!strcasecmp(var, "force-publish-expires")) {
|
||||
} else if (!strcasecmp(var, "force-publish-expires") && !zstr(val)) {
|
||||
int tmp = atoi(val);
|
||||
if (tmp > 0) {
|
||||
profile->force_publish_expires = tmp;
|
||||
@@ -4724,7 +4735,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
} else if (!strcasecmp(var, "send-message-query-on-register")) {
|
||||
if (switch_true(val)) {
|
||||
sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER);
|
||||
} else if (!strcasecmp(val, "first-only")) {
|
||||
} else if (val && !strcasecmp(val, "first-only")) {
|
||||
sofia_clear_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER);
|
||||
sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER);
|
||||
} else {
|
||||
@@ -4779,20 +4790,20 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
}
|
||||
} else if (!strcasecmp(var, "user-agent-filter")) {
|
||||
profile->user_agent_filter = switch_core_strdup(profile->pool, val);
|
||||
} else if (!strcasecmp(var, "max-registrations-per-extension")) {
|
||||
} else if (!strcasecmp(var, "max-registrations-per-extension") && !zstr(val)) {
|
||||
profile->max_registrations_perext = atoi(val);
|
||||
} else if (!strcasecmp(var, "rfc2833-pt")) {
|
||||
} else if (!strcasecmp(var, "rfc2833-pt") && !zstr(val)) {
|
||||
profile->te = (switch_payload_t) atoi(val);
|
||||
} else if (!strcasecmp(var, "cng-pt") && !sofia_test_media_flag(profile, SCMF_SUPPRESS_CNG)) {
|
||||
} else if (!strcasecmp(var, "cng-pt") && !sofia_test_media_flag(profile, SCMF_SUPPRESS_CNG) && !zstr(val)) {
|
||||
profile->cng_pt = (switch_payload_t) atoi(val);
|
||||
} else if (!strcasecmp(var, "sip-port")) {
|
||||
} else if (!strcasecmp(var, "sip-port") && !zstr(val)) {
|
||||
if (!strcasecmp(val, "auto")) {
|
||||
sofia_set_pflag(profile, PFLAG_AUTO_ASSIGN_PORT);
|
||||
} else {
|
||||
profile->sip_port = (switch_port_t) atoi(val);
|
||||
if (!profile->extsipport) profile->extsipport = profile->sip_port;
|
||||
}
|
||||
} else if (!strcasecmp(var, "vad")) {
|
||||
} else if (!strcasecmp(var, "vad") && !zstr(val)) {
|
||||
if (!strcasecmp(val, "in")) {
|
||||
profile->vflags |= VAD_IN;
|
||||
} else if (!strcasecmp(val, "out")) {
|
||||
@@ -4829,7 +4840,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid ext-rtp-ip\n");
|
||||
}
|
||||
} else if (!strcasecmp(var, "rtp-ip")) {
|
||||
} else if (!strcasecmp(var, "rtp-ip") && val) {
|
||||
char *ip = mod_sofia_globals.guess_ip;
|
||||
char buf[64];
|
||||
|
||||
@@ -4864,7 +4875,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Max IPs configured for profile %s.\n", profile->name);
|
||||
}
|
||||
}
|
||||
} else if (!strcasecmp(var, "sip-ip")) {
|
||||
} else if (!strcasecmp(var, "sip-ip") && val) {
|
||||
char *ip = mod_sofia_globals.guess_ip;
|
||||
char buf[64];
|
||||
|
||||
@@ -4922,7 +4933,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid ext-sip-ip\n");
|
||||
}
|
||||
} else if (!strcasecmp(var, "local-network-acl")) {
|
||||
if (!strcasecmp(var, "none")) {
|
||||
if (val && !strcasecmp(val, "none")) {
|
||||
profile->local_network = NULL;
|
||||
} else {
|
||||
profile->local_network = switch_core_strdup(profile->pool, val);
|
||||
@@ -4941,7 +4952,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
profile->timer_name = switch_core_strdup(profile->pool, val);
|
||||
} else if (!strcasecmp(var, "hold-music")) {
|
||||
profile->hold_music = switch_core_strdup(profile->pool, val);
|
||||
} else if (!strcasecmp(var, "outbound-proxy")) {
|
||||
} else if (!strcasecmp(var, "outbound-proxy") && val) {
|
||||
if (strncasecmp(val, "sip:", 4) && strncasecmp(val, "sips:", 5)) {
|
||||
profile->outbound_proxy = switch_core_sprintf(profile->pool, "sip:%s", val);
|
||||
} else {
|
||||
@@ -4951,22 +4962,22 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
profile->rtcp_audio_interval_msec = switch_core_strdup(profile->pool, val);
|
||||
} else if (!strcasecmp(var, "rtcp-video-interval-msec")) {
|
||||
profile->rtcp_video_interval_msec = switch_core_strdup(profile->pool, val);
|
||||
} else if (!strcasecmp(var, "session-timeout")) {
|
||||
} else if (!strcasecmp(var, "session-timeout") && !zstr(val)) {
|
||||
int v_session_timeout = atoi(val);
|
||||
if (v_session_timeout >= 0) {
|
||||
profile->session_timeout = v_session_timeout;
|
||||
}
|
||||
} else if (!strcasecmp(var, "max-proceeding")) {
|
||||
} else if (!strcasecmp(var, "max-proceeding") && !zstr(val)) {
|
||||
int v_max_proceeding = atoi(val);
|
||||
if (v_max_proceeding >= 0) {
|
||||
profile->max_proceeding = v_max_proceeding;
|
||||
}
|
||||
} else if (!strcasecmp(var, "rtp-timeout-sec")) {
|
||||
} else if (!strcasecmp(var, "rtp-timeout-sec") && !zstr(val)) {
|
||||
int v = atoi(val);
|
||||
if (v >= 0) {
|
||||
profile->rtp_timeout_sec = v;
|
||||
}
|
||||
} else if (!strcasecmp(var, "rtp-hold-timeout-sec")) {
|
||||
} else if (!strcasecmp(var, "rtp-hold-timeout-sec") && !zstr(val)) {
|
||||
int v = atoi(val);
|
||||
if (v >= 0) {
|
||||
profile->rtp_hold_timeout_sec = v;
|
||||
@@ -4983,7 +4994,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
} else {
|
||||
profile->mflags |= MFLAG_REGISTER;
|
||||
}
|
||||
} else if (!strcasecmp(var, "media-option")) {
|
||||
} else if (!strcasecmp(var, "media-option") && !zstr(val)) {
|
||||
if (!strcasecmp(val, "resume-media-on-hold")) {
|
||||
profile->media_options |= MEDIA_OPT_MEDIA_ON_HOLD;
|
||||
} else if (!strcasecmp(val, "bypass-media-after-att-xfer")) {
|
||||
@@ -5001,10 +5012,10 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
} else if (!strcasecmp(var, "pnp-provision-url")) {
|
||||
profile->pnp_prov_url = switch_core_strdup(profile->pool, val);
|
||||
} else if (!strcasecmp(var, "manage-presence")) {
|
||||
if (!strcasecmp(val, "passive")) {
|
||||
if (val && !strcasecmp(val, "passive")) {
|
||||
profile->pres_type = PRES_TYPE_PASSIVE;
|
||||
|
||||
} else if (!strcasecmp(val, "pnp")) {
|
||||
} else if (val && !strcasecmp(val, "pnp")) {
|
||||
profile->pres_type = PRES_TYPE_PNP;
|
||||
} else if (switch_true(val)) {
|
||||
profile->pres_type = PRES_TYPE_FULL;
|
||||
@@ -5012,9 +5023,9 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
profile->pres_type = 0;
|
||||
}
|
||||
} else if (!strcasecmp(var, "presence-hold-state")) {
|
||||
if (!strcasecmp(val, "confirmed")) {
|
||||
if (val && !strcasecmp(val, "confirmed")) {
|
||||
profile->pres_held_type = PRES_HELD_CONFIRMED;
|
||||
} else if (!strcasecmp(val, "terminated")) {
|
||||
} else if (val && !strcasecmp(val, "terminated")) {
|
||||
profile->pres_held_type = PRES_HELD_TERMINATED;
|
||||
} else {
|
||||
profile->pres_held_type = 0;
|
||||
@@ -5031,7 +5042,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
profile->pres_type = PRES_TYPE_FULL;
|
||||
sofia_set_pflag(profile, PFLAG_MULTIREG);
|
||||
|
||||
} else if (!strcasecmp(val, "sylantro")) {
|
||||
} else if (val && !strcasecmp(val, "sylantro")) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
|
||||
"Sylantro support has been removed.\n"
|
||||
"It was incomplete anyway, and we fully support the broadsoft SCA shared line spec.");
|
||||
@@ -5063,9 +5074,9 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
} else {
|
||||
sofia_clear_pflag(profile, PFLAG_UNREG_OPTIONS_FAIL);
|
||||
}
|
||||
} else if (!strcasecmp(var, "sip-user-ping-max")) {
|
||||
} else if (!strcasecmp(var, "sip-user-ping-max") && !zstr(val)) {
|
||||
profile->sip_user_ping_max = atoi(val);
|
||||
} else if (!strcasecmp(var, "sip-user-ping-min")) {
|
||||
} else if (!strcasecmp(var, "sip-user-ping-min") && !zstr(val)) {
|
||||
profile->sip_user_ping_min = atoi(val);
|
||||
} else if (!strcasecmp(var, "require-secure-rtp")) {
|
||||
if (switch_true(val)) {
|
||||
@@ -5079,9 +5090,9 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
if (found) continue;
|
||||
|
||||
if (!strcasecmp(var, "multiple-registrations")) {
|
||||
if (!strcasecmp(val, "call-id")) {
|
||||
if (val && !strcasecmp(val, "call-id")) {
|
||||
sofia_set_pflag(profile, PFLAG_MULTIREG);
|
||||
} else if (!strcasecmp(val, "contact") || switch_true(val)) {
|
||||
} else if (val && (!strcasecmp(val, "contact") || switch_true(val))) {
|
||||
sofia_set_pflag(profile, PFLAG_MULTIREG);
|
||||
sofia_set_pflag(profile, PFLAG_MULTIREG_CONTACT);
|
||||
} else if (!switch_true(val)) {
|
||||
@@ -5146,7 +5157,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
} else if (!strcasecmp(var, "contact-user")) {
|
||||
profile->contact_user = switch_core_strdup(profile->pool, val);
|
||||
} else if (!strcasecmp(var, "nat-options-ping")) {
|
||||
if (!strcasecmp(val, "udp-only")) {
|
||||
if (val && !strcasecmp(val, "udp-only")) {
|
||||
sofia_set_pflag(profile, PFLAG_UDP_NAT_OPTIONS_PING);
|
||||
} else if (switch_true(val)) {
|
||||
sofia_set_pflag(profile, PFLAG_NAT_OPTIONS_PING);
|
||||
@@ -5161,9 +5172,9 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
sofia_clear_pflag(profile, PFLAG_ALL_REG_OPTIONS_PING);
|
||||
}
|
||||
} else if (!strcasecmp(var, "inbound-codec-negotiation")) {
|
||||
if (!strcasecmp(val, "greedy")) {
|
||||
if (val && !strcasecmp(val, "greedy")) {
|
||||
sofia_set_media_flag(profile, SCMF_CODEC_GREEDY);
|
||||
} else if (!strcasecmp(val, "scrooge")) {
|
||||
} else if (val && !strcasecmp(val, "scrooge")) {
|
||||
sofia_set_media_flag(profile, SCMF_CODEC_GREEDY);
|
||||
sofia_set_media_flag(profile, SCMF_CODEC_SCROOGE);
|
||||
} else {
|
||||
@@ -5206,9 +5217,9 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
} else {
|
||||
sofia_clear_pflag(profile, PFLAG_EXTENDED_INFO_PARSING);
|
||||
}
|
||||
} else if (!strcasecmp(var, "nonce-ttl")) {
|
||||
} else if (!strcasecmp(var, "nonce-ttl") && !zstr(val)) {
|
||||
profile->nonce_ttl = atoi(val);
|
||||
} else if (!strcasecmp(var, "max-auth-validity")) {
|
||||
} else if (!strcasecmp(var, "max-auth-validity") && !zstr(val)) {
|
||||
profile->max_auth_validity = atoi(val);
|
||||
} else if (!strcasecmp(var, "accept-blind-reg")) {
|
||||
if (switch_true(val)) {
|
||||
@@ -5264,7 +5275,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
} else {
|
||||
sofia_clear_pflag(profile, PFLAG_ENABLE_RFC5626);
|
||||
}
|
||||
} else if (!strcasecmp(var, "minimum-session-expires")) {
|
||||
} else if (!strcasecmp(var, "minimum-session-expires") && !zstr(val)) {
|
||||
profile->minimum_session_expires = atoi(val);
|
||||
/* per RFC 4028: minimum_session_expires must be > 90 */
|
||||
if (profile->minimum_session_expires < 90) {
|
||||
@@ -5301,7 +5312,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
sofia_clear_pflag(profile, PFLAG_PARSE_ALL_INVITE_HEADERS);
|
||||
}
|
||||
} else if (!strcasecmp(var, "bitpacking")) {
|
||||
if (!strcasecmp(val, "aal2")) {
|
||||
if (val && !strcasecmp(val, "aal2")) {
|
||||
profile->codec_flags = SWITCH_CODEC_FLAG_AAL2;
|
||||
} else {
|
||||
profile->codec_flags = 0;
|
||||
@@ -5310,7 +5321,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
profile->sdp_username = switch_core_strdup(profile->pool, val);
|
||||
} else if (!strcasecmp(var, "context")) {
|
||||
profile->context = switch_core_strdup(profile->pool, val);
|
||||
} else if (!strcasecmp(var, "apply-nat-acl")) {
|
||||
} else if (!strcasecmp(var, "apply-nat-acl") && !zstr(val)) {
|
||||
if (!strcasecmp(val,"none")) {
|
||||
profile->nat_acl_count = 0;
|
||||
} else if (profile->nat_acl_count < SOFIA_MAX_ACL) {
|
||||
@@ -5322,7 +5333,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL);
|
||||
}
|
||||
} else if (!strcasecmp(var, "apply-inbound-acl")) {
|
||||
} else if (!strcasecmp(var, "apply-inbound-acl") && !zstr(val)) {
|
||||
if (!strcasecmp(val,"none")) {
|
||||
profile->acl_count = 0;
|
||||
} else if (profile->acl_count < SOFIA_MAX_ACL) {
|
||||
@@ -5348,7 +5359,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL);
|
||||
}
|
||||
} else if (!strcasecmp(var, "apply-proxy-acl")) {
|
||||
} else if (!strcasecmp(var, "apply-proxy-acl") && !zstr(val)) {
|
||||
if (!strcasecmp(val,"none")) {
|
||||
profile->proxy_acl_count = 0;
|
||||
} else if (profile->proxy_acl_count < SOFIA_MAX_ACL) {
|
||||
@@ -5356,7 +5367,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL);
|
||||
}
|
||||
} else if (!strcasecmp(var, "apply-register-acl")) {
|
||||
} else if (!strcasecmp(var, "apply-register-acl") && !zstr(val)) {
|
||||
if (!strcasecmp(val,"none")) {
|
||||
profile->reg_acl_count = 0;
|
||||
} else if (profile->reg_acl_count < SOFIA_MAX_ACL) {
|
||||
@@ -5365,7 +5376,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Max acl records of %d reached\n", SOFIA_MAX_ACL);
|
||||
}
|
||||
|
||||
} else if (!strcasecmp(var, "apply-candidate-acl")) {
|
||||
} else if (!strcasecmp(var, "apply-candidate-acl") && !zstr(val)) {
|
||||
if (!strcasecmp(val,"none")) {
|
||||
profile->cand_acl_count = 0;
|
||||
} else if (profile->cand_acl_count < SWITCH_MAX_CAND_ACL) {
|
||||
@@ -5387,7 +5398,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
}
|
||||
} else if (!strcasecmp(var, "dialplan")) {
|
||||
profile->dialplan = switch_core_strdup(profile->pool, val);
|
||||
} else if (!strcasecmp(var, "max-calls")) {
|
||||
} else if (!strcasecmp(var, "max-calls") && !zstr(val)) {
|
||||
profile->max_calls = atoi(val);
|
||||
} else if (!strcasecmp(var, "codec-prefs")) {
|
||||
profile->inbound_codec_string = switch_core_strdup(profile->pool, val);
|
||||
@@ -5398,7 +5409,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
profile->outbound_codec_string = switch_core_strdup(profile->pool, val);
|
||||
} else if (!strcasecmp(var, "challenge-realm")) {
|
||||
profile->challenge_realm = switch_core_strdup(profile->pool, val);
|
||||
} else if (!strcasecmp(var, "dtmf-duration")) {
|
||||
} else if (!strcasecmp(var, "dtmf-duration") && !zstr(val)) {
|
||||
uint32_t dur = atoi(val);
|
||||
if (dur >= switch_core_min_dtmf_duration(0) && dur <= switch_core_max_dtmf_duration(0)) {
|
||||
profile->dtmf_duration = dur;
|
||||
@@ -5451,7 +5462,7 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
sofia_clear_pflag(profile, PFLAG_TLS);
|
||||
}
|
||||
} else if (!strcasecmp(var, "tls-bind-params")) {
|
||||
if (switch_stristr("transport=tls", val)) {
|
||||
if (val && switch_stristr("transport=tls", val)) {
|
||||
profile->tls_bind_params = switch_core_strdup(profile->pool, val);
|
||||
} else {
|
||||
profile->tls_bind_params = switch_core_sprintf(profile->pool, "%s;transport=tls", val);
|
||||
@@ -5460,11 +5471,11 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
profile->tls_only = switch_true(val);
|
||||
} else if (!strcasecmp(var, "tls-verify-date")) {
|
||||
profile->tls_verify_date = switch_true(val);
|
||||
} else if (!strcasecmp(var, "tls-verify-depth")) {
|
||||
} else if (!strcasecmp(var, "tls-verify-depth") && !zstr(val)) {
|
||||
profile->tls_verify_depth = atoi(val);
|
||||
} else if (!strcasecmp(var, "tls-verify-policy")) {
|
||||
profile->tls_verify_policy = sofia_glue_str2tls_verify_policy(val);
|
||||
} else if (!strcasecmp(var, "tls-sip-port")) {
|
||||
} else if (!strcasecmp(var, "tls-sip-port") && !zstr(val)) {
|
||||
if (!strcasecmp(val, "auto")) {
|
||||
sofia_set_pflag(profile, PFLAG_AUTO_ASSIGN_TLS_PORT);
|
||||
} else {
|
||||
@@ -5501,79 +5512,79 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
profile->tls_version |= SOFIA_TLS_VERSION_TLSv1_2;
|
||||
ps=pe+1;
|
||||
}
|
||||
} else if (!strcasecmp(var, "tls-timeout")) {
|
||||
} else if (!strcasecmp(var, "tls-timeout") && !zstr(val)) {
|
||||
int v = atoi(val);
|
||||
profile->tls_timeout = v > 0 ? (unsigned int)v : 300;
|
||||
} else if (!strcasecmp(var, "timer-T1")) {
|
||||
} else if (!strcasecmp(var, "timer-T1") && !zstr(val)) {
|
||||
int v = atoi(val);
|
||||
if (v > 0) {
|
||||
profile->timer_t1 = v;
|
||||
} else {
|
||||
profile->timer_t1 = 500;
|
||||
}
|
||||
} else if (!strcasecmp(var, "timer-T1X64")) {
|
||||
} else if (!strcasecmp(var, "timer-T1X64") && !zstr(val)) {
|
||||
int v = atoi(val);
|
||||
if (v > 0) {
|
||||
profile->timer_t1x64 = v;
|
||||
} else {
|
||||
profile->timer_t1x64 = 32000;
|
||||
}
|
||||
} else if (!strcasecmp(var, "timer-T2")) {
|
||||
} else if (!strcasecmp(var, "timer-T2") && !zstr(val)) {
|
||||
int v = atoi(val);
|
||||
if (v > 0) {
|
||||
profile->timer_t2 = v;
|
||||
} else {
|
||||
profile->timer_t2 = 4000;
|
||||
}
|
||||
} else if (!strcasecmp(var, "timer-T4")) {
|
||||
} else if (!strcasecmp(var, "timer-T4") && !zstr(val)) {
|
||||
int v = atoi(val);
|
||||
if (v > 0) {
|
||||
profile->timer_t4 = v;
|
||||
} else {
|
||||
profile->timer_t4 = 4000;
|
||||
}
|
||||
} else if (!strcasecmp(var, "sip-options-respond-503-on-busy")) {
|
||||
if (switch_true(val)) {
|
||||
sofia_set_pflag(profile, PFLAG_OPTIONS_RESPOND_503_ON_BUSY);
|
||||
} else {
|
||||
sofia_clear_pflag(profile, PFLAG_OPTIONS_RESPOND_503_ON_BUSY);
|
||||
}
|
||||
} else if (!strcasecmp(var, "sip-expires-late-margin")) {
|
||||
} else if (!strcasecmp(var, "sip-options-respond-503-on-busy")) {
|
||||
if (switch_true(val)) {
|
||||
sofia_set_pflag(profile, PFLAG_OPTIONS_RESPOND_503_ON_BUSY);
|
||||
} else {
|
||||
sofia_clear_pflag(profile, PFLAG_OPTIONS_RESPOND_503_ON_BUSY);
|
||||
}
|
||||
} else if (!strcasecmp(var, "sip-expires-late-margin") && !zstr(val)) {
|
||||
int32_t sip_expires_late_margin = atoi(val);
|
||||
if (sip_expires_late_margin >= 0) {
|
||||
profile->sip_expires_late_margin = sip_expires_late_margin;
|
||||
} else {
|
||||
profile->sip_expires_late_margin = 60;
|
||||
}
|
||||
} else if (!strcasecmp(var, "sip-force-expires-min")) {
|
||||
} else if (!strcasecmp(var, "sip-force-expires-min") && !zstr(val)) {
|
||||
int32_t sip_force_expires_min = atoi(val);
|
||||
if (sip_force_expires_min >= 0) {
|
||||
profile->sip_force_expires_min = sip_force_expires_min;
|
||||
} else {
|
||||
profile->sip_force_expires_min = 0;
|
||||
}
|
||||
} else if (!strcasecmp(var, "sip-force-expires-max")) {
|
||||
} else if (!strcasecmp(var, "sip-force-expires-max") && !zstr(val)) {
|
||||
int32_t sip_force_expires_max = atoi(val);
|
||||
if (sip_force_expires_max >= 0) {
|
||||
profile->sip_force_expires_max = sip_force_expires_max;
|
||||
} else {
|
||||
profile->sip_force_expires_max = 0;
|
||||
}
|
||||
} else if (!strcasecmp(var, "sip-force-expires")) {
|
||||
} else if (!strcasecmp(var, "sip-force-expires") && !zstr(val)) {
|
||||
int32_t sip_force_expires = atoi(val);
|
||||
if (sip_force_expires >= 0) {
|
||||
profile->sip_force_expires = sip_force_expires;
|
||||
} else {
|
||||
profile->sip_force_expires = 0;
|
||||
}
|
||||
} else if (!strcasecmp(var, "sip-expires-max-deviation")) {
|
||||
} else if (!strcasecmp(var, "sip-expires-max-deviation") && !zstr(val)) {
|
||||
int32_t sip_expires_max_deviation = atoi(val);
|
||||
if (sip_expires_max_deviation >= 0) {
|
||||
profile->sip_expires_max_deviation = sip_expires_max_deviation;
|
||||
} else {
|
||||
profile->sip_expires_max_deviation = 0;
|
||||
}
|
||||
} else if (!strcasecmp(var, "sip-subscription-max-deviation")) {
|
||||
} else if (!strcasecmp(var, "sip-subscription-max-deviation") && !zstr(val)) {
|
||||
int32_t sip_subscription_max_deviation = atoi(val);
|
||||
if (sip_subscription_max_deviation >= 0) {
|
||||
profile->sip_subscription_max_deviation = sip_subscription_max_deviation;
|
||||
@@ -5588,7 +5599,9 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
sofia_clear_pflag(profile, PFLAG_NO_CONNECTION_REUSE);
|
||||
}
|
||||
} else if (!strcasecmp(var, "p-asserted-id-parse")) {
|
||||
if (!strncasecmp(val, "default", 7)) {
|
||||
if (!val) {
|
||||
profile->paid_type = PAID_DEFAULT;
|
||||
} else if (!strncasecmp(val, "default", 7)) {
|
||||
profile->paid_type = PAID_DEFAULT;
|
||||
} else if (!strncasecmp(val, "user-only", 9)) {
|
||||
profile->paid_type = PAID_USER;
|
||||
@@ -5611,12 +5624,22 @@ switch_status_t config_sofia(sofia_config_t reload, char *profile_name)
|
||||
} else {
|
||||
sofia_clear_pflag(profile, PFLAG_FIRE_TRANFER_EVENTS);
|
||||
}
|
||||
} else if (!strcasecmp(var, "enforce-blind-auth-result")) {
|
||||
if(switch_true(val)) {
|
||||
sofia_set_pflag(profile, PFLAG_BLIND_AUTH_ENFORCE_RESULT);
|
||||
} else {
|
||||
sofia_clear_pflag(profile, PFLAG_BLIND_AUTH_ENFORCE_RESULT);
|
||||
}
|
||||
} else if (!strcasecmp(var, "enforce-blind-auth-result")) {
|
||||
if(switch_true(val)) {
|
||||
sofia_set_pflag(profile, PFLAG_BLIND_AUTH_ENFORCE_RESULT);
|
||||
} else {
|
||||
sofia_clear_pflag(profile, PFLAG_BLIND_AUTH_ENFORCE_RESULT);
|
||||
}
|
||||
} else if (!strcasecmp(var, "proxy-hold")) {
|
||||
if(switch_true(val)) {
|
||||
sofia_set_pflag(profile, PFLAG_PROXY_HOLD);
|
||||
} else {
|
||||
sofia_clear_pflag(profile, PFLAG_PROXY_HOLD);
|
||||
}
|
||||
} else if (!strcasecmp(var, "proxy-notify-events")) {
|
||||
profile->proxy_notify_events = switch_core_strdup(profile->pool, val);
|
||||
} else if (!strcasecmp(var, "proxy-info-content-types")) {
|
||||
profile->proxy_info_content_types = switch_core_strdup(profile->pool, val);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6495,6 +6518,12 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
|
||||
switch_core_media_proxy_remote_addr(session, NULL);
|
||||
}
|
||||
|
||||
if (status == 415) {
|
||||
int new_status = 488;
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Overriding %d %s with %d\n", status, phrase, new_status);
|
||||
status = new_status;
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Passing %d %s to other leg\n%s\n", status, phrase, switch_str_nil(r_sdp));
|
||||
|
||||
if (switch_core_session_compare(session, other_session)) {
|
||||
@@ -6854,7 +6883,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
||||
if (tech_pvt->mparams.last_sdp_response) {
|
||||
r_sdp = tech_pvt->mparams.last_sdp_response;
|
||||
}
|
||||
} else if (ss_state == nua_callstate_received) {
|
||||
} else if (ss_state == nua_callstate_received || ss_state == nua_callstate_ready) {
|
||||
if (tech_pvt->mparams.last_sdp_str) {
|
||||
r_sdp = tech_pvt->mparams.last_sdp_str;
|
||||
}
|
||||
@@ -7398,9 +7427,11 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
||||
} else {
|
||||
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_NOSDP");
|
||||
switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0);
|
||||
switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0);
|
||||
sofia_set_flag_locked(tech_pvt, TFLAG_3PCC);
|
||||
switch_core_media_prepare_codecs(session, 1);
|
||||
switch_channel_set_state(channel, CS_HIBERNATE);
|
||||
switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 0);
|
||||
sofia_set_flag_locked(tech_pvt, TFLAG_3PCC);
|
||||
|
||||
if (sofia_use_soa(tech_pvt)) {
|
||||
nua_respond(tech_pvt->nh, SIP_200_OK,
|
||||
SIPTAG_CONTACT_STR(tech_pvt->profile->url),
|
||||
@@ -7457,15 +7488,13 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
||||
|
||||
switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0);
|
||||
|
||||
nua_respond(tech_pvt->nh, SIP_200_OK, TAG_END());
|
||||
goto done;
|
||||
|
||||
/* } else if (0 && r_sdp && !sofia_use_soa(tech_pvt)) {
|
||||
nua_respond(tech_pvt->nh, SIP_200_OK,
|
||||
NUTAG_MEDIA_ENABLE(0),
|
||||
SIPTAG_CONTACT_STR(tech_pvt->profile->url),
|
||||
SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str), TAG_END());
|
||||
*/
|
||||
|
||||
goto done;
|
||||
|
||||
} else {
|
||||
ss_state = nua_callstate_completed;
|
||||
goto state_process;
|
||||
@@ -7659,6 +7688,64 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
|
||||
}
|
||||
goto done;
|
||||
} else {
|
||||
if (sofia_test_pflag(profile, PFLAG_PROXY_HOLD)) {
|
||||
switch_channel_set_flag(tech_pvt->channel, CF_REINVITE);
|
||||
if (tech_pvt->mparams.num_codecs){
|
||||
match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_REQUEST);
|
||||
}
|
||||
if (!match) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Reinvite Codec Error!\n");
|
||||
nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_END());
|
||||
goto done;
|
||||
}
|
||||
if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_core_session_message_t *msg;
|
||||
|
||||
msg = switch_core_session_alloc(other_session, sizeof(*msg));
|
||||
if (switch_stristr("sendonly", r_sdp) || switch_stristr("0.0.0.0", r_sdp)) {
|
||||
const char *hold_msg = "hold";
|
||||
|
||||
msg->message_id = SWITCH_MESSAGE_INDICATE_HOLD;
|
||||
if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) {
|
||||
const char *info = switch_channel_get_variable(channel, "presence_call_info");
|
||||
|
||||
if (info) {
|
||||
if (switch_stristr("private", info)) {
|
||||
hold_msg = "hold-private";
|
||||
}
|
||||
}
|
||||
}
|
||||
sofia_set_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
|
||||
switch_channel_set_flag(channel, CF_LEG_HOLDING);
|
||||
switch_channel_presence(tech_pvt->channel, "unknown", hold_msg, NULL);
|
||||
} else {
|
||||
msg->message_id = SWITCH_MESSAGE_INDICATE_UNHOLD;
|
||||
sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
|
||||
switch_channel_clear_flag(channel, CF_LEG_HOLDING);
|
||||
switch_channel_presence(tech_pvt->channel, "unknown", "unhold", NULL);
|
||||
}
|
||||
msg->from = __FILE__;
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Indicating Hold to other leg.\n%s\n", r_sdp);
|
||||
|
||||
switch_core_session_queue_message(other_session, msg);
|
||||
switch_core_session_rwunlock(other_session);
|
||||
}
|
||||
switch_core_media_gen_local_sdp(session, SDP_TYPE_RESPONSE, NULL, 0, NULL, 0);
|
||||
if (sofia_use_soa(tech_pvt)){
|
||||
nua_respond(tech_pvt->nh, SIP_200_OK,
|
||||
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
|
||||
SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
|
||||
SOATAG_REUSE_REJECTED(1),
|
||||
SOATAG_AUDIO_AUX("cn telephone-event"),
|
||||
TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_100REL), NUTAG_INCLUDE_EXTRA_SDP(1)), TAG_END());
|
||||
} else {
|
||||
nua_respond(tech_pvt->nh, SIP_200_OK,
|
||||
NUTAG_MEDIA_ENABLE(0),
|
||||
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
|
||||
SIPTAG_CONTENT_TYPE_STR("application/sdp"), SIPTAG_PAYLOAD_STR(tech_pvt->mparams.local_sdp_str), TAG_END());
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
if (switch_channel_test_app_flag_key("T38", tech_pvt->channel, CF_APP_T38_NEGOTIATED)) {
|
||||
nua_respond(tech_pvt->nh, SIP_200_OK, TAG_END());
|
||||
goto done;
|
||||
@@ -8816,6 +8903,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
|
||||
switch_core_session_t *b_session;
|
||||
|
||||
switch_channel_set_variable_printf(channel, "transfer_to", "blind:%s", br ? br : exten);
|
||||
switch_channel_set_variable_printf(channel, "transfer_destination", "blind:%s", exten);
|
||||
|
||||
if (!zstr(br) && (b_session = switch_core_session_locate(br))) {
|
||||
const char *var;
|
||||
@@ -9052,8 +9140,37 @@ void sofia_handle_sip_i_info(nua_t *nua, sofia_profile_t *profile, nua_handle_t
|
||||
assert(switch_core_session_get_private(session));
|
||||
|
||||
sofia_glue_set_extra_headers(session, sip, SOFIA_SIP_INFO_HEADER_PREFIX);
|
||||
if (!zstr(profile->proxy_info_content_types) && sip && sip->sip_content_type && sip->sip_content_type->c_type && sip->sip_content_type->c_subtype &&
|
||||
(!strcasecmp(profile->proxy_info_content_types,"all") || strstr(profile->proxy_info_content_types,sip->sip_content_type->c_type))) {
|
||||
switch_core_session_t *other_session;
|
||||
|
||||
if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
|
||||
char *pl = NULL;
|
||||
char *ct = NULL;
|
||||
char *extra_headers = NULL;
|
||||
char *unknown = NULL;
|
||||
private_object_t *other_tech_pvt = switch_core_session_get_private(other_session);
|
||||
|
||||
ct = switch_core_session_strdup(other_session, (char*)sip->sip_content_type->c_type);
|
||||
if (sip->sip_payload && sip->sip_payload->pl_data) {
|
||||
pl = switch_core_session_strdup(other_session,(char*)sip->sip_payload->pl_data);
|
||||
}
|
||||
unknown = sofia_glue_get_non_extra_unknown_headers(sip);
|
||||
|
||||
extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_INFO_HEADER_PREFIX);
|
||||
|
||||
nua_info(other_tech_pvt->nh,
|
||||
SIPTAG_CONTENT_TYPE_STR(ct),
|
||||
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
|
||||
TAG_IF(!zstr(unknown), SIPTAG_HEADER_STR(unknown)),
|
||||
TAG_IF(!zstr(other_tech_pvt->user_via), SIPTAG_VIA_STR(other_tech_pvt->user_via)),
|
||||
TAG_IF(!zstr(pl), SIPTAG_PAYLOAD_STR(pl)),
|
||||
TAG_END());
|
||||
switch_safe_free(extra_headers);
|
||||
switch_safe_free(unknown);
|
||||
switch_core_session_rwunlock(other_session);
|
||||
}
|
||||
}
|
||||
|
||||
if (sip && sip->sip_content_type && sip->sip_content_type->c_type && !strcasecmp(sip->sip_content_type->c_type, "freeswitch/data")) {
|
||||
char *data = NULL;
|
||||
@@ -9984,11 +10101,9 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
|
||||
user, ipv6 ? "[" : "", host, ipv6 ? "]" : "", port, sofia_glue_transport2str(transport));
|
||||
|
||||
if (sofia_glue_check_nat(profile, tech_pvt->mparams.remote_ip)) {
|
||||
url = (sofia_glue_transport_has_tls(transport)) ? profile->tls_public_url : profile->public_url;
|
||||
check_nat = 1;
|
||||
} else {
|
||||
url = (sofia_glue_transport_has_tls(transport)) ? profile->tls_url : profile->url;
|
||||
}
|
||||
url = sofia_glue_get_profile_url(profile, tech_pvt->mparams.remote_ip, transport);
|
||||
|
||||
if (!url) {
|
||||
if (check_nat) {
|
||||
@@ -10023,11 +10138,7 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
|
||||
|
||||
} else {
|
||||
const char *url = NULL;
|
||||
if (sofia_glue_check_nat(profile, tech_pvt->mparams.remote_ip)) {
|
||||
url = (sofia_glue_transport_has_tls(transport)) ? profile->tls_public_url : profile->public_url;
|
||||
} else {
|
||||
url = (sofia_glue_transport_has_tls(transport)) ? profile->tls_url : profile->url;
|
||||
}
|
||||
url = sofia_glue_get_profile_url(profile, tech_pvt->mparams.remote_ip, transport);
|
||||
|
||||
if (url) {
|
||||
const char *brackets = NULL;
|
||||
|
||||
@@ -644,7 +644,7 @@ void sofia_glue_set_extra_headers(switch_core_session_t *session, sip_t const *s
|
||||
}
|
||||
|
||||
for (un = sip->sip_unknown; un; un = un->un_next) {
|
||||
if ((!strncasecmp(un->un_name, "X-", 2) && strncasecmp(un->un_name, "X-FS-", 5)) || !strncasecmp(un->un_name, "P-", 2) || !strncasecmp(un->un_name, "On", 2)) {
|
||||
if (sofia_test_extra_headers(un->un_name)) {
|
||||
if (!zstr(un->un_value)) {
|
||||
switch_snprintf(name, sizeof(name), "%s%s", prefix, un->un_name);
|
||||
switch_channel_set_variable(channel, name, un->un_value);
|
||||
@@ -685,6 +685,33 @@ char *sofia_glue_get_extra_headers_from_event(switch_event_t *event, const char
|
||||
return extra_headers;
|
||||
}
|
||||
|
||||
char *sofia_glue_get_non_extra_unknown_headers(sip_t const *sip)
|
||||
{
|
||||
char *unknown = NULL;
|
||||
switch_stream_handle_t stream = { 0 };
|
||||
sip_unknown_t *un;
|
||||
|
||||
if (!sip) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_STREAM(stream);
|
||||
for (un = sip->sip_unknown; un; un = un->un_next) {
|
||||
if (!sofia_test_extra_headers(un->un_name)) {
|
||||
if (!zstr(un->un_value)) {
|
||||
stream.write_function(&stream, "%s: %s\r\n",un->un_name,un->un_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!zstr((char *) stream.data)) {
|
||||
unknown = stream.data;
|
||||
} else {
|
||||
switch_safe_free(stream.data);
|
||||
}
|
||||
|
||||
return unknown;
|
||||
}
|
||||
|
||||
switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
|
||||
{
|
||||
char *alert_info = NULL;
|
||||
@@ -931,15 +958,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
|
||||
ipv6 ? "[" : "", ip_addr, ipv6 ? "]" : "", tech_pvt->profile->extsipport);
|
||||
}
|
||||
} else {
|
||||
if (sofia_glue_transport_has_tls(tech_pvt->transport)) {
|
||||
tech_pvt->invite_contact = tech_pvt->profile->tls_url;
|
||||
} else {
|
||||
if (!zstr(tech_pvt->mparams.remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->mparams.remote_ip)) {
|
||||
tech_pvt->invite_contact = tech_pvt->profile->public_url;
|
||||
} else {
|
||||
tech_pvt->invite_contact = tech_pvt->profile->url;
|
||||
}
|
||||
}
|
||||
tech_pvt->invite_contact = sofia_glue_get_profile_url(tech_pvt->profile, tech_pvt->mparams.remote_ip, tech_pvt->transport);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3105,6 +3124,33 @@ void sofia_glue_clear_soa(switch_core_session_t *session, switch_bool_t partner)
|
||||
|
||||
}
|
||||
|
||||
char *sofia_glue_get_profile_url(sofia_profile_t *profile, char *remote_ip, const sofia_transport_t transport)
|
||||
{
|
||||
char *url = NULL;
|
||||
int check_nat = 0;
|
||||
|
||||
if (!zstr(remote_ip) && sofia_glue_check_nat(profile, remote_ip)) {
|
||||
check_nat = 1;
|
||||
}
|
||||
|
||||
if (sofia_glue_transport_has_tls(transport)) {
|
||||
if (check_nat && profile->tls_public_url) {
|
||||
url = profile->tls_public_url;
|
||||
} else {
|
||||
url = profile->tls_url;
|
||||
}
|
||||
} else {
|
||||
if (check_nat && profile->public_url) {
|
||||
url = profile->public_url;
|
||||
} else {
|
||||
url = profile->url;
|
||||
}
|
||||
}
|
||||
|
||||
if (!url) url = profile->url;
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
|
||||
@@ -384,6 +384,7 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event)
|
||||
|
||||
sofia_glue_free_destination(dst);
|
||||
switch_safe_free(dup_dest);
|
||||
switch_safe_free(user_via);
|
||||
switch_safe_free(remote_host);
|
||||
}
|
||||
|
||||
|
||||
@@ -161,7 +161,7 @@ static void close_socket(ws_socket_t *sock)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void verto_broadcast(const char *event_channel, cJSON *json, const char *key, switch_event_channel_id_t id);
|
||||
static int ssl_init = 0;
|
||||
|
||||
static int verto_init_ssl(verto_profile_t *profile)
|
||||
@@ -2389,8 +2389,6 @@ static void verto_set_media_options(verto_pvt_t *tech_pvt, verto_profile_t *prof
|
||||
tech_pvt->mparams->jb_msec = "-1";
|
||||
switch_media_handle_set_media_flag(tech_pvt->smh, SCMF_SUPPRESS_CNG);
|
||||
|
||||
switch_media_handle_set_media_flag(tech_pvt->smh, SCMF_RENEG_ON_REINVITE);
|
||||
|
||||
//tech_pvt->mparams->auto_rtp_bugs = profile->auto_rtp_bugs;
|
||||
tech_pvt->mparams->timer_name = profile->timer_name;
|
||||
//tech_pvt->mparams->vflags = profile->vflags;
|
||||
@@ -3819,8 +3817,10 @@ static switch_bool_t verto__broadcast_func(const char *method, cJSON *params, js
|
||||
}
|
||||
|
||||
jevent = cJSON_Duplicate(params, 1);
|
||||
write_event(event_channel, NULL, jevent);
|
||||
switch_event_channel_broadcast(event_channel, &jevent, modname, globals.event_channel_id);
|
||||
|
||||
|
||||
if (jsock->profile->mcast_pub.sock != ws_sock_invalid) {
|
||||
if ((json_text = cJSON_PrintUnformatted(params))) {
|
||||
|
||||
@@ -4677,7 +4677,7 @@ static switch_status_t parse_config(const char *cf)
|
||||
vhost->alias = switch_core_strdup(vhost->pool, val);
|
||||
} else if (!strcasecmp(var, "root")) {
|
||||
vhost->root = switch_core_strdup(vhost->pool, val);
|
||||
} else if (!strcasecmp(var, "script_root")) {
|
||||
} else if (!strcasecmp(var, "script-root")) {
|
||||
vhost->script_root = switch_core_strdup(vhost->pool, val);
|
||||
} else if (!strcasecmp(var, "index")) {
|
||||
vhost->index = switch_core_strdup(vhost->pool, val);
|
||||
|
||||
@@ -94,12 +94,13 @@ switch_status_t mod_amqp_logging_recv(const switch_log_node_t *node, switch_log_
|
||||
|
||||
if (switch_queue_trypush(logging->send_queue, msg) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "AMQP logging message queue full. Messages will be dropped!\n");
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
switch_safe_free(hi);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
done:
|
||||
switch_safe_free(json);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -201,6 +201,7 @@ switch_status_t mod_smpp_gateway_connection_read(mod_smpp_gateway_t *gateway, sw
|
||||
switch_event_t *evt = NULL;
|
||||
generic_nack_t *gennack = NULL;
|
||||
char data[2048] = {0}; /* local buffer for unpacked PDU */
|
||||
int err = 0;
|
||||
|
||||
/* Read from socket */
|
||||
/* TODO: Add/Expand support for partial reads */
|
||||
@@ -227,8 +228,7 @@ switch_status_t mod_smpp_gateway_connection_read(mod_smpp_gateway_t *gateway, sw
|
||||
}
|
||||
|
||||
if ( smpp34_unpack2((void *)data, local_buffer, read_len + 4) ) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "smpp: error decoding the receive buffer:%d:%s\n", smpp34_errno, smpp34_strerror);
|
||||
switch_goto_status(SWITCH_STATUS_GENERR, done);
|
||||
err++;
|
||||
}
|
||||
|
||||
if ( mod_smpp_globals.debug || gateway->debug ) {
|
||||
@@ -237,6 +237,12 @@ switch_status_t mod_smpp_gateway_connection_read(mod_smpp_gateway_t *gateway, sw
|
||||
|
||||
gennack = (generic_nack_t *) data;
|
||||
*command_id = gennack->command_id;
|
||||
|
||||
if (err && *command_id != SUBMIT_SM_RESP) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "smpp: error decoding the receive buffer:%d:%s\n", smpp34_errno, smpp34_strerror);
|
||||
switch_goto_status(SWITCH_STATUS_GENERR, done);
|
||||
}
|
||||
|
||||
switch(*command_id) {
|
||||
case BIND_TRANSCEIVER_RESP:
|
||||
if ( gennack->command_status != ESME_ROK ) {
|
||||
@@ -256,6 +262,21 @@ switch_status_t mod_smpp_gateway_connection_read(mod_smpp_gateway_t *gateway, sw
|
||||
case ENQUIRE_LINK:
|
||||
case ENQUIRE_LINK_RESP:
|
||||
case SUBMIT_SM_RESP:
|
||||
switch (gennack->command_status) {
|
||||
case ESME_ROK:
|
||||
//AOK
|
||||
break;
|
||||
case ESME_RINVSRCADR:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Source Addr ID: %u\n", *command_id);
|
||||
break;
|
||||
case ESME_RINVDSTADR:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Dest Addr ID: %u\n", *command_id);
|
||||
break;
|
||||
default:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Undocumented Error 0X%.8x ID: %u\n", gennack->command_status, *command_id);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unrecognized Command ID: %u\n", *command_id);
|
||||
|
||||
@@ -4,5 +4,5 @@ MODNAME=mod_snmp
|
||||
mod_LTLIBRARIES = mod_snmp.la
|
||||
mod_snmp_la_SOURCES = mod_snmp.c subagent.c
|
||||
mod_snmp_la_CFLAGS = $(AM_CFLAGS)
|
||||
mod_snmp_la_LIBADD = $(switch_builddir)/libfreeswitch.la -lnetsnmpmibs -lnetsnmpagent -lnetsnmp
|
||||
mod_snmp_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(SNMP_LIBS)
|
||||
mod_snmp_la_LDFLAGS = -avoid-version -module -no-undefined -shared
|
||||
|
||||
@@ -125,6 +125,7 @@ struct local_stream_source {
|
||||
switch_img_position_t logo_pos;
|
||||
uint8_t logo_opacity;
|
||||
uint8_t text_opacity;
|
||||
switch_mm_t mm;
|
||||
};
|
||||
|
||||
typedef struct local_stream_source local_stream_source_t;
|
||||
@@ -479,6 +480,10 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
|
||||
|
||||
retry:
|
||||
|
||||
if (switch_core_file_has_video(use_fh, SWITCH_TRUE)) {
|
||||
source->mm = use_fh->mm;
|
||||
}
|
||||
|
||||
source->has_video = switch_core_file_has_video(use_fh, SWITCH_TRUE) || source->cover_art || source->banner_txt;
|
||||
|
||||
is_open = switch_test_flag(use_fh, SWITCH_FILE_OPEN);
|
||||
@@ -934,8 +939,9 @@ static switch_status_t local_stream_file_read_video(switch_file_handle_t *handle
|
||||
switch_status_t status;
|
||||
switch_time_t now;
|
||||
unsigned int fps = (unsigned int)ceil(handle->mm.fps);
|
||||
unsigned int min_qsize = fps;
|
||||
|
||||
unsigned int min_qsize = fps / 2;
|
||||
unsigned int buf_qsize = 5;
|
||||
|
||||
if (!(context->ready && context->source->ready)) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
@@ -973,7 +979,12 @@ static switch_status_t local_stream_file_read_video(switch_file_handle_t *handle
|
||||
return SWITCH_STATUS_BREAK;
|
||||
}
|
||||
|
||||
while(context->ready && context->source->ready && (flags & SVR_FLUSH) && switch_queue_size(context->video_q) > min_qsize / 2) {
|
||||
if (handle->mm.fps >= context->source->mm.source_fps) {
|
||||
min_qsize = 1;
|
||||
buf_qsize = 1;
|
||||
}
|
||||
|
||||
while(context->ready && context->source->ready && (flags & SVR_FLUSH) && switch_queue_size(context->video_q) > min_qsize) {
|
||||
if (switch_queue_trypop(context->video_q, &pop) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_image_t *img = (switch_image_t *) pop;
|
||||
switch_img_free(&img);
|
||||
@@ -984,7 +995,7 @@ static switch_status_t local_stream_file_read_video(switch_file_handle_t *handle
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
while (!(flags & SVR_BLOCK) && switch_queue_size(context->video_q) < 5) {
|
||||
while (!(flags & SVR_BLOCK) && switch_queue_size(context->video_q) < buf_qsize) {
|
||||
return SWITCH_STATUS_BREAK;
|
||||
}
|
||||
|
||||
|
||||
@@ -1659,7 +1659,7 @@ int vlc_write_video_imem_get_callback(void *data, const char *cookie, int64_t *
|
||||
}
|
||||
|
||||
*output = context->video_frame_buffer;
|
||||
switch_img_to_raw(img, *output, *size, SWITCH_IMG_FMT_YUY2);
|
||||
switch_img_to_raw(img, *output, 0, SWITCH_IMG_FMT_YUY2);
|
||||
switch_img_free(&img);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@ public:
|
||||
JS_COREDB_FUNCTION_DEF(Prepare);
|
||||
JS_COREDB_FUNCTION_DEF(BindText);
|
||||
JS_COREDB_FUNCTION_DEF(BindInt);
|
||||
JS_COREDB_FUNCTION_DEF(Finalize);
|
||||
JS_COREDB_GET_PROPERTY_DEF(GetProperty);
|
||||
};
|
||||
|
||||
|
||||
@@ -232,6 +232,14 @@ JS_COREDB_FUNCTION_IMPL(Step)
|
||||
StepEx(info, SWITCH_CORE_DB_DONE);
|
||||
}
|
||||
|
||||
JS_COREDB_FUNCTION_IMPL(Finalize)
|
||||
{
|
||||
if (_stmt) {
|
||||
switch_core_db_finalize(_stmt);
|
||||
_stmt = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
JS_COREDB_FUNCTION_IMPL(Fetch)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
@@ -415,6 +423,7 @@ static const js_function_t db_methods[] = {
|
||||
{"prepare", FSCoreDB::Prepare},
|
||||
{"bindText", FSCoreDB::BindText},
|
||||
{"bindInt", FSCoreDB::BindInt},
|
||||
{"finalize", FSCoreDB::Finalize},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
||||
+2
-2
@@ -504,8 +504,8 @@ int main(int argc, char *argv[])
|
||||
char *arg_argv[128] = { 0 };
|
||||
int alt_dirs = 0, alt_base = 0, log_set = 0, run_set = 0, do_kill = 0;
|
||||
int priority = 0;
|
||||
#ifdef __sun
|
||||
switch_core_flag_t flags = SCF_USE_SQL;
|
||||
#if (defined(__SVR4) && defined(__sun))
|
||||
switch_core_flag_t flags = SCF_USE_SQL | SCF_CALIBRATE_CLOCK | SCF_USE_CLOCK_RT;
|
||||
#else
|
||||
switch_core_flag_t flags = SCF_USE_SQL | SCF_USE_AUTO_NAT | SCF_USE_NAT_MAPPING | SCF_CALIBRATE_CLOCK | SCF_USE_CLOCK_RT;
|
||||
#endif
|
||||
|
||||
@@ -1373,6 +1373,10 @@ SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip_token(const char *ip_
|
||||
switch_bool_t ok = SWITCH_FALSE;
|
||||
char *ipv4 = NULL;
|
||||
|
||||
if (!list_name) {
|
||||
return SWITCH_FALSE;
|
||||
}
|
||||
|
||||
if ((ipv4 = switch_network_ipv4_mapped_ipv6_addr(ip_str))) {
|
||||
ip_str = ipv4;
|
||||
ipv6 = NULL;
|
||||
|
||||
+281
-295
@@ -1827,6 +1827,8 @@ SWITCH_DECLARE(void) switch_core_media_prepare_codecs(switch_core_session_t *ses
|
||||
return;
|
||||
}
|
||||
|
||||
ocodec = switch_channel_get_variable(session->channel, SWITCH_ORIGINATOR_CODEC_VARIABLE);
|
||||
|
||||
smh->payload_space = 0;
|
||||
|
||||
switch_assert(smh->session != NULL);
|
||||
@@ -1837,11 +1839,10 @@ SWITCH_DECLARE(void) switch_core_media_prepare_codecs(switch_core_session_t *ses
|
||||
}
|
||||
|
||||
val = switch_channel_get_variable_dup(session->channel, "media_mix_inbound_outbound_codecs", SWITCH_FALSE, -1);
|
||||
if (!val || !switch_true(val)) {
|
||||
if ((ocodec = switch_channel_get_variable(session->channel, SWITCH_ORIGINATOR_CODEC_VARIABLE))) {
|
||||
codec_string = ocodec;
|
||||
goto ready;
|
||||
}
|
||||
|
||||
if ((!val || !switch_true(val) || smh->media_flags[SCMF_DISABLE_TRANSCODING]) && ocodec) {
|
||||
codec_string = ocodec;
|
||||
goto ready;
|
||||
}
|
||||
|
||||
if (!(codec_string = switch_channel_get_variable(session->channel, "codec_string"))) {
|
||||
@@ -1854,13 +1855,7 @@ SWITCH_DECLARE(void) switch_core_media_prepare_codecs(switch_core_session_t *ses
|
||||
}
|
||||
|
||||
if (ocodec) {
|
||||
if (!codec_string || (smh->media_flags[SCMF_DISABLE_TRANSCODING])) {
|
||||
codec_string = ocodec;
|
||||
} else {
|
||||
if (!(codec_string = switch_core_session_sprintf(smh->session, "%s,%s", ocodec, codec_string))) {
|
||||
codec_string = ocodec;
|
||||
}
|
||||
}
|
||||
codec_string = switch_core_session_sprintf(smh->session, "%s,%s", ocodec, codec_string);
|
||||
}
|
||||
|
||||
ready:
|
||||
@@ -1873,83 +1868,6 @@ SWITCH_DECLARE(void) switch_core_media_prepare_codecs(switch_core_session_t *ses
|
||||
switch_channel_set_variable(session->channel, "rtp_use_codec_string", codec_string);
|
||||
smh->codec_order_last = switch_separate_string(tmp_codec_string, ',', smh->codec_order, SWITCH_MAX_CODECS);
|
||||
smh->mparams->num_codecs = switch_loadable_module_get_codecs_sorted(smh->codecs, smh->fmtp, SWITCH_MAX_CODECS, smh->codec_order, smh->codec_order_last);
|
||||
|
||||
}
|
||||
|
||||
static void adjust_jb(switch_core_session_t *session, int new_ptime_ms)
|
||||
{
|
||||
const char *val;
|
||||
switch_media_handle_t *smh;
|
||||
switch_rtp_engine_t *a_engine = NULL;
|
||||
int maxlen = 0;
|
||||
int32_t jb_msec = 0 ;
|
||||
int qlen, maxqlen = 50;
|
||||
|
||||
switch_assert(session);
|
||||
|
||||
if (!(smh = session->media_handle)) {
|
||||
return;
|
||||
}
|
||||
|
||||
a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
|
||||
|
||||
if ((val = switch_channel_get_variable(session->channel, "jitterbuffer_msec")) || (val = smh->mparams->jb_msec)) {
|
||||
char *p;
|
||||
|
||||
if (!jb_msec) {
|
||||
jb_msec = atoi(val);
|
||||
|
||||
if (strchr(val, 'p') && jb_msec > 0) {
|
||||
jb_msec *= -1;
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG3, "Will not adjust JB size, token 'p' not specified\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((p = strchr(val, ':'))) {
|
||||
p++;
|
||||
maxlen = atoi(p);
|
||||
|
||||
if (strchr(p, 'p') && maxlen > 0) {
|
||||
maxlen *= -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (jb_msec < 0 && jb_msec > -1000) {
|
||||
jb_msec = new_ptime_ms * abs(jb_msec);
|
||||
}
|
||||
|
||||
if (maxlen < 0 && maxlen > -1000) {
|
||||
maxlen = new_ptime_ms * abs(maxlen);
|
||||
}
|
||||
|
||||
if (jb_msec < 10 || jb_msec > 10000) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,
|
||||
"Invalid Jitterbuffer spec [%d] must be between 10 and 10000\n", jb_msec);
|
||||
} else {
|
||||
qlen = jb_msec / new_ptime_ms;
|
||||
if (maxlen) {
|
||||
maxqlen = maxlen / new_ptime_ms;
|
||||
}
|
||||
if (maxqlen < qlen) {
|
||||
maxqlen = qlen * 5;
|
||||
}
|
||||
if (switch_rtp_activate_jitter_buffer(a_engine->rtp_session, qlen, maxqlen,
|
||||
a_engine->read_impl.samples_per_packet, a_engine->read_impl.samples_per_second) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session),
|
||||
SWITCH_LOG_DEBUG, "Adjusting Jitterbuffer to %dms (%d frames) (%d max frames)\n",
|
||||
jb_msec, qlen, maxqlen);
|
||||
switch_channel_set_flag(session->channel, CF_JITTERBUFFER);
|
||||
if (!switch_false(switch_channel_get_variable(session->channel, "rtp_jitter_buffer_plc"))) {
|
||||
switch_channel_set_flag(session->channel, CF_JITTERBUFFER_PLC);
|
||||
}
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session),
|
||||
SWITCH_LOG_DEBUG, "Error adjusting Jitterbuffer to %dms (%d frames)\n", jb_msec, qlen);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void check_jb(switch_core_session_t *session, const char *input, int32_t jb_msec, int32_t maxlen, switch_bool_t silent)
|
||||
@@ -2498,6 +2416,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session
|
||||
|
||||
if (engine->last_codec_ms && engine->last_codec_ms == codec_ms) {
|
||||
engine->mismatch_count++;
|
||||
} else {
|
||||
engine->mismatch_count = 0;
|
||||
}
|
||||
|
||||
engine->last_codec_ms = codec_ms;
|
||||
@@ -2554,9 +2474,17 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session
|
||||
codec_ms = codec_ms / (int) (engine->read_frame.seq - engine->last_seq);
|
||||
}
|
||||
|
||||
if (codec_ms && codec_ms != engine->cur_payload_map->codec_ms) {
|
||||
if (engine->last_codec_ms && engine->last_codec_ms == codec_ms) {
|
||||
engine->mismatch_count++;
|
||||
}
|
||||
} else {
|
||||
engine->mismatch_count = 0;
|
||||
}
|
||||
|
||||
engine->last_codec_ms = codec_ms;
|
||||
|
||||
if (codec_ms != engine->cur_payload_map->codec_ms && codec_ms) {
|
||||
if (engine->mismatch_count > MAX_MISMATCH_FRAMES) {
|
||||
|
||||
if (codec_ms > 120) {
|
||||
/*will show too many times with packet loss*/
|
||||
@@ -2571,14 +2499,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session
|
||||
|
||||
if (codec_ms != engine->cur_payload_map->codec_ms) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
|
||||
"[%s]: Asynchronous PTIME supported, adjusting JB size. Remote PTIME changed from [%d] to [%d]\n",
|
||||
"[%s]: Packet size change detected. Remote PTIME changed from [%d] to [%d]\n",
|
||||
is_vbr?"VBR":"CBR",
|
||||
(int) engine->cur_payload_map->codec_ms,
|
||||
(int) codec_ms
|
||||
);
|
||||
engine->cur_payload_map->codec_ms = codec_ms;
|
||||
/* adjust audio JB size, but do not substitute the codec */
|
||||
adjust_jb(session,codec_ms);
|
||||
engine->reset_codec = 2;
|
||||
|
||||
if (switch_channel_test_flag(session->channel, CF_CONFERENCE)) {
|
||||
@@ -3576,7 +3502,7 @@ static switch_status_t check_ice(switch_media_handle_t *smh, switch_media_type_t
|
||||
done_choosing:
|
||||
|
||||
|
||||
if (!engine->ice_in.is_chosen[0] || !engine->ice_in.is_chosen[1]) {
|
||||
if (!engine->ice_in.is_chosen[0]) {
|
||||
/* PUNT */
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG, "%s no suitable candidates found.\n",
|
||||
switch_channel_get_name(smh->session->channel));
|
||||
@@ -3780,7 +3706,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
|
||||
sdp_media_t *m;
|
||||
sdp_attribute_t *attr;
|
||||
int ptime = 0, dptime = 0, maxptime = 0, dmaxptime = 0;
|
||||
int sendonly = 0, recvonly = 0;
|
||||
int sendonly = 0, recvonly = 0, inactive = 0;
|
||||
int greedy = 0, x = 0, skip = 0;
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
const char *val;
|
||||
@@ -3789,7 +3715,6 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
|
||||
int scrooge = 0;
|
||||
sdp_parser_t *parser = NULL;
|
||||
sdp_session_t *sdp;
|
||||
int reneg = 1;
|
||||
const switch_codec_implementation_t **codec_array;
|
||||
int total_codecs;
|
||||
switch_rtp_engine_t *a_engine, *v_engine;
|
||||
@@ -3839,7 +3764,9 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
|
||||
a_engine->new_dtls = 1;
|
||||
a_engine->new_ice = 1;
|
||||
a_engine->reject_avp = 0;
|
||||
|
||||
|
||||
switch_media_handle_set_media_flag(smh, SCMF_RECV_SDP);
|
||||
|
||||
switch_core_session_parse_crypto_prefs(session);
|
||||
|
||||
clear_pmaps(a_engine);
|
||||
@@ -3951,116 +3878,120 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
|
||||
got_udptl++;
|
||||
}
|
||||
|
||||
if (got_udptl && m->m_type == sdp_media_image && m->m_port) {
|
||||
switch_t38_options_t *t38_options = switch_core_media_process_udptl(session, sdp, m);
|
||||
if (got_udptl && m->m_type == sdp_media_image) {
|
||||
switch_channel_set_flag(session->channel, CF_IMAGE_SDP);
|
||||
|
||||
if (switch_channel_test_app_flag_key("T38", session->channel, CF_APP_T38_NEGOTIATED)) {
|
||||
if (m->m_port) {
|
||||
switch_t38_options_t *t38_options = switch_core_media_process_udptl(session, sdp, m);
|
||||
|
||||
if (switch_channel_test_app_flag_key("T38", session->channel, CF_APP_T38_NEGOTIATED)) {
|
||||
match = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (switch_true(switch_channel_get_variable(channel, "refuse_t38"))) {
|
||||
switch_channel_clear_app_flag_key("T38", session->channel, CF_APP_T38);
|
||||
match = 0;
|
||||
goto done;
|
||||
} else {
|
||||
const char *var = switch_channel_get_variable(channel, "t38_passthru");
|
||||
int pass = switch_channel_test_flag(smh->session->channel, CF_T38_PASSTHRU);
|
||||
|
||||
|
||||
if (switch_channel_test_app_flag_key("T38", session->channel, CF_APP_T38)) {
|
||||
if (proceed) *proceed = 0;
|
||||
}
|
||||
|
||||
if (var) {
|
||||
if (!(pass = switch_true(var))) {
|
||||
if (!strcasecmp(var, "once")) {
|
||||
pass = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((pass == 2 && switch_channel_test_flag(smh->session->channel, CF_T38_PASSTHRU))
|
||||
|| !switch_channel_test_flag(session->channel, CF_REINVITE) ||
|
||||
|
||||
switch_channel_test_flag(session->channel, CF_PROXY_MODE) ||
|
||||
switch_channel_test_flag(session->channel, CF_PROXY_MEDIA) ||
|
||||
!switch_rtp_ready(a_engine->rtp_session)) {
|
||||
pass = 0;
|
||||
}
|
||||
|
||||
if (pass && switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
|
||||
switch_core_session_message_t *msg;
|
||||
char *remote_host = switch_rtp_get_remote_host(a_engine->rtp_session);
|
||||
switch_port_t remote_port = switch_rtp_get_remote_port(a_engine->rtp_session);
|
||||
char tmp[32] = "";
|
||||
|
||||
|
||||
if (!switch_channel_test_flag(other_channel, CF_ANSWERED)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session),
|
||||
SWITCH_LOG_WARNING, "%s Error Passing T.38 to unanswered channel %s\n",
|
||||
switch_channel_get_name(session->channel), switch_channel_get_name(other_channel));
|
||||
switch_core_session_rwunlock(other_session);
|
||||
|
||||
pass = 0;
|
||||
match = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
if (switch_true(switch_channel_get_variable(session->channel, "t38_broken_boolean")) &&
|
||||
switch_true(switch_channel_get_variable(session->channel, "t38_pass_broken_boolean"))) {
|
||||
switch_channel_set_variable(other_channel, "t38_broken_boolean", "true");
|
||||
}
|
||||
|
||||
a_engine->cur_payload_map->remote_sdp_ip = switch_core_session_strdup(session, t38_options->remote_ip);
|
||||
a_engine->cur_payload_map->remote_sdp_port = t38_options->remote_port;
|
||||
|
||||
if (remote_host && remote_port && !strcmp(remote_host, a_engine->cur_payload_map->remote_sdp_ip) && remote_port == a_engine->cur_payload_map->remote_sdp_port) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio params are unchanged for %s.\n",
|
||||
switch_channel_get_name(session->channel));
|
||||
} else {
|
||||
const char *err = NULL;
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio params changed for %s from %s:%d to %s:%d\n",
|
||||
switch_channel_get_name(session->channel),
|
||||
remote_host, remote_port, a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port);
|
||||
|
||||
switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->cur_payload_map->remote_sdp_port);
|
||||
switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, a_engine->cur_payload_map->remote_sdp_ip);
|
||||
switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp);
|
||||
|
||||
if (switch_rtp_set_remote_address(a_engine->rtp_session, a_engine->cur_payload_map->remote_sdp_ip,
|
||||
a_engine->cur_payload_map->remote_sdp_port, 0, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err);
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
|
||||
}
|
||||
|
||||
switch_core_media_check_autoadj(session);
|
||||
}
|
||||
|
||||
|
||||
|
||||
switch_core_media_copy_t38_options(t38_options, other_session);
|
||||
|
||||
switch_channel_set_flag(smh->session->channel, CF_T38_PASSTHRU);
|
||||
switch_channel_set_flag(other_session->channel, CF_T38_PASSTHRU);
|
||||
|
||||
msg = switch_core_session_alloc(other_session, sizeof(*msg));
|
||||
msg->message_id = SWITCH_MESSAGE_INDICATE_REQUEST_IMAGE_MEDIA;
|
||||
msg->from = __FILE__;
|
||||
msg->string_arg = switch_core_session_strdup(other_session, r_sdp);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Passing T38 req to other leg.\n%s\n", r_sdp);
|
||||
switch_core_session_queue_message(other_session, msg);
|
||||
switch_core_session_rwunlock(other_session);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* do nothing here, mod_fax will trigger a response (if it's listening =/) */
|
||||
match = 1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (switch_true(switch_channel_get_variable(channel, "refuse_t38"))) {
|
||||
switch_channel_clear_app_flag_key("T38", session->channel, CF_APP_T38);
|
||||
match = 0;
|
||||
goto done;
|
||||
} else {
|
||||
const char *var = switch_channel_get_variable(channel, "t38_passthru");
|
||||
int pass = switch_channel_test_flag(smh->session->channel, CF_T38_PASSTHRU);
|
||||
|
||||
|
||||
if (switch_channel_test_app_flag_key("T38", session->channel, CF_APP_T38)) {
|
||||
if (proceed) *proceed = 0;
|
||||
}
|
||||
|
||||
if (var) {
|
||||
if (!(pass = switch_true(var))) {
|
||||
if (!strcasecmp(var, "once")) {
|
||||
pass = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((pass == 2 && switch_channel_test_flag(smh->session->channel, CF_T38_PASSTHRU))
|
||||
|| !switch_channel_test_flag(session->channel, CF_REINVITE) ||
|
||||
|
||||
switch_channel_test_flag(session->channel, CF_PROXY_MODE) ||
|
||||
switch_channel_test_flag(session->channel, CF_PROXY_MEDIA) ||
|
||||
!switch_rtp_ready(a_engine->rtp_session)) {
|
||||
pass = 0;
|
||||
}
|
||||
|
||||
if (pass && switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
|
||||
switch_core_session_message_t *msg;
|
||||
char *remote_host = switch_rtp_get_remote_host(a_engine->rtp_session);
|
||||
switch_port_t remote_port = switch_rtp_get_remote_port(a_engine->rtp_session);
|
||||
char tmp[32] = "";
|
||||
|
||||
|
||||
if (!switch_channel_test_flag(other_channel, CF_ANSWERED)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session),
|
||||
SWITCH_LOG_WARNING, "%s Error Passing T.38 to unanswered channel %s\n",
|
||||
switch_channel_get_name(session->channel), switch_channel_get_name(other_channel));
|
||||
switch_core_session_rwunlock(other_session);
|
||||
|
||||
pass = 0;
|
||||
match = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
if (switch_true(switch_channel_get_variable(session->channel, "t38_broken_boolean")) &&
|
||||
switch_true(switch_channel_get_variable(session->channel, "t38_pass_broken_boolean"))) {
|
||||
switch_channel_set_variable(other_channel, "t38_broken_boolean", "true");
|
||||
}
|
||||
|
||||
a_engine->cur_payload_map->remote_sdp_ip = switch_core_session_strdup(session, t38_options->remote_ip);
|
||||
a_engine->cur_payload_map->remote_sdp_port = t38_options->remote_port;
|
||||
|
||||
if (remote_host && remote_port && !strcmp(remote_host, a_engine->cur_payload_map->remote_sdp_ip) && remote_port == a_engine->cur_payload_map->remote_sdp_port) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio params are unchanged for %s.\n",
|
||||
switch_channel_get_name(session->channel));
|
||||
} else {
|
||||
const char *err = NULL;
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Audio params changed for %s from %s:%d to %s:%d\n",
|
||||
switch_channel_get_name(session->channel),
|
||||
remote_host, remote_port, a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port);
|
||||
|
||||
switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->cur_payload_map->remote_sdp_port);
|
||||
switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_IP_VARIABLE, a_engine->cur_payload_map->remote_sdp_ip);
|
||||
switch_channel_set_variable(session->channel, SWITCH_REMOTE_MEDIA_PORT_VARIABLE, tmp);
|
||||
|
||||
if (switch_rtp_set_remote_address(a_engine->rtp_session, a_engine->cur_payload_map->remote_sdp_ip,
|
||||
a_engine->cur_payload_map->remote_sdp_port, 0, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err);
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
|
||||
}
|
||||
|
||||
switch_core_media_check_autoadj(session);
|
||||
}
|
||||
|
||||
|
||||
|
||||
switch_core_media_copy_t38_options(t38_options, other_session);
|
||||
|
||||
switch_channel_set_flag(smh->session->channel, CF_T38_PASSTHRU);
|
||||
switch_channel_set_flag(other_session->channel, CF_T38_PASSTHRU);
|
||||
|
||||
msg = switch_core_session_alloc(other_session, sizeof(*msg));
|
||||
msg->message_id = SWITCH_MESSAGE_INDICATE_REQUEST_IMAGE_MEDIA;
|
||||
msg->from = __FILE__;
|
||||
msg->string_arg = switch_core_session_strdup(other_session, r_sdp);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Passing T38 req to other leg.\n%s\n", r_sdp);
|
||||
switch_core_session_queue_message(other_session, msg);
|
||||
switch_core_session_rwunlock(other_session);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* do nothing here, mod_fax will trigger a response (if it's listening =/) */
|
||||
match = 1;
|
||||
goto done;
|
||||
} else if (m->m_type == sdp_media_audio && m->m_port && got_audio && got_savp) {
|
||||
a_engine->reject_avp = 1;
|
||||
} else if (m->m_type == sdp_media_audio && m->m_port && !got_audio) {
|
||||
@@ -4074,6 +4005,9 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
|
||||
|
||||
if (!sendonly && (m->m_mode == sdp_sendonly || m->m_mode == sdp_inactive)) {
|
||||
sendonly = 1;
|
||||
if (m->m_mode == sdp_inactive) {
|
||||
inactive = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sendonly && m->m_connections && m->m_connections->c_address && !strcmp(m->m_connections->c_address, "0.0.0.0")) {
|
||||
@@ -4093,6 +4027,10 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
|
||||
switch_channel_set_variable(smh->session->channel, "audio_media_flow", "recvonly");
|
||||
a_engine->smode = SWITCH_MEDIA_FLOW_RECVONLY;
|
||||
break;
|
||||
case SWITCH_MEDIA_FLOW_INACTIVE:
|
||||
switch_channel_set_variable(smh->session->channel, "audio_media_flow", "inactive");
|
||||
a_engine->smode = SWITCH_MEDIA_FLOW_INACTIVE;
|
||||
break;
|
||||
default:
|
||||
switch_channel_set_variable(smh->session->channel, "audio_media_flow", "sendrecv");
|
||||
a_engine->smode = SWITCH_MEDIA_FLOW_SENDRECV;
|
||||
@@ -4112,7 +4050,6 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
|
||||
sendonly = 1;
|
||||
switch_channel_set_variable(session->channel, "media_audio_mode", "recvonly");
|
||||
} else if (sendonly < 2 && !strcasecmp(attr->a_name, "inactive")) {
|
||||
sendonly = 1;
|
||||
switch_channel_set_variable(session->channel, "media_audio_mode", "inactive");
|
||||
} else if (!strcasecmp(attr->a_name, "recvonly")) {
|
||||
switch_channel_set_variable(session->channel, "media_audio_mode", "sendonly");
|
||||
@@ -4140,12 +4077,19 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
|
||||
}
|
||||
|
||||
|
||||
if (sendonly != 1 && recvonly != 1) {
|
||||
if (sendonly != 1 && recvonly != 1 && inactive != 1) {
|
||||
switch_channel_set_variable(session->channel, "media_audio_mode", NULL);
|
||||
}
|
||||
|
||||
if (sdp_type == SDP_TYPE_RESPONSE) {
|
||||
if (sendonly) {
|
||||
if (inactive) {
|
||||
// When freeswitch had previously sent inactive in sip request. it should remain inactive otherwise smode should be sendrecv
|
||||
if (a_engine->smode==SWITCH_MEDIA_FLOW_INACTIVE) {
|
||||
a_engine->smode = sdp_media_flow(sdp_inactive);
|
||||
} else {
|
||||
a_engine->smode = sdp_media_flow(sdp_sendrecv);
|
||||
}
|
||||
} else if (sendonly) {
|
||||
a_engine->smode = sdp_media_flow(sdp_sendonly);
|
||||
} else if (recvonly) {
|
||||
a_engine->smode = sdp_media_flow(sdp_recvonly);
|
||||
@@ -4158,48 +4102,15 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
|
||||
&& switch_true(val)))
|
||||
&& !smh->mparams->hold_laps) {
|
||||
smh->mparams->hold_laps++;
|
||||
if (switch_core_media_toggle_hold(session, sendonly)) {
|
||||
reneg = switch_media_handle_test_media_flag(smh, SCMF_RENEG_ON_HOLD);
|
||||
if ((val = switch_channel_get_variable(session->channel, "rtp_renegotiate_codec_on_hold"))) {
|
||||
reneg = switch_true(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (reneg) {
|
||||
reneg = switch_media_handle_test_media_flag(smh, SCMF_RENEG_ON_REINVITE);
|
||||
|
||||
if ((val = switch_channel_get_variable(session->channel, "rtp_renegotiate_codec_on_reinvite"))) {
|
||||
reneg = switch_true(val);
|
||||
}
|
||||
}
|
||||
|
||||
if (session->bugs) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
|
||||
"Session is connected to a media bug. "
|
||||
"Re-Negotiation implicitly disabled.\n");
|
||||
reneg = 0;
|
||||
}
|
||||
|
||||
if (switch_channel_test_flag(session->channel, CF_RECOVERING)) {
|
||||
reneg = 0;
|
||||
}
|
||||
|
||||
if (sdp_type == SDP_TYPE_RESPONSE && smh->num_negotiated_codecs) {
|
||||
/* response to re-invite or update, only negotiated codecs are valid */
|
||||
reneg = 0;
|
||||
switch_core_media_toggle_hold(session, sendonly);
|
||||
}
|
||||
|
||||
|
||||
if (!reneg && smh->num_negotiated_codecs) {
|
||||
codec_array = smh->negotiated_codecs;
|
||||
total_codecs = smh->num_negotiated_codecs;
|
||||
} else if (reneg) {
|
||||
smh->mparams->num_codecs = 0;
|
||||
switch_core_media_prepare_codecs(session, SWITCH_FALSE);
|
||||
codec_array = smh->codecs;
|
||||
total_codecs = smh->mparams->num_codecs;
|
||||
}
|
||||
smh->mparams->num_codecs = 0;
|
||||
smh->num_negotiated_codecs = 0;
|
||||
switch_core_media_prepare_codecs(session, SWITCH_TRUE);
|
||||
codec_array = smh->codecs;
|
||||
total_codecs = smh->mparams->num_codecs;
|
||||
|
||||
|
||||
if (switch_rtp_has_dtls() && dtls_ok(session)) {
|
||||
@@ -4261,7 +4172,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
|
||||
}
|
||||
|
||||
x = 0;
|
||||
|
||||
|
||||
for (map = m->m_rtpmaps; map; map = map->rm_next) {
|
||||
int32_t i;
|
||||
const char *rm_encoding;
|
||||
@@ -4493,7 +4404,6 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
|
||||
|
||||
match = 1;
|
||||
a_engine->codec_negotiated = 1;
|
||||
smh->num_negotiated_codecs = 0;
|
||||
|
||||
for(j = 0; j < m_idx; j++) {
|
||||
payload_map_t *pmap = switch_core_media_add_payload_map(session,
|
||||
@@ -4552,6 +4462,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
|
||||
pmap->rm_fmtp = switch_core_session_strdup(session, (char *) mmap->rm_fmtp);
|
||||
|
||||
pmap->agreed_pt = (switch_payload_t) mmap->rm_pt;
|
||||
|
||||
smh->negotiated_codecs[smh->num_negotiated_codecs++] = mimp;
|
||||
pmap->recv_pt = (switch_payload_t)mmap->rm_pt;
|
||||
|
||||
@@ -4585,14 +4496,6 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
if (!switch_true(mirror) &&
|
||||
switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND &&
|
||||
(!switch_channel_test_flag(session->channel, CF_REINVITE) || switch_media_handle_test_media_flag(smh, SCMF_RENEG_ON_REINVITE))) {
|
||||
switch_core_media_get_offered_pt(session, matches[0].imp, &a_engine->cur_payload_map->recv_pt);
|
||||
}
|
||||
#endif
|
||||
|
||||
switch_snprintf(tmp, sizeof(tmp), "%d", a_engine->cur_payload_map->recv_pt);
|
||||
switch_channel_set_variable(session->channel, "rtp_audio_recv_pt", tmp);
|
||||
|
||||
@@ -4759,6 +4662,10 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
|
||||
switch_channel_set_variable(smh->session->channel, "video_media_flow", "recvonly");
|
||||
v_engine->smode = SWITCH_MEDIA_FLOW_RECVONLY;
|
||||
break;
|
||||
case SWITCH_MEDIA_FLOW_INACTIVE:
|
||||
switch_channel_set_variable(smh->session->channel, "video_media_flow", "inactive");
|
||||
v_engine->smode = SWITCH_MEDIA_FLOW_INACTIVE;
|
||||
break;
|
||||
default:
|
||||
switch_channel_set_variable(smh->session->channel, "video_media_flow", "sendrecv");
|
||||
v_engine->smode = SWITCH_MEDIA_FLOW_SENDRECV;
|
||||
@@ -4836,10 +4743,11 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
|
||||
if (!(rm_encoding = map->rm_encoding)) {
|
||||
rm_encoding = "";
|
||||
}
|
||||
printf("WTF TOT %d\n", total_codecs);
|
||||
|
||||
for (i = 0; i < total_codecs; i++) {
|
||||
const switch_codec_implementation_t *imp = codec_array[i];
|
||||
|
||||
|
||||
if (imp->codec_type != SWITCH_CODEC_TYPE_VIDEO) {
|
||||
continue;
|
||||
}
|
||||
@@ -4849,7 +4757,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
|
||||
continue;
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CONSOLE, "Video Codec Compare [%s:%d]/[%s:%d]\n",
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Video Codec Compare [%s:%d]/[%s:%d]\n",
|
||||
rm_encoding, map->rm_pt, imp->iananame, imp->ianacode);
|
||||
if ((zstr(map->rm_encoding) || (smh->mparams->ndlb & SM_NDLB_ALLOW_BAD_IANANAME)) && map->rm_pt < 96) {
|
||||
vmatch = (map->rm_pt == imp->ianacode) ? 1 : 0;
|
||||
@@ -4873,9 +4781,10 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
|
||||
matches[m_idx].imp = imp;
|
||||
matches[m_idx].map = map;
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CONSOLE, "Video Codec Compare [%s:%d] +++ is saved as a match\n",
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Video Codec Compare [%s:%d] +++ is saved as a match\n",
|
||||
imp->iananame, map->rm_pt);
|
||||
m_idx++;
|
||||
|
||||
m_idx++;
|
||||
}
|
||||
|
||||
vmatch = 0;
|
||||
@@ -5255,7 +5164,7 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void
|
||||
switch_core_media_gen_key_frame(session);
|
||||
|
||||
|
||||
if (smh->video_write_fh->mm.source_fps) {
|
||||
if (smh->video_write_fh && smh->video_write_fh->mm.source_fps) {
|
||||
fps = (int) smh->video_write_fh->mm.source_fps;
|
||||
} else {
|
||||
fps = video_globals.fps;
|
||||
@@ -5758,6 +5667,24 @@ SWITCH_DECLARE(switch_bool_t) switch_core_session_in_video_thread(switch_core_se
|
||||
}
|
||||
|
||||
|
||||
SWITCH_DECLARE(void) switch_core_media_parse_media_flags(switch_core_session_t *session)
|
||||
{
|
||||
const char *var;
|
||||
switch_media_handle_t *smh;
|
||||
|
||||
if (!(smh = session->media_handle)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((var = switch_channel_get_variable(session->channel, "rtp_media_autofix_timing"))) {
|
||||
if (switch_true(var)) {
|
||||
switch_media_handle_set_media_flag(smh, SCMF_AUTOFIX_TIMING);
|
||||
} else {
|
||||
switch_media_handle_clear_media_flag(smh, SCMF_AUTOFIX_TIMING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//?
|
||||
#define RA_PTR_LEN 512
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_media_proxy_remote_addr(switch_core_session_t *session, const char *sdp_str)
|
||||
@@ -6134,6 +6061,16 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_choose_port(switch_core_sessio
|
||||
use_ip = smh->mparams->rtpip;
|
||||
}
|
||||
|
||||
if (zstr(smh->mparams->remote_ip)) { /* no remote_ip, we're originating */
|
||||
if (!zstr(smh->mparams->extrtpip)) { /* and we've got an ext-rtp-ip, eg, from verto config */
|
||||
use_ip = smh->mparams->extrtpip; /* let's use it for composing local sdp to send to client */
|
||||
/*
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,
|
||||
"%s will use %s instead of %s in SDP, because we're originating and we have an ext-rtp-ip setting\n",
|
||||
switch_channel_get_name(smh->session->channel), smh->mparams->extrtpip, smh->mparams->rtpip);
|
||||
*/
|
||||
}
|
||||
}
|
||||
engine->adv_sdp_port = sdp_port;
|
||||
engine->adv_sdp_ip = smh->mparams->adv_sdp_audio_ip = smh->mparams->extrtpip = switch_core_session_strdup(session, use_ip);
|
||||
|
||||
@@ -6392,6 +6329,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
switch_core_media_parse_media_flags(session);
|
||||
|
||||
if (switch_rtp_ready(a_engine->rtp_session)) {
|
||||
switch_rtp_reset_media_timer(a_engine->rtp_session);
|
||||
@@ -6525,9 +6463,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "AUDIO RTP CHANGING DEST TO: [%s:%d]\n",
|
||||
a_engine->cur_payload_map->remote_sdp_ip, a_engine->cur_payload_map->remote_sdp_port);
|
||||
|
||||
if (switch_channel_test_flag(session->channel, CF_PROTO_HOLD) && strcmp(a_engine->cur_payload_map->remote_sdp_ip, "0.0.0.0")) {
|
||||
switch_core_media_toggle_hold(session, 0);
|
||||
}
|
||||
//if (switch_channel_test_flag(session->channel, CF_PROTO_HOLD) && strcmp(a_engine->cur_payload_map->remote_sdp_ip, "0.0.0.0")) {
|
||||
// switch_core_media_toggle_hold(session, 0);
|
||||
//}
|
||||
|
||||
|
||||
if (!switch_media_handle_test_media_flag(smh, SCMF_DISABLE_RTP_AUTOADJ) &&
|
||||
@@ -7099,8 +7037,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
|
||||
|
||||
if (v_engine->ice_in.cands[v_engine->ice_in.chosen[1]][1].ready) {
|
||||
|
||||
if (v_engine->rtcp_mux > 0 && !strcmp(v_engine->ice_in.cands[v_engine->ice_in.chosen[1]][1].con_addr, v_engine->ice_in.cands[v_engine->ice_in.chosen[0]][0].con_addr)
|
||||
&& v_engine->ice_in.cands[v_engine->ice_in.chosen[1]][1].con_port == v_engine->ice_in.cands[v_engine->ice_in.chosen[0]][0].con_port) {
|
||||
if (v_engine->rtcp_mux > 0 && v_engine->ice_in.cands[v_engine->ice_in.chosen[0]][0].ready &&
|
||||
!strcmp(v_engine->ice_in.cands[v_engine->ice_in.chosen[1]][1].con_addr,
|
||||
v_engine->ice_in.cands[v_engine->ice_in.chosen[0]][0].con_addr) &&
|
||||
v_engine->ice_in.cands[v_engine->ice_in.chosen[1]][1].con_port == v_engine->ice_in.cands[v_engine->ice_in.chosen[0]][0].con_port) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Skipping VIDEO RTCP ICE (Same as VIDEO RTP)\n");
|
||||
} else {
|
||||
|
||||
@@ -7410,7 +7350,7 @@ static void generate_m(switch_core_session_t *session, char *buf, size_t buflen,
|
||||
}
|
||||
|
||||
if (!zstr(a_engine->local_dtls_fingerprint.type) && secure) {
|
||||
switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=fingerprint:%s %s\na=setup:%s\r\n", a_engine->local_dtls_fingerprint.type,
|
||||
switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=fingerprint:%s %s\r\na=setup:%s\r\n", a_engine->local_dtls_fingerprint.type,
|
||||
a_engine->local_dtls_fingerprint.str, get_setup(a_engine, session, sdp_type));
|
||||
}
|
||||
|
||||
@@ -7704,7 +7644,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
|
||||
int is_outbound = switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND;
|
||||
const char *vbw;
|
||||
int bw = 256;
|
||||
uint8_t fir = 0, nack = 0, pli = 0, tmmbr = 0;
|
||||
uint8_t fir = 0, nack = 0, pli = 0, tmmbr = 0, has_vid = 0;
|
||||
|
||||
switch_assert(session);
|
||||
|
||||
@@ -7749,6 +7689,10 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
|
||||
smh->mparams->rtcp_video_interval_msec = SWITCH_RTCP_VIDEO_INTERVAL_MSEC;
|
||||
}
|
||||
|
||||
if (switch_true(switch_channel_get_variable(session->channel, "add_ice_candidates"))) {
|
||||
switch_channel_set_flag(session->channel, CF_ICE);
|
||||
}
|
||||
|
||||
if ( switch_rtp_has_dtls() && dtls_ok(session)) {
|
||||
if (switch_channel_test_flag(session->channel, CF_AVPF) ||
|
||||
switch_true(switch_channel_get_variable(smh->session->channel, "rtp_use_dtls"))) {
|
||||
@@ -7940,12 +7884,14 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
|
||||
sr = "sendonly";
|
||||
} else if (a_engine->smode == SWITCH_MEDIA_FLOW_RECVONLY) {
|
||||
sr = "recvonly";
|
||||
} else if (a_engine->smode == SWITCH_MEDIA_FLOW_INACTIVE) {
|
||||
sr = "inactive";
|
||||
} else {
|
||||
sr = "sendrecv";
|
||||
}
|
||||
|
||||
if ((var_val = switch_channel_get_variable(session->channel, "origination_audio_mode"))) {
|
||||
if (!strcasecmp(sr, "sendonly") || !strcasecmp(sr, "recvonly") || !strcasecmp(sr, "sendrecv")) {
|
||||
if (!strcasecmp(sr, "sendonly") || !strcasecmp(sr, "recvonly") || !strcasecmp(sr, "sendrecv") || !strcasecmp(sr, "inactive")) {
|
||||
sr = var_val;
|
||||
}
|
||||
switch_channel_set_variable(session->channel, "origination_audio_mode", NULL);
|
||||
@@ -8073,7 +8019,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
|
||||
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d telephone-event/%d\r\n",
|
||||
smh->mparams->te, smh->mparams->te_rate);
|
||||
} else {
|
||||
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d telephone-event/%d\na=fmtp:%d 0-16\r\n",
|
||||
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d telephone-event/%d\r\na=fmtp:%d 0-16\r\n",
|
||||
smh->mparams->te, smh->mparams->te_rate, smh->mparams->te);
|
||||
}
|
||||
}
|
||||
@@ -8290,9 +8236,34 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
|
||||
|
||||
}
|
||||
|
||||
if (switch_channel_test_flag(session->channel, CF_IMAGE_SDP)) {
|
||||
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "m=image 0 UDPTL T38\r\n", SWITCH_VA_NONE);
|
||||
|
||||
}
|
||||
|
||||
|
||||
video:
|
||||
|
||||
if (!switch_channel_test_flag(session->channel, CF_VIDEO_POSSIBLE)) {
|
||||
|
||||
if (!switch_channel_test_flag(session->channel, CF_VIDEO_POSSIBLE) && switch_media_handle_test_media_flag(smh, SCMF_RECV_SDP)) {
|
||||
has_vid = 0;
|
||||
} else {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < smh->mparams->num_codecs; i++) {
|
||||
const switch_codec_implementation_t *imp = smh->codecs[i];
|
||||
|
||||
|
||||
if (imp->codec_type == SWITCH_CODEC_TYPE_VIDEO) {
|
||||
has_vid = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (!has_vid) {
|
||||
if (switch_channel_test_flag(session->channel, CF_VIDEO_SDP_RECVD)) {
|
||||
switch_channel_clear_flag(session->channel, CF_VIDEO_SDP_RECVD);
|
||||
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "m=video 0 %s 19\r\n",
|
||||
@@ -8385,6 +8356,24 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
|
||||
}
|
||||
|
||||
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "\r\n");
|
||||
|
||||
|
||||
if (!(vbw = switch_channel_get_variable(smh->session->channel, "rtp_video_max_bandwidth"))) {
|
||||
vbw = switch_channel_get_variable(smh->session->channel, "rtp_video_max_bandwidth_in");
|
||||
}
|
||||
|
||||
if (!vbw) {
|
||||
vbw = "1mb";
|
||||
}
|
||||
|
||||
bw = switch_parse_bandwidth_string(vbw);
|
||||
|
||||
if (bw > 0) {
|
||||
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "b=AS:%d\r\n", bw);
|
||||
//switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "b=TIAS:%d\r\n", bw);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (v_engine->codec_negotiated) {
|
||||
const char *of;
|
||||
@@ -8452,6 +8441,8 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
|
||||
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "%s", "a=sendonly\r\n");
|
||||
} else if (v_engine->smode == SWITCH_MEDIA_FLOW_RECVONLY) {
|
||||
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "%s", "a=recvonly\r\n");
|
||||
} else if (v_engine->smode == SWITCH_MEDIA_FLOW_INACTIVE) {
|
||||
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "%s", "a=inactive\r\n");
|
||||
}
|
||||
|
||||
} else if (smh->mparams->num_codecs) {
|
||||
@@ -8537,8 +8528,8 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
|
||||
|
||||
|
||||
if (!zstr(v_engine->local_dtls_fingerprint.type)) {
|
||||
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=fingerprint:%s %s\na=setup:%s\r\n", v_engine->local_dtls_fingerprint.type,
|
||||
v_engine->local_dtls_fingerprint.str, get_setup(v_engine, session, sdp_type));
|
||||
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=fingerprint:%s %s\r\na=setup:%s\r\n",
|
||||
v_engine->local_dtls_fingerprint.type, v_engine->local_dtls_fingerprint.str, get_setup(v_engine, session, sdp_type));
|
||||
}
|
||||
|
||||
|
||||
@@ -8551,22 +8542,6 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!(vbw = switch_channel_get_variable(smh->session->channel, "rtp_video_max_bandwidth"))) {
|
||||
vbw = switch_channel_get_variable(smh->session->channel, "rtp_video_max_bandwidth_in");
|
||||
}
|
||||
|
||||
if (!vbw) {
|
||||
vbw = "1mb";
|
||||
}
|
||||
|
||||
bw = switch_parse_bandwidth_string(vbw);
|
||||
|
||||
if (bw > 0) {
|
||||
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "b=AS:%d\r\n", bw);
|
||||
//switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "b=TIAS:%d\r\n", bw);
|
||||
}
|
||||
|
||||
if (sdp_type == SDP_TYPE_REQUEST) {
|
||||
fir++;
|
||||
pli++;
|
||||
@@ -8826,6 +8801,7 @@ SWITCH_DECLARE(void) switch_core_media_set_udptl_image_sdp(switch_core_session_t
|
||||
|
||||
a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
|
||||
|
||||
switch_channel_clear_flag(session->channel, CF_IMAGE_SDP);
|
||||
|
||||
switch_assert(t38_options);
|
||||
|
||||
@@ -9837,8 +9813,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se
|
||||
switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 1);
|
||||
}
|
||||
|
||||
switch_media_handle_set_media_flag(smh, SCMF_RENEG_ON_REINVITE);
|
||||
|
||||
if (msg->numeric_arg && switch_core_session_get_partner(session, &nsession) == SWITCH_STATUS_SUCCESS) {
|
||||
msg->numeric_arg = 0;
|
||||
switch_core_session_receive_message(nsession, msg);
|
||||
@@ -11222,8 +11196,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_encoded_video_frame(sw
|
||||
switch_io_event_hook_video_write_frame_t *ptr;
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
|
||||
if (switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG3, "Writing video to RECVONLY session\n");
|
||||
if (switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG3, "Writing video to RECVONLY/INACTIVE session\n");
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -11293,8 +11267,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if (switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG3, "Writing video to RECVONLY session\n");
|
||||
if (switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG3, "Writing video to RECVONLY/INACTIVE session\n");
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -11524,6 +11498,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_video_frame(switch_core
|
||||
switch_io_event_hook_video_read_frame_t *ptr;
|
||||
uint32_t loops = 0;
|
||||
switch_media_handle_t *smh;
|
||||
int patchers = 0;
|
||||
|
||||
switch_assert(session != NULL);
|
||||
|
||||
@@ -11679,7 +11654,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_video_frame(switch_core
|
||||
|
||||
|
||||
if (bp->callback && switch_test_flag(bp, SMBF_READ_VIDEO_PING)) {
|
||||
if (switch_test_flag(bp, SMBF_READ_VIDEO_PATCH)) {
|
||||
patchers++;
|
||||
}
|
||||
|
||||
bp->video_ping_frame = *frame;
|
||||
|
||||
if (bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_READ_VIDEO_PING) == SWITCH_FALSE
|
||||
|| (bp->stop_time && bp->stop_time <= switch_epoch_time_now(NULL))) {
|
||||
ok = SWITCH_FALSE;
|
||||
@@ -11705,7 +11685,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_video_frame(switch_core
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ((*frame) && (*frame)->codec) {
|
||||
if (patchers) {
|
||||
switch_set_flag((*frame)->codec, SWITCH_CODEC_FLAG_VIDEO_PATCHING);
|
||||
} else {
|
||||
switch_clear_flag((*frame)->codec, SWITCH_CODEC_FLAG_VIDEO_PATCHING);
|
||||
}
|
||||
}
|
||||
|
||||
if (status == SWITCH_STATUS_SUCCESS) {
|
||||
switch_core_session_video_read_callback(session, *frame);
|
||||
|
||||
@@ -2031,7 +2031,7 @@ static inline uint32_t switch_img_fmt2fourcc(switch_img_fmt_t fmt)
|
||||
}
|
||||
#endif
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_img_to_raw(switch_image_t *src, void *dest, switch_size_t size, switch_img_fmt_t fmt)
|
||||
SWITCH_DECLARE(switch_status_t) switch_img_to_raw(switch_image_t *src, void *dest, int stride, switch_img_fmt_t fmt)
|
||||
{
|
||||
#ifdef SWITCH_HAVE_YUV
|
||||
uint32_t fourcc;
|
||||
@@ -2050,7 +2050,7 @@ SWITCH_DECLARE(switch_status_t) switch_img_to_raw(switch_image_t *src, void *des
|
||||
ret = ConvertFromI420(src->planes[0], src->stride[0],
|
||||
src->planes[1], src->stride[1],
|
||||
src->planes[2], src->stride[2],
|
||||
dest, size,
|
||||
dest, stride,
|
||||
src->d_w, src->d_h,
|
||||
fourcc);
|
||||
|
||||
|
||||
@@ -2752,6 +2752,7 @@ static void unsub_all_switch_event_channel(void)
|
||||
free(head);
|
||||
}
|
||||
|
||||
switch_safe_free(hi);
|
||||
switch_thread_rwlock_unlock(event_channel_manager.rwlock);
|
||||
}
|
||||
|
||||
|
||||
@@ -1759,9 +1759,18 @@ static void *SWITCH_THREAD_FUNC early_thread_run(switch_thread_t *thread, void *
|
||||
switch_codec_implementation_t read_impl = { 0 };
|
||||
|
||||
for (i = 0; i < MAX_PEERS && i < state->ttl; i++) {
|
||||
if (switch_core_session_read_lock(state->originate_status[i].peer_session) == SWITCH_STATUS_SUCCESS) {
|
||||
originate_status[i].peer_session = state->originate_status[i].peer_session;
|
||||
originate_status[i].peer_channel = switch_core_session_get_channel(state->originate_status[i].peer_session);
|
||||
switch_core_session_t *session = state->originate_status[i].peer_session;
|
||||
switch_channel_t *channel = NULL;
|
||||
|
||||
if (session) channel = switch_core_session_get_channel(session);
|
||||
|
||||
if (!session || !channel || !switch_channel_up(channel)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (switch_core_session_read_lock(session) == SWITCH_STATUS_SUCCESS) {
|
||||
originate_status[i].peer_session = session;
|
||||
originate_status[i].peer_channel = channel;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2111,6 +2111,259 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_wait_for_silence(switch_core_session_
|
||||
return status;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_detect_audio(switch_core_session_t *session, uint32_t thresh,
|
||||
uint32_t audio_hits, uint32_t timeout_ms, const char *file)
|
||||
{
|
||||
uint32_t score, count = 0, j = 0;
|
||||
double energy = 0;
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
int divisor = 0;
|
||||
uint32_t channels;
|
||||
switch_frame_t *read_frame;
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
int16_t *data;
|
||||
uint32_t hits = 0;
|
||||
switch_codec_t raw_codec = { 0 };
|
||||
int16_t *abuf = NULL;
|
||||
switch_frame_t write_frame = { 0 };
|
||||
switch_file_handle_t fh = { 0 };
|
||||
int32_t sample_count = 0;
|
||||
switch_codec_implementation_t read_impl = { 0 };
|
||||
switch_core_session_get_read_impl(session, &read_impl);
|
||||
|
||||
if (timeout_ms) {
|
||||
sample_count = (read_impl.actual_samples_per_second / 1000) * timeout_ms;
|
||||
}
|
||||
|
||||
if (file) {
|
||||
if (switch_core_file_open(&fh,
|
||||
file,
|
||||
read_impl.number_of_channels,
|
||||
read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_core_session_reset(session, SWITCH_TRUE, SWITCH_FALSE);
|
||||
return SWITCH_STATUS_NOTFOUND;
|
||||
}
|
||||
switch_zmalloc(abuf, SWITCH_RECOMMENDED_BUFFER_SIZE);
|
||||
write_frame.data = abuf;
|
||||
write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
|
||||
if (switch_core_codec_init(&raw_codec,
|
||||
"L16",
|
||||
NULL,
|
||||
NULL,
|
||||
read_impl.actual_samples_per_second,
|
||||
read_impl.microseconds_per_packet / 1000,
|
||||
1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
|
||||
NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
|
||||
|
||||
status = SWITCH_STATUS_FALSE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
write_frame.codec = &raw_codec;
|
||||
|
||||
divisor = read_impl.actual_samples_per_second / 8000;
|
||||
channels = read_impl.number_of_channels;
|
||||
|
||||
switch_core_session_set_read_codec(session, &raw_codec);
|
||||
|
||||
while (switch_channel_ready(channel)) {
|
||||
|
||||
status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
|
||||
|
||||
if (!SWITCH_READ_ACCEPTABLE(status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (sample_count) {
|
||||
sample_count -= raw_codec.implementation->samples_per_packet;
|
||||
if (sample_count <= 0) {
|
||||
switch_channel_set_variable(channel, "detect_audio_timeout", "true");
|
||||
switch_channel_set_variable_printf(channel, "detect_audio_hits", "%d", hits);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "switch_ivr_detect_audio: TIMEOUT %d hits\n", hits);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (abuf) {
|
||||
switch_size_t olen = raw_codec.implementation->samples_per_packet;
|
||||
|
||||
if (switch_core_file_read(&fh, abuf, &olen) != SWITCH_STATUS_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
|
||||
write_frame.samples = (uint32_t) olen;
|
||||
write_frame.datalen = (uint32_t) (olen * sizeof(int16_t) * fh.channels);
|
||||
if ((status = switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0)) != SWITCH_STATUS_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
data = (int16_t *) read_frame->data;
|
||||
|
||||
for (energy = 0, j = 0, count = 0; count < read_frame->samples; count++) {
|
||||
energy += abs(data[j++]);
|
||||
j += channels;
|
||||
}
|
||||
|
||||
score = (uint32_t) (energy / (read_frame->samples / divisor));
|
||||
|
||||
if (score >= thresh) {
|
||||
hits++;
|
||||
} else {
|
||||
hits=0;
|
||||
}
|
||||
|
||||
if (hits > audio_hits) {
|
||||
switch_channel_set_variable(channel, "detect_audio_timeout", "false");
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "switch_ivr_detect_audio: AUDIO DETECTED\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch_core_session_reset(session, SWITCH_FALSE, SWITCH_TRUE);
|
||||
switch_core_codec_destroy(&raw_codec);
|
||||
|
||||
end:
|
||||
|
||||
if (abuf) {
|
||||
|
||||
switch_core_file_close(&fh);
|
||||
free(abuf);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_detect_silence(switch_core_session_t *session, uint32_t thresh,
|
||||
uint32_t silence_hits, uint32_t timeout_ms, const char *file)
|
||||
{
|
||||
uint32_t score, count = 0, j = 0;
|
||||
double energy = 0;
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
int divisor = 0;
|
||||
uint32_t channels;
|
||||
switch_frame_t *read_frame;
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
int16_t *data;
|
||||
uint32_t hits = 0;
|
||||
switch_codec_t raw_codec = { 0 };
|
||||
int16_t *abuf = NULL;
|
||||
switch_frame_t write_frame = { 0 };
|
||||
switch_file_handle_t fh = { 0 };
|
||||
int32_t sample_count = 0;
|
||||
switch_codec_implementation_t read_impl = { 0 };
|
||||
switch_core_session_get_read_impl(session, &read_impl);
|
||||
|
||||
|
||||
if (timeout_ms) {
|
||||
sample_count = (read_impl.actual_samples_per_second / 1000) * timeout_ms;
|
||||
}
|
||||
|
||||
if (file) {
|
||||
if (switch_core_file_open(&fh,
|
||||
file,
|
||||
read_impl.number_of_channels,
|
||||
read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_core_session_reset(session, SWITCH_TRUE, SWITCH_FALSE);
|
||||
return SWITCH_STATUS_NOTFOUND;
|
||||
}
|
||||
switch_zmalloc(abuf, SWITCH_RECOMMENDED_BUFFER_SIZE);
|
||||
write_frame.data = abuf;
|
||||
write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
|
||||
if (switch_core_codec_init(&raw_codec,
|
||||
"L16",
|
||||
NULL,
|
||||
NULL,
|
||||
read_impl.actual_samples_per_second,
|
||||
read_impl.microseconds_per_packet / 1000,
|
||||
1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
|
||||
NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
|
||||
|
||||
status = SWITCH_STATUS_FALSE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
write_frame.codec = &raw_codec;
|
||||
|
||||
divisor = read_impl.actual_samples_per_second / 8000;
|
||||
channels = read_impl.number_of_channels;
|
||||
|
||||
switch_core_session_set_read_codec(session, &raw_codec);
|
||||
|
||||
while (switch_channel_ready(channel)) {
|
||||
|
||||
status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
|
||||
|
||||
if (!SWITCH_READ_ACCEPTABLE(status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (sample_count) {
|
||||
sample_count -= raw_codec.implementation->samples_per_packet;
|
||||
if (sample_count <= 0) {
|
||||
switch_channel_set_variable(channel, "detect_silence_timeout", "true");
|
||||
switch_channel_set_variable_printf(channel, "detect_silence_hits", "%d", hits);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "switch_ivr_detect_silence: TIMEOUT %d hits\n", hits);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (abuf) {
|
||||
switch_size_t olen = raw_codec.implementation->samples_per_packet;
|
||||
|
||||
if (switch_core_file_read(&fh, abuf, &olen) != SWITCH_STATUS_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
|
||||
write_frame.samples = (uint32_t) olen;
|
||||
write_frame.datalen = (uint32_t) (olen * sizeof(int16_t) * fh.channels);
|
||||
if ((status = switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0)) != SWITCH_STATUS_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
data = (int16_t *) read_frame->data;
|
||||
|
||||
for (energy = 0, j = 0, count = 0; count < read_frame->samples; count++) {
|
||||
energy += abs(data[j++]);
|
||||
j += channels;
|
||||
}
|
||||
|
||||
score = (uint32_t) (energy / (read_frame->samples / divisor));
|
||||
|
||||
if (score <= thresh) {
|
||||
hits++;
|
||||
} else {
|
||||
hits=0;
|
||||
}
|
||||
|
||||
if (hits > silence_hits) {
|
||||
switch_channel_set_variable(channel, "detect_silence_timeout", "false");
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "switch_ivr_detect_silence: SILENCE DETECTED\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch_core_session_reset(session, SWITCH_FALSE, SWITCH_TRUE);
|
||||
switch_core_codec_destroy(&raw_codec);
|
||||
|
||||
end:
|
||||
|
||||
if (abuf) {
|
||||
|
||||
switch_core_file_close(&fh);
|
||||
free(abuf);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_ivr_read(switch_core_session_t *session,
|
||||
uint32_t min_digits,
|
||||
uint32_t max_digits,
|
||||
|
||||
@@ -902,10 +902,10 @@ SWITCH_DECLARE(switch_status_t) switch_jb_peek_frame(switch_jb_t *jb, uint32_t t
|
||||
frame->seq = ntohs(node->packet.header.seq);
|
||||
frame->timestamp = ntohl(node->packet.header.ts);
|
||||
frame->m = node->packet.header.m;
|
||||
frame->datalen = node->len;
|
||||
frame->datalen = node->len - 12;
|
||||
|
||||
if (frame->data && frame->buflen > node->len) {
|
||||
memcpy(frame->data, node->packet.body, node->len);
|
||||
if (frame->data && frame->buflen > node->len - 12) {
|
||||
memcpy(frame->data, node->packet.body, node->len - 12);
|
||||
}
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
@@ -1039,7 +1039,7 @@ SWITCH_DECLARE(uint32_t) switch_jb_pop_nack(switch_jb_t *jb)
|
||||
|
||||
top:
|
||||
|
||||
for (hi = switch_core_hash_first(jb->missing_seq_hash); hi; hi = switch_core_hash_next(&hi)) {
|
||||
for (hi = switch_core_hash_first_iter(jb->missing_seq_hash, hi); hi; hi = switch_core_hash_next(&hi)) {
|
||||
uint16_t seq;
|
||||
//const char *token;
|
||||
switch_time_t then = 0;
|
||||
@@ -1076,6 +1076,8 @@ SWITCH_DECLARE(uint32_t) switch_jb_pop_nack(switch_jb_t *jb)
|
||||
}
|
||||
}
|
||||
|
||||
switch_safe_free(hi);
|
||||
|
||||
if (least && switch_core_inthash_delete(jb->missing_seq_hash, (uint32_t)htons(least))) {
|
||||
jb_debug(jb, 3, "Found NACKABLE seq %u\n", least);
|
||||
nack = (uint32_t) htons(least);
|
||||
|
||||
+26
-16
@@ -452,6 +452,7 @@ struct switch_rtp {
|
||||
uint8_t has_ice;
|
||||
uint8_t punts;
|
||||
uint8_t clean;
|
||||
uint32_t last_max_vb_frames;
|
||||
#ifdef ENABLE_ZRTP
|
||||
zrtp_session_t *zrtp_session;
|
||||
zrtp_profile_t *zrtp_profile;
|
||||
@@ -2069,17 +2070,8 @@ static int check_rtcp_and_ice(switch_rtp_t *rtp_session)
|
||||
rtcp_generate_report_block(rtp_session, rtcp_report_block);
|
||||
|
||||
rtp_session->rtcp_send_msg.header.length = htons((uint16_t)(rtcp_bytes / 4) - 1);
|
||||
|
||||
if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) {
|
||||
//if (rtp_session->remote_ssrc == 0) {
|
||||
// rtp_session->remote_ssrc = rtp_session->stats.rtcp.peer_ssrc;
|
||||
//}
|
||||
|
||||
//if (rtp_session->remote_ssrc == 0) {
|
||||
// rtp_session->remote_ssrc = ntohl(rtp_session->last_rtp_hdr.ssrc);
|
||||
//}
|
||||
|
||||
|
||||
if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) {
|
||||
if (rtp_session->pli_count) {
|
||||
switch_rtcp_ext_hdr_t *ext_hdr;
|
||||
|
||||
@@ -2094,7 +2086,8 @@ static int check_rtcp_and_ice(switch_rtp_t *rtp_session)
|
||||
ext_hdr->send_ssrc = htonl(rtp_session->ssrc);
|
||||
ext_hdr->recv_ssrc = htonl(rtp_session->remote_ssrc);
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG1, "Sending RTCP PLI\n");
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG1, "Sending RTCP PLI %u %u\n",
|
||||
rtp_session->ssrc, rtp_session->remote_ssrc);
|
||||
|
||||
ext_hdr->length = htons((uint8_t)(sizeof(switch_rtcp_ext_hdr_t) / 4) - 1);
|
||||
rtcp_bytes += sizeof(switch_rtcp_ext_hdr_t);
|
||||
@@ -2927,7 +2920,6 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_remote_address(switch_rtp_t *rtp_
|
||||
switch_mutex_lock(rtp_session->write_mutex);
|
||||
|
||||
rtp_session->remote_addr = remote_addr;
|
||||
switch_cp_addr(rtp_session->rtp_from_addr, rtp_session->remote_addr);
|
||||
|
||||
if (change_adv_addr) {
|
||||
rtp_session->remote_host_str = switch_core_strdup(rtp_session->pool, host);
|
||||
@@ -3734,7 +3726,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_ssrc(switch_rtp_t *rtp_session, u
|
||||
SWITCH_DECLARE(switch_status_t) switch_rtp_set_remote_ssrc(switch_rtp_t *rtp_session, uint32_t ssrc)
|
||||
{
|
||||
rtp_session->remote_ssrc = ssrc;
|
||||
|
||||
rtp_session->flags[SWITCH_RTP_FLAG_DETECT_SSRC] = 0;
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -4005,6 +3997,7 @@ SWITCH_DECLARE(switch_rtp_t *) switch_rtp_new(const char *rx_host,
|
||||
rtp_session->rx_host = switch_core_strdup(rtp_session->pool, rx_host);
|
||||
rtp_session->rx_port = rx_port;
|
||||
switch_rtp_set_flag(rtp_session, SWITCH_RTP_FLAG_FLUSH);
|
||||
switch_rtp_set_flag(rtp_session, SWITCH_RTP_FLAG_DETECT_SSRC);
|
||||
} else {
|
||||
switch_rtp_release_port(rx_host, rx_port);
|
||||
}
|
||||
@@ -4106,9 +4099,15 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_video_buffer_size(switch_rtp_t *r
|
||||
}
|
||||
|
||||
if (!max_frames) {
|
||||
max_frames = 50;
|
||||
max_frames = rtp_session->last_max_vb_frames;
|
||||
}
|
||||
|
||||
if (!max_frames || frames >= max_frames) {
|
||||
max_frames = frames + 8;
|
||||
}
|
||||
|
||||
rtp_session->last_max_vb_frames = max_frames;
|
||||
|
||||
if (!rtp_session->vb) {
|
||||
switch_jb_create(&rtp_session->vb, SJB_VIDEO, frames, max_frames, rtp_session->pool);
|
||||
switch_jb_set_session(rtp_session->vb, rtp_session->session);
|
||||
@@ -5251,6 +5250,17 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
|
||||
rtp_session->missed_count = 0;
|
||||
switch_cp_addr(rtp_session->rtp_from_addr, rtp_session->from_addr);
|
||||
rtp_session->last_rtp_hdr = rtp_session->recv_msg.header;
|
||||
|
||||
|
||||
if (rtp_session->flags[SWITCH_RTP_FLAG_DETECT_SSRC]) {
|
||||
//if (rtp_session->remote_ssrc != rtp_session->stats.rtcp.peer_ssrc && rtp_session->stats.rtcp.peer_ssrc) {
|
||||
// rtp_session->remote_ssrc = rtp_session->stats.rtcp.peer_ssrc;
|
||||
//}
|
||||
|
||||
if (rtp_session->remote_ssrc != rtp_session->last_rtp_hdr.ssrc && rtp_session->last_rtp_hdr.ssrc) {
|
||||
rtp_session->remote_ssrc = ntohl(rtp_session->last_rtp_hdr.ssrc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5802,7 +5812,7 @@ static void handle_nack(switch_rtp_t *rtp_session, uint32_t nack)
|
||||
send_msg->header.pt, ntohl(send_msg->header.ts), ntohs(send_msg->header.seq), send_msg->header.m);
|
||||
|
||||
}
|
||||
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "RE----SEND %u\n", ntohs(send_msg->header.seq));
|
||||
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "RE----SEND %u\n", ntohs(send_msg->header.seq));
|
||||
switch_rtp_write_raw(rtp_session, (void *) send_msg, &bytes, SWITCH_FALSE);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG1, "Cannot send NACK for seq %u\n", ntohs(seq));
|
||||
@@ -5826,7 +5836,7 @@ static void handle_nack(switch_rtp_t *rtp_session, uint32_t nack)
|
||||
send_msg->header.pt, ntohl(send_msg->header.ts), ntohs(send_msg->header.seq), send_msg->header.m);
|
||||
|
||||
}
|
||||
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "RE----SEND %u\n", ntohs(send_msg->header.seq));
|
||||
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "RE----SEND %u\n", ntohs(send_msg->header.seq));
|
||||
switch_rtp_write_raw(rtp_session, (void *) &send_msg, &bytes, SWITCH_FALSE);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG1, "Cannot send NACK for seq %u\n", ntohs(seq) + i);
|
||||
|
||||
+41
-15
@@ -42,6 +42,12 @@
|
||||
|
||||
// #define DEBUG_VP9
|
||||
|
||||
#ifdef DEBUG_VP9
|
||||
#define VPX_SWITCH_LOG_LEVEL SWITCH_LOG_ERROR
|
||||
#else
|
||||
#define VPX_SWITCH_LOG_LEVEL SWITCH_LOG_DEBUG1
|
||||
#endif
|
||||
|
||||
#define SLICE_SIZE SWITCH_DEFAULT_VIDEO_SIZE
|
||||
#define KEY_FRAME_MIN_FREQ 250000
|
||||
|
||||
@@ -291,6 +297,7 @@ struct vpx_context {
|
||||
int got_start_frame;
|
||||
uint32_t last_received_timestamp;
|
||||
switch_bool_t last_received_complete_picture;
|
||||
uint16_t last_received_seq;
|
||||
int need_key_frame;
|
||||
int need_encoder_reset;
|
||||
int need_decoder_reset;
|
||||
@@ -299,6 +306,7 @@ struct vpx_context {
|
||||
switch_memory_pool_t *pool;
|
||||
switch_buffer_t *pbuffer;
|
||||
switch_time_t start_time;
|
||||
switch_image_t *patch_img;
|
||||
};
|
||||
typedef struct vpx_context vpx_context_t;
|
||||
|
||||
@@ -332,6 +340,7 @@ static switch_status_t init_decoder(switch_codec_t *codec)
|
||||
context->last_ts = 0;
|
||||
context->last_received_timestamp = 0;
|
||||
context->last_received_complete_picture = 0;
|
||||
context->last_received_seq = 0;
|
||||
context->decoder_init = 1;
|
||||
context->got_key_frame = 0;
|
||||
context->no_key_frame = 0;
|
||||
@@ -405,7 +414,7 @@ static switch_status_t init_encoder(switch_codec_t *codec)
|
||||
config->g_lag_in_frames = 0;
|
||||
config->kf_max_dist = 360;//2000;
|
||||
threads = cpus / 4;
|
||||
if (threads < 0) threads = 1;
|
||||
if (threads < 1) threads = 1;
|
||||
config->g_threads = threads;
|
||||
|
||||
if (context->is_vp9) {
|
||||
@@ -965,7 +974,8 @@ static switch_status_t buffer_vp9_packets(vpx_context_t *context, switch_frame_t
|
||||
int len = 0;
|
||||
|
||||
#ifdef DEBUG_VP9
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%02x %02x %02x %02x m=%d len=%4d "
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, frame->m ? SWITCH_LOG_ERROR : SWITCH_LOG_INFO,
|
||||
"[%02x %02x %02x %02x] m=%d len=%4d seq=%d ts=%u ssrc=%u "
|
||||
"have_pid=%d "
|
||||
"have_p_layer=%d "
|
||||
"have_layer_ind=%d "
|
||||
@@ -974,7 +984,7 @@ static switch_status_t buffer_vp9_packets(vpx_context_t *context, switch_frame_t
|
||||
"end=%d "
|
||||
"have_ss=%d "
|
||||
"zero=%d\n",
|
||||
*data, *(data+1), *(data+2), *(data+3), frame->m, frame->datalen,
|
||||
*data, *(data+1), *(data+2), *(data+3), frame->m, frame->datalen, frame->seq, frame->timestamp, frame->ssrc,
|
||||
desc->have_pid,
|
||||
desc->have_p_layer,
|
||||
desc->have_layer_ind,
|
||||
@@ -1000,7 +1010,7 @@ static switch_status_t buffer_vp9_packets(vpx_context_t *context, switch_frame_t
|
||||
vp9++;
|
||||
|
||||
#ifdef DEBUG_VP9
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "have pid: %d start=%d end=%d\n", pid, desc->start, desc->end);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "have pid: %d start=%d end=%d\n", pid, desc->start, desc->end);
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -1071,12 +1081,7 @@ static switch_status_t buffer_vp9_packets(vpx_context_t *context, switch_frame_t
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (switch_buffer_inuse(context->vpx_packet_buffer)) { // middle packet
|
||||
if (desc->start) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "got invalid vp9 packet, packet loss? resetting buffer\n");
|
||||
switch_buffer_zero(context->vpx_packet_buffer);
|
||||
}
|
||||
} else { // start packet
|
||||
if (!switch_buffer_inuse(context->vpx_packet_buffer)) { // start packet
|
||||
if (!desc->start) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "got invalid vp9 packet, packet loss? waiting for a start packet\n");
|
||||
goto end;
|
||||
@@ -1089,7 +1094,7 @@ static switch_status_t buffer_vp9_packets(vpx_context_t *context, switch_frame_t
|
||||
end:
|
||||
|
||||
#ifdef DEBUG_VP9
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "buffered %d bytes, buffer size: %" SWITCH_SIZE_T_FMT "\n", len, switch_buffer_inuse(context->vpx_packet_buffer));
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "buffered %d bytes, buffer size: %" SWITCH_SIZE_T_FMT "\n", len, switch_buffer_inuse(context->vpx_packet_buffer));
|
||||
#endif
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
@@ -1114,11 +1119,16 @@ static switch_status_t switch_vpx_decode(switch_codec_t *codec, switch_frame_t *
|
||||
is_keyframe = IS_VP9_KEY_FRAME(*(unsigned char *)frame->data);
|
||||
is_start = IS_VP9_START_PKT(*(unsigned char *)frame->data);
|
||||
|
||||
#ifdef DEBUG_VP9
|
||||
if (is_keyframe) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "================Got a key frame!!!!========================\n");
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, VPX_SWITCH_LOG_LEVEL, "================Got a key frame!!!!========================\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (context->last_received_seq && context->last_received_seq + 1 != frame->seq) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, VPX_SWITCH_LOG_LEVEL, "Packet loss detected last=%d got=%d lost=%d\n", context->last_received_seq, frame->seq, frame->seq - context->last_received_seq);
|
||||
if (is_keyframe && context->vpx_packet_buffer) switch_buffer_zero(context->vpx_packet_buffer);
|
||||
}
|
||||
|
||||
context->last_received_seq = frame->seq;
|
||||
} else { // vp8
|
||||
is_start = (*(unsigned char *)frame->data & 0x10);
|
||||
is_keyframe = IS_VP8_KEY_FRAME((uint8_t *)frame->data);
|
||||
@@ -1213,8 +1223,15 @@ static switch_status_t switch_vpx_decode(switch_codec_t *codec, switch_frame_t *
|
||||
err = vpx_codec_decode(decoder, data, (unsigned int)len, NULL, 0);
|
||||
|
||||
if (err != VPX_CODEC_OK) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Error decoding %" SWITCH_SIZE_T_FMT " bytes, [%d:%s:%s]\n",
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, VPX_SWITCH_LOG_LEVEL, "Error decoding %" SWITCH_SIZE_T_FMT " bytes, [%d:%s:%s]\n",
|
||||
len, err, vpx_codec_error(decoder), vpx_codec_error_detail(decoder));
|
||||
|
||||
|
||||
if (err == VPX_CODEC_MEM_ERROR) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "VPX MEM ERROR, resetting decoder!\n");
|
||||
context->need_decoder_reset = 1;
|
||||
}
|
||||
|
||||
switch_goto_status(SWITCH_STATUS_RESTART, end);
|
||||
}
|
||||
|
||||
@@ -1264,6 +1281,12 @@ end:
|
||||
switch_set_flag(frame, SFF_WAIT_KEY_FRAME);
|
||||
}
|
||||
|
||||
if (frame->img && (codec->flags & SWITCH_CODEC_FLAG_VIDEO_PATCHING)) {
|
||||
switch_img_free(&context->patch_img);
|
||||
switch_img_copy(frame->img, &context->patch_img);
|
||||
frame->img = context->patch_img;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -1326,6 +1349,9 @@ static switch_status_t switch_vpx_destroy(switch_codec_t *codec)
|
||||
vpx_context_t *context = (vpx_context_t *)codec->private_info;
|
||||
|
||||
if (context) {
|
||||
|
||||
switch_img_free(&context->patch_img);
|
||||
|
||||
if ((codec->flags & SWITCH_CODEC_FLAG_ENCODE)) {
|
||||
vpx_codec_destroy(&context->encoder);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user