mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-07-04 19:31:56 +00:00
Merge branch 'master' into v1.10
This commit is contained in:
@@ -40,7 +40,7 @@ Step by step tutorials to install FreeSWITCH from packages:
|
||||
### Build from source
|
||||
|
||||
Example Dockerfiles to build FreeSWITCH and dependencies from source:
|
||||
* https://github.com/signalwire/freeswitch/tree/dockerfile/docker/examples
|
||||
* https://github.com/signalwire/freeswitch/tree/master/docker/examples
|
||||
|
||||
Step by step tutorials to build FreeSWITCH with provided dependency packages:
|
||||
* [Debian](https://freeswitch.org/confluence/display/FREESWITCH/Debian#Debian-buildfromsource) [<b>Recommended</b>]
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# Security Policy
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Send an e-mail to security@signalwire.com to report a vulnerability. If accepted, we'll create a security advisory and add you and your team as collaborators. Please allow our team sufficient time to resolve the vulnerability before disclosing it; we'll remain in contact about the fix and may ask for your assistance to verify it is resolved.
|
||||
@@ -1 +1 @@
|
||||
1.10.9-release
|
||||
1.10.10-release
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
|
||||
Before you start to modify this default please visit this wiki page:
|
||||
|
||||
http://wiki.freeswitch.org/wiki/Getting_Started_Guide#Some_stuff_to_try_out.21
|
||||
https://developer.signalwire.com/freeswitch/FreeSWITCH-Explained/Configuration/Default-Configuration_6587388/#6-configuration-files
|
||||
|
||||
If all else fails you can read our FAQ located at:
|
||||
|
||||
http://wiki.freeswitch.org/wiki/FreeSwitch_FAQ
|
||||
https://developer.signalwire.com/freeswitch/FreeSWITCH-Explained/Miscellaneous/FAQ/
|
||||
|
||||
NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE
|
||||
-->
|
||||
|
||||
+39
-19
@@ -3,10 +3,10 @@
|
||||
|
||||
# Must change all of the below together
|
||||
# For a release, set revision for that tagged release as well and uncomment
|
||||
AC_INIT([freeswitch], [1.10.9-release], bugs@freeswitch.org)
|
||||
AC_INIT([freeswitch], [1.10.10-release], bugs@freeswitch.org)
|
||||
AC_SUBST(SWITCH_VERSION_MAJOR, [1])
|
||||
AC_SUBST(SWITCH_VERSION_MINOR, [10])
|
||||
AC_SUBST(SWITCH_VERSION_MICRO, [9-release])
|
||||
AC_SUBST(SWITCH_VERSION_MICRO, [10-release])
|
||||
AC_SUBST(SWITCH_VERSION_REVISION, [])
|
||||
AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, [])
|
||||
|
||||
@@ -582,7 +582,7 @@ AC_SUBST(SYS_XMLRPC_CFLAGS)
|
||||
AC_SUBST(SYS_XMLRPC_LDFLAGS)
|
||||
AM_CONDITIONAL([SYSTEM_XMLRPCC],[test "${enable_xmlrpcc}" = "yes"])
|
||||
|
||||
for luaversion in luajit lua5.2 lua-5.2 lua52 lua5.1 lua-5.1 lua; do
|
||||
for luaversion in luajit lua5.3 lua-5.3 lua53 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
|
||||
@@ -716,7 +716,7 @@ PKG_CHECK_MODULES([SPANDSP], [spandsp >= 3.0],[
|
||||
AC_MSG_ERROR([no usable spandsp; please install spandsp3 devel package or equivalent])
|
||||
])
|
||||
|
||||
PKG_CHECK_MODULES([SOFIA_SIP], [sofia-sip-ua >= 1.13.12],[
|
||||
PKG_CHECK_MODULES([SOFIA_SIP], [sofia-sip-ua >= 1.13.15],[
|
||||
AM_CONDITIONAL([HAVE_SOFIA_SIP],[true])],[
|
||||
AC_MSG_ERROR([no usable sofia-sip; please install sofia-sip-ua devel package or equivalent])
|
||||
])
|
||||
@@ -1352,7 +1352,21 @@ PKG_CHECK_MODULES([MPG123], [libmpg123 >= 1.16.0],[
|
||||
AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_MPG123],[false])])
|
||||
|
||||
PKG_CHECK_MODULES([SHOUT], [shout >= 2.2.2],[
|
||||
AM_CONDITIONAL([HAVE_SHOUT],[true])],[
|
||||
AM_CONDITIONAL([HAVE_SHOUT],[true])
|
||||
SHOUT_VERSION="`$PKG_CONFIG --modversion shout`"
|
||||
SHOUT_MAJOR_VERSION="`echo $SHOUT_VERSION | cut -d. -f1`"
|
||||
SHOUT_MINOR_VERSION="`echo $SHOUT_VERSION | cut -d. -f2`"
|
||||
SHOUT_PATCH_VERSION="`echo $SHOUT_VERSION | cut -d. -f3`"
|
||||
test -n "$SHOUT_PATCH_VERSION" || SHOUT_PATCH_VERSION=0
|
||||
AC_MSG_NOTICE([SHOUT version: $SHOUT_VERSION])
|
||||
AC_MSG_NOTICE([SHOUT major version: $SHOUT_MAJOR_VERSION])
|
||||
AC_MSG_NOTICE([SHOUT minor version: $SHOUT_MINOR_VERSION])
|
||||
AC_MSG_NOTICE([SHOUT patch version: $SHOUT_PATCH_VERSION])
|
||||
AC_SUBST([SHOUT_VERSION])
|
||||
AC_SUBST([SHOUT_MAJOR_VERSION])
|
||||
AC_SUBST([SHOUT_MINOR_VERSION])
|
||||
AC_SUBST([SHOUT_PATCH_VERSION])
|
||||
],[
|
||||
AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_SHOUT],[false])])
|
||||
|
||||
mp3lame=false
|
||||
@@ -1518,26 +1532,32 @@ PKG_CHECK_MODULES([V8FS_STATIC], [v8-6.1_static >= 6.1.298],[
|
||||
])
|
||||
])
|
||||
|
||||
PKG_CHECK_MODULES([KS], [libks >= 1.8.2],[
|
||||
PKG_CHECK_MODULES([KS], [libks2 >= 2.0.0],[
|
||||
AM_CONDITIONAL([HAVE_KS],[true])],[
|
||||
if module_enabled mod_verto; then
|
||||
AC_MSG_ERROR([You need to either install libks or disable mod_verto in modules.conf])
|
||||
else
|
||||
if module_enabled mod_signalwire; then
|
||||
AC_MSG_ERROR([You need to either install libks or disable mod_signalwire in modules.conf])
|
||||
PKG_CHECK_MODULES([KS], [libks >= 1.8.2],[
|
||||
AM_CONDITIONAL([HAVE_KS],[true])],[
|
||||
if module_enabled mod_verto; then
|
||||
AC_MSG_ERROR([You need to either install libks2 or libks or disable mod_verto in modules.conf])
|
||||
else
|
||||
AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_KS],[false])
|
||||
if module_enabled mod_signalwire; then
|
||||
AC_MSG_ERROR([You need to either install libks2 or libks or disable mod_signalwire in modules.conf])
|
||||
else
|
||||
AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_KS],[false])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
])
|
||||
])
|
||||
|
||||
PKG_CHECK_MODULES([SIGNALWIRE_CLIENT], [signalwire_client >= 1.0.0],[
|
||||
PKG_CHECK_MODULES([SIGNALWIRE_CLIENT], [signalwire_client2 >= 2.0.0],[
|
||||
AM_CONDITIONAL([HAVE_SIGNALWIRE_CLIENT],[true])],[
|
||||
if module_enabled mod_signalwire; then
|
||||
AC_MSG_ERROR([You need to either install signalwire-client-c or disable mod_signalwire in modules.conf])
|
||||
else
|
||||
AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_SIGNALWIRE_CLIENT],[false])
|
||||
fi
|
||||
PKG_CHECK_MODULES([SIGNALWIRE_CLIENT], [signalwire_client >= 1.0.0],[
|
||||
AM_CONDITIONAL([HAVE_SIGNALWIRE_CLIENT],[true])],[
|
||||
if module_enabled mod_signalwire; then
|
||||
AC_MSG_ERROR([You need to either install signalwire-client-c2 or signalwire-client-c or disable mod_signalwire in modules.conf])
|
||||
else
|
||||
AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_SIGNALWIRE_CLIENT],[false])
|
||||
fi
|
||||
])
|
||||
])
|
||||
|
||||
PKG_CHECK_MODULES([AMQP], [librabbitmq >= 0.5.2],[
|
||||
|
||||
Vendored
+7
-4
@@ -29,7 +29,7 @@ conf_dir="../conf"
|
||||
lang_dir="../conf/vanilla/lang"
|
||||
fs_description="FreeSWITCH is a scalable open source cross-platform telephony platform designed to route and interconnect popular communication protocols using audio, video, text or any other form of media."
|
||||
mod_build_depends="." mod_depends="." mod_recommends="." mod_suggests="."
|
||||
supported_debian_distros="wheezy jessie stretch buster bullseye sid"
|
||||
supported_debian_distros="wheezy jessie stretch buster bullseye bookworm sid"
|
||||
supported_ubuntu_distros="trusty utopic xenial"
|
||||
supported_distros="$supported_debian_distros $supported_ubuntu_distros"
|
||||
avoid_mods=(
|
||||
@@ -71,6 +71,9 @@ avoid_mods_sid=(
|
||||
avoid_mods_jessie=(
|
||||
directories/mod_ldap
|
||||
)
|
||||
avoid_mods_bookworm=(
|
||||
languages/mod_python
|
||||
)
|
||||
avoid_mods_wheezy=(
|
||||
event_handlers/mod_amqp
|
||||
languages/mod_java
|
||||
@@ -325,14 +328,14 @@ Build-Depends:
|
||||
# configure options
|
||||
libssl1.0-dev | libssl-dev, unixodbc-dev, libpq-dev,
|
||||
libncurses5-dev, libjpeg62-turbo-dev | libjpeg-turbo8-dev | libjpeg62-dev | libjpeg8-dev,
|
||||
python-dev | python-dev-is-python2, python3-dev, python-all-dev, python-support (>= 0.90) | dh-python, erlang-dev, libtpl-dev (>= 1.5),
|
||||
python-dev | python-dev-is-python2 | python-dev-is-python3, python3-dev, python-all-dev | python3-all-dev, python-support (>= 0.90) | dh-python, erlang-dev, libtpl-dev (>= 1.5),
|
||||
# documentation
|
||||
doxygen,
|
||||
# for APR (not essential for build)
|
||||
uuid-dev, libexpat1-dev, libgdbm-dev, libdb-dev,
|
||||
# used by many modules
|
||||
libcurl4-openssl-dev | libcurl4-gnutls-dev | libcurl-dev,
|
||||
bison, zlib1g-dev, libsofia-sip-ua-dev (>= 1.13.12),
|
||||
bison, zlib1g-dev, libsofia-sip-ua-dev (>= 1.13.15),
|
||||
libspandsp3-dev,
|
||||
# used to format the private freeswitch apt-repo key properly
|
||||
gnupg,
|
||||
@@ -371,7 +374,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch
|
||||
|
||||
Package: libfreeswitch1
|
||||
Architecture: amd64 armhf
|
||||
Depends: \${shlibs:Depends}, \${misc:Depends}, libsofia-sip-ua0 (>= 1.13.12)
|
||||
Depends: \${shlibs:Depends}, \${misc:Depends}, libsofia-sip-ua0 (>= 1.13.15)
|
||||
Recommends:
|
||||
Suggests: libfreeswitch1-dbg
|
||||
Conflicts: freeswitch-all (<= 1.6.7)
|
||||
|
||||
Vendored
+6
-1
@@ -12,6 +12,7 @@ Module: applications/mod_av
|
||||
Description: mod_av
|
||||
Adds mod_av.
|
||||
Build-Depends: libavformat-dev, libswscale-dev, libavresample-dev
|
||||
Build-Depends-Bookworm: libavformat-dev, libswscale-dev, libswresample-dev
|
||||
|
||||
Module: applications/mod_avmd
|
||||
Description: Advanced voicemail detection
|
||||
@@ -209,7 +210,7 @@ Description: Adds mod_skel
|
||||
Module: applications/mod_signalwire
|
||||
Description: mod_signalwire
|
||||
Adds mod_signalwire.
|
||||
Build-Depends: libks, signalwire-client-c
|
||||
Build-Depends: libks2, signalwire-client-c2
|
||||
|
||||
Module: applications/mod_sms
|
||||
Description: Astract SMS
|
||||
@@ -485,6 +486,7 @@ Description: Adds mod_verto.
|
||||
Build-Depends: libperl-dev
|
||||
Build-Depends-Buster: libperl-dev, libgdbm-compat-dev
|
||||
Build-Depends-Bullseye: libperl-dev, libgdbm-compat-dev
|
||||
Build-Depends-Bookworm: libperl-dev, libgdbm-compat-dev
|
||||
|
||||
## mod/event_handlers
|
||||
|
||||
@@ -647,6 +649,7 @@ Module: languages/mod_lua
|
||||
Description: mod_lua
|
||||
Adds mod_lua.
|
||||
Build-Depends: liblua5.2-dev | liblua5.1-dev
|
||||
Build-Depends-Bookworm: liblua5.3-dev | liblua5.2-dev | liblua5.1-dev
|
||||
|
||||
Module: languages/mod_managed
|
||||
Description: mod_managed
|
||||
@@ -659,6 +662,7 @@ Description: mod_perl
|
||||
Build-Depends: libperl-dev
|
||||
Build-Depends-Buster: libperl-dev, libgdbm-compat-dev
|
||||
Build-Depends-Bullseye: libperl-dev, libgdbm-compat-dev
|
||||
Build-Depends-Bookworm: libperl-dev, libgdbm-compat-dev
|
||||
|
||||
Module: languages/mod_python
|
||||
Description: mod_python
|
||||
@@ -669,6 +673,7 @@ Module: languages/mod_python3
|
||||
Description: mod_python3
|
||||
Adds mod_python3.
|
||||
Build-Depends: python3-dev
|
||||
Build-Depends-Bookworm: python3-dev, python3-setuptools
|
||||
|
||||
Module: languages/mod_v8
|
||||
Description: mod_v8
|
||||
|
||||
Vendored
+2
@@ -46,6 +46,7 @@ find_distro () {
|
||||
case "$1" in
|
||||
experimental) echo "sid";;
|
||||
unstable) echo "sid";;
|
||||
experimental) echo "bookworm";;
|
||||
testing) echo "bullseye";;
|
||||
stable) echo "buster";;
|
||||
oldstable) echo "stretch";;
|
||||
@@ -56,6 +57,7 @@ find_distro () {
|
||||
find_suite () {
|
||||
case "$1" in
|
||||
sid) echo "unstable";;
|
||||
bookworm) echo "experimental";;
|
||||
bullseye) echo "testing";;
|
||||
buster) echo "stable";;
|
||||
stretch) echo "oldstable";;
|
||||
|
||||
@@ -31,13 +31,18 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get -yq install \
|
||||
# mod_pgsql
|
||||
libpq-dev \
|
||||
# mod_sndfile
|
||||
libsndfile1-dev libflac-dev libogg-dev libvorbis-dev
|
||||
|
||||
libsndfile1-dev libflac-dev libogg-dev libvorbis-dev \
|
||||
# mod_shout
|
||||
libshout3-dev libmpg123-dev libmp3lame-dev
|
||||
|
||||
RUN cd /usr/src/libs/libks && cmake . -DCMAKE_INSTALL_PREFIX=/usr -DWITH_LIBBACKTRACE=1 && make install
|
||||
RUN cd /usr/src/libs/sofia-sip && ./bootstrap.sh && ./configure CFLAGS="-g -ggdb" --with-pic --with-glib=no --without-doxygen --disable-stun --prefix=/usr && make -j`nproc --all` && make install
|
||||
RUN cd /usr/src/libs/spandsp && ./bootstrap.sh && ./configure CFLAGS="-g -ggdb" --with-pic --prefix=/usr && make -j`nproc --all` && make install
|
||||
RUN cd /usr/src/libs/signalwire-c && PKG_CONFIG_PATH=/usr/lib/pkgconfig cmake . -DCMAKE_INSTALL_PREFIX=/usr && make install
|
||||
|
||||
# Enable modules
|
||||
RUN sed -i 's|#formats/mod_shout|formats/mod_shout|' /usr/src/freeswitch/build/modules.conf.in
|
||||
|
||||
RUN cd /usr/src/freeswitch && ./bootstrap.sh -j
|
||||
RUN cd /usr/src/freeswitch && ./configure
|
||||
RUN cd /usr/src/freeswitch && make -j`nproc` && make install
|
||||
@@ -46,4 +51,4 @@ RUN cd /usr/src/freeswitch && make -j`nproc` && make install
|
||||
RUN apt-get clean
|
||||
|
||||
# Uncomment to cleanup even more
|
||||
#RUN rm -rf /usr/src/*
|
||||
#RUN rm -rf /usr/src/*
|
||||
|
||||
+2
-2
@@ -140,7 +140,7 @@ BuildRequires: curl-devel >= 7.19
|
||||
BuildRequires: gcc-c++
|
||||
BuildRequires: libtool >= 1.5.17
|
||||
BuildRequires: openssl-devel >= 1.0.1e
|
||||
BuildRequires: sofia-sip-devel >= 1.13.12
|
||||
BuildRequires: sofia-sip-devel >= 1.13.15
|
||||
BuildRequires: spandsp3-devel >= 3.0
|
||||
BuildRequires: pcre-devel
|
||||
BuildRequires: speex-devel
|
||||
@@ -497,7 +497,7 @@ the entries aloud via a TTS engine
|
||||
Summary: FreeSWITCH mod_signalwire
|
||||
Group: System/Libraries
|
||||
Requires: %{name} = %{version}-%{release}
|
||||
BuildRequires: libks signalwire-client-c
|
||||
BuildRequires: libks2 signalwire-client-c2
|
||||
|
||||
%description application-signalwire
|
||||
Provides FreeSWITCH mod_signalwire
|
||||
|
||||
@@ -582,7 +582,7 @@ typedef void (*ARGBBlendRow)(const uint8_t* src_argb0,
|
||||
|
||||
// Get function to Alpha Blend ARGB pixels and store to destination.
|
||||
LIBYUV_API
|
||||
ARGBBlendRow GetARGBBlend();
|
||||
ARGBBlendRow GetARGBBlend(void);
|
||||
|
||||
// Alpha Blend ARGB images and store to destination.
|
||||
// Source is pre-multiplied by alpha using ARGBAttenuate.
|
||||
|
||||
@@ -1185,7 +1185,7 @@ int ARGBMirror(const uint8_t* src_argb,
|
||||
// As there are 6 blenders to choose from, the caller should try to use
|
||||
// the same blend function for all pixels if possible.
|
||||
LIBYUV_API
|
||||
ARGBBlendRow GetARGBBlend() {
|
||||
ARGBBlendRow GetARGBBlend(void) {
|
||||
void (*ARGBBlendRow)(const uint8_t* src_argb, const uint8_t* src_argb1,
|
||||
uint8_t* dst_argb, int width) = ARGBBlendRow_C;
|
||||
#if defined(HAS_ARGBBLENDROW_SSSE3)
|
||||
|
||||
@@ -679,7 +679,6 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
|
||||
char * descXML;
|
||||
int descXMLsize = 0;
|
||||
struct UPNPDev * dev;
|
||||
int ndev = 0;
|
||||
int state; /* state 1 : IGD connected. State 2 : IGD. State 3 : anything */
|
||||
if(!devlist)
|
||||
{
|
||||
@@ -698,7 +697,6 @@ UPNP_GetValidIGD(struct UPNPDev * devlist,
|
||||
lanaddr, lanaddrlen);
|
||||
if(descXML)
|
||||
{
|
||||
ndev++;
|
||||
memset(data, 0, sizeof(struct IGDdatas));
|
||||
memset(urls, 0, sizeof(struct UPNPUrls));
|
||||
parserootdesc(descXML, descXMLsize, data);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,12 @@
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <strings.h>
|
||||
#else
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include "xmlrpc_config.h"
|
||||
#include "c_util.h"
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
/* Copyright information is at end of file */
|
||||
|
||||
#define _XOPEN_SOURCE 600 /* Make sure strdup() is in <string.h> */
|
||||
#ifdef __APPLE__
|
||||
#define _DARWIN_C_SOURCE
|
||||
#endif
|
||||
#define _BSD_SOURCE /* Make sure setgroups()is in <grp.h> */
|
||||
#ifndef _DEFAULT_SOURCE
|
||||
#define _DEFAULT_SOURCE
|
||||
|
||||
@@ -3,7 +3,11 @@
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#ifdef __APPLE__
|
||||
#include <sys/wait.h>
|
||||
#else
|
||||
#include <wait.h>
|
||||
#endif
|
||||
#include <signal.h>
|
||||
|
||||
#include "xmlrpc_config.h"
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
#define _XOPEN_SOURCE 600 /* Make sure strdup() is in <string.h> */
|
||||
#ifdef __APPLE__
|
||||
#define _DARWIN_C_SOURCE
|
||||
#endif
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE /* But only when HAVE_ASPRINTF */
|
||||
#endif
|
||||
|
||||
Executable
+53
@@ -0,0 +1,53 @@
|
||||
local https = require("socket.http")
|
||||
local ip = os.getenv("LOCAL_IPV4")
|
||||
local response_body = {}
|
||||
-- jitter buffer stats
|
||||
local size_max_ms = session:getVariable("rtp_jb_size_max_ms");
|
||||
local size_est_ms = session:getVariable("rtp_jb_size_est_ms");
|
||||
local acceleration_ms = session:getVariable("rtp_jb_acceleration_ms");
|
||||
local expand_ms = session:getVariable("rtp_jb_expand_ms");
|
||||
local jitter_max_ms = session:getVariable("rtp_jb_jitter_max_ms");
|
||||
local jitter_est_ms = session:getVariable("rtp_jb_jitter_est_ms");
|
||||
|
||||
local reset_count = session:getVariable("rtp_jb_reset_count");
|
||||
local reset_too_big = session:getVariable("rtp_jb_reset_too_big");
|
||||
local reset_missing_frames = session:getVariable("rtp_jb_reset_missing_frames");
|
||||
local reset_ts_jump = session:getVariable("rtp_jb_reset_ts_jump");
|
||||
local reset_error = session:getVariable("rtp_jb_reset_error");
|
||||
local call_id = session:getVariable("sip_call_id");
|
||||
local out_call_id = session:getVariable("last_bridge_to");
|
||||
|
||||
if size_max_ms == nil or size_est_ms == nil or acceleration_ms == nil or expand_ms == nil or jitter_max_ms == nil or jitter_est_ms == nil then
|
||||
session:consoleLog("info", "[metrics] jitter no data\n");
|
||||
return
|
||||
end
|
||||
local request_body = '{"in_call_id": "'..call_id..'", "out_call_id": "'..out_call_id..'", "jb":{"size_max_ms":'..size_max_ms..
|
||||
',"size_est_ms":'..size_est_ms..',"acceleration_ms":'..acceleration_ms..',"expand_ms":'..expand_ms..
|
||||
',"jitter_max_ms":'..jitter_max_ms..',"jitter_est_ms":'..jitter_est_ms..',"reset":'..reset_count
|
||||
-- if reset_too_big ~= "0" then
|
||||
request_body = request_body .. ',"reset_too_big":'..reset_too_big
|
||||
-- end
|
||||
if reset_missing_frames ~= "0" then
|
||||
request_body = request_body .. ',"reset_missing_frames":'..reset_missing_frames
|
||||
end
|
||||
if reset_ts_jump ~= "0" then
|
||||
request_body = request_body .. ',"reset_ts_jump":'..reset_ts_jump
|
||||
end
|
||||
if reset_error ~= "0" then
|
||||
request_body = request_body .. ',"reset_error":'..reset_error
|
||||
end
|
||||
|
||||
local v = request_body .. '}}';
|
||||
|
||||
local r, c, h, s = https.request{
|
||||
method = 'POST',
|
||||
url = "http://"..ip..":80/freeswitch_metrics",
|
||||
headers = {
|
||||
["Content-Type"] = "application/json",
|
||||
["Content-Length"] = string.len(v)
|
||||
},
|
||||
source = ltn12.source.string(v),
|
||||
sink = ltn12.sink.table(response_body)
|
||||
}
|
||||
-- print('statusCode ', c)
|
||||
session:consoleLog("info", "[metrics] jitter:".. v .. "\n");
|
||||
+1
-1
@@ -46,7 +46,7 @@
|
||||
#pragma warning (disable:167)
|
||||
#endif
|
||||
|
||||
static void fs_encode_cleanup()
|
||||
static void fs_encode_cleanup(void)
|
||||
{
|
||||
switch_safe_free(SWITCH_GLOBAL_dirs.conf_dir);
|
||||
switch_safe_free(SWITCH_GLOBAL_dirs.mod_dir);
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@
|
||||
#pragma warning (disable:167)
|
||||
#endif
|
||||
|
||||
static void fs_tts_cleanup()
|
||||
static void fs_tts_cleanup(void)
|
||||
{
|
||||
switch_safe_free(SWITCH_GLOBAL_dirs.conf_dir);
|
||||
switch_safe_free(SWITCH_GLOBAL_dirs.mod_dir);
|
||||
|
||||
@@ -310,7 +310,7 @@ extern struct switch_session_manager session_manager;
|
||||
|
||||
|
||||
switch_status_t switch_core_sqldb_init(const char **err);
|
||||
void switch_core_sqldb_destroy();
|
||||
void switch_core_sqldb_destroy(void);
|
||||
switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_t manage);
|
||||
void switch_core_sqldb_stop(void);
|
||||
void switch_core_session_init(switch_memory_pool_t *pool);
|
||||
|
||||
@@ -325,6 +325,24 @@ SWITCH_DECLARE(switch_status_t) switch_channel_get_scope_variables(switch_channe
|
||||
SWITCH_DECLARE(const char *) switch_channel_get_variable_dup(switch_channel_t *channel, const char *varname, switch_bool_t dup, int idx);
|
||||
#define switch_channel_get_variable(_c, _v) switch_channel_get_variable_dup(_c, _v, SWITCH_TRUE, -1)
|
||||
|
||||
/*!
|
||||
\brief Retrieve a copy of a variable from a given channel. switch_safe_free() call will be required.
|
||||
\param channel channel to retrieve variable from
|
||||
\param varname the name of the variable
|
||||
\return a strdup copy the value of the requested variable without using a memory pool.
|
||||
*/
|
||||
SWITCH_DECLARE(const char *) switch_channel_get_variable_strdup(switch_channel_t *channel, const char *varname);
|
||||
|
||||
/*!
|
||||
\brief Retrieve a variable from a given channel to a pre-allocated buffer without using a memory pool.
|
||||
\param channel channel to retrieve variable from
|
||||
\param varname the name of the variable
|
||||
\param buf a pre allocated buffer to put the value to
|
||||
\param buflen size of the buffer
|
||||
\return SWITCH_STATUS_SUCCESS if the value was copied to the buffer and it is not NULL, SWITCH_STATUS_FALSE otherwise.
|
||||
*/
|
||||
SWITCH_DECLARE(switch_status_t) switch_channel_get_variable_buf(switch_channel_t *channel, const char *varname, char *buf, switch_size_t buflen);
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_channel_get_variables(switch_channel_t *channel, switch_event_t **event);
|
||||
SWITCH_DECLARE(switch_status_t) switch_channel_get_variables_prefix(switch_channel_t *channel, const char *prefix, switch_event_t **event);
|
||||
SWITCH_DECLARE(switch_status_t) switch_channel_pass_callee_id(switch_channel_t *channel, switch_channel_t *other_channel);
|
||||
|
||||
@@ -399,6 +399,10 @@ SWITCH_DECLARE(void) switch_core_media_set_smode(switch_core_session_t *session,
|
||||
SWITCH_DECLARE(void) switch_core_media_set_resolveice(switch_bool_t resolve_ice);
|
||||
SWITCH_DECLARE(switch_bool_t) switch_core_media_has_resolveice(void);
|
||||
|
||||
typedef struct switch_rtp_engine_s switch_rtp_engine_t;
|
||||
SWITCH_DECLARE(switch_rtp_engine_t *) switch_core_media_get_engine(switch_core_session_t *session, int media_type);
|
||||
SWITCH_DECLARE(switch_codec_t*) switch_core_media_get_codec(switch_core_session_t *session, switch_media_type_t type);
|
||||
|
||||
SWITCH_END_EXTERN_C
|
||||
#endif
|
||||
/* For Emacs:
|
||||
|
||||
@@ -448,7 +448,7 @@ SWITCH_DECLARE(switch_status_t) switch_img_to_raw(switch_image_t *src, void *des
|
||||
* \param[in] width The raw data width
|
||||
* \param[in] height The raw data height
|
||||
*/
|
||||
SWITCH_DECLARE(switch_status_t) switch_img_from_raw(switch_image_t *dest, void *src, switch_img_fmt_t fmt, int width, int height);
|
||||
SWITCH_DECLARE(switch_status_t) switch_img_from_raw(switch_image_t** destP, void *src, switch_img_fmt_t fmt, int width, int height);
|
||||
SWITCH_DECLARE(switch_image_t *) switch_img_write_text_img(int w, int h, switch_bool_t full, const char *text);
|
||||
|
||||
SWITCH_DECLARE(switch_image_t *) switch_img_read_file(const char* file_name);
|
||||
|
||||
@@ -40,6 +40,9 @@ typedef int switch_CURLINFO;
|
||||
typedef int switch_CURLcode;
|
||||
typedef int switch_CURLoption;
|
||||
|
||||
#define HAVE_SWITCH_CURL_MIME
|
||||
typedef void switch_curl_mime;
|
||||
|
||||
SWITCH_DECLARE(switch_CURL *) switch_curl_easy_init(void);
|
||||
SWITCH_DECLARE(switch_CURLcode) switch_curl_easy_perform(switch_CURL *handle);
|
||||
SWITCH_DECLARE(switch_CURLcode) switch_curl_easy_getinfo(switch_CURL *curl, switch_CURLINFO info, ... );
|
||||
@@ -50,7 +53,9 @@ SWITCH_DECLARE(switch_CURLcode) switch_curl_easy_setopt(CURL *handle, switch_CUR
|
||||
SWITCH_DECLARE(const char *) switch_curl_easy_strerror(switch_CURLcode errornum );
|
||||
SWITCH_DECLARE(void) switch_curl_init(void);
|
||||
SWITCH_DECLARE(void) switch_curl_destroy(void);
|
||||
SWITCH_DECLARE(switch_status_t) switch_curl_process_form_post_params(switch_event_t *event, switch_CURL *curl_handle, struct curl_httppost **formpostp);
|
||||
SWITCH_DECLARE(switch_status_t) switch_curl_process_mime(switch_event_t *event, switch_CURL *curl_handle, switch_curl_mime **mimep);
|
||||
SWITCH_DECLARE(void) switch_curl_mime_free(switch_curl_mime **mimep);
|
||||
SWITCH_DECLARE(switch_CURLcode) switch_curl_easy_setopt_mime(switch_CURL *curl_handle, switch_curl_mime *mime);
|
||||
#define switch_curl_easy_setopt curl_easy_setopt
|
||||
|
||||
SWITCH_END_EXTERN_C
|
||||
|
||||
@@ -61,6 +61,7 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp
|
||||
SWITCH_DECLARE(uint32_t) switch_jb_pop_nack(switch_jb_t *jb);
|
||||
SWITCH_DECLARE(switch_status_t) switch_jb_get_packet_by_seq(switch_jb_t *jb, uint16_t seq, switch_rtp_packet_t *packet, switch_size_t *len);
|
||||
SWITCH_DECLARE(void) switch_jb_set_session(switch_jb_t *jb, switch_core_session_t *session);
|
||||
SWITCH_DECLARE(void) switch_jb_set_jitter_estimator(switch_jb_t *jb, double *jitter, uint32_t samples_per_frame, uint32_t samples_per_second);
|
||||
SWITCH_DECLARE(void) switch_jb_ts_mode(switch_jb_t *jb, uint32_t samples_per_frame, uint32_t samples_per_second);
|
||||
SWITCH_DECLARE(void) switch_jb_set_flag(switch_jb_t *jb, switch_jb_flag_t flag);
|
||||
SWITCH_DECLARE(void) switch_jb_clear_flag(switch_jb_t *jb, switch_jb_flag_t flag);
|
||||
|
||||
@@ -676,8 +676,14 @@ struct switch_codec_fmtp {
|
||||
int bits_per_second;
|
||||
/*! number of microseconds of media in one packet (ptime * 1000) */
|
||||
int microseconds_per_packet;
|
||||
/*! stereo */
|
||||
int stereo;
|
||||
/*! maximum ptime in ms */
|
||||
int max_ptime;
|
||||
/*! minimum ptime in ms */
|
||||
int min_ptime;
|
||||
/*! stereo, typically bidirectional */
|
||||
int stereo;
|
||||
/* sender properties (stereo) */
|
||||
int sprop_stereo;
|
||||
/*! private data for the codec module to store handle specific info */
|
||||
void *private_info;
|
||||
|
||||
|
||||
@@ -106,12 +106,13 @@ typedef struct icand_s {
|
||||
} icand_t;
|
||||
|
||||
#define MAX_CAND 50
|
||||
#define MAX_CAND_IDX_COUNT 2
|
||||
typedef struct ice_s {
|
||||
|
||||
icand_t cands[MAX_CAND][2];
|
||||
int cand_idx[2];
|
||||
int chosen[2];
|
||||
int is_chosen[2];
|
||||
icand_t cands[MAX_CAND][MAX_CAND_IDX_COUNT];
|
||||
int cand_idx[MAX_CAND_IDX_COUNT];
|
||||
int chosen[MAX_CAND_IDX_COUNT];
|
||||
int is_chosen[MAX_CAND_IDX_COUNT];
|
||||
char *ufrag;
|
||||
char *pwd;
|
||||
char *options;
|
||||
|
||||
@@ -2249,7 +2249,8 @@ typedef enum {
|
||||
SWITCH_CAUSE_BAD_IDENTITY_INFO = 821,
|
||||
SWITCH_CAUSE_UNSUPPORTED_CERTIFICATE = 822,
|
||||
SWITCH_CAUSE_INVALID_IDENTITY = 823,
|
||||
SWITCH_CAUSE_STALE_DATE = 824
|
||||
SWITCH_CAUSE_STALE_DATE = 824,
|
||||
SWITCH_CAUSE_REJECT_ALL = 825
|
||||
} switch_call_cause_t;
|
||||
|
||||
typedef enum {
|
||||
@@ -2424,6 +2425,7 @@ typedef enum {
|
||||
SCC_VIDEO_RESET,
|
||||
SCC_AUDIO_PACKET_LOSS,
|
||||
SCC_AUDIO_ADJUST_BITRATE,
|
||||
SCC_AUDIO_VAD,
|
||||
SCC_DEBUG,
|
||||
SCC_CODEC_SPECIFIC
|
||||
} switch_codec_control_command_t;
|
||||
|
||||
@@ -498,6 +498,14 @@ SWITCH_DECLARE(switch_size_t) switch_fp_read_dline(FILE *fd, char **buf, switch_
|
||||
SWITCH_DECLARE(switch_status_t) switch_frame_alloc(switch_frame_t **frame, switch_size_t size);
|
||||
SWITCH_DECLARE(switch_status_t) switch_frame_dup(switch_frame_t *orig, switch_frame_t **clone);
|
||||
SWITCH_DECLARE(switch_status_t) switch_frame_free(switch_frame_t **frame);
|
||||
|
||||
/*! \brief Check if a 32 bit unsigned number is in a range.
|
||||
* \param str string to check. Should not contain non-digit characters.
|
||||
* \param from start of range including this number
|
||||
* \param to end of range including this number
|
||||
* \return true or false
|
||||
*/
|
||||
SWITCH_DECLARE(switch_bool_t) switch_is_uint_in_range(const char *str, unsigned int from, unsigned int to);
|
||||
SWITCH_DECLARE(switch_bool_t) switch_is_number(const char *str);
|
||||
SWITCH_DECLARE(switch_bool_t) switch_is_leading_number(const char *str);
|
||||
SWITCH_DECLARE(char *) switch_find_parameter(const char *str, const char *param, switch_memory_pool_t *pool);
|
||||
|
||||
@@ -255,7 +255,7 @@ fctstr_safe_cpy(char *dst, char const *src, size_t num)
|
||||
#if defined(WIN32) && _MSC_VER >= 1400
|
||||
strncpy_s(dst, num, src, _TRUNCATE);
|
||||
#else
|
||||
strncpy(dst, src, num);
|
||||
strncpy(dst, src, num - 1);
|
||||
#endif
|
||||
dst[num-1] = '\0';
|
||||
}
|
||||
@@ -760,6 +760,7 @@ fct_nlist__init2(fct_nlist_t *list, size_t start_sz)
|
||||
list->itm_list = (void**)malloc(sizeof(void*)*start_sz);
|
||||
if ( list->itm_list == NULL )
|
||||
{
|
||||
list->used_itm_num = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
* Seven Du <dujinfang@gmail.com>
|
||||
* Anthony Minessale <anthm@freeswitch.org>
|
||||
* Emmanuel Schmidbauer <eschmidbauer@gmail.com>
|
||||
* Jakub Karolczyk <jakub.karolczyk@signalwire.com>
|
||||
*
|
||||
* mod_avcodec -- Codec with libav.org and ffmpeg
|
||||
*
|
||||
@@ -34,6 +35,9 @@
|
||||
#include <switch.h>
|
||||
#include "mod_av.h"
|
||||
#include <libavcodec/avcodec.h>
|
||||
#ifdef _MSC_VER
|
||||
#include <libavcodec/version.h> /* LIBAVCODEC_VERSION_INT */
|
||||
#endif
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavutil/opt.h>
|
||||
#include <libavutil/imgutils.h>
|
||||
@@ -373,8 +377,13 @@ typedef struct our_h264_nalu_s {
|
||||
|
||||
typedef struct h264_codec_context_s {
|
||||
switch_buffer_t *nalu_buffer;
|
||||
#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V)
|
||||
AVCodec *decoder;
|
||||
AVCodec *encoder;
|
||||
#else
|
||||
const AVCodec *decoder;
|
||||
const AVCodec *encoder;
|
||||
#endif
|
||||
AVCodecContext *decoder_ctx;
|
||||
int got_pps; /* if pps packet received */
|
||||
int64_t pts;
|
||||
@@ -393,12 +402,13 @@ typedef struct h264_codec_context_s {
|
||||
switch_codec_settings_t codec_settings;
|
||||
AVCodecContext *encoder_ctx;
|
||||
AVFrame *encoder_avframe;
|
||||
AVPacket encoder_avpacket;
|
||||
AVPacket *encoder_avpacket;
|
||||
AVFrame *decoder_avframe;
|
||||
our_h264_nalu_t nalus[MAX_NALUS];
|
||||
enum AVCodecID av_codec_id;
|
||||
uint16_t last_seq; // last received frame->seq
|
||||
int hw_encoder;
|
||||
switch_packetizer_t *packetizer;
|
||||
} h264_codec_context_t;
|
||||
|
||||
#ifndef AV_INPUT_BUFFER_PADDING_SIZE
|
||||
@@ -825,7 +835,11 @@ static void fs_rtp_parse_h263_rfc2190(h264_codec_context_t *context, AVPacket *p
|
||||
const uint8_t *p = buf;
|
||||
const uint8_t *buf_base = buf;
|
||||
uint32_t code = (ntohl(*(uint32_t *)buf) & 0xFFFFFC00) >> 10;
|
||||
#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V)
|
||||
int mb_info_size = 0;
|
||||
#else
|
||||
switch_size_t mb_info_size = 0;
|
||||
#endif
|
||||
int mb_info_pos = 0, mb_info_count = 0;
|
||||
const uint8_t *mb_info;
|
||||
|
||||
@@ -889,7 +903,11 @@ static void fs_rtp_parse_h263_rfc2190(h264_codec_context_t *context, AVPacket *p
|
||||
"Unable to split H263 packet! mb_info_pos=%d mb_info_count=%d pos=%d max=%"SWITCH_SIZE_T_FMT"\n", mb_info_pos, mb_info_count, pos, (switch_size_t)(end - buf_base));
|
||||
}
|
||||
} else {
|
||||
#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V)
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Should Not Happen!!! mb_info_pos=%d mb_info_count=%d mb_info_size=%d\n", mb_info_pos, mb_info_count, mb_info_size);
|
||||
#else
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Should Not Happen!!! mb_info_pos=%d mb_info_count=%d mb_info_size=%ld\n", mb_info_pos, mb_info_count, mb_info_size);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1033,7 +1051,7 @@ static switch_status_t consume_h263_bitstream(h264_codec_context_t *context, swi
|
||||
}
|
||||
|
||||
if (!context->nalus[context->nalu_current_index].len) {
|
||||
av_packet_unref(&context->encoder_avpacket);
|
||||
av_packet_unref(context->encoder_avpacket);
|
||||
frame->m = 1;
|
||||
}
|
||||
|
||||
@@ -1081,81 +1099,27 @@ static switch_status_t consume_h263p_bitstream(h264_codec_context_t *context, sw
|
||||
#endif
|
||||
|
||||
if (frame->m) {
|
||||
av_packet_unref(&context->encoder_avpacket);
|
||||
av_packet_unref(context->encoder_avpacket);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_MORE_DATA;
|
||||
}
|
||||
|
||||
static switch_status_t consume_h264_bitstream(h264_codec_context_t *context, switch_frame_t *frame)
|
||||
{
|
||||
AVPacket *pkt = &context->encoder_avpacket;
|
||||
our_h264_nalu_t *nalu = &context->nalus[context->nalu_current_index];
|
||||
uint8_t nalu_hdr = *(uint8_t *)(nalu->start);
|
||||
uint8_t nalu_type = nalu_hdr & 0x1f;
|
||||
uint8_t nri = nalu_hdr & 0x60;
|
||||
int left = nalu->len - (nalu->eat - nalu->start);
|
||||
uint8_t *p = frame->data;
|
||||
uint8_t start = nalu->start == nalu->eat ? 0x80 : 0;
|
||||
int n = nalu->len / SLICE_SIZE;
|
||||
int slice_size = nalu->len / (n + 1) + 1 + 2;
|
||||
|
||||
if (nalu->len <= SLICE_SIZE) {
|
||||
memcpy(frame->data, nalu->start, nalu->len);
|
||||
frame->datalen = nalu->len;
|
||||
context->nalu_current_index++;
|
||||
|
||||
if (context->nalus[context->nalu_current_index].len) {
|
||||
frame->m = 0;
|
||||
return SWITCH_STATUS_MORE_DATA;
|
||||
}
|
||||
|
||||
if (pkt->size > 0) av_packet_unref(pkt);
|
||||
|
||||
switch_clear_flag(frame, SFF_CNG);
|
||||
frame->m = 1;
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (left <= (slice_size - 2)) {
|
||||
p[0] = nri | 28; // FU-A
|
||||
p[1] = 0x40 | nalu_type;
|
||||
memcpy(p+2, nalu->eat, left);
|
||||
nalu->eat += left;
|
||||
frame->datalen = left + 2;
|
||||
context->nalu_current_index++;
|
||||
|
||||
if (!context->nalus[context->nalu_current_index].len) {
|
||||
if (pkt->size > 0) av_packet_unref(pkt);
|
||||
frame->m = 1;
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_MORE_DATA;
|
||||
}
|
||||
|
||||
p[0] = nri | 28; // FU-A
|
||||
p[1] = start | nalu_type;
|
||||
if (start) nalu->eat++;
|
||||
memcpy(p+2, nalu->eat, slice_size - 2);
|
||||
nalu->eat += (slice_size - 2);
|
||||
frame->datalen = slice_size;
|
||||
frame->m = 0;
|
||||
return SWITCH_STATUS_MORE_DATA;
|
||||
}
|
||||
|
||||
static switch_status_t consume_nalu(h264_codec_context_t *context, switch_frame_t *frame)
|
||||
{
|
||||
AVPacket *pkt = &context->encoder_avpacket;
|
||||
AVPacket *pkt = context->encoder_avpacket;
|
||||
our_h264_nalu_t *nalu = &context->nalus[context->nalu_current_index];
|
||||
|
||||
if (!nalu->len) {
|
||||
frame->datalen = 0;
|
||||
frame->m = 0;
|
||||
if (pkt->size > 0) av_packet_unref(pkt);
|
||||
if (pkt->size > 0) {
|
||||
av_packet_unref(pkt);
|
||||
}
|
||||
|
||||
context->nalu_current_index = 0;
|
||||
|
||||
return SWITCH_STATUS_NOTFOUND;
|
||||
}
|
||||
|
||||
@@ -1167,7 +1131,9 @@ static switch_status_t consume_nalu(h264_codec_context_t *context, switch_frame_
|
||||
return consume_h263p_bitstream(context, frame);
|
||||
}
|
||||
|
||||
return consume_h264_bitstream(context, frame);
|
||||
switch_assert(0);
|
||||
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
static void set_h264_private_data(h264_codec_context_t *context, avcodec_profile_t *profile)
|
||||
@@ -1342,9 +1308,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
|
||||
set_h264_private_data(context, aprofile);
|
||||
}
|
||||
|
||||
GCC_DIAG_OFF(deprecated-declarations)
|
||||
avcodec_string(codec_string, sizeof(codec_string), context->encoder_ctx, 0);
|
||||
GCC_DIAG_ON(deprecated-declarations)
|
||||
|
||||
dump_encoder_ctx(context->encoder_ctx);
|
||||
|
||||
@@ -1436,6 +1400,16 @@ static switch_status_t switch_h264_init(switch_codec_t *codec, switch_codec_flag
|
||||
}
|
||||
}
|
||||
|
||||
switch (context->av_codec_id) {
|
||||
case AV_CODEC_ID_H264:
|
||||
context->packetizer = switch_packetizer_create(SPT_H264_BITSTREAM, SLICE_SIZE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
context->encoder_avpacket = av_packet_alloc();
|
||||
|
||||
switch_buffer_create_dynamic(&(context->nalu_buffer), H264_NALU_BUFFER_SIZE, H264_NALU_BUFFER_SIZE * 8, 0);
|
||||
codec->private_info = context;
|
||||
|
||||
@@ -1460,7 +1434,7 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, switch_frame_t
|
||||
int ret;
|
||||
int *got_output = &context->got_encoded_output;
|
||||
AVFrame *avframe = NULL;
|
||||
AVPacket *pkt = &context->encoder_avpacket;
|
||||
AVPacket **pkt = &context->encoder_avpacket;
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
switch_image_t *img = frame->img;
|
||||
@@ -1480,6 +1454,16 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, switch_frame_t
|
||||
}
|
||||
|
||||
if (frame->flags & SFF_SAME_IMAGE) {
|
||||
if (context->packetizer) {
|
||||
switch_status_t status = switch_packetizer_read(context->packetizer, frame);
|
||||
|
||||
if (status == SWITCH_STATUS_SUCCESS && (*pkt)->size > 0) {
|
||||
av_packet_unref(*pkt);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
// read from nalu buffer
|
||||
return consume_nalu(context, frame);
|
||||
}
|
||||
@@ -1489,6 +1473,7 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, switch_frame_t
|
||||
if (open_encoder(context, width, height) != SWITCH_STATUS_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
avctx = context->encoder_ctx;
|
||||
}
|
||||
|
||||
@@ -1498,6 +1483,7 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, switch_frame_t
|
||||
if (open_encoder(context, width, height) != SWITCH_STATUS_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
avctx = context->encoder_ctx;
|
||||
}
|
||||
|
||||
@@ -1507,13 +1493,13 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, switch_frame_t
|
||||
if (open_encoder(context, width, height) != SWITCH_STATUS_SUCCESS) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
avctx = context->encoder_ctx;
|
||||
switch_set_flag(frame, SFF_WAIT_KEY_FRAME);
|
||||
}
|
||||
|
||||
av_init_packet(pkt);
|
||||
pkt->data = NULL; // packet data will be allocated by the encoder
|
||||
pkt->size = 0;
|
||||
av_packet_unref(*pkt);
|
||||
/* packet data will be allocated by the encoder */
|
||||
|
||||
avframe = context->encoder_avframe;
|
||||
|
||||
@@ -1578,14 +1564,42 @@ static switch_status_t switch_h264_encode(switch_codec_t *codec, switch_frame_t
|
||||
/* encode the image */
|
||||
memset(context->nalus, 0, sizeof(context->nalus));
|
||||
context->nalu_current_index = 0;
|
||||
#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V)
|
||||
GCC_DIAG_OFF(deprecated-declarations)
|
||||
ret = avcodec_encode_video2(avctx, pkt, avframe, got_output);
|
||||
ret = avcodec_encode_video2(avctx, *pkt, avframe, got_output);
|
||||
GCC_DIAG_ON(deprecated-declarations)
|
||||
|
||||
if (ret < 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Encoding Error %d\n", ret);
|
||||
goto error;
|
||||
}
|
||||
#else
|
||||
ret = avcodec_send_frame(avctx, avframe);
|
||||
|
||||
if (ret == AVERROR_EOF) {
|
||||
ret = 0;
|
||||
} else if (ret == AVERROR(EAGAIN)) {
|
||||
/* we fully drain all the output in each encode call, so this should not ever happen */
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "Error sending frame to encoder - BUG, should never happen\n");
|
||||
ret = AVERROR_BUG;
|
||||
goto error;
|
||||
} else if (ret < 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error sending frame to encoder\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_packet(avctx, *pkt);
|
||||
if (ret == AVERROR(EAGAIN)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "No more video packets at the moment\n");
|
||||
} else if (ret == AVERROR_EOF) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "No more video packets at all\n");
|
||||
} else if (ret < 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Encoding error\n");
|
||||
av_packet_unref(*pkt);
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (context->need_key_frame && avframe->key_frame == 1) {
|
||||
avframe->pict_type = 0;
|
||||
@@ -1595,81 +1609,78 @@ GCC_DIAG_ON(deprecated-declarations)
|
||||
|
||||
// process:
|
||||
|
||||
#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V)
|
||||
if (*got_output) {
|
||||
const uint8_t *p = pkt->data;
|
||||
int i = 0;
|
||||
#else
|
||||
if (ret >= 0) {
|
||||
#endif
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
|
||||
*got_output = 0;
|
||||
|
||||
if (context->av_codec_id == AV_CODEC_ID_H263) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG5,
|
||||
"Encoded frame %" SWITCH_INT64_T_FMT " (size=%5d) [0x%02x 0x%02x 0x%02x 0x%02x] got_output: %d slices: %d\n",
|
||||
context->pts, pkt->size, *((uint8_t *)pkt->data), *((uint8_t *)(pkt->data + 1)), *((uint8_t *)(pkt->data + 2)),
|
||||
*((uint8_t *)(pkt->data + 3)), *got_output, avctx->slices);
|
||||
context->pts, (*pkt)->size, *((uint8_t *)(*pkt)->data), *((uint8_t *)((*pkt)->data + 1)), *((uint8_t *)((*pkt)->data + 2)),
|
||||
*((uint8_t *)((*pkt)->data + 3)), *got_output, avctx->slices);
|
||||
|
||||
#ifdef H263_MODE_B
|
||||
fs_rtp_parse_h263_rfc2190(context, pkt);
|
||||
fs_rtp_parse_h263_rfc2190(context, *pkt);
|
||||
#endif
|
||||
|
||||
context->nalu_current_index = 0;
|
||||
|
||||
return consume_nalu(context, frame);
|
||||
} else if (context->av_codec_id == AV_CODEC_ID_H263P){
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG5,
|
||||
"Encoded frame %" SWITCH_INT64_T_FMT " (size=%5d) [0x%02x 0x%02x 0x%02x 0x%02x] got_output: %d slices: %d\n",
|
||||
context->pts, pkt->size, *((uint8_t *)pkt->data), *((uint8_t *)(pkt->data + 1)), *((uint8_t *)(pkt->data + 2)),
|
||||
*((uint8_t *)(pkt->data + 3)), *got_output, avctx->slices);
|
||||
fs_rtp_parse_h263_rfc4629(context, pkt);
|
||||
context->pts, (*pkt)->size, *((uint8_t *)(*pkt)->data), *((uint8_t *)((*pkt)->data + 1)), *((uint8_t *)((*pkt)->data + 2)),
|
||||
*((uint8_t *)((*pkt)->data + 3)), *got_output, avctx->slices);
|
||||
fs_rtp_parse_h263_rfc4629(context, *pkt);
|
||||
context->nalu_current_index = 0;
|
||||
|
||||
return consume_nalu(context, frame);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG5,
|
||||
"Encoded frame %" SWITCH_INT64_T_FMT " (size=%5d) nalu_type=0x%x %d\n",
|
||||
context->pts, pkt->size, *((uint8_t *)pkt->data +4), *got_output);
|
||||
}
|
||||
/* split into nalus */
|
||||
memset(context->nalus, 0, sizeof(context->nalus));
|
||||
|
||||
while ((p = fs_avc_find_startcode(p, pkt->data+pkt->size)) < (pkt->data + pkt->size)) {
|
||||
if (!context->nalus[i].start) {
|
||||
while (!(*p++)) ; /* eat the sync bytes, what ever 0 0 1 or 0 0 0 1 */
|
||||
context->nalus[i].start = p;
|
||||
context->nalus[i].eat = p;
|
||||
|
||||
if ((*p & 0x1f) == 7) { // Got Keyframe
|
||||
// prevent to generate key frame too frequently
|
||||
context->last_keyframe_request = switch_time_now();
|
||||
if (mod_av_globals.debug) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "KEY FRAME GENERATED\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
context->nalus[i].len = p - context->nalus[i].start;
|
||||
while (!(*p++)) ; /* eat the sync bytes, what ever 0 0 1 or 0 0 0 1 */
|
||||
i++;
|
||||
context->nalus[i].start = p;
|
||||
context->nalus[i].eat = p;
|
||||
}
|
||||
if (i >= MAX_NALUS - 2) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "TOO MANY SLICES!\n");
|
||||
break;
|
||||
}
|
||||
context->pts, (*pkt)->size, *((uint8_t *)(*pkt)->data +4), *got_output);
|
||||
}
|
||||
|
||||
context->nalus[i].len = p - context->nalus[i].start;
|
||||
context->nalu_current_index = 0;
|
||||
return consume_nalu(context, frame);
|
||||
status = switch_packetizer_feed(context->packetizer, (*pkt)->data, (*pkt)->size);
|
||||
if (status != SWITCH_STATUS_SUCCESS) {
|
||||
if ((*pkt)->size > 0) {
|
||||
av_packet_unref(*pkt);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
status = switch_packetizer_read(context->packetizer, frame);
|
||||
if (status == SWITCH_STATUS_SUCCESS && (*pkt)->size > 0) {
|
||||
av_packet_unref(*pkt);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#if (LIBAVCODEC_VERSION_MAJOR >= LIBAVCODEC_V)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
error:
|
||||
frame->datalen = 0;
|
||||
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
static switch_status_t switch_h264_decode(switch_codec_t *codec, switch_frame_t *frame)
|
||||
{
|
||||
h264_codec_context_t *context = (h264_codec_context_t *)codec->private_info;
|
||||
AVCodecContext *avctx= context->decoder_ctx;
|
||||
switch_status_t status;
|
||||
#if (LIBAVCODEC_VERSION_MAJOR >= LIBAVCODEC_V)
|
||||
int ret = 0;
|
||||
#endif
|
||||
|
||||
switch_assert(frame);
|
||||
|
||||
@@ -1702,27 +1713,57 @@ static switch_status_t switch_h264_decode(switch_codec_t *codec, switch_frame_t
|
||||
|
||||
if (frame->m) {
|
||||
uint32_t size = switch_buffer_inuse(context->nalu_buffer);
|
||||
AVPacket pkt = { 0 };
|
||||
AVPacket *pkt = NULL;
|
||||
AVFrame *picture;
|
||||
#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V)
|
||||
int got_picture = 0;
|
||||
int decoded_len;
|
||||
#endif
|
||||
|
||||
if (size > 0) {
|
||||
av_init_packet(&pkt);
|
||||
pkt = av_packet_alloc();
|
||||
switch_buffer_zero_fill(context->nalu_buffer, AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
switch_buffer_peek_zerocopy(context->nalu_buffer, (const void **)&pkt.data);
|
||||
pkt.size = size;
|
||||
switch_buffer_peek_zerocopy(context->nalu_buffer, (const void **)&pkt->data);
|
||||
pkt->size = size;
|
||||
|
||||
if (!context->decoder_avframe) context->decoder_avframe = av_frame_alloc();
|
||||
picture = context->decoder_avframe;
|
||||
switch_assert(picture);
|
||||
#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V)
|
||||
GCC_DIAG_OFF(deprecated-declarations)
|
||||
decoded_len = avcodec_decode_video2(avctx, picture, &got_picture, &pkt);
|
||||
decoded_len = avcodec_decode_video2(context->decoder_ctx, picture, &got_picture, pkt);
|
||||
GCC_DIAG_ON(deprecated-declarations)
|
||||
#else
|
||||
ret = avcodec_send_packet(context->decoder_ctx, pkt);
|
||||
|
||||
if (ret == AVERROR_EOF) {
|
||||
ret = 0;
|
||||
} else if (ret == AVERROR(EAGAIN)) {
|
||||
/* we fully drain all the output in each decode call, so this should not ever happen */
|
||||
ret = AVERROR_BUG;
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Error sending packet to decoder BUG, should never happen\n");
|
||||
} else if (ret < 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Error sending packet to decoder\n");
|
||||
}
|
||||
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_frame(context->decoder_ctx, picture);
|
||||
if (ret == AVERROR(EAGAIN)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "No more video frames at the moment\n");
|
||||
} else if (ret == AVERROR_EOF) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "No more video frames at all\n");
|
||||
} else if (ret < 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Video decoding error\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
// switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "buffer: %d got pic: %d len: %d [%dx%d]\n", size, got_picture, decoded_len, picture->width, picture->height);
|
||||
|
||||
#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V)
|
||||
if (got_picture && decoded_len > 0) {
|
||||
#else
|
||||
if (ret >= 0) {
|
||||
#endif
|
||||
int width = picture->width;
|
||||
int height = picture->height;
|
||||
|
||||
@@ -1744,7 +1785,15 @@ GCC_DIAG_ON(deprecated-declarations)
|
||||
frame->img = context->img;
|
||||
}
|
||||
|
||||
#if (LIBAVCODEC_VERSION_MAJOR >= LIBAVCODEC_V)
|
||||
if (ret < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
av_frame_unref(picture);
|
||||
av_packet_free(&pkt);
|
||||
}
|
||||
|
||||
switch_buffer_zero(context->nalu_buffer);
|
||||
@@ -1825,6 +1874,10 @@ static switch_status_t switch_h264_destroy(switch_codec_t *codec)
|
||||
av_free(context->encoder_ctx);
|
||||
}
|
||||
|
||||
if (context->packetizer) {
|
||||
switch_packetizer_close(&context->packetizer);
|
||||
}
|
||||
|
||||
if (context->encoder_avframe) {
|
||||
av_frame_free(&context->encoder_avframe);
|
||||
}
|
||||
@@ -1833,6 +1886,10 @@ static switch_status_t switch_h264_destroy(switch_codec_t *codec)
|
||||
av_frame_free(&context->decoder_avframe);
|
||||
}
|
||||
|
||||
if (context->encoder_avpacket) {
|
||||
av_packet_free(&context->encoder_avpacket);
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1860,8 +1917,10 @@ static const AVCodec *next_codec_for_id(enum AVCodecID id, const AVCodec *prev,
|
||||
#endif
|
||||
if (prev->id == id &&
|
||||
(encoder ? av_codec_is_encoder(prev) : av_codec_is_decoder(prev)))
|
||||
|
||||
return prev;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -2208,7 +2267,7 @@ static void parse_codecs(avcodec_profile_t *aprofile, switch_xml_t codecs)
|
||||
}
|
||||
|
||||
|
||||
static void load_config()
|
||||
static void load_config(void)
|
||||
{
|
||||
switch_xml_t cfg = NULL, xml = NULL;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -25,6 +25,7 @@
|
||||
*
|
||||
* Seven Du <dujinfang@gmail.com>
|
||||
* Anthony Minessale <anthm@freeswitch.org>
|
||||
* Jakub Karolczyk <jakub.karolczyk@signalwire.com>
|
||||
*
|
||||
* mod_av -- FS Video Codec / File Format using libav.org
|
||||
*
|
||||
@@ -33,7 +34,13 @@
|
||||
#include <switch.h>
|
||||
#include "mod_av.h"
|
||||
#include <libavcodec/avcodec.h>
|
||||
#ifdef _MSC_VER
|
||||
#include <libavcodec/version.h> /* LIBAVCODEC_VERSION_INT */
|
||||
#endif
|
||||
#include <libavformat/avformat.h>
|
||||
#ifdef _MSC_VER
|
||||
#include <libavformat/version.h> /* LIBAVFORMAT_VERSION_INT */
|
||||
#endif
|
||||
|
||||
SWITCH_MODULE_LOAD_FUNCTION(mod_avformat_load);
|
||||
SWITCH_MODULE_LOAD_FUNCTION(mod_avcodec_load);
|
||||
@@ -49,6 +56,7 @@ typedef struct av_mutex_helper_s {
|
||||
switch_memory_pool_t *pool;
|
||||
} av_mutex_helper_t;
|
||||
|
||||
#if (LIBAVCODEC_VERSION_MAJOR < LIBAVCODEC_V)
|
||||
int mod_av_lockmgr_cb(void **m, enum AVLockOp op)
|
||||
{
|
||||
av_mutex_helper_t *context = NULL;
|
||||
@@ -93,6 +101,7 @@ int mod_av_lockmgr_cb(void **m, enum AVLockOp op)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef AV_LOG_TRACE
|
||||
#define AV_LOG_TRACE 96
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
* Marcel Barbulescu <marcelbarbulescu@gmail.com>
|
||||
* Raymond Chandler <intralanman@gmail.com>
|
||||
* Emmanuel Schmidbauer <e.schmidbauer@gmail.com>
|
||||
* Jakub Karolczyk <jakub.karolczyk@signalwire.com>
|
||||
*
|
||||
*
|
||||
* mod_av.h -- LibAV mod
|
||||
@@ -39,6 +40,10 @@
|
||||
#ifndef MOD_AV_H
|
||||
#define MOD_AV_H
|
||||
|
||||
#define LIBAVCODEC_V 59
|
||||
#define LIBAVFORMAT_V 59
|
||||
#define LIBAVUTIL_V 57
|
||||
|
||||
struct mod_av_globals {
|
||||
int debug;
|
||||
};
|
||||
|
||||
@@ -86,7 +86,6 @@ typedef union {
|
||||
static uint32_t index_from_float(float f);
|
||||
static float float_from_index(uint32_t d);
|
||||
static float *acos_table = NULL;
|
||||
static int acos_fd = -1;
|
||||
|
||||
|
||||
#ifdef FAST_ACOSF_TESTING
|
||||
@@ -112,6 +111,10 @@ extern int compute_table(void)
|
||||
|
||||
acos_table_file = fopen(ACOS_TABLE_FILENAME, "w");
|
||||
|
||||
if (!acos_table_file) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
for (i = 0; i < ACOS_TABLE_LENGTH; i++) {
|
||||
f = acosf(float_from_index(i));
|
||||
res = fwrite(&f, sizeof(f), 1, acos_table_file);
|
||||
@@ -124,10 +127,12 @@ extern int compute_table(void)
|
||||
if (res != 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
fclose(acos_table_file);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -144,8 +149,9 @@ extern int init_fast_acosf(void)
|
||||
* or some other error occured */
|
||||
errsv = errno;
|
||||
strerror_r(errsv, err, 150);
|
||||
if (errsv != ENOENT) return -1;
|
||||
else {
|
||||
if (errsv != ENOENT) {
|
||||
return -1;
|
||||
} else {
|
||||
switch_log_printf(
|
||||
SWITCH_CHANNEL_LOG,
|
||||
SWITCH_LOG_NOTICE,
|
||||
@@ -166,10 +172,10 @@ extern int init_fast_acosf(void)
|
||||
acos_fp = fopen(ACOS_TABLE_FILENAME, "r");
|
||||
if (acos_fp == NULL) return -3;
|
||||
/* can't fail */
|
||||
acos_fd = fileno(acos_fp);
|
||||
acos_table = (float *) mmap(
|
||||
NULL, /* kernel chooses the address at which to create the mapping */
|
||||
ACOS_TABLE_LENGTH * sizeof(float), PROT_READ, MAP_SHARED, acos_fd, 0);
|
||||
ACOS_TABLE_LENGTH * sizeof(float), PROT_READ, MAP_SHARED, fileno(acos_fp), 0);
|
||||
fclose(acos_fp);
|
||||
if (acos_table == MAP_FAILED) return -4;
|
||||
|
||||
return 0;
|
||||
@@ -178,9 +184,7 @@ extern int init_fast_acosf(void)
|
||||
extern int destroy_fast_acosf(void)
|
||||
{
|
||||
if (munmap(acos_table, ACOS_TABLE_LENGTH) == -1) return -1;
|
||||
if (acos_fd != -1) {
|
||||
if (close(acos_fd) == -1) return -2;
|
||||
}
|
||||
|
||||
/* disable use of fast arc cosine file */
|
||||
acos_table = NULL;
|
||||
|
||||
|
||||
@@ -1138,6 +1138,13 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_avmd_load) {
|
||||
|
||||
switch_application_interface_t *app_interface;
|
||||
switch_api_interface_t *api_interface;
|
||||
|
||||
if (pool == NULL) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No memory pool assigned!\n");
|
||||
|
||||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
|
||||
/* connect my internal structure to the blank pointer passed to me */
|
||||
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
|
||||
|
||||
@@ -1147,10 +1154,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_avmd_load) {
|
||||
}
|
||||
|
||||
memset(&avmd_globals, 0, sizeof(avmd_globals));
|
||||
if (pool == NULL) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No memory pool assigned!\n");
|
||||
return SWITCH_STATUS_TERM;
|
||||
}
|
||||
switch_mutex_init(&avmd_globals.mutex, SWITCH_MUTEX_NESTED, pool);
|
||||
avmd_globals.pool = pool;
|
||||
|
||||
@@ -1622,9 +1625,6 @@ SWITCH_STANDARD_APP(avmd_start_function) {
|
||||
|
||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_avmd_shutdown) {
|
||||
size_t session_n;
|
||||
#ifndef WIN32
|
||||
int res;
|
||||
#endif
|
||||
|
||||
switch_mutex_lock(avmd_globals.mutex);
|
||||
|
||||
@@ -1638,18 +1638,8 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_avmd_shutdown) {
|
||||
|
||||
#ifndef WIN32
|
||||
if (avmd_globals.settings.fast_math == 1) {
|
||||
res = destroy_fast_acosf();
|
||||
if (res != 0) {
|
||||
switch (res) {
|
||||
case -1:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed unmap arc cosine table\n");
|
||||
break;
|
||||
case -2:
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed closing arc cosine table\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (destroy_fast_acosf()) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed unmap arc cosine table\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1658,6 +1648,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_avmd_shutdown) {
|
||||
switch_mutex_unlock(avmd_globals.mutex);
|
||||
switch_mutex_destroy(avmd_globals.mutex);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Advanced voicemail detection disabled\n");
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -1969,9 +1969,10 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
|
||||
playback_array(agent_session, o_announce);
|
||||
}
|
||||
|
||||
/* This is used for the waiting caller to quit waiting for a agent */
|
||||
/* This is used to set the reason for callcenter_function breakout */
|
||||
switch_channel_set_variable(member_channel, "cc_agent_found", "true");
|
||||
switch_channel_set_variable(member_channel, "cc_agent_uuid", agent_uuid);
|
||||
|
||||
if (switch_true(switch_channel_get_variable(member_channel, SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE)) || switch_true(switch_channel_get_variable(agent_channel, SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE))) {
|
||||
switch_channel_set_flag(member_channel, CF_BYPASS_MEDIA_AFTER_BRIDGE);
|
||||
}
|
||||
@@ -1990,6 +1991,12 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
|
||||
switch_channel_set_variable(agent_channel, "cc_agent_bridged", "false");
|
||||
switch_channel_set_variable(member_channel, "cc_agent_bridged", "false");
|
||||
|
||||
/* Set member to Abandoned state, previous Trying */
|
||||
sql = switch_mprintf("UPDATE members SET state = '%q', session_uuid = '', abandoned_epoch = '%" SWITCH_TIME_T_FMT "' WHERE uuid = '%q' AND instance_id = '%q'",
|
||||
cc_member_state2str(CC_MEMBER_STATE_ABANDONED), local_epoch_time_now(NULL), h->member_uuid, globals.cc_instance_id);
|
||||
cc_execute_sql(NULL, sql, NULL);
|
||||
switch_safe_free(sql);
|
||||
|
||||
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);
|
||||
@@ -2008,9 +2015,15 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
|
||||
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);
|
||||
|
||||
/* Update member to Answered state, previous Trying */
|
||||
sql = switch_mprintf("UPDATE members SET state = '%q', bridge_epoch = '%" SWITCH_TIME_T_FMT "' WHERE uuid = '%q' AND instance_id = '%q'",
|
||||
cc_member_state2str(CC_MEMBER_STATE_ANSWERED), local_epoch_time_now(NULL), h->member_uuid, globals.cc_instance_id);
|
||||
cc_execute_sql(NULL, sql, NULL);
|
||||
switch_safe_free(sql);
|
||||
}
|
||||
|
||||
if (bridged) {
|
||||
@@ -2111,7 +2124,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Agent didn't answer or originate failed */
|
||||
/* Agent didn't answer or originate/bridge failed */
|
||||
int delay_next_agent_call = 0;
|
||||
switch_channel_t *member_channel = switch_core_session_get_channel(member_session);
|
||||
switch_channel_clear_app_flag_key(CC_APP_KEY, member_channel, CC_APP_AGENT_CONNECTING);
|
||||
@@ -3051,6 +3064,10 @@ SWITCH_STANDARD_APP(callcenter_function)
|
||||
switch_channel_set_variable(member_channel, "cc_side", "member");
|
||||
switch_channel_set_variable(member_channel, "cc_member_uuid", member_uuid);
|
||||
|
||||
/* Clear flags in case previously set */
|
||||
switch_channel_set_variable(member_channel, "cc_agent_found", NULL);
|
||||
switch_channel_set_variable(member_channel, "cc_agent_bridged", NULL);
|
||||
|
||||
/* Add manually imported score */
|
||||
if (cc_base_score) {
|
||||
cc_base_score_int += atoi(cc_base_score);
|
||||
@@ -3178,8 +3195,8 @@ SWITCH_STANDARD_APP(callcenter_function)
|
||||
args.buf = (void *) &ht;
|
||||
args.buflen = sizeof(h);
|
||||
|
||||
/* An agent was found, time to exit and let the bridge do it job */
|
||||
if ((p = switch_channel_get_variable(member_channel, "cc_agent_found")) && (agent_found = switch_true(p))) {
|
||||
/* If the bridge didn't break the loop, break out now */
|
||||
if ((p = switch_channel_get_variable(member_channel, "cc_agent_bridged")) && (agent_found = switch_true(p))) {
|
||||
break;
|
||||
}
|
||||
/* If the member thread set a different reason, we monitor it so we can quit the wait */
|
||||
@@ -3201,8 +3218,6 @@ SWITCH_STANDARD_APP(callcenter_function)
|
||||
switch_channel_set_variable(member_channel, "cc_exit_key", buf);
|
||||
h->member_cancel_reason = CC_MEMBER_CANCEL_REASON_EXIT_WITH_KEY;
|
||||
break;
|
||||
} else if (!SWITCH_READ_ACCEPTABLE(status)) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch_status_t status = switch_ivr_collect_digits_callback(member_session, &args, 0, 0);
|
||||
@@ -3230,12 +3245,18 @@ SWITCH_STANDARD_APP(callcenter_function)
|
||||
h->running = 0;
|
||||
}
|
||||
|
||||
/* Stop uuid_broadcasts */
|
||||
switch_core_session_flush_private_events(member_session);
|
||||
switch_channel_stop_broadcast(member_channel);
|
||||
switch_channel_set_flag_value(member_channel, CF_BREAK, 2);
|
||||
|
||||
/* Check if we were removed because FS Core(BREAK) asked us to */
|
||||
if (h->member_cancel_reason == CC_MEMBER_CANCEL_REASON_NONE && !agent_found) {
|
||||
h->member_cancel_reason = CC_MEMBER_CANCEL_REASON_BREAK_OUT;
|
||||
}
|
||||
|
||||
switch_channel_set_variable(member_channel, "cc_agent_found", NULL);
|
||||
|
||||
/* Canceled for some reason */
|
||||
if (!switch_channel_up(member_channel) || h->member_cancel_reason != CC_MEMBER_CANCEL_REASON_NONE) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Member %s <%s> abandoned waiting in queue %s\n", switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_name")), switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number")), queue_name);
|
||||
@@ -3282,12 +3303,6 @@ SWITCH_STANDARD_APP(callcenter_function)
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_session), SWITCH_LOG_DEBUG, "Member %s <%s> is answered by an agent in queue %s\n", switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_name")), switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number")), queue_name);
|
||||
|
||||
/* Update member state */
|
||||
sql = switch_mprintf("UPDATE members SET state = '%q', bridge_epoch = '%" SWITCH_TIME_T_FMT "' WHERE uuid = '%q' AND instance_id = '%q'",
|
||||
cc_member_state2str(CC_MEMBER_STATE_ANSWERED), local_epoch_time_now(NULL), member_uuid, globals.cc_instance_id);
|
||||
cc_execute_sql(NULL, sql, NULL);
|
||||
switch_safe_free(sql);
|
||||
|
||||
/* Update some channel variables for xml_cdr needs */
|
||||
switch_channel_set_variable_printf(member_channel, "cc_cause", "%s", "answered");
|
||||
if ((queue = get_queue(queue_name))) {
|
||||
|
||||
@@ -347,7 +347,7 @@ static size_t file_callback(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
return realsize;
|
||||
}
|
||||
|
||||
static long do_lookup_url(switch_memory_pool_t *pool, switch_event_t *event, char **response, const char *query, struct curl_httppost *post,
|
||||
static long do_lookup_url(switch_memory_pool_t *pool, switch_event_t *event, char **response, const char *query, switch_curl_mime *post,
|
||||
switch_curl_slist_t *headers, int timeout)
|
||||
{
|
||||
switch_time_t start_time = switch_micro_time_now();
|
||||
@@ -373,7 +373,7 @@ static long do_lookup_url(switch_memory_pool_t *pool, switch_event_t *event, cha
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
}
|
||||
if (post) {
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPPOST, post);
|
||||
switch_curl_easy_setopt_mime(curl_handle, post);
|
||||
} else {
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPGET, 1);
|
||||
}
|
||||
@@ -845,6 +845,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_cidlookup_load)
|
||||
Macro expands to: switch_status_t mod_cidlookup_shutdown() */
|
||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_cidlookup_shutdown)
|
||||
{
|
||||
switch_xml_config_cleanup(instructions);
|
||||
switch_event_unbind(&reload_xml_event);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -2417,7 +2417,7 @@ SWITCH_STANDARD_API(uptime_function)
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#define CTL_SYNTAX "[recover|send_sighup|hupall|pause [inbound|outbound]|resume [inbound|outbound]|shutdown [cancel|elegant|asap|now|restart]|sps|sps_peak_reset|sync_clock|sync_clock_when_idle|reclaim_mem|max_sessions|min_dtmf_duration [num]|max_dtmf_duration [num]|default_dtmf_duration [num]|min_idle_cpu|loglevel [level]|debug_level [level]|mdns_resolve [enable|disable]]"
|
||||
#define CTL_SYNTAX "[api_expansion [on|off]|recover|send_sighup|hupall|pause [inbound|outbound]|resume [inbound|outbound]|shutdown [cancel|elegant|asap|now|restart]|sps|sps_peak_reset|sync_clock|sync_clock_when_idle|reclaim_mem|max_sessions|min_dtmf_duration [num]|max_dtmf_duration [num]|default_dtmf_duration [num]|min_idle_cpu|loglevel [level]|debug_level [level]|mdns_resolve [enable|disable]]"
|
||||
SWITCH_STANDARD_API(ctl_function)
|
||||
{
|
||||
int argc;
|
||||
@@ -3225,6 +3225,7 @@ SWITCH_STANDARD_API(uuid_capture_text)
|
||||
} else {
|
||||
if ((tsession = switch_core_session_locate(uuid))) {
|
||||
switch_ivr_capture_text(tsession, switch_true(onoff));
|
||||
switch_core_session_rwunlock(tsession);
|
||||
} else {
|
||||
stream->write_function(stream, "-ERR No such channel %s!\n", uuid);
|
||||
}
|
||||
@@ -5653,22 +5654,26 @@ SWITCH_STANDARD_API(alias_function)
|
||||
#define COALESCE_SYNTAX "[^^<delim>]<value1>,<value2>,..."
|
||||
SWITCH_STANDARD_API(coalesce_function)
|
||||
{
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
char *data = (char *) cmd;
|
||||
char *mydata = NULL, *argv[256] = { 0 };
|
||||
char *arg = (char *) cmd;
|
||||
int argc = -1;
|
||||
char delim = ',';
|
||||
|
||||
if (data && *data && (mydata = strdup(data))) {
|
||||
argc = switch_separate_string(mydata, ',', argv,
|
||||
if (!zstr(arg) && *arg == '^' && *(arg+1) == '^') {
|
||||
arg += 2;
|
||||
delim = *arg++;
|
||||
}
|
||||
|
||||
if (!zstr(arg) && (mydata = strdup(arg))) {
|
||||
argc = switch_separate_string(mydata, delim, argv,
|
||||
(sizeof(argv) / sizeof(argv[0])));
|
||||
}
|
||||
|
||||
if (argc > 0) {
|
||||
int i;
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (argv[i] && *argv[i]) {
|
||||
if (!zstr(argv[i])) {
|
||||
stream->write_function(stream, argv[i]);
|
||||
status = SWITCH_STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -5676,7 +5681,9 @@ SWITCH_STANDARD_API(coalesce_function)
|
||||
stream->write_function(stream, "-USAGE: %s\n", COALESCE_SYNTAX);
|
||||
}
|
||||
|
||||
return status;
|
||||
switch_safe_free(mydata);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#define SHOW_SYNTAX "codec|endpoint|application|api|dialplan|file|timer|calls [count]|channels [count|like <match string>]|calls|detailed_calls|bridged_calls|detailed_bridged_calls|aliases|complete|chat|management|modules|nat_map|say|interfaces|interface_types|tasks|limits|status"
|
||||
@@ -7745,6 +7752,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
|
||||
switch_console_set_complete("add complete add");
|
||||
switch_console_set_complete("add complete del");
|
||||
switch_console_set_complete("add db_cache status");
|
||||
switch_console_set_complete("add fsctl api_expansion on");
|
||||
switch_console_set_complete("add fsctl api_expansion off");
|
||||
switch_console_set_complete("add fsctl debug_level");
|
||||
switch_console_set_complete("add fsctl debug_pool");
|
||||
switch_console_set_complete("add fsctl debug_sql");
|
||||
@@ -7793,6 +7802,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
|
||||
switch_console_set_complete("add fsctl shutdown restart elegant");
|
||||
switch_console_set_complete("add fsctl sps");
|
||||
switch_console_set_complete("add fsctl sync_clock");
|
||||
switch_console_set_complete("add fsctl sync_clock_when_idle");
|
||||
switch_console_set_complete("add fsctl flush_db_handles");
|
||||
switch_console_set_complete("add fsctl min_idle_cpu");
|
||||
switch_console_set_complete("add fsctl send_sighup");
|
||||
|
||||
@@ -4087,7 +4087,6 @@ switch_status_t conference_api_sub_set(conference_obj_t *conference,
|
||||
|
||||
switch_status_t conference_api_sub_xml_list(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv)
|
||||
{
|
||||
int count = 0;
|
||||
switch_hash_index_t *hi;
|
||||
void *val;
|
||||
switch_xml_t x_conference, x_conferences;
|
||||
@@ -4106,7 +4105,6 @@ switch_status_t conference_api_sub_xml_list(conference_obj_t *conference, switch
|
||||
x_conference = switch_xml_add_child_d(x_conferences, "conference", off++);
|
||||
switch_assert(conference);
|
||||
|
||||
count++;
|
||||
conference_xlist(conference, x_conference, off);
|
||||
|
||||
}
|
||||
@@ -4114,7 +4112,7 @@ switch_status_t conference_api_sub_xml_list(conference_obj_t *conference, switch
|
||||
} else {
|
||||
x_conference = switch_xml_add_child_d(x_conferences, "conference", off++);
|
||||
switch_assert(conference);
|
||||
count++;
|
||||
|
||||
conference_xlist(conference, x_conference, off);
|
||||
}
|
||||
|
||||
|
||||
@@ -662,6 +662,9 @@ void conference_cdr_render(conference_obj_t *conference)
|
||||
x_tag = switch_xml_add_child_d(x_flags, "end_conference", flag_off++);
|
||||
switch_xml_set_txt_d(x_tag, conference_cdr_test_mflag(np, MFLAG_ENDCONF) ? "true" : "false");
|
||||
|
||||
x_tag = switch_xml_add_child_d(x_flags, "mandatory_member_end_conference", flag_off++);
|
||||
switch_xml_set_txt_d(x_tag, conference_cdr_test_mflag(np, MFLAG_MANDATORY_MEMBER_ENDCONF) ? "true" : "false");
|
||||
|
||||
x_tag = switch_xml_add_child_d(x_flags, "was_kicked", flag_off++);
|
||||
switch_xml_set_txt_d(x_tag, conference_cdr_test_mflag(np, MFLAG_KICKED) ? "true" : "false");
|
||||
|
||||
@@ -737,7 +740,7 @@ void conference_cdr_render(conference_obj_t *conference)
|
||||
#endif
|
||||
int wrote;
|
||||
wrote = write(fd, xml_text, (unsigned) strlen(xml_text));
|
||||
wrote++;
|
||||
(void)wrote;
|
||||
close(fd);
|
||||
} else {
|
||||
char ebuf[512] = { 0 };
|
||||
|
||||
@@ -75,7 +75,7 @@ struct _mapping control_mappings[] = {
|
||||
{"deaf off", conference_loop_deaf_off}
|
||||
};
|
||||
|
||||
int conference_loop_mapping_len()
|
||||
int conference_loop_mapping_len(void)
|
||||
{
|
||||
return (sizeof(control_mappings)/sizeof(control_mappings[0]));
|
||||
}
|
||||
|
||||
@@ -766,7 +766,12 @@ switch_status_t conference_member_add(conference_obj_t *conference, conference_m
|
||||
conference->count++;
|
||||
}
|
||||
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_ENDCONF)) {
|
||||
conference->endconference_time = 0;
|
||||
}
|
||||
|
||||
if (conference_utils_member_test_flag(member, MFLAG_MANDATORY_MEMBER_ENDCONF)) {
|
||||
if (conference->end_count++) {
|
||||
conference->endconference_time = 0;
|
||||
}
|
||||
@@ -1314,9 +1319,14 @@ switch_status_t conference_member_del(conference_obj_t *conference, conference_m
|
||||
|
||||
conference_video_check_flush(member, SWITCH_FALSE);
|
||||
|
||||
/* End conference when any member with "endconf" flag disconnects */
|
||||
if (conference_utils_member_test_flag(member, MFLAG_ENDCONF)) {
|
||||
conference_utils_set_flag_locked(conference, CFLAG_DESTRUCT);
|
||||
}
|
||||
|
||||
/* End conference only if all mandatory members have disconnected */
|
||||
if (conference_utils_member_test_flag(member, MFLAG_MANDATORY_MEMBER_ENDCONF)) {
|
||||
if (!--conference->end_count) {
|
||||
//conference_utils_set_flag_locked(conference, CFLAG_DESTRUCT);
|
||||
conference->endconference_time = switch_epoch_time_now(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,6 +132,8 @@ void conference_utils_set_mflags(const char *flags, member_flag_t *f)
|
||||
f[MFLAG_NOMOH] = 1;
|
||||
} else if (!strcasecmp(argv[i], "endconf")) {
|
||||
f[MFLAG_ENDCONF] = 1;
|
||||
} else if (!strcasecmp(argv[i], "mandatory_member_endconf")) {
|
||||
f[MFLAG_MANDATORY_MEMBER_ENDCONF] = 1;
|
||||
} else if (!strcasecmp(argv[i], "mintwo")) {
|
||||
f[MFLAG_MINTWO] = 1;
|
||||
} else if (!strcasecmp(argv[i], "talk-data-events")) {
|
||||
|
||||
@@ -3803,6 +3803,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) ||
|
||||
(conference_utils_test_flag(omember->conference, CFLAG_VIDEO_MUTE_EXIT_CANVAS) && !conference_utils_member_test_flag(omember, MFLAG_CAN_BE_SEEN)) ||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1347,6 +1347,9 @@ void conference_xlist(conference_obj_t *conference, switch_xml_t x_conference, i
|
||||
x_tag = switch_xml_add_child_d(x_flags, "end_conference", count++);
|
||||
switch_xml_set_txt_d(x_tag, conference_utils_member_test_flag(member, MFLAG_ENDCONF) ? "true" : "false");
|
||||
|
||||
x_tag = switch_xml_add_child_d(x_flags, "mandatory_member_end_conference", count++);
|
||||
switch_xml_set_txt_d(x_tag, conference_utils_member_test_flag(member, MFLAG_MANDATORY_MEMBER_ENDCONF) ? "true" : "false");
|
||||
|
||||
x_tag = switch_xml_add_child_d(x_flags, "is_ghost", count++);
|
||||
switch_xml_set_txt_d(x_tag, conference_utils_member_test_flag(member, MFLAG_GHOST) ? "true" : "false");
|
||||
|
||||
@@ -1456,6 +1459,7 @@ void conference_jlist(conference_obj_t *conference, cJSON *json_conferences)
|
||||
ADDBOOL(json_conference_member_flags, "has_floor", member->id == member->conference->floor_holder);
|
||||
ADDBOOL(json_conference_member_flags, "is_moderator", conference_utils_member_test_flag(member, MFLAG_MOD));
|
||||
ADDBOOL(json_conference_member_flags, "end_conference", conference_utils_member_test_flag(member, MFLAG_ENDCONF));
|
||||
ADDBOOL(json_conference_member_flags, "mandatory_member_end_conference", conference_utils_member_test_flag(member, MFLAG_MANDATORY_MEMBER_ENDCONF));
|
||||
ADDBOOL(json_conference_member_flags, "pass_digits", conference_utils_member_test_flag(member, MFLAG_DIST_DTMF));
|
||||
}
|
||||
switch_mutex_unlock(conference->member_mutex);
|
||||
|
||||
@@ -178,6 +178,7 @@ typedef enum {
|
||||
MFLAG_NO_MINIMIZE_ENCODING,
|
||||
MFLAG_FLUSH_BUFFER,
|
||||
MFLAG_ENDCONF,
|
||||
MFLAG_MANDATORY_MEMBER_ENDCONF,
|
||||
MFLAG_HAS_AUDIO,
|
||||
MFLAG_TALKING,
|
||||
MFLAG_RESTART,
|
||||
@@ -1123,7 +1124,7 @@ void conference_video_canvas_del_fnode_layer(conference_obj_t *conference, confe
|
||||
void conference_video_canvas_set_fnode_layer(mcu_canvas_t *canvas, conference_file_node_t *fnode, int idx);
|
||||
void conference_list(conference_obj_t *conference, switch_stream_handle_t *stream, char *delim);
|
||||
const char *conference_utils_combine_flag_var(switch_core_session_t *session, const char *var_name);
|
||||
int conference_loop_mapping_len();
|
||||
int conference_loop_mapping_len(void);
|
||||
void conference_api_set_agc(conference_member_t *member, const char *data);
|
||||
|
||||
switch_status_t conference_outcall(conference_obj_t *conference,
|
||||
|
||||
@@ -104,8 +104,13 @@ struct http_sendfile_data_obj {
|
||||
char *extrapost_elements;
|
||||
switch_CURL *curl_handle;
|
||||
char *cacert;
|
||||
#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800)
|
||||
curl_mime *mime;
|
||||
curl_mimepart *part;
|
||||
#else
|
||||
struct curl_httppost *formpost;
|
||||
struct curl_httppost *lastptr;
|
||||
#endif
|
||||
uint8_t flags; /* This is for where to send output of the curl_sendfile commands */
|
||||
switch_stream_handle_t *stream;
|
||||
char *sendfile_response;
|
||||
@@ -456,8 +461,19 @@ static void http_sendfile_initialize_curl(http_sendfile_data_t *http_data)
|
||||
curl_easy_setopt(http_data->curl_handle, CURLOPT_WRITEFUNCTION, http_sendfile_response_callback);
|
||||
curl_easy_setopt(http_data->curl_handle, CURLOPT_WRITEDATA, (void *) http_data);
|
||||
|
||||
/* Initial http_data->mime */
|
||||
#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800)
|
||||
http_data->mime = curl_mime_init(http_data->curl_handle);
|
||||
#endif
|
||||
|
||||
/* Add the file to upload as a POST form field */
|
||||
#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800)
|
||||
http_data->part = curl_mime_addpart(http_data->mime);
|
||||
curl_mime_name(http_data->part, http_data->filename_element_name);
|
||||
curl_mime_filedata(http_data->part, http_data->filename_element);
|
||||
#else
|
||||
curl_formadd(&http_data->formpost, &http_data->lastptr, CURLFORM_COPYNAME, http_data->filename_element_name, CURLFORM_FILE, http_data->filename_element, CURLFORM_END);
|
||||
#endif
|
||||
|
||||
if(!zstr(http_data->extrapost_elements))
|
||||
{
|
||||
@@ -476,16 +492,32 @@ static void http_sendfile_initialize_curl(http_sendfile_data_t *http_data)
|
||||
if(argc2 == 2) {
|
||||
switch_url_decode(argv2[0]);
|
||||
switch_url_decode(argv2[1]);
|
||||
#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800)
|
||||
http_data->part = curl_mime_addpart(http_data->mime);
|
||||
curl_mime_name(http_data->part, argv2[0]);
|
||||
curl_mime_data(http_data->part, argv2[1], CURL_ZERO_TERMINATED);
|
||||
#else
|
||||
curl_formadd(&http_data->formpost, &http_data->lastptr, CURLFORM_COPYNAME, argv2[0], CURLFORM_COPYCONTENTS, argv2[1], CURLFORM_END);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill in the submit field too, even if this isn't really needed */
|
||||
#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800)
|
||||
http_data->part = curl_mime_addpart(http_data->mime);
|
||||
curl_mime_name(http_data->part, "submit");
|
||||
curl_mime_data(http_data->part, "or_die", CURL_ZERO_TERMINATED);
|
||||
#else
|
||||
curl_formadd(&http_data->formpost, &http_data->lastptr, CURLFORM_COPYNAME, "submit", CURLFORM_COPYCONTENTS, "or_die", CURLFORM_END);
|
||||
#endif
|
||||
|
||||
/* what URL that receives this POST */
|
||||
#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800)
|
||||
curl_easy_setopt(http_data->curl_handle, CURLOPT_MIMEPOST, http_data->mime);
|
||||
#else
|
||||
curl_easy_setopt(http_data->curl_handle, CURLOPT_HTTPPOST, http_data->formpost);
|
||||
#endif
|
||||
|
||||
// This part actually fires off the curl, captures the HTTP response code, and then frees up the handle.
|
||||
curl_easy_perform(http_data->curl_handle);
|
||||
@@ -494,7 +526,11 @@ static void http_sendfile_initialize_curl(http_sendfile_data_t *http_data)
|
||||
curl_easy_cleanup(http_data->curl_handle);
|
||||
|
||||
// Clean up the form data from POST
|
||||
#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800)
|
||||
curl_mime_free(http_data->mime);
|
||||
#else
|
||||
curl_formfree(http_data->formpost);
|
||||
#endif
|
||||
}
|
||||
|
||||
static switch_status_t http_sendfile_test_file_open(http_sendfile_data_t *http_data, switch_event_t *event)
|
||||
|
||||
@@ -854,7 +854,7 @@ static switch_status_t video_thread_callback(switch_core_session_t *session, swi
|
||||
}
|
||||
|
||||
if (context->rawImage && (context->debug || !context->overlay_count)) {
|
||||
switch_img_from_raw(frame->img, (uint8_t *)context->rawImage->imageData, SWITCH_IMG_FMT_RGB24, context->rawImage->width, context->rawImage->height);
|
||||
switch_img_from_raw(&frame->img, (uint8_t *)context->rawImage->imageData, SWITCH_IMG_FMT_RGB24, context->rawImage->width, context->rawImage->height);
|
||||
}
|
||||
|
||||
int abs = 0;
|
||||
|
||||
@@ -280,7 +280,7 @@ static switch_xml_config_item_t config_settings[] = {
|
||||
SWITCH_CONFIG_ITEM_END()
|
||||
};
|
||||
|
||||
static switch_status_t do_config()
|
||||
static switch_status_t do_config(void)
|
||||
{
|
||||
switch_cache_db_handle_t *dbh = NULL;
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
|
||||
@@ -161,7 +161,6 @@ static switch_status_t digit_action_callback(switch_ivr_dmachine_match_t *match)
|
||||
char *string = NULL;
|
||||
switch_channel_t *channel;
|
||||
switch_core_session_t *use_session = act->session;
|
||||
int x = 0;
|
||||
char *flags = "";
|
||||
|
||||
if (act->target == DIGIT_TARGET_PEER || act->target == DIGIT_TARGET_BOTH) {
|
||||
@@ -171,7 +170,6 @@ static switch_status_t digit_action_callback(switch_ivr_dmachine_match_t *match)
|
||||
}
|
||||
|
||||
top:
|
||||
x++;
|
||||
|
||||
string = switch_core_session_strdup(use_session, act->string);
|
||||
exec = 0;
|
||||
@@ -4584,7 +4582,7 @@ SWITCH_STANDARD_APP(wait_for_silence_function)
|
||||
timeout_ms = switch_atoui(argv[3]);
|
||||
}
|
||||
|
||||
if (thresh > 0 && silence_hits > 0 && listen_hits >= 0) {
|
||||
if (thresh > 0 && silence_hits > 0) {
|
||||
switch_ivr_wait_for_silence(session, thresh, silence_hits, listen_hits, timeout_ms, argv[4]);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -497,6 +497,7 @@ switch_status_t ldns_lookup(const char *number, const char *root, char *server_n
|
||||
/* create a new resolver from /etc/resolv.conf */
|
||||
if (res) {
|
||||
ldns_resolver_free(res);
|
||||
res = NULL;
|
||||
}
|
||||
s = ldns_resolver_new_frm_file(&res, NULL);
|
||||
}
|
||||
|
||||
@@ -1419,7 +1419,7 @@ static switch_status_t httapi_sync(client_t *client)
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
int get_style_method = 0;
|
||||
char *method = NULL;
|
||||
struct curl_httppost *formpost=NULL;
|
||||
switch_curl_mime *formpost = NULL;
|
||||
switch_event_t *save_params = NULL;
|
||||
const char *put_file;
|
||||
FILE *fd = NULL;
|
||||
@@ -1476,7 +1476,7 @@ static switch_status_t httapi_sync(client_t *client)
|
||||
}
|
||||
|
||||
if (!put_file) {
|
||||
switch_curl_process_form_post_params(client->params, curl_handle, &formpost);
|
||||
switch_curl_process_mime(client->params, curl_handle, &formpost);
|
||||
}
|
||||
|
||||
if (formpost) {
|
||||
@@ -1588,7 +1588,7 @@ static switch_status_t httapi_sync(client_t *client)
|
||||
curl_easy_setopt(curl_handle, CURLOPT_READFUNCTION, put_file_read);
|
||||
|
||||
} else if (formpost) {
|
||||
curl_easy_setopt(curl_handle, CURLOPT_HTTPPOST, formpost);
|
||||
switch_curl_easy_setopt_mime(curl_handle, formpost);
|
||||
} else {
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_POST, !get_style_method);
|
||||
}
|
||||
@@ -1670,9 +1670,7 @@ static switch_status_t httapi_sync(client_t *client)
|
||||
switch_curl_easy_cleanup(curl_handle);
|
||||
switch_curl_slist_free_all(headers);
|
||||
|
||||
if (formpost) {
|
||||
curl_formfree(formpost);
|
||||
}
|
||||
switch_curl_mime_free(&formpost);
|
||||
|
||||
if (client->err) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error encountered! [%s]\ndata: [%s]\n", client->profile->url, data);
|
||||
|
||||
@@ -279,7 +279,11 @@ switch_status_t azure_blob_finalise_put(http_profile_t *profile, const char *url
|
||||
goto done;
|
||||
}
|
||||
|
||||
#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x070c01)
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_UPLOAD, 1);
|
||||
#else
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_PUT, 1);
|
||||
#endif
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers);
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_URL, full_url);
|
||||
|
||||
@@ -393,7 +393,9 @@ static switch_status_t http_put(url_cache_t *cache, http_profile_t *profile, swi
|
||||
goto done;
|
||||
}
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_UPLOAD, 1);
|
||||
#if !defined(LIBCURL_VERSION_NUM) || (LIBCURL_VERSION_NUM < 0x070c01)
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_PUT, 1);
|
||||
#endif
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers);
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_URL, full_url);
|
||||
|
||||
@@ -370,6 +370,11 @@ static switch_bool_t ladspa_callback(switch_media_bug_t *bug, void *user_data, s
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pvt->ldesc->activate) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "ACTIVATE\n");
|
||||
pvt->ldesc->activate(pvt->handle);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -382,6 +387,10 @@ static switch_bool_t ladspa_callback(switch_media_bug_t *bug, void *user_data, s
|
||||
}
|
||||
|
||||
if (pvt->handle && pvt->ldesc) {
|
||||
if (pvt->ldesc->deactivate) {
|
||||
pvt->ldesc->deactivate(pvt->handle);
|
||||
}
|
||||
|
||||
pvt->ldesc->cleanup(pvt->handle);
|
||||
}
|
||||
|
||||
|
||||
@@ -228,7 +228,7 @@ static ks_status_t load_credentials_from_json(ks_json_t *json)
|
||||
const char *relay_connector_id = NULL;
|
||||
|
||||
#if SIGNALWIRE_CLIENT_C_VERSION_MAJOR >= 2
|
||||
if ((bootstrap = ks_json_get_string(json, "bootstrap")) == NULL) {
|
||||
if ((bootstrap = ks_json_get_object_string(json, "bootstrap", NULL)) == NULL) {
|
||||
#else
|
||||
if ((bootstrap = ks_json_get_object_cstr(json, "bootstrap")) == NULL) {
|
||||
#endif
|
||||
@@ -238,7 +238,7 @@ static ks_status_t load_credentials_from_json(ks_json_t *json)
|
||||
}
|
||||
|
||||
#if SIGNALWIRE_CLIENT_C_VERSION_MAJOR >= 2
|
||||
if ((relay_connector_id = ks_json_get_string(json, "relay_connector_id")) == NULL) {
|
||||
if ((relay_connector_id = ks_json_get_object_string(json, "relay_connector_id", NULL)) == NULL) {
|
||||
#else
|
||||
if ((relay_connector_id = ks_json_get_object_cstr(json, "relay_connector_id")) == NULL) {
|
||||
#endif
|
||||
@@ -704,7 +704,7 @@ done:
|
||||
return status;
|
||||
}
|
||||
|
||||
static switch_status_t load_config()
|
||||
static switch_status_t load_config(void)
|
||||
{
|
||||
char *cf = "signalwire.conf";
|
||||
switch_xml_t cfg, xml;
|
||||
@@ -797,6 +797,7 @@ static ks_status_t load_credentials(void)
|
||||
status = KS_STATUS_FAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
json = ks_json_parse(data);
|
||||
@@ -805,6 +806,7 @@ static ks_status_t load_credentials(void)
|
||||
status = KS_STATUS_FAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
status = load_credentials_from_json(json);
|
||||
ks_json_delete(&json);
|
||||
|
||||
@@ -981,7 +983,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_signalwire_load)
|
||||
#ifdef WIN32
|
||||
sslLoadWindowsCACertificate();
|
||||
#endif
|
||||
|
||||
// Configuration
|
||||
swclt_config_create(&globals.config);
|
||||
load_config();
|
||||
@@ -1206,6 +1207,7 @@ static void mod_signalwire_state_configure(void)
|
||||
#if SIGNALWIRE_CLIENT_C_VERSION_MAJOR >= 2
|
||||
if (!swclt_sess_provisioning_configure(globals.signalwire_session, "freeswitch", local_endpoint, external_endpoint, globals.relay_connector_id, &reply)) {
|
||||
if (reply->type == SWCLT_CMD_TYPE_RESULT) {
|
||||
ks_json_t *result;
|
||||
#else
|
||||
if (!swclt_sess_provisioning_configure(globals.signalwire_session, "freeswitch", local_endpoint, external_endpoint, globals.relay_connector_id, &cmd)) {
|
||||
SWCLT_CMD_TYPE cmd_type;
|
||||
@@ -1215,7 +1217,8 @@ static void mod_signalwire_state_configure(void)
|
||||
#endif
|
||||
signalwire_provisioning_configure_response_t *configure_res;
|
||||
#if SIGNALWIRE_CLIENT_C_VERSION_MAJOR >= 2
|
||||
if (!SIGNALWIRE_PROVISIONING_CONFIGURE_RESPONSE_PARSE(reply->pool, reply->json, &configure_res)) {
|
||||
result = ks_json_get_object_item(reply->json, "result");
|
||||
if (!SIGNALWIRE_PROVISIONING_CONFIGURE_RESPONSE_PARSE(reply->pool, result, &configure_res)) {
|
||||
#else
|
||||
swclt_cmd_result(cmd, &result);
|
||||
result = ks_json_get_object_item(result, "result");
|
||||
@@ -1223,7 +1226,7 @@ static void mod_signalwire_state_configure(void)
|
||||
#endif
|
||||
ks_json_t *configuration = configure_res->configuration;
|
||||
#if SIGNALWIRE_CLIENT_C_VERSION_MAJOR >= 2
|
||||
const char *configuration_profile = ks_json_get_string(configuration, "profile");
|
||||
const char *configuration_profile = ks_json_get_object_string(configuration, "profile", NULL);
|
||||
#else
|
||||
const char *configuration_profile = ks_json_get_object_cstr(configuration, "profile");
|
||||
#endif
|
||||
@@ -1231,6 +1234,7 @@ static void mod_signalwire_state_configure(void)
|
||||
switch_xml_free(globals.signalwire_profile);
|
||||
globals.signalwire_profile = NULL;
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\"%s\"\n", configuration_profile);
|
||||
globals.signalwire_profile = switch_xml_parse_str_dynamic((char *)configuration_profile, SWITCH_TRUE);
|
||||
if (!globals.signalwire_profile) {
|
||||
@@ -1386,7 +1390,7 @@ static void mod_signalwire_state_register(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void mod_signalwire_state_ready()
|
||||
static void mod_signalwire_state_ready(void)
|
||||
{
|
||||
if (globals.profile_update) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Signalwire SIP profile update initiated\n");
|
||||
|
||||
@@ -897,9 +897,7 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
||||
|
||||
fail:
|
||||
|
||||
if (new_session) {
|
||||
switch_core_session_destroy(new_session);
|
||||
}
|
||||
switch_core_session_destroy(new_session);
|
||||
|
||||
if (modem) {
|
||||
modem_set_state(modem, MODEM_STATE_ONHOOK);
|
||||
|
||||
@@ -130,6 +130,7 @@ static void translate_number(char *number, char *profile, char **translated, swi
|
||||
hi = switch_core_hash_find_rdlock(globals.translate_profiles, (const char *)profile, globals.profile_hash_rwlock);
|
||||
if (!hi) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "can't find key for profile matching [%s]\n", profile);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -142,6 +143,7 @@ static void translate_number(char *number, char *profile, char **translated, swi
|
||||
switch_regex_safe_free(re);
|
||||
goto end;
|
||||
}
|
||||
|
||||
memset(substituted, 0, len);
|
||||
|
||||
switch_perform_substitution(re, proceed, rule->replace, number, substituted, len, ovector);
|
||||
@@ -153,16 +155,21 @@ static void translate_number(char *number, char *profile, char **translated, swi
|
||||
} else if (event) {
|
||||
subbed = switch_event_expand_headers(event, substituted);
|
||||
}
|
||||
|
||||
if (subbed != substituted) {
|
||||
switch_safe_free(substituted);
|
||||
}
|
||||
|
||||
if (session) {
|
||||
substituted = switch_core_session_strdup(session, subbed);
|
||||
} else {
|
||||
substituted = switch_core_strdup(pool, subbed);
|
||||
}
|
||||
if (subbed != substituted) {
|
||||
switch_safe_free(subbed);
|
||||
}
|
||||
|
||||
switch_safe_free(subbed);
|
||||
}
|
||||
|
||||
switch_regex_safe_free(re);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -645,7 +645,7 @@ static switch_status_t video_thread_callback(switch_core_session_t *session, swi
|
||||
}
|
||||
|
||||
|
||||
switch_img_from_raw(frame->img, patch_data, SWITCH_IMG_FMT_ARGB, frame->img->d_w, frame->img->d_h);
|
||||
switch_img_from_raw(&frame->img, patch_data, SWITCH_IMG_FMT_ARGB, frame->img->d_w, frame->img->d_h);
|
||||
|
||||
switch_img_free(&img);
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ extern int switch_amr_array_lshift(uint8_t lshift, uint8_t *buf, int a_len)
|
||||
if (!buf || !a_len)
|
||||
return (-1);
|
||||
|
||||
if ((lshift < 0) || (lshift > 8))
|
||||
if (lshift > 8)
|
||||
return (-1);
|
||||
|
||||
first_byte = 0xFF >> lshift;
|
||||
|
||||
@@ -48,7 +48,7 @@ static switch_status_t switch_ilbc_fmtp_parse(const char *fmtp, switch_codec_fmt
|
||||
|
||||
memset(codec_fmtp, '\0', sizeof(struct switch_codec_fmtp));
|
||||
|
||||
if (fmtp && (mode = strstr(fmtp, "mode=")) && (mode + 5)) {
|
||||
if (fmtp && (mode = strstr(fmtp, "mode=")) && *(mode + 5)) {
|
||||
codec_ms = atoi(mode + 5);
|
||||
}
|
||||
if (!codec_ms) {
|
||||
|
||||
@@ -4,7 +4,7 @@ MODNAME=mod_opus
|
||||
if HAVE_OPUS
|
||||
|
||||
mod_LTLIBRARIES = mod_opus.la
|
||||
mod_opus_la_SOURCES = mod_opus.c
|
||||
mod_opus_la_SOURCES = mod_opus.c opus_parse.c
|
||||
mod_opus_la_CFLAGS = $(AM_CFLAGS) $(OPUS_CFLAGS)
|
||||
mod_opus_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(OPUS_LIBS)
|
||||
mod_opus_la_LDFLAGS = -avoid-version -module -no-undefined -shared -lm -lz
|
||||
|
||||
@@ -130,6 +130,10 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="mod_opus.c" />
|
||||
<ClCompile Include="opus_parse.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="opus_parse.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\libs\win32\opus\opus.2017.vcxproj">
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
#include "switch.h"
|
||||
#include "opus.h"
|
||||
#include "opus_parse.h"
|
||||
|
||||
#define SWITCH_OPUS_MIN_BITRATE 6000
|
||||
#define SWITCH_OPUS_MAX_BITRATE 510000
|
||||
@@ -142,25 +143,26 @@ struct opus_context {
|
||||
dec_stats_t decoder_stats;
|
||||
enc_stats_t encoder_stats;
|
||||
codec_control_state_t control_state;
|
||||
switch_bool_t recreate_decoder;
|
||||
};
|
||||
|
||||
struct {
|
||||
int use_vbr;
|
||||
int use_dtx;
|
||||
switch_bool_t use_vbr;
|
||||
switch_bool_t use_dtx;
|
||||
int complexity;
|
||||
int maxaveragebitrate;
|
||||
int maxplaybackrate;
|
||||
int sprop_maxcapturerate;
|
||||
int plpct;
|
||||
int asymmetric_samplerates;
|
||||
int bitrate_negotiation;
|
||||
int keep_fec;
|
||||
int fec_decode;
|
||||
int adjust_bitrate;
|
||||
switch_bool_t asymmetric_samplerates;
|
||||
switch_bool_t bitrate_negotiation;
|
||||
switch_bool_t keep_fec;
|
||||
switch_bool_t fec_decode;
|
||||
switch_bool_t adjust_bitrate;
|
||||
int debuginfo;
|
||||
uint32_t use_jb_lookahead;
|
||||
switch_bool_t use_jb_lookahead;
|
||||
switch_mutex_t *mutex;
|
||||
int mono;
|
||||
switch_bool_t mono;
|
||||
} opus_prefs;
|
||||
|
||||
static struct {
|
||||
@@ -272,10 +274,12 @@ static switch_status_t switch_opus_fmtp_parse(const char *fmtp, switch_codec_fmt
|
||||
|
||||
if (!strcasecmp(data, "maxptime")) {
|
||||
codec_settings->maxptime = atoi(arg);
|
||||
codec_fmtp->max_ptime = codec_settings->maxptime;
|
||||
}
|
||||
|
||||
if (!strcasecmp(data, "minptime")) {
|
||||
codec_settings->minptime = atoi(arg);
|
||||
codec_fmtp->min_ptime = codec_settings->minptime;
|
||||
}
|
||||
|
||||
if (!strcasecmp(data, "ptime")) {
|
||||
@@ -290,6 +294,7 @@ static switch_status_t switch_opus_fmtp_parse(const char *fmtp, switch_codec_fmt
|
||||
|
||||
if (!strcasecmp(data, "sprop-stereo")) {
|
||||
codec_settings->sprop_stereo = atoi(arg);
|
||||
codec_fmtp->sprop_stereo = codec_settings->sprop_stereo;
|
||||
}
|
||||
|
||||
if (!strcasecmp(data, "maxaveragebitrate")) {
|
||||
@@ -310,6 +315,10 @@ static switch_status_t switch_opus_fmtp_parse(const char *fmtp, switch_codec_fmt
|
||||
if (!switch_opus_acceptable_rate(codec_settings->sprop_maxcapturerate)) {
|
||||
codec_settings->sprop_maxcapturerate = 0; /* value not supported */
|
||||
}
|
||||
|
||||
if (codec_settings->sprop_maxcapturerate) {
|
||||
codec_fmtp->actual_samples_per_second = codec_settings->sprop_maxcapturerate;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -471,7 +480,7 @@ static int switch_opus_get_fec_bitrate(int fs, int loss)
|
||||
return SWITCH_STATUS_FALSE ;
|
||||
}
|
||||
|
||||
static switch_status_t switch_opus_info(void * encoded_data, uint32_t len, uint32_t samples_per_second, char *print_text)
|
||||
static switch_status_t switch_opus_info(switch_core_session_t *session, void * encoded_data, uint32_t len, uint32_t samples_per_second, char *print_text)
|
||||
{
|
||||
int nb_samples, nb_opus_frames, nb_channels;
|
||||
int audiobandwidth;
|
||||
@@ -483,18 +492,18 @@ static switch_status_t switch_opus_info(void * encoded_data, uint32_t len, uint3
|
||||
|
||||
if (!encoded_data) {
|
||||
/* print stuff, even if encoded_data is NULL. eg: "PLC correction" */
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s", print_text);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s", print_text);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
audiobandwidth = opus_packet_get_bandwidth(encoded_data);
|
||||
|
||||
if (!switch_opus_show_audio_bandwidth(audiobandwidth,audiobandwidth_str)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s: OPUS_INVALID_PACKET !\n", print_text);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s: OPUS_INVALID_PACKET !\n", print_text);
|
||||
}
|
||||
|
||||
if ((nb_opus_frames = opus_packet_parse(encoded_data, len, NULL, frame_data, frame_sizes, NULL)) <= 0 ) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s: OPUS_INVALID_PACKET ! frames: %d\n", print_text, nb_opus_frames);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s: OPUS_INVALID_PACKET ! frames: %d\n", print_text, nb_opus_frames);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
@@ -504,7 +513,7 @@ static switch_status_t switch_opus_info(void * encoded_data, uint32_t len, uint3
|
||||
|
||||
nb_channels = opus_packet_get_nb_channels(payload);
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s: opus_frames [%d] samples [%d] audio bandwidth [%s] bytes [%d] FEC[%s] channels[%d]\n",
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s: opus_frames [%d] samples [%d] audio bandwidth [%s] bytes [%d] FEC[%s] channels[%d]\n",
|
||||
print_text, nb_opus_frames, nb_samples, audiobandwidth_str, len, has_fec ? "yes" : "no", nb_channels);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
@@ -518,6 +527,7 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag
|
||||
switch_codec_fmtp_t codec_fmtp, codec_fmtp_only_remote = { 0 };
|
||||
opus_codec_settings_t opus_codec_settings = { 0 };
|
||||
opus_codec_settings_t opus_codec_settings_remote = { 0 };
|
||||
switch_core_session_t *session = codec->session;
|
||||
|
||||
if (!(encoding || decoding) || (!(context = switch_core_alloc(codec->memory_pool, sizeof(*context))))) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
@@ -591,7 +601,7 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag
|
||||
if (settings && settings->maxplaybackrate < enc_samplerate && settings->maxplaybackrate) {
|
||||
enc_samplerate = settings->maxplaybackrate; /*R1*/
|
||||
context->enc_frame_size = enc_samplerate * (codec->implementation->microseconds_per_packet / 1000) / 1000;
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder will be created at sample rate %d hz\n",enc_samplerate);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Opus encoder will be created at sample rate %d hz\n",enc_samplerate);
|
||||
} else {
|
||||
enc_samplerate = codec->implementation->actual_samples_per_second;
|
||||
}
|
||||
@@ -604,19 +614,19 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag
|
||||
codec->implementation->number_of_channels == 1 ? OPUS_APPLICATION_VOIP : OPUS_APPLICATION_AUDIO, &err);
|
||||
|
||||
if (err != OPUS_OK) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot create encoder: %s\n", opus_strerror(err));
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot create encoder: %s\n", opus_strerror(err));
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
/* https://tools.ietf.org/html/rfc7587 */
|
||||
if (opus_codec_settings.maxaveragebitrate) {
|
||||
opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(opus_codec_settings.maxaveragebitrate));
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: set bitrate based on maxaveragebitrate value found in SDP or local config [%dbps]\n", opus_codec_settings.maxaveragebitrate);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Opus encoder: set bitrate based on maxaveragebitrate value found in SDP or local config [%dbps]\n", opus_codec_settings.maxaveragebitrate);
|
||||
} else {
|
||||
opus_encoder_ctl(context->encoder_object, OPUS_SET_BANDWIDTH(OPUS_AUTO));
|
||||
opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(bitrate_bps)); /* OPUS_AUTO */
|
||||
opus_encoder_ctl(context->encoder_object, OPUS_GET_BITRATE(&bitrate_bps)); /* return average bps for this audio bandwidth */
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: set bitrate to local settings [%dbps]\n", bitrate_bps);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Opus encoder: set bitrate to local settings [%dbps]\n", bitrate_bps);
|
||||
}
|
||||
/* Another fmtp setting from https://tools.ietf.org/html/rfc7587 - "RTP Payload Format for the Opus Speech and Audio Codec" */
|
||||
if (opus_codec_settings.maxplaybackrate) {
|
||||
@@ -627,14 +637,14 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag
|
||||
if (!switch_opus_show_audio_bandwidth(audiobandwidth,audiobandwidth_str)) {
|
||||
snprintf(audiobandwidth_str, sizeof(audiobandwidth_str), "%s", "OPUS_AUTO");
|
||||
}
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: set audio bandwidth to [%s] based on maxplaybackrate value found in SDP or local config [%dHz]\n",audiobandwidth_str,opus_codec_settings.maxplaybackrate);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Opus encoder: set audio bandwidth to [%s] based on maxplaybackrate value found in SDP or local config [%dHz]\n",audiobandwidth_str,opus_codec_settings.maxplaybackrate);
|
||||
}
|
||||
|
||||
if (use_vbr) {
|
||||
/* VBR is default*/
|
||||
opus_encoder_ctl(context->encoder_object, OPUS_SET_VBR(use_vbr));
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: CBR mode enabled\n");
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Opus encoder: CBR mode enabled\n");
|
||||
opus_encoder_ctl(context->encoder_object, OPUS_SET_VBR(0));
|
||||
}
|
||||
|
||||
@@ -684,7 +694,7 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag
|
||||
if (settings && dec_samplerate > settings->sprop_maxcapturerate && settings->sprop_maxcapturerate) {
|
||||
dec_samplerate = settings->sprop_maxcapturerate; /* R2 */
|
||||
context->dec_frame_size = dec_samplerate*(codec->implementation->microseconds_per_packet / 1000) / 1000;
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus decoder will be created at sample rate %d hz\n",dec_samplerate);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Opus decoder will be created at sample rate %d hz\n",dec_samplerate);
|
||||
} else {
|
||||
dec_samplerate = codec->implementation->actual_samples_per_second;
|
||||
}
|
||||
@@ -697,7 +707,7 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag
|
||||
switch_set_flag(codec, SWITCH_CODEC_FLAG_HAS_PLC);
|
||||
|
||||
if (err != OPUS_OK) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot create decoder: %s\n", opus_strerror(err));
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot create decoder: %s\n", opus_strerror(err));
|
||||
|
||||
if (context->encoder_object) {
|
||||
opus_encoder_destroy(context->encoder_object);
|
||||
@@ -774,7 +784,7 @@ static switch_status_t switch_opus_encode(switch_codec_t *codec,
|
||||
|
||||
if (globals.debug || context->debug > 1) {
|
||||
int samplerate = context->enc_frame_size * 1000 / (codec->implementation->microseconds_per_packet / 1000);
|
||||
switch_opus_info(encoded_data, bytes, samplerate, "encode");
|
||||
switch_opus_info(codec->session, encoded_data, bytes, samplerate, "encode");
|
||||
}
|
||||
|
||||
if (bytes > 0) {
|
||||
@@ -796,7 +806,7 @@ static switch_status_t switch_opus_encode(switch_codec_t *codec,
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_ERROR,
|
||||
"Encoder Error: %s Decoded Datalen %u Codec NumberChans %u Len %u DecodedDate %p EncodedData %p ContextEncoderObject %p!\n",
|
||||
opus_strerror(bytes),decoded_data_len,codec->implementation->number_of_channels,len,(void *) decoded_data,
|
||||
(void *) encoded_data,(void *) context->encoder_object);
|
||||
@@ -817,6 +827,8 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec,
|
||||
int fec = 0, plc = 0;
|
||||
int32_t frame_size = 0, last_frame_size = 0;
|
||||
uint32_t frame_samples;
|
||||
uint8_t buf[SWITCH_RTP_MAX_BUF_LEN];
|
||||
switch_core_session_t *session = codec->session;
|
||||
|
||||
if (!context) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
@@ -826,7 +838,6 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec,
|
||||
frame_size = frame_samples - (frame_samples % (codec->implementation->actual_samples_per_second / 400));
|
||||
|
||||
if (*flag & SFF_PLC) {
|
||||
switch_core_session_t *session = codec->session;
|
||||
switch_jb_t *jb = NULL;
|
||||
|
||||
plc = 1;
|
||||
@@ -842,7 +853,6 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec,
|
||||
}
|
||||
if (codec->cur_frame && (jb = switch_core_session_get_jb(session, SWITCH_MEDIA_TYPE_AUDIO))) {
|
||||
switch_frame_t frame = { 0 };
|
||||
uint8_t buf[SWITCH_RTP_MAX_BUF_LEN];
|
||||
uint32_t ts = 0;
|
||||
uint16_t seq = 0;
|
||||
|
||||
@@ -856,12 +866,12 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec,
|
||||
frame.buflen = sizeof(buf);
|
||||
|
||||
if (globals.debug || context->debug) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Missing %s %u Checking JB\n", seq ? "SEQ" : "TS", seq ? seq : ts);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Missing %s %u Checking JB\n", seq ? "SEQ" : "TS", seq ? seq : ts);
|
||||
}
|
||||
|
||||
if (switch_jb_peek_frame(jb, ts, seq, 1, &frame) == SWITCH_STATUS_SUCCESS) {
|
||||
if (globals.debug || context->debug) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Lookahead frame found: %u:%u\n",
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Lookahead frame found: %u:%u\n",
|
||||
frame.timestamp, frame.seq);
|
||||
}
|
||||
|
||||
@@ -873,10 +883,10 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec,
|
||||
|
||||
if (globals.debug || context->debug) {
|
||||
if (fec) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FEC info available in packet with SEQ: %d LEN: %d\n",
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "FEC info available in packet with SEQ: %d LEN: %d\n",
|
||||
frame.seq, frame.datalen);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "NO FEC info in this packet with SEQ: %d LEN: %d\n",
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "NO FEC info in this packet with SEQ: %d LEN: %d\n",
|
||||
frame.seq, frame.datalen);
|
||||
}
|
||||
}
|
||||
@@ -890,9 +900,9 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec,
|
||||
|
||||
if (globals.debug || context->debug) {
|
||||
if (opus_prefs.use_jb_lookahead || context->use_jb_lookahead) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "MISSING FRAME: %s\n", fec ? "Look-ahead FEC" : "PLC");
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "MISSING FRAME: %s\n", fec ? "Look-ahead FEC" : "PLC");
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "MISSING FRAME: OPUS_PLC\n");
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "MISSING FRAME: OPUS_PLC\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -901,7 +911,7 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec,
|
||||
|
||||
if (globals.debug || context->debug > 1) {
|
||||
int samplerate = context->dec_frame_size * 1000 / (codec->implementation->microseconds_per_packet / 1000);
|
||||
switch_opus_info(encoded_data, encoded_data_len,
|
||||
switch_opus_info(codec->session, encoded_data, encoded_data_len,
|
||||
samplerate ? samplerate : codec->implementation->actual_samples_per_second,
|
||||
!encoded_data ? "PLC correction" : fec ? "FEC correction" : "decode");
|
||||
}
|
||||
@@ -918,8 +928,8 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec,
|
||||
samples = opus_decode(context->decoder_object, encoded_data, encoded_data_len, decoded_data, frame_size, fec);
|
||||
|
||||
if (samples < 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Decoder Error: %s fs:%u plc:%s!\n",
|
||||
opus_strerror(samples), frame_size, plc ? "true" : "false");
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Decoder Error: %s fs:%u plc:%s!\n",
|
||||
opus_strerror(samples), frame_size, plc ? "true" : "false");
|
||||
return SWITCH_STATUS_NOOP;
|
||||
}
|
||||
|
||||
@@ -962,7 +972,7 @@ static switch_status_t switch_opus_encode_repacketize(switch_codec_t *codec,
|
||||
}
|
||||
frame_size = (decoded_data_len / 2) / nb_frames;
|
||||
if((frame_size * nb_frames) != context->enc_frame_size) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,"Encoder Error: Decoded Datalen %u Number of frames: %u Encoder frame size: %u\n",decoded_data_len,nb_frames,context->enc_frame_size);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_ERROR,"Encoder Error: Decoded Datalen %u Number of frames: %u Encoder frame size: %u\n",decoded_data_len,nb_frames,context->enc_frame_size);
|
||||
switch_goto_status(SWITCH_STATUS_GENERR, end);
|
||||
}
|
||||
opus_repacketizer_init(rp);
|
||||
@@ -982,7 +992,7 @@ static switch_status_t switch_opus_encode_repacketize(switch_codec_t *codec,
|
||||
bytes = opus_encode(context->encoder_object, (opus_int16 *) dec_ptr_buf, frame_size, enc_ptr_buf, len);
|
||||
|
||||
if (bytes < 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Encoder Error: %s Decoded Datalen %u Codec NumberChans %u" \
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_ERROR, "Encoder Error: %s Decoded Datalen %u Codec NumberChans %u" \
|
||||
"Len %u DecodedDate %p EncodedData %p ContextEncoderObject %p enc_frame_size: %d\n",
|
||||
opus_strerror(bytes), decoded_data_len, codec->implementation->number_of_channels, len,
|
||||
(void *) decoded_data, (void *) encoded_data, (void *) context->encoder_object, context->enc_frame_size);
|
||||
@@ -991,7 +1001,7 @@ static switch_status_t switch_opus_encode_repacketize(switch_codec_t *codec,
|
||||
/* enc_ptr_buf : Opus API manual: "The application must ensure this pointer remains valid until the next call to opus_repacketizer_init() or opus_repacketizer_destroy()." */
|
||||
ret = opus_repacketizer_cat(rp, enc_ptr_buf, bytes);
|
||||
if (ret != OPUS_OK) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Opus encoder: error while repacketizing (cat) : %s !\n",opus_strerror(ret));
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_ERROR, "Opus encoder: error while repacketizing (cat) : %s !\n",opus_strerror(ret));
|
||||
switch_goto_status(SWITCH_STATUS_GENERR, end);
|
||||
}
|
||||
enc_ptr_buf += bytes;
|
||||
@@ -1000,18 +1010,18 @@ static switch_status_t switch_opus_encode_repacketize(switch_codec_t *codec,
|
||||
}
|
||||
/* this will never happen, unless there is a huge and unsupported number of frames */
|
||||
if (total_len + opus_repacketizer_get_nb_frames(rp) > len / 2) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Opus encoder: error while repacketizing: not enough buffer space\n");
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_ERROR, "Opus encoder: error while repacketizing: not enough buffer space\n");
|
||||
switch_goto_status(SWITCH_STATUS_GENERR, end);
|
||||
}
|
||||
ret = opus_repacketizer_out(rp, encoded_data, total_len+opus_repacketizer_get_nb_frames(rp));
|
||||
|
||||
if (globals.debug || context->debug) {
|
||||
int samplerate = context->enc_frame_size * 1000 / (codec->implementation->microseconds_per_packet / 1000);
|
||||
switch_opus_info(encoded_data, ret, samplerate, "encode_repacketize");
|
||||
switch_opus_info(codec->session, encoded_data, ret, samplerate, "encode_repacketize");
|
||||
}
|
||||
|
||||
if (ret <= 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Opus encoder: error while repacketizing (out) : %s ! packed nb_frames: %d\n", opus_strerror(ret), opus_repacketizer_get_nb_frames(rp));
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_ERROR, "Opus encoder: error while repacketizing (out) : %s ! packed nb_frames: %d\n", opus_strerror(ret), opus_repacketizer_get_nb_frames(rp));
|
||||
switch_goto_status(SWITCH_STATUS_GENERR, end);
|
||||
}
|
||||
if (want_fec) {
|
||||
@@ -1052,25 +1062,25 @@ static switch_status_t opus_load_config(switch_bool_t reload)
|
||||
char *val = (char *) switch_xml_attr_soft(param, "value");
|
||||
|
||||
if (!strcasecmp(key, "use-vbr") && !zstr(val)) {
|
||||
opus_prefs.use_vbr = atoi(val);
|
||||
opus_prefs.use_vbr = switch_true(val);
|
||||
} else if (!strcasecmp(key, "use-dtx")) {
|
||||
opus_prefs.use_dtx = atoi(val);
|
||||
opus_prefs.use_dtx = switch_true(val);
|
||||
} else if (!strcasecmp(key, "complexity")) {
|
||||
opus_prefs.complexity = atoi(val);
|
||||
} else if (!strcasecmp(key, "packet-loss-percent")) {
|
||||
opus_prefs.plpct = atoi(val);
|
||||
} else if (!strcasecmp(key, "asymmetric-sample-rates")) {
|
||||
opus_prefs.asymmetric_samplerates = atoi(val);
|
||||
opus_prefs.asymmetric_samplerates = switch_true(val);
|
||||
} else if (!strcasecmp(key, "bitrate-negotiation")) {
|
||||
opus_prefs.bitrate_negotiation = atoi(val);
|
||||
opus_prefs.bitrate_negotiation = switch_true(val);
|
||||
} else if (!strcasecmp(key, "use-jb-lookahead")) {
|
||||
opus_prefs.use_jb_lookahead = switch_true(val);
|
||||
} else if (!strcasecmp(key, "keep-fec-enabled")) { /* encoder */
|
||||
opus_prefs.keep_fec = atoi(val);
|
||||
opus_prefs.keep_fec = switch_true(val);
|
||||
} else if (!strcasecmp(key, "advertise-useinbandfec")) { /*decoder, has meaning only for FMTP: useinbandfec=1 by default */
|
||||
opus_prefs.fec_decode = atoi(val);
|
||||
opus_prefs.fec_decode = switch_true(val);
|
||||
} else if (!strcasecmp(key, "adjust-bitrate")) { /* encoder, this setting will make the encoder adjust its bitrate based on a feedback loop (RTCP). This is not "VBR".*/
|
||||
opus_prefs.adjust_bitrate = atoi(val);
|
||||
opus_prefs.adjust_bitrate = switch_true(val);
|
||||
} else if (!strcasecmp(key, "maxaveragebitrate")) {
|
||||
opus_prefs.maxaveragebitrate = atoi(val);
|
||||
if (opus_prefs.maxaveragebitrate < SWITCH_OPUS_MIN_BITRATE || opus_prefs.maxaveragebitrate > SWITCH_OPUS_MAX_BITRATE) {
|
||||
@@ -1087,7 +1097,7 @@ static switch_status_t opus_load_config(switch_bool_t reload)
|
||||
opus_prefs.sprop_maxcapturerate = 0; /* value not supported */
|
||||
}
|
||||
} else if (!strcasecmp(key, "mono")) {
|
||||
opus_prefs.mono = atoi(val);
|
||||
opus_prefs.mono = switch_true(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1105,7 +1115,7 @@ static switch_status_t switch_opus_keep_fec_enabled(switch_codec_t *codec)
|
||||
uint32_t LBRR_threshold_bitrate,LBRR_rate_thres_bps,real_target_bitrate ;
|
||||
opus_int32 a32,b32;
|
||||
uint32_t fs = context->enc_frame_size * 1000 / (codec->implementation->microseconds_per_packet / 1000);
|
||||
float frame_rate =(float)(1000 / (codec->implementation->microseconds_per_packet / 1000));
|
||||
float frame_rate =(float)(1000 / (float)(codec->implementation->microseconds_per_packet / 1000));
|
||||
uint32_t step = (codec->implementation->microseconds_per_packet / 1000) != 60 ? 8000 / (codec->implementation->microseconds_per_packet / 1000 ) : 134 ;
|
||||
|
||||
opus_encoder_ctl(context->encoder_object, OPUS_GET_BITRATE(¤t_bitrate));
|
||||
@@ -1132,7 +1142,7 @@ static switch_status_t switch_opus_keep_fec_enabled(switch_codec_t *codec)
|
||||
LBRR_threshold_bitrate = (a32 >> 16) * (opus_int32)((opus_int16)b32) + (((a32 & 0x0000FFFF) * (opus_int32)((opus_int16)b32)) >> 16);
|
||||
|
||||
if (!real_target_bitrate || !LBRR_threshold_bitrate) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Opus encoder: error while controlling FEC params\n");
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_ERROR, "Opus encoder: error while controlling FEC params\n");
|
||||
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
@@ -1141,7 +1151,7 @@ static switch_status_t switch_opus_keep_fec_enabled(switch_codec_t *codec)
|
||||
if (real_target_bitrate > LBRR_threshold_bitrate) {
|
||||
/*FEC is already enabled, do nothing*/
|
||||
if (globals.debug || context->debug) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: FEC is enabled\n");
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "Opus encoder: FEC is enabled\n");
|
||||
}
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
} else {
|
||||
@@ -1153,13 +1163,40 @@ static switch_status_t switch_opus_keep_fec_enabled(switch_codec_t *codec)
|
||||
opus_encoder_ctl(context->encoder_object,OPUS_SET_BITRATE(current_bitrate));
|
||||
|
||||
if (globals.debug || context->debug) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: increased bitrate to [%d] to keep FEC enabled\n", current_bitrate);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "Opus encoder: increased bitrate to [%d] to keep FEC enabled\n", current_bitrate);
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
static switch_bool_t switch_opus_vad(struct opus_context *context, void *encoded_data, uint32_t encoded_data_len)
|
||||
{
|
||||
const uint8_t *payload = (const uint8_t *)encoded_data;
|
||||
opus_packet_info_t opus_packet_info;
|
||||
switch_bool_t debug = (globals.debug || context->debug > 1);
|
||||
|
||||
if (!switch_opus_packet_parse(payload, encoded_data_len, &opus_packet_info, debug)) {
|
||||
if (debug) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "OPUS PACKET PARSING ERROR len:%d bytes:%02x %02x\n",
|
||||
(int)encoded_data_len, payload[0], payload[1]);
|
||||
}
|
||||
|
||||
return SWITCH_TRUE;
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "OPUS EXTRACT PAYLOAD VAD len:%d vad_ms:%d bytes:%02x %02x\n",
|
||||
(int)encoded_data_len, opus_packet_info.vad_ms, payload[0], payload[1]);
|
||||
}
|
||||
|
||||
if (opus_packet_info.vad_ms == 0) {
|
||||
return SWITCH_FALSE;
|
||||
}
|
||||
|
||||
return SWITCH_TRUE;
|
||||
}
|
||||
|
||||
static switch_status_t switch_opus_control(switch_codec_t *codec,
|
||||
switch_codec_control_command_t cmd,
|
||||
switch_codec_control_type_t ctype,
|
||||
@@ -1229,7 +1266,7 @@ static switch_status_t switch_opus_control(switch_codec_t *codec,
|
||||
}
|
||||
|
||||
if (globals.debug || context->debug) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: Adjusting packet loss percent from %d%% to %d%%!\n",
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "Opus encoder: Adjusting packet loss percent from %d%% to %d%%!\n",
|
||||
context->old_plpct, plpct);
|
||||
}
|
||||
}
|
||||
@@ -1243,7 +1280,7 @@ static switch_status_t switch_opus_control(switch_codec_t *codec,
|
||||
float steps = (float)((float)(range / 100) / base_step);
|
||||
int br_step = (int)(round(steps) * base_step) * plpct;
|
||||
if (globals.debug || context->debug) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG,
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session),
|
||||
SWITCH_LOG_DEBUG, "Opus encoder: bitrate increase/decrease step now is: %d bps, range:%d\n", br_step, range);
|
||||
}
|
||||
context->control_state.increase_step = context->control_state.decrease_step = br_step;
|
||||
@@ -1251,6 +1288,15 @@ static switch_status_t switch_opus_control(switch_codec_t *codec,
|
||||
context->old_plpct = plpct;
|
||||
}
|
||||
break;
|
||||
case SCC_AUDIO_VAD:
|
||||
{
|
||||
void *encoded_data = (void *)cmd_data;
|
||||
uint16_t *encoded_data_len = (uint16_t *)cmd_arg;
|
||||
switch_bool_t *ret = (switch_bool_t *)*ret_data;
|
||||
|
||||
*ret = switch_opus_vad(context, encoded_data, *encoded_data_len);
|
||||
}
|
||||
break;
|
||||
case SCC_AUDIO_ADJUST_BITRATE:
|
||||
{
|
||||
const char *cmd = (const char *)cmd_data;
|
||||
@@ -1269,7 +1315,7 @@ static switch_status_t switch_opus_control(switch_codec_t *codec,
|
||||
opus_prefs.keep_fec = 1; /* enable back FEC if it was disabled by SCC_AUDIO_ADJUST_BITRATE, we have enough network bandwidth now */
|
||||
}
|
||||
if (globals.debug || context->debug) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (increase)\n", current_bitrate+br_step);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (increase)\n", current_bitrate+br_step);
|
||||
}
|
||||
}
|
||||
} else if (!strcasecmp(cmd, "decrease")) {
|
||||
@@ -1283,7 +1329,7 @@ static switch_status_t switch_opus_control(switch_codec_t *codec,
|
||||
}
|
||||
opus_encoder_ctl(context->encoder_object, OPUS_SET_BITRATE(current_bitrate-br_step));
|
||||
if (globals.debug || context->debug) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (decrease)\n", current_bitrate-br_step);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (decrease)\n", current_bitrate-br_step);
|
||||
}
|
||||
}
|
||||
} else if (!strcasecmp(cmd, "default")) {
|
||||
@@ -1293,7 +1339,7 @@ static switch_status_t switch_opus_control(switch_codec_t *codec,
|
||||
opus_prefs.keep_fec = 1; /* enable back FEC, we have enough network bandwidth now */
|
||||
}
|
||||
if (globals.debug || context->debug) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (configured maxaveragebitrate)\n", opus_prefs.maxaveragebitrate);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (configured maxaveragebitrate)\n", opus_prefs.maxaveragebitrate);
|
||||
}
|
||||
} else {
|
||||
/* set Opus minimum bitrate */
|
||||
@@ -1302,7 +1348,7 @@ static switch_status_t switch_opus_control(switch_codec_t *codec,
|
||||
opus_prefs.keep_fec = 0; /* do not enforce FEC anymore, we're low on network bandwidth */
|
||||
}
|
||||
if (globals.debug || context->debug) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (minimum)\n", SWITCH_OPUS_MIN_BITRATE);
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_DEBUG, "Opus encoder: Adjusting bitrate to %d (minimum)\n", SWITCH_OPUS_MIN_BITRATE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1340,7 +1386,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load)
|
||||
{
|
||||
switch_codec_interface_t *codec_interface;
|
||||
switch_api_interface_t *commands_api_interface;
|
||||
int samples = 480;
|
||||
int samples = 480; /* start with 10 ms ptime */
|
||||
int bytes = 960;
|
||||
int mss = 10000;
|
||||
int x = 0;
|
||||
@@ -1441,7 +1487,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load)
|
||||
}
|
||||
|
||||
/* 16 khz */
|
||||
samples = 480;
|
||||
samples = 160;
|
||||
bytes = 320;
|
||||
mss = 10000;
|
||||
rate = 16000;
|
||||
@@ -1538,7 +1584,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_opus_load)
|
||||
}
|
||||
|
||||
/* 8 khz */
|
||||
samples = 480;
|
||||
samples = 80;
|
||||
bytes = 160;
|
||||
mss = 10000;
|
||||
rate = 8000;
|
||||
|
||||
@@ -0,0 +1,401 @@
|
||||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2005-2023, 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):
|
||||
*
|
||||
* Claude Lamblin
|
||||
* Julien Chavanton <jchavanton@gmail.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "switch.h"
|
||||
#include "opus.h"
|
||||
#include "opus_parse.h"
|
||||
/* Tables for LBRR_sympbol decoding */
|
||||
|
||||
static const opus_int16 silk_LBRR_flags_2_PDFCum[3] = { 53, 106, 256 }; /* 256 - silk_LBRR_flags_2_iCDF[i] ; silk_LBRR_flags_2_iCDF[ 3 ] = { 203, 150, 0 }; */
|
||||
static const opus_int16 silk_LBRR_flags_3_PDFCum[7] = { 41, 61, 90, 131, 146, 174, 256 }; /* 256 - silk_LBRR_flags_3_iCDF[i] ; silk_LBRR_flags_3_iCDF[ 7 ] = { 215, 195, 166, 125, 110, 82, 0 }; */
|
||||
|
||||
/* Get the number of VAD flags - i.e. number of 20 ms frame - from the config
|
||||
* in a silk-only or hybrid opus frame mono or stereo
|
||||
* 5 MSB TOC byte (see table 2 of IETF RFC6716 clause 3.1)
|
||||
* if 10 ms frame (config=0, 4, 8, 12, 14) : return 1
|
||||
* if CELT_only frame no VAD flag =>return 0 */
|
||||
static opus_int16 switch_opus_get_nb_flags_in_silk_frame(int16_t config)
|
||||
{
|
||||
opus_int16 silk_frame_nb_flags;
|
||||
|
||||
if (config > 15) {
|
||||
/* CELT_only frame no VAD flag nor LBRR flag */
|
||||
silk_frame_nb_flags = 0;
|
||||
} else {
|
||||
silk_frame_nb_flags = 1; /* default */
|
||||
|
||||
if (config < 12) {
|
||||
/* silk-only NB, MB or WB
|
||||
* The least two significant bits give the number of VAD flags inside the silk frame 1, 2 or 3 */
|
||||
silk_frame_nb_flags = config & 0x3;
|
||||
|
||||
if (silk_frame_nb_flags == 0) { /* 0 => 10ms frame : one VAD flag */
|
||||
silk_frame_nb_flags++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return silk_frame_nb_flags;
|
||||
}
|
||||
|
||||
/* Get the time in ms corresponding to one VAD flag from the config
|
||||
* in a silk-only or hybrid opus frame mono or stereo
|
||||
* 5 MSB TOC byte (see table 2 of IETF RFC6716 clause 3.1)
|
||||
* if CELT_only frame (config >15) no VAD flag =>return FALSE
|
||||
* if 10 ms frame (config=0, 4, 8, 12, 14) : return 10
|
||||
* otherwise return 20 */
|
||||
static opus_int16 switch_opus_get_silk_frame_ms_per_flag(int16_t config, opus_int16 silk_frame_nb_flags)
|
||||
{
|
||||
opus_int16 silk_size_frame_ms_per_flag;
|
||||
|
||||
if (config > 15) {
|
||||
/* CELT_only frame no VAD flag nor LBRR flag */
|
||||
/* switch_opus_get_silk_frame_ms_per_flag: code not written for CELT-only mode */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
silk_size_frame_ms_per_flag = 20; /* default*/
|
||||
if (silk_frame_nb_flags == 1) { /* could be 10 or 20 ms */
|
||||
if ((config & 0x01) == 0) {
|
||||
silk_size_frame_ms_per_flag = 10;
|
||||
}
|
||||
}
|
||||
|
||||
return silk_size_frame_ms_per_flag;
|
||||
}
|
||||
|
||||
/* Code written only for mono, silk-only or hybrid mode
|
||||
* for CELT-only frame no vad flags for LBRR flag the routine must not be called
|
||||
* for stereo : the mid frame VAD_flags and the LBRR_flag could be obtained
|
||||
* yet, to get the LBRR_flags of the mid frame the routine should be modified
|
||||
* to skip the side VAD flags and the side LBRR flag and to get the mid LBRR_symbol */
|
||||
static void switch_opus_get_VAD_LBRR_flags(const uint8_t *buf, opus_int16 silk_frame_nb_flags,
|
||||
opus_int16 *VAD_flags, opus_int16 *LBRR_flags, opus_int16 *nb_VAD1, opus_int16 *nb_FEC)
|
||||
{
|
||||
const opus_int16 *ptr_pdf_cum;
|
||||
opus_int nb_pdf_symbol;
|
||||
opus_uint16 LBRR_symbol;
|
||||
opus_int16 val, nb_bit, compl_nb_bit, mask, mask2;
|
||||
opus_int16 *ptr_flags;
|
||||
opus_int16 LBRR_flag;
|
||||
opus_int16 nb_vad, nb_fec;
|
||||
int i;
|
||||
|
||||
nb_vad = 0;
|
||||
nb_fec = 0;
|
||||
|
||||
/* Get VAD_FLAGS & LBRR_FLAG
|
||||
* silk_frame_nb_flags = 1 (10 or 20 ms), the two MSB of the first byte are the VAD flag and the LBRR flag
|
||||
* silk_frame_nb_flags = 2 (40 ms), the three MSB of the first byte are the two VAD flags and the LBRR flag
|
||||
* silk_frame_nb_flags = 3 (60 ms), the four MSB of the first byte are the three VAD flags and the LBRR flag
|
||||
* compute the number of MSB to analyze */
|
||||
nb_bit = silk_frame_nb_flags + 1;
|
||||
|
||||
/* number of right shifts to apply to the first byte to only have the bits of LBRR flag and of the VAD flags */
|
||||
compl_nb_bit = 8 - nb_bit;
|
||||
mask = (1 << nb_bit) - 1;
|
||||
|
||||
/* The bits of the silk_frame_nb_flags VAD flags and the LBRR flag are the MSB of the first byte
|
||||
* silk_frame_nb_flags = 1 (10 or 20 ms), VAD_flags(0) | LBRR_flag
|
||||
* silk_frame_nb_flags = 2 (40 ms), VAD_flags(0) | VAD_flags(1) | LBRR_flag
|
||||
* silk_frame_nb_flags = 3 (60 ms), VAD_flags(0) | VAD_flags(1) | VAD_flags(2) |LBRR_flag */
|
||||
val = (buf[0] >> compl_nb_bit) & mask;
|
||||
|
||||
LBRR_flag = val & 0x1; /* LBRR_FLAG LSB */
|
||||
|
||||
/* get VAD_flags */
|
||||
ptr_flags = VAD_flags + silk_frame_nb_flags;
|
||||
for (i = 0; i < silk_frame_nb_flags; i++) {
|
||||
LBRR_flags[i] = 0; /* init */
|
||||
val >>= 1;
|
||||
*(--ptr_flags) = val & 0x1;
|
||||
}
|
||||
|
||||
if (LBRR_flag != 0) { /* there is at least one LBRR frame */
|
||||
if (silk_frame_nb_flags == 1) {
|
||||
LBRR_flags[0] = 1;
|
||||
nb_fec = 1;
|
||||
} else { /* get LBRR_symbol then LBRR_flags */
|
||||
/* LBRR symbol is encoded with range encoder : range on 8 bits
|
||||
* silk_frame_nb_flags = 2 ; 3 possible values for LBRR_flags(1) | LBRR_flags(0))= 01, 10, 11
|
||||
* silk_frame_nb_flags = 3 ; 7 possible values for LBRR_flags(2) | LBRR_flags(1) | LBRR_flags(0))= 001, 010, 011, 100, 101, 110, 111 */
|
||||
mask2 = (1 << compl_nb_bit) - 1;
|
||||
/* get next 8 bits: (8-nb_bit) LSB of the first byte and nb_bit MSB of the second byte */
|
||||
val = (((buf[0]) & mask2) << nb_bit) | ((buf[1] >> compl_nb_bit) & mask);
|
||||
|
||||
if (silk_frame_nb_flags == 2) {
|
||||
nb_pdf_symbol = 3;
|
||||
ptr_pdf_cum = silk_LBRR_flags_2_PDFCum;
|
||||
} else {
|
||||
nb_pdf_symbol = 7;
|
||||
ptr_pdf_cum = silk_LBRR_flags_3_PDFCum;
|
||||
}
|
||||
|
||||
LBRR_symbol = 0;
|
||||
for (i = 1; i <= nb_pdf_symbol; i++) {
|
||||
if (val < *ptr_pdf_cum++) {
|
||||
LBRR_symbol = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < silk_frame_nb_flags; i++) {
|
||||
LBRR_flags[i] = LBRR_symbol & 0x01;
|
||||
LBRR_symbol >>= 1;
|
||||
nb_fec += LBRR_flags[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < silk_frame_nb_flags; i++) {
|
||||
nb_vad += VAD_flags[i];
|
||||
}
|
||||
|
||||
*nb_VAD1 = nb_vad;
|
||||
*nb_FEC = nb_fec;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Parse the packet to retrieve informations about its content
|
||||
* RFC6716: Definition of the Opus Audio Codec
|
||||
* return: SWITCH_FALSE if there was a problem found parsing the packet, the info returned should be ignored.
|
||||
* */
|
||||
switch_bool_t switch_opus_packet_parse(const uint8_t *payload, int payload_length_bytes, opus_packet_info_t *packet_info, switch_bool_t debug)
|
||||
{
|
||||
int f;
|
||||
int32_t samplerate;
|
||||
int i, shift_silk, silk_frame_packet;
|
||||
int16_t vad_flags_per_silk_frame, fec_flags_per_silk_frame;
|
||||
opus_int16 frame_sizes[48];
|
||||
const unsigned char *frame_data[48];
|
||||
opus_int16 packet_LBBR_FLAGS[3 * 48], packet_VAD_FLAGS[3 * 48];
|
||||
opus_int16 *ptr_LBBR_FLAGS, *ptr_VAD_FLAGS;
|
||||
opus_int16 silk_frame_nb_flags, silk_size_frame_ms_per_flag;
|
||||
opus_int16 silk_frame_nb_fec, silk_frame_nb_vad1;
|
||||
opus_int sample_per_frame;
|
||||
|
||||
packet_info->config = 0;
|
||||
packet_info->fec = 0;
|
||||
packet_info->fec_ms = 0;
|
||||
packet_info->vad = 0;
|
||||
packet_info->vad_ms = 0;
|
||||
packet_info->stereo = FALSE;
|
||||
packet_info->frames = 0;
|
||||
packet_info->channels = 1; /* as stereo is set to FALSE */
|
||||
packet_info->ms_per_frame = 0;
|
||||
packet_info->ptime_ts = 0;
|
||||
|
||||
if (payload == NULL || payload_length_bytes <= 0) {
|
||||
if (debug) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: payload null.");
|
||||
}
|
||||
|
||||
return SWITCH_FALSE;
|
||||
}
|
||||
|
||||
/* In CELT_ONLY mode, packets should not have FEC. */
|
||||
if (payload[0] & 0x80) {
|
||||
/* opus_packet_parse: CELT_ONLY mode, we do not support this mode. */
|
||||
return SWITCH_FALSE;
|
||||
} else {
|
||||
int mode = (payload[0] >> 3);
|
||||
|
||||
if (mode <= 3) {
|
||||
samplerate = 8000;
|
||||
} else if (mode <= 7) {
|
||||
samplerate = 12000;
|
||||
} else if (mode <= 11) {
|
||||
samplerate = 16000;
|
||||
} else if (mode <= 13) {
|
||||
samplerate = 24000;
|
||||
} else if (mode <= 15) {
|
||||
samplerate = 48000;
|
||||
} else {
|
||||
/* opus_packet_parse: CELT_ONLY mode, we do not support this mode. */
|
||||
return SWITCH_FALSE;
|
||||
}
|
||||
if (debug) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: mode[%d]s[%d]c[%d] [%d]Hz\n", mode, (payload[0] >> 2) & 0x1, (payload[0]) & 0x3, samplerate);
|
||||
}
|
||||
}
|
||||
|
||||
if (payload[0] & 0x04) {
|
||||
packet_info->stereo = TRUE;
|
||||
packet_info->channels = 2;
|
||||
}
|
||||
|
||||
packet_info->config = payload[0] >> 3;
|
||||
sample_per_frame = opus_packet_get_samples_per_frame(payload, samplerate);
|
||||
packet_info->ms_per_frame = sample_per_frame * 1000 / samplerate;
|
||||
if (packet_info->ms_per_frame < 10 || packet_info->ms_per_frame > 120) {
|
||||
if (debug) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: invalid packet.");
|
||||
}
|
||||
|
||||
return SWITCH_FALSE;
|
||||
}
|
||||
|
||||
packet_info->frames = opus_packet_parse(payload, payload_length_bytes, NULL, frame_data, frame_sizes, NULL);
|
||||
if (packet_info->frames < 0) {
|
||||
packet_info->frames = 0;
|
||||
if (debug) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: opus_packet_parse found no frame.\n");
|
||||
}
|
||||
|
||||
return SWITCH_FALSE;
|
||||
}
|
||||
|
||||
packet_info->ptime_ts = packet_info->frames * sample_per_frame;
|
||||
|
||||
if (frame_sizes[0] <= 1) {
|
||||
if (debug) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: opus_packet_parse frame size too small.\n");
|
||||
}
|
||||
|
||||
return SWITCH_FALSE;
|
||||
}
|
||||
|
||||
/* +---------------+-----------+-----------+-------------------+
|
||||
| Configuration | Mode | Bandwidth | Frame Sizes |
|
||||
| Number(s) | | | |
|
||||
+---------------+-----------+-----------+-------------------+
|
||||
| 0...3 | SILK-only | NB | 10, 20, 40, 60 ms |
|
||||
| 4...7 | SILK-only | MB | 10, 20, 40, 60 ms |
|
||||
| 8...11 | SILK-only | WB | 10, 20, 40, 60 ms |
|
||||
| 12...13 | Hybrid | SWB | 10, 20 ms |
|
||||
| 14...15 | Hybrid | FB | 10, 20 ms |
|
||||
| 16...19 | CELT-only | NB | 2.5, 5, 10, 20 ms |
|
||||
| 20...23 | CELT-only | WB | 2.5, 5, 10, 20 ms |
|
||||
| 24...27 | CELT-only | SWB | 2.5, 5, 10, 20 ms |
|
||||
| 28...31 | CELT-only | FB | 2.5, 5, 10, 20 ms |
|
||||
+---------------+-----------+-----------+-------------------+ */
|
||||
|
||||
if (!packet_info->stereo) {
|
||||
/* The routines opus_get_nb_flags_in_silk_frame and opus_get_silk_frame_ms_per_flag are also valid for stereo frames
|
||||
* yet the routine opus_get_VAD_LBRR_flags is currently only for mono frame */
|
||||
silk_frame_nb_flags = switch_opus_get_nb_flags_in_silk_frame(packet_info->config); /* =1 for 10 or 20 ms frame; = 2 for 40 ms; = 3 for 60 ms */
|
||||
if (!silk_frame_nb_flags) {
|
||||
/* We should not go there as CELT_ONLY is already tested above */
|
||||
return SWITCH_FALSE;
|
||||
}
|
||||
|
||||
packet_info->frames_silk = silk_frame_nb_flags;
|
||||
silk_size_frame_ms_per_flag = switch_opus_get_silk_frame_ms_per_flag(packet_info->config, silk_frame_nb_flags); /* 10 or 20 ms frame*/
|
||||
if (!silk_size_frame_ms_per_flag) {
|
||||
/* we should not go there as CELT_ONLY is already tested above */
|
||||
return SWITCH_FALSE;
|
||||
}
|
||||
|
||||
ptr_LBBR_FLAGS = packet_LBBR_FLAGS;
|
||||
ptr_VAD_FLAGS = packet_VAD_FLAGS;
|
||||
|
||||
for (f = 0; f < packet_info->frames; f++) {
|
||||
switch_opus_get_VAD_LBRR_flags(frame_data[f], silk_frame_nb_flags, ptr_VAD_FLAGS, ptr_LBBR_FLAGS,
|
||||
&silk_frame_nb_vad1, &silk_frame_nb_fec);
|
||||
packet_info->vad += silk_frame_nb_vad1;
|
||||
packet_info->fec += silk_frame_nb_fec;
|
||||
packet_info->vad_ms += silk_frame_nb_vad1 * silk_size_frame_ms_per_flag;
|
||||
packet_info->fec_ms += silk_frame_nb_fec * silk_size_frame_ms_per_flag;
|
||||
|
||||
ptr_VAD_FLAGS += silk_frame_nb_flags;
|
||||
ptr_LBBR_FLAGS += silk_frame_nb_flags;
|
||||
}
|
||||
|
||||
/* store the VAD & LBRR flags of all 20 ms silk-frames of the packet; LSB the first frame, MSB: the last */
|
||||
vad_flags_per_silk_frame = 0;
|
||||
fec_flags_per_silk_frame = 0;
|
||||
silk_frame_packet = packet_info->frames * packet_info->frames_silk;
|
||||
if (silk_frame_packet > 15) {
|
||||
if (debug) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: more than %d 20-ms frames in the packet ; only first 15 silk-frames data will be stored (pb silkFastAccelerate)\n", silk_frame_packet);
|
||||
}
|
||||
|
||||
silk_frame_packet = 15;
|
||||
}
|
||||
|
||||
ptr_LBBR_FLAGS = packet_LBBR_FLAGS;
|
||||
ptr_VAD_FLAGS = packet_VAD_FLAGS;
|
||||
shift_silk = 0;
|
||||
for (i = 0; i < silk_frame_packet; i++) {
|
||||
vad_flags_per_silk_frame += (*ptr_VAD_FLAGS) << shift_silk;
|
||||
fec_flags_per_silk_frame += (*ptr_LBBR_FLAGS) << shift_silk;
|
||||
shift_silk++;
|
||||
ptr_LBBR_FLAGS++; ptr_VAD_FLAGS++;
|
||||
}
|
||||
|
||||
packet_info->vad_flags_per_silk_frame = vad_flags_per_silk_frame;
|
||||
packet_info->fec_flags_per_silk_frame = fec_flags_per_silk_frame;
|
||||
|
||||
return SWITCH_TRUE;
|
||||
}
|
||||
|
||||
if (packet_info->config != 1 && packet_info->config != 5 && packet_info->config != 9) {
|
||||
if (debug) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: the current parser implementation does not support muliple SILK frames for VAD or FEC detection.\n");
|
||||
}
|
||||
|
||||
return SWITCH_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the VAD and LBRR flags in each Opus frame
|
||||
* */
|
||||
for (f = 0; f < packet_info->frames; f++) {
|
||||
if (frame_data[f][0] & 0x80) {
|
||||
packet_info->vad++;
|
||||
}
|
||||
|
||||
if (frame_data[f][0] & 0x40) {
|
||||
packet_info->fec++;
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: LP layer opus_frame[%d] VAD[%d] FEC[%d]\n", f + 1, (frame_data[f][0] & 0x80) >> 7, (frame_data[f][0] & 0x40) >> 6);
|
||||
}
|
||||
}
|
||||
|
||||
packet_info->vad_ms = packet_info->vad * packet_info->ms_per_frame;
|
||||
packet_info->fec_ms = packet_info->fec * packet_info->ms_per_frame;
|
||||
|
||||
return SWITCH_TRUE;
|
||||
}
|
||||
|
||||
/* 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,69 @@
|
||||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2005-2023, 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):
|
||||
*
|
||||
* Julien Chavanton <jchavanton@gmail.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SWITCH_OPUS_PARSE_H
|
||||
#define SWITCH_OPUS_PARSE_H
|
||||
|
||||
typedef enum { false, true } bool_t;
|
||||
|
||||
typedef struct opus_packet_info {
|
||||
int16_t vad;
|
||||
int16_t vad_ms;
|
||||
int16_t fec;
|
||||
int16_t fec_ms;
|
||||
bool_t stereo;
|
||||
/* number of opus frames in the packet */
|
||||
int16_t frames;
|
||||
int16_t config;
|
||||
int16_t channels;
|
||||
int16_t ms_per_frame;
|
||||
int32_t ptime_ts;
|
||||
bool_t valid;
|
||||
/* number of silk_frames in an opus frame */
|
||||
int16_t frames_silk;
|
||||
/* VAD flag of all 20 ms silk-frames of the packet; LSB the first frame, MSB: the last */
|
||||
int16_t vad_flags_per_silk_frame;
|
||||
/* LBRR (FEC) flag of all 20 ms silk-frames of the packet; LSB the first frame, MSB: the last */
|
||||
int16_t fec_flags_per_silk_frame;
|
||||
} opus_packet_info_t;
|
||||
|
||||
switch_bool_t switch_opus_packet_parse(const uint8_t *payload, int payload_length_bytes, opus_packet_info_t *packet_info, switch_bool_t debug);
|
||||
|
||||
#endif /* SWITCH_OPUS_PARSE_H */
|
||||
|
||||
/* 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:
|
||||
*/
|
||||
@@ -411,7 +411,7 @@ switch_status_t mariadb_finish_results_real(const char* file, const char* func,
|
||||
if ((status = mysql_next_result(&handle->con))) {
|
||||
if (status > 0) {
|
||||
err_str = mariadb_handle_get_error(handle);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "An error occurred trying to get next for query (%s): %s\n", handle->sql, err_str);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "An error occurred trying to get next for query (%s): %s\n", handle->sql, switch_str_nil(err_str));
|
||||
switch_safe_free(err_str);
|
||||
|
||||
break;
|
||||
@@ -627,13 +627,27 @@ switch_status_t mariadb_send_query(mariadb_handle_t *handle, const char* sql)
|
||||
{
|
||||
char *err_str;
|
||||
int ret;
|
||||
unsigned retries = 60; /* 60 tries, will take 30 to 60 seconds at worst */
|
||||
|
||||
switch_safe_free(handle->sql);
|
||||
handle->sql = strdup(sql);
|
||||
again:
|
||||
handle->stored_results = 0;
|
||||
ret = mysql_real_query(&handle->con, sql, (unsigned long)strlen(sql));
|
||||
if (ret) {
|
||||
err_str = mariadb_handle_get_error(handle);
|
||||
if (strstr(err_str, "Deadlock found when trying to get lock; try restarting transaction")) {
|
||||
if (--retries > 0) {
|
||||
switch_safe_free(err_str);
|
||||
/* We are waiting for 500 ms and random time is not more than 500 ms.
|
||||
This is necessary so that the delay on the primary and secondary servers does not coincide and deadlock does not occur again. */
|
||||
switch_yield(500 + (rand() & 511));
|
||||
goto again;
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "DeadLock. The retries are over.\n");
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to send query (%s) to database: %s\n", sql, err_str);
|
||||
switch_safe_free(err_str);
|
||||
mariadb_finish_results(handle);
|
||||
|
||||
@@ -629,6 +629,8 @@ done:
|
||||
|
||||
error:
|
||||
|
||||
pgsql_free_result(&result);
|
||||
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -142,6 +142,7 @@ SWITCH_STANDARD_DIALPLAN(asterisk_dialplan_hunt)
|
||||
|
||||
if (!caller_profile || zstr(caller_profile->destination_number)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Obtaining Profile!\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -150,6 +151,7 @@ SWITCH_STANDARD_DIALPLAN(asterisk_dialplan_hunt)
|
||||
if (!switch_config_open_file(&cfg, cf)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf);
|
||||
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -226,12 +228,14 @@ SWITCH_STANDARD_DIALPLAN(asterisk_dialplan_hunt)
|
||||
}
|
||||
} else {
|
||||
if (pattern && strcasecmp(pattern, field_data)) {
|
||||
switch_safe_free(field_expanded);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (cid) {
|
||||
if (strcasecmp(cid, caller_profile->caller_id_number)) {
|
||||
switch_safe_free(field_expanded);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -266,15 +270,19 @@ SWITCH_STANDARD_DIALPLAN(asterisk_dialplan_hunt)
|
||||
switch_perform_substitution(re, proceed, argument, field_data, substituted, sizeof(substituted), ovector);
|
||||
argument = substituted;
|
||||
}
|
||||
|
||||
switch_regex_safe_free(re);
|
||||
|
||||
if (!extension) {
|
||||
if (zstr(field_data)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No extension!\n");
|
||||
switch_safe_free(field_expanded);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((extension = switch_caller_extension_new(session, field_data, field_data)) == 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
|
||||
switch_safe_free(field_expanded);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1296,9 +1296,9 @@ error:
|
||||
}
|
||||
switch_mutex_unlock(endpoint->mutex);
|
||||
}
|
||||
if (new_session && *new_session) {
|
||||
switch_core_session_destroy(new_session);
|
||||
}
|
||||
|
||||
switch_core_session_destroy(new_session);
|
||||
|
||||
return retcause;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#if OPENSSL_VERSION_NUMBER < 0x0090800 || !defined(SHA256_DIGEST_LENGTH)
|
||||
#error Your OpenSSL is too old, need 0.9.8 or newer with SHA256
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#define HMAC_setup(ctx, key, len) HMAC_CTX_init(&ctx); HMAC_Init_ex(&ctx, key, len, EVP_sha256(), 0)
|
||||
#define HMAC_crunch(ctx, buf, len) HMAC_Update(&ctx, buf, len)
|
||||
@@ -51,6 +52,7 @@
|
||||
#define HMAC_crunch(ctx, buf, len)HMAC_Update(ctx, buf, len)
|
||||
#define HMAC_finish(ctx, dig, dlen) HMAC_Final(ctx, dig, &dlen); HMAC_CTX_free(ctx)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define FP10
|
||||
#define RTMP_SIG_SIZE 1536
|
||||
@@ -155,9 +157,13 @@ static unsigned int GetDigestOffset1(uint8_t *handshake, unsigned int len)
|
||||
static getoff *digoff[] = {GetDigestOffset1, GetDigestOffset2};
|
||||
// static getoff *dhoff[] = {GetDHOffset1, GetDHOffset2};
|
||||
|
||||
static void HMACsha256(const uint8_t *message, size_t messageLen, const uint8_t *key, size_t keylen, uint8_t *digest)
|
||||
static void HMACsha256(const uint8_t *message, size_t messageLen, const uint8_t *key, int keylen, uint8_t *digest)
|
||||
{
|
||||
unsigned int digestLen;
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
HMAC(EVP_sha256(), key, keylen, (uint8_t *)message, messageLen, digest, &digestLen);
|
||||
#else
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
HMAC_CTX ctx;
|
||||
#else
|
||||
@@ -167,11 +173,12 @@ static void HMACsha256(const uint8_t *message, size_t messageLen, const uint8_t
|
||||
HMAC_setup(ctx, key, (int)keylen);
|
||||
HMAC_crunch(ctx, message, messageLen);
|
||||
HMAC_finish(ctx, digest, digestLen);
|
||||
#endif
|
||||
|
||||
assert(digestLen == 32);
|
||||
}
|
||||
|
||||
static void CalculateDigest(unsigned int digestPos, uint8_t *handshakeMessage, const uint8_t *key, size_t keyLen, uint8_t *digest)
|
||||
static void CalculateDigest(unsigned int digestPos, uint8_t *handshakeMessage, const uint8_t *key, int keyLen, uint8_t *digest)
|
||||
{
|
||||
const int messageLen = RTMP_SIG_SIZE - SHA256_DIGEST_LENGTH;
|
||||
uint8_t message[RTMP_SIG_SIZE - SHA256_DIGEST_LENGTH];
|
||||
@@ -184,7 +191,7 @@ static void CalculateDigest(unsigned int digestPos, uint8_t *handshakeMessage, c
|
||||
HMACsha256(message, messageLen, key, keyLen, digest);
|
||||
}
|
||||
|
||||
static int VerifyDigest(unsigned int digestPos, uint8_t *handshakeMessage, const uint8_t *key, size_t keyLen)
|
||||
static int VerifyDigest(unsigned int digestPos, uint8_t *handshakeMessage, const uint8_t *key, int keyLen)
|
||||
{
|
||||
uint8_t calcDigest[SHA256_DIGEST_LENGTH];
|
||||
|
||||
|
||||
@@ -2136,7 +2136,7 @@ void launch_skinny_profile_thread(skinny_profile_t *profile) {
|
||||
/*****************************************************************************/
|
||||
/* MODULE FUNCTIONS */
|
||||
/*****************************************************************************/
|
||||
switch_endpoint_interface_t *skinny_get_endpoint_interface()
|
||||
switch_endpoint_interface_t *skinny_get_endpoint_interface(void)
|
||||
{
|
||||
return skinny_endpoint_interface;
|
||||
}
|
||||
|
||||
@@ -355,7 +355,7 @@ switch_status_t channel_kill_channel(switch_core_session_t *session, int sig);
|
||||
/*****************************************************************************/
|
||||
/* MODULE FUNCTIONS */
|
||||
/*****************************************************************************/
|
||||
switch_endpoint_interface_t *skinny_get_endpoint_interface();
|
||||
switch_endpoint_interface_t *skinny_get_endpoint_interface(void);
|
||||
|
||||
/*****************************************************************************/
|
||||
/* TEXT FUNCTIONS */
|
||||
|
||||
@@ -697,7 +697,7 @@ switch_status_t skinny_api_register(switch_loadable_module_interface_t **module_
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
switch_status_t skinny_api_unregister()
|
||||
switch_status_t skinny_api_unregister(void)
|
||||
{
|
||||
switch_console_set_complete("del skinny");
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#define _SKINNY_API_H
|
||||
|
||||
switch_status_t skinny_api_register(switch_loadable_module_interface_t **module_interface);
|
||||
switch_status_t skinny_api_unregister();
|
||||
switch_status_t skinny_api_unregister(void);
|
||||
|
||||
#endif /* _SKINNY_API_H */
|
||||
|
||||
|
||||
@@ -92,14 +92,14 @@ char* skinny_codec2string(skinny_codecs skinnycodec);
|
||||
/*****************************************************************************/
|
||||
|
||||
#define skinny_create_message(message,msgtype,field) \
|
||||
message = calloc(1, 12 + sizeof(message->data.field)); \
|
||||
message = calloc(1, sizeof(skinny_message_t)); \
|
||||
message->type = msgtype; \
|
||||
message->length = 4 + sizeof(message->data.field)
|
||||
|
||||
#define skinny_create_empty_message(message,msgtype) \
|
||||
message = calloc(1, 12); \
|
||||
message->type = msgtype; \
|
||||
message->length = 4
|
||||
message = calloc(1, sizeof(skinny_empty_message_t)); \
|
||||
((skinny_empty_message_t *)message)->type = msgtype; \
|
||||
((skinny_empty_message_t *)message)->length = 4
|
||||
|
||||
|
||||
/* KeepAliveMessage */
|
||||
@@ -937,6 +937,12 @@ union skinny_data {
|
||||
#pragma pack(push, r1, 1)
|
||||
#endif
|
||||
|
||||
struct PACKED skinny_empty_message {
|
||||
uint32_t length;
|
||||
uint32_t version;
|
||||
uint32_t type;
|
||||
};
|
||||
|
||||
/*
|
||||
* header is length+version
|
||||
* body is type+data
|
||||
@@ -954,6 +960,7 @@ struct PACKED skinny_message {
|
||||
#endif
|
||||
|
||||
typedef struct skinny_message skinny_message_t;
|
||||
typedef struct skinny_empty_message skinny_empty_message_t;
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ switch_endpoint_interface_t *sofia_endpoint_interface;
|
||||
|
||||
#define STRLEN 15
|
||||
|
||||
void mod_sofia_shutdown_cleanup();
|
||||
void mod_sofia_shutdown_cleanup(void);
|
||||
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);
|
||||
@@ -348,6 +348,7 @@ static int hangup_cause_to_sip(switch_call_cause_t cause)
|
||||
case SWITCH_CAUSE_BUSY_EVERYWHERE:
|
||||
return 600;
|
||||
case SWITCH_CAUSE_DECLINE:
|
||||
case SWITCH_CAUSE_REJECT_ALL:
|
||||
return 603;
|
||||
case SWITCH_CAUSE_DOES_NOT_EXIST_ANYWHERE:
|
||||
return 604;
|
||||
@@ -472,7 +473,7 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session)
|
||||
switch_core_hash_delete_locked(tech_pvt->profile->chat_hash, tech_pvt->hash_key, tech_pvt->profile->flag_mutex);
|
||||
}
|
||||
|
||||
if (session && tech_pvt->profile->pres_type) {
|
||||
if (tech_pvt->profile->pres_type) {
|
||||
char *sql = switch_mprintf("delete from sip_dialogs where uuid='%q'", switch_core_session_get_uuid(session));
|
||||
switch_assert(sql);
|
||||
sofia_glue_execute_sql_now(tech_pvt->profile, &sql, SWITCH_TRUE);
|
||||
@@ -2065,7 +2066,8 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
||||
|
||||
nua_info(tech_pvt->nh, SIPTAG_CONTENT_TYPE_STR("message/sipfrag"),
|
||||
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), SIPTAG_PAYLOAD_STR(message), TAG_END());
|
||||
} else if (update_allowed && ua && (switch_stristr("polycom", ua) ||
|
||||
} else if (update_allowed && ua && (switch_channel_var_true(tech_pvt->channel, "update_ignore_ua") ||
|
||||
switch_stristr("polycom", ua) ||
|
||||
(switch_stristr("aastra", ua) && !switch_stristr("Intelligate", ua)) ||
|
||||
(switch_stristr("cisco/spa50", ua) ||
|
||||
switch_stristr("cisco/spa525", ua)) ||
|
||||
@@ -2204,11 +2206,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
||||
argv[i], (double)((double)(MAX_REDIR + 1 - i))/1000);
|
||||
}
|
||||
} else {
|
||||
if (i == argc - 1) {
|
||||
switch_snprintf(newdest + strlen(newdest), len - strlen(newdest), "\"unknown\" <%s>", argv[i]);
|
||||
} else {
|
||||
switch_snprintf(newdest + strlen(newdest), len - strlen(newdest), "\"unknown\" <%s>,", argv[i]);
|
||||
}
|
||||
switch_snprintf(newdest + strlen(newdest), len - strlen(newdest), "\"unknown\" <%s>", argv[i]);
|
||||
}
|
||||
} else {
|
||||
if (i == argc - 1) {
|
||||
@@ -3257,8 +3255,6 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl
|
||||
switch_hash_index_t *hi;
|
||||
void *val;
|
||||
const void *vvar;
|
||||
int c = 0;
|
||||
int ac = 0;
|
||||
const char *header = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>";
|
||||
|
||||
if (argc > 0) {
|
||||
@@ -3468,7 +3464,6 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl
|
||||
if (sofia_test_pflag(profile, PFLAG_RUNNING)) {
|
||||
|
||||
if (strcmp(vvar, profile->name)) {
|
||||
ac++;
|
||||
stream->write_function(stream, "<alias>\n<name>%s</name>\n<type>%s</type>\n<data>%s</data>\n<state>%s</state>\n</alias>\n", vvar, "alias",
|
||||
profile->name, "ALIASED");
|
||||
} else {
|
||||
@@ -3494,8 +3489,6 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl
|
||||
profile->inuse);
|
||||
}
|
||||
|
||||
c++;
|
||||
|
||||
for (gp = profile->gateways; gp; gp = gp->next) {
|
||||
switch_assert(gp->state < REG_STATE_LAST);
|
||||
stream->write_function(stream, "<gateway>\n<name>%s</name>\n<type>%s</type>\n<data>%s</data>\n<state>%s</state>\n</gateway>\n",
|
||||
@@ -4312,6 +4305,8 @@ SWITCH_STANDARD_API(sofia_presence_data_function)
|
||||
user = argv[1];
|
||||
}
|
||||
|
||||
if (!user) goto end;
|
||||
|
||||
if ((domain = strchr(user, '@'))) {
|
||||
*domain++ = '\0';
|
||||
if ((concat = strchr(domain, '/'))) {
|
||||
@@ -4328,8 +4323,6 @@ SWITCH_STANDARD_API(sofia_presence_data_function)
|
||||
domain = dup_domain;
|
||||
}
|
||||
|
||||
if (!user) goto end;
|
||||
|
||||
if (zstr(profile_name) || strcmp(profile_name, "*") || zstr(domain)) {
|
||||
if (!zstr(profile_name)) {
|
||||
profile = sofia_glue_find_profile(profile_name);
|
||||
@@ -6835,7 +6828,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
|
||||
return status;
|
||||
}
|
||||
|
||||
void mod_sofia_shutdown_cleanup() {
|
||||
void mod_sofia_shutdown_cleanup(void) {
|
||||
int sanity = 0;
|
||||
int i;
|
||||
switch_status_t st;
|
||||
|
||||
@@ -82,9 +82,6 @@
|
||||
* <dt>-6</dt>
|
||||
* <dd>Query IP6 addresses (AAAA records).
|
||||
* </dd>
|
||||
* <dt>-v</dt>
|
||||
* <dd>Be verbatim.
|
||||
* </dd>
|
||||
* <dt></dt>
|
||||
* <dd>
|
||||
* </dd>
|
||||
@@ -201,7 +198,7 @@ switch_bool_t verify_ip(sres_record_t **answers, const char *ip, switch_bool_t i
|
||||
switch_status_t sip_dig_function(_In_opt_z_ const char *cmd, _In_opt_ switch_core_session_t *session, _In_ switch_stream_handle_t *stream)
|
||||
|
||||
{
|
||||
int o_sctp = 1, o_tls_sctp = 1, o_verbatim = 1;
|
||||
int o_sctp = 1, o_tls_sctp = 1;
|
||||
int family = 0, multiple = 0;
|
||||
char const *string;
|
||||
url_t *uri = NULL;
|
||||
@@ -247,9 +244,7 @@ switch_status_t sip_dig_function(_In_opt_z_ const char *cmd, _In_opt_ switch_cor
|
||||
}
|
||||
|
||||
while (argv[i] && argv[i][0] == '-') {
|
||||
if (strcmp(argv[i], "-v") == 0) {
|
||||
o_verbatim++;
|
||||
} else if (strcmp(argv[i], "-6") == 0) {
|
||||
if (strcmp(argv[i], "-6") == 0) {
|
||||
dig->ip6 = ++family;
|
||||
} else if (strcmp(argv[i], "-4") == 0) {
|
||||
dig->ip4 = ++family;
|
||||
@@ -815,8 +810,12 @@ sres_record_t ** dig_addr_simple(struct dig *dig,
|
||||
uint16_t type)
|
||||
{
|
||||
sres_record_t **answers = NULL;
|
||||
int error;
|
||||
|
||||
sres_blocking_query(dig->sres, type, host, 0, &answers);
|
||||
error = sres_blocking_query(dig->sres, type, host, 0, &answers);
|
||||
if (error < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return answers;
|
||||
}
|
||||
|
||||
@@ -2818,7 +2818,10 @@ void event_handler(switch_event_t *event)
|
||||
|
||||
if ((sptr = strstr(fixed_contact_str, needle))) {
|
||||
char *origsptr = strstr(contact_str, needle);
|
||||
eptr = strchr(++origsptr, ';');
|
||||
|
||||
if (origsptr) {
|
||||
eptr = strchr(++origsptr, ';');
|
||||
}
|
||||
} else {
|
||||
sptr = strchr(fixed_contact_str, '\0') - 1;
|
||||
}
|
||||
@@ -2949,6 +2952,9 @@ void *SWITCH_THREAD_FUNC sofia_profile_worker_thread_run(switch_thread_t *thread
|
||||
|
||||
sofia_set_pflag_locked(profile, PFLAG_WORKER_RUNNING);
|
||||
|
||||
/* Seed PRNG for functions within worker thread */
|
||||
srand((unsigned)((intptr_t) switch_thread_self() + switch_micro_time_now()));
|
||||
|
||||
while ((mod_sofia_globals.running == 1 && sofia_test_pflag(profile, PFLAG_RUNNING))) {
|
||||
|
||||
if (tick) {
|
||||
|
||||
@@ -446,14 +446,16 @@ void sofia_glue_store_session_id(switch_core_session_t *session, sofia_profile_t
|
||||
|
||||
a_id = switch_strip_whitespace(duped);
|
||||
|
||||
if (zstr(a_id)) return;
|
||||
if (zstr(a_id)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
p = strchr(a_id, ';');
|
||||
if (p) *p = '\0';
|
||||
|
||||
if (!sofia_glue_is_valid_session_uuid(a_id)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Session-ID: Ignoring \"%s\" parsed as \"%s\"\n", header, a_id);
|
||||
return;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* RFC7329 compatibility */
|
||||
@@ -483,7 +485,7 @@ void sofia_glue_store_session_id(switch_core_session_t *session, sofia_profile_t
|
||||
if (!p) {
|
||||
switch_channel_set_flag(channel, CF_RFC7329_COMPAT);
|
||||
switch_channel_set_flag_partner(channel, CF_RFC7329_COMPAT);
|
||||
return;
|
||||
goto end;
|
||||
}
|
||||
p++;
|
||||
remote_param = strstr(p, "remote=");
|
||||
@@ -491,7 +493,7 @@ void sofia_glue_store_session_id(switch_core_session_t *session, sofia_profile_t
|
||||
switch_channel_set_flag(channel, CF_RFC7329_COMPAT);
|
||||
switch_channel_set_flag_partner(channel, CF_RFC7329_COMPAT);
|
||||
sofia_glue_check_filter_generic_params(session, profile, p);
|
||||
return;
|
||||
goto end;
|
||||
}
|
||||
b_id = remote_param + 7;
|
||||
if (!zstr(b_id) && strlen(b_id) == RFC7989_SESSION_UUID_LEN /*32*/) {
|
||||
@@ -503,6 +505,9 @@ void sofia_glue_store_session_id(switch_core_session_t *session, sofia_profile_t
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Session-ID: invalid uuid, ignored.\n");
|
||||
}
|
||||
|
||||
end:
|
||||
switch_safe_free(a_id);
|
||||
}
|
||||
|
||||
/* add "Session-ID:" header */
|
||||
@@ -924,9 +929,9 @@ char *sofia_glue_get_extra_headers(switch_channel_t *channel, const char *prefix
|
||||
if ( !exclude_regex || !(/*proceed*/ switch_regex_perform(name, exclude_regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
|
||||
const char *hname = name + strlen(prefix);
|
||||
stream.write_function(&stream, "%s: %s\r\n", hname, value);
|
||||
switch_regex_safe_free(re);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Ignoring Extra Header [%s] , matches exclude_outgoing_extra_header [%s]\n", name, exclude_regex);
|
||||
switch_regex_safe_free(re);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2277,8 +2282,7 @@ int sofia_recover_callback(switch_core_session_t *session)
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
private_object_t *tech_pvt = NULL;
|
||||
sofia_profile_t *profile = NULL;
|
||||
const char *tmp;
|
||||
const char *rr;
|
||||
const char *tmp, *rr, *use_uuid;
|
||||
int r = 0;
|
||||
const char *profile_name = switch_channel_get_variable_dup(channel, "recovery_profile_name", SWITCH_FALSE, -1);
|
||||
int swap = switch_channel_var_true(channel, "dlg_req_swap_direction");
|
||||
@@ -2369,17 +2373,13 @@ int sofia_recover_callback(switch_core_session_t *session)
|
||||
);
|
||||
}
|
||||
|
||||
if (session) {
|
||||
const char *use_uuid;
|
||||
|
||||
if ((use_uuid = switch_channel_get_variable(channel, "origination_uuid"))) {
|
||||
if (switch_core_session_set_uuid(session, use_uuid) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s set UUID=%s\n", switch_channel_get_name(channel),
|
||||
use_uuid);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "%s set UUID=%s FAILED\n",
|
||||
switch_channel_get_name(channel), use_uuid);
|
||||
}
|
||||
if ((use_uuid = switch_channel_get_variable(channel, "origination_uuid"))) {
|
||||
if (switch_core_session_set_uuid(session, use_uuid) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s set UUID=%s\n", switch_channel_get_name(channel),
|
||||
use_uuid);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "%s set UUID=%s FAILED\n",
|
||||
switch_channel_get_name(channel), use_uuid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -399,6 +399,7 @@ switch_status_t sofia_presence_chat_send(switch_event_t *message_event)
|
||||
switch_safe_free(route_uri);
|
||||
switch_safe_free(ffrom);
|
||||
switch_safe_free(dup);
|
||||
switch_safe_free(extra_headers);
|
||||
|
||||
if (profile) {
|
||||
switch_thread_rwlock_unlock(profile->rwlock);
|
||||
@@ -1620,7 +1621,6 @@ void *SWITCH_THREAD_FUNC sofia_presence_event_thread_run(switch_thread_t *thread
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Event Thread Started\n");
|
||||
|
||||
while (mod_sofia_globals.running == 1) {
|
||||
int count = 0;
|
||||
|
||||
if (switch_queue_pop(mod_sofia_globals.presence_queue, &pop) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_event_t *event = (switch_event_t *) pop;
|
||||
@@ -1655,7 +1655,6 @@ void *SWITCH_THREAD_FUNC sofia_presence_event_thread_run(switch_thread_t *thread
|
||||
}
|
||||
|
||||
switch_event_destroy(&event);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3755,7 +3754,6 @@ void sofia_presence_handle_sip_i_subscribe(int status,
|
||||
|
||||
if ((sub_max_deviation_var = profile->sip_subscription_max_deviation)) {
|
||||
int sub_deviation;
|
||||
srand( (unsigned) ( (unsigned)(intptr_t)switch_thread_self() + switch_micro_time_now() ) );
|
||||
/* random negative number between 0 and negative sub_max_deviation_var: */
|
||||
sub_deviation = ( rand() % sub_max_deviation_var ) - sub_max_deviation_var;
|
||||
if ( (exp_delta + sub_deviation) > 45 ) {
|
||||
|
||||
@@ -884,7 +884,6 @@ long sofia_reg_uniform_distribution(int max)
|
||||
int result;
|
||||
int range = max + 1;
|
||||
|
||||
srand((unsigned)((intptr_t) switch_thread_self() + switch_micro_time_now()));
|
||||
result = (int)((double)rand() / (((double)RAND_MAX + (double)1) / range));
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "Generated random %ld, max is %d\n", (long) result, max);
|
||||
@@ -894,8 +893,7 @@ long sofia_reg_uniform_distribution(int max)
|
||||
void sofia_reg_check_ping_expire(sofia_profile_t *profile, time_t now, int interval)
|
||||
{
|
||||
char *sql;
|
||||
int mean = interval / 2;
|
||||
long next, irand;
|
||||
long next;
|
||||
char buf[32] = "";
|
||||
int count;
|
||||
|
||||
@@ -952,8 +950,7 @@ void sofia_reg_check_ping_expire(sofia_profile_t *profile, time_t now, int inter
|
||||
/* only update if needed */
|
||||
if (count) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "Updating ping expires for profile %s\n", profile->name);
|
||||
irand = mean + sofia_reg_uniform_distribution(interval);
|
||||
next = (long) now + irand;
|
||||
next = (long) now + interval;
|
||||
|
||||
sql = switch_mprintf("update sip_registrations set ping_expires = %ld where hostname='%q' and profile_name='%q' and ping_expires <= %ld ",
|
||||
next, mod_sofia_globals.hostname, profile->name, (long) now);
|
||||
@@ -1765,7 +1762,6 @@ uint8_t sofia_reg_handle_register_token(nua_t *nua, sofia_profile_t *profile, nu
|
||||
(( exp_max_deviation_var = profile->sip_expires_max_deviation )) ) {
|
||||
if (exp_max_deviation_var > 0) {
|
||||
int exp_deviation;
|
||||
srand( (unsigned) ( (unsigned)(intptr_t)switch_thread_self() + switch_micro_time_now() ) );
|
||||
/* random number between negative exp_max_deviation_var and positive exp_max_deviation_var: */
|
||||
exp_deviation = ( rand() % ( exp_max_deviation_var * 2 ) ) - exp_max_deviation_var;
|
||||
exptime += exp_deviation;
|
||||
@@ -2013,23 +2009,26 @@ uint8_t sofia_reg_handle_register_token(nua_t *nua, sofia_profile_t *profile, nu
|
||||
sql = switch_mprintf("insert into sip_registrations "
|
||||
"(call_id,sip_user,sip_host,presence_hosts,contact,status,rpid,expires,"
|
||||
"user_agent,server_user,server_host,profile_name,hostname,network_ip,network_port,sip_username,sip_realm,"
|
||||
"mwi_user,mwi_host, orig_server_host, orig_hostname, sub_host, ping_status, ping_count, force_ping) "
|
||||
"values ('%q','%q', '%q','%q','%q','%q', '%q', %ld, '%q', '%q', '%q', '%q', '%q', '%q', '%q','%q','%q','%q','%q','%q','%q','%q', '%q', %d, %d)",
|
||||
"mwi_user,mwi_host, orig_server_host, orig_hostname, sub_host, ping_status, ping_count, ping_expires, force_ping) "
|
||||
"values ('%q','%q', '%q','%q','%q','%q', '%q', %ld, '%q', '%q', '%q', '%q', '%q', '%q', '%q','%q','%q','%q','%q','%q','%q','%q', '%q', %d, %ld, %d)",
|
||||
call_id, to_user, reg_host, profile->presence_hosts ? profile->presence_hosts : "",
|
||||
contact_str, reg_desc, rpid, (long) reg_time + (long) exptime + profile->sip_expires_late_margin,
|
||||
agent, from_user, guess_ip4, profile->name, mod_sofia_globals.hostname, network_ip, network_port_c, username, realm,
|
||||
mwi_user, mwi_host, guess_ip4, mod_sofia_globals.hostname, sub_host, "Reachable", 0, force_ping);
|
||||
mwi_user, mwi_host, guess_ip4, mod_sofia_globals.hostname, sub_host, "Reachable", 0,
|
||||
(long) switch_epoch_time_now(NULL) + sofia_reg_uniform_distribution(profile->iping_seconds), force_ping);
|
||||
} else {
|
||||
sql = switch_mprintf("update sip_registrations set call_id='%q',"
|
||||
"sub_host='%q', network_ip='%q',network_port='%q',"
|
||||
"presence_hosts='%q', server_host='%q', orig_server_host='%q',"
|
||||
"hostname='%q', orig_hostname='%q',"
|
||||
"expires = %ld, force_ping=%d where sip_user='%q' and sip_username='%q' and sip_host='%q' and contact='%q'",
|
||||
"expires = %ld, ping_expires=%ld, force_ping=%d "
|
||||
"where sip_user='%q' and sip_username='%q' and sip_host='%q' and contact='%q'",
|
||||
call_id, sub_host, network_ip, network_port_c,
|
||||
profile->presence_hosts ? profile->presence_hosts : "", guess_ip4, guess_ip4,
|
||||
mod_sofia_globals.hostname, mod_sofia_globals.hostname,
|
||||
(long) reg_time + (long) exptime + profile->sip_expires_late_margin, force_ping,
|
||||
to_user, username, reg_host, contact_str);
|
||||
(long) reg_time + (long) exptime + profile->sip_expires_late_margin,
|
||||
(long) switch_epoch_time_now(NULL) + sofia_reg_uniform_distribution(profile->iping_seconds),
|
||||
force_ping, to_user, username, reg_host, contact_str);
|
||||
}
|
||||
|
||||
if (sql) {
|
||||
|
||||
@@ -90,7 +90,7 @@ static const char *test_wait_for_chan_var(switch_channel_t *channel, const char
|
||||
return var;
|
||||
}
|
||||
|
||||
static switch_bool_t has_ipv6()
|
||||
static switch_bool_t has_ipv6(void)
|
||||
{
|
||||
switch_stream_handle_t stream = { 0 };
|
||||
SWITCH_STANDARD_STREAM(stream);
|
||||
@@ -110,7 +110,7 @@ static switch_bool_t has_ipv6()
|
||||
return SWITCH_TRUE;
|
||||
}
|
||||
|
||||
static void register_gw()
|
||||
static void register_gw(void)
|
||||
{
|
||||
switch_stream_handle_t stream = { 0 };
|
||||
SWITCH_STANDARD_STREAM(stream);
|
||||
@@ -118,7 +118,7 @@ static void register_gw()
|
||||
switch_safe_free(stream.data);
|
||||
}
|
||||
|
||||
static void unregister_gw()
|
||||
static void unregister_gw(void)
|
||||
{
|
||||
switch_stream_handle_t stream = { 0 };
|
||||
SWITCH_STANDARD_STREAM(stream);
|
||||
|
||||
@@ -86,6 +86,7 @@ int mcast_socket_create(const char *host, int16_t port, mcast_handle_t *handle,
|
||||
|
||||
if ( setsockopt(handle->sock, SOL_SOCKET, SO_REUSEADDR, (void *)&one, sizeof(one)) != 0 ) {
|
||||
mcast_socket_close(handle);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -103,11 +104,13 @@ int mcast_socket_create(const char *host, int16_t port, mcast_handle_t *handle,
|
||||
|
||||
if (setsockopt(handle->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&mreq, sizeof(mreq)) < 0) {
|
||||
mcast_socket_close(handle);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bind(handle->sock, (struct sockaddr *) &handle->recv_addr, sizeof(handle->recv_addr)) < 0) {
|
||||
mcast_socket_close(handle);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -124,7 +127,11 @@ int mcast_socket_create(const char *host, int16_t port, mcast_handle_t *handle,
|
||||
addr_criteria.ai_flags |= AI_NUMERICHOST;
|
||||
|
||||
snprintf(service, sizeof(service), "%d", port);
|
||||
getaddrinfo(host, service, &addr_criteria, &mcast_addr);
|
||||
if (getaddrinfo(host, service, &addr_criteria, &mcast_addr) != 0) {
|
||||
mcast_socket_close(handle);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
memset(&handle->recv_addr6, 0, sizeof(handle->recv_addr6));
|
||||
@@ -134,11 +141,14 @@ int mcast_socket_create(const char *host, int16_t port, mcast_handle_t *handle,
|
||||
|
||||
memcpy(&mreq.ipv6mr_multiaddr, &((struct sockaddr_in6 *)mcast_addr->ai_addr)->sin6_addr, sizeof(struct in6_addr));
|
||||
|
||||
freeaddrinfo(mcast_addr);
|
||||
|
||||
mreq.ipv6mr_interface = 0;
|
||||
setsockopt(handle->sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, (const char *)&mreq, sizeof(mreq));
|
||||
|
||||
if (bind(handle->sock, (struct sockaddr *) &handle->recv_addr6, sizeof(handle->recv_addr6)) < 0) {
|
||||
mcast_socket_close(handle);
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ SWITCH_MODULE_DEFINITION(mod_verto, mod_verto_load, mod_verto_shutdown, mod_vert
|
||||
#define HTTP_CHUNK_SIZE 1024 * 32
|
||||
#define EP_NAME "verto.rtc"
|
||||
//#define WSS_STANDALONE 1
|
||||
#include "ks.h"
|
||||
#include "libks/ks.h"
|
||||
|
||||
#include <mod_verto.h>
|
||||
#ifndef WIN32
|
||||
@@ -771,10 +771,6 @@ static void jsock_send_event(cJSON *event)
|
||||
}
|
||||
switch_thread_rwlock_unlock(verto_globals.event_channel_rwlock);
|
||||
|
||||
if (use_jsock) {
|
||||
switch_thread_rwlock_unlock(use_jsock->rwlock);
|
||||
use_jsock = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static jrpc_func_t jrpc_get_func(jsock_t *jsock, const char *method)
|
||||
@@ -827,7 +823,6 @@ static void set_perm(const char *str, switch_event_t **event, switch_bool_t add)
|
||||
{
|
||||
char delim = ',';
|
||||
char *cur, *next;
|
||||
int count = 0;
|
||||
char *edup;
|
||||
|
||||
if (!zstr(str)) {
|
||||
@@ -840,7 +835,7 @@ static void set_perm(const char *str, switch_event_t **event, switch_bool_t add)
|
||||
switch_event_create(event, SWITCH_EVENT_REQUEST_PARAMS);
|
||||
}
|
||||
|
||||
if (!zstr(str)) {
|
||||
if (!zstr(str) && event && *event) {
|
||||
edup = strdup(str);
|
||||
switch_assert(edup);
|
||||
|
||||
@@ -848,7 +843,7 @@ static void set_perm(const char *str, switch_event_t **event, switch_bool_t add)
|
||||
delim = ' ';
|
||||
}
|
||||
|
||||
for (cur = edup; cur; count++) {
|
||||
for (cur = edup; cur;) {
|
||||
if ((next = strchr(cur, delim))) {
|
||||
*next++ = '\0';
|
||||
}
|
||||
@@ -1063,13 +1058,13 @@ static switch_bool_t check_auth(jsock_t *jsock, cJSON *params, int *code, char *
|
||||
*code = CODE_AUTH_FAILED;
|
||||
switch_snprintf(message, mlen, "Login Incorrect");
|
||||
login_fire_custom_event(jsock, params, 0, "Login Incorrect");
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Login incorrect for user: %s domain: %s\n", id, domain ? domain : "N/A");
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Login incorrect for user: %s domain: %s\n", id, domain);
|
||||
} else {
|
||||
switch_xml_t x_param, x_params;
|
||||
const char *use_passwd = NULL, *verto_context = NULL, *verto_dialplan = NULL;
|
||||
time_t now = switch_epoch_time_now(NULL);
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Login sucessful for user: %s domain: %s\n", id, domain ? domain : "N/A");
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Login sucessful for user: %s domain: %s\n", id, domain);
|
||||
|
||||
jsock->logintime = now;
|
||||
jsock->id = switch_core_strdup(jsock->pool, id);
|
||||
@@ -3870,6 +3865,15 @@ static switch_bool_t verto__info_func(const char *method, cJSON *params, jsock_t
|
||||
cJSON *i, *indialog = cJSON_GetObjectItem(msg, "inDialog");
|
||||
const char *body = cJSON_GetObjectCstr(msg, "body");
|
||||
switch_bool_t is_dialog = indialog && (indialog->type == cJSON_True || (indialog->type == cJSON_String && switch_true(indialog->valuestring)));
|
||||
const char *context = NULL;
|
||||
|
||||
switch_mutex_lock(jsock->flag_mutex);
|
||||
|
||||
if (!(context = switch_event_get_header(jsock->vars, "user_context"))) {
|
||||
context = switch_either(jsock->context, jsock->profile->context);
|
||||
}
|
||||
|
||||
switch_mutex_unlock(jsock->flag_mutex);
|
||||
|
||||
if (!zstr(to)) {
|
||||
if (strchr(to, '+')) {
|
||||
@@ -3906,6 +3910,8 @@ static switch_bool_t verto__info_func(const char *method, cJSON *params, jsock_t
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call_id", call_id);
|
||||
}
|
||||
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "context", context);
|
||||
|
||||
switch_event_add_body(event, "%s", body);
|
||||
|
||||
if (strcasecmp(proto, VERTO_CHAT_PROTO)) {
|
||||
@@ -3958,7 +3964,7 @@ static switch_bool_t verto__invite_func(const char *method, cJSON *params, jsock
|
||||
cJSON *obj = cJSON_CreateObject(), *vobj = NULL, *dedEnc = NULL, *mirrorInput, *bandwidth = NULL, *canvas = NULL;
|
||||
switch_core_session_t *session = NULL;
|
||||
switch_channel_t *channel;
|
||||
switch_event_t *var_event;
|
||||
switch_event_t *var_event = NULL;
|
||||
switch_call_cause_t reason = SWITCH_CAUSE_INVALID_MSG_UNSPECIFIED, cancel_cause = 0;
|
||||
switch_caller_profile_t *caller_profile;
|
||||
int err = 0;
|
||||
@@ -4760,14 +4766,12 @@ static int start_jsock(verto_profile_t *profile, ks_socket_t sock, int family)
|
||||
|
||||
error:
|
||||
|
||||
if (jsock) {
|
||||
if (jsock->client_socket != KS_SOCK_INVALID) {
|
||||
close_socket(&jsock->client_socket);
|
||||
}
|
||||
|
||||
switch_core_destroy_memory_pool(&pool);
|
||||
if (jsock->client_socket != KS_SOCK_INVALID) {
|
||||
close_socket(&jsock->client_socket);
|
||||
}
|
||||
|
||||
switch_core_destroy_memory_pool(&pool);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -5585,8 +5589,6 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl
|
||||
{
|
||||
verto_profile_t *profile = NULL;
|
||||
jsock_t *jsock;
|
||||
int cp = 0;
|
||||
int cc = 0;
|
||||
const char *header = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>";
|
||||
int i;
|
||||
|
||||
@@ -5600,14 +5602,12 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl
|
||||
stream->write_function(stream, "<profile>\n<name>%s</name>\n<type>%s</type>\n<data>%s</data>\n<state>%s</state>\n</profile>\n", profile->name, "profile", tmpurl, (profile->running) ? "RUNNING" : "DOWN");
|
||||
switch_safe_free(tmpurl);
|
||||
}
|
||||
cp++;
|
||||
|
||||
switch_mutex_lock(profile->mutex);
|
||||
for(jsock = profile->jsock_head; jsock; jsock = jsock->next) {
|
||||
char *tmpname = switch_mprintf("%s@%s", jsock->id, jsock->domain);
|
||||
stream->write_function(stream, "<client>\n<profile>%s</profile>\n<name>%s</name>\n<type>%s</type>\n<data>%s</data>\n<state>%s (%s)</state>\n</client>\n", profile->name, tmpname, "client", jsock->name,
|
||||
(!zstr(jsock->uid)) ? "CONN_REG" : "CONN_NO_REG", (jsock->ptype & PTYPE_CLIENT_SSL) ? "WSS": "WS");
|
||||
cc++;
|
||||
switch_safe_free(tmpname);
|
||||
}
|
||||
switch_mutex_unlock(profile->mutex);
|
||||
@@ -5617,7 +5617,7 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cJSON *json_status()
|
||||
static cJSON *json_status(void)
|
||||
{
|
||||
cJSON *obj, *profiles, *jprofile, *users, *user;
|
||||
verto_profile_t *profile = NULL;
|
||||
@@ -6746,14 +6746,14 @@ static void mod_verto_ks_logger(const char *file, const char *func, int line, in
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
static void verto_event_free_subclass()
|
||||
static void verto_event_free_subclass(void)
|
||||
{
|
||||
switch_event_free_subclass(MY_EVENT_LOGIN);
|
||||
switch_event_free_subclass(MY_EVENT_CLIENT_DISCONNECT);
|
||||
switch_event_free_subclass(MY_EVENT_CLIENT_CONNECT);
|
||||
}
|
||||
|
||||
static void verto_destroy_globals_hash_tables()
|
||||
static void verto_destroy_globals_hash_tables(void)
|
||||
{
|
||||
if (verto_globals.method_hash) {
|
||||
switch_core_hash_destroy(&verto_globals.method_hash);
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
#include <openssl/ssl.h>
|
||||
#include "mcast.h"
|
||||
|
||||
#include "ks.h"
|
||||
#include "libks/ks.h"
|
||||
|
||||
#define MAX_QUEUE_LEN 100000
|
||||
#define MAX_MISSED 500
|
||||
|
||||
@@ -70,6 +70,11 @@
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>AMQP_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
|
||||
@@ -87,6 +87,11 @@ typedef struct mod_amqp_keypart_s {
|
||||
int size;
|
||||
} mod_amqp_keypart_t;
|
||||
|
||||
typedef struct {
|
||||
switch_event_types_t id;
|
||||
char* subclass;
|
||||
} mod_amqp_events_t;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
|
||||
@@ -103,7 +108,7 @@ typedef struct {
|
||||
/* Array to store the possible event subscriptions */
|
||||
int event_subscriptions;
|
||||
switch_event_node_t *event_nodes[SWITCH_EVENT_ALL];
|
||||
switch_event_types_t event_ids[SWITCH_EVENT_ALL];
|
||||
mod_amqp_events_t events[SWITCH_EVENT_ALL];
|
||||
switch_event_node_t *eventNode;
|
||||
|
||||
|
||||
|
||||
@@ -203,7 +203,11 @@ switch_status_t mod_amqp_connection_create(mod_amqp_connection_t **conn, switch_
|
||||
amqp_boolean_t ssl_verify_peer = 1;
|
||||
|
||||
if (zstr(name)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Connection missing name attribute\n%s\n", switch_xml_toxml(cfg, 1));
|
||||
char *str_tmp = switch_xml_toxml(cfg, 1);
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Connection missing name attribute\n%s\n", str_tmp);
|
||||
switch_safe_free(str_tmp);
|
||||
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
@@ -260,6 +264,7 @@ switch_status_t mod_amqp_connection_create(mod_amqp_connection_t **conn, switch_
|
||||
new_con->ssl_verify_peer = ssl_verify_peer;
|
||||
|
||||
*conn = new_con;
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -186,7 +186,8 @@ switch_status_t mod_amqp_producer_create(char *name, switch_xml_t cfg)
|
||||
profile->name = switch_core_strdup(profile->pool, name);
|
||||
profile->running = 1;
|
||||
memset(profile->format_fields, 0, (MAX_ROUTING_KEY_FORMAT_FIELDS + 1) * sizeof(mod_amqp_keypart_t));
|
||||
profile->event_ids[0] = SWITCH_EVENT_ALL;
|
||||
profile->events[0].id = SWITCH_EVENT_ALL;
|
||||
profile->events[0].subclass = SWITCH_EVENT_SUBCLASS_ANY;
|
||||
profile->event_subscriptions = 1;
|
||||
profile->conn_root = NULL;
|
||||
profile->conn_active = NULL;
|
||||
@@ -269,7 +270,14 @@ switch_status_t mod_amqp_producer_create(char *name, switch_xml_t cfg)
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Found %d subscriptions\n", profile->event_subscriptions);
|
||||
|
||||
for (arg = 0; arg < profile->event_subscriptions; arg++) {
|
||||
if (switch_name_event(argv[arg], &(profile->event_ids[arg])) != SWITCH_STATUS_SUCCESS) {
|
||||
char *subclass = SWITCH_EVENT_SUBCLASS_ANY;
|
||||
if ((subclass = strchr(argv[arg], '^'))) {
|
||||
*subclass++ = '\0';
|
||||
}
|
||||
|
||||
if (switch_name_event(argv[arg], &(profile->events[arg].id)) == SWITCH_STATUS_SUCCESS) {
|
||||
profile->events[arg].subclass = subclass;
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "The switch event %s was not recognised.\n", argv[arg]);
|
||||
}
|
||||
}
|
||||
@@ -344,13 +352,13 @@ switch_status_t mod_amqp_producer_create(char *name, switch_xml_t cfg)
|
||||
/* Subscribe events */
|
||||
for (i = 0; i < profile->event_subscriptions; i++) {
|
||||
if (switch_event_bind_removable("AMQP",
|
||||
profile->event_ids[i],
|
||||
SWITCH_EVENT_SUBCLASS_ANY,
|
||||
profile->events[i].id,
|
||||
profile->events[i].subclass,
|
||||
mod_amqp_producer_event_handler,
|
||||
profile,
|
||||
&(profile->event_nodes[i])) != SWITCH_STATUS_SUCCESS) {
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot bind to event handler %d!\n",(int)profile->event_ids[i]);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot bind to event handler %d!\n",(int)profile->events[i].id);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,7 +272,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session)
|
||||
}
|
||||
|
||||
|
||||
static void do_rotate_all()
|
||||
static void do_rotate_all(void)
|
||||
{
|
||||
switch_hash_index_t *hi;
|
||||
void *val;
|
||||
@@ -294,7 +294,7 @@ static void do_rotate_all()
|
||||
}
|
||||
|
||||
|
||||
static void do_teardown()
|
||||
static void do_teardown(void)
|
||||
{
|
||||
switch_hash_index_t *hi;
|
||||
void *val;
|
||||
|
||||
@@ -1998,7 +1998,7 @@ SWITCH_MODULE_RUNTIME_FUNCTION(mod_erlang_event_runtime)
|
||||
struct ei_cnode_s ec;
|
||||
ErlConnect conn;
|
||||
int clientfd;
|
||||
switch_os_socket_t epmdfd;
|
||||
switch_os_socket_t epmdfd = SWITCH_SOCK_INVALID;
|
||||
switch_socket_t *epmd_sock = NULL;
|
||||
|
||||
if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
|
||||
|
||||
@@ -153,16 +153,18 @@ static switch_status_t load_config(switch_xml_t input_cfg)
|
||||
}
|
||||
|
||||
if ((settings = switch_xml_child(cfg, "settings"))) {
|
||||
|
||||
for (param = switch_xml_child(settings, "param"); param; param = param->next) {
|
||||
char *var = (char *) switch_xml_attr_soft(param, "name");
|
||||
char *val = (char *) switch_xml_attr_soft(param, "value");
|
||||
char *val_no_whitespace = switch_strip_whitespace(val);
|
||||
|
||||
if (!strcasecmp(var, "address")) {
|
||||
set_global_dst_addrs(switch_strip_whitespace(val));
|
||||
set_global_dst_addrs(val_no_whitespace);
|
||||
} else if (!strcasecmp(var, "source_address")) {
|
||||
set_global_src_addr(switch_strip_whitespace(val));
|
||||
set_global_src_addr(val_no_whitespace);
|
||||
} else if (!strcasecmp(var, "source_address_ipv6")) {
|
||||
set_global_src_addr6(switch_strip_whitespace(val));
|
||||
set_global_src_addr6(val_no_whitespace);
|
||||
} else if (!strcasecmp(var, "bindings")) {
|
||||
set_global_bindings(val);
|
||||
} else if (!strcasecmp(var, "port")) {
|
||||
@@ -183,6 +185,8 @@ static switch_status_t load_config(switch_xml_t input_cfg)
|
||||
} else if (!strcasecmp(var, "loopback")) {
|
||||
globals.loopback = switch_true(val);
|
||||
}
|
||||
|
||||
switch_safe_free(val_no_whitespace);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,6 +194,7 @@ static switch_status_t load_config(switch_xml_t input_cfg)
|
||||
|
||||
|
||||
if (globals.bindings) {
|
||||
|
||||
for (cur = globals.bindings; cur; count++) {
|
||||
switch_event_types_t type;
|
||||
|
||||
@@ -293,13 +298,13 @@ static switch_status_t initialize_sockets(switch_xml_t input_cfg)
|
||||
char *host_string;
|
||||
char ipv6_first_octet[3];
|
||||
|
||||
memset(&globals.dst_sockaddrs[globals.num_dst_addrs].sockaddr, 0, sizeof(dst_sockaddr_t));
|
||||
|
||||
if (globals.num_dst_addrs > MAX_DST_HOSTS) {
|
||||
if (globals.num_dst_addrs >= MAX_DST_HOSTS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot add destination address: %s, exceeded maximum of %d\n", dst_hosts[i], MAX_DST_HOSTS);
|
||||
continue;
|
||||
}
|
||||
|
||||
memset(&globals.dst_sockaddrs[globals.num_dst_addrs], 0, sizeof(dst_sockaddr_t));
|
||||
|
||||
if (switch_sockaddr_info_get(&globals.dst_sockaddrs[globals.num_dst_addrs].sockaddr, dst_hosts[i], SWITCH_UNSPEC, globals.port, 0, module_pool) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find address: %s\n", dst_hosts[i]);
|
||||
switch_goto_status(SWITCH_STATUS_TERM, fail);
|
||||
@@ -627,8 +632,8 @@ static void event_handler(switch_event_t *event)
|
||||
len = strlen(packet) + strlen((char *) MAGIC);
|
||||
#endif
|
||||
buf = malloc(len + 1);
|
||||
memset(buf, 0, len + 1);
|
||||
switch_assert(buf);
|
||||
memset(buf, 0, len + 1);
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
if (globals.psk) {
|
||||
@@ -777,7 +782,11 @@ static switch_status_t process_packet(char* packet, size_t len)
|
||||
switch_url_decode(val);
|
||||
switch_snprintf(tmpname, sizeof(tmpname), "Orig-%s", var);
|
||||
switch_event_add_header_string(local_event, SWITCH_STACK_BOTTOM, tmpname, val);
|
||||
var = term + 1;
|
||||
if (term) {
|
||||
var = term + 1;
|
||||
} else {
|
||||
var = NULL;
|
||||
}
|
||||
} else {
|
||||
/* This should be our magic packet, done processing incoming headers */
|
||||
break;
|
||||
|
||||
@@ -866,7 +866,7 @@ SWITCH_STANDARD_API(event_sink_function)
|
||||
char *loglevel = switch_event_get_header(stream->param_event, "loglevel");
|
||||
switch_memory_pool_t *pool;
|
||||
char *next, *cur;
|
||||
uint32_t count = 0, key_count = 0;
|
||||
uint32_t key_count = 0;
|
||||
uint8_t custom = 0;
|
||||
char *edup;
|
||||
|
||||
@@ -925,7 +925,7 @@ SWITCH_STANDARD_API(event_sink_function)
|
||||
delim = ' ';
|
||||
}
|
||||
|
||||
for (cur = edup; cur; count++) {
|
||||
for (cur = edup; cur;) {
|
||||
switch_event_types_t type;
|
||||
|
||||
if ((next = strchr(cur, delim))) {
|
||||
@@ -1846,7 +1846,7 @@ static switch_status_t parse_command(listener_t *listener, switch_event_t **even
|
||||
if (allowed_events) {
|
||||
char delim = ',';
|
||||
char *cur, *next;
|
||||
int count = 0, custom = 0, key_count = 0;
|
||||
int custom = 0;
|
||||
|
||||
switch_set_flag(listener, LFLAG_AUTH_EVENTS);
|
||||
|
||||
@@ -1862,7 +1862,7 @@ static switch_status_t parse_command(listener_t *listener, switch_event_t **even
|
||||
delim = ' ';
|
||||
}
|
||||
|
||||
for (cur = edup; cur; count++) {
|
||||
for (cur = edup; cur;) {
|
||||
switch_event_types_t type;
|
||||
|
||||
if ((next = strchr(cur, delim))) {
|
||||
@@ -1872,7 +1872,6 @@ static switch_status_t parse_command(listener_t *listener, switch_event_t **even
|
||||
if (custom) {
|
||||
switch_core_hash_insert(listener->allowed_event_hash, cur, MARKER);
|
||||
} else if (switch_name_event(cur, &type) == SWITCH_STATUS_SUCCESS) {
|
||||
key_count++;
|
||||
if (type == SWITCH_EVENT_ALL) {
|
||||
uint32_t x = 0;
|
||||
switch_set_flag(listener, LFLAG_ALL_EVENTS_AUTHED);
|
||||
@@ -1904,7 +1903,6 @@ static switch_status_t parse_command(listener_t *listener, switch_event_t **even
|
||||
if (allowed_api) {
|
||||
char delim = ',';
|
||||
char *cur, *next;
|
||||
int count = 0;
|
||||
|
||||
switch_snprintf(api_reply, sizeof(api_reply), "Allowed-API: %s\n", allowed_api);
|
||||
|
||||
@@ -1916,7 +1914,7 @@ static switch_status_t parse_command(listener_t *listener, switch_event_t **even
|
||||
delim = ' ';
|
||||
}
|
||||
|
||||
for (cur = edup; cur; count++) {
|
||||
for (cur = edup; cur;) {
|
||||
if ((next = strchr(cur, delim))) {
|
||||
*next++ = '\0';
|
||||
}
|
||||
@@ -2540,14 +2538,14 @@ static switch_status_t parse_command(listener_t *listener, switch_event_t **even
|
||||
|
||||
} else if (!strncasecmp(cmd, "nixevent", 8)) {
|
||||
char *next, *cur;
|
||||
uint32_t count = 0, key_count = 0;
|
||||
uint32_t key_count = 0;
|
||||
uint8_t custom = 0;
|
||||
|
||||
strip_cr(cmd);
|
||||
cur = cmd + 8;
|
||||
|
||||
if ((cur = strchr(cur, ' '))) {
|
||||
for (cur++; cur; count++) {
|
||||
for (cur++; cur;) {
|
||||
switch_event_types_t type;
|
||||
|
||||
if ((next = strchr(cur, ' '))) {
|
||||
|
||||
@@ -366,7 +366,9 @@ SWITCH_STANDARD_API(kz_http_put)
|
||||
goto done;
|
||||
}
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_UPLOAD, 1);
|
||||
#if !defined(LIBCURL_VERSION_NUM) || (LIBCURL_VERSION_NUM < 0x070c01)
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_PUT, 1);
|
||||
#endif
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers);
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_URL, url);
|
||||
|
||||
@@ -564,13 +564,16 @@ switch_status_t kazoo_config_fetch_handler(kazoo_config_ptr definitions, kazoo_c
|
||||
switch_memory_pool_t *pool = NULL;
|
||||
|
||||
char *name = (char *) switch_xml_attr_soft(cfg, "name");
|
||||
|
||||
if (zstr(name)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "missing name in profile\n");
|
||||
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error allocation pool for new profile : %s\n", name);
|
||||
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
@@ -582,6 +585,7 @@ switch_status_t kazoo_config_fetch_handler(kazoo_config_ptr definitions, kazoo_c
|
||||
fetch_section = switch_xml_parse_section_string(name);
|
||||
|
||||
if ((params = switch_xml_child(cfg, "params")) != NULL) {
|
||||
|
||||
for (param = switch_xml_child(params, "param"); param; param = param->next) {
|
||||
char *var = (char *) switch_xml_attr_soft(param, "name");
|
||||
char *val = (char *) switch_xml_attr_soft(param, "value");
|
||||
@@ -605,7 +609,9 @@ switch_status_t kazoo_config_fetch_handler(kazoo_config_ptr definitions, kazoo_c
|
||||
}
|
||||
|
||||
if (fetch_section == SWITCH_XML_SECTION_RESULT) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Fetch Profile[%s] invalid fetch-section: %s\n", name, switch_xml_toxml(cfg, SWITCH_FALSE));
|
||||
char *tmp = switch_xml_toxml(cfg, SWITCH_FALSE);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Fetch Profile[%s] invalid fetch-section: %s\n", name, tmp);
|
||||
free(tmp);
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -622,17 +628,20 @@ switch_status_t kazoo_config_fetch_handler(kazoo_config_ptr definitions, kazoo_c
|
||||
}
|
||||
}
|
||||
|
||||
if(ptr)
|
||||
if (ptr) {
|
||||
*ptr = profile;
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "fetch handler profile %s successfully configured\n", name);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
||||
err:
|
||||
/* Cleanup */
|
||||
if(pool) {
|
||||
switch_core_destroy_memory_pool(&pool);
|
||||
}
|
||||
if(pool) {
|
||||
switch_core_destroy_memory_pool(&pool);
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_GENERR;
|
||||
|
||||
}
|
||||
|
||||
@@ -233,9 +233,11 @@ cJSON * kazoo_event_add_field_to_json(cJSON *dst, switch_event_t *src, kazoo_fie
|
||||
} else if((header = switch_event_get_header_ptr(src, field->name)) != NULL) {
|
||||
if (header->idx) {
|
||||
item = cJSON_CreateArray();
|
||||
|
||||
for(i = 0; i < header->idx; i++) {
|
||||
cJSON_AddItemToArray(item, kazoo_event_json_value(field->out_type, header->array[i]));
|
||||
}
|
||||
|
||||
kazoo_cJSON_AddItemToObject(dst, field->as ? field->as : field->name, item);
|
||||
} else if (field->out_type_as_array) {
|
||||
item = cJSON_CreateArray();
|
||||
@@ -251,13 +253,16 @@ cJSON * kazoo_event_add_field_to_json(cJSON *dst, switch_event_t *src, kazoo_fie
|
||||
expanded = kz_event_expand_headers(src, field->value);
|
||||
if(expanded != NULL && !zstr(expanded)) {
|
||||
item = kazoo_event_add_json_value(dst, field, field->as ? field->as : field->name, expanded);
|
||||
if(expanded != field->value) {
|
||||
free(expanded);
|
||||
}
|
||||
}
|
||||
|
||||
if (expanded != field->value) {
|
||||
switch_safe_free(expanded);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case FIELD_FIRST_OF:
|
||||
|
||||
for(n = 0; n < field->list.size; n++) {
|
||||
if(*field->list.value[n] == '#') {
|
||||
item = kazoo_event_add_json_value(dst, field, field->as ? field->as : field->name, ++field->list.value[n]);
|
||||
@@ -267,33 +272,41 @@ cJSON * kazoo_event_add_field_to_json(cJSON *dst, switch_event_t *src, kazoo_fie
|
||||
if(header) {
|
||||
if (header->idx) {
|
||||
item = cJSON_CreateArray();
|
||||
|
||||
for(i = 0; i < header->idx; i++) {
|
||||
cJSON_AddItemToArray(item, kazoo_event_json_value(field->out_type, header->array[i]));
|
||||
}
|
||||
|
||||
kazoo_cJSON_AddItemToObject(dst, field->as ? field->as : field->name, item);
|
||||
} else {
|
||||
item = kazoo_event_add_json_value(dst, field, field->as ? field->as : field->name, header->value);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case FIELD_PREFIX:
|
||||
|
||||
for (header = src->headers; header; header = header->next) {
|
||||
if(!strncmp(header->name, field->name, strlen(field->name))) {
|
||||
if (header->idx) {
|
||||
cJSON *array = cJSON_CreateArray();
|
||||
|
||||
for(i = 0; i < header->idx; i++) {
|
||||
cJSON_AddItemToArray(array, kazoo_event_json_value(field->out_type, header->array[i]));
|
||||
}
|
||||
|
||||
kazoo_cJSON_AddItemToObject(dst, field->exclude_prefix ? header->name+strlen(field->name) : header->name, array);
|
||||
} else {
|
||||
kazoo_event_add_json_value(dst, field, field->exclude_prefix ? header->name+strlen(field->name) : header->name, header->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case FIELD_STATIC:
|
||||
@@ -308,7 +321,7 @@ cJSON * kazoo_event_add_field_to_json(cJSON *dst, switch_event_t *src, kazoo_fie
|
||||
break;
|
||||
}
|
||||
|
||||
return item;
|
||||
return item;
|
||||
}
|
||||
|
||||
static switch_status_t kazoo_event_add_fields_to_json(kazoo_logging_ptr logging, cJSON *dst, switch_event_t *src, kazoo_field_ptr field) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user