Merge branch 'master' of ssh://git.freeswitch.org:222/freeswitch

This commit is contained in:
Mathieu Rene 2012-06-20 15:43:20 -04:00
commit a0a9efcf02
102 changed files with 1581 additions and 3304 deletions

1
.gitignore vendored
View File

@ -99,6 +99,7 @@ TAGS
/build/Makefile
/build/Makefile.in
/build/modmake.rules
/build/print_git_revision
/libs/curl/lib/ca-bundle.h
/libs/esl/fs_cli

View File

@ -1 +0,0 @@
@SWITCH_VERSION_REVISION@

View File

@ -527,6 +527,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_gsmopen", "src\mod\endp
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libzrtp", "libs\libzrtp\projects\win\libzrtp.2010.vcxproj", "{C13CC324-0032-4492-9A30-310A6BD64FF5}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_redis", "src\mod\applications\mod_redis\mod_redis.2010.vcxproj", "{886B5E9D-F2C2-4AF2-98C8-EF98C4C770E6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
All|Win32 = All|Win32
@ -3593,6 +3595,19 @@ Global
{C13CC324-0032-4492-9A30-310A6BD64FF5}.Release|x64.Build.0 = Release|x64
{C13CC324-0032-4492-9A30-310A6BD64FF5}.Release|x64 Setup.ActiveCfg = Release|Win32
{C13CC324-0032-4492-9A30-310A6BD64FF5}.Release|x86 Setup.ActiveCfg = Release|Win32
{886B5E9D-F2C2-4AF2-98C8-EF98C4C770E6}.All|Win32.ActiveCfg = Release|x64
{886B5E9D-F2C2-4AF2-98C8-EF98C4C770E6}.All|x64.ActiveCfg = Release|x64
{886B5E9D-F2C2-4AF2-98C8-EF98C4C770E6}.All|x64.Build.0 = Release|x64
{886B5E9D-F2C2-4AF2-98C8-EF98C4C770E6}.All|x64 Setup.ActiveCfg = Release|x64
{886B5E9D-F2C2-4AF2-98C8-EF98C4C770E6}.All|x86 Setup.ActiveCfg = Release|x64
{886B5E9D-F2C2-4AF2-98C8-EF98C4C770E6}.Debug|Win32.ActiveCfg = Debug|Win32
{886B5E9D-F2C2-4AF2-98C8-EF98C4C770E6}.Debug|x64.ActiveCfg = Debug|x64
{886B5E9D-F2C2-4AF2-98C8-EF98C4C770E6}.Debug|x64 Setup.ActiveCfg = Debug|x64
{886B5E9D-F2C2-4AF2-98C8-EF98C4C770E6}.Debug|x86 Setup.ActiveCfg = Debug|x64
{886B5E9D-F2C2-4AF2-98C8-EF98C4C770E6}.Release|Win32.ActiveCfg = Release|Win32
{886B5E9D-F2C2-4AF2-98C8-EF98C4C770E6}.Release|x64.ActiveCfg = Release|x64
{886B5E9D-F2C2-4AF2-98C8-EF98C4C770E6}.Release|x64 Setup.ActiveCfg = Release|x64
{886B5E9D-F2C2-4AF2-98C8-EF98C4C770E6}.Release|x86 Setup.ActiveCfg = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -3648,6 +3663,7 @@ Global
{4748FF56-CA85-4809-97D6-A94C0FAC1D77} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78}
{60C542EE-6882-4EA2-8C21-5AB6DB1BA73F} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78}
{2469B306-B027-4FF2-8815-C9C1EA2CAE79} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78}
{886B5E9D-F2C2-4AF2-98C8-EF98C4C770E6} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78}
{07113B25-D3AF-4E04-BA77-4CD1171F022C} = {C5F182F9-754A-4EC5-B50F-76ED02BE13F4}
{A27CCA23-1541-4337-81A4-F0A6413078A0} = {C5F182F9-754A-4EC5-B50F-76ED02BE13F4}
{E7BC026C-7CC5-45A3-BC7C-3B88EEF01F24} = {C5F182F9-754A-4EC5-B50F-76ED02BE13F4}

View File

@ -415,29 +415,16 @@ $(OUR_MODULES): $(switch_builddir)/modules.conf libfreeswitch.la
$(switch_builddir)/quiet_libtool: $(switch_builddir)/libtool
@cat libtool | sed -e 's|$$show "$$command"|if test -z "$$suppress_output" ; then $$show "Compiling $$srcfile ..." ; fi|' > $(switch_builddir)/quiet_libtool
src/include/switch_version.h: src/include/switch_version.h.in .version $(libfreeswitch_la_SOURCES) $(library_include_HEADERS)
@have_version=1 ; \
force=0 ; \
grep -- "@SWITCH_VERSION_REVISION@" src/include/switch_version.h.in > /dev/null || have_version=0 ; \
test ! -f src/include/switch_version.h || grep -- "@SWITCH_VERSION_REVISION@" src/include/switch_version.h > /dev/null && force=1 ; \
if test $$have_version = 1 ; then \
cat src/include/switch_version.h.in > src/include/switch_version.h ; \
touch .version ; \
else \
if [ -d .git ] ; then \
version=`git log --pretty=format:"%h %ci" -1 HEAD | head -1 | sed -e 's|:|-|g' || echo hacked` ; \
if [ "x$$version" = "xhacked" ] ; then \
version="hacked-`date -u +%Y%m%dT%H%M%SZ`" ; \
else \
version="git-$$version" ; \
fi ;\
fi ; \
oldversion=`cat .version 2>/dev/null || echo "0"` ; \
if test "$$oldversion" != "$$version" || test $$force = 1 ; then \
cat src/include/switch_version.h.in | sed "s/@SWITCH_VERSION_REVISION@/$$version/g" > src/include/switch_version.h ; \
echo $$version > .version ; \
fi ; \
fi ;
build/print_git_revision: build/print_git_revision.c
$(CC) -o $@ $<
src/include/switch_version.h: src/include/switch_version.h.in Makefile build/print_git_revision $(libfreeswitch_la_SOURCES) $(library_include_HEADERS)
@cat $< > $@; \
if [ -d .git ] && [ -n "$$(which git)" ]; then \
xver="$$(./build/print_git_revision)"; \
sed -e "/#define *SWITCH_VERSION_REVISION/{s/\"\([^\"]*\)\"/\"\1$$xver\"/;}" \
$< > $@; \
fi;
##
## Dependency targets
@ -544,7 +531,6 @@ is-scm:
update: is-scm
@if test -d .git ; then \
test ! -f .version || rm -f .version ; \
echo "Pulling updates..." ; \
git pull ; \
else \

View File

@ -58,12 +58,12 @@ codecs/mod_bv
codecs/mod_g723_1
codecs/mod_g729
codecs/mod_h26x
codecs/mod_ilbc
#codecs/mod_ilbc
#codecs/mod_isac
#codecs/mod_opus
#codecs/mod_sangoma_codec
#codecs/mod_silk
codecs/mod_siren
#codecs/mod_siren
codecs/mod_speex
dialplans/mod_dialplan_asterisk
#dialplans/mod_dialplan_directory

View File

@ -0,0 +1,63 @@
/* -*- mode:c; indent-tabs-mode:nil; c-basic-offset:2 -*-
* Author: Travis Cross <tc@traviscross.com>
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <time.h>
static int sys(char *buf, int buflen, char *cmd) {
int i, p[2];
if (pipe(p)) return 255;
if (!(i=fork())) {
close(p[0]);
dup2(p[1],1);
close(p[1]);
execlp("sh","sh","-c",cmd,NULL);
} else {
int s, x=0;
close(p[1]);
waitpid(i,&s,0);
if (!(WIFEXITED(s))) return 255;
if (WEXITSTATUS(s)) return WEXITSTATUS(s);
if (buf) {
while (buflen>1 && (x=read(p[0],buf,buflen-1))>0) buf+=x,buflen-=x;
close(p[0]);
if (x<0) return 255;
*buf=0;
} else close(p[0]);
}
return 0;
}
static int sys1(char *buf, int buflen, char *cmd) {
int r; char *c;
if ((r=sys(buf,buflen,cmd))) return r;
if ((c=strstr(buf,"\n"))) *c=0;
return 0;
}
int main(int argc, char **argv) {
char xver[256], xdate[256], xfdate[256], xcommit[256];
time_t xdate_t; struct tm *xdate_tm;
if ((sys1(xdate,sizeof(xdate),"git log -n1 --format='%ct' HEAD"))) return 1;
xdate_t=(time_t)atoi(xdate);
if (!(xdate_tm=gmtime(&xdate_t))) return 1;
strftime(xfdate,sizeof(xfdate),"%Y%m%dT%H%M%SZ",xdate_tm);
if ((sys1(xcommit,sizeof(xcommit),"git rev-list -n1 --abbrev=10 --abbrev-commit HEAD")))
return 1;
snprintf(xver,sizeof(xver),"+git~%s~%s",xfdate,xcommit);
if ((sys(NULL,0,"git diff-index --quiet HEAD"))) {
char buf[256], now[256]; time_t now_t=time(NULL); struct tm *now_tm;
if (!(now_tm=gmtime(&now_t))) return 1;
strftime(now,sizeof(now),"%Y%m%dT%H%M%SZ",now_tm);
snprintf(buf,sizeof(buf),"%s+unclean~%s",xver,now);
strncpy(xver,buf,sizeof(xver));
}
printf("%s\n",xver);
return 0;
}

View File

@ -48,7 +48,7 @@
<param name="auth-calls" value="false"/>
<param name="rtp-timeout-sec" value="1800"/>
<param name="inbound-late-negotiation" value="true"/>
<param name="inbound-zrtp-passthru" value="true"/>
<param name="inbound-zrtp-passthru" value="true"/> <!-- (also enables late negotiation) -->
<!--
DO NOT USE HOSTNAMES, ONLY IP ADDRESSES IN THESE SETTINGS!
-->

View File

@ -69,7 +69,7 @@
<!-- Let calls hit the dialplan before selecting codec for the a-leg -->
<param name="inbound-late-negotiation" value="true"/>
<!-- Allow ZRTP clients to negotiate end-to-end security associations -->
<!-- Allow ZRTP clients to negotiate end-to-end security associations (also enables late negotiation) -->
<param name="inbound-zrtp-passthru" value="true"/>
<!-- this lets anything register -->

View File

@ -104,7 +104,7 @@
<!-- Let calls hit the dialplan before selecting codec for the a-leg -->
<param name="inbound-late-negotiation" value="true"/>
<!-- Allow ZRTP clients to negotiate end-to-end security associations -->
<!-- Allow ZRTP clients to negotiate end-to-end security associations (also enables late negotiation) -->
<param name="inbound-zrtp-passthru" value="true"/>
<!-- this lets anything register -->

View File

@ -49,7 +49,7 @@
<param name="auth-calls" value="false"/>
<param name="rtp-timeout-sec" value="1800"/>
<param name="inbound-late-negotiation" value="true"/>
<param name="inbound-zrtp-passthru" value="true"/>
<param name="inbound-zrtp-passthru" value="true"/> <!-- (also enables late negotiation) -->
<!--
DO NOT USE HOSTNAMES, ONLY IP ADDRESSES IN THESE SETTINGS!
-->

View File

@ -69,7 +69,7 @@
<!-- Let calls hit the dialplan before selecting codec for the a-leg -->
<param name="inbound-late-negotiation" value="true"/>
<!-- Allow ZRTP clients to negotiate end-to-end security associations -->
<!-- Allow ZRTP clients to negotiate end-to-end security associations (also enables late negotiation) -->
<param name="inbound-zrtp-passthru" value="true"/>
<!-- this lets anything register -->

View File

@ -110,7 +110,7 @@
<!-- Let calls hit the dialplan before selecting codec for the a-leg -->
<param name="inbound-late-negotiation" value="true"/>
<!-- Allow ZRTP clients to negotiate end-to-end security associations -->
<!-- Allow ZRTP clients to negotiate end-to-end security associations (also enables late negotiation) -->
<param name="inbound-zrtp-passthru" value="true"/>
<!-- this lets anything register -->

View File

@ -57,7 +57,7 @@
<param name="nonce-ttl" value="60"/>
<param name="auth-calls" value="false"/>
<param name="inbound-late-negotiation" value="true"/>
<param name="inbound-zrtp-passthru" value="true"/>
<param name="inbound-zrtp-passthru" value="true"/> <!-- (also enables late negotiation) -->
<!--
DO NOT USE HOSTNAMES, ONLY IP ADDRESSES IN THESE SETTINGS!
-->

View File

@ -70,7 +70,7 @@
<!-- Let calls hit the dialplan before selecting codec for the a-leg -->
<param name="inbound-late-negotiation" value="true"/>
<!-- Allow ZRTP clients to negotiate end-to-end security associations -->
<!-- Allow ZRTP clients to negotiate end-to-end security associations (also enables late negotiation) -->
<param name="inbound-zrtp-passthru" value="true"/>
<!-- this lets anything register -->

View File

@ -222,7 +222,7 @@
<!-- Let calls hit the dialplan before selecting codec for the a-leg -->
<param name="inbound-late-negotiation" value="true"/>
<!-- Allow ZRTP clients to negotiate end-to-end security associations -->
<!-- Allow ZRTP clients to negotiate end-to-end security associations (also enables late negotiation) -->
<param name="inbound-zrtp-passthru" value="true"/>
<!-- this lets anything register -->

View File

@ -10,7 +10,6 @@ AC_SUBST(SWITCH_VERSION_MICRO, [0])
AC_SUBST(SWITCH_VERSION_REVISION, [-rc2])
AC_CONFIG_FILES([src/include/switch_version.h.in:src/include/switch_version.h.template])
AC_CONFIG_FILES([.version:.version.in])
AC_CONFIG_AUX_DIR(build/config)
AM_INIT_AUTOMAKE(libfreeswitch,0.1)
@ -925,7 +924,7 @@ then
#
# python distutils found, get settings from python directly
#
PYTHON_CFLAGS="`$PYTHON -c 'from distutils import sysconfig; flags = [[\"-I\" + sysconfig.get_python_inc(0), \"-I\" + sysconfig.get_python_inc(1), \" \".join(sysconfig.get_config_var(\"CFLAGS\").split())]]; print(\" \".join(flags));'`"
PYTHON_CFLAGS="`$PYTHON -c 'from distutils import sysconfig; flags = [[\"-I\" + sysconfig.get_python_inc(0), \"-I\" + sysconfig.get_python_inc(1), \" \".join(sysconfig.get_config_var(\"CFLAGS\").split())]]; print(\" \".join(flags));' | sed -e 's/-arch i386//g;s/-arch x86_64//g'`"
PYTHON_LDFLAGS="`$PYTHON -c 'from distutils import sysconfig; libs = sysconfig.get_config_var(\"LIBS\").split() + sysconfig.get_config_var(\"SYSLIBS\").split(); libs.append(\"-lpython\"+sysconfig.get_config_var(\"VERSION\")); print(\" \".join(libs));'`"
PYTHON_LIB="`$PYTHON -c 'from distutils import sysconfig; print(\"python\" + sysconfig.get_config_var(\"VERSION\"));'`"
PYTHON_LIBDIR="`$PYTHON -c 'from distutils import sysconfig; print(sysconfig.get_config_var(\"LIBDIR\"));'`"
@ -993,7 +992,6 @@ AC_CONFIG_FILES([Makefile
src/Makefile
src/mod/Makefile
src/mod/applications/mod_expr/Makefile
src/mod/applications/mod_fax/Makefile
src/mod/applications/mod_spandsp/Makefile
src/mod/applications/mod_osp/Makefile
src/mod/applications/mod_stress/Makefile

1
debian/bootstrap.sh vendored
View File

@ -31,6 +31,7 @@ avoid_mods=(
endpoints/mod_reference
endpoints/mod_unicall
formats/mod_shout
languages/mod_managed
languages/mod_spidermonkey
sdk/autotools
xml_int/mod_xml_ldap

76
debian/util.sh vendored
View File

@ -234,9 +234,11 @@ EOF
build_debs () {
{
set -e
local OPTIND OPTARG debug_hook=false hookdir=""
while getopts 'd' o "$@"; do
local OPTIND OPTARG debug_hook=false hookdir="" cow_build_opts=""
while getopts 'Bbd' o "$@"; do
case "$o" in
B) cow_build_opts="--debbuildopts '-B'";;
b) cow_build_opts="--debbuildopts '-b'";;
d) debug_hook=true;;
esac
done
@ -274,9 +276,10 @@ build_debs () {
fi
cow --build $dsc \
--hookdir "$hookdir" \
--buildresult ../
--buildresult ../ \
$cow_build_opts
} 1>&2
echo ${dsc}_${arch}.changes
echo ${dsc%.dsc}_${arch}.changes
}
build_all () {
@ -304,38 +307,96 @@ build_all () {
mkdir -p ../log
> ../log/changes
echo; echo; echo; echo
trap 'echo "Killing children...">&2; for x in $(jobs -p); do kill $x; done' EXIT
if [ "${orig:0:2}" = ".." ]; then
for distro in $distros; do
echo "Creating $distro dsc..." >&2
local dsc="$(create_dsc $dsc_opts $distro $orig 2>../log/$distro | tail -n1)"
echo "Done creating $distro dsc." >&2
if [ "${dsc:0:2}" = ".." ]; then
local lopts="-b"
for arch in $archs; do
{
echo "Building $distro-$arch debs..." >&2
local changes="$(build_debs $deb_opts $distro $dsc $arch 2>../log/$distro-$arch | tail -n1)"
local changes="$(build_debs $lopts $deb_opts $distro $dsc $arch 2>../log/$distro-$arch | tail -n1)"
echo "Done building $distro-$arch debs." >&2
if [ "${changes:0:2}" = ".." ]; then
echo "$changes" >> ../log/changes
fi
} &
$par || wait
lopts="-B"
done
fi
done
! $par || wait
fi
trap - EXIT
cat ../log/changes
}
while getopts 'd' o "$@"; do
usage () {
cat >&2 <<EOF
$0 [opts] [cmd] [cmd-opts]
options:
-d Enable debugging mode.
commands:
archive-orig
build-all
-a Specify architectures
-b Bundle downloaded libraries in source package
-c Specify distributions
-d Enable cowbuilder debug hook
-j Build debs in parallel
-n Nightly build
-m [ quicktest ]
Choose custom list of modules to build
-s [ paranoid | reckless ]
Set FS bootstrap/build -j flags
-v Set version
-z Set compression level
build-debs <distro> <dsc-file> <architecture>
-B Binary architecture-dependent build
-b Binary-only build
-d Enable cowbuilder debug hook
create-dbg-pkgs
create-dsc <distro> <orig-file>
-m [ quicktest ]
Choose custom list of modules to build
-s [ paranoid | reckless ]
Set FS bootstrap/build -j flags
create-orig <treeish>
-b Bundle downloaded libraries in source package
-n Nightly build
-v Set version
-z Set compression level
EOF
exit 1
}
while getopts 'dh' o "$@"; do
case "$o" in
d) set -vx;;
h) usage;;
esac
done
shift $(($OPTIND-1))
cmd="$1"
cmd="$1"; [ -n "$cmd" ] || usage
shift
case "$cmd" in
archive-orig) archive_orig "$@" ;;
@ -344,5 +405,6 @@ case "$cmd" in
create-dbg-pkgs) create_dbg_pkgs ;;
create-dsc) create_dsc "$@" ;;
create-orig) create_orig "$@" ;;
*) usage ;;
esac

1
libs/.gitignore vendored
View File

@ -225,6 +225,7 @@ missing
/ldns/doc/ldns_manpages
/ldns/include/
/ldns/ldns/config.h
/ldns/ldns/ldns
/ldns/ldns/net.h
/ldns/ldns/util.h
/ldns/lib

View File

@ -527,7 +527,12 @@ typedef struct zrtp_stream_mescache_t
zrtp_retry_task_t errorack_task;
zrtp_retry_task_t sasrelay_task;
zrtp_string16_t signaling_hash;
/*!
* Hash pre-image of the remote party Hello retrieved from Signaling. When
* user calls zrtp_signaling_hash_set() libzrtp stores hash value in this
* variable and checks all incoming Hello-s to prevent DOS attacks.
*/
zrtp_string64_t signaling_hash;
} zrtp_stream_mescache_t;
@ -722,14 +727,7 @@ struct zrtp_stream_t
* crypto sources and performs traffic encryption/decryption.
*/
zrtp_protocol_t *protocol;
/*!
* Hash pre-image of the remote party Hello retrieved from Signaling. When
* user calls zrtp_signaling_hash_set() libzrtp stores hash value in this
* variable and checks all incoming Hellos to prevent DOS attacks.
*/
zrtp_string128_t signaling_hash;
/*!< Holder for RTP/ZRTP media stream options. */
zrtp_media_context_t media_ctx;

View File

@ -12,8 +12,8 @@
#define LIBZRTP_VERSION_MAJOR 1
#define LIBZRTP_VERSION_MINOR 13
#define LIBZRTP_VERSION_BUILD 604
#define LIBZRTP_VERSION_STR "v1.13 604"
#define LIBZRTP_VERSION_MINOR 15
#define LIBZRTP_VERSION_BUILD 607
#define LIBZRTP_VERSION_STR "v1.15 607"
#endif /*__ZRTP_VERSION_H__*/

View File

@ -32,7 +32,7 @@ case $target_os in
esac
AM_INIT_AUTOMAKE([libzrtp], [1.14])
AM_INIT_AUTOMAKE([libzrtp], [1.15])
AX_PREFIX_CONFIG_H(../../include/zrtp_config_unix.h,ZRTP,config/config.h)
CFLAGS="$CFLAGS -Wno-unused-parameter -fno-strict-aliasing -fPIC -DZRTP_AUTOMAKE=1"

View File

