Merge branch 'master' of ssh://git.freeswitch.org:222/freeswitch
This commit is contained in:
commit
a0a9efcf02
|
@ -99,6 +99,7 @@ TAGS
|
||||||
/build/Makefile
|
/build/Makefile
|
||||||
/build/Makefile.in
|
/build/Makefile.in
|
||||||
/build/modmake.rules
|
/build/modmake.rules
|
||||||
|
/build/print_git_revision
|
||||||
|
|
||||||
/libs/curl/lib/ca-bundle.h
|
/libs/curl/lib/ca-bundle.h
|
||||||
/libs/esl/fs_cli
|
/libs/esl/fs_cli
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
@SWITCH_VERSION_REVISION@
|
|
|
@ -527,6 +527,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_gsmopen", "src\mod\endp
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libzrtp", "libs\libzrtp\projects\win\libzrtp.2010.vcxproj", "{C13CC324-0032-4492-9A30-310A6BD64FF5}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libzrtp", "libs\libzrtp\projects\win\libzrtp.2010.vcxproj", "{C13CC324-0032-4492-9A30-310A6BD64FF5}"
|
||||||
EndProject
|
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
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
All|Win32 = All|Win32
|
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.Build.0 = Release|x64
|
||||||
{C13CC324-0032-4492-9A30-310A6BD64FF5}.Release|x64 Setup.ActiveCfg = Release|Win32
|
{C13CC324-0032-4492-9A30-310A6BD64FF5}.Release|x64 Setup.ActiveCfg = Release|Win32
|
||||||
{C13CC324-0032-4492-9A30-310A6BD64FF5}.Release|x86 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
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -3648,6 +3663,7 @@ Global
|
||||||
{4748FF56-CA85-4809-97D6-A94C0FAC1D77} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78}
|
{4748FF56-CA85-4809-97D6-A94C0FAC1D77} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78}
|
||||||
{60C542EE-6882-4EA2-8C21-5AB6DB1BA73F} = {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}
|
{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}
|
{07113B25-D3AF-4E04-BA77-4CD1171F022C} = {C5F182F9-754A-4EC5-B50F-76ED02BE13F4}
|
||||||
{A27CCA23-1541-4337-81A4-F0A6413078A0} = {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}
|
{E7BC026C-7CC5-45A3-BC7C-3B88EEF01F24} = {C5F182F9-754A-4EC5-B50F-76ED02BE13F4}
|
||||||
|
|
34
Makefile.am
34
Makefile.am
|
@ -415,29 +415,16 @@ $(OUR_MODULES): $(switch_builddir)/modules.conf libfreeswitch.la
|
||||||
$(switch_builddir)/quiet_libtool: $(switch_builddir)/libtool
|
$(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
|
@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)
|
build/print_git_revision: build/print_git_revision.c
|
||||||
@have_version=1 ; \
|
$(CC) -o $@ $<
|
||||||
force=0 ; \
|
|
||||||
grep -- "@SWITCH_VERSION_REVISION@" src/include/switch_version.h.in > /dev/null || have_version=0 ; \
|
src/include/switch_version.h: src/include/switch_version.h.in Makefile build/print_git_revision $(libfreeswitch_la_SOURCES) $(library_include_HEADERS)
|
||||||
test ! -f src/include/switch_version.h || grep -- "@SWITCH_VERSION_REVISION@" src/include/switch_version.h > /dev/null && force=1 ; \
|
@cat $< > $@; \
|
||||||
if test $$have_version = 1 ; then \
|
if [ -d .git ] && [ -n "$$(which git)" ]; then \
|
||||||
cat src/include/switch_version.h.in > src/include/switch_version.h ; \
|
xver="$$(./build/print_git_revision)"; \
|
||||||
touch .version ; \
|
sed -e "/#define *SWITCH_VERSION_REVISION/{s/\"\([^\"]*\)\"/\"\1$$xver\"/;}" \
|
||||||
else \
|
$< > $@; \
|
||||||
if [ -d .git ] ; then \
|
fi;
|
||||||
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 ;
|
|
||||||
|
|
||||||
##
|
##
|
||||||
## Dependency targets
|
## Dependency targets
|
||||||
|
@ -544,7 +531,6 @@ is-scm:
|
||||||
|
|
||||||
update: is-scm
|
update: is-scm
|
||||||
@if test -d .git ; then \
|
@if test -d .git ; then \
|
||||||
test ! -f .version || rm -f .version ; \
|
|
||||||
echo "Pulling updates..." ; \
|
echo "Pulling updates..." ; \
|
||||||
git pull ; \
|
git pull ; \
|
||||||
else \
|
else \
|
||||||
|
|
|
@ -58,12 +58,12 @@ codecs/mod_bv
|
||||||
codecs/mod_g723_1
|
codecs/mod_g723_1
|
||||||
codecs/mod_g729
|
codecs/mod_g729
|
||||||
codecs/mod_h26x
|
codecs/mod_h26x
|
||||||
codecs/mod_ilbc
|
#codecs/mod_ilbc
|
||||||
#codecs/mod_isac
|
#codecs/mod_isac
|
||||||
#codecs/mod_opus
|
#codecs/mod_opus
|
||||||
#codecs/mod_sangoma_codec
|
#codecs/mod_sangoma_codec
|
||||||
#codecs/mod_silk
|
#codecs/mod_silk
|
||||||
codecs/mod_siren
|
#codecs/mod_siren
|
||||||
codecs/mod_speex
|
codecs/mod_speex
|
||||||
dialplans/mod_dialplan_asterisk
|
dialplans/mod_dialplan_asterisk
|
||||||
#dialplans/mod_dialplan_directory
|
#dialplans/mod_dialplan_directory
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
<param name="auth-calls" value="false"/>
|
<param name="auth-calls" value="false"/>
|
||||||
<param name="rtp-timeout-sec" value="1800"/>
|
<param name="rtp-timeout-sec" value="1800"/>
|
||||||
<param name="inbound-late-negotiation" value="true"/>
|
<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!
|
DO NOT USE HOSTNAMES, ONLY IP ADDRESSES IN THESE SETTINGS!
|
||||||
-->
|
-->
|
||||||
|
|
|
@ -69,7 +69,7 @@
|
||||||
<!-- Let calls hit the dialplan before selecting codec for the a-leg -->
|
<!-- Let calls hit the dialplan before selecting codec for the a-leg -->
|
||||||
<param name="inbound-late-negotiation" value="true"/>
|
<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"/>
|
<param name="inbound-zrtp-passthru" value="true"/>
|
||||||
|
|
||||||
<!-- this lets anything register -->
|
<!-- this lets anything register -->
|
||||||
|
|
|
@ -104,7 +104,7 @@
|
||||||
<!-- Let calls hit the dialplan before selecting codec for the a-leg -->
|
<!-- Let calls hit the dialplan before selecting codec for the a-leg -->
|
||||||
<param name="inbound-late-negotiation" value="true"/>
|
<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"/>
|
<param name="inbound-zrtp-passthru" value="true"/>
|
||||||
|
|
||||||
<!-- this lets anything register -->
|
<!-- this lets anything register -->
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
<param name="auth-calls" value="false"/>
|
<param name="auth-calls" value="false"/>
|
||||||
<param name="rtp-timeout-sec" value="1800"/>
|
<param name="rtp-timeout-sec" value="1800"/>
|
||||||
<param name="inbound-late-negotiation" value="true"/>
|
<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!
|
DO NOT USE HOSTNAMES, ONLY IP ADDRESSES IN THESE SETTINGS!
|
||||||
-->
|
-->
|
||||||
|
|
|
@ -69,7 +69,7 @@
|
||||||
<!-- Let calls hit the dialplan before selecting codec for the a-leg -->
|
<!-- Let calls hit the dialplan before selecting codec for the a-leg -->
|
||||||
<param name="inbound-late-negotiation" value="true"/>
|
<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"/>
|
<param name="inbound-zrtp-passthru" value="true"/>
|
||||||
|
|
||||||
<!-- this lets anything register -->
|
<!-- this lets anything register -->
|
||||||
|
|
|
@ -110,7 +110,7 @@
|
||||||
<!-- Let calls hit the dialplan before selecting codec for the a-leg -->
|
<!-- Let calls hit the dialplan before selecting codec for the a-leg -->
|
||||||
<param name="inbound-late-negotiation" value="true"/>
|
<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"/>
|
<param name="inbound-zrtp-passthru" value="true"/>
|
||||||
|
|
||||||
<!-- this lets anything register -->
|
<!-- this lets anything register -->
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
<param name="nonce-ttl" value="60"/>
|
<param name="nonce-ttl" value="60"/>
|
||||||
<param name="auth-calls" value="false"/>
|
<param name="auth-calls" value="false"/>
|
||||||
<param name="inbound-late-negotiation" value="true"/>
|
<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!
|
DO NOT USE HOSTNAMES, ONLY IP ADDRESSES IN THESE SETTINGS!
|
||||||
-->
|
-->
|
||||||
|
|
|
@ -70,7 +70,7 @@
|
||||||
<!-- Let calls hit the dialplan before selecting codec for the a-leg -->
|
<!-- Let calls hit the dialplan before selecting codec for the a-leg -->
|
||||||
<param name="inbound-late-negotiation" value="true"/>
|
<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"/>
|
<param name="inbound-zrtp-passthru" value="true"/>
|
||||||
|
|
||||||
<!-- this lets anything register -->
|
<!-- this lets anything register -->
|
||||||
|
|
|
@ -222,7 +222,7 @@
|
||||||
<!-- Let calls hit the dialplan before selecting codec for the a-leg -->
|
<!-- Let calls hit the dialplan before selecting codec for the a-leg -->
|
||||||
<param name="inbound-late-negotiation" value="true"/>
|
<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"/>
|
<param name="inbound-zrtp-passthru" value="true"/>
|
||||||
|
|
||||||
<!-- this lets anything register -->
|
<!-- this lets anything register -->
|
||||||
|
|
|
@ -10,7 +10,6 @@ AC_SUBST(SWITCH_VERSION_MICRO, [0])
|
||||||
AC_SUBST(SWITCH_VERSION_REVISION, [-rc2])
|
AC_SUBST(SWITCH_VERSION_REVISION, [-rc2])
|
||||||
|
|
||||||
AC_CONFIG_FILES([src/include/switch_version.h.in:src/include/switch_version.h.template])
|
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)
|
AC_CONFIG_AUX_DIR(build/config)
|
||||||
AM_INIT_AUTOMAKE(libfreeswitch,0.1)
|
AM_INIT_AUTOMAKE(libfreeswitch,0.1)
|
||||||
|
@ -925,7 +924,7 @@ then
|
||||||
#
|
#
|
||||||
# python distutils found, get settings from python directly
|
# 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_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_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\"));'`"
|
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/Makefile
|
||||||
src/mod/Makefile
|
src/mod/Makefile
|
||||||
src/mod/applications/mod_expr/Makefile
|
src/mod/applications/mod_expr/Makefile
|
||||||
src/mod/applications/mod_fax/Makefile
|
|
||||||
src/mod/applications/mod_spandsp/Makefile
|
src/mod/applications/mod_spandsp/Makefile
|
||||||
src/mod/applications/mod_osp/Makefile
|
src/mod/applications/mod_osp/Makefile
|
||||||
src/mod/applications/mod_stress/Makefile
|
src/mod/applications/mod_stress/Makefile
|
||||||
|
|
|
@ -31,6 +31,7 @@ avoid_mods=(
|
||||||
endpoints/mod_reference
|
endpoints/mod_reference
|
||||||
endpoints/mod_unicall
|
endpoints/mod_unicall
|
||||||
formats/mod_shout
|
formats/mod_shout
|
||||||
|
languages/mod_managed
|
||||||
languages/mod_spidermonkey
|
languages/mod_spidermonkey
|
||||||
sdk/autotools
|
sdk/autotools
|
||||||
xml_int/mod_xml_ldap
|
xml_int/mod_xml_ldap
|
||||||
|
|
|
@ -234,9 +234,11 @@ EOF
|
||||||
build_debs () {
|
build_debs () {
|
||||||
{
|
{
|
||||||
set -e
|
set -e
|
||||||
local OPTIND OPTARG debug_hook=false hookdir=""
|
local OPTIND OPTARG debug_hook=false hookdir="" cow_build_opts=""
|
||||||
while getopts 'd' o "$@"; do
|
while getopts 'Bbd' o "$@"; do
|
||||||
case "$o" in
|
case "$o" in
|
||||||
|
B) cow_build_opts="--debbuildopts '-B'";;
|
||||||
|
b) cow_build_opts="--debbuildopts '-b'";;
|
||||||
d) debug_hook=true;;
|
d) debug_hook=true;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
@ -274,9 +276,10 @@ build_debs () {
|
||||||
fi
|
fi
|
||||||
cow --build $dsc \
|
cow --build $dsc \
|
||||||
--hookdir "$hookdir" \
|
--hookdir "$hookdir" \
|
||||||
--buildresult ../
|
--buildresult ../ \
|
||||||
|
$cow_build_opts
|
||||||
} 1>&2
|
} 1>&2
|
||||||
echo ${dsc}_${arch}.changes
|
echo ${dsc%.dsc}_${arch}.changes
|
||||||
}
|
}
|
||||||
|
|
||||||
build_all () {
|
build_all () {
|
||||||
|
@ -304,38 +307,96 @@ build_all () {
|
||||||
mkdir -p ../log
|
mkdir -p ../log
|
||||||
> ../log/changes
|
> ../log/changes
|
||||||
echo; echo; echo; echo
|
echo; echo; echo; echo
|
||||||
|
trap 'echo "Killing children...">&2; for x in $(jobs -p); do kill $x; done' EXIT
|
||||||
if [ "${orig:0:2}" = ".." ]; then
|
if [ "${orig:0:2}" = ".." ]; then
|
||||||
for distro in $distros; do
|
for distro in $distros; do
|
||||||
echo "Creating $distro dsc..." >&2
|
echo "Creating $distro dsc..." >&2
|
||||||
local dsc="$(create_dsc $dsc_opts $distro $orig 2>../log/$distro | tail -n1)"
|
local dsc="$(create_dsc $dsc_opts $distro $orig 2>../log/$distro | tail -n1)"
|
||||||
echo "Done creating $distro dsc." >&2
|
echo "Done creating $distro dsc." >&2
|
||||||
if [ "${dsc:0:2}" = ".." ]; then
|
if [ "${dsc:0:2}" = ".." ]; then
|
||||||
|
local lopts="-b"
|
||||||
for arch in $archs; do
|
for arch in $archs; do
|
||||||
{
|
{
|
||||||
echo "Building $distro-$arch debs..." >&2
|
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
|
echo "Done building $distro-$arch debs." >&2
|
||||||
if [ "${changes:0:2}" = ".." ]; then
|
if [ "${changes:0:2}" = ".." ]; then
|
||||||
echo "$changes" >> ../log/changes
|
echo "$changes" >> ../log/changes
|
||||||
fi
|
fi
|
||||||
} &
|
} &
|
||||||
$par || wait
|
$par || wait
|
||||||
|
lopts="-B"
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
! $par || wait
|
! $par || wait
|
||||||
fi
|
fi
|
||||||
|
trap - EXIT
|
||||||
cat ../log/changes
|
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
|
case "$o" in
|
||||||
d) set -vx;;
|
d) set -vx;;
|
||||||
|
h) usage;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
shift $(($OPTIND-1))
|
shift $(($OPTIND-1))
|
||||||
|
|
||||||
cmd="$1"
|
cmd="$1"; [ -n "$cmd" ] || usage
|
||||||
shift
|
shift
|
||||||
case "$cmd" in
|
case "$cmd" in
|
||||||
archive-orig) archive_orig "$@" ;;
|
archive-orig) archive_orig "$@" ;;
|
||||||
|
@ -344,5 +405,6 @@ case "$cmd" in
|
||||||
create-dbg-pkgs) create_dbg_pkgs ;;
|
create-dbg-pkgs) create_dbg_pkgs ;;
|
||||||
create-dsc) create_dsc "$@" ;;
|
create-dsc) create_dsc "$@" ;;
|
||||||
create-orig) create_orig "$@" ;;
|
create-orig) create_orig "$@" ;;
|
||||||
|
*) usage ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
|
|
@ -225,6 +225,7 @@ missing
|
||||||
/ldns/doc/ldns_manpages
|
/ldns/doc/ldns_manpages
|
||||||
/ldns/include/
|
/ldns/include/
|
||||||
/ldns/ldns/config.h
|
/ldns/ldns/config.h
|
||||||
|
/ldns/ldns/ldns
|
||||||
/ldns/ldns/net.h
|
/ldns/ldns/net.h
|
||||||
/ldns/ldns/util.h
|
/ldns/ldns/util.h
|
||||||
/ldns/lib
|
/ldns/lib
|
||||||
|
|
|
@ -527,7 +527,12 @@ typedef struct zrtp_stream_mescache_t
|
||||||
zrtp_retry_task_t errorack_task;
|
zrtp_retry_task_t errorack_task;
|
||||||
zrtp_retry_task_t sasrelay_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;
|
} zrtp_stream_mescache_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -723,13 +728,6 @@ struct zrtp_stream_t
|
||||||
*/
|
*/
|
||||||
zrtp_protocol_t *protocol;
|
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. */
|
/*!< Holder for RTP/ZRTP media stream options. */
|
||||||
zrtp_media_context_t media_ctx;
|
zrtp_media_context_t media_ctx;
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,8 @@
|
||||||
|
|
||||||
#define LIBZRTP_VERSION_MAJOR 1
|
#define LIBZRTP_VERSION_MAJOR 1
|
||||||
|
|
||||||
#define LIBZRTP_VERSION_MINOR 13
|
#define LIBZRTP_VERSION_MINOR 15
|
||||||
#define LIBZRTP_VERSION_BUILD 604
|
#define LIBZRTP_VERSION_BUILD 607
|
||||||
#define LIBZRTP_VERSION_STR "v1.13 604"
|
#define LIBZRTP_VERSION_STR "v1.15 607"
|
||||||
|
|
||||||
#endif /*__ZRTP_VERSION_H__*/
|
#endif /*__ZRTP_VERSION_H__*/
|
||||||
|
|
|
@ -32,7 +32,7 @@ case $target_os in
|
||||||
esac
|
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)
|
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"
|
CFLAGS="$CFLAGS -Wno-unused-parameter -fno-strict-aliasing -fPIC -DZRTP_AUTOMAKE=1"
|
||||||
|
|
|
@ -418,8 +418,6 @@ zrtp_status_t zrtp_stream_attach(zrtp_session_t *session, zrtp_stream_t** stream
|
||||||
return zrtp_status_alloc_fail;
|
return zrtp_status_alloc_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZSTR_SET_EMPTY(new_stream->signaling_hash);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the private data stream with default initial values
|
* 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.zrtp_key);
|
||||||
ZSTR_SET_EMPTY(new_stream->cc.peer_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;
|
new_stream->dh_cc.initialized_with = ZRTP_COMP_UNKN;
|
||||||
bnBegin(&new_stream->dh_cc.peer_pv);
|
bnBegin(&new_stream->dh_cc.peer_pv);
|
||||||
ZSTR_SET_EMPTY(new_stream->dh_cc.dhss);
|
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;
|
ctx->messages.signaling_hash.length = ZRTP_MESSAGE_HASH_SIZE;
|
||||||
|
|
||||||
{
|
{
|
||||||
char buff[66];
|
char buff[64];
|
||||||
ZRTP_LOG(3, (_ZTU_,"SIGNALLING HAS was ADDED for the comparing. ID=%u\n", ctx->id));
|
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))));
|
ZRTP_LOG(3, (_ZTU_,"Hash=%s.\n", hex2str(hash_buff, hash_buff_length, buff, sizeof(buff))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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_status_t s = zrtp_status_fail;
|
||||||
zrtp_string128_t hmac = ZSTR_INIT_EMPTY(hmac);
|
zrtp_string128_t hmac = ZSTR_INIT_EMPTY(hmac);
|
||||||
char zerosashash[32];
|
char zerosashash[32];
|
||||||
|
unsigned sas_scheme_did_change = 0;
|
||||||
|
unsigned sas_hash_did_change = 0;
|
||||||
|
|
||||||
/* (padding + sig_len + flags) + SAS scheme and SAS hash */
|
/* (padding + sig_len + flags) + SAS scheme and SAS hash */
|
||||||
const uint8_t encrypted_body_size = (2 + 1 + 1) + 4 + 32;
|
const uint8_t encrypted_body_size = (2 + 1 + 1) + 4 + 32;
|
||||||
|
|
||||||
zrtp_memset(zerosashash, 0, sizeof(zerosashash));
|
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) {
|
if (!stream->peer_mitm_flag) {
|
||||||
ZRTP_LOG(2,(_ZTU_, ZRTP_RELAYED_SAS_FROM_NONMITM_STR));
|
ZRTP_LOG(2,(_ZTU_, ZRTP_RELAYED_SAS_FROM_NONMITM_STR));
|
||||||
return zrtp_status_fail;
|
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;
|
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 */
|
/* Then we need to decrypt Confirm body */
|
||||||
do
|
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);
|
_zrtp_machine_enter_initiatingerror(stream, zrtp_error_invalid_packet, 1);
|
||||||
return zrtp_status_fail;
|
return zrtp_status_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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 );
|
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));
|
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 (session->secrets.matches & ZRTP_BIT_PBX) {
|
||||||
if ( ( ((uint32_t) *sasrelay->sas_scheme) != (uint32_t)0x0L ) &&
|
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);
|
zrtp_memcpy(session->sasbin.buffer, sasrelay->sashash, session->sasbin.length);
|
||||||
stream->mitm_mode = ZRTP_MITM_MODE_RECONFIRM_CLIENT;
|
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)));
|
hex2str(buff, sizeof(buff), session->sasbin.buffer, session->sasbin.length)));
|
||||||
}
|
}
|
||||||
} else if (0 != zrtp_memcmp(sasrelay->sashash, zerosashash, sizeof(sasrelay->sashash))) {
|
} else if (0 != zrtp_memcmp(sasrelay->sashash, zerosashash, sizeof(sasrelay->sashash))) {
|
||||||
|
@ -242,6 +250,13 @@ 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));
|
ZRTP_LOG(1,(_ZTU_, "\rERROR! For SasRelay Other secret doesn't match. ID=%u\n", stream->id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 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);
|
s = session->sasscheme->compute(session->sasscheme, stream, session->hash, 1);
|
||||||
if (zrtp_status_ok != s) {
|
if (zrtp_status_ok != s) {
|
||||||
_zrtp_machine_enter_initiatingerror(stream, zrtp_error_software, 1);
|
_zrtp_machine_enter_initiatingerror(stream, zrtp_error_software, 1);
|
||||||
|
@ -253,6 +268,7 @@ zrtp_status_t _zrtp_machine_process_sasrelay(zrtp_stream_t *stream, zrtp_rtp_inf
|
||||||
if (session->zrtp->cb.event_cb.on_zrtp_protocol_event) {
|
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);
|
session->zrtp->cb.event_cb.on_zrtp_protocol_event(stream, ZRTP_EVENT_LOCAL_SAS_UPDATED);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return zrtp_status_ok;
|
return zrtp_status_ok;
|
||||||
}
|
}
|
||||||
|
@ -492,7 +508,7 @@ zrtp_status_t zrtp_update_remote_options( zrtp_stream_t* stream,
|
||||||
return zrtp_status_bad_param;
|
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) {
|
if (!stream->zrtp->is_mitm) {
|
||||||
ZRTP_LOG(3,(_ZTU_,"\tERROR! The endpoint can't transfer SAS values to other endpoints"
|
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"));
|
" without introducing itself by M-flag in Hello. see zrtp_init().\n"));
|
||||||
|
|
|
@ -488,7 +488,7 @@ zrtp_status_t _zrtp_packet_preparse( zrtp_stream_t* stream,
|
||||||
(const char*) info->message,
|
(const char*) info->message,
|
||||||
zrtp_ntoh16(((zrtp_packet_Hello_t*) info->message)->hdr.length)*4,
|
zrtp_ntoh16(((zrtp_packet_Hello_t*) info->message)->hdr.length)*4,
|
||||||
ZSTR_GV(hash_str) );
|
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) {
|
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);
|
stream->zrtp->cb.event_cb.on_zrtp_security_event(stream, ZRTP_EVENT_WRONG_SIGNALING_HASH);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Thu May 3 16:30:20 CDT 2012
|
Sat Jun 9 03:24:47 UTC 2012
|
||||||
|
|
|
@ -198,6 +198,12 @@ enum tport_tls_verify_policy {
|
||||||
TPTLS_VERIFY_SUBJECTS_ALL = 0xF,
|
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;
|
TPORT_DLL extern tag_typedef_t tptag_tls_passphrase;
|
||||||
#define TPTAG_TLS_PASSPHRASE(x) tptag_tls_passphrase, tag_str_v(x)
|
#define TPTAG_TLS_PASSPHRASE(x) tptag_tls_passphrase, tag_str_v(x)
|
||||||
|
|
||||||
|
|
|
@ -280,6 +280,19 @@ tag_typedef_t tptag_compartment = PTRTAG_TYPEDEF(compartment);
|
||||||
*/
|
*/
|
||||||
tag_typedef_t tptag_tls_version = UINTTAG_TYPEDEF(tls_version);
|
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)
|
/**@def TPTAG_TLS_VERIFY_PEER(x)
|
||||||
* @par Depreciated:
|
* @par Depreciated:
|
||||||
* Alias for TPTAG_TLS_VERIFY_POLICY(TPTLS_VERIFY_IN|TPTLS_VERIFY_OUT)
|
* Alias for TPTAG_TLS_VERIFY_POLICY(TPTLS_VERIFY_IN|TPTLS_VERIFY_OUT)
|
||||||
|
|
|
@ -311,6 +311,8 @@ int tls_init_context(tls_t *tls, tls_issues_t const *ti)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SSL_CTX_set_timeout(tls->ctx, ti->timeout);
|
||||||
|
|
||||||
/* Set callback if we have a passphrase */
|
/* Set callback if we have a passphrase */
|
||||||
if (ti->passphrase != NULL) {
|
if (ti->passphrase != NULL) {
|
||||||
SSL_CTX_set_default_passwd_cb(tls->ctx, passwd_cb);
|
SSL_CTX_set_default_passwd_cb(tls->ctx, passwd_cb);
|
||||||
|
|
|
@ -65,6 +65,7 @@ typedef struct tls_issues_s {
|
||||||
*/
|
*/
|
||||||
int version; /* For tls1, version is 1. When ssl3/ssl2 is
|
int version; /* For tls1, version is 1. When ssl3/ssl2 is
|
||||||
* used, it is 0. */
|
* used, it is 0. */
|
||||||
|
unsigned timeout; /* Maximum session lifetime in seconds */
|
||||||
} tls_issues_t;
|
} tls_issues_t;
|
||||||
|
|
||||||
typedef struct tport_tls_s {
|
typedef struct tport_tls_s {
|
||||||
|
|
|
@ -181,6 +181,7 @@ static int tport_tls_init_master(tport_primary_t *pri,
|
||||||
char *tbf = NULL;
|
char *tbf = NULL;
|
||||||
char const *path = NULL;
|
char const *path = NULL;
|
||||||
unsigned tls_version = 1;
|
unsigned tls_version = 1;
|
||||||
|
unsigned tls_timeout = 300;
|
||||||
unsigned tls_verify = 0;
|
unsigned tls_verify = 0;
|
||||||
char const *passphrase = NULL;
|
char const *passphrase = NULL;
|
||||||
unsigned tls_policy = TPTLS_VERIFY_NONE;
|
unsigned tls_policy = TPTLS_VERIFY_NONE;
|
||||||
|
@ -198,6 +199,7 @@ static int tport_tls_init_master(tport_primary_t *pri,
|
||||||
tl_gets(tags,
|
tl_gets(tags,
|
||||||
TPTAG_CERTIFICATE_REF(path),
|
TPTAG_CERTIFICATE_REF(path),
|
||||||
TPTAG_TLS_VERSION_REF(tls_version),
|
TPTAG_TLS_VERSION_REF(tls_version),
|
||||||
|
TPTAG_TLS_TIMEOUT_REF(tls_timeout),
|
||||||
TPTAG_TLS_VERIFY_PEER_REF(tls_verify),
|
TPTAG_TLS_VERIFY_PEER_REF(tls_verify),
|
||||||
TPTAG_TLS_PASSPHRASE_REF(passphrase),
|
TPTAG_TLS_PASSPHRASE_REF(passphrase),
|
||||||
TPTAG_TLS_VERIFY_POLICY_REF(tls_policy),
|
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.cert = ti.key;
|
||||||
ti.CAfile = su_sprintf(autohome, "%s/%s", path, "cafile.pem");
|
ti.CAfile = su_sprintf(autohome, "%s/%s", path, "cafile.pem");
|
||||||
ti.version = tls_version;
|
ti.version = tls_version;
|
||||||
|
ti.timeout = tls_timeout;
|
||||||
ti.CApath = su_strdup(autohome, path);
|
ti.CApath = su_strdup(autohome, path);
|
||||||
|
|
||||||
SU_DEBUG_9(("%s(%p): tls key = %s\n", __func__, (void *)pri, ti.key));
|
SU_DEBUG_9(("%s(%p): tls key = %s\n", __func__, (void *)pri, ti.key));
|
||||||
|
|
|
@ -271,14 +271,15 @@ Sub CreateVersion(tmpFolder, VersionDir, includebase, includedest)
|
||||||
strVerRev = FindVersionStringInConfigure(VersionDir & "configure.in", "SWITCH_VERSION_REVISION")
|
strVerRev = FindVersionStringInConfigure(VersionDir & "configure.in", "SWITCH_VERSION_REVISION")
|
||||||
|
|
||||||
'Set version to the one reported by configure.in
|
'Set version to the one reported by configure.in
|
||||||
if strVerRev <> "" Then
|
If strVerRev <> "" Then
|
||||||
VERSION = strVerRev
|
VERSION = strVerRev
|
||||||
End If
|
End If
|
||||||
|
|
||||||
Dim sLastFile
|
Dim sLastFile
|
||||||
Const ForReading = 1
|
Const ForReading = 1
|
||||||
|
|
||||||
'Try To read revision from git, if it's found, use this instead of strVerRev found above
|
'Try To read revision from git, if it was not found in "configure.in" already
|
||||||
|
If strVerRev = "" Then
|
||||||
If FSO.FolderExists(VersionDir & ".git") Then
|
If FSO.FolderExists(VersionDir & ".git") Then
|
||||||
VersionCmd="git log --format=" & quote & "%%h %%ci" & quote & " -1 HEAD"
|
VersionCmd="git log --format=" & quote & "%%h %%ci" & quote & " -1 HEAD"
|
||||||
Set MyFile = FSO.CreateTextFile(tmpFolder & "tmpVersion.Bat", True)
|
Set MyFile = FSO.CreateTextFile(tmpFolder & "tmpVersion.Bat", True)
|
||||||
|
@ -298,9 +299,10 @@ Sub CreateVersion(tmpFolder, VersionDir, includebase, includedest)
|
||||||
sLastFile.Close
|
sLastFile.Close
|
||||||
VERSION = Replace(VERSION, ":", "-")
|
VERSION = Replace(VERSION, ":", "-")
|
||||||
End If
|
End If
|
||||||
|
End If
|
||||||
|
|
||||||
If VERSION = "" Then
|
If VERSION = "" Then
|
||||||
VERSION = "UNKNOWN"
|
VERSION = "-UNKNOWN"
|
||||||
End If
|
End If
|
||||||
|
|
||||||
If VERSION <> sLastVersion Then
|
If VERSION <> sLastVersion Then
|
||||||
|
|
|
@ -28,6 +28,7 @@ mkdir -p $ddir
|
||||||
git clone . $bdir
|
git clone . $bdir
|
||||||
cd $bdir
|
cd $bdir
|
||||||
set_fs_ver "$gver" "$gmajor" "$gminor" "$gmicro" "$grev"
|
set_fs_ver "$gver" "$gmajor" "$gminor" "$gmicro" "$grev"
|
||||||
|
echo "$gver" > .version
|
||||||
cd libs
|
cd libs
|
||||||
getlib () {
|
getlib () {
|
||||||
f="${1##*/}"
|
f="${1##*/}"
|
||||||
|
|
|
@ -22,6 +22,7 @@ cp -r . $dst_dir
|
||||||
|
|
||||||
cd $dst_dir
|
cd $dst_dir
|
||||||
set_fs_ver "$gver" "$gmajor" "$gminor" "$gmicro" "$grev"
|
set_fs_ver "$gver" "$gmajor" "$gminor" "$gmicro" "$grev"
|
||||||
|
echo "$gver" > .version
|
||||||
gnuize
|
gnuize
|
||||||
cd ..
|
cd ..
|
||||||
ls
|
ls
|
||||||
|
|
|
@ -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;
|
|
@ -2300,10 +2300,12 @@ SWITCH_DECLARE(uint32_t) switch_default_ptime(const char *name, uint32_t number)
|
||||||
\param [in] network_ip
|
\param [in] network_ip
|
||||||
\param [in] network_port
|
\param [in] network_port
|
||||||
\param [in] network_proto - one of tls, tcp, udp
|
\param [in] network_proto - one of tls, tcp, udp
|
||||||
|
\param [in] metadata - generic metadata supplied by module
|
||||||
\param [out] err - Error if it exists
|
\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,
|
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
|
\brief Delete user registration
|
||||||
\param [in] user
|
\param [in] user
|
||||||
|
|
|
@ -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];
|
switch_event_node_t *enodes[SWITCH_EVENT_ALL + 1];
|
||||||
uint32_t node_index;
|
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_CONSTRUCTOR ~ EventConsumer();
|
||||||
SWITCH_DECLARE(int) bind(const char *event_name, const char *subclass_name = "");
|
SWITCH_DECLARE(int) bind(const char *event_name, const char *subclass_name = "");
|
||||||
SWITCH_DECLARE(Event *) pop(int block = 0, int timeout = 0);
|
SWITCH_DECLARE(Event *) pop(int block = 0, int timeout = 0);
|
||||||
|
|
|
@ -41,7 +41,7 @@ extern "C" {
|
||||||
#define SWITCH_VERSION_MINOR "@freeswitch_MINOR_VERSION@"
|
#define SWITCH_VERSION_MINOR "@freeswitch_MINOR_VERSION@"
|
||||||
#define SWITCH_VERSION_MICRO "@freeswitch_PATCH_LEVEL@"
|
#define SWITCH_VERSION_MICRO "@freeswitch_PATCH_LEVEL@"
|
||||||
#define SWITCH_VERSION_REVISION "@Project_WC_REVISION@"
|
#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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ extern "C" {
|
||||||
#define SWITCH_VERSION_MINOR "@SWITCH_VERSION_MINOR@"
|
#define SWITCH_VERSION_MINOR "@SWITCH_VERSION_MINOR@"
|
||||||
#define SWITCH_VERSION_MICRO "@SWITCH_VERSION_MICRO@"
|
#define SWITCH_VERSION_MICRO "@SWITCH_VERSION_MICRO@"
|
||||||
#define SWITCH_VERSION_REVISION "@SWITCH_VERSION_REVISION@"
|
#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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,9 +48,23 @@ typedef struct conference_cdr_node_s {
|
||||||
char *record_path;
|
char *record_path;
|
||||||
switch_time_t join_time;
|
switch_time_t join_time;
|
||||||
switch_time_t leave_time;
|
switch_time_t leave_time;
|
||||||
|
uint32_t flags;
|
||||||
struct conference_cdr_node_s *next;
|
struct conference_cdr_node_s *next;
|
||||||
} conference_cdr_node_t;
|
} 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 {
|
typedef enum {
|
||||||
|
@ -175,7 +189,8 @@ typedef enum {
|
||||||
CFLAG_EXIT_SOUND = (1 << 12),
|
CFLAG_EXIT_SOUND = (1 << 12),
|
||||||
CFLAG_ENTER_SOUND = (1 << 13),
|
CFLAG_ENTER_SOUND = (1 << 13),
|
||||||
CFLAG_VIDEO_BRIDGE = (1 << 14),
|
CFLAG_VIDEO_BRIDGE = (1 << 14),
|
||||||
CFLAG_AUDIO_ALWAYS = (1 << 15)
|
CFLAG_AUDIO_ALWAYS = (1 << 15),
|
||||||
|
CFLAG_ENDCONF_FORCED = (1 << 16)
|
||||||
} conf_flag_t;
|
} conf_flag_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -332,6 +347,7 @@ typedef struct conference_obj {
|
||||||
uint32_t originating;
|
uint32_t originating;
|
||||||
switch_call_cause_t cancel_cause;
|
switch_call_cause_t cancel_cause;
|
||||||
conference_cdr_node_t *cdr_nodes;
|
conference_cdr_node_t *cdr_nodes;
|
||||||
|
conference_cdr_reject_t *cdr_rejected;
|
||||||
switch_time_t start_time;
|
switch_time_t start_time;
|
||||||
switch_time_t end_time;
|
switch_time_t end_time;
|
||||||
char *log_dir;
|
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)
|
static void conference_cdr_del(conference_member_t *member)
|
||||||
{
|
{
|
||||||
member->cdr_node->leave_time = switch_epoch_time_now(NULL);
|
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)
|
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);
|
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)
|
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_node_t *np;
|
||||||
|
conference_cdr_reject_t *rp;
|
||||||
int cdr_off = 0, conf_off = 0;
|
int cdr_off = 0, conf_off = 0;
|
||||||
char str[512];
|
char str[512];
|
||||||
char *path, *xml_text;
|
char *path, *xml_text;
|
||||||
|
@ -544,7 +581,7 @@ static void conference_cdr_render(conference_obj_t *conference)
|
||||||
|
|
||||||
if (zstr(conference->log_dir)) return;
|
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"))) {
|
if (!(cdr = switch_xml_new("cdr"))) {
|
||||||
abort();
|
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++))) {
|
if (!(x_ptr = switch_xml_add_child_d(x_conference, "end_time", conf_off++))) {
|
||||||
abort();
|
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_xml_set_attr_d(x_ptr, "type", "UNIX-epoch");
|
||||||
switch_snprintf(str, sizeof(str), "%ld", (long)conference->end_time);
|
switch_snprintf(str, sizeof(str), "%ld", (long)conference->end_time);
|
||||||
switch_xml_set_txt_d(x_ptr, str);
|
switch_xml_set_txt_d(x_ptr, str);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!(x_members = switch_xml_add_child_d(x_conference, "members", conf_off++))) {
|
if (!(x_members = switch_xml_add_child_d(x_conference, "members", conf_off++))) {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (np = conference->cdr_nodes; np; np = np->next) {
|
for (np = conference->cdr_nodes; np; np = np->next) {
|
||||||
int member_off = 0;
|
int member_off = 0;
|
||||||
|
int flag_off = 0;
|
||||||
|
|
||||||
|
|
||||||
if (!(x_member = switch_xml_add_child_d(x_members, "member", conf_off++))) {
|
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);
|
switch_xml_set_txt_d(x_ptr, str);
|
||||||
|
|
||||||
if (np->cp) {
|
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++))) {
|
if (!(x_cp = switch_xml_add_child_d(x_member, "caller_profile", member_off++))) {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
@ -631,8 +682,47 @@ static void conference_cdr_render(conference_obj_t *conference)
|
||||||
}
|
}
|
||||||
switch_xml_set_txt_d(x_ptr, np->record_path);
|
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);
|
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;
|
want_refresh = 0;
|
||||||
|
|
||||||
for (imember = conference->members; imember; imember = imember->next) {
|
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)) {
|
if (switch_channel_test_flag(ichannel, CF_VIDEO_REFRESH_REQ)) {
|
||||||
want_refresh++;
|
want_refresh++;
|
||||||
|
@ -1354,6 +1451,8 @@ static void *SWITCH_THREAD_FUNC conference_video_thread_run(switch_thread_t *thr
|
||||||
has_vid++;
|
has_vid++;
|
||||||
switch_core_session_write_video_frame(imember->session, vid_frame, SWITCH_IO_FLAG_NONE, 0);
|
switch_core_session_write_video_frame(imember->session, vid_frame, SWITCH_IO_FLAG_NONE, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch_core_session_rwunlock(isession);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (want_refresh) {
|
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_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",
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Conference %s: endconf grace time exceeded (%u)\n",
|
||||||
conference->name, conference->endconf_grace_time);
|
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);
|
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++);
|
x_member = switch_xml_add_child_d(x_members, "member", moff++);
|
||||||
switch_assert(x_member);
|
switch_assert(x_member);
|
||||||
|
switch_xml_set_attr_d(x_member, "type", "caller");
|
||||||
|
|
||||||
switch_snprintf(i, sizeof(i), "%d", member->id);
|
switch_snprintf(i, sizeof(i), "%d", member->id);
|
||||||
|
|
||||||
|
@ -6616,6 +6716,7 @@ SWITCH_STANDARD_APP(conference_function)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pin_valid) {
|
if (!pin_valid) {
|
||||||
|
conference_cdr_rejected(conference, channel, CDRR_PIN);
|
||||||
goto done;
|
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 */
|
/* don't allow more callers if the conference is locked, unless we invited them */
|
||||||
if (switch_test_flag(conference, CFLAG_LOCKED) && enforce_security) {
|
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);
|
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) {
|
if (conference->locked_sound) {
|
||||||
/* Answer the channel */
|
/* Answer the channel */
|
||||||
switch_channel_answer(channel);
|
switch_channel_answer(channel);
|
||||||
|
@ -6641,6 +6743,7 @@ SWITCH_STANDARD_APP(conference_function)
|
||||||
*/
|
*/
|
||||||
if ((conference->max_members > 0) && (conference->count >= conference->max_members)) {
|
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);
|
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) {
|
if (conference->maxmember_sound) {
|
||||||
/* Answer the channel */
|
/* Answer the channel */
|
||||||
switch_channel_answer(channel);
|
switch_channel_answer(channel);
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
* Bret McDanel <trixter AT 0xdecafbad dot com>
|
* Bret McDanel <trixter AT 0xdecafbad dot com>
|
||||||
* Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
|
* Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
|
||||||
* Cesar Cepeda <cesar@auronix.com>
|
* 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
|
* mod_dptools.c -- Raw Audio File Streaming Application Module
|
||||||
*
|
*
|
||||||
|
|
|
@ -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
|
@ -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 ------------------------------------------------------------*/
|
|
|
@ -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 ------------------------------------------------------------*/
|
|
|
@ -23,7 +23,10 @@
|
||||||
*
|
*
|
||||||
* Contributor(s):
|
* 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
|
* mod_http_cache.c -- HTTP GET with caching
|
||||||
* -- designed for downloading audio files from a webserver for playback
|
* -- 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)
|
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_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;
|
CURL *curl_handle = NULL;
|
||||||
long httpRes = 0;
|
long httpRes = 0;
|
||||||
struct stat file_info = {0};
|
struct stat file_info = {0};
|
||||||
FILE *file_to_put = NULL;
|
FILE *file_to_put = NULL;
|
||||||
int fd;
|
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 */
|
/* 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);
|
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);
|
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_UPLOAD, 1);
|
||||||
switch_curl_easy_setopt(curl_handle, CURLOPT_PUT, 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_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_URL, url);
|
||||||
switch_curl_easy_setopt(curl_handle, CURLOPT_READDATA, file_to_put);
|
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);
|
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);
|
fclose(file_to_put);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (headers) {
|
||||||
|
switch_curl_slist_free_all(headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_safe_free(buf);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,11 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <io.h>
|
||||||
|
#include <WinSock2.h>
|
||||||
|
#define snprintf _snprintf
|
||||||
|
#else
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
@ -39,6 +44,7 @@
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
@ -550,6 +556,7 @@ REDIS credis_connect(const char *host, int port, int timeout)
|
||||||
int fd, yes = 1;
|
int fd, yes = 1;
|
||||||
struct sockaddr_in sa;
|
struct sockaddr_in sa;
|
||||||
REDIS rhnd;
|
REDIS rhnd;
|
||||||
|
int valid = 0;
|
||||||
|
|
||||||
if ((rhnd = cr_new()) == NULL)
|
if ((rhnd = cr_new()) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -566,7 +573,16 @@ REDIS credis_connect(const char *host, int port, int timeout)
|
||||||
|
|
||||||
sa.sin_family = AF_INET;
|
sa.sin_family = AF_INET;
|
||||||
sa.sin_port = htons(port);
|
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);
|
struct hostent *he = gethostbyname(host);
|
||||||
if (he == NULL)
|
if (he == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
<VisualStudioProject
|
<VisualStudioProject
|
||||||
ProjectType="Visual C++"
|
ProjectType="Visual C++"
|
||||||
Version="9.00"
|
Version="9.00"
|
||||||
Name="mod_fax"
|
Name="mod_redis"
|
||||||
ProjectGUID="{7877EFC8-4807-484B-B573-D7B7FD058FAA}"
|
ProjectGUID="{886B5E9D-F2C2-4AF2-98C8-EF98C4C770E6}"
|
||||||
RootNamespace="mod_fax"
|
RootNamespace="mod_redis"
|
||||||
Keyword="Win32Proj"
|
Keyword="Win32Proj"
|
||||||
TargetFrameworkVersion="131072"
|
TargetFrameworkVersion="131072"
|
||||||
>
|
>
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
Name="Debug|Win32"
|
Name="Debug|Win32"
|
||||||
ConfigurationType="2"
|
ConfigurationType="2"
|
||||||
InheritedPropertySheets="..\..\..\..\w32\module_debug.vsprops"
|
InheritedPropertySheets="..\..\..\..\w32\module_debug.vsprops"
|
||||||
CharacterSet="0"
|
CharacterSet="2"
|
||||||
>
|
>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCPreBuildEventTool"
|
Name="VCPreBuildEventTool"
|
||||||
|
@ -42,7 +42,6 @@
|
||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
AdditionalIncludeDirectories=""$(InputDir)..\..\..\..\libs\spandsp\src\msvc";"$(InputDir)..\..\..\..\libs\spandsp\src";"$(InputDir)..\..\..\..\libs\tiff-3.8.2\libtiff""
|
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
|
@ -56,7 +55,6 @@
|
||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalDependencies="ws2_32.lib"
|
|
||||||
RandomizedBaseAddress="1"
|
RandomizedBaseAddress="1"
|
||||||
DataExecutionPrevention="0"
|
DataExecutionPrevention="0"
|
||||||
/>
|
/>
|
||||||
|
@ -84,9 +82,11 @@
|
||||||
</Configuration>
|
</Configuration>
|
||||||
<Configuration
|
<Configuration
|
||||||
Name="Debug|x64"
|
Name="Debug|x64"
|
||||||
|
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||||
ConfigurationType="2"
|
ConfigurationType="2"
|
||||||
InheritedPropertySheets="..\..\..\..\w32\module_debug.vsprops"
|
InheritedPropertySheets="..\..\..\..\w32\module_debug.vsprops"
|
||||||
CharacterSet="0"
|
CharacterSet="2"
|
||||||
>
|
>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCPreBuildEventTool"
|
Name="VCPreBuildEventTool"
|
||||||
|
@ -106,7 +106,6 @@
|
||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
AdditionalIncludeDirectories=""$(InputDir)..\..\..\..\libs\spandsp\src\msvc";"$(InputDir)..\..\..\..\libs\spandsp\src";"$(InputDir)..\..\..\..\libs\tiff-3.8.2\libtiff""
|
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
|
@ -120,7 +119,6 @@
|
||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalDependencies="ws2_32.lib"
|
|
||||||
OutputFile="$(SolutionDir)$(PlatformName)\$(ConfigurationName)/mod/$(ProjectName).dll"
|
OutputFile="$(SolutionDir)$(PlatformName)\$(ConfigurationName)/mod/$(ProjectName).dll"
|
||||||
RandomizedBaseAddress="1"
|
RandomizedBaseAddress="1"
|
||||||
DataExecutionPrevention="0"
|
DataExecutionPrevention="0"
|
||||||
|
@ -152,7 +150,7 @@
|
||||||
Name="Release|Win32"
|
Name="Release|Win32"
|
||||||
ConfigurationType="2"
|
ConfigurationType="2"
|
||||||
InheritedPropertySheets="..\..\..\..\w32\module_release.vsprops"
|
InheritedPropertySheets="..\..\..\..\w32\module_release.vsprops"
|
||||||
CharacterSet="0"
|
CharacterSet="2"
|
||||||
>
|
>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCPreBuildEventTool"
|
Name="VCPreBuildEventTool"
|
||||||
|
@ -171,7 +169,6 @@
|
||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
AdditionalIncludeDirectories=""$(InputDir)..\..\..\..\libs\spandsp\src\msvc";"$(InputDir)..\..\..\..\libs\spandsp\src";"$(InputDir)..\..\..\..\libs\tiff-3.8.2\libtiff""
|
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
|
@ -185,7 +182,6 @@
|
||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalDependencies="ws2_32.lib"
|
|
||||||
RandomizedBaseAddress="1"
|
RandomizedBaseAddress="1"
|
||||||
DataExecutionPrevention="0"
|
DataExecutionPrevention="0"
|
||||||
/>
|
/>
|
||||||
|
@ -213,9 +209,11 @@
|
||||||
</Configuration>
|
</Configuration>
|
||||||
<Configuration
|
<Configuration
|
||||||
Name="Release|x64"
|
Name="Release|x64"
|
||||||
|
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||||
ConfigurationType="2"
|
ConfigurationType="2"
|
||||||
InheritedPropertySheets="..\..\..\..\w32\module_release.vsprops"
|
InheritedPropertySheets="..\..\..\..\w32\module_release.vsprops"
|
||||||
CharacterSet="0"
|
CharacterSet="2"
|
||||||
>
|
>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCPreBuildEventTool"
|
Name="VCPreBuildEventTool"
|
||||||
|
@ -235,7 +233,6 @@
|
||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
AdditionalIncludeDirectories=""$(InputDir)..\..\..\..\libs\spandsp\src\msvc";"$(InputDir)..\..\..\..\libs\spandsp\src";"$(InputDir)..\..\..\..\libs\tiff-3.8.2\libtiff""
|
|
||||||
UsePrecompiledHeader="0"
|
UsePrecompiledHeader="0"
|
||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
|
@ -249,7 +246,6 @@
|
||||||
/>
|
/>
|
||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalDependencies="ws2_32.lib"
|
|
||||||
OutputFile="$(SolutionDir)$(PlatformName)\$(ConfigurationName)/mod/$(ProjectName).dll"
|
OutputFile="$(SolutionDir)$(PlatformName)\$(ConfigurationName)/mod/$(ProjectName).dll"
|
||||||
RandomizedBaseAddress="1"
|
RandomizedBaseAddress="1"
|
||||||
DataExecutionPrevention="0"
|
DataExecutionPrevention="0"
|
||||||
|
@ -282,15 +278,15 @@
|
||||||
</References>
|
</References>
|
||||||
<Files>
|
<Files>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\mod_fax.c"
|
RelativePath=".\mod_redis.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\udptl.c"
|
RelativePath=".\credis.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\udptl.h"
|
RelativePath=".\credis.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
</Files>
|
</Files>
|
|
@ -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>
|
|
@ -29,7 +29,7 @@
|
||||||
* Brian West <brian@freeswitch.org>
|
* Brian West <brian@freeswitch.org>
|
||||||
* Steve Underwood <steveu@coppice.org>
|
* Steve Underwood <steveu@coppice.org>
|
||||||
* Antonio Gallo <agx@linux.it>
|
* 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
|
* mod_spandsp.c -- Module implementing spandsp fax, dsp, and codec functionality
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
* Anthony Minessale II <anthm@freeswitch.org>
|
* Anthony Minessale II <anthm@freeswitch.org>
|
||||||
* Steve Underwood <steveu@coppice.org>
|
* Steve Underwood <steveu@coppice.org>
|
||||||
* Antonio Gallo <agx@linux.it>
|
* 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
|
* mod_spandsp_dsp.c -- dsp applications provided by SpanDSP
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -3489,7 +3489,7 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, vm_p
|
||||||
|
|
||||||
switch_safe_free(file_path);
|
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);
|
status = switch_ivr_phrase_macro(session, VM_GOODBYE_MACRO, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
* The Original Code is FreeSWITCH mod_unimrcp
|
* The Original Code is FreeSWITCH mod_unimrcp
|
||||||
*
|
*
|
||||||
* The Initial Developer of the Original Code is
|
* 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)
|
* Portions created by the Initial Developer are Copyright (C)
|
||||||
* the Initial Developer. All Rights Reserved.
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
@ -25,9 +25,11 @@
|
||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
*
|
*
|
||||||
* Brian West <brian@freeswitch.org>
|
* Brian West <brian@freeswitch.org>
|
||||||
* Christopher M. Rienzo <chris@rienzo.net>
|
* Christopher M. Rienzo <chris@rienzo.com>
|
||||||
* Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
|
* Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
|
||||||
*
|
*
|
||||||
|
* Maintainer: Christopher M. Rienzo <chris@rienzo.com>
|
||||||
|
*
|
||||||
* mod_unimrcp.c -- UniMRCP module (MRCP client)
|
* mod_unimrcp.c -- UniMRCP module (MRCP client)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
*
|
*
|
||||||
* Anthony Minessale II <anthm@freeswitch.org>
|
* Anthony Minessale II <anthm@freeswitch.org>
|
||||||
* Chris Rienzo <chris@rienzo.net>
|
* Christopher M. Rienzo <chris@rienzo.com>
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* mod_speex.c -- Speex Codec Module
|
* mod_speex.c -- Speex Codec Module
|
||||||
|
|
|
@ -132,7 +132,7 @@
|
||||||
//#define SAMPLES_PER_FRAME SAMPLERATE_GSMOPEN/50
|
//#define SAMPLES_PER_FRAME SAMPLERATE_GSMOPEN/50
|
||||||
|
|
||||||
#ifndef GSMOPEN_SVN_VERSION
|
#ifndef GSMOPEN_SVN_VERSION
|
||||||
#define GSMOPEN_SVN_VERSION SWITCH_VERSION_REVISION
|
#define GSMOPEN_SVN_VERSION SWITCH_VERSION_FULL
|
||||||
#endif /* GSMOPEN_SVN_VERSION */
|
#endif /* GSMOPEN_SVN_VERSION */
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
* 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
|
* Version: MPL 1.1
|
||||||
*
|
*
|
||||||
|
@ -23,17 +23,15 @@
|
||||||
*
|
*
|
||||||
* This module (mod_gsmopen) has been contributed by:
|
* 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.cpp -- GSM Modem compatible Endpoint Module
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* mod_gsmopen.c -- GSM compatible Endpoint Module
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#define __STDC_LIMIT_MACROS
|
#define __STDC_LIMIT_MACROS
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
@ -115,7 +113,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef GSMOPEN_SVN_VERSION
|
#ifndef GSMOPEN_SVN_VERSION
|
||||||
#define GSMOPEN_SVN_VERSION SWITCH_VERSION_REVISION
|
#define GSMOPEN_SVN_VERSION SWITCH_VERSION_FULL
|
||||||
#endif /* GSMOPEN_SVN_VERSION */
|
#endif /* GSMOPEN_SVN_VERSION */
|
||||||
|
|
||||||
#include "ctb-0.16/ctb.h"
|
#include "ctb-0.16/ctb.h"
|
||||||
|
|
|
@ -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"
|
#include "gsmopen.h"
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include "win_iconv.c"
|
#include "win_iconv.c"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
* 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
|
* Version: MPL 1.1
|
||||||
*
|
*
|
||||||
|
@ -23,14 +23,11 @@
|
||||||
*
|
*
|
||||||
* This module (mod_gsmopen) has been contributed by:
|
* 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.cpp -- GSM Modem compatible Endpoint Module
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* mod_gsmopen.c -- GSM compatible Endpoint Module
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -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");
|
const char *value = switch_xml_attr_soft(xbutton, "value");
|
||||||
if(type == SKINNY_BUTTON_LINE) {
|
if(type == SKINNY_BUTTON_LINE) {
|
||||||
const char *caller_name = switch_xml_attr_soft(xbutton, "caller-name");
|
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_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 ring_on_active = atoi(switch_xml_attr_soft(xbutton, "ring-on-active"));
|
||||||
uint32_t busy_trigger = atoi(switch_xml_attr_soft(xbutton, "busy-trigger"));
|
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);
|
switch_safe_free(sql);
|
||||||
token = switch_mprintf("skinny/%q/%q/%q:%d", profile->name, value, request->data.reg.device_name, request->data.reg.instance);
|
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);
|
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(token);
|
||||||
switch_safe_free(url);
|
switch_safe_free(url);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
* 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
|
* Version: MPL 1.1
|
||||||
*
|
*
|
||||||
|
@ -21,19 +21,17 @@
|
||||||
* Portions created by the Initial Developer are Copyright (C)
|
* Portions created by the Initial Developer are Copyright (C)
|
||||||
* the Initial Developer. All Rights Reserved.
|
* 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
|
* mod_skypopen.c -- Skype compatible Endpoint Module
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "skypopen.h"
|
#include "skypopen.h"
|
||||||
#define SKYPE_CHAT_PROTO "skype"
|
#define SKYPE_CHAT_PROTO "skype"
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
#include <linux/cdev.h>
|
#include <linux/cdev.h>
|
||||||
|
|
||||||
#include <asm/system.h> /* cli(), *_flags */
|
|
||||||
#include <asm/uaccess.h> /* copy_*_user */
|
#include <asm/uaccess.h> /* copy_*_user */
|
||||||
|
|
||||||
#include <linux/soundcard.h>
|
#include <linux/soundcard.h>
|
||||||
|
|
|
@ -21,6 +21,12 @@
|
||||||
|
|
||||||
#include <linux/version.h>
|
#include <linux/version.h>
|
||||||
#include <linux/ioctl.h> /* needed for the _IOW etc stuff used later */
|
#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)
|
#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 18)
|
||||||
#define CENTOS_5
|
#define CENTOS_5
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
* 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
|
* Version: MPL 1.1
|
||||||
*
|
*
|
||||||
|
@ -21,18 +21,17 @@
|
||||||
* Portions created by the Initial Developer are Copyright (C)
|
* Portions created by the Initial Developer are Copyright (C)
|
||||||
* the Initial Developer. All Rights Reserved.
|
* 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)
|
* Giovanni Maruzzelli <gmaruzz@gmail.com>
|
||||||
*
|
|
||||||
*
|
|
||||||
* Further Contributors:
|
|
||||||
*
|
*
|
||||||
|
* Maintainer: Giovanni Maruzzelli <gmaruzz@gmail.com>
|
||||||
*
|
*
|
||||||
* mod_skypopen.c -- Skype compatible Endpoint Module
|
* mod_skypopen.c -- Skype compatible Endpoint Module
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
#include <switch_version.h>
|
#include <switch_version.h>
|
||||||
|
|
||||||
|
@ -86,7 +85,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef SKYPOPEN_SVN_VERSION
|
#ifndef SKYPOPEN_SVN_VERSION
|
||||||
#define SKYPOPEN_SVN_VERSION SWITCH_VERSION_REVISION
|
#define SKYPOPEN_SVN_VERSION SWITCH_VERSION_FULL
|
||||||
#endif /* SKYPOPEN_SVN_VERSION */
|
#endif /* SKYPOPEN_SVN_VERSION */
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
|
@ -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"
|
#include "skypopen.h"
|
||||||
|
|
||||||
#ifdef ASTERISK
|
#ifdef ASTERISK
|
||||||
|
|
|
@ -242,6 +242,8 @@
|
||||||
<!-- TLS version ("sslv23" (default), "tlsv1"). NOTE: Phones may not
|
<!-- TLS version ("sslv23" (default), "tlsv1"). NOTE: Phones may not
|
||||||
work with TLSv1 -->
|
work with TLSv1 -->
|
||||||
<param name="tls-version" value="$${sip_tls_version}"/>
|
<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
|
<!-- turn on auto-flush during bridge (skip timer sleep when the socket
|
||||||
already has data) (reduces delay on latent connections default
|
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 -->
|
<!-- Let calls hit the dialplan before selecting codec for the a-leg -->
|
||||||
<param name="inbound-late-negotiation" value="true"/>
|
<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"/>
|
<param name="inbound-zrtp-passthru" value="true"/>
|
||||||
|
|
||||||
<!-- this lets anything register -->
|
<!-- this lets anything register -->
|
||||||
|
|
|
@ -1587,6 +1587,8 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
||||||
|
|
||||||
case SWITCH_MESSAGE_INDICATE_BRIDGE:
|
case SWITCH_MESSAGE_INDICATE_BRIDGE:
|
||||||
{
|
{
|
||||||
|
|
||||||
|
switch_channel_set_variable(channel, SOFIA_REPLACES_HEADER, NULL);
|
||||||
sofia_glue_tech_track(tech_pvt->profile, session);
|
sofia_glue_tech_track(tech_pvt->profile, session);
|
||||||
|
|
||||||
sofia_set_flag(tech_pvt, TFLAG_SIMPLIFY);
|
sofia_set_flag(tech_pvt, TFLAG_SIMPLIFY);
|
||||||
|
@ -2337,6 +2339,19 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SWITCH_MESSAGE_INDICATE_RESPOND:
|
case SWITCH_MESSAGE_INDICATE_RESPOND:
|
||||||
|
{
|
||||||
|
int status = 0;
|
||||||
|
|
||||||
|
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 (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;
|
||||||
|
}
|
||||||
|
|
||||||
if (msg->numeric_arg || msg->string_arg) {
|
if (msg->numeric_arg || msg->string_arg) {
|
||||||
int code = msg->numeric_arg;
|
int code = msg->numeric_arg;
|
||||||
const char *reason = NULL;
|
const char *reason = NULL;
|
||||||
|
@ -2483,6 +2498,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SWITCH_MESSAGE_INDICATE_RINGING:
|
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 *body = switch_event_get_body(event);
|
||||||
const char *to_uri = switch_event_get_header(event, "to-uri");
|
const char *to_uri = switch_event_get_header(event, "to-uri");
|
||||||
const char *from_uri = switch_event_get_header(event, "from-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;
|
sofia_profile_t *profile;
|
||||||
|
|
||||||
|
|
||||||
|
@ -4977,7 +4995,8 @@ static void general_event_handler(switch_event_t *event)
|
||||||
nua_notify(nh,
|
nua_notify(nh,
|
||||||
NUTAG_NEWSUB(1), SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
|
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)),
|
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);
|
switch_safe_free(route_uri);
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
* Paul D. Tinsley <pdt at jackhammer.org>
|
* Paul D. Tinsley <pdt at jackhammer.org>
|
||||||
* Bret McDanel <trixter AT 0xdecafbad.com>
|
* Bret McDanel <trixter AT 0xdecafbad.com>
|
||||||
* Marcel Barbulescu <marcelbarbulescu@gmail.com>
|
* Marcel Barbulescu <marcelbarbulescu@gmail.com>
|
||||||
|
* Raymond Chandler <intralanman@gmail.com>
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* mod_sofia.h -- SOFIA SIP Endpoint
|
* mod_sofia.h -- SOFIA SIP Endpoint
|
||||||
|
@ -92,7 +93,7 @@ typedef struct private_object private_object_t;
|
||||||
|
|
||||||
#define MULTICAST_EVENT "multicast::event"
|
#define MULTICAST_EVENT "multicast::event"
|
||||||
#define SOFIA_REPLACES_HEADER "_sofia_replaces_"
|
#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_CHAT_PROTO "sip"
|
||||||
#define SOFIA_MULTIPART_PREFIX "sip_mp_"
|
#define SOFIA_MULTIPART_PREFIX "sip_mp_"
|
||||||
#define SOFIA_MULTIPART_PREFIX_T "~sip_mp_"
|
#define SOFIA_MULTIPART_PREFIX_T "~sip_mp_"
|
||||||
|
@ -517,7 +518,8 @@ struct sofia_gateway {
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PRES_TYPE_NONE = 0,
|
PRES_TYPE_NONE = 0,
|
||||||
PRES_TYPE_FULL = 1,
|
PRES_TYPE_FULL = 1,
|
||||||
PRES_TYPE_PASSIVE = 2
|
PRES_TYPE_PASSIVE = 2,
|
||||||
|
PRES_TYPE_PNP = 3
|
||||||
} sofia_presence_type_t;
|
} sofia_presence_type_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -586,12 +588,15 @@ struct sofia_profile {
|
||||||
char *rtcp_audio_interval_msec;
|
char *rtcp_audio_interval_msec;
|
||||||
char *rtcp_video_interval_msec;
|
char *rtcp_video_interval_msec;
|
||||||
char *jb_msec;
|
char *jb_msec;
|
||||||
|
char *pnp_prov_url;
|
||||||
|
char *pnp_notify_profile;
|
||||||
sofia_cid_type_t cid_type;
|
sofia_cid_type_t cid_type;
|
||||||
sofia_dtmf_t dtmf_type;
|
sofia_dtmf_t dtmf_type;
|
||||||
int auto_restart;
|
int auto_restart;
|
||||||
switch_port_t sip_port;
|
switch_port_t sip_port;
|
||||||
switch_port_t tls_sip_port;
|
switch_port_t tls_sip_port;
|
||||||
int tls_version;
|
int tls_version;
|
||||||
|
unsigned int tls_timeout;
|
||||||
char *inbound_codec_string;
|
char *inbound_codec_string;
|
||||||
char *outbound_codec_string;
|
char *outbound_codec_string;
|
||||||
int running;
|
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_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_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_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);
|
const char *network_ip);
|
||||||
void sofia_glue_restart_all_profiles(void);
|
void sofia_glue_restart_all_profiles(void);
|
||||||
int sofia_glue_toggle_hold(private_object_t *tech_pvt, int sendonly);
|
int sofia_glue_toggle_hold(private_object_t *tech_pvt, int sendonly);
|
||||||
|
|
|
@ -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)),
|
TPTAG_TLS_VERIFY_SUBJECTS(profile->tls_verify_in_subjects)),
|
||||||
TAG_IF(sofia_test_pflag(profile, PFLAG_TLS),
|
TAG_IF(sofia_test_pflag(profile, PFLAG_TLS),
|
||||||
TPTAG_TLS_VERSION(profile->tls_version)),
|
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, ':'),
|
TAG_IF(!strchr(profile->sipip, ':'),
|
||||||
NTATAG_UDP_MTU(65535)),
|
NTATAG_UDP_MTU(65535)),
|
||||||
TAG_IF(sofia_test_pflag(profile, PFLAG_DISABLE_SRV),
|
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("include-session-description")),
|
||||||
TAG_IF(profile->pres_type, NUTAG_ALLOW_EVENTS("presence.winfo")),
|
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, 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());
|
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);
|
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);
|
sofia_clear_pflag_locked(profile, PFLAG_SHUTDOWN);
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Waiting for worker thread\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Waiting for worker thread\n");
|
||||||
|
|
||||||
|
if ( worker_thread ) {
|
||||||
switch_thread_join(&st, 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;
|
sanity = 4;
|
||||||
while (profile->inuse) {
|
while (profile->inuse) {
|
||||||
|
@ -3929,6 +3936,7 @@ switch_status_t config_sofia(int reload, char *profile_name)
|
||||||
profile->sip_force_expires = 0;
|
profile->sip_force_expires = 0;
|
||||||
profile->sip_expires_max_deviation = 0;
|
profile->sip_expires_max_deviation = 0;
|
||||||
profile->tls_version = 0;
|
profile->tls_version = 0;
|
||||||
|
profile->tls_timeout = 300;
|
||||||
profile->mflags = MFLAG_REFER | MFLAG_REGISTER;
|
profile->mflags = MFLAG_REFER | MFLAG_REGISTER;
|
||||||
profile->server_rport_level = 1;
|
profile->server_rport_level = 1;
|
||||||
profile->client_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")) {
|
} else if (!strcasecmp(val, "bypass-media-after-att-xfer")) {
|
||||||
profile->media_options |= MEDIA_OPT_BYPASS_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")) {
|
} else if (!strcasecmp(var, "manage-presence")) {
|
||||||
if (!strcasecmp(val, "passive")) {
|
if (!strcasecmp(val, "passive")) {
|
||||||
profile->pres_type = PRES_TYPE_PASSIVE;
|
profile->pres_type = PRES_TYPE_PASSIVE;
|
||||||
|
|
||||||
|
} else if (!strcasecmp(val, "pnp")) {
|
||||||
|
profile->pres_type = PRES_TYPE_PNP;
|
||||||
} else if (switch_true(val)) {
|
} else if (switch_true(val)) {
|
||||||
profile->pres_type = PRES_TYPE_FULL;
|
profile->pres_type = PRES_TYPE_FULL;
|
||||||
}
|
}
|
||||||
|
@ -4743,6 +4757,9 @@ switch_status_t config_sofia(int reload, char *profile_name)
|
||||||
} else {
|
} else {
|
||||||
profile->tls_version = 0;
|
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")) {
|
} else if (!strcasecmp(var, "timer-T1")) {
|
||||||
int v = atoi(val);
|
int v = atoi(val);
|
||||||
if (v > 0) {
|
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);
|
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);
|
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);
|
config_sofia_profile_urls(profile);
|
||||||
|
|
||||||
if (sofia_test_pflag(profile, PFLAG_TLS) && !profile->tls_cert_dir) {
|
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);
|
tech_pvt->remote_sdp_str = switch_core_session_strdup(session, r_sdp);
|
||||||
switch_channel_set_variable(channel, SWITCH_R_SDP_VARIABLE, 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))) {
|
if ((sdp = sdp_session(parser))) {
|
||||||
sofia_glue_set_r_sdp_codec_string(session, sofia_glue_get_codec_string(tech_pvt), sdp);
|
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());
|
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) {
|
if (sip->sip_referred_by) {
|
||||||
full_ref_by = sip_header_as_string(home, (void *) 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[])
|
tagi_t tags[])
|
||||||
{
|
{
|
||||||
char *call_info = NULL;
|
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)) {
|
if (session && profile && sip && sofia_test_pflag(profile, PFLAG_TRACK_CALLS)) {
|
||||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
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)) {
|
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) {
|
if (channel && sip->sip_call_info) {
|
||||||
char *p;
|
char *p;
|
||||||
if ((call_info = sip_header_as_string(nua_handle_home(nh), (void *) sip->sip_call_info))) {
|
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,
|
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,
|
||||||
|
|
|
@ -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);
|
tech_pvt->local_sdp_audio_zrtp_hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sr) {
|
if (!zstr(sr)) {
|
||||||
switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=%s\n", 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)
|
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;
|
int ptime = 0;
|
||||||
uint32_t rate = 0;
|
uint32_t rate = 0;
|
||||||
uint32_t v_port;
|
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;
|
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))) {
|
&& (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) || switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA))) {
|
||||||
return;
|
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);
|
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"))) {
|
if ((var_val = switch_channel_get_variable(tech_pvt->channel, "media_audio_mode"))) {
|
||||||
sr = var_val;
|
sr = var_val;
|
||||||
} else {
|
} 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) ||
|
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))) {
|
((var_val = switch_channel_get_variable(tech_pvt->channel, "ndlb_sendrecv_in_session")) && switch_true(var_val))) {
|
||||||
|
if (!zstr(sr)) {
|
||||||
switch_snprintf(srbuf, sizeof(srbuf), "a=%s\n", sr);
|
switch_snprintf(srbuf, sizeof(srbuf), "a=%s\n", sr);
|
||||||
|
}
|
||||||
sr = NULL;
|
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);
|
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);
|
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;
|
cur_ptime = this_ptime;
|
||||||
|
|
||||||
if ((!zstr(tech_pvt->local_crypto_key) && sofia_test_flag(tech_pvt, TFLAG_SECURE))) {
|
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));
|
bp = (buf + strlen(buf));
|
||||||
|
|
||||||
/* asterisk can't handle AVP and SAVP in sep streams, way to blow off the spec....*/
|
/* asterisk can't handle AVP and SAVP in sep streams, way to blow off the spec....*/
|
||||||
|
@ -776,8 +778,13 @@ 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 *sofia_glue_get_codec_string(private_object_t *tech_pvt)
|
||||||
{
|
{
|
||||||
const char *codec_string = NULL, *preferred = NULL, *fallback = NULL;
|
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) {
|
if (switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
|
||||||
preferred = tech_pvt->profile->outbound_codec_string;
|
preferred = tech_pvt->profile->outbound_codec_string;
|
||||||
fallback = tech_pvt->profile->inbound_codec_string;
|
fallback = tech_pvt->profile->inbound_codec_string;
|
||||||
|
@ -785,10 +792,9 @@ const char *sofia_glue_get_codec_string(private_object_t *tech_pvt)
|
||||||
preferred = tech_pvt->profile->inbound_codec_string;
|
preferred = tech_pvt->profile->inbound_codec_string;
|
||||||
fallback = tech_pvt->profile->outbound_codec_string;
|
fallback = tech_pvt->profile->outbound_codec_string;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
codec_string = !zstr(preferred) ? preferred : fallback;
|
return !zstr(preferred) ? preferred : fallback;
|
||||||
|
|
||||||
return codec_string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sofia_glue_tech_prepare_codecs(private_object_t *tech_pvt)
|
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);
|
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;
|
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)) {
|
if (sofia_use_soa(tech_pvt)) {
|
||||||
nua_invite(tech_pvt->nh,
|
nua_invite(tech_pvt->nh,
|
||||||
NUTAG_AUTOANSWER(0),
|
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)
|
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);
|
switch_channel_t *aleg_channel;
|
||||||
private_object_t *aleg_tech_pvt = switch_core_session_get_private(aleg_session);
|
private_object_t *aleg_tech_pvt;
|
||||||
switch_channel_t *bleg_channel = switch_core_session_get_channel(bleg_session);
|
switch_channel_t *bleg_channel;
|
||||||
private_object_t *bleg_tech_pvt = switch_core_session_get_private(bleg_session);
|
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");
|
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))) {
|
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");
|
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;
|
int changed = 0;
|
||||||
|
|
||||||
if (sofia_test_flag(tech_pvt, TFLAG_SLA_BARGE) || sofia_test_flag(tech_pvt, TFLAG_SLA_BARGING)) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4697,10 +4722,6 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
|
||||||
goto done;
|
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"))) {
|
if (switch_true(switch_channel_get_variable(channel, "refuse_t38"))) {
|
||||||
switch_channel_clear_app_flag_key("T38", tech_pvt->channel, CF_APP_T38);
|
switch_channel_clear_app_flag_key("T38", tech_pvt->channel, CF_APP_T38);
|
||||||
match = 0;
|
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");
|
const char *var = switch_channel_get_variable(channel, "t38_passthru");
|
||||||
int pass = sofia_test_pflag(tech_pvt->profile, PFLAG_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 (var) {
|
||||||
if (!(pass = switch_true(var))) {
|
if (!(pass = switch_true(var))) {
|
||||||
if (!strcasecmp(var, "once")) {
|
if (!strcasecmp(var, "once")) {
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
* Ken Rice <krice@freeswitch.org>
|
* Ken Rice <krice@freeswitch.org>
|
||||||
* Paul D. Tinsley <pdt at jackhammer.org>
|
* Paul D. Tinsley <pdt at jackhammer.org>
|
||||||
* Bret McDanel <trixter AT 0xdecafbad.com>
|
* Bret McDanel <trixter AT 0xdecafbad.com>
|
||||||
|
* Raymond Chandler <intralanman@gmail.com>
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* sofia_presence.c -- SOFIA SIP Endpoint (presence code)
|
* 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,"
|
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"
|
"full_via,expires,user_agent,accept,profile_name,network_ip"
|
||||||
",'%q',full_to,network_ip,network_port from sip_subscriptions "
|
",'%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%%')",
|
"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) {
|
} 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,"
|
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"
|
"full_via,expires,user_agent,accept,profile_name,network_ip"
|
||||||
",'%q',full_to,network_ip,network_port from sip_subscriptions where "
|
",'%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'",
|
"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) {
|
if (for_everyone) {
|
||||||
sql = switch_mprintf("select sip_user,sip_host,contact,profile_name,network_ip,'%q',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 mwi_user='%q' and mwi_host='%q'",
|
"from sip_registrations where hostname='%q' and mwi_user='%q' and mwi_host='%q'",
|
||||||
stream.data, mod_sofia_globals.hostname, profile->name, user, host);
|
stream.data, mod_sofia_globals.hostname, user, host);
|
||||||
} else if (call_id) {
|
} else if (call_id) {
|
||||||
sql = switch_mprintf("select sip_user,sip_host,contact,profile_name,network_ip,'%q',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'",
|
"from sip_registrations where hostname='%q' and call_id='%q'",
|
||||||
stream.data, mod_sofia_globals.hostname, profile->name, call_id);
|
stream.data, mod_sofia_globals.hostname, call_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sql) {
|
if (sql) {
|
||||||
|
@ -3273,7 +3274,9 @@ void sofia_presence_handle_sip_i_subscribe(int status,
|
||||||
int sent_reply = 0;
|
int sent_reply = 0;
|
||||||
sip_contact_t const *contact;
|
sip_contact_t const *contact;
|
||||||
const char *ipv6;
|
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 } };
|
sofia_nat_parse_t np = { { 0 } };
|
||||||
int found_proto = 0;
|
int found_proto = 0;
|
||||||
char to_tag[13] = "";
|
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);
|
switch_stun_random_string(to_tag, 12, NULL);
|
||||||
|
|
||||||
//contact_host = sip->sip_contact->m_url->url_host;
|
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;
|
contact_user = sip->sip_contact->m_url->url_user;
|
||||||
|
}
|
||||||
|
|
||||||
//tl_gets(tags, NUTAG_SUBSTATE_REF(sub_state), TAG_END());
|
//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(¶ms, 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(¶ms);
|
||||||
|
|
||||||
|
switch_safe_free(uri);
|
||||||
|
switch_safe_free(extra_headers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
|
||||||
if (strcasecmp(event, "call-info") && strcasecmp(event, "line-seize")) {
|
if (strcasecmp(event, "call-info") && strcasecmp(event, "line-seize")) {
|
||||||
|
|
|
@ -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 *network_ip)
|
||||||
{
|
{
|
||||||
const char *event = "check-sync";
|
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";
|
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)
|
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;
|
sofia_profile_t *profile = (sofia_profile_t *) pArg;
|
||||||
|
|
||||||
if (argc > 12 && atoi(argv[12]) == 1) {
|
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) {
|
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_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;
|
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;
|
sip_contact_t const *contact = NULL;
|
||||||
char *sql;
|
char *sql;
|
||||||
switch_event_t *s_event;
|
switch_event_t *s_event;
|
||||||
|
const char *reg_meta = NULL;
|
||||||
const char *to_user = NULL;
|
const char *to_user = NULL;
|
||||||
const char *to_host = NULL;
|
const char *to_host = NULL;
|
||||||
char *mwi_account = 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;
|
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"))) {
|
if (v_event && *v_event && (mwi_account = switch_event_get_header(*v_event, "mwi-account"))) {
|
||||||
dup_mwi_account = strdup(mwi_account);
|
dup_mwi_account = strdup(mwi_account);
|
||||||
switch_assert(dup_mwi_account != NULL);
|
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));
|
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,
|
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(url);
|
||||||
switch_safe_free(contact);
|
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");
|
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,
|
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) {
|
&x_user, locate_params) == SWITCH_STATUS_SUCCESS) {
|
||||||
if ((x_params = switch_xml_child(x_user, "params"))) {
|
if ((x_params = switch_xml_child(x_user, "params"))) {
|
||||||
|
|
|
@ -145,7 +145,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session)
|
||||||
for (ap = app_log; ap; ap = ap->next) {
|
for (ap = app_log; ap; ap = ap->next) {
|
||||||
bson_append_start_object(&cdr, "application");
|
bson_append_start_object(&cdr, "application");
|
||||||
bson_append_string(&cdr, "app_name", ap->app);
|
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_long(&cdr, "app_stamp", ap->stamp);
|
||||||
bson_append_finish_object(&cdr); /* application */
|
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_bool(&cdr, "last_executed", 1);
|
||||||
}
|
}
|
||||||
bson_append_string(&cdr, "app_name", ap->application_name);
|
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);
|
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_bool(&cdr, "last_executed", 1);
|
||||||
}
|
}
|
||||||
bson_append_string(&cdr, "app_name", ap->application_name);
|
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);
|
bson_append_finish_object(&cdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
* Rob Charlton <rob.charlton@savageminds.com>
|
* Rob Charlton <rob.charlton@savageminds.com>
|
||||||
* Darren Schreiber <d@d-man.org>
|
* Darren Schreiber <d@d-man.org>
|
||||||
* Mike Jerris <mike@jerris.com>
|
* Mike Jerris <mike@jerris.com>
|
||||||
|
* Tamas Cseke <tamas.cseke@virtual-call-center.eu>
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* handle_msg.c -- handle messages received from erlang nodes
|
* 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_set_flag_locked(listener, LFLAG_EVENTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch_thread_rwlock_wrlock(listener->event_rwlock);
|
||||||
|
|
||||||
for (i = 1; i < arity; i++) {
|
for (i = 1; i < arity; i++) {
|
||||||
if (!ei_decode_atom(buf->buff, &buf->index, atom)) {
|
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_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");
|
ei_x_encode_atom(rbuf, "ok");
|
||||||
}
|
}
|
||||||
return SWITCH_STATUS_SUCCESS;
|
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;
|
switch_event_types_t type;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
switch_thread_rwlock_wrlock(session->event_rwlock);
|
||||||
|
|
||||||
for (i = 1; i < arity; i++) {
|
for (i = 1; i < arity; i++) {
|
||||||
if (!ei_decode_atom(buf->buff, &buf->index, atom)) {
|
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_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");
|
ei_x_encode_atom(rbuf, "ok");
|
||||||
} else {
|
} else {
|
||||||
ei_x_encode_tuple_header(rbuf, 2);
|
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;
|
int i = 0;
|
||||||
switch_event_types_t type;
|
switch_event_types_t type;
|
||||||
|
|
||||||
|
switch_thread_rwlock_wrlock(listener->event_rwlock);
|
||||||
|
|
||||||
for (i = 1; i < arity; i++) {
|
for (i = 1; i < arity; i++) {
|
||||||
if (!ei_decode_atom(buf->buff, &buf->index, atom)) {
|
if (!ei_decode_atom(buf->buff, &buf->index, atom)) {
|
||||||
|
|
||||||
if (custom) {
|
if (custom) {
|
||||||
|
|
||||||
switch_core_hash_delete(listener->event_hash, atom);
|
switch_core_hash_delete(listener->event_hash, atom);
|
||||||
} else if (switch_name_event(atom, &type) == SWITCH_STATUS_SUCCESS) {
|
} else if (switch_name_event(atom, &type) == SWITCH_STATUS_SUCCESS) {
|
||||||
uint32_t x = 0;
|
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");
|
ei_x_encode_atom(rbuf, "ok");
|
||||||
}
|
}
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
@ -426,6 +441,8 @@ static switch_status_t handle_msg_session_nixevent(listener_t *listener, erlang_
|
||||||
int i = 0;
|
int i = 0;
|
||||||
switch_event_types_t type;
|
switch_event_types_t type;
|
||||||
|
|
||||||
|
switch_thread_rwlock_wrlock(session->event_rwlock);
|
||||||
|
|
||||||
for (i = 1; i < arity; i++) {
|
for (i = 1; i < arity; i++) {
|
||||||
if (!ei_decode_atom(buf->buff, &buf->index, atom)) {
|
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");
|
ei_x_encode_atom(rbuf, "ok");
|
||||||
} else { /* no session for this pid */
|
} else { /* no session for this pid */
|
||||||
ei_x_encode_tuple_header(rbuf, 2);
|
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;
|
int i = 0;
|
||||||
|
|
||||||
/* clear any previous event registrations */
|
/* 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;
|
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 */
|
/* 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));
|
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);
|
switch_core_hash_destroy(&listener->event_hash);
|
||||||
listener->event_hash = 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 */
|
/* TODO - we should flush any non-matching events from the queue */
|
||||||
ei_x_encode_atom(rbuf, "ok");
|
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);
|
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 */
|
/* 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));
|
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 */
|
/* wipe the old hash, and point the pointer at the new one */
|
||||||
switch_core_hash_destroy(&session->event_hash);
|
switch_core_hash_destroy(&session->event_hash);
|
||||||
session->event_hash = 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 */
|
/* TODO - we should flush any non-matching events from the queue */
|
||||||
ei_x_encode_atom(rbuf, "ok");
|
ei_x_encode_atom(rbuf, "ok");
|
||||||
} else { /* no session for this pid */
|
} else { /* no session for this pid */
|
||||||
|
@ -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_tuple_header(rbuf, 2);
|
||||||
ei_x_encode_atom(rbuf, "error");
|
ei_x_encode_atom(rbuf, "error");
|
||||||
ei_x_encode_atom(rbuf, "badarg");
|
ei_x_encode_atom(rbuf, "badarg");
|
||||||
|
switch_event_destroy(&event);
|
||||||
} else {
|
} else {
|
||||||
if (switch_core_session_queue_private_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
|
if (switch_core_session_queue_private_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
|
||||||
ei_x_encode_atom(rbuf, "ok");
|
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_tuple_header(rbuf, 2);
|
||||||
ei_x_encode_atom(rbuf, "error");
|
ei_x_encode_atom(rbuf, "error");
|
||||||
ei_x_encode_atom(rbuf, "badmem");
|
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)) {
|
if (switch_test_flag(listener, LFLAG_EVENTS)) {
|
||||||
uint8_t x = 0;
|
uint8_t x = 0;
|
||||||
switch_clear_flag_locked(listener, LFLAG_EVENTS);
|
switch_clear_flag_locked(listener, LFLAG_EVENTS);
|
||||||
|
|
||||||
|
switch_thread_rwlock_wrlock(listener->event_rwlock);
|
||||||
for (x = 0; x <= SWITCH_EVENT_ALL; x++) {
|
for (x = 0; x <= SWITCH_EVENT_ALL; x++) {
|
||||||
listener->event_list[x] = 0;
|
listener->event_list[x] = 0;
|
||||||
}
|
}
|
||||||
/* wipe the hash */
|
|
||||||
switch_core_hash_destroy(&listener->event_hash);
|
switch_core_hash_delete_multi(listener->event_hash, NULL, NULL);
|
||||||
switch_core_hash_init(&listener->event_hash, listener->pool);
|
|
||||||
|
switch_thread_rwlock_unlock(listener->event_rwlock);
|
||||||
ei_x_encode_atom(rbuf, "ok");
|
ei_x_encode_atom(rbuf, "ok");
|
||||||
} else {
|
} else {
|
||||||
ei_x_encode_tuple_header(rbuf, 2);
|
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 */
|
/*purge the event queue */
|
||||||
while (switch_queue_trypop(session->event_queue, &pop) == SWITCH_STATUS_SUCCESS);
|
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++) {
|
for (x = 0; x <= SWITCH_EVENT_ALL; x++) {
|
||||||
session->event_list[x] = 0;
|
session->event_list[x] = 0;
|
||||||
}
|
}
|
||||||
/* wipe the hash */
|
/* wipe the hash */
|
||||||
switch_core_hash_destroy(&session->event_hash);
|
switch_core_hash_delete_multi(session->event_hash, NULL, NULL);
|
||||||
switch_core_hash_init(&session->event_hash, session->pool);
|
switch_thread_rwlock_unlock(session->event_rwlock);
|
||||||
|
|
||||||
ei_x_encode_atom(rbuf, "ok");
|
ei_x_encode_atom(rbuf, "ok");
|
||||||
} else {
|
} else {
|
||||||
ei_x_encode_tuple_header(rbuf, 2);
|
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)
|
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_ref ref;
|
||||||
erlang_pid *pid;
|
erlang_pid pid;
|
||||||
char hash[100];
|
char hash[100];
|
||||||
int arity;
|
int arity;
|
||||||
const void *key;
|
const void *key;
|
||||||
void *val;
|
void *val;
|
||||||
session_elem_t *se;
|
session_elem_t *se;
|
||||||
switch_hash_index_t *iter;
|
switch_hash_index_t *iter;
|
||||||
|
int found = 0;
|
||||||
|
|
||||||
ei_decode_tuple_header(buf->buff, &buf->index, &arity);
|
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;
|
return SWITCH_STATUS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(pid = malloc(sizeof(erlang_pid)))) {
|
if (ei_decode_pid(buf->buff, &buf->index, &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)) {
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid pid in a reference/pid tuple\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid pid in a reference/pid tuple\n");
|
||||||
return SWITCH_STATUS_FALSE;
|
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);
|
switch_hash_this(iter, &key, NULL, &val);
|
||||||
se = (session_elem_t*)val;
|
se = (session_elem_t*)val;
|
||||||
if (se->spawn_reply && !strncmp(se->spawn_reply->hash, hash, 100)) {
|
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) {
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "found matching session for %s : %s\n", hash, se->uuid_str);
|
||||||
se->spawn_reply->pid = pid;
|
|
||||||
|
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_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);
|
switch_mutex_unlock(se->spawn_reply->mutex);
|
||||||
return SWITCH_STATUS_SUCCESS;
|
|
||||||
}
|
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);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch_thread_rwlock_unlock(listener->session_rwlock);
|
switch_thread_rwlock_unlock(listener->session_rwlock);
|
||||||
|
|
||||||
|
if (found) {
|
||||||
|
ei_x_encode_atom(rbuf, "ok");
|
||||||
|
} else {
|
||||||
ei_x_encode_tuple_header(rbuf, 2);
|
ei_x_encode_tuple_header(rbuf, 2);
|
||||||
ei_x_encode_atom(rbuf, "error");
|
ei_x_encode_atom(rbuf, "error");
|
||||||
ei_x_encode_atom(rbuf, "notfound");
|
ei_x_encode_atom(rbuf, "notfound");
|
||||||
|
}
|
||||||
switch_safe_free(pid); /* don't need it */
|
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
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;
|
buf->index = 0;
|
||||||
ei_decode_version(buf->buff, &buf->index, &version);
|
ei_decode_version(buf->buff, &buf->index, &version);
|
||||||
ei_get_type(buf->buff, &buf->index, &type, &size);
|
ei_get_type(buf->buff, &buf->index, &type, &size);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ERL_SMALL_TUPLE_EXT:
|
case ERL_SMALL_TUPLE_EXT:
|
||||||
case ERL_LARGE_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
|
#ifdef EI_DEBUG
|
||||||
ei_x_print_msg(rbuf, &msg->from, 1);
|
ei_x_print_msg(rbuf, &msg->from, 1);
|
||||||
#endif
|
#endif
|
||||||
|
return SWITCH_STATUS_SUCCESS != ret;
|
||||||
|
|
||||||
if (SWITCH_STATUS_SUCCESS == ret)
|
|
||||||
return 0;
|
|
||||||
else /* SWITCH_STATUS_TERM */
|
|
||||||
return 1;
|
|
||||||
} else {
|
} else {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Empty reply, supressing\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Empty reply, supressing\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
* Anthony Minessale II <anthm@freeswitch.org>
|
* Anthony Minessale II <anthm@freeswitch.org>
|
||||||
* Andrew Thompson <andrew@hijacked.us>
|
* Andrew Thompson <andrew@hijacked.us>
|
||||||
* Rob Charlton <rob.charlton@savageminds.com>
|
* 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
|
* 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 switch_memory_pool_t *module_pool = NULL;
|
||||||
|
|
||||||
static void remove_listener(listener_t *listener);
|
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);
|
static switch_status_t state_handler(switch_core_session_t *session);
|
||||||
|
|
||||||
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_pref_ip, prefs.ip);
|
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 *SWITCH_THREAD_FUNC listener_run(switch_thread_t *thread, void *obj);
|
||||||
static void launch_listener_thread(listener_t *listener);
|
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)
|
static switch_status_t socket_logger(const switch_log_node_t *node, switch_log_level_t level)
|
||||||
{
|
{
|
||||||
listener_t *l;
|
listener_t *l;
|
||||||
|
|
||||||
switch_thread_rwlock_rdlock(globals.listener_rwlock);
|
switch_thread_rwlock_rdlock(globals.listener_rwlock);
|
||||||
for (l = listen_list.listeners; l; l = l->next) {
|
for (l = listen_list.listeners; l; l = l->next) {
|
||||||
|
|
||||||
if (switch_test_flag(l, LFLAG_LOG) && l->level >= node->level) {
|
if (switch_test_flag(l, LFLAG_LOG) && l->level >= node->level) {
|
||||||
|
|
||||||
switch_log_node_t *dnode = switch_log_node_dup(node);
|
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++;
|
l->lost_logs++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
switch_thread_rwlock_unlock(globals.listener_rwlock);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_thread_rwlock_rdlock(listener->session_rwlock);
|
if ((s = (session_elem_t*)find_session_elem_by_uuid(listener, uuid))) {
|
||||||
s = (session_elem_t*)switch_core_hash_find(listener->sessions, uuid);
|
|
||||||
switch_thread_rwlock_unlock(listener->session_rwlock);
|
|
||||||
|
|
||||||
if (s) {
|
|
||||||
int send = 0;
|
int send = 0;
|
||||||
|
|
||||||
|
switch_thread_rwlock_rdlock(s->event_rwlock);
|
||||||
|
|
||||||
if (s->event_list[SWITCH_EVENT_ALL]) {
|
if (s->event_list[SWITCH_EVENT_ALL]) {
|
||||||
send = 1;
|
send = 1;
|
||||||
} else if ((s->event_list[event->event_id])) {
|
} 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) {
|
if (send) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(s->uuid_str), SWITCH_LOG_DEBUG, "Sending event %s to attached session %s\n",
|
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);
|
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_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_event_name(event->event_id), s->uuid_str);
|
||||||
}
|
}
|
||||||
|
switch_thread_rwlock_unlock(s->rwlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void event_handler(switch_event_t *event)
|
static void event_handler(switch_event_t *event)
|
||||||
|
@ -175,9 +184,10 @@ static void event_handler(switch_event_t *event)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch_thread_rwlock_rdlock(globals.listener_rwlock);
|
||||||
|
|
||||||
lp = listen_list.listeners;
|
lp = listen_list.listeners;
|
||||||
|
|
||||||
switch_thread_rwlock_rdlock(globals.listener_rwlock);
|
|
||||||
while (lp) {
|
while (lp) {
|
||||||
uint8_t send = 0;
|
uint8_t send = 0;
|
||||||
|
|
||||||
|
@ -194,6 +204,8 @@ static void event_handler(switch_event_t *event)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch_thread_rwlock_rdlock(l->event_rwlock);
|
||||||
|
|
||||||
if (l->event_list[SWITCH_EVENT_ALL]) {
|
if (l->event_list[SWITCH_EVENT_ALL]) {
|
||||||
send = 1;
|
send = 1;
|
||||||
} else if ((l->event_list[event->event_id])) {
|
} 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 (send) {
|
||||||
if (switch_event_dup(&clone, event) == SWITCH_STATUS_SUCCESS) {
|
if (switch_event_dup(&clone, event) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
@ -277,7 +290,7 @@ static void remove_listener(listener_t *listener)
|
||||||
switch_thread_rwlock_unlock(globals.listener_rwlock);
|
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)
|
static listener_t *find_listener(char *nodename)
|
||||||
{
|
{
|
||||||
listener_t *l = NULL;
|
listener_t *l = NULL;
|
||||||
|
@ -285,6 +298,7 @@ static listener_t *find_listener(char *nodename)
|
||||||
switch_thread_rwlock_rdlock(globals.listener_rwlock);
|
switch_thread_rwlock_rdlock(globals.listener_rwlock);
|
||||||
for (l = listen_list.listeners; l; l = l->next) {
|
for (l = listen_list.listeners; l; l = l->next) {
|
||||||
if (!strncmp(nodename, l->peer_nodename, MAXNODELEN)) {
|
if (!strncmp(nodename, l->peer_nodename, MAXNODELEN)) {
|
||||||
|
switch_thread_rwlock_rdlock(l->rwlock);
|
||||||
break;
|
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)
|
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_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)
|
static void destroy_session_elem(session_elem_t *session_element)
|
||||||
{
|
{
|
||||||
switch_core_session_t *session;
|
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))) {
|
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_session_rwunlock(session);
|
||||||
}
|
}
|
||||||
switch_core_destroy_memory_pool(&session_element->pool);
|
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);
|
session_elem_t *session = NULL;
|
||||||
remove_session_elem_from_listener(listener, session_element);
|
|
||||||
switch_thread_rwlock_unlock(listener->session_rwlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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)
|
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);
|
switch_thread_rwlock_rdlock(listener->session_rwlock);
|
||||||
for (iter = switch_hash_first(NULL, listener->sessions); iter; iter = switch_hash_next(iter)) {
|
for (iter = switch_hash_first(NULL, listener->sessions); iter; iter = switch_hash_next(iter)) {
|
||||||
switch_hash_this(iter, &key, NULL, &val);
|
switch_hash_this(iter, &key, NULL, &val);
|
||||||
|
|
||||||
|
if (((session_elem_t*)val)->process.type == ERLANG_PID && !ei_compare_pids(pid, &((session_elem_t*)val)->process.pid)) {
|
||||||
session = (session_elem_t*)val;
|
session = (session_elem_t*)val;
|
||||||
if (session->process.type == ERLANG_PID && !ei_compare_pids(pid, &session->process.pid)) {
|
switch_thread_rwlock_rdlock(session->rwlock);
|
||||||
switch_thread_rwlock_unlock(listener->session_rwlock);
|
break;
|
||||||
return session;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch_thread_rwlock_unlock(listener->session_rwlock);
|
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;
|
switch_xml_t xml = NULL;
|
||||||
ei_x_buff *rep;
|
ei_x_buff *rep;
|
||||||
ei_x_buff buf;
|
ei_x_buff buf;
|
||||||
|
|
||||||
ei_x_new_with_version(&buf);
|
ei_x_new_with_version(&buf);
|
||||||
|
|
||||||
switch_uuid_get(&uuid);
|
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. */
|
/* Create a new fetch object. */
|
||||||
p = malloc(sizeof(*p));
|
p = malloc(sizeof(*p));
|
||||||
switch_thread_cond_create(&p->ready_or_found, module_pool);
|
switch_thread_cond_create(&p->ready_or_found, module_pool);
|
||||||
|
/* TODO module pool */
|
||||||
switch_mutex_init(&p->mutex, SWITCH_MUTEX_UNNESTED, module_pool);
|
switch_mutex_init(&p->mutex, SWITCH_MUTEX_UNNESTED, module_pool);
|
||||||
p->state = reply_not_ready;
|
p->state = reply_not_ready;
|
||||||
p->reply = NULL;
|
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. */
|
/* Tell the threads to be ready, and wait five seconds for a reply. */
|
||||||
switch_mutex_lock(p->mutex);
|
switch_mutex_lock(p->mutex);
|
||||||
//p->state = reply_waiting;
|
//p->state = reply_waiting;
|
||||||
switch_thread_cond_timedwait(p->ready_or_found,
|
switch_thread_cond_timedwait(p->ready_or_found, p->mutex, 5000000);
|
||||||
p->mutex, 5000000);
|
|
||||||
if (!p->reply) {
|
if (!p->reply) {
|
||||||
p->state = reply_timeout;
|
p->state = reply_timeout;
|
||||||
switch_mutex_unlock(p->mutex);
|
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))) {
|
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_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;
|
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_caller_profile_event_set_data(switch_channel_get_caller_profile(channel), "Channel", call_event);
|
||||||
switch_channel_event_set_data(channel, call_event);
|
switch_channel_event_set_data(channel, call_event);
|
||||||
switch_core_session_rwunlock(session);
|
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, "Content-Type", "command/reply");
|
||||||
switch_event_add_header_string(call_event, SWITCH_STACK_BOTTOM, "Reply-Text", "+OK\n");
|
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 */
|
/* event used to track sessions to remove */
|
||||||
switch_event_t *event = NULL;
|
switch_event_t *event = NULL;
|
||||||
switch_event_header_t *header = NULL;
|
switch_event_header_t *header = NULL;
|
||||||
|
|
||||||
switch_event_create_subclass(&event, SWITCH_EVENT_CLONE, NULL);
|
switch_event_create_subclass(&event, SWITCH_EVENT_CLONE, NULL);
|
||||||
switch_assert(event);
|
switch_assert(event);
|
||||||
/* check up on all the attached sessions -
|
/* 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 they have pending events in their queues then send them
|
||||||
if the session has finished then clean it up
|
if the session has finished then clean it up
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* TODO try to minimize critical section */
|
||||||
switch_thread_rwlock_rdlock(listener->session_rwlock);
|
switch_thread_rwlock_rdlock(listener->session_rwlock);
|
||||||
for (iter = switch_hash_first(NULL, listener->sessions); iter; iter = switch_hash_next(iter)) {
|
for (iter = switch_hash_first(NULL, listener->sessions); iter; iter = switch_hash_next(iter)) {
|
||||||
switch_hash_this(iter, &key, NULL, &value);
|
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);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "delete", (const char *) key);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
switch_set_flag(sp, LFLAG_OUTBOUND_INIT);
|
switch_set_flag_locked(sp, LFLAG_OUTBOUND_INIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (switch_test_flag(sp, LFLAG_SESSION_COMPLETE)) {
|
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);
|
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 */
|
/* do the deferred remove */
|
||||||
for (header = event->headers; header; header = header->next) {
|
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);
|
remove_session_elem_from_listener(listener, sp);
|
||||||
|
switch_thread_rwlock_unlock(sp->rwlock);
|
||||||
destroy_session_elem(sp);
|
destroy_session_elem(sp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_thread_rwlock_unlock(listener->session_rwlock);
|
|
||||||
|
|
||||||
/* remove the temporary event */
|
/* remove the temporary event */
|
||||||
switch_event_destroy(&event);
|
switch_event_destroy(&event);
|
||||||
|
|
||||||
|
@ -749,29 +782,32 @@ static void handle_exit(listener_t *listener, erlang_pid * pid)
|
||||||
session_elem_t *s;
|
session_elem_t *s;
|
||||||
|
|
||||||
remove_binding(NULL, pid); /* TODO - why don't we pass the listener as the first argument? */
|
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 = find_session_elem_by_pid(listener, pid))) {
|
||||||
if (s->channel_state < CS_HANGUP) {
|
switch_core_session_t *session = NULL;
|
||||||
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))) {
|
if ((session = switch_core_session_locate(s->uuid_str))) {
|
||||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
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);
|
if (switch_channel_get_state(channel) < CS_HANGUP) {
|
||||||
switch_core_event_hook_remove_state_change(session, state_handler);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Outbound session exited unexpectedly %s!\n", s->uuid_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
||||||
switch_core_session_rwunlock(session);
|
switch_core_session_rwunlock(session);
|
||||||
}
|
}
|
||||||
/* TODO - if a spawned process that was handling an outbound call fails.. what do we do with the call? */
|
|
||||||
}
|
switch_thread_rwlock_unlock(s->rwlock);
|
||||||
remove_session_elem_from_listener_locked(listener, s);
|
|
||||||
destroy_session_elem(s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (listener->log_process.type == ERLANG_PID && !ei_compare_pids(&listener->log_process.pid, pid)) {
|
if (listener->log_process.type == ERLANG_PID && !ei_compare_pids(&listener->log_process.pid, pid)) {
|
||||||
void *pop;
|
void *pop;
|
||||||
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Log handler process for node %s exited\n", pid->node);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Log handler process for node %s exited\n", pid->node);
|
||||||
/*purge the log queue */
|
/*purge the log queue */
|
||||||
|
/* TODO don't we want to clear flag first? */
|
||||||
while (switch_queue_trypop(listener->log_queue, &pop) == SWITCH_STATUS_SUCCESS) {
|
while (switch_queue_trypop(listener->log_queue, &pop) == SWITCH_STATUS_SUCCESS) {
|
||||||
switch_log_node_t *dnode = (switch_log_node_t *) pop;
|
switch_log_node_t *dnode = (switch_log_node_t *) pop;
|
||||||
switch_log_node_free(&dnode);
|
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);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Event handler process for node %s exited\n", pid->node);
|
||||||
/*purge the event queue */
|
/*purge the event queue */
|
||||||
|
/* TODO don't we want to clear flag first? */
|
||||||
while (switch_queue_trypop(listener->event_queue, &pop) == SWITCH_STATUS_SUCCESS) {
|
while (switch_queue_trypop(listener->event_queue, &pop) == SWITCH_STATUS_SUCCESS) {
|
||||||
switch_event_t *pevent = (switch_event_t *) pop;
|
switch_event_t *pevent = (switch_event_t *) pop;
|
||||||
switch_event_destroy(&pevent);
|
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)) {
|
if (switch_test_flag(listener, LFLAG_EVENTS)) {
|
||||||
uint8_t x = 0;
|
uint8_t x = 0;
|
||||||
switch_clear_flag_locked(listener, LFLAG_EVENTS);
|
switch_clear_flag_locked(listener, LFLAG_EVENTS);
|
||||||
|
|
||||||
|
switch_thread_rwlock_wrlock(listener->event_rwlock);
|
||||||
for (x = 0; x <= SWITCH_EVENT_ALL; x++) {
|
for (x = 0; x <= SWITCH_EVENT_ALL; x++) {
|
||||||
listener->event_list[x] = 0;
|
listener->event_list[x] = 0;
|
||||||
}
|
}
|
||||||
/* wipe the hash */
|
switch_core_hash_delete_multi(listener->event_hash, NULL, NULL);
|
||||||
switch_core_hash_destroy(&listener->event_hash);
|
switch_thread_rwlock_unlock(listener->event_rwlock);
|
||||||
switch_core_hash_init(&listener->event_hash, listener->pool);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -865,6 +903,7 @@ static void listener_main_loop(listener_t *listener)
|
||||||
case ERL_EXIT:
|
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,
|
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);
|
msg.from.serial);
|
||||||
|
|
||||||
handle_exit(listener, &msg.from);
|
handle_exit(listener, &msg.from);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -874,7 +913,7 @@ static void listener_main_loop(listener_t *listener)
|
||||||
break;
|
break;
|
||||||
case ERL_ERROR:
|
case ERL_ERROR:
|
||||||
if (erl_errno != ETIMEDOUT && erl_errno != EAGAIN) {
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -892,6 +931,11 @@ static void listener_main_loop(listener_t *listener)
|
||||||
return;
|
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)
|
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)
|
static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t *thread, void *obj)
|
||||||
{
|
{
|
||||||
listener_t *listener = (listener_t *) 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);
|
switch_mutex_lock(globals.listener_count_mutex);
|
||||||
prefs.threads++;
|
prefs.threads++;
|
||||||
|
@ -963,38 +1003,10 @@ static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t *thread, void *obj)
|
||||||
listener_main_loop(listener);
|
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_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_listener(listener);
|
||||||
remove_binding(listener, NULL);
|
destroy_listener(listener);
|
||||||
|
|
||||||
/* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch_mutex_lock(globals.listener_count_mutex);
|
switch_mutex_lock(globals.listener_count_mutex);
|
||||||
prefs.threads--;
|
prefs.threads--;
|
||||||
|
@ -1156,43 +1168,46 @@ static int config(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static listener_t *new_listener(struct ei_cnode_s *ec, int clientfd)
|
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;
|
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");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "OH OH no pool\n");
|
||||||
return NULL;
|
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_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error\n");
|
||||||
|
switch_core_destroy_memory_pool(&pool);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
memset(listener, 0, sizeof(*listener));
|
memset(listener, 0, sizeof(*listener));
|
||||||
|
|
||||||
switch_thread_rwlock_create(&listener->rwlock, listener_pool);
|
switch_queue_create(&listener->event_queue, SWITCH_CORE_QUEUE_LEN, pool);
|
||||||
switch_queue_create(&listener->event_queue, SWITCH_CORE_QUEUE_LEN, listener_pool);
|
switch_queue_create(&listener->log_queue, SWITCH_CORE_QUEUE_LEN, pool);
|
||||||
switch_queue_create(&listener->log_queue, SWITCH_CORE_QUEUE_LEN, listener_pool);
|
|
||||||
|
|
||||||
listener->sockfd = clientfd;
|
listener->sockfd = clientfd;
|
||||||
listener->pool = listener_pool;
|
listener->pool = pool;
|
||||||
listener_pool = NULL;
|
|
||||||
listener->ec = switch_core_alloc(listener->pool, sizeof(ei_cnode));
|
listener->ec = switch_core_alloc(listener->pool, sizeof(ei_cnode));
|
||||||
memcpy(listener->ec, ec, sizeof(ei_cnode));
|
memcpy(listener->ec, ec, sizeof(ei_cnode));
|
||||||
listener->level = SWITCH_LOG_DEBUG;
|
listener->level = SWITCH_LOG_DEBUG;
|
||||||
switch_mutex_init(&listener->flag_mutex, SWITCH_MUTEX_NESTED, listener->pool);
|
switch_mutex_init(&listener->flag_mutex, SWITCH_MUTEX_NESTED, listener->pool);
|
||||||
switch_mutex_init(&listener->sock_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_thread_rwlock_create(&listener->session_rwlock, listener->pool);
|
||||||
|
|
||||||
switch_core_hash_init(&listener->event_hash, listener->pool);
|
switch_core_hash_init(&listener->event_hash, listener->pool);
|
||||||
switch_core_hash_init(&listener->sessions, listener->pool);
|
switch_core_hash_init(&listener->sessions, listener->pool);
|
||||||
|
|
||||||
return listener;
|
return listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
static listener_t *new_outbound_listener(char *node)
|
|
||||||
|
static listener_t *new_outbound_listener_locked(char *node)
|
||||||
{
|
{
|
||||||
listener_t *listener = NULL;
|
listener_t *listener = NULL;
|
||||||
struct ei_cnode_s ec;
|
struct ei_cnode_s ec;
|
||||||
|
@ -1206,27 +1221,67 @@ static listener_t *new_outbound_listener(char *node)
|
||||||
#endif
|
#endif
|
||||||
if ((clientfd = ei_connect(&ec, node)) < 0) {
|
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);
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
listener = new_listener(&ec, clientfd);
|
listener = new_listener(&ec, clientfd);
|
||||||
listener->peer_nodename = switch_core_strdup(listener->pool, node);
|
listener->peer_nodename = switch_core_strdup(listener->pool, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch_thread_rwlock_rdlock(listener->rwlock);
|
||||||
|
|
||||||
return listener;
|
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)
|
static switch_status_t state_handler(switch_core_session_t *session)
|
||||||
{
|
{
|
||||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||||
switch_channel_state_t state = switch_channel_get_state(channel);
|
switch_channel_state_t state = switch_channel_get_state(channel);
|
||||||
session_elem_t *session_element = switch_channel_get_private(channel, "_erlang_session_");
|
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) {
|
if (session_element) {
|
||||||
session_element->channel_state = state;
|
session_element->channel_state = state;
|
||||||
if (state == CS_DESTROY) {
|
if (state == CS_DESTROY) {
|
||||||
/* indicate that once all the events in the event queue are done
|
/* indicate that once all the events in the event queue are done
|
||||||
* we can throw this away */
|
* we can throw this away */
|
||||||
switch_set_flag(session_element, LFLAG_SESSION_COMPLETE);
|
switch_set_flag_locked(session_element, LFLAG_SESSION_COMPLETE);
|
||||||
}
|
}
|
||||||
} else {
|
} 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),
|
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;
|
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 */
|
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_session_", session_element);
|
||||||
switch_channel_set_private(channel, "_erlang_listener_", listener);
|
|
||||||
|
|
||||||
switch_core_event_hook_add_state_change(session, state_handler);
|
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));
|
memcpy(&session_element->process.pid, pid, sizeof(erlang_pid));
|
||||||
/* attach the session to the listener */
|
/* attach the session to the listener */
|
||||||
add_session_elem_to_listener(listener, session_element);
|
add_session_elem_to_listener(listener, session_element);
|
||||||
|
/* TODO link before added to listener? */
|
||||||
ei_link(listener, ei_self(listener->ec), pid);
|
ei_link(listener, ei_self(listener->ec), pid);
|
||||||
|
|
||||||
return session_element;
|
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 */
|
/* create a session list element */
|
||||||
session_elem_t *session_element = session_elem_create(listener, session);
|
session_elem_t *session_element = session_elem_create(listener, session);
|
||||||
char hash[100];
|
char hash[100];
|
||||||
//void *p = NULL;
|
|
||||||
spawn_reply_t *p;
|
spawn_reply_t *p;
|
||||||
erlang_ref ref;
|
erlang_ref ref;
|
||||||
|
|
||||||
|
|
||||||
|
ei_init_ref(listener->ec, &ref);
|
||||||
|
ei_hash_ref(&ref, hash);
|
||||||
|
|
||||||
|
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->hash = switch_core_strdup(session_element->pool, hash);
|
||||||
|
p->pid = NULL;
|
||||||
|
|
||||||
|
session_element->spawn_reply = p;
|
||||||
|
|
||||||
|
/* insert the waiting marker */
|
||||||
switch_set_flag(session_element, LFLAG_WAITING_FOR_PID);
|
switch_set_flag(session_element, LFLAG_WAITING_FOR_PID);
|
||||||
|
|
||||||
/* attach the session to the listener */
|
/* attach the session to the listener */
|
||||||
add_session_elem_to_listener(listener, session_element);
|
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->pid = NULL;
|
|
||||||
|
|
||||||
session_element->spawn_reply = p;
|
|
||||||
|
|
||||||
switch_mutex_lock(p->mutex);
|
|
||||||
p->state = reply_waiting;
|
|
||||||
|
|
||||||
if (!strcmp(function, "!")) {
|
if (!strcmp(function, "!")) {
|
||||||
/* send a message to request a pid */
|
/* 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,
|
switch_thread_cond_timedwait(p->ready_or_found, p->mutex, 5000000);
|
||||||
p->mutex, 5000000);
|
|
||||||
if (!p->pid) {
|
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);
|
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);
|
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
||||||
destroy_session_elem(session_element);
|
|
||||||
return NULL;
|
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));
|
memcpy(&session_element->process.pid, p->pid, sizeof(erlang_pid));
|
||||||
session_element->spawn_reply = NULL;
|
session_element->spawn_reply = NULL;
|
||||||
|
|
||||||
switch_clear_flag(session_element, LFLAG_OUTBOUND_INIT);
|
switch_clear_flag_locked(session_element, LFLAG_WAITING_FOR_PID);
|
||||||
switch_clear_flag(session_element, LFLAG_WAITING_FOR_PID);
|
|
||||||
|
|
||||||
ei_link(listener, ei_self(listener->ec), &session_element->process.pid);
|
ei_link(listener, ei_self(listener->ec), &session_element->process.pid);
|
||||||
|
|
||||||
switch_safe_free(p->pid);
|
|
||||||
|
|
||||||
return session_element;
|
return session_element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1414,7 +1465,6 @@ SWITCH_STANDARD_APP(erlang_outbound_function)
|
||||||
char *argv[80] = { 0 }, *argv2[80] = { 0 };
|
char *argv[80] = { 0 }, *argv2[80] = { 0 };
|
||||||
char *mydata, *myarg;
|
char *mydata, *myarg;
|
||||||
char uuid[SWITCH_UUID_FORMATTED_LENGTH + 1];
|
char uuid[SWITCH_UUID_FORMATTED_LENGTH + 1];
|
||||||
switch_bool_t new_session = SWITCH_FALSE;
|
|
||||||
session_elem_t *session_element = NULL;
|
session_elem_t *session_element = NULL;
|
||||||
|
|
||||||
/* process app arguments */
|
/* process app arguments */
|
||||||
|
@ -1460,17 +1510,15 @@ SWITCH_STANDARD_APP(erlang_outbound_function)
|
||||||
/* if there is no listener, then create one */
|
/* if there is no listener, then create one */
|
||||||
if (!listener) {
|
if (!listener) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Creating new listener for session\n");
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Creating new listener for session\n");
|
||||||
new_session = SWITCH_TRUE;
|
if ((listener = new_outbound_listener_locked(node))) {
|
||||||
listener = new_outbound_listener(node);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Launching new listener\n");
|
||||||
|
launch_listener_thread(listener);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Using existing listener for session\n");
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Using existing listener for session\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listener) {
|
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) {
|
if (module && function) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Creating new spawned session for listener\n");
|
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);
|
session_element = attach_call_to_registered_process(listener, reg_name, session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch_thread_rwlock_unlock(listener->rwlock);
|
||||||
|
|
||||||
if (session_element) {
|
if (session_element) {
|
||||||
switch_ivr_park(session, NULL);
|
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");
|
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);
|
listener = find_listener(node);
|
||||||
if (!listener) {
|
if (!listener) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Creating new listener for sendmsg %s\n", node);
|
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 {
|
} else {
|
||||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Using existing listener for sendmsg to %s\n", node);
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Using existing listener for sendmsg to %s\n", node);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listener) {
|
if (listener) {
|
||||||
ei_reg_send(listener->ec, listener->sockfd, reg_name, buf.buff, buf.index);
|
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,
|
stream->write_function(stream, "Outbound session for %s in state %s\n", sp->uuid_str,
|
||||||
switch_channel_state_name(sp->channel_state));
|
switch_channel_state_name(sp->channel_state));
|
||||||
}
|
}
|
||||||
|
switch_thread_rwlock_unlock(l->session_rwlock);
|
||||||
|
|
||||||
if (empty) {
|
if (empty) {
|
||||||
stream->write_function(stream, "No active sessions for %s\n", argv[1]);
|
stream->write_function(stream, "No active sessions for %s\n", argv[1]);
|
||||||
}
|
}
|
||||||
switch_thread_rwlock_unlock(l->session_rwlock);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,8 @@ typedef enum {
|
||||||
} session_flag_t;
|
} session_flag_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ERLANG_PID = 0,
|
NONE = 0,
|
||||||
|
ERLANG_PID,
|
||||||
ERLANG_REG_PROCESS
|
ERLANG_REG_PROCESS
|
||||||
} process_type;
|
} process_type;
|
||||||
|
|
||||||
|
@ -70,7 +71,6 @@ struct spawn_reply_struct
|
||||||
{
|
{
|
||||||
switch_thread_cond_t *ready_or_found;
|
switch_thread_cond_t *ready_or_found;
|
||||||
switch_mutex_t *mutex;
|
switch_mutex_t *mutex;
|
||||||
enum reply_state state;
|
|
||||||
erlang_pid *pid;
|
erlang_pid *pid;
|
||||||
char *hash;
|
char *hash;
|
||||||
};
|
};
|
||||||
|
@ -82,6 +82,8 @@ struct session_elem {
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
struct erlang_process process;
|
struct erlang_process process;
|
||||||
switch_queue_t *event_queue;
|
switch_queue_t *event_queue;
|
||||||
|
switch_thread_rwlock_t *rwlock;
|
||||||
|
switch_thread_rwlock_t *event_rwlock;
|
||||||
switch_channel_state_t channel_state;
|
switch_channel_state_t channel_state;
|
||||||
switch_memory_pool_t *pool;
|
switch_memory_pool_t *pool;
|
||||||
uint8_t event_list[SWITCH_EVENT_ALL + 1];
|
uint8_t event_list[SWITCH_EVENT_ALL + 1];
|
||||||
|
@ -128,6 +130,7 @@ struct listener {
|
||||||
uint8_t event_list[SWITCH_EVENT_ALL + 1];
|
uint8_t event_list[SWITCH_EVENT_ALL + 1];
|
||||||
switch_hash_t *event_hash;
|
switch_hash_t *event_hash;
|
||||||
switch_thread_rwlock_t *rwlock;
|
switch_thread_rwlock_t *rwlock;
|
||||||
|
switch_thread_rwlock_t *event_rwlock;
|
||||||
switch_thread_rwlock_t *session_rwlock;
|
switch_thread_rwlock_t *session_rwlock;
|
||||||
//session_elem_t *session_list;
|
//session_elem_t *session_list;
|
||||||
switch_hash_t *sessions;
|
switch_hash_t *sessions;
|
||||||
|
|
|
@ -1185,7 +1185,7 @@ static switch_status_t read_packet(listener_t *listener, switch_event_t **event,
|
||||||
}
|
}
|
||||||
count++;
|
count++;
|
||||||
if (count == 1) {
|
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);
|
switch_event_add_header_string(*event, SWITCH_STACK_BOTTOM, "Command", mbuf);
|
||||||
} else if (cur) {
|
} else if (cur) {
|
||||||
char *var, *val;
|
char *var, *val;
|
||||||
|
|
|
@ -91,8 +91,8 @@ public class EventConsumer {
|
||||||
return new SWIGTYPE_p_uint32_t(freeswitchJNI.EventConsumer_node_index_get(swigCPtr, this), true);
|
return new SWIGTYPE_p_uint32_t(freeswitchJNI.EventConsumer_node_index_get(swigCPtr, this), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public EventConsumer(String event_name, String subclass_name) {
|
public EventConsumer(String event_name, String subclass_name, int len) {
|
||||||
this(freeswitchJNI.new_EventConsumer(event_name, subclass_name), true);
|
this(freeswitchJNI.new_EventConsumer(event_name, subclass_name, len), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int bind(String event_name, String subclass_name) {
|
public int bind(String event_name, String subclass_name) {
|
||||||
|
|
|
@ -81,7 +81,7 @@ class freeswitchJNI {
|
||||||
public final static native long EventConsumer_enodes_get(long jarg1, EventConsumer jarg1_);
|
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 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 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 void delete_EventConsumer(long jarg1);
|
||||||
public final static native int EventConsumer_bind(long jarg1, EventConsumer jarg1_, String jarg2, String jarg3);
|
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);
|
public final static native long EventConsumer_pop(long jarg1, EventConsumer jarg1_, int jarg2, int jarg3);
|
||||||
|
|
|
@ -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 ;
|
jlong jresult = 0 ;
|
||||||
char *arg1 = (char *) NULL ;
|
char *arg1 = (char *) NULL ;
|
||||||
char *arg2 = (char *) "" ;
|
char *arg2 = (char *) "" ;
|
||||||
|
int arg3 = (int) 5000 ;
|
||||||
EventConsumer *result = 0 ;
|
EventConsumer *result = 0 ;
|
||||||
|
|
||||||
(void)jenv;
|
(void)jenv;
|
||||||
|
@ -1605,7 +1606,8 @@ SWIGEXPORT jlong JNICALL Java_org_freeswitch_swig_freeswitchJNI_new_1EventConsum
|
||||||
arg2 = (char *)jenv->GetStringUTFChars(jarg2, 0);
|
arg2 = (char *)jenv->GetStringUTFChars(jarg2, 0);
|
||||||
if (!arg2) return 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;
|
*(EventConsumer **)&jresult = result;
|
||||||
if (arg1) jenv->ReleaseStringUTFChars(jarg1, (const char *)arg1);
|
if (arg1) jenv->ReleaseStringUTFChars(jarg1, (const char *)arg1);
|
||||||
if (arg2) jenv->ReleaseStringUTFChars(jarg2, (const char *)arg2);
|
if (arg2) jenv->ReleaseStringUTFChars(jarg2, (const char *)arg2);
|
||||||
|
|
|
@ -3705,18 +3705,23 @@ static int _wrap_new_EventConsumer(lua_State* L) {
|
||||||
int SWIG_arg = -1;
|
int SWIG_arg = -1;
|
||||||
char *arg1 = (char *) NULL ;
|
char *arg1 = (char *) NULL ;
|
||||||
char *arg2 = (char *) "" ;
|
char *arg2 = (char *) "" ;
|
||||||
|
int arg3 = (int) 5000 ;
|
||||||
EventConsumer *result = 0 ;
|
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)>=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)>=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){
|
if(lua_gettop(L)>=1){
|
||||||
arg1 = (char *)lua_tostring(L, 1);
|
arg1 = (char *)lua_tostring(L, 1);
|
||||||
}
|
}
|
||||||
if(lua_gettop(L)>=2){
|
if(lua_gettop(L)>=2){
|
||||||
arg2 = (char *)lua_tostring(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_arg=0;
|
||||||
SWIG_NewPointerObj(L,result,SWIGTYPE_p_EventConsumer,1); SWIG_arg++;
|
SWIG_NewPointerObj(L,result,SWIGTYPE_p_EventConsumer,1); SWIG_arg++;
|
||||||
return SWIG_arg;
|
return SWIG_arg;
|
||||||
|
|
|
@ -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() {
|
SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_ORIGINATOR_VARIABLE_get() {
|
||||||
char * jresult ;
|
char * jresult ;
|
||||||
char *result = 0 ;
|
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 ;
|
int jresult ;
|
||||||
char *arg1 = (char *) 0 ;
|
char *arg1 = (char *) 0 ;
|
||||||
char *arg2 = (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 *arg6 = (char *) 0 ;
|
||||||
char *arg7 = (char *) 0 ;
|
char *arg7 = (char *) 0 ;
|
||||||
char *arg8 = (char *) 0 ;
|
char *arg8 = (char *) 0 ;
|
||||||
|
char *arg9 = (char *) 0 ;
|
||||||
switch_status_t result;
|
switch_status_t result;
|
||||||
|
|
||||||
arg1 = (char *)jarg1;
|
arg1 = (char *)jarg1;
|
||||||
|
@ -11128,7 +11139,8 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_add_registration(char * jarg1, cha
|
||||||
arg6 = (char *)jarg6;
|
arg6 = (char *)jarg6;
|
||||||
arg7 = (char *)jarg7;
|
arg7 = (char *)jarg7;
|
||||||
arg8 = (char *)jarg8;
|
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;
|
jresult = result;
|
||||||
return jresult;
|
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) {
|
SWIGEXPORT int SWIGSTDCALL CSharp_switch_buffer_create(void * jarg1, void * jarg2, void * jarg3) {
|
||||||
int jresult ;
|
int jresult ;
|
||||||
switch_memory_pool_t *arg1 = (switch_memory_pool_t *) 0 ;
|
switch_memory_pool_t *arg1 = (switch_memory_pool_t *) 0 ;
|
||||||
|
|
|
@ -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() {
|
SWIGEXPORT char * SWIGSTDCALL CSharp_SWITCH_ORIGINATOR_VARIABLE_get() {
|
||||||
char * jresult ;
|
char * jresult ;
|
||||||
char *result = 0 ;
|
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 ;
|
int jresult ;
|
||||||
char *arg1 = (char *) 0 ;
|
char *arg1 = (char *) 0 ;
|
||||||
char *arg2 = (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 *arg6 = (char *) 0 ;
|
||||||
char *arg7 = (char *) 0 ;
|
char *arg7 = (char *) 0 ;
|
||||||
char *arg8 = (char *) 0 ;
|
char *arg8 = (char *) 0 ;
|
||||||
|
char *arg9 = (char *) 0 ;
|
||||||
switch_status_t result;
|
switch_status_t result;
|
||||||
|
|
||||||
arg1 = (char *)jarg1;
|
arg1 = (char *)jarg1;
|
||||||
|
@ -11447,7 +11459,8 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_add_registration(char * jarg1, cha
|
||||||
arg6 = (char *)jarg6;
|
arg6 = (char *)jarg6;
|
||||||
arg7 = (char *)jarg7;
|
arg7 = (char *)jarg7;
|
||||||
arg8 = (char *)jarg8;
|
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;
|
jresult = result;
|
||||||
return jresult;
|
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) {
|
SWIGEXPORT int SWIGSTDCALL CSharp_switch_buffer_create(void * jarg1, void * jarg2, void * jarg3) {
|
||||||
int jresult ;
|
int jresult ;
|
||||||
switch_memory_pool_t *arg1 = (switch_memory_pool_t *) 0 ;
|
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 ;
|
void * jresult ;
|
||||||
char *arg1 = (char *) NULL ;
|
char *arg1 = (char *) NULL ;
|
||||||
char *arg2 = (char *) "" ;
|
char *arg2 = (char *) "" ;
|
||||||
|
int arg3 = (int) 5000 ;
|
||||||
EventConsumer *result = 0 ;
|
EventConsumer *result = 0 ;
|
||||||
|
|
||||||
arg1 = (char *)jarg1;
|
arg1 = (char *)jarg1;
|
||||||
arg2 = (char *)jarg2;
|
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;
|
jresult = (void *)result;
|
||||||
return jresult;
|
return jresult;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2671,8 +2671,8 @@ public class freeswitch {
|
||||||
return ret;
|
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) {
|
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);
|
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;
|
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));
|
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) {
|
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));
|
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();
|
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_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_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_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_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_CODEC_VARIABLE = freeswitchPINVOKE.SWITCH_ORIGINATOR_CODEC_VARIABLE_get();
|
||||||
public static readonly string SWITCH_ORIGINATOR_VIDEO_CODEC_VARIABLE = freeswitchPINVOKE.SWITCH_ORIGINATOR_VIDEO_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")]
|
[DllImport("mod_managed", EntryPoint="CSharp_SWITCH_SIGNAL_BOND_VARIABLE_get")]
|
||||||
public static extern string 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")]
|
[DllImport("mod_managed", EntryPoint="CSharp_SWITCH_ORIGINATOR_VARIABLE_get")]
|
||||||
public static extern string 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);
|
public static extern uint switch_default_ptime(string jarg1, uint jarg2);
|
||||||
|
|
||||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_core_add_registration")]
|
[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")]
|
[DllImport("mod_managed", EntryPoint="CSharp_switch_core_del_registration")]
|
||||||
public static extern int switch_core_del_registration(string jarg1, string jarg2, string jarg3);
|
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")]
|
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_transfer_to_extension")]
|
||||||
public static extern void switch_channel_transfer_to_extension(HandleRef jarg1, HandleRef jarg2);
|
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")]
|
[DllImport("mod_managed", EntryPoint="CSharp_switch_buffer_create")]
|
||||||
public static extern int switch_buffer_create(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3);
|
public static extern int switch_buffer_create(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3);
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
public int bind(string event_name, string subclass_name) {
|
||||||
|
@ -2659,8 +2659,8 @@ public class freeswitch {
|
||||||
return ret;
|
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) {
|
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);
|
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;
|
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));
|
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) {
|
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));
|
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();
|
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_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_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_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_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_CODEC_VARIABLE = freeswitchPINVOKE.SWITCH_ORIGINATOR_CODEC_VARIABLE_get();
|
||||||
public static readonly string SWITCH_ORIGINATOR_VIDEO_CODEC_VARIABLE = freeswitchPINVOKE.SWITCH_ORIGINATOR_VIDEO_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")]
|
[DllImport("mod_managed", EntryPoint="CSharp_SWITCH_SIGNAL_BOND_VARIABLE_get")]
|
||||||
public static extern string 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")]
|
[DllImport("mod_managed", EntryPoint="CSharp_SWITCH_ORIGINATOR_VARIABLE_get")]
|
||||||
public static extern string 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);
|
public static extern uint switch_default_ptime(string jarg1, uint jarg2);
|
||||||
|
|
||||||
[DllImport("mod_managed", EntryPoint="CSharp_switch_core_add_registration")]
|
[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")]
|
[DllImport("mod_managed", EntryPoint="CSharp_switch_core_del_registration")]
|
||||||
public static extern int switch_core_del_registration(string jarg1, string jarg2, string jarg3);
|
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")]
|
[DllImport("mod_managed", EntryPoint="CSharp_switch_channel_transfer_to_extension")]
|
||||||
public static extern void switch_channel_transfer_to_extension(HandleRef jarg1, HandleRef jarg2);
|
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")]
|
[DllImport("mod_managed", EntryPoint="CSharp_switch_buffer_create")]
|
||||||
public static extern int switch_buffer_create(HandleRef jarg1, HandleRef jarg2, HandleRef jarg3);
|
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);
|
public static extern uint EventConsumer_node_index_get(HandleRef jarg1);
|
||||||
|
|
||||||
[DllImport("mod_managed", EntryPoint="CSharp_new_EventConsumer")]
|
[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")]
|
[DllImport("mod_managed", EntryPoint="CSharp_delete_EventConsumer")]
|
||||||
public static extern void delete_EventConsumer(HandleRef jarg1);
|
public static extern void delete_EventConsumer(HandleRef jarg1);
|
||||||
|
|
|
@ -4675,6 +4675,7 @@ XS(_wrap_new_EventConsumer) {
|
||||||
{
|
{
|
||||||
char *arg1 = (char *) NULL ;
|
char *arg1 = (char *) NULL ;
|
||||||
char *arg2 = (char *) "" ;
|
char *arg2 = (char *) "" ;
|
||||||
|
int arg3 = (int) 5000 ;
|
||||||
EventConsumer *result = 0 ;
|
EventConsumer *result = 0 ;
|
||||||
int res1 ;
|
int res1 ;
|
||||||
char *buf1 = 0 ;
|
char *buf1 = 0 ;
|
||||||
|
@ -4682,11 +4683,13 @@ XS(_wrap_new_EventConsumer) {
|
||||||
int res2 ;
|
int res2 ;
|
||||||
char *buf2 = 0 ;
|
char *buf2 = 0 ;
|
||||||
int alloc2 = 0 ;
|
int alloc2 = 0 ;
|
||||||
|
int val3 ;
|
||||||
|
int ecode3 = 0 ;
|
||||||
int argvi = 0;
|
int argvi = 0;
|
||||||
dXSARGS;
|
dXSARGS;
|
||||||
|
|
||||||
if ((items < 0) || (items > 2)) {
|
if ((items < 0) || (items > 3)) {
|
||||||
SWIG_croak("Usage: new_EventConsumer(event_name,subclass_name);");
|
SWIG_croak("Usage: new_EventConsumer(event_name,subclass_name,len);");
|
||||||
}
|
}
|
||||||
if (items > 0) {
|
if (items > 0) {
|
||||||
res1 = SWIG_AsCharPtrAndSize(ST(0), &buf1, NULL, &alloc1);
|
res1 = SWIG_AsCharPtrAndSize(ST(0), &buf1, NULL, &alloc1);
|
||||||
|
@ -4702,14 +4705,23 @@ XS(_wrap_new_EventConsumer) {
|
||||||
}
|
}
|
||||||
arg2 = reinterpret_cast< char * >(buf2);
|
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++ ;
|
ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EventConsumer, SWIG_OWNER | SWIG_SHADOW); argvi++ ;
|
||||||
if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
|
if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
|
||||||
if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
|
if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
|
||||||
|
|
||||||
XSRETURN(argvi);
|
XSRETURN(argvi);
|
||||||
fail:
|
fail:
|
||||||
if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
|
if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
|
||||||
if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
|
if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
|
||||||
|
|
||||||
SWIG_croak_null();
|
SWIG_croak_null();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5406,6 +5406,7 @@ SWIGINTERN PyObject *_wrap_new_EventConsumer(PyObject *SWIGUNUSEDPARM(self), PyO
|
||||||
PyObject *resultobj = 0;
|
PyObject *resultobj = 0;
|
||||||
char *arg1 = (char *) NULL ;
|
char *arg1 = (char *) NULL ;
|
||||||
char *arg2 = (char *) "" ;
|
char *arg2 = (char *) "" ;
|
||||||
|
int arg3 = (int) 5000 ;
|
||||||
EventConsumer *result = 0 ;
|
EventConsumer *result = 0 ;
|
||||||
int res1 ;
|
int res1 ;
|
||||||
char *buf1 = 0 ;
|
char *buf1 = 0 ;
|
||||||
|
@ -5413,10 +5414,13 @@ SWIGINTERN PyObject *_wrap_new_EventConsumer(PyObject *SWIGUNUSEDPARM(self), PyO
|
||||||
int res2 ;
|
int res2 ;
|
||||||
char *buf2 = 0 ;
|
char *buf2 = 0 ;
|
||||||
int alloc2 = 0 ;
|
int alloc2 = 0 ;
|
||||||
|
int val3 ;
|
||||||
|
int ecode3 = 0 ;
|
||||||
PyObject * obj0 = 0 ;
|
PyObject * obj0 = 0 ;
|
||||||
PyObject * obj1 = 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) {
|
if (obj0) {
|
||||||
res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
|
res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
|
||||||
if (!SWIG_IsOK(res1)) {
|
if (!SWIG_IsOK(res1)) {
|
||||||
|
@ -5431,7 +5435,14 @@ SWIGINTERN PyObject *_wrap_new_EventConsumer(PyObject *SWIGUNUSEDPARM(self), PyO
|
||||||
}
|
}
|
||||||
arg2 = reinterpret_cast< char * >(buf2);
|
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 );
|
resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_EventConsumer, SWIG_POINTER_NEW | 0 );
|
||||||
if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
|
if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
|
||||||
if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
|
if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
|
||||||
|
|
|
@ -22,9 +22,11 @@
|
||||||
* the Initial Developer. All Rights Reserved.
|
* the Initial Developer. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Contributor(s):
|
* 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)
|
* 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)
|
* 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_RUNTIME_FUNCTION(mod_posix_timer_runtime);
|
||||||
SWITCH_MODULE_DEFINITION(mod_posix_timer, mod_posix_timer_load, mod_posix_timer_shutdown, 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 MAX_INTERVAL 2000 /* ms */
|
||||||
#define TIMERS_PER_INTERVAL 4
|
#define TIMERS_PER_INTERVAL 4
|
||||||
#define MAX_ACTIVE_TIMERS 256 /* one byte */
|
#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) {
|
if (val >= 0 && val <= MAX_ACTIVE_TIMERS) {
|
||||||
uint8_t active_id = (uint8_t)val;
|
uint8_t active_id = (uint8_t)val;
|
||||||
/* notify runtime thread that timer identified by active_id has ticked */
|
/* 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 */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,7 +115,7 @@ static void *module_thread(void *dummy)
|
||||||
/**
|
/**
|
||||||
* Load mod_posix_timer and start the runtime thread
|
* Load mod_posix_timer and start the runtime thread
|
||||||
*/
|
*/
|
||||||
static void load_module()
|
static int load_module()
|
||||||
{
|
{
|
||||||
fail_count = 0;
|
fail_count = 0;
|
||||||
warn_count = 0;
|
warn_count = 0;
|
||||||
|
@ -124,9 +124,11 @@ static void load_module()
|
||||||
session_count = 0;
|
session_count = 0;
|
||||||
last_reported_session_count = 0;
|
last_reported_session_count = 0;
|
||||||
shutdown = 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;
|
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;
|
struct timespec ts;
|
||||||
clock_gettime(CLOCK_REALTIME, &ts);
|
clock_gettime(CLOCK_REALTIME, &ts);
|
||||||
srand48(ts.tv_nsec);
|
srand48(ts.tv_nsec);
|
||||||
load_module();
|
if (load_module() == -1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
//test_timer(20, 5.0f, .2f, 1000);
|
//test_timer(20, 5.0f, .2f, 1000);
|
||||||
//test_timer_session(intervals, interval_weights, 4, 2 * 86400.0f, 90, 2000, 30.0, 5.0f);
|
//test_timer_session(intervals, interval_weights, 4, 2 * 86400.0f, 90, 2000, 30.0, 5.0f);
|
||||||
while(1) {
|
while(1) {
|
||||||
/* stop periodically to trigger timer shutdown */
|
/* 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(1000, 5.0f, 1);
|
||||||
//test_timer(20, 5.0f, .2f, 1000);
|
//test_timer(20, 5.0f, .2f, 1000);
|
||||||
|
|
|
@ -102,7 +102,6 @@ static void handle_SIGCHLD(int sig)
|
||||||
pid = wait(&status);
|
pid = wait(&status);
|
||||||
|
|
||||||
if (pid > 0) {
|
if (pid > 0) {
|
||||||
printf("ASS %d\n", pid);
|
|
||||||
system_ready = -1;
|
system_ready = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
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);
|
return apr_thread_join((apr_status_t *) retval, (apr_thread_t *) thd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1928,6 +1928,8 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_running_state(
|
||||||
if (state == CS_ROUTING) {
|
if (state == CS_ROUTING) {
|
||||||
switch_channel_event_set_data(channel, event);
|
switch_channel_event_set_data(channel, event);
|
||||||
} else {
|
} 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-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_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);
|
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 {
|
} else {
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Answer-State", "ringing");
|
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);
|
switch_event_fire(&event);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1577,16 +1577,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc
|
||||||
static void handle_SIGCHLD(int sig)
|
static void handle_SIGCHLD(int sig)
|
||||||
{
|
{
|
||||||
int status = 0;
|
int status = 0;
|
||||||
int pid = 0;
|
|
||||||
|
|
||||||
if (sig) {};
|
|
||||||
|
|
||||||
pid = wait(&status);
|
|
||||||
|
|
||||||
if (pid > 0) {
|
|
||||||
printf("ASS %d\n", pid);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
wait(&status);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
* Anthony Minessale II <anthm@freeswitch.org>
|
* Anthony Minessale II <anthm@freeswitch.org>
|
||||||
* Michael Jerris <mike@jerris.com>
|
* Michael Jerris <mike@jerris.com>
|
||||||
* Paul D. Tinsley <pdt at jackhammer.org>
|
* 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)
|
* Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
* Anthony Minessale II <anthm@freeswitch.org>
|
* Anthony Minessale II <anthm@freeswitch.org>
|
||||||
* Michael Jerris <mike@jerris.com>
|
* Michael Jerris <mike@jerris.com>
|
||||||
* Paul D. Tinsley <pdt at jackhammer.org>
|
* 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)
|
* switch_core_codec.c -- Main Core Library (codec functions)
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
* Anthony Minessale II <anthm@freeswitch.org>
|
* Anthony Minessale II <anthm@freeswitch.org>
|
||||||
* Michael Jerris <mike@jerris.com>
|
* Michael Jerris <mike@jerris.com>
|
||||||
* Paul D. Tinsley <pdt at jackhammer.org>
|
* 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)
|
* switch_core_speech.c -- Main Core Library (speech functions)
|
||||||
|
|
|
@ -1193,7 +1193,7 @@ static char *parse_presence_data_cols(switch_event_t *event)
|
||||||
for (i = 0; i < col_count; i++) {
|
for (i = 0; i < col_count; i++) {
|
||||||
const char *val = NULL;
|
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);
|
val = switch_event_get_header_nil(event, col_name);
|
||||||
if (zstr(val)) {
|
if (zstr(val)) {
|
||||||
stream.write_function(&stream, "%q=NULL,", cols[i]);
|
stream.write_function(&stream, "%q=NULL,", cols[i]);
|
||||||
|
@ -1403,10 +1403,23 @@ static void core_event_handler(switch_event_t *event)
|
||||||
|
|
||||||
switch (state_i) {
|
switch (state_i) {
|
||||||
case CS_NEW:
|
case CS_NEW:
|
||||||
case CS_HANGUP:
|
|
||||||
case CS_DESTROY:
|
case CS_DESTROY:
|
||||||
case CS_REPORTING:
|
case CS_REPORTING:
|
||||||
break;
|
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:
|
case CS_ROUTING:
|
||||||
if ((extra_cols = parse_presence_data_cols(event))) {
|
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',"
|
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_ip VARCHAR(256),\n"
|
||||||
" network_port VARCHAR(256),\n"
|
" network_port VARCHAR(256),\n"
|
||||||
" network_proto VARCHAR(256),\n"
|
" network_proto VARCHAR(256),\n"
|
||||||
" hostname VARCHAR(256)\n"
|
" hostname VARCHAR(256),\n"
|
||||||
|
" metadata VARCHAR(256)\n"
|
||||||
");\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,
|
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;
|
char *sql;
|
||||||
|
|
||||||
|
@ -1861,6 +1876,21 @@ SWITCH_DECLARE(switch_status_t) switch_core_add_registration(const char *user, c
|
||||||
|
|
||||||
switch_queue_push(sql_manager.sql_queue[0], sql);
|
switch_queue_push(sql_manager.sql_queue[0], sql);
|
||||||
|
|
||||||
|
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) "
|
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')",
|
"values ('%q','%q','%q','%q',%ld,'%q','%q','%q','%q')",
|
||||||
switch_str_nil(user),
|
switch_str_nil(user),
|
||||||
|
@ -1873,6 +1903,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_add_registration(const char *user, c
|
||||||
switch_str_nil(network_proto),
|
switch_str_nil(network_proto),
|
||||||
switch_core_get_switchname()
|
switch_core_get_switchname()
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
switch_queue_push(sql_manager.sql_queue[0], sql);
|
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'",
|
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);
|
"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) {
|
switch (dbh->type) {
|
||||||
case SCDB_TYPE_ODBC:
|
case SCDB_TYPE_ODBC:
|
||||||
|
|
|
@ -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_core_new_memory_pool(&pool);
|
||||||
switch_queue_create(&events, 5000, pool);
|
switch_queue_create(&events, len, pool);
|
||||||
node_index = 0;
|
node_index = 0;
|
||||||
|
|
||||||
if (!zstr(event_name)) {
|
if (!zstr(event_name)) {
|
||||||
|
|
|
@ -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.... */
|
/* should go back and proto all the say mods to const.... */
|
||||||
switch_say_args_t say_args = {0};
|
switch_say_args_t say_args = {0};
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
* Michael Jerris <mike@jerris.com>
|
* Michael Jerris <mike@jerris.com>
|
||||||
* Bret McDanel <bret AT 0xdecafbad dot com>
|
* Bret McDanel <bret AT 0xdecafbad dot com>
|
||||||
* Luke Dashjr <luke@openmethods.com> (OpenMethods, LLC)
|
* 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)
|
* switch_ivr_async.c -- IVR Library (async operations)
|
||||||
*
|
*
|
||||||
|
|
|
@ -385,7 +385,9 @@ static void inherit_codec(switch_channel_t *caller_channel, switch_core_session_
|
||||||
const char *var = switch_channel_get_variable(caller_channel, "inherit_codec");
|
const char *var = switch_channel_get_variable(caller_channel, "inherit_codec");
|
||||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
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 impl = { 0 };
|
||||||
switch_codec_implementation_t video_impl = { 0 };
|
switch_codec_implementation_t video_impl = { 0 };
|
||||||
char tmp[128] = "";
|
char tmp[128] = "";
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue