diff --git a/Freeswitch.2008.sln b/Freeswitch.2008.sln
index d87a7ecfa7..8e6df5cc57 100644
--- a/Freeswitch.2008.sln
+++ b/Freeswitch.2008.sln
@@ -1277,11 +1277,9 @@ Global
{1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}.Debug|Win32.ActiveCfg = Debug|Win32
{1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}.Debug|Win32.Build.0 = Debug|Win32
{1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}.Debug|x64.ActiveCfg = Debug|x64
- {1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}.Debug|x64.Build.0 = Debug|x64
{1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}.Release|Win32.ActiveCfg = Release|Win32
{1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}.Release|Win32.Build.0 = Release|Win32
{1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}.Release|x64.ActiveCfg = Release|x64
- {1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}.Release|x64.Build.0 = Release|x64
{692F6330-4D87-4C82-81DF-40DB5892636E}.All|Win32.ActiveCfg = Release|x64
{692F6330-4D87-4C82-81DF-40DB5892636E}.All|x64.ActiveCfg = Release|x64
{692F6330-4D87-4C82-81DF-40DB5892636E}.All|x64.Build.0 = Release|x64
@@ -1593,22 +1591,18 @@ Global
{ACFFF684-4D19-4D48-AF12-88EA1D778BDF}.Debug|Win32.ActiveCfg = Debug|Win32
{ACFFF684-4D19-4D48-AF12-88EA1D778BDF}.Debug|Win32.Build.0 = Debug|Win32
{ACFFF684-4D19-4D48-AF12-88EA1D778BDF}.Debug|x64.ActiveCfg = Debug|x64
- {ACFFF684-4D19-4D48-AF12-88EA1D778BDF}.Debug|x64.Build.0 = Debug|x64
{ACFFF684-4D19-4D48-AF12-88EA1D778BDF}.Release|Win32.ActiveCfg = Release|Win32
{ACFFF684-4D19-4D48-AF12-88EA1D778BDF}.Release|Win32.Build.0 = Release|Win32
{ACFFF684-4D19-4D48-AF12-88EA1D778BDF}.Release|x64.ActiveCfg = Release|x64
- {ACFFF684-4D19-4D48-AF12-88EA1D778BDF}.Release|x64.Build.0 = Release|x64
{8F992C49-6C51-412F-B2A3-34EAB708EB65}.All|Win32.ActiveCfg = Release|x64
{8F992C49-6C51-412F-B2A3-34EAB708EB65}.All|x64.ActiveCfg = Release|x64
{8F992C49-6C51-412F-B2A3-34EAB708EB65}.All|x64.Build.0 = Release|x64
{8F992C49-6C51-412F-B2A3-34EAB708EB65}.Debug|Win32.ActiveCfg = Debug|Win32
{8F992C49-6C51-412F-B2A3-34EAB708EB65}.Debug|Win32.Build.0 = Debug|Win32
{8F992C49-6C51-412F-B2A3-34EAB708EB65}.Debug|x64.ActiveCfg = Debug|x64
- {8F992C49-6C51-412F-B2A3-34EAB708EB65}.Debug|x64.Build.0 = Debug|x64
{8F992C49-6C51-412F-B2A3-34EAB708EB65}.Release|Win32.ActiveCfg = Release|Win32
{8F992C49-6C51-412F-B2A3-34EAB708EB65}.Release|Win32.Build.0 = Release|Win32
{8F992C49-6C51-412F-B2A3-34EAB708EB65}.Release|x64.ActiveCfg = Release|x64
- {8F992C49-6C51-412F-B2A3-34EAB708EB65}.Release|x64.Build.0 = Release|x64
{4043FC6A-9A30-4577-8AD5-9B233C9575D8}.All|Win32.ActiveCfg = Release|x64
{4043FC6A-9A30-4577-8AD5-9B233C9575D8}.All|x64.ActiveCfg = Release|x64
{4043FC6A-9A30-4577-8AD5-9B233C9575D8}.All|x64.Build.0 = Release|x64
@@ -1637,11 +1631,9 @@ Global
{0A6B5EA5-6E9B-4A51-931F-ED25AA87B4DF}.Debug|Win32.ActiveCfg = Debug|Win32
{0A6B5EA5-6E9B-4A51-931F-ED25AA87B4DF}.Debug|Win32.Build.0 = Debug|Win32
{0A6B5EA5-6E9B-4A51-931F-ED25AA87B4DF}.Debug|x64.ActiveCfg = Debug|x64
- {0A6B5EA5-6E9B-4A51-931F-ED25AA87B4DF}.Debug|x64.Build.0 = Debug|x64
{0A6B5EA5-6E9B-4A51-931F-ED25AA87B4DF}.Release|Win32.ActiveCfg = Release|Win32
{0A6B5EA5-6E9B-4A51-931F-ED25AA87B4DF}.Release|Win32.Build.0 = Release|Win32
{0A6B5EA5-6E9B-4A51-931F-ED25AA87B4DF}.Release|x64.ActiveCfg = Release|x64
- {0A6B5EA5-6E9B-4A51-931F-ED25AA87B4DF}.Release|x64.Build.0 = Release|x64
{AB91A099-7690-4ECF-8994-E458F4EA1ED4}.All|Win32.ActiveCfg = Release|x64
{AB91A099-7690-4ECF-8994-E458F4EA1ED4}.All|x64.ActiveCfg = Release|x64
{AB91A099-7690-4ECF-8994-E458F4EA1ED4}.All|x64.Build.0 = Release|x64
@@ -1736,11 +1728,9 @@ Global
{028C7278-05D7-4E18-82FE-BE231B844F41}.Debug|Win32.ActiveCfg = Debug|Win32
{028C7278-05D7-4E18-82FE-BE231B844F41}.Debug|Win32.Build.0 = Debug|Win32
{028C7278-05D7-4E18-82FE-BE231B844F41}.Debug|x64.ActiveCfg = Debug|x64
- {028C7278-05D7-4E18-82FE-BE231B844F41}.Debug|x64.Build.0 = Debug|x64
{028C7278-05D7-4E18-82FE-BE231B844F41}.Release|Win32.ActiveCfg = Release|Win32
{028C7278-05D7-4E18-82FE-BE231B844F41}.Release|Win32.Build.0 = Release|Win32
{028C7278-05D7-4E18-82FE-BE231B844F41}.Release|x64.ActiveCfg = Release|x64
- {028C7278-05D7-4E18-82FE-BE231B844F41}.Release|x64.Build.0 = Release|x64
{D7F1E3F2-A3F4-474C-8555-15122571AF52}.All|Win32.ActiveCfg = Release|x64
{D7F1E3F2-A3F4-474C-8555-15122571AF52}.All|x64.ActiveCfg = Release|x64
{D7F1E3F2-A3F4-474C-8555-15122571AF52}.All|x64.Build.0 = Release|x64
@@ -1901,11 +1891,9 @@ Global
{36E854E3-CE12-4348-A125-CCF3F9D74813}.Debug|Win32.ActiveCfg = Debug|Win32
{36E854E3-CE12-4348-A125-CCF3F9D74813}.Debug|Win32.Build.0 = Debug|Win32
{36E854E3-CE12-4348-A125-CCF3F9D74813}.Debug|x64.ActiveCfg = Debug|x64
- {36E854E3-CE12-4348-A125-CCF3F9D74813}.Debug|x64.Build.0 = Debug|x64
{36E854E3-CE12-4348-A125-CCF3F9D74813}.Release|Win32.ActiveCfg = Release|Win32
{36E854E3-CE12-4348-A125-CCF3F9D74813}.Release|Win32.Build.0 = Release|Win32
{36E854E3-CE12-4348-A125-CCF3F9D74813}.Release|x64.ActiveCfg = Release|x64
- {36E854E3-CE12-4348-A125-CCF3F9D74813}.Release|x64.Build.0 = Release|x64
{7B077E7F-1BE7-4291-AB86-55E527B25CAC}.All|Win32.ActiveCfg = Release|x64
{7B077E7F-1BE7-4291-AB86-55E527B25CAC}.All|x64.ActiveCfg = Release|x64
{7B077E7F-1BE7-4291-AB86-55E527B25CAC}.All|x64.Build.0 = Release|x64
@@ -2225,10 +2213,12 @@ Global
{834E2B2F-5483-4B80-8FE3-FE48FF76E5C0}.All|x64.ActiveCfg = Release|Any CPU
{834E2B2F-5483-4B80-8FE3-FE48FF76E5C0}.Debug|Win32.ActiveCfg = Debug|Any CPU
{834E2B2F-5483-4B80-8FE3-FE48FF76E5C0}.Debug|Win32.Build.0 = Debug|Any CPU
- {834E2B2F-5483-4B80-8FE3-FE48FF76E5C0}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {834E2B2F-5483-4B80-8FE3-FE48FF76E5C0}.Debug|x64.ActiveCfg = Debug|x64
+ {834E2B2F-5483-4B80-8FE3-FE48FF76E5C0}.Debug|x64.Build.0 = Debug|x64
{834E2B2F-5483-4B80-8FE3-FE48FF76E5C0}.Release|Win32.ActiveCfg = Release|Any CPU
{834E2B2F-5483-4B80-8FE3-FE48FF76E5C0}.Release|Win32.Build.0 = Release|Any CPU
- {834E2B2F-5483-4B80-8FE3-FE48FF76E5C0}.Release|x64.ActiveCfg = Release|Any CPU
+ {834E2B2F-5483-4B80-8FE3-FE48FF76E5C0}.Release|x64.ActiveCfg = Release|x64
+ {834E2B2F-5483-4B80-8FE3-FE48FF76E5C0}.Release|x64.Build.0 = Release|x64
{E796E337-DE78-4303-8614-9A590862EE95}.All|Win32.ActiveCfg = Release|Win32
{E796E337-DE78-4303-8614-9A590862EE95}.All|Win32.Build.0 = Release|Win32
{E796E337-DE78-4303-8614-9A590862EE95}.All|x64.ActiveCfg = Release|Win32
diff --git a/Freeswitch.2010.sln b/Freeswitch.2010.sln
index c865b6861a..4729745778 100644
--- a/Freeswitch.2010.sln
+++ b/Freeswitch.2010.sln
@@ -703,6 +703,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_directory", "src\mod\ap
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_h323", "src\mod\endpoints\mod_h323\mod_h323.2010.vcxproj", "{05C9FB27-480E-4D53-B3B7-7338E2514666}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_distributor", "src\mod\applications\mod_distributor\mod_distributor.2010.vcxproj", "{5C2B4D88-3BEA-4FE0-90DF-FA9836099D5F}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
All|Win32 = All|Win32
@@ -2424,6 +2426,13 @@ Global
{05C9FB27-480E-4D53-B3B7-7338E2514666}.Debug|x64.ActiveCfg = Debug|x64
{05C9FB27-480E-4D53-B3B7-7338E2514666}.Release|Win32.ActiveCfg = Release|Win32
{05C9FB27-480E-4D53-B3B7-7338E2514666}.Release|x64.ActiveCfg = Release|x64
+ {5C2B4D88-3BEA-4FE0-90DF-FA9836099D5F}.All|Win32.ActiveCfg = Release|x64
+ {5C2B4D88-3BEA-4FE0-90DF-FA9836099D5F}.All|x64.ActiveCfg = Release|x64
+ {5C2B4D88-3BEA-4FE0-90DF-FA9836099D5F}.All|x64.Build.0 = Release|x64
+ {5C2B4D88-3BEA-4FE0-90DF-FA9836099D5F}.Debug|Win32.ActiveCfg = Debug|Win32
+ {5C2B4D88-3BEA-4FE0-90DF-FA9836099D5F}.Debug|x64.ActiveCfg = Debug|x64
+ {5C2B4D88-3BEA-4FE0-90DF-FA9836099D5F}.Release|Win32.ActiveCfg = Release|Win32
+ {5C2B4D88-3BEA-4FE0-90DF-FA9836099D5F}.Release|x64.ActiveCfg = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -2470,6 +2479,7 @@ Global
{1E21AFE0-6FDB-41D2-942D-863607C24B91} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78}
{2E250296-0C08-4342-9C8A-BCBDD0E7DF65} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78}
{B889A18E-70A7-44B5-B2C9-47798D4F43B3} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78}
+ {5C2B4D88-3BEA-4FE0-90DF-FA9836099D5F} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78}
{07113B25-D3AF-4E04-BA77-4CD1171F022C} = {C5F182F9-754A-4EC5-B50F-76ED02BE13F4}
{A27CCA23-1541-4337-81A4-F0A6413078A0} = {C5F182F9-754A-4EC5-B50F-76ED02BE13F4}
{E7BC026C-7CC5-45A3-BC7C-3B88EEF01F24} = {C5F182F9-754A-4EC5-B50F-76ED02BE13F4}
diff --git a/Makefile.am b/Makefile.am
index ad04fde392..b11e3ff988 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -367,14 +367,14 @@ src/include/switch_version.h: src/include/switch_version.h.in .version $(libfree
else \
if [ -d .git ] ; then \
version=`git log --format="%h %ci" -1 HEAD | head -1 | sed -e 's|:|-|g' || echo hacked` ; \
- if [ "x$$version" == "xhacked" ] ; then \
+ if [ "x$$version" = "xhacked" ] ; then \
version="hacked-`date -u +%Y%m%dT%H%M%SZ`" ; \
else \
version="git-$$version" ; \
fi ;\
else \
version=`svnversion . -n || echo hacked` ; \
- if [ "x$$version" == "xhacked" ] ; then \
+ if [ "x$$version" = "xhacked" ] ; then \
version="hacked-`date -u +%Y%m%dT%H%M%SZ`" ; \
else \
version="svn-$$version" ; \
diff --git a/bootstrap.sh b/bootstrap.sh
index 0ea5cd43d4..4e65c5ca15 100755
--- a/bootstrap.sh
+++ b/bootstrap.sh
@@ -16,7 +16,7 @@ done
BASEDIR=`pwd`;
LIBDIR=${BASEDIR}/libs;
SUBDIRS="ilbc curl iksemel js js/nsprpub libdingaling libedit libsndfile pcre sofia-sip \
- speex sqlite srtp openzap freetdm spandsp libg722_1 portaudio unimrcp tiff-3.8.2 broadvoice silk";
+ speex sqlite srtp openzap freetdm spandsp libg722_1 portaudio unimrcp tiff-3.8.2 broadvoice silk libcodec2";
if [ ! -f modules.conf ]; then
cp build/modules.conf.in modules.conf
diff --git a/build/modules.conf.in b/build/modules.conf.in
index 7730cf2a94..67e1fe62ae 100644
--- a/build/modules.conf.in
+++ b/build/modules.conf.in
@@ -39,6 +39,7 @@ codecs/mod_g723_1
codecs/mod_amr
#codecs/mod_amrwb
#codecs/mod_silk
+#codecs/mod_codec2
codecs/mod_g729
codecs/mod_h26x
codecs/mod_bv
diff --git a/conf/autoload_configs/callcenter.conf.xml b/conf/autoload_configs/callcenter.conf.xml
index e764d17f15..9140193b22 100644
--- a/conf/autoload_configs/callcenter.conf.xml
+++ b/conf/autoload_configs/callcenter.conf.xml
@@ -1,6 +1,7 @@
+
@@ -22,15 +23,15 @@
-
-
-
+
+
+
-
-
+
+
diff --git a/conf/autoload_configs/sangoma_codec.conf.xml b/conf/autoload_configs/sangoma_codec.conf.xml
index 14fae63a6b..05d70de0a7 100644
--- a/conf/autoload_configs/sangoma_codec.conf.xml
+++ b/conf/autoload_configs/sangoma_codec.conf.xml
@@ -23,6 +23,13 @@
to listen for HTTP requests on the same IP/port that you specify here.
-->
+
+
diff --git a/conf/autoload_configs/switch.conf.xml b/conf/autoload_configs/switch.conf.xml
index 7a68a7f2bd..e861b1b61a 100644
--- a/conf/autoload_configs/switch.conf.xml
+++ b/conf/autoload_configs/switch.conf.xml
@@ -15,6 +15,11 @@
+
+
+
+
+
diff --git a/conf/dialplan/default.xml b/conf/dialplan/default.xml
index b143280fba..8bdcfa0da2 100644
--- a/conf/dialplan/default.xml
+++ b/conf/dialplan/default.xml
@@ -240,7 +240,7 @@
diff --git a/conf/lang/en/dir/sounds.xml b/conf/lang/en/dir/sounds.xml
index 02d6b3671f..2bdc1492ec 100644
--- a/conf/lang/en/dir/sounds.xml
+++ b/conf/lang/en/dir/sounds.xml
@@ -2,13 +2,13 @@
-
+
-
+
@@ -33,7 +33,7 @@
-
+
@@ -43,7 +43,7 @@
-
+
@@ -57,7 +57,7 @@
-
+
@@ -66,7 +66,7 @@
-
+
@@ -102,7 +102,7 @@
-
+
diff --git a/conf/sip_profiles/internal.xml b/conf/sip_profiles/internal.xml
index 1c2ef1216c..93558a3584 100644
--- a/conf/sip_profiles/internal.xml
+++ b/conf/sip_profiles/internal.xml
@@ -42,6 +42,26 @@
+
+
+
+
+
+
@@ -226,6 +246,8 @@
+
+
diff --git a/conf/skinny_profiles/internal.xml b/conf/skinny_profiles/internal.xml
index 5feac1ffbf..52da89741d 100644
--- a/conf/skinny_profiles/internal.xml
+++ b/conf/skinny_profiles/internal.xml
@@ -16,7 +16,7 @@
-
+
diff --git a/configure.in b/configure.in
index e8b462f54a..de7261266e 100644
--- a/configure.in
+++ b/configure.in
@@ -904,6 +904,7 @@ AC_CONFIG_FILES([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
src/mod/applications/mod_hash/Makefile
src/mod/endpoints/mod_portaudio/Makefile
@@ -998,6 +999,7 @@ AC_CONFIG_SUBDIRS([libs/spandsp])
AC_CONFIG_SUBDIRS([libs/broadvoice])
AC_CONFIG_SUBDIRS([libs/libg722_1])
AC_CONFIG_SUBDIRS([libs/silk])
+AC_CONFIG_SUBDIRS([libs/libcodec2])
case $host in
*-openbsd*)
diff --git a/debian/changelog b/debian/changelog
index d49637cfc0..7f4e8d7749 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,9 +1,14 @@
freeswitch (1.0.6-1ubuntu1) maverick; urgency=low
+ [ Gabriel Gunderson ]
* upgrade: Added mod_callcenter and pulled out Python into its own
package.
- -- Gabriel Gunderson Thu, 16 Nov 2010 18:28:30 -0800
+ [ Mathieu Parent ]
+ * Updated Uploaders list
+ * Updated Standards-Version to 3.9.1
+
+ -- Mathieu Parent Thu, 23 Sep 2010 15:34:00 +0200
freeswitch (1.0.4-1ubuntu2) karmic; urgency=low
diff --git a/debian/control b/debian/control
index 145f28d767..92b4e6ada5 100644
--- a/debian/control
+++ b/debian/control
@@ -1,10 +1,11 @@
Source: freeswitch
Section: comm
Priority: extra
-Maintainer: Michal Bielicki
+Maintainer: FreeSWITCH developers
+Uploaders: Michal Bielicki , Gabriel Gunderson , William King , Mathieu Parent
Build-Depends: debhelper (>= 5), fakeroot, wget, automake (>=1.9), autoconf, libtool, unixodbc-dev, libasound2-dev, libcurl3-openssl-dev|libcurl4-openssl-dev, libssl-dev, ncurses-dev, libogg-dev, libvorbis-dev, libperl-dev, libgdbm-dev, libdb-dev, libgnutls-dev, libtiff4-dev, python-dev, libx11-dev, uuid-dev
Homepage: http://freeswitch.org/
-Standards-Version: 3.8.4
+Standards-Version: 3.9.1
Vcs-Svn: http://svn.freeswitch.org/svn/freeswitch/trunk/
Vcs-Browser: http://fisheye.freeswitch.org/browse/FreeSWITCH
diff --git a/devel-bootstrap.sh b/devel-bootstrap.sh
new file mode 100755
index 0000000000..a8c4f7d734
--- /dev/null
+++ b/devel-bootstrap.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+export CFLAGS="-ggdb3 -O0"
+export CXXFLAGS="-ggdb3 -O0"
+./bootstrap.sh -j
+./configure $@
+
diff --git a/docs/ChangeLog b/docs/ChangeLog
index a2ed493f37..d6fddd6bfa 100644
--- a/docs/ChangeLog
+++ b/docs/ChangeLog
@@ -16,12 +16,20 @@ freeswitch (1.0.7)
build: VS 2010 - Change to V4 framework, add SWIG v2.0 files to fix release build exceptions(temp fix till we upgrade all SWIG files) (r:812f4309)
build: Windows VS2010 build - remove strange characters (r:ba1546e0/FSBUILD-297)
build: Make bootstrap.sh Bourne shell compatible (r:8dbd62ff/FSBUILD-301)
+ build: add mod_osp Makefile to configure generated Makefiles (r:dc06a039/FS-122)
+ build: Remove mod_spidermonkey from windows 2008 x64 builds - does not work (r:280e894d)
+ build: fix warnings on windows x64 builds src and mods projects - only libsofia included on the libs side (r:45ecbc2f)
+ codec2: working prototype, still for testing only (r:04ca0751)
config: move limit.conf to db.conf
config: Update VM phrase macros to voice option then action on main, config menus
config: Remove 99xx extension numbers to avoid dp conflicts (r:0c9bb174/DP-17)
config: update config example for caller-id-type (r:8f03a7cd)
config: default to 48k since most sound cards can do that (r:170404a4)
config: Create RFC2822_DATE for use in emails. Some clients fail to sort emails properly without a Date: line. (r:a1f19d91)
+ config: move enum to the bottom of default. (r:4d448c97)
+ config: Add att_xfer example to default dialplan (r:20ec962a)
+ config: default example to resolve some issues with SCA in cases where host and ip are mixed causing the phone to be confused. (r:0279261b)
+ config: Fix phrase files, still missing a sound file (r:6741f350/FS-2742)
core: Add RTCP support (FSRTP-14)
core: handle some errors on missing db handle conditions
core: add ... and shutdown as a fail-safe when no modules are loaded
@@ -78,8 +86,34 @@ freeswitch (1.0.7)
core: Implemented 'Block Fork' and removed possibility for "-nc -nf" potential issue. (r:f26a6972/FSCORE-652)
core: Add console callback for listing loaded/available modules for load/unload/reload commands (r:d68a1218/FSCORE-662)
core: strip trailing and leading whitespace in api execute args and commands (r:ca481842)
+ core: Fix SQLLEN to prevent queue buffer overrun (r:68d1c32a/FS-2149)
+ core: add origination_caller_profile to log all attempted calls for a paticular leg (r:977a8ad7)
+ core: Add attribute "path" to autoload_configs/modules.conf.xml entry. (r:1a75821d)
+ core: add tone2wav (r:6f2c455f)
+ core: add speed boost to sql thread (r:ef79535c)
+ core: reverse the linked list in ivr menus to support accidental feature of multiple entries for the same keys (r:d4a01324)
+ core: Add time of day string compare function switch_tod_cmp. It usable in XML dialplan with time-of-day. String format is hh:mm:ss you can define a range like this : 09:00-17:00 (Second are not optional) (r:4ab8fa13)
+ core: Add date time range string compare function switch_fulldate_cmp. It usable in XML dialplan with date-time. String format example : 2009-10-10 14:33:22~2009-11-10 17:32:31. (r:c9fcce08)
+ core: Add day of week 3 letter initial usage in "wday" field in the dialplan. Example : mon-fri. Using number as before is still supported. Several public switch function are available. (r:59ec8ced)
+ core: set conditionals to only fire when the mutex can be obtained (r:07ec7867)
+ core: avoid segfault when sofia tries to update the callee id at the same time as the outbound call is transferred (r:df63657e)
+ core: make code more automagic to shut up the dude on the list (r:d093a4a4)
+ core: Fix memory leak if we fail to enqueue new event to EVENT_QUEUE in switch_event.c (r:ef773e07/FS-2148)
+ core: fix endless loop on startup when specifying -nosql (r:b6a533ee)
+ core: Buffer for url encode in switch_ivr_set_xml_chan_vars() too small by 1 (r:0cc28f37/FS-2167)
+ core: fix switch_ivr_collect_digits_callback to allow an args pointer with null callback to work like other apis (r:89d99a91)
+ core: ERROR_PARTIAL and BAD_PARTIAL are regarded as PARTIAL in switch_regex_match_partial (r:b4548a60/FS-2238)
+ core: sprinkle digit_timeout into switch_ivr_read and switch_ivr_play_and_get_digits and the higher level variants (r:cfa30468)
+ core: Fix parse of variable absolute_codec_string when inside [] (r:54bf6575/FS-2126)
+ core: Fix SWITCH_IO_FLAG_NOBLOCK needed for mod_sangoma_codec (r:bc304153/FS-2017)
+ core: fix coredump in rtcp socket handling (r:6c1070ea/FS-2009)
+ core: add bitrate patch from moc with some extra stuff for late neg mode (r:633f193d)
+ core: refactor fmtp parser as a core func (r:56f8c11f)
+ core: add switch_ivr_dmachine async digit parser to core (r:7f3319dc)
lang: Improve French phrase files (FSCONFIG-23)
+ libapr: Fix issue where after a bridge with a member, uuid of Agent is set to single quote character ' (r:3fee704d/FS-2738)
libdingaling: fix race on shutdown causing crash (FSMOD-47)
+ libdingaling: Fix crash in new GV interface when exceeding 24 calls (r:be00609a/FS-2171)
libesl: Fix potential race condition (ESL-36)
libesl: Add /uuid command to fs_cli to filter logs by uuid
libesl: Increase buffer in fs_cli for Win (r:d1d6be88/FSCORE-611)
@@ -93,9 +127,13 @@ freeswitch (1.0.7)
libesl: Fix SEGV when using serialize function without any arguments (r:910729b5/ESL-44)
libesl: fix leak-on-error in esl_connect_timeout() (r:4263d60e)
libfreetdm: implemented freetdm config nodes and ss7 initial configuration
+ libfreetdm: fix codec for CAS signaling (r:b76e7f18)
+ libfreetdm: freetdm: ss7- added support for incoming group blocks, started adding support for ansi (r:c219a73c)
+ libgnutls: link to libgcrypt as well, please report any platforms this breaks, but it should be portable (r:c569fb0f/FS-1248)
libopenzap: Add CLI tracing
libs: Merged OpenZAP and FreeTDM into the FreeSWITCH tree.
libs: Add support for TLS on Windows using openssl (r:1abe3b93/MODSOFIA-92)
+ libs: fix bsd shell incompatibility (r:e2b85e94/FS-287)
libsofiasip: Fix random crashes (r:c15ee980/SFSIP-219)
libsofiasip: Fix T.38 bug in sofia_glue (r:2843f1ad/MODSOFIA-94)
libsofiasip: VS2010 sofia posix problem (r:46dd24c2/SFSIP-220)
@@ -103,6 +141,7 @@ freeswitch (1.0.7)
libspandsp: removed a saturate16 from spandsp that was causing problems fixed a typo in the MSVC inttypes.h file for spandsp
libspandsp: Changes to the signaling tone detector to detect concurrent 2400Hz + 2600Hz tones. This passes voice immunity and other key tests, but it bounces a bit when transitions like 2400 -> 2400+2600 -> 2600 occur. Transitions between tone off and tone on are clean. (r:bc13e944)
libspandsp: Fix Windows build after libspandsp update (r:d70cc852/FSBUILD-293)
+ libspandsp: Fix for T.30 processing of operator interrupts, to improve compatibility with some machines, which seem to send them when no operator is around. (r:84ee0ae6)
mod_avmd: Initial check in - Advanced Voicemail Detect (r:10c6a30a) (by Eric Des Courtis)
mod_avmd: Add to windows build (r:df4bd935)
mod_callcenter: Initial commit of the mod_callcenter application. This module is in it early state of developpement. You can see documentation on the wiki at : http://wiki.freeswitch.org/wiki/Mod_callcenter For support/comments, please use http://jira.freeswitch.org/ and select the MOD CALLCENTER module. (r:ba09b96d)
@@ -116,7 +155,10 @@ freeswitch (1.0.7)
mod_callcenter: You can now allow caller that have hangup before agent answer to call back and resume their previous position. (r:ab2529d4)
mod_callcenter: correct multiple little things following the recent tiers and join back features (r:9b33bd1c)
mod_callcenter: Add more channel variable and event and fix a mem leak (r:2d3d8c8d)
- od_callcenter: Make more sence to bridge the caller to the agent. Before, in the xml_cdr you saw it it like the agent initiated the call to the member (r:0be95658)
+ mod_callcenter: Make more sence to bridge the caller to the agent. Before, in the xml_cdr you saw it it like the agent initiated the call to the member (r:0be95658)
+ mod_callcenter: Added max-wait-time and max-wait-time-with-no-agent param to a queue. (r:3482f95e)
+ mod_callcenter: Make sure we fail to load if config is not present (r:e1fb79a1)
+ mod_callcenter: Fix invalid update of agent field (r:426a448f/FS-2738)
mod_cidlookup: null xml is bad (r:095815f8)
mod_cid_lookup: honor skipcitystate when using whitepages (r:a66654de/FSMOD-53)
mod_commands: make break uuid_break and add cascade flag
@@ -127,6 +169,10 @@ freeswitch (1.0.7)
mod_commands: Fix a segfault if no arguments is provided to limit_hash_usage (r:8ceb2a9b)
mod_commands: fsctl max_session should display int, not float (r:f7e2410e/FSCORE-634)
mod_commands: limit - reset rate and release resource apis Thanks Moy (r:a7c31e6f/FSCORE-637)
+ mod_commands: Fix user_data returning the first value found instead of the last. Also add support to get variable from the group. (r:402f2391)
+ mod_commands: Allow cond API to return empty false value (r:c8a897b9)
+ mod_commands: ***BEHAVIOUR CHANGE*** reloadacl, load , reload will now explicitly call reloadxml (r:42c9df72)
+ mod_commands: add nat_map usage (r:7577b8aa)
mod_conference: Fix reporting of volume up/down (MODAPP-419)
mod_conference: add last talking time per member to conference xml list
mod_conference: add terminate-on-silence conference param
@@ -139,10 +185,13 @@ freeswitch (1.0.7)
mod_dingaling: make mod_dingaling compat with google's new free phonecalls thing (r:ba0a2a32)
mod_dingaling: make dingaling work with google voice inbound too (r:4ee68141)
mod_dingaling: Fix crash when testing the new gv-dingaling with around 24 concurrent calls (r:73e1ec5e/FSCORE-667)
+ mod_dingaling: Fix NULL pointer (r:e3eff816/FS-1103)
+ mod_directory: Add variable directory_search_order to allow to search by first name by default is set to "first_name" (r:163ca31f)
mod_db: fix stack corruption (MODAPP-407)
mod_dptools: add eavesdrop_enable_dtmf chan var (r:596c0012)
mod_dptools: Make park app not send 183 session progress (r:76932995/FSCORE-567)
mod_dptools: add block_dtmf and unblock_dtmf apps (r:d9eb0197)
+ mod_dptools: refactor export code and add new bridge_export app which is like export but exports across when one channel bridges another (r:4aa9a838)
mod_erlang_event: Make XML fetch reply ACKs distinguishable, update freeswitch.erl (r:9d44ed04)
mod_erlang_event: Add 3 new commands; session_event, session_noevents, session_nixevent (r:698fa045)
mod_erlang_event: generate long node names the same as erlang does (r:9ad509c2)
@@ -153,6 +202,8 @@ freeswitch (1.0.7)
mod_fifo: cancel outbound call if customer hangs up (r:cadb4d94)
mod_fifo: add taking_calls param to fifo member add and config file (r:821488bf)
mod_fifo: add nomedia flag (r:2d30a8c2)
+ mod_fifo: Fix inconsistency between the fifo queue and the channels (num callers in queue can become "-1") (r:07487114/FS-1659)
+ mod_fifo: fix issue leaving stale records in fifo_bridge table (r:b36d015f)
mod_freetdm: Fix for TON and NPI not passed through to channel variables on incoming calls
mod_freetdm: add pvt data to freetdm channels fix fxs features (r:9d456900)
mod_freetdm: export and import boost custom data (r:edb2d582)
@@ -213,9 +264,15 @@ freeswitch (1.0.7)
mod_lcr: fix dialplan issues with default profile and logging when no caller_profile set (r:00170558)
mod_lcr: assign default profile even if testing is skipped (r:6420099c)
mod_lcr: fix compiler warning on newer gcc (r:bfa414cb)
+ mod_lcr: don't count twice (r:eaeabc7b/FS-1810)
mod_loopback: add loopback_bowout_on_execute var to make 1 legged loopback calls bow out of the picture
mod_loopback: only execute app once in app mode (r:64f58f2d)
+ mod_loopback: fix bug in mod_loopback where bowout=false (r:e9ab5368)
+ mod_lua: Add switch_core_sqldb functionality from inside Lua script (r:26f2e095/FS-1384)
+ mod_lua: Made 2nd arg to freeswitch.Dbh:query (cb func) optional (r:87db11af)
+ mod_lua: Added SAF_ROUTING_EXEC flag to lua app, so it can be run inline (r:7d5ca1c0)
mod_managed: Added wrapper for switch_event_bind for .net (r:a5f07a80/MODLANG-165)
+ mod_managed: add additional support (r:5be58aac)
mod_mp4v: MP4V-ES passthru for washibechi on IRC
mod_nibblebill: free allocated mem at shutdown; free properly if using custom_sql
mod_nibblebill: Add SAF_SUPPORT_NOMEDIA to nibblebill
@@ -235,6 +292,7 @@ freeswitch (1.0.7)
mod_sangoma_codec: rename load/noload to register/noregister
mod_sangoma_codec: silence suppression (r:73d9d56f)
mod_say_es: fix grammar when saying dates and time (r:6bed19b2/MODAPP-429)
+ mod_say_ja: initial commit, still needs sound files (r:b2423158/FS-2755)
mod_say_ru: Fix saying time with +1 hour of current time (r:68d74c31/MODAPP-444)
mod_say_zh: Number reading should now be OK for the whole range of integers for Cantonese and Mandarin
mod_silk: Fix mod_silk compliance and performance issues (r:2ddbc457/MODCODEC-20)
@@ -303,12 +361,47 @@ freeswitch (1.0.7)
mod_sofia: Fix memleak and mwi event not generated on first register (r:04b9b3e2)
mod_sofia: when getting presence with no payload consider it an extension to the expires time in the dialog (r:70331e88)
mod_sofia: don't put blank 'version' attr in dialog-info packets (r:749dc864)
+ mod_sofia: speed up db action in sofia recover (r:8114b3f1)
+ mod_sofia: Support display updates for Cisco SIP endpoints (tested on SPA series) (r:ac205288/FS-884)
+ mod_sofia: dont put an rpid in 183 or 200 if pass-callee-id is false (r:86de47ff)
+ mod_sofia: improve sofia recover in some nat cases (r:4526ba30)
+ mod_sofia: edge cases for sofia recover (r:646a5609)
+ mod_sofia: Correct the order what param and variables are overriding them self in user/group/domain (r:5a6f0f5c)
+ mod_sofia: include accumulated stats from rtcp into vars (r:d5ff3e04)
+ mod_sofia: make sure hold-related code is skipped 100% with disable-hold set (r:403bf6af)
+ mod_sofia: make force-subscription-expires only work on nonzero expire deltas, 0 means unscubscribe (r:b7751868)
+ mod_sofia: presence tweaks and addition of all-reg-options-ping which is like nat-options-ping only for every registered host (r:04b52156)
+ mod_sofia: If sip_invite_domain is used lets use it for rpid_domain no matter what because I know best if I set it (r:8726104a)
+ mod_sofia: add inline lists for tab complete db using ::[a:b syntax (r:445731ee)
+ mod_sofia: add sofia profile gwlist up|down to list up or downed profiles for feeding into mod distributor to exclude dead gateways (r:0477cb67)
+ mod_sofia: add 'sofia global siptrace on' so we don't have to always teach people to enable sip trace on each profile (r:09fa6678)
+ mod_sofia: fix seg on subscribe with no contact host (r:c236541e)
+ mod_sofia: fix typo and printf specifier resulting in incorrect output of call counts on profiles and gateways (r:29ea6e29)
+ mod_sofia: fix t38 passthru when port changes on re-invite (r:72baaf6d)
+ mod_sofia: let ~ signify that multipart content will contain headers (r:3548168d)
+ mod_sofia: Fix rash with rxfax when no remote host (r:a9446ac1/FS-677)
+ mod_sofia: Handle incorrectly formatted T.38 booleans (r:8f731f42/FS-957)
+ mod_sofia: fix crash in sofia_reg_find_gateway_by_realm__ (r:721c8019/FS-488)
+ mod_sofia: Handle 301 moved permanently. (r:ba59c51d/FS-2739)
+ mod_sofia: don't passthru when its proxy media, bypass media or there is no rtp session, fixes seg (r:45e2b99d)
+ mod_sofia: improve video support for new polycom phones (r:84a383fe)
+ mod_sofia: Forward unsolicited MWI nofity (r:e946da9a/FS-861)
+ mod_sofia: Support display updates for Cisco SIP endpoints (tested on SPA series) (r:6937ca39/FS-884)
+ mod_sofia: BLF compliance with RFC-4235: dialog-info 'version=' field is reset to 0 on every new call instead of being incremented (r:589502d3/FS-2747)
+ mod_sofia: fix parsing of sofia tracelevel param, moved param from profile params to global_settings as its global, and it only worked on reparse before anyways. Please correct any documentation on this issue on the wiki (r:82c4c4cc/FS-523)
+ mod_sofia: fix nat acl count check to check against the number of nat acls (r:e11550e7/FS-502)
+ mod_sofia: add sofia_glue_find_parameter_value function to get a specific value from a url params string (r:c701d41c)
mod_spandsp: initial checkin of mod_fax/mod_voipcodecs merge into mod_spandsp (r:fa9a59a8)
mod_spandsp: rework of new mod_spandsp to have functions broken up into different c files (r:65400642)
mod_spandsp: improve duplicate digit detection and add 'min_dup_digit_spacing_ms' channel variable for use with the dtmf detector (r:eab4f246/FSMOD-45)
mod_spandsp: add start_tone_detect/stop_tone_detect app and api commands for tone and cadence detection (r:a6e65147/MODAPP-378)
mod_spandsp: Fix mod_spandsp receive t38 fax error in windows7 (r:fca93f29/MODAPP-443)
mod_spandsp: Moved spandsp to a more recent version. A huge number of little changes occur here, as recently spandsp lost all the $Id$ entries the source files had for the dark old days of CVS (r:f029f7ef)
+ mod_spandsp: move app flag into 'T38' namespace for the sake of housekeeping (r:0d0b4b43)
+ mod_spandsp: make t38 terminal mode more reliable (r:83da7bd3)
+ mod_spandsp: deadlock in mod_spandsp (mod_spandsp_fax.c) (r:b02c69bb/FS-1690)
+ mod_spandsp: T.38 reINVITE glare condition causes FAX processing to stop. (r:04aa7ef9/FS-1682)
+ mod_spandsp: improve nat handling when using stun or host as ext-rtp-ip (r:03e74c51/FS-526)
mod_spidermonkey: allow vars to be set containing vars from languages (r:5cd072a3)
mod_spidermonkey: fix seg in js hangup (r:7d554c11)
mod_spidermonkey: Fix mod_spidermonkey build on FreeBSD, (Undefined symbol PR_LocalTimeParameters). (r:3edb8419)
@@ -317,15 +410,22 @@ freeswitch (1.0.7)
mod_unimrcp: fix fortify findings for mod_unimrcp (r:336f0b4e/FSMOD-67)
mod_valet_parking: add event data to valet parking hold event
mod_valet_parking: add event for Valet Parking action exit
+ mod_valet_parking: pass hold class on transfer (r:76a065ec)
mod_voicemail: Fix vm_prefs profile lock (MODAPP-417)
mod_voicemail: add 'vm-enabled' param (default true)
mod_voicemail: fix vm msg being deleted when pressing key to forward to email (MODAPP-403)
mod_voicemail: make voicemails use the uuid of the channel who recorded it when applicable (r:98a5a30a)
mod_voicemail: user unable to play or delete voicemail via web API (r:b5205c0b/MODAPP-447)
+ mod_voicemail: Allow to forward a message or send it via email key during the playback of the recording, not just when the menu is playing. (r:83aeda79)
+ mod_voicemail: fix vm_inject to a group and change syntax for sending to a whole domain to domain= for clarity sake (r:f30a1cc6)
+ mod_voicemail: add quotes to vm_cc command generated internally to escape spaces in the caller id name (r:5f012813)
+ mod_voicemail: Play caller id of callee prior to playing a vmail (r:e7b97907/FS-2719)
mod_xml_cdr: add force_process_cdr var to process b leg cdr on a case by case basis when b leg cdr is disabled (XML-17)
mod_xml_cdr: add leg param to query string (XML-24)
mod_xml_cdr: fix locked sessions (XML-26)
mod_xml_cdr: fix minor memory leaks and config bug (r:19253d83/MODEVENT-62)
+ mod_xml_rpc: Fix crash if unauthorized XML RPC is attempted (r:9835395c/FS-184)
+ scripts: added honeypot.pl and blacklist.pl which add extra SIP security options (r:b6a81ba7)
sofia-sip: fix null derefernce segfault in soa (r:f356c5e6)
sofia-sip: extend timeout for session expires on short timeouts to be 90% of timeout instead of 1/3 to handle devices that do not refresh in time such as polycom (r:a7f48928/SFSIP-212)
diff --git a/docs/phrase/phrase_en.xml b/docs/phrase/phrase_en.xml
index 65c394cfc8..318aba18dd 100644
--- a/docs/phrase/phrase_en.xml
+++ b/docs/phrase/phrase_en.xml
@@ -364,6 +364,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -387,15 +402,40 @@
-
+
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/freeswitch.spec b/freeswitch.spec
index 76f9df4fb9..a2c975b5a9 100644
--- a/freeswitch.spec
+++ b/freeswitch.spec
@@ -1,11 +1,11 @@
-###############################################################################################################################
-###############################################################################################################################
+######################################################################################################################
+######################################################################################################################
#
# spec file for package freeswitch
#
# includes module(s): freeswitch-devel freeswitch-codec-passthru-amr freeswitch-codec-passthru-amrwb freeswitch-codec-passthru-g729
# freeswitch-codec-passthru-g7231 freeswitch-lua freeswitch-perl freeswitch-python freeswitch-spidermonkey
-# freeswitch-lan-de freeswitch-lang-en freeswitch-lang-fr freeswitch-lang-ru freeswitch-openzap
+# freeswitch-lan-de freeswitch-lang-en freeswitch-lang-fr freeswitch-lang-ru freeswitch-freetdm
#
# Initial Version Copyright (C) 2007 Peter Nixon and Michal Bielicki, All Rights Reserved.
#
@@ -26,8 +26,8 @@
#
# Maintainer(s): Michal Bielicki 100
#BuildRequires: openldap2-devel
@@ -103,6 +103,7 @@ BuildRequires: alsa-lib-devel
BuildRequires: which
BuildRequires: zlib-devel
BuildRequires: e2fsprogs-devel
+BuildRequires: libtheora-devel
Requires: alsa-lib
Requires: libogg
Requires: libvorbis
@@ -115,6 +116,9 @@ Requires: openldap
Requires: db4
Requires: gdbm
Requires: zlib
+Requires: libtiff
+Requires: python
+Requires: libtheora
%if %{?suse_version:1}0
%if 0%{?suse_version} > 910
@@ -128,11 +132,11 @@ PreReq: %insserv_prereq %fillup_prereq
%endif
-###############################################################################################################################
+######################################################################################################################
#
-# Where the packages are going to be built
+# Where the packages are going to be built
#
-###############################################################################################################################
+######################################################################################################################
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
%description
@@ -155,12 +159,12 @@ Our developers are heavily involved in open source and have donated code and oth
other telephony projects including sipXecs, OpenSER, Asterisk, CodeWeaver and OpenPBX.
-###############################################################################################################################
+######################################################################################################################
#
-# Sub Package definitions. Description and Runtime Requirements go here
-# What goes into which package is in the files section after the whole build enchilada
+# Sub Package definitions. Description and Runtime Requirements go here
+# What goes into which package is in the files section after the whole build enchilada
#
-###############################################################################################################################
+######################################################################################################################
%package devel
@@ -269,19 +273,23 @@ Group: System/LibrariesRequires: %{name} = %{version}-%{release}
German language phrases module and directory structure for say module and voicemail
-%package openzap
+%package freetdm
Summary: Provides a unified interface to hardware TDM cards and ss7 stacks for FreeSWITCH
Group: System/Libraries
Requires: %{name} = %{version}-%{release}
+%{?with_sang_isdn: Requires: wanpipe }
+%{?with_sang_isdn: Requires: libsng_isdn }
+%{?with_sang_isdn: BuildRequires: wanpipe }
+%{?with_sang_isdn: BuildRequires: libang_isdn }
-%description openzap
-OpenZAP
+%description freetdm
+FreeTDM
-###############################################################################################################################
+######################################################################################################################
#
-# Unpack and prepare Source archives, copy stuff around etc ..
+# Unpack and prepare Source archives, copy stuff around etc ..
#
-###############################################################################################################################
+######################################################################################################################
%prep
%setup -b0 -q
@@ -297,11 +305,11 @@ cp %{SOURCE9} libs/
cp %{SOURCE10} libs/
cp %{SOURCE11} libs/
-###############################################################################################################################
+######################################################################################################################
#
-# Start the Build process
+# Start the Build process
#
-###############################################################################################################################
+######################################################################################################################
%build
%ifos linux
%if 0%{?suse_version} > 1000 && 0%{?suse_version} < 1030
@@ -312,115 +320,124 @@ export QA_RPATHS=$[ 0x0001|0x0002 ]
%endif
%endif
-###############################################################################################################################
+######################################################################################################################
#
-# Here the modules that will be build get defined
+# Here the modules that will be build get defined
#
-###############################################################################################################################
-###############################################################################################################################
+######################################################################################################################
+######################################################################################################################
#
-# Application Modules
+# Application Modules
#
-###############################################################################################################################
-APPLICATION_MODULES_AE="applications/mod_avmd applications/mod_commands applications/mod_conference applications/mod_db applications/mod_directory applications/mod_distributor applications/mod_dptools applications/mod_easyroute applications/mod_enum applications/mod_esf applications/mod_expr applications/mod_callcenter"
-
-APPLICATION_MODULES_FM="applications/mod_fifo applications/mod_fsv applications/mod_hash applications/mod_lcr applications/mod_limit applications/mod_memcache"
-
-APPLICATION_MODULES_NY=" applications/mod_redis applications/mod_rss applications/mod_soundtouch applications/mod_spandsp applications/mod_stress applications/mod_spy "
-
-APPLICATION_MODULES_VZ="applications/mod_valet_parking applications/mod_vmd applications/mod_voicemail"
+######################################################################################################################
+APPLICATION_MODULES_AE="applications/mod_avmd applications/mod_callcenter applications/mod_cidlookup applications/mod_cluechoo \
+ applications/mod_commands applications/mod_conference applications/mod_db applications/mod_directory \
+ applications/mod_distributor applications/mod_dptools applications/mod_easyroute applications/mod_enum \
+ applications/mod_esf applications/mod_expr"
+APPLICATION_MODULES_FM="applications/mod_fifo applications/mod_fsv applications/mod_hash applications/mod_lcr applications/mod_limit \
+ applications/mod_memcache"
+APPLICATION_MODULES_NY="applications/mod_nibblebill applications/mod_redis applications/mod_rss 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_MODULES="$APPLICATION_MODULES_AE $APPLICATION_MODULES_FM $APPLICATION_MODULES_NY $APPLICATION_MODULES_VZ"
-###############################################################################################################################
+######################################################################################################################
#
-# Automatic Speech Recognition and Text To Speech Modules
+# Automatic Speech Recognition and Text To Speech Modules
#
-###############################################################################################################################
+######################################################################################################################
ASR_TTS_MODULES="asr_tts/mod_pocketsphinx asr_tts/mod_flite asr_tts/mod_unimrcp"
-###############################################################################################################################
+######################################################################################################################
#
-# Codecs
+# Codecs
#
-###############################################################################################################################
-CODECS_MODULES="codecs/mod_ilbc codecs/mod_h26x codecs/mod_speex codecs/mod_celt codecs/mod_siren codecs/mod_bv"
-###############################################################################################################################
+######################################################################################################################
+CODECS_MODULES="codecs/mod_bv codecs/mod_h26x codecs/mod_speex codecs/mod_celt codecs/mod_codec2 codecs/mod_ilbc codecs/mod_mp4v \
+ codecs/mod_silk codecs/mod_siren codecs/mod_theora"
+######################################################################################################################
#
-# Dialplan Modules
+# Dialplan Modules
#
-###############################################################################################################################
+######################################################################################################################
DIALPLANS_MODULES="dialplans/mod_dialplan_asterisk dialplans/mod_dialplan_directory dialplans/mod_dialplan_xml"
-###############################################################################################################################
+######################################################################################################################
#
-# Directory Modules
+# Directory Modules
#
-###############################################################################################################################
+######################################################################################################################
DIRECTORIES_MODULES=""
-###############################################################################################################################
+######################################################################################################################
#
-# Endpoints
+# Endpoints
#
-###############################################################################################################################
-ENDPOINTS_MODULES="endpoints/mod_dingaling endpoints/mod_portaudio endpoints/mod_sofia ../../libs/openzap/mod_openzap endpoints/mod_loopback"
-###############################################################################################################################
+######################################################################################################################
+ENDPOINTS_MODULES="endpoints/mod_dingaling endpoints/mod_loopback ../../libs/freetdm/mod_freetdm endpoints/mod_portaudio \
+ endpoints/mod_sofia"
+
+######################################################################################################################
#
-# Event Handlers
+# Event Handlers
#
-###############################################################################################################################
-EVENT_HANDLERS_MODULES="event_handlers/mod_event_multicast event_handlers/mod_event_socket event_handlers/mod_cdr_csv"
-###############################################################################################################################
+######################################################################################################################
+EVENT_HANDLERS_MODULES="event_handlers/mod_cdr_csv event_handlers/mod_event_socket event_handlers/mod_event_multicast"
+######################################################################################################################
#
-# File and Audio Format Handlers
+# File and Audio Format Handlers
#
-###############################################################################################################################
-FORMATS_MODULES="formats/mod_local_stream formats/mod_native_file formats/mod_sndfile formats/mod_tone_stream formats/mod_shout formats/mod_file_string"
-###############################################################################################################################
-#
-# Embedded Languages
-#
-###############################################################################################################################
-LANGUAGES_MODULES="languages/mod_lua languages/mod_perl languages/mod_python languages/mod_spidermonkey"
-###############################################################################################################################
-#
-# Logging Modules
-#
-###############################################################################################################################
-LOGGERS_MODULES="loggers/mod_console loggers/mod_logfile loggers/mod_syslog"
-###############################################################################################################################
-#
-# Passthru Codecs
-#
-###############################################################################################################################
-PASSTHRU_CODEC_MODULES="codecs/mod_amr codecs/mod_amrwb codecs/mod_g723_1 codecs/mod_g729"
-###############################################################################################################################
-#
-# Phrase engine language modules
-#
-###############################################################################################################################
-SAY_MODULES="say/mod_say_de say/mod_say_en say/mod_say_fr say/mod_say_ru"
-###############################################################################################################################
-#
-# Timers
-#
-###############################################################################################################################
-TIMERS_MODULES=
-###############################################################################################################################
-#
-# XML Modules
-#
-###############################################################################################################################
-XML_INT_MODULES="xml_int/mod_xml_cdr xml_int/mod_xml_curl xml_int/mod_xml_rpc"
-###############################################################################################################################
-#
-# Create one environment variable out of all the module defs
-#
-###############################################################################################################################
-MYMODULES="$PASSTHRU_CODEC_MODULES $APPLICATIONS_MODULES $CODECS_MODULES $DIALPLANS_MODULES $DIRECTORIES_MODULES $ENDPOINTS_MODULES $ASR_TTS_MODULES $EVENT_HANDLERS_MODULES $FORMATS_MODULES $LANGUAGES_MODULES $LOGGERS_MODULES $SAY_MODULES $TIMERS_MODULES $XML_INT_MODULES"
+######################################################################################################################
+FORMATS_MODULES="formats/mod_file_string formats/mod_local_stream formats/mod_native_file formats/mod_portaudio_stream \
+ formats/mod_shout formats/mod_sndfile formats/mod_tone_stream"
-###############################################################################################################################
+######################################################################################################################
#
-# Create Modules build list and set variables
+# Embedded Languages
#
-###############################################################################################################################
+######################################################################################################################
+LANGUAGES_MODULES="languages/mod_lua languages/mod_perl languages/mod_python languages/mod_spidermonkey"
+######################################################################################################################
+#
+# Logging Modules
+#
+######################################################################################################################
+LOGGERS_MODULES="loggers/mod_console loggers/mod_logfile loggers/mod_syslog"
+######################################################################################################################
+#
+# Passthru Codecs
+#
+######################################################################################################################
+PASSTHRU_CODEC_MODULES="codecs/mod_amr codecs/mod_amrwb codecs/mod_g723_1 codecs/mod_g729"
+######################################################################################################################
+#
+# Phrase engine language modules
+#
+######################################################################################################################
+SAY_MODULES="say/mod_say_de say/mod_say_en say/mod_say_fr say/mod_say_ru"
+######################################################################################################################
+#
+# Timers
+#
+######################################################################################################################
+TIMERS_MODULES=
+######################################################################################################################
+#
+# XML Modules
+#
+######################################################################################################################
+XML_INT_MODULES="xml_int/mod_xml_cdr xml_int/mod_xml_curl xml_int/mod_xml_rpc"
+######################################################################################################################
+#
+# Create one environment variable out of all the module defs
+#
+######################################################################################################################
+MYMODULES="$PASSTHRU_CODEC_MODULES $APPLICATIONS_MODULES $CODECS_MODULES $DIALPLANS_MODULES $DIRECTORIES_MODULES \
+$ENDPOINTS_MODULES $ASR_TTS_MODULES $EVENT_HANDLERS_MODULES $FORMATS_MODULES $LANGUAGES_MODULES $LOGGERS_MODULES \
+$SAY_MODULES $TIMERS_MODULES $XML_INT_MODULES"
+
+######################################################################################################################
+#
+# Create Modules build list and set variables
+#
+######################################################################################################################
export MODULES=$MYMODULES
test ! -f modules.conf || rm -f modules.conf
@@ -431,11 +448,11 @@ export DESTDIR=%{buildroot}/
export PKG_CONFIG_PATH=/usr/bin/pkg-config:$PKG_CONFIG_PATH
export ACLOCAL_FLAGS="-I /usr/share/aclocal"
-###############################################################################################################################
+######################################################################################################################
#
-# Bootstrap, Configure and Build the whole enchilada
+# Bootstrap, Configure and Build the whole enchilada
#
-###############################################################################################################################
+######################################################################################################################
if test ! -f Makefile.in
then
@@ -447,10 +464,10 @@ fi
--prefix=%{prefix} \
--infodir=%{_infodir} \
--mandir=%{_mandir} \
- --sysconfdir=%{sysconfdir} \
- --libdir=%{prefix}/lib \
- --enable-core-libedit-support \
- --enable-core-odbc-support \
+ --sysconfdir=%{sysconfdir} \
+ --libdir=%{prefix}/lib \
+ --enable-core-libedit-support \
+ --enable-core-odbc-support \
%ifos linux
%if 0%{?fedora_version} >= 8
%else
@@ -467,11 +484,11 @@ touch .noversion
%{__make}
-###############################################################################################################################
+######################################################################################################################
#
-# Install it and create some required dirs and links
+# Install it and create some required dirs and links
#
-###############################################################################################################################
+######################################################################################################################
%install
%{__make} DESTDIR=%{buildroot} install
@@ -502,11 +519,11 @@ touch .noversion
%endif
-###############################################################################################################################
+######################################################################################################################
#
-# Add a freeswitch user with group daemon that will own the whole enchilada
+# Add a freeswitch user with group daemon that will own the whole enchilada
#
-###############################################################################################################################
+######################################################################################################################
%pre
%ifos linux
if ! /usr/bin/id freeswitch &>/dev/null; then
@@ -526,11 +543,11 @@ chkconfig --add freeswitch
%postun
-###############################################################################################################################
+######################################################################################################################
#
-# On uninstallation get rid of the freeswitch user
+# On uninstallation get rid of the freeswitch user
#
-###############################################################################################################################
+######################################################################################################################
%{?run_ldconfig:%run_ldconfig}
if [ $1 -eq 0 ]; then
userdel freeswitch || %logmsg "User \"freeswitch\" could not be deleted."
@@ -540,19 +557,19 @@ fi
%{__rm} -rf %{buildroot}
%files
-###############################################################################################################################
+######################################################################################################################
#
-# What to install where ... first set default permissions
+# What to install where ... first set default permissions
#
-###############################################################################################################################
+######################################################################################################################
%defattr(-,freeswitch,daemon)
-###############################################################################################################################
+######################################################################################################################
#
-# Directories
+# Directories
#
-###############################################################################################################################
+######################################################################################################################
#
-#################################### Basic Directory Structure ################################################################
+#################################### Basic Directory Structure #######################################################
#
%dir %attr(0750, freeswitch, daemon) %{prefix}/conf
%dir %attr(0750, freeswitch, daemon) %{prefix}/db
@@ -562,7 +579,7 @@ fi
%dir %attr(0750, freeswitch, daemon) %{runtimedir}
%dir %attr(0750, freeswitch, daemon) %{prefix}/scripts
#
-#################################### Config Directory Structure ################################################################
+#################################### Config Directory Structure #######################################################
#
%dir %attr(0750, freeswitch, daemon) %{prefix}/conf/autoload_configs
%dir %attr(0750, freeswitch, daemon) %{prefix}/conf/dialplan
@@ -579,7 +596,7 @@ fi
%dir %attr(0750, freeswitch, daemon) %{prefix}/conf/sip_profiles/internal
%dir %attr(0750, freeswitch, daemon) %{prefix}/conf/skinny_profiles
#
-#################################### Grammar Directory Structure ################################################################
+#################################### Grammar Directory Structure #####################################################
#
%dir %attr(0750, freeswitch, daemon) %{prefix}/grammar/model
%dir %attr(0750, freeswitch, daemon) %{prefix}/grammar/model/communicator
@@ -587,11 +604,11 @@ fi
%ifos linux
%config(noreplace) %attr(0644, freeswitch, daemon) /etc/monit.d/freeswitch.monitrc
%endif
-###############################################################################################################################
+######################################################################################################################
#
-# Config Files
+# Config Files
#
-###############################################################################################################################
+######################################################################################################################
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/*.tpl
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/*.ttml
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/*.xml
@@ -650,60 +667,59 @@ fi
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/xml_curl.conf.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/xml_rpc.conf.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/zeroconf.conf.xml
-###############################################################################################################################
+######################################################################################################################
#
-# Dialplans
+# Dialplans
#
-###############################################################################################################################
+######################################################################################################################
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/dialplan/*.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/dialplan/default/*.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/dialplan/public/*.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/dialplan/skinny-patterns/*.xml
-###############################################################################################################################
+######################################################################################################################
#
-# User Directories
+# User Directories
#
-###############################################################################################################################
+######################################################################################################################
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/directory/*.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/directory/default/*
-###############################################################################################################################
+######################################################################################################################
#
-# IVR Menues
+# IVR Menues
#
-###############################################################################################################################
+######################################################################################################################
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/ivr_menus/*.xml
-###############################################################################################################################
+######################################################################################################################
#
-# Sip Profiles
+# Sip Profiles
#
-###############################################################################################################################
+######################################################################################################################
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/sip_profiles/*.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/sip_profiles/internal/*.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/sip_profiles/external/*.xml
-###############################################################################################################################
+######################################################################################################################
#
-# Other Protocol Profiles (skinny, jingle, mrcp)
+# Other Protocol Profiles (skinny, jingle, mrcp)
#
-###############################################################################################################################
+######################################################################################################################
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/skinny_profiles/*.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/jingle_profiles/*.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/mrcp_profiles/*.xml
-###############################################################################################################################
+######################################################################################################################
#
-# Grammar Files
+# Grammar Files
#
-###############################################################################################################################
+######################################################################################################################
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/grammar/default.dic
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/grammar/model/communicator/*
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/grammar/model/wsj1/*
-###############################################################################################################################
+######################################################################################################################
#
-# Other FÃles
+# Other FÃles
#
-###############################################################################################################################
+######################################################################################################################
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/htdocs/*
%ifos linux
-#/etc/ld.so.conf.d/*
/etc/rc.d/init.d/freeswitch
/etc/sysconfig/freeswitch
%if 0%{?suse_version} > 100
@@ -713,23 +729,27 @@ fi
%ifos linux
%dir %attr(0750, root, root) /etc/monit.d
%endif
-###############################################################################################################################
+######################################################################################################################
#
-# Binaries
+# Binaries
#
-###############################################################################################################################
+######################################################################################################################
%attr(0755, freeswitch, daemon) %{prefix}/bin/*
%{prefix}/lib/libfreeswitch*.so*
-###############################################################################################################################
+######################################################################################################################
#
-# Modules in Alphabetical Order, please keep them that way..
+# Modules in Alphabetical Order, please keep them that way..
#
-###############################################################################################################################
+######################################################################################################################
%{prefix}/mod/mod_amrwb.so*
%{prefix}/mod/mod_avmd.so*
%{prefix}/mod/mod_bv.so*
+%{prefix}/mod/mod_callcenter.so*
%{prefix}/mod/mod_cdr_csv.so*
%{prefix}/mod/mod_celt.so*
+%{prefix}/mod/mod_cidlookup.so*
+%{prefix}/mod/mod_cluechoo.so*
+%{prefix}/mod/mod_codec2.so*
%{prefix}/mod/mod_console.so*
%{prefix}/mod/mod_commands.so*
%{prefix}/mod/mod_conference.so*
@@ -747,7 +767,6 @@ fi
%{prefix}/mod/mod_event_multicast.so*
%{prefix}/mod/mod_event_socket.so*
%{prefix}/mod/mod_expr.so*
-%{prefix}/mod/mod_callcenter.so*
%{prefix}/mod/mod_fifo.so*
%{prefix}/mod/mod_file_string.so*
%{prefix}/mod/mod_flite.so*
@@ -761,14 +780,19 @@ fi
%{prefix}/mod/mod_logfile.so*
%{prefix}/mod/mod_loopback.so*
%{prefix}/mod/mod_memcache.so*
+%{prefix}/mod/mod_mp4v.so*
%{prefix}/mod/mod_native_file.so*
+%{prefix}/mod/mod_nibblebill.so*
%{prefix}/mod/mod_pocketsphinx.so*
%{prefix}/mod/mod_portaudio.so*
+%{prefix}/mod/mod_portaudio_stream.so*
%{prefix}/mod/mod_redis.so*
%{prefix}/mod/mod_rss.so*
%{prefix}/mod/mod_shout.so*
+%{prefix}/mod/mod_silk.so*
%{prefix}/mod/mod_siren.so*
%{prefix}/mod/mod_sndfile.so*
+%{prefix}/mod/mod_snom.so*
%{prefix}/mod/mod_sofia.so*
%{prefix}/mod/mod_soundtouch.so*
%{prefix}/mod/mod_spandsp.so*
@@ -776,6 +800,7 @@ fi
%{prefix}/mod/mod_spy.so*
%{prefix}/mod/mod_stress.so*
%{prefix}/mod/mod_syslog.so*
+%{prefix}/mod/mod_theora.so*
%{prefix}/mod/mod_tone_stream.so*
%{prefix}/mod/mod_unimrcp.so*
%{prefix}/mod/mod_valet_parking.so*
@@ -784,13 +809,11 @@ fi
%{prefix}/mod/mod_xml_cdr.so*
%{prefix}/mod/mod_xml_curl.so*
%{prefix}/mod/mod_xml_rpc.so*
-
-
-###############################################################################################################################
+######################################################################################################################
#
-# Package for the developer
+# Package for the developer
#
-###############################################################################################################################
+######################################################################################################################
%files devel
%defattr(-, freeswitch, daemon)
%{prefix}/lib/*.a
@@ -799,29 +822,28 @@ fi
%{prefix}/mod/*.a
%{prefix}/mod/*.la
%{prefix}/include/*.h
-
-###############################################################################################################################
+######################################################################################################################
#
-# OpenZAP Module for TDM Interaction
+# OpenZAP Module for TDM Interaction
#
-###############################################################################################################################
-%files openzap
+######################################################################################################################
+%files freetdm
%defattr(-, freeswitch, daemon)
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/tones.conf
-%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/openzap.conf.xml
+%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/freetdm.conf.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/pika.conf
-%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/openzap.conf
+%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/freetdm.conf
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/wanpipe.conf
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/zt.conf
-%{prefix}/lib/libopenzap.so*
-%{prefix}/mod/mod_openzap.so*
-%{prefix}/mod/ozmod_*.so*
+%{prefix}/lib/libfreetdm.so*
+%{prefix}/mod/mod_freetdm.so*
+%{prefix}/mod/ftm*.so*
-###############################################################################################################################
+######################################################################################################################
#
-# Passthru Codec Modules
+# Passthru Codec Modules
#
-###############################################################################################################################
+######################################################################################################################
%files codec-passthru-amrwb
%defattr(-,freeswitch,daemon)
%{prefix}/mod/mod_amrwb.so*
@@ -838,12 +860,11 @@ fi
%defattr(-,freeswitch,daemon)
%{prefix}/mod/mod_g729.so*
-
-###############################################################################################################################
+######################################################################################################################
#
-# Embedded Language Modules
+# Embedded Language Modules
#
-###############################################################################################################################
+######################################################################################################################
%files spidermonkey
%defattr(-,freeswitch,daemon)
%{prefix}/mod/mod_spidermonkey*.so*
@@ -874,11 +895,11 @@ fi
%dir %attr(0750, freeswitch, daemon) %{prefix}/conf/autoload_configs
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/python.conf.xml
-###############################################################################################################################
+######################################################################################################################
#
-# Language Modules
+# Language Modules
#
-###############################################################################################################################
+######################################################################################################################
%files lang-en
%defattr(-, freeswitch, daemon)
%dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang/en
@@ -922,12 +943,24 @@ fi
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/ru/dir/*.xml
%{prefix}/mod/mod_say_ru.so*
-###############################################################################################################################
+######################################################################################################################
#
-# Changelog
+# Changelog
#
-###############################################################################################################################
+######################################################################################################################
%changelog
+* Sat Oct 09 2010 - michal.bielicki@seventhsignal.de
+- added mod_silk
+- added mod_codec2
+- moved from openzap to freetdm to make way for inclusion of libsng_isdn and wanpipe
+- added mod_freetdm
+- added mod_cidlookup
+- added more runtime dependencies
+* Thu Sep 30 2010 - michal.bielicki@seventhsignal.de
+- added mod_nibblebill to standard modules
+* Sun Sep 26 2010 - michal.bielicki@seventhsignal.de
+- added portaudio_stream module
+- some more formating work
* Mon Jul 19 2010 - michal.bielicki@seventhsignal.de
- new hash module config file added to freeswitch.spec
* Mon Jul 19 2010 - michal.bielicki@seventhsignal.de
diff --git a/libs/apr/.update b/libs/apr/.update
index 097f707e64..d5bc43d9d4 100644
--- a/libs/apr/.update
+++ b/libs/apr/.update
@@ -1 +1 @@
-Thu Nov 19 09:24:37 EST 2009
+Mon Sep 27 13:15:54 CDT 2010
diff --git a/libs/apr/strings/apr_snprintf.c b/libs/apr/strings/apr_snprintf.c
index fe8b382d14..4f59f92c76 100644
--- a/libs/apr/strings/apr_snprintf.c
+++ b/libs/apr/strings/apr_snprintf.c
@@ -824,7 +824,13 @@ APR_DECLARE(int) apr_vformatter(int (*flush_func)(apr_vformatter_buff_t *),
* Modifier check. Note that if APR_INT64_T_FMT is "d",
* the first if condition is never true.
*/
- if ((sizeof(APR_INT64_T_FMT) == 4 &&
+
+ /* HACK BY FREESWITCH TEAM TO FIX COMPATIBILITY 2010-09-27 */
+ if (*fmt == 'l' && *(fmt + 1) == 'l') {
+ var_type = IS_QUAD;
+ fmt += 2;
+ }
+ else if ((sizeof(APR_INT64_T_FMT) == 4 &&
fmt[0] == APR_INT64_T_FMT[0] &&
fmt[1] == APR_INT64_T_FMT[1]) ||
(sizeof(APR_INT64_T_FMT) == 3 &&
@@ -843,6 +849,11 @@ APR_DECLARE(int) apr_vformatter(int (*flush_func)(apr_vformatter_buff_t *),
else if (*fmt == 'l') {
var_type = IS_LONG;
fmt++;
+ /* HACK BY FREESWITCH TEAM TO FIX COMPATIBILITY 2010-09-27 */
+ if (*fmt == 'l') {
+ var_type = IS_QUAD;
+ fmt++;
+ }
}
else if (*fmt == 'h') {
var_type = IS_SHORT;
diff --git a/libs/broadvoice/configure.ac b/libs/broadvoice/configure.ac
index d42ee823eb..ceb92a57cb 100644
--- a/libs/broadvoice/configure.ac
+++ b/libs/broadvoice/configure.ac
@@ -207,7 +207,7 @@ AC_CHECK_HEADERS([sndfile.h])
AC_LANG([C])
-if test "${build}" == "${host}"
+if test "${build}" = "${host}"
then
case "${host}" in
x86_64-*)
diff --git a/libs/esl/src/esl.c b/libs/esl/src/esl.c
index 160fe2d759..4a02a8fe38 100644
--- a/libs/esl/src/esl.c
+++ b/libs/esl/src/esl.c
@@ -36,7 +36,10 @@
#define closesocket(x) close(x)
#include
#else
+#pragma warning (disable:6386)
+/* These warnings need to be ignored warning in sdk header */
#include
+#pragma warning (default:6386)
#endif
@@ -762,6 +765,7 @@ ESL_DECLARE(esl_status_t) esl_connect_timeout(esl_handle_t *handle, const char *
fail:
handle->connected = 0;
+ esl_disconnect(handle);
return ESL_FAIL;
}
diff --git a/libs/esl/src/esl_config.c b/libs/esl/src/esl_config.c
index 4616356f7f..2e24007799 100644
--- a/libs/esl/src/esl_config.c
+++ b/libs/esl/src/esl_config.c
@@ -110,7 +110,7 @@ ESL_DECLARE(int) esl_config_next_pair(esl_config_t *cfg, char **var, char **val)
*var = *val = NULL;
- if (!cfg->path) {
+ if (!cfg || !cfg->file) {
return 0;
}
diff --git a/libs/esl/src/esl_event.c b/libs/esl/src/esl_event.c
index 2e1d8a302a..db7c581ee9 100644
--- a/libs/esl/src/esl_event.c
+++ b/libs/esl/src/esl_event.c
@@ -513,6 +513,9 @@ ESL_DECLARE(esl_status_t) esl_event_serialize(esl_event_t *event, char **str, es
char *encode_buf = NULL; /* used for url encoding of variables to make sure unsafe things stay out of the serialized copy */
int clen = 0;
+ if (!event || !event->headers)
+ return ESL_FAIL;
+
*str = NULL;
dlen = blocksize * 2;
diff --git a/libs/freetdm/CMakeLists.txt b/libs/freetdm/CMakeLists.txt
new file mode 100644
index 0000000000..24cbf7c9eb
--- /dev/null
+++ b/libs/freetdm/CMakeLists.txt
@@ -0,0 +1,244 @@
+#
+# cmake file that generate build files for freetdm.
+# this automatically includes the tests and also
+# mod_freetdm
+#
+# Arnaldo M Pereira
+#
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(freetdm)
+
+ADD_SUBDIRECTORY(sample)
+ADD_SUBDIRECTORY(mod_freetdm)
+
+# includes
+SET(freetdm_INCLUDES
+ ${PROJECT_SOURCE_DIR}/src/include
+ ${PROJECT_SOURCE_DIR}/src/isdn/include
+ ${PROJECT_SOURCE_DIR}/src/include/private
+ ${PROJECT_SOURCE_DIR}/src/ftmod/ftmod_sangoma_boost
+)
+INCLUDE_DIRECTORIES(${freetdm_INCLUDES})
+LINK_DIRECTORIES(${freetdm_BINARY_DIR})
+
+# optional includes
+IF(DEFINED SNGSS7)
+ SET(freetdm_INCLUDES ${freetdm_INCLUDES} /usr/include/sng_ss7)
+ENDIF(DEFINED SNGSS7)
+
+IF(DEFINED SNGISDN)
+ SET(freetdm_INCLUDES ${freetdm_INCLUDES} /usr/include/sng_isdn)
+ENDIF(DEFINED SNGISDN)
+
+# definitions / CFLAGS
+ADD_DEFINITIONS(-DFTDM_CONFIG_DIR="/FIXME" -DFTDM_MOD_DIR="/FIXME")
+IF(DEFINED WIN32)
+ ADD_DEFINITIONS(-DFREETDM_EXPORTS -DTELETONE_EXPORTS -DMOD_EXPORTS -DDLL_EXPORTS)
+ENDIF(DEFINED WIN32)
+IF(DEFINED SNGISDN)
+ SET(freetdm_INCLUDES ${freetdm_INCLUDES} /usr/include/sng_isdn)
+ENDIF(DEFINED SNGISDN)
+
+# lib sources
+SET(freetdm_SOURCES
+ ${PROJECT_SOURCE_DIR}/src/hashtable.c
+ ${PROJECT_SOURCE_DIR}/src/hashtable_itr.c
+ ${PROJECT_SOURCE_DIR}/src/ftdm_io.c
+ ${PROJECT_SOURCE_DIR}/src/ftdm_queue.c
+ ${PROJECT_SOURCE_DIR}/src/ftdm_sched.c
+ ${PROJECT_SOURCE_DIR}/src/ftdm_call_utils.c
+ ${PROJECT_SOURCE_DIR}/src/ftdm_config.c
+ ${PROJECT_SOURCE_DIR}/src/ftdm_callerid.c
+ ${PROJECT_SOURCE_DIR}/src/fsk.c
+ ${PROJECT_SOURCE_DIR}/src/uart.c
+ ${PROJECT_SOURCE_DIR}/src/g711.c
+ ${PROJECT_SOURCE_DIR}/src/libteletone_detect.c
+ ${PROJECT_SOURCE_DIR}/src/libteletone_generate.c
+ ${PROJECT_SOURCE_DIR}/src/ftdm_buffer.c
+ ${PROJECT_SOURCE_DIR}/src/ftdm_threadmutex.c
+ ${PROJECT_SOURCE_DIR}/src/ftdm_dso.c
+ ${PROJECT_SOURCE_DIR}/src/ftdm_cpu_monitor.c
+)
+
+# libfreetdm.so
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${freetdm_SOURCES})
+
+IF(NOT DEFINED WIN32)
+ TARGET_LINK_LIBRARIES(${PROJECT_NAME} m pthread dl)
+ENDIF(NOT DEFINED WIN32)
+
+REMOVE_DEFINITIONS(-DLL_EXPORTS)
+
+# tools & tests
+IF(NOT DEFINED WIN32)
+ FOREACH(TOOL testtones testpri testr2 testapp testcid)
+ ADD_EXECUTABLE(${TOOL} ${PROJECT_SOURCE_DIR}/src/${TOOL}.c)
+ TARGET_LINK_LIBRARIES(${TOOL} -l${PROJECT_NAME})
+ ADD_DEPENDENCIES(${TOOL} ${PROJECT_NAME})
+ ENDFOREACH(TOOL)
+
+ ADD_EXECUTABLE(detect_dtmf
+ ${PROJECT_SOURCE_DIR}/src/detect_dtmf.c
+ ${PROJECT_SOURCE_DIR}/src/libteletone_detect.c
+ )
+ TARGET_LINK_LIBRARIES(detect_dtmf ${PROJECT_NAME})
+ ADD_DEPENDENCIES(detect_dtmf ${PROJECT_NAME})
+
+ ADD_EXECUTABLE(detect_tones
+ ${PROJECT_SOURCE_DIR}/src/detect_tones.c
+ ${PROJECT_SOURCE_DIR}/src/libteletone_detect.c
+ )
+ TARGET_LINK_LIBRARIES(detect_tones ${PROJECT_NAME})
+ ADD_DEPENDENCIES(detect_tones ${PROJECT_NAME})
+
+ ADD_EXECUTABLE(testanalog
+ ${PROJECT_SOURCE_DIR}/src/testanalog.c
+ )
+ TARGET_LINK_LIBRARIES(testanalog -l${PROJECT_NAME})
+ ADD_DEPENDENCIES(testanalog ${PROJECT_NAME})
+
+ # optional tests/tools
+ IF(HAVE_SCTP)
+ ADD_EXECUTABLE(testboost src/testboost.c)
+ TARGET_LINK_LIBRARIES(testboost ${PROJECT_NAME})
+ ENDIF(HAVE_SCTP)
+ELSE(NOT DEFINED WIN32)
+ MESSAGE(WARNING "Not building tools/tests on WIN32 yet.")
+ENDIF(NOT DEFINED WIN32)
+
+#
+# ftmod modules
+#
+SET(ftmod_DIR ${PROJECT_SOURCE_DIR}/src/ftmod)
+
+IF(DEFINED WIN32)
+ SET(ftmod_ADDITIONAL_SOURCES
+ ${PROJECT_SOURCE_DIR}/src/ftdm_io.c
+ ${PROJECT_SOURCE_DIR}/src/ftdm_config.c
+ ${PROJECT_SOURCE_DIR}/src/ftdm_queue.c
+ ${PROJECT_SOURCE_DIR}/src/g711.c
+ )
+ SET(module_list skel analog analog_em)
+ELSE(DEFINED WIN32)
+ SET(module_list skel analog analog_em zt)
+ENDIF(DEFINED WIN32)
+
+# build default modules
+FOREACH(module ${module_list})
+ ADD_LIBRARY(ftmod_${module} MODULE ${ftmod_DIR}/ftmod_${module}/ftmod_${module}.c ${ftmod_ADDITIONAL_SOURCES})
+ TARGET_LINK_LIBRARIES(ftmod_${module} ${PROJECT_NAME})
+ENDFOREACH(module)
+
+# build isdn ftmod
+IF(DEFINED BUILD_FTMOD_ISDN)
+ SET(ftmod_isdn_SOURCES
+ ${PROJECT_SOURCE_DIR}/src/isdn/EuroISDNStateNT.c
+ ${PROJECT_SOURCE_DIR}/src/isdn/EuroISDNStateTE.c
+ ${PROJECT_SOURCE_DIR}/src/isdn/mfifo.c
+ ${PROJECT_SOURCE_DIR}/src/isdn/Q921.c
+ ${PROJECT_SOURCE_DIR}/src/isdn/Q931api.c
+ ${PROJECT_SOURCE_DIR}/src/isdn/Q931.c
+ ${PROJECT_SOURCE_DIR}/src/isdn/Q931ie.c
+ ${PROJECT_SOURCE_DIR}/src/isdn/Q931mes.c
+ ${PROJECT_SOURCE_DIR}/src/isdn/Q931StateNT.c
+ ${PROJECT_SOURCE_DIR}/src/isdn/Q931StateTE.c
+ ${PROJECT_SOURCE_DIR}/src/isdn/nationalmes.c
+ ${PROJECT_SOURCE_DIR}/src/isdn/nationalStateNT.c
+ ${PROJECT_SOURCE_DIR}/src/isdn/nationalStateTE.c
+ ${PROJECT_SOURCE_DIR}/src/isdn/DMSmes.c
+ ${PROJECT_SOURCE_DIR}/src/isdn/DMSStateNT.c
+ ${PROJECT_SOURCE_DIR}/src/isdn/DMSStateTE.c
+ ${PROJECT_SOURCE_DIR}/src/isdn/5ESSmes.c
+ ${PROJECT_SOURCE_DIR}/src/isdn/5ESSStateNT.c
+ ${PROJECT_SOURCE_DIR}/src/isdn/5ESSStateTE.c
+ ${PROJECT_SOURCE_DIR}/src/isdn/Q932mes.c
+ ${ftmod_DIR}/ftmod_isdn/ftmod_isdn.c
+ )
+ IF(NOT DEFINED WIN32)
+ ADD_DEFINITIONS(-D_GNU_SOURCE)
+ ENDIF(NOT DEFINED WIN32)
+ ADD_LIBRARY(ftmod_isdn MODULE ${ftmod_isdn_SOURCES})
+ TARGET_LINK_LIBRARIES(ftmod_isdn ${PROJECT_NAME})
+ENDIF(DEFINED BUILD_FTMOD_ISDN)
+
+# from now on, optionals
+IF(DEFINED LIBSANGOMA)
+ ADD_LIBRARY(ftmod_wanpipe MODULE ${ftmod_DIR}/ftmod_wanpipe/ftmod_wanpipe.c)
+ IF(DEFINED WIN32)
+ MESSAGE(WARNING "FIXME: look for wanpipe headers on win32")
+ ELSE(DEFINED WIN32)
+ ADD_DEFINITIONS(-D__LINUX__)
+ INCLUDE_DIRECTORIES(/usr/include/wanpipe)
+ ENDIF(DEFINED WIN32)
+ TARGET_LINK_LIBRARIES(ftmod_wanpipe sangoma ${PROJECT_NAME})
+ENDIF(DEFINED LIBSANGOMA)
+
+IF(DEFINED HAVE_SCTP)
+ ADD_LIBRARY(ftmod_sangoma_boost MODULE
+ ${ftmod_DIR}/ftmod_sangoma_boost/sangoma_boost_client.c
+ ${ftmod_DIR}/ftmod_sangoma_boost/ftmod_sangoma_boost.c
+ )
+ TARGET_LINK_LIBRARIES(ftmod_sangoma_boost ${PROJECT_NAME})
+ENDIF(DEFINED HAVE_SCTP)
+
+IF(DEFINED LIBPRI)
+ ADD_LIBRARY(ftmod_libpri MODULE
+ ${ftmod_DIR}/ftmod_libpri/libpri_client.c
+ ${ftmod_DIR}/ftmod_libpri/ftmod_libpri.c
+ )
+ TARGET_LINK_LIBRARIES(ftmod_libpri ${PROJECT_NAME})
+ENDIF(DEFINED LIBPRI)
+
+IF(DEFINED PRITAP)
+ ADD_LIBRARY(ftmod_pritap MODULE
+ ${ftmod_DIR}/ftmod_pritap/pritap_client.c
+ ${ftmod_DIR}/ftmod_pritap/ftmod_pritap.c
+ )
+ TARGET_LINK_LIBRARIES(ftmod_pritap ${PROJECT_NAME} pri)
+ENDIF(DEFINED PRITAP)
+
+IF(DEFINED SNGSS7)
+ ADD_LIBRARY(ftmod_sangoma_ss7 MODULE
+ ${ftmod_DIR}/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c
+ ${ftmod_DIR}/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c
+ ${ftmod_DIR}/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c
+ ${ftmod_DIR}/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c
+ ${ftmod_DIR}/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c
+ ${ftmod_DIR}/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c
+ ${ftmod_DIR}/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c
+ ${ftmod_DIR}/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c
+ ${ftmod_DIR}/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c
+ ${ftmod_DIR}/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c
+ ${ftmod_DIR}/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c
+ ${ftmod_DIR}/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sts.c
+ ${ftmod_DIR}/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c
+ )
+ IF(NOT DEFINED WIN32)
+ ADD_DEFINITIONS(-D_GNU_SOURCE)
+ ENDIF(NOT DEFINED WIN32)
+ TARGET_LINK_LIBRARIES(ftmod_sangoma_ss7 ${PROJECT_NAME} sng_ss7)
+ENDIF(DEFINED SNGSS7)
+
+IF(DEFINED SNGISDN)
+ ADD_LIBRARY(ftmod_sangoma_isdn MODULE
+ ${ftmod_DIR}/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c
+ ${ftmod_DIR}/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c
+ ${ftmod_DIR}/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cntrl.c
+ ${ftmod_DIR}/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c
+ ${ftmod_DIR}/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c
+ ${ftmod_DIR}/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c
+ ${ftmod_DIR}/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c
+ ${ftmod_DIR}/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c
+ ${ftmod_DIR}/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c
+ ${ftmod_DIR}/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c
+ )
+ IF(NOT DEFINED WIN32)
+ ADD_DEFINITIONS(-D_GNU_SOURCE)
+ ENDIF(NOT DEFINED WIN32)
+ TARGET_LINK_LIBRARIES(ftmod_sangoma_isdn ${PROJECT_NAME} sng_isdn)
+ENDIF(DEFINED SNGISDN)
+
+IF(DEFINED OPENR2)
+ ADD_LIBRARY(ftmod_r2 MODULE ${ftmod_DIR}/ftmod_r2/ftmod_r2.c)
+ TARGET_LINK_LIBRARIES(ftmod_r2 ${PROJECT_NAME} openr2)
+ENDIF(DEFINED OPENR2)
diff --git a/libs/freetdm/Makefile.am b/libs/freetdm/Makefile.am
index 33a8b96936..d14013ab9b 100644
--- a/libs/freetdm/Makefile.am
+++ b/libs/freetdm/Makefile.am
@@ -312,7 +312,7 @@ ftmod_r2_la_LIBADD = $(MYLIB)
endif
dox doxygen:
- cd docs && doxygen $(FT_SRCDIR)/docs/Doxygen.conf
+ doxygen $(FT_SRCDIR)/docs/Doxygen.conf
mod_freetdm/mod_freetdm.$(DYNAMIC_LIB_EXTEN): $(MYLIB) mod_freetdm/mod_freetdm.c
cd mod_freetdm && make
diff --git a/libs/freetdm/README b/libs/freetdm/README
index 2c2119f55b..4ca13d19c9 100644
--- a/libs/freetdm/README
+++ b/libs/freetdm/README
@@ -1,3 +1,3 @@
-FREETDM (WORK IN PROGRESS)
+FreeTDM
+http://wiki.freeswitch.org/wiki/FreeTDM
-*shrug*
diff --git a/libs/freetdm/conf/freetdm.conf b/libs/freetdm/conf/freetdm.conf
index 1ea1a9f62a..bbaf1e3687 100644
--- a/libs/freetdm/conf/freetdm.conf
+++ b/libs/freetdm/conf/freetdm.conf
@@ -1,19 +1,47 @@
-[span wanpipe]
-name => FreeTDM
-number => 1
+; !! THIS IS A SAMPLE CONFIGURATION ONLY !!
+
+; refer to http://wiki.freeswitch.org/wiki/FreeTDM for further documentation
+
+[general]
+; whether to launch a thread for CPU usage monitoring
+cpu_monitor => no
+
+; How often (in milliseconds) monitor CPU usage
+cpu_monitoring_interval => 1000
+
+; At what CPU percentage raise a CPU alarm
+cpu_set_alarm_threshold => 80
+
+; At what CPU percentage stop the CPU alarm
+cpu_reset_alarm_threshold => 70
+
+; Which action to take when the CPU alarm is raised
+; it can be warn and/or reject calls
+; cpu_alarm_action => warn,reject
+cpu_alarm_action => warn
+
+; spans are defined with [span ]
+; the span type can either be zt, wanpipe or pika
+; the span name can be any unique string
+[span wanpipe myWanpipe]
+
+; valid trunk types are: FXO, FXS, EM, E1, T1, J1, BRI, BRI_PTMP
+trunk_type => FXS
+
+; add FXS channels from 3 to 4 at wanpipe span 1 to this freetdm span
fxs-channel => 1:3-4
-[span wanpipe]
+[span wanpipe myWanpipe2]
+trunk_type => FXO
+; This number will be used as DNIS for FXO devices
fxo-channel => 1:1-2
-[span zt]
-name => FreeTDM
-number => 2
+[span zt myZaptelSpan]
+number => 9999
fxs-channel => 1
-[span zt]
-name => FreeTDM
+[span zt mySecondZaptelSpan]
+; This number will be used as DNIS for FXO devices
number => 2
fxo-channel => 3
-
diff --git a/libs/freetdm/conf/freetdm.conf.xml b/libs/freetdm/conf/freetdm.conf.xml
index 69bf99a0a0..986074dffb 100644
--- a/libs/freetdm/conf/freetdm.conf.xml
+++ b/libs/freetdm/conf/freetdm.conf.xml
@@ -1,3 +1,5 @@
+
+
@@ -5,6 +7,8 @@
+
+
@@ -24,9 +28,11 @@
-
+
+
+
-
+
@@ -42,4 +48,5 @@
+
diff --git a/libs/freetdm/conf/pika.conf b/libs/freetdm/conf/pika.conf
index 8cc8d9c11d..78e095205e 100644
--- a/libs/freetdm/conf/pika.conf
+++ b/libs/freetdm/conf/pika.conf
@@ -1,3 +1,5 @@
+; you dont need this file unless you use PIKA boards
+
; each category is a config profile
; to apply the profile append it to a channel def in
; openzap.conf with @
diff --git a/libs/freetdm/conf/tones.conf b/libs/freetdm/conf/tones.conf
index 36db1d4d91..155b5fe17e 100644
--- a/libs/freetdm/conf/tones.conf
+++ b/libs/freetdm/conf/tones.conf
@@ -1,3 +1,5 @@
+; This file is used to generate telephony tones by FreeTDM
+
[us]
generate-dial => v=-7;%(1000,0,350,440)
detect-dial => 350,440
diff --git a/libs/freetdm/configure.ac b/libs/freetdm/configure.ac
index a8ed67f228..18f83d8f1d 100644
--- a/libs/freetdm/configure.ac
+++ b/libs/freetdm/configure.ac
@@ -205,6 +205,18 @@ if test "${have_sng_isdn}" = "yes"; then
fi
fi
+if test "${have_sng_ss7}" = "yes"; then
+ if test "${build}" == "${host}"
+ then
+ case "${host}" in
+ x86_64-*)
+ # X86_64 machines need additional flags when compiling against libsng_isdn
+ CFLAGS="$CFLAGS -DBIT_64 -DALIGN_64BIT"
+ ;;
+ esac
+ fi
+fi
+
COMP_VENDOR_CFLAGS="$COMP_VENDOR_CFLAGS"
AC_SUBST(COMP_VENDOR_CFLAGS)
AC_CONFIG_FILES([Makefile
diff --git a/libs/freetdm/freetdm.2008.sln b/libs/freetdm/freetdm.2008.sln
index 66ea2920a2..61f631f5c0 100644
--- a/libs/freetdm/freetdm.2008.sln
+++ b/libs/freetdm/freetdm.2008.sln
@@ -58,6 +58,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testsangomaboost", "msvc\te
{93B8812C-3EC4-4F78-8970-FFBFC99E167D} = {93B8812C-3EC4-4F78-8970-FFBFC99E167D}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftmod_sangoma_isdn", "src\ftmod\ftmod_sangoma_isdn\ftmod_sangoma_isdn.2008.vcproj", "{B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}"
+ ProjectSection(ProjectDependencies) = postProject
+ {93B8812C-3EC4-4F78-8970-FFBFC99E167D} = {93B8812C-3EC4-4F78-8970-FFBFC99E167D}
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -119,6 +124,7 @@ Global
{E886B4D5-AB4F-4092-B8F4-3B06E1E462EF}.Release|Win32.ActiveCfg = Release|Win32
{E886B4D5-AB4F-4092-B8F4-3B06E1E462EF}.Release|x64.ActiveCfg = Release|x64
{1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Debug|Win32.ActiveCfg = Debug|Win32
+ {1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Debug|Win32.Build.0 = Debug|Win32
{1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Debug|x64.ActiveCfg = Debug|x64
{1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Release|Win32.ActiveCfg = Release|Win32
{1A145EE9-BBD8-45E5-98CD-EB4BE99E1DCD}.Release|x64.ActiveCfg = Release|x64
@@ -146,6 +152,12 @@ Global
{0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|Win32.Build.0 = Release|Win32
{0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|x64.ActiveCfg = Release|x64
{0DA69C18-4FA1-4E8C-89CE-12498637C5BE}.Release|x64.Build.0 = Release|x64
+ {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|Win32.Build.0 = Debug|Win32
+ {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Debug|x64.ActiveCfg = Debug|Win32
+ {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|Win32.ActiveCfg = Release|Win32
+ {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|Win32.Build.0 = Release|Win32
+ {B2AF4EA6-0CD7-4529-9EB5-5AF43DB90395}.Release|x64.ActiveCfg = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/libs/freetdm/mkrelease.sh b/libs/freetdm/mkrelease.sh
new file mode 100755
index 0000000000..58d176119d
--- /dev/null
+++ b/libs/freetdm/mkrelease.sh
@@ -0,0 +1,64 @@
+#!/bin/bash
+INSTALLPREFIX="/usr/local/freetdm"
+VERSION=""
+NODOCS="NO"
+
+for i in $*
+do
+ case $i in
+ --version=*)
+ VERSION=`echo $i | sed 's/[-a-zA-Z0-9]*=//'`
+ ;;
+ --prefix=*)
+ INSTALLPREFIX=`echo $i | sed 's/[-a-zA-Z0-9]*=//'`
+ ;;
+ --nodocs)
+ NODOCS="YES"
+ ;;
+ *)
+ # unknown option
+ echo "Unknown option $i"
+ exit
+ ;;
+ esac
+done
+
+if [ "x$VERSION" = "x" ]
+then
+ echo "Provide a version number with --version="
+ exit 1
+fi
+
+if [ ! -d $INSTALLPREFIX ]
+then
+ mkdir -p $INSTALLPREFIX || exit 1
+fi
+
+make clean
+make mod_freetdm-clean
+if [ $NODOCS = "NO" ]
+then
+ make dox || exit 1
+fi
+
+major=$(echo "$VERSION" | cut -d. -f1)
+minor=$(echo "$VERSION" | cut -d. -f2)
+micro=$(echo "$VERSION" | cut -d. -f3)
+release="freetdm-$VERSION"
+
+echo "Creating $release ($major.$minor.$micro) at $INSTALLPREFIX/$release (directory will be removed if exists already) ... press any key to continue"
+read
+
+mkdir -p $INSTALLPREFIX/$release
+
+cp -r ./* $INSTALLPREFIX/$release
+
+find $INSTALLPREFIX/ -name .libs -exec rm -rf {} \;
+find $INSTALLPREFIX/ -name .deps -exec rm -rf {} \;
+find $INSTALLPREFIX/ -name *.so -exec rm -rf {} \;
+find $INSTALLPREFIX/ -name *.lo -exec rm -rf {} \;
+
+
+tar -C $INSTALLPREFIX -czf $INSTALLPREFIX/$release.tar.gz $release/
+
+
diff --git a/libs/freetdm/mod_freetdm/CMakeLists.txt b/libs/freetdm/mod_freetdm/CMakeLists.txt
new file mode 100644
index 0000000000..25847e713f
--- /dev/null
+++ b/libs/freetdm/mod_freetdm/CMakeLists.txt
@@ -0,0 +1,32 @@
+#
+# Arnaldo M Pereira
+#
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(mod_freetdm)
+
+IF(NOT DEFINED WIN32)
+ ADD_DEFINITIONS(-g -O2 -ffast-math -Wall -Werror -Wunused-variable -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -O0 -g -ggdb -DPACKAGE_NAME=\"freetdm\" -DPACKAGE_TARNAME=\"freetdm\" -DPACKAGE_VERSION=\"pre-alpha\" -DPACKAGE_STRING=\"freetdm\ pre-alpha\" -DPACKAGE_BUGREPORT=\"bugs@freeswitch.org\" -DPACKAGE_URL=\"\" -DPACKAGE=\"libfreetdm\" -DVERSION=\"0.1\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" -DHAVE_LIBDL=1 -DHAVE_LIBPTHREAD=1 -DHAVE_LIBM=1 -DSIZEOF_LONG=8 -DHAVE_NETINET_SCTP_H=1 -DHAVE_NETDB_H=1 -DHAVE_SYS_SELECT_H=1 -DHAVE_GETHOSTBYNAME_R=1) # -DDEBUG=/\*\*/)
+ENDIF(NOT DEFINED WIN32)
+
+# includes
+SET(mod_freetdm_INCLUDES
+ ${PROJECT_SOURCE_DIR}/../src/include
+ ${PROJECT_SOURCE_DIR}/../src/isdn/include
+ ${PROJECT_SOURCE_DIR}/../../libteletone/src
+ ${PROJECT_SOURCE_DIR}/../../../src/include
+)
+INCLUDE_DIRECTORIES(${mod_freetdm_INCLUDES})
+
+LINK_DIRECTORIES(${PROJECT_SOURCE_DIR}/..)
+ADD_LIBRARY(${PROJECT_NAME} SHARED mod_freetdm.c)
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} freetdm -fPIC -Werror -fvisibility=hidden)
+
+IF(DEFINED WIN32)
+ SET(EXT lib)
+ELSE(DEFINED WIN32)
+ SET(EXT so)
+ENDIF(DEFINED WIN32)
+
+ADD_CUSTOM_COMMAND(TARGET ${PROJECT_NAME} POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E rename lib${PROJECT_NAME}.${EXT} ${PROJECT_NAME}.${EXT}
+)
diff --git a/libs/freetdm/sample/CMakeLists.txt b/libs/freetdm/sample/CMakeLists.txt
new file mode 100644
index 0000000000..330d590fd4
--- /dev/null
+++ b/libs/freetdm/sample/CMakeLists.txt
@@ -0,0 +1,8 @@
+#
+# Arnaldo M Pereira
+#
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(sample)
+
+ADD_SUBDIRECTORY(boost)
+#ADD_SUBDIRECTORY(sched) FIXME: this code doesnt compile
diff --git a/libs/freetdm/sample/boost/CMakeLists.txt b/libs/freetdm/sample/boost/CMakeLists.txt
new file mode 100644
index 0000000000..6f36f106a5
--- /dev/null
+++ b/libs/freetdm/sample/boost/CMakeLists.txt
@@ -0,0 +1,12 @@
+#
+# Arnaldo M Pereira
+#
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(boost)
+
+IF(NOT DEFINED WIN32)
+ INCLUDE_DIRECTORIES(/usr/local/freeswitch/include)
+ ADD_DEFINITIONS(-Wall)
+ ADD_EXECUTABLE(ftdmstart ftdmstart.c)
+ TARGET_LINK_LIBRARIES(ftdmstart freetdm)
+ENDIF(NOT DEFINED WIN32)
diff --git a/libs/freetdm/sample/boost/ftdmstart.c b/libs/freetdm/sample/boost/ftdmstart.c
index 972ed43146..bff0664bce 100644
--- a/libs/freetdm/sample/boost/ftdmstart.c
+++ b/libs/freetdm/sample/boost/ftdmstart.c
@@ -313,13 +313,6 @@ int main(int argc, char *argv[])
/* set the logging level to use */
ftdm_global_set_default_logger(FTDM_LOG_LEVEL_DEBUG);
- /* this is optional.
- * cpu monitor is a default feature in freetdm that launches 1 thread
- * to monitor system-wide CPU usage. If it goes above a predefined threshold
- * it will stop accepting calls to try to protect the quality of current calls */
- ftdm_cpu_monitor_disable();
-
-
/* Initialize the FTDM library */
if (ftdm_global_init() != FTDM_SUCCESS) {
fprintf(stderr, "Error loading FreeTDM\n");
diff --git a/libs/freetdm/sample/dso/CMakeLists.txt b/libs/freetdm/sample/dso/CMakeLists.txt
new file mode 100644
index 0000000000..defcc5c7f5
--- /dev/null
+++ b/libs/freetdm/sample/dso/CMakeLists.txt
@@ -0,0 +1,12 @@
+#
+# Arnaldo M Pereira
+#
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(dso)
+
+IF(NOT DEFINED WIN32)
+ INCLUDE_DIRECTORIES(/usr/local/freeswitch/include)
+ ADD_DEFINITIONS(-Wall)
+ ADD_EXECUTABLE(ftdmload ftdmload.c)
+ TARGET_LINK_LIBRARIES(ftdmload freetdm)
+ENDIF(NOT DEFINED WIN32)
diff --git a/libs/freetdm/sample/dso/ftdmload.c b/libs/freetdm/sample/dso/ftdmload.c
index 5b150d67ed..80bcc02fc0 100644
--- a/libs/freetdm/sample/dso/ftdmload.c
+++ b/libs/freetdm/sample/dso/ftdmload.c
@@ -134,8 +134,6 @@ int main(int argc, char *argv[])
ftdm_global_set_default_logger(FTDM_LOG_LEVEL_DEBUG);
- ftdm_cpu_monitor_disable();
-
if (ftdm_global_init() != FTDM_SUCCESS) {
fprintf(stderr, "Error loading FreeTDM\n");
exit(-1);
diff --git a/libs/freetdm/sample/sched/CMakeLists.txt b/libs/freetdm/sample/sched/CMakeLists.txt
new file mode 100644
index 0000000000..d769925be0
--- /dev/null
+++ b/libs/freetdm/sample/sched/CMakeLists.txt
@@ -0,0 +1,12 @@
+#
+# Arnaldo M Pereira
+#
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(sched)
+
+IF(NOT DEFINED WIN32)
+ INCLUDE_DIRECTORIES(/usr/local/freeswitch/include)
+ ADD_DEFINITIONS(-Wall)
+ ADD_EXECUTABLE(ftdmsched ftdmsched.c)
+ TARGET_LINK_LIBRARIES(ftdmsched freetdm)
+ENDIF(NOT DEFINED WIN32)
diff --git a/libs/freetdm/sample/sched/ftdmsched.c b/libs/freetdm/sample/sched/ftdmsched.c
index 5cd7d6340a..e6e391ee4b 100644
--- a/libs/freetdm/sample/sched/ftdmsched.c
+++ b/libs/freetdm/sample/sched/ftdmsched.c
@@ -73,8 +73,6 @@ int main(int argc, char *argv[])
ftdm_global_set_default_logger(FTDM_LOG_LEVEL_DEBUG);
- ftdm_cpu_monitor_disable();
-
if (ftdm_global_init() != FTDM_SUCCESS) {
fprintf(stderr, "Error loading FreeTDM\n");
exit(-1);
diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c
index 2ffa26848e..f02c9c48db 100644
--- a/libs/freetdm/src/ftdm_io.c
+++ b/libs/freetdm/src/ftdm_io.c
@@ -244,6 +244,39 @@ static __inline__ void ftdm_std_free(void *pool, void *ptr)
free(ptr);
}
+static void ftdm_set_echocancel_call_begin(ftdm_channel_t *chan)
+{
+ ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan);
+ if (ftdm_channel_test_feature(chan, FTDM_CHANNEL_FEATURE_HWEC)) {
+ if (ftdm_channel_test_feature(chan, FTDM_CHANNEL_FEATURE_HWEC_DISABLED_ON_IDLE)) {
+ if (caller_data->bearer_capability != FTDM_BEARER_CAP_64K_UNRESTRICTED) {
+ ftdm_channel_command(chan, FTDM_COMMAND_ENABLE_ECHOCANCEL, NULL);
+ }
+ } else {
+ if (caller_data->bearer_capability == FTDM_BEARER_CAP_64K_UNRESTRICTED) {
+ ftdm_channel_command(chan, FTDM_COMMAND_DISABLE_ECHOCANCEL, NULL);
+ }
+ }
+ }
+}
+
+static void ftdm_set_echocancel_call_end(ftdm_channel_t *chan)
+{
+ ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(chan);
+ if (ftdm_channel_test_feature(chan, FTDM_CHANNEL_FEATURE_HWEC)) {
+ if (ftdm_channel_test_feature(chan, FTDM_CHANNEL_FEATURE_HWEC_DISABLED_ON_IDLE)) {
+ if (caller_data->bearer_capability != FTDM_BEARER_CAP_64K_UNRESTRICTED) {
+ ftdm_channel_command(chan, FTDM_COMMAND_DISABLE_ECHOCANCEL, NULL);
+ }
+ } else {
+ if (caller_data->bearer_capability == FTDM_BEARER_CAP_64K_UNRESTRICTED) {
+ ftdm_channel_command(chan, FTDM_COMMAND_ENABLE_ECHOCANCEL, NULL);
+ }
+ }
+ }
+}
+
+
FT_DECLARE_DATA ftdm_memory_handler_t g_ftdm_mem_handler =
{
/*.pool =*/ NULL,
@@ -1251,6 +1284,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_set_state(const char *file, const char *f
case FTDM_CHANNEL_STATE_RING:
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
case FTDM_CHANNEL_STATE_PROGRESS:
+ case FTDM_CHANNEL_STATE_IDLE:
case FTDM_CHANNEL_STATE_GET_CALLERID:
case FTDM_CHANNEL_STATE_GENRING:
ok = 1;
@@ -1759,7 +1793,6 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open(uint32_t span_id, uint32_t chan_id,
ftdm_channel_t *best_rated = NULL;
ftdm_status_t status = FTDM_FAIL;
int best_rate = 0;
- int may_be_available = 0;
*ftdmchan = NULL;
@@ -1794,38 +1827,55 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open(uint32_t span_id, uint32_t chan_id,
ftdm_mutex_lock(check->mutex);
+ /* The following if's and gotos replace a big if (this || this || this || this) else { nothing; } */
+
+ /* if it is not a voice channel, nothing else to check to open it */
+ if (!FTDM_IS_VOICE_CHANNEL(check)) {
+ goto openchan;
+ }
+
+ /* if it's an FXS device with a call active and has callwaiting enabled, we allow to open it twice */
+ if (check->type == FTDM_CHAN_TYPE_FXS
+ && check->token_count == 1
+ && ftdm_channel_test_feature(check, FTDM_CHANNEL_FEATURE_CALLWAITING)) {
+ goto openchan;
+ }
+
+ /* if channel is available, time to open it */
+ if (chan_is_avail(check)) {
+ goto openchan;
+ }
+
+ /* not available, but still might be available ... */
calculate_best_rate(check, &best_rated, &best_rate);
if (best_rated) {
- may_be_available = 1;
+ goto openchan;
}
- /* the channel is only allowed to be open if not in use, or, for FXS devices with a call with call waiting enabled */
- if (
- (check->type == FTDM_CHAN_TYPE_FXS
- && check->token_count == 1
- && ftdm_channel_test_feature(check, FTDM_CHANNEL_FEATURE_CALLWAITING))
- ||
- chan_is_avail(check)
- ||
- may_be_available) {
- if (!ftdm_test_flag(check, FTDM_CHANNEL_OPEN)) {
- status = check->fio->open(check);
- if (status == FTDM_SUCCESS) {
- ftdm_set_flag(check, FTDM_CHANNEL_OPEN);
- }
- } else {
- status = FTDM_SUCCESS;
+ /* channel is unavailable, do not open the channel */
+ goto unlockchan;
+
+openchan:
+ if (!ftdm_test_flag(check, FTDM_CHANNEL_OPEN)) {
+ status = check->fio->open(check);
+ if (status == FTDM_SUCCESS) {
+ ftdm_set_flag(check, FTDM_CHANNEL_OPEN);
}
- ftdm_set_flag(check, FTDM_CHANNEL_INUSE);
- ftdm_set_flag(check, FTDM_CHANNEL_OUTBOUND);
- *ftdmchan = check;
+ } else {
+ status = FTDM_SUCCESS;
}
+ ftdm_set_flag(check, FTDM_CHANNEL_INUSE);
+ ftdm_set_flag(check, FTDM_CHANNEL_OUTBOUND);
+ *ftdmchan = check;
+unlockchan:
ftdm_mutex_unlock(check->mutex);
done:
-
ftdm_mutex_unlock(globals.mutex);
+ if (status != FTDM_SUCCESS) {
+ ftdm_log(FTDM_LOG_ERROR, "Failed to open channel %d:%d\n", span_id, chan_id);
+ }
return status;
}
@@ -2008,6 +2058,9 @@ done:
static ftdm_status_t call_hangup(ftdm_channel_t *chan, const char *file, const char *func, int line)
{
ftdm_set_flag(chan, FTDM_CHANNEL_USER_HANGUP);
+
+ ftdm_set_echocancel_call_end(chan);
+
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 */
@@ -2173,10 +2226,12 @@ done:
FT_DECLARE(ftdm_status_t) _ftdm_channel_call_place(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan)
{
ftdm_status_t status = FTDM_FAIL;
-
+
ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "null channel");
ftdm_assert_return(ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND), FTDM_FAIL, "Call place, but outbound flag not set\n");
+ ftdm_set_echocancel_call_begin(ftdmchan);
+
ftdm_channel_lock(ftdmchan);
if (ftdmchan->span->outgoing_call) {
@@ -3688,6 +3743,102 @@ static struct {
ftdm_io_interface_t *pika_interface;
} interfaces;
+static void print_channels_by_state(ftdm_stream_handle_t *stream, ftdm_channel_state_t state, int not, int *count)
+{
+ ftdm_hash_iterator_t *i = NULL;
+ ftdm_span_t *span;
+ ftdm_channel_t *fchan = NULL;
+ ftdm_iterator_t *citer = NULL;
+ ftdm_iterator_t *curr = NULL;
+ const void *key = NULL;
+ void *val = NULL;
+
+ *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 (!citer) {
+ continue;
+ }
+ for (curr = citer ; curr; curr = ftdm_iterator_next(curr)) {
+ fchan = ftdm_iterator_current(curr);
+ if (not && (fchan->state != state)) {
+ stream->write_function(stream, "[s%dc%d][%d:%d] in state %s\n",
+ fchan->span_id, fchan->chan_id,
+ fchan->physical_span_id, fchan->physical_chan_id, ftdm_channel_state2str(fchan->state));
+ (*count)++;
+ } else if (!not && (fchan->state == state)) {
+ stream->write_function(stream, "[s%dc%d][%d:%d] in state %s\n",
+ fchan->span_id, fchan->chan_id,
+ fchan->physical_span_id, fchan->physical_chan_id, ftdm_channel_state2str(fchan->state));
+ (*count)++;
+ }
+ }
+ ftdm_iterator_free(citer);
+ }
+
+ ftdm_mutex_unlock(globals.mutex);
+}
+
+static char *handle_core_command(const char *cmd)
+{
+ char *mycmd = NULL;
+ int argc = 0;
+ int count = 0;
+ int not = 0;
+ char *argv[10] = { 0 };
+ char *state = NULL;
+ ftdm_channel_state_t i = FTDM_CHANNEL_STATE_INVALID;
+ ftdm_stream_handle_t stream = { 0 };
+
+ FTDM_STANDARD_STREAM(stream);
+
+ if (cmd) {
+ mycmd = ftdm_strdup(cmd);
+ argc = ftdm_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+ } else {
+ stream.write_function(&stream, "invalid core command\n");
+ goto done;
+ }
+
+ if (!strcasecmp(argv[0], "state")) {
+ if (argc < 2) {
+ stream.write_function(&stream, "core state command requires an argument\n");
+ goto done;
+ }
+ state = argv[1];
+ if (argv[1][0] == '!') {
+ not = 1;
+ state++;
+ }
+ for (i = FTDM_CHANNEL_STATE_DOWN; i < FTDM_CHANNEL_STATE_INVALID; i++) {
+ if (!strcasecmp(state, ftdm_channel_state2str(i))) {
+ break;
+ }
+ }
+ if (i == FTDM_CHANNEL_STATE_INVALID) {
+ stream.write_function(&stream, "invalid state %s\n", state);
+ goto done;
+ }
+ 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 {
+ stream.write_function(&stream, "invalid core command %s\n", argv[0]);
+ }
+
+done:
+ ftdm_safe_free(mycmd);
+
+ return stream.data;
+}
+
FT_DECLARE(char *) ftdm_api_execute(const char *cmd)
{
ftdm_io_interface_t *fio = NULL;
@@ -3702,6 +3853,10 @@ FT_DECLARE(char *) ftdm_api_execute(const char *cmd)
}
type = dup;
+
+ if (!strcasecmp(type, "core")) {
+ return handle_core_command(cmd);
+ }
ftdm_mutex_lock(globals.mutex);
if (!(fio = (ftdm_io_interface_t *) hashtable_search(globals.interface_hash, (void *)type))) {
@@ -4640,11 +4795,15 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
break;
case FTDM_SIGEVENT_START:
- /* when cleaning up the public API I added this because mod_freetdm.c on_fxs_signal was
- * doing it during SIGEVENT_START, but now that flags are private they can't, wonder if
- * is needed at all?
- * */
- ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_HOLD);
+ {
+ ftdm_set_echocancel_call_begin(sigmsg->channel);
+
+ /* when cleaning up the public API I added this because mod_freetdm.c on_fxs_signal was
+ * doing it during SIGEVENT_START, but now that flags are private they can't, wonder if
+ * is needed at all?
+ * */
+ ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_HOLD);
+ }
break;
case FTDM_SIGEVENT_STOP:
@@ -4832,16 +4991,19 @@ FT_DECLARE(uint32_t) ftdm_running(void)
FT_DECLARE(ftdm_status_t) ftdm_global_destroy(void)
{
ftdm_span_t *sp;
- uint32_t sanity = 100;
time_end();
+ /* many freetdm event loops rely on this variable to decide when to stop, do this first */
globals.running = 0;
- ftdm_sched_destroy(&globals.timingsched);
+ /* stop the scheduling thread */
+ ftdm_free_sched_stop();
+ /* stop the cpu monitor thread */
ftdm_cpu_monitor_stop();
+ /* now destroy channels and spans */
globals.span_index = 0;
ftdm_span_close_all();
@@ -4866,18 +5028,12 @@ FT_DECLARE(ftdm_status_t) ftdm_global_destroy(void)
globals.spans = NULL;
ftdm_mutex_unlock(globals.span_mutex);
+ /* destroy signaling and io modules */
ftdm_unload_modules();
- while (ftdm_free_sched_running() && --sanity) {
- ftdm_log(FTDM_LOG_DEBUG, "Waiting for schedule thread to finish\n");
- ftdm_sleep(100);
- }
-
- if (!sanity) {
- ftdm_log(FTDM_LOG_CRIT, "schedule thread did not stop running, we may crash on shutdown\n");
- }
-
+ /* finally destroy the globals */
ftdm_mutex_lock(globals.mutex);
+ ftdm_sched_destroy(&globals.timingsched);
hashtable_destroy(globals.interface_hash);
hashtable_destroy(globals.module_hash);
hashtable_destroy(globals.span_hash);
@@ -5208,38 +5364,21 @@ FT_DECLARE(char *) ftdm_strndup(const char *str, ftdm_size_t inlen)
return new;
}
-#define FTDM_DEBUG_LINE_LEN 255
-#define handle_snprintf_result(buff, written, len, debugstr) \
- if (written >= len) { \
- ftdm_free(debugstr); \
- return NULL; \
- } \
- len -= written; \
- buff += written;
-
FT_DECLARE(char *) ftdm_channel_get_history_str(const ftdm_channel_t *fchan)
{
char func[255];
char line[255];
char states[255];
- int written = 0;
- char *buff = NULL;
uint8_t i = 0;
- int dbglen = ftdm_array_len(fchan->history) * FTDM_DEBUG_LINE_LEN;
- int len = dbglen;
+ ftdm_stream_handle_t stream = { 0 };
+ FTDM_STANDARD_STREAM(stream);
if (!fchan->history[0].file) {
- return ftdm_strdup("-- No state history --\n");
+ stream.write_function(&stream, "-- No state history --\n");
+ return stream.data;
}
- char *debugstr = ftdm_calloc(1, dbglen);
- if (!debugstr) {
- return NULL;
- }
- buff = debugstr;
-
- written = snprintf(buff, len, "%-30.30s %-30.30s %s", "-- States --", "-- Function --", "-- Location --\n");
- handle_snprintf_result(buff, written, len, debugstr);
+ stream.write_function(&stream, "%-30.30s %-30.30s %s", "-- States --", "-- Function --", "-- Location --\n");
for (i = fchan->hindex; i < ftdm_array_len(fchan->history); i++) {
if (!fchan->history[i].file) {
@@ -5248,21 +5387,17 @@ FT_DECLARE(char *) ftdm_channel_get_history_str(const ftdm_channel_t *fchan)
snprintf(states, sizeof(states), "%-5.15s => %-5.15s", ftdm_channel_state2str(fchan->history[i].last_state), ftdm_channel_state2str(fchan->history[i].state));
snprintf(func, sizeof(func), "[%s]", fchan->history[i].func);
snprintf(line, sizeof(func), "[%s:%d]", fchan->history[i].file, fchan->history[i].line);
- written = snprintf(buff, len, "%-30.30s %-30.30s %s\n", states, func, line);
- handle_snprintf_result(buff, written, len, debugstr);
+ stream.write_function(&stream, "%-30.30s %-30.30s %s\n", states, func, line);
}
for (i = 0; i < fchan->hindex; i++) {
snprintf(states, sizeof(states), "%-5.15s => %-5.15s", ftdm_channel_state2str(fchan->history[i].last_state), ftdm_channel_state2str(fchan->history[i].state));
snprintf(func, sizeof(func), "[%s]", fchan->history[i].func);
snprintf(line, sizeof(func), "[%s:%d]", fchan->history[i].file, fchan->history[i].line);
- written = snprintf(buff, len, "%-30.30s %-30.30s %s\n", states, func, line);
- handle_snprintf_result(buff, written, len, debugstr);
+ stream.write_function(&stream, "%-30.30s %-30.30s %s\n", states, func, line);
}
- debugstr[dbglen-1] = 0;
-
- return debugstr;
+ return stream.data;
}
diff --git a/libs/freetdm/src/ftdm_sched.c b/libs/freetdm/src/ftdm_sched.c
index be21696d71..c48c3e9433 100644
--- a/libs/freetdm/src/ftdm_sched.c
+++ b/libs/freetdm/src/ftdm_sched.c
@@ -34,6 +34,40 @@
#include "private/ftdm_core.h"
+#ifdef __WINDOWS__
+struct ftdm_timezone {
+ int tz_minuteswest; /* minutes W of Greenwich */
+ int tz_dsttime; /* type of dst correction */
+};
+int gettimeofday(struct timeval *tv, struct ftdm_timezone *tz)
+{
+ FILETIME ft;
+ unsigned __int64 tmpres = 0;
+ static int tzflag;
+ if (NULL != tv) {
+ GetSystemTimeAsFileTime(&ft);
+ tmpres |= ft.dwHighDateTime;
+ tmpres <<= 32;
+ tmpres |= ft.dwLowDateTime;
+
+ /*converting file time to unix epoch */
+ tmpres /= 10; /*convert into microseconds */
+ tmpres -= DELTA_EPOCH_IN_MICROSECS;
+ tv->tv_sec = (long) (tmpres / 1000000UL);
+ tv->tv_usec = (long) (tmpres % 1000000UL);
+ }
+ if (NULL != tz) {
+ if (!tzflag) {
+ _tzset();
+ tzflag++;
+ }
+ tz->tz_minuteswest = _timezone / 60;
+ tz->tz_dsttime = _daylight;
+ }
+ return 0;
+}
+#endif /* __WINDOWS__ */
+
typedef struct ftdm_timer ftdm_timer_t;
static struct {
@@ -55,9 +89,7 @@ struct ftdm_sched {
struct ftdm_timer {
char name[80];
ftdm_timer_id_t id;
-#ifdef __linux__
struct timeval time;
-#endif
void *usrdata;
ftdm_sched_callback_t callback;
ftdm_timer_t *next;
@@ -176,6 +208,24 @@ FT_DECLARE(ftdm_bool_t) ftdm_free_sched_running(void)
return sched_globals.running;
}
+FT_DECLARE(ftdm_bool_t) ftdm_free_sched_stop(void)
+{
+ /* currently we really dont stop the thread here, we rely on freetdm being shutdown and ftdm_running() to be false
+ * so the scheduling thread dies and we just wait for it here */
+ uint32_t sanity = 100;
+ while (ftdm_free_sched_running() && --sanity) {
+ ftdm_log(FTDM_LOG_DEBUG, "Waiting for main schedule thread to finish\n");
+ ftdm_sleep(100);
+ }
+
+ if (!sanity) {
+ ftdm_log(FTDM_LOG_CRIT, "schedule thread did not stop running, we may crash on shutdown\n");
+ return FTDM_FALSE;
+ }
+
+ return FTDM_TRUE;
+}
+
FT_DECLARE(ftdm_status_t) ftdm_sched_create(ftdm_sched_t **sched, const char *name)
{
ftdm_sched_t *newsched = NULL;
@@ -216,7 +266,6 @@ failed:
FT_DECLARE(ftdm_status_t) ftdm_sched_run(ftdm_sched_t *sched)
{
ftdm_status_t status = FTDM_FAIL;
-#ifdef __linux__
ftdm_timer_t *runtimer;
ftdm_timer_t *timer;
ftdm_sched_callback_t callback;
@@ -282,10 +331,6 @@ tryagain:
done:
ftdm_mutex_unlock(sched->mutex);
-#else
- ftdm_log(FTDM_LOG_CRIT, "Not implemented in this platform\n");
- status = FTDM_NOTIMPL;
-#endif
#ifdef __WINDOWS__
UNREFERENCED_PARAMETER(sched);
#endif
@@ -297,7 +342,6 @@ FT_DECLARE(ftdm_status_t) ftdm_sched_timer(ftdm_sched_t *sched, const char *name
int ms, ftdm_sched_callback_t callback, void *data, ftdm_timer_id_t *timerid)
{
ftdm_status_t status = FTDM_FAIL;
-#ifdef __linux__
struct timeval now;
int rc = 0;
ftdm_timer_t *newtimer;
@@ -360,17 +404,13 @@ FT_DECLARE(ftdm_status_t) ftdm_sched_timer(ftdm_sched_t *sched, const char *name
done:
ftdm_mutex_unlock(sched->mutex);
-#else
- ftdm_log(FTDM_LOG_CRIT, "Not implemented in this platform\n");
- status = FTDM_NOTIMPL;
-#endif
#ifdef __WINDOWS__
UNREFERENCED_PARAMETER(sched);
UNREFERENCED_PARAMETER(name);
UNREFERENCED_PARAMETER(ms);
UNREFERENCED_PARAMETER(callback);
UNREFERENCED_PARAMETER(data);
- UNREFERENCED_PARAMETER(timer);
+ UNREFERENCED_PARAMETER(timerid);
#endif
return status;
}
@@ -378,7 +418,6 @@ done:
FT_DECLARE(ftdm_status_t) ftdm_sched_get_time_to_next_timer(const ftdm_sched_t *sched, int32_t *timeto)
{
ftdm_status_t status = FTDM_FAIL;
-#ifdef __linux__
int res = -1;
int ms = 0;
struct timeval currtime;
@@ -427,10 +466,6 @@ FT_DECLARE(ftdm_status_t) ftdm_sched_get_time_to_next_timer(const ftdm_sched_t *
done:
ftdm_mutex_unlock(sched->mutex);
-#else
- ftdm_log(FTDM_LOG_ERROR, "Implement me!\n");
- status = FTDM_NOTIMPL;
-#endif
#ifdef __WINDOWS__
UNREFERENCED_PARAMETER(timeto);
UNREFERENCED_PARAMETER(sched);
diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c
index 2dc223eb91..a7135aab0d 100644
--- a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c
+++ b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c
@@ -374,7 +374,7 @@ static ftdm_state_map_t isdn_state_map = {
ZSD_OUTBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END},
- {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_DOWN, FTDM_END}
+ {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_DOWN, FTDM_END}
},
{
ZSD_OUTBOUND,
@@ -424,7 +424,7 @@ static ftdm_state_map_t isdn_state_map = {
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END},
- {FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_DOWN, FTDM_END},
+ {FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_CHANNEL_STATE_DOWN, FTDM_END},
},
{
ZSD_INBOUND,
@@ -605,10 +605,9 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
if (call) {
pri_hangup(isdn_data->spri.pri, call, ftdmchan->caller_data.hangup_cause);
pri_destroycall(isdn_data->spri.pri, call);
- ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
- } else {
- ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
- }
+ ftdmchan->call_data = NULL;
+ }
+ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
}
break;
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
@@ -617,8 +616,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
{
sig.event_id = FTDM_SIGEVENT_STOP;
status = ftdm_span_send_signal(ftdmchan->span, &sig);
- ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
-
+ /* user moves us to HANGUP and from there we go to DOWN */
}
default:
break;
@@ -641,10 +639,12 @@ static __inline__ void check_state(ftdm_span_t *span)
for(j = 1; j <= span->chan_count; j++) {
if (ftdm_test_flag((span->channels[j]), FTDM_CHANNEL_STATE_CHANGE)) {
ftdm_mutex_lock(span->channels[j]->mutex);
+ ftdm_channel_lock(span->channels[j]);
ftdm_clear_flag((span->channels[j]), FTDM_CHANNEL_STATE_CHANGE);
state_advance(span->channels[j]);
ftdm_channel_complete_state(span->channels[j]);
ftdm_mutex_unlock(span->channels[j]->mutex);
+ ftdm_channel_unlock(span->channels[j]);
}
}
}
@@ -682,18 +682,35 @@ static int on_hangup(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_even
q931_call *call = NULL;
ftdmchan = span->channels[pevent->hangup.channel];
- if (ftdmchan) {
- call = (q931_call *) ftdmchan->call_data;
- ftdm_log(FTDM_LOG_DEBUG, "-- Hangup on channel %d:%d\n", spri->span->span_id, pevent->hangup.channel);
- ftdmchan->caller_data.hangup_cause = pevent->hangup.cause;
- pri_release(spri->pri, call, 0);
- pri_destroycall(spri->pri, call);
- ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
- } else {
- ftdm_log(FTDM_LOG_DEBUG, "-- Hangup on channel %d:%d %s but it's not in use?\n", spri->span->span_id,
- pevent->hangup.channel, ftdmchan->chan_id);
+ if (!ftdmchan) {
+ ftdm_log(FTDM_LOG_CRIT, "-- Hangup on channel %d:%d %s but it's not in use?\n", spri->span->span_id, pevent->hangup.channel);
+ return 0;
}
+ ftdm_channel_lock(ftdmchan);
+
+ if (ftdmchan->state >= FTDM_CHANNEL_STATE_TERMINATING) {
+ ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Ignoring remote hangup in state %s\n", ftdm_channel_state2str(ftdmchan->state));
+ goto done;
+ }
+
+ if (!ftdmchan->call_data) {
+ ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Ignoring remote hangup in state %s with no call data\n", ftdm_channel_state2str(ftdmchan->state));
+ goto done;
+ }
+
+ call = (q931_call *) ftdmchan->call_data;
+ ftdm_log(FTDM_LOG_DEBUG, "-- Hangup on channel %d:%d\n", spri->span->span_id, pevent->hangup.channel);
+ ftdmchan->caller_data.hangup_cause = pevent->hangup.cause;
+ pri_release(spri->pri, call, 0);
+ pri_destroycall(spri->pri, call);
+ ftdmchan->call_data = NULL;
+ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
+
+done:
+
+ ftdm_channel_unlock(ftdmchan);
+
return 0;
}
@@ -1087,10 +1104,17 @@ static void *ftdm_libpri_run(ftdm_thread_t *me, void *obj)
got_d = 1;
x++;
break;
+ } else {
+ ftdm_log(FTDM_LOG_ERROR, "failed to open d-channel #%d %d:%d\n", x, span->channels[i]->span_id, span->channels[i]->chan_id);
}
}
}
}
+
+ if (!got_d) {
+ ftdm_log(FTDM_LOG_ERROR, "Failed to get a D-channel in span %d\n", span->span_id);
+ break;
+ }
if (lpwrap_init_pri(&isdn_data->spri,
@@ -1133,7 +1157,9 @@ static void *ftdm_libpri_run(ftdm_thread_t *me, void *obj)
}
ftdm_log(FTDM_LOG_CRIT, "PRI down on span %d\n", isdn_data->spri.span->span_id);
- isdn_data->spri.dchan->state = FTDM_CHANNEL_STATE_DOWN;
+ if (isdn_data->spri.dchan) {
+ isdn_data->spri.dchan->state = FTDM_CHANNEL_STATE_DOWN;
+ }
if (!down) {
ftdm_set_state_all(span, FTDM_CHANNEL_STATE_RESTART);
@@ -1147,7 +1173,7 @@ static void *ftdm_libpri_run(ftdm_thread_t *me, void *obj)
ftdm_sleep(5000);
}
- ftdm_log(FTDM_LOG_DEBUG, "PRI thread ended on span %d\n", isdn_data->spri.span->span_id);
+ ftdm_log(FTDM_LOG_DEBUG, "PRI thread ended on span %d\n", span->span_id);
ftdm_clear_flag(span, FTDM_SPAN_IN_THREAD);
ftdm_clear_flag(isdn_data, FTMOD_LIBPRI_RUNNING);
diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c b/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c
index b286ec1df6..8dfba34ec3 100644
--- a/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c
+++ b/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c
@@ -177,7 +177,7 @@ int lpwrap_init_pri(struct lpwrap_pri *spri, ftdm_span_t *span, ftdm_channel_t *
spri->dchan = dchan;
spri->span = span;
- if ((spri->pri = pri_new_cb(spri->dchan->sockfd, node, swtype, __pri_lpwrap_read, __pri_lpwrap_write, spri))){
+ if (spri->dchan && (spri->pri = pri_new_cb(spri->dchan->sockfd, node, swtype, __pri_lpwrap_read, __pri_lpwrap_write, spri))){
unsigned char buf[4] = { 0 };
size_t buflen = sizeof(buf), len = 0;
pri_set_debug(spri->pri, debug);
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2008.vcproj b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2008.vcproj
new file mode 100644
index 0000000000..e3930d8188
--- /dev/null
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.2008.vcproj
@@ -0,0 +1,241 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c
index 08f340dc83..8dbbda7a65 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c
@@ -265,10 +265,12 @@ static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj)
}
while (ftdm_running() && !(ftdm_test_flag(span, FTDM_SPAN_STOP_THREAD))) {
- /* find out why we returned from the interrupt queue */
- ret_status = ftdm_interrupt_multiple_wait(ftdm_sangoma_isdn_int, 2, sleep);
+
/* Check if there are any timers to process */
ftdm_sched_run(signal_data->sched);
+
+ ret_status = ftdm_interrupt_multiple_wait(ftdm_sangoma_isdn_int, 2, sleep);
+ /* find out why we returned from the interrupt queue */
switch (ret_status) {
case FTDM_SUCCESS: /* there was a state change on the span */
/* process all pending state changes */
@@ -289,13 +291,30 @@ static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj)
/* twiddle */
break;
case FTDM_FAIL:
- ftdm_log(FTDM_LOG_ERROR,"ftdm_interrupt_wait returned error!\non span = %s\n", span->name);
+ ftdm_log(FTDM_LOG_ERROR,"%s:ftdm_interrupt_wait returned error!\n", span->name);
break;
default:
- ftdm_log(FTDM_LOG_ERROR,"ftdm_interrupt_wait returned with unknown code on span = %s\n", span->name);
+ ftdm_log(FTDM_LOG_ERROR,"%s:ftdm_interrupt_wait returned with unknown code\n", span->name);
break;
}
+
+ /* Poll for events, e.g HW DTMF */
+ ret_status = ftdm_span_poll_event(span, 0);
+ switch(ret_status) {
+ case FTDM_SUCCESS:
+ {
+ ftdm_event_t *event;
+ while (ftdm_span_next_event(span, &event) == FTDM_SUCCESS);
+ }
+ break;
+ case FTDM_TIMEOUT:
+ /* No events pending */
+ break;
+ default:
+ ftdm_log(FTDM_LOG_WARNING, "%s:Failed to poll span event\n", span->name);
+ }
+
if (ftdm_sched_get_time_to_next_timer(signal_data->sched, &sleep) == FTDM_SUCCESS) {
if (sleep < 0 || sleep > SNGISDN_EVENT_POLL_RATE) {
sleep = SNGISDN_EVENT_POLL_RATE;
@@ -726,7 +745,7 @@ static FIO_SPAN_SET_SIG_STATUS_FUNCTION(ftdm_sangoma_isdn_set_span_sig_status)
}
static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span)
-{
+{
ftdm_log(FTDM_LOG_INFO,"Starting span %s:%u.\n",span->name,span->span_id);
if (sng_isdn_stack_start(span) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "Failed to start span %s\n", span->name);
@@ -747,9 +766,11 @@ static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span)
}
static ftdm_status_t ftdm_sangoma_isdn_stop(ftdm_span_t *span)
-{
+{
ftdm_iterator_t *chaniter = NULL;
ftdm_iterator_t *curr = NULL;
+ unsigned i;
+ sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data;
ftdm_log(FTDM_LOG_INFO, "Stopping span %s\n", span->name);
/* throw the STOP_THREAD flag to signal monitor thread stop */
@@ -772,8 +793,13 @@ static ftdm_status_t ftdm_sangoma_isdn_stop(ftdm_span_t *span)
}
ftdm_iterator_free(chaniter);
- ftdm_sched_destroy(&((sngisdn_span_data_t*)span->signal_data)->sched);
- ftdm_queue_destroy(&((sngisdn_span_data_t*)span->signal_data)->event_queue);
+ ftdm_sched_destroy(&signal_data->sched);
+ ftdm_queue_destroy(&signal_data->event_queue);
+ for (i = 0 ; i < signal_data->num_local_numbers ; i++) {
+ if (signal_data->local_numbers[i] != NULL) {
+ ftdm_safe_free(signal_data->local_numbers[i]);
+ }
+ }
ftdm_safe_free(span->signal_data);
ftdm_log(FTDM_LOG_DEBUG, "Finished stopping span %s\n", span->name);
@@ -1003,7 +1029,7 @@ static FIO_IO_LOAD_FUNCTION(ftdm_sangoma_isdn_io_init)
return FTDM_SUCCESS;
}
-ftdm_module_t ftdm_module =
+EX_DECLARE_DATA ftdm_module_t ftdm_module =
{
"sangoma_isdn", /* char name[256]; */
ftdm_sangoma_isdn_io_init, /* fio_io_load_t */
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h
index ae6c0d92f7..7db753e420 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h
@@ -38,8 +38,12 @@
#include
#include
#include
+#ifdef HAVE_STDINT_H
#include
+#endif
+#ifdef HAVE_UNISTD_H
#include
+#endif
#include
#include "private/ftdm_core.h"
@@ -55,6 +59,7 @@
#define NUM_BRI_CHANNELS_PER_SPAN 2
#define SNGISDN_EVENT_QUEUE_SIZE 100
#define SNGISDN_EVENT_POLL_RATE 100
+#define SNGISDN_NUM_LOCAL_NUMBERS 8
/* TODO: rename all *_cc_* to *_an_* */
@@ -161,7 +166,7 @@ typedef struct sngisdn_chan_data {
/* Span specific data */
typedef struct sngisdn_span_data {
- ftdm_span_t *ftdm_span;
+ ftdm_span_t *ftdm_span;
uint8_t link_id;
uint8_t switchtype;
uint8_t signalling; /* SNGISDN_SIGNALING_CPE or SNGISDN_SIGNALING_NET */
@@ -175,7 +180,9 @@ typedef struct sngisdn_span_data {
uint8_t setup_arb;
uint8_t facility;
int8_t facility_timeout;
- ftdm_sched_t *sched;
+ uint8_t num_local_numbers;
+ char* local_numbers[SNGISDN_NUM_LOCAL_NUMBERS];
+ ftdm_sched_t *sched;
ftdm_queue_t *event_queue;
} sngisdn_span_data_t;
@@ -259,16 +266,16 @@ extern ftdm_sngisdn_data_t g_sngisdn_data;
ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span);
/* Support functions */
-uint32_t get_unique_suInstId(uint8_t cc_id);
-void clear_call_data(sngisdn_chan_data_t *sngisdn_info);
-void clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info);
+FT_DECLARE_INLINE(uint32_t) get_unique_suInstId(uint8_t cc_id);
+FT_DECLARE_INLINE(void) clear_call_data(sngisdn_chan_data_t *sngisdn_info);
+FT_DECLARE_INLINE(void) clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info);
void stack_hdr_init(Header *hdr);
void stack_pst_init(Pst *pst);
-ftdm_status_t get_ftdmchan_by_spInstId(uint8_t cc_id, uint32_t spInstId, sngisdn_chan_data_t **sngisdn_data);
-ftdm_status_t get_ftdmchan_by_suInstId(uint8_t cc_id, uint32_t suInstId, sngisdn_chan_data_t **sngisdn_data);
-ftdm_status_t sng_isdn_set_avail_rate(ftdm_span_t *ftdmspan, sngisdn_avail_t avail);
+FT_DECLARE_INLINE(ftdm_status_t) get_ftdmchan_by_spInstId(uint8_t cc_id, uint32_t spInstId, sngisdn_chan_data_t **sngisdn_data);
+FT_DECLARE_INLINE(ftdm_status_t) get_ftdmchan_by_suInstId(uint8_t cc_id, uint32_t suInstId, sngisdn_chan_data_t **sngisdn_data);
+FT_DECLARE_INLINE(ftdm_status_t) sng_isdn_set_avail_rate(ftdm_span_t *ftdmspan, sngisdn_avail_t avail);
/* Outbound Call Control functions */
void sngisdn_snd_setup(ftdm_channel_t *ftdmchan);
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c
index 361b389f96..64d7a2403f 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c
@@ -36,9 +36,23 @@
ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span);
ftdm_status_t parse_signalling(const char* signalling, ftdm_span_t *span);
+ftdm_status_t add_local_number(const char* val, ftdm_span_t *span);
extern ftdm_sngisdn_data_t g_sngisdn_data;
+ftdm_status_t add_local_number(const char* val, ftdm_span_t *span)
+{
+ sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data;
+
+ if (signal_data->num_local_numbers >= SNGISDN_NUM_LOCAL_NUMBERS) {
+ ftdm_log(FTDM_LOG_ERROR, "%s: Maximum number of local-numbers exceeded (max:%d)\n", span->name, SNGISDN_NUM_LOCAL_NUMBERS);
+ return FTDM_FAIL;
+ }
+
+ signal_data->local_numbers[signal_data->num_local_numbers++] = ftdm_strdup(val);
+ return FTDM_SUCCESS;
+}
+
ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span)
{
unsigned i;
@@ -253,6 +267,10 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
ftdm_span_set_bearer_capability(val, &span->default_caller_data.bearer_capability);
} else if (!strcasecmp(var, "outbound-bearer_layer1")) {
ftdm_span_set_bearer_layer1(val, &span->default_caller_data.bearer_layer1);
+ } else if (!strcasecmp(var, "local-number")) {
+ if (add_local_number(val, span) != FTDM_SUCCESS) {
+ return FTDM_FAIL;
+ }
} else if (!strcasecmp(var, "facility-timeout")) {
signal_data->facility_timeout = atoi(val);
if (signal_data->facility_timeout < 0) {
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c
index 3a4a001089..5a3e06ec89 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c
@@ -193,10 +193,12 @@ ftdm_status_t sng_isdn_stack_cfg_phy_gen(void)
ftdm_status_t sng_isdn_stack_cfg_phy_psap(ftdm_span_t *span)
{
- /*local variables*/
- L1Mngmt cfg; /*configuration structure*/
- Pst pst; /*post structure*/
+ ftdm_iterator_t *chaniter;
+ ftdm_iterator_t *curr;
+ L1Mngmt cfg;
+ Pst pst;
+ S32 d_channel_fd = -1;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
/* initalize the post structure */
@@ -219,20 +221,35 @@ ftdm_status_t sng_isdn_stack_cfg_phy_psap(ftdm_span_t *span)
cfg.hdr.elmId.elmntInst1 = signal_data->link_id;
- cfg.t.cfg.s.l1PSAP.span = span->channels[1]->physical_span_id;
+
+ /* Find the d-channel */
+ chaniter = ftdm_span_get_chan_iterator(span, NULL);
+ for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
+ ftdm_channel_t *ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr);
+ if (ftdmchan->type == FTDM_CHAN_TYPE_DQ921) {
+ d_channel_fd = (S32) ftdmchan->sockfd;
+ break;
+ }
+ }
+ ftdm_iterator_free(chaniter);
+
+ if(d_channel_fd < 0) {
+ ftdm_log(FTDM_LOG_ERROR, "%s:No d-channels specified\n", span->name);
+ return FTDM_FAIL;
+ }
+
+ cfg.t.cfg.s.l1PSAP.sockfd = d_channel_fd;
+
switch(span->trunk_type) {
case FTDM_TRUNK_E1:
- cfg.t.cfg.s.l1PSAP.chan = 16;
cfg.t.cfg.s.l1PSAP.type = SNG_L1_TYPE_PRI;
break;
case FTDM_TRUNK_T1:
case FTDM_TRUNK_J1:
- cfg.t.cfg.s.l1PSAP.chan = 24;
cfg.t.cfg.s.l1PSAP.type = SNG_L1_TYPE_PRI;
break;
case FTDM_TRUNK_BRI:
case FTDM_TRUNK_BRI_PTMP:
- cfg.t.cfg.s.l1PSAP.chan = 3;
cfg.t.cfg.s.l1PSAP.type = SNG_L1_TYPE_BRI;
break;
default:
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c
index cea8ac0173..27c16c2a51 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c
@@ -158,7 +158,7 @@ ftdm_status_t sng_isdn_deactivate_phy(ftdm_span_t *span)
ftdm_status_t sng_isdn_activate_cc(ftdm_span_t *span)
{
- CcMngmt cntrl;;
+ CcMngmt cntrl;
Pst pst;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
@@ -239,7 +239,7 @@ ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t tra
ftdm_status_t sng_isdn_cntrl_q931(ftdm_span_t *span, uint8_t action, uint8_t subaction)
{
- InMngmt cntrl;;
+ InMngmt cntrl;
Pst pst;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c
index b7af8e98c5..9adcc08296 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c
@@ -42,8 +42,7 @@ extern ftdm_status_t cpy_calling_name_from_stack(ftdm_caller_data_t *ftdm, Displ
/* Remote side transmit a SETUP */
void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
-
+ unsigned i;
int16_t suId = sngisdn_event->suId;
uint32_t suInstId = sngisdn_event->suInstId;
uint32_t spInstId = sngisdn_event->spInstId;
@@ -54,10 +53,12 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
ConEvnt *conEvnt = &sngisdn_event->event.conEvnt;
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
+
ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n");
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
-
+
switch (ftdmchan->state) {
case FTDM_CHANNEL_STATE_DOWN: /* Proper state to receive a SETUP */
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_INUSE) ||
@@ -77,14 +78,39 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
break;
}
- sngisdn_info->suInstId = get_unique_suInstId(suId);
+ sngisdn_info->suInstId = get_unique_suInstId((int8_t) suId);
sngisdn_info->spInstId = spInstId;
+
+
+ if (conEvnt->cdPtyNmb.eh.pres && signal_data->num_local_numbers) {
+ uint8_t local_number_matched = 0;
+ for (i = 0 ; i < signal_data->num_local_numbers ; i++) {
+ if (!strcmp(signal_data->local_numbers[i], (char*)conEvnt->cdPtyNmb.nmbDigits.val)) {
+ local_number_matched++;
+ break;
+ }
+ }
+ if (!local_number_matched) {
+ ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received SETUP, but local-number %s does not match - ignoring\n", conEvnt->cdPtyNmb.nmbDigits.val);
+ /* Special case to tell the stack to clear all internal resources about this call. We will no receive any event for this call after sending disconnect request */
+ ftdmchan->caller_data.hangup_cause = IN_CCNORTTODEST;
+ ftdm_sched_timer(signal_data->sched, "delayed_disconnect", 1, sngisdn_delayed_disconnect, (void*) sngisdn_info, NULL);
+ return;
+ }
+ }
/* If this is a glared call that was previously saved, we moved
all the info to the current call, so clear the glared saved data */
if (sngisdn_info->glare.spInstId == spInstId) {
clear_call_glare_data(sngisdn_info);
- }
+ }
+
+
+ if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
+ if (signal_data->signalling == SNGISDN_SIGNALING_NET) {
+ sngisdn_info->ces = ces;
+ }
+ }
ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex);
g_sngisdn_data.ccs[suId].active_suInstIds[sngisdn_info->suInstId] = sngisdn_info;
@@ -92,11 +118,6 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND);
- if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP &&
- signal_data->signalling == SNGISDN_SIGNALING_NET) {
- sngisdn_info->ces = ces;
- }
-
/* try to open the channel */
if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Failed to open channel");
@@ -109,27 +130,24 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
#if 0
/* Export ftdmchan variables here if we need to */
ftdm_channel_add_var(ftdmchan, "isdn_specific_var", "1");
- ftdm_channel_add_var(ftdmchan, "isdn_crap", "morecrap");
- ftdm_channel_add_var(ftdmchan, "isdn_stuff", "s");
- ftdm_channel_add_var(ftdmchan, "isdn_d", "asdsadasdasdsad");
#endif
/* Fill in call information */
cpy_calling_num_from_stack(&ftdmchan->caller_data, &conEvnt->cgPtyNmb);
cpy_called_num_from_stack(&ftdmchan->caller_data, &conEvnt->cdPtyNmb);
cpy_calling_name_from_stack(&ftdmchan->caller_data, &conEvnt->display);
+ ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Incoming call: Called No:[%s] Calling No:[%s]\n", ftdmchan->caller_data.dnis.digits, ftdmchan->caller_data.cid_num.digits);
if (conEvnt->bearCap[0].eh.pres) {
ftdmchan->caller_data.bearer_layer1 = sngisdn_get_infoTranCap_from_stack(conEvnt->bearCap[0].usrInfoLyr1Prot.val);
ftdmchan->caller_data.bearer_capability = sngisdn_get_infoTranCap_from_stack(conEvnt->bearCap[0].infoTranCap.val);
}
-
+
if (signal_data->switchtype == SNGISDN_SWITCH_NI2) {
if (conEvnt->shift11.eh.pres && conEvnt->ni2OctStr.eh.pres) {
if (conEvnt->ni2OctStr.str.len == 4 && conEvnt->ni2OctStr.str.val[0] == 0x37) {
snprintf(ftdmchan->caller_data.aniII, 5, "%.2d", conEvnt->ni2OctStr.str.val[3]);
}
}
-
if (signal_data->facility == SNGISDN_OPT_TRUE && conEvnt->facilityStr.eh.pres) {
/* Verify whether the Caller Name will come in a subsequent FACILITY message */
@@ -187,7 +205,7 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
sngisdn_set_flag(sngisdn_info, FLAG_DELAYED_REL);
sngisdn_info->glare.suId = suId;
- sngisdn_info->glare.suInstId = get_unique_suInstId(suId);
+ sngisdn_info->glare.suInstId = get_unique_suInstId((int8_t) suId);
sngisdn_info->glare.spInstId = spInstId;
sngisdn_info->glare.dChan = dChan;
@@ -223,8 +241,6 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
/* Remote side transmit a CONNECT or CONNECT ACK */
void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
-
int16_t suId = sngisdn_event->suId;
uint32_t suInstId = sngisdn_event->suInstId;
uint32_t spInstId = sngisdn_event->spInstId;
@@ -232,6 +248,8 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
+
/* Function does not require any info from conStEvnt struct for now */
/* CnStEvnt *cnStEvnt = &sngisdn_event->event.cnStEvnt; */
@@ -260,6 +278,10 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
case FTDM_CHANNEL_STATE_DIALING:
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP);
break;
+ case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
+ case FTDM_CHANNEL_STATE_HANGUP:
+ /* Race condition, we just hung up the call - ignore this message */
+ break;
default:
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing CONNECT/CONNECT ACK in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
@@ -274,7 +296,7 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
/* do nothing */
break;
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
- /* We just hung up an incoming call right after we sent a CONNECT so ignore this message */
+ /* Race condition, We just hung up an incoming call right after we sent a CONNECT - ignore this message */
break;
default:
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing CONNECT/CONNECT ACK in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
@@ -291,8 +313,6 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
-
int16_t suId = sngisdn_event->suId;
uint32_t suInstId = sngisdn_event->suInstId;
uint32_t spInstId = sngisdn_event->spInstId;
@@ -306,6 +326,8 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
CnStEvnt *cnStEvnt = &sngisdn_event->event.cnStEvnt;
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
+
ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n");
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing %s (suId:%u suInstId:%u spInstId:%u ces:%d)\n",
@@ -423,8 +445,6 @@ sngisdn_process_cnst_ind_end:
void sngisdn_process_disc_ind (sngisdn_event_data_t *sngisdn_event)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
-
int16_t suId = sngisdn_event->suId;
uint32_t suInstId = sngisdn_event->suInstId;
uint32_t spInstId = sngisdn_event->spInstId;
@@ -433,6 +453,8 @@ void sngisdn_process_disc_ind (sngisdn_event_data_t *sngisdn_event)
DiscEvnt *discEvnt = &sngisdn_event->event.discEvnt;
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
+
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing DISCONNECT (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n");
@@ -480,7 +502,6 @@ void sngisdn_process_disc_ind (sngisdn_event_data_t *sngisdn_event)
void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
int16_t suId = sngisdn_event->suId;
uint32_t suInstId = sngisdn_event->suInstId;
uint32_t spInstId = sngisdn_event->spInstId;
@@ -489,6 +510,8 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event)
RelEvnt *relEvnt = &sngisdn_event->event.relEvnt;
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
+
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing RELEASE/RELEASE COMPLETE (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n");
@@ -575,7 +598,6 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event)
void sngisdn_process_dat_ind (sngisdn_event_data_t *sngisdn_event)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
int16_t suId = sngisdn_event->suId;
uint32_t suInstId = sngisdn_event->suInstId;
uint32_t spInstId = sngisdn_event->spInstId;
@@ -583,6 +605,8 @@ void sngisdn_process_dat_ind (sngisdn_event_data_t *sngisdn_event)
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
+
/* Function does not require any info from infoEvnt struct for now */
/* InfoEvnt *infoEvnt = &sngisdn_event->event.infoEvnt; */
@@ -593,7 +617,6 @@ void sngisdn_process_dat_ind (sngisdn_event_data_t *sngisdn_event)
void sngisdn_process_sshl_ind (sngisdn_event_data_t *sngisdn_event)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
int16_t suId = sngisdn_event->suId;
uint32_t suInstId = sngisdn_event->suInstId;
uint32_t spInstId = sngisdn_event->spInstId;
@@ -601,6 +624,8 @@ void sngisdn_process_sshl_ind (sngisdn_event_data_t *sngisdn_event)
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
+
/* Function does not require any info from ssHlEvnt struct for now */
/* SsHlEvnt *ssHlEvnt = &sngisdn_event->event.ssHlEvnt; */
@@ -611,14 +636,15 @@ void sngisdn_process_sshl_ind (sngisdn_event_data_t *sngisdn_event)
void sngisdn_process_sshl_cfm (sngisdn_event_data_t *sngisdn_event)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
int16_t suId = sngisdn_event->suId;
uint32_t suInstId = sngisdn_event->suInstId;
uint32_t spInstId = sngisdn_event->spInstId;
-
+
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
+
/* Function does not require any info from ssHlEvnt struct for now */
/* SsHlEvnt *ssHlEvnt = &sngisdn_event->event.ssHlEvnt; */
@@ -629,7 +655,6 @@ void sngisdn_process_sshl_cfm (sngisdn_event_data_t *sngisdn_event)
void sngisdn_process_rmrt_ind (sngisdn_event_data_t *sngisdn_event)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
int16_t suId = sngisdn_event->suId;
uint32_t suInstId = sngisdn_event->suInstId;
uint32_t spInstId = sngisdn_event->spInstId;
@@ -637,6 +662,8 @@ void sngisdn_process_rmrt_ind (sngisdn_event_data_t *sngisdn_event)
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
+
/* Function does not require any info from ssHlEvnt struct for now */
/* RmRtEvnt *rmRtEvnt = &sngisdn_event->event.rmRtEvnt; */
@@ -647,7 +674,6 @@ void sngisdn_process_rmrt_ind (sngisdn_event_data_t *sngisdn_event)
void sngisdn_process_rmrt_cfm (sngisdn_event_data_t *sngisdn_event)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
int16_t suId = sngisdn_event->suId;
uint32_t suInstId = sngisdn_event->suInstId;
uint32_t spInstId = sngisdn_event->spInstId;
@@ -655,6 +681,8 @@ void sngisdn_process_rmrt_cfm (sngisdn_event_data_t *sngisdn_event)
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
+
/* Function does not require any info from ssHlEvnt struct for now */
/* RmRtEvnt *rmRtEvnt = &sngisdn_event->event.rmRtEvnt; */
@@ -665,7 +693,6 @@ void sngisdn_process_rmrt_cfm (sngisdn_event_data_t *sngisdn_event)
void sngisdn_process_flc_ind (sngisdn_event_data_t *sngisdn_event)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
int16_t suId = sngisdn_event->suId;
uint32_t suInstId = sngisdn_event->suInstId;
uint32_t spInstId = sngisdn_event->spInstId;
@@ -673,6 +700,8 @@ void sngisdn_process_flc_ind (sngisdn_event_data_t *sngisdn_event)
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
+
/* Function does not require any info from ssHlEvnt struct for now */
/* StaEvnt *staEvnt = &sngisdn_event->event.staEvnt; */
@@ -683,8 +712,6 @@ void sngisdn_process_flc_ind (sngisdn_event_data_t *sngisdn_event)
void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
-
int16_t suId = sngisdn_event->suId;
uint32_t suInstId = sngisdn_event->suInstId;
uint32_t spInstId = sngisdn_event->spInstId;
@@ -695,6 +722,8 @@ void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event)
FacEvnt *facEvnt = &sngisdn_event->event.facEvnt;
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
+
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing FACILITY IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
switch (ftdmchan->state) {
@@ -736,8 +765,6 @@ void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event)
void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
-
int16_t suId = sngisdn_event->suId;
uint32_t suInstId = sngisdn_event->suInstId;
uint32_t spInstId = sngisdn_event->spInstId;
@@ -748,6 +775,8 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event)
uint8_t call_state = 0;
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
+
if (staEvnt->callSte.eh.pres && staEvnt->callSte.callGlblSte.pres) {
call_state = staEvnt->callSte.callGlblSte.val;
}
@@ -923,6 +952,16 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event)
break;
}
break;
+ case 12: /* We received a disconnect indication */
+ switch (ftdmchan->state) {
+ case FTDM_CHANNEL_STATE_TERMINATING:
+ /* We are already waiting for user app to handle the disconnect, do nothing */
+ break;
+ default:
+ ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
+ break;
+ }
+ break;
case 22:
switch (ftdmchan->state) {
case FTDM_CHANNEL_STATE_UP:
@@ -937,6 +976,18 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event)
//ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
break;
}
+ break;
+ case 25: /* Overlap receiving */
+ switch (ftdmchan->state) {
+ case FTDM_CHANNEL_STATE_COLLECT:
+ /* do nothing */
+ break;
+ default:
+ ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
+ //ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
+ break;
+ }
+ break;
default:
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle incompatible state. remote call state:%d our state:%s\n", call_state, ftdm_channel_state2str(ftdmchan->state));
//ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
@@ -951,11 +1002,12 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event)
void sngisdn_process_srv_ind (sngisdn_event_data_t *sngisdn_event)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
int16_t suId = sngisdn_event->suId;
int16_t dChan = sngisdn_event->dChan;
uint8_t ces = sngisdn_event->ces;
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
+
/* Function does not require any info from ssHlEvnt struct for now */
/*Srv *srvEvnt = &sngisdn_event->event.srvEvnt;*/
@@ -966,11 +1018,12 @@ void sngisdn_process_srv_ind (sngisdn_event_data_t *sngisdn_event)
void sngisdn_process_srv_cfm (sngisdn_event_data_t *sngisdn_event)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
int16_t suId = sngisdn_event->suId;
int16_t dChan = sngisdn_event->dChan;
uint8_t ces = sngisdn_event->ces;
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
+
/* Function does not require any info from ssHlEvnt struct for now */
/*Srv *srvEvnt = &sngisdn_event->event.srvEvnt;*/
@@ -981,12 +1034,13 @@ void sngisdn_process_srv_cfm (sngisdn_event_data_t *sngisdn_event)
void sngisdn_process_rst_cfm (sngisdn_event_data_t *sngisdn_event)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
int16_t suId = sngisdn_event->suId;
int16_t dChan = sngisdn_event->dChan;
uint8_t ces = sngisdn_event->ces;
uint8_t evntType = sngisdn_event->evntType;
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
+
/* Function does not require any info from ssHlEvnt struct for now */
/*Rst *rstEvnt = &sngisdn_event->event.rstEvnt;*/
@@ -998,12 +1052,13 @@ void sngisdn_process_rst_cfm (sngisdn_event_data_t *sngisdn_event)
void sngisdn_process_rst_ind (sngisdn_event_data_t *sngisdn_event)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
int16_t suId = sngisdn_event->suId;
int16_t dChan = sngisdn_event->dChan;
uint8_t ces = sngisdn_event->ces;
uint8_t evntType = sngisdn_event->evntType;
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
+
/* Function does not require any info from ssHlEvnt struct for now */
/*Rst *rstEvnt = &sngisdn_event->event.rstEvnt;*/
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c
index 80a85ceec8..3284d54165 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c
@@ -143,6 +143,7 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
signal_data->signalling == SNGISDN_SIGNALING_NET) {
sngisdn_info->ces = CES_MNGMNT;
}
+ ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Outgoing call: Called No:[%s] Calling No:[%s]\n", ftdmchan->caller_data.dnis.digits, ftdmchan->caller_data.cid_num.digits);
cpy_called_num_from_user(&conEvnt.cdPtyNmb, &ftdmchan->caller_data);
cpy_calling_num_from_user(&conEvnt.cgPtyNmb, &ftdmchan->caller_data);
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c
index 791c6b7d8c..39c5693728 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c
@@ -43,11 +43,12 @@ extern void get_memory_info(void);
void sngisdn_rcv_con_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, ConEvnt *conEvnt, int16_t dChan, uint8_t ces)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
uint8_t bchan_no = 0;
sngisdn_chan_data_t *sngisdn_info = NULL;
sngisdn_event_data_t *sngisdn_event = NULL;
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
+
ftdm_assert(g_sngisdn_data.ccs[suId].activation_done != 0, "Con Ind on unconfigured cc\n");
ftdm_assert(g_sngisdn_data.dchans[dChan].num_spans != 0, "Con Ind on unconfigured dchan\n");
@@ -103,14 +104,15 @@ void sngisdn_rcv_con_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Co
void sngisdn_rcv_con_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, int16_t dChan, uint8_t ces)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info = NULL;
sngisdn_event_data_t *sngisdn_event = NULL;
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
+
ftdm_assert(g_sngisdn_data.ccs[suId].activation_done != 0, "Con Cfm on unconfigured cc\n");
ftdm_assert(g_sngisdn_data.dchans[dChan].num_spans != 0, "Con Cfm on unconfigured dchan\n");
- if (get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) != FTDM_SUCCESS) {
+ if (get_ftdmchan_by_suInstId((int8_t) suId, suInstId, &sngisdn_info) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId);
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
return;
@@ -146,14 +148,15 @@ void sngisdn_rcv_con_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, Cn
void sngisdn_rcv_cnst_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, uint8_t evntType, int16_t dChan, uint8_t ces)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info = NULL;
sngisdn_event_data_t *sngisdn_event = NULL;
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
+
ftdm_assert(g_sngisdn_data.ccs[suId].activation_done != 0, "Cnst Ind on unconfigured cc\n");
ftdm_assert(g_sngisdn_data.dchans[dChan].num_spans != 0, "Cnst Ind on unconfigured dchan\n");
- if (get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) != FTDM_SUCCESS) {
+ if (get_ftdmchan_by_suInstId((int8_t) suId, suInstId, &sngisdn_info) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId);
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
return;
@@ -196,14 +199,15 @@ void sngisdn_rcv_cnst_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, C
void sngisdn_rcv_disc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, DiscEvnt *discEvnt)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info = NULL;
sngisdn_event_data_t *sngisdn_event = NULL;
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
+
ftdm_assert(spInstId != 0, "Received DISCONNECT with invalid id");
- if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
- !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
+ if (!(spInstId && get_ftdmchan_by_spInstId((int8_t) suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
+ !(suInstId && get_ftdmchan_by_suInstId((int8_t) suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId);
ftdm_assert(0, "Inconsistent call states\n");
@@ -231,12 +235,13 @@ void sngisdn_rcv_disc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, D
void sngisdn_rcv_rel_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, RelEvnt *relEvnt)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info = NULL;
sngisdn_event_data_t *sngisdn_event = NULL;
+
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
- if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
- !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
+ if (!(spInstId && get_ftdmchan_by_spInstId((int8_t) suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
+ !(suInstId && get_ftdmchan_by_suInstId((int8_t) suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId);
/* It seems that Trillium has a bug where they sometimes send release twice on a call, so do not crash on these for now */
@@ -264,12 +269,13 @@ void sngisdn_rcv_rel_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Re
void sngisdn_rcv_dat_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, InfoEvnt *infoEvnt)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info;
sngisdn_event_data_t *sngisdn_event = NULL;
- if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
- !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
+
+ if (!(spInstId && get_ftdmchan_by_spInstId((int8_t) suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
+ !(suInstId && get_ftdmchan_by_suInstId((int8_t) suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId);
ftdm_assert(0, "Inconsistent call states\n");
@@ -296,12 +302,13 @@ void sngisdn_rcv_dat_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, In
void sngisdn_rcv_sshl_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, SsHlEvnt *ssHlEvnt, uint8_t action)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info;
sngisdn_event_data_t *sngisdn_event = NULL;
+
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
- if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
- !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
+ if (!(spInstId && get_ftdmchan_by_spInstId((int8_t) suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
+ !(suInstId && get_ftdmchan_by_suInstId((int8_t) suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId);
ftdm_assert(0, "Inconsistent call states\n");
@@ -329,12 +336,13 @@ void sngisdn_rcv_sshl_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, S
void sngisdn_rcv_sshl_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, SsHlEvnt *ssHlEvnt, uint8_t action)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info;
sngisdn_event_data_t *sngisdn_event = NULL;
+
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
- if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
- !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
+ if (!(spInstId && get_ftdmchan_by_spInstId((int8_t) suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
+ !(suInstId && get_ftdmchan_by_suInstId((int8_t) suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId);
ftdm_assert(0, "Inconsistent call states\n");
@@ -361,12 +369,13 @@ void sngisdn_rcv_sshl_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, S
}
void sngisdn_rcv_rmrt_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info;
sngisdn_event_data_t *sngisdn_event = NULL;
+
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
- if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
- !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
+ if (!(spInstId && get_ftdmchan_by_spInstId((int8_t) suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
+ !(suInstId && get_ftdmchan_by_suInstId((int8_t) suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId);
ftdm_assert(0, "Inconsistent call states\n");
@@ -394,12 +403,13 @@ void sngisdn_rcv_rmrt_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, R
void sngisdn_rcv_rmrt_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info;
sngisdn_event_data_t *sngisdn_event = NULL;
+
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
- if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
- !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
+ if (!(spInstId && get_ftdmchan_by_spInstId((int8_t) suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
+ !(suInstId && get_ftdmchan_by_suInstId((int8_t) suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId);
ftdm_assert(0, "Inconsistent call states\n");
@@ -427,12 +437,13 @@ void sngisdn_rcv_rmrt_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, R
void sngisdn_rcv_flc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, StaEvnt *staEvnt)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info;
sngisdn_event_data_t *sngisdn_event = NULL;
+
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
- if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
- !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
+ if (!(spInstId && get_ftdmchan_by_spInstId((int8_t) suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
+ !(suInstId && get_ftdmchan_by_suInstId((int8_t) suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId);
ftdm_assert(0, "Inconsistent call states\n");
@@ -460,12 +471,13 @@ void sngisdn_rcv_flc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, St
void sngisdn_rcv_fac_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, FacEvnt *facEvnt, uint8_t evntType, int16_t dChan, uint8_t ces)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info;
sngisdn_event_data_t *sngisdn_event = NULL;
+
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
- if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
- !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
+ if (!(spInstId && get_ftdmchan_by_spInstId((int8_t) suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
+ !(suInstId && get_ftdmchan_by_suInstId((int8_t) suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId);
ftdm_assert(0, "Inconsistent call states\n");
@@ -493,12 +505,13 @@ void sngisdn_rcv_fac_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, Fa
void sngisdn_rcv_sta_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, StaEvnt *staEvnt)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
sngisdn_chan_data_t *sngisdn_info;
sngisdn_event_data_t *sngisdn_event = NULL;
+
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
- if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
- !(suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
+ if (!(spInstId && get_ftdmchan_by_spInstId((int8_t) suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
+ !(suInstId && get_ftdmchan_by_suInstId((int8_t) suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId);
ftdm_assert(0, "Inconsistent call states\n");
@@ -525,11 +538,12 @@ void sngisdn_rcv_sta_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, St
void sngisdn_rcv_srv_ind (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
unsigned i;
sngisdn_span_data_t *signal_data;
sngisdn_event_data_t *sngisdn_event = NULL;
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
+
ftdm_log(FTDM_LOG_INFO, "Received SERVICE IND (dChan:%d ces:%u)\n", dChan, ces);
/* Enqueue the event to each span within the dChan */
@@ -554,11 +568,12 @@ void sngisdn_rcv_srv_ind (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces
void sngisdn_rcv_srv_cfm (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
unsigned i;
sngisdn_span_data_t *signal_data = NULL;
sngisdn_event_data_t *sngisdn_event = NULL;
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
+
ftdm_log(FTDM_LOG_INFO, "Received SERVICE CFM (dChan:%d ces:%u)\n", dChan, ces);
/* Enqueue the event to each span within the dChan */
@@ -582,11 +597,12 @@ void sngisdn_rcv_srv_cfm (int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces
void sngisdn_rcv_rst_ind (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
unsigned i;
sngisdn_span_data_t *signal_data = NULL;
sngisdn_event_data_t *sngisdn_event = NULL;
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
+
ftdm_log(FTDM_LOG_INFO, "Received RESTART IND (dChan:%d ces:%u type:%u)\n", dChan, ces, evntType);
/* Enqueue the event to each span within the dChan */
@@ -612,11 +628,12 @@ void sngisdn_rcv_rst_ind (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces
void sngisdn_rcv_rst_cfm (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType)
{
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
unsigned i;
sngisdn_span_data_t *signal_data;
sngisdn_event_data_t *sngisdn_event = NULL;
+ ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
+
ftdm_log(FTDM_LOG_INFO, "Received RESTART CFM (dChan:%d ces:%u type:%u)\n", dChan, ces, evntType);
/* Enqueue the event to each span within the dChan */
@@ -706,7 +723,7 @@ void sngisdn_rcv_q931_ind(InMngmt *status)
ftdm_span_t *ftdmspan;
sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[status->t.usta.suId];
if (!signal_data) {
- ftdm_log(FTDM_LOG_INFO, "Received q921 status on unconfigured span (lnkNmb:%d)\n", status->t.usta.suId);
+ ftdm_log(FTDM_LOG_INFO, "Received q931 status on unconfigured span (lnkNmb:%d)\n", status->t.usta.suId);
return;
}
ftdmspan = signal_data->ftdm_span;
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c
index db22fe5ce8..5cc17a539a 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c
@@ -49,7 +49,7 @@ ftdm_status_t sngisdn_check_free_ids(void);
extern ftdm_sngisdn_data_t g_sngisdn_data;
void get_memory_info(void);
-void __inline__ clear_call_data(sngisdn_chan_data_t *sngisdn_info)
+FT_DECLARE_INLINE(void) clear_call_data(sngisdn_chan_data_t *sngisdn_info)
{
uint32_t cc_id = ((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->cc_id;
@@ -66,7 +66,7 @@ void __inline__ clear_call_data(sngisdn_chan_data_t *sngisdn_info)
return;
}
-void __inline__ clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info)
+FT_DECLARE_INLINE(void) clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info)
{
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_DEBUG, "Clearing glare data (suId:%d suInstId:%u spInstId:%u actv-suInstId:%u actv-spInstId:%u)\n",
sngisdn_info->glare.suId,
@@ -91,7 +91,7 @@ void __inline__ clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info)
}
-uint32_t __inline__ get_unique_suInstId(uint8_t cc_id)
+FT_DECLARE_INLINE(uint32_t) get_unique_suInstId(uint8_t cc_id)
{
uint32_t suInstId;
ftdm_mutex_lock(g_sngisdn_data.ccs[cc_id].mutex);
@@ -112,7 +112,7 @@ uint32_t __inline__ get_unique_suInstId(uint8_t cc_id)
return 0;
}
-ftdm_status_t __inline__ get_ftdmchan_by_suInstId(uint8_t cc_id, uint32_t suInstId, sngisdn_chan_data_t **sngisdn_data)
+FT_DECLARE_INLINE(ftdm_status_t) get_ftdmchan_by_suInstId(uint8_t cc_id, uint32_t suInstId, sngisdn_chan_data_t **sngisdn_data)
{
ftdm_assert_return(g_sngisdn_data.ccs[cc_id].activation_done, FTDM_FAIL, "Trying to find call on unconfigured CC\n");
@@ -123,7 +123,7 @@ ftdm_status_t __inline__ get_ftdmchan_by_suInstId(uint8_t cc_id, uint32_t suInst
return FTDM_SUCCESS;
}
-ftdm_status_t __inline__ get_ftdmchan_by_spInstId(uint8_t cc_id, uint32_t spInstId, sngisdn_chan_data_t **sngisdn_data)
+FT_DECLARE_INLINE(ftdm_status_t) get_ftdmchan_by_spInstId(uint8_t cc_id, uint32_t spInstId, sngisdn_chan_data_t **sngisdn_data)
{
ftdm_assert_return(g_sngisdn_data.ccs[cc_id].activation_done, FTDM_FAIL, "Trying to find call on unconfigured CC\n");
@@ -188,11 +188,11 @@ ftdm_status_t cpy_called_num_from_stack(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPt
}
if (cdPtyNmb->nmbPlanId.pres == PRSNT_NODEF) {
- ftdm->cid_num.plan = cdPtyNmb->nmbPlanId.val;
+ ftdm->dnis.plan = cdPtyNmb->nmbPlanId.val;
}
if (cdPtyNmb->typeNmb0.pres == PRSNT_NODEF) {
- ftdm->cid_num.type = cdPtyNmb->typeNmb0.val;
+ ftdm->dnis.type = cdPtyNmb->typeNmb0.val;
}
if (cdPtyNmb->nmbDigits.pres == PRSNT_NODEF) {
@@ -424,11 +424,15 @@ void sngisdn_delayed_disconnect(void* p_sngisdn_info)
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
ftdm_mutex_lock(ftdmchan->mutex);
- if (ftdmchan->state != FTDM_CHANNEL_STATE_DOWN) {
+ if (ftdmchan->caller_data.hangup_cause == IN_CCNORTTODEST || ftdmchan->state != FTDM_CHANNEL_STATE_DOWN) {
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending delayed DISCONNECT (suId:%d suInstId:%u spInstId:%u)\n",
signal_data->cc_id, sngisdn_info->glare.spInstId, sngisdn_info->glare.suInstId);
sngisdn_snd_disconnect(ftdmchan);
+ if (ftdmchan->caller_data.hangup_cause == IN_CCNORTTODEST) {
+ ftdm_channel_t *close_chan = ftdmchan;
+ ftdm_channel_close(&close_chan);
+ }
}
ftdm_mutex_unlock(ftdmchan->mutex);
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c
index 7d4d347eab..624d35c147 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_trace.c
@@ -100,7 +100,7 @@ uint8_t get_bits(uint8_t octet, uint8_t bitLo, uint8_t bitHi)
void sngisdn_trace_q921(char* str, uint8_t* data, uint32_t data_len)
{
int str_len;
- int i;
+ uint32_t i;
uint8_t sapi, cr, ea, tei, ns, nr, pf, p, cmd;
uint8_t frame_format = 0;
@@ -649,7 +649,7 @@ uint32_t sngisdn_decode_ie(char *str, uint32_t *str_len, uint8_t current_codeset
void print_hex_dump(char* str, uint32_t *str_len, uint8_t* data, uint32_t index_start, uint32_t index_end)
{
- int k;
+ uint32_t k;
*str_len += sprintf(&str[*str_len], " [ ");
for(k=index_start; k <= index_end; k++) {
if (k && !(k%32)) {
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c
index 21ab1d32d2..87d80f18a4 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c
@@ -85,35 +85,35 @@ int ft_to_sngss7_cfg_all(void)
if (ftmod_ss7_mtp1_gen_config()) {
SS7_CRITICAL("MTP1 General configuration FAILED!\n");
- SS7_ASSERT
+ return 1;
} else {
SS7_INFO("MTP1 General configuration DONE\n");
}
if (ftmod_ss7_mtp2_gen_config()) {
SS7_CRITICAL("MTP2 General configuration FAILED!\n");
- SS7_ASSERT
+ return 1;
} else {
SS7_INFO("MTP2 General configuration DONE\n");
}
if (ftmod_ss7_mtp3_gen_config()) {
SS7_CRITICAL("MTP3 General configuration FAILED!\n");
- SS7_ASSERT
+ return 1;
} else {
SS7_INFO("MTP3 General configuration DONE\n");
}
if (ftmod_ss7_isup_gen_config()) {
SS7_CRITICAL("ISUP General configuration FAILED!\n");
- SS7_ASSERT
+ return 1;
} else {
SS7_INFO("ISUP General configuration DONE\n");
}
if (ftmod_ss7_cc_gen_config()) {
SS7_CRITICAL("CC General configuration FAILED!\n");
- SS7_ASSERT
+ return 1;
} else {
SS7_INFO("CC General configuration DONE\n");
}
@@ -131,7 +131,7 @@ int ft_to_sngss7_cfg_all(void)
/* configure mtp1 */
if (ftmod_ss7_mtp1_psap_config(x)) {
SS7_CRITICAL("MTP1 PSAP %d configuration FAILED!\n", x);
- SS7_ASSERT;
+ return 1;;
} else {
SS7_INFO("MTP1 PSAP %d configuration DONE!\n", x);
}
@@ -139,7 +139,7 @@ int ft_to_sngss7_cfg_all(void)
/* configure mtp2 */
if (ftmod_ss7_mtp2_dlsap_config(x)) {
SS7_CRITICAL("MTP2 DLSAP %d configuration FAILED!\n",x);
- SS7_ASSERT;
+ return 1;;
} else {
SS7_INFO("MTP2 DLSAP %d configuration DONE!\n", x);
}
@@ -147,7 +147,7 @@ int ft_to_sngss7_cfg_all(void)
/* configure mtp3 */
if (ftmod_ss7_mtp3_dlsap_config(x)) {
SS7_CRITICAL("MTP3 DLSAP %d configuration FAILED!\n", x);
- SS7_ASSERT;
+ return 1;;
} else {
SS7_INFO("MTP3 DLSAP %d configuration DONE!\n", x);
}
@@ -166,14 +166,14 @@ int ft_to_sngss7_cfg_all(void)
if (ftmod_ss7_mtp3_nsap_config(x)) {
SS7_CRITICAL("MTP3 NSAP %d configuration FAILED!\n", x);
- SS7_ASSERT
+ return 1;
} else {
SS7_INFO("MTP3 NSAP %d configuration DONE!\n", x);
}
if (ftmod_ss7_isup_nsap_config(x)) {
SS7_CRITICAL("ISUP NSAP %d configuration FAILED!\n", x);
- SS7_ASSERT
+ return 1;
} else {
SS7_INFO("ISUP NSAP %d configuration DONE!\n", x);
}
@@ -192,7 +192,7 @@ int ft_to_sngss7_cfg_all(void)
if (ftmod_ss7_mtp3_linkset_config(x)) {
SS7_CRITICAL("MTP3 LINKSET %d configuration FAILED!\n", x);
- SS7_ASSERT
+ return 1;
} else {
SS7_INFO("MTP3 LINKSET %d configuration DONE!\n", x);
}
@@ -211,7 +211,7 @@ int ft_to_sngss7_cfg_all(void)
if (ftmod_ss7_mtp3_route_config(x)) {
SS7_CRITICAL("MTP3 ROUTE %d configuration FAILED!\n", x);
- SS7_ASSERT
+ return 1;
} else {
SS7_INFO("MTP3 ROUTE %d configuration DONE!\n",x);
}
@@ -227,7 +227,7 @@ int ft_to_sngss7_cfg_all(void)
if (ftmod_ss7_mtp3_route_config(0)) {
SS7_CRITICAL("MTP3 ROUTE 0 configuration FAILED!\n");
- SS7_ASSERT
+ return 1;
} else {
SS7_INFO("MTP3 ROUTE 0 configuration DONE!\n");
}
@@ -244,14 +244,14 @@ int ft_to_sngss7_cfg_all(void)
if (ftmod_ss7_isup_isap_config(x)) {
SS7_CRITICAL("ISUP ISAP %d configuration FAILED!\n", x);
- SS7_ASSERT
+ return 1;
} else {
SS7_INFO("ISUP ISAP %d configuration DONE!\n", x);
}
if (ftmod_ss7_cc_isap_config(x)) {
SS7_CRITICAL("CC ISAP %d configuration FAILED!\n", x);
- SS7_ASSERT
+ return 1;
} else {
SS7_INFO("CC ISAP %d configuration DONE!\n", x);
}
@@ -270,9 +270,11 @@ int ft_to_sngss7_cfg_all(void)
if (ftmod_ss7_isup_intf_config(x)) {
SS7_CRITICAL("ISUP INTF %d configuration FAILED!\n", x);
- SS7_ASSERT
+ 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 CONFIGURED flag */
@@ -289,7 +291,7 @@ int ft_to_sngss7_cfg_all(void)
if ( g_ftdm_sngss7_data.cfg.isupCkt[x].type == 0) {
if (ftmod_ss7_isup_ckt_config(x)) {
SS7_CRITICAL("ISUP CKT %d configuration FAILED!\n", x);
- SS7_ASSERT
+ return 1;
} else {
SS7_INFO("ISUP CKT %d configuration DONE!\n", x);
}
@@ -1018,8 +1020,8 @@ int ftmod_ss7_mtp3_route_config(int id)
cfg.t.cfg.s.snRout.slsRange = LSN_ANSI_5BIT_SLS_RANGE; /* max value of SLS for this DPC */
}
cfg.t.cfg.s.snRout.lsetSel = 0x1; /* linkset selection bit in SLS for STP */
- cfg.t.cfg.s.snRout.multiMsgPrior = FALSE; /* TRUE if multiple cong priorities of messages */
- cfg.t.cfg.s.snRout.rctReq = TRUE; /* route set congestion test required or not */
+ cfg.t.cfg.s.snRout.multiMsgPrior = TRUE; /* TRUE if multiple cong priorities of messages */
+ cfg.t.cfg.s.snRout.rctReq = TRUE; /* route set congestion test required or not */
cfg.t.cfg.s.snRout.slsLnk = FALSE;
#ifdef LSNV2
# if (SS7_NTT || defined(TDS_ROLL_UPGRADE_SUPPORT))
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c
index cf56f51a0a..38d3723061 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c
@@ -240,9 +240,7 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha
/**********************************************************************/
} else if (!strcasecmp(argv[c], "mem")) {
/**********************************************************************/
- /*uint32_t availMem;*/
-
- /*sng_sta_mem(&availMem);*/
+ sng_isup_reg_info_show();
/**********************************************************************/
} else if (!strcasecmp(argv[c], "stats")) {
/**********************************************************************/
@@ -618,8 +616,8 @@ static ftdm_status_t handle_print_usuage(ftdm_stream_handle_t *stream)
stream->write_function(stream, "Sangoma SS7 CLI usuage:\n\n");
stream->write_function(stream, "Ftmod_sangoma_ss7 general control:\n");
- stream->write_function(stream, "ftdm ss7 set ftace X Y\n");
- stream->write_function(stream, "ftdm ss7 set mtace X Y\n");
+ stream->write_function(stream, "ftdm ss7 set ftrace X Y\n");
+ stream->write_function(stream, "ftdm ss7 set mtrace X Y\n");
stream->write_function(stream, "\n");
stream->write_function(stream, "Ftmod_sangoma_ss7 information:\n");
stream->write_function(stream, "ftdm ss7 show status link X\n");
@@ -1066,7 +1064,7 @@ static ftdm_status_t handle_show_status(ftdm_stream_handle_t *stream, int span,
/* grab the signaling_status */
ftdm_channel_get_sig_status(ftdmchan, &sigstatus);
- stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|sig_status=%s|state=%s|",
+ stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|sig_status=%4s|state=%s|",
ckt->span,
ckt->chan,
ckt->cic,
@@ -1156,7 +1154,12 @@ static ftdm_status_t handle_tx_blo(ftdm_stream_handle_t *stream, int span, int c
/* check if there is a pending state change|give it a bit to clear */
if (check_for_state_change(ftdmchan)) {
SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", ss7_info->circuit->cic);
+ /* check if we need to die */
SS7_ASSERT;
+ /* unlock the channel again before we exit */
+ ftdm_mutex_unlock(ftdmchan->mutex);
+ /* move to the next channel */
+ continue;
} else {
/* throw the ckt block flag */
sngss7_set_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX);
@@ -1217,7 +1220,12 @@ static ftdm_status_t handle_tx_ubl(ftdm_stream_handle_t *stream, int span, int c
/* check if there is a pending state change|give it a bit to clear */
if (check_for_state_change(ftdmchan)) {
SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", ss7_info->circuit->cic);
+ /* check if we need to die */
SS7_ASSERT;
+ /* unlock the channel again before we exit */
+ ftdm_mutex_unlock(ftdmchan->mutex);
+ /* move to the next channel */
+ continue;
} else {
/* throw the ckt block flag */
sngss7_set_flag(ss7_info, FLAG_CKT_MN_UNBLK_TX);
@@ -1273,13 +1281,17 @@ static ftdm_status_t handle_status_link(ftdm_stream_handle_t *stream, char *name
(sta.t.ssta.s.snDLSAP.remBlkd) ? "Y":"N",
(sta.t.ssta.s.snDLSAP.locInhbt) ? "Y":"N",
(sta.t.ssta.s.snDLSAP.rmtInhbt) ? "Y":"N");
- break;
+
+ goto success;
}
/* move to the next link */
x++;
} /* while (id != 0) */
+ stream->write_function(stream, "Failed to find link=\"%s\"\n", name);
+
+success:
return FTDM_SUCCESS;
}
@@ -1305,13 +1317,17 @@ static ftdm_status_t handle_status_linkset(ftdm_stream_handle_t *stream, char *n
name,
DECODE_LSN_LINKSET_STATUS(sta.t.ssta.s.snLnkSet.state),
sta.t.ssta.s.snLnkSet.nmbActLnks);
- break;
+
+ goto success;
}
/* move to the next linkset */
x++;
} /* while (id != 0) */
+ stream->write_function(stream, "Failed to find link=\"%s\"\n", name);
+
+success:
return FTDM_SUCCESS;
}
@@ -1334,13 +1350,16 @@ static ftdm_status_t handle_set_inhibit(ftdm_stream_handle_t *stream, char *name
/* print the new status of the link */
handle_status_link(stream, &name[0]);
- break;
+ goto success;
}
/* move to the next linkset */
x++;
} /* while (id != 0) */
+ stream->write_function(stream, "Failed to find link=\"%s\"\n", name);
+
+success:
return FTDM_SUCCESS;
}
@@ -1363,13 +1382,16 @@ static ftdm_status_t handle_set_uninhibit(ftdm_stream_handle_t *stream, char *na
/* print the new status of the link */
handle_status_link(stream, &name[0]);
- break;
+ goto success;
}
/* move to the next linkset */
x++;
} /* while (id != 0) */
+ stream->write_function(stream, "Failed to find link=\"%s\"\n", name);
+
+success:
return FTDM_SUCCESS;
}
@@ -1432,6 +1454,10 @@ static ftdm_status_t handle_tx_rsc(ftdm_stream_handle_t *stream, int span, int c
/* go the next circuit */
x++;
} /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */
+
+ /* print the status of channels */
+ handle_show_status(stream, span, chan, verbose);
+
return FTDM_SUCCESS;
@@ -1466,7 +1492,12 @@ static ftdm_status_t handle_tx_grs(ftdm_stream_handle_t *stream, int span, int c
/* check if there is a pending state change|give it a bit to clear */
if (check_for_state_change(ftdmchan)) {
SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic);
+ /* check if we need to die */
SS7_ASSERT;
+ /* unlock the channel again before we exit */
+ ftdm_mutex_unlock(ftdmchan->mutex);
+ /* move to the next channel */
+ continue;
} else {
/* throw the grp reset flag */
sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX);
@@ -1492,6 +1523,24 @@ static ftdm_status_t handle_tx_grs(ftdm_stream_handle_t *stream, int span, int c
x++;
} /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */
+ x=1;
+ while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) {
+ if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) {
+
+ sngss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj;
+ ftdmchan = sngss7_info->ftdmchan;
+ sngss7_span = ftdmchan->span->mod_data;
+
+ if ((ftdmchan->physical_span_id == span) &&
+ ((ftdmchan->physical_chan_id >= chan) && (ftdmchan->physical_chan_id < (chan+range)))) {
+
+ handle_show_status(stream, span, chan, verbose);
+ }
+ } /* if ( cic == voice) */
+
+ /* go the next circuit */
+ x++;
+ } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */
return FTDM_SUCCESS;
}
@@ -1572,6 +1621,25 @@ static ftdm_status_t handle_tx_cgb(ftdm_stream_handle_t *stream, int span, int c
/* send the circuit group block */
ft_to_sngss7_cgb(main_chan);
+
+ x=1;
+ while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) {
+ if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) {
+
+ sngss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj;
+ ftdmchan = sngss7_info->ftdmchan;
+ sngss7_span = ftdmchan->span->mod_data;
+
+ if ((ftdmchan->physical_span_id == span) &&
+ ((ftdmchan->physical_chan_id >= chan) && (ftdmchan->physical_chan_id < (chan+range)))) {
+
+ handle_show_status(stream, span, chan, verbose);
+ }
+ } /* if ( cic == voice) */
+
+ /* go the next circuit */
+ x++;
+ } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */
return FTDM_SUCCESS;
@@ -1653,6 +1721,25 @@ static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int c
/* send the circuit group block */
ft_to_sngss7_cgu(main_chan);
+
+ x=1;
+ while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) {
+ if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) {
+
+ sngss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj;
+ ftdmchan = sngss7_info->ftdmchan;
+ sngss7_span = ftdmchan->span->mod_data;
+
+ if ((ftdmchan->physical_span_id == span) &&
+ ((ftdmchan->physical_chan_id >= chan) && (ftdmchan->physical_chan_id < (chan+range)))) {
+
+ handle_show_status(stream, span, chan, verbose);
+ }
+ } /* if ( cic == voice) */
+
+ /* go the next circuit */
+ x++;
+ } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */
return FTDM_SUCCESS;
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c
index 0d76329d25..87733dd594 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c
@@ -75,7 +75,7 @@ int ft_to_sngss7_activate_all(void)
if (ftmod_ss7_enable_isap(x)) {
SS7_CRITICAL("ISAP %d Enable: NOT OK\n", x);
- SS7_ASSERT;
+ return 1;
} else {
SS7_INFO("ISAP %d Enable: OK\n", x);
}
@@ -94,7 +94,7 @@ int ft_to_sngss7_activate_all(void)
if (ftmod_ss7_enable_nsap(x)) {
SS7_CRITICAL("NSAP %d Enable: NOT OK\n", x);
- SS7_ASSERT;
+ return 1;
} else {
SS7_INFO("NSAP %d Enable: OK\n", x);
}
@@ -113,7 +113,7 @@ int ft_to_sngss7_activate_all(void)
if (ftmod_ss7_enable_mtpLinkSet(x)) {
SS7_CRITICAL("LinkSet \"%s\" Enable: NOT OK\n", g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name);
- SS7_ASSERT;
+ return 1;
} else {
SS7_INFO("LinkSet \"%s\" Enable: OK\n", g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name);
}
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c
index 5e6a246ba2..af3b9edbae 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c
@@ -51,6 +51,8 @@ ftdm_status_t handle_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
ftdm_status_t handle_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt);
ftdm_status_t handle_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt);
ftdm_status_t handle_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit);
+ftdm_status_t handle_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt);
+ftdm_status_t handle_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt);
ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
@@ -73,6 +75,7 @@ ftdm_status_t handle_local_ubl(uint32_t suInstId, uint32_t spInstId, uint32_t ci
ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
+ftdm_status_t handle_olm_msg(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
/******************************************************************************/
/* FUNCTIONS ******************************************************************/
@@ -208,10 +211,28 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/* add any special variables for the dialplan */
sprintf(nadi, "%d", siConEvnt->cgPtyNum.natAddrInd.val);
- ftdm_channel_add_var(ftdmchan, "ss7_nadi", nadi);
+ ftdm_channel_add_var(ftdmchan, "ss7_clg_nadi", nadi);
- /* set the state of the channel to collecting...the rest is done by the chan monitor */
- ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_COLLECT);
+ sprintf(nadi, "%d", siConEvnt->cdPtyNum.natAddrInd.val);
+ ftdm_channel_add_var(ftdmchan, "ss7_cld_nadi", nadi);
+
+
+ /* check if a COT test is requested */
+ if ((siConEvnt->natConInd.eh.pres) &&
+ (siConEvnt->natConInd.contChkInd.pres) &&
+ (siConEvnt->natConInd.contChkInd.val)) {
+
+ SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Found COT Request\n", sngss7_info->circuit->cic);
+
+ /* tell the core to loop the channel */
+ ftdm_channel_command(ftdmchan, FTDM_COMMAND_ENABLE_LOOP, NULL);
+
+ /* move to in loop state */
+ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IN_LOOP);
+ } else {
+ /* set the state of the channel to collecting...the rest is done by the chan monitor */
+ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_COLLECT);
+ }
} /* if (channel is usable */
@@ -250,6 +271,9 @@ handle_glare:
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_flag(sngss7_info, FLAG_RESET_TX);
+
/* move the state of the channel to RESTART to force a reset */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
@@ -286,6 +310,7 @@ ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/**************************************************************************/
case (ADDRCMPLT):
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx ACM\n", sngss7_info->circuit->cic);
+
switch (ftdmchan->state) {
/**********************************************************************/
case FTDM_CHANNEL_STATE_DIALING:
@@ -294,16 +319,37 @@ ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/* need to grab the sp instance id */
sngss7_info->spInstId = spInstId;
- /* go to PROGRESS */
- ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
- break;
+ if ((siCnStEvnt->optBckCalInd.eh.pres) &&
+ (siCnStEvnt->optBckCalInd.inbndInfoInd.pres)) {
+
+ if (siCnStEvnt->optBckCalInd.inbndInfoInd.val) {
+ /* go to PROGRESS_MEDIA */
+ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
+ } else {
+ /* go to PROGRESS */
+ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
+ } /* if (inband) */
+ } else {
+ /* go to PROGRESS_MEDIA */
+ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
+ }
+
+ break;
/**********************************************************************/
default: /* incorrect state...reset the CIC */
+ SS7_ERROR_CHAN(ftdmchan, "RX ACM in invalid state :%s...resetting CIC\n",
+ ftdm_channel_state2str (ftdmchan->state));
+
+ /* reset the cic */
+ sngss7_set_flag(sngss7_info, FLAG_RESET_TX);
+
/* go to RESTART */
- ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
- break;
+ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
+ break;
/**********************************************************************/
} /* switch (ftdmchan->state) */
+
+ break;
/**************************************************************************/
case (MODIFY):
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx MODIFY\n", sngss7_info->circuit->cic);
@@ -335,6 +381,34 @@ ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/**************************************************************************/
case (SUBSADDR):
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx SAM\n", sngss7_info->circuit->cic);
+
+ /* check the channel state */
+ switch (ftdmchan->state) {
+ /**********************************************************************/
+ case (FTDM_CHANNEL_STATE_COLLECT):
+
+ /* confirm that the event contains the subsquent number field */
+ if (siCnStEvnt->subNum.eh.pres && siCnStEvnt->subNum.addrSig.pres) {
+ /* add the digits to the ftdm channel variable */
+ append_tknStr_from_sngss7(siCnStEvnt->subNum.addrSig,
+ ftdmchan->caller_data.dnis.digits,
+ siCnStEvnt->subNum.oddEven);
+ } else {
+ SS7_INFO_CHAN(ftdmchan,"No Called party (DNIS) information in SAM!%s\n", " ");
+ }
+
+ /* go to idle so that collect state is processed again */
+ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE);
+
+ break;
+ /**********************************************************************/
+ default:
+ SS7_ERROR_CHAN(ftdmchan, "RX SAM in invalid state :%s...ignoring\n",
+ ftdm_channel_state2str (ftdmchan->state));
+ break;
+ /**********************************************************************/
+ } /* switch (ftdmchan->state) */
+
break;
/**************************************************************************/
case (EXIT):
@@ -524,7 +598,7 @@ ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/* this is a remote hangup request */
sngss7_set_flag(sngss7_info, FLAG_REMOTE_REL);
-
+ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL);
/* move the state of the channel to CANCEL to end the call */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
@@ -539,7 +613,7 @@ ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
if (siRelEvnt->causeDgn.causeVal.pres) {
ftdmchan->caller_data.hangup_cause = siRelEvnt->causeDgn.causeVal.val;
} else {
- SS7_ERROR("REL does not have a cause code!\n");
+ SS7_ERROR("REL does not have a cause ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL);code!\n");
ftdmchan->caller_data.hangup_cause = 0;
}
@@ -551,6 +625,23 @@ ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
break;
/**************************************************************************/
+ case FTDM_CHANNEL_STATE_IN_LOOP:
+
+ /* inform the core to unloop the channel*/
+ ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL);
+
+ /* since we need to acknowledge the hang up set the flag for remote release */
+ sngss7_set_flag(sngss7_info, FLAG_REMOTE_REL);
+
+ /* go to hangup complete to send the RLC */
+ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
+
+ /* save the call info for the RLC */
+ sngss7_info->suInstId = get_unique_id();
+ sngss7_info->spInstId = spInstId;
+
+ break;
+ /**************************************************************************/
default:
/* throw the reset flag */
@@ -729,6 +820,60 @@ ftdm_status_t handle_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t cir
return FTDM_SUCCESS;
}
+/******************************************************************************/
+ftdm_status_t handle_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt)
+{
+ SS7_FUNC_TRACE_ENTER(__FUNCTION__);
+
+ sngss7_chan_data_t *sngss7_info ;
+ ftdm_channel_t *ftdmchan;
+
+ /* 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);
+ SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+ return FTDM_FAIL;
+ }
+
+ /* lock the channel */
+ ftdm_mutex_lock(ftdmchan->mutex);
+
+ SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Call-Suspend msg\n", sngss7_info->circuit->cic);
+
+ /* unlock the channel */
+ ftdm_mutex_unlock(ftdmchan->mutex);
+
+ SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+ return FTDM_SUCCESS;
+}
+
+/******************************************************************************/
+ftdm_status_t handle_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt)
+{
+ SS7_FUNC_TRACE_ENTER(__FUNCTION__);
+
+ sngss7_chan_data_t *sngss7_info ;
+ ftdm_channel_t *ftdmchan;
+
+ /* 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);
+ SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+ return FTDM_FAIL;
+ }
+
+ /* lock the channel */
+ ftdm_mutex_lock(ftdmchan->mutex);
+
+ SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Call-Resume msg\n", sngss7_info->circuit->cic);
+
+ /* unlock the channel */
+ ftdm_mutex_unlock(ftdmchan->mutex);
+
+ SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+ return FTDM_SUCCESS;
+}
+
/******************************************************************************/
ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
{
@@ -757,7 +902,7 @@ ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
break;
/**************************************************************************/
case SIT_STA_CONTCHK: /* continuity check */
- SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx COT start\n", sngss7_info->circuit->cic);
+ SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CCR start\n", sngss7_info->circuit->cic);
handle_cot_start(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
break;
/**************************************************************************/
@@ -767,7 +912,7 @@ ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
break;
/**************************************************************************/
case SIT_STA_STPCONTIN: /* stop continuity */
- SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx COT stop\n", sngss7_info->circuit->cic);
+ SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx CCR stop\n", sngss7_info->circuit->cic);
handle_cot_stop(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
break;
/**************************************************************************/
@@ -928,7 +1073,7 @@ ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/**************************************************************************/
case SIT_STA_OVERLOAD: /* Overload */
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Overload\n", sngss7_info->circuit->cic);
- SS7_WARN(" %s indication not currently supported\n", DECODE_LCC_EVENT(evntType));
+ handle_olm_msg(suInstId, spInstId, circuit, globalFlg, evntType, siStaEvnt);
break;
/**************************************************************************/
case SIT_STA_LMCGBREQ: /* when LM requests ckt grp blocking */
@@ -1029,6 +1174,9 @@ ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circui
/* extract the affected infId from the circuit structure */
infId = g_ftdm_sngss7_data.cfg.isupCkt[circuit].infId;
+
+ /* set the interface to paused */
+ sngss7_set_flag(&g_ftdm_sngss7_data.cfg.isupIntf[infId], SNGSS7_PAUSED);
/* go through all the circuits now and find any other circuits on this infId */
i = 1;
@@ -1050,6 +1198,7 @@ ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circui
/* check if the circuit is fully started */
if (ftdm_test_flag(ftdmchan->span, FTDM_SPAN_IN_THREAD)) {
+ SS7_DEBUG_CHAN(ftdmchan, "Rx PAUSE%s\n", "");
/* set the pause flag on the channel */
sngss7_set_flag(sngss7_info, FLAG_INFID_PAUSED);
}
@@ -1081,6 +1230,9 @@ ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circu
/* extract the affect infId from the circuit structure */
infId = g_ftdm_sngss7_data.cfg.isupCkt[circuit].infId;
+ /* set the interface to resumed */
+ sngss7_clear_flag(&g_ftdm_sngss7_data.cfg.isupIntf[infId], SNGSS7_PAUSED);
+
/* go through all the circuits now and find any other circuits on this infId */
i = 1;
while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) {
@@ -1101,6 +1253,8 @@ ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circu
/* only resume if we are paused */
if (sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) {
+ SS7_DEBUG_CHAN(ftdmchan, "Rx RESUME%s\n", "");
+
/* set the resume flag on the channel */
sngss7_set_flag(sngss7_info, FLAG_INFID_RESUME);
@@ -1143,7 +1297,7 @@ ftdm_status_t handle_cot_start(uint32_t suInstId, uint32_t spInstId, uint32_t ci
/* open the channel if it is not open */
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) {
if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
- SS7_ERROR("Failed to open CIC %d for COT test!\n", sngss7_info->circuit->cic);
+ SS7_ERROR("Failed to open CIC %d for CCR test!\n", sngss7_info->circuit->cic);
/* KONRAD FIX ME */
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_FAIL;
@@ -1156,15 +1310,6 @@ ftdm_status_t handle_cot_start(uint32_t suInstId, uint32_t spInstId, uint32_t ci
/* switch to the IN_LOOP state */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IN_LOOP);
- /* store the sngss7 ids */
- if (suInstId == 0) {
- sngss7_info->suInstId = get_unique_id();
- } else {
- sngss7_info->suInstId = suInstId;
- }
- sngss7_info->spInstId = spInstId;
- sngss7_info->globalFlg = globalFlg;
-
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);
@@ -1208,6 +1353,38 @@ ftdm_status_t handle_cot(uint32_t suInstId, uint32_t spInstId, uint32_t circuit,
{
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
+ sngss7_chan_data_t *sngss7_info = NULL;
+ ftdm_channel_t *ftdmchan = NULL;
+
+ /* 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);
+ SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+ return FTDM_FAIL;
+ }
+
+ /* lock the channel */
+ ftdm_mutex_lock(ftdmchan->mutex);
+
+ switch (ftdmchan->state) {
+ /**************************************************************************/
+ case (FTDM_CHANNEL_STATE_IN_LOOP):
+ /* tell the core to stop looping the channel */
+ ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL);
+
+ /* exit out of the LOOP state and go to collect */
+ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_COLLECT);
+
+ break;
+ /**************************************************************************/
+ default:
+ /* exit out of the LOOP state to the last state */
+ ftdm_set_state_locked(ftdmchan, ftdmchan->last_state);
+
+ break;
+ /**************************************************************************/
+ } /* switch (ftdmchan->state) */
+
if ( (siStaEvnt->contInd.eh.pres > 0) && (siStaEvnt->contInd.contInd.pres > 0)) {
SS7_INFO("Continuity Test result for CIC = %d (span %d, chan %d) is: \"%s\"\n",
g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic,
@@ -1218,13 +1395,13 @@ ftdm_status_t handle_cot(uint32_t suInstId, uint32_t spInstId, uint32_t circuit,
SS7_ERROR("Recieved Continuity report containing no results!\n");
}
+ /* unlock the channel again before we exit */
+ ftdm_mutex_unlock(ftdmchan->mutex);
+
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_SUCCESS;
}
-/******************************************************************************/
-
-
/******************************************************************************/
ftdm_status_t handle_blo_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
{
@@ -1493,7 +1670,7 @@ ftdm_status_t handle_rsc_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sngss7_set_flag(sngss7_info, FLAG_RESET_TX_RSP);
/* go to DOWN */
- ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
+ /*ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);*/
break;
/**********************************************************************/
@@ -1527,7 +1704,7 @@ 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;
- int x;
+
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
@@ -1544,51 +1721,12 @@ ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
return FTDM_FAIL;
}
- /* 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 != 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;
- }
-
- /* lock the channel */
- ftdm_mutex_lock(ftdmchan->mutex);
+ /* fill in the span structure for this circuit */
+ sngss7_span = ftdmchan->span->mod_data;
+ sngss7_span->rx_grs.circuit = circuit;
+ sngss7_span->rx_grs.range = range;
- /* fill in the span structure for this circuit */
- sngss7_span = ftdmchan->span->mod_data;
- sngss7_span->rx_grs.circuit = circuit;
- sngss7_span->rx_grs.range = range;
-
- SS7_INFO_CHAN(ftdmchan, "Rx GRS (%d:%d)\n",
- g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic,
- (g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic + range));
-
- /* flag the channel as having received a reset */
- sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX);
-
- switch (ftdmchan->state) {
- /**************************************************************************/
- case FTDM_CHANNEL_STATE_RESTART:
-
- /* go to idle so that we can redo the restart state*/
- ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE);
-
- break;
- /**************************************************************************/
- default:
-
- /* set the state of the channel to restart...the rest is done by the chan monitor */
- ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
- break;
- /**************************************************************************/
- }
-
- /* unlock the channel again before we exit */
- ftdm_mutex_unlock(ftdmchan->mutex);
-
- }
+ /* the reset will be started in the main thread by "check_if_rx_grs_started" */
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_SUCCESS;
@@ -1599,10 +1737,16 @@ ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ
{
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
- sngss7_chan_data_t *sngss7_info = NULL;
- ftdm_channel_t *ftdmchan = NULL;
+ sngss7_chan_data_t *sngss7_info = NULL;
+ ftdm_channel_t *ftdmchan = NULL;
+ sngss7_span_data_t *sngss7_span = NULL;
int range;
- int x;
+
+ if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
+ SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
+ SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+ return FTDM_FAIL;
+ }
/* extract the range value from the event structure */
if ((siStaEvnt->rangStat.eh.pres == PRSNT_NODEF) && (siStaEvnt->rangStat.range.pres == PRSNT_NODEF)) {
@@ -1613,70 +1757,20 @@ ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ
return FTDM_FAIL;
}
- /* go through all the circuits in the range */
- for ( x = circuit; x < (circuit + range + 1); x++) {
+ /* fill in the span structure for this circuit */
+ sngss7_span = ftdmchan->span->mod_data;
+ sngss7_span->rx_gra.circuit = circuit;
+ sngss7_span->rx_gra.range = range;
- /* grab the circuit in question */
- if (extract_chan_data(x, &sngss7_info, &ftdmchan)) {
- SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit);
- break;
- }
+ /* check if there is a cause value in the GRA */
+ if ((siStaEvnt != NULL) &&
+ (siStaEvnt->causeDgn.eh.pres == PRSNT_NODEF) &&
+ (siStaEvnt->causeDgn.causeVal.pres == PRSNT_NODEF)) {
- /* lock the channel */
- ftdm_mutex_lock(ftdmchan->mutex);
-
- SS7_INFO_CHAN(ftdmchan, "Rx GRA (%d:%d)\n",
- g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic,
- (g_ftdm_sngss7_data.cfg.isupCkt[circuit].cic + range));
+ sngss7_span->rx_gra.cause = siStaEvnt->causeDgn.causeVal.val;
+ }
- switch (ftdmchan->state) {
- /**********************************************************************/
- case FTDM_CHANNEL_STATE_RESTART:
-
- /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */
- sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP);
-
- /* go to DOWN */
- ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
-
- break;
- /**********************************************************************/
- case FTDM_CHANNEL_STATE_DOWN:
-
- /* do nothing, just drop the message */
- SS7_DEBUG("Receveived GRA in down state, dropping\n");
-
- break;
- /**********************************************************************/
- case FTDM_CHANNEL_STATE_TERMINATING:
- case FTDM_CHANNEL_STATE_HANGUP:
- case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
-
- /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */
- sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP);
-
- break;
- /**********************************************************************/
- default:
- /* ITU Q764-2.9.5.1.c -> release the circuit */
- if ((siStaEvnt != NULL) &&
- (siStaEvnt->causeDgn.eh.pres ==PRSNT_NODEF) &&
- (siStaEvnt->causeDgn.causeVal.pres == PRSNT_NODEF)) {
- ftdmchan->caller_data.hangup_cause = siStaEvnt->causeDgn.causeVal.val;
- } else {
- ftdmchan->caller_data.hangup_cause = 98; /* Message not compatiable with call state */
- }
-
- /* go to terminating to hang up the call */
- ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
- break;
- /**********************************************************************/
- }
-
- /* unlock the channel again before we exit */
- ftdm_mutex_unlock(ftdmchan->mutex);
-
- } /* for (( x = 0; x < (circuit + range); x++) */
+ /* the reset will be started in the main thread by "check_if_rx_gra_started" */
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_SUCCESS;
@@ -1759,8 +1853,10 @@ ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit
{
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
- sngss7_chan_data_t *sngss7_info = NULL;
- ftdm_channel_t *ftdmchan = NULL;
+ sngss7_chan_data_t *sngss7_info = NULL;
+ sngss7_span_data_t *sngss7_span = NULL;
+ ftdm_channel_t *ftdmchan = NULL;
+
/* get the ftdmchan and ss7_chan_data from the circuit */
if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) {
@@ -1769,6 +1865,15 @@ ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit
return FTDM_FAIL;
}
+ /* check if we just sent a GRS request...*/
+ sngss7_span = ftdmchan->span->mod_data;
+ if (sngss7_span->tx_grs.circuit > 0) {
+ /* we need to put all circuits on this UCIC */
+ sngss7_span->ucic.circuit = sngss7_span->tx_grs.circuit;
+ sngss7_span->ucic.range = sngss7_span->tx_grs.range;
+ goto done;
+ }
+
/* lock the channel */
ftdm_mutex_lock(ftdmchan->mutex);
@@ -1780,7 +1885,7 @@ ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit
/* unlock the channel again before we exit */
ftdm_mutex_unlock(ftdmchan->mutex);
-
+done:
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_SUCCESS;
}
@@ -2057,6 +2162,30 @@ ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ
return FTDM_SUCCESS;
}
+/******************************************************************************/
+ftdm_status_t handle_olm_msg(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt)
+{
+ SS7_FUNC_TRACE_ENTER(__FUNCTION__);
+
+ sngss7_chan_data_t *sngss7_info = NULL;
+ ftdm_channel_t *ftdmchan = NULL;
+
+ /* 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);
+ SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+ return FTDM_FAIL;
+ }
+
+ /* handle overload */
+ SS7_ERROR_CHAN(ftdmchan,"[CIC:%d]Rx Overload\n", sngss7_info->circuit->cic);
+
+ sng_isup_reg_info_show();
+
+ SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+ return FTDM_SUCCESS;
+}
+
/******************************************************************************/
/* For Emacs:
* Local Variables:
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c
index 34893cf5aa..06fae0cd37 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c
@@ -52,7 +52,9 @@ void sngss7_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiIn
void sngss7_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt);
void sngss7_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt);
void sngss7_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit);
-
+void sngss7_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt);
+void sngss7_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt);
+void sngss7_ssp_sta_cfm(uint32_t infId);
/******************************************************************************/
/* FUNCTIONS ******************************************************************/
@@ -442,7 +444,127 @@ void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint
}
/******************************************************************************/
+void sngss7_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt)
+{
+ SS7_FUNC_TRACE_ENTER(__FUNCTION__);
+ sngss7_chan_data_t *sngss7_info = NULL;
+ ftdm_channel_t *ftdmchan = NULL;
+ sngss7_event_data_t *sngss7_event = NULL;
+
+ /* 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);
+ SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+ return;
+ }
+
+ /* 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__);
+ return;
+ }
+ memset(sngss7_event, 0x0, sizeof(*sngss7_event));
+
+ /* fill in the sngss7_event struct */
+ sngss7_event->spInstId = spInstId;
+ sngss7_event->suInstId = suInstId;
+ sngss7_event->circuit = circuit;
+ sngss7_event->event_id = SNGSS7_SUSP_IND_EVENT;
+ if (siSuspEvnt != NULL) {
+ memcpy(&sngss7_event->event.siSuspEvnt, siSuspEvnt, sizeof(*siSuspEvnt));
+ }
+
+ /* enqueue this event */
+ ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event);
+
+ SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+
+}
+
+/******************************************************************************/
+void sngss7_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt)
+{
+ SS7_FUNC_TRACE_ENTER(__FUNCTION__);
+
+ sngss7_chan_data_t *sngss7_info = NULL;
+ ftdm_channel_t *ftdmchan = NULL;
+ sngss7_event_data_t *sngss7_event = NULL;
+
+ /* 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);
+ SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+ return;
+ }
+
+ /* 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__);
+ return;
+ }
+ memset(sngss7_event, 0x0, sizeof(*sngss7_event));
+
+ /* fill in the sngss7_event struct */
+ sngss7_event->spInstId = spInstId;
+ sngss7_event->suInstId = suInstId;
+ sngss7_event->circuit = circuit;
+ sngss7_event->event_id = SNGSS7_RESM_IND_EVENT;
+ if (siResmEvnt != NULL) {
+ memcpy(&sngss7_event->event.siResmEvnt, siResmEvnt, sizeof(*siResmEvnt));
+ }
+
+ /* enqueue this event */
+ ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event);
+
+ SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+
+}
+
+/******************************************************************************/
+void sngss7_ssp_sta_cfm(uint32_t infId)
+{
+ SS7_FUNC_TRACE_ENTER(__FUNCTION__);
+#if 0
+ sngss7_chan_data_t *sngss7_info = NULL;
+ ftdm_channel_t *ftdmchan = NULL;
+ sngss7_event_data_t *sngss7_event = NULL;
+
+ /* 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);
+ SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+ return;
+ }
+
+ /* 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__);
+ return;
+ }
+ memset(sngss7_event, 0x0, sizeof(*sngss7_event));
+
+ /* fill in the sngss7_event struct */
+ sngss7_event->spInstId = spInstId;
+ sngss7_event->suInstId = suInstId;
+ sngss7_event->circuit = circuit;
+ sngss7_event->event_id = SNGSS7_RESM_IND_EVENT;
+ if (siSuspEvnt != NULL) {
+ memcpy(&sngss7_event->event.siResmEvnt, siResmEvnt, sizeof(*siResmEvnt));
+ }
+
+ /* enqueue this event */
+ ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->mod_data)->event_queue, sngss7_event);
+#endif
+ SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+
+}
/******************************************************************************/
/* For Emacs:
* Local Variables:
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c
index 3ef8db53d1..7612f3dd74 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c
@@ -46,7 +46,7 @@ ftdm_sngss7_data_t g_ftdm_sngss7_data;
/* PROTOTYPES *****************************************************************/
static void *ftdm_sangoma_ss7_run (ftdm_thread_t * me, void *obj);
-static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan);
+void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan);
static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_event);
static ftdm_status_t ftdm_sangoma_ss7_stop (ftdm_span_t * span);
@@ -79,7 +79,7 @@ ftdm_state_map_t sangoma_ss7_state_map = {
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_IDLE, FTDM_END},
- {FTDM_CHANNEL_STATE_RESTART, FTDM_END}
+ {FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_COLLECT, FTDM_END}
},
{
ZSD_INBOUND,
@@ -93,14 +93,16 @@ ftdm_state_map_t sangoma_ss7_state_map = {
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_IN_LOOP, FTDM_END},
{FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
- FTDM_CHANNEL_STATE_COLLECT, FTDM_CHANNEL_STATE_DOWN, FTDM_END}
+ FTDM_CHANNEL_STATE_COLLECT, FTDM_CHANNEL_STATE_DOWN,
+ FTDM_CHANNEL_STATE_HANGUP_COMPLETE, FTDM_END}
},
{
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_COLLECT, FTDM_END},
{FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
- FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_RING, FTDM_END}
+ FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_RING,
+ FTDM_CHANNEL_STATE_IDLE, FTDM_END}
},
{
ZSD_INBOUND,
@@ -208,7 +210,7 @@ ftdm_state_map_t sangoma_ss7_state_map = {
{FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_RESTART,
FTDM_CHANNEL_STATE_CANCEL, FTDM_CHANNEL_STATE_TERMINATING,
FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS,
- FTDM_CHANNEL_STATE_UP, FTDM_END}
+ FTDM_CHANNEL_STATE_PROGRESS_MEDIA ,FTDM_CHANNEL_STATE_UP, FTDM_END}
},
{
ZSD_OUTBOUND,
@@ -342,12 +344,26 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
/**********************************************************************/
} /* switch ((ftdm_interrupt_wait(ftdm_sangoma_ss7_int, 100))) */
+ /* check if there is a GRA to proccess on the span */
+ if (sngss7_span->rx_gra.range > 0) {
+ check_if_rx_gra_started(ftdmspan);
+ } /* if (sngss7->span->rx_gra.range > 0) */
+
/* check if there is a GRS being processed on the span */
if (sngss7_span->rx_grs.range > 0) {
+ /* check if the rx_grs has started */
+ check_if_rx_grs_started(ftdmspan);
+
/* check if the rx_grs has cleared */
check_if_rx_grs_processed(ftdmspan);
} /* if (sngss7_span->rx_grs.range > 0) */
+ /* check if there is a UCIC to be processed on the span */
+ if (sngss7_span->ucic.range > 0) {
+ /* process the span wide UCIC */
+ process_span_ucic(ftdmspan);
+ } /* if (sngss7_span->ucic.range > 0) */
+
/* check each channel on the span to see if there is an un-procressed SUS/RES flag */
check_for_res_sus_flag(ftdmspan);
} /* master while loop */
@@ -434,6 +450,17 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev
handle_sta_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, sngss7_event->globalFlg, sngss7_event->evntType, &sngss7_event->event.siStaEvnt);
break;
/**************************************************************************/
+ case (SNGSS7_SUSP_IND_EVENT):
+ handle_susp_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siSuspEvnt);
+ break;
+ /**************************************************************************/
+ case (SNGSS7_RESM_IND_EVENT):
+ handle_resm_ind(sngss7_event->suInstId, sngss7_event->spInstId, sngss7_event->circuit, &sngss7_event->event.siResmEvnt);
+ break;
+ /**************************************************************************/
+ case (SNGSS7_SSP_STA_CFM_EVENT):
+ break;
+ /**************************************************************************/
default:
SS7_ERROR("Unknown Event Id!\n");
break;
@@ -452,9 +479,10 @@ static void ftdm_sangoma_ss7_process_stack_event (sngss7_event_data_t *sngss7_ev
}
/******************************************************************************/
-static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
+void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
{
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
+ sng_isup_inf_t *isup_intf = NULL;
int i = 0;
ftdm_sigmsg_t sigev;
@@ -500,29 +528,32 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RING);
} else {
- SS7_INFO_CHAN(ftdmchan,"Received %d out of %d so far: %s...starting T35\n",
- i,
- g_ftdm_sngss7_data.min_digits,
- ftdmchan->caller_data.dnis.digits);
-
- /* start ISUP t35 */
- if (ftdm_sched_timer (sngss7_info->t35.sched,
- "t35",
- sngss7_info->t35.beat,
- sngss7_info->t35.callback,
- &sngss7_info->t35,
- &sngss7_info->t35.hb_timer_id)) {
-
- SS7_ERROR ("Unable to schedule timer, hanging up call!\n");
-
- ftdmchan->caller_data.hangup_cause = 41;
-
- /* set the flag to indicate this hangup is started from the local side */
- sngss7_set_flag (sngss7_info, FLAG_LOCAL_REL);
-
- /* end the call */
- ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
- } /* if (ftdm_sched_timer(sngss7_info->t35.sched, */
+ /* if we are coming from idle state then we have already been here once before */
+ if (ftdmchan->last_state != FTDM_CHANNEL_STATE_IDLE) {
+ SS7_INFO_CHAN(ftdmchan,"Received %d out of %d so far: %s...starting T35\n",
+ i,
+ g_ftdm_sngss7_data.min_digits,
+ ftdmchan->caller_data.dnis.digits);
+
+ /* start ISUP t35 */
+ if (ftdm_sched_timer (sngss7_info->t35.sched,
+ "t35",
+ sngss7_info->t35.beat,
+ sngss7_info->t35.callback,
+ &sngss7_info->t35,
+ &sngss7_info->t35.hb_timer_id)) {
+
+ SS7_ERROR ("Unable to schedule timer, hanging up call!\n");
+
+ ftdmchan->caller_data.hangup_cause = 41;
+
+ /* set the flag to indicate this hangup is started from the local side */
+ sngss7_set_flag (sngss7_info, FLAG_LOCAL_REL);
+
+ /* end the call */
+ ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
+ } /* if (ftdm_sched_timer(sngss7_info->t35.sched, */
+ } /* if (ftdmchan->last_state != FTDM_CHANNEL_STATE_IDLE) */
} /* checking ST/#digits */
break;
@@ -575,15 +606,16 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
}
/*check if the channel is inbound or outbound */
- if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
+ if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
/*OUTBOUND...so we were told by the line of this so noifiy the user */
sigev.event_id = FTDM_SIGEVENT_PROGRESS;
ftdm_span_send_signal (ftdmchan->span, &sigev);
+ /* move to progress media */
ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
} else {
/* inbound call so we need to send out ACM */
- ft_to_sngss7_acm (ftdmchan);
+ ft_to_sngss7_acm(ftdmchan);
}
break;
@@ -595,6 +627,13 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
break;
}
+ if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
+ /* inform the user there is media avai */
+ sigev.event_id = FTDM_SIGEVENT_PROGRESS_MEDIA;
+ ftdm_span_send_signal (ftdmchan->span, &sigev);
+ }
+
+
/* nothing to do at this time */
break;
/**************************************************************************/
@@ -727,14 +766,19 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
/**************************************************************************/
case FTDM_CHANNEL_STATE_DOWN: /*the call is finished and removed */
+ if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) {
+ SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n");
+ break;
+ }
+
/* check if there is a reset response that needs to be sent */
if (sngss7_test_flag (sngss7_info, FLAG_RESET_RX)) {
/* send a RSC-RLC */
ft_to_sngss7_rsca (ftdmchan);
/* clear the reset flag */
- sngss7_clear_flag (sngss7_info, FLAG_RESET_RX);
- }
+ clear_rx_rsc_flags(sngss7_info);
+ } /* if (sngss7_test_flag (sngss7_info, FLAG_RESET_RX)) */
/* check if there was a GRS that needs a GRA */
if ((sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX)) &&
@@ -750,33 +794,26 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
ft_to_sngss7_gra(ftdmchan);
/* clean out the spans GRS structure */
- sngss7_span_data_t *span = ftdmchan->span->mod_data;
- span->rx_grs.circuit = 0;
- span->rx_grs.range = 0;
+ clear_rx_grs_data(sngss7_info);
}
/* clear the grp reset flag */
- sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_RX);
- sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_RX_DN);
- sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT);
-
+ clear_rx_grs_flags(sngss7_info);
}/* if ( sngss7_test_flag ( sngss7_info, FLAG_GRP_RESET_RX ) ) */
/* check if we got the reset response */
if (sngss7_test_flag(sngss7_info, FLAG_RESET_TX_RSP)) {
/* clear the reset flag */
- sngss7_clear_flag(sngss7_info, FLAG_RESET_TX_RSP);
- sngss7_clear_flag(sngss7_info, FLAG_RESET_SENT);
- sngss7_clear_flag(sngss7_info, FLAG_RESET_TX);
- }
+ clear_tx_rsc_flags(sngss7_info);
+ } /* if (sngss7_test_flag(sngss7_info, FLAG_RESET_TX_RSP)) */
if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) {
/* clear the reset flag */
- sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP);
- sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_TX);
- sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_BASE);
- sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_SENT);
- }
+ clear_tx_grs_flags(sngss7_info);
+
+ /* clean out the spans GRA structure */
+ clear_rx_gra_data(sngss7_info);
+ } /* if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) */
/* check if we came from reset (aka we just processed a reset) */
if ((ftdmchan->last_state == FTDM_CHANNEL_STATE_RESTART) ||
@@ -807,7 +844,6 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
} /* if (!ftdm_test_flag (ftdmchan, FTDM_CHANNEL_SIG_UP)) */
} /* if !blocked */
} else {
-
SS7_DEBUG_CHAN(ftdmchan,"Reset flags present (0x%X)\n", sngss7_info->flags);
/* there is still another reset pending so go back to reset*/
@@ -868,6 +904,11 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
/* set the unblk flag */
sngss7_set_flag(sngss7_info, FLAG_CKT_UCIC_UNBLK);
+
+ /* clear the block flag */
+ sngss7_clear_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK);
+
+ /* process the flag */
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
/* break out of the processing for now */
@@ -930,6 +971,14 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
ftdm_set_state_locked (ftdmchan, ftdmchan->last_state);
break;
/******************************************************************/
+ case (FTDM_CHANNEL_STATE_IN_LOOP):
+ /* we screwed up in a COT/CCR, remove the loop */
+ ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL);
+
+ /* go to down */
+ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
+ break;
+ /******************************************************************/
default:
/* KONRAD: find out what the cause code should be */
ftdmchan->caller_data.hangup_cause = 41;
@@ -965,6 +1014,7 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
/**********************************************************************/
if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) {
+ SS7_DEBUG_CHAN(ftdmchan, "Processing RESUME%s\n", "");
/* clear the RESUME flag */
sngss7_clear_flag(sngss7_info, FLAG_INFID_RESUME);
@@ -990,6 +1040,7 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
} /* if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) */
if (sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) {
+ SS7_DEBUG_CHAN(ftdmchan, "Processing PAUSE%s\n", "");
/* bring the sig status down */
sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
@@ -1100,14 +1151,12 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
ftdm_span_send_signal (ftdmchan->span, &sigev);
/* remove any reset flags */
- sngss7_clear_flag (sngss7_info, FLAG_GRP_RESET_TX_RSP);
- sngss7_clear_flag (sngss7_info, FLAG_GRP_RESET_TX);
- sngss7_clear_flag (sngss7_info, FLAG_RESET_TX_RSP);
- sngss7_clear_flag (sngss7_info, FLAG_RESET_TX);
- sngss7_clear_flag (sngss7_info, FLAG_RESET_SENT);
- sngss7_clear_flag (sngss7_info, FLAG_GRP_RESET_RX);
- sngss7_clear_flag (sngss7_info, FLAG_RESET_RX);
- sngss7_clear_flag (sngss7_info, FLAG_GRP_RESET_BASE);
+ clear_rx_grs_flags(sngss7_info);
+ clear_rx_grs_data(sngss7_info);
+ clear_tx_grs_flags(sngss7_info);
+ clear_tx_grs_data(sngss7_info);
+ clear_rx_rsc_flags(sngss7_info);
+ clear_tx_rsc_flags(sngss7_info);
/* bring the channel down */
goto suspend_goto_last;
@@ -1116,8 +1165,14 @@ static void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
if (sngss7_test_flag (sngss7_info, FLAG_CKT_UCIC_UNBLK)) {
SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_UCIC_UNBLK flag %s\n", "");;
- /* throw the channel into reset from our side since it is already in reset from the remote side */
- sngss7_set_flag (sngss7_info, FLAG_RESET_TX);
+ /* remove the UCIC block flag */
+ sngss7_clear_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK);
+
+ /* remove the UCIC unblock flag */
+ sngss7_clear_flag(sngss7_info, FLAG_CKT_UCIC_UNBLK);
+
+ /* throw the channel into reset to sync states */
+ sngss7_set_flag(sngss7_info, FLAG_RESET_TX);
/* bring the channel into restart again */
goto suspend_goto_restart;
@@ -1131,11 +1186,15 @@ suspend_goto_restart:
ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RESTART);
break;
-/**************************************************************************/
+ /**************************************************************************/
case FTDM_CHANNEL_STATE_IN_LOOP: /* COT test */
- /* send the lpa */
- ft_to_sngss7_lpa (ftdmchan);
+ isup_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId];
+
+ if (sngss7_test_options(isup_intf, SNGSS7_LPA_FOR_COT)) {
+ /* send the lpa */
+ ft_to_sngss7_lpa (ftdmchan);
+ }
break;
/**************************************************************************/
@@ -1165,9 +1224,10 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(ftdm_sangoma_ss7_outgoing_call)
/* check if there is a pending state change, give it a bit to clear */
if (check_for_state_change(ftdmchan)) {
SS7_ERROR("Failed to wait for pending state change on CIC = %d\n", sngss7_info->circuit->cic);
- ftdm_mutex_unlock(ftdmchan->mutex);
- SS7_FUNC_TRACE_EXIT(__FUNCTION__);
+ /* check if we need to die */
SS7_ASSERT;
+ /* end the request */
+ goto outgoing_fail;
};
/* check if the channel sig state is UP */
@@ -1278,6 +1338,7 @@ static ftdm_status_t ftdm_sangoma_ss7_start(ftdm_span_t * span)
ftdm_channel_t *ftdmchan = NULL;
sngss7_chan_data_t *sngss7_info = NULL;
sngss7_span_data_t *sngss7_span = NULL;
+ sng_isup_inf_t *sngss7_intf = NULL;
int x;
@@ -1290,12 +1351,22 @@ static ftdm_status_t ftdm_sangoma_ss7_start(ftdm_span_t * span)
if (ftdmchan->call_data == NULL) continue;
sngss7_info = ftdmchan->call_data;
sngss7_span = ftdmchan->span->mod_data;
+ sngss7_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId];
+
/* lock the channel */
ftdm_mutex_lock(ftdmchan->mutex);
- /* throw the pause flag */
- sngss7_set_flag(sngss7_info, FLAG_INFID_PAUSED);
+ /* check if the interface is paused or resumed */
+ if (sngss7_test_flag(sngss7_intf, SNGSS7_PAUSED)) {
+ /* throw the pause flag */
+ sngss7_clear_flag(sngss7_info, FLAG_INFID_RESUME);
+ sngss7_set_flag(sngss7_info, FLAG_INFID_PAUSED);
+ } else {
+ /* throw the pause flag */
+ sngss7_clear_flag(sngss7_info, FLAG_INFID_PAUSED);
+ sngss7_set_flag(sngss7_info, FLAG_INFID_RESUME);
+ }
#if 0
/* throw the grp reset flag */
sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX);
@@ -1444,7 +1515,7 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_ss7_init)
sngss7_id = 0;
- cmbLinkSetId = 1;
+ cmbLinkSetId = 0;
/* initalize the global gen_config flag */
g_ftdm_sngss7_data.gen_config = 0;
@@ -1471,9 +1542,9 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_ss7_init)
sng_event.cc.sng_fac_cfm = sngss7_fac_cfm;
sng_event.cc.sng_sta_ind = sngss7_sta_ind;
sng_event.cc.sng_umsg_ind = sngss7_umsg_ind;
- sng_event.cc.sng_susp_ind = NULL;
- sng_event.cc.sng_resm_ind = NULL;
- sng_event.cc.sng_ssp_sta_cfm = NULL;
+ sng_event.cc.sng_susp_ind = sngss7_susp_ind;
+ sng_event.cc.sng_resm_ind = sngss7_resm_ind;
+ sng_event.cc.sng_ssp_sta_cfm = sngss7_ssp_sta_cfm;
sng_event.sm.sng_log = handle_sng_log;
sng_event.sm.sng_mtp1_alarm = handle_sng_mtp1_alarm;
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h
index 850bbf0d1a..378b50e0ad 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h
@@ -58,6 +58,8 @@
#define SNGSS7_EVENT_QUEUE_SIZE 100
+#define MAX_SIZEOF_SUBADDR_IE 24 /* as per Q931 4.5.9 */
+
typedef enum {
SNGSS7_CON_IND_EVENT = 0,
SNGSS7_CON_CFM_EVENT,
@@ -68,7 +70,10 @@ typedef enum {
SNGSS7_FAC_IND_EVENT,
SNGSS7_FAC_CFM_EVENT,
SNGSS7_UMSG_IND_EVENT,
- SNGSS7_STA_IND_EVENT
+ SNGSS7_STA_IND_EVENT,
+ SNGSS7_SUSP_IND_EVENT,
+ SNGSS7_RESM_IND_EVENT,
+ SNGSS7_SSP_STA_CFM_EVENT
} sng_event_type_t;
typedef enum {
@@ -79,9 +84,20 @@ typedef enum {
typedef enum {
CONFIGURED = (1 << 0),
- ACTIVE = (1 << 1)
+ ACTIVE = (1 << 1),
+ SNGSS7_PAUSED = (1 << 7)
} sng_flag_t;
+typedef enum {
+ SNGSS7_LPA_FOR_COT = (1 << 0), /* send LPA when COT arrives */
+ SNGSS7_ACM_OBCI_BITA = (1 << 10) /* in-band indication */
+} sng_intf_options_t;
+
+typedef enum {
+ SNG_CALLED = 1,
+ SNG_CALLING = 2
+} sng_addr_type_t;
+
typedef struct sng_mtp_link {
char name[MAX_NAME_LEN];
uint32_t id;
@@ -197,6 +213,7 @@ typedef struct sng_route {
typedef struct sng_isup_intf {
uint32_t id;
char name[MAX_NAME_LEN];
+ uint32_t options;
uint32_t flags;
uint32_t spc;
uint32_t dpc;
@@ -205,6 +222,8 @@ typedef struct sng_isup_intf {
uint32_t mtpRouteId;
uint32_t ssf;
uint32_t isap;
+ uint32_t clg_nadi;
+ uint32_t cld_nadi;
uint16_t t4;
uint32_t t10;
uint32_t t11;
@@ -335,6 +354,7 @@ typedef struct sngss7_group_data {
uint32_t range;
uint8_t status[255];
uint8_t type;
+ uint8_t cause;
}sngss7_group_data_t;
typedef struct sngss7_chan_data {
@@ -353,11 +373,13 @@ typedef struct sngss7_chan_data {
typedef struct sngss7_span_data {
ftdm_sched_t *sched;
sngss7_group_data_t rx_grs;
+ sngss7_group_data_t rx_gra;
sngss7_group_data_t tx_grs;
sngss7_group_data_t rx_cgb;
sngss7_group_data_t tx_cgb;
sngss7_group_data_t rx_cgu;
sngss7_group_data_t tx_cgu;
+ sngss7_group_data_t ucic;
ftdm_queue_t *event_queue;
}sngss7_span_data_t;
@@ -379,6 +401,8 @@ typedef struct sngss7_event_data
SiInfoEvnt siInfoEvnt;
SiFacEvnt siFacEvnt;
SiStaEvnt siStaEvnt;
+ SiSuspEvnt siSuspEvnt;
+ SiResmEvnt siResmEvnt;
} event;
} sngss7_event_data_t;
@@ -427,6 +451,10 @@ extern int cmbLinkSetId;
/******************************************************************************/
/* PROTOTYPES *****************************************************************/
+/* in ftmod_sangoma_ss7_main.c */
+void ftdm_sangoma_ss7_process_state_change (ftdm_channel_t *ftdmchan);
+
+/* in ftmod_sangoma_ss7_logger.c */
void handle_sng_log(uint8_t level, char *fmt,...);
void handle_sng_mtp1_alarm(Pst *pst, L1Mngmt *sta);
void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta);
@@ -434,6 +462,7 @@ 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);
+/* in ftmod_sangoma_ss7_cfg.c */
int ft_to_sngss7_cfg_all(void);
int ftmod_ss7_mtp1_gen_config(void);
int ftmod_ss7_mtp2_gen_config(void);
@@ -452,6 +481,9 @@ int ftmod_ss7_isup_ckt_config(int id);
int ftmod_ss7_isup_isap_config(int id);
int ftmod_ss7_cc_isap_config(int id);
+/* in ftmod_sangoma_ss7_cntrl.c */
+int ft_to_sngss7_activate_all(void);
+
int ftmod_ss7_inhibit_mtplink(uint32_t id);
int ftmod_ss7_uninhibit_mtplink(uint32_t id);
int ftmod_ss7_activate_mtplink(uint32_t id);
@@ -463,11 +495,12 @@ int ftmod_ss7_deactivate2_mtplinkSet(uint32_t id);
int ftmod_ss7_lpo_mtplink(uint32_t id);
int ftmod_ss7_lpr_mtplink(uint32_t id);
+/* in ftmod_sangoma_ss7_sta.c */
int ftmod_ss7_mtplink_sta(uint32_t id, SnMngmt *cfm);
int ftmod_ss7_mtplinkSet_sta(uint32_t id, SnMngmt *cfm);
-int ft_to_sngss7_activate_all(void);
+/* in ftmod_sangoma_ss7_out.c */
void ft_to_sngss7_iam(ftdm_channel_t *ftdmchan);
void ft_to_sngss7_acm(ftdm_channel_t *ftdmchan);
void ft_to_sngss7_anm(ftdm_channel_t *ftdmchan);
@@ -487,6 +520,7 @@ void ft_to_sngss7_cgua(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_cgb(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_cgu(ftdm_channel_t * ftdmchan);
+/* in ftmod_sangoma_ss7_in.c */
void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
void sngss7_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt);
void sngss7_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt);
@@ -498,7 +532,11 @@ void sngss7_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint
void sngss7_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt);
void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
void sngss7_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit);
+void sngss7_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt);
+void sngss7_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt);
+void sngss7_ssp_sta_cfm(uint32_t infId);
+/* in ftmod_sangoma_ss7_handle.c */
ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt);
ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCnStEvnt *siCnStEvnt, uint8_t evntType);
ftdm_status_t handle_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt);
@@ -508,6 +546,8 @@ ftdm_status_t handle_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
ftdm_status_t handle_fac_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt);
ftdm_status_t handle_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t evntType, SiFacEvnt *siFacEvnt);
ftdm_status_t handle_umsg_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit);
+ftdm_status_t handle_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt);
+ftdm_status_t handle_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiResmEvnt *siResmEvnt);
ftdm_status_t handle_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
@@ -529,25 +569,46 @@ ftdm_status_t handle_local_blk(uint32_t suInstId, uint32_t spInstId, uint32_t ci
ftdm_status_t handle_local_ubl(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
+/* in ftmod_sangoma_ss7_xml.c */
+int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span);
+
+/* in ftmod_sangoma_ss7_cli.c */
+ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const char *data);
+
+/* in ftmod_sangoma_ss7_support.c */
uint8_t copy_cgPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum);
uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum);
uint8_t copy_cdPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum);
uint8_t copy_cdPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum);
uint8_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
+uint8_t append_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
+
int check_for_state_change(ftdm_channel_t *ftdmchan);
int check_cics_in_range(sngss7_chan_data_t *sngss7_info);
int check_for_reset(sngss7_chan_data_t *sngss7_info);
ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_info, ftdm_channel_t **ftdmchan);
unsigned long get_unique_id(void);
-int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span);
-
-void handle_isup_t35(void *userdata);
-
-ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const char *data);
-
+ftdm_status_t check_if_rx_grs_started(ftdm_span_t *ftdmspan);
ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan);
+ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan);
ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan);
+
+ftdm_status_t process_span_ucic(ftdm_span_t *ftdmspan);
+
+ftdm_status_t clear_rx_grs_flags(sngss7_chan_data_t *sngss7_info);
+ftdm_status_t clear_tx_grs_flags(sngss7_chan_data_t *sngss7_info);
+ftdm_status_t clear_rx_rsc_flags(sngss7_chan_data_t *sngss7_info);
+ftdm_status_t clear_tx_rsc_flags(sngss7_chan_data_t *sngss7_info);
+ftdm_status_t clear_rx_grs_data(sngss7_chan_data_t *sngss7_info);
+ftdm_status_t clear_rx_gra_data(sngss7_chan_data_t *sngss7_info);
+ftdm_status_t clear_tx_grs_data(sngss7_chan_data_t *sngss7_info);
+
+ftdm_status_t encode_subAddrIE_nsap(const char *subAddr, char *subAddrIE, int type);
+ftdm_status_t encode_subAddrIE_nat(const char *subAddr, char *subAddrIE, int type);
+
+/* in ftmod_sangoma_ss7_timers.c */
+void handle_isup_t35(void *userdata);
/******************************************************************************/
/* MACROS *********************************************************************/
@@ -678,7 +739,19 @@ ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan);
#define sngss7_clear_flag(obj, flag) ((obj)->flags &= ~(flag))
#define sngss7_set_flag(obj, flag) ((obj)->flags |= (flag))
-# define SS7_ASSERT *(int*)0=0;
+#define sngss7_test_options(obj, option) ((obj)->options & option)
+#define sngss7_clear_options(obj, option) ((obj)->options &= ~(option))
+#define sngss7_set_options(obj, option) ((obj)->options |= (option))
+
+
+#ifdef SS7_PRODUCTION
+# define SS7_ASSERT \
+ SS7_INFO_CHAN(ftdmchan,"Production Mode, continuing%s\n", "");
+#else
+# define SS7_ASSERT \
+ SS7_ERROR_CHAN(ftdmchan, "Debugging Mode, ending%s\n", ""); \
+ *(int*)0=0;
+#endif
/******************************************************************************/
/******************************************************************************/
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c
index 8b3f9d8424..f2e34e6c2c 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c
@@ -74,7 +74,11 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;;
- const char *nadi = NULL;
+ const char *clg_nadi = NULL;
+ const char *cld_nadi = NULL;
+ const char *clg_subAddr = NULL;
+ const char *cld_subAddr = NULL;
+ char subAddrIE[MAX_SIZEOF_SUBADDR_IE];
SiConEvnt iam;
sngss7_info->suInstId = get_unique_id ();
@@ -183,15 +187,104 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
copy_cgPtyNum_to_sngss7 (&ftdmchan->caller_data, &iam.cgPtyNum);
/* check if the user would like a custom NADI value for the calling Pty Num */
- nadi = ftdm_channel_get_var(ftdmchan, "ss7_nadi");
- if ((nadi != NULL) && (*nadi)) {
- SS7_DEBUG_CHAN(ftdmchan,"Found user supplied NADI value \"%s\"\n", nadi);
- iam.cgPtyNum.natAddrInd.val = atoi(nadi);
+ clg_nadi = ftdm_channel_get_var(ftdmchan, "ss7_clg_nadi");
+ if ((clg_nadi != NULL) && (*clg_nadi)) {
+ SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Calling NADI value \"%s\"\n", clg_nadi);
+ iam.cgPtyNum.natAddrInd.val = atoi(clg_nadi);
} else {
- SS7_DEBUG_CHAN(ftdmchan,"No user supplied NADI value found, using \"3\" %s\n", " ");
- iam.cgPtyNum.natAddrInd.val = 0x03;
+ iam.cgPtyNum.natAddrInd.val = g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].clg_nadi;
+ SS7_DEBUG_CHAN(ftdmchan,"No user supplied NADI value found for CLG, using \"%d\"\n", iam.cgPtyNum.natAddrInd.val);
}
+ cld_nadi = ftdm_channel_get_var(ftdmchan, "ss7_cld_nadi");
+ if ((cld_nadi != NULL) && (*cld_nadi)) {
+ SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Called NADI value \"%s\"\n", cld_nadi);
+ iam.cdPtyNum.natAddrInd.val = atoi(cld_nadi);
+ } else {
+ iam.cdPtyNum.natAddrInd.val = g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].cld_nadi;
+ SS7_DEBUG_CHAN(ftdmchan,"No user supplied NADI value found for CLD, using \"%d\"\n", iam.cdPtyNum.natAddrInd.val);
+ }
+
+ /* check if the user would like us to send a clg_sub-address */
+ clg_subAddr = ftdm_channel_get_var(ftdmchan, "ss7_clg_subaddr");
+ if ((clg_subAddr != NULL) && (*clg_subAddr)) {
+ SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Calling Sub-Address value \"%s\"\n", clg_subAddr);
+
+ /* clean out the subAddrIE */
+ memset(subAddrIE, 0x0, sizeof(subAddrIE));
+
+ /* check the first character in the sub-address to see what type of encoding to use */
+ switch (clg_subAddr[0]) {
+ case '0': /* NSAP */
+ encode_subAddrIE_nsap(&clg_subAddr[1], subAddrIE, SNG_CALLING);
+ break;
+ case '1': /* national variant */
+ encode_subAddrIE_nat(&clg_subAddr[1], subAddrIE, SNG_CALLING);
+ break;
+ default:
+ SS7_ERROR_CHAN(ftdmchan,"Invalid Calling Sub-Address encoding requested: %c\n", clg_subAddr[0]);
+ break;
+ } /* switch (cld_subAddr[0]) */
+
+
+ /* if subaddIE is still empty don't copy it in */
+ if (subAddrIE[0] != '0') {
+ /* check if the clg_subAddr has already been added */
+ if (iam.accTrnspt.eh.pres == PRSNT_NODEF) {
+ /* append the subAddrIE */
+ memcpy(&iam.accTrnspt.infoElmts.val[iam.accTrnspt.infoElmts.len], subAddrIE, (subAddrIE[1] + 2));
+ iam.accTrnspt.infoElmts.len = iam.accTrnspt.infoElmts.len +subAddrIE[1] + 2;
+ } else {
+ /* fill in from the beginning */
+ iam.accTrnspt.eh.pres = PRSNT_NODEF;
+ iam.accTrnspt.infoElmts.pres = PRSNT_NODEF;
+ memcpy(iam.accTrnspt.infoElmts.val, subAddrIE, (subAddrIE[1] + 2));
+ iam.accTrnspt.infoElmts.len = subAddrIE[1] + 2;
+ } /* if (iam.accTrnspt.eh.pres */
+ } /* if (subAddrIE[0] != '0') */
+ }
+
+ /* check if the user would like us to send a cld_sub-address */
+ cld_subAddr = ftdm_channel_get_var(ftdmchan, "ss7_cld_subaddr");
+ if ((cld_subAddr != NULL) && (*cld_subAddr)) {
+ SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Called Sub-Address value \"%s\"\n", cld_subAddr);
+
+ /* clean out the subAddrIE */
+ memset(subAddrIE, 0x0, sizeof(subAddrIE));
+
+ /* check the first character in the sub-address to see what type of encoding to use */
+ switch (cld_subAddr[0]) {
+ case '0': /* NSAP */
+ encode_subAddrIE_nsap(&cld_subAddr[1], subAddrIE, SNG_CALLED);
+ break;
+ case '1': /* national variant */
+ encode_subAddrIE_nat(&cld_subAddr[1], subAddrIE, SNG_CALLED);
+ break;
+ default:
+ SS7_ERROR_CHAN(ftdmchan,"Invalid Called Sub-Address encoding requested: %c\n", cld_subAddr[0]);
+ break;
+ } /* switch (cld_subAddr[0]) */
+
+ /* if subaddIE is still empty don't copy it in */
+ if (subAddrIE[0] != '0') {
+ /* check if the cld_subAddr has already been added */
+ if (iam.accTrnspt.eh.pres == PRSNT_NODEF) {
+ /* append the subAddrIE */
+ memcpy(&iam.accTrnspt.infoElmts.val[iam.accTrnspt.infoElmts.len], subAddrIE, (subAddrIE[1] + 2));
+ iam.accTrnspt.infoElmts.len = iam.accTrnspt.infoElmts.len +subAddrIE[1] + 2;
+ } else {
+ /* fill in from the beginning */
+ iam.accTrnspt.eh.pres = PRSNT_NODEF;
+ iam.accTrnspt.infoElmts.pres = PRSNT_NODEF;
+ memcpy(iam.accTrnspt.infoElmts.val, subAddrIE, (subAddrIE[1] + 2));
+ iam.accTrnspt.infoElmts.len = subAddrIE[1] + 2;
+ } /* if (iam.accTrnspt.eh.pres */
+ } /* if (subAddrIE[0] != '0') */
+ } /* if ((cld_subAddr != NULL) && (*cld_subAddr)) */
+
+
+
+
sng_cc_con_request (sngss7_info->spId,
sngss7_info->suInstId,
sngss7_info->spInstId,
@@ -199,10 +292,12 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
&iam,
0);
- SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM clg = \"%s\", cld = \"%s\"\n",
+ SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM clg = \"%s\" (NADI=%d), cld = \"%s\" (NADI=%d)\n",
sngss7_info->circuit->cic,
ftdmchan->caller_data.cid_num.digits,
- ftdmchan->caller_data.dnis.digits);
+ iam.cgPtyNum.natAddrInd.val,
+ ftdmchan->caller_data.dnis.digits,
+ iam.cdPtyNum.natAddrInd.val);
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
return;
@@ -213,7 +308,8 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan)
{
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
- sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
+ sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
+ sng_isup_inf_t *isup_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId];
SiCnStEvnt acm;
memset (&acm, 0x0, sizeof (acm));
@@ -242,7 +338,19 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan)
acm.bckCallInd.echoCtrlDevInd.val = 0x1; /* ec device present */
acm.bckCallInd.sccpMethInd.pres = PRSNT_NODEF;
acm.bckCallInd.sccpMethInd.val = SCCPMTH_NOIND;
-
+
+ /* fill in any optional parameters */
+ if (sngss7_test_options(isup_intf, SNGSS7_ACM_OBCI_BITA)) {
+ SS7_DEBUG_CHAN(ftdmchan, "Found ACM_OBCI_BITA flag:0x%X\n", isup_intf->options);
+ acm.optBckCalInd.eh.pres = PRSNT_NODEF;
+ acm.optBckCalInd.inbndInfoInd.pres = PRSNT_NODEF;
+ acm.optBckCalInd.inbndInfoInd.val = 0x1;
+ acm.optBckCalInd.caFwdMayOcc.pres = PRSNT_DEF;
+ acm.optBckCalInd.simpleSegmInd.pres = PRSNT_DEF;
+ acm.optBckCalInd.mlppUserInd.pres = PRSNT_DEF;
+ acm.optBckCalInd.usrNetIneractInd.pres = PRSNT_DEF;
+ } /* if (sngss7_test_options(isup_intf, SNGSS7_ACM_OBCI_BITA)) */
+
/* send the ACM request to LibSngSS7 */
sng_cc_con_status (1,
sngss7_info->suInstId,
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c
index d238462046..1235238452 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c
@@ -50,27 +50,41 @@ int ftmod_ss7_mtplinkSet_sta(uint32_t id, SnMngmt *cfm);
int ftmod_ss7_mtplink_sta(uint32_t id, SnMngmt *cfm)
{
SnMngmt sta;
+ Pst pst;
memset(&sta, 0x0, sizeof(sta));
+ /* initalize the post structure */
+ smPstInit(&pst);
+
+ /* insert the destination Entity */
+ pst.dstEnt = ENTSN;
+
sta.hdr.elmId.elmnt = STDLSAP;
sta.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id;
- return(sng_sta_mtp3(&sta, cfm));
+ return(sng_sta_mtp3(&pst, &sta, cfm));
}
/******************************************************************************/
int ftmod_ss7_mtplinkSet_sta(uint32_t id, SnMngmt *cfm)
{
SnMngmt sta;
+ Pst pst;
memset(&sta, 0x0, sizeof(sta));
+ /* initalize the post structure */
+ smPstInit(&pst);
+
+ /* insert the destination Entity */
+ pst.dstEnt = ENTSN;
+
sta.hdr.elmId.elmnt = STLNKSET;
sta.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].id;
sta.hdr.elmId.elmntInst2 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].links[0];
- return(sng_sta_mtp3(&sta, cfm));
+ return(sng_sta_mtp3(&pst, &sta, cfm));
}
/******************************************************************************/
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c
index aaffeb0a36..4d514caf86 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c
@@ -44,6 +44,7 @@ uint32_t sngss7_id;
/* PROTOTYPES *****************************************************************/
uint8_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
+uint8_t append_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
uint8_t copy_cgPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum);
uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum);
uint8_t copy_cdPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum);
@@ -57,8 +58,23 @@ unsigned long get_unique_id(void);
ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_info, ftdm_channel_t **ftdmchan);
+ftdm_status_t check_if_rx_grs_started(ftdm_span_t *ftdmspan);
ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan);
+ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan);
ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan);
+
+ftdm_status_t process_span_ucic(ftdm_span_t *ftdmspan);
+
+ftdm_status_t clear_rx_grs_flags(sngss7_chan_data_t *sngss7_info);
+ftdm_status_t clear_tx_grs_flags(sngss7_chan_data_t *sngss7_info);
+ftdm_status_t clear_rx_rsc_flags(sngss7_chan_data_t *sngss7_info);
+ftdm_status_t clear_tx_rsc_flags(sngss7_chan_data_t *sngss7_info);
+ftdm_status_t clear_rx_grs_data(sngss7_chan_data_t *sngss7_info);
+ftdm_status_t clear_rx_gra_data(sngss7_chan_data_t *sngss7_info);
+ftdm_status_t clear_tx_grs_data(sngss7_chan_data_t *sngss7_info);
+
+ftdm_status_t encode_subAddrIE_nsap(const char *subAddr, char *subAddrIE, int type);
+ftdm_status_t encode_subAddrIE_nat(const char *subAddr, char *subAddrIE, int type);
/******************************************************************************/
/* FUNCTIONS ******************************************************************/
@@ -152,8 +168,8 @@ uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum)
} else {
/* keep the odd flag down */
odd = 0;
- /* throw the flag */
- flag = 1;
+ /* break right away since we don't need to write the digits */
+ break;
}
/* push the digits into the trillium structure */
@@ -254,14 +270,14 @@ uint8_t copy_cdPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum)
upper = (atoi(&tmp[0])) << 4;
} else {
/* there is no upper ... fill in ST */
- upper = 0xF;
- /* throw the odd flag */
- odd = 1;
+ upper = 0xF0;
+ /* keep the odd flag down */
+ odd = 0;
/* throw the end flag */
flag = 1;
} /* if (tmp != '\0') */
} else {
- /* keep the odd flag down */
+ /* throw the odd flag */
odd = 1;
/* need to add the ST */
lower = 0xF;
@@ -328,6 +344,49 @@ uint8_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven)
return 0;
}
+/******************************************************************************/
+uint8_t append_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven)
+{
+ int i = 0;
+ int j = 0;
+
+ /* check if the token string is present */
+ if (str.pres == 1) {
+ /* find the length of the digits so far */
+ j = strlen(ftdm);
+
+ /* confirm that we found an acceptable length */
+ if ( j > 25 ) {
+ SS7_ERROR("string length exceeds maxium value...aborting append!\n");
+ return 1;
+ } /* if ( j > 25 ) */
+
+ /* copy in digits */
+ for (i = 0; i < str.len; i++) {
+ /* convert 4 bit integer to char and copy into lower nibblet*/
+ sprintf(&ftdm[j], "%X", (str.val[i] & 0x0F));
+ /* move along */
+ j++;
+ /* convert 4 bit integer to char and copy into upper nibblet */
+ sprintf(&ftdm[j], "%X", ((str.val[i] & 0xF0) >> 4));
+ /* move along */
+ j++;
+ } /* for (i = 0; i < str.len; i++) */
+
+ /* if the odd flag is up the last digit is a fake "0" */
+ if ((oddEven.pres == 1) && (oddEven.val == 1)) {
+ ftdm[j-1] = '\0';
+ } else {
+ ftdm[j] = '\0';
+ } /* if ((oddEven.pres == 1) && (oddEven.val == 1)) */
+ } else {
+ SS7_ERROR("Asked to copy tknStr that is not present!\n");
+ return 1;
+ } /* if (str.pres == 1) */
+
+ return 0;
+}
+
/******************************************************************************/
int check_for_state_change(ftdm_channel_t *ftdmchan)
{
@@ -445,6 +504,68 @@ unsigned long get_unique_id(void)
return(sngss7_id);
}
+/******************************************************************************/
+ftdm_status_t check_if_rx_grs_started(ftdm_span_t *ftdmspan)
+{
+ ftdm_channel_t *ftdmchan = NULL;
+ sngss7_chan_data_t *sngss7_info = NULL;
+ sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->mod_data;
+ int i;
+
+ for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
+
+ /* extract the channel in question */
+ if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
+ SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i);
+ continue;
+ }
+
+ /* check if the GRP_RESET_RX flag is already up */
+ if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX)) {
+ /* we have already processed this channel...move along */
+ continue;
+ }
+
+ /* lock the channel */
+ ftdm_mutex_lock(ftdmchan->mutex);
+
+ /* clear up any pending state changes */
+ while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
+ ftdm_sangoma_ss7_process_state_change (ftdmchan);
+ }
+
+ SS7_INFO_CHAN(ftdmchan, "Rx GRS (%d:%d)\n",
+ g_ftdm_sngss7_data.cfg.isupCkt[sngss7_span->rx_grs.circuit].cic,
+ (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_span->rx_grs.circuit].cic + sngss7_span->rx_grs.range));
+
+ /* flag the channel as having received a reset */
+ sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX);
+
+ switch (ftdmchan->state) {
+ /**************************************************************************/
+ case FTDM_CHANNEL_STATE_RESTART:
+
+ /* go to idle so that we can redo the restart state*/
+ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_IDLE);
+
+ break;
+ /**************************************************************************/
+ default:
+
+ /* set the state of the channel to restart...the rest is done by the chan monitor */
+ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
+ break;
+ /**************************************************************************/
+ } /* switch (ftdmchan->state) */
+
+ /* unlock the channel again before we exit */
+ ftdm_mutex_unlock(ftdmchan->mutex);
+
+ } /* for (chans in GRS */
+
+ return FTDM_SUCCESS;
+}
+
/******************************************************************************/
ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan)
{
@@ -456,7 +577,7 @@ ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan)
int bit = 0;
- ftdm_log(FTDM_LOG_DEBUG, "Found Rx GRS on span %d...checking circuits\n", ftdmspan->span_id);
+ ftdm_log(FTDM_LOG_DEBUG, "Found Rx GRS on span %s...checking circuits\n", ftdmspan->name);
/* check all the circuits in the range to see if they are done resetting */
for ( i = sngss7_span->rx_grs.circuit; i < (sngss7_span->rx_grs.circuit + sngss7_span->rx_grs.range + 1); i++) {
@@ -493,7 +614,10 @@ ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan)
/* extract the channel in question */
if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
SS7_ERROR("Failed to extract channel data for circuit = %d!\n",i);
+ /* check if we need to die */
SS7_ASSERT;
+ /* move along */
+ continue;
}
/* throw the GRP reset flag complete flag */
@@ -534,6 +658,91 @@ GRS_UNLOCK_ALL:
return FTDM_SUCCESS;
}
+/******************************************************************************/
+ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan)
+{
+ ftdm_channel_t *ftdmchan = NULL;
+ sngss7_chan_data_t *sngss7_info = NULL;
+ sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->mod_data;
+ int i;
+
+ for (i = sngss7_span->rx_gra.circuit; i < (sngss7_span->rx_gra.circuit + sngss7_span->rx_gra.range + 1); i++) {
+
+ /* extract the channel in question */
+ if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
+ SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i);
+ continue;
+ }
+
+ /* check if the channel is already procoessing the GRA */
+ if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) {
+ /* move along */
+ continue;
+ }
+
+ /* lock the channel */
+ ftdm_mutex_lock(ftdmchan->mutex);
+
+ /* clear up any pending state changes */
+ while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
+ ftdm_sangoma_ss7_process_state_change (ftdmchan);
+ }
+
+ SS7_INFO_CHAN(ftdmchan, "Rx GRA (%d:%d)\n",
+ g_ftdm_sngss7_data.cfg.isupCkt[sngss7_span->rx_gra.circuit].cic,
+ (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_span->rx_gra.circuit].cic + sngss7_span->rx_gra.range));
+
+ switch (ftdmchan->state) {
+ /**********************************************************************/
+ case FTDM_CHANNEL_STATE_RESTART:
+
+ /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */
+ sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP);
+
+ /* go to DOWN */
+ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
+
+ break;
+ /**********************************************************************/
+ case FTDM_CHANNEL_STATE_DOWN:
+
+ /* do nothing, just drop the message */
+ SS7_DEBUG("Receveived GRA in down state, dropping\n");
+
+ break;
+ /**********************************************************************/
+ case FTDM_CHANNEL_STATE_TERMINATING:
+ case FTDM_CHANNEL_STATE_HANGUP:
+ case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
+
+ /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */
+ sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP);
+
+ break;
+ /**********************************************************************/
+ default:
+ /* ITU Q764-2.9.5.1.c -> release the circuit */
+ if (sngss7_span->rx_gra.cause != 0) {
+ ftdmchan->caller_data.hangup_cause = sngss7_span->rx_gra.cause;
+ } else {
+ ftdmchan->caller_data.hangup_cause = 98; /* Message not compatiable with call state */
+ }
+
+ /* go to terminating to hang up the call */
+ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
+ break;
+ /**********************************************************************/
+ }
+
+ /* unlock the channel again before we exit */
+ ftdm_mutex_unlock(ftdmchan->mutex);
+
+ } /* for ( circuits in request */
+
+
+ return FTDM_SUCCESS;
+}
+
/******************************************************************************/
ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan)
{
@@ -564,6 +773,11 @@ ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan)
/* if we have the PAUSED flag and the sig status is still UP */
if ((sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) &&
(ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP))) {
+
+ /* clear up any pending state changes */
+ while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
+ ftdm_sangoma_ss7_process_state_change (ftdmchan);
+ }
/* throw the channel into SUSPENDED to process the flag */
/* after doing this once the sig status will be down */
@@ -573,6 +787,13 @@ ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan)
/* if the RESUME flag is up go to SUSPENDED to process the flag */
/* after doing this the flag will be cleared */
if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) {
+
+ /* clear up any pending state changes */
+ while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
+ ftdm_sangoma_ss7_process_state_change (ftdmchan);
+ }
+
+ /* got SUSPENDED state to clear the flag */
ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
}
@@ -588,7 +809,336 @@ ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan)
}
/******************************************************************************/
+ftdm_status_t process_span_ucic(ftdm_span_t *ftdmspan)
+{
+ ftdm_channel_t *ftdmchan = NULL;
+ sngss7_chan_data_t *sngss7_info = NULL;
+ sngss7_span_data_t *sngss7_span = (sngss7_span_data_t *)ftdmspan->mod_data;
+ int i;
+ for (i = sngss7_span->ucic.circuit; i < (sngss7_span->ucic.circuit + sngss7_span->ucic.range + 1); i++) {
+
+ /* extract the channel in question */
+ if (extract_chan_data(i, &sngss7_info, &ftdmchan)) {
+ SS7_ERROR("Failed to extract channel data for circuit = %d!\n", i);
+ continue;
+ }
+
+ /* lock the channel */
+ ftdm_mutex_lock(ftdmchan->mutex);
+
+ SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx UCIC\n", sngss7_info->circuit->cic);
+
+ /* clear up any pending state changes */
+ while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
+ ftdm_sangoma_ss7_process_state_change (ftdmchan);
+ }
+
+ /* throw the ckt block flag */
+ sngss7_set_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK);
+
+ /* set the channel to suspended state */
+ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED);
+
+ /* unlock the channel again before we exit */
+ ftdm_mutex_unlock(ftdmchan->mutex);
+ }
+
+ /* clear out the ucic data since we're done with it */
+ memset(&sngss7_span->ucic, 0x0, sizeof(sngss7_group_data_t));
+
+ return FTDM_SUCCESS;
+}
+
+/******************************************************************************/
+ftdm_status_t clear_rx_grs_flags(sngss7_chan_data_t *sngss7_info)
+{
+ /* clear all the flags related to an incoming GRS */
+ sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_RX);
+ sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_RX_DN);
+ sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT);
+
+ return FTDM_SUCCESS;
+}
+
+/******************************************************************************/
+ftdm_status_t clear_rx_grs_data(sngss7_chan_data_t *sngss7_info)
+{
+ ftdm_channel_t *ftdmchan = sngss7_info->ftdmchan;
+ sngss7_span_data_t *sngss7_span = ftdmchan->span->mod_data;
+
+ /* clear the rx_grs data fields */
+ memset(&sngss7_span->rx_grs, 0x0, sizeof(sngss7_group_data_t));
+
+ return FTDM_SUCCESS;
+}
+
+/******************************************************************************/
+ftdm_status_t clear_rx_gra_data(sngss7_chan_data_t *sngss7_info)
+{
+ ftdm_channel_t *ftdmchan = sngss7_info->ftdmchan;
+ sngss7_span_data_t *sngss7_span = ftdmchan->span->mod_data;
+
+ /* clear the rx_grs data fields */
+ memset(&sngss7_span->rx_gra, 0x0, sizeof(sngss7_group_data_t));
+
+ return FTDM_SUCCESS;
+}
+/******************************************************************************/
+ftdm_status_t clear_tx_grs_flags(sngss7_chan_data_t *sngss7_info)
+{
+ /* clear all the flags related to an outgoing GRS */
+ sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_BASE);
+ sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_TX);
+ sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_SENT);
+ sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP);
+
+ return FTDM_SUCCESS;
+}
+
+/******************************************************************************/
+ftdm_status_t clear_tx_grs_data(sngss7_chan_data_t *sngss7_info)
+{
+ ftdm_channel_t *ftdmchan = sngss7_info->ftdmchan;
+ sngss7_span_data_t *sngss7_span = ftdmchan->span->mod_data;
+
+ /* clear the rx_grs data fields */
+ memset(&sngss7_span->tx_grs, 0x0, sizeof(sngss7_group_data_t));
+
+ return FTDM_SUCCESS;
+}
+
+/******************************************************************************/
+
+/******************************************************************************/
+ftdm_status_t clear_rx_rsc_flags(sngss7_chan_data_t *sngss7_info)
+{
+ /* clear all the flags related to an incoming RSC */
+ sngss7_clear_flag(sngss7_info, FLAG_RESET_RX);
+
+ return FTDM_SUCCESS;
+}
+
+/******************************************************************************/
+ftdm_status_t clear_tx_rsc_flags(sngss7_chan_data_t *sngss7_info)
+{
+ /* clear all the flags related to an outgoing RSC */
+ sngss7_clear_flag(sngss7_info, FLAG_RESET_TX);
+ sngss7_clear_flag(sngss7_info, FLAG_RESET_SENT);
+ sngss7_clear_flag(sngss7_info, FLAG_RESET_TX_RSP);
+
+ return FTDM_SUCCESS;
+}
+
+/******************************************************************************/
+ftdm_status_t encode_subAddrIE_nsap(const char *subAddr, char *subAddrIE, int type)
+{
+ /* Q931 4.5.9
+ * 8 7 6 5 4 3 2 1 (octet)
+ *
+ * 0 1 1 1 0 0 0 1 (spare 8) ( IE id 1-7)
+ * X X X X X X X X (length of IE contents)
+ * 1 0 0 0 Z 0 0 0 (ext 8) (NSAP type 5-7) (odd/even 4) (spare 1-3)
+ * X X X X X X X X (sub address encoded in ia5)
+ */
+
+ int x = 0;
+ int p = 0;
+ int len = 0;
+ char tmp[2];
+
+ /* initalize the second element of tmp to \0 so that atoi doesn't go to far */
+ tmp[1]='\0';
+
+ /* set octet 1 aka IE id */
+ p = 0;
+ switch(type) {
+ /**************************************************************************/
+ case SNG_CALLED: /* called party sub address */
+ subAddrIE[p] = 0x71;
+ break;
+ /**************************************************************************/
+ case SNG_CALLING: /* calling party sub address */
+ subAddrIE[p] = 0x6d;
+ break;
+ /**************************************************************************/
+ default: /* not good */
+ SS7_ERROR("Sub-Address type is invalid: %d\n", type);
+ return FTDM_FAIL;
+ break;
+ /**************************************************************************/
+ } /* switch(type) */
+
+ /* set octet 3 aka type and o/e */
+ p = 2;
+ subAddrIE[p] = 0x80;
+
+ /* set the subAddrIE pointer octet 4 */
+ p = 3;
+
+ /* loop through all digits in subAddr and insert them into subAddrIE */
+ while (subAddr[x] != '\0') {
+
+ /* grab a character */
+ tmp[0] = subAddr[x];
+
+ /* confirm it is a digit */
+ if (!isdigit(tmp[0])) {
+ /* move to the next character in subAddr */
+ x++;
+
+ /* restart the loop */
+ continue;
+ }
+
+ /* convert the character to IA5 encoding and write into subAddrIE */
+ subAddrIE[p] = atoi(&tmp[0]); /* lower nibble is the digit */
+ subAddrIE[p] |= 0x3 << 4; /* upper nibble is 0x3 */
+
+ /* increment address length counter */
+ len++;
+
+ /* increment the subAddrIE pointer */
+ p++;
+
+ /* move to the next character in subAddr */
+ x++;
+
+ } /* while (subAddr[x] != '\0') */
+
+ /* set octet 2 aka length of subaddr */
+ p = 1;
+ subAddrIE[p] = len + 1;
+
+
+ return FTDM_SUCCESS;
+}
+
+/******************************************************************************/
+ftdm_status_t encode_subAddrIE_nat(const char *subAddr, char *subAddrIE, int type)
+{
+ /* Q931 4.5.9
+ * 8 7 6 5 4 3 2 1 (octet)
+ *
+ * 0 1 1 1 0 0 0 1 (spare 8) ( IE id 1-7)
+ * X X X X X X X X (length of IE contents)
+ * 1 0 0 0 Z 0 0 0 (ext 8) (NSAP type 5-7) (odd/even 4) (spare 1-3)
+ * X X X X X X X X (sub address encoded in ia5)
+ */
+
+ int x = 0;
+ int p = 0;
+ int len = 0;
+ char tmp[2];
+ int flag = 0;
+ int odd = 0;
+ uint8_t lower = 0x0;
+ uint8_t upper = 0x0;
+
+ /* initalize the second element of tmp to \0 so that atoi doesn't go to far */
+ tmp[1]='\0';
+
+ /* set octet 1 aka IE id */
+ p = 0;
+ switch(type) {
+ /**************************************************************************/
+ case SNG_CALLED: /* called party sub address */
+ subAddrIE[p] = 0x71;
+ break;
+ /**************************************************************************/
+ case SNG_CALLING: /* calling party sub address */
+ subAddrIE[p] = 0x6d;
+ break;
+ /**************************************************************************/
+ default: /* not good */
+ SS7_ERROR("Sub-Address type is invalid: %d\n", type);
+ return FTDM_FAIL;
+ break;
+ /**************************************************************************/
+ } /* switch(type) */
+
+ /* set the subAddrIE pointer octet 4 */
+ p = 3;
+
+ /* loop through all digits in subAddr and insert them into subAddrIE */
+ while (1) {
+
+ /* grab a character */
+ tmp[0] = subAddr[x];
+
+ /* confirm it is a hex digit */
+ while ((!isxdigit(tmp[0])) && (tmp[0] != '\0')) {
+ /* move to the next character in subAddr */
+ x++;
+ tmp[0] = subAddr[x];
+ }
+
+ /* check if tmp is null or a digit */
+ if (tmp[0] != '\0') {
+ /* push it into the lower nibble using strtol to allow a-f chars */
+ lower = strtol(&tmp[0], (char **)NULL, 16);
+ /* move to the next digit */
+ x++;
+ /* grab a digit from the ftdm digits */
+ tmp[0] = subAddr[x];
+
+ /* check if the digit is a hex digit and that is not null */
+ while (!(isxdigit(tmp[0])) && (tmp[0] != '\0')) {
+ x++;
+ tmp[0] = subAddr[x];
+ } /* while(!(isdigit(tmp))) */
+
+ /* check if tmp is null or a digit */
+ if (tmp[0] != '\0') {
+ /* push the digit into the upper nibble using strtol to allow a-f chars */
+ upper = (strtol(&tmp[0], (char **)NULL, 16)) << 4;
+ } else {
+ /* there is no upper ... fill in spare */
+ upper = 0x00;
+ /* throw the odd flag since we need to buffer */
+ odd = 1;
+ /* throw the end flag */
+ flag = 1;
+ } /* if (tmp != '\0') */
+ } else {
+ /* keep the odd flag down */
+ odd = 0;
+
+ /* throw the flag */
+ flag = 1;
+
+ /* bounce out right away */
+ break;
+ }
+
+ /* fill in the octet */
+ subAddrIE[p] = upper | lower;
+
+ /* increment address length counter */
+ len++;
+
+ /* if the flag is we're through all the digits */
+ if (flag) break;
+
+ /* increment the subAddrIE pointer */
+ p++;
+
+ /* move to the next character in subAddr */
+ x++;
+
+ } /* while (subAddr[x] != '\0') */
+
+ /* set octet 2 aka length of subaddr */
+ p = 1;
+ subAddrIE[p] = len + 1;
+
+ /* set octet 3 aka type and o/e */
+ p = 2;
+ subAddrIE[p] = 0xa0 | (odd << 3);
+
+
+ return FTDM_SUCCESS;
+}
/******************************************************************************/
/* For Emacs:
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c
index bd1be4b6a4..74d37b53d1 100644
--- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c
+++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c
@@ -47,6 +47,23 @@ typedef struct sng_timeslot
int hole;
}sng_timeslot_t;
+typedef struct sng_isupCkt
+{
+ ftdm_span_t *span;
+ uint32_t cicbase;
+ uint32_t typeCntrl;
+ char ch_map[MAX_CIC_MAP_LENGTH];
+ uint32_t isupInf;
+ uint32_t t3;
+ uint32_t t12;
+ uint32_t t13;
+ uint32_t t14;
+ uint32_t t15;
+ uint32_t t16;
+ uint32_t t17;
+ uint32_t tval;
+} sng_isupCkt_t;
+
int cmbLinkSetId;
/******************************************************************************/
@@ -77,7 +94,7 @@ static int ftmod_ss7_fill_in_isap(sng_isap_t *sng_isap);
static int ftmod_ss7_fill_in_self_route(int spc, int linkType, int switchType, int ssf);
-static int ftmod_ss7_fill_in_circuits(char *ch_map, int cicbase, int typeCntrl, int isup_id, ftdm_span_t *span);
+static int ftmod_ss7_fill_in_circuits(sng_isupCkt_t *isupCkt);
static int ftmod_ss7_next_timeslot(char *ch_map, sng_timeslot_t *timeslot);
/******************************************************************************/
@@ -91,9 +108,10 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa
const char *val = NULL;
ftdm_conf_node_t *ptr = NULL;
sng_route_t self_route;
- char ch_map[MAX_CIC_MAP_LENGTH];
- int typeCntrl = 0;
- int cicbase = 0;
+ sng_isupCkt_t isupCkt;
+
+ /* clean out the isup ckt */
+ memset(&isupCkt, 0x0, sizeof(sng_isupCkt_t));
/* clean out the self route */
memset(&self_route, 0x0, sizeof(sng_route_t));
@@ -124,24 +142,24 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa
if (!strcasecmp(var, "ch_map")) {
/**********************************************************************/
- strcpy(ch_map, val);
- SS7_DEBUG("\tFound channel map \"%s\"\n", ch_map);
+ strcpy(isupCkt.ch_map, val);
+ SS7_DEBUG("\tFound channel map \"%s\"\n", isupCkt.ch_map);
/**********************************************************************/
} else if (!strcasecmp(var, "typeCntrl")) {
if (!strcasecmp(val, "bothway")) {
- typeCntrl = BOTHWAY;
+ isupCkt.typeCntrl = BOTHWAY;
SS7_DEBUG("\tFound control type \"bothway\"\n");
} else if (!strcasecmp(val, "incoming")) {
- typeCntrl = INCOMING;
+ isupCkt.typeCntrl = INCOMING;
SS7_DEBUG("\tFound control type \"incoming\"\n");
} else if (!strcasecmp(val, "outgoing")) {
- typeCntrl = OUTGOING;
+ isupCkt.typeCntrl = OUTGOING;
SS7_DEBUG("\tFound control type \"outgoing\"\n");
} else if (!strcasecmp(val, "controlled")) {
- typeCntrl = CONTROLLED;
+ isupCkt.typeCntrl = CONTROLLED;
SS7_DEBUG("\tFound control type \"controlled\"\n");
} else if (!strcasecmp(val, "controlling")) {
- typeCntrl = CONTROLLING;
+ isupCkt.typeCntrl = CONTROLLING;
SS7_DEBUG("\tFound control type \"controlling\"\n");
} else {
SS7_ERROR("Found invalid circuit control type \"%s\"!", val);
@@ -149,8 +167,8 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa
}
/**********************************************************************/
} else if (!strcasecmp(var, "cicbase")) {
- cicbase = atoi(val);
- SS7_DEBUG("\tFound cicbase = %d\n", cicbase);
+ isupCkt.cicbase = atoi(val);
+ SS7_DEBUG("\tFound cicbase = %d\n", isupCkt.cicbase);
/**********************************************************************/
} else if (!strcasecmp(var, "dialplan")) {
/* do i give a shit about this??? */
@@ -169,7 +187,41 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa
/* move on to the next one */
x++;
}
- SS7_DEBUG("\tFound isup_interface = %s\n",g_ftdm_sngss7_data.cfg.isupIntf[x].name );
+
+ isupCkt.isupInf = x;
+ SS7_DEBUG("\tFound isup_interface = %s\n",g_ftdm_sngss7_data.cfg.isupIntf[x].name);
+ /**********************************************************************/
+ } else if (!strcasecmp(var, "isup.t3")) {
+ isupCkt.t3 = atoi(val);
+ SS7_DEBUG("\tFound isup t3 = \"%d\"\n", isupCkt.t3);
+ /**********************************************************************/
+ } else if (!strcasecmp(var, "isup.t12")) {
+ isupCkt.t12 = atoi(val);
+ SS7_DEBUG("\tFound isup t12 = \"%d\"\n", isupCkt.t12);
+ /**********************************************************************/
+ } else if (!strcasecmp(var, "isup.t13")) {
+ isupCkt.t13 = atoi(val);
+ SS7_DEBUG("\tFound isup t13 = \"%d\"\n", isupCkt.t13);
+ /**********************************************************************/
+ } else if (!strcasecmp(var, "isup.t14")) {
+ isupCkt.t14 = atoi(val);
+ SS7_DEBUG("\tFound isup t14 = \"%d\"\n", isupCkt.t14);
+ /**********************************************************************/
+ } else if (!strcasecmp(var, "isup.t15")) {
+ isupCkt.t15 = atoi(val);
+ SS7_DEBUG("\tFound isup t15 = \"%d\"\n", isupCkt.t15);
+ /**********************************************************************/
+ } else if (!strcasecmp(var, "isup.t16")) {
+ isupCkt.t16 = atoi(val);
+ SS7_DEBUG("\tFound isup t16 = \"%d\"\n", isupCkt.t16);
+ /**********************************************************************/
+ } else if (!strcasecmp(var, "isup.t17")) {
+ isupCkt.t17 = atoi(val);
+ SS7_DEBUG("\tFound isup t17 = \"%d\"\n", isupCkt.t17);
+ /**********************************************************************/
+ } else if (!strcasecmp(var, "isup.tval")) {
+ isupCkt.tval = atoi(val);
+ SS7_DEBUG("\tFound isup tval = \"%d\"\n", isupCkt.tval);
/**********************************************************************/
} else {
SS7_ERROR("Unknown parameter found =\"%s\"...ignoring it!\n", var);
@@ -192,10 +244,11 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa
}
+ /* fill the pointer to span into isupCkt */
+ isupCkt.span = span;
/* setup the circuits structure */
- if(ftmod_ss7_fill_in_circuits(ch_map, cicbase, typeCntrl,
- g_ftdm_sngss7_data.cfg.isupIntf[x].id, span)) {
+ if(ftmod_ss7_fill_in_circuits(&isupCkt)) {
SS7_ERROR("Failed to fill in circuits structure!\n");
goto ftmod_ss7_parse_xml_error;
}
@@ -573,6 +626,10 @@ static int ftmod_ss7_parse_mtp_link(ftdm_conf_node_t *mtp_link, sng_mtp_link_t *
mtpLink->mtp3.ssf = SSF_NAT;
} else if (!strcasecmp(parm->val, "int")) {
mtpLink->mtp3.ssf = SSF_INTL;
+ } else if (!strcasecmp(parm->val, "spare")) {
+ mtpLink->mtp3.ssf = SSF_SPARE;
+ } else if (!strcasecmp(parm->val, "res")) {
+ mtpLink->mtp3.ssf = SSF_RES;
} else {
SS7_ERROR("\tFound an invalid ssf of \"%s\"!\n", parm->val);
return FTDM_FAIL;
@@ -582,6 +639,130 @@ static int ftmod_ss7_parse_mtp_link(ftdm_conf_node_t *mtp_link, sng_mtp_link_t *
mtpLink->mtp3.slc = atoi(parm->val);
SS7_DEBUG("\tFound mtpLink->slc = \"%d\"\n",mtpLink->mtp3.slc);
/**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp2.t1")) {
+ mtpLink->mtp2.t1 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp2 t1 = \"%d\"\n",mtpLink->mtp2.t1);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp2.t2")) {
+ mtpLink->mtp2.t2 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp2 t2 = \"%d\"\n",mtpLink->mtp2.t2);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp2.t3")) {
+ mtpLink->mtp2.t3 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp2 t3 = \"%d\"\n",mtpLink->mtp2.t3);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp2.t4n")) {
+ mtpLink->mtp2.t4n = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp2 t4n = \"%d\"\n",mtpLink->mtp2.t4n);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp2.t4e")) {
+ mtpLink->mtp2.t4e = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp2 t4e = \"%d\"\n",mtpLink->mtp2.t4e);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp2.t5")) {
+ mtpLink->mtp2.t5 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp2 t5 = \"%d\"\n",mtpLink->mtp2.t5);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp2.t6")) {
+ mtpLink->mtp2.t6 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp2 t6 = \"%d\"\n",mtpLink->mtp2.t6);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp2.t7")) {
+ mtpLink->mtp2.t7 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp2 t7 = \"%d\"\n",mtpLink->mtp2.t7);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t1")) {
+ mtpLink->mtp3.t1 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t1 = \"%d\"\n",mtpLink->mtp3.t1);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t2")) {
+ mtpLink->mtp3.t2 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t2 = \"%d\"\n",mtpLink->mtp3.t2);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t3")) {
+ mtpLink->mtp3.t3 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t3 = \"%d\"\n",mtpLink->mtp3.t3);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t4")) {
+ mtpLink->mtp3.t4 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t4 = \"%d\"\n",mtpLink->mtp3.t4);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t5")) {
+ mtpLink->mtp3.t5 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t5 = \"%d\"\n",mtpLink->mtp3.t5);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t7")) {
+ mtpLink->mtp3.t7 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t7 = \"%d\"\n",mtpLink->mtp3.t7);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t12")) {
+ mtpLink->mtp3.t12 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t12 = \"%d\"\n",mtpLink->mtp3.t12);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t13")) {
+ mtpLink->mtp3.t13 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t13 = \"%d\"\n",mtpLink->mtp3.t13);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t14")) {
+ mtpLink->mtp3.t14 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t14 = \"%d\"\n",mtpLink->mtp3.t14);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t17")) {
+ mtpLink->mtp3.t17 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t17 = \"%d\"\n",mtpLink->mtp3.t17);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t22")) {
+ mtpLink->mtp3.t22 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t22 = \"%d\"\n",mtpLink->mtp3.t22);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t23")) {
+ mtpLink->mtp3.t23 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t23 = \"%d\"\n",mtpLink->mtp3.t23);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t24")) {
+ mtpLink->mtp3.t24 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t24 = \"%d\"\n",mtpLink->mtp3.t24);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t31")) {
+ mtpLink->mtp3.t31 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t31 = \"%d\"\n",mtpLink->mtp3.t31);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t32")) {
+ mtpLink->mtp3.t32 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t32 = \"%d\"\n",mtpLink->mtp3.t32);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t33")) {
+ mtpLink->mtp3.t33 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t33 = \"%d\"\n",mtpLink->mtp3.t33);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t34")) {
+ mtpLink->mtp3.t34 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t34 = \"%d\"\n",mtpLink->mtp3.t34);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t35")) {
+ mtpLink->mtp3.t35 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t35 = \"%d\"\n",mtpLink->mtp3.t35);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t36")) {
+ mtpLink->mtp3.t36 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t36 = \"%d\"\n",mtpLink->mtp3.t36);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t37")) {
+ mtpLink->mtp3.t37 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t37 = \"%d\"\n",mtpLink->mtp3.t37);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.tcraft")) {
+ mtpLink->mtp3.tcraft = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 tcraft = \"%d\"\n",mtpLink->mtp3.tcraft);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.tflc")) {
+ mtpLink->mtp3.tflc = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 tflc = \"%d\"\n",mtpLink->mtp3.tflc);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.tbnd")) {
+ mtpLink->mtp3.tbnd = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 tbnd = \"%d\"\n",mtpLink->mtp3.tbnd);
+ /**********************************************************************/
} else {
SS7_ERROR("\tFound an invalid parameter \"%s\"!\n", parm->val);
return FTDM_FAIL;
@@ -697,6 +878,50 @@ static int ftmod_ss7_parse_mtp_route(ftdm_conf_node_t *mtp_route)
return FTDM_FAIL;
}
/**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t6")) {
+ mtpRoute.t6 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t6 = \"%d\"\n",mtpRoute.t6);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t8")) {
+ mtpRoute.t8 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t8 = \"%d\"\n",mtpRoute.t8);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t10")) {
+ mtpRoute.t10 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t10 = \"%d\"\n",mtpRoute.t10);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t11")) {
+ mtpRoute.t11 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t11 = \"%d\"\n",mtpRoute.t11);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t15")) {
+ mtpRoute.t15 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t15 = \"%d\"\n",mtpRoute.t15);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t16")) {
+ mtpRoute.t16 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t16 = \"%d\"\n",mtpRoute.t16);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t18")) {
+ mtpRoute.t18 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t18 = \"%d\"\n",mtpRoute.t18);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t19")) {
+ mtpRoute.t19 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t19 = \"%d\"\n",mtpRoute.t19);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t21")) {
+ mtpRoute.t21 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t21 = \"%d\"\n",mtpRoute.t21);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t25")) {
+ mtpRoute.t25 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t25 = \"%d\"\n",mtpRoute.t25);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "mtp3.t26")) {
+ mtpRoute.t26 = atoi(parm->val);
+ SS7_DEBUG("\tFound mtp3 t26 = \"%d\"\n",mtpRoute.t26);
+ /**********************************************************************/
} else {
SS7_ERROR("\tFound an invalid parameter \"%s\"!\n", parm->val);
return FTDM_FAIL;
@@ -755,6 +980,8 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface)
int num_parms = isup_interface->n_parameters;
int i;
int linkSetId;
+ int flag_cld_nadi = 0;
+ int flag_clg_nadi = 0;
memset(&sng_isup, 0x0, sizeof(sng_isup));
memset(&sng_isap, 0x0, sizeof(sng_isap));
@@ -827,6 +1054,12 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface)
} else if (!strcasecmp(parm->val, "int")) {
sng_isup.ssf = SSF_INTL;
sng_isap.ssf = SSF_INTL;
+ } else if (!strcasecmp(parm->val, "spare")) {
+ sng_isup.ssf = SSF_SPARE;
+ sng_isap.ssf = SSF_SPARE;
+ } else if (!strcasecmp(parm->val, "res")) {
+ sng_isup.ssf = SSF_RES;
+ sng_isap.ssf = SSF_RES;
} else {
SS7_ERROR("\tFound an invalid ssf of \"%s\"!\n", parm->val);
return FTDM_FAIL;
@@ -840,6 +1073,216 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface)
SS7_DEBUG("\tFound license file = %s\n", g_ftdm_sngss7_data.cfg.license);
SS7_DEBUG("\tFound signature file = %s\n", g_ftdm_sngss7_data.cfg.signature);
/**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t1")) {
+ sng_isap.t1 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t1 = \"%d\"\n",sng_isap.t1);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t2")) {
+ sng_isap.t2 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t2 = \"%d\"\n",sng_isap.t2);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t4")) {
+ sng_isup.t4 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t4 = \"%d\"\n",sng_isup.t4);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t5")) {
+ sng_isap.t5 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t5 = \"%d\"\n",sng_isap.t5);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t6")) {
+ sng_isap.t6 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t6 = \"%d\"\n",sng_isap.t6);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t7")) {
+ sng_isap.t7 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t7 = \"%d\"\n",sng_isap.t7);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t8")) {
+ sng_isap.t8 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t8 = \"%d\"\n",sng_isap.t8);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t9")) {
+ sng_isap.t9 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t9 = \"%d\"\n",sng_isap.t9);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t10")) {
+ sng_isup.t10 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t10 = \"%d\"\n",sng_isup.t10);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t11")) {
+ sng_isup.t11 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t11 = \"%d\"\n",sng_isup.t11);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t18")) {
+ sng_isup.t18 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t18 = \"%d\"\n",sng_isup.t18);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t19")) {
+ sng_isup.t19 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t19 = \"%d\"\n",sng_isup.t19);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t20")) {
+ sng_isup.t20 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t20 = \"%d\"\n",sng_isup.t20);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t21")) {
+ sng_isup.t21 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t21 = \"%d\"\n",sng_isup.t21);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t22")) {
+ sng_isup.t22 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t22 = \"%d\"\n",sng_isup.t22);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t23")) {
+ sng_isup.t23 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t23 = \"%d\"\n",sng_isup.t23);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t24")) {
+ sng_isup.t24 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t24 = \"%d\"\n",sng_isup.t24);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t25")) {
+ sng_isup.t25 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t25 = \"%d\"\n",sng_isup.t25);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t26")) {
+ sng_isup.t26 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t26 = \"%d\"\n",sng_isup.t26);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t28")) {
+ sng_isup.t28 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t28 = \"%d\"\n",sng_isup.t28);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t29")) {
+ sng_isup.t29 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t29 = \"%d\"\n",sng_isup.t29);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t30")) {
+ sng_isup.t30 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t30 = \"%d\"\n",sng_isup.t30);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t31")) {
+ sng_isap.t31 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t31 = \"%d\"\n",sng_isap.t31);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t32")) {
+ sng_isup.t32 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t32 = \"%d\"\n",sng_isup.t32);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t33")) {
+ sng_isap.t33 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t33 = \"%d\"\n",sng_isap.t33);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t34")) {
+ sng_isap.t34 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t34 = \"%d\"\n",sng_isap.t34);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t35")) {
+ sng_isup.t35 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t35 = \"%d\"\n",sng_isup.t35);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t36")) {
+ sng_isap.t36 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t36 = \"%d\"\n",sng_isap.t36);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t37")) {
+ sng_isup.t37 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t37 = \"%d\"\n",sng_isup.t37);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t38")) {
+ sng_isup.t38 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t38 = \"%d\"\n",sng_isup.t38);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.t39")) {
+ sng_isup.t39 = atoi(parm->val);
+ SS7_DEBUG("\tFound isup t39 = \"%d\"\n",sng_isup.t39);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.tccr")) {
+ sng_isap.tccr = atoi(parm->val);
+ SS7_DEBUG("\tFound isup tccr = \"%d\"\n",sng_isap.tccr);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.tccrt")) {
+ sng_isap.tccrt = atoi(parm->val);
+ SS7_DEBUG("\tFound isup tccrt = \"%d\"\n",sng_isap.tccrt);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.tex")) {
+ sng_isap.tex = atoi(parm->val);
+ SS7_DEBUG("\tFound isup tex = \"%d\"\n",sng_isap.tex);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.tect")) {
+ sng_isap.tect = atoi(parm->val);
+ SS7_DEBUG("\tFound isup tect = \"%d\"\n",sng_isap.tect);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.tcrm")) {
+ sng_isap.tcrm = atoi(parm->val);
+ SS7_DEBUG("\tFound isup tcrm = \"%d\"\n",sng_isap.tcrm);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.tcra")) {
+ sng_isap.tcra = atoi(parm->val);
+ SS7_DEBUG("\tFound isup tcra = \"%d\"\n",sng_isap.tcra);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.tfgr")) {
+ sng_isup.tfgr = atoi(parm->val);
+ SS7_DEBUG("\tFound isup tfgr = \"%d\"\n",sng_isup.tfgr);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.trelrsp")) {
+ sng_isap.trelrsp = atoi(parm->val);
+ SS7_DEBUG("\tFound isup trelrsp = \"%d\"\n",sng_isap.trelrsp);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.tfnlrelrsp")) {
+ sng_isap.tfnlrelrsp = atoi(parm->val);
+ SS7_DEBUG("\tFound isup tfnlrelrsp = \"%d\"\n",sng_isap.tfnlrelrsp);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.tfnlrelrsp")) {
+ sng_isap.tfnlrelrsp = atoi(parm->val);
+ SS7_DEBUG("\tFound isup tfnlrelrsp = \"%d\"\n",sng_isap.tfnlrelrsp);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.tpause")) {
+ sng_isup.tpause = atoi(parm->val);
+ SS7_DEBUG("\tFound isup tpause = \"%d\"\n",sng_isup.tpause);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "isup.tstaenq")) {
+ sng_isup.tstaenq = atoi(parm->val);
+ SS7_DEBUG("\tFound isup tstaenq = \"%d\"\n",sng_isup.tstaenq);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "clg_nadi")) {
+ /**********************************************************************/
+ /* throw the flag so that we know we got this optional parameter */
+ flag_clg_nadi = 1;
+ sng_isup.clg_nadi = atoi(parm->val);
+ SS7_DEBUG("\tFound default CLG_NADI value = %d\n", sng_isup.clg_nadi);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "cld_nadi")) {
+ /**********************************************************************/
+ /* throw the flag so that we know we got this optional parameter */
+ flag_cld_nadi = 1;
+ sng_isup.cld_nadi = atoi(parm->val);
+ SS7_DEBUG("\tFound default CLD_NADI value = %d\n", sng_isup.cld_nadi);
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "obci_bita")) {
+ /**********************************************************************/
+ if (*parm->val == '1') {
+ sngss7_set_options(&sng_isup, SNGSS7_ACM_OBCI_BITA);
+ SS7_DEBUG("\tFound Optional Backwards Indicator: Bit A (early media) enable option\n");
+ } else if (*parm->val == '0') {
+ sngss7_clear_options(&sng_isup, SNGSS7_ACM_OBCI_BITA);
+ SS7_DEBUG("\tFound Optional Backwards Indicator: Bit A (early media) disable option\n");
+ } else {
+ SS7_DEBUG("\tInvalid value for \"obci_bita\" option\n");
+ }
+ /**********************************************************************/
+ } else if (!strcasecmp(parm->var, "lpa_on_cot")) {
+ /**********************************************************************/
+ if (*parm->val == '1') {
+ sngss7_set_options(&sng_isup, SNGSS7_LPA_FOR_COT);
+ SS7_DEBUG("\tFound Tx LPA on COT enable option\n");
+ } else if (*parm->val == '0') {
+ sngss7_clear_options(&sng_isup, SNGSS7_LPA_FOR_COT);
+ SS7_DEBUG("\tFound Tx LPA on COT disable option\n");
+ } else {
+ SS7_DEBUG("\tInvalid value for \"lpa_on_cot\" option\n");
+ }
+ /**********************************************************************/
} else {
SS7_ERROR("\tFound an invalid parameter \"%s\"!\n", parm->val);
return FTDM_FAIL;
@@ -850,6 +1293,17 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface)
parm = parm + 1;
}
+ /* check if the user filled in a nadi value by looking at flag */
+ if (!flag_cld_nadi) {
+ /* default the nadi value to national */
+ sng_isup.cld_nadi = 0x03;
+ }
+
+ if (!flag_clg_nadi) {
+ /* default the nadi value to national */
+ sng_isup.clg_nadi = 0x03;
+ }
+
/* trickle down the SPC to all sub entities */
linkSetId = g_ftdm_sngss7_data.cfg.mtpRoute[sng_isup.mtpRouteId].linkSetId;
@@ -1249,7 +1703,9 @@ static int ftmod_ss7_fill_in_isup_interface(sng_isup_inf_t *sng_isup)
g_ftdm_sngss7_data.cfg.isupIntf[i].switchType = sng_isup->switchType;
g_ftdm_sngss7_data.cfg.isupIntf[i].ssf = sng_isup->ssf;
g_ftdm_sngss7_data.cfg.isupIntf[i].isap = sng_isup->isap;
-
+ g_ftdm_sngss7_data.cfg.isupIntf[i].cld_nadi = sng_isup->cld_nadi;
+ g_ftdm_sngss7_data.cfg.isupIntf[i].clg_nadi = sng_isup->clg_nadi;
+ g_ftdm_sngss7_data.cfg.isupIntf[i].options = sng_isup->options;
if (sng_isup->t4 != 0) {
g_ftdm_sngss7_data.cfg.isupIntf[i].t4 = sng_isup->t4;
} else {
@@ -1544,7 +2000,7 @@ static int ftmod_ss7_fill_in_self_route(int spc, int linkType, int switchType, i
}
/******************************************************************************/
-static int ftmod_ss7_fill_in_circuits(char *ch_map, int cicbase, int typeCntrl, int isup_id, ftdm_span_t *span)
+static int ftmod_ss7_fill_in_circuits(sng_isupCkt_t *isupCkt)
{
sngss7_chan_data_t *ss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
@@ -1555,10 +2011,10 @@ static int ftmod_ss7_fill_in_circuits(char *ch_map, int cicbase, int typeCntrl,
count = 1;
- while (ch_map[0] != '\0') {
+ while (isupCkt->ch_map[0] != '\0') {
/* pull out the next timeslot */
- if (ftmod_ss7_next_timeslot(ch_map, ×lot)) {
+ if (ftmod_ss7_next_timeslot(isupCkt->ch_map, ×lot)) {
SS7_ERROR("Failed to parse the channel map!\n");
return FTDM_FAIL;
}
@@ -1568,10 +2024,10 @@ static int ftmod_ss7_fill_in_circuits(char *ch_map, int cicbase, int typeCntrl,
x = 1;
while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) {
if ((g_ftdm_sngss7_data.cfg.isupCkt[x].chan == count) &&
- (g_ftdm_sngss7_data.cfg.isupCkt[x].span == span->channels[1]->physical_span_id)) {
+ (g_ftdm_sngss7_data.cfg.isupCkt[x].span == isupCkt->span->channels[1]->physical_span_id)) {
SS7_DEVEL_DEBUG("Circuit for span=%d, chan=%d is already exists...id=%d\n",
- span->channels[1]->physical_span_id,
+ isupCkt->span->channels[1]->physical_span_id,
count,
x);
@@ -1585,7 +2041,7 @@ static int ftmod_ss7_fill_in_circuits(char *ch_map, int cicbase, int typeCntrl,
/* check why we exited the while loop */
if (g_ftdm_sngss7_data.cfg.isupCkt[x].id == 0) {
SS7_DEVEL_DEBUG("Circuit for span=%d, chan=%d is new...id=%d\n",
- span->channels[1]->physical_span_id,
+ isupCkt->span->channels[1]->physical_span_id,
count,
x);
@@ -1596,7 +2052,7 @@ static int ftmod_ss7_fill_in_circuits(char *ch_map, int cicbase, int typeCntrl,
/* circuit is new so fill in the needed information */
g_ftdm_sngss7_data.cfg.isupCkt[x].id = x;
- g_ftdm_sngss7_data.cfg.isupCkt[x].span = span->channels[1]->physical_span_id;
+ g_ftdm_sngss7_data.cfg.isupCkt[x].span = isupCkt->span->channels[1]->physical_span_id;
g_ftdm_sngss7_data.cfg.isupCkt[x].chan = count;
if (timeslot.siglink) {
g_ftdm_sngss7_data.cfg.isupCkt[x].type = SIG;
@@ -1605,22 +2061,14 @@ static int ftmod_ss7_fill_in_circuits(char *ch_map, int cicbase, int typeCntrl,
}
if (timeslot.channel) {
- g_ftdm_sngss7_data.cfg.isupCkt[x].cic = cicbase;
- cicbase++;
+ g_ftdm_sngss7_data.cfg.isupCkt[x].cic = isupCkt->cicbase;
+ isupCkt->cicbase++;
} else {
g_ftdm_sngss7_data.cfg.isupCkt[x].cic = 0;
}
- g_ftdm_sngss7_data.cfg.isupCkt[x].infId = isup_id;
- g_ftdm_sngss7_data.cfg.isupCkt[x].typeCntrl = typeCntrl;
- g_ftdm_sngss7_data.cfg.isupCkt[x].t3 = 1200;
- g_ftdm_sngss7_data.cfg.isupCkt[x].t12 = 300;
- g_ftdm_sngss7_data.cfg.isupCkt[x].t13 = 3000;
- g_ftdm_sngss7_data.cfg.isupCkt[x].t14 = 300;
- g_ftdm_sngss7_data.cfg.isupCkt[x].t15 = 3000;
- g_ftdm_sngss7_data.cfg.isupCkt[x].t16 = 300;
- g_ftdm_sngss7_data.cfg.isupCkt[x].t17 = 3000;
- g_ftdm_sngss7_data.cfg.isupCkt[x].tval = 10;
- g_ftdm_sngss7_data.cfg.isupCkt[x].ssf = g_ftdm_sngss7_data.cfg.isupIntf[isup_id].ssf;
+ g_ftdm_sngss7_data.cfg.isupCkt[x].infId = isupCkt->isupInf;
+ g_ftdm_sngss7_data.cfg.isupCkt[x].typeCntrl = isupCkt->typeCntrl;
+ g_ftdm_sngss7_data.cfg.isupCkt[x].ssf = g_ftdm_sngss7_data.cfg.isupIntf[isupCkt->isupInf].ssf;
g_ftdm_sngss7_data.cfg.isupCkt[x].obj = ss7_info;
} /* if (g_ftdm_sngss7_data.cfg.isupCkt[x].id == 0) */
@@ -1631,26 +2079,26 @@ static int ftmod_ss7_fill_in_circuits(char *ch_map, int cicbase, int typeCntrl,
} else { /* if ((timeslot.siglink) || (timeslot.gap)) */
/* find the ftdm the channel structure for this channel*/
i = 1;
- while (span->channels[i] != NULL) {
- if (span->channels[i]->physical_chan_id == timeslot.channel) {
+ while (isupCkt->span->channels[i] != NULL) {
+ if (isupCkt->span->channels[i]->physical_chan_id == timeslot.channel) {
break;
}
i++;
} /* while (span->channels[i] != NULL) */
- if (span->channels[i] == NULL) {
+ if (isupCkt->span->channels[i] == NULL) {
/* we weren't able to find the channel in the ftdm channels */
SS7_ERROR("Unable to find the requested channel %d in the FreeTDM channels!\n", timeslot.channel);
return FTDM_FAIL;
} else {
- ftdmchan = span->channels[i];
+ ftdmchan = isupCkt->span->channels[i];
}
/* try to find a match for the physical span and chan */
x = 1;
while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) {
- if ((g_ftdm_sngss7_data.cfg.isupCkt[x].chan == ftdmchan->physical_chan_id)
- && (g_ftdm_sngss7_data.cfg.isupCkt[x].span == ftdmchan->physical_span_id)) {
+ if ((g_ftdm_sngss7_data.cfg.isupCkt[x].chan == ftdmchan->physical_chan_id) &&
+ (g_ftdm_sngss7_data.cfg.isupCkt[x].span == ftdmchan->physical_span_id)) {
/* we have a match so this circuit already exists in the structure */
break;
@@ -1673,33 +2121,65 @@ static int ftmod_ss7_fill_in_circuits(char *ch_map, int cicbase, int typeCntrl,
ftdmchan->call_data = ss7_info;
/* prepare the timer structures */
- ss7_info->t35.sched = ((sngss7_span_data_t *)span->mod_data)->sched;
+ ss7_info->t35.sched = ((sngss7_span_data_t *)isupCkt->span->mod_data)->sched;
ss7_info->t35.counter = 1;
- ss7_info->t35.beat = g_ftdm_sngss7_data.cfg.isupIntf[isup_id].t35*100; /* beat is in ms, t35 is in 100ms */
+ ss7_info->t35.beat = g_ftdm_sngss7_data.cfg.isupIntf[isupCkt->isupInf].t35*100; /* beat is in ms, t35 is in 100ms */
ss7_info->t35.callback = handle_isup_t35;
ss7_info->t35.sngss7_info = ss7_info;
/* circuit is new so fill in the needed information */
- g_ftdm_sngss7_data.cfg.isupCkt[x].id = x;
+ g_ftdm_sngss7_data.cfg.isupCkt[x].id = x;
g_ftdm_sngss7_data.cfg.isupCkt[x].span = ftdmchan->physical_span_id;
g_ftdm_sngss7_data.cfg.isupCkt[x].chan = ftdmchan->physical_chan_id;
g_ftdm_sngss7_data.cfg.isupCkt[x].type = VOICE;
- g_ftdm_sngss7_data.cfg.isupCkt[x].cic = cicbase;
- g_ftdm_sngss7_data.cfg.isupCkt[x].infId = isup_id;
- g_ftdm_sngss7_data.cfg.isupCkt[x].typeCntrl = typeCntrl;
- g_ftdm_sngss7_data.cfg.isupCkt[x].t3 = 1200;
- g_ftdm_sngss7_data.cfg.isupCkt[x].t12 = 300;
- g_ftdm_sngss7_data.cfg.isupCkt[x].t13 = 3000;
- g_ftdm_sngss7_data.cfg.isupCkt[x].t14 = 300;
- g_ftdm_sngss7_data.cfg.isupCkt[x].t15 = 3000;
- g_ftdm_sngss7_data.cfg.isupCkt[x].t16 = 300;
- g_ftdm_sngss7_data.cfg.isupCkt[x].t17 = 3000;
- g_ftdm_sngss7_data.cfg.isupCkt[x].tval = 10;
+ g_ftdm_sngss7_data.cfg.isupCkt[x].cic = isupCkt->cicbase;
+ g_ftdm_sngss7_data.cfg.isupCkt[x].infId = isupCkt->isupInf;
+ g_ftdm_sngss7_data.cfg.isupCkt[x].typeCntrl = isupCkt->typeCntrl;
+ if (isupCkt->t3 == 0) {
+ g_ftdm_sngss7_data.cfg.isupCkt[x].t3 = 1200;
+ } else {
+ g_ftdm_sngss7_data.cfg.isupCkt[x].t3 = isupCkt->t3;
+ }
+ if (isupCkt->t12 == 0) {
+ g_ftdm_sngss7_data.cfg.isupCkt[x].t12 = 300;
+ } else {
+ g_ftdm_sngss7_data.cfg.isupCkt[x].t12 = isupCkt->t12;
+ }
+ if (isupCkt->t13 == 0) {
+ g_ftdm_sngss7_data.cfg.isupCkt[x].t13 = 3000;
+ } else {
+ g_ftdm_sngss7_data.cfg.isupCkt[x].t13 = isupCkt->t13;
+ }
+ if (isupCkt->t14 == 0) {
+ g_ftdm_sngss7_data.cfg.isupCkt[x].t14 = 300;
+ } else {
+ g_ftdm_sngss7_data.cfg.isupCkt[x].t14 = isupCkt->t14;
+ }
+ if (isupCkt->t15 == 0) {
+ g_ftdm_sngss7_data.cfg.isupCkt[x].t15 = 3000;
+ } else {
+ g_ftdm_sngss7_data.cfg.isupCkt[x].t15 = isupCkt->t15;
+ }
+ if (isupCkt->t16 == 0) {
+ g_ftdm_sngss7_data.cfg.isupCkt[x].t16 = 300;
+ } else {
+ g_ftdm_sngss7_data.cfg.isupCkt[x].t16 = isupCkt->t16;
+ }
+ if (isupCkt->t17 == 0) {
+ g_ftdm_sngss7_data.cfg.isupCkt[x].t17 = 3000;
+ } else {
+ g_ftdm_sngss7_data.cfg.isupCkt[x].t17 = isupCkt->t17;
+ }
+ if (isupCkt->tval == 0) {
+ g_ftdm_sngss7_data.cfg.isupCkt[x].tval = 10;
+ } else {
+ g_ftdm_sngss7_data.cfg.isupCkt[x].tval = isupCkt->tval;
+ }
g_ftdm_sngss7_data.cfg.isupCkt[x].obj = ss7_info;
- g_ftdm_sngss7_data.cfg.isupCkt[x].ssf = g_ftdm_sngss7_data.cfg.isupIntf[isup_id].ssf;
+ g_ftdm_sngss7_data.cfg.isupCkt[x].ssf = g_ftdm_sngss7_data.cfg.isupIntf[isupCkt->isupInf].ssf;
/* increment the cicbase */
- cicbase++;
+ isupCkt->cicbase++;
} else { /* if (g_ftdm_sngss7_data.cfg.isupCkt[x].id == 0) */
SS7_DEBUG("Circuit for span=%d, chan=%d is new...id=%d\n",
ftdmchan->physical_span_id,
@@ -1745,12 +2225,12 @@ static int ftmod_ss7_fill_in_circuits(char *ch_map, int cicbase, int typeCntrl,
/******************************************************************************/
static int ftmod_ss7_next_timeslot(char *ch_map, sng_timeslot_t *timeslot)
{
- int i;
- int x;
- int lower;
- int upper;
- char tmp[5]; /*KONRAD FIX ME*/
- char new_ch_map[MAX_CIC_LENGTH];
+ int i;
+ int x;
+ int lower;
+ int upper;
+ char tmp[5]; /*KONRAD FIX ME*/
+ char new_ch_map[MAX_CIC_LENGTH];
memset(&tmp[0], '\0', sizeof(tmp));
memset(&new_ch_map[0], '\0', sizeof(new_ch_map));
diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c
index 5a472e5a8d..86940107e7 100644
--- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c
+++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c
@@ -280,6 +280,25 @@ static unsigned wp_open_range(ftdm_span_t *span, unsigned spanno, unsigned start
ftdm_channel_set_feature(chan, FTDM_CHANNEL_FEATURE_DTMF_DETECT);
dtmf = "hardware";
}
+
+ err = sangoma_tdm_get_hw_ec(chan->sockfd, &tdm_api);
+ if (err > 0) {
+ ftdm_channel_set_feature(chan, FTDM_CHANNEL_FEATURE_HWEC);
+ }
+
+#ifdef WP_API_FEATURE_HWEC_PERSIST
+ err = sangoma_tdm_get_hwec_persist_status(chan->sockfd, &tdm_api);
+ if (err == 0) {
+ ftdm_channel_set_feature(chan, FTDM_CHANNEL_FEATURE_HWEC_DISABLED_ON_IDLE);
+ }
+#else
+ if (span->trunk_type == FTDM_TRUNK_BRI || span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
+ ftdm_log(FTDM_LOG_WARNING, "WP_API_FEATURE_HWEC_PERSIST feature is not supported \
+ with your version of libsangoma, you should update your Wanpipe drivers\n");
+
+ }
+#endif
+
}
#ifdef LIBSANGOMA_VERSION
@@ -598,18 +617,33 @@ static FIO_COMMAND_FUNCTION(wanpipe_command)
break;
case FTDM_COMMAND_ENABLE_ECHOCANCEL:
{
+#ifdef WP_API_FEATURE_EC_CHAN_STAT
+ err=sangoma_tdm_get_hwec_chan_status(ftdmchan->sockfd, &tdm_api);
+ if (err > 0) {
+ /* Hardware echo canceller already enabled */
+ err = 0;
+ break;
+ }
+#endif
err=sangoma_tdm_enable_hwec(ftdmchan->sockfd, &tdm_api);
if (err) {
- snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "HWEC Enable Failed");
+ snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "HWEC Enable Failed");
return FTDM_FAIL;
}
}
break;
case FTDM_COMMAND_DISABLE_ECHOCANCEL:
{
+#ifdef WP_API_FEATURE_EC_CHAN_STAT
+ err=sangoma_tdm_get_hwec_chan_status(ftdmchan->sockfd, &tdm_api);
+ if (!err) {
+ /* Hardware echo canceller already disabled */
+ break;
+ }
+#endif
err=sangoma_tdm_disable_hwec(ftdmchan->sockfd, &tdm_api);
if (err) {
- snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "HWEC Disable Failed");
+ snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "HWEC Disable Failed");
return FTDM_FAIL;
}
}
diff --git a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c
index c4ba3ae749..ae9398418a 100644
--- a/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c
+++ b/libs/freetdm/src/ftmod/ftmod_zt/ftmod_zt.c
@@ -170,8 +170,8 @@ static const char *chanpath = NULL;
static const char dahdi_ctlpath[] = "/dev/dahdi/ctl";
static const char dahdi_chanpath[] = "/dev/dahdi/channel";
-static const char zt_ctlpath[] = "/dev/ftdm/ctl";
-static const char zt_chanpath[] = "/dev/ftdm/channel";
+static const char zt_ctlpath[] = "/dev/zap/ctl";
+static const char zt_chanpath[] = "/dev/zap/channel";
static ftdm_socket_t CONTROL_FD = ZT_INVALID_SOCKET;
@@ -974,7 +974,7 @@ FIO_SPAN_POLL_EVENT_FUNCTION(zt_poll_event)
*/
FIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event)
{
- uint32_t i, event_id = 0;
+ uint32_t i, event_id = FTDM_OOB_INVALID;
zt_event_t zt_event_id = 0;
for(i = 1; i <= span->chan_count; i++) {
@@ -1022,6 +1022,8 @@ FIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event)
event_id = FTDM_OOB_OFFHOOK;
} else if (span->channels[i]->type == FTDM_CHAN_TYPE_FXO) {
event_id = FTDM_OOB_RING_START;
+ } else {
+ event_id = FTDM_OOB_NOOP;
}
}
break;
diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h
index b1188e35fc..64ecc2e357 100644
--- a/libs/freetdm/src/include/freetdm.h
+++ b/libs/freetdm/src/include/freetdm.h
@@ -667,9 +667,6 @@ FT_DECLARE(ftdm_status_t) ftdm_span_set_sig_status(ftdm_span_t *span, ftdm_signa
/*! \brief Get span signaling status (ie: whether protocol layer is up or down) */
FT_DECLARE(ftdm_status_t) ftdm_span_get_sig_status(ftdm_span_t *span, ftdm_signaling_status_t *status);
-/*! \brief Get span signaling status (ie: whether protocol layer is up or down) */
-FT_DECLARE(void) ftdm_channel_clear_detected_tones(ftdm_channel_t *ftdmchan);
-
/*!
* \brief Set user private data in the channel
*
@@ -1177,16 +1174,6 @@ FT_DECLARE(ftdm_iterator_t *) ftdm_span_get_chan_iterator(const ftdm_span_t *spa
*/
FT_DECLARE(char *) ftdm_api_execute(const char *cmd);
-/*!
- * \brief Disables CPU monitoring
- *
- * \note CPU monitoring is enabled by default. This means a thread will be launched at startup (ftdm_global_init)
- * with the sole purpose of monitoring system-wide CPU usage. If the CPU usage raises above a defined
- * threshold, no new calls will be accepted (neither incoming or outgoing)
- *
- */
-FT_DECLARE(void) ftdm_cpu_monitor_disable(void);
-
/*!
* \brief Create a configuration node
*
@@ -1279,7 +1266,7 @@ FT_DECLARE(const char *) ftdm_channel_get_state_str(const ftdm_channel_t *channe
FT_DECLARE(const char *) ftdm_channel_get_last_state_str(const ftdm_channel_t *channel);
/*! \brief For display debugging purposes you can display this string which describes the history of the channel
- * \param The channel
+ * \param channel The channel to get the history from
* \return History string for the channel. You must free the string with ftdm_free
*/
FT_DECLARE(char *) ftdm_channel_get_history_str(const ftdm_channel_t *channel);
diff --git a/libs/freetdm/src/include/ftdm_declare.h b/libs/freetdm/src/include/ftdm_declare.h
index 03071a60bb..2985ab4f45 100644
--- a/libs/freetdm/src/include/ftdm_declare.h
+++ b/libs/freetdm/src/include/ftdm_declare.h
@@ -70,6 +70,7 @@ extern "C" {
#define FT_DECLARE_NONSTD(type) __declspec(dllimport) type __cdecl
#define FT_DECLARE_DATA __declspec(dllimport)
#endif
+#define FT_DECLARE_INLINE(type) type
#define EX_DECLARE_DATA __declspec(dllexport)
#else
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(HAVE_VISIBILITY)
@@ -81,6 +82,7 @@ extern "C" {
#define FT_DECLARE_NONSTD(type) type
#define FT_DECLARE_DATA
#endif
+#define FT_DECLARE_INLINE(type) type __inline__
#define EX_DECLARE_DATA
#endif
@@ -156,7 +158,12 @@ typedef __int64 int64_t;
typedef __int32 int32_t;
typedef __int16 int16_t;
typedef __int8 int8_t;
+#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
+#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
#else
+#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
+#endif /* _MSC_VER */
+#else /* __WINDOWS__ */
#define FTDM_INVALID_SOCKET -1
typedef int ftdm_socket_t;
#include
diff --git a/libs/freetdm/src/include/private/ftdm_core.h b/libs/freetdm/src/include/private/ftdm_core.h
index beee868633..8bdbdd60f8 100644
--- a/libs/freetdm/src/include/private/ftdm_core.h
+++ b/libs/freetdm/src/include/private/ftdm_core.h
@@ -595,6 +595,10 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_queue_dtmf(ftdm_channel_t *ftdmchan, cons
/* dequeue pending signals and notify the user via the span signal callback */
FT_DECLARE(ftdm_status_t) ftdm_span_trigger_signals(const ftdm_span_t *span);
+/*! \brief clear the tone detector state */
+FT_DECLARE(void) ftdm_channel_clear_detected_tones(ftdm_channel_t *ftdmchan);
+
+
/*!
\brief Assert condition
*/
diff --git a/libs/freetdm/src/include/private/ftdm_sched.h b/libs/freetdm/src/include/private/ftdm_sched.h
index 9a222896f5..c1818d8bb5 100644
--- a/libs/freetdm/src/include/private/ftdm_sched.h
+++ b/libs/freetdm/src/include/private/ftdm_sched.h
@@ -95,6 +95,9 @@ FT_DECLARE(ftdm_status_t) ftdm_sched_global_init(void);
/*! \brief Checks if the main scheduling thread is running */
FT_DECLARE(ftdm_bool_t) ftdm_free_sched_running(void);
+/*! \brief Stop the main scheduling thread (if running) */
+FT_DECLARE(ftdm_bool_t) ftdm_free_sched_stop(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/libs/freetdm/src/include/private/ftdm_types.h b/libs/freetdm/src/include/private/ftdm_types.h
index d0d19e5a55..bddefd9be6 100644
--- a/libs/freetdm/src/include/private/ftdm_types.h
+++ b/libs/freetdm/src/include/private/ftdm_types.h
@@ -191,6 +191,8 @@ typedef enum {
FTDM_CHANNEL_FEATURE_CALLERID = (1 << 4), /*!< Channel can detect caller id (read-only) */
FTDM_CHANNEL_FEATURE_PROGRESS = (1 << 5), /*!< Channel can detect inband progress (read-only) */
FTDM_CHANNEL_FEATURE_CALLWAITING = (1 << 6), /*!< Channel will allow call waiting (ie: FXS devices) (read/write) */
+ FTDM_CHANNEL_FEATURE_HWEC = (1<<7), /*!< Channel has a hardware echo canceller */
+ FTDM_CHANNEL_FEATURE_HWEC_DISABLED_ON_IDLE = (1<<8), /*!< hardware echo canceller is disabled when there are no calls on this channel */
} ftdm_channel_feature_t;
typedef enum {
@@ -382,7 +384,7 @@ struct ftdm_iterator {
unsigned int allocated:1;
union {
struct {
- int32_t index;
+ uint32_t index;
const ftdm_span_t *span;
} chaniter;
ftdm_hash_iterator_t *hashiter;
diff --git a/libs/iksemel/build/libgnutls.m4 b/libs/iksemel/build/libgnutls.m4
index 479d5a2dcf..cf3fe4641a 100644
--- a/libs/iksemel/build/libgnutls.m4
+++ b/libs/iksemel/build/libgnutls.m4
@@ -28,11 +28,11 @@ AC_ARG_WITH(libgnutls-prefix,
no_libgnutls=""
if test "$LIBGNUTLS_CONFIG" != "no"; then
LIBGNUTLS_CFLAGS=`$LIBGNUTLS_CONFIG $libgnutls_config_args --cflags`
- LIBGNUTLS_LIBS="`$LIBGNUTLS_CONFIG $libgnutls_config_args --libs` -lpthread"
+ LIBGNUTLS_LIBS="`$LIBGNUTLS_CONFIG $libgnutls_config_args --libs` -lpthread -lgcrypt"
libgnutls_config_version=`$LIBGNUTLS_CONFIG $libgnutls_config_args --version`
elif test "$PKG_CONFIG" != "no"; then
LIBGNUTLS_CFLAGS=`$PKG_CONFIG --cflags gnutls`
- LIBGNUTLS_LIBS="`$PKG_CONFIG --libs gnutls` -lpthread"
+ LIBGNUTLS_LIBS="`$PKG_CONFIG --libs gnutls` -lpthread -lgcrypt"
libgnutls_config_version=`$PKG_CONFIG --modversion gnutls`
else
no_libgnutls=yes
diff --git a/libs/ilbc/configure.ac b/libs/ilbc/configure.ac
index b3fda17c66..3dbfb24abd 100644
--- a/libs/ilbc/configure.ac
+++ b/libs/ilbc/configure.ac
@@ -175,14 +175,14 @@ AC_CHECK_HEADERS([sys/select.h])
AC_CHECK_HEADERS([sys/ioctl.h])
AC_CHECK_HEADERS([sys/fcntl.h])
AC_CHECK_HEADERS([audiofile.h])
-if test "${build}" == "${host}"
+if test "${build}" = "${host}"
then
AC_CHECK_HEADERS([X11/X.h])
fi
AC_LANG([C++])
-if test "${build}" == "${host}"
+if test "${build}" = "${host}"
then
case "${host}" in
x86_64-*)
@@ -193,7 +193,7 @@ fi
AC_LANG([C])
-if test "${build}" == "${host}"
+if test "${build}" = "${host}"
then
case "${host}" in
x86_64-*)
diff --git a/libs/libcodec2/.update b/libs/libcodec2/.update
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/libs/libcodec2/AUTHORS b/libs/libcodec2/AUTHORS
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/libs/libcodec2/COPYING b/libs/libcodec2/COPYING
new file mode 100644
index 0000000000..4362b49151
--- /dev/null
+++ b/libs/libcodec2/COPYING
@@ -0,0 +1,502 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ , 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/libs/libcodec2/ChangeLog b/libs/libcodec2/ChangeLog
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/libs/libcodec2/INSTALL b/libs/libcodec2/INSTALL
new file mode 100644
index 0000000000..23e5f25d0e
--- /dev/null
+++ b/libs/libcodec2/INSTALL
@@ -0,0 +1,236 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
+Software Foundation, Inc.
+
+This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+These are generic installation instructions.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+ It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring. (Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.)
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+ The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'. You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system. If you're
+ using `csh' on an old version of System V, you might need to type
+ `sh ./configure' instead to prevent `csh' from trying to execute
+ `configure' itself.
+
+ Running `configure' takes awhile. While running, it prints some
+ messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 5. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+Compilers and Options
+=====================
+
+Some systems require unusual options for compilation or linking that the
+`configure' script does not know about. Run `./configure --help' for
+details on some of the pertinent environment variables.
+
+ You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment. Here
+is an example:
+
+ ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
+
+ *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+ If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory. After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
+
+Installation Names
+==================
+
+By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc. You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files. Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+There may be some features `configure' cannot figure out automatically,
+but needs to determine by the type of machine the package will run on.
+Usually, assuming the package is built to be run on the _same_
+architectures, `configure' can figure that out, but if it prints a
+message saying it cannot guess the machine type, give it the
+`--build=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+ CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+ OS KERNEL-OS
+
+ See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+ If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+ If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+If you want to set default values for `configure' scripts to share, you
+can create a site shell script called `config.site' that gives default
+values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+Variables not defined in a site shell script can be set in the
+environment passed to `configure'. However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost. In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'. For example:
+
+ ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script). Here is a another example:
+
+ /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
+configuration-related scripts to be executed by `/bin/bash'.
+
+`configure' Invocation
+======================
+
+`configure' recognizes the following options to control how it operates.
+
+`--help'
+`-h'
+ Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`--cache-file=FILE'
+ Enable the cache: use and save the results of the tests in FILE,
+ traditionally `config.cache'. FILE defaults to `/dev/null' to
+ disable caching.
+
+`--config-cache'
+`-C'
+ Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options. Run
+`configure --help' for more details.
+
diff --git a/libs/libcodec2/Makefile.am b/libs/libcodec2/Makefile.am
new file mode 100644
index 0000000000..a1820f9162
--- /dev/null
+++ b/libs/libcodec2/Makefile.am
@@ -0,0 +1,98 @@
+AM_CFLAGS = -Isrc -Wall -lm
+AUTOMAKE_OPTS = gnu
+NAME = libcodec2
+AM_CPPFLAGS = $(AM_CFLAGS)
+
+EXTRA_DIST = pitch/hts1a.p \
+pitch/hts2a.p \
+octave/glottal.m \
+octave/lsp_pdf.m \
+octave/phase.m \
+octave/pl2.m \
+octave/plinterp.m \
+octave/plnlp.m \
+octave/plpitch.m \
+octave/postfilter.m \
+octave/load_raw.m \
+octave/phase2.m \
+octave/pitch_test.m \
+octave/plamp.m \
+octave/pl.m \
+octave/plphase.m \
+octave/png.m \
+octave/pulse.m \
+raw/b0067.raw \
+raw/forig_speex_8k.raw \
+raw/hts1.raw \
+raw/hts2.raw \
+raw/mmt1.raw \
+raw/morig_speex_8k.raw \
+raw/f2400.raw \
+raw/hts1a_g729a.raw \
+raw/hts2a_g729a.raw \
+raw/hts.raw \
+raw/mmt1_speex_8k.raw \
+raw/forig_g729a.raw \
+raw/hts1a_gsm13k.raw \
+raw/hts2a_gsm13k.raw \
+raw/m2400.raw \
+raw/morig_g729a.raw \
+raw/forig_gsm13k.raw \
+raw/hts1a.raw \
+raw/hts2a.raw \
+raw/mmt1_g729a.raw \
+raw/morig_gsm13k.raw \
+raw/forig.raw \
+raw/hts1a_speex_8k.raw \
+raw/hts2a_speex_8k.raw \
+raw/mmt1_gsm13k.raw \
+raw/morig.raw \
+script/menu.sh \
+script/playraw.sh \
+script/raw2wav.sh \
+script/wav2raw.sh \
+wav/f2400.wav \
+wav/hts1a_c2_v0.1.wav \
+wav/hts1a.wav \
+wav/hts2a_speex_8k.wav \
+wav/mmt1_speex_8k.wav \
+wav/morig.wav \
+wav/forig_speex_8k.wav \
+wav/hts1a_g729a.wav \
+wav/hts2a_c2_v0.1.wav \
+wav/hts2a.wav \
+wav/mmt1.wav \
+wav/forig.wav \
+wav/hts1a_speex_8k.wav \
+wav/hts2a_g729a.wav \
+wav/m2400.wav \
+wav/morig_speex_8k.wav \
+src/globals.c \
+doc/A_m.gif \
+doc/omega_0.gif \
+doc/phi_m.gif \
+doc/s_n.gif \
+doc/s_n.txt \
+unittest/lsp2.txt \
+unittest/lsp7.txt \
+unittest/lspd78.txt \
+unittest/lsp3.txt \
+unittest/lsp8.txt \
+unittest/lspd910.txt \
+unittest/lsp4.txt \
+unittest/lsp9.txt \
+unittest/lsp10.txt \
+unittest/lsp5.txt \
+unittest/lspd123.txt \
+unittest/lsp1.txt \
+unittest/lsp6.txt \
+unittest/lspd456.txt \
+src/codeall.sh \
+src/fq20.sh \
+src/listen1.sh \
+src/listen.sh \
+src/listensim.sh \
+src/sim.sh
+
+
+SUBDIRS = src unittest
diff --git a/libs/libcodec2/NEWS b/libs/libcodec2/NEWS
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/libs/libcodec2/README b/libs/libcodec2/README
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/libs/libcodec2/configure.gnu b/libs/libcodec2/configure.gnu
new file mode 100644
index 0000000000..c78238de46
--- /dev/null
+++ b/libs/libcodec2/configure.gnu
@@ -0,0 +1,4 @@
+#! /bin/sh
+srcpath=$(dirname $0 2>/dev/null ) || srcpath="."
+$srcpath/configure "$@" --disable-shared --with-pic
+
diff --git a/libs/libcodec2/configure.in b/libs/libcodec2/configure.in
new file mode 100644
index 0000000000..378ef5f2b9
--- /dev/null
+++ b/libs/libcodec2/configure.in
@@ -0,0 +1,26 @@
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ([2.59])
+AC_INIT(libcodec2, 1.0, david@rowetel.com)
+AM_INIT_AUTOMAKE(libcodec2,1.0)
+
+# Checks for programs.
+AC_PROG_CC
+AC_PROG_LIBTOOL
+
+# Checks for libraries.
+# FIXME: Replace `main' with a function in `-lm':
+AC_CHECK_LIB([m], [main])
+
+# Checks for header files.
+AC_CHECK_HEADERS([stdlib.h string.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+
+# Checks for library functions.
+AC_FUNC_MALLOC
+AC_CHECK_FUNCS([floor pow sqrt])
+
+AC_CONFIG_FILES([Makefile src/Makefile unittest/Makefile])
+AC_OUTPUT
diff --git a/libs/libcodec2/doc/A_m.gif b/libs/libcodec2/doc/A_m.gif
new file mode 100644
index 0000000000..47b89bd6c9
Binary files /dev/null and b/libs/libcodec2/doc/A_m.gif differ
diff --git a/libs/libcodec2/doc/omega_0.gif b/libs/libcodec2/doc/omega_0.gif
new file mode 100644
index 0000000000..02877e09d7
Binary files /dev/null and b/libs/libcodec2/doc/omega_0.gif differ
diff --git a/libs/libcodec2/doc/phi_m.gif b/libs/libcodec2/doc/phi_m.gif
new file mode 100644
index 0000000000..3f2fd57e52
Binary files /dev/null and b/libs/libcodec2/doc/phi_m.gif differ
diff --git a/libs/libcodec2/doc/s_n.gif b/libs/libcodec2/doc/s_n.gif
new file mode 100644
index 0000000000..c739ab4de1
Binary files /dev/null and b/libs/libcodec2/doc/s_n.gif differ
diff --git a/libs/libcodec2/doc/s_n.txt b/libs/libcodec2/doc/s_n.txt
new file mode 100644
index 0000000000..fec16b3a31
--- /dev/null
+++ b/libs/libcodec2/doc/s_n.txt
@@ -0,0 +1 @@
+s(n)=A_1cos(\omega_0+\phi_1)+A_2cos(2\omega_0+\phi_2)+...+A_Lcos(L\omega_0+\phi_L)
diff --git a/libs/libcodec2/octave/glottal.m b/libs/libcodec2/octave/glottal.m
new file mode 100644
index 0000000000..2b823c37e3
--- /dev/null
+++ b/libs/libcodec2/octave/glottal.m
@@ -0,0 +1,25 @@
+% glottal.m
+% David Rowe 12 Sep 2009
+% Matlab script to generate the phase spectra of a glottal pulse
+
+% lpc10 pulse from spandsp. When the file glottal.c was used as a part of the
+% excitation phase component in phase.c, phase_synth_zero_order(), no difference
+% in speech quality was apparent. So left out of code for now.
+
+sh=12
+kexc = [ 8, -16, 26, -48, 86, -162, 294, -502, 718, -728, 184 672, -610, -672, 184, 728, 718, 502, 294, 162, 86, 48, 26, 16, 8];
+kexc = shift(kexc,sh);
+kexc = [kexc(1:sh) zeros(1,512-25) kexc(sh+1:25)];
+figure(1)
+plot(kexc)
+figure(2)
+G = fft(kexc);
+plot((1:256)*(4000/256),unwrap(angle(G(1:256))))
+
+f=fopen("glottal.c","wt");
+fprintf(f,"float glottal[]={\n");
+for m=1:255
+ fprintf(f," %f,\n",angle(G(m)));
+endfor
+fprintf(f," %f};\n",angle(G(256)));
+fclose(f);
diff --git a/libs/libcodec2/octave/load_raw.m b/libs/libcodec2/octave/load_raw.m
new file mode 100644
index 0000000000..1f7868d42c
--- /dev/null
+++ b/libs/libcodec2/octave/load_raw.m
@@ -0,0 +1,8 @@
+% load_raw.m
+% David Rowe 7 Oct 2009
+
+function s = load_raw(fn)
+ fs=fopen(fn,"rb");
+ s = fread(fs,Inf,"short");
+ plot(s)
+endfunction
diff --git a/libs/libcodec2/octave/lsp_pdf.m b/libs/libcodec2/octave/lsp_pdf.m
new file mode 100644
index 0000000000..6617066e3d
--- /dev/null
+++ b/libs/libcodec2/octave/lsp_pdf.m
@@ -0,0 +1,50 @@
+% lsp_pdf.m
+% David Rowe 2 Oct 2009
+% Plots histograms (PDF estimates) of LSP training data
+
+function lsp_pdf(lsp)
+ [r,c] = size(lsp);
+
+ % LSPs
+
+ figure(3);
+ clf;
+ [x,y] = hist(lsp(:,1),100);
+ plot(y*4000/pi,x,";1;");
+ hold on;
+ for i=2:c
+ [x,y] = hist(lsp(:,i),100);
+ legend = sprintf(";%d;",i);
+ plot(y*4000/pi,x,legend);
+ endfor
+ hold off;
+ grid;
+
+ % LSP differences
+
+ figure(4);
+ clf;
+ subplot(211)
+ [x,y] = hist(lsp(:,1),100);
+ plot(y,x,";1;");
+ hold on;
+ for i=2:5
+ [x,y] = hist(lsp(:,i) - lsp(:,i-1),100);
+ legend = sprintf(";%d;",i);
+ plot(y,x,legend);
+ endfor
+ hold off;
+ grid;
+
+ subplot(212)
+ [x,y] = hist(lsp(:,6)-lsp(:,5),100);
+ plot(y,x,";6;");
+ hold on;
+ for i=7:c
+ [x,y] = hist(lsp(:,i) - lsp(:,i-1),100);
+ legend = sprintf(";%d;",i);
+ plot(y,x,legend);
+ endfor
+ hold off;
+ grid;
+endfunction
diff --git a/libs/libcodec2/octave/phase.m b/libs/libcodec2/octave/phase.m
new file mode 100644
index 0000000000..f973590345
--- /dev/null
+++ b/libs/libcodec2/octave/phase.m
@@ -0,0 +1,56 @@
+% phase.m
+% David Rowe August 2009
+% experiments with phase for sinusoidal codecs
+
+function phase(samname, F0, png)
+ Wo=2*pi*F0/8000;
+ P=2*pi/Wo;
+ L = floor(pi/Wo);
+ Nsam = 16000;
+ N = 80;
+ F = Nsam/N;
+ A = 10000/L;
+ phi = zeros(1,L);
+ s = zeros(1,Nsam);
+
+ for m=floor(L/2):L
+ phi_off(m) = -m*Wo*8;
+ end
+
+ for f=1:F
+ phi(1) = phi(1) + Wo*N;
+ phi(1) = mod(phi(1),2*pi);
+
+ for m=1:L
+ phi(m) = m*phi(1);
+ end
+
+ x = zeros(1,N);
+ for m=1:L
+ x = x + A*cos(m*Wo*(0:(N-1)) + phi(m));
+ endfor
+ s((f-1)*N+1:f*N) = x;
+ endfor
+
+ figure(1);
+ clf;
+ plot(s(1:250));
+
+ fs=fopen(samname,"wb");
+ fwrite(fs,s,"short");
+ fclose(fs);
+
+ if (nargin == 3)
+ % small image to fit blog
+
+ __gnuplot_set__ terminal png size 450,300
+ ss = sprintf("__gnuplot_set__ output \"%s.png\"", samname);
+ eval(ss)
+ replot;
+
+ % for some reason I need this to stop large plot getting wiped
+ __gnuplot_set__ output "/dev/null"
+ endif
+
+endfunction
+
diff --git a/libs/libcodec2/octave/phase2.m b/libs/libcodec2/octave/phase2.m
new file mode 100644
index 0000000000..ea58dcbe11
--- /dev/null
+++ b/libs/libcodec2/octave/phase2.m
@@ -0,0 +1,50 @@
+% phase2.m
+% David Rowe Sep 2009
+% experiments with phase for sinusoidal codecs, looking at phase
+% of excitation with real Am samples from hts1
+
+function phase2(samname, png)
+ N = 16000;
+
+ f=45;
+ model = load("../src/hts1a_model.txt");
+ phase = load("../src/hts1a_phase_phase.txt");
+ Wo = model(f,1);
+ P=2*pi/Wo;
+ L = model(f,2);
+ A = model(f,3:(L+2));
+ phi = phase(f,1:L);
+ phi = zeros(1,L);
+ for m=L/2:L
+ phi(m) = 2*pi*rand(1,1);
+ end
+
+ s = zeros(1,N);
+
+ for m=1:L
+ s_m = A(m)*cos(m*Wo*(0:(N-1)) + phi(m));
+ s = s + s_m;
+ endfor
+
+ figure(1);
+ clf;
+ plot(s(1:250));
+
+ fs=fopen(samname,"wb");
+ fwrite(fs,s,"short");
+ fclose(fs);
+
+ if (nargin == 2)
+ % small image to fit blog
+
+ __gnuplot_set__ terminal png size 450,300
+ ss = sprintf("__gnuplot_set__ output \"%s.png\"", samname);
+ eval(ss)
+ replot;
+
+ % for some reason I need this to stop large plot getting wiped
+ __gnuplot_set__ output "/dev/null"
+ endif
+
+endfunction
+
diff --git a/libs/libcodec2/octave/pitch_test.m b/libs/libcodec2/octave/pitch_test.m
new file mode 100644
index 0000000000..3fe0d1ad66
--- /dev/null
+++ b/libs/libcodec2/octave/pitch_test.m
@@ -0,0 +1,39 @@
+% pitch_test.m
+% David Rowe Sep 2009
+% Constructs a sequence to test the pitch estimator
+
+function pitch_test(samname)
+ M=320;
+ F=200;
+
+ fs=fopen(samname,"wb");
+
+ f0 = 100;
+ for f=1:200
+ Wo=2*pi*f0/8000;
+ P=2*pi/Wo;
+ L = floor(pi/Wo);
+ A = 10000/L;
+ phi = zeros(1,L);
+ s = zeros(1,M);
+
+ for m=1:L
+ s = s + A*cos(m*Wo*(0:(M-1)) + phi(m));
+ endfor
+
+ figure(1);
+ clf;
+ plot(s);
+
+ fwrite(fs,s,"short");
+
+ f0 = f0 + 5;
+ if (f0 > 400)
+ f0 = 100;
+ endif
+ endfor
+
+ fclose(fs);
+
+endfunction
+
diff --git a/libs/libcodec2/octave/pl.m b/libs/libcodec2/octave/pl.m
new file mode 100644
index 0000000000..49968961d4
--- /dev/null
+++ b/libs/libcodec2/octave/pl.m
@@ -0,0 +1,42 @@
+% Copyright David Rowe 2009
+% This program is distributed under the terms of the GNU General Public License
+% Version 2
+
+function pl(samname1, start_sam, end_sam, pngname)
+
+ fs=fopen(samname1,"rb");
+ s=fread(fs,Inf,"short");
+
+ st = 1;
+ en = length(s);
+ if (nargin >= 2)
+ st = start_sam;
+ endif
+ if (nargin >= 3)
+ en = end_sam;
+ endif
+
+ figure(1);
+ clf;
+ plot(s(st:en));
+ axis([1 en-st min(s) max(s)]);
+
+ if (nargin == 4)
+
+ % small image
+
+ __gnuplot_set__ terminal png size 420,300
+ ss = sprintf("__gnuplot_set__ output \"%s.png\"", pngname);
+ eval(ss)
+ replot;
+
+ % larger image
+
+ __gnuplot_set__ terminal png size 800,600
+ ss = sprintf("__gnuplot_set__ output \"%s_large.png\"", pngname);
+ eval(ss)
+ replot;
+
+ endif
+
+endfunction
diff --git a/libs/libcodec2/octave/pl2.m b/libs/libcodec2/octave/pl2.m
new file mode 100644
index 0000000000..6e6d37aab8
--- /dev/null
+++ b/libs/libcodec2/octave/pl2.m
@@ -0,0 +1,50 @@
+% Copyright David Rowe 2009
+% This program is distributed under the terms of the GNU General Public License
+% Version 2
+
+function pl2(samname1, samname2, start_sam, end_sam, pngname)
+
+ fs1=fopen(samname1,"rb");
+ s1=fread(fs1,Inf,"short");
+ fs2=fopen(samname2,"rb");
+ s2=fread(fs2,Inf,"short");
+
+ st = 1;
+ en = length(s1);
+ if (nargin >= 3)
+ st = start_sam;
+ endif
+ if (nargin >= 4)
+ en = end_sam;
+ endif
+
+ figure(1);
+ clf;
+ subplot(211);
+ l1 = strcat("r;",samname1,";");
+ plot(s1(st:en), l1);
+ axis([1 en-st min(s1(st:en)) max(s1(st:en))]);
+ subplot(212);
+ l2 = strcat("r;",samname2,";");
+ plot(s2(st:en),l2);
+ axis([1 en-st min(s1(st:en)) max(s1(st:en))]);
+
+ if (nargin == 5)
+
+ % small image
+
+ __gnuplot_set__ terminal png size 420,300
+ s = sprintf("__gnuplot_set__ output \"%s.png\"", pngname);
+ eval(s)
+ replot;
+
+ % larger image
+
+ __gnuplot_set__ terminal png size 800,600
+ s = sprintf("__gnuplot_set__ output \"%s_large.png\"", pngname);
+ eval(s)
+ replot;
+
+ endif
+
+endfunction
diff --git a/libs/libcodec2/octave/plamp.m b/libs/libcodec2/octave/plamp.m
new file mode 100644
index 0000000000..892830f032
--- /dev/null
+++ b/libs/libcodec2/octave/plamp.m
@@ -0,0 +1,166 @@
+% Copyright David Rowe 2009
+% This program is distributed under the terms of the GNU General Public License
+% Version 2
+%
+% Plot ampltiude modelling information from dump files.
+
+function plamp(samname, f)
+
+ sn_name = strcat(samname,"_sn.txt");
+ Sn = load(sn_name);
+
+ sw_name = strcat(samname,"_sw.txt");
+ Sw = load(sw_name);
+
+ sw__name = strcat(samname,"_sw_.txt");
+ if (file_in_path(".",sw__name))
+ Sw_ = load(sw__name);
+ endif
+
+ model_name = strcat(samname,"_model.txt");
+ model = load(model_name);
+
+ modelq_name = strcat(samname,"_qmodel.txt");
+ if (file_in_path(".",modelq_name))
+ modelq = load(modelq_name);
+ endif
+
+ pw_name = strcat(samname,"_pw.txt");
+ if (file_in_path(".",pw_name))
+ Pw = load(pw_name);
+ endif
+
+ lsp_name = strcat(samname,"_lsp.txt");
+ if (file_in_path(".",lsp_name))
+ lsp = load(lsp_name);
+ endif
+
+ phase_name = strcat(samname,"_phase.txt");
+ if (file_in_path(".",phase_name))
+ phase = load(phase_name);
+ endif
+
+ phase_name_ = strcat(samname,"_phase_.txt");
+ if (file_in_path(".",phase_name_))
+ phase_ = load(phase_name_);
+ endif
+
+ snr_name = strcat(samname,"_snr.txt");
+ if (file_in_path(".",snr_name))
+ snr = load(snr_name);
+ endif
+
+ k = ' ';
+ do
+ figure(1);
+ clf;
+% s = [ Sn(2*(f-2)-1,:) Sn(2*(f-2),:) ];
+ s = [ Sn(2*f-1,:) Sn(2*f,:) ];
+ plot(s);
+ axis([1 length(s) -20000 20000]);
+
+ figure(2);
+ Wo = model(f,1);
+ L = model(f,2);
+ Am = model(f,3:(L+2));
+ plot((1:L)*Wo*4000/pi, 20*log10(Am),";Am;r");
+ axis([1 4000 -10 80]);
+ hold on;
+% plot((0:255)*4000/256, Sw(f-2,:),";Sw;");
+ plot((0:255)*4000/256, Sw(f,:),";Sw;");
+
+ if (file_in_path(".",modelq_name))
+ Amq = modelq(f,3:(L+2));
+ plot((1:L)*Wo*4000/pi, 20*log10(Amq),";Amq;g" );
+ if (file_in_path(".",pw_name))
+ plot((0:255)*4000/256, 10*log10(Pw(f,:)),";Pw;c");
+ endif
+ signal = Am * Am';
+ noise = (Am-Amq) * (Am-Amq)';
+ snr1 = 10*log10(signal/noise);
+ Am_err_label = sprintf(";Am error SNR %4.2f dB;m",snr1);
+ plot((1:L)*Wo*4000/pi, 20*log10(Amq) - 20*log10(Am), Am_err_label);
+ endif
+
+ if (file_in_path(".",snr_name))
+ snr_label = sprintf(";phase SNR %4.2f dB;",snr(f));
+ plot(1,1,snr_label);
+ endif
+
+ % phase model - determine SNR and error spectrum for phase model 1
+
+ if (file_in_path(".",phase_name_))
+ orig = Am.*exp(j*phase(f,1:L));
+ synth = Am.*exp(j*phase_(f,1:L));
+ signal = orig * orig';
+ noise = (orig-synth) * (orig-synth)';
+ snr_phase = 10*log10(signal/noise);
+
+ phase_err_label = sprintf(";phase_err SNR %4.2f dB;",snr_phase);
+ plot((1:L)*Wo*4000/pi, 20*log10(orig-synth), phase_err_label);
+ endif
+
+ if (file_in_path(".",lsp_name))
+ for l=1:10
+ plot([lsp(f,l)*4000/pi lsp(f,l)*4000/pi], [60 80], 'r');
+ endfor
+ endif
+
+ hold off;
+
+ if (file_in_path(".",phase_name))
+ figure(3);
+ plot((1:L)*Wo*4000/pi, phase(f,1:L), ";phase;");
+ axis;
+ if (file_in_path(".",phase_name_))
+ hold on;
+ plot((1:L)*Wo*4000/pi, phase_(f,1:L), ";phase_;");
+ hold off;
+ endif
+ figure(2);
+ endif
+
+ % autocorrelation function to research voicing est
+
+ %M = length(s);
+ %sw = s .* hanning(M)';
+ %for k=0:159
+ % R(k+1) = sw(1:320-k) * sw(1+k:320)';
+ %endfor
+ %figure(4);
+ %R_label = sprintf(";R(k) %3.2f;",max(R(20:159))/R(1));
+ %plot(R/R(1),R_label);
+ %grid
+
+ % interactive menu
+
+ printf("\rframe: %d menu: n-next b-back p-png q-quit ", f);
+ fflush(stdout);
+ k = kbhit();
+ if (k == 'n')
+ f = f + 1;
+ endif
+ if (k == 'b')
+ f = f - 1;
+ endif
+
+ % optional print to PNG
+
+ if (k == 'p')
+ figure(1);
+ pngname = sprintf("%s_%d_sn.png",samname,f);
+ print(pngname, '-dpng', "-S500,500")
+ pngname = sprintf("%s_%d_sn_large.png",samname,f);
+ print(pngname, '-dpng', "-S800,600")
+
+ figure(2);
+ pngname = sprintf("%s_%d_sw.png",samname,f);
+ print(pngname, '-dpng', "-S500,500")
+ pngname = sprintf("%s_%d_sw_large.png",samname,f);
+ print(pngname, '-dpng', "-S800,600")
+ endif
+
+ until (k == 'q')
+ printf("\n");
+
+endfunction
diff --git a/libs/libcodec2/octave/plinterp.m b/libs/libcodec2/octave/plinterp.m
new file mode 100644
index 0000000000..794a0853b2
--- /dev/null
+++ b/libs/libcodec2/octave/plinterp.m
@@ -0,0 +1,11 @@
+load ../unittest/tinterp_prev.txt;
+load ../unittest/tinterp_interp.txt;
+load ../unittest/tinterp_next.txt;
+
+clf;
+plot(tinterp_prev(:,1), 20.0*log10(tinterp_prev(:,2)),";prev;")
+hold on;
+plot(tinterp_interp(:,1), 20.0*log10(tinterp_interp(:,2)),'g+-;interp;')
+plot(tinterp_next(:,1), 20.0*log10(tinterp_next(:,2)),'ro-;next;')
+hold off;
+axis([0 pi 0 80])
diff --git a/libs/libcodec2/octave/plnlp.m b/libs/libcodec2/octave/plnlp.m
new file mode 100644
index 0000000000..01b493113b
--- /dev/null
+++ b/libs/libcodec2/octave/plnlp.m
@@ -0,0 +1,134 @@
+% Copyright David Rowe 2009
+% This program is distributed under the terms of the GNU General Public License
+% Version 2
+%
+% Plot NLP states from dump files.
+
+function plnlp(samname, f)
+
+ sn_name = strcat(samname,"_sn.txt");
+ Sn = load(sn_name);
+
+ sw_name = strcat(samname,"_sw.txt");
+ Sw = load(sw_name);
+
+ fw_name = strcat(samname,"_fw.txt");
+ if (file_in_path(".",fw_name))
+ fw = load(fw_name);
+ endif
+
+ e_name = strcat(samname,"_e.txt");
+ if (file_in_path(".",e_name))
+ e = load(e_name);
+ endif
+
+ p_name = strcat(samname,".p");
+ if (file_in_path(".",p_name))
+ p = load(p_name);
+ endif
+
+ sq_name = strcat(samname,"_sq.txt");
+ if (file_in_path(".",sq_name))
+ sq = load(sq_name);
+ endif
+
+ dec_name = strcat(samname,"_dec.txt");
+ if (file_in_path(".",dec_name))
+ dec = load(dec_name);
+ endif
+
+ do
+ figure(1);
+ clf;
+ s = [ Sn(2*f-1,:) Sn(2*f,:) ];
+ plot(s, ";Sn;");
+ grid
+ axis([1 length(s) -20000 20000]);
+
+ figure(2);
+ plot((0:255)*4000/256, Sw(f,:),";Sw;");
+ grid
+ axis([1 4000 -10 80]);
+ hold on;
+
+ f0 = 8000/p(f);
+ Wo = 2*pi/p(f);
+ L = floor(pi/Wo);
+ f0_label = sprintf("b;P=%3.1f F0=%3.0f;",p(f),f0);
+ for m=1:L-1
+ plot([ m*Wo*4000/pi m*Wo*4000/pi], [10 60], 'b');
+ endfor
+ plot([ L*Wo*4000/pi L*Wo*4000/pi], [10 60], f0_label);
+
+ hold off;
+
+ if (file_in_path(".",fw_name))
+ figure(3);
+ if (file_in_path(".",e_name))
+ subplot(211);
+ endif
+ plot((0:255)*800/256, fw(f,:)/max(fw(f,:)), ";Fw;");
+ axis([1 400 0 1]);
+ if (file_in_path(".",e_name))
+ subplot(212);
+ e_concat = [ e(2*f-1,:) e(2*f,:) ];
+ plot(e_concat(1:400)/max(e_concat(1:400)), "+;MBE E(f);");
+ axis([1 400 0 1]);
+ endif
+ endif
+
+ if (file_in_path(".",sq_name))
+ figure(4);
+ sq_concat = [ sq(2*f-1,:) sq(2*f,:) ];
+ axis
+ plot(sq_concat, ";sq;");
+ endif
+
+ if (file_in_path(".",dec_name))
+ figure(5);
+ plot(dec(f,:), ";dec;");
+ endif
+
+ figure(2);
+
+ % interactive menu
+
+ printf("\rframe: %d menu: n-next b-back p-png q-quit ", f);
+ fflush(stdout);
+ k = kbhit();
+ if (k == 'n')
+ f = f + 1;
+ endif
+ if (k == 'b')
+ f = f - 1;
+ endif
+
+ % optional print to PNG
+
+ if (k == 'p')
+
+ pngname = sprintf("%s_%d",samname,f);
+
+ % small image
+
+ __gnuplot_set__ terminal png size 420,300
+ ss = sprintf("__gnuplot_set__ output \"%s.png\"", pngname);
+ eval(ss)
+ replot;
+
+ % larger image
+
+ __gnuplot_set__ terminal png size 800,600
+ ss = sprintf("__gnuplot_set__ output \"%s_large.png\"", pngname);
+ eval(ss)
+ replot;
+
+ % for some reason I need this to stop large plot getting wiped
+ __gnuplot_set__ output "/dev/null"
+
+ endif
+
+ until (k == 'q')
+ printf("\n");
+
+endfunction
diff --git a/libs/libcodec2/octave/plphase.m b/libs/libcodec2/octave/plphase.m
new file mode 100644
index 0000000000..9e61185676
--- /dev/null
+++ b/libs/libcodec2/octave/plphase.m
@@ -0,0 +1,198 @@
+% Copyright David Rowe 2009
+% This program is distributed under the terms of the GNU General Public License
+% Version 2
+%
+% Plot phase modelling information from dump files.
+
+function plphase(samname, f)
+
+ sn_name = strcat(samname,"_sn.txt");
+ Sn = load(sn_name);
+
+ sw_name = strcat(samname,"_sw.txt");
+ Sw = load(sw_name);
+
+ model_name = strcat(samname,"_model.txt");
+ model = load(model_name);
+
+ sw__name = strcat(samname,"_sw_.txt");
+ if (file_in_path(".",sw__name))
+ Sw_ = load(sw__name);
+ endif
+
+ pw_name = strcat(samname,"_pw.txt");
+ if (file_in_path(".",pw_name))
+ Pw = load(pw_name);
+ endif
+
+ ak_name = strcat(samname,"_ak.txt");
+ if (file_in_path(".",ak_name))
+ ak = load(ak_name);
+ endif
+
+ phase_name = strcat(samname,"_phase.txt");
+ if (file_in_path(".",phase_name))
+ phase = load(phase_name);
+ endif
+
+ phase_name_ = strcat(samname,"_phase_.txt");
+ if (file_in_path(".",phase_name_))
+ phase_ = load(phase_name_);
+ endif
+
+ snr_name = strcat(samname,"_snr.txt");
+ if (file_in_path(".",snr_name))
+ snr = load(snr_name);
+ endif
+
+ sn_name_ = strcat(samname,".raw");
+ if (file_in_path(".",sn_name_))
+ fs_ = fopen(sn_name_,"rb");
+ sn_ = fread(fs_,Inf,"short");
+ endif
+
+ k = ' ';
+ do
+ figure(1);
+ clf;
+ s = [ Sn(2*f-1,:) Sn(2*f,:) ];
+ plot(s);
+ grid;
+ axis([1 length(s) -20000 20000]);
+ if (k == 'p')
+ pngname = sprintf("%s_%d_sn",samname,f);
+ png(pngname);
+ endif
+
+ figure(2);
+ Wo = model(f,1);
+ L = model(f,2);
+ Am = model(f,3:(L+2));
+ plot((1:L)*Wo*4000/pi, 20*log10(Am),"r;Am;");
+ axis([1 4000 -10 80]);
+ hold on;
+ plot((0:255)*4000/256, Sw(f,:),";Sw;");
+ grid;
+
+ if (file_in_path(".",sw__name))
+ plot((0:255)*4000/256, Sw_(f,:),"g;Sw_;");
+ endif
+
+ if (file_in_path(".",pw_name))
+ plot((0:255)*4000/256, 10*log10(Pw(f,:)),";Pw;");
+ endif
+
+ if (file_in_path(".",snr_name))
+ snr_label = sprintf(";phase SNR %4.2f dB;",snr(f));
+ plot(1,1,snr_label);
+ endif
+
+ % phase model - determine SNR and error spectrum for phase model 1
+
+ if (file_in_path(".",phase_name_))
+ orig = Am.*exp(j*phase(f,1:L));
+ synth = Am.*exp(j*phase_(f,1:L));
+ signal = orig * orig';
+ noise = (orig-synth) * (orig-synth)';
+ snr_phase = 10*log10(signal/noise);
+
+ phase_err_label = sprintf("g;phase_err SNR %4.2f dB;",snr_phase);
+ plot((1:L)*Wo*4000/pi, 20*log10(orig-synth), phase_err_label);
+ endif
+
+ hold off;
+ if (k == 'p')
+ pngname = sprintf("%s_%d_sw",samname,f);
+ png(pngname);
+ endif
+
+ if (file_in_path(".",phase_name))
+ figure(3);
+ plot((1:L)*Wo*4000/pi, phase(f,1:L)*180/pi, "-o;phase;");
+ axis;
+ if (file_in_path(".", phase_name_))
+ hold on;
+ plot((1:L)*Wo*4000/pi, phase_(f,1:L)*180/pi, "g;phase_;");
+ grid
+ hold off;
+ endif
+ if (k == 'p')
+ pngname = sprintf("%s_%d_phase",samname,f);
+ png(pngname);
+ endif
+ endif
+
+ % synthesised speech
+
+ if (file_in_path(".",sn_name_))
+ figure(4);
+ s_ = sn_((f-3)*80+1:(f+1)*80);
+ plot(s_);
+ axis([1 length(s_) -20000 20000]);
+ if (k == 'p')
+ pngname = sprintf("%s_%d_sn_",samname,f)
+ png(pngname);
+ endif
+ endif
+
+ if (file_in_path(".",ak_name))
+ figure(5);
+ axis;
+ akw = ak(f,:);
+ weight = 1.0 .^ (0:length(akw)-1);
+ akw = akw .* weight;
+ H = 1./fft(akw,8000);
+ subplot(211);
+ plot(20*log10(abs(H(1:4000))),";LPC mag spec;");
+ grid;
+ subplot(212);
+ plot(angle(H(1:4000))*180/pi,";LPC phase spec;");
+ grid;
+ if (k == 'p')
+ % stops multimode errors from gnuplot, I know not why...
+ figure(2);
+ figure(5);
+
+ pngname = sprintf("%s_%d_lpc",samname,f);
+ png(pngname);
+ endif
+ endif
+
+
+ % autocorrelation function to research voicing est
+
+ %M = length(s);
+ %sw = s .* hanning(M)';
+ %for k=0:159
+ % R(k+1) = sw(1:320-k) * sw(1+k:320)';
+ %endfor
+ %figure(4);
+ %R_label = sprintf(";R(k) %3.2f;",max(R(20:159))/R(1));
+ %plot(R/R(1),R_label);
+ %grid
+
+ figure(2);
+
+ % interactive menu
+
+ printf("\rframe: %d menu: n-next b-back p-png q-quit ", f);
+ fflush(stdout);
+ k = kbhit();
+ if (k == 'n')
+ f = f + 1;
+ endif
+ if (k == 'b')
+ f = f - 1;
+ endif
+
+ % optional print to PNG
+
+ if (k == 'p')
+ pngname = sprintf("%s_%d",samname,f);
+ png(pngname);
+ endif
+
+ until (k == 'q')
+ printf("\n");
+
+endfunction
diff --git a/libs/libcodec2/octave/plpitch.m b/libs/libcodec2/octave/plpitch.m
new file mode 100644
index 0000000000..69ad533890
--- /dev/null
+++ b/libs/libcodec2/octave/plpitch.m
@@ -0,0 +1,36 @@
+% Copyright David Rowe 2009
+% This program is distributed under the terms of the GNU General Public License
+% Version 2
+%
+% plpitch.m
+% Plots two pitch tracks on top of each other, used for comparing pitch
+% estimators
+
+function plpitch(pitch1_name, pitch2_name, start_fr, end_fr)
+
+ pitch1 = load(pitch1_name);
+ pitch2 = load(pitch2_name);
+
+ st = 1;
+ en = length(pitch1);
+ if (nargin >= 3)
+ st = start_fr;
+ endif
+ if (nargin >= 4)
+ en = end_fr;
+ endif
+
+ figure(1);
+ clf;
+ l1 = strcat("r;",pitch1_name,";")
+ l1
+ st
+ en
+ plot(pitch1(st:en), l1);
+ axis([1 en-st 20 160]);
+ l2 = strcat("g;",pitch2_name,";");
+ hold on;
+ plot(pitch2(st:en),l2);
+ hold off;
+endfunction
+
diff --git a/libs/libcodec2/octave/png.m b/libs/libcodec2/octave/png.m
new file mode 100644
index 0000000000..09a79968c6
--- /dev/null
+++ b/libs/libcodec2/octave/png.m
@@ -0,0 +1,25 @@
+% Copyright David Rowe 2009
+% This program is distributed under the terms of the GNU General Public License
+% Version 2
+%
+% Replot current plot as a png, generates small and large versions
+
+function png(pngname)
+ % small image
+
+ __gnuplot_set__ terminal png size 420,300
+ ss = sprintf("__gnuplot_set__ output \"%s.png\"", pngname);
+ eval(ss)
+ replot;
+
+ % larger image
+
+ __gnuplot_set__ terminal png size 800,600
+ ss = sprintf("__gnuplot_set__ output \"%s_large.png\"", pngname);
+ eval(ss)
+ replot;
+
+ % for some reason I need this to stop large plot getting wiped
+ __gnuplot_set__ output "/dev/null"
+
+endfunction
diff --git a/libs/libcodec2/octave/postfilter.m b/libs/libcodec2/octave/postfilter.m
new file mode 100644
index 0000000000..84f7dfc773
--- /dev/null
+++ b/libs/libcodec2/octave/postfilter.m
@@ -0,0 +1,24 @@
+% Copyright David Rowe 2009
+% This program is distributed under the terms of the GNU General Public License
+% Version 2
+%
+% Plot postfilter doing its thing
+
+function postfilter(samname)
+ p = load(samname);
+ figure(1);
+ plot(p(:,1),";energy;");
+ hold on;
+ plot(p(:,2),";bg_est;");
+ hold off;
+ grid;
+ pngname=sprintf("%s_postfilter_1", samname);
+ png(pngname);
+
+ figure(2);
+ plot(p(:,3),";% unvoiced;");
+ grid;
+ pngname=sprintf("%s_postfilter_2", samname);
+ png(pngname);
+endfunction
+
diff --git a/libs/libcodec2/octave/pulse.m b/libs/libcodec2/octave/pulse.m
new file mode 100644
index 0000000000..223389e777
--- /dev/null
+++ b/libs/libcodec2/octave/pulse.m
@@ -0,0 +1,37 @@
+% pulse.m
+% David Rowe August 2009
+%
+% Experiments with human pulse perception for sinusoidal codecs
+
+function pulse(samname)
+
+ A = 1000;
+ K = 16000;
+ N = 80;
+ frames = K/N;
+ s = zeros(1,K);
+
+ for f=1:frames
+ % lets try placing np random pulses in every frame
+
+ P = 20 + (160-20)*rand(1,1);
+ Wo = 2*pi/P;
+ L = floor(pi/Wo);
+ sf = zeros(1,N);
+ for m=1:L/2:L
+ pos = floor(rand(1,1)*N)+1;
+ %pos = 50;
+ for l=m:m+L/2-1
+ sf = sf + A*cos(l*Wo*((f-1)*N+1:f*N) - pos*l*Wo);
+ endfor
+ endfor
+ s((f-1)*N+1:f*N) = sf;
+ endfor
+
+ plot(s(1:250));
+
+ fs=fopen(samname,"wb");
+ fwrite(fs,s,"short");
+ fclose(fs);
+endfunction
+
diff --git a/libs/libcodec2/pitch/hts1a.p b/libs/libcodec2/pitch/hts1a.p
new file mode 100644
index 0000000000..c11b8e90fc
--- /dev/null
+++ b/libs/libcodec2/pitch/hts1a.p
@@ -0,0 +1,298 @@
+111.627907
+97.959183
+97.959183
+97.959183
+87.272736
+78.048775
+112.280701
+120.000008
+61.538464
+68.817207
+84.210526
+90.140846
+90.140846
+90.140846
+101.587303
+80.000000
+72.727272
+95.522392
+90.140846
+90.140846
+101.587303
+90.140846
+85.333336
+86.486488
+91.428574
+91.428574
+91.428574
+91.428574
+91.428574
+90.140846
+86.486488
+86.486488
+85.333336
+85.333336
+85.333336
+81.012657
+74.418610
+71.111115
+71.111115
+71.111115
+71.111115
+68.085106
+68.085106
+67.368423
+67.368423
+70.329674
+70.329674
+70.329674
+71.111115
+74.418610
+74.418610
+75.294121
+79.012352
+85.333336
+96.969704
+111.627907
+111.627907
+120.000008
+111.627907
+104.347832
+104.347832
+97.959183
+104.347832
+104.347832
+104.347832
+104.347832
+104.347832
+104.347832
+104.347832
+104.347832
+97.959183
+97.959183
+112.280701
+112.280701
+96.969704
+96.969704
+96.969704
+110.344841
+104.347832
+97.959183
+97.959183
+104.347832
+97.959183
+104.347832
+120.000008
+104.347832
+120.000008
+120.000008
+97.959183
+83.116882
+75.294121
+71.910118
+71.910110
+71.910110
+71.910110
+75.294121
+76.190483
+80.000008
+80.000008
+84.210526
+85.333336
+90.140846
+101.587303
+108.474571
+104.347832
+120.000008
+120.000008
+104.347832
+104.347832
+71.111115
+88.888893
+75.294121
+111.627907
+120.000008
+120.000008
+97.959183
+111.627907
+111.627907
+111.627907
+97.959183
+92.307693
+92.307693
+92.307693
+92.307693
+120.000008
+111.627907
+111.627907
+86.486488
+85.333336
+85.333336
+90.140846
+95.522392
+101.587311
+101.587311
+104.918037
+104.347832
+104.347832
+111.627907
+120.000008
+97.959183
+104.347832
+111.627907
+88.888893
+80.000000
+81.012657
+85.333336
+85.333336
+86.486488
+91.428574
+90.140846
+91.428574
+96.969704
+96.969704
+95.522392
+95.522392
+95.522392
+96.969704
+96.969704
+98.461533
+104.918022
+97.959183
+97.959183
+97.959183
+104.347832
+120.000008
+120.000008
+92.307693
+92.307693
+77.108429
+79.012344
+75.294121
+75.294121
+76.190483
+76.190483
+80.000008
+81.012657
+85.333336
+85.333336
+85.333336
+85.333336
+85.333336
+90.140846
+90.140846
+91.428574
+96.969704
+98.461533
+120.000008
+120.000008
+104.347832
+97.959183
+97.959183
+104.918037
+120.000008
+120.000008
+120.000008
+104.347832
+92.307693
+72.727272
+72.727272
+76.190483
+84.210533
+88.888901
+120.000008
+104.347832
+120.000008
+120.000008
+111.627907
+92.307693
+97.959183
+97.959183
+111.627907
+120.000008
+120.000008
+97.959183
+97.959183
+104.347832
+104.347832
+104.347832
+111.627907
+120.000008
+97.959183
+104.347832
+97.959183
+97.959183
+84.210526
+94.117653
+96.969704
+110.344841
+120.000008
+97.959183
+97.959183
+104.347832
+97.959183
+104.347832
+97.959183
+97.959183
+111.627907
+120.000008
+92.307693
+92.307693
+98.461533
+98.461533
+104.918022
+111.627907
+111.627907
+92.307693
+97.959183
+92.307693
+92.307693
+92.307693
+92.307693
+92.307693
+57.657658
+90.140846
+90.140846
+95.522392
+101.587311
+101.587311
+108.474586
+111.627907
+97.959183
+111.627907
+120.000008
+92.307693
+74.418610
+74.418610
+74.418610
+74.418610
+76.190483
+72.727280
+76.190483
+76.190483
+69.565224
+66.666672
+54.700855
+56.637169
+56.637169
+71.910110
+90.140846
+90.140846
+72.727272
+72.727272
+72.727272
+72.727272
+55.172413
+57.142857
+55.172413
+90.140846
+95.522392
+101.587311
+101.587311
+71.910110
+74.418610
+46.376812
+40.000000
+95.522392
+0
+0
diff --git a/libs/libcodec2/pitch/hts2a.p b/libs/libcodec2/pitch/hts2a.p
new file mode 100644
index 0000000000..20e2680487
--- /dev/null
+++ b/libs/libcodec2/pitch/hts2a.p
@@ -0,0 +1,300 @@
+ 0.0000000e+000
+ 9.2753623e+001
+ 5.4237288e+001
+ 8.5906040e+001
+ 7.0329670e+001
+ 5.5652174e+001
+ 5.4237288e+001
+ 5.4935622e+001
+ 5.4700855e+001
+ 7.5739645e+001
+ 7.3563218e+001
+ 1.2307692e+002
+ 1.1428571e+002
+ 7.3563218e+001
+ 7.7108434e+001
+ 1.8550725e+002
+ 1.2673267e+002
+ 1.0847458e+002
+ 7.8527607e+001
+ 8.8888889e+001
+ 8.3116883e+001
+ 8.1012658e+001
+ 1.0756303e+002
+ 1.3061224e+002
+ 4.8301887e+001
+ 4.7940075e+001
+ 4.8120301e+001
+ 4.9230769e+001
+ 4.9420849e+001
+ 4.6886447e+001
+ 4.2953020e+001
+ 3.9263804e+001
+ 3.7869822e+001
+ 3.5457064e+001
+ 3.4224599e+001
+ 3.3333333e+001
+ 3.2820513e+001
+ 3.2000000e+001
+ 3.1295844e+001
+ 2.9906542e+001
+ 2.9493088e+001
+ 2.9090909e+001
+ 2.8699552e+001
+ 2.8131868e+001
+ 2.7826087e+001
+ 2.7826087e+001
+ 2.7826087e+001
+ 2.8193833e+001
+ 2.7467811e+001
+ 2.6890756e+001
+ 5.4468085e+001
+ 5.4237288e+001
+ 6.4974619e+001
+ 1.0756303e+002
+ 8.8888889e+001
+ 1.0406504e+002
+ 4.4599303e+001
+ 5.4468085e+001
+ 3.6260623e+001
+ 3.6260623e+001
+ 8.1012658e+001
+ 7.0329670e+001
+ 1.2929293e+002
+ 9.9224806e+001
+ 4.3097643e+001
+ 4.4137931e+001
+ 4.5714286e+001
+ 4.7407407e+001
+ 4.8301887e+001
+ 4.9230769e+001
+ 4.9420849e+001
+ 5.0996016e+001
+ 5.1405622e+001
+ 5.1405622e+001
+ 5.2244898e+001
+ 5.2459016e+001
+ 5.2459016e+001
+ 5.2244898e+001
+ 5.3333333e+001
+ 5.2459016e+001
+ 5.2244898e+001
+ 5.1405622e+001
+ 5.1405622e+001
+ 5.1200000e+001
+ 5.0996016e+001
+ 5.0196078e+001
+ 4.9230769e+001
+ 4.9230769e+001
+ 4.9230769e+001
+ 4.9420849e+001
+ 4.9230769e+001
+ 4.9042146e+001
+ 9.8461538e+001
+ 1.0158730e+002
+ 5.1821862e+001
+ 9.0140845e+001
+ 1.0491803e+002
+ 1.4382022e+002
+ 5.2459016e+001
+ 5.2459016e+001
+ 1.2929293e+002
+ 1.6410256e+002
+ 8.0000000e+001
+ 7.3563218e+001
+ 1.0158730e+002
+ 9.9224806e+001
+ 4.9042146e+001
+ 4.9042146e+001
+ 4.9042146e+001
+ 5.9259259e+001
+ 1.4382022e+002
+ 7.2316384e+001
+ 1.0847458e+002
+ 1.1228070e+002
+ 1.6202532e+002
+ 8.1528662e+001
+ 7.2727273e+001
+ 1.8550725e+002
+ 6.0093897e+001
+ 1.0847458e+002
+ 8.9510490e+001
+ 7.1508380e+001
+ 4.0125392e+001
+ 4.0634921e+001
+ 4.0634921e+001
+ 4.0251572e+001
+ 4.0506329e+001
+ 4.3986254e+001
+ 4.0506329e+001
+ 9.8461538e+001
+ 5.6140351e+001
+ 6.5641026e+001
+ 5.4237288e+001
+ 1.1636364e+002
+ 3.4316354e+001
+ 3.4972678e+001
+ 3.7758112e+001
+ 4.0634921e+001
+ 4.0506329e+001
+ 4.1290323e+001
+ 4.2524917e+001
+ 4.3389831e+001
+ 4.4599303e+001
+ 4.4912281e+001
+ 4.6545455e+001
+ 4.7232472e+001
+ 4.8301887e+001
+ 4.9230769e+001
+ 4.9420849e+001
+ 5.0393701e+001
+ 5.1405622e+001
+ 5.3333333e+001
+ 5.3112033e+001
+ 1.1034483e+002
+ 9.7709924e+001
+ 1.4382022e+002
+ 5.0996016e+001
+ 5.1821862e+001
+ 5.0996016e+001
+ 5.2032520e+001
+ 5.3112033e+001
+ 5.3556485e+001
+ 5.4468085e+001
+ 5.5652174e+001
+ 5.4700855e+001
+ 5.4700855e+001
+ 5.4935622e+001
+ 5.4700855e+001
+ 5.4700855e+001
+ 5.4468085e+001
+ 5.4468085e+001
+ 5.4468085e+001
+ 5.4468085e+001
+ 5.3333333e+001
+ 5.1405622e+001
+ 5.0996016e+001
+ 5.0000000e+001
+ 4.8120301e+001
+ 4.8669202e+001
+ 4.7058824e+001
+ 4.6376812e+001
+ 4.5070423e+001
+ 4.4912281e+001
+ 4.4137931e+001
+ 4.2809365e+001
+ 4.2666667e+001
+ 4.2105263e+001
+ 4.1423948e+001
+ 4.1290323e+001
+ 4.1290323e+001
+ 4.1290323e+001
+ 4.0634921e+001
+ 4.0634921e+001
+ 4.0634921e+001
+ 4.0634921e+001
+ 4.0764331e+001
+ 4.1423948e+001
+ 4.2953020e+001
+ 4.5551601e+001
+ 1.7534247e+002
+ 4.7232472e+001
+ 1.3763441e+002
+ 1.3061224e+002
+ 4.5551601e+001
+ 4.3686007e+001
+ 4.8669202e+001
+ 9.4117647e+001
+ 8.1012658e+001
+ 1.1228070e+002
+ 1.3617021e+002
+ 4.3097643e+001
+ 4.3835616e+001
+ 4.6376812e+001
+ 4.6545455e+001
+ 4.6043165e+001
+ 4.8301887e+001
+ 4.9042146e+001
+ 4.9420849e+001
+ 5.1200000e+001
+ 5.1405622e+001
+ 5.2244898e+001
+ 1.2929293e+002
+ 1.2929293e+002
+ 1.5238095e+002
+ 1.5238095e+002
+ 1.3913043e+002
+ 9.0140845e+001
+ 1.0940171e+002
+ 9.0140845e+001
+ 1.2307692e+002
+ 8.9510490e+001
+ 6.9565217e+001
+ 7.3142857e+001
+ 1.1034483e+002
+ 7.8048780e+001
+ 7.2727273e+001
+ 1.0078740e+002
+ 1.0940171e+002
+ 1.1743119e+002
+ 8.7074830e+001
+ 1.8550725e+002
+ 6.5306122e+001
+ 1.3617021e+002
+ 5.2674897e+001
+ 1.0940171e+002
+ 1.5238095e+002
+ 1.4065934e+002
+ 1.0756303e+002
+ 1.0406504e+002
+ 5.0793651e+001
+ 4.9420849e+001
+ 4.4444444e+001
+ 7.0329670e+001
+ 7.2727273e+001
+ 7.4418605e+001
+ 1.1636364e+002
+ 1.0406504e+002
+ 1.2307692e+002
+ 1.2549020e+002
+ 1.7297297e+002
+ 4.5878136e+001
+ 4.9805447e+001
+ 6.2745098e+001
+ 9.2086331e+001
+ 9.1428571e+001
+ 5.7142857e+001
+ 4.8484848e+001
+ 4.1157556e+001
+ 2.2857143e+001
+ 3.0046948e+001
+ 9.4814815e+001
+ 5.7918552e+001
+ 9.0140845e+001
+ 7.4418605e+001
+ 7.4418605e+001
+ 5.4700855e+001
+ 9.5522388e+001
+ 7.4853801e+001
+ 9.4117647e+001
+ 9.5522388e+001
+ 9.9224806e+001
+ 8.1012658e+001
+ 1.1851852e+002
+ 6.8817204e+001
+ 8.5906040e+001
+ 6.7015707e+001
+ 4.3537415e+001
+ 6.5306122e+001
+ 3.1295844e+001
+ 7.5739645e+001
+ 6.2135922e+001
+ 9.9224806e+001
+ 5.7657658e+001
+ 5.2244898e+001
+ 5.8447489e+001
+ 0.0000000e+000
+ 0.0000000e+000
+ 0.0000000e+000
+ 0.0000000e+000
+ 0.0000000e+000
diff --git a/libs/libcodec2/raw/b0067.raw b/libs/libcodec2/raw/b0067.raw
new file mode 100644
index 0000000000..3aea9cdaaa
Binary files /dev/null and b/libs/libcodec2/raw/b0067.raw differ
diff --git a/libs/libcodec2/raw/f2400.raw b/libs/libcodec2/raw/f2400.raw
new file mode 100644
index 0000000000..5f4427f2fb
Binary files /dev/null and b/libs/libcodec2/raw/f2400.raw differ
diff --git a/libs/libcodec2/raw/forig.raw b/libs/libcodec2/raw/forig.raw
new file mode 100644
index 0000000000..4ba294d788
Binary files /dev/null and b/libs/libcodec2/raw/forig.raw differ
diff --git a/libs/libcodec2/raw/forig_g729a.raw b/libs/libcodec2/raw/forig_g729a.raw
new file mode 100644
index 0000000000..fbca567b24
Binary files /dev/null and b/libs/libcodec2/raw/forig_g729a.raw differ
diff --git a/libs/libcodec2/raw/forig_gsm13k.raw b/libs/libcodec2/raw/forig_gsm13k.raw
new file mode 100644
index 0000000000..71cbe6f6de
Binary files /dev/null and b/libs/libcodec2/raw/forig_gsm13k.raw differ
diff --git a/libs/libcodec2/raw/forig_speex_8k.raw b/libs/libcodec2/raw/forig_speex_8k.raw
new file mode 100644
index 0000000000..e95302ef59
Binary files /dev/null and b/libs/libcodec2/raw/forig_speex_8k.raw differ
diff --git a/libs/libcodec2/raw/hts.raw b/libs/libcodec2/raw/hts.raw
new file mode 100644
index 0000000000..79f869add1
Binary files /dev/null and b/libs/libcodec2/raw/hts.raw differ
diff --git a/libs/libcodec2/raw/hts1.raw b/libs/libcodec2/raw/hts1.raw
new file mode 100644
index 0000000000..3369387e09
Binary files /dev/null and b/libs/libcodec2/raw/hts1.raw differ
diff --git a/libs/libcodec2/raw/hts1a.raw b/libs/libcodec2/raw/hts1a.raw
new file mode 100644
index 0000000000..7332f936e4
Binary files /dev/null and b/libs/libcodec2/raw/hts1a.raw differ
diff --git a/libs/libcodec2/raw/hts1a_g729a.raw b/libs/libcodec2/raw/hts1a_g729a.raw
new file mode 100644
index 0000000000..130f1ddcb1
Binary files /dev/null and b/libs/libcodec2/raw/hts1a_g729a.raw differ
diff --git a/libs/libcodec2/raw/hts1a_gsm13k.raw b/libs/libcodec2/raw/hts1a_gsm13k.raw
new file mode 100644
index 0000000000..dd102f59c6
Binary files /dev/null and b/libs/libcodec2/raw/hts1a_gsm13k.raw differ
diff --git a/libs/libcodec2/raw/hts1a_speex_8k.raw b/libs/libcodec2/raw/hts1a_speex_8k.raw
new file mode 100644
index 0000000000..9289e1c923
Binary files /dev/null and b/libs/libcodec2/raw/hts1a_speex_8k.raw differ
diff --git a/libs/libcodec2/raw/hts2.raw b/libs/libcodec2/raw/hts2.raw
new file mode 100644
index 0000000000..0bb9df1028
Binary files /dev/null and b/libs/libcodec2/raw/hts2.raw differ
diff --git a/libs/libcodec2/raw/hts2a.raw b/libs/libcodec2/raw/hts2a.raw
new file mode 100644
index 0000000000..6d9cf17bb9
Binary files /dev/null and b/libs/libcodec2/raw/hts2a.raw differ
diff --git a/libs/libcodec2/raw/hts2a_g729a.raw b/libs/libcodec2/raw/hts2a_g729a.raw
new file mode 100644
index 0000000000..9199b0ad70
Binary files /dev/null and b/libs/libcodec2/raw/hts2a_g729a.raw differ
diff --git a/libs/libcodec2/raw/hts2a_gsm13k.raw b/libs/libcodec2/raw/hts2a_gsm13k.raw
new file mode 100644
index 0000000000..f0a58505d1
Binary files /dev/null and b/libs/libcodec2/raw/hts2a_gsm13k.raw differ
diff --git a/libs/libcodec2/raw/hts2a_speex_8k.raw b/libs/libcodec2/raw/hts2a_speex_8k.raw
new file mode 100644
index 0000000000..c421bb4e7d
Binary files /dev/null and b/libs/libcodec2/raw/hts2a_speex_8k.raw differ
diff --git a/libs/libcodec2/raw/m2400.raw b/libs/libcodec2/raw/m2400.raw
new file mode 100644
index 0000000000..1c0956daba
Binary files /dev/null and b/libs/libcodec2/raw/m2400.raw differ
diff --git a/libs/libcodec2/raw/mmt1.raw b/libs/libcodec2/raw/mmt1.raw
new file mode 100644
index 0000000000..40638a5a8e
Binary files /dev/null and b/libs/libcodec2/raw/mmt1.raw differ
diff --git a/libs/libcodec2/raw/mmt1_g729a.raw b/libs/libcodec2/raw/mmt1_g729a.raw
new file mode 100644
index 0000000000..196716e04f
Binary files /dev/null and b/libs/libcodec2/raw/mmt1_g729a.raw differ
diff --git a/libs/libcodec2/raw/mmt1_gsm13k.raw b/libs/libcodec2/raw/mmt1_gsm13k.raw
new file mode 100644
index 0000000000..a9965af376
Binary files /dev/null and b/libs/libcodec2/raw/mmt1_gsm13k.raw differ
diff --git a/libs/libcodec2/raw/mmt1_speex_8k.raw b/libs/libcodec2/raw/mmt1_speex_8k.raw
new file mode 100644
index 0000000000..769a49cde4
Binary files /dev/null and b/libs/libcodec2/raw/mmt1_speex_8k.raw differ
diff --git a/libs/libcodec2/raw/morig.raw b/libs/libcodec2/raw/morig.raw
new file mode 100644
index 0000000000..4af0e8f90f
Binary files /dev/null and b/libs/libcodec2/raw/morig.raw differ
diff --git a/libs/libcodec2/raw/morig_g729a.raw b/libs/libcodec2/raw/morig_g729a.raw
new file mode 100644
index 0000000000..636ecfdc7f
Binary files /dev/null and b/libs/libcodec2/raw/morig_g729a.raw differ
diff --git a/libs/libcodec2/raw/morig_gsm13k.raw b/libs/libcodec2/raw/morig_gsm13k.raw
new file mode 100644
index 0000000000..660368fece
Binary files /dev/null and b/libs/libcodec2/raw/morig_gsm13k.raw differ
diff --git a/libs/libcodec2/raw/morig_speex_8k.raw b/libs/libcodec2/raw/morig_speex_8k.raw
new file mode 100644
index 0000000000..ab667a1ba2
Binary files /dev/null and b/libs/libcodec2/raw/morig_speex_8k.raw differ
diff --git a/libs/libcodec2/script/menu.sh b/libs/libcodec2/script/menu.sh
new file mode 100755
index 0000000000..11297df9b9
--- /dev/null
+++ b/libs/libcodec2/script/menu.sh
@@ -0,0 +1,70 @@
+#!/bin/bash
+# ./menu.sh
+#
+# David Rowe
+# Created August 2009
+#
+# Presents a menu of sound files, press 1 to play file1, 2 to play file2 etc
+#
+# The aim is to make comparing files with different processing easier than
+# using up-arrow on the command line. Based on cdialog.
+#
+# usage:
+# menu.sh file1.raw file2.raw ........ [-d playbackdevice]
+#
+# for example:
+#
+# ../script/menu.sh hts1a.raw hts1a_uq.raw
+#
+# or:
+#
+# ../script/menu.sh hts1a.raw hts1a_uq.raw -d /dev/dsp1
+#
+
+# Copyright (C) 2007 David Rowe
+#
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2, as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+files=0
+items="Q-Quit\n"
+while [ ! -z "$1" ]
+do
+ case "$1" in
+ -d) dsp="${1} ${2}"; shift;;
+ *) files=`expr 1 + $files`;
+ new_file=$1;
+ file[$files]=$new_file;
+ items="${items} ${files}-${new_file}\n";;
+ esac
+ shift
+done
+
+readchar=1
+echo -n -e "\r" $items"- "
+while [ $readchar -ne 0 ]
+do
+ echo -n -e "\r -"
+ stty cbreak # or stty raw
+ readchar=`dd if=/dev/tty bs=1 count=1 2>/dev/null`
+ stty -cbreak
+ if [ $readchar == 'q' ] ; then
+ readchar=0
+ fi
+ if [ $readchar -ne 0 ] ; then
+ play -r 8000 -s -2 ${file[$readchar]} $dsp 2> /dev/null
+ fi
+done
+echo
diff --git a/libs/libcodec2/script/playraw.sh b/libs/libcodec2/script/playraw.sh
new file mode 100755
index 0000000000..683cbaa16d
--- /dev/null
+++ b/libs/libcodec2/script/playraw.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+# Plays a raw file
+# usage:
+# playraw file.raw
+# playraw file.raw -d /dev/dsp1 (e.g. for USB headphones)
+play -r 8000 -s -2 $1 $2 $3
diff --git a/libs/libcodec2/script/raw2wav.sh b/libs/libcodec2/script/raw2wav.sh
new file mode 100755
index 0000000000..a05efb72f6
--- /dev/null
+++ b/libs/libcodec2/script/raw2wav.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+# Converts 16 bit signed short 8 kHz raw (headerless) files to wave
+sox -r 8000 -s -2 $1 $2
diff --git a/libs/libcodec2/script/wav2raw.sh b/libs/libcodec2/script/wav2raw.sh
new file mode 100755
index 0000000000..39c0f1aefd
--- /dev/null
+++ b/libs/libcodec2/script/wav2raw.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+# Converts wave files to raw (headerless) files
+sox $1 -t raw $2
diff --git a/libs/libcodec2/src/Makefile.am b/libs/libcodec2/src/Makefile.am
new file mode 100644
index 0000000000..ce240785d9
--- /dev/null
+++ b/libs/libcodec2/src/Makefile.am
@@ -0,0 +1,53 @@
+AM_CFLAGS = -I../src -Wall -DFLOATING_POINT -DVAR_ARRAYS
+AUTOMAKE_OPTS = gnu
+NAME = libcodec2
+AM_CPPFLAGS = $(AM_CFLAGS)
+
+lib_LTLIBRARIES = libcodec2.la
+libcodec2_la_SOURCES = dump.c \
+lpc.c \
+nlp.c \
+postfilter.c \
+sine.c \
+codec2.c \
+four1.c \
+interp.c \
+lsp.c \
+phase.c \
+quantise.c \
+pack.c \
+codebook.c
+
+libcodec2_la_CFLAGS = $(AM_CFLAGS)
+libcodec2_la_LDFLAGS = $(LIBS)
+
+library_includedir = $(prefix)
+library_include_HEADERS = codec2.h \
+defines.h \
+four1.h \
+interp.h \
+lsp.h \
+phase.h \
+quantise.h \
+comp.h \
+dump.h \
+globals.h \
+lpc.h \
+nlp.h \
+postfilter.h \
+sine.h \
+codebook.h
+
+bin_PROGRAMS = c2dec c2enc c2sim
+
+c2dec_SOURCES = c2dec.c
+c2dec_LDADD = $(lib_LTLIBRARIES)
+c2dec_LDFLAGS = $(LIBS)
+
+c2enc_SOURCES = c2enc.c
+c2enc_LDADD = $(lib_LTLIBRARIES)
+c2enc_LDFLAGS = $(LIBS)
+
+c2sim_SOURCES = c2sim.c
+c2sim_LDADD = $(lib_LTLIBRARIES)
+c2sim_LDFLAGS = $(LIBS)
diff --git a/libs/libcodec2/src/c2dec.c b/libs/libcodec2/src/c2dec.c
new file mode 100644
index 0000000000..3b876bcac0
--- /dev/null
+++ b/libs/libcodec2/src/c2dec.c
@@ -0,0 +1,80 @@
+/*---------------------------------------------------------------------------*\
+
+ FILE........: c2dec.c
+ AUTHOR......: David Rowe
+ DATE CREATED: 23/8/2010
+
+ Decodes a file of bits to a file of raw speech samples using codec2. Demo
+ program for codec2.
+
+ NOTE: the bit file is not packed, 51 bits/frame actually consumes 51
+ bytes/frame on disk. If you are using this for a real world
+ application you may want to pack the 51 bytes into 7 bytes.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+ Copyright (C) 2010 David Rowe
+
+ All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License version 2.1, as
+ published by the Free Software Foundation. This program is
+ distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "codec2.h"
+
+#include
+#include
+#include
+#include
+
+int main(int argc, char *argv[])
+{
+ static const int bitsSize = ((CODEC2_BITS_PER_FRAME + 7) / 8);
+ void *codec2;
+ FILE *fin;
+ FILE *fout;
+ short buf[CODEC2_SAMPLES_PER_FRAME];
+ unsigned char bits[bitsSize];
+
+ if (argc != 3) {
+ printf("usage: %s InputBitFile OutputRawSpeechFile\n", argv[0]);
+ exit(1);
+ }
+
+ if ( (fin = fopen(argv[1],"rb")) == NULL ) {
+ fprintf(stderr, "Error opening input bit file: %s: %s.\n",
+ argv[1], strerror(errno));
+ exit(1);
+ }
+
+ if ( (fout = fopen(argv[2],"wb")) == NULL ) {
+ fprintf(stderr, "Error opening output speech file: %s: %s.\n",
+ argv[2], strerror(errno));
+ exit(1);
+ }
+
+ codec2 = codec2_create();
+
+ while(fread(bits, sizeof(char), bitsSize, fin) == bitsSize) {
+ codec2_decode(codec2, buf, bits);
+ fwrite(buf, sizeof(short), CODEC2_SAMPLES_PER_FRAME, fout);
+ }
+
+ codec2_destroy(codec2);
+
+ fclose(fin);
+ fclose(fout);
+
+ return 0;
+}
diff --git a/libs/libcodec2/src/c2enc.c b/libs/libcodec2/src/c2enc.c
new file mode 100644
index 0000000000..8fd7c7778d
--- /dev/null
+++ b/libs/libcodec2/src/c2enc.c
@@ -0,0 +1,82 @@
+/*---------------------------------------------------------------------------*\
+
+ FILE........: c2enc.c
+ AUTHOR......: David Rowe
+ DATE CREATED: 23/8/2010
+
+ Encodes a file of raw speech samples using codec2 and ouputs a file
+ of bits (each bit is stored in the LSB or each output byte). Demo
+ program for codec2.
+
+ NOTE: the bit file is not packed, 51 bits/frame actually consumes 51
+ bytes/frame on disk. If you are using this for a real world
+ application you may want to pack the 51 bytes into 7 bytes.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+ Copyright (C) 2010 David Rowe
+
+ All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License version 2.1, as
+ published by the Free Software Foundation. This program is
+ distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "codec2.h"
+
+#include
+#include
+#include
+#include
+
+int main(int argc, char *argv[])
+{
+ static const int bitsSize = ((CODEC2_BITS_PER_FRAME + 7) / 8);
+ void *codec2;
+ FILE *fin;
+ FILE *fout;
+ short buf[CODEC2_SAMPLES_PER_FRAME];
+ unsigned char bits[bitsSize];
+
+ if (argc != 3) {
+ printf("usage: %s InputRawspeechFile OutputBitFile\n", argv[0]);
+ exit(1);
+ }
+
+ if ( (fin = fopen(argv[1],"rb")) == NULL ) {
+ fprintf(stderr, "Error opening input bit file: %s: %s.\n",
+ argv[1], strerror(errno));
+ exit(1);
+ }
+
+ if ( (fout = fopen(argv[2],"wb")) == NULL ) {
+ fprintf(stderr, "Error opening output speech file: %s: %s.\n",
+ argv[2], strerror(errno));
+ exit(1);
+ }
+
+ codec2 = codec2_create();
+
+ while(fread(buf, sizeof(short), CODEC2_SAMPLES_PER_FRAME, fin) ==
+ CODEC2_SAMPLES_PER_FRAME) {
+ codec2_encode(codec2, bits, buf);
+ fwrite(bits, sizeof(char), bitsSize, fout);
+ }
+
+ codec2_destroy(codec2);
+
+ fclose(fin);
+ fclose(fout);
+
+ return 0;
+}
diff --git a/libs/libcodec2/src/c2sim.c b/libs/libcodec2/src/c2sim.c
new file mode 100644
index 0000000000..b9e5f0f78a
--- /dev/null
+++ b/libs/libcodec2/src/c2sim.c
@@ -0,0 +1,408 @@
+/*---------------------------------------------------------------------------*\
+
+ FILE........: c2sim.c
+ AUTHOR......: David Rowe
+ DATE CREATED: 20/8/2010
+
+ Codec2 simulation. Combines encoder and decoder and allows switching in
+ out various algorithms and quantisation steps.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+ Copyright (C) 2009 David Rowe
+
+ All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License version 2.1, as
+ published by the Free Software Foundation. This program is
+ distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "defines.h"
+#include "sine.h"
+#include "nlp.h"
+#include "dump.h"
+#include "lpc.h"
+#include "lsp.h"
+#include "quantise.h"
+#include "phase.h"
+#include "postfilter.h"
+#include "interp.h"
+
+/*---------------------------------------------------------------------------*\
+
+ switch_present()
+
+ Searches the command line arguments for a "switch". If the switch is
+ found, returns the command line argument where it ws found, else returns
+ NULL.
+
+\*---------------------------------------------------------------------------*/
+
+int switch_present(sw,argc,argv)
+register char sw[]; /* switch in string form */
+register int argc; /* number of command line arguments */
+register char *argv[]; /* array of command line arguments in string form */
+{
+ register int i; /* loop variable */
+
+ for(i=1; i 20)) {
+ fprintf(stderr, "Error in lpc order: %d\n", order);
+ exit(1);
+ }
+ }
+
+ dump = switch_present("--dump",argc,argv);
+ if (dump)
+ dump_on(argv[dump+1]);
+
+ lsp = switch_present("--lsp",argc,argv);
+ lsp_quantiser = 0;
+
+ phase0 = switch_present("--phase0",argc,argv);
+ if (phase0) {
+ ex_phase[0] = 0;
+ }
+
+ hand_voicing = switch_present("--hand_voicing",argc,argv);
+ if (hand_voicing) {
+ fvoicing = fopen(argv[hand_voicing+1],"rt");
+ assert(fvoicing != NULL);
+ }
+
+ bg_est = 0.0;
+ postfilt = switch_present("--postfilter",argc,argv);
+
+ decimate = switch_present("--dec",argc,argv);
+
+ /* Initialise ------------------------------------------------------------*/
+
+ make_analysis_window(w,W);
+ make_synthesis_window(Pn);
+ quantise_init();
+
+ /* Main loop ------------------------------------------------------------*/
+
+ frames = 0;
+ sum_snr = 0;
+ while(fread(buf,sizeof(short),N,fin)) {
+ frames++;
+
+ /* Read input speech */
+
+ for(i=0; i 32767.0)
+ buf[i] = 32767;
+ else if (Sn_[i] < -32767.0)
+ buf[i] = -32767;
+ else
+ buf[i] = Sn_[i];
+ }
+
+}
diff --git a/libs/libcodec2/src/codeall.sh b/libs/libcodec2/src/codeall.sh
new file mode 100755
index 0000000000..6bdf825f49
--- /dev/null
+++ b/libs/libcodec2/src/codeall.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+# codeall.sh
+# David Rowe 24 sep 2009
+# Code all samples using various processing steps
+./code.sh hts1a
+./code.sh hts2a
+./code.sh mmt1
+./code.sh morig
+./code.sh forig
diff --git a/libs/libcodec2/src/codebook.c b/libs/libcodec2/src/codebook.c
new file mode 100644
index 0000000000..74ed9ad5fe
--- /dev/null
+++ b/libs/libcodec2/src/codebook.c
@@ -0,0 +1,162 @@
+float codebook_lsp1[] = {
+ 225,
+ 250,
+ 275,
+ 300,
+ 325,
+ 350,
+ 375,
+ 400,
+ 425,
+ 450,
+ 475,
+ 500,
+ 525,
+ 550,
+ 575,
+ 600,0,0,0,0,0,0,0,0,0,0
+};
+
+float codebook_lsp2[] = {
+ 325,
+ 350,
+ 375,
+ 400,
+ 425,
+ 450,
+ 475,
+ 500,
+ 525,
+ 550,
+ 575,
+ 600,
+ 625,
+ 650,
+ 675,
+ 700,0,0,0,0,0,0,0,0,0,0
+};
+
+float codebook_lsp3[] = {
+ 500,
+ 550,
+ 600,
+ 650,
+ 700,
+ 750,
+ 800,
+ 850,
+ 900,
+ 950,
+ 1000,
+ 1050,
+ 1100,
+ 1150,
+ 1200,
+ 1250,0,0,0,0,0,0,0,0,0,0
+};
+
+float codebook_lsp4[] = {
+ 700,
+ 800,
+ 900,
+ 1000,
+ 1100,
+ 1200,
+ 1300,
+ 1400,
+ 1500,
+ 1600,
+ 1700,
+ 1800,
+ 1900,
+ 2000,
+ 2100,
+ 2200,0,0,0,0,0,0,0,0,0,0
+};
+
+float codebook_lsp5[] = {
+ 950,
+ 1050,
+ 1150,
+ 1250,
+ 1350,
+ 1450,
+ 1550,
+ 1650,
+ 1750,
+ 1850,
+ 1950,
+ 2050,
+ 2150,
+ 2250,
+ 2350,
+ 2450,0,0,0,0,0,0,0,0,0,0
+};
+
+float codebook_lsp6[] = {
+ 1100,
+ 1200,
+ 1300,
+ 1400,
+ 1500,
+ 1600,
+ 1700,
+ 1800,
+ 1900,
+ 2000,
+ 2100,
+ 2200,
+ 2300,
+ 2400,
+ 2500,
+ 2600,0,0,0,0,0,0,0,0,0,0
+};
+
+float codebook_lsp7[] = {
+ 1500,
+ 1600,
+ 1700,
+ 1800,
+ 1900,
+ 2000,
+ 2100,
+ 2200,
+ 2300,
+ 2400,
+ 2500,
+ 2600,
+ 2700,
+ 2800,
+ 2900,
+ 3000,0,0,0,0,0,0,0,0,0,0
+};
+
+float codebook_lsp8[] = {
+ 2300,
+ 2400,
+ 2500,
+ 2600,
+ 2700,
+ 2800,
+ 2900,
+ 3000,0,0,0,0,0,0,0,0,0,0
+};
+
+float codebook_lsp9[] = {
+ 2500,
+ 2600,
+ 2700,
+ 2800,
+ 2900,
+ 3000,
+ 3100,
+ 3200,0,0,0,0,0,0,0,0,0,0
+};
+
+float codebook_lsp10[] = {
+ 2900,
+ 3100,
+ 3300,
+ 3500,0,0,0,0,0,0,0,0,0,0
+};
+
diff --git a/libs/libcodec2/src/codebook.h b/libs/libcodec2/src/codebook.h
new file mode 100644
index 0000000000..d2e77a53f2
--- /dev/null
+++ b/libs/libcodec2/src/codebook.h
@@ -0,0 +1,15 @@
+#ifndef CODEBOOK_H
+#define CODEBOOK_H
+
+extern float codebook_lsp1[];
+extern float codebook_lsp2[];
+extern float codebook_lsp3[];
+extern float codebook_lsp4[];
+extern float codebook_lsp5[];
+extern float codebook_lsp6[];
+extern float codebook_lsp7[];
+extern float codebook_lsp8[];
+extern float codebook_lsp9[];
+extern float codebook_lsp10[];
+
+#endif
diff --git a/libs/libcodec2/src/codec2.c b/libs/libcodec2/src/codec2.c
new file mode 100644
index 0000000000..30142fec1d
--- /dev/null
+++ b/libs/libcodec2/src/codec2.c
@@ -0,0 +1,337 @@
+/*---------------------------------------------------------------------------*\
+
+ FILE........: codec2.c
+ AUTHOR......: David Rowe
+ DATE CREATED: 21/8/2010
+
+ Codec2 fully quantised encoder and decoder functions. If you want use
+ codec2, the codec2_xxx functions are for you.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+ Copyright (C) 2010 David Rowe
+
+ All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License version 2.1, as
+ published by the Free Software Foundation. This program is
+ distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include
+#include
+#include
+#include
+#include
+
+#include "defines.h"
+#include "sine.h"
+#include "nlp.h"
+#include "dump.h"
+#include "lpc.h"
+#include "quantise.h"
+#include "phase.h"
+#include "interp.h"
+#include "postfilter.h"
+#include "codec2.h"
+
+typedef struct {
+ float Sn[M]; /* input speech */
+ float w[M]; /* time domain hamming window */
+ COMP W[FFT_ENC]; /* DFT of w[] */
+ float Pn[2*N]; /* trapezoidal synthesis window */
+ float Sn_[2*N]; /* synthesised speech */
+ float prev_Wo; /* previous frame's pitch estimate */
+ float ex_phase; /* excitation model phase track */
+ float bg_est; /* background noise estimate for post filter */
+ MODEL prev_model; /* model parameters from 20ms ago */
+ void *nlp; /* pitch predictor states */
+} CODEC2;
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION HEADERS
+
+\*---------------------------------------------------------------------------*/
+
+void analyse_one_frame(CODEC2 *c2, MODEL *model, short speech[]);
+void synthesise_one_frame(CODEC2 *c2, short speech[], MODEL *model,float ak[]);
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTIONS
+
+\*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: codec2_create
+ AUTHOR......: David Rowe
+ DATE CREATED: 21/8/2010
+
+ Create and initialise an instance of the codec. Returns a pointer
+ to the codec states or NULL on failure. One set of states is
+ sufficient for a full duuplex codec (i.e. an encoder and decoder).
+ You don't need separate states for encoders and decoders. See
+ c2enc.c and c2dec.c for examples.
+
+\*---------------------------------------------------------------------------*/
+
+void *codec2_create()
+{
+ CODEC2 *c2;
+ int i,l;
+
+ c2 = (CODEC2*)malloc(sizeof(CODEC2));
+ if (c2 == NULL)
+ return NULL;
+
+ for(i=0; iSn[i] = 1.0;
+ for(i=0; i<2*N; i++)
+ c2->Sn_[i] = 0;
+ make_analysis_window(c2->w,c2->W);
+ make_synthesis_window(c2->Pn);
+ quantise_init();
+ c2->prev_Wo = 0.0;
+ c2->bg_est = 0.0;
+ c2->ex_phase = 0.0;
+
+ for(l=1; l<=MAX_AMP; l++)
+ c2->prev_model.A[l] = 0.0;
+ c2->prev_model.Wo = TWO_PI/P_MAX;
+
+ c2->nlp = nlp_create();
+ if (c2->nlp == NULL) {
+ free (c2);
+ return NULL;
+ }
+
+ return (void*)c2;
+}
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: codec2_create
+ AUTHOR......: David Rowe
+ DATE CREATED: 21/8/2010
+
+ Destroy an instance of the codec.
+
+\*---------------------------------------------------------------------------*/
+
+void codec2_destroy(void *codec2_state)
+{
+ CODEC2 *c2;
+
+ assert(codec2_state != NULL);
+ c2 = (CODEC2*)codec2_state;
+ nlp_destroy(c2->nlp);
+ free(codec2_state);
+}
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: codec2_encode
+ AUTHOR......: David Rowe
+ DATE CREATED: 21/8/2010
+
+ Encodes 160 speech samples (20ms of speech) into 51 bits.
+
+ The codec2 algorithm actually operates internally on 10ms (80
+ sample) frames, so we run the encoding algorithm twice. On the
+ first frame we just send the voicing bit. One the second frame we
+ send all model parameters.
+
+ The bit allocation is:
+
+ Parameter bits/frame
+ --------------------------------------
+ Harmonic magnitudes (LSPs) 36
+ Low frequency LPC correction 1
+ Energy 5
+ Wo (fundamental frequnecy) 7
+ Voicing (10ms update) 2
+ TOTAL 51
+
+\*---------------------------------------------------------------------------*/
+
+void codec2_encode(void *codec2_state, unsigned char * bits, short speech[])
+{
+ CODEC2 *c2;
+ MODEL model;
+ int voiced1, voiced2;
+ int lsp_indexes[LPC_ORD];
+ int lpc_correction;
+ int energy_index;
+ int Wo_index;
+ int i;
+ unsigned int nbit = 0;
+
+ assert(codec2_state != NULL);
+ c2 = (CODEC2*)codec2_state;
+
+ /* first 10ms analysis frame - we just want voicing */
+
+ analyse_one_frame(c2, &model, speech);
+ voiced1 = model.voiced;
+
+ /* second 10ms analysis frame */
+
+ analyse_one_frame(c2, &model, &speech[N]);
+ voiced2 = model.voiced;
+
+ Wo_index = encode_Wo(model.Wo);
+ encode_amplitudes(lsp_indexes,
+ &lpc_correction,
+ &energy_index,
+ &model,
+ c2->Sn,
+ c2->w);
+ memset(bits, '\0', ((CODEC2_BITS_PER_FRAME + 7) / 8));
+ pack(bits, &nbit, Wo_index, WO_BITS);
+ for(i=0; iprev_model, &model);
+
+ synthesise_one_frame(c2, speech, &model_interp, ak);
+ synthesise_one_frame(c2, &speech[N], &model, ak);
+
+ memcpy(&c2->prev_model, &model, sizeof(MODEL));
+}
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: synthesise_one_frame()
+ AUTHOR......: David Rowe
+ DATE CREATED: 23/8/2010
+
+ Synthesise 80 speech samples (10ms) from model parameters.
+
+\*---------------------------------------------------------------------------*/
+
+void synthesise_one_frame(CODEC2 *c2, short speech[], MODEL *model, float ak[])
+{
+ int i;
+
+ phase_synth_zero_order(model, ak, &c2->ex_phase);
+ postfilter(model, &c2->bg_est);
+ synthesise(c2->Sn_, model, c2->Pn, 1);
+
+ for(i=0; iSn_[i] > 32767.0)
+ speech[i] = 32767;
+ else if (c2->Sn_[i] < -32767.0)
+ speech[i] = -32767;
+ else
+ speech[i] = c2->Sn_[i];
+ }
+
+}
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: analyse_one_frame()
+ AUTHOR......: David Rowe
+ DATE CREATED: 23/8/2010
+
+ Extract sinusoidal model parameters from 80 speech samples (10ms of
+ speech).
+
+\*---------------------------------------------------------------------------*/
+
+void analyse_one_frame(CODEC2 *c2, MODEL *model, short speech[])
+{
+ COMP Sw[FFT_ENC];
+ COMP Sw_[FFT_ENC];
+ float pitch;
+ int i;
+
+ /* Read input speech */
+
+ for(i=0; iSn[i] = c2->Sn[i+N];
+ for(i=0; iSn[i+M-N] = speech[i];
+ dft_speech(Sw, c2->Sn, c2->w);
+
+ /* Estimate pitch */
+
+ nlp(c2->nlp,c2->Sn,N,M,P_MIN,P_MAX,&pitch,Sw,&c2->prev_Wo);
+ c2->prev_Wo = TWO_PI/pitch;
+ model->Wo = TWO_PI/pitch;
+ model->L = PI/model->Wo;
+
+ /* estimate model parameters */
+
+ dft_speech(Sw, c2->Sn, c2->w);
+ two_stage_pitch_refinement(model, Sw);
+ estimate_amplitudes(model, Sw, c2->W);
+ est_voicing_mbe(model, Sw, c2->W, (FS/TWO_PI)*model->Wo, Sw_);
+}
diff --git a/libs/libcodec2/src/codec2.h b/libs/libcodec2/src/codec2.h
new file mode 100644
index 0000000000..7a1d1450a5
--- /dev/null
+++ b/libs/libcodec2/src/codec2.h
@@ -0,0 +1,43 @@
+/*---------------------------------------------------------------------------*\
+
+ FILE........: codec2.h
+ AUTHOR......: David Rowe
+ DATE CREATED: 21/8/2010
+
+ Codec2 fully quantised encoder and decoder functions. If you want use
+ codec2, these are the functions you need to call.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+ Copyright (C) 2010 David Rowe
+
+ All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License version 2.1, as
+ published by the Free Software Foundation. This program is
+ distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __CODEC2__
+#define __CODEC2__
+#include "codebook.h"
+
+#define CODEC2_SAMPLES_PER_FRAME 160
+#define CODEC2_BITS_PER_FRAME 51
+
+void *codec2_create();
+void codec2_destroy(void *codec2_state);
+void codec2_encode(void *codec2_state, unsigned char * bits, short speech_in[]);
+void codec2_decode(void *codec2_state, short speech_out[],
+ const unsigned char * bits);
+
+#endif
diff --git a/libs/libcodec2/src/comp.h b/libs/libcodec2/src/comp.h
new file mode 100644
index 0000000000..bca01b5d2f
--- /dev/null
+++ b/libs/libcodec2/src/comp.h
@@ -0,0 +1,39 @@
+/*---------------------------------------------------------------------------*\
+
+ FILE........: comp.h
+ AUTHOR......: David Rowe
+ DATE CREATED: 24/08/09
+
+ Complex number definition.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+ Copyright (C) 2009 David Rowe
+
+ All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License version 2.1, as
+ published by the Free Software Foundation. This program is
+ distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __COMP__
+#define __COMP__
+
+/* Complex number */
+
+typedef struct {
+ float real;
+ float imag;
+} COMP;
+
+#endif
diff --git a/libs/libcodec2/src/defines.h b/libs/libcodec2/src/defines.h
new file mode 100644
index 0000000000..ef4899f70a
--- /dev/null
+++ b/libs/libcodec2/src/defines.h
@@ -0,0 +1,84 @@
+/*---------------------------------------------------------------------------*\
+
+ FILE........: defines.h
+ AUTHOR......: David Rowe
+ DATE CREATED: 23/4/93
+
+ Defines and structures used throughout the codec.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+ Copyright (C) 2009 David Rowe
+
+ All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License version 2.1, as
+ published by the Free Software Foundation. This program is
+ distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __DEFINES__
+#define __DEFINES__
+
+/*---------------------------------------------------------------------------*\
+
+ DEFINES
+
+\*---------------------------------------------------------------------------*/
+
+/* General defines */
+
+#define N 80 /* number of samples per frame */
+#define MAX_AMP 80 /* maximum number of harmonics */
+#define PI 3.141592654 /* mathematical constant */
+#define TWO_PI 6.283185307 /* mathematical constant */
+#define FS 8000 /* sample rate in Hz */
+#define MAX_STR 256 /* maximum string size */
+
+#define NW 279 /* analysis window size */
+#define FFT_ENC 512 /* size of FFT used for encoder */
+#define FFT_DEC 512 /* size of FFT used in decoder */
+#define TW 40 /* Trapezoidal synthesis window overlap */
+#define V_THRESH 4.0 /* voicing threshold in dB */
+#define LPC_MAX 20 /* maximum LPC order */
+#define LPC_ORD 10 /* phase modelling LPC order */
+
+/* Pitch estimation defines */
+
+#define M 320 /* pitch analysis frame size */
+#define P_MIN 20 /* minimum pitch */
+#define P_MAX 160 /* maximum pitch */
+
+/*---------------------------------------------------------------------------*\
+
+ TYPEDEFS
+
+\*---------------------------------------------------------------------------*/
+
+/* Complex number */
+
+typedef struct {
+ float real;
+ float imag;
+} COMP;
+
+/* Structure to hold model parameters for one frame */
+
+typedef struct {
+ float Wo; /* fundamental frequency estimate in radians */
+ int L; /* number of harmonics */
+ float A[MAX_AMP]; /* amplitiude of each harmonic */
+ float phi[MAX_AMP]; /* phase of each harmonic */
+ int voiced; /* non-zero if this frame is voiced */
+} MODEL;
+
+#endif
diff --git a/libs/libcodec2/src/dump.c b/libs/libcodec2/src/dump.c
new file mode 100644
index 0000000000..2d18744483
--- /dev/null
+++ b/libs/libcodec2/src/dump.c
@@ -0,0 +1,402 @@
+/*---------------------------------------------------------------------------*\
+
+ FILE........: dump.c
+ AUTHOR......: David Rowe
+ DATE CREATED: 25/8/09
+
+ Routines to dump data to text files for Octave analysis.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+ All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License version 2.1, as
+ published by the Free Software Foundation. This program is
+ distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "defines.h"
+#include "dump.h"
+#include
+#include
+#include
+#include
+#include
+
+static int dumpon = 0;
+
+static FILE *fsn = NULL;
+static FILE *fsw = NULL;
+static FILE *fsw_ = NULL;
+static FILE *fmodel = NULL;
+static FILE *fqmodel = NULL;
+static FILE *fpw = NULL;
+static FILE *flsp = NULL;
+static FILE *fphase = NULL;
+static FILE *fphase_ = NULL;
+static FILE *ffw = NULL;
+static FILE *fe = NULL;
+static FILE *fsq = NULL;
+static FILE *fdec = NULL;
+static FILE *fsnr = NULL;
+static FILE *fak = NULL;
+static FILE *fbg = NULL;
+static FILE *fE = NULL;
+
+static char prefix[MAX_STR];
+
+void dump_on(char p[]) {
+ dumpon = 1;
+ strcpy(prefix, p);
+}
+
+void dump_off(){
+ if (fsn != NULL)
+ fclose(fsn);
+ if (fsw != NULL)
+ fclose(fsw);
+ if (fsw_ != NULL)
+ fclose(fsw_);
+ if (fmodel != NULL)
+ fclose(fmodel);
+ if (fqmodel != NULL)
+ fclose(fqmodel);
+ if (fpw != NULL)
+ fclose(fpw);
+ if (flsp != NULL)
+ fclose(flsp);
+ if (fphase != NULL)
+ fclose(fphase);
+ if (fphase_ != NULL)
+ fclose(fphase_);
+ if (ffw != NULL)
+ fclose(ffw);
+ if (fe != NULL)
+ fclose(fe);
+ if (fsq != NULL)
+ fclose(fsq);
+ if (fdec != NULL)
+ fclose(fdec);
+ if (fsnr != NULL)
+ fclose(fsnr);
+ if (fak != NULL)
+ fclose(fak);
+ if (fbg != NULL)
+ fclose(fbg);
+ if (fE != NULL)
+ fclose(fE);
+}
+
+void dump_Sn(float Sn[]) {
+ int i;
+ char s[MAX_STR];
+
+ if (!dumpon) return;
+
+ if (fsn == NULL) {
+ sprintf(s,"%s_sn.txt", prefix);
+ fsn = fopen(s, "wt");
+ assert(fsn != NULL);
+ }
+
+ /* split across two lines to avoid max line length problems */
+ /* reconstruct in Octave */
+
+ for(i=0; iWo, model->L);
+ for(l=1; l<=model->L; l++)
+ fprintf(fmodel,"%f\t",model->A[l]);
+ for(l=model->L+1; lvoiced);
+ fprintf(fmodel,"\n");
+}
+
+void dump_quantised_model(MODEL *model) {
+ int l;
+ char s[MAX_STR];
+
+ if (!dumpon) return;
+
+ if (fqmodel == NULL) {
+ sprintf(s,"%s_qmodel.txt", prefix);
+ fqmodel = fopen(s, "wt");
+ assert(fqmodel != NULL);
+ }
+
+ fprintf(fqmodel,"%f\t%d\t", model->Wo, model->L);
+ for(l=1; l<=model->L; l++)
+ fprintf(fqmodel,"%f\t",model->A[l]);
+ for(l=model->L+1; l
+
+#define SWAP(a,b) tempr=(a);(a)=(b);(b)=tempr
+
+void four1(data,nn,isign)
+float data[];
+int nn,isign;
+{
+ int n,mmax,m,j,istep,i;
+ double wtemp,wr,wpr,wpi,wi,theta;
+ float tempr,tempi;
+
+ n=nn << 1;
+ j=1;
+ for (i=1;i i) {
+ SWAP(data[j],data[i]);
+ SWAP(data[j+1],data[i+1]);
+ }
+ m=n >> 1;
+ while (m >= 2 && j > m) {
+ j -= m;
+ m >>= 1;
+ }
+ j += m;
+ }
+ mmax=2;
+ while (n > mmax) {
+ istep=2*mmax;
+ theta=6.28318530717959/(isign*mmax);
+ wtemp=sin(0.5*theta);
+ wpr = -2.0*wtemp*wtemp;
+ wpi=sin(theta);
+ wr=1.0;
+ wi=0.0;
+ for (m=1;m
+#include
+#include
+
+#include "defines.h"
+#include "interp.h"
+
+float sample_log_amp(MODEL *model, float w);
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: interp()
+ AUTHOR......: David Rowe
+ DATE CREATED: 22/8/10
+
+ Given two frames decribed by model parameters 20ms apart, determines
+ the model parameters of the 10ms frame between them. Assumes
+ voicing is available for middle (interpolated) frame. Outputs are
+ amplitudes and Wo for the interpolated frame.
+
+ This version can interpolate the amplitudes between two frames of
+ different Wo and L.
+
+\*---------------------------------------------------------------------------*/
+
+void interpolate(
+ MODEL *interp, /* interpolated model params */
+ MODEL *prev, /* previous frames model params */
+ MODEL *next /* next frames model params */
+)
+{
+ int l;
+ float w,log_amp;
+
+ /* Wo depends on voicing of this and adjacent frames */
+
+ if (interp->voiced) {
+ if (prev->voiced && next->voiced)
+ interp->Wo = (prev->Wo + next->Wo)/2.0;
+ if (!prev->voiced && next->voiced)
+ interp->Wo = next->Wo;
+ if (prev->voiced && !next->voiced)
+ interp->Wo = prev->Wo;
+ }
+ else {
+ interp->Wo = TWO_PI/P_MAX;
+ }
+ interp->L = PI/interp->Wo;
+
+ /* Interpolate amplitudes using linear interpolation in log domain */
+
+ for(l=1; l<=interp->L; l++) {
+ w = l*interp->Wo;
+ log_amp = (sample_log_amp(prev, w) + sample_log_amp(next, w))/2.0;
+ interp->A[l] = pow(10.0, log_amp);
+ }
+}
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: sample_log_amp()
+ AUTHOR......: David Rowe
+ DATE CREATED: 22/8/10
+
+ Samples the amplitude envelope at an arbitrary frequency w. Uses
+ linear interpolation in the log domain to sample between harmonic
+ amplitudes.
+
+\*---------------------------------------------------------------------------*/
+
+float sample_log_amp(MODEL *model, float w)
+{
+ int m;
+ float f, log_amp;
+
+ assert(w > 0.0); assert (w <= PI);
+
+ m = floor(w/model->Wo + 0.5);
+ f = (w - m*model->Wo)/w;
+ assert(f <= 1.0);
+
+ if (m < 1) {
+ log_amp = f*log10(model->A[1]);
+ }
+ else if ((m+1) > model->L) {
+ log_amp = (1.0-f)*log10(model->A[model->L]);
+ }
+ else {
+ log_amp = (1.0-f)*log10(model->A[m]) + f*log10(model->A[m+1]);
+ }
+
+ return log_amp;
+}
+
diff --git a/libs/libcodec2/src/interp.h b/libs/libcodec2/src/interp.h
new file mode 100644
index 0000000000..0684b5bbff
--- /dev/null
+++ b/libs/libcodec2/src/interp.h
@@ -0,0 +1,34 @@
+/*---------------------------------------------------------------------------*\
+
+ FILE........: interp.h
+ AUTHOR......: David Rowe
+ DATE CREATED: 9/10/09
+
+ Interpolation of 20ms frames to 10ms frames.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+ Copyright (C) 2009 David Rowe
+
+ All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License version 2.1, as
+ published by the Free Software Foundation. This program is
+ distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __INTERP__
+#define __INTERP__
+
+void interpolate(MODEL *interp, MODEL *prev, MODEL *next);
+
+#endif
diff --git a/libs/libcodec2/src/listen.sh b/libs/libcodec2/src/listen.sh
new file mode 100644
index 0000000000..bebd106f7a
--- /dev/null
+++ b/libs/libcodec2/src/listen.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+# listensim.sh
+# David Rowe 10 Sep 2009
+#
+# Listen to files processed with sim.sh
+
+../script/menu.sh ../raw/$1.raw $1_uq.raw $1_phase0.raw $1_lpc10.raw $1_lsp.raw $1_phase0_lpc10.raw $1_phase0_lsp.raw $1_phase0_lsp.raw $2 $3
+
+
diff --git a/libs/libcodec2/src/listen1.sh b/libs/libcodec2/src/listen1.sh
new file mode 100755
index 0000000000..a3b72671bc
--- /dev/null
+++ b/libs/libcodec2/src/listen1.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+# listen1.sh
+# David Rowe 10 Sep 2009
+#
+# Run menu with common sample file options, headphone version
+
+#../script/menu.sh ../raw/$1.raw $1_uq.raw $1_phase0.raw $1_lpc10.raw $1_lsp.raw $1_phase0_lpc10.raw $1_phase0_lsp.raw ../raw/$1_g729a.raw $2 $3 -d /dev/dsp1
+
+# compare to other codecs
+
+#../script/menu.sh ../raw/$1.raw $1_phase0_lsp.raw $1_phase0_lsp_20.raw ../raw/$1_g729a.raw ../raw/$1_gsm13k.raw ../raw/$1_speex_8k.raw $2 $3 -d /dev/dsp1
+
+../script/menu.sh ../raw/$1.raw $1_uq.raw $1_phase0.raw $1_test.raw ../raw/$1_g729a.raw $2 $3 -d /dev/dsp1
+
+
diff --git a/libs/libcodec2/src/listensim.sh b/libs/libcodec2/src/listensim.sh
new file mode 100755
index 0000000000..64f7455ab3
--- /dev/null
+++ b/libs/libcodec2/src/listensim.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+# listensim.sh
+# David Rowe 10 Sep 2009
+#
+# Listen to files processed with sim.sh
+
+../script/menu.sh ../raw/$1.raw $1_uq.raw $1_phase0.raw $1_lpc10.raw $1_lsp.raw $1_phase0_lpc10.raw $1_phase0_lsp.raw $1_phase0_lsp_dec.raw $2 $3
+
+
diff --git a/libs/libcodec2/src/lpc.c b/libs/libcodec2/src/lpc.c
new file mode 100644
index 0000000000..1f9ff2bf10
--- /dev/null
+++ b/libs/libcodec2/src/lpc.c
@@ -0,0 +1,253 @@
+/*---------------------------------------------------------------------------*\
+
+ FILE........: lpc.c
+ AUTHOR......: David Rowe
+ DATE CREATED: 30/9/90
+
+ Linear Prediction functions written in C.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+ Copyright (C) 2009 David Rowe
+
+ All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License version 2.1, as
+ published by the Free Software Foundation. This program is
+ distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#define LPC_MAX_N 512 /* maximum no. of samples in frame */
+#define PI 3.141592654 /* mathematical constant */
+
+#include
+#include
+#include "defines.h"
+#include "lpc.h"
+
+/*---------------------------------------------------------------------------*\
+
+ hanning_window()
+
+ Hanning windows a frame of speech samples.
+
+\*---------------------------------------------------------------------------*/
+
+void hanning_window(
+ float Sn[], /* input frame of speech samples */
+ float Wn[], /* output frame of windowed samples */
+ int Nsam /* number of samples */
+)
+{
+ int i; /* loop variable */
+
+ for(i=0; i 1.0)
+ k[i] = 0.0;
+
+ a[i][i] = k[i];
+
+ for(j=1; j<=i-1; j++)
+ a[i][j] = a[i-1][j] + k[i]*a[i-1][i-j]; /* Equation 38c, Makhoul */
+
+ E[i] = (1-k[i]*k[i])*E[i-1]; /* Equation 38d, Makhoul */
+ }
+
+ for(i=1; i<=order; i++)
+ lpcs[i] = a[order][i];
+ lpcs[0] = 1.0;
+}
+
+/*---------------------------------------------------------------------------*\
+
+ inverse_filter()
+
+ Inverse Filter, A(z). Produces an array of residual samples from an array
+ of input samples and linear prediction coefficients.
+
+ The filter memory is stored in the first order samples of the input array.
+
+\*---------------------------------------------------------------------------*/
+
+void inverse_filter(
+ float Sn[], /* Nsam input samples */
+ float a[], /* LPCs for this frame of samples */
+ int Nsam, /* number of samples */
+ float res[], /* Nsam residual samples */
+ int order /* order of LPC */
+)
+{
+ int i,j; /* loop variables */
+
+ for(i=0; i
+#include
+#include
+
+/*---------------------------------------------------------------------------*\
+
+ Introduction to Line Spectrum Pairs (LSPs)
+ ------------------------------------------
+
+ LSPs are used to encode the LPC filter coefficients {ak} for
+ transmission over the channel. LSPs have several properties (like
+ less sensitivity to quantisation noise) that make them superior to
+ direct quantisation of {ak}.
+
+ A(z) is a polynomial of order lpcrdr with {ak} as the coefficients.
+
+ A(z) is transformed to P(z) and Q(z) (using a substitution and some
+ algebra), to obtain something like:
+
+ A(z) = 0.5[P(z)(z+z^-1) + Q(z)(z-z^-1)] (1)
+
+ As you can imagine A(z) has complex zeros all over the z-plane. P(z)
+ and Q(z) have the very neat property of only having zeros _on_ the
+ unit circle. So to find them we take a test point z=exp(jw) and
+ evaluate P (exp(jw)) and Q(exp(jw)) using a grid of points between 0
+ and pi.
+
+ The zeros (roots) of P(z) also happen to alternate, which is why we
+ swap coefficients as we find roots. So the process of finding the
+ LSP frequencies is basically finding the roots of 5th order
+ polynomials.
+
+ The root so P(z) and Q(z) occur in symmetrical pairs at +/-w, hence
+ the name Line Spectrum Pairs (LSPs).
+
+ To convert back to ak we just evaluate (1), "clocking" an impulse
+ thru it lpcrdr times gives us the impulse response of A(z) which is
+ {ak}.
+
+\*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: cheb_poly_eva()
+ AUTHOR......: David Rowe
+ DATE CREATED: 24/2/93
+
+ This function evalutes a series of chebyshev polynomials
+
+ FIXME: performing memory allocation at run time is very inefficient,
+ replace with stack variables of MAX_P size.
+
+\*---------------------------------------------------------------------------*/
+
+
+float cheb_poly_eva(float *coef,float x,int m)
+/* float coef[] coefficients of the polynomial to be evaluated */
+/* float x the point where polynomial is to be evaluated */
+/* int m order of the polynomial */
+{
+ int i;
+ float *T,*t,*u,*v,sum;
+
+ /* Allocate memory for chebyshev series formulation */
+
+ if((T = (float *)malloc((m/2+1)*sizeof(float))) == NULL){
+ fprintf(stderr, "not enough memory to allocate buffer\n");
+ exit(1);
+ }
+
+ /* Initialise pointers */
+
+ t = T; /* T[i-2] */
+ *t++ = 1.0;
+ u = t--; /* T[i-1] */
+ *u++ = x;
+ v = u--; /* T[i] */
+
+ /* Evaluate chebyshev series formulation using iterative approach */
+
+ for(i=2;i<=m/2;i++)
+ *v++ = (2*x)*(*u++) - *t++; /* T[i] = 2*x*T[i-1] - T[i-2] */
+
+ sum=0.0; /* initialise sum to zero */
+ t = T; /* reset pointer */
+
+ /* Evaluate polynomial and return value also free memory space */
+
+ for(i=0;i<=m/2;i++)
+ sum+=coef[(m/2)-i]**t++;
+
+ free(T);
+ return sum;
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: lpc_to_lsp()
+ AUTHOR......: David Rowe
+ DATE CREATED: 24/2/93
+
+ This function converts LPC coefficients to LSP coefficients.
+
+\*---------------------------------------------------------------------------*/
+
+int lpc_to_lsp (float *a, int lpcrdr, float *freq, int nb, float delta)
+/* float *a lpc coefficients */
+/* int lpcrdr order of LPC coefficients (10) */
+/* float *freq LSP frequencies in radians */
+/* int nb number of sub-intervals (4) */
+/* float delta grid spacing interval (0.02) */
+{
+ float psuml,psumr,psumm,temp_xr,xl,xr,xm;
+ float temp_psumr;
+ int i,j,m,flag,k;
+ float *Q; /* ptrs for memory allocation */
+ float *P;
+ float *px; /* ptrs of respective P'(z) & Q'(z) */
+ float *qx;
+ float *p;
+ float *q;
+ float *pt; /* ptr used for cheb_poly_eval()
+ whether P' or Q' */
+ int roots=0; /* number of roots found */
+ flag = 1;
+ m = lpcrdr/2; /* order of P'(z) & Q'(z) polynimials */
+
+ /* Allocate memory space for polynomials */
+
+ Q = (float *) malloc((m+1)*sizeof(float));
+ P = (float *) malloc((m+1)*sizeof(float));
+ if( (P == NULL) || (Q == NULL) ) {
+ fprintf(stderr,"not enough memory to allocate buffer\n");
+ exit(1);
+ }
+
+ /* determine P'(z)'s and Q'(z)'s coefficients where
+ P'(z) = P(z)/(1 + z^(-1)) and Q'(z) = Q(z)/(1-z^(-1)) */
+
+ px = P; /* initilaise ptrs */
+ qx = Q;
+ p = px;
+ q = qx;
+ *px++ = 1.0;
+ *qx++ = 1.0;
+ for(i=1;i<=m;i++){
+ *px++ = a[i]+a[lpcrdr+1-i]-*p++;
+ *qx++ = a[i]-a[lpcrdr+1-i]+*q++;
+ }
+ px = P;
+ qx = Q;
+ for(i=0;i= -1.0)){
+ xr = xl - delta ; /* interval spacing */
+ psumr = cheb_poly_eva(pt,xr,lpcrdr);/* poly(xl-delta_x) */
+ temp_psumr = psumr;
+ temp_xr = xr;
+
+ /* if no sign change increment xr and re-evaluate
+ poly(xr). Repeat til sign change. if a sign change has
+ occurred the interval is bisected and then checked again
+ for a sign change which determines in which interval the
+ zero lies in. If there is no sign change between poly(xm)
+ and poly(xl) set interval between xm and xr else set
+ interval between xl and xr and repeat till root is located
+ within the specified limits */
+
+ if((psumr*psuml)<0.0){
+ roots++;
+
+ psumm=psuml;
+ for(k=0;k<=nb;k++){
+ xm = (xl+xr)/2; /* bisect the interval */
+ psumm=cheb_poly_eva(pt,xm,lpcrdr);
+ if(psumm*psuml>0.){
+ psuml=psumm;
+ xl=xm;
+ }
+ else{
+ psumr=psumm;
+ xr=xm;
+ }
+ }
+
+ /* once zero is found, reset initial interval to xr */
+ freq[j] = (xm);
+ xl = xm;
+ flag = 0; /* reset flag for next search */
+ }
+ else{
+ psuml=temp_psumr;
+ xl=temp_xr;
+ }
+ }
+ }
+ free(P); /* free memory space */
+ free(Q);
+
+ /* convert from x domain to radians */
+
+ for(i=0; i
+#include
+#include
+
+/*---------------------------------------------------------------------------*\
+
+ DEFINES
+
+\*---------------------------------------------------------------------------*/
+
+#define PMAX_M 600 /* maximum NLP analysis window size */
+#define COEFF 0.95 /* notch filter parameter */
+#define PE_FFT_SIZE 512 /* DFT size for pitch estimation */
+#define DEC 5 /* decimation factor */
+#define SAMPLE_RATE 8000
+#define PI 3.141592654 /* mathematical constant */
+#define T 0.1 /* threshold for local minima candidate */
+#define F0_MAX 500
+#define CNLP 0.3 /* post processor constant */
+#define NLP_NTAP 48 /* Decimation LPF order */
+
+/*---------------------------------------------------------------------------*\
+
+ GLOBALS
+
+\*---------------------------------------------------------------------------*/
+
+/* 48 tap 600Hz low pass FIR filter coefficients */
+
+float nlp_fir[] = {
+ -1.0818124e-03,
+ -1.1008344e-03,
+ -9.2768838e-04,
+ -4.2289438e-04,
+ 5.5034190e-04,
+ 2.0029849e-03,
+ 3.7058509e-03,
+ 5.1449415e-03,
+ 5.5924666e-03,
+ 4.3036754e-03,
+ 8.0284511e-04,
+ -4.8204610e-03,
+ -1.1705810e-02,
+ -1.8199275e-02,
+ -2.2065282e-02,
+ -2.0920610e-02,
+ -1.2808831e-02,
+ 3.2204775e-03,
+ 2.6683811e-02,
+ 5.5520624e-02,
+ 8.6305944e-02,
+ 1.1480192e-01,
+ 1.3674206e-01,
+ 1.4867556e-01,
+ 1.4867556e-01,
+ 1.3674206e-01,
+ 1.1480192e-01,
+ 8.6305944e-02,
+ 5.5520624e-02,
+ 2.6683811e-02,
+ 3.2204775e-03,
+ -1.2808831e-02,
+ -2.0920610e-02,
+ -2.2065282e-02,
+ -1.8199275e-02,
+ -1.1705810e-02,
+ -4.8204610e-03,
+ 8.0284511e-04,
+ 4.3036754e-03,
+ 5.5924666e-03,
+ 5.1449415e-03,
+ 3.7058509e-03,
+ 2.0029849e-03,
+ 5.5034190e-04,
+ -4.2289438e-04,
+ -9.2768838e-04,
+ -1.1008344e-03,
+ -1.0818124e-03
+};
+
+typedef struct {
+ float sq[PMAX_M]; /* squared speech samples */
+ float mem_x,mem_y; /* memory for notch filter */
+ float mem_fir[NLP_NTAP]; /* decimation FIR filter memory */
+} NLP;
+
+float post_process_mbe(COMP Fw[], int pmin, int pmax, float gmax);
+float post_process_sub_multiples(COMP Fw[],
+ int pmin, int pmax, float gmax, int gmax_bin,
+ float *prev_Wo);
+
+/*---------------------------------------------------------------------------*\
+
+ nlp_create()
+
+ Initialisation function for NLP pitch estimator.
+
+\*---------------------------------------------------------------------------*/
+
+void *nlp_create()
+{
+ NLP *nlp;
+ int i;
+
+ nlp = (NLP*)malloc(sizeof(NLP));
+ if (nlp == NULL)
+ return NULL;
+
+ for(i=0; isq[i] = 0.0;
+ nlp->mem_x = 0.0;
+ nlp->mem_y = 0.0;
+ for(i=0; imem_fir[i] = 0.0;
+
+ return (void*)nlp;
+}
+
+/*---------------------------------------------------------------------------*\
+
+ nlp_destory()
+
+ Initialisation function for NLP pitch estimator.
+
+\*---------------------------------------------------------------------------*/
+
+void nlp_destroy(void *nlp_state)
+{
+ assert(nlp_state != NULL);
+ free(nlp_state);
+}
+
+/*---------------------------------------------------------------------------*\
+
+ nlp()
+
+ Determines the pitch in samples using the Non Linear Pitch (NLP)
+ algorithm [1]. Returns the fundamental in Hz. Note that the actual
+ pitch estimate is for the centre of the M sample Sn[] vector, not
+ the current N sample input vector. This is (I think) a delay of 2.5
+ frames with N=80 samples. You should align further analysis using
+ this pitch estimate to be centred on the middle of Sn[].
+
+ Two post processors have been tried, the MBE version (as discussed
+ in [1]), and a post processor that checks sub-multiples. Both
+ suffer occasional gross pitch errors (i.e. neither are perfect). In
+ the presence of background noise the sub-multiple algorithm tends
+ towards low F0 which leads to better sounding background noise than
+ the MBE post processor.
+
+ A good way to test and develop the NLP pitch estimator is using the
+ tnlp (codec2/unittest) and the codec2/octave/plnlp.m Octave script.
+
+ A pitch tracker searching a few frames forward and backward in time
+ would be a useful addition.
+
+ References:
+
+ [1] http://www.itr.unisa.edu.au/~steven/thesis/dgr.pdf Chapter 4
+
+\*---------------------------------------------------------------------------*/
+
+float nlp(
+ void *nlp_state,
+ float Sn[], /* input speech vector */
+ int n, /* frames shift (no. new samples in Sn[]) */
+ int m, /* analysis window size */
+ int pmin, /* minimum pitch value */
+ int pmax, /* maximum pitch value */
+ float *pitch, /* estimated pitch period in samples */
+ COMP Sw[], /* Freq domain version of Sn[] */
+ float *prev_Wo
+)
+{
+ NLP *nlp;
+ float notch; /* current notch filter output */
+ COMP Fw[PE_FFT_SIZE]; /* DFT of squared signal */
+ float gmax;
+ int gmax_bin;
+ int i,j;
+ float best_f0;
+
+ assert(nlp_state != NULL);
+ nlp = (NLP*)nlp_state;
+
+ /* Square, notch filter at DC, and LP filter vector */
+
+ for(i=m-n; isq[i] = Sn[i]*Sn[i];
+
+ for(i=m-n; isq[i] - nlp->mem_x;
+ notch += COEFF*nlp->mem_y;
+ nlp->mem_x = nlp->sq[i];
+ nlp->mem_y = notch;
+ nlp->sq[i] = notch;
+ }
+
+ for(i=m-n; imem_fir[j] = nlp->mem_fir[j+1];
+ nlp->mem_fir[NLP_NTAP-1] = nlp->sq[i];
+
+ nlp->sq[i] = 0.0;
+ for(j=0; jsq[i] += nlp->mem_fir[j]*nlp_fir[j];
+ }
+
+ /* Decimate and DFT */
+
+ for(i=0; isq[i*DEC]*(0.5 - 0.5*cos(2*PI*i/(m/DEC-1)));
+ }
+ dump_dec(Fw);
+ four1(&Fw[-1].imag,PE_FFT_SIZE,1);
+ for(i=0; isq);
+ dump_Fw(Fw);
+
+ /* find global peak */
+
+ gmax = 0.0;
+ gmax_bin = PE_FFT_SIZE*DEC/pmax;
+ for(i=PE_FFT_SIZE*DEC/pmax; i<=PE_FFT_SIZE*DEC/pmin; i++) {
+ if (Fw[i].real > gmax) {
+ gmax = Fw[i].real;
+ gmax_bin = i;
+ }
+ }
+
+ best_f0 = post_process_sub_multiples(Fw, pmin, pmax, gmax, gmax_bin,
+ prev_Wo);
+
+ /* Shift samples in buffer to make room for new samples */
+
+ for(i=0; isq[i] = nlp->sq[i+n];
+
+ /* return pitch and F0 estimate */
+
+ *pitch = (float)SAMPLE_RATE/best_f0;
+ return(best_f0);
+}
+
+/*---------------------------------------------------------------------------*\
+
+ post_process_sub_multiples()
+
+ Given the global maximma of Fw[] we search interger submultiples for
+ local maxima. If local maxima exist and they are above an
+ experimentally derived threshold (OK a magic number I pulled out of
+ the air) we choose the submultiple as the F0 estimate.
+
+ The rational for this is that the lowest frequency peak of Fw[]
+ should be F0, as Fw[] can be considered the autocorrelation function
+ of Sw[] (the speech spectrum). However sometimes due to phase
+ effects the lowest frequency maxima may not be the global maxima.
+
+ This works OK in practice and favours low F0 values in the presence
+ of background noise which means the sinusoidal codec does an OK job
+ of synthesising the background noise. High F0 in background noise
+ tends to sound more periodic introducing annoying artifacts.
+
+\*---------------------------------------------------------------------------*/
+
+float post_process_sub_multiples(COMP Fw[],
+ int pmin, int pmax, float gmax, int gmax_bin,
+ float *prev_Wo)
+{
+ int min_bin, cmax_bin;
+ int mult;
+ float thresh, best_f0;
+ int b, bmin, bmax, lmax_bin;
+ float lmax, cmax;
+ int prev_f0_bin;
+
+ /* post process estimate by searching submultiples */
+
+ mult = 2;
+ min_bin = PE_FFT_SIZE*DEC/pmax;
+ cmax_bin = gmax_bin;
+ prev_f0_bin = *prev_Wo*(4000.0/PI)*(PE_FFT_SIZE*DEC)/SAMPLE_RATE;
+
+ while(gmax_bin/mult >= min_bin) {
+
+ b = gmax_bin/mult; /* determine search interval */
+ bmin = 0.8*b;
+ bmax = 1.2*b;
+ if (bmin < min_bin)
+ bmin = min_bin;
+
+ /* lower threshold to favour previous frames pitch estimate,
+ this is a form of pitch tracking */
+
+ if ((prev_f0_bin > bmin) && (prev_f0_bin < bmax))
+ thresh = CNLP*0.5*gmax;
+ else
+ thresh = CNLP*gmax;
+
+ lmax = 0;
+ lmax_bin = bmin;
+ for (b=bmin; b<=bmax; b++) /* look for maximum in interval */
+ if (Fw[b].real > lmax) {
+ lmax = Fw[b].real;
+ lmax_bin = b;
+ }
+
+ if (lmax > thresh)
+ if ((lmax > Fw[lmax_bin-1].real) && (lmax > Fw[lmax_bin+1].real)) {
+ cmax = lmax;
+ cmax_bin = lmax_bin;
+ }
+
+ mult++;
+ }
+
+ best_f0 = (float)cmax_bin*SAMPLE_RATE/(PE_FFT_SIZE*DEC);
+
+ return best_f0;
+}
+
diff --git a/libs/libcodec2/src/nlp.h b/libs/libcodec2/src/nlp.h
new file mode 100644
index 0000000000..eaaae97052
--- /dev/null
+++ b/libs/libcodec2/src/nlp.h
@@ -0,0 +1,38 @@
+/*---------------------------------------------------------------------------*\
+
+ FILE........: nlp.c
+ AUTHOR......: David Rowe
+ DATE CREATED: 23/3/93
+
+ Non Linear Pitch (NLP) estimation functions.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+ Copyright (C) 2009 David Rowe
+
+ All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License version 2.1, as
+ published by the Free Software Foundation. This program is
+ distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __NLP__
+#define __NLP__
+
+void *nlp_create();
+void nlp_destroy(void *nlp_state);
+float nlp(void *nlp_state, float Sn[], int n, int m, int pmin, int pmax,
+ float *pitch, COMP Sw[], float *prev_Wo);
+float test_candidate_mbe(COMP Sw[], float f0, COMP Sw_[]);
+
+#endif
diff --git a/libs/libcodec2/src/pack.c b/libs/libcodec2/src/pack.c
new file mode 100644
index 0000000000..2cbff4438a
--- /dev/null
+++ b/libs/libcodec2/src/pack.c
@@ -0,0 +1,104 @@
+/*
+ Copyright (C) 2010 Perens LLC
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ */
+#include "defines.h"
+#include "quantise.h"
+#include
+
+/* Compile-time constants */
+/* Size of unsigned char in bits. Assumes 8 bits-per-char. */
+static const unsigned int WordSize = 8;
+
+/* Mask to pick the bit component out of bitIndex. */
+static const unsigned int IndexMask = 0x7;
+
+/* Used to pick the word component out of bitIndex. */
+static const unsigned int ShiftRight = 3;
+
+/** Pack a bit field into a bit string, encoding the field in Gray code.
+ *
+ * The output is an array of unsigned char data. The fields are efficiently
+ * packed into the bit string. The Gray coding is a naive attempt to reduce
+ * the effect of single-bit errors, we expect to do a better job as the
+ * codec develops.
+ *
+ * This code would be simpler if it just set one bit at a time in the string,
+ * but would hit the same cache line more often. I'm not sure the complexity
+ * gains us anything here.
+ *
+ * Although field is currently of int type rather than unsigned for
+ * compatibility with the rest of the code, indices are always expected to
+ * be >= 0.
+ */
+void
+pack(
+ unsigned char * bitArray, /* The output bit string. */
+ unsigned int * bitIndex, /* Index into the string in BITS, not bytes.*/
+ int field, /* The bit field to be packed. */
+ unsigned int fieldWidth/* Width of the field in BITS, not bytes. */
+ )
+{
+ /* Convert the field to Gray code */
+ field = (field >> 1) ^ field;
+
+ do {
+ unsigned int bI = *bitIndex;
+ unsigned int bitsLeft = WordSize - (bI & IndexMask);
+ unsigned int sliceWidth =
+ bitsLeft < fieldWidth ? bitsLeft : fieldWidth;
+ unsigned int wordIndex = bI >> ShiftRight;
+
+ bitArray[wordIndex] |=
+ ((unsigned char)((field >> (fieldWidth - sliceWidth))
+ << (bitsLeft - sliceWidth)));
+
+ *bitIndex = bI + sliceWidth;
+ fieldWidth -= sliceWidth;
+ } while ( fieldWidth != 0 );
+}
+
+/** Unpack a field from a bit string, converting from Gray code to binary.
+ *
+ */
+int
+unpack(
+ const unsigned char * bitArray, /* The input bit string. */
+ unsigned int * bitIndex, /* Index into the string in BITS, not bytes.*/
+ unsigned int fieldWidth/* Width of the field in BITS, not bytes. */
+ )
+{
+ unsigned int field = 0;
+
+ do {
+ unsigned int bI = *bitIndex;
+ unsigned int bitsLeft = WordSize - (bI & IndexMask);
+ unsigned int sliceWidth =
+ bitsLeft < fieldWidth ? bitsLeft : fieldWidth;
+
+ field |= (((bitArray[bI >> ShiftRight] >> (bitsLeft - sliceWidth)) & ((1 << sliceWidth) - 1)) << (fieldWidth - sliceWidth));
+
+ *bitIndex = bI + sliceWidth;
+ fieldWidth -= sliceWidth;
+ } while ( fieldWidth != 0 );
+
+ /* Convert from Gray code to binary. Works for maximum 8-bit fields. */
+ unsigned int t = field ^ (field >> 8);
+ t ^= (t >> 4);
+ t ^= (t >> 2);
+ t ^= (t >> 1);
+ return t;
+}
diff --git a/libs/libcodec2/src/phase.c b/libs/libcodec2/src/phase.c
new file mode 100644
index 0000000000..83fd680e79
--- /dev/null
+++ b/libs/libcodec2/src/phase.c
@@ -0,0 +1,254 @@
+/*---------------------------------------------------------------------------*\
+
+ FILE........: phase.c
+ AUTHOR......: David Rowe
+ DATE CREATED: 1/2/09
+
+ Functions for modelling and synthesising phase.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+ Copyright (C) 2009 David Rowe
+
+ All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License version 2.1, as
+ published by the Free Software Foundation. This program is
+ distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "defines.h"
+#include "phase.h"
+#include "four1.h"
+
+#include
+#include
+#include
+#include
+
+#define VTHRESH 4.0
+
+/*---------------------------------------------------------------------------*\
+
+ aks_to_H()
+
+ Samples the complex LPC synthesis filter spectrum at the harmonic
+ frequencies.
+
+\*---------------------------------------------------------------------------*/
+
+void aks_to_H(
+ MODEL *model, /* model parameters */
+ float aks[], /* LPC's */
+ float G, /* energy term */
+ COMP H[], /* complex LPC spectral samples */
+ int order
+)
+{
+ COMP Pw[FFT_DEC]; /* power spectrum */
+ int i,m; /* loop variables */
+ int am,bm; /* limits of current band */
+ float r; /* no. rads/bin */
+ float Em; /* energy in band */
+ float Am; /* spectral amplitude sample */
+ int b; /* centre bin of harmonic */
+ float phi_; /* phase of LPC spectra */
+
+ r = TWO_PI/(FFT_DEC);
+
+ /* Determine DFT of A(exp(jw)) ------------------------------------------*/
+
+ for(i=0; iL; m++) {
+ am = floor((m - 0.5)*model->Wo/r + 0.5);
+ bm = floor((m + 0.5)*model->Wo/r + 0.5);
+ b = floor(m*model->Wo/r + 0.5);
+
+ Em = 0.0;
+ for(i=am; iWo)*N/2;
+ */
+
+ ex_phase[0] += (model->Wo)*N;
+ ex_phase[0] -= TWO_PI*floor(ex_phase[0]/TWO_PI + 0.5);
+
+ for(m=1; m<=model->L; m++) {
+
+ /* generate excitation */
+
+ if (model->voiced) {
+ /* This method of adding jitter really helped remove the clicky
+ sound in low pitched makes like hts1a. This moves the onset
+ of each harmonic over at +/- 0.25 of a sample.
+ */
+ jitter = 0.25*(1.0 - 2.0*rand()/RAND_MAX);
+ Ex[m].real = cos(ex_phase[0]*m - jitter*model->Wo*m);
+ Ex[m].imag = sin(ex_phase[0]*m - jitter*model->Wo*m);
+ }
+ else {
+
+ /* When a few samples were tested I found that LPC filter
+ phase is not needed in the unvoiced case, but no harm in
+ keeping it.
+ */
+ float phi = TWO_PI*(float)rand()/RAND_MAX;
+ Ex[m].real = cos(phi);
+ Ex[m].imag = sin(phi);
+ }
+
+ /* filter using LPC filter */
+
+ A_[m].real = H[m].real*Ex[m].real - H[m].imag*Ex[m].imag;
+ A_[m].imag = H[m].imag*Ex[m].real + H[m].real*Ex[m].imag;
+
+ /* modify sinusoidal phase */
+
+ new_phi = atan2(A_[m].imag, A_[m].real+1E-12);
+ model->phi[m] = new_phi;
+ }
+
+}
diff --git a/libs/libcodec2/src/phase.h b/libs/libcodec2/src/phase.h
new file mode 100644
index 0000000000..6dbf3fa2d6
--- /dev/null
+++ b/libs/libcodec2/src/phase.h
@@ -0,0 +1,34 @@
+/*---------------------------------------------------------------------------*\
+
+ FILE........: phase.h
+ AUTHOR......: David Rowe
+ DATE CREATED: 1/2/09
+
+ Functions for modelling phase.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+ Copyright (C) 2009 David Rowe
+
+ All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License version 2.1, as
+ published by the Free Software Foundation. This program is
+ distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __PHASE__
+#define __PHASE__
+
+void phase_synth_zero_order(MODEL *model, float aks[], float *ex_phase);
+
+#endif
diff --git a/libs/libcodec2/src/postfilter.c b/libs/libcodec2/src/postfilter.c
new file mode 100644
index 0000000000..6dad76b1e1
--- /dev/null
+++ b/libs/libcodec2/src/postfilter.c
@@ -0,0 +1,131 @@
+/*---------------------------------------------------------------------------*\
+
+ FILE........: postfilter.c
+ AUTHOR......: David Rowe
+ DATE CREATED: 13/09/09
+
+ Postfilter to improve sound quality for speech with high levels of
+ background noise. Unlike mixed-excitation models requires no bits
+ to be transmitted to handle background noise.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+ Copyright (C) 2009 David Rowe
+
+ All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License version 2.1, as
+ published by the Free Software Foundation. This program is
+ distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include
+#include
+#include
+
+#include "defines.h"
+#include "dump.h"
+#include "postfilter.h"
+
+/*---------------------------------------------------------------------------*\
+
+ DEFINES
+
+\*---------------------------------------------------------------------------*/
+
+#define BG_THRESH 40.0 /* only consider low levels signals for bg_est */
+#define BG_BETA 0.1 /* averaging filter constant */
+
+/*---------------------------------------------------------------------------*\
+
+ postfilter()
+
+ The post filter is designed to help with speech corrupted by
+ background noise. The zero phase model tends to make speech with
+ background noise sound "clicky". With high levels of background
+ noise the low level inter-formant parts of the spectrum will contain
+ noise rather than speech harmonics, so modelling them as voiced
+ (i.e. a continuous, non-random phase track) is inaccurate.
+
+ Some codecs (like MBE) have a mixed voicing model that breaks the
+ spectrum into voiced and unvoiced regions. Several bits/frame
+ (5-12) are required to transmit the frequency selective voicing
+ information. Mixed excitation also requires accurate voicing
+ estimation (parameter estimators always break occasionally under
+ exceptional condition).
+
+ In our case we use a post filter approach which requires no
+ additional bits to be transmitted. The decoder measures the average
+ level of the background noise during unvoiced frames. If a harmonic
+ is less than this level it is made unvoiced by randomising it's
+ phases.
+
+ This idea is rather experimental. Some potential problems that may
+ happen:
+
+ 1/ If someone says "aaaaaaaahhhhhhhhh" will background estimator track
+ up to speech level? This would be a bad thing.
+
+ 2/ If background noise suddenly dissapears from the source speech does
+ estimate drop quickly? What is noise suddenly re-appears?
+
+ 3/ Background noise with a non-flat sepctrum. Current algorithm just
+ comsiders scpetrum as a whole, but this could be broken up into
+ bands, each with their own estimator.
+
+ 4/ Males and females with the same level of background noise. Check
+ performance the same. Changing Wo affects width of each band, may
+ affect bg energy estimates.
+
+ 5/ Not sure what happens during long periods of voiced speech
+ e.g. "sshhhhhhh"
+
+\*---------------------------------------------------------------------------*/
+
+void postfilter(
+ MODEL *model,
+ float *bg_est
+)
+{
+ int m, uv;
+ float e;
+
+ /* determine average energy across spectrum */
+
+ e = 0.0;
+ for(m=1; m<=model->L; m++)
+ e += model->A[m]*model->A[m];
+
+ e = 10.0*log10(e/model->L);
+
+ /* If beneath threhold, update bg estimate. The idea
+ of the threshold is to prevent updating during high level
+ speech. */
+
+ if ((e < BG_THRESH) && !model->voiced)
+ *bg_est = *bg_est*(1.0 - BG_BETA) + e*BG_BETA;
+
+ /* now mess with phases during voiced frames to make any harmonics
+ less then our background estimate unvoiced.
+ */
+
+ uv = 0;
+ if (model->voiced)
+ for(m=1; m<=model->L; m++)
+ if (20.0*log10(model->A[m]) < *bg_est) {
+ model->phi[m] = TWO_PI*(float)rand()/RAND_MAX;
+ uv++;
+ }
+
+ dump_bg(e, *bg_est, 100.0*uv/model->L);
+
+}
diff --git a/libs/libcodec2/src/postfilter.h b/libs/libcodec2/src/postfilter.h
new file mode 100644
index 0000000000..d4dd4ae053
--- /dev/null
+++ b/libs/libcodec2/src/postfilter.h
@@ -0,0 +1,34 @@
+/*---------------------------------------------------------------------------*\
+
+ FILE........: postfilter.h
+ AUTHOR......: David Rowe
+ DATE CREATED: 13/09/09
+
+ Postfilter header file.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+ Copyright (C) 2009 David Rowe
+
+ All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License version 2.1, as
+ published by the Free Software Foundation. This program is
+ distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __POSTFILTER__
+#define __POSTFILTER__
+
+void postfilter(MODEL *model, float *bg_est);
+
+#endif
diff --git a/libs/libcodec2/src/quantise.c b/libs/libcodec2/src/quantise.c
new file mode 100644
index 0000000000..a1cd728112
--- /dev/null
+++ b/libs/libcodec2/src/quantise.c
@@ -0,0 +1,868 @@
+/*---------------------------------------------------------------------------*\
+
+ FILE........: quantise.c
+ AUTHOR......: David Rowe
+ DATE CREATED: 31/5/92
+
+ Quantisation functions for the sinusoidal coder.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+ All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License version 2.1, as
+ published by the Free Software Foundation. This program is
+ distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "defines.h"
+#include "dump.h"
+#include "quantise.h"
+#include "lpc.h"
+#include "lsp.h"
+#include "four1.h"
+#include "codebook.h"
+
+#define LSP_DELTA1 0.01 /* grid spacing for LSP root searches */
+#define MAX_CB 20 /* max number of codebooks */
+
+/* describes each codebook */
+
+typedef struct {
+ int k; /* dimension of vector */
+ int log2m; /* number of bits in m */
+ int m; /* elements in codebook */
+ float *fn; /* file name of text file storing the VQ */
+} LSP_CB;
+
+/* lsp_q describes entire quantiser made up of several codebooks */
+
+#ifdef OLDER
+/* 10+10+6+6 = 32 bit LSP difference split VQ */
+
+LSP_CB lsp_q[] = {
+ {3, 1024, "/usr/src/freeswitch/libs/libcodec2-1.0/unittest/lspd123.txt"},
+ {3, 1024, "/usr/src/freeswitch/libs/libcodec2-1.0/unittest/lspd456.txt"},
+ {2, 64, "/usr/src/freeswitch/libs/libcodec2-1.0/unittest/lspd78.txt"},
+ {2, 64, "/usr/src/freeswitch/libs/libcodec2-1.0/unittest/lspd910.txt"},
+ {0, 0, ""}
+};
+#endif
+
+LSP_CB lsp_q[] = {
+ {1,4,16, codebook_lsp1 },
+ {1,4,16, codebook_lsp2 },
+ {1,4,16, codebook_lsp3 },
+ {1,4,16, codebook_lsp4 },
+ {1,4,16, codebook_lsp5 },
+ {1,4,16, codebook_lsp6 },
+ {1,4,16, codebook_lsp7 },
+ {1,3,8, codebook_lsp8 },
+ {1,3,8, codebook_lsp9 },
+ {1,2,4, codebook_lsp10 },
+ {0,0,0, NULL },
+};
+
+/* ptr to each codebook */
+
+static float *plsp_cb[MAX_CB];
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION HEADERS
+
+\*---------------------------------------------------------------------------*/
+
+float speech_to_uq_lsps(float lsp[], float ak[], float Sn[], float w[],
+ int order);
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTIONS
+
+\*---------------------------------------------------------------------------*/
+
+int lsp_bits(int i) {
+ return lsp_q[i].log2m;
+}
+
+/*---------------------------------------------------------------------------*\
+
+ quantise_uniform
+
+ Simulates uniform quantising of a float.
+
+\*---------------------------------------------------------------------------*/
+
+void quantise_uniform(float *val, float min, float max, int bits)
+{
+ int levels = 1 << (bits-1);
+ float norm;
+ int index;
+
+ /* hard limit to quantiser range */
+
+ printf("min: %f max: %f val: %f ", min, max, val[0]);
+ if (val[0] < min) val[0] = min;
+ if (val[0] > max) val[0] = max;
+
+ norm = (*val - min)/(max-min);
+ printf("%f norm: %f ", val[0], norm);
+ index = fabs(levels*norm + 0.5);
+
+ *val = min + index*(max-min)/levels;
+
+ printf("index %d val_: %f\n", index, val[0]);
+}
+
+/*---------------------------------------------------------------------------*\
+
+ lspd_quantise
+
+ Simulates differential lsp quantiser
+
+\*---------------------------------------------------------------------------*/
+
+void lsp_quantise(
+ float lsp[],
+ float lsp_[],
+ int order
+)
+{
+ int i;
+ float dlsp[LPC_MAX];
+ float dlsp_[LPC_MAX];
+
+ dlsp[0] = lsp[0];
+ for(i=1; i {Am} LPC decode */
+
+ return snr;
+}
+
+/*---------------------------------------------------------------------------*\
+
+ aks_to_M2()
+
+ Transforms the linear prediction coefficients to spectral amplitude
+ samples. This function determines A(m) from the average energy per
+ band using an FFT.
+
+\*---------------------------------------------------------------------------*/
+
+void aks_to_M2(
+ float ak[], /* LPC's */
+ int order,
+ MODEL *model, /* sinusoidal model parameters for this frame */
+ float E, /* energy term */
+ float *snr, /* signal to noise ratio for this frame in dB */
+ int dump /* true to dump sample to dump file */
+)
+{
+ COMP Pw[FFT_DEC]; /* power spectrum */
+ int i,m; /* loop variables */
+ int am,bm; /* limits of current band */
+ float r; /* no. rads/bin */
+ float Em; /* energy in band */
+ float Am; /* spectral amplitude sample */
+ float signal, noise;
+
+ r = TWO_PI/(FFT_DEC);
+
+ /* Determine DFT of A(exp(jw)) --------------------------------------------*/
+
+ for(i=0; iL; m++) {
+ am = floor((m - 0.5)*model->Wo/r + 0.5);
+ bm = floor((m + 0.5)*model->Wo/r + 0.5);
+ Em = 0.0;
+
+ for(i=am; iA[m],2.0);
+ noise += pow(model->A[m] - Am,2.0);
+ model->A[m] = Am;
+ }
+ *snr = 10.0*log10(signal/noise);
+}
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: encode_Wo()
+ AUTHOR......: David Rowe
+ DATE CREATED: 22/8/2010
+
+ Encodes Wo using a WO_LEVELS quantiser.
+
+\*---------------------------------------------------------------------------*/
+
+int encode_Wo(float Wo)
+{
+ int index;
+ float Wo_min = TWO_PI/P_MAX;
+ float Wo_max = TWO_PI/P_MIN;
+ float norm;
+
+ norm = (Wo - Wo_min)/(Wo_max - Wo_min);
+ index = floor(WO_LEVELS * norm + 0.5);
+ if (index < 0 ) index = 0;
+ if (index > (WO_LEVELS-1)) index = WO_LEVELS-1;
+
+ return index;
+}
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: decode_Wo()
+ AUTHOR......: David Rowe
+ DATE CREATED: 22/8/2010
+
+ Decodes Wo using a WO_LEVELS quantiser.
+
+\*---------------------------------------------------------------------------*/
+
+float decode_Wo(int index)
+{
+ float Wo_min = TWO_PI/P_MAX;
+ float Wo_max = TWO_PI/P_MIN;
+ float step;
+ float Wo;
+
+ step = (Wo_max - Wo_min)/WO_LEVELS;
+ Wo = Wo_min + step*(index);
+
+ return Wo;
+}
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: speech_to_uq_lsps()
+ AUTHOR......: David Rowe
+ DATE CREATED: 22/8/2010
+
+ Analyse a windowed frame of time domain speech to determine LPCs
+ which are the converted to LSPs for quantisation and transmission
+ over the channel.
+
+\*---------------------------------------------------------------------------*/
+
+float speech_to_uq_lsps(float lsp[],
+ float ak[],
+ float Sn[],
+ float w[],
+ int order
+)
+{
+ int i, roots;
+ float Wn[M];
+ float R[LPC_MAX+1];
+ float E;
+
+ for(i=0; iA[1]) - 20.0*log10(tmp.A[1]));
+ if (E1 > 6.0)
+ return 1;
+ else
+ return 0;
+}
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: apply_lpc_correction()
+ AUTHOR......: David Rowe
+ DATE CREATED: 22/8/2010
+
+ Apply first harmonic LPC correction at decoder.
+
+\*---------------------------------------------------------------------------*/
+
+void apply_lpc_correction(MODEL *model, int lpc_correction)
+{
+ if (lpc_correction) {
+ if (model->Wo < (PI*150.0/4000)) {
+ model->A[1] *= 0.032;
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: encode_energy()
+ AUTHOR......: David Rowe
+ DATE CREATED: 22/8/2010
+
+ Encodes LPC energy using an E_LEVELS quantiser.
+
+\*---------------------------------------------------------------------------*/
+
+int encode_energy(float e)
+{
+ int index;
+ float e_min = E_MIN_DB;
+ float e_max = E_MAX_DB;
+ float norm;
+
+ e = 10.0*log10(e);
+ norm = (e - e_min)/(e_max - e_min);
+ index = floor(E_LEVELS * norm + 0.5);
+ if (index < 0 ) index = 0;
+ if (index > (E_LEVELS-1)) index = E_LEVELS-1;
+
+ return index;
+}
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: decode_energy()
+ AUTHOR......: David Rowe
+ DATE CREATED: 22/8/2010
+
+ Decodes energy using a WO_BITS quantiser.
+
+\*---------------------------------------------------------------------------*/
+
+float decode_energy(int index)
+{
+ float e_min = E_MIN_DB;
+ float e_max = E_MAX_DB;
+ float step;
+ float e;
+
+ step = (e_max - e_min)/E_LEVELS;
+ e = e_min + step*(index);
+ e = pow(10.0,e/10.0);
+
+ return e;
+}
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: encode_amplitudes()
+ AUTHOR......: David Rowe
+ DATE CREATED: 22/8/2010
+
+ Time domain LPC is used model the amplitudes which are then
+ converted to LSPs and quantised. So we don't actually encode the
+ amplitudes directly, rather we derive an equivalent representation
+ from the time domain speech.
+
+\*---------------------------------------------------------------------------*/
+
+void encode_amplitudes(int lsp_indexes[],
+ int *lpc_correction,
+ int *energy_index,
+ MODEL *model,
+ float Sn[],
+ float w[])
+{
+ float lsps[LPC_ORD];
+ float ak[LPC_ORD+1];
+ float e;
+
+ e = speech_to_uq_lsps(lsps, ak, Sn, w, LPC_ORD);
+ encode_lsps(lsp_indexes, lsps, LPC_ORD);
+ *lpc_correction = need_lpc_correction(model, ak, e);
+ *energy_index = encode_energy(e);
+}
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: decode_amplitudes()
+ AUTHOR......: David Rowe
+ DATE CREATED: 22/8/2010
+
+ Given the amplitude quantiser indexes recovers the harmonic
+ amplitudes.
+
+\*---------------------------------------------------------------------------*/
+
+float decode_amplitudes(MODEL *model,
+ float ak[],
+ int lsp_indexes[],
+ int lpc_correction,
+ int energy_index
+)
+{
+ float lsps[LPC_ORD];
+ float e;
+ float snr;
+
+ decode_lsps(lsps, lsp_indexes, LPC_ORD);
+ bw_expand_lsps(lsps, LPC_ORD);
+ lsp_to_lpc(lsps, ak, LPC_ORD);
+ e = decode_energy(energy_index);
+ aks_to_M2(ak, LPC_ORD, model, e, &snr, 1);
+ apply_lpc_correction(model, lpc_correction);
+
+ return snr;
+}
diff --git a/libs/libcodec2/src/quantise.h b/libs/libcodec2/src/quantise.h
new file mode 100644
index 0000000000..ded7645381
--- /dev/null
+++ b/libs/libcodec2/src/quantise.h
@@ -0,0 +1,84 @@
+/*---------------------------------------------------------------------------*\
+
+ FILE........: quantise.h
+ AUTHOR......: David Rowe
+ DATE CREATED: 31/5/92
+
+ Quantisation functions for the sinusoidal coder.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+ All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License version 2.1, as
+ published by the Free Software Foundation. This program is
+ distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __QUANTISE__
+#define __QUANTISE__
+
+#define WO_BITS 7
+#define WO_LEVELS (1<
+#include
+#include
+
+#include "defines.h"
+#include "sine.h"
+#include "four1.h"
+
+/*---------------------------------------------------------------------------*\
+
+ HEADERS
+
+\*---------------------------------------------------------------------------*/
+
+void hs_pitch_refinement(MODEL *model, COMP Sw[], float pmin, float pmax,
+ float pstep);
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTIONS
+
+\*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: make_analysis_window
+ AUTHOR......: David Rowe
+ DATE CREATED: 11/5/94
+
+ Init function that generates the time domain analysis window and it's DFT.
+
+\*---------------------------------------------------------------------------*/
+
+void make_analysis_window(float w[],COMP W[])
+{
+ float m;
+ COMP temp;
+ int i,j;
+
+ /*
+ Generate Hamming window centered on M-sample pitch analysis window
+
+ 0 M/2 M-1
+ |-------------|-------------|
+ |-------|-------|
+ NW samples
+
+ All our analysis/synthsis is centred on the M/2 sample.
+ */
+
+ m = 0.0;
+ for(i=0; iWo + 5;
+ pmin = TWO_PI/model->Wo - 5;
+ pstep = 1.0;
+ hs_pitch_refinement(model,Sw,pmin,pmax,pstep);
+
+ /* Fine refinement */
+
+ pmax = TWO_PI/model->Wo + 1;
+ pmin = TWO_PI/model->Wo - 1;
+ pstep = 0.25;
+ hs_pitch_refinement(model,Sw,pmin,pmax,pstep);
+
+ /* Limit range */
+
+ if (model->Wo < TWO_PI/P_MAX)
+ model->Wo = TWO_PI/P_MAX;
+ if (model->Wo > TWO_PI/P_MIN)
+ model->Wo = TWO_PI/P_MIN;
+
+ model->L = floor(PI/model->Wo);
+}
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: hs_pitch_refinement
+ AUTHOR......: David Rowe
+ DATE CREATED: 27/5/94
+
+ Harmonic sum pitch refinement function.
+
+ pmin pitch search range minimum
+ pmax pitch search range maximum
+ step pitch search step size
+ model current pitch estimate in model.Wo
+
+ model refined pitch estimate in model.Wo
+
+\*---------------------------------------------------------------------------*/
+
+void hs_pitch_refinement(MODEL *model, COMP Sw[], float pmin, float pmax, float pstep)
+{
+ int m; /* loop variable */
+ int b; /* bin for current harmonic centre */
+ float E; /* energy for current pitch*/
+ float Wo; /* current "test" fundamental freq. */
+ float Wom; /* Wo that maximises E */
+ float Em; /* mamimum energy */
+ float r; /* number of rads/bin */
+ float p; /* current pitch */
+
+ /* Initialisation */
+
+ model->L = PI/model->Wo; /* use initial pitch est. for L */
+ Wom = model->Wo;
+ Em = 0.0;
+ r = TWO_PI/FFT_ENC;
+
+ /* Determine harmonic sum for a range of Wo values */
+
+ for(p=pmin; p<=pmax; p+=pstep) {
+ E = 0.0;
+ Wo = TWO_PI/p;
+
+ /* Sum harmonic magnitudes */
+
+ for(m=1; m<=model->L; m++) {
+ b = floor(m*Wo/r + 0.5);
+ E += Sw[b].real*Sw[b].real + Sw[b].imag*Sw[b].imag;
+ }
+
+ /* Compare to see if this is a maximum */
+
+ if (E > Em) {
+ Em = E;
+ Wom = Wo;
+ }
+ }
+
+ model->Wo = Wom;
+}
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: estimate_amplitudes
+ AUTHOR......: David Rowe
+ DATE CREATED: 27/5/94
+
+ Estimates the complex amplitudes of the harmonics.
+
+\*---------------------------------------------------------------------------*/
+
+void estimate_amplitudes(MODEL *model, COMP Sw[], COMP W[])
+{
+ int i,m; /* loop variables */
+ int am,bm; /* bounds of current harmonic */
+ int b; /* DFT bin of centre of current harmonic */
+ float den; /* denominator of amplitude expression */
+ float r; /* number of rads/bin */
+ int offset;
+ COMP Am;
+
+ r = TWO_PI/FFT_ENC;
+
+ for(m=1; m<=model->L; m++) {
+ den = 0.0;
+ am = floor((m - 0.5)*model->Wo/r + 0.5);
+ bm = floor((m + 0.5)*model->Wo/r + 0.5);
+ b = floor(m*model->Wo/r + 0.5);
+
+ /* Estimate ampltude of harmonic */
+
+ den = 0.0;
+ Am.real = Am.imag = 0.0;
+ for(i=am; iWo/r + 0.5);
+ Am.real += Sw[i].real*W[offset].real;
+ Am.imag += Sw[i].imag*W[offset].real;
+ }
+
+ model->A[m] = sqrt(den);
+
+ /* Estimate phase of harmonic */
+
+ model->phi[m] = atan2(Sw[b].imag,Sw[b].real);
+ }
+}
+
+/*---------------------------------------------------------------------------*\
+
+ est_voicing_mbe()
+
+ Returns the error of the MBE cost function for a fiven F0.
+
+ Note: I think a lot of the operations below can be simplified as
+ W[].imag = 0 and has been normalised such that den always equals 1.
+
+\*---------------------------------------------------------------------------*/
+
+float est_voicing_mbe(
+ MODEL *model,
+ COMP Sw[],
+ COMP W[],
+ float f0,
+ COMP Sw_[] /* DFT of all voiced synthesised signal for f0 */
+ /* useful for debugging/dump file */
+)
+{
+ int i,l,al,bl,m; /* loop variables */
+ COMP Am; /* amplitude sample for this band */
+ int offset; /* centers Hw[] about current harmonic */
+ float den; /* denominator of Am expression */
+ float error; /* accumulated error between originl and synthesised */
+ float Wo; /* current "test" fundamental freq. */
+ int L;
+ float sig, snr;
+
+ sig = 0.0;
+ for(l=1; l<=model->L/4; l++) {
+ sig += model->A[l]*model->A[l];
+ }
+
+ for(i=0; i V_THRESH)
+ model->voiced = 1;
+ else
+ model->voiced = 0;
+
+ return snr;
+}
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: make_synthesis_window
+ AUTHOR......: David Rowe
+ DATE CREATED: 11/5/94
+
+ Init function that generates the trapezoidal (Parzen) sythesis window.
+
+\*---------------------------------------------------------------------------*/
+
+void make_synthesis_window(float Pn[])
+{
+ int i;
+ float win;
+
+ /* Generate Parzen window in time domain */
+
+ win = 0.0;
+ for(i=0; iL; l++) {
+ b = floor(l*model->Wo*FFT_DEC/TWO_PI + 0.5);
+ Sw_[b].real = model->A[l]*cos(model->phi[l]);
+ Sw_[b].imag = model->A[l]*sin(model->phi[l]);
+ Sw_[FFT_DEC-b].real = Sw_[b].real;
+ Sw_[FFT_DEC-b].imag = -Sw_[b].imag;
+ }
+
+ /* Perform inverse DFT */
+
+ four1(&Sw_[-1].imag,FFT_DEC,1);
+
+ /* Overlap add to previous samples */
+
+ for(i=0; i
+#include
+#include
+
+void scan_line(FILE *fp, float f[], int n);
+
+int main(int argc, char *argv[]) {
+ FILE *ftext; /* text file of vectors */
+ FILE *ffloat; /* float file of vectors */
+ int st,en; /* start and end values of vector to copy */
+ float *buf; /* ptr to vector read from ftext */
+ long lines; /* lines read so far */
+
+ if (argc != 5) {
+ printf("usage: extract TextFile FloatFile start end\n");
+ exit(0);
+ }
+
+ /* read command line arguments and open files */
+
+ ftext = fopen(argv[1],"rt");
+ if (ftext == NULL) {
+ printf("Error opening text file: %s\n",argv[1]);
+ exit(1);
+ }
+
+ ffloat = fopen(argv[2],"wb");
+ if (ffloat == NULL) {
+ printf("Error opening float file: %s\n",argv[2]);
+ exit(1);
+ }
+
+ st = atoi(argv[3]);
+ en = atoi(argv[4]);
+
+ buf = (float*)malloc(en*sizeof(float));
+ if (buf == NULL) {
+ printf("Error in malloc()\n");
+ exit(1);
+ }
+
+ lines = 0;
+ while(!feof(ftext)) {
+ scan_line(ftext, buf, en);
+ fwrite(&buf[st-1], sizeof(float), en-st+1, ffloat);
+ printf("\r%ld lines",lines++);
+ }
+ printf("\n");
+
+ /* clean up and exit */
+
+ free(buf);
+ fclose(ftext);
+ fclose(ffloat);
+
+ return 0;
+}
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: scan_line()
+
+ AUTHOR......: David Rowe
+ DATE CREATED: 20/2/95
+
+ This function reads a vector of floats from a line in a text file.
+
+\*---------------------------------------------------------------------------*/
+
+void scan_line(FILE *fp, float f[], int n)
+/* FILE *fp; file ptr to text file */
+/* float f[]; array of floats to return */
+/* int n; number of floats in line */
+{
+ char s[MAX_STR];
+ char *ps,*pe;
+ int i;
+
+ fgets(s,MAX_STR,fp);
+ ps = pe = s;
+ for(i=0; i
+#include
+#include
+#include
+#include "lpc.h" /* LPC analysis functions */
+#include "lsp.h" /* LSP encode/decode functions */
+
+int switch_present(sw,argc,argv)
+ char sw[]; /* switch in string form */
+ int argc; /* number of command line arguments */
+ char *argv[]; /* array of command line arguments in string form */
+{
+ int i; /* loop variable */
+
+ for(i=1; i THRESH) {
+ af++;
+ printf("Active Frame: %ld unstables: %d\n",af, unstables);
+
+ find_aks(Sn, ak, NW, P, &Eres);
+ roots = lpc_to_lsp(&ak[1], P , lsp, 5, LSP_DELTA1);
+ if (roots == P) {
+ if (lspd) {
+ fprintf(flsp,"%f ",lsp[0]);
+ for(i=1; i
+#include
+#include
+
+#define N 160
+#define P 10
+
+int main(int argc, char *argv[])
+{
+ FILE *fin,*fres; /* input and output files */
+ short buf[N]; /* buffer of 16 bit speech samples */
+ float Sn[P+N]; /* input speech samples */
+ float res[N]; /* residual after LPC filtering */
+ float E;
+ float ak[P+1]; /* LP coeffs */
+
+ int frames; /* frames processed so far */
+ int i; /* loop variables */
+
+ if (argc < 3) {
+ printf("usage: %s InputFile ResidualFile\n", argv[0]);
+ exit(0);
+ }
+
+ /* Open files */
+
+ if ((fin = fopen(argv[1],"rb")) == NULL) {
+ printf("Error opening input file: %s\n",argv[1]);
+ exit(0);
+ }
+
+ if ((fres = fopen(argv[2],"wb")) == NULL) {
+ printf("Error opening output residual file: %s\n",argv[2]);
+ exit(0);
+ }
+
+ /* Initialise */
+
+ frames = 0;
+ for(i=0; i
+#include
+#include
+#include
+#include
+#include
+
+#define N 160
+#define P 10
+
+#define LPC_FLOOR 0.0002 /* autocorrelation floor */
+#define LSP_DELTA1 0.2 /* grid spacing for LSP root searches */
+#define NDFT 256 /* DFT size for SD calculation */
+
+/* Speex lag window */
+
+const float lag_window[11] = {
+ 1.00000, 0.99716, 0.98869, 0.97474, 0.95554, 0.93140, 0.90273, 0.86998,
+ 0.83367, 0.79434, 0.75258
+};
+
+/*---------------------------------------------------------------------------*\
+
+ find_aks_for_lsp()
+
+ This function takes a frame of samples, and determines the linear
+ prediction coefficients for that frame of samples. Modified version of
+ find_aks from lpc.c to include autocorrelation noise floor and lag window
+ to match Speex processing steps prior to LSP conversion.
+
+\*---------------------------------------------------------------------------*/
+
+void find_aks_for_lsp(
+ float Sn[], /* Nsam samples with order sample memory */
+ float a[], /* order+1 LPCs with first coeff 1.0 */
+ int Nsam, /* number of input speech samples */
+ int order, /* order of the LPC analysis */
+ float *E /* residual energy */
+)
+{
+ float Wn[N]; /* windowed frame of Nsam speech samples */
+ float R[P+1]; /* order+1 autocorrelation values of Sn[] */
+ int i;
+
+ hanning_window(Sn,Wn,Nsam);
+
+ autocorrelate(Wn,R,Nsam,order);
+ R[0] += LPC_FLOOR;
+ assert(order == 10); /* lag window only defined for order == 10 */
+ for(i=0; i<=order; i++)
+ R[i] *= lag_window[i];
+ levinson_durbin(R,a,order);
+
+ *E = 0.0;
+ for(i=0; i<=order; i++)
+ *E += a[i]*R[i];
+ if (*E < 0.0)
+ *E = 1E-12;
+}
+
+/*---------------------------------------------------------------------------*\
+
+ MAIN
+
+\*---------------------------------------------------------------------------*/
+
+int main(int argc, char *argv[])
+{
+ FILE *fin; /* input speech files */
+ short buf[N]; /* buffer of 16 bit speech samples */
+ float Sn[P+N]; /* input speech samples */
+ float E;
+ float ak[P+1]; /* LP coeffs */
+ float ak_[P+1]; /* quantised LP coeffs */
+ float lsp[P];
+ float lsp_[P]; /* quantised LSPs */
+ int roots; /* number of LSP roots found */
+ int frames; /* frames processed so far */
+ int i; /* loop variables */
+
+ SpeexBits bits;
+
+ float sd; /* SD for this frame */
+ float totsd; /* accumulated SD so far */
+ int gt2,gt4; /* number of frames > 2 and 4 dB SD */
+ int unstables; /* number of unstable LSP frames */
+
+ if (argc < 2) {
+ printf("usage: %s InputFile\n", argv[0]);
+ exit(0);
+ }
+
+ /* Open files */
+
+ if ((fin = fopen(argv[1],"rb")) == NULL) {
+ printf("Error opening input file: %s\n",argv[1]);
+ exit(0);
+ }
+
+ /* Initialise */
+
+ frames = 0;
+ for(i=0; i
2.0) gt2++;
+ if (sd > 4.0) gt4++;
+ totsd += sd;
+ }
+ else
+ unstables++;
+ }
+
+ fclose(fin);
+
+ printf("frames = %d Av sd = %3.2f dB", frames, totsd/frames);
+ printf(" >2 dB %3.2f%% >4 dB %3.2f%% unstables: %d\n",gt2*100.0/frames,
+ gt4*100.0/frames, unstables);
+
+ return 0;
+}
+
diff --git a/libs/libcodec2/unittest/sd.c b/libs/libcodec2/unittest/sd.c
new file mode 100644
index 0000000000..f77b5099d5
--- /dev/null
+++ b/libs/libcodec2/unittest/sd.c
@@ -0,0 +1,84 @@
+/*--------------------------------------------------------------------------*\
+
+ FILE........: sd.c
+ AUTHOR......: David Rowe
+ DATE CREATED: 20/7/93
+
+ Function to determine spectral distortion between two sets of LPCs.
+
+\*--------------------------------------------------------------------------*/
+
+/*
+ Copyright (C) 2009 David Rowe
+
+ All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License version 2, as
+ published by the Free Software Foundation. This program is
+ distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#define MAX_N 2048 /* maximum DFT size */
+
+#include
+#include "four1.h"
+#include "comp.h"
+#include "sd.h"
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: spectral_dist()
+
+ AUTHOR......: David Rowe
+ DATE CREATED: 20/7/93
+
+ This function returns the soectral distoertion between two
+ sets of LPCs.
+
+\*---------------------------------------------------------------------------*/
+
+float spectral_dist(float ak1[], float ak2[], int p, int n)
+/* float ak1[]; unquantised set of p+1 LPCs */
+/* float ak2[]; quantised set of p+1 LPCs */
+/* int p; LP order */
+/* int n; DFT size to use for SD calculations (power of 2) */
+{
+ COMP A1[MAX_N]; /* DFT of ak1[] */
+ COMP A2[MAX_N]; /* DFT of ak2[] */
+ float P1,P2; /* power of current bin */
+ float sd;
+ int i;
+
+ for(i=0; i
+#include
+#include
+#include
+#include
+#include "defines.h"
+#include "codec2.h"
+#include "quantise.h"
+#include "interp.h"
+
+/* CODEC2 struct copies from codec2.c to help with testing */
+
+typedef struct {
+ float Sn[M]; /* input speech */
+ float w[M]; /* time domain hamming window */
+ COMP W[FFT_ENC]; /* DFT of w[] */
+ float Pn[2*N]; /* trapezoidal synthesis window */
+ float Sn_[2*N]; /* synthesised speech */
+ float prev_Wo; /* previous frame's pitch estimate */
+ float ex_phase; /* excitation model phase track */
+ float bg_est; /* background noise estimate for post filter */
+ MODEL prev_model; /* model parameters from 20ms ago */
+} CODEC2;
+
+void analyse_one_frame(CODEC2 *c2, MODEL *model, short speech[]);
+void synthesise_one_frame(CODEC2 *c2, short speech[], MODEL *model, float ak[]);
+
+int test1()
+{
+ FILE *fin, *fout;
+ short buf[N];
+ void *c2;
+ CODEC2 *c3;
+ MODEL model;
+ float ak[LPC_ORD+1];
+ float lsps[LPC_ORD];
+
+ c2 = codec2_create();
+ c3 = (CODEC2*)c2;
+
+ fin = fopen("../raw/hts1a.raw", "rb");
+ assert(fin != NULL);
+ fout = fopen("hts1a_test.raw", "wb");
+ assert(fout != NULL);
+
+ while(fread(buf, sizeof(short), N, fin) == N) {
+ analyse_one_frame(c3, &model, buf);
+ speech_to_uq_lsps(lsps, ak, c3->Sn, c3->w, LPC_ORD);
+ synthesise_one_frame(c3, buf, &model, ak);
+ fwrite(buf, sizeof(short), N, fout);
+ }
+
+ codec2_destroy(c2);
+
+ fclose(fin);
+ fclose(fout);
+
+ return 0;
+}
+
+int test2()
+{
+ FILE *fin, *fout;
+ short buf[2*N];
+ void *c2;
+ CODEC2 *c3;
+ MODEL model, model_interp;
+ float ak[LPC_ORD+1];
+ int voiced1, voiced2;
+ int lsp_indexes[LPC_ORD];
+ int lpc_correction;
+ int energy_index;
+ int Wo_index;
+ char bits[CODEC2_BITS_PER_FRAME];
+ int nbit;
+ int i;
+
+ c2 = codec2_create();
+ c3 = (CODEC2*)c2;
+
+ fin = fopen("../raw/hts1a.raw", "rb");
+ assert(fin != NULL);
+ fout = fopen("hts1a_test.raw", "wb");
+ assert(fout != NULL);
+
+ while(fread(buf, sizeof(short), 2*N, fin) == 2*N) {
+ /* first 10ms analysis frame - we just want voicing */
+
+ analyse_one_frame(c3, &model, buf);
+ voiced1 = model.voiced;
+
+ /* second 10ms analysis frame */
+
+ analyse_one_frame(c3, &model, &buf[N]);
+ voiced2 = model.voiced;
+
+ Wo_index = encode_Wo(model.Wo);
+ encode_amplitudes(lsp_indexes,
+ &lpc_correction,
+ &energy_index,
+ &model,
+ c3->Sn,
+ c3->w);
+ nbit = 0;
+ pack(bits, &nbit, Wo_index, WO_BITS);
+ for(i=0; iprev_model, &model);
+
+ synthesise_one_frame(c3, buf, &model_interp, ak);
+ synthesise_one_frame(c3, &buf[N], &model, ak);
+
+ memcpy(&c3->prev_model, &model, sizeof(MODEL));
+ fwrite(buf, sizeof(short), 2*N, fout);
+ }
+
+ codec2_destroy(c2);
+
+ fclose(fin);
+ fclose(fout);
+
+ return 0;
+}
+
+int test3()
+{
+ FILE *fin, *fout, *fbits;
+ short buf1[2*N];
+ short buf2[2*N];
+ char bits[CODEC2_BITS_PER_FRAME];
+ void *c2;
+
+ c2 = codec2_create();
+
+ fin = fopen("../raw/hts1a.raw", "rb");
+ assert(fin != NULL);
+ fout = fopen("hts1a_test.raw", "wb");
+ assert(fout != NULL);
+ fbits = fopen("hts1a_test3.bit", "wb");
+ assert(fout != NULL);
+
+ while(fread(buf1, sizeof(short), 2*N, fin) == 2*N) {
+ codec2_encode(c2, bits, buf1);
+ fwrite(bits, sizeof(char), CODEC2_BITS_PER_FRAME, fbits);
+ codec2_decode(c2, buf2, bits);
+ fwrite(buf2, sizeof(short), CODEC2_SAMPLES_PER_FRAME, fout);
+ }
+
+ codec2_destroy(c2);
+
+ fclose(fin);
+ fclose(fout);
+ fclose(fbits);
+
+ return 0;
+}
+
+int main() {
+ test3();
+ return 0;
+}
diff --git a/libs/libcodec2/unittest/tcontphase.c b/libs/libcodec2/unittest/tcontphase.c
new file mode 100644
index 0000000000..ee2f662a48
--- /dev/null
+++ b/libs/libcodec2/unittest/tcontphase.c
@@ -0,0 +1,187 @@
+/*---------------------------------------------------------------------------*\
+
+ FILE........: tcontphase.c
+ AUTHOR......: David Rowe
+ DATE CREATED: 11/9/09
+
+ Test program for developing continuous phase track synthesis algorithm.
+ However while developing this it was discovered that synthesis_mixed()
+ worked just as well.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+ Copyright (C) 2009 David Rowe
+
+ All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License version 2, as
+ published by the Free Software Foundation. This program is
+ distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#define N 80 /* frame size */
+#define F 160 /* frames to synthesis */
+#define P 10 /* LPC order */
+
+#include
+#include
+#include
+#include
+#include "sine.h"
+#include "dump.h"
+#include "synth.h"
+#include "phase.h"
+
+int frames;
+
+float ak[] = {
+ 1.000000,
+-1.455836,
+ 1.361841,
+-0.879267,
+ 0.915985,
+-1.002202,
+ 0.944103,
+-0.743094,
+ 1.053356,
+-0.817491,
+ 0.431222
+};
+
+
+/*---------------------------------------------------------------------------*\
+
+ switch_present()
+
+ Searches the command line arguments for a "switch". If the switch is
+ found, returns the command line argument where it ws found, else returns
+ NULL.
+
+\*---------------------------------------------------------------------------*/
+
+int switch_present(sw,argc,argv)
+ char sw[]; /* switch in string form */
+ int argc; /* number of command line arguments */
+ char *argv[]; /* array of command line arguments in string form */
+{
+ int i; /* loop variable */
+
+ for(i=1; i
+#include
+#include
+#include
+#include
+#include
+
+#include "defines.h"
+#include "sine.h"
+#include "interp.h"
+
+void make_amp(MODEL *model, float f0, float cdB, float mdBHz)
+{
+ int i;
+ float mdBrad = mdBHz*FS/TWO_PI;
+
+ model->Wo = f0*TWO_PI/FS;
+ model->L = PI/model->Wo;
+ for(i=0; i<=model->L; i++)
+ model->A[i] = pow(10.0,(cdB + (float)i*model->Wo*mdBrad)/20.0);
+ model->voiced = 1;
+}
+
+void write_amp(char file[], MODEL *model)
+{
+ FILE *f;
+ int i;
+
+ f = fopen(file,"wt");
+ for(i=1; i<=model->L; i++)
+ fprintf(f, "%f\t%f\n", model->Wo*i, model->A[i]);
+ fclose(f);
+}
+
+char *get_next_float(char *s, float *num)
+{
+ char *p = s;
+ char tmp[MAX_STR];
+
+ while(*p && !isspace(*p))
+ p++;
+ memcpy(tmp, s, p-s);
+ tmp[p-s] = 0;
+ *num = atof(tmp);
+
+ return p+1;
+}
+
+char *get_next_int(char *s, int *num)
+{
+ char *p = s;
+ char tmp[MAX_STR];
+
+ while(*p && !isspace(*p))
+ p++;
+ memcpy(tmp, s, p-s);
+ tmp[p-s] = 0;
+ *num = atoi(tmp);
+
+ return p+1;
+}
+
+void load_amp(MODEL *model, char file[], int frame)
+{
+ FILE *f;
+ int i;
+ char s[1024];
+ char *ps;
+
+ f = fopen(file,"rt");
+
+ for(i=0; iWo);
+ ps = get_next_int(ps, &model->L);
+ for(i=1; i<=model->L; i++)
+ ps = get_next_float(ps, &model->A[i]);
+
+ fclose(f);
+}
+
+int main() {
+ MODEL prev, next, interp;
+
+ //make_amp(&prev, 50.0, 60.0, 6E-3);
+ //make_amp(&next, 50.0, 40.0, 6E-3);
+ load_amp(&prev, "../src/hts1a_model.txt", 32);
+ load_amp(&next, "../src/hts1a_model.txt", 34);
+
+ interp.voiced = 1;
+ interpolate(&interp, &prev, &next);
+
+ write_amp("tinterp_prev.txt", &prev);
+ write_amp("tinterp_interp.txt", &interp);
+ write_amp("tinterp_next.txt", &next);
+
+ return 0;
+}
diff --git a/libs/libcodec2/unittest/tnlp.c b/libs/libcodec2/unittest/tnlp.c
new file mode 100644
index 0000000000..4abf69c4ef
--- /dev/null
+++ b/libs/libcodec2/unittest/tnlp.c
@@ -0,0 +1,148 @@
+/*---------------------------------------------------------------------------*\
+
+ FILE........: tnlp.c
+ AUTHOR......: David Rowe
+ DATE CREATED: 23/3/93
+
+ Test program for non linear pitch estimation functions.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+ Copyright (C) 2009 David Rowe
+
+ All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License version 2, as
+ published by the Free Software Foundation. This program is
+ distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#define N 80 /* frame size */
+#define M 320 /* pitch analysis window size */
+#define PITCH_MIN 20
+#define PITCH_MAX 160
+#define TNLP
+
+#include
+#include
+#include
+#include
+
+#include "defines.h"
+#include "dump.h"
+#include "sine.h"
+#include "nlp.h"
+
+int frames;
+
+/*---------------------------------------------------------------------------*\
+
+ switch_present()
+
+ Searches the command line arguments for a "switch". If the switch is
+ found, returns the command line argument where it ws found, else returns
+ NULL.
+
+\*---------------------------------------------------------------------------*/
+
+int switch_present(sw,argc,argv)
+ char sw[]; /* switch in string form */
+ int argc; /* number of command line arguments */
+ char *argv[]; /* array of command line arguments in string form */
+{
+ int i; /* loop variable */
+
+ for(i=1; i
+#include
+#include
+#include
+#include
+
+#include "defines.h"
+#include "dump.h"
+#include "quantise.h"
+
+int test_Wo_quant();
+int test_lsp_quant();
+int test_lsp(int lsp_number, int levels, float max_error_hz);
+int test_energy_quant(int levels, float max_error_dB);
+
+int main() {
+ quantise_init();
+ test_Wo_quant();
+ test_lsp_quant();
+ test_energy_quant(E_LEVELS, 0.5*(E_MAX_DB - E_MIN_DB)/E_LEVELS);
+
+ return 0;
+}
+
+int test_lsp_quant() {
+ test_lsp( 1, 16, 12.5);
+ test_lsp( 2, 16, 12.5);
+ test_lsp( 3, 16, 25);
+ test_lsp( 4, 16, 50);
+ test_lsp( 5, 16, 50);
+ test_lsp( 6, 16, 50);
+ test_lsp( 7, 16, 50);
+ test_lsp( 8, 8, 50);
+ test_lsp( 9, 8, 50);
+ test_lsp(10, 4, 100);
+
+ return 0;
+}
+
+int test_energy_quant(int levels, float max_error_dB) {
+ FILE *fe;
+ float e,e_dec, error, low_e, high_e;
+ int index, index_in, index_out, i;
+
+ /* check 1:1 match between input and output levels */
+
+ for(i=0; i max_error_dB) {
+ printf("error: %f %f\n", error, max_error_dB);
+ exit(0);
+ }
+ }
+
+ fclose(fe);
+ return 0;
+}
+
+int test_lsp(int lsp_number, int levels, float max_error_hz) {
+ float lsp[LPC_ORD];
+ int indexes_in[LPC_ORD];
+ int indexes_out[LPC_ORD];
+ int indexes[LPC_ORD];
+ int i;
+ float lowf, highf, f, error;
+ char s[MAX_STR];
+ FILE *flsp;
+ float max_error_rads;
+
+ lsp_number--;
+ max_error_rads = max_error_hz*TWO_PI/FS;
+
+ for(i=0; i max_error_rads) {
+ printf("%d error: %f %f\n", lsp_number+1, error, max_error_rads);
+ exit(0);
+ }
+ }
+
+ fclose(flsp);
+
+ printf("OK\n");
+
+ return 0;
+}
+
+int test_Wo_quant() {
+ int c;
+ FILE *f;
+ float Wo,Wo_dec, error, step_size;
+ int index, index_in, index_out;
+
+ /* output Wo quant curve for plotting */
+
+ f = fopen("quant_pitch.txt","wt");
+
+ for(Wo=0.9*(TWO_PI/P_MAX); Wo<=1.1*(TWO_PI/P_MIN); Wo += 0.001) {
+ index = encode_Wo(Wo);
+ fprintf(f, "%f %d\n", Wo, index);
+ }
+
+ fclose(f);
+
+ /* check for all Wo codes we get 1:1 match between encoder
+ and decoder Wo levels */
+
+ for(c=0; c (step_size/2.0)) {
+ printf("error: %f step_size/2: %f\n", error, step_size/2.0);
+ exit(0);
+ }
+ fprintf(f,"%f\n",error);
+ }
+ printf("OK\n");
+
+ fclose(f);
+ return 0;
+}
diff --git a/libs/libcodec2/unittest/vqtrain.c b/libs/libcodec2/unittest/vqtrain.c
new file mode 100644
index 0000000000..b46d4fcf30
--- /dev/null
+++ b/libs/libcodec2/unittest/vqtrain.c
@@ -0,0 +1,297 @@
+/*--------------------------------------------------------------------------*\
+
+ FILE........: VQTRAIN.C
+ AUTHOR......: David Rowe
+ DATE CREATED: 23/2/95
+
+ This program trains vector quantisers using K dimensional Lloyd-Max
+ method.
+
+\*--------------------------------------------------------------------------*/
+
+/*
+ Copyright (C) 2009 David Rowe
+
+ All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License version 2, as
+ published by the Free Software Foundation. This program is
+ distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*-----------------------------------------------------------------------*\
+
+ INCLUDES
+
+\*-----------------------------------------------------------------------*/
+
+#include
+#include
+#include
+#include
+#include
+
+/*-----------------------------------------------------------------------*\
+
+ DEFINES
+
+\*-----------------------------------------------------------------------*/
+
+#define DELTAQ 0.01 /* quiting distortion */
+#define MAX_STR 80 /* maximum string length */
+
+/*-----------------------------------------------------------------------*\
+
+ FUNCTION PROTOTYPES
+
+\*-----------------------------------------------------------------------*/
+
+void zero(float v[], int k);
+void acc(float v1[], float v2[], int k);
+void norm(float v[], int k, long n);
+long quantise(float cb[], float vec[], int k, int m, float *se);
+
+/*-----------------------------------------------------------------------*\
+
+ MAIN
+
+\*-----------------------------------------------------------------------*/
+
+int main(int argc, char *argv[]) {
+ long k,m; /* dimension and codebook size */
+ float *vec; /* current vector */
+ float *cb; /* vector codebook */
+ float *cent; /* centroids for each codebook entry */
+ long *n; /* number of vectors in this interval */
+ long J; /* number of vectors in training set */
+ long i,j;
+ long ind; /* index of current vector */
+ float se; /* squared error for this iteration */
+ float Dn,Dn_1; /* current and previous iterations distortion */
+ float delta; /* improvement in distortion */
+ FILE *ftrain; /* file containing training set */
+ FILE *fvq; /* file containing vector quantiser */
+
+ /* Interpret command line arguments */
+
+ if (argc != 5) {
+ printf("usage: vqtrain TrainFile K M VQFile\n");
+ exit(0);
+ }
+
+ /* Open training file */
+
+ ftrain = fopen(argv[1],"rb");
+ if (ftrain == NULL) {
+ printf("Error opening training database file: %s\n",argv[1]);
+ exit(1);
+ }
+
+ /* determine k and m, and allocate arrays */
+
+ k = atol(argv[2]);
+ m = atol(argv[3]);
+ printf("dimension K=%ld number of entries M=%ld\n", k,m);
+ vec = (float*)malloc(sizeof(float)*k);
+ cb = (float*)malloc(sizeof(float)*k*m);
+ cent = (float*)malloc(sizeof(float)*k*m);
+ n = (long*)malloc(sizeof(long)*m);
+ if (cb == NULL || cb == NULL || cent == NULL || vec == NULL) {
+ printf("Error in malloc.\n");
+ exit(1);
+ }
+
+ /* determine size of training set */
+
+ J = 0;
+ while(fread(vec, sizeof(float), k, ftrain) == k)
+ J++;
+ printf("J=%ld entries in training set\n", J);
+
+ /* set up initial codebook state from samples of training set */
+
+ rewind(ftrain);
+ fread(cb, sizeof(float), k*m, ftrain);
+
+ /* main loop */
+
+ Dn = 1E32;
+ j = 1;
+ do {
+ Dn_1 = Dn;
+
+ /* zero centroids */
+
+ for(i=0; i DELTAQ)
+ for(i=0; i DELTAQ);
+
+ /* save codebook to disk */
+
+ fvq = fopen(argv[4],"wt");
+ if (fvq == NULL) {
+ printf("Error opening VQ file: %s\n",argv[4]);
+ exit(1);
+ }
+
+ for(j=0; jchan_count; i++) {
@@ -1025,6 +1025,8 @@ ZIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event)
event_id = ZAP_OOB_OFFHOOK;
} else if (span->channels[i]->type == ZAP_CHAN_TYPE_FXO) {
event_id = ZAP_OOB_RING_START;
+ } else {
+ event_id = ZAP_OOB_NOOP;
}
}
break;
diff --git a/libs/openzap/src/zap_io.c b/libs/openzap/src/zap_io.c
index 7d37a493c4..283a9fe332 100644
--- a/libs/openzap/src/zap_io.c
+++ b/libs/openzap/src/zap_io.c
@@ -1017,6 +1017,7 @@ OZ_DECLARE(zap_status_t) zap_channel_set_state(zap_channel_t *zchan, zap_channel
case ZAP_CHANNEL_STATE_RING:
case ZAP_CHANNEL_STATE_PROGRESS_MEDIA:
case ZAP_CHANNEL_STATE_PROGRESS:
+ case ZAP_CHANNEL_STATE_IDLE:
case ZAP_CHANNEL_STATE_GET_CALLERID:
case ZAP_CHANNEL_STATE_GENRING:
ok = 1;
diff --git a/libs/sofia-sip/configure.ac b/libs/sofia-sip/configure.ac
index 0eb2418ad9..196d815157 100644
--- a/libs/sofia-sip/configure.ac
+++ b/libs/sofia-sip/configure.ac
@@ -53,6 +53,7 @@ AC_CHECK_PROG(ETAGS, etags, etags, echo)
AC_CHECK_TOOL(AR, ar, ar)
AC_CHECK_TOOL(LD, ld, ld)
AC_PROG_LIBTOOL
+AM_PROG_CC_C_O
SAC_ENABLE_NDEBUG
SAC_ENABLE_EXPENSIVE_CHECKS
diff --git a/libs/sofia-sip/libsofia-sip-ua/http/sofia-sip/http.h b/libs/sofia-sip/libsofia-sip-ua/http/sofia-sip/http.h
index d5bb617914..bd42743c9f 100644
--- a/libs/sofia-sip/libsofia-sip-ua/http/sofia-sip/http.h
+++ b/libs/sofia-sip/libsofia-sip-ua/http/sofia-sip/http.h
@@ -58,7 +58,11 @@ SOFIA_BEGIN_DECLS
#define HTTP_DEFAULT_SERV "80"
/** HTTP protocol identifier */
+#ifndef _MSC_VER
#define HTTP_PROTOCOL_TAG ((void *)0x48545450) /* 'HTTP' */
+#else
+#define HTTP_PROTOCOL_TAG ((void *)(UINT_PTR)0x48545450) /* 'HTTP' */
+#endif
/** HTTP parser flags */
enum {
diff --git a/libs/sofia-sip/libsofia-sip-ua/msg/msg_tag.c b/libs/sofia-sip/libsofia-sip-ua/msg/msg_tag.c
index 2be30b04b9..061cd5ef2a 100644
--- a/libs/sofia-sip/libsofia-sip-ua/msg/msg_tag.c
+++ b/libs/sofia-sip/libsofia-sip-ua/msg/msg_tag.c
@@ -50,7 +50,11 @@
#include
#include "sofia-sip/msg_tag_class.h"
+#ifndef _MSC_VER
#define NONE ((void*)-1)
+#else
+#define NONE ((void*)(INT_PTR)-1)
+#endif
int msghdrtag_snprintf(tagi_t const *t, char b[], size_t size)
{
diff --git a/libs/sofia-sip/libsofia-sip-ua/msg/sofia-sip/msg_header.h b/libs/sofia-sip/libsofia-sip-ua/msg/sofia-sip/msg_header.h
index 91fd72316b..c633aa3632 100644
--- a/libs/sofia-sip/libsofia-sip-ua/msg/sofia-sip/msg_header.h
+++ b/libs/sofia-sip/libsofia-sip-ua/msg/sofia-sip/msg_header.h
@@ -299,7 +299,12 @@ enum {
(h))
/** No header. */
+
+#ifndef _MSC_VER
#define MSG_HEADER_NONE ((msg_header_t *)-1)
+#else
+#define MSG_HEADER_NONE ((msg_header_t *)(INT_PTR)-1)
+#endif
SOFIA_END_DECLS
diff --git a/libs/sofia-sip/libsofia-sip-ua/msg/sofia-sip/msg_mime.h b/libs/sofia-sip/libsofia-sip-ua/msg/sofia-sip/msg_mime.h
index 4a9f234dec..033c551fdb 100644
--- a/libs/sofia-sip/libsofia-sip-ua/msg/sofia-sip/msg_mime.h
+++ b/libs/sofia-sip/libsofia-sip-ua/msg/sofia-sip/msg_mime.h
@@ -235,7 +235,11 @@ msg_content_length_t *msg_content_length_create(su_home_t *home, uint32_t n);
SOFIAPUBVAR char const msg_mime_version_1_0[];
/** MIME multipart parser table identifier. @HIDE */
+#ifndef _MSC_VER
#define MSG_MULTIPART_PROTOCOL_TAG ((void *)0x4d494d45) /* 'MIME' */
+#else
+#define MSG_MULTIPART_PROTOCOL_TAG ((void *)(UINT_PTR)0x4d494d45) /* 'MIME' */
+#endif
SOFIA_END_DECLS
diff --git a/libs/sofia-sip/libsofia-sip-ua/nea/nea_server.c b/libs/sofia-sip/libsofia-sip-ua/nea/nea_server.c
index 4287ae4359..a6c7d49ac6 100644
--- a/libs/sofia-sip/libsofia-sip-ua/nea/nea_server.c
+++ b/libs/sofia-sip/libsofia-sip-ua/nea/nea_server.c
@@ -41,7 +41,11 @@
#include "nea_debug.h"
+#ifndef _MSC_VER
#define NONE ((void *)- 1)
+#else
+#define NONE ((void *)(INT_PTR)- 1)
+#endif
#define SU_ROOT_MAGIC_T struct nea_server_s
#define SU_MSG_ARG_T tagi_t
diff --git a/libs/sofia-sip/libsofia-sip-ua/nta/nta.c b/libs/sofia-sip/libsofia-sip-ua/nta/nta.c
index 656aecc195..40ee1f8f85 100644
--- a/libs/sofia-sip/libsofia-sip-ua/nta/nta.c
+++ b/libs/sofia-sip/libsofia-sip-ua/nta/nta.c
@@ -104,8 +104,11 @@ char const nta_version[] = PACKAGE_VERSION;
static char const __func__[] = "nta";
#endif
+#ifndef _MSC_VER
#define NONE ((void *)-1)
-
+#else
+#define NONE ((void *)(INT_PTR)-1)
+#endif
/* ------------------------------------------------------------------------- */
/** Resolving order */
diff --git a/libs/sofia-sip/libsofia-sip-ua/nta/run_check_nta b/libs/sofia-sip/libsofia-sip-ua/nta/run_check_nta
old mode 100644
new mode 100755
diff --git a/libs/sofia-sip/libsofia-sip-ua/nta/run_test_nta b/libs/sofia-sip/libsofia-sip-ua/nta/run_test_nta
old mode 100644
new mode 100755
diff --git a/libs/sofia-sip/libsofia-sip-ua/nta/run_test_nta_api b/libs/sofia-sip/libsofia-sip-ua/nta/run_test_nta_api
old mode 100644
new mode 100755
diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_dialog.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_dialog.c
index bf35263d92..b96b1f31c0 100644
--- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_dialog.c
+++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_dialog.c
@@ -53,7 +53,12 @@
#include
#ifndef NONE
+
+#ifndef _MSC_VER
#define NONE ((void *)-1)
+#else
+#define NONE ((void *)(INT_PTR)-1)
+#endif
#endif
/* ======================================================================== */
diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.h b/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.h
index 318ccdd61d..97c88582a3 100644
--- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.h
+++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_stack.h
@@ -83,7 +83,11 @@ typedef struct nua_ee_data {
nua_event_data_t ee_data[1];
} nua_ee_data_t;
+#ifndef _MSC_VER
#define NONE ((void *)-1)
+#else
+#define NONE ((void *)(INT_PTR)-1)
+#endif
typedef struct register_usage nua_registration_t;
diff --git a/libs/sofia-sip/libsofia-sip-ua/sdp/run_test_sdp b/libs/sofia-sip/libsofia-sip-ua/sdp/run_test_sdp
old mode 100644
new mode 100755
diff --git a/libs/sofia-sip/libsofia-sip-ua/sip/run-tests b/libs/sofia-sip/libsofia-sip-ua/sip/run-tests
old mode 100644
new mode 100755
diff --git a/libs/sofia-sip/libsofia-sip-ua/sip/run_test_date b/libs/sofia-sip/libsofia-sip-ua/sip/run_test_date
old mode 100644
new mode 100755
diff --git a/libs/sofia-sip/libsofia-sip-ua/sip/sofia-sip/sip.h b/libs/sofia-sip/libsofia-sip-ua/sip/sofia-sip/sip.h
index 1a235ca4c8..37ae836598 100644
--- a/libs/sofia-sip/libsofia-sip-ua/sip/sofia-sip/sip.h
+++ b/libs/sofia-sip/libsofia-sip-ua/sip/sofia-sip/sip.h
@@ -81,10 +81,18 @@ typedef enum {
#define SIP_METHOD_PUBLISH sip_method_publish, "PUBLISH"
/** Magic pointer value - never valid for SIP headers. @HI */
+#ifndef _MSC_VER
#define SIP_NONE ((void const *)-1L)
+#else
+#define SIP_NONE ((void const *)(INT_PTR)-1L)
+#endif
/** SIP protocol identifier @HIDE */
+#ifndef _MSC_VER
#define SIP_PROTOCOL_TAG ((void *)0x53495020) /* 'SIP'20 */
+#else
+#define SIP_PROTOCOL_TAG ((void *)(UINT_PTR)0x53495020) /* 'SIP'20 */
+#endif
enum {
/** Default port for SIP as integer */
diff --git a/libs/sofia-sip/libsofia-sip-ua/soa/soa.c b/libs/sofia-sip/libsofia-sip-ua/soa/soa.c
index de79e0f3a5..7f272a8e6f 100644
--- a/libs/sofia-sip/libsofia-sip-ua/soa/soa.c
+++ b/libs/sofia-sip/libsofia-sip-ua/soa/soa.c
@@ -56,7 +56,11 @@
#include
#include
+#ifndef _MSC_VER
#define NONE ((void *)-1)
+#else
+#define NONE ((void *)(INT_PTR)-1)
+#endif
#define XXX assert(!"implemented")
typedef unsigned longlong ull;
diff --git a/libs/sofia-sip/libsofia-sip-ua/soa/soa_static.c b/libs/sofia-sip/libsofia-sip-ua/soa/soa_static.c
index f94f9b2962..f104274ef4 100644
--- a/libs/sofia-sip/libsofia-sip-ua/soa/soa_static.c
+++ b/libs/sofia-sip/libsofia-sip-ua/soa/soa_static.c
@@ -396,7 +396,11 @@ sdp_rtpmap_t *soa_sdp_media_matching_rtpmap(sdp_rtpmap_t const *from,
return NULL;
}
+#ifndef _MSC_VER
#define SDP_MEDIA_NONE ((sdp_media_t *)-1)
+#else
+#define SDP_MEDIA_NONE ((sdp_media_t *)(INT_PTR)-1)
+#endif
/** Find first matching media in table @a mm.
*
diff --git a/libs/sofia-sip/libsofia-sip-ua/sresolv/run_test_sresolv b/libs/sofia-sip/libsofia-sip-ua/sresolv/run_test_sresolv
old mode 100644
new mode 100755
diff --git a/libs/sofia-sip/libsofia-sip-ua/sresolv/sres.c b/libs/sofia-sip/libsofia-sip-ua/sresolv/sres.c
index f660b2ce22..e494571f54 100644
--- a/libs/sofia-sip/libsofia-sip-ua/sresolv/sres.c
+++ b/libs/sofia-sip/libsofia-sip-ua/sresolv/sres.c
@@ -125,7 +125,7 @@ su_inline
ssize_t sres_recvfrom(sres_socket_t s, void *buffer, size_t length, int flags,
struct sockaddr *from, socklen_t *fromlen)
{
- int retval, ilen;
+ int retval, ilen = 0;
if (fromlen)
ilen = *fromlen;
diff --git a/libs/sofia-sip/libsofia-sip-ua/su/run_addrinfo b/libs/sofia-sip/libsofia-sip-ua/su/run_addrinfo
old mode 100644
new mode 100755
diff --git a/libs/sofia-sip/libsofia-sip-ua/su/run_localinfo b/libs/sofia-sip/libsofia-sip-ua/su/run_localinfo
old mode 100644
new mode 100755
diff --git a/libs/sofia-sip/libsofia-sip-ua/su/run_test_su b/libs/sofia-sip/libsofia-sip-ua/su/run_test_su
old mode 100644
new mode 100755
diff --git a/libs/sofia-sip/libsofia-sip-ua/su/run_test_su_osx b/libs/sofia-sip/libsofia-sip-ua/su/run_test_su_osx
old mode 100644
new mode 100755
diff --git a/libs/sofia-sip/libsofia-sip-ua/su/su.c b/libs/sofia-sip/libsofia-sip-ua/su/su.c
index 250b5d62d1..8067fdec60 100644
--- a/libs/sofia-sip/libsofia-sip-ua/su/su.c
+++ b/libs/sofia-sip/libsofia-sip-ua/su/su.c
@@ -434,7 +434,7 @@ ssize_t su_recv(su_socket_t s, void *buffer, size_t length, int flags)
ssize_t su_recvfrom(su_socket_t s, void *buffer, size_t length, int flags,
su_sockaddr_t *from, socklen_t *fromlen)
{
- int retval, ilen;
+ int retval, ilen = 0;
if (fromlen)
ilen = *fromlen;
diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/tport_internal.h b/libs/sofia-sip/libsofia-sip-ua/tport/tport_internal.h
index b56dd2d9bc..683b79a360 100644
--- a/libs/sofia-sip/libsofia-sip-ua/tport/tport_internal.h
+++ b/libs/sofia-sip/libsofia-sip-ua/tport/tport_internal.h
@@ -79,7 +79,11 @@
#endif
#ifndef NONE
+#ifndef _MSC_VER
#define NONE ((void *)-1)
+#else
+#define NONE ((void *)(INT_PTR)-1)
+#endif
#endif
SOFIA_BEGIN_DECLS
diff --git a/libs/sofia-sip/scripts/coverage b/libs/sofia-sip/scripts/coverage
old mode 100644
new mode 100755
diff --git a/libs/sofia-sip/scripts/fix-include-sofia-sip b/libs/sofia-sip/scripts/fix-include-sofia-sip
old mode 100644
new mode 100755
diff --git a/libs/sofia-sip/scripts/lcov-report b/libs/sofia-sip/scripts/lcov-report
old mode 100644
new mode 100755
diff --git a/libs/sofia-sip/scripts/rpmbuild-snaphot b/libs/sofia-sip/scripts/rpmbuild-snaphot
old mode 100644
new mode 100755
diff --git a/libs/sofia-sip/scripts/uncovered b/libs/sofia-sip/scripts/uncovered
old mode 100644
new mode 100755
diff --git a/libs/spandsp/configure.ac b/libs/spandsp/configure.ac
index 3aeb44ff52..7914885d79 100644
--- a/libs/spandsp/configure.ac
+++ b/libs/spandsp/configure.ac
@@ -207,7 +207,7 @@ AC_CHECK_HEADERS([fenv.h])
AC_CHECK_HEADERS([fftw3.h], , [AC_CHECK_HEADERS([fftw.h])])
AC_CHECK_HEADERS([pcap.h])
AC_CHECK_HEADERS([pthread.h])
-if test "${build}" == "${host}"
+if test "${build}" = "${host}"
then
AC_CHECK_HEADERS([X11/X.h])
fi
@@ -253,7 +253,7 @@ AC_CHECK_HEADERS([FL/Fl_Audio_Meter.H], [], [], [],[[#include
AC_LANG([C])
-if test "${build}" == "${host}"
+if test "${build}" = "${host}"
then
case "${host}" in
x86_64-*)
diff --git a/libs/spandsp/src/spandsp/t38_core.h b/libs/spandsp/src/spandsp/t38_core.h
index 1476969eeb..3d8e864513 100644
--- a/libs/spandsp/src/spandsp/t38_core.h
+++ b/libs/spandsp/src/spandsp/t38_core.h
@@ -286,7 +286,7 @@ SPAN_DECLARE(int) t38_core_send_data_multi_field(t38_core_state_t *s, int data_t
\param len The length of the packet contents.
\param seq_no The packet sequence number.
\return 0 for OK, else -1. */
-SPAN_DECLARE(int) t38_core_rx_ifp_packet(t38_core_state_t *s, const uint8_t *buf, int len, uint16_t seq_no);
+SPAN_DECLARE_NONSTD(int) t38_core_rx_ifp_packet(t38_core_state_t *s, const uint8_t *buf, int len, uint16_t seq_no);
/*! Set the method to be used for data rate management, as per the T.38 spec.
\param s The T.38 context.
diff --git a/libs/spandsp/src/t38_core.c b/libs/spandsp/src/t38_core.c
index 551d6c0155..e7ee967e93 100644
--- a/libs/spandsp/src/t38_core.c
+++ b/libs/spandsp/src/t38_core.c
@@ -325,7 +325,7 @@ static __inline__ int classify_seq_no_offset(int expected, int actual)
}
/*- End of function --------------------------------------------------------*/
-SPAN_DECLARE(int) t38_core_rx_ifp_packet(t38_core_state_t *s, const uint8_t *buf, int len, uint16_t seq_no)
+SPAN_DECLARE_NONSTD(int) t38_core_rx_ifp_packet(t38_core_state_t *s, const uint8_t *buf, int len, uint16_t seq_no)
{
int i;
int t30_indicator;
diff --git a/libs/spandsp/unpack_gsm0610_data.sh b/libs/spandsp/unpack_gsm0610_data.sh
index d1f8b92a23..482334c79e 100755
--- a/libs/spandsp/unpack_gsm0610_data.sh
+++ b/libs/spandsp/unpack_gsm0610_data.sh
@@ -53,7 +53,7 @@ else
cd gsm0610
fi
-if [ $1x == --no-exe-runx ]
+if [ $1x = --no-exe-runx ]
then
# Run the .exe files, which should be here
./FR_A.EXE
@@ -77,7 +77,7 @@ rm -rf READ_FRA.TXT
rm -rf ACTION
rm -rf unpacked
-if [ $1x == --no-exex ]
+if [ $1x = --no-exex ]
then
# We need to prepare the .exe files to be run separately
rm -rf *.INP
diff --git a/libs/sqlite/configure.ac b/libs/sqlite/configure.ac
index fc21161fda..75d6f512d1 100644
--- a/libs/sqlite/configure.ac
+++ b/libs/sqlite/configure.ac
@@ -447,7 +447,7 @@ if test "$TARGET_EXEEXT" = ".exe"; then
OS_WIN=0
OS_OS2=1
TARGET_CFLAGS="$TARGET_CFLAGS -DOS_OS2=1"
- if test "$ac_compiler_gnu" == "yes" ; then
+ if test "$ac_compiler_gnu" = "yes" ; then
TARGET_CFLAGS="$TARGET_CFLAGS -Zomf -Zexe -Zmap"
BUILD_CFLAGS="$BUILD_CFLAGS -Zomf -Zexe"
fi
diff --git a/libs/win32/Sound_Files/16khz.2008.vcproj b/libs/win32/Sound_Files/16khz.2008.vcproj
index 994b21ee0d..d8f80bbde6 100644
--- a/libs/win32/Sound_Files/16khz.2008.vcproj
+++ b/libs/win32/Sound_Files/16khz.2008.vcproj
@@ -33,7 +33,7 @@
/>
diff --git a/libs/win32/Sound_Files/16khz.2010.vcxproj b/libs/win32/Sound_Files/16khz.2010.vcxproj
index 2d11a5232b..90d4abd4e9 100644
--- a/libs/win32/Sound_Files/16khz.2010.vcxproj
+++ b/libs/win32/Sound_Files/16khz.2010.vcxproj
@@ -67,7 +67,8 @@
- xcopy "$(SolutionDir)libs\sounds\en\us\callie\voicemail\16000\*.*" "$(OutDir)sounds\en\us\callie\voicemail\16000" /C /D /Y /S /I
+
+xcopy "$(SolutionDir)libs\sounds\en\us\callie\voicemail\16000\*.*" "$(OutDir)sounds\en\us\callie\voicemail\16000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\ivr\16000\*.*" "$(OutDir)sounds\en\us\callie\ivr\16000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\conference\16000\*.*" "$(OutDir)sounds\en\us\callie\conference\16000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\time\16000\*.*" "$(OutDir)sounds\en\us\callie\time\16000" /C /D /Y /S /I
@@ -76,12 +77,14 @@ xcopy "$(SolutionDir)libs\sounds\en\us\callie\ascii\16000\*.*" "$(OutDir)sounds\
xcopy "$(SolutionDir)libs\sounds\en\us\callie\misc\16000\*.*" "$(OutDir)sounds\en\us\callie\misc\16000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\currency\16000\*.*" "$(OutDir)sounds\en\us\callie\currency\16000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\phonetic-ascii\16000\*.*" "$(OutDir)sounds\en\us\callie\phonetic-ascii\16000" /C /D /Y /S /I
+xcopy "$(SolutionDir)libs\sounds\en\us\callie\directory\16000\*.*" "$(OutDir)sounds\en\us\callie\directory\16000" /C /D /Y /S /I
- xcopy "$(SolutionDir)libs\sounds\en\us\callie\voicemail\16000\*.*" "$(OutDir)sounds\en\us\callie\voicemail\16000" /C /D /Y /S /I
+
+xcopy "$(SolutionDir)libs\sounds\en\us\callie\voicemail\16000\*.*" "$(OutDir)sounds\en\us\callie\voicemail\16000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\ivr\16000\*.*" "$(OutDir)sounds\en\us\callie\ivr\16000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\conference\16000\*.*" "$(OutDir)sounds\en\us\callie\conference\16000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\time\16000\*.*" "$(OutDir)sounds\en\us\callie\time\16000" /C /D /Y /S /I
@@ -90,12 +93,14 @@ xcopy "$(SolutionDir)libs\sounds\en\us\callie\ascii\16000\*.*" "$(OutDir)sounds\
xcopy "$(SolutionDir)libs\sounds\en\us\callie\misc\16000\*.*" "$(OutDir)sounds\en\us\callie\misc\16000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\currency\16000\*.*" "$(OutDir)sounds\en\us\callie\currency\16000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\phonetic-ascii\16000\*.*" "$(OutDir)sounds\en\us\callie\phonetic-ascii\16000" /C /D /Y /S /I
+xcopy "$(SolutionDir)libs\sounds\en\us\callie\directory\16000\*.*" "$(OutDir)sounds\en\us\callie\directory\16000" /C /D /Y /S /I
- xcopy "$(SolutionDir)libs\sounds\en\us\callie\voicemail\16000\*.*" "$(OutDir)sounds\en\us\callie\voicemail\16000" /C /D /Y /S /I
+
+xcopy "$(SolutionDir)libs\sounds\en\us\callie\voicemail\16000\*.*" "$(OutDir)sounds\en\us\callie\voicemail\16000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\ivr\16000\*.*" "$(OutDir)sounds\en\us\callie\ivr\16000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\conference\16000\*.*" "$(OutDir)sounds\en\us\callie\conference\16000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\time\16000\*.*" "$(OutDir)sounds\en\us\callie\time\16000" /C /D /Y /S /I
@@ -104,12 +109,14 @@ xcopy "$(SolutionDir)libs\sounds\en\us\callie\ascii\16000\*.*" "$(OutDir)sounds\
xcopy "$(SolutionDir)libs\sounds\en\us\callie\misc\16000\*.*" "$(OutDir)sounds\en\us\callie\misc\16000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\currency\16000\*.*" "$(OutDir)sounds\en\us\callie\currency\16000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\phonetic-ascii\16000\*.*" "$(OutDir)sounds\en\us\callie\phonetic-ascii\16000" /C /D /Y /S /I
+xcopy "$(SolutionDir)libs\sounds\en\us\callie\directory\16000\*.*" "$(OutDir)sounds\en\us\callie\directory\16000" /C /D /Y /S /I
- xcopy "$(SolutionDir)libs\sounds\en\us\callie\voicemail\16000\*.*" "$(OutDir)sounds\en\us\callie\voicemail\16000" /C /D /Y /S /I
+
+xcopy "$(SolutionDir)libs\sounds\en\us\callie\voicemail\16000\*.*" "$(OutDir)sounds\en\us\callie\voicemail\16000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\ivr\16000\*.*" "$(OutDir)sounds\en\us\callie\ivr\16000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\conference\16000\*.*" "$(OutDir)sounds\en\us\callie\conference\16000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\time\16000\*.*" "$(OutDir)sounds\en\us\callie\time\16000" /C /D /Y /S /I
@@ -118,6 +125,7 @@ xcopy "$(SolutionDir)libs\sounds\en\us\callie\ascii\16000\*.*" "$(OutDir)sounds\
xcopy "$(SolutionDir)libs\sounds\en\us\callie\misc\16000\*.*" "$(OutDir)sounds\en\us\callie\misc\16000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\currency\16000\*.*" "$(OutDir)sounds\en\us\callie\currency\16000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\phonetic-ascii\16000\*.*" "$(OutDir)sounds\en\us\callie\phonetic-ascii\16000" /C /D /Y /S /I
+xcopy "$(SolutionDir)libs\sounds\en\us\callie\directory\16000\*.*" "$(OutDir)sounds\en\us\callie\directory\16000" /C /D /Y /S /I
diff --git a/libs/win32/Sound_Files/32khz.2008.vcproj b/libs/win32/Sound_Files/32khz.2008.vcproj
index e735a0c011..d2ac0af2e3 100644
--- a/libs/win32/Sound_Files/32khz.2008.vcproj
+++ b/libs/win32/Sound_Files/32khz.2008.vcproj
@@ -33,7 +33,7 @@
/>
diff --git a/libs/win32/Sound_Files/32khz.2010.vcxproj b/libs/win32/Sound_Files/32khz.2010.vcxproj
index 32651e40dd..1435d0c7a3 100644
--- a/libs/win32/Sound_Files/32khz.2010.vcxproj
+++ b/libs/win32/Sound_Files/32khz.2010.vcxproj
@@ -67,7 +67,8 @@
- xcopy "$(SolutionDir)libs\sounds\en\us\callie\voicemail\32000\*.*" "$(OutDir)sounds\en\us\callie\voicemail\32000" /C /D /Y /S /I
+
+xcopy "$(SolutionDir)libs\sounds\en\us\callie\voicemail\32000\*.*" "$(OutDir)sounds\en\us\callie\voicemail\32000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\ivr\32000\*.*" "$(OutDir)sounds\en\us\callie\ivr\32000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\conference\32000\*.*" "$(OutDir)sounds\en\us\callie\conference\32000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\time\32000\*.*" "$(OutDir)sounds\en\us\callie\time\32000" /C /D /Y /S /I
@@ -76,12 +77,14 @@ xcopy "$(SolutionDir)libs\sounds\en\us\callie\ascii\32000\*.*" "$(OutDir)sounds\
xcopy "$(SolutionDir)libs\sounds\en\us\callie\misc\32000\*.*" "$(OutDir)sounds\en\us\callie\misc\32000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\currency\32000\*.*" "$(OutDir)sounds\en\us\callie\currency\32000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\phonetic-ascii\32000\*.*" "$(OutDir)sounds\en\us\callie\phonetic-ascii\32000" /C /D /Y /S /I
+xcopy "$(SolutionDir)libs\sounds\en\us\callie\directory\32000\*.*" "$(OutDir)sounds\en\us\callie\directory\32000" /C /D /Y /S /I
- xcopy "$(SolutionDir)libs\sounds\en\us\callie\voicemail\32000\*.*" "$(OutDir)sounds\en\us\callie\voicemail\32000" /C /D /Y /S /I
+
+xcopy "$(SolutionDir)libs\sounds\en\us\callie\voicemail\32000\*.*" "$(OutDir)sounds\en\us\callie\voicemail\32000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\ivr\32000\*.*" "$(OutDir)sounds\en\us\callie\ivr\32000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\conference\32000\*.*" "$(OutDir)sounds\en\us\callie\conference\32000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\time\32000\*.*" "$(OutDir)sounds\en\us\callie\time\32000" /C /D /Y /S /I
@@ -90,12 +93,14 @@ xcopy "$(SolutionDir)libs\sounds\en\us\callie\ascii\32000\*.*" "$(OutDir)sounds\
xcopy "$(SolutionDir)libs\sounds\en\us\callie\misc\32000\*.*" "$(OutDir)sounds\en\us\callie\misc\32000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\currency\32000\*.*" "$(OutDir)sounds\en\us\callie\currency\32000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\phonetic-ascii\32000\*.*" "$(OutDir)sounds\en\us\callie\phonetic-ascii\32000" /C /D /Y /S /I
+xcopy "$(SolutionDir)libs\sounds\en\us\callie\directory\32000\*.*" "$(OutDir)sounds\en\us\callie\directory\32000" /C /D /Y /S /I
- xcopy "$(SolutionDir)libs\sounds\en\us\callie\voicemail\32000\*.*" "$(OutDir)sounds\en\us\callie\voicemail\32000" /C /D /Y /S /I
+
+xcopy "$(SolutionDir)libs\sounds\en\us\callie\voicemail\32000\*.*" "$(OutDir)sounds\en\us\callie\voicemail\32000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\ivr\32000\*.*" "$(OutDir)sounds\en\us\callie\ivr\32000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\conference\32000\*.*" "$(OutDir)sounds\en\us\callie\conference\32000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\time\32000\*.*" "$(OutDir)sounds\en\us\callie\time\32000" /C /D /Y /S /I
@@ -104,12 +109,14 @@ xcopy "$(SolutionDir)libs\sounds\en\us\callie\ascii\32000\*.*" "$(OutDir)sounds\
xcopy "$(SolutionDir)libs\sounds\en\us\callie\misc\32000\*.*" "$(OutDir)sounds\en\us\callie\misc\32000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\currency\32000\*.*" "$(OutDir)sounds\en\us\callie\currency\32000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\phonetic-ascii\32000\*.*" "$(OutDir)sounds\en\us\callie\phonetic-ascii\32000" /C /D /Y /S /I
+xcopy "$(SolutionDir)libs\sounds\en\us\callie\directory\32000\*.*" "$(OutDir)sounds\en\us\callie\directory\32000" /C /D /Y /S /I
- xcopy "$(SolutionDir)libs\sounds\en\us\callie\voicemail\32000\*.*" "$(OutDir)sounds\en\us\callie\voicemail\32000" /C /D /Y /S /I
+
+xcopy "$(SolutionDir)libs\sounds\en\us\callie\voicemail\32000\*.*" "$(OutDir)sounds\en\us\callie\voicemail\32000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\ivr\32000\*.*" "$(OutDir)sounds\en\us\callie\ivr\32000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\conference\32000\*.*" "$(OutDir)sounds\en\us\callie\conference\32000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\time\32000\*.*" "$(OutDir)sounds\en\us\callie\time\32000" /C /D /Y /S /I
@@ -118,6 +125,7 @@ xcopy "$(SolutionDir)libs\sounds\en\us\callie\ascii\32000\*.*" "$(OutDir)sounds\
xcopy "$(SolutionDir)libs\sounds\en\us\callie\misc\32000\*.*" "$(OutDir)sounds\en\us\callie\misc\32000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\currency\32000\*.*" "$(OutDir)sounds\en\us\callie\currency\32000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\phonetic-ascii\32000\*.*" "$(OutDir)sounds\en\us\callie\phonetic-ascii\32000" /C /D /Y /S /I
+xcopy "$(SolutionDir)libs\sounds\en\us\callie\directory\32000\*.*" "$(OutDir)sounds\en\us\callie\directory\32000" /C /D /Y /S /I
diff --git a/libs/win32/Sound_Files/8khz.2008.vcproj b/libs/win32/Sound_Files/8khz.2008.vcproj
index aed0a1f798..413c47dc63 100644
--- a/libs/win32/Sound_Files/8khz.2008.vcproj
+++ b/libs/win32/Sound_Files/8khz.2008.vcproj
@@ -33,7 +33,7 @@
/>
diff --git a/libs/win32/Sound_Files/8khz.2010.vcxproj b/libs/win32/Sound_Files/8khz.2010.vcxproj
index 1535b2c4ce..664e9755d7 100644
--- a/libs/win32/Sound_Files/8khz.2010.vcxproj
+++ b/libs/win32/Sound_Files/8khz.2010.vcxproj
@@ -67,7 +67,8 @@
- xcopy "$(SolutionDir)libs\sounds\en\us\callie\voicemail\8000\*.*" "$(OutDir)sounds\en\us\callie\voicemail\8000" /C /D /Y /S /I
+
+xcopy "$(SolutionDir)libs\sounds\en\us\callie\voicemail\8000\*.*" "$(OutDir)sounds\en\us\callie\voicemail\8000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\ivr\8000\*.*" "$(OutDir)sounds\en\us\callie\ivr\8000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\conference\8000\*.*" "$(OutDir)sounds\en\us\callie\conference\8000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\time\8000\*.*" "$(OutDir)sounds\en\us\callie\time\8000" /C /D /Y /S /I
@@ -76,12 +77,14 @@ xcopy "$(SolutionDir)libs\sounds\en\us\callie\ascii\8000\*.*" "$(OutDir)sounds\e
xcopy "$(SolutionDir)libs\sounds\en\us\callie\misc\8000\*.*" "$(OutDir)sounds\en\us\callie\misc\8000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\currency\8000\*.*" "$(OutDir)sounds\en\us\callie\currency\8000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\phonetic-ascii\8000\*.*" "$(OutDir)sounds\en\us\callie\phonetic-ascii\8000" /C /D /Y /S /I
+xcopy "$(SolutionDir)libs\sounds\en\us\callie\directory\8000\*.*" "$(OutDir)sounds\en\us\callie\directory\8000" /C /D /Y /S /I
- xcopy "$(SolutionDir)libs\sounds\en\us\callie\voicemail\8000\*.*" "$(OutDir)sounds\en\us\callie\voicemail\8000" /C /D /Y /S /I
+
+xcopy "$(SolutionDir)libs\sounds\en\us\callie\voicemail\8000\*.*" "$(OutDir)sounds\en\us\callie\voicemail\8000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\ivr\8000\*.*" "$(OutDir)sounds\en\us\callie\ivr\8000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\conference\8000\*.*" "$(OutDir)sounds\en\us\callie\conference\8000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\time\8000\*.*" "$(OutDir)sounds\en\us\callie\time\8000" /C /D /Y /S /I
@@ -90,12 +93,14 @@ xcopy "$(SolutionDir)libs\sounds\en\us\callie\ascii\8000\*.*" "$(OutDir)sounds\e
xcopy "$(SolutionDir)libs\sounds\en\us\callie\misc\8000\*.*" "$(OutDir)sounds\en\us\callie\misc\8000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\currency\8000\*.*" "$(OutDir)sounds\en\us\callie\currency\8000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\phonetic-ascii\8000\*.*" "$(OutDir)sounds\en\us\callie\phonetic-ascii\8000" /C /D /Y /S /I
+xcopy "$(SolutionDir)libs\sounds\en\us\callie\directory\8000\*.*" "$(OutDir)sounds\en\us\callie\directory\8000" /C /D /Y /S /I
- xcopy "$(SolutionDir)libs\sounds\en\us\callie\voicemail\8000\*.*" "$(OutDir)sounds\en\us\callie\voicemail\8000" /C /D /Y /S /I
+
+xcopy "$(SolutionDir)libs\sounds\en\us\callie\voicemail\8000\*.*" "$(OutDir)sounds\en\us\callie\voicemail\8000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\ivr\8000\*.*" "$(OutDir)sounds\en\us\callie\ivr\8000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\conference\8000\*.*" "$(OutDir)sounds\en\us\callie\conference\8000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\time\8000\*.*" "$(OutDir)sounds\en\us\callie\time\8000" /C /D /Y /S /I
@@ -104,12 +109,14 @@ xcopy "$(SolutionDir)libs\sounds\en\us\callie\ascii\8000\*.*" "$(OutDir)sounds\e
xcopy "$(SolutionDir)libs\sounds\en\us\callie\misc\8000\*.*" "$(OutDir)sounds\en\us\callie\misc\8000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\currency\8000\*.*" "$(OutDir)sounds\en\us\callie\currency\8000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\phonetic-ascii\8000\*.*" "$(OutDir)sounds\en\us\callie\phonetic-ascii\8000" /C /D /Y /S /I
+xcopy "$(SolutionDir)libs\sounds\en\us\callie\directory\8000\*.*" "$(OutDir)sounds\en\us\callie\directory\8000" /C /D /Y /S /I
- xcopy "$(SolutionDir)libs\sounds\en\us\callie\voicemail\8000\*.*" "$(OutDir)sounds\en\us\callie\voicemail\8000" /C /D /Y /S /I
+
+xcopy "$(SolutionDir)libs\sounds\en\us\callie\voicemail\8000\*.*" "$(OutDir)sounds\en\us\callie\voicemail\8000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\ivr\8000\*.*" "$(OutDir)sounds\en\us\callie\ivr\8000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\conference\8000\*.*" "$(OutDir)sounds\en\us\callie\conference\8000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\time\8000\*.*" "$(OutDir)sounds\en\us\callie\time\8000" /C /D /Y /S /I
@@ -118,6 +125,7 @@ xcopy "$(SolutionDir)libs\sounds\en\us\callie\ascii\8000\*.*" "$(OutDir)sounds\e
xcopy "$(SolutionDir)libs\sounds\en\us\callie\misc\8000\*.*" "$(OutDir)sounds\en\us\callie\misc\8000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\currency\8000\*.*" "$(OutDir)sounds\en\us\callie\currency\8000" /C /D /Y /S /I
xcopy "$(SolutionDir)libs\sounds\en\us\callie\phonetic-ascii\8000\*.*" "$(OutDir)sounds\en\us\callie\phonetic-ascii\8000" /C /D /Y /S /I
+xcopy "$(SolutionDir)libs\sounds\en\us\callie\directory\8000\*.*" "$(OutDir)sounds\en\us\callie\directory\8000" /C /D /Y /S /I
diff --git a/libs/win32/openssl/libeay32.2010.vcxproj b/libs/win32/openssl/libeay32.2010.vcxproj
index 1157e5ca87..4d0d9a44ee 100644
--- a/libs/win32/openssl/libeay32.2010.vcxproj
+++ b/libs/win32/openssl/libeay32.2010.vcxproj
@@ -74,6 +74,10 @@
truetruetrue
+ $(PlatformName)\libeay32\$(Configuration)\
+ $(PlatformName)\libeay32\$(Configuration)\
+ $(PlatformName)\libeay32\$(Configuration)\
+ $(PlatformName)\libeay32\$(Configuration)\
diff --git a/libs/win32/openssl/ssleay32.2010.vcxproj b/libs/win32/openssl/ssleay32.2010.vcxproj
index 8d6c22df18..1a444bb41f 100644
--- a/libs/win32/openssl/ssleay32.2010.vcxproj
+++ b/libs/win32/openssl/ssleay32.2010.vcxproj
@@ -73,6 +73,10 @@
truetruetrue
+ $(PlatformName)\ssleay32\$(Configuration)\
+ $(PlatformName)\ssleay32\$(Configuration)\
+ $(PlatformName)\ssleay32\$(Configuration)\
+ $(PlatformName)\ssleay32\$(Configuration)\
diff --git a/scripts/perl/blacklist.pl b/scripts/perl/blacklist.pl
new file mode 100755
index 0000000000..f434669f36
--- /dev/null
+++ b/scripts/perl/blacklist.pl
@@ -0,0 +1,29 @@
+#!/usr/bin/perl
+#
+# Add this to acl.conf.xml
+#
+#
+#
+
+use Data::Dumper;
+use LWP::Simple;
+
+# http://www.infiltrated.net/voipabuse/addresses.txt
+# http://www.infiltrated.net/voipabuse/netblocks.txt
+
+
+my @addresses = split(/\n/, get("http://www.infiltrated.net/voipabuse/addresses.txt"));
+my @netblocks = split(/\n/, get("http://www.infiltrated.net/voipabuse/netblocks.txt"));
+
+print "\n";
+foreach $addr (@addresses) {
+ print " \n";
+}
+print "\n";
+
+
+print "\n";
+foreach $netb (@netblocks) {
+ print " \n";
+}
+print "\n";
diff --git a/scripts/perl/honeypot.pl b/scripts/perl/honeypot.pl
new file mode 100755
index 0000000000..ef52142cb1
--- /dev/null
+++ b/scripts/perl/honeypot.pl
@@ -0,0 +1,26 @@
+#!/usr/bin/perl
+#
+# Add this to conf/dialplan/public but only if you wish to setup a honeypot.
+#
+#
+#
+
+use Data::Dumper;
+use LWP::Simple;
+
+# http://www.infiltrated.net/voipabuse/numberscalled.txt
+
+my @numberscalled = split(/\n/, get("http://www.infiltrated.net/voipabuse/numberscalled.txt"));
+
+foreach $number (@numberscalled) {
+ my ($num,$ts) = split(/\t/, $number);
+
+ print "\n";
+ print " \n";
+ print " \n";
+ print " \n";
+ print " \n";
+ print "\n";
+}
+
+
diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h
index e77d5f74ef..ea02f22fa0 100644
--- a/src/include/private/switch_core_pvt.h
+++ b/src/include/private/switch_core_pvt.h
@@ -167,6 +167,7 @@ struct switch_core_session {
uint32_t track_id;
switch_log_level_t loglevel;
uint32_t soft_lock;
+ switch_ivr_dmachine_t *dmachine;
};
struct switch_media_bug {
@@ -198,6 +199,7 @@ struct switch_runtime {
int64_t offset;
switch_event_t *global_vars;
switch_hash_t *mime_types;
+ switch_hash_t *ptimes;
switch_memory_pool_t *memory_pool;
const switch_state_handler_table_t *state_handlers[SWITCH_MAX_STATE_HANDLERS];
int state_handler_index;
diff --git a/src/include/switch.h b/src/include/switch.h
index 7143c61d91..81684c59b0 100644
--- a/src/include/switch.h
+++ b/src/include/switch.h
@@ -91,7 +91,10 @@
#include
#pragma warning(pop)
#else
+/* work around for warnings in vs 2010 */
+#pragma warning (disable:6386)
#include
+#pragma warning (default:6386)
#endif
#else
#include
diff --git a/src/include/switch_channel.h b/src/include/switch_channel.h
index 3f92534e3e..a1f13edd85 100644
--- a/src/include/switch_channel.h
+++ b/src/include/switch_channel.h
@@ -261,10 +261,17 @@ SWITCH_DECLARE(const char *) switch_channel_get_variable_partner(switch_channel_
#define switch_channel_set_variable_partner(_channel, _var, _val) switch_channel_set_variable_partner_var_check(_channel, _var, _val, SWITCH_TRUE)
-SWITCH_DECLARE(switch_status_t) switch_channel_export_variable_var_check(switch_channel_t *channel, const char *varname, const char *value, switch_bool_t var_check);
+SWITCH_DECLARE(switch_status_t) switch_channel_export_variable_var_check(switch_channel_t *channel,
+ const char *varname, const char *val,
+ const char *export_varname,
+ switch_bool_t var_check);
-#define switch_channel_export_variable(_channel, _varname, _value) switch_channel_export_variable_var_check(_channel, _varname, _value, SWITCH_TRUE)
-SWITCH_DECLARE(switch_status_t) switch_channel_export_variable_printf(switch_channel_t *channel, const char *varname, const char *fmt, ...);
+SWITCH_DECLARE(void) switch_channel_process_export(switch_channel_t *channel, switch_channel_t *peer_channel,
+ switch_event_t *var_event, const char *export_varname);
+
+#define switch_channel_export_variable(_channel, _varname, _value, _ev) switch_channel_export_variable_var_check(_channel, _varname, _value, _ev, SWITCH_TRUE)
+SWITCH_DECLARE(switch_status_t) switch_channel_export_variable_printf(switch_channel_t *channel, const char *varname,
+ const char *export_varname, const char *fmt, ...);
/*!
diff --git a/src/include/switch_core.h b/src/include/switch_core.h
index 7275f26319..3f636d00c4 100644
--- a/src/include/switch_core.h
+++ b/src/include/switch_core.h
@@ -704,7 +704,8 @@ SWITCH_DECLARE(switch_log_level_t) switch_core_session_get_loglevel(switch_core_
SWITCH_DECLARE(void) switch_core_session_soft_lock(switch_core_session_t *session, uint32_t sec);
SWITCH_DECLARE(void) switch_core_session_soft_unlock(switch_core_session_t *session);
-
+SWITCH_DECLARE(void) switch_core_session_set_dmachine(switch_core_session_t *session, switch_ivr_dmachine_t *dmachine);
+SWITCH_DECLARE(switch_ivr_dmachine_t *) switch_core_session_get_dmachine(switch_core_session_t *session);
/*!
\brief Retrieve the unique identifier from the core
@@ -1339,15 +1340,19 @@ SWITCH_DECLARE(switch_status_t) switch_core_timer_destroy(switch_timer_t *timer)
\param pool the memory pool to use
\return SWITCH_STATUS_SUCCESS if the handle is allocated
*/
-SWITCH_DECLARE(switch_status_t) switch_core_codec_init(switch_codec_t *codec,
+#define switch_core_codec_init(_codec, _codec_name, _fmtp, _rate, _ms, _channels, _flags, _codec_settings, _pool) \
+ switch_core_codec_init_with_bitrate(_codec, _codec_name, _fmtp, _rate, _ms, _channels, 0, _flags, _codec_settings, _pool)
+SWITCH_DECLARE(switch_status_t) switch_core_codec_init_with_bitrate(switch_codec_t *codec,
const char *codec_name,
const char *fmtp,
uint32_t rate,
int ms,
int channels,
+ uint32_t bitrate,
uint32_t flags, const switch_codec_settings_t *codec_settings, switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_status_t) switch_core_codec_copy(switch_codec_t *codec, switch_codec_t *new_codec, switch_memory_pool_t *pool);
+SWITCH_DECLARE(switch_status_t) switch_core_codec_parse_fmtp(const char *codec_name, const char *fmtp, uint32_t rate, switch_codec_fmtp_t *codec_fmtp);
SWITCH_DECLARE(switch_status_t) switch_core_codec_reset(switch_codec_t *codec);
/*!
@@ -2163,6 +2168,7 @@ SWITCH_DECLARE(uint32_t) switch_core_debug_level(void);
SWITCH_DECLARE(void) switch_cache_db_flush_handles(void);
SWITCH_DECLARE(const char *) switch_core_banner(void);
SWITCH_DECLARE(switch_bool_t) switch_core_session_in_thread(switch_core_session_t *session);
+SWITCH_DECLARE(uint32_t) switch_default_ptime(const char *name, uint32_t number);
SWITCH_END_EXTERN_C
#endif
diff --git a/src/include/switch_cpp.h b/src/include/switch_cpp.h
index ed14f108c7..0ede8e638f 100644
--- a/src/include/switch_cpp.h
+++ b/src/include/switch_cpp.h
@@ -292,7 +292,8 @@ SWITCH_DECLARE(void) consoleCleanLog(char *msg);
SWITCH_DECLARE(int) transfer(char *extension, char *dialplan = NULL, char *context = NULL);
- SWITCH_DECLARE(char *) read(int min_digits, int max_digits, const char *prompt_audio_file, int timeout, const char *valid_terminators);
+ SWITCH_DECLARE(char *) read(int min_digits, int max_digits,
+ const char *prompt_audio_file, int timeout, const char *valid_terminators, int digit_timeout = 0);
/** \brief Play a file into channel and collect dtmfs
*
@@ -306,7 +307,7 @@ SWITCH_DECLARE(void) consoleCleanLog(char *msg);
int max_digits,
int max_tries,
int timeout, char *terminators, char *audio_files, char *bad_input_audio_files,
- char *digits_regex, const char *var_name = NULL);
+ char *digits_regex, const char *var_name = NULL, int digit_timeout = 0);
/** \brief Play a file that resides on disk into the channel
*
diff --git a/src/include/switch_ivr.h b/src/include/switch_ivr.h
index 40ba1dc16f..fb023848ec 100644
--- a/src/include/switch_ivr.h
+++ b/src/include/switch_ivr.h
@@ -369,7 +369,8 @@ SWITCH_DECLARE(switch_status_t) switch_play_and_get_digits(switch_core_session_t
const char *audio_file,
const char *bad_input_audio_file,
const char *var_name, char *digit_buffer, uint32_t digit_buffer_length,
- const char *digits_regex);
+ const char *digits_regex,
+ uint32_t digit_timeout);
SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session_t *session,
switch_speech_handle_t *sh,
@@ -556,6 +557,7 @@ SWITCH_DECLARE(uint32_t) switch_ivr_schedule_broadcast(time_t runtime, const cha
\return SWITCH_STATUS_SUCCESS if all is well
*/
SWITCH_DECLARE(switch_status_t) switch_ivr_broadcast(const char *uuid, const char *path, switch_media_flag_t flags);
+SWITCH_DECLARE(void) switch_ivr_broadcast_in_thread(switch_core_session_t *session, const char *app, int flags);
/*!
\brief Transfer variables from one session to another
@@ -804,7 +806,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_read(switch_core_session_t *session,
uint32_t max_digits,
const char *prompt_audio_file,
const char *var_name,
- char *digit_buffer, switch_size_t digit_buffer_length, uint32_t timeout, const char *valid_terminators);
+ char *digit_buffer,
+ switch_size_t digit_buffer_length,
+ uint32_t timeout,
+ const char *valid_terminators,
+ uint32_t digit_timeout);
+
SWITCH_DECLARE(switch_status_t) switch_ivr_block_dtmf_session(switch_core_session_t *session);
SWITCH_DECLARE(switch_status_t) switch_ivr_unblock_dtmf_session(switch_core_session_t *session);
@@ -836,6 +843,35 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_sound_test(switch_core_session_t *ses
SWITCH_DECLARE(void) switch_process_import(switch_core_session_t *session, switch_channel_t *peer_channel, const char *varname);
SWITCH_DECLARE(switch_bool_t) switch_ivr_uuid_exists(const char *uuid);
+
+
+SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_create(switch_ivr_dmachine_t **dmachine_p,
+ const char *name,
+ switch_memory_pool_t *pool,
+ uint32_t digit_timeout, uint32_t input_timeout,
+ switch_ivr_dmachine_callback_t match_callback,
+ switch_ivr_dmachine_callback_t nonmatch_callback,
+ void *user_data);
+
+SWITCH_DECLARE(void) switch_ivr_dmachine_destroy(switch_ivr_dmachine_t **dmachine);
+
+SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_bind(switch_ivr_dmachine_t *dmachine,
+ const char *realm,
+ const char *digits,
+ int32_t key,
+ switch_ivr_dmachine_callback_t callback,
+ void *user_data);
+
+SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_feed(switch_ivr_dmachine_t *dmachine, const char *digits, switch_ivr_dmachine_match_t **match);
+SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_clear(switch_ivr_dmachine_t *dmachine);
+SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_ping(switch_ivr_dmachine_t *dmachine, switch_ivr_dmachine_match_t **match_p);
+SWITCH_DECLARE(switch_ivr_dmachine_match_t *) switch_ivr_dmachine_get_match(switch_ivr_dmachine_t *dmachine);
+SWITCH_DECLARE(const char *) switch_ivr_dmachine_get_failed_digits(switch_ivr_dmachine_t *dmachine);
+SWITCH_DECLARE(void) switch_ivr_dmachine_set_digit_timeout_ms(switch_ivr_dmachine_t *dmachine, uint32_t digit_timeout_ms);
+SWITCH_DECLARE(void) switch_ivr_dmachine_set_input_timeout_ms(switch_ivr_dmachine_t *dmachine, uint32_t input_timeout_ms);
+SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_clear_realm(switch_ivr_dmachine_t *dmachine, const char *realm);
+SWITCH_DECLARE(switch_status_t) switch_ivr_dmachine_set_realm(switch_ivr_dmachine_t *dmachine, const char *realm);
+
/** @} */
SWITCH_END_EXTERN_C
diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h
index 078b83d2fd..a6013a9386 100644
--- a/src/include/switch_module_interfaces.h
+++ b/src/include/switch_module_interfaces.h
@@ -570,42 +570,23 @@ struct switch_directory_handle {
void *private_info;
};
-
/* nobody has more setting than speex so we will let them set the standard */
/*! \brief Various codec settings (currently only relevant to speex) */
struct switch_codec_settings {
- /*! desired quality */
- int quality;
- /*! desired complexity */
- int complexity;
- /*! desired enhancement */
- int enhancement;
- /*! desired vad level */
- int vad;
- /*! desired vbr level */
- int vbr;
- /*! desired vbr quality */
- float vbr_quality;
- /*! desired abr level */
- int abr;
- /*! desired dtx setting */
- int dtx;
- /*! desired preprocessor settings */
- int preproc;
- /*! preprocessor vad settings */
- int pp_vad;
- /*! preprocessor gain control settings */
- int pp_agc;
- /*! preprocessor gain level */
- float pp_agc_level;
- /*! preprocessor denoise level */
- int pp_denoise;
- /*! preprocessor dereverb settings */
- int pp_dereverb;
- /*! preprocessor dereverb decay level */
- float pp_dereverb_decay;
- /*! preprocessor dereverb level */
- float pp_dereverb_level;
+ int unused;
+};
+
+/*! an abstract handle of a fmtp parsed by codec */
+struct switch_codec_fmtp {
+ /*! actual samples transferred per second for those who are not moron g722 RFC writers */
+ uint32_t actual_samples_per_second;
+ /*! bits transferred per second */
+ int bits_per_second;
+ /*! number of microseconds of media in one packet (ptime * 1000) */
+ int microseconds_per_packet;
+ /*! private data for the codec module to store handle specific info */
+ void *private_info;
+
};
/*! an abstract handle to a codec module */
@@ -618,8 +599,6 @@ struct switch_codec {
char *fmtp_in;
/*! fmtp line for local sdp */
char *fmtp_out;
- /*! codec settings for this handle */
- switch_codec_settings_t codec_settings;
/*! flags to modify behaviour */
uint32_t flags;
/*! the handle's memory pool */
@@ -678,6 +657,8 @@ struct switch_codec_interface {
const char *interface_name;
/*! a list of codec implementations related to the codec */
switch_codec_implementation_t *implementations;
+ /*! function to decode a codec fmtp parameters */
+ switch_core_codec_fmtp_parse_func_t parse_fmtp;
uint32_t codec_id;
switch_thread_rwlock_t *rwlock;
int refs;
diff --git a/src/include/switch_rtp.h b/src/include/switch_rtp.h
index 7e6028a68b..7269a2b8d9 100644
--- a/src/include/switch_rtp.h
+++ b/src/include/switch_rtp.h
@@ -449,6 +449,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_stun_ping(switch_rtp_t *rtp_
SWITCH_DECLARE(void) switch_rtp_intentional_bugs(switch_rtp_t *rtp_session, switch_rtp_bug_flag_t bugs);
SWITCH_DECLARE(switch_rtp_stats_t *) switch_rtp_get_stats(switch_rtp_t *rtp_session, switch_memory_pool_t *pool);
+SWITCH_DECLARE(switch_byte_t) switch_rtp_check_auto_adj(switch_rtp_t *rtp_session);
/*!
\}
diff --git a/src/include/switch_types.h b/src/include/switch_types.h
index b0395bafdc..b1fc627354 100644
--- a/src/include/switch_types.h
+++ b/src/include/switch_types.h
@@ -123,6 +123,7 @@ SWITCH_BEGIN_EXTERN_C
#define SWITCH_CURRENT_APPLICATION_VARIABLE "current_application"
#define SWITCH_CURRENT_APPLICATION_DATA_VARIABLE "current_application_data"
#define SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE "current_application_response"
+#define SWITCH_PASSTHRU_PTIME_MISMATCH_VARIABLE "passthru_ptime_mismatch"
#define SWITCH_ENABLE_HEARTBEAT_EVENTS_VARIABLE "enable_heartbeat_events"
#define SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE "bypass_media_after_bridge"
#define SWITCH_READ_RESULT_VARIABLE "read_result"
@@ -156,6 +157,7 @@ SWITCH_BEGIN_EXTERN_C
#define SWITCH_ENDPOINT_DISPOSITION_VARIABLE "endpoint_disposition"
#define SWITCH_HOLD_MUSIC_VARIABLE "hold_music"
#define SWITCH_EXPORT_VARS_VARIABLE "export_vars"
+#define SWITCH_BRIDGE_EXPORT_VARS_VARIABLE "bridge_export_vars"
#define SWITCH_R_SDP_VARIABLE "switch_r_sdp"
#define SWITCH_L_SDP_VARIABLE "switch_l_sdp"
#define SWITCH_B_SDP_VARIABLE "switch_m_sdp"
@@ -188,9 +190,14 @@ SWITCH_BEGIN_EXTERN_C
#define SWITCH_DTMF_LOG_LEN 1000
typedef uint8_t switch_byte_t;
+typedef enum {
+ DTMF_FLAG_SKIP_PROCESS = (1 << 0)
+} dtmf_flag_t;
+
typedef struct {
char digit;
uint32_t duration;
+ int32_t flags;
} switch_dtmf_t;
typedef enum {
@@ -770,9 +777,9 @@ typedef struct {
const char *T38FaxUdpEC;
const char *T38VendorInfo;
const char *remote_ip;
- uint32_t remote_port;
+ uint16_t remote_port;
const char *local_ip;
- uint32_t local_port;
+ uint16_t local_port;
} switch_t38_options_t;
/*!
@@ -832,6 +839,7 @@ typedef enum {
SWITCH_STATUS_NOUNLOAD,
SWITCH_STATUS_IGNORE,
SWITCH_STATUS_TOO_SMALL,
+ SWITCH_STATUS_FOUND,
SWITCH_STATUS_NOT_INITALIZED
} switch_status_t;
@@ -1053,6 +1061,8 @@ typedef enum {
CF_EARLY_HANGUP,
CF_MEDIA_SET,
CF_CONSUME_ON_ORIGINATE,
+ CF_PASSTHRU_PTIME_MISMATCH,
+ CF_BRIDGE_NOWRITE,
/* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
CF_FLAG_MAX
} switch_channel_flag_t;
@@ -1588,6 +1598,7 @@ typedef struct switch_core_thread_session switch_core_thread_session_t;
typedef struct switch_codec_implementation switch_codec_implementation_t;
typedef struct switch_buffer switch_buffer_t;
typedef struct switch_codec_settings switch_codec_settings_t;
+typedef struct switch_codec_fmtp switch_codec_fmtp_t;
typedef struct switch_odbc_handle switch_odbc_handle_t;
typedef struct switch_io_routines switch_io_routines_t;
@@ -1646,6 +1657,7 @@ typedef switch_status_t (*switch_core_codec_decode_func_t) (switch_codec_t *code
void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate, unsigned int *flag);
typedef switch_status_t (*switch_core_codec_init_func_t) (switch_codec_t *, switch_codec_flag_t, const switch_codec_settings_t *codec_settings);
+typedef switch_status_t (*switch_core_codec_fmtp_parse_func_t) (const char *fmtp, switch_codec_fmtp_t *codec_fmtp);
typedef switch_status_t (*switch_core_codec_destroy_func_t) (switch_codec_t *);
@@ -1681,12 +1693,35 @@ typedef switch_status_t (*switch_input_callback_function_t) (switch_core_session
switch_input_type_t input_type, void *buf, unsigned int buflen);
typedef switch_status_t (*switch_read_frame_callback_function_t) (switch_core_session_t *session, switch_frame_t *frame, void *user_data);
typedef struct switch_say_interface switch_say_interface_t;
+
+#define DMACHINE_MAX_DIGIT_LEN 512
+
+typedef enum {
+ DM_MATCH_POSITIVE,
+ DM_MATCH_NEGATIVE
+} dm_match_type_t;
+
+struct switch_ivr_dmachine;
+typedef struct switch_ivr_dmachine switch_ivr_dmachine_t;
+
+struct switch_ivr_dmachine_match {
+ switch_ivr_dmachine_t *dmachine;
+ const char *match_digits;
+ int32_t match_key;
+ dm_match_type_t type;
+ void *user_data;
+};
+
+typedef struct switch_ivr_dmachine_match switch_ivr_dmachine_match_t;
+typedef switch_status_t (*switch_ivr_dmachine_callback_t) (switch_ivr_dmachine_match_t *match);
+
typedef struct {
switch_input_callback_function_t input_callback;
void *buf;
uint32_t buflen;
switch_read_frame_callback_function_t read_frame_callback;
void *user_data;
+ switch_ivr_dmachine_t *dmachine;
} switch_input_args_t;
typedef struct {
@@ -1714,7 +1749,7 @@ struct switch_network_list;
typedef struct switch_network_list switch_network_list_t;
-#define SWITCH_API_VERSION 4
+#define SWITCH_API_VERSION 5
#define SWITCH_MODULE_LOAD_ARGS (switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool)
#define SWITCH_MODULE_RUNTIME_ARGS (void)
#define SWITCH_MODULE_SHUTDOWN_ARGS (void)
diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h
index 4dc7ed7f1b..945583ee07 100644
--- a/src/include/switch_utils.h
+++ b/src/include/switch_utils.h
@@ -139,6 +139,9 @@ static inline char *switch_strchr_strict(const char *in, char find, const char *
#define switch_is_valid_rate(_tmp) (_tmp == 8000 || _tmp == 12000 || _tmp == 16000 || _tmp == 24000 || _tmp == 32000 || _tmp == 11025 || _tmp == 22050 || _tmp == 44100 || _tmp == 48000)
+#ifdef _MSC_VER
+#pragma warning(disable:6011)
+#endif
static inline int switch_string_has_escaped_data(const char *in)
{
const char *i = strchr(in, '\\');
@@ -153,6 +156,9 @@ static inline int switch_string_has_escaped_data(const char *in)
return 0;
}
+#ifdef _MSC_VER
+#pragma warning(default:6011)
+#endif
SWITCH_DECLARE(switch_status_t) switch_b64_encode(unsigned char *in, switch_size_t ilen, unsigned char *out, switch_size_t olen);
SWITCH_DECLARE(switch_size_t) switch_b64_decode(char *in, char *out, switch_size_t olen);
@@ -171,6 +177,23 @@ static inline switch_bool_t switch_is_digit_string(const char *s)
return SWITCH_TRUE;
}
+
+static inline uint32_t switch_known_bitrate(switch_payload_t payload)
+{
+ switch(payload) {
+ case 0: /* PCMU */ return 64000;
+ case 3: /* GSM */ return 13200;
+ case 4: /* G723 */ return 6300;
+ case 7: /* LPC */ return 2400;
+ case 8: /* PCMA */ return 64000;
+ case 9: /* G722 */ return 64000;
+ case 18: /* G729 */ return 8000;
+ default: break;
+ }
+
+ return 0;
+}
+
SWITCH_DECLARE(switch_size_t) switch_fd_read_line(int fd, char *buf, switch_size_t len);
@@ -353,7 +376,7 @@ switch_mutex_unlock(obj->flag_mutex);
#define switch_set_string(_dst, _src) switch_copy_string(_dst, _src, sizeof(_dst))
- static inline char *switch_sanitize_number(char *number)
+static inline char *switch_sanitize_number(char *number)
{
char *p = number, *q;
char warp[] = "/:";
@@ -455,6 +478,9 @@ static inline char *switch_safe_strdup(const char *it)
}
+#ifdef _MSC_VER
+#pragma warning(disable:6011)
+#endif
static inline char *switch_lc_strdup(const char *it)
{
char *dup;
@@ -487,6 +513,9 @@ static inline char *switch_uc_strdup(const char *it)
return NULL;
}
+#ifdef _MSC_VER
+#pragma warning(default:6011)
+#endif
/*!
diff --git a/src/mod/applications/mod_callcenter/mod_callcenter.c b/src/mod/applications/mod_callcenter/mod_callcenter.c
index 874c6156fd..ddd2cd5175 100644
--- a/src/mod/applications/mod_callcenter/mod_callcenter.c
+++ b/src/mod/applications/mod_callcenter/mod_callcenter.c
@@ -402,6 +402,7 @@ static struct {
char *odbc_dsn;
char *odbc_user;
char *odbc_pass;
+ char *dbname;
int32_t threads;
int32_t running;
switch_mutex_t *mutex;
@@ -506,7 +507,7 @@ switch_cache_db_handle_t *cc_get_db_handle(void)
dbh = NULL;
return dbh;
} else {
- options.core_db_options.db_path = CC_SQLITE_DB_NAME;
+ options.core_db_options.db_path = globals.dbname;
if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_CORE_DB, &options) != SWITCH_STATUS_SUCCESS)
dbh = NULL;
return dbh;
@@ -1258,6 +1259,8 @@ static switch_status_t load_config(void)
if (!strcasecmp(var, "debug")) {
globals.debug = atoi(val);
+ } else if (!strcasecmp(var, "dbname")) {
+ globals.dbname = strdup(val);
} else if (!strcasecmp(var, "odbc-dsn")) {
globals.odbc_dsn = strdup(val);
@@ -1272,6 +1275,9 @@ static switch_status_t load_config(void)
}
}
}
+ if (!globals.dbname) {
+ globals.dbname = strdup(CC_SQLITE_DB_NAME);
+ }
/* Loading queue into memory struct */
if ((x_queues = switch_xml_child(cfg, "queues"))) {
@@ -1498,7 +1504,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
/* Update Agents Items */
/* Do not remove uuid of the agent if we are a standby agent */
- sql = switch_mprintf("UPDATE agents SET %q last_bridge_end = %ld, talk_time = talk_time + (%ld-last_bridge_start) WHERE name = '%q' AND system = '%q';"
+ sql = switch_mprintf("UPDATE agents SET %s last_bridge_end = %ld, talk_time = talk_time + (%ld-last_bridge_start) WHERE name = '%q' AND system = '%q';"
, (strcasecmp(h->agent_type, CC_AGENT_TYPE_UUID_STANDBY)?"uuid = '',":""), (long) switch_epoch_time_now(NULL), (long) switch_epoch_time_now(NULL), h->agent_name, h->agent_system);
cc_execute_sql(NULL, sql, NULL);
switch_safe_free(sql);
@@ -2675,9 +2681,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_callcenter_load)
{
switch_application_interface_t *app_interface;
switch_api_interface_t *api_interface;
-
- /* connect my internal structure to the blank pointer passed to me */
- *module_interface = switch_loadable_module_create_module_interface(pool, modname);
+ switch_status_t status;
memset(&globals, 0, sizeof(globals));
globals.pool = pool;
@@ -2685,11 +2689,16 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_callcenter_load)
switch_core_hash_init(&globals.queue_hash, globals.pool);
switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, globals.pool);
+ if ((status = load_config()) != SWITCH_STATUS_SUCCESS) {
+ return status;
+ }
+
switch_mutex_lock(globals.mutex);
globals.running = 1;
switch_mutex_unlock(globals.mutex);
- load_config();
+ /* connect my internal structure to the blank pointer passed to me */
+ *module_interface = switch_loadable_module_create_module_interface(pool, modname);
if (!AGENT_DISPATCH_THREAD_STARTED) {
cc_agent_dispatch_thread_start();
@@ -2770,6 +2779,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_callcenter_shutdown)
}
switch_safe_free(globals.odbc_dsn);
+ switch_safe_free(globals.dbname);
switch_mutex_unlock(globals.mutex);
return SWITCH_STATUS_SUCCESS;
diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c
index 68cc58d10e..1fb1c95c47 100644
--- a/src/mod/applications/mod_commands/mod_commands.c
+++ b/src/mod/applications/mod_commands/mod_commands.c
@@ -135,7 +135,7 @@ SWITCH_STANDARD_API(nat_map_function)
switch_bool_t sticky = SWITCH_FALSE;
if (!cmd) {
- goto error;
+ goto usage;
}
if (!switch_nat_is_initialized()) {
@@ -147,9 +147,8 @@ SWITCH_STANDARD_API(nat_map_function)
switch_assert(mydata);
argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
-
if (argc < 1) {
- goto error;
+ goto usage;
}
if (argv[0] && switch_stristr("status", argv[0])) {
tmp = switch_nat_status();
@@ -197,6 +196,10 @@ SWITCH_STANDARD_API(nat_map_function)
error:
stream->write_function(stream, "false");
+ goto ok;
+
+ usage:
+ stream->write_function(stream, "USAGE: nat_map [status|reinit|republish] | [add|del] [tcp|udp] [sticky]");
ok:
@@ -1062,7 +1065,7 @@ SWITCH_STANDARD_API(url_encode_function)
int len = 0;
if (!zstr(cmd)) {
- len = (strlen(cmd) * 3) + 1;
+ len = (int)(strlen(cmd) * 3) + 1;
switch_zmalloc(data, len);
switch_url_encode(cmd, data, len);
reply = data;
@@ -3045,7 +3048,7 @@ SWITCH_STANDARD_API(xml_wrap_api_function)
if (mystream.data) {
if (encoded) {
- elen = (int) strlen(mystream.data) * 3;
+ elen = (int) strlen(mystream.data) * 3 + 1;
edata = malloc(elen);
switch_assert(edata != NULL);
memset(edata, 0, elen);
@@ -4215,7 +4218,7 @@ SWITCH_STANDARD_API(escape_function)
return SWITCH_STATUS_SUCCESS;
}
- len = strlen(cmd) * 2;
+ len = (int)strlen(cmd) * 2;
mycmd = malloc(len);
stream->write_function(stream, "%s", switch_escape_string(cmd, mycmd, len));
diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c
index dc1995fbef..ed62da107b 100644
--- a/src/mod/applications/mod_conference/mod_conference.c
+++ b/src/mod/applications/mod_conference/mod_conference.c
@@ -1012,7 +1012,7 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
uint8_t *file_frame;
uint8_t *async_file_frame;
int16_t *bptr;
- int x = 0;
+ uint32_t x = 0;
int32_t z = 0;
int member_score_sum = 0;
int divisor = 0;
@@ -1330,6 +1330,7 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
switch_mutex_unlock(omember->audio_out_mutex);
if (!ok) {
+ switch_mutex_unlock(conference->mutex);
goto end;
}
}
@@ -1913,6 +1914,8 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v
uint32_t hangover = 40, hangunder = 15, hangover_hits = 0, hangunder_hits = 0, energy_level = 0, diff_level = 400;
switch_codec_implementation_t read_impl = { 0 };
switch_core_session_t *session = member->session;
+ int check_floor_change;
+
switch_assert(member != NULL);
switch_clear_flag_locked(member, MFLAG_TALKING);
@@ -1925,6 +1928,7 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v
and mux it with any audio from other channels. */
while (switch_test_flag(member, MFLAG_RUNNING) && switch_channel_ready(channel)) {
+ check_floor_change = 0;
if (switch_channel_ready(channel) && switch_channel_test_app_flag(channel, CF_APP_TAGGED)) {
switch_yield(100000);
@@ -2082,25 +2086,7 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v
}
if (diff >= diff_level || ++hangunder_hits >= hangunder) {
-
- switch_mutex_lock(member->conference->member_mutex);
- if ((!member->conference->floor_holder ||
- !switch_test_flag(member->conference->floor_holder, MFLAG_TALKING) ||
- ((member->score_iir > SCORE_IIR_SPEAKING_MAX) && (member->conference->floor_holder->score_iir < SCORE_IIR_SPEAKING_MIN))) &&
- (!switch_test_flag(member->conference, CFLAG_VID_FLOOR) || switch_channel_test_flag(channel, CF_VIDEO))) {
-
- if (test_eflag(member->conference, EFLAG_FLOOR_CHANGE) &&
- switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
- conference_add_event_member_data(member, event);
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "floor-change");
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Old-ID", "%d",
- member->conference->floor_holder ? member->conference->floor_holder->id : 0);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-ID", "%d", member->conference->floor_holder ? member->id : 0);
- switch_event_fire(&event);
- }
- member->conference->floor_holder = member;
- }
- switch_mutex_unlock(member->conference->member_mutex);
+ check_floor_change = 1;
hangover_hits = hangunder_hits = 0;
member->last_talking = switch_epoch_time_now(NULL);
@@ -2190,6 +2176,28 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v
do_continue:
switch_mutex_unlock(member->read_mutex);
+
+ if (check_floor_change) {
+ switch_mutex_lock(member->conference->member_mutex);
+ if ((!member->conference->floor_holder ||
+ !switch_test_flag(member->conference->floor_holder, MFLAG_TALKING) ||
+ ((member->score_iir > SCORE_IIR_SPEAKING_MAX) && (member->conference->floor_holder->score_iir < SCORE_IIR_SPEAKING_MIN))) &&
+ (!switch_test_flag(member->conference, CFLAG_VID_FLOOR) || switch_channel_test_flag(channel, CF_VIDEO))) {
+
+ if (test_eflag(member->conference, EFLAG_FLOOR_CHANGE) &&
+ switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
+ conference_add_event_member_data(member, event);
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "floor-change");
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Old-ID", "%d",
+ member->conference->floor_holder ? member->conference->floor_holder->id : 0);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-ID", "%d", member->conference->floor_holder ? member->id : 0);
+ switch_event_fire(&event);
+ }
+ member->conference->floor_holder = member;
+ }
+ switch_mutex_unlock(member->conference->member_mutex);
+ }
+
}
@@ -2572,7 +2580,10 @@ static void conference_loop_output(conference_member_t *member)
if (member->fnode) {
member_add_file_data(member, write_frame.data, write_frame.datalen);
}
- switch_core_session_write_frame(member->session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
+ if (switch_core_session_write_frame(member->session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
+ switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+ break;
+ }
}
}
@@ -2582,7 +2593,10 @@ static void conference_loop_output(conference_member_t *member)
write_frame.samples = samples;
memset(write_frame.data, 255, write_frame.datalen);
member_add_file_data(member, write_frame.data, write_frame.datalen);
- switch_core_session_write_frame(member->session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
+ if (switch_core_session_write_frame(member->session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
+ switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+ break;
+ }
} else if (!switch_test_flag(member->conference, CFLAG_WASTE_BANDWIDTH)) {
if (switch_test_flag(member, MFLAG_WASTE_BANDWIDTH)) {
if (member->conference->comfort_noise_level) {
@@ -2595,7 +2609,10 @@ static void conference_loop_output(conference_member_t *member)
write_frame.samples = samples;
write_frame.timestamp = timer.samplecount;
- switch_core_session_write_frame(member->session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
+ if (switch_core_session_write_frame(member->session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
+ switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+ break;
+ }
}
}
@@ -3733,7 +3750,7 @@ static switch_status_t conf_api_sub_list(conference_obj_t *conference, switch_st
static switch_xml_t add_x_tag(switch_xml_t x_member, const char *name, const char *value, int off)
{
- switch_size_t dlen = strlen(value) * 3;
+ switch_size_t dlen = strlen(value) * 3 + 1;
char *data;
switch_xml_t x_tag;
diff --git a/src/mod/applications/mod_directory/mod_directory.c b/src/mod/applications/mod_directory/mod_directory.c
index bfad1a68f6..d92974766d 100644
--- a/src/mod/applications/mod_directory/mod_directory.c
+++ b/src/mod/applications/mod_directory/mod_directory.c
@@ -393,7 +393,7 @@ static dir_profile_t *load_profile(const char *profile_name)
profile_set_config(profile);
/* Add the params to the event structure */
- count = switch_event_import_xml(switch_xml_child(x_profile, "param"), "name", "value", &event);
+ count = (int)switch_event_import_xml(switch_xml_child(x_profile, "param"), "name", "value", &event);
if (switch_xml_config_parse_event(event, count, SWITCH_FALSE, profile->config) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to process configuration\n");
@@ -611,7 +611,7 @@ static switch_status_t on_dtmf(switch_core_session_t *session, void *input, swit
}
if (strlen(cbr->digits) < sizeof(cbr->digits) - 2) {
- int at = strlen(cbr->digits);
+ int at = (int)strlen(cbr->digits);
cbr->digits[at++] = dtmf->digit;
cbr->digits[at] = '\0';
} else {
@@ -649,25 +649,25 @@ static switch_status_t listen_entry(switch_core_session_t *session, dir_profile_
if (zstr_buf(buf)) {
switch_snprintf(macro, sizeof(macro), "phrase:%s:%d", DIR_RESULT_ITEM, cbt->want + 1);
- switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), 1, profile->terminator_key);
+ switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), 1, profile->terminator_key, 0);
}
if (!zstr_buf(recorded_name) && zstr_buf(buf)) {
- switch_ivr_read(session, 0, 1, recorded_name, NULL, buf, sizeof(buf), 1, profile->terminator_key);
+ switch_ivr_read(session, 0, 1, recorded_name, NULL, buf, sizeof(buf), 1, profile->terminator_key, 0);
}
if (zstr_buf(recorded_name) && zstr_buf(buf)) {
switch_snprintf(macro, sizeof(macro), "phrase:%s:%s", DIR_RESULT_SAY_NAME, cbt->fullname);
- switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), 1, profile->terminator_key);
+ switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), 1, profile->terminator_key, 0);
}
if (cbt->exten_visible && zstr_buf(buf)) {
switch_snprintf(macro, sizeof(macro), "phrase:%s:%s", DIR_RESULT_AT, cbt->extension);
- switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), 1, profile->terminator_key);
+ switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), 1, profile->terminator_key, 0);
}
if (zstr_buf(buf)) {
switch_snprintf(macro, sizeof(macro), "phrase:%s:%c,%c,%c,%c", DIR_RESULT_MENU, *profile->select_name_key, *profile->next_key, *profile->prev_key,
*profile->new_search_key);
- switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), profile->digit_timeout, profile->terminator_key);
+ switch_ivr_read(session, 0, 1, macro, NULL, buf, sizeof(buf), profile->digit_timeout, profile->terminator_key, 0);
}
if (!zstr_buf(buf)) {
diff --git a/src/mod/applications/mod_distributor/mod_distributor.2010.vcxproj b/src/mod/applications/mod_distributor/mod_distributor.2010.vcxproj
new file mode 100644
index 0000000000..368cfa18d7
--- /dev/null
+++ b/src/mod/applications/mod_distributor/mod_distributor.2010.vcxproj
@@ -0,0 +1,130 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ mod_distributor
+ {5C2B4D88-3BEA-4FE0-90DF-FA9836099D5F}
+ mod_distributor
+ Win32Proj
+
+
+
+ DynamicLibrary
+ MultiByte
+
+
+ DynamicLibrary
+ MultiByte
+
+
+ DynamicLibrary
+ MultiByte
+
+
+ DynamicLibrary
+ MultiByte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_ProjectFileVersion>10.0.30319.1
+
+
+
+
+
+
+
+ false
+
+
+
+
+
+
+ X64
+
+
+
+
+
+
+ false
+
+
+ MachineX64
+
+
+
+
+
+
+
+
+ false
+
+
+
+
+
+
+ X64
+
+
+
+
+
+
+ false
+
+
+ MachineX64
+
+
+
+
+
+
+
+ {202d7a4e-760d-4d0e-afa1-d7459ced30ff}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c
index 55429275dd..06f545928d 100755
--- a/src/mod/applications/mod_dptools/mod_dptools.c
+++ b/src/mod/applications/mod_dptools/mod_dptools.c
@@ -95,6 +95,176 @@ SWITCH_STANDARD_DIALPLAN(inline_dialplan_hunt)
return extension;
}
+struct action_binding {
+ char *realm;
+ char *input;
+ char *string;
+ char *value;
+ switch_core_session_t *session;
+};
+
+static switch_status_t digit_nomatch_action_callback(switch_ivr_dmachine_match_t *match)
+{
+ switch_core_session_t *session = (switch_core_session_t *) match->user_data;
+ switch_channel_t *channel = switch_core_session_get_channel(session);
+ char str[DMACHINE_MAX_DIGIT_LEN + 2];
+ switch_event_t *event;
+ switch_status_t status;
+
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Digit NOT match binding [%s]\n",
+ switch_channel_get_name(channel), match->match_digits);
+
+ if (switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) {
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "digits", match->match_digits);
+
+ if ((status = switch_core_session_queue_event(session, &event)) != SWITCH_STATUS_SUCCESS) {
+ switch_event_destroy(&event);
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s event queue faiure.\n",
+ switch_core_session_get_name(session));
+ }
+ }
+
+ /* send it back around flagged to skip the dmachine */
+ switch_snprintf(str, sizeof(str), "!%s", match->match_digits);
+
+ switch_channel_queue_dtmf_string(channel, str);
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t digit_action_callback(switch_ivr_dmachine_match_t *match)
+{
+ struct action_binding *act = (struct action_binding *) match->user_data;
+ switch_event_t *event;
+ switch_status_t status;
+ int exec = 0;
+ char *string = act->string;
+ switch_channel_t *channel = switch_core_session_get_channel(act->session);
+
+ if (switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(act->session), SWITCH_LOG_DEBUG, "%s Digit match binding [%s][%s]\n",
+ switch_channel_get_name(channel), act->string, act->value);
+
+ if (!strncasecmp(string, "exec:", 5)) {
+ string += 5;
+ exec = 1;
+ }
+
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, string, act->value);
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "digits", match->match_digits);
+
+ if (exec) {
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute", exec == 2 ? "non-blocking" : "blocking");
+ }
+
+ if ((status = switch_core_session_queue_event(act->session, &event)) != SWITCH_STATUS_SUCCESS) {
+ switch_event_destroy(&event);
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(act->session), SWITCH_LOG_WARNING, "%s event queue faiure.\n",
+ switch_core_session_get_name(act->session));
+ }
+ }
+
+ if (exec) {
+ char *cmd = switch_core_session_sprintf(act->session, "%s::%s", string, act->value);
+ switch_ivr_broadcast_in_thread(act->session, cmd, SMF_ECHO_ALEG|SMF_HOLD_BLEG);
+ }
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
+#define CLEAR_DIGIT_ACTION_USAGE "|all"
+SWITCH_STANDARD_APP(clear_digit_action_function)
+{
+ //switch_channel_t *channel = switch_core_session_get_channel(session);
+ switch_ivr_dmachine_t *dmachine;
+ char *realm = (char *) data;
+
+ if ((dmachine = switch_core_session_get_dmachine(session))) {
+ if (zstr(realm) || !strcasecmp(realm, "all")) {
+ switch_core_session_set_dmachine(session, NULL);
+ switch_ivr_dmachine_destroy(&dmachine);
+ } else {
+ switch_ivr_dmachine_clear_realm(dmachine, realm);
+ }
+ }
+}
+
+#define DIGIT_ACTION_SET_REALM_USAGE ""
+SWITCH_STANDARD_APP(digit_action_set_realm_function)
+{
+ switch_ivr_dmachine_t *dmachine;
+ char *realm = (char *) data;
+
+ if (zstr(data)) {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Syntax Error, USAGE %s\n", DIGIT_ACTION_SET_REALM_USAGE);
+ return;
+ }
+
+ if ((dmachine = switch_core_session_get_dmachine(session))) {
+ switch_ivr_dmachine_set_realm(dmachine, realm);
+ }
+
+}
+
+#define BIND_DIGIT_ACTION_USAGE ",,,"
+SWITCH_STANDARD_APP(bind_digit_action_function)
+{
+ switch_channel_t *channel = switch_core_session_get_channel(session);
+ switch_ivr_dmachine_t *dmachine;
+ char *mydata;
+ int argc = 0;
+ char *argv[4] = { 0 };
+ struct action_binding *act;
+
+ if (zstr(data)) {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Syntax Error, USAGE %s\n", BIND_DIGIT_ACTION_USAGE);
+ return;
+ }
+
+ mydata = switch_core_session_strdup(session, data);
+
+ argc = switch_separate_string(mydata, ',', argv, (sizeof(argv) / sizeof(argv[0])));
+
+ if (argc < 4 || zstr(argv[0]) || zstr(argv[1]) || zstr(argv[2]) || zstr(argv[3])) {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Syntax Error, USAGE %s\n", BIND_DIGIT_ACTION_USAGE);
+ return;
+ }
+
+
+ if (!(dmachine = switch_core_session_get_dmachine(session))) {
+ uint32_t digit_timeout = 1500;
+ uint32_t input_timeout = 0;
+ const char *var;
+ uint32_t tmp;
+
+ if ((var = switch_channel_get_variable(channel, "bind_digit_digit_timeout"))) {
+ tmp = (uint32_t) atol(var);
+ if (tmp < 0) tmp = 0;
+ digit_timeout = tmp;
+ }
+
+ if ((var = switch_channel_get_variable(channel, "bind_digit_input_timeout"))) {
+ tmp = (uint32_t) atol(var);
+ if (tmp < 0) tmp = 0;
+ input_timeout = tmp;
+ }
+
+ switch_ivr_dmachine_create(&dmachine, "DPTOOLS", NULL, digit_timeout, input_timeout, NULL, digit_nomatch_action_callback, session);
+ switch_core_session_set_dmachine(session, dmachine);
+ }
+
+
+ act = switch_core_session_alloc(session, sizeof(*act));
+ act->realm = argv[0];
+ act->input = argv[1];
+ act->string = argv[2];
+ act->value = argv[3];
+ act->session = session;
+
+ switch_ivr_dmachine_bind(dmachine, act->realm, act->input, 0, digit_action_callback, act);
+}
+
+
#define DETECT_SPEECH_SYNTAX " [] OR grammar [] OR pause OR resume"
SWITCH_STANDARD_APP(detect_speech_function)
{
@@ -909,48 +1079,42 @@ SWITCH_STANDARD_APP(set_profile_var_function)
SWITCH_STANDARD_APP(export_function)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
- const char *exports;
- char *new_exports = NULL, *new_exports_d = NULL, *var, *val = NULL, *var_name = NULL;
- int local = 1;
+ char *var, *val = NULL;
if (zstr(data)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No variable name specified.\n");
} else {
- exports = switch_channel_get_variable(channel, SWITCH_EXPORT_VARS_VARIABLE);
var = switch_core_session_strdup(session, data);
- if (var) {
- val = strchr(var, '=');
- if (!strncasecmp(var, "nolocal:", 8)) {
- var_name = var + 8;
- local = 0;
- } else {
- var_name = var;
- }
- }
- if (val) {
+ if ((val = strchr(var, '='))) {
*val++ = '\0';
if (zstr(val)) {
val = NULL;
}
}
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "EXPORT %s[%s]=[%s]\n", local ? "" : "(REMOTE ONLY) ",
- var_name ? var_name : "", val ? val : "UNDEF");
- switch_channel_set_variable(channel, var, val);
+ switch_channel_export_variable(channel, var, val, SWITCH_EXPORT_VARS_VARIABLE);
+ }
+}
- if (var && val) {
- if (exports) {
- new_exports_d = switch_mprintf("%s,%s", exports, var);
- new_exports = new_exports_d;
- } else {
- new_exports = var;
+SWITCH_STANDARD_APP(bridge_export_function)
+{
+ switch_channel_t *channel = switch_core_session_get_channel(session);
+ char *var, *val = NULL;
+
+ if (zstr(data)) {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No variable name specified.\n");
+ } else {
+ var = switch_core_session_strdup(session, data);
+
+ if ((val = strchr(var, '='))) {
+ *val++ = '\0';
+ if (zstr(val)) {
+ val = NULL;
}
-
- switch_channel_set_variable(channel, SWITCH_EXPORT_VARS_VARIABLE, new_exports);
-
- switch_safe_free(new_exports_d);
}
+
+ switch_channel_export_variable(channel, var, val, SWITCH_BRIDGE_EXPORT_VARS_VARIABLE);
}
}
@@ -1712,10 +1876,11 @@ SWITCH_STANDARD_APP(att_xfer_function)
SWITCH_STANDARD_APP(read_function)
{
char *mydata;
- char *argv[6] = { 0 };
+ char *argv[7] = { 0 };
int argc;
int32_t min_digits = 0;
int32_t max_digits = 0;
+ uint32_t digit_timeout = 0;
int timeout = 1000;
char digit_buffer[128] = "";
const char *prompt_audio_file = NULL;
@@ -1751,6 +1916,13 @@ SWITCH_STANDARD_APP(read_function)
valid_terminators = argv[5];
}
+ if (argc > 6) {
+ digit_timeout = atoi(argv[6]);
+ if (digit_timeout < 0) {
+ digit_timeout = 0;
+ }
+ }
+
if (min_digits <= 1) {
min_digits = 1;
}
@@ -1767,17 +1939,19 @@ SWITCH_STANDARD_APP(read_function)
valid_terminators = "#";
}
- switch_ivr_read(session, min_digits, max_digits, prompt_audio_file, var_name, digit_buffer, sizeof(digit_buffer), timeout, valid_terminators);
+ switch_ivr_read(session, min_digits, max_digits, prompt_audio_file, var_name, digit_buffer, sizeof(digit_buffer), timeout, valid_terminators,
+ digit_timeout);
}
SWITCH_STANDARD_APP(play_and_get_digits_function)
{
char *mydata;
- char *argv[9] = { 0 };
+ char *argv[10] = { 0 };
int argc;
int32_t min_digits = 0;
int32_t max_digits = 0;
int32_t max_tries = 0;
+ uint32_t digit_timeout = 0;
int timeout = 1000;
char digit_buffer[128] = "";
const char *prompt_audio_file = NULL;
@@ -1827,6 +2001,14 @@ SWITCH_STANDARD_APP(play_and_get_digits_function)
digits_regex = argv[8];
}
+ if (argc > 9) {
+ digit_timeout = atoi(argv[9]);
+ if (digit_timeout < 0) {
+ digit_timeout = 0;
+ }
+ }
+
+
if (min_digits <= 1) {
min_digits = 1;
}
@@ -1844,7 +2026,7 @@ SWITCH_STANDARD_APP(play_and_get_digits_function)
}
switch_play_and_get_digits(session, min_digits, max_digits, max_tries, timeout, valid_terminators,
- prompt_audio_file, bad_input_audio_file, var_name, digit_buffer, sizeof(digit_buffer), digits_regex);
+ prompt_audio_file, bad_input_audio_file, var_name, digit_buffer, sizeof(digit_buffer), digits_regex, digit_timeout);
}
#define SAY_SYNTAX " [] "
@@ -3265,6 +3447,17 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SWITCH_ADD_API(api_interface, "chat", "chat", chat_api_function, "||||[]");
SWITCH_ADD_API(api_interface, "strftime", "strftime", strftime_api_function, "");
SWITCH_ADD_API(api_interface, "presence", "presence", presence_api_function, PRESENCE_USAGE);
+
+ SWITCH_ADD_APP(app_interface, "bind_digit_action", "bind a key sequence or regex to an action",
+ "bind a key sequence or regex to an action", bind_digit_action_function, BIND_DIGIT_ACTION_USAGE, SAF_SUPPORT_NOMEDIA);
+
+ SWITCH_ADD_APP(app_interface, "clear_digit_action", "clear all digit bindings", "",
+ clear_digit_action_function, CLEAR_DIGIT_ACTION_USAGE, SAF_SUPPORT_NOMEDIA);
+
+ SWITCH_ADD_APP(app_interface, "digit_action_set_realm", "change binding realm", "",
+ digit_action_set_realm_function, DIGIT_ACTION_SET_REALM_USAGE, SAF_SUPPORT_NOMEDIA);
+
+
SWITCH_ADD_APP(app_interface, "privacy", "Set privacy on calls", "Set caller privacy on calls.", privacy_function, "off|on|name|full|number",
SAF_SUPPORT_NOMEDIA);
@@ -3299,6 +3492,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SWITCH_ADD_APP(app_interface, "sound_test", "Analyze Audio", "Analyze Audio", sound_test_function, "", SAF_NONE);
SWITCH_ADD_APP(app_interface, "export", "Export a channel variable across a bridge", EXPORT_LONG_DESC, export_function, "=",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
+ SWITCH_ADD_APP(app_interface, "bridge_export", "Export a channel variable across a bridge", EXPORT_LONG_DESC, bridge_export_function, "=",
+ SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "set", "Set a channel variable", SET_LONG_DESC, set_function, "=",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "set_global", "Set a global variable", SET_GLOBAL_LONG_DESC, set_global_function, "=",
@@ -3367,9 +3562,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SWITCH_ADD_APP(app_interface, "endless_playback", "Playback File Endlessly", "Endlessly Playback a file to the channel",
endless_playback_function, "", SAF_NONE);
SWITCH_ADD_APP(app_interface, "att_xfer", "Attended Transfer", "Attended Transfer", att_xfer_function, "", SAF_NONE);
- SWITCH_ADD_APP(app_interface, "read", "Read Digits", "Read Digits", read_function, "", SAF_NONE);
+ SWITCH_ADD_APP(app_interface, "read", "Read Digits", "Read Digits", read_function,
+ "", SAF_NONE);
SWITCH_ADD_APP(app_interface, "play_and_get_digits", "Play and get Digits", "Play and get Digits",
- play_and_get_digits_function, "