@ -418,8 +418,6 @@ zrtp_status_t zrtp_stream_attach(zrtp_session_t *session, zrtp_stream_t** stream
return zrtp_status_alloc_fail;
}
ZSTR_SET_EMPTY(new_stream->signaling_hash);
/*
* Initialize the private data stream with default initial values
*/
@ -437,6 +435,8 @@ zrtp_status_t zrtp_stream_attach(zrtp_session_t *session, zrtp_stream_t** stream
ZSTR_SET_EMPTY(new_stream->cc.zrtp_key);
ZSTR_SET_EMPTY(new_stream->cc.peer_zrtp_key);
ZSTR_SET_EMPTY(new_stream->messages.signaling_hash);
new_stream->dh_cc.initialized_with = ZRTP_COMP_UNKN;
bnBegin(&new_stream->dh_cc.peer_pv);
ZSTR_SET_EMPTY(new_stream->dh_cc.dhss);
@ -638,8 +638,8 @@ zrtp_status_t zrtp_signaling_hash_set( zrtp_stream_t* ctx,
ctx->messages.signaling_hash.length = ZRTP_MESSAGE_HASH_SIZE;
{
char buff[66];
ZRTP_LOG(3, (_ZTU_,"SIGNALLING HAS was ADDED for the comparing. ID=%u\n", ctx->id));
char buff[64];
ZRTP_LOG(3, (_ZTU_,"SIGNALLING HAS was ADDED for the comparision. ID=%u\n", ctx->id));
ZRTP_LOG(3, (_ZTU_,"Hash=%s.\n", hex2str(hash_buff, hash_buff_length, buff, sizeof(buff))));
}

View File

@ -128,13 +128,15 @@ zrtp_status_t _zrtp_machine_process_sasrelay(zrtp_stream_t *stream, zrtp_rtp_inf
zrtp_status_t s = zrtp_status_fail;
zrtp_string128_t hmac = ZSTR_INIT_EMPTY(hmac);
char zerosashash[32];
unsigned sas_scheme_did_change = 0;
unsigned sas_hash_did_change = 0;
/* (padding + sig_len + flags) + SAS scheme and SAS hash */
const uint8_t encrypted_body_size = (2 + 1 + 1) + 4 + 32;
zrtp_memset(zerosashash, 0, sizeof(zerosashash));
/* Check if the remote endpoint is assiggneed to relay the SAS values */
/* Check if the remote endpoint is assigned to relay the SAS values */
if (!stream->peer_mitm_flag) {
ZRTP_LOG(2,(_ZTU_, ZRTP_RELAYED_SAS_FROM_NONMITM_STR));
return zrtp_status_fail;
@ -157,7 +159,7 @@ zrtp_status_t _zrtp_machine_process_sasrelay(zrtp_stream_t *stream, zrtp_rtp_inf
return zrtp_status_fail;
}
ZRTP_LOG(3,(_ZTU_, "\tHMAC value for the SASRELAY is correct - decryptiong...\n"));
ZRTP_LOG(3,(_ZTU_, "\tHMAC value for the SASRELAY is correct - decrypting...\n"));
/* Then we need to decrypt Confirm body */
do
@ -217,9 +219,14 @@ zrtp_status_t _zrtp_machine_process_sasrelay(zrtp_stream_t *stream, zrtp_rtp_inf
_zrtp_machine_enter_initiatingerror(stream, zrtp_error_invalid_packet, 1);
return zrtp_status_fail;
}
session->sasscheme = zrtp_comp_find(ZRTP_CC_SAS, rendering_id, session->zrtp );
ZRTP_LOG(3,(_ZTU_,"\tSasrelay: New Rendering scheme %.4s.\n", session->sasscheme->base.type));
/* Check is SAS rendering did change */
if (rendering_id != session->sasscheme->base.id) {
session->sasscheme = zrtp_comp_find(ZRTP_CC_SAS, rendering_id, session->zrtp );
sas_scheme_did_change = 1;
ZRTP_LOG(3,(_ZTU_,"\tSasrelay: Rendering scheme was updated to %.4s.\n", session->sasscheme->base.type));
}
if (session->secrets.matches & ZRTP_BIT_PBX) {
if ( ( ((uint32_t) *sasrelay->sas_scheme) != (uint32_t)0x0L ) &&
@ -231,7 +238,8 @@ zrtp_status_t _zrtp_machine_process_sasrelay(zrtp_stream_t *stream, zrtp_rtp_inf
zrtp_memcpy(session->sasbin.buffer, sasrelay->sashash, session->sasbin.length);
stream->mitm_mode = ZRTP_MITM_MODE_RECONFIRM_CLIENT;
ZRTP_LOG(3,(_ZTU_,"\tSasRelay: SAS value was updated bin=%s.\n",
sas_hash_did_change = 1;
ZRTP_LOG(3,(_ZTU_,"\tSasRelay: SAS value was updated to bin=%s.\n",
hex2str(buff, sizeof(buff), session->sasbin.buffer, session->sasbin.length)));
}
} else if (0 != zrtp_memcmp(sasrelay->sashash, zerosashash, sizeof(sasrelay->sashash))) {
@ -242,16 +250,24 @@ zrtp_status_t _zrtp_machine_process_sasrelay(zrtp_stream_t *stream, zrtp_rtp_inf
ZRTP_LOG(1,(_ZTU_, "\rERROR! For SasRelay Other secret doesn't match. ID=%u\n", stream->id));
}
s = session->sasscheme->compute(session->sasscheme, stream, session->hash, 1);
if (zrtp_status_ok != s) {
_zrtp_machine_enter_initiatingerror(stream, zrtp_error_software, 1);
return s;
}
ZRTP_LOG(3,(_ZTU_,"\tSasRelay: Updated SAS is <%s> <%s>.\n", session->sas1.buffer, session->sas2.buffer));
/* Generate new SAS if hash or rendering scheme did change.
* Note: latest libzrtp may send "empty" SasRelay with the same SAS rendering
* scheme and empty Hello hash for consistency reasons, we should ignore
* such packets.
*/
if (sas_scheme_did_change || sas_hash_did_change) {
s = session->sasscheme->compute(session->sasscheme, stream, session->hash, 1);
if (zrtp_status_ok != s) {
_zrtp_machine_enter_initiatingerror(stream, zrtp_error_software, 1);
return s;
}
if (session->zrtp->cb.event_cb.on_zrtp_protocol_event) {
session->zrtp->cb.event_cb.on_zrtp_protocol_event(stream, ZRTP_EVENT_LOCAL_SAS_UPDATED);
ZRTP_LOG(3,(_ZTU_,"\tSasRelay: Updated SAS is <%s> <%s>.\n", session->sas1.buffer, session->sas2.buffer));
if (session->zrtp->cb.event_cb.on_zrtp_protocol_event) {
session->zrtp->cb.event_cb.on_zrtp_protocol_event(stream, ZRTP_EVENT_LOCAL_SAS_UPDATED);
}
}
return zrtp_status_ok;
@ -492,7 +508,7 @@ zrtp_status_t zrtp_update_remote_options( zrtp_stream_t* stream,
return zrtp_status_bad_param;
}
/* Don't allow to transfer the SAS if the library wasn't initalized as MiTM endpoint */
/* Don't allow to transfer the SAS if the library wasn't initialized as MiTM endpoint */
if (!stream->zrtp->is_mitm) {
ZRTP_LOG(3,(_ZTU_,"\tERROR! The endpoint can't transfer SAS values to other endpoints"
" without introducing itself by M-flag in Hello. see zrtp_init().\n"));

View File

@ -488,7 +488,7 @@ zrtp_status_t _zrtp_packet_preparse( zrtp_stream_t* stream,
(const char*) info->message,
zrtp_ntoh16(((zrtp_packet_Hello_t*) info->message)->hdr.length)*4,
ZSTR_GV(hash_str) );
if (!zrtp_memcmp(stream->messages.signaling_hash.buffer, hash_str.buffer, ZRTP_MESSAGE_HASH_SIZE)) {
if (zrtp_memcmp(stream->messages.signaling_hash.buffer, hash_str.buffer, ZRTP_MESSAGE_HASH_SIZE)) {
if (stream->zrtp->cb.event_cb.on_zrtp_security_event) {
stream->zrtp->cb.event_cb.on_zrtp_security_event(stream, ZRTP_EVENT_WRONG_SIGNALING_HASH);
}

View File

@ -1 +1 @@
Thu May 3 16:30:20 CDT 2012
Sat Jun 9 03:24:47 UTC 2012

View File

@ -198,6 +198,12 @@ enum tport_tls_verify_policy {
TPTLS_VERIFY_SUBJECTS_ALL = 0xF,
};
TPORT_DLL extern tag_typedef_t tptag_tls_timeout;
#define TPTAG_TLS_TIMEOUT(x) tptag_tls_timeout, tag_uint_v((x))
TPORT_DLL extern tag_typedef_t tptag_tls_timeout_ref;
#define TPTAG_TLS_TIMEOUT_REF(x) tptag_tls_timeout_ref, tag_uint_vr(&(x))
TPORT_DLL extern tag_typedef_t tptag_tls_passphrase;
#define TPTAG_TLS_PASSPHRASE(x) tptag_tls_passphrase, tag_str_v(x)

View File

@ -280,6 +280,19 @@ tag_typedef_t tptag_compartment = PTRTAG_TYPEDEF(compartment);
*/
tag_typedef_t tptag_tls_version = UINTTAG_TYPEDEF(tls_version);
/**@def TPTAG_TLS_TIMEOUT(x)
*
* Sets the maximum TLS session lifetime in seconds.
*
* The default value is 300 seconds.
*
* Use with tport_tbind(), nua_create(), nta_agent_create(),
* nta_agent_add_tport(), nth_engine_create(), or initial nth_site_create().
*
* @NEW_UNRELEASED.
*/
tag_typedef_t tptag_tls_timeout = UINTTAG_TYPEDEF(tls_timeout);
/**@def TPTAG_TLS_VERIFY_PEER(x)
* @par Depreciated:
* Alias for TPTAG_TLS_VERIFY_POLICY(TPTLS_VERIFY_IN|TPTLS_VERIFY_OUT)

View File

@ -311,6 +311,8 @@ int tls_init_context(tls_t *tls, tls_issues_t const *ti)
return -1;
}
SSL_CTX_set_timeout(tls->ctx, ti->timeout);
/* Set callback if we have a passphrase */
if (ti->passphrase != NULL) {
SSL_CTX_set_default_passwd_cb(tls->ctx, passwd_cb);

View File

@ -65,6 +65,7 @@ typedef struct tls_issues_s {
*/
int version; /* For tls1, version is 1. When ssl3/ssl2 is
* used, it is 0. */
unsigned timeout; /* Maximum session lifetime in seconds */
} tls_issues_t;
typedef struct tport_tls_s {

View File

@ -181,6 +181,7 @@ static int tport_tls_init_master(tport_primary_t *pri,
char *tbf = NULL;
char const *path = NULL;
unsigned tls_version = 1;
unsigned tls_timeout = 300;
unsigned tls_verify = 0;
char const *passphrase = NULL;
unsigned tls_policy = TPTLS_VERIFY_NONE;
@ -198,6 +199,7 @@ static int tport_tls_init_master(tport_primary_t *pri,
tl_gets(tags,
TPTAG_CERTIFICATE_REF(path),
TPTAG_TLS_VERSION_REF(tls_version),
TPTAG_TLS_TIMEOUT_REF(tls_timeout),
TPTAG_TLS_VERIFY_PEER_REF(tls_verify),
TPTAG_TLS_PASSPHRASE_REF(passphrase),
TPTAG_TLS_VERIFY_POLICY_REF(tls_policy),
@ -224,6 +226,7 @@ static int tport_tls_init_master(tport_primary_t *pri,
ti.cert = ti.key;
ti.CAfile = su_sprintf(autohome, "%s/%s", path, "cafile.pem");
ti.version = tls_version;
ti.timeout = tls_timeout;
ti.CApath = su_strdup(autohome, path);
SU_DEBUG_9(("%s(%p): tls key = %s\n", __func__, (void *)pri, ti.key));

View File

@ -271,36 +271,38 @@ Sub CreateVersion(tmpFolder, VersionDir, includebase, includedest)
strVerRev = FindVersionStringInConfigure(VersionDir & "configure.in", "SWITCH_VERSION_REVISION")
'Set version to the one reported by configure.in
if strVerRev <> "" Then
If strVerRev <> "" Then
VERSION = strVerRev
End If
Dim sLastFile
Const ForReading = 1
'Try To read revision from git, if it's found, use this instead of strVerRev found above
If FSO.FolderExists(VersionDir & ".git") Then
VersionCmd="git log --format=" & quote & "%%h %%ci" & quote & " -1 HEAD"
Set MyFile = FSO.CreateTextFile(tmpFolder & "tmpVersion.Bat", True)
MyFile.WriteLine("@" & "cd " & quote & VersionDir & quote)
MyFile.WriteLine("@" & VersionCmd)
MyFile.Close
Set oExec = WshShell.Exec("cmd /C " & quote & tmpFolder & "tmpVersion.Bat" & quote)
Do
strFromProc = Trim(OExec.StdOut.ReadLine())
VERSION="git-" & strFromProc
Loop While Not OExec.StdOut.atEndOfStream
sLastVersion = ""
Set sLastFile = FSO.OpenTextFile(tmpFolder & "lastversion", ForReading, true, OpenAsASCII)
If Not sLastFile.atEndOfStream Then
sLastVersion = sLastFile.ReadLine()
'Try To read revision from git, if it was not found in "configure.in" already
If strVerRev = "" Then
If FSO.FolderExists(VersionDir & ".git") Then
VersionCmd="git log --format=" & quote & "%%h %%ci" & quote & " -1 HEAD"
Set MyFile = FSO.CreateTextFile(tmpFolder & "tmpVersion.Bat", True)
MyFile.WriteLine("@" & "cd " & quote & VersionDir & quote)
MyFile.WriteLine("@" & VersionCmd)
MyFile.Close
Set oExec = WshShell.Exec("cmd /C " & quote & tmpFolder & "tmpVersion.Bat" & quote)
Do
strFromProc = Trim(OExec.StdOut.ReadLine())
VERSION="git-" & strFromProc
Loop While Not OExec.StdOut.atEndOfStream
sLastVersion = ""
Set sLastFile = FSO.OpenTextFile(tmpFolder & "lastversion", ForReading, true, OpenAsASCII)
If Not sLastFile.atEndOfStream Then
sLastVersion = sLastFile.ReadLine()
End If
sLastFile.Close
VERSION = Replace(VERSION, ":", "-")
End If
sLastFile.Close
VERSION = Replace(VERSION, ":", "-")
End If
If VERSION = "" Then
VERSION = "UNKNOWN"
VERSION = "-UNKNOWN"
End If
If VERSION <> sLastVersion Then

View File

@ -28,6 +28,7 @@ mkdir -p $ddir
git clone . $bdir
cd $bdir
set_fs_ver "$gver" "$gmajor" "$gminor" "$gmicro" "$grev"
echo "$gver" > .version
cd libs
getlib () {
f="${1##*/}"

View File

@ -22,6 +22,7 @@ cp -r . $dst_dir
cd $dst_dir
set_fs_ver "$gver" "$gmajor" "$gminor" "$gmicro" "$grev"
echo "$gver" > .version
gnuize
cd ..
ls

63
scripts/perl/cnam.cgi Executable file
View File

@ -0,0 +1,63 @@
#!/usr/bin/perl
#
# OpenCNAM front end because they only take 10 digits and can't filter 11 on their side.
#
use Data::Dumper;
use CGI qw/:standard/;
use LWP::UserAgent;
use SDBM_File;
use Fcntl;
my %params = map { $_ => get_data( $_ ) } param;
$ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 0 });
sub get_data {
my $name = shift;
my @values = param( $name );
return @values > 1
? \@values
: $values[0];
}
print "Content-Type: text/plain\n\n";
tie (my %cache, 'SDBM_File', 'cnam.dbm', O_RDWR|O_CREAT, 0640) || die $!;
my $number = $params{number};
if($number =~ m/1?\d{10}/) {
if($number =~ m/^1(\d{10})$/) {
$number = $1;
}
if($cache{"$number"}) {
print $cache{"$number"};
untie %cache;
exit;
}
my $url = "https://api.opencnam.com/v1/phone/$number?format=text";
my $res = $ua->get( $url );
if ($res->is_success) {
my $content = $res->decoded_content;
if ($content =~ m/^Invalid/) {
# API shouldn't return this crap.
print "UNKNOWN";
} else {
# Cache the entry.
$cache{"$number"} = $content;
# print the entry.
print $content;
}
}
}
untie %cache;

View File

@ -2300,10 +2300,12 @@ SWITCH_DECLARE(uint32_t) switch_default_ptime(const char *name, uint32_t number)
\param [in] network_ip
\param [in] network_port
\param [in] network_proto - one of tls, tcp, udp
\param [in] metadata - generic metadata supplied by module
\param [out] err - Error if it exists
*/
SWITCH_DECLARE(switch_status_t) switch_core_add_registration(const char *user, const char *realm, const char *token, const char *url, uint32_t expires,
const char *network_ip, const char *network_port, const char *network_proto);
const char *network_ip, const char *network_port, const char *network_proto,
const char *metadata);
/*!
\brief Delete user registration
\param [in] user

View File

@ -186,7 +186,7 @@ SWITCH_DECLARE(bool) email(char *to, char *from, char *headers = NULL, char *bod
switch_event_node_t *enodes[SWITCH_EVENT_ALL + 1];
uint32_t node_index;
SWITCH_DECLARE_CONSTRUCTOR EventConsumer(const char *event_name = NULL, const char *subclass_name = "");
SWITCH_DECLARE_CONSTRUCTOR EventConsumer(const char *event_name = NULL, const char *subclass_name = "", int len = 5000);
SWITCH_DECLARE_CONSTRUCTOR ~ EventConsumer();
SWITCH_DECLARE(int) bind(const char *event_name, const char *subclass_name = "");
SWITCH_DECLARE(Event *) pop(int block = 0, int timeout = 0);

View File

@ -41,7 +41,7 @@ extern "C" {
#define SWITCH_VERSION_MINOR "@freeswitch_MINOR_VERSION@"
#define SWITCH_VERSION_MICRO "@freeswitch_PATCH_LEVEL@"
#define SWITCH_VERSION_REVISION "@Project_WC_REVISION@"
#define SWITCH_VERSION_FULL SWITCH_VERSION_MAJOR "." SWITCH_VERSION_MINOR "." SWITCH_VERSION_MICRO " (" SWITCH_VERSION_REVISION ")"
#define SWITCH_VERSION_FULL SWITCH_VERSION_MAJOR "." SWITCH_VERSION_MINOR "." SWITCH_VERSION_MICRO SWITCH_VERSION_REVISION
#ifdef __cplusplus
}

View File

@ -41,7 +41,7 @@ extern "C" {
#define SWITCH_VERSION_MINOR "@SWITCH_VERSION_MINOR@"
#define SWITCH_VERSION_MICRO "@SWITCH_VERSION_MICRO@"
#define SWITCH_VERSION_REVISION "@SWITCH_VERSION_REVISION@"
#define SWITCH_VERSION_FULL SWITCH_VERSION_MAJOR "." SWITCH_VERSION_MINOR "." SWITCH_VERSION_MICRO " (" SWITCH_VERSION_REVISION ")"
#define SWITCH_VERSION_FULL SWITCH_VERSION_MAJOR "." SWITCH_VERSION_MINOR "." SWITCH_VERSION_MICRO SWITCH_VERSION_REVISION
#ifdef __cplusplus
}

View File

@ -48,9 +48,23 @@ typedef struct conference_cdr_node_s {
char *record_path;
switch_time_t join_time;
switch_time_t leave_time;
uint32_t flags;
struct conference_cdr_node_s *next;
} conference_cdr_node_t;
typedef enum {
CDRR_LOCKED = 1,
CDRR_PIN,
CDRR_MAXMEMBERS
} cdr_reject_reason_t;
typedef struct conference_cdr_reject_s {
switch_caller_profile_t *cp;
switch_time_t reject_time;
cdr_reject_reason_t reason;
struct conference_cdr_reject_s *next;
} conference_cdr_reject_t;
typedef enum {
@ -175,7 +189,8 @@ typedef enum {
CFLAG_EXIT_SOUND = (1 << 12),
CFLAG_ENTER_SOUND = (1 << 13),
CFLAG_VIDEO_BRIDGE = (1 << 14),
CFLAG_AUDIO_ALWAYS = (1 << 15)
CFLAG_AUDIO_ALWAYS = (1 << 15),
CFLAG_ENDCONF_FORCED = (1 << 16)
} conf_flag_t;
typedef enum {
@ -332,6 +347,7 @@ typedef struct conference_obj {
uint32_t originating;
switch_call_cause_t cancel_cause;
conference_cdr_node_t *cdr_nodes;
conference_cdr_reject_t *cdr_rejected;
switch_time_t start_time;
switch_time_t end_time;
char *log_dir;
@ -505,6 +521,7 @@ static switch_status_t conference_add_event_member_data(conference_member_t *mem
static void conference_cdr_del(conference_member_t *member)
{
member->cdr_node->leave_time = switch_epoch_time_now(NULL);
member->cdr_node->flags = member->flags;
}
static void conference_cdr_add(conference_member_t *member)
@ -533,10 +550,30 @@ static void conference_cdr_add(conference_member_t *member)
member->cdr_node->cp = switch_caller_profile_dup(member->conference->pool, cp);
}
static void conference_cdr_rejected(conference_obj_t *conference, switch_channel_t *channel, cdr_reject_reason_t reason)
{
conference_cdr_reject_t *rp;
switch_caller_profile_t *cp;
rp = switch_core_alloc(conference->pool, sizeof(*rp));
rp->next = conference->cdr_rejected;
conference->cdr_rejected = rp;
rp->reason = reason;
rp->reject_time = switch_epoch_time_now(NULL);
if (!(cp = switch_channel_get_caller_profile(channel))) {
return;
}
rp->cp = switch_caller_profile_dup(conference->pool, cp);
}
static void conference_cdr_render(conference_obj_t *conference)
{
switch_xml_t cdr, x_ptr, x_member, x_members, x_conference, x_cp;
switch_xml_t cdr, x_ptr, x_member, x_members, x_conference, x_cp, x_flags, x_tag, x_rejected, x_attempt;
conference_cdr_node_t *np;
conference_cdr_reject_t *rp;
int cdr_off = 0, conf_off = 0;
char str[512];
char *path, *xml_text;
@ -544,7 +581,7 @@ static void conference_cdr_render(conference_obj_t *conference)
if (zstr(conference->log_dir)) return;
if (!conference->cdr_nodes) return;
if (!conference->cdr_nodes && !conference->cdr_rejected) return;
if (!(cdr = switch_xml_new("cdr"))) {
abort();
@ -583,18 +620,20 @@ static void conference_cdr_render(conference_obj_t *conference)
if (!(x_ptr = switch_xml_add_child_d(x_conference, "end_time", conf_off++))) {
abort();
}
switch_xml_set_attr_d(x_ptr, "endconf_forced", switch_test_flag(conference, CFLAG_ENDCONF_FORCED) ? "true" : "false");
switch_xml_set_attr_d(x_ptr, "type", "UNIX-epoch");
switch_snprintf(str, sizeof(str), "%ld", (long)conference->end_time);
switch_xml_set_txt_d(x_ptr, str);
if (!(x_members = switch_xml_add_child_d(x_conference, "members", conf_off++))) {
abort();
}
for (np = conference->cdr_nodes; np; np = np->next) {
int member_off = 0;
int flag_off = 0;
if (!(x_member = switch_xml_add_child_d(x_members, "member", conf_off++))) {
@ -619,6 +658,18 @@ static void conference_cdr_render(conference_obj_t *conference)
switch_xml_set_txt_d(x_ptr, str);
if (np->cp) {
x_flags = switch_xml_add_child_d(x_member, "flags", member_off++);
switch_assert(x_flags);
x_tag = switch_xml_add_child_d(x_flags, "is_moderator", flag_off++);
switch_xml_set_txt_d(x_tag, switch_test_flag(np, MFLAG_MOD) ? "true" : "false");
x_tag = switch_xml_add_child_d(x_flags, "end_conference", flag_off++);
switch_xml_set_txt_d(x_tag, switch_test_flag(np, MFLAG_ENDCONF) ? "true" : "false");
x_tag = switch_xml_add_child_d(x_flags, "was_kicked", flag_off++);
switch_xml_set_txt_d(x_tag, switch_test_flag(np, MFLAG_KICKED) ? "true" : "false");
if (!(x_cp = switch_xml_add_child_d(x_member, "caller_profile", member_off++))) {
abort();
}
@ -631,8 +682,47 @@ static void conference_cdr_render(conference_obj_t *conference)
}
switch_xml_set_txt_d(x_ptr, np->record_path);
}
}
if (!(x_rejected = switch_xml_add_child_d(x_conference, "rejected", conf_off++))) {
abort();
}
for (rp = conference->cdr_rejected; rp; rp = rp->next) {
int attempt_off = 0;
int tag_off = 0;
if (!(x_attempt = switch_xml_add_child_d(x_rejected, "attempt", attempt_off++))) {
abort();
}
if (!(x_ptr = switch_xml_add_child_d(x_attempt, "reason", tag_off++))) {
abort();
}
if (rp->reason == CDRR_LOCKED) {
switch_xml_set_txt_d(x_ptr, "conference_locked");
} else if (rp->reason == CDRR_MAXMEMBERS) {
switch_xml_set_txt_d(x_ptr, "max_members_reached");
} else if (rp->reason == CDRR_PIN) {
switch_xml_set_txt_d(x_ptr, "invalid_pin");
}
if (!(x_ptr = switch_xml_add_child_d(x_attempt, "reject_time", tag_off++))) {
abort();
}
switch_xml_set_attr_d(x_ptr, "type", "UNIX-epoch");
switch_snprintf(str, sizeof(str), "%ld", (long) rp->reject_time);
switch_xml_set_txt_d(x_ptr, str);
if (rp->cp) {
if (!(x_cp = switch_xml_add_child_d(x_attempt, "caller_profile", attempt_off++))) {
abort();
}
switch_ivr_set_xml_profile_data(x_cp, rp->cp, 0);
}
}
xml_text = switch_xml_toxml(cdr, SWITCH_TRUE);
@ -1343,7 +1433,14 @@ static void *SWITCH_THREAD_FUNC conference_video_thread_run(switch_thread_t *thr
want_refresh = 0;
for (imember = conference->members; imember; imember = imember->next) {
switch_channel_t *ichannel = switch_core_session_get_channel(imember->session);
switch_core_session_t *isession = imember->session;
switch_channel_t *ichannel;
if (!isession || !switch_core_session_read_lock(isession)) {
continue;
}
ichannel = switch_core_session_get_channel(imember->session);
if (switch_channel_test_flag(ichannel, CF_VIDEO_REFRESH_REQ)) {
want_refresh++;
@ -1354,6 +1451,8 @@ static void *SWITCH_THREAD_FUNC conference_video_thread_run(switch_thread_t *thr
has_vid++;
switch_core_session_write_video_frame(imember->session, vid_frame, SWITCH_IO_FLAG_NONE, 0);
}
switch_core_session_rwunlock(isession);
}
if (want_refresh) {
@ -1835,7 +1934,7 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
switch_epoch_time_now(NULL) - conference->endconf_time > conference->endconf_grace_time) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Conference %s: endconf grace time exceeded (%u)\n",
conference->name, conference->endconf_grace_time);
switch_set_flag(conference, CFLAG_DESTRUCT);
switch_set_flag(conference, CFLAG_DESTRUCT | CFLAG_ENDCONF_FORCED);
}
switch_mutex_unlock(conference->mutex);
@ -4595,6 +4694,7 @@ static void conference_xlist(conference_obj_t *conference, switch_xml_t x_confer
x_member = switch_xml_add_child_d(x_members, "member", moff++);
switch_assert(x_member);
switch_xml_set_attr_d(x_member, "type", "caller");
switch_snprintf(i, sizeof(i), "%d", member->id);
@ -6616,6 +6716,7 @@ SWITCH_STANDARD_APP(conference_function)
}
if (!pin_valid) {
conference_cdr_rejected(conference, channel, CDRR_PIN);
goto done;
}
}
@ -6627,6 +6728,7 @@ SWITCH_STANDARD_APP(conference_function)
/* don't allow more callers if the conference is locked, unless we invited them */
if (switch_test_flag(conference, CFLAG_LOCKED) && enforce_security) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Conference %s is locked.\n", conf_name);
conference_cdr_rejected(conference, channel, CDRR_LOCKED);
if (conference->locked_sound) {
/* Answer the channel */
switch_channel_answer(channel);
@ -6641,6 +6743,7 @@ SWITCH_STANDARD_APP(conference_function)
*/
if ((conference->max_members > 0) && (conference->count >= conference->max_members)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Conference %s is full.\n", conf_name);
conference_cdr_rejected(conference, channel, CDRR_MAXMEMBERS);
if (conference->maxmember_sound) {
/* Answer the channel */
switch_channel_answer(channel);

View File

@ -30,7 +30,7 @@
* Bret McDanel <trixter AT 0xdecafbad dot com>
* Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
* Cesar Cepeda <cesar@auronix.com>
* Chris Rienzo <chris@rienzo.net>
* Christopher M. Rienzo <chris@rienzo.com>
*
* mod_dptools.c -- Raw Audio File Streaming Application Module
*

View File

@ -1,24 +0,0 @@
include $(top_srcdir)/build/modmake.rulesam
MODNAME=mod_fax
TIFF_DIR=$(switch_srcdir)/libs/tiff-3.8.2
TIFF_BUILDDIR=$(switch_builddir)/libs/tiff-3.8.2
TIFF_LA=$(TIFF_BUILDDIR)/libtiff/libtiff.la
SPANDSP_DIR=$(switch_srcdir)/libs/spandsp
SPANDSP_BUILDDIR=$(switch_builddir)/libs/spandsp
SPANDSP_LA=$(SPANDSP_BUILDDIR)/src/libspandsp.la
mod_LTLIBRARIES = mod_fax.la
mod_fax_la_SOURCES = mod_fax.c udptl.c
mod_fax_la_CFLAGS = $(AM_CFLAGS) -I$(SPANDSP_DIR)/src -I$(TIFF_DIR)/libtiff -I$(SPANDSP_BUILDDIR)/src -I$(TIFF_BUILDDIR)/libtiff -I.
mod_fax_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(SPANDSP_LA) $(TIFF_LA)
mod_fax_la_LDFLAGS = -avoid-version -module -no-undefined -shared -ljpeg
$(SPANDSP_LA): $(TIFF_LA) $(SPANDSP_DIR) $(SPANDSP_DIR)/.update
cd $(SPANDSP_BUILDDIR) && $(MAKE) -j1
$(TOUCH_TARGET)
$(TIFF_LA): $(TIFF_DIR) $(TIFF_DIR)/.update
cd $(TIFF_BUILDDIR) && $(MAKE) -j1
$(TOUCH_TARGET)

File diff suppressed because it is too large Load Diff

View File

@ -1,563 +0,0 @@
//#define UDPTL_DEBUG
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2009, Steve Underwood <steveu@coppice.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.
*
* Contributor(s):
*
* Steve Underwood <steveu@coppice.org>
*
* udptl.c -- UDPTL handling for T.38
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <inttypes.h>
#include <memory.h>
#include "udptl.h"
#define FALSE 0
#define TRUE (!FALSE)
static int decode_length(const uint8_t *buf, int limit, int *len, int *pvalue)
{
if (*len >= limit)
return -1;
if ((buf[*len] & 0x80) == 0) {
*pvalue = buf[(*len)++];
return 0;
}
if ((buf[*len] & 0x40) == 0) {
if (*len >= limit - 1)
return -1;
*pvalue = (buf[(*len)++] & 0x3F) << 8;
*pvalue |= buf[(*len)++];
return 0;
}
*pvalue = (buf[(*len)++] & 0x3F) << 14;
/* Indicate we have a fragment */
return 1;
}
/*- End of function --------------------------------------------------------*/
static int decode_open_type(const uint8_t *buf, int limit, int *len, const uint8_t ** p_object, int *p_num_octets)
{
int octet_cnt;
int octet_idx;
int stat;
int i;
const uint8_t **pbuf;
for (octet_idx = 0, *p_num_octets = 0;; octet_idx += octet_cnt) {
if ((stat = decode_length(buf, limit, len, &octet_cnt)) < 0)
return -1;
if (octet_cnt > 0) {
*p_num_octets += octet_cnt;
pbuf = &p_object[octet_idx];
i = 0;
/* Make sure the buffer contains at least the number of bits requested */
if ((*len + octet_cnt) > limit)
return -1;
*pbuf = &buf[*len];
*len += octet_cnt;
}
if (stat == 0)
break;
}
return 0;
}
/*- End of function --------------------------------------------------------*/
static int encode_length(uint8_t *buf, int *len, int value)
{
int multiplier;
if (value < 0x80) {
/* 1 octet */
buf[(*len)++] = value;
return value;
}
if (value < 0x4000) {
/* 2 octets */
/* Set the first bit of the first octet */
buf[(*len)++] = ((0x8000 | value) >> 8) & 0xFF;
buf[(*len)++] = value & 0xFF;
return value;
}
/* Fragmentation */
multiplier = (value < 0x10000) ? (value >> 14) : 4;
/* Set the first 2 bits of the octet */
buf[(*len)++] = 0xC0 | multiplier;
return multiplier << 14;
}
/*- End of function --------------------------------------------------------*/
static int encode_open_type(uint8_t *buf, int *len, const uint8_t *data, int num_octets)
{
int enclen;
int octet_idx;
uint8_t zero_byte;
/* If open type is of zero length, add a single zero byte (10.1) */
if (num_octets == 0) {
zero_byte = 0;
data = &zero_byte;
num_octets = 1;
}
/* Encode the open type */
for (octet_idx = 0;; num_octets -= enclen, octet_idx += enclen) {
if ((enclen = encode_length(buf, len, num_octets)) < 0)
return -1;
if (enclen > 0) {
memcpy(&buf[*len], &data[octet_idx], enclen);
*len += enclen;
}
if (enclen >= num_octets)
break;
}
return 0;
}
/*- End of function --------------------------------------------------------*/
int udptl_rx_packet(udptl_state_t *s, const uint8_t buf[], int len)
{
int stat;
int stat2;
int i;
int j;
int k;
int l;
int m;
int x;
int limit;
int which;
int ptr;
int count;
int total_count;
int seq_no;
const uint8_t *msg;
const uint8_t *data;
int msg_len;
int repaired[16];
const uint8_t *bufs[16];
int lengths[16];
int span;
int entries;
ptr = 0;
/* Decode seq_number */
if (ptr + 2 > len)
return -1;
seq_no = (buf[0] << 8) | buf[1];
ptr += 2;
/* Break out the primary packet */
if ((stat = decode_open_type(buf, len, &ptr, &msg, &msg_len)) != 0)
return -1;
/* Decode error_recovery */
if (ptr + 1 > len)
return -1;
/* Our buffers cannot tolerate overlength packets */
if (msg_len > LOCAL_FAX_MAX_DATAGRAM)
return -1;
/* Update any missed slots in the buffer */
for (i = s->rx_seq_no; seq_no > i; i++) {
x = i & UDPTL_BUF_MASK;
s->rx[x].buf_len = -1;
s->rx[x].fec_len[0] = 0;
s->rx[x].fec_span = 0;
s->rx[x].fec_entries = 0;
}
/* Save the new packet. Pure redundancy mode won't use this, but some systems will switch
into FEC mode after sending some redundant packets. */
x = seq_no & UDPTL_BUF_MASK;
memcpy(s->rx[x].buf, msg, msg_len);
s->rx[x].buf_len = msg_len;
s->rx[x].fec_len[0] = 0;
s->rx[x].fec_span = 0;
s->rx[x].fec_entries = 0;
if ((buf[ptr++] & 0x80) == 0) {
/* Secondary packet mode for error recovery */
/* We might have the packet we want, but we need to check through
the redundant stuff, and verify the integrity of the UDPTL.
This greatly reduces our chances of accepting garbage. */
total_count = 0;
do {
if ((stat2 = decode_length(buf, len, &ptr, &count)) < 0)
return -1;
for (i = 0; i < count; i++) {
if ((stat = decode_open_type(buf, len, &ptr, &bufs[total_count + i], &lengths[total_count + i])) != 0)
return -1;
}
total_count += count;
}
while (stat2 > 0);
/* We should now be exactly at the end of the packet. If not, this is a fault. */
if (ptr != len)
return -1;
if (seq_no > s->rx_seq_no) {
/* We received a later packet than we expected, so we need to check if we can fill in the gap from the
secondary packets. */
/* Step through in reverse order, so we go oldest to newest */
for (i = total_count; i > 0; i--) {
if (seq_no - i >= s->rx_seq_no) {
/* This one wasn't seen before */
/* Decode the secondary packet */
#if defined(UDPTL_DEBUG)
fprintf(stderr, "Secondary %d, len %d\n", seq_no - i, lengths[i - 1]);
#endif
/* Save the new packet. Redundancy mode won't use this, but some systems will switch into
FEC mode after sending some redundant packets, and this may then be important. */
x = (seq_no - i) & UDPTL_BUF_MASK;
memcpy(s->rx[x].buf, bufs[i - 1], lengths[i - 1]);
s->rx[x].buf_len = lengths[i - 1];
s->rx[x].fec_len[0] = 0;
s->rx[x].fec_span = 0;
s->rx[x].fec_entries = 0;
if (s->rx_packet_handler(s->user_data, bufs[i - 1], lengths[i - 1], seq_no - i) < 0)
fprintf(stderr, "Bad IFP\n");
}
}
}
} else {
/* FEC mode for error recovery */
/* Decode the FEC packets */
/* The span is defined as an unconstrained integer, but will never be more
than a small value. */
if (ptr + 2 > len)
return -1;
if (buf[ptr++] != 1)
return -1;
span = buf[ptr++];
x = seq_no & UDPTL_BUF_MASK;
s->rx[x].fec_span = span;
memset(repaired, 0, sizeof(repaired));
repaired[x] = TRUE;
/* The number of entries is defined as a length, but will only ever be a small
value. Treat it as such. */
if (ptr + 1 > len)
return -1;
entries = buf[ptr++];
s->rx[x].fec_entries = entries;
/* Decode the elements */
for (i = 0; i < entries; i++) {
if ((stat = decode_open_type(buf, len, &ptr, &data, &s->rx[x].fec_len[i])) != 0)
return -1;
if (s->rx[x].fec_len[i] > LOCAL_FAX_MAX_DATAGRAM)
return -1;
/* Save the new FEC data */
memcpy(s->rx[x].fec[i], data, s->rx[x].fec_len[i]);
#if 0
fprintf(stderr, "FEC: ");
for (j = 0; j < s->rx[x].fec_len[i]; j++)
fprintf(stderr, "%02X ", data[j]);
fprintf(stderr, "\n");
#endif
}
/* We should now be exactly at the end of the packet. If not, this is a fault. */
if (ptr != len)
return -1;
/* See if we can reconstruct anything which is missing */
/* TODO: this does not comprehensively hunt back and repair everything that is possible */
for (l = x; l != ((x - (16 - span * entries)) & UDPTL_BUF_MASK); l = (l - 1) & UDPTL_BUF_MASK) {
if (s->rx[l].fec_len[0] <= 0)
continue;
for (m = 0; m < s->rx[l].fec_entries; m++) {
limit = (l + m) & UDPTL_BUF_MASK;
for (which = -1, k = (limit - s->rx[l].fec_span * s->rx[l].fec_entries) & UDPTL_BUF_MASK; k != limit;
k = (k + s->rx[l].fec_entries) & UDPTL_BUF_MASK) {
if (s->rx[k].buf_len <= 0)
which = (which == -1) ? k : -2;
}
if (which >= 0) {
/* Repairable */
for (j = 0; j < s->rx[l].fec_len[m]; j++) {
s->rx[which].buf[j] = s->rx[l].fec[m][j];
for (k = (limit - s->rx[l].fec_span * s->rx[l].fec_entries) & UDPTL_BUF_MASK; k != limit;
k = (k + s->rx[l].fec_entries) & UDPTL_BUF_MASK)
s->rx[which].buf[j] ^= (s->rx[k].buf_len > j) ? s->rx[k].buf[j] : 0;
}
s->rx[which].buf_len = s->rx[l].fec_len[m];
repaired[which] = TRUE;
}
}
}
/* Now play any new packets forwards in time */
for (l = (x + 1) & UDPTL_BUF_MASK, j = seq_no - UDPTL_BUF_MASK; l != x; l = (l + 1) & UDPTL_BUF_MASK, j++) {
if (repaired[l]) {
#if defined(UDPTL_DEBUG)
fprintf(stderr, "Fixed packet %d, len %d\n", j, l);
#endif
if (s->rx_packet_handler(s->user_data, s->rx[l].buf, s->rx[l].buf_len, j) < 0)
fprintf(stderr, "Bad IFP\n");
}
}
}
/* If packets are received out of sequence, we may have already processed this packet from the error
recovery information in a packet already received. */
if (seq_no >= s->rx_seq_no) {
/* Decode the primary packet */
#if defined(UDPTL_DEBUG)
fprintf(stderr, "Primary packet %d, len %d\n", seq_no, msg_len);
#endif
if (s->rx_packet_handler(s->user_data, msg, msg_len, seq_no) < 0)
fprintf(stderr, "Bad IFP\n");
}
s->rx_seq_no = (seq_no + 1) & 0xFFFF;
return 0;
}
/*- End of function --------------------------------------------------------*/
int udptl_build_packet(udptl_state_t *s, uint8_t buf[], const uint8_t msg[], int msg_len)
{
uint8_t fec[LOCAL_FAX_MAX_DATAGRAM];
int i;
int j;
int seq;
int entry;
int entries;
int span;
int m;
int len;
int limit;
int high_tide;
/* UDPTL cannot cope with zero length messages, and our buffering for redundancy limits their
maximum length. */
if (msg_len < 1 || msg_len > LOCAL_FAX_MAX_DATAGRAM)
return -1;
seq = s->tx_seq_no & 0xFFFF;
/* Map the sequence number to an entry in the circular buffer */
entry = seq & UDPTL_BUF_MASK;
/* We save the message in a circular buffer, for generating FEC or
redundancy sets later on. */
s->tx[entry].buf_len = msg_len;
memcpy(s->tx[entry].buf, msg, msg_len);
/* Build the UDPTL packet */
len = 0;
/* Encode the sequence number */
buf[len++] = (seq >> 8) & 0xFF;
buf[len++] = seq & 0xFF;
/* Encode the primary packet */
if (encode_open_type(buf, &len, msg, msg_len) < 0)
return -1;
/* Encode the appropriate type of error recovery information */
switch (s->error_correction_scheme) {
case UDPTL_ERROR_CORRECTION_NONE:
/* Encode the error recovery type */
buf[len++] = 0x00;
/* The number of entries will always be zero, so it is pointless allowing
for the fragmented case here. */
if (encode_length(buf, &len, 0) < 0)
return -1;
break;
case UDPTL_ERROR_CORRECTION_REDUNDANCY:
/* Encode the error recovery type */
buf[len++] = 0x00;
if (s->tx_seq_no > s->error_correction_entries)
entries = s->error_correction_entries;
else
entries = s->tx_seq_no;
/* The number of entries will always be small, so it is pointless allowing
for the fragmented case here. */
if (encode_length(buf, &len, entries) < 0)
return -1;
/* Encode the elements */
for (i = 0; i < entries; i++) {
j = (entry - i - 1) & UDPTL_BUF_MASK;
if (encode_open_type(buf, &len, s->tx[j].buf, s->tx[j].buf_len) < 0)
return -1;
}
break;
case UDPTL_ERROR_CORRECTION_FEC:
span = s->error_correction_span;
entries = s->error_correction_entries;
if (seq < s->error_correction_span * s->error_correction_entries) {
/* In the initial stages, wind up the FEC smoothly */
entries = seq / s->error_correction_span;
if (seq < s->error_correction_span)
span = 0;
}
/* Encode the error recovery type */
buf[len++] = 0x80;
/* Span is defined as an inconstrained integer, which it dumb. It will only
ever be a small value. Treat it as such. */
buf[len++] = 1;
buf[len++] = span;
/* The number of entries is defined as a length, but will only ever be a small
value. Treat it as such. */
buf[len++] = entries;
for (m = 0; m < entries; m++) {
/* Make an XOR'ed entry the maximum length */
limit = (entry + m) & UDPTL_BUF_MASK;
high_tide = 0;
for (i = (limit - span * entries) & UDPTL_BUF_MASK; i != limit; i = (i + entries) & UDPTL_BUF_MASK) {
if (high_tide < s->tx[i].buf_len) {
for (j = 0; j < high_tide; j++)
fec[j] ^= s->tx[i].buf[j];
for (; j < s->tx[i].buf_len; j++)
fec[j] = s->tx[i].buf[j];
high_tide = s->tx[i].buf_len;
} else {
for (j = 0; j < s->tx[i].buf_len; j++)
fec[j] ^= s->tx[i].buf[j];
}
}
if (encode_open_type(buf, &len, fec, high_tide) < 0)
return -1;
}
break;
}
if (s->verbose)
fprintf(stderr, "\n");
s->tx_seq_no++;
return len;
}
/*- End of function --------------------------------------------------------*/
int udptl_set_error_correction(udptl_state_t *s, int ec_scheme, int span, int entries)
{
switch (ec_scheme) {
case UDPTL_ERROR_CORRECTION_FEC:
case UDPTL_ERROR_CORRECTION_REDUNDANCY:
case UDPTL_ERROR_CORRECTION_NONE:
s->error_correction_scheme = ec_scheme;
break;
case -1:
/* Just don't change the scheme */
break;
default:
return -1;
}
if (span >= 0)
s->error_correction_span = span;
if (entries >= 0)
s->error_correction_entries = entries;
return 0;
}
/*- End of function --------------------------------------------------------*/
int udptl_get_error_correction(udptl_state_t *s, int *ec_scheme, int *span, int *entries)
{
if (ec_scheme)
*ec_scheme = s->error_correction_scheme;
if (span)
*span = s->error_correction_span;
if (entries)
*entries = s->error_correction_entries;
return 0;
}
/*- End of function --------------------------------------------------------*/
int udptl_set_local_max_datagram(udptl_state_t *s, int max_datagram)
{
s->local_max_datagram_size = max_datagram;
return 0;
}
/*- End of function --------------------------------------------------------*/
int udptl_get_local_max_datagram(udptl_state_t *s)
{
return s->local_max_datagram_size;
}
/*- End of function --------------------------------------------------------*/
int udptl_set_far_max_datagram(udptl_state_t *s, int max_datagram)
{
s->far_max_datagram_size = max_datagram;
return 0;
}
/*- End of function --------------------------------------------------------*/
int udptl_get_far_max_datagram(udptl_state_t *s)
{
return s->far_max_datagram_size;
}
/*- End of function --------------------------------------------------------*/
udptl_state_t *udptl_init(udptl_state_t *s, int ec_scheme, int span, int entries, udptl_rx_packet_handler_t rx_packet_handler, void *user_data)
{
int i;
if (rx_packet_handler == NULL)
return NULL;
if (s == NULL) {
if ((s = (udptl_state_t *) malloc(sizeof(*s))) == NULL)
return NULL;
}
memset(s, 0, sizeof(*s));
s->error_correction_scheme = ec_scheme;
s->error_correction_span = span;
s->error_correction_entries = entries;
s->far_max_datagram_size = LOCAL_FAX_MAX_DATAGRAM;
s->local_max_datagram_size = LOCAL_FAX_MAX_DATAGRAM;
memset(&s->rx, 0, sizeof(s->rx));
memset(&s->tx, 0, sizeof(s->tx));
for (i = 0; i <= UDPTL_BUF_MASK; i++) {
s->rx[i].buf_len = -1;
s->tx[i].buf_len = -1;
}
s->rx_packet_handler = rx_packet_handler;
s->user_data = user_data;
return s;
}
/*- End of function --------------------------------------------------------*/
int udptl_release(udptl_state_t *s)
{
return 0;
}
/*- End of function --------------------------------------------------------*/
/*- End of file ------------------------------------------------------------*/

View File

@ -1,153 +0,0 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2009, Steve Underwood <steveu@coppice.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.
*
* Contributor(s):
*
* Steve Underwood <steveu@coppice.org>
*
* udptl.h -- UDPTL handling for T.38
*
*/
#if !defined(FREESWITCH_UDPTL_H)
#define FREESWITCH_UDPTL_H
#define LOCAL_FAX_MAX_DATAGRAM 400
#define LOCAL_FAX_MAX_FEC_PACKETS 5
#define UDPTL_BUF_MASK 15
typedef int (udptl_rx_packet_handler_t) (void *user_data, const uint8_t msg[], int len, int seq_no);
typedef struct {
int buf_len;
uint8_t buf[LOCAL_FAX_MAX_DATAGRAM];
} udptl_fec_tx_buffer_t;
typedef struct {
int buf_len;
uint8_t buf[LOCAL_FAX_MAX_DATAGRAM];
int fec_len[LOCAL_FAX_MAX_FEC_PACKETS];
uint8_t fec[LOCAL_FAX_MAX_FEC_PACKETS][LOCAL_FAX_MAX_DATAGRAM];
int fec_span;
int fec_entries;
} udptl_fec_rx_buffer_t;
struct udptl_state_s {
udptl_rx_packet_handler_t *rx_packet_handler;
void *user_data;
/*! This option indicates the error correction scheme used in transmitted UDPTL
packets. */
int error_correction_scheme;
/*! This option indicates the number of error correction entries transmitted in
UDPTL packets. */
int error_correction_entries;
/*! This option indicates the span of the error correction entries in transmitted
UDPTL packets (FEC only). */
int error_correction_span;
/*! This option indicates the maximum size of a datagram that can be accepted by
the remote device. */
int far_max_datagram_size;
/*! This option indicates the maximum size of a datagram that we are prepared to
accept. */
int local_max_datagram_size;
int verbose;
int tx_seq_no;
int rx_seq_no;
int rx_expected_seq_no;
udptl_fec_tx_buffer_t tx[UDPTL_BUF_MASK + 1];
udptl_fec_rx_buffer_t rx[UDPTL_BUF_MASK + 1];
};
enum {
UDPTL_ERROR_CORRECTION_NONE,
UDPTL_ERROR_CORRECTION_FEC,
UDPTL_ERROR_CORRECTION_REDUNDANCY
};
typedef struct udptl_state_s udptl_state_t;
#if defined(__cplusplus)
extern "C" {
#endif
/*! \brief Process an arriving UDPTL packet.
\param s The UDPTL context.
\param buf The UDPTL packet buffer.
\param len The length of the packet.
\return 0 for OK. */
int udptl_rx_packet(udptl_state_t *s, const uint8_t buf[], int len);
/*! \brief Construct a UDPTL packet, ready for transmission.
\param s The UDPTL context.
\param buf The UDPTL packet buffer.
\param msg The primary packet.
\param len The length of the primary packet.
\return The length of the constructed UDPTL packet. */
int udptl_build_packet(udptl_state_t *s, uint8_t buf[], const uint8_t msg[], int msg_len);
/*! \brief Change the error correction settings of a UDPTL context.
\param s The UDPTL context.
\param ec_scheme One of the optional error correction schemes.
\param span The packet span over which error correction should be applied.
\param entries The number of error correction entries to include in packets.
\return 0 for OK. */
int udptl_set_error_correction(udptl_state_t *s, int ec_scheme, int span, int entries);
/*! \brief Check the error correction settings of a UDPTL context.
\param s The UDPTL context.
\param ec_scheme One of the optional error correction schemes.
\param span The packet span over which error correction is being applied.
\param entries The number of error correction being included in packets.
\return 0 for OK. */
int udptl_get_error_correction(udptl_state_t *s, int *ec_scheme, int *span, int *entries);
int udptl_set_local_max_datagram(udptl_state_t *s, int max_datagram);
int udptl_get_local_max_datagram(udptl_state_t *s);
int udptl_set_far_max_datagram(udptl_state_t *s, int max_datagram);
int udptl_get_far_max_datagram(udptl_state_t *s);
/*! \brief Initialise a UDPTL context.
\param s The UDPTL context.
\param ec_scheme One of the optional error correction schemes.
\param span The packet span over which error correction should be applied.
\param entries The number of error correction entries to include in packets.
\param rx_packet_handler The callback function, used to report arriving IFP packets.
\param user_data An opaque pointer supplied to rx_packet_handler.
\return A pointer to the UDPTL context, or NULL if there was a problem. */
udptl_state_t *udptl_init(udptl_state_t *s, int ec_scheme, int span, int entries, udptl_rx_packet_handler_t rx_packet_handler, void *user_data);
/*! \brief Release a UDPTL context.
\param s The UDPTL context.
\return 0 for OK. */
int udptl_release(udptl_state_t *s);
#if defined(__cplusplus)
}
#endif
#endif
/*- End of file ------------------------------------------------------------*/

View File

@ -23,7 +23,10 @@
*
* Contributor(s):
*
* Chris Rienzo <chris@rienzo.net>
* Christopher M. Rienzo <chris@rienzo.com>
* Darren Schreiber <d@d-man.org>
*
* Maintainer: Christopher M. Rienzo <chris@rienzo.com>
*
* mod_http_cache.c -- HTTP GET with caching
* -- designed for downloading audio files from a webserver for playback
@ -188,12 +191,29 @@ static void url_cache_clear(url_cache_t *cache, switch_core_session_t *session);
static switch_status_t http_put(url_cache_t *cache, switch_core_session_t *session, const char *url, const char *filename)
{
switch_status_t status = SWITCH_STATUS_SUCCESS;
switch_curl_slist_t *headers = NULL; /* optional linked-list of HTTP headers */
char *ext; /* file extension, used for MIME type identification */
const char *mime_type = "application/octet-stream";
char *buf;
CURL *curl_handle = NULL;
long httpRes = 0;
struct stat file_info = {0};
FILE *file_to_put = NULL;
int fd;
/* guess what type of mime content this is going to be */
if ((ext = strrchr(filename, '.'))) {
ext++;
if (!(mime_type = switch_core_mime_ext2type(ext))) {
mime_type = "application/octet-stream";
}
}
buf = switch_mprintf("Content-Type: %s", mime_type);
headers = switch_curl_slist_append(headers, buf);
/* open file and get the file size */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "opening %s for upload to %s\n", filename, url);
fd = open(filename, O_RDONLY);
@ -224,6 +244,7 @@ static switch_status_t http_put(url_cache_t *cache, switch_core_session_t *sessi
switch_curl_easy_setopt(curl_handle, CURLOPT_UPLOAD, 1);
switch_curl_easy_setopt(curl_handle, CURLOPT_PUT, 1);
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);
switch_curl_easy_setopt(curl_handle, CURLOPT_READDATA, file_to_put);
switch_curl_easy_setopt(curl_handle, CURLOPT_INFILESIZE_LARGE, (curl_off_t)file_info.st_size);
@ -258,6 +279,12 @@ done:
fclose(file_to_put);
}
if (headers) {
switch_curl_slist_free_all(headers);
}
switch_safe_free(buf);
return status;
}

View File

@ -32,6 +32,11 @@
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#ifdef _MSC_VER
#include <io.h>
#include <WinSock2.h>
#define snprintf _snprintf
#else
#include <unistd.h>
#include <sys/select.h>
#include <sys/time.h>
@ -39,6 +44,7 @@
#include <netdb.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#endif
#include <fcntl.h>
#include <errno.h>
#include <assert.h>
@ -550,6 +556,7 @@ REDIS credis_connect(const char *host, int port, int timeout)
int fd, yes = 1;
struct sockaddr_in sa;
REDIS rhnd;
int valid = 0;
if ((rhnd = cr_new()) == NULL)
return NULL;
@ -566,7 +573,16 @@ REDIS credis_connect(const char *host, int port, int timeout)
sa.sin_family = AF_INET;
sa.sin_port = htons(port);
if (inet_aton(host, &sa.sin_addr) == 0) {
#ifdef WIN32
sa.sin_addr.S_un.S_addr = inet_addr(host);
if (sa.sin_addr.S_un.S_addr != 0) {
valid = 1;
}
#else
valid = inet_aton(host, &sa.sin_addr);
#endif
if (valid == 0) {
struct hostent *he = gethostbyname(host);
if (he == NULL)
goto error;

View File

@ -2,9 +2,9 @@
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="mod_fax"
ProjectGUID="{7877EFC8-4807-484B-B573-D7B7FD058FAA}"
RootNamespace="mod_fax"
Name="mod_redis"
ProjectGUID="{886B5E9D-F2C2-4AF2-98C8-EF98C4C770E6}"
RootNamespace="mod_redis"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
@ -23,7 +23,7 @@
Name="Debug|Win32"
ConfigurationType="2"
InheritedPropertySheets="..\..\..\..\w32\module_debug.vsprops"
CharacterSet="0"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
@ -42,7 +42,6 @@
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;$(InputDir)..\..\..\..\libs\spandsp\src\msvc&quot;;&quot;$(InputDir)..\..\..\..\libs\spandsp\src&quot;;&quot;$(InputDir)..\..\..\..\libs\tiff-3.8.2\libtiff&quot;"
UsePrecompiledHeader="0"
/>
<Tool
@ -56,7 +55,6 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2_32.lib"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
/>
@ -84,9 +82,11 @@
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
InheritedPropertySheets="..\..\..\..\w32\module_debug.vsprops"
CharacterSet="0"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
@ -106,7 +106,6 @@
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;$(InputDir)..\..\..\..\libs\spandsp\src\msvc&quot;;&quot;$(InputDir)..\..\..\..\libs\spandsp\src&quot;;&quot;$(InputDir)..\..\..\..\libs\tiff-3.8.2\libtiff&quot;"
UsePrecompiledHeader="0"
/>
<Tool
@ -120,7 +119,6 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2_32.lib"
OutputFile="$(SolutionDir)$(PlatformName)\$(ConfigurationName)/mod/$(ProjectName).dll"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
@ -152,7 +150,7 @@
Name="Release|Win32"
ConfigurationType="2"
InheritedPropertySheets="..\..\..\..\w32\module_release.vsprops"
CharacterSet="0"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
@ -171,7 +169,6 @@
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;$(InputDir)..\..\..\..\libs\spandsp\src\msvc&quot;;&quot;$(InputDir)..\..\..\..\libs\spandsp\src&quot;;&quot;$(InputDir)..\..\..\..\libs\tiff-3.8.2\libtiff&quot;"
UsePrecompiledHeader="0"
/>
<Tool
@ -185,7 +182,6 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2_32.lib"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
/>
@ -213,9 +209,11 @@
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
InheritedPropertySheets="..\..\..\..\w32\module_release.vsprops"
CharacterSet="0"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
@ -235,7 +233,6 @@
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;$(InputDir)..\..\..\..\libs\spandsp\src\msvc&quot;;&quot;$(InputDir)..\..\..\..\libs\spandsp\src&quot;;&quot;$(InputDir)..\..\..\..\libs\tiff-3.8.2\libtiff&quot;"
UsePrecompiledHeader="0"
/>
<Tool
@ -249,7 +246,6 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2_32.lib"
OutputFile="$(SolutionDir)$(PlatformName)\$(ConfigurationName)/mod/$(ProjectName).dll"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
@ -282,15 +278,15 @@
</References>
<Files>
<File
RelativePath=".\mod_fax.c"
RelativePath=".\mod_redis.c"
>
</File>
<File
RelativePath=".\udptl.c"
RelativePath=".\credis.c"
>
</File>
<File
RelativePath=".\udptl.h"
RelativePath=".\credis.h"
>
</File>
</Files>

View File

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>mod_redis</ProjectName>
<ProjectGuid>{886B5E9D-F2C2-4AF2-98C8-EF98C4C770E6}</ProjectGuid>
<RootNamespace>mod_redis</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\..\..\w32\module_release.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\..\..\w32\module_debug.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\..\..\w32\module_release.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\..\..\w32\module_debug.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile />
<Link>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile />
<Link>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile />
<Link>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile />
<Link>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="mod_redis.c" />
<ClCompile Include="credis.c" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\w32\Library\FreeSwitchCore.2010.vcxproj">
<Project>{202d7a4e-760d-4d0e-afa1-d7459ced30ff}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClInclude Include="credis.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -29,7 +29,7 @@
* Brian West <brian@freeswitch.org>
* Steve Underwood <steveu@coppice.org>
* Antonio Gallo <agx@linux.it>
* Christopher M. Rienzo <chris@rienzo.net>
* Christopher M. Rienzo <chris@rienzo.com>
* mod_spandsp.c -- Module implementing spandsp fax, dsp, and codec functionality
*
*/

View File

@ -28,7 +28,7 @@
* Anthony Minessale II <anthm@freeswitch.org>
* Steve Underwood <steveu@coppice.org>
* Antonio Gallo <agx@linux.it>
* Christopher M. Rienzo <chris@rienzo.net>
* Christopher M. Rienzo <chris@rienzo.com>
* mod_spandsp_dsp.c -- dsp applications provided by SpanDSP
*
*/

View File

@ -3489,7 +3489,7 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p
switch_safe_free(file_path);
if (switch_channel_ready(channel)) {
if (switch_channel_ready(channel) && vm_enabled) {
status = switch_ivr_phrase_macro(session, VM_GOODBYE_MACRO, NULL, NULL, NULL);
}

View File

@ -17,7 +17,7 @@
* The Original Code is FreeSWITCH mod_unimrcp
*
* The Initial Developer of the Original Code is
* Christopher M. Rienzo <chris@rienzo.net>
* Christopher M. Rienzo <chris@rienzo.com>
*
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
@ -25,9 +25,11 @@
* Contributor(s):
*
* Brian West <brian@freeswitch.org>
* Christopher M. Rienzo <chris@rienzo.net>
* Christopher M. Rienzo <chris@rienzo.com>
* Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
*
* Maintainer: Christopher M. Rienzo <chris@rienzo.com>
*
* mod_unimrcp.c -- UniMRCP module (MRCP client)
*
*/

View File

@ -24,7 +24,7 @@
* Contributor(s):
*
* Anthony Minessale II <anthm@freeswitch.org>
* Chris Rienzo <chris@rienzo.net>
* Christopher M. Rienzo <chris@rienzo.com>
*
*
* mod_speex.c -- Speex Codec Module

View File

@ -132,7 +132,7 @@
//#define SAMPLES_PER_FRAME SAMPLERATE_GSMOPEN/50
#ifndef GSMOPEN_SVN_VERSION
#define GSMOPEN_SVN_VERSION SWITCH_VERSION_REVISION
#define GSMOPEN_SVN_VERSION SWITCH_VERSION_FULL
#endif /* GSMOPEN_SVN_VERSION */
typedef enum {

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005/2012, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -23,17 +23,15 @@
*
* This module (mod_gsmopen) has been contributed by:
*
* Giovanni Maruzzelli (gmaruzz@gmail.com)
* Giovanni Maruzzelli <gmaruzz@gmail.com>
*
* Maintainer: Giovanni Maruzzelli <gmaruzz@gmail.com>
*
* Further Contributors:
*
*
*
* mod_gsmopen.c -- GSM compatible Endpoint Module
* mod_gsmopen.cpp -- GSM Modem compatible Endpoint Module
*
*/
#define __STDC_LIMIT_MACROS
#ifdef WIN32
@ -115,7 +113,7 @@
#endif
#ifndef GSMOPEN_SVN_VERSION
#define GSMOPEN_SVN_VERSION SWITCH_VERSION_REVISION
#define GSMOPEN_SVN_VERSION SWITCH_VERSION_FULL
#endif /* GSMOPEN_SVN_VERSION */
#include "ctb-0.16/ctb.h"

View File

@ -1,3 +1,39 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, 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.
*
* This module (mod_gsmopen) has been contributed by:
*
* Giovanni Maruzzelli <gmaruzz@gmail.com>
*
* Maintainer: Giovanni Maruzzelli <gmaruzz@gmail.com>
*
* gsmopen_protocol.cpp -- Low Level Interface for mod_gamopen
*
*/
#include "gsmopen.h"
#ifdef WIN32
#include "win_iconv.c"

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005/2012, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -23,14 +23,11 @@
*
* This module (mod_gsmopen) has been contributed by:
*
* Giovanni Maruzzelli (gmaruzz@gmail.com)
* Giovanni Maruzzelli <gmaruzz@gmail.com>
*
* Maintainer: Giovanni Maruzzelli <gmaruzz@gmail.com>
*
* Further Contributors:
*
*
*
* mod_gsmopen.c -- GSM compatible Endpoint Module
* mod_gsmopen.cpp -- GSM Modem compatible Endpoint Module
*
*/

View File

@ -1007,6 +1007,7 @@ switch_status_t skinny_handle_register(listener_t *listener, skinny_message_t *r
const char *value = switch_xml_attr_soft(xbutton, "value");
if(type == SKINNY_BUTTON_LINE) {
const char *caller_name = switch_xml_attr_soft(xbutton, "caller-name");
const char *reg_metadata = switch_xml_attr_soft(xbutton, "registration-metadata");
uint32_t ring_on_idle = atoi(switch_xml_attr_soft(xbutton, "ring-on-idle"));
uint32_t ring_on_active = atoi(switch_xml_attr_soft(xbutton, "ring-on-active"));
uint32_t busy_trigger = atoi(switch_xml_attr_soft(xbutton, "busy-trigger"));
@ -1030,7 +1031,7 @@ switch_status_t skinny_handle_register(listener_t *listener, skinny_message_t *r
switch_safe_free(sql);
token = switch_mprintf("skinny/%q/%q/%q:%d", profile->name, value, request->data.reg.device_name, request->data.reg.instance);
url = switch_mprintf("skinny/%q/%q", profile->name, value);
switch_core_add_registration(value, profile->domain, token, url, 0, network_ip, network_port_c, "tcp");
switch_core_add_registration(value, profile->domain, token, url, 0, network_ip, network_port_c, "tcp", reg_metadata);
switch_safe_free(token);
switch_safe_free(url);
}

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -21,19 +21,17 @@
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* This module (mod_skypopen) has been contributed by:
*
* Giovanni Maruzzelli (gmaruzz@gmail.com)
*
*
* Further Contributors:
* This module (mod_gsmopen) has been contributed by:
*
* Giovanni Maruzzelli <gmaruzz@gmail.com>
*
* Maintainer: Giovanni Maruzzelli <gmaruzz@gmail.com>
*
* mod_skypopen.c -- Skype compatible Endpoint Module
*
*/
#include "skypopen.h"
#define SKYPE_CHAT_PROTO "skype"

View File

@ -29,7 +29,6 @@
#include <linux/seq_file.h>
#include <linux/cdev.h>
#include <asm/system.h> /* cli(), *_flags */
#include <asm/uaccess.h> /* copy_*_user */
#include <linux/soundcard.h>

View File

@ -21,6 +21,12 @@
#include <linux/version.h>
#include <linux/ioctl.h> /* needed for the _IOW etc stuff used later */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
#include <asm/switch_to.h> /* cli(), *_flags */
#else
#include <asm/system.h> /* cli(), *_flags */
#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 18)
#define CENTOS_5

View File

@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005/2012, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@ -21,18 +21,17 @@
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* This module (mod_skypopen) has been contributed by:
* This module (mod_gsmopen) has been contributed by:
*
* Giovanni Maruzzelli (gmaruzz@gmail.com)
*
*
* Further Contributors:
* Giovanni Maruzzelli <gmaruzz@gmail.com>
*
* Maintainer: Giovanni Maruzzelli <gmaruzz@gmail.com>
*
* mod_skypopen.c -- Skype compatible Endpoint Module
*
*/
#include <switch.h>
#include <switch_version.h>
@ -86,7 +85,7 @@
#endif
#ifndef SKYPOPEN_SVN_VERSION
#define SKYPOPEN_SVN_VERSION SWITCH_VERSION_REVISION
#define SKYPOPEN_SVN_VERSION SWITCH_VERSION_FULL
#endif /* SKYPOPEN_SVN_VERSION */
typedef enum {

View File

@ -1,3 +1,37 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, 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.
*
* This module (mod_gsmopen) has been contributed by:
*
* Giovanni Maruzzelli <gmaruzz@gmail.com>
*
* Maintainer: Giovanni Maruzzelli <gmaruzz@gmail.com>
*
* skypopen_protocol.c -- Low Level Interface for mod_skypopen
*
*/
#include "skypopen.h"
#ifdef ASTERISK

View File

@ -242,6 +242,8 @@
<!-- TLS version ("sslv23" (default), "tlsv1"). NOTE: Phones may not
work with TLSv1 -->
<param name="tls-version" value="$${sip_tls_version}"/>
<!-- TLS maximum session lifetime -->
<!-- <param name="tls-timeout" value="300"/> -->
<!-- turn on auto-flush during bridge (skip timer sleep when the socket
already has data) (reduces delay on latent connections default
@ -266,7 +268,7 @@
<!-- Let calls hit the dialplan before selecting codec for the a-leg -->
<param name="inbound-late-negotiation" value="true"/>
<!-- Allow ZRTP clients to negotiate end-to-end security associations -->
<!-- Allow ZRTP clients to negotiate end-to-end security associations (also enables late negotiation) -->
<param name="inbound-zrtp-passthru" value="true"/>
<!-- this lets anything register -->

View File

@ -1587,6 +1587,8 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
case SWITCH_MESSAGE_INDICATE_BRIDGE:
{
switch_channel_set_variable(channel, SOFIA_REPLACES_HEADER, NULL);
sofia_glue_tech_track(tech_pvt->profile, session);
sofia_set_flag(tech_pvt, TFLAG_SIMPLIFY);
@ -2337,151 +2339,165 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
break;
case SWITCH_MESSAGE_INDICATE_RESPOND:
if (msg->numeric_arg || msg->string_arg) {
int code = msg->numeric_arg;
const char *reason = NULL;
{
int status = 0;
if (code) {
reason = msg->string_arg;
} else {
if (!zstr(msg->string_arg)) {
if ((code = atoi(msg->string_arg))) {
if ((reason = strchr(msg->string_arg, ' '))) {
reason++;
}
}
}
if (tech_pvt->nh && tech_pvt->nh->nh_ds && tech_pvt->nh->nh_ds->ds_sr && nua_server_request_is_pending(tech_pvt->nh->nh_ds->ds_sr)) {
status = tech_pvt->nh->nh_ds->ds_sr->sr_status;
}
if (!code) {
code = 488;
}
if (!switch_channel_test_flag(channel, CF_ANSWERED) && code >= 300) {
if (sofia_test_flag(tech_pvt, TFLAG_BYE)) {
goto end_lock;
}
}
if (zstr(reason) && code != 407 && code != 302) {
reason = sip_status_phrase(code);
if (zstr(reason)) {
reason = "Because";
}
}
if (code == 407 && !msg->numeric_arg) {
const char *to_uri = switch_channel_get_variable(channel, "sip_to_uri");
const char *to_host = reason;
if (zstr(to_host)) {
to_host = switch_channel_get_variable(channel, "sip_to_host");
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Challenging call %s\n", to_uri);
sofia_reg_auth_challenge(tech_pvt->profile, tech_pvt->nh, NULL, REG_INVITE, to_host, 0);
switch_channel_hangup(channel, SWITCH_CAUSE_USER_CHALLENGE);
} else if (code == 484 && msg->numeric_arg) {
const char *to = switch_channel_get_variable(channel, "sip_to_uri");
const char *max_forwards = switch_channel_get_variable(channel, SWITCH_MAX_FORWARDS_VARIABLE);
char *cid = generate_pai_str(tech_pvt);
char *to_uri = NULL;
if (to) {
char *p;
to_uri = switch_core_session_sprintf(session, "sip:%s", to);
if ((p = strstr(to_uri, ":5060"))) {
*p = '\0';
}
}
if (!switch_channel_test_flag(channel, CF_ANSWERED) && !sofia_test_flag(tech_pvt, TFLAG_BYE)) {
char *extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_RESPONSE_HEADER_PREFIX);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Overlap Dial with %d %s\n", code, reason);
nua_respond(tech_pvt->nh, code, su_strdup(nua_handle_home(tech_pvt->nh), reason), TAG_IF(to_uri, SIPTAG_CONTACT_STR(to_uri)),
SIPTAG_SUPPORTED_STR(NULL), SIPTAG_ACCEPT_STR(NULL),
TAG_IF(cid, SIPTAG_HEADER_STR(cid)),
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
TAG_IF(!zstr(max_forwards), SIPTAG_MAX_FORWARDS_STR(max_forwards)), TAG_END());
sofia_set_flag_locked(tech_pvt, TFLAG_BYE);
switch_safe_free(extra_headers);
}
} else if (code == 302 && !zstr(msg->string_arg)) {
char *p;
if ((p = strchr(msg->string_arg, ' '))) {
*p = '\0';
msg->string_arg = p;
}
msg->message_id = SWITCH_MESSAGE_INDICATE_REDIRECT;
switch_core_session_receive_message(session, msg);
if (status == 0 || status > 199 || tech_pvt->nh->nh_destroyed) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s Cannot call respond on handle at status %d\n",
switch_channel_get_name(channel), status);
goto end_lock;
} else {
if (!sofia_test_flag(tech_pvt, TFLAG_BYE)) {
char *extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_PROGRESS_HEADER_PREFIX);
char *sdp = (char *) msg->pointer_arg;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Responding with %d [%s]\n", code, reason);
sofia_clear_flag(tech_pvt, TFLAG_REINVITED);
if (!zstr((sdp))) {
if (!strcasecmp(sdp, "t38")) {
switch_t38_options_t *t38_options = switch_channel_get_private(tech_pvt->channel, "t38_options");
if (t38_options) {
sofia_glue_set_image_sdp(tech_pvt, t38_options, 0);
if (switch_rtp_ready(tech_pvt->rtp_session)) {
sofia_clear_flag(tech_pvt, TFLAG_NOTIMER_DURING_BRIDGE);
switch_rtp_udptl_mode(tech_pvt->rtp_session);
}
}
} else {
sofia_glue_tech_set_local_sdp(tech_pvt, sdp, SWITCH_TRUE);
}
if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
sofia_glue_tech_patch_sdp(tech_pvt);
sofia_glue_tech_proxy_remote_addr(tech_pvt, NULL);
}
if (sofia_use_soa(tech_pvt)) {
nua_respond(tech_pvt->nh, code, su_strdup(nua_handle_home(tech_pvt->nh), reason), SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
SOATAG_REUSE_REJECTED(1),
SOATAG_ORDERED_USER(1), SOATAG_AUDIO_AUX("cn telephone-event"), NUTAG_INCLUDE_EXTRA_SDP(1),
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
} else {
nua_respond(tech_pvt->nh, code, su_strdup(nua_handle_home(tech_pvt->nh), reason), SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
NUTAG_MEDIA_ENABLE(0),
SIPTAG_CONTENT_TYPE_STR("application/sdp"),
SIPTAG_PAYLOAD_STR(tech_pvt->local_sdp_str),
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
}
if (sofia_test_pflag(tech_pvt->profile, PFLAG_3PCC_PROXY) && sofia_test_flag(tech_pvt, TFLAG_3PCC)) {
/* Unlock the session signal to allow the ack to make it in */
// Maybe we should timeout?
switch_mutex_unlock(tech_pvt->sofia_mutex);
while (switch_channel_ready(channel) && !sofia_test_flag(tech_pvt, TFLAG_3PCC_HAS_ACK)) {
switch_cond_next();
}
/* Regain lock on sofia */
switch_mutex_lock(tech_pvt->sofia_mutex);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "3PCC-PROXY, Done waiting for ACK\n");
sofia_clear_flag(tech_pvt, TFLAG_3PCC);
sofia_clear_flag(tech_pvt, TFLAG_3PCC_HAS_ACK);
switch_core_session_pass_indication(session, SWITCH_MESSAGE_INDICATE_ANSWER);
}
} else {
nua_respond(tech_pvt->nh, code, su_strdup(nua_handle_home(tech_pvt->nh), reason), SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
}
switch_safe_free(extra_headers);
}
}
if (msg->numeric_arg || msg->string_arg) {
int code = msg->numeric_arg;
const char *reason = NULL;
if (code) {
reason = msg->string_arg;
} else {
if (!zstr(msg->string_arg)) {
if ((code = atoi(msg->string_arg))) {
if ((reason = strchr(msg->string_arg, ' '))) {
reason++;
}
}
}
}
if (!code) {
code = 488;
}
if (!switch_channel_test_flag(channel, CF_ANSWERED) && code >= 300) {
if (sofia_test_flag(tech_pvt, TFLAG_BYE)) {
goto end_lock;
}
}
if (zstr(reason) && code != 407 && code != 302) {
reason = sip_status_phrase(code);
if (zstr(reason)) {
reason = "Because";
}
}
if (code == 407 && !msg->numeric_arg) {
const char *to_uri = switch_channel_get_variable(channel, "sip_to_uri");
const char *to_host = reason;
if (zstr(to_host)) {
to_host = switch_channel_get_variable(channel, "sip_to_host");
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Challenging call %s\n", to_uri);
sofia_reg_auth_challenge(tech_pvt->profile, tech_pvt->nh, NULL, REG_INVITE, to_host, 0);
switch_channel_hangup(channel, SWITCH_CAUSE_USER_CHALLENGE);
} else if (code == 484 && msg->numeric_arg) {
const char *to = switch_channel_get_variable(channel, "sip_to_uri");
const char *max_forwards = switch_channel_get_variable(channel, SWITCH_MAX_FORWARDS_VARIABLE);
char *cid = generate_pai_str(tech_pvt);
char *to_uri = NULL;
if (to) {
char *p;
to_uri = switch_core_session_sprintf(session, "sip:%s", to);
if ((p = strstr(to_uri, ":5060"))) {
*p = '\0';
}
}
if (!switch_channel_test_flag(channel, CF_ANSWERED) && !sofia_test_flag(tech_pvt, TFLAG_BYE)) {
char *extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_RESPONSE_HEADER_PREFIX);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Overlap Dial with %d %s\n", code, reason);
nua_respond(tech_pvt->nh, code, su_strdup(nua_handle_home(tech_pvt->nh), reason), TAG_IF(to_uri, SIPTAG_CONTACT_STR(to_uri)),
SIPTAG_SUPPORTED_STR(NULL), SIPTAG_ACCEPT_STR(NULL),
TAG_IF(cid, SIPTAG_HEADER_STR(cid)),
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
TAG_IF(!zstr(max_forwards), SIPTAG_MAX_FORWARDS_STR(max_forwards)), TAG_END());
sofia_set_flag_locked(tech_pvt, TFLAG_BYE);
switch_safe_free(extra_headers);
}
} else if (code == 302 && !zstr(msg->string_arg)) {
char *p;
if ((p = strchr(msg->string_arg, ' '))) {
*p = '\0';
msg->string_arg = p;
}
msg->message_id = SWITCH_MESSAGE_INDICATE_REDIRECT;
switch_core_session_receive_message(session, msg);
goto end_lock;
} else {
if (!sofia_test_flag(tech_pvt, TFLAG_BYE)) {
char *extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_PROGRESS_HEADER_PREFIX);
char *sdp = (char *) msg->pointer_arg;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Responding with %d [%s]\n", code, reason);
sofia_clear_flag(tech_pvt, TFLAG_REINVITED);
if (!zstr((sdp))) {
if (!strcasecmp(sdp, "t38")) {
switch_t38_options_t *t38_options = switch_channel_get_private(tech_pvt->channel, "t38_options");
if (t38_options) {
sofia_glue_set_image_sdp(tech_pvt, t38_options, 0);
if (switch_rtp_ready(tech_pvt->rtp_session)) {
sofia_clear_flag(tech_pvt, TFLAG_NOTIMER_DURING_BRIDGE);
switch_rtp_udptl_mode(tech_pvt->rtp_session);
}
}
} else {
sofia_glue_tech_set_local_sdp(tech_pvt, sdp, SWITCH_TRUE);
}
if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
sofia_glue_tech_patch_sdp(tech_pvt);
sofia_glue_tech_proxy_remote_addr(tech_pvt, NULL);
}
if (sofia_use_soa(tech_pvt)) {
nua_respond(tech_pvt->nh, code, su_strdup(nua_handle_home(tech_pvt->nh), reason), SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
SOATAG_REUSE_REJECTED(1),
SOATAG_ORDERED_USER(1), SOATAG_AUDIO_AUX("cn telephone-event"), NUTAG_INCLUDE_EXTRA_SDP(1),
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
} else {
nua_respond(tech_pvt->nh, code, su_strdup(nua_handle_home(tech_pvt->nh), reason), SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
NUTAG_MEDIA_ENABLE(0),
SIPTAG_CONTENT_TYPE_STR("application/sdp"),
SIPTAG_PAYLOAD_STR(tech_pvt->local_sdp_str),
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
}
if (sofia_test_pflag(tech_pvt->profile, PFLAG_3PCC_PROXY) && sofia_test_flag(tech_pvt, TFLAG_3PCC)) {
/* Unlock the session signal to allow the ack to make it in */
// Maybe we should timeout?
switch_mutex_unlock(tech_pvt->sofia_mutex);
while (switch_channel_ready(channel) && !sofia_test_flag(tech_pvt, TFLAG_3PCC_HAS_ACK)) {
switch_cond_next();
}
/* Regain lock on sofia */
switch_mutex_lock(tech_pvt->sofia_mutex);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "3PCC-PROXY, Done waiting for ACK\n");
sofia_clear_flag(tech_pvt, TFLAG_3PCC);
sofia_clear_flag(tech_pvt, TFLAG_3PCC_HAS_ACK);
switch_core_session_pass_indication(session, SWITCH_MESSAGE_INDICATE_ANSWER);
}
} else {
nua_respond(tech_pvt->nh, code, su_strdup(nua_handle_home(tech_pvt->nh), reason), SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
}
switch_safe_free(extra_headers);
}
}
}
}
break;
case SWITCH_MESSAGE_INDICATE_RINGING:
@ -4919,6 +4935,8 @@ static void general_event_handler(switch_event_t *event)
const char *body = switch_event_get_body(event);
const char *to_uri = switch_event_get_header(event, "to-uri");
const char *from_uri = switch_event_get_header(event, "from-uri");
const char *extra_headers = switch_event_get_header(event, "extra-headers");
sofia_profile_t *profile;
@ -4977,7 +4995,8 @@ static void general_event_handler(switch_event_t *event)
nua_notify(nh,
NUTAG_NEWSUB(1), SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
TAG_IF(dst->route_uri, NUTAG_PROXY(dst->route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)),
SIPTAG_EVENT_STR(es), TAG_IF(ct, SIPTAG_CONTENT_TYPE_STR(ct)), TAG_IF(!zstr(body), SIPTAG_PAYLOAD_STR(body)), TAG_END());
SIPTAG_EVENT_STR(es), TAG_IF(ct, SIPTAG_CONTENT_TYPE_STR(ct)), TAG_IF(!zstr(body), SIPTAG_PAYLOAD_STR(body)),
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)), TAG_END());
switch_safe_free(route_uri);

View File

@ -28,6 +28,7 @@
* Paul D. Tinsley <pdt at jackhammer.org>
* Bret McDanel <trixter AT 0xdecafbad.com>
* Marcel Barbulescu <marcelbarbulescu@gmail.com>
* Raymond Chandler <intralanman@gmail.com>
*
*
* mod_sofia.h -- SOFIA SIP Endpoint
@ -92,7 +93,7 @@ typedef struct private_object private_object_t;
#define MULTICAST_EVENT "multicast::event"
#define SOFIA_REPLACES_HEADER "_sofia_replaces_"
#define SOFIA_USER_AGENT "FreeSWITCH-mod_sofia/" SWITCH_VERSION_MAJOR "." SWITCH_VERSION_MINOR "." SWITCH_VERSION_MICRO "-" SWITCH_VERSION_REVISION
#define SOFIA_USER_AGENT "FreeSWITCH-mod_sofia/" SWITCH_VERSION_FULL
#define SOFIA_CHAT_PROTO "sip"
#define SOFIA_MULTIPART_PREFIX "sip_mp_"
#define SOFIA_MULTIPART_PREFIX_T "~sip_mp_"
@ -517,7 +518,8 @@ struct sofia_gateway {
typedef enum {
PRES_TYPE_NONE = 0,
PRES_TYPE_FULL = 1,
PRES_TYPE_PASSIVE = 2
PRES_TYPE_PASSIVE = 2,
PRES_TYPE_PNP = 3
} sofia_presence_type_t;
typedef enum {
@ -586,12 +588,15 @@ struct sofia_profile {
char *rtcp_audio_interval_msec;
char *rtcp_video_interval_msec;
char *jb_msec;
char *pnp_prov_url;
char *pnp_notify_profile;
sofia_cid_type_t cid_type;
sofia_dtmf_t dtmf_type;
int auto_restart;
switch_port_t sip_port;
switch_port_t tls_sip_port;
int tls_version;
unsigned int tls_timeout;
char *inbound_codec_string;
char *outbound_codec_string;
int running;
@ -1111,7 +1116,7 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile);
void sofia_glue_del_gateway(sofia_gateway_t *gp);
void sofia_glue_gateway_list(sofia_profile_t *profile, switch_stream_handle_t *stream, int up);
void sofia_glue_del_every_gateway(sofia_profile_t *profile);
void sofia_reg_send_reboot(sofia_profile_t *profile, const char *user, const char *host, const char *contact, const char *user_agent,
void sofia_reg_send_reboot(sofia_profile_t *profile, const char *callid, const char *user, const char *host, const char *contact, const char *user_agent,
const char *network_ip);
void sofia_glue_restart_all_profiles(void);
int sofia_glue_toggle_hold(private_object_t *tech_pvt, int sendonly);

View File

@ -2071,6 +2071,8 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
TPTAG_TLS_VERIFY_SUBJECTS(profile->tls_verify_in_subjects)),
TAG_IF(sofia_test_pflag(profile, PFLAG_TLS),
TPTAG_TLS_VERSION(profile->tls_version)),
TAG_IF(sofia_test_pflag(profile, PFLAG_TLS) && profile->tls_timeout,
TPTAG_TLS_TIMEOUT(profile->tls_timeout)),
TAG_IF(!strchr(profile->sipip, ':'),
NTATAG_UDP_MTU(65535)),
TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_SRV),
@ -2138,6 +2140,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
TAG_IF(profile->pres_type, NUTAG_ALLOW_EVENTS("include-session-description")),
TAG_IF(profile->pres_type, NUTAG_ALLOW_EVENTS("presence.winfo")),
TAG_IF(profile->pres_type, NUTAG_ALLOW_EVENTS("message-summary")),
TAG_IF(profile->pres_type == PRES_TYPE_PNP, NUTAG_ALLOW_EVENTS("ua-profile")),
NUTAG_ALLOW_EVENTS("refer"), SIPTAG_SUPPORTED_STR(supported), SIPTAG_USER_AGENT_STR(profile->user_agent), TAG_END());
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Set params for %s\n", profile->name);
@ -2251,7 +2254,11 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void
sofia_clear_pflag_locked(profile, PFLAG_SHUTDOWN);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Waiting for worker thread\n");
switch_thread_join(&st, worker_thread);
if ( worker_thread ) {
switch_thread_join(&st, worker_thread);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: Sofia worker thead failed to start\n");
}
sanity = 4;
while (profile->inuse) {
@ -3929,6 +3936,7 @@ switch_status_t config_sofia(int reload, char *profile_name)
profile->sip_force_expires = 0;
profile->sip_expires_max_deviation = 0;
profile->tls_version = 0;
profile->tls_timeout = 300;
profile->mflags = MFLAG_REFER | MFLAG_REGISTER;
profile->server_rport_level = 1;
profile->client_rport_level = 1;
@ -4417,10 +4425,16 @@ switch_status_t config_sofia(int reload, char *profile_name)
} else if (!strcasecmp(val, "bypass-media-after-att-xfer")) {
profile->media_options |= MEDIA_OPT_BYPASS_AFTER_ATT_XFER;
}
} else if (!strcasecmp(var, "pnp-provision-url")) {
profile->pnp_prov_url = switch_core_strdup(profile->pool, val);
} else if (!strcasecmp(var, "pnp-notify-profile")) {
profile->pnp_notify_profile = switch_core_strdup(profile->pool, val);
} else if (!strcasecmp(var, "manage-presence")) {
if (!strcasecmp(val, "passive")) {
profile->pres_type = PRES_TYPE_PASSIVE;
} else if (!strcasecmp(val, "pnp")) {
profile->pres_type = PRES_TYPE_PNP;
} else if (switch_true(val)) {
profile->pres_type = PRES_TYPE_FULL;
}
@ -4743,6 +4757,9 @@ switch_status_t config_sofia(int reload, char *profile_name)
} else {
profile->tls_version = 0;
}
} else if (!strcasecmp(var, "tls-timeout")) {
int v = atoi(val);
profile->tls_timeout = v > 0 ? (unsigned int)v : 300;
} else if (!strcasecmp(var, "timer-T1")) {
int v = atoi(val);
if (v > 0) {
@ -4813,7 +4830,8 @@ switch_status_t config_sofia(int reload, char *profile_name)
}
}
if (sofia_test_flag(profile, TFLAG_ZRTP_PASSTHRU)) {
if (sofia_test_flag(profile, TFLAG_ZRTP_PASSTHRU) && !sofia_test_flag(profile, TFLAG_LATE_NEGOTIATION)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "ZRTP passthrough implictly enables inbound-late-negotiation\n");
sofia_set_flag(profile, TFLAG_LATE_NEGOTIATION);
}
@ -4874,6 +4892,23 @@ switch_status_t config_sofia(int reload, char *profile_name)
profile->sipdomain = switch_core_strdup(profile->pool, profile->sipip);
}
if (profile->pres_type == PRES_TYPE_PNP) {
if (!profile->pnp_prov_url) {
profile->pnp_prov_url = switch_core_sprintf(profile->pool, "http://%s/provision/", mod_sofia_globals.guess_ip);
}
if (!profile->pnp_notify_profile) {
profile->pnp_notify_profile = switch_core_strdup(profile->pool, mod_sofia_globals.guess_ip);
}
if (!profile->extsipip) {
profile->extsipip = switch_core_strdup(profile->pool, mod_sofia_globals.guess_ip);
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "we're configured to provision to [%s] on profile [%s]\n",
profile->pnp_prov_url, profile->pnp_notify_profile);
}
config_sofia_profile_urls(profile);
if (sofia_test_pflag(profile, PFLAG_TLS) && !profile->tls_cert_dir) {
@ -5815,7 +5850,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
tech_pvt->remote_sdp_str = switch_core_session_strdup(session, r_sdp);
switch_channel_set_variable(channel, SWITCH_R_SDP_VARIABLE, r_sdp);
if (sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) && (parser = sdp_parse(NULL, r_sdp, (int) strlen(r_sdp), 0))) {
if ((sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) || switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) && (parser = sdp_parse(NULL, r_sdp, (int) strlen(r_sdp), 0))) {
if ((sdp = sdp_session(parser))) {
sofia_glue_set_r_sdp_codec_string(session, sofia_glue_get_codec_string(tech_pvt), sdp);
}
@ -6797,6 +6832,9 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t
nua_respond(nh, SIP_202_ACCEPTED, NUTAG_WITH_THIS_MSG(de->data->e_msg), SIPTAG_EXPIRES_STR("60"), TAG_END());
switch_channel_set_variable(tech_pvt->channel, SOFIA_REPLACES_HEADER, NULL);
if (sip->sip_referred_by) {
full_ref_by = sip_header_as_string(home, (void *) sip->sip_referred_by);
}
@ -7641,6 +7679,11 @@ void sofia_handle_sip_i_reinvite(switch_core_session_t *session,
tagi_t tags[])
{
char *call_info = NULL;
switch_channel_t *channel = NULL;
if (session) {
channel = switch_core_session_get_channel(session);
}
if (session && profile && sip && sofia_test_pflag(profile, PFLAG_TRACK_CALLS)) {
switch_channel_t *channel = switch_core_session_get_channel(session);
@ -7665,7 +7708,6 @@ void sofia_handle_sip_i_reinvite(switch_core_session_t *session,
}
if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) {
switch_channel_t *channel = switch_core_session_get_channel(session);
if (channel && sip->sip_call_info) {
char *p;
if ((call_info = sip_header_as_string(nua_handle_home(nh), (void *) sip->sip_call_info))) {
@ -7679,6 +7721,14 @@ void sofia_handle_sip_i_reinvite(switch_core_session_t *session,
}
}
}
if (channel) {
if (sip->sip_payload && sip->sip_payload->pl_data) {
switch_channel_set_variable(channel, "sip_reinvite_sdp", sip->sip_payload->pl_data);
}
switch_channel_execute_on(channel, "execute_on_sip_reinvite");
}
}
void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,

View File

@ -350,7 +350,7 @@ static void generate_m(private_object_t *tech_pvt, char *buf, size_t buflen,
tech_pvt->local_sdp_audio_zrtp_hash);
}
if (sr) {
if (!zstr(sr)) {
switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=%s\n", sr);
}
}
@ -375,7 +375,7 @@ void sofia_glue_check_dtmf_type(private_object_t *tech_pvt)
void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, switch_port_t port, const char *sr, int force)
{
char buf[2048];
char buf[65536];
int ptime = 0;
uint32_t rate = 0;
uint32_t v_port;
@ -434,7 +434,7 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, switch
verbose_sdp = 1;
}
if (!force && !ip && !sr
if (!force && !ip && zstr(sr)
&& (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) || switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA))) {
return;
}
@ -465,7 +465,7 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, switch
sofia_glue_sdp_map(b_sdp, &map, &ptmap);
}
if (!sr) {
if (zstr(sr)) {
if ((var_val = switch_channel_get_variable(tech_pvt->channel, "media_audio_mode"))) {
sr = var_val;
} else {
@ -485,7 +485,9 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, switch
if ((tech_pvt->profile->ndlb & PFLAG_NDLB_SENDRECV_IN_SESSION) ||
((var_val = switch_channel_get_variable(tech_pvt->channel, "ndlb_sendrecv_in_session")) && switch_true(var_val))) {
switch_snprintf(srbuf, sizeof(srbuf), "a=%s\n", sr);
if (!zstr(sr)) {
switch_snprintf(srbuf, sizeof(srbuf), "a=%s\n", sr);
}
sr = NULL;
}
@ -554,7 +556,7 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, switch
tech_pvt->local_sdp_audio_zrtp_hash);
}
if (sr) {
if (!zstr(sr)) {
switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=%s\n", sr);
}
@ -619,7 +621,7 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, switch
cur_ptime = this_ptime;
if ((!zstr(tech_pvt->local_crypto_key) && sofia_test_flag(tech_pvt, TFLAG_SECURE))) {
generate_m(tech_pvt, buf, sizeof(buf), port, cur_ptime, append_audio, sr, use_cng, cng_type, map, verbose_sdp, 1);
generate_m(tech_pvt, bp, sizeof(buf) - strlen(buf), port, cur_ptime, append_audio, sr, use_cng, cng_type, map, verbose_sdp, 1);
bp = (buf + strlen(buf));
/* asterisk can't handle AVP and SAVP in sep streams, way to blow off the spec....*/
@ -776,19 +778,23 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, switch
const char *sofia_glue_get_codec_string(private_object_t *tech_pvt)
{
const char *codec_string = NULL, *preferred = NULL, *fallback = NULL;
if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
preferred = tech_pvt->profile->outbound_codec_string;
fallback = tech_pvt->profile->inbound_codec_string;
} else {
preferred = tech_pvt->profile->inbound_codec_string;
fallback = tech_pvt->profile->outbound_codec_string;
const char *preferred = NULL, *fallback = NULL;
if (!(preferred = switch_channel_get_variable(tech_pvt->channel, "absolute_codec_string"))) {
preferred = switch_channel_get_variable(tech_pvt->channel, "codec_string");
}
if (!preferred) {
if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
preferred = tech_pvt->profile->outbound_codec_string;
fallback = tech_pvt->profile->inbound_codec_string;
} else {
preferred = tech_pvt->profile->inbound_codec_string;
fallback = tech_pvt->profile->outbound_codec_string;
}
}
codec_string = !zstr(preferred) ? preferred : fallback;
return codec_string;
return !zstr(preferred) ? preferred : fallback;
}
void sofia_glue_tech_prepare_codecs(private_object_t *tech_pvt)
@ -2087,7 +2093,9 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
}
rep = switch_channel_get_variable(channel, SOFIA_REPLACES_HEADER);
if ((rep = switch_channel_get_variable(channel, SOFIA_REPLACES_HEADER))) {
switch_channel_set_variable(channel, SOFIA_REPLACES_HEADER, NULL);
}
switch_assert(tech_pvt != NULL);
@ -2590,6 +2598,11 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
tech_pvt->session_refresher = nua_no_refresher;
}
if (tech_pvt->local_sdp_str) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG,
"Local SDP:\n%s\n", tech_pvt->local_sdp_str);
}
if (sofia_use_soa(tech_pvt)) {
nua_invite(tech_pvt->nh,
NUTAG_AUTOANSWER(0),
@ -3856,10 +3869,21 @@ static void add_audio_codec(sdp_rtpmap_t *map, int ptime, char *buf, switch_size
void sofia_glue_pass_zrtp_hash2(switch_core_session_t *aleg_session, switch_core_session_t *bleg_session)
{
switch_channel_t *aleg_channel = switch_core_session_get_channel(aleg_session);
private_object_t *aleg_tech_pvt = switch_core_session_get_private(aleg_session);
switch_channel_t *bleg_channel = switch_core_session_get_channel(bleg_session);
private_object_t *bleg_tech_pvt = switch_core_session_get_private(bleg_session);
switch_channel_t *aleg_channel;
private_object_t *aleg_tech_pvt;
switch_channel_t *bleg_channel;
private_object_t *bleg_tech_pvt;
if (!switch_core_session_compare(aleg_session, bleg_session)) {
/* since this digs into channel internals its only compatible with sofia sessions*/
return;
}
aleg_channel = switch_core_session_get_channel(aleg_session);
aleg_tech_pvt = switch_core_session_get_private(aleg_session);
bleg_channel = switch_core_session_get_channel(bleg_session);
bleg_tech_pvt = switch_core_session_get_private(bleg_session);
switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(aleg_channel), SWITCH_LOG_DEBUG, "Deciding whether to pass zrtp-hash between a-leg and b-leg\n");
if (!(switch_channel_test_flag(aleg_tech_pvt->channel, CF_ZRTP_PASSTHRU_REQ))) {
switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(aleg_channel), SWITCH_LOG_DEBUG, "CF_ZRTP_PASSTHRU_REQ not set on a-leg, so not propagating zrtp-hash\n");
@ -4155,6 +4179,7 @@ int sofia_glue_toggle_hold(private_object_t *tech_pvt, int sendonly)
int changed = 0;
if (sofia_test_flag(tech_pvt, TFLAG_SLA_BARGE) || sofia_test_flag(tech_pvt, TFLAG_SLA_BARGING)) {
switch_channel_mark_hold(tech_pvt->channel, sendonly);
return 0;
}
@ -4697,10 +4722,6 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
goto done;
}
if (switch_channel_test_app_flag_key("T38", tech_pvt->channel, CF_APP_T38)) {
sofia_set_flag(tech_pvt, TFLAG_NOREPLY);
}
if (switch_true(switch_channel_get_variable(channel, "refuse_t38"))) {
switch_channel_clear_app_flag_key("T38", tech_pvt->channel, CF_APP_T38);
match = 0;
@ -4709,6 +4730,11 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
const char *var = switch_channel_get_variable(channel, "t38_passthru");
int pass = sofia_test_pflag(tech_pvt->profile, PFLAG_T38_PASSTHRU);
if (switch_channel_test_app_flag_key("T38", tech_pvt->channel, CF_APP_T38)) {
sofia_set_flag(tech_pvt, TFLAG_NOREPLY);
}
if (var) {
if (!(pass = switch_true(var))) {
if (!strcasecmp(var, "once")) {

View File

@ -27,6 +27,7 @@
* Ken Rice <krice@freeswitch.org>
* Paul D. Tinsley <pdt at jackhammer.org>
* Bret McDanel <trixter AT 0xdecafbad.com>
* Raymond Chandler <intralanman@gmail.com>
*
*
* sofia_presence.c -- SOFIA SIP Endpoint (presence code)
@ -537,16 +538,16 @@ static void actual_sofia_presence_mwi_event_handler(switch_event_t *event)
sql = switch_mprintf("select proto,sip_user,sip_host,sub_to_user,sub_to_host,event,contact,call_id,full_from,"
"full_via,expires,user_agent,accept,profile_name,network_ip"
",'%q',full_to,network_ip,network_port from sip_subscriptions "
"where hostname='%q' and profile_name='%q' and event='message-summary' "
"where hostname='%q' and event='message-summary' "
"and sub_to_user='%q' and (sub_to_host='%q' or presence_hosts like '%%%q%%')",
stream.data, mod_sofia_globals.hostname, profile->name, user, host, host);
stream.data, mod_sofia_globals.hostname, user, host, host);
} else if (sub_call_id) {
sql = switch_mprintf("select proto,sip_user,sip_host,sub_to_user,sub_to_host,event,contact,call_id,full_from,"
"full_via,expires,user_agent,accept,profile_name,network_ip"
",'%q',full_to,network_ip,network_port from sip_subscriptions where "
"hostname='%q' and profile_name='%q' and event='message-summary' "
"hostname='%q' and event='message-summary' "
"and sub_to_user='%q' and (sub_to_host='%q' or presence_hosts like '%%%q%%') and call_id='%q'",
stream.data, mod_sofia_globals.hostname, profile->name, user, host, host, sub_call_id);
stream.data, mod_sofia_globals.hostname, user, host, host, sub_call_id);
}
@ -559,12 +560,12 @@ static void actual_sofia_presence_mwi_event_handler(switch_event_t *event)
if (for_everyone) {
sql = switch_mprintf("select sip_user,sip_host,contact,profile_name,network_ip,'%q',call_id "
"from sip_registrations where hostname='%q' and profile_name='%q' and mwi_user='%q' and mwi_host='%q'",
stream.data, mod_sofia_globals.hostname, profile->name, user, host);
"from sip_registrations where hostname='%q' and mwi_user='%q' and mwi_host='%q'",
stream.data, mod_sofia_globals.hostname, user, host);
} else if (call_id) {
sql = switch_mprintf("select sip_user,sip_host,contact,profile_name,network_ip,'%q',call_id "
"from sip_registrations where hostname='%q' and profile_name='%q' and call_id='%q'",
stream.data, mod_sofia_globals.hostname, profile->name, call_id);
"from sip_registrations where hostname='%q' and call_id='%q'",
stream.data, mod_sofia_globals.hostname, call_id);
}
if (sql) {
@ -3273,7 +3274,9 @@ void sofia_presence_handle_sip_i_subscribe(int status,
int sent_reply = 0;
sip_contact_t const *contact;
const char *ipv6;
const char *contact_user;
const char *contact_user = NULL;
const char *contact_host = NULL;
const char *contact_port = NULL;
sofia_nat_parse_t np = { { 0 } };
int found_proto = 0;
char to_tag[13] = "";
@ -3295,8 +3298,11 @@ void sofia_presence_handle_sip_i_subscribe(int status,
switch_stun_random_string(to_tag, 12, NULL);
//contact_host = sip->sip_contact->m_url->url_host;
contact_user = sip->sip_contact->m_url->url_user;
if ( sip->sip_contact && sip->sip_contact->m_url ) {
contact_host = sip->sip_contact->m_url->url_host;
contact_port = sip->sip_contact->m_url->url_port;
contact_user = sip->sip_contact->m_url->url_user;
}
//tl_gets(tags, NUTAG_SUBSTATE_REF(sub_state), TAG_END());
@ -3645,6 +3651,38 @@ void sofia_presence_handle_sip_i_subscribe(int status,
}
}
if ( sip->sip_event && sip->sip_event->o_type && !strcasecmp(sip->sip_event->o_type, "ua-profile") && contact_host ) {
switch_event_t *params;
char *uri = NULL;
char *extra_headers = NULL;
if ( contact_port ) {
uri = switch_mprintf("sip:%s:%s", contact_host, contact_port);
} else {
uri = switch_mprintf("sip:%s", contact_host);
}
if ( uri ) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "sending pnp NOTIFY to %s\n", uri);
/* Grandstream REALLY uses a header called Message Body */
extra_headers = switch_mprintf("MessageBody: %s\r\n", profile->pnp_prov_url);
switch_event_create(&params, SWITCH_EVENT_NOTIFY);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "profile", profile->pnp_notify_profile);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "event-string", sip->sip_event->o_type);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "to-uri", uri);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "from-uri", uri);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "extra-headers", extra_headers);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "content-type", "application/url");
switch_event_add_body(params, "%s", profile->pnp_prov_url);
switch_event_fire(&params);
switch_safe_free(uri);
switch_safe_free(extra_headers);
}
}
end:
if (strcasecmp(event, "call-info") && strcasecmp(event, "line-seize")) {

View File

@ -572,7 +572,7 @@ int sofia_reg_nat_callback(void *pArg, int argc, char **argv, char **columnNames
}
void sofia_reg_send_reboot(sofia_profile_t *profile, const char *user, const char *host, const char *contact, const char *user_agent,
void sofia_reg_send_reboot(sofia_profile_t *profile, const char *callid, const char *user, const char *host, const char *contact, const char *user_agent,
const char *network_ip)
{
const char *event = "check-sync";
@ -587,7 +587,7 @@ void sofia_reg_send_reboot(sofia_profile_t *profile, const char *user, const cha
event = "reboot";
}
sofia_glue_send_notify(profile, user, host, event, contenttype, body, contact, network_ip, NULL);
sofia_glue_send_notify(profile, user, host, event, contenttype, body, contact, network_ip, callid);
}
int sofia_sla_dialog_del_callback(void *pArg, int argc, char **argv, char **columnNames)
@ -608,7 +608,7 @@ int sofia_reg_del_callback(void *pArg, int argc, char **argv, char **columnNames
sofia_profile_t *profile = (sofia_profile_t *) pArg;
if (argc > 12 && atoi(argv[12]) == 1) {
sofia_reg_send_reboot(profile, argv[1], argv[2], argv[3], argv[7], argv[11]);
sofia_reg_send_reboot(profile, argv[0], argv[1], argv[2], argv[3], argv[7], argv[11]);
}
if (argc >= 3) {
@ -787,7 +787,7 @@ int sofia_reg_check_callback(void *pArg, int argc, char **argv, char **columnNam
{
sofia_profile_t *profile = (sofia_profile_t *) pArg;
sofia_reg_send_reboot(profile, argv[1], argv[2], argv[3], argv[7], argv[11]);
sofia_reg_send_reboot(profile, argv[0], argv[1], argv[2], argv[3], argv[7], argv[11]);
return 0;
}
@ -1028,6 +1028,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
sip_contact_t const *contact = NULL;
char *sql;
switch_event_t *s_event;
const char *reg_meta = NULL;
const char *to_user = NULL;
const char *to_host = NULL;
char *mwi_account = NULL;
@ -1485,6 +1486,10 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
to_user = var;
}
if (v_event && *v_event && (var = switch_event_get_header(*v_event, "registration_metadata"))) {
reg_meta = var;
}
if (v_event && *v_event && (mwi_account = switch_event_get_header(*v_event, "mwi-account"))) {
dup_mwi_account = strdup(mwi_account);
switch_assert(dup_mwi_account != NULL);
@ -1559,7 +1564,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
url = switch_mprintf("sofia/%q/sip:%q", profile->name, sofia_glue_strip_proto(contact));
switch_core_add_registration(to_user, reg_host, call_id, url, (long) switch_epoch_time_now(NULL) + (long) exptime + 60,
network_ip, network_port_c, is_tls ? "tls" : is_tcp ? "tcp" : "udp");
network_ip, network_port_c, is_tls ? "tls" : is_tcp ? "tcp" : "udp", reg_meta);
switch_safe_free(url);
switch_safe_free(contact);
@ -2119,6 +2124,10 @@ void sofia_reg_handle_sip_r_challenge(int status,
switch_event_add_header_string(locate_params, SWITCH_STACK_BOTTOM, "action", "reverse-auth-lookup");
if ( sip->sip_call_id ) {
switch_event_add_header_string(locate_params, SWITCH_STACK_BOTTOM, "sip_call_id", sip->sip_call_id->i_id);
}
if (switch_xml_locate_user_merged("id", sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, NULL,
&x_user, locate_params) == SWITCH_STATUS_SUCCESS) {
if ((x_params = switch_xml_child(x_user, "params"))) {

View File

@ -145,7 +145,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session)
for (ap = app_log; ap; ap = ap->next) {
bson_append_start_object(&cdr, "application");
bson_append_string(&cdr, "app_name", ap->app);
bson_append_string(&cdr, "app_data", ap->arg);
bson_append_string(&cdr, "app_data", switch_str_nil(ap->arg));
bson_append_long(&cdr, "app_stamp", ap->stamp);
bson_append_finish_object(&cdr); /* application */
}
@ -186,7 +186,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session)
bson_append_bool(&cdr, "last_executed", 1);
}
bson_append_string(&cdr, "app_name", ap->application_name);
bson_append_string(&cdr, "app_data", ap->application_data);
bson_append_string(&cdr, "app_data", switch_str_nil(ap->application_data));
bson_append_finish_object(&cdr);
}
@ -215,7 +215,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session)
bson_append_bool(&cdr, "last_executed", 1);
}
bson_append_string(&cdr, "app_name", ap->application_name);
bson_append_string(&cdr, "app_data", ap->application_data);
bson_append_string(&cdr, "app_data", switch_str_nil(ap->application_data));
bson_append_finish_object(&cdr);
}

View File

@ -28,6 +28,7 @@
* Rob Charlton <rob.charlton@savageminds.com>
* Darren Schreiber <d@d-man.org>
* Mike Jerris <mike@jerris.com>
* Tamas Cseke <tamas.cseke@virtual-call-center.eu>
*
*
* handle_msg.c -- handle messages received from erlang nodes
@ -286,6 +287,8 @@ static switch_status_t handle_msg_event(listener_t *listener, int arity, ei_x_bu
switch_set_flag_locked(listener, LFLAG_EVENTS);
}
switch_thread_rwlock_wrlock(listener->event_rwlock);
for (i = 1; i < arity; i++) {
if (!ei_decode_atom(buf->buff, &buf->index, atom)) {
@ -311,6 +314,8 @@ static switch_status_t handle_msg_event(listener_t *listener, int arity, ei_x_bu
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "enable event %s\n", atom);
}
}
switch_thread_rwlock_unlock(listener->event_rwlock);
ei_x_encode_atom(rbuf, "ok");
}
return SWITCH_STATUS_SUCCESS;
@ -332,6 +337,8 @@ static switch_status_t handle_msg_session_event(listener_t *listener, erlang_msg
switch_event_types_t type;
int i = 0;
switch_thread_rwlock_wrlock(session->event_rwlock);
for (i = 1; i < arity; i++) {
if (!ei_decode_atom(buf->buff, &buf->index, atom)) {
@ -357,6 +364,9 @@ static switch_status_t handle_msg_session_event(listener_t *listener, erlang_msg
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "enable event %s for session %s\n", atom, session->uuid_str);
}
}
switch_thread_rwlock_unlock(session->event_rwlock);
ei_x_encode_atom(rbuf, "ok");
} else {
ei_x_encode_tuple_header(rbuf, 2);
@ -380,10 +390,13 @@ static switch_status_t handle_msg_nixevent(listener_t *listener, int arity, ei_x
int i = 0;
switch_event_types_t type;
switch_thread_rwlock_wrlock(listener->event_rwlock);
for (i = 1; i < arity; i++) {
if (!ei_decode_atom(buf->buff, &buf->index, atom)) {
if (custom) {
switch_core_hash_delete(listener->event_hash, atom);
} else if (switch_name_event(atom, &type) == SWITCH_STATUS_SUCCESS) {
uint32_t x = 0;
@ -406,6 +419,8 @@ static switch_status_t handle_msg_nixevent(listener_t *listener, int arity, ei_x
}
}
}
switch_thread_rwlock_unlock(listener->event_rwlock);
ei_x_encode_atom(rbuf, "ok");
}
return SWITCH_STATUS_SUCCESS;
@ -426,6 +441,8 @@ static switch_status_t handle_msg_session_nixevent(listener_t *listener, erlang_
int i = 0;
switch_event_types_t type;
switch_thread_rwlock_wrlock(session->event_rwlock);
for (i = 1; i < arity; i++) {
if (!ei_decode_atom(buf->buff, &buf->index, atom)) {
@ -452,6 +469,8 @@ static switch_status_t handle_msg_session_nixevent(listener_t *listener, erlang_
}
}
}
switch_thread_rwlock_unlock(session->event_rwlock);
ei_x_encode_atom(rbuf, "ok");
} else { /* no session for this pid */
ei_x_encode_tuple_header(rbuf, 2);
@ -481,7 +500,7 @@ static switch_status_t handle_msg_setevent(listener_t *listener, erlang_msg *msg
int i = 0;
/* clear any previous event registrations */
for( x = 0; x <= SWITCH_EVENT_ALL; x++){
for(x = 0; x <= SWITCH_EVENT_ALL; x++) {
event_list[x] = 0;
}
@ -515,10 +534,11 @@ static switch_status_t handle_msg_setevent(listener_t *listener, erlang_msg *msg
}
}
/* update the event subscriptions with the new ones */
switch_thread_rwlock_wrlock(listener->event_rwlock);
memcpy(listener->event_list, event_list, sizeof(uint8_t) * (SWITCH_EVENT_ALL + 1));
/* wipe the old hash, and point the pointer at the new one */
switch_core_hash_destroy(&listener->event_hash);
listener->event_hash = event_hash;
switch_thread_rwlock_unlock(listener->event_rwlock);
/* TODO - we should flush any non-matching events from the queue */
ei_x_encode_atom(rbuf, "ok");
@ -573,11 +593,15 @@ static switch_status_t handle_msg_session_setevent(listener_t *listener, erlang_
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "enable event %s for session %s\n", atom, session->uuid_str);
}
}
/* update the event subscriptions with the new ones */
switch_thread_rwlock_wrlock(session->event_rwlock);
memcpy(session->event_list, event_list, sizeof(uint8_t) * (SWITCH_EVENT_ALL + 1));
/* wipe the old hash, and point the pointer at the new one */
switch_core_hash_destroy(&session->event_hash);
session->event_hash = event_hash;
switch_thread_rwlock_unlock(session->event_rwlock);
/* TODO - we should flush any non-matching events from the queue */
ei_x_encode_atom(rbuf, "ok");
} else { /* no session for this pid */
@ -601,13 +625,13 @@ static switch_status_t handle_msg_api(listener_t *listener, erlang_msg * msg, in
fail = SWITCH_TRUE;
}
ei_get_type(buf->buff, &buf->index, &type, &size);
ei_get_type(buf->buff, &buf->index, &type, &size);
if ((size > (sizeof(api_cmd) - 1)) || ei_decode_atom(buf->buff, &buf->index, api_cmd)) {
fail = SWITCH_TRUE;
}
ei_get_type(buf->buff, &buf->index, &type, &size);
ei_get_type(buf->buff, &buf->index, &type, &size);
arg = malloc(size + 1);
if (ei_decode_string(buf->buff, &buf->index, arg)) {
@ -706,29 +730,29 @@ static switch_status_t handle_msg_sendevent(listener_t *listener, int arity, ei_
while (!ei_decode_tuple_header(buf->buff, &buf->index, &arity) && arity == 2) {
i++;
ei_get_type(buf->buff, &buf->index, &type, &size);
ei_get_type(buf->buff, &buf->index, &type, &size);
if ((size > (sizeof(key) - 1)) || ei_decode_string(buf->buff, &buf->index, key)) {
fail = SWITCH_TRUE;
break;
}
ei_get_type(buf->buff, &buf->index, &type, &size);
value = malloc(size + 1);
ei_get_type(buf->buff, &buf->index, &type, &size);
value = malloc(size + 1);
if (ei_decode_string(buf->buff, &buf->index, value)) {
fail = SWITCH_TRUE;
break;
}
if (!fail && !strcmp(key, "body")) {
switch_safe_free(event->body);
event->body = value;
} else if (!fail) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP, key, value);
}
/* Do not free malloc here! The above commands utilize the raw allocated memory and skip any copying/duplication. Faster. */
if (!fail && !strcmp(key, "body")) {
switch_safe_free(event->body);
event->body = value;
} else if (!fail) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP, key, value);
}
/* Do not free malloc here! The above commands utilize the raw allocated memory and skip any copying/duplication. Faster. */
}
if (headerlength != i || fail) {
@ -763,30 +787,30 @@ static switch_status_t handle_msg_sendmsg(listener_t *listener, int arity, ei_x_
char key[1024];
char *value;
int type;
int size;
int type;
int size;
int i = 0;
switch_bool_t fail = SWITCH_FALSE;
while (!ei_decode_tuple_header(buf->buff, &buf->index, &arity) && arity == 2) {
i++;
ei_get_type(buf->buff, &buf->index, &type, &size);
ei_get_type(buf->buff, &buf->index, &type, &size);
if ((size > (sizeof(key) - 1)) || ei_decode_string(buf->buff, &buf->index, key)) {
fail = SWITCH_TRUE;
break;
}
ei_get_type(buf->buff, &buf->index, &type, &size);
value = malloc(size + 1);
ei_get_type(buf->buff, &buf->index, &type, &size);
value = malloc(size + 1);
if (ei_decode_string(buf->buff, &buf->index, value)) {
fail = SWITCH_TRUE;
fail = SWITCH_TRUE;
break;
}
if (!fail) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP, key, value);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM | SWITCH_STACK_NODUP, key, value);
}
}
@ -794,6 +818,7 @@ static switch_status_t handle_msg_sendmsg(listener_t *listener, int arity, ei_x_
ei_x_encode_tuple_header(rbuf, 2);
ei_x_encode_atom(rbuf, "error");
ei_x_encode_atom(rbuf, "badarg");
switch_event_destroy(&event);
} else {
if (switch_core_session_queue_private_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
ei_x_encode_atom(rbuf, "ok");
@ -801,6 +826,7 @@ static switch_status_t handle_msg_sendmsg(listener_t *listener, int arity, ei_x_
ei_x_encode_tuple_header(rbuf, 2);
ei_x_encode_atom(rbuf, "error");
ei_x_encode_atom(rbuf, "badmem");
switch_event_destroy(&event);
}
}
@ -1020,12 +1046,15 @@ static switch_status_t handle_msg_atom(listener_t *listener, erlang_msg * msg, e
if (switch_test_flag(listener, LFLAG_EVENTS)) {
uint8_t x = 0;
switch_clear_flag_locked(listener, LFLAG_EVENTS);
switch_thread_rwlock_wrlock(listener->event_rwlock);
for (x = 0; x <= SWITCH_EVENT_ALL; x++) {
listener->event_list[x] = 0;
}
/* wipe the hash */
switch_core_hash_destroy(&listener->event_hash);
switch_core_hash_init(&listener->event_hash, listener->pool);
switch_core_hash_delete_multi(listener->event_hash, NULL, NULL);
switch_thread_rwlock_unlock(listener->event_rwlock);
ei_x_encode_atom(rbuf, "ok");
} else {
ei_x_encode_tuple_header(rbuf, 2);
@ -1040,12 +1069,15 @@ static switch_status_t handle_msg_atom(listener_t *listener, erlang_msg * msg, e
/*purge the event queue */
while (switch_queue_trypop(session->event_queue, &pop) == SWITCH_STATUS_SUCCESS);
switch_thread_rwlock_wrlock(session->event_rwlock);
for (x = 0; x <= SWITCH_EVENT_ALL; x++) {
session->event_list[x] = 0;
}
/* wipe the hash */
switch_core_hash_destroy(&session->event_hash);
switch_core_hash_init(&session->event_hash, session->pool);
switch_core_hash_delete_multi(session->event_hash, NULL, NULL);
switch_thread_rwlock_unlock(session->event_rwlock);
ei_x_encode_atom(rbuf, "ok");
} else {
ei_x_encode_tuple_header(rbuf, 2);
@ -1076,13 +1108,14 @@ static switch_status_t handle_msg_atom(listener_t *listener, erlang_msg * msg, e
static switch_status_t handle_ref_tuple(listener_t *listener, erlang_msg * msg, ei_x_buff * buf, ei_x_buff * rbuf)
{
erlang_ref ref;
erlang_pid *pid;
erlang_pid pid;
char hash[100];
int arity;
const void *key;
void *val;
session_elem_t *se;
switch_hash_index_t *iter;
int found = 0;
ei_decode_tuple_header(buf->buff, &buf->index, &arity);
@ -1091,15 +1124,7 @@ static switch_status_t handle_ref_tuple(listener_t *listener, erlang_msg * msg,
return SWITCH_STATUS_FALSE;
}
if (!(pid = malloc(sizeof(erlang_pid)))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error\n");
ei_x_encode_tuple_header(rbuf, 2);
ei_x_encode_atom(rbuf, "error");
ei_x_encode_atom(rbuf, "badmem");
return SWITCH_STATUS_SUCCESS;
}
if (ei_decode_pid(buf->buff, &buf->index, pid)) {
if (ei_decode_pid(buf->buff, &buf->index, &pid)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid pid in a reference/pid tuple\n");
return SWITCH_STATUS_FALSE;
}
@ -1113,32 +1138,32 @@ static switch_status_t handle_ref_tuple(listener_t *listener, erlang_msg * msg,
switch_hash_this(iter, &key, NULL, &val);
se = (session_elem_t*)val;
if (se->spawn_reply && !strncmp(se->spawn_reply->hash, hash, 100)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "found matching session for %s : %s\n", hash, se->uuid_str);
switch_mutex_lock(se->spawn_reply->mutex);
if (se->spawn_reply->state == reply_not_ready) {
switch_thread_cond_wait(se->spawn_reply->ready_or_found, se->spawn_reply->mutex);
}
if (se->spawn_reply->state == reply_waiting) {
se->spawn_reply->pid = pid;
switch_thread_cond_signal(se->spawn_reply->ready_or_found);
ei_x_encode_atom(rbuf, "ok");
switch_thread_rwlock_unlock(listener->session_rwlock);
switch_mutex_unlock(se->spawn_reply->mutex);
return SWITCH_STATUS_SUCCESS;
}
switch_mutex_lock(se->spawn_reply->mutex);
se->spawn_reply->pid = switch_core_alloc(se->pool, sizeof(erlang_pid));
switch_assert(se->spawn_reply->pid != NULL);
memcpy(se->spawn_reply->pid, &pid, sizeof(erlang_pid));
switch_thread_cond_signal(se->spawn_reply->ready_or_found);
switch_mutex_unlock(se->spawn_reply->mutex);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "get_pid came in too late for %s; %s\n", hash, se->uuid_str);
found++;
break;
}
}
switch_thread_rwlock_unlock(listener->session_rwlock);
ei_x_encode_tuple_header(rbuf, 2);
ei_x_encode_atom(rbuf, "error");
ei_x_encode_atom(rbuf, "notfound");
switch_safe_free(pid); /* don't need it */
if (found) {
ei_x_encode_atom(rbuf, "ok");
} else {
ei_x_encode_tuple_header(rbuf, 2);
ei_x_encode_atom(rbuf, "error");
ei_x_encode_atom(rbuf, "notfound");
}
return SWITCH_STATUS_SUCCESS;
}
@ -1240,6 +1265,7 @@ int handle_msg(listener_t *listener, erlang_msg * msg, ei_x_buff * buf, ei_x_buf
buf->index = 0;
ei_decode_version(buf->buff, &buf->index, &version);
ei_get_type(buf->buff, &buf->index, &type, &size);
switch (type) {
case ERL_SMALL_TUPLE_EXT:
case ERL_LARGE_TUPLE_EXT:
@ -1288,11 +1314,8 @@ int handle_msg(listener_t *listener, erlang_msg * msg, ei_x_buff * buf, ei_x_buf
#ifdef EI_DEBUG
ei_x_print_msg(rbuf, &msg->from, 1);
#endif
return SWITCH_STATUS_SUCCESS != ret;
if (SWITCH_STATUS_SUCCESS == ret)
return 0;
else /* SWITCH_STATUS_TERM */
return 1;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Empty reply, supressing\n");
return 0;

View File

@ -26,6 +26,7 @@
* Anthony Minessale II <anthm@freeswitch.org>
* Andrew Thompson <andrew@hijacked.us>
* Rob Charlton <rob.charlton@savageminds.com>
* Tamas Cseke <tamas.cseke@virtual-call-center.eu>
*
*
* mod_erlang_event.c -- Erlang Event Handler derived from mod_event_socket
@ -44,6 +45,7 @@ SWITCH_MODULE_DEFINITION(mod_erlang_event, mod_erlang_event_load, mod_erlang_eve
static switch_memory_pool_t *module_pool = NULL;
static void remove_listener(listener_t *listener);
static void destroy_listener(listener_t *listener);
static switch_status_t state_handler(switch_core_session_t *session);
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_pref_ip, prefs.ip);
@ -53,12 +55,15 @@ SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_pref_nodename, prefs.nodename);
static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t *thread, void *obj);
static void launch_listener_thread(listener_t *listener);
session_elem_t *find_session_elem_by_uuid(listener_t *listener, const char *uuid);
static switch_status_t socket_logger(const switch_log_node_t *node, switch_log_level_t level)
{
listener_t *l;
switch_thread_rwlock_rdlock(globals.listener_rwlock);
for (l = listen_list.listeners; l; l = l->next) {
if (switch_test_flag(l, LFLAG_LOG) && l->level >= node->level) {
switch_log_node_t *dnode = switch_log_node_dup(node);
@ -79,6 +84,7 @@ static switch_status_t socket_logger(const switch_log_node_t *node, switch_log_l
l->lost_logs++;
}
}
}
switch_thread_rwlock_unlock(globals.listener_rwlock);
@ -131,12 +137,11 @@ static void send_event_to_attached_sessions(listener_t *listener, switch_event_t
return;
}
switch_thread_rwlock_rdlock(listener->session_rwlock);
s = (session_elem_t*)switch_core_hash_find(listener->sessions, uuid);
switch_thread_rwlock_unlock(listener->session_rwlock);
if (s) {
if ((s = (session_elem_t*)find_session_elem_by_uuid(listener, uuid))) {
int send = 0;
switch_thread_rwlock_rdlock(s->event_rwlock);
if (s->event_list[SWITCH_EVENT_ALL]) {
send = 1;
} else if ((s->event_list[event->event_id])) {
@ -145,6 +150,8 @@ static void send_event_to_attached_sessions(listener_t *listener, switch_event_t
}
}
switch_thread_rwlock_unlock(s->event_rwlock);
if (send) {
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(s->uuid_str), SWITCH_LOG_DEBUG, "Sending event %s to attached session %s\n",
switch_event_name(event->event_id), s->uuid_str);
@ -161,7 +168,9 @@ static void send_event_to_attached_sessions(listener_t *listener, switch_event_t
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(s->uuid_str), SWITCH_LOG_DEBUG, "Ignoring event %s for attached session %s\n",
switch_event_name(event->event_id), s->uuid_str);
}
switch_thread_rwlock_unlock(s->rwlock);
}
}
static void event_handler(switch_event_t *event)
@ -175,9 +184,10 @@ static void event_handler(switch_event_t *event)
return;
}
switch_thread_rwlock_rdlock(globals.listener_rwlock);
lp = listen_list.listeners;
switch_thread_rwlock_rdlock(globals.listener_rwlock);
while (lp) {
uint8_t send = 0;
@ -194,6 +204,8 @@ static void event_handler(switch_event_t *event)
continue;
}
switch_thread_rwlock_rdlock(l->event_rwlock);
if (l->event_list[SWITCH_EVENT_ALL]) {
send = 1;
} else if ((l->event_list[event->event_id])) {
@ -202,6 +214,7 @@ static void event_handler(switch_event_t *event)
}
}
switch_thread_rwlock_unlock(l->event_rwlock);
if (send) {
if (switch_event_dup(&clone, event) == SWITCH_STATUS_SUCCESS) {
@ -251,7 +264,7 @@ static void close_socket(int *sock)
static void add_listener(listener_t *listener)
{
/* add me to the listeners so I get events */
/* add me to the listeners so I get events */
switch_thread_rwlock_wrlock(globals.listener_rwlock);
listener->next = listen_list.listeners;
listen_list.listeners = listener;
@ -277,7 +290,7 @@ static void remove_listener(listener_t *listener)
switch_thread_rwlock_unlock(globals.listener_rwlock);
}
/* Search for a listener already talking to the specified node */
/* Search for a listener already talking to the specified node and lock for reading*/
static listener_t *find_listener(char *nodename)
{
listener_t *l = NULL;
@ -285,6 +298,7 @@ static listener_t *find_listener(char *nodename)
switch_thread_rwlock_rdlock(globals.listener_rwlock);
for (l = listen_list.listeners; l; l = l->next) {
if (!strncmp(nodename, l->peer_nodename, MAXNODELEN)) {
switch_thread_rwlock_rdlock(l->rwlock);
break;
}
}
@ -303,28 +317,42 @@ static void add_session_elem_to_listener(listener_t *listener, session_elem_t *s
static void remove_session_elem_from_listener(listener_t *listener, session_elem_t *session_element)
{
switch_thread_rwlock_wrlock(listener->session_rwlock);
switch_core_hash_delete(listener->sessions, session_element->uuid_str);
switch_thread_rwlock_unlock(listener->session_rwlock);
}
static void destroy_session_elem(session_elem_t *session_element)
{
switch_core_session_t *session;
/* wait for readers */
switch_thread_rwlock_wrlock(session_element->rwlock);
switch_thread_rwlock_unlock(session_element->rwlock);
if ((session = switch_core_session_locate(session_element->uuid_str))) {
switch_channel_clear_flag(switch_core_session_get_channel(session), CF_CONTROLLED);
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_channel_set_private(channel, "_erlang_session_", NULL);
switch_channel_clear_flag(channel, CF_CONTROLLED);
switch_core_session_rwunlock(session);
}
switch_core_destroy_memory_pool(&session_element->pool);
/*switch_safe_free(s); */
}
static void remove_session_elem_from_listener_locked(listener_t *listener, session_elem_t *session_element)
session_elem_t *find_session_elem_by_uuid(listener_t *listener, const char *uuid)
{
switch_thread_rwlock_wrlock(listener->session_rwlock);
remove_session_elem_from_listener(listener, session_element);
switch_thread_rwlock_unlock(listener->session_rwlock);
}
session_elem_t *session = NULL;
switch_thread_rwlock_rdlock(listener->session_rwlock);
if ((session = (session_elem_t*)switch_core_hash_find(listener->sessions, uuid))) {
switch_thread_rwlock_rdlock(session->rwlock);
}
switch_thread_rwlock_unlock(listener->session_rwlock);
return session;
}
session_elem_t *find_session_elem_by_pid(listener_t *listener, erlang_pid *pid)
{
@ -336,15 +364,16 @@ session_elem_t *find_session_elem_by_pid(listener_t *listener, erlang_pid *pid)
switch_thread_rwlock_rdlock(listener->session_rwlock);
for (iter = switch_hash_first(NULL, listener->sessions); iter; iter = switch_hash_next(iter)) {
switch_hash_this(iter, &key, NULL, &val);
session = (session_elem_t*)val;
if (session->process.type == ERLANG_PID && !ei_compare_pids(pid, &session->process.pid)) {
switch_thread_rwlock_unlock(listener->session_rwlock);
return session;
if (((session_elem_t*)val)->process.type == ERLANG_PID && !ei_compare_pids(pid, &((session_elem_t*)val)->process.pid)) {
session = (session_elem_t*)val;
switch_thread_rwlock_rdlock(session->rwlock);
break;
}
}
switch_thread_rwlock_unlock(listener->session_rwlock);
return NULL;
return session;
}
@ -362,6 +391,7 @@ static switch_xml_t erlang_fetch(const char *sectionstr, const char *tag_name, c
switch_xml_t xml = NULL;
ei_x_buff *rep;
ei_x_buff buf;
ei_x_new_with_version(&buf);
switch_uuid_get(&uuid);
@ -403,6 +433,7 @@ static switch_xml_t erlang_fetch(const char *sectionstr, const char *tag_name, c
/* Create a new fetch object. */
p = malloc(sizeof(*p));
switch_thread_cond_create(&p->ready_or_found, module_pool);
/* TODO module pool */
switch_mutex_init(&p->mutex, SWITCH_MUTEX_UNNESTED, module_pool);
p->state = reply_not_ready;
p->reply = NULL;
@ -430,8 +461,7 @@ static switch_xml_t erlang_fetch(const char *sectionstr, const char *tag_name, c
/* Tell the threads to be ready, and wait five seconds for a reply. */
switch_mutex_lock(p->mutex);
//p->state = reply_waiting;
switch_thread_cond_timedwait(p->ready_or_found,
p->mutex, 5000000);
switch_thread_cond_timedwait(p->ready_or_found, p->mutex, 5000000);
if (!p->reply) {
p->state = reply_timeout;
switch_mutex_unlock(p->mutex);
@ -508,6 +538,7 @@ static switch_status_t notify_new_session(listener_t *listener, session_elem_t *
if (!(session = switch_core_session_locate(session_element->uuid_str))) {
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(session_element->uuid_str), SWITCH_LOG_WARNING, "Can't locate session %s\n", session_element->uuid_str);
switch_event_destroy(&call_event);
return SWITCH_STATUS_FALSE;
}
@ -516,6 +547,7 @@ static switch_status_t notify_new_session(listener_t *listener, session_elem_t *
switch_caller_profile_event_set_data(switch_channel_get_caller_profile(channel), "Channel", call_event);
switch_channel_event_set_data(channel, call_event);
switch_core_session_rwunlock(session);
/* TODO reply? sure? */
switch_event_add_header_string(call_event, SWITCH_STACK_BOTTOM, "Content-Type", "command/reply");
switch_event_add_header_string(call_event, SWITCH_STACK_BOTTOM, "Reply-Text", "+OK\n");
@ -551,6 +583,7 @@ static switch_status_t check_attached_sessions(listener_t *listener)
/* event used to track sessions to remove */
switch_event_t *event = NULL;
switch_event_header_t *header = NULL;
switch_event_create_subclass(&event, SWITCH_EVENT_CLONE, NULL);
switch_assert(event);
/* check up on all the attached sessions -
@ -558,6 +591,8 @@ static switch_status_t check_attached_sessions(listener_t *listener)
if they have pending events in their queues then send them
if the session has finished then clean it up
*/
/* TODO try to minimize critical section */
switch_thread_rwlock_rdlock(listener->session_rwlock);
for (iter = switch_hash_first(NULL, listener->sessions); iter; iter = switch_hash_next(iter)) {
switch_hash_this(iter, &key, NULL, &value);
@ -574,7 +609,7 @@ static switch_status_t check_attached_sessions(listener_t *listener)
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "delete", (const char *) key);
continue;
}
switch_set_flag(sp, LFLAG_OUTBOUND_INIT);
switch_set_flag_locked(sp, LFLAG_OUTBOUND_INIT);
}
if (switch_test_flag(sp, LFLAG_SESSION_COMPLETE)) {
@ -640,18 +675,16 @@ static switch_status_t check_attached_sessions(listener_t *listener)
}
}
switch_thread_rwlock_unlock(listener->session_rwlock);
/* release the read lock and get a write lock */
switch_thread_rwlock_wrlock(listener->session_rwlock);
/* do the deferred remove */
for (header = event->headers; header; header = header->next) {
if ((sp = (session_elem_t*)switch_core_hash_find(listener->sessions, header->value))) {
if ((sp = (session_elem_t*)find_session_elem_by_uuid(listener, header->value))) {
remove_session_elem_from_listener(listener, sp);
switch_thread_rwlock_unlock(sp->rwlock);
destroy_session_elem(sp);
}
}
switch_thread_rwlock_unlock(listener->session_rwlock);
/* remove the temporary event */
switch_event_destroy(&event);
@ -749,29 +782,32 @@ static void handle_exit(listener_t *listener, erlang_pid * pid)
session_elem_t *s;
remove_binding(NULL, pid); /* TODO - why don't we pass the listener as the first argument? */
if ((s = find_session_elem_by_pid(listener, pid))) {
if (s->channel_state < CS_HANGUP) {
switch_core_session_t *session;
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(s->uuid_str), SWITCH_LOG_WARNING, "Outbound session for %s exited unexpectedly!\n", s->uuid_str);
if ((session = switch_core_session_locate(s->uuid_str))) {
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_channel_set_private(channel, "_erlang_session_", NULL);
switch_channel_set_private(channel, "_erlang_listener_", NULL);
switch_core_event_hook_remove_state_change(session, state_handler);
switch_core_session_rwunlock(session);
if ((s = find_session_elem_by_pid(listener, pid))) {
switch_core_session_t *session = NULL;
if ((session = switch_core_session_locate(s->uuid_str))) {
switch_channel_t *channel = switch_core_session_get_channel(session);
if (switch_channel_get_state(channel) < CS_HANGUP) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Outbound session exited unexpectedly %s!\n", s->uuid_str);
}
/* TODO - if a spawned process that was handling an outbound call fails.. what do we do with the call? */
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
switch_core_session_rwunlock(session);
}
remove_session_elem_from_listener_locked(listener, s);
destroy_session_elem(s);
switch_thread_rwlock_unlock(s->rwlock);
}
if (listener->log_process.type == ERLANG_PID && !ei_compare_pids(&listener->log_process.pid, pid)) {
void *pop;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Log handler process for node %s exited\n", pid->node);
/*purge the log queue */
/* TODO don't we want to clear flag first? */
while (switch_queue_trypop(listener->log_queue, &pop) == SWITCH_STATUS_SUCCESS) {
switch_log_node_t *dnode = (switch_log_node_t *) pop;
switch_log_node_free(&dnode);
@ -787,6 +823,7 @@ static void handle_exit(listener_t *listener, erlang_pid * pid)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Event handler process for node %s exited\n", pid->node);
/*purge the event queue */
/* TODO don't we want to clear flag first? */
while (switch_queue_trypop(listener->event_queue, &pop) == SWITCH_STATUS_SUCCESS) {
switch_event_t *pevent = (switch_event_t *) pop;
switch_event_destroy(&pevent);
@ -795,12 +832,13 @@ static void handle_exit(listener_t *listener, erlang_pid * pid)
if (switch_test_flag(listener, LFLAG_EVENTS)) {
uint8_t x = 0;
switch_clear_flag_locked(listener, LFLAG_EVENTS);
switch_thread_rwlock_wrlock(listener->event_rwlock);
for (x = 0; x <= SWITCH_EVENT_ALL; x++) {
listener->event_list[x] = 0;
}
/* wipe the hash */
switch_core_hash_destroy(&listener->event_hash);
switch_core_hash_init(&listener->event_hash, listener->pool);
switch_core_hash_delete_multi(listener->event_hash, NULL, NULL);
switch_thread_rwlock_unlock(listener->event_rwlock);
}
}
}
@ -865,6 +903,7 @@ static void listener_main_loop(listener_t *listener)
case ERL_EXIT:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "erl_exit from %s <%d.%d.%d>\n", msg.from.node, msg.from.creation, msg.from.num,
msg.from.serial);
handle_exit(listener, &msg.from);
break;
default:
@ -874,7 +913,7 @@ static void listener_main_loop(listener_t *listener)
break;
case ERL_ERROR:
if (erl_errno != ETIMEDOUT && erl_errno != EAGAIN) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "erl_error\n");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "erl_error: status=%d, erl_errno=%d errno=%d\n", status, erl_errno, errno);
}
break;
default:
@ -892,6 +931,11 @@ static void listener_main_loop(listener_t *listener)
return;
}
}
if (prefs.done) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "shutting down listener\n");
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "listener exit: status=%d, erl_errno=%d errno=%d\n", status, erl_errno, errno);
}
}
static switch_bool_t check_inbound_acl(listener_t *listener)
@ -941,10 +985,6 @@ static switch_bool_t check_inbound_acl(listener_t *listener)
static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t *thread, void *obj)
{
listener_t *listener = (listener_t *) obj;
session_elem_t *s;
const void *key;
void *value;
switch_hash_index_t *iter;
switch_mutex_lock(globals.listener_count_mutex);
prefs.threads++;
@ -963,38 +1003,10 @@ static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t *thread, void *obj)
listener_main_loop(listener);
}
/* clean up */
remove_listener(listener);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Session complete, waiting for children\n");
switch_thread_rwlock_wrlock(listener->rwlock);
if (listener->sockfd) {
close_socket(&listener->sockfd);
}
switch_thread_rwlock_unlock(listener->rwlock);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connection Closed\n");
switch_core_hash_destroy(&listener->event_hash);
/* remove any bindings for this connection */
remove_binding(listener, NULL);
/* clean up all the attached sessions */
switch_thread_rwlock_wrlock(listener->session_rwlock);
for (iter = switch_hash_first(NULL, listener->sessions); iter; iter = switch_hash_next(iter)) {
switch_hash_this(iter, &key, NULL, &value);
s = (session_elem_t*)value;
destroy_session_elem(s);
}
switch_thread_rwlock_unlock(listener->session_rwlock);
if (listener->pool) {
switch_memory_pool_t *pool = listener->pool;
switch_core_destroy_memory_pool(&pool);
}
remove_listener(listener);
destroy_listener(listener);
switch_mutex_lock(globals.listener_count_mutex);
prefs.threads--;
@ -1156,43 +1168,46 @@ static int config(void)
return 0;
}
static listener_t *new_listener(struct ei_cnode_s *ec, int clientfd)
{
switch_memory_pool_t *listener_pool = NULL;
switch_memory_pool_t *pool = NULL;
listener_t *listener = NULL;
if (switch_core_new_memory_pool(&listener_pool) != SWITCH_STATUS_SUCCESS) {
if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "OH OH no pool\n");
return NULL;
}
if (!(listener = switch_core_alloc(listener_pool, sizeof(*listener)))) {
if (!(listener = switch_core_alloc(pool, sizeof(*listener)))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error\n");
switch_core_destroy_memory_pool(&pool);
return NULL;
}
memset(listener, 0, sizeof(*listener));
switch_thread_rwlock_create(&listener->rwlock, listener_pool);
switch_queue_create(&listener->event_queue, SWITCH_CORE_QUEUE_LEN, listener_pool);
switch_queue_create(&listener->log_queue, SWITCH_CORE_QUEUE_LEN, listener_pool);
switch_queue_create(&listener->event_queue, SWITCH_CORE_QUEUE_LEN, pool);
switch_queue_create(&listener->log_queue, SWITCH_CORE_QUEUE_LEN, pool);
listener->sockfd = clientfd;
listener->pool = listener_pool;
listener_pool = NULL;
listener->pool = pool;
listener->ec = switch_core_alloc(listener->pool, sizeof(ei_cnode));
memcpy(listener->ec, ec, sizeof(ei_cnode));
listener->level = SWITCH_LOG_DEBUG;
switch_mutex_init(&listener->flag_mutex, SWITCH_MUTEX_NESTED, listener->pool);
switch_mutex_init(&listener->sock_mutex, SWITCH_MUTEX_NESTED, listener->pool);
switch_thread_rwlock_create(&listener->rwlock, pool);
switch_thread_rwlock_create(&listener->event_rwlock, pool);
switch_thread_rwlock_create(&listener->session_rwlock, listener->pool);
switch_core_hash_init(&listener->event_hash, listener->pool);
switch_core_hash_init(&listener->sessions, listener->pool);
return listener;
}
static listener_t *new_outbound_listener(char *node)
static listener_t *new_outbound_listener_locked(char *node)
{
listener_t *listener = NULL;
struct ei_cnode_s ec;
@ -1206,27 +1221,67 @@ static listener_t *new_outbound_listener(char *node)
#endif
if ((clientfd = ei_connect(&ec, node)) < 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error connecting to node %s (erl_errno=%d, errno=%d)!\n", node, erl_errno, errno);
return NULL;
}
listener = new_listener(&ec, clientfd);
listener->peer_nodename = switch_core_strdup(listener->pool, node);
}
switch_thread_rwlock_rdlock(listener->rwlock);
return listener;
}
void destroy_listener(listener_t * listener)
{
session_elem_t *s = NULL;
const void *key;
void *value;
switch_hash_index_t *iter;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Session complete, waiting for children\n");
switch_thread_rwlock_wrlock(listener->rwlock);
if (listener->sockfd) {
close_socket(&listener->sockfd);
}
switch_core_hash_destroy(&listener->event_hash);
/* remove any bindings for this connection */
remove_binding(listener, NULL);
/* clean up all the attached sessions */
switch_thread_rwlock_wrlock(listener->session_rwlock);
for (iter = switch_hash_first(NULL, listener->sessions); iter; iter = switch_hash_next(iter)) {
switch_hash_this(iter, &key, NULL, &value);
s = (session_elem_t*)value;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Orphaning call %s\n", s->uuid_str);
destroy_session_elem(s);
}
switch_thread_rwlock_unlock(listener->session_rwlock);
switch_thread_rwlock_unlock(listener->rwlock);
if (listener->pool) {
switch_memory_pool_t *pool = listener->pool;
switch_core_destroy_memory_pool(&pool);
}
}
static switch_status_t state_handler(switch_core_session_t *session)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_channel_state_t state = switch_channel_get_state(channel);
session_elem_t *session_element = switch_channel_get_private(channel, "_erlang_session_");
/*listener_t* listener = switch_channel_get_private(channel, "_erlang_listener_"); */
if (session_element) {
session_element->channel_state = state;
if (state == CS_DESTROY) {
/* indicate that once all the events in the event queue are done
* we can throw this away */
switch_set_flag(session_element, LFLAG_SESSION_COMPLETE);
switch_set_flag_locked(session_element, LFLAG_SESSION_COMPLETE);
}
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "unable to update channel state for %s to %s\n", switch_core_session_get_uuid(session),
@ -1266,10 +1321,12 @@ session_elem_t *session_elem_create(listener_t *listener, switch_core_session_t
session_element->event_list[x] = 0;
}
switch_thread_rwlock_create(&session_element->rwlock, session_element->pool);
switch_thread_rwlock_create(&session_element->event_rwlock, session_element->pool);
session_element->event_list[SWITCH_EVENT_ALL] = 1; /* defaults to everything */
switch_channel_set_private(channel, "_erlang_session_", session_element);
switch_channel_set_private(channel, "_erlang_listener_", listener);
switch_core_event_hook_add_state_change(session, state_handler);
@ -1298,6 +1355,7 @@ session_elem_t *attach_call_to_pid(listener_t *listener, erlang_pid * pid, switc
memcpy(&session_element->process.pid, pid, sizeof(erlang_pid));
/* attach the session to the listener */
add_session_elem_to_listener(listener, session_element);
/* TODO link before added to listener? */
ei_link(listener, ei_self(listener->ec), pid);
return session_element;
@ -1308,30 +1366,27 @@ session_elem_t *attach_call_to_spawned_process(listener_t *listener, char *modul
/* create a session list element */
session_elem_t *session_element = session_elem_create(listener, session);
char hash[100];
//void *p = NULL;
spawn_reply_t *p;
erlang_ref ref;
switch_set_flag(session_element, LFLAG_WAITING_FOR_PID);
/* attach the session to the listener */
add_session_elem_to_listener(listener, session_element);
ei_init_ref(listener->ec, &ref);
ei_hash_ref(&ref, hash);
/* insert the waiting marker */
p = switch_core_alloc(session_element->pool, sizeof(*p));
switch_thread_cond_create(&p->ready_or_found, session_element->pool);
switch_mutex_init(&p->mutex, SWITCH_MUTEX_UNNESTED, session_element->pool);
p->state = reply_not_ready;
p->hash = hash;
p->hash = switch_core_strdup(session_element->pool, hash);
p->pid = NULL;
session_element->spawn_reply = p;
switch_mutex_lock(p->mutex);
p->state = reply_waiting;
/* insert the waiting marker */
switch_set_flag(session_element, LFLAG_WAITING_FOR_PID);
/* attach the session to the listener */
add_session_elem_to_listener(listener, session_element);
if (!strcmp(function, "!")) {
/* send a message to request a pid */
@ -1361,13 +1416,12 @@ session_elem_t *attach_call_to_spawned_process(listener_t *listener, char *modul
*/
}
switch_thread_cond_timedwait(p->ready_or_found,
p->mutex, 5000000);
switch_thread_cond_timedwait(p->ready_or_found, p->mutex, 5000000);
if (!p->pid) {
p->state = reply_timeout;
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Timed out when waiting for outbound pid %s %s\n", hash, session_element->uuid_str);
remove_session_elem_from_listener_locked(listener, session_element);
destroy_session_elem(session_element);
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
return NULL;
}
@ -1377,13 +1431,10 @@ session_elem_t *attach_call_to_spawned_process(listener_t *listener, char *modul
memcpy(&session_element->process.pid, p->pid, sizeof(erlang_pid));
session_element->spawn_reply = NULL;
switch_clear_flag(session_element, LFLAG_OUTBOUND_INIT);
switch_clear_flag(session_element, LFLAG_WAITING_FOR_PID);
switch_clear_flag_locked(session_element, LFLAG_WAITING_FOR_PID);
ei_link(listener, ei_self(listener->ec), &session_element->process.pid);
switch_safe_free(p->pid);
return session_element;
}
@ -1414,7 +1465,6 @@ SWITCH_STANDARD_APP(erlang_outbound_function)
char *argv[80] = { 0 }, *argv2[80] = { 0 };
char *mydata, *myarg;
char uuid[SWITCH_UUID_FORMATTED_LENGTH + 1];
switch_bool_t new_session = SWITCH_FALSE;
session_elem_t *session_element = NULL;
/* process app arguments */
@ -1460,17 +1510,15 @@ SWITCH_STANDARD_APP(erlang_outbound_function)
/* if there is no listener, then create one */
if (!listener) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Creating new listener for session\n");
new_session = SWITCH_TRUE;
listener = new_outbound_listener(node);
if ((listener = new_outbound_listener_locked(node))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Launching new listener\n");
launch_listener_thread(listener);
}
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Using existing listener for session\n");
}
if (listener) {
if (new_session == SWITCH_TRUE) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Launching new listener\n");
launch_listener_thread(listener);
}
if (module && function) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Creating new spawned session for listener\n");
@ -1480,11 +1528,16 @@ SWITCH_STANDARD_APP(erlang_outbound_function)
session_element = attach_call_to_registered_process(listener, reg_name, session);
}
switch_thread_rwlock_unlock(listener->rwlock);
if (session_element) {
switch_ivr_park(session, NULL);
}
} else {
switch_thread_rwlock_unlock(globals.listener_rwlock);
}
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "exit erlang_outbound_function\n");
}
@ -1523,13 +1576,15 @@ SWITCH_STANDARD_APP(erlang_sendmsg_function)
listener = find_listener(node);
if (!listener) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Creating new listener for sendmsg %s\n", node);
listener = new_outbound_listener(node);
listener = new_outbound_listener_locked(node);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Using existing listener for sendmsg to %s\n", node);
}
if (listener) {
ei_reg_send(listener->ec, listener->sockfd, reg_name, buf.buff, buf.index);
switch_thread_rwlock_unlock(listener->rwlock);
}
}
@ -1598,11 +1653,11 @@ SWITCH_STANDARD_API(erlang_cmd)
stream->write_function(stream, "Outbound session for %s in state %s\n", sp->uuid_str,
switch_channel_state_name(sp->channel_state));
}
switch_thread_rwlock_unlock(l->session_rwlock);
if (empty) {
stream->write_function(stream, "No active sessions for %s\n", argv[1]);
}
switch_thread_rwlock_unlock(l->session_rwlock);
break;
}
}

View File

@ -39,7 +39,8 @@ typedef enum {
} session_flag_t;
typedef enum {
ERLANG_PID = 0,
NONE = 0,
ERLANG_PID,
ERLANG_REG_PROCESS
} process_type;
@ -70,7 +71,6 @@ struct spawn_reply_struct
{
switch_thread_cond_t *ready_or_found;
switch_mutex_t *mutex;
enum reply_state state;
erlang_pid *pid;
char *hash;
};
@ -82,6 +82,8 @@ struct session_elem {
uint32_t flags;
struct erlang_process process;
switch_queue_t *event_queue;
switch_thread_rwlock_t *rwlock;
switch_thread_rwlock_t *event_rwlock;
switch_channel_state_t channel_state;
switch_memory_pool_t *pool;
uint8_t event_list[SWITCH_EVENT_ALL + 1];
@ -128,6 +130,7 @@ struct listener {
uint8_t event_list[SWITCH_EVENT_ALL + 1];
switch_hash_t *event_hash;
switch_thread_rwlock_t *rwlock;
switch_thread_rwlock_t *event_rwlock;
switch_thread_rwlock_t *session_rwlock;
//session_elem_t *session_list;
switch_hash_t *sessions;

View File

@ -1185,7 +1185,7 @@ static switch_status_t read_packet(listener_t *listener, switch_event_t **event,
}
count++;
if (count == 1) {
switch_event_create(event, SWITCH_EVENT_SOCKET_DATA);
switch_event_create(event, SWITCH_EVENT_CLONE);
switch_event_add_header_string(*event, SWITCH_STACK_BOTTOM, "Command", mbuf);
} else if (cur) {
char *var, *val;

View File

@ -91,8 +91,8 @@ public class EventConsumer {
return new SWIGTYPE_p_uint32_t(freeswitchJNI.EventConsumer_node_index_get(swigCPtr, this), true);
}
public EventConsumer(String event_name, String subclass_name) {
this(freeswitchJNI.new_EventConsumer(event_name, subclass_name), true);
public EventConsumer(String event_name, String subclass_name, int len) {
this(freeswitchJNI.new_EventConsumer(event_name, subclass_name, len), true);
}
public int bind(String event_name, String subclass_name) {

View File

@ -81,7 +81,7 @@ class freeswitchJNI {
public final static native long EventConsumer_enodes_get(long jarg1, EventConsumer jarg1_);
public final static native void EventConsumer_node_index_set(long jarg1, EventConsumer jarg1_, long jarg2);
public final static native long EventConsumer_node_index_get(long jarg1, EventConsumer jarg1_);
public final static native long new_EventConsumer(String jarg1, String jarg2);
public final static native long new_EventConsumer(String jarg1, String jarg2, int jarg3);
public final static native void delete_EventConsumer(long jarg1);
public final static native int EventConsumer_bind(long jarg1, EventConsumer jarg1_, String jarg2, String jarg3);
public final static native long EventConsumer_pop(long jarg1, EventConsumer jarg1_, int jarg2, int jarg3);

View File

@ -1587,10 +1587,11 @@ SWIGEXPORT jlong JNICALL Java_org_freeswitch_swig_freeswitchJNI_EventConsumer_1n
}
SWIGEXPORT jlong JNICALL Java_org_freeswitch_swig_freeswitchJNI_new_1EventConsumer(JNIEnv *jenv, jclass jcls, jstring jarg1, jstring jarg2) {
SWIGEXPORT jlong JNICALL Java_org_freeswitch_swig_freeswitchJNI_new_1EventConsumer(JNIEnv *jenv, jclass jcls, jstring jarg1, jstring jarg2, jint jarg3) {
jlong jresult = 0 ;
char *arg1 = (char *) NULL ;
char *arg2 = (char *) "" ;
int arg3 = (int) 5000 ;
EventConsumer *result = 0 ;
(void)jenv;
@ -1605,7 +1606,8 @@ SWIGEXPORT jlong JNICALL Java_org_freeswitch_swig_freeswitchJNI_new_1EventConsum
arg2 = (char *)jenv->GetStringUTFChars(jarg2, 0);
if (!arg2) return 0;
}
result = (EventConsumer *)new EventConsumer((char const *)arg1,(char const *)arg2);
arg3 = (int)jarg3;
result = (EventConsumer *)new EventConsumer((char const *)arg1,(char const *)arg2,arg3);
*(EventConsumer **)&jresult = result;
if (arg1) jenv->ReleaseStringUTFChars(jarg1, (const char *)arg1);
if (arg2) jenv->ReleaseStringUTFChars(jarg2, (const char *)arg2);

View File

@ -3705,18 +3705,23 @@ static int _wrap_new_EventConsumer(lua_State* L) {
int SWIG_arg = -1;
char *arg1 = (char *) NULL ;
char *arg2 = (char *) "" ;
int arg3 = (int) 5000 ;
EventConsumer *result = 0 ;
SWIG_check_num_args("EventConsumer",0,2)
SWIG_check_num_args("EventConsumer",0,3)
if(lua_gettop(L)>=1 && !lua_isstring(L,1)) SWIG_fail_arg("EventConsumer",1,"char const *");
if(lua_gettop(L)>=2 && !lua_isstring(L,2)) SWIG_fail_arg("EventConsumer",2,"char const *");
if(lua_gettop(L)>=3 && !lua_isnumber(L,3)) SWIG_fail_arg("EventConsumer",3,"int");
if(lua_gettop(L)>=1){
arg1 = (char *)lua_tostring(L, 1);
}
if(lua_gettop(L)>=2){
arg2 = (char *)lua_tostring(L, 2);
}
result = (EventConsumer *)new EventConsumer((char const *)arg1,(char const *)arg2);
if(lua_gettop(L)>=3){
arg3 = (int)lua_tonumber(L, 3);
}
result = (EventConsumer *)new EventConsumer((char const *)arg1,(char const *)arg2,arg3);
SWIG_arg=0;
SWIG_NewPointerObj(L,result,SWIGTYPE_p_EventConsumer,1); SWIG_arg++;
return SWIG_arg;

View File

@ -1550,6 +1550,16 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_SIGNAL_BOND_VARIABLE_get() {
}
SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_ORIGINATE_SIGNAL_BOND_VARIABLE_get() {
char * jresult ;
char *result = 0 ;
result = (char *)("originate_signal_bond");
jresult = SWIG_csharp_string_callback((const char *)result);
return jresult;
}
SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_ORIGINATOR_VARIABLE_get() {
char * jresult ;
char *result = 0 ;
@ -11108,7 +11118,7 @@ SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_default_ptime(char * jarg1, u
}
SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_add_registration(char * jarg1, char * jarg2, char * jarg3, char * jarg4, unsigned long jarg5, char * jarg6, char * jarg7, char * jarg8) {
SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_add_registration(char * jarg1, char * jarg2, char * jarg3, char * jarg4, unsigned long jarg5, char * jarg6, char * jarg7, char * jarg8, char * jarg9) {
int jresult ;
char *arg1 = (char *) 0 ;
char *arg2 = (char *) 0 ;
@ -11118,6 +11128,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_add_registration(char * jarg1, cha
char *arg6 = (char *) 0 ;
char *arg7 = (char *) 0 ;
char *arg8 = (char *) 0 ;
char *arg9 = (char *) 0 ;
switch_status_t result;
arg1 = (char *)jarg1;
@ -11128,7 +11139,8 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_add_registration(char * jarg1, cha
arg6 = (char *)jarg6;
arg7 = (char *)jarg7;
arg8 = (char *)jarg8;
result = (switch_status_t)switch_core_add_registration((char const *)arg1,(char const *)arg2,(char const *)arg3,(char const *)arg4,arg5,(char const *)arg6,(char const *)arg7,(char const *)arg8);
arg9 = (char *)jarg9;
result = (switch_status_t)switch_core_add_registration((char const *)arg1,(char const *)arg2,(char const *)arg3,(char const *)arg4,arg5,(char const *)arg6,(char const *)arg7,(char const *)arg8,(char const *)arg9);
jresult = result;
return jresult;
}
@ -25772,6 +25784,18 @@ SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_transfer_to_extension(void * j
}
SWIGEXPORT char * SWIGSTDCALL CSharp_switch_channel_get_partner_uuid(void * jarg1) {
char * jresult ;
switch_channel_t *arg1 = (switch_channel_t *) 0 ;
char *result = 0 ;
arg1 = (switch_channel_t *)jarg1;
result = (char *)switch_channel_get_partner_uuid(arg1);
jresult = SWIG_csharp_string_callback((const char *)result);
return jresult;
}
SWIGEXPORT int SWIGSTDCALL CSharp_switch_buffer_create(void * jarg1, void * jarg2, void * jarg3) {
int jresult ;
switch_memory_pool_t *arg1 = (switch_memory_pool_t *) 0 ;

View File

@ -1663,6 +1663,17 @@ SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_SIGNAL_BOND_VARIABLE_get() {
}
SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_ORIGINATE_SIGNAL_BOND_VARIABLE_get() {
char * jresult ;
char *result = 0 ;
result = (char *) "originate_signal_bond";
jresult = SWIG_csharp_string_callback((const char *)result);
return jresult;
}
SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_ORIGINATOR_VARIABLE_get() {
char * jresult ;
char *result = 0 ;
@ -11427,7 +11438,7 @@ SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_default_ptime(char * jarg1, u
}
SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_add_registration(char * jarg1, char * jarg2, char * jarg3, char * jarg4, unsigned long jarg5, char * jarg6, char * jarg7, char * jarg8) {
SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_add_registration(char * jarg1, char * jarg2, char * jarg3, char * jarg4, unsigned long jarg5, char * jarg6, char * jarg7, char * jarg8, char * jarg9) {
int jresult ;
char *arg1 = (char *) 0 ;
char *arg2 = (char *) 0 ;
@ -11437,6 +11448,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_add_registration(char * jarg1, cha
char *arg6 = (char *) 0 ;
char *arg7 = (char *) 0 ;
char *arg8 = (char *) 0 ;
char *arg9 = (char *) 0 ;
switch_status_t result;
arg1 = (char *)jarg1;
@ -11447,7 +11459,8 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_add_registration(char * jarg1, cha
arg6 = (char *)jarg6;
arg7 = (char *)jarg7;
arg8 = (char *)jarg8;
result = (switch_status_t)switch_core_add_registration((char const *)arg1,(char const *)arg2,(char const *)arg3,(char const *)arg4,arg5,(char const *)arg6,(char const *)arg7,(char const *)arg8);
arg9 = (char *)jarg9;
result = (switch_status_t)switch_core_add_registration((char const *)arg1,(char const *)arg2,(char const *)arg3,(char const *)arg4,arg5,(char const *)arg6,(char const *)arg7,(char const *)arg8,(char const *)arg9);
jresult = result;
return jresult;
}
@ -26470,6 +26483,18 @@ SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_transfer_to_extension(void * j
}
SWIGEXPORT char * SWIGSTDCALL CSharp_switch_channel_get_partner_uuid(void * jarg1) {
char * jresult ;
switch_channel_t *arg1 = (switch_channel_t *) 0 ;
char *result = 0 ;
arg1 = (switch_channel_t *)jarg1;
result = (char *)switch_channel_get_partner_uuid(arg1);
jresult = SWIG_csharp_string_callback((const char *)result);
return jresult;
}
SWIGEXPORT int SWIGSTDCALL CSharp_switch_buffer_create(void * jarg1, void * jarg2, void * jarg3) {
int jresult ;
switch_memory_pool_t *arg1 = (switch_memory_pool_t *) 0 ;
@ -36454,15 +36479,17 @@ SWIGEXPORT unsigned long SWIGSTDCALL CSharp_EventConsumer_node_index_get(void *
}
SWIGEXPORT void * SWIGSTDCALL CSharp_new_EventConsumer(char * jarg1, char * jarg2) {
SWIGEXPORT void * SWIGSTDCALL CSharp_new_EventConsumer(char * jarg1, char * jarg2, int jarg3) {
void * jresult ;
char *arg1 = (char *) NULL ;
char *arg2 = (char *) "" ;
int arg3 = (int) 5000 ;
EventConsumer *result = 0 ;
arg1 = (char *)jarg1;
arg2 = (char *)jarg2;
result = (EventConsumer *)new EventConsumer((char const *)arg1,(char const *)arg2);
arg3 = (int)jarg3;
result = (EventConsumer *)new EventConsumer((char const *)arg1,(char const *)arg2,arg3);
jresult = (void *)result;
return jresult;
}

View File

@ -2671,8 +2671,8 @@ public class freeswitch {
return ret;
}
public static switch_status_t switch_core_add_registration(string user, string realm, string token, string url, uint expires, string network_ip, string network_port, string network_proto) {
switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_add_registration(user, realm, token, url, expires, network_ip, network_port, network_proto);
public static switch_status_t switch_core_add_registration(string user, string realm, string token, string url, uint expires, string network_ip, string network_port, string network_proto, string metadata) {
switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_add_registration(user, realm, token, url, expires, network_ip, network_port, network_proto, metadata);
return ret;
}
@ -4118,6 +4118,11 @@ public class freeswitch {
freeswitchPINVOKE.switch_channel_transfer_to_extension(SWIGTYPE_p_switch_channel.getCPtr(channel), switch_caller_extension.getCPtr(caller_extension));
}
public static string switch_channel_get_partner_uuid(SWIGTYPE_p_switch_channel channel) {
string ret = freeswitchPINVOKE.switch_channel_get_partner_uuid(SWIGTYPE_p_switch_channel.getCPtr(channel));
return ret;
}
public static switch_status_t switch_buffer_create(SWIGTYPE_p_apr_pool_t pool, SWIGTYPE_p_p_switch_buffer buffer, SWIGTYPE_p_switch_size_t max_len) {
switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_buffer_create(SWIGTYPE_p_apr_pool_t.getCPtr(pool), SWIGTYPE_p_p_switch_buffer.getCPtr(buffer), SWIGTYPE_p_switch_size_t.getCPtr(max_len));
if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve();
@ -6130,6 +6135,7 @@ public class freeswitch {
public static readonly string SWITCH_LAST_BRIDGE_VARIABLE = freeswitchPINVOKE.SWITCH_LAST_BRIDGE_VARIABLE_get();
public static readonly string SWITCH_SIGNAL_BRIDGE_VARIABLE = freeswitchPINVOKE.SWITCH_SIGNAL_BRIDGE_VARIABLE_get();
public static readonly string SWITCH_SIGNAL_BOND_VARIABLE = freeswitchPINVOKE.SWITCH_SIGNAL_BOND_VARIABLE_get();
public static readonly string SWITCH_ORIGINATE_SIGNAL_BOND_VARIABLE = freeswitchPINVOKE.SWITCH_ORIGINATE_SIGNAL_BOND_VARIABLE_get();
public static readonly string SWITCH_ORIGINATOR_VARIABLE = freeswitchPINVOKE.SWITCH_ORIGINATOR_VARIABLE_get();
public static readonly string SWITCH_ORIGINATOR_CODEC_VARIABLE = freeswitchPINVOKE.SWITCH_ORIGINATOR_CODEC_VARIABLE_get();
public static readonly string SWITCH_ORIGINATOR_VIDEO_CODEC_VARIABLE = freeswitchPINVOKE.SWITCH_ORIGINATOR_VIDEO_CODEC_VARIABLE_get();
@ -6780,6 +6786,9 @@ class freeswitchPINVOKE {
[DllImport("mod_managed", EntryPoint="CSharp_SWITCH_SIGNAL_BOND_VARIABLE_get")]
public static extern string SWITCH_SIGNAL_BOND_VARIABLE_get();
[DllImport("mod_managed", EntryPoint="CSharp_SWITCH_ORIGINATE_SIGNAL_BOND_VARIABLE_get")]
public static extern string SWITCH_ORIGINATE_SIGNAL_BOND_VARIABLE_get();
[DllImport("mod_managed", EntryPoint="CSharp_SWITCH_ORIGINATOR_VARIABLE_get")]
public static extern string SWITCH_ORIGINATOR_VARIABLE_get();
@ -9094,7 +9103,7 @@ class freeswitchPINVOKE {
public static extern uint switch_default_ptime(string jarg1, uint jarg2);
[DllImport("mod_managed", EntryPoint="CSharp_switch_core_add_registration")]
public static extern int switch_core_add_registration(string jarg1, string jarg2, string jarg3, string jarg4, uint jarg5, string jarg6, string jarg7, string jarg8);
public static extern int switch_core_add_registration(string jarg1, string jarg2, string jarg3, string jarg4, uint jarg5, string jarg6, string jarg7, string jarg8, string jarg9);
[DllImport("mod_managed", EntryPoint="CSharp_switch_core_del_registration")]
public static extern int switch_core_del_registration(string jarg1, string jarg2, string jarg3);
@ -12705,6 +12714,9 @@ class freeswitchPINVOKE {
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_transfer_to_extension")]
public static extern void switch_channel_transfer_to_extension(HandleRef jarg1, HandleRef jarg2);
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_get_partner_uuid")]
public static extern string switch_channel_get_partner_uuid(HandleRef jarg1);
[DllImport("mod_managed", EntryPoint="CSharp_switch_buffer_create")]
public static extern int switch_buffer_create(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3);

View File

@ -709,7 +709,7 @@ public class EventConsumer : IDisposable {
}
}
public EventConsumer(string event_name, string subclass_name) : this(freeswitchPINVOKE.new_EventConsumer(event_name, subclass_name), true) {
public EventConsumer(string event_name, string subclass_name, int len) : this(freeswitchPINVOKE.new_EventConsumer(event_name, subclass_name, len), true) {
}
public int bind(string event_name, string subclass_name) {
@ -2659,8 +2659,8 @@ public class freeswitch {
return ret;
}
public static switch_status_t switch_core_add_registration(string user, string realm, string token, string url, uint expires, string network_ip, string network_port, string network_proto) {
switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_add_registration(user, realm, token, url, expires, network_ip, network_port, network_proto);
public static switch_status_t switch_core_add_registration(string user, string realm, string token, string url, uint expires, string network_ip, string network_port, string network_proto, string metadata) {
switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_add_registration(user, realm, token, url, expires, network_ip, network_port, network_proto, metadata);
return ret;
}
@ -4106,6 +4106,11 @@ public class freeswitch {
freeswitchPINVOKE.switch_channel_transfer_to_extension(SWIGTYPE_p_switch_channel.getCPtr(channel), switch_caller_extension.getCPtr(caller_extension));
}
public static string switch_channel_get_partner_uuid(SWIGTYPE_p_switch_channel channel) {
string ret = freeswitchPINVOKE.switch_channel_get_partner_uuid(SWIGTYPE_p_switch_channel.getCPtr(channel));
return ret;
}
public static switch_status_t switch_buffer_create(SWIGTYPE_p_apr_pool_t pool, SWIGTYPE_p_p_switch_buffer buffer, SWIGTYPE_p_switch_size_t max_len) {
switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_buffer_create(SWIGTYPE_p_apr_pool_t.getCPtr(pool), SWIGTYPE_p_p_switch_buffer.getCPtr(buffer), SWIGTYPE_p_switch_size_t.getCPtr(max_len));
if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve();
@ -6118,6 +6123,7 @@ public class freeswitch {
public static readonly string SWITCH_LAST_BRIDGE_VARIABLE = freeswitchPINVOKE.SWITCH_LAST_BRIDGE_VARIABLE_get();
public static readonly string SWITCH_SIGNAL_BRIDGE_VARIABLE = freeswitchPINVOKE.SWITCH_SIGNAL_BRIDGE_VARIABLE_get();
public static readonly string SWITCH_SIGNAL_BOND_VARIABLE = freeswitchPINVOKE.SWITCH_SIGNAL_BOND_VARIABLE_get();
public static readonly string SWITCH_ORIGINATE_SIGNAL_BOND_VARIABLE = freeswitchPINVOKE.SWITCH_ORIGINATE_SIGNAL_BOND_VARIABLE_get();
public static readonly string SWITCH_ORIGINATOR_VARIABLE = freeswitchPINVOKE.SWITCH_ORIGINATOR_VARIABLE_get();
public static readonly string SWITCH_ORIGINATOR_CODEC_VARIABLE = freeswitchPINVOKE.SWITCH_ORIGINATOR_CODEC_VARIABLE_get();
public static readonly string SWITCH_ORIGINATOR_VIDEO_CODEC_VARIABLE = freeswitchPINVOKE.SWITCH_ORIGINATOR_VIDEO_CODEC_VARIABLE_get();
@ -6764,6 +6770,9 @@ class freeswitchPINVOKE {
[DllImport("mod_managed", EntryPoint="CSharp_SWITCH_SIGNAL_BOND_VARIABLE_get")]
public static extern string SWITCH_SIGNAL_BOND_VARIABLE_get();
[DllImport("mod_managed", EntryPoint="CSharp_SWITCH_ORIGINATE_SIGNAL_BOND_VARIABLE_get")]
public static extern string SWITCH_ORIGINATE_SIGNAL_BOND_VARIABLE_get();
[DllImport("mod_managed", EntryPoint="CSharp_SWITCH_ORIGINATOR_VARIABLE_get")]
public static extern string SWITCH_ORIGINATOR_VARIABLE_get();
@ -9078,7 +9087,7 @@ class freeswitchPINVOKE {
public static extern uint switch_default_ptime(string jarg1, uint jarg2);
[DllImport("mod_managed", EntryPoint="CSharp_switch_core_add_registration")]
public static extern int switch_core_add_registration(string jarg1, string jarg2, string jarg3, string jarg4, uint jarg5, string jarg6, string jarg7, string jarg8);
public static extern int switch_core_add_registration(string jarg1, string jarg2, string jarg3, string jarg4, uint jarg5, string jarg6, string jarg7, string jarg8, string jarg9);
[DllImport("mod_managed", EntryPoint="CSharp_switch_core_del_registration")]
public static extern int switch_core_del_registration(string jarg1, string jarg2, string jarg3);
@ -12689,6 +12698,9 @@ class freeswitchPINVOKE {
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_transfer_to_extension")]
public static extern void switch_channel_transfer_to_extension(HandleRef jarg1, HandleRef jarg2);
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_get_partner_uuid")]
public static extern string switch_channel_get_partner_uuid(HandleRef jarg1);
[DllImport("mod_managed", EntryPoint="CSharp_switch_buffer_create")]
public static extern int switch_buffer_create(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3);
@ -14904,7 +14916,7 @@ class freeswitchPINVOKE {
public static extern uint EventConsumer_node_index_get(HandleRef jarg1);
[DllImport("mod_managed", EntryPoint="CSharp_new_EventConsumer")]
public static extern IntPtr new_EventConsumer(string jarg1, string jarg2);
public static extern IntPtr new_EventConsumer(string jarg1, string jarg2, int jarg3);
[DllImport("mod_managed", EntryPoint="CSharp_delete_EventConsumer")]
public static extern void delete_EventConsumer(HandleRef jarg1);

View File

@ -4675,6 +4675,7 @@ XS(_wrap_new_EventConsumer) {
{
char *arg1 = (char *) NULL ;
char *arg2 = (char *) "" ;
int arg3 = (int) 5000 ;
EventConsumer *result = 0 ;
int res1 ;
char *buf1 = 0 ;
@ -4682,11 +4683,13 @@ XS(_wrap_new_EventConsumer) {
int res2 ;
char *buf2 = 0 ;
int alloc2 = 0 ;
int val3 ;
int ecode3 = 0 ;
int argvi = 0;
dXSARGS;
if ((items < 0) || (items > 2)) {
SWIG_croak("Usage: new_EventConsumer(event_name,subclass_name);");
if ((items < 0) || (items > 3)) {
SWIG_croak("Usage: new_EventConsumer(event_name,subclass_name,len);");
}
if (items > 0) {
res1 = SWIG_AsCharPtrAndSize(ST(0), &buf1, NULL, &alloc1);
@ -4702,14 +4705,23 @@ XS(_wrap_new_EventConsumer) {
}
arg2 = reinterpret_cast< char * >(buf2);
}
result = (EventConsumer *)new EventConsumer((char const *)arg1,(char const *)arg2);
if (items > 2) {
ecode3 = SWIG_AsVal_int SWIG_PERL_CALL_ARGS_2(ST(2), &val3);
if (!SWIG_IsOK(ecode3)) {
SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_EventConsumer" "', argument " "3"" of type '" "int""'");
}
arg3 = static_cast< int >(val3);
}
result = (EventConsumer *)new EventConsumer((char const *)arg1,(char const *)arg2,arg3);
ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EventConsumer, SWIG_OWNER | SWIG_SHADOW); argvi++ ;
if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
XSRETURN(argvi);
fail:
if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
SWIG_croak_null();
}
}

View File

@ -5406,6 +5406,7 @@ SWIGINTERN PyObject *_wrap_new_EventConsumer(PyObject *SWIGUNUSEDPARM(self), PyO
PyObject *resultobj = 0;
char *arg1 = (char *) NULL ;
char *arg2 = (char *) "" ;
int arg3 = (int) 5000 ;
EventConsumer *result = 0 ;
int res1 ;
char *buf1 = 0 ;
@ -5413,10 +5414,13 @@ SWIGINTERN PyObject *_wrap_new_EventConsumer(PyObject *SWIGUNUSEDPARM(self), PyO
int res2 ;
char *buf2 = 0 ;
int alloc2 = 0 ;
int val3 ;
int ecode3 = 0 ;
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
PyObject * obj2 = 0 ;
if (!PyArg_ParseTuple(args,(char *)"|OO:new_EventConsumer",&obj0,&obj1)) SWIG_fail;
if (!PyArg_ParseTuple(args,(char *)"|OOO:new_EventConsumer",&obj0,&obj1,&obj2)) SWIG_fail;
if (obj0) {
res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
if (!SWIG_IsOK(res1)) {
@ -5431,7 +5435,14 @@ SWIGINTERN PyObject *_wrap_new_EventConsumer(PyObject *SWIGUNUSEDPARM(self), PyO
}
arg2 = reinterpret_cast< char * >(buf2);
}
result = (EventConsumer *)new EventConsumer((char const *)arg1,(char const *)arg2);
if (obj2) {
ecode3 = SWIG_AsVal_int(obj2, &val3);
if (!SWIG_IsOK(ecode3)) {
SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "new_EventConsumer" "', argument " "3"" of type '" "int""'");
}
arg3 = static_cast< int >(val3);
}
result = (EventConsumer *)new EventConsumer((char const *)arg1,(char const *)arg2,arg3);
resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EventConsumer, SWIG_POINTER_NEW | 0 );
if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
if (alloc2 == SWIG_NEWOBJ) delete[] buf2;

View File

@ -22,9 +22,11 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Chris Rienzo <chris@rienzo.net>
* Christopher M. Rienzo <chris@rienzo.com>
* Timo Teräs <timo.teras@iki.fi> (based on mod_timerfd.c)
*
* Maintainer: Christopher M. Rienzo <chris@rienzo.com>
*
* mod_posix_timer.c -- soft timer implemented with POSIX timers (timer_create/timer_settime/timer_getoverrun)
*
*/
@ -44,7 +46,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_posix_timer_shutdown);
SWITCH_MODULE_RUNTIME_FUNCTION(mod_posix_timer_runtime);
SWITCH_MODULE_DEFINITION(mod_posix_timer, mod_posix_timer_load, mod_posix_timer_shutdown, mod_posix_timer_runtime);
#define SIG SIGRTMAX
#define SIG (SIGRTMAX - 1)
#define MAX_INTERVAL 2000 /* ms */
#define TIMERS_PER_INTERVAL 4
#define MAX_ACTIVE_TIMERS 256 /* one byte */
@ -111,7 +113,9 @@ static void timer_signal_handler(int sig, siginfo_t *si, void *cu)
if (val >= 0 && val <= MAX_ACTIVE_TIMERS) {
uint8_t active_id = (uint8_t)val;
/* notify runtime thread that timer identified by active_id has ticked */
write(globals.timer_tick_pipe[1], &active_id, 1);
if (write(globals.timer_tick_pipe[1], &active_id, 1) == -1) {
/* don't actually care about this error- this is only to make the compiler happy */
}
}
}
}

View File

@ -115,7 +115,7 @@ static void *module_thread(void *dummy)
/**
* Load mod_posix_timer and start the runtime thread
*/
static void load_module()
static int load_module()
{
fail_count = 0;
warn_count = 0;
@ -124,9 +124,11 @@ static void load_module()
session_count = 0;
last_reported_session_count = 0;
shutdown = 0;
mod_posix_timer_load(&mod, &pool);
if (mod_posix_timer_load(&mod, &pool) != SWITCH_STATUS_SUCCESS) {
return -1;
}
timer_if = mod->timer;
pthread_create(&module_runtime_thread_id, NULL, module_thread, NULL);
return pthread_create(&module_runtime_thread_id, NULL, module_thread, NULL);
}
/**
@ -444,12 +446,14 @@ int main (int argc, char **argv)
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
srand48(ts.tv_nsec);
load_module();
if (load_module() == -1) {
return -1;
}
//test_timer(20, 5.0f, .2f, 1000);
//test_timer_session(intervals, interval_weights, 4, 2 * 86400.0f, 90, 2000, 30.0, 5.0f);
while(1) {
/* stop periodically to trigger timer shutdown */
test_timer_session(intervals, interval_weights, 1, 60, 150, 3000, 30.0, 5.0f);
test_timer_session(intervals, interval_weights, 1, 60, 150, 190 /* 3000 */, 30.0, 5.0f);
}
//test_timer(1000, 5.0f, 1);
//test_timer(20, 5.0f, .2f, 1000);

View File

@ -102,7 +102,6 @@ static void handle_SIGCHLD(int sig)
pid = wait(&status);
if (pid > 0) {
printf("ASS %d\n", pid);
system_ready = -1;
}

View File

@ -1169,6 +1169,11 @@ SWITCH_DECLARE(switch_status_t) switch_thread_exit(switch_thread_t *thd, switch_
*/
SWITCH_DECLARE(switch_status_t) switch_thread_join(switch_status_t *retval, switch_thread_t *thd)
{
if ( !thd ) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: Attempting to join thread that does not exist\n");
return SWITCH_STATUS_FALSE;
}
return apr_thread_join((apr_status_t *) retval, (apr_thread_t *) thd);
}

View File

@ -1928,6 +1928,8 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_running_state(
if (state == CS_ROUTING) {
switch_channel_event_set_data(channel, event);
} else {
const char *v;
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-State", switch_channel_state_name(state));
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Call-State", switch_channel_callstate2str(channel->callstate));
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Channel-State-Number", "%d", state);
@ -1951,6 +1953,21 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_running_state(
} else {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Answer-State", "ringing");
}
if ((v = switch_channel_get_variable(channel, "presence_id"))) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Presence-ID", v);
}
if ((v = switch_channel_get_variable(channel, "presence_data"))) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Presence-Data", v);
}
if ((v = switch_channel_get_variable(channel, "presence_data_cols"))) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Presence-Data-Cols", v);
switch_event_add_presence_data_cols(channel, event, "PD-");
}
}
switch_event_fire(&event);
}

View File

@ -1577,16 +1577,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc
static void handle_SIGCHLD(int sig)
{
int status = 0;
int pid = 0;
if (sig) {};
pid = wait(&status);
if (pid > 0) {
printf("ASS %d\n", pid);
}
wait(&status);
return;
}
#endif

View File

@ -26,7 +26,7 @@
* Anthony Minessale II <anthm@freeswitch.org>
* Michael Jerris <mike@jerris.com>
* Paul D. Tinsley <pdt at jackhammer.org>
* Christopher M. Rienzo <chris@rienzo.net>
* Christopher M. Rienzo <chris@rienzo.com>
* Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
*
*

View File

@ -26,7 +26,7 @@
* Anthony Minessale II <anthm@freeswitch.org>
* Michael Jerris <mike@jerris.com>
* Paul D. Tinsley <pdt at jackhammer.org>
* Chris Rienzo <chris@rienzo.net>
* Christopher M. Rienzo <chris@rienzo.com>
*
*
* switch_core_codec.c -- Main Core Library (codec functions)

View File

@ -26,7 +26,7 @@
* Anthony Minessale II <anthm@freeswitch.org>
* Michael Jerris <mike@jerris.com>
* Paul D. Tinsley <pdt at jackhammer.org>
* Christopher M. Rienzo <chris@rienzo.net>
* Christopher M. Rienzo <chris@rienzo.com>
*
*
* switch_core_speech.c -- Main Core Library (speech functions)

View File

@ -1193,7 +1193,7 @@ static char *parse_presence_data_cols(switch_event_t *event)
for (i = 0; i < col_count; i++) {
const char *val = NULL;
switch_snprintfv(col_name, sizeof(col_name), "variable_%q", cols[i]);
switch_snprintfv(col_name, sizeof(col_name), "PD-%q", cols[i]);
val = switch_event_get_header_nil(event, col_name);
if (zstr(val)) {
stream.write_function(&stream, "%q=NULL,", cols[i]);
@ -1403,10 +1403,23 @@ static void core_event_handler(switch_event_t *event)
switch (state_i) {
case CS_NEW:
case CS_HANGUP:
case CS_DESTROY:
case CS_REPORTING:
break;
case CS_EXECUTE:
if ((extra_cols = parse_presence_data_cols(event))) {
new_sql() = switch_mprintf("update channels set state='%s',%s where uuid='%q'",
switch_event_get_header_nil(event, "channel-state"),
extra_cols,
switch_event_get_header_nil(event, "unique-id"));
free(extra_cols);
} else {
new_sql() = switch_mprintf("update channels set state='%s' where uuid='%s'",
switch_event_get_header_nil(event, "channel-state"),
switch_event_get_header_nil(event, "unique-id"));
}
break;
case CS_ROUTING:
if ((extra_cols = parse_presence_data_cols(event))) {
new_sql() = switch_mprintf("update channels set state='%s',cid_name='%q',cid_num='%q',callee_name='%q',callee_num='%q',"
@ -1713,7 +1726,8 @@ static char create_registrations_sql[] =
" network_ip VARCHAR(256),\n"
" network_port VARCHAR(256),\n"
" network_proto VARCHAR(256),\n"
" hostname VARCHAR(256)\n"
" hostname VARCHAR(256),\n"
" metadata VARCHAR(256)\n"
");\n";
@ -1843,7 +1857,8 @@ static char basic_calls_sql[] =
SWITCH_DECLARE(switch_status_t) switch_core_add_registration(const char *user, const char *realm, const char *token, const char *url, uint32_t expires,
const char *network_ip, const char *network_port, const char *network_proto)
const char *network_ip, const char *network_port, const char *network_proto,
const char *metadata)
{
char *sql;
@ -1860,19 +1875,35 @@ SWITCH_DECLARE(switch_status_t) switch_core_add_registration(const char *user, c
}
switch_queue_push(sql_manager.sql_queue[0], sql);
sql = switch_mprintf("insert into registrations (reg_user,realm,token,url,expires,network_ip,network_port,network_proto,hostname) "
"values ('%q','%q','%q','%q',%ld,'%q','%q','%q','%q')",
switch_str_nil(user),
switch_str_nil(realm),
switch_str_nil(token),
switch_str_nil(url),
expires,
switch_str_nil(network_ip),
switch_str_nil(network_port),
switch_str_nil(network_proto),
switch_core_get_switchname()
);
if ( !zstr(metadata) ) {
sql = switch_mprintf("insert into registrations (reg_user,realm,token,url,expires,network_ip,network_port,network_proto,hostname,metadata) "
"values ('%q','%q','%q','%q',%ld,'%q','%q','%q','%q','%q')",
switch_str_nil(user),
switch_str_nil(realm),
switch_str_nil(token),
switch_str_nil(url),
expires,
switch_str_nil(network_ip),
switch_str_nil(network_port),
switch_str_nil(network_proto),
switch_core_get_switchname(),
metadata
);
} else {
sql = switch_mprintf("insert into registrations (reg_user,realm,token,url,expires,network_ip,network_port,network_proto,hostname) "
"values ('%q','%q','%q','%q',%ld,'%q','%q','%q','%q')",
switch_str_nil(user),
switch_str_nil(realm),
switch_str_nil(token),
switch_str_nil(url),
expires,
switch_str_nil(network_ip),
switch_str_nil(network_port),
switch_str_nil(network_proto),
switch_core_get_switchname()
);
}
switch_queue_push(sql_manager.sql_queue[0], sql);
@ -2007,6 +2038,8 @@ switch_status_t switch_core_sqldb_start(switch_memory_pool_t *pool, switch_bool_
switch_cache_db_test_reactive(dbh, "delete from registrations where reg_user='' or network_proto='tcp' or network_proto='tls'",
"DROP TABLE registrations", create_registrations_sql);
switch_cache_db_test_reactive(dbh, "select metadata from registrations", NULL, "ALTER TABLE registrations ADD COLUMN metadata VARCHAR(256)");
switch (dbh->type) {
case SCDB_TYPE_ODBC:

View File

@ -50,11 +50,11 @@ static void event_handler(switch_event_t *event)
}
SWITCH_DECLARE_CONSTRUCTOR EventConsumer::EventConsumer(const char *event_name, const char *subclass_name)
SWITCH_DECLARE_CONSTRUCTOR EventConsumer::EventConsumer(const char *event_name, const char *subclass_name, int len)
{
switch_core_new_memory_pool(&pool);
switch_queue_create(&events, 5000, pool);
switch_queue_create(&events, len, pool);
node_index = 0;
if (!zstr(event_name)) {

View File

@ -2976,7 +2976,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_say_string(switch_core_session_t *ses
}
}
if ((si = switch_loadable_module_get_say_interface(module_name))) {
if ((si = switch_loadable_module_get_say_interface(module_name)) && si->say_string_function) {
/* should go back and proto all the say mods to const.... */
switch_say_args_t say_args = {0};

View File

@ -27,7 +27,7 @@
* Michael Jerris <mike@jerris.com>
* Bret McDanel <bret AT 0xdecafbad dot com>
* Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
* Chris Rienzo <chris@rienzo.net>
* Christopher M. Rienzo <chris@rienzo.com>
*
* switch_ivr_async.c -- IVR Library (async operations)
*

View File

@ -384,8 +384,10 @@ static void inherit_codec(switch_channel_t *caller_channel, switch_core_session_
{
const char *var = switch_channel_get_variable(caller_channel, "inherit_codec");
switch_channel_t *channel = switch_core_session_get_channel(session);
if (switch_true(var)) {
if (!zstr(var) && !strcasecmp(var, "passthru")) {
switch_channel_set_variable(caller_channel, "absolute_codec_string", switch_channel_get_variable(channel, "ep_codec_string"));
} else if (switch_true(var)) {
switch_codec_implementation_t impl = { 0 };
switch_codec_implementation_t video_impl = { 0 };
char tmp[128] = "";

Some files were not shown because too many files have changed in this diff Show More