Merge branch 'nsg-4.3'

This commit is contained in:
David Yat Sin 2012-09-11 15:01:26 -04:00
commit c425955670
260 changed files with 40957 additions and 8701 deletions

15
.gitattributes vendored Normal file
View File

@ -0,0 +1,15 @@
# gitattributes
*.exe -diff binary executable windows dfsg-nonfree debian-ignore
*.wav -diff binary sound
*.gif -diff binary image
*.jpg -diff binary image
*.jpeg -diff binary image
*.pbm -diff binary image
/clients/flex* dfsg-nonfree
/debian* debian-ignore
/freeswitch.xcodeproj debian-ignore
/libs/ilbc* dfsg-nonfree
/libs/libg722_1* dfsg-nonfree
/libs/win32* windows debian-ignore
/htdocs* dfsg-nonfree debian-ignore
/w32* windows debian-ignore

21
.gitignore vendored
View File

@ -43,6 +43,7 @@ configure.lineno
config.log
config.status
core.*
TAGS
*.2010.log
*.Build.CppClean.log
*.tlog
@ -201,3 +202,23 @@ src/mod/formats/mod_shout/*/*/mod_shout.log
/src/mod/languages/mod_managed/x64/Release_CLR/FREESWITCH.MANAGED.DLL.metagen
/src/mod/languages/mod_managed/x64/Release_CLR/RSAENH.DLL.bi
/src/mod/languages/mod_managed/x64/Release_CLR/TZRES.DLL.bi
libs/apr-util/a.out.dSYM/Contents/Info.plist
libs/apr-util/a.out.dSYM/Contents/Resources/DWARF/a.out
libs/apr/a.out.dSYM/Contents/Info.plist
libs/apr/a.out.dSYM/Contents/Resources/DWARF/a.out
libs/iksemel/a.out.dSYM/Contents/Info.plist
libs/iksemel/a.out.dSYM/Contents/Resources/DWARF/a.out
libs/ilbc/a.out.dSYM/Contents/Info.plist
libs/ilbc/a.out.dSYM/Contents/Resources/DWARF/a.out
libs/libedit/a.out.dSYM/Contents/Info.plist
libs/libedit/a.out.dSYM/Contents/Resources/DWARF/a.out
libs/pcre/a.out.dSYM/Contents/Info.plist
libs/pcre/a.out.dSYM/Contents/Resources/DWARF/a.out
libs/sqlite/lemon.dSYM/Contents/Info.plist
libs/sqlite/lemon.dSYM/Contents/Resources/DWARF/lemon
libs/sqlite/mkkeywordhash.dSYM/Contents/Info.plist
libs/sqlite/mkkeywordhash.dSYM/Contents/Resources/DWARF/mkkeywordhash
libs/sqlite/sqlite3.dSYM/Contents/Info.plist
libs/sqlite/sqlite3.dSYM/Contents/Resources/DWARF/sqlite3
libs/srtp/a.out.dSYM/Contents/Info.plist
libs/srtp/a.out.dSYM/Contents/Resources/DWARF/a.out

View File

@ -320,6 +320,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ldns", "libs\win32\ldns\ldn
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpcre Generate pcre_chartables.c", "libs\win32\pcre\pcre_chartables.c.2010.vcxproj", "{1CED5987-A529-46DC-B30F-870D85FF9C94}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libzrtp", "libs\libzrtp\projects\win\libzrtp.2010.vcxproj", "{C13CC324-0032-4492-9A30-310A6BD64FF5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
All|Win32 = All|Win32
@ -1989,6 +1991,17 @@ Global
{1CED5987-A529-46DC-B30F-870D85FF9C94}.Release|Win32.ActiveCfg = Release|Win32
{1CED5987-A529-46DC-B30F-870D85FF9C94}.Release|Win32.Build.0 = Release|Win32
{1CED5987-A529-46DC-B30F-870D85FF9C94}.Release|x64.ActiveCfg = Release|Win32
{C13CC324-0032-4492-9A30-310A6BD64FF5}.All|Win32.ActiveCfg = Release|x64
{C13CC324-0032-4492-9A30-310A6BD64FF5}.All|x64.ActiveCfg = Release|x64
{C13CC324-0032-4492-9A30-310A6BD64FF5}.All|x64.Build.0 = Release|x64
{C13CC324-0032-4492-9A30-310A6BD64FF5}.Debug|Win32.ActiveCfg = Debug|Win32
{C13CC324-0032-4492-9A30-310A6BD64FF5}.Debug|Win32.Build.0 = Debug|Win32
{C13CC324-0032-4492-9A30-310A6BD64FF5}.Debug|x64.ActiveCfg = Debug|x64
{C13CC324-0032-4492-9A30-310A6BD64FF5}.Debug|x64.Build.0 = Debug|x64
{C13CC324-0032-4492-9A30-310A6BD64FF5}.Release|Win32.ActiveCfg = Release|Win32
{C13CC324-0032-4492-9A30-310A6BD64FF5}.Release|Win32.Build.0 = Release|Win32
{C13CC324-0032-4492-9A30-310A6BD64FF5}.Release|x64.ActiveCfg = Release|x64
{C13CC324-0032-4492-9A30-310A6BD64FF5}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -2089,6 +2102,7 @@ Global
{ABB71A76-42B0-47A4-973A-42E3D920C6FD} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{9778F1C0-09BC-4698-8EBC-BD982247209A} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{56B91D01-9150-4BBF-AFA1-5B68AB991B76} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{C13CC324-0032-4492-9A30-310A6BD64FF5} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{EC3E5C7F-EE09-47E2-80FE-546363D14A98} = {B8F5B47B-8568-46EB-B320-64C17D2A98BC}
{1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F} = {0C808854-54D1-4230-BFF5-77B5FD905000}
{ACFFF684-4D19-4D48-AF12-88EA1D778BDF} = {0C808854-54D1-4230-BFF5-77B5FD905000}

View File

@ -525,6 +525,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gsmlib", "src\mod\endpoints
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_gsmopen", "src\mod\endpoints\mod_gsmopen\mod_gsmopen.2010.vcxproj", "{74B120FF-6935-4DFE-A142-CDB6BEA99C90}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libzrtp", "libs\libzrtp\projects\win\libzrtp.2010.vcxproj", "{C13CC324-0032-4492-9A30-310A6BD64FF5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
All|Win32 = All|Win32
@ -3574,6 +3576,23 @@ Global
{74B120FF-6935-4DFE-A142-CDB6BEA99C90}.Release|x64.ActiveCfg = Release|x64
{74B120FF-6935-4DFE-A142-CDB6BEA99C90}.Release|x64 Setup.ActiveCfg = Release|x64
{74B120FF-6935-4DFE-A142-CDB6BEA99C90}.Release|x86 Setup.ActiveCfg = Release|x64
{C13CC324-0032-4492-9A30-310A6BD64FF5}.All|Win32.ActiveCfg = Release|Win32
{C13CC324-0032-4492-9A30-310A6BD64FF5}.All|Win32.Build.0 = Release|Win32
{C13CC324-0032-4492-9A30-310A6BD64FF5}.All|x64.ActiveCfg = Release|Win32
{C13CC324-0032-4492-9A30-310A6BD64FF5}.All|x64 Setup.ActiveCfg = Release|Win32
{C13CC324-0032-4492-9A30-310A6BD64FF5}.All|x86 Setup.ActiveCfg = Release|Win32
{C13CC324-0032-4492-9A30-310A6BD64FF5}.Debug|Win32.ActiveCfg = Debug|Win32
{C13CC324-0032-4492-9A30-310A6BD64FF5}.Debug|Win32.Build.0 = Debug|Win32
{C13CC324-0032-4492-9A30-310A6BD64FF5}.Debug|x64.ActiveCfg = Debug|x64
{C13CC324-0032-4492-9A30-310A6BD64FF5}.Debug|x64.Build.0 = Debug|x64
{C13CC324-0032-4492-9A30-310A6BD64FF5}.Debug|x64 Setup.ActiveCfg = Debug|Win32
{C13CC324-0032-4492-9A30-310A6BD64FF5}.Debug|x86 Setup.ActiveCfg = Debug|Win32
{C13CC324-0032-4492-9A30-310A6BD64FF5}.Release|Win32.ActiveCfg = Release|Win32
{C13CC324-0032-4492-9A30-310A6BD64FF5}.Release|Win32.Build.0 = Release|Win32
{C13CC324-0032-4492-9A30-310A6BD64FF5}.Release|x64.ActiveCfg = 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|x86 Setup.ActiveCfg = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -3687,6 +3706,7 @@ Global
{70A49BC2-7500-41D0-B75D-EDCC5BE987A0} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{23B4D303-79FC-49E0-89E2-2280E7E28940} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{26C82FCE-E0CF-4D10-A00C-D8E582FFEB53} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{C13CC324-0032-4492-9A30-310A6BD64FF5} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{EC3E5C7F-EE09-47E2-80FE-546363D14A98} = {B8F5B47B-8568-46EB-B320-64C17D2A98BC}
{1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F} = {0C808854-54D1-4230-BFF5-77B5FD905000}
{ACFFF684-4D19-4D48-AF12-88EA1D778BDF} = {0C808854-54D1-4230-BFF5-77B5FD905000}

View File

@ -20,11 +20,18 @@ DEFAULT_SOUNDS=en-us-callie-8000
sounds_version=`grep $$base_sound_dir $(switch_srcdir)/build/sounds_version.txt | cut -d ' ' -f2`;\
soundfile=`echo freeswitch-sounds-$$full_sound_dir-$$moh_version.tar.gz`; \
echo $$full_sound_dir | grep music >/dev/null || soundfile=`echo freeswitch-sounds-$$full_sound_dir-$$sounds_version.tar.gz`; \
if test "$$target" = "install"; then $(MAKE) $(AM_MAKEFLAGS) core_install; else $(MAKE) $(AM_MAKEFLAGS) core ; fi; \
if test "$$target_prefix" = "sounds"; then \
if test "$$target" = "install"; then $(GETSOUNDS) $$soundfile $(DESTDIR)$(soundsdir)/; else $(GETSOUNDS) $$soundfile ; fi; \
if test "$$target" = "install"; then \
$(GETSOUNDS) $$soundfile $(DESTDIR)$(soundsdir)/;\
else \
$(GETSOUNDS) $$soundfile ; \
fi; \
else \
cd src/mod && $(MAKE) $(AM_MAKEFLAGS) $@ ;\
if test "$$target" = "install"; then \
$(MAKE) $(AM_MAKEFLAGS) core_install && cd src/mod && $(MAKE) $(AM_MAKEFLAGS) $@ ; \
else \
$(MAKE) $(AM_MAKEFLAGS) core && cd src/mod && $(MAKE) $(AM_MAKEFLAGS) $@ ;\
fi; \
fi
sounds: sounds-en-us-callie-8000
@ -150,8 +157,8 @@ if ENABLE_ZRTP
CORE_CFLAGS += -I$(switch_srcdir)/libs/libzrtp/third_party/bgaes
CORE_CFLAGS += -I$(switch_srcdir)/libs/libzrtp/third_party/bnlib
CORE_CFLAGS += -isystem $(switch_srcdir)/libs/libzrtp/include
ZRTP_LDFLAGS = -Llibs/libzrtp/third_party/bnlib
ZRTP_LDFLAGS += -Llibs/libzrtp/projects/gnu/build
ZRTP_LDFLAGS = -L$(switch_srcdir)/libs/libzrtp/third_party/bnlib
ZRTP_LDFLAGS += -L$(switch_srcdir)/libs/libzrtp/projects/gnu/build
ZRTP_LIBS = -lbn -lzrtp
libfreeswitch_la_LDFLAGS += $(ZRTP_LDFLAGS)
libfreeswitch_la_LIBADD += $(ZRTP_LIBS)
@ -411,8 +418,8 @@ $(switch_builddir)/quiet_libtool: $(switch_builddir)/libtool
src/include/switch_version.h: src/include/switch_version.h.in .version $(libfreeswitch_la_SOURCES) $(library_include_HEADERS)
@have_version=1 ; \
force=0 ; \
grep "@SWITCH_VERSION_REVISION@" src/include/switch_version.h.in > /dev/null && have_version=0 ; \
test ! -f src/include/switch_version.h || grep "@SWITCH_VERSION_REVISION@" src/include/switch_version.h > /dev/null && force=1 ; \
grep -- "@SWITCH_VERSION_REVISION@" src/include/switch_version.h.in > /dev/null || have_version=0 ; \
test ! -f src/include/switch_version.h || grep -- "@SWITCH_VERSION_REVISION@" src/include/switch_version.h > /dev/null && force=1 ; \
if test $$have_version = 1 ; then \
cat src/include/switch_version.h.in > src/include/switch_version.h ; \
touch .version ; \

View File

@ -343,11 +343,7 @@ bootstrap_apr() {
echo "Entering directory ${LIBDIR}/apr-util"
cd ${LIBDIR}/apr-util
if ! ${BGJOB}; then
./buildconf
else
./buildconf &
fi
./buildconf
}
bootstrap_libzrtp() {
@ -454,9 +450,10 @@ bootstrap_libs() {
if ! ${BGJOB}; then
libbootstrap ${i} ; bootstrap_libs_post ${i}
else
((libbootstrap ${i} ; bootstrap_libs_post ${i}) &)
(libbootstrap ${i} ; bootstrap_libs_post ${i}) &
fi
done
${BGJOB} && wait
}
run() {
@ -471,7 +468,6 @@ run() {
check_libtoolize
print_autotools_vers
bootstrap_libs
${BGJOB} && wait
return 0
}

View File

@ -46,12 +46,7 @@
# Voice Platform
### END INIT INFO
#
# Check for missing binaries (stale symlinks should not happen)
# Note: Special treatment of stop for LSB conformance
FREESWITCH_BIN=/opt/freeswitch/bin/freeswitch
test -x $FREESWITCH_BIN || { echo "$FREESWITCH_BIN not installed";
if [ "$1" = "stop" ]; then exit 0;
else exit 5; fi; }
# Check for existence of needed config file and read it
FREESWITCH_CONFIG=/etc/sysconfig/freeswitch
@ -62,6 +57,12 @@ test -r $FREESWITCH_CONFIG || { echo "$FREESWITCH_CONFIG not existing";
# Read config
. $FREESWITCH_CONFIG
# Check for missing binaries (stale symlinks should not happen)
# Note: Special treatment of stop for LSB conformance
test -x $FREESWITCH_BIN || { echo "$FREESWITCH_BIN not installed";
if [ "$1" = "stop" ]; then exit 0;
else exit 5; fi; }
# Source LSB init functions
# providing start_daemon, killproc, pidofproc,
# log_success_msg, log_failure_msg and log_warning_msg.
@ -202,7 +203,7 @@ case "$1" in
## argument to this init script which is required for a reload.
## Note: probe is not (yet) part of LSB (as of 1.9)
test /opt/freeswitch/conf/freeswitch.xml -nt /opt/freeswitch/run/freeswitch.pid && echo reload
test ${FREESWITCH_HOME}/conf/freeswitch.xml -nt ${FREESWITCH_HOME}/run/freeswitch.pid && echo reload
;;
*)
echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload|probe}"

View File

@ -1,4 +1,5 @@
#!/bin/sh
##### -*- mode:shell-script; indent-tabs-mode:nil; sh-basic-offset:2 -*-
TAR=@TAR@
ZCAT=@ZCAT@
@ -8,39 +9,39 @@ WGET=@WGET@
CURL=@CURL@
if [ -f "$WGET" ]; then
DOWNLOAD_CMD=$WGET
DOWNLOAD_CMD=$WGET
elif [ -f "$CURL" ]; then
DOWNLOAD_CMD="$CURL -O"
DOWNLOAD_CMD="$CURL -O"
fi
if [ -n "`echo $1 | grep '://'`" ]; then
base=$1/
tarfile=$2
base=$1/
tarfile=$2
else
base=http://files.freeswitch.org/downloads/libs/
tarfile=$1
base=http://files.freeswitch.org/downloads/libs/
tarfile=$1
fi
uncompressed=`echo $tarfile | sed 's/\(\(\.tar\.gz\|\.tar\.bz2\|\.tar\.xz\)\|\(\.tgz\|\.tbz2\)\)$//'`
case `echo $tarfile | sed 's/^.*\.//'` in
bz2|tbz2) UNZIPPER=$BZIP ;;
xz) UNZIPPER=$XZ ;;
gz|tgz|*) UNZIPPER=$ZCAT ;;
bz2|tbz2) UNZIPPER=$BZIP ;;
xz) UNZIPPER=$XZ ;;
gz|tgz|*) UNZIPPER=$ZCAT ;;
esac
if [ ! -d $tarfile ]; then
if [ ! -f $tarfile ]; then
rm -fr $uncompressed
$DOWNLOAD_CMD $base$tarfile
if [ ! -f $tarfile ]; then
rm -fr $uncompressed
$DOWNLOAD_CMD $base$tarfile
if [ ! -f $tarfile ]; then
echo cannot find $tarfile
exit 1
fi
fi
if [ ! -d $uncompressed ]; then
$UNZIPPER -c -d $tarfile | $TAR -xf -
echo cannot find $tarfile
exit 1
fi
fi
if [ ! -d $uncompressed ]; then
$UNZIPPER -c -d $tarfile | $TAR -xf -
fi
fi
exit 0

View File

@ -1,132 +1,18 @@
#applications/mod_abstraction
#applications/mod_avmd
#applications/mod_blacklist
#applications/mod_callcenter
#applications/mod_cidlookup
applications/mod_cluechoo
applications/mod_commands
applications/mod_conference
#applications/mod_curl
applications/mod_db
#applications/mod_directory
#applications/mod_distributor
applications/mod_dptools
#applications/mod_easyroute
applications/mod_enum
applications/mod_esf
#applications/mod_esl
applications/mod_expr
applications/mod_fifo
#applications/mod_fsk
applications/mod_fsv
applications/mod_hash
applications/mod_httapi
#applications/mod_http_cache
#applications/mod_ladspa
#applications/mod_lcr
#applications/mod_memcache
#applications/mod_mongo
#applications/mod_nibblebill
#applications/mod_osp
#applications/mod_redis
#applications/mod_rss
applications/mod_sms
#applications/mod_snapshot
#applications/mod_snipe_hunt
#applications/mod_snom
#applications/mod_soundtouch
applications/mod_spandsp
#applications/mod_spy
#applications/mod_stress
applications/mod_valet_parking
#applications/mod_vmd
applications/mod_voicemail
#applications/mod_voicemail_ivr
#asr_tts/mod_cepstral
#asr_tts/mod_flite
#asr_tts/mod_pocketsphinx
#asr_tts/mod_tts_commandline
#asr_tts/mod_unimrcp
codecs/mod_amr
#codecs/mod_amrwb
codecs/mod_bv
#codecs/mod_celt
#codecs/mod_codec2
#codecs/mod_com_g729
#codecs/mod_dahdi_codec
codecs/mod_g723_1
codecs/mod_g729
codecs/mod_h26x
codecs/mod_ilbc
#codecs/mod_isac
#codecs/mod_opus
#codecs/mod_sangoma_codec
#codecs/mod_silk
codecs/mod_siren
codecs/mod_speex
dialplans/mod_dialplan_asterisk
#dialplans/mod_dialplan_directory
dialplans/mod_dialplan_xml
#directories/mod_ldap
#endpoints/mod_alsa
#endpoints/mod_dingaling
#endpoints/mod_h323
#endpoints/mod_khomp
endpoints/mod_loopback
#endpoints/mod_opal
#endpoints/mod_portaudio
#endpoints/mod_rtmp
#endpoints/mod_skinny
#endpoints/mod_skypopen
endpoints/mod_sofia
event_handlers/mod_cdr_csv
#event_handlers/mod_cdr_mongodb
#event_handlers/mod_cdr_pg_csv
event_handlers/mod_cdr_sqlite
#event_handlers/mod_erlang_event
#event_handlers/mod_event_multicast
event_handlers/mod_event_socket
#event_handlers/mod_event_zmq
#event_handlers/mod_radius_cdr
#event_handlers/mod_snmp
formats/mod_local_stream
formats/mod_native_file
#formats/mod_portaudio_stream
#formats/mod_shell_stream
#formats/mod_shout
formats/mod_sndfile
formats/mod_tone_stream
#languages/mod_java
languages/mod_lua
#languages/mod_managed
#languages/mod_perl
#languages/mod_python
languages/mod_spidermonkey
#languages/mod_yaml
loggers/mod_console
loggers/mod_logfile
loggers/mod_syslog
#say/mod_say_de
say/mod_say_en
#say/mod_say_es
#say/mod_say_fr
#say/mod_say_he
#say/mod_say_hu
#say/mod_say_it
#say/mod_say_nl
#say/mod_say_pt
#say/mod_say_ru
#say/mod_say_th
#say/mod_say_zh
#timers/mod_posix_timer
#timers/mod_timerfd
applications/mod_dptools
applications/mod_commands
applications/mod_hash
applications/mod_spandsp
applications/mod_distributor
dialplans/mod_dialplan_xml
endpoints/mod_sofia
endpoints/mod_opal
endpoints/mod_media_gateway
../../libs/freetdm/mod_freetdm
xml_int/mod_xml_cdr
#xml_int/mod_xml_curl
#xml_int/mod_xml_ldap
xml_int/mod_xml_rpc
#../../libs/freetdm/mod_freetdm
#../../libs/openzap/mod_openzap
## Experimental Modules (don't cry if they're broken)
#../../contrib/mod/xml_int/mod_xml_odbc
event_handlers/mod_event_socket
codecs/mod_sangoma_codec
event_handlers/mod_radius_cdr
applications/mod_rad_auth

1
build/next-release.txt Normal file
View File

@ -0,0 +1 @@
1.2-rc3

16
build/set-fs-version.sh Executable file
View File

@ -0,0 +1,16 @@
#!/bin/sh
##### -*- mode:shell-script; indent-tabs-mode:nil; sh-basic-offset:2 -*-
sdir="."
[ -n "${0%/*}" ] && sdir="${0%/*}"
. $sdir/../scripts/ci/common.sh
check_pwd
check_input_ver_build $@
in_ver="$1"
if [ "$in_ver" = "auto" ]; then
in_ver="$(cat build/next-release.txt)"
fi
eval $(parse_version "$in_ver")
set_fs_ver "$gver" "$gmajor" "$gminor" "$gmicro" "$grev"

View File

@ -60,7 +60,7 @@
<load module="mod_g723_1"/>
<load module="mod_g729"/>
<load module="mod_amr"/>
<load module="mod_ilbc"/>
<!--<load module="mod_ilbc"/>-->
<load module="mod_speex"/>
<load module="mod_h26x"/>
<!--<load module="mod_siren"/>-->

View File

@ -1,4 +1,4 @@
<!-- http://wiki.freeswitch.org/wiki/Sofia_Configuration_Files -->
<!-- http://wiki.freeswitch.org/wiki/Sofia_Configuration_Files -->
<profile name="external">
<!-- This profile is only for outbound registrations to providers -->
<gateways>
@ -29,10 +29,10 @@
<!-- This could be set to "passive" -->
<param name="manage-presence" value="passive"/>
<!-- used to share presence info across sofia profiles
manage-presence needs to be set to passive on this profile
if you want it to behave as if it were the internal profile
for presence.
<!-- used to share presence info across sofia profiles
manage-presence needs to be set to passive on this profile
if you want it to behave as if it were the internal profile
for presence.
-->
<!-- Name of the db to use for this profile -->
<param name="dbname" value="$${domain}"/>
@ -47,8 +47,10 @@
<param name="nonce-ttl" value="60"/>
<param name="auth-calls" value="false"/>
<param name="rtp-timeout-sec" value="1800"/>
<param name="inbound-late-negotiation" value="true"/>
<param name="inbound-zrtp-passthru" value="true"/>
<!--
DO NOT USE HOSTNAMES, ONLY IP ADDRESSES IN THESE SETTINGS!
DO NOT USE HOSTNAMES, ONLY IP ADDRESSES IN THESE SETTINGS!
-->
<param name="rtp-ip" value="$${local_ip_v4}"/>
<param name="sip-ip" value="$${local_ip_v4}"/>

View File

@ -9,7 +9,7 @@
<!--/// domain to use in from: *optional* same as realm, if blank ///-->
<!--<param name="from-domain" value="asterlink.com"/>-->
<!--/// account password *required* ///-->
<!--<param name="password" value="2007"/>-->
<!--<param name="password" value="2007"/>-->
<!--/// extension for inbound calls: *optional* same as username, if blank ///-->
<!--<param name="extension" value="cluecon"/>-->
<!--/// proxy host: *optional* same as realm, if blank ///-->

View File

@ -53,36 +53,39 @@
<param name="tls-cert-dir" value="$${internal_ssl_dir}"/>
<!-- TLS version ("sslv23" (default), "tlsv1"). NOTE: Phones may not work with TLSv1 -->
<param name="tls-version" value="$${sip_tls_version}"/>
<!--If you don't want to pass through timestampes from 1 RTP call to another (on a per call basis with rtp_rewrite_timestamps chanvar)-->
<!--<param name="rtp-rewrite-timestamps" value="true"/>-->
<!--<param name="pass-rfc2833" value="true"/>-->
<!--If you have ODBC support and a working dsn you can use it instead of SQLite-->
<!--<param name="odbc-dsn" value="dsn:user:pass"/>-->
<!--Uncomment to set all inbound calls to no media mode-->
<!--<param name="inbound-bypass-media" value="true"/>-->
<!--Uncomment to set all inbound calls to proxy media mode-->
<!--<param name="inbound-proxy-media" value="true"/>-->
<!--Uncomment to let calls hit the dialplan *before* you decide if the codec is ok-->
<!--<param name="inbound-late-negotiation" value="true"/>-->
<!-- Let calls hit the dialplan before selecting codec for the a-leg -->
<param name="inbound-late-negotiation" value="true"/>
<!-- Allow ZRTP clients to negotiate end-to-end security associations -->
<param name="inbound-zrtp-passthru" value="true"/>
<!-- this lets anything register -->
<!-- comment the next line and uncomment one or both of the other 2 lines for call authentication -->
<!-- <param name="accept-blind-reg" value="true"/> -->
<!-- accept any authentication without actually checking (not a good feature for most people) -->
<!-- <param name="accept-blind-auth" value="true"/> -->
<!-- suppress CNG on this profile or per call with the 'suppress_cng' variable -->
<!-- <param name="suppress-cng" value="true"/> -->
<!--TTL for nonce in sip auth-->
<param name="nonce-ttl" value="60"/>
<!--Uncomment if you want to force the outbound leg of a bridge to only offer the codec
that the originator is using-->
<!--Uncomment if you want to force the outbound leg of a bridge to only offer the codec
that the originator is using-->
<!--<param name="disable-transcoding" value="true"/>-->
<!-- Used for when phones respond to a challenged ACK with method INVITE in the hash -->
<!--<param name="NDLB-broken-auth-hash" value="true"/>-->
@ -128,4 +131,3 @@
</settings>
</profile>

View File

@ -1,7 +1,7 @@
<!--
This is a sofia sip profile/user agent. This will service exactly one ip and port.
In FreeSWITCH you can run multiple sip user agents on their own ip and port.
When you hear someone say "sofia profile" this is what they are talking about.
-->
@ -16,24 +16,24 @@
<gateways>
<X-PRE-PROCESS cmd="include" data="internal/*.xml"/>
</gateways>
<domains>
<!-- indicator to parse the directory for domains with parse="true" to get gateways-->
<!--<domain name="$${domain}" parse="true"/>-->
<!-- indicator to parse the directory for domains with parse="true" to get gateways and alias every domain to this profile -->
<!--<domain name="all" alias="true" parse="true"/>-->
<domain name="all" alias="true" parse="false"/>
<domain name="all" alias="true" parse="false"/>
</domains>
<settings>
<!--
When calls are in no media this will bring them back to media
when you press the hold button.
When calls are in no media this will bring them back to media
when you press the hold button.
-->
<!--<param name="media-option" value="resume-media-on-hold"/> -->
<!--
This will allow a call after an attended transfer go back to
bypass media after an attended transfer.
This will allow a call after an attended transfer go back to
bypass media after an attended transfer.
-->
<!--<param name="media-option" value="bypass-media-after-att-xfer"/>-->
<!-- <param name="user-agent-string" value="FreeSWITCH Rocks!"/> -->
@ -63,7 +63,7 @@
<!--<param name="dtmf-type" value="info"/>-->
<param name="record-template" value="$${base_dir}/recordings/${caller_id_number}.${target_domain}.${strftime(%Y-%m-%d-%H-%M-%S)}.wav"/>
<!-- This setting is for AAL2 bitpacking on G726 -->
<!-- <param name="bitpacking" value="aal2"/> -->
<!--max number of open dialogs in proceeding -->
@ -88,36 +88,39 @@
<param name="tls-cert-dir" value="$${internal_ssl_dir}"/>
<!-- TLS version ("sslv23" (default), "tlsv1"). NOTE: Phones may not work with TLSv1 -->
<param name="tls-version" value="$${sip_tls_version}"/>
<!--If you don't want to pass through timestamps from 1 RTP call to another (on a per call basis with rtp_rewrite_timestamps chanvar)-->
<!--<param name="rtp-rewrite-timestamps" value="true"/>-->
<!--<param name="pass-rfc2833" value="true"/>-->
<!--If you have ODBC support and a working dsn you can use it instead of SQLite-->
<!--<param name="odbc-dsn" value="dsn:user:pass"/>-->
<!--Uncomment to set all inbound calls to no media mode-->
<!--<param name="inbound-bypass-media" value="true"/>-->
<!--Uncomment to set all inbound calls to proxy media mode-->
<!--<param name="inbound-proxy-media" value="true"/>-->
<!--Uncomment to let calls hit the dialplan *before* you decide if the codec is ok-->
<!--<param name="inbound-late-negotiation" value="true"/>-->
<!-- Let calls hit the dialplan before selecting codec for the a-leg -->
<param name="inbound-late-negotiation" value="true"/>
<!-- Allow ZRTP clients to negotiate end-to-end security associations -->
<param name="inbound-zrtp-passthru" value="true"/>
<!-- this lets anything register -->
<!-- comment the next line and uncomment one or both of the other 2 lines for call authentication -->
<!-- <param name="accept-blind-reg" value="true"/> -->
<!-- accept any authentication without actually checking (not a good feature for most people) -->
<!-- <param name="accept-blind-auth" value="true"/> -->
<!-- suppress CNG on this profile or per call with the 'suppress_cng' variable -->
<!-- <param name="suppress-cng" value="true"/> -->
<!--TTL for nonce in sip auth-->
<param name="nonce-ttl" value="60"/>
<!--Uncomment if you want to force the outbound leg of a bridge to only offer the codec
that the originator is using-->
<!--Uncomment if you want to force the outbound leg of a bridge to only offer the codec
that the originator is using-->
<!--<param name="disable-transcoding" value="true"/>-->
<!-- Used for when phones respond to a challenged ACK with method INVITE in the hash -->
<!--<param name="NDLB-broken-auth-hash" value="true"/>-->
@ -138,7 +141,7 @@
<!-- <param name="vad" value="out"/> -->
<!-- <param name="vad" value="both"/> -->
<!--<param name="alias" value="sip:10.0.1.251:5555"/>-->
<!--all inbound reg will look in this domain for the users -->
<param name="force-register-domain" value="$${domain}"/>
<!--all inbound reg will stored in the db using this domain -->
@ -158,24 +161,24 @@
<!--<param name="disable-transfer" value="true"/>-->
<!--<param name="disable-register" value="true"/>-->
<!-- enable-3pcc can be set to either 'true' or 'proxy', true accepts the call right away, proxy waits until the call has been answered then sends accepts -->
<!-- enable-3pcc can be set to either 'true' or 'proxy', true accepts the call right away, proxy waits until the call has been answered then sends accepts -->
<!--<param name="enable-3pcc" value="true"/>-->
<!-- use at your own risk or if you know what this does.-->
<!--<param name="NDLB-force-rport" value="true"/>-->
<!--
Choose the realm challenge key. Default is auto_to if not set.
auto_from - uses the from field as the value for the sip realm.
auto_to - uses the to field as the value for the sip realm.
<anyvalue> - you can input any value to use for the sip realm.
Choose the realm challenge key. Default is auto_to if not set.
If you want URL dialing to work you'll want to set this to auto_from.
If you use any other value besides auto_to or auto_from you'll loose
the ability to do multiple domains.
Note: comment out to restore the behavior before 2008-09-29
auto_from - uses the from field as the value for the sip realm.
auto_to - uses the to field as the value for the sip realm.
<anyvalue> - you can input any value to use for the sip realm.
If you want URL dialing to work you'll want to set this to auto_from.
If you use any other value besides auto_to or auto_from you'll loose
the ability to do multiple domains.
Note: comment out to restore the behavior before 2008-09-29
-->
<param name="challenge-realm" value="auto_from"/>
@ -186,4 +189,3 @@
<!--<param name="outbound-use-uuid-as-callid" value="true"/>-->
</settings>
</profile>

View File

@ -9,7 +9,7 @@
<!--/// domain to use in from: *optional* same as realm, if blank ///-->
<!--<param name="from-domain" value="asterlink.com"/>-->
<!--/// account password *required* ///-->
<!--<param name="password" value="2007"/>-->
<!--<param name="password" value="2007"/>-->
<!--/// extension for inbound calls: *optional* same as username, if blank ///-->
<!--<param name="extension" value="cluecon"/>-->
<!--/// proxy host: *optional* same as realm, if blank ///-->

View File

@ -39,7 +39,7 @@
<load module="mod_g723_1"/>
<load module="mod_g729"/>
<load module="mod_amr"/>
<load module="mod_ilbc"/>
<!--<load module="mod_ilbc"/>-->
<load module="mod_speex"/>
<load module="mod_h26x"/>
<!--<load module="mod_siren"/>-->

View File

@ -1,4 +1,4 @@
<!-- http://wiki.freeswitch.org/wiki/Sofia_Configuration_Files -->
<!-- http://wiki.freeswitch.org/wiki/Sofia_Configuration_Files -->
<profile name="external">
<!-- This profile is only for outbound registrations to providers -->
<gateways>
@ -7,7 +7,7 @@
<aliases>
<alias name="outbound"/>
<alias name="nat"/> <!-- for backwards compatibility -->
<alias name="nat"/> <!-- for backwards compatibility -->
</aliases>
<domains>
@ -30,10 +30,10 @@
<!-- This could be set to "passive" -->
<param name="manage-presence" value="false"/>
<!-- used to share presence info across sofia profiles
manage-presence needs to be set to passive on this profile
if you want it to behave as if it were the internal profile
for presence.
<!-- used to share presence info across sofia profiles
manage-presence needs to be set to passive on this profile
if you want it to behave as if it were the internal profile
for presence.
-->
<!-- Name of the db to use for this profile -->
<!--<param name="dbname" value="share_presence"/>-->
@ -48,8 +48,10 @@
<param name="nonce-ttl" value="60"/>
<param name="auth-calls" value="false"/>
<param name="rtp-timeout-sec" value="1800"/>
<param name="inbound-late-negotiation" value="true"/>
<param name="inbound-zrtp-passthru" value="true"/>
<!--
DO NOT USE HOSTNAMES, ONLY IP ADDRESSES IN THESE SETTINGS!
DO NOT USE HOSTNAMES, ONLY IP ADDRESSES IN THESE SETTINGS!
-->
<param name="rtp-ip" value="$${local_ip_v4}"/>
<param name="sip-ip" value="$${local_ip_v4}"/>

View File

@ -9,7 +9,7 @@
<!--/// domain to use in from: *optional* same as realm, if blank ///-->
<!--<param name="from-domain" value="asterlink.com"/>-->
<!--/// account password *required* ///-->
<!--<param name="password" value="2007"/>-->
<!--<param name="password" value="2007"/>-->
<!--/// extension for inbound calls: *optional* same as username, if blank ///-->
<!--<param name="extension" value="cluecon"/>-->
<!--/// proxy host: *optional* same as realm, if blank ///-->

View File

@ -53,36 +53,39 @@
<param name="tls-cert-dir" value="$${internal_ssl_dir}"/>
<!-- TLS version ("sslv23" (default), "tlsv1"). NOTE: Phones may not work with TLSv1 -->
<param name="tls-version" value="$${sip_tls_version}"/>
<!--If you don't want to pass through timestampes from 1 RTP call to another (on a per call basis with rtp_rewrite_timestamps chanvar)-->
<!--<param name="rtp-rewrite-timestamps" value="true"/>-->
<!--<param name="pass-rfc2833" value="true"/>-->
<!--If you have ODBC support and a working dsn you can use it instead of SQLite-->
<!--<param name="odbc-dsn" value="dsn:user:pass"/>-->
<!--Uncomment to set all inbound calls to no media mode-->
<!--<param name="inbound-bypass-media" value="true"/>-->
<!--Uncomment to set all inbound calls to proxy media mode-->
<!--<param name="inbound-proxy-media" value="true"/>-->
<!--Uncomment to let calls hit the dialplan *before* you decide if the codec is ok-->
<!--<param name="inbound-late-negotiation" value="true"/>-->
<!-- Let calls hit the dialplan before selecting codec for the a-leg -->
<param name="inbound-late-negotiation" value="true"/>
<!-- Allow ZRTP clients to negotiate end-to-end security associations -->
<param name="inbound-zrtp-passthru" value="true"/>
<!-- this lets anything register -->
<!-- comment the next line and uncomment one or both of the other 2 lines for call authentication -->
<!-- <param name="accept-blind-reg" value="true"/> -->
<!-- accept any authentication without actually checking (not a good feature for most people) -->
<!-- <param name="accept-blind-auth" value="true"/> -->
<!-- suppress CNG on this profile or per call with the 'suppress_cng' variable -->
<!-- <param name="suppress-cng" value="true"/> -->
<!--TTL for nonce in sip auth-->
<param name="nonce-ttl" value="60"/>
<!--Uncomment if you want to force the outbound leg of a bridge to only offer the codec
that the originator is using-->
<!--Uncomment if you want to force the outbound leg of a bridge to only offer the codec
that the originator is using-->
<!--<param name="disable-transcoding" value="true"/>-->
<!-- Used for when phones respond to a challenged ACK with method INVITE in the hash -->
<!--<param name="NDLB-broken-auth-hash" value="true"/>-->
@ -128,4 +131,3 @@
</settings>
</profile>

View File

@ -1,7 +1,7 @@
<!--
This is a sofia sip profile/user agent. This will service exactly one ip and port.
In FreeSWITCH you can run multiple sip user agents on their own ip and port.
When you hear someone say "sofia profile" this is what they are talking about.
-->
@ -15,24 +15,24 @@
<gateways>
<X-PRE-PROCESS cmd="include" data="internal/*.xml"/>
</gateways>
<domains>
<!-- indicator to parse the directory for domains with parse="true" to get gateways-->
<!--<domain name="$${domain}" parse="true"/>-->
<!-- indicator to parse the directory for domains with parse="true" to get gateways and alias every domain to this profile -->
<!--<domain name="all" alias="true" parse="true"/>-->
<domain name="all" alias="true" parse="false"/>
<domain name="all" alias="true" parse="false"/>
</domains>
<settings>
<!--
When calls are in no media this will bring them back to media
when you press the hold button.
When calls are in no media this will bring them back to media
when you press the hold button.
-->
<!--<param name="media-option" value="resume-media-on-hold"/> -->
<!--
This will allow a call after an attended transfer go back to
bypass media after an attended transfer.
This will allow a call after an attended transfer go back to
bypass media after an attended transfer.
-->
<!--<param name="media-option" value="bypass-media-after-att-xfer"/>-->
<!-- <param name="user-agent-string" value="FreeSWITCH Rocks!"/> -->
@ -69,7 +69,7 @@
<!--<param name="dbname" value="share_presence"/>-->
<!--<param name="presence-hosts" value="$${domain}"/>-->
<!-- ************************************************* -->
<!-- This setting is for AAL2 bitpacking on G726 -->
<!-- <param name="bitpacking" value="aal2"/> -->
<!--max number of open dialogs in proceeding -->
@ -94,36 +94,39 @@
<param name="tls-cert-dir" value="$${internal_ssl_dir}"/>
<!-- TLS version ("sslv23" (default), "tlsv1"). NOTE: Phones may not work with TLSv1 -->
<param name="tls-version" value="$${sip_tls_version}"/>
<!--If you don't want to pass through timestamps from 1 RTP call to another (on a per call basis with rtp_rewrite_timestamps chanvar)-->
<!--<param name="rtp-rewrite-timestamps" value="true"/>-->
<!--<param name="pass-rfc2833" value="true"/>-->
<!--If you have ODBC support and a working dsn you can use it instead of SQLite-->
<!--<param name="odbc-dsn" value="dsn:user:pass"/>-->
<!--Uncomment to set all inbound calls to no media mode-->
<!--<param name="inbound-bypass-media" value="true"/>-->
<!--Uncomment to set all inbound calls to proxy media mode-->
<!--<param name="inbound-proxy-media" value="true"/>-->
<!--Uncomment to let calls hit the dialplan *before* you decide if the codec is ok-->
<!--<param name="inbound-late-negotiation" value="true"/>-->
<!-- Let calls hit the dialplan before selecting codec for the a-leg -->
<param name="inbound-late-negotiation" value="true"/>
<!-- Allow ZRTP clients to negotiate end-to-end security associations -->
<param name="inbound-zrtp-passthru" value="true"/>
<!-- this lets anything register -->
<!-- comment the next line and uncomment one or both of the other 2 lines for call authentication -->
<!-- <param name="accept-blind-reg" value="true"/> -->
<!-- accept any authentication without actually checking (not a good feature for most people) -->
<!-- <param name="accept-blind-auth" value="true"/> -->
<!-- suppress CNG on this profile or per call with the 'suppress_cng' variable -->
<!-- <param name="suppress-cng" value="true"/> -->
<!--TTL for nonce in sip auth-->
<param name="nonce-ttl" value="60"/>
<!--Uncomment if you want to force the outbound leg of a bridge to only offer the codec
that the originator is using-->
<!--Uncomment if you want to force the outbound leg of a bridge to only offer the codec
that the originator is using-->
<!--<param name="disable-transcoding" value="true"/>-->
<!-- Used for when phones respond to a challenged ACK with method INVITE in the hash -->
<!--<param name="NDLB-broken-auth-hash" value="true"/>-->
@ -154,24 +157,24 @@
<!--<param name="disable-transfer" value="true"/>-->
<!--<param name="disable-register" value="true"/>-->
<!-- enable-3pcc can be set to either 'true' or 'proxy', true accepts the call right away, proxy waits until the call has been answered then sends accepts -->
<!-- enable-3pcc can be set to either 'true' or 'proxy', true accepts the call right away, proxy waits until the call has been answered then sends accepts -->
<!--<param name="enable-3pcc" value="true"/>-->
<!-- use at your own risk or if you know what this does.-->
<!--<param name="NDLB-force-rport" value="true"/>-->
<!--
Choose the realm challenge key. Default is auto_to if not set.
auto_from - uses the from field as the value for the sip realm.
auto_to - uses the to field as the value for the sip realm.
<anyvalue> - you can input any value to use for the sip realm.
Choose the realm challenge key. Default is auto_to if not set.
If you want URL dialing to work you'll want to set this to auto_from.
If you use any other value besides auto_to or auto_from you'll loose
the ability to do multiple domains.
Note: comment out to restore the behavior before 2008-09-29
auto_from - uses the from field as the value for the sip realm.
auto_to - uses the to field as the value for the sip realm.
<anyvalue> - you can input any value to use for the sip realm.
If you want URL dialing to work you'll want to set this to auto_from.
If you use any other value besides auto_to or auto_from you'll loose
the ability to do multiple domains.
Note: comment out to restore the behavior before 2008-09-29
-->
<param name="challenge-realm" value="auto_from"/>
@ -182,4 +185,3 @@
<!--<param name="outbound-use-uuid-as-callid" value="true"/>-->
</settings>
</profile>

View File

@ -9,7 +9,7 @@
<!--/// domain to use in from: *optional* same as realm, if blank ///-->
<!--<param name="from-domain" value="asterlink.com"/>-->
<!--/// account password *required* ///-->
<!--<param name="password" value="2007"/>-->
<!--<param name="password" value="2007"/>-->
<!--/// extension for inbound calls: *optional* same as username, if blank ///-->
<!--<param name="extension" value="cluecon"/>-->
<!--/// proxy host: *optional* same as realm, if blank ///-->

View File

@ -3,7 +3,7 @@
<X-PRE-PROCESS cmd="set" data="auto_answer=false"/>
<X-PRE-PROCESS cmd="set" data="domain=$${local_ip_v4}"/>
<X-PRE-PROCESS cmd="set" data="hold_music=local_stream://moh"/>
<X-PRE-PROCESS cmd="set" data="codec_prefs=CELT@48000h,G7221@32000h,G7221@16000h,G722,PCMU,PCMA,GSM"/>
<X-PRE-PROCESS cmd="set" data="codec_prefs=CELT@48000h,G722,PCMU,PCMA,GSM"/>
<X-PRE-PROCESS cmd="set" data="external_rtp_ip=stun:stun.freeswitch.org"/>
<X-PRE-PROCESS cmd="set" data="external_sip_ip=stun:stun.freeswitch.org"/>
<X-PRE-PROCESS cmd="set" data="outbound_caller_name=FreeSWITCH"/>
@ -86,10 +86,8 @@
<load module="mod_dptools"/>
<load module="mod_dialplan_xml"/>
<load module="mod_voipcodecs"/>
<load module="mod_ilbc"/>
<load module="mod_speex"/>
<load module="mod_celt"/>
<load module="mod_siren"/>
<load module="mod_sndfile"/>
<load module="mod_tone_stream"/>
<load module="mod_local_stream"/>

View File

@ -16,6 +16,7 @@
<!-- <load module="mod_xml_rpc"/> -->
<!-- <load module="mod_xml_curl"/> -->
<!-- <load module="mod_xml_cdr"/> -->
<!-- <load module="mod_xml_scgi"/> -->
<!-- Event Handlers -->
<load module="mod_cdr_csv"/>
@ -62,6 +63,7 @@
<load module="mod_valet_parking"/>
<!--<load module="mod_fsk"/>-->
<!--<load module="mod_spy"/>-->
<!--<load module="mod_random"/>-->
<load module="mod_httapi"/>
<!-- SNOM Module -->
@ -80,10 +82,10 @@
<load module="mod_g723_1"/>
<load module="mod_g729"/>
<load module="mod_amr"/>
<load module="mod_ilbc"/>
<!--<load module="mod_ilbc"/>-->
<load module="mod_speex"/>
<load module="mod_h26x"/>
<load module="mod_siren"/>
<!--<load module="mod_siren"/>-->
<!--<load module="mod_isac"/>-->
<!--<load module="mod_celt"/>-->
<!--<load module="mod_opus"/>-->

View File

@ -0,0 +1,12 @@
<configuration name="xml_scgi.conf" description="SCGI XML Gateway">
<bindings>
<binding name="example">
<!-- one or more |-delim of configuration|directory|dialplan -->
<!-- <param name="host" value="127.0.0.1" bindings="dialplan"/> -->
<!-- <param name="port" value="8080"/> -->
<!-- <param name="timeout" value="10"/> -->
<!-- one or more of these imply you want to pick the exact variables that are transmitted -->
<!--<param name="enable-post-var" value="Unique-ID"/>-->
</binding>
</bindings>
</configuration>

View File

@ -29,7 +29,7 @@
<macro name="voicemail_change_pass_success">
<input pattern="(.*)">
<match>
<action function="play-file" data="ivr/ivr-Thank_you.wav"/>
<action function="play-file" data="voicemail/vm-password_has_been_changed.wav"/>
</match>
</input>
</macro>
@ -37,7 +37,7 @@
<macro name="voicemail_change_pass_fail">
<input pattern="(.*)">
<match>
<action function="play-file" data="voicemail/vm-fail_auth.wav"/>
<action function="play-file" data="voicemail/vm-password_not_valid.wav"/>
</match>
</input>
</macro>

View File

@ -1,14 +1,14 @@
<profile name="external">
<!-- http://wiki.freeswitch.org/wiki/Sofia_Configuration_Files -->
<!-- http://wiki.freeswitch.org/wiki/Sofia_Configuration_Files -->
<!-- This profile is only for outbound registrations to providers -->
<gateways>
<X-PRE-PROCESS cmd="include" data="external/*.xml"/>
</gateways>
<aliases>
<!--
<alias name="outbound"/>
<alias name="nat"/>
<!--
<alias name="outbound"/>
<alias name="nat"/>
-->
</aliases>
@ -18,10 +18,10 @@
<settings>
<param name="debug" value="0"/>
<!-- If you want FreeSWITCH to shutdown if this profile fails to load, uncomment the next line. -->
<!-- <param name="shutdown-on-fail" value="true"/> -->
<!-- If you want FreeSWITCH to shutdown if this profile fails to load, uncomment the next line. -->
<!-- <param name="shutdown-on-fail" value="true"/> -->
<param name="sip-trace" value="no"/>
<param name="sip-capture" value="no"/>
<param name="sip-capture" value="no"/>
<param name="rfc2833-pt" value="101"/>
<!-- RFC 5626 : Send reg-id and sip.instance -->
<!--<param name="enable-rfc-5626" value="true"/> -->
@ -34,15 +34,15 @@
<param name="hold-music" value="$${hold_music}"/>
<param name="rtp-timer-name" value="soft"/>
<!--<param name="enable-100rel" value="true"/>-->
<!--<param name="disable-srv503" value="true"/>-->
<!--<param name="disable-srv503" value="true"/>-->
<!-- This could be set to "passive" -->
<param name="local-network-acl" value="localnet.auto"/>
<param name="manage-presence" value="false"/>
<!-- used to share presence info across sofia profiles
manage-presence needs to be set to passive on this profile
if you want it to behave as if it were the internal profile
for presence.
<!-- used to share presence info across sofia profiles
manage-presence needs to be set to passive on this profile
if you want it to behave as if it were the internal profile
for presence.
-->
<!-- Name of the db to use for this profile -->
<!--<param name="dbname" value="share_presence"/>-->
@ -56,8 +56,10 @@
<param name="inbound-codec-negotiation" value="generous"/>
<param name="nonce-ttl" value="60"/>
<param name="auth-calls" value="false"/>
<param name="inbound-late-negotiation" value="true"/>
<param name="inbound-zrtp-passthru" value="true"/>
<!--
DO NOT USE HOSTNAMES, ONLY IP ADDRESSES IN THESE SETTINGS!
DO NOT USE HOSTNAMES, ONLY IP ADDRESSES IN THESE SETTINGS!
-->
<param name="rtp-ip" value="$${local_ip_v4}"/>
<param name="sip-ip" value="$${local_ip_v4}"/>
@ -90,6 +92,5 @@
<param name="tls-verify-in-subjects" value=""/>
<!-- TLS version ("sslv23" (default), "tlsv1"). NOTE: Phones may not work with TLSv1 -->
<param name="tls-version" value="$${sip_tls_version}"/>
</settings>
</profile>

View File

@ -9,7 +9,7 @@
<!--/// domain to use in from: *optional* same as realm, if blank ///-->
<!--<param name="from-domain" value="asterlink.com"/>-->
<!--/// account password *required* ///-->
<!--<param name="password" value="2007"/>-->
<!--<param name="password" value="2007"/>-->
<!--/// extension for inbound calls: *optional* same as username, if blank ///-->
<!--<param name="extension" value="cluecon"/>-->
<!--/// proxy host: *optional* same as realm, if blank ///-->

View File

@ -54,36 +54,39 @@
<param name="tls-cert-dir" value="$${internal_ssl_dir}"/>
<!-- TLS version ("sslv23" (default), "tlsv1"). NOTE: Phones may not work with TLSv1 -->
<param name="tls-version" value="$${sip_tls_version}"/>
<!--If you don't want to pass through timestampes from 1 RTP call to another (on a per call basis with rtp_rewrite_timestamps chanvar)-->
<!--<param name="rtp-rewrite-timestamps" value="true"/>-->
<!--<param name="pass-rfc2833" value="true"/>-->
<!--If you have ODBC support and a working dsn you can use it instead of SQLite-->
<!--<param name="odbc-dsn" value="dsn:user:pass"/>-->
<!--Uncomment to set all inbound calls to no media mode-->
<!--<param name="inbound-bypass-media" value="true"/>-->
<!--Uncomment to set all inbound calls to proxy media mode-->
<!--<param name="inbound-proxy-media" value="true"/>-->
<!--Uncomment to let calls hit the dialplan *before* you decide if the codec is ok-->
<!--<param name="inbound-late-negotiation" value="true"/>-->
<!-- Let calls hit the dialplan before selecting codec for the a-leg -->
<param name="inbound-late-negotiation" value="true"/>
<!-- Allow ZRTP clients to negotiate end-to-end security associations -->
<param name="inbound-zrtp-passthru" value="true"/>
<!-- this lets anything register -->
<!-- comment the next line and uncomment one or both of the other 2 lines for call authentication -->
<!-- <param name="accept-blind-reg" value="true"/> -->
<!-- accept any authentication without actually checking (not a good feature for most people) -->
<!-- <param name="accept-blind-auth" value="true"/> -->
<!-- suppress CNG on this profile or per call with the 'suppress_cng' variable -->
<!-- <param name="suppress-cng" value="true"/> -->
<!--TTL for nonce in sip auth-->
<param name="nonce-ttl" value="60"/>
<!--Uncomment if you want to force the outbound leg of a bridge to only offer the codec
that the originator is using-->
<!--Uncomment if you want to force the outbound leg of a bridge to only offer the codec
that the originator is using-->
<!--<param name="disable-transcoding" value="true"/>-->
<!-- Used for when phones respond to a challenged ACK with method INVITE in the hash -->
<!--<param name="NDLB-broken-auth-hash" value="true"/>-->
@ -103,8 +106,8 @@
<!-- <param name="vad" value="both"/> -->
<!--<param name="alias" value="sip:10.0.1.251:5555"/>-->
<!--
These are enabled to make the default config work better out of the box.
If you need more than ONE domain you'll need to not use these options.
These are enabled to make the default config work better out of the box.
If you need more than ONE domain you'll need to not use these options.
-->
<!--all inbound reg will look in this domain for the users -->
@ -121,10 +124,9 @@
<!-- set to true to have the profile determine stun is not useful and turn it off globally-->
<!--<param name="stun-auto-disable" value="true"/>-->
<!-- the following can be used as workaround with bogus SRV/NAPTR records -->
<!--<param name="disable-srv" value="false" />-->
<!--<param name="disable-naptr" value="false" />-->
<!-- the following can be used as workaround with bogus SRV/NAPTR records -->
<!--<param name="disable-srv" value="false" />-->
<!--<param name="disable-naptr" value="false" />-->
</settings>
</profile>

View File

@ -2,30 +2,30 @@
<!--
This is a sofia sip profile/user agent. This will service exactly one ip and port.
In FreeSWITCH you can run multiple sip user agents on their own ip and port.
When you hear someone say "sofia profile" this is what they are talking about.
-->
<!-- http://wiki.freeswitch.org/wiki/Sofia_Configuration_Files -->
<!--aliases are other names that will work as a valid profile name for this profile-->
<aliases>
<!--
<alias name="default"/>
<alias name="default"/>
-->
</aliases>
<!-- Outbound Registrations -->
<gateways>
<X-PRE-PROCESS cmd="include" data="internal/*.xml"/>
</gateways>
<domains>
<!-- indicator to parse the directory for domains with parse="true" to get gateways-->
<!--<domain name="$${domain}" parse="true"/>-->
<!-- indicator to parse the directory for domains with parse="true" to get gateways and alias every domain to this profile -->
<!--<domain name="all" alias="true" parse="true"/>-->
<domain name="all" alias="true" parse="false"/>
<domain name="all" alias="true" parse="false"/>
</domains>
<settings>
@ -33,31 +33,31 @@
<!-- <param name="rtp-digit-delay" value="40"/>-->
<!--
When calls are in no media this will bring them back to media
when you press the hold button.
When calls are in no media this will bring them back to media
when you press the hold button.
-->
<!--<param name="media-option" value="resume-media-on-hold"/> -->
<!--
This will allow a call after an attended transfer go back to
bypass media after an attended transfer.
This will allow a call after an attended transfer go back to
bypass media after an attended transfer.
-->
<!--<param name="media-option" value="bypass-media-after-att-xfer"/>-->
<!-- <param name="user-agent-string" value="FreeSWITCH Rocks!"/> -->
<param name="debug" value="0"/>
<!-- If you want FreeSWITCH to shutdown if this profile fails to load, uncomment the next line. -->
<!-- <param name="shutdown-on-fail" value="true"/> -->
<!-- If you want FreeSWITCH to shutdown if this profile fails to load, uncomment the next line. -->
<!-- <param name="shutdown-on-fail" value="true"/> -->
<param name="sip-trace" value="no"/>
<param name="sip-capture" value="no"/>
<!-- Use presence_map.conf.xml to convert extension regex to presence protos for routing -->
<!-- <param name="presence-proto-lookup" value="true"/> -->
<!-- Don't be picky about negotiated DTMF just always offer 2833 and accept both 2833 and INFO -->
<!--<param name="liberal-dtmf" value="true"/>-->
<!--
<!--
Sometimes, in extremely rare edge cases, the Sofia SIP stack may stop
responding. These options allow you to enable and control a watchdog
on the Sofia SIP stack so that if it stops responding for the
@ -70,7 +70,7 @@
through the FreeSWITCH CLI either on an individual profile basis or
globally for all profiles. So, if you run in an HA environment with a
master and slave, you should use the CLI to make sure the watchdog is
only enabled on the master.
only enabled on the master.
If such crash occurs, FreeSWITCH will dump core if allowed. The
stacktrace will include function watchdog_triggered_abort().
-->
@ -106,26 +106,26 @@
<!--<param name="aggressive-nat-detection" value="true"/>-->
<!--
There are known issues (asserts and segfaults) when 100rel is enabled.
It is not recommended to enable 100rel at this time.
There are known issues (asserts and segfaults) when 100rel is enabled.
It is not recommended to enable 100rel at this time.
-->
<!--<param name="enable-100rel" value="true"/>-->
<!-- uncomment if you don't wish to try a next SRV destination on 503 response -->
<!-- RFC3263 Section 4.3 -->
<!--<param name="disable-srv503" value="true"/>-->
<!-- RFC3263 Section 4.3 -->
<!--<param name="disable-srv503" value="true"/>-->
<!-- Enable Compact SIP headers. -->
<!--<param name="enable-compact-headers" value="true"/>-->
<!--
enable/disable session timers
enable/disable session timers
-->
<!--<param name="enable-timer" value="false"/>-->
<!--<param name="minimum-session-expires" value="120"/>-->
<param name="apply-inbound-acl" value="domains"/>
<!--
This defines your local network, by default we detect your local network
and create this localnet.auto ACL for this.
This defines your local network, by default we detect your local network
and create this localnet.auto ACL for this.
-->
<param name="local-network-acl" value="localnet.auto"/>
<!--<param name="apply-register-acl" value="domains"/>-->
@ -134,10 +134,10 @@
<!-- 'true' means every time 'first-only' means on the first register -->
<!--<param name="send-message-query-on-register" value="true"/>-->
<!-- 'true' means every time 'first-only' means on the first register -->
<!--<param name="send-presence-on-register" value="first-only"/> -->
<!-- Caller-ID type (choose one, can be overridden by inbound call type and/or sip_cid_type channel variable -->
<!-- Remote-Party-ID header -->
@ -164,7 +164,7 @@
<param name="presence-hosts" value="$${domain},$${local_ip_v4}"/>
<param name="presence-privacy" value="$${presence_privacy}"/>
<!-- ************************************************* -->
<!-- This setting is for AAL2 bitpacking on G726 -->
<!-- <param name="bitpacking" value="aal2"/> -->
<!--max number of open dialogs in proceeding -->
@ -203,39 +203,42 @@
<!-- TLS version ("sslv23" (default), "tlsv1"). NOTE: Phones may not work with TLSv1 -->
<param name="tls-version" value="$${sip_tls_version}"/>
<!-- turn on auto-flush during bridge (skip timer sleep when the socket already has data)
(reduces delay on latent connections default true, must be disabled explicitly)-->
<!-- turn on auto-flush during bridge (skip timer sleep when the socket already has data)
(reduces delay on latent connections default true, must be disabled explicitly)-->
<!--<param name="rtp-autoflush-during-bridge" value="false"/>-->
<!--If you don't want to pass through timestamps from 1 RTP call to another (on a per call basis with rtp_rewrite_timestamps chanvar)-->
<!--<param name="rtp-rewrite-timestamps" value="true"/>-->
<!--<param name="pass-rfc2833" value="true"/>-->
<!--If you have ODBC support and a working dsn you can use it instead of SQLite-->
<!--<param name="odbc-dsn" value="dsn:user:pass"/>-->
<!--Uncomment to set all inbound calls to no media mode-->
<!--<param name="inbound-bypass-media" value="true"/>-->
<!--Uncomment to set all inbound calls to proxy media mode-->
<!--<param name="inbound-proxy-media" value="true"/>-->
<!--Uncomment to let calls hit the dialplan *before* you decide if the codec is ok-->
<!--<param name="inbound-late-negotiation" value="true"/>-->
<!-- Let calls hit the dialplan before selecting codec for the a-leg -->
<param name="inbound-late-negotiation" value="true"/>
<!-- Allow ZRTP clients to negotiate end-to-end security associations -->
<param name="inbound-zrtp-passthru" value="true"/>
<!-- this lets anything register -->
<!-- comment the next line and uncomment one or both of the other 2 lines for call authentication -->
<!-- <param name="accept-blind-reg" value="true"/> -->
<!-- accept any authentication without actually checking (not a good feature for most people) -->
<!-- <param name="accept-blind-auth" value="true"/> -->
<!-- suppress CNG on this profile or per call with the 'suppress_cng' variable -->
<!-- <param name="suppress-cng" value="true"/> -->
<!--TTL for nonce in sip auth-->
<param name="nonce-ttl" value="60"/>
<!--Uncomment if you want to force the outbound leg of a bridge to only offer the codec
that the originator is using-->
<!--Uncomment if you want to force the outbound leg of a bridge to only offer the codec
that the originator is using-->
<!--<param name="disable-transcoding" value="true"/>-->
<!-- Handle 302 Redirect in the dialplan -->
<!--<param name="manual-redirect" value="true"/> -->
@ -252,16 +255,16 @@
<param name="inbound-reg-force-matching-username" value="true"/>
<!-- on authed calls, authenticate *all* the packets not just invite -->
<param name="auth-all-packets" value="false"/>
<!-- external_sip_ip
Used as the public IP address for SDP.
Can be an one of:
ip address - "12.34.56.78"
a stun server lookup - "stun:stun.server.com"
a DNS name - "host:host.server.com"
auto - Use guessed ip.
auto-nat - Use ip learned from NAT-PMP or UPNP
-->
Used as the public IP address for SDP.
Can be an one of:
ip address - "12.34.56.78"
a stun server lookup - "stun:stun.server.com"
a DNS name - "host:host.server.com"
auto - Use guessed ip.
auto-nat - Use ip learned from NAT-PMP or UPNP
-->
<param name="ext-rtp-ip" value="auto-nat"/>
<param name="ext-sip-ip" value="auto-nat"/>
@ -274,8 +277,8 @@
<!-- <param name="vad" value="both"/> -->
<!--<param name="alias" value="sip:10.0.1.251:5555"/>-->
<!--
These are enabled to make the default config work better out of the box.
If you need more than ONE domain you'll need to not use these options.
These are enabled to make the default config work better out of the box.
If you need more than ONE domain you'll need to not use these options.
-->
<!--all inbound reg will look in this domain for the users -->
@ -297,28 +300,27 @@
<!--<param name="disable-transfer" value="true"/>-->
<!--<param name="disable-register" value="true"/>-->
<!--
enable-3pcc can be set to either 'true' or 'proxy', true accepts the call
right away, proxy waits until the call has been answered then sends accepts
<!--
enable-3pcc can be set to either 'true' or 'proxy', true accepts the call
right away, proxy waits until the call has been answered then sends accepts
-->
<!--<param name="enable-3pcc" value="true"/>-->
<!-- use at your own risk or if you know what this does.-->
<!--<param name="NDLB-force-rport" value="true"/>-->
<!--
Choose the realm challenge key. Default is auto_to if not set.
auto_from - uses the from field as the value for the sip realm.
auto_to - uses the to field as the value for the sip realm.
<anyvalue> - you can input any value to use for the sip realm.
Choose the realm challenge key. Default is auto_to if not set.
If you want URL dialing to work you'll want to set this to auto_from.
If you use any other value besides auto_to or auto_from you'll loose
the ability to do multiple domains.
Note: comment out to restore the behavior before 2008-09-29
auto_from - uses the from field as the value for the sip realm.
auto_to - uses the to field as the value for the sip realm.
<anyvalue> - you can input any value to use for the sip realm.
If you want URL dialing to work you'll want to set this to auto_from.
If you use any other value besides auto_to or auto_from you'll
loose the ability to do multiple domains.
Note: comment out to restore the behavior before 2008-09-29
-->
<param name="challenge-realm" value="auto_from"/>
<!--<param name="disable-rtp-auto-adjust" value="true"/>-->
@ -332,59 +334,58 @@
<!-- set this param to false if your gateway for some reason hates X- headers that it is supposed to ignore-->
<!--<param name="pass-callee-id" value="false"/>-->
<!-- clear clears them all or supply the name to add or the name prefixed with ~ to remove
valid values:
<!-- clear clears them all or supply the name to add or the name
prefixed with ~ to remove valid values:
clear
CISCO_SKIP_MARK_BIT_2833
SONUS_SEND_INVALID_TIMESTAMP_2833
clear
CISCO_SKIP_MARK_BIT_2833
SONUS_SEND_INVALID_TIMESTAMP_2833
-->
<!--<param name="auto-rtp-bugs" data="clear"/>-->
<!-- the following can be used as workaround with bogus SRV/NAPTR records -->
<!--<param name="disable-srv" value="false" />-->
<!--<param name="disable-naptr" value="false" />-->
<!-- the following can be used as workaround with bogus SRV/NAPTR records -->
<!--<param name="disable-srv" value="false" />-->
<!--<param name="disable-naptr" value="false" />-->
<!-- The following can be used to fine-tune timers within sofia's transport layer
Those settings are for advanced users and can safely be left as-is -->
<!-- Initial retransmission interval (in milliseconds).
Set the T1 retransmission interval used by the SIP transaction engine.
The T1 is the initial duration used by request retransmission timers A and E (UDP) as well as response retransmission timer G. -->
<!-- <param name="timer-T1" value="500" /> -->
<!-- Transaction timeout (defaults to T1 * 64).
Set the T1x64 timeout value used by the SIP transaction engine.
The T1x64 is duration used for timers B, F, H, and J (UDP) by the SIP transaction engine.
The timeout value T1x64 can be adjusted separately from the initial retransmission interval T1. -->
<!-- <param name="timer-T1X64" value="32000" /> -->
<!-- Maximum retransmission interval (in milliseconds).
Set the maximum retransmission interval used by the SIP transaction engine.
The T2 is the maximum duration used for the timers E (UDP) and G by the SIP transaction engine.
Note that the timer A is not capped by T2. Retransmission interval of INVITE requests grows exponentially
until the timer B fires. -->
<!-- <param name="timer-T2" value="4000" /> -->
<!--
Transaction lifetime (in milliseconds).
Set the lifetime for completed transactions used by the SIP transaction engine.
A completed transaction is kept around for the duration of T4 in order to catch late responses.
The T4 is the maximum duration for the messages to stay in the network and the duration of SIP timer K. -->
<!-- <param name="timer-T4" value="4000" /> -->
<!-- The following can be used to fine-tune timers within sofia's transport layer
Those settings are for advanced users and can safely be left as-is -->
<!-- Turn on a jitterbuffer for every call -->
<!-- <param name="auto-jitterbuffer-msec" value="60"/> -->
<!-- Initial retransmission interval (in milliseconds).
Set the T1 retransmission interval used by the SIP transaction engine.
The T1 is the initial duration used by request retransmission timers A and E (UDP) as well as response retransmission timer G. -->
<!-- <param name="timer-T1" value="500" /> -->
<!-- Transaction timeout (defaults to T1 * 64).
Set the T1x64 timeout value used by the SIP transaction engine.
The T1x64 is duration used for timers B, F, H, and J (UDP) by the SIP transaction engine.
The timeout value T1x64 can be adjusted separately from the initial retransmission interval T1. -->
<!-- <param name="timer-T1X64" value="32000" /> -->
<!-- By default mod_sofia will ignore the codecs in the sdp for hold/unhold operations
Set this to true if you want to actually parse the sdp and re-negotiate the codec during hold/unhold.
It's probably not what you want so stick with the default unless you really need to change this.
-->
<!--<param name="renegotiate-codec-on-hold" value="true"/>-->
<!-- Maximum retransmission interval (in milliseconds).
Set the maximum retransmission interval used by the SIP transaction engine.
The T2 is the maximum duration used for the timers E (UDP) and G by the SIP transaction engine.
Note that the timer A is not capped by T2. Retransmission interval of INVITE requests grows exponentially
until the timer B fires. -->
<!-- <param name="timer-T2" value="4000" /> -->
<!--
Transaction lifetime (in milliseconds).
Set the lifetime for completed transactions used by the SIP transaction engine.
A completed transaction is kept around for the duration of T4 in order to catch late responses.
The T4 is the maximum duration for the messages to stay in the network and the duration of SIP timer K. -->
<!-- <param name="timer-T4" value="4000" /> -->
<!-- Turn on a jitterbuffer for every call -->
<!-- <param name="auto-jitterbuffer-msec" value="60"/> -->
<!-- By default mod_sofia will ignore the codecs in the sdp for hold/unhold operations
Set this to true if you want to actually parse the sdp and re-negotiate the codec during hold/unhold.
It's probably not what you want so stick with the default unless you really need to change this.
-->
<!--<param name="renegotiate-codec-on-hold" value="true"/>-->
</settings>
</profile>

View File

@ -9,7 +9,7 @@
<!--/// domain to use in from: *optional* same as realm, if blank ///-->
<!--<param name="from-domain" value="asterlink.com"/>-->
<!--/// account password *required* ///-->
<!--<param name="password" value="2007"/>-->
<!--<param name="password" value="2007"/>-->
<!--/// extension for inbound calls: *optional* same as username, if blank ///-->
<!--<param name="extension" value="cluecon"/>-->
<!--/// proxy host: *optional* same as realm, if blank ///-->

View File

@ -123,7 +123,7 @@
127 - BV32
-->
<X-PRE-PROCESS cmd="set" data="global_codec_prefs=G7221@32000h,G7221@16000h,G722,PCMU,PCMA,GSM"/>
<X-PRE-PROCESS cmd="set" data="global_codec_prefs=G722,PCMU,PCMA,GSM"/>
<X-PRE-PROCESS cmd="set" data="outbound_codec_prefs=PCMU,PCMA,GSM"/>
<!--

View File

@ -3,11 +3,11 @@
# Must change all of the below together
# For a release, set revision for that tagged release as well and uncomment
AC_INIT([freeswitch], [1.1.beta1], BUG-REPORT-ADDRESS)
AC_SUBST(SWITCH_VERSION_MAJOR, [1])
AC_SUBST(SWITCH_VERSION_MINOR, [1])
AC_SUBST(SWITCH_VERSION_MICRO, [beta1])
#AC_SUBST(SWITCH_VERSION_REVISION, [])
AC_INIT([freeswitch], [4.3.0], BUG-REPORT-ADDRESS)
AC_SUBST(SWITCH_VERSION_MAJOR, [4])
AC_SUBST(SWITCH_VERSION_MINOR, [3])
AC_SUBST(SWITCH_VERSION_MICRO, [0])
AC_SUBST(SWITCH_VERSION_REVISION, [3e39945d73bc55c9bae492161e968bed239a4f4f])
AC_CONFIG_FILES([src/include/switch_version.h.in:src/include/switch_version.h.template])
AC_CONFIG_FILES([.version:.version.in])
@ -993,7 +993,6 @@ AC_CONFIG_FILES([Makefile
src/Makefile
src/mod/Makefile
src/mod/applications/mod_expr/Makefile
src/mod/applications/mod_fax/Makefile
src/mod/applications/mod_spandsp/Makefile
src/mod/applications/mod_osp/Makefile
src/mod/applications/mod_stress/Makefile

2
debian/.gitignore vendored
View File

@ -20,7 +20,6 @@
/freeswitch-dbg/
/freeswitch-dev/
/freeswitch-doc/
/freeswitch-htdocs-slim*/
/freeswitch-init*/
/freeswitch-meta*/
/freeswitch-mod-*/
@ -28,3 +27,4 @@
/freeswitch-sounds*/
/freeswitch-systemd/
/freeswitch-sysvinit/
/libfreeswitch*/

17
debian/README.source vendored
View File

@ -48,10 +48,17 @@ The format of debian/modules.conf is:
To build this package, I recommend running the following from the root
directory of your FS git working tree:
mkdir ../sounds
export FS_SOUNDS_DIR=$(pwd)/../sounds
distro=sid
ver="$(cat build/next-release.txt | sed -e 's/-/~/g')~n$(date +%Y%m%dT%H%M%SZ)-1~${distro}+1"
git clean -fdx && git reset --hard HEAD
(cd debian && ./bootstrap.sh)
schedtool -B -e git-buildpackage --git-verbose -us -uc
./build/set-fs-version.sh "$ver"
git add configure.in && git commit -m "bump to custom v$ver"
(cd debian && ./bootstrap.sh -c $distro)
dch -b -m -v "$ver" --force-distribution -D "$suite" "Custom build."
git-buildpackage -b -us -uc \
--git-verbose \
--git-pbuilder --git-dist=$distro \
--git-compression-level=1v --git-compression=xz
git reset --hard HEAD^
-- Travis Cross <tc@traviscross.com>, Sat, 5 May 2012 23:32:53 +0000
-- Travis Cross <tc@traviscross.com>, Thu, 24 May 2012 16:35:57 +0000

290
debian/bootstrap.sh vendored
View File

@ -6,38 +6,47 @@ mod_dir="../src/mod"
conf_dir="../conf"
fs_description="FreeSWITCH is a scalable open source cross-platform telephony platform designed to route and interconnect popular communication protocols using audio, video, text or any other form of media."
mod_build_depends="."
supported_distros="squeeze wheezy sid"
avoid_mods=(
applications/mod_fax
applications/mod_ladspa
applications/mod_limit
applications/mod_mongo
applications/mod_mp4
applications/mod_osp
applications/mod_rad_auth
applications/mod_skel
applications/mod_soundtouch
asr_tts/mod_cepstral
asr_tts/mod_flite
codecs/mod_com_g729
codecs/mod_ilbc
codecs/mod_sangoma_codec
codecs/mod_siren
codecs/mod_skel_codec
codecs/mod_voipcodecs
endpoints/mod_gsmopen
endpoints/mod_h323
endpoints/mod_khomp
endpoints/mod_opal
endpoints/mod_portaudio
endpoints/mod_reference
endpoints/mod_unicall
event_handlers/mod_snmp
formats/mod_portaudio_stream
formats/mod_shout
formats/mod_vlc
languages/mod_java
languages/mod_managed
languages/mod_spidermonkey
languages/mod_yaml
sdk/autotools
xml_int/mod_xml_ldap
)
avoid_mods_sid=(
endpoints/mod_portaudio
formats/mod_portaudio_stream
)
avoid_mods_wheezy=(
endpoints/mod_portaudio
formats/mod_portaudio_stream
)
avoid_mods_squeeze=(
formats/mod_vlc
languages/mod_managed
)
err () {
echo "$0 error: $1" >&2
@ -54,15 +63,23 @@ xread () {
}
avoid_mod_filter () {
for x in "${avoid_mods[@]}"; do
[ "$1" = "$x" ] && return 1
local x="avoid_mods_$codename[@]"
local -a mods=("${avoid_mods[@]}" "${!x}")
for x in "${mods[@]}"; do
if [ "$1" = "$x" ]; then
[ "$2" = "show" ] && echo "excluding module $x" >&2
return 1
fi
done
return 0
}
modconf_filter () {
while xread line; do
[ "$1" = "$line" ] && return 0
while xread l; do
if [ "$1" = "$l" ]; then
[ "$2" = "show" ] && echo "including module $l" >&2
return 0
fi
done < modules.conf
return 1
}
@ -75,6 +92,10 @@ mod_filter () {
fi
}
mod_filter_show () {
mod_filter "$1" show
}
map_fs_modules () {
local filterfn="$1" percatfns="$2" permodfns="$3"
for x in $mod_dir/*; do
@ -106,18 +127,23 @@ map_modules () {
module=${y##*/} module_path=$y
$filterfn $category/$module || continue
module="" category="" module_name=""
description="" long_description=""
section="" description="" long_description=""
build_depends="" depends="" recommends="" suggests=""
distro_conflicts=""
distro_vars=""
for x in $supported_distros; do
distro_vars="$distro_vars build_depends_$x"
eval build_depends_$x=""
done
. $y
[ -n "$description" ] || description="$module_name"
[ -n "$long_description" ] || description="Adds ${module_name}."
for f in $permodfns; do $f; done
unset \
module module_name module_path \
description long_description \
section description long_description \
build_depends depends recommends suggests \
distro_conflicts
distro_conflicts $distro_vars
done
unset category category_path
done
@ -150,7 +176,7 @@ Build-Depends:
wget, pkg-config,
# configure options
libssl-dev, unixodbc-dev,
libncurses5-dev, libjpeg8-dev,
libncurses5-dev, libjpeg62-dev,
python-dev, erlang-dev,
# documentation
doxygen,
@ -172,7 +198,8 @@ print_core_control () {
cat <<EOF
Package: freeswitch
Architecture: any
Depends: \${shlibs:Depends}, \${perl:Depends}, \${misc:Depends}
Depends: \${shlibs:Depends}, \${perl:Depends}, \${misc:Depends},
libfreeswitch1 (= \${binary:Version})
Recommends:
Suggests: freeswitch-dbg
Description: Cross-Platform Scalable Multi-Protocol Soft Switch
@ -180,12 +207,21 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch
.
This package contains the FreeSWITCH core.
Package: libfreeswitch1
Architecture: any
Depends: \${shlibs:Depends}, \${misc:Depends}
Recommends:
Suggests: libfreeswitch1-dbg
Description: Cross-Platform Scalable Multi-Protocol Soft Switch
$(debian_wrap "${fs_description}")
.
This package contains the FreeSWITCH core library.
Package: freeswitch-meta-bare
Architecture: any
Depends: \${misc:Depends}, freeswitch (= \${binary:Version})
Recommends:
freeswitch-doc (= \${binary:Version}),
freeswitch-htdocs-slim (= \${binary:Version}),
freeswitch-mod-commands (= \${binary:Version}),
freeswitch-init (= \${binary:Version}),
freeswitch-music (= \${binary:Version}),
@ -264,10 +300,8 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}),
freeswitch-mod-g723-1 (= \${binary:Version}),
freeswitch-mod-g729 (= \${binary:Version}),
freeswitch-mod-amr (= \${binary:Version}),
freeswitch-mod-ilbc (= \${binary:Version}),
freeswitch-mod-speex (= \${binary:Version}),
freeswitch-mod-h26x (= \${binary:Version}),
freeswitch-mod-siren (= \${binary:Version}),
freeswitch-mod-sndfile (= \${binary:Version}),
freeswitch-mod-native-file (= \${binary:Version}),
freeswitch-mod-local-stream (= \${binary:Version}),
@ -298,13 +332,15 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}),
freeswitch-mod-g723-1 (= \${binary:Version}),
freeswitch-mod-g729 (= \${binary:Version}),
freeswitch-mod-h26x (= \${binary:Version}),
freeswitch-mod-ilbc (= \${binary:Version}),
freeswitch-mod-mp4v (= \${binary:Version}),
freeswitch-mod-opus (= \${binary:Version}),
freeswitch-mod-silk (= \${binary:Version}),
freeswitch-mod-siren (= \${binary:Version}),
freeswitch-mod-spandsp (= \${binary:Version}),
freeswitch-mod-speex (= \${binary:Version}),
freeswitch-mod-theora (= \${binary:Version})
Suggests:
freeswitch-mod-ilbc (= \${binary:Version}),
freeswitch-mod-siren (= \${binary:Version})
Description: Cross-Platform Scalable Multi-Protocol Soft Switch
$(debian_wrap "${fs_description}")
.
@ -321,7 +357,17 @@ Description: debugging symbols for FreeSWITCH
.
This package contains debugging symbols for FreeSWITCH.
Package: freeswitch-dev
Package: libfreeswitch1-dbg
Section: debug
Priority: extra
Architecture: any
Depends: \${misc:Depends}, libfreeswitch1 (= \${binary:Version})
Description: debugging symbols for FreeSWITCH
$(debian_wrap "${fs_description}")
.
This package contains debugging symbols for libfreeswitch1.
Package: libfreeswitch-dev
Section: libdevel
Architecture: any
Depends: \${misc:Depends}, freeswitch
@ -369,40 +415,18 @@ Description: FreeSWITCH systemd configuration
## misc
Package: freeswitch-htdocs-slim
Architecture: all
Depends: \${misc:Depends}
Description: FreeSWITCH htdocs slim player
$(debian_wrap "${fs_description}")
.
This package contains the slim SWF player for FreeSWITCH.
## sounds
Package: freeswitch-music
Architecture: all
Depends: \${misc:Depends},
freeswitch-music-default (= \${binary:Version})
freeswitch-music-default (>= 1.0.8)
Description: Music on hold audio for FreeSWITCH
$(debian_wrap "${fs_description}")
.
This is a metapackage which depends on the default music on hold
packages for FreeSWITCH.
Package: freeswitch-music-default
Architecture: all
Depends: \${misc:Depends},
freeswitch-music-default-8k (= \${binary:Version})
Recommends:
freeswitch-music-default-16k (= \${binary:Version}),
freeswitch-music-default-32k (= \${binary:Version}),
freeswitch-music-default-48k (= \${binary:Version})
Description: Music on hold audio for FreeSWITCH
$(debian_wrap "${fs_description}")
.
This is a metapackage which depends on the default music on hold
packages for FreeSWITCH at various sampling rates.
Package: freeswitch-sounds
Architecture: all
Depends: \${misc:Depends},
@ -426,33 +450,21 @@ Description: English sounds for FreeSWITCH
Package: freeswitch-sounds-en-us
Architecture: all
Depends: \${misc:Depends},
freeswitch-sounds-en-us-callie (= \${binary:Version})
freeswitch-sounds-en-us-callie (>= 1.0.18)
Description: US English sounds for FreeSWITCH
$(debian_wrap "${fs_description}")
.
This is a metapackage which depends on the default US/English sound
packages for FreeSWITCH.
Package: freeswitch-sounds-en-us-callie
Architecture: all
Depends: \${misc:Depends},
freeswitch-sounds-en-us-callie-8k (= \${binary:Version})
Recommends:
freeswitch-sounds-en-us-callie-16k (= \${binary:Version}),
freeswitch-sounds-en-us-callie-32k (= \${binary:Version}),
freeswitch-sounds-en-us-callie-48k (= \${binary:Version})
Description: US English sounds for FreeSWITCH
$(debian_wrap "${fs_description}")
.
This is a metapackage which depends on the US/English Callie sound
packages for FreeSWITCH at various sampling rates.
EOF
}
print_mod_control () {
local m_section="${section:-comm}"
cat <<EOF
Package: freeswitch-${module_name//_/-}
Section: ${m_section}
Architecture: any
$(debian_wrap "Depends: \${shlibs:Depends}, \${misc:Depends}, freeswitch, ${depends}")
$(debian_wrap "Recommends: ${recommends}")
@ -482,7 +494,6 @@ EOF
print_mod_install () {
cat <<EOF
/usr/lib/freeswitch/mod/${1}.la
/usr/lib/freeswitch/mod/${1}.so
EOF
}
@ -508,6 +519,15 @@ ${p}: possible-gpl-code-linked-with-openssl
EOF
}
print_itp_override () {
local p="$1"
cat <<EOF
# We're not in Debian (yet) so we don't have an ITP bug to close.
${p}: new-package-should-close-itp-bug
EOF
}
print_common_overrides () {
print_long_filename_override "$1"
}
@ -521,14 +541,6 @@ print_conf_overrides () {
print_common_overrides "$1"
}
print_sound_overrides () {
print_common_overrides "$1"
}
print_music_overrides () {
print_common_overrides "$1"
}
print_conf_control () {
cat <<EOF
Package: freeswitch-conf-${conf//_/-}
@ -548,46 +560,6 @@ conf/${conf} /usr/share/freeswitch/conf
EOF
}
print_music_control () {
cat <<EOF
Package: freeswitch-music-default-${rate_k}
Architecture: all
Depends: \${misc:Depends}
Description: Music on hold audio for FreeSWITCH
$(debian_wrap "${fs_description}")
.
This package contains the default music on hold audio for FreeSWITCH
at a sampling rate of ${rate}Hz.
EOF
}
print_music_install () {
cat <<EOF
/usr/share/freeswitch/sounds/music/${rate}
EOF
}
print_sound_control () {
cat <<EOF
Package: freeswitch-sounds-${sound//\//-}-${rate_k}
Architecture: all
Depends: \${misc:Depends}
Description: ${sound} sounds for FreeSWITCH
$(debian_wrap "${fs_description}")
.
This package contains the ${sound} sounds for FreeSWITCH at a
sampling rate of ${rate}Hz.
EOF
}
print_sound_install () {
cat <<EOF
/usr/share/freeswitch/sounds/${sound_path}/*/${rate}
EOF
}
print_edit_warning () {
echo "#### Do not edit! This file is auto-generated from debian/bootstrap.sh."; echo
}
@ -631,41 +603,18 @@ genconf () {
test -f $f.tmpl && cat $f.tmpl >> $f
}
genmusic () {
rate="$1" rate_k="${rate%%000}k"
print_music_control >> control
local p=freeswitch-music-default-${rate_k}
local f=$p.install
(print_edit_warning; print_music_install) > $f
test -f $f.tmpl && cat $f.tmpl >> $f
local f=$p.lintian-overrides
(print_edit_warning; print_music_overrides "$p") > $f
test -f $f.tmpl && cat $f.tmpl >> $f
unset rate rate_k
}
gensound () {
rate="$1" rate_k="${rate%%000}k" sound_path="$2" sound="${2,,}"
language=$(echo $sound | cut -d/ -f1)
country=$(echo $sound | cut -d/ -f2)
speaker=$(echo $sound | cut -d/ -f3)
print_sound_control >> control
local p=freeswitch-sounds-${sound//\//-}-${rate_k}
local f=$p.install
(print_edit_warning; print_sound_install) > $f
test -f $f.tmpl && cat $f.tmpl >> $f
local f=$p.lintian-overrides
(print_edit_warning; print_sound_overrides "$p") > $f
test -f $f.tmpl && cat $f.tmpl >> $f
unset rate rate_k sound sound_path language country speaker
}
accumulate_build_depends () {
if [ -n "$build_depends" ]; then
local x=""
if [ -n "$(eval echo \$build_depends_$codename)" ]; then
x="$(eval echo \$build_depends_$codename)"
else
x="${build_depends}"
fi
if [ -n "$x" ]; then
if [ ! "$mod_build_depends" = "." ]; then
mod_build_depends="${mod_build_depends}, ${build_depends}"
mod_build_depends="${mod_build_depends}, ${x}"
else
mod_build_depends="${build_depends}"
mod_build_depends="${x}"
fi
fi
}
@ -775,12 +724,17 @@ genmodctl_cat () {
genmodctl_mod () {
echo "Module: $module"
[ -n "$section" ] && echo "Section: $section"
echo "Description: $description"
echo "$long_description" | fold -s -w 69 | while xread l; do
local v="$(echo "$l" | sed -e 's/ *$//g')"
echo " $v"
done
[ -n "$build_depends" ] && debian_wrap "Build-Depends: $build_depends"
for x in $supported_distros; do
[ -n "$(eval echo \$build_depends_$x)" ] \
&& debian_wrap "Build-Depends-$x: $(eval echo \$build_depends_$x)"
done
[ -n "$depends" ] && debian_wrap "Depends: $depends"
[ -n "$reccomends" ] && debian_wrap "Recommends: $recommends"
[ -n "$suggests" ] && debian_wrap "Suggests: $suggests"
@ -788,42 +742,68 @@ genmodctl_mod () {
echo
}
codename="sid"
while getopts "c:" o; do
case "$o" in
c) codename="$OPTARG" ;;
esac
done
shift $(($OPTIND-1))
echo "Bootstrapping debian/ for ${codename}" >&2
echo >&2
echo "Please wait, this takes a few seconds..." >&2
echo "Adding any new modules to control-modules..." >&2
parse_dir=control-modules.parse
map_fs_modules ':' 'genmodctl_new_cat' 'genmodctl_new_mod' >> control-modules
echo "Parsing control-modules..." >&2
parse_mod_control
(echo "# -*- mode:debian-control -*-"; echo; \
echo "Displaying includes/excludes..." >&2
map_modules 'mod_filter_show' '' ''
echo "Generating control-modules.gen as sanity check..." >&2
(echo "# -*- mode:debian-control -*-"; \
echo "##### Author: Travis Cross <tc@traviscross.com>"; echo; \
map_modules ':' 'genmodctl_cat' 'genmodctl_mod' \
) > control-modules.gen
print_edit_warning > modules_.conf
echo "Accumulating build dependencies from modules..." >&2
map_modules 'mod_filter' '' 'accumulate_build_depends'
echo "Generating debian/..." >&2
> control
(print_edit_warning; print_source_control; print_core_control) >> control
for r in 8000 16000 32000 48000; do genmusic $r; done
for x in 'en/us/callie'; do
for r in 8000 16000 32000 48000; do
gensound $r $x
done
done
echo "Generating debian/ (conf)..." >&2
(echo "### conf"; echo) >> control
map_confs 'genconf'
echo "Generating debian/ (modules)..." >&2
(echo "### modules"; echo) >> control
print_edit_warning > modules_.conf
map_modules "mod_filter" \
"gencontrol_per_cat genmodules_per_cat" \
"gencontrol_per_mod geninstall_per_mod genoverrides_per_mod genmodules_per_mod"
echo "Generating additional lintian overrides..." >&2
grep -e '^Package:' control | while xread l; do
m="${l#*: }"
f=$m.lintian-overrides
if [ ! -s $f ] || ! grep -e 'package-has-long-file-name' $f >/dev/null; then
[ -s $f ] || print_edit_warning >> $f
[ -s $f ] || print_edit_warning >> $f
if ! grep -e 'package-has-long-file-name' $f >/dev/null; then
print_long_filename_override "$m" >> $f
fi
if ! grep -e 'new-package-should-close-itp-bug' $f >/dev/null; then
print_itp_override "$m" >> $f
fi
done
for p in freeswitch libfreeswitch1; do
f=$p.lintian-overrides
[ -s $f ] || print_edit_warning >> $f
print_gpl_openssl_override "$p" >> $f
done
f=freeswitch.lintian-overrides
[ -s $f ] || print_edit_warning >> $f
print_gpl_openssl_override "freeswitch" >> $f
echo "Cleaning up..." >&2
rm -f control-modules.preparse
rm -rf control-modules.parse
diff control-modules control-modules.gen >/dev/null && rm -f control-modules.gen
echo "Done bootstrapping debian/" >&2
touch .stamp-bootstrap

7
debian/changelog vendored
View File

@ -1,3 +1,10 @@
freeswitch (1.2~rc2-1) unstable; urgency=low
* Bump version.
* Sounds and music have been moved to their own source packaging.
-- Travis Cross <tc@traviscross.com> Thu, 24 May 2012 15:15:10 +0000
freeswitch (1.2~alpha1-1) unstable; urgency=low
* Initial release of FreeSWITCH in new debian packaging.

View File

@ -114,6 +114,8 @@ Description: HTTP GET with caching
Module: applications/mod_ladspa
Description: LADSPA
This module provides an API for accessing LADSPA plugins.
Build-Depends: ladspa-sdk
Suggests: tap-plugins, swh-plugins, autotalent
Module: applications/mod_lcr
Description: LCR
@ -133,13 +135,12 @@ Description: MongoDB
This module provides an interface to MongoDB.
Build-Depends: scons, libboost-dev, libboost-system-dev,
libboost-date-time-dev, libboost-thread-dev, libboost-filesystem-dev
Depends: libicu44, libboost-system1.42.0, libboost-date-time1.42.0,
libboost-serialization1.42.0, libboost-thread1.42.0,
libboost-filesystem1.42.0
Module: applications/mod_mp4
Section: contrib/comm
Description: MP4 video support
This module adds support for MP4 video playback.
Build-Depends: libmp4v2-dev
Module: applications/mod_nibblebill
Description: Nibblebill
@ -149,11 +150,17 @@ Description: Nibblebill
Module: applications/mod_osp
Description: Open Settlement Protocol
This module adds support for the Open Settlement Protocol (OSP).
Build-Depends: libosptk3-dev
Module: applications/mod_rad_auth
Description: RADIUS AA
This module implements RADIUS Authentication and Authorization.
Module: applications/mod_random
Description: Entropy extraction
This module extracts entropy from FreeSWITCH and feeds it into
/dev/random.
Module: applications/mod_redis
Description: Redis limit backend
This module provides a mechanism to use Redis as a backend data
@ -282,6 +289,7 @@ Description: mod_h26x
Adds mod_h26x.
Module: codecs/mod_ilbc
Section: non-free/comm
Description: mod_ilbc
Adds mod_ilbc.
@ -306,6 +314,7 @@ Description: mod_silk
Adds mod_silk.
Module: codecs/mod_siren
Section: non-free/comm
Description: mod_siren
Adds mod_siren.
@ -317,7 +326,6 @@ Module: codecs/mod_speex
Description: mod_speex
Adds mod_speex.
Build-Depends: libogg-dev
Depends: libogg0
Module: codecs/mod_theora
Description: mod_theora
@ -353,7 +361,6 @@ Module: endpoints/mod_alsa
Description: mod_alsa
Adds mod_alsa.
Build-Depends: libasound2-dev
Depends: libasound2
Module: endpoints/mod_dingaling
Description: mod_dingaling
@ -362,10 +369,12 @@ Description: mod_dingaling
Module: endpoints/mod_gsmopen
Description: mod_gsmopen
Adds mod_gsmopen.
Build-Depends: libx11-dev
Module: endpoints/mod_h323
Description: mod_h323
Adds mod_h323.
Build-Depends: libopenh323-dev, libpt-dev
Module: endpoints/mod_khomp
Description: mod_khomp
@ -399,7 +408,6 @@ Module: endpoints/mod_skypopen
Description: mod_skypopen
Adds mod_skypopen.
Build-Depends: libx11-dev
Depends: libpthread-stubs0
Module: endpoints/mod_sofia
Description: mod_sofia
@ -423,7 +431,6 @@ Module: event_handlers/mod_cdr_pg_csv
Description: mod_cdr_pg_csv
Adds mod_cdr_pg_csv.
Build-Depends: libpq-dev
Depends: libpq5
Module: event_handlers/mod_cdr_sqlite
Description: mod_cdr_sqlite
@ -432,10 +439,12 @@ Description: mod_cdr_sqlite
Module: event_handlers/mod_erlang_event
Description: mod_erlang_event
Adds mod_erlang_event.
Build-Depends: erlang-dev
Module: event_handlers/mod_event_multicast
Description: mod_event_multicast
Adds mod_event_multicast.
Build-Depends: libssl-dev
Module: event_handlers/mod_event_socket
Description: mod_event_socket
@ -460,6 +469,7 @@ Description: mod_radius_cdr
Module: event_handlers/mod_snmp
Description: mod_snmp
Adds mod_snmp.
Build-Depends: libsnmp-dev
## mod/formats
@ -483,8 +493,6 @@ Module: formats/mod_shout
Description: mod_shout
Adds mod_shout.
Build-Depends: libogg-dev, libvorbis-dev
Depends: libogg0, libvorbis0a, libvorbisenc2, libvorbisfile3,
libvorbisidec1
Module: formats/mod_sndfile
Description: mod_sndfile
@ -498,7 +506,6 @@ Module: formats/mod_vlc
Description: VLC streaming
This module provides VLC streaming.
Build-Depends: libvlc-dev (>= 2.0.0)
Depends: libvlc5
Distro-Conflicts: squeeze
## mod/languages
@ -506,6 +513,7 @@ Distro-Conflicts: squeeze
Module: languages/mod_java
Description: mod_java
Adds mod_java.
Build-Depends: default-jdk, gcj-jdk
Module: languages/mod_lua
Description: mod_lua
@ -514,24 +522,27 @@ Description: mod_lua
Module: languages/mod_managed
Description: mod_managed
Adds mod_managed.
Build-Depends: libmono-2.0-dev, mono-gmcs
Module: languages/mod_perl
Description: mod_perl
Adds mod_perl.
Build-Depends: libperl-dev
Depends: libperl5.10
Module: languages/mod_python
Description: mod_python
Adds mod_python.
Build-Depends: python-dev
Module: languages/mod_spidermonkey
Description: mod_spidermonkey
Adds mod_spidermonkey.
Build-Depends: unixodbc-dev
Module: languages/mod_yaml
Description: mod_yaml
Adds mod_yaml.
Build-Depends: libyaml-dev
## mod/loggers
@ -561,6 +572,10 @@ Module: say/mod_say_es
Description: mod_say_es
Adds mod_say_es.
Module: say/mod_say_fa
Description: mod_say_fa
Adds mod_say_fa.
Module: say/mod_say_fr
Description: mod_say_fr
Adds mod_say_fr.
@ -635,9 +650,12 @@ Module: xml_int/mod_xml_ldap
Description: mod_xml_ldap
Adds mod_xml_ldap.
Build-Depends: libsasl2-dev
Depends: libsasl2-modules
Module: xml_int/mod_xml_rpc
Description: mod_xml_rpc
Adds mod_xml_rpc.
Module: xml_int/mod_xml_scgi
Description: mod_xml_scgi
Adds mod_xml_scgi.

1022
debian/copyright vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +0,0 @@
/usr/share/freeswitch/htdocs/license.txt
/usr/share/freeswitch/htdocs/slim.swf
/usr/share/freeswitch/htdocs/slimtest.htm

View File

@ -0,0 +1 @@
/usr/share/freeswitch/scripts/freeswitch.jar

View File

@ -1,3 +1 @@
/usr/bin
/usr/lib/libfreeswitch.so.*
/usr/share/freeswitch/scripts

1
debian/gbp.conf vendored
View File

@ -7,7 +7,6 @@ upstream-branch=master
debian-branch=master
upstream-tree=branch
tag=False
force-create=True
compression=xz
compression-level=9ev
builder=debuild --prepend-path=/usr/lib/ccache -eFS_* -eCCACHE_* -i\.git -I.git -Zxz -z9

View File

@ -1,6 +1,4 @@
/usr/include
/usr/lib/freeswitch/mod/*.la
/usr/lib/libfreeswitch.so
/usr/lib/*.a
/usr/lib/*.la
/usr/lib/pkgconfig

1
debian/libfreeswitch1.install vendored Normal file
View File

@ -0,0 +1 @@
/usr/lib/libfreeswitch.so.*

16
debian/rules vendored
View File

@ -1,11 +1,12 @@
#!/usr/bin/make -f
# -*- mode:makefile -*-
##### Author: Travis Cross <tc@traviscross.com>
#export DH_VERBOSE=1
FS_CFLAGS?=-ggdb3 -O2
FS_CPPFLAGS?=
FS_CXXFLAGS?=$(FS_CFLAGS)
FS_INSTALL_SOUNDS?=true
export PATH?=/usr/lib/ccache:/usr/sbin:/usr/bin:/sbin:/bin
export CFLAGS=$(FS_CFLAGS)
export CPPFLAGS=$(FS_CPPFLAGS)
@ -18,7 +19,6 @@ show_vars= \
echo "CFLAGS='$(CFLAGS)'"; \
echo "CXXFLAGS='$(CXXFLAGS)'"; \
echo "CCACHE_DIR='$(CCACHE_DIR)'"; \
echo "FS_INSTALL_SOUNDS='$(FS_INSTALL_SOUNDS)'"; \
echo;
binary:
@ -88,9 +88,9 @@ override_dh_strip:
override_dh_auto_install:
dh_auto_install
-$(FS_INSTALL_SOUNDS) && DESTDIR=debian/tmp make cd-sounds-install cd-moh-install
mkdir -p debian/tmp/lib/systemd/system
install -m0644 debian/freeswitch-systemd.freeswitch.service debian/tmp/lib/systemd/system/freeswitch.service
rm -f debian/tmp/usr/share/freeswitch/grammar/model/communicator/COPYING
override_dh_installinit:
dh_installinit -pfreeswitch-sysvinit --name=freeswitch
@ -115,13 +115,5 @@ binary-quicktest:
@$(call show_vars)
echo "applications/mod_commands" > debian/modules.conf
(cd debian && ./bootstrap.sh)
env FS_INSTALL_SOUNDS=false dh binary \
-Nfreeswitch-sounds-music-8k \
-Nfreeswitch-sounds-music-16k \
-Nfreeswitch-sounds-music-32k \
-Nfreeswitch-sounds-music-48k \
-Nfreeswitch-sounds-en-us-callie-8k \
-Nfreeswitch-sounds-en-us-callie-16k \
-Nfreeswitch-sounds-en-us-callie-32k \
-Nfreeswitch-sounds-en-us-callie-48k
dh binary

342
debian/util.sh vendored
View File

@ -2,14 +2,29 @@
##### -*- mode:shell-script; indent-tabs-mode:nil; sh-basic-offset:2 -*-
##### Author: Travis Cross <tc@traviscross.com>
set -e
ddir="."
[ -n "${0%/*}" ] && ddir="${0%/*}"
cd $ddir/../
#### lib
err () {
echo "$0 error: $1" >&2
exit 1
}
announce () {
cat >&2 <<EOF
########################################################################
## $1
########################################################################
EOF
}
xread () {
local xIFS="$IFS"
IFS=''
@ -19,6 +34,35 @@ xread () {
return $ret
}
mk_dver () { echo "$1" | sed -e 's/-/~/g'; }
mk_uver () { echo "$1" | sed -e 's/-.*$//' -e 's/~/-/'; }
dsc_source () { dpkg-parsechangelog | grep '^Source:' | awk '{print $2}'; }
dsc_ver () { dpkg-parsechangelog | grep '^Version:' | awk '{print $2}'; }
up_ver () { mk_uver "$(dsc_ver)"; }
dsc_base () { echo "$(dsc_source)_$(dsc_ver)"; }
up_base () { echo "$(dsc_source)-$(up_ver)"; }
find_distro () {
case "$1" in
experimental) echo "sid";;
unstable) echo "sid";;
testing) echo "wheezy";;
stable) echo "squeeze";;
*) echo "$1";;
esac
}
find_suite () {
case "$1" in
sid) echo "unstable";;
wheezy) echo "testing";;
squeeze) echo "stable";;
*) echo "$1";;
esac
}
#### debian/rules helpers
create_dbg_pkgs () {
for x in $ddir/*; do
test ! -d $x && continue
@ -30,51 +74,275 @@ create_dbg_pkgs () {
done
}
list_build_depends () {
test -f $ddir/.stamp-bootstrap || (cd $ddir && ./bootstrap.sh)
local deps="" found=false
while xread l; do
if [ "${l%%:*}" = "Build-Depends" ]; then
deps="${l#*:}"
found=true
continue
elif $found; then
if [ -z "$l" ]; then
# is newline
break
elif [ -z "${l##\#*}" ]; then
# is comment
continue
elif [ -z "${l## *}" ]; then
# is continuation line
deps="$deps $(echo "$l" | sed -e 's/^ *//' -e 's/ *([^)]*)//g' -e 's/,//g')"
else
# is a new header
break
fi
cwget () {
local url="$1" f="${1##*/}"
echo "fetching: $url to $f" >&2
if [ -n "$FS_FILES_DIR" ]; then
if ! [ -s "$FS_FILES_DIR/$f" ]; then
(cd $FS_FILES_DIR && wget -N "$url")
fi
done < $ddir/control
echo "${deps# }"
cp -a $FS_FILES_DIR/$f .
else
wget -N "$url"
fi
}
install_build_depends () {
local apt=""
if [ -n "$(which aptitude)" ]; then
apt=$(which aptitude)
elif [ -n "$(which apt-get)" ]; then
apt=$(which apt-get)
else
err "Can't find apt-get or aptitude; are you running on debian?"
fi
$apt install -y $(list_build_depends)
touch $ddir/.stamp-build-depends
getlib () {
local url="$1" f="${1##*/}"
cwget "$url"
tar -xv --no-same-owner --no-same-permissions -f "$f"
rm -f "$f" && mkdir -p $f && touch $f/.download-stamp
}
getlibs () {
# get pinned libraries
getlib http://downloads.mongodb.org/cxx-driver/mongodb-linux-x86_64-v1.8-latest.tgz
getlib http://files.freeswitch.org/downloads/libs/json-c-0.9.tar.gz
getlib http://files.freeswitch.org/downloads/libs/libmemcached-0.32.tar.gz
getlib http://files.freeswitch.org/downloads/libs/soundtouch-1.6.0.tar.gz
getlib http://files.freeswitch.org/downloads/libs/flite-1.5.4-current.tar.bz2
getlib http://files.freeswitch.org/downloads/libs/sphinxbase-0.7.tar.gz
getlib http://files.freeswitch.org/downloads/libs/pocketsphinx-0.7.tar.gz
getlib http://files.freeswitch.org/downloads/libs/communicator_semi_6000_20080321.tar.gz
getlib http://files.freeswitch.org/downloads/libs/celt-0.10.0.tar.gz
getlib http://files.freeswitch.org/downloads/libs/opus-0.9.0.tar.gz
getlib http://files.freeswitch.org/downloads/libs/openldap-2.4.19.tar.gz
getlib http://download.zeromq.org/zeromq-2.1.9.tar.gz \
|| getlib http://download.zeromq.org/historic/zeromq-2.1.9.tar.gz
getlib http://files.freeswitch.org/downloads/libs/freeradius-client-1.1.6.tar.gz
getlib http://files.freeswitch.org/downloads/libs/lame-3.98.4.tar.gz
getlib http://files.freeswitch.org/downloads/libs/libshout-2.2.2.tar.gz
getlib http://files.freeswitch.org/downloads/libs/mpg123-1.13.2.tar.gz
# cleanup mongo
(
cd mongo-cxx-driver-v1.8
rm -rf config.log .sconf_temp *Test *Example
find . -name "*.o" -exec rm -f {} \;
)
}
check_repo_clean () {
git diff-index --quiet --cached HEAD \
|| err "uncommitted changes present"
git diff-files --quiet \
|| err "unclean working tree"
git diff-index --quiet HEAD \
|| err "unclean repository"
! git ls-files --other --error-unmatch . >/dev/null 2>&1 \
|| err "untracked files or build products present"
}
create_orig () {
{
set -e
local OPTIND OPTARG
local uver="" bundle_deps=false zl=9e
while getopts 'bnv:z:' o "$@"; do
case "$o" in
b) bundle_deps=true;;
n) uver="nightly";;
v) uver="$OPTARG";;
z) zl="$OPTARG";;
esac
done
shift $(($OPTIND-1))
[ -z "$uver" ] || [ "$uver" = "nightly" ] \
&& uver="$(cat build/next-release.txt)-n$(date +%Y%m%dT%H%M%SZ)"
local treeish="$1" dver="$(mk_dver "$uver")"
local orig="../freeswitch_$dver.orig.tar.xz"
[ -n "$treeish" ] || treeish="HEAD"
check_repo_clean
git reset --hard "$treeish"
mv .gitattributes .gitattributes.orig
grep .gitattributes.orig \
-e '\bdebian-ignore\b' \
-e '\bdfsg-nonfree\b' \
| while xread l; do
echo "$l export-ignore" >> .gitattributes
done
if $bundle_deps; then
(cd libs && getlibs)
git add -f libs
fi
./build/set-fs-version.sh "$uver" && git add configure.in
git commit --allow-empty -m "nightly v$uver"
git archive -v \
--worktree-attributes \
--format=tar \
--prefix=freeswitch-$uver/ \
HEAD \
| xz -c -${zl}v > $orig
mv .gitattributes.orig .gitattributes
git reset --hard HEAD^ && git clean -fdx
} 1>&2
echo $orig
}
set_modules_quicktest () {
cat > debian/modules.conf <<EOF
applications/mod_commands
EOF
}
create_dsc () {
{
set -e
local OPTIND OPTARG modules_list="" speed="normal"
while getopts 'm:s:' o "$@"; do
case "$o" in
m) modules_list="$OPTARG";;
s) speed="$OPTARG";;
esac
done
shift $(($OPTIND-1))
local distro="$(find_distro $1)" orig="$2"
local suite="$(find_suite $distro)"
local orig_ver="$(echo "$orig" | sed -e 's/^.*_//' -e 's/\.orig\.tar.*$//')"
local dver="${orig_ver}-1~${distro}+1"
[ -x "$(which dch)" ] \
|| err "package devscripts isn't installed"
if [ -n "$modules_list" ]; then
set_modules_${modules_list}
fi
(cd debian && ./bootstrap.sh -c $distro)
case "$speed" in
paranoid) sed -i ./debian/rules \
-e '/\.stamp-bootstrap:/{:l2 n; /\.\/bootstrap.sh -j/{s/ -j//; :l3 n; b l3}; b l2};' ;;
reckless) sed -i ./debian/rules \
-e '/\.stamp-build:/{:l2 n; /make/{s/$/ -j/; :l3 n; b l3}; b l2};' ;;
esac
git add debian/rules
dch -b -m -v "$dver" --force-distribution -D "$suite" "Nightly build."
git add debian/changelog && git commit -m "nightly v$orig_ver"
dpkg-source -i.* -Zxz -z9 -b .
dpkg-genchanges -S > ../$(dsc_base)_source.changes
local dsc="../$(dsc_base).dsc"
git reset --hard HEAD^ && git clean -fdx
} 1>&2
echo $dsc
}
fmt_debug_hook () {
cat <<'EOF'
#!/bin/bash
export debian_chroot="cow"
cd /tmp/buildd/*/debian/..
/bin/bash < /dev/tty > /dev/tty 2> /dev/tty
EOF
}
build_debs () {
{
set -e
local OPTIND OPTARG debug_hook=false hookdir=""
while getopts 'd' o "$@"; do
case "$o" in
d) debug_hook=true;;
esac
done
shift $(($OPTIND-1))
local distro="$(find_distro $1)" dsc="$2" arch="$3"
if [ -z "$distro" ] || [ "$distro" = "auto" ]; then
if ! (echo "$dsc" | grep -e '-[0-9]*~[a-z]*+[0-9]*'); then
err "no distro specified or found"
fi
local x="$(echo $dsc | sed -e 's/^[^-]*-[0-9]*~//' -e 's/+[^+]*$//')"
distro="$(find_distro $x)"
fi
[ -n "$arch" ] || arch="$(dpkg-architecture | grep '^DEB_BUILD_ARCH=' | cut -d'=' -f2)"
[ -x "$(which cowbuilder)" ] \
|| err "package cowbuilder isn't installed"
local cow_img=/var/cache/pbuilder/base-$distro-$arch.cow
cow () {
cowbuilder "$@" \
--distribution $distro \
--architecture $arch \
--basepath $cow_img
}
if ! [ -d $cow_img ]; then
announce "Creating base $distro-$arch image..."
cow --create
fi
announce "Updating base $distro-$arch image..."
cow --update
announce "Building $distro-$arch DEBs from $dsc..."
if $debug_hook; then
mkdir -p .hooks
fmt_debug_hook > .hooks/C10shell
chmod +x .hooks/C10shell
hookdir=$(pwd)/.hooks
fi
cow --build $dsc \
--hookdir "$hookdir" \
--buildresult ../
} 1>&2
echo ${dsc}_${arch}.changes
}
build_all () {
local OPTIND OPTARG
local orig_opts="" dsc_opts="" deb_opts=""
local archs="" distros="" par=false
while getopts 'a:bc:djnm:s:v:z:' o "$@"; do
case "$o" in
a) archs="$archs $OPTARG";;
b) orig_opts="$orig_opts -b";;
c) distros="$distros $OPTARG";;
d) deb_opts="$deb_opts -d";;
j) par=true;;
n) orig_opts="$orig_opts -n";;
m) dsc_opts="$dsc_opts -m$OPTARG";;
s) dsc_opts="$dsc_opts -s$OPTARG";;
v) orig_opts="$orig_opts -v$OPTARG";;
z) orig_opts="$orig_opts -z$OPTARG";;
esac
done
shift $(($OPTIND-1))
[ -n "$archs" ] || archs="amd64 i386"
[ -n "$distros" ] || distros="sid wheezy squeeze"
local orig="$(create_orig $orig_opts HEAD | tail -n1)"
mkdir -p ../log
> ../log/changes
echo; echo; echo; echo
if [ "${orig:0:2}" = ".." ]; then
for distro in $distros; do
echo "Creating $distro dsc..." >&2
local dsc="$(create_dsc $dsc_opts $distro $orig 2>../log/$distro | tail -n1)"
echo "Done creating $distro dsc." >&2
if [ "${dsc:0:2}" = ".." ]; then
for arch in $archs; do
{
echo "Building $distro-$arch debs..." >&2
local changes="$(build_debs $deb_opts $distro $dsc $arch 2>../log/$distro-$arch | tail -n1)"
echo "Done building $distro-$arch debs." >&2
if [ "${changes:0:2}" = ".." ]; then
echo "$changes" >> ../log/changes
fi
} &
$par || wait
done
fi
done
! $par || wait
fi
cat ../log/changes
}
while getopts 'd' o "$@"; do
case "$o" in
d) set -vx;;
esac
done
shift $(($OPTIND-1))
cmd="$1"
shift
case "$cmd" in
archive-orig) archive_orig "$@" ;;
build-all) build_all "$@" ;;
build-debs) build_debs "$@" ;;
create-dbg-pkgs) create_dbg_pkgs ;;
list-build-depends) list_build_depends ;;
install-build-depends) install_build_depends ;;
create-dsc) create_dsc "$@" ;;
create-orig) create_orig "$@" ;;
esac

View File

@ -1,3 +1,18 @@
freeswitch (1.2.0)
config: add screen_confirm macro to lang/en/ivr/sounds.xml (r:9ea3ce66)
config: support for --with-logfilesdir, --with-dbdir, --with-htdocsdir, --with-soundsdir, --with-grammardir, --with-scriptdir and --with-recordin
gsdir (r:7ae3f5b7/FS-302)
core: Add RECORD_STEREO_SWAP to reverse the record channels (r:d5042f2c/FS-3069)
core: api_on_startup (r:e164b76c)
mod_conference: Add auto-record filename to conference_recording channel variable and ability to pull filename from API (r:b9295fd5/FS-1573)
mod_conference: Convenience feature in mod_conference: apply sub cmds to non_moderator members (r:04295ac9/FS-3249)
mod_conference: New conference commands: get and set (r:ab5f3f28/FS-3254)
mod_commands: allow system API command to capture output from the executed command (r:d7a37e97)
mod_posix_timer: New timer module mod_posix_timer (r:9d7e9e67/FS-3731)
mod_sofia: Add presence-privacy parameter to exclude extension numbers from the distributed presence string (r:c6633fa3/FS-849)
mod_spandsp: Add T31 modem support to mod_spandsp - similar to iaxmodem only wired into FS. Also merge configs into single spandsp.conf.xml --see in tree example-- (r:d91f67d0)
mod_valet_parking: add orbit feature to valet_parking similar to mod_fifo (r:09725e2b)
freeswitch (1.0.7)
build: Add mod_silk to windows build

View File

@ -77,6 +77,7 @@ BuildArch: noarch
BuildRequires: sox
Requires: freeswitch
Requires: freeswitch-sounds-en-us-callie-48000
Requires: sox
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
%description

View File

@ -1,3 +1,4 @@
%define fsname freeswitch
%define PREFIX %{_prefix}
%define EXECPREFIX %{_exec_prefix}
%define BINDIR %{_bindir}

View File

@ -15,13 +15,13 @@
# This file and all modifications and additions to the pristine package are under the same license as the package itself.
#
# Contributor(s): Mike Jerris
# Brian West
# Raul Fragoso
# Rupa Shomaker
# Marc Olivier Chouinard
# Raymond Chandler
# Anthony Minessale II <anthm@freeswitch.org>
#
# Brian West
# Anthony Minessale II <anthm@freeswitch.org>
# Raul Fragoso
# Rupa Shomaker
# Marc Olivier Chouinard
# Raymond Chandler
# Ken Rice <krice@freeswitch.org>
#
# Maintainer(s): Ken Rice <krice@freeswitch.org>
#
@ -1433,7 +1433,7 @@ export ACLOCAL_FLAGS="-I /usr/share/aclocal"
if test ! -f Makefile.in
then
./bootstrap.sh -j
./bootstrap.sh
fi
%configure -C \
@ -1593,6 +1593,7 @@ fi
#################################### Basic Directory Structure #######################################################
#
%dir %attr(0750, freeswitch, daemon) %{sysconfdir}
%dir %attr(0750, freeswitch, daemon) %{LOCALSTATEDIR}
%dir %attr(0750, freeswitch, daemon) %{DBDIR}
%dir %attr(0750, freeswitch, daemon) %{GRAMMARDIR}
%dir %attr(0750, freeswitch, daemon) %{HTDOCSDIR}
@ -1756,6 +1757,7 @@ fi
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/xml_cdr.conf.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/xml_curl.conf.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/xml_rpc.conf.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/xml_scgi.conf.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/zeroconf.conf.xml
######################################################################################################################
# Chatplans

View File

@ -9,6 +9,7 @@
#include <getopt.h>
#define CMD_BUFLEN 1024
#define PROMPT_PREFIX "netborder-ss7"
#ifndef WIN32
#include <sys/select.h>
@ -902,30 +903,19 @@ static const char *basic_gets(int *cnt)
return command_buf;
}
static const char *banner =
" _____ ____ ____ _ ___ \n"
" | ___/ ___| / ___| | |_ _| \n"
" | |_ \\___ \\ | | | | | | \n"
" | _| ___) | | |___| |___ | | \n"
" |_| |____/ \\____|_____|___| \n"
"\n"
"*******************************************************\n"
"* Anthony Minessale II, Ken Rice, *\n"
"* Michael Jerris, Travis Cross *\n"
"* FreeSWITCH (http://www.freeswitch.org) *\n"
"* Paypal Donations Appreciated: paypal@freeswitch.org *\n"
"* Brought to you by ClueCon http://www.cluecon.com/ *\n"
"*******************************************************\n"
"\n"
"Type /help <enter> to see a list of commands\n\n\n";
static void print_banner(FILE *stream)
{
#ifndef WIN32
fprintf(stream, "%s%s", output_text_color, banner);
#else
fprintf(stream, "%s", banner);
#endif
fprintf(stream,
"\n"
"*******************************************************\n"
"* Netborder SS7 Gateway *\n"
"* Powered by FreeSWITCH (http://www.freeswitch.org) *\n"
"*******************************************************\n"
"\n"
"Type /help <enter> to see a list of commands\n\n\n"
);
}
static void set_fn_keys(cli_profile_t *profile)
@ -1152,13 +1142,13 @@ int main(int argc, char *argv[])
char cmd_str[1024] = "";
cli_profile_t *profile = NULL;
#ifndef WIN32
char hfile[512] = "/tmp/fs_cli_history";
char cfile[512] = "/etc/fs_cli.conf";
char dft_cfile[512] = "/etc/fs_cli.conf";
char hfile[512] = "/etc/nbess7_cli_history";
char cfile[512] = "/etc/nbess7_cli.conf";
char dft_cfile[512] = "/etc/nbess7_cli.conf";
#else
char hfile[512] = "fs_cli_history";
char cfile[512] = "fs_cli.conf";
char dft_cfile[512] = "fs_cli.conf";
char hfile[512] = "nbess7_cli_history";
char cfile[512] = "nbess7_cli.conf";
char dft_cfile[512] = "nbess7_cli.conf";
#endif
char *home = getenv("HOME");
/* Vars for optargs */
@ -1203,18 +1193,19 @@ int main(int argc, char *argv[])
#else
feature_level = 1;
#endif
feature_level = 0;
strncpy(internal_profile.host, "127.0.0.1", sizeof(internal_profile.host));
strncpy(internal_profile.pass, "ClueCon", sizeof(internal_profile.pass));
strncpy(internal_profile.name, "internal", sizeof(internal_profile.name));
internal_profile.port = 8021;
internal_profile.port = 8821;
set_fn_keys(&internal_profile);
esl_set_string(internal_profile.prompt_color, prompt_color);
esl_set_string(internal_profile.input_text_color, input_text_color);
esl_set_string(internal_profile.output_text_color, output_text_color);
if (home) {
snprintf(hfile, sizeof(hfile), "%s/.fs_cli_history", home);
snprintf(cfile, sizeof(cfile), "%s/.fs_cli_conf", home);
snprintf(hfile, sizeof(hfile), "%s/.nbess7_cli_history", home);
snprintf(cfile, sizeof(cfile), "%s/.nbess7_cli_conf", home);
}
signal(SIGINT, handle_SIGINT);
#ifdef SIGTSTP
@ -1335,20 +1326,24 @@ int main(int argc, char *argv[])
esl_set_string(input_text_color, profile->input_text_color);
esl_set_string(output_text_color, profile->output_text_color);
if (argv_host) {
if (argv_port && profile->port != 8021) {
snprintf(bare_prompt_str, sizeof(bare_prompt_str), "freeswitch@%s:%u@%s> ", profile->host, profile->port, profile->name);
if (argv_port && profile->port != 8821) {
snprintf(prompt_str, sizeof(prompt_str), PROMPT_PREFIX "@%s:%u@%s> ", profile->host, profile->port, profile->name);
} else {
snprintf(bare_prompt_str, sizeof(bare_prompt_str), "freeswitch@%s@%s> ", profile->host, profile->name);
snprintf(prompt_str, sizeof(prompt_str), PROMPT_PREFIX "@%s@%s> ", profile->host, profile->name);
}
} else {
snprintf(bare_prompt_str, sizeof(bare_prompt_str), "freeswitch@%s> ", profile->name);
snprintf(prompt_str, sizeof(prompt_str), PROMPT_PREFIX "@%s> ", profile->name);
}
bare_prompt_str_len = (int)strlen(bare_prompt_str);
if (feature_level) {
snprintf(prompt_str, sizeof(prompt_str), "%s%s%s", prompt_color, bare_prompt_str, input_text_color);
} else {
}
/*
else {
snprintf(prompt_str, sizeof(prompt_str), "%s", bare_prompt_str);
}
}
*/
connect:
connected = 0;
while (--loops > 0) {
@ -1470,8 +1465,10 @@ int main(int argc, char *argv[])
setvbuf(stdout, (char*)NULL, _IONBF, 0);
}
print_banner(stdout);
esl_log(ESL_LOG_INFO, "FS CLI Ready.\nenter /help for a list of commands.\n");
esl_log(ESL_LOG_INFO, "Netborder SS7 CLI Ready.\nenter /help for a list of commands.\n");
output_printf("%s\n", handle.last_sr_reply);
while (running > 0) {
int r;
#ifdef HAVE_EDITLINE

View File

@ -4,7 +4,7 @@
host => 127.0.0.1
password => ClueCon
port => 8021
port => 8821
debug => 2
key_f1 => help

View File

@ -213,6 +213,8 @@ ftmod_sangoma_ss7_la_SOURCES = \
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c \
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sts.c \
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c \
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_m2ua_xml.c \
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_m2ua.c \
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_relay.c
ftmod_sangoma_ss7_la_CFLAGS = $(FTDM_CFLAGS) $(AM_CFLAGS) -D_GNU_SOURCE

View File

@ -13,7 +13,7 @@ cpu_monitoring_interval => 1000
cpu_set_alarm_threshold => 80
; At what CPU percentage stop the CPU alarm
cpu_reset_alarm_threshold => 70
cpu_clear_alarm_threshold => 70
; Which action to take when the CPU alarm is raised
; it can be warn and/or reject calls

View File

@ -0,0 +1,43 @@
SS7 Native Bridge
Native bridge is enabled on 2 conditions:
* The SIP header FreeTDM-TransUUID is set in the originating leg and matches a freetdm channel
* The variable freetdm_native_sigbridge is true and the originating leg is also a freetdm channel
Some coding rules apply to this feature:
- Each channel is responsible for clearning its own peer_data and event queue
at the end of the call (when moving to DOWN state)
- Each channel dequeues messages only from its own queue and enqueues messages
in the peer's queue, with the only exception being messages received before
the bridge is stablished (IAM for sure and possible SAM messages) because
if the bridge is not yet stablished the messages must be queued by the channel
in its own queue temporarily until the bridge is ready
- When the bridge is ready it is the responsibility of the incoming channel to
move the messages that stored temporarily in its own queue to the bridged peer queue
- During hangup, each channel is responsible for moving itself to DOWN. The procedure
however differs slightly depending on the hangup conditions
If the user requests hangup (ie, FreeSWITCH) the request will be noted by setting the
FTDM_CHANNEL_USER_HANGUP flag but will not be processed yet because call control is
driven only by the link messages (so no hangup from ESL or command line allowed)
When REL message comes, the channel receiving it must move to TERMINATING state and:
- If the user has not hangup yet (FTDM_CHANNEL_USER_HANGUP flag not set) then
notify the user via SIGEVENT_STOP and wait for the user to move to HANGUP
state by calling ftdm_channel_call_hangup() before sending RLC
- If the user did hangup already (FTDM_CHANNEL_USER_HANGUP flag is set) then
skip user notification and move to HANGUP state directly where the RLC message
will be sent
- On HANGUP state the RLC is sent and the channel is moved to DOWN, final state
The peer channel will forward the REL message and wait for RLC from the network, when
RLC is received the channel can move straight to DOWN itself because the peer channel
is completing its own shutdown procedure when it received the REL message

View File

@ -4,6 +4,7 @@ BASE=../../..
FT_DIR=..
VERBOSE=1
FTLA=$(FT_DIR)/libfreetdm.la
LOCAL_OBJS=tdm.o
LOCAL_CFLAGS=-I$(FT_DIR)/src/include -I$(FT_DIR)/src/isdn/include $(FT_CFLAGS)
LOCAL_LDFLAGS=-L$(FT_DIR) -lfreetdm
include $(BASE)/build/modmake.rules

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,712 @@
/*
* 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.
*
* Contributor(s):
*
* Mathieu Rene <mrene@avgs.ca>
*
* tdm.c -- FreeTDM Controllable Channel Module
*
*/
#include <switch.h>
#include "freetdm.h"
void ctdm_init(switch_loadable_module_interface_t *module_interface);
/* Parameters */
#define kSPAN_ID "span"
#define kCHAN_ID "chan"
#define kSPAN_NAME "span_name"
#define kPREBUFFER_LEN "prebuffer_len"
#define kECHOCANCEL "echo_cancel"
static struct {
switch_memory_pool_t *pool;
switch_endpoint_interface_t *endpoint_interface;
} ctdm;
typedef struct {
int span_id;
int chan_id;
ftdm_channel_t *ftdm_channel;
switch_core_session_t *session;
switch_codec_t read_codec, write_codec;
switch_frame_t read_frame;
int prebuffer_len;
unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
} ctdm_private_t;
static switch_status_t channel_on_init(switch_core_session_t *session);
static switch_status_t channel_on_destroy(switch_core_session_t *session);
static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session,
switch_memory_pool_t **pool,
switch_originate_flag_t flags, switch_call_cause_t *cancel_cause);
static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id);
static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
static switch_status_t channel_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg);
static switch_status_t channel_receive_event(switch_core_session_t *session, switch_event_t *event);
static switch_status_t channel_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf);
static ftdm_status_t ctdm_span_prepare(ftdm_span_t *span);
switch_state_handler_table_t ctdm_state_handlers = {
.on_init = channel_on_init,
.on_destroy = channel_on_destroy
};
switch_io_routines_t ctdm_io_routines = {
.send_dtmf = channel_send_dtmf,
.outgoing_channel = channel_outgoing_channel,
.read_frame = channel_read_frame,
.write_frame = channel_write_frame,
.receive_message = channel_receive_message,
.receive_event = channel_receive_event
};
static void ctdm_report_alarms(ftdm_channel_t *channel)
{
switch_event_t *event = NULL;
ftdm_alarm_flag_t alarmflag = 0;
if (switch_event_create(&event, SWITCH_EVENT_TRAP) != SWITCH_STATUS_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "failed to create alarms events\n");
return;
}
if (ftdm_channel_get_alarms(channel, &alarmflag) != FTDM_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to retrieve alarms %s:%d\n", ftdm_channel_get_span_name(channel), ftdm_channel_get_id(channel));
return;
}
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-name", "%s", ftdm_channel_get_span_name(channel));
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-number", "%d", ftdm_channel_get_span_id(channel));
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "chan-number", "%d", ftdm_channel_get_id(channel));
if (alarmflag) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-trap");
} else {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-clear");
}
if (alarmflag & FTDM_ALARM_RED) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "red");
}
if (alarmflag & FTDM_ALARM_YELLOW) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "yellow");
}
if (alarmflag & FTDM_ALARM_RAI) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "rai");
}
if (alarmflag & FTDM_ALARM_BLUE) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "blue");
}
if (alarmflag & FTDM_ALARM_AIS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "ais");
}
if (alarmflag & FTDM_ALARM_GENERAL) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "general");
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Reporting [%s] alarms for %s:%d\n",
(alarmflag?"ftdm-alarm-trap":"ftdm-alarm-clear"), ftdm_channel_get_span_name(channel), ftdm_channel_get_id(channel));
switch_event_fire(&event);
return;
}
static ftdm_channel_t *ctdm_get_channel_from_event(switch_event_t *event, ftdm_span_t *span)
{
uint32_t chan_id = 0;
const char *chan_number = NULL;
chan_number = switch_event_get_header(event, "chan-number");
if (zstr(chan_number)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No channel number specified\n");
return NULL;
}
chan_id = atoi(chan_number);
if (!chan_id) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid channel number:%s\n", chan_number);
return NULL;
}
return ftdm_span_get_channel_ph(span, chan_id);
}
static void ctdm_event_handler(switch_event_t *event)
{
ftdm_status_t status = FTDM_FAIL;
switch(event->event_id) {
case SWITCH_EVENT_TRAP:
{
ftdm_span_t *span = NULL;
ftdm_channel_t *channel = NULL;
const char *span_name = NULL;
const char *cond = switch_event_get_header(event, "condition");
const char *command = switch_event_get_header(event, "command");
if (zstr(cond)) {
return;
}
span_name = switch_event_get_header(event, "span-name");
if (ftdm_span_find_by_name(span_name, &span) != FTDM_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find span [%s]\n", span_name);
return;
}
if (!strcmp(cond, "mg-tdm-prepare")) {
status = ctdm_span_prepare(span);
if (status == FTDM_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s:prepared successfully\n", span_name);
} else if (status != FTDM_EINVAL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s:Failed to prepare span\n", span_name);
}
} else if (!strcmp(cond, "mg-tdm-check")) {
channel = ctdm_get_channel_from_event(event, span);
if (!channel) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find channel\n");
return;
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Requesting alarm status for %s:%d\n",
ftdm_channel_get_span_name(channel), ftdm_channel_get_id(channel));
ctdm_report_alarms(channel);
} else if (!strcmp(cond, "mg-tdm-dtmfremoval")) {
uint8_t enable = 0;
channel = ctdm_get_channel_from_event(event, span);
if (!channel) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find channel\n");
return;
}
if (zstr(command)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s:No command specified for mg-tdm-dtmfremoval\n", span_name);
return;
}
if (!strcmp(command, "enable")) {
enable = 1;
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s DTMF-removal for %s:%d\n",
enable ? "Enabling" : "Disabling", ftdm_channel_get_span_name(channel), ftdm_channel_get_id(channel));
ftdm_channel_command(channel, enable ? FTDM_COMMAND_ENABLE_DTMF_REMOVAL : FTDM_COMMAND_DISABLE_DTMF_REMOVAL, 0);
}
}
break;
default:
break;
}
return;
}
void ctdm_init(switch_loadable_module_interface_t *module_interface)
{
switch_endpoint_interface_t *endpoint_interface;
ctdm.pool = module_interface->pool;
endpoint_interface = switch_loadable_module_create_interface(module_interface, SWITCH_ENDPOINT_INTERFACE);
endpoint_interface->interface_name = "tdm";
endpoint_interface->io_routines = &ctdm_io_routines;
endpoint_interface->state_handler = &ctdm_state_handlers;
ctdm.endpoint_interface = endpoint_interface;
switch_event_bind("mod_freetdm", SWITCH_EVENT_TRAP, SWITCH_EVENT_SUBCLASS_ANY, ctdm_event_handler, NULL);
}
static FIO_SIGNAL_CB_FUNCTION(on_signal_cb)
{
uint32_t chanid, spanid;
switch_event_t *event = NULL;
ftdm_alarm_flag_t alarmbits = FTDM_ALARM_NONE;
chanid = ftdm_channel_get_id(sigmsg->channel);
spanid = ftdm_channel_get_span_id(sigmsg->channel);
switch(sigmsg->event_id) {
case FTDM_SIGEVENT_ALARM_CLEAR:
case FTDM_SIGEVENT_ALARM_TRAP:
{
if (ftdm_channel_get_alarms(sigmsg->channel, &alarmbits) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "failed to retrieve alarms\n");
return FTDM_FAIL;
}
if (switch_event_create(&event, SWITCH_EVENT_TRAP) != SWITCH_STATUS_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "failed to create alarms events\n");
return FTDM_FAIL;
}
if (sigmsg->event_id == FTDM_SIGEVENT_ALARM_CLEAR) {
ftdm_log(FTDM_LOG_NOTICE, "Alarm cleared on channel %d:%d\n", spanid, chanid);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-clear");
} else {
ftdm_log(FTDM_LOG_NOTICE, "Alarm raised on channel %d:%d\n", spanid, chanid);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-trap");
}
}
break;
default:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unhandled event %d\n", sigmsg->event_id);
break;
}
if (event) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-name", "%s", ftdm_channel_get_span_name(sigmsg->channel));
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-number", "%d", ftdm_channel_get_span_id(sigmsg->channel));
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "chan-number", "%d", ftdm_channel_get_id(sigmsg->channel));
if (alarmbits & FTDM_ALARM_RED) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "red");
}
if (alarmbits & FTDM_ALARM_YELLOW) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "yellow");
}
if (alarmbits & FTDM_ALARM_RAI) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "rai");
}
if (alarmbits & FTDM_ALARM_BLUE) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "blue");
}
if (alarmbits & FTDM_ALARM_AIS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "ais");
}
if (alarmbits & FTDM_ALARM_GENERAL) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "general");
}
switch_event_fire(&event);
}
return FTDM_SUCCESS;
}
static ftdm_status_t ctdm_span_prepare(ftdm_span_t *span)
{
if (ftdm_span_register_signal_cb(span, on_signal_cb) != FTDM_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register signal CB\n");
return FTDM_FAIL;
}
return ftdm_span_start(span);
}
static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session,
switch_memory_pool_t **pool,
switch_originate_flag_t flags, switch_call_cause_t *cancel_cause)
{
const char *szchanid = switch_event_get_header(var_event, kCHAN_ID),
*span_name = switch_event_get_header(var_event, kSPAN_NAME),
*szprebuffer_len = switch_event_get_header(var_event, kPREBUFFER_LEN);
int chan_id;
int span_id;
switch_caller_profile_t *caller_profile;
ftdm_span_t *span;
ftdm_channel_t *chan;
switch_channel_t *channel;
char name[128];
const char *dname;
ftdm_codec_t codec;
uint32_t interval;
ctdm_private_t *tech_pvt = NULL;
if (zstr(szchanid) || zstr(span_name)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Both ["kSPAN_ID"] and ["kCHAN_ID"] have to be set.\n");
goto fail;
}
chan_id = atoi(szchanid);
if (ftdm_span_find_by_name(span_name, &span) == FTDM_SUCCESS) {
span_id = ftdm_span_get_id(span);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find span [%s]\n", span_name);
goto fail;
}
if (!(*new_session = switch_core_session_request(ctdm.endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, 0, pool))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't request session.\n");
goto fail;
}
channel = switch_core_session_get_channel(*new_session);
if (ftdm_channel_open_ph(span_id, chan_id, &chan) != FTDM_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't open span or channel.\n");
goto fail;
}
span = ftdm_channel_get_span(chan);
tech_pvt = switch_core_session_alloc(*new_session, sizeof *tech_pvt);
tech_pvt->chan_id = chan_id;
tech_pvt->span_id = span_id;
tech_pvt->ftdm_channel = chan;
tech_pvt->session = *new_session;
tech_pvt->read_frame.buflen = sizeof(tech_pvt->databuf);
tech_pvt->read_frame.data = tech_pvt->databuf;
tech_pvt->prebuffer_len = zstr(szprebuffer_len) ? 0 : atoi(szprebuffer_len);
switch_core_session_set_private(*new_session, tech_pvt);
caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
switch_channel_set_caller_profile(channel, caller_profile);
snprintf(name, sizeof(name), "tdm/%d:%d", span_id, chan_id);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connect outbound channel %s\n", name);
switch_channel_set_name(channel, name);
switch_channel_set_state(channel, CS_INIT);
if (FTDM_SUCCESS != ftdm_channel_command(chan, FTDM_COMMAND_GET_CODEC, &codec)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to retrieve channel codec.\n");
return SWITCH_STATUS_GENERR;
}
if (FTDM_SUCCESS != ftdm_channel_command(chan, FTDM_COMMAND_GET_INTERVAL, &interval)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to retrieve channel interval.\n");
return SWITCH_STATUS_GENERR;
}
if (FTDM_SUCCESS != ftdm_channel_command(chan, FTDM_COMMAND_SET_PRE_BUFFER_SIZE, &tech_pvt->prebuffer_len)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to set channel pre buffer size.\n");
return SWITCH_STATUS_GENERR;
}
if (FTDM_SUCCESS != ftdm_channel_command(tech_pvt->ftdm_channel, FTDM_COMMAND_ENABLE_ECHOCANCEL, NULL)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to set enable echo cancellation.\n");
}
switch(codec) {
case FTDM_CODEC_ULAW:
{
dname = "PCMU";
}
break;
case FTDM_CODEC_ALAW:
{
dname = "PCMA";
}
break;
case FTDM_CODEC_SLIN:
{
dname = "L16";
}
break;
default:
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid codec value retrieved from channel, codec value: %d\n", codec);
goto fail;
}
}
if (switch_core_codec_init(&tech_pvt->read_codec,
dname,
NULL,
8000,
interval,
1,
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
goto fail;
} else {
if (switch_core_codec_init(&tech_pvt->write_codec,
dname,
NULL,
8000,
interval,
1,
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
switch_core_codec_destroy(&tech_pvt->read_codec);
goto fail;
}
}
if (switch_core_session_set_read_codec(*new_session, &tech_pvt->read_codec) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't set read codec?\n");
goto fail;
}
if (switch_core_session_set_write_codec(*new_session, &tech_pvt->write_codec) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't set write codec?\n");
}
if (switch_core_session_thread_launch(*new_session) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't start session thread.\n");
goto fail;
}
switch_channel_mark_answered(channel);
return SWITCH_CAUSE_SUCCESS;
fail:
if (tech_pvt) {
if (tech_pvt->ftdm_channel) {
ftdm_channel_close(&tech_pvt->ftdm_channel);
}
if (tech_pvt->read_codec.implementation) {
switch_core_codec_destroy(&tech_pvt->read_codec);
}
if (tech_pvt->write_codec.implementation) {
switch_core_codec_destroy(&tech_pvt->write_codec);
}
}
if (*new_session) {
switch_core_session_destroy(new_session);
}
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
}
static switch_status_t channel_on_init(switch_core_session_t *session)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_channel_set_state(channel, CS_CONSUME_MEDIA);
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t channel_on_destroy(switch_core_session_t *session)
{
ctdm_private_t *tech_pvt = switch_core_session_get_private(session);
if ((tech_pvt = switch_core_session_get_private(session))) {
if (FTDM_SUCCESS != ftdm_channel_command(tech_pvt->ftdm_channel, FTDM_COMMAND_ENABLE_ECHOCANCEL, NULL)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to enable echo cancellation.\n");
}
if (tech_pvt->read_codec.implementation) {
switch_core_codec_destroy(&tech_pvt->read_codec);
}
if (tech_pvt->write_codec.implementation) {
switch_core_codec_destroy(&tech_pvt->write_codec);
}
ftdm_channel_close(&tech_pvt->ftdm_channel);
}
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
{
ftdm_wait_flag_t wflags = FTDM_READ;
ftdm_status_t status;
ctdm_private_t *tech_pvt;
const char *name;
switch_channel_t *channel;
int chunk;
uint32_t span_id, chan_id;
ftdm_size_t len;
char dtmf[128] = "";
channel = switch_core_session_get_channel(session);
assert(channel != NULL);
tech_pvt = switch_core_session_get_private(session);
assert(tech_pvt != NULL);
name = switch_channel_get_name(channel);
top:
wflags = FTDM_READ;
chunk = ftdm_channel_get_io_interval(tech_pvt->ftdm_channel) * 2;
status = ftdm_channel_wait(tech_pvt->ftdm_channel, &wflags, chunk);
span_id = ftdm_channel_get_span_id(tech_pvt->ftdm_channel);
chan_id = ftdm_channel_get_id(tech_pvt->ftdm_channel);
if (status == FTDM_FAIL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to read from channel %s device %d:%d!\n", name, span_id, chan_id);
goto fail;
}
if (status == FTDM_TIMEOUT) {
goto top;
}
if (!(wflags & FTDM_READ)) {
goto top;
}
len = tech_pvt->read_frame.buflen;
if (ftdm_channel_read(tech_pvt->ftdm_channel, tech_pvt->read_frame.data, &len) != FTDM_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to read from channel %s device %d:%d!\n", name, span_id, chan_id);
}
*frame = &tech_pvt->read_frame;
tech_pvt->read_frame.datalen = (uint32_t)len;
tech_pvt->read_frame.samples = tech_pvt->read_frame.datalen;
tech_pvt->read_frame.codec = &tech_pvt->read_codec;
if (ftdm_channel_get_codec(tech_pvt->ftdm_channel) == FTDM_CODEC_SLIN) {
tech_pvt->read_frame.samples /= 2;
}
while (ftdm_channel_dequeue_dtmf(tech_pvt->ftdm_channel, dtmf, sizeof(dtmf))) {
switch_dtmf_t _dtmf = { 0, switch_core_default_dtmf_duration(0) };
char *p;
for (p = dtmf; p && *p; p++) {
if (is_dtmf(*p)) {
_dtmf.digit = *p;
ftdm_log(FTDM_LOG_DEBUG, "Queuing DTMF [%c] in channel %s device %d:%d\n", *p, name, span_id, chan_id);
switch_channel_queue_dtmf(channel, &_dtmf);
}
}
}
return SWITCH_STATUS_SUCCESS;
fail:
return SWITCH_STATUS_GENERR;
}
static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
{
ftdm_wait_flag_t wflags = FTDM_WRITE;
ctdm_private_t *tech_pvt;
const char *name;
switch_channel_t *channel;
uint32_t span_id, chan_id;
ftdm_size_t len;
unsigned char data[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0};
channel = switch_core_session_get_channel(session);
assert(channel != NULL);
tech_pvt = switch_core_session_get_private(session);
assert(tech_pvt != NULL);
span_id = ftdm_channel_get_span_id(tech_pvt->ftdm_channel);
chan_id = ftdm_channel_get_id(tech_pvt->ftdm_channel);
name = switch_channel_get_name(channel);
if (switch_test_flag(frame, SFF_CNG)) {
frame->data = data;
frame->buflen = sizeof(data);
if ((frame->datalen = tech_pvt->write_codec.implementation->encoded_bytes_per_packet) > frame->buflen) {
goto fail;
}
memset(data, 255, frame->datalen);
}
wflags = FTDM_WRITE;
ftdm_channel_wait(tech_pvt->ftdm_channel, &wflags, ftdm_channel_get_io_interval(tech_pvt->ftdm_channel) * 10);
if (!(wflags & FTDM_WRITE)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Dropping frame! (write not ready) in channel %s device %d:%d!\n", name, span_id, chan_id);
return SWITCH_STATUS_SUCCESS;
}
len = frame->datalen;
if (ftdm_channel_write(tech_pvt->ftdm_channel, frame->data, frame->buflen, &len) != FTDM_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Failed to write to channel %s device %d:%d!\n", name, span_id, chan_id);
}
return SWITCH_STATUS_SUCCESS;
fail:
return SWITCH_STATUS_GENERR;
}
static switch_status_t channel_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf)
{
ctdm_private_t *tech_pvt = NULL;
char tmp[2] = "";
tech_pvt = switch_core_session_get_private(session);
assert(tech_pvt != NULL);
tmp[0] = dtmf->digit;
ftdm_channel_command(tech_pvt->ftdm_channel, FTDM_COMMAND_SEND_DTMF, tmp);
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t channel_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg)
{
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t channel_receive_event(switch_core_session_t *session, switch_event_t *event)
{
const char *command = switch_event_get_header(event, "command");
ctdm_private_t *tech_pvt = switch_core_session_get_private(session);
if (!zstr(command)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FreeTDM received %s command \n",command);
if (!strcasecmp(command, kPREBUFFER_LEN)) {
const char *szval = switch_event_get_header(event, kPREBUFFER_LEN);
int val = !zstr(szval) ? atoi(szval) : 0;
if (tech_pvt->prebuffer_len == val) {
tech_pvt->prebuffer_len = val;
if (FTDM_SUCCESS != ftdm_channel_command(tech_pvt->ftdm_channel, FTDM_COMMAND_SET_PRE_BUFFER_SIZE, &tech_pvt->prebuffer_len)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to set channel pre buffer size.\n");
return SWITCH_STATUS_GENERR;
}
}
} else if (!strcasecmp(command, kECHOCANCEL)) {
const char *szval = switch_event_get_header(event, kECHOCANCEL);
int enabled = !!switch_true(szval);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FreeTDM sending echo cancel [%s] command \n",enabled ? "enable" : "disable");
if (FTDM_SUCCESS != ftdm_channel_command(tech_pvt->ftdm_channel, enabled ? FTDM_COMMAND_ENABLE_ECHOCANCEL : FTDM_COMMAND_DISABLE_ECHOCANCEL, NULL)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to %s echo cancellation.\n", enabled ? "enable" : "disable");
}
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FreeTDM received unknown command [%s] \n",command);
}
}
return SWITCH_STATUS_SUCCESS;
}

View File

@ -36,10 +36,10 @@
* David Yat Sin <dyatsin@sangoma.com>
*
*/
#define _GNU_SOURCE
#include "private/ftdm_core.h"
#include <stdarg.h>
#include <ctype.h>
#ifdef WIN32
#include <io.h>
#endif
@ -52,9 +52,7 @@
struct tm *localtime_r(const time_t *clock, struct tm *result);
#endif
#define FORCE_HANGUP_TIMER 3000
#define SPAN_PENDING_CHANS_QUEUE_SIZE 1000
#define SPAN_PENDING_SIGNALS_QUEUE_SIZE 1000
#define FORCE_HANGUP_TIMER 30000
#define FTDM_READ_TRACE_INDEX 0
#define FTDM_WRITE_TRACE_INDEX 1
#define MAX_CALLIDS 6000
@ -64,11 +62,78 @@ struct tm *localtime_r(const time_t *clock, struct tm *result);
ftdm_time_t time_last_throttle_log = 0;
ftdm_time_t time_current_throttle_log = 0;
typedef struct val_str {
const char *str;
unsigned long long val;
} val_str_t;
static val_str_t channel_flag_strs[] = {
{ "configured" , FTDM_CHANNEL_CONFIGURED},
{ "ready", FTDM_CHANNEL_READY},
{ "open", FTDM_CHANNEL_OPEN},
{ "dtmf-detect", FTDM_CHANNEL_DTMF_DETECT},
{ "suppress-dtmf", FTDM_CHANNEL_SUPRESS_DTMF},
{ "transcode", FTDM_CHANNEL_TRANSCODE},
{ "buffer", FTDM_CHANNEL_BUFFER},
{ "in-thread", FTDM_CHANNEL_INTHREAD},
{ "wink", FTDM_CHANNEL_WINK},
{ "flash", FTDM_CHANNEL_FLASH},
{ "state-change", FTDM_CHANNEL_STATE_CHANGE},
{ "hold", FTDM_CHANNEL_HOLD},
{ "in-use", FTDM_CHANNEL_INUSE},
{ "off-hook", FTDM_CHANNEL_OFFHOOK},
{ "ringing", FTDM_CHANNEL_RINGING},
{ "progress-detect", FTDM_CHANNEL_PROGRESS_DETECT},
{ "callerid-detect", FTDM_CHANNEL_CALLERID_DETECT},
{ "outbound", FTDM_CHANNEL_OUTBOUND},
{ "suspended", FTDM_CHANNEL_SUSPENDED},
{ "3-way", FTDM_CHANNEL_3WAY},
{ "progress", FTDM_CHANNEL_PROGRESS},
{ "media", FTDM_CHANNEL_MEDIA},
{ "answered", FTDM_CHANNEL_ANSWERED},
{ "mute", FTDM_CHANNEL_MUTE},
{ "use-rx-gain", FTDM_CHANNEL_USE_RX_GAIN},
{ "use-tx-gain", FTDM_CHANNEL_USE_TX_GAIN},
{ "in-alarm", FTDM_CHANNEL_IN_ALARM},
{ "sig-up", FTDM_CHANNEL_SIG_UP},
{ "user-hangup", FTDM_CHANNEL_USER_HANGUP},
{ "rx-disabled", FTDM_CHANNEL_RX_DISABLED},
{ "tx-disabled", FTDM_CHANNEL_TX_DISABLED},
{ "call-started", FTDM_CHANNEL_CALL_STARTED},
{ "non-block", FTDM_CHANNEL_NONBLOCK},
{ "ind-ack-pending", FTDM_CHANNEL_IND_ACK_PENDING},
{ "blocking", FTDM_CHANNEL_BLOCKING},
{ "media", FTDM_CHANNEL_DIGITAL_MEDIA},
{ "native-sigbridge", FTDM_CHANNEL_NATIVE_SIGBRIDGE},
{ "invalid", FTDM_CHANNEL_MAX_FLAG},
};
static val_str_t span_flag_strs[] = {
{ "configured", FTDM_SPAN_CONFIGURED},
{ "started", FTDM_SPAN_STARTED},
{ "state-change", FTDM_SPAN_STATE_CHANGE},
{ "suspended", FTDM_SPAN_SUSPENDED},
{ "in-thread", FTDM_SPAN_IN_THREAD},
{ "stop-thread", FTDM_SPAN_STOP_THREAD},
{ "use-chan-queue", FTDM_SPAN_USE_CHAN_QUEUE},
{ "suggest-chan-id", FTDM_SPAN_SUGGEST_CHAN_ID},
{ "use-av-rate", FTDM_SPAN_USE_AV_RATE},
{ "power-saving", FTDM_SPAN_PWR_SAVING},
{ "signals-queue", FTDM_SPAN_USE_SIGNALS_QUEUE},
{ "proceed-state", FTDM_SPAN_USE_PROCEED_STATE},
{ "skip-state", FTDM_SPAN_USE_SKIP_STATES},
{ "non-stoppable", FTDM_SPAN_NON_STOPPABLE},
{ "use-transfer", FTDM_SPAN_USE_TRANSFER},
};
static ftdm_status_t ftdm_call_set_call_id(ftdm_channel_t *fchan, ftdm_caller_data_t *caller_data);
static ftdm_status_t ftdm_call_clear_call_id(ftdm_caller_data_t *caller_data);
static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan);
static ftdm_status_t ftdm_channel_sig_indicate(ftdm_channel_t *ftdmchan, ftdm_channel_indication_t indication, ftdm_usrmsg_t *usrmsg);
static const char *ftdm_val2str(unsigned long long val, val_str_t *val_str_table, ftdm_size_t array_size, const char *default_str);
static unsigned long long ftdm_str2val(const char *str, val_str_t *val_str_table, ftdm_size_t array_size, unsigned long long default_val);
static int time_is_init = 0;
@ -171,7 +236,7 @@ static void stop_chan_io_dump(ftdm_io_dump_t *dump)
return;
}
ftdm_safe_free(dump->buffer);
memset(dump, 0, sizeof(dump));
memset(dump, 0, sizeof(*dump));
}
static ftdm_status_t start_chan_io_dump(ftdm_channel_t *chan, ftdm_io_dump_t *dump, ftdm_size_t size)
@ -223,7 +288,7 @@ typedef struct {
uint32_t interval;
uint8_t alarm_action_flags;
uint8_t set_alarm_threshold;
uint8_t reset_alarm_threshold;
uint8_t clear_alarm_threshold;
ftdm_interrupt_t *interrupt;
} cpu_monitor_t;
@ -1051,7 +1116,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_add_channel(ftdm_span_t *span, ftdm_socket_t
i++;
}
ftdm_set_flag(new_chan, FTDM_CHANNEL_CONFIGURED | FTDM_CHANNEL_READY);
ftdm_set_flag(new_chan, FTDM_CHANNEL_CONFIGURED | FTDM_CHANNEL_READY);
new_chan->state = FTDM_CHANNEL_STATE_DOWN;
new_chan->state_status = FTDM_STATE_STATUS_COMPLETED;
*chan = new_chan;
@ -1404,13 +1469,24 @@ FT_DECLARE(ftdm_status_t) ftdm_group_channel_use_count(ftdm_group_t *group, uint
static __inline__ int chan_is_avail(ftdm_channel_t *check)
{
if (!ftdm_test_flag(check, FTDM_CHANNEL_READY) ||
!ftdm_test_flag(check, FTDM_CHANNEL_SIG_UP) ||
ftdm_test_flag(check, FTDM_CHANNEL_INUSE) ||
ftdm_test_flag(check, FTDM_CHANNEL_SUSPENDED) ||
ftdm_test_flag(check, FTDM_CHANNEL_IN_ALARM) ||
check->state != FTDM_CHANNEL_STATE_DOWN) {
return 0;
if ((check->span->signal_type == FTDM_SIGTYPE_M2UA) ||
(check->span->signal_type == FTDM_SIGTYPE_NONE)) {
if (!ftdm_test_flag(check, FTDM_CHANNEL_READY) ||
ftdm_test_flag(check, FTDM_CHANNEL_INUSE) ||
ftdm_test_flag(check, FTDM_CHANNEL_SUSPENDED) ||
ftdm_test_flag(check, FTDM_CHANNEL_IN_ALARM) ||
check->state != FTDM_CHANNEL_STATE_DOWN) {
return 0;
}
} else {
if (!ftdm_test_flag(check, FTDM_CHANNEL_READY) ||
!ftdm_test_flag(check, FTDM_CHANNEL_SIG_UP) ||
ftdm_test_flag(check, FTDM_CHANNEL_INUSE) ||
ftdm_test_flag(check, FTDM_CHANNEL_SUSPENDED) ||
ftdm_test_flag(check, FTDM_CHANNEL_IN_ALARM) ||
check->state != FTDM_CHANNEL_STATE_DOWN) {
return 0;
}
}
return 1;
}
@ -1816,7 +1892,7 @@ done:
return status;
}
static ftdm_status_t _ftdm_channel_open(uint32_t span_id, uint32_t chan_id, ftdm_channel_t **ftdmchan)
static ftdm_status_t _ftdm_channel_open(uint32_t span_id, uint32_t chan_id, ftdm_channel_t **ftdmchan, uint8_t physical)
{
ftdm_channel_t *check = NULL;
ftdm_span_t *span = NULL;
@ -1845,14 +1921,46 @@ static ftdm_status_t _ftdm_channel_open(uint32_t span_id, uint32_t chan_id, ftdm
goto done;
}
if (chan_id < 1 || chan_id > span->chan_count) {
ftdm_log(FTDM_LOG_ERROR, "Invalid channel %d to open in span %d\n", chan_id, span_id);
goto done;
}
if (physical) { /* Open by physical */
ftdm_channel_t *fchan = NULL;
ftdm_iterator_t *citer = NULL;
ftdm_iterator_t *curr = NULL;
if (!(check = span->channels[chan_id])) {
ftdm_log(FTDM_LOG_CRIT, "Wow, no channel %d in span %d\n", chan_id, span_id);
goto done;
if (chan_id < 1) {
ftdm_log(FTDM_LOG_ERROR, "Invalid physical channel %d to open in span %d\n", chan_id, span_id);
status = FTDM_FAIL;
goto done;
}
citer = ftdm_span_get_chan_iterator(span, NULL);
if (!citer) {
status = ENOMEM;
goto done;
}
for (curr = citer ; curr; curr = ftdm_iterator_next(curr)) {
fchan = ftdm_iterator_current(curr);
if (fchan->physical_chan_id == chan_id) {
check = fchan;
break;
}
}
ftdm_iterator_free(citer);
if (!check) {
ftdm_log(FTDM_LOG_CRIT, "Wow, no physical channel %d in span %d\n", chan_id, span_id);
goto done;
}
} else { /* Open by logical */
if (chan_id < 1 || chan_id > span->chan_count) {
ftdm_log(FTDM_LOG_ERROR, "Invalid channel %d to open in span %d\n", chan_id, span_id);
goto done;
}
if (!(check = span->channels[chan_id])) {
ftdm_log(FTDM_LOG_CRIT, "Wow, no channel %d in span %d\n", chan_id, span_id);
goto done;
}
}
ftdm_channel_lock(check);
@ -1923,7 +2031,18 @@ done:
FT_DECLARE(ftdm_status_t) ftdm_channel_open(uint32_t span_id, uint32_t chan_id, ftdm_channel_t **ftdmchan)
{
ftdm_status_t status;
status = _ftdm_channel_open(span_id, chan_id, ftdmchan);
status = _ftdm_channel_open(span_id, chan_id, ftdmchan, 0);
if (status == FTDM_SUCCESS) {
ftdm_channel_t *fchan = *ftdmchan;
ftdm_channel_unlock(fchan);
}
return status;
}
FT_DECLARE(ftdm_status_t) ftdm_channel_open_ph(uint32_t span_id, uint32_t chan_id, ftdm_channel_t **ftdmchan)
{
ftdm_status_t status;
status = _ftdm_channel_open(span_id, chan_id, ftdmchan, 1);
if (status == FTDM_SUCCESS) {
ftdm_channel_t *fchan = *ftdmchan;
ftdm_channel_unlock(fchan);
@ -2205,6 +2324,15 @@ static ftdm_status_t _ftdm_channel_call_hangup_nl(const char *file, const char *
{
ftdm_status_t status = FTDM_SUCCESS;
/* In native sigbridge mode we ignore hangup requests from the user and hangup only when the signaling module decides it */
if (ftdm_test_flag(chan, FTDM_CHANNEL_NATIVE_SIGBRIDGE) && chan->state != FTDM_CHANNEL_STATE_TERMINATING) {
ftdm_log_chan_ex(chan, file, func, line, FTDM_LOG_LEVEL_DEBUG,
"Ignoring hangup in channel in state %s (native bridge enabled)\n", ftdm_channel_state2str(chan->state));
ftdm_set_flag(chan, FTDM_CHANNEL_USER_HANGUP);
goto done;
}
if (chan->state != FTDM_CHANNEL_STATE_DOWN) {
if (chan->state == FTDM_CHANNEL_STATE_HANGUP) {
/* make user's life easier, and just ignore double hangup requests */
@ -2231,6 +2359,8 @@ static ftdm_status_t _ftdm_channel_call_hangup_nl(const char *file, const char *
ftdm_channel_close(&chan);
}
}
done:
return status;
}
@ -2289,6 +2419,39 @@ FT_DECLARE(ftdm_channel_t *) ftdm_span_get_channel(const ftdm_span_t *span, uint
return chan;
}
FT_DECLARE(ftdm_channel_t *) ftdm_span_get_channel_ph(const ftdm_span_t *span, uint32_t chanid)
{
ftdm_channel_t *chan = NULL;
ftdm_channel_t *fchan = NULL;
ftdm_iterator_t *citer = NULL;
ftdm_iterator_t *curr = NULL;
ftdm_mutex_lock(span->mutex);
if (chanid == 0) {
ftdm_mutex_unlock(span->mutex);
return NULL;
}
citer = ftdm_span_get_chan_iterator(span, NULL);
if (!citer) {
ftdm_mutex_unlock(span->mutex);
return NULL;
}
for (curr = citer ; curr; curr = ftdm_iterator_next(curr)) {
fchan = ftdm_iterator_current(curr);
if (fchan->physical_chan_id == chanid) {
chan = fchan;
break;
}
}
ftdm_iterator_free(citer);
ftdm_mutex_unlock(span->mutex);
return chan;
}
FT_DECLARE(uint32_t) ftdm_span_get_chan_count(const ftdm_span_t *span)
{
uint32_t count;
@ -2326,6 +2489,15 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch
ftdm_channel_lock(ftdmchan);
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) {
ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_DEBUG,
"Ignoring indication %s in channel in state %s (native bridge enabled)\n",
ftdm_channel_indication2str(indication),
ftdm_channel_state2str(ftdmchan->state));
status = FTDM_SUCCESS;
goto done;
}
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_IND_ACK_PENDING)) {
ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_WARNING, "Cannot indicate %s in channel with indication %s still pending in state %s\n",
ftdm_channel_indication2str(indication),
@ -2426,10 +2598,56 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_reset(const char *file, const char *func
return FTDM_SUCCESS;
}
FT_DECLARE(ftdm_status_t) ftdm_get_channel_from_string(const char *string_id, ftdm_span_t **out_span, ftdm_channel_t **out_channel)
{
ftdm_status_t status = FTDM_SUCCESS;
int rc = 0;
ftdm_span_t *span = NULL;
ftdm_channel_t *ftdmchan = NULL;
unsigned span_id = 0;
unsigned chan_id = 0;
*out_span = NULL;
*out_channel = NULL;
if (!string_id) {
ftdm_log(FTDM_LOG_ERROR, "Cannot parse NULL channel id string\n");
status = FTDM_EINVAL;
goto done;
}
rc = sscanf(string_id, "%u:%u", &span_id, &chan_id);
if (rc != 2) {
ftdm_log(FTDM_LOG_ERROR, "Failed to parse channel id string '%s'\n", string_id);
status = FTDM_EINVAL;
goto done;
}
status = ftdm_span_find(span_id, &span);
if (status != FTDM_SUCCESS || !span) {
ftdm_log(FTDM_LOG_ERROR, "Failed to find span for channel id string '%s'\n", string_id);
status = FTDM_EINVAL;
goto done;
}
if (chan_id > (FTDM_MAX_CHANNELS_SPAN+1) || !(ftdmchan = span->channels[chan_id])) {
ftdm_log(FTDM_LOG_ERROR, "Invalid channel id string '%s'\n", string_id);
status = FTDM_EINVAL;
goto done;
}
status = FTDM_SUCCESS;
*out_span = span;
*out_channel = ftdmchan;
done:
return status;
}
/* this function MUST be called with the channel lock held with lock recursivity of 1 exactly,
* and the caller must be aware we might unlock the channel for a brief period of time and then lock it again */
static ftdm_status_t _ftdm_channel_call_place_nl(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_usrmsg_t *usrmsg)
{
const char *var = NULL;
ftdm_status_t status = FTDM_FAIL;
ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "null channel");
@ -2465,6 +2683,16 @@ static ftdm_status_t _ftdm_channel_call_place_nl(const char *file, const char *f
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_CALL_STARTED);
ftdm_call_set_call_id(ftdmchan, &ftdmchan->caller_data);
var = ftdm_usrmsg_get_var(usrmsg, "sigbridge_peer");
if (var) {
ftdm_span_t *peer_span = NULL;
ftdm_channel_t *peer_chan = NULL;
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE);
ftdm_get_channel_from_string(var, &peer_span, &peer_chan);
if (peer_chan) {
ftdm_set_flag(peer_chan, FTDM_CHANNEL_NATIVE_SIGBRIDGE);
}
}
/* if the signaling stack left the channel in state down on success, is expecting us to move to DIALING */
if (ftdmchan->state == FTDM_CHANNEL_STATE_DOWN) {
@ -2520,7 +2748,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_call_place(const char *file, const char *func, i
status = _ftdm_channel_open_by_group(hunting->mode_data.group.group_id,
hunting->mode_data.group.direction, caller_data, &fchan);
} else if (hunting->mode == FTDM_HUNT_CHAN) {
status = _ftdm_channel_open(hunting->mode_data.chan.span_id, hunting->mode_data.chan.chan_id, &fchan);
status = _ftdm_channel_open(hunting->mode_data.chan.span_id, hunting->mode_data.chan.chan_id, &fchan, 0);
} else {
ftdm_log(FTDM_LOG_ERROR, "Cannot make outbound call with invalid hunting mode %d\n", hunting->mode);
return FTDM_EINVAL;
@ -2668,6 +2896,7 @@ static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan)
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_ANSWERED);
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_USER_HANGUP);
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_DIGITAL_MEDIA);
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE);
ftdm_mutex_lock(ftdmchan->pre_buffer_mutex);
ftdm_buffer_destroy(&ftdmchan->pre_buffer);
ftdmchan->pre_buffer_size = 0;
@ -4264,7 +4493,7 @@ static struct {
ftdm_io_interface_t *pika_interface;
} interfaces;
static void print_channels_by_flag(ftdm_stream_handle_t *stream, int32_t flagval, int not, int *count)
static void print_channels_by_flag(ftdm_stream_handle_t *stream, ftdm_span_t *inspan, uint32_t inchan_id, int32_t flagval, int not, int *count)
{
ftdm_hash_iterator_t *i = NULL;
ftdm_span_t *span;
@ -4274,40 +4503,147 @@ static void print_channels_by_flag(ftdm_stream_handle_t *stream, int32_t flagval
const void *key = NULL;
void *val = NULL;
uint32_t flag = (1 << flagval);
int mycount = 0;
*count = 0;
ftdm_mutex_lock(globals.mutex);
for (i = hashtable_first(globals.span_hash); i; i = hashtable_next(i)) {
hashtable_this(i, &key, NULL, &val);
if (!key || !val) {
break;
}
span = val;
citer = ftdm_span_get_chan_iterator(span, NULL);
if (inspan) {
citer = ftdm_span_get_chan_iterator(inspan, NULL);
if (!citer) {
continue;
goto end;
}
for (curr = citer ; curr; curr = ftdm_iterator_next(curr)) {
fchan = ftdm_iterator_current(curr);
if (not && !ftdm_test_flag(fchan, flag)) {
stream->write_function(stream, "[s%dc%d][%d:%d] has not flag %d\n",
fchan->span_id, fchan->chan_id,
fchan->physical_span_id, fchan->physical_chan_id,
flagval);
(*count)++;
} else if (!not && ftdm_test_flag(fchan, flag)) {
stream->write_function(stream, "[s%dc%d][%d:%d] has flag %d\n",
fchan->span_id, fchan->chan_id,
fchan->physical_span_id, fchan->physical_chan_id,
flagval);
(*count)++;
if (!inchan_id || inchan_id == fchan->chan_id) {
if (not) {
if (!ftdm_test_flag(fchan, flag)) {
stream->write_function(stream, "[s%dc%d][%d:%d] flag !%d(!%s) ON \n",
fchan->span_id, fchan->chan_id,
fchan->physical_span_id, fchan->physical_chan_id,
flagval, ftdm_val2str(flag, channel_flag_strs, ftdm_array_len(channel_flag_strs), "invalid"));
mycount++;
} else {
stream->write_function(stream, "[s%dc%d][%d:%d] flag !%d(!%s) OFF \n",
fchan->span_id, fchan->chan_id,
fchan->physical_span_id, fchan->physical_chan_id,
flagval, ftdm_val2str(flag, channel_flag_strs, ftdm_array_len(channel_flag_strs), "invalid"));
}
} else {
if (ftdm_test_flag(fchan, flag)) {
stream->write_function(stream, "[s%dc%d][%d:%d] flag %d(%s) ON\n",
fchan->span_id, fchan->chan_id,
fchan->physical_span_id, fchan->physical_chan_id,
flagval, ftdm_val2str(flag, channel_flag_strs, ftdm_array_len(channel_flag_strs), "invalid"));
mycount++;
} else {
stream->write_function(stream, "[s%dc%d][%d:%d] flag %d(%s) OFF \n",
fchan->span_id, fchan->chan_id,
fchan->physical_span_id, fchan->physical_chan_id,
flagval, ftdm_val2str(flag, channel_flag_strs, ftdm_array_len(channel_flag_strs), "invalid"));
}
}
}
}
ftdm_iterator_free(citer);
}
} else {
for (i = hashtable_first(globals.span_hash); i; i = hashtable_next(i)) {
hashtable_this(i, &key, NULL, &val);
if (!key || !val) {
break;
}
span = val;
citer = ftdm_span_get_chan_iterator(span, NULL);
if (!citer) {
continue;
}
for (curr = citer ; curr; curr = ftdm_iterator_next(curr)) {
fchan = ftdm_iterator_current(curr);
if (not && !ftdm_test_flag(fchan, flag)) {
stream->write_function(stream, "[s%dc%d][%d:%d] flag !%d(!%s)\n",
fchan->span_id, fchan->chan_id,
fchan->physical_span_id, fchan->physical_chan_id,
flagval, ftdm_val2str(flag, channel_flag_strs, ftdm_array_len(channel_flag_strs), "invalid"));
mycount++;
} else if (!not && ftdm_test_flag(fchan, flag)) {
stream->write_function(stream, "[s%dc%d][%d:%d] flag %d(%s)\n",
fchan->span_id, fchan->chan_id,
fchan->physical_span_id, fchan->physical_chan_id,
flagval, ftdm_val2str(flag, channel_flag_strs, ftdm_array_len(channel_flag_strs), "invalid"));
mycount++;
}
}
ftdm_iterator_free(citer);
}
}
*count = mycount;
end:
ftdm_mutex_unlock(globals.mutex);
}
static void print_spans_by_flag(ftdm_stream_handle_t *stream, ftdm_span_t *inspan, int32_t flagval, int not, int *count)
{
ftdm_hash_iterator_t *i = NULL;
ftdm_span_t *span;
const void *key = NULL;
void *val = NULL;
uint32_t flag = (1 << flagval);
int mycount = 0;
*count = 0;
ftdm_mutex_lock(globals.mutex);
if (inspan) {
if (not) {
if (!ftdm_test_flag(inspan, flag)) {
stream->write_function(stream, "[s%d] flag !%d(!%s) ON \n",
inspan->span_id,
flagval, ftdm_val2str(flag, span_flag_strs, ftdm_array_len(span_flag_strs), "invalid"));
mycount++;
} else {
stream->write_function(stream, "[s%d] flag !%d(!%s) OFF \n",
inspan->span_id,
flagval, ftdm_val2str(flag, span_flag_strs, ftdm_array_len(span_flag_strs), "invalid"));
}
} else {
if (ftdm_test_flag(inspan, flag)) {
stream->write_function(stream, "[s%d] flag %d(%s) ON \n",
inspan->span_id,
flagval, ftdm_val2str(flag, span_flag_strs, ftdm_array_len(span_flag_strs), "invalid"));
mycount++;
} else {
stream->write_function(stream, "[s%d] flag %d(%s) OFF \n",
inspan->span_id,
flagval, ftdm_val2str(flag, span_flag_strs, ftdm_array_len(span_flag_strs), "invalid"));
}
}
} else {
for (i = hashtable_first(globals.span_hash); i; i = hashtable_next(i)) {
hashtable_this(i, &key, NULL, &val);
if (!key || !val) {
break;
}
span = val;
if (not && !ftdm_test_flag(span, flag)) {
stream->write_function(stream, "[s%d] flag !%d(!%s)\n",
span->span_id,
flagval, ftdm_val2str(flag, span_flag_strs, ftdm_array_len(span_flag_strs), "invalid"));
mycount++;
} else if (!not && ftdm_test_flag(span, flag)) {
stream->write_function(stream, "[s%d] flag %d(%s)\n",
span->span_id,
flagval, ftdm_val2str(flag, span_flag_strs, ftdm_array_len(span_flag_strs), "invalid"));
mycount++;
}
}
}
*count = mycount;
ftdm_mutex_unlock(globals.mutex);
}
@ -4359,12 +4695,52 @@ static void print_core_usage(ftdm_stream_handle_t *stream)
{
stream->write_function(stream,
"--------------------------------------------------------------------------------\n"
"ftdm core state [!]<state_name> - List all channels in or not in the given state\n"
"ftdm core flag <flag-int-value> - List all channels with the given flag value set\n"
"ftdm core state [!]<state-name> - List all channels in or not in the given state\n"
"ftdm core flag [!]<flag-int-value|flag-name> [<span_id|span_name>] [<chan_id>] - List all channels with the given flag value set\n"
"ftdm core spanflag [!]<flag-int-value|flag-name> [<span_id|span_name>] - List all spans with the given span flag value set\n"
"ftdm core calls - List all known calls to the FreeTDM core\n"
"--------------------------------------------------------------------------------\n");
}
static unsigned long long ftdm_str2val(const char *str, val_str_t *val_str_table, ftdm_size_t array_size, unsigned long long default_val)
{
int i;
for (i = 0; i < array_size; i++) {
if (!strcasecmp(val_str_table[i].str, str)) {
return val_str_table[i].val;
}
}
return default_val;
}
static const char *ftdm_val2str(unsigned long long val, val_str_t *val_str_table, ftdm_size_t array_size, const char *default_str)
{
int i;
for (i = 0; i < array_size; i++) {
if (val_str_table[i].val == val) {
return val_str_table[i].str;
}
}
return default_str;
}
static void print_channel_flag_values(ftdm_stream_handle_t *stream)
{
int i;
for (i = 0; i < ftdm_array_len(channel_flag_strs); i++) {
stream->write_function(stream, "%s\n", channel_flag_strs[i].str);
}
}
static void print_span_flag_values(ftdm_stream_handle_t *stream)
{
int i;
for (i = 0; i < ftdm_array_len(span_flag_strs); i++) {
stream->write_function(stream, "%s\n", span_flag_strs[i].str);
}
}
static char *handle_core_command(const char *cmd)
{
char *mycmd = NULL;
@ -4374,11 +4750,12 @@ static char *handle_core_command(const char *cmd)
char *argv[10] = { 0 };
char *state = NULL;
char *flag = NULL;
uint32_t flagval = 0;
unsigned long long flagval = 0;
uint32_t current_call_id = 0;
ftdm_caller_data_t *calldata = NULL;
ftdm_channel_t *fchan = NULL;
ftdm_channel_state_t i = FTDM_CHANNEL_STATE_INVALID;
ftdm_span_t *fspan = NULL;
ftdm_stream_handle_t stream = { 0 };
FTDM_STANDARD_STREAM(stream);
@ -4419,6 +4796,7 @@ static char *handle_core_command(const char *cmd)
print_channels_by_state(&stream, i, not, &count);
stream.write_function(&stream, "\nTotal channels %s %s: %d\n", not ? "not in state" : "in state", ftdm_channel_state2str(i), count);
} else if (!strcasecmp(argv[0], "flag")) {
uint32_t chan_id = 0;
if (argc < 2) {
stream.write_function(&stream, "core flag command requires an argument\n");
print_core_usage(&stream);
@ -4429,9 +4807,77 @@ static char *handle_core_command(const char *cmd)
not = 1;
flag++;
}
flagval = atoi(flag);
print_channels_by_flag(&stream, flagval, not, &count);
if (isalpha(flag[0])) {
flagval = ftdm_str2val(flag, channel_flag_strs, ftdm_array_len(channel_flag_strs), FTDM_CHANNEL_MAX_FLAG);
if (flagval == FTDM_CHANNEL_MAX_FLAG) {
stream.write_function(&stream, "\nInvalid channel flag value. Possible channel flags\n");
print_channel_flag_values(&stream);
goto done;
}
flagval = flagval >> 1;
} else {
flagval = atoi(flag);
}
/* Specific span specified */
if (argv[2]) {
ftdm_span_find_by_name(argv[2], &fspan);
if (!fspan) {
stream.write_function(&stream, "-ERR span:%s not found\n", argv[2]);
goto done;
}
}
/* Specific channel specified */
if (argv[3]) {
chan_id = atoi(argv[3]);
if (chan_id >= ftdm_span_get_chan_count(fspan)) {
stream.write_function(&stream, "-ERR invalid channel %d\n", chan_id);
goto done;
}
}
print_channels_by_flag(&stream, fspan, chan_id, flagval, not, &count);
stream.write_function(&stream, "\nTotal channels %s %d: %d\n", not ? "without flag" : "with flag", flagval, count);
} else if (!strcasecmp(argv[0], "spanflag")) {
if (argc < 2) {
stream.write_function(&stream, "core spanflag command requires an argument\n");
print_core_usage(&stream);
goto done;
}
flag = argv[1];
if (argv[1][0] == '!') {
not = 1;
flag++;
}
if (isalpha(flag[0])) {
flagval = ftdm_str2val(flag, span_flag_strs, ftdm_array_len(span_flag_strs), FTDM_SPAN_MAX_FLAG);
if (flagval == FTDM_SPAN_MAX_FLAG) {
stream.write_function(&stream, "\nInvalid span flag value. Possible span flags\n");
print_span_flag_values(&stream);
goto done;
}
flagval = flagval >> 1;
} else {
flagval = atoi(flag);
}
/* Specific span specified */
if (argv[2]) {
ftdm_span_find_by_name(argv[2], &fspan);
if (!fspan) {
stream.write_function(&stream, "-ERR span:%s not found\n", argv[2]);
goto done;
}
}
print_spans_by_flag(&stream, fspan, flagval, not, &count);
if (!fspan) {
stream.write_function(&stream, "\nTotal spans %s %d: %d\n", not ? "without flag" : "with flag", flagval, count);
}
} else if (!strcasecmp(argv[0], "calls")) {
ftdm_mutex_lock(globals.call_id_mutex);
current_call_id = globals.last_call_id;
@ -4872,14 +5318,15 @@ static ftdm_status_t load_config(void)
} else {
ftdm_log(FTDM_LOG_ERROR, "Invalid cpu alarm set threshold %s\n", val);
}
} else if (!strncasecmp(var, "cpu_reset_alarm_threshold", sizeof("cpu_reset_alarm_threshold")-1)) {
} else if (!strncasecmp(var, "cpu_reset_alarm_threshold", sizeof("cpu_reset_alarm_threshold")-1) ||
!strncasecmp(var, "cpu_clear_alarm_threshold", sizeof("cpu_clear_alarm_threshold")-1)) {
intparam = atoi(val);
if (intparam > 0 && intparam < 100) {
globals.cpu_monitor.reset_alarm_threshold = (uint8_t)intparam;
if (globals.cpu_monitor.reset_alarm_threshold > globals.cpu_monitor.set_alarm_threshold) {
globals.cpu_monitor.reset_alarm_threshold = globals.cpu_monitor.set_alarm_threshold - 10;
ftdm_log(FTDM_LOG_ERROR, "Cpu alarm reset threshold must be lower than set threshold"
", setting threshold to %d\n", globals.cpu_monitor.reset_alarm_threshold);
globals.cpu_monitor.clear_alarm_threshold = (uint8_t)intparam;
if (globals.cpu_monitor.clear_alarm_threshold > globals.cpu_monitor.set_alarm_threshold) {
globals.cpu_monitor.clear_alarm_threshold = globals.cpu_monitor.set_alarm_threshold - 10;
ftdm_log(FTDM_LOG_ERROR, "Cpu alarm clear threshold must be lower than set threshold, "
"setting clear threshold to %d\n", globals.cpu_monitor.clear_alarm_threshold);
}
} else {
ftdm_log(FTDM_LOG_ERROR, "Invalid cpu alarm reset threshold %s\n", val);
@ -5247,16 +5694,68 @@ FT_DECLARE(ftdm_status_t) ftdm_configure_span_signaling(ftdm_span_t *span, const
return status;
}
static void *ftdm_span_service_events(ftdm_thread_t *me, void *obj)
{
int i;
unsigned waitms;
ftdm_event_t *event;
ftdm_status_t status = FTDM_SUCCESS;
ftdm_span_t *span = (ftdm_span_t*) obj;
short *poll_events = ftdm_malloc(sizeof(short) * span->chan_count);
memset(poll_events, 0, sizeof(short) * span->chan_count);
for(i = 1; i <= span->chan_count; i++) {
poll_events[i] |= FTDM_EVENTS;
}
while (ftdm_running() && !(ftdm_test_flag(span, FTDM_SPAN_STOP_THREAD))) {
waitms = 1000;
status = ftdm_span_poll_event(span, waitms, poll_events);
switch (status) {
case FTDM_FAIL:
ftdm_log(FTDM_LOG_CRIT, "%s:Failed to poll span for events\n", span->name);
break;
case FTDM_TIMEOUT:
break;
case FTDM_SUCCESS:
/* Check if there are any channels that have events available */
while (ftdm_span_next_event(span, &event) == FTDM_SUCCESS);
break;
default:
ftdm_log(FTDM_LOG_CRIT, "%s:Unhandled IO event\n", span->name);
}
}
return NULL;
}
FT_DECLARE(ftdm_status_t) ftdm_span_register_signal_cb(ftdm_span_t *span, fio_signal_cb_t sig_cb)
{
span->signal_cb = sig_cb;
return FTDM_SUCCESS;
}
FT_DECLARE(ftdm_status_t) ftdm_span_start(ftdm_span_t *span)
{
ftdm_status_t status = FTDM_FAIL;
ftdm_mutex_lock(span->mutex);
if (ftdm_test_flag(span, FTDM_SPAN_STARTED)) {
status = FTDM_EINVAL;
goto done;
}
if (span->signal_type == FTDM_SIGTYPE_NONE) {
/* If there is no signalling component, start a thread to poll events */
status = ftdm_thread_create_detached(ftdm_span_service_events, span);
if (status != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT,"Failed to start span event monitor thread!\n");
goto done;
}
//ftdm_report_initial_channels_alarms(span);
ftdm_set_flag_locked(span, FTDM_SPAN_STARTED);
goto done;
}
if (!span->start) {
status = FTDM_ENOSYS;
@ -5272,7 +5771,6 @@ FT_DECLARE(ftdm_status_t) ftdm_span_start(ftdm_span_t *span)
if (status == FTDM_SUCCESS) {
ftdm_set_flag_locked(span, FTDM_SPAN_STARTED);
}
done:
ftdm_mutex_unlock(span->mutex);
return status;
@ -5457,8 +5955,10 @@ FT_DECLARE(ftdm_status_t) ftdm_group_create(ftdm_group_t **group, const char *na
static ftdm_status_t ftdm_span_trigger_signal(const ftdm_span_t *span, ftdm_sigmsg_t *sigmsg)
{
ftdm_status_t status = span->signal_cb(sigmsg);
return status;
if (!span->signal_cb) {
return FTDM_FAIL;
}
return span->signal_cb(sigmsg);
}
static ftdm_status_t ftdm_span_queue_signal(const ftdm_span_t *span, ftdm_sigmsg_t *sigmsg)
@ -5492,7 +5992,7 @@ static void execute_safety_hangup(void *data)
ftdm_channel_lock(fchan);
fchan->hangup_timer = 0;
if (fchan->state == FTDM_CHANNEL_STATE_TERMINATING) {
ftdm_log_chan(fchan, FTDM_LOG_CRIT, "Forcing hangup since the user did not confirmed our hangup after %dms\n", FORCE_HANGUP_TIMER);
ftdm_log_chan(fchan, FTDM_LOG_WARNING, "Forcing hangup since the user did not confirmed our hangup after %dms\n", FORCE_HANGUP_TIMER);
_ftdm_channel_call_hangup_nl(__FILE__, __FUNCTION__, __LINE__, fchan, NULL);
} else {
ftdm_log_chan(fchan, FTDM_LOG_CRIT, "Not performing safety hangup, channel state is %s\n", ftdm_channel_state2str(fchan->state));
@ -5623,28 +6123,32 @@ static void *ftdm_cpu_monitor_run(ftdm_thread_t *me, void *obj)
{
cpu_monitor_t *monitor = (cpu_monitor_t *)obj;
struct ftdm_cpu_monitor_stats *cpu_stats = ftdm_new_cpu_monitor();
ftdm_log(FTDM_LOG_DEBUG, "CPU monitor thread is now running\n");
if (!cpu_stats) {
return NULL;
goto done;
}
monitor->running = 1;
while(ftdm_running()) {
double time;
if (ftdm_cpu_get_system_idle_time(cpu_stats, &time)) {
while (ftdm_running()) {
double idle_time = 0.0;
int cpu_usage = 0;
if (ftdm_cpu_get_system_idle_time(cpu_stats, &idle_time)) {
break;
}
cpu_usage = (int)(100 - idle_time);
if (monitor->alarm) {
if ((int)time >= (100 - monitor->set_alarm_threshold)) {
ftdm_log(FTDM_LOG_DEBUG, "CPU alarm OFF (idle:%d)\n", (int) time);
if (cpu_usage <= monitor->clear_alarm_threshold) {
ftdm_log(FTDM_LOG_DEBUG, "CPU alarm is now OFF (cpu usage: %d)\n", cpu_usage);
monitor->alarm = 0;
}
if (monitor->alarm_action_flags & FTDM_CPU_ALARM_ACTION_WARN) {
ftdm_log(FTDM_LOG_WARNING, "CPU alarm is ON (cpu usage:%d)\n", (int) (100-time));
} else if (monitor->alarm_action_flags & FTDM_CPU_ALARM_ACTION_WARN) {
ftdm_log(FTDM_LOG_WARNING, "CPU alarm is still ON (cpu usage: %d)\n", cpu_usage);
}
} else {
if ((int)time <= (100-monitor->reset_alarm_threshold)) {
ftdm_log(FTDM_LOG_DEBUG, "CPU alarm ON (idle:%d)\n", (int) time);
if (cpu_usage >= monitor->set_alarm_threshold) {
ftdm_log(FTDM_LOG_WARNING, "CPU alarm is now ON (cpu usage: %d)\n", cpu_usage);
monitor->alarm = 1;
}
}
@ -5653,7 +6157,11 @@ static void *ftdm_cpu_monitor_run(ftdm_thread_t *me, void *obj)
ftdm_delete_cpu_monitor(cpu_stats);
monitor->running = 0;
done:
ftdm_log(FTDM_LOG_DEBUG, "CPU monitor thread is now terminating\n");
return NULL;
#ifdef __WINDOWS__
UNREFERENCED_PARAMETER(me);
#endif
@ -5755,8 +6263,8 @@ FT_DECLARE(ftdm_status_t) ftdm_global_configuration(void)
globals.cpu_monitor.enabled = 0;
globals.cpu_monitor.interval = 1000;
globals.cpu_monitor.alarm_action_flags = 0;
globals.cpu_monitor.set_alarm_threshold = 80;
globals.cpu_monitor.reset_alarm_threshold = 70;
globals.cpu_monitor.set_alarm_threshold = 92;
globals.cpu_monitor.clear_alarm_threshold = 82;
if (load_config() != FTDM_SUCCESS) {
globals.running = 0;
@ -5765,10 +6273,10 @@ FT_DECLARE(ftdm_status_t) ftdm_global_configuration(void)
}
if (globals.cpu_monitor.enabled) {
ftdm_log(FTDM_LOG_INFO, "CPU Monitor is running interval:%d lo-thres:%d hi-thres:%d\n",
ftdm_log(FTDM_LOG_INFO, "CPU Monitor is running interval:%d set-thres:%d clear-thres:%d\n",
globals.cpu_monitor.interval,
globals.cpu_monitor.set_alarm_threshold,
globals.cpu_monitor.reset_alarm_threshold);
globals.cpu_monitor.clear_alarm_threshold);
if (ftdm_cpu_monitor_start() != FTDM_SUCCESS) {
return FTDM_FAIL;

View File

@ -48,9 +48,26 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_complete_state(const char *file, const c
ftdm_time_t diff = 0;
ftdm_channel_state_t state = fchan->state;
#if 0
/* I could not perform this sanity check without more disruptive changes. Ideally we should check here if the signaling module completing the state
executed a state processor (called ftdm_channel_advance_states() which call fchan->span->state_processor(fchan)) for the state. That is just a
sanity check, as in the past we had at least one bug where the signaling module set the state and then accidentally changed the state to a new one
without calling ftdm_channel_advance_states(), meaning the state processor for the first state was not executed and that lead to unexpected behavior.
If we want to be able to perform this kind of sanity check it would be nice to add a new state status (FTDM_STATE_STATUS_PROCESSING), the function
ftdm_channel_advance_states() would set the state_status to PROCESSING and then the check below for STATUS_NEW would be valid. Currently is not
valid because the signaling module may be completing the state at the end of the state_processor callback and therefore the state will still be
in STATUS_NEW, and is perfectly valid ... */
if (fchan->state_status == FTDM_STATE_STATUS_NEW) {
ftdm_log_chan_ex(fchan, file, func, line, FTDM_LOG_LEVEL_CRIT,
"Asking to complete state change from %s to %s in %llums, but the state is still unprocessed (this might be a bug!)\n",
ftdm_channel_state2str(fchan->last_state), ftdm_channel_state2str(state), diff);
}
#endif
if (fchan->state_status == FTDM_STATE_STATUS_COMPLETED) {
ftdm_assert_return(!ftdm_test_flag(fchan, FTDM_CHANNEL_STATE_CHANGE), FTDM_FAIL,
"State change flag set but state is not completed\n");
ftdm_assert_return(!ftdm_test_flag(fchan, FTDM_CHANNEL_STATE_CHANGE), FTDM_FAIL, "State change flag set but state is already completed\n");
return FTDM_SUCCESS;
}
@ -87,6 +104,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_complete_state(const char *file, const c
ftdm_assert(!fchan->history[hindex].end_time, "End time should be zero!\n");
fchan->history[hindex].end_time = ftdm_current_time_in_ms();
fchan->last_state_change_time = ftdm_current_time_in_ms();
fchan->state_status = FTDM_STATE_STATUS_COMPLETED;
@ -262,6 +280,9 @@ static ftdm_status_t ftdm_core_set_state(const char *file, const char *func, int
}
}
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) {
goto perform_state_change;
}
if (ftdmchan->span->state_map) {
ok = ftdm_parse_state_map(ftdmchan, state, ftdmchan->span->state_map);
@ -353,6 +374,8 @@ end:
goto done;
}
perform_state_change:
ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Changed state from %s to %s\n", ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state));
ftdmchan->last_state = ftdmchan->state;
ftdmchan->state = state;

View File

@ -401,7 +401,7 @@ FT_DECLARE(ftdm_status_t) ftdm_interrupt_wait(ftdm_interrupt_t *interrupt, int m
if (interrupt->device != FTDM_INVALID_SOCKET) {
num++;
ints[1] = interrupt->device;
ftdm_log(FTDM_LOG_CRIT, "implement me! (Windows support for device_output_flags member!)\n", size);
ftdm_log(FTDM_LOG_CRIT, "implement me! (Windows support for device_output_flags member!)\n");
}
res = WaitForMultipleObjects(num, ints, FALSE, ms >= 0 ? ms : INFINITE);
switch (res) {

View File

@ -77,7 +77,9 @@ int ft_to_sngss7_cfg_all(void)
int ret = 0;
/* check if we have done gen_config already */
if (!(g_ftdm_sngss7_data.gen_config)) {
if (g_ftdm_sngss7_data.gen_config == SNG_GEN_CFG_STATUS_INIT) {
/* update the global gen_config so we don't do it again */
g_ftdm_sngss7_data.gen_config = SNG_GEN_CFG_STATUS_PENDING;
/* start of by checking if the license and sig file are valid */
if (sng_validate_license(g_ftdm_sngss7_data.cfg.license,
@ -92,7 +94,7 @@ int ft_to_sngss7_cfg_all(void)
/* set the desired procID value */
sng_set_procId((uint16_t)g_ftdm_sngss7_data.cfg.procId);
}
/* start up the stack manager */
if (sng_isup_init_sm()) {
SS7_CRITICAL("Failed to start Stack Manager\n");
@ -207,30 +209,22 @@ int ft_to_sngss7_cfg_all(void)
}
} /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2)) */
/* update the global gen_config so we don't do it again */
g_ftdm_sngss7_data.gen_config = 1;
if(SNG_SS7_OPR_MODE_M2UA_SG == g_ftdm_operating_mode){
if(FTDM_SUCCESS != ftmod_ss7_m2ua_init()){
ftdm_log (FTDM_LOG_ERROR, "ftmod_ss7_m2ua_init FAILED \n");
return FTDM_FAIL;
}
}
g_ftdm_sngss7_data.gen_config = SNG_GEN_CFG_STATUS_DONE;
} /* if (!(g_ftdm_sngss7_data.gen_config)) */
/* go through all the relays channels and configure it */
x = 1;
while (x < (MAX_RELAY_CHANNELS)) {
/* check if this relay channel has been configured already */
if ((g_ftdm_sngss7_data.cfg.relay[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.relay[x].flags & SNGSS7_CONFIGURED))) {
/* send the specific configuration */
if (ftmod_ss7_relay_chan_config(x)) {
SS7_CRITICAL("Relay Channel %d configuration FAILED!\n", x);
return 1;
} else {
SS7_INFO("Relay Channel %d configuration DONE!\n", x);
}
/* set the SNGSS7_CONFIGURED flag */
g_ftdm_sngss7_data.cfg.relay[x].flags |= SNGSS7_CONFIGURED;
} /* if !SNGSS7_CONFIGURED */
x++;
} /* while (x < (MAX_RELAY_CHANNELS)) */
if (g_ftdm_sngss7_data.gen_config != SNG_GEN_CFG_STATUS_DONE) {
SS7_CRITICAL("General configuration FAILED!\n");
return 1;
}
x = 1;
while (x < (MAX_MTP_LINKS)) {
@ -272,160 +266,203 @@ int ft_to_sngss7_cfg_all(void)
x++;
} /* while (x < (MAX_MTP_LINKS+1)) */
x = 1;
while (x < (MAX_MTP_LINKS)) {
/* check if this link has been configured already */
if ((g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.mtp3Link[x].flags & SNGSS7_CONFIGURED))) {
/* configure mtp3 */
if (ftmod_ss7_mtp3_dlsap_config(x)) {
SS7_CRITICAL("MTP3 DLSAP %d configuration FAILED!\n", x);
return 1;;
} else {
SS7_INFO("MTP3 DLSAP %d configuration DONE!\n", x);
}
/* set the SNGSS7_CONFIGURED flag */
g_ftdm_sngss7_data.cfg.mtp3Link[x].flags |= SNGSS7_CONFIGURED;
}
x++;
} /* while (x < (MAX_MTP_LINKS+1)) */
x = 1;
while (x < (MAX_NSAPS)) {
/* check if this link has been configured already */
if ((g_ftdm_sngss7_data.cfg.nsap[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.nsap[x].flags & SNGSS7_CONFIGURED))) {
ret = ftmod_ss7_mtp3_nsap_config(x);
if (ret) {
SS7_CRITICAL("MTP3 NSAP %d configuration FAILED!(%s)\n", x, DECODE_LCM_REASON(ret));
return 1;
} else {
SS7_INFO("MTP3 NSAP %d configuration DONE!\n", x);
}
ret = ftmod_ss7_isup_nsap_config(x);
if (ret) {
SS7_CRITICAL("ISUP NSAP %d configuration FAILED!(%s)\n", x, DECODE_LCM_REASON(ret));
return 1;
} else {
SS7_INFO("ISUP NSAP %d configuration DONE!\n", x);
}
/* set the SNGSS7_CONFIGURED flag */
g_ftdm_sngss7_data.cfg.nsap[x].flags |= SNGSS7_CONFIGURED;
} /* if !SNGSS7_CONFIGURED */
x++;
} /* while (x < (MAX_NSAPS)) */
x = 1;
while (x < (MAX_MTP_LINKSETS+1)) {
/* check if this link has been configured already */
if ((g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags & SNGSS7_CONFIGURED))) {
if (ftmod_ss7_mtp3_linkset_config(x)) {
SS7_CRITICAL("MTP3 LINKSET %d configuration FAILED!\n", x);
return 1;
} else {
SS7_INFO("MTP3 LINKSET %d configuration DONE!\n", x);
}
/* set the SNGSS7_CONFIGURED flag */
g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags |= SNGSS7_CONFIGURED;
} /* if !SNGSS7_CONFIGURED */
x++;
} /* while (x < (MAX_MTP_LINKSETS+1)) */
x = 1;
while (x < (MAX_MTP_ROUTES+1)) {
/* check if this link has been configured already */
if ((g_ftdm_sngss7_data.cfg.mtpRoute[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.mtpRoute[x].flags & SNGSS7_CONFIGURED))) {
if (ftmod_ss7_mtp3_route_config(x)) {
SS7_CRITICAL("MTP3 ROUTE %d configuration FAILED!\n", x);
return 1;
} else {
SS7_INFO("MTP3 ROUTE %d configuration DONE!\n",x);
}
/* set the SNGSS7_CONFIGURED flag */
g_ftdm_sngss7_data.cfg.mtpRoute[x].flags |= SNGSS7_CONFIGURED;
} /* if !SNGSS7_CONFIGURED */
x++;
} /* while (x < (MAX_MTP_ROUTES+1)) */
x = 1;
while (x < (MAX_ISAPS)) {
/* check if this link has been configured already */
if ((g_ftdm_sngss7_data.cfg.isap[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.isap[x].flags & SNGSS7_CONFIGURED))) {
if (ftmod_ss7_isup_isap_config(x)) {
SS7_CRITICAL("ISUP ISAP %d configuration FAILED!\n", x);
return 1;
} else {
SS7_INFO("ISUP ISAP %d configuration DONE!\n", x);
}
/* set the SNGSS7_CONFIGURED flag */
g_ftdm_sngss7_data.cfg.isap[x].flags |= SNGSS7_CONFIGURED;
} /* if !SNGSS7_CONFIGURED */
x++;
} /* while (x < (MAX_ISAPS)) */
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP_STARTED)) {
/* no configs above mtp2 for relay */
if (g_ftdm_sngss7_data.cfg.procId == 1) {
x = 1;
while (x < (MAX_ISUP_INFS)) {
while (x < (MAX_MTP_LINKS)) {
/* check if this link has been configured already */
if ((g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.mtp3Link[x].flags & SNGSS7_CONFIGURED))) {
/* configure mtp3 */
if (ftmod_ss7_mtp3_dlsap_config(x)) {
SS7_CRITICAL("MTP3 DLSAP %d configuration FAILED!\n", x);
return 1;;
} else {
SS7_INFO("MTP3 DLSAP %d configuration DONE!\n", x);
}
/* set the SNGSS7_CONFIGURED flag */
g_ftdm_sngss7_data.cfg.mtp3Link[x].flags |= SNGSS7_CONFIGURED;
}
x++;
} /* while (x < (MAX_MTP_LINKS+1)) */
/* in M2UA_SG mode there will not be any MTP3 layer */
if(SNG_SS7_OPR_MODE_M2UA_SG != g_ftdm_operating_mode){
x = 1;
while (x < (MAX_NSAPS)) {
/* check if this link has been configured already */
if ((g_ftdm_sngss7_data.cfg.nsap[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.nsap[x].flags & SNGSS7_CONFIGURED))) {
ret = ftmod_ss7_mtp3_nsap_config(x);
if (ret) {
SS7_CRITICAL("MTP3 NSAP %d configuration FAILED!(%s)\n", x, DECODE_LCM_REASON(ret));
return 1;
} else {
SS7_INFO("MTP3 NSAP %d configuration DONE!\n", x);
}
ret = ftmod_ss7_isup_nsap_config(x);
if (ret) {
SS7_CRITICAL("ISUP NSAP %d configuration FAILED!(%s)\n", x, DECODE_LCM_REASON(ret));
return 1;
} else {
SS7_INFO("ISUP NSAP %d configuration DONE!\n", x);
}
/* set the SNGSS7_CONFIGURED flag */
g_ftdm_sngss7_data.cfg.nsap[x].flags |= SNGSS7_CONFIGURED;
} /* if !SNGSS7_CONFIGURED */
x++;
} /* while (x < (MAX_NSAPS)) */
}
/* in M2UA_SG mode there will not be any MTP3 layer */
if(SNG_SS7_OPR_MODE_M2UA_SG != g_ftdm_operating_mode){
x = 1;
while (x < (MAX_MTP_LINKSETS+1)) {
/* check if this link has been configured already */
if ((g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags & SNGSS7_CONFIGURED))) {
if (ftmod_ss7_mtp3_linkset_config(x)) {
SS7_CRITICAL("MTP3 LINKSET %d configuration FAILED!\n", x);
return 1;
} else {
SS7_INFO("MTP3 LINKSET %d configuration DONE!\n", x);
}
/* set the SNGSS7_CONFIGURED flag */
g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags |= SNGSS7_CONFIGURED;
} /* if !SNGSS7_CONFIGURED */
x++;
} /* while (x < (MAX_MTP_LINKSETS+1)) */
}
/* in M2UA_SG mode there will not be any MTP3 layer */
if(SNG_SS7_OPR_MODE_M2UA_SG != g_ftdm_operating_mode){
x = 1;
while (x < (MAX_MTP_ROUTES+1)) {
/* check if this link has been configured already */
if ((g_ftdm_sngss7_data.cfg.mtpRoute[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.mtpRoute[x].flags & SNGSS7_CONFIGURED))) {
if (ftmod_ss7_mtp3_route_config(x)) {
SS7_CRITICAL("MTP3 ROUTE %d configuration FAILED!\n", x);
return 1;
} else {
SS7_INFO("MTP3 ROUTE %d configuration DONE!\n",x);
}
/* set the SNGSS7_CONFIGURED flag */
g_ftdm_sngss7_data.cfg.mtpRoute[x].flags |= SNGSS7_CONFIGURED;
} /* if !SNGSS7_CONFIGURED */
x++;
} /* while (x < (MAX_MTP_ROUTES+1)) */
}
x = 1;
while (x < (MAX_ISAPS)) {
/* check if this link has been configured already */
if ((g_ftdm_sngss7_data.cfg.isupIntf[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.isupIntf[x].flags & SNGSS7_CONFIGURED))) {
if (ftmod_ss7_isup_intf_config(x)) {
SS7_CRITICAL("ISUP INTF %d configuration FAILED!\n", x);
if ((g_ftdm_sngss7_data.cfg.isap[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.isap[x].flags & SNGSS7_CONFIGURED))) {
if (ftmod_ss7_isup_isap_config(x)) {
SS7_CRITICAL("ISUP ISAP %d configuration FAILED!\n", x);
return 1;
} else {
SS7_INFO("ISUP INTF %d configuration DONE!\n", x);
/* set the interface to paused */
sngss7_set_flag(&g_ftdm_sngss7_data.cfg.isupIntf[x], SNGSS7_PAUSED);
SS7_INFO("ISUP ISAP %d configuration DONE!\n", x);
}
/* set the SNGSS7_CONFIGURED flag */
g_ftdm_sngss7_data.cfg.isupIntf[x].flags |= SNGSS7_CONFIGURED;
g_ftdm_sngss7_data.cfg.isap[x].flags |= SNGSS7_CONFIGURED;
} /* if !SNGSS7_CONFIGURED */
x++;
} /* while (x < (MAX_ISUP_INFS)) */
} /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP)) */
} /* while (x < (MAX_ISAPS)) */
x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1;
while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) {
/* check if this link has been configured already */
if ((g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.isupCkt[x].flags & SNGSS7_CONFIGURED))) {
if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP_STARTED)) {
x = 1;
while (x < (MAX_ISUP_INFS)) {
/* check if this link has been configured already */
if ((g_ftdm_sngss7_data.cfg.isupIntf[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.isupIntf[x].flags & SNGSS7_CONFIGURED))) {
if (ftmod_ss7_isup_intf_config(x)) {
SS7_CRITICAL("ISUP INTF %d configuration FAILED!\n", x);
return 1;
} else {
SS7_INFO("ISUP INTF %d configuration DONE!\n", x);
/* set the interface to paused */
sngss7_set_flag(&g_ftdm_sngss7_data.cfg.isupIntf[x], SNGSS7_PAUSED);
}
/* set the SNGSS7_CONFIGURED flag */
g_ftdm_sngss7_data.cfg.isupIntf[x].flags |= SNGSS7_CONFIGURED;
} /* if !SNGSS7_CONFIGURED */
x++;
} /* while (x < (MAX_ISUP_INFS)) */
} /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP)) */
if (ftmod_ss7_isup_ckt_config(x)) {
SS7_CRITICAL("ISUP CKT %d configuration FAILED!\n", x);
x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1;
while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) {
if (g_ftdm_sngss7_data.cfg.procId > 1) {
break;
}
/* check if this link has been configured already */
if ((g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.isupCkt[x].flags & SNGSS7_CONFIGURED))) {
if (ftmod_ss7_isup_ckt_config(x)) {
SS7_CRITICAL("ISUP CKT %d configuration FAILED!\n", x);
return 1;
} else {
SS7_INFO("ISUP CKT %d configuration DONE!\n", x);
}
/* set the SNGSS7_CONFIGURED flag */
g_ftdm_sngss7_data.cfg.isupCkt[x].flags |= SNGSS7_CONFIGURED;
} /* if !SNGSS7_CONFIGURED */
x++;
} /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */
}
/* go through all the relays channels and configure it */
x = 1;
while (x < (MAX_RELAY_CHANNELS)) {
/* check if this relay channel has been configured already */
if ((g_ftdm_sngss7_data.cfg.relay[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.relay[x].flags & SNGSS7_CONFIGURED))) {
/* send the specific configuration */
if (ftmod_ss7_relay_chan_config(x)) {
SS7_CRITICAL("Relay Channel %d configuration FAILED!\n", x);
return 1;
} else {
SS7_INFO("ISUP CKT %d configuration DONE!\n", x);
SS7_INFO("Relay Channel %d configuration DONE!\n", x);
}
/* set the SNGSS7_CONFIGURED flag */
g_ftdm_sngss7_data.cfg.isupCkt[x].flags |= SNGSS7_CONFIGURED;
g_ftdm_sngss7_data.cfg.relay[x].flags |= SNGSS7_CONFIGURED;
} /* if !SNGSS7_CONFIGURED */
x++;
} /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */
} /* while (x < (MAX_RELAY_CHANNELS)) */
if(SNG_SS7_OPR_MODE_M2UA_SG == g_ftdm_operating_mode){
return ftmod_ss7_m2ua_cfg();
}
return 0;
}

View File

@ -48,35 +48,7 @@ static int ftmod_ss7_enable_isap(int suId);
static int ftmod_ss7_enable_nsap(int suId);
static int ftmod_ss7_enable_mtpLinkSet(int lnkSetId);
int ftmod_ss7_inhibit_mtp3link(uint32_t id);
int ftmod_ss7_uninhibit_mtp3link(uint32_t id);
int ftmod_ss7_bind_mtp3link(uint32_t id);
int ftmod_ss7_unbind_mtp3link(uint32_t id);
int ftmod_ss7_activate_mtp3link(uint32_t id);
int ftmod_ss7_deactivate_mtp3link(uint32_t id);
int ftmod_ss7_deactivate2_mtp3link(uint32_t id);
int ftmod_ss7_activate_mtplinkSet(uint32_t id);
int ftmod_ss7_deactivate_mtplinkSet(uint32_t id);
int ftmod_ss7_deactivate2_mtplinkSet(uint32_t id);
int ftmod_ss7_lpo_mtp3link(uint32_t id);
int ftmod_ss7_lpr_mtp3link(uint32_t id);
int ftmod_ss7_shutdown_isup(void);
int ftmod_ss7_shutdown_mtp3(void);
int ftmod_ss7_shutdown_mtp2(void);
int ftmod_ss7_shutdown_relay(void);
int ftmod_ss7_disable_relay_channel(uint32_t chanId);
int ftmod_ss7_disable_grp_mtp3Link(uint32_t procId);
int ftmod_ss7_enable_grp_mtp3Link(uint32_t procId);
int ftmod_ss7_disable_grp_mtp2Link(uint32_t procId);
int ftmod_ss7_block_isup_ckt(uint32_t cktId);
int ftmod_ss7_unblock_isup_ckt(uint32_t cktId);
/******************************************************************************/
/* FUNCTIONS ******************************************************************/
@ -88,7 +60,7 @@ int ft_to_sngss7_activate_all(void)
while (x < (MAX_ISAPS)) {
/* check if this link has already been actived */
if ((g_ftdm_sngss7_data.cfg.isap[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.isap[x].flags & SNGSS7_ACTIVE))) {
(!(g_ftdm_sngss7_data.cfg.isap[x].flags & SNGSS7_ACTIVE))) {
if (ftmod_ss7_enable_isap(x)) {
SS7_CRITICAL("ISAP %d Enable: NOT OK\n", x);
@ -100,15 +72,16 @@ int ft_to_sngss7_activate_all(void)
/* set the SNGSS7_ACTIVE flag */
g_ftdm_sngss7_data.cfg.isap[x].flags |= SNGSS7_ACTIVE;
} /* if !SNGSS7_ACTIVE */
x++;
} /* while (x < (MAX_ISAPS)) */
if(SNG_SS7_OPR_MODE_M2UA_SG != g_ftdm_operating_mode){
x = 1;
while (x < (MAX_NSAPS)) {
/* check if this link has already been actived */
if ((g_ftdm_sngss7_data.cfg.nsap[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.nsap[x].flags & SNGSS7_ACTIVE))) {
(!(g_ftdm_sngss7_data.cfg.nsap[x].flags & SNGSS7_ACTIVE))) {
if (ftmod_ss7_enable_nsap(x)) {
SS7_CRITICAL("NSAP %d Enable: NOT OK\n", x);
@ -120,30 +93,35 @@ int ft_to_sngss7_activate_all(void)
/* set the SNGSS7_ACTIVE flag */
g_ftdm_sngss7_data.cfg.nsap[x].flags |= SNGSS7_ACTIVE;
} /* if !SNGSS7_ACTIVE */
x++;
} /* while (x < (MAX_NSAPS)) */
if (g_ftdm_sngss7_data.cfg.mtpRoute[1].id != 0) {
x = 1;
while (x < (MAX_MTP_LINKSETS+1)) {
/* check if this link has already been actived */
if ((g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags & SNGSS7_ACTIVE))) {
if (ftmod_ss7_enable_mtpLinkSet(x)) {
SS7_CRITICAL("LinkSet \"%s\" Enable: NOT OK\n", g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name);
return 1;
} else {
SS7_INFO("LinkSet \"%s\" Enable: OK\n", g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name);
}
/* set the SNGSS7_ACTIVE flag */
g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags |= SNGSS7_ACTIVE;
} /* if !SNGSS7_ACTIVE */
x++;
} /* while (x < (MAX_MTP_LINKSETS+1)) */
if (g_ftdm_sngss7_data.cfg.mtpRoute[1].id != 0) {
x = 1;
while (x < (MAX_MTP_LINKSETS+1)) {
/* check if this link has already been actived */
if ((g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) &&
(!(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags & SNGSS7_ACTIVE))) {
if (ftmod_ss7_enable_mtpLinkSet(x)) {
SS7_CRITICAL("LinkSet \"%s\" Enable: NOT OK\n", g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name);
return 1;
} else {
SS7_INFO("LinkSet \"%s\" Enable: OK\n", g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name);
}
/* set the SNGSS7_ACTIVE flag */
g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags |= SNGSS7_ACTIVE;
} /* if !SNGSS7_ACTIVE */
x++;
} /* while (x < (MAX_MTP_LINKSETS+1)) */
}
}
if(SNG_SS7_OPR_MODE_M2UA_SG == g_ftdm_operating_mode){
return ftmod_ss7_m2ua_start();
}
return 0;
@ -779,7 +757,14 @@ int ftmod_ss7_disable_grp_mtp3Link(uint32_t procId)
cntrl.t.cntrl.action = AUBND_DIS; /* disable and unbind */
cntrl.t.cntrl.subAction = SAGR_DSTPROCID; /* specificed element */
return (sng_cntrl_mtp3(&pst, &cntrl));
if (g_ftdm_sngss7_data.cfg.procId == procId) {
SS7_DEBUG("Executing MTP3 cntrl command local pid =%i\n",procId);
return (sng_cntrl_mtp3(&pst, &cntrl));
} else {
SS7_WARN("Executing MTP3 cntrl command different local=%i target=%i\n",
g_ftdm_sngss7_data.cfg.procId,procId);
return (sng_cntrl_mtp3_nowait(&pst, &cntrl));
}
}
@ -811,7 +796,14 @@ int ftmod_ss7_enable_grp_mtp3Link(uint32_t procId)
cntrl.t.cntrl.action = ABND_ENA; /* bind and enable */
cntrl.t.cntrl.subAction = SAGR_DSTPROCID; /* specificed element */
return (sng_cntrl_mtp3(&pst, &cntrl));
if (g_ftdm_sngss7_data.cfg.procId == procId) {
SS7_DEBUG("Executing MTP3 cntrl command local pid =%i\n",procId);
return (sng_cntrl_mtp3(&pst, &cntrl));
} else {
SS7_WARN("Executing MTP3 cntrl command different local=%i target=%i\n",
g_ftdm_sngss7_data.cfg.procId,procId);
return (sng_cntrl_mtp3_nowait(&pst, &cntrl));
}
}
@ -848,7 +840,7 @@ int ftmod_ss7_disable_grp_mtp2Link(uint32_t procId)
}
/******************************************************************************/
int ftmod_ss7_block_isup_ckt(uint32_t cktId)
int __ftmod_ss7_block_isup_ckt(uint32_t cktId, ftdm_bool_t wait)
{
SiMngmt cntrl;
Pst pst;
@ -876,7 +868,11 @@ int ftmod_ss7_block_isup_ckt(uint32_t cktId)
cntrl.t.cntrl.action = ADISIMM; /* block via BLO */
cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */
return (sng_cntrl_isup(&pst, &cntrl));
if (wait == FTDM_TRUE) {
return (sng_cntrl_isup(&pst, &cntrl));
} else {
return (sng_cntrl_isup_nowait(&pst, &cntrl));
}
}
/******************************************************************************/

View File

@ -33,6 +33,7 @@
* Contributors:
*
* Ricardo Barroetaveña <rbarroetavena@anura.com.ar>
* James Zhang <jzhang@sangoma.com>
*
*/
@ -87,6 +88,8 @@ ftdm_status_t handle_olm_msg(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/* FUNCTIONS ******************************************************************/
#define ftdm_running_return(var) if (!ftdm_running()) { SS7_ERROR("Error: ftdm_running is not set! Ignoring\n"); return var; }
ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt)
{
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
@ -94,9 +97,11 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
char var[FTDM_DIGITS_LIMIT];
memset(var, '\0', sizeof(var));
ftdm_running_return(FTDM_FAIL);
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
@ -118,11 +123,24 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/* as per Q.764, 2.8.2.3 xiv ... remove the block from this channel */
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX);
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX_DN);
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX);
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX_DN);
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX);
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX_DN);
/* KONRAD FIX ME : check in case there is a ckt and grp block */
}
sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_TX);
sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_SENT);
sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_RX);
sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_RX_DN);
sngss7_clear_ckt_flag(sngss7_info, FLAG_INF_TX);
sngss7_clear_ckt_flag(sngss7_info, FLAG_INF_SENT);
sngss7_clear_ckt_flag(sngss7_info, FLAG_INF_RX);
sngss7_clear_ckt_flag(sngss7_info, FLAG_INF_RX_DN);
sngss7_clear_ckt_flag(sngss7_info, FLAG_FULL_NUMBER);
/* check whether the ftdm channel is in a state to accept a call */
switch (ftdmchan->state) {
@ -167,6 +185,12 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/* fill in ANI */
ftdm_set_string(ftdmchan->caller_data.ani.digits, ftdmchan->caller_data.cid_num.digits);
}
else {
if (g_ftdm_sngss7_data.cfg.force_inr) {
sngss7_set_ckt_flag(sngss7_info, FLAG_INR_TX);
sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_SENT);
}
}
if (siConEvnt->cgPtyNum.scrnInd.pres) {
/* fill in the screening indication value */
@ -178,6 +202,11 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
ftdmchan->caller_data.pres = siConEvnt->cgPtyNum.presRest.val;
}
} else {
if (g_ftdm_sngss7_data.cfg.force_inr) {
sngss7_set_ckt_flag(sngss7_info, FLAG_INR_TX);
sngss7_clear_ckt_flag(sngss7_info, FLAG_INR_SENT);
}
SS7_INFO_CHAN(ftdmchan,"No Calling party (ANI) information in IAM!%s\n", " ");
}
@ -192,12 +221,16 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
} else {
SS7_INFO_CHAN(ftdmchan,"No Called party (DNIS) information in IAM!%s\n", " ");
}
copy_NatureOfConnection_from_sngss7(ftdmchan, &siConEvnt->natConInd);
copy_fwdCallInd_hex_from_sngss7(ftdmchan, &siConEvnt->fwdCallInd);
copy_access_transport_from_sngss7(ftdmchan, &siConEvnt->accTrnspt);
copy_ocn_from_sngss7(ftdmchan, &siConEvnt->origCdNum);
copy_redirgNum_from_sngss7(ftdmchan, &siConEvnt->redirgNum);
copy_redirgInfo_from_sngss7(ftdmchan, &siConEvnt->redirInfo);
copy_genNmb_from_sngss7(ftdmchan, &siConEvnt->genNmb);
copy_cgPtyCat_from_sngss7(ftdmchan, &siConEvnt->cgPtyCat);
copy_cdPtyNum_from_sngss7(ftdmchan, &siConEvnt->cdPtyNum);
/* fill in the TMR/bearer capability */
if (siConEvnt->txMedReq.eh.pres) {
@ -213,9 +246,6 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sprintf(var, "%d", siConEvnt->cgPtyNum.natAddrInd.val);
sngss7_add_var(sngss7_info, "ss7_clg_nadi", var);
sprintf(var, "%d", siConEvnt->cdPtyNum.natAddrInd.val);
sngss7_add_var(sngss7_info, "ss7_cld_nadi", var);
/* Retrieve the Location Number if present (see ITU Q.763, 3.30) */
if (siConEvnt->cgPtyNum1.eh.pres) {
if (siConEvnt->cgPtyNum1.addrSig.pres) {
@ -247,7 +277,8 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sprintf(var, "%d", sngss7_info->circuit->cic);
sngss7_add_var(sngss7_info, "ss7_cic", var);
sprintf(var, "%d", g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].spc );
sprintf(var, "%d", g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].dpc );
sngss7_add_var(sngss7_info, "ss7_opc", var);
if (siConEvnt->callRef.callId.pres) {
@ -308,24 +339,26 @@ handle_glare:
/* setup the hangup cause */
ftdmchan->caller_data.hangup_cause = 34; /* Circuit Congrestion */
/* this is a remote hangup request */
sngss7_set_ckt_flag(sngss7_info, FLAG_REMOTE_REL);
/* move the state of the channel to Terminating to end the call */
/* move the state of the channel to Terminating to end the call
in TERMINATING state, the release cause is set to REMOTE_REL
in any means. So we don't have to set the release reason here.
*/
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
} /* if (!(sngss7_test_ckt_flag(sngss7_info, FLAG_GLARE))) */
}
break;
/**************************************************************************/
default: /* should not have gotten an IAM while in this state */
SS7_ERROR_CHAN(ftdmchan, "Got IAM on channel in invalid state(%s)...reset!\n", ftdm_channel_state2str (ftdmchan->state));
/* reset the cic */
sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX);
/* move the state of the channel to RESTART to force a reset */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
/* throw the TX reset flag */
if (!sngss7_tx_reset_status_pending(sngss7_info)) {
sngss7_tx_reset_restart(sngss7_info);
sngss7_set_ckt_flag (sngss7_info, FLAG_REMOTE_REL);
/* go to RESTART */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
}
break;
/**************************************************************************/
} /* switch (ftdmchan->state) */
@ -344,6 +377,8 @@ ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_chan_data_t *sngss7_info ;
ftdm_channel_t *ftdmchan;
ftdm_running_return(FTDM_FAIL);
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@ -389,11 +424,14 @@ ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circ
SS7_ERROR_CHAN(ftdmchan, "RX ACM in invalid state :%s...resetting CIC\n",
ftdm_channel_state2str (ftdmchan->state));
/* reset the cic */
sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX);
/* throw the TX reset flag */
if (!sngss7_tx_reset_status_pending(sngss7_info)) {
sngss7_tx_reset_restart(sngss7_info);
sngss7_set_ckt_flag (sngss7_info, FLAG_REMOTE_REL);
/* go to RESTART */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
/* go to RESTART */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
}
break;
/**********************************************************************/
} /* switch (ftdmchan->state) */
@ -422,10 +460,26 @@ ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/**************************************************************************/
case (INFORMATION):
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx INF\n", sngss7_info->circuit->cic);
SS7_DEBUG_CHAN (ftdmchan, "Cancelling T.39 timer %s\n", " ");
/* check if t39 is active */
if (sngss7_info->t39.hb_timer_id) {
ftdm_sched_cancel_timer (sngss7_info->t39.sched, sngss7_info->t39.hb_timer_id);
SS7_DEBUG_CHAN (ftdmchan, "T.39 timer has been cancelled upon receiving INF message %s\n", " ");
}
sngss7_set_ckt_flag(sngss7_info, FLAG_INF_RX_DN);
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_IDLE);
break;
/**************************************************************************/
case (INFORMATREQ):
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx INR\n", sngss7_info->circuit->cic);
ft_to_sngss7_inf(ftdmchan, siCnStEvnt);
sngss7_set_ckt_flag(sngss7_info, FLAG_INR_RX);
break;
/**************************************************************************/
case (SUBSADDR):
@ -599,6 +653,8 @@ ftdm_status_t handle_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_chan_data_t *sngss7_info ;
ftdm_channel_t *ftdmchan;
ftdm_running_return(FTDM_FAIL);
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@ -651,10 +707,13 @@ ftdm_status_t handle_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circ
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx ANM/CON\n", sngss7_info->circuit->cic);
/* throw the TX reset flag */
sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX);
if (!sngss7_tx_reset_status_pending(sngss7_info)) {
sngss7_tx_reset_restart(sngss7_info);
sngss7_set_ckt_flag (sngss7_info, FLAG_REMOTE_REL);
/* go to RESTART */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
/* go to RESTART */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
}
break;
/**************************************************************************/
@ -674,6 +733,8 @@ ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_chan_data_t *sngss7_info ;
ftdm_channel_t *ftdmchan;
ftdm_running_return(FTDM_FAIL);
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@ -750,6 +811,10 @@ ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/* send out the release complete */
ft_to_sngss7_rlc (ftdmchan);
} else {
SS7_DEBUG_CHAN(ftdmchan, "Collision of REL messages - resetting state.\n", " ");
ft_to_sngss7_rlc (ftdmchan);
goto rel_ind_reset;
}
break;
/**************************************************************************/
@ -772,11 +837,15 @@ ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/**************************************************************************/
default:
/* throw the reset flag */
sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_RX);
rel_ind_reset:
/* throw the TX reset flag */
if (!sngss7_tx_reset_status_pending(sngss7_info)) {
sngss7_set_ckt_flag (sngss7_info, FLAG_REMOTE_REL);
sngss7_tx_reset_restart(sngss7_info);
/* set the state to RESTART */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
/* go to RESTART */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
}
break;
/**************************************************************************/
} /* switch (ftdmchan->state) */
@ -796,6 +865,8 @@ ftdm_status_t handle_rel_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_chan_data_t *sngss7_info ;
ftdm_channel_t *ftdmchan;
ftdm_running_return(FTDM_FAIL);
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@ -847,6 +918,8 @@ ftdm_status_t handle_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_chan_data_t *sngss7_info ;
ftdm_channel_t *ftdmchan;
ftdm_running_return(FTDM_FAIL);
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@ -874,6 +947,8 @@ ftdm_status_t handle_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_chan_data_t *sngss7_info ;
ftdm_channel_t *ftdmchan;
ftdm_running_return(FTDM_FAIL);
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@ -901,6 +976,8 @@ ftdm_status_t handle_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_chan_data_t *sngss7_info ;
ftdm_channel_t *ftdmchan;
ftdm_running_return(FTDM_FAIL);
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@ -928,6 +1005,8 @@ ftdm_status_t handle_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t cir
sngss7_chan_data_t *sngss7_info ;
ftdm_channel_t *ftdmchan;
ftdm_running_return(FTDM_FAIL);
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@ -955,6 +1034,8 @@ ftdm_status_t handle_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t cir
sngss7_chan_data_t *sngss7_info ;
ftdm_channel_t *ftdmchan;
ftdm_running_return(FTDM_FAIL);
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@ -982,6 +1063,8 @@ ftdm_status_t handle_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t cir
sngss7_chan_data_t *sngss7_info ;
ftdm_channel_t *ftdmchan;
ftdm_running_return(FTDM_FAIL);
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@ -1006,6 +1089,8 @@ ftdm_status_t handle_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t cir
ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
{
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is active on our side otherwise move to the next circuit */
if (!sngss7_test_flag(&g_ftdm_sngss7_data.cfg.isupCkt[circuit], SNGSS7_ACTIVE)) {
@ -1098,11 +1183,12 @@ ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
break;
/**************************************************************************/
case SIT_STA_CGBRSP: /* mntc. oriented CGB response */
/*handle_cgb_req(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);*/
SS7_INFO(" Rx CGBA \n");
break;
/**************************************************************************/
case SIT_STA_CGURSP: /* mntc. oriented CGU response */
/*SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));*/
SS7_INFO(" Rx CGUA \n");
break;
/**************************************************************************/
case SIT_STA_GRSREQ: /* circuit group reset request */
@ -1206,6 +1292,8 @@ ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t ci
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -1235,6 +1323,7 @@ ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t ci
/* the glare flag is already up so it was caught ... do nothing */
SS7_DEBUG_CHAN(ftdmchan, "Glare flag is already up...nothing to do!%s\n", " ");
} else {
int bHangup = 0;
SS7_DEBUG_CHAN(ftdmchan, "Glare flag is not up yet...indicating glare from reattempt!%s\n", " ");
/* glare, throw the flag */
sngss7_set_ckt_flag(sngss7_info, FLAG_GLARE);
@ -1242,14 +1331,45 @@ ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t ci
/* clear any existing glare data from the channel */
memset(&sngss7_info->glare, 0x0, sizeof(sngss7_glare_data_t));
if (g_ftdm_sngss7_data.cfg.glareResolution == SNGSS7_GLARE_DOWN) {
/* If I'm in DOWN mode, I will always hangup my call. */
bHangup = 1;
}
else if (g_ftdm_sngss7_data.cfg.glareResolution == SNGSS7_GLARE_PC) {
/* I'm in PointCode mode.
Case 1: My point code is higher than the other side.
If the CIC number is even, I'm trying to control.
If the CIC number is odd, I'll hangup my call and back off.
Case 2: My point code is lower than the other side.
If the CIC number is odd, I'm trying to control.
If the CIC number is even, I'll hangup my call and back off.
*/
if( g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].spc > g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].dpc )
{
if ((sngss7_info->circuit->cic % 2) == 1 ) {
bHangup = 1;
}
} else {
if( (sngss7_info->circuit->cic % 2) == 0 ) {
bHangup = 1;
}
}
}
else {
/* If I'm in CONTROL mode, I will not hangup my call. */
bHangup = 0;
}
if (bHangup) {
/* setup the hangup cause */
ftdmchan->caller_data.hangup_cause = 34; /* Circuit Congrestion */
/* this is a remote hangup request */
sngss7_set_ckt_flag(sngss7_info, FLAG_REMOTE_REL);
/* move the state of the channel to Terminating to end the call */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
/* move the state of the channel to Terminating to end the call
in TERMINATING state, the release cause is set to REMOTE_REL
in any means. So we don't have to set the release reason here.
*/
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
}
}
/* unlock the channel again before we exit */
@ -1269,6 +1389,8 @@ ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circui
int infId;
int i;
ftdm_running_return(FTDM_FAIL);
/* extract the affected infId from the circuit structure */
infId = g_ftdm_sngss7_data.cfg.isupCkt[circuit].infId;
@ -1333,6 +1455,8 @@ ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circu
ftdm_channel_t *ftdmchan = NULL;
int infId;
int i;
ftdm_running_return(FTDM_FAIL);
/* extract the affect infId from the circuit structure */
infId = g_ftdm_sngss7_data.cfg.isupCkt[circuit].infId;
@ -1397,6 +1521,8 @@ ftdm_status_t handle_cot_start(uint32_t suInstId, uint32_t spInstId, uint32_t ci
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -1452,6 +1578,8 @@ ftdm_status_t handle_cot_stop(uint32_t suInstId, uint32_t spInstId, uint32_t cir
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -1497,6 +1625,8 @@ ftdm_status_t handle_cot(uint32_t suInstId, uint32_t spInstId, uint32_t circuit,
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -1565,6 +1695,8 @@ ftdm_status_t handle_blo_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -1597,6 +1729,7 @@ ftdm_status_t handle_blo_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/* throw the ckt block flag */
sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX);
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX_DN);
/* set the channel to suspended state */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
@ -1615,6 +1748,8 @@ ftdm_status_t handle_blo_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -1656,6 +1791,8 @@ ftdm_status_t handle_ubl_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -1744,6 +1881,8 @@ ftdm_status_t handle_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -1784,6 +1923,7 @@ ftdm_status_t handle_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
default:
/* set the state of the channel to restart...the rest is done by the chan monitor */
sngss7_set_ckt_flag(sngss7_info, FLAG_REMOTE_REL);
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
break;
/**************************************************************************/
@ -1803,6 +1943,8 @@ ftdm_status_t handle_local_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -1861,6 +2003,8 @@ ftdm_status_t handle_rsc_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -1917,7 +2061,7 @@ ftdm_status_t handle_rsc_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX_RSP);
/* go to DOWN */
/*ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);*/
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
break;
/**********************************************************************/
@ -1951,6 +2095,8 @@ ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
ftdm_channel_t *ftdmchan = NULL;
sngss7_span_data_t *sngss7_span = NULL;
int range = 0;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -2008,6 +2154,8 @@ ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ
ftdm_channel_t *ftdmchan = NULL;
sngss7_span_data_t *sngss7_span = NULL;
int range = 0;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -2072,6 +2220,8 @@ ftdm_status_t handle_local_blk(uint32_t suInstId, uint32_t spInstId, uint32_t ci
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -2122,6 +2272,8 @@ ftdm_status_t handle_local_ubl(uint32_t suInstId, uint32_t spInstId, uint32_t ci
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -2177,6 +2329,7 @@ ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit
sngss7_span_data_t *sngss7_span = NULL;
ftdm_channel_t *ftdmchan = NULL;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {
@ -2215,6 +2368,8 @@ ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit
cinfo->ucic.range = cinfo->tx_grs.range;
ftdm_set_flag(sngss7_span, SNGSS7_UCIC_PENDING);
SS7_WARN("Set span SNGSS7_UCIC_PENDING for ISUP circuit = %d!\n", circuit);
ftdm_channel_unlock(fchan);
goto done;
@ -2227,6 +2382,7 @@ ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit
ftdm_mutex_lock(ftdmchan->mutex);
/* throw the ckt block flag */
SS7_DEBUG("Set FLAG_CKT_UCIC_BLOCK for ISUP circuit = %d!\n", circuit);
sngss7_set_ckt_blk_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK);
/* set the channel to suspended state */
@ -2256,7 +2412,10 @@ ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
int blockType = 0;
int byte = 0;
int bit = 0;
int x;
int x;
int loop_range=0;
ftdm_running_return(FTDM_FAIL);
memset(&status[0], '\0', sizeof(status));
@ -2321,61 +2480,56 @@ ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
}
/* loop over the cics starting from circuit until range+1 */
for (x = circuit; x < (circuit + range + 1); x++) {
/* confirm this is a voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[x].type != SNG_CKT_VOICE) continue;
/* grab the circuit in question */
if (extract_chan_data(x, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", x);
break;
loop_range = circuit + range + 1;
x = circuit;
while( x < loop_range ) {
if (g_ftdm_sngss7_data.cfg.isupCkt[x].type != SNG_CKT_VOICE) {
loop_range++;
}
/* lock the channel */
ftdm_mutex_lock(ftdmchan->mutex);
else {
if (extract_chan_data(x, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", x);
} else {
ftdm_mutex_lock(ftdmchan->mutex);
if (status[byte] & (1 << bit)) {
switch (blockType) {
/**********************************************************************/
case 0: /* maintenance oriented */
sngss7_set_ckt_blk_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX);
break;
/**********************************************************************/
case 1: /* hardware failure oriented */
sngss7_set_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX);
break;
/**********************************************************************/
case 2: /* reserved for national use */
break;
/**********************************************************************/
default:
break;
/**********************************************************************/
}
}
#if 0
SS7_ERROR("KONRAD -> circuit=%d, byte=%d, bit=%d, status[byte]=%d, math=%d\n",
x,
byte,
bit,
status[byte],
(status[byte] & (1 << bit)));
#endif
if (status[byte] & (1 << bit)) {
switch (blockType) {
/**********************************************************************/
case 0: /* maintenance oriented */
sngss7_set_ckt_blk_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX);
break;
/**********************************************************************/
case 1: /* hardware failure oriented */
sngss7_set_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX);
break;
/**********************************************************************/
case 2: /* reserved for national use */
break;
/**********************************************************************/
default:
break;
/**********************************************************************/
} /* switch (blockType) */
/* bring the sig status down */
sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_DOWN);
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);
/* update the bit and byte counter*/
bit ++;
if (bit == 8) {
byte++;
bit = 0;
}
}
}
x++;
}
/* bring the sig status down */
sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_DOWN);
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);
/* update the bit and byte counter*/
bit ++;
if (bit == 8) {
byte++;
bit = 0;
}
} /* for (x = circuit; x < (circuit + range + 1); x++) */
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@ -2402,8 +2556,11 @@ ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
int blockType = 0;
int byte = 0;
int bit = 0;
int x;
int x;
int loop_range=0;
ftdm_sigmsg_t sigev;
ftdm_running_return(FTDM_FAIL);
memset(&sigev, 0, sizeof (sigev));
memset(&status[0], '\0', sizeof(status));
@ -2470,57 +2627,62 @@ ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
}
/* loop over the cics starting from circuit until range+1 */
for (x = circuit; x < (circuit + range + 1); x++) {
if (g_ftdm_sngss7_data.cfg.isupCkt[x].type != SNG_CKT_VOICE) continue;
/* grab the circuit in question */
if (extract_chan_data(x, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", x);
break;
loop_range = circuit + range + 1;
x = circuit;
while( x < loop_range ) {
if (g_ftdm_sngss7_data.cfg.isupCkt[x].type != SNG_CKT_VOICE) {
loop_range++;
} else {
if (extract_chan_data(x, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", x);
}
else {
ftdm_mutex_lock(ftdmchan->mutex);
if (status[byte] & (1 << bit)) {
switch (blockType) {
/**********************************************************************/
case 0: /* maintenance oriented */
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX);
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX);
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX_DN);
break;
/**********************************************************************/
case 1: /* hardware failure oriented */
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX);
break;
/**********************************************************************/
case 2: /* reserved for national use */
break;
/**********************************************************************/
default:
break;
/**********************************************************************/
} /* switch (blockType) */
} /* if (status[byte] & (1 << bit)) */
sigev.chan_id = ftdmchan->chan_id;
sigev.span_id = ftdmchan->span_id;
sigev.channel = ftdmchan;
/* bring the sig status down */
if (sngss7_channel_status_clear(sngss7_info)) {
sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_UP);
}
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
ftdm_mutex_unlock(ftdmchan->mutex);
/* update the bit and byte counter*/
bit ++;
if (bit == 8) {
byte++;
bit = 0;
}
}
}
/* lock the channel */
ftdm_mutex_lock(ftdmchan->mutex);
if (status[byte] & (1 << bit)) {
switch (blockType) {
/**********************************************************************/
case 0: /* maintenance oriented */
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX);
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX);
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX_DN);
break;
/**********************************************************************/
case 1: /* hardware failure oriented */
sngss7_clear_ckt_blk_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX);
break;
/**********************************************************************/
case 2: /* reserved for national use */
break;
/**********************************************************************/
default:
break;
/**********************************************************************/
} /* switch (blockType) */
} /* if (status[byte] & (1 << bit)) */
sigev.chan_id = ftdmchan->chan_id;
sigev.span_id = ftdmchan->span_id;
sigev.channel = ftdmchan;
/* bring the sig status down */
sngss7_set_sig_status(sngss7_info, FTDM_SIG_STATE_UP);
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);
/* update the bit and byte counter*/
bit ++;
if (bit == 8) {
byte++;
bit = 0;
}
} /* for (x = circuit; x < (circuit + range + 1); x++) */
x++;
}
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@ -2541,6 +2703,8 @@ ftdm_status_t handle_olm_msg(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
ftdm_running_return(FTDM_FAIL);
/* confirm that the circuit is voice channel */
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].type != SNG_CKT_VOICE) {

View File

@ -81,6 +81,7 @@ void sngss7_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCo
/* initalize the sngss7_event */
sngss7_event = ftdm_malloc(sizeof(*sngss7_event));
if (sngss7_event == NULL) {
SS7_ERROR("Failed to allocate memory for sngss7_event!\n");
SS7_FUNC_TRACE_EXIT(__FUNCTION__);

View File

@ -114,6 +114,7 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
{
char buf[50];
int x = 1;
int log_level = FTDM_LOG_LEVEL_DEBUG;
memset(buf, '\0', sizeof(buf));
@ -158,11 +159,22 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
break;
case (LCM_CAUSE_UNKNOWN):
default:
ftdm_log(FTDM_LOG_DEBUG,"[MTP2]%s cause:%s event:%s\n",
buf,
DECODE_LCM_CAUSE(sta->t.usta.alarm.cause),
DECODE_LSD_EVENT(sta->t.usta.alarm.event));
break;
{
if ((LSD_EVENT_ALIGN_LOST == sta->t.usta.alarm.event) ||
(LSD_EVENT_PROT_ST_DN == sta->t.usta.alarm.event)) {
log_level = FTDM_LOG_LEVEL_WARNING;
} else if ((LSD_EVENT_LINK_ALIGNED == sta->t.usta.alarm.event) ||
(LSD_EVENT_PROT_ST_UP == sta->t.usta.alarm.event)){
log_level = FTDM_LOG_LEVEL_INFO;
} else {
log_level = FTDM_LOG_LEVEL_WARNING;
}
ftdm_log(FTDM_PRE, log_level,"[MTP2]%s cause:%s event:%s\n",
buf,
DECODE_LCM_CAUSE(sta->t.usta.alarm.cause),
DECODE_LSD_EVENT(sta->t.usta.alarm.event));
break;
}
/******************************************************************/
} /* switch (sta->t.usta.alarm.cause) */
break;
@ -184,7 +196,7 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp2Link[x].name);
}
ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : %s\n",
ftdm_log(FTDM_LOG_WARNING,"[MTP2]%s %s : %s\n",
buf,
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
DECODE_LSD_CAUSE(sta->t.usta.alarm.cause));
@ -207,7 +219,7 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp2Link[x].name);
}
ftdm_log(FTDM_LOG_DEBUG,"[MTP2]%s %s : %s\n",
ftdm_log(FTDM_LOG_WARNING,"[MTP2]%s %s : %s\n",
buf,
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
DECODE_DISC_REASON(sta->t.usta.evntParm[1]));
@ -231,7 +243,7 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp2Link[x].name);
}
ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : RTB Queue Len(%d)|Oldest BSN(%d)|Tx Queue Len(%d)|Outstanding Frames(%d)\n",
ftdm_log(FTDM_LOG_WARNING,"[MTP2]%s %s : RTB Queue Len(%d)|Oldest BSN(%d)|Tx Queue Len(%d)|Outstanding Frames(%d)\n",
buf,
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
sta->t.usta.evntParm[1],
@ -257,7 +269,7 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp2Link[x].name);
}
ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : RTB Queue Len(%d)\n",
ftdm_log(FTDM_LOG_WARNING,"[MTP2]%s %s : RTB Queue Len(%d)\n",
buf,
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
sta->t.usta.evntParm[1]);
@ -280,7 +292,7 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp2Link[x].name);
}
ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : %d\n",
ftdm_log(FTDM_LOG_WARNING,"[MTP2]%s %s : %d\n",
buf,
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
DECODE_DISC_REASON(sta->t.usta.evntParm[1]));
@ -288,7 +300,7 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
/**********************************************************************/
case (LCM_EVENT_UI_INV_EVT):
case (LCM_EVENT_LI_INV_EVT):
ftdm_log(FTDM_LOG_ERROR,"[MTP2] %s(%d) : %s(%d) : Primitive (%d)\n",
ftdm_log(FTDM_LOG_WARNING,"[MTP2] %s(%d) : %s(%d) : Primitive (%d)\n",
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
sta->t.usta.alarm.event,
DECODE_LCM_CAUSE(sta->t.usta.alarm.cause),
@ -302,14 +314,14 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
/******************************************************************/
case (LCM_CAUSE_UNKNOWN):
case (LCM_CAUSE_SWVER_NAVAIL):
ftdm_log(FTDM_LOG_ERROR,"[MTP2] %s : %s : Event (%d)\n",
ftdm_log(FTDM_LOG_WARNING,"[MTP2] %s : %s : Event (%d)\n",
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
DECODE_LCM_CAUSE(sta->t.usta.alarm.cause),
sta->t.usta.evntParm[0]);
break;
/******************************************************************/
case (LCM_CAUSE_DECODE_ERR):
ftdm_log(FTDM_LOG_ERROR,"[MTP2] %s : %s : Primitive (%d)|Version (%d)\n",
ftdm_log(FTDM_LOG_WARNING,"[MTP2] %s : %s : Primitive (%d)|Version (%d)\n",
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
DECODE_LCM_CAUSE(sta->t.usta.alarm.cause),
sta->t.usta.evntParm[0],
@ -317,7 +329,7 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
break;
/******************************************************************/
default:
ftdm_log(FTDM_LOG_ERROR,"[MTP2] %s(%d) : %s(%d)\n",
ftdm_log(FTDM_LOG_WARNING,"[MTP2] %s(%d) : %s(%d)\n",
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
sta->t.usta.alarm.event,
DECODE_LSD_CAUSE(sta->t.usta.alarm.cause),
@ -328,7 +340,7 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
break;
/**********************************************************************/
default:
ftdm_log(FTDM_LOG_ERROR,"[MTP2] %s(%d) : %s(%d)\n",
ftdm_log(FTDM_LOG_WARNING,"[MTP2] %s(%d) : %s(%d)\n",
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
sta->t.usta.alarm.event,
DECODE_LSD_CAUSE(sta->t.usta.alarm.cause),
@ -381,7 +393,7 @@ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta)
/**********************************************************************/
case (LSN_EVENT_INV_OPC_OTHER_END):
ftdm_log(FTDM_LOG_ERROR,"[MTP3]%s %s : %s : OPC(0x%X%X%X%X)\n",
ftdm_log(FTDM_LOG_WARNING,"[MTP3]%s %s : %s : OPC(0x%X%X%X%X)\n",
buf,
DECODE_LSN_EVENT(sta->t.usta.alarm.event),
DECODE_LSN_CAUSE(sta->t.usta.alarm.cause),
@ -392,7 +404,7 @@ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta)
break;
/**********************************************************************/
case (LSN_EVENT_INV_SLC_OTHER_END):
ftdm_log(FTDM_LOG_ERROR,"[MTP3]%s %s : %s : SLC(%d)\n",
ftdm_log(FTDM_LOG_WARNING,"[MTP3]%s %s : %s : SLC(%d)\n",
buf,
DECODE_LSN_EVENT(sta->t.usta.alarm.event),
DECODE_LSN_CAUSE(sta->t.usta.alarm.cause),
@ -400,7 +412,7 @@ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta)
break;
/**********************************************************************/
default:
ftdm_log(FTDM_LOG_DEBUG,"[MTP3]%s %s(%d) : %s(%d)\n",
ftdm_log(FTDM_LOG_WARNING,"[MTP3]%s %s(%d) : %s(%d)\n",
buf,
DECODE_LSN_EVENT(sta->t.usta.alarm.event),
sta->t.usta.alarm.event,
@ -412,7 +424,7 @@ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta)
break;
/**************************************************************************/
case (STNSAP):
ftdm_log(FTDM_LOG_ERROR,"[MTP3][SAPID:%d] %s : %s\n",
ftdm_log(FTDM_LOG_WARNING,"[MTP3][SAPID:%d] %s : %s\n",
sta->hdr.elmId.elmntInst1,
DECODE_LSN_EVENT(sta->t.usta.alarm.event),
DECODE_LSN_CAUSE(sta->t.usta.alarm.cause));
@ -463,7 +475,7 @@ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta)
break;
/**********************************************************************/
default:
ftdm_log(FTDM_LOG_ERROR,"[MTP3][DPC:0x%X%X%X%X] %s : %s\n",
ftdm_log(FTDM_LOG_WARNING,"[MTP3][DPC:0x%X%X%X%X] %s : %s\n",
sta->t.usta.evntParm[0],
sta->t.usta.evntParm[1],
sta->t.usta.evntParm[2],
@ -733,7 +745,7 @@ void handle_sng_isup_alarm(Pst *pst, SiMngmt *sta)
} /* switch (sta->t.usta.dgn.dgnVal[x].t.type) */
} /* for (x = 0; x < 5; x++) */
ftdm_log(FTDM_LOG_ERROR,"%s %s : %s\n",
ftdm_log(FTDM_LOG_WARNING,"%s %s : %s\n",
msg,
DECODE_LSI_EVENT(sta->t.usta.alarm.event),
DECODE_LSI_CAUSE(sta->t.usta.alarm.cause));
@ -759,7 +771,7 @@ void handle_sng_relay_alarm(Pst *pst, RyMngmt *sta)
switch (sta->hdr.elmId.elmnt) {
/**************************************************************************/
case (LRY_USTA_ERR): /* ERROR */
ftdm_log(FTDM_LOG_ERROR,"[RELAY] Error: tx procId %d: err procId %d: channel %d: seq %s: reason %s\n",
ftdm_log(FTDM_LOG_WARNING,"[RELAY] Error: tx procId %d: err procId %d: channel %d: seq %s: reason %s\n",
sta->t.usta.s.ryErrUsta.sendPid,
sta->t.usta.s.ryErrUsta.errPid,
sta->t.usta.s.ryErrUsta.id,
@ -783,7 +795,7 @@ void handle_sng_relay_alarm(Pst *pst, RyMngmt *sta)
break;
/**************************************************************************/
case (LRY_USTA_CNG): /* Congestion */
ftdm_log(FTDM_LOG_ERROR,"[RELAY] Congestion: tx procId %d: rem procId %d: channel %d: %s\n",
ftdm_log(FTDM_LOG_WARNING,"[RELAY] Congestion: tx procId %d: rem procId %d: channel %d: %s\n",
sta->t.usta.s.ryCongUsta.sendPid,
sta->t.usta.s.ryCongUsta.remPid,
sta->t.usta.s.ryCongUsta.id,
@ -791,7 +803,7 @@ void handle_sng_relay_alarm(Pst *pst, RyMngmt *sta)
break;
/**************************************************************************/
case (LRY_USTA_UP): /* channel up */
ftdm_log(FTDM_LOG_ERROR,"[RELAY] Channel UP: tx procId %d: channel %d\n",
ftdm_log(FTDM_LOG_INFO,"[RELAY] Channel UP: tx procId %d: channel %d\n",
sta->t.usta.s.ryUpUsta.sendPid,
sta->t.usta.s.ryUpUsta.id);
@ -801,7 +813,7 @@ void handle_sng_relay_alarm(Pst *pst, RyMngmt *sta)
break;
/**************************************************************************/
case (LRY_USTA_DN): /* channel down */
ftdm_log(FTDM_LOG_ERROR,"[RELAY] Channel DOWN: tx procId %d: channel %d\n",
ftdm_log(FTDM_LOG_WARNING,"[RELAY] Channel DOWN: tx procId %d: channel %d\n",
sta->t.usta.s.ryUpUsta.sendPid,
sta->t.usta.s.ryUpUsta.id);
@ -810,6 +822,11 @@ void handle_sng_relay_alarm(Pst *pst, RyMngmt *sta)
break;
/**************************************************************************/
case (LRY_USTA_TCP_CONN_FAILED):
ftdm_log(FTDM_LOG_WARNING,"[RELAY] TCP connection failed \n" );
break;
/**************************************************************************/
default:
ftdm_log(FTDM_LOG_ERROR,"Unknown Relay Alram\n");
break;
@ -819,6 +836,311 @@ void handle_sng_relay_alarm(Pst *pst, RyMngmt *sta)
return;
}
/******************************************************************************/
void handle_sng_m2ua_alarm(Pst *pst, MwMgmt *sta)
{
/* To print the general information */
ftdm_log(FTDM_LOG_INFO, "Recieved a status indication from M2UA layer \n\n");
ftdm_log(FTDM_LOG_INFO," Category = %d , event = %d , cause = %d\n",
sta->t.usta.alarm.category, sta->t.usta.alarm.event, sta->t.usta.alarm.cause);
/* To print the affected element value */
switch(sta->hdr.elmId.elmnt)
{
case STMWDLSAP:
{
ftdm_log(FTDM_LOG_INFO," STMWDLSAP: with lnkNmb (%d) \n\n",
sta->t.usta.s.lnkNmb);
break;
}
case STMWSCTSAP:
{
ftdm_log(FTDM_LOG_INFO," STMWSCTSAP: suId (%d) \n\n",
sta->t.usta.s.suId);
break;
}
case STMWPEER:
{
ftdm_log(FTDM_LOG_INFO," STMWPEER: peerId (%d) \n\n",
sta->t.usta.s.peerId);
break;
}
case STMWCLUSTER:
{
ftdm_log(FTDM_LOG_INFO," STMWCLUSTER: clusterId (%d) \n\n",
sta->t.usta.s.peerId);
break;
}
default:
{
ftdm_log(FTDM_LOG_ERROR, "[MW_USTA]: Invalid element \n\n");
break;
}
}
/* To print the event specific information */
switch(sta->t.usta.alarm.event)
{
case LMW_EVENT_TERM_OK:
{
ftdm_log(FTDM_LOG_INFO," M2UA : LMW_EVENT_TERM_OK: Association Terminated with PeerId[%d] \n",sta->t.usta.s.peerId);
break;
}
case LMW_EVENT_ENDPOPEN_OK:
{
ftdm_log(FTDM_LOG_INFO," M2UA : LMW_EVENT_ENDPOPEN_OK: \n");
break;
}
case LMW_EVENT_ESTABLISH_OK:
{
ftdm_log(FTDM_LOG_INFO," M2UA : LMW_EVENT_ESTABLISH_OK Event raised on peerId[%d]\n",sta->t.usta.s.peerId);
break;
}
case LMW_EVENT_ESTABLISH_FAIL:
{
ftdm_log(FTDM_LOG_INFO," M2UA : LMW_EVENT_ESTABLISH_FAIL Event raised on peerId[%d]\n",sta->t.usta.s.peerId);
break;
}
case LMW_EVENT_ASPM:
{
ftdm_log(FTDM_LOG_INFO," M2UA : LMW_EVENT_ASPM Event raised with peerId (%d), aspId (%d),"
" msgType (%d)\n\n",sta->t.usta.s.peerId,
sta->t.usta.t.aspm.msgType);
break;
}
case LMW_EVENT_CLUSTER:
{
ftdm_log(FTDM_LOG_INFO," M2UA : LMW_EVENT_CLUSTER Event raised on clusterId (%d), state (%d)\n\n",
sta->t.usta.s.clusterId, sta->t.usta.t.cluster.state);
break;
}
case LMW_EVENT_NOTIFY:
{
ftdm_log(FTDM_LOG_INFO," M2UA : LMW_EVENT_NOTIFY: peerId (%d), aspId (%d), ntfy status type (%d),"
" ntfy status id (%d)\n\n", sta->t.usta.s.peerId,
sta->t.usta.t.ntfy.aspId, sta->t.usta.t.ntfy.stType,
sta->t.usta.t.ntfy.stId);
break;
}
case LMW_EVENT_M2UA_PROTO_ERROR:
{
ftdm_log(FTDM_LOG_ERROR, " M2UA : LMW_EVENT_M2UA_PROTO_ERROR with errorCode (%d)\n\n",
sta->t.usta.t.error.errCode);
break;
}
default:
break;
}
} /* handle_sng_m2ua_alarm */
/******************************************************************************/
void handle_sng_nif_alarm(Pst *pst, NwMgmt *sta)
{
/* To print the general information */
ftdm_log(FTDM_LOG_INFO," Recieved a status indication from NIF layer\n");
ftdm_log(FTDM_LOG_INFO," Category = %d , event = %d , cause = %d\n", sta->t.usta.alarm.category,
sta->t.usta.alarm.event, sta->t.usta.alarm.cause);
switch(sta->hdr.elmId.elmnt)
{
case STNWDLSAP:
{
ftdm_log(FTDM_LOG_INFO," Recieved STNWDLSAP status indication for suId (%d) \n", sta->t.usta.suId);
switch(sta->t.usta.alarm.event)
{
case LCM_EVENT_LI_INV_EVT:
{
switch(sta->t.usta.alarm.cause)
{
case LCM_CAUSE_INV_SAP:
{
ftdm_log(FTDM_LOG_ERROR, " LCM_CAUSE_INV_SAP Alarm \n");
break;
}
case LCM_CAUSE_INV_STATE:
{
ftdm_log(FTDM_LOG_ERROR, " LCM_CAUSE_INV_STATE Alarm \n");
break;
}
default:
break;
}
break;
}
case LCM_EVENT_BND_OK:
{
ftdm_log(FTDM_LOG_INFO," NIF: LCM_EVENT_BND_OK Alarm \n");
break;
}
case LCM_EVENT_BND_FAIL:
{
ftdm_log(FTDM_LOG_INFO," NIF: LCM_EVENT_BND_FAIL Alarm \n");
break;
}
default:
break;
}
break;
}
default:
break;
}
} /* handle_sng_nif_alarm */
/******************************************************************************/
void handle_sng_tucl_alarm(Pst *pst, HiMngmt *sta)
{
/* To print the general information */
ftdm_log(FTDM_LOG_INFO, "Recieved a status indication from TUCL layer \n\n");
ftdm_log(FTDM_LOG_INFO, " Category = %d , event = %d , cause = %d\n",
sta->t.usta.alarm.category,
sta->t.usta.alarm.event, sta->t.usta.alarm.cause);
switch(sta->t.usta.alarm.event)
{
case LCM_EVENT_INV_EVT:
{
ftdm_log(FTDM_LOG_INFO," [HI_USTA]: LCM_EVENT_INV_EVT with type (%d)\n\n",
sta->t.usta.info.type);
break;
}
case LHI_EVENT_BNDREQ:
{
ftdm_log(FTDM_LOG_INFO," [HI_USTA]: LHI_EVENT_BNDREQ with type (%d) spId (%d)\n\n",
sta->t.usta.info.type, sta->t.usta.info.spId);
break;
}
case LHI_EVENT_SERVOPENREQ:
case LHI_EVENT_DATREQ:
case LHI_EVENT_UDATREQ:
case LHI_EVENT_CONREQ:
case LHI_EVENT_DISCREQ:
#if(defined(HI_TLS) && defined(HI_TCP_TLS))
case LHI_EVENT_TLS_ESTREQ:
#endif
{
ftdm_log(FTDM_LOG_INFO," [HI_USTA]: partype (%d) type(%d)\n\n",
sta->t.usta.info.inf.parType, sta->t.usta.info.type);
break;
}
case LCM_EVENT_DMEM_ALLOC_FAIL:
case LCM_EVENT_SMEM_ALLOC_FAIL:
{
ftdm_log(FTDM_LOG_ERROR," [HI_USTA]: MEM_ALLOC_FAIL with region(%d) pool (%d) type(%d)\n\n",
sta->t.usta.info.inf.mem.region, sta->t.usta.info.inf.mem.pool,
sta->t.usta.info.type);
break;
}
default:
break;
}
} /* handle_sng_tucl_alarm */
/******************************************************************************/
void handle_sng_sctp_alarm(Pst *pst, SbMgmt *sta)
{
ftdm_log(FTDM_LOG_INFO, "Recieved a status indication from SCTP layer \n\n");
ftdm_log(FTDM_LOG_INFO," Category = %d , event = %d , cause = %d "
" [SB_USTA]: sapId (%d) and swtch (%d)\n",
sta->t.usta.alarm.category,
sta->t.usta.alarm.event, sta->t.usta.alarm.cause,
sta->t.usta.sapId, sta->t.usta.swtch);
switch(sta->t.usta.alarm.category)
{
case LCM_CATEGORY_INTERFACE:
{
switch(sta->t.usta.alarm.cause)
{
case LCM_CAUSE_INV_SPID:
{
ftdm_log(FTDM_LOG_ERROR, "SCTP : LCM_CAUSE_INV_SPID Alarm \n");
break;
}
case LCM_CAUSE_SWVER_NAVAIL:
{
ftdm_log(FTDM_LOG_ERROR, "SCTP : LCM_CAUSE_SWVER_NAVAIL Alarm\n");
break;
}
case LCM_CAUSE_INV_PAR_VAL:
{
ftdm_log(FTDM_LOG_ERROR, "SCTP : LCM_CAUSE_INV_PAR_VAL Alarm\n");
break;
}
case LCM_CAUSE_INV_SUID:
{
ftdm_log(FTDM_LOG_ERROR, "SCTP : LCM_CAUSE_INV_SUID Alarm\n");
break;
}
case LCM_CAUSE_INV_SAP:
{
ftdm_log(FTDM_LOG_ERROR, "SCTP : LCM_CAUSE_INV_SAP Alarm\n");
break;
}
default:
break;
}
break;
}
case LCM_CATEGORY_RESOURCE:
{
switch(sta->t.usta.alarm.cause)
{
case LCM_CAUSE_MEM_ALLOC_FAIL:
{
ftdm_log(FTDM_LOG_ERROR, "SCTP : LCM_CAUSE_MEM_ALLOC_FAIL Alarm \n");
break;
}
case LSB_CAUSE_NUM_ADDR_EXCEED:
{
ftdm_log(FTDM_LOG_ERROR, "SCTP : LSB_CAUSE_NUM_ADDR_EXCEED Alarm\n");
break;
}
default:
break;
}
break;
}
case LCM_CATEGORY_PROTOCOL:
{
switch(sta->t.usta.alarm.cause)
{
case LSB_CAUSE_PATH_FAILURE:
{
ftdm_log(FTDM_LOG_ERROR, "SCTP : LSB_CAUSE_PATH_FAILURE Alarm \n");
break;
}
case LSB_CAUSE_PATH_ACTIVE:
{
ftdm_log(FTDM_LOG_ERROR, "SCTP : LSB_CAUSE_PATH_ACTIVE Alarm \n");
break;
}
case LSB_CAUSE_UNRSLVD_ADDR:
{
ftdm_log(FTDM_LOG_ERROR, "SCTP : LSB_CAUSE_UNRSLVD_ADDR Alarm \n");
break;
}
default:
break;
}
break;
}
default:
break;
}
} /* handle_sng_sctp_alarm */
/******************************************************************************/
/******************************************************************************/
/* For Emacs:
* Local Variables:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,136 @@
/*
* Copyright (c) 2012, Kapil Gupta <kgupta@sangoma.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* Contributors:
*
*/
/******************************************************************************/
#ifndef __FTMOD_SNG_SS7_M2UA_H__
#define __FTMOD_SNG_SS7_M2UA_H__
/******************************************************************************/
#include "private/ftdm_core.h"
#define MAX_NAME_LEN 25
typedef struct sng_nif_cfg{
char name[MAX_NAME_LEN];
uint32_t flags;
uint32_t id;
uint32_t m2uaLnkNmb;
uint32_t mtp2LnkNmb;
}sng_nif_cfg_t;
typedef enum{
SNG_M2UA_NODE_TYPE_SGP = 1, /* type SG */
SNG_M2UA_NODE_TYPE_ASP = 2, /* type ASP */
}sng_m2ua_node_types_e;
typedef struct sng_m2ua_cfg{
char name[MAX_NAME_LEN];
uint32_t flags;
uint32_t id; /* ID */
uint32_t iid; /* ID */
uint8_t nodeType; /*Node Type SG/ASP */
uint8_t end_point_opened; /* flag to check is end-point already opened */
uint16_t clusterId; /* idx to m2ua_cluster profile */
}sng_m2ua_cfg_t;
typedef struct sng_m2ua_peer_cfg{
char name[MAX_NAME_LEN];
uint32_t flags;
uint32_t id; /* ID */
uint8_t aspIdFlag; /* Flag used to indicate whether include the ASP ID in the ASP UP message */
uint16_t selfAspId; /* Self ASP ID. ASP identifier for this ASP node if the aspIdFlag is TRUE. */
uint32_t numDestAddr; /* Number of destination address defined */
uint16_t sctpId; /* idx to sctp profile */
uint16_t port;
uint32_t destAddrList[SCT_MAX_NET_ADDRS+1]; /* Destination adddress list */
uint16_t locOutStrms; /*Number of outgoing streams supported by this association*/
int init_sctp_assoc; /* flag to tell if we need to initiate SCTP association */
}sng_m2ua_peer_cfg_t;
typedef enum{
SNG_M2UA_LOAD_SHARE_ALGO_RR = 0x1, /* Round Robin Mode*/
SNG_M2UA_LOAD_SHARE_ALGO_LS = 0x2, /* Link Specified */
SNG_M2UA_LOAD_SHARE_ALGO_CS = 0x3, /* Customer Specified */
}sng_m2ua_load_share_algo_types_e;
/* Possible values of Traffic mode */
typedef enum{
SNG_M2UA_TRF_MODE_OVERRIDE = 0x1, /* Override Mode */
SNG_M2UA_TRF_MODE_LOADSHARE = 0x2, /* Loadshare Mode */
SNG_M2UA_TRF_MODE_BROADCAST = 0x3, /* Broadcast Mode */
SNG_M2UA_TRF_MODE_ANY = 0x0, /* ANY Mode */
}sng_m2ua_traffic_mode_types_e;
typedef struct sng_m2ua_cluster_cfg{
char name[MAX_NAME_LEN];
uint32_t flags;
uint32_t id; /* ID */
uint32_t sct_sap_id; /* Internal - sct_sap_id */
uint8_t trfMode; /* Traffic mode. This parameter defines the mode in which this m2ua cluster is supposed to work */
uint8_t loadShareAlgo; /* This parameter defines the M2UA load share algorithm which is used to distribute the traffic */
uint16_t numOfPeers; /* idx to m2ua_peer profile */
uint16_t peerIdLst[MW_MAX_NUM_OF_PEER]; /* idx to m2ua_peer profile */
}sng_m2ua_cluster_cfg_t;
typedef struct sng_m2ua_gbl_cfg{
sng_nif_cfg_t nif[MW_MAX_NUM_OF_INTF+1];
sng_m2ua_cfg_t m2ua[MW_MAX_NUM_OF_INTF+1];
sng_m2ua_peer_cfg_t m2ua_peer[MW_MAX_NUM_OF_PEER+1];
sng_m2ua_cluster_cfg_t m2ua_clus[MW_MAX_NUM_OF_CLUSTER+1];
}sng_m2ua_gbl_cfg_t;
/* m2ua xml parsing APIs */
int ftmod_ss7_parse_nif_interfaces(ftdm_conf_node_t *nif_interfaces);
int ftmod_ss7_parse_m2ua_interfaces(ftdm_conf_node_t *m2ua_interfaces);
int ftmod_ss7_parse_m2ua_peer_interfaces(ftdm_conf_node_t *m2ua_peer_interfaces);
int ftmod_ss7_parse_m2ua_clust_interfaces(ftdm_conf_node_t *m2ua_clust_interfaces);
int ftmod_ss7_parse_sctp_links(ftdm_conf_node_t *node);
uint32_t iptoul(const char *ip);
int ftmod_ss7_m2ua_start(void);
void ftmod_ss7_m2ua_free(void);
ftdm_status_t ftmod_ss7_m2ua_cfg(void);
ftdm_status_t ftmod_ss7_m2ua_init(void);
int ftmod_sctp_ssta_req(int elemt, int id, SbMgmt* cfm);
int ftmod_m2ua_ssta_req(int elemt, int id, MwMgmt* cfm);
int ftmod_nif_ssta_req(int elemt, int id, NwMgmt* cfm);
void ftmod_ss7_enable_m2ua_sg_logging(void);
void ftmod_ss7_disable_m2ua_sg_logging(void);
#endif /*__FTMOD_SNG_SS7_M2UA_H__*/

View File

@ -0,0 +1,690 @@
/*
* Copyright (c) 2012, Kapil Gupta <kgupta@sangoma.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* Contributors:
*
*
*/
/* INCLUDE ********************************************************************/
#include "ftmod_sangoma_ss7_main.h"
/******************************************************************************/
/* DEFINES ********************************************************************/
/******************************************************************************/
static int ftmod_ss7_parse_nif_interface(ftdm_conf_node_t *nif_interface);
static int ftmod_ss7_parse_m2ua_interface(ftdm_conf_node_t *m2ua_interface);
static int ftmod_ss7_parse_m2ua_peer_interface(ftdm_conf_node_t *m2ua_peer_interface);
static int ftmod_ss7_parse_m2ua_clust_interface(ftdm_conf_node_t *m2ua_clust_interface);
static int ftmod_ss7_fill_in_nif_interface(sng_nif_cfg_t *nif_iface);
static int ftmod_ss7_fill_in_m2ua_interface(sng_m2ua_cfg_t *m2ua_iface);
static int ftmod_ss7_fill_in_m2ua_peer_interface(sng_m2ua_peer_cfg_t *m2ua_peer_face);
static int ftmod_ss7_fill_in_m2ua_clust_interface(sng_m2ua_cluster_cfg_t *m2ua_cluster_face);
static int ftmod_ss7_parse_sctp_link(ftdm_conf_node_t *node);
/******************************************************************************/
int ftmod_ss7_parse_nif_interfaces(ftdm_conf_node_t *nif_interfaces)
{
ftdm_conf_node_t *nif_interface = NULL;
/* confirm that we are looking at sng_nif_interfaces */
if (strcasecmp(nif_interfaces->name, "sng_nif_interfaces")) {
SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"sng_nif_interfaces\"!\n",nif_interfaces->name);
return FTDM_FAIL;
} else {
SS7_DEBUG("Parsing \"nif_interfaces\"...\n");
}
/* extract the isup_interfaces */
nif_interface = nif_interfaces->child;
while (nif_interface != NULL) {
/* parse the found mtp_route */
if (ftmod_ss7_parse_nif_interface(nif_interface)) {
SS7_ERROR("Failed to parse \"nif_interface\"\n");
return FTDM_FAIL;
}
/* go to the next nif_interface */
nif_interface = nif_interface->next;
}
return FTDM_SUCCESS;
}
/******************************************************************************/
static int ftmod_ss7_parse_nif_interface(ftdm_conf_node_t *nif_interface)
{
sng_nif_cfg_t sng_nif;
ftdm_conf_parameter_t *parm = nif_interface->parameters;
int num_parms = nif_interface->n_parameters;
int i;
/* initalize the nif intf and isap structure */
memset(&sng_nif, 0x0, sizeof(sng_nif));
if(!nif_interface){
SS7_ERROR("ftmod_ss7_parse_nif_interface: Null XML Node pointer \n");
return FTDM_FAIL;
}
/* confirm that we are looking at an nif_interface */
if (strcasecmp(nif_interface->name, "sng_nif_interface")) {
SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"nif_interface\"!\n",nif_interface->name);
return FTDM_FAIL;
} else {
SS7_DEBUG("Parsing \"nif_interface\"...\n");
}
for (i = 0; i < num_parms; i++) {
/**************************************************************************/
/* try to match the parameter to what we expect */
if (!strcasecmp(parm->var, "name")) {
/**********************************************************************/
strcpy((char *)sng_nif.name, parm->val);
SS7_DEBUG("Found an nif_interface named = %s\n", sng_nif.name);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "id")) {
/**********************************************************************/
sng_nif.id = atoi(parm->val);
SS7_DEBUG("Found an nif id = %d\n", sng_nif.id);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "m2ua-interface-id")) {
/**********************************************************************/
sng_nif.m2uaLnkNmb = atoi(parm->val);
SS7_DEBUG("Found an nif m2ua-interface-id = %d\n", sng_nif.m2uaLnkNmb);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "mtp2-interface-id")) {
/**********************************************************************/
sng_nif.mtp2LnkNmb=atoi(parm->val);
SS7_DEBUG("Found an nif mtp2-interface-id = %d\n", sng_nif.mtp2LnkNmb);
/**********************************************************************/
} else {
/**********************************************************************/
SS7_ERROR("Found an invalid parameter %s!\n", parm->var);
return FTDM_FAIL;
/**********************************************************************/
}
/* move to the next parameter */
parm = parm + 1;
/**************************************************************************/
} /* for (i = 0; i < num_parms; i++) */
/* fill in the nif interface */
ftmod_ss7_fill_in_nif_interface(&sng_nif);
return FTDM_SUCCESS;
}
/******************************************************************************/
static int ftmod_ss7_fill_in_nif_interface(sng_nif_cfg_t *nif_iface)
{
int i = nif_iface->id;
strncpy((char *)g_ftdm_sngss7_data.cfg.g_m2ua_cfg.nif[i].name, (char *)nif_iface->name, MAX_NAME_LEN-1);
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.nif[i].id = nif_iface->id;
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.nif[i].m2uaLnkNmb = nif_iface->m2uaLnkNmb;
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.nif[i].mtp2LnkNmb = nif_iface->mtp2LnkNmb;
sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_NIF_PRESENT);
return 0;
}
/******************************************************************************/
int ftmod_ss7_parse_m2ua_interfaces(ftdm_conf_node_t *m2ua_interfaces)
{
ftdm_conf_node_t *m2ua_interface = NULL;
/* confirm that we are looking at sng_m2ua_interfaces */
if (strcasecmp(m2ua_interfaces->name, "sng_m2ua_interfaces")) {
SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"m2ua_nif_interfaces\"!\n",m2ua_interfaces->name);
return FTDM_FAIL;
} else {
SS7_DEBUG("Parsing \"m2ua_interfaces\"...\n");
}
/* extract the isup_interfaces */
m2ua_interface = m2ua_interfaces->child;
while (m2ua_interface != NULL) {
/* parse the found mtp_route */
if (ftmod_ss7_parse_m2ua_interface(m2ua_interface)) {
SS7_ERROR("Failed to parse \"m2ua_interface\"\n");
return FTDM_FAIL;
}
/* go to the next m2ua_interface */
m2ua_interface = m2ua_interface->next;
}
return FTDM_SUCCESS;
}
/******************************************************************************/
static int ftmod_ss7_parse_m2ua_interface(ftdm_conf_node_t *m2ua_interface)
{
sng_m2ua_cfg_t sng_m2ua;
ftdm_conf_parameter_t *parm = m2ua_interface->parameters;
int num_parms = m2ua_interface->n_parameters;
int i;
/* initalize the m2ua intf */
memset(&sng_m2ua, 0x0, sizeof(sng_m2ua));
if(!m2ua_interface){
SS7_ERROR("ftmod_ss7_parse_m2ua_interface: Null XML Node pointer \n");
return FTDM_FAIL;
}
/* confirm that we are looking at an nif_interface */
if (strcasecmp(m2ua_interface->name, "sng_m2ua_interface")) {
SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"m2ua_interface\"!\n",m2ua_interface->name);
return FTDM_FAIL;
} else {
SS7_DEBUG("Parsing \"m2ua_interface\"...\n");
}
for (i = 0; i < num_parms; i++) {
/**************************************************************************/
/* try to match the parameter to what we expect */
if (!strcasecmp(parm->var, "name")) {
/**********************************************************************/
strcpy((char *)sng_m2ua.name, parm->val);
SS7_DEBUG("Found an m2ua_interface named = %s\n", sng_m2ua.name);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "id")) {
/**********************************************************************/
sng_m2ua.id = atoi(parm->val);
SS7_DEBUG("Found an m2ua id = %d\n", sng_m2ua.id);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "m2ua-cluster-interface-id")) {
/**********************************************************************/
sng_m2ua.clusterId=atoi(parm->val);
SS7_DEBUG("Found an m2ua cluster_id = %d\n", sng_m2ua.clusterId);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "interface-identifier")) {
/**********************************************************************/
sng_m2ua.iid=atoi(parm->val);
SS7_DEBUG("Found an m2ua interface-identifier = %d\n", sng_m2ua.iid);
/**********************************************************************/
} else {
/**********************************************************************/
SS7_ERROR("Found an invalid parameter %s!\n", parm->var);
return FTDM_FAIL;
/**********************************************************************/
}
/* move to the next parameter */
parm = parm + 1;
/**************************************************************************/
} /* for (i = 0; i < num_parms; i++) */
sng_m2ua.nodeType = SNG_M2UA_NODE_TYPE_SGP;
/* fill in the nif interface */
ftmod_ss7_fill_in_m2ua_interface(&sng_m2ua);
return FTDM_SUCCESS;
}
/******************************************************************************/
static int ftmod_ss7_fill_in_m2ua_interface(sng_m2ua_cfg_t *m2ua_iface)
{
int i = m2ua_iface->id;
strncpy((char *)g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[i].name, (char *)m2ua_iface->name, MAX_NAME_LEN-1);
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[i].id = m2ua_iface->id;
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[i].nodeType = m2ua_iface->nodeType;
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[i].clusterId = m2ua_iface->clusterId;
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[i].iid = m2ua_iface->iid;
sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_M2UA_PRESENT);
return 0;
}
/******************************************************************************/
int ftmod_ss7_parse_m2ua_peer_interfaces(ftdm_conf_node_t *m2ua_peer_interfaces)
{
ftdm_conf_node_t *m2ua_peer_interface = NULL;
/* confirm that we are looking at m2ua_peer_interfaces */
if (strcasecmp(m2ua_peer_interfaces->name, "sng_m2ua_peer_interfaces")) {
SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"m2ua_peer_interfaces\"!\n",m2ua_peer_interfaces->name);
return FTDM_FAIL;
} else {
SS7_DEBUG("Parsing \"m2ua_peer_interfaces\"...\n");
}
/* extract the m2ua_peer_interfaces */
m2ua_peer_interface = m2ua_peer_interfaces->child;
while (m2ua_peer_interface != NULL) {
/* parse the found mtp_route */
if (ftmod_ss7_parse_m2ua_peer_interface(m2ua_peer_interface)) {
SS7_ERROR("Failed to parse \"m2ua_peer_interface\"\n");
return FTDM_FAIL;
}
/* go to the next m2ua_peer_interface */
m2ua_peer_interface = m2ua_peer_interface->next;
}
return FTDM_SUCCESS;
}
/******************************************************************************/
static int ftmod_ss7_parse_m2ua_peer_interface(ftdm_conf_node_t *m2ua_peer_interface)
{
sng_m2ua_peer_cfg_t sng_m2ua_peer;
ftdm_conf_parameter_t *parm = m2ua_peer_interface->parameters;
int num_parms = m2ua_peer_interface->n_parameters;
int i;
/* initalize the m2ua intf */
memset(&sng_m2ua_peer, 0x0, sizeof(sng_m2ua_peer));
if(!m2ua_peer_interface){
SS7_ERROR("ftmod_ss7_parse_m2ua_peer_interface: Null XML Node pointer \n");
return FTDM_FAIL;
}
/* confirm that we are looking at an m2ua_peer_interface */
if (strcasecmp(m2ua_peer_interface->name, "sng_m2ua_peer_interface")) {
SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"m2ua_peer_interface\"!\n",m2ua_peer_interface->name);
return FTDM_FAIL;
} else {
SS7_DEBUG("Parsing \"m2ua_peer_interface\"...\n");
}
for (i = 0; i < num_parms; i++) {
/**************************************************************************/
/* try to match the parameter to what we expect */
if (!strcasecmp(parm->var, "name")) {
/**********************************************************************/
strcpy((char *)sng_m2ua_peer.name, parm->val);
SS7_DEBUG("Found an sng_m2ua_peer named = %s\n", sng_m2ua_peer.name);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "id")) {
/**********************************************************************/
sng_m2ua_peer.id = atoi(parm->val);
SS7_DEBUG("Found an sng_m2ua_peer id = %d\n", sng_m2ua_peer.id);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "include-asp-identifier")) {
/**********************************************************************/
if(!strcasecmp(parm->val, "TRUE")){
sng_m2ua_peer.aspIdFlag = 0x01;
} else if(!strcasecmp(parm->val, "FALSE")){
sng_m2ua_peer.aspIdFlag = 0x00;
} else {
SS7_ERROR("Found an invalid aspIdFlag Parameter Value[%s]\n", parm->val);
return FTDM_FAIL;
}
SS7_DEBUG("Found an sng_m2ua_peer aspIdFlag = %d\n", sng_m2ua_peer.aspIdFlag);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "asp-identifier")) {
/**********************************************************************/
sng_m2ua_peer.selfAspId=atoi(parm->val);
SS7_DEBUG("Found an sng_m2ua_peer self_asp_id = %d\n", sng_m2ua_peer.selfAspId);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "sctp-interface-id")) {
/**********************************************************************/
sng_m2ua_peer.sctpId = atoi(parm->val);
SS7_DEBUG("Found an sng_m2ua_peer sctp_id = %d\n", sng_m2ua_peer.sctpId);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "destination-port")) {
/**********************************************************************/
sng_m2ua_peer.port = atoi(parm->val);
SS7_DEBUG("Found an sng_m2ua_peer port = %d\n", sng_m2ua_peer.port);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "address")) {
/**********************************************************************/
if (sng_m2ua_peer.numDestAddr < SCT_MAX_NET_ADDRS) {
sng_m2ua_peer.destAddrList[sng_m2ua_peer.numDestAddr] = iptoul (parm->val);
sng_m2ua_peer.numDestAddr++;
SS7_DEBUG("sng_m2ua_peer - Parsing with dest IP Address = %s \n", parm->val);
} else {
SS7_ERROR("sng_m2ua_peer - too many dest address configured. dropping %s \n", parm->val);
}
/**********************************************************************/
} else if (!strcasecmp(parm->var, "number-of-outgoing-streams")) {
/**********************************************************************/
sng_m2ua_peer.locOutStrms=atoi(parm->val);
SS7_DEBUG("Found an sng_m2ua_peer number-of-outgoing-streams = %d\n", sng_m2ua_peer.locOutStrms);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "init-sctp-association")) {
/**********************************************************************/
if(!strcasecmp(parm->val, "TRUE")){
sng_m2ua_peer.init_sctp_assoc = 0x01;
} else if(!strcasecmp(parm->val, "FALSE")){
sng_m2ua_peer.init_sctp_assoc = 0x00;
} else {
SS7_ERROR("Found an invalid init_sctp_assoc Parameter Value[%s]\n", parm->val);
return FTDM_FAIL;
}
SS7_DEBUG("Found an sng_m2ua_peer init_sctp_assoc = %d\n", sng_m2ua_peer.init_sctp_assoc);
/**********************************************************************/
} else {
/**********************************************************************/
SS7_ERROR("Found an invalid parameter %s!\n", parm->var);
return FTDM_FAIL;
/**********************************************************************/
}
/* move to the next parameter */
parm = parm + 1;
/**************************************************************************/
} /* for (i = 0; i < num_parms; i++) */
/* fill in the sng_m2ua_peer interface */
ftmod_ss7_fill_in_m2ua_peer_interface(&sng_m2ua_peer);
return FTDM_SUCCESS;
}
/******************************************************************************/
static int ftmod_ss7_fill_in_m2ua_peer_interface(sng_m2ua_peer_cfg_t *m2ua_peer_iface)
{
int k = 0x00;
int i = m2ua_peer_iface->id;
strncpy((char *)g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].name, (char *)m2ua_peer_iface->name, MAX_NAME_LEN-1);
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].id = m2ua_peer_iface->id;
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].aspIdFlag = m2ua_peer_iface->aspIdFlag;
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].selfAspId = m2ua_peer_iface->selfAspId;
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].locOutStrms = m2ua_peer_iface->locOutStrms;
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].numDestAddr = m2ua_peer_iface->numDestAddr;
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].sctpId = m2ua_peer_iface->sctpId;
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].port = m2ua_peer_iface->port;
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].init_sctp_assoc = m2ua_peer_iface->init_sctp_assoc;
for (k=0; k<m2ua_peer_iface->numDestAddr; k++) {
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].destAddrList[k] = m2ua_peer_iface->destAddrList[k];
}
return 0;
}
/******************************************************************************/
int ftmod_ss7_parse_m2ua_clust_interfaces(ftdm_conf_node_t *m2ua_cluster_interfaces)
{
ftdm_conf_node_t *m2ua_cluster_interface = NULL;
/* confirm that we are looking at m2ua_cluster_interfaces */
if (strcasecmp(m2ua_cluster_interfaces->name, "sng_m2ua_cluster_interfaces")) {
SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"m2ua_cluster_interfaces\"!\n",m2ua_cluster_interfaces->name);
return FTDM_FAIL;
} else {
SS7_DEBUG("Parsing \"m2ua_cluster_interfaces\"...\n");
}
/* extract the m2ua_cluster_interfaces */
m2ua_cluster_interface = m2ua_cluster_interfaces->child;
while (m2ua_cluster_interface != NULL) {
/* parse the found m2ua_cluster_interface */
if (ftmod_ss7_parse_m2ua_clust_interface(m2ua_cluster_interface)) {
SS7_ERROR("Failed to parse \"m2ua_cluster_interface\"\n");
return FTDM_FAIL;
}
/* go to the next m2ua_cluster_interface */
m2ua_cluster_interface = m2ua_cluster_interface->next;
}
return FTDM_SUCCESS;
}
/******************************************************************************/
static int ftmod_ss7_parse_m2ua_clust_interface(ftdm_conf_node_t *m2ua_cluster_interface)
{
sng_m2ua_cluster_cfg_t sng_m2ua_cluster;
ftdm_conf_parameter_t *parm = m2ua_cluster_interface->parameters;
int num_parms = m2ua_cluster_interface->n_parameters;
int i;
/* initalize the m2ua_cluster_interface */
memset(&sng_m2ua_cluster, 0x0, sizeof(sng_m2ua_cluster));
if (!m2ua_cluster_interface){
SS7_ERROR("ftmod_ss7_parse_m2ua_clust_interface - NULL XML Node pointer \n");
return FTDM_FAIL;
}
/* confirm that we are looking at an m2ua_cluster_interface */
if (strcasecmp(m2ua_cluster_interface->name, "sng_m2ua_cluster_interface")) {
SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"m2ua_cluster_interface\"!\n",m2ua_cluster_interface->name);
return FTDM_FAIL;
} else {
SS7_DEBUG("Parsing \"m2ua_cluster_interface\"...\n");
}
for (i = 0; i < num_parms; i++) {
/**************************************************************************/
/* try to match the parameter to what we expect */
if (!strcasecmp(parm->var, "name")) {
/**********************************************************************/
strcpy((char *)sng_m2ua_cluster.name, parm->val);
SS7_DEBUG("Found an sng_m2ua_cluster named = %s\n", sng_m2ua_cluster.name);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "id")) {
/**********************************************************************/
sng_m2ua_cluster.id = atoi(parm->val);
SS7_DEBUG("Found an sng_m2ua_cluster id = %d\n", sng_m2ua_cluster.id);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "traffic-mode")) {
/**********************************************************************/
if(!strcasecmp(parm->val, "loadshare")){
sng_m2ua_cluster.trfMode = SNG_M2UA_TRF_MODE_LOADSHARE;
} else if(!strcasecmp(parm->val, "override")){
sng_m2ua_cluster.trfMode = SNG_M2UA_TRF_MODE_OVERRIDE;
} else if(!strcasecmp(parm->val, "broadcast")){
sng_m2ua_cluster.trfMode = SNG_M2UA_TRF_MODE_BROADCAST;
} else {
SS7_ERROR("Found an invalid trfMode Parameter Value[%s]..adding default one[ANY]\n", parm->val);
sng_m2ua_cluster.trfMode = SNG_M2UA_TRF_MODE_ANY;
}
SS7_DEBUG("Found an sng_m2ua_cluster.trfMode = %d\n", sng_m2ua_cluster.trfMode);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "load-share-algorithm")) {
/**********************************************************************/
if(!strcasecmp(parm->val, "roundrobin")){
sng_m2ua_cluster.loadShareAlgo = SNG_M2UA_LOAD_SHARE_ALGO_RR;
} else if(!strcasecmp(parm->val, "linkspecified")){
sng_m2ua_cluster.loadShareAlgo = SNG_M2UA_LOAD_SHARE_ALGO_LS;
} else if(!strcasecmp(parm->val, "customerspecified")){
sng_m2ua_cluster.loadShareAlgo = SNG_M2UA_LOAD_SHARE_ALGO_CS;
} else {
SS7_ERROR("Found an invalid loadShareAlgo Parameter Value[%s]\n", parm->val);
return FTDM_FAIL;
}
SS7_DEBUG("Found an sng_m2ua_cluster.loadShareAlgo = %d\n", sng_m2ua_cluster.loadShareAlgo);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "m2ua-peer-interface-id")) {
/**********************************************************************/
if(sng_m2ua_cluster.numOfPeers < MW_MAX_NUM_OF_PEER) {
sng_m2ua_cluster.peerIdLst[sng_m2ua_cluster.numOfPeers] = atoi(parm->val);
SS7_DEBUG("Found an sng_m2ua_cluster peerId[%d], Total numOfPeers[%d] \n",
sng_m2ua_cluster.peerIdLst[sng_m2ua_cluster.numOfPeers],
sng_m2ua_cluster.numOfPeers+1);
sng_m2ua_cluster.numOfPeers++;
}else{
SS7_ERROR("Peer List excedding max[%d] limit \n", MW_MAX_NUM_OF_PEER);
return FTDM_FAIL;
}
/**********************************************************************/
} else {
/**********************************************************************/
SS7_ERROR("Found an invalid parameter %s!\n", parm->var);
return FTDM_FAIL;
/**********************************************************************/
}
/* move to the next parameter */
parm = parm + 1;
/**************************************************************************/
} /* for (i = 0; i < num_parms; i++) */
/* fill in the sng_m2ua_peer interface */
ftmod_ss7_fill_in_m2ua_clust_interface(&sng_m2ua_cluster);
return FTDM_SUCCESS;
}
/******************************************************************************/
static int ftmod_ss7_fill_in_m2ua_clust_interface(sng_m2ua_cluster_cfg_t *m2ua_cluster_iface)
{
int k = 0x00;
int i = m2ua_cluster_iface->id;
strncpy((char *)g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_clus[i].name, (char *)m2ua_cluster_iface->name, MAX_NAME_LEN-1);
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_clus[i].id = m2ua_cluster_iface->id;
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_clus[i].trfMode = m2ua_cluster_iface->trfMode;
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_clus[i].loadShareAlgo = m2ua_cluster_iface->loadShareAlgo;
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_clus[i].numOfPeers = m2ua_cluster_iface->numOfPeers;
for(k=0;k<m2ua_cluster_iface->numOfPeers;k++){
g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_clus[i].peerIdLst[k] = m2ua_cluster_iface->peerIdLst[k];
}
return 0;
}
/******************************************************************************/
int ftmod_ss7_parse_sctp_links(ftdm_conf_node_t *node)
{
ftdm_conf_node_t *node_sctp_link = NULL;
if (!node)
return FTDM_FAIL;
if (strcasecmp(node->name, "sng_sctp_interfaces")) {
SS7_ERROR("SCTP - We're looking at <%s>...but we're supposed to be looking at <sng_sctp_interfaces>!\n", node->name);
return FTDM_FAIL;
} else {
SS7_DEBUG("SCTP - Parsing <sng_sctp_interface> configurations\n");
}
for (node_sctp_link = node->child; node_sctp_link != NULL; node_sctp_link = node_sctp_link->next) {
if (ftmod_ss7_parse_sctp_link(node_sctp_link) != FTDM_SUCCESS) {
SS7_ERROR("SCTP - Failed to parse <node_sctp_link>. \n");
return FTDM_FAIL;
}
}
return FTDM_SUCCESS;
}
/******************************************************************************/
static int ftmod_ss7_parse_sctp_link(ftdm_conf_node_t *node)
{
ftdm_conf_parameter_t *param = NULL;
int num_params = 0;
int i=0;
if (!node){
SS7_ERROR("SCTP - NULL XML Node pointer \n");
return FTDM_FAIL;
}
param = node->parameters;
num_params = node->n_parameters;
sng_sctp_link_t t_link;
memset (&t_link, 0, sizeof(sng_sctp_link_t));
if (strcasecmp(node->name, "sng_sctp_interface")) {
SS7_ERROR("SCTP - We're looking at <%s>...but we're supposed to be looking at <sng_sctp_interface>!\n", node->name);
return FTDM_FAIL;
} else {
SS7_DEBUG("SCTP - Parsing <sng_sctp_interface> configurations\n");
}
for (i=0; i<num_params; i++, param++) {
if (!strcasecmp(param->var, "name")) {
int n_strlen = strlen(param->val);
strncpy((char*)t_link.name, param->val, (n_strlen>MAX_NAME_LEN)?MAX_NAME_LEN:n_strlen);
SS7_DEBUG("SCTP - Parsing <sng_sctp_interface> with name = %s\n", param->val);
}
else if (!strcasecmp(param->var, "id")) {
t_link.id = atoi(param->val);
SS7_DEBUG("SCTP - Parsing <sng_sctp_interface> with id = %s\n", param->val);
}
else if (!strcasecmp(param->var, "address")) {
if (t_link.numSrcAddr < SCT_MAX_NET_ADDRS) {
t_link.srcAddrList[t_link.numSrcAddr+1] = iptoul (param->val);
t_link.numSrcAddr++;
SS7_DEBUG("SCTP - Parsing <sng_sctp_interface> with source IP Address = %s\n", param->val);
} else {
SS7_ERROR("SCTP - too many source address configured. dropping %s \n", param->val);
}
} else if (!strcasecmp(param->var, "source-port")) {
t_link.port = atoi(param->val);
SS7_DEBUG("SCTP - Parsing <sng_sctp_interface> with port = %s\n", param->val);
}
else {
SS7_ERROR("SCTP - Found an unknown parameter <%s>. Skipping it.\n", param->var);
}
}
g_ftdm_sngss7_data.cfg.sctpCfg.linkCfg[t_link.id].id = t_link.id;
g_ftdm_sngss7_data.cfg.sctpCfg.linkCfg[t_link.id].port = t_link.port;
strncpy((char*)g_ftdm_sngss7_data.cfg.sctpCfg.linkCfg[t_link.id].name, t_link.name, strlen(t_link.name) );
g_ftdm_sngss7_data.cfg.sctpCfg.linkCfg[t_link.id].numSrcAddr = t_link.numSrcAddr;
for (i=1; i<=t_link.numSrcAddr; i++) {
g_ftdm_sngss7_data.cfg.sctpCfg.linkCfg[t_link.id].srcAddrList[i] = t_link.srcAddrList[i];
}
sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_SCTP_PRESENT);
return FTDM_SUCCESS;
}
/******************************************************************************/

View File

@ -29,6 +29,12 @@
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* Contributors:
*
* James Zhang <jzhang@sangoma.com>
*
*/
/******************************************************************************/
#ifndef __FTMOD_SNG_SS7_H__
@ -46,17 +52,20 @@
#include "private/ftdm_core.h"
#include "sng_ss7/sng_ss7.h"
#include "ftmod_sangoma_ss7_m2ua.h"
/******************************************************************************/
/* DEFINES ********************************************************************/
#define MAX_NAME_LEN 25
#define MAX_PATH 4096
#define MAX_CIC_LENGTH 5
#define MAX_CIC_MAP_LENGTH 1000
#define MAX_SCTP_LINK 100
#define SNGSS7_EVENT_QUEUE_SIZE 100
#define SNGSS7_PEER_CHANS_QUEUE_SIZE 100
#define SNGSS7_CHAN_EVENT_QUEUE_SIZE 100
#define MAX_SIZEOF_SUBADDR_IE 24 /* as per Q931 4.5.9 */
@ -64,6 +73,14 @@
(switchtype == LSI_SW_ANS92) || \
(switchtype == LSI_SW_ANS95)
#define sngss7_flush_queue(queue) \
do { \
void *__queue_data = NULL; \
while ((__queue_data = ftdm_queue_dequeue(queue))) { \
ftdm_safe_free(__queue_data); \
} \
} while (0)
typedef struct ftdm2trillium {
uint8_t ftdm_val;
uint8_t trillium_val;
@ -82,8 +99,12 @@ typedef enum {
SNGSS7_STA_IND_EVENT,
SNGSS7_SUSP_IND_EVENT,
SNGSS7_RESM_IND_EVENT,
SNGSS7_SSP_STA_CFM_EVENT
SNGSS7_SSP_STA_CFM_EVENT,
SNGSS7_INVALID_EVENT,
} sng_event_type_t;
#define SNG_EVENT_TYPE_STRINGS "CON_IND", "CON_CFM", "CON_STA", "REL_IND", "REL_CFM", "DAT_IND", "FAC_IND", \
"FAC_CFM", "UMSG_IND", "STA_IND", "SUSP_IND", "RESM_IND", "SSP_STA_CFM", "INVALID"
FTDM_STR2ENUM_P(ftdm_str2sngss7_event, ftdm_sngss7_event2str, sng_event_type_t)
typedef enum {
SNG_BIT_A = (1 << 0),
@ -117,6 +138,12 @@ typedef enum {
SNG_CALLING = 2
} sng_addr_type_t;
typedef enum {
SNG_GEN_CFG_STATUS_INIT = 0,
SNG_GEN_CFG_STATUS_PENDING = 1,
SNG_GEN_CFG_STATUS_DONE = 2
} nsg_gen_cfg_type_t;
typedef struct sng_mtp2_error_type {
int init;
char sng_type[MAX_NAME_LEN];
@ -176,6 +203,21 @@ typedef struct sng_mtp2_link {
uint32_t t7;
} sng_mtp2_link_t;
/* defining glare handling methods:
SNGSS7_GLARE_PC:
higher PointCode controls even number CIC
lower PointCode controls odd number CIC
SNGSS7_GLARE_DOWN:
always give control to the other side
SNGSS7_GLARE_CONTROL:
always trying to control
*/
typedef enum {
SNGSS7_GLARE_PC = 0,
SNGSS7_GLARE_DOWN,
SNGSS7_GLARE_CONTROL
} sng_glare_resolution;
typedef struct sng_mtp3_link {
char name[MAX_NAME_LEN];
uint32_t flags;
@ -328,6 +370,7 @@ typedef struct sng_isup_ckt {
uint32_t clg_nadi;
uint32_t cld_nadi;
uint8_t rdnis_nadi;
uint32_t loc_nadi;
/* Generic Number defaults */
uint8_t gn_nmbqual; /* Number Qualifier */
@ -339,8 +382,11 @@ typedef struct sng_isup_ckt {
/* END - Generic Number defaults */
uint32_t min_digits;
uint8_t itx_auto_reply;
uint32_t transparent_iam_max_size;
uint8_t transparent_iam;
uint8_t cpg_on_progress_media;
uint8_t cpg_on_progress;
uint8_t itx_auto_reply;
void *obj;
uint16_t t3;
uint32_t t10;
@ -351,6 +397,7 @@ typedef struct sng_isup_ckt {
uint16_t t16;
uint16_t t17;
uint32_t t35;
uint32_t t39;
uint16_t tval;
} sng_isup_ckt_t;
@ -404,11 +451,34 @@ typedef struct sng_relay {
uint32_t procId;
} sng_relay_t;
/**********************************************
sctp structures and data definitions
**********************************************/
typedef struct sng_sctp_gen_cfg {
} sng_sctp_gen_cfg_t;
typedef struct sng_sctp_link {
char name[MAX_NAME_LEN];
uint32_t flags;
uint32_t id;
uint32_t port;
uint32_t numSrcAddr;
uint32_t srcAddrList[SCT_MAX_NET_ADDRS+1];
} sng_sctp_link_t;
typedef struct sng_sctp_cfg {
sng_sctp_gen_cfg_t genCfg;
sng_sctp_link_t linkCfg[MAX_SCTP_LINK+1];
} sng_sctp_cfg_t;
typedef struct sng_ss7_cfg {
uint32_t spc;
uint32_t procId;
char license[MAX_PATH];
char signature[MAX_PATH];
char license[MAX_SNGSS7_PATH];
char signature[MAX_SNGSS7_PATH];
uint32_t transparent_iam_max_size;
uint32_t flags;
sng_relay_t relay[MAX_RELAY_CHANNELS+1];
@ -421,6 +491,10 @@ typedef struct sng_ss7_cfg {
sng_isup_ckt_t isupCkt[10000]; /* KONRAD - only need 2000 ( and 0-1000 aren't used) since other servers are registerd else where */
sng_nsap_t nsap[MAX_NSAPS+1];
sng_isap_t isap[MAX_ISAPS+1];
sng_glare_resolution glareResolution;
uint32_t force_inr;
sng_m2ua_gbl_cfg_t g_m2ua_cfg;
sng_sctp_cfg_t sctpCfg;
} sng_ss7_cfg_t;
typedef struct ftdm_sngss7_data {
@ -433,6 +507,14 @@ typedef struct ftdm_sngss7_data {
fio_signal_cb_t sig_cb;
} ftdm_sngss7_data_t;
typedef enum{
SNG_SS7_OPR_MODE_NONE,
SNG_SS7_OPR_MODE_M2UA_SG,
SNG_SS7_OPR_MODE_ISUP,
}ftdm_sngss7_operating_modes_e;
typedef ftdm_sngss7_operating_modes_e ftdm_sngss7_opr_mode;
typedef struct sngss7_timer_data {
ftdm_timer_id_t hb_timer_id;
int beat;
@ -472,10 +554,14 @@ typedef struct sngss7_chan_data {
sngss7_glare_data_t glare;
sngss7_timer_data_t t35;
sngss7_timer_data_t t10;
sngss7_timer_data_t t39;
sngss7_group_data_t rx_grs;
sngss7_group_data_t rx_gra;
sngss7_group_data_t tx_grs;
sngss7_group_data_t ucic;
ftdm_queue_t *event_queue;
struct sngss7_chan_data *peer_data;
uint8_t peer_event_transfer_cnt;
} sngss7_chan_data_t;
#define SNGSS7_RX_GRS_PENDING (1 << 0)
@ -533,6 +619,18 @@ typedef enum {
FLAG_INFID_RESUME = (1 << 14),
FLAG_INFID_PAUSED = (1 << 15),
FLAG_SENT_ACM = (1 << 16),
FLAG_SENT_CPG = (1 << 17),
FLAG_SUS_RECVD = (1 << 18),
FLAG_T6_CANCELED = (1 << 19),
FLAG_INR_TX = (1 << 20),
FLAG_INR_SENT = (1 << 21),
FLAG_INR_RX = (1 << 22),
FLAG_INR_RX_DN = (1 << 23),
FLAG_INF_TX = (1 << 24),
FLAG_INF_SENT = (1 << 25),
FLAG_INF_RX = (1 << 26),
FLAG_INF_RX_DN = (1 << 27),
FLAG_FULL_NUMBER = (1 << 28),
FLAG_RELAY_DOWN = (1 << 30),
FLAG_CKT_RECONFIG = (1 << 31)
} sng_ckt_flag_t;
@ -541,20 +639,28 @@ typedef enum {
"RX_RSC", \
"TX_RSC", \
"TX_RSC_REQ_SENT", \
"TX_RSC_RSP_RECIEVED", \
"TX_RSC_RSP_RECEIVED", \
"RX_GRS", \
"RX_GRS_DONE", \
"RX_GRS_CMPLT", \
"GRS_BASE", \
"TX_GRS", \
"TX_GRS_REQ_SENT", \
"TX_GRS_RSP_RECIEVED", \
"TX_GRS_RSP_RECEIVED", \
"REMOTE_REL", \
"LOCAL_REL", \
"GLARE", \
"INF_RESUME", \
"INF_PAUSED", \
"TX_ACM_SENT" \
"TX_INR" \
"INR_SENT" \
"RX_INR" \
"RX_INR_DN" \
"TX_INF" \
"INF SENT" \
"RX_INF" \
"RX_INF_DN" \
"RELAY_DOWN", \
"CKT_RECONFIG"
FTDM_STR2ENUM_P(ftmod_ss7_ckt_state2flag, ftmod_ss7_ckt_flag2str, sng_ckt_flag_t)
@ -588,7 +694,7 @@ typedef enum {
FLAG_GRP_HW_UNBLK_TX = (1 << 24),
FLAG_GRP_HW_UNBLK_TX_DN = (1 << 25),
FLAG_GRP_MN_UNBLK_TX = (1 << 26),
FLAG_GRP_MN_UNBLK_TX_DN = (1 << 27)
FLAG_GRP_MN_UNBLK_TX_DN = (1 << 27),
} sng_ckt_block_flag_t;
#define BLK_FLAGS_STRING \
@ -652,11 +758,27 @@ typedef enum {
SNGSS7_CC_PRESENT = (1 << 12),
SNGSS7_CC_STARTED = (1 << 13),
SNGSS7_TUCL_PRESENT = (1 << 14),
SNGSS7_TUCL_STARTED = (1 << 15),
SNGSS7_SCTP_PRESENT = (1 << 16),
SNGSS7_SCTP_STARTED = (1 << 17),
SNGSS7_M2UA_PRESENT = (1 << 18),
SNGSS7_M2UA_STARTED = (1 << 19),
SNGSS7_M2UA_EP_OPENED = (1 << 20),
SNGSS7_M2UA_INIT_ASSOC_DONE = (1 << 21),
SNGSS7_NIF_PRESENT = (1 << 22),
SNGSS7_NIF_STARTED = (1 << 23),
} sng_task_flag_t;
/******************************************************************************/
/* GLOBALS ********************************************************************/
extern ftdm_sngss7_data_t g_ftdm_sngss7_data;
extern ftdm_sngss7_opr_mode g_ftdm_operating_mode;
extern sng_ssf_type_t sng_ssf_type_map[];
extern sng_switch_type_t sng_switch_type_map[];
extern sng_link_type_t sng_link_type_map[];
@ -679,6 +801,10 @@ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta);
void handle_sng_isup_alarm(Pst *pst, SiMngmt *sta);
void handle_sng_cc_alarm(Pst *pst, CcMngmt *sta);
void handle_sng_relay_alarm(Pst *pst, RyMngmt *sta);
void handle_sng_m2ua_alarm(Pst *pst, MwMgmt *sta);
void handle_sng_nif_alarm(Pst *pst, NwMgmt *sta);
void handle_sng_tucl_alarm(Pst *pst, HiMngmt *sta);
void handle_sng_sctp_alarm(Pst *pst, SbMgmt *sta);
/* in ftmod_sangoma_ss7_relay.c */
ftdm_status_t handle_relay_connect(RyMngmt *sta);
@ -731,7 +857,9 @@ int ftmod_ss7_enable_grp_mtp3Link(uint32_t procId);
int ftmod_ss7_disable_grp_mtp2Link(uint32_t procId);
int ftmod_ss7_block_isup_ckt(uint32_t cktId);
#define ftmod_ss7_block_isup_ckt(x) __ftmod_ss7_block_isup_ckt(x,FTDM_TRUE)
#define ftmod_ss7_block_isup_ckt_nowait(x) __ftmod_ss7_block_isup_ckt(x,FTDM_FALSE)
int __ftmod_ss7_block_isup_ckt(uint32_t cktId, ftdm_bool_t wait);
int ftmod_ss7_unblock_isup_ckt(uint32_t cktId);
@ -767,6 +895,9 @@ void ft_to_sngss7_cgb(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_cgu(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_itx (ftdm_channel_t * ftdmchan);
void ft_to_sngss7_txa (ftdm_channel_t * ftdmchan);
void ft_to_sngss7_inr(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_inf(ftdm_channel_t *ftdmchan, SiCnStEvnt *inr);
/* in ftmod_sangoma_ss7_in.c */
@ -835,15 +966,27 @@ ftdm_status_t copy_cdPtyNum_from_sngss7(ftdm_channel_t *ftdmchan, SiCdPtyNum *cd
ftdm_status_t copy_cdPtyNum_to_sngss7(ftdm_channel_t *ftdmchan, SiCdPtyNum *cdPtyNum);
ftdm_status_t copy_redirgNum_to_sngss7(ftdm_channel_t *ftdmchan, SiRedirNum *redirgNum);
ftdm_status_t copy_redirgNum_from_sngss7(ftdm_channel_t *ftdmchan, SiRedirNum *redirgNum);
ftdm_status_t copy_redirgInfo_from_sngss7(ftdm_channel_t *ftdmchan, SiRedirInfo *redirInfo);
ftdm_status_t copy_redirgInfo_to_sngss7(ftdm_channel_t *ftdmchan, SiRedirInfo *redirInfo);
ftdm_status_t copy_ocn_to_sngss7(ftdm_channel_t *ftdmchan, SiOrigCdNum *origCdNum);
ftdm_status_t copy_ocn_from_sngss7(ftdm_channel_t *ftdmchan, SiOrigCdNum *origCdNum);
ftdm_status_t copy_access_transport_from_sngss7(ftdm_channel_t *ftdmchan, SiAccTrnspt *accTrnspt);
ftdm_status_t copy_access_transport_to_sngss7(ftdm_channel_t *ftdmchan, SiAccTrnspt *accTrnspt);
ftdm_status_t copy_locPtyNum_to_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyNum *locPtyNum);
ftdm_status_t copy_locPtyNum_from_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyNum *locPtyNum);
ftdm_status_t copy_genNmb_to_sngss7(ftdm_channel_t *ftdmchan, SiGenNum *genNmb);
ftdm_status_t copy_genNmb_from_sngss7(ftdm_channel_t *ftdmchan, SiGenNum *genNmb);
ftdm_status_t copy_cgPtyCat_to_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyCat *cgPtyCat);
ftdm_status_t copy_cgPtyCat_from_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyCat *cgPtyCat);
ftdm_status_t copy_accTrnspt_to_sngss7(ftdm_channel_t *ftdmchan, SiAccTrnspt *accTrnspt);
ftdm_status_t copy_natConInd_to_sngss7(ftdm_channel_t *ftdmchan, SiNatConInd *natConInd);
ftdm_status_t copy_fwdCallInd_hex_from_sngss7(ftdm_channel_t *ftdmchan, SiFwdCallInd *fwdCallInd);
ftdm_status_t copy_fwdCallInd_to_sngss7(ftdm_channel_t *ftdmchan, SiFwdCallInd *fwdCallInd);
ftdm_status_t copy_txMedReq_to_sngss7(ftdm_channel_t *ftdmchan, SiTxMedReq *txMedReq);
ftdm_status_t copy_usrServInfoA_to_sngss7(ftdm_channel_t *ftdmchan, SiUsrServInfo *usrServInfoA);
ftdm_status_t copy_NatureOfConnection_from_sngss7(ftdm_channel_t *ftdmchan, SiNatConInd *natConInd );
ftdm_status_t copy_NatureOfConnection_to_sngss7(ftdm_channel_t *ftdmchan, SiNatConInd *natConInd);
ftdm_status_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
ftdm_status_t append_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
@ -889,6 +1032,8 @@ ftdm_status_t sngss7_add_raw_data(sngss7_chan_data_t *sngss7_info, uint8_t* data
/* in ftmod_sangoma_ss7_timers.c */
void handle_isup_t35(void *userdata);
void handle_isup_t10(void *userdata);
void handle_isup_t39(void *userdata);
/******************************************************************************/
@ -910,9 +1055,9 @@ if (ftdmchan->state == new_state) { \
#define SS7_INFO_CHAN(fchan, msg, args...) ftdm_log_chan(fchan, FTDM_LOG_INFO, msg , ##args)
#define SS7_WARN_CHAN(fchan, msg, args...) ftdm_log_chan(fchan, FTDM_LOG_WARNING, msg , ##args)
#define SS7_ERROR_CHAN(fchan, msg, args...) ftdm_log_chan(fchan, FTDM_LOG_ERROR, msg , ##args)
#define SS7_CTRIT_CHAN(fchan, msg, args...) ftdm_log_chan(fchan, FTDM_LOG_CRIT, msg , ##args)
#define SS7_CRIT_CHAN(fchan, msg, args...) ftdm_log_chan(fchan, FTDM_LOG_CRIT, msg , ##args)
#ifdef KONRAD_DEVEL
#ifdef SS7_CODE_DEVEL
#define SS7_DEVEL_DEBUG(a,...) ftdm_log(FTDM_LOG_DEBUG,a,##__VA_ARGS__ );
#else
#define SS7_DEVEL_DEBUG(a,...)
@ -1039,6 +1184,40 @@ if (ftdmchan->state == new_state) { \
#define sngss7_clear_options(obj, option) ((obj)->options &= ~(option))
#define sngss7_set_options(obj, option) ((obj)->options |= (option))
#define sngss7_tx_block_status_clear(obj) (!sngss7_test_ckt_blk_flag(obj, (FLAG_CKT_MN_BLOCK_TX | \
FLAG_CKT_MN_BLOCK_TX_DN | \
FLAG_GRP_MN_BLOCK_TX | \
FLAG_GRP_MN_BLOCK_TX_DN | \
FLAG_GRP_HW_BLOCK_TX | \
FLAG_GRP_HW_BLOCK_TX_DN | \
FLAG_GRP_HW_UNBLK_TX | \
FLAG_CKT_MN_UNBLK_TX )))
#define sngss7_block_status_clear(obj) (obj->blk_flags == 0)
#define sngss7_reset_status_clear(obj) (!sngss7_test_ckt_flag(obj, (FLAG_RESET_TX | \
FLAG_RESET_RX | \
FLAG_GRP_RESET_TX | \
FLAG_GRP_RESET_RX )))
#define sngss7_tx_reset_sent(obj) ((sngss7_test_ckt_flag(obj, (FLAG_RESET_TX)) && \
sngss7_test_ckt_flag(obj, (FLAG_RESET_SENT))) || \
(sngss7_test_ckt_flag(obj, (FLAG_GRP_RESET_TX)) && \
sngss7_test_ckt_flag(obj, (FLAG_GRP_RESET_SENT))))
#define sngss7_tx_reset_status_pending(obj) (sngss7_test_ckt_flag(obj, (FLAG_RESET_TX)) || sngss7_test_ckt_flag(obj, (FLAG_GRP_RESET_TX)))
#define sngss7_channel_status_clear(obj) ((sngss7_block_status_clear(obj)) && \
(sngss7_reset_status_clear(obj)) && \
(!sngss7_test_ckt_flag((obj),FLAG_INFID_PAUSED)))
#define sngss7_tx_reset_restart(obj) do { clear_tx_grs_flags((obj)); \
clear_tx_grs_data((obj)); \
clear_tx_rsc_flags((obj)); \
sngss7_set_ckt_flag((obj), (FLAG_RESET_TX)); \
} while (0);
#ifdef SMG_RELAY_DBG
#define SS7_RELAY_DBG(a,...) printf(a"\n", ##__VA_ARGS__)

View File

@ -44,8 +44,11 @@
/* FUNCTIONS ******************************************************************/
void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
{
const char *var = NULL;
SiConEvnt iam;
ftdm_bool_t native_going_up = FTDM_FALSE;
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;;
sngss7_event_data_t *event_clone = NULL;
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
@ -55,9 +58,113 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
memset (&iam, 0x0, sizeof (iam));
if (sngss7_info->circuit->transparent_iam &&
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) {
ftdm_span_t *peer_span = NULL;
ftdm_channel_t *peer_chan = NULL;
sngss7_chan_data_t *peer_info = NULL;
var = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "sigbridge_peer");
ftdm_get_channel_from_string(var, &peer_span, &peer_chan);
if (!peer_chan) {
SS7_ERROR_CHAN(ftdmchan, "Failed to find sigbridge peer from string '%s'\n", var);
} else {
if (peer_span->signal_type != FTDM_SIGTYPE_SS7) {
SS7_ERROR_CHAN(ftdmchan, "Peer channel '%s' has different signaling type %d'\n",
var, peer_span->signal_type);
} else {
peer_info = peer_chan->call_data;
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Starting native bridge with peer CIC %d\n",
sngss7_info->circuit->cic, peer_info->circuit->cic);
/* retrieve only first message from the others guys queue (must be IAM) */
event_clone = ftdm_queue_dequeue(peer_info->event_queue);
/* make each one of us aware of the native bridge */
peer_info->peer_data = sngss7_info;
sngss7_info->peer_data = peer_info;
/* Go to up until release comes, note that state processing is done different and much simpler when there is a peer,
We can't go to UP state right away yet though, so do not set the state to UP here, wait until the end of this function
because moving from one state to another causes the ftdmchan->usrmsg structure to be wiped
and we still need those variables for further IAM processing */
native_going_up = FTDM_TRUE;
}
}
}
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_NATIVE_SIGBRIDGE)) {
if (!event_clone) {
SS7_ERROR_CHAN(ftdmchan, "No IAM event clone in peer queue!%s\n", "");
} else if (event_clone->event_id != SNGSS7_CON_IND_EVENT) {
/* first message in the queue should ALWAYS be an IAM */
SS7_ERROR_CHAN(ftdmchan, "Invalid initial peer message type '%d'\n", event_clone->event_id);
} else {
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged, dialing %s)\n", sngss7_info->circuit->cic, caller_data->dnis.digits);
/* copy original incoming IAM */
memcpy(&iam, &event_clone->event.siConEvnt, sizeof(iam));
/* Change DNIS to whatever was specified, do not change NADI or anything else! */
copy_tknStr_to_sngss7(caller_data->dnis.digits, &iam.cdPtyNum.addrSig, &iam.cdPtyNum.oddEven);
/* SPIROU certification hack
If the IAM already contain RDINF, just increment the count and set the RDNIS digits
otherwise, honor RDNIS and RDINF stuff coming from the user */
if (iam.redirInfo.eh.pres == PRSNT_NODEF) {
const char *val = NULL;
if (iam.redirInfo.redirCnt.pres) {
iam.redirInfo.redirCnt.val++;
SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), redirect count incremented = %d\n", sngss7_info->circuit->cic, iam.redirInfo.redirCnt.val);
}
val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rdnis_digits");
if (!ftdm_strlen_zero(val)) {
SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), found user supplied RDNIS digits = %s\n", sngss7_info->circuit->cic, val);
copy_tknStr_to_sngss7((char*)val, &iam.redirgNum.addrSig, &iam.redirgNum.oddEven);
} else {
SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), not found user supplied RDNIS digits\n", sngss7_info->circuit->cic);
}
} else {
SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Bridged), redirect info not present, attempting to copy user supplied values\n", sngss7_info->circuit->cic);
/* Redirecting Number */
copy_redirgNum_to_sngss7(ftdmchan, &iam.redirgNum);
/* Redirecting Information */
copy_redirgInfo_to_sngss7(ftdmchan, &iam.redirInfo);
}
if (iam.origCdNum.eh.pres != PRSNT_NODEF) {
/* Original Called Number */
copy_ocn_to_sngss7(ftdmchan, &iam.origCdNum);
}
copy_access_transport_to_sngss7(ftdmchan, &iam.accTrnspt);
}
} else if (sngss7_info->circuit->transparent_iam &&
sngss7_retrieve_iam(ftdmchan, &iam) == FTDM_SUCCESS) {
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Transparent)\n", sngss7_info->circuit->cic);
/* Called Number information */
copy_cdPtyNum_to_sngss7(ftdmchan, &iam.cdPtyNum);
/* Redirecting Number */
copy_redirgNum_to_sngss7(ftdmchan, &iam.redirgNum);
/* Redirecting Information */
copy_redirgInfo_to_sngss7(ftdmchan, &iam.redirInfo);
/* Location Number information */
copy_locPtyNum_to_sngss7(ftdmchan, &iam.cgPtyNum1);
/* Forward Call Indicators */
copy_fwdCallInd_to_sngss7(ftdmchan, &iam.fwdCallInd);
/* Original Called Number */
copy_ocn_to_sngss7(ftdmchan, &iam.origCdNum);
copy_access_transport_to_sngss7(ftdmchan, &iam.accTrnspt);
copy_NatureOfConnection_to_sngss7(ftdmchan, &iam.natConInd);
} else {
/* Nature of Connection Indicators */
copy_natConInd_to_sngss7(ftdmchan, &iam.natConInd);
@ -79,6 +186,9 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
/* Calling Number information */
copy_cgPtyNum_to_sngss7(ftdmchan, &iam.cgPtyNum);
/* Location Number information */
copy_locPtyNum_to_sngss7(ftdmchan, &iam.cgPtyNum1);
/* Generic Number information */
copy_genNmb_to_sngss7(ftdmchan, &iam.genNmb);
@ -88,15 +198,30 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
/* Redirecting Number */
copy_redirgNum_to_sngss7(ftdmchan, &iam.redirgNum);
/* Access Transport */
copy_accTrnspt_to_sngss7(ftdmchan, &iam.accTrnspt);
/* Redirecting Information */
copy_redirgInfo_to_sngss7(ftdmchan, &iam.redirInfo);
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM clg = \"%s\" (NADI=%d), cld = \"%s\" (NADI=%d)\n",
/* Original Called Number */
copy_ocn_to_sngss7(ftdmchan, &iam.origCdNum);
/* Access Transport - old implementation, taking from channel variable of ss7_clg_subaddr */
copy_accTrnspt_to_sngss7(ftdmchan, &iam.accTrnspt);
/* Access Transport - taking from channel variable of ss7_access_transport_urlenc.
This will overwirte the IE value set be above old implementation.
*/
copy_access_transport_to_sngss7(ftdmchan, &iam.accTrnspt);
copy_NatureOfConnection_to_sngss7(ftdmchan, &iam.natConInd);
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM clg = \"%s\" (NADI=%d), cld = \"%s\" (NADI=%d), loc = %s (NADI=%d)\n",
sngss7_info->circuit->cic,
ftdmchan->caller_data.cid_num.digits,
iam.cgPtyNum.natAddrInd.val,
ftdmchan->caller_data.dnis.digits,
iam.cdPtyNum.natAddrInd.val);
iam.cdPtyNum.natAddrInd.val,
ftdmchan->caller_data.loc.digits,
iam.cgPtyNum1.natAddrInd.val);
}
sng_cc_con_request (sngss7_info->spId,
@ -106,16 +231,124 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
&iam,
0);
if (native_going_up) {
/*
Note that this function (ft_to_sngss7_iam) is run within the main SS7 processing loop in
response to the DIALING state handler, we can set the state to UP here and that will
implicitly complete the DIALING state, but we *MUST* also advance the state handler
right away for a native bridge, otherwise, the processing state function (ftdm_sangoma_ss7_process_state_change)
will complete the state without having executed the handler for FTDM_CHANNEL_STATE_UP, and we won't notify
the user sending FTDM_SIGEVENT_UP which can cause the application to misbehave (ie, no audio) */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP);
ftdm_channel_advance_states(ftdmchan);
}
ftdm_safe_free(event_clone);
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
return;
}
void ft_to_sngss7_inf(ftdm_channel_t *ftdmchan, SiCnStEvnt *inr)
{
SiCnStEvnt evnt;
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
memset (&evnt, 0x0, sizeof (evnt));
evnt.infoInd.eh.pres = PRSNT_NODEF;
evnt.infoInd.cgPtyAddrRespInd.pres = PRSNT_NODEF;
evnt.infoInd.cgPtyCatRespInd.pres = PRSNT_NODEF;
evnt.infoInd.chrgInfoRespInd.pres = PRSNT_NODEF;
evnt.infoInd.chrgInfoRespInd.val = 0;
evnt.infoInd.solInfoInd.pres = PRSNT_NODEF;
evnt.infoInd.solInfoInd.val = 0;
evnt.infoInd.holdProvInd.pres = PRSNT_NODEF;
evnt.infoInd.holdProvInd.val = 0;
evnt.infoInd.spare.pres = PRSNT_NODEF;
evnt.infoInd.spare.val = 0;
if (inr->infoReqInd.eh.pres == PRSNT_NODEF) {
if ((inr->infoReqInd.holdingInd.pres == PRSNT_NODEF) && (inr->infoReqInd.holdingInd.val == HOLD_REQ)) {
SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Received INR requesting holding information. Holding is not supported in INF.\n", sngss7_info->circuit->cic);
}
if ((inr->infoReqInd.chrgInfoReqInd.pres == PRSNT_NODEF) && (inr->infoReqInd.chrgInfoReqInd.val == CHRGINFO_REQ)) {
SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Received INR requesting charging information. Charging is not supported in INF.\n", sngss7_info->circuit->cic);
}
if ((inr->infoReqInd.malCaIdReqInd.pres == PRSNT_NODEF) && (inr->infoReqInd.malCaIdReqInd.val == CHRGINFO_REQ)) {
SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Received INR requesting malicious call id. Malicious call id is not supported in INF.\n", sngss7_info->circuit->cic);
}
if ((inr->infoReqInd.cgPtyAdReqInd.pres == PRSNT_NODEF) && (inr->infoReqInd.cgPtyAdReqInd.val == CGPRTYADDREQ_REQ)) {
evnt.infoInd.cgPtyAddrRespInd.val=CGPRTYADDRESP_INCL;
copy_cgPtyNum_to_sngss7 (ftdmchan, &evnt.cgPtyNum);
} else {
evnt.infoInd.cgPtyAddrRespInd.val=CGPRTYADDRESP_NOTINCL;
}
if ((inr->infoReqInd.cgPtyCatReqInd.pres == PRSNT_NODEF) && (inr->infoReqInd.cgPtyCatReqInd.val == CGPRTYCATREQ_REQ)) {
evnt.infoInd.cgPtyCatRespInd.val = CGPRTYCATRESP_INCL;
copy_cgPtyCat_to_sngss7 (ftdmchan, &evnt.cgPtyCat);
} else {
evnt.infoInd.cgPtyCatRespInd.val = CGPRTYCATRESP_NOTINCL;
}
}
else {
SS7_DEBUG_CHAN(ftdmchan,"[CIC:%d]Received INR with no information request. Sending back default INF.\n", sngss7_info->circuit->cic);
}
sng_cc_inf(1,
sngss7_info->suInstId,
sngss7_info->spInstId,
sngss7_info->circuit->id,
&evnt,
INFORMATION);
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx INF\n", sngss7_info->circuit->cic);
}
void ft_to_sngss7_inr(ftdm_channel_t *ftdmchan)
{
SiCnStEvnt evnt;
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
memset (&evnt, 0x0, sizeof (evnt));
evnt.infoReqInd.eh.pres = PRSNT_NODEF;
evnt.infoReqInd.cgPtyAdReqInd.pres = PRSNT_NODEF;
evnt.infoReqInd.cgPtyAdReqInd.val=CGPRTYADDREQ_REQ;
evnt.infoReqInd.holdingInd.pres = PRSNT_NODEF;
evnt.infoReqInd.holdingInd.val = HOLD_REQ;
evnt.infoReqInd.cgPtyCatReqInd.pres = PRSNT_NODEF;
evnt.infoReqInd.cgPtyCatReqInd.val = CGPRTYCATREQ_REQ;
evnt.infoReqInd.chrgInfoReqInd.pres = PRSNT_NODEF;
evnt.infoReqInd.chrgInfoReqInd.val = CHRGINFO_REQ;
evnt.infoReqInd.malCaIdReqInd.pres = PRSNT_NODEF;
evnt.infoReqInd.malCaIdReqInd.val = MLBG_INFOREQ;
sng_cc_inr(1,
sngss7_info->suInstId,
sngss7_info->spInstId,
sngss7_info->circuit->id,
&evnt,
INFORMATREQ);
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx INR\n", sngss7_info->circuit->cic);
}
void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan)
{
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
SiCnStEvnt acm;
const char *backwardInd = NULL;
memset (&acm, 0x0, sizeof (acm));
@ -133,8 +366,16 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan)
acm.bckCallInd.intInd.val = INTIND_NOINTW;
acm.bckCallInd.end2EndInfoInd.pres = PRSNT_NODEF;
acm.bckCallInd.end2EndInfoInd.val = E2EINF_NOINFO;
acm.bckCallInd.isdnUsrPrtInd.pres = PRSNT_NODEF;
acm.bckCallInd.isdnUsrPrtInd.val = ISUP_USED;
acm.bckCallInd.isdnUsrPrtInd.val = ISUP_NOTUSED;
backwardInd = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "acm_bi_iup");
if (!ftdm_strlen_zero(backwardInd)) {
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied backward indicator ISDN user part indicator ACM, value \"%s\"\n", backwardInd);
if (atoi(backwardInd) != 0 ) {
acm.bckCallInd.isdnUsrPrtInd.val = ISUP_USED;
}
}
acm.bckCallInd.holdInd.pres = PRSNT_NODEF;
acm.bckCallInd.holdInd.val = HOLD_NOTREQD;
acm.bckCallInd.isdnAccInd.pres = PRSNT_NODEF;
@ -241,6 +482,7 @@ void ft_to_sngss7_anm (ftdm_channel_t * ftdmchan)
/******************************************************************************/
void ft_to_sngss7_rel (ftdm_channel_t * ftdmchan)
{
const char *loc_ind = NULL;
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
@ -250,7 +492,15 @@ void ft_to_sngss7_rel (ftdm_channel_t * ftdmchan)
rel.causeDgn.eh.pres = PRSNT_NODEF;
rel.causeDgn.location.pres = PRSNT_NODEF;
rel.causeDgn.location.val = 0x01;
loc_ind = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_rel_loc");
if (!ftdm_strlen_zero(loc_ind)) {
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied location indicator in REL, value \"%s\"\n", loc_ind);
rel.causeDgn.location.val = atoi(loc_ind);
} else {
rel.causeDgn.location.val = 0x01;
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "No user supplied location indicator in REL, using 0x01\"%s\"\n", "");
}
rel.causeDgn.cdeStand.pres = PRSNT_NODEF;
rel.causeDgn.cdeStand.val = 0x00;
rel.causeDgn.recommend.pres = NOTPRSNT;
@ -260,10 +510,10 @@ void ft_to_sngss7_rel (ftdm_channel_t * ftdmchan)
/* send the REL request to LibSngSS7 */
sng_cc_rel_request (1,
sngss7_info->suInstId,
sngss7_info->spInstId,
sngss7_info->circuit->id,
&rel);
sngss7_info->suInstId,
sngss7_info->spInstId,
sngss7_info->circuit->id,
&rel);
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx REL cause=%d \n",
sngss7_info->circuit->cic,
@ -518,8 +768,6 @@ void ft_to_sngss7_grs (ftdm_channel_t *fchan)
cinfo->circuit->cic,
(cinfo->circuit->cic + cinfo->tx_grs.range));
memset(&cinfo->tx_grs, 0, sizeof(cinfo->tx_grs));
sngss7_set_ckt_flag(cinfo, FLAG_GRP_RESET_SENT);
SS7_FUNC_TRACE_EXIT (__FUNCTION__);

View File

@ -42,8 +42,6 @@
/******************************************************************************/
/* PROTOTYPES *****************************************************************/
ftdm_status_t handle_relay_connect(RyMngmt *sta);
ftdm_status_t handle_relay_disconnect(RyMngmt *sta);
/*static ftdm_status_t enable_all_ckts_for_relay(void);*/
static ftdm_status_t reconfig_all_ckts_for_relay(void);
@ -66,11 +64,9 @@ ftdm_status_t handle_relay_connect(RyMngmt *sta)
SS7_INFO("Relay Channel %d connection UP\n", sng_relay->id);
if (sng_relay->type == LRY_CT_TCP_CLIENT) {
if (!sngss7_test_flag(sng_relay, SNGSS7_RELAY_INIT)) {
if (reconfig_all_ckts_for_relay()) {
SS7_ERROR("Failed to reconfigure ISUP Ckts!\n");
/* we're done....this is very bad! */
}
if (reconfig_all_ckts_for_relay()) {
SS7_ERROR("Failed to reconfigure ISUP Ckts!\n");
/* we're done....this is very bad! */
}
return FTDM_SUCCESS;
} else if (sng_relay->type == LRY_CT_TCP_SERVER) {
@ -84,23 +80,24 @@ ftdm_status_t handle_relay_connect(RyMngmt *sta)
/******************************************************************************/
ftdm_status_t handle_relay_disconnect_on_error(RyMngmt *sta)
{
SS7_DEBUG("SS7 relay disconnect on error\n");
/* check which procId is in error, if it is 1, disable the ckts */
if (sta->t.usta.s.ryErrUsta.errPid == 1 ) {
/* we've lost the server, bring down the mtp2 links */
disble_all_mtp2_sigs_for_relay();
/* we've lost the server, bring the sig status down on all ckts */
disable_all_ckts_for_relay();
/* we've lost the server, bring down the mtp2 links */
disble_all_mtp2_sigs_for_relay();
}
/* check if the channel is a server, means we just lost a MGW */
if (g_ftdm_sngss7_data.cfg.relay[sta->t.usta.s.ryErrUsta.errPid].type == LRY_CT_TCP_SERVER) {
/* we've lost the client, bring down all mtp3 links for this procId */
disable_all_sigs_for_relay(sta->t.usta.s.ryErrUsta.errPid);
/* we've lost the client, bring down all the ckts for this procId */
block_all_ckts_for_relay(sta->t.usta.s.ryErrUsta.errPid);
/* we've lost the client, bring down all mtp3 links for this procId */
disable_all_sigs_for_relay(sta->t.usta.s.ryErrUsta.errPid);
}
return FTDM_SUCCESS;
@ -110,6 +107,8 @@ ftdm_status_t handle_relay_disconnect_on_error(RyMngmt *sta)
ftdm_status_t handle_relay_disconnect_on_down(RyMngmt *sta)
{
SS7_DEBUG("SS7 relay disconnect on down\n");
/* check if the channel is a server, means we just lost a MGW */
if (g_ftdm_sngss7_data.cfg.relay[sta->t.usta.s.ryUpUsta.id].type == LRY_CT_TCP_SERVER) {
block_all_ckts_for_relay(sta->t.usta.s.ryUpUsta.id);
@ -248,7 +247,7 @@ ftdm_status_t block_all_ckts_for_relay(uint32_t procId)
if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == SNG_CKT_VOICE) {
/* send a block request via stack manager */
ret = ftmod_ss7_block_isup_ckt(g_ftdm_sngss7_data.cfg.isupCkt[x].id);
ret = ftmod_ss7_block_isup_ckt_nowait(g_ftdm_sngss7_data.cfg.isupCkt[x].id);
if (ret) {
SS7_INFO("Successfully BLOcked CIC:%d(ckt:%d) due to Relay failure\n",
g_ftdm_sngss7_data.cfg.isupCkt[x].cic,
@ -331,6 +330,7 @@ static ftdm_status_t unblock_all_ckts_for_relay(uint32_t procId)
}
#endif
/******************************************************************************/
/* For Emacs:
* Local Variables:

View File

@ -49,7 +49,7 @@
/******************************************************************************/
/* PROTOTYPES *****************************************************************/
void handle_isup_t35(void *userdata);
/******************************************************************************/
/* FUNCTIONS ******************************************************************/
@ -76,10 +76,13 @@ void handle_isup_t35(void *userdata)
/* end the call */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
/* kill t10 if active */
/* kill t10 t39 if active */
if (sngss7_info->t10.hb_timer_id) {
ftdm_sched_cancel_timer (sngss7_info->t10.sched, sngss7_info->t10.hb_timer_id);
}
if (sngss7_info->t39.hb_timer_id) {
ftdm_sched_cancel_timer (sngss7_info->t39.sched, sngss7_info->t39.hb_timer_id);
}
/*unlock*/
ftdm_channel_unlock(ftdmchan);
@ -108,7 +111,43 @@ void handle_isup_t10(void *userdata)
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
}
void handle_isup_t39(void *userdata)
{
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
sngss7_timer_data_t *timer = userdata;
sngss7_chan_data_t *sngss7_info = timer->sngss7_info;
ftdm_channel_t *ftdmchan = sngss7_info->ftdmchan;
/* now that we have the right channel...put a lock on it so no-one else can use it */
ftdm_channel_lock(ftdmchan);
/* Q.764 2.2.5 Address incomplete (T35 expiry action is hangup with cause 28 according to Table A.1/Q.764) */
SS7_ERROR("[Call-Control] Timer 39 expired on CIC = %d\n", sngss7_info->circuit->cic);
/* set the flag to indicate this hangup is started from the local side */
sngss7_set_ckt_flag(sngss7_info, FLAG_LOCAL_REL);
/* hang up on timer expiry */
ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_INVALID_NUMBER_FORMAT;
/* end the call */
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
/* kill t10 t35 if active */
if (sngss7_info->t10.hb_timer_id) {
ftdm_sched_cancel_timer (sngss7_info->t10.sched, sngss7_info->t10.hb_timer_id);
}
if (sngss7_info->t35.hb_timer_id) {
ftdm_sched_cancel_timer (sngss7_info->t35.sched, sngss7_info->t35.hb_timer_id);
}
/*unlock*/
ftdm_channel_unlock(ftdmchan);
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
}
/******************************************************************************/
/* For Emacs:
* Local Variables:

View File

@ -29,6 +29,12 @@
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* Contributors:
*
* James Zhang <jzhang@sangoma.com>
*
*/
/* INCLUDE ********************************************************************/
@ -124,9 +130,13 @@ typedef struct sng_ccSpan
uint32_t clg_nadi;
uint32_t cld_nadi;
uint32_t rdnis_nadi;
uint32_t loc_nadi;
uint32_t min_digits;
uint8_t itx_auto_reply;
uint32_t transparent_iam_max_size;
uint8_t transparent_iam;
uint8_t cpg_on_progress_media;
uint8_t cpg_on_progress;
uint8_t itx_auto_reply;
uint32_t t3;
uint32_t t10;
uint32_t t12;
@ -136,6 +146,7 @@ typedef struct sng_ccSpan
uint32_t t16;
uint32_t t17;
uint32_t t35;
uint32_t t39;
uint32_t tval;
} sng_ccSpan_t;
@ -187,18 +198,20 @@ static int ftmod_ss7_fill_in_self_route(int spc, int linkType, int switchType, i
static int ftmod_ss7_fill_in_circuits(sng_span_t *sngSpan);
static int ftmod_ss7_next_timeslot(char *ch_map, sng_timeslot_t *timeslot);
static void ftmod_ss7_set_glare_resolution (const char *method);
/******************************************************************************/
/* FUNCTIONS ******************************************************************/
int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span)
{
sng_route_t self_route;
sng_span_t sngSpan;
int i = 0;
const char *var = NULL;
const char *val = NULL;
ftdm_conf_node_t *ptr = NULL;
sng_route_t self_route;
sng_span_t sngSpan;
/* clean out the isup ckt */
memset(&sngSpan, 0x0, sizeof(sngSpan));
@ -206,11 +219,31 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa
/* clean out the self route */
memset(&self_route, 0x0, sizeof(self_route));
var = ftdm_parameters[i].var;
val = ftdm_parameters[i].val;
g_ftdm_operating_mode = SNG_SS7_OPR_MODE_ISUP;
/* confirm that the first parameter is the "operating-mode" */
if(!strcasecmp(var, "operating-mode")){
if(!strcasecmp(val, "ISUP")) {
g_ftdm_operating_mode = SNG_SS7_OPR_MODE_ISUP;
}
else if(!strcasecmp(val, "M2UA_SG")) {
g_ftdm_operating_mode = SNG_SS7_OPR_MODE_M2UA_SG;
} else {
SS7_DEBUG("Operating mode not specified, defaulting to ISUP\n");
}
i++;
}
var = ftdm_parameters[i].var;
val = ftdm_parameters[i].val;
ptr = (ftdm_conf_node_t *)ftdm_parameters[i].ptr;
/* confirm that the first parameter is the "confnode" */
/* confirm that the 2nd parameter is the "confnode" */
if (!strcasecmp(var, "confnode")) {
/* parse the confnode and fill in the global libsng_ss7 config structure */
if (ftmod_ss7_parse_sng_isup(ptr)) {
@ -225,28 +258,20 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa
}
i++;
while (ftdm_parameters[i].var != NULL) {
/**************************************************************************/
while (ftdm_parameters[i].var != NULL) {
var = ftdm_parameters[i].var;
val = ftdm_parameters[i].val;
if (!strcasecmp(var, "dialplan")) {
/**********************************************************************/
/* don't care for now */
/**********************************************************************/
} else if (!strcasecmp(var, "context")) {
/**********************************************************************/
/* don't care for now */
/**********************************************************************/
} else if (!strcasecmp(var, "ccSpanId")) {
/**********************************************************************/
} else if (!strcasecmp(var, "span-id") || !strcasecmp(var, "ccSpanId")) {
sngSpan.ccSpanId = atoi(val);
SS7_DEBUG("Found an ccSpanId = %d\n",sngSpan.ccSpanId);
/**********************************************************************/
} else {
SS7_ERROR("Unknown parameter found =\"%s\"...ignoring it!\n", var);
/**********************************************************************/
}
i++;
@ -255,10 +280,12 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa
/* fill the pointer to span into isupCkt */
sngSpan.span = span;
/* setup the circuits structure */
if(ftmod_ss7_fill_in_circuits(&sngSpan)) {
SS7_ERROR("Failed to fill in circuits structure!\n");
goto ftmod_ss7_parse_xml_error;
if(SNG_SS7_OPR_MODE_ISUP == g_ftdm_operating_mode){
/* setup the circuits structure */
if(ftmod_ss7_fill_in_circuits(&sngSpan)) {
SS7_ERROR("Failed to fill in circuits structure!\n");
goto ftmod_ss7_parse_xml_error;
}
}
return FTDM_SUCCESS;
@ -280,6 +307,11 @@ static int ftmod_ss7_parse_sng_isup(ftdm_conf_node_t *sng_isup)
ftdm_conf_node_t *isup_interfaces = NULL;
ftdm_conf_node_t *cc_spans = NULL;
ftdm_conf_node_t *tmp_node = NULL;
ftdm_conf_node_t *nif_ifaces = NULL;
ftdm_conf_node_t *m2ua_ifaces = NULL;
ftdm_conf_node_t *m2ua_peer_ifaces = NULL;
ftdm_conf_node_t *m2ua_clust_ifaces = NULL;
ftdm_conf_node_t *sctp_ifaces = NULL;
/* confirm that we are looking at sng_isup */
if (strcasecmp(sng_isup->name, "sng_isup")) {
@ -385,12 +417,62 @@ static int ftmod_ss7_parse_sng_isup(ftdm_conf_node_t *sng_isup)
return FTDM_FAIL;
}
/**********************************************************************/
} else if (!strcasecmp(tmp_node->name, "sng_nif_interfaces")) {
/**********************************************************************/
if (nif_ifaces == NULL) {
nif_ifaces = tmp_node;
SS7_DEBUG("Found a \"sng_nif_interfaces\" section!\n");
} else {
SS7_ERROR("Found a second \"sng_nif_interfaces\" section\n!");
return FTDM_FAIL;
}
/**********************************************************************/
} else if (!strcasecmp(tmp_node->name, "sng_m2ua_interfaces")) {
/**********************************************************************/
if (m2ua_ifaces == NULL) {
m2ua_ifaces = tmp_node;
SS7_DEBUG("Found a \"sng_m2ua_interfaces\" section!\n");
} else {
SS7_ERROR("Found a second \"sng_m2ua_interfaces\" section\n!");
return FTDM_FAIL;
}
/**********************************************************************/
} else if (!strcasecmp(tmp_node->name, "sng_m2ua_peer_interfaces")) {
/**********************************************************************/
if (m2ua_peer_ifaces == NULL) {
m2ua_peer_ifaces = tmp_node;
SS7_DEBUG("Found a \"sng_m2ua_peer_interfaces\" section!\n");
} else {
SS7_ERROR("Found a second \"sng_m2ua_peer_interfaces\" section\n!");
return FTDM_FAIL;
}
/**********************************************************************/
} else if (!strcasecmp(tmp_node->name, "sng_m2ua_cluster_interfaces")) {
/**********************************************************************/
if (m2ua_clust_ifaces == NULL) {
m2ua_clust_ifaces = tmp_node;
SS7_DEBUG("Found a \"sng_m2ua_cluster_interfaces\" section!\n");
} else {
SS7_ERROR("Found a second \"sng_m2ua_peer_interfaces\" section\n!");
return FTDM_FAIL;
}
/**********************************************************************/
} else if (!strcasecmp(tmp_node->name, "sng_sctp_interfaces")) {
/**********************************************************************/
if (sctp_ifaces == NULL) {
sctp_ifaces = tmp_node;
SS7_DEBUG("Found a <sng_sctp_interfaces> section!\n");
} else {
SS7_ERROR("Found a second <sng_sctp_interfaces> section!\n");
return FTDM_FAIL;
}
/**********************************************************************/
} else {
/**********************************************************************/
SS7_ERROR("\tFound an unknown section \"%s\"!\n", tmp_node->name);
return FTDM_FAIL;
/**********************************************************************/
}
}
/* go to the next sibling */
tmp_node = tmp_node->next;
@ -417,34 +499,92 @@ static int ftmod_ss7_parse_sng_isup(ftdm_conf_node_t *sng_isup)
return FTDM_FAIL;
}
if (ftmod_ss7_parse_mtp3_links(mtp3_links)) {
SS7_ERROR("Failed to parse \"mtp3_links\"!\n");
return FTDM_FAIL;
}
if (ftmod_ss7_parse_mtp_linksets(mtp_linksets)) {
SS7_ERROR("Failed to parse \"mtp_linksets\"!\n");
return FTDM_FAIL;
}
switch(g_ftdm_operating_mode)
{
case SNG_SS7_OPR_MODE_ISUP:
{
if (mtp3_links && ftmod_ss7_parse_mtp3_links(mtp3_links)) {
SS7_ERROR("Failed to parse \"mtp3_links\"!\n");
return FTDM_FAIL;
}
if (ftmod_ss7_parse_mtp_routes(mtp_routes)) {
SS7_ERROR("Failed to parse \"mtp_routes\"!\n");
return FTDM_FAIL;
}
if (ftmod_ss7_parse_mtp_linksets(mtp_linksets)) {
SS7_ERROR("Failed to parse \"mtp_linksets\"!\n");
return FTDM_FAIL;
}
if (ftmod_ss7_parse_isup_interfaces(isup_interfaces)) {
SS7_ERROR("Failed to parse \"isup_interfaces\"!\n");
return FTDM_FAIL;
}
if (ftmod_ss7_parse_mtp_routes(mtp_routes)) {
SS7_ERROR("Failed to parse \"mtp_routes\"!\n");
return FTDM_FAIL;
}
if (isup_interfaces && ftmod_ss7_parse_isup_interfaces(isup_interfaces)) {
SS7_ERROR("Failed to parse \"isup_interfaces\"!\n");
return FTDM_FAIL;
}
if (cc_spans && ftmod_ss7_parse_cc_spans(cc_spans)) {
SS7_ERROR("Failed to parse \"cc_spans\"!\n");
return FTDM_FAIL;
}
break;
}
case SNG_SS7_OPR_MODE_M2UA_SG:
{
if (ftmod_ss7_parse_sctp_links(sctp_ifaces) != FTDM_SUCCESS) {
SS7_ERROR("Failed to parse <sctp_links>!\n");
return FTDM_FAIL;
}
if (nif_ifaces && ftmod_ss7_parse_nif_interfaces(nif_ifaces)) {
SS7_ERROR("Failed to parse \"nif_ifaces\"!\n");
return FTDM_FAIL;
}
if (m2ua_ifaces && ftmod_ss7_parse_m2ua_interfaces(m2ua_ifaces)) {
SS7_ERROR("Failed to parse \"m2ua_ifaces\"!\n");
return FTDM_FAIL;
}
if (m2ua_peer_ifaces && ftmod_ss7_parse_m2ua_peer_interfaces(m2ua_peer_ifaces)) {
SS7_ERROR("Failed to parse \"m2ua_peer_ifaces\"!\n");
return FTDM_FAIL;
}
if (m2ua_clust_ifaces && ftmod_ss7_parse_m2ua_clust_interfaces(m2ua_clust_ifaces)) {
SS7_ERROR("Failed to parse \"m2ua_clust_ifaces\"!\n");
return FTDM_FAIL;
}
break;
}
default:
SS7_ERROR("Invalid operating mode[%d]\n",g_ftdm_operating_mode);
break;
if (ftmod_ss7_parse_cc_spans(cc_spans)) {
SS7_ERROR("Failed to parse \"cc_spans\"!\n");
return FTDM_FAIL;
}
return FTDM_SUCCESS;
}
static void ftmod_ss7_set_glare_resolution (const char *method)
{
sng_glare_resolution iMethod=SNGSS7_GLARE_PC;
if (!method || (strlen (method) <=0) ) {
SS7_ERROR( "Wrong glare resolution parameter, using default. \n" );
} else {
if (!strcasecmp( method, "PointCode")) {
iMethod = SNGSS7_GLARE_PC;
} else if (!strcasecmp( method, "Down")) {
iMethod = SNGSS7_GLARE_DOWN;
} else if (!strcasecmp( method, "Control")) {
iMethod = SNGSS7_GLARE_CONTROL;
} else {
SS7_ERROR( "Wrong glare resolution parameter, using default. \n" );
iMethod = SNGSS7_GLARE_PC;
}
}
g_ftdm_sngss7_data.cfg.glareResolution = iMethod;
}
/******************************************************************************/
static int ftmod_ss7_parse_sng_gen(ftdm_conf_node_t *sng_gen)
{
@ -452,31 +592,41 @@ static int ftmod_ss7_parse_sng_gen(ftdm_conf_node_t *sng_gen)
int num_parms = sng_gen->n_parameters;
int i = 0;
/* Set the transparent_iam_max_size to default value */
g_ftdm_sngss7_data.cfg.transparent_iam_max_size=800;
g_ftdm_sngss7_data.cfg.force_inr = 0;
/* extract all the information from the parameters */
for (i = 0; i < num_parms; i++) {
/**************************************************************************/
if (!strcasecmp(parm->var, "procId")) {
/**********************************************************************/
g_ftdm_sngss7_data.cfg.procId = atoi(parm->val);
SS7_DEBUG("Found a procId = %d\n", g_ftdm_sngss7_data.cfg.procId);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "license")) {
/**********************************************************************/
strcpy(g_ftdm_sngss7_data.cfg.license, parm->val);
strcpy(g_ftdm_sngss7_data.cfg.signature, parm->val);
strcat(g_ftdm_sngss7_data.cfg.signature, ".sig");
}
else if (!strcasecmp(parm->var, "license")) {
ftdm_set_string(g_ftdm_sngss7_data.cfg.license, parm->val);
snprintf(g_ftdm_sngss7_data.cfg.signature, sizeof(g_ftdm_sngss7_data.cfg.signature), "%s.sig", parm->val);
SS7_DEBUG("Found license file = %s\n", g_ftdm_sngss7_data.cfg.license);
SS7_DEBUG("Found signature file = %s\n", g_ftdm_sngss7_data.cfg.signature);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "transparent_iam_max_size")) {
}
else if (!strcasecmp(parm->var, "transparent_iam_max_size")) {
g_ftdm_sngss7_data.cfg.transparent_iam_max_size = atoi(parm->val);
SS7_DEBUG("Found a transparent_iam max size = %d\n", g_ftdm_sngss7_data.cfg.transparent_iam_max_size);
} else {
/**********************************************************************/
}
else if (!strcasecmp(parm->var, "glare-reso")) {
ftmod_ss7_set_glare_resolution (parm->val);
SS7_DEBUG("Found glare resolution configuration = %d %s\n", g_ftdm_sngss7_data.cfg.glareResolution, parm->val );
}
else if (!strcasecmp(parm->var, "force-inr")) {
if (ftdm_true(parm->val)) {
g_ftdm_sngss7_data.cfg.force_inr = 1;
} else {
g_ftdm_sngss7_data.cfg.force_inr = 0;
}
SS7_DEBUG("Found INR force configuration = %s\n", parm->val );
}
else {
SS7_ERROR("Found an invalid parameter \"%s\"!\n", parm->val);
return FTDM_FAIL;
/**********************************************************************/
}
/* move to the next parmeter */
@ -1845,12 +1995,14 @@ static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span)
int flag_clg_nadi = 0;
int flag_cld_nadi = 0;
int flag_rdnis_nadi = 0;
int flag_loc_nadi = 0;
int i;
int ret;
/* initalize the ccSpan structure */
memset(&sng_ccSpan, 0x0, sizeof(sng_ccSpan));
/* confirm that we are looking at an mtp_link */
if (strcasecmp(cc_span->name, "cc_span")) {
SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"cc_span\"!\n",cc_span->name);
@ -1859,6 +2011,14 @@ static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span)
SS7_DEBUG("Parsing \"cc_span\"...\n");
}
/* Backward compatible.
* If cpg_on_progress_media is not in the config file
* default the cpg on progress_media to TRUE */
sng_ccSpan.cpg_on_progress_media=FTDM_TRUE;
/* If transparent_iam_max_size is not set in cc spans
* use the global value */
sng_ccSpan.transparent_iam_max_size=g_ftdm_sngss7_data.cfg.transparent_iam_max_size;
for (i = 0; i < num_parms; i++) {
/**************************************************************************/
@ -1904,6 +2064,15 @@ static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span)
sng_ccSpan.transparent_iam = ftdm_true(parm->val);
SS7_DEBUG("Found transparent_iam %d\n", sng_ccSpan.transparent_iam);
#endif
} else if (!strcasecmp(parm->var, "transparent_iam_max_size")) {
sng_ccSpan.transparent_iam_max_size = atoi(parm->val);
SS7_DEBUG("Found transparent_iam_max_size %d\n", sng_ccSpan.transparent_iam_max_size);
} else if (!strcasecmp(parm->var, "cpg_on_progress_media")) {
sng_ccSpan.cpg_on_progress_media = ftdm_true(parm->val);
SS7_DEBUG("Found cpg_on_progress_media %d\n", sng_ccSpan.cpg_on_progress_media);
} else if (!strcasecmp(parm->var, "cpg_on_progress")) {
sng_ccSpan.cpg_on_progress = ftdm_true(parm->val);
SS7_DEBUG("Found cpg_on_progress %d\n", sng_ccSpan.cpg_on_progress);
} else if (!strcasecmp(parm->var, "cicbase")) {
/**********************************************************************/
sng_ccSpan.cicbase = atoi(parm->val);
@ -1946,6 +2115,12 @@ static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span)
SS7_DEBUG("Invalid parm->value for obci_bita option\n");
}
/**********************************************************************/
} else if (!strcasecmp(parm->var, "loc_nadi")) {
/* add location reference number */
flag_loc_nadi = 1;
sng_ccSpan.loc_nadi = atoi(parm->val);
SS7_DEBUG("Found default LOC_NADI parm->value = %d\n", sng_ccSpan.loc_nadi);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "lpa_on_cot")) {
/**********************************************************************/
if (*parm->val == '1') {
@ -2002,6 +2177,11 @@ static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span)
sng_ccSpan.t35 = atoi(parm->val);
SS7_DEBUG("Found isup t35 = %d\n",sng_ccSpan.t35);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.t39")) {
/**********************************************************************/
sng_ccSpan.t39 = atoi(parm->val);
SS7_DEBUG("Found isup t39 = %d\n",sng_ccSpan.t39);
/**********************************************************************/
} else if (!strcasecmp(parm->var, "isup.tval")) {
/**********************************************************************/
sng_ccSpan.tval = atoi(parm->val);
@ -2035,6 +2215,11 @@ static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span)
sng_ccSpan.rdnis_nadi = 0x03;
}
if (!flag_loc_nadi) {
/* default the nadi value to national */
sng_ccSpan.loc_nadi = 0x03;
}
/* pull up the SSF and Switchtype from the isup interface */
sng_ccSpan.ssf = g_ftdm_sngss7_data.cfg.isupIntf[sng_ccSpan.isupInf].ssf;
sng_ccSpan.switchType = g_ftdm_sngss7_data.cfg.isupIntf[sng_ccSpan.isupInf].switchType;
@ -2723,7 +2908,7 @@ static int ftmod_ss7_fill_in_isap(sng_isap_t *sng_isap)
if (sng_isap->t1 != 0) {
g_ftdm_sngss7_data.cfg.isap[i].t1 = sng_isap->t1;
} else {
g_ftdm_sngss7_data.cfg.isap[i].t1 = 200;
g_ftdm_sngss7_data.cfg.isap[i].t1 = 150;
}
if (sng_isap->t2 != 0) {
g_ftdm_sngss7_data.cfg.isap[i].t2 = sng_isap->t2;
@ -2738,17 +2923,17 @@ static int ftmod_ss7_fill_in_isap(sng_isap_t *sng_isap)
if (sng_isap->t6 != 0) {
g_ftdm_sngss7_data.cfg.isap[i].t6 = sng_isap->t6;
} else {
g_ftdm_sngss7_data.cfg.isap[i].t6 = 200;
g_ftdm_sngss7_data.cfg.isap[i].t6 = 600;
}
if (sng_isap->t7 != 0) {
g_ftdm_sngss7_data.cfg.isap[i].t7 = sng_isap->t7;
} else {
g_ftdm_sngss7_data.cfg.isap[i].t7 = 250;
g_ftdm_sngss7_data.cfg.isap[i].t7 = 200;
}
if (sng_isap->t8 != 0) {
g_ftdm_sngss7_data.cfg.isap[i].t8 = sng_isap->t8;
} else {
g_ftdm_sngss7_data.cfg.isap[i].t8 = 120;
g_ftdm_sngss7_data.cfg.isap[i].t8 = 100;
}
if (sng_isap->t9 != 0) {
g_ftdm_sngss7_data.cfg.isap[i].t9 = sng_isap->t9;
@ -2863,7 +3048,7 @@ static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan)
(g_ftdm_sngss7_data.cfg.isupCkt[x].chan == count)) {
/* we are processing a circuit that already exists */
SS7_DEBUG("Found an existing circuit %d, ccSpanId=%d, chan%d\n",
SS7_DEVEL_DEBUG("Found an existing circuit %d, ccSpanId=%d, chan%d\n",
x,
ccSpan->id,
count);
@ -2872,7 +3057,7 @@ static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan)
flag = 1;
/* not supporting reconfig at this time */
SS7_DEBUG("Not supporting ckt reconfig at this time!\n");
SS7_DEVEL_DEBUG("Not supporting ckt reconfig at this time!\n");
goto move_along;
} else {
/* this is not the droid you are looking for */
@ -2885,6 +3070,9 @@ static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan)
/* prepare the global info sturcture */
ss7_info = ftdm_calloc(1, sizeof(sngss7_chan_data_t));
ss7_info->ftdmchan = NULL;
if (ftdm_queue_create(&ss7_info->event_queue, SNGSS7_CHAN_EVENT_QUEUE_SIZE) != FTDM_SUCCESS) {
SS7_CRITICAL("Failed to create ss7 cic event queue\n");
}
ss7_info->circuit = &g_ftdm_sngss7_data.cfg.isupCkt[x];
g_ftdm_sngss7_data.cfg.isupCkt[x].obj = ss7_info;
@ -2919,12 +3107,16 @@ static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan)
g_ftdm_sngss7_data.cfg.isupCkt[x].ssf = ccSpan->ssf;
g_ftdm_sngss7_data.cfg.isupCkt[x].cld_nadi = ccSpan->cld_nadi;
g_ftdm_sngss7_data.cfg.isupCkt[x].clg_nadi = ccSpan->clg_nadi;
g_ftdm_sngss7_data.cfg.isupCkt[x].rdnis_nadi = ccSpan->rdnis_nadi;
g_ftdm_sngss7_data.cfg.isupCkt[x].rdnis_nadi = ccSpan->rdnis_nadi;
g_ftdm_sngss7_data.cfg.isupCkt[x].loc_nadi = ccSpan->loc_nadi;
g_ftdm_sngss7_data.cfg.isupCkt[x].options = ccSpan->options;
g_ftdm_sngss7_data.cfg.isupCkt[x].switchType = ccSpan->switchType;
g_ftdm_sngss7_data.cfg.isupCkt[x].min_digits = ccSpan->min_digits;
g_ftdm_sngss7_data.cfg.isupCkt[x].itx_auto_reply = ccSpan->itx_auto_reply;
g_ftdm_sngss7_data.cfg.isupCkt[x].transparent_iam = ccSpan->transparent_iam;
g_ftdm_sngss7_data.cfg.isupCkt[x].switchType = ccSpan->switchType;
g_ftdm_sngss7_data.cfg.isupCkt[x].min_digits = ccSpan->min_digits;
g_ftdm_sngss7_data.cfg.isupCkt[x].itx_auto_reply = ccSpan->itx_auto_reply;
g_ftdm_sngss7_data.cfg.isupCkt[x].transparent_iam = ccSpan->transparent_iam;
g_ftdm_sngss7_data.cfg.isupCkt[x].transparent_iam_max_size = ccSpan->transparent_iam_max_size;
g_ftdm_sngss7_data.cfg.isupCkt[x].cpg_on_progress_media = ccSpan->cpg_on_progress_media;
g_ftdm_sngss7_data.cfg.isupCkt[x].cpg_on_progress = ccSpan->cpg_on_progress;
if (ccSpan->t3 == 0) {
g_ftdm_sngss7_data.cfg.isupCkt[x].t3 = 1200;
@ -2972,6 +3164,12 @@ static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan)
} else {
g_ftdm_sngss7_data.cfg.isupCkt[x].t35 = ccSpan->t35;
}
if (ccSpan->t39 == 0) {
g_ftdm_sngss7_data.cfg.isupCkt[x].t39 = 120;
} else {
g_ftdm_sngss7_data.cfg.isupCkt[x].t39 = ccSpan->t39;
}
if (ccSpan->tval == 0) {
g_ftdm_sngss7_data.cfg.isupCkt[x].tval = 10;
} else {
@ -3076,6 +3274,13 @@ static int ftmod_ss7_fill_in_circuits(sng_span_t *sngSpan)
ss7_info->t10.callback = handle_isup_t10;
ss7_info->t10.sngss7_info = ss7_info;
/* prepare the timer structures */
ss7_info->t39.sched = ((sngss7_span_data_t *)(ftdmspan->signal_data))->sched;
ss7_info->t39.counter = 1;
ss7_info->t39.beat = (isupCkt->t39) * 100; /* beat is in ms, t39 is in 100ms */
ss7_info->t39.callback = handle_isup_t39;
ss7_info->t39.sngss7_info = ss7_info;
/**************************************************************************/
} /* for (i == 1; i < ftdmspan->chan_count; i++) */

View File

@ -764,6 +764,28 @@ static FIO_COMMAND_FUNCTION(wanpipe_command)
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Disabled DTMF events\n");
#else
return FTDM_NOTIMPL;
#endif
}
break;
case FTDM_COMMAND_ENABLE_DTMF_REMOVAL:
{
#ifdef WP_API_FEATURE_LIBSNG_HWEC
int return_code = 0;
err = sangoma_hwec_set_hwdtmf_removal(ftdmchan->sockfd, ftdmchan->physical_chan_id, &return_code, 1, 0);
if (return_code) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Wanpipe failed to Disable HW-DTMF removal\n");
}
#endif
}
break;
case FTDM_COMMAND_DISABLE_DTMF_REMOVAL:
{
#ifdef WP_API_FEATURE_LIBSNG_HWEC
int return_code = 0;
err = sangoma_hwec_set_hwdtmf_removal(ftdmchan->sockfd, ftdmchan->physical_chan_id, &return_code, 0, 0);
if (return_code) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Wanpipe failed to Disable HW-DTMF removal\n");
}
#endif
}
break;

View File

@ -40,7 +40,6 @@
#ifndef FREETDM_H
#define FREETDM_H
#include "ftdm_declare.h"
#include "ftdm_call_utils.h"
@ -359,6 +358,7 @@ typedef struct ftdm_caller_data {
ftdm_number_t ani; /*!< ANI (Automatic Number Identification) */
ftdm_number_t dnis; /*!< DNIS (Dialed Number Identification Service) */
ftdm_number_t rdnis; /*!< RDNIS (Redirected Dialed Number Identification Service) */
ftdm_number_t loc; /*!< LOC (Location Reference Code) */
char aniII[FTDM_DIGITS_LIMIT]; /*! ANI II */
uint8_t screen; /*!< Screening */
uint8_t pres; /*!< Presentation*/
@ -733,6 +733,10 @@ typedef enum {
/*!< Enable/disable IO stats in the channel */
FTDM_COMMAND_SWITCH_IOSTATS = 60,
/*!< Enable/disable DTMF removal */
FTDM_COMMAND_ENABLE_DTMF_REMOVAL = 61,
FTDM_COMMAND_DISABLE_DTMF_REMOVAL = 62,
FTDM_COMMAND_COUNT,
} ftdm_command_t;
@ -1366,7 +1370,7 @@ FT_DECLARE(uint32_t) ftdm_group_get_id(const ftdm_group_t *group);
* Only use ftdm_channel_close if there is no call (incoming or outgoing) in the channel
*
* \param span_id The span id the channel belongs to
* \param chan_id Channel id of the channel you want to open
* \param chan_id Logical channel id of the channel you want to open
* \param ftdmchan Pointer to store the channel once is open
*
* \retval FTDM_SUCCESS success (the channel was found and is available)
@ -1374,6 +1378,23 @@ FT_DECLARE(uint32_t) ftdm_group_get_id(const ftdm_group_t *group);
*/
FT_DECLARE(ftdm_status_t) ftdm_channel_open(uint32_t span_id, uint32_t chan_id, ftdm_channel_t **ftdmchan);
/*!
* \brief Open a channel specifying the span id and physical chan id (required before placing a call on the channel)
*
* \warning Try using ftdm_call_place instead if you plan to place a call after opening the channel
*
* \note You must call ftdm_channel_close() or ftdm_channel_call_hangup() to release the channel afterwards
* Only use ftdm_channel_close if there is no call (incoming or outgoing) in the channel
*
* \param span_id The span id the channel belongs to
* \param chan_id Physical channel id of the channel you want to open
* \param ftdmchan Pointer to store the channel once is open
*
* \retval FTDM_SUCCESS success (the channel was found and is available)
* \retval FTDM_FAIL failure (channel was not found or not available)
*/
FT_DECLARE(ftdm_status_t) ftdm_channel_open_ph(uint32_t span_id, uint32_t chan_id, ftdm_channel_t **ftdmchan);
/*!
* \brief Hunts and opens a channel specifying the span id only
*
@ -1611,6 +1632,17 @@ FT_DECLARE(ftdm_status_t) ftdm_configure_span(ftdm_span_t *span, const char *typ
*/
FT_DECLARE(ftdm_status_t) ftdm_configure_span_signaling(ftdm_span_t *span, const char *type, fio_signal_cb_t sig_cb, ftdm_conf_parameter_t *parameters);
/*!
* \brief Register callback to listen for incoming events
* \note This function should only be used when there is no signalling module
* \param span The span to register to
* \param sig_cb The callback that the signaling stack will use to notify about events
*
* \retval FTDM_SUCCESS success
* \retval FTDM_FAIL failure
*/
FT_DECLARE(ftdm_status_t) ftdm_span_register_signal_cb(ftdm_span_t *span, fio_signal_cb_t sig_cb);
/*!
* \brief Start the span signaling (must call ftdm_configure_span_signaling first)
*
@ -1626,7 +1658,6 @@ FT_DECLARE(ftdm_status_t) ftdm_configure_span_signaling(ftdm_span_t *span, const
*/
FT_DECLARE(ftdm_status_t) ftdm_span_start(ftdm_span_t *span);
/*!
* \brief Stop the span signaling (must call ftdm_span_start first)
* \note certain signalings (boost signaling) does not support granular span start/stop
@ -1745,15 +1776,25 @@ FT_DECLARE(ftdm_trunk_type_t) ftdm_span_get_trunk_type(const ftdm_span_t *span);
FT_DECLARE(const char *) ftdm_span_get_trunk_type_str(const ftdm_span_t *span);
/*!
* \brief Return the channel identified by the provided id
* \brief Return the channel identified by the provided logical id
*
* \param span The span where the channel belongs
* \param chanid The channel id within the span
* \param chanid The logical channel id within the span
*
* \return The channel pointer if found, NULL otherwise
*/
FT_DECLARE(ftdm_channel_t *) ftdm_span_get_channel(const ftdm_span_t *span, uint32_t chanid);
/*!
* \brief Return the channel identified by the provided physical id
*
* \param span The span where the channel belongs
* \param chanid The physical channel id within the span
*
* \return The channel pointer if found, NULL otherwise
*/
FT_DECLARE(ftdm_channel_t *) ftdm_span_get_channel_ph(const ftdm_span_t *span, uint32_t chanid);
/*! \brief Return the channel count number for the given span */
FT_DECLARE(uint32_t) ftdm_span_get_chan_count(const ftdm_span_t *span);

View File

@ -130,6 +130,9 @@
extern "C" {
#endif
#define SPAN_PENDING_CHANS_QUEUE_SIZE 1000
#define SPAN_PENDING_SIGNALS_QUEUE_SIZE 1000
#define GOTO_STATUS(label,st) status = st; goto label ;
#define ftdm_copy_string(x,y,z) strncpy(x, y, z - 1)
@ -477,6 +480,7 @@ struct ftdm_channel {
int32_t txdrops;
int32_t rxdrops;
ftdm_usrmsg_t *usrmsg;
ftdm_time_t last_state_change_time;
};
struct ftdm_span {
@ -693,6 +697,9 @@ FT_DECLARE(ftdm_status_t) ftdm_sigmsg_remove_var(ftdm_sigmsg_t *sigmsg, const ch
*/
FT_DECLARE(ftdm_status_t) ftdm_sigmsg_set_raw_data(ftdm_sigmsg_t *sigmsg, void *data, ftdm_size_t datalen);
/*! \brief Retrieve a span and channel data structure from a string in the format 'span_id:chan_id'*/
FT_DECLARE(ftdm_status_t) ftdm_get_channel_from_string(const char *string_id, ftdm_span_t **out_span, ftdm_channel_t **out_channel);
/*!
\brief Assert condition
*/

View File

@ -162,6 +162,7 @@ typedef enum {
FTDM_SIGTYPE_ANALOG,
FTDM_SIGTYPE_SANGOMABOOST,
FTDM_SIGTYPE_M3UA,
FTDM_SIGTYPE_M2UA,
FTDM_SIGTYPE_R2,
FTDM_SIGTYPE_SS7,
FTDM_SIGTYPE_GSM
@ -198,6 +199,8 @@ typedef enum {
FTDM_SPAN_NON_STOPPABLE = (1 << 13),
/* If this flag is set, then this span supports TRANSFER state */
FTDM_SPAN_USE_TRANSFER = (1 << 14),
/* This is the last flag, no more flags bigger than this */
FTDM_SPAN_MAX_FLAG = (1 << 15),
} ftdm_span_flag_t;
/*! \brief Channel supported features */
@ -266,6 +269,12 @@ typedef enum {
#define FTDM_CHANNEL_BLOCKING (1ULL << 35)
/*!< Media is digital */
#define FTDM_CHANNEL_DIGITAL_MEDIA (1ULL << 36)
/*!< Native signaling bridge is enabled */
#define FTDM_CHANNEL_NATIVE_SIGBRIDGE (1ULL << 37)
/*!< This no more flags after this flag */
#define FTDM_CHANNEL_MAX_FLAG (1ULL << 38)
/*!<When adding a new flag, need to update ftdm_io.c:channel_flag_strs */
#include "ftdm_state.h"

View File

@ -18,7 +18,7 @@ a separate process, and your application communicates with it through pipes or
sockets.
This implementation of G.722.1 is adapted from the reference source code
provided by Polycom. Polycom has given its concent for this library to be
provided by Polycom. Polycom has given its consent for this library to be
distributed as source code, either on its own or as part of a larger package
which they have licenced under their royalty free licencing scheme.

6
libs/libscgi/FSSCGI.i Normal file
View File

@ -0,0 +1,6 @@
%{
#include "scgi.h"
#include "scgi_oop.h"
%}
%include "scgi_oop.h"

51
libs/libscgi/Makefile Normal file
View File

@ -0,0 +1,51 @@
PWD=$(shell pwd)
INCS=-I$(PWD)/src/include
DEBUG=-g -ggdb
BASE_FLAGS=$(INCS) $(DEBUG) -fPIC
PICKY=-O2
CFLAGS=$(BASE_FLAGS) $(PICKY)
CXXFLAGS=$(BASE_FLAGS)
MYLIB=libscgi.a
LIBS=
LDFLAGS=-L.
OBJS=src/scgi.o
SRC=src/scgi.c src/scgi_oop.cpp
HEADERS=src/include/scgi.h src/include/scgi_oop.h
SOLINK=-shared -Xlinker -x
# comment the next line to disable c++ (no swig mods for you then)
OBJS += src/scgi_oop.o
all: $(MYLIB) testclient testserver
$(MYLIB): $(OBJS) $(HEADERS) $(SRC)
ar rcs $(MYLIB) $(OBJS)
ranlib $(MYLIB)
%.o: %.c $(HEADERS)
$(CC) $(CC_CFLAGS) $(CFLAGS) -c $< -o $@
%.o: %.cpp $(HEADERS)
$(CXX) $(CXX_CFLAGS) $(CXXFLAGS) -c $< -o $@
testclient: $(MYLIB) testclient.c
$(CC) $(CC_CFLAGS) $(CFLAGS) testclient.c -o testclient -lscgi $(LDFLAGS) $(LIBS)
testserver: $(MYLIB) testserver.c
$(CC) $(CC_CFLAGS) $(CFLAGS) testserver.c -o testserver -lscgi $(LDFLAGS) $(LIBS)
clean:
rm -f *.o src/*.o libscgi.a *~ src/*~ src/include/*~ testclient testserver
$(MAKE) -C perl clean
reswig: swigclean
$(MAKE) -C perl reswig
swigclean: clean
$(MAKE) -C perl swigclean
perlmod: $(MYLIB)
$(MAKE) MYLIB="../$(MYLIB)" SOLINK="$(SOLINK)" CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" CXX_CFLAGS="$(CXX_CFLAGS)" -C perl
perlmod-install: perlmod
$(MAKE) -C perl install

105
libs/libscgi/perl/FSSCGI.pm Normal file
View File

@ -0,0 +1,105 @@
# This file was automatically generated by SWIG (http://www.swig.org).
# Version 1.3.35
#
# Don't modify this file, modify the SWIG interface instead.
package FSSCGI;
require Exporter;
require DynaLoader;
@ISA = qw(Exporter DynaLoader);
package FSSCGIc;
bootstrap FSSCGI;
package FSSCGI;
@EXPORT = qw( );
# ---------- BASE METHODS -------------
package FSSCGI;
sub TIEHASH {
my ($classname,$obj) = @_;
return bless $obj, $classname;
}
sub CLEAR { }
sub FIRSTKEY { }
sub NEXTKEY { }
sub FETCH {
my ($self,$field) = @_;
my $member_func = "swig_${field}_get";
$self->$member_func();
}
sub STORE {
my ($self,$field,$newval) = @_;
my $member_func = "swig_${field}_set";
$self->$member_func($newval);
}
sub this {
my $ptr = shift;
return tied(%$ptr);
}
# ------- FUNCTION WRAPPERS --------
package FSSCGI;
############# Class : FSSCGI::SCGIhandle ##############
package FSSCGI::SCGIhandle;
use vars qw(@ISA %OWNER %ITERATORS %BLESSEDMEMBERS);
@ISA = qw( FSSCGI );
%OWNER = ();
%ITERATORS = ();
sub new {
my $pkg = shift;
my $self = FSSCGIc::new_SCGIhandle(@_);
bless $self, $pkg if defined($self);
}
sub DESTROY {
return unless $_[0]->isa('HASH');
my $self = tied(%{$_[0]});
return unless defined $self;
delete $ITERATORS{$self};
if (exists $OWNER{$self}) {
FSSCGIc::delete_SCGIhandle($self);
delete $OWNER{$self};
}
}
*connected = *FSSCGIc::SCGIhandle_connected;
*socketDescriptor = *FSSCGIc::SCGIhandle_socketDescriptor;
*disconnect = *FSSCGIc::SCGIhandle_disconnect;
*addParam = *FSSCGIc::SCGIhandle_addParam;
*addBody = *FSSCGIc::SCGIhandle_addBody;
*getBody = *FSSCGIc::SCGIhandle_getBody;
*getParam = *FSSCGIc::SCGIhandle_getParam;
*sendRequest = *FSSCGIc::SCGIhandle_sendRequest;
*respond = *FSSCGIc::SCGIhandle_respond;
*bind = *FSSCGIc::SCGIhandle_bind;
*accept = *FSSCGIc::SCGIhandle_accept;
sub DISOWN {
my $self = shift;
my $ptr = tied(%$self);
delete $OWNER{$ptr};
}
sub ACQUIRE {
my $self = shift;
my $ptr = tied(%$self);
$OWNER{$ptr} = 1;
}
# ------- VARIABLE STUBS --------
package FSSCGI;
1;

View File

@ -0,0 +1,38 @@
PERL=$(shell which perl)
PERL_SITEDIR=$(shell perl -MConfig -e 'print $$Config{sitelibexp}')
PERL_LIBDIR=-L$(shell perl -MConfig -e 'print $$Config{archlib}')/CORE
PERL_LIBS=$(shell perl -MConfig -e 'print $$Config{libs}')
LOCAL_CFLAGS=-w -DMULTIPLICITY $(shell $(PERL) -MExtUtils::Embed -e ccopts) -DEMBED_PERL
LOCAL_LDFLAGS=$(shell $(PERL) -MExtUtils::Embed -e ldopts) $(shell $(PERL) -MConfig -e 'print $$Config{libs}')
GCC_WARNING_JUNK=-w
PERL_INC=$(shell $(PERL) -MExtUtils::Embed -e perl_inc)
all: FSSCGI.so
scgi_wrap.cpp:
swig -module FSSCGI -shadow -perl5 -c++ -DMULTIPLICITY -I../src/include -o scgi_wrap.cpp ../FSSCGI.i
perlxsi.c:
$(PERL) -MExtUtils::Embed -e xsinit -- -o perlxsi.c
perlxsi.o: perlxsi.c
$(CC) $(CC_CFLAGS) $(CFLAGS) $(LOCAL_CFLAGS) -c perlxsi.c -o perlxsi.o
scgi_wrap.o: scgi_wrap.cpp
$(CXX) $(CXX_CFLAGS) $(CXXFLAGS) $(GCC_WARNING_JUNK) $(PERL_INC) -c scgi_wrap.cpp -o scgi_wrap.o
FSSCGI.so: scgi_wrap.o perlxsi.o
$(CXX) $(SOLINK) scgi_wrap.o perlxsi.o $(MYLIB) $(LOCAL_LDFLAGS) -o FSSCGI.so -L. $(LIBS)
clean:
rm -f *.o *.so *~
swigclean:
rm -f scgi_wrap.* FSSCGI.so FSSCGI.pm perlxsi.*
reswig: swigclean scgi_wrap.cpp perlxsi.c
install: FSSCGI.so
install -m 755 FSSCGI.so $(PERL_SITEDIR)
install -m 755 FSSCGI.pm $(PERL_SITEDIR)
install -d -m 755 FSSCGI $(PERL_SITEDIR)/FSSCGI
install -m 755 FSSCGI/* $(PERL_SITEDIR)/FSSCGI

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,16 @@
#include <EXTERN.h>
#include <perl.h>
EXTERN_C void xs_init (pTHX);
EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);
EXTERN_C void
xs_init(pTHX)
{
char *file = __FILE__;
dXSUB_SYS;
/* DynaLoader is a special case */
newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,19 @@
use FSSCGI;
my $handle = new FSSCGI::SCGIhandle();
$handle->addParam( "REQUEST_METHOD", "POST");
$handle->addParam( "REQUEST_URI", "/deepthought");
$handle->addParam( "TESTING", "TRUE");
$handle->addParam( "TESTING", "TRUE");
$handle->addBody("What is the answer to life?");
if ((my $response = $handle->sendRequest("127.0.0.1", 7777, 10000))) {
print "RESP[$response]\n";
} else {
print "ERROR!\n";
}

View File

@ -0,0 +1,17 @@
use FSSCGI;
my $handle = new FSSCGI::SCGIhandle();
if ($handle->bind("127.0.0.1", 7777)) {
while($handle->accept()) {
print "REQ: " . $handle->getBody(). "\n\n";
$handle->respond("W00t!!!!!!\n");
}
print "DONE\n";
} else {
print "FAIL\n";
}

101
libs/libscgi/protocol.txt Normal file
View File

@ -0,0 +1,101 @@
SCGI: A Simple Common Gateway Interface alternative
Neil Schemenauer <nas@python.ca>
2008-06-23
1. Introduction
The SCGI protocol is a replacement for the Common Gateway Interface
(CGI) protocol. It is a standard for applications to interface with
HTTP servers. It is similar to FastCGI but is designed to be easier
to implement.
In this document, a string of 8-bit bytes may be written in two
different forms: as a series of hexadecimal numbers between angle
brackets, or as a sequence of ASCII characters between double quotes.
For example, <68 65 6c 6c 6f 20 77 6f 72 6c 64 21> is a string of
length 12; it is the same as the string "hello world!". Note that
these notations are part of this document, not part of the protocol.
2. Protocol
The client connects to a SCGI server over a reliable stream protocol
allowing transmission of 8-bit bytes. The client begins by sending a
request. See section 3 for the format of the request. When the SCGI
server sees the end of the request it sends back a response and closes
the connection. The format of the response is not specified by this
protocol.
3. Request Format
A request consists of a number of headers and a body. The format of
the headers is:
headers ::= header*
header ::= name NUL value NUL
name ::= notnull+
value ::= notnull*
notnull ::= <01> | <02> | <03> | ... | <ff>
NUL = <00>
Duplicate names are not allowed in the headers. The first header
must have the name "CONTENT_LENGTH" and a value that is a nonempty
sequence of ASCII digits giving the of the body length in decimal.
The "CONTENT_LENGTH" header must always be present, even if its
value is "0". There must also always be a header with the name
"SCGI" and a value of "1". In order to facilitate the transition
from CGI, standard CGI environment variables should be provided as
SCGI headers.
The headers are sent encoded as a netstring. Netstring encoding is
explained in section 4. The body is sent following the headers and
its length is specified by the "CONTENT_LENGTH" header.
4. Netstrings
Any string of 8-bit bytes may be encoded as [len]":"[string]",". Here
[string] is the string and [len] is a nonempty sequence of ASCII
digits giving the length of [string] in decimal. The ASCII digits are
<30> for 0, <31> for 1, and so on up through <39> for 9. Extra zeros
at the front of [len] are prohibited: [len] begins with <30> exactly
when [string] is empty.
For example, the string "hello world!" is encoded as <31 32 3a 68 65
6c 6c 6f 20 77 6f 72 6c 64 21 2c>, i.e., "12:hello world!,". The empty
string is encoded as "0:,".
[len]":"[string]"," is called a netstring. [string] is called the
interpretation of the netstring.
5. Example
The web server (a SCGI client) opens a connection and sends the
concatenation of the following strings:
"70:"
"CONTENT_LENGTH" <00> "27" <00>
"SCGI" <00> "1" <00>
"REQUEST_METHOD" <00> "POST" <00>
"REQUEST_URI" <00> "/deepthought" <00>
","
"What is the answer to life?"
The SCGI server sends the following response:
"Status: 200 OK" <0d 0a>
"Content-Type: text/plain" <0d 0a>
"" <0d 0a>
"42"
The SCGI server closes the connection.
6. Copyright
This document has been placed in the public domain.
/* vim: set ai tw=74 et sw=4 sts=4: */

View File

@ -0,0 +1,220 @@
/*
* Copyright (c) 2012-2013, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _SCGI_H_
#define _SCGI_H_
#include <stdarg.h>
#ifdef __cplusplus
extern "C" {
#endif /* defined(__cplusplus) */
#if EMACS_BUG
}
#endif
#ifdef _MSC_VER
#define FD_SETSIZE 8192
#define SCGI_USE_SELECT
#else
#define SCGI_USE_POLL
#endif
#ifdef SCGI_USE_POLL
#include <poll.h>
#endif
#ifdef WIN32
#include <winsock2.h>
#include <windows.h>
typedef SOCKET scgi_socket_t;
typedef unsigned __int64 uint64_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int8 uint8_t;
typedef __int64 int64_t;
typedef __int32 int32_t;
typedef __int16 int16_t;
typedef __int8 int8_t;
typedef intptr_t scgi_ssize_t;
typedef int scgi_filehandle_t;
#define SCGI_SOCK_INVALID INVALID_SOCKET
#define strerror_r(num, buf, size) strerror_s(buf, size, num)
#if defined(SCGI_DECLARE_STATIC)
#define SCGI_DECLARE(type) type __stdcall
#define SCGI_DECLARE_NONSTD(type) type __cdecl
#define SCGI_DECLARE_DATA
#elif defined(SCGI_EXPORTS)
#define SCGI_DECLARE(type) __declspec(dllexport) type __stdcall
#define SCGI_DECLARE_NONSTD(type) __declspec(dllexport) type __cdecl
#define SCGI_DECLARE_DATA __declspec(dllexport)
#else
#define SCGI_DECLARE(type) __declspec(dllimport) type __stdcall
#define SCGI_DECLARE_NONSTD(type) __declspec(dllimport) type __cdecl
#define SCGI_DECLARE_DATA __declspec(dllimport)
#endif
#else
#define SCGI_DECLARE(type) type
#define SCGI_DECLARE_NONSTD(type) type
#define SCGI_DECLARE_DATA
#include <stdint.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <stdarg.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define SCGI_SOCK_INVALID -1
typedef int scgi_socket_t;
typedef ssize_t scgi_ssize_t;
typedef int scgi_filehandle_t;
#endif
#include <time.h>
#ifndef WIN32
#include <sys/time.h>
#endif
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef WIN32
#include <sys/types.h>
#include <sys/select.h>
#include <netinet/tcp.h>
#include <sys/signal.h>
#include <unistd.h>
#include <ctype.h>
#endif
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#include <assert.h>
#if (_MSC_VER >= 1400) // VC8+
#define scgi_assert(expr) assert(expr);__analysis_assume( expr )
#endif
#ifndef scgi_assert
#define scgi_assert(_x) assert(_x)
#endif
#define scgi_safe_free(_x) if (_x) free(_x); _x = NULL
#define scgi_strlen_zero(s) (!s || *(s) == '\0')
#define scgi_strlen_zero_buf(s) (*(s) == '\0')
#define end_of(_s) *(*_s == '\0' ? _s : _s + strlen(_s) - 1)
#define end_of_p(_s) (*_s == '\0' ? _s : _s + strlen(_s) - 1)
typedef enum {
SCGI_POLL_READ = (1 << 0),
SCGI_POLL_WRITE = (1 << 1),
SCGI_POLL_ERROR = (1 << 2)
} scgi_poll_t;
typedef struct scgi_param_s {
char *name;
char *value;
struct scgi_param_s *next;
} scgi_param_t;
typedef struct scgi_handle_s {
scgi_param_t *params;
char *body;
struct sockaddr_in sockaddr;
struct hostent hostent;
char hostbuf[256];
scgi_socket_t sock;
char err[256];
int errnum;
int connected;
struct sockaddr_in addr;
int destroyed;
} scgi_handle_t;
typedef int16_t scgi_port_t;
typedef size_t scgi_size_t;
typedef enum {
SCGI_SUCCESS,
SCGI_FAIL,
SCGI_BREAK,
SCGI_DISCONNECTED,
SCGI_GENERR
} scgi_status_t;
typedef void (*scgi_listen_callback_t)(scgi_socket_t server_sock, scgi_socket_t *client_sock, struct sockaddr_in *addr);
SCGI_DECLARE(scgi_status_t) scgi_connect(scgi_handle_t *handle, const char *host, scgi_port_t port, uint32_t timeout);
SCGI_DECLARE(scgi_status_t) scgi_disconnect(scgi_handle_t *handle);
SCGI_DECLARE(scgi_status_t) scgi_parse(scgi_socket_t sock, scgi_handle_t *handle);
SCGI_DECLARE(int) scgi_wait_sock(scgi_socket_t sock, uint32_t ms, scgi_poll_t flags);
SCGI_DECLARE(ssize_t) scgi_recv(scgi_handle_t *handle, unsigned char *buf, size_t buflen);
SCGI_DECLARE(scgi_status_t) scgi_send_request(scgi_handle_t *handle);
SCGI_DECLARE(scgi_status_t) scgi_add_param(scgi_handle_t *handle, const char *name, const char *value);
SCGI_DECLARE(scgi_status_t) scgi_add_body(scgi_handle_t *handle, const char *value);
SCGI_DECLARE(size_t) scgi_build_message(scgi_handle_t *handle, char **buffer);
SCGI_DECLARE(scgi_status_t) scgi_destroy_params(scgi_handle_t *handle);
SCGI_DECLARE(scgi_status_t) scgi_listen(const char *host, scgi_port_t port, scgi_listen_callback_t callback);
SCGI_DECLARE(const char *) scgi_get_body(scgi_handle_t *handle);
SCGI_DECLARE(const char *) scgi_get_param(scgi_handle_t *handle, const char *name);
SCGI_DECLARE(scgi_status_t) scgi_bind(const char *host, scgi_port_t port, scgi_socket_t *socketp);
SCGI_DECLARE(scgi_status_t) scgi_accept(scgi_socket_t server_sock, scgi_socket_t *client_sock_p, struct sockaddr_in *echoClntAddr);
#ifndef WIN32
#define closesocket(x) close(x)
#endif
#ifdef __cplusplus
}
#endif /* defined(__cplusplus) */
#endif /* defined(_SCGI_H_) */
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
*/

View File

@ -0,0 +1,78 @@
/*
* Copyright (c) 2007-2012, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _SCGI_OOP_H_
#define _SCGI_OOP_H_
#include <scgi.h>
#ifdef __cplusplus
extern "C" {
#endif
#define this_check(x) do { if (!this) { scgi_log(SCGI_LOG_ERROR, "object is not initalized\n"); return x;}} while(0)
#define this_check_void() do { if (!this) { scgi_log(SCGI_LOG_ERROR, "object is not initalized\n"); return;}} while(0)
class SCGIhandle {
private:
scgi_socket_t server_sock;
scgi_handle_t handle;
unsigned char buf[65536];
char *data_buf;
int buflen;
int bufsize;
public:
SCGIhandle();
virtual ~SCGIhandle();
int connected();
int socketDescriptor();
int disconnect(void);
int addParam(const char *name, const char *value);
int addBody(const char *value);
char *getBody();
char *getParam(const char *name);
char *sendRequest(const char *host, int port, int timeout);
int respond(char *msg);
int bind(const char *host, int port);
int accept(void);
};
#ifdef __cplusplus
}
#endif
#endif

739
libs/libscgi/src/scgi.c Normal file
View File

@ -0,0 +1,739 @@
/*
* Copyright (c) 2012-2013, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <scgi.h>
#ifndef WIN32
#include <fcntl.h>
#include <errno.h>
#else
#pragma warning (disable:6386)
/* These warnings need to be ignored warning in sdk header */
#include <Ws2tcpip.h>
#include <windows.h>
#ifndef errno
#define errno WSAGetLastError()
#endif
#ifndef EINTR
#define EINTR WSAEINTR
#endif
#pragma warning (default:6386)
#endif
static scgi_status_t scgi_push_param(scgi_handle_t *handle, const char *name, const char *value);
static int sock_setup(scgi_handle_t *handle)
{
if (handle->sock == SCGI_SOCK_INVALID) {
return SCGI_FAIL;
}
#ifdef WIN32
{
BOOL bOptVal = TRUE;
int bOptLen = sizeof(BOOL);
setsockopt(handle->sock, IPPROTO_TCP, TCP_NODELAY, (const char *)&bOptVal, bOptLen);
}
#else
{
int x = 1;
setsockopt(handle->sock, IPPROTO_TCP, TCP_NODELAY, &x, sizeof(x));
}
#endif
return SCGI_SUCCESS;
}
SCGI_DECLARE(size_t) scgi_build_message(scgi_handle_t *handle, char **bufferp)
{
scgi_param_t *pp;
size_t len = 0, plen = 0, ctlen = 0;
char *s, *bp;
char *buffer = NULL;
char tmp[128] = "";
scgi_push_param(handle, "SCGI", "1");
if (handle->body) {
ctlen = strlen(handle->body);
}
snprintf(tmp, sizeof(tmp), "%d", (int)ctlen);
scgi_push_param(handle, "CONTENT_LENGTH", tmp);
for(pp = handle->params; pp; pp = pp->next) {
plen += (strlen(pp->name) + strlen(pp->value) + 2);
}
snprintf(tmp, sizeof(tmp), "%d", (int) (plen + ctlen));
len = plen + ctlen + strlen(tmp) + 2;
buffer = malloc(len);
memset(buffer, 0, len);
snprintf(buffer, len, "%d:", (int)plen);
bp = buffer + strlen(buffer);
for(pp = handle->params; pp; pp = pp->next) {
for (s = pp->name; s && *s; s++) {
*bp++ = *s;
}
*bp++ = '\0';
for (s = pp->value; s && *s; s++) {
*bp++ = *s;
}
*bp++ = '\0';
}
*bp++ = ',';
if (handle->body) {
for (s = handle->body; s && *s; s++) {
*bp++ = *s;
}
}
*bufferp = buffer;
return len;
}
SCGI_DECLARE(scgi_status_t) scgi_destroy_params(scgi_handle_t *handle)
{
scgi_param_t *param, *pp;
pp = handle->params;
while(pp) {
param = pp;
pp = pp->next;
free(param->name);
free(param->value);
free(param);
}
handle->params = NULL;
return SCGI_SUCCESS;
}
SCGI_DECLARE(scgi_status_t) scgi_add_body(scgi_handle_t *handle, const char *value)
{
handle->body = strdup(value);
return SCGI_SUCCESS;
}
SCGI_DECLARE(const char *) scgi_get_body(scgi_handle_t *handle)
{
return handle->body;
}
SCGI_DECLARE(scgi_status_t) scgi_add_param(scgi_handle_t *handle, const char *name, const char *value)
{
scgi_param_t *param, *pp;
for(pp = handle->params; pp && pp->next; pp = pp->next) {
if (!strcasecmp(pp->name, name)) {
return SCGI_FAIL;
}
}
param = malloc(sizeof(*param));
memset(param, 0, sizeof(*param));
param->name = strdup(name);
param->value = strdup(value);
if (!pp) {
handle->params = param;
} else {
pp->next = param;
}
return SCGI_SUCCESS;
}
SCGI_DECLARE(const char *) scgi_get_param(scgi_handle_t *handle, const char *name)
{
scgi_param_t *pp;
for(pp = handle->params; pp; pp = pp->next) {
if (!strcasecmp(pp->name, name)) {
return pp->value;
}
}
return NULL;
}
static scgi_status_t scgi_push_param(scgi_handle_t *handle, const char *name, const char *value)
{
scgi_param_t *param;
param = malloc(sizeof(*param));
memset(param, 0, sizeof(*param));
param->name = strdup(name);
param->value = strdup(value);
param->next = handle->params;
handle->params = param;
return SCGI_SUCCESS;
}
SCGI_DECLARE(scgi_status_t) scgi_send_request(scgi_handle_t *handle)
{
scgi_status_t status = SCGI_SUCCESS;
char *buffer = NULL;
size_t bytes = 0;
ssize_t sent = 0;
if (handle->connected != 1) {
return SCGI_FAIL;
}
bytes = scgi_build_message(handle, &buffer);
sent = send(handle->sock, buffer, bytes, 0);
if (sent <= 0) {
handle->connected = -1;
}
scgi_safe_free(buffer);
return status;
}
SCGI_DECLARE(ssize_t) scgi_recv(scgi_handle_t *handle, unsigned char *buf, size_t buflen)
{
ssize_t recvd;
if (handle->connected != 1) {
return -1;
}
recvd = recv(handle->sock, buf, buflen, 0);
if (recvd == 0) {
handle->connected = -1;
}
return recvd;
}
SCGI_DECLARE(scgi_status_t) scgi_connect(scgi_handle_t *handle, const char *host, scgi_port_t port, uint32_t timeout)
{
int rval = 0;
struct addrinfo hints = { 0 }, *result;
#ifndef WIN32
int fd_flags = 0;
#else
WORD wVersionRequested = MAKEWORD(2, 0);
WSADATA wsaData;
int err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
snprintf(handle->err, sizeof(handle->err), "WSAStartup Error");
return SCGI_FAIL;
}
#endif
handle->sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (handle->sock == SCGI_SOCK_INVALID) {
snprintf(handle->err, sizeof(handle->err), "Socket Error");
return SCGI_FAIL;
}
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
if (getaddrinfo(host, NULL, &hints, &result)) {
strncpy(handle->err, "Cannot resolve host", sizeof(handle->err));
goto fail;
}
memcpy(&handle->sockaddr, result->ai_addr, sizeof(handle->sockaddr));
handle->sockaddr.sin_family = AF_INET;
handle->sockaddr.sin_port = htons(port);
freeaddrinfo(result);
if (timeout) {
#ifdef WIN32
u_long arg = 1;
if (ioctlsocket(handle->sock, FIONBIO, &arg) == SOCKET_ERROR) {
snprintf(handle->err, sizeof(handle->err), "Socket Connection Error");
goto fail;
}
#else
fd_flags = fcntl(handle->sock, F_GETFL, 0);
if (fcntl(handle->sock, F_SETFL, fd_flags | O_NONBLOCK)) {
snprintf(handle->err, sizeof(handle->err), "Socket Connection Error");
goto fail;
}
#endif
}
rval = connect(handle->sock, (struct sockaddr*)&handle->sockaddr, sizeof(handle->sockaddr));
if (timeout) {
int r;
r = scgi_wait_sock(handle->sock, timeout, SCGI_POLL_WRITE);
if (r <= 0) {
snprintf(handle->err, sizeof(handle->err), "Connection timed out");
goto fail;
}
if (!(r & SCGI_POLL_WRITE)) {
snprintf(handle->err, sizeof(handle->err), "Connection timed out");
goto fail;
}
#ifdef WIN32
{
u_long arg = 0;
if (ioctlsocket(handle->sock, FIONBIO, &arg) == SOCKET_ERROR) {
snprintf(handle->err, sizeof(handle->err), "Socket Connection Error");
goto fail;
}
}
#else
fcntl(handle->sock, F_SETFL, fd_flags);
#endif
rval = 0;
}
result = NULL;
if (rval) {
snprintf(handle->err, sizeof(handle->err), "Socket Connection Error");
goto fail;
}
sock_setup(handle);
handle->connected = 1;
return SCGI_SUCCESS;
fail:
handle->connected = 0;
scgi_disconnect(handle);
return SCGI_FAIL;
}
SCGI_DECLARE(scgi_status_t) scgi_disconnect(scgi_handle_t *handle)
{
scgi_status_t status = SCGI_FAIL;
if (handle->destroyed) {
return SCGI_FAIL;
}
if (handle->sock != SCGI_SOCK_INVALID) {
closesocket(handle->sock);
handle->sock = SCGI_SOCK_INVALID;
status = SCGI_SUCCESS;
}
handle->destroyed = 1;
handle->connected = 0;
scgi_destroy_params(handle);
scgi_safe_free(handle->body);
return status;
}
/* USE WSAPoll on vista or higher */
#ifdef SCGI_USE_WSAPOLL
SCGI_DECLARE(int) scgi_wait_sock(scgi_socket_t sock, uint32_t ms, scgi_poll_t flags)
{
}
#endif
#ifdef SCGI_USE_SELECT
#ifdef WIN32
#pragma warning( push )
#pragma warning( disable : 6262 ) /* warning C6262: Function uses '98348' bytes of stack: exceeds /analyze:stacksize'16384'. Consider moving some data to heap */
#endif
SCGI_DECLARE(int) scgi_wait_sock(scgi_socket_t sock, uint32_t ms, scgi_poll_t flags)
{
int s = 0, r = 0;
fd_set rfds;
fd_set wfds;
fd_set efds;
struct timeval tv;
FD_ZERO(&rfds);
FD_ZERO(&wfds);
FD_ZERO(&efds);
#ifndef WIN32
/* Wouldn't you rather know?? */
assert(sock <= FD_SETSIZE);
#endif
if ((flags & SCGI_POLL_READ)) {
#ifdef WIN32
#pragma warning( push )
#pragma warning( disable : 4127 )
FD_SET(sock, &rfds);
#pragma warning( pop )
#else
FD_SET(sock, &rfds);
#endif
}
if ((flags & SCGI_POLL_WRITE)) {
#ifdef WIN32
#pragma warning( push )
#pragma warning( disable : 4127 )
FD_SET(sock, &wfds);
#pragma warning( pop )
#else
FD_SET(sock, &wfds);
#endif
}
if ((flags & SCGI_POLL_ERROR)) {
#ifdef WIN32
#pragma warning( push )
#pragma warning( disable : 4127 )
FD_SET(sock, &efds);
#pragma warning( pop )
#else
FD_SET(sock, &efds);
#endif
}
tv.tv_sec = ms / 1000;
tv.tv_usec = (ms % 1000) * ms;
s = select(sock + 1, (flags & SCGI_POLL_READ) ? &rfds : NULL, (flags & SCGI_POLL_WRITE) ? &wfds : NULL, (flags & SCGI_POLL_ERROR) ? &efds : NULL, &tv);
if (s < 0) {
r = s;
} else if (s > 0) {
if ((flags & SCGI_POLL_READ) && FD_ISSET(sock, &rfds)) {
r |= SCGI_POLL_READ;
}
if ((flags & SCGI_POLL_WRITE) && FD_ISSET(sock, &wfds)) {
r |= SCGI_POLL_WRITE;
}
if ((flags & SCGI_POLL_ERROR) && FD_ISSET(sock, &efds)) {
r |= SCGI_POLL_ERROR;
}
}
return r;
}
#ifdef WIN32
#pragma warning( pop )
#endif
#endif
#ifdef SCGI_USE_POLL
SCGI_DECLARE(int) scgi_wait_sock(scgi_socket_t sock, uint32_t ms, scgi_poll_t flags)
{
struct pollfd pfds[2] = { { 0 } };
int s = 0, r = 0;
pfds[0].fd = sock;
if ((flags & SCGI_POLL_READ)) {
pfds[0].events |= POLLIN;
}
if ((flags & SCGI_POLL_WRITE)) {
pfds[0].events |= POLLOUT;
}
if ((flags & SCGI_POLL_ERROR)) {
pfds[0].events |= POLLERR;
}
s = poll(pfds, 1, ms);
if (s < 0) {
r = s;
} else if (s > 0) {
if ((pfds[0].revents & POLLIN)) {
r |= SCGI_POLL_READ;
}
if ((pfds[0].revents & POLLOUT)) {
r |= SCGI_POLL_WRITE;
}
if ((pfds[0].revents & POLLERR)) {
r |= SCGI_POLL_ERROR;
}
}
return r;
}
#endif
static int scgi_socket_reuseaddr(scgi_socket_t socket)
{
#ifdef WIN32
BOOL reuse_addr = TRUE;
return setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse_addr, sizeof(reuse_addr));
#else
int reuse_addr = 1;
return setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, &reuse_addr, sizeof(reuse_addr));
#endif
}
SCGI_DECLARE(scgi_status_t) scgi_bind(const char *host, scgi_port_t port, scgi_socket_t *socketp)
{
scgi_socket_t server_sock = SCGI_SOCK_INVALID;
struct sockaddr_in addr;
scgi_status_t status = SCGI_SUCCESS;
if ((server_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
return SCGI_FAIL;
}
scgi_socket_reuseaddr(server_sock);
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(port);
if (bind(server_sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
status = SCGI_FAIL;
goto end;
}
if (listen(server_sock, 10000) < 0) {
status = SCGI_FAIL;
goto end;
}
end:
if (status == SCGI_FAIL) {
if (server_sock != SCGI_SOCK_INVALID) {
closesocket(server_sock);
server_sock = SCGI_SOCK_INVALID;
}
} else {
*socketp = server_sock;
}
return status;
}
SCGI_DECLARE(scgi_status_t) scgi_accept(scgi_socket_t server_sock, scgi_socket_t *client_sock_p, struct sockaddr_in *echoClntAddr)
{
scgi_status_t status = SCGI_SUCCESS;
int client_sock;
struct sockaddr_in local_echoClntAddr;
#ifdef WIN32
int clntLen;
#else
unsigned int clntLen;
#endif
if (!echoClntAddr) {
echoClntAddr = &local_echoClntAddr;
}
clntLen = sizeof(*echoClntAddr);
if ((client_sock = accept(server_sock, (struct sockaddr *) echoClntAddr, &clntLen)) == SCGI_SOCK_INVALID) {
printf("FRICK %s\n", strerror(errno));
status = SCGI_FAIL;
} else {
*client_sock_p = client_sock;
}
return status;
}
SCGI_DECLARE(scgi_status_t) scgi_listen(const char *host, scgi_port_t port, scgi_listen_callback_t callback)
{
scgi_socket_t server_sock = SCGI_SOCK_INVALID, client_sock = SCGI_SOCK_INVALID;
scgi_status_t status = SCGI_FAIL;
struct sockaddr_in echoClntAddr;
if ((status = scgi_bind(host, port, &server_sock)) == SCGI_SUCCESS) {
while(scgi_accept(server_sock, &client_sock, &echoClntAddr) == SCGI_SUCCESS) {
callback(server_sock, &client_sock, &echoClntAddr);
if (client_sock != SCGI_SOCK_INVALID) {
closesocket(client_sock);
client_sock = SCGI_SOCK_INVALID;
}
}
}
return status;
}
#define next_str(_e, _s) _s = _e; while(*_s) _s++; _s++
SCGI_DECLARE(scgi_status_t) scgi_parse(scgi_socket_t sock, scgi_handle_t *handle)
{
char sbuf[128] = "";
char *p = sbuf, *e, *end;
ssize_t r = 0;
scgi_status_t status = SCGI_FAIL;
ssize_t bytes = 0;
char *headers = NULL;
int loops = 0;
ssize_t clen = 0;
char *body = NULL;
char comma = 0;
memset(handle, 0, sizeof(*handle));
handle->sock = sock;
handle->connected = 1;
sock_setup(handle);
for(;;) {
if ((r = recv(sock, p, 1, 0)) < 1) {
break;
}
if (*p == ':') {
*p = '\0';
break;
}
p++;
}
if (r <= 0) goto end;
bytes = atoi(sbuf);
if (bytes <= 0) goto end;
headers = malloc(bytes);
r = recv(sock, headers, bytes, 0);
if (r <= 0) goto end;
r = recv(sock, &comma, 1, 0);
if (r <= 0 || comma != ',') goto end;
p = headers;
end = p + bytes;
e = NULL;
while(p < end) {
next_str(p, e);
if (!e) break;
if (!loops++) {
if (!strcasecmp(p, "CONTENT_LENGTH") && e) {
clen = atoi(e);
if (clen) {
body = malloc(clen+1);
r = recv(sock, body, clen, 0);
*(body + clen) = '\0';
if (r <= 0) goto end;
scgi_add_body(handle, body);
scgi_safe_free(body);
}
status = SCGI_SUCCESS;
} else {
goto end;
}
}
scgi_add_param(handle, p, e);
next_str(e, p);
}
end:
scgi_safe_free(headers);
return status;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
*/

View File

@ -0,0 +1,127 @@
#include <scgi.h>
#include <scgi_oop.h>
#define connection_construct_common() memset(&handle, 0, sizeof(handle))
SCGIhandle::SCGIhandle(void)
{
connection_construct_common();
}
SCGIhandle::~SCGIhandle()
{
scgi_disconnect(&handle);
scgi_safe_free(data_buf);
buflen = 0;
bufsize = 0;
}
int SCGIhandle::socketDescriptor()
{
if (handle.connected) {
return (int) handle.sock;
}
return -1;
}
int SCGIhandle::disconnect()
{
return scgi_disconnect(&handle);
}
int SCGIhandle::connected()
{
return handle.connected;
}
int SCGIhandle::addParam(const char *name, const char *value)
{
return (int) scgi_add_param(&handle, name, value);
}
int SCGIhandle::addBody(const char *value)
{
return (int) scgi_add_body(&handle, value);
}
char *SCGIhandle::getBody()
{
return handle.body;
}
char *SCGIhandle::getParam(const char *name)
{
return (char *) scgi_get_param(&handle, name);
}
char *SCGIhandle::sendRequest(const char *host, int port, int timeout)
{
ssize_t len;
if (!host) {
return 0;
}
if (timeout < 1000) {
timeout = 1000;
}
if (scgi_connect(&handle, host, port, timeout) == SCGI_SUCCESS) {
if (scgi_send_request(&handle) == SCGI_SUCCESS) {
while((len = scgi_recv(&handle, buf, sizeof(buf))) > 0) {
if (buflen + len > bufsize) {
bufsize = buflen + len + 1024;
void *tmp = realloc(data_buf, bufsize);
assert(tmp);
data_buf = (char *)tmp;
*(data_buf+buflen) = '\0';
}
snprintf(data_buf+buflen, bufsize-buflen, "%s", buf);
buflen += len;
}
return data_buf;
}
}
return (char *) "";
}
int SCGIhandle::bind(const char *host, int port)
{
return (scgi_bind(host, port, &server_sock) == SCGI_SUCCESS) ? 1 : 0;
}
int SCGIhandle::accept(void)
{
scgi_socket_t client_sock;
if (scgi_accept(server_sock, &client_sock, NULL) == SCGI_SUCCESS) {
if (scgi_parse(client_sock, &handle) == SCGI_SUCCESS) {
return 1;
}
closesocket(client_sock);
}
return 0;
}
int SCGIhandle::respond(char *msg)
{
int b = write(handle.sock, msg, strlen(msg));
scgi_disconnect(&handle);
scgi_safe_free(data_buf);
buflen = 0;
bufsize = 0;
return b;
}

40
libs/libscgi/testclient.c Normal file
View File

@ -0,0 +1,40 @@
#include <scgi.h>
int main(int argc, char *argv[])
{
char buf[16336] = "";
ssize_t len;
scgi_handle_t handle = { 0 };
char *ip;
int port = 0;
if (argc < 2) {
fprintf(stderr, "usage: testclient <ip> <port>\n");
exit(-1);
}
ip = argv[1];
port = atoi(argv[2]);
scgi_add_param(&handle, "REQUEST_METHOD", "POST");
scgi_add_param(&handle, "REQUEST_URI", "/deepthought");
scgi_add_param(&handle, "TESTING", "TRUE");
scgi_add_param(&handle, "TESTING", "TRUE");
scgi_add_body(&handle, "What is the answer to life?");
scgi_connect(&handle, ip, port, 10000);
scgi_send_request(&handle);
while((len = scgi_recv(&handle, buf, sizeof(buf))) > 0) {
printf("READ [%s]\n", buf);
}
scgi_disconnect(&handle);
}

43
libs/libscgi/testserver.c Normal file
View File

@ -0,0 +1,43 @@
#include <scgi.h>
static void callback(scgi_socket_t server_sock, scgi_socket_t *client_sock, struct sockaddr_in *addr)
{
scgi_handle_t handle = { 0 };
if (scgi_parse(*client_sock, &handle) == SCGI_SUCCESS) {
scgi_param_t *pp;
*client_sock = SCGI_SOCK_INVALID;
for(pp = handle.params; pp; pp = pp->next) {
printf("HEADER: [%s] VALUE: [%s]\n", pp->name, pp->value);
}
if (handle.body) {
printf("\n\nBODY:\n%s\n\n", handle.body);
}
scgi_disconnect(&handle);
}
}
int main(int argc, char *argv[])
{
char *ip;
int port = 0;
if (argc < 2) {
fprintf(stderr, "usage: testserver <ip> <port>\n");
exit(-1);
}
ip = argv[1];
port = atoi(argv[2]);
scgi_listen(ip, port, callback);
}

